wpf - 强制 WPF DataGrid 添加特定新项目的最佳方法是什么?

标签 wpf datagrid datacontract itemssource type-constraints

我在 WPF 应用程序中有一个 DataGrid,它的 ItemsSource 是我编写的自定义集合。该集合强制其所有项目满足特定要求(即它们必须介于某个最小值和最大值之间)。

集合的类签名是:

   public class CheckedObservableCollection<T> : IList<T>, ICollection<T>, IList, ICollection,
                                            INotifyCollectionChanged
                                             where T : IComparable<T>, IEditableObject, ICloneable, INotifyPropertyChanged

我希望能够使用 DataGrid 功能,其中对 DataGrid 中的最后一行进行编辑会导致将新项目添加到ItemsSource

不幸的是,DataGrid 只是添加了一个使用默认构造函数创建的新项。因此,当添加新项目时,DataGrid 间接地(通过它的 ItemCollection 这是一个密封类)声明:

ItemsSource.Add(new T())

其中 T 是 CheckedObservableCollection 中元素的类型。我希望网格改为添加一个不同的 T,它满足对集合施加的约束。

我的问题是:是否有内置的方法来执行此操作?有人已经这样做了吗?执行此操作的最佳(最简单、最快速的编码;性能不是问题)方法是什么?

目前我只是派生了 DataGrid 来用我自己的覆盖 OnExecutedBeginEdit 函数,如下所示:

public class CheckedDataGrid<T> : DataGrid where T : IEditableObject, IComparable<T>, INotifyPropertyChanged, ICloneable
{
  public CheckedDataGrid() : base() { }

  private IEditableCollectionView EditableItems {
     get { return (IEditableCollectionView)Items; }
  }

  protected override void OnExecutedBeginEdit(ExecutedRoutedEventArgs e) {
     try {
        base.OnExecutedBeginEdit(e);
     } catch (ArgumentException) {
        var source = ItemsSource as CheckedObservableCollection<T>;
        source.Add((T)source.MinValue.Clone());
        this.Focus();
     }
  }
}

其中 MinValue 是集合中允许的最小项。

我不喜欢这个解决方案。如果你们有任何建议,我将不胜感激!

谢谢

最佳答案

这个问题现在在 4.5 下使用 DataGridAddingNewItem 事件可以半解决。 Here is my answer to a similar question .

I solved the problem by using DataGrid's AddingNewItem event. This almost entirely undocumented event not only tells you a new item is being added, but also [allows lets you choose which item is being added][2]. AddingNewItem fires before anything else; the NewItem property of the EventArgs is simply null.

Even if you provide a handler for the event, DataGrid will refuse to allow the user to add rows if the class doesn't have a default constructor. However, bizarrely (but thankfully) if you do have one, and set the NewItem property of the AddingNewItemEventArgs, it will never be called.

If you choose to do this, you can make use of attributes such as [Obsolete("Error", true)] and [EditorBrowsable(EditorBrowsableState.Never)] in order to make sure no one ever invokes the constructor. You can also have the constructor body throw an exception

Decompiling the control lets us see what's happening in there...

关于wpf - 强制 WPF DataGrid 添加特定新项目的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9951769/

相关文章:

wpf - 带有附加属性的模板绑定(bind)

c# - 事件不会跨模块触发(prism、MVVM、silverlight c#)

c# - WPF SplashScreen 何时关闭?

WCF Rest DataContract 和 ServiceContract 版本控制

c# - 在列表框中显示图像会锁定文件

wpf - 如何更改自动生成的列文本对齐方式

c# - 如何在运行时动态更改 DataGrid String 列格式?

javascript - 什么是好的 "Pythonic"Web Ajax 数据网格?

c# - 如何替换 ServiceContract 和 OperationContract 的命名约定?

c# - 使用 DataContract 从 List<> 派生的类的序列化