【发布时间】:2018-08-25 19:35:41
【问题描述】:
我正在尝试创建自定义的可重用 WPF UserControl,它具有一个列表框和一个用于添加新行的按钮,就像 DataGrid 允许用户添加新行一样。
此控件将绑定到各种视图模型中的许多不同类型的集合(即 List、ObservableCollection 等)。
我的 UserControl 具有一个名为 DataSource 的 IEnumerable 类型的依赖属性(它必须是 IEnumerable 才能允许 ObservableCollections、Lists 等)。我想为基础集合中的任何对象创建一个新实例,并将其添加到绑定到 ItemsSource 的原始集合中。
我创建了一个方法,该方法将创建集合所包含的对象的新实例:
private object GetNewItem()
{
if (ItemsSource == null)
throw new ArgumentException("ItemsSource not set");
Type itemType = null;
foreach (Type i in ItemsSource.GetType().GetInterfaces())
{
if (i.IsGenericType && i.GetGenericTypeDefinition().Equals(typeof(IEnumerable<>)))
itemType = i.GetGenericArguments()[0];
}
if (itemType == null)
throw new ArgumentException("Unable to get ItemsSource's Type T");
return Activator.CreateInstance(itemType);
}
现在我只需要将新对象添加到原始集合中。不幸的是,IEnumerable 不允许添加项目,因为它不是可变的。
我可以检测出最初使用的是哪种类型的集合,即:
if (itemsType.IsGenericType && itemsType.GetGenericTypeDefinition() == typeof(ObservableCollection<>))
所以,我可以获得集合的类型,以及该集合的泛型类型(即,集合是“ObservableCollection”,泛型类型是“Person”),但我不知道如何将其转换回来。 ..即使可以,我也无法将 GetNewItem 的结果添加为:
((ObservableCollection<Person>) ItemsSource).Add(object)
...如果不将对象转换为“Person”,则无法正常工作。
DataGrids 能够添加它的 ItemsSource 基础类型的新实例,即使它的 ItemsSource 是 IEnumerable,所以我知道这不是不可能的。我只是看不出如何使它工作。如有任何建议,我将不胜感激。
【问题讨论】:
标签: c# wpf generics reflection