我有一个自定义集合,我将其传递给WPF客户端,该客户端使用datagrid
将集合绑定到AutoGenerateColumns="True"
。但是,数据网格显示空行(尽管空行数正确)。我究竟做错了什么?以下是一些示例代码。现在我省略了与INotifyPropertyChanged
和INotifyCollectionChanged
有关的所有内容,因为我首先想要在网格中显示一些数据。
我还应该提一下,我已尝试实现上述两个接口,但它们似乎与此问题无关。
(你可能实际上并不想查看示例代码,因为它没有什么有趣的。集合实现只是包装一个内部List。)
一些随机的POCO:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
简单的集合实现:
public class MyCollection<T> : IList<T>
{
private List<T> list = new List<T>();
public MyCollection()
{
}
public MyCollection(IEnumerable<T> collection)
{
list.AddRange(collection);
}
#region ICollection<T> Members
public void Add(T item)
{
list.Add(item);
}
public void Clear()
{
list.Clear();
}
public bool Contains(T item)
{
return list.Contains(item);
}
public void CopyTo(T[] array, int arrayIndex)
{
list.CopyTo(array, arrayIndex);
}
public int Count
{
get { return list.Count; }
}
public bool IsReadOnly
{
get { return false; }
}
public bool Remove(T item)
{
return list.Remove(item);
}
#endregion
#region IEnumerable<T> Members
public IEnumerator<T> GetEnumerator()
{
return list.GetEnumerator();
}
#endregion
#region IEnumerable Members
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
#region IList<T> Members
public int IndexOf(T item)
{
return list.IndexOf(item);
}
public void Insert(int index, T item)
{
list.Insert(index, item);
}
public void RemoveAt(int index)
{
list.RemoveAt(index);
}
public T this[int index]
{
get { return list[index]; }
set { list[index] = value; }
}
#endregion
}
XAML:
<Window x:Class="TestWpfCustomCollection.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<DataGrid AutoGenerateColumns="True"
HorizontalAlignment="Stretch"
Name="dataGrid1" VerticalAlignment="Stretch"
ItemsSource="{Binding}"
/>
</Grid>
</Window>
窗口的代码隐藏:
public MainWindow()
{
InitializeComponent();
MyCollection<Person> persons = new MyCollection<Person>()
{
new Person(){FirstName="john", LastName="smith"},
new Person(){FirstName="foo", LastName="bar"}
};
dataGrid1.DataContext = persons;
}
顺便说一句,如果您更改代码隐藏以使用List&lt; Person&gt;而不是MyCollection&lt; Person&gt;,一切都按预期工作。
编辑:
以上代码并非取自实际情况。我只发布它来展示我正在做的事情,以便测试我的问题并使其更容易复制。 实际的自定义集合对象非常复杂,我无法在此处发布。同样,我只是想了解需要做什么的基本概念,以便数据网格正确绑定到自定义集合并自动为底层对象生成列。
答案 0 :(得分:4)
显然,为了让AutoGenerateColumns在WPF DataGrid
中工作,你的集合必须实现IItemProperties,尽管我发现将我的集合包装在(windows窗体)BindingList中就可以了同样(它实际上包装了你的收藏,不像ObservableCollection
只是将你的收藏成员复制到自己身上)。
答案 1 :(得分:3)
MyCollection<T>
类型添加List<T>
的内容是什么?无论哪种方式,我都会使用ObservableCollection代替(以便通知UI添加/删除),并在INotifyPropertyChanged
类上实现Person
,以便通知用户界面更改该类型的属性值。
修改强>
我认为这对您自己的自定义集合类型没有特别的微不足道的约束力。您需要在该类型上实施INotifyPropertyChanged
和INotifyCollectionChanged
。这篇文章可能有用 - http://www.e-pedro.com/2009/04/creating-a-custom-observable-collection-in-wpf/
如果您使用MVVM,另一个选择是在模型上使用自定义集合类型,并在视图模型上使用标准ObservableCollection
并从模型中填充视图模型集合,然后将网格绑定到你的视图模型集合。
答案 2 :(得分:3)
我认为你通过写作来使用Windows Forms的知识 dataGrid1.DataContext = persons; 在WPF中,DataGrid连接到集合(比如List)非常简单: dataGrid1.ItemsSource = persons;