我在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); }
}
(我已按照建议here初始化行为构造函数中的列表。)但我无法弄清楚如何将元素列表绑定到此来自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语法是做什么的,或者甚至是可能的?如果不可能,有任何其他方法可以实现这种效果吗?谢谢!
答案 0 :(得分:1)
我最终解决了这个问题。事实证明,我可以使用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>
我正在使用&#34; OneTime&#34;绑定模式只是因为这些是视图中的UI元素,我绑定到了行为。它们在视图和行为的生命周期中永远不会改变。因此无需更新绑定。
总的来说,我对此表示满意。我现在可以允许行为影响任意UI元素列表,无论我使用哪个视图。我希望这个描述能够帮助其他人尝试做类似的事情。