Проблема с навигацией анонимного типа в WPF ListBox ListCollectionView

Пример проблемы:

Платформа: WPF Визуальный контроль: DataGrid из 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();
}

Курсор DataGrid не меняет позицию на 1, если изменить значение одного из анонимных типов:

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

Курсор работает правильно и SelectedIndex = 1.

Я думаю, это происходит из-за переопределения анонимного объекта GetHashCode(). Для анонимного объекта GetHashCode: сумма всех полей. Если поля одинаковы для двух разных экземпляров анонимных объектов, GetHashCode() вернет одно и то же значение для обоих экземпляров.

Возможно, DataGrid внутренне сравнивает объекты с помощью GetHashCode и не изменяет SelectedPosition.

Кто-нибудь знает, как избежать этой проблемы? Назначение анонимных объектов в DataGrid является обязательным требованием, я не могу создавать строго типизированные объекты, что означает, что мне нужно создать оболочку для объекта и автоматически сгенерировать столбцы:

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

Спасибо


person user72888    schedule 02.03.2009    source источник


Ответы (1)


В DataGrid есть свойство CustomSort, которое вы можете установить для реализации IComparer<T>, что позволит вам реализовать собственный порядок сортировки для ваших анонимных типов. Дополнительная информация о свойстве CustomSort приведена здесь:

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

Что вам нужно сделать, так это создать класс оболочки, который принимает делегата Comparer<T>, а затем вызывает его в реализации IComparer<T>.Compare.

Таким образом, вы можете использовать var для объявления экземпляра (поскольку вы не будете знать, что такое T) в своем коде, который создает анонимный тип.

Идея о том, что вы привязаны к анонимным типам и не можете создавать строго типизированные объекты, немного нелепа. Вы не создаете анонимные запросы из источника, который не известен во время компиляции, поэтому я не понимаю, почему ограничение на анонимные типы.

person casperOne    schedule 02.03.2009