Unexpected behavior of a Winforms label - winforms

I am working on a Windows Forms application and I would like someone to explain why the problem I'm encountering happens. The problem is that a label whose text I set at the beginning of a function changes (apparently) at the end of the function.
I have the following code:
private void OnButtonSearchClick(object sender, EventArgs e)
{
labelLoading.Text = "Loading...";
dataGridViewSearchResults.DataSource = listOfFilteredEntities();
}
My filtering function gets a list of entities from the database and filters them by parameters passed to the function.
The problem is that the label text becomes visible after the datagridview displays the results. I'm not using background threads which might change the label text. Thank you.

Related

How to get the last click event on DataGridViewCheckBoxCell

I'm using a DataGridViewCheckBoxColumn inside a DataGridView in a WinForm panel.
When a checkbox is clicked, I need to compute things that might change a Control state outside the DataGridView.
To do so, I have to handle the CellContentClick event because I need to compute only when a checkbox value is actually changed.
Grid.CellContentClick += Grid_CellContentClick
private void Grid_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
DataGridView dgv = (DataGridView)sender;
dgv.EndEdit();
// Compute stuff
}
However CellContentClick doesn't always fire, while the internal event that does change the DataGridViewCheckboxCell checked state is.
Most importantly, fast successive clicks on a checkbox do not fire CellContentClick, only the first is catched until the user stops clicking.
As a result I end up in an invalid state where the control outside the DataGridView doesn't display as intended because the computation doesn't use the checkboxes final values.
I've tried to debounce the event and creating a pseudo-lock using MouseDown and the grid ReadOnly property, with no success.
Is there a way to catch only the last event of a series of clicks? Is there a better way to do this?
Thank you #Jimi and #JohnG for your insights, it helped me solving this issue.
I could not make it work using CellValueChanged and CellContentClick, even with async and await Task.Delay(...) as it did not fire correctly and triggered inter-thread exceptions in my computation afterwards.
It might just have been me though, but I wasn't very fond of using Threading in this context anyway.
I hadn't considered using CellValueChanged and noticed that it wouldn't trigger for a DataGridViewCheckBoxCell when clicked, so I ended up reading this thread and the solution is actually quite simple.
Grid.CurrentCellDirtyStateChanged += Grid_CurrentCellDirtyStateChanged;
Grid.CellValueChanged += Grid_CellValueChanged;
private void Grid_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (Grid.IsCurrentCellDirty)
{
Grid.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
}
private void Grid_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
DataGridViewCheckBoxCell cell = (DataGridViewCheckBoxCell)Grid[e.ColumnIndex, e.RowIndex];
// Compute stuff
}
This code is executed each time a grid checkbox is clicked on, and has a far better logic since it relies on a direct value change.
However it means the computation takes place each time the value is changed.
I believe one could debounce the computation in order to improve this solution, fortunately mine isn't too resource expensive so it runs smoothly and I don't need to take it that far.

Visual Studio "Not Responding" when I change a datetimepicker value in Winforms [duplicate]

I have a datetimepicker in C#. When I click on it, it expands to show a monthly calendar, when I click the left arrow to go back a month, it changes the value and calls my event. The event includes too much code to include here but it calls several functions needless to say.
The problem I'm having is that when I click that left arrow it gets stuck in some sort of loop and keeps descending through the months and I can't stop it. One of the functions that is being called contains a Application.DoEvents() and if I comment that out it doesn't get stuck in the loop, but I need that command to update another section of the interface. Any idea why this is happening?
I can duplicate it sometimes with this code, sometimes it just does it a couple times, sometimes it gets stuck in the loop.
private void DateTimePickerValueChangedEvent(object sender, EventArgs e)
{
afunction();
}
private void afunction()
{
listView1.Clear();
panel1.Visible = true;
Application.DoEvents();
}
I also have the same problem. In my case, instead of calling DoEvents I'm updating a Crystal Report view. The only workaround I found is to update my view upon the CloseUp event instead of ValueChanged or TextChanged.
Scott, how did you finally corrected your problem ?
The DateTimePicker ValueChanged event is buggy. Per Microsoft Windows Forms Team on this page https://connect.microsoft.com/VisualStudio/feedback/details/1290685/debugging-datetimepicker-event-hangs-vs:
"The DateTimePicker control installs a mouse hook as part of its functionality, but when the debugger has the WinForms application stopped on a breakpoint, it allows the possibility of a deadlock if VS happens to get a mouse message. For now, the deadlock is unfortunately a consequence of the DateTimePicker's design. The mouse hook is installed when the drop down is clicked to display the calendar. This means that breakpoints should not be sent in any event handlers which would be called while the calendar is active. We are currently investigating whether it is possible to address this issue and we will update this thread with further information if we are able to make a fix available."
Without seeing any of the code, try these steps:
Comment out the entire event handler
to see how fast it runs with nothing
attached to it.
Uncomment lines one at a time to see
which ones are causing the most
problems.
Analyze those method calls.
...
Profit!
You could try a couple of things. Get rid of the DoEvents inside of the ChangedEvent.
Call the doevents inside of a seperate function after maybe a period of time (thread.sleep() ?).
I know doevents does cause issues but I rarely use it.
event procedure ValueChanged :
set parameter in sender.tag
enableTimer and execute parameter using sender.tag
example:
private void DateTimePicker_ValueChanged(object sender, EventArgs e)
{
DateTimePicker ThisSender = (DateTimePicker)sender;
Timer.Tag = ThisSender.Name.ToString() + "=" + ThisSender.Value;
Timer.Enabled = true;
}

Clear SelectionBackColor from text in RichTextBox [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
RichTextBox syntax highlighting in real time--Disabling the repaint
I'm using a RichTextBox control to find and change the SelectionBackColor property of some words. The words are not fixed so basically the text that has different BackColor varies.
I've already tried two methods of clearing the BackColor from the previous text before applying it to the new words:
Selecting all the text and setting the SelectionBackColor to the Controls BackColor.
Saving the text to string then putting it back to RichTextBox to clear it's formatting.
Although both methods work an issue arises when you have a lot of text in the control. For the first method, it becomes clearer that all text gets selected (you can notice it for a few milliseconds), which becomes annoying since this happens in the TextChanges event, so basically every letter that gets removed/added triggers this. As for the second method, it's not that obvious as the first, but since the text is removed and then insert back, the scrolling becomes a bit odd since even after using .ScrollToCaret() the scrollbar isn't exactly were it was before the SelectionBackColor clearing.
It feels like there should be a better way of clearing the existing SelectionBackColor without all these issues. Especially in this case since it has to do the cleaning in the TextChanged event.
Waiting for your thoughts. Thanks in advance.
Edit: You can see below the method I'm using for the first example I mentioned above (selecting all).
private void ClearSelection(RichTextBox rtb)
{
if (rtb.Text.Length > 0)
{
int currentIndex = rtb.SelectionStart;
rtb.SelectAll();
rtb.SelectionBackColor = Color.White;
rtb.SelectionLength = 0;
rtb.SelectionStart = currentIndex;
}
}
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
if (!_working)
{
ClearSelection(richTextBox1);
}
}
The _working bool is just to make sure that the method doesn't get trigged when the program is changing the colour of certain words so that it will only be trigged when it's the user changing the text.
Edit2: For those interested, the solution at Reset RTF in RichTextBox? seems to do the trick. I would avoid the one that was voted as duplicate (for some odd reason) since it produces more graphical issues.
Have you tried using double buffering? Maybe something like:
richTextBox1.SetStyle( ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.DoubleBuffer,true);

How to select multiple files with an OpenFileDialog?

I have a WinForms application with an OpenFileDialog in it and I'd like to enable selection of multiple files when the user interacts with the dialog. How can I accomplish this?
See the OpenFileDialog::Multiselect property, from the docs:
Gets or sets a value indicating whether the dialog box allows multiple files to be selected.
To get the list of files selected you should use the OpenFileDialog::FileNames property.
adding the style OFN_ALLOWMULTISELECT will add this see this
If you want to select a folder you should use something else :)
If you are using c++ .net (you didn't state that). You can use the MultiSelect property MSDN
Don't know what you did, but when I click File/Open in Visual Studio 2008, it is possible to multi-select all files or just a part of them by clicking on the first file in the list, holding the shift key and then clicking on the last file.
EDIT: ok, you edited the question, seems that I misunderstood you in the first place. Idan K's answer should be correct.
C# code
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.MultiSelect = true; //sets to multiple selects
ofd.ShowDialog();
}

Showing a tooltip inside a datagrid

I'm trying to show a windows forms tooltip inside a datagrid to highlight an error. The problem I have is that everytime I call tooltip.Show("You have an error", datagrid, 0, 0), The tooltip is confined within the datagrids boundaries and doesn't go outside, which ultimately means the tooltip itself covers up the actual row where the error occurs.
I thought about tooltip.Show("You have an error", Form1, ?, ?) but I don't see an easy way to compute the offset of the datagrid on the form. Since all controls are docked, depending on how the user resizes the form, the location will change.
There is a caveat, the datagrid itself is not a Forms.DataGrid, instead it is an Infragistics UltraGrid which may do funny things itself, which are outside of my ability to alter.
It turns out that it's easy enough to get the location for the Show command from the UltraGrid by querying the UIElement associated with it. Here's what I'm doing:
private void ultraGrid1_BeforeCellUpdate(object sender, BeforeCellUpdateEventArgs e)
{
if (!DataFormat.CanEdit(e.Cell.Row.ListObject, e.Cell.Column.PropertyDescriptor))
{
var tip = new System.Windows.Forms.ToolTip();
tip.BackColor = Color.Orange;
tip.Show("unable to edit", this, e.Cell.GetUIElement().Rect.Left, e.Cell.GetUIElement().Rect.Top, 500);
e.Cancel = true;
}
}
Have you looked at these:
HOWTO:Create Advanced ToolTips For The WinGrid
BeforeDisplayDataErrorTooltip Event

Resources