c# - 从子视图 mvvm 返回数据
问题描述
我第一次在 wpf mvvm 工作,我在“现实生活中的问题”中遇到了一些问题
我有一个带有视图的 ViewModel,我必须从那里打开第二个视图(带有它的 ViewModel,它将有一个对象列表),在这里,我必须选择一个对象,将其返回到第一个 ViewModel,我将使用它。
我正在使用一种简单的方法打开第二个窗口,我知道我有点破坏了 mvvm 模式
public object ShowDialog<TView, TViewModel>(TViewModel dataContext) where TView : IWindow, new() where TViewModel : BaseViewModel<TViewModel>
{
//Instancio la vista.
TView view = new TView();
WindowService wnd = new WindowService(view);
dataContext?.SetWindowService(wnd);
view.DataContext = dataContext;
view.ShowDialog();
return dataContext;
}
在 ViewModel 中我像这样打开第二页
WindowService.ShowDialog<ChooseOneCat, ChooseOneCatViewModel>(null);
然后在ChooseOneCat
ViewModel 中,我让用户选择我以后必须返回的类别
这是我的问题,我怎样才能将该对象提供给第一个视图模型?
Pd:我不使用任何额外的框架。
谢谢!
解决方案
我设法使用messenger解决了这个问题,特别是我在Dalstroem 响应中找到的一个实现
源代码:
using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; namespace Application.Messaging { public class Messenger { private static readonly object CreationLock = new object(); private static readonly ConcurrentDictionary<MessengerKey, object> Dictionary = new ConcurrentDictionary<MessengerKey, object>(); #region Default property private static Messenger _instance; /// <summary> /// Gets the single instance of the Messenger. /// </summary> public static Messenger Default { get { if (_instance == null) { lock (CreationLock) { if (_instance == null) { _instance = new Messenger(); } } } return _instance; } } #endregion /// <summary> /// Initializes a new instance of the Messenger class. /// </summary> private Messenger() { } /// <summary> /// Registers a recipient for a type of message T. The action parameter will be executed /// when a corresponding message is sent. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="recipient"></param> /// <param name="action"></param> public void Register<T>(object recipient, Action<T> action) { Register(recipient, action, null); } /// <summary> /// Registers a recipient for a type of message T and a matching context. The action parameter will be executed /// when a corresponding message is sent. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="recipient"></param> /// <param name="action"></param> /// <param name="context"></param> public void Register<T>(object recipient, Action<T> action, object context) { var key = new MessengerKey(recipient, context); Dictionary.TryAdd(key, action); } /// <summary> /// Unregisters a messenger recipient completely. After this method is executed, the recipient will /// no longer receive any messages. /// </summary> /// <param name="recipient"></param> public void Unregister(object recipient) { Unregister(recipient, null); } /// <summary> /// Unregisters a messenger recipient with a matching context completely. After this method is executed, the recipient will /// no longer receive any messages. /// </summary> /// <param name="recipient"></param> /// <param name="context"></param> public void Unregister(object recipient, object context) { object action; var key = new MessengerKey(recipient, context); Dictionary.TryRemove(key, out action); } /// <summary> /// Sends a message to registered recipients. The message will reach all recipients that are /// registered for this message type. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="message"></param> public void Send<T>(T message) { Send(message, null); } /// <summary> /// Sends a message to registered recipients. The message will reach all recipients that are /// registered for this message type and matching context. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="message"></param> /// <param name="context"></param> public void Send<T>(T message, object context) { IEnumerable<KeyValuePair<MessengerKey, object>> result; if (context == null) { // Get all recipients where the context is null. result = from r in Dictionary where r.Key.Context == null select r; } else { // Get all recipients where the context is matching. result = from r in Dictionary where r.Key.Context != null && r.Key.Context.Equals(context) select r; } foreach (var action in result.Select(x => x.Value).OfType<Action<T>>()) { // Send the message to all recipients. action(message); } } protected class MessengerKey { public object Recipient { get; private set; } public object Context { get; private set; } /// <summary> /// Initializes a new instance of the MessengerKey class. /// </summary> /// <param name="recipient"></param> /// <param name="context"></param> public MessengerKey(object recipient, object context) { Recipient = recipient; Context = context; } /// <summary> /// Determines whether the specified MessengerKey is equal to the current MessengerKey. /// </summary> /// <param name="other"></param> /// <returns></returns> protected bool Equals(MessengerKey other) { return Equals(Recipient, other.Recipient) && Equals(Context, other.Context); } /// <summary> /// Determines whether the specified MessengerKey is equal to the current MessengerKey. /// </summary> /// <param name="obj"></param> /// <returns></returns> public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; if (obj.GetType() != GetType()) return false; return Equals((MessengerKey)obj); } /// <summary> /// Serves as a hash function for a particular type. /// </summary> /// <returns></returns> public override int GetHashCode() { unchecked { return ((Recipient != null ? Recipient.GetHashCode() : 0) * >397) ^ (Context != null ? Context.GetHashCode() : 0); } } } } }
推荐阅读
- python-3.6 - 单独打包时,哪些文件夹将包含在无服务器功能中?
- .net - 在 Windows 10 上停止 oracle 客户端连接
- css - 混合混合模式闪烁问题
- python - itertools / takewhile -> 给了我意想不到的结果 [0]
- sql - Oracle - PLSQL / 如果已进行更新,则插入一行
- php - 在数据库数据透视表 Laravel 中存储数据
- delphi - 如何在 EWS SOAP 响应中获取更详细的错误信息?
- ios - 通过 automaticMergesChangesFromParent 同步还是异步获取更改?
- mysql - 仅在满足所有 CASE 语句条件时才显示行
- angular - Angular Material Table filterPredicate 过滤对象