WPF textbox's toolip foreground not changing - wpf

I have created a customized textbox which have a property SelfPropertyInfo. This again have some other property which we use(like IsValid, Description etc). I am trying to add style on text box so that if if IsValid is false it should show a tooltip(which contains Description).
<Style TargetType="{x:Type ToolTip}">
<Setter Property = "Foreground" Value=" Red "/>
</Style>
<Style TargetType="{x:Type CustomControls:TextBox}">
<Setter Property="Height" Value="22"/>
<Setter Property="Margin" Value="2,2,2,2"/>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="DarkGray" />
</Trigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=SelfPropertyInfo.IsValid}" Value="False">
<Setter Property="BorderBrush" Value="Red"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=SelfPropertyInfo.RuleDescription}" >
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
By above code everything is working fine, but the issue is that the tooltip is not in "Red" color. :(
Can anybody suggest?
I tried another approach and the foreground is now "Red", but I need help about how TO bind description with tootip's text. Please see the changes inside DataTrigger, :
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=SelfPropertyInfo.IsValid}" Value="False">
<Setter Property="BorderBrush" Value="Red"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="ToolTip">
<Setter.Value>
<ToolTip >
<TextBlock Foreground="Red" Text="Hello"/>
</ToolTip>
</Setter.Value>
</Setter>
</DataTrigger>
Thanks in advance for any help.
I also tried below code, but it makes tooltip blank:
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=SelfPropertyInfo.IsValid}" Value="False">
<Setter Property="BorderBrush" Value="Red"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="ToolTip">
<Setter.Value>
<ToolTip >
<TextBlock Foreground="Red" Text="{Binding RelativeSource={RelativeSource Self}, Path=SelfPropertyInfo.RuleDescription}"/>
</ToolTip>
</Setter.Value>
</Setter>

In the DataTrigger, "Text" property of TextBlock used to set Foreground for tooltip is overriding the Tooltip's text value, thats why you're unable to see the description. So bind the "Text" property with SelfPropertyInfo.RuleDescription.

I tried out using normal property it worked fine for me
private string testString;
public string TestString
{
get { return testString; }
set
{
testString = value;
RaisePropertyChanged("TestString");
}
}
<TextBox Height="100" Text="{Binding TestString}">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<DataTrigger Binding="{Binding TestString}" Value="False">
<Setter Property="BorderBrush" Value="Red"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="ToolTip">
<Setter.Value>
<ToolTip >
<TextBlock Foreground="Red" Text="{Binding TestString}"/>
</ToolTip>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>

Related

How can I highlight the cell which contains the error?

I have a DataGrid with four columns for which I have defined a style as well as a triggered style for the case the user enters an invalid value.
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="FontSize" Value="16"/>
<Setter Property="FontFamily" Value="ArialMT"/>
<Setter Property="Height" Value="24"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="ValidationErrorTemplate">
<Setter.Value>
<ControlTemplate>
<Grid>
<Ellipse Width="12" Height="12" Fill="Red" Stroke="Black" StrokeThickness="0.5"/>
<TextBlock FontWeight="Bold" Padding="4,0,0,0" Margin="0" VerticalAlignment="Top" Foreground="White" Text="!" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="BorderBrush" Value="Red"/>
<Setter Property="IsEnabled" Value="True" />
<Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
This works well and the complete DataGridRow is marked as faulty because I used this in the XAML:
<DataGrid.RowValidationRules>
<local:CycleValidationRule ValidationStep="UpdatedValue" />
</DataGrid.RowValidationRules>
Now I want to highlight the DataGridCell with the invalid value explictely additionally (setting the background colour). Hence, I defined another style:
<Style x:Key="cycleErrStyle" TargetType="{x:Type TextBlock}">
<Setter Property="Background" Value="Magenta"/>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true" >
<Setter Property="Background" Value="Red" />
<Setter Property="Foreground" Value="White" />
</Trigger>
</Style.Triggers>
</Style>
but this doesn't work.
When I set <Trigger Property="Validation.HasError" Value="false" > to false, the style affects. It seems as if the Validation.HasError property has been reset after validation for the grid's row.
In the XAML I defined this:
<DataGridTextColumn x:Name="TagCycle" Header="Cycle" Binding="{Binding Mode=TwoWay, Path=RawTag.Cycle, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"
ElementStyle="{StaticResource ResourceKey=cycleErrStyle}" />
How can I highlight the invalid cell additionally to marking the row as faulty?
You could use a DataTrigger that binds to the Validation.HasError attached property of the parent DataGridRow:
<Style x:Key="cycleErrStyle" TargetType="{x:Type TextBlock}">
<Setter Property="Background" Value="Magenta"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=(Validation.HasError), RelativeSource={RelativeSource AncestorType=DataGridRow}}" Value="true" >
<Setter Property="Background" Value="Red" />
<Setter Property="Foreground" Value="White" />
</DataTrigger>
</Style.Triggers>
</Style>

Binding Error : Cannot find source for binding with reference 'RelativeSource FindAncestor

I have a customized Textbox which has some property SelfPropertyInfo(which further has some property like IsValid and RuleDescription).
I am trying to add below style on every Textbox of this type.
<Style TargetType="{x:Type CustomControls:TextBox}">
<Setter Property="Height" Value="22"/>
<Setter Property="Margin" Value="2,2,2,2"/>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="DarkGray" />
</Trigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=SelfPropertyInfo.IsValid}" Value="False">
<Setter Property="BorderBrush" Value="Red"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="ToolTip" >
<Setter.Value>
<ToolTip >
<TextBlock Foreground="Red" Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type CustomControls:TextBox},AncestorLevel=2},Path=SelfPropertyInfo.RuleDescription}"/>
</ToolTip>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
In above code I am not getting Tooltip Text. (Result of below code)
<TextBlock Foreground="Red" Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type CustomControls:TextBox},AncestorLevel=2},Path=SelfPropertyInfo.RuleDescription}"/>
I am getting below error:
System.Windows.Data Error: 4 : Cannot find source for binding with
reference 'RelativeSource FindAncestor,
AncestorType='CustomControls.TextBox', AncestorLevel='2''.
BindingExpression:Path=SelfPropertyInfo.RuleDescription;
DataItem=null; target element is 'TextBlock' (Name=''); target
property is 'Text' (type 'String')
Can anybody suggest the mistake I did in Text binding?
Note: I can't change the way Tooltip is added :(
First of all I would like to say thanks to nkoniishvt for this link. It helped me to understand the problem. By using below code it worked as expected:
<Style TargetType="{x:Type CustomControls:TextBox}">
<Setter Property="Height" Value="22"/>
<Setter Property="Margin" Value="2,2,2,2"/>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="DarkGray" />
</Trigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=SelfPropertyInfo.IsValid}" Value="False">
<Setter Property="BorderBrush" Value="Red"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Tag" Value= "{Binding RelativeSource={RelativeSource Self}}"/>
<Setter Property="ToolTip">
<Setter.Value>
<ToolTip Height="28" Background="Red" DataContext="{Binding RelativeSource={RelativeSource Self},Path=PlacementTarget.Tag}">
<TextBlock Foreground="White" Text="{Binding Path=SelfPropertyInfo.RuleDescription}"/>
</ToolTip>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>

Change image and textblock foreground on TabItem = IsSelected

I have some TabItems, each one containg one image and a textblock. Here is the code:
<TabItem.Header>
<ContentControl>
<ContentControl.Template>
<ControlTemplate>
<StackPanel x:Name="sp" Orientation="Horizontal">
<Image x:Name="img" Source="img0.png"/>
<TextBlock x:Name="tb" Text="Tab1" VerticalAlignment="Center" Foreground="Green"/>
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="TabItem.IsSelected" Value="True">
<Setter TargetName="img" Property="Source" Value="img1.png" />
<Setter TargetName="tb" Property="Foreground" Value="Red" />
<Setter Property="FontWeight" Value="Bold"/>
</Trigger>
<Trigger SourceName="sp" Property="IsMouseOver" Value="True">
<Setter TargetName="img" Property="Source" Value="img1.png" />
<Setter TargetName="tb" Property="Foreground" Value="Red" />
<Setter Property="FontWeight" Value="Bold"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</ContentControl.Template>
</ContentControl>
What I'm trying to achieve is to change the image's source and textblock's foreground value when the TabItem is selected. The IsMouseOver behaviour is working properly but the TabItem.IsSelected is not working as expected.
Basically this code is not doing what I'm thinking it should do:
<Trigger Property="TabItem.IsSelected" Value="True">
<Setter TargetName="img" Property="Source" Value="img1.png" />
<Setter TargetName="tb" Property="Foreground" Value="Red" />
<Setter Property="FontWeight" Value="Bold"/>
Please share your opinion.
Thank you.
You are trying to reach the IsSelected property of the TabItem from the TabItem.Header and that can't be accomplished with an ordinary Trigger. Instead, you need to use a DataTrigger so that you can Bind to the IsSelected property with a RelativeSource Binding:
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=
{x:Type TabItem}}}" Value="True">
<Setter TargetName="img" Property="Source"
Value="/WpfApplication1;component/Images/Tulips.jpg" />
<Setter TargetName="tb" Property="Foreground" Value="Red" />
<Setter Property="TextElement.FontWeight" Value="Bold"/>
</DataTrigger>

Unable to change background for a Wpf toolkit autocompletebox?

How should i change the background of the wpftoolkit autocompletebox.? I tried by subscribing to enabledchanged event and changed the background of the control which is not changing at all.Can any body help.
<WpfToolkit:AutoCompleteBox x:Name="txtBxSearch" Background="White" IsTextCompletionEnabled="True" MinimumPrefixLength="0" FilterMode="Contains" Height="24" Width="150" KeyDown="txtBxSearch_KeyDown" >
<WpfToolkit:AutoCompleteBox.TextBoxStyle>
<Style TargetType="TextBox">
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="FocusManager.FocusedElement" Value="{Binding RelativeSource={RelativeSource Self}}"/>
</Style>
</WpfToolkit:AutoCompleteBox.TextBoxStyle>
</WpfToolkit:AutoCompleteBox>
You can do this in XAML:
<toolkit:AutoCompleteBox
ToolTip="Enter the path of an assembly."
x:Name="tbAssembly" Height="27" Width="200"
Populating="tbAssembly_Populating"
>
<toolkit:AutoCompleteBox.Style>
<Style TargetType="toolkit:AutoCompleteBox">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=tbAssembly, Path=IsEnabled}" Value="True">
<Setter Property="Background" Value="Yellow" />
<Setter Property="Foreground" Value="Red" />
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=tbAssembly, Path=IsEnabled}" Value="False">
<Setter Property="Background" Value="Black" />
<Setter Property="Foreground" Value="Yellow" />
</DataTrigger>
</Style.Triggers>
</Style>
</toolkit:AutoCompleteBox.Style>
</toolkit:AutoCompleteBox>

How do I override the WPF GroupBox disabled (i.e. Gray) color for its header?

I have followed the advice of previous answers for setting a global GroupBox style that includes a HeaderTemplate. The style works great for when the affected GroupBox objects are enabled. When the affected GroupBox objects are disabled, I can only get the border color to change. I don't want the default Gray color when the GroupBox objects are disabled. My GroupBox style is shown below:
<!-- This is the color brush I am trying to set on the header text -->
<SolidColorBrush x:Key="moDisabledFGColor" Color="DarkBlue" Opacity="0.5" />
<Style TargetType="{x:Type GroupBox}">
<Setter Property="BorderThickness" Value="2" />
<Setter Property="BorderBrush" Value="{StaticResource moFGColor}"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Foreground" Value="{StaticResource moFGColor}" />
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock x:Name="HeaderText" Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type GroupBox}}, Path=Header}" FontWeight="Bold"
Foreground="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type GroupBox}}, Path=Foreground}" />
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=IsEnabled, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type GroupBox}}}" Value="False">
<Setter TargetName="HeaderText" Property="Foreground" Value="{StaticResource moDisabledFGColor}"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="BorderBrush" Value="{StaticResource moDisabledFGColor}" />
<Setter Property="Foreground" Value="{StaticResource moDisabledFGColor}" />
</Trigger>
</Style.Triggers>
</Style>

Resources