My XAML code is: <ListBox Name="Seq"><TextBlock Name="txt1" Text="Hello"/></ListBox>
Code-behind would be:Seq.Style = ...; or txt1.Style=...;
I want to make some items green, bold and italic. What should I do? Thanks.
You can add style in App.xaml as per your requirement, for example :
<Style TargetType="TextBlock" x:Key="mystyle">
<Setter Property="Foreground" Value="Green"></Setter>
<Setter Property="FontStyle" Value="Italic"></Setter>
<Setter Property="FontWeight" Value="Bold"></Setter>
</Style>
and then you can apply that style to text block of list box as below:
this.txt1.Style = (Style)Application.Current.FindResource("mystyle");
What you really should do is to bind the ItemsSource property of the ListBox to an IEnumerable<T> and then add properties to the type T that you can bind to in an ItemTemplate, e.g.:
<ListBox Name="Seq">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock x:Name="txt1" Text="{Binding TextProperty}" />
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding SomeOtherProperty}" Value="SomeValue">
<Setter TargetName="txt1" Property="Foreground" Value="Green" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
As a quick fix you could define a TextBlock style in your XAML markup:
<ListBox Name="Seq">
<ListBox.Resources>
<Style x:Key="style" TargetType="TextBlock">
<Setter Property="Foreground" Value="Green" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="FontStyle" Value="Italic" />
</Style>
</ListBox.Resources>
<TextBlock Name="txt1" Text="Hello"/>
</ListBox>
...and set the Style property of the TextBlock, either programmatically:
txt1.Style = Seq.Resources["style"] as Style;
...or directly in the XAML markup:
<TextBlock Name="txt1" Text="Hello" Style="{StaticResource style}"/>
Related
Good afternoon,
I´m binding a list of doubles (Latlng) to an ItemsControl and in a TextBlock I want to make a custom text when the list binded has a count of 0. With the code I have the TextBlock is empty when the ItemsSource of the ItemsControl is that list.
What am I doing wrong?
Btw the list Latlng is a property of a class.
<ItemsControl Name="icLatLng" ItemsSource="{Binding Latlng}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock FontFamily="Arial" FontSize="14">
<TextBlock.Style>
<Style>
<Setter Property="TextBlock.Text" Value="{Binding}"></Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=ItemsControl}, Path=Items.Count}" Value="0">
<Setter Property="TextBlock.Text" Value="—"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Thanks in advance.
Welcome to SO.
ItemsControl.ItemTemplate is the template that gets applied to each element in the Items list the control is bound to. If there are no items to begin with, then it won't be created, so anything you do in it won't be seen.
I suspect what you're really trying to do is replace the look of the entire control when the list is empty. If so, you can do that by applying a new template to the ItemsControl itself using a DataTrigger on the HasItems property:
<ItemsControl Name="icLatLng" ItemsSource="{Binding Latlng}">
<ItemsControl.Style>
<Style TargetType="{x:Type ItemsControl}" BasedOn="{StaticResource {x:Type ItemsControl}}">
<Style.Triggers>
<DataTrigger Binding="{Binding HasItems, RelativeSource={RelativeSource Self}}" Value="False">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ItemsControl}">
<TextBlock Text="-" />
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ItemsControl.Style>
</ItemsControl>
I am using DataTrigger to deselect ComboBox with CheckBox (Unchecked == deselected).
What i Need is:
when i select some item from ComboBox then CheckBox need to become
Checked.
When i uncheck CheckBox then ComboBox need to deselect.
CheckBox cannot be checked if ComboBox is deselected (or if ComboBox is deselected after CheckBox is Checked ComboBox should be selected with first item)
Here is XAML (this is working version and need to be changed). Solution must be pure XAML (no C# code)!
<CheckBox HorizontalContentAlignment="Stretch" VerticalContentAlignment="Center" Margin="90,519,13,0" VerticalAlignment="Top" Height="21" Width="Auto">
<CheckBox.Style>
<Style TargetType="{x:Type CheckBox}" BasedOn="{StaticResource {x:Type CheckBox}}">
<Style.Resources>
<Style TargetType="Path">
<Setter Property="FlowDirection" Value="LeftToRight" />
</Style>
<Style TargetType="TextBlock">
<Setter Property="FlowDirection" Value="LeftToRight" />
</Style>
</Style.Resources>
<Setter Property="FlowDirection" Value="RightToLeft" />
<!--<Setter Property="IsChecked" Value="True" />
<Style.Triggers>
<DataTrigger Binding="{Binding SelectedItem, ElementName=comboBoxEventDevice, UpdateSourceTrigger=PropertyChanged}" Value="{x:Null}">
<Setter Property="IsChecked" Value="False" />
</DataTrigger>
</Style.Triggers>-->
</Style>
</CheckBox.Style>
<ComboBox x:Name="comboBoxEventDevice" FlowDirection="LeftToRight" SelectionChanged="comboBoxEventDevice_SelectionChanged" Width="Auto">
<ComboBox.Style>
<Style TargetType="{x:Type ComboBox}" BasedOn="{StaticResource {x:Type ComboBox}}">
<Setter Property="SelectedIndex" Value="1" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsChecked, RelativeSource={RelativeSource AncestorType={x:Type CheckBox}}}" Value="True">
<Setter Property="SelectedIndex" Value="0" />
</DataTrigger>
<!--<DataTrigger Binding="{Binding Path=IsChecked, RelativeSource={RelativeSource AncestorType={x:Type CheckBox}}}" Value="False">
<Setter Property="SelectedIndex" Value="1" />
</DataTrigger>-->
</Style.Triggers>
</Style>
</ComboBox.Style>
</ComboBox>
</CheckBox>
UPDATE:
I try to not use nested controls (combobox inside checkbox) so i change XAML bu everything is same as before:
<CheckBox x:Name="checkBoxEventDevice" Margin="70,600,13,0" VerticalAlignment="Top" Height="21"/>
<ComboBox x:Name="comboBoxEventDevice" Margin="90,519,10,0" VerticalAlignment="Top" SelectionChanged="comboBoxEventDevice_SelectionChanged">
<ComboBox.Style>
<Style TargetType="{x:Type ComboBox}" BasedOn="{StaticResource {x:Type ComboBox}}">
<Setter Property="SelectedIndex" Value="1" />
<Style.Triggers>
<!--<DataTrigger Binding="{Binding Path=IsChecked, ElementName=checkBoxEventDevice}" Value="True">
<Setter Property="SelectedIndex" Value="0" />
</DataTrigger>-->
<DataTrigger Binding="{Binding Path=IsChecked, ElementName=checkBoxEventDevice}" Value="false">
<Setter Property="SelectedIndex" Value="-1" />
</DataTrigger>
</Style.Triggers>
</Style>
</ComboBox.Style>
</ComboBox>
Problem is in <Setter Property="SelectedIndex" Value="1" /> line. If i remove it then ComboBox is deselected when datatrigger is off but if i keep it then when datatrigger is off combobox is set to second item. So i need some line where i can tell: do nothing, do not deselect combobox, keep current state.
I found solution and these features are satisfied :
When i select some item from ComboBox then CheckBox need to become Checked.
When i uncheck CheckBox then ComboBox need to deselect.
If ComboBox is in deselected state, and when CheckBox is Checked ComboBox should be selected with first item (if items exist elsewhere CheckBox stays checked and ComboBox deselected).
Here is XAML:
<CheckBox HorizontalContentAlignment="Stretch" VerticalContentAlignment="Center" Margin="90,519,13,0" VerticalAlignment="Top" Height="21">
<CheckBox.Style>
<Style TargetType="{x:Type CheckBox}" BasedOn="{StaticResource {x:Type CheckBox}}">
<Style.Resources>
<Style TargetType="Path">
<Setter Property="FlowDirection" Value="LeftToRight" />
</Style>
<Style TargetType="TextBlock">
<Setter Property="FlowDirection" Value="LeftToRight" />
</Style>
</Style.Resources>
<Setter Property="FlowDirection" Value="RightToLeft" />
<Setter Property="IsChecked" Value="True" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=SelectedIndex, ElementName=comboBoxEventDevice}" Value="-1">
<Setter Property="IsChecked" Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
</CheckBox.Style>
<ComboBox x:Name="comboBoxEventDevice" FlowDirection="LeftToRight" SelectionChanged="comboBoxEventDevice_SelectionChanged">
<ComboBox.Style>
<Style TargetType="{x:Type ComboBox}" BasedOn="{StaticResource {x:Type ComboBox}}">
<Setter Property="SelectedIndex" Value="0" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsChecked, RelativeSource={RelativeSource AncestorType={x:Type CheckBox}}}" Value="False">
<Setter Property="SelectedIndex" Value="-1" />
</DataTrigger>
</Style.Triggers>
</Style>
</ComboBox.Style>
</ComboBox>
</CheckBox>
Now if someone need WPF nullable ComboBox all what need to do is to simple replace existing Combobox tag in its XAML code with XAML above and change x:Name and ElementName of ComboBox to original ComboBox in these lines:
<DataTrigger Binding="{Binding Path=SelectedIndex, ElementName=comboBoxEventDevice}" Value="-1">
<ComboBox x:Name="comboBoxEventDevice" FlowDirection="LeftToRight" SelectionChanged="comboBoxEventDevice_SelectionChanged">
Also callback for SelectionChanged="comboBoxEventDevice_SelectionChanged" should be changed or removed depending do you need event handling or not.
Margins of CheckBox need to be changed to your margins (and maybe you will need to add Width property but that depends on your project) in line:
<CheckBox HorizontalContentAlignment="Stretch" VerticalContentAlignment="Center" Margin="90,519,13,0" VerticalAlignment="Top" Height="21">
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 have a TreeView where the data is bound to generic derived wrapper classes over my data hierarchy.
My bound wrapper classes include added fields like "IsHilighted" and "IsExpanded".
I would like to change the background of any TreeViewItem according to its bound data property "IsHiglighted". I would like to set the color of Hilighted item to the same (or lighter) color as the default Selected item background color.
Ideally, I would like to not modify existing XAML... I mean being able to eventually add the behavior through code.
UPDATE
I have found a partial solution: I had to add triggers as defined below. Code included below.
<Style TargetType="TreeViewItem">
<Setter Property="IsExpanded" Value="{Binding Path=IsExpanded}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsHilighted}" Value="true">
<Setter Property="Background" Value="SlateBlue"></Setter>
<Setter Property="Opacity" Value="160"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
Still not resolved: How could I bind the color of Hilighted item (see partial solution above) to the "Selected" TreeViewItem background color, i.e. replace "SlateBlue" on partial solution to binding to existing selected item style background color ?
Original TreeView XAML code:
<TreeView Name="TreeViewSelectScopeStudy" MinHeight="24" Margin="7" ItemsSource="{Binding Path=TvItemRootPssTreeViewRoot.ChildsView}" Height="Auto"
VerticalAlignment="Stretch"
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Recycling">
<TreeView.Resources>
<Style TargetType="TreeViewItem">
<Setter Property="IsExpanded" Value="{Binding Path=IsExpanded}"/>
</Style>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Red" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Green" />
<HierarchicalDataTemplate DataType="{x:Type scopeSelection:WrapperSimulatedInfoStudy}" ItemsSource="{Binding Path=Childs}">
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding Path=IsSelected}"></CheckBox>
<TextBlock Text="{Binding Path=TvItemName}" Margin="5,0,0,0"></TextBlock>
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type scopeSelection:WrapperSimulatedInfoSimulation}">
<StackPanel Orientation="Horizontal" ToolTip="{Binding Path=Item.InvalidityReason}">
<StackPanel.Style>
<Style TargetType="{x:Type StackPanel}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Item.IsValid}" Value="false">
<Setter Property="Opacity" Value="160"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
<CheckBox IsChecked="{Binding Path=IsSelected}" IsEnabled="{Binding Path=Item.IsValid}" ToolTip="{Binding Path=Item.InvalidityReason}"></CheckBox>
<CheckBox IsChecked="{Binding Path=IsHilighted}"></CheckBox>
<TextBlock Text="{Binding Path=TvItemName}" Margin="5,0,0,0" ToolTip="{Binding Path=Item.InvalidityReason}">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Item.IsValid}" Value="false">
<Setter Property="Background" Value="LightPink"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
You could define one more property called IsItemSelected and bind it to TreeViewItems IsSelected property (similar to how you have done for IsExpanded).
<Style TargetType="TreeViewItem">
<Setter Property="IsExpanded" Value="{Binding Path=IsExpanded}"/>
<Setter Property="IsSelected" Value="{Binding Path=IsItemSelected}"/>
</Style>
Then you could define a DataTrigger for the IsItemSelected property and set the background color.
<DataTrigger Binding="{Binding Path=IsItemSelected}" Value="true">
<Setter Property="Background" Value="Blue"></Setter>
</DataTrigger>
How can I set the trigger to be depend on a children's property?
Like I want to change the header of my Expander depending whether the Expander's ListView
does have children or not.
But I always get an Comilor error, that HasItems can not be resolved...
<Expander Header="Expand to add new ports">
<Expander.Resources>
<Style TargetType="{x:Type Expander}">
<Style.Triggers>
<Trigger Property="Content.HasItems" Value="False">
<Setter Property="Header" Value="No children" />
</Trigger>
</Style.Triggers>
</Style>
</Expander.Resources>
<ListView ItemsSource="{Binding Path=SomeItems}">
</ListView>
You can use a DataTrigger bound to the ListView using ElementName:
<Expander>
<Expander.Resources>
<Style TargetType="{x:Type Expander}">
<Setter Property="Header" Value="Expand to add new ports" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=ListView, Path=HasItems}" Value="False">
<Setter Property="Header" Value="No children" />
</DataTrigger>
</Style.Triggers>
</Style>
</Expander.Resources>
<ListView x:Name="ListView" ItemsSource="{Binding Path=SomeItems}">
</ListView>
</Expander>
Also note that if you set a property along with the declaration of the control the Setter in the trigger won't have any effect.
Use this:
<Setter Property="Header" Value="Expand to add new ports" />
Instead of this:
<Expander Header="Expand to add new ports">
There are multiple issues in your code -
First, you should set the property in style setter instead of declaring it locally.
Second, use DataTrigger in place of Trigger.
<Expander>
<Expander.Style>
<Style TargetType="{x:Type Expander}">
<Setter Property="Header" Value="Expand to add new ports"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=SomeItems.Count}" Value="0">
<Setter Property="Header" Value="No children" />
</DataTrigger>
</Style.Triggers>
</Style>
</Expander.Style>
<ListView ItemsSource="{Binding Path=SomeItems}">
</ListView>
</Expander>