WPF Cannot make the passwordbox element corners rounded - c#

I am trying to to get my PasswordBox corners rounded to make it look more modern. I have successfully done so with my button and TexBlock. However attempting to do so with my PasswordBox does not yield the same results that I desire.
The xaml code for the PasswordBox looks like this
<PasswordBox
Grid.Column="1"
Grid.Row="5"
x:Name="paswordinput"
Margin="170,0,0,0">
<PasswordBox.Resources>
<Style TargetType="Border">
<Setter Property="CornerRadius" Value="8"></Setter>
</Style>
</PasswordBox.Resources>
</PasswordBox>
the same code worked for my TextBox and my Button. Any help would greatly be appreciated!

The PasswordBox control clears the Style of the Border so you should set the local value of the CornerRadius property in the template:
<PasswordBox
Grid.Column="1"
Grid.Row="5"
x:Name="paswordinput"
Margin="170,0,0,0">
<PasswordBox.Style>
<Style TargetType="{x:Type PasswordBox}">
<Style.Resources>
<Style TargetType="Border">
<Setter Property="CornerRadius" Value="8" />
</Style>
</Style.Resources>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type PasswordBox}">
<Border x:Name="border" CornerRadius="8" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="#FF7EB4EA"/>
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="#FF569DE5"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsInactiveSelectionHighlightEnabled" Value="true"/>
<Condition Property="IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="SelectionBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
</MultiTrigger>
</Style.Triggers>
</Style>
</PasswordBox.Style>
</PasswordBox>

Hope this blog post will help - https://www.kailashsblogs.com/2017/01/round-corner-passwordbox-in-wpf.html
Use the below code -
<PasswordBox Margin="10" Height="50" Width="200">
<PasswordBox.Template>
<ControlTemplate TargetType="PasswordBox">
<Border CornerRadius="10" BorderBrush="Gray" BorderThickness="1" />
</ControlTemplate>
</PasswordBox.Template>
</PasswordBox>

You could also try to use the following code to set rounded corners for Password. For more details, please refer to here.
<PasswordBox x:Name="paswordinput" Width="100" Height="50">
<PasswordBox.Resources>
<Style TargetType="PasswordBox">
<Setter Property="Template" >
<Setter.Value>
<ControlTemplate>
<Border CornerRadius="10" BorderBrush="Gray" BorderThickness="2" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</PasswordBox.Resources>
</PasswordBox>

Related

Change BorderBrush when button IsPressed

I'm creating a WPF application for a touchscreen.
There should be a button on the screen with an Icon (image).
The code below shows how the button should look like.
So far so good..
What I would like to achieve is that when you press the button, the first BorderBrush color should change from “#0070b8” to “#00395c” and the second BorderBrush color should change from “#e3e3e3” to “#727272”.
Could someone please help me how to achieve this?
<Button Width="64" Height="64" Grid.Row="1" Margin="1,1" HorizontalAlignment="Left" VerticalAlignment="Top">
<Image Source="Resources\Home_Icon_2.bmp" Width="54" Height="54"></Image>
<Button.Style>
<Style TargetType="{x:Type Button}" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ButtonBase}">
<Border CornerRadius="6" Background="{TemplateBinding Background}" Name="button" Width="64">
<Grid>
<Border BorderThickness="0,0,2,2" BorderBrush="#0070b8" CornerRadius="{Binding ElementName=button, Path=CornerRadius}">
<Border.Effect>
<BlurEffect Radius="1" KernelType="Gaussian"/>
</Border.Effect>
</Border>
<Border BorderThickness="2,2,0,0" BorderBrush="#e3e3e3" Opacity="0.5" CornerRadius="{Binding ElementName=button, Path=CornerRadius}">
<Border.Effect>
<BlurEffect Radius="1" KernelType="Gaussian"/>
</Border.Effect>
</Border>
<ContentPresenter TextBlock.FontSize="{TemplateBinding FontSize}" TextBlock.FontFamily="{TemplateBinding FontFamily}" TextBlock.Foreground="{TemplateBinding Foreground}" VerticalAlignment="Center" HorizontalAlignment="Center" Content="{TemplateBinding Content}"></ContentPresenter>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="button" Property="Background" Value="#e3e3e3" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Background" Value="#c6c3c6" />
</Style>
</Button.Style>
</Button>
You could always set the brush color in your click event:
private void btnYourButton_Click(object sender, RoutedEventArgs e)
{
btnYourButton.BorderBrush = (Brush)new BrushConverter().ConvertFrom("#00395c");
}
This would be one solution. Note that we've assigned our brushes to separate resources so that we don't have magic numbers in our style. This is ideal for when you need to use the same colour scheme across multiple controls, and saves a lot of time when you want to change said colour scheme.
<Style x:Key="AdtakrButton" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="ButtonBorder" CornerRadius="5" BorderThickness="{DynamicResource AdtakrButtonBorderThickness}" BorderBrush="{DynamicResource AdtakrBlack}" Background="{DynamicResource AdtakrWhite}" Margin="{DynamicResource ButtonMargin}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Margin="6,0,6,0" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{DynamicResource AdtakrGrey2}"/>
<Setter Property="BorderBrush" Value="{DynamicResource AdtakrGrey2}" TargetName="ButtonBorder"/>
<Setter Property="Background" Value="{DynamicResource AdtakrGrey1}" TargetName="ButtonBorder"/>
<Setter Property="Visibility" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{DynamicResource AdtakrGrey2}" TargetName="ButtonBorder"/>
<Setter Property="BorderBrush" Value="{DynamicResource AdtakrGrey2}" TargetName="ButtonBorder"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="{DynamicResource AdtakrLightBlue}" TargetName="ButtonBorder"/>
<Setter Property="BorderBrush" Value="{DynamicResource AdtakrLightBlue}" TargetName="ButtonBorder"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="FontSize" Value="{DynamicResource AdtakrDefFontSize}"/>
<Setter Property="MinWidth" Value="90"/>
<Setter Property="Height" Value="40"/>
<Setter Property="ToolTipService.ShowOnDisabled" Value="True"/>
</Style>
If you need to have it change between more than 1 colour, then your best bet is to have a command on your databound VM and the command changes a colour property that the button also binds to. Alternatively, if it's supposed to reflect 3 states, using a toggle button with the three state option is probably your better bet, as then you can set triggers against the IsChecked property of the button.
Found the solution!
By giving the borders a name and then they are accessible in the Trigger Property
<Button Width="64" Height="64" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Top">
<Image Source="Images\Home_Icon_2.png" Width="54" Height="54"></Image>
<Button.Style>
<Style TargetType="{x:Type Button}" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ButtonBase}">
<Border x:Name="button" CornerRadius="6" Background="{TemplateBinding Background}" Width="64">
<Grid>
<Border x:Name="border1" BorderThickness="0,0,2,2" BorderBrush="#0070b8" CornerRadius="{Binding ElementName=button, Path=CornerRadius}">
<Border.Effect>
<BlurEffect Radius="1" KernelType="Gaussian"/>
</Border.Effect>
</Border>
<Border x:Name="border2" BorderThickness="2,2,0,0" BorderBrush="#e3e3e3" Opacity="0.5" CornerRadius="{Binding ElementName=button, Path=CornerRadius}">
<Border.Effect>
<BlurEffect Radius="1" KernelType="Gaussian"/>
</Border.Effect>
</Border>
<ContentPresenter TextBlock.FontSize="{TemplateBinding FontSize}" TextBlock.FontFamily="{TemplateBinding FontFamily}" TextBlock.Foreground="{TemplateBinding Foreground}" VerticalAlignment="Center" HorizontalAlignment="Center" Content="{TemplateBinding Content}"></ContentPresenter>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="button" Property="Background" Value="#e3e3e3" />
<Setter TargetName="border1" Property="BorderBrush" Value="#00395c" />
<Setter TargetName="border2" Property="BorderBrush" Value="#727272" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Background" Value="#c6c3c6" />
</Style>
</Button.Style>
</Button>

TextBox SelectionStart is always 0 with custom style

I have a TextBox input field with a custom style:
<TextBox Style="{StaticResource SettingsTextBoxHint}" KeyDown="textBoxInput_KeyDown" PreviewKeyDown="textBoxInput_PreviewKeyDown" Name="TextBoxInput" Text="{Binding TextBoxInput, Mode=TwoWay}" Tag="{lex:LocText TypeAMessageHere}" VerticalScrollBarVisibility="Auto" TextWrapping="Wrap" FontSize="14" HorizontalAlignment="Stretch" VerticalAlignment="Center" VerticalContentAlignment="Center" BorderThickness="0" Margin="0,0,33,0"/>
To which I added the custom style:
<Style TargetType="{x:Type TextBox}" x:Key="SettingsTextBoxHint" BasedOn="{StaticResource {x:Type TextBox}}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Border x:Name="Border"
BorderThickness="{TemplateBinding BorderThickness}"
Background="White"
Padding="1,2,5,2"
BorderBrush="{StaticResource PrimaryColor}"
ToolTip="{TemplateBinding ToolTip}">
<Grid>
<TextBox Text="{Binding Path=Text,
RelativeSource={RelativeSource TemplatedParent},
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"
x:Name="textSource"
Background="Transparent"
BorderBrush="Transparent"
TextWrapping="{TemplateBinding TextWrapping}"
Panel.ZIndex="2"
FontSize="12">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Border x:Name="Border"
Background="Transparent"
BorderBrush="Transparent"
CornerRadius="0">
<ScrollViewer x:Name="PART_ContentHost" VerticalAlignment="Center" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TextBox.Style>
</TextBox>
<TextBox Margin="0,3,0,0" BorderThickness="0" Text="{TemplateBinding Tag}" Background="{TemplateBinding Background}" Panel.ZIndex="1">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="FontFamily" Value="{StaticResource RobotoRegularFont}" />
<Setter Property="Foreground" Value="Transparent"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Text, Source={x:Reference textSource}}" Value="">
<Setter Property="Foreground" Value="#cccccc"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="Border" Property="BorderBrush" Value="DarkGray"/>
</Trigger>
<Trigger Property="IsFocused" Value="True">
<Setter TargetName="textSource" Property="FocusManager.FocusedElement" Value="{Binding ElementName=textSource}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The point of which is to make the TextBox transparent and to add hint functionality which text is set trough Tag.
Everything works exactly as I want. The problem I have is that I am writing a new functionality in which I need the position of cursor in the TextBox. But SelectionStart or CaretIndex always return 0 value. If I remove my style I get the correct value.
Can anyone tell me what I missed?
The problem is that you are using a TextBox within a TextBox. The user interacts with the inner text box, whose text, caret position, etc. are in no way related to the outer text box.
Let me clean up your style for you:
<Style x:Key="SettingsTextBoxHint"
TargetType="{x:Type TextBox}"
BasedOn="{StaticResource {x:Type TextBox}}">
<Setter Property="BorderBrush"
Value="{StaticResource PrimaryColor}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Border x:Name="Border"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
Padding="{TemplateBinding Padding}">
<Grid>
<ScrollViewer x:Name="PART_ContentHost" VerticalAlignment="Center" />
<TextBlock x:Name="Hint"
Margin="3,1"
Text="{TemplateBinding Tag}"
FontStyle="Italic"
Foreground="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"
Visibility="Hidden" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Border"
Property="Background"
Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
<Trigger Property="Text" Value="">
<Setter TargetName="Hint" Property="Visibility" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
To find the cursor position within the TextBox, you can use Mouse.GetPosition(your_text_box). To get the caret position within the text, use the CaretIndex property. Note, however, that CaretIndex is *not* a dependency property, so it does not raise change notifications. Thus, you cannot bind to it and expect the binding target to be updated.

Adjust dropdown arrow margin of WPF TreeView

I have a TreeView which simplified is defined as
<TreeView ItemsSource="{Binding TreeItems}">
<TreeView.Resources>
<DataTemplate DataType="{x:Type models:MyModel}">
<Border Margin="{Binding Margin}" >
<Grid>
<TextBlock Text="{Binding Path=Name}" Margin="3,3,3,3" />
</Grid>
</Border>
</DataTemplate>
</TreeView.Resources>
</TreeView>
It looks like this
As you can see due to the Margin, which is variable, there is space between the items. The problem is the dropdown arrow. It is not centered on the element. Well, it is centered on the element ignoring the margin. How do I adjust the arrow?
Your XAML markup is both incomplete and incorrect: the DataTemplate should be a HierarchicalDataTemplate and it should be placed in a <TreeView.ItemTemplate> tag. This doesn't apply after your edit.
You can apply the margin to the complete TreeViewItem content including the dropdown arrow:
<TreeView ItemsSource="{Binding Items}">
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Setter Property="Margin" Value="{Binding Margin}"/>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding SubItems}">
<Border>
<Grid>
<TextBlock Margin="3,3,3,3"/>
</Grid>
</Border>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
Yes, I know the style below is too lengthy, but give it a try.
Just put it in a separate resource dictionary and merge it.
<TreeView ItemsSource="{Binding TreeItems}" ItemContainerStyle="{StaticResource CenteredExpanderTreeViewItemStyle}">
<TreeView.Resources>
<DataTemplate DataType="{x:Type models:MyModel}">
<Border Margin="{Binding Margin}" >
<Grid>
<TextBlock Text="{Binding Path=Name}" Margin="3,3,3,3" />
</Grid>
</Border>
</DataTemplate>
</TreeView.Resources>
</TreeView>
CenteredExpanderTreeViewItemStyle.xaml
<Style x:Key="TreeViewItemFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<SolidColorBrush x:Key="TreeViewItem.TreeArrow.Static.Checked.Fill" Color="#FF595959"/>
<SolidColorBrush x:Key="TreeViewItem.TreeArrow.Static.Checked.Stroke" Color="#FF262626"/>
<SolidColorBrush x:Key="TreeViewItem.TreeArrow.MouseOver.Stroke" Color="#FF27C7F7"/>
<SolidColorBrush x:Key="TreeViewItem.TreeArrow.MouseOver.Fill" Color="#FFCCEEFB"/>
<SolidColorBrush x:Key="TreeViewItem.TreeArrow.MouseOver.Checked.Stroke" Color="#FF1CC4F7"/>
<SolidColorBrush x:Key="TreeViewItem.TreeArrow.MouseOver.Checked.Fill" Color="#FF82DFFB"/>
<PathGeometry x:Key="TreeArrow" Figures="M0,0 L0,6 L6,0 z"/>
<SolidColorBrush x:Key="TreeViewItem.TreeArrow.Static.Fill" Color="#FFFFFFFF"/>
<SolidColorBrush x:Key="TreeViewItem.TreeArrow.Static.Stroke" Color="#FF818181"/>
<Style x:Key="ExpandCollapseToggleStyle" TargetType="{x:Type ToggleButton}">
<Setter Property="Focusable" Value="False"/>
<Setter Property="Width" Value="16"/>
<Setter Property="Height" Value="16"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border Background="Transparent" Height="16" Padding="5,5,5,5" Width="16">
<Path x:Name="ExpandPath" Data="{StaticResource TreeArrow}" Fill="{StaticResource TreeViewItem.TreeArrow.Static.Fill}" Stroke="{StaticResource TreeViewItem.TreeArrow.Static.Stroke}">
<Path.RenderTransform>
<RotateTransform Angle="135" CenterY="3" CenterX="3"/>
</Path.RenderTransform>
</Path>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="RenderTransform" TargetName="ExpandPath">
<Setter.Value>
<RotateTransform Angle="180" CenterY="3" CenterX="3"/>
</Setter.Value>
</Setter>
<Setter Property="Fill" TargetName="ExpandPath" Value="{StaticResource TreeViewItem.TreeArrow.Static.Checked.Fill}"/>
<Setter Property="Stroke" TargetName="ExpandPath" Value="{StaticResource TreeViewItem.TreeArrow.Static.Checked.Stroke}"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Stroke" TargetName="ExpandPath" Value="{StaticResource TreeViewItem.TreeArrow.MouseOver.Stroke}"/>
<Setter Property="Fill" TargetName="ExpandPath" Value="{StaticResource TreeViewItem.TreeArrow.MouseOver.Fill}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True"/>
<Condition Property="IsChecked" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Stroke" TargetName="ExpandPath" Value="{StaticResource TreeViewItem.TreeArrow.MouseOver.Checked.Stroke}"/>
<Setter Property="Fill" TargetName="ExpandPath" Value="{StaticResource TreeViewItem.TreeArrow.MouseOver.Checked.Fill}"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="CenteredExpanderTreeViewItemStyle" TargetType="{x:Type TreeViewItem}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="Padding" Value="1,0,0,0"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="FocusVisualStyle" Value="{StaticResource TreeViewItemFocusVisual}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TreeViewItem}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="19" Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<ToggleButton x:Name="Expander" VerticalAlignment="Center" ClickMode="Press" IsChecked="{Binding IsExpanded, RelativeSource={RelativeSource TemplatedParent}}" Style="{StaticResource ExpandCollapseToggleStyle}"/>
<Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.Column="1" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
<ContentPresenter x:Name="PART_Header" ContentSource="Header" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
<ItemsPresenter x:Name="ItemsHost" Grid.ColumnSpan="2" Grid.Column="1" Grid.Row="1"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="false">
<Setter Property="Visibility" TargetName="ItemsHost" Value="Collapsed"/>
</Trigger>
<Trigger Property="HasItems" Value="false">
<Setter Property="Visibility" TargetName="Expander" Value="Hidden"/>
</Trigger>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}}"/>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="VirtualizingPanel.IsVirtualizing" Value="true">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
Use given style for TreeViewItem like give below
<Style TargetType="TreeViewItem" BasedOn="{StaticResource {x:Type TreeViewItem}}">
<Setter Property="Margin" Value="3,3,3,3"></Setter>
</Style>
Hope this help.
To add a margin to the ToggleButton in a TreeView, you have to add a custom ControlTemplate. There are several good tutorials on MSDN, for example here: https://msdn.microsoft.com/de-de/library/ms788727(v=vs.85).aspx
I stripped one example down to the necessary elements to match your requirements. Please note, that the ToggleButton is this example is not styled at all, so it appears a normal Button would do. But I am sure, you find several good examples on how to style this Button in a way that suites you the best.
The code:
<Window.Resources>
<Style x:Key="TreeViewItemStyle" TargetType="{x:Type TreeViewItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TreeViewItem}">
<Grid Margin="{Binding Margin}">
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="20" Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<ToggleButton Grid.Column="0" x:Name="Expander" ClickMode="Press" IsChecked="{Binding IsExpanded, RelativeSource={RelativeSource TemplatedParent}}" />
<Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.Row="0" Grid.Column="1" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
<ContentPresenter x:Name="PART_Header" ContentSource="Header" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
<ItemsPresenter x:Name="ItemsHost" Grid.ColumnSpan="2" Grid.Column="1" Grid.Row="1" Margin="-10,0,0,0"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="false">
<Setter Property="Visibility" TargetName="ItemsHost" Value="Collapsed"/>
</Trigger>
<Trigger Property="HasItems" Value="false">
<Setter Property="Visibility" TargetName="Expander" Value="Hidden"/>
</Trigger>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="VirtualizingStackPanel.IsVirtualizing" Value="true">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<TreeView ItemsSource="{Binding TreeItems}" ItemContainerStyle="{StaticResource TreeViewItemStyle}">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type library:MyModel}" ItemsSource="{Binding Children}" >
<TextBlock Text="{Binding Name}"></TextBlock>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
You should be able to do just this:
<Style TargetType="{x:Type TreeViewItem}" BasedOn="{StaticResource {x:Type TreeViewItem}}">
<Setter Property="Margin" Value="0,0,0,0" />
<!--Or edit Padding if Margin doesn't work-->
</Style>
It will use default style of a TreeViewItem and edit only defined properties. If you use explicitly defined style for TreeViewItem, use BaseOn="{StaticResource [YourStyleKey]}" (without [ ]).
If you need some more advanced styling I'd suggest you to use Blend to get the ControlTemplate of a TreeViewItem, then just edit it to your needs, without changing too much (keep in mind that names of controls used as a template may have a crucial meaning, so be careful what you are editing).
If you don't know how to use Blend to get your control's template, here is a simple tutorial described in a documentation of Telerik controls (don't worry, it works the same for all controls). You just need to create copy of a TreeViewItem ControlTemplate, paste it to your application and you are good to go (editing).
By using Blend you can get templates of all building blocks of a TreeView control and make them look like you want them to. You just need to do some digging.

Styling Multiple Menus in WPF

I'm new to WPF and am trying to figure out how to customize menus for a Windows 7 touch screen application. I'm using the xaml below that was taken from another question on StackOverflow to style one of the menus. I now want to style another menu that will be used in a different way. How would I style another menu of the same type?
If the answer should be simple / something I should be able to figure out, please post a link to where I can read on how to do this type of thing. I've been reviewing MSDN for a while now and while I'm reading all sorts of stuff I already know, I'm not seeing anything helpful for me here. (Sorry, just discouraged by the constant battle to find basic information I need to complete a simple task.)
<Window.Resources>
<Style TargetType="ContextMenu">
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Grid.IsSharedSizeScope" Value="true"/>
<Setter Property="HasDropShadow" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContextMenu">
<Border
Name="Border"
BorderThickness="1"
BorderBrush="{DynamicResource userContextMenuBorder}"
Background="{DynamicResource userContextMenuBackground}"
MinWidth="182"
MinHeight="60"
>
<StackPanel IsItemsHost="True"
KeyboardNavigation.DirectionalNavigation="Cycle"
>
</StackPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="HasDropShadow" Value="true">
<Setter TargetName="Border" Property="Padding" Value="0,3,0,3"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- SimpleStyles: MenuItem -->
<Style x:Key="{x:Static MenuItem.SeparatorStyleKey}" TargetType="{x:Type Separator}">
<Setter Property="Height" Value="1"/>
<Setter Property="Margin" Value="0,4,0,4"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Separator}">
<Border BorderBrush="{DynamicResource userContextMenuSeparatorBorder}" BorderThickness="1"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- TopLevelHeader -->
<ControlTemplate x:Key="{x:Static MenuItem.TopLevelHeaderTemplateKey}" TargetType="{x:Type MenuItem}">
<Border Name="Border" >
<Grid>
<ContentPresenter
Margin="6,3,6,3"
ContentSource="Header"
RecognizesAccessKey="True" />
<Popup
Name="Popup"
Placement="Bottom"
IsOpen="{TemplateBinding IsSubmenuOpen}"
AllowsTransparency="True"
Focusable="False"
PopupAnimation="Fade">
<Border
Name="SubmenuBorder"
SnapsToDevicePixels="True"
Background="{DynamicResource userCMSubmenuBackground}"
BorderBrush="{DynamicResource userCMSubmenuBorder}"
BorderThickness="1" >
<StackPanel
IsItemsHost="True"
KeyboardNavigation.DirectionalNavigation="Cycle" />
</Border>
</Popup>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSuspendingPopupAnimation" Value="true">
<Setter TargetName="Popup" Property="PopupAnimation" Value="None"/>
</Trigger>
<Trigger Property="IsHighlighted" Value="true">
<Setter TargetName="Border" Property="Background" Value="{DynamicResource userContextMenuHighlightedBackground}"/>
<Setter TargetName="Border" Property="BorderBrush" Value="{DynamicResource userContextMenuHighlightedBorder}"/>
</Trigger>
<Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="True">
<Setter TargetName="SubmenuBorder" Property="CornerRadius" Value="0,0,4,4"/>
<Setter TargetName="SubmenuBorder" Property="Padding" Value="0,0,0,3"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{DynamicResource userContextMenuForeground}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<!-- SubmenuHeader -->
<ControlTemplate
x:Key="{x:Static MenuItem.SubmenuHeaderTemplateKey}"
TargetType="{x:Type MenuItem}">
<Border Name="Border" Background="{DynamicResource userCMSubmenuHeaderBackground}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Icon"/>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Shortcut"/>
<ColumnDefinition Width="13"/>
</Grid.ColumnDefinitions>
<ContentPresenter
Name="Icon"
Margin="6,0,6,0"
VerticalAlignment="Center"
ContentSource="Icon"/>
<ContentPresenter
Name="HeaderHost"
Grid.Column="1"
ContentSource="Header"
RecognizesAccessKey="True"/>
<TextBlock x:Name="InputGestureText"
Grid.Column="2"
Text="{TemplateBinding InputGestureText}"
Margin="5,2,2,2"
DockPanel.Dock="Right"/>
<Path
Grid.Column="3"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="M 0 0 L 0 7 L 4 3.5 Z"
Fill="#404040" />
<Popup
Name="Popup"
Placement="Right"
HorizontalOffset="-4"
IsOpen="{TemplateBinding IsSubmenuOpen}"
AllowsTransparency="True"
Focusable="False"
PopupAnimation="Fade">
<Border
Name="SubmenuBorder"
SnapsToDevicePixels="True"
Background="#FFFFFF"
BorderBrush="#888888"
BorderThickness="1" >
<StackPanel
IsItemsHost="True"
KeyboardNavigation.DirectionalNavigation="Cycle" />
</Border>
</Popup>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Icon" Value="{x:Null}">
<Setter TargetName="Icon" Property="Visibility" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsHighlighted" Value="true">
<Setter TargetName="Border" Property="Background">
<Setter.Value>
<LinearGradientBrush>
<GradientStop Color="#EEEEEE" Offset="0"/>
<GradientStop Color="#FFFFFF" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
<Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="True">
<Setter TargetName="SubmenuBorder" Property="CornerRadius" Value="4"/>
<Setter TargetName="SubmenuBorder" Property="Padding" Value="0,3,0,3"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#888888"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<!-- MenuItem Style -->
<Style x:Key="{x:Type MenuItem}" TargetType="{x:Type MenuItem}">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Style.Triggers>
<Trigger Property="Role" Value="TopLevelHeader">
<Setter Property="Template" Value="{StaticResource {x:Static MenuItem.TopLevelHeaderTemplateKey}}"/>
<Setter Property="Grid.IsSharedSizeScope" Value="true"/>
</Trigger>
<Trigger Property="Role" Value="TopLevelItem">
<Setter Property="Template" Value="{StaticResource {x:Static MenuItem.TopLevelItemTemplateKey}}"/>
</Trigger>
<Trigger Property="Role" Value="SubmenuHeader">
<Setter Property="Template" Value="{StaticResource {x:Static MenuItem.SubmenuHeaderTemplateKey}}"/>
</Trigger>
<Trigger Property="Role" Value="SubmenuItem">
<Setter Property="Template" Value="{StaticResource {x:Static MenuItem.SubmenuItemTemplateKey}}"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
Give your styles different keys:
<Style TargetType="ContextMenu" x:Key="MyStyle1">
</Style>
<Style TargetType="ContextMenu" x:Key="MyStyle2">
</Style>
You then need to specify which style you want your ContextMenu to use
<ContextMenu Style="{StaticResource MyStyle1}"></ContextMenu>
<ContextMenu Style="{StaticResource MyStyle2}"></ContextMenu>
If you had any shared style for these ContextMenus, you could do this:
<Style TargetType="ContextMenu" x:Key="BaseStyle"></Style
<Style TargetType="ContextMenu" x:Key="MyStyle1" BasedOn="{StaticResource BaseStyle}">
</Style>
<Style TargetType="ContextMenu" x:Key="MyStyle2" BasedOn="{StaticResource BaseStyle}">
</Style>
MyStyle1 and MyStyle2 would then inherit any styles from BaseStyle
All the information I provided could be found here:
http://msdn.microsoft.com/en-us/library/ms745683(v=vs.110).aspx
I ended up defining the styles for the child objects in the styles style.resources.
<Style TargetType="ContextMenu" x:Key="UserMenu">
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Grid.IsSharedSizeScope" Value="true"/>
<Setter Property="HasDropShadow" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContextMenu">
<Border
Name="Border"
BorderThickness="1"
BorderBrush="{DynamicResource userContextMenuBorder}"
Background="{DynamicResource userContextMenuBackground}"
MinWidth="182"
MinHeight="60"
>
<StackPanel IsItemsHost="True"
KeyboardNavigation.DirectionalNavigation="Cycle"
>
</StackPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="HasDropShadow" Value="true">
<Setter TargetName="Border" Property="Padding" Value="0,3,0,3"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Resources>
<!-- SimpleStyles: MenuItem -->
<Style TargetType="{x:Type Separator}">
<Setter Property="Height" Value="1"/>
<Setter Property="Margin" Value="0,4,0,4"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Separator}">
<Border BorderBrush="{DynamicResource userContextMenuSeparatorBorder}" BorderThickness="1"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Style>

Change the Button contents in XAML on trigger

I'm trying to make a template that will change a Button's background as well as the color of it's TextBlock. I tried the following XAML in my template, but it just makes the button dissapear on mouseover. Is there any way to change the properties of a buttons contents on triggers?
<ControlTemplate TargetType="{x:Type Button}">
<Border
x:Name="Border"
CornerRadius="0"
BorderThickness="0"
Background="{x:Null}"
BorderBrush="#FF404040" />
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="Border" Property="Background" Value="White" />
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate DataType="TextBlock">
<TextBlock Foreground="Blue" />
</DataTemplate>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
Style:
<Style TargetType="{x:Type Button}" x:Key="MyButton">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="Border"
CornerRadius="0"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
TextBlock.Foreground="{TemplateBinding Foreground}"
BorderBrush="#FF404040">
<ContentPresenter Margin="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="Border" Property="Background" Value="White" />
<Setter TargetName="Border" Property="TextBlock.Foreground" Value="Blue" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Usage:
<Button Width="100" Height="50" Content="Lalala" Style="{StaticResource MyButton}" Background="Brown" Foreground="Green" BorderThickness="2"></Button>
You're missing the ContentPresenter, responsible for visualizing the Content property of the Button.
To set the foreground you can use TextBlock.Foreground attached property.
Control Styles and Templates has always been very usefull to me :)

Categories