2011-03-01 52 views
2

我想在我的Silverlight MVVM应用程序中创建一个“向导”。该向导应包含多个步骤,您可以使用“next”和“previous”进行导航。 我面临的问题是视图和视图模型之间的关系。 我希望有一个视图和视图模型的向导本身。我的直觉告诉我,向导中的每一步都应该有一个视图/视图模型对。如何使用Silverlight和MVVM设计复合视图和视图模型?

维护这些关系的好方法是什么?一个视图模型包含多个其他视图模型,而视图实际上包含几个较小的视图? 我可以使用任何模式或做法吗?

我知道这个问题可能是主观的,但给我一个粗略的方法,我会给你一个答案!

回答

4

我建议主向导viewModel有一个steps视图模型的集合并处理它们之间的导航。在浏览它应该调用的验证方法中step的ViewModels:

WizardVM:

public class WizardVM 
{ 
    // this commands should support CanExecute 
    public ICommand GotoNextCommand { get; private set; } // should open next step VM 
    public ICommand GotoBackCommand { get; private set; } // should open previous step VM 

    // this prop should be set by 'GotoNext', 'GotoBack' commands 
    public object CurrentStep { get; private set; } 

    // probably internally you will have a list of all steps: 
    private ICollection<object> _stepViewModels = ...; 
} 

WizardView:

<StackPanel> 
    <ContentPresenter Content="{Binding CurrentStep}"> 
    <StackPanel Orientation="Horizontal"> 
     <Button Command="{Binding GotoBackCommand}">Back</Button> 
     <Button Command="{Binding GotoNextCommand}">Next</Button> 
    </StackPanel> 
</StackPanel> 

UPDATE

视图可以用的ViewModels经由Datatemplating耦合。例如添加到这个资源App.Xaml

<DataTemplate DataType="{x:Type local:Step1ViewModel}"> 
    <Step1View /> 
</DateTemplate> 
<DataTemplate DataType="{x:Type local:Step2ViewModel}"> 
    <Step2View /> 
</DateTemplate> 

你的ViewModels应该知道绝对没有关于意见。这意味着WizardVM应该 只公开其他viewModels但不公开视图。这是MVVM的经验法则。

UPDATE2糟糕,我忘了Silverlight还没有DataTemplating。在Silverlight中,我仍然会公开ViewModels,但使用转换器将它们绑定到ContentPresenters,转换器会将viewModel转换为相应的视图。

+0

哇,这很快! 但是......我很好奇,你认为CurrentStep属性应该是可见的东西(I.E一个视图)?否则,我不会看到ContentPresenter如何呈现它。我的问题是将包含的视图和视图模型与海誓山盟联系起来。 – 2011-03-01 22:08:43

+0

@Per,'CurrentStep'应该公开Step ViewModel。查看更新后的答案 – Snowbear 2011-03-01 22:14:23

+0

好的...使用值转换器将视图模型转换为视图。这是相当操纵,ehrm ..我的意思是务实的:)但不过,我没有想到一个新的方法!我怀疑这是我将要去做的事情,但是我将授予你创新的答案,甚至超出我自己的(而非操纵性的)本质......感谢您花时间回复! – 2011-03-02 06:20:02