【发布时间】:2021-11-05 03:49:34
【问题描述】:
我有一个用户控件,用于从后面的代码动态填充 ListBox。我希望在选择父 ListBoxItem 时反转图标的颜色。
但是数据触发器不起作用。我收到以下错误消息:“找不到源:RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ListBoxItem', AncestorLevel='1'”
但是,我遇到了 2 个 DataTrigger(如下所示)开始工作的案例。
- 如果我在我的 XAML 中对用户控件进行硬编码。这不是一个选择。
- 如果我更改样式的某些内容(例如,将默认值从 true 变回 false)。所以基本上如果我强制重新评估样式。
所以我想我知道发生了什么,但我不知道该怎么做:我在后面的代码中创建了一个 UserControl 的新实例,并且 Style 和 DataTrigger 立即被评估并抛出一个错误(这使得感觉,因为它还没有添加到 VisualTree,因此没有找到祖先)。
这是我的用户控件的内容:
<UserControl.Resources>
<Style x:Key="FontAwesomeIconInvertedColorOnSelection" TargetType="fonts:FontAwesomeIcon">
<Setter Property="ReverseColors" Value="False" />
<Style.Triggers>
<DataTrigger Binding="{Binding
RelativeSource={RelativeSource
Mode=FindAncestor,
AncestorType={x:Type ListBoxItem}},
Path=IsSelected}"
Value="True">
<Setter Property="ReverseColors" Value="True" />
</DataTrigger>
</Style.Triggers>
</Style>
</UserControl.Resources>
<Grid>
<fonts:FontAwesomeIcon
Style="{StaticResource FontAwesomeIconInvertedColorOnSelection}" />
</Grid>
我能否以某种方式强制在 UserControl.Loaded 上重新评估样式?或者您对如何获得我想要的行为有其他建议?
【问题讨论】:
-
UserControl 根本不应该声明 DataTrigger 绑定,因为它会创建不必要的依赖项。为什么控件总是只能在 ListBoxItem 中使用?相反,让您的 UserControl 公开其自己的
IsSelected属性,您将 DataTrigger(或常规触发器)绑定到该属性,并在您使用该控件的 ListBox 的 ItemTemplate 中绑定。 -
从您所展示的内容来看,人们甚至可能会争论为什么有一个 UserControl,而不是一个简单的 DataTemplate 资源。
-
我省略了一些代码以减少混乱。它比上面显示的要多一点。谢谢您的建议。这很有意义!但是,如果我在 ItemTemplate 中使用我的 UserControl,那么我的 UserControl 中的 DataContext 将自动成为基础数据对象。然后如何绑定到我的 UserControl 中的 IsSelected 属性?
-
我想RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:MyUserControl} 应该可以工作。
标签: c# wpf binding datatrigger