Entwickler-Ecke
Sonstiges (.NET) - XAML: Steuerelement in Template updaten
Schafschaf - Fr 15.01.16 11:46
Titel: XAML: Steuerelement in Template updaten
Hallo,
ich bin gerade an einer UWP App, die als Client fungiert für Tasks auf meiner Serveranwendung zu verwalten.
Dazu habe ich eine Listview, die mir die Details eines Tasks anzeigt. Im ViewModel habe ich eine ObservableCollection gefüllt mit Taskobjekten.
Die Listview ist an die Collection gebunden und mein ViewModel implementiert INotifyPropertyChanged.
Das CollectionChanged-Event der Collection wird beim Hinzufügen oder Löschen aufgerufen und dies feuert das PropertyChanged-Event.
Das funktioniert auch soweit ganz gut. Jetzt habe ich aber in meinem TaskObjekt eine Boolproperty "IsActive". Dies wird als CheckBox im Template der ListViewItems angezeigt.
Damit man sieht ob ein Task gerade aktiv ist. Jetzt möchte ich mit einem Play/Pause Button die Tasks anhalten oder fortsetzen.
Das klappt auch soweit, allerdings ändert sich die Checkbox mit "IsActive" nicht.
Jetzt weiß ich nicht wie ich das angehen soll.
Entweder ich versuche das PropertyChanged dazu zu bringen, die ListView zu updaten, wenn der Bool-Wert geändert wurde,
oder ich versuche über den Button in die listView zu kommen und dort die Checkbox entsprechen zu setzen.
Bei beiden Methoden weiß ich nicht wie ichs machen soll.
Hoffe jemand kann mir helfen.
LG Schafschaf
Palladin007 - Fr 15.01.16 15:04
Beide Methoden lässt Du schön bleiben ^^
Nach MVVM hat das ViewModel nichts mit der View am Hut. Es kennt sie nicht und macht nichts mit ihr. Die View dagegen nutzt das ViewModel und arbeitet aktiv damit.
Dein Problem wird wohl auf ein kaputtes Binding zurück zu führen sein - oder das Collection-Item informiert die View nicht korrekt über eine Änderung.
Wie sieht denn die Klasse aus, wie in der Collection verwendet wird? Die muss auch INotifyPropertyChaned implementieren, sonst sieht die View zwar die Items und deren Properties, bemerkt aber nicht, wenn sich dort etwas ändert.
Und wie sieht denn das Template bzw. das Binding im Template oder im Control, wo das Template genutzt wird, aus?
Schafschaf - Fr 15.01.16 15:47
Ich kürze mal den Code aufs Wesentliche:
Mein View sieht so aus:
XML-Daten
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| <ListView x:Name="listViewJobs" ItemsSource="{Binding Jobs, UpdateSourceTrigger=PropertyChanged}" SelectionChanged="listViewJobs_SelectionChanged"> <ListView.ItemContainerStyle> ... </ListView.ItemContainerStyle> <ListView.ItemTemplate> <DataTemplate> <StackPanel> ... <CheckBox IsChecked="{Binding IsActive}" Content="Aktiv" IsHitTestVisible="False" /> ... </StackPanel> </DataTemplate> </ListView.ItemTemplate> </ListView> |
Das ViewModel:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42:
| public class JobsVm : INotifyPropertyChanged { public JobsVm() { Initialize(); } private void Jobs_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { OnPropertyChanged("Jobs"); }
private void OnPropertyChanged(string prop) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(prop)); }
public event PropertyChangedEventHandler PropertyChanged; public void PauseResumeJob(int Id) { if(Jobs.Where(x => x.JobId.Equals(Id)).SingleOrDefault().IsActive) { Model.Current.PauseJob(Id); Jobs.Where(x => x.JobId.Equals(Id)).SingleOrDefault().IsActive = false; } else { Model.Current.ResumeJob(Id); Jobs.Where(x => x.JobId.Equals(Id)).SingleOrDefault().IsActive = true; } } public async void Initialize() { }
public ObservableCollection<JobForUser> Jobs { get; set; } } |
So wie du es beschreibst mache ich es auch. Das ViewModel kümmert sich nur um seine Collections und redet mit dem Model. (In meinem Fall ein Singleton was mit WCF mit dem Server redet)
Das View ruft den Krempel im ViewModel auf oder bindet sich daran was ich da bereitgestellt habe.
Im ViewModel sind noch Methoden Add und Delete, die habe ich hier für die Veranschaulichung nicht mitgenommen, die fügen Jobs was hinzu oder nehmen was weg.
Dann wird auch korrekterweise CollectionChanged aufgerufen und ich sehe wie in der Liste ein Element dazukommt oder verschwindet.
Ich möchte allerdings nur das Häkchen eines bestehenden Listenelements verändern, je nachdem wie ich die "IsActive" Eigenschaft eines Job-Objektes ändere.
Da passiert komischerweise nichts, selbst wenn ich PropertyChanged aufrufe.
Ralf Jansen - Fr 15.01.16 15:54
Es ist eine Property von JobForUser? Dann ist die Frage ob JobForUser INotifyPropertyChanged implementiert.
Schafschaf - Fr 15.01.16 16:11
Ralf Jansen Hero of the Day!
Ich denke der Groschen ist bei mir gefallen :)
Habe INotifyPropertyChanged in JobForUser implementiert und rufe das Event im Setter des IsActive Propertys auf.
Nun ändert sich das Häkchen an der Checkbox wenn der Bool sich ändert.
Danke!
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!