【问题标题】:DataGridCell ContextMenu throws ArgumentNullException unless cell is pre-clicked除非预先单击单元格,否则 DataGridCell ContextMenu 会引发 ArgumentNullException
【发布时间】:2019-11-05 01:28:50
【问题描述】:

我试图在 DataGridView 中右键单击特定类型的单元格时显示 ContextMenu。如果我在右键单击以调出上下文菜单之前单击单元格以选择它,它会按预期工作。

如果我右键单击单元格而不先单击选择它,我的应用程序会由于未处理的异常而崩溃。

System.ArgumentNullException: '值不能为空。 (参数'容器')'

我环顾四周,我认为WPF Contextmenu itemtemplate commandParameter binding returns null 的答案基本上是我需要做的,但我不明白如何将其应用于我的问题。

编辑:这是整个调用堆栈

>   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>

【问题讨论】:

  • 请为异常提供整个堆栈跟踪。
  • 遵循DataGrid.OnContextMenuOpening的源代码containernull这里是cell.RowOwner
  • 你能分享整个 xaml 的网格和数据模板吗?另外,是否有任何原因没有在DataGrid.RowStyle 中设置上下文菜单?
  • @PavelAnikhouski 添加。没有特别的理由不在 DataGrid.RowStyle 中设置上下文菜单,这对我来说是一个选项吗?
  • 当您为每个数据模板设置上下文菜单时,DataGrid.RowStyle 对您没有帮助。但是为什么需要同时设置CellTemplateSelectorCellEditingTemplateSelector呢?

标签: c# datagrid contextmenu


【解决方案1】:

我解决了这个问题。

参考此 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。

因此,当我在 DataTemplate 中放置一个 DataGridCell 时,我实际上是在现有 DataGridCell 中放置了一个 DataGridCell。这会导致右键单击单元格时出现问题。 ContextMenu其实是无关紧要的,不管怎样都会出现问题。

这可以通过在 DataTemplate 中使用另一种类型的 Container 来解决,例如:

            <!-- 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>

【讨论】:

    猜你喜欢
    • 2013-03-24
    • 2019-05-12
    • 1970-01-01
    • 2021-11-01
    • 1970-01-01
    • 2013-06-18
    • 2017-03-11
    • 1970-01-01
    • 2021-06-14
    相关资源
    最近更新 更多