我正在尝试将我的孩子ViewModel中的事件传递回父母。子视图模型的视图是一个单独的窗口,我相信我无法传递构造函数参数。此视图上的按钮需要在父ViewModel上触发方法。
Child ViewModel:
public ConnectViewModel(ConnectEvents connectEvents)
{
ConnectEvents = connectEvents;
}
父ViewModel
public MainWindowViewModel()
{
ConnectEvents connectEvents = new ConnectEvents();
ConnectViewModel = new ConnectViewModel(connectEvents);
connectEvents.ThrowEvent += ConnectToServer;
}
我如何在这两者之间进行沟通?是否有更好的系统,或者我如何允许父母订阅孩子?
答案 0 :(得分:5)
你有很多选择。您可以使用custom event,您可以直接使用delegate,您可以使用普通订阅在您的父ViewModel中订阅PropertyChanged或CollectionChanged事件,或{{3 }}
我更喜欢最后一个,因为没有必要取消订阅。
答案 1 :(得分:4)
您可以制作自己的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);
}
}
在此帮助下,您可以与视图模型进行通信
答案 2 :(得分: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
}
答案 3 :(得分: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();
}
}
}