greenoldman
greenoldman

Reputation: 21072

Why the content of the pure IEnumerable is invisible for WPF DataGrid?

Let's say I have a datagrid with itemsource binded to property Collection, which is for example IEnumerable. Of course I wrote appropriate getter and setter for it.

Now, when I assign to this property (Collection) just IEnumerable (as the result of some method), like:

Collection = FooMethod(); // FooMethod returns IEnumerable<MyClass>

datagrid will display empty rows. The count of the rows will match the count of the Collection.

But when I force conversion, like this:

Collection = FooMethodp().ToArray(); // forced fetching data

datagrid will show all rows with content now.

So what stops datagrid from showing data in case of pure IEnumerable? It has to iterate over a collection so fetching occurs anyway.

edits

Just for the record. MyClass is this:

public class ErrorsIndicators
{
    public double Min { get; set; }
    public double Max { get; set; }
    public double Avg { get; set; }
}

and FooMethod returns (return yield) several items. So, nothing fancy here.

Upvotes: 4

Views: 3481

Answers (1)

Kent Boogaart
Kent Boogaart

Reputation: 178700

It's hard to say without seeing the implementation of FooMethod(), but I suspect it is returning something that implements IEnumerable<T> but not anything further (such as ICollection<T> or IList<T>). That being the case, it appears as though the DataGrid is unable to dynamically determine the column names and you need to tell it yourself via the DataGrid.Columns property.

Here's a simple repro I put together.

MainWindow.xaml.cs:

namespace DataGridTest
{
    using System.Collections.Generic;
    using System.Windows;

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            Customers = this.GetCustomers();
            DataContext = this;
        }

        private IEnumerable<Customer> GetCustomers()
        {
            yield return new Customer() { Name = "first" };
            yield return new Customer() { Name = "second" };
            yield return new Customer() { Name = "third" };
        }

        public IEnumerable<Customer> Customers
        {
            get;
            set;
        }
    }

    public class Customer
    {
        public string Name
        {
            get;
            set;
        }
    }
}

MainWindow.xaml:

<Window x:Class="DataGridTest.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">
    <DataGrid ItemsSource="{Binding Customers}">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
        </DataGrid.Columns>
    </DataGrid>
</Window>

If you remove the DataGrid.Columns from the XAML, it displays three empty rows. So it appears as though it's not the enumerating of the data source that is broken when the source only implements IEnumerable<T>, but rather the automatic column creation.

Upvotes: 5

Related Questions