I've made customCheckedListBox, which I want to use to filter dataGridView with mulitselect option. I would like to be able to catch CheckedListBox CheckedChange state, but CheckedListBox only supports ItemCheck event.
Here is my code:
private void customCheckedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
{
FilterDataGrid();
}
private void FilterDataGrid()
{
var list4 = customCheckedListBox1.SelectedItems.Cast<string>().ToList();
if (customCheckedListBox1.SelectedItems.Count != 0)
{
var result = list3.Where(Srodek => list4.Any(x => x == Srodek.Srodek.category1));
DataTable ListAsDataTable3 = BuildDataTable2<CalaLinijka>(result);
DataView ListAsDataView3 = ListAsDataTable3.DefaultView;
dataGridView4.DataSource = view = ListAsDataView3;
}
}
Problem is that ItemCheck event can handle only one choice, so even when user decided to choose more than one opiton it will show only first selected item. I guess that CheckedChanged event would work in my case, but when ItemCheck event is called there are no CheckedItems yet. They become "Checked" after ItemCheck event is finished. So when it goes inside FilterDataGrid CheckedChanged.Count equals to 0.
My question is how should I handle CheckedChanged event in CheckedListBox. I hope that I didn't messed up too much. If there will be any questions, just let me know and I will try to expain more.
I solved this problem by using foreach loop (just like KingKing suggested) and putting it inside MouseLeave event.
private void customCheckedListBox1_MouseLeave(object sender, EventArgs e)
{
foreach (string itemChecked in customCheckedListBox1.CheckedItems)
{
CheckedList.Add(itemChecked);
}
FilterDataGrid();
}
Related
I need to make it so when the user clicks on a cell with TextEdit in a grid view, it will select all in the textedit. I tried many many ways i could find in the internet, but none of them work well.
"EditorShowMode = MouseUp" way breaks everything, for example when you click on a cell that has checkedit; it selects the cell, then you need o click again to actually click on the CheckEdit.
"Use EditorShowMode = MouseUp and manually handle other things on MouseDown" is just ew. Won't work fine for all types of controls.
"Change selection length etc. on ShownEditor event" way doesn't work too, actually it selects the text when clicked, but it doesn't override the default function so the selection instantly changes. Also tried the SelectAll method but it had some problems that i dont remember (probably didnt work at all).
I have really tried many things, but couldn't find a totally fine way. Please tell me if you can get a working way without breaking other types of controls in the grid.
Answered by Pavel on DevExpress Support (works great):
The easiest way to achieve this is to use the GridView.ShownEditor event to subscribe to the active editor's MouseUp event. Then, select all text in the MouseUp event handler and detach this handler to avoid subsequent text selection.
private void GridView_ShownEditor(object sender, EventArgs e)
{
GridView view = sender as GridView;
if (view.ActiveEditor is TextEdit)
view.ActiveEditor.MouseUp += ActiveEditor_MouseUp;
}
private void ActiveEditor_MouseUp(object sender, MouseEventArgs e)
{
BaseEdit edit = sender as BaseEdit;
edit.MouseUp -= ActiveEditor_MouseUp;
edit.SelectAll();
}
You could use GridView CustomRowCellEdit event and set an event of text editor such as Mouse Up. Setting the RepositoryItemTextEdit MouseUp event can be set as in the example.
Example:
private void gridView1_CustomRowCellEdit(object sender, CustomRowCellEditEventArgs e)
{
if (e.RepositoryItem is DevExpress.XtraEditors.Repository.RepositoryItemTextEdit)
{
DevExpress.XtraEditors.Repository.RepositoryItemTextEdit rep = new DevExpress.XtraEditors.Repository.RepositoryItemTextEdit();
rep.ReadOnly = false;
rep.MouseUp += rep_MouseUp;
e.RepositoryItem = rep;
}
}
void rep_MouseUp(object sender, MouseEventArgs e)
{
DevExpress.XtraEditors.TextEdit te = sender as DevExpress.XtraEditors.TextEdit;
te.SelectAll();
}
You should handle Enter event for TextEdit
private void myRepositoryItemTextEdit_Enter(object sender, EventArgs e)
{
var editor = (DevExpress.XtraEditors.TextEdit)sender;
BeginInvoke(new MethodInvoker(() =>
{
editor.SelectionStart = 0;
editor.SelectionLength = editor.Text.Length;
}
}
Can you guys help me code if I select one of the checkboxes on the ListView section, the rest of the checkboxes should be checked.
My ListView name is lvBase and I want to used the ListView ItemCheck events.
This is my code.
private void lvBase_ItemCheck_1(object sender, ItemCheckEventArgs e)
{
}
Use the following line to add an itemcheck or itemchecked event:
this.listView1.ItemCheck += new ItemCheckEventHandler(listView1_ItemCheck);
Hope I understood your question correctly, If you want to check all the checkbox in the list, you can loop through them and set Checked Property to true.
private void lvBase_ItemChecked(object sender, ItemCheckedEventArgs e)
{
for (int i = 0; i < lvBase.Items.Count; i++)
{
lvBase.Items[i].Checked = e.Item.Checked;
}
}
I need to update the edit value of the CheckedComboBoxEdit control immediately after the item has been checked
The MouseUp event can be used to trigger EndEditwhich will commit the change slightly faster.
I used this to solve my simular issue when working with a CheckBox within a DateGridView. As by default the event to submit changes in a DataGridView only fires when leaving the cell.
You should subscribe Popup event of CheckedComboBoxEdit, find CheckedListBoxControl and subscribe ItemCheck event. Like this:
void _orgStructEntitesCheckedComboBoxEdit_Popup(object sender, EventArgs e)
{
var popup = (IPopupControl)sender;
var control = popup.PopupWindow.Controls.OfType<PopupContainerControl>().First().Controls.OfType<CheckedListBoxControl>().First();
control.ItemCheck += control_ItemCheck;
}
void control_ItemCheck(object sender, DevExpress.XtraEditors.Controls.ItemCheckEventArgs e)
{
var checkedListBoxControl = (CheckedListBoxControl)sender;
var current = checkedListBoxControl.Items[e.Index];
}
Use e.Index to get current item changed.
More information here and here.
I am using CheckedListBox in C# Window Forms Application.
I want to do something after one item checked or unchecked but ItemCheck event runs before the item checked/unchecked .
How can I do that?
CheckedListBox.ItemCheck Event
The check state is not updated until after the ItemCheck event occurs.
To run some codes after the item checked, you should use a workaround.
Best Option
You can use this option (Thanks to Hans Passant for this post):
private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
{
this.BeginInvoke(new Action(() =>
{
//Do the after check tasks here
}));
}
Another option
If in middle of ItemCheck Event, you need to know state of item, you should use e.NewValue instead of using checkedListBox1.GetItemChecked(i)
If you need to pass a list of checked indices to a method do this:
Using the code:
var checkedIndices = this.checkedListBox1.CheckedIndices.Cast<int>().ToList();
if (e.NewValue == CheckState.Checked)
checkedIndices.Add(e.Index);
else
if(checkedIndices.Contains(e.Index))
checkedIndices.Remove(e.Index);
//now you can do what you need to checkedIndices
//Here if after check but you should use the local variable checkedIndices
//to find checked indices
Another Option
In middle of ItemCheck event, remove handler of ItemCheck, SetItemCheckState and then add handler egain.
private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
{
var control = (CheckedListBox)sender;
// Remove handler
control.ItemCheck -= checkedListBox_ItemCheck;
control.SetItemCheckState(e.Index, e.NewValue);
// Add handler again
control.ItemCheck += checkedListBox_ItemCheck;
//Here is After Check, do additional stuff here
}
Try searching more for answers, cause here it is
private void clbOrg_ItemCheck(object sender, ItemCheckEventArgs e)
{
CheckedListBox clb = (CheckedListBox)sender;
// Switch off event handler
clb.ItemCheck -= clbOrg_ItemCheck;
clb.SetItemCheckState(e.Index, e.NewValue);
// Switch on event handler
clb.ItemCheck += clbOrg_ItemCheck;
// Now you can go further
CallExternalRoutine();
}
And the link:
Which CheckedListBox event triggers after a item is checked?
You can hook up an event on ItemCheck. You can do it by right clicking your checkboxlist and select properties. And at the right side you will see the property tab, click the event tab button and locate ItemCheck event and double click it. It will generate a event method for you depend on your checkboxlist name like below.
Then, you can verify selected/checked checkbox using code below.
private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
{
var checkBoxName = checkedListBox1.Items[e.Index];
Console.WriteLine("Current {0}, New {1} , value {2}", e.CurrentValue, e.NewValue, checkBoxName);
}
I have the following code that load my windows form:
private void Panou_Load(object sender, EventArgs e)
{
List<string>[] list;
list = Conexiune.Select();
dataGridView1.Rows.Clear();
(dataGridView1.Columns[3] as DataGridViewComboBoxColumn).DataSource = new List<string> { "", "activ", "inactiv", "neverificat", "blocat" };
for (int i = 0; i < list[0].Count; i++)
{
int number = dataGridView1.Rows.Add();
dataGridView1.Rows[number].Cells[0].Value = list[0][i];
dataGridView1.Rows[number].Cells[1].Value = list[1][i];
dataGridView1.Rows[number].Cells[2].Value = list[2][i];
dataGridView1.Rows[number].Cells[3].Value = list[3][i];
dataGridView1.Rows[number].Cells[4].Value = list[4][i];
dataGridView1.Rows[number].Cells[5].Value = list[5][i];
dataGridView1.Rows[number].Cells[6].Value = list[6][i];
}
}
Everything works normally but now I want to make some updates in database when I remove a row so I use: dataGridView1_RowsRemoved .
Example:
private void dataGridView1_RowsRemoved(object sender, DataGridViewRowsRemovedEventArgs e)
{
MessageBox.Show("deleted");
}
Why the message "deleted" is showing up when the form load?
dataGridView1.Rows[number].Cells[0].Value contain the id from database. How I retrieve this id in the dataGridView1_RowsRemoved function?
The actual binding of the data source (your list) to the DataGridView happens after the form load event, and so a lot of events that your would not expect to be fired are fired in the process of data binding.
I don't know why that is - would need to dig through the code or the DataGridView component itself, but there is fortunately a work around - attach all such events during the event handler of the DataBindingComplete event.
void dataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
dataGridView1.RowsRemoved += new DataGridViewRowsRemovedEventHandler(dataGridView1_RowsRemoved);
}
That way you will not see RowsRemoved fired at form load.
Even better in your case, the answer to the second part of your question involves using a different event, that behaves as expected, even when not attached during DataBindingComplete.
The problem with RowsRemoved is that it fires after the row has been removed, so even though you have the (old) index of the row from the event args, getting to the data is very tricky (maybe impossible?)
The fix is to instead handle the UserDeletingRow event:
void dataGridView1_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)
{
var msg = e.Row.Cells[0].Value.ToString();
MessageBox.Show(msg);
}
This event is fired once for every row that is deleted - it would probably make sense to aggregate these events and then perform a single database action from within the RowsRemoved handler.