您知道,我们可以很容易地为图表制作行光标(例如:图)。但是有了PictureBox,我该怎么做呢?有人找到解决办法了吗?
发布于 2021-12-29 16:41:23
您可以拦截MouseMove和画图事件。把十字架画在油漆上。
使用画法的优点,是原来的图像没有改变,所以不需要恢复覆盖像素由十字头发。
下面是一个例子:
我把一个picturebox放在了一个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
控件,默认情况下该控件具有交叉关系。
如果要在PictureBox
中绘制图表,请使用Bitmap
并使用Graphics.FromImage(bitmap)
绘制,并将其放入PictureBox.Image
中。不要忘记释放Graphics对象。
发布于 2021-12-29 16:25:08
您可以通过存储接收到的最后一点的位置来实现这一点,然后使用Graphics.DrawLine
方法在旧位置和新位置之间绘制一条线。
还请注意,当鼠标移动时,鼠标指针移动的每个像素的Control.MouseMove
事件并不是每一次移动都会收到。您确实在相当一致的时间间隔内接收Control.MouseMove
事件。这意味着,鼠标移动得越快,实际接收到的点数就越远。
查看本演练以获取一些示例- https://www.c-sharpcorner.com/UploadFile/mahesh/drawing-lines-in-gdi/
发布于 2021-12-29 18:17:16
如果我正确地理解了这个问题,那么您有兴趣为图表绘制x轴和y轴,但不使用聊天控件。
在这种情况下,您需要做的是:处理PictureBox的画图事件,并从上、中到下、从左、中到右中间画线。
下面是我编写的代码,用于生成上面的图表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);
}
您还可以对控件进行add a crosshair and rubber-band rectangle,如下所示:
https://stackoverflow.com/questions/70521868
复制相似问题