XAML触发器设置器和UIElementCollection类型的属性

时间:2011-01-30 13:48:00

标签: wpf xaml triggers styling

我的控件具有Buttons类型的属性UIElementCollection。是否可以通过触发器修改此类属性(特别是DataTrigger)?

我有以下代码:

<Setter Property="Buttons">
    <Setter.Value>
        <Button>A</Button>
        <Button>B</Button>
    </Setter.Value>
</Setter>

我收到错误“属性值设置不止一次”。包装UIElementCollection标记中的按钮不起作用(UIElementCollection没有默认的构造函数)。如果我删除了第二个按钮,我会发现Buttons属性与类型Button不兼容。

感谢您的帮助

3 个答案:

答案 0 :(得分:3)

您可以使用附加行为来使用setter修改集合。以下是基于Panel.Children属性的工作示例,该属性也是UIElementCollection

<Grid>
    <Grid.Resources>
        <Style x:Key="twoButtons" TargetType="Panel">
            <Setter Property="local:SetCollection.Children">
                <Setter.Value>
                    <x:Array Type="UIElement">
                        <Button Content="Button1"/>
                        <Button Content="Button2"/>
                    </x:Array>
                </Setter.Value>
            </Setter>
        </Style>
    </Grid.Resources>
    <StackPanel Style="{StaticResource twoButtons}"/>
</Grid>

以下是附加属性SetCollection.Children

public static class SetCollection
{
    public static ICollection<UIElement> GetChildren(DependencyObject obj)
    {
        return (ICollection<UIElement>)obj.GetValue(ChildrenProperty);
    }

    public static void SetChildren(DependencyObject obj, ICollection<UIElement> value)
    {
        obj.SetValue(ChildrenProperty, value);
    }

    public static readonly DependencyProperty ChildrenProperty =
        DependencyProperty.RegisterAttached("Children", typeof(ICollection<UIElement>), typeof(SetCollection), new UIPropertyMetadata(OnChildrenPropertyChanged));

    static void OnChildrenPropertyChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        var panel = sender as Panel;
        var children = e.NewValue as ICollection<UIElement>;
        panel.Children.Clear();
        foreach (var child in children) panel.Children.Add(child);
    }
}

答案 1 :(得分:2)

修改:解决方法是使用转换器,在某些资源的列表中定义按钮:

    <col:ArrayList x:Key="Buttons">
        <Button>A</Button>
        <Button>B</Button>
    </col:ArrayList>

命名空间:xmlns:col="clr-namespace:System.Collections;assembly=mscorlib"

在setter中使用自定义转换器将其转换为集合:

<Setter Property="Buttons" Value="{Binding Source={StaticResource Buttons}, Converter={StaticResource ListToUIElementCollectionConverter}}"/>

编辑:要使其正常工作并非易事,因为转换器需要知道UIElementCollection构造函数的父对象。

答案 2 :(得分:0)

最后,我决定通过修改(使用触发器)集合中的各个项目(单个按钮)而不是更改整个集合来规避问题。

我只是隐藏并根据某些条件显示按钮。