gpt4 book ai didi

c# - 如何在MVVM Light和WPF中从父级创建子级窗口?

转载 作者:行者123 更新时间:2023-12-03 10:47:18 25 4
gpt4 key购买 nike

我的主窗口上有一个按钮。当我单击它时,我想在主窗口顶部弹出另一个窗口。

主窗口仍然可见,并且应该是该新窗口的父窗口。

我一直在环顾四周,但不确定如何做到这一点,有人建议使用Messenger来执行此操作,但并没有给出任何示例。

最佳答案

嗨,我没有MVVMLight,所以我使用了自定义Messanger,因为它使画面更清晰。

MessageType


public enum MessageType
{
DataLoaded,
OpenWindow,
SetFocus,
OpenExceptionWindow,
Refresh
//etc
}

Message


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; }
}

Messanger


    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)
{

}

}

View


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 Here first element is not Window now


<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));
}
}

ViewModel


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"));
}
}

我希望这将有所帮助。这是易于理解的简单代码。

关于c# - 如何在MVVM Light和WPF中从父级创建子级窗口?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21055210/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com