I have this TabItem:
<TabItem x:Name="tabTFGWReadingMainHall" Header="Main Hall" DataContext="{Binding Meeting}">
<TabItem.Style>
<Style TargetType="{x:Type TabItem}">
<Setter Property="IsEnabled" Value="False"/>
<Setter Property="IsSelected" Value="False"/>
<Style.Triggers>
<DataTrigger Binding="{Binding NumberClasses, ConverterParameter=1, Converter={StaticResource IsEqualOrGreaterThanConverter}}" Value="True">
<Setter Property="IsEnabled" Value="True" />
</DataTrigger>
<DataTrigger Binding="{Binding SelectedItem, ElementName=comboActiveStudentAssignmentType}" Value="{x:Static StudentInfoEnums:StudentAssignmentType.BibleReadingMain}">
<Setter Property="IsSelected" Value="True"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TabItem.Style>
<Border x:Name="borderBibleReadingMain" BorderThickness="5">
<Border.Style>
<Style TargetType="Border">
<Setter Property="BorderBrush" Value="Transparent"/>
<Style.Triggers>
<DataTrigger Binding="{Binding SelectedItem, ElementName=comboActiveStudentAssignmentType}" Value="{x:Static StudentInfoEnums:StudentAssignmentType.BibleReadingMain}">
<Setter Property="BorderBrush" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<StackPanel>
<StackPanel.Style>
<Style TargetType="{x:Type StackPanel}">
<Setter Property="IsEnabled" Value="False"/>
<Style.Triggers>
<DataTrigger Binding="{Binding NumberClasses, ConverterParameter=1, Converter={StaticResource IsEqualOrGreaterThanConverter}}" Value="True">
<Setter Property="IsEnabled" Value="True" />
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
<Label Content="Student:"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<TextBox x:Name="textBibleReadingMain" Grid.Column="0" Margin="2" IsEnabled="False"
DataContext="{Binding TFGW.BibleReadingItem.Main}"
Text="{Binding DataContext.BibleReadingMain, ElementName=oclmEditor, Mode=TwoWay, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}"/>
<Button x:Name="buttonBibleReadingMain" Grid.Column="1" Background="Transparent"
DataContext="{Binding DataContext, ElementName=oclmEditor}"
Command="{Binding ApplicationCommand}" CommandParameter="BibleReadingMain">
<Image Source="Images/AssignmentTypeBibleReading16.png" Margin="2"/>
</Button>
</Grid>
<Label Content="Study:"/>
<ComboBox DataContext="{Binding DataContext, ElementName=oclmEditor}"
ItemsSource="{Binding ReadingStudyPointsList}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Number}"/>
<TextBlock Text=" - "/>
<TextBlock Text="{Binding Title}"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</StackPanel>
</Border>
</TabItem>
As you can see, it has some DataTriggers implemented. Thus, when you change the comboActiveStudentAssignmentType (over on the right edge of the editor):
This is how the controls on the left change:
Before:
After:
The DataTriggers are working right. The Border is set correctly and the TabItem gets selected. But, if possible, I would like to end up with this:
I have done some research on this and it appears that I need to use BringIntoView to get the desired results. But that needs to be called from the code behind. I added a SelectionChanged handler and did this:
private void comboActiveStudentAssignmentType_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
OCLMEditorViewModel vm = this.DataContext as OCLMEditorViewModel;
if(borderBibleReadingMain != null &&
vm.ActiveStudentAssignmentType == Data.StudentInfo.Enums.StudentAssignmentType.BibleReadingMain)
borderBibleReadingMain.BringIntoView();
// TODO: Add others here
}
Whilst it did get fired, it did not seem to make any difference. I still had to scroll the reactangle to bring it into view.
How should I be doing this?
Thank you.
Related
I have a ListView Control in WPF which displays a list of boxes from which the user can select one from the collection. What I'm currently trying to accomplish is to have Selected Item's Background Property changed to a different color for a proper identification.
I found a Code Snippet which partially solves my problem, however, the Background value of the SelectedItem reverts back to its original when I press anywhere within the module.
What I'd like to happen is for the Background value to persist for the SelectedItem regardless if I press on other controls or even if the Window gets unfocused.
Below is my XAML Code Snippet with the Setters and Triggers I currently have in place.
<ListView Grid.Row="2"
ItemsSource="{Binding FakeDispatchBoxCollection}">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<ContentPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="IsSelected" Value="True" />
</Trigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<md:Card Margin="0,0,0,10"
Cursor="Hand">
<md:Card.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListViewItem}}}" Value="true">
<Setter Property="md:Card.Background" Value="LightGray" />
</DataTrigger>
</Style.Triggers>
</Style>
</md:Card.Style>
<Grid Margin="5">
<!--#region Row & Column Definitions -->
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.60*" />
<ColumnDefinition Width="0.40*" />
</Grid.ColumnDefinitions>
<!--#endregion-->
<Label Grid.Row="0" Grid.Column="0"
Content="{Binding DispatchBoxName}"
FontWeight="ExtraBlack"
FontSize="15"
FontFamily="Baloo Bhai 2" />
<Label Grid.Row="1" Grid.Column="0"
Content="{Binding DispatchBoxType}"
FontWeight="SemiBold"
FontSize="13"
FontFamily="Baloo Bhai 2" />
<Label Grid.Row="0" Grid.Column="1"
Grid.RowSpan="2"
Content="{Binding UnitCount}"
VerticalAlignment="Center"
HorizontalAlignment="Right"
FontWeight="ExtraBlack"
FontSize="20"
FontFamily="Baloo Bhai 2" />
</Grid>
</md:Card>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
In the Item's Data Template (ItemTemplate property), you don't have any items that can accept keyboard focus. There are only Labels.
And in the ListViewItem Template Trigger (ItemContainerStyle property), you set the IsSelected property dependency on the keyboard focus inside the ListViewItem.
Also, you shouldn't use a ListView if you don't specify columns. In this case it is better to use ListBox.
An example of a correct implementation:
<Window.Resources>
<!--To simplify the example.-->
<CompositeCollection x:Key="source">
<sys:String>First</sys:String>
<sys:String>Second</sys:String>
<sys:String>Third</sys:String>
<sys:String>Fourth</sys:String>
</CompositeCollection>
</Window.Resources>
<ListBox ItemsSource="{DynamicResource source}">
<ItemsControl.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<ContentPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Label x:Name="label" Content="{Binding}"/>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}}"
Value="true">
<Setter TargetName="label" Property="Background" Value="Coral" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ListBox>
I have the same design and function for every column in my UI but it is very annoying to update something, since I have to do it for every column. Can someone help me to simplify it somehow? I already looked up a lot in the internet but I found no possibility, I want to do something like:
<Datagridentry (push monday)>
<Datagridentry (push tuesday)>
and so on...
and simply one layout which gets filled with the data.
<DataGridTextColumn Binding="{Binding Path=FirstWeek.Monday.Content}" x:Name="Column1" Width="50">
<DataGridTextColumn.HeaderTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock
Background="{Binding Path=DataContext.ColorsArray[0], RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
HorizontalAlignment="Center"
Text="Mo"
Grid.Row="0"/>
<TextBlock
HorizontalAlignment="Center"
Text="{Binding Path=DataContext.MonthDaysDate[0], RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
Grid.Row="1">
</TextBlock>
</Grid>
</DataTemplate>
</DataGridTextColumn.HeaderTemplate>
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="Margin" Value="10,5,10,5"/>
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
</DataGridTextColumn.ElementStyle>
<DataGridTextColumn.CellStyle >
<Style TargetType="DataGridCell">
<EventSetter Event="MouseUp" Handler="DataGridCell_PreviewMouseUp"/>
<Setter Property="ToolTip">
<Setter.Value>
<ToolTip Visibility="{Binding FirstWeek.Monday,Converter={StaticResource ContentVisibilityConverter}}">
<StackPanel>
<TextBlock Text="{Binding FirstWeek.Monday.Dienstbezeichnung}"/>
<TextBlock Text="{Binding FirstWeek.Monday.Comment}" Visibility="{Binding FirstWeek.Monday.Comment,Converter={StaticResource ContentVisibilityConverter}}"/>
</StackPanel>
</ToolTip>
</Setter.Value>
</Setter>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding FirstWeek.Monday, Converter={StaticResource CheckCellItem} }" Value="True"/>
<Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" Value="False"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" Value="{Binding FirstWeek.Monday.ContentColor, Converter={StaticResource ColorStringToColorConverter}}"></Setter>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
<DataGridTextColumn Binding="{Binding Path=FirstWeek.Tuesday.Content}" x:Name="Column2" Width="50">
<DataGridTextColumn.HeaderTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock
Background="{Binding Path=DataContext.ColorsArray[1], RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
HorizontalAlignment="Center"
Text="Di"
Grid.Row="0" />
<TextBlock
HorizontalAlignment="Center"
Text="{Binding Path=DataContext.MonthDaysDate[1], RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
Grid.Row="1"/>
</Grid>
</DataTemplate>
</DataGridTextColumn.HeaderTemplate>
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="Margin" Value="10,5,10,5"/>
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
</DataGridTextColumn.ElementStyle>
<DataGridTextColumn.CellStyle>
<Style TargetType="DataGridCell">
<EventSetter Event="MouseUp" Handler="DataGridCell_PreviewMouseUp"/>
<Setter Property="ToolTip">
<Setter.Value>
<ToolTip Visibility="{Binding FirstWeek.Tuesday,Converter={StaticResource ContentVisibilityConverter}}">
<StackPanel>
<TextBlock Text="{Binding FirstWeek.Tuesday.Dienstbezeichnung}"/>
<TextBlock Text="{Binding FirstWeek.Tuesday.Comment}" Visibility="{Binding FirstWeek.Tuesday.Comment,Converter={StaticResource ContentVisibilityConverter}}"/>
</StackPanel>
</ToolTip>
</Setter.Value>
</Setter>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding FirstWeek.Tuesday, Converter={StaticResource CheckCellItem} }" Value="True"/>
<Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" Value="False"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" Value="{Binding FirstWeek.Tuesday.ContentColor, Converter={StaticResource ColorStringToColorConverter}}"></Setter>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
<DataGridTextColumn Binding="{Binding Path=FirstWeek.Wednesday.Content}" Header="Mi" x:Name="Column3" Width="50">
<DataGridTextColumn.HeaderTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock
Background="{Binding Path=DataContext.ColorsArray[2], RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
HorizontalAlignment="Center"
Text="Mi"
Grid.Row="0" />
<TextBlock
HorizontalAlignment="Center"
Text="{Binding Path=DataContext.MonthDaysDate[2], RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
Grid.Row="1"/>
</Grid>
</DataTemplate>
</DataGridTextColumn.HeaderTemplate>
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="Margin" Value="10,5,10,5"/>
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
</DataGridTextColumn.ElementStyle>
<DataGridTextColumn.CellStyle>
<Style TargetType="DataGridCell">
<EventSetter Event="MouseUp" Handler="DataGridCell_PreviewMouseUp"/>
<Setter Property="ToolTip">
<Setter.Value>
<ToolTip Visibility="{Binding FirstWeek.Wednesday,Converter={StaticResource ContentVisibilityConverter}}">
<StackPanel>
<TextBlock Text="{Binding FirstWeek.Wednesday.Dienstbezeichnung}"/>
<TextBlock Text="{Binding FirstWeek.Wednesday.Comment}" Visibility="{Binding FirstWeek.Wednesday.Comment,Converter={StaticResource ContentVisibilityConverter}}"/>
</StackPanel>
</ToolTip>
</Setter.Value>
</Setter>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding FirstWeek.Wednesday, Converter={StaticResource CheckCellItem} }" Value="True"/>
<Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" Value="False"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" Value="{Binding FirstWeek.Wednesday.ContentColor, Converter={StaticResource ColorStringToColorConverter}}"></Setter>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
<DataGridTextColumn Binding="{Binding Path=FirstWeek.Thursday.Content}" Header="Do" x:Name="Column4" Width="50">
<DataGridTextColumn.HeaderTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock
Background="{Binding Path=DataContext.ColorsArray[3], RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
HorizontalAlignment="Center"
Text="Do"
Grid.Row="0" />
<TextBlock
HorizontalAlignment="Center"
Text="{Binding Path=DataContext.MonthDaysDate[3], RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
Grid.Row="1"/>
</Grid>
</DataTemplate>
</DataGridTextColumn.HeaderTemplate>
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="Margin" Value="10,5,10,5"/>
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
</DataGridTextColumn.ElementStyle>
<DataGridTextColumn.CellStyle>
<Style TargetType="DataGridCell">
<EventSetter Event="MouseUp" Handler="DataGridCell_PreviewMouseUp"/>
<Setter Property="ToolTip">
<Setter.Value>
<ToolTip Visibility="{Binding FirstWeek.Thursday,Converter={StaticResource ContentVisibilityConverter}}">
<StackPanel>
<TextBlock Text="{Binding FirstWeek.Thursday.Dienstbezeichnung}"/>
<TextBlock Text="{Binding FirstWeek.Thursday.Comment}" Visibility="{Binding FirstWeek.Thursday.Comment,Converter={StaticResource ContentVisibilityConverter}}"/>
</StackPanel>
</ToolTip>
</Setter.Value>
</Setter>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding FirstWeek.Thursday, Converter={StaticResource CheckCellItem} }" Value="True"/>
<Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" Value="False"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" Value="{Binding FirstWeek.Thursday.ContentColor, Converter={StaticResource ColorStringToColorConverter}}"></Setter>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
<DataGridTextColumn Binding="{Binding Path=FirstWeek.Friday.Content}" Header="Fr" x:Name="Column5" Width="50">
<DataGridTextColumn.HeaderTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock
Background="{Binding Path=DataContext.ColorsArray[4], RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
HorizontalAlignment="Center"
Text="Fr"
Grid.Row="0" />
<TextBlock
HorizontalAlignment="Center"
Text="{Binding Path=DataContext.MonthDaysDate[4], RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
Grid.Row="1"/>
</Grid>
</DataTemplate>
</DataGridTextColumn.HeaderTemplate>
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="Margin" Value="10,5,10,5"/>
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
</DataGridTextColumn.ElementStyle>
<DataGridTextColumn.CellStyle>
<Style TargetType="DataGridCell">
<EventSetter Event="MouseUp" Handler="DataGridCell_PreviewMouseUp"/>
<Setter Property="ToolTip">
<Setter.Value>
<ToolTip Visibility="{Binding FirstWeek.Friday,Converter={StaticResource ContentVisibilityConverter}}">
<StackPanel>
<TextBlock Text="{Binding FirstWeek.Friday.Dienstbezeichnung}"/>
<TextBlock Text="{Binding FirstWeek.Friday.Comment}" Visibility="{Binding FirstWeek.Friday.Comment,Converter={StaticResource ContentVisibilityConverter}}"/>
</StackPanel>
</ToolTip>
</Setter.Value>
</Setter>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding FirstWeek.Friday, Converter={StaticResource CheckCellItem} }" Value="True"/>
<Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" Value="False"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" Value="{Binding FirstWeek.Friday.ContentColor, Converter={StaticResource ColorStringToColorConverter}}"></Setter>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
The ElementStyle can be defined as a resource and be referenced using the StaticResource markup extension.
It's worse with the data templates since you cannot dynamically replace only a binding path in a template and keep the rest in XAML.
You may consider to create the templates programmtically using the XamlReader.Parse method. This will let you use a method like string.Replace to replace the binding path for each column. You will still have to create a template per column but it will let you define the XAML markup for the template once.
I've got a ListBox as such:
<ListBox Margin="5" ItemsSource="{Binding NetworkAdapters, Mode=OneWay}" SelectedItem="{Binding SelectedNetworkAdapter}" SelectionChanged="{s:Action SelectedNetworkAdapterChanged}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="2" VerticalAlignment="Top"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Ellipse Width="15" Height="15" Margin="5">
<Ellipse.Style>
<Style TargetType="Ellipse">
<Setter Property="Fill" Value="Gray"></Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding Status}" Value="{x:Static wpf:NetworkAdapterStatus.Up}">
<Setter Property="Fill" Value="Green"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Status}" Value="{x:Static wpf:NetworkAdapterStatus.Down}">
<Setter Property="Fill" Value="Red"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Ellipse.Style>
</Ellipse>
<StackPanel Margin="5,0,0,0">
<TextBlock Text="{Binding Name}" FontWeight="Bold"/>
<TextBlock Text="{Binding Description}"></TextBlock>
<TextBlock Text="{Binding Speed, StringFormat='Speed: {0}'}" FontSize="10"/>
<TextBlock Text="{Binding Status}" FontSize="10"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
NetworkAdapters is a collection of View Models that implement INotifyDataErrorInfo.
With the current XAML, if there is an error in any of the View Models the whole ListBox will be highlighted red, but I would like just the single ListBoxItems that contains errors to be highlighted.
I had a look at similar questions such as:
WPF ListBox ErrorTemplate and
Validating a ListBoxItem rather than a ListBox
But I still can't make this work. Any help would be appreciated.
UPDATE:
As per Krzysztof's advice, I tried wrapping the StackPanel around a border and using a DataTrigger as such:
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderThickness="1">
<Border.Resources>
<Style TargetType="Border">
<Style.Triggers>
<DataTrigger Binding="{Binding HasErrors}" Value="True">
<Setter Property="BorderBrush" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Resources>
<StackPanel> ... </StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
However, what this produces is the following:
Which is slightly different from what I expected. I would like to have the highlight around the whole ListBoxItem not just part of it as per the image.
You need to implement an ItemContainerStyle as below:
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="BorderThickness" Value="1" />
<Setter Property="BorderBrush" Value="Transparent" />
<Style.Triggers>
<DataTrigger Binding="{Binding Validation.HasErrors}" Value="True">
<Setter Property="BorderBrush" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
This will enable you to change the border of the ListBoxItem itself, so the whole things as you want.
You can forget about ErrorTemplate and just use DataTrigger to bind to Validation.HasErrors:
<StackPanel>
<StackPanel.Resources>
<Style TargetType="{x:Type StackPanel}" BasedOn="{StaticResource {x:Type StackPanel}}">
<Style.Triggers>
<DataTrigger Binding="{Binding Validation.HasErrors}" Value="True"> <!-- change all text to red -->
<Setter Property="Foreground" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Resources>
</StackPanel>
If you want a highlight, you can wrap StackPanel with a Border and set its color to red in a style.
I have a Grid like this:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20px" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="200px" />
</Grid.ColumnDefinitions>
<CheckBox Grid.Column="0" IsChecked="{Binding IsChecked, Mode = TwoWay}" VerticalAlignment="Center">
</CheckBox>
<StackPanel Grid.Column="1" Orientation="Vertical" >
<Label Content="{Binding property1}" ></Label>
<Label Content="{Binding property2}" ></Label>
</StackPanel>
<Button Grid.Column="2" Content="Click it" x:Name="myCoolbutton" Command="{Binding Parameter}"/>
</Grid>
My plan is to change the Visibility property of the button, if there is a MouseOver event on the grid's row. Actually I tried this with style triggers, but I couldn't reach my goal and it would be delightful, if anyone could give me a hint.
Thank You
EDIT:
Here are some examples of my previous work - It's as a comment, because it doesn't work properly
<Grid.Style>
<Style TargetType="{x:Type Grid}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<!-- <EventSetter Event="MouseMove" Handler="{Binding Rowhover}"></EventSetter>-->
<!-- <Setter Property="Opacity" Value="0.5"></Setter>-->
</Trigger>
<!--<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Control,AncestorLevel=1}, Path=IsMouseOver}" Value="True" >
<Setter Property="Visibility" Value="Hidden" />
</DataTrigger>-->
<!--<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Control,AncestorLevel=1}, Path=IsMouseOver}" Value="True">
<Setter TargetName="copyToClipboardButton" Property="Visibility" Value="Hidden" />
</DataTrigger>-->
</Style.Triggers>
</Style>
Add this style to the Button and when ever the Mouse is over the grid the EnterActions property will be executed , otherwise the ExitActions will be executed; effectively changing a child control property by binding its Data to an event to one of its ancestors .
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Grid},Path=(IsMouseOver)}" Value="True">
<Setter Property="SomeChildControlProperty" Value="SomeValue" />
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Grid},Path=(IsMouseOver)}" Value="False">
<Setter Property="SomeChildControlProperty" Value="SomeValue" />
</DataTrigger>
</Style.Triggers>
</Style>
I am trying to implement alternating background Color on my Rows.
I have an ItemsControl with an ItemTemplate in which I use Triggers on the Style Property of the Border.
But I end up with all RoyalBlue Rows instead of alternating with Red.
Can somene assist? Thank you very much!
<Page.Resources>
<DataTemplate x:Key="myTemplate" >
<Grid>
<Border BorderThickness="1" CornerRadius="2" Margin="2" VerticalAlignment="Stretch" Height="20" Width="Auto">
<Border.Style>
<Style TargetType="{x:Type Border}">
<Style.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="Red" />
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Background" Value="RoyalBlue" />
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Grid.Row="0" Content="{Binding Name}"/>
</Grid >
</Border>
</Grid>
</DataTemplate>
</Page.Resources>
<ScrollViewer >
<StackPanel >
<ItemsControl ItemsSource="{Binding Path=myElements}" ItemTemplate="{StaticResource myTemplate}" AlternationCount="2"/>
</StackPanel>
</ScrollViewer>
ItemsControl.AlternationIndex will be set against direct child of ItemsControl panel (ContentPresenter) so you need to use DataTrigger with RelativeSource binding and because it's an attached property you need to put in brackets like Path=(ItemsControl.AlternationIndex)
<Style TargetType="{x:Type Border}">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ContentPresenter}}, Path=(ItemsControl.AlternationIndex)}" Value="1">
<Setter Property="Background" Value="Red" />
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ContentPresenter}}, Path=(ItemsControl.AlternationIndex)}" Value="0">
<Setter Property="Background" Value="RoyalBlue" />
</DataTrigger>
</Style.Triggers>
</Style>