添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
留胡子的鼠标  ·  spark ...·  2 年前    · 
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I would like to use ICommand to change the Paddle1.Y int value of my ViewModel. Am I supposed to create a class implementing ICommand interface? I have done that. But since it is a class, it doesn't have access to my ViewModel's Paddle1 property without creating a property for it. I would prefer to create the command within my ViewModel for this reason. At this point I'm trying to pass the Paddle1 to the Command as a CommandParameter in XAML. I am failing at this, and I'm not sure it is the cleanest approach to editing the state of my ViewModel either.

Could I get a code example of my UpKeyPressed command being bound to either a button or the keyboard up key? With no CommandParameter would be more clean, if the command could access my ViewModel Paddle1 property.

My ViewModel:

namespace Pong.Core.ViewModels
    public class GamePlayViewModel
        private readonly Paddle Paddle1;
        private Paddle Paddle2;
        public GamePlayViewModel()
            Paddle1 = new Paddle();
            Paddle2 = new Paddle();
            UpKeyPressed();
        public ICommand UpKeyPressed()
            var r = new UpKeyPressed();
            r.Execute(Paddle1);
            return r;
    public class UpKeyPressed : ICommand
        public void Execute(object parameter)
            var paddle = parameter as Paddle;
            Debug.Assert(paddle != null, "paddle != null");
            paddle.IncreaseY();
            Debug.WriteLine(paddle.Y);
        public bool CanExecute(object parameter)
            return parameter != null;
        public event EventHandler CanExecuteChanged;

My XAML page that uses the viewmodel as a dataContext:

<Window x:Class="Pong.Windows.Views.GamePlayView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:Pong.Core.ViewModels;assembly=Pong.Core"
        Title="GamePlayView" Height="350" Width="525">
        <Button CommandParameter="{Binding ElementName=Paddle1}" 
                Command="{StaticResource UpKeyPressed}"  >
            Click
        </Button>
    </Grid>
    <Window.DataContext>
        <local:GamePlayViewModel/>
    </Window.DataContext>
    <Window.InputBindings>
        <KeyBinding Command="{Binding Path=UpKeyPressed}" 
                Key="O" 
                Modifiers="Control"/>
    </Window.InputBindings>
</Window>

Data structure of my solution

My attempt to fix:

    namespace Pong.Core.ViewModels
    public class GamePlayViewModel
        private readonly Paddle Paddle1;
        private Paddle Paddle2;
        private ICommand _doSomething;
        public ICommand DoSomethingCommand
                if (_doSomething == null)
                    _doSomething = new UpKeyPressed(Paddle1);
                return _doSomething;
        public GamePlayViewModel()
            Paddle1 = new Paddle();
            Paddle2 = new Paddle();
    public class UpKeyPressed : ICommand
        private Paddle Paddle1;
        public UpKeyPressed(Paddle paddle)
            Paddle1 = paddle;
        public void Execute(object parameter)
            //var paddle = parameter as Paddle;
            //Debug.Assert(paddle != null, "paddle != null");
            //paddle.IncreaseY();
            Paddle1.IncreaseY();
            //Debug.WriteLine(paddle.Y);
            Debug.WriteLine(Paddle1.Y);
        public bool CanExecute(object parameter)
            return Paddle1 != null;
        public event EventHandler CanExecuteChanged;

XAML attempt (no errors but not workling upon pressing the 'O' key):

<Window x:Class="Pong.Windows.Views.GamePlayView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:viewModels="clr-namespace:Pong.Core.ViewModels;assembly=Pong.Core"
    Title="GamePlayView" Height="350" Width="525">
</Grid>
<Window.DataContext>
    <viewModels:GamePlayViewModel/>
</Window.DataContext>
<Window.InputBindings>
    <KeyBinding Command="{Binding DoSomethingCommand}" 
        Key="O" 
        Modifiers="Control"/>
</Window.InputBindings>
                you have just 1 method UpKeyPressed in your view-model, it cannot be used for binding. You need to declare a property. Also the UpKeyPressed command should have some property accepting your Paddle1, and you need to set that property at the time initializing the command in your view-model class.
– King King
                Oct 13, 2015 at 2:14
                @KingKing Do you mean I create a property in my ViewModel of type UpKeyPressed and I create a property in my UpKeyPressed class called Paddle1 and I give the class a constructor which sets the Paddle1 property?
– Ben
                Oct 13, 2015 at 2:47
                something like that but you should set the Paddle1 property right after init your command (normally in the getter of the UpKeyPressed property)
– King King
                Oct 13, 2015 at 2:52
                @KingKing I have attempted to fix and pasted it into the question. Not working yet. Cheers.
– Ben
                Oct 13, 2015 at 3:11

Looked at your attempt, there are some things we need to be fix, first your CanExecute should not involve the parameter anymore:

public bool CanExecute(object parameter) {
   return Paddle1 != null;

Secondly your XAML binding is wrong, you already have DataContext of your view-model flown in your visual tree, you just need a simple Binding with some Path specified like this:

<KeyBinding Command="{Binding DoSomethingCommand}" 
            Key="O" 
            Modifiers="Control"/>
                Thanks. I have a break point in the execute method of the UpKeyPressed class and it still doesn't fire when the "o" key is pressed. There is no error displaying.
– Ben
                Oct 13, 2015 at 3:32
                @Ben I've just tested it and confirm that it should work. Do you have any DataContext set to something different in code behind?
– King King
                Oct 13, 2015 at 3:48
                This is my codebehind:  public partial class GamePlayView : Window     {         public GamePlayView()         {             InitializeComponent();             DataContext = new GamePlayViewModel();         }     }
– Ben
                Oct 13, 2015 at 3:55
                Can you see in the Output window to check if there is any exception thrown silently there?
– King King
                Oct 13, 2015 at 3:58
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.