I'm trying to using DataTemplates and Styles with DataTriggers to simplify my code and I'm having difficulty figuring out how to properly set up the binding. I keep staring at this and just feel 'stuck' with where to go next.
The DataTemplate will be applied to the items in a ListView, and the items themselves will be a [5,5] array of booleans. I'm merely trying to display these items where the border background is red if true, and white if false.
Am I going down the wrong path entirely and should be utilizing a UserControl?
<Style x:Key="BingoCell" TargetType="Border">
<Setter Property="Background" Value="White"/>
<Style.Triggers>
<DataTrigger Binding="{Binding}" Value="True">
<Setter Property="Background" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
<DataTemplate x:Key="BingoRulesTemplate">
<Grid Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border Grid.Row="0" Grid.Column="0" BorderBrush="Black" BorderThickness="1" Style="{StaticResource BingoCell}"/>
<Border Grid.Row="0" Grid.Column="1" BorderBrush="Black" BorderThickness="1" Style="{StaticResource BingoCell}"/>
<Border Grid.Row="0" Grid.Column="2" BorderBrush="Black" BorderThickness="1" Style="{StaticResource BingoCell}"/>
<Border Grid.Row="0" Grid.Column="3" BorderBrush="Black" BorderThickness="1" Style="{StaticResource BingoCell}"/>
<Border Grid.Row="0" Grid.Column="4" BorderBrush="Black" BorderThickness="1" Style="{StaticResource BingoCell}"/>
<Border Grid.Row="1" Grid.Column="0" BorderBrush="Black" BorderThickness="1" Style="{StaticResource BingoCell}"/>
<Border Grid.Row="1" Grid.Column="1" BorderBrush="Black" BorderThickness="1" Style="{StaticResource BingoCell}"/>
<Border Grid.Row="1" Grid.Column="2" BorderBrush="Black" BorderThickness="1" Style="{StaticResource BingoCell}"/>
<Border Grid.Row="1" Grid.Column="3" BorderBrush="Black" BorderThickness="1" Style="{StaticResource BingoCell}"/>
<Border Grid.Row="1" Grid.Column="4" BorderBrush="Black" BorderThickness="1" Style="{StaticResource BingoCell}"/>
<Border Grid.Row="2" Grid.Column="0" BorderBrush="Black" BorderThickness="1" Style="{StaticResource BingoCell}"/>
<Border Grid.Row="2" Grid.Column="1" BorderBrush="Black" BorderThickness="1" Style="{StaticResource BingoCell}"/>
<Border Grid.Row="2" Grid.Column="2" BorderBrush="Black" BorderThickness="1" Style="{StaticResource BingoCell}"/>
<Border Grid.Row="2" Grid.Column="3" BorderBrush="Black" BorderThickness="1" Style="{StaticResource BingoCell}"/>
<Border Grid.Row="2" Grid.Column="4" BorderBrush="Black" BorderThickness="1" Style="{StaticResource BingoCell}"/>
<Border Grid.Row="3" Grid.Column="0" BorderBrush="Black" BorderThickness="1" Style="{StaticResource BingoCell}"/>
<Border Grid.Row="3" Grid.Column="1" BorderBrush="Black" BorderThickness="1" Style="{StaticResource BingoCell}"/>
<Border Grid.Row="3" Grid.Column="2" BorderBrush="Black" BorderThickness="1" Style="{StaticResource BingoCell}"/>
<Border Grid.Row="3" Grid.Column="3" BorderBrush="Black" BorderThickness="1" Style="{StaticResource BingoCell}"/>
<Border Grid.Row="3" Grid.Column="4" BorderBrush="Black" BorderThickness="1" Style="{StaticResource BingoCell}"/>
<Border Grid.Row="4" Grid.Column="0" BorderBrush="Black" BorderThickness="1" Style="{StaticResource BingoCell}"/>
<Border Grid.Row="4" Grid.Column="1" BorderBrush="Black" BorderThickness="1" Style="{StaticResource BingoCell}"/>
<Border Grid.Row="4" Grid.Column="2" BorderBrush="Black" BorderThickness="1" Style="{StaticResource BingoCell}"/>
<Border Grid.Row="4" Grid.Column="3" BorderBrush="Black" BorderThickness="1" Style="{StaticResource BingoCell}"/>
<Border Grid.Row="4" Grid.Column="4" BorderBrush="Black" BorderThickness="1" Style="{StaticResource BingoCell}"/>
</Grid>
</DataTemplate>
CodePudding user response:
You can bind to a specific position in a jagged array using the following syntax:
<DataTrigger Binding="{Binding [0][0]}" Value="True">
<Setter Property="Background" Value="Red"/>
</DataTrigger>
Unfortunately this means that you will need a separate Style
with a separate Trigger
for each bool
in the array(s). There is no way to dynamically replace just the binding path in a template but keep the rest. XAML doesn't support this.
One option would be to create the styles/templates programmatically, for example using the XamlReader.Parse method.
Or replace the jagged array with a view model class that has a property that can be used to determine the background colour of the Border
in the template.
CodePudding user response:
Thanks to @Clemens and @Andy I was able to find a solution using a pair of nested ItemsControl that worked for me. I did have to flatten the 5x5 array of bools.
<ItemsControl x:Name="ExamplePatterns" Grid.Row="1" ItemsSource="{Binding GameRules.ExamplePatterns}" HorizontalAlignment="Center">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="1"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ItemsControl ItemsSource="{Binding BoolsFlat}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Margin="10" Columns="5" Background="Azure"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Black" BorderThickness="1" Style="{StaticResource BingoCell}">
<TextBlock Text="" Height="Auto" Width="{Binding ActualHeight, RelativeSource={RelativeSource Self}}"/>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>