3

ユーザーがマウスを使用して長方形をペイントできるWPFアプリケーションを作成するのがいかに簡単であるかをよく知っています。これを行うには、Rectangleコントロールを作成してその座標を設定するだけで、DoubleBufferingや再描画などについて心配する必要はありません。ユーザーがさまざまな形状をペイントできるアプリケーションにWPFを使用できることを非常に嬉しく思いますが、クライアントはWinFormsアプリケーションであると主張しています。したがって、ここでの解決策は、古き良きWinAPIの年のようにXORまたはROP演算を使用することであり、私はこれがあまり好きではありません。これでは、XORモードでテキストを移動するための優れたオプションは提供されません。

そのため、WPFの場合と同じように、WinFormsアプリケーションでスムーズなペイントエクスペリエンスを実現するにはどうすればよいかを考えていました。このようなコードをまとめると、残りのオブジェクトはそのままにして、現在の形状をペイントする別のレイヤーを作成したいと思いました。私はiPadアプリケーションで同じテクニックを使用し、かなりうまく機能しました。

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

namespace TestPainting
{
    public partial class Form1 : Form
    {
        private bool _isMouseDown;
        private Graphics _bufferGraphics;
        private Point _startPos;
        private TransparentPanel _paintBuffer;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void Form1_MouseDown(object sender, MouseEventArgs e)
        {
            _isMouseDown = true;
            _paintBuffer = new TransparentPanel
                            {
                                Size = Size,
                            };
            Controls.Add(_paintBuffer);
            _paintBuffer.BringToFront();

            _bufferGraphics = Graphics.FromHwnd(_paintBuffer.Handle);
            _startPos = e.Location;
            Capture = true;
        }

        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            if (!_isMouseDown)
                return;

            _bufferGraphics.Clear(Color.Transparent);
            _bufferGraphics.DrawRectangle(Pens.Green, _startPos.X, _startPos.Y, e.X - _startPos.X, e.Y - _startPos.Y);

        }

        private void Form1_MouseUp(object sender, MouseEventArgs e)
        {
            _isMouseDown = false;
            Capture = false;
            _bufferGraphics.Dispose();
            Controls.Remove(_paintBuffer);
            _paintBuffer.Dispose();
        }
    }

    public class TransparentPanel : Panel
    {
        public TransparentPanel()
        {
            DoubleBuffered = true;
        }

        [Browsable(false)]
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x20;
                return cp;
            }
        }

        protected override void OnPaintBackground(PaintEventArgs e)
        {
            // Do Nothing
        }
    }
}

コースが必要に応じて機能しない場合。マウスを押すと、透明なパネルではなく黒いパネルが表示されます。さらに、DoubleBufferingを設定したにもかかわらず、ペイント中の長方形がちらつきます。

誰かがそのような実装のより良いアイデアを提供できますか、あるいは他の人々がどのようにやっているかを見ることができる他のオープンソースプロジェクトがあるかもしれません。Paint.NETと同じ経験が必要ですが、あまりにも悪いのはもうオープンソースではありません。(私はReflectorを使用できることを知っています、そして私は使用しました、しかし男、あそこにはたくさんのコードがあります:))

どんなアイデアでもThx。

4

1 に答える 1

0

これを試してください (FIX #1 と FIX #2 を参照):

    private void Form1_MouseDown( object sender, MouseEventArgs e )
    {
        _isMouseDown = true;
        _paintBuffer = new TransparentPanel
        {
            Size = Size,
        };
        Controls.Add( _paintBuffer );
        _paintBuffer.BringToFront();

        // FIX #1:
        //
        this.Refresh();

        _bufferGraphics = Graphics.FromHwnd( _paintBuffer.Handle );

        _startPos = e.Location;
        Capture = true;
    }

    private void Form1_MouseMove( object sender, MouseEventArgs e )
    {
        if ( !_isMouseDown )
            return;

        //FIX #2:
        //   _bufferGraphics.Clear( Color.Transparent );
        _bufferGraphics.Clear( this.BackColor );

        _bufferGraphics.DrawRectangle( Pens.Green, _startPos.X, _startPos.Y, e.X - _startPos.X, e.Y - _startPos.Y );

    }
于 2012-06-01T19:06:53.863 に答える