I'm trying to write a xaml piece that will set my TextBox's text whenever it gets / loses focus. Currently it looks like this :
<TextBox Name="TextBoxLogin" HorizontalAlignment="Left" Height="25" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="160">
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Triggers>
<Trigger Property="IsMouseCaptured" Value="True">
<Setter Property="Text" Value="test"/>
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
But for some reason whenever I click it, the text doesn't change. I'd like to know why and what are my options to make it work. I also tried other properties like IsStylusCaptured and IsFocused, they didn't work either.
The issue is simple, you are setting the Text property in the first line :( Either set it in the STyle or don't set it :
<TextBox Name="TextBoxLogin" HorizontalAlignment="Left" Height="25" TextWrapping="Wrap" VerticalAlignment="Top" Width="160">
<TextBox.Style>
<Style TargetType="TextBox">
<Setter Property="Text" Value = "TextHEre"/>
<Style.Triggers>
<Trigger Property="IsMouseCaptured" Value="True">
<Setter Property="Text" Value="test"/>
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
Related
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>
I want to have dynamic editable listbox in wpf application. I am using textbox inside listbox, and I am binding Observable collection to that listbox. Now, I want to make textbox editable on mouse click. So, user can make change to textbox and save new textbox text.
<ListBox Name="ListTwo" ItemsSource="{Binding CollectionUrl, Mode=TwoWay}" >
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox Name="TextBoxList" Text="{Binding Path=urlString}" IsEnabled="False" >
</TextBox>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
You should use IsReadOnly property. In the trigger you should check IsFocused property.
In the following example, I changed foreground color to indicate which TextBox is in the edit mode.
Example:
<ListBox Name="ListTwo" ItemsSource="{Binding CollectionUrl, Mode=TwoWay}" >
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox Name="TextBoxList" Text="{Binding Path=urlString}" MinWidth="100">
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Foreground" Value="Green"/>
<Setter Property="IsReadOnly" Value="False" />
</Trigger>
<Trigger Property="IsFocused" Value="False">
<Setter Property="Foreground" Value="Red"/>
<Setter Property="IsReadOnly" Value="True" />
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
If you want to allow users save changes after edit value in the TextBox, you can add button and show in the actual editing row:
<ListBox Name="ListTwo" ItemsSource="{Binding CollectionUrl, Mode=TwoWay}" >
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="50" />
</Grid.ColumnDefinitions>
<TextBox Name="TextBoxList" Text="{Binding Path=urlString}" MinWidth="100">
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Foreground" Value="Green"/>
<Setter Property="IsReadOnly" Value="False" />
</Trigger>
<Trigger Property="IsFocused" Value="False">
<Setter Property="Foreground" Value="Red"/>
<Setter Property="IsReadOnly" Value="True" />
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
<Button Content="Save" Grid.Column="1" Command="{Binding SaveChanges}">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=TextBoxList, Path=IsFocused}" Value="True">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
My approach to accessing the text box (which was proving a nightmare) was to use your save button approach and in the Button's Button_Click function I used sender to retrieve the Button's parent, cast to (in your case) Grid. Then you can use that to access the Grid's Children with .Children[0] being your TextBox.
Bit of a Kluge because your code has to 'know' the type of the parent and the index of the child TextBox but these will not change. If necessary the purists can iterate through the Children to identify the required child explicitly.
Hope this helps someone.
I'm trying to set the width property of textbox when text is "ABC",however the trigger doesn't work. the width remains '40'.
<TextBox Height="23" HorizontalAlignment="Left" Margin="295,211,0,0" Name="textBox1" VerticalAlignment="Top" Width="40" Text="{Binding Text}" >
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Triggers>
<Trigger Property="Text" Value="ABC" >
<Setter Property="Width" Value="120"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
You need to remove the Width property in the TextBox definition because this will take precedence over the Trigger. Set the Width in a Style setter as below:
<TextBox Height="23" HorizontalAlignment="Left" Margin="295,211,0,0" Name="textBox1" VerticalAlignment="Top" Text="{Binding Text}" >
<TextBox.Style>
<Style TargetType="TextBox">
<Setter Property="Width" Value="40"/>
<Style.Triggers>
<Trigger Property="Text" Value="ABC" >
<Setter Property="Width " Value="120"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
UPDATE -
Local value has higher precedence compared to triggers. Refer to this - Dependency Property Value Precedence.
Can anyone suggest the best way to display a Textblock (with a text such as "List Empty") so that it's visibility is bound to the Items.Count.
I have tried the following code and can't get it to work, so think that I must be doing it wrong.
<ListBox x:Name="lstItems"
ItemsSource="{Binding ListItems}">
</ListBox>
<TextBlock Margin="4" FontStyle="Italic" FontSize="12" Text="List is empty" Visibility="Collapsed">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=lstItems, Path=Items.Count}" Value="0">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
The problem in your code is that setting the value of Visibility in the text block itself has higher priority than setting it in the style. So, even when the trigger occurs, the setting inside the trigger has no effect. Change the XAML to:
<TextBlock Margin="4" FontStyle="Italic" FontSize="12" Text="List is empty" >
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=lstItems, Path=Items.Count}" Value="0">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
Where the setting of Visibility is all in the style and it works (at least in my demo project).
I have a custom window which have two depencency properties: Boolean? ValidationStatus, and string ValidationMessage. Binding these properties works fine but trigger doesn't seem to be triggered when these values change. What am I doing wrong?
<TextBlock x:Name="validationTextBox"
Grid.Row="1"
Grid.ColumnSpan="2"
Text="{Binding ElementName=_this, Path=ValidationMessage}"
TextAlignment="Center"
Background="Green">
<TextBlock.Style>
<Style>
<Style.Triggers>
<DataTrigger Value="False" Binding="{Binding ElementName=_this, Path=ValidationStatus}">
<Setter Property="Panel.Background" Value="Red"/>
<Setter Property="TextBox.Text" Value="Outer checkbox is not checked"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
Style Setters do not override local attribute settings. Therefore the data trigger's values are being ignored because you have specified the Text and Background properties on the TextBlock. To fix the problem set the default values of these properties in the style as shown in the following code:
<TextBlock x:Name="validationTextBox"
Grid.Row="1"
Grid.ColumnSpan="2"
TextAlignment="Center">
<TextBlock.Style>
<Style>
<Setter Property="TextBox.Text" Value="{Binding ElementName=_this, Path=ValidationMessage}"/>
<Setter Property="TextBox.Background" Value="Green"/>
<Style.Triggers>
<DataTrigger Value="False" Binding="{Binding ElementName=_this, Path=ValidationStatus}">
<Setter Property="TextBox.Background" Value="Red"/>
<Setter Property="TextBox.Text" Value="Outer checkbox is not checked"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>