2011-11-30 6 views
1

J'ai DataGrid lié à un ObservableCollection <> dans son ViewModel:dans WPF-Preselection DataGrid avec MVVM

<DataGrid ItemsSource="{Binding Path=Data}" SelectedItem="{Binding Path=CurrentItem}" /> 

ViewModel:

public ObservableCollection<TestModel> Data { get; set; } 

    private TestModel _currentItem; 

    public TestModel CurrentItem 
    { 
     get { return _currentItem; } 
     set 
     { 
      _currentItem = value; 
      RaisePropertyChanged("CurrentItem"); 
     } 
    } 

Maintenant ce que je veux est que le DataGrid présélectionnera la première ligne à droite au démarrage du formulaire. Donc, je mets ce qui suit dans mon test de code dans le constructeur:

Data = new ObservableCollection<TestModel> 
    { 
     new TestModel() { Property1 = Guid.NewGuid().ToString() }, 
     new TestModel() { Property1 = Guid.NewGuid().ToString() }, 
     new TestModel() { Property1 = Guid.NewGuid().ToString() } 
    }; 
    CurrentItem = Data[0]; 

Les données sont affichées, mais la première ligne n'est pas sélectionnée par la grille. Même si je mets la liaison à TwoWay, ça ne marchera pas.

Si je supprime le SelectedItem contraignant en XAML et ajouter ce qui suit dans le code-behind, il fonctionne bien:

private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     var m = this.DataContext as MainViewModel; 
     grid.SelectedItem = m.CurrentItem; 
    } 
+0

Pouvez-vous essayer si la sélection d'une ligne dans DataGrid met à jour la propriété CurrentItem de votre modèle de vue? – Amit

+0

@Amit Si vous voulez savoir, si le CurrentItem-setter est appelé lorsque je clique sur une ligne dans la grille alors la réponse est oui, c'est. Même si je laisse le réglage pour la direction de liaison. – sprinter252

+1

J'ai remarqué le même problème et j'ai fini par utiliser la même solution de contournement. – RQDQ

Répondre

1

Ce qui se passe est que votre machine virtuelle est affectée au contexte de données avant que la fenêtre est initialisé et ne reçoit donc jamais le message que CurrentItem a changé car il a été modifié avant son chargement. Ce que je fais, c'est passer dans le modèle de vue dans le constructeur de View et le définir après l'appel de la fonction InitializeComponent(). Parce que j'utilise Prism j'utilise l'inversion de contrôle (IOC) et Prism sait entrer ma VM dans le constructeur. Si vous instanciez votre vue et visualisez le modèle vous-même, vous pouvez simplement passer dans le modèle de vue. J'ai rencontré le même problème et cela fonctionne.

public MyView(IMyVM viewModel) 
    { 
     InitializeComponent(); 
     this.DataContext = viewModel; 
    } 

Par ailleurs, en travaillant avec MVVM, je ne vois aucune raison de ne pas passer dans le ViewModel dans la vue, car la vue dépend de toute façon. Je sais que certaines personnes se sentent différemment mais c'est soit cela ou vous devrez donc un certain type d'actualisation du datacontext dans l'événement Window_Loaded.

Questions connexes