В 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]()