0

I have TreeView control and I need to bind property from root (window/usercontrol) DataContext in context menu in that treeview.

 <TextBox Text="{Binding Header}"></TextBox> <TreeView ItemsSource="{Binding Items}" Grid.Row="1"> <TreeView.ItemContainerStyle> <Style TargetType="{x:Type TreeViewItem}"> <Setter Property="ContextMenu"> <Setter.Value> <ContextMenu> <MenuItem Header="{{ BINDING TO HEADER PROPERTY FROM WINDOW DATACONTEXT}}"/> </ContextMenu> </Setter.Value> </Setter> </Style> </TreeView.ItemContainerStyle> </TreeView> public ObservableCollection<string> Items { get; set; } public string Header { get { return _header; } set { _header = value; } } 

I've tried multiple things: I've added x:Name="WindowRoot" to Window and {Binding Header, ElementName=WindowRoot} but it didn't work, I've tried multiple FindAncestor and RelativeSource but it didn't work.

Can someone help me?

Edit:

This is simplified case, in my normal application I use Unity + Prism, so ViewModel is AutoDiscovered (prism:ViewModelLocator.AutoWireViewModel="True") and it generally works. By "works" I mean: TreeView shows items from my collection, so it is connected, the problem is with context menu binding only.

In this simplified example I have ugly and simple code-behind, because I only want to test this ContextMenu binding:

public partial class MainWindow : Window { public ObservableCollection<string> Items { get; set; } private string _header = "testtest"; public string Header { get { return _header ; } set { _header = value; } } public MainWindow() { Items = new ObservableCollection<string>(); Items.Add("ItemTest"); InitializeComponent(); this.DataContext = this; } } 
10
  • Try adding DataContext to your binding so DataContext.Header Commented Jun 3, 2017 at 22:35
  • @NicolasPierre Thanks for the idea, sadly it doesn't work too (it works finein TextBox which is directly in Window, so it is not problem with the property Header) Commented Jun 3, 2017 at 22:43
  • Is your DataContext properly bound ? Commented Jun 3, 2017 at 22:44
  • Should I do anything beside window.DataContext = MyViewModel? Binding in the <TextBox Text="{Binding Header}"></TextBox> above TreeView works fine. Commented Jun 3, 2017 at 22:47
  • Edit your question with how you bound the viewmodel if you would please Commented Jun 3, 2017 at 22:48

1 Answer 1

1

You could bind the Tag property of the TreeViewItem to the parent window or user control using a {RelativeSource} and then bind the Header property of the MenuItem to the Tag property of the PlacementTarget of the ContextMenu:

<TreeView x:Name="tv" ItemsSource="{Binding Items}" Grid.Row="1"> <TreeView.ItemContainerStyle> <Style TargetType="{x:Type TreeViewItem}"> <Setter Property="Tag" Value="{Binding RelativeSource={RelativeSource AncestorType=Window}}" /> <Setter Property="ContextMenu"> <Setter.Value> <ContextMenu> <MenuItem Header="{Binding PlacementTarget.Tag.DataContext.Header, RelativeSource={RelativeSource AncestorType=ContextMenu}}"/> </ContextMenu> </Setter.Value> </Setter> </Style> </TreeView.ItemContainerStyle> </TreeView> 

The reason you cannot bind directly to any property of the window from the MenuItem is that a ContextMenu resides in a different element tree than the parent window or user control.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much! It works flawlessly! Thanks again.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.