I have been really struggling to customize the look of my context menu without losing any functionality. What I have currently would be workable, except that for some reason I can't click any item.
I have a breakpoint in my code-behind for the XamlContextMenu.ItemClicked. When I run the program and click an item, I get a null pointer exception - before the breakpoint even gets hit. It takes me to the 'app.Run()' call.
Here's the menu:
<ig:ContextMenuService.Manager> <ig:ContextMenuManager OpenMode="LeftClick"> <ig:ContextMenuManager.ContextMenu> <ig:XamContextMenu> <ig:XamContextMenu.Items> <ig:XamMenuItem Header="Mountain Map" Icon="{StaticResource IconMountains}" CommandParameter="{x:Static enums:ClientTabScreenType.MountainMap}" Click="XamMenuItem_OnClick" /> <ig:XamMenuItem Header="All Machines" Icon="{StaticResource IconMachines}" CommandParameter="{x:Static enums:ClientTabScreenType.AllMachines}" /> <ig:XamMenuItem Header="Alarms" Icon="{StaticResource IconAlarms}" CommandParameter="{x:Static enums:ClientTabScreenType.Alarms}" /> <ig:XamMenuItem Header="Logging" Icon="{StaticResource IconLogging}" CommandParameter="{x:Static enums:ClientTabScreenType.EventLogs}" /> <ig:XamMenuItem Header="Chat" Icon="{StaticResource IconChat}" CommandParameter="{x:Static enums:ClientTabScreenType.Chat}" /> <ig:XamMenuItem Header="Trending" Icon="{StaticResource IconTrending}" CommandParameter="{x:Static enums:ClientTabScreenType.Trending}" /> <ig:XamMenuItem Header="Reporting" Icon="{StaticResource IconReporting}" CommandParameter="{x:Static enums:ClientTabScreenType.Reporting}" /> <ig:XamMenuItem Header="Weather Stations" Icon="{StaticResource IconWeather}" CommandParameter="{x:Static enums:ClientTabScreenType.WeatherStations}" /> </ig:XamContextMenu.Items> </ig:XamContextMenu> </ig:ContextMenuManager.ContextMenu> </ig:ContextMenuManager> </ig:ContextMenuService.Manager>
and the styles:
<Style TargetType="ig:XamContextMenu"> <Setter Property="Foreground" Value="#FFFFFF"/> <Setter Property="Background" Value="Transparent" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="ig:XamContextMenu"> <Border CornerRadius="8" BorderThickness="0" Background="{StaticResource BrushGreyDark}" SnapsToDevicePixels="True" HorizontalAlignment="Stretch"> <ItemsPresenter VerticalAlignment="Center" /> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style TargetType="ig:XamMenuItem"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ig:XamMenuItem}"> <Border x:Name="Bd" HorizontalAlignment="Stretch" Height="25" Margin="4" CornerRadius="5"> <Border.Style> <Style TargetType="Border"> <Setter Property="Background" Value="{StaticResource BrushBlue}" /> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Background" Value="{StaticResource BrushBlueBright}"/> </Trigger> </Style.Triggers> </Style> </Border.Style> <StackPanel Orientation="Horizontal"> <ContentControl Template="{TemplateBinding Icon}" Height="20" Margin="2" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" /> <ContentPresenter x:Name="ContentPresenter" Content="{TemplateBinding Header}" ContentSource="Header" Margin="4" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" /> </StackPanel> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style>
and the error:
System.NullReferenceException HResult=0x80004003 Message=Object reference not set to an instance of an object. Source=InfragisticsWPF4.Controls.Menus.XamMenu.v13.2 StackTrace: at Infragistics.Controls.Menus.XamMenuItem.OnMouseLeftButtonDownImpl(MouseButtonEventArgs e) at Infragistics.Controls.Menus.XamMenuItem.OnMouseLeftButtonDown(MouseButtonEventArgs e) at System.Windows.UIElement.OnMouseLeftButtonDownThunk(Object sender, MouseButtonEventArgs e) at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget) at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target) at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs) at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent) at System.Windows.UIElement.OnMouseDownThunk(Object sender, MouseButtonEventArgs e) at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget) at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target) at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs) at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args) at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args) at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted) at System.Windows.Input.InputManager.ProcessStagingArea() at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input) at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport) at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel) at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler) at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs) at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam) at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg) at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame) at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame) at System.Windows.Application.RunDispatcher(Object ignore) at System.Windows.Application.RunInternal(Window window) at System.Windows.Application.Run(Window window) at System.Windows.Application.Run() at SmartSnow.Client.Boot.Main(String[] args) in D:\Source\Repos\SmartSnow 7.0\SmartSnow.Client\Boot.cs:line 47
An upgrade did the trick. Thank you!
Hello Doug,
I have created a sample project against the code that you have provided, and I can see that in the stack trace, version 13.2 is referenced. I have tested your code against version 13.2 and I can reproduce the exception you are seeing. This appears to be due to the re-template of the XamMenuItem and XamContextMenu as it appears that you have excluded a piece of the template that is likely used internally in the OnMouseLeftButtonDownImpl method.
This appears to have been a bug in version 13.2 that has since been fixed, as I cannot currently reproduce the behavior with the versions that are currently receiving active development (17.2 and later at the time of writing this). As such, I can recommend a couple of options in this case.
The first option is to upgrade to a more recent version such as version 17.2 or later.
Alternatively, I would recommend that you include the entire default template of the XamContextMenu and XamMenuItem so that you are not excluding the piece that it is looking for. These default styles can be found in the DefaultStyles/Menu/generic.xaml file at the installation directory for your Infragistics WPF 2013.2 product. You can then make your changes to those default styles and templates to get the menu items and the context menu to look the way you want them to.
Please let me know if you have any other questions or concerns on this matter.