Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 绑定父窗口';使用MVVM将事件发送给UserControl内部处理程序_Wpf_Mvvm - Fatal编程技术网

Wpf 绑定父窗口';使用MVVM将事件发送给UserControl内部处理程序

Wpf 绑定父窗口';使用MVVM将事件发送给UserControl内部处理程序,wpf,mvvm,Wpf,Mvvm,我有一个在ContentControl中加载usercontrol的父窗口。父窗口有一个带有一些按钮(即保存按钮)的工具栏。我想分配那些按钮命令,这些命令将在usercontrol内部处理 我需要从usercontrol的ViewModel管理我自己的ICommand命令,因此,总结一下:用户单击“保存”按钮(在主窗口上),因此该按钮触发事件,usercontrol处理该事件以将信息保存在控件中 这可能吗?有两种方法 使用MVVM, 因为您的窗口包含UserControl,所以需要进行设置,以便

我有一个在ContentControl中加载usercontrol的父窗口。父窗口有一个带有一些按钮(即保存按钮)的工具栏。我想分配那些按钮命令,这些命令将在usercontrol内部处理

我需要从usercontrol的ViewModel管理我自己的ICommand命令,因此,总结一下:用户单击“保存”按钮(在主窗口上),因此该按钮触发事件,usercontrol处理该事件以将信息保存在控件中


这可能吗?

有两种方法

  • 使用MVVM,
    因为您的窗口包含UserControl,所以需要进行设置,以便该窗口引用UserControl ViewModel(假定它被称为UserControlViewModel)。如果您在UserControlViewModel中有一个命令,您可以通过调用:UserControlViewModel.command之类的命令绑定到该命令:

    <Button x:Name="Save" Content="Save" Command="{Binding UserControlViewModel.SaveCommand}">
    

  • 好的,您正在尝试将子元素的命令绑定到父窗口。首先给usercontrol命名(例如x:name=MyUserControl),并在usercontrol的datacontext/viewmodel(例如ICommand MyCommand)中编写一个公共命令。现在在按钮中执行此操作

    <Button x:Name="SaveButton" Command={Binding ElementName=MyUserControl, Path=DataContext.MyCommand} />
    
    
    
    这将把save buttons命令绑定到子usercontrol:)的datacontext中的命令

    顺便说一句,如果您正在寻找另一种解决方法(即在mvvm中将子命令绑定到父命令),那么您需要使用FindAncestor。你可以看看我的衣服
    关于这一点:)

    这听起来像是路由命令可以工作的情况。对于路由命令,将通行费按钮的命令设置为“保存”。然后在用户控件中,添加侦听“save”命令的命令绑定

    
    
    在命令绑定的代码隐藏事件处理程序中,只需找到viewmodel并在其viewmodel上调用save命令。如果您想要更纯粹的MVVM方法,您可以尝试

    使用这种方法,只要用户控件的焦点在其中的某个位置,那么save按钮的save命令将路由到用户控件的命令绑定并执行save命令

    <UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
      <UserControl.CommandBindings>
        <CommandBinding 
          Command="Save" 
          CanExecute="SaveCommand_CanExecute" 
          Executed="SaveCommand_Executed" 
        />
      </UserControl.CommandBindings>
    
    </UserControl>
    

    我认为这可能会实现将工具栏按钮与ContentPresenter中动态加载的用户控件分离的目标

    过了一会儿,我又回到这个问题上来。我需要与父窗口通信,因此我决定从父窗口执行viewmodel datacontext绑定权限,主要是因为我希望子viewmodel附加到从其父窗口触发的事件,并且我还可以向父窗口触发事件,以便显示子控件外的消息


    我知道我可能没有完全使用MVVM模式,但我想对这些功能有更多的控制。

    谢谢@Amit提供的代码和链接。我想做的是有一个带有一些按钮的包装器,我将加载我想要的任何usercontrol,但是每个usercontrol都应该响应在包装器上单击的事件。我能用一种更通用的方式吗?或者,我做错了吗?@Rodrigo Caballero:我能想到的最好的方法是。您可以下载并查看第6章。这将给你一个想法,然后你可以下载Prism的代码并以你自己的方式实现:)Hi@seekle,如果我没有显式声明usercontrol,而是用一个带有viewModel的ContentControl加载它们会怎么样。我如何告诉通用父级“知道”某些viewModel正在侦听其事件?谢谢你。事实上,这种方法可以解决这个问题。但是,您谈论的是使用应用程序命令。如果我想使用我自己的ICommands(在特定的ViewModel上),我认为这是不可能的,可能将命令作为静态属性,但我认为可能还有另一种方法。这种方法使用ApplicationCommands,您可以在UserControl中截取它。一旦被拦截,您可以在代码中调用自己的ICommand。或者,您可以使用类似Josh Smith的方法将截获的应用程序命令直接传递给VM。
    <Button x:Name="SaveButton" Command={Binding ElementName=MyUserControl, Path=DataContext.MyCommand} />
    
    <UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
      <UserControl.CommandBindings>
        <CommandBinding 
          Command="Save" 
          CanExecute="SaveCommand_CanExecute" 
          Executed="SaveCommand_Executed" 
        />
      </UserControl.CommandBindings>
    
    </UserControl>