Запуск RelayCommand из CodeBehind, привязанного к виртуальной машине - PullRequest
8 голосов
/ 09 ноября 2010

Интересно, смогу ли я создать RelayCommand в моей ViewModel следующим образом:

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

ctor:

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

А из кода XAML я получаю выбранные строки изDataGrid и поместите их в список.

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

На этом этапе я хотел бы отправить список обратно в ViewModel с помощью той команды RelayCommand, которую я создал ранее.Возможно ли создать RelayCommand в коде и связать его с командой ViewModel и запустить его?

Какой альтернативный способ существует?Конечно, я мог бы использовать класс Messenger со слабой ссылкой в ​​MVVM-Light, но мне не нравится, что он будет отправлять его всем абонентам этого вызова, а не только базовому ViewModel (его использование Messenger смертельно опасно, если у вас несколькоэкземпляры одного и того же представления в TabControls)

Надеюсь, у кого-то есть идея поддержать меня, Большое спасибо, Каве

Ответы [ 2 ]

17 голосов
/ 09 ноября 2010

Просто вызовите метод Execute команды после проверки результата CanExecute:

var viewModel = (MyViewModel)DataContext;
if (viewModel.MyCommand.CanExecute(list))
    viewModel.MyCommand.Execute(list);
0 голосов
/ 01 августа 2011

и если иногда DataContext элемента пользовательского интерфейса отличается от формы в целом, как я столкнулся, то вы можете сделать что-то вроде этого:

 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);
    }

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

Обратите внимание, что FindVisualParent происходит отсюда >>> /532159/kak-ya-mogu-naiti-elementy-upravleniya-wpf-po-imeni-ili-tipu

...