RelativeSource和Popup

时间:2013-02-18 15:24:04

标签: wpf silverlight data-binding binding

问题是RelativeSource在以下情况下不起作用。我使用silverlight 5。

//From MainPage.xaml
<Grid x:Name="LayoutRoot" Background="White" Height="100" Width="200">
    <Popup IsOpen="True">
        <TextBlock Text="{Binding Path=DataContext, RelativeSource={RelativeSource AncestorType=Grid}}" />
    </Popup>
</Grid>

//From MainPage.xaml.cs
public MainPage()
{
    InitializeComponent();
    DataContext = "ololo";
}

如果我在绑定上设置断点,我将得到错误:

  

System.Exception:BindingExpression_CannotFindAncestor。

如果我使用ElementName=LayoutRoot代替RelativeSource,一切都会好的。

为什么相对源绑定不起作用?

4 个答案:

答案 0 :(得分:8)

Popup就像ContextMenu,ToolTip控件,它们没有被添加到VisualTree中。为此,你必须这样做

<Grid x:Name="LayoutRoot" Height="100" Width="200" Background="Black">
    <Popup Grid.Row="0"  x:Name="popup" DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Mode=Self}}">
        <TextBlock Text="{Binding DataContext, ElementName=popup}" Background="Red" Width="30" Height="30" />
    </Popup>
</Grid>

public MainWindow()
    {
        InitializeComponent();
        DataContext = "abcd";
        popup.PlacementTarget = LayoutRoot; 
    }

我希望这会有所帮助。不像在ContextMenu或Tooltip的情况下,在这里你还必须指定PlacementTarget。

答案 1 :(得分:2)

正如其他人所说,这是因为Popup不是视觉树的一部分。相反,您可以使用Popup的PlacementTarget属性返回可视树:

<Grid x:Name="LayoutRoot" Background="White" Height="100" Width="200">
    <Popup IsOpen="True">
        <TextBlock Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Popup}}, 
                                  Path=PlacementTarget.DataContext}" />
    </Popup>
</Grid>

答案 2 :(得分:1)

您可以制作小型黑客:通过资源设置DataContext。

<Grid.Resources>
    <Style TargetType="TextBlock">
        <Setter Property="DataContext" Value="{Binding ElementName=myGrid, Path=DataContext}" />
    </Style>
</Grid.Resources>

答案 3 :(得分:-1)

弹出窗口不是可视树的一部分。

Relative Source“通过指定绑定源相对于绑定目标(MSDN)位置的位置来获取或设置绑定源”。由于弹出窗口不是显示它的控件的可视树的一部分,因此它无法解析弹出窗口之外的任何内容。

相关问题