none
Implementierung von INotifyPropertyChanged in einer anderen Klasse RRS feed

  • Frage

  • Hallo zusammen,

    Folgendes Problem: Ich habe 2 ViewModel in meinem Programm. Das eine (FirstPageViewModel) enthält die Daten, welche in den TextBlöcken im View wiedergegeben werden. Das andere ViewModel (NavigationViewModel) ist verantwortlich für die Navigation zwischen meinen Seiten UND soll die Werte der TextBlöcke ändern:

    <StackPanel>
    <Button Content="SecondPage" 
            DataContext="{Binding Source={StaticResource NavigationVM}}" /// reference to App.xaml
            Command="{Binding NavigationCommand}" 
            CommandParameter="SecondPage" />
    <Grid  DataContext="{Binding Source={StaticResource FirstPageViewModel}}">
      <TextBlock  Text="{Binding helloWorld.Counter, UpdateSourceTrigger=PropertyChanged}"/>
      <TextBlock  Text="{Binding helloWorld.Message, UpdateSourceTrigger=PropertyChanged}"/>
        ...
    </Grid>

    Die Navigation stellt kein Problem dar. Wenn ich allerdings probiere die TextBlöcke durch "NavigationCommand" (=Button Click)  zu ändern, passiert nichts:

    (TextBlockSetter führt INotifyPropertyChanged aus)

    public TextBlockSetter _helloWorld;
    
    
        public NavigationViewModel()
        {
    
            _helloWorld = new TextBlockSetter();
    
        }
    
        public TextBlockSetter helloWorld
        {
            get
            {
                return _helloWorld;
            }
            set
            {
                _helloWorld = value;
            }
        }
     private void navigationCommand(object destination)
    {
      switch (destination.ToString())
      {
        case "SecondPage": ///Navigiert zur 2. Seite
          {
    
             ... ///Code for page Navigation
    
            helloWorld.Counter++;
            helloWorld.Message = "done";
            break;
          }
      }
    }

    "FirstPageViewModel" enthält die selbe Implementierung und bestimmt die Ausgangswerte der TextBlöcke:

    static int _roundCounter = 1;
    public TextBlockSetter _helloWorld;
    
        public FirstPageViewModel()
        {
            helloWorld.Counter = _roundCounter;
            _helloWorld = new TextBlockSetter();
    
        }
    
        public TextBlockSetter helloWorld
        {
            get
            {
                return _helloWorld;
            }
            set
            {
                _helloWorld = value;
            }
        }
    Weiß jemand vielleicht, wie man implementiert, dass INotifyPropertyChanged die Änderungen durch NavigationViewModel wahrnimmt? Meine Idee war es in "NavigationViewModel" eine Referenz zu "FirstPageViewModel" zu machen, wenn die TextBlöcke sich ändern sollen. Leider hat keiner meiner Ideen funktioniert.

    Danke für eure Hilfe!

    MfG

    Samstag, 3. September 2016 13:41

Antworten

  • Hi,
    versuche mal, Deinen Code zu überblicken:

    1. Wo erzeugst Du eine Instanz von TextBlockSetter?

    2. Welche Instanz nutzt Du in der Bindung in der Oberfläche und in welcher Instanz änderst Du Counter?

    3. Wie heißen die Schlüssel in den Ressourcenwörterbüchern für die einzelnen ViewModels und in welchen Scopes sind sie gültig?

    Das von mir hochgeladene Beispiel funktioniert bei mir. Warum es bei Dir nicht funktioniert, verstehe ich nicht. Der Schlüssel "NavigationVM" wird entsprechend Deines anderen Beitrages in App.xaml eingetragen. Warum er diesen Schlüssel nicht findet, kann ich nicht sagen.

    ... Außerdem frage ich mich, wie im FirstPageViewModel die Werte setzen soll (helloWorld.Counter = 1) ohne: set {_helloWorld = value;}

    Was Du da machen sollst, kannst Du nur aus der Aufgabenstellung erfahren. Deine set-Methode muss in dem Objekt ausgeführt werden, welches an die Oberfläche gebunden ist und die Veränderung an die Oberfläche melden soll. In meinem Beispiel anhand Deiner Codeschnipsel ist das das Objekt vom Typ "TextBlockSetter". Wenn Du in "FirstPageViewModel" den Wert der Counter-Eigenschaft des TextBlockSetter-Objektes veränderst, muss es dasselbe Objekt sein, welches auch an die Oberfläche gebunden ist, damit die Änderungen auch sichtbar werden. Der "FirstPageViewModel" kann nur Veränderungen seiner Eigenschaften mit Deiner set-Methode an die Oberfläche melden, nicht die Veränderungen im TextBlockSetter-Objekt. Das muss das TextBlockSetter-Objekt selbst machen (s. mein Code, der aus Deinem Code abgeleitet ist).


    --
    Viele Grüsse
    Peter Fleischer (MVP, Partner)
    Meine Homepage mit Tipps und Tricks
    Warum Groß- und Kleinschreibung wichtig ist:
    Der Gefangene floh.
    Der gefangene Floh.

    Samstag, 3. September 2016 16:08

Alle Antworten

  • Hi MfG,
    ich hatte Dir doch die Lösung gepostet. In Deinem Codeauszug erzeugst die mehrere Instanzen (Objekte) der Klasse TextBlockSetter. Du änderst Counter in einer Instanz und nutzt aber für die Anzeige die andere Instanz. Mein Beispiel habe ich auf Github hochgeladen.


    --
    Viele Grüsse
    Peter Fleischer (MVP, Partner)
    Meine Homepage mit Tipps und Tricks
    Warum Groß- und Kleinschreibung wichtig ist:
    Der Gefangene floh.
    Der gefangene Floh.

    Samstag, 3. September 2016 13:58
  • Hey,

    Tut mir leid für das doppel Posting, aber ich bin aus deiner Antwort nicht wirklich schlau geworden und wollte dann auch nicht zum wiederholten mal auf die Problemstellung eingehen.

    public TextBlockSetter helloWorld
        {
          get
          {
            return ((NavigationViewModel)Application.Current.FindResource("NavigationVM")).helloWorld;
          }
        }

    wenn ich das in meine Code einfüge, dann erhalte ich nur den Error, dass "NavigationVM" nicht gefunden werden kann. Außerdem frage ich mich, wie im FirstPageViewModel die Werte setzen soll (helloWorld.Counter = 1) ohne:

    set {_helloWorld = value;}


    Samstag, 3. September 2016 15:33
  • Hi,
    versuche mal, Deinen Code zu überblicken:

    1. Wo erzeugst Du eine Instanz von TextBlockSetter?

    2. Welche Instanz nutzt Du in der Bindung in der Oberfläche und in welcher Instanz änderst Du Counter?

    3. Wie heißen die Schlüssel in den Ressourcenwörterbüchern für die einzelnen ViewModels und in welchen Scopes sind sie gültig?

    Das von mir hochgeladene Beispiel funktioniert bei mir. Warum es bei Dir nicht funktioniert, verstehe ich nicht. Der Schlüssel "NavigationVM" wird entsprechend Deines anderen Beitrages in App.xaml eingetragen. Warum er diesen Schlüssel nicht findet, kann ich nicht sagen.

    ... Außerdem frage ich mich, wie im FirstPageViewModel die Werte setzen soll (helloWorld.Counter = 1) ohne: set {_helloWorld = value;}

    Was Du da machen sollst, kannst Du nur aus der Aufgabenstellung erfahren. Deine set-Methode muss in dem Objekt ausgeführt werden, welches an die Oberfläche gebunden ist und die Veränderung an die Oberfläche melden soll. In meinem Beispiel anhand Deiner Codeschnipsel ist das das Objekt vom Typ "TextBlockSetter". Wenn Du in "FirstPageViewModel" den Wert der Counter-Eigenschaft des TextBlockSetter-Objektes veränderst, muss es dasselbe Objekt sein, welches auch an die Oberfläche gebunden ist, damit die Änderungen auch sichtbar werden. Der "FirstPageViewModel" kann nur Veränderungen seiner Eigenschaften mit Deiner set-Methode an die Oberfläche melden, nicht die Veränderungen im TextBlockSetter-Objekt. Das muss das TextBlockSetter-Objekt selbst machen (s. mein Code, der aus Deinem Code abgeleitet ist).


    --
    Viele Grüsse
    Peter Fleischer (MVP, Partner)
    Meine Homepage mit Tipps und Tricks
    Warum Groß- und Kleinschreibung wichtig ist:
    Der Gefangene floh.
    Der gefangene Floh.

    Samstag, 3. September 2016 16:08