Benutzer mit den meisten Antworten
Daten von Access Tabelle in TextBox anzeigen lassen - WPF MVVM

Frage
-
Hallo,
nehmen wir mal an meine Tabelle in Access sieht so aus:
Spalte 1 - int (Primärschlüssel) : 1 , 2 , 3 , 4, 5
Spalte 2 - sring : lukas, matthias, norbert, dieter, matze
Spalte 3 - sring : müller, herbert, schölli, mustermann, friedrich
Ich will dass wenn ich in meinem Programm (WPF Applikation) zum Beispiel die "1" eingebe, anschliessend in einer textBox Lukas Müller ausgegeben wird.
Ich weiss, dass es über ein DataGrid funktioniert, aber ich will das mir auf direktem Wege anzeigen lassen.
Kann mir jemand bitte helfen? ^^
Danke im Voraus
- Bearbeitet michad2151 Montag, 29. Oktober 2018 08:50
Antworten
-
Hi Micha,
hier mal eine Demo für einen der möglichen Lösungswege.XAML:
<Window x:Class="WpfApp1.Window61" 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:WpfApp1" mc:Ignorable="d" Title="Window61" Height="450" Width="800"> <Window.Resources> <local:Window61VM x:Key="vm"/> </Window.Resources> <Grid DataContext="{StaticResource vm}"> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <ListBox ItemsSource="{Binding View}" DisplayMemberPath="Info"/> <Grid Grid.Column="1" DataContext="{Binding Detail}"> <Grid.Resources> <Style TargetType="Label"> <Setter Property="HorizontalAlignment" Value="Right"/> </Style> </Grid.Resources> <Grid.RowDefinitions> <RowDefinition Height="auto"/> <RowDefinition Height="auto"/> <RowDefinition Height="auto"/> <RowDefinition Height="auto"/> <RowDefinition Height="auto"/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="auto"/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Label Content="Detail" Grid.ColumnSpan="2" HorizontalAlignment="Center"/> <Label Content="ID" Grid.Row="1"/> <Label Content="{Binding ID}" Grid.Row="1" Grid.Column="1"/> <Label Content="Info" Grid.Row="2"/> <TextBox Text="{Binding Info}" Grid.Row="2" Grid.Column="1"/> </Grid> <StackPanel Grid.Column="1" Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right"> <StackPanel.Resources> <Style TargetType="Button"> <Setter Property="Margin" Value="5"/> </Style> </StackPanel.Resources> <Button Content="Laden" Command="{Binding Cmd}" CommandParameter="load"/> <Button Content="Hinzufügen" Command="{Binding Cmd}" CommandParameter="new"/> <Button Content="Löschen" Command="{Binding Cmd}" CommandParameter="del"/> <Button Content="Speichern" Command="{Binding Cmd}" CommandParameter="save"/> </StackPanel> </Grid> </Window>
Dazu alle Klassen:
using System.ComponentModel; using System.Data; using System.Runtime.CompilerServices; using System.Windows; using System.Windows.Data; using System.Windows.Input; namespace WpfApp1 { public class Window61VM : INotifyPropertyChanged { // Model-Instanz beim Instanziieren des ViewModels erzeugen Window61Mod model = new Window61Mod(); // Quelle für die Sicht auf die Liste der Daten CollectionViewSource cvs = new CollectionViewSource(); // Sicht-Eigenschaft zur Bindung an die ListrBox public ICollectionView View { get => cvs.View; } /// <summary> /// Eigenschaft für Command-Bindung /// </summary> public ICommand Cmd { get { return new RelayCommand(CmdExec, CmdCanExec); } } /// <summary> /// Methode, die bei Command-Auslösung abgearbeitet wird /// </summary> /// <param name="obj">CommandParameter</param> private void CmdExec(object obj) { switch (obj.ToString()) { case "load": cvs.Source = model.GetData(); cvs.View.CurrentChanged += (o, ev) => { Detail = cvs.View.CurrentItem; OnPropertyChanged(nameof(Detail)); }; OnPropertyChanged(nameof(View)); OnPropertyChanged(nameof(Cmd)); break; case "new": Detail = model.InsertNewRow(); OnPropertyChanged(nameof(Detail)); break; case "del": model.DeleteRow(Detail); break; case "save": model.Save(); object det = Detail; Detail = null; OnPropertyChanged(nameof(Detail)); Detail = det; OnPropertyChanged(nameof(Detail)); OnPropertyChanged(nameof(View)); break; default: break; } } private bool CmdCanExec(object obj) { switch (obj.ToString()) { case "load": return true; case "new": case "del": case "save": return cvs.Source != null; default: break; } return true; } public object Detail { get; set; } #region OnPropertyChanged public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged([CallerMemberName] string propName = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName)); #endregion } public class Window61Mod { private Window61DataSet.Window61DBTab1DataTable dt = new Window61DataSet.Window61DBTab1DataTable(); internal DataTable GetData() { using (Window61DataSetTableAdapters.Window61DBTab1TableAdapter ta = new Window61DataSetTableAdapters.Window61DBTab1TableAdapter()) { ta.Fill(dt); } return dt; } internal DataRow InsertNewRow() { Window61DataSet.Window61DBTab1Row row = dt.NewWindow61DBTab1Row(); row.Info = "neu"; dt.Rows.Add(row); return row; } internal void DeleteRow(object detail) { DataRowView drv = detail as DataRowView; if (drv == null) { DataRow r = detail as DataRow; r?.Delete(); } else drv.Row.Delete(); } internal void Save() { using (Window61DataSetTableAdapters.Window61DBTab1TableAdapter ta = new Window61DataSetTableAdapters.Window61DBTab1TableAdapter()) { ta.Adapter.RowUpdated += (object sender, System.Data.OleDb.OleDbRowUpdatedEventArgs e) => { if (e.StatementType == StatementType.Insert) { int newID = 0; System.Data.OleDb.OleDbCommand idCmd = new System.Data.OleDb.OleDbCommand("SELECT @@IDENTITY", e.Command.Connection); newID = (int)(idCmd.ExecuteScalar()); foreach (DataColumn col in e.Row.Table.Columns) { if (col.AutoIncrement) { e.Row[col.ColumnName] = newID; return; } } } }; ta.Update(dt); } } } }
--
Viele Grüsse
Peter Fleischer (ehem. MVP für Developer Technologies)
Meine Homepage mit Tipps und Tricks- Als Antwort markiert michad2151 Donnerstag, 1. November 2018 06:51
Alle Antworten
-
Hi,
wo genau ist dein Problem? Generell beim lesen der Datenbank oder suchen/finden eines bestimmten Datensatzes?
Wenn du das MVVM Entwurfsmuster anwendest, werden die Daten deiner Datenbank üblicherweise vom Model bereitgestellt. Dieses kannst du erweitern, um mit Linq eine Abfrage zu erstellen, damit die von dir gewünschten Daten geliefert werden. Oder du filterst es im VM...
In Abhängigkeit deines Projekts, kannst du die Datenbank bei jedem zugriff lesen oder nur beim Start deiner Anwendung... Wie stellst du dem Viewmodel die Daten zur Verfügung (List, Collection...)?
Gruß
Freiberufler im Bereich Softwareentwicklung Von der PLC und Robotik zu VB.NET & C#, vorrangig WPF und UWP
-
Hallo Stefan,
generell bei allem :D.
Ich hab bereits Verbindung zur Access-Datei und reinschreiben geht auch aber beim lesen hab ich absolut keinen Ansatz und Ahnung wie das funktionieren soll.
Zu der Bereitstellung der Daten: Ich muss gestehen, dass ich noch nie mit nem richtigen Model gearbeitet habe. Das Verhältnis zwischen View und ViewModel klappt perfekt. Ich hab die Anwendung vom Model nie richtig verstanden, daher hab ich die die Daten immer direkt über den ViewModel verwaltet.
Ich kann deine Antwort schon fühlen, daher eigne ich mir erstmal den Model an haha.
Liebe Grüsse -
...daher hab ich die die Daten immer direkt über den ViewModel verwaltet.
Ich kann deine Antwort schon fühlen, daher eigne ich mir erstmal den Model an haha.
Ging mir am Anfang genauso. Ich habe mich auch erst schwer damit getan. Aber es lohnt sich, sich damit zu beschäftigen. Bin jetzt erst mal beschäftigt, später erstelle ich eine kleine Demo ...falls nicht jemand anderes hier schneller ist.
Gruß
Freiberufler im Bereich Softwareentwicklung Von der PLC und Robotik zu VB.NET & C#, vorrangig WPF und UWP
-
Hey Stefan,
okay, danke für den Tipp und für die kommende Demo <3. Ich bin jetzt denke mal ne Weile damit beschäftigt.
LG- Bearbeitet michad2151 Montag, 29. Oktober 2018 14:31
-
Hi Micha,
hier mal eine Demo für einen der möglichen Lösungswege.XAML:
<Window x:Class="WpfApp1.Window61" 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:WpfApp1" mc:Ignorable="d" Title="Window61" Height="450" Width="800"> <Window.Resources> <local:Window61VM x:Key="vm"/> </Window.Resources> <Grid DataContext="{StaticResource vm}"> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <ListBox ItemsSource="{Binding View}" DisplayMemberPath="Info"/> <Grid Grid.Column="1" DataContext="{Binding Detail}"> <Grid.Resources> <Style TargetType="Label"> <Setter Property="HorizontalAlignment" Value="Right"/> </Style> </Grid.Resources> <Grid.RowDefinitions> <RowDefinition Height="auto"/> <RowDefinition Height="auto"/> <RowDefinition Height="auto"/> <RowDefinition Height="auto"/> <RowDefinition Height="auto"/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="auto"/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Label Content="Detail" Grid.ColumnSpan="2" HorizontalAlignment="Center"/> <Label Content="ID" Grid.Row="1"/> <Label Content="{Binding ID}" Grid.Row="1" Grid.Column="1"/> <Label Content="Info" Grid.Row="2"/> <TextBox Text="{Binding Info}" Grid.Row="2" Grid.Column="1"/> </Grid> <StackPanel Grid.Column="1" Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right"> <StackPanel.Resources> <Style TargetType="Button"> <Setter Property="Margin" Value="5"/> </Style> </StackPanel.Resources> <Button Content="Laden" Command="{Binding Cmd}" CommandParameter="load"/> <Button Content="Hinzufügen" Command="{Binding Cmd}" CommandParameter="new"/> <Button Content="Löschen" Command="{Binding Cmd}" CommandParameter="del"/> <Button Content="Speichern" Command="{Binding Cmd}" CommandParameter="save"/> </StackPanel> </Grid> </Window>
Dazu alle Klassen:
using System.ComponentModel; using System.Data; using System.Runtime.CompilerServices; using System.Windows; using System.Windows.Data; using System.Windows.Input; namespace WpfApp1 { public class Window61VM : INotifyPropertyChanged { // Model-Instanz beim Instanziieren des ViewModels erzeugen Window61Mod model = new Window61Mod(); // Quelle für die Sicht auf die Liste der Daten CollectionViewSource cvs = new CollectionViewSource(); // Sicht-Eigenschaft zur Bindung an die ListrBox public ICollectionView View { get => cvs.View; } /// <summary> /// Eigenschaft für Command-Bindung /// </summary> public ICommand Cmd { get { return new RelayCommand(CmdExec, CmdCanExec); } } /// <summary> /// Methode, die bei Command-Auslösung abgearbeitet wird /// </summary> /// <param name="obj">CommandParameter</param> private void CmdExec(object obj) { switch (obj.ToString()) { case "load": cvs.Source = model.GetData(); cvs.View.CurrentChanged += (o, ev) => { Detail = cvs.View.CurrentItem; OnPropertyChanged(nameof(Detail)); }; OnPropertyChanged(nameof(View)); OnPropertyChanged(nameof(Cmd)); break; case "new": Detail = model.InsertNewRow(); OnPropertyChanged(nameof(Detail)); break; case "del": model.DeleteRow(Detail); break; case "save": model.Save(); object det = Detail; Detail = null; OnPropertyChanged(nameof(Detail)); Detail = det; OnPropertyChanged(nameof(Detail)); OnPropertyChanged(nameof(View)); break; default: break; } } private bool CmdCanExec(object obj) { switch (obj.ToString()) { case "load": return true; case "new": case "del": case "save": return cvs.Source != null; default: break; } return true; } public object Detail { get; set; } #region OnPropertyChanged public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged([CallerMemberName] string propName = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName)); #endregion } public class Window61Mod { private Window61DataSet.Window61DBTab1DataTable dt = new Window61DataSet.Window61DBTab1DataTable(); internal DataTable GetData() { using (Window61DataSetTableAdapters.Window61DBTab1TableAdapter ta = new Window61DataSetTableAdapters.Window61DBTab1TableAdapter()) { ta.Fill(dt); } return dt; } internal DataRow InsertNewRow() { Window61DataSet.Window61DBTab1Row row = dt.NewWindow61DBTab1Row(); row.Info = "neu"; dt.Rows.Add(row); return row; } internal void DeleteRow(object detail) { DataRowView drv = detail as DataRowView; if (drv == null) { DataRow r = detail as DataRow; r?.Delete(); } else drv.Row.Delete(); } internal void Save() { using (Window61DataSetTableAdapters.Window61DBTab1TableAdapter ta = new Window61DataSetTableAdapters.Window61DBTab1TableAdapter()) { ta.Adapter.RowUpdated += (object sender, System.Data.OleDb.OleDbRowUpdatedEventArgs e) => { if (e.StatementType == StatementType.Insert) { int newID = 0; System.Data.OleDb.OleDbCommand idCmd = new System.Data.OleDb.OleDbCommand("SELECT @@IDENTITY", e.Command.Connection); newID = (int)(idCmd.ExecuteScalar()); foreach (DataColumn col in e.Row.Table.Columns) { if (col.AutoIncrement) { e.Row[col.ColumnName] = newID; return; } } } }; ta.Update(dt); } } } }
--
Viele Grüsse
Peter Fleischer (ehem. MVP für Developer Technologies)
Meine Homepage mit Tipps und Tricks- Als Antwort markiert michad2151 Donnerstag, 1. November 2018 06:51