Any way to reuse bindings in WPF?

I get to the point in the WPF application where all the bindings on my controls become pretty repetitive, as well as a bit detailed. Also, if I want to change this binding, I will have to change it in different places, and not just on one.

Is there a way to write the source part of the binding once, for example, to a resource, and then reuse it, referring to it with a more compact syntax. I searched for such opportunities, but did not find it.

What am I doing now

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

What I want to do (Pseudocode)

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

Is there a similar type of similar function or method that will allow me to declare a binding source once and then reuse it?

+7
variables resources wpf binding reusability
source share
3 answers

You can simply bind the someToggleButton IsChecked property to a property on your model viewmodel (DataContext) and use it. It will look something like this:

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

This will require your Window DataContext have a ToggleVisibility property of type Visibility .

EDIT:

To align further, your view model might look like this:

 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 } 

And you have to set its instance as DataContext on Window or even just on StackPanel

+1
source share

Is there a way to write the source part of the binding once, for example, to a resource, and then reuse it, referring to it with a more compact syntax.

Perhaps you can do this with PyBinding. I don’t know how possible it is, but I use it all the time to avoid type conversion. Here is an example that I use a lot.

 Visibility="{p:PyBinding BooleanToVisibility(IsNotNull($[.InstanceName]))}" 
  • BooleanToVisibility is a function that I wrote in IronPython.
  • $ [. InstanceName] is bound to the InstanceName property of the current data-bound item.

EDIT: You can also use this to bind one property of the user interface to another. Here is some information from the help file.

  • $ [NameTextBlock.Text] - The text property of the element with x: Name equal to "NameTextBlock"
  • $ [NameTextBlock] is the actual instance of TextBlock, not one of its properties
  • $ [{Self}] - get attached to yourself. Equivalent {RelativeSource Binding = {RelativeSource Self}}
  • $ [{Self} .Text] - The Text property is beside itself. Equivalent to {Binding Path = Text, RelativeSource = {RelativeSource Self}}

http://pybinding.codeplex.com/

Wrong theory

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

Second attempt

 <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> 
0
source share

Just by looking at the source code, you can group the necessary elements into your own container and then manage the container. Visibility:

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

In fact, today I would do it with VSM - you have a state with Visible elements and the state with them is not visible, and then use the GoToState Behaviors button on the Toggle button to set the state based on the button switching state.

0
source share