Home > Software engineering >  Using WPF, how can I bind to a style's DataTrigger to an specific element of an array
Using WPF, how can I bind to a style's DataTrigger to an specific element of an array

Time:01-13

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>
  • Related