3

I want to use command to realize the KeyDown Event in textbox,

I wnat to let the command can recognize which key input such as KeyEventArgs do in KeyDown Event and do some other things,

So I want to pass command parameter into ReactiveCommand (just like Eventargs do in Event Method),

but I don't know how to do it.

I have WPF Xaml code :

<Window x:Class="NameSpaceTest.OpenFileW"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        xmlns:command="http://www.galasoft.ch/mvvmlight"
        Title="OpenFileWVieModel" Height="50" Width="200" WindowStyle="None">
    <Grid>
        <TextBox Name="Box" Text="{Binding OpenFPth, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="KeyDown">
                    <i:InvokeCommandAction Command="{Binding OpenFCmd}" CommandParameter=""/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </TextBox>
    </Grid>
</Window>

and two class code first is the view, second the viewmodel:

   public partial class OpenFileW : Window
    {
        OpenFileWVieModel OFVM  = new OpenFileWVieModel();
        public OpenFileW()
        {
            this.DataContext = OFVM;
            InitializeComponent();
        }
    }


    public class OpenFileWVieModel : ReactiveObject
    {
        public string OpenFPth { get { return _openFpth; } set { this.RaiseAndSetIfChanged(ref _openFpth, value); } }
        private string _openFpth;

        public IReactiveCommand OpenFCmd { get; set; }

        public OpenFileWVieModel()
        {
          var TextChange = this.WhenAny(
                    x => x.OpenFPth,
                x =>
                {
                    MessageBox.Show("HI");
                    return true;
                });

       OpenFCmd = ReactiveCommand.CreateAsyncTask(
        TextChange,  //CanExecute
         async _ =>//Execute
         {
             MessageBox.Show("HI");
         }
           );

        }
    }

What to do next to pass the textbox KeyInput as parameter to the command?

yu yang Jian
  • 6,680
  • 7
  • 55
  • 80

2 Answers2

0

You can pass the Text box it self or just the text. I don't know what you want to do with it, but if you have to interact with the textbox then I would suggest to pass the text box it self:

Passing the text:

<i:Interaction.Triggers>
   <i:EventTrigger EventName="KeyDown">
     <i:InvokeCommandAction Command="{Binding OpenFCmd}" 
        CommandParameter="{Binding ElementName=Box, Path=Text}" />
   </i:EventTrigger>
</i:Interaction.Triggers>

Passing the textBox:

<i:Interaction.Triggers>
   <i:EventTrigger EventName="KeyDown">
     <i:InvokeCommandAction Command="{Binding OpenFCmd}" 
        CommandParameter="{Binding ElementName=Box}" />
   </i:EventTrigger>
</i:Interaction.Triggers>

Edit:

Whit the above code you can create an eventhandler in your code:

void OpenFCmn_OnClick(object obj)
    {
        var tb = (TextBox) obj;

        tb.KeyDown += TbOnKeyDown;

    }

    private void TbOnKeyDown(object sender, KeyEventArgs keyEventArgs)
    {
        MessageBox.Show(keyEventArgs.Key.ToString());
        keyEventArgs.Handled = true;

    }
Nawed Nabi Zada
  • 2,819
  • 5
  • 29
  • 40
  • sorry I haven't really know how to create EventHandler and its uasge yet, I do some research then reply you later.. – yu yang Jian Feb 02 '16 at 09:35
  • but if write CommandParameter="{Binding ElementName=Box}", who will receive this textbox, is the ViewModel receive it? and how to make the connection to receive this pass? And keep the view and viewmodel seperated, viewmodel doesn't know about the view at the same time – yu yang Jian Feb 02 '16 at 09:40
  • 1
    Yes your view model will get it as parameter. But now I don't know what IReactiveCommand is, if it's just an implementation of ICommand, then you have Action as Execute. And that object will be your TextBox – Nawed Nabi Zada Feb 02 '16 at 10:00
  • @NawedNabiZada -1, Your solution will not work unless the user clicks the textbox. – Sivasubramanian Feb 02 '16 at 12:10
  • @Sivasubramanian. Lol, what do you mean ? You have to type something in the textbox. It has nothing to do clicking. – Nawed Nabi Zada Feb 02 '16 at 12:15
  • On what action the method "OpenFCmn_OnClick" get called ?? – Sivasubramanian Feb 02 '16 at 12:21
  • @Sivasubramanian As you can see on my comment it's bound to the Execute action of ICommand. So again I don't know what IReactiveCommand is, but if you implement this with ICommand, then it works perfectly. – Nawed Nabi Zada Feb 02 '16 at 12:27
  • @NawedNabiZada On what action the method "OpenFCmn_OnClick" get called ?? – Sivasubramanian Feb 02 '16 at 12:43
  • 1
    @Sivasubramanian, Not sure if you know what I mean, but it's the action of the Command, OpenFCmd. If still in doubt see this link: http://www.codeproject.com/Articles/126249/MVVM-Pattern-in-WPF-A-Simple-Tutorial-for-Absolute Check the ViewModel part – Nawed Nabi Zada Feb 02 '16 at 12:55
0

Bind the KeyDown event to the view model's command and set PassEventArgsToCommand="True" this will pass the KeyDown event's arguments to your command.

<TextBox  VerticalAlignment="Top" Width="120">
     <i:Interaction.Triggers>
           <i:EventTrigger EventName="KeyDown">
                  <GalaSoft_MvvmLight_Command:EventToCommand Command="{Binding KeyDownCommand}" PassEventArgsToCommand="True" />
           </i:EventTrigger>
     </i:Interaction.Triggers>
</TextBox>
Sivasubramanian
  • 935
  • 7
  • 22