问题是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
,一切都会好的。
为什么相对源绑定不起作用?
答案 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)位置的位置来获取或设置绑定源”。由于弹出窗口不是显示它的控件的可视树的一部分,因此它无法解析弹出窗口之外的任何内容。