0

How can I get access to the related MenuItem? It has been created on the fly, so I cannot just use it by a name in the xaml file.

private void menuItem_canExecute(object sender, CanExecuteRoutedEventArgs e)
{
    var snd = sender; // This is the main window
    var orgSource = e.OriginalSource; // This is a RichTextBox;
    var src = e.Source; // This is a UserControl

    // I think I must use the Command, but how?
    RoutedCommand routedCommand = e.Command as RoutedCommand;
}
Pollitzer
  • 1,580
  • 3
  • 18
  • 28
  • 1
    You could bind the MenuItem's `CommandParameter` to the MenuItem instance, like `CommandParameter="{Binding RelativeSource={RelativeSource Self}}` and than access it by the `Parameter` property of the CanExecuteRoutedEventArgs. – Clemens Jan 16 '16 at 15:59
  • Why do you need access to the `MenuItem`? Maybe there is a better way to accomplish what you are trying to do. – StillLearnin Jan 16 '16 at 18:19
  • @Clemens: This is a working solution, please turn your comment into an answer. – Pollitzer Jan 17 '16 at 08:41
  • @StillLearnin: In the subitems of a menu "Document" I insert a new item if the user opens a document. After he has closed the document he can easily reopen it by the new menu item. The menu item text consists of a leading number and the document name. To solve the access problem I can use Clemens' proposal. – Pollitzer Jan 17 '16 at 08:54

2 Answers2

1

CanExecuteRoutedEventArgs has an OriginalSource property.

MSDN Doc for CanExecuteRoutedEventArgs

The OriginalSender will probably be a TextBlock which is "inside" the MenuItem. You will likely need to traverse the visual tree to find the parent which is of type MenuItem

Sample code from here

public static T GetVisualParent<T>(this DependencyObject child) where T : Visual
{
    //TODO wrap this in a loop to keep climbing the tree till the correct type is found 
    //or till we reach the end and haven't found the type
    Visual parentObject = VisualTreeHelper.GetParent(child) as Visual;
    if (parentObject == null) return null;
    return parentObject is T ? parentObject as T : GetVisualParent<T>(parentObject);
}

Used like this

var menuItem = e.OriginalSource.GetVisualParent<MenuItem>();
if (menuItem != null)
    //Do something....
StillLearnin
  • 1,391
  • 15
  • 41
1

You can always pass the commanding UI element to a command by binding itself to its CommandParameter property, like

<MenuItem ... CommandParameter="{Binding RelativeSource={RelativeSource Self}}"/>

Now you can access the MenuItem by the Parameter property of the CanExecuteRoutedEventArgs:

private void menuItem_canExecute(object sender, CanExecuteRoutedEventArgs e)
{
    var menuItem = e.Parameter as MenuItem;
    ...
}
Clemens
  • 123,504
  • 12
  • 155
  • 268