我在 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
下使用 DataGrid
的 AddingNewItem
事件可以半解决。 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; theNewItem
property of theEventArgs
is simplynull
.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 theAddingNewItemEventArgs
, 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 exceptionDecompiling the control lets us see what's happening in there...
关于wpf - 强制 WPF DataGrid 添加特定新项目的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9951769/