Bind to parent / sibling current datacontext / source property in WPF

How do we bind to the parent / sibling of the current datacontext (i.e., to the original property representing the current datacontext)?

I'm not talking about binding to a parent control property (in this case we are talking about the parent object, not the source) - and this can easily be done using RelativeSourceMode = FindAncestor.

RelativeSourceMode = PreviousData provides limited support for binding to the previous sibling of a data item, but not to parents or other siblings.

Dummy example:
(suppose the INPC is in place)
How to bind ItemsSource ComboBox with Departments ViewModel property?

public class Person { public string Name { get; set; } public string Department { get; set; } } public class PersonViewModel { public List<Person> Persons { get; set; } public List<string> Departments { get; set; } public PersonViewModel() { Departments = new List<string>(); Departments.Add("Finance"); Departments.Add("HR"); Departments.Add("Marketing"); Departments.Add("Operations"); Persons = new List<Person>(); Persons.Add(new Person() { Name = "First", Department = "HR" }); Persons.Add(new Person() { Name = "Second", Department = "Marketing" }); Persons.Add(new Person() { Name = "Third", Department = "Marketing" }); } } 

XAML:

 <Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApplication1" Title="MainWindow" Height="300" Width="300"> <Grid> <DataGrid ItemsSource="{Binding Persons}" AutoGenerateColumns="False"> <DataGrid.Columns> <DataGridTextColumn Header="Name" Binding="{Binding Name}" /> <DataGridTemplateColumn> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <ComboBox ItemsSource="{Binding Departments???}" SelectedValue="{Binding Department}"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid> </Grid> </Window> 
+6
source share
3 answers

you can access the ancestors of the DataContext as follows:

 <ComboBox ItemsSource="{Binding DataContext.Departments, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGrid}}}" SelectedValue="{Binding Department}"/> 
+10
source

In most cases, I use the DataContext as the root of the path:

 {Binding Path=DataContext.MyProperty,ElementName=MyElement} {Binding Path=DataContext.MyProperty,RelativeSource={RelativeSource AncestorType=MyAnsectorTypr} 
+3
source

I'm not sure why the RelativeSource approach is not working. (I do this all the time, AncestorType=UserControl ). But if this is unacceptable, there are two ways that come to mind.

1) Give each person a list of departments to which you need to become attached. In your example, you can simply pass the list in the constructor of Person. Or, give each Person a link back to the parent to get any property of the parent, for example: {Binding Parent.Departments}

2) Create an attached property "ParentDataContext" and set it outside the element control, for example:

 <Window local:Attached.ParentDataContext="{Binding}" ... > 

Then you can snap it to the tree below:

 {Binding Path=(local:Attached.ParentDataContext).Departments, RelativeSource=Self} 

A nested property must inherit so that everything below in the tree sets it, setting it to the top level.

0
source

Source: https://habr.com/ru/post/886536/


All Articles