I have a Gridview. I and populating two dynamic text box for each cell inside it. User will enter the arriving time in first textbox and the arriving + 9 hours will be added and display in second textbox. I have written event handler where i am calculating exit time. the event handler is working fine but I need to event handler will fire for first Cell only. How to prevent event handler for rest of the textbox.
You didn't provide code but this is a general example.
private bool _isFirst = true;
private void CellEventHandler(object sender, EventArgs e)
{
if (!_isFirst) return;
// code
_isFirst = false;
}
You could also unbind the event handler
private void CellEventHandler(object sender, EventArgs e)
{
// your code here
textBox.Click -= CellEventHandler;
}
Related
I have a TextBox and I want all the text inside of it to be highlighted when the user clicks on it (so that they can replace it easily). I have the following event handler linked up the the TextBox:
private void TextBox_Enter(object sender, EventArgs e) {
SelectAll();
}
When I click on the TextBox, the text is only selected for a fraction of a second (sometime it's so fast I can't see it at all) and then it goes back to being a cursor. Does anyone know how to fix this or if there are any relatively simple workarounds?
I tried the same thing with the TextBox.MouseClick event (and it highlighted the text), but because it was the MouseClick event the text was highlighted every time I clicked the TextBox (even when the TextBox already had focus).
I have also tried SelectionStart = 0; SelectionLength = Text.Length, but the same thing happens. This leads me be believe the issue has something to do with the event.
I also tried the TextBox.GotFocus event and had the exact same problem.
I am doing this in a Windows Form application.
The reason why you didn't see the text getting selected is that the TextBox is busy when one of those events occurred (e.g., caret positioning). You actually select the text, but then the internal event handlers of the TextBox execute and remove the selection e.g. by setting the caret position.
All you have to do is to wait until the internal event handlers have completed.
You do this by using the Dispatcher. When you invoke the Dispatcher asynchronously the delegate is not immediately executed but enqueued and executed once all previously enqueued actions (like the internal event handlers) are cleared from the dispatcher queue.
So going with the TextBox.GotFocus event in WPF (or the TextBox.Enter in WinForms) and the asynchronous Dispatcher will do the trick:
WPF
private async void SelectAll_OnTextBoxGotFocus(object sender, RoutedEventArgs e)
{
await Application.Current.Dispatcher.InvokeAsync((sender as TextBox).SelectAll);
}
WinForms
private void SelectAll_OnTextBoxEnter(object sender, EventArgs e)
{
var textBox = sender as TextBox;
textBox.BeginInvoke(new Action(textBox.SelectAll));
}
Thankfully I found a solution! It turns out that the Click event is executed before the Enter event, this allowed me to set up a JustGotFocus variable and do the following:
private void myTextBox_Click(object sender, EventArgs e) {
this.JustGotFocus = true;
if (JustGotFocus) {
myTextBox.SelectAll();
}
}
private void myTextBox_Enter(object sender, EventArgs e) {
JustGotFocus = false;
}
If anyone else has this problem hopefully my solution is useful.
I use ContexMenuStrip on DataGridView to delete some rows but it doesn't work correctly.
Every time if I checked 3 rows, after selecting the ContexMenuStrip it only deletes 2 rows. When I do this code without the ContexMenuStrip (by Button) that works correctly.
When I see the behavior I understand current row is editing but doesn't finish. After double clicking on the current row to stop editing my ContexMenuStrip works correctly.
How to stop editing after checking the CheckBox?
When a cell has been selected and edited, the DataGridView property IsCurrentCellDirty is set to True. If you catch the event handler when this state changes on a DataGridViewCheckBoxCell, you can call DataGridView.EndEdit() to finalize those changes immediately.
this.dataGridView1.CurrentCellDirtyStateChanged += DataGridView1_CurrentCellDirtyStateChanged;
private void DataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (this.dataGridView1.IsCurrentCellDirty && this.dataGridView1.CurrentCell is DataGridViewCheckBoxCell)
{
this.dataGridView1.EndEdit();
}
}
Further explanation:
Behind the scenes, DataGridView.IsCurrentCellDirty is updated whenever you edit the current cell. The first line of code above allows you to attach to the CurrentCellDirtyStateChanged event your own event handler (DataGridView1_CurrentCellDirtyStateChanged) . So whenever the cell becomes dirty, behind the scenes will call the base level event and then your method as well. Without that line, your method will not be called. The += operator is what attaches your method to the event's call-chain.
For example, adding the following handlers:
this.dataGridView1.CurrentCellDirtyStateChanged += DataGridView1_Example1;
// this.dataGridView1.CurrentCellDirtyStateChanged += DataGridView1_Example2;
this.dataGridView1.CurrentCellDirtyStateChanged += DataGridView1_Example3;
private void DataGridView1_Example1(object sender, EventArgs e)
{
Console.WriteLine("Example 1");
}
private void DataGridView1_Example2(object sender, EventArgs e)
{
Console.WriteLine("Example 2");
}
private void DataGridView1_Example3(object sender, EventArgs e)
{
Console.WriteLine("Example 3");
}
When the dirty state changes, you'll see the following output. Notice the 2nd event handler was excluded:
// Example 1
// Example 3
There's a small problem in the code proposed by OhBeWise. It works for Mouse-Clicks. But if you toggle the checkbox with the Space key you can't toggle the checkbox again without manually switching the current cell first. With a small change it will work:
private void DataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (this.dataGridView1.IsCurrentCellDirty && this.dataGridView1.CurrentCell is DataGridViewCheckBoxCell)
{
this.dataGridView1.EndEdit();
DataGridViewCell currentCell = this.dataGridView1.CurrentCell;
this.dataGridView1.CurrentCell = null;
this.dataGridView1.CurrentCell = currentCell;
}
}
I'm trying to use this function:
private void IDCustTextBox_LostFocus(object sender, System.EventArgs e)
{
if (CustName.Text == "abc")
MessageBox.Show("Error");
}
When I type abc in CustName textbox, and then leave the textbox, I dont get any message. In the textbox properties I can see that "textbox.Changed" is using the event LostFocus.
How can I get this to show the Error message above?
There is no LostFocus event for textbox in property Window,if you want to use this then you must need to add event handler, there is textbox leave event in property window, that could be used as below:
private void textBox1_Leave(object sender, EventArgs e)
{
// do your stuff
}
for adding event handler you need to write the following:
textBox1.LostFocus += new EventHandler(textBox1_LostFocus);
then you can use it as below:
private void textBox1_LostFocus(object sender, EventArgs e)
{
// do your stuff
}
You will need to let the field know that there is a handler for the event LostFocus
Since this is not part of the properties window you will have attach the handler as such
CustTextBox.LostFocus += new EventHandler(IDCustTextBox_LostFocus);
In the code below the SelectionChanged event is fired before the end of RowsAdded,how can I make the Event atomic?
private void dataGridView1_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
{
dataGridView1.CurrentCell = dataGridView1.Rows[dataGridView1.Rows.Count - 1].Cells[1];
dataGridView1.Rows[dataGridView1.Rows.Count - 1].Cells[1].Selected = true;
}
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
if (dataGridView1.CurrentRow != null)
{
//Something
}
}
what should i do?
SelectionChanged is fired in the middle of handling RowsAdded because you are causing a SelectionChanged by changing the current cell within dataGridView1_RowsAdded. Adding a row doesn't cause both events to be fired -- you're causing the second event while handling the first one. (In fact, you're probably causing SelectionChanged twice, because both lines in the handler seem to change the selection).
If you don't want dataGridView1_SelectionChanged running while in the RowsAdded handler, you need to either temporarily unsubscribe from the event:
dataGridView1.SelectionChanged -= dataGridView1_SelectionChanged;
// change the selection...
dataGridView1.SelectionChanged += dataGridView1_SelectionChanged;
Or even better, re-design what you're doing inside the SelectionChanged handler so that it is appropriate for all instances of the event.
You can override the event you want to conrol and then put an if condition in the overriden event and control when it fires and when it does not.
mahdi
I've added a handler for the CellFormatting event on a DataGridView to modify the background color based on the content of the row.
It doesn't seem to be firing even as data gets inserted into the table. I added the event handler by doubleclicking in the IDE on the CellFormatting event which seemed to create the code properly.
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
// this never gets called
MessageBox.Show("Event fired");
}
What could I be doing wrong?
I think you cannot use CellFormating event for your case. It occurs when the contents of a cell need to be formatted for display.
Try CellValueChanged event instead (http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.cellvaluechanged.aspx)
Or
Select other appropriate event from http://msdn.microsoft.com/en-us/library/x4dwfh7x.aspx
You could try the RowValidated event:
private void dataGridView1_RowValidated(object sender, DataGridViewCellEventArgs e)
{
dataGridView1.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Blue;
}
NOTE: This event will fire when you click on rows and when you close the form.