如何在底层对象状态更改时触发 ListBoxItem 的样式更改?

Posted

技术标签:

【中文标题】如何在底层对象状态更改时触发 ListBoxItem 的样式更改?【英文标题】:How to trigger a ListBoxItem's style change on the underlying object state change? 【发布时间】:2021-10-31 07:59:48 【问题描述】:

我有一个ListBox 的基本设置,其ItemSource 属性设置为ObservableCollection<Human>

<ListBox ItemsSource="Humans" DisplayMemberPath="Name">
  <ListBox.ItemContainerStyle>
    <Style TargetType="ListBoxItem">
        <!-- Some setters -->
    </Style>
</ListBox>

Human 是这样定义的:

public class Human 

  public string Name  get; set; 
  public bool IsAnswered  get; set; 

  public override string ToString() => this.Name;

所以我们有一个 Human 对象作为列表框的每个项目的源,并显示其字符串表示形式的默认行为(在本例中为 Name 属性)。

现在,当IsAnswered 更改为true 时,我希望将显示的Human.Name 值设置为粗体。如何做到这一点?

【问题讨论】:

通过 ItemContainerStyle 中的 DataTrigger 或 ItemTemplate 中的 Binding。人类必须实现 INotifyPropertyChanged 并在 IsAnswered 设置器中触发 PropertyChanged 事件。 但是如何将DataTrigger 中的ItemContainerStyle 指向IsAnswered 项目容器的 DataContext 始终是数据模型,在您的情况下是 Human 实例。 【参考方案1】:

项目容器的DataContext 始终是数据模型,在您的情况下是Human 实例。因此只需绑定到DataContext

<ListBox>
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Style.Triggers>
                <DataTrigger Binding="Binding IsAnswered" Value="True">
                    <Setter Property="FontWeight" Value="Bold" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ListBox.ItemContainerStyle>           
</ListBox>

正如 cmets 中已经指出的,您必须让 Human 实现 INotifyPropertyChanged。属性IsAnswered 必须引发INotifyPropertyChanged.PropertyChanged 事件。否则属性的变化不会被传播。

【讨论】:

@Luuklag 思考我是否真的像你所说的那样“表现出了努力” ,但该网站的成立理由首先是回答问题,而不是要求其他人“做出足够的努力”才能被某些精英俱乐部录取。如果有人认为我没有付出足够的努力,可以很高兴地忽略我的问题,让其他可能认为其他人回答。幸运的是,我的问题得到了一个有效且有用的答案,因此真正使任何关闭问题无效。 我同意你的观点。但请再次考虑我的观点。少即是多。就像您说的那样,添加额外的上下文可能会有所帮助,但也很容易(我认为更容易)没有帮助并使问题不那么集中。这就是所谓的关闭原因。我可以在代码中呈现的文本段落只是一个易于理解的句子——在这种情况下它真的会改变什么吗?还要考虑一下我是在家里写的,无法访问生产机器。从内存中生成有效代码并不容易,而且容易出错。 感谢您的意见。我根据您的建议稍微编辑了答案并添加了更多上下文。检查生产代码。它有效。 是的,我看到了决定留下什么和包括什么的困难。这就是为什么我说:当我们提供最少的代码时,除了准确地重现问题之外什么都不做,那么你就不会做错了。艺术不是决定要留下什么,而是花时间减少代码,去除所有令人分心的噪音,并且仍然拥有我们可以审查甚至调试的最少可行代码。如果你设法做到这一点,没有人会抱怨。人们也会对好的问题投赞成票。如果我发现这样的问题,我会很乐意回答它。无需为了获取更多信息而进行耗时的询问。 我很高兴你是那种人。很好的谈话,没有攻击性,谢谢

以上是关于如何在底层对象状态更改时触发 ListBoxItem 的样式更改?的主要内容,如果未能解决你的问题,请参考以下文章

更新底层 SQL 表时如何在 Access 中触发 VBA 代码?

如何在触发状态转换 ui-router 时保留 ui-view 的旧内容并更改另一个

Swift inout 如何在未更改时不复制回属性,以不触发对象设置器

鼠标在圆角QPushButton时如何不触发悬停状态?

在mat-sidenav组件的'closing'事件中更改状态时,角度动画不会触发?

Vue.js 组件内部状态在底层数据更改时被重用