2009-03-19 29 views

答えて

2

スクロールはListViewItem.EnsureVisibleメソッドで実行できます。 現在ドラッグしているアイテムがリストビューの目に見える境界にあり、最初/最後でないかどうかを判断する必要があります。

private static void RevealMoreItems(object sender, DragEventArgs e) 
{ 
    var listView = (ListView)sender; 

    var point = listView.PointToClient(new Point(e.X, e.Y)); 
    var item = listView.GetItemAt(point.X, point.Y); 
    if (item == null) 
     return; 

    var index = item.Index; 
    var maxIndex = listView.Items.Count; 
    var scrollZoneHeight = listView.Font.Height; 

    if (index > 0 && point.Y < scrollZoneHeight) 
    { 
     listView.Items[index - 1].EnsureVisible(); 
    } 
    else if (index < maxIndex && point.Y > listView.Height - scrollZoneHeight) 
    { 
     listView.Items[index + 1].EnsureVisible(); 
    } 
} 

このメソッドをDragOverイベントに配線します。

targetListView.DragOver += RevealMoreItems; 

targetListView.DragOver += (sender, e) => 
{ 
    e.Effect = DragDropEffects.Move; 
}; 
+0

null以外の項目を取得したら、常にitem.EnsureVisible()を呼び出すことができます。スクロールが必要な場合はそれを行い、それ以外の場合は何も行いません。 –

+0

私はそれを取得しません。ここでのアイデアは、あなたがドラッグしているアイテムの横にある項目のInsureVisibleコールです。 –

+0

item.EnsureVisible()は、その項目がnullでないことを確認してから使用できます。インデックス、maxIndex、scrollZoneHeightなどを取得しないようにすることができます。ユーザーは、上端または下端に少しドラッグする必要があります。ユーザーがスクロールして最初の項目または最後の項目にカーソルを移動させたい場合は、コードは完璧です。 –

8

リンク(http://www.knowdotnet.com/articles/listviewdragdropscroll.html)のおかげで、私はC#が

class ListViewBase:ListView 
{ 
    private Timer tmrLVScroll; 
    private System.ComponentModel.IContainer components; 
    private int mintScrollDirection; 
    [DllImport("user32.dll", CharSet = CharSet.Auto)] 
    private static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam); 
    const int WM_VSCROLL = 277; // Vertical scroll 
    const int SB_LINEUP = 0; // Scrolls one line up 
    const int SB_LINEDOWN = 1; // Scrolls one line down 

    public ListViewBase() 
    { 
     InitializeComponent(); 
    } 
    protected void InitializeComponent() 
    { 
     this.components = new System.ComponentModel.Container(); 
     this.tmrLVScroll = new System.Windows.Forms.Timer(this.components); 
     this.SuspendLayout(); 
     // 
     // tmrLVScroll 
     // 
     this.tmrLVScroll.Tick += new System.EventHandler(this.tmrLVScroll_Tick); 
     // 
     // ListViewBase 
     // 
     this.DragOver += new System.Windows.Forms.DragEventHandler(this.ListViewBase_DragOver); 
     this.ResumeLayout(false); 

    } 

    protected void ListViewBase_DragOver(object sender, DragEventArgs e) 
    { 
     Point position = PointToClient(new Point(e.X, e.Y)); 

     if (position.Y <= (Font.Height/2)) 
     { 
      // getting close to top, ensure previous item is visible 
      mintScrollDirection = SB_LINEUP; 
      tmrLVScroll.Enabled = true; 
     }else if (position.Y >= ClientSize.Height - Font.Height/2) 
     { 
      // getting close to bottom, ensure next item is visible 
      mintScrollDirection = SB_LINEDOWN; 
      tmrLVScroll.Enabled = true; 
     }else{ 
      tmrLVScroll.Enabled = false; 
     } 
    } 

    private void tmrLVScroll_Tick(object sender, EventArgs e) 
    { 
     SendMessage(Handle, WM_VSCROLL, (IntPtr)mintScrollDirection, IntPtr.Zero); 
    } 
} 
+0

私は同じコードを使用しましたが、なぜ私のために働かないのですか? – Ram

+0

George Polevoyの回答はこれよりずっと簡単です –

2

それをised ObjectListViewを見てください。それはこのことをします。 ObjectListView自体を使用したくない場合は、コードを読み込んで使用できます。

0

将来のgooglerへのちょっとした注意:より複雑なコントロール(DataGridViewなど)でこれを機能させるには、this threadを参照してください。

関連する問題