在WPF中,有没有办法绑定兄弟属性?

时间:2009-05-15 21:23:22

标签: wpf data-binding xaml

我有一系列TextBlockTextBox控件。有没有办法将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}"/>

这样的事情是否可能?

2 个答案:

答案 0 :(得分:24)

我知道这是一个旧帖子,但我找到了解决此问题的方法。我能够使用 Aland Li的建议,发现here。它不像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>

此时您可能认为它不仅仅比在Binding中使用ElementName更好。 但不同的是,现在我可以将此绑定移动到Style中以便重用:

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

现在,当我有一个充满了这些出现的View时,我就可以这样(我已经设置了隐式应用的必要样式,所以这就是为什么没有显示设置样式的标记):

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

这给了我这些结果

在任何TextBox有焦点之前:

Before any TextBoxes have focus

使用不同的TextBox获得焦点:

after focus 1

after focus 2

答案 1 :(得分:17)

我认为在这种情况下最好的事情是通过ElementName绑定:

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

它将实现类似的目标。这对你有用吗?