none
MVVM - DataGrid - View aktualisieren nach Messwertuebergabe RRS feed

  • Frage

  • Hallo ich habe noch eine Frage.

    Zurzeit fülle ich die Tabelle mit entsprechenden Messwerten über einen Button mit

            private void AddMesswert()
            {
                // Aus Schnittstelle übergeben
                Pruefling.Messpunkte[0].X_Mess = 655;            
                // View aktualisieren
                OnPropertyChanged("Pruefling");
            }

    Erste Frage: Wie kann ich den GridView aktualisieren. Mit OnPropertyChanged("Pruefling"); funktioniert es nicht.

    Zweite Frage: Gibt es die Möglichkeit im View per CurrentChanged auf die zweite Tabelle zuzugreifen wenn ein Wert geändert wird? Ich möchte gern das Pruefling.Messpunkte[i].X_Mess füllen in Abhänigkeit von der angewählten (Messpunkt) Zeile im View.

                cvsP.View.CurrentChanged += (object sender, EventArgs e) =>
                {
                    Pruefling = cvsP.View.CurrentItem as Pruefling;
                    OnPropertyChanged("Pruefling");
    
                    // TODO Zeile des aktuellen Prüflings einfärben 
                    // DataRow row = (cvsP.View.CurrentItem as DataRowView).Row;
                    // row.Background = Brushes.Pink;
                };

    Prüfling ist Datenklasse für die erste Tabelle (ItemsSource="{Binding ViewP}"). Für die erste Tabelle funktioniert es. CurrentChanged wird jedoch nicht ausgelöst wenn man in die zweite Tabelle klickt (ItemsSource="{Binding Pruefling.Messpunkte}").

    Nachfolgend die xaml für den View:

                    <Grid DataContext="{StaticResource vm}">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition/>
                            <ColumnDefinition/>
                        </Grid.ColumnDefinitions>
                        <Grid Grid.Column="0">
                            <Grid.RowDefinitions>
                                <RowDefinition/>
                                <RowDefinition Height="Auto"/>
                            </Grid.RowDefinitions>
                            <DataGrid Grid.Row="0" ItemsSource="{Binding ViewP}" AutoGenerateColumns="False" IsReadOnly="False">
                                <DataGrid.Columns>
                                    <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
                                </DataGrid.Columns>
                            </DataGrid>
                            <Button Grid.Row="1" Content="Prüfling hinzufügen" Command="{Binding ClickAddPrüfling}" Margin="5,5,0,5" HorizontalAlignment="Left" Width="188"/>
                            <Button Grid.Row="1" Content="Prüfling entfernen" Command="{Binding ClickRemovePrüfling}" Margin="0,5,5,5" HorizontalAlignment="Right" Width="188"/>
                        </Grid>
                        <Grid Grid.Column="1">
                            <Grid.RowDefinitions>
                                <RowDefinition/>
                                <RowDefinition Height="Auto"/>
                            </Grid.RowDefinitions>
                            <DataGrid Grid.Row="0" ItemsSource="{Binding Pruefling.Messpunkte}"/>
                            <Button Grid.Row="1" Content="Messpunkt hinzufügen" Command="{Binding ClickAddMesspunkt}" Margin="5,5,0,5" HorizontalAlignment="Left" Width="188"/>
                            <Button Grid.Row="1" Content="Messpunkt entfernen" Command="{Binding ClickRemoveMesspunkt}" Margin="0,5,5,5" HorizontalAlignment="Right" Width="188"/>
                        </Grid>
                    </Grid>

    Vielen Dank.

    Viele Grüße
    Martin






    • Bearbeitet mApO18 Mittwoch, 9. Mai 2018 08:58 Titel korrigiert
    Mittwoch, 9. Mai 2018 08:57

Antworten

  • Hi Martin,
    mit PropertyChanged teilst Du der Oberfläche mit, die Werte welcher gebundenen Eigenschaft sind neu abzurufen.

    Erste Frage: Wie kann ich den GridView aktualisieren. Mit OnPropertyChanged("Pruefling"); funktioniert es nicht.

    und im XAML steht:

    datagrid autogeneratecolumns="False" grid.row="0" isreadonly="False" itemssource="{Binding ViewP}"

    Wo wird der Oberfläche mit PropertyChanged mitgeteilt, dass sich die Werte der Eigenschaft "ViewP" geändert haben? Normalerweise reichen da die Eigenschaften einer ObservableCollection.

    Zweite Frage: Gibt es die Möglichkeit im View per CurrentChanged auf die zweite Tabelle zuzugreifen wenn ein Wert geändert wird?

    Ein Beispiel dazu hatte ich Dir bereits gepostet. Da wurde an die View eine Ereignisroutine gehängt, die auf CurrentChanged reagiert und damit den aktuellen "Prüfling" der Eigenschaft "Pruefling" zuweist. Mit dem folgenden OnPropertyChanged("Pruefling") wird der Oberfläche mitgeteilt, dass es einen neuen aktuellen Prüfling gibt. 

    DataGrid Grid.Row="0" ItemsSource="{Binding Pruefling.Messpunkte}"

    Damit wird die Ansicht (DataGrid) der im Prüfling eingebetteten Messpunkte aktualisiert.

    Warum funktioniert mein gepostetes Beispiel bei Dir nicht?

    Ich vermute, dass entgegen Deiner Information Du ein anderes Datenmodell nutzt. Das solltest Du mal erläutern, wenn Du wirklich Hilfe benötigst.


    --
    Viele Grüsse
    Peter Fleischer (ehem. MVP)
    Meine Homepage mit Tipps und Tricks

    Mittwoch, 9. Mai 2018 11:12
  • Hi Martin,
    wenn Du willst, dass sich bei einer Änderung des Wertes der X_Mess-Eigenschaft die gebundene Zelle im DataGrid den neuen Wert für eine Anzeige holt, dann musst Du dort auch das PropertyChanged auslösen:

              Pruefling.Messpunkte[0].Messwert = 655;
    
    ...
    
      // Datenklasse für Messpunkt
      public class Window52DataM : INotifyPropertyChanged
      {
        public string Messpunkt { get; set; }
        private decimal _messwert;
        public decimal Messwert { get { return this._messwert; }
          set { this._messwert = value; OnPropertyChanged(); } }
        public decimal Abweichung { get; set; }
    
        #region  OnPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged([CallerMemberName] string propName = "") =>
          PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
        #endregion
      }

    Um den ausgewählten Messpunkt zu ermitteln, muss Du genau so auf CurrentChanged reagieren. Da das in jeder Collection erforderlich ist, ist es sinnvoll, eine eigene Collection-Klasse herzuleiten und zu nutzen.


    --
    Viele Grüsse
    Peter Fleischer (ehem. MVP)
    Meine Homepage mit Tipps und Tricks

    Mittwoch, 9. Mai 2018 15:36

Alle Antworten

  • Hi Martin,
    mit PropertyChanged teilst Du der Oberfläche mit, die Werte welcher gebundenen Eigenschaft sind neu abzurufen.

    Erste Frage: Wie kann ich den GridView aktualisieren. Mit OnPropertyChanged("Pruefling"); funktioniert es nicht.

    und im XAML steht:

    datagrid autogeneratecolumns="False" grid.row="0" isreadonly="False" itemssource="{Binding ViewP}"

    Wo wird der Oberfläche mit PropertyChanged mitgeteilt, dass sich die Werte der Eigenschaft "ViewP" geändert haben? Normalerweise reichen da die Eigenschaften einer ObservableCollection.

    Zweite Frage: Gibt es die Möglichkeit im View per CurrentChanged auf die zweite Tabelle zuzugreifen wenn ein Wert geändert wird?

    Ein Beispiel dazu hatte ich Dir bereits gepostet. Da wurde an die View eine Ereignisroutine gehängt, die auf CurrentChanged reagiert und damit den aktuellen "Prüfling" der Eigenschaft "Pruefling" zuweist. Mit dem folgenden OnPropertyChanged("Pruefling") wird der Oberfläche mitgeteilt, dass es einen neuen aktuellen Prüfling gibt. 

    DataGrid Grid.Row="0" ItemsSource="{Binding Pruefling.Messpunkte}"

    Damit wird die Ansicht (DataGrid) der im Prüfling eingebetteten Messpunkte aktualisiert.

    Warum funktioniert mein gepostetes Beispiel bei Dir nicht?

    Ich vermute, dass entgegen Deiner Information Du ein anderes Datenmodell nutzt. Das solltest Du mal erläutern, wenn Du wirklich Hilfe benötigst.


    --
    Viele Grüsse
    Peter Fleischer (ehem. MVP)
    Meine Homepage mit Tipps und Tricks

    Mittwoch, 9. Mai 2018 11:12
  • Hallo Peter,

    genau richtig. Dein Beispiel funktioniert genau so wie du es geschrieben hast. Mit OnPropertyChanged("Pruefling")  wird der Oberfläche mitgeteilt, dass es einen neuen aktuellen Prüfling gibt. Dadurch werden die Eigenschaften des neuen Prüflings im Grid

    DataGrid Grid.Row="0" ItemsSource="{Binding Pruefling.Messpunkte}"

    angezeigt. Das klappt soweit. Es funktioniert auch, wenn der Nutzer neue Werte in die Tabelle einträgt.

     Wie im Beispiel angedeutet wird nun nicht durch den Nutzer über die Oberfläche, sondern intern ein Wert in Prüfling.Messpunkte aktualisiert. Mit

                Pruefling.Messpunkte[0].X_Mess = 655;            

    wird dem ersten Messpunkt im aktuellen Prüfling der X_Mess - Wert auf 655 gesetzt. Wobei X_Mess eine Eigenschaft der ObservableCollection<Messpunkt> Messpunkte in der Klasse Prüfling ist.

    Dieser Wert wird nun aber erst angezeigt, wenn ich die Prüflingszeile erneut im VIEW anklicke. Mein Ziel ist es jedoch den View sofort zu aktualisieren.

    Genau wie bei der Detektion des aktuellen Prüflings über CurrentChanged würde ich gerne den angewählten Messpunkt im View erkennen. Damit ich weiß mit welchem Messpunkt der Anwender gerade arbeitet und dort Messwerte (Ist - Werte) über eine Schnittstelle eintragen kann.

    Ich hoffe das war verständlich.

    Danke sehr.

    Viele Grüße
    Martin



    • Bearbeitet mApO18 Mittwoch, 9. Mai 2018 13:43 Wort korrigiert
    Mittwoch, 9. Mai 2018 13:42
  • Hi Martin,
    wenn Du willst, dass sich bei einer Änderung des Wertes der X_Mess-Eigenschaft die gebundene Zelle im DataGrid den neuen Wert für eine Anzeige holt, dann musst Du dort auch das PropertyChanged auslösen:

              Pruefling.Messpunkte[0].Messwert = 655;
    
    ...
    
      // Datenklasse für Messpunkt
      public class Window52DataM : INotifyPropertyChanged
      {
        public string Messpunkt { get; set; }
        private decimal _messwert;
        public decimal Messwert { get { return this._messwert; }
          set { this._messwert = value; OnPropertyChanged(); } }
        public decimal Abweichung { get; set; }
    
        #region  OnPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged([CallerMemberName] string propName = "") =>
          PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
        #endregion
      }

    Um den ausgewählten Messpunkt zu ermitteln, muss Du genau so auf CurrentChanged reagieren. Da das in jeder Collection erforderlich ist, ist es sinnvoll, eine eigene Collection-Klasse herzuleiten und zu nutzen.


    --
    Viele Grüsse
    Peter Fleischer (ehem. MVP)
    Meine Homepage mit Tipps und Tricks

    Mittwoch, 9. Mai 2018 15:36
  • "Um den ausgewählten Messpunkt zu ermitteln, muss Du genau so auf CurrentChanged reagieren. Da das in jeder Collection erforderlich ist, ist es sinnvoll, eine eigene Collection-Klasse herzuleiten und zu nutzen. "

    Kannst du mir bitte ein Beispiel geben?

    Über
            private CollectionViewSource cvsM = new CollectionViewSource();
            public ICollectionView ViewM { get { return cvsM.View; } }

    würde ich mir einen neuen View und Source definieren. Das Zuweißen der Sourve dann über den Datenlayer der Anzeige (Windows 52DL dl ) Jedoch würde ich gerne weiterhin die Spalten der Messpunkte sofort anzeigen lassen wenn ein neuer Prüfling angeklickt wird.

    Wie komme ich quasi von                        

    <DataGrid Grid.Row="0" ItemsSource="{Binding Pruefling.Messpunkte}"/>

    auf

    <DataGrid Grid.Row="0" ItemsSource="{Binding ViewM}" AutoGenerateColumns="True" IsReadOnly="False"/>

    Alle Eigenschaften sollen gleich bleiben. Jedoch nur das Anklicken der Zeile würde hinzukommen.

    Dankeschön!

    Einen schönen Brückentag wünsche ich euch allen.

    Viele Grüße
    Martin

    Freitag, 11. Mai 2018 12:14
  • Hi Martin,
    Du hattest geschrieben, dass den Datenmodell in der Anwendung so aussieht:

    Liste der Prüflinge
        Prüfling
            Liste der Messpunkte im Prüfling

    Was soll dann in diesem Datenmodell ViewM sein? Wenn das die Sicht auf die Messpunkte in einem Prüfling sein soll, dann musst Du in der Liste der Prüflinge bei jeder Navigation die Sicht neu erstellen. Was soll dieser Aufwand bringen?

    Du kannst z.B. im Prüfling eine Eigenschaft mit dem aktuellen Messwert nach außen reichen. Diesen aktuellen Messwert lässt Du Dir von der Liste der Messwerte geben. Dann brauchst Du nicht den Umweg über jedes Neuladen der Sicht der Messwerte gehen.


    --
    Viele Grüsse
    Peter Fleischer (ehem. MVP)
    Meine Homepage mit Tipps und Tricks

    Montag, 14. Mai 2018 13:10