如何禁用用户控件来绘制它的背景(或区域)

时间:2013-02-07 16:42:52

标签: c# winforms background

我的问题:如何禁用用户控件以绘制其背景(或区域)

注意:我已经尝试覆盖并清空OnPaintBackground或将背景颜色设置为透明。

我正在尝试绕过自定义容器中的自定义用户控件的winform paint。 为此,我想尝试一下:Beginners-Starting-a-2D-Game-with-GDIplus

我的设置是:

  • 包含以下内容的表格:
    • 用户控件(DrawingBoard)
    • 包含元素的容器我可以拖放到此DrawingBoard(它是一个列表框)。

我的渲染循环位于DrawingBoard中,其中包含前一个链接中指定的所有元素。

public DrawingBoard()
{
    InitializeComponent();

    //Resize event are ignored
    SetStyle(ControlStyles.FixedHeight, true);
    SetStyle(ControlStyles.FixedWidth, true);
    SetStyle(System.Windows.Forms.ControlStyles.AllPaintingInWmPaint, true);// True is better
    SetStyle(System.Windows.Forms.ControlStyles.OptimizedDoubleBuffer, true); // True is better
    // Disable the on built PAINT event. We dont need it with a renderloop.
    // The form will no longer refresh itself
    // we will raise the paint event ourselves from our renderloop.
    SetStyle(System.Windows.Forms.ControlStyles.UserPaint, false); // False is better
}

#region GDI+ RENDERING
public Timer t = new Timer();
//This is your BackBuffer, a Bitmap:
Bitmap B_BUFFER = null;
//This is the surface that allows you to draw on your backbuffer bitmap.
Graphics G_BUFFER = null;
//This is the surface you will use to draw your backbuffer to your display.
Graphics G_TARGET = null;
Size DisplaySize = new Size(1120, 630);
bool Antialiasing = false;

const int MS_REDRAW = 32;

public void GDIInit()
{
    B_BUFFER = new Bitmap(DisplaySize.Width, DisplaySize.Height);
    G_BUFFER = Graphics.FromImage(B_BUFFER); //drawing surface
    G_TARGET = CreateGraphics();

    // Configure the display (target) graphics for the fastest rendering.
    G_TARGET.CompositingMode    = CompositingMode.SourceCopy;
    G_TARGET.CompositingQuality = CompositingQuality.AssumeLinear;
    G_TARGET.SmoothingMode      = SmoothingMode.None;
    G_TARGET.InterpolationMode  = InterpolationMode.NearestNeighbor;
    G_TARGET.TextRenderingHint  = TextRenderingHint.SystemDefault;
    G_TARGET.PixelOffsetMode    = PixelOffsetMode.HighSpeed;

    // Configure the backbuffer's drawing surface for optimal rendering with optional
    // antialiasing for Text and Polygon Shapes            
    //Antialiasing is a boolean that tells us weather to enable antialiasing.
    //It is declared somewhere else
    if (Antialiasing)
    {
        G_BUFFER.SmoothingMode      = SmoothingMode.AntiAlias;
        G_BUFFER.TextRenderingHint  = TextRenderingHint.AntiAlias;
    }
    else
    {
        // No Text or Polygon smoothing is applied by default
        G_BUFFER.CompositingMode    = CompositingMode.SourceOver;
        G_BUFFER.CompositingQuality = CompositingQuality.HighSpeed;
        G_BUFFER.InterpolationMode  = InterpolationMode.Low;
        G_BUFFER.PixelOffsetMode    = PixelOffsetMode.Half;
    }

    t.Tick += RenderingLoop;
    t.Interval = MS_REDRAW;
    t.Start();
}
void RenderingLoop(object sender, EventArgs e)
{
    try
    {
        G_BUFFER.Clear(Color.DarkSlateGray);
        UIPaint(G_BUFFER);
        G_TARGET.DrawImageUnscaled(B_BUFFER, 0, 0);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex);
    }
}
#endregion

然后我的元素会触发事件并尝试绘制我想要的内容:

public override void UIPaint(Graphics g)
{     
    Pen p = new Pen(Color.Blue,4);
    p.Alignment = System.Drawing.Drawing2D.PenAlignment.Inset;          
    g.DrawLines(p, new Point[] { new Point(Location.X, Location.Y), new Point(Location.X + Width, Location.Y), new Point(Location.X + Width, Location.Y + Height), new Point(Location.X, Location.Y + Height), new Point(Location.X, Location.Y - 2) });

    g.DrawImageUnscaled(GDATA.GetWindowImage(), Location);        
    }

这是我的DrawingBoard上发生的事情:

由于我无法发布图片...这里是链接:http://s8.postimage.org/iqpxtaoht/Winform.jpg

  • 背景是DarkSlateGray,因为我的G_BUFFER状态清除了每个勾号,确定
  • 蓝色矩形是我画的,但它会被裁剪,KO
  • 纹理被裁剪,KO
  • 裁剪我的绘图的区域是控件尺寸。

所以从那里开始我已经尽力禁用WinForm在背景中进行魔术绘制。试图覆盖并清空在Form / DrawingBoard / Elements上获得绘制/更新/刷新/无效/验证的所有内容,但没有任何东西允许我让我的纹理或绘图不被控件背景裁剪:(

我还尝试将Element的背景设置为透明,并将每个元素BackColor = blabla设置为Form.TransparencyKey = blabla。但每次都失败了。

我当然错过了一些东西:/但我不知道是什么。

1 个答案:

答案 0 :(得分:1)

你为什么不想画背景?为了避免我的自定义控件中闪烁的问题(从类Control派生),这就是我所做的:

(1)覆盖OnPaintBackground

protected override void OnPaintBackground(PaintEventArgs pevent)
{
}

(2)在屏幕外Bitmap绘制,然后将其传输到屏幕:

Bitmap _completeFrame;
protected override void OnPaint(PaintEventArgs pe)
{
    DrawFrame(); // draws onto _completeFrame, calling new Bitmap() 
                 // when _completeFrame is null or its Size is wrong
    var g = pe.Graphics;
    g.DrawImage(_completeFrame, new Point());
}