Сохранение пропорций элемента управления - PullRequest
0 голосов
/ 25 мая 2018

Я довольно долго искал способ указать элементу управления WPF (или окну) сохранить определенное соотношение сторон.

  1. Для Window я нашел это решение, которое работает довольно хорошо.Но поскольку он использует Win32 API и дескрипторы окон, он не работает ни для каких WPF Control s (поскольку, насколько мне известно, в WPF только само окно имеет дескриптор)
  2. Для Control обычнополучает совет поместить Control в ViewBox, но я не хочу масштабировать свои элементы управления, я хочу, чтобы они меняли размер (и сохраняли любую ширину границы или размер шрифта).
  3. Other "Решения "для Control включают в себя любую форму привязки Width к ActualHeight или Height к ActualWidth, или использование события SizeChanged, но это приводит к сильному мерцанию при изменении размера, и этоне очень надежныйВ случае привязки Width к ActualHeight вы не можете изменить размер только Width (путем перетаскивания правой границы), потому что ActualHeight не изменяется.В случае события становится сложно, когда ширина и высота изменяются одновременно, тогда вам придется изменить размер внутри события SizeChanged ... и я упоминал о мерцании?

После долгих чтений и поисков я пришел к выводу, что лучший способ заставить любой элемент управления сохранять определенное соотношение сторон - это делать это внутри функций Measure и Arrange.

Я нашел это решение, которое создает элемент управления Decorator с переопределенными функциями Measure и Measure, но это будет означать, что любой элемент управления, который должен сохранять соотношение сторон, внутри собственного Decorator.Я мог бы жить с этим, если бы мне пришлось, но мне интересно, есть ли лучший способ сделать это.

Итак, вот мой вопрос.Можно ли создать присоединенное свойство Ratio и присоединенное свойство KeepRatio и каким-либо образом переопределить функции Measure и Arrange рассматриваемых элементов управления в обратных вызовах OnKeepRatioChanged и RatioChanged присоединенных свойств?

1 Ответ

0 голосов
/ 25 мая 2018

Если вы хотите переопределить методы Arrange / Measure, тогда в вложенных свойствах нет необходимости.Эта обертка должна быть в порядке:

public partial class RatioKeeper : UserControl
{
    public static readonly DependencyProperty VerticalAspectProperty = DependencyProperty.Register(
        "VerticalAspect", typeof(double), typeof(RatioKeeper), new PropertyMetadata(1d));

    public static readonly DependencyProperty HorizontalAspectProperty = DependencyProperty.Register(
        "HorizontalAspect", typeof(double), typeof(RatioKeeper), new PropertyMetadata(1d));

    public double HorizontalAspect
    {
        get { return (double) GetValue(HorizontalAspectProperty); }
        set { SetValue(HorizontalAspectProperty, value); }
    }

    public double VerticalAspect
    {
        get { return (double) GetValue(VerticalAspectProperty); }
        set { SetValue(VerticalAspectProperty, value); }
    }
    public RatioKeeper()
    {
        InitializeComponent();
    }

    //arrangeBounds provides size of a host.
    protected override Size ArrangeOverride(Size arrangeBounds)
    {
        //Calculation of a content size that wont exceed host's size and will be of the desired ratio at the same time
        var horizontalPart = arrangeBounds.Width / HorizontalAspect;
        var verticalPart = arrangeBounds.Height / VerticalAspect;
        var minPart = Math.Min(horizontalPart, verticalPart);
        var size = new Size(minPart * HorizontalAspect, minPart * VerticalAspect);
        //apply size to wrapped content
        base.ArrangeOverride(size);
        //return size to host
        return size;
    }
}
...