重叠System.Drawing.Graphics对象对象、System、Drawing、Graphics

2023-09-04 05:12:01 作者:『我的心,留着你、』

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

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

在精心加载的底层图像逐位从外部输入设备;和 一系列的创建一个视觉图像通过该图像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.

 
精彩推荐
图片推荐