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