0

ユーザー コントロールにグラフのようなものを描画する GDI+ を使用した複雑な描画コードを所有していました。ユーザーがコントロールを押したままクリックすると、ダッシュ スタイルの垂直マーカー ラインが表示されます。

ここで、複雑な描画コードに手を加えることなく、描画コードを拡張する方法を探しています。

ユーザー コントロールのマウスアップ イベントにアタッチするマーカー クラスを作成しました。イベントハンドラでチェック(ModifierKeys == Keys.Control)が行われます。

ユーザーがコントロール キーを押したままマウスの左ボタンをクリックすると、ユーザー コントロールのGraphicsオブジェクトをパラメーターとしてマーカー クラスの draw メソッドが呼び出されます。

現在の動作では、クリックするたびに新しい線が描画されますが、線を削除して新しい線を描画する必要があります。

描いた線を消すにはどうすればいいですか?

ユーザー コントロールの完全なコンテンツを再描画する必要がありますか?

4

2 に答える 2

3

下にあるグラフィックを復元する方法がないため、描画された線を削除することはできません。

あなたができることは次のいずれかです:

  • グラフ全体を再描画します (線なし)

また

  • 2 つ目の透明なユーザー コントロールを上に重ね、それを使用して線を表示します。必要に応じて削除して描画します。
于 2012-08-05T13:26:05.457 に答える
2

ここでの答えは明らかにイエスです。GDI+ を使用すると、ビットマップ バッファーに直接描画するだけなので、以前の描画操作を元に戻したい場合は、次のいずれかを実行できます (問題の複雑さとパフォーマンスによって異なります)。

  • ビットマップバッファで変更されたバイトを復元します
  • 描画ビットマップの前の状態を再読み込みします

簡単な解決策は、2 つのビットマップを使用することです (このようなことは、通常、ダブル バッファリングと呼ばれます)。現在表示されているもの (および最終状態が含まれているもの) と、プレビューのみに使用されるものです。プレビュー 1 は、常に最初の 1 のコピーです - 現在の変更のみです。

この単純な実装の基本的なアルゴリズムは次のとおりです。

  • 2 つのビットマップ (空白だが同じサイズ) [A と B という名前] から開始します。
  • ユーザーが線を描く場合、常にビットマップ A のコピーを B に作成し、B に描画します - B を表示します
  • ユーザーが行を終了したら、A に B のコピーを作成し、もう一度 B を表示します。

そのため、元のビットマップを変更しただけのプレビュー ビットマップを常に表示します。

C# でのプログラミング コードの例を次に示します (すべてのイベントが接続され、プレビュー ビットマップ B がピクチャ ボックス自体であると仮定します (ここでは、pictureBox1 という名前になっています)。

Bitmap bmp;
bool isDrawing;
Point previous;

void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
    isDrawing = true;
    previous = e.Location;
}

void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
    isDrawing = false;
}

void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
    if (isDrawing)
    {
        using (Graphics g = Graphics.FromImage(bmp))
        {
            double wf = (double)bmp.Width / (double)pictureBox1.Width;
            double hf = (double)bmp.Height / (double)pictureBox1.Height;
            g.ScaleTransform((float)wf, (float)hf);
            g.DrawLine(Pens.Black, e.Location, previous);
        }

        pictureBox1.Refresh();
        previous = e.Location;
    }
}

このコードは、マウスの左ボタンを押すだけで、ある点から別の点への直線の描画を表示するためにあらゆることを行います。

于 2012-08-05T13:26:54.240 に答える