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



我有一个窗口,它托管各种UserControl的页面。是否可以关闭用户控件的数据上下文中没有引用的窗口?简化细节:

设置窗口

    public SetupWindow()
    {
        InitializeComponent();
        Switcher.SetupWindow = this;
        Switcher.Switch(new SetupStart());  
    }
    public void Navigate(UserControl nextPage)
    {
        this.Content = nextPage;
    }

设置启动用户控件

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

设置开始视图模型

    public SetupStartViewModel()
    {
    }
    private bool canContinueCommandExecute() { return true; }
    private void continueCommandExectue()
    {
        Switcher.Switch(new SetupFinish());
    }
    public ICommand ContinueCommand
    {
        get { return new RelayCommand(continueCommandExectue, canContinueCommandExecute); }
    }

我设法从这里的答案中找到了一个解决方案: 如何将关闭命令绑定到按钮

视图模型:

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"/>

我通过在 ViewModel 中设置一个 RequestClose 事件来实现这一点,当它希望关闭视图时,它可以引发该事件。

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

var window    = new Window();
var viewModel = new MyViewModel();
window.Content = viewModel;
viewModel.RequestClose += window.Close;
window.Show()

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

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

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

编辑:

如果您没有引用正在使用数据上下文的用户控件,那么您没有大量的选择,如果只有 1 个应用程序窗口,您可以侥幸逃脱

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

最后,我想(尽管这很好)您可以遍历应用程序窗口类,检查可视化树中每个对象的数据上下文,直到找到所需的引用,窗口可以从那里关闭。

相关内容

  • 没有找到相关文章

最新更新