Как избежать дублирования кода привязки в XAML-разметке? - CodeHelper

Как избежать дублирования кода привязки в XAML-разметке?

1

Рассмотрим пример:

Window1.xaml:

<Window x:Class="WpfApplication2.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <ToolBar Grid.Row="0">
            <Button Content="Button1" IsEnabled="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}, Path=IsButtonsEnabled}" />
            <Button Content="Button2" IsEnabled="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}, Path=IsButtonsEnabled}" />
            <Button Content="Button3" IsEnabled="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}, Path=IsButtonsEnabled}" />
            <Button Content="Button4" IsEnabled="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}, Path=IsButtonsEnabled}" />
        </ToolBar>
    </Grid>
</Window>

Window1.xaml.cs:

namespace WpfApplication2
{
    using System.Windows;

    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        public bool IsButtonsEnabled { get; set; }
    }
}

Видим многократное повторение одного и того же кода для привязки свойства IsEnabled каждой кнопки к свойству IsButtonsEnabled окна. Отсюда вопрос — как можно избежать подобного дублирования в XAML-разметке?

В примере можно было бы, конечно, привязать IsEnabled для всего ToolBar'а, но на практике бывает так, что необходимо сделать недоступными лишь часть кнопок.

Вынести Binding в ресурсы тоже не получается. При запуске возникает XamlParseException с сообщением "A 'Binding' cannot be used within a 'ResourceDictionary' collection. A 'Binding' can only be set on a DependencyProperty of a DependencyObject."

Новые ответы


1

А что если использовать стиль?

...
<ToolBar Grid.Row="0">
    <ToolBar.Resources>
        <Style x:Key="bindingButtonStyle" TargetType="{x:Type Button}">
            <Setter Property="IsEnabled" Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}, Path=IsButtonsEnabled}"/>
        </Style>
    </ToolBar.Resources>
    <Button Content="Button1" Style="{StaticResource bindingButtonStyle}" />
    <Button Content="Button2" />
    <Button Content="Button3" Style="{StaticResource bindingButtonStyle}"/>

При этом кнопки, к которым применен стиль, получат привязку. Ну, либо все кнопки, если стилю не задавать ключ.


v1.7.123.556
© 2009—2010 CodeHelper FAQ | О сайте | Обратная связь | История изменений | Статьи
Creative Commons LicenseМатериалы сайта распространяются под лицензией Creative Commons Attribution-Share Alike 3.0 Unported.