2011-11-09 13 views
1

WinformsのListBoxが異常な動作をしているようです。 SelectionModeを1に設定すると、アイテムをクリックして選択されると予想されます。これは当てはまりますが、アイテムをクリックしてリストを上下にドラッグすると、選択が変更されます。ListBoxで「ドラッグ選択」を無効にする

これは、いくつかのコントロール間でドラッグアンドドロップを実行する必要があることを除けば、それほど大したことではありません。したがって、アイテムを選択してリストの下にドラッグすると、新しく選択されたアイテムが実際にドラッグして登録したアイテムになり、間違ったアイテムが送信されます。

それで、私はさらにmousedownで選択したアイテムへの参照を保存することで包帯を作成しますが、それは悪いユーザーエクスペリエンスとして巻き起こします。私のユーザは、他のリストボックスに項目をドラッグしても機能しますが、元のリストボックスにはもう「正しい」項目が選択されていないため、実際に2番目のコントロールでドロップされた項目が混乱します。

このような動作を変更する方法はありますか? MouseUpの部分を無視して、MouseDownで項目を選択したい。単にイベントを消費するだけでは十分ではないようで、ListBoxをオーバーライドする必要はありません(作成する新しいクラスのドキュメントを作成する必要があります)。

答えて

1

DoDragDropに電話するとこの現象は消滅します。 Windowsはドラッグモードの間に&ドロップモードでメッセージMouseOverをディスパッチしません。 propperドラッグ&ドロップの

例:

private void listBox_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e) 
    { 
     // Get the index of the item the mouse is below. 
     indexOfItemUnderMouseToDrag = listBox.IndexFromPoint(e.X, e.Y); 

     if (indexOfItemUnderMouseToDrag != ListBox.NoMatches) { 

      // Remember the point where the mouse down occurred. The DragSize indicates 
      // the size that the mouse can move before a drag event should be started.     
      Size dragSize = SystemInformation.DragSize; 

      // Create a rectangle using the DragSize, with the mouse position being 
      // at the center of the rectangle. 
      dragBoxFromMouseDown = new Rectangle(new Point(e.X - (dragSize.Width /2), 
                  e.Y - (dragSize.Height /2)), dragSize); 
     } else 
      // Reset the rectangle if the mouse is not over an item in the ListBox. 
      dragBoxFromMouseDown = Rectangle.Empty; 

    } 

    private void listBox_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e) { 
     // Reset the drag rectangle when the mouse button is raised. 
     dragBoxFromMouseDown = Rectangle.Empty; 
    } 

    private void listBox_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e) 
    { 
     if ((e.Button & MouseButtons.Left) == MouseButtons.Left) { 

      // If the mouse moves outside the rectangle, start the drag. 
      if (dragBoxFromMouseDown != Rectangle.Empty && 
       !dragBoxFromMouseDown.Contains(e.X, e.Y)) 
      { 
        DragDropEffects dropEffect = listBox.DoDragDrop(listBox.Items[indexOfItemUnderMouseToDrag], DragDropEffects.All | DragDropEffects.Link); 

        // If the drag operation was a move then remove the item. 
        if (dropEffect == DragDropEffects.Move) {       
         listBox.Items.RemoveAt(indexOfItemUnderMouseToDrag); 

         // Selects the previous item in the list as long as the list has an item. 
         if (indexOfItemUnderMouseToDrag > 0) 
          listBox.SelectedIndex = indexOfItemUnderMouseToDrag -1; 

         else if (ListDragSource.Items.Count > 0) 
          // Selects the first item. 
          listBox.SelectedIndex =0; 
        } 
       } 
      } 
     } 
    } 

...とSelectedIndexChangedはまだ動作します!

+0

もう1つの問題があります。情報を表示するにはドラッグアンドドロップと 'SelectedIndexChanged'イベントの両方を処理する必要があります。それで、私は古いタイマーのトリックを使用しました(MouseDownでタイマーを開始し、MouseUpでそれをクリアしてからDoDragDrop()を押します)。私はあなたが正しいと思う。 DoDragDropをすぐに呼び出すと、選択モードを回避できます。 – drharris

+0

ドラッグ&ドロップと 'SelectedIndexChanged'の両方を扱うのは問題ありません。アイテムをクリックすると、選択インデックスが変更され、右イベントが発生します。次に 'MouseMove'では、現在のカーソル位置と、' DoDragDrop'を呼び出す適切な時点で、マウスダウンポイントからどのくらい離れているかを確認します。上の私のポストを見て - 私はどのようにドラッグ&ドロップを適切に動作させるための例を追加しました。 – rotman

関連する問題