2016-05-31 22 views
0

は、私は、次のコードを採用することにより、ゴムバンドを実装している:それは作品それ自体私のラバーバンドのちらつきを防ぎますか?

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Drawing; 
using System.Drawing.Drawing2D; 
using System.Data; 
using System.Text; 
using System.Windows.Forms; 
using System.IO; 
using System.Reflection; 

namespace Test 
{ 
    public partial class TestX: UserControl 
    { 
     private Boolean m_bLeftButton { get; set; } 
     private Boolean m_bMiddleButton { get; set; } 
     private Boolean m_bZoomWindow { get; set; } 

     Point m_ptOriginal = new Point(); 
     Point m_ptLast = new Point(); 

     public TestX() 
     { 
      m_bZoomWindow = false; 
      m_bLeftButton = false; 
      m_bMiddleButton = false; 
     } 

     // Called when the left mouse button is pressed. 
     public void MyMouseDown(Object sender, MouseEventArgs e) 
     { 
      if(m_bZoomWindow && e.Button == MouseButtons.Left) 
      { 
       // Make a note that we "have the mouse". 
       m_bLeftButton = true; 

       // Store the "starting point" for this rubber-band rectangle. 
       m_ptOriginal.X = e.X; 
       m_ptOriginal.Y = e.Y; 
       // Special value lets us know that no previous 
       // rectangle needs to be erased. 
       m_ptLast.X = -1; 
       m_ptLast.Y = -1; 
      } 
     } 

     // Convert and normalize the points and draw the reversible frame. 
     private void MyDrawReversibleRectangle(Point p1, Point p2) 
     { 
      Rectangle rc = new Rectangle(); 

      // Convert the points to screen coordinates. 
      p1 = PointToScreen(p1); 
      p2 = PointToScreen(p2); 
      // Normalize the rectangle. 
      if (p1.X < p2.X) 
      { 
       rc.X = p1.X; 
       rc.Width = p2.X - p1.X; 
      } 
      else 
      { 
       rc.X = p2.X; 
       rc.Width = p1.X - p2.X; 
      } 
      if (p1.Y < p2.Y) 
      { 
       rc.Y = p1.Y; 
       rc.Height = p2.Y - p1.Y; 
      } 
      else 
      { 
       rc.Y = p2.Y; 
       rc.Height = p1.Y - p2.Y; 
      } 
      // Draw the reversible frame. 
      ControlPaint.DrawReversibleFrame(rc, 
          Color.WhiteSmoke, FrameStyle.Thick); 
     } 

     // Called when the left mouse button is released. 
     public void MyMouseUp(Object sender, MouseEventArgs e) 
     { 
      if(m_bZoomWindow && e.Button == MouseButtons.Left) 
      { 
       // Set internal flag to know we no longer "have the mouse". 
       m_bZoomWindow = false; 
       m_bLeftButton = false; 

       // If we have drawn previously, draw again in that spot 
       // to remove the lines. 
       if (m_ptLast.X != -1) 
       { 
        Point ptCurrent = new Point(e.X, e.Y); 
        MyDrawReversibleRectangle(m_ptOriginal, m_ptLast); 

        // Do zoom now ... 
       } 
       // Set flags to know that there is no "previous" line to reverse. 
       m_ptLast.X = -1; 
       m_ptLast.Y = -1; 
       m_ptOriginal.X = -1; 
       m_ptOriginal.Y = -1; 
      } 
     } 

     // Called when the mouse is moved. 
     public void MyMouseMove(Object sender, MouseEventArgs e) 
     { 
      Point ptCurrent = new Point(e.X, e.Y); 

      if(m_bLeftButton) 
      { 
       // If we "have the mouse", then we draw our lines. 
       if (m_bZoomWindow) 
       { 
        // If we have drawn previously, draw again in 
        // that spot to remove the lines. 
        if (m_ptLast.X != -1) 
        { 
         MyDrawReversibleRectangle(m_ptOriginal, m_ptLast); 
        } 
        // Update last point. 
        if(ptCurrent != m_ptLast) 
        { 
         m_ptLast = ptCurrent; 
         // Draw new lines. 
         MyDrawReversibleRectangle(m_ptOriginal, ptCurrent); 
        } 
       } 
      } 
     } 

     // Set up delegates for mouse events. 
     protected override void OnLoad(System.EventArgs e) 
     { 
      MouseDown += new MouseEventHandler(MyMouseDown); 
      MouseUp += new MouseEventHandler(MyMouseUp); 
      MouseMove += new MouseEventHandler(MyMouseMove); 
      MouseWheel += new MouseEventHandler(MyMouseWheel); 

      m_bZoomWindow = false; 
     } 
    } 
} 

が、四角形が点滅:

https://support.microsoft.com/en-gb/kb/314945

これは私のコードです。 CADパッケージのような他のプログラムでは、矩形を描くときにちらつきがゼロになります。

私のフォームはDoubleBufferingを使用するように設定されていますので、問題ありません。他の誰かがこの問題に遭遇しましたか?

更新:私は最初に戻って、テーブルレイアウトパネルと埋め込みユーザーコントロールでテストwinformsプロジェクトを実行すると考えました。私はユーザーコントロールが私が提供された答えのように動作するように設定しました。

public MyUserControl() 
{ 
    InitializeComponent(); 

    _selectionPen = new Pen(Color.Black, 3.0f); 

    SetStyle(ControlStyles.OptimizedDoubleBuffer | 
      ControlStyles.AllPaintingInWmPaint | 
      ControlStyles.UserPaint, true); 
    BackColor = Color.Transparent; 
    Dock = DockStyle.Fill; 
    Margin = new Padding(1); 
} 

お知らせAllPaintingInWmPaintUserPaint追加のコントロールスタイル:唯一の違いは、私はこのようなユーザーコントロールのコンストラクタを設定することでしたか?それはOptimizedDoubleBufferスタイルに加えてこれらを必要としていたようです。私はダブルバッファリングとしてフォームを設定します。

これらの調整を行うと、フリッカーフリーのゴムバンドを描くことができます。ホア!しかし、ユーザーコントロールにDWGをレンダリングするために埋め込みクラスに追加したとき、私は他のものを当てにすることと比べて1つのコンフリクトを取得します。

私はここにいるので、私はDWGビューアクラスのベンダーから何が得られるかを見ていきます。

+0

私はそのdupリンクを削除私はOPがデスクトップまたは複数のコントロールをラバーバンド化しようとしていると思っているから)。 – LarsTech

+0

私のフォームには、パネルを埋めるためにドッキングされたUserControlを持つTableLayoutPanelがあります。 UserControlも図面を描画します(わかりやすくするためにこのコードを削除しました)。ユーザーは、1つのUserControlオブジェクトに長方形をドラッグしています。 –

+1

あなたは 'MouseMove'に矩形を描画していますか? 'MouseMove'の座標を追跡し、実際の描画呼び出しを' Paint'イベントに移動するだけです。マウス移動中にアクションがフォームを無効にすると、ペイントが呼び出されます。そうでない場合は、矩形を上書きします。 'MouseMove'からいつでも' Invalidate'を呼び出して強制的に再描画することができます。 – jimbobmcgee

答えて

1

私のコメントからOPへのPaintイベントの使用を実証するために。

Paintに設定し、コントロール上にControlStyles.OptimizeDoubleBufferを設定すると、最もスムーズなボックスドローが得られました。もちろん、それはあなたのボックスの意図された範囲に依存します - これはコントロール自体の境界を超えません(すなわち、フォームやデスクトップに描画されません):

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

namespace WinformsScratch.RubberBand 
{ 
    public class TestY : Control 
    { 
     private Point? _selectionStart; 
     private Point? _selectionEnd; 

     private readonly Pen _selectionPen; 

     public TestY() 
     { 
      _selectionPen = new Pen(Color.Black, 3.0f); 

      SetStyle(ControlStyles.OptimizedDoubleBuffer, true); 

      MouseDown += (s, e) => { 
       if (e.Button == MouseButtons.Left) 
        _selectionStart = _selectionEnd = e.Location; 
      }; 

      MouseUp += (s, e) => { 
       if (e.Button == MouseButtons.Left) 
       { 
        _selectionStart = _selectionEnd = null; 
        Invalidate(false); 
       } 
      }; 

      MouseMove += (s, e) => { 
       if (_selectionStart.HasValue && 
        _selectionEnd.HasValue && 
        _selectionEnd.Value != e.Location) 
       { 
        _selectionEnd = e.Location; 
        Invalidate(false); 
       } 
      }; 

      Paint += (s, e) => { 
       if (_selectionStart.HasValue && _selectionEnd.HasValue) 
        e.Graphics.DrawRectangle(_selectionPen, GetSelectionRectangle()); 
      }; 
     } 

     protected override void Dispose(bool disposing) 
     { 
      if (disposing) 
      { 
       if (_selectionPen != null) _selectionPen.Dispose(); 
      } 
      base.Dispose(disposing); 
     } 

     private Rectangle GetSelectionRectangle() 
     { 
      Rectangle rc = new Rectangle(); 

      if (_selectionStart.HasValue && _selectionEnd.HasValue) 
      { 
       // Normalize the rectangle. 
       if (_selectionStart.Value.X < _selectionEnd.Value.X) 
       { 
        rc.X = _selectionStart.Value.X; 
        rc.Width = _selectionEnd.Value.X - _selectionStart.Value.X; 
       } 
       else 
       { 
        rc.X = _selectionEnd.Value.X; 
        rc.Width = _selectionStart.Value.X - _selectionEnd.Value.X; 
       } 

       if (_selectionStart.Value.Y < _selectionEnd.Value.Y) 
       { 
        rc.Y = _selectionStart.Value.Y; 
        rc.Height = _selectionEnd.Value.Y - _selectionStart.Value.Y; 
       } 
       else 
       { 
        rc.Y = _selectionEnd.Value.Y; 
        rc.Height = _selectionStart.Value.Y - _selectionEnd.Value.Y; 
       } 
      } 

      return rc; 
     } 
    } 
} 
+0

ありがとうございます。私はこのラバーバンドの矩形クラスを朝にしよう!意図した境界に関しては、基本的には一時的なズームウィンドウです。したがって、描画されると、新しいデータがレンダリングされると消滅します。 –

+0

克服するにはzオーダーの問題があるかもしれません。そのため、コントロールの基本色を透明にし、 'this.BringToFront()'を使用してズームしているものにオーバーレイする必要があります。 – jimbobmcgee

+0

ご協力いただきありがとうございます。私はそれを追加しましたが、あなたが思ったように、私は矩形の描画とそのデータを描画するインターバルビューオブジェクトの間で戦いがあります。だから問題があったかもしれない両者の間に戦いが起こっている。では、矩形をレンダリングするための専用のコントロールを提案していますか?私が得たマウスの移動イベントなどは、usercontrolオブジェクトの場合のみです。 –

関連する問題