views:

32

answers:

2

I'm trying to fill a DataGrid with an anonymous type generated by a LINQ query. When I put the query results in a list box, it appears fine. However, when I put the query results in a data grid, the correct number of rows are generated, but the cells are empty.

Silverlight screen cap showing the error

(The data grid is on the left, with the list box on the right.)

Assigning the data source:

testListBox.ItemsSource = debtPerUser.ItemsSource = ExpenseViewModel.getDebtData(username);

The XAML:

<sdk:DataGrid Height="222" HorizontalAlignment="Left" Margin="31,89,0,0" Name="debtPerUser" VerticalAlignment="Top" Width="516" AutoGenerateColumns="True" />
<ListBox Height="222" HorizontalAlignment="Left" Margin="567,89,0,0" Name="testListBox" VerticalAlignment="Top" Width="173" />

What could I be doing wrong here?

getDebtData:

    internal static IEnumerable getDebtData(string username)
    {
        IEnumerable<String> users = getUsersInvolving(username);

        var debt = from user in users
                   select new {
                     User = user,
                     Net = owedBetween(username, user) - owedBetween(user, username)
                   };

        return debt.Where(d => d.Net != 0);
    }

Update: It works when I'm not using an anonymous query type. Perhaps that's the problem?

A: 

Without knowing exactly what type of collection the method ExpenseViewModel.getDebtData returns, if it's using LINQ you might have some luck trying ExpenseViewModel.getDebtData(username).ToList()

bufferz
It returns `IEnumerable`, but the type of `ItemsSource` is `IEnumerable` as well, so I don't think that's the issue. Also, the return type doesn't have a `ToList()` method.
Rosarch
+2  A: 

Yes, anonymous types are designed to be used in the method they're declared in. Exposing them outside can lead to evil outcomes. I would use a strongly typed enumerable in this case.

vc 74
+1: to be technical the reason this doesn't work is that anonymous types are internal. Binding requires the types involved to be visible to the System.Windows assembly and hence this typically requires those types to be public. This can be circumvented to degree by adding the `InternalsVisibleTo` assembly attribute and specifying the strong name for the System.Windows assembly.
AnthonyWJones