làm thế nào để ngăn chặn các biểu mẫu C # nhấp nháy


76

Tôi có một chương trình về cơ bản giống như một ứng dụng sơn. Tuy nhiên, chương trình của tôi có một số vấn đề chập chờn. Tôi có dòng sau trong mã của mình (sẽ loại bỏ hiện tượng nhấp nháy - nhưng không):

this.SetStyle(ControlStyles.AllPaintingInWmPaint 
| ControlStyles.UserPaint | ControlStyles.DoubleBuffer, true);

mã của tôi (trừ lớp siêu và lớp con cho các hình dạng như sau:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Paint
{
    public partial class Paint : Form
    {
        private Point startPoint;
        private Point endPoint;
        private Rectangle rect = new Rectangle();
        private Int32 brushThickness = 0;
        private Boolean drawSPaint = false;
        private List<Shapes> listOfShapes = new List<Shapes>();
        private Color currentColor;
        private Color currentBoarderColor;
        private Boolean IsShapeRectangle = false;
        private Boolean IsShapeCircle = false;
        private Boolean IsShapeLine = false;

        public SPaint()
        {

            InitializeComponent();
            this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.DoubleBuffer, true);

            currentColor = Color.Red;
            currentBoarderColor = Color.DodgerBlue;
            IsShapeRectangle = true; 
        }

        private void panelArea_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = panelArea.CreateGraphics();

            if (drawSPaint == true)
            {

                Pen p = new Pen(Color.Blue);
                p.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;

                if (IsShapeRectangle == true)
                {
                    g.DrawRectangle(p, rect);
                }
                else if (IsShapeCircle == true)
                {
                    g.DrawEllipse(p, rect);
                }
                else if (IsShapeLine == true)
                {
                    g.DrawLine(p, startPoint, endPoint);
                }
            }
            foreach (Shapes shape in listOfShapes)
            {

                shape.Draw(g);

            }
        }

        private void panelArea_MouseDown(object sender, MouseEventArgs e)
        {

            startPoint.X = e.X;
            startPoint.Y = e.Y;

            drawSPaint = true;
        }

        private void panelArea_MouseMove(object sender, MouseEventArgs e)
        {


            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {

                if (e.X > startPoint.X)
                {
                    rect.X = startPoint.X;
                    rect.Width = e.X - startPoint.X;
                }
                else
                {
                    rect.X = e.X;
                    rect.Width = startPoint.X - e.X;
                }
                if (e.Y > startPoint.Y)
                {
                    rect.Y = startPoint.Y;
                    rect.Height = e.Y - startPoint.Y;
                }
                else
                {
                    rect.Y = e.Y;
                    rect.Height = startPoint.Y - e.Y;
                }


                panelArea.Invalidate();

            }

        }

        private void panelArea_MouseUp(object sender, MouseEventArgs e)
        {

            endPoint.X = e.X;
            endPoint.Y = e.Y;

            drawSPaint = false;

            if (rect.Width > 0 && rect.Height > 0)
            {
                if (IsShapeRectangle == true)
                {
                    listOfShapes.Add(new TheRectangles(rect, currentColor, currentBoarderColor, brushThickness));
                }
                else if (IsShapeCircle == true)
                {
                    listOfShapes.Add(new TheCircles(rect, currentColor, currentBoarderColor, brushThickness));
                }
                else if (IsShapeLine == true)
                {
                    listOfShapes.Add(new TheLines(startPoint, endPoint, currentColor, currentBoarderColor, brushThickness));
                }

                panelArea.Invalidate();
            }
        }


        private void rectangleToolStripMenuItem_Click(object sender, EventArgs e)
        {
            IsShapeRectangle = true;
            IsShapeCircle = false;
            IsShapeLine = false; 
        }

        private void ellipseToolStripMenuItem_Click(object sender, EventArgs e)
        {
            IsShapeRectangle = false;
            IsShapeCircle = true;
            IsShapeLine = false; 
        }

        private void lineToolStripMenuItem_Click(object sender, EventArgs e)
        {
            IsShapeCircle = false;
            IsShapeRectangle = false;
            IsShapeLine = true; 
        }

        private void ThicknessLevel0_Click(object sender, EventArgs e)
        {
            brushThickness = 0; 
        }

        private void ThicknessLevel2_Click(object sender, EventArgs e)
        {
            brushThickness = 2; 
        }

        private void ThicknessLevel4_Click(object sender, EventArgs e)
        {
            brushThickness = 4; 
        }

        private void ThicknessLevel6_Click(object sender, EventArgs e)
        {
            brushThickness = 6; 
        }

        private void ThicknessLevel8_Click(object sender, EventArgs e)
        {
            brushThickness = 8; 
        }

        private void ThicknessLevel10_Click(object sender, EventArgs e)
        {
            brushThickness = 10; 
        }

        private void ThicknessLevel12_Click(object sender, EventArgs e)
        {
            brushThickness = 12; 
        }

        private void ThicknessLevel14_Click(object sender, EventArgs e)
        {
            brushThickness = 14; 
        }

        private void FillColour_Click(object sender, EventArgs e)
        {

            ColorDialog fillColourDialog = new ColorDialog();
            fillColourDialog.ShowDialog();
            currentColor = fillColourDialog.Color;
            panelArea.Invalidate(); 
        }

        private void button1_Click(object sender, EventArgs e)
        {

            ColorDialog fillColourDialog = new ColorDialog();
            fillColourDialog.ShowDialog();
            currentBoarderColor = fillColourDialog.Color;
            panelArea.Invalidate(); 
        }


    }
}

Làm cách nào để tôi ngừng nhấp nháy?

* CẬP NHẬT: * Mã này thực sự hoạt động tốt khi tôi đang vẽ trực tiếp trên biểu mẫu. Tuy nhiên, khi tôi cố gắng vẽ trên bảng điều khiển, nhấp nháy sẽ trở thành một vấn đề


7
Bạn cũng đã đặt this.DoubleBuffered = true;?
Marc Gravell

1
@ Marc Gravell, tôi vừa thử thêm vào this.DoubleBuffered = true; và nó vẫn nhấp nháy như điên: S
BigBug

PanelArea có đầy đủ các điều khiển không? Vô hiệu các công trình đệ quy và do đó có thể đá từng kiểm soát trẻ em trong panelArea để sơn lại bản thân
Chính thể

@ Polity no, panelArea chỉ là một bảng điều khiển mà tôi đang sử dụng để vẽ. Nó không có điều khiển mặc dù ..
BigBug

1
+1, thành thật mà nói, chức năng SetStyle đã giúp tôi xóa hiện tượng nhấp nháy. c # tốt hơn nhiều so với c ++ !!!
Neophile

Câu trả lời:


71

Để có "giải pháp sạch hơn" và để tiếp tục sử dụng Bảng điều khiển cơ sở, bạn có thể chỉ cần sử dụng Phản chiếu để triển khai bộ đệm kép, bằng cách thêm mã này vào biểu mẫu chứa các bảng mà bạn muốn vẽ vào

    typeof(Panel).InvokeMember("DoubleBuffered", 
    BindingFlags.SetProperty | BindingFlags.Instance | BindingFlags.NonPublic, 
    null, DrawingPanel, new object[] { true });

Trong đó "DrawingPanel" là tên của bảng điều khiển mà bạn muốn thực hiện bộ đệm kép.

Tôi biết khá nhiều thời gian đã trôi qua kể từ khi câu hỏi được đặt ra, nhưng điều này có thể giúp ích cho ai đó trong tương lai.


3
Đây là một giải pháp tuyệt vời! Rất đơn giản để thực hiện và hoạt động chính xác như mong muốn
Poetfan

5
@musefan Tôi rất vui vì đã giúp được bạn: DI rất vui vì giải pháp được đăng sau 2 năm so với câu hỏi ban đầu vẫn có thể giúp được mọi người! Đó là lý do tại sao chống tràn ngăn xếp rất tốt! :)
viper

1
Nó vẫn nhấp nháy đối với tôi. Tôi thêm mã này vào đâu? Tái bút. trong câu trả lời này, nó phải được nói "bạn cần 'sử dụng System.Reflection' ở trên cùng".
john ktejik

2
Bạn phải gọi điều này cho bảng điều khiển mà bạn muốn dừng nhấp nháy trước khi bắt đầu sử dụng. Bạn có thể gọi nó trong sự kiện Tải của biểu mẫu chính của bạn (hoặc biểu mẫu sẽ có bảng điều khiển). Bạn đang gọi nó ở đâu?
viper

3
@RotaryHeart xin lưu ý rằng bạn không nên sử dụng điều này trong phương pháp sơn vì nó sẽ chạy mỗi khi điều khiển được sơn lại và phản chiếu rất tốn kém. Bạn chỉ cần đặt điều này một lần cho mỗi điều khiển. Tôi không chắc đây có phải là những gì bạn đã làm hay không, từ việc đọc bình luận của bạn, nó có vẻ như đó có thể là giải pháp của bạn.
viper

64

Cuối cùng đã giải quyết được sự chập chờn. Vì tôi đang vẽ trên bảng điều khiển thay vì ở dạng dòng mã dưới đây sẽ không giải quyết được hiện tượng nhấp nháy:

this.SetStyle(
    ControlStyles.AllPaintingInWmPaint | 
    ControlStyles.UserPaint | 
    ControlStyles.DoubleBuffer, 
    true);

SetStyle phải thuộc loại 'YourProject.YourProject' (hoặc có nguồn gốc từ nó) do đó, bạn phải tạo một lớp như vậy (để bạn có thể sử dụng MyPanel sẽ bắt nguồn từ SPaint.SPaint và do đó cho phép bạn sử dụng bộ đệm kép trực tiếp cho bảng điều khiển - thay vì biểu mẫu):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SPaint; 

namespace YourProject
{
    public class MyPanel : System.Windows.Forms.Panel
    {
        public MyPanel()
        {
            this.SetStyle(
                System.Windows.Forms.ControlStyles.UserPaint | 
                System.Windows.Forms.ControlStyles.AllPaintingInWmPaint | 
                System.Windows.Forms.ControlStyles.OptimizedDoubleBuffer, 
                true);
        }
    }
}

Sau khi bạn thực hiện xong việc này (mặc dù bạn thực sự không bao giờ nên chỉnh sửa mã thiết kế trừ khi bạn thực sự biết mình đang làm gì), bạn sẽ phải chỉnh sửa Form.Designer.cs. Bên trong tệp này, bạn sẽ tìm thấy mã trông giống như sau:

this.panelArea = new YourProject.MyPanel();

Dòng trên cần được thay đổi thành:

this.panelArea = new MyPanel(); 

Sau khi tôi hoàn thành các bước này, chương trình sơn của tôi không còn nhấp nháy nữa.

Đối với bất kỳ ai khác gặp vấn đề tương tự, vấn đề cuối cùng đã được giải quyết.

Thưởng thức!


Nhưng nó không xuất hiện trong trình thiết kế nữa. Bất kỳ cách nào để khắc phục nó?
Winger Sendon

@WingerSendon - để tránh các vấn đề của nhà thiết kế, hãy sử dụng giải pháp "mã", chẳng hạn như viper's , đặt bộ đệm kép trong thời gian chạy.
ToolmakerSteve

43

Sao chép và dán cái này vào dự án của bạn

protected override CreateParams CreateParams
{
    get
    {
        CreateParams handleParam = base.CreateParams;
        handleParam.ExStyle |= 0x02000000;   // WS_EX_COMPOSITED       
        return handleParam;
    }
}

Điều này cho phép đệm kép cho tất cả các điều khiển từ cấp biểu mẫu trở xuống, nếu không đệm kép cần được bật riêng cho từng điều khiển ... bạn có thể muốn tinh chỉnh bộ đệm kép sau đó vì đệm kép có thể tạo ra các tác dụng phụ không mong muốn.


8
Để làm cho câu trả lời của bạn hữu ích hơn, hãy xem xét thêm một lời giải thích ngắn gọn về lý do tại sao một đoạn mã cụ thể có thể giúp trả lời câu hỏi.
Kris

2
Có vẻ như đây có thể là nguồn , cũng được đăng ở đây trên SO ... lời giải thích cơ bản cho lý do tại sao điều này hoạt động là vì nó cho phép đệm kép cho tất cả các điều khiển từ cấp biểu mẫu trở xuống, nếu không, bộ đệm kép cần được bật riêng cho mỗi cái ... bạn có thể muốn tinh chỉnh bộ đệm kép sau đó vì bộ đệm kép được che phủ có thể gây ra các tác dụng phụ không mong muốn
u8it

tại sao điều này lại hiệu quả hơn là câu trả lời được chấp nhận?
aswzen

@Ivan 10+? Wow: D
Momoro

16

Tôi đã có cùng một vấn đề. Tôi không bao giờ có thể loại bỏ 100% hiện tượng nhấp nháy (xem điểm 2), nhưng tôi đã sử dụng

protected override void OnPaint(PaintEventArgs e) {}

cũng như

this.DoubleBuffered = true;

Vấn đề chính của việc nhấp nháy là đảm bảo bạn

  1. sơn mọi thứ theo đúng thứ tự!
  2. đảm bảo rằng hàm vẽ của bạn <khoảng 1/60 giây

winforms gọi OnPaintphương thức mỗi khi biểu mẫu cần được vẽ lại. Có nhiều cách nó có thể bị giảm giá trị, bao gồm cả việc di chuyển con trỏ chuột qua biểu mẫu đôi khi có thể gọi ra sự kiện vẽ lại.

Và lưu ý quan trọng OnPaint, là bạn không bắt đầu từ đầu mỗi lần, thay vào đó bạn bắt đầu từ vị trí cũ của bạn, nếu bạn tô màu nền ngập tràn, bạn có thể sẽ bị nhấp nháy.

Cuối cùng là đối tượng gfx của bạn. Bên trong, OnPaintbạn sẽ cần phải tạo lại đối tượng đồ họa, nhưng CHỈ khi kích thước màn hình đã thay đổi. việc tạo lại đối tượng là rất tốn kém và nó cần phải được xử lý trước khi nó được tái tạo (việc thu gom rác không xử lý chính xác 100% hoặc tài liệu nói như vậy). Tôi đã tạo một biến lớp

protected Graphics gfx = null;

và sau đó sử dụng nó cục bộ OnPaintnhư vậy, nhưng điều này là do tôi cần sử dụng đối tượng gfx ở các vị trí khác trong lớp của mình. Nếu không thì KHÔNG LÀM ĐIỀU NÀY. Nếu bạn chỉ vẽ trong OnPaint, thì hãy sử dụng e.Graphics!!

// clean up old graphics object
gfx.Dispose();

// recreate graphics object (dont use e.Graphics, because we need to use it 
// in other functions)
gfx = this.CreateGraphics();

Hi vọng điêu nay co ich.


điều này đã không được giải quyết vấn đề của tôi :( .. mã này thực sự hoạt động tuyệt vời khi tôi đang vẽ trực tiếp trên hình thức Tuy nhiên, khi tôi cố gắng để vẽ trên bảng điều khiển, nhấp nháy trở thành một vấn đề ....
BigBug

@BlueMonster thay vì thử Panel.DoubleBuffered = true;
Burimi

Tôi khuyên bạn nên tạo một đối tượng con của lớp bảng điều khiển, kế thừa từ bảng điều khiển, sau đó ghi đè protected override void OnPaint(PaintEventArgs e) {}đối tượng con đó. Đối tượng mới sẽ hiển thị trên danh sách các mục để thả vào biểu mẫu của bạn. Ngoài ra, bạn có thể chỉnh sửa thủ công mã để thay đổi loại tham chiếu, nếu bạn đã tạo bảng điều khiển và không có tùy chọn dễ dàng là chỉ tạo lại nó.
ohmusama

Sử dụng e.Graphicstrợ giúp, cùng với this.DoubleBuffered = true. Bằng cách sử dụng Graphicsbộ đệm kép đã tạo không chỉ làm tăng hiệu ứng nhấp nháy mà còn làm cho Control(hoặc Form) màu trắng trong hầu hết thời gian.
Meow Cat 2012

4

Tôi e rằng đệm kép sẽ không giúp ích được nhiều ở đây. Tôi đã gặp phải điều này một lúc trước và cuối cùng đã thêm một bảng điều khiển riêng biệt theo một cách khá vụng về nhưng nó hoạt động cho ứng dụng của tôi.

Đặt bảng điều khiển ban đầu mà bạn có (panelArea) thành một khu vực trong suốt và đặt nó lên trên bảng điều khiển thứ hai, ví dụ như bạn gọi là panelDraw. Đảm bảo có panelArea ở phía trước. Tôi đánh nó lên và nó đã loại bỏ sự nhấp nháy, nhưng để lại hình dạng đang được vẽ bị mờ đi nên nó cũng không phải là một giải pháp đầy đủ.

Có thể tạo bảng trong suốt bằng cách ghi đè một số thao tác sơn từ bảng gốc:

public class ClearPanel : Panel
{
    public ClearPanel(){}

    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams createParams = base.CreateParams;
            createParams.ExStyle |= 0x00000020;
            return createParams;
        }
    }

    protected override void OnPaintBackground(PaintEventArgs e){}
}

Ý tưởng là xử lý việc vẽ hình dạng tạm thời trong sự kiện MouseMove của 'panelArea' và CHỈ sơn lại 'panelDraw' trong Sự kiện MouseUp.

// Use the panelDraw paint event to draw shapes that are done
void panelDraw_Paint(object sender, PaintEventArgs e)
{
    Graphics g = panelDraw.CreateGraphics();

    foreach (Rectangle shape in listOfShapes)
    {
        shape.Draw(g);
    }
}

// Use the panelArea_paint event to update the new shape-dragging...
private void panelArea_Paint(object sender, PaintEventArgs e)
{
    Graphics g = panelArea.CreateGraphics();

    if (drawSETPaint == true)
    {
        Pen p = new Pen(Color.Blue);
        p.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;

        if (IsShapeRectangle == true)
        {
            g.DrawRectangle(p, rect);
        }
        else if (IsShapeCircle == true)
        {
            g.DrawEllipse(p, rect);
        }
        else if (IsShapeLine == true)
        {
            g.DrawLine(p, startPoint, endPoint);
        }
    }
}

private void panelArea_MouseUp(object sender, MouseEventArgs e)
{

    endPoint.X = e.X;
    endPoint.Y = e.Y;

    drawSETPaint = false;

    if (rect.Width > 0 && rect.Height > 0)
    {
        if (IsShapeRectangle == true)
        {
            listOfShapes.Add(new TheRectangles(rect, currentColor, currentBoarderColor, brushThickness));
        }
        else if (IsShapeCircle == true)
        {
            listOfShapes.Add(new TheCircles(rect, currentColor, currentBoarderColor, brushThickness));
        }
        else if (IsShapeLine == true)
        {
            listOfShapes.Add(new TheLines(startPoint, endPoint, currentColor, currentBoarderColor, brushThickness));
        }

        panelArea.Invalidate();
    }

    panelDraw.Invalidate();
}

3

Tôi khuyên bạn nên ghi đè OnPaintBackground và tự xử lý xóa nền. Nếu bạn biết bạn đang sơn toàn bộ điều khiển, bạn không thể làm gì trong OnPaintBackground (không gọi phương thức cơ sở) và nó sẽ ngăn màu nền được sơn trước


1
sau khi đọc lại câu hỏi của bạn, điều này có lẽ sẽ không thể giúp ích ... nào khác ngoài việc đề nghị có lẽ subclassing bảng điều khiển và cho phép bạn ghi đè OnPaint và OnPaintBackground, và làm bản vẽ của bạn có ...
Matt

3

Tôi biết đây là câu hỏi thực sự cũ nhưng có lẽ ai đó sẽ thấy nó hữu ích.
Tôi muốn cải thiện một chút cho câu trả lời của viper.

Bạn có thể tạo phần mở rộng đơn giản cho lớp Panel và ẩn thuộc tính cài đặt thông qua phản chiếu.

public static class MyExtensions {

    public static void SetDoubleBuffered(this Panel panel) {
        typeof(Panel).InvokeMember(
           "DoubleBuffered",
           BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty,
           null,
           panel,
           new object[] { true });
    }
}

Nếu tên biến Panel của bạn là myPanel, bạn chỉ cần gọi
myPanel.SetDoubleBuffered ();
và đó là nó. Mã trông sạch hơn nhiều.


3

Trong điều kiện này, bạn phải bật bộ đệm kép. Mở biểu mẫu hiện tại và đi đến các thuộc tính của biểu mẫu và áp dụng bộ đệm kép true; hoặc bạn cũng có thể viết mã này.

this.DoubleBuffered = true;     

Trong tải hình thức.


1

đây là chương trình di chuyển vòng tròn trong .net, không nhấp nháy.

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.Threading;
namespace CircleMove
{
    /// <summary>
    /// Description of MainForm.
    /// </summary>
    public partial class MainForm : Form
    {
        int x=0,y=0;
        Thread t;

        public MainForm()
        {

            //
            // The InitializeComponent() call is required for Windows Forms designer support.
            //
            InitializeComponent();

            //
            // TODO: Add constructor code after the InitializeComponent() call.
            //
        }
        void MainFormPaint(object sender, PaintEventArgs e)
        {
            Graphics g=e.Graphics;
            Pen p=new Pen(Color.Orange);
            Brush b=new SolidBrush(Color.Red);
        //  g.FillRectangle(b,0,0,100,100);
            g.FillEllipse(b,x,y,100,100);
        }
        void MainFormLoad(object sender, EventArgs e)
        {
            t=new Thread(  new ThreadStart(

                ()=>{
                    while(true)
                    {
                        Thread.Sleep(10);
                        x++;y++;
                        this.Invoke(new Action(
                            ()=>{

                                this.Refresh();
                                this.Invalidate();
                                this.DoubleBuffered=true;
                                }
                                            )
                                        );
                    }
                    }
                                            )

                        );

            t.Start();
        }
    }
}


1

Đó là một câu hỏi hơi và cũ, nhưng chỉ cần hoàn chỉnh: Vẫn còn một giải pháp khác, đã làm việc cho tôi khi bộ đệm kép không làm được.

Hóa ra là Microsoft cung cấp lớp BufferedGraphics như một giải pháp. Điều thú vị về lớp này là nó cho phép bạn sao chép một đối tượng Đồ họa này sang một đối tượng Đồ họa khác, vì vậy ngoại trừ việc thiết lập một đối tượng Đồ họa tạm thời và cuối cùng sao chép nó đến đích cuối cùng, người ta có thể sử dụng khá nhiều mã mà người ta đã làm khi sự nhấp nháy không phải là một vấn đề:

private void Indicator_Paint(object sender, PaintEventArgs e)
{
    Control pbIndicator = (Control)sender;
    Rectangle targetRect = pbIndicator.ClientRectangle;

    Image img = Bitmap.FromFile("bitmap.bmp");

    BufferedGraphicsContext ctx = new BufferedGraphicsContext();
    BufferedGraphics bg = ctx.Allocate(e.Graphics, targetRect);

    // Do the graphic stuff 
    bg.Graphics.Clear(this.BackColor);
    bg.Graphics.DrawImage(img, 0, 0);
    // etcetera

    bg.Render(e.Graphics);
    bg.Dispose();
    ctx.Dispose();
}

Nhược điểm của giải pháp này là nó có thể làm rối mã của bạn. Hơn nữa, tôi không chắc liệu có nên thiết lập ngữ cảnh mỗi lần hay không, hay liệu có đủ để tạo trước và tiếp tục sử dụng ngữ cảnh đó hay không.

Để biết thêm thông tin, hãy xem https://docs.microsoft.com/en-us/dotnet/api/system.drawing.bufferedgraphicscontext?view=dotnet-plat-ext-3.1


0

Nếu bộ nhớ chật hẹp (vì vậy bạn không muốn tốn bộ nhớ đệm gấp đôi), một cách có thể để GIẢM, mặc dù không loại bỏ hiện tượng nhấp nháy, là đặt màu nền thành màu chủ đạo trong cảnh hiện tại của bạn.

Tại sao điều này lại hữu ích: nhấp nháy là hiện tượng nhấp nháy tạm thời của màu nền mà Hệ điều hành vẽ trước khi vẽ các điều khiển con hoặc mã bản vẽ tùy chỉnh của bạn. Nếu đèn flash đó là màu gần với màu cuối cùng được hiển thị, nó sẽ ít được chú ý hơn.

Nếu bạn không chắc chắn nên bắt đầu với màu gì, hãy bắt đầu với 50% màu xám, vì đây là mức trung bình của màu đen và trắng, vì vậy sẽ gần với hầu hết các màu trong cảnh của bạn.

myFormOrControl.BackColor = Color.Gray;

0

Cố gắng chèn logic bản vẽ trong biểu mẫu hiện tại

protected override void OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);
}

phương pháp. Trong trường hợp này, bạn nên sử dụng tham số e để lấy đối tượng Graphics. Sử dụng thuộc tính e.Graphics. Sau đó, bạn nên gọi phương thức Invalidate () cho biểu mẫu này bất cứ khi nào biểu mẫu phải được vẽ lại. Tái bút: DoubleBuffered phải được đặt thành true.


0

Vẽ lên Nhãn thay vì Bảng, đã giải quyết được vấn đề cho tôi.

Không cần sử dụng DoubleBuffering hay bất cứ thứ gì.

Bạn có thể xóa văn bản khỏi nhãn, đặt Kích thước Tự động thành false, sau đó Gắn nó hoặc đặt Kích thước và sử dụng nó như cho Bảng điều khiển.

Lời chúc tốt nhất,


Lưu ý: Một ArgumentException được đưa ra sau khi Dispose () được gọi trên đối tượng Graphics từ PaintEventArgs. Điều này xảy ra khi Nhãn là Điều khiển đầu tiên (bậc cao nhất) trong cha mẹ.
ThrowNewRandomException

-2

Bạn có thể thử sử dụng bộ đếm thời gian và boolean để kiểm tra xem chuột có bị hỏng không và vẽ ở vị trí đó, sử dụng một biến lại để kiểm tra xem người dùng đã di chuyển chuột của mình chưa, nếu di chuyển thì sơn vị trí đó v.v.

Hoặc chỉ cần kiểm tra xem chuột xuống (thông qua boolean đặt true khi chuột không hoạt động) bằng cách sử dụng bộ đếm thời gian và tô nó xem có thể bạn đang cố chỉ vẽ một pixel, không giống như bạn có bóng, v.v. Thay vì sử dụng mousedown thực tế. Vì vậy, bạn kiểm tra mỗi 1 giây thay vì 0,0001 và nó sẽ không nhấp nháy. Hoặc ngược lại, hãy thử nó với thời gian của riêng bạn.


1
Hiện tượng nhấp nháy xảy ra khi màu nền (thường là màu trắng) của biểu mẫu hoặc điều khiển được vẽ và sau đó mã tùy chỉnh của bạn chạy để vẽ lại vùng bị ảnh hưởng. "Hiện tượng nhấp nháy" là sự lóe sáng nhất thời của màu nền. Việc giải quyết hiện tượng nhấp nháy yêu cầu bộ đệm kép, để hệ thống có một nơi mà từ đó nó có thể lấy nội dung mong muốn để khôi phục, thay vì vẽ màu nền. Đặt mã bản vẽ của bạn trên bộ đếm thời gian còn tệ hơn là không làm gì cả (tốn nhiều chu kỳ cpu mà không có lợi). Dựa vào hệ điều hành để cho bạn biết khi nào bạn cần vẽ, đừng cố gắng vẽ thông minh.
ToolmakerSteve

-2

chỉ làm this.Refresh()khi hiển thị biểu mẫu.


Xin lỗi? Điều này không trả lời câu hỏi.
Momoro
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.