tags:

views:

131

answers:

3

I have a list which contains the data that is shown in my WPF Datagrid. I have the following code which searches the grid for a match with a textbox entered string. the code is in a button click handler.

var search = from s in dglist // dglist is my List<APerson>
                         where s.FirstName == textBox1.Text
                         select new
                             {
                                 Firstname = s.FirstName,
                                 Lastname = s.LastName
                             };
dataGrid1.ItemsSource = search; 

The last line does not put the resultset in search back into the datagrid, why?

A: 

A LINQ query returns an IEnumerable result set, whereas ToList returns List<> (of course). The differences with these is that enumerable where List has the ability to reference by index, alter the list, and use methods to find at specific values.

I am surprised the original query didn't work, which is why you are still seeing the loading in the DataGrid as you mentioned... Also, to return an APerson enumerable collection, you need to change your query to:

select new APerson { ... }

So that the final resultset is of the type you want. That may be another issue potentially with anonymous types??? Not sure on that one. Seems odd...

Sorry, this may not help...

Brian
+1  A: 

Tony, Brian is correct - your original code should work as you described, as long as you have the columns properly configured. The grid will enumerate the query for you and you do not need to use ToList() yourself. I created a test project and it worked. Is it possible that you have to revisit the Binding properties of your columns? Did you leave the grid to auto-generate the columns? If so, when you assign the project out the anonymous object the grid won't know what to display.

Try configuring the columns as following:

<wpftk:DataGrid.Columns>
   <wpftk:DataGridTextColumn Header="First Name" Binding="{Binding Path=FirstName}"  />
   <wpftk:DataGridTextColumn Header="Last Name" Binding="{Binding Path=LastName}"/>
</wpftk:DataGrid.Columns>

Also, in your projection you use Firstname = s.FirstName. Note the lower case n in Firstname. This won't match the column binding of the grid and nothing will be updated. You don't need to specify a different name in your projection. You can simply do select new {s.FirstName, s.LastName}...

Finally, just a suggestion, I wouldn't set the ItemsSource of the grid directly. I would use a DataContext, as you may consume the same data in a different control in the future.

Gustavo Cavalcanti
+1  A: 

I cannot offer a solution but only a workaround: If you use

dataGrid1.ItemsSource = search.ToList();

the LINQ query will be evaluated right now, which should trigger an update in your list.

Heinzi
Did this really work? It should not have worked...
Gustavo Cavalcanti
@Gustavo: Why? Like Brian and you, I am surprised that Tony's original solution didn't work. But why should binding to a list fail?
Heinzi
Heinzi, my point is binding to a List<> in this case is the same thing as binding to the IEnumerable, as the grid itself will enumerate the IEnumerable. If binding to the IEnumerable is not working, in my opinion, binding to seach.ToList() wouldn't make any difference whatsoever. That's what I meant by "it should not have worked".
Gustavo Cavalcanti
@Gustavo: I get your point. Still, binding to the IEnumerable *does* seem to work (the first time), so somehow the dataGrid doesn't realize that the ItemsSource is set to a *different* IEnumerable. BTW, is it even a *different* IEnumerable? Isn't it the same LINQ closure before and after setting ItemsSource?
Heinzi