我想在Silverlight 4中使用MVVM設計模式來擴展我的知識來構建一個示例遊戲。我也使用Laurent Bugnion的MvvmLight工具包(在這裏找到:http://mvvmlight.codeplex.com/)。我現在想要做的就是通過按特定鍵在Canvas中移動一個形狀。我的解決方案包含一個Player.xaml(只是一個矩形;這將被移動)和MainPage.xaml(Canvas和Player控件的一個實例)。Silverlight 4 + MVVM + KeyDown事件
據我的理解,Silverlight不支持隧道路由事件,只冒泡。我的大問題是Player.xaml永遠不會識別KeyDown事件。它總是首先被MainPage.xaml攔截,它永遠不會到達任何子控件,因爲它向上冒泡。我更喜歡移動播放器的邏輯是在PlayerViewModel類中,但我不認爲播放器可以知道任何KeyDown事件沒有我明確地從MainPage傳遞它們。
我最終將處理程序邏輯添加到MainPageViewModel類。現在我的問題是,MainPageViewModel不知道Player.xaml,所以在處理KeyDown事件時它不能移動這個對象。我想這是預期的,因爲ViewModels不應該有任何關於它們相關視圖的知識。
沒有那麼多的話......這個Player用戶在我的MainPage.xaml中控制的方式是否可以直接接受和處理KeyDown事件?如果不是,我的MainPageViewModel與View的子控件進行通信的理想方法是什麼?我試圖儘可能避免代碼隱藏文件中的代碼。似乎最好將邏輯放在ViewModel中以便於測試並將UI與邏輯分離。
(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)
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
}
}
由於提前, 傑里米
您的MainViewModel是否可以訪問您的播放器對象?如果是這樣,那麼Player對象上就不能有一個名爲MoveUp()的方法,那麼在KeyPressed事件中,你可以調用Player.MoveUp()?這樣,播放器移動的邏輯仍然在Player對象中。 – JSprang 2010-05-20 17:23:04
不,它沒有對Player對象的引用。它沒有提及任何XAML,這是我認爲MVVM應該如何工作的。有沒有一種方法可以將我的Player的XAML實例綁定到MainViewModel中的變量? – jturinetti 2010-05-21 15:29:34