重叠System.Drawing.Graphics对象 [英] Overlapping System.Drawing.Graphics objects

查看:200
本文介绍了重叠System.Drawing.Graphics对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个WinForms控制上,我想显示两件事情:

I have a WinForms control on which I want to display two things:

  1. 在精心加载的底层图像逐位从外部输入设备;和
  2. 一系列的创建一个视觉图像通过该图像DrawLine的电话。

事#1,我们的目的是不会改变的,我宁愿没有重新绘制它。

Thing #1, for our purposes, doesn't change, and I'd rather not have to redraw it.

东西#2已被相对快速地重新绘制的,因为它的用户接通另一控制时旋转。

Thing #2 has to be redrawn relatively quickly, as it rotates when the user turns another control.

在我的幻想,我希望把每一件事情在自己的图形对象,给#2透明背景,并简单地打#2旋转变换,来匹配用户控制设置。但我不明白的方式,使Graphics对象透明,也没有办法转动什么已经绘制于一体。所以我可能会问图形做一些它不适合。

In my fantasy, I want to put each Thing in its own Graphics object, give #2 a transparent background, and simply hit #2 with a rotational transformation to match the user control setting. But I don't see a way to make a Graphics object transparent, nor a way to rotate what's already been drawn on one. So I'm probably asking Graphics to do something it wasn't designed for.

下面是我的问题:什么是设置它的最好方法是什么?我应该尝试我的重叠图形对象,或者是有一些完全不同的,更好的方式来做到这一点,我没有想到的?

Here's my question: What's the best way to set this up? Should I attempt to overlap my Graphics objects, or is there some completely different and better way to do this that I'm not thinking of?

推荐答案

在Windows绘画模型是适合您的需求。它分离借鉴前景(的OnPaint)背景(OnPaintBackground)。然而,这并不意味着你只能绘制背景一次,并用它做。窗表面失效调用两个。这是首先需要进行反锯齿效果正常工作,他们只能好看针对已知的背景颜色。

The Windows painting model is a good match for your requirements. It separates drawing the background (OnPaintBackground) from the foreground (OnPaint). That however doesn't mean that you can only paint the background once and be done with it. Window surface invalidation invokes both. This is above all required to make anti-aliasing effects work properly, they can only look good against a known background color.

平底船这一点,并绘制图像在OnPaintBackground()重写。你可以让控制做到这一点自动为您分配BackgroundImage属性。你可能需要将DoubleBuffer属性设置为true,避免闪烁,你会看到当背景绘制,暂时扫除前景像素。调用invalidate(),如果你需要更新的前景。

Punt this and draw the Image in the OnPaintBackground() override. You can let Control do this automatically for you by assigning the BackgroundImage property. You'll probably need to set the DoubleBuffer property to true to avoid the flicker you'll see when the background is drawn, temporarily wiping out the foreground pixels. Call Invalidate() if you need to update the foreground.

要完成,你的幻想,其实是可能的。你需要覆盖的图像与顶层分层的窗口。这是很容易得到与他们的TransparencyKey属性设置表单。下面是一个简单的实现:

To be complete, your fantasy is in fact possible. You'd need to overlay the image with a toplevel layered window. That is easy to get with a Form whose TransparencyKey property is set. Here is a sample implementation:

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

class OverlayedPictureBox : PictureBox {
    private Form mOverlay;
    private bool mShown;
    public event PaintEventHandler PaintOverlay;
    public OverlayedPictureBox() {
        mOverlay = new Form();
        mOverlay.FormBorderStyle = FormBorderStyle.None;
        mOverlay.TransparencyKey = mOverlay.BackColor = Color.Magenta;
        mOverlay.ShowInTaskbar = false;
    }
    protected void OnPaintOverlay(PaintEventArgs e) {
        // NOTE: override this or implement the PaintOverlay event
        PaintEventHandler handler = PaintOverlay;
        if (handler != null) handler(this, e);
    }
    public void RefreshOverlay() {
        // NOTE: call this to force the overlay to be repainted
        mOverlay.Invalidate();
    }
    protected override void Dispose(bool disposing) {
        if (disposing) mOverlay.Dispose();
        base.Dispose(disposing);
    }
    protected override void OnVisibleChanged(EventArgs e) {
        if (!mShown && !this.DesignMode) {
            Control parent = this.Parent;
            while (!(parent is Form)) parent = parent.Parent;
            parent.LocationChanged += new EventHandler(parent_LocationChanged);
            mOverlay.Paint += new PaintEventHandler(mOverlay_Paint);
            mOverlay.Show(parent);
            mShown = true;
        }
        base.OnVisibleChanged(e);
    }
    protected override void OnLocationChanged(EventArgs e) {
        mOverlay.Location = this.PointToScreen(Point.Empty);
        base.OnLocationChanged(e);
    }
    protected override void OnSizeChanged(EventArgs e) {
        mOverlay.Size = this.Size;
        base.OnSizeChanged(e);
    }
    void parent_LocationChanged(object sender, EventArgs e) {
        mOverlay.Location = this.PointToScreen(Point.Empty);
    }
    private void mOverlay_Paint(object sender, PaintEventArgs e) {
        OnPaintOverlay(e);
    }
}

一个有趣的神器:最小化的形式,并再次恢复它看起来,嗯,特别

One interesting artifact: minimizing the form and restoring it again looks, erm, special.

这篇关于重叠System.Drawing.Graphics对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆