WPF - How to skip a label in tab navigation? - wpf

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"

Related

How to resize button content in WPF with a viewbox while maintaining the Font size?

I am creating an app and I need the content of a button to be resizable when the user minimises their screen. We know that the viewbox does this in WPF; it's the easiest way to resize text automatically.
This is the code for [the top part] of the button, I apologise about the formatting:
<Button Grid.Row="0"
Grid.Column="2"
Background="#3767B0"
Style="{DynamicResource IconStyle}"
BorderBrush="Transparent">
<Button.ContentTemplate>
<DataTemplate >
<Viewbox>
<TextBlock></TextBlock>
</Viewbox>
</DataTemplate>
</Button.ContentTemplate>
</Button>
What I want to get out of this is: to use the Viewbox in WPF to resize the content of this button while maintaining the font size of the content.
This resizes the content of the button, but the button's content is not maintained:
This is how it should look like with a viewbox, and should resize properly:
By maintaining I mean I want to use the viewbox whilst the content of the button (which is a child of the viewbox) looks exactly how it would've with a font size of 22. You can see how I want it to look like with a viewbox inside the content of the button in the image above. I've tried to be as clear as possible on this. Maybe I don't understand how the viewbox works?
Someone requested the icon style. Here is the icon style code:
<Style TargetType="Button"
x:Key="IconStyle"
BasedOn="{StaticResource ButtonStyle1}">
<Setter Property="FontFamily"
Value="Segoe MDL2 Assets" />
<Setter Property="Grid.RowSpan"
Value="2" />
<Setter Property="Padding"
Value="0,0,0,60" />
<Setter Property="Foreground"
Value="White" />
<Setter Property="FontSize"
Value="80" />
<Setter Property="Background"
Value="#307A85" />
<Setter Property="BorderBrush"
Value="Transparent" />
<Setter Property="BorderThickness"
Value="0" />
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect BlurRadius="15"
ShadowDepth="0"
Opacity="0.4"
Color="Black" />
</Setter.Value>
</Setter>
If I understand correctly what you need to implement, then remove the ViewBox and set the explicit dimensions of the TextBlock.
I am showing an arbitrary example, but for your task, you yourself choose the required dimensions and alignment.
<Button Background="#3767B0"
Style="{DynamicResource IconStyle}"
BorderBrush="Transparent">
<Button.ContentTemplate>
<DataTemplate >
<TextBlock Width="300"
Height="300"
FontSize="200"
Text=""/>
</DataTemplate>
</Button.ContentTemplate>
</Button>
Hello my good friends on Stack OverFlow. I have found a solution to this problem, all I had to do was set the padding of the TextBlock:
<!--FEEDBACK BUTTON-->
<Button Grid.Row="3"
Grid.Column="2"
Grid.RowSpan="2"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
BorderThickness="3"
Name="Feedback_Button"
BorderBrush="White"
Click="Button_Click"
MouseEnter="Button_MouseEnter"
MouseLeave="Button_MouseLeave">
<Button.Template>
<ControlTemplate TargetType="Button">
<ContentPresenter Content="{TemplateBinding Content}" />
</ControlTemplate>
</Button.Template>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="218*" />
<RowDefinition Height="68*" />
</Grid.RowDefinitions>
<Button Grid.Row="0"
Grid.Column="2"
Background="#3767B0"
FontFamily="Segoe MDL2 Assets"
Foreground="White"
Content="Feedback"
BorderBrush="Transparent">
<Button.ContentTemplate>
<DataTemplate>
<Viewbox>
<TextBlock Padding="15"></TextBlock>
</Viewbox>
</DataTemplate>
</Button.ContentTemplate>
</Button>
<Button Grid.Row="4"
Grid.Column="2"
Background="#FF2D5BA0"
FontFamily="Segoe UI Light"
Style="{StaticResource TextButton}"
Content="Feedback"
BorderBrush="Transparent">
<Button.ContentTemplate>
<DataTemplate>
<Viewbox>
<TextBlock Padding="15">Feedback</TextBlock>
</Viewbox>
</DataTemplate>
</Button.ContentTemplate>
</Button>
</Grid>
</Button>
<!--FEEDBACK BUTTON-->
Thank you my friends for your help, such a simple solution I would've expected you guys to know this.
Cheers,
#Tom Joney , I do not quite clearly understand what you need to implement, so I cannot give an exact answer.
General answer for using different layout.
The ViewBox scales the content to the maximum allowed size provided by the outer container.
The Padding property of a container sets the size of the border between the container and its contents.
The element's Margin property sets the size of the border between the element and its containing container.
That is, these are very close properties.
In our case, the main content is Text.
Therefore, there is no difference how to set the size of the border: between the Text and the containing TextBlock (TextBlock.Padding) or between the TextBlock and its containing outer container (the Grid line).
Look at two examples in which I set the background colors for better clarity.
Example with Padding
<Window x:Class="ViewBoxScaleText.PaddingWind"
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"
xmlns:local="clr-namespace:ViewBoxScaleText"
mc:Ignorable="d"
Title="PaddingWind" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border Background="LightGreen">
<Viewbox>
<TextBlock Padding="15"
Background="LightBlue"
Text="{Binding Text, ElementName=tb}"/>
</Viewbox>
</Border>
<TextBox x:Name="tb" Grid.Row="1" Margin="10" Text="Feedback"/>
</Grid>
</Window>
Example with Margin
<Window x:Class="ViewBoxScaleText.MarginWind"
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"
xmlns:local="clr-namespace:ViewBoxScaleText"
mc:Ignorable="d"
Title="MarginWind" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border Background="LightGreen">
<Viewbox>
<TextBlock Margin="15"
Background="LightBlue"
Text="{Binding Text, ElementName=tb}"/>
</Viewbox>
</Border>
<TextBox x:Name="tb" Grid.Row="1" Margin="10" Text="Feedback"/>
</Grid>
</Window>
The color of the regions shows that the containers have different sizes, but this does not affect the location and size of the Text.
Try to enter text in the field at the bottom of the window to see how the amount of text affects its size and the size of the border.
Since the ViewBox scales the entire content, both the text size size and are the border scaled.
If in the examples above you change the size of the window, you will see that the size of the container occupied by the text also changes.
This happens due to the fact that the setting of the border occurs inside the ViewBox and thus we set the size of the border, in fact, in units relative to the size of the text.
Changing the size of the text will change the size of the face and therefore change the overall container for the text.
Here is an example with the ability to change the font size in the very bottom margin of the window.
See how this affects the size of the border.
<Window x:Class="ViewBoxScaleText.FontSizeWind"
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"
xmlns:local="clr-namespace:ViewBoxScaleText"
mc:Ignorable="d"
Title="FontSizeWind" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border Background="LightGreen">
<Viewbox>
<TextBlock Margin="15"
Background="LightBlue"
Text="{Binding Text, ElementName=tbText}" FontSize="{Binding Text, ElementName=tbFontSize}"/>
</Viewbox>
</Border>
<TextBox x:Name="tbText" Grid.Row="1" Margin="10" Text="Feedback"/>
<TextBox x:Name="tbFontSize" Grid.Row="2" Margin="10" Text="80"/>
</Grid>
</Window>
Here are some more layout options in one XAML so that you can launch, check their behavior and choose the one that suits you
<Window x:Class="ViewBoxScaleText.MultiVariantWind"
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"
xmlns:local="clr-namespace:ViewBoxScaleText"
mc:Ignorable="d"
Title="MultiVariantWind" Height="750" Width="400">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border Background="LightGreen" Margin="5">
<Viewbox>
<TextBlock Margin="15"
Background="LightBlue"
Text="{Binding Text, ElementName=tbText}" FontSize="{Binding Text, ElementName=tbFontSize}"/>
</Viewbox>
</Border>
<Border Background="LightGreen" Margin="5" Grid.Row="1">
<Viewbox Margin="15">
<TextBlock
Background="LightBlue"
Text="{Binding Text, ElementName=tbText}" FontSize="{Binding Text, ElementName=tbFontSize}"/>
</Viewbox>
</Border>
<Border Background="LightGreen" Margin="5" Grid.Row="2">
<Viewbox Width="150" Height="150">
<TextBlock
Background="LightBlue"
Text="{Binding Text, ElementName=tbText}" FontSize="{Binding Text, ElementName=tbFontSize}"/>
</Viewbox>
</Border>
<Border Background="LightGreen" Margin="5" Grid.Row="3">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="15*"/>
<ColumnDefinition Width="70*"/>
<ColumnDefinition Width="15*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="15*"/>
<RowDefinition Height="70*"/>
<RowDefinition Height="15*"/>
</Grid.RowDefinitions>
<Viewbox Grid.Row="1" Grid.Column="1">
<TextBlock
Background="LightBlue"
Text="{Binding Text, ElementName=tbText}" FontSize="{Binding Text, ElementName=tbFontSize}"/>
</Viewbox>
</Grid>
</Border>
<TextBox x:Name="tbText" Grid.Row="4" Margin="10" Text="Feedback"/>
<TextBox x:Name="tbFontSize" Grid.Row="5" Margin="10" Text="80"/>
</Grid>
</Window>

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>

UserControl content is empty when trying to use ContentPresenter inside DataTemplate

I have a main abstract code-only class BaseImpostorButton, inheriting UserControl. I have a child class ClickableImageButton with xaml and code-behind.
I'm using the following style with ControlTemplate :
<Style TargetType="{x:Type local:ClickableImageButton}">
<Setter Property="ToolTipService.InitialShowDelay" Value="0"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ClickableImageButton}">
<StackPanel Margin="{TemplateBinding Margin}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}">
<ContentPresenter
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}" />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
When using in a ListView as raw ListViewItem, my ClickableImageButton shows correctly.
BUT: when using it in a listview with ItemTemplate DataTemplate, the ClickableImageButton is no longer shown... as if the Content was empty when inside a DataTemplate.
The solution i found was to write a DependencyProperty ButtonContent on BaseImpostorButton and set it explicitly in xaml.
But can someone explain this issue ?
EDIT: Here are the 2 different xaml
The one that is correctly showing the underlying image (ClickableImage is an Image)
<ListView Grid.Row="1" Name="ListViewSections" ItemsSource="{Binding Path=Sections}" Background="{x:Null}" SizeChanged="ListViewSections_SizeChanged">
<ListViewItem>
<Grid MaxWidth="600">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition MaxWidth="150"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.ColumnSpan="2" Text="{Binding Path=Titre}" Margin="5,0,5,0" FontSize="18" FontWeight="Bold" Foreground="White" TextWrapping="Wrap" FontFamily="Arial" HorizontalAlignment="Left" />
<local:ClickableImageButton Grid.Row="1" Tag="{Binding Path=Id}" Grid.Column="0" ImpostorClick="Image_Click" Margin="10">
<local:ClickableImageButton.Content>
<local:ClickableImage Source="Content/tada.png" />
</local:ClickableImageButton.Content>
</local:ClickableImageButton>
<TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding Path=Texte}" Margin="10,0,10,0" FontSize="16" Foreground="White" TextWrapping="Wrap" FontFamily="Arial" VerticalAlignment="Center" HorizontalAlignment="Left" />
</Grid>
</ListViewItem>
</ListView>
And the one that's not working
<ListView Grid.Row="1" Name="ListViewSections" ItemsSource="{Binding Path=Sections}" Background="{x:Null}" SizeChanged="ListViewSections_SizeChanged">
<ListView.ItemTemplate>
<DataTemplate>
<Grid MaxWidth="600">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition MaxWidth="150"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.ColumnSpan="2" Text="{Binding Path=Titre}" Margin="5,0,5,0" FontSize="18" FontWeight="Bold" Foreground="White" TextWrapping="Wrap" FontFamily="Arial" HorizontalAlignment="Left" />
<local:ClickableImageButton Grid.Row="1" Tag="{Binding Path=Id}" Grid.Column="0" ImpostorClick="Image_Click" Margin="10">
<local:ClickableImageButton.Content>
<local:ClickableImage Source="Content/tada.png" />
</local:ClickableImageButton.Content>
</local:ClickableImageButton>
<TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding Path=Texte}" Margin="10,0,10,0" FontSize="16" Foreground="White" TextWrapping="Wrap" FontFamily="Arial" VerticalAlignment="Center" HorizontalAlignment="Left" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
So finally i get it to work. That wasn't due to the fact that i was deriving from UserControl.
So i kept deriving BaseImpostorButton from UserControl, i emptyed the ContentPresenter in the ControlTemplate (<ContentPresenter />).
I didn't have to set the DefaultStyleKey.
I just had to remove any content from the child class xaml file. Indeed, when i created my child UserControl, i didn't removed the default content added, that is <Grid />. Removing this just solved all my problems.
Looks like the default Content is not overriden when we try to set it from a templated context, but only when set from a non templated context.
ie Former code:
<sk:BaseImpostorButton x:Class="Compteur_3D.ClickableImageButton"
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="300" d:DesignWidth="300">
<Grid/>
</sk:BaseImpostorButton>
revised code:
<sk:BaseImpostorButton x:Class="Compteur_3D.ClickableImageButton"
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="300" d:DesignWidth="300">
</sk:BaseImpostorButton>
Edit: At runtime, my ClickableImageButton element has the right content (ie ClickableImage) when the <Grid /> is removed. BUT when <Grid /> is not removed, my ClickableImageButton has the empty Grid as content... As if this <Grid /> was not overriden when setting the content in:
<local:ClickableImageButton ImpostorClick="Image_Click" Margin="10">
<local:ClickableImageButton.Content>
<local:ClickableImage Source="{Binding Path=Image.Source}" />
</local:ClickableImageButton.Content>
</local:ClickableImageButton>
Edit: Target Framework 4 Client Profile

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