2010-01-19 152 views
9

我在使用我正在處理的小應用程序中的CheckedListBox控件。這是一個很好的控制,但有一件事困擾我;我無法設置屬性,以便在我實際選中複選框時僅檢查項目。 解決這個問題的最好方法是什麼? 我一直在考慮獲取鼠標點擊的位置,相對於複選框的左側。哪部分工作,但如果我點擊一個空的空間,足夠靠近左邊,當前選定的項目仍然會被檢查。有關這個的任何想法?CheckedListBox控件 - 僅當點擊實際複選框時才選中複選框

+0

也許我錯過了一些東西。當你檢查盒子時現在發生了什麼?沒有?它是否默認檢查某些東西?你想停止發生什麼事情? – hunter 2010-01-19 14:40:11

+0

我只想點擊盒子本身而不是線條來檢查盒子。想象一下,它看起來像: []項目1 目前,對整個項目,當點擊該框被選中,但我不希望出現這種情況。我只希望當我點擊箱子本身,而不是描述性文本旁邊它被點擊。 – Oxymoron 2010-01-19 14:46:17

+0

你可以使用額外的標籤,只是複選框列表,然後創建標籤,.. 這不是很好的解決,但它的工作原理:> – Tyzak 2010-01-19 14:14:10

回答

7

嗯,這是很醜陋,但你可以通過CheckedListBox.MouseDownCheckedListBox.ItemCheck掛鉤像下面

/// <summary> 
/// In order to control itemcheck changes (blinds double clicking, among other things) 
/// </summary> 
bool AuthorizeCheck { get; set; } 

private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e) 
{ 
    if(!AuthorizeCheck) 
     e.NewValue = e.CurrentValue; //check state change was not through authorized actions 
} 

private void checkedListBox1_MouseDown(object sender, MouseEventArgs e) 
{ 
    Point loc = this.checkedListBox1.PointToClient(Cursor.Position); 
    for (int i = 0; i < this.checkedListBox1.Items.Count; i++) 
    { 
     Rectangle rec = this.checkedListBox1.GetItemRectangle(i); 
     rec.Width = 16; //checkbox itself has a default width of about 16 pixels 

     if (rec.Contains(loc)) 
     { 
      AuthorizeCheck = true; 
      bool newValue = !this.checkedListBox1.GetItemChecked(i); 
      this.checkedListBox1.SetItemChecked(i, newValue);//check 
      AuthorizeCheck = false; 

      return; 
     } 
    } 
} 
+0

是的,就像我在OP中所說的那樣,我也在想這樣的事情,但是因爲它感覺不太好,所以我開始尋找替代品:) – Oxymoron 2010-01-20 06:34:53

+2

謝謝,它只是起作用!一些優化是可能的,但這個想法很有效! – nightcoder 2010-04-29 14:13:50

0

默認情況下呈現CheckedListBox中複選框的文本是在複選框輸入後放置HTML標籤,並將標籤的「for」屬性設置爲複選框的ID。

當一個標籤表示一個「for」的元素時,點擊該標籤會告訴瀏覽器關注該元素,這就是你所看到的。

兩個選項來渲染自己的列表與獨立的CheckBox控件和文本(不是CheckBox的Text屬性,如,做了同樣的事情的CheckBoxList)如果該列表是靜態的或使用的東西就像一箇中繼器如果列表是動態的。

+0

這不是一個網絡表格,但一個winform :) 但我得到你的漂移。聚焦是好的,實際上我想要的,我只是不希望點擊項目本身時選中複選框。似乎我會擺弄自定義控件:) – Oxymoron 2010-01-19 15:09:06

+0

好吧,很難說只有c#和CheckedListBox作爲標籤。我繼續並添加了winforms。 – 2010-01-20 00:45:21

9

我知道這個線程是有點老了計算鼠標擊中座標下的項目的矩形,但我不」 t認爲這是一個問題提供另一種解決方案:

private void checkedListBox1_MouseClick(object sender, MouseEventArgs e) 
{ 
    if ((e.Button == MouseButtons.Left) & (e.X > 13)) 
    { 
     this.checkedListBox1.SetItemChecked(this.checkedListBox1.SelectedIndex, !this.checkedListBox1.GetItemChecked(this.checkedListBox1.SelectedIndex)); 
    } 
} 

(值爲CheckOnClick = True)。

你可以在矩形中使用那些東西,但爲什麼使它更復雜,它需要。

5

另一個解決方案是簡單地使用Treeview。
將CheckBoxes設置爲true,將ShowLines設置爲false,將ShowPlusMinus設置爲false,並且基本上與CheckedListBox具有相同的功能。只有當實際的CheckBox被點擊時纔會檢查項目。

CheckedListBox更簡單,但TreeView提供了很多選項,可能更適合您的程序。

0

試試這個。將iLastIndexClicked聲明爲表單級別的int變量。

private void chklst_MouseClick(object sender, MouseEventArgs e) 
{ 
    Point p = chklst.PointToClient(MousePosition); 
    int i = chklst.IndexFromPoint(p); 
    if (p.X > 15) { return; } // Body click. 
    if (chklst.CheckedIndices.Contains(i)){ return; } // If already has focus click anywhere works right. 
if (iLastIndexClicked == i) { return; } // native code will check/uncheck 
    chklst.SetItemChecked(i, true); 
    iLastIndexClicked = i; 
} 

只是檢查,看看用戶在檢查列表(複選框區域)的最左邊的15個像素點擊在所有工作時間,除了重新檢查當前選擇的項目。存儲最後一個索引並退出而不更改會讓本機代碼正確處理,試圖將其設置爲在該情況下將其設置爲「已檢查」,以便在「ItemCheck」代碼運行時將其打開並關閉。