MVVM:在Windows 8中使用键盘处理列表项导航

MVVM:在Windows 8中使用键盘处理列表项导航,mvvm,windows-8,keyboard,navigation,mvvm-light,Mvvm,Windows 8,Keyboard,Navigation,Mvvm Light,我对Windows8的开发完全陌生,我现在面临着一个问题,即使用MVVM Light进行触摸和键盘导航 因此,我在网格视图中有一个视图模型列表,只要选择其中一个,就会激活到所选视图模型的导航。这在触摸屏或鼠标上完全可以使用,但在键盘上,它会变得非常混乱。事实上,当我想显示项目时,自然的行为是用箭头导航列表并按enter键,但在这里,当简单地用箭头键更改项目时,导航将被激活,这对用户来说确实很困惑 那么,我该怎么做才能通过触摸和鼠标的选择激活导航,以及通过键盘的选择和输入键的组合激活导航呢 这是我

我对Windows8的开发完全陌生,我现在面临着一个问题,即使用MVVM Light进行触摸和键盘导航

因此,我在网格视图中有一个视图模型列表,只要选择其中一个,就会激活到所选视图模型的导航。这在触摸屏或鼠标上完全可以使用,但在键盘上,它会变得非常混乱。事实上,当我想显示项目时,自然的行为是用箭头导航列表并按enter键,但在这里,当简单地用箭头键更改项目时,导航将被激活,这对用户来说确实很困惑

那么,我该怎么做才能通过触摸和鼠标的选择激活导航,以及通过键盘的选择和输入键的组合激活导航呢

这是我使用的代码

视图模型:

public ReleaseViewModel SelectedRelease
{
    get
    {
        return selectedRelease;
    }
    set
    {
        if(selectRelease != value)
        {
            selectedRelease = value;
        }

        // Navigation code here
    }
}
视图:


在我看来,使用MVVM模式编码并不意味着所有与代码相关的事情都应该在模型中完成。与UI Beavior相关的操作(如导航)仍应在视图(codebehind)中通过使用控件中的可用事件来完成。类似于GridView的事件鼠标和键盘事件

很多人可能不同意我的观点,但在WPF和Silverlight中使用MVVM模式多年后,我必须说,如果UI行为(视图)和控件的逻辑/功能性(模型)结合良好,您还将被迫将一些只与UI有关的内容放到代码背后。至少,这是我的观点

您可以做的是创建一个继承GridView的类(我们称之为MyDataGrid)。 然后,您可以使用OnKeyDown覆盖,并在按enter键时使导航垂直。
实际上,你可以让MyDataGrid的外观和行为“开箱即用”,就像你想要的那样,这样,如果你想在你的应用程序(或其他应用程序)的其他地方使用相同的网格行为,就不需要额外的代码了。

我最终找到的最佳方法是使用一些隐藏的代码。但是我没有直接从UI导航,而是在视图模型中保留了导航逻辑

因此,我只是从GridView连接了ItemClick事件,在事件处理程序中,我将页面数据上下文转换为视图模型,然后从视图模型执行命令。这不容易维护,但它确实保持了MVVM关注点的分离

private void GridView_ItemClick(object sender, ItemClickEventArgs e)
{
    MyViewModel vm = (MyViewModel)this.DataContext;

    if(vm.NavigateToSelectionCommand.CanExecute(null))
    {
        vm.NavigateToSelectionCommand.Execute(e.ClickedItem);
    }
}

不过,我还是希望随着时间的推移,能找到一个更干净、更易于维护的解决方案。

我最初是一名WPF开发人员,迁移到这个新平台实际上让我想知道导航究竟是一个UI问题还是一个应用程序逻辑问题?它是应用程序工作流的一部分,但同时也是一个UI运动。实际上,我想知道MVVM模式是否变得不那么极端,并将导航返回到UI(如在默认模板中)。关于GridView,无需扩展它,因为处理单击事件实际上对键盘/触摸/鼠标自然交互的反应是一致的,但它当然与MVVM.True不兼容。很难区分什么是UI和什么不是UI,因为在某些情况下,这是一个因人而异的定义。我通常说,当涉及到如何选择事物或获取值时,这是一个UI问题。如果是双击、单击、单击按钮或选项卡,则使用键盘/回车键。这对模特来说真的不重要。该模型只关注实际选中时发生的情况。而不是如何。我不是设计师。如果设计师能就用户如何工作提出更好的解决方案,我希望不必改变模型。只有视图。需要从工作流/导航的角度来管理UI的状态。此关注领域通常通过ApplicationController模式解决。Laurent在他的例子中称之为“导航服务”,但这与此非常接近。ApplicationController可以像switch语句一样简单,也可以像完全有限状态机一样复杂。主要的是视图和/或ViewModel将向ApplicationController发送消息(或触发事件),然后ApplicationController将UI导航到新视图。
private void GridView_ItemClick(object sender, ItemClickEventArgs e)
{
    MyViewModel vm = (MyViewModel)this.DataContext;

    if(vm.NavigateToSelectionCommand.CanExecute(null))
    {
        vm.NavigateToSelectionCommand.Execute(e.ClickedItem);
    }
}