Daten aus Datenbank-Tabelle binden

  • WPF

Es gibt 12 Antworten in diesem Thema. Der letzte Beitrag () ist von Nofear23m.

    Daten aus Datenbank-Tabelle binden

    Hallo Leute,

    ich stehe noch ganz am Anfang mit WPF- führe mit grade das Tutorial von Sascha zu Gemüte.

    Sascha zeigt ja wie man mittels Klassen eine Sicht bauen kann, die eine Liste von "Kopf"-Informationen anzeigt und beim
    Auswahl eines Eintrags zusätzliche Detailinfos.

    Ich versuche Ähnliches mit Daten aus einer DB-Tabelle.

    Ausgangsglage:

    Ich habe eine SQL-Tabelle (MS SQL-Server) mit sehr vielen Spalten und möchte darauf zugreifen.

    Dazu sollen in einer Listbox 2-3 Spalten der Tabelle als Kopfinfo dargestellt werden.
    Außerdem soll es ein zweites Control (ich habe hier auch eine Listbox zum Testen genommen) darunter einige andere Spalten des aktuell gewählten Datensatzes in der Listbox angezeigen.

    Ich habe das nun mit einer DataTable versucht und der Listbox als DataContext meine Datatable zugewiesen:

    C#-Quellcode

    1. ListboxTestDaten.DataContext = Testdaten.DefaultView();


    Das funktioniert auch.

    Was ich partout nicht auf die Reihe bekomme, ist das abhängige Anzeigen der Detaildaten zu dem selektierten Element(en).

    Macht man das überhaupt mit Datatables? Vielleicht gibt es in WPF eine bessere / andere Lösung dafür wie man das macht (bspw. EF).
    Gruß Murdoc
    Hallo @Murdoc

    Da ich selbst noch nie mit DataTables unter WPF gearbeitet habe musste ich es selbst mal probieren. Ob es bessere Wege gibt weis ich jetzt nicht aber es funzt soweit mal.
    Probier es mal aus, ich hänge dir das Testprojekt hier mal an.

    Grüße
    Sascha
    Dateien
    • WpfApp1.zip

      (777,33 kB, 216 mal heruntergeladen, zuletzt: )
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Also ich hab das mit den anhängigen Details jetzt hinbekommen, allerdings glaube ich,
    dass ich weit an dem Standard wie man mit WPF + Binding richtig arbeitet vorbei schramme?

    C#-Quellcode

    1. public partial class MainWindow : Window
    2. {
    3. DataTable MainData;
    4. DataTable Selected = new DataTable();
    5. public MainWindow()
    6. {
    7. InitializeComponent();
    8. MainData = Helpers.GetDataAsDataTableFromSQLQuery("Data Source = <Server>; Initial Catalog = <DB>; User ID = <User>; Password = <Passphrase>", "Select Top 10 * from <Tabelle>");
    9. Selected = MainData.Clone();
    10. LBHeadData.ItemsSource = MainData.DefaultView;
    11. }
    12. private void LBHeadData_SelectionChanged(object sender, SelectionChangedEventArgs e)
    13. {
    14. Selected.Clear();
    15. foreach (DataRowView rw in LBHeadData.SelectedItems)
    16. {
    17. Selected.ImportRow(rw.Row);
    18. }
    19. LBDetailData.ItemsSource = Selected.DefaultView;
    20. }
    21. }


    XML-Quellcode

    1. <Window x:Class="WpfApp1.MainWindow"
    2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    5. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    6. xmlns:local="clr-namespace:WpfApp1"
    7. mc:Ignorable="d"
    8. Title="MainWindow" Height="450" Width="800">
    9. <Grid>
    10. <ListBox Name="LBHeadData" HorizontalAlignment="Left" Height="165" Margin="10,10,0,0" VerticalAlignment="Top" Width="516" SelectionChanged="LBHeadData_SelectionChanged">
    11. <ListBox.ItemTemplate>
    12. <DataTemplate>
    13. <TextBlock Text="{Binding <IrgendEineSpalte>}"></TextBlock>
    14. </DataTemplate>
    15. </ListBox.ItemTemplate>
    16. </ListBox>
    17. <ListBox Name="LBDetailData" HorizontalAlignment="Left" Height="149" Margin="22,211,0,0" VerticalAlignment="Top" Width="590">
    18. <ListBox.ItemTemplate>
    19. <DataTemplate>
    20. <TextBlock Text="{Binding <IrgendEineAndereSpalte>}"></TextBlock>
    21. </DataTemplate>
    22. </ListBox.ItemTemplate>
    23. </ListBox>
    24. </Grid>
    25. </Window>
    Gruß Murdoc
    Hallo

    Naja. Man muss immer sehen wofür man es benötigt. Da in der WPF so ziemlich alles über Binding funktioniert.
    Ich verwende z.b. keinerlei Dinge wie LBDetailData.ItemsSource = Selected.DefaultView;. Dies ist in der WPF schlichtweg der falsche weg, zumindest auf Dauer gesehen.
    Man sollte zusehen das man so schnell wie möglich mit Binding zurechtkommt, das hast du bestimmt auch bereits in meinen Tutorials mitbekommen.

    In der Beispielsolution welche ich dir angehängt habe siehst du auch das alles mittels Binding gelöst wurde. Auch weiter keine große Sache in diesem Beispiel.

    Zurück zu deiner Frage:

    In deinem Beispiel werden Daten nicht zur Laufzeit verändert. Soweit klappt das dann auch, aber weder eine DataTable noch eine DataRow oder eine DataColumn implementieren INotifyPropertyChanged welche die WPF benötigt um im Falle eines Bindings über Änderungen informiert zu werden. Insofern klappt es nur eine Zeit lang. Sobald du diese Mechanismen benötigst wirst du "anstehen".
    Das ist der Grund warum ich meist dazu rate alles schön in ViewModel Klassen zu packen und dann mit diesen zu arbeiten.

    Da ich nicht genau weis wie dein Programm aufgebaut ist oder was genau es machen soll kann ich dir schwer einen guten Rat geben wie du es besser machen könntest.
    Wenn eine Anwendung sehr Datenlastig ist (viele CRUD Operationen) dann empfehle ich meist EntityFramework da es sich dann auszahlt. Ansonsten eher per "Hand".

    Edit @Murdoc:

    Murdoc schrieb:

    Gibt es einen Grund- warum du im XAML für das Binding Row.ItemArray nimmst anstatt den Spaltennamen?

    Weil ich nicht wusste das es geht 8o
    Die WPF kann hier wohl Convertieren. Ich hatte mir die Eigenschaften von "DataRow" angesehen und kahm automatisch auf das Konstrukt. Tja, oft Hilft auch einfach probieren. *gg*

    PS: Bitte lass das Toteditieren von Beiträgen, jetzt weis niemand mehr warum ich die Antwort geschrieben habe. =O

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Hallo

    Murdoc schrieb:

    Was meinst du?

    Oh, sorry. Mein Fehler. Du hattest ja eine zweite Antwort erstellt und nicht die alte bearbeitet. Seit wann geht das in diesem Forum? Sonst musste man ne weile warten. Sorry, mein Fehler.

    Murdoc schrieb:

    Heißt das dein Beispiel funktioniert nicht, wenn Daten zur Laufzeit geändert werden?

    Nicht so wie es (für mich) sollte.

    Ändere mal die Textblöcke in meinem Beispiel auf TextBoxen und ändere den Wert. Du wirst sehen das sich hier nichts im DataGrid ändert. Weil die WPF es nicht mitbekommt. Wie auch.
    Schon in den ersten Kapiteln meine Tuts spreche ich darüber wie wichtig INotifyPropertyChanged ist, das bleibt es auch bei Daten aus einer DB. Leider.

    XML-Quellcode

    1. <StackPanel DockPanel.Dock="Bottom" DataContext="{Binding SelectedPerson}">
    2. <StackPanel Orientation="Horizontal">
    3. <TextBlock Text="{Binding FirstName}" FontWeight="Bold"/>
    4. <TextBlock Text="{Binding Row.ItemArray[1]}" FontWeight="Bold"/>
    5. </StackPanel>
    6. <TextBox Text="{Binding Row.ItemArray[2]}"/>
    7. <TextBox Text="{Binding Row.ItemArray[3]}"/>
    8. <TextBox Text="{Binding Row.ItemArray[4]}"/>
    9. </StackPanel>




    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Jaja, ich habs dann auch probiert wie du an dem Code oben sehen kannst. Cool. Wieder was gelernt. Wie gesagt, das erste mal DataTable. :thumbup:

    Grüße
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Jep.

    Ich kann dir nur leider nicht sagen ob du wieder irgendwo an Grenzen stoßt.
    Da musst du probieren.

    Aber vielleicht komme ich jetzt besser voran mit meinem Tutorial so das wir bald auch Datengetriebene Dinge durchgehen können.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Murdoc schrieb:

    Ich werd dein Tutorial weiter durchackern.

    Sehr lobenswert. Und versuche mit Binding zu arbeiten. Gaaanz wichtig.

    Schöne Grüße
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##