WPF MVVM如何在视图更改后重新定位应用程序窗口?

时间:2014-02-24 14:40:13

标签: wpf mvvm centering

我正在使用本机WPF和MVVM开发一个非常简单的应用程序。主“shell”视图使用我认为是常见的基本模式,其中它包含一个ContentControl,它与活动视图模型数据绑定,后者通过数据模板注入视图。这是它的缩写版本:

<Window.DataContext>
    <local:ShellViewModel/>
</Window.DataContext>

<Window.Resources>
    <DataTemplate DataType="{x:Type local:DbConfigViewModel}">
        <local:DbConfigView/>
    </DataTemplate>
    <DataTemplate DataType="{x:Type local:AuthenticationViewModel}">
        <local:AuthenticationView/>
    </DataTemplate>
</Window.Resources>

<DockPanel>
    <ContentControl Content="{Binding CurrentViewModel}"/>
</DockPanel>

此窗口根据视图设置为自动调整大小,并设置为以中心启动。这适用于初始视图。但是有些视图要大得多,并且当它们变为活动状态时会成为UI问题。我需要做的是让应用程序在视图发生变化时重新定位。

到目前为止我尝试过的是对主窗口的Left和Top属性进行数据绑定,如下所示:

<Window (....)
    Width="auto" Height="auto"
    SizeToContent="WidthAndHeight"
    WindowStartupLocation="CenterScreen"
    Left="{Binding WindowLeft}"
    Top="{Binding WindowTop}">

我的导航与主Windows视图模型中的方法绑定,因此在该方法中,在将新的viewmodel设置为CurrentViewModel属性之后,我将调用此方法:

    private void CenterWindow()
    {
        Rect workArea = System.Windows.SystemParameters.WorkArea;
        WindowLeft = (workArea.Width - Application.Current.MainWindow.Width) / 2 + workArea.Left;
        WindowTop = (workArea.Height - Application.Current.MainWindow.Height) / 2 + workArea.Top;
    }

这似乎应该可行,但似乎正在发生的是MainWindow.Width和Height尚未调整,因此它基于前一个视图而不是我刚刚实例化的视图。

是否有一些事件或其他地方调用此代码,以便在呈现新视图后发生?这甚至是正确的方法吗?

1 个答案:

答案 0 :(得分:3)

您需要在窗口中订阅SizeChanged:

private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
{
    if (e.PreviousSize == e.NewSize)
        return;

    var w = SystemParameters.PrimaryScreenWidth;
    var h = SystemParameters.PrimaryScreenHeight;

    this.Left = (w - e.NewSize.Width) / 2;
    this.Top = (h - e.NewSize.Height) / 2;
}

如果您希望在viewModel中使用交互事件

,则可以使用它