2008-12-16 47 views

回答

6

爲什麼在列表滾動時需要調用函數?

如果您正在更改項目,因爲它滾動我建議將列表視圖設置爲虛擬。

或者你可以重寫ListView和做到這一點:

public class TestListView : System.Windows.Forms.ListView 
{ 
    private const int WM_HSCROLL = 0x114; 
    private const int WM_VSCROLL = 0x115; 
    public event EventHandler Scroll; 

    protected void OnScroll() 
    { 

     if (this.Scroll != null) 
      this.Scroll(this, EventArgs.Empty); 

    } 

    protected override void WndProc(ref System.Windows.Forms.Message m) 
    { 
     base.WndProc(ref m); 
     if (m.Msg == WM_HSCROLL || m.Msg == WM_VSCROLL) 
      this.OnScroll(); 
    } 
} 
0

下面是尊重每個ListView的顯示模式的解決方案:

我們依靠的事實,作爲ListView滾動時,項目的位置變化。如果我們檢查第一個ListViewItemBounds屬性中的更改,我們可以跟蹤是否發生了移動。

你需要一個Timer控件添加到同一形成你ListView並且它的Enabled屬性設置爲True(這意味着它會定期火而不必Start版)。還要添加一個私有變量到您的表單類來記錄第一個項目的Bounds

private Rectangle _firstItemBounds = null; 

當填充您的ListView,這個變量設置爲第一個項目的Bounds。例如:

private void Form1_Load(object sender, EventArgs e) 
{ 
    for (int i = 0; i < 1000; i++) 
    { 
     listView1.Items.Add(new ListViewItem("Item " + i)); 
    } 

    _firstItemBounds = listView1.Items[0].Bounds; 
} 

然後添加一個處理程序TimerTick事件:

private void timer1_Tick(object sender, EventArgs e) 
{ 
    if (listView1.Items[0] == null) 
    { 
     return; 
    } 

    Rectangle bounds = listView1.Items[0].Bounds; 

    if (bounds != _firstItemBounds) 
    { 
     _firstItemBounds = bounds; 

     // Any scroll logic here 
     // ... 
    } 
} 

默認爲100ms的Timer Interval似乎爲我工作得很好,但你可能需要調整,使之適合你的申請。

我希望這會有所幫助。

4

看來,最好的辦法是布賴恩的解決方案。但是,它只響應由滾動條生成的事件,但不響應鼠標中鍵的事件。

如果更改條件

if (m.Msg == WM_HSCROLL || m.Msg == WM_VSCROLL) 
      this.OnScroll(); 

由:

if (m.Msg == 0x000c2c9) 
      this.OnScroll(); 

現在respods在列表視圖所有滾動事件。

相關問題