Autor Beitrag
Schafschaf
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 63
Erhaltene Danke: 2

Windows 10
C# (VS 2015)
BeitragVerfasst: Fr 15.01.16 11:46 
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 63
Erhaltene Danke: 2

Windows 10
C# (VS 2015)
BeitragVerfasst: Fr 15.01.16 15:47 
Ich kürze mal den Code aufs Wesentliche:

Mein View sieht so aus:
ausblenden 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:
ausblenden volle Höhe 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(thisnew 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//Hier ändere ich was an Jobs, warum passiert da nix?
            }
            else
            {
                Model.Current.ResumeJob(Id);
                Jobs.Where(x => x.JobId.Equals(Id)).SingleOrDefault().IsActive = true//Hier ändere ich was an Jobs, warum passiert da nix?
            }
        }
       
        public async void Initialize()
        {
            //Fülle Jobs mit Daten vom Server
        }

        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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4701
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Fr 15.01.16 15:54 
Es ist eine Property von JobForUser? Dann ist die Frage ob JobForUser INotifyPropertyChanged implementiert.

Für diesen Beitrag haben gedankt: Schafschaf
Schafschaf Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 63
Erhaltene Danke: 2

Windows 10
C# (VS 2015)
BeitragVerfasst: 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!