WPF MVVM How to re-center application window after view changes?

陌路散爱 提交于 2020-12-13 11:49:08

问题


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>

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.

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

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

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?


回答1:


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

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



来源:https://stackoverflow.com/questions/21990866/wpf-mvvm-how-to-re-center-application-window-after-view-changes

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!