Are textblocks focusable in WPF? I want to change the background color of the textblock if it is currently the one focused, but I want to do it in XAML.
This is what I have now. It is a bunch of textboxes in a Stackpanel. I can get the XAML to target the non focus or base state, but when I try to add a trigger, the background does not change on focus. Code is below:
<Style x:Key="QueueListTextBlocks" TargetType="TextBlock">
<Setter Property="Background" Value="#027802"></Setter>
<Setter Property="Foreground" Value="White"></Setter>
<Setter Property="Padding" Value="10,5"></Setter>
<Setter Property="Margin" Value="5,2,5,0"></Setter>
<Setter Property="FontSize" Value="14"></Setter>
<Setter Property="Focusable" Value="true"/>
<Setter Property="Cursor" Value="Hand"></Setter>
<!-- Trigger-->
<Style.Triggers>
<!--Does not pick up a IsFucused State--Alternative?-->
<Trigger Property="IsFocused" Value="True">
<Setter Property="Background" Value="Blue"></Setter>
<Setter Property="FontSize" Value="18"></Setter>
<Setter Property="Foreground" Value="Orange"></Setter>
</Trigger>
</Style.Triggers>
<!--<Setter Property="Background" Value="White" />-->
</Style>
I tried your style and it works perfectly.
TextBlocks in my window change their look just pressing the TAB key.
I'm using .NET 4.0 framework.
This is the XAML of my window:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style TargetType="TextBlock" x:Key="TextBlockStyle">
<Setter Property="Background" Value="#027802"></Setter>
<Setter Property="Foreground" Value="White"></Setter>
<Setter Property="Padding" Value="10,5"></Setter>
<Setter Property="Margin" Value="5,2,5,0"></Setter>
<Setter Property="FontSize" Value="14"></Setter>
<Setter Property="Focusable" Value="true"/>
<Setter Property="Cursor" Value="Hand"></Setter>
<!-- Trigger-->
<Style.Triggers>
<!--Does not pick up a IsFucused State-Alternative?-->
<Trigger Property="IsFocused" Value="True">
<Setter Property="Background" Value="Blue"></Setter>
<Setter Property="FontSize" Value="18"></Setter>
<Setter Property="Foreground" Value="Orange"></Setter>
</Trigger>
</Style.Triggers>
<!--<Setter Property="Background" Value="White" />-->
</Style>
</Window.Resources>
<StackPanel Orientation="Vertical">
<TextBlock Text="One" Style="{StaticResource TextBlockStyle}" />
<TextBlock Text="Two" Style="{StaticResource TextBlockStyle}" />
<TextBlock Text="Three" Style="{StaticResource TextBlockStyle}" />
<TextBlock Text="Four" Style="{StaticResource TextBlockStyle}" />
<TextBlock Text="Five" Style="{StaticResource TextBlockStyle}" />
</StackPanel>
</Window>
I hope it helps
Related
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>
Short background on the problem: I am trying to make a readable, xaml only TextBox Placeholder, which is packed to a ResourceDictionary.
At this point - I have made a well working prototype, which looks and used on the page like this:
<Grid>
<TextBox Style="{StaticResource SearchBox}"
Width="325"
x:Name="UsarioDisponiblesSearch"/>
<TextBlock IsHitTestVisible="False"
Text="Search..."
VerticalAlignment="Center"
HorizontalAlignment="Left"
Margin="5,0,0,0"
Foreground="{StaticResource WhiteFadedBrush}">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Text, ElementName=UsarioDisponiblesSearch}" Value="">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<Image Source="/img/search.png" Height="15" HorizontalAlignment="Right" Margin="0,0,5,0" />
</Grid>
Grid, that holds the SearchBox consist of 3 elements:
TextBox - which will receive search string;
TextBlock - which actually holds the PlaceHolder. It disapears, as soon as ElementName of TextBox is not an empty string;
Image - custom icon on the right from the SearchBox.
What I want to achieve is a look like this on the page:
<Grid>
<TextBox Style="{StaticResource SearchBox}"
Width="325"
x:Name="UarioDisponiblesSearch"/>
<TextBlock Style="{StaticResource PlaceHolder}"
x:Name="{Binding Text, ElementName=UarioDisponiblesSearch}" />
</Grid>
And like around this styles, described in the ResourceDictionary:
<Style x:Key="SearchBox" TargetType="{x:Type TextBox}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Margin" Value="5,0,0,0" />
<Setter Property="Foreground" Value="{StaticResource WhiteBrush}" />
</Style>
<Style x:Key="Placeholder" TargetType="{x:Type TextBlock}">
<Setter Property="IsHitTestVisible" Value="False" />
<Setter Property="Text" Value="Search..." />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="Margin" Value="5,0,0,0" />
<Setter Property="Foreground" Value="{StaticResource WhiteFadedBrush}" />
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Text, RelativeSource={RelativeSource Self}}" Value="">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
The main obstacle on my way there is the Binding, because I am not really good still in understanding how does it work, and the fact, that at this point three elements will have to share the same Name property (Which I suppose is a pretty huge obstacle as well).
I am not sticking to exactly this construction but I want it to be reusable, useful for the community and neat looking.
This XAML will give a templated TextBox that will display a given message if the Text is empty on the TextBox and it does not have focus. So when you click it the message disappears, and if you enter text (or have bound text) the message will also disappear.
You can do any further fancy bindings and such if you want to make it more re-usable. I.E. you could templatebind the DisplayText.Text to something to allow for dynamic messages.
When I was doing a quick search as I was styling, I stumbled on This, which is almost the same thing. So it would be worth giving fair reference. I prefer to use keys and compartmentalize my templates and styles. In the event I want a slightly different style elsewhere, then i can just do a BasedOn Style (which i do often). It is really 6 of one and half a dozen of another (although I didn't test the linked code).
<ControlTemplate x:Key="SearchMessageTextBoxControlTemplate" TargetType="{x:Type TextBox}">
<Grid>
<Grid x:Name="SearchTextGrid">
<ScrollViewer x:Name="PART_ContentHost" Background="{TemplateBinding Background}" />
<TextBlock x:Name="DisplayText" Text="Type Your Search..."
HorizontalAlignment="Center"
VerticalAlignment="Center"
Opacity="0.5"
Visibility="Hidden"
FontSize="{TemplateBinding FontSize}"/>
</Grid>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter TargetName="DisplayText" Property="Visibility" Value="Hidden"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsFocused" Value="False"/>
<Condition Property="Text" Value=""/>
</MultiTrigger.Conditions>
<Setter TargetName="DisplayText" Property="Visibility" Value="Visible"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Style x:Key="WaterMarkMessageTextBoxStyle" TargetType="{x:Type TextBox}">
<Setter Property="FontSize" Value="20"/>
<Setter Property="Background" Value="DarkSlateGray"/>
<Setter Property="CaretBrush" Value="White"/>
<Setter Property="Foreground" Value="#F2FFE5"/>
<Setter Property="FontWeight" Value="Normal"/>
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="TextWrapping" Value="Wrap"/>
<Setter Property="Template" Value="{StaticResource SearchMessageTextBoxControlTemplate}"/>
</Style>
You would use it as follows:
<TextBox Style="{StaticResource WaterMarkMessageTextBoxStyle}"/>
I am struggling to find a solution to this. Every other one i;ve tried is not working. Maybe I am missing something.
I want to change the background color of a Button when I hover over it with the mouse.
This is my XAML:
<Window x:Class="Recruitment_Manager.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="374" Width="940">
<Window.Resources>
<Style TargetType="Button" x:Key="NavigationButtonStyle">
<Setter Property="Height" Value="35"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="Background" Value="Transparent"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Green"/>
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="StackPanel" x:Key="NavigationButtonContentStyle">
<Setter Property="Orientation" Value="Horizontal"/>
</Style>
<Style TargetType="Image" x:Key="NavigationButtonImageStyle">
<Setter Property="Width" Value="35"/>
</Style>
<Style TargetType="Label" x:Key="NavigationButtonLabelStyle">
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontSize" Value="15"/>
</Style>
</Window.Resources>
<Grid>
<StackPanel HorizontalAlignment="Left" Width="200">
<StackPanel.Background>
<SolidColorBrush Color="#404040"/>
</StackPanel.Background>
<Button Style="{StaticResource ResourceKey=NavigationButtonStyle}">
<StackPanel Style="{StaticResource ResourceKey=NavigationButtonContentStyle}">
<Image Style="{StaticResource ResourceKey=NavigationButtonImageStyle}">
</Image>
<Label Style="{StaticResource ResourceKey=NavigationButtonLabelStyle}">
Settings
</Label>
</StackPanel>
</Button>
</StackPanel>
</Grid>
But it looks like the trigger never executes?
What am I missing or how can I get what I want?
Thank you in advance.
To remove the default MouseOver behaviour on the Button you will need to modify the ControlTemplate. Changing your Style definition to the following should do the trick:
<Style TargetType="{x:Type Button}" x:Key="NavigationButtonStyle">
<Setter Property="Height" Value="35"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Green"/>
</Trigger>
</Style.Triggers>
</Style>
Try following code
<Style TargetType="Button" x:Key="NavigationButtonStyle">
...
<Trigger Property="Control.IsMouseOver" Value="True">
<Setter Property="Background" Value="Green"/>
</Trigger>
</Style>
I am trying to style my WPF TabControl. I basically want to get the tab control to have a transparent background, with a white border and text. I want the selected tab to have a White Background and Transparent Text (or any colour text!). Essentially a 2 colour tab.
However, I cannot override the selected tab appearance - this shows as white. And my child textboxes are taking the style of the TabItem font. Note, in the screen shot my labels have their own style set so do not take the TabItem font.
I have the following XAML in place to do this. Ideally I want to create the styles so that I can reuse across the application.
Resource Dictionary
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008">
<Style x:Key="Tabs" TargetType="TabControl">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="White"/>
</Style>
<Style x:Key="TabItemStyle" TargetType="TabItem">
<Setter Property="Foreground" Value="White" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="FontSize" Value="16" />
<Setter Property="Background" Value="Transparent"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=TabItem}}" Value="True">
<Setter Property="Foreground" Value="Red"/>
<Setter Property="Background" Value="White"/>
</DataTrigger>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=TabItem}}" Value="False">
<Setter Property="Foreground" Value="LightGray"/>
<Setter Property="Background" Value="Transparent"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
Then the XAML MarkUp
<TabControl Style="{StaticResource Tabs}">
<TabItem Header="General" Style="{StaticResource TabItemStyle}">...</TabItem>
<TabItem Header="Details" Style="{StaticResource TabItemStyle}">...</TabItem>
<TabItem Header="Info" Style="{StaticResource TabItemStyle}">...</TabItem>
<TabItem Header="More Stuff..." Style="{StaticResource TabItemStyle}">...</TabItem>
</TabControl>
How can I style my tabs to be and prevent the children from sizing?
Your DataTriggers don't work. To fix it change RelatveSource to Self
Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource Self}}"
However I would suggest to change them to Triggers like so:
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="Red"/>
<Setter Property="Background" Value="White"/>
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter Property="Foreground" Value="LightGray"/>
<Setter Property="Background" Value="Transparent"/>
</Trigger>
</Style.Triggers>
You should create control template for TabItem.
This sample change TabItem background to Transparent and Text color to White.
You can use own color schema.
<Window.Resources>
<Style TargetType="TabControl">
<Setter Property="Background"
Value="Transparent" />
<Setter Property="BorderBrush"
Value="White" />
</Style>
<Style TargetType="{x:Type TabItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid>
<Border Name="Border"
Margin="0,0,-4,0"
Background="{x:Static Brushes.White}"
BorderBrush="{x:Static Brushes.White}"
BorderThickness="1,1,1,1"
CornerRadius="2,12,0,0">
<ContentPresenter x:Name="ContentSite"
Margin="12,2,12,2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
ContentSource="Header"
RecognizesAccessKey="True" />
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected"
Value="True">
<Setter Property="Panel.ZIndex"
Value="100" />
<Setter TargetName="Border"
Property="Background"
Value="{x:Static Brushes.Transparent}" />
<Setter TargetName="Border"
Property="BorderThickness"
Value="1,1,1,0" />
<Setter Property="TextBlock.Foreground"
Value="White" />
<!--<Setter Property="TextBlock.Foreground"
Value="Transparent" />-->
</Trigger>
<Trigger Property="IsEnabled"
Value="False">
<Setter TargetName="Border"
Property="Background"
Value="{x:Static Brushes.White}" />
<Setter TargetName="Border"
Property="BorderBrush"
Value="{x:Static Brushes.White}" />
<Setter Property="Foreground"
Value="{x:Static Brushes.White}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid Background="SkyBlue">
<TabControl Margin="20">
<TabItem Header="TabItem #1">
<TextBox>Tab Item #1 content</TextBox>
</TabItem>
<TabItem Header="TabItem #2">
<TextBox>Tab Item #1 content</TextBox>
</TabItem>
<TabItem Header="TabItem #3">
<TextBox>Tab Item #1 content</TextBox>
</TabItem>
</TabControl>
</Grid>
I want no animation when button is pressed, but only the foreground and the background are changed, just like metro style. I'm so perplexed.
Edit:
I create a sample in Expression Blend 4.
There are 3 states: Normal, IsMouseOver, IsPressed:
Edit 2:
I just modify the Title "In WPF: how to disable the animation when the button is pressed?" to "In WPF: how to disable the animation when the button after be pressed?"
I find some problems:
When the mouse is over or press the button, the backgroud of button is not changed;
The animation run after the button has be pressed, I just want to disable the animation.
Edit 3:
This .xaml can run in VS.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="WpfApplication17.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640" Height="480">
<Window.Resources>
<Style x:Key="ButtonStyle1" TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="White"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="Background" Value="Black"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="Black"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="Foreground" Value="Red"/>
</Trigger>
</Style.Triggers>
<Setter Property="Background" Value="White"/>
<Setter Property="BorderBrush" Value="White"/>
<Setter Property="Foreground" Value="Black" />
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
</Style>
</Window.Resources>
<Grid x:Name="LayoutRoot" >
<Button Content="Button"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Width="75"
Style="{DynamicResource ButtonStyle1}"/>
</Grid>
Try this (create a new project and just paste it beneath your definition) :
<Window.Resources>
<Style x:Key="NoAnimations" TargetType="{x:Type Button}" >
<Setter Property="Foreground" Value="Black" />
<Setter Property="Background" Value="White"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border BorderBrush="Black" BorderThickness="1">
<Border Name="border" Background="{TemplateBinding Background}" Padding="3">
<Grid>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Name="content" />
</Grid>
</Border>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Black"></Setter>
<Setter Property="Foreground" Value="White"></Setter>
</Trigger>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="Background" Value="White"></Setter>
<Setter Property="Foreground" Value="Black"></Setter>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="Black"></Setter>
<Setter Property="Foreground" Value="Red"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<StackPanel>
<Button Style="{StaticResource NoAnimations}"
Content="Testing"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="20"
/>
</StackPanel>