使用XAML资源来减少重复

时间:2012-10-26 14:08:39

标签: wpf silverlight xaml

我有一个场景,我将相同的值传递给数据模板中不同按钮的多值转换器,这些按钮都可以正常工作。但是想知道通过删除可重复元素来使代码更好的方法,因为我将相同的内容传入

<telerik:RadButton.Visibility>
    <MultiBinding Converter="{StaticResource multiValueToBooleanConverter}" ConverterParameter="ViewCommentsDialog">
        <Binding Path="DataContext.CanEdit" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type UserControl}}" />
        <Binding Path="DataContext.CanView" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type UserControl}}" />
        <Binding Path="Comment"/>
        <Binding Path="ExecutionId"/>
    </MultiBinding>
</telerik:RadButton.Visibility>

代码:

<DataTemplate>
    <StackPanel Orientation="Horizontal">
        <telerik:RadButton Margin="2" Command="{Binding DataContext.ViewCommentCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" CommandParameter="{Binding}">
            <telerik:RadButton.Visibility>
                <MultiBinding Converter="{StaticResource multiValueToBooleanConverter}" ConverterParameter="ViewCommentsDialog">
                    <Binding Path="DataContext.CanEdit" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type UserControl}}" />
                    <Binding Path="DataContext.CanView" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type UserControl}}" />
                    <Binding Path="Comment"/>
                    <Binding Path="ExecutionId"/>
                </MultiBinding>
            </telerik:RadButton.Visibility>
            <telerik:RadButton.Content>
                <Image Width="20" Height="20" Source="pack://application:,,,/Mizuho.Minar.UI.Common;component/png/Comments.png" />
            </telerik:RadButton.Content>
        </telerik:RadButton>
        <telerik:RadButton Margin="2" Command="{Binding  DataContext.AddCommentCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" CommandParameter="{Binding}">
            <telerik:RadButton.Visibility>
                <MultiBinding Converter="{StaticResource multiValueToBooleanConverter}" ConverterParameter="AddCommentDialog">
                    <Binding Path="DataContext.CanEdit" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type UserControl}}" />
                    <Binding Path="DataContext.CanView" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type UserControl}}" />
                    <Binding Path="Comment"/>
                    <Binding Path="ExecutionId"/>
                </MultiBinding>
            </telerik:RadButton.Visibility>
            <telerik:RadButton.Content>
                <Image Width="20" Height="20" Source="pack://application:,,,/Mizuho.Minar.UI.Common;component/png/Comment-Add.png" />
            </telerik:RadButton.Content>
        </telerik:RadButton>
        <telerik:RadButton Margin="2" Command="{Binding DataContext.ViewBreaksCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" CommandParameter="{Binding}">
            <telerik:RadButton.Visibility>
                <MultiBinding Converter="{StaticResource multiValueToBooleanConverter}" ConverterParameter="ViewBreaksDialog">
                    <Binding Path="DataContext.CanEdit" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type UserControl}}" />
                    <Binding Path="DataContext.CanView" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type UserControl}}" />
                    <Binding Path="Comment"/>
                    <Binding Path="ExecutionId"/>
                </MultiBinding>
            </telerik:RadButton.Visibility>
            <telerik:RadButton.Content>
                <Image Width="20" Height="20" Source="pack://application:,,,/Mizuho.Minar.UI.Common;component/png/Folder-Bug.png" />
            </telerik:RadButton.Content>
        </telerik:RadButton>
    </StackPanel>
</DataTemplate>

1 个答案:

答案 0 :(得分:2)

基本上有两种非常简单的方法。

选项1 - 绑定到其他属性。

您可以在其他依赖项属性上设置绑定(实际上是多绑定),然后将按钮可见性绑定到该属性。如果您没有这样的属性的任何好的候选者,您可以使用一些简单的对象,在Resources集合中放置单个依赖属性。以下是此类对象的类的代码:

public class VisibilityValueHolder : ValueHolder<Visibility> { }

public abstract class ValueHolder<T> : DependencyObject
{
    public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
        "Value", typeof(T), typeof(ValueHolder<T>), null);
    public T Value
    {
        get { return (T)GetValue(ValueProperty); }
        set { SetValue(ValueProperty, value); }
    }

    public ValueHolder() { }

    public ValueHolder(T value)
    {
        Value = value;
    }
}

代码中的用法:

<DataTemplate>
    <StackPanel Orientation="Horizontal">
        <StackPanel.Resources>
            <common:VisibilityValueHolder x:Key="VisibilityHolder">
                <common:VisibilityValueHolder.Value>
                     <MultiBinding Converter="{StaticResource multiValueToBooleanConverter}" ConverterParameter="ViewCommentsDialog">
                        <Binding Path="DataContext.CanEdit" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type UserControl}}" />
                        <Binding Path="DataContext.CanView" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type UserControl}}" />
                        <Binding Path="Comment"/>
                        <Binding Path="ExecutionId"/>
                    </MultiBinding>
                </common:VisibilityValueHolder.Value>
            </common:VisibilityValueHolder.Value>
        </StackPanel.Resources>

        <telerik:RadButton Margin="2" Command="{Binding DataContext.ViewCommentCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" CommandParameter="{Binding}"
                Visibility={Binding Value, Source={StaticResource VisibilityHolder}}>
            <telerik:RadButton.Content>
                <Image Width="20" Height="20" Source="pack://application:,,,/Mizuho.Minar.UI.Common;component/png/Comments.png" />
            </telerik:RadButton.Content>
        </telerik:RadButton>

选项2 - 在Setter中使用带有绑定的Style

您可以声明隐式或显式样式(如果您想对所有按钮应用相同的可见性,或者仅对所选按钮应用相同的可见性)。

您的代码如下所示:

<DataTemplate>
    <StackPanel Orientation="Horizontal">
        <StackPanel.Resources>
            <Style TargetType="telerik:RadButton">
                <Setter Property="Visibility">
                    <Setter.Value>
                        <MultiBinding Converter="{StaticResource multiValueToBooleanConverter}" ConverterParameter="ViewCommentsDialog">
                            <Binding Path="DataContext.CanEdit" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type UserControl}}" />
                            <Binding Path="DataContext.CanView" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type UserControl}}" />
                            <Binding Path="Comment"/>
                            <Binding Path="ExecutionId"/>
                        </MultiBinding>
                    </Setter.Value>
                </Setter>
            </Style>
        </StackPanel.Resources>

        <telerik:RadButton Margin="2" Command="{Binding DataContext.ViewCommentCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" CommandParameter="{Binding}">
            <telerik:RadButton.Content>
                <Image Width="20" Height="20" Source="pack://application:,,,/Mizuho.Minar.UI.Common;component/png/Comments.png" />
            </telerik:RadButton.Content>
        </telerik:RadButton>