Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RelativeSource and Popup

The problem is that RelativeSource does not work in the following case. I use 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";
}

If I set a breakpoint on the binding, I'll get Error:

System.Exception: BindingExpression_CannotFindAncestor.

If I use ElementName=LayoutRoot instead of RelativeSource, everything will be OK.

Why does the relative source binding not work?

like image 464
Alexander Boriskin Avatar asked Feb 18 '13 15:02

Alexander Boriskin


3 Answers

Popup is like ContextMenu , ToolTip controls , They are not added to the VisualTree. For this you will have to do like

<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; 
    }

I hope this will help.Not like in case of ContextMenu or Tooltip , here you will also have to specify the PlacementTarget.

like image 187
yo chauhan Avatar answered Sep 28 '22 04:09

yo chauhan


You can make small hack: setup DataContext via resources.

<Grid.Resources>
    <Style TargetType="TextBlock">
        <Setter Property="DataContext" Value="{Binding ElementName=myGrid, Path=DataContext}" />
    </Style>
</Grid.Resources>
like image 42
Rover Avatar answered Sep 28 '22 04:09

Rover


As others have mentioned, it's because the Popup is not part of the visual tree. Instead, you can use the Popup's PlacementTarget property to get back to the visual tree:

<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>
like image 24
17 of 26 Avatar answered Sep 28 '22 04:09

17 of 26