I am using HeaderedContentControl for displaying my label & text box as below..
<Style x:Key="ContentBorderStyle" TargetType="Border">
<Setter Property="BorderBrush" Value="Blue"/>
</Style>
<Style TargetType="HeaderedContentControl" x:Key="BaseLabeledItemStyle">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="HeaderedContentControl">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Border Grid.Column="0">
<ContentPresenter Name="header"
Content="{TemplateBinding Header}"/>
</Border>
<Border Grid.Column="1"
Style="{StaticResource ContentBorderStyle}">
<AdornerDecorator>
<ContentPresenter Name="content"
Content="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Content}"/>
</AdornerDecorator>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
<HeaderedContentControl
Style="{StaticResource ResourceKey=BaseLabeledItemStyle}"
Header="Emp Name">
<!--<ContentControl>-->
<TextBox x:Name="txtName"
Text="{Binding Path=EmpName, Mode=TwoWay, ValidatesOnDataErrors=True}"/>
</HeaderedContentControl>
As I am using Border brush as "Blue" for content control My content Control is always displaying with Blue border. When there is an validation error, my text box which I am using inside Headered content control's border is changing to red as I am using ValidationOnDataerror. now my requirement is to change even the content border too in Red Color when Validation occurs (i.e. when inner text box is in red color)...
I am attaching an Image how my control is populating.. in that (1) is border of my content control & (2) is my text box control.
How can I change the color of content control based on Text box color...
thanks in advance...
You could use a DataTrigger for additional highlighting
<Style x:Key="ContentBorderStyle" TargetType="Border">
<Setter Property="BorderBrush" Value="Blue"/>
<Style.Triggers>
<DataTrigger Binding="{Binding (Validation.HasError), ElementName=txtName}" Value="True">
<Setter Property="BorderBrush" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
FYI:
If you want to show the Validation.ErrorTemplate on any other control than TextBox use Validation.ValidationAdornerSiteFor Attached Property. e.g.
<HeaderedContentControl Validation.ValidationAdornerSiteFor="{Binding ElementName=txtName}"
or
<Style x:Key="ContentBorderStyle" TargetType="Border">
<Setter Property="BorderBrush" Value="Blue"/>
<Setter Property="Validation.ValidationAdornerSiteFor" Value="{Binding ElementName=txtName}"/>
</Style>
Related
I have this button and wanted to change the design if I hover over it with the mouse. It's not working and I'm not getting an error.
What am I doing wrong?
(I'm really new to WPF)
<Button MaxWidth="180"
Margin="5"
DockPanel.Dock="Top"
Padding="5"
FontSize="12"
Foreground="#1261AC"
FontWeight="SemiBold"
BorderBrush="Transparent">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border CornerRadius="5" Background="LightGray" BorderThickness="1" Padding="5">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Foreground" Value="#157ec4"/>
<Setter Property="Background" Value="#000000"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
The button itself is working but it is not chaning the color of the background or font.
(The colors in my example are just for testing)
The problem with your code is that you define the border-background to be gray.
Now you change the control background using a trigger.
However, the background that is set by the trigger is not yet related to the border background in your example.
I added a template binding that fixes this issue to you. Now the border in your template will always have the Background defined in your style, set by triggers or directly set in XAML.
PLEASE NOTE:
If you set the color in XAML by using <Button Background="Pink"/> this will overwrite the style and trigger attributes.
if you still want to overwrite the background property for a single button for some reason without overwritting the triggers you'll have to create a style based on the original style using the BasedOn Property:
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Setter Propert="Background" Value="Yellow"/>
</Style>
try this piece of art:
ButtonStyle:
<Button Content="Hello there!"
MaxWidth="180"
Margin="5"
DockPanel.Dock="Top"
Padding="5"
FontSize="12"
Foreground="#1261AC"
FontWeight="SemiBold"
BorderBrush="Transparent">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Background" Value="HotPink"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border CornerRadius="5" Background="{TemplateBinding Background}" BorderThickness="1" Padding="5">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Red" />
<Setter Property="Background" Value="Lime" />
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
I'm trying to change the text color of ToolTips through a style template. But changing the ToolTip Foreground property doesn't change the color no matter what I do. I'm almost certain this is because I also have a TextBlock style that's overriding it.
When attempting to retemplate with a new textblock, it has no effect at all. I've spent all day yesterday fiddling with this issue and searching through threads and have found nothing.. Any contribution would be appreciated.
This is the style in my resource dictionary:
<!-- TextBlock -->
<Style TargetType="{x:Type TextBlock}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Foreground" Value="#B2FFFFFF"/> <!-- ToolTip text color overridden by this -->
</Style>
<!-- ToolTip -->
<Style TargetType="{x:Type ToolTip}" BasedOn="{StaticResource {x:Type ToolTip}}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="HasDropShadow" Value="True" />
<Setter Property="Foreground" Value="DarkBlue"/> <!-- has no effect -->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToolTip">
<Grid>
<Border Name="Border"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
MinWidth="100"
MinHeight="30"
Margin="0,0,0,50"
Background="Beige"
BorderBrush="Black"
BorderThickness="1"
CornerRadius="10"/>
<TextBlock Foreground="DarkBlue"/> <!-- has not effect -->
<ContentPresenter Margin="4"
HorizontalAlignment="Center"
VerticalAlignment="Top"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I figured out one solution to this issue.
Removing the TargetType from this line:
<ControlTemplate TargetType="ToolTip">
to read as so:
<ControlTemplate >
and further down in the ControlTemplate, the textblock should be set like this:
<TextBlock
Text="{Binding Path=Content, RelativeSource={RelativeSource TemplatedParent}}"
Foreground="{Binding Path=Foreground, RelativeSource={RelativeSource TemplatedParent}}">
</TextBlock>
This allows the text color of a tooltip to be set with the ToolTip's "Foreground" property and is not overridden by other TextBlock styles.
I want to change the color of a MenuItem at mouseOver. I need also rounded borders, an image and a textBox. When I set the style all is ok only the mouseOverEvent is doing anything, the background doesnot change. My code is:
<Style x:Key="BaseStyle" TargetType="MenuItem">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="#0a99f3" />
</Trigger>
<Trigger Property="IsKeyboardFocusWithin" Value="true">
<Setter Property="Background" Value="#0a99f3" />
</Trigger>
</Style.Triggers>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<Grid>
<Border Name="MainBorder" BorderThickness="2,2,2,0" CornerRadius="8,8,8,8" Margin="0,0,1,0" BorderBrush="AliceBlue">
<Grid>
<TextBlock Text="Info" Margin="30,10,0,0" FontFamily="Arial" FontSize="14" FontWeight="Bold" />
<Image Width="15" Height="15" Source="menu.PNG" Margin="-100,0,0,0" />
</Grid>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Hope anybody know what I am missing. Thanks!
You're overwritting the Template, but not using the Background Color anywhere in it so the value never gets applied.
Set the Background Color in your MenuItem Template
<ControlTemplate TargetType="{x:Type MenuItem}">
<Grid Background="{TemplateBinding Background}">
You are not binding the Background anywhere in your template so changing that property has no effect.
I have a combobox that i need to edit its error template to show a red border when there is a validation error.
I am using the following style
<Style TargetType="{x:Type ComboBox}" >
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<DockPanel>
<Border BorderBrush="Red" BorderThickness="3">
<AdornedElementPlaceholder />
</Border>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="FontSize" Value="12" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
The border never shows up when validation errors occur. Any tips what is going wrong?
The Style you posted works. You should check your binding, did you add ValidatesOnDataErrors=True and ValidatesOnExceptions=True to the binding of SelectedValue?
enter code heretry without the dock panel, that is uneuseful since it wraps jus one element. However, sicnecerely I don't wnow if it makes sense to wrap a textbox with a border, since it has already a border! You should try to change directly the colour of its border. You could try to use again the panel but then put the border around the panel ie:
Border BorderBrush="Red" BorderThickness="3"
DockPanel
AdornedElement
This makes more sense because the wrap panel has not its own border.
Use This.
<Style x:Key="textBoxStyle" TargetType="{x:Type telerik:RadMaskedTextBox}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
<Setter Property="Control.BorderBrush" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
I don't like any of the responses here. Simply put, how do you change the border color for the error template for a ComboBox using Blend or not? It shouldn't be acceptable to draw another border around the existing border of the ComboBox. I've figured out how to creat a ControlTemplate in Blend but not a Validation Template.
I've come close with trying to make it appear like I've changed the actual border color, but that's not what I actually want. Suggestions? To complicate it a bit, I'd like to display a red asterisk outside of the right border of the control.
The following code is a close attempt, but it is actually drawing a border inside the ComboBox and if you look close, you can see that the border is 2 pixels wide when combined with the ComboBox border:
<DockPanel Name="myDockPanel">
<AdornedElementPlaceholder>
<Border BorderBrush="Blue" BorderThickness="1" CornerRadius="2" />
</AdornedElementPlaceholder>
<TextBlock Text="*" FontWeight="Bold" FontSize="14" Foreground="Red" DockPanel.Dock="Left" ToolTip="{Binding .CurrentItem}" />
</DockPanel>
I searched around some more and came up with a solution based on another article here: WPF - How to apply style to AdornedElementPlaceholder's AdornedElement?
<!-- This works -->
<ComboBox Name="comboBox1" Style="{StaticResource NewComboBoxStyle}" Validation.ErrorTemplate="{StaticResource comboBoxValidationTemplate}" />
<SolidColorBrush x:Key="MainBorderBrush">#FF91B3FF</SolidColorBrush>
<Style x:Key="NewComboBoxStyle" TargetType="{x:Type ComboBox}" BasedOn="{StaticResource myErrorTemplate}">
<Setter Property="BorderBrush" Value="{DynamicResource MainBorderBrush}" />
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="BorderBrush" Value="Blue" />
</Trigger>
</Style.Triggers>
</Style>
<!-- Sets ToolTip when Validation.HasError is True. -->
<Style TargetType="Control" x:Key="myErrorTemplate">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={x:Static RelativeSource.Self},
Path=(Validation.Errors).CurrentItem.ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
<ControlTemplate x:Key="comboBoxValidationTemplate">
<DockPanel Name="myDockPanel">
<AdornedElementPlaceholder/>
<TextBlock Text="*" FontWeight="Bold" FontSize="14" Foreground="Red" DockPanel.Dock="Left" ToolTip="{Binding .CurrentItem}" />
</DockPanel>
</ControlTemplate>
I have a TabControl that I have restyled. The TabItem has a trigger that is fired when the TabItem is selected that changes the TabItem text to bold and green. The problem I have is that the text in the contents of the tab is also set to bold and green.
I can work around this by setting all of my controls in the tab content to be the color and font weight I want, but should I have to do this? So, I have to make sure that every textblock in the contents area has a style that sets the color to black and font weight normal.
How can I set the IsSelected part of the TabItem to show green, but leave the contents of the tab alone?
I've tried to set the foreground of the TabControl to black, but this doesn't work.
You will see from the code sample below that the text on the first tab is green, and I want it to be black, but without setting each control in the tab content.
Code Sample below:
<Grid>
<Grid.Resources>
<!-- Tab item -->
<Style TargetType="{x:Type TabItem}">
<Setter Property="FontSize" Value="14"/>
<Setter Property="MinWidth" Value="200"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid>
<Border Name="Border" Padding="5,2">
<ContentPresenter ContentSource="Header"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Border.IsMouseOver" Value="True"/>
<Condition Property="IsSelected" Value="False"/>
</MultiTrigger.Conditions>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Foreground" Value="Black"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Border.IsMouseOver" Value="False"/>
<Condition Property="IsSelected" Value="False"/>
</MultiTrigger.Conditions>
<Setter Property="Foreground" Value="Black" />
</MultiTrigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="Green"/>
<Setter Property="FontWeight" Value="Bold"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Tab control -->
<Style TargetType="{x:Type TabControl}">
<Setter Property="SelectedIndex" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabControl}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Border Grid.Column="0" Padding="5" Margin="0,0,5,0" CornerRadius="3">
<StackPanel Orientation="Vertical">
<ScrollViewer VerticalScrollBarVisibility="Auto" FocusVisualStyle="{x:Null}">
<TabPanel IsItemsHost="True"/>
</ScrollViewer>
</StackPanel>
</Border>
<Border Grid.Column="1" BorderBrush="Black" BorderThickness="0">
<ScrollViewer VerticalScrollBarVisibility="Auto" FocusVisualStyle="{x:Null}" Padding="10,0">
<ContentPresenter ContentSource="SelectedContent"/>
</ScrollViewer>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
<TabControl Name="tabControl" TabStripPlacement="Left">
<!-- First tab item -->
<TabItem IsSelected="True">
<TabItem.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Profile"/>
</StackPanel>
</TabItem.Header>
<TextBlock Text="Page 1 Sample Text with no foreground set." FontSize="30"/>
</TabItem>
<!-- Second tab item -->
<TabItem IsSelected="True">
<TabItem.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Profile"/>
</StackPanel>
</TabItem.Header>
<TextBlock Text="Page 2 Sample Text with foreground set manually." FontSize="30" Foreground="Red"/>
</TabItem>
</TabControl>
</Grid>
I have just come across this very same problem, and after fiddling around with it a little I think I have found a more elegant solution.
I'm saying more elegant since it would leave the ContentPresenter intact, and apply the foreground and fontweight setters to the ContentPresenter's TextElement (which is basically an attached property, but that's beside the point).
The main advantage of this approach is that replacing the ContentPresenter with a TextBlock implicitly assumes that the header will only contain text, which limits the usability of the workaround and produces a less robust code. Leaving the ContentPresenter in place will allow any content, e.g. images+text.
One more thing you would have to do is name your ContentPresenter:
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid>
<Border Name="Border" Padding="5,2">
<ContentPresenter x:Name="CP" ContentSource="Header"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Border.IsMouseOver" Value="True"/>
<Condition Property="IsSelected" Value="False"/>
</MultiTrigger.Conditions>
<Setter Property="TextElement.FontWeight" TargetName="CP" Value="Bold"/>
<Setter Property="TextElement.Foreground" TargetName="CP" Value="Black"/>
</MultiTrigger>...
Now the Foreground and FontWeight will not be inherited by the contents of the TabItem (tested).
Enjoy :)
This is pretty old, but I came across it while looking for an answer for a similar problem, and I found the supplied answers not at all helpful.
Here is how I fixed this.
If you change the ContentPresenter to a TextBlock in the control template of your tabitem, like this:
....stuff above here...
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid>
<Border Name="Border" Padding="5,2">
<TextBlock x:Name="TabItemContent" Text="{TemplateBinding Header}"/>
</Border>
</Grid>
... stuff below here....
Then in your trigger on that control template you specify the targetname in the IsSelected trigger..ie.
...stuff above here...
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" TargetName="TabItemContent" Value="Green"/>
<Setter Property="FontWeight" Value="Bold"/>
</Trigger>
... stuff below here ...
That should give you green text when the tab is selected, and not green all the other times, while leaving the text coloring in the rest of the app alone.
Unfortunately, if you set the Foreground (or FontWeight) on a ContentPresenter by some trigger, you still assume that the header will only contain Text.
If you set Header="SomeHeaderName" (i.e. text only), the ContentPresenter will generate a TextBlock to host this headertext; the ContentPresenter will be the (logical) parent of this TextBlock and so, the new Foreground set on the ContentPresenter will be inherited by this TextBlock. This works ok.
However, if the Header is assigned some piece of visual tree, like a horizontal StackPanel with an Image and a TextBlock (or even a single TextBlock), then the logical parent of the StackPanel is the TabItem and not the ContentPresenter. Inheritance works via the logical tree and so the TextBlock inside the StackPanel will ultimately inherit its Foreground from the TabItem again; the foreground that was set on the ContentPresenter does not have any effect on this.
One possible solution: a DataTemplate is eventually applied to a ContentPresenter, so the TemplatedParent of the root of the DataTemplate is the ContentPresenter; and inheritance works through a TemplatedParent-Child barrier as well. So if you are able to set the TabItem.HeaderTemplate instead of the TabItem.Header, then you can set the Foreground on the header's ContentPresenter, because the root of the HeaderTemplate will inherit the Foreground from the ContentPresenter. The SelectedContent however, will not because the Foreground is not set on the TabItem (and the content inherits its Foreground from the TabItem).
Hope this helps!
Every control in wpf inherits properties from its parent. Since the TabItem's color was black, its child textblock was also of black color. Now since you've changed the entire TabItem's foreground color to green, all its children will inherit it.
Here you can set your TabItem.Header's or its contents' foreground to green, so that it will not affect other contents in the TabItem. Else you can invert the solution.
Else Try this:
<Window.Resources>
<DataTemplate x:Key="greenHeaderTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Profile"
FontWeight="Bold"
Foreground="Green"/>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="defaultHeaderTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Profile"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
<Trigger Property="IsSelected" Value="True">
<Setter Property="HeaderTemplate"
Value="{StaticResource greenHeaderTemplate}"/>
</Trigger>
<TabItem IsSelected="True" HeaderTemplate="{StaticResource defaultHeaderTemplate}">
<TextBlock Text="Page 1 Sample Text with no foreground set." FontSize="30"/>
</TabItem>
Here is a practical solution which assumes that black will be an acceptable foreground color for TextBlocks etc. in your TabItem.
First, because I use a Canvas for the body of my TabItem, I made a custom style like this:
<Style x:Key="canvasStyle_BlackForeground" TargetType="{x:Type Canvas}">
<Setter Property="TextElement.Foreground" Value="Black"/>
</Style>
Then, the TabItem (which happens to use a Canvas as container) looks like this, where the TabItem Foreground is set to Green, but the Canvas is styled to Foreground black:
<TabItem Header="TabItem" Foreground="Green">
<Canvas Background="#FFE5E5E5" Style="{StaticResource canvasStyle_BlackForeground}">
<TextBlock Canvas.Left="79" Text="This is a TextBlock" Canvas.Top="63"/>
</Canvas>
</TabItem>
If you're using a Grid instead of a Canvas, it works just as well. Just make your style's TargetType as x:Type Grid.