【问题标题】:Changing frame in windows store app using MVVM使用 MVVM 在 Windows 商店应用程序中更改框架
【发布时间】:2015-12-18 21:02:49
【问题描述】:

我正在用 c# 制作一个 Windows 商店应用程序。在我的 MainPage 中,我有一个框架。我的按钮绑定到 RelayCommand,当用户单击按钮时,框架应更改 AddMovie 框架。为什么它不会改变框架?我的框架已绑定到我的视图模型中的框架属性。

 private Frame _frame;

    public Frame Frame
    {
        get { return _frame; }
        set
        {
            _frame = value;
            OnPropertyChanged();
        }
    }

在构造函数中

   _frame = new Frame();
   NavToCommand = new RelayCommand(() =>
    {
        Frame.Navigate(typeof(AddMovie));
    });

【问题讨论】:

  • 请注意,在 ViewModel 中使用 View 相关的东西是直接违反 MVVM 原则的
  • 为什么是直接违规?你能发个链接让我了解一下具体的违规行为吗?
  • MVVM 旨在将表示逻辑分离到 ViewModel 中,并使 ViewModel 在不同平台之间解耦和重用(即在 Windows Store Apps、Silverlight、WPF 甚至控制台应用程序中具有相同的 ViewModel 工作)并且很容易可测试的。当您在 ViewModels 中引用与 View 相关的类型时,您将 Viewmodel 与某种技术(即 WPF 或 UWP)紧密结合,并且您无法再对该代码进行单元测试。很容易违反这条规则,如果你在同一个项目中有 ViewModel 和 Views,那么与视图相关的类型就没有Frame那么明显
  • 因此,要真正实施这种分离,必须将 ViewModel 放入自己的程序集中,该程序集不引用 Presentation.dll 或其他与视图相关的程序集。那么违规就更明显了。如果您随后尝试在 ViewModel 中使用Frame,您将能够因为“缺少程序集引用”而对 Presentation.dll (WPF) 或 Windows 应用商店应用程序引用,并且违规行为变得明显并且您知道:“我尝试的方法是错误的。我需要另辟蹊径”

标签: c# wpf mvvm windows-store-apps


【解决方案1】:

确保您在 MainPage 中用于导航的框架与您的应用用作当前窗口内容的框架相同。

通常您不需要在 MainPage 中创建新框架。相反,它是在 App.xaml.cs 中以如下所示的方法设置的:

    /// <summary>
    /// Invoked when the application is launched normally by the end user.  Other entry points
    /// will be used such as when the application is launched to open a specific file.
    /// </summary>
    /// <param name="e">Details about the launch request and process.</param>
    protected override void OnLaunched(LaunchActivatedEventArgs e)
    {
        Frame rootFrame = Window.Current.Content as Frame;

        // Do not repeat app initialization when the Window already has content,
        // just ensure that the window is active
        if (rootFrame == null)
        {
            // Create a Frame to act as the navigation context and navigate to the first page
            rootFrame = new Frame();

            rootFrame.NavigationFailed += OnNavigationFailed;

            if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
            {
                //TODO: Load state from previously suspended application
            }

            // Place the frame in the current Window
            Window.Current.Content = rootFrame;
        }

        if (e.PrelaunchActivated == false)
        {
            if (rootFrame.Content == null)
            {
                // When the navigation stack isn't restored navigate to the first page,
                // configuring the new page by passing required information as a navigation
                // parameter
                rootFrame.Navigate(typeof(MainPage), e.Arguments);
            }
            // Ensure the current window is active
            Window.Current.Activate();
        }
    }

您可以在该阶段将 rootFrame 注入 MainPage 并将其用于导航目的,而不是创建新实例。

但是,如果您想将 Navigation 与 MVVM 一起使用,请在此处查看如何在我的其他答案中实现 NavigationService 模式: https://stackoverflow.com/a/38362370/1008758

【讨论】:

    猜你喜欢
    • 2013-09-09
    • 2014-02-03
    • 2013-06-24
    • 2012-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多