Problems with DataGridColumnHeader Style - c#

Trying to style my datagrid column headers, I encounter two problems.
What I want : I'd like my headers to be written in a border with the border drawn and a margin. See the picture :
What I get : I found that the border are drawn between 2 headers, plus I can't get rid of the shadow of the grip (white grip, grey shadow), as you as see in the picture
Here is my style for the headers :
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Height" Value="30" />
<Setter Property="SeparatorBrush" Value="{StaticResource ScbWhite}" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Foreground" Value="{StaticResource ScbBlue1}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<Grid Margin="{TemplateBinding Padding}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Border x:Name="columnHeaderBorder"
TextBlock.FontWeight="Bold"
TextBlock.Foreground="{StaticResource ScbBlue1}"
BorderThickness="2"
BorderBrush="{StaticResource ScbBlue1}"
Background="{StaticResource ScbWhite}"
Width="{TemplateBinding Width}"
Margin="3,3,3,3"
Padding="3,0,3,0">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border>
<!--BorderBrush="{Binding VerticalGridLinesBrush, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"-->
<Thumb x:Name="PART_RightHeaderGripper" Grid.Column="1"
HorizontalAlignment="Right"
Width="6" BorderThickness="0"
BorderBrush="{StaticResource ScbWhite}"
Background="{StaticResource ScbWhite}"
Cursor="SizeWE">
<Thumb.BitmapEffect>
<DropShadowBitmapEffect Color="Transparent" Opacity="0"/>
</Thumb.BitmapEffect>
</Thumb>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Please, what can I do to get what I want?

DataGrid adds empty column header to fill space for situations when other columns don't cover full width. That header has null Content. I added a ControlTemplate Trigger to make border transparent for header without content.
To change Thumb apperance I changed Thumb.Template and made it a flat white rectangle
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<Grid Margin="{TemplateBinding Padding}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Border x:Name="columnHeaderBorder"
TextBlock.FontWeight="Bold"
TextBlock.Foreground="blue"
BorderThickness="2"
BorderBrush="blue"
Background="white"
Width="{TemplateBinding Width}"
Margin="3,3,3,3"
Padding="3,0,3,0">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border>
<!--BorderBrush="{Binding VerticalGridLinesBrush, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"-->
<Thumb x:Name="PART_RightHeaderGripper" Grid.Column="1"
HorizontalAlignment="Right"
Width="6" BorderThickness="0"
Margin="0,3"
BorderBrush="white"
Background="white"
Cursor="SizeWE">
<Thumb.Template>
<ControlTemplate>
<Border Background="{TemplateBinding Background}"></Border>
</ControlTemplate>
</Thumb.Template>
</Thumb>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="Content" Value="{x:Null}">
<!--<Setter Property="BorderBrush" Value="Red" TargetName="columnHeaderBorder"/>-->
<Setter Property="BorderBrush" Value="Transparent" TargetName="columnHeaderBorder"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
// I replaced some StaticResources in a template to make my project compile. please restore them back or copy only modified parts of template

Related

WPF Datagrid with multiple Column Header Templates [duplicate]

Trying to style my datagrid column headers, I encounter two problems.
What I want : I'd like my headers to be written in a border with the border drawn and a margin. See the picture :
What I get : I found that the border are drawn between 2 headers, plus I can't get rid of the shadow of the grip (white grip, grey shadow), as you as see in the picture
Here is my style for the headers :
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Height" Value="30" />
<Setter Property="SeparatorBrush" Value="{StaticResource ScbWhite}" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Foreground" Value="{StaticResource ScbBlue1}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<Grid Margin="{TemplateBinding Padding}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Border x:Name="columnHeaderBorder"
TextBlock.FontWeight="Bold"
TextBlock.Foreground="{StaticResource ScbBlue1}"
BorderThickness="2"
BorderBrush="{StaticResource ScbBlue1}"
Background="{StaticResource ScbWhite}"
Width="{TemplateBinding Width}"
Margin="3,3,3,3"
Padding="3,0,3,0">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border>
<!--BorderBrush="{Binding VerticalGridLinesBrush, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"-->
<Thumb x:Name="PART_RightHeaderGripper" Grid.Column="1"
HorizontalAlignment="Right"
Width="6" BorderThickness="0"
BorderBrush="{StaticResource ScbWhite}"
Background="{StaticResource ScbWhite}"
Cursor="SizeWE">
<Thumb.BitmapEffect>
<DropShadowBitmapEffect Color="Transparent" Opacity="0"/>
</Thumb.BitmapEffect>
</Thumb>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Please, what can I do to get what I want?
DataGrid adds empty column header to fill space for situations when other columns don't cover full width. That header has null Content. I added a ControlTemplate Trigger to make border transparent for header without content.
To change Thumb apperance I changed Thumb.Template and made it a flat white rectangle
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<Grid Margin="{TemplateBinding Padding}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Border x:Name="columnHeaderBorder"
TextBlock.FontWeight="Bold"
TextBlock.Foreground="blue"
BorderThickness="2"
BorderBrush="blue"
Background="white"
Width="{TemplateBinding Width}"
Margin="3,3,3,3"
Padding="3,0,3,0">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border>
<!--BorderBrush="{Binding VerticalGridLinesBrush, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"-->
<Thumb x:Name="PART_RightHeaderGripper" Grid.Column="1"
HorizontalAlignment="Right"
Width="6" BorderThickness="0"
Margin="0,3"
BorderBrush="white"
Background="white"
Cursor="SizeWE">
<Thumb.Template>
<ControlTemplate>
<Border Background="{TemplateBinding Background}"></Border>
</ControlTemplate>
</Thumb.Template>
</Thumb>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="Content" Value="{x:Null}">
<!--<Setter Property="BorderBrush" Value="Red" TargetName="columnHeaderBorder"/>-->
<Setter Property="BorderBrush" Value="Transparent" TargetName="columnHeaderBorder"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
// I replaced some StaticResources in a template to make my project compile. please restore them back or copy only modified parts of template

How to Trigger IsFocused on DatePickerTextBox in WPF

I set the Validation.ErrorTemplate property via a DataTrigger. The template includes the Border around my DatePicker and second Border with a TextBlock inside.
I am trying to visible the second Border when DatePickerTextBox IsFocused property is True only.
Below my code I have so far (it is just a shortened version):
<Style x:Key="CustomDatePickerStyle" TargetType="{x:Type DatePicker}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DatePicker}">
<Border Background="{DynamicResource Control.Background}" Padding="0" BorderThickness="0" CornerRadius="3">
<Button x:Name="PART_Button" Grid.Column="1" Foreground="{TemplateBinding Foreground}" Focusable="False" HorizontalAlignment="Left" Margin="3,0,3,0" Grid.Row="0" Template="{StaticResource DropDownButtonTemplate}" VerticalAlignment="Center" Width="20"/>
<DatePickerTextBox x:Name="PART_TextBox" Height="14" Margin="3 0 0 0" Grid.Column="0" Focusable="{TemplateBinding Focusable}"
HorizontalContentAlignment="Stretch" Grid.Row="0" VerticalContentAlignment="Center">
<DatePickerTextBox.Template>
<ControlTemplate TargetType="DatePickerTextBox">
<Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" CornerRadius="3" Opacity="1">
<Grid x:Name="WatermarkContent" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<Border x:Name="ContentElement" BorderBrush="Red" BorderThickness="0"/>
<ScrollViewer x:Name="PART_ContentHost" Background="{TemplateBinding Background}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Border x:Name="FocusVisual" BorderBrush="Red" CornerRadius="3" IsHitTestVisible="False" Opacity="0"/>
</Grid>
</Border>
</ControlTemplate>
</DatePickerTextBox.Template>
</DatePickerTextBox>
</Grid>
</Border>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsReadOnly}" Value="false">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<StackPanel>
<Border BorderThickness="1" BorderBrush="Red" CornerRadius="3" HorizontalAlignment="Left">
<AdornedElementPlaceholder x:Name="textBox"/>
</Border>
<Border Background="{DynamicResource Control.Validation.Background}" BorderBrush="{DynamicResource Control.Validation.Border}" BorderThickness="1" CornerRadius="3" >
<TextBlock Text="{Binding [0].ErrorContent}" Padding="3 0 3 0" Foreground="{DynamicResource Control.Validation.Foreground}" Margin="1"/>
<Border.Style>
<Style>
<Setter Property="Border.Visibility" Value="Collapsed"></Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding AdornedElement.(DatePicker.IsFocused), ElementName=textBox}" Value="True">
<Setter Property="Border.Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I think it is possible by accessing via ElementName = PART_TextBox, Path=IsFocused but I always get the Error: PART_TextBox not found
The DatePicker also has a IsKeyboardFocusWithin Property which is True if the focus is in the Textbox of the DatePicker. This helps out, i had the same problem.
<Style TargetType="DatePicker">
<Style.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="Background" Value="Green"/>
</Trigger>
</Style.Triggers>
</Style>

C# WPF Menu Item Style let the Header disappear

I have set a style for my MenuItems which looks like the following
App.xaml
<Style x:Key="MenuItemHover" TargetType="MenuItem">
<Setter Property="Width" Value="50"></Setter>
<Setter Property="FontFamily" Value="Calibri"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="MenuItem">
<Border x:Name="border"
Background="#282828"
>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="border" Property="Background" Value="Gray"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
MainWindow.xaml
<Menu x:Name="Menu_Dropdown" Width="150" Background="#282828" Foreground="White" HorizontalAlignment="Left" Grid.Column="0" Grid.ColumnSpan="2" Height="25" VerticalAlignment="Top">
<MenuItem x:Name="MenuItem_User" Height="25" Header="Nutzer" Style="{DynamicResource MenuItemHover}"></MenuItem>
<MenuItem x:Name="MenuItem_Kasse" Header="Kasse" Style="{DynamicResource MenuItemHover}"></MenuItem>
<MenuItem x:Name="MenuItem_Design" Header="Design" Style="{DynamicResource MenuItemHover}"></MenuItem>
</Menu>
When I use my style "MenuItemHover" it let the text disappear. The rest is working fine. (so the hover effect itself - it's changing the color when I move my mouse over)
Without using the style the header is getting showed normally.
There are a couple of things to make this code better, let's take a look one by one.
First of all, when you override the template, you need to know that you're not extending, but rather rewrite it; therefore you need to add the "obvious" parts as well, not just the new ones. As Anton says, you need at least one control to display the text itself. See his answer for an example.
Secondly, if you want to use the same style for every MenuItem, it is better to define the Style without a key. That way that's going to be the default style for MenuItems and it will be applied to all of them unless you say explicitly otherwise. (You don't need to add Style="{DynamicResource MenuItemHover}" to every MenuItem tag. Keep in mind that there is a hierarchy of applying styles. For example if you set the font size to 15 in the style, but then you add FontSize="50" to one of the MenuItems explicitly that MenuItem will use the value 50. See more about it here)
Last, but not least I think a good way to do this kind of changes in the styles is opening up Blend, select the control, then create a copy of the original template:
and customize that copy. (As you can see below this is just the ControlTemplate, you need to put this into a style) This way you can be sure you won't lose anything that is there originally.
Example (MenuItem ControlTemplate):
<ControlTemplate x:Key="MenuItemControlTemplate1" TargetType="{x:Type MenuItem}">
<Border x:Name="templateRoot" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<Grid VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ContentPresenter x:Name="Icon" Content="{TemplateBinding Icon}" ContentSource="Icon" HorizontalAlignment="Center" Height="16" Margin="3" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center" Width="16"/>
<Path x:Name="GlyphPanel" Data="F1M10,1.2L4.7,9.1 4.5,9.1 0,5.2 1.3,3.5 4.3,6.1 8.3,0 10,1.2z" Fill="#FF212121" FlowDirection="LeftToRight" Margin="3" Visibility="Collapsed" VerticalAlignment="Center"/>
<ContentPresenter ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Grid.Column="1" ContentStringFormat="{TemplateBinding HeaderStringFormat}" ContentSource="Header" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Icon" Value="{x:Null}">
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Visibility" TargetName="GlyphPanel" Value="Visible"/>
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsHighlighted" Value="True">
<Setter Property="Background" TargetName="templateRoot" Value="#3D26A0DA"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="#FF26A0DA"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="TextElement.Foreground" TargetName="templateRoot" Value="#FF707070"/>
<Setter Property="Fill" TargetName="GlyphPanel" Value="#FF707070"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsHighlighted" Value="True"/>
<Condition Property="IsEnabled" Value="False"/>
</MultiTrigger.Conditions>
<Setter Property="Background" TargetName="templateRoot" Value="#0A000000"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="#21000000"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
The relevant part in your case is:
<Trigger Property="IsHighlighted" Value="True">
<Setter Property="Background" TargetName="templateRoot" Value="#3D26A0DA"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="#FF26A0DA"/>
</Trigger>
You can change the background color here to achieve what you want (I changed it to Red to see it better):
You may want to change the BorderBrush color as well.
Your template should contains ContentPresenter
<Border x:Name="border"Background="#282828" >
<ContentPresenter Content="{TemplateBinding Header}"/>
</Border>
In native template of MenuItem used ContentPresenter and set ContentSource="Header"
<ControlTemplate x:Key="{ComponentResourceKey ResourceId=SubmenuItemTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}" TargetType="{x:Type MenuItem}">
<Border x:Name="templateRoot" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Height="22" SnapsToDevicePixels="true">
<Grid Margin="-1">
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="22" SharedSizeGroup="MenuItemIconColumnGroup" Width="Auto"/>
<ColumnDefinition Width="13"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="30"/>
<ColumnDefinition SharedSizeGroup="MenuItemIGTColumnGroup" Width="Auto"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<ContentPresenter x:Name="Icon" ContentSource="Icon" HorizontalAlignment="Center" Height="16" Margin="3" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center" Width="16"/>
<Border x:Name="GlyphPanel" BorderBrush="{StaticResource MenuItem.Highlight.Border}" BorderThickness="1" Background="{StaticResource MenuItem.Highlight.Background}" HorizontalAlignment="Center" Height="22" Margin="-1,0,0,0" Visibility="Hidden" VerticalAlignment="Center" Width="22">
<Path x:Name="Glyph" Data="{StaticResource Checkmark}" Fill="{StaticResource MenuItem.Selected.Glyph}" FlowDirection="LeftToRight" Height="11" Width="9"/>
</Border>
<!-- ContentPresenter which showing MenuItem.Header -->
<ContentPresenter x:Name="menuHeaderContainer" Grid.Column="2" ContentSource="Header" HorizontalAlignment="Left" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center"/>
<TextBlock x:Name="menuGestureText" Grid.Column="4" Margin="{TemplateBinding Padding}" Opacity="0.7" Text="{TemplateBinding InputGestureText}" VerticalAlignment="Center"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
...
</ControlTemplate.Triggers>
</ControlTemplate>

Reuse ControlTemplate in DataTriggers

I'm using WPF 4.0 to develop windows and want to reuse a ControlTemplate in my Resources for various Label controls.
I define a generic base Label Style with the ControlTemplate and then define derived Label Styles to control colors and label text.
I then apply these styles to data triggers based on a property value.
What I have tried so far throws an IllegalArgument exception: 'Style object is not allowed to affect the Style property of the object to which it applies'.
Is there a valid way to do this?
This is what I have so far that produces the exception:
<Style x:Key="BaseLabelStyle" TargetType="{x:Type Label}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid Background="{TemplateBinding Background}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="24"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="24"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="1"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"
Foreground="{TemplateBinding Foreground}"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="AvailableLabelStyle" TargetType="{x:Type Label}" BasedOn="{StaticResource BaseLabelStyle}">
<Style.Resources>
<Style>
<Setter Property="Label.Background" Value="#FF567E4A"/>
<Setter Property="Label.Foreground" Value="White"/>
<Setter Property="TextBlock.Text" Value="Available"/>
</Style>
</Style.Resources>
</Style>
I want to expand the derived styles to define other color and label text changes.
This derived Style is applied here:
<Label x:Name="Avail_Out_LBL"
HorizontalAlignment="Left" Margin="111,44,0,0"
VerticalAlignment="Top" Width="124" Height="18"
VerticalContentAlignment="Center"
HorizontalContentAlignment="Center" SnapsToDevicePixels="False"
Grid.Column="1" Padding="0">
<Label.Style>
<Style TargetType="{x:Type Label}">
<Style.Triggers>
<DataTrigger Binding="{Binding MonitorAndControlData.Availability}" Value="Available">
<Setter Property="Style" Value="{StaticResource AvailableLabelStyle}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Label.Style>
</Label>
The exception points to the closing /DataTrigger in the Label. I can't tell if the problem is in the Style's use or in the definition up top in the Resources.
Any help would be greatly appreciated.
The problem is that you are trying to change the style from the style, which is not permitted.
What I would do in your situation is create a custom UserControl for your label, which would look like this :
<UserControl ...>
<UserControl.Resources>
<Style TargetType="{x:Type Label}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid Background="{TemplateBinding Background}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="24"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="24"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="1"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"
Foreground="{TemplateBinding Foreground}"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"/>
</Grid>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding Availability, RelativeSource={RelativeSource AncestorType={x:Type theTypeOfYourControl}}}" Value="Available">
<Setter Property="Label.Background" Value="#FF567E4A"/>
<Setter Property="Label.Foreground" Value="White"/>
<Setter Property="TextBlock.Text" Value="Available"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Label x:Name="Avail_Out_LBL"
HorizontalAlignment="Left" Margin="111,44,0,0"
VerticalAlignment="Top" Width="124" Height="18"
VerticalContentAlignment="Center"
HorizontalContentAlignment="Center" SnapsToDevicePixels="False"
Grid.Column="1" Padding="0"/>
</UserControl>
The setters in the trigger are probably not good, you'll have to target the right property to make it work. Also, you will need to make a dependency property named Availability or any other relevant name (I just used the name in your binding) to expose it outside the UserControl. You will need to bind to this DependencyProperty when using your UserControl.
Here are some links on how to do it, with more détails :
http://www.codeproject.com/Articles/32825/How-to-Creating-a-WPF-User-Control-using-it-in-a-W
http://www.wpftutorial.net/dependencyproperties.html

Styling a WPF Button content with auto Texttrimming with Image or only text for localization

I have following Button in my c#WPF 3.5 .NET Application
<Button Height="23" x:Name="btnImportKvf" Width="75" Click="btnImportKvf_Click" IsEnabled="True" ToolTip="Click to Import" Content="Import KVF" />
My button style template applied in ResourceDirectory App.xaml as following
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Luna">
<!-- Focus Visual -->
<Style x:Key="ButtonFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Border>
<Rectangle
Margin="2"
StrokeThickness="1"
Stroke="#60000000"
StrokeDashArray="1 2"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- SimpleStyles: Button -->
<Style TargetType="Button">
<!--Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/-->
<Setter Property="Foreground" Value="{StaticResource GlyphLightBrush}"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border" Background="{DynamicResource BackgroundNormal}" BorderThickness="1,1,1,2" CornerRadius="4,4,4,4" BorderBrush="{DynamicResource GlyphDarkBrush}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="0.507*"/>
<RowDefinition Height="0.493*"/>
</Grid.RowDefinitions>
<Border Opacity="0" HorizontalAlignment="Stretch" x:Name="glow" Width="Auto" Grid.RowSpan="2" CornerRadius="4,4,4,4" Background="{StaticResource GlowBrush}" />
<!--ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Width="Auto" Grid.RowSpan="2"/-->
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" RecognizesAccessKey="True" Grid.RowSpan="2"/>
<Border HorizontalAlignment="Stretch" Margin="0,0,0,0" x:Name="shine" Width="Auto" CornerRadius="4,4,0,0" Background="{DynamicResource ShineBrush}"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" TargetName="border" Value="{DynamicResource DisabledForegroundBrush}"/>
</Trigger>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Background" TargetName="border" Value="{DynamicResource GlowBrush}"/>
</Trigger>
<!--Trigger Property="LostFocus">
<Setter Property="Background" TargetName="border" Value="{DynamicResource BackgroundNormal}"/>
</Trigger-->
<Trigger Property="IsPressed" Value="True">
<Setter Property="Opacity" TargetName="shine" Value="0.4"/>
<Setter Property="Visibility" TargetName="glow" Value="Hidden"/>
<Setter Property="Background" TargetName="border" Value="{DynamicResource GlowBrush}"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="{StaticResource GlyphDarkBrush}" />
<Setter Property="Background" TargetName="border" Value="{DynamicResource GlowBrush}"/>
</Trigger>
<Trigger Property="IsCancel" Value="False"/>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFFFFFFF" Offset="0"/>
<GradientStop Color="#FFEAEBF0" Offset="0.9"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
Now I am doing localization in my project, so while changes language like french, then Button text would become big rather than button width, so I want auto texttrimming in button style. and full text display in tooltip.
Also i have second kind of button with Images and Text as following.
<Button Name="btnRefresh" Click="btnRefresh_Click" Width="69" ToolTipService.ToolTip="Click To Refresh" FontSize="11" Content="Refresh">
<Image Source="../Images/Refresh.png" Width="18" Height="13" />
</Button>
I also want to apply same style with this button too.
So is it possible to do this in same style template?
Please help me to solve this.
Thanks in Advance.
To do this, you need to change the ContentPresenter in your style to a Textblock, and bind its Text to your Content.
If you replace with something along those lines, you should be able to set text trimming as you like.
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border"
Background="{DynamicResource BackgroundNormal}"
BorderThickness="1,1,1,2"
CornerRadius="4,4,4,4"
BorderBrush="{DynamicResource GlyphDarkBrush}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="0.507*"/>
<RowDefinition Height="0.493*"/>
</Grid.RowDefinitions>
<Border Opacity="0"
HorizontalAlignment="Stretch"
x:Name="glow"
Width="Auto"
Grid.RowSpan="2"
CornerRadius="4,4,4,4"
Background="{StaticResource GlowBrush}" />
<TextBlock Text="{TemplateBinding Content}"
TextTrimming="WordEllipsis"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Grid.RowSpan="2"/>
<Border HorizontalAlignment="Stretch"
Margin="0,0,0,0"
x:Name="shine"
Width="Auto"
CornerRadius="4,4,0,0"
Background="{DynamicResource ShineBrush}"/>
</Grid>
</Border>
...
</ControlTemplate>
EDIT: regarding the second part of your question.
The last piece of code you show cannot work as you're setting the Content of your Button twice (I don't think it actually compiles).
The cleanest way of doing what you're trying to achieve is to define a custom Control class, as described here.
A "not so clean" hack could be to use the Tag field of your Button to store the image source URI like this:
<Button Name="btnRefresh"
Click="btnRefresh_Click"
Width="69"
ToolTipService.ToolTip="Click To Refresh"
FontSize="11" Content="Refresh"
Tag="../Images/Refresh.png" Width="18" Height="13" />
And then retrieve it in your style. This Grid replaces the Textblock in the previous solution:
<Grid Grid.RowSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0"
Source="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Tag}" />
<TextBlock Text="{TemplateBinding Content}"
Grid.Column="1"
TextTrimming="WordEllipsis"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Grid>
The reason why the binding is slightly different is explained here.
But again, creating a custom Button with image and text is probably the cleanest way to do this!

Categories

Resources