Я почти уверен, что ответ "не легко".
Вот идея, которая работает, но она неуклюжа:
Бросьте свою StackPanelв UserControl (UserControl1
в приведенном ниже примере).
Поместите две копии этого UserControl в контейнер (Grid в примере ниже).
a,Выровняйте первую копию по верхнему / левому краю, чтобы она осталась в размере по умолчанию.Эта копия предназначена исключительно для целей измерения, и ее видимость должна быть скрытой.
b.Поместите вторую копию в Viewbox.Эта копия - та, которую пользователь фактически увидит.
Используйте MultiBinding с MultiValueConverter, чтобы отрегулировать ширину второго UserControl так, чтобы он имел правильное соотношение сторон перед это расширяется с помощью окна просмотра.
Вот разметка:
<Grid>
<local:UserControl1 x:Name="RawControl" HorizontalAlignment="Left" VerticalAlignment="Top" Visibility="Hidden" />
<Viewbox>
<local:UserControl1>
<local:UserControl1.Width>
<MultiBinding Converter="{StaticResource WidthAdjuster}">
<Binding ElementName="RawControl" Path="ActualHeight" />
<Binding RelativeSource="{RelativeSource AncestorType=Grid}" Path="ActualWidth" />
<Binding RelativeSource="{RelativeSource AncestorType=Grid}" Path="ActualHeight" />
</MultiBinding>
</local:UserControl1.Width>
</local:UserControl1>
</Viewbox>
</Grid>
Вот MultiValueConverter
public class WidthAdjuster : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var rawHeight = (double)values[0];
var containerWidth = (double)values[1];
var containerHeight = (double)values[2];
var ratio = containerWidth / containerHeight;
return rawHeight * ratio;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Результат для контейнера 525 x 350