标题有点说明了一切,但让我通过例子更详细地解释它。
让我们假设你想出于各种原因创建一个CustomList。
例如:
public CustomList<T> : IList<T>
{
//all members from IList<T> are implemented and are working
}
现在你有一个绑定到这个列表的DataGrid
在XAML(WPF)文件的代码后面:
TestDataGrid.ItemsSource = new CustomList<Person>() { new Person(), new Person() };
现在您可以假设编辑工作正常,因为Person类没有任何限制,并且CustomList的IsReadOnly设置为false。
public class Person
{
public string Name { get; set }
}
但等等,WPF DataGrid发出错误消息: 此视图不允许使用“EditItem”。
现在,如果我将CustomList的实现更改为:
public CustomList<T> : IList
{
//all members from IList are implemented and are working
}
编辑工作,但行为或LINQ和IEnumerable扩展很糟糕,因为GetEnumerator返回一个非泛型版本,所以我只停留在对象中,并且需要一直强制转换为我想要的类。
我看到了什么问题或没有好的解决方案吗? 我只想要一个带有排序功能的可编辑(在WPF DataGrid中)CustomList(不是OrderBy - 就地排序)。
答案 0 :(得分:3)
WPF引擎的某些部分会查找IList
,而不是IList<T>
。由于IList<T>
未实现IList
,因此WPF仅知道您的列表为IEnumerable
,而非IList
。您应该实现两个接口。您应该使用explicit interface implementation来隐藏对象上不应公开的实现,例如
public class CustomList<T> : IList<T>, IList
{
// this is the one we want users of this class to use
public void Add(T value) { ... }
// IList's implementation; needs to exist, but this way it's hidden,
// unless you cast to IList
int IList.Add(object value) { this.Add((T)value); return this.Count - 1; }
// etc
}
答案 1 :(得分:1)
实施接口IList<T>
和 IList
,就像List<T>
一样。
答案 2 :(得分:1)
要使其正常工作,您可能希望CustomList
实现其他必需的接口,例如List<T>
。所以改变自:
public CustomList<T> : IList<T>
{
//all members from IList are implemented and are working
}
到
public CustomList<T> : IList<T>, IList, IReadOnlyList<T>, IReadOnlyCollection<T>, IEnumerable<T>
{
//all members from IList are implemented and are working
}