Laden...

CollectionChanged --> verschachteln oder eigenständig?

Erstellt von Moritz83 vor 4 Jahren Letzter Beitrag vor 4 Jahren 1.456 Views
M
Moritz83 Themenstarter:in
50 Beiträge seit 2013
vor 4 Jahren
CollectionChanged --> verschachteln oder eigenständig?

Moin,

ich habe folgenden Ausgangssituation (WPF MVVM):
Auf einer View habe ich eine Listview und einen Button mit dem ich einen Eintrag aus der Listview löschen und danach die SQLite Datei aktualisieren möchte.

Das mit dem Binding des Buttons klappt soweit, allerdings habe ich ein Verständnis Problem wie der Hintergrund aussehen sollte. Meiner Meinung nach habe ich 2 Möglichkeiten:

        public RelayCommand DeleteEmployee
        {
            get
            {
                command = new RelayCommand(Delete);
                return command;
            }
        }
  1. Möglichkeit
        public void Delete()
        {
            //aus Listview löschen
            //aus SQLite löschen
        }

oder ich gehe über die CollectionChanged Variante (eine ObservableCollection dient als Datenlieferant für die Listview) als

  1. Möglichkeit
EmployeeListView.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler
(CollectionChangedMethod);
        public void Delete()
        {
            //aus Listview löschen und CollectionChanged triggern
        }
        private void CollectionChangedMethod(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.Action == NotifyCollectionChangedAction.Remove)
            {
                //Aus SQLite löschen
            }
        }

Würde jetzt die 1. Möglichkeit nehmen da sie mir "sauberer" erscheint, wie "sollte" man das lösen?

16.806 Beiträge seit 2008
vor 4 Jahren

In MVVM arbeitet man aber nicht mit Code Behind Eventhandling und damit auch nicht mit CollectionChanged.
[Artikel] MVVM und DataBinding

M
Moritz83 Themenstarter:in
50 Beiträge seit 2013
vor 4 Jahren

Der Code steht auch in meinem ViewModel und net im Code Behind. Im Code Behind von MainWindow.xaml steht nur

        public MainWindow()
        {
            InitializeComponent();
            DataContext = new EmployeeViewModel();
        }
16.806 Beiträge seit 2008
vor 4 Jahren

Schau Dir MVVM an.

Das Control gehört da nicht in Dein ViewModel.
In das ViewModel gehören die Daten, die gebunden werden.

Und im XAML steht dann welches Control was bindet.
Du arbeitest mit Events - das ist in MVVM so nicht vorgesehen. Es ist eine Abhängigkeit, die man mit MVVM eben nicht will.

Aktionen werden dann zB. über Commands gelöst - aber nicht über Events.
Steht alles in dem Artikel.

Und so eine Aktualisierung würde man auch nicht über den Eintrag der UI-Elemente machen, sondern über die gebundenen Daten.

M
Moritz83 Themenstarter:in
50 Beiträge seit 2013
vor 4 Jahren

entweder verstehe ich nicht was du mir sagen willst oder wir reden komplett aneinander vorbei. Hier ganz vereinfacht die Ausgangslage:

MainWindow.xaml

<ListView Name="MuhKuh" ItemsSource="{Binding EmployeeListView, UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding YourSelectedItem, Mode=TwoWay}" Height="86">
//Code
<Button Command="{Binding DeleteEmployee}" CommandParameter="{Binding EmployeesListView}" Margin="0,0,10,0">Delete</Button>
//Code
</ListView>

MainWindow.xaml.cs

        public MainWindow()
        {
            InitializeComponent();
            DataContext = new EmployeeViewModel();
        }

----> Binding ---->

EmployeeViewModel.cs (RelayCommand ist eine eigene Klasse in einer eigenen Datei)

       
//Definition der ObservableCollection für die View
//Code
//RelayCommand Definition
public RelayCommand DeleteEmployee
        {
            get
            {
                command = new RelayCommand(Delete);
                return command;
            }
        }

meine Frage wäre nun ob die Delete Void die ich aufrufe
a.) Das Löschen des Eintrags aus der ObservableCollection (die View kriegt durch das Binding ja automatisch ein Feedback) UND das Löschen des Eintrags aus der DB beinhaltet.

oder

b.) Das Löschen des Eintrags aus der ObservableCollection beinhaltet und die Funktion zum löschen des DB Eintrags in der SQLite Datei im besagten CollectionChanged Event steht

Sorry wenn ich mich vielleicht nicht klar ausgedrückt habe

3.170 Beiträge seit 2006
vor 4 Jahren

Hallo,

auf jeden Fall Möglichkeit a.)
Und zwar in umgekehrter Reihenfolge: Erst löschst Du das Objekt aus der Datenbank (über ein entsprechedes Datenlayer), und erst wenn das funktioniert hat aus der ObservableCollection im ViewModel. Dann kannst Du auch noch Fehlerbehandlung machen, wenn das Löschen aus der DB schiefgeht, und das Objekt ist in der UI noch vorhanden.

Möglichkeit b.) ist ein völlig falscher Ansatz.
Wenn ein solcher Code

EmployeeListView.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler
(CollectionChangedMethod);

im ViewModel auftaucht, bedeutet das, dass das ViewModel die View kennt und das sollte es nie.

Wenn der Code im CodeBehind steht, verlagerst Du Deine Löschlogik direkt unter Umgehung des ViewModels in die View - und das ist dann auf jeden Fall ein Designfehler.

Auf dieser Grundlage sind dann auch die Aussagen

In MVVM arbeitet man aber nicht mit Code Behind Eventhandling

Das Control gehört da nicht in Dein ViewModel.

hoffentlich verständlich, denn bei dem Ansatz über CollectionChanged trifft auf jeden Fall einer dieser Umstände zu.

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

4.931 Beiträge seit 2008
vor 4 Jahren

Da ist die Benennung eindeutig schlecht, denn bei EmployeeListView handelt es sich (wohl) nicht um das UI-Element (denn dieses hat ja gar kein CollectionChanged-Ereignis), sondern um die Collection, an der die ListView gebunden ist (d.h. Employees o.ä. wäre ein besserer Name für diese ViewModel-Eigenschaft).

PS: Auch der von dir benutzte Ausdruck

Delete Void deutet darauf hin, daß du anscheinend noch nicht so ganz in der Materie drin bist, denn du meinst wohl "Delete Methode"?! void ist ja nur der Rückgabewert dieser Methode (und bedeutet einfach "leer") - du sagst doch auch nicht "Delete Int" oder "Delete Float"?!

Aber diesen Ausdruck habe ich schon des öfteren bei Anfängern gelesen, da sie wohl davon ausgehen (wie in anderen, nicht auf C basierenden, Sprachen, daß dies so etwas wie "procedure" oder "function" bedeutet - und verwenden es daher fälschlicherweise als Synonym dafür).

M
Moritz83 Themenstarter:in
50 Beiträge seit 2013
vor 4 Jahren

@MarsStein
Super, danke für den Wink wie man so etwas angehen könnte. Auf die Idee mit der integrierten Fehlerbehandlung bin ich gar nicht gekommen, macht aber mehr als Sinn.

Klar, nun verstehe ich auch was Abt gemeint hat (wenn gleich das im ersten Augenblick vielleicht mehr als verwirrend war).

Merci für deine Hilfe und hilfreichen Tipps!

@Th69
Ja die Benennung ist wirklich schlecht in meinem Projekt. Hab da noch kein Händchen für. Meine Idee war erstmal ein funktionierendes "Etwas" auf die Beine zu stellen und mir dann Schritt für Schritt den Code durcharbeiten um eben sowas, als auch die von Abt und MarsStein angesprochenen Sachen zu ändern.

Bin definitiv noch ein Anfänger und habe tatsächlich nur Erfahrung mit Visual Basic (aber da auch eher Quick & Dirty als Ordentlich & Strukturiert). Ich habe natürlich die Methode gemeint.

Danke dir für deinen Input!

@Abt
auch dir vielen Dank (auch wenn ich Hilfe gebraucht habe um die Message zu verstehen 😉 )

3.170 Beiträge seit 2006
vor 4 Jahren

Hallo,

denn bei EmployeeListView handelt es sich (wohl) nicht um das UI-Element (denn dieses hat ja gar kein CollectionChanged-Ereignis), sondern um die Collection

In der Tat, da habe ich mich wohl von der Benennung hinreissen lassen - Freitag Nachmittag, puh!

Das bedeutet, was ich bezüglich Views geschrieben habe, trifft hier nicht zu, wir sind die ganze Zeit auf ViewModel-Ebene.

Trotzdem halte ich den Ansatz, über das CollectionChanged-Ereignis zu gehen, aus den ebenfalls genannten Gründen für den falschen Weg.

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

16.806 Beiträge seit 2008
vor 4 Jahren

In der Tat, da habe ich mich wohl von der Benennung hinreissen lassen

Same here.