Как сделать так, чтобы пользовательские элементы управления AutoScale были компактными - PullRequest
3 голосов
/ 16 ноября 2011

Windows Forms (включая Windows Forms для Compact Framwork, который я и использую) имеет функцию AutoScale . Установив для свойства AutoScaleMode значение AutoScaleMode.Dpi, ваше приложение, скажем, для 320x200, автоматически масштабируется до большего дисплея, например, устройства VGA.

Это прекрасно работает, но у меня есть несколько самодельных пользовательских элементов управления, которые делают свои собственные вещи OnPaint, и я бы хотел, чтобы они также масштабировались. К сожалению, я не нашел хорошую документацию или пример того, как это сделать.

В настоящее время я делаю это:

protected SizeF zoom = new SizeF(1.0, 1.0);

protected override void ScaleControl(SizeF factor, BoundsSpecified specified)
{
    base.ScaleControl(factor, specified);
    zoom = factor;        // remember the zoom factor
}

protected override void OnPaint(PaintEventArgs e)
{
    // scale everything by zoom.Width and zoom.Height
    ...
    e.Graphics.DrawImage(...);
    ...
}

Это работает, но мне интересно, если это "правильный способ" сделать это. Поскольку (согласно ILSpy) ни один из других элементов управления CF не имеет внутреннего поля для хранения коэффициента масштабирования, мне интересно, есть ли более простой или лучший способ сделать это.

1 Ответ

3 голосов
/ 18 ноября 2011

Мы обычно обрабатываем все масштабирования в OnResize в наших элементах управления и формах.Мы также должны поддерживать множество различных устройств с невероятными размерами и DPI (некоторые форматы даже не сообщают правильный DPI!).Мы обнаружили, что при отключенном AutoScaleMode вы можете пропорционально использовать такого помощника для масштабирования дочерних элементов формы в OnResize.Вы просто добавляете набор элементов Size _initalSize к размеру формы в конструкторе.Тем не менее, в большинстве форм я обнаружил, что мне нужно написать собственный код макета, который бы подходил для портретной и альбомной ориентации.

        protected override void OnResize(EventArgs e)
    {
        base.OnResize(e);

        // Scale the control
        ScaleChildren(this, ref _initialFormSize);
    }


        public static void ScaleChildren(Control control, ref Size initialSize, float fontFactor)
    {
        if (control == null || control.Size == initialSize)
            return;

        SizeF scaleFactor = new SizeF((float)control.Width / (float)initialSize.Width, (float)control.Height / (float)initialSize.Height);
        initialSize = control.Size;

        if (!float.IsInfinity(scaleFactor.Width) || !float.IsInfinity(scaleFactor.Height))
        {
            foreach (Control child in control.Controls)
            {
                child.Scale(scaleFactor);

                if (child is Panel)
                    continue;

                try
                {
                    // scale the font
                    float scaledFontSize = (float)(int)(child.Font.Size * scaleFactor.Height * fontFactor + 0.5f);

                    System.Diagnostics.Debug.WriteLine(
                        string.Format("ScaleChildren(): scaleFactor = ({0}, {1}); fontFactor = {2}; scaledFontSize = {3}; \"{4}\"",
                        scaleFactor.Width, scaleFactor.Height, fontFactor, scaledFontSize, child.Text));

                    child.Font = new Font(child.Font.Name, scaledFontSize, child.Font.Style);
                }
                catch { }
            }
        }
    }
...