How can I toggle the checkbox of an item in a CheckedListbox if CheckOnClick is True, but SelectionMode is None..?
If I set SelectionMode to One it works as expected, but I would like to prevent items in the list from being selected. The only purpose of the CheckedListbox is to use the checkboxes; having items selected is not desired.
I tried a bit of code with the various Click and Mouse events, but none of them seem to report the item in the list that was clicked. If I could determine that, it would be a simple matter to toggle the checkbox of the clicked item.
The MouseClick event will tell you when the control was clicked and where. Determine whether the click was on an item and which one, then toggle it:
Private Sub CheckedListBox1_MouseClick(sender As Object, e As MouseEventArgs) Handles CheckedListBox1.MouseClick
Dim clickedIndex = CheckedListBox1.IndexFromPoint(e.X, e.Y)
If clickedIndex <> ListBox.NoMatches Then
CheckedListBox1.SetItemChecked(clickedIndex, Not CheckedListBox1.GetItemChecked(clickedIndex))
End If
End Sub
After a little testing, I would say that you need to consider “how” you want to achieve the non-selection mode you describe. As you have noted, if you set the CheckedListBoxes SelectionMode to None… then basically the check boxes become unusable.
The user cannot check or un-check any check box, as you already know… and this is why you want “your” code to change the check boxes checked state. So, you have now inherited the job of changing the check boxes check state because you set its “SelectionMode” to “None" … ? …
In addition, when the selection mode is set to “None” … then many “typical” properties of the CheckedListBox will lose functionality and become useless. Example, the checked list boxes SelectedItem property will always be null and its SelectedIndex property will most likely always be -1. Meaning, most “selection” type events will need to find what item was clicked by using the mouse location as shown in another answer.
The main point here is that when you decided to set the checked list boxes selection mode to “None”, then you basically open the door for more coding/responsibility on your part as far as “managing” the checked list box. I am just saying that the out-of-the-box .Net CheckedListBox is not feature rich and is a basic control. I am guessing there “may” be a third-party CheckedListBox Control that may have this “non-selected” functionality built-in.
So… I suggest another approach… however… it also has some drawbacks… basically you have to create a new Class MyCheckedListBox type “Control” that inherits from the CheckedListBox and then override its draw method to paint the cell the way we want.
I tend to avoid creating new controls. However, this will allow us to “keep” the CheckedListBoxes “selection functionality” by keeping its SelectionMode set to One. In addition to removing the job of “your” code having to manage each check box’s check state… we can also use all the checked list boxes “selection” events and use them as we typically would using the list boxes “selection” properties.
Below is a crude example of how to override the CheckedListBox’s Draw method to keep the “selected” items back color to the same color of the non-selected items.
class CheckedListBox_NoSelect : CheckedListBox {
protected override void OnDrawItem(DrawItemEventArgs e) {
DrawItemEventArgs new_e_Args = new DrawItemEventArgs
(e.Graphics,
e.Font,
new Rectangle(e.Bounds.Location, e.Bounds.Size),
e.Index,
(e.State & DrawItemState.Focus) == DrawItemState.Focus ? DrawItemState.Focus : DrawItemState.None,
this.ForeColor,
this.BackColor);
base.OnDrawItem(new_e_Args);
}
}
The code above is a simplified version of this SO question… How change the color of SelectedItem in CheckedListBox in WindowsForms? …
As I started, you will have to decide which approach you need. I may tend to go the route of #user18387401‘s answer … simply to avoid creating a new User Control. However, if you want this functionality for all the CheckedListBoxes, then creating the control may be a better approach.
Below is a full example of what is described above.
The CheckedListBox on the left is a regular CheckedListBox and uses the approach from user18387401‘s answer. The CheckedListBox on the right is our new control class CheckedListBox_NoSelect above.
For each control, the SelectedIndexChanged event is wired up to demonstrate that the checked list box on the left with its SelectionMode set to None will always have its SelectedItem set to null and its SelectedIndex will always be set to -1. However, it is not difficult to figure out “which” item was selected using user18387401‘s approach. This index is also displayed in its SelectedIndexChanged event.
private void Form1_Load(object sender, EventArgs e) {
checkedListBox1.SelectionMode = SelectionMode.None;
checkedListBox1.Items.Add("Item 1");
checkedListBox1.Items.Add("Item 2");
checkedListBox1.Items.Add("Item 3");
checkedListBox1.Items.Add("Item 4");
checkedListBox1.Items.Add("Item 5");
checkedListBox1.CheckOnClick = true;
// Leave default selection mode to "One"
checkedListBox_NoSelect1.Items.Add("Item 1");
checkedListBox_NoSelect1.Items.Add("Item 2");
checkedListBox_NoSelect1.Items.Add("Item 3");
checkedListBox_NoSelect1.Items.Add("Item 4");
checkedListBox_NoSelect1.Items.Add("Item 5");
checkedListBox_NoSelect1.CheckOnClick = true;
}
private void checkedListBox1_MouseClick(object sender, MouseEventArgs e) {
int clickedIndex = checkedListBox1.IndexFromPoint(e.X, e.Y);
if (clickedIndex != -1) {
checkedListBox1.SetItemChecked(clickedIndex, !checkedListBox1.GetItemChecked(clickedIndex));
Debug.WriteLine("LEFT: MouseClick Selected Index: " + clickedIndex);
}
}
private void checkedListBox1_SelectedIndexChanged(object sender, EventArgs e) {
Debug.WriteLine(" LEFT -> Item: " + (checkedListBox1.SelectedItem == null ? "Null" : checkedListBox1.SelectedItem));
Debug.WriteLine(" LEFT -> Index: " + checkedListBox1.SelectedIndex);
}
private void checkedListBox_NoSelect1_SelectedIndexChanged(object sender, EventArgs e) {
Debug.WriteLine("RIGHT -> Item: " + (checkedListBox_NoSelect1.SelectedItem == null ? "Null" : checkedListBox_NoSelect1.SelectedItem));
Debug.WriteLine("RIGHT -> Index: " + checkedListBox_NoSelect1.SelectedIndex);
}
I hope this makes sense and helps. Sorry that I did this in C#. If you can not convert the code to a VB version, then let me know and I will add a VB version.
I have a very simple Windows Forms Application. And, in Windows (or, atleast Windows Forms Applications), when you press Enter while inside a Single-line TextBox Control, you hear a Ding. It's an unpleasent sound, that indicated you cannot enter a newline, because it is a single-line TextBox.
This is all fine. However, in my Form, I have 1 TextBox, and a Search Button. And I am allowing the user to Perform a search by pressing Enter after they've finished typing, so they don't have to use the mouse to click the Search Button.
But this Ding sound occurs. It's very annoying.
How can we make it so just that sound doesn't play at all in my Form?
#David H - Here's how I'm detecting the enter pressing:
private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
// Perform search now.
}
}
It works for me:
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
//Se apertou o enter
if (e.KeyCode == Keys.Enter)
{
//enter key is down
this.doSomething();
e.Handled = true;
e.SuppressKeyPress = true;
}
}
The SuppressKeyPress is the really trick. I hope that help you.
Check out the Form.AcceptButton property. You can use it to specify a default button for a form, in this case for pressing enter.
From the docs:
This property enables you to designate
a default action to occur when the
user presses the ENTER key in your
application. The button assigned to
this property must be an
IButtonControl that is on the current
form or located within a container on
the current form.
There is also a CancelButton property for when the user presses escape.
Try
textBox.KeyPress += new KeyPressEventHandler(keypressed);
private void keypressed(Object o, KeyPressEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
e.Handled = true; //this line will do the trick
}
}
Just add e.SuppressKeyPress = true; in your "if" statement.
private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
//If true, do not pass the key event to the underlying control.
e.SuppressKeyPress = true; //This will suppress the "ding" sound.*/
// Perform search now.
}
}
You can Use KeyPress instead of KeyUp or KeyDown its more efficient
and here's how to handle
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (char)Keys.Enter)
{
e.Handled = true;
button1.PerformClick();
}
}
and say peace to the 'Ding'
Use SuppressKeyPress to stop continued processing of the keystroke after handling it.
public class EntryForm: Form
{
public EntryForm()
{
}
private void EntryTextBox_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.Enter)
{
e.Handled = true;
e.SuppressKeyPress = true;
// do some stuff
}
else if(e.KeyCode == Keys.Escape)
{
e.Handled = true;
e.SuppressKeyPress = true;
// do some stuff
}
}
private void EntryTextBox_KeyUp(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.Enter)
{
// do some stuff
}
else if(e.KeyCode == Keys.Escape)
{
// do some stuff
}
}
}
On WinForms the Enter key causes a Ding sound because the form property AcceptButton is not specified.
If you don't need an AcceptButton the ding sound can be suppressed by setting the form KeyPreview to true and enter the following KeyPress event:
private void Form_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == '\r')
e.Handled = true;
}
No matter what control is active, there will be no more ding sound when pressing the Enter key. Since the key event proccessing order is KeyDown, KeyPress and KeyUp the Enter key will still work for the KeyDown events for the controls.
I stumbled on this post while trying to handle a KeyDown this worked for me.
If e.KeyCode = Keys.Enter Then
e.SuppressKeyPress = True
btnLogIn.PerformClick()
End If
Supressing the Key Press stops the event from being sent to the underlying control. This should work if you're manually handling everything that the enter key will be doing within that textbox. Sorry about the Visual Basic.
$("#txtSomething").keypress(function (e) {
if (e.which == 13) {
e.Handled = true; //This will prevent the "ding" sound
//Write the rest of your code
}
});
There is a very little chance anyone gets to this answer but some other answers are truly scary. Suppressing event on KeyDown kills 2 additional events in one strike. Setting e.Handled property to true is useless in this context.
The best way is to set Form.AcceptButton property to the actual Search Button.
There is also another way of utilizing Enter key - some people may want it to act as TAB button. To do that, add a new Button, set its Location property outside of the Form area (i.e. (-100, -100)) - setting Visible property to false may disable Button handlers in some cases. Set Form.AcceptButton property to your new button. In Click event handler add following code
this.SelectNextControl(ActiveControl, true, true, true, true)
Now, you may want to transfer focus only when focus it on TextBox you may want to either test ActiveControl type or use e.Supress property in event handlers of controls not meant to use Enter as TAB
That's it. You don't even need to capture e.KeyCode
Set your Search button's IsDefault property to true. This will make it a default button and it will be auto-clicked when Enter is pressed.
Well I lived with this problem long enough and looked it up here.
After thinking about this for quite some time and wanting the simplest way to fix it I came up with the easiest but not so elegant way to fix it.
Here is what I did.
Put 2 invisible buttons "Ok" and "Cancel" on the form.
Set the AcceptButton and CancelButton Property on the form to the invisible buttons.
Added no code to the buttons!
This solved all the secondary problems listed in this thread including the ToolStripMenu. My biggest complaint was the BindingNavigator, when I would enter a record number into the Current position to navigate to and pressed enter.
As per the original question in which the programmer wanted a search function when the enter button was pressed I simply put the search code in the invisible OK Button!
So far this seems to solve all problems but as we all know with Visual Studio, something will probably crop up.
The only other possible elegant way I could think of would be to write a new keystroke handling class which is way to much work for most of my projects.
You can set your textbox multi-line to true then handle the Enter key press.
private void yourForm_Load(object sender, EventArgs e)
{
textBox1.Multiline = true;
}
//then write your TextBox codes
private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
// doSomething();
}
}
i changed the textbox properties for an multiline textbox and it works for me.
Concerning the e.SuppressKeyPress = true; solution, it works fine by itself. Setting SuppressKeyPress to true also sets Handled to true, so there's no need to use e.Handled= true;
void RTextBox_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyData == Keys.Enter)
{
//do ...
bool temp = Multiline;
Multiline = true;
e.Handled = true;
Multiline = temp;
}
}
I have DataGrid this DataGrid content some row and columns "Id ...", but i don't know how can get value column "Id" when user double click by mouse.
This code for MouseDoubleClick:
<DataGrid ... >
<DataGrid.ItemContainerStyle>
<Style TargetType="DataGridRow">
<EventSetter Event="MouseDoubleClick" Handler="Row_DoubleClick"/>
</Style>
</DataGrid.ItemContainerStyle>
...
</DataGrid>
Behind code:
private void Row_DoubleClick(object sender, MouseButtonEventArgs e)
{
MessageBox.Show("here I want get column id when user DoubleClick some row");
}
This will also work
private void Row_DoubleClick(object sender, MouseButtonEventArgs e)
{
int index = DataGridName.SelectedIndex;
MessageBox.Show(index);
}
Hope that answers your question. :)
This might help you further:
WPF DataGrid - detecting the column, cell and row that has been clicked
I have a gridview which is binded to the datasource.In that gridview i have one column of checkboxes.I want to delete the rows of gridview by checking the checkbox of particular rows,Finally i have delete button outside the gridview which deletes the checked rows from the gridview.
problem is even though am checking checkboxes of rows..but it's showing checked=false...so none of the rows am able t delete..i tried all the possibilities but its not working
Please give me solution ASAP
this is my code
foreach (GridViewRow row in GridView1.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
CheckBox chkDelete = (CheckBox)row.Cells[5].FindControl("chkDelete");
if (chkDelete != null)
{
if (chkDelete.Checked)//It Showing checked=false
{
//delete code goes here//
Check you page load event, grid view may be rebinding again on each Postbacks. If you found such scenario, make following changes in your code.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//logic on page load
}
}
I'm using gridview with templates to show and edit some information from a sql database.
When I edit and change the data in that row and then click enter it automatically presses the highest on page button which uses submit to server set to true which means it'll try to delete instead of update.
I've have tried setting a panel round the gridview and setting the panel's default button to the "updatebutton" but it won't allow that because it can't 'see' the buttons.
I had a similar problem and I found a very simple workaround:
Place a button below the GridView and make it invisible by CSS (i.e. position: relative; left: -2000px)
Create a Panel around the GridView and give it as DefaultButton the ID of the button we just created.
Write the following line of code for the click-event of the button:
myGridView.UpdateRow(myGridView.EditIndex, false);
Whenever you press enter in the GridView now, the edited row will be confirmed.
You need to precess KeyDown or KeyPress event of the grid, and check if pressed key if Keys.Enter :
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
button1_Click(this, EventArgs.Empty);
}
}
private void button1_Click(object sender, EventArgs e)
{
// Your logic here
}
}