【问题标题】:how can I set the xaml content in viewmodel如何在 viewmodel 中设置 xaml 内容
【发布时间】:2012-03-21 18:25:09
【问题描述】:

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

    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();来自视图模型中的代码?

【问题讨论】:

    标签: silverlight xaml mvvm ria


    【解决方案1】:

    一个好的设计模式是有两个不同的数据模板,一个在登录前呈现数据,第二个数据模板在登录后使用。

    有几种方法可以实现这一目标。我通常使用的只是将 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 无法引用视图中的任何内容。以这种方式通信发生在视图事件(例如,数据绑定只是属性更改事件的包装器)。所以在你的视图模型中有一个事件 UiRequest,并设计一个协议。在 View 的构造函数中 - 注册一个处理程序。在handler中,改变内容(人们用这个习语主要是为了启动一个弹窗,但它可以在任何地方使用)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-12
      • 1970-01-01
      • 1970-01-01
      • 2016-11-27
      • 2011-06-03
      • 1970-01-01
      相关资源
      最近更新 更多