WPF - 如何结合DataTrigger和触发器?

发布于 2024-07-14 13:20:25 字数 1280 浏览 4 评论 0原文

注意我已经问过相关问题:如何结合DataTrigger和EventTrigger?

我有一个包含多个项目的列表框。 该项目的类实现 INotifyPropertyChanged 并具有属性 IsAvailable。 我使用该属性来使用不同的颜色来指示列表中不可用的选项。

但是,如果所选项目不可用,则前景色应为红色。

<ListBox>
  <ListBox.Resources>
    <DataTemplate DataType="{x:Type local:InstitutionViewModel}">
      <TextBlock Name="Name" Text="{Binding Name}"/>
      <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding IsAvailable}" Value="False">
          <Setter TargetName="Name" Property="Foreground" Value="#888"/>
        </DataTrigger>
      </DataTemplate.Triggers>
    </DataTemplate>
  </ListBox.Resources>
</ListBox>

我使用上述数据触发器将不可用的项目灰显。

我面临的问题是,选择该项目的事实与模板绑定的基础数据无关。 我真正想要的是某种多触发器,它支持依赖属性 (ListBoxItem.IsSelected) 上的常规 Trigger 以及 DataTrigger > 在绑定的数据项上。

可以在不将选择概念引入我的视图模型的情况下完成此操作吗?

对于任何想知道为什么我不禁用不可用项目的人,请理解,应用程序要求可以选择不可用的选项。 实际上有几个列表框,其中一个列表框的选择会影响其他列表框中可用的内容。 我无法禁用这些项目,因为如果根据之前的选择禁用项目,用户将无法改变主意或探索不同的组合。

NOTE I have asked the related question: How to combine DataTrigger and EventTrigger?

I have a list box containing several items. The item's class implements INotifyPropertyChanged and has a property IsAvailable. I use that property to indicate unavailable options in the list using a different colour.

However, if a selected item is not available, then the foreground colour should be red.

<ListBox>
  <ListBox.Resources>
    <DataTemplate DataType="{x:Type local:InstitutionViewModel}">
      <TextBlock Name="Name" Text="{Binding Name}"/>
      <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding IsAvailable}" Value="False">
          <Setter TargetName="Name" Property="Foreground" Value="#888"/>
        </DataTrigger>
      </DataTemplate.Triggers>
    </DataTemplate>
  </ListBox.Resources>
</ListBox>

I use the above data trigger to grey out unavailable items.

The problem I'm facing is that the fact that the item is selected has nothing to do with the underlying data to which the template is bound. What I really want is some kind of multi-trigger that supports both a regular Trigger on a dependency property (ListBoxItem.IsSelected) along with a DataTrigger on the bound data item.

Can this be done without introducing the concept of selection into my view model?

For anyone wondering why I do not disable unavailable items, understand that it is a requirement of the application that unavailable options may be selected. There are actually a few list boxes, and selection in one effects what's available in the others. I cannot disable the items as the user would not be able to change their minds or explore different combinations if items were disabled based upon earlier selections.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

旧竹 2024-07-21 13:20:25

对于遇到此问题的其他人,我找到了适合我的解决方案。 当然,我仍然有兴趣看到其他有趣的答案。

这就是我所做的:

<MultiDataTrigger>
  <MultiDataTrigger.Conditions>
    <Condition Binding="{Binding
      RelativeSource={
        RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}},
        Path=IsSelected}" Value="True"/>
    <Condition Binding="{Binding IsAvailable}" Value="False"/>
  </MultiDataTrigger.Conditions>
  <Setter TargetName="Name" Property="Foreground" Value="#F00"/>
</MultiDataTrigger>

虽然这是一个多触发器,但没有什么特别的。 如果您只想在数据模板中以不同的方式设置所选项目的样式,您可以使用:

<DataTrigger Binding="{Binding 
  RelativeSource={
    RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}},
    Path=IsSelected}" Value="True">
  <Setter TargetName="Name" Property="Foreground" Value="#888"/>
</DataTrigger>

For anyone else who's up against this problem, I found a solution that works for me. Of course, I'm still interested to see other interesting answers.

Here's what I did:

<MultiDataTrigger>
  <MultiDataTrigger.Conditions>
    <Condition Binding="{Binding
      RelativeSource={
        RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}},
        Path=IsSelected}" Value="True"/>
    <Condition Binding="{Binding IsAvailable}" Value="False"/>
  </MultiDataTrigger.Conditions>
  <Setter TargetName="Name" Property="Foreground" Value="#F00"/>
</MultiDataTrigger>

There's nothing special about this being a multi trigger though. If you just wanted to style the selected item differently in your data template, you could use:

<DataTrigger Binding="{Binding 
  RelativeSource={
    RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}},
    Path=IsSelected}" Value="True">
  <Setter TargetName="Name" Property="Foreground" Value="#888"/>
</DataTrigger>
紅太極 2024-07-21 13:20:25

要将其与 DataGridRow 一起使用,请将绑定模式更改为 Self

Binding="{Binding RelativeSource={RelativeSource Mode=Self}, Path=... 

To use it with DataGridRow change binding mode to Self:

Binding="{Binding RelativeSource={RelativeSource Mode=Self}, Path=... 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文