Я перехожу к сути дела в приложении 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>
Есть ли какой-либо подобный тип подобной функции или техники, которая позволит мне объявлять обязательный источник однажды и затем снова использовать его?
Есть ли способ написать исходную часть привязки один раз, например, в ресурсе, а затем повторно использовать его, ссылаясь на него более компактным синтаксисом.
Возможно, вы можете сделать это с PyBinding. Я не знаю степень его возможностей, но я использую все время, чтобы избежать преобразователей типа. Вот пример, который я много использую.
Visibility="{p:PyBinding BooleanToVisibility(IsNotNull($[.InstanceName]))}"
Редактировать: Вы также можете использовать это, чтобы связать одно свойство UI для другого. Вот некоторая информация из файла справки.
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>
Вы можете просто связать некоторое свойствоToggleButton
IsChecked
со свойством вашей viewmodel (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
's DataContext
было свойство под названием ToggleVisibility
типа Visibility
.
EDIT:
Для дальнейшего повышения наглядности ваша viewmodel может выглядеть следующим образом:
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
Просто посмотрев на оригинальный код, вы могли бы сгруппировать необходимые элементы в их собственный контейнер и затем управлять видимостью контейнера:
<StackPanel>
<ToggleButton x:Name="someToggleButton" />
<StackPanel Visibility="{Binding ElementName=someToggleButton, Path=IsChecked, Converter={StaticResource BoolToVisibilityConverter}}">
<Button />
<Grid />
<TextBox />
<CheckBox />
</StackPanel>
</StackPanel>
На самом деле, сегодня я бы сделал это с помощью VSM - иметь состояние с видимыми элементами и состояние, когда они не видны, затем использовать два поведения GoToState для кнопки Toggle, чтобы установить состояние на основе состояния переключения кнопки.