I am trying to prevent items fr开发者_JS百科om being selected in listbox that matches specified condition. After some MSDN Study I came to know that LBN_SELCHANGE is sent to it's parent window via WM_COMMAND so I tried to hook LBN_SELCHANGE message sent by the list box on OnNotifyMessage as below.
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);
}
}
But This seems not working, please guide me if I have missed something. Thanks in advance.
Yes, that cannot work. LBN_SELCHANGE is sent after the deed was done, the item is already selected. You could only unselect it.
You can already do this without trapping the Windows message. Here's a silly example, it only allows selecting even numbered items:
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);
}
}
}
An inevitable problem is that the selection blinks when it is selected by the user and unselected by your program. You should look at the CheckedListBox control if that's not desirable.
精彩评论