c# - 如何编写可以承载可变数量的子属性/元素/xaml-tags 的行为
问题描述
我创建了一个Interaction.Behavior
需要接收可变数量输入的行为。
为此,该行为具有一个List<>
Dependency 属性来接收内容:
private static readonly DependencyPropertyKey FocusTargetsPropertyKey = DependencyProperty.RegisterReadOnly("Targets", typeof(List<FocusTarget>), typeof(StatefulFocusManagerBehavior), new PropertyMetadata(new List<FocusTarget>()));
public static readonly DependencyProperty FocusTargetsProperty = FocusTargetsPropertyKey.DependencyProperty;
public List<FocusTarget> Targets
{
get => (List<FocusTarget>)this.GetValue(FocusTargetsProperty);
set => this.SetValue(FocusTargetsProperty, value);
}
并且内容被实现为一个FocusTarget
派生自的类FrameworkElement
:
public class FocusTarget : FrameworkElement
{
#region DepProp: FocusTarget
public static readonly DependencyProperty FocusTargetProperty = DependencyProperty.Register("Target", typeof(FrameworkElement), typeof(FocusTarget), new PropertyMetadata(null));
public FrameworkElement Target
{
get => (FrameworkElement)this.GetValue(FocusTargetProperty);
set => this.SetValue(FocusTargetProperty, value);
}
#endregion
#region DepProp: StateName
public static readonly DependencyProperty StateNameProperty = DependencyProperty.Register("StateName", typeof(string), typeof(FocusTarget), new PropertyMetadata(null));
public string StateName
{
get => (string)this.GetValue(StateNameProperty);
set => this.SetValue(StateNameProperty, value);
}
#endregion
}
行为声明如下:
<b:Interaction.Behaviors>
<behav:StatefulFocusManagerBehavior FocusTarget="{Binding ElementName=txtResponse}">
<behav:StatefulFocusManagerBehavior.Targets>
<behav:FocusTarget Target="{Binding ElementName=txtResponse}" StateName="Text" />
<behav:FocusTarget Target="{Binding ElementName=QnAToggle}" StateName="Toggle"/>
</behav:StatefulFocusManagerBehavior.Targets>
</behav:StatefulFocusManagerBehavior>
</b:Interaction.Behaviors>
现在有什么有效的:
- 其属性绑定按预期
behav:StatefulFocusManagerBehavior
工作FocusTarget
behav:FocusTarget
实例已StateName
按预期设置其属性behav:FocusTarget
实例的属性Target
始终设置为 null
我确实怀疑这可能是一个 DataContext 问题,但无法验证也无法消除它,这让我对可能的问题和解决方案感到困惑。
我试图设置 DataContext 但这个绑定不起作用并给我 null:
<behav:FocusTarget Target="{Binding ElementName=txtResponse}"
StateName="Text"
DataContext="{Binding DataContext, RelativeSource={RelativeSource AncestorType=UserControl}}" />
解决方案
继承数据上下文和访问行为集合中的元素不能以这种方式工作,因为该集合不在可视树中,也不是启用绑定的FrameworkElement
或。Freezable
将 更改FocusTargetsProperty
为 aFreezableCollection<FocusTarget>
而不是 a List<FocusTarget>
。此外,请确保您在构造函数中分配了集合的新实例。
public class StatefulFocusManagerBehavior : Behavior<FrameworkElement>
{
private static readonly DependencyPropertyKey FocusTargetsPropertyKey = DependencyProperty.RegisterReadOnly("Targets", typeof(FreezableCollection<FocusTarget>), typeof(StatefulFocusManagerBehavior), new PropertyMetadata(null));
public static readonly DependencyProperty FocusTargetsProperty = FocusTargetsPropertyKey.DependencyProperty;
public FreezableCollection<FocusTarget> Targets
{
get => (FreezableCollection<FocusTarget>)this.GetValue(FocusTargetsProperty);
set => this.SetValue(FocusTargetsProperty, value);
}
public StatefulFocusManagerBehavior()
{
SetValue(FocusTargetsPropertyKey, new FreezableCollection<FocusTarget>());
}
}
然后,不是继承自FrameworkElement
in ,而是FocusTarget
派生自Freezable
。
public class FocusTarget : Freezable
{
protected override Freezable CreateInstanceCore()
{
return new FocusTarget();
}
// ...your other code.
}
推荐阅读
- node.js - 在 docker 容器中找不到依赖项
- python - 如何在 Python 2.7 中将参数值转换为 unicode?
- node.js - 检查公共远程 ftp 服务器上是否存在文件
- php - 在 PHP 中加密和在 VBA 中解密
- php - 检查互联网连接是否通过 PHP 工作
- sql - 如何在查询中同时选择有无 WHERE?
- java - 如何在单个 latlng arraylist 中设置纬度和经度 arraylist,然后显示 latlng 坐标列表
- java - 如何在soapUI中获取请求的http头信息?
- javascript - 通过 content-scripts 将 Vue 注入网页时如何使用 Vue Router
- python - Django 一个表单上的两个模型