2011-03-08 89 views
6

我有一个自定义集合,我传递给WPF客户端,该客户端使用AutoGenerateColumns="True"将集合绑定到datagrid。但是,datagrid显示的是空行(尽管是空行的正确数目)。我究竟做错了什么?以下是一些示例代码。现在我已经省略了与INotifyPropertyChangedINotifyCollectionChanged有关的所有事情,因为我首先想要在网格中显示一些数据。WPF:实现和绑定(数据网格)到自定义集合

我还应该提到,我已经尝试过实现上述两个接口,但它们似乎与此问题无关。

(您可能实际上并不想看看示例代码是绝对没有什么有趣的关于它的收取执行只是包裹了一个内部列表。)

一些随机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; 
} 

顺便说一句,如果你改变了代码隐藏使用列表<人>而不是MyCollection的<人>,一切正常。

编辑:

上面的代码不是从实际情况考虑。我只是发布它来显示我正在做什么,以便测试我的问题并使其更容易复制。 实际的自定义集合对象非常复杂,我不能在这里发布。再次,我只是想了解为了使数据网格正确绑定到自定义集合并自动为基础对象生成列需要完成的基本概念。

回答

4

显然,为了在的AutoGenerateColumns一个WPF DataGrid工作,你的收藏必须实现IItemProperties,但我发现我的包裹在(Windows窗体)集合的BindingList的伎俩以及(它实际上你的包裹与ObservableCollection不同,它只是将您的收藏的成员复制到自己的收藏中)。

3

什么是您的MyCollection<T>类型加入List<T>?无论使用哪种方式,我都会使用ObservableCollection来代替(以便通知用户界面添加/删除),并在Person类上实现INotifyPropertyChanged,以便向UI通知该类型属性值的更改。

编辑

我不认为这是特别琐碎结合自己的自定义集合类型。您需要在该类型上实施INotifyPropertyChangedINotifyCollectionChanged。这篇文章可能是一些使用 - 如果你正在使用MVVM http://www.e-pedro.com/2009/04/creating-a-custom-observable-collection-in-wpf/

另一种选择,就是用你的自定义集合类型的模型,并在您的视图模型使用标准ObservableCollection和模型填充您的视图模型集合,然后将您的网格绑定到您的视图模型集合。

+0

对不起,我可能不清楚我的问题。 MyCollection对象仅用于描述问题。我使用的实际自定义集合完全不同。我只是想了解如何使这项工作。将更新问题。 – joniba 2011-03-08 16:12:57

+0

刚刚更新的答案 – devdigital 2011-03-08 16:59:58

+0

有趣的是,所有的道路都会导致同一篇文章。事实上,我确实按照您链接的文章的指示。这导致了我在这个问题中提到的现象。至于使用视图模型作为中介,那正是我想通过实现我自己的集合来避免的。这是当前的实现,但我想减少绑定代码的数量。另外,我有意避免INotify___的话题,因为我首先想看到AutoGenerateColumns在数据网格中工作。 – joniba 2011-03-08 17:41:57

3

我想你使用Windows Forms的知识写作 dataGrid1.DataContext = persons; 在WPF DataGrid连接到集合(比如List)很简单: dataGrid1.ItemsSource = persons;