WPF ListBox ListCollectionView проблема навигации анонимного типа - PullRequest
0 голосов
/ 02 марта 2009

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

Каркас: 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: сумма всех полей. Если поля одинаковы для 2 разных экземпляров анонимных объектов, GetHashCode () вернет одинаковое значение для обоих экземпляров.

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

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

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

Спасибо

1 Ответ

2 голосов
/ 02 марта 2009

В 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) в вашем коде, который создает анонимный тип.

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

...