I have a WPF project with a view model and some nested UI elements. Here is the (relevant section of) XAML:
<UserControl> // DataContext is MyVM (set programmatically)
<TreeView ItemsSource="{Binding Trees}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Subtrees}">
<StackPanel>
<ListView ItemsSource="{Binding Contents}"
SelectedValue="{Binding SelectedContent}" // won't work: Tree has no such property
SelectionMode="Single"/>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</UserControl>
Here the code for the ViewModel class:
public class MyVM : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
public IEnumerable<Tree> Trees { get; set; }
private object _selectedContent;
public string SelectedContent
{
get => _selectedContent;
set
{
_selectedContent = value;
OnPropertyChanged();
}
}
}
Here the code for class Tree:
public class Tree
{
public IEnumerable<Tree> Subtrees { get; set; }
public IEnumerable<string> Contents { get; set; }
}
I want to allow only one selection globally for all ListViews. Just like here, I want to bind all ListViews to the property SelectedContent in the view model MyVM.
The problem is that the data context of the ListView is a Tree, and not the MyVM from the top user control. (It should be Tree, since we want to show the Contents.) I know I can bind downwards using SelectedValuePath, but how do I go up instead in order to bind SelectedValue to the MyVM property SelectedContent?
I tried SelectedValue="{Binding RelativeSource={RelativeSource AncestorType ={x:Type UserControl}}, Path=SelectedContent}", but it did not work.