2012-05-31 48 views
1

我是新来的MVVM,并在其自己的视图模型C#-file碰到问题如何打开一个对话框,关闭后的对话框。搜索可能的解决方案,发现什么都不合适 我的解决方案如下所示,但我不确定这是否有一些缺点。 定义的用户控件,并打开它:WPF用户控件MVVM如何关闭对话框

void ChangeDataPathExecute() 
{ 
    Window window = new Window 
    { 
     Content = new ChangeDataRootPathUserControl(), 
    }; 

    window.ShowDialog(); 
} 

在用户控件文件的视图模型实现:

void OkChangeDataRootPathExecute() 
{ 
    DetermineMyWindow(); 

    myWindow.Close(); 
} 

你怎么想:

private void DetermineMyWindow() 
{ 
    foreach (Window window in App.Current.Windows) 
    { 
     ChangeDataRootPathUserControl uc = window.Content as ChangeDataRootPathUserControl; 
     if (uc == null) 
      continue; 

     myWindow = window; 
    } 
在关闭方法

最后对这个?黑客或好的解决方案? 感谢您的反馈 节拍

回答

1

您可以通过从UserControl内部引用this.Parent(只要它是第一个内容元素)来更容易地访问该窗口。

你正在试图做的是创建一个新的XAML文件的窗口,把你的用户控件的一个实例,在XAML窗口里面有什么更正统的方法。

如果你希望你的用户控件能够关闭它的父窗口,那么一个简单的关闭事件添加到用户控件。现在在您的Window XAML中,您可以将事件处理程序添加到关闭事件中,并在UserControl引发事件时让窗口调用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,边框等,来控制你的对话框的外观和感觉。

然后,当你想展示你的代码中的对话框,你写这样的:

void ChangeDataPathExecute() 
{ 
    var window = new ChangeDataRootPathWindow(); 

    window.ShowDialog(); 
} 
2

ViewModel在MVVM情况下不应该知道的事情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; 
    } 
} 
+0

感谢这个想法。 我会说这是所谓的“后面的代码”,我试图避免 – Vik

0

您的视图模型应该只是开个DialogService。看看here得到一个起点。

+0

感谢您的链接。 我试图避免的是 _...在创建对话框的模块中对对话结果..._ 执行任何操作。作为一名初学者,我期望在对话本身的密切行动中实现这一点 – Vik

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

感谢您的支持。我认为那样更好 – Vik

-1

这件怎么样?

Window parentWindow = (Window)this.Parent; 
parentWindow.Close();