您知道,我們可以輕松地為圖表制作線條游標(例如:圖)。但是有了 PictureBox,我該怎么做呢?有沒有人有解決方案?

uj5u.com熱心網友回復:
您可以攔截 MouseMove 和 Paint 事件。只需在油漆上畫十字。
使用 Paint 方法的好處是,原始影像不會發生變化,因此不需要恢復被十字準線覆寫的像素。
下面是一個例子:
我在 winform 上放置了一個圖片框并鏈接了一些事件。
using System;
using System.Drawing;
using System.Windows.Forms;
namespace MouseCrosshair
{
public partial class Form1 : Form
{
// to store the latest mouse position
private Point? _mousePos;
// the pen to draw the crosshair.
private Pen _pen = new Pen(Brushes.Red);
public Form1()
{
InitializeComponent();
}
private void pictureBox1_MouseEnter(object sender, EventArgs e)
{
// when the mouse enters the picturebox, we just hide it.
Cursor.Hide();
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
var pictureBox = (PictureBox)sender;
// on a mouse move, save the current location (to be used when drawing the crosshair)
_mousePos = e.Location;
// force an update to the picturebox.
pictureBox.Invalidate();
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
// if the mousepos is assigned (meaning we have a mouse pos, draw the crosshair)
if (_mousePos.HasValue)
{
var pictureBox = (PictureBox)sender;
// draw a vertical line
e.Graphics.DrawLine(_pen, new Point(_mousePos.Value.X, 0), new Point(_mousePos.Value.X, pictureBox.Height));
// draw a horizontal line
e.Graphics.DrawLine(_pen, new Point(0, _mousePos.Value.Y), new Point(pictureBox.Width, _mousePos.Value.Y));
}
}
private void pictureBox1_MouseLeave(object sender, EventArgs e)
{
// when the mouse is outside the picturebox, clear the mousepos
_mousePos = null;
// repaint the picturebox
pictureBox1.Invalidate();
// show the mouse cursor again.
Cursor.Show();
}
}
}
由于事件使用sender,您可以將多個圖片框鏈接到這些事件。
也可以從 繼承PictureBox,并撰寫一個新CrosshairPictureBox控制元件,默認情況下它有一個十字準線。
如果您想在 a 中繪制圖表PictureBox,請使用 aBitmap并使用繪制該圖表Graphics.FromImage(bitmap)并將其放入PictureBox.Image. 不要忘記處理 Graphics 物件。
uj5u.com熱心網友回復:
您可以通過存盤接收到的最后一個點的位置來實作這一點,然后使用Graphics.DrawLine舊位置和新位置之間的方法繪制一條線。
另請注意,當滑鼠移動時,Control.MouseMove滑鼠指標移動的每個像素的事件不會在每次移動時收到。您確實Control.MouseMove以相當一致的時間間隔接收事件。這意味著滑鼠移動得越快,您實際收到的點就越遠。
查看此演練以獲取一些示例 - 
這是我撰寫的用于生成上圖的代碼,y = Sin(x):
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
var axisWidth = 3;
var axisColor = Color.Red;
var chartLineWidth = 2;
var chartLineColor = Color.Blue;
var scale = 90;
var gridSize = 45;
var gridLineWidth = 1;
var gridLineColor = Color.LightGray;
var g = e.Graphics;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
var w = pictureBox1.ClientRectangle.Width / 2;
var h = pictureBox1.ClientRectangle.Height / 2;
g.TranslateTransform(w, h);
g.ScaleTransform(1, -1);
//Draw grid
for (int i = -w / gridSize; i <= w / gridSize; i )
using (var axisPen = new Pen(gridLineColor, gridLineWidth))
g.DrawLine(axisPen, i * gridSize, -h, i * gridSize, h);
for (int i = -h / gridSize; i <= h / gridSize; i )
using (var axisPen = new Pen(gridLineColor, gridLineWidth))
g.DrawLine(axisPen, -w, i * gridSize, w, i * gridSize);
//Draw axis
using (var axisPen = new Pen(axisColor, axisWidth))
{
g.DrawLine(axisPen, -w, 0, w, 0); //X-Asxis
g.DrawLine(axisPen, 0, -h, 0, h); //Y-Asxis
}
//Draw y = Sin(x)
var points = new List<PointF>();
for (var x = -w; x < w; x )
{
var y = System.Math.Sin(x * Math.PI / 180);
points.Add(new PointF(x, scale * (float)y));
}
using (var chartLinePen = new Pen(chartLineColor, chartLineWidth))
{
g.DrawCurve(chartLinePen, points.ToArray());
}
g.ResetTransform();
}
您還需要以下代碼來處理圖片框的大小調整:
private void MyForm_Load(object sender, EventArgs e)
{
this.pictureBox1.GetType().GetProperty("ResizeRedraw",
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance).SetValue(
this.pictureBox1, true);
}
您還可以向控制元件添加十字準線和橡皮筋矩形,如下圖所示:

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/397853.html
