WPF MVVM如何在视图更改后重新居中应用程序窗口? [英] WPF MVVM How to re-center application window after view changes?

查看:61
本文介绍了WPF MVVM如何在视图更改后重新居中应用程序窗口?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用本机WPF和MVVM开发一个非常简单的应用程序.我认为主要的外壳"视图使用的是一种常见的基本模式,其中包含一个ContentControl,该ContentControl与活动的视图模型进行数据绑定,该控件通过数据模板注入视图.这是它的缩写形式:

I'm working on a very simple application using native WPF and MVVM. The main "shell" view uses what I believe is a common basic pattern, in which it contains a ContentControl that is databound to the active viewmodel, which injects the view through data templates. This is an abbreviated version of what it looks like:

<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问题.我需要发生的是,只要视图发生更改,就让应用程序重新居中.

This window is set to auto-size based on the view, and is set to start up centered. This works fine for the initial view. Some views are much larger though, and it becomes a UI issue when they become active. What I need to occur is have the application re-center itself whenever a view changes.

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

What I've tried so far is to databind the Left and Top properties of the main Window, like this:

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

我的导航与主Windows的viewmodel中的一个方法相关联,因此在该方法中,将新的viewmodel设置为CurrentViewModel属性之后,我将调用此方法:

My navigation is tied to a method within the main Windows's viewmodel, so in that method, after the new viewmodel is set to the CurrentViewModel property, I then call this method:

    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尚未调整,因此它是基于上一个视图而不是我刚刚实例化的视图居中.

This seems like it should work, but what appears to be happening is that the MainWindow.Width and Height have not yet been adjusted, so it is centering based on the previous view rather than the one I just instantiated.

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

So is there some event or other place to call this code so that it occurs after the new view is rendered? Is this even the correct approach?

推荐答案

您需要在窗口中订阅SizeChanged,然后:

You need to subscribe to SizeChanged in your window then:

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中使用交互事件,则可以使用

You can use interaction events if you want it in your viewModel

这篇关于WPF MVVM如何在视图更改后重新居中应用程序窗口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆