Laden...

[WPF MVVM] Bei Button Click anzeigen des Datenbankinhaltes in DataGrid

Erstellt von SyntaxTalksToMe vor 5 Jahren Letzter Beitrag vor 5 Jahren 2.586 Views
S
SyntaxTalksToMe Themenstarter:in
17 Beiträge seit 2017
vor 5 Jahren
[WPF MVVM] Bei Button Click anzeigen des Datenbankinhaltes in DataGrid

verwendetes Datenbanksystem: <SQL>

Guten Abend,

ich hatte vor kurzen einen Thread aufgemacht, wo es um die Vorgehensweise einer bestimmten Sache ging. ich habe mich an die Ratschläge gehalten und mir in den letzten Tagen/Wochen das MVVM Prinzip angeeignet. Es tun sich aber aber hier und da noch ein paar Fragen auf.

Es geht darum:

Jetzt würde ich gerne per ButtonClick eine den Inhalt in ein DataGrid laden.

Mein Code sieht dabei folgendermaßen aus:

Model:


        //Load Table
        public DataView LoadTable()
        {
            // Verbindungspfad zum Server inkl Daten
            string constring = "Server=server; Database=db; PORT=0000; Uid=user; Pwd=pw;";

            MySqlConnection con = new MySqlConnection(constring);

            MySqlCommand cmdDataBase = new MySqlCommand("select * from KeyDataBase;", con);

            MySqlDataAdapter sda = new MySqlDataAdapter();
            sda.SelectCommand = cmdDataBase;

            DataTable dt = new DataTable("KeyDataBase");
            sda.Fill(dt);

            DataView dv = new DataView();
            dv.Table = dt;

            sda.Update(dt);

            con.Close();

            return dv;
            //view.ItemsSource = dv;   

View Model:


 public DataGrid dg = new DataGrid();

        //Methode mit Rückgabewert zum ausgeben der Datentabelle
        public void LadeTabelle(object obj)
        {
            //ModelKlasse
            Datenbank datenQuelle = new Datenbank();

            dg.ItemsSource = datenQuelle.LoadTable();

        }



        <DataGrid x:Name="meinGrid" HorizontalAlignment="Left" Height="257" Margin="421,310,0,0" VerticalAlignment="Top" Width="597" ItemsSource="{Binding Path=dv, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Grid.ColumnSpan="2" FontSize="14" FontFamily="Arial" Background="#FFFAFAFA"/>


        <Button Content="Load Table" HorizontalAlignment="Left" Height="63" Margin="256,644,0,0" VerticalAlignment="Top" Width="120" Click="Button_Click" Command="{Binding LoadTable,  Mode=TwoWay}"/>


Man kann bestimmt noch einiges besser machen. Aber die Frage ist, warum es nicht klappt. Ich habe andere Methoden, die funktionieren. Der Knackpunkt ist das senden der Daten an das Grid. Ich hatte ein paar Trockenübungen gemacht und das gemacht:


     //Datenbank bank = new Datenbank();
            //meinGrid.ItemsSource = bank.LoadTable();

Da hats auch funktioniert.

Ich hab mir das so vorgestellt:Das Datagrid greift mittels Binding auf


public DataGrid dg = new DataGrid();

Die Methode, siehe oben, lädt dann die Tabelle per ButtonClick in das Grid "dg" rein.

Danke im Voraus für die Antworten

Gruß

5.658 Beiträge seit 2006
vor 5 Jahren

Das DataGrid im ViewModel zu erzeugen widerspricht dem Sinn von MVVM.

Das DataGrid wird in der View (XAML) erzeugt, und dort die Daten aus dem ViewModel an ItemsSource gebunden.

Siehe Code-Beispiele und Beispiel-Projekt in [Artikel] MVVM und DataBinding

Weeks of programming can save you hours of planning

S
SyntaxTalksToMe Themenstarter:in
17 Beiträge seit 2017
vor 5 Jahren

Das ist mir bewusst, dass das dem Konzept von MVVM widerspricht. Ich habe es ja auch nicht so. Es ist ja so:

View -> ViewModel --> Model und umgekehrt.

Ich habe ja ein DataGrid in meiner View. Aber ich muss ja den Wert vom ViewModel an das View - in dem Fall das Grid, übergeben. Und ich dachte, ich habe genau das in meinem Code gemacht 🙂

        <DataGrid x:Name="meinGrid" HorizontalAlignment="Left" Height="257" Margin="421,310,0,0" VerticalAlignment="Top" Width="597" ItemsSource="{Binding Path=dv, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Grid.ColumnSpan="2" FontSize="14" FontFamily="Arial" Background="#FFFAFAFA"/>

Ich hatte deswegen ein Grid im ViewModel erstellt, damit ich das Grid im View daran binden kann um die Daten der Datenbank zu übergeben 🤔

5.658 Beiträge seit 2006
vor 5 Jahren

Wenn in deinem ViewModel dieser von dir gepostete Code ist, dann stimmt etwas Grundsätzliches nicht:

public DataGrid dg = new DataGrid();

Wenn nicht, dann poste den richtigen Code.

Weeks of programming can save you hours of planning

S
SyntaxTalksToMe Themenstarter:in
17 Beiträge seit 2017
vor 5 Jahren

Ich glaube ich weiß jetzt was du meinst.

Das war so gedacht:

Ich habe ja das GridView in meiner Oberfläche. Dieses wollte ich an das Binden, damit ich es im ViewModel damit befüllen kann. Aber offenbar war das falsch gedacht.

Ich will einfahc dass sich per ButtonClick die Daten in das GridView laden.

Ich muss es ja hinkriegen, das er beim Buttonclick die Daten an das Grid in der View übergibt. Daran hapert es irgendwie gerade. Evlt steh ich auch grad aufn Schlauch. Sitz schon wieder viel zu lange vorm PC heute.

5.658 Beiträge seit 2006
vor 5 Jahren

Dann schlaf erstmal eine Nacht drüber und schau dir morgen den verlinkten Artikel nochmal an.

Weeks of programming can save you hours of planning

S
SyntaxTalksToMe Themenstarter:in
17 Beiträge seit 2017
vor 5 Jahren

Bei den anderen Bindings funktioniert es doch auch. Das Binding an die Eigenschaften die dann die Methode nutzt funzt auch wunderbar 😃

Oder muss ich da ne Liste machen und die mit dem Datenbankinhalt füllen?


amespace Key_Master.ViewM
{
    class Mittelebene : INotifyPropertyChanged
    {

        //Eventhandler zum ändern von Propertys
        public event PropertyChangedEventHandler PropertyChanged;
        private void ChangeProperty(string property)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(property));
            }
        }

        //Methode mit Rückgabewert zum ausgeben der Datentabelle
        public void LadeTabelle(object obj)
        {   //ModelKlasse
            Datenbank datenQuelle = new Datenbank();

            datenQuelle.LoadTable();

        }

        public int Nummer { get; set; }
        public string Bezeichnung { get; set; }
        public string Ort { get; set; }
        public string Mase { get; set; }
        public int Schrank { get; set; }
        public int Reserve { get; set; }
        public int Umlauf { get; set; }
        public string Personen { get; set; }

        public void SendData(object obj)
        {
            Datenbank datenQuelle = new Datenbank();
            datenQuelle.SendData(Nummer, Bezeichnung, Ort, Mase, Schrank, Reserve, Umlauf, Personen);
        }


 
        //ButtonCommand zum weiterreichen des Befehls an das RelaysCo
        private ICommand _loadTableButton;
        public ICommand LoadTable
        {
            get { return _loadTableButton; }
            set
            {
                _loadTableButton = value;
            }
        }

        private ICommand _sendDataButton;
        public ICommand SendDataQuery
        {
            get { return _sendDataButton; }
            set
            {
                _sendDataButton = value;
            }
        }


        private bool _canExecute = true;
        public bool CanExecute
        {
            get { return _canExecute; }
            set
            {
                _canExecute = value;
            }
        }


        public Mittelebene()
        {
            _sendDataButton = new RelaysCo(SendData, param => _canExecute);
            _loadTableButton = new RelaysCo(LadeTabelle, param => _canExecute);
        }



    }


Und hier nochmal der XAML Code:


  <DataGrid x:Name="meinGrid" HorizontalAlignment="Left" Height="257" Margin="421,310,0,0" VerticalAlignment="Top" Width="597" ItemsSource="{Binding LoadTable}" Grid.ColumnSpan="2" FontSize="14" FontFamily="Arial" Background="#FFFAFAFA"/>
        <TextBox x:Name="txtPersonen" HorizontalAlignment="Left" Height="20" Margin="281,494,0,0" TextWrapping="Wrap" Text="{Binding Personen}" VerticalAlignment="Top" Width="118"/>
        <TextBox x:Name="txtNummer" HorizontalAlignment="Left" Height="20" Margin="281,319,0,0" TextWrapping="Wrap" Text="{Binding Nummer, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="118"/>
        <TextBox x:Name="txtBezeichnung" HorizontalAlignment="Left" Height="20" Margin="281,345,0,0" TextWrapping="Wrap" Text="{Binding Bezeichnung}" VerticalAlignment="Top" Width="118"/>
        <TextBox x:Name="txtOrt" HorizontalAlignment="Left" Height="20" Margin="281,369,0,0" TextWrapping="Wrap" Text="{Binding Ort}" VerticalAlignment="Top" Width="118"/>
        <TextBox x:Name="txtMase" HorizontalAlignment="Left" Height="20" Margin="281,394,0,0" TextWrapping="Wrap" Text="{Binding Mase}" VerticalAlignment="Top" Width="118"/>
        <TextBox x:Name="txtSchrank" HorizontalAlignment="Left" Height="20" Margin="281,419,0,0" TextWrapping="Wrap" Text="{Binding Schrank}" VerticalAlignment="Top" Width="118"/>
        <TextBox x:Name="txtReserve" HorizontalAlignment="Left" Height="20" Margin="281,445,0,0" TextWrapping="Wrap" Text="{Binding Reserve}" VerticalAlignment="Top" Width="118"/>
        <TextBox x:Name="txtUmlauf" HorizontalAlignment="Left" Height="20" Margin="281,469,0,0" TextWrapping="Wrap" Text="{Binding Umlauf}" VerticalAlignment="Top" Width="118"/>
        <Button Content="Datensatz speichern" HorizontalAlignment="Left" Height="30" Margin="286,533,0,0" VerticalAlignment="Top" Width="112" Click="Button_Click_1" Command="{Binding SendDataQuery}"/>

Ich hab mir den Artikel, den ich schon hatte durchgelesen. Über dieses Problem an sich steht da aber nix drinnen.

Das weiterreichen des Inhaltes der Database an das Grid will einfach nicht klappen. Es wird einfach nicht angezeigt.

Ich hab schon mehrere Sachen ausprobiert, natürlich immer das MVVM Prinzip vor Augen.

Du siehst auch im XAML Code "ItemSource = {Binding LoadTable}

Ich hätte einfach gerne einen Tipp oder eine konkrete Antwort wie ich das schaffe.

4.939 Beiträge seit 2008
vor 5 Jahren

Du benötigst eine Eigenschaft (in deinem ViewModel) vom Typ DataView (oder aber alternativ ObservableCollection<T>), welche dann mit dem DataGrid verbunden wird - eine Methode kann nicht per DataBinding verbunden werden.


ItemSource = {Binding MyDataView}

Und dein "Lade"-Button befüllt dann per ICommand diese Eigenschaft:


MyDataView = datenQuelle.LoadTable();

s.a. MVVM and the WPF DataGrid

PS: Du solltest den vollen Namen RelayCommand für die ICommand-Implementierungsklasse benutzen, keine komische Abkürzung.

S
SyntaxTalksToMe Themenstarter:in
17 Beiträge seit 2017
vor 5 Jahren

vielen Dank.

Jetzt klappt es.