2010-01-19 19 views
9

Ich verwende ein CheckedListBox-Steuerelement in einer kleinen Anwendung, an der ich arbeite. Es ist eine nette Kontrolle, aber eine Sache stört mich; Ich kann keine Eigenschaft festlegen, sodass sie nur das Element überprüft, wenn ich das Kontrollkästchen aktiviere. Was ist der beste Weg, dies zu überwinden? Ich habe darüber nachgedacht, die Position des Mausklicks relativ von der linken Seite des Kontrollkästchens zu erhalten. Was teilweise funktioniert, aber wenn ich auf einen leeren Platz klicken würde, würde der aktuell ausgewählte Punkt immer noch so weit links liegen. Irgendwelche Ideen diesbezüglich?CheckedListBox-Steuerelement - Aktivieren Sie nur das Kontrollkästchen, wenn das Kontrollkästchen aktiviert ist

+0

Vielleicht vermisse ich etwas. Was passiert jetzt, wenn Sie die Box ankreuzen? Nichts? Überprüft es standardmäßig? Was passiert, dass du aufhören willst zu passieren? – hunter

+0

Ich möchte nur die Box überprüft werden, wenn ich auf die Box selbst, nicht die Zeile klicken. Stellen Sie sich vor, es sieht so aus: [] Item1 Derzeit wird die Box überprüft, wenn Sie auf das gesamte Element klicken, aber das will ich nicht. Ich möchte nur darauf klicken, wenn ich auf die Box selbst klicke, nicht auf den beschreibenden Text daneben. – Oxymoron

+0

Sie könnten ein zusätzliches Label verwenden, nur die Checkbox-Liste, und dann Etiketten erstellen .. es ist nicht so schön gelöst, aber es funktioniert:> – Tyzak

Antwort

7

Nun ist es ziemlich hässlich, aber man konnte auf CheckedListBox.MouseDown und CheckedListBox.ItemCheck wie folgt

/// <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

Ja, wie ich im OP gesagt habe, habe ich über so etwas nachgedacht, aber da es sich nicht wirklich gut anfühlt, habe ich angefangen nach Alternativen zu suchen :) – Oxymoron

+2

Danke, es funktioniert einfach! Einige Optimierungen sind möglich, aber die Idee funktioniert! – nightcoder

0

Der Text für eine Checkbox in einer CheckedListBox wird standardmäßig gerendert, um eine HTML-Beschriftung nach der Checkbox-Eingabe zu platzieren und das Attribut "for" der Beschriftung auf die ID der Checkbox zu setzen.

Wenn ein Label ein Element bezeichnet, für das es "ist", wird durch Klicken auf dieses Label der Browser angewiesen, sich auf das Element zu konzentrieren, das Sie gerade sehen.

Zwei Optionen bestehen darin, eine eigene Liste mit separaten CheckBox-Steuerelementen und Text darzustellen (nicht als Text-Eigenschaft der CheckBox, da dies die CheckBoxList ist), wenn die Liste statisch ist oder einen Repeater verwendet wenn die Liste dynamisch ist.

+0

Es ist kein Webformular, sondern eine Winform :) Aber ich bekomme Ihre Drift. Die Fokussierung ist in Ordnung und genau das, was ich will, ich will nur nicht, dass das Kontrollkästchen aktiviert wird, wenn ich auf den Gegenstand klicke. Scheint, ich werde mit einem benutzerdefinierten Steuerelement herumspielen :) – Oxymoron

+0

Ok, es ist schwer zu sagen, wenn nur C# und CheckedListBox als Tags vorhanden waren. Ich ging weiter und fügte winforms hinzu. –

9

Ich weiß, dass dieser Thread ist ein bisschen alt, aber ich don‘Maus Trefferkoordinaten gegen Rechtecke der Elemente berechnen durch Einhaken t denke, es ist ein Problem, eine andere Lösung zu bieten:

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)); 
    } 
} 

(Mit dem Wert von CheckOnClick = True).

Sie könnten dieses Ding mit dem Rechteck verwenden, aber warum es komplizierter machen muss es.

5

Eine andere Lösung ist einfach eine Treeview zu verwenden.
Setzen Sie CheckBoxes auf true, ShowLines auf false und ShowPlusMinus auf false, und Sie haben im Grunde dasselbe wie eine CheckedListBox. Die Elemente werden nur geprüft, wenn auf die CheckBox geklickt wird.

Die CheckedListBox ist viel einfacher, aber das TreeView bietet viele Optionen, die möglicherweise besser für Ihr Programm geeignet sind.

0

Versuchen Sie dies. Deklarieren Sie iLastIndexClicked als eine form-level-int-Variable.

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; 
} 

einfach zu überprüfen, ob der Benutzer in den linksen 15 Pixel der geprüften Liste (das Kontrollkästchen Bereich) arbeitet geklickt ein aktuell ausgewähltes Element jederzeit außer erneut zu überprüfen. Wenn der letzte Index gespeichert und ohne Änderung beendet wird, kann der native Code diesen Code korrekt verarbeiten. Wenn er in diesem Fall auf checked gesetzt wird, wird er aktiviert und bei der Ausführung des ItemCheck-Codes wieder deaktiviert.

Verwandte Themen