I'm wondering how to maintain the aspect ratio (i.e.: 16x9) of a window in WPF upon resize--if possible in a way that leverages MVVM. As I'm new to both MVVM and WPF, I'm not sure where to begin. Thanks.
This may be difficult to do with a "pure" MVVM implementation, because you need to know which direction the resize happened (horizontally or vertically). Note that if both change at once (i.e. the user resizes by dragging the corner), you will need to decide which of these to use.
In your ViewModel, you will probably have a property named AspectRatio.
In your View, you will most likely override the OnRenderSizeChanged event. Its then a matter of taste whether you do the work in the view using the property from the ViewModel, or whether you pass the value to a property in the ViewModel to do the work, and bind to the new values.
Example 1: Do the work here
protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
{
if (sizeInfo.WidthChanged)
{
this.Width = sizeInfo.NewSize.Height * mViewModel.AspectRatio;
}
else
{
this.Height = sizeInfo.NewSize.Width * mViewModel.AspectRatio;
}
}
Example 2: Do the work in the ViewModel
View.xaml.cs
protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
{
if (sizeInfo.WidthChanged)
{
viewModel.AspectWidth = sizeInfo.NewSize.Width;
}
else
{
viewModel.AspectHeight = sizeInfo.NewSize.Height;
}
}
ViewModel.cs
public Double AspectWidth
{
get { return mAspectWidth; }
set
{
// Some method that sets your property and implements INotifyPropertyChanged
SetValue("AspectWidth", ref mAspectWidth, value);
SetValue("AspectHeight", ref mAspectHeight, mAspectWidth * mAspectRatio);
}
}
public Double AspectHeight
{
get { return mAspectHeight; }
set
{
// Some method that sets your property and implements INotifyPropertyChanged
SetValue("AspectHeight", ref mAspectHeight, value);
SetValue("AspectWidth", ref mAspectWidth, mAspectHeight* mAspectRatio);
}
}
And your view (for example 2) would bind the window's width and height to the AspectWidth and AspectHeight properties in the viewmodel.
View.xaml
<Window Width="{Binding AspectWidth}"
Height="{Binding AspectHeight}">
</Window>
So, in either case, you override OnRenderSizeChanged. The details on how you implement that method are up to your tastes. I guess that Example #2 is closer to pure "MVVM" but it may also be overkill in this case.