wpf - 使用 XAML 资源减少重复

标签 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 - 绑定(bind)到其他属性。

您可以在其他一些依赖属性上设置您的绑定(bind)(实际上是多重绑定(bind)),然后将您的按钮可见性绑定(bind)到该属性。如果您没有适合此类属性的候选者,则可以使用一些简单的对象,该对象具有放置在 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 中使用带有绑定(bind)的样式

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

您的代码如下所示:

<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>

关于wpf - 使用 XAML 资源减少重复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13088524/

相关文章:

c# - ListBox.ItemsSource 的显示属性

.net - Silverlight、EDM/LINQ 和 WCF Web 服务 - 如何将集合传递给 Silverlight

silverlight - 是否需要 System.Web.Silverlight 引用?

c# - Windows 8 XAML Metro App 中的基本 UserControl 类

c# - 通过文本窗口应用程序崩溃搜索

c# - 在 Popup 中使用 WinFormElementHost

c# - Silverlight中用于Wave文件的Sound Visualizer

c# - AvalonEdit (C#) XSHD 文件中的自定义属性

wpf - 在样式的名称范围中找不到 Storyboard

wpf - 在显示加载缓慢的用户控件时保持 WPF UI 响应