DataGridCell ContextMenu 抛出 ArgumentNullException 除非预先单击单元格
DataGridCell ContextMenu throws ArgumentNullException unless cell is pre-clicked
我试图在 DataGridView 中右键单击特定类型的单元格时显示上下文菜单。如果我在右键单击以调出上下文菜单之前单击单元格 select 它会按预期工作。
但是,如果我在没有先单击 select 的情况下右键单击该单元格,我的应用程序就会因未处理的异常而崩溃。
System.ArgumentNullException: '值不能为空。 (参数'container')'
我环顾四周,我认为 的答案基本上是我需要做的,但我不明白如何将其应用于我的问题。
编辑:这是整个调用堆栈
> PresentationFramework.dll!System.Windows.Controls.ItemContainerGenerator.ItemFromContainer(System.Windows.DependencyObject container) Unknown
PresentationFramework.dll!System.Windows.Controls.ItemsControl.ItemInfoFromContainer(System.Windows.DependencyObject container) Unknown
PresentationFramework.dll!System.Windows.Controls.DataGrid.HandleSelectionForCellInput(System.Windows.Controls.DataGridCell cell, bool startDragging, bool allowsExtendSelect, bool allowsMinimalSelect) Unknown
PresentationFramework.dll!System.Windows.Controls.DataGrid.OnContextMenuOpening(System.Windows.Controls.ContextMenuEventArgs e) Unknown
PresentationFramework.dll!System.Windows.FrameworkElement.OnContextMenuOpeningThunk(object sender, System.Windows.Controls.ContextMenuEventArgs e) Unknown
PresentationFramework.dll!System.Windows.Controls.ContextMenuEventArgs.InvokeEventHandler(System.Delegate genericHandler, object genericTarget) Unknown
PresentationCore.dll!System.Windows.RoutedEventArgs.InvokeHandler(System.Delegate handler, object target) Unknown
PresentationCore.dll!System.Windows.EventRoute.InvokeHandlersImpl(object source, System.Windows.RoutedEventArgs args, bool reRaised) Unknown
PresentationCore.dll!System.Windows.UIElement.RaiseEventImpl(System.Windows.DependencyObject sender, System.Windows.RoutedEventArgs args) Unknown
PresentationCore.dll!System.Windows.UIElement.RaiseTrustedEvent(System.Windows.RoutedEventArgs args) Unknown
PresentationCore.dll!System.Windows.UIElement.RaiseEvent(System.Windows.RoutedEventArgs args, bool trusted) Unknown
PresentationFramework.dll!System.Windows.Controls.PopupControlService.RaiseContextMenuOpeningEvent(System.Windows.IInputElement source, double x, double y, bool userInitiated) Unknown
PresentationFramework.dll!System.Windows.Controls.PopupControlService.ProcessMouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e) Unknown
PresentationFramework.dll!System.Windows.Controls.PopupControlService.OnPostProcessInput(object sender, System.Windows.Input.ProcessInputEventArgs e) Unknown
PresentationCore.dll!System.Windows.Input.InputManager.RaiseProcessInputEventHandlers(System.Windows.Input.ProcessInputEventHandler postProcessInput, System.Windows.Input.ProcessInputEventArgs processInputEventArgs) Unknown
PresentationCore.dll!System.Windows.Input.InputManager.ProcessStagingArea() Unknown
PresentationCore.dll!System.Windows.Input.InputProviderSite.ReportInput(System.Windows.Input.InputReport inputReport) Unknown
PresentationCore.dll!System.Windows.Interop.HwndMouseInputProvider.ReportInput(System.IntPtr hwnd, System.Windows.Input.InputMode mode, int timestamp, System.Windows.Input.RawMouseActions actions, int x, int y, int wheel) Unknown
PresentationCore.dll!System.Windows.Interop.HwndMouseInputProvider.FilterMessage(System.IntPtr hwnd, MS.Internal.Interop.WindowMessage msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) Unknown
PresentationCore.dll!System.Windows.Interop.HwndSource.InputFilterMessage(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) Unknown
WindowsBase.dll!MS.Win32.HwndWrapper.WndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) Unknown
WindowsBase.dll!MS.Win32.HwndSubclass.DispatcherCallbackOperation(object o) Unknown
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs) Unknown
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(object source, System.Delegate callback, object args, int numArgs, System.Delegate catchHandler) Unknown
WindowsBase.dll!System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority priority, System.TimeSpan timeout, System.Delegate method, object args, int numArgs) Unknown
WindowsBase.dll!MS.Win32.HwndSubclass.SubclassWndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam) Unknown
[Native to Managed Transition]
[Managed to Native Transition]
WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame frame) Unknown
WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame frame) Unknown
WindowsBase.dll!System.Windows.Threading.Dispatcher.Run() Unknown
PresentationFramework.dll!System.Windows.Application.RunDispatcher(object ignore) Unknown
PresentationFramework.dll!System.Windows.Application.RunInternal(System.Windows.Window window) Unknown
PresentationFramework.dll!System.Windows.Application.Run() Unknown
Testproject.dll!Testproject.App.Main() Unknown
再次编辑;这是完整的 XAML
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.Resources>
<!-- Default DataTemplate -->
<DataTemplate x:Key="DefaultDataTemplate">
<TextBox Text="{Binding Path=Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
<!-- DataTemplate for Booleans -->
<DataTemplate x:Key="BooleanDataTemplate">
<CheckBox IsChecked="{Binding Path=Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
<!-- DataTemplate for Arrays -->
<DataTemplate x:Key="ArrayDataTemplate">
<DataGridCell Content="{Binding Path=Value, Mode=OneWay}" >
<DataGridCell.ContextMenu>
<ContextMenu>
<MenuItem Header="View / Edit..." />
</ContextMenu>
</DataGridCell.ContextMenu>
</DataGridCell>
</DataTemplate>
<local:ValueDataTemplateSelector x:Key="templateSelector"
DefaultDataTemplate="{StaticResource DefaultDataTemplate}"
BooleanDataTemplate="{StaticResource BooleanDataTemplate}"
ArrayDataTemplate="{StaticResource ArrayDataTemplate}" />
</Grid.Resources>
<DataGrid Name="DG2" ItemsSource="{Binding TagListView}" AutoGenerateColumns="False" Grid.Row="1">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Width="*" Binding="{Binding Path=Name, Mode=OneWay}" />
<DataGridTemplateColumn Header="Value" Width="2*" CellTemplateSelector="{StaticResource templateSelector}" CellEditingTemplateSelector="{StaticResource templateSelector}" />
</DataGrid.Columns>
</DataGrid>
</Grid>
我解决了问题。
参考这个XAML:
<!-- DataTemplate for Arrays -->
<DataTemplate x:Key="ArrayDataTemplate">
<DataGridCell Content="{Binding Path=Value, Mode=OneWay}" >
<DataGridCell.ContextMenu>
<ContextMenu>
<MenuItem Header="View / Edit..." />
</ContextMenu>
</DataGridCell.ContextMenu>
</DataGridCell>
</DataTemplate>
应用了 DataTemplate 的任何 DataGridTemplateColumn 已经在每一行中包含 DataGridCells。
因此,当我将 DataGridCell 放入 DataTemplate 中时,我实际上是将 DataGridCell 放入现有的 DataGridCell 中。右键单击单元格时,这会导致出现问题。 ContextMenu其实是无关紧要的,不管怎样都会出现问题
这可以通过在 DataTemplate 中使用另一种类型的容器来解决,例如:
<!-- DataTemplate for Arrays -->
<DataTemplate x:Key="ArrayDataTemplate">
<TextBox Text="{Binding Path=Value, Mode=OneWay}" >
<TextBox.ContextMenu>
<ContextMenu>
<MenuItem Header="View / Edit..." Click="menuItem_Click" />
</ContextMenu>
</TextBox.ContextMenu>
</TextBox>
</DataTemplate>
我试图在 DataGridView 中右键单击特定类型的单元格时显示上下文菜单。如果我在右键单击以调出上下文菜单之前单击单元格 select 它会按预期工作。
但是,如果我在没有先单击 select 的情况下右键单击该单元格,我的应用程序就会因未处理的异常而崩溃。
System.ArgumentNullException: '值不能为空。 (参数'container')'
我环顾四周,我认为
编辑:这是整个调用堆栈
> PresentationFramework.dll!System.Windows.Controls.ItemContainerGenerator.ItemFromContainer(System.Windows.DependencyObject container) Unknown
PresentationFramework.dll!System.Windows.Controls.ItemsControl.ItemInfoFromContainer(System.Windows.DependencyObject container) Unknown
PresentationFramework.dll!System.Windows.Controls.DataGrid.HandleSelectionForCellInput(System.Windows.Controls.DataGridCell cell, bool startDragging, bool allowsExtendSelect, bool allowsMinimalSelect) Unknown
PresentationFramework.dll!System.Windows.Controls.DataGrid.OnContextMenuOpening(System.Windows.Controls.ContextMenuEventArgs e) Unknown
PresentationFramework.dll!System.Windows.FrameworkElement.OnContextMenuOpeningThunk(object sender, System.Windows.Controls.ContextMenuEventArgs e) Unknown
PresentationFramework.dll!System.Windows.Controls.ContextMenuEventArgs.InvokeEventHandler(System.Delegate genericHandler, object genericTarget) Unknown
PresentationCore.dll!System.Windows.RoutedEventArgs.InvokeHandler(System.Delegate handler, object target) Unknown
PresentationCore.dll!System.Windows.EventRoute.InvokeHandlersImpl(object source, System.Windows.RoutedEventArgs args, bool reRaised) Unknown
PresentationCore.dll!System.Windows.UIElement.RaiseEventImpl(System.Windows.DependencyObject sender, System.Windows.RoutedEventArgs args) Unknown
PresentationCore.dll!System.Windows.UIElement.RaiseTrustedEvent(System.Windows.RoutedEventArgs args) Unknown
PresentationCore.dll!System.Windows.UIElement.RaiseEvent(System.Windows.RoutedEventArgs args, bool trusted) Unknown
PresentationFramework.dll!System.Windows.Controls.PopupControlService.RaiseContextMenuOpeningEvent(System.Windows.IInputElement source, double x, double y, bool userInitiated) Unknown
PresentationFramework.dll!System.Windows.Controls.PopupControlService.ProcessMouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e) Unknown
PresentationFramework.dll!System.Windows.Controls.PopupControlService.OnPostProcessInput(object sender, System.Windows.Input.ProcessInputEventArgs e) Unknown
PresentationCore.dll!System.Windows.Input.InputManager.RaiseProcessInputEventHandlers(System.Windows.Input.ProcessInputEventHandler postProcessInput, System.Windows.Input.ProcessInputEventArgs processInputEventArgs) Unknown
PresentationCore.dll!System.Windows.Input.InputManager.ProcessStagingArea() Unknown
PresentationCore.dll!System.Windows.Input.InputProviderSite.ReportInput(System.Windows.Input.InputReport inputReport) Unknown
PresentationCore.dll!System.Windows.Interop.HwndMouseInputProvider.ReportInput(System.IntPtr hwnd, System.Windows.Input.InputMode mode, int timestamp, System.Windows.Input.RawMouseActions actions, int x, int y, int wheel) Unknown
PresentationCore.dll!System.Windows.Interop.HwndMouseInputProvider.FilterMessage(System.IntPtr hwnd, MS.Internal.Interop.WindowMessage msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) Unknown
PresentationCore.dll!System.Windows.Interop.HwndSource.InputFilterMessage(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) Unknown
WindowsBase.dll!MS.Win32.HwndWrapper.WndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) Unknown
WindowsBase.dll!MS.Win32.HwndSubclass.DispatcherCallbackOperation(object o) Unknown
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs) Unknown
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(object source, System.Delegate callback, object args, int numArgs, System.Delegate catchHandler) Unknown
WindowsBase.dll!System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority priority, System.TimeSpan timeout, System.Delegate method, object args, int numArgs) Unknown
WindowsBase.dll!MS.Win32.HwndSubclass.SubclassWndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam) Unknown
[Native to Managed Transition]
[Managed to Native Transition]
WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame frame) Unknown
WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame frame) Unknown
WindowsBase.dll!System.Windows.Threading.Dispatcher.Run() Unknown
PresentationFramework.dll!System.Windows.Application.RunDispatcher(object ignore) Unknown
PresentationFramework.dll!System.Windows.Application.RunInternal(System.Windows.Window window) Unknown
PresentationFramework.dll!System.Windows.Application.Run() Unknown
Testproject.dll!Testproject.App.Main() Unknown
再次编辑;这是完整的 XAML
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.Resources>
<!-- Default DataTemplate -->
<DataTemplate x:Key="DefaultDataTemplate">
<TextBox Text="{Binding Path=Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
<!-- DataTemplate for Booleans -->
<DataTemplate x:Key="BooleanDataTemplate">
<CheckBox IsChecked="{Binding Path=Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
<!-- DataTemplate for Arrays -->
<DataTemplate x:Key="ArrayDataTemplate">
<DataGridCell Content="{Binding Path=Value, Mode=OneWay}" >
<DataGridCell.ContextMenu>
<ContextMenu>
<MenuItem Header="View / Edit..." />
</ContextMenu>
</DataGridCell.ContextMenu>
</DataGridCell>
</DataTemplate>
<local:ValueDataTemplateSelector x:Key="templateSelector"
DefaultDataTemplate="{StaticResource DefaultDataTemplate}"
BooleanDataTemplate="{StaticResource BooleanDataTemplate}"
ArrayDataTemplate="{StaticResource ArrayDataTemplate}" />
</Grid.Resources>
<DataGrid Name="DG2" ItemsSource="{Binding TagListView}" AutoGenerateColumns="False" Grid.Row="1">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Width="*" Binding="{Binding Path=Name, Mode=OneWay}" />
<DataGridTemplateColumn Header="Value" Width="2*" CellTemplateSelector="{StaticResource templateSelector}" CellEditingTemplateSelector="{StaticResource templateSelector}" />
</DataGrid.Columns>
</DataGrid>
</Grid>
我解决了问题。
参考这个XAML:
<!-- DataTemplate for Arrays -->
<DataTemplate x:Key="ArrayDataTemplate">
<DataGridCell Content="{Binding Path=Value, Mode=OneWay}" >
<DataGridCell.ContextMenu>
<ContextMenu>
<MenuItem Header="View / Edit..." />
</ContextMenu>
</DataGridCell.ContextMenu>
</DataGridCell>
</DataTemplate>
应用了 DataTemplate 的任何 DataGridTemplateColumn 已经在每一行中包含 DataGridCells。
因此,当我将 DataGridCell 放入 DataTemplate 中时,我实际上是将 DataGridCell 放入现有的 DataGridCell 中。右键单击单元格时,这会导致出现问题。 ContextMenu其实是无关紧要的,不管怎样都会出现问题
这可以通过在 DataTemplate 中使用另一种类型的容器来解决,例如:
<!-- DataTemplate for Arrays -->
<DataTemplate x:Key="ArrayDataTemplate">
<TextBox Text="{Binding Path=Value, Mode=OneWay}" >
<TextBox.ContextMenu>
<ContextMenu>
<MenuItem Header="View / Edit..." Click="menuItem_Click" />
</ContextMenu>
</TextBox.ContextMenu>
</TextBox>
</DataTemplate>