2010-11-09 23 views
8

Mi chiedo se posso creare un RelayCommand sul mio ViewModel come questo:Firing RelayCommand da CodeBehind destinata a VM

public RelayCommand<IList<VectorViewModel>> MyCommand { get; set; } 

ctor:

MyCommand = new RelayCommand<IList<VectorViewModel>>(DoSomething); 

E dal codice dietro XAML, ho la righe selezionate da un DataGrid e metterle in una lista.

if (xamDatagridVector.SelectedItems.Records.Count >= 3) 
{ 
       var list = new List<VectorViewModel>(); 
       foreach (DataRecord record in xamDatagridVector.SelectedItems.Records) 
       { 
        list.Add((VectorViewModel)record.DataItem); 
       } 
} 

A questo punto vorrei restituire la lista al ViewModel utilizzando tale RelayCommand avevo creato in precedenza. Sarebbe possibile creare un RelayCommand nel codice e collegarlo al comando ViewModel e attivarlo?

Quale alternativa c'è? Ovviamente potrei usare la classe Messenger di debole riferimento in MVVM-Light, ma qualcosa che non mi piace è che lo invierà a tutti gli utenti di quella chiamata, e non solo al ViewModel sottostante (È mortale usare Messenger quando ne hai diversi istanze dello stesso View all'interno TabControls)

spero che qualcuno ha un'idea per farmi andare avanti, Molte grazie, Kave

risposta

14

Basta chiamare il metodo del comando Execute dopo aver controllato il risultato di CanExecute:

var viewModel = (MyViewModel)DataContext; 
if (viewModel.MyCommand.CanExecute(list)) 
    viewModel.MyCommand.Execute(list); 
0

a ND se a volte il DataContext di un elemento dell'interfaccia utente è diversa dalla forma nel suo complesso, come ho incontrato, allora si può fare qualcosa di simile:

private void TextBoxTextChanged(object sender, TextChangedEventArgs e) 
    { 
     var binding = ((TextBox)sender).GetBindingExpression(TextBox.TextProperty); 
     binding.UpdateSource(); 

     var msg = String.Format("Migrator file selection updated to {0}", ((TextBox)sender).Text); 
     var rowControl = UiHelpers.FindVisualParent<UserControl>((DependencyObject)sender); // get the  FileNameSettingsRow UserControl 
     var form = UiHelpers.FindVisualParent<UserControl>((DependencyObject)rowControl); // get the main form it is used on 

     var viewModel = (UseCaseSettingsViewModel)form.DataContext; 

     if (viewModel.UpdateFileInCollectionCommand.CanExecute(((TextBox)sender).Text)) 
      viewModel.UpdateFileInCollectionCommand.Execute(((TextBox)sender).Text); 


     Messenger.Default.Send(new NotificationMessage(this, msg), Notifications.AppendSysMessageTextToken); 

     // Tell the UseCaseSettingsViewModel to force an update and reload 
     //Messenger.Default.Send(new NotificationMessage(this, ((TextBox)sender).Text), Notifications.FileSelectionChangedInternalToken); 
    } 

che troverà il DataContext di UserControl su cui esiste l'UserControl subordinato , quindi vai avanti e fai cose divertenti come indicato nelle risposte precedenti. In questo caso, la modifica di una casella di testo sul controllo utente subordinato era necessaria per dire al modello di visualizzazione sovrastante che il testo era cambiato.

Nota che FindVisualParent viene da qui >>> https://stackoverflow.com/questions/636383/wpf-ways-to-find-controls