Gebundene Eigenschaft wird nur einmal beim Start abgeholt...

  • WPF

Es gibt 14 Antworten in diesem Thema. Der letzte Beitrag () ist von Joshi.

    Gebundene Eigenschaft wird nur einmal beim Start abgeholt...

    Hallo Leute und danke fürs Reinschauen...

    Kann mir jemand behilflich sein, warum meine gebundene Variable nur einmal abgeholt wird:

    Quellcode

    1. private TimeSpan _wmBusyTime;
    2. public TimeSpan wmBusyTime
    3. {
    4. get
    5. {
    6. return _wmBusyTime;
    7. }
    8. set
    9. {
    10. if (_wmBusyTime == value)
    11. return;
    12. _wmBusyTime = value;
    13. wmBusyTimeChanged?.Invoke(this, _wmBusyTime);
    14. OnPropertyChanged("wmBusyTime");
    15. }
    16. }​


    XML-Quellcode

    1. ​<Label Grid.Column="3" Content="{Binding Path=wm00_ListOfvSharePointLeihgeraete.wmBusyTime, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" HorizontalAlignment="Right" VerticalContentAlignment="Center" Foreground="Gray" FontWeight="Bold" FontSize="16" Padding="0,0,5,0"/>


    Beim Start holt er die einmal ab und danach nicht mehr... Kann sich jemand vorstellen woran es liegt?
    Hi.

    Versuche mal das mit dem Invoke wegzulassen.

    Das sollte bei der Bindung zur Eigenschaft mit dem eingestellten "Mode" und dem "PropertyChanged-Event" automatisch laufen.

    Unde versuche einmal des "wm00_ListOfvSharePointLeihgeraete." im XAML wegzulassen.

    Wenns geht, dann weiter Tippeln, ansonsten mich ankreiden für gefährliches Halbwissen. ;)

    c.u. Joshi aus HH
    @Joshi, hab ich schon alles ausprobiert. geht leider nicht.

    @Christoph1972:

    C#-Quellcode

    1. private wm00_ListOfvSharePointLeihgeraete _wm00_ListOfvSharePointLeihgeraete;
    2. public wm00_ListOfvSharePointLeihgeraete wm00_ListOfvSharePointLeihgeraete
    3. {
    4. get
    5. {
    6. if (_wm00_ListOfvSharePointLeihgeraete == null)
    7. _wm00_ListOfvSharePointLeihgeraete = new wm00_ListOfvSharePointLeihgeraete();
    8. return _wm00_ListOfvSharePointLeihgeraete;
    9. }
    10. }

    Wird nur einmal instantiiert.

    Wenn ich das so mache:

    C#-Quellcode

    1. if (e.PropertyName == "wmBusyTimeFormated" || e.PropertyName == "wmCollection")
    2. lbl.Content = string.Format("{0} | {1}", wm00_ListOfvSharePointLeihgeraete.wmCollection, wm00_ListOfvSharePointLeihgeraete.wmBusyTimeFormated);
    3. else if (e.PropertyName == "wmProgress")
    4. prg.Value = wm00_ListOfvSharePointLeihgeraete.wmProgress;
    5. else if (e.PropertyName == "wmBusyVisibility")
    6. prg.Visibility = wm00_ListOfvSharePointLeihgeraete.wmBusyVisibility;
    , dann geht es... Hätte aber gern gebunden.

    Irgend wie als ob er die Verbindung verlieren würde. Das erste mal geht es. Dann plötzlich nicht mehr...

    Keiner atmet oder zuckt nur mit einem einzige Muskel...

    Waaarte maaaal... Äh Hi.

    C#-Quellcode

    1. private wm00_ListOfvSharePointLeihgeraete _wm00_ListOfvSharePointLeihgeraete;


    Dort sollte das "New" stehen, nicht beim "Getter" (und auch sollte David Guetta dort nicht rumstehen... Ist der eigentlich aus der Mode?).

    Ist ein "Setter" nicht notwendig? Macht ja nicht so viel umstand.

    Wenn der Getter "abgefrag" wird, erstellt er nur dann eine neue Instanz.

    C#-Quellcode

    1. private wm00_ListOfvSharePointLeihgeraete = New _wm00_ListOfvSharePointLeihgeraete();
    2. public wm00_ListOfvSharePointLeihgeraete wm00_ListOfvSharePointLeihgeraete
    3. {
    4. get
    5. {
    6. return _wm00_ListOfvSharePointLeihgeraete;
    7. }
    8. Set
    9. {
    10. If (_wm00_ListOfvSharePointLeihgeraete! = Value)
    11. {
    12. _wm00_ListOfvSharePointLeihgeraete= Value;
    13. OnPropertyChanged("wm00_ListOfvSharePointLeihgeraete");
    14. }
    15. }
    16. }



    In der Annahme das ist im VieModel abgebildet.
    Wenn nicht, mich ankreiden... (Ich glaub das wird mein neuer Fetisch... Mhhh Kreide. Mal Blau, mal Grün... Hust Prust Pffff...)
    Vielleicht mal so. Um mal jetzt so einwenig pekierter als sonst zu wirken, C# ? Was ist das mit den Klammer mal geschweift dann wieder nicht?
    Hauptsache Java und C++ ähnlichkeit... Wer Programmiert denn heutzutage noch in VB? Pfff (Nase hoch... Ich bin NICHT zickig, ich bin Emotional KREATIV!!!!)

    Und ohne den ersten Kaffee, kann ich eh nicht gut (hier ........ Eintragen).

    Die "TimeSpan", der ? "TimeSpan", dann halt ES "TimeSpan".

    Die "wm00_ListOfvSharePointLeihgeraete.wmBusyTimeFormated" ist wohl im CodeBehind, und aber die Änderungen finden für XAML nicht auf der "wm00_ListOfvSharePointLeihgeraete"-Ebene statt sondern in der darunter, dort sollte dann auf für jede Eigenschaft (Property) auch das "OnPropertyChanged" beim "SETTER" getriggert werden.

    ahhh Kaffee ist fertig... Primat macht Pause, und kommt als Mensch zurück.

    c.u. Joshi

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Joshi“ ()

    Was ist das den? Hast dich mehr über Kaffee unterhalten als über das Problem selbst... Und neben bei über VB sich ausgekotzt...

    Wie dem auch sei, das mit dem get und set, mach ich immer so. Geht jedes mal. So stelle ich sicher, dass niemand auf eine nicht initialisierte Instanz zugreift... Wobei das Set ist wirklich nicht nötig.

    Kannst es gern selbst ausprobieren. Bei eigenen Datentypen wird die Referenz weitergegeben. Somit ist ein Set, eigentlich nicht notwendig. Es wird sowieso nur die Adresse hin und her gereicht, selbst dann, wenn du es explizit als "Kopie" in eine Methode weitergeben willst, so wird das eigentliche Objekt geändert...
    Ich habe dein Beispiel mal minimal (ohne dem Invoke im Setter) nachgebaut mit den Infos welche du zur Verfügung gestellt hast.
    Bei mir hat es funktioniert wie es soll. Interessant wäre noch wo du den Wert versuchst zu ändern.

    LG
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten
    hm...

    also der Event kommt aus der klasse public abstract class wmListOfItem<T> : ObservableCollection<T>

    wobei der Event: public event PropertyChangedEventHandler PropertyChanged; ist noch mal in der Liste vorhanden...

    Hast du es auch mal mit dem Invoke ausprobiert. Es wird genau so gut gehen...
    Hi.

    Ok. Mein fehler... Werde auch meine Freizeit nur noch mit Expertenwissen verbringen.

    VB ist meine Programmiersprache.
    Damit habe ich versucht Satirisch auf ein altes "Pferd" zu setzen, um meine Abneigung gegen C# nicht gleich offen zu legen.
    Mea Culpa...

    Zum Thema zurück:

    Ich bevorzuge die Instanziierung einer Klasse im Feld, wenn ich im ViewModel gebundene Eigenschaften proklamiere.

    In deinem Beispiel sehe ich nicht wo die Eigenschaft "wmBusyTime" eine Wertänderung erfährt, und somit kann ich nicht sehen, ob der Wert in der "wm00_ListOfvSharePointLeihgeraete" überhaupt geändert wird.

    XAML sieht verdächtig robust Implementiert aus, genauso die Eigenschaft "wmBusyTime".

    Daher war der Aufruf (wmBusyTimeChanged?.Invoke(this, _wmBusyTime);) , als erster Verdächtiger für mein zutun auszuschliessen.

    Da @fichz das nun ausgeschlossen hat, würde ich das "DataContext" oder besagte Wertänderung, als Fehlerquelle einkreisen.

    Versuchen würde ich einmal das im Getter der Eigenschaft "wmBusyTime" so abzuwandeln.

    C#-Quellcode

    1. return wm00_ListOfvSharePointLeihgeraete.wmBusyTime;


    Achtung: Nur zum Testen, bitte nicht implementieren.

    Wenn das auch nichts wird, dann bitte ich um mehr Quellcode zum aufruf der gebundenen Eigenschaft, und evtl. zur Wertänderung der Eigenschaft "wm00_ListOfvSharePointLeihgeraete.wmBusyTime" und der "wmBusyTime".

    c.u. Joshi aus HH


    Edit: uups zu spät...
    Hier mal mein Projekt damit du siehst was ich meine:

    wm00_ListOfvSharePointLeihgeraete.cs:
    Spoiler anzeigen

    C#-Quellcode

    1. ​using System;
    2. using System.ComponentModel;
    3. namespace TestWpf
    4. {
    5. public class wm00_ListOfvSharePointLeihgeraete : INotifyPropertyChanged
    6. {
    7. private TimeSpan _wmBusyTime;
    8. public TimeSpan wmBusyTime
    9. {
    10. get
    11. {
    12. return _wmBusyTime;
    13. }
    14. set
    15. {
    16. if(_wmBusyTime == value)
    17. return;
    18. _wmBusyTime = value;
    19. //wmBusyTimeChanged?.Invoke(this, _wmBusyTime);
    20. OnPropertyChanged("wmBusyTime");
    21. }
    22. }
    23. public event PropertyChangedEventHandler PropertyChanged;
    24. protected void OnPropertyChanged(string propertyName)
    25. {
    26. var handler = PropertyChanged;
    27. if(handler != null)
    28. handler(this, new PropertyChangedEventArgs(propertyName));
    29. }
    30. }
    31. }


    MainWindowViewModel:
    Spoiler anzeigen

    C#-Quellcode

    1. ​using System.ComponentModel;
    2. namespace TestWpf
    3. {
    4. public class MainWindowViewModel : INotifyPropertyChanged
    5. {
    6. private wm00_ListOfvSharePointLeihgeraete _wm00_ListOfvSharePointLeihgeraete;
    7. public wm00_ListOfvSharePointLeihgeraete wm00_ListOfvSharePointLeihgeraete
    8. {
    9. get
    10. {
    11. if(_wm00_ListOfvSharePointLeihgeraete == null)
    12. _wm00_ListOfvSharePointLeihgeraete = new wm00_ListOfvSharePointLeihgeraete();
    13. return _wm00_ListOfvSharePointLeihgeraete;
    14. }
    15. }
    16. public event PropertyChangedEventHandler PropertyChanged;
    17. protected void OnPropertyChanged(string propertyName)
    18. {
    19. var handler = PropertyChanged;
    20. if(handler != null)
    21. handler(this, new PropertyChangedEventArgs(propertyName));
    22. }
    23. }
    24. }


    MainWindow.xaml:
    Spoiler anzeigen

    XML-Quellcode

    1. ​<Window x:Class="TestWpf.MainWindow"
    2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4. xmlns:viewmodel="clr-namespace:TestWpf"
    5. Title="MainWindow" Height="350" Width="525">
    6. <Window.DataContext>
    7. <viewmodel:MainWindowViewModel x:Name="viewmodel" />
    8. </Window.DataContext>
    9. <Grid>
    10. <Grid.ColumnDefinitions>
    11. <ColumnDefinition />
    12. <ColumnDefinition />
    13. </Grid.ColumnDefinitions>
    14. <Label Grid.Column="0" Content="{Binding Path=wm00_ListOfvSharePointLeihgeraete.wmBusyTime, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
    15. <Button Grid.Column="1" x:Name="btn" Click="btn_Click" />
    16. </Grid>
    17. </Window>


    MainWindow.xaml.cs
    Spoiler anzeigen

    C#-Quellcode

    1. ​using System;
    2. using System.Windows;
    3. namespace TestWpf
    4. {
    5. /// <summary>
    6. /// Interaction logic for MainWindow.xaml
    7. /// </summary>
    8. public partial class MainWindow : Window
    9. {
    10. private int i;
    11. public MainWindow()
    12. {
    13. InitializeComponent();
    14. }
    15. private void btn_Click(object sender, RoutedEventArgs e)
    16. {
    17. i +=1;
    18. var viewmodel = (MainWindowViewModel)this.DataContext;
    19. viewmodel.wm00_ListOfvSharePointLeihgeraete.wmBusyTime = new TimeSpan(1000 * i);
    20. }
    21. }
    22. }


    Hier wird der Wert immer brav erhöht.
    Ich ändere den Wert halt im Codebehind der xaml-Datei (Button_click).

    Die Frage ist wo du den Wert versuchst zu ändern. Das geht aus den Codeschnipsel nicht hervor.

    lg
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten
    Ich nochmal...

    wm00_ListOfvSharePointLeihgeraete.wmBusyTime

    Im ViewModel ist die Eigenschaft wmBusyTime doch gebunden.

    Wo ist der Bezug zur Eltern-Klasse "wm00_ListOfvSharePointLeihgeraete" im XAML?

    XML-Quellcode

    1. <Label Grid.Column="0" Content="{Binding Path=wmBusyTime, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" DataContext="{Binding viewmodel.wm00_ListOfvSharePointLeihgeraete}" />


    Achtung: aus dem Kopf das DataContext geschrieben... bestimmt Falsch. :saint:

    c.u. Joshi
    irgend wie ist es wie verflucht... geht einfach nicht...

    Ich hab das jetzt mit Invoke raus genommen. geht trozdem nicht. vielleicht muss ich euch ein wenig tiefer aufgraben:

    die Liste: wmListOfvSharePointLeihgeraete (hab das jetzt ein wenig umbenannt) wird von der Basisliste wmListOfItem abgeleitet. Die worauf ich binden will, ist die BasisListe Variablen... Die wiederrum wird von ObservableCollection<T> abgeleitet... Sieht dann ungefähr so aus:

    wmListOfvSharePointLeihgeraete -> wmListOfItem -> (ObservableCollection<T>) -> wmBusyTime

    Hat es vielleicht damit was zu tun? Aber eigentlich sollten die Klassen problemlos die Eigenschaften ihrer Eltern erben können...
    Versuche sonst einmal das Binding zu debuggen:
    spin.atomicobject.com/2013/12/11/wpf-data-binding-debug/

    Falls da nichts rauskommt, erstelle ein neues Projekt nur mit den benötigten Klassen und versuche es da.

    lg
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten
    Hi.

    VB.NET-Quellcode

    1. CollectionViewSource.GetDefaultView(DieSuperDuperObservableCollectionImGebundenemViewModel).Refresh()


    Damit konnte ich Eigenschaften im View/UI updaten, die Asynchron in Kind-Eigenschaften/Objekten sich zur laufzeit geändert haben.

    Das ist nur so, weil ich keine INotifyPropertyChandeg in den Model-Klassen implementieren wollte.

    Die asynchrone Methode holt die Daten online ab, und muss das in zwei Schritten machen.

    Dabei ist der zweite Durchlauf nicht mehr aktuallisiert im View, und ".Refresh()" gibt mir eine Auffrischung, die so nicht sein sollte, aber es geschieht nur einmal im ganzen Programm.

    Also einmal die "wmListOfvSharePointLeihgeraete" refreshen, wenn sie eine ObserveableCollection ist, sonst die abgeleitete Collection.

    VB.NET-Quellcode

    1. CollectionViewSource.GetDefaultView(wmListOfvSharePointLeihgeraete).Refresh()


    EDIT: Mal das Beispiel in meinem Fall. Ist nicht zu empfehlen, aber...

    VB.NET-Quellcode

    1. Private Async Function HoleTvDbDaten() As Task
    2. Await TvDbService.StarteTvDbClient
    3. For Each tempserie In SerienListe
    4. Await TvDbService.HoleSerieInfosTvDb(tempserie.TvDbId) 'Innerhalb der Methode "HoleSerienInfosTvDb" sind zwei Aufrufe auf die "tempserie".
    5. CollectionViewSource.GetDefaultView(SerienListe).Refresh() 'Hier dann der Refresh, könnte auch ausserhalb der Schleife geschehen.
    6. Next
    7. End Function




    c.u. Joshi aus HH

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Joshi“ ()