Silverlight的4 + MVVM + KeyDown事件 [英] Silverlight 4 + MVVM + KeyDown event

查看:128
本文介绍了Silverlight的4 + MVVM + KeyDown事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用MVVM设计模式,以扩大我的知识,建立在Silverlight 4的样本游戏。我使用的洛朗·比尼翁的MvvmLight工具包,以及(在这里找到: HTTP://mvvmlight.$c$cplex.com/ )。所有我想做的事情,现在是一个画布pressing特定的密钥中移动的形状左右。我的解决方案包含一个Player.xaml(只是一个矩形,这将是到处移动)和MainPage.xaml中(Canvas和玩家控制的一个实例)

I'm trying to build a sample game in Silverlight 4 using the MVVM design pattern to broaden my knowledge. I'm using Laurent Bugnion's MvvmLight toolkit as well (found here: http://mvvmlight.codeplex.com/ ). All I want to do right now is move a shape around within a Canvas by pressing specific keys. My solution contains a Player.xaml (just a rectangle; this will be moved around) and MainPage.xaml (the Canvas and an instance of the Player control).

据我了解,Silverlight不支持隧道路由事件,只是冒泡。我的大问题是,Player.xaml从未承认KeyDown事件。它总是由MainPage.xaml中截获第一,它永远不会达到任何子控件,因为它气泡向上。我倒是preFER的逻辑移动播放器会在PlayerViewModel类,但我不认为球员可以知道任何的KeyDown事件射击没有我明确的传递MainPage的他们下来。

To my understanding, Silverlight doesn't support tunneling routed events, only bubbling. My big problem is that Player.xaml never recognizes the KeyDown event. It's always intercepted by MainPage.xaml first and it never reaches any child controls because it bubbles upward. I'd prefer that the logic to move the Player be in the PlayerViewModel class, but I don't think the Player can know about any KeyDown events firing without me explicitly passing them on down from the MainPage.

我结束了加入处理逻辑来MainPageViewModel类。现在我的问题是,MainPageViewModel不了解Player.xaml这么处理的KeyDown事件时,无法移动该对象。我想这是意料之中的,因为的ViewModels不应该有自己的相关意见的任何知识。

I ended up adding the handler logic to the MainPageViewModel class. Now my problem is that the MainPageViewModel has no knowledge of Player.xaml so it cannot move this object when handling KeyDown events. I guess this is expected, as ViewModels should not have any knowledge of their associated Views.

在没有那么多的话......有没有办法我MainPage.xaml中在该播放器的用户控件可以直接受理的KeyDown事件?如果没有,什么是我的MainPageViewModel与视图的子控件通讯的理想方法是什么?我试图保持code OUT的code隐藏文件尽可能。好像这是最好把逻辑中的ViewModels为便于测试,并从逻辑中分离出的UI。

In not so many words...is there a way this Player user control within my MainPage.xaml can directly accept and handle KeyDown events? If not, what's the ideal method for my MainPageViewModel to communicate with its View's child controls? I'm trying to keep code out of the code-behind files as much as possible. Seems like it's best to put logic in the ViewModels for ease of testing and to decouple UI from logic.

(MainPage.xaml中)

(MainPage.xaml)

<UserControl x:Class="MvvmSampleGame.MainPage"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:game="clr-namespace:MvvmSampleGame"             
         xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
         xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.SL4"
         mc:Ignorable="d"
         Height="300"
         Width="300"
         DataContext="{Binding Main, Source={StaticResource Locator}}">

<i:Interaction.Triggers>
    <i:EventTrigger EventName="KeyDown">
        <cmd:EventToCommand Command="{Binding KeyPressCommand}" PassEventArgsToCommand="True" />
    </i:EventTrigger>
</i:Interaction.Triggers>

<Canvas x:Name="LayoutRoot">       
    <game:Player x:Name="Player1"></game:Player> 
</Canvas>

(MainViewModel.cs)

(MainViewModel.cs)

public MainViewModel()
{

  KeyPressCommand = new RelayCommand<KeyEventArgs>(KeyPressed);

}       

public RelayCommand<KeyEventArgs> KeyPressCommand
{
    get;
    private set;
}

private void KeyPressed(KeyEventArgs e)
{

        if (e.Key == Key.Up || e.Key == Key.W)
        {
            // move player up

        }
        else if (e.Key == Key.Left || e.Key == Key.A)
        {
            // move player left
        }
        else if (e.Key == Key.Down || e.Key == Key.S)
        {
            // move player down
        }
        else if (e.Key == Key.Right || e.Key == Key.D)
        {
            // move player right
        }
}

在此先感谢, 杰里米

Thanks in advance, Jeremy

推荐答案

,尝试使用KeyTrigger并设置源对象是LayoutRoot。

Instead of using the EventTrigger, try to use the KeyTrigger and set the Source object to be the LayoutRoot.

另一种选择(我认为这是更好的)是让视图模型处理球员的位置。例如,有一个名为PlayerTop属性和一个名为PlayerLeft属性。玩家的Canvas.Top和Canvas.Left属性为这些绑定。当用户presses钥匙,一个命令是在其上更新这些属性在VM执行。以此方式,虚拟机不必知道什么被移动,或者它是如何移动。

Another option (which I think is better) is to let the ViewModel handle the position of the player. For example, have a property called PlayerTop and a property named PlayerLeft. Bind the PLayer's Canvas.Top and Canvas.Left property to these. When the user presses the Keys, a command is executed on the VM which updates these properties. This way the VM does not have to know what is moved, or how it is moved.

这是否有道理?

这篇关于Silverlight的4 + MVVM + KeyDown事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆