繁体   English   中英

在WPF中将元素列表绑定到基于集合的依赖项属性

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM