I have got a style as follows.
<TextBox HorizontalContentAlignment="Center" Text="{Binding IpAddress, Mode=TwoWay}" ToolTip="Ip Address of camera">
<TextBox.Style>
<Style TargetType="TextBox" xmlns:sys="clr-namespace:System;assembly=mscorlib">
<Style.Resources>
<VisualBrush x:Key="CueBannerBrush" AlignmentX="Center" AlignmentY="Center" Stretch="None">
<VisualBrush.Visual>
<Label Content="Camera Ip Address" Foreground="Gray" Opacity="0.5" FontStyle="Italic" />
</VisualBrush.Visual>
</VisualBrush>
</Style.Resources>
<Style.Triggers>
<Trigger Property="Text" Value="{x:Static sys:String.Empty}">
<Setter Property="Background" Value="{StaticResource CueBannerBrush}" />
</Trigger>
<Trigger Property="Text" Value="{x:Null}">
<Setter Property="Background" Value="{StaticResource CueBannerBrush}" />
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter Property="Background" Value="White" />
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
And I had kept it as a resource dictionary in a Skin.xaml file to be re-used as explained in the answer here.
But now I want the Content="Camera Ip Address" (the 7th line in the style) to be different for each textbox that I apply the style to. I saw SO answers this and this. These SO answers are suggesting the BasedOn attribute, but I am not sure how to apply this to my case. My case seems to be many levels deep. Can someone please suggest me how to achieve this.
Basically what I want is, for one textbox that I apply the Content should be Camera Ip Address, while for another textbox I want this content to be Camera Login. How do I achieve this?
You can set the content of that inner Label to the Tag property of the TextBox and then display it in the Label.
Like so:
<TextBox Tag="Whatever you want">
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Resources>
<VisualBrush x:Key="CueBannerBrush">
<VisualBrush.Visual>
<Label Content="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=TextBox},Path=Tag,Mode=OneWay" />
</VisualBrush.Visual>
</VisualBrush>
</Style.Resources>
</Style>
</TextBox.Style>
</TextBox>
Related
Here is the code for the Textbox in one of my form(window1.xaml) here i have applied Textbox.style for the textbox, My requirement is i want to apply this same style for all the textboxes in my project all windows(window2.xaml,window3.xaml,.........)
<TextBox Grid.Column="0" MaxLength="1000" x:Name="txtQuestionDesc" HorizontalAlignment="Stretch" TextWrapping="Wrap" AcceptsReturn="True"
Grid.Row="1"
Margin="5,0,0,5" Height="100"
Text="{Binding QuestionText, UpdateSourceTrigger=LostFocus}" >
<TextBox.Style>
<Style TargetType="TextBox" xmlns:sys="clr-namespace:System;assembly=mscorlib">
<Style.Resources>
<VisualBrush x:Key="CueBannerBrush" AlignmentX="Left" AlignmentY="Center" Stretch="None">
<VisualBrush.Visual>
<Label Content="Question Description" Foreground="LightGray" HorizontalAlignment="Center" />
</VisualBrush.Visual>
</VisualBrush>
</Style.Resources>
<Style.Triggers>
<Trigger Property="Text" Value="{x:Static sys:String.Empty}">
<Setter Property="Background" Value="{StaticResource CueBannerBrush}" />
</Trigger>
<Trigger Property="Text" Value="{x:Null}">
<Setter Property="Background" Value="{StaticResource CueBannerBrush}" />
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter Property="Background" Value="White" />
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
Add the Style on your App.xaml, it should work
I have a custom control that holds two Rectangles and several TextBoxes. I wish to change the background color of the Rectangle on MouseOver.
I add trigger as following:
<Rectangle
Grid.Column="1"
Fill="#FF383838"
Grid.ColumnSpan="3"
Margin="0,4,4,4">
<Rectangle.Style>
<Style TargetType="{x:Type Rectangle}">
<Setter Property="Fill" Value="#FF383838" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Fill" Value="#FF575757" />
</Trigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
But since rectangle is part of my control, I assume the event is not firing.
Setting a property via XAML will be applied over the style properties that you try to set. To fix this, remove Fill=#FF383838 so you should have:
<Rectangle Grid.Column="1"
Grid.ColumnSpan="3"
Margin="0,4,4,4">
//... rest of code here
Try this code:
<Window.Resources>
<Style TargetType="Rectangle" x:Key="test">
<Setter Property="Fill" Value="#FF383838" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Fill" Value="#FF575757" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Rectangle Style="{StaticResource test}" />
I've got the following pure XAML:
<DockPanel>
<ComboBox Name="combo" Height="24" Width="60">
<Border Background="Gray" Padding="20,10">
<Border.Style>
<Style TargetType="Border">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=combo, Path=IsDropDownOpen}" Value="True">
<Setter Property="Background" Value="Red"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
</ComboBox>
<TextBlock Text="{Binding ElementName=combo, Path=IsDropDownOpen}"></TextBlock>
</DockPanel>
I would expect the datatrigger to change the background colour of the border object to red as soon as the combobox is opened, but instead nothing happens.
Since you have set the background property directly on the ComboBox the trigger is not going to override that value.
This behavior is explained on MSDN.
You have to set it in the style instead like this:
<Border Padding="20,10">
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background" Value="Gray" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=combo, Path=IsDropDownOpen}" Value="True">
<Setter Property="Background" Value="Red"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
In my Window.Resources I have the following style:
<Style TargetType="TextBox" x:Key="HintText" xmlns:sys="clr-namespace:System;assembly=mscorlib">
<Style.Resources>
<VisualBrush x:Key="CueBannerBrush" AlignmentX="Left" AlignmentY="Center" Stretch="None">
<VisualBrush.Visual>
<Label Content="{DynamicResource EmptyText}" Foreground="LightGray" />
</VisualBrush.Visual>
</VisualBrush>
</Style.Resources>
<Style.Triggers>
<Trigger Property="Text" Value="{x:Static sys:String.Empty}">
<Setter Property="Background" Value="{StaticResource CueBannerBrush}" />
</Trigger>
<Trigger Property="Text" Value="{x:Null}">
<Setter Property="Background" Value="{StaticResource CueBannerBrush}" />
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter Property="Background" Value="White" />
</Trigger>
</Style.Triggers>
</Style>
If I use this for 1 TextBox with this,
<Label Content="Test" Foreground="LightGray" />
Test will show up in my TextBox if it's empty. When I try to use this style in different TextBoxes with this,
<Label Content="{DynamicResource EmptyText}" Foreground="LightGray" />
and
<TextBox.Resources>
<sys:String x:Key="EmptyText">Test</sys:String>
</TextBox.Resources>
it doesn't show anything. Is it possible to use this 1 style with a different string that is shown in the TextBox or do I have to make a different style for each TextBox?
You don't appear to be employing this style in any of the examples you give and it isn't at all clear what relationship your last XAML block has with the one before it.
However, yes you should be able to redefine EmptyText as often as you like. The Text property will be resolved in accordance with the Dependency Property value precedence rules.
So you can do something like this:
<DockPanel HorizontalAlignment="Stretch">
<DockPanel.Resources>
<Style TargetType="TextBlock">
<Setter Property="Text"
Value="{DynamicResource EmptyText/>
</Style>
<sys:String x:Key="EmptyText">Defined in the Dockpanel resource</sys:String>
</DockPanel.Resources>
<TextBlock/>
<TextBlock>
<TextBlock.Resources>
<sys:String x:Key="EmptyText">Defined in the textbox resource</sys:String>
</TextBlock.Resources>
</TextBlock>
<TextBlock>
<TextBlock.Resources>
<sys:String x:Key="EmptyText">Also defined at the textbox</sys:String>
</TextBlock.Resources>
</TextBlock>
</DockPanel>
I have search hint textbox
<TextBox
TextChanged="textboxsearch_TextChanged"
Grid.Column="4" Margin="0,0,10,10" Height="22" >
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Triggers>
<Trigger Property="Text" Value="">
<Setter Property="Background" Value="{StaticResource SearchHint}" />
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter Property="Background" Value="White" />
</Trigger>
</Style.Triggers>
<Setter Property="VerticalAlignment" Value="Bottom"/>
</Style>
</TextBox.Style>
</TextBox>
here is SearchHint style
<VisualBrush x:Key="SearchHint" Stretch="None">
<VisualBrush.Visual>
<TextBox FontStyle="Italic" Background="White" Foreground="Gray" Text="Enter search text…" />
</VisualBrush.Visual>
</VisualBrush>
The search box back ground is filled by the searchhint style. The problem I have now is how can I make the width of the visual brush fill the size of the textbox. Right now it fills only a portion of the textbox.
The Text="Enter search text…" has a white background but the rest of the textbox is gray. I wanted to have a white background with gray hint text.
Give the TextBox in the VisualBrush a large padding (to the right), and give the VisualBrush a left alignment:
<VisualBrush x:Key="SearchHint" Stretch="None" AlignmentX="Left">
<VisualBrush.Visual>
<TextBox FontStyle="Italic" Background="White" Foreground="Gray" Text="Enter search text…"
Padding="0,0,1000,0" />
</VisualBrush.Visual>
</VisualBrush>
Well for what you're trying you can bind the Width of the control in the VisualBrush to your actual target's ActualWidth
something like:
<VisualBrush x:Key="SearchHint"
Stretch="None">
<VisualBrush.Visual>
<TextBox Background="White"
FontStyle="Italic"
Foreground="Gray"
Width="{Binding ElementName=tb, Path=ActualWidth}"
Height="{Binding ElementName=tb, Path=ActualHeight}"
Text="Enter search text…" />
</VisualBrush.Visual>
</VisualBrush>
...
<TextBox Grid.Column="4"
Height="22"
TextChanged="textboxsearch_TextChanged"
x:Name="tb"
Margin="0,0,10,10">
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Triggers>
<Trigger Property="Text"
Value="">
<Setter Property="Background"
Value="{StaticResource SearchHint}" />
</Trigger>
<Trigger Property="IsKeyboardFocused"
Value="True">
<Setter Property="Background"
Value="White" />
</Trigger>
</Style.Triggers>
<Setter Property="VerticalAlignment"
Value="Bottom" />
</Style>
</TextBox.Style>
</TextBox>
However
What you're "functionally" trying to do is referred to commonly as "Watermark" / "Placeholder text" and it's much simpler to use that approach than have a complicated VisualBrush with an actual control being turned into a Brush. Just my opinion.
If you want to try the Watermark approach This Answer gives a good example for you to work with.