В WPF существует ли способ привязки к свойствам братьев?

У меня есть серия элементов управления TextBlock и TextBox. Есть ли способ применить Style к TextBlock, чтобы они могли привязывать данные к элементу управления сразу после них?

Я хотел бы сделать что-то вроде этого:

<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}"/>

Возможно ли что-то подобное?

Ответы

Ответ 1

Я думаю, что лучше всего сделать в этом случае bind by ElementName:

<TextBlock Text="{Binding ElementName=textBox1, Path=Text}" />
<TextBox x:Name="textBox1">this is the textBox 1 text</TextBox>
<TextBlock Text="{Binding ElementName=textBox2, Path=Text}" />
<TextBox x:Name="textBox2">this is the textBox 2 text</TextBox>

Он достигнет чего-то подобного. Это работает для вас?

Ответ 2

Я знаю, что это старый поток, но я нашел решение этой проблемы. Я смог использовать Aland Li, нашел здесь. Это не совсем так, как в CSS, но если вы знаете тип родительского элемента, это прекрасно работает даже в стиле.

Вот пример того, как я его использовал. У меня есть элемент управления TextBox, который загорается с "цветом подсветки", когда он имеет фокус. Кроме того, я хотел, чтобы его связанный элемент управления Label также загорался, когда TextBox имел фокус. Поэтому я написал триггер для элемента управления Label, который запустил его так же, как и элемент управления TextBox. Этот триггер запускается специальным вложенным свойством IsFocusedByProxy. Затем мне нужно было привязать Label IsFocusedByProxy к TextBox IsFocused. Поэтому я использовал эту технику:

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

На этом этапе вы можете подумать, что это не лучше, чем просто использовать ElementName в Binding. Но разница в том, что теперь я могу перенести это привязку в стиль для повторного использования:

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

И теперь я могу, когда у меня есть полный просмотр этих событий, как это (я установил необходимые стили, которые будут применяться неявно, поэтому почему нет разметки, которая устанавливает стили):

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

Что дает мне эти результаты:

Перед тем, как любые текстовые поля будут иметь фокус:

Before any TextBoxes have focus

С разными текстовыми блоками, получающими фокус:

after focus 1

after focus 2