Evaniar
Evaniar

Reputation: 143

How to get access to parent's DataContext

how can I get access to a parent's DataContext?

I've got an UserControl containing 3 buttons, which I want to use for several different UserControls - so the user has always the same actions available.

When clicked on button 'Add' I need to do something inside the current DataContext, which isn't much of a hassle since I can just do the following:

public void CtrlClicked(object sender, RoutedEventArgs e){
    Button btn = sender as Button;
    MyClass2 c2 = btn.DataContext as MyClass2;
    c2.CallCustomMethod();
}

When the button 'Del' is clicked I want to delete the object MyClass2 out of a List<MyClass2> which is held in MyClass1. In order to do that I need to have access to MyClass1.

My UI (pseudo code):

Window (DataContext = base)
  Grid
    UserControl uc1 (DataContext = base.MyClass1)
      Grid
        ListView
          ListView.DataTemplate
            UserControl uc2 (DataContext = base.MyClass1.MyClass2)
              Grid
                UserControl ucButtons
              Grid
            UserControl uc2
          ListView.DataTempate
          ListView.PanelTemplate
            UniformGrid
          ListView.PanelTemplate
        ListView
      Grid
    UserControl uc1
  Grid
Window

So how can I get access to the MyClass1-objext?

I found out that I can walk the tree using .Parent, but can only do that to a certain point:

Grid gScheduleControlBar = btn.Parent as Grid;
UserControl ucScheduleControlBar = gScheduleControlBar.Parent as UserControl;
Grid gDay = ucScheduleControlBar.Parent as Grid;
UserControl ucDay = gDay.Parent as UserControl;
//ucDay.Name confirms it's the userControl defined
Grid grid = ucDay.Parent as Grid;
// grid.Name="" and grid.Parent = null

so from here there is no further way upwards, which means I can't pass the UserControl 'border'.

Any ideas?
As fallback-option there is of course the way of storing a reference of MyClass1 in MyClass2.

EDIT => Final Result:
<Button x:Name="Del" DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor AncestorType=UserControl AncestorLevel=3}}"

Upvotes: 2

Views: 1495

Answers (1)

Manfred Radlwimmer
Manfred Radlwimmer

Reputation: 13394

If you want to do this via Bindings, you can use RelativeSource={RelativeSource Mode=FindAncestor AncestorType=yourNamespace:YourType}, from code you can use the VisualTreeHelper to get the visual parent of any control.

If there are multiple parents of that type in your hierarchy can can additionally specify an AncestorLevel. In the example you included, it looks like AncestorType=UserControl and AncestorLevel=2 should work.

Upvotes: 1

Related Questions