WPF Style design TextBox Tooltip - wpf

I would like to style the Tooltip of Textboxes which are used for validation. I'm trying to get a rounded corners Tooltip without sucess. How may I get it from ResourceDictonary?
With the code below, I'm getting the Tooltip text on validation error with a rectangular border. Here is my code:
<ResourceDictionary>
<!-- Textbox with validation capabilities -->
<Style x:Key="ValidableTextBox" TargetType="TextBox">
<Style.Resources>
<Style x:Key="ToolTip" TargetType="ToolTip">
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="HasDropShadow" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToolTip">
<Border Name="Border" CornerRadius="4" BorderThickness="1" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
<ContentPresenter />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Style.Resources>
<Setter Property="Height" Value="22"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>

I just realized that BorderBrush property was missing, thanks to Muhammad for he made it working (remove the x:Key="ToolTip"), here is the updated code:
<ResourceDictionary>
<!-- Textbox with validation capabilities -->
<Style x:Key="ValidableTextBox" TargetType="TextBox">
<Style.Resources>
<Style TargetType="ToolTip">
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="HasDropShadow" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToolTip">
<Border Name="Border" CornerRadius="4" BorderThickness="1" BorderBrush="Red" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
<ContentPresenter />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Style.Resources>
<Setter Property="Height" Value="22"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>

Related

WPF application: Tool tip not started all across all my application

I have WPF application and I am using materialDesign.
This is my app.xaml:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.ToolTip.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
My style:
<Style TargetType="{x:Type ToolTip}">
<Setter Property="OverridesDefaultStyle" Value="False"/>
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Foreground" Value="Silver"/>
<Setter Property="FontSize" Value="11"/>
<Setter Property="Placement" Value="Bottom"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="ToolTipService.ShowDuration" Value="10000"/>
<Setter Property="ToolTipService.HorizontalOffset" Value="-20"/>
<Setter Property="ToolTipService.Placement" Value="Left"/>
<Setter Property="ToolTipService.ShowsToolTipOnKeyboardFocus" Value="True"/>
<Setter Property="Margin" Value="0,0,0,0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToolTip}">
<Border x:Name="Root" CornerRadius="5" BorderThickness="1" BorderBrush="{DynamicResource SettingsLeftMenueBackgroundColor}" Background="{DynamicResource ToolTipBackgroundColor}">
<ContentPresenter Margin="10" HorizontalAlignment="Left" VerticalAlignment="Top"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsOpen" Value="False">
<Setter TargetName="Root" Property="Visibility" Value="Collapsed"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Some control:
<Button Name="btnSettings"
Padding="0"
Cursor="Hand"
Command="{Binding OpenSettingsFormCommand}">
<Button.ToolTip>
<ToolTip Content="Settings"
ToolTipService.Placement="Top"/>
</Button.ToolTip>
</Button>
And I cannot see this ToolTip at all.
I try to remove MaterialDesignTheme.ToolTip.xaml from my app.xaml or add key into my ToolTip style and using this style via key but this not helped at all.
My ToolTip missing across all my application.

TextBox ControlTemplate inside of a Style with InputBindings

I've created a WPF Style for a TextBox with an InputBindings (KeyBinding for Enter) inside the ControlTemplate.
Style and InputBindings is working fine for my TextBoxes, but if I use this Style for my TextBoxes the TabOrder/TabStop is not working any more.
This is the style:
<Style x:Key="TextBoxTemplate" TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="FontSize" Value="16"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="Margin" Value="5,0,5,5"/>
<Setter Property="Width" Value="150"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<TextBox Text="{TemplateBinding Text}">
<TextBox.InputBindings>
<KeyBinding Command="{Binding EnterKeyCommand}" Key="Enter"/>
</TextBox.InputBindings>
</TextBox>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
How I add it to my TextBoxes:
<TextBox Text={Binding FirstName} Style="{StaticResource TextBoxTemplate}">
<TextBox Text={Binding LastName} Style="{StaticResource TextBoxTemplate}">
I think the problem is that I use a TextBox inside of the ControlTemplate.
But I don't know how to get running the InputBindings without the TextBox inside of the Template
Do you have any idea?
Thanks Phil
Modify your template to look like the original one plus your KeyBinding:
<Style x:Key="TextBoxTemplate" TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="FontSize" Value="16"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="Margin" Value="5,0,5,5"/>
<Setter Property="Width" Value="150"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"
SnapsToDevicePixels="True">
<ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden">
<ScrollViewer.InputBindings>
<KeyBinding Command="{Binding EnterKeyCommand}" Key="Enter"/>
</ScrollViewer.InputBindings>
</ScrollViewer>
</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>

WPF Datagrid Selected Row Color and Centered Text

I have a simple DataGrid where I want to Style the selected row and center the text. I have tried the following and it does not work:
<DataGrid.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center" />
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Blue" />
<Setter Property="Foreground" Value="White" />
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.CellStyle>
Why will the above not work together? If I remove the trigger, it will center but the color I want will not be used.
Try add Grid to the ControlTemplate of DataGridCell style:
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Grid Background="{TemplateBinding Background}">
<ContentPresenter Margin="2"
VerticalAlignment="Center"
HorizontalAlignment="Center" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="White" />
<Setter Property="Background" Value="Blue" />
</Trigger>
</Style.Triggers>
</Style>

WPF DataGridCell, Style.Trigger, basedon multiple styles

I have got this problem with styles in WPF.
I want every cells in row in red color.
When I use two styles for one cell MyCellStyle and RightCellStyle (based on MyCellStyle) the result is:
image
Here is may code for MyCellStyle and RightCellStyle
<Style x:Key="MyCellStyle" TargetType="DataGridCell">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DataGridCell">
<Border Background="{TemplateBinding Background}">
<ContentPresenter VerticalAlignment="Center" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="{StaticResource SelectedRowColor}" />
<Setter Property="BorderBrush" Value="#FFDFE9F5" />
<Setter Property="BorderThickness" Value="1" />
</Trigger>
</Style.Triggers>
<Style x:Key="RightCellStyle" TargetType="DataGridCell" BasedOn="{StaticResource MyCellStyle}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DataGridCell">
<Border Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Right" VerticalAlignment="Center" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
And here is part where I set red Color
<DataGrid.Style>
<Style TargetType="DataGrid" BasedOn="{StaticResource {x:Type DataGrid}}">
<Setter Property="CellStyle">
<Setter.Value>
<Style TargetType="DataGridCell" BasedOn="{StaticResource MyCellStyle}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsNew}" Value="True">
<Setter Property="Foreground" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</Setter.Value>
</Setter>
</Style>

Validation.ErrorTemplate Style Issue

I am trying to apply a style to a text box when the content is not valid.
The following style works:
<Style x:Key="textBoxNormalStyle" TargetType="{x:Type TextBox}">
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="FontSize" Value="16"/>
<Setter Property="ForceCursor" Value="False"/>
<Setter Property="Foreground" Value="{StaticResource TextColor}"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="3,0,3,0"/>
<Setter Property="Margin" Value="2"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border Background="{StaticResource TextBackColor}" BorderBrush="{StaticResource BorderColor}" x:Name="Bd" CornerRadius="4" BorderThickness="2">
<ScrollViewer Margin="0" x:Name="PART_ContentHost"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="FontSize" Value="16"/>
<Setter Property="ForceCursor" Value="False"/>
<Setter Property="Foreground" Value="{StaticResource TextColor}"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="3,0,3,0"/>
<Setter Property="Margin" Value="2"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid Name="test">
<Border Background="{StaticResource TextBackColor}" BorderBrush="#d99" x:Name="Bd" CornerRadius="4" BorderThickness="2">
<ScrollViewer Margin="0" x:Name="PART_ContentHost"/>
</Border>
<Image Name="ErrorImage" Width="24" Height="24" Margin="0,0,4,0" Source="/Images/error.png" HorizontalAlignment="Right">
</Image>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
However I want to get rid of the trigger above and move the control template within the trigger to the Validation.ErrorTemplate section. But when I do this the control for the error template does not display correctly (the size of the error template defaults to the size of the image contained within it, left aligned, and blocks the text the user might have typed in the textbox).
Is there a cleaner way for the xaml above?
The ErrorTemplate is an adorner, not a replacement for the control template. You include an AdornedElementPlaceholder in the template where you want to leave space for the original control. So, your error template should look like:
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<Grid Name="test">
<AdornedElementPlaceholder/>
<Image Name="ErrorImage" Width="24" Height="24" Margin="0,0,4,0" Source="/Images/error.png" HorizontalAlignment="Right"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
Since you also want to change the color of the border, I would use a TemplateBinding for the border brush and change that in the Validation.HasError trigger:
<Setter Property="BorderBrush" Value="{StaticResource BorderColor}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border Background="{StaticResource TextBackColor}" BorderBrush="{TemplateBinding BorderBrush}" x:Name="Bd" CornerRadius="4" BorderThickness="2">
<ScrollViewer Margin="0" x:Name="PART_ContentHost"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="BorderBrush" Value="#d99"/>
</Trigger>
</Style.Triggers>

Resources