我是MVVM的新手,遇到了如何打开对话框并在其自己的ViewModel c#-file中关闭对话框的问题。搜索可能的解决方案,找不到合适的。 我的解决方案如下所示,但我不确定这是否有一些缺点。 定义UserControl并使用以下命令打开它:
void ChangeDataPathExecute()
{
Window window = new Window
{
Content = new ChangeDataRootPathUserControl(),
};
window.ShowDialog();
}
在UserControl文件的ViewModel中实现:
private void DetermineMyWindow()
{
foreach (Window window in App.Current.Windows)
{
ChangeDataRootPathUserControl uc = window.Content as ChangeDataRootPathUserControl;
if (uc == null)
continue;
myWindow = window;
}
最后在Close方法中:
void OkChangeDataRootPathExecute()
{
DetermineMyWindow();
myWindow.Close();
}
您如何看待这个?黑客或好的解决方案? 感谢您的反馈 打
答案 0 :(得分:2)
MVVM场景中的ViewModel
不应该对View
有任何了解。在你的例子中,它似乎必须对视图有很多了解。
许多人使用许多不同的模式来打开/关闭ViewModel中的窗口。我更喜欢事件/回调:
class ViewModel {
public event EventHandler ChangeDataRootPath;
}
class View : Window {
public View() {
InitializeComponent();
var vm = new ViewModel();
vm.ChangeDataRootPath += (s, e) => {
Window window = new Window {
Content = new ChangeDataRootPathUserControl {
DataContext = vm
}
};
window.ShowDialog();
};
DataContext = vm;
}
}
答案 1 :(得分:1)
您可以通过从UserControl内部引用this.Parent(只要它是第一个内容元素)更轻松地访问窗口。
您正在尝试做的更正统的方法是为Window创建一个新的XAML文件,将一个UserControl实例放在XAML中的Window中。
如果您希望UserControl能够关闭其父窗口,则将一个简单的Close事件添加到UserControl。现在,在您的Window XAML中,您可以向close事件添加一个事件处理程序,并在UserControl引发事件时让Window调用Close()。
// UserControl.cs
public event EventHandler Close;
void OkChangeDataRootPathExecute()
{
if (Close != null)
Close(this, EventArgs.Empty);
}
// Window.cs
void UserControl_Close(object sender, EventArgs e)
{
Close();
}
然后,如果你想添加任何额外的选项或样式,你可以将它添加到你的XAML,如SizeToContent,WindowStartupLocation,BorderStyle等,以控制你的对话框的外观。
然后,当您想要在代码中显示对话框时,您可以将其写为:
void ChangeDataPathExecute()
{
var window = new ChangeDataRootPathWindow();
window.ShowDialog();
}
答案 2 :(得分:0)
您的viewmodel应该只打开 DialogService 。看here得到一个起点。
答案 3 :(得分:0)
在我的个人实现中,我不会让我的视图模型知道有关窗口,用户控件或任何其他可视元素的任何信息。但这需要整个框架的定义。有很多,只需搜索并使用最适合你的那个。
但是对于快速解决方案,如果您要从任何地方关闭的窗口是当前具有焦点的窗口,您可以使用此方法来访问它:
public static Window GetCurrentFocusedWindow()
{
Window window = null;
Control currentControl = System.Windows.Input.Keyboard.FocusedElement as Control;
if (currentControl != null)
window = Window.GetWindow(currentControl);
return window;
}
答案 4 :(得分:-1)
如果你打算做MVVM,you'll want an MVVM framework。我推荐Caliburn.Micro,并查看其window manager。
答案 5 :(得分:-1)
这个怎么样?
Window parentWindow = (Window)this.Parent;
parentWindow.Close();