none
Keine Aktualisierung der Oberfläche RRS feed

  • Frage

  • Hallo!

    Obwohl ich explizit OnPropertyChanged aufrufe wird die Oberfläche nicht aktualisiert.

    Ich habe eine kurzes Beispiel erstellt:

    DataModel mit nur einer Property (ID):

    public class svTabelle2
    {
        public int ID { get; set; }                                 // ID
    
        public svTabelle2(int _ID) {ID = _ID;}                      // Constructor der ID setzt
    
    }

    ViewModel, mit der Methode incrementID:

    public class vmSV2 : INotifyPropertyChanged
    {
        #region  OnPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged([CallerMemberName] string propName = "") =>
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
        #endregion
    
            CollectionViewSource cvsTabellen = new CollectionViewSource();                          // Collection der SQL-Viewer-Tabellen
    
        public ICollectionView ViewTabellen { get { return cvsTabellen.View; } }                // View der SQL-Viewer Tabellen
    
        public svTabelle2 SelectedTabelle { get; set; }                                         // Aktuell selektierte Tabelle (mit allen Eigenschaften)
    
        public vmSV2(List<svTabelle2> _svTabellen = null)
        {
            _svTabellen = new List<svTabelle2>();                                               // Leere Liste erstellen
            _svTabellen.Add(new svTabelle2(1));                                                 // 2 Standard-Einträge erzeugen (ID=1,2)
            _svTabellen.Add(new svTabelle2(2));
            cvsTabellen.Source = _svTabellen;                                                   // SQL-Viewer-Tabellen-Einträge initalisieren            
            SelectedTabelle = (svTabelle2)cvsTabellen.View.CurrentItem;                         // Das akt. selektierte Tabelle Objekt initalisieren
            cvsTabellen.View.CurrentChanged += Tabellen_View_CurrentChanged;                    // View-Änderungs-Event deklarieren
            OnPropertyChanged(nameof(ViewTabellen));                                            // Der Oberfläche mitteilen, dass sich der Inhalt der Sicht geändert hat
        }
    
        private void Tabellen_View_CurrentChanged(object sender, EventArgs e)
        {
            SelectedTabelle = (svTabelle2)cvsTabellen.View.CurrentItem;                         // Das akt. selektierte Tabelle Objekt, aktualisieren            
            OnPropertyChanged(nameof(ViewTabellen));                                            // Der Oberfläche mitteilen, dass sich der Inhalt der Sicht geändert hat
        }
    
        public void incrementID()                                          // Methode, um den Cursor der SQL-Eingabe zu setzen
        {
            if (SelectedTabelle != null)                                                        // Ist eine Tabelle ausgewählt?
            {
                ++SelectedTabelle.ID;
                OnPropertyChanged(nameof(ViewTabellen));                                        // Der Oberfläche mitteilen, dass sich die View geändert hat
            }
        }
    
    }


    Im Fenster ordne ich das ViewModel dem Datacontext des Fensters zu und rufe im Button die incrementID Methode auf:

    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
            wndVMTest.DataContext = vm;       // DataContext des Fensters = ViewModel des Fensters
        }
        vmSV2 vm = new vmSV2();               // ViewModel des Fensters initalisieren
    
        private void btn_Click(object sender, RoutedEventArgs e)
        {
            vm.incrementID();   // ID des akt. Eintrages erhöhen
            MessageBox.Show("ID: " + vm.SelectedTabelle.ID.ToString());
        }
    }


    <Window x:Name="wndVMTest" x:Class="SQLtoExcel.Window1"
            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:SQLtoExcel"
            mc:Ignorable="d"
            Title="Window1" Height="300" Width="300">
        <Grid>
            <ListBox BorderThickness="2" BorderBrush="Blue" HorizontalAlignment="Center" Height="100" Margin="0,40,0,0" VerticalAlignment="Top" Width="200" 
                     ItemsSource="{Binding ViewTabellen}" DisplayMemberPath="ID" IsSynchronizedWithCurrentItem="True" />
            <Button Content="ID inkrementieren" HorizontalAlignment="Center" VerticalAlignment="Bottom" Click="btn_Click" Margin="0,0,0,20"/>
        </Grid>
    </Window>

    Wie man an der MessageBox sehen kann, wird das DataModel aktualisiert. Warum wird das nicht angezeigt???

    Fred.

    Dienstag, 26. Februar 2019 10:12

Antworten

  • Hi Fred,
    wie soll die Oberfläche eine Änderung des Wertes der ID-Eigenschaft (btn_Click -> vm.incrementID -> ++SelectedTabelle.ID) mitbekommen, wenn diese Änderung (der ID) nicht mit PropertyChanged gemeldet wird? Bau in die Klasse svTabelle2 INotifyPropertyChanged ein und löse das im Setter der Eigenschaft "ID" aus.

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

    • Als Antwort markiert perlfred Dienstag, 26. Februar 2019 13:05
    Dienstag, 26. Februar 2019 11:30

Alle Antworten

  • Hi Fred,
    wie soll die Oberfläche eine Änderung des Wertes der ID-Eigenschaft (btn_Click -> vm.incrementID -> ++SelectedTabelle.ID) mitbekommen, wenn diese Änderung (der ID) nicht mit PropertyChanged gemeldet wird? Bau in die Klasse svTabelle2 INotifyPropertyChanged ein und löse das im Setter der Eigenschaft "ID" aus.

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

    • Als Antwort markiert perlfred Dienstag, 26. Februar 2019 13:05
    Dienstag, 26. Februar 2019 11:30
  • Hallo Peter!

    Mit INotfyPropertyChanged im Model funktioniert die Aktualisierung hervorragend!

    Ich bin davon ausgegangen, wenn ich im ViewModel ein INotifyPropertyChanged der View an die Oberfläche "melde", werden auch alle (gebundenen) Eigenschaften dieser View auf der Oberfläche aktualisiert.

    Danke! für deine Lösung!

    Fred.

    public class svTabelle2 : INotifyPropertyChanged
    {
        #region  OnPropertyChanged
             ...
        #endregion
    
        private int id;
        public int ID                                               // ID
        {
            get { return id; }
            set { id = value; OnPropertyChanged(nameof(ID)); }
        }                                 
    ...

    Dienstag, 26. Februar 2019 13:16