2010-01-17 4 views
1

J'essaie d'empêcher la sélection d'éléments dans la liste qui correspond à la condition spécifiée. Après une étude MSDN, j'ai appris que LBN_SELCHANGE est envoyé à la fenêtre parente via WM_COMMAND, j'ai donc essayé pour accrocher le message LBN_SELCHANGE envoyé par la zone de liste sur OnNotifyMessage comme ci-dessous.Listbox Message de notification

public class SimpleListBox:ListBox 
{ 
    public SimpleListBox() 
    { 
     SetStyle(ControlStyles.EnableNotifyMessage, true); 
    } 
    private const int LBN_SELCANCEL = 0x3; 
    private const int LBN_SELCHANGE = 0x1; 
    protected override void OnNotifyMessage(Message m) 
    { 
     switch (m.Msg) 
     { 
      ////http://msdn.microsoft.com/en-us/library/bb775161(VS.85).aspx 
      case (int)WindowsMessages.WM_COMMAND: //0x111 
       if (((int)m.WParam).LoWord() == LBN_SELCHANGE) 
       { 
        int i = 0; 
       } 
       break; 
     } 
     base.OnNotifyMessage(m); 
    } 

} 

Mais cela ne semble pas fonctionner, s'il vous plaît me guider si j'ai manqué quelque chose. Merci d'avance.

Répondre

2

Oui, cela ne peut pas fonctionner. LBN_SELCHANGE est envoyé après que l'acte a été fait, l'élément est déjà sélectionné. Vous ne pouvez que le désélectionner.

Vous pouvez déjà le faire sans intercepter le message Windows. Voici un exemple stupide, il permet uniquement de sélectionner des éléments paires:

public partial class Form1 : Form { 
    public Form1() { 
     InitializeComponent(); 
     listBox1.SelectionMode = SelectionMode.MultiSimple; 
     listBox1.SelectedIndexChanged += new EventHandler(listBox1_SelectedIndexChanged); 
    } 

    void listBox1_SelectedIndexChanged(object sender, EventArgs e) { 
     for (int ix = listBox1.SelectedIndices.Count - 1; ix >= 0; --ix) { 
     int index = listBox1.SelectedIndices[ix]; 
     if (index % 2 != 0) listBox1.SelectedIndices.Remove(index); 
     } 
    } 
    } 

Un problème inévitable est que le voyant de sélection lorsqu'il est sélectionné par l'utilisateur et non sélectionnés par votre programme. Vous devriez regarder le contrôle CheckedListBox si ce n'est pas souhaitable.

+0

C'est fait, merci. Je me demandais juste. Si je définis un point d'arrêt sur "case (int) WindowsMessages.WM_COMMAND: // 0x111". Le point d'arrêt ne déclenche pas. avez-vous la moindre idée de pourquoi cela ne fonctionne pas. Merci encore – crypted

+1

Utilisez WndProc(). Les messages de notification parent sont renvoyés au contrôle en ajoutant 0x2000 au message. –

+0

Génial, C'est tout ce que je voulais. Je vous remercie. – crypted

Questions connexes