我的控件的位置与鼠标按下和 -Up 事件的位置之间似乎不匹配



我正在尝试设置在鼠标按下和鼠标向上事件之间定义的矩形内的每个文本框的背面颜色,其中鼠标打开事件发生在鼠标按下事件的右侧和下方。

我以这种方式捕获要点:

static readonly Color PSEUDO_HIGHLIGHT_COLOR = Color.Gainsboro;
private Point selectionStart; 
private Point selectionEnd; 
. . .
private void flowLayoutPanelGreatGooglyMoogly_MouseDown(object sender, MouseEventArgs e) {
    if (e.Button == MouseButtons.Left) {
        selectionStart = PointToClient(MousePosition);
    }
}
private void flowLayoutPanelGreatGooglyMoogly_MouseUp(object sender, MouseEventArgs e) {
    if (e.Button == MouseButtons.Left) {
        selectionEnd = PointToClient(MousePosition);
        HighlightAllTextBoxValsBetweenPoints();
    }
}

。以下是应将文本框的背景颜色设置在点描述的虚拟矩形"下方"的代码:

private void HighlightAllTextBoxValsBetweenPoints() {
    TextBox tb;
    foreach (Control ctrl in flowLayoutPanelGreatGooglyMoogly.Controls) {
        if (ctrl is TextBox) {
            tb = (TextBox)ctrl;
            if ((tb.Location.X >= selectionStart.X) &&
                (tb.Location.Y >= selectionStart.Y) &&
                (tb.Location.X <= selectionEnd.X) &&
                (tb.Location.Y >= selectionEnd.Y)) {
                tb.BackColor = PSEUDO_HIGHLIGHT_COLOR;
            }
        }
    }
}

。但是,尽管正在执行代码,但没有任何文本框被视为在这些约束范围内。

就好像我在拖着一张美国地图,但桥下的巨魔告诉我堪萨斯州真的在加拿大。

我的逻辑可能是混淆或倒退的(未能正确比较 X 和 Y 坐标(,或者我无法将点从相对转换为绝对,反之亦然。

更新:

答案几乎是完美的(约翰怎么知道我的FlowLayoutPanel位于它所在的位置(;为了让它工作,我只需要在他的代码上方添加它:

// Have to subtract the Top (Y) value of the Panel 
int DeltaFromFormTopToPanelTop = flowLayoutPanelGreatGooglyMoogly.Location.Y; 
selectionStart.Y = selectionStart.Y - DeltaFromFormTopToPanelTop; 
selectionEnd.Y = selectionEnd.Y - DeltaFromFormTopToPanelTop;

更新到更新

为了防止在用户只选择一个控件时着色/提示,我还必须添加以下代码:

if (e.Button == MouseButtons.Left) {
  selectionEnd = PointToClient(MousePosition);
  if (MouseHasNotMovedFar()) {
    return;
  }
  HighlightAllTextBoxValsBetweenPoints();
  PromptForAndAssignInputValue();
}
private bool MouseHasNotMovedFar() {
// The "X" or horizontal, is TextBoxWidth*2 + LabelWidth*1
// The "Y" or vertical, is TextBoxHeight*2
// If the user has moved the mouse less than these between
// MouseDown and MouseUp, they probably have not dragged to 
// select multiple TextBoxes.
  const int ACCEPTABLE_X_DELTA = 74;
  const int ACCEPTABLE_Y_DELTA = 40;
  return (selectionEnd.X - selectionStart.X) <= ACCEPTABLE_X_DELTA &&
         (selectionEnd.Y - selectionStart.Y) <= ACCEPTABLE_Y_DELTA;
}

有几个问题。
首先 - 文本框坐标相对于 flowLayoutPanel。 因此,您的 PointToClient 必须相同:

selectionStart = flowLayoutPanelGreatGooglyMoogly.PointToClient(MousePosition);

第二,你有一个逻辑错误;最后一个比较被颠倒了。 (结核。位置.Y >= 选择结束.Y(( {

简化过程并允许向任何方向拖动的建议是使用矩形:

private void HighlightAllTextBoxValsBetweenPoints()
{
    var selectionBounds = new Rectangle(
        selectionStart.X, 
        selectionStart.Y, 
        selectionEnd.X - selectionStart.X, 
        selectionEnd.Y - selectionStart.Y);
    foreach (Control ctrl in flowLayoutPanel1.Controls)
    {
        var tb = ctrl as TextBox;
        if (tb == null)
            continue;
        if (tb.Bounds.IntersectsWith(selectionBounds))
            tb.BackColor = PSEUDO_HIGHLIGHT_COLOR;
    }
}

最新更新