Я пытаюсь создать демонстрационную игру в Silverlight 4 с помощью шаблона разработки MVVM для расширения моего знания. Я использую инструментарий MvvmLight Laurent Bugnion также (найденный здесь: http://mvvmlight.codeplex.com/). Все, что я хочу сделать прямо сейчас, перемещают форму в Холсте путем нажатия определенных клавиш. Мое решение содержит Player.xaml (просто прямоугольник; это будет перемещено), и MainPage.xaml (Холст и экземпляр управления Плеера).
К моему пониманию Silverlight не поддерживает направленные события туннелирования, только пузырение. Моя большая проблема состоит в том, что Player.xaml никогда не распознает событие KeyDown. Это всегда прерывается MainPage.xaml сначала, и это никогда не достигает никаких дочерних элементов управления, потому что это пузырится вверх. Я предпочел бы, чтобы логика для перемещения Плеера была в классе PlayerViewModel, но я не думаю, что Игрок может знать о любых событиях KeyDown, стреляющих без меня явно передача их вниз от MainPage.
Я закончил тем, что добавил логику обработчика к классу MainPageViewModel. Теперь моя проблема состоит в том, что MainPageViewModel не знает о Player.xaml, таким образом, он не может переместить этот объект при обработке событий KeyDown. Я предполагаю, что это ожидается, поскольку ViewModels не должен иметь никакого знания их связанных Представлений.
В не столько слов... является там способом, которым этот пользовательский элемент управления Плеера в моем MainPage.xaml может непосредственно принять и обработать события KeyDown? В противном случае, каков идеальный метод для моего MainPageViewModel для общения с дочерними элементами управления его Представления? Я пытаюсь не допустить код в код - позади файлов как можно больше. Походит лучше помещать логику в ViewModels для простоты тестирования и отделять UI от логики.
(MainPage.xaml)
(MainViewModel.cs)
public MainViewModel()
{
KeyPressCommand = new RelayCommand(KeyPressed);
}
public RelayCommand 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
}
}
Заранее спасибо, Jeremy
Вместо использования EventTrigger попробуйте использовать KeyTrigger и установить для объекта Source значение LayoutRoot.
Другой вариант (который, как мне кажется, лучше) - позволить ViewModel обрабатывать позицию игрока. Например, есть свойство с именем PlayerTop и свойство с именем PlayerLeft. Привяжите к ним свойства Canvas.Top и Canvas.Left игрока. Когда пользователь нажимает клавиши, на виртуальной машине выполняется команда, которая обновляет эти свойства. Таким образом, виртуальной машине не нужно знать, что перемещается или как перемещается.
Есть ли в этом смысл?