从绑定到 VM 的 CodeBehind 触发 RelayCommand

发布于 2024-10-02 06:15:55 字数 960 浏览 0 评论 0原文

我想知道是否可以在 ViewModel 上创建一个 RelayCommand,如下所示:

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

在此阶段,我想使用我之前创建的 RelayCommand 将列表发送回 ViewModel。是否可以在代码中创建一个 RelayCommand 并将其绑定到 ViewModel 的命令并将其关闭?

还有什么替代方法吗?我当然可以在 MVVM-Light 中使用弱引用的 Messenger 类,但我不喜欢的是它会将其发送给该调用的所有订阅者,而不仅仅是底层的 ViewModel(当你有多个订阅者时,使用 Messenger 是致命的) TabControls 中相同视图的实例)

我希望有人有一个想法让我继续前进, 非常感谢, 卡韦

I wonder if I can create a RelayCommand on my ViewModel like this:

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

ctor:

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

And from the Code behind XAML, I get the selected rows from a DataGrid and put them into a List.

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

At this stage I would like to send the List back to the ViewModel by using that RelayCommand I had created earlier. Would that be possible to create a RelayCommand in code and Bind it to the ViewModel's command and fire it off?

What alternative way is there? I could of course use the weak-referenced Messenger class in MVVM-Light, but something I dont like there is that it will send it to all subscribers of that call, and not only the underlying ViewModel (Its deadly using Messenger when you have several instances of the same View within TabControls)

I hope someone has an idea to keep me going,
Many Thanks,
Kave

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

原来分手还会想你 2024-10-09 06:15:55

只需在检查 CanExecute 的结果后调用命令的 Execute 方法即可:

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

Just call the Execute method of the command after checking the result of CanExecute:

var viewModel = (MyViewModel)DataContext;
if (viewModel.MyCommand.CanExecute(list))
    viewModel.MyCommand.Execute(list);
靖瑶 2024-10-09 06:15:55

如果有时 ui 元素的 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);
    }

它将找到存在从属 UserControl 的 UserControl 的 DataContext,然后继续进行有趣的操作前面的答案中指出的事情。在这种情况下,编辑从属用户控件上的文本框需要告诉总体视图模型文本已更改。

请注意,FindVisualParent 来自此处>>> https://stackoverflow.com/questions/636383/wpf-ways-to-find-controls

and if sometimes the DataContext of a ui element differs from the form as a whole, as I encountered, then you can do something like this:

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

which will find the DataContext of the UserControl on which the subordinate UserControl exists, then go ahead and do fun things as indicated in the earlier answers. In this case editing a text box on the subordinate user control needed to tell the overarching viewmodel that the text had changed.

Note that FindVisualParent comes from here >>> https://stackoverflow.com/questions/636383/wpf-ways-to-find-controls

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文