Есть ли способ повторно использовать привязки в WPF? - PullRequest
7 голосов
/ 26 января 2010

Я дошел до того, что в приложении WPF все привязки на моих элементах управления становятся довольно повторяющимися и слишком многословными. Также, если я хочу изменить эту привязку, мне придется менять ее в разных местах, а не в одной.

Можно ли один раз написать исходную часть привязки, например, в ресурсе, а затем повторно использовать ее, сославшись на более компактный синтаксис. Я искал такие возможности, но не нашел.

Что я сейчас делаю

<StackPanel>
    <ToggleButton x:Name="someToggleButton" />
    <Button Visibility="{Binding ElementName=someToggleButton, Path=IsChecked, Converter={StaticResource BoolToVisibilityConverter}}" />
    <Grid Visibility="{Binding ElementName=someToggleButton, Path=IsChecked, Converter={StaticResource BoolToVisibilityConverter}}" />
    <TextBox Visibility="{Binding ElementName=someToggleButton, Path=IsChecked, Converter={StaticResource BoolToVisibilityConverter}}" />
    <CheckBox Visibility="{Binding ElementName=someToggleButton, Path=IsChecked, Converter={StaticResource BoolToVisibilityConverter}}" />
</StackPanel>

Что я хочу делать (псевдокод)

<StackPanel>
    <StackPanel.Resources>
        <Variable x:Name="someToggleButtonIsChecked" 
                  Type="{x:Type Visibility}"  
                  Value="{Binding ElementName=someToggleButton, Path=IsChecked, Converter={StaticResource BoolToVisibilityConverter}}" />
    </StackPanel.Resources>

    <ToggleButton x:Name="someToggleButton" />
    <Button Visibility="{VariableBinding someToggleButtonIsChecked}" />
    <Grid Visibility="{VariableBinding someToggleButtonIsChecked}" />
    <TextBox Visibility="{VariableBinding someToggleButtonIsChecked}" />
    <CheckBox Visibility="{VariableBinding someToggleButtonIsChecked}" />
</StackPanel>

Существует ли подобный тип аналогичной функции или метода, который позволит мне один раз объявить источник привязки и затем повторно использовать его?

Ответы [ 3 ]

1 голос
/ 26 января 2010

Вы можете просто связать свойство someToggleButton IsChecked со свойством вашей модели представления (DataContext) и использовать его. Это будет выглядеть примерно так:

<StackPanel>  
<ToggleButton x:Name="someToggleButton" IsChecked="{Binding ToggleVisibility, Mode=TwoWay, Converter={StaticResource BoolToVisibilityConverter}}"   /> 
<Button Visibility="{Binding ToggleVisibility}" /> 
<Grid Visibility="{Binding ToggleVisibility}" /> 
<TextBox Visibility="{Binding ToggleVisibility}" /> 
<CheckBox Visibility="{Binding ToggleVisibility}" /> 
</StackPanel> 

Для этого потребуется, чтобы у Window DataContext было свойство с именем ToggleVisibility типа Visibility.

EDIT:

Чтобы продолжить, ваша модель может выглядеть следующим образом:

public class SomeViewModel : INotifyPropertyChanged
{

    private Visibility toggleVisibility;

    public SomeViewModel()
    {
        this.toggleVisibility = Visibility.Visible;
    }

    public Visibility ToggleVisibility
    {
        get
        {
            return this.toggleVisibility;
        }
        set
        {
            this.toggleVisibility = value;
            RaisePropertyChanged("ToggleVisibility");
        }
    }

    private void RaisePropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion
}

И затем вы должны установить его экземпляр как DataContext на Window или даже просто на StackPanel

0 голосов
/ 10 августа 2010

Просто глядя на исходный код, вы можете сгруппировать необходимые элементы в их собственный контейнер и затем управлять контейнером. Видимость:

<StackPanel>
    <ToggleButton x:Name="someToggleButton" />
    <StackPanel Visibility="{Binding ElementName=someToggleButton, Path=IsChecked, Converter={StaticResource BoolToVisibilityConverter}}">
        <Button />
        <Grid />
        <TextBox />
        <CheckBox />
    </StackPanel>
</StackPanel>

На самом деле, сегодня я хотел бы сделать это с VSM - иметь состояние с элементами Visible и состояние с ними Not Visible, а затем использовать два поведения GoToState для кнопки Toggle, чтобы установить состояние на основе состояния переключения кнопки.

0 голосов
/ 27 января 2010

Есть ли способ написать исходную часть привязки один раз, например, в ресурсе, а затем повторно использовать ее, сославшись на более компактный синтаксис.

Возможно, вы можете сделать это с помощью PyBinding.Я не знаю степени его возможностей, но я использую его все время, чтобы не использовать преобразователи типов.Вот пример, который я часто использую.

Visibility="{p:PyBinding BooleanToVisibility(IsNotNull($[.InstanceName]))}"
  • BooleanToVisibility - это функция, которую я написал в IronPython.
  • $ [. InstanceName] привязывается к свойству InstanceName текущего элемента с привязкой к данным.

РЕДАКТИРОВАТЬ: Вы также можете использовать это для привязки свойства одного пользовательского интерфейса к другому.Вот некоторая информация из файла справки.

  • $ [NameTextBlock.Text] - Текстовое свойство элемента с x: Name, равным «NameTextBlock»
  • $ [NameTextBlock]- Фактический экземпляр TextBlock, а не одно из его свойств
  • $ [{Self}] - Привязать к себе.Эквивалент {Binding RelativeSource = {RelativeSource Self}}}
  • $ [{Self} .Text] - Свойство Text вне вашей собственной личности.Эквивалентен {Binding Path = Text, RelativeSource = {RelativeSource Self}}

http://pybinding.codeplex.com/

непроверенная теория

<StackPanel> 
    <ToggleButton x:Name="someToggleButton" /> 
    <Button Visibility="{p:PyBinding BooleanToVisibility($[someToggleButton.IsChecked])}" /> 
    <Grid Visibility="{p:PyBinding BooleanToVisibility($[someToggleButton.IsChecked])}"/> 
    <TextBox Visibility="{p:PyBinding BooleanToVisibility($[someToggleButton.IsChecked])}"/> 
    <CheckBox Visibility="{p:PyBinding BooleanToVisibility($[someToggleButton.IsChecked])}"/> 
</StackPanel> 

Вторая попытка

<StackPanel> 
    <ToggleButton x:Name="someToggleButton" /> 
    <Button Name="myButton" Visibility="{p:PyBinding BooleanToVisibility($[someToggleButton.IsChecked])}" /> 
    <Grid Visibility="{p:PyBinding $[myButton.Visibility]}"/> 
    <TextBox Visibility="{p:PyBinding $[myButton.Visibility]}"/> 
    <CheckBox Visibility="{p:PyBinding $[myButton.Visibility]}"/> 
</StackPanel> 
...