문제

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

도움이 되었습니까?

해결책

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

다른 팁

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>
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top