Is it possible to bind the IsEnabled property of a button to a context menu item that is represented by a NotifyIcon?
When I push the menu item, it starts a method that disables my btnSave. In that case, I would like to "turn off" the MenuItem too. I attempted it this way, but it's not working:
<Window.Resources>
<ContextMenu x:Key="NotifierContextMenu" Placement="MousePoint">
<MenuItem Header="Start" Click="start_timer" IsEnabled="{Binding ElementName=btnSave, Path=IsEnabled}"/>
</ContextMenu>
</Window.Resources>
I believe your problem stems from a ContextMenu not existing within the visual tree, so ElementName bindings will be unsuccessful, unless you take some additional steps to correct the Name Scope, or resolve the DataContext to the visual tree.
Most of the techniques are covered fairly comprehensively in this answer: ElementName Binding from MenuItem in ContextMenu.
I've had success in the past with binding to a named element by reference, in your case, that would look something like this:
<MenuItem Header="Start"
IsEnabled="{Binding IsEnabled, Source={x:Reference btnSave}}"
Click="btnSave_Click"/>
Related
Stackoverflow.
I've looked through a good amount of questions\answers, and still not found the clue to the issue I'm facing in Visual UI Automation Verify (2.0).
I have a ContextMenu in TreeList (DevExpress control):
<dxg:TreeListControl.ContextMenu>
<ContextMenu x:Name="TreeListContextMenu" DataContext="{Binding Path=Data, Source={StaticResource Proxy}}" ItemsSource="{Binding Path=Data.SelectedItemContextMenuItemCollection, Source={StaticResource Proxy}}"/>
</dxg:TreeListControl.ContextMenu>
I have a simple binding proxy, like this one declared with the following code:
<dataStructures:BindingProxy x:Key="Proxy" Data="{Binding}" />
DataContext of the User Control and DataContext of the ContextMenu are bound to Data property on the proxy (because ContextMenu doesn't belong to the same visual tree).
In the non-shared MenuItem style I'm assigning the value from Data property of the proxy to the attached property of the MenuItem:
<Setter Property="helpers:ParentControlDataContextBindingHelper.ParentControlDataContext" Value="{Binding Path=Data, Source={StaticResource Proxy}}" />
The reason it's done this way:
In the tree there are various objects. Each object might have different ContextMenu item list based on object's certain property value. I'm handling the "ContextMenuOpening" event by routing it to the Command:
<i:Interaction.Triggers>
<i:EventTrigger EventName="ContextMenuOpening">
<prism:InvokeCommandAction Command="{Binding ContextMenuOpeningCommand}"/>
</i:EventTrigger>
<i:Interaction.Triggers/>
In ContextMenuOpeningCommand command I'm clearing and then filling up SelectedItemContextMenuItemCollection (which consists of MenuItem Visual Models - binding sources for Header, Command and Icon for the MenuItem) based on the property of the SelectedItem
When the context menu is called the first time - it appears on Visual UI Automation Verify (with the correct ContextMenuItem headers), but it can't be tested after it is closed - its contents in Visual UI Automation Verify are DisconnnectedItems. If I call next ContextMenu on the different type of element and the list of ContextMenu items is different - Visual UI Automation Verify doesn't show even headers of the menu items (the headers are empty because DataContext of menu item is DisconnectedItem after menu closes). If I'm using "hardcoded" ContextMenu with all bindings and items in XAML - everything is ok.
I'm not sure if this behavior is actually by design or not. Is it possible to test ContextMenu with non-static items collection with Visual UI Automation Verify? Inspect.exe in WindowsKits behaves the same way. What's more important - how I can get around that to be able to test the menu with VisualUIAVerify?
currently I have the basic radgridview Context menu, I'm trying to get it to look like the context menu in here from this demo ContextMenu
May I get some tips or suggestions, I'm not quite sure where to start.
My Contextmenu code:
<telerik:RadGridView.ContextMenu>
<ContextMenu>
<MenuItem Header="View Contact" cal:Message.Attach="[Event Click] = [Action Open()]"/>
</ContextMenu>
</telerik:RadGridView.ContextMenu>
Since you are asking for a direction here.
I would suggest you to read about Styles and templates in WPF (MSDN)
In WPF the controls are view-less. The view is controlled by the style/template that you apply to the control.
For instance, in your case if you can get the style of the Context menu control you have mentioned (say it's named "FancyContextMenu" in resource dictionary).
Then you just need to modify your code to below:
<telerik:RadGridView.ContextMenu>
<ContextMenu Style="{StaticResource ResourceKey=FancyContextMenu}">....
I have two user controls LeftPanel and DeviceList. DeviceList is inside the LeftPanel. I want the context menu in device list to be able to call a command on the parent view model, which is set on a grid that hosts DeviceList. I have tried the following but it does not work.
Here is the ContextMenu within DeviceList
<MenuItem Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type local:LeftPanel}},
Path=DeviceListViewModel.RemoveDevice}">
Here is the LeftPanel usercontrol
<UserControl x:Class="Tool.LeftPanel" .... >
<Grid DataContext="{Binding DeviceListViewModel}" Grid.Column="1">
<local:DeviceList Grid.Row="1" Margin="0,0,0,10"/>
I had a similar problem, but the ContextMenu does not see the DataContext of the ViewModel or the Parent.
A possible solution is here Access ViewModel / DataConext inside ContextMenu .
the contextmenu is not part of the visualtree, so i think your binding is simply wrong because the datacontext is not what you think of.
use Snoop to check your DataContext and bindings at runtime
i assume that you have to work with PlacementTarget in your bindings
How could i bind all context menu items to one single command, which gets the index of the menu item called? I have a WPF/MVVM project.
<ContextMenu x:Key="cm" ItemsSource="{Binding ActionItems}"
DisplayMemberPath="ActionDescription">
</ContextMenu>
Your should pass it as a CommandParameter:
<ContextMenu x:Key="cm" ItemsSource="{Binding ActionItems}" DisplayMemberPath="ActionDescription"
Command="{Binding YourCommand}" CommandParameter="{Binding YourParameter}">
...
</ContextMenu>
Updated
you need the solution described here: MVVM binding command to contextmenu item
Updated after comments
relapse - than you should implement it as shown here: WPF ContextMenu with ItemsSource - how to bind to Command in each item?. Please notice that link is a duplication of other question. So read the both please.
I have a TreeView setup so that each TreeViewItem has right-click context menu applied as a Style. Something like:
<Grid.Resources>
<ContextMenu x:Key="contextMenu">
<MenuItem Header="Save" IsEnabled="{Binding Path=Saveable}"/>
<MenuItem Header="Copy" IsEnabled="{Binding Path=Copyable}"/>
<MenuItem Header="Remove" IsEnabled="{Binding Path=Removeable}"/>
</ContextMenu>
<Style TargetType="TreeViewItem">
<Setter Property="ContextMenu" Value="{StaticResource contextMenu}" />
</Style>
</Grid.Resources>
Saveable, Copyable and Removeable are properties that come from the object that's used as the TreeViewItem.
What I'm looking for is when the user clicks on a MenuItem, it would click on the appropriate method of the selected object. So clicking on the "Save" MenuItem would call object.Save(), "Copy" calls object.Copy(), etc. But I'm not sure what the syntax would look like, or whether the idea is actually acceptable in terms of typical WPF style. I know I can just create a new event handler in the encompassing window, but I'd prefer the selected item itself to handle the event.
Thoughts?
Thanks!
Unfortunately, I don't think that there is an automated way of doing this. The closest option would be to setup a RoutedUICommand for each item in the ContextMenu, and then create a CommandBinding for each in your class. If you want those to go to the TreeViewItem, you'll probably need to subclass TreeViewItem and set up the CommandBindings there.
The one option that I thought might work would be to add an EventSetter for MenuItem.Click to the TreeViewItem style. However, that did not work - probably because the items in the ContextMenu are in a different visual tree from the TreeViewItems.