如何解决如何编写可以承载可变数量的子属性/元素/xaml 标签的行为
我创建了一个需要接收可变数量输入的 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),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,但此绑定不起作用并给我空值:
<behav:FocusTarget Target="{Binding ElementName=txtResponse}"
StateName="Text"
DataContext="{Binding DataContext,RelativeSource={RelativeSource AncestorType=UserControl}}" />
解决方法
从行为集合继承数据上下文和访问元素不会这样,因为集合不在可视化树中,也不是启用绑定的 FrameworkElement
或 Freezable
。
将 FocusTargetsProperty
更改为 FreezableCollection<FocusTarget>
而不是 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
中的 FocusTarget
继承,而是从 Freezable
派生。
public class FocusTarget : Freezable
{
protected override Freezable CreateInstanceCore()
{
return new FocusTarget();
}
// ...your other code.
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。