【问题标题】:How to handle the back button on WP 8.1 using MVVM light?如何使用 MVVM 灯处理 WP 8.1 上的后退按钮?
【发布时间】:2015-03-23 01:32:12
【问题描述】:

我正在寻找使用 MVVM 灯 5 上可用的 NavigationService 在 Windows Phone 8.1 WinRT 上处理后退按钮按下事件的适当方法。

到目前为止,我认为最好的方法是在 ViewModelLocator 内注册 NavigationServiceGoBack 方法,同时按照 NavigationService in MVVM Light V5 中概述的方法创建它

这是一种有效的方法。但是,在返回之前我无法处理验证,所以我想知道是否有更合适的方式来处理此事件。

public class ViewModelLocator
{
    public ViewModelLocator()
    {
        ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
        // Register NavigationService
        SimpleIoc.Default.Register(CreateNavigationService);
        // Register ViewModels here
    }

    private INavigationService CreateNavigationService()
    {
        var navigationService = new NavigationService();
        // Register pages here
        navigationService.Configure("Details", typeof(DetailsPage));
        // Handle back button
        HardwareButtons.BackPressed += (sender, args) => {
            navigationService.GoBack();
            args.Handled = true;
        }; 
        return navigationService;
    }
}

【问题讨论】:

  • 您希望执行哪种验证?结果是否只是一个简单的布尔值,告诉 NavigationService 是否可以导航?
  • 是的,我期待某种 CanNavigate 布尔返回方法,但逻辑可能取决于 ViewModel
  • mytoolkit.codeplex.com 具有框架、页面和导航的实现,其行为类似于 WP8 SL。有关该主题的更多信息:stackoverflow.com/questions/11539755/…

标签: c# mvvm windows-phone-8.1 winrt-xaml mvvm-light


【解决方案1】:

如果您在博文中了解 Marco 如何启用 OnNavigatedTo 和 OnNavigatedFrom 调用以传播到 ViewModel

Calling ViewModel methods in response to Page navigation events using MVVM Light in WinRT

您会注意到他使用了 INavigable 接口以及激活和停用方法。您可以使用 AllowGoingBack 方法扩展该 INavigable 接口,如下所示:

public interface INavigable
{
    void Activate(object parameter);
    void Deactivate(object parameter);
    bool AllowGoingBack();
}

然后,每个与页面相关的 ViewModel 都可以根据上下文拥有自己的 AllowGoingBack 方法实现。然后,在 View 后面的代码中(没关系,因为 View 可以知道 ViewModel)你可以重写 OnNavigatingFrom 并检查是否应该允许返回:

protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
    var navigableViewModel = this.DataContext as INavigable;

    if (navigableViewModel != null)
    {
        if (e.NavigationMode == NavigationMode.Back && !navigableViewModel.AllowGoBack())
        {
            e.Cancel = true;
        }
    }
}

然后您的 ViewModel 将实现 INavigable,因此您将在 AllowGoingBack() 中定义验证代码,如果返回正常则返回 true,否则返回 false。

【讨论】:

  • 非常好的主意,我终于把它留给任何类型的导航(不仅是返回),但使用 OnNavigatingFrom 是我所缺少的。谢谢!
【解决方案2】:

根据 igrali 的回答,并按照Calling ViewModel methods in response to Page navigation events using MVVM Light in WinRT 中的说明,我在“BindablePage.cs”类中所做的,在 OnNavigatedTo 方法中添加以下内容:

            HardwareButtons.BackPressed += HardwareButtons_BackPressed;

在 OnNavigatedFrom 中:

            HardwareButtons.BackPressed -= HardwareButtons_BackPressed;

然后添加事件处理程序:

        void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
        {
            var navigableViewModel = this.DataContext as INavigable;
            if (navigableViewModel != null)
                navigableViewModel.BackButonPressed(e);
        }

接下来,在 INavigable 界面中添加

void BackButonPressed(Windows.Phone.UI.Input.BackPressedEventArgs e);

最后,在每个视图模型上:

public void BackButonPressed(Windows.Phone.UI.Input.BackPressedEventArgs e)
{
    // You can modify this code to show a confirmation dialog, etc...
    e.Handled = true;
    navigationService.GoBack(); 
}

如果这是一个通用应用,那么别忘了用#if WINDOWS_PHONE_APP ... #endif包围这些新代码

【讨论】:

    【解决方案3】:

    我发现一篇关于你的问题的有趣文章:http://blog.falafel.com/windows-phone-and-mvvm-light-navigationservice-and-cangoback/

    这就是想法:

    public AboutPage()
    {
       this.InitializeComponent();
       HardwareButtons.BackPressed += HardwareButtons_BackPressed;
    }
    
    private void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
    {
       var frame = Window.Current.Content as Frame;
       if (frame.CanGoBack)
       {
          var navigation = ServiceLocator.Current.GetInstance<INavigationService>();
                navigation.GoBack();
                e.Handled = true;
       }
     }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-13
      • 2011-10-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多