2011-03-08 21 views
6

Tengo una colección personalizada que paso a un cliente WPF, que vincula la colección a datagrid usando AutoGenerateColumns="True". Sin embargo, la cuadrícula de datos muestra filas vacías (aunque el número correcto de filas vacías). ¿Qué estoy haciendo mal? Lo siguiente es un código de muestra. Por ahora, he omitido todo lo relacionado con INotifyPropertyChanged y INotifyCollectionChanged porque, bueno, primero quiero que aparezcan algunos datos en la grilla.WPF: Implementación y enlace (datagrid) a una colección personalizada

También debo mencionar que he intentado implementar las dos interfaces anteriores, pero parecen no tener nada que ver con este problema.

(En realidad, no puede ser que desee ver en el código de ejemplo que no hay absolutamente nada interesante al respecto La implementación de la colección se acaba envolviendo una Lista de interior..)

Algunos aleatoria POCO:

public class Person 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
} 

implementación simple colección:

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 
} 

El 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> 

de la ventana de código subyacente:

public MainWindow() 
{ 
    InitializeComponent(); 

    MyCollection<Person> persons = new MyCollection<Person>() 
    { 
     new Person(){FirstName="john", LastName="smith"}, 
     new Person(){FirstName="foo", LastName="bar"} 
    }; 

    dataGrid1.DataContext = persons; 
} 

Por cierto, si se cambia el código subyacente para utilizar una lista < persona> en lugar de la MiColeccion < persona>, todo funciona como se esperaba.

EDIT:

El código anterior no se ha tomado de la situación real. Solo lo publiqué para mostrar lo que estoy haciendo para probar mi problema y facilitar la replicación. El objeto de recopilación personalizado real es bastante complejo y no puedo publicarlo aquí. Una vez más, estoy tratando de entender el concepto básico detrás de lo que se necesita hacer para que una cuadrícula de datos se vincule correctamente a una colección personalizada y genere columnas automáticamente para los objetos subyacentes.

Respuesta

4

Al parecer, con el fin de AutoGenerateColumns para trabajar en un WPF DataGrid, su colección tiene que implementar IItemProperties, aunque he encontrado que envolver mi colección en un (formas de las ventanas) BindingList hace el truco, así (que en realidad envuelve su colección, a diferencia del ObservableCollection que simplemente copia los miembros de su colección en sí mismo).

3

¿Cuál es su tipo de MyCollection<T> que suma más de List<T>? De cualquier manera, usaría un ObservableCollection (para que la UI reciba notificaciones de adiciones/eliminaciones) e implemente INotifyPropertyChanged en su clase Person para que se notifique a la UI de los cambios en los valores de propiedad de ese tipo.

EDITAR

no creo que es especialmente trivial unión a su propio tipo de colección personalizada. Tendrá que implementar INotifyPropertyChanged y INotifyCollectionChanged en ese tipo. Este artículo podría ser de alguna utilidad - http://www.e-pedro.com/2009/04/creating-a-custom-observable-collection-in-wpf/

Otra opción si está usando MVVM, es utilizar el tipo de colección personalizada de su modelo, y el uso de un estándar ObservableCollection en su modelo de vista y poblar su colección de modelos de vista de su modelo , luego une tu cuadrícula a tu colección de modelos de vista.

+0

Lo siento, probablemente no estaba claro en mi pregunta. El objeto MyCollection solo pretendía describir el problema. La colección personalizada real que estoy usando es completamente diferente. Solo estoy tratando de entender cómo hacer que esto funcione. Actualizará la pregunta. – joniba

+0

Respuesta recién actualizada – devdigital

+0

Divertido, todos los caminos solo conducen a ese mismo artículo. De hecho, seguí las instrucciones del artículo al que me vinculaste. Y eso me llevó al fenómeno que mencioné en la pregunta. En cuanto a usar el modelo de vista como intermediario, eso es exactamente lo que quería evitar implementando mi propia colección. Esa es la implementación actual, pero quiero reducir la cantidad de código vinculante. Además, intencionalmente quería evitar el tema de INotify___ porque primero quiero ver que AutoGenerateColumns funciona en la cuadrícula de datos. – joniba

3

Creo que está usando su conocimiento de Windows Forms escribiendo dataGrid1.DataContext = persons; En WPF DataGrid está conectado a la colección (por ejemplo, Lista) muy simple: dataGrid1.ItemsSource = personas;

Cuestiones relacionadas