RibbonCheckBox alignment in a RibbonGroup - wpf

<RibbonWindow x:Class="xxx.yyy"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
...
<Ribbon x:Name="mainRibbon" Grid.Row="0" >
...
<RibbonTab Name="ComparisonTab" HorizontalContentAlignment="Left" Header="Comparison" >
<!--<StackPanel Orientation="Vertical" HorizontalAlignment="Left">-->
<RibbonGroup HorizontalContentAlignment="Left" Header="Images" >
<RibbonCheckBox HorizontalAlignment="Left" Width="200" IsChecked="{Binding CompInfo1Check}" Label="{Binding CompInfo1Text}" />
<RibbonCheckBox HorizontalAlignment="Left" Width="200" IsChecked="{Binding CompInfo2Check}" Label="{Binding CompInfo2Text}" />
<RibbonCheckBox HorizontalAlignment="Left" Width="200" IsChecked="{Binding CompInfo3Check}" Label="{Binding CompInfo3Text}" />
</RibbonGroup>
<!--</StackPanel>-->
</RibbonTab>
I have some checkboxes with a dynamic text (labels) and I want to have them left aligned within a ribbon group.
I've tried every imaginable combination of Horizontal(Content)Alignment on them and on their parents. I tried to put them into a container (StackPanel, Grid). I even tried to set a label as a separate element.
The checkboxes stubbornly remain centered within a ribbon group. How do I align them horizontally to the left?

I've found a workaround in using standard check boxes inside a ribbon. There is no problem with their alignment. They could be styled to look as the ribbon check boxes, if required.
So, the modified xaml is:
<RibbonTab Name="ComparisonTab" HorizontalContentAlignment="Left" Header="Comparison" >
<RibbonGroup Header="Images" >
<StackPanel Orientation="Vertical" HorizontalAlignment="Left">
<CheckBox Height="25" IsChecked="{Binding CompInfo1Check}" Content="{Binding CompInfo1Text}" />
<CheckBox Height="25" IsChecked="{Binding CompInfo2Check}" Content="{Binding CompInfo2Text}" />
<CheckBox Height="25" IsChecked="{Binding CompInfo3Check}" Content="{Binding CompInfo3Text}" />
</StackPanel>
</RibbonGroup>
</RibbonTab>
EDIT
Probably a better way is to use a grid, RibbonCheckBox without a label and a TextBlock instead.
Explained here.

Related

Datagrid inside of MahApps.Metro Flyout

I am trying to create a flyout for settings using MahApps.Metro inside of a MetroWindow control using WPF. I have created the flyout and have several other radio buttons and seperators. I am now adding a datagrid to hold a list of StockSymbols used as a watch list for my application. What I am having trouble with is properly setting the datagrid so that it does not autogrow past the size of the flyout. If you add rows to the datagrid you can keep adding until it flows offscreen ouside of the window. I would like to do it so that I don't have to manually set the max Height and for it to dynamically grow as the window grows.
Here is my current code for the flyout:
<Controls:MetroWindow.Flyouts>
<Controls:Flyout Header="Settings"
Background="#9f000000"
Position="Right"
IsOpen="{Binding IsSettingsFlyoutOpen}">
<DockPanel HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<StackPanel Orientation="Vertical"
VerticalAlignment="Top"
HorizontalAlignment="Center"
Margin="20,0"
DockPanel.Dock="Top">
<Label Content="Theme"
Style="{StaticResource DescriptionHeaderStyle}" />
<StackPanel Orientation="Horizontal">
<RadioButton Content="Dark"
Margin="0,0,5,0"
IsChecked="True"
Checked="ThemeDark" />
<RadioButton Content="Light"
Margin="0,0,5,0"
Checked="ThemeLight" />
</StackPanel>
<Separator Margin="0,10,0,10" />
<Label Content="Accent"
Style="{StaticResource DescriptionHeaderStyle}" />
<StackPanel Orientation="Vertical">
<RadioButton Content="Black"
Margin="0,5,0,0" />
<RadioButton Content="Blue"
Margin="0,5,0,0"
Checked="AccentBlue" />
<RadioButton Content="Red"
Margin="0,5,0,0"
Checked="AccentRed" />
<RadioButton Content="Green"
Margin="0,5,0,0"
Checked="AccentGreen" />
<RadioButton Content="Orange"
Margin="0,5,0,0"
IsChecked="True"
Checked="AccentOrange" />
<RadioButton Content="Purple"
Margin="0,5,0,0"
Checked="AccentPurple" />
</StackPanel>
<Separator Margin="0,10,0,10" />
</StackPanel>
<StackPanel Orientation="Vertical"
Height="Auto"
VerticalAlignment="Top"
DockPanel.Dock="Bottom"
Margin="20,0">
<Label Content="Watch List"
Style="{StaticResource DescriptionHeaderStyle}" />
<DataGrid ItemsSource="{Binding WatchList}"
AutoGenerateColumns="False"
CanUserResizeRows="False"
CanUserReorderColumns="False"
HeadersVisibility="Column">
<DataGrid.Columns>
<DataGridTextColumn Header="Symbol"
Binding="{Binding Symbol}" />
<DataGridTextColumn Header="Name"
Binding="{Binding Name}" />
</DataGrid.Columns>
</DataGrid>
</StackPanel>
</DockPanel>
</Controls:Flyout>
</Controls:MetroWindow.Flyouts>
Any and all help is appreciated.
I solved this question by using only a Dock Panel to hold all the controls inside the Flyout. The all controls but the data grid should be set to top docking and no docking set on the datagrid. This then auto sizes the datagrid to fill the remaining space and no more.
I had the same problem.
I solved this issue setting the Flyout size.
I think the problem occurs when WPF render the grid and the Flyout size is smaller than grid size.
anyway, our Flyout was dynamic, I had to create a Converter to get its size and set my child control to same width

Dock a resizable wpf DataGrid at bottom of window

In a WPF project, I want to dock a DataGrid to the bottom of a window so that if the window resizes, I will be able to utilize more of the DataGrid. Like this:
How do I do that? All my DockPanel attempts have failed.
The current attempt is here:
<Window x:Class="Foo.SQLDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:Foo.Controls"
Title="test" ResizeMode="CanResize" Width="400" Height="400">
<StackPanel Orientation="Vertical" Height="Auto" Width="Auto">
<StackPanel Orientation="Vertical">
<Label Content="SQL" HorizontalAlignment="Left"/>
<TextBox Width="377" Height="100" Name="txtSQL"/>
<Button Content="Run SQL" Click="Button_Click_1" />
</StackPanel>
<Label Content="Result" HorizontalAlignment="Left"/>
<ScrollViewer Width="Auto" Height="180" DockPanel.Dock="Right,Bottom"
ScrollViewer.CanContentScroll="True"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Auto">
<DataGrid x:Name="dataResult" />
</ScrollViewer>
</StackPanel>
</Window>
The height of the scrollviewer+datagrid will not adapt however.
First of all, using DockPanel.Dock without having a DockPanel as a parent doesn't do much...
In my example I changed your root StackPanel to a DockPanel so it will work as you want.
I also used DockPanel.LastChildFill property which makes sure the last child of the DockPanel will get all the remaining space:
<DockPanel LastChildFill="True">
<StackPanel Orientation="Vertical" DockPanel.Dock="Top">
<Label Content="SQL" HorizontalAlignment="Left"/>
<TextBox Width="377" Height="100" Name="txtSQL"/>
<Button Content="Run SQL" Click="Button_Click_1" />
</StackPanel>
<Label Content="Result" HorizontalAlignment="Left" DockPanel.Dock="Top"/>
<ScrollViewer DockPanel.Dock="Bottom,Right"
ScrollViewer.CanContentScroll="True"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Auto">
<DataGrid x:Name="dataResult" />
</ScrollViewer>
</DockPanel>
Finally, to make it really stretch on all the remaining space, I removed the Height property you set, as this blocked it from stretching.
Not sure if useful or if i understand you question the right way but have you tried this:
<DataGrid DockPanel.Dock="Right, Bottom" VerticalAlignment="Bottom" HorizontalAlignment="Right" ></DataGrid>

Autoresize ListBox inside ScrollViewer

In my application I have a Window. It contains a left side menu, a header and a place for content.
This content is being loaded dynamically - a UserControl is put in there. These UserControls are various. From just a TextBlock to quite complex pages. To make sure all the content will be visible I have to wrap it with a ScrollViewer (I mean in MyWindow.xaml). It all works fine until I need to put a ListView in the content.
More or less the code looks like that:
<ScrollViewer> // this is the wrapping viewer actually it's in a different file
<UserControl>
......
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10*"/>
<ColumnDefinition Width="20*"/>
</Grid.ColumnDefinitions>
<ListView ItemsSource="{Binding Entities}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Style="{StaticResource Value}" Text="{Binding WorkOrderNumber}"/>
<TextBlock Style="{StaticResource Value}" Text="{Binding ActionType}"/>
<TextBlock Style="{StaticResource Value}" Text="{Binding StartDate}"/>
<TextBlock Style="{StaticResource Value}" Text="{Binding StopDate}"/>
<Separator/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Whatever.. Grid.Row="0" Grid.Column="1"/>
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Style="{StaticResource CustomButton}" Content="Previous" />
<Button Style="{StaticResource CustomButton}" Content="Current" />
<Button Style="{StaticResource CustomButton}" Content="Next" />
</StackPanel>
</Grid>
</UserControl>
</ScrollViewer>
The result is that the listbox has no scrollbar and gets vary high. The scrollbar is only at the window's scrollviewer.
So in my UserControl I want:
the buttons always to be at the very bottom
the listbox to fill the whole space left (also to resize along with the window)
avoid hardcoding listbox's height
Is that possible?
Use a DockPanel instead of a Grid. DockPanel has a property called LastChhildFill. It is by default true. If you set your ListBox to be the last Child, it will fill all the space:
<ScrollViewer>
<DockPanel>
<StackPanel DockPanel.Dock="Bottom"
Orientation="Horizontal"
HorizontalAlignment="Center">
<Button Style="{StaticResource CustomButton}"
Content="Previous" />
<Button Style="{StaticResource CustomButton}"
Content="Current" />
<Button Style="{StaticResource CustomButton}"
Content="Next" />
</StackPanel>
<ListView >
</ListView>
</DockPanel>
</ScrollViewer>
But this setting makes the Buttons to disappear. I mean they are always at the Bottom of the ListBox. So maybe you need to remove the ScrollViewer.

How to make a ListView inside a grid in WPF fill the whole screen, even when resized

I have a control which is a grid where the first row contains some buttons, with fixed height, and the second (and last) row contains a ListView. Then I have a main screen which contains only a menu and this user control above. I would like to have the size of the ListView as the maximum for the window, which means that if the window is maximized the ListView will be large, in case the window is smaller, so is the ListView (with vertical scroll to help navigating through items).
This is how I am doing it:
Window:
<Window x:Class="TestUI.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Width="auto" Height="auto"
MinHeight="300" MinWidth="300"
Title="Test"
DataContext="{Binding MainViewModel, Source={StaticResource Locator}}" >
<StackPanel Orientation="Vertical" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<DockPanel>
<Menu DockPanel.Dock="Top" >
<MenuItem Header="Item 1" Command="{Binding Command1}"/>
<MenuItem Header="Item 2" Command="{Binding Command2}"/>
<MenuItem Header="Item 3" Command="{Binding Command3}"/>
</Menu>
</DockPanel>
<DockPanel LastChildFill="True">
<ScrollViewer Content="{Binding Content}" VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Disabled" DockPanel.Dock="Bottom" />
</DockPanel>
</StackPanel>
</Window>
User Control:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="35" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Margin="5, 5, 5, 5" Orientation="Horizontal">
<Button Content="New" Width="60" Command="{Binding NewCommand}"/>
<Button Content="Remove" Width="60" Margin="10, 0, 0, 0" Command="{Binding RemoveCommand}" />
</StackPanel>
<DockPanel Grid.Row="1" Margin="5,5,5,5" LastChildFill="True" HorizontalAlignment="Stretch">
<ListView x:Name="ListView" SelectionMode="Single" DockPanel.Dock="Top" ItemsSource="{Binding Entities}" SelectedItem="{Binding SelectedEntity}" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto" VerticalAlignment="Stretch">
<ListView.View>
<GridView>
<GridViewColumn Width="auto" Header="Product" DisplayMemberBinding="{Binding Description}"/>
</GridView>
</ListView.View>
</ListView>
</DockPanel>
</Grid>
Could you please help me?
Thank you!
I've just inspected your User Control and the Listview docking is working just fine. You can verify layout in the designer by using background colours. Setting the listview's background to blue shows it is using the available space.
I believe the problem is with the layout in your main form, specifically the Stackpanel. These are notorious for layout issues, and from what I can tell you don't need it. use the DockPanel as the high-level container rather than multiple dock panels. (This is what they're for)
<DockPanel>
<Menu DockPanel.Dock="Top" >
<MenuItem Header="Item 1" Command="{Binding Command1}"/>
<MenuItem Header="Item 2" Command="{Binding Command2}"/>
<MenuItem Header="Item 3" Command="{Binding Command3}"/>
</Menu>
<ScrollViewer Content="{Binding Content}" VerticalScrollBarVisibility="Disabled"
HorizontalScrollBarVisibility="Disabled" DockPanel.Dock="Fill" />
</DockPanel>
This will put your menu at the top of the panel, and let your scroll viewer containing the user control (assumed) use up the remaining available space.
Stack-panels are only good for arranging items within an area. If you want to use layout to allocate available space, use DockPanels or Grids.
Hi remove Width="Auto" from GridviewColumn. I hope this will help

How to make WPF Expander expand upwards while keeping the header fixed

I am trying to create an Expander where the header stays fixed and the contents appear above the header overlaying any other controls above. Setting ExpandDirection="Up" and putting the Expander inside a Canvas achieves half of this - the contents expands up relative to the header and it overlays other controls (albeit below), but the header moves downwards.
Is there any way to do this but keeping the header in a fixed position so that the contents ends up overlaying controls above?
This is what I have poduced so far:
<Window x:Class="Sandbox.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="900" Width="1100">
<StackPanel>
<StackPanel Margin="20,0,0,0">
<RadioButton Content="Choice One"/>
<RadioButton Content="Choice Two"/>
<RadioButton Content="Choice Three"/>
<RadioButton Content="Choice Four"/>
<RadioButton Content="Choice Five"/>
<RadioButton Content="Choice Six"/>
</StackPanel>
<Canvas MinHeight="25" Panel.ZIndex="99">
<Expander Header="This must stay fixed" ExpandDirection="Up" Width="175">
<Grid Background="Cornsilk">
<Grid.BitmapEffect>
<DropShadowBitmapEffect />
</Grid.BitmapEffect>
<TextBlock TextWrapping="Wrap" Margin="5">
This must expand upwards, not downwards.
The header must remain exactly where it is.
This TextBlock must appear above the header
and overlay the top radio buttons instead.
</TextBlock>
</Grid>
</Expander>
</Canvas>
<StackPanel Margin="20,0,0,0">
<RadioButton Content="Choice One"/>
<RadioButton Content="Choice Two"/>
<RadioButton Content="Choice Three"/>
<RadioButton Content="Choice Four"/>
<RadioButton Content="Choice Five"/>
<RadioButton Content="Choice Six"/>
</StackPanel>
</StackPanel>
</Window>
You can use ToggleButton and Popup instead of Expander:
<Canvas MinHeight="25" Panel.ZIndex="99">
<ToggleButton x:Name="toggle" Content="This must stay fixed" Width="175" />
<Popup Placement="Top" PlacementTarget="{Binding ElementName=toggle}"
IsOpen="{Binding ElementName=toggle, Path=IsChecked}">
<Grid Background="Cornsilk" Width="175">
<Grid.BitmapEffect>
<DropShadowBitmapEffect />
</Grid.BitmapEffect>
<TextBlock TextWrapping="Wrap" Margin="5">
This must expand upwards, not downwards.
The header must remain exactly where it is.
This TextBlock must appear above the header
and overlay the top radio buttons instead.
</TextBlock>
</Grid>
</Popup>
</Canvas>
The other way is to use CheckBox control instead of ToggleButton. It is easy to hide the box using e.g. StackPanel with negative margin value. Also, you don't need to care about borders etc. It is much easier in some cases.

Resources