5

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

设置窗口

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

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

SetupStart 用户控制

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

设置StartViewModel

    public SetupStartViewModel()
    {
    }

    private bool canContinueCommandExecute() { return true; }

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

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

3 回答 3

6

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

视图模型:

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"/>
于 2012-07-09T13:30:38.727 回答
5

我通过RequestClose在我的 ViewModel 中有一个事件来做到这一点,当它想要关闭视图时它可以引发该事件。

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

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

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

window.Show()

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

于 2012-06-15T10:00:44.273 回答
3

在您的用户控件中,您可以使用 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;
}

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

于 2012-06-15T09:33:28.587 回答