Laden...
R
resper
myCSharp.de - Member
12
Themen
33
Beiträge
Letzte Aktivität
vor 7 Jahren
Dabei seit
15.02.2017
Alter
45
Herkunft
Kassel
Website
Erstellt vor 7 Jahren

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));
        }
    }
}
Erstellt vor 7 Jahren

Das erspart dann auch das string.Join.

Das String.Join fand ich ganz praktisch wegen dem eingebauten Seperator

Und ich würde das selbst implementieren komplett sein lassen, wenn es nicht der eigentliche Sinn ist das mit Attributen und Refelection zu lernen.


>
hat das alles schon implementiert incl. Schemaupdate und allem.

An dem Prinzip versuche ich mich zu orientieren. Aber so lerne ich am besten, wenn ich solche Funktionen nachbaue und versuche zu verstehen wie das funktioniert.

Erstellt vor 7 Jahren

Hallo gfoidl,

danke für die Anpassung des Titels und die Verschiebung ins richtige Forum.

Zu Punkt 2:
Ich habe das ganze mal mit einem StringBuilder umgesetzt, war es ungefähr das was du meintest:

private void createTable<T>()
{
    PropertyInfo[] props = typeof(T).GetProperties();

    string[] cols = new string[props.Count()];

    for(int i = 0; i < props.Count(); i++)
    {
        StringBuilder colString = new StringBuilder(String.Format("'{0}'", props[i].Name));
        var attrs = props[i].GetCustomAttributes(true);
        foreach (DbAttributes attr in attrs)
        {
            if (attr.IsInteger) colString.Append(" INTEGER");
            if (attr.IsText) colString.Append(" TEXT");
            if (attr.IsPrimary) colString.Append(" PRIMARY KEY");
            if (attr.IsAuto) colString.Append(" AUTOINCREMENT");
        }
        cols[i] = colString.ToString();
    }

    string createTable = String.Format("CREATE TABLE IF NOT EXISTS '{0}' ({1});", typeof(T).Name, String.Join(", ", cols));
    queryNon(createTable);
}

Zu Punkt 1 und 3:
Da muss ich wohl noch etwas Zeit investieren. Da mein Englisch nicht sehr gut ist, brauche ich für solche etwas komplexeren Themen immer etwas länger, weil ich die Artikel in der Regel mehrfach lesen muss. Werde ich mich die nächsten Tage dran setzten.

Erstellt vor 7 Jahren

Danke hat geklappt in Bezug auf PresentationFramework

Erstellt vor 7 Jahren

Hallo,

Leider ist mir für diesen Beitrag kein andere Titel eingefallen. Wie bereits aus meinen anderen Beiträgen ersichtlich beschäftige ich mich momentan mit der Integration von SQLlite in mein kleines Programm. Dazu bastel ich an eine Klasse für meine SQLite Operationen, die ich evtl. später auch für andere Projekte nutzen kann. Ähnlich wie bei der SQLite-net habe ich eine Methode, dass mir erlaubt aus Models Tabellen zu erstellen. Mich würde interessieren, wie die Profis unter Euch meine aktuelle Methode beurteilen und was ich evtl. verbessern könnte. Dabei geht es nicht direkt um die SQLite Funktion, der String der erzeugt wird macht als SQLite Befehl, das was er soll, sonder rein um den Weg zum String.

Meine Klasse für die Attribute:

class DbAttributes : Attribute
{
    public bool IsPrimary { get; set; }
    public bool IsAuto { get; set; }
    public bool IsInteger { get; set; }
    public bool IsText { get; set; }
}

Beispiel eines Models:

    class User
    {
        [DbAttributes(IsPrimary =true, IsAuto =true, IsInteger =true)]
        public long Id { get; set; }
        [DbAttributes(IsText =true)]
        public string Login { get; set; }
        [DbAttributes(IsText = true)]
        public string Firstname { get; set; }
        [DbAttributes(IsText = true)]
        public string Lastname { get; set; }
        [DbAttributes(IsText = true)]
        public string PersId { get; set; }
        [DbAttributes(IsText = true)]
        public string Password { get; set; }
        [DbAttributes(IsInteger =true)]
        public long Role { get; set; }
        [DbAttributes(IsInteger = true)]
        public long First { get; set; }
        [DbAttributes(IsInteger = true)]
        public long Active { get; set; }
    }

Meine Methode:

private void createTable<T>()
{
    PropertyInfo[] props = typeof(T).GetProperties();
    string[] cols = new string[props.Count()];
    for(int i = 0; i < props.Count(); i++)
    {
        string colString = String.Format("'{0}'", props[i].Name);
        var attrs = props[i].GetCustomAttributes(true);
        foreach (DbAttributes attr in attrs)
        {
            colString += (attr.IsInteger) ? " INTEGER" : "";
            colString += (attr.IsText) ? " TEXT" : "";
            colString += (attr.IsPrimary) ? " PRIMARY KEY" : "";
            colString += (attr.IsAuto) ? " AUTOINCREMENT" : "";
        }
        cols[i] = colString;
    }
    string createTable = String.Format("CREATE TABLE IF NOT EXISTS '{0}' ({1});", typeof(T).Name, String.Join(", ", cols));
            
    queryNon(createTable);
}
createTable<User>();

erzeugt dann folgenden String

CREATE TABLE IF NOT EXISTS 'User' ('Id' INTEGER PRIMARY KEY AUTOINCREMENT, 'Login' TEXT, 'Firstname' TEXT, 'Lastname' TEXT, 'PersId' TEXT, 'Password' TEXT, 'Role' INTEGER, 'First' INTEGER, 'Active' INTEGER);

Erstellt vor 7 Jahren

Danke für die Tipps. Ich werde weiter versuchen mich zu belesen.

Erstellt vor 7 Jahren

Unter Tools - Options - Environment - International Settings kannst du die Sprache umstellen.

Dort ist bereits English ausgewählt, wie gesagt die Oberfläche ist ja auch in Englisch nur komischerweise die Fehlermeldungen nicht.

Erstellt vor 7 Jahren

Hallo,

ich nutze VS 2017 Community, mein Windows System läuft auf Deutsch, VS habe ich in Englisch installiert. Jetzt zeigt er mir aber die Fehlermeldungen trotzdem in Deutsch an. Im Netzt gibt es für ältere Versionen von VS den Tipp die .net Language Pakete zu deinstallieren. Aber unter Windows 10 und VS 2017 gibt es die wohl nicht mehr. Jedenfalls weder unter Windows "Programme deinstallieren" noch im Setup von VS.

Dan bekomme ich bei Fehlern, scheinbar nur wenn es SQLite betrifft die Meldung:

No Symbols Loaded: PresentationFramework.pdb not included. Bekomme dann auch nicht die Stelle im Code angezeigt, die den Fehler verursacht.

Erstellt vor 7 Jahren

Also ich habe mich jetzt durch alle möglichen Beispiele gewühlt, die ich mit Hilfe von Google und den Suchbegriffen "c# wpf sqlite" gefunden habe und bin bisher kaum auf aussagekräftige Beispiele gestoßen, die sich stark von meinem zur Zeit verwendeten Code unterscheiden.

Wäre es evtl. möglich mir in Bezug auf "Verwende Dependency Injection und vermeide Magic Strings oder Hardcoded-Stuff wie DB-Namen." Beispiele in Bezug auf meinen Code aufzuzeigen?

Erstellt vor 7 Jahren

Ja, das ist schon sehr unelegant. Im Falle des Klartext-Passwortes sogar fahrlässig.

  • Schau Dir den Repository Pattern an.
  • Speicher Passwörter niemals im Klartext, sondern gesalzen (
    >
    )
  • Verwende Dependency Injection und vermeide Magic Strings oder Hardcoded-Stuff wie DB-Namen.
  • Erstelle Datenbanken besser mit Bibliotheken wie FluentMigrator.
  • Bei Sqlite würde ich auch Dapper als MicroORM empfehlen.

Passwörter: Meine MD5 Methode aus den Anwendungsbeispiel:

User login = sqlite.Login(Loginname, HelperClass.MD5Hash(Password));

versieht das Passwort mit einem Salt.

Der Rest der Punkte sind für mich ehrlich gesagt böhmische Dörfer 😉 Da werde ich mich wohl noch weiter einlesen müssen.