C# 将鼠标单击位置转换为给定比例

C# 将鼠标单击位置转换为给定比例,c#,winforms,C#,Winforms,以下是我试图解决的问题: 你有一个显示心率(1小时-60分钟)的屏幕,点击屏幕,你如何知道你在哪一分钟? 当你点击屏幕时,你会得到特定的高度和宽度 这就是我所做的:我创建了一个表单,并在表单上停靠了PictureBox对象。PictureBox对象具有通过单击PictureBox对象调用的方法。方法: private void pictureBox1_Click(object sender, EventArgs e) { var mouseEventArgs = e as MouseEv

以下是我试图解决的问题:

你有一个显示心率(1小时-60分钟)的屏幕,点击屏幕,你如何知道你在哪一分钟? 当你点击屏幕时,你会得到特定的高度和宽度

这就是我所做的:我创建了一个表单,并在表单上停靠了PictureBox对象。PictureBox对象具有通过单击PictureBox对象调用的方法。方法:

private void pictureBox1_Click(object sender, EventArgs e)
{
    var mouseEventArgs = e as MouseEventArgs;
    if (mouseEventArgs != null)
    {
        int widthPerMinute = (int)(mouseEventArgs.X / ((pictureBox1.Width + 1) / 60.0));
        MessageBox.Show((widthPerMinute).ToString());
    }
}

有更优雅的解决方案吗?

我很确定我误解了你要求我的第一个答复(我将它放在这个答案的末尾以供参考)

我现在认为你在要求对你正在做的事情进行更高层次的设计

如果您打算进一步开发心率图显示,那么您可能需要为它编写自己的自定义
控件,而不仅仅是使用PictureBox。这样,您就可以将所有绘图逻辑很好地封装在其实现中

不过,这需要很多学习。如果你认为你将来可能需要写更多的东西,那就值得了

MSDN简介如下:

但从听起来,这是一个面试问题或什么的,在这种情况下,你可能不想在上面花这么多时间


我先前的答复是:

我不会说有更“优雅”的方法,但我想您可以通过将计算分钟数的逻辑提取到单独的方法中,使代码更具可读性:

int minuteAtPictureBoxCoord(int x)
{
    double totalMinutes = 60;
    double minutesPerPixel = totalMinutes/(pictureBox1.Width+1);
    int minute = (int)(x*minutesPerPixel);
    return minute;
}
这显然要长得多,但可以说更容易看出代码是正确的。(虽然我不能完全确定
pictureBox1.Width+1
上的+1,但我不确定这是否正确;我是从您的原始代码复制的。)

它还简化了呼叫站点:

private void pictureBox1_Click(object sender, EventArgs e)
{
    var mouseEventArgs = e as MouseEventArgs;
    if (mouseEventArgs != null)
    {
        int minute = minuteAtPictureBoxCoord(mouseEventArgs.X);
        MessageBox.Show(minute.ToString());
    }
}
我认为一眼就能看出代码在干什么会更容易一些

此外,如果您更改屏幕上显示的分钟数,或者如果您有多行心率数据(那么您需要一个X和Y客户机坐标),那么以后更改计算会更容易

还有一件事:您可能应该使用而不仅仅是
Click()
。这样你就可以通过一个
MouseEventArgs
,这样你就不需要做演员了。因此,它将成为:

private void pictureBox1_MouseClick(object sender, mouseEventArgs e)
{
    int minute = minuteAtPictureBoxCoord(e.X);
    MessageBox.Show(minute.ToString());
}

你想如何改进它?它到底出了什么问题?我在寻找更优雅的方式来表演。。如果可能的话..如果你点击图片框的一半,你的相对位置是eposx/boxWidth=.5;那么,你不是简单地用0.5乘以60分钟就得到了30分钟吗?你在除以60。@Tim他实际上得到了
x/(y/z)
,这当然是
(x*z)/y
,在这个例子中,z=60
。你只得到了+1,David。我不知道一个EventArgs可以像那样简单地投给MouseEventArgs。我在用这个!建议:将
pictureBox1.Width+1
更改为
pictureBox1.ClientSize.Width
以获得宽度减去边框/边距等,并将1添加到
minute
,因为第一分钟将是
1
,而不是
0
,我相信。当然,我可以做得更具可读性。但我正在寻找更优雅的方式来表现……是的,这是一个面试问题:)我不想花时间来做这件事,为了检查我的答案,我用picturebox做了这件事。。但我喜欢你的回答!非常感谢。嗯,+1是因为要得到0-59之间的分钟数,@Jordantrudget pictureBox1.ClientSize.Width和pictureBox1.Width之间有什么区别?@DavidMichaeli
.Width
将给出控件的大小,包括边框、滚动条等,但是
.ClientSize.Width
会给出图片盒中的大小@DavidMichaeli I在一个scratch项目上测试了这段代码,每边有3个边框,用户只能点击距离
.Width
不到6个像素的地方,这在某些情况下可能会导致不准确