问题
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