I have a WinForms application written in C#. The first screen to appear when it opens is a dashboard screen that can take some time to load. The data loading method is called using BeginInvoke on delegate. That part is fine, my problem is when I want to load the read data into some grids. The code to get me back to my UI thread looks like so
BeginInvoke(new Action<DashboardDataInfo, int>(LoadDashboardData), data, outbox);
This all happens without error. My problem is the dashboard Form will jump to the top of the screen. If data loading has taken long enough the user could be already onto another from in the app (so this is really annoying). The LoadDashboardData method doesn't do much besides assign the DataSource property of a few DataGridView controls.
Related
I'm updating a very large Windows Forms app to .Net Maui to make it into a cross platform app. Ideally, I would have the time to rewrite everything, but I don't. The client wants it yesterday. I'm already using a ton of the allotted time replacing the Windows Forms style interface with the XAML version. I've tried not to tinker too much with the code since the app was behaving flawlessly. Still, I've had to make a lot of changes because the Maui controls aren't always accessed the same ways as Windows Form's controls. Almost all of the methods and functions in the original app are synchronous. But some of the .Net Maui functions that I use to replace them are asynchronous. One function that is giving me a lot of trouble is the awaitable DisplayAlert(). Execution moves right onto the next statement in the code without waiting for the alert to be displayed or the user to respond. The function can be made awaitable, but to do this, the entire method within which it appears must be marked Async, which creates its own problems. There are literally hundreds of calls to The Windows Forms version of DisplayAlert(). Any solution that isn't basically a drop in replacement is going to cost tons of time.
I've been trying to create a blocking popup function that waits for the user's response before executing the next line of code within a synchronous block of code. In the XAML markup I've defined a popup "panel" with a frame, two labels and 3 buttons. Ideally, the code behind should be a function with the same parameters and behaviors as DisplayAlert() except that it blocks. It should display the panel, wait for a user response (button click/press), hide the panel, and finally return the text string of the button that was clicked...all within the same function.
Using simple method's like while loops to determine if a button was pressed block the thread from detecting that a button was press. Moving the panel display to a different thread than the button press, does nothing since the panel can only be displayed on the main thread. Invoking on the main thread has not been successful...at least not the way I wrote the code. I'm hoping someone can provide a very simple example of a blocking DisplayAlert() function that can be used within a non-async method.
I have very generic question. I tried google it but couldn't find anything good.
So the question is: I have winform application where based on option selected from menu bar, child form/view is loaded and these child forms are used to display reports.
in order to generate report, these child form contains report selection criteria like date, name etc and these value comes from DB. based on values available in DB, we add controls in the view.
Problem comes when screen takes lots of time to load, it freeze UI/application during loading that I don't want.
I also tried run tasks async but since it is using view during the processing, this option failed.
ThreadPool.QueueUserWorkItem(delegate { method.Invoke(presenter, results); });
presenter is my viewpresenter and results is parameters to invoke it. application concluding presenter name at run time and calling its default method using methodinfo.invoke().
Is there any other way to achive the same.
Point: I cannot redesign the whole application to separate out complete DB logic from UI logic as it is legacy application and this might break the application.
If "freezing" is the problem, you could use doevents, see here: Use of Application.DoEvents()
Or, you could go the really old fashioned, vb6 way: run the code that freezes your UI synchronously, but from a modal window shown above your ui. You can event present the user with the progress indicator.
My app consists of 3 tabs, each tab has a DGV, tab 1 and 2 do not contain that much data within the DGV but in tab 3 it can be between 100-5000 rows
The problem im having is that when i start my app, and move to tab 3 it takes a while before anything is displayed..
Im looking for a way to display a loading form to the user while the data is being added to the DGV..
How would i accomplish something like this?
Start loading data on a background thread and monitor the progress(displayed as progress bar).If you are doing it on main thread than you'll hang your interface.
Theres one good article but it is in VB.
Long running operations should be running in a seperate worker thread, commonly BackgroundWorker class. This prevents the UI from locking up during said operation. You can also choose to display a loading dialogue while this thread runs.
The other answers here are correct. But since you specifically asked about a loading window, I remembered a very nice example in Code Project.
In a project I was involved with, we took this example and made it independent. We added static methods called Start and Stop, and the Start method would create a thread, and then load the window, while the Stop method signaled the form it needs to close gracefully.
Hope this helps!
Thanks for your time, i am creating an application which will take 5
URL's from database and then navigate each in 5 browser-controls
respectively. This activity is done in "background worker control's do
work function". On first time load of this window form, everything
goes fine, i am having a function of leave this form (which will go
back to main form). when i again navigate to this form, i am having
following exception on loading document in web-browser control.
"The message filter indicated that the application is busy. (Exception from HRESULT: 0x8001010A (RPC_E_SERVERCALL_RETRYLATER))"
From http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.dowork.aspx
You must be careful not to manipulate any user-interface objects in your DoWork event handler. Instead, communicate to the user interface through the BackgroundWorker events.
I was opening each document in each web-browser-control in the backgroundworker_DoWork function, what solved my problem is by loading data from database in backgroundWorker_DoWork and loading documents in each web-browser-control in backgroundWorker_Completed function.
how do i calculate the loading percentage of my C# application. i want to show a splash screen with a progress bar showing percentage of application loaded.
Is there any standard method\library for that or i will have to just update the progress bar value at different points in my form load code.
Or can any gimme a tutorial on application preloaders
The first time user starts your application, assume it will take 10 seconds and show progressbar counting down those 10 seconds. Once the application is loaded, save somewhere on user's computer actual time it took to load your application. Next time user loads your application, use saved time instead of your original 10 seconds.
This is simple and obvious concept. User doesn't care what parts of the application are loading, he cares how long it's going to take and he wants to see countdown.
Probably the easiest way to do this is to create an instance of your splash form at the beginning of your startup form's Load event. In the splash form, expose its ProgressBar as a public property. After creating the splash form, set its ProgressBar's Maximum property to the number of discrete steps that you can identify in the Load event code, then show it by calling its .Show() method (not .ShowDialog(), of course).
As each step in the Load event completes, you just increment the public ProgressBar's Value property. When all steps have completed, close the splash form and dispose it.
This may or may not work properly, because if your startup form contains a large number of controls, then a good percentage of the total loadup time will actually be spent in the form's constructor, which will be called before the Load event. It might be best to move all of your initialization code into the constructor, and create and Show the splash screen from there.
Well, in any case you need a fairly accurate guess at how long your individual steps take. Only then can you give an actually meaningful progress bar. You can approximate it by dividing your loading process into several steps you assume to be roughly equal in time and calculate progress as you finish those steps.
An alternative would be not to show a progress bar but rather a series of loading steps, represented either by text or graphically. I think KDE does this on startup. That way you show progress but avoid the user's expectations towards a progress bar (which works best if the progress bar is either linearly progressing or accelerating. If it frequently stops and jumps it just creates the impression of a very slow process).
Another option would be to eliminate the splash screen entirely by trying to make program startup fast and loading what you need at runtime. This may or may not be an option for you or your program but it can show pretty significant improvements in startup time and overall impression of program speed.
First of all the Splash screen is shown to give user an illusion that program has started and they will be handled control at any moment.
Secondly if you want to show the progress bar then you need to accurately calculate the number of tasks you perform. Then show the label loading xxxxxx....... and increment progress bar after completion of every item.
As for the question of optimizing starting up time it mainly depends upon the function of your application.
Suppose you app is a PIM then you may load the events and tasks for today and show it to the user quickly and then start loading other data.
I once had an application where I had to show the object hierarchy using Treeview each node could have unlimited number of items. I loaded the top level objects and displayed then in the tree view and put marker (actually I put * in tag of the node, which I learned from some .net book or article I had read long ago but remembered) when use clicked on the node I loaded the immediate children.
A Pretty Good Splash Screen or Splash Screen