locked
Keydown event from Barcode scanner in a MVVM pattern RRS feed

  • Question

  • My application accepts input into a textbox from Barcode scanner.  I need to capture the Keydown event that comes in the input. 

    I was able to do this using a code behind pattern. But I have switched the application to MVVM and need to capture the KeyDown event and "Submit" when the TextBox is populated from the barcode scanner. 

    Friday, May 6, 2016 2:22 PM

Answers

  • Events which will only do view stuff, yes I'd say they're 100% OK.

    Click a button and show a window is view responsibility so you don't need to do anything in any viewmodel. That would be OK.

    When they do viewmodel stuff I think that's less fine.

    My opinion is that handling an event in the view and invoking a method in the viewmodel is in a sort of a grey area. If you have to then it's not the end of the world. Just don't make it your first choice.

    I would prefer an interaction trigger to handling an event, casting the viewmodel from the datacontext and invoking a method on that.

    I mean like:

        <i:Interaction.Triggers>
            <i:EventTrigger EventName="KeyDown">
                <i:InvokeCommandAction Command="{Binding Path=SomeCommand, Mode=OneWay}"/>
            </i:EventTrigger>
        </i:Interaction.Triggers>

    The View doesn't need to "know" the type of the viewmodel and if that vm isn't there in the datacontext for some reason then it will not error.

    .

    If all you're looking for is to act when you have 11 characters scanned then you don't need that and you don't need to handle any event in the view because you will already have bound that text property.

    It doesn't make any sense to involve any other mechanism as well.

    Assuming I have understood what's going on here.


    Hope that helps.

    Technet articles: WPF: Layout Lab; All my Technet Articles

    • Proposed as answer by DotNet Wang Monday, May 23, 2016 9:40 AM
    • Marked as answer by Xavier Xie-MSFT Tuesday, May 24, 2016 11:23 AM
    Friday, May 6, 2016 6:16 PM
  • >>But I have switched the application to MVVM and need to capture the KeyDown event and "Submit" when the TextBox is populated from the barcode scanner.

    You could use Expression Blend interaction triggers to associate an event with a command property of the view model that will be invoked whenever the event fires. Please refer to my blog post for more information about this: https://blog.magnusmontin.net/2013/06/30/handling-events-in-an-mvvm-wpf-application/.

    You will need to add a reference to System.Windows.Interactivity.dll which can be downloaded from NuGet: https://www.nuget.org/packages/System.Windows.Interactivity.WPF/

    ...or the Blend SDK: https://www.microsoft.com/en-us/download/details.aspx?id=10801

    <YourControl... Width="100" Height="100" xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="KeyDown" >
                        <i:InvokeCommandAction Command="{Binding YourCommand}" />
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </YourControl>


    Hope that helps.

    Please remember to close your threads by marking helpful posts as answer and then start a new thread if you have a new question. Please don't ask several questions in the same thread.

    • Proposed as answer by DotNet Wang Monday, May 23, 2016 9:40 AM
    • Marked as answer by Xavier Xie-MSFT Tuesday, May 24, 2016 11:23 AM
    Saturday, May 7, 2016 8:53 AM

All replies

  • Make your binding 

            <TextBox Name="Barcode"
                     Text="{Binding SomeTextProperty
                , UpdateSourceTrigger=PropertyChanged}"

    And the setter of the bound property ( in the viewmodel ) will be invoked as each character arrives in the textbox.

    You can drive your logic from there.


    Hope that helps.

    Technet articles: WPF: Layout Lab; All my Technet Articles

    Friday, May 6, 2016 2:36 PM
  • Also it's perfectly fine to have "code behind" in MVVM, it just should be View code, not ViewModel code.  IE it should communicate between the view's controls and some method on the ViewModel.

    David


    David http://blogs.msdn.com/b/dbrowne/

    Friday, May 6, 2016 3:27 PM
  • Events which will only do view stuff, yes I'd say they're 100% OK.

    Click a button and show a window is view responsibility so you don't need to do anything in any viewmodel. That would be OK.

    When they do viewmodel stuff I think that's less fine.

    My opinion is that handling an event in the view and invoking a method in the viewmodel is in a sort of a grey area. If you have to then it's not the end of the world. Just don't make it your first choice.

    I would prefer an interaction trigger to handling an event, casting the viewmodel from the datacontext and invoking a method on that.

    I mean like:

        <i:Interaction.Triggers>
            <i:EventTrigger EventName="KeyDown">
                <i:InvokeCommandAction Command="{Binding Path=SomeCommand, Mode=OneWay}"/>
            </i:EventTrigger>
        </i:Interaction.Triggers>

    The View doesn't need to "know" the type of the viewmodel and if that vm isn't there in the datacontext for some reason then it will not error.

    .

    If all you're looking for is to act when you have 11 characters scanned then you don't need that and you don't need to handle any event in the view because you will already have bound that text property.

    It doesn't make any sense to involve any other mechanism as well.

    Assuming I have understood what's going on here.


    Hope that helps.

    Technet articles: WPF: Layout Lab; All my Technet Articles

    • Proposed as answer by DotNet Wang Monday, May 23, 2016 9:40 AM
    • Marked as answer by Xavier Xie-MSFT Tuesday, May 24, 2016 11:23 AM
    Friday, May 6, 2016 6:16 PM
  • >>But I have switched the application to MVVM and need to capture the KeyDown event and "Submit" when the TextBox is populated from the barcode scanner.

    You could use Expression Blend interaction triggers to associate an event with a command property of the view model that will be invoked whenever the event fires. Please refer to my blog post for more information about this: https://blog.magnusmontin.net/2013/06/30/handling-events-in-an-mvvm-wpf-application/.

    You will need to add a reference to System.Windows.Interactivity.dll which can be downloaded from NuGet: https://www.nuget.org/packages/System.Windows.Interactivity.WPF/

    ...or the Blend SDK: https://www.microsoft.com/en-us/download/details.aspx?id=10801

    <YourControl... Width="100" Height="100" xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="KeyDown" >
                        <i:InvokeCommandAction Command="{Binding YourCommand}" />
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </YourControl>


    Hope that helps.

    Please remember to close your threads by marking helpful posts as answer and then start a new thread if you have a new question. Please don't ask several questions in the same thread.

    • Proposed as answer by DotNet Wang Monday, May 23, 2016 9:40 AM
    • Marked as answer by Xavier Xie-MSFT Tuesday, May 24, 2016 11:23 AM
    Saturday, May 7, 2016 8:53 AM