2011-06-10 93 views
0

我有一個Winform應用程序,我正在爲朋友修改。它有一個列表視圖,並希望我爲每行添加一個複選框並使它們互斥。所以在我測試如何使它工作的時候,我發現了一個奇怪的行爲,而跳着的人可以告訴我我錯過了什麼。ListView複選框行爲

如果我顯示沒有選中複選框的列表視圖。當我點擊右邊的複選框時,我無法檢查,但行劑量被選中。如果我點擊列中的項目(在這種情況下的名稱),它會被檢查和選擇。

無論我點擊哪一行,任何未選定行的複選框都將被取消選中。這是我的小測試程序。我使用.NET 4


public partial class Form1 : Form { 
    public Form1() { 
     InitializeComponent(); 
    } 

    private void Form1_Load(object sender, EventArgs e) { 
     TestListView.Items.Add("Bob"); 
     TestListView.Items.Add("Ann"); 
     TestListView.Items.Add("Frank"); 
    } 

    void TestListView_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e) { 
     ListViewItem currentItem = TestListView.GetItemAt(e.X, e.Y); 
     if (currentItem != null) { 
      foreach (ListViewItem item in TestListView.Items) { 
       if (item.Text == currentItem.Text) { 
        item.Checked = true; 
        item.Selected = !currentItem.Selected; 
       } 
       else 
        item.Checked = false; 
      } 
     } 
    } 
} 

回答

1

我目前也有一個非常類似的問題,但是,對Timwi的迴應並不是代碼執行取消選中。我一直在慢慢瀏覽它,當點擊複選框時代碼被觸發,它說明它已經檢查過它。但是當表格恢復時,它不會再被選中。在閱讀Timwi的文章後,他帶我回答了這個問題。這不是未經檢查的代碼,而是事後發起的winforms事件取消選中該框。這修復它:

我的代碼是:

private bool allowCheck = false; 
private bool preventOverflow = true; 

private void lstvwRaiseLimitStore_MouseClick(object sender, MouseEventArgs e) 
    { 
     preventOverflow = false; 
     ListViewItem item = lstvwRaiseLimitStore.HitTest(e.X, e.Y).Item; 
     if (item.Checked) 
     { 
      allowCheck = true; 
      item.Checked = false; 
     } 
     else 
     { 
      allowCheck = true; 
      item.Checked = true; 
     } 
    } 

private void lstvwRaiseLimitStore_ItemChecked(object sender, ItemCheckedEventArgs e) 
    { 
     if (!preventOverflow) 
     { 
      if (!allowCheck) 
      { 
       preventOverflow = true; 
       e.Item.Checked = !e.Item.Checked; 
      } 
      else 
       allowCheck = false; 
     } 
    } 

所以它在做什麼,首先我必須設置一個標誌,以防止溢出,否則當表單建立或當你取消窗口旁邊的框,它不斷循環代碼並最終堆棧溢出。下一個標誌是實際允許通過您的代碼檢查複選框,而不是通過其他方法。

點擊它們的項目,它找到點擊的位置,然後設置標誌以允許檢查完成。代碼然後檢查框和項目檢查部分開始,因爲它是由我們的代碼完成的,它不做任何事情,但重置allowcheck標誌。

如果你點擊了一行,它什麼都不做,但是如果它是一個複選框,在我們代碼的最後,Windows函數啓動並嘗試檢查該框,因爲allowcheck標誌爲false,代碼首先設置一個標誌來表示我已經阻止了一個檢查,然後將檢查重置爲初始狀態。因爲這樣做,項目檢查事件再次啓動,但代碼已設置標誌,以防止它做任何事情。然後代碼完成,它阻止了窗口檢查複選框,只允許我們的代碼。

希望它有幫助!

+0

太棒了!終於這爲我工作!複選框已被禁用。但在行選擇它的切換! :( – Raghavendra 2015-03-13 09:16:04

1

似乎是的WinForms勾選複選框,當你直接點擊該複選框,然後你的代碼立即撤消檢查,所以你永遠不會看到它。

也許不是MouseClick,您應該使用ItemCheckItemChecked事件。第一個在Checked屬性更改之前觸發,第二個在之後。

+0

不,如果我刪除除第一行(currentItem)以外的所有代碼,我會得到相同的行爲。 ItemCheck和ItemChecked激發了很多次我遇到不同的問題。 – RWBear 2011-06-11 18:03:28