Laden...

WPF mit MVVM Komunikation zwischen zwei ViewModels?

Erstellt von Heppy vor 5 Jahren Letzter Beitrag vor 5 Jahren 994 Views
H
Heppy Themenstarter:in
5 Beiträge seit 2019
vor 5 Jahren
WPF mit MVVM Komunikation zwischen zwei ViewModels?

Hallo allerseits,
Ich stecke grade in einem Vorgang fest und bin mir nicht sicher wie ich weiter komme vielleicht kann mir jemand mal auf die Sprünge helfen.

In meinem MainWindow befindet sich ein Frame welches mittels Binding eine seite aufruft, was auch ganz gut funktioniert, jetzt mochte ich auf auf der aufgerufenen seite einen Knopf haben welche das Frame vom MainWindow eine andere seite Laden läst.

Main View Klasse


public class MainViewModel : ViewModelBase
    {
        /// <summary>
        /// Initializes a new instance of the MainViewModel class.
        /// </summary>
        public MainViewModel()
        {
            if (Properties.Settings.Default.ErsterStart)
            {
                FrameUri = ViewModelLocator.EinstellungenSeiteUri;
            }
            else
            {
                FrameUri = ViewModelLocator.AnmeldungSeiteUri;
            }
        }

        public Uri FrameUri { get; set; }
    }

Einstellungen Klasse:


public class EinstellungenViewModel : ViewModelBase
    {
        public Uri EinstellungenFrameUri { get; set; }
        public List<string> EinstellungKategorie { get; private set; }

        private string _einstellungKategorieAuswahl;
        public RelayCommand Einstellungen_Speichern_Befehl { get; private set; }

        public string EinstellungKategorieAuswahl
        {
            get { return _einstellungKategorieAuswahl; }
            set
            {
                switch (value)
                {
                    case "Datenbank":
                        EinstellungenFrameUri = ViewModelLocator.EinstellungenDatenbankUri;
                        break;
                }
                _einstellungKategorieAuswahl = value;
            }
        }

        public EinstellungenViewModel()
        {
            Einstellungen_Speichern_Befehl = new RelayCommand(Einstellungen_Speichern);
            EinstellungKategorie = new List<string>();
            EinstellungKategorie.Add("Datenbank");
            EinstellungKategorieAuswahl = "Datenbank";
        }

        public void Einstellungen_Speichern()
        {
            Properties.Settings.Default.Save();
            Trace.TraceInformation("Speichern Gedrückt");
        }
    }

Also Kurz gesagt wenn in der Einstellungen Klasse Einstellungen Speichern ausgelöst wird möchte ich das in der Main View Klasse die FrameUri neu Gesetzt wird und die Main UI neu geladen wird mit dem neuen Frame.

Ich hab keinen schimmer wie ich das realisieren soll oder ob es da einen anderen weg gibt oder sogar ein komplett anderer aufbau besser wäre.

Ich wäre für jede hilfe dankbar.

Leben ist das, was passiert
Wenn du woander so beschäftigt bist.

301 Beiträge seit 2009
vor 5 Jahren

Wenn deine Main Komponente eine Referenz auf deine Einstellungskomponente hat ( was allerdings nicht danach aussieht ) könntest du es über ein einfaches Event lösen.

Eine andere Variante, die ähnlich funktioniert, wäre ein Messaging System in deiner Anwendung einzusetzen. Dadurch würde deine Einstellungskomponente eine Nachricht über einen MessageBus senden und deine Main Komponente jegliche Nachrichten dieser Art empfangen und behandeln auch ohne eine direkte Referenz auf die Instanz zu haben. Für einen MessageBus gibt es bereits verschiedene Implementierungen am besten einfach mal danach googlen.

Eine dritte Variante wäre glaub ich auch der Einsatz von MediatR. Ich weiß allerdings nicht ob das in deinem Fall mit Raketen auf Spatzen geschossen ist.

EDIT: Falls du MvvmLight einsetzt -> das Framework hat glaube ich bereits einen internen Messagebus
Falls du Prism nutzt -> Auch da gibt es mWn eine integrierte Pipeline

H
Heppy Themenstarter:in
5 Beiträge seit 2019
vor 5 Jahren

Ja aber natürlich ach man ich hab an viel zu komplizierte dinge gedacht und das direkt vor der nase liegende einfach übersehen. Danke vielmals hab es jetzt mit dem Messaging System von MVVM Light gemacht.

Sender:


MessengerInstance.Send<NotificationMessage<string>>(new NotificationMessage<string>("HAUPTFRAME", "ZURÜCK"));

Empfänger:


public class MainViewModel : ViewModelBase
    {
        public MainViewModel()
        {
              MessengerInstance.Register<NotificationMessage<string>>(this, NotifyMe);
        }
    }


private void NotifyMe(NotificationMessage<string> obj)
        {
            string notification = obj.Notification;
            string genericValue = obj.Content;
            if(genericValue.Equals("HAUPTFRAME"))
            {
                if(notification.Equals("ZURÜCK"))
                {
                    if(FrameUriAlt == null)
                    {
                        FrameUri = ViewModelLocator.HauptSeiteUri;
                    }
                    else
                    {
                        FrameUri = FrameUriAlt;
                    }
                }
            }
            Trace.TraceInformation(notification + " -> " + genericValue);
        }

Leben ist das, was passiert
Wenn du woander so beschäftigt bist.

301 Beiträge seit 2009
vor 5 Jahren

Ich würde die empfehlen mit echten Typen bei den Nachrichten zu arbeiten. Im Optimalen Fall hast du für jede Nachricht einen eigenen Typen.

Mit den Magic Strings wirst du dir auf Dauer keinen Gefallen tun.