ComboBox SelectionChangeCommitted event doesn't work with AutoComplete - c#

Here is a short program that reproduces the problem I just encountered. This was compiled under MS Windows 7 with .NET 4.0, just in case that makes a difference.
using System;
using System.Drawing;
using System.Windows.Forms;
// Compile with "csc /target:exe /out:comboboxbug.exe /r:System.dll /r:System.Drawing.dll /r:System.Windows.Forms.dll comboboxbug.cs"
// in a Visual Studio command prompt.
static class Program
{
[STAThread]
static void Main()
{
//Create a label.
Label oLabel = new Label();
oLabel.Location = new Point (10, 10);
oLabel.Size = new Size (100, 15);
oLabel.Text = "Combo box bug:";
// Create a combo-box.
ComboBox oComboBox = new ComboBox();
oComboBox.Location = new Point (10, 50);
oComboBox.Size = new Size (150, 21);
oComboBox.Items.AddRange (new object[]
{ "A", "A B", "A C", "A B C", "A C B", "A B C D", "A C B D" });
oComboBox.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
oComboBox.AutoCompleteSource = AutoCompleteSource.ListItems;
oComboBox.SelectionChangeCommitted
+= new EventHandler (comboBox_SelectionChangeCommitted);
// Create a form.
Form oForm = new Form();
oForm.Size = new Size (200, 150);
oForm.Controls.Add (oLabel);
oForm.Controls.Add (oComboBox);
// Run this form.
Application.Run (oForm);
}
static void comboBox_SelectionChangeCommitted (object sender,
EventArgs e)
{
MessageBox.Show ("SelectionChangeCommitted");
}
}
Click in the text portion of the combo-box and type "A". You will get a list of autocomplete suggestions. Click one of the selections with your mouse. The SelectionChangeCommitted event doesn't happen!
Select a menu-item without using autocomplete. You'll get a message-box showing that the SelectionChangeCommitted event happened!
Given that the selection was changed by the user in both cases, shouldn't SelectionChangeCommitted be called in both cases?
Using the SelectedIndexChanged event is not an option, because for the application behind this canned example, I only want it to happen when the user makes a selection, not when it's set programmatically.
EDIT 2020-Oct-28: I found another case where SelectionChangeCommitted doesn't get called! Auto-complete doesn't even need to be set for the problem to happen! Click to open the combo-box, press a key that matches the beginning of one of the combo-box items, and then press Tab to leave. The combo-box item gets selected, but SelectionChangeCommitted is not called! My revised answer is below.

Using the SelectedIndexChanged event is not an option, because for the application behind this canned example, I only want it to happen when the user makes a selection, not when it's set programmatically.
You could also accomplish this by writing a wrapper method for changing the selection that temporarily disables your event.
Unfortunately I do not know off hand a solution to the issue that SelectionChangeCommitted not being started for the more general case (such as where you don't control the ComboBox or how it is accessed).
EDIT:
I made a streamer of all the events that ComboBox calls, and it doesn't appear that any other event will do what you are looking for. The only solution I can think of would involve hooking into the events that the AutoComplete triggers. The difficulty is knowing what those events are, since they don't appear to trigger off the ComboBox from what my minor testing shows.

FYI, here was the best solution I ever came up with. Obviously, this is a Leave event-handler on a ComboBox subclass. The SelectionChangeCommitted event doesn't happen on the mouse-click, but at least it happens during the normal flow of GUI interaction.
private void this_Leave (object sender, EventArgs e)
{
// If this is an autocomplete combo-box, select the
// item that was found by autocomplete.
// This seems like something that ComboBox should be
// doing automatically...I wonder why it doesn't?
if (this.AutoCompleteMode != AutoCompleteMode.None)
{
// Determine which combo-box item matches the text.
// Since IndexOf() is case-sensitive, do our own
// search.
int iIndex = -1;
string strText = this.Text;
ComboBox.ObjectCollection lstItems = this.Items;
int iCount = lstItems.Count;
for (int i = 0; i < iCount; ++i)
{
string strItem = lstItems[i].ToString();
if (string.Compare (strText, strItem, true) == 0)
{
iIndex = i;
break;
}
}
// If there's a match, and this isn't already the
// selected item, make it the selected item.
//
// Force a selection-change-committed event, since
// the autocomplete was driven by the user.
if (iIndex >= 0
&& this.SelectedIndex != iIndex)
{
this.SelectedIndex = iIndex;
OnSelectionChangeCommitted (EventArgs.Empty);
}
}
}

If someone got this problem, I suggest a solution that works fine to me...
Think with me, to accept the suggest of Combo-box, generally the user needs to key down with an Enter key.
You can write into KeyDown event of Combo-box property, something like this:
private void cboProperty_SelectionChangeCommitted(object sender, EventArgs e)
{
//Call here the event of SelectionChangeCommitted
cboProperty_SelectionChangeCommitted(sender,null);
}
It will raise the SelectionChangeCommitted on the right time.

This workaround worked fine for me and hope for you too. When use Autocomplete by typing data in your combo box to get an item through keyboard or mouse selection you need _KeyDown event. From inside invoke _SelectionChangeCommitted method which contains code for other operations. See code below:
private void YourComboBox_KeyDown(object sender, KeyEventArgs e)
{
//Works also when user select and click on autocomplete list.
if (e.KeyCode == Keys.Enter && YourComboBox.SelectedItem != null)
YourComboBox_SelectionChangeCommitted(sender, e);
}

For the non-auto-complete case mentioned above (i.e. my 2020-Oct-28 edit), this Leave event-handler on a ComboBox subclass incorporates the new case as well as the old one, as long as your SelectionChangeCommitted event-handler is idempotent. Compared to my previous answer, it removes the test for auto-complete, and always calls OnSelectionChangeCommitted().
private void this_Leave (object sender, EventArgs e)
{
// Determine which combo-box item matches the text.
// Since IndexOf() is case-sensitive, do our own
// search.
int iIndex = -1;
string strText = this.Text;
ComboBox.ObjectCollection lstItems = this.Items;
int iCount = lstItems.Count;
for (int i = 0; i < iCount; ++i)
{
string strItem = lstItems[i].ToString();
if (string.Compare (strText, strItem, true) == 0)
{
iIndex = i;
break;
}
}
// If there's a match, and this isn't already the
// selected item, make it the selected item.
if (iIndex >= 0
&& this.SelectedIndex != iIndex)
this.SelectedIndex = iIndex;
// Force a selection-change-committed event, since
// the autocomplete was driven by the user.
OnSelectionChangeCommitted (EventArgs.Empty);
}

Related

Winforms ListView item selection bug

I'm making an application that uses a ListView control with MultiSelect = false. In some situations I need to prevent the user from changing the selected item. I thought it would be a simple task, but hours later I'm still trying to figure out what's going on.
So in order to have the option to "freeze" the ListView selection, I made a custom class CListView that inherits from ListView. If FreezeSelection is set to true, every time the users changes the selection, I'm trying to change it back:
public class CListView : ListView
{
public bool FreezeSelection { get; set; } = false;
bool _applyingSelectionUpdates = false;
protected override void OnSelectedIndexChanged(EventArgs e)
{
if (FreezeSelection)
{
if (_applyingSelectionUpdates)
return;
// for simplicity consider that the selected index while the selection is frozen is always 2
int selectedIndex = 2;
_applyingSelectionUpdates = true;
try
{
SelectedIndices.Clear();
if (selectedIndex >= 0)
SelectedIndices.Add(selectedIndex);
}
finally { _applyingSelectionUpdates = false; }
return;
}
base.OnSelectedIndexChanged(e);
}
}
The problem is when I set FreezeSelection back to false, and the user tries to select a different item. First of all, even if MultiSelect is false, visually it appears as there are two items selected. But programatically, when the user changes the selection, it seems there is sometimes the correct item selected, sometimes no item selected.
This behaviour is clearly a bug and I suspect what is causing this bug. When the user clicks on an item, the event SelectedIndexChanged is fired twice. Once after the SelectedIndices collection is cleared and the second time after the clicked item is added to the collection of selected items. I think the bug is caused by changing the selected items between these two events, but I need to know more about this. If MultiSelect is true and the user tries to select items with Ctrl, I have no problems.
To reproduce this bug you can use the following TestForm:
public class TestForm : Form
{
CListView listView;
CheckBox checkBox;
public TestForm()
{
listView = new() { Dock = DockStyle.Fill, View = View.Details, FullRowSelect = true, MultiSelect = false };
listView.Columns.Add("col 1");
listView.SelectedIndexChanged += ListView_SelectedIndexChanged;
Controls.Add(listView);
checkBox = new() { Dock = DockStyle.Right, Text = "freeze selection" };
checkBox.CheckedChanged += CheckBox_CheckedChanged;
Controls.Add(checkBox);
listView.Items.Add("item 1");
listView.Items.Add("item 2");
listView.Items.Add("item 3");
listView.Items.Add("item 4");
}
private void CheckBox_CheckedChanged(object? sender, EventArgs e)
{
listView.FreezeSelection = checkBox.Checked;
}
DateTime lastSelChangeTime = DateTime.MinValue;
private void ListView_SelectedIndexChanged(object? sender, EventArgs e)
{
if ((DateTime.Now - lastSelChangeTime).TotalMilliseconds > 200)
Debug.WriteLine(""); // this is just to group together what happens on a single user interaction
var indices = listView.SelectedIndices.Cast<int>().ToArray();
Debug.WriteLine("CListView fired selection changed event! "
+ DateTime.Now.ToString("h:m:s:fff") + " "
+ "{ " + string.Join(", ", indices) + " }");
lastSelChangeTime = DateTime.Now;
}
}
If you run this form:
Select the third item (with index 2)
Check "freeze selection"
Click on the forth item
Uncheck "freeze selection"
Try changing the selected item now and observe the bug
The question is how to solve this bug or how to achieve my initial goal (prevent users from selecting a different item).
Update:
To clarify, what I refered to as "a bug" is not the fact that I get two events for one selection change (I'm fine with that), it's the inconsistent behaviour between the UI and ListView.SelectedIndices after I "unfreeze" the selected index. I will demonstrate the problem with the following picture (note that each screenshot is taken after I clicked where the cursor is positioned; also the output window shows the SelectedIndices every time I get an SelectedIndexChanged event):
I use .NET 6.0.
As others have mentioned, there is no bug here as shown in this sequence of selecting Item 1, then Selecting Item2 (which first changes the selection by deselecting Item 1.
If you don't want the User to be selecting things during some arbitrary task (like waiting for a modified document to be saved), why not just set ListView.Enabled to false while you perform the work? In the testcode referenced below, I made an all-in-one for when the checkbox changes that sets the SelectionIndices collection to '2' as in your post;
There are now no issues going back to a state where freeze selection is unchecked and selecting some new item.
public TestForm()
{
InitializeComponent();
listView.MultiSelect = false;
listView.Columns.Add("col 1");
for (int i = 1; i <= 4; i++) listView.Items.Add($"Item {i}");
listView.SelectedIndexChanged += (sender, e) =>
{
richTextBox.AppendLine(
$"{DateTime.Now} : [{string.Join(", ", listView.SelectedIndices.Cast<int>())}]" );
var sel =
listView
.SelectedItems
.Cast<ListViewItem>();
if (sel.Any())
{
foreach (var item in sel)
{
richTextBox.AppendLine(item);
richTextBox.AppendLine();
}
}
else richTextBox.AppendLine("No selections", Color.Salmon);
};
checkBox.CheckedChanged += (sender, e) =>
{
listView.Enabled = !checkBox.Checked;
if (checkBox.Checked) doWork();
};
void doWork()
{
listView.SelectedIndices.Clear();
listView.SelectedIndices.Add(2);
}
}
Uses this extension for RichTextBox
static class Extensions
{
public static void AppendLine(this RichTextBox richTextBox) =>
richTextBox.AppendText($"{Environment.NewLine}");
public static void AppendLine(this RichTextBox richTextBox, object text) =>
richTextBox.AppendText($"{text}{Environment.NewLine}");
public static void AppendLine(this RichTextBox richTextBox, object text, Color color)
{
var colorB4 = richTextBox.SelectionColor;
richTextBox.SelectionColor = color;
richTextBox.AppendText($"{text}{Environment.NewLine}");
richTextBox.SelectionColor = colorB4;
}
}

Disable multiple controls based upon Combo Box value

I have tried a number of iterations to get this to work, and although I am close, I cannot seem to solve this.
private void cbxMealsNum_SelectedIndexChanged(object sender, EventArgs e)
{
int count = 0;
int cbxCurr = cbxMealsNum.SelectedIndex+1;
foreach (Control control in foodMeals.Controls.OfType<ComboBox>().Where(x => x.Name.Contains("MealsNo" + cbxMealsNum.Text)))
{
TextBox textBox = control as TextBox;
if (count < cbxCurr)
{
control.Enabled = true;
}
else
{
control.Enabled = false;
}
count++;
}
}
The above code allows me to Enable the correct combo box but none of the combo boxes before it. As such, if I select '6' in cbxMealsNum, meal 6 is enabled, but not the 5 preceding it.
Thus, I am asking how I would change the index for cbxMealsNum to, say, 4, and have only cbxMealsNo1 through to 4 enabled. If I then change cbxMealsNum to 3, cbxMealsNo4 should be disabled. If I change cbxMealsNum to 5, cbxMealsNo4 should be enabled once more, as should cbxMealsNo5.
I have tried a number of iterations of this code, including the following answer here as seen in the above sample, but to no avail. I am new to C# but I have been looking for every possible solution I can. I do not know if my search terms are malformed.
Please note, I have used the Where method as I intend to add textboxes and other controls contain the same naming convention (thus; cbxMealsNo1, txtMealsNo1, lblMealsNo1, and so on)
I am assuming you want all the combos enabled up to the selected number in the “number of meals” combo box. If this is the case then the code below may help.
First, it may be easier to put all the combo boxes into a collection since you will be needing them each time the “number of meals” combo box changes. It seems unnecessary to “re-collect” them each time. In the example below I created a simple array of six (6) combo boxes. We can then use that array to loop through all the combo boxes and enable the proper combo boxes.
ComboBox[] combos = new ComboBox[6];
public Form1() {
InitializeComponent();
combos[0] = cbxMealsNo1;
combos[1] = cbxMealsNo2;
combos[2] = cbxMealsNo3;
combos[3] = cbxMealsNo4;
combos[4] = cbxMealsNo5;
combos[5] = cbxMealsNo6;
}
Then in the “number of meals” selection changed event, a simple loop to enable all the combo boxes that are less than the selected number of meals. Something like….
private void cbxMealsNum_SelectedIndexChanged(object sender, EventArgs e) {
int cbxCurr = cbxMealsNum.SelectedIndex;
for (int i = 0; i < combos.Length; i++) {
if (i <= cbxCurr) {
combos[i].Enabled = true;
}
else {
combos[i].Enabled = false;
}
}
}

CheckedListBox Only One Checked But Keep Last

I am having some difficulty getting a CheckedListBox to behave the way I want it to. What I am trying to accomplish is getting a CheckedListBox with the first box checked on PageLoad. I want only one checkbox checked at any given time but I also don't want the user to uncheck the last checked box. I can do one or the other but I can't seem to do both.
Here is some code snippets that I have used to accomplish the task of having only one checkbox checked. The problem with these are the last selection can be unchecked where there are no checkboxes checked.
1st Snippet:
if(e.NewValue == CheckState.Checked)
{
// Uncheck the other items
for (int i = 0; i < defCheckedListBox.Items.Count; i++)
{
if (e.Index != i)
{
this.defCheckedListBox.SetItemChecked(i, false);
}
}
}
2nd Snippet
// Ensure that we are checking an item
if (e.NewValue != CheckState.Checked)
{
return;
}
// Get the items that are selected
CheckedListBox.CheckedIndexCollection selectedItems = this.defCheckedListBox.CheckedIndices;
// Check that we have at least 1 item selected
if (selectedItems.Count > 0)
{
// Uncheck the other item
this.defCheckedListBox.SetItemChecked(selectedItems[0], false);
}
Here is what I have used to prevent the last checked box to be "unchecked"
if (laborLevelDefCheckedListBox.CheckedItems.Count == 1)
{
if (e.CurrentValue == CheckState.Checked)
{
e.NewValue = CheckState.Checked;
}
}
I know this has got to be simple but I think because I've had a long week and I have looked at this too long it is just not coming to me. Any help with this is super appreciated! If I solve this over the weekend I will be sure to post my solution. BTW Happy Holidays to those here in the States :)
Chris makes a good point in the comments that this feels like you are re-inventing radio buttons but you are almost there with the code you have posted if you really want it to work with a CheckedListBox. I have adapted the code from your 1st Snippet which I think does the trick:
//remove the event handler so when we change the state of other items the event
//isn't fired again.
defCheckedListBox.ItemCheck -= defCheckedListBox_ItemCheck;
if (e.NewValue == CheckState.Checked)
{
// Uncheck the other items
for (int i = 0; i < defCheckedListBox.Items.Count; i++)
{
if (e.Index != i)
{
this.defCheckedListBox.SetItemChecked(i, false);
}
}
}
else
{
//the state was not checked.
//as only one item can ever be Checked inside the event
//handler the state of not checked is invalid for us; set the state back to Checked.
e.NewValue = CheckState.Checked;
}
//re-add the event handler
defCheckedListBox.ItemCheck += defCheckedListBox_ItemCheck;
Essentially the only new parts are the else where we reset the state if the state was not Checked and the removing and re-adding of the event to prevent it firing again when we manually set the state of other items (this could be handled with a global bool if you prefer).
// Use CheckBoxList Event
private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e) {
// Stops DeInitialize Event
checkedListBox1.ItemCheck -= checkedListBox1_ItemCheck;
// Get the new value old value my be in Indeterminate State
checkedListBox1.SetItemCheckState(e.Index, e.NewValue);
// Start ReInitialize Event
checkedListBox1.ItemCheck += checkedListBox1_ItemCheck;
}

C# WinForm Datagrid doubleclick event

Is there a doubleclick event for a datagrid? I'm trying to use this code to open a details form when the user doubleclicks on a row.
http://www.codeproject.com/KB/grid/usingdatagrid.aspx
I tried adding it by doubleclicking on the control, but it gives dataGrid1_Navigate instead.
What you get when you double click a control in design mode is the event the designers of the control thought would be the most used, in this case it's Navigate.
But yes, this control has two double click events:
public partial class Form1 : Form
{
DataGrid grid = new DataGrid();
public Form1()
{
InitializeComponent();
grid.DoubleClick += new EventHandler(grid_DoubleClick);
grid.MouseDoubleClick += new MouseEventHandler(grid_MouseDoubleClick);
grid.Dock = DockStyle.Fill;
this.Controls.Add(grid);
}
void grid_MouseDoubleClick(object sender, MouseEventArgs e)
{
}
void grid_DoubleClick(object sender, EventArgs e)
{
}
}
However, both of these events run when you double click anywhere on the control and they don't directly give you information on what row was selected. You might be able to retrieve the row double clicked in the grid_MouseDoubleClick handler by getting it from the control based on the point being clicked (e.Location), that's how it works in the TreeView control for example. At a quick glance I didn't see if the control has such a method. You might want to consider using DataGridView instead, if you don't have a particular reason to use this control.
Sounds like you need a way to get a list of all the events for a given control, rather than finding the default event (which is what VS gives you when you double click a control in the designer)
There are a few ways of doing this:
One way Select the grid.
Then click the events icon to turn the properties window into a list of events, then doubel click the event you want to strart coding the event.
Alternatively, switch to code view, select the grid in the drop down list of objects at the top left of the code window, then select the event you want from the list of all the events for that control in the event list (top right of the code window)
I tried #steve76's code, but had to tweak it slightly to work in a Windows Embedded CE 6.0 system. Here is what worked for me.
private void dataGrid1_DoubleClick(object sender, EventArgs e)
{
Point pt = dataGrid1.PointToClient(Control.MousePosition);
DataGrid.HitTestInfo info = dataGrid1.HitTest(pt.X, pt.Y);
int row;
int col;
if (info.Column < 0)
col = 0;
else
col = info.Column;
if (info.Row < 0)
row = 0;
else
row = info.Row;
object cellData = dataGrid1[row, col];
string cellString = "(null)";
if (cellData != null)
cellString = cellData.ToString();
MessageBox.Show(cellString, "Cell Contents");
}
Perhaps you can use the DataGridView.CellContentDoubleClick event.
Example:
private void DataGridView1_CellContentDoubleClick(Object sender, DataGridViewCellEventArgs e) {
System.Text.StringBuilder messageBoxCS = new System.Text.StringBuilder();
messageBoxCS.AppendFormat("{0} = {1}", "ColumnIndex", e.ColumnIndex );
messageBoxCS.AppendLine();
messageBoxCS.AppendFormat("{0} = {1}", "RowIndex", e.RowIndex );
messageBoxCS.AppendLine();
MessageBox.Show(messageBoxCS.ToString(), "CellContentDoubleClick Event" );
}
If that is not what you are looking for, you can find other events in the reference:
http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview_events.aspx

CheckedListBox Control - Only checking the checkbox when the actual checkbox is clicked

I'm using a CheckedListBox control in a small application I'm working on. It's a nice control, but one thing bothers me; I can't set a property so that it only checks the item when I actually check the checkbox.
What's the best way to overcome this?
I've been thinking about getting the position of the mouseclick, relative from the left side of the checkbox. Which works partly, but if I would click on an empty space, close enough to the left the current selected item would still be checked. Any ideas regarding this?
I know this thread's a bit old, but I don't think it's a problem to offer another solution:
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));
}
}
(With the value of CheckOnClick = True).
You could use that thingy with the rectangle, but why make it more complex the it needs to.
Well, it is quite ugly, but you could calculate mouse hit coordinates against rectangles of items by hooking on CheckedListBox.MouseDown and CheckedListBox.ItemCheck like the following
/// <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;
}
}
}
Another solution is to simply use a Treeview.
Set CheckBoxes to true, ShowLines to false, and ShowPlusMinus to false and you have basically the same thing as a CheckedListBox. The items are only checked when the actual CheckBox is clicked.
The CheckedListBox is much more simplistic, but the TreeView offers a lot of options that can potentially be better suited for your program.
I succesfully used this property:
CheckedBoxList.CheckOnClick
https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.checkedlistbox.checkonclick?view=netframework-4.7.2
The text for a checkbox in a CheckedListBox is rendered by default is to place an HTML label after the checkbox input and set the label's "for" attribute to the ID of the checkbox.
When a label is denoting an element that it is "for," clicking on that label tells the browser to focus on that element, which is what you're seeing.
Two options are to render your own list with separate CheckBox controls and text (not as the Text property of the CheckBox, as that does the same thing as the CheckBoxList) if the list is static or to use something like a Repeater if the list is dynamic.
Try this. Declare iLastIndexClicked as a 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;
}
Just checking to see if the user clicked in the leftmost 15 pixels of the checked list (the check box area) works at all times except re-checking a currently selected item. Storing the last index and exiting without changing lets the native code handle that properly, trying to set it to checked in that case turns it on and it just turns back off when the "ItemCheck" code runs.

Categories