2009-03-02 9 views
0

Exemple de problème:WPF ListBox ListCollectionView problème de navigation type anonyme

Cadre: WPF Contrôle visuel: DataGrid de 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(); 
} 

Le curseur DataGrid ne change pas de position à 1, si le changement d'une valeur d'un des types anonymes:

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

curseur fonctionne correctement et SelectedIndex = 1.

Je pense que cela arrive à cause d'un remplacement d'objet anonyme GetHashCode() Pour un objet anonyme GetHashCode: somme de tous les champs. Si les champs sont identiques pour 2 instances différentes d'objets anonymes, GetHashCode() retournera la même valeur pour les deux instances.

Peut-être DataGrid compare-t-il en interne les objets à l'aide de GetHashCode et ne modifie pas SelectedPosition.

Est-ce que quelqu'un sait comment éviter ce problème? Attribution des objets anonymes à DataGrid est nécessaire, je ne peux pas créer des objets fortement typés, ce qui signifie que je dois créer une enveloppe pour l'objet et autogenerate les colonnes:

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

Merci

Répondre

2

Il y a un CustomSort propriété sur le DataGrid que vous pouvez définir à une implémentation de IComparer<T> qui vous permettra d'implémenter un ordre de tri personnalisé pour vos types anonymes. Il y a plus d'informations sur la propriété CustomSort ici:

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

Qu'est-ce que vous voulez faire est de créer effectivement une classe shell qui prend un délégué Comparer<T> et appelle ensuite que, dans la mise en œuvre de IComparer<T>.Compare. De cette façon, vous pouvez utiliser var pour déclarer l'instance (puisque vous ne saurez pas ce que T est) dans votre code qui crée le type anonyme.

L'idée que vous êtes lié à des types anonymes et que vous ne pouvez pas créer des objets fortement typés est un peu ridicule. Vous ne créez pas de requêtes anonymes à partir d'une source qui n'est pas connue au moment de la compilation, donc je ne vois pas pourquoi la restriction sur les types anonymes.