【问题标题】:How to change itemsControl stackpanel background color如何更改 itemsControl 堆栈面板背景颜色
【发布时间】:2014-03-24 10:15:08
【问题描述】:

说我有一个包含 10 个项目的列表 someList,我将通过 itemsControl 在我的页面上显示它们,如下所示:

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

我确实能够触发someCommand 方法并且我确实能够传入someID 作为输入参数。现在我想知道如何更新 stackPanel 背景颜色,使其看起来像“选中”。这意味着现在所有项目都将具有绿色背景,当我单击其中一个堆栈面板时,该堆栈面板应将背景更改为红色并将其他项目更改回绿色

【问题讨论】:

  • 为什么不在一个组中将ItemTemplate 更改为RadioButton,并在选中/未选中时设置样式,或者更好地使用ListBox 进行单选和样式设置?
  • 或者使用ListView和dataTemplate。

标签: c# wpf itemscontrol stackpanel


【解决方案1】:

如果您想使用ItemsControl,您可以使用自定义ControlTemplateItemTemplate 更改为RadioButton,这将包括Border,而Background 将在@987654327 时更改为红色 @:

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

但是我看不出你不能将ListBoxSelectionMode=Single(默认值)一起使用并更改ListBoxItemTemplate 的原因:

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

甚至做这样的事情,而不改变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>

在 WPF 中,通常更容易选择具有所需功能的控件并将其样式设置为您想要的样式,然后以相反的方式执行此操作

【讨论】:

    【解决方案2】:

    为什么不做这样的事情

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

    【讨论】:

    • 你的方法行不通。我猜是因为MyBorder 不是唯一的?
    • 它不能那样工作 - myborder 在数据模板的范围内是唯一的(这是一个封装边界),所以它会像我展示的那样工作
    • 您需要在已绑定的数据项上使用 IsSelected 属性(例如 textblock 绑定到“某物”属性。您在视图模型中的命令需要正确设置“IsSelected”数据项。
    猜你喜欢
    • 2011-02-08
    • 2017-11-30
    • 1970-01-01
    • 2011-05-12
    • 1970-01-01
    • 2015-09-06
    • 2011-01-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多