值不能为空。参数名称:key(只发生在XAML设计师的设计视图)

Value cannot be null. Parameter name: key (only happens on XAML Designer's design view)

XAML Designer 设计视图显示

抛出异常

ArgumentNullException: 值不能为空。

参数名称:key

StackTrace(见照片后)

内部异常:None

我已经为以下问题苦苦挣扎了几天,这使我无法在每个受影响的视图上使用 XAML Designer 的设计视图。

昨天,我最终设法隔离了这种特别难以追踪的奇怪行为,因为它只发生在设计时,而且这似乎是泛型和 DataGrid[=75= 之间的冲突] 的 ItemsSource 属性 (System.Windows.Controls).

所以,这就是 设计视图

上显示的内容

at System.Collections.Generic.Dictionary2.FindEntry(TKey key) at System.Collections.Generic.Dictionary2.TryGetValue(TKey key, TValue& value) at System.Windows.Controls.DataGridItemAttachedStorage.TryGetValue(Object item, DependencyProperty property, Object& value) at System.Windows.Controls.DataGridRow.RestoreAttachedItemValue(DependencyObject objectWithProperty, DependencyProperty property) at System.Windows.Controls.DataGridRow.SyncProperties(Boolean forcePrepareCells) at System.Windows.Controls.DataGridRow.PrepareRow(Object item, DataGrid owningDataGrid) at System.Windows.Controls.DataGrid.PrepareContainerForItemOverride(DependencyObject element, Object item) at System.Windows.Controls.ItemsControl.MS.Internal.Controls.IGeneratorHost.PrepareItemContainer(DependencyObject container, Object item) at System.Windows.Controls.ItemContainerGenerator.System.Windows.Controls.Primitives.IItemContainerGenerator.PrepareItemContainer(DependencyObject container) at System.Windows.Controls.VirtualizingStackPanel.InsertContainer(Int32 childIndex, UIElement container, Boolean isRecycled) at System.Windows.Controls.VirtualizingStackPanel.AddContainerFromGenerator(Int32 childIndex, UIElement child, Boolean newlyRealized, Boolean isBeforeViewport) at System.Windows.Controls.VirtualizingStackPanel.MeasureChild(IItemContainerGenerator& generator, IContainItemStorage& itemStorageProvider, IContainItemStorage& parentItemStorageProvider, Object& parentItem, Boolean& hasUniformOrAverageContainerSizeBeenSet, Double& computedUniformOrAverageContainerSize, Double& computedUniformOrAverageContainerPixelSize, Boolean& computedAreContainersUniformlySized, IList& items, Object& item, IList& children, Int32& childIndex, Boolean& visualOrderChanged, Boolean& isHorizontal, Size& childConstraint, Rect& viewport, VirtualizationCacheLength& cacheSize, VirtualizationCacheLengthUnit& cacheUnit, Boolean& foundFirstItemInViewport, Double& firstItemInViewportOffset, Size& stackPixelSize, Size& stackPixelSizeInViewport, Size& stackPixelSizeInCacheBeforeViewport, Size& stackPixelSizeInCacheAfterViewport, Size& stackLogicalSize, Size& stackLogicalSizeInViewport, Size& stackLogicalSizeInCacheBeforeViewport, Size& stackLogicalSizeInCacheAfterViewport, Boolean& mustDisableVirtualization, Boolean isBeforeFirstItem, Boolean isAfterFirstItem, Boolean isAfterLastItem, Boolean skipActualMeasure, Boolean skipGeneration, Boolean& hasBringIntoViewContainerBeenMeasured, Boolean& hasVirtualizingChildren) at System.Windows.Controls.VirtualizingStackPanel.MeasureOverrideImpl(Size constraint, Nullable1& lastPageSafeOffset, List1& previouslyMeasuredOffsets, Nullable`1& lastPagePixelSize, Boolean remeasure) at System.Windows.Controls.VirtualizingStackPanel.MeasureOverride(Size constraint) at System.Windows.Controls.Primitives.DataGridRowsPresenter.MeasureOverride(Size constraint) at System.Windows.FrameworkElement.MeasureCore(Size availableSize) at System.Windows.UIElement.Measure(Size availableSize) at System.Windows.ContextLayoutManager.UpdateLayout() at System.Windows.UIElement.UpdateLayout()

Sample project source code

MyViewModelbase.cs(这是我的通用视图模型基础)

namespace BugProof.ViewModels
{
    using System.Collections.Generic;

    public class MyViewModelBase<TItem> where TItem : class
    {
        public List<TItem> Items { get; set; }
        public MyViewModelBase() { }
    }
}

MyExtendedViewModel.cs(这是我的扩展视图模型,它将基于 string 类型)

namespace BugProof.ViewModels
{
    public class MyExtendedViewModel : MyViewModelBase<string>
    {
        public MyExtendedViewModel()
        {
        }
    }
}

MainWindow.xaml

<Window x:Class="BugProof.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="clr-namespace:BugProof.ViewModels"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:BugProof"
        mc:Ignorable="d"
        d:DataContext="{d:DesignInstance {x:Type vm:MyExtendedViewModel}, IsDesignTimeCreatable=False}"                  
        Title="MainWindow" Height="350" Width="525">
    <StackPanel>
        <TextBlock>This is what you should se in the designer</TextBlock>
        <!--Try replacing following DataGrid by a ListBox or ListView-->
        <DataGrid ItemsSource="{Binding Items}"/>
    </StackPanel>
</Window>

MainWindow.xaml.cs (MainWindow 后面的代码)

using System.Windows;

namespace BugProof
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
}

补充细节:

  • 如果用 ListboxListView 替换 DataGrid 控件,则不会发生此行为或 ItemsControl
  • 我正在使用 Visual Studio 2015,版本 14.0.25431.01 更新 3
  • 项目针对 .Net Framework 4.5

MainWindows.xaml 上设置 IsDesignTimeCreatable=True 就成功了,尽管它需要特别小心地实现视图模型的无参数构造函数,检查代码在设计时是否 运行。

According to Microsoft,设置 IsDesignTimeCreatable=True,"specifies that the design instance is created from your type, instead of a designer-generated substitute type".

令人惊讶的是,还有 according to Microsoft,如果 IsDesignTimeCreatable 未设置或设置为 False,"all the design tool does is parse the class for its bindable properties"。

我想我们有两个相反的事实。这甚至可能是两者都是真的,这取决于上下文。可能是,第二个来源不知道,在文档编写时,XAML Designer 自动生成一次 IsDesignTimeCreatable 的 3 个示例设置为默认值 False 值,每当它找到一个集合 (IEnumerable) 属性

除非另有证明,否则当 ItemsSource 绑定到通用集合源且 IsDesignTimeCreatable=False,因为如果我们用ListBoxListView或[=22=替换DataGrid控件就不会出现这个问题]ItemsControls.

另一种解决方案是简单地删除 "d:DataContext" 属性,这将禁用 Datacontext 相关的自动完成。

我不得不使用这个解决方案,因为 Julio 建议的 "IsDesignTimeCreatable" 属性对我不起作用:/

通过以下方式修复了此问题:

  1. 增加了设计宽度
  2. 将设计宽度还原为原始宽度。

仅供参考,我使用的是 Visual Studio 2019。