views:

525

answers:

1

Example of problem:

Framework: WPF Visual control: DataGrid from CodePlex

public Window()
{
  InitializeComponent();

  var listView = new ListCollectionView(
    new[]
    {
       new 
       {   
         Bool = false,
         Str = "Value1"
       },
       new 
       {   
          Bool = false,
          Str = "Value1"
       }
     }.ToList());

  dataGrid.ItemsSource = listView;

  listView.MoveCurrentToFirst();
  listView.MoveCurrentToNext();
}

The DataGrid cursor doesn't change position to 1, if change a value of one of anonymous types:

var listView = new ListCollectionView(
    new[]
    {
       new 
       {   
         Bool = false,
         Str = "Value1"
       },
       new 
       {   
          Bool = false,
          Str = "Value2"
       }
     }.ToList());

Cursor works correct and SelectedIndex = 1.

I think it happens because of anonymous object override GetHashCode() For anonymous object GetHashCode: sum of all fields. If fields are the same for 2 different instances of anonymous objects GetHashCode() will return the same value for both instances.

Maybe DataGrid internally compares objects using GetHashCode and doesn't change SelectedPosition.

Does anybody know how avoid this problem? Assigning anonymous objects to DataGrid is requirement, I can't create strongly typed objects, which means I have to create a wrapper for the object and autogenerate the columns:

public class ViewItemHodler
{
   public object ViewItem { get; set; }
}

Thanks

+2  A: 

There is a CustomSort property on the DataGrid which you can set to an implementation of IComparer<T> which will allow you to implement a custom sort order for your anonymous types. There is more info on the CustomSort property here:

http://blogs.msdn.com/jgoldb/archive/2008/08/26/improving-microsoft-datagrid-ctp-sorting-performance.aspx

What you will want to do is actually create a shell class which takes a Comparer<T> delegate and then calls that in the implementation of IComparer<T>.Compare.

This way, you can use var to declare the instance (since you won't know what T is) in your code that creates the anonymous type.

The idea that you are bound to anonymous types and can't create strongly typed objects is a little ridiculous. You aren't creating anonymous queries from a source that isn't known at compile time, so I don't see why the restriction on anonymous types.

casperOne