0

MouseDownイベントとMouseUpイベントの間に定義された長方形内にある各TextBoxの背景色を設定しようとしています。ここで、MouseUpイベントはMouseDownイベントの右下で発生します。

私はこの方法でポイントをキャプチャします:

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();
    }
}

...そして、Pointsによって記述された仮想長方形の「下」にあるTextBoxのBackColorを設定する必要があるコードは次のとおりです。

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;
            }
        }
    }
}

...しかし、コードは実行されていますが、これらの制約内にあると見なされるTextBoxはありません。

まるで古き良きアメリカの地図をドラッグしているようですが、橋の下のトロールは、カンザスが本当にカナダにいることを教えてくれます。

私のロジックはおそらく混同または逆方向(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;

UPDATEからUPDATEへ

ユーザーがコントロールを1つだけ選択したときに色付けやプロンプトが表示されないようにするには、次のコードも追加する必要がありました。

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;
}
4

1 に答える 1

2

いくつかの問題があります。
最初-テキストボックスの座標はflowLayoutPanelを基準にしています。したがって、PointToClientは同じである必要があります。

selectionStart = flowLayoutPanelGreatGooglyMoogly.PointToClient(MousePosition);

2番目-論理的なバグがありました。最後の比較は逆になりました。(tb.Location.Y > = selectionEnd.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;
    }
}
于 2012-04-26T23:21:14.850 に答える