【问题标题】:WPF RelativeSource behaviorWPF 相对源行为
【发布时间】:2013-02-20 15:14:57
【问题描述】:

我在理解RelativeSource 绑定行为方面存在一些问题。 下面是将Label内容正确绑定到StackPanel标签的代码:

<Window x:Class="Binding_RelativeSource.MainWindow" Tag="Window Tag">
    <Grid Tag="Grid Tag">
        <StackPanel Tag="StackPanel Tag" Height="100" HorizontalAlignment="Left" Margin="156,97,0,0" Name="stackPanel1" VerticalAlignment="Top" Width="200">
            <Label Content="{Binding Path=Tag,RelativeSource={RelativeSource Mode=FindAncestor,AncestorLevel=1,AncestorType=StackPanel},FallbackValue=BindingFailed}" Height="28" Name="label1" />
        </StackPanel>
    </Grid>
</Window>

如果我更改AncestorType=GridAncestorLevel=2,上述代码不会绑定Grid 标签。 我有两个问题:

  1. 我想我应该将 AncestorLevel 更改为 2,以绑定到 Grid。但它 为AncestorLevel=1工作。为什么?

  2. 我也无法将标签绑定到窗口标签。请建议。

【问题讨论】:

    标签: wpf data-binding binding


    【解决方案1】:

    AncestorLevel 用于查找要绑定的正确祖先,这是因为该类型的祖先可能不止一个。

    这里有一个场景说明了这一点:

    <Grid Tag="AncestorLevel 3">
        <Grid Tag="AncestorLevel 2">
            <Grid Tag="AncestorLevel 1">
                <StackPanel Tag="StackPanel Tag" Height="100" HorizontalAlignment="Left" Margin="156,97,0,0" Name="stackPanel1" VerticalAlignment="Top" Width="200">
                    <Label Content="{Binding Path=Tag,RelativeSource={RelativeSource Mode=FindAncestor,AncestorLevel=1,AncestorType=Grid},FallbackValue=BindingFailed}" Height="28"  />
                    <Label Content="{Binding Path=Tag,RelativeSource={RelativeSource Mode=FindAncestor,AncestorLevel=2,AncestorType=Grid},FallbackValue=BindingFailed}" Height="28"  />
                    <Label Content="{Binding Path=Tag,RelativeSource={RelativeSource Mode=FindAncestor,AncestorLevel=3,AncestorType=Grid},FallbackValue=BindingFailed}" Height="28"  />
                </StackPanel>
            </Grid>
        </Grid>
    </Grid>
    

    结果:

    替代方法

    但是你可以通过使用ElementName绑定来简化代码,这里使用元素的Name

    例子:

    <Window x:Class="WpfApplication9.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525" Name="MyWindow" Tag="This is the window">
        <Grid Name="Grid1" Tag="First grid">
            <Grid Name="Grid2" Tag="Second grid">
                <Grid Name="Grid3" Tag="ThirdGrid">
                    <StackPanel Name="stackPanel1" Tag="StackPanel Tag" Height="160" HorizontalAlignment="Left" Margin="156,97,0,0" VerticalAlignment="Top" Width="200">
                        <Label Content="{Binding ElementName=MyWindow, Path=Tag}" Height="28"  />
                        <Label Content="{Binding ElementName=Grid1, Path=Tag}" Height="28"  />
                        <Label Content="{Binding ElementName=Grid2, Path=Tag}" Height="28"  />
                        <Label Content="{Binding ElementName=Grid3, Path=Tag}" Height="28"  />
                        <Label Content="{Binding ElementName=stackPanel1, Path=Tag}" Height="28"  />
                    </StackPanel>
                </Grid>
            </Grid>
        </Grid>
    </Window>
    

    结果:

    如果你想绑定回Window,你仍然可以使用FindAncestor

    <Window x:Class="WpfApplication9.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525" Tag="This is the window">
        <Grid>
            <StackPanel Height="100" HorizontalAlignment="Left" Margin="156,97,0,0" Name="stackPanel1" VerticalAlignment="Top" Width="200">
                <Label Content="{Binding Path=Tag,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Window},FallbackValue=BindingFailed}" Height="28"  />
            </StackPanel>
        </Grid>
    

    结果:

    【讨论】:

    • 1.这意味着在我的情况下,如果我不提及 AncestorLevel,应该没问题。我验证了它,它适用于 StackPanel & Grid 而无需设置 AncestorLevel 属性。但它不适用于Window,为什么?请给我一个理由好吗? 2.我明白了,ElementName属性绑定。对于那件事我没有任何疑问。但是,我想知道为什么 RelativeSource 绑定适用于 StackPanel 和 Grid,但不适用于 Window。请提出建议。
    • 它确实适用于窗口,Content="{Binding Path=Tag,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Window} 在这里工作正常
    • 哦,是的。它也对我有用。但它在运行时绑定窗口。对于 Grid & StackPanel,它在编译时执行。有什么具体原因吗?
    • 你用的是什么VS版本?
    • 我已经完成了与您更新的答案相同的操作。但它会在运行时更新绑定。我正在使用 VS2010。
    【解决方案2】:

    我的最终结论:VS2010 设计器的问题是它没有更新 Window 标签的 RelativeSource 绑定。它更新设计器中其他控件的绑定(我使用 Grid 和 StackPanel 检查),但对于 Winodw,它会在运行时更新。微软已经在 VS2012 中解决了这个问题。

    【讨论】:

      猜你喜欢
      • 2018-11-27
      • 2010-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多