如何在选择后持久改变ListBox SelectedItem的颜色

问题描述 投票:0回答:1

我有一个列表框,用于将前景颜色设置为红色的项目加载到其中。我想做的是:用鼠标选择一个项目后,将SelectedItem的前景色更改为黑色,但要使更改持久化,以便在取消选择该项目后,颜色保持黑色。顺便说一句,我想将其实现为向用户显示“已读项目”的方式。

基本上,我想要类似通用属性触发器的实现,如下面的代码,但取消选择后不恢复样式。我也玩过事件触发器,但运气不佳。

        <ListBox.ItemContainerStyle>
            <Style TargetType="ListBoxItem">
                <Style.Triggers>
                    <Trigger Property="IsSelected" Value="True" >
                        <Setter Property="Foreground" Value="Black" />   //make this persist after deselection
                    </Trigger>
                </Style.Triggers>
            </Style>                
        </ListBox.ItemContainerStyle>

提前感谢!

c# wpf listbox selecteditem listboxitem
1个回答
0
投票

您可以为Foreground属性设置动画:

<ListBox>
  <ListBox.ItemContainerStyle>
    <Style TargetType="ListBoxItem">
      <Setter Property="Foreground" Value="Red" />

      <Style.Triggers>
        <Trigger Property="IsSelected" Value="True">
          <Trigger.EnterActions>
            <BeginStoryboard>
              <Storyboard>
                <ColorAnimation Storyboard.TargetProperty="(ListBoxItem.Foreground).(SolidColorBrush.Color)"
                                To="Black" />
              </Storyboard>
            </BeginStoryboard>
          </Trigger.EnterActions>
        </Trigger>
      </Style.Triggers>
    </Style>
  </ListBox.ItemContainerStyle>
</ListBox>

这种简单方法的缺点是信息未存储在某处。这是纯可视化,没有任何数据支持。为了保留信息,以便重新启动应用程序显示相同的先前状态,您应该为数据模型引入专用属性,例如IsMarkedAsRead

根据您的要求,您可以覆盖ListBoxItem.Template并将ToggleButton.IsChecked绑定到IsMarkedAsRead,或使用通过ICommand设置Button属性的IsMarkedAsRead。有很多解决方案,例如实现附加行为。

以下示例将覆盖ListBoxItem.Template,将其变为Button。现在,当单击该项目时,数据模型的IsMarkedAsRead属性将设置为true

数据模型(有关Microsoft Docs: Patterns - WPF Apps With The Model-View-ViewModel Design Pattern的实现示例,请参见RelayCommand。)

public class Notification : INotifyPropertyChanged
{    
  public string Text { get; set; }
  public ICommand MarkAsReadCommand => new RelayCommand(() => this.IsMarkedAsRead = true);
  public ICommand MarkAsUnreadCommand => new RelayCommand(() => this.IsMarkedAsRead = false);
  private bool isMarkedAsRead;

  public bool IsMarkedAsRead
  {
    get => this.isMarkedAsRead;
    set
    {
      this.isMarkedAsRead = value;
      OnPropertyChanged();
    }
  }

  #region INotifyPropertyChanged

  public event PropertyChangedEventHandler PropertyChanged;

  protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
  {
    this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
  }

  #endregion
}

ListBox

<ListBox ItemsSource="{Binding Notifications}">
  <ListBox.ItemContainerStyle>
    <Style TargetType="ListBoxItem">
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="ListBoxItem">
            <Border Background="{TemplateBinding Background}">
              <Button x:Name="ContentPresenter"
                      ContentTemplate="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ListBox}, Path=ItemTemplate}"
                      Content="{TemplateBinding Content}"
                      Command="{Binding MarkAsReadCommand}"
                      Foreground="Red">
                <Button.Template>
                  <ControlTemplate TargetType="Button">
                    <Border>
                      <ContentPresenter />
                    </Border>
                  </ControlTemplate>
                </Button.Template>
              </Button>
            </Border>
            <ControlTemplate.Triggers>
              <DataTrigger Binding="{Binding IsMarkedAsRead}" Value="True">
                <Setter TargetName="ContentPresenter" Property="Foreground" Value="Green" />
              </DataTrigger>
            </ControlTemplate.Triggers>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>
  </ListBox.ItemContainerStyle>

  <ListBox.ItemTemplate>
    <DataTemplate DataType="{x:Type Notification}">
      <TextBlock Text="{Binding Text}"/>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>
© www.soinside.com 2019 - 2024. All rights reserved.