如何在viewmodel中设置xaml内容

时间:2012-03-21 18:25:10

标签: silverlight xaml mvvm ria

我有一个超链接按钮,如果登录成功,我在按钮中点击内容后面的代码点击新视图。

    private void OkButtonClick(object sender, RoutedEventArgs e)
    {
        LoginOperation loginOp = FLS.Utilities.RIAWebContext.Current.Authentication.Login(
            new LoginParameters(usernameTextBox.Text, passwordTextBox.Text));
        loginOp.Completed += (s2, e2) =>
        {
            if (loginOp.HasError)
            {
                errorTextBlock.Text = loginOp.Error.Message;
                loginOp.MarkErrorAsHandled();
                return;
            }
            else if (!loginOp.LoginSuccess)
            {
                errorTextBlock.Text = "Login failed.";
                return;
            }
            else
            {
                errorTextBlock.Text = string.Empty;
                Content = new WelcomeView();

            }
        };
    }

我现在已经在视图模型中移动了MVVM的代码,并在超链接按钮上使用了delegateCommand。

<UserControl ... >
<Grid ... >
...
<HyperlinkButton Content="Login" Height="23" HorizontalAlignment="Left" Margin="313,265,0,0" Name="loginButton" Command="{Binding Path=LoginCommand}" VerticalAlignment="Top" Width="75"/>
...
</Grid>
</UserControl>

但我不知道,我如何制作Content = new WelcomeView();来自viewmodel中的代码?

1 个答案:

答案 0 :(得分:0)

一个好的设计模式是拥有两个不同的数据模板,一个用于在登录前显示数据,另一个用于登录后使用的数据模板。

有几种方法可以实现这一目标。我通常使用的那个只是将ViewModel(直接使用绑定)放在Window的唯一子项中。

在ViewModel中实现内容选择器类。这是一个派生自DataTemplateSelector的类,它使用FindResource API来获取适当的数据模板。

<Window ...>
    <Window.Resources>
        <DataTemplate x:key="beforeLogin">
            ...
        </DataTemplate>
        <DataTemplate x:Key="afterLogin">
            ...
        </DataTemplate>            
    </Window.Resources>

    <Window.ContentTemplateSelector>
        <code:MyTemplateSelector />
    </Window.ContentTemplateSelector>

    <-- Here is the content of Window. It's the view model (data). The View will be
        bind by the TemplateSelector
    <code:YourViewModel />

</Window>

查看此页面:http://msdn.microsoft.com/en-us/library/system.windows.controls.contentcontrol.contenttemplateselector.aspx以获取相关示例。

还有其他设计模式。另一个常见的习惯是简单地触发“UiRequest”事件,该事件将由视图的代码隐藏。请记住,MVVM规定ViewModel是“视图不可知”,但它实际上并不意味着“没有代码隐藏”。这意味着VM无法引用视图中的任何内容。通过这种方式进行通信会发生视图事件(例如,数据绑定只是属性更改事件的包装)。因此,在View Model中有一个事件UiRequest,并设计一个协议。在View的构造函数中 - 注册一个处理程序。在处理程序中,更改内容(人们使用这个成语主要是为了启动一个弹出窗口,但它可以在任何地方使用)。