Laden...

Wie kann ich ein KeyDown-Event in UserControl in einem MVVM Projekt hinzufügen?

Erstellt von resper vor 6 Jahren Letzter Beitrag vor 6 Jahren 1.878 Views
R
resper Themenstarter:in
33 Beiträge seit 2017
vor 6 Jahren
Wie kann ich ein KeyDown-Event in UserControl in einem MVVM Projekt hinzufügen?

Hallo,

ich möchte gerne die Eingabe eines Barcode-Scanner erfassen (USB Modus, läuft als Tastatur Eingabe).

Das ganze soll in einem ContentControl Bereich stattfinden. Zum Testen habe ich mir jetzt eine ganze einfache Version gebaut (siehe unten).

Wie bekomme ich es jetzt hin, dem UserControl einen KeyDown Event hinzuzufügen?
Der Scanner sendet ja wie eine Tastatur jedes Zeichen als Tastenanschlag und zum Schluss ein Enter. Ich möchte nun jedes Zeichen erfassen und prüfen ob es ein Enter ist oder nicht. Wenn nicht, dann soll das Zeichen einem String hinzugefügt werden, wenn es ein Enter ist, soll der String verarbeitet werden.

Ich möchte keine TextBox oder ähnliches nutzen.

Wie das ganze funktioniert, wenn ich kein MVVM Konzept nutze, habe ich ja gefunden aber mit MVVM bekomme ich es nicht hin.

MainWindow.xaml

<Window x:Class="resperLaMa.MainWindow"
        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:local="clr-namespace:resperLaMa"
        xmlns:local1="clr-namespace:resperLaMa.Pages"
        xmlns:local2="clr-namespace:resperLaMa.ViewModels"
        mc:Ignorable="d"
        Title="Test" 
        WindowStartupLocation="CenterScreen" WindowState="Maximized">
    <Window.Resources>
        <DataTemplate DataType="{x:Type local2:BarcodeViewModel}">
            <local1:Barcode/>
        </DataTemplate>
    </Window.Resources>
    <DockPanel LastChildFill="True">
        <ContentControl x:Name="Pages" DockPanel.Dock="Right" Content="{Binding SelectedViewModel}"/>
    </DockPanel>
</Window>

MainWindow.cs

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = new MainWindowViewModel();
        }
    }

MainWindowViewModel.cs


namespace resperLaMa.ViewModels
{
    class MainWindowViewModel : BaseViewModel
    {
        private object selectedViewModel;
        public object SelectedViewModel
        {
            get { return selectedViewModel; }
            set
            {
                selectedViewModel = value;
                OnPropertyChanged("SelectedViewModel");
            }
        }

        public MainWindowViewModel()
        {
            SelectedViewModel = new BarcodeViewModel();
        }
    }
}

Barcode.xaml:

<UserControl x:Class="resperLaMa.Pages.Barcode"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:resperLaMa.Pages"
             mc:Ignorable="d">
    <StackPanel>
        <Label Content="Bitte Code scannen" />
    </StackPanel>
</UserControl>

BarcodeViewModel.cs:


namespace resperLaMa.ViewModels
{
    class BarcodeViewModel : BaseViewModel
    {
        public BarcodeViewModel ()
        {
        }
    }
}

BaseViewModel:

namespace resperLaMa.ViewModels
{
    public abstract class BaseViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
4.939 Beiträge seit 2008
vor 6 Jahren

Hallo,

um vom UserControl aus an das (Preview)KeyDown zu kommen, mußt du zwingend "Focusable" setzen, s.a. How can I capture KeyDown event on a WPF Page or UserControl object?.

Wenn du das Ereignis dann weiterleiten willst, dann könntest du in deinem ViewModel ein ICommand bereitstellen: s. z.B. Basic MVVM and ICommand Usage Example (statt dem RelayCommand kannst du auch z.B. ein DelegateCommand benutzen).