[英]How to Create a Child Window From Parent in MVVM Light and WPF?
我的主窗口上有一个按钮。 当我单击它时,我希望在主窗口顶部弹出另一个窗口。
主窗口仍然可见,并且应该是该新窗口的父窗口。
我一直在环顾四周,但不确定如何做到这一点,有人建议使用Messenger来执行此操作,但并没有给出任何示例。
嗨,我没有MVVMLight,所以我使用了自定义Messanger,因为它使画面更清晰。
消息类型
public enum MessageType
{
DataLoaded,
OpenWindow,
SetFocus,
OpenExceptionWindow,
Refresh
//etc
}
信息
public class Message
{
public Message(MessageType messageType, object message)
{
MessageType = messageType;
MessageObject = message;
}
public MessageType MessageType { get; private set; }
public object MessageObject { get; private set; }
}
信使
public class Messanger
{
//Singleton
private Messanger()
{ }
static Messanger instance;
public static Messanger Instance
{
get{return instance ?? (instance=new Messanger());}
}
static Dictionary<string, Action<Message>> dictionary = new Dictionary<string, Action<Message>>();
//View Calls this and register the delegate corresponding to the unique token
public void Register(string token,Action<Message> action)
{
if (dictionary.ContainsKey(token))
throw new Exception("Already registered");
if (action == null)
throw new ArgumentNullException("action is null");
dictionary.Add(token, action);
}
public void UnRegister(string token)
{
if(dictionary.ContainsKey(token))
dictionary.Remove(token);
}
//ViewModel Calls this and pass the token and Message.
//the registered delegate is looked up in dictionary corresponding to that token and
//Corresponding register delegate fired.
public void SendMessage(string token,Message message)
{
if (dictionary.ContainsKey(token))
dictionary[token](message);
}
}
ViewBase
public class ViewBase:Window
{
protected string Token { get; private set; }
public ViewBase()
{
Token = Guid.NewGuid().ToString();
//Register to Messanger
Messanger.Instance.Register(Token, HandleMessages);
//UnRegister On Closing or Closed
this.Closing +=(s,e)=> Messanger.Instance.UnRegister(Token);
}
//Handle Common Messages to all Windows Here
void HandleMessages(Message message)
{
switch (message.MessageType)
{
case MessageType.OpenExceptionWindow:
Exception ex = message.MessageObject as Exception;
ExceptionWindow window = new ExceptionWindow();
window.Exception = ex;
window.ShowDialog();
break;
//other common cases should be handled here
default : HandleWindowLevelMessage(message);
break;
}
}
protected virtual void HandleWindowLevelMessage(Message message)
{
}
}
视图
public partial class Mywindow : ViewBase
{
public Mywindow()
{
InitializeComponent();
DataContext = new MyViewModel(Token);
}
protected override void HandleWindowLevelMessage(Message message)
{
//open window according to OP Requirement
if (message.MessageType == MessageType.OpenWindow)
{
string windowName = message.ToString();
if (windowName != null)
{
//logic to get the window . I assume that OP have some logic to get the child window this is just temporary
var window = Application.Current.Windows.OfType<Window>().FirstOrDefault(s=>s.Name==windowName);
if (window != null)
{
window.Owner=this;
window.Show();
}
}
}
base.HandleWindowLevelMessage(message);
}
}
View.xaml这里的第一个元素不是Window
<local:ViewBase x:Class="WpfApplication4.Mywindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication4"
Title="Mywindow" Height="300" Width="300">
<Grid>
<Button Content="ok" Click="Button_Click_1"/>
</Grid>
ViewModelBase
public class ViewModelBase : INotifyPropertyChanged
{
public ViewModelBase(string token)
{
Token = token;
}
protected string Token { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
void RaisePropertyChanged(string propName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
视图模型
public class MyViewModel : ViewModelBase
{
public MyViewModel(string token)
: base(token)
{
}
//say OP want to open window on Command Execute
public void OnCommand()
{
Messanger.Instance.SendMessage(Token, new Message(MessageType.OpenWindow, "MyChildWindow"));
}
}
我希望这将有所帮助。 这是易于理解的简单代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.