Setting Z-Index in DataBound items on a Canvas - wpf

I am trying to bind a list of items to an ItemsControl, using a Canvas layout, where the item has multiple "levels". This is easiest to explain using an image:
My lower level is a drop-shadow in this case. Because I assumed the drop shadow would be attached to the main element (a Button), I created another visual element, a Border, which sits behind the Button and has the shadow attached. What I would like is for all of my shadow elements to be at the same overall ZIndex, and all of the Button elements to be above them.
In practice, it appears that WPF renders the contents of my template as a single UI element, essentially flattening the ZIndexes within it. Is there any way I can make it so that the ZIndex values are not flattened?
I have created a sample below which shows the problem:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="250" Width="600" Background="White">
<Window.Resources>
<DropShadowEffect Color="Blue" BlurRadius="75" x:Key="ActionDropShadow" />
<XmlDataProvider x:Key="myData" XPath="Data/Items">
<x:XData>
<Data xmlns="">
<Items>
<Item X="50" Title="AAA" />
<Item X="100" Title="BBB" />
<Item X="150" Title="CCC" />
</Items>
</Data>
</x:XData>
</XmlDataProvider>
<DataTemplate x:Key="BoxTemplate">
<Grid>
<Border Background="Black" BorderThickness="1" Effect="{StaticResource ActionDropShadow}" />
<Button Background="White" BorderThickness="1">
<TextBlock Text="{Binding XPath=#Title}" />
</Button>
</Grid>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ItemsControl Grid.Column="0" x:Name="list" ItemTemplate="{StaticResource BoxTemplate}" ItemsSource="{Binding Source={StaticResource myData},XPath=*}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding XPath=#X}" />
<Setter Property="Canvas.Top" Value="50" />
<Setter Property="Width" Value="50" />
<Setter Property="Height" Value="80" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
<Canvas Grid.Column="1">
<Border Panel.ZIndex="5" Canvas.Top="50" Canvas.Left="50" Width="50" Height="80" Background="Black" BorderThickness="1" Effect="{StaticResource ActionDropShadow}" />
<Button Panel.ZIndex="10" Canvas.Top="50" Canvas.Left="50" Width="50" Height="80" Background="White" BorderThickness="1">
<TextBlock Text="AAA" />
</Button>
<Border Panel.ZIndex="5" Canvas.Top="50" Canvas.Left="100" Width="50" Height="80" Background="Black" BorderThickness="1" Effect="{StaticResource ActionDropShadow}" />
<Button Panel.ZIndex="10" Canvas.Top="50" Canvas.Left="100" Width="50" Height="80" Background="White" BorderThickness="1">
<TextBlock Text="BBB" />
</Button>
<Border Panel.ZIndex="5" Canvas.Top="50" Canvas.Left="150" Width="50" Height="80" Background="Black" BorderThickness="1" Effect="{StaticResource ActionDropShadow}" />
<Button Panel.ZIndex="10" Canvas.Top="50" Canvas.Left="150" Width="50" Height="80" Background="White" BorderThickness="1">
<TextBlock Text="CCC" />
</Button>
</Canvas>
<TextBlock Grid.Row="1" Grid.Column="0" HorizontalAlignment="Center">Databinding Version</TextBlock>
<TextBlock Grid.Row="1" Grid.Column="1" HorizontalAlignment="Center">What it should look like</TextBlock>
</Grid>
</Window>
Thanks in advance for any ideas you can offer!

Since the bound objects are wrapped in a ContentPresenter all internal ZIndex settings will be ignored, so you cannot do what you described. You might be better off creating an ItemsControl for each layer.

Get the parent ContentPresenter and set ZIndex on that.
E.g:
var parent = (UIElement) VisualTreeHelper.GetParent((UIElement) sender);
parent.SetZIndex(parent, z);

Related

How can I disable all component and change background color?

I have a WPF application. When I press the exit button, I want to see the box like this:
The box name is Risultati. This works, but I want the all WPF application is disable and I can see a light gray how the modal dialog.
This is the code that I use to create my box, Risutlati:
<UserControl x:Class="ContattoOculare.RiepilogoEsercizio"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="342" d:DesignWidth="520">
<Grid Margin="0,0,0,0" Height="342" Width="520">
<Grid.RowDefinitions>
<RowDefinition Height="80" />
<RowDefinition Height="35" />
<RowDefinition Height="40" />
<RowDefinition Height="100" />
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<Grid.Background>
<ImageBrush x:Name="backgroudCarta" ImageSource="./Resources/Esci_dal_gioco_Maschera.png"/>
</Grid.Background>
<!--INTESTAZIONE-->
<Grid Grid.Row="0" Margin="0,20,0,0" >
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="32" />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Label Content="Risultati" VerticalAlignment="Bottom" HorizontalAlignment="Center"
FontSize="30" FontFamily="./Font/#Roboto-Bold" Foreground="White"/>
</Grid>
<Grid Grid.Row="1" Margin="0,0,0,14">
<Label Content="Contatto Oculare" VerticalAlignment="Top" HorizontalAlignment="Center"
FontSize="18" FontFamily="./Font/#Roboto-Bold" Foreground="White" Margin="190,-12,184,0"/>
</Grid>
</Grid>
<!--FINE INTESTAZIONE-->
<!--PRIMA RIGA-->
<Grid Grid.Row="1">
<Label Content="Tempo" FontSize="22"
FontFamily="./Font/#Roboto-Bold" Foreground="Gray" HorizontalAlignment="Center"/>
</Grid>
<!--FINE PRIMA RIGA-->
<!--SECONDA RIGA-->
<Grid Grid.Row="2" Margin="0,-12,0,0">
<Label x:Name="labelTempo" Content="0 sec" FontSize="25" FontWeight="Bold"
FontFamily="./Font/#Roboto-Bold" Foreground="Gray" HorizontalAlignment="Center"/>
</Grid>
<!--FINE SECONDA RIGA-->
<!--TERZA RIGA-->
<Grid Grid.Row="3" Margin="50,0,50,0">
<TextBox x:Name="textDescrizione" VerticalAlignment="Top" FontSize="25"
FontFamily="Calibri" Foreground="Gray"
TextWrapping="Wrap" AcceptsReturn="True" Height="100" />
</Grid>
<!--FINE TERZA RIGA-->
<!--QUARTA RIGA-->
<Grid Grid.Row="4" HorizontalAlignment="Center" Margin="0,5,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid Height="Auto" Width="Auto" HorizontalAlignment="Center"
Grid.Column="0" >
<Image Width="206" Height="46"
HorizontalAlignment="Center" VerticalAlignment="Bottom"
x:Name="save">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="./Resources/Tasto_Uscita gioco_Salva_Roll_ON.png"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Source" Value="./Resources/Tasto_Uscita_gioco_Roll_OFF.png"/>
</Trigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
<Label HorizontalAlignment="Center" VerticalAlignment="Center" FontFamily="Roboto-Bold"
FontSize="20" Foreground="White">Salva</Label>
</Grid>
<Grid Height="Auto" Width="Auto" HorizontalAlignment="Center"
Grid.Column="1" >
<Image Width="206" Height="46"
HorizontalAlignment="Center" VerticalAlignment="Bottom"
x:Name="stop">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="./Resources/Tasto_Uscita_gioco_Salva_Roll_OFF.png"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Source" Value="./Resources/Tasto_Uscita_gioco_Roll_OFF.png"/>
</Trigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
<Label HorizontalAlignment="Center" VerticalAlignment="Center" FontFamily="Roboto-Bold"
FontSize="20" Foreground="White">Annulla</Label>
</Grid>
</Grid>
<!--FINE QUARTA RIGA-->
</Grid>
</UserControl>
How can I do this?
For any WPF window, I normally will implement a mask over its content, something like:
<Window>
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibility"/>
</Window.Resources>
<Grid>
<Grid>
<!--your window content-->
</Grid>
<!--this is your mask, give it a semi-transparent color-->
<Grid Background="#65000000" Visibility="{Binding IsModalDialogActived, Converter={StaticResource BooleanToVisibility}}"/>
<Grid>
<!--your dialog-->
</Grid>
</Grid>
</Window>
So that you can set the mask to Visible when your show the modal dialogue, and the mask will cast a shadow over the interface and prevent any user interactions with your application.
I would extend the Window class rather than the UserControl class. Then, call ShowDialog to show up your box. All other windows in the application will be disabled. That's a true (WPF) modal dialog, loosely coupled and reusable across your application.
Keep in mind:
Use AllowsTransparency="True" to allow semi-transparent colors for the Background.
Use WindowStyle="None" to remove the borders.
Use WindowState="Maximized" to occupy all available space.
Set the HorizontalAlignment, VerticalAlignment, Width, Height and Margin properties in your main Grid to place your box where desired.

WPF: How to ignore defined style for concrete control

I have the Rectangle control style (for the type of Rectangle) defined in resource dictionary and it reflects the style for a Menu control also.
How to ignore these settings for Menu and leave it for (just) Rectangle? - Drawing purposes in canvas .... The Rectangle control is added to canvas dynamically from code behind. In main window is dockpanel, grid, menu, textblock and canvas controls. Style for rectangle also harm style properties for Menu (needed to keep the default style).
Thanks for advice
Main window controls:
<DockPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch" LastChildFill="True">
<Grid DockPanel.Dock="Top">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Menu Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3" HorizontalAlignment="Stretch" Height="21" Name="menu" Style="{StaticResource ResourceKey=menuStyle}">
<MenuItem Header="File">
<MenuItem Header="Open image" Command="{Binding DoCommand}" CommandParameter="OpenImage"/>
<MenuItem Header="Exit" Command="{Binding DoCommand}" CommandParameter="Exit"/>
</MenuItem>
</Menu>
<RadioButton Margin="5" Grid.Row="1" Grid.Column="0" Content="Text selection" GroupName="ObjectType" IsChecked="{Binding Path=ObjectType, Mode=TwoWay, Converter={StaticResource ResourceKey=RadioButtonTypeConverter}, ConverterParameter=Text}" />
<RadioButton Margin="5" Grid.Row="1" Grid.Column="1" Content="Picture selection" GroupName="ObjectType" IsChecked="{Binding Path=ObjectType, Mode=TwoWay, Converter={StaticResource ResourceKey=RadioButtonTypeConverter}, ConverterParameter=Picture}" />
</Grid>
<pt:PropertyControl DockPanel.Dock="Right" SelectedObject="{Binding SelectedObject}" MinWidth="150"/>
<TextBlock DockPanel.Dock="Bottom" Height="100" Margin="5" Background="#FFF9F9F9">
</TextBlock>
<Canvas Name="canvas" MouseLeftButtonDown="Canvas_MouseLeftButtonDown" Background="White" Width="{Binding ElementName=ImgEdit, Path=Width}" Height="{Binding ElementName=ImgEdit, Path=Height}" MinWidth="300" MinHeight="100" VerticalAlignment="Top" MouseMove="canvas_MouseMove" MouseLeftButtonUp="canvas_MouseLeftButtonUp" >
<Image x:Name="ImgEdit" Source="{Binding BackgroundImage}" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Canvas>
</DockPanel>
Code of my Style resource dictionary:
<Style TargetType="{x:Type Rectangle}" >
<Setter Property="Fill" Value="Yellow" />
<Setter Property="Opacity" Value="0.2"/>
<Setter Property="StrokeThickness" Value="2"/>
<Setter Property="Stroke" Value="Red" />
</Style>

WPF - How to skip a label in tab navigation?

I have a stackpanel inside a controltemplate inside a itemscontrol inside a stackpanel inside a grid inside a usercontrol (se the xaml below). In the inner stackpanel there is a label (Name="NoComponentChosen") and another stackpanel (Name="ComponentChosen"). The label's visibility is initially collapsed.
The controltemplate has a datatrigger with a binding. When the binding reference has a specific value the label (NoComponentChosen) becomes visible and the stackpanel collapses.
I would like to skip the label/stackpanel when I am tabbing trough the user interface. I would also like to still be able tab through the rest of the things in my ChangeRequestView.xaml (listbox and buttons).
Right now - when I tab - the label/stackpanel eventually becomes chosen and is surrounded by a dotted rectangle. That is what I would like to avoid.
This is my ChangeRequestView.xaml:
<UserControl x:Class="MyProgram.View.ChangeRequestView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
xmlns:ListBoxBehavior="clr-namespace:MyProgram.Utility"
mc:Ignorable="d"
d:DesignHeight="500" d:DesignWidth="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="35"/>
<RowDefinition Height="45*"/>
<RowDefinition Height="10*"/>
<RowDefinition Height="20*"/>
<RowDefinition Height="35"/>
</Grid.RowDefinitions>
<!--The title of the view-->
<Label Grid.Row="0" Content="Change Requests" FontWeight="Bold" Margin="5,5,5,5" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<!--The component chosen-->
<StackPanel Grid.Row="1" Orientation="Horizontal" Margin="5,0,0,0" IsHitTestVisible="False" Focusable="False">
<ItemsControl>
<ItemsControl.Template>
<ControlTemplate>
<StackPanel>
<StackPanel Name="ComponentChosen" Orientation="Horizontal">
<Label Content="Reference des.: " />
<Label Name="referenceDesignation" Content="{Binding Path=ReferenceDesignation, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
<Label Name="NoComponentChosen" Content="Choose a component" Visibility="Collapsed"/>
</StackPanel>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding ReferenceDesignation}" Value="">
<Setter TargetName="ComponentChosen" Property="Visibility" Value="Collapsed"/>
<Setter TargetName="NoComponentChosen" Property="Visibility" Value="Visible"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</ItemsControl.Template>
</ItemsControl>
</StackPanel>
<ListBox Grid.Row="2" ... />
<Button Grid.Row="3" ... />
<Button Grid.Row="4" ... />
</Grid>
</UserControl>
The whole UserControl/ChangeRequestView.xaml is part of my MainWindow - I don't know if that has anything to say. I tab through all of the different views in my MainWindow, and when I get to the ChangeRequestView I would like to skip the label/stackpanel according to which of them isn't collapsed.
This is my MainWindow.xaml:
<Window x:Class="MyProgram.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:view="clr-namespace:MyProgram.View"
xmlns:vm="clr-namespace:MyProgram.ViewModel"
...>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="309*"/>
<RowDefinition Height="187*"/>
<RowDefinition Height="120*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="209*"/>
<ColumnDefinition Width="558*"/>
<ColumnDefinition Width="250*"/>
</Grid.ColumnDefinitions>
<Menu IsMainMenu="True" Name="Menu1" VerticalAlignment="Top" Grid.Row="0" Grid.ColumnSpan="3">
<MenuItem Header="_File">
<MenuItem Header="_Save changed change requests for current reference designation"
InputGestureText="Ctrl+S" Command="{Binding Path=HotKeysSaveChangeRequestUpdateCmd}"/>
<MenuItem Header="_Upload change requests for current project"
InputGestureText="Ctrl+U" Command="{Binding Path=HotKeysUploadCmd}"/>
<MenuItem Header="_Exit" ToolTip="Exit this program"
InputGestureText="CTRL+X" Command="{Binding Path=ShutDownCmd}"/>
</MenuItem>
</Menu>
<!--Search Region-->
<Border Grid.Row="2" Grid.Column="0" Grid.RowSpan="2" Margin="3,1,1,3" BorderThickness="2,2,2,2" CornerRadius="4,4,4,4" BorderBrush="LightGray">
<view:SearchView x:Name="SearchView"/>
</Border>
<!-- Project Region -->
<Border Grid.Row="1" Grid.Column="0" Margin="3,3,1,1" BorderThickness="2,2,2,2" CornerRadius="4,4,4,4" BorderBrush="LightGray">
<view:ProjectView x:Name="ProjectView" />
</Border>
<!-- Components Region -->
<Border Grid.Row="1" Grid.Column="1" Grid.RowSpan="2" Margin="1,3,1,1" BorderThickness="2,2,2,2" CornerRadius="4,4,4,4" BorderBrush="LightGray">
<view:ComponentView x:Name="ComponentView" />
</Border>
<!-- Change Request Region -->
<Border Grid.Row="1" Grid.Column="2" Grid.RowSpan="2" Margin="1,3,3,1" BorderThickness="2,2,2,2" CornerRadius="4,4,4,4" BorderBrush="LightGray">
<view:ChangeRequestView x:Name="ChangeRequestView" />
</Border>
<!-- Log Region -->
<Border Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="2" Margin="1,1,3,3" BorderThickness="2,2,2,2" CornerRadius="4,4,4,4" BorderBrush="LightGray">
<view:LogView x:Name="LogView" />
</Border>
</Grid>
<Window.InputBindings>
<KeyBinding Gesture="CTRL+U" Command="{Binding Path=HotKeysUploadCmd}"/>
<KeyBinding Gesture="CTRL+S" Command="{Binding Path=HotKeysSaveChangeRequestUpdateCmd}"/>
<KeyBinding Gesture="CTRL+X" Command="{Binding Path=ShutDownCmd}"/>
</Window.InputBindings>
</Window> </br>
I apologize for the long xaml-files, but I'm thinking the more information I provide to you the easier it will be for you to help me solve this tabbing issue.
Do you have any ideas of how to skip the label "NoComponentChosen"/the stackpanel "ComponentChosen" when I tab through the user interface?
Try KeyboardNavigation.TabNavigation Attached Property with KeyboardNavigationMode.None on the container with the elements you want to skip.
KeyboardNavigation.TabNavigation="None"

WPF: ComboBoxItem background

I have a ComboBox based on XML file data:
<Root>
<Node Background="Yellow" Foreground="Cyan" Image="1.ico" Property="aaaa" Value="28" />
<Node Background="SlateBlue" Foreground="Black" Image="2.ico" Property="bbbb" Value="2.5" />
<Node Background="Teal" Foreground="Green" Image="3.ico" Property="cccc" Value="4.0" />
<Node Background="Yellow" Foreground="Red" Image="4.ico" Property="dddd" Value="0" /></Root>
So, in this case, I need to create a compound ComboBoxItem when each item has a suitable background.
I tried to do something like this:
<UserControl.Resources>
<DataTemplate DataType="Node">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="20"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto" MinWidth="20"/>
</Grid.ColumnDefinitions>
<Border Background="{Binding XPath=#Background}" Grid.Column="0">
<Image Source="{Binding XPath=#Image}"
Width="16"
Height="16"
Margin="3" />
</Border>
<Border Background="{Binding XPath=#Background}" Grid.Column="1">
<TextBlock Foreground="{Binding XPath=#Foreground}"
Margin="3"
Text="{Binding XPath=#Property}" />
</Border>
<Border Background="{Binding XPath=#Background}" Grid.Column="2">
<TextBlock Foreground="{Binding XPath=#Foreground}"
Margin="3"
FontWeight="Bold"
Text="{Binding XPath=#Value}" />
</Border>
</Grid>
</DataTemplate>
<XmlDataProvider x:Key="xmlNodeList"
Source="/data/Combo.xml"
XPath="/Root/Node"/>
</UserControl.Resources>
<ComboBox Name="myComboBox"
ItemsSource="{Binding Source={StaticResource xmlNodeList}}"
SelectedIndex="0" />
but it's not looks good :-(
What solution you recommend?
Thanks in advance!
One thing is that you forgot to indicate which template to use:
<DataTemplate x:Key="Node">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="20"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto" MinWidth="20"/>
</Grid.ColumnDefinitions>
<Border Background="{Binding XPath=#Background}" Grid.Column="0">
<Image Source="{Binding XPath=#Image}"
Width="16"
Height="16"
Margin="3" />
</Border>
<Border Background="{Binding XPath=#Background}" Grid.Column="1">
<TextBlock Foreground="{Binding XPath=#Foreground}"
Margin="3"
Text="{Binding XPath=#Property}" />
</Border>
<Border Background="{Binding XPath=#Background}" Grid.Column="2">
<TextBlock Foreground="{Binding XPath=#Foreground}"
Margin="3"
FontWeight="Bold"
Text="{Binding XPath=#Value}" />
</Border>
</Grid>
</DataTemplate>
And then your ComboBox:
<ComboBox Name="myComboBox"
ItemsSource="{Binding Source={StaticResource xmlNodeList}}"
ItemTemplate="{StaticResource Node}"
SelectedIndex="0" />
The "dataType" system works with typed object, I'm not sure you can make it work with XML data. This will work.
Update:
Before you ask, you should also define a Style for the items so that they cove the width of the list, otherwise your columns are going to be uneven:
<ComboBox Name="myComboBox"
ItemsSource="{Binding Source={StaticResource xmlNodeList}}"
ItemTemplate="{StaticResource Node}"
SelectedIndex="0">
<ComboBox.ItemContainerStyle>
<Style TargetType="{x:Type ComboBoxItem}">
<Setter Property="HorizontalContentAlignment"
Value="Stretch" />
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>
This will stretch the individual items to cover the whole width of the list.

WPF - Maximizing app window does not expand controls vertically - horizontally it does

when I press the Maximize button on my WPF app, all the controls therein expand perfectly horizontally, but they do not expand to fill the window vertically. I figure it Maximize handles it horizontally, it should handle it vertically as well. Should I be setting a property somewhere on each control? I can catch the Resize event, but it seems like a lot of work to go through all the controls and resize them vertically only.
Thank you for your help.
FYI. I ended up changing the Height of the grid to "Auto", and then when the SizeChanged event for the Window1 fired, I set the grid Height to the e.NewSize.Height minus the ActualHeights of the controls in the StackPanel that are above it. Not how I would like it to be, but so far the only solution I found that works.
Thanks.
Can you show us some Xaml? Try setting the outer container to VerticalAlignment="Stretch"
Does the control in question shrink/grow vertically when you resize the window?
You're setting the Height attribute of the Grid to "390", which makes it fixed size vertically. If that's your "parent" control for everything else, they will key from that.
Yes, that is the control that doesn't shrink/grow vertically when I resize the window.
Since I wrote, I changed the grid height to auto, which, when I run my app, the grid, since it is the last control in the StackPanel, takes up only a portion of the remaining space in the window when it is first shown - maybe 80 of the 390. In row 0, column 0, I have a custom panel (theGraphPanel) where I draw nodes in a circle. If I draw say 20 nodes, that cell sizes appropriately, even to take up the entire screen when it is maximized. This somewhat solves the problem, although the vertical scrolling doesn't work because I believe it thinks it has infinite height.
I would like the grid to show up on the screen the way it does when I set the size to 390 - the first row taking up 3* the height of the remaining space and second row taking up * height. I guess what I am trying to do is simulate a MDI set up. I want the proportions to stay the same when I first start the app (800 x 600) and then when I maximize it. From what I can tell, unless the grid cells have content, they will stay at a minimum size and grow to whatever size the content is when the overall grid height is set to "Auto". Perhaps I am trying to do something that is not possible.
Thanks for the answers so far.
The preview window cuts off some of the XAML, but shows up in the answer text box OK. Let me know if it comes across OK or not. The VerticalAlignment="Stretch" doesn't help.
<Window x:Class="MainScreen.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MainScreen"
xmlns:r="clr-namespace:Microsoft.Windows.Controls.Ribbon;assembly=RibbonControlsLibrary"
xmlns:dg="http://schemas.microsoft.com/wpf/2008/toolkit"
WindowStartupLocation="CenterScreen"
Title="Nodes" Height="600" Width="800"
>
<!-- The "toolkit" namespace above is for the data grid control. It's reference is WPFToolkit. -->
<Window.CommandBindings>
<CommandBinding Command="{StaticResource LineTopologyCommand}" Executed="OnLineTopology" />
<CommandBinding Command="{StaticResource PointToPointTopologyCommand}" Executed="OnPointToPointTopology" />
<CommandBinding Command="{StaticResource PointToMultiPointTopologyCommand}" Executed="OnPointToMultiPointTopology" />
<CommandBinding Command="{StaticResource MultiToMultiTopologyCommand}" Executed="OnMultiToMultiTopology" />
<CommandBinding Command="{StaticResource CesTopologyCommand}" Executed="OnCESTopology" />
<CommandBinding Command="{StaticResource AllTopologyCommand}" Executed="OnAllTopology" />
</Window.CommandBindings>
<StackPanel VerticalAlignment="Stretch">
<r:Ribbon Name="mRibbon" DockPanel.Dock="Top">
<r:Ribbon.Resources>
<r:RibbonGroupSizeDefinitionCollection x:Key="ViewLayout">
<r:RibbonGroupSizeDefinition>
<!-- Control sizes: L,L,L -->
<r:RibbonControlSizeDefinition ImageSize="Small" IsLabelVisible="True"/>
<r:RibbonControlSizeDefinition ImageSize="Small" IsLabelVisible="True"/>
<r:RibbonControlSizeDefinition ImageSize="Small" IsLabelVisible="True"/>
<r:RibbonControlSizeDefinition ImageSize="Small" IsLabelVisible="True"/>
<r:RibbonControlSizeDefinition ImageSize="Small" IsLabelVisible="True"/>
<r:RibbonControlSizeDefinition ImageSize="Small" IsLabelVisible="True"/>
</r:RibbonGroupSizeDefinition>
</r:RibbonGroupSizeDefinitionCollection>
</r:Ribbon.Resources>
<r:Ribbon.ApplicationMenu>
<r:RibbonApplicationMenu>
<r:RibbonApplicationMenu.Command>
<r:RibbonCommand
Executed="OnCloseApplication"
LabelDescription="Application Button"
SmallImageSource="Images/SEL.ico"
LargeImageSource="Images/SEL.ico"
ToolTipTitle="SEL Network Management System"
ToolTipDescription="" />
</r:RibbonApplicationMenu.Command>
</r:RibbonApplicationMenu>
</r:Ribbon.ApplicationMenu>
<r:Ribbon.QuickAccessToolBar>
<r:RibbonQuickAccessToolBar CanUserCustomize="True">
</r:RibbonQuickAccessToolBar>
</r:Ribbon.QuickAccessToolBar>
<r:RibbonTab Label="View" MouseLeftButtonUp="RibbonTab_View_MouseLeftButtonUp">
<r:RibbonTab.Groups>
<r:RibbonGroup GroupSizeDefinitions="{StaticResource ViewLayout}">
<r:RibbonGroup.Command>
<r:RibbonCommand LabelTitle="Topology"/>
</r:RibbonGroup.Command>
<r:RibbonButton Command="{StaticResource LineTopologyCommand}"/>
<r:RibbonButton Command="{StaticResource PointToPointTopologyCommand}" />
<r:RibbonButton Command="{StaticResource PointToMultiPointTopologyCommand }" />
<r:RibbonButton Command="{StaticResource MultiToMultiTopologyCommand }" />
<r:RibbonButton Command="{StaticResource CesTopologyCommand }" />
<r:RibbonButton Command="{StaticResource AllTopologyCommand }" />
</r:RibbonGroup>
</r:RibbonTab.Groups>
</r:RibbonTab>
<r:RibbonTab Label="Home" MouseLeftButtonUp="RibbonTab_Home_MouseLeftButtonUp">
</r:RibbonTab>
<r:RibbonTab Label="Device Designer">
</r:RibbonTab>
<r:RibbonTab Label="Network Design">
</r:RibbonTab>
</r:Ribbon>
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" HorizontalAlignment="Center">
<StackPanel.Resources>
<Style x:Name="ButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="theBorder" BorderBrush="Gray" BorderThickness="2"
CornerRadius="10" Padding="5" Background="{TemplateBinding Background}">
<ContentPresenter/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="theBorder" Property="BorderBrush" Value="#333333"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="theBorder" Property="Background" Value="#CCCCCC"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</StackPanel.Resources>
<Label Content="Number of Nodes"/>
<TextBox x:Name="NumNodes" HorizontalAlignment="Right" Margin="0,0,6.71,0" Width="30"/>
<Slider
x:Name="uiScaleSlider"
Width="78"
HorizontalAlignment="Left"
VerticalAlignment="Top"
ToolTip="Determines the UI scale factor."
Height="27"
Value=".1" Minimum=".5" Maximum="5"
Orientation="Horizontal"
Ticks="1"
IsSnapToTickEnabled="False"
TickFrequency="1"
TickPlacement="BottomRight"
AutoToolTipPlacement="BottomRight"
AutoToolTipPrecision="2" />
<Button Name="AddNodes" Content="Add Nodes" Margin="0,0,10,0"/>
<Button Name="Clear" Content="Clear" Margin="0,0,5,0"/>
</StackPanel>
<Grid VerticalAlignment="Stretch" x:Name="mainGrid" Margin="2,5,0,0" Height="390" Background="WhiteSmoke">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="3*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<GridSplitter Grid.Column="0" Grid.RowSpan="2" Width="5" ResizeDirection="Columns" Grid.ColumnSpan="1" Height="Auto" ResizeBehavior="BasedOnAlignment" VerticalAlignment="Stretch"/>
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<local:Graph x:Name="theGraphPanel" Background="#FFE7CEBF" Grid.Column="0" Grid.Row="0" Margin="2,2,2,2">
<local:Graph.LayoutTransform>
<ScaleTransform
CenterX="0" CenterY="0"
ScaleX="{Binding Path=Value, ElementName=uiScaleSlider}"
ScaleY="{Binding Path=Value, ElementName=uiScaleSlider}"
/>
</local:Graph.LayoutTransform>
</local:Graph>
</ScrollViewer>
<TabControl x:Name="mTabControl" Grid.Column="1" Grid.RowSpan="2" Margin="3,0,0,2">
<TabItem Name="Item1" Header="Circuit">
<TreeView>
<TreeViewItem Header="Ring1">
<TreeViewItem Header="Site 1">
<TreeViewItem Header="Node 1">
Data (#113)
</TreeViewItem>
<TreeViewItem Header="Node 2">
Data (#114)
</TreeViewItem>
<TreeViewItem Header="Node 3">
Data (#115)
</TreeViewItem>
</TreeViewItem>
<TreeViewItem Header="Site 2">
</TreeViewItem>
</TreeViewItem>
<TreeViewItem Header="Ring 2">
<TreeViewItem Header="Site 2">
<TreeViewItem Header="Node 1">
Data (#7)
</TreeViewItem>
</TreeViewItem>
</TreeViewItem>
</TreeView>
</TabItem>
<TabItem Name="Item2" Header="Inventory"></TabItem>
</TabControl>
<GridSplitter Grid.Row="1" ResizeDirection="Rows" ResizeBehavior="BasedOnAlignment" HorizontalAlignment="Stretch" Name="GridSplitter1" Height="5" VerticalAlignment="Top" />
</Grid>
</StackPanel>
</Window>
Why not just use nested grids
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition Height="33"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120"></ColumnDefinition>
<ColumnDefinition Width="200"></ColumnDefinition>
<ColumnDefinition Width="3"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<GridSplitter Grid.Column="2" Grid.Row="0"
Height="Auto" Width="Auto" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" />
<Grid Grid.Column="0" Margin="4,10,2,0" Grid.Row="0" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="20"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0" Style="{StaticResource HeaderText}" FontSize="13" >Templates</TextBlock>
<ListBox Grid.Column="0" Grid.Row="1" FontSize="13" >
<ListBoxItem>
Blank
</ListBoxItem>
<ListBoxItem>
New from existing...
</ListBoxItem>
</ListBox>
</Grid>
<ListView Grid.Column="1" Style="{StaticResource MyView}" Grid.Row="0" Margin="2,10,2,0">
<ListViewItem>item1</ListViewItem>
</ListView>
<ListView Grid.Column="3" Style="{StaticResource MyView}" Grid.Row="0" Margin="2,10,4,0">
<ListViewItem>item1</ListViewItem>
</ListView>
<WrapPanel Grid.Row="1" Grid.Column="3" HorizontalAlignment="Right">
<Button Height="22" Width="60">Create</Button>
<Button Height="22" Width="60">Cancel</Button>
</WrapPanel>
</Grid>

Resources