Попытка установить фоновое изображение, которое всегда покрывает форму, но имеет статическое / фиксированное соотношение сторон - PullRequest
0 голосов
/ 28 июня 2018

Так что я довольно долго осматривался по этому вопросу, но результаты всегда возвращаются к тому, что для BackgroundImageLayout установлено значение «Растянуть». Что, конечно, не делает ничего о поддержании соотношения сторон исходного изображения или учебниках о том, как вручную масштабировать PictureBox или другие загруженные изображения при сохранении соотношения сторон, но я не могу (очень удивительно для меня) найти что-нибудь о том, как заставить WinForm управлять фоновым изображением, которое всегда центрировано на окне, растянуто, чтобы покрыть его, но сохраняя то же соотношение сторон, что и оригинал.

Я пробовал это:

public class CustomForm : Form
{
    protected Size _scale;
    protected Size _originalSize;
    protected float _aspectRatio;

    public CustomForm() : base()
    {
        this.DoubleBuffered = true;
    }

    private float AspectRatio() { return this.AspectRatio(this._originalSize); }
    private float AspectRatio(int width, int height) { return (float)width / height; }
    private float AspectRatio(Size value) { return this.AspectRatio(value.Width, value.Height); }

    protected override void OnBackgroundImageChanged(EventArgs e)
    {
        this._originalSize = new Size(this.BackgroundImage.Width, this.BackgroundImage.Height);
        this._aspectRatio = this.AspectRatio(this._originalSize);
        base.OnBackgroundImageChanged(e);
    }

    protected override void OnPaintBackground(PaintEventArgs e)
    {
        if (this.BackgroundImage == null) base.OnPaintBackground(e);
        else
        {
            e.Graphics.FillRectangle(new SolidBrush(this.BackColor), ClientRectangle);

            int x = (this._scale.Width > this.Width) ? (int)Math.Round((this._scale.Width - this.Width) / 2.0) : 0;
            int y = (this._scale.Height > this.Height) ? (int)Math.Round((this._scale.Height - this.Height) / 2.0) : 0;

            e.Graphics.DrawImage(this.BackgroundImage, new Rectangle(x, y, this._scale.Width, this._scale.Height));
        }
    }

    protected override void OnSizeChanged(EventArgs e)
    {
        if ( this._aspectRatio > this.AspectRatio(this.Size))
        {
            this._scale.Width = this.Width;
            this._scale.Height = (int)(this.Width / this._aspectRatio);
        }
        else
        {
            this._scale.Height = this.Height;
            this._scale.Width = (int)(this.Height * this._aspectRatio);
        }
        base.OnSizeChanged(e);
    }
}

Но все, что он делает, это фиксирует изображение в верхнем левом углу формы в его основных размерах, независимо от того, как форма (ре) измерена ...

Может кто-нибудь, пожалуйста, указать мне в направлении правильного решения или на то, что я до сих пор сделал / сделал неправильно?

Спасибо!

1 Ответ

0 голосов
/ 28 июня 2018

Ладно, после еще нескольких исследований, и с некоторым бодрством я наконец-то разобрался с этим! Размещайте это здесь для тех, кто может найти его в будущем!

public class CustomForm : Form
{
    protected Size _scale;
    protected Size _originalSize;

    public CustomForm() : base()
    {
        this.InitializeComponent();
    }

    protected override void OnBackgroundImageChanged(EventArgs e)
    {
        this._originalSize = new Size(this.BackgroundImage.Width, this.BackgroundImage.Height);
        base.OnBackgroundImageChanged(e);
    }

    protected override void OnPaintBackground(PaintEventArgs e)
    {
        if ((BackgroundImage != null) && (BackgroundImageLayout == ImageLayout.None))
        {
            Point p = new Point(
                            (int)((this.Width - this._scale.Width) / 2),
                            (int)((this.Height - this._scale.Height) / 2)
                          );

            e.Graphics.DrawImage(this.BackgroundImage, new Rectangle(p, this._scale));
        }
        else
            base.OnPaintBackground(e);
    }

    protected override void OnSizeChanged(EventArgs e)
    {
        if ((BackgroundImage != null) && (BackgroundImageLayout == ImageLayout.None))
        {
            float rX = (float) this.Width / this._originalSize.Width;
            float rY = (float) this.Height / this._originalSize.Height;
            float r = (rX < rY) ? rY : rX;

            this._scale.Height = (int)(this._originalSize.Height * r);
            this._scale.Width = (int)(this._originalSize.Width * r);
        }
        base.OnSizeChanged(e);
    }

    private void InitializeComponent()
    {
        this._originalSize = new Size(0, 0);
        this._scale = new Size(0, 0);

        this.SuspendLayout();
        // 
        // CustomForm
        // 
        this.Name = "CustomForm";
        this.DoubleBuffered = true; // minimizes "flicker" when resizing
        this.ResizeRedraw = true; // forces a full redraw when resized!
        this.ResumeLayout(false);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...