【问题标题】:why is rendering turning form black为什么渲染变成黑色
【发布时间】:2017-09-02 13:45:35
【问题描述】:

我正在使用眼动仪在表单上显示眼动。运动一直在闪烁,所以我发现我可以使用 BufferedGraphics 一切正常,除了当眼球运动开始时,它会将表单从原始颜色变为黑色。这是代码。希望有人可以提供帮助!

private void button2_Click(object sender, EventArgs e)
{
    var host = new Host();
    var gazeStream = host.Streams.CreateGazePointDataStream();
    gazeStream.GazePoint((x, y, ts) 
         => drawCircle(new PointF((float)x, (float)y)));
}

delegate void SetCallback(PointF point);

private void drawCircle(PointF point)
{
    float x = point.X;
    float y = point.Y;

    if (this.InvokeRequired)
    {
        SetCallback d = new SetCallback(drawCircle);
        this.Invoke(d, new object[] { point });
    }
    else
    {
        SolidBrush semiTransBrush = new SolidBrush(Color.Coral);
        Pen pen = new Pen(Color.Aquamarine, 2);

        BufferedGraphicsContext currentContext;
        BufferedGraphics myBuffer;
        // Gets a reference to the current BufferedGraphicsContext
        currentContext = BufferedGraphicsManager.Current;
        // Creates a BufferedGraphics instance associated with Form1, and with 
        // dimensions the same size as the drawing surface of Form1.
        myBuffer = currentContext.Allocate(this.CreateGraphics(),this.DisplayRectangle);
        myBuffer.Graphics.DrawEllipse(pen, x, y, 100, 100);
        myBuffer.Graphics.FillEllipse(semiTransBrush, x, y, 100, 100);


        // Renders the contents of the buffer to the specified drawing surface.
        myBuffer.Render(this.CreateGraphics());

        myBuffer.Dispose();
    }

您可以在图像中看到圆圈出现在控件后面,看起来好像表单消失了?

【问题讨论】:

  • 在绘制形状之前尝试myBuffer.Graphics.Clear(this.BackColor); - 如果表单上没有其他内容
  • 我在表单上有单选按钮和标签。控件仍然显示。看起来好像表单的背景已经被移除,而不是颜色只是改变了
  • 问题的代码在哪里?显示有关该方法的更多详细信息
  • 好的,我添加了更多信息。但我不确定这会有所不同
  • 谁能帮忙?????????

标签: c# winforms rendering buffering


【解决方案1】:

当您分配缓冲区时,它会创建一个与您提供的图形兼容的渲染表面。但它不会复制它或任何东西,所以如果你只画一个圆圈,其余部分仍然是黑色。

BufferedGraphics 确实可以帮助您避免特殊情况下的闪烁(例如,当系统双缓冲由于某种原因必须禁用时),但这里有点过头了。

所以关键是启用双缓冲并在Paint 事件(或OnPaint 方法)中进行每一次绘制。在您的代码中,您会立即进行绘制,但总是会闪烁。相反,您应该使表单无效并让系统执行定期重绘会话,如果您愿意,可以使用双缓冲。

进入构造函数:

SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);

然后修改点击事件:

private PointF lastGazePoint;

private void button2_Click(object sender, EventArgs e)
{
    var host = new Host();
    var gazeStream = host.Streams.CreateGazePointDataStream();
    gazeStream.GazePoint((x, y, ts) => 
        {
            lastGazePoint = new PointF((float)x, (float)y);
            Invalidate();
        });
 }

这幅画本身:

protected override void OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);
    DrawCircle(e.Graphics, lastGazePoint.X, lastGazePoint.Y);
}

最后,修改DrawCircle 以使用来自PaintEventArgsGraphics

private void DrawCircle(Graphics g, float x, float y)
{
    using (Brush semiTransBrush = new SolidBrush(Color.Coral))
    {
        using (Pen pen = new Pen(Color.Aquamarine, 2))
        {
            g.DrawEllipse(pen, x, y, 100, 100);
            g.FillEllipse(semiTransBrush, x, y, 100, 100);
        }        
    }        
}

【讨论】:

  • 感谢工作。只需要弄清楚如果用户从屏幕上移开并再次回到屏幕上,如何保持圆圈移动
  • 您好,我正在尝试使用相同的逻辑从 xml 文件中播放圆圈运动。我能够读取文件并对其进行解析以获取 x 和 y,但圆圈只会绘制一次。我使用相同的 Draw circle 和 onPaint 方法,但这次我有另一种方法来检索坐标 public void EyeMove(float x, float y) { point = new PointF(x, y); }
  • 您应该提供一些详细信息。如果没有源代码,我只能怀疑您在播放动画时阻塞了 UI 线程,您只会看到最后一帧。重播引擎不应包含Thread.Sleep 或类似的线程阻塞技术。如果信息不足,请发布另一个包含详细信息的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-27
  • 1970-01-01
  • 1970-01-01
  • 2017-09-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多