4

我正在尝试将来自我的孩子 ViewModel 的事件传回给父母。子视图模型的视图是一个单独的窗口,我相信我无法将构造函数参数传递给它。此视图上的按钮需要触发父 ViewModel 上的方法。

子视图模型:

public ConnectViewModel(ConnectEvents connectEvents)
{
    ConnectEvents = connectEvents;
}

父视图模型

public MainWindowViewModel()
{
    ConnectEvents connectEvents = new ConnectEvents();
    ConnectViewModel = new ConnectViewModel(connectEvents);
    connectEvents.ThrowEvent += ConnectToServer;
}

我如何在这两者之间进行交流?有没有更好的系统,或者我怎样才能让父母订阅孩子?

4

4 回答 4

8

你有很多选择。您可以使用自定义事件,也可以直接使用委托,您可以在父 ViewModel 中订阅PropertyChangedCollectionChanged事件,使用普通订阅或弱事件模式

我更喜欢最后一个,因为不需要退订。

于 2013-10-10T04:44:57.517 回答
7

您可以制作自己的 EventAggregator

public static class DumbAggregator
{
  public static void BroadCast(string message)
  {
   if (OnMessageTransmitted != null)
       OnMessageTransmitted(message);
  }

 public static Action<string> OnMessageTransmitted;
}

用法:

  public class MySender
  {
    public void SendMessage()
    {
      DumbAggregator.BroadCast("Hello There!");
    }
  }

public class MySubscriber
{
  public MySubscriber()
  {
   DumbAggregator.OnMessageTransmitted += OnMessageReceived;
  }

 private void OnMessageReceived(string message)
 {
  MessageBox.Show("I Received a Message! - " + message);
 }
}

并在此帮助下,您可以与您的视图模型进行通信

于 2013-10-10T04:43:31.307 回答
2

使用事件传达“事件”

在您的 ConnectViewModel...

public ConnectViewModel(ConnectEvents connectEvents)
{
    public event EventHandler<EventArgs> SomethingHappenedEvent;

     ...

     private void DoSomething()
     {
          if (SomethingHappenedEvent != null)
          {
              SomethingHappenedEvent(this, newEventArgs());
          }
     }

     RelayComand _somethingCommand;
     public ICommand SomethingHappenedCommand
     {   
          get
          {
              if (_someethingCommand == null)
                   _somethingCommand = new RelayCommand(DoSomething)
           }
     }
}

在你的 MainWindowViewModel

public MainWindowViewModel()
{
    ConnectEvents connectEvents = new ConnectEvents();
    ConnectViewModel = new ConnectViewModel(connectEvents);
    ConnectViewModel.SomethingHappenedEvent += HandleSomethingHappened;
    connectEvents.ThrowEvent += ConnectToServer;
}
private void HandleSomethingHappened(object sender, EventArgs e)
{
    // Now your mainviewmodel knows that something happened
}
于 2013-10-10T04:41:37.947 回答
0

这是一个使用已接受答案中提到的WeakEventManager的示例。

namespace Stuff {
    using System;
    using System.Windows;

    // An "event bus" public to all view models.
    public sealed class Events {
        public static Events Instance { get; } = new Events();

        public event EventHandler<EventArgs>? SomethingHappend;

        private Events() { }

        public static void RaiseSomethingHappend(object? sender = null)
            => Instance.SomethingHappend?.Invoke(sender ?? Instance, EventArgs.Empty);
    }

    // A view model that wants to listen to one or more events.
    public class Listener {
        public Listener() {
            WeakEventManager<Events, EventArgs>.AddHandler(
                source: Events.Instance,
                eventName: nameof(Events.SomethingHappend),
                Handle);
        }

        private void Handle(object? sender, EventArgs args) { }
    }

    // A view model that raises events.
    public class Source {
        public void Foo() {
            Events.RaiseSomethingHappend();
        }
    }
}
于 2021-03-28T11:32:33.470 回答