2016-05-31 111 views
2

我發現這個問題(如其他一些),但是這是一個到目前爲止,我已經實現了:增強十字光標可能嗎?

Crosshair cursor with additional lines in C#

因爲它規定,我可以直接用股票光標「跨界」 IDE。這是一種非常好的做事方式。在上面的答案中指定的答案在給定的寬度/高度處在屏幕上繪製了一個十字。例如:

private Cursor crossCursor(Pen pen, Brush brush, int x, int y) 
{ 
    var pic = new Bitmap(x, y); 
    Graphics gr = Graphics.FromImage(pic); 

    var pathX = new GraphicsPath(); 
    var pathY = new GraphicsPath(); 
    pathX.AddLine(0, y/2, x, y/2); 
    pathY.AddLine(x/2, 0, x/2, y); 
    gr.DrawPath(pen, pathX); 
    gr.DrawPath(pen, pathY); 

    IntPtr ptr = pic.GetHicon(); 
    var c = new Cursor(ptr); 
    return c; 
} 

我的問題是,我想我的十字線,以擴大界的可視面積。這裏提供上下文,我有:

//Form 
    //TableLayoutPanel 
     //UserControl (fills the TableLayoutPanel visible area) 

因此,如何能調整我的光標,線(在CAD pacakages很像)延伸?

感謝。

更新:我已經打過電話,從這裏的方法:

protected override void OnLoad(System.EventArgs e) 
{ 
    Cursor = crossCursor(Pens.WhiteSmoke, Brushes.WhiteSmoke, Bounds.Width, Bounds.Height); 
} 

但它也不行,因爲在時間界限是150返回的150的尺寸這一點是不是TableLayoutPanel的大小。

更新:我已經adjuted它使用調整大小處理程序,而不是和它改善的事情:

protected override void OnResize(EventArgs e) 
{ 
    base.OnResize(e); 

    Cursor = crossCursor(Pens.WhiteSmoke, Brushes.WhiteSmoke, Bounds.Width, Bounds.Height); 
} 

唯一的問題,現在(和它種是有道理的,我想)是將光標只有當視圖爲中心時才佔用視圖的全部寬度和高度。只要我移動光標不調整的視圖。我總是希望通過鼠標位置的水平/垂直線(不只是最初的十字)。

參見:

Crosshairs

十字的需要延伸(較厚的紅線)。當鼠標移動或以另一種方式構建兩條線時,我需要不斷創建光標。該怎麼辦?

我碰到這樣的:

https://social.msdn.microsoft.com/Forums/vstudio/en-US/7bdbad6d-1f65-461b-8f0c-6ef4f243fa6b/crosshair-cursor-using-c?forum=csharpgeneral

因此,而不是改變光標對象我現在繪製控件的MouseMove處理線:

Region r = new Region(); 
r.Union(new Rectangle(0, lastY, this.Width, 1)); 
r.Union(new Rectangle(lastX, 0, 1, this.Height)); 
this.Invalidate(r); 
this.Update(); 
Graphics g = Graphics.FromHwnd(this.Handle); 
g.DrawLine(Pens.White, 0, e.Y, this.Width, e.Y); 
g.DrawLine(Pens.White, e.X, 0, e.X, this.Height); 
int intDiameter = 20;//the diameter of this circle 
g.DrawEllipse(Pens.White, e.X - intDiameter/2, e.Y - intDiameter/2, 20, 20); 
//to draw the circle 
lastX = e.X; 
lastY = e.Y; 

它的工作原理,但我得到noticiable屏幕閃爍這樣做。

+0

貌似這正是它應該做的。你應該通過'界限。寬度'爲X和'Bounds.Height'爲Y. – DonBoitnott

+0

@DonBoitnott謝謝,請參閱我的更新問題。 –

+1

你應該掛鉤一個'Resize'事件而不是'Load'事件。這樣,您不僅可以第一次獲得正確的「Bounds」,但每次調整窗體大小時都可以進行更新。 – DonBoitnott

回答

1

您不需要創建遊標。您可以創建雙緩衝控制並繪製交叉控制。

using System; 
using System.Drawing; 
using System.Windows.Forms; 
public class DrawingSurface : Control 
{ 
    Pen crossPen; 
    Pen rectanglePen; 
    Brush rectangleBrush; 

    public DrawingSurface() 
    { 
     this.DoubleBuffered = true; 
     this.ResizeRedraw = true; 
     crossPen = new Pen(Color.Red, 2); 
     rectangleBrush = new SolidBrush(Color.FromArgb(50, Color.Blue)); 
     rectanglePen = new Pen(Color.Blue, 1); 
    } 
    bool mouseDown = false; 
    Point startPoint = Point.Empty; 
    Point endPoint = Point.Empty; 
    protected override void OnMouseDown(MouseEventArgs e) 
    { 
     startPoint = e.Location; 
     mouseDown = true; 
     base.OnMouseDown(e); 
    } 
    protected override void OnMouseUp(MouseEventArgs e) 
    { 
     mouseDown = false; 
     base.OnMouseUp(e); 
    } 
    protected override void OnMouseMove(MouseEventArgs e) 
    { 
     endPoint = e.Location; 
     this.Invalidate(); 
     base.OnMouseMove(e); 
    } 
    protected override void OnPaint(PaintEventArgs e) 
    { 
     var g = e.Graphics; 

     if (this.ClientRectangle.Contains(endPoint)) 
      DrawCross(e.Graphics, endPoint); 

     if (mouseDown) 
      DrawRectangle(e.Graphics, startPoint, endPoint); 
    } 

    void DrawCross(Graphics g, Point point) 
    { 
     g.DrawLine(crossPen, new Point(0, point.Y), new Point(Width, point.Y)); 
     g.DrawLine(crossPen, new Point(point.X, 0), new Point(point.X, Height)); 
    } 
    void DrawRectangle(Graphics g, Point point1, Point point2) 
    { 
     var rectangle = new Rectangle(
      Math.Min(point1.X, point2.X), Math.Min(point1.Y, point2.Y), 
      Math.Abs(point1.X - point2.X), Math.Abs(point1.Y - point2.Y)); 

     g.FillRectangle(rectangleBrush, rectangle); 
     g.DrawRectangle(rectanglePen, rectangle); 
    } 
    protected override void Dispose(bool disposing) 
    { 
     crossPen.Dispose(); 
     rectanglePen.Dispose(); 
     rectangleBrush.Dispose(); 
     base.Dispose(disposing); 
    } 
} 

enter image description here

+0

謝謝。原則上你說的是正確的。但是我所遇到的問題是由於我現在糾正的內部視圖對象。所以現在我知道如何正確地將內部視圖對象渲染到位圖上(使用任何圖形)。一切都很好。 :) –

+0

不客氣。看來你是你在正確的方向:) –