Question

Says I have a list of 10 items someList, I will show them on my page via itemsControl like below:

<ItemsControl DataContext="{Binding [someViewModel]}" 
              BorderBrush="Black" 
              ItemSource="{Binding someList}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Border BorderThickness="1" Background="Green">
                <StackPanel MouseDown="{Binding Path=DataContext.someCommand,   
                                        RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type ItemsControl}}}" 
                                        Command Parameter="{Binding someID}">
                    <TextBlock Text="{Binding something}">
                </StackPanel>
            </Border>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

I do able to trigger someCommand method and I do able to pass in someID as input parameter. Now I'm wondering how to update the stackPanel background color, making it looks like "selected". Meaning now all item will have a green background, when I click on one of the stackpanel, that stackpanel should change background to red and change others back to green

Was it helpful?

Solution

If you want to use ItemsControl you can change ItemTemplate to RadioButton with custom ControlTemplate that will include Border which Background would change to Red when IsChecked == true:

<ItemsControl DataContext="{Binding [someViewModel]}" BorderBrush="Black" ItemSource="{Binding someList}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <RadioButton Content="{Binding something}" GroupName="radioGroup">
                <RadioButton.Template>
                    <ControlTemplate TargetType="{x:Type RadioButton}">
                        <Border Background="Green" x:Name="PART_Border">
                            <ContentPresenter/>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsChecked" Value="True">
                                <Setter TargetName="PART_Border" Property="Background" Value="Red"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </RadioButton.Template>
            </RadioButton>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

However I don't see a reason why you cannot use ListBox with SelectionMode=Single (default value) and change Template of ListBoxItem:

<ListBox DataContext="{Binding [someViewModel]}" BorderBrush="Black" ItemSource="{Binding someList}">
    <ListBox.ItemContainerStyle>
        <Style TargetType="{x:Type ListBoxItem}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListBoxItem}">
                        <Border Background="Green" x:Name="PART_Border">
                            <ContentPresenter/>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsSelected" Value="True">
                                <Setter TargetName="PART_Border" Property="Background" Value="Red"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

or even do something like this, without changing Template:

<ListBox DataContext="{Binding [someViewModel]}" BorderBrush="Black" ItemSource="{Binding someList}">
    <ListBox.Resources>
        <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Red"/>
    </ListBox.Resources>
    <ListBox.ItemContainerStyle>
        <Style TargetType="{x:Type ListBoxItem}">
            <Setter Property="Background" Value="Green"/>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

In WPF it's generally much easier to pick a control that has functionality that you need and style it to look like you want then do this the other way round

OTHER TIPS

why not do something like this

<DataTemplate>
    <Border BorderThickness="1" Background="Green" x:Name="MyBorder">
        <StackPanel MouseDown="{Binding Path=DataContext.someCommand,   
            RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type ItemsControl}}}" 
            Command Parameter="{Binding someID}">
            <TextBlock Text="{Binding something}">
        </StackPanel>
    </Border>
    <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding Path=IsSelected}" Value="true">
                    <Setter TargetName="MyBorder" Property="Background" Value="Black" />
            </DataTrigger>
    </DataTemplate.Triggers>
</DataTemplate>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top