How to force a bound to be bound every time ContextMenu opens?

I have a ContextMenu with a MenuItem in it:

<Grid> <Button Content="{Binding Test}"> <Button.ContextMenu> <ContextMenu> <StackPanel> <MenuItem Header="{Binding Test}"/> </StackPanel> </ContextMenu> </Button.ContextMenu> </Button> </Grid> 

The Test property is as follows:

 private Random rand; public string Test { get { return "Test " + this.rand.Next(50); } } 

When I click the button with the right mouse button, I have, for example, "Test 41". Next time I open the menu, I have the same value. Is there a way to get the menu to evaluate the binding every time? (and then "Test 3", "Test 45", "Test 65" ...

+4
source share
2 answers

Here is the hack I use in the same situation:

Name your context menu and create your own RoutedCommand, I use them for all buttons and menus as they have a CanExecute method that enables or disables the control and an Execute method that is called to do the job. each time the context menu is opened, the CanExecute method is called. this means that you can perform custom processing to see if it should be activated, or you can change the contents of the menu, which is useful for changing the menu while saving different things. we use it to say "Save xyx .." when the user edits xyx.

In any case, if the name of the menu, you can change its contents to CanExecute. (If a command appeared on the menu, you will have it as the sender of the CanExecute event anyway, but sometimes I like to select them higher, because you can assign them shortcuts that can be executed from anywhere they are covered.)

+1
source

The Test property should inform other components when its value changes, for example. implementing the INotifyPropertyChanged interface in the containing class as follows:

 class Window1 : Window, INotifyPropertyChanged { ... private string m_Test; public string Test { get { return m_Test; } set { m_Test = value; OnPropertyChanged("Test"); } } } 

You can then change the Test value from anywhere to using the property ( Test = "newValue"; ), and the changes will be displayed in the user interface.

If you really need to change the value of the property when ContextMenu displayed, use the Opend ContextMenu event:

Xaml:

 <ContextMenu Opened="UpdateTest"> <MenuItem Header="{Binding Test}" /> </ContextMenu> 

Code for:

 private void UpdateTest(object sender, RoutedEventArgs e) { // just assign a new value to the property, // UI will be notified automatically Test = "Test " + this.rand.Next(50); } 
0
source

All Articles