Laden...

Verbesserte CheckedListbox

Erstellt von ErfinderDesRades vor 13 Jahren Letzter Beitrag vor 13 Jahren 5.009 Views
ErfinderDesRades Themenstarter:in
5.299 Beiträge seit 2008
vor 13 Jahren
Verbesserte CheckedListbox

Checkedlistbox ist etwas unintuitiv, weil man jedes Item, was man checken möchte, erst selektieren muß. Hier habichwas gebastelt, damit kann man unabhängig von der Selektion die Items checken oder unchecken.
Außerdem habichmir erlaubt, die DataBindingfähigkeit wieder offenzulegen, die die Checkedlistbox vorm Benutzer verbirgt.
Ach, und ein neues Event - AfterCheck habich drangemacht, weil im ItemCheck-Event das aktuelle Item noch nicht in der CheckedIndices-auflistung geführt wird.

Letzteres hat den Hintergrund, dass das IntemCheck nicht eiglich designed ist, um auf Check-Änderungen zu reagieren, sondern man kann dort den neuen Checkstate benutzerdefiniert setzen (und dadurch zB. den Check-Vorgang canceln).

Auch das Verstecken der DataBinding-Funktionalität ist nicht reine schikane, denn so wie ichs gemacht hab, hat man nun quasi eine Item-Property angezeigt (quasi "Item.Checked"), die trotz Databinding nicht an die Datenquelle gebunden ist, und das verstößt wohl gegen Databinding-Konventionen.
Aber in der Praxis mag es praktisch sein, Items markieren zu können 🙂

Wer den Code gucken will:


using System;
using System.Drawing;
using System.Windows.Forms;
using System.ComponentModel;
using System.Drawing.Design;

namespace CheckedListboxExTest {

   [System.ComponentModel.DesignerCategory("Code")]
   public class CheckedListboxEx : CheckedListBox {

      public class AfterCheckEventArgs : EventArgs {
         public readonly int Index;
         public AfterCheckEventArgs(int Index) { this.Index = Index; }
      }
      public event EventHandler<AfterCheckEventArgs> AfterCheck = delegate { };

      private ItemCheckEventArgs _ICE;

      protected override void OnItemCheck(ItemCheckEventArgs ice) {
         //note: the ItemCheck-event enables the eventhandler to change the proposed ice.NewValue
         base.OnItemCheck(ice);
         _ICE = ice;
      }

      [EditorBrowsable(EditorBrowsableState.Always), Browsable(true)]
      public new object DataSource {
         get { return ((ListControl)this).DataSource; }
         set { ((ListControl)this).DataSource = value; }
      }
      [EditorBrowsable(EditorBrowsableState.Always), Browsable(true)]
      public new string DisplayMember {
         get { return ((ListControl)this).DisplayMember; }
         set { ((ListControl)this).DisplayMember = value; }
      }
      [EditorBrowsable(EditorBrowsableState.Always), Browsable(true)]
      public new string ValueMember {
         get { return ((ListControl)this).ValueMember; }
         set { ((ListControl)this).ValueMember = value; }
      } 

      protected override void WndProc(ref Message m) {
         /*suppress clicks close to the left edge (x<=16). instead toggle the checkstate of the hit item*/
         switch((API.Enums.WM)m.Msg) {
         case API.Enums.WM.LBUTTONUP:
         case API.Enums.WM.LBUTTONDBLCLK:
            var wd = new API.Word(m.LParam);
            if(wd.Lo > 16) break;
            return;
         case API.Enums.WM.LBUTTONDOWN:
            wd = new API.Word(m.LParam);
            var pt = new Point(wd.Lo, wd.Hi);
            if(pt.X > 16) break;
            var i = IndexFromPoint(pt);
            if(i < 0) return;
            //toggling. because 3-value-CheckState there maybe other kinds of toggling suitable
            SetItemCheckState(i, 
               GetItemCheckState(i) == CheckState.Checked 
               ? CheckState.Unchecked : CheckState.Checked);
            if(_ICE.NewValue == _ICE.CurrentValue) return;
            AfterCheck(this, new AfterCheckEventArgs(_ICE.Index));
            return;
         }
         base.WndProc(ref m);
      }
   }
}

(ist nicht ganz vollständig, da ich API-Deklarationen ausgelagert hab)

Der frühe Apfel fängt den Wurm.

C
51 Beiträge seit 2007
vor 13 Jahren

Hallo,

Dass man ein Item, welches man checken möchte, zuerst selektieren möchte stimmt nicht, es gibt da schon eine Einstellung. (OneClick, oder so was ähnliches).
Das AfterCheck-Event finde ich nützlich, den Rest kann ich persönlich nicht gebrauchen.

Gruss C_C

ErfinderDesRades Themenstarter:in
5.299 Beiträge seit 2008
vor 13 Jahren

Jo, stimmt. Die Einstellung ist CheckOnClick=true, und bewirkt, dass beim Klick sowohl die Selektion ggfs. umspringt, als auch der Checkstate umschaltet.

Also ist dieses Dings nur noch bei besonderen Erfordernissen von Belang, hmm.

SelectionMode ist immer One, alles andere wirft eine Exception.

Der frühe Apfel fängt den Wurm.