[英]Binding a list of elements to a collection-based dependency property in WPF
我正在WPF应用程序(.Net 4.5)中实现自定义Blend行为。 我在行为类中添加了一些类型为FrameworkElement的依赖项属性,以允许行为的用户绑定他们想要控制的视图的元素。 (此行为会在多个元素上调用某些动画,因此我不能仅使用AssociatedObject)。 这工作正常,基本上看起来像这样:
public class MyBehavior : Behavior<FrameworkElement>
{
public static readonly DependencyProperty Element1Property = DependencyProperty.Register("Element1", typeof (FrameworkElement), typeof (MyBehavior), new UIPropertyMetadata());
public FrameworkElement Element1
{
get { return (FrameworkElement) GetValue(Element1Property); }
set { SetValue(Element1Property, value); }
}
public static readonly DependencyProperty Element2Property = DependencyProperty.Register("Element2", typeof(FrameworkElement), typeof(MyBehavior), new UIPropertyMetadata());
public FrameworkElement Element2
{
get { return (FrameworkElement) GetValue(Element2Property); }
set { SetValue(Element2Property, value); }
}
}
标准依赖项属性的东西。 我可以这样使用它:
<Grid x:Name="Container">
<i:Interaction:Behaviors>
<local:MyBehavior
Element1="{Binding ElementName=FirstElement}"
Element2="{Binding ElementName=SecondElement}"
/>
</i:Interaction:Behaviors>
</Grid>
这很好用,我可以处理行为中的元素。 但是现在我需要绑定这样的元素列表。 所以我不提前知道会有2个元素,可能需要N个元素。 因此,我向MyBehavior类添加了另一个属性,如下所示:
public static readonly DependencyProperty ElementsProperty = DependencyProperty.Register("Elements", typeof(List<FrameworkElement>), typeof(MyBehavior), new UIPropertyMetadata(new List<FrameworkElement>()));
public List<FrameworkElement> Elements
{
get { return (List<FrameworkElement>) GetValue(ElementsProperty); }
set { SetValue(ElementsProperty, value); }
}
(并且我遵循了这里的建议在行为的构造函数中初始化列表。)但是我无法弄清楚如何从视图的XAML将元素列表绑定到此属性。 基本上,我想按照以下方式做一些事情:
<Grid x:Name="Container">
<i:Interaction:Behaviors>
<local:MyBehavior>
<local:MyBehavior.Elements>
<Binding ElementName="FirstElement" />
<Binding ElementName="SecondElement" />
<Binding ElementName="ThirdElement" />
</local:MyBehavior.Elements>
</local:MyBehavior>
</i:Interaction:Behaviors>
</Grid>
但是当然这实际上不起作用。 我在这里尝试了MultiBinding,但这也不起作用。 知道这样做的XAML语法是什么,或者甚至可能吗? 如果不可能的话,对实现此效果的其他方法有什么想法? 谢谢!
我最终自己解决了这个问题。 事实证明,我可以为此使用MultiBinding。 转换器看起来像这样:
public class MultiFrameworkElementConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return values != null ?
values.Cast<FrameworkElement>().ToList() :
new List<FrameworkElement>();
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
我应该对该转换器进行更全面的检查,并确保values []数组中的所有对象的类型均为FrameworkElement,但这可以使您理解。 然后在XAML中,我可以将行为绑定到属性,如下所示:
<local:MyBehavior.Elements>
<MultiBinding Converter="{StaticResource MultiFrameworkElementConverter}" Mode="OneTime">
<Binding ElementName="FirstElement" />
<Binding ElementName="SecondElement" />
<Binding ElementName="ThirdElement" />
</MultiBinding>
</local:MyBehavior.Elements>
我在绑定上使用“ OneTime”模式仅仅是因为这些是我绑定到行为的视图中的UI元素。 在视图和行为的生命周期中,它们永远不会改变。 因此,无需更新绑定。
总的来说,我对此感到满意。 现在,无论我在哪个视图上使用它,我都可以允许该行为影响UI元素的任意列表。 我希望这个描述能够帮助其他尝试做类似事情的人。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.