如何将Shell中的按钮绑定到已加载模块的viewmodel中定义的Command?

时间:2017-05-04 17:02:40

标签: wpf shell mvvm prism prism-6

情景如下:

我有一个在WPF,MVVM,Prism 6.3.0中开发的应用程序。这个应用程序考虑

  • Shell.xaml(shell)
  • UserControl1.xaml(在模块内部,独立的类库)

当我单击Shell中定义的Button时,我希望正在执行的命令和CanExecute中定义的条件得到验证。但是,此命令被定义到ViewModel类中,该类是模块的视图模型(在此应用程序中将是多个模块,在Prism实现此操作时加载)。

要调用,我尝试将一个localviewmodel定义到Shell的资源集合中。这会触发命令,但不会触发条件CanExecute。

如果我将用户控件中定义的XAML代码放在模块中,(换句话说,如果我编写一个不使用内容区域管理器的简单应用程序)单页XAML应用程序,该命令将验证CanExecute而不执行一个问题。我最好的猜测是将模块视图模型中定义的命令绑定到Shell中的按钮的问题。阅读了很多关于它的内容,我只是没有得到正确的方式来声明绑定。

以下是一个例子:

<Telerik:RadRibbonView x:Name="BarraHerramientas" Grid.Row="0"
                           DockPanel.Dock="Top" 
                           ContentHeight="130" 
                           Height="160" 
                           Template="{DynamicResource RadRibbonViewStyle}" 
                           MinimizeButtonVisibility="Visible" 
                           HelpButtonVisibility="Visible" Background="Red">
        <Telerik:RadRibbonTab Header="1" 
                              Style="{DynamicResource RadRibbonTabStyle}" 
                              IsSelected="True" 
                              TabIndex="0">
            <Telerik:RadRibbonGroup Header="RibbonGroup1" 
                                    DialogLauncherVisibility="Visible">
                <Telerik:RadRibbonButton CollapseToMedium="Never" 
                                         CollapseToSmall="WhenGroupIsMedium" 
                                         IsAutoSize="True" 
                                         LargeImage="Agregar.png" 
                                         Size="Large" 
                                         SmallImage="Agregar_16x16.png" 
                                         Text="Add..." 
                                         Command="{Binding AddRecordCommand, Source={StaticResource LocalViewModel}}" 
                                         CommandTarget="{Binding ElementName=MyRecords}"
                                         CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" " 
                                         Telerik:ScreenTip.Description="..." />
            </Telerik:RadRibbonGroup>
        </Telerik:RadRibbonTab>
</Telerik:RadRibbonView>

其中MyRecords是保存数据的GridView的名称,而LocalViewModel是加载模块中定义的ViewModel实例的键。因此,在LocalViewModel的一个时间点有两个实例,一个在Shell.xaml中定义为资源的实例,以及一个在加载的模块中定义的实例,它包含“MyRecords”GridView。

使用一页的例子,这当然是完美无缺的。因为我需要编写一些模块,每个模块都定义了自己的ViewModel,或者不止一个。所以,那是因为我需要使用定义到不同模块的视图模型中的命令,来自Shell的 。如果我在shell中声明每个ViewModel(很多数据进入)可能会出现性能问题。

那么,我如何调用ViewModel中定义的命令(来自shell)作为“按需”加载的模块中的资源?

谢谢大家。

1 个答案:

答案 0 :(得分:0)

有很多方法可以达到你想要的效果。一种方法是使用CompositeCommand。如果您的ShellViewModel将始终包含您用作参数的数据,这将适合您。每个ViewModel都可以订阅父CompositeCommand,每当调用CompositeCommand时,也会调用所有已注册的VM命令。您可以在此处查看CompositeCommands的示例:

https://github.com/PrismLibrary/Prism-Samples-Wpf/tree/master/12-UsingCompositeCommands

另一种方法是将您的功能区按钮注入您注入外壳的每个视图。因此,在添加/删除shell区域中的视图时,每个视图都将知道需要向功能区添加/删除哪些选项卡。您可以在我的Pluralsight课程中看到如何做到这一点Prism Problems&amp;解决方案:加载依赖视图:

https://www.pluralsight.com/courses/prism-problems-solutions