【发布时间】:2020-07-07 12:46:50
【问题描述】:
我正在尝试将嵌套在附加属性中的元素绑定到我的DataContext,但问题是附加属性不是逻辑树的一部分,因此没有正确设置或绑定到父对象。依赖属性,在本例中为 Value,始终为 null。
这是一些 XAML 示例
<StackPanel>
<!-- attached property of static class DataManager -->
<local:DataManager.Identifiers>
<local:TextIdentifier Value="{Binding Path=MyViewModelString}" />
<local:NumericIdentifier Value="{Binding Path=MyViewModelInt}" />
<local:NumericIdentifier Value="{Binding Path=SomeOtherInt}" />
</local:DataIdentifiers>
<!-- normal StackPanel items -->
<Button />
<Button />
</StackPanel>
由于实施,这不能是单个附加属性 - 它需要是允许 n 个实体的集合。另一个可接受的解决方案是将标识符直接放在节点中,但我认为如果不将这些元素显式包含在逻辑树中,这种语法是不可能的。即……
<Button>
<local:NumericIdentifier Value="{Binding}" />
<local:TextIdentifier Value="{Binding}" />
<TextBlock>Actual button content</TextBlock>
</Button>
这里是DataManager的实现开始。
[ContentProperty("IdentifiersProperty")]
public static class DataManager
{
public static Collection<Identifier> GetIdentifiers(DependencyObject obj)
{
return (Collection<Identifier>)obj.GetValue(IdentifiersProperty);
}
public static void SetIdentifiers(DependencyObject obj, Collection<Identifier> value)
{
obj.SetValue(IdentifiersProperty, value);
}
public static readonly DependencyProperty IdentifiersProperty =
DependencyProperty.RegisterAttached("Identifiers", typeof(Collection<Identifier>), typeof(DataManager), new FrameworkPropertyMetadata(new PropertyChangedCallback(OnIdentifiersChanged)));
}
我尝试让基类Identifiers 实现Freezable,希望它能用于数据和绑定上下文的继承,但这没有任何效果(可能是因为它嵌套在另一层中- 附加属性)。
还有几个关键点:
- 我希望这适用于任何
UIElement,而不仅仅是StackPanels -
Identifiers 不是可视化树的一部分。它们没有也不应该有视觉元素 - 因为这是一个内部库,我宁愿避免要求绑定
Source或RelativeSource,因为这样做并不直观
是否可以在标记的这一层绑定到继承的DataContext?我需要手动将这些添加到逻辑树吗?如果有,怎么做?
谢谢!
【问题讨论】:
-
您是否考虑过为 DataManager.Identifiers 属性使用 MultiBinding?它将使用返回
Collection<Identifier>的IMultiValueConverter,这也将解决您如何使用集合实例初始化Identifiers属性的问题。 -
这可能仅通过使用单个附加属性来工作,但它也增加了对混合、转换器甚至更多标记的另一个要求。我可以试一试,但希望有一个更清洁的解决方案。
标签: c# wpf xaml data-binding attached-properties