Hello,
I recently switched my WPF app to use RadMenu and RadMenuItems. After making this change, I noticed a subtle difference in behavior.The problem is that when a new window is launched in response to a RadMenuitem click, it is immediately deactivated. I proved this by hooking the Deactivated event of the window I was opening. (See the stack trace below.) I have confirmed that this problem is due to RadMenu/RadMenuItem - changing back to WPF Menu/MenuItem made the problem go away. The deactivated window is a problem because immediately after launch users try to interact with the window, and there is a short delay to activate it again.
Background:
I have an MVVM WPF application. I open new windows by sending a message (mediator pattern) from the MainViewModel to the MainView. The MainView creates a new window, associates a view model to datacontext, and calls Show():
| ''' <summary> |
| ''' Handles displaying and replying to any received command messages |
| ''' </summary> |
| ''' <param name="message"></param> |
| ''' <remarks></remarks> |
| Private Sub HandleCommandMessage(ByVal message As CommandMessage) |
| If Not IsNothing(message) Then 'AndAlso message.Sender.GetType() Is GetType(MainViewModel) Then |
| ' Check if we are running on the UI thread. If not, call begin invoke |
| If Not _dispatcher.CheckAccess Then |
| _dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, _ |
| New Action(Of CommandMessage)(AddressOf HandleCommandMessage), message) |
| Else |
| Select Case message.Command |
| Case Messages.ViewMessages.ShowDiagnosticsView.ToString() |
| If IsNothing(_diagWindow) Then |
| _diagWindow = New DiagnosticsView |
| _diagWindow.Owner = Me |
| _diagWindow.DataContext = Me.ViewModel.DiagViewModel |
| _diagWindow.Show() |
| End If |
| Case Messages.ViewMessages.CloseDiagnosticView.ToString() |
| If Not IsNothing(_diagWindow) Then |
| _diagWindow.Close() |
| _diagWindow = Nothing |
| End If |
| '... |
| Case Else |
| End Select |
| End If |
| End If |
| End Sub |
The MainViewModel has an ICommand instance called ShowDiagnosticviewCommand. This Command is bound to the RadMenuItem in my MainView as follows:
| <!-- ... --> |
| <telerik:RadMenuItem Header="Tools"> |
| <telerik:RadMenuItem Header="Diagnostics" Command="{Binding Path=ShowDiagnosticsViewCommand}" /> |
| </telerik:RadMenuItem> |
| <!-- ... ---> |
The MainViewModel has the following code:
| /// <summary> |
| /// Returns a command that opens the image view. |
| /// </summary> |
| public ICommand ShowDiagnosticsViewCommand |
| { |
| get |
| { |
| if (_showDiagnosticsViewCommand == null) |
| { |
| _showDiagnosticsViewCommand = new RelayCommand((param) => this.ShowDiagnosticsView(), (param) => !this.DiagnosticsViewActive); |
| } |
| return _showDiagnosticsViewCommand; |
| } |
| } |
| private void ShowDiagnosticsView() |
| { |
| Messenger.Default.Send<CommandMessage>(new CommandMessage(this, Messages.ViewMessages.ShowDiagnosticsView.ToString())); |
| } |
Here is the call stack when i break on the Window_Deactivated event of the window being launched:
Call stack:
| Imager.exe!CM.Imager.DiagnosticsView.Window_Deactivated(Object sender = {CM.Imager.DiagnosticsView}, System.EventArgs e = {System.EventArgs}) Line 57 Basic |
| [External Code] |
| Telerik.Windows.Controls.Navigation.dll!Telerik.Windows.Controls.RadMenuItem.OnIsSubmenuOpenChanged(System.Windows.DependencyObject d = {Telerik.Windows.Controls.RadMenuItem Header:Tools Items.Count:7}, System.Windows.DependencyPropertyChangedEventArgs e = {System.Windows.DependencyPropertyChangedEventArgs}) Line 1813 + 0xa bytes C# |
| [External Code] |
| Telerik.Windows.Controls.Navigation.dll!Telerik.Windows.Controls.RadMenuItem.IsSubmenuOpen.set(bool value = false) Line 496 C# |
| Telerik.Windows.Controls.Navigation.dll!Telerik.Windows.Controls.RadMenuItem.CloseMenu() Line 944 C# |
| Telerik.Windows.Controls.Navigation.dll!Telerik.Windows.Controls.RadMenuItem.OnIsSelectedChanged(System.Windows.DependencyObject d = {Telerik.Windows.Controls.RadMenuItem Header:Tools Items.Count:7}, System.Windows.DependencyPropertyChangedEventArgs e = {System.Windows.DependencyPropertyChangedEventArgs}) Line 1756 C# |
| [External Code] |
| Telerik.Windows.Controls.Navigation.dll!Telerik.Windows.Controls.RadMenuItem.IsSelected.set(bool value = false) Line 648 C# |
| Telerik.Windows.Controls.Navigation.dll!Telerik.Windows.Controls.MenuBase.CurrentSelection.set(Telerik.Windows.Controls.RadMenuItem value = null) Line 302 C# |
| Telerik.Windows.Controls.Navigation.dll!Telerik.Windows.Controls.MenuBase.CloseAll() Line 327 C# |
| Telerik.Windows.Controls.Navigation.dll!Telerik.Windows.Controls.RadMenuItem.OnClickImpl() Line 1126 C# |
| Telerik.Windows.Controls.Navigation.dll!Telerik.Windows.Controls.RadMenuItem.OnClick() Line 1488 C# |
| Telerik.Windows.Controls.Navigation.dll!Telerik.Windows.Controls.RadMenuItem.ClickItem() Line 2527 C# |
| Telerik.Windows.Controls.Navigation.dll!Telerik.Windows.Controls.RadMenuItem.HandleMouseUp() Line 1098 C# |
| Telerik.Windows.Controls.Navigation.dll!Telerik.Windows.Controls.RadMenuItem.OnMouseLeftButtonUp(System.Windows.Input.MouseButtonEventArgs e = {System.Windows.Input.MouseButtonEventArgs}) Line 1291 C# |
| [External Code] |
My guess is that somehow the window is losing focus back to the RadmenuItem after the bound command is fired, possibly on the RadmenuItem.OnIsSubmenuOpenChanged().
For now, I have switched back to using the default WPF menu. I prefer the Radmenu because of the nice theme support. Any help with this problem will be appreciated.
Thanks
Chris Boarman