Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In WPF, is there a way to bind to sibling properties?

Tags:

I have a series of TextBlock and TextBox controls. Is there a way to apply a Style to the TextBlocks such that they can databind to the control immediately after them?

I'd like to be able to do something like this:

<Resources..>     <Style x:Key="BindToFollowingTextBoxSibling">         <Setter Property="TextBlock.Text" Value="{Binding RelativeSource={RelativeSource FollowingSibling}, Path=Text, Converter={StaticResource MyConverter}}" />         <Setter Property="TextBlock.Background" Value="{Binding RelativeSource={RelativeSource FollowingSibling}, Path=Text, Converter={StaticResource TextToBrushConverter}}" />         ... More properties and converters.     </Style> </Resources>  ...  <TextBlock Style="{StaticResource BindToFollowingTextBoxSibling}"/> <TextBox/>  <TextBlock Style="{StaticResource BindToFollowingTextBoxSibling}"/> <TextBox/> <TextBlock Style="{StaticResource BindToPreviousTextBoxSibling}"/> 

Is something like this even possible?

like image 644
Eclipse Avatar asked May 15 '09 21:05

Eclipse


People also ask

How many types of binding are there in WPF?

WPF binding offers four types of Binding. Remember, Binding runs on UI thread unless otherwise you specify it to run otherwise. OneWay: The target property will listen to the source property being changed and will update itself.

What is two way binding WPF?

Two way binding is used when we want to update some controls property when some other related controls property change and when source property change the actual control also updates its property.

What is relative resource in WPF?

The RelativeSource is a markup extension that is used in particular binding cases when we try to bind a property of a given object to another property of the object itself, when we try to bind a property of a object to another one of its relative parents, when binding a dependency property value to a piece of XAML in ...


1 Answers

I know this is an old thread, but I've found a solution to this problem. I was able to use Aland Li's suggestion, found here. Its not quite as generic as it is in CSS, but if you know the parent element type, this works nicely even in a Style.

Here's an example of how I used it. I have a TextBox control that lights up with a "highlight color" when it has focus. Additionally, I wanted its associated Label control to also light up when the TextBox had focus. So I wrote a Trigger for the Label control that made it light up in a similar way that the TextBox control did. This Trigger is triggered by a custom attached property called IsFocusedByProxy. Then I needed to bind the Label's IsFocusedByProxy to the TextBox's IsFocused. So I used this technique:

<Grid x:Name="MaxGrid">     <Label  x:Name="MaxLabel"             Content="Max:"               c5:TagHelper.IsFocusedByProxy="{Binding                                    Path=Children[1].IsFocused,                                   RelativeSource={RelativeSource AncestorType=Grid}}"         />      <c5:TextBoxC5Mediator x:Name="MaxTextBox"                                                      DataContext="{Binding ConfigVm.Max_mediator}" /> </Grid> 

At this point you may be thinking that its not any better than than just using ElementName in the Binding. But the difference is that now I can move this binding into a Style for reusability:

<Setter Property="C5_Behaviors:TagHelper.IsFocusedByProxy"         Value="{Binding Path=Children[1].IsFocused,                      RelativeSource={RelativeSource AncestorType=Grid}}" /> 

And now I can when I have a View full of these occurances, like this (I have setup the necessary Styles to be applied implicitly, so that's why there's no markup shown that sets the Styles):

<Grid x:Name="MaxGrid">     <Label  x:Name="MaxLabel"             Content="Max:"  />     <c5:TextBoxC5Mediator x:Name="MaxTextBox"                                                     DataContext="{Binding ConfigVm.Max_mediator}" />  </Grid>   <Grid x:Name="MinGrid">      <Label  x:Name="MinLabel"              Content="Min:" />      <c5:TextBoxC5Mediator x:Name="MinTextBox"                                                      DataContext="{Binding ConfigVm.Min_mediator}" /> </Grid> <Grid x:Name="StepFactorGrid">     <Label  x:Name="StepFactorLabel"             Content="Step Factor:" />     <c5:TextBoxC5Mediator x:Name="StepFactorTextBox"                                                     DataContext="{Binding ConfigVm.StepFactor_mediator}" /> </Grid> <!-- ... and lots more ... --> 

Which gives me these results:

Before any TextBoxes have focus:

Before any TextBoxes have focus

With different TextBoxes receiving focus:

after focus 1

after focus 2

like image 188
Jason Frank Avatar answered Nov 10 '22 01:11

Jason Frank