2010-01-17 72 views
1

我试图阻止在匹配指定条件的列表框中选择项目。经过一些MSDN研究后,我开始知道LBN_SELCHANGE是通过WM_COMMAND发送给它的父窗口的,所以我试图用 钩住OnNotifyMessage列表框发送的LBN_SELCHANGE消息,如下所示。列表框通知消息

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

} 

但这似乎不工作,请指导我,如果我错过了什么。 在此先感谢。

回答

2

是的,那是行不通的。在完成契约后发送LBN_SELCHANGE,该项目已被选中。你只能取消选择它。

您可以在不捕获Windows消息的情况下执行此操作。这是一个愚蠢的例子,只允许选择偶数项:

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

不可回避的问题是,当它是由用户选择和你的程序未选择的选择闪烁。如果不需要,您应该查看CheckedListBox控件。

+0

这样做,谢谢。 我只是想知道。如果我在 “case(int)WindowsMessages.WM_COMMAND:// 0x111”上设置断点。断点不会触发。你有什么线索为什么这不起作用。 再次感谢 – crypted 2010-01-18 07:41:45

+1

使用WndProc()。家长通知消息通过向消息添加0x2000反映回控制。 – 2010-01-18 08:54:03

+0

太棒了,这就是我想要的。谢谢。 – crypted 2010-01-18 12:15:20