如何从用户控件视图模型中关闭窗口?

时间:2012-06-15 09:30:56

标签: c# wpf user-controls viewmodel datacontext

我有一个窗口,它将各种UserControl作为页面托管。是否可以在usercontrol的datacontext中关闭我没有引用的窗口? 简化细节:

SetupWindow

    public SetupWindow()
    {
        InitializeComponent();
        Switcher.SetupWindow = this;
        Switcher.Switch(new SetupStart());  
    }

    public void Navigate(UserControl nextPage)
    {
        this.Content = nextPage;
    }

SetupStart UserControl

<UserControl x:Class="...">
 <UserControl.DataContext>
    <local:SetupStartViewModel/>
 </UserControl.DataContext>
 <Grid>
    <Button Content="Continue" Command="{Binding ContinueCommand}"/>
 </Grid>
</UserControl>

SetupStartViewModel

    public SetupStartViewModel()
    {
    }

    private bool canContinueCommandExecute() { return true; }

    private void continueCommandExectue()
    {
        Switcher.Switch(new SetupFinish());
    }

    public ICommand ContinueCommand
    {
        get { return new RelayCommand(continueCommandExectue, canContinueCommandExecute); }
    }

3 个答案:

答案 0 :(得分:5)

我这样做是因为我的ViewModel中有一个RequestClose事件,当它希望视图关闭时它可以引发。

然后通过创建窗口的代码将其连接到窗口的Close()命令。例如

var window    = new Window();
var viewModel = new MyViewModel();

window.Content = viewModel;
viewModel.RequestClose += window.Close;

window.Show()

这样,所有与窗口创建有关的事情都在一个地方处理。视图或视图模型都不知道窗口。

答案 1 :(得分:5)

我设法从答案中找到了解决方案:How to bind Close command to a button

查看 - 型号:

public ICommand CloseCommand
{
    get { return new RelayCommand<object>((o) => ((Window)o).Close(), (o) => true); }
}

查看:

<Button Command="{Binding CloseCommand}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" Content="Close"/>

答案 2 :(得分:3)

在用户控件中,您可以在Window类上找到对使用静态方法托管它的窗口的引用。

var targetWindow = Window.GetWindow(this);
targetWindow.Close();

修改

如果你没有引用用户控件,你没有使用数据上下文,那么如果只有一个应用程序窗口,你可以使用

Application.Current.MainWindow.Close()

如果您的应用程序中有许多窗口并且您要关闭的窗口是焦点,您可以通过类似

的内容找到它
public Window GetFocusWindow()
{
    Window results = null;
    for (int i = 0; i < Application.Current.Windows.Count; i ++)
        if (Application.Current.Windows[i].IsFocused)
        {
            results = Application.Current.Windows[i];
            break;
        }
    return results;
}

最后我想(虽然这很漂亮)你可以循环遍历应用程序窗口类,检查可视树中每个对象的数据上下文,直到找到你想要的引用,窗口可以从关闭那里。