在MVVM中实现命令

时间:2010-04-09 01:55:04

标签: wpf

我正在尝试在SampleCommand超时时更改Page1.xaml中帧的source属性。 我如何在View Model中实现这一点?

的Page1.xaml:

<Page ...>
<DockPanel>
    <r:ribbon>         
        <r:RibbonTab Label="Keys">
            <r:RibbonTab.Groups>
                <r:RibbonGroup GroupSizeDefinitions="{StaticResource RibbonLayout}">
                    <r:RibbonGroup.Command>
                        <r:RibbonCommand LabelTitle="RibbonButton"/>
                    </r:RibbonGroup.Command>
                    <r:RibbonButton x:Name="RibbonButton1" Command="{Binding Path=SampleCommand}"/>
                </r:RibbonGroup>
            </r:RibbonTab.Groups>
        </r:RibbonTab>
    </r:Ribbon>

    <Border Name="PageBorder" Grid.Row="0" Grid.Column="1">
        <Frame Name="pageFrame" Source="FirstPage.xaml" />

    </Border>
</DockPanel>
</Page>

Page1ViewModel.cs:

RelayCommand _sampleCommand;

public ICommand SampleCommand
{
    get
    {
        // create command ??

        return _sampleCommand 
    }
}

page1.xaml.cs:

Page1ViewModel pageViewModel;

//When page loads

this.DataContext = pageViewModel;

1 个答案:

答案 0 :(得分:3)

根据您正在使用的RelayCommand的实现,它应该将Action作为其构造函数的参数,该构造函数表示在实现时要调用的代码。所以在你的ViewModel中:

_sampleComand = new RelayCommand(() => DoStuff());

但这里的问题是,您希望在“pageFrame”控件上调用Navigate,而ViewModel将无法访问该控件。

可能最简单的方法是将Frame的NavigationService作为参数传递给命令。您可能需要更改_sampleCommand的声明,以便它知道它需要一个参数; RelayCommand的一些实现还定义了RelayCommand<T>,这是一个接受强类型参数的命令。

private ICommand _sampleCommand;
...
_sampleCommand = new RelayCommand<NavigationService>(
    ns => ns.Navigate(destinationUri));

所以现在你需要将框架的NavigationService传递给命令:

<r:RibbonButton x:Name="RibbonButton1" 
                Command="{Binding Path=SampleCommand}"
                CommandParameter="{Binding NavigationService,ElementName=pageFrame}"
                />

由于您的ViewModel可能会有一大堆导航命令,因此在ViewModel本身上设置NavigationService类型的属性可能更容易,并且在初始化时将页面挂钩到其框架。这样您就可以引用该属性,而不是每次都将其作为命令参数传递。