Как правильно отобразить перекрывающиеся пользовательские элементы управления? - PullRequest
2 голосов
/ 01 февраля 2012

Я использую C #, VisualStudio 2010 и создал пользовательский UserControl для приложения Windows Forms.У них нет особого поведения, кроме как показывать себя и позволять себя тащить в другое место.Однако они имеют круглую форму, и я не могу правильно отобразить их, когда они перекрываются по углам.

Вот мой код для рисования их на экране:

  public void Circle_Paint(object sender, PaintEventArgs e)
  {
     var g = e.Graphics;

     g.FillEllipse(brushForOuterCircle, 0, 0, Width, Height);
     g.FillEllipse(brushForInnerCircle, lineWidth, lineWidth, Width - 2*lineWidth, Height - 2*lineWidth);

     if(!textLocation.HasValue)
     {
        SizeF m = g.MeasureString(text, textFont);
        textLocation = new PointF((float)((Width - m.Width)/2.0), (float)((Height - m.Height)/2.0));
     }
     g.DrawString(text, textFont, brushForText, textLocation.Value);
  }

Вот примернеправильное отображение, юго-восточная часть круга AB не отображается, потому что CD переопределяет эту область.

enter image description here Как мне предотвратить это, есть ли способ сообщить UserControl "вы прозрачны по умолчанию; любая часть, на которую я не рисую, должна оставаться такой"?

Ответы [ 3 ]

3 голосов
/ 01 февраля 2012

Попробуйте:

сначала настройте свой пользовательский элемент управления WS_EX_COMPOSITED расширенный стиль, переопределив

protected override CreateParams CreateParams
{
   get
   {
     CreateParams cp = base.CreateParams;
     cp.ExStyle |= 0x00000020; // add this
     return cp;
   }
}

после ничего не закрашивать в фоновом режиме

protected override void OnPaintBackground(PaintEventArgs e)
{
   // leave this empty 
}

и, наконец, Paint нарисуйте свою форму.

Должно работать.

1 голос
/ 01 февраля 2012

Вы также должны установить область так, чтобы она игнорировала щелчки мыши для области, которая должна быть прозрачной. Взгляните на следующий элемент управления в качестве примера. Это элемент управления, который рисует круг. Я установил Регион на Эллипс, чтобы WinForms не рисовали область за пределами круга. Устанавливая регион, он также знает, как игнорировать щелчки мышью в области за пределами области.


using System;
using System.Drawing.Drawing2D;
using System.Drawing;
using System.Windows.Forms;

namespace WindowsApplication1
{
    public class RoundControl : Control
    {
        private readonly GraphicsPath _path;

        public RoundControl()
        {
            _path = new GraphicsPath();
        }

        protected override void OnResize(EventArgs e)
        {
            _path.Reset();
            _path.AddEllipse(ClientRectangle);
            Invalidate(Region);
            Region = new Region(_path);
            base.OnResize(e);
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                _path.Dispose();
            }
            base.Dispose(disposing);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            using (Pen borderPen = new Pen(ForeColor, 8))
            {
                e.Graphics.DrawEllipse(borderPen, ClientRectangle);
            }
            base.OnPaint(e);
        }
    }
}

This is what two 'RoundControl' instances look like when rendered in a Form

1 голос
/ 01 февраля 2012

Попробуй это. Создайте TransparencyControl, как предложено здесь: Прозрачные изображения с C # WinForms

using System;
using System.Windows.Forms;
using System.Drawing;

public class TransparentControl : Control
{
    private readonly Timer refresher;
    private Image _image;

    public TransparentControl()
    {
        SetStyle(ControlStyles.SupportsTransparentBackColor, true);
        BackColor = Color.Transparent;
        refresher = new Timer();
        refresher.Tick += TimerOnTick;
        refresher.Interval = 50;
        refresher.Enabled = true;
        refresher.Start();
    }

    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            cp.ExStyle |= 0x20;
            return cp;
        }
    }

    protected override void OnMove(EventArgs e)
    {
        RecreateHandle();
    }


    protected override void OnPaint(PaintEventArgs e)
    {
        if (_image != null)
        {
            e.Graphics.DrawImage(_image, (Width / 2) - (_image.Width / 2), (Height / 2) - (_image.Height / 2));
        }
    }

    protected override void OnPaintBackground(PaintEventArgs e)
    {
       //Do not paint background
    }

    //Hack
    public void Redraw()
    {
        RecreateHandle();
    }

    private void TimerOnTick(object source, EventArgs e)
    {
        RecreateHandle();
        refresher.Stop();
    }

    public Image Image
    {
        get
        {
            return _image;
        }
        set
        {
            _image = value;
            RecreateHandle();
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...