Populating Tabs WinForms Goes Undetected without User View - c#

This might just be a small quirk. But I've built a small windows form application with multiple tabs.
I have a feature that allows users to "load" the entries in each of the tabs by opening a json file. This lets them avoid manually inserting the data. At the same time, I have a "check" to make sure that all required fields have been populated.
What I've found is that even if the load process is successfully populating all the right fields, the user still needs to select each tab (even though they are already filled), in order to avoid hitting the flag.
Hopefully, this makes sense. Right now, my work around is to have the program flip through each tab automatically upon "load", but it seems strange that winforms can't detect a text box has been filled unless the tab is viewed.
Any advice?

Some events only fire when the control is visible. This sounds like what you should do is decouple the text entries from the control and store them in another object which fires off the filled events then do data binding to those entries.
This has the nice benefit of decoupling the UI from the data storage (always a nice thing) as well as freeing you from the vagaries of the .net UI system (both winforms and wpf have 'interesting' quirks like the above which assume specific behavior preferences).

Related

How to make a Windows Form to change it height adaptively as controls get added/removed or hidden/shown?

What I need can probably be described as "reverse-anchor", "reverse-dock" or something like that (I have chosen to mention this just because "reverse-anchor" happened to be the first thing to come into my mind as a keyword candidate when searching for questions and answers that might already have been submitted discussing this subject, perhaps this will help people thinking a similar way to find this one in future). WinForms controls implement the Anchor property to set up adaptive resizing on containing control/form size change but I need the opposite - the form to resize adaptively to the controls.
A thing adding a minor bit of complexity to the task is that the controls meant to be added/removed/shown/hidden/enabled/disabled (and resized perhaps - this functionality is not really needed directly so far but I suspect it can turn to be required for compatibility with non-default Windows visual styles and themes that have potential to affect controls sizes unpredictably and can change at any moment of the app running) are not going to be the last ones on the form - a row of buttons will always be in between of the last control of the volatile group and the window lower border.
The actual task is to design a form that will display a collection of objects with a row of controls (a label, a text box and 0-2 buttons) corresponding each of them and it is strongly preferable to use just the very basic "common controls" avoiding grids, lists and stuff like that in this case (wrapping them in an additional container controls like panels is perfectly acceptable though, abstracting them in a separate "user control" can be considered too if this can really make the solution easier, more reliable or otherwise better, using hand-written code manipulating controls and form sizes is perfectly acceptable too (I can hardly expect a "set a magic property and it's done" kind of solution to exist for this task) but I haven't found a reliable algorithm so far (when to change what properties and what formulae to calculate new values with)).
The maximum capacity can be safely limited to something near 10 (or 20, perhaps, but not more - more would be just absolutely unreasonable to display on one form (provided scrolling is not an option)) so both ways are acceptable: to add/remove the controls in runtime or to put them on the form in the designer and just manipulate Visible and/or Enabled properties in the code. By the way I have found a problem with Visible - it gets switched off and back on by the framework internals before the form is rendered and other controls Anchor properties come in the game but I don't think it's a good idea to rely on this to happen always and the same way so just adjusting the form Size property on a control Visible property change does not feel really convenient).
What might be some good ideas relevant to implementing this behaviour?
PS: As far as I know this is a natural feature of WPF but I am to use WinForms to make the app runnable on Macs and, perhaps, other non-Windows platforms with help of Mono.
I'll tell you about some clues may help you:
1- correct to build your own Procedure for manipulating all the matter.
2- i advice to use a Wizard methodology (Next / Back buttons) so if the plate form is small like tablet or smart phone, so the mentioned procedure will decide how many Controls combinations (Label, text box, option button...) will be in each frame of that wizard and keep the remaining for Next button.
3- By the way if you will hide some controls use the original event fires to run the mentioned Procedure. (like a basic button to start the form so don't depend on visible / resize events).
4- Resize the size of each form of the wizard in the last part of the mentioned procedure.
If still a problem exists tell me and i hope i can help :-)

Best way to handle different panels occupying same area

I have this application:
I want to change the marked area when the user is clicked one of the navBarItems (like Microsoft OUTLOOK). I've been doing some research and a lot of people said that I can add several panels and show/hide them when user is clicked a navBarItem. But the area will contain a lot of gridviews and a lot of other controls. I don't know if I want to initialize all of them when application starts because it's gonna be hard on the cpu and memory to keep all the controls running at the same time. And I don't think it's an elegant solution for this kind of situation. But if I choose to initialize controls when user is clicked to corresponding navBarItem, it's gonna be laggy for the user.
What is the best design approach for this situation?
PS: I can use commercial libraries too.
Thank you.
Does not necessarily have to be laggy. If you show the screen first and then populate the data in the background it may not look too bad for the user. Also, once a particular screen is initialized you might keep it in memory so subsequent times user navigates to it it will be faster.
Also, look at what data you are loading into each control. Is some of the data the same? Can you preload some of the data in the background and keep it around?
Do you have a lot of drop down lists? If so, can you prepopulate or cache some of the drop down list data to improve the performance?
Is there one or two of the panels that will be used a large majority of the time? If so you could preload these panels so the user has a better experience for the panels they will most often navigate to.
Background processing to load data will make your code more complex but that is going to be the best way to get good response time from your app.
Here is an example of running a background thread from the UI using Task.
And another one using the BackgroundWorker.

Best way to load a heavy UI with lots of controls

I am working in a Windows Forms application, it needs a lot (and I mean a lot) of controls. Using tab controls to organize them (sometimes nested tab controls).
I was reading how to load the App faster and a lot of people said to think twice if the controls are really needed. Well, to be honest I think that it's possible to reduce the number of controls used BUT the client requested it that way, so there's almost nothing I can do about it.
I was reading that I should use multithreading tactics but there's a hardware limitation: the application MUST run on an average neetbook. It's really a pain because I'm limited in terms of load time and how much space I can use to put the controls.
I was wondering if I can just load one or two tabs before the form is shown and then load the others, would that be possible/correct/efficient? If it is, how could I achieve it? I also was planning to use MDI childs but I need to retrieve all the information in all the controls at some point (from absolutely all the tabs and nested tabs).
Can you please give me some tips? Do you have any experience working on something similar?
One strategy is creating your main page with a TabControl holding empty TabPages.
Then you can design several auxiliary forms (one for each TabPage you require) each containing a single Panel control with Public visibility (change the Panel's Modifiers property to Public) holding the real UI elements that you would have placed on the TabPage.
When the empty TabPage is clicked by the user, then you create the auxiliary Form (you don't show it, just create it), and then access the Panel control in the auxiliary Form, then you can reparent it to your empty tab Page, like this
AuxForm1 frm = new AuxForm1();
frm.MainPanel.Parent = this.tabControl1.TabPages[0];
This will delay the TabPage's control creation until the panel is clicked by the user :)
Hope this helps!
I was wondering if I can just load one or two tabs before the form is shown and then load the others
You could make each "tab" contain a UserControl, and load that UserControl on demand, when the tab is activated. That would, at least, prevent you from having to initialize everything on startup.
"lots of controls" is not a requirement anyone can answer. A dropdown list with tens of millions of rows is a very different problem than a wizard UI with thousands of steps and require different answers.
Why has the client "requested it that way"? We need to know the actual deliverable requirements to answer your question. Have you shown them alternatives?
First, post some of your mockups. If you don't have mockups yet, make some and perform paper testing with them, then post them.
Who's "a lot of people"? Testers? Customers? Anonymous forum posters? Post your mockups to https://ux.stackexchange.com/ and ask for comments.
"I can just load one or two tabs before the form is shown"? Of course you can do that, but why are you presupposing that your UI will be "one or two tabs" before you have shown us any requirements at all? Get requirements, make mockups, then ask specific, answerable questions.

How can I detect the visibility of a control?

How to detect if a control is visible to a user? I have a control that displays status of application, and I want it to be updated (it's value to be updated, for example, increase the value of a progress bar, or change a label's Text property) only if a user sees it. No need to update it if a user has minimized the form that contains this control, or if another form overlaps this control. I just don't want to do extra calculations if the control isn't visible any way.
Also, how do I detect the events that hide/show this control?
This seems to be one of the topics which is frequently asked and which has many possible solutions, depending on the context.
First, for reference sake, some links to old discussions I stumbled over during my research:
How to check absolute control visibility and how to be notified for changes of absolute visibility
C# winform check if control is physicaly visible
starting position:
An IDE for heterogenous systems with plenty of different hardware and many different transport layers where some are really slow. One feature is to display memory values of remote hw in editors. A typical use case is to have >20 editors open, where each displays between 1 and 100 different values.
Because the transport layers are limited in bandwith I was looking for a solution to "prioritise" the data acquisition.
(partial) solution:
A visibility tracker which basically manages a specialised adapter for the control itself and every ancestor control. The adapter handles the visibility dependent on the ancestors type, ie. for a Control, it's just instance.Visible, for a TabPage I check which page is selected, ...
The manager's housekeeping then is just to keep track of parent-changes for all the ancestors so that it tracks the correct visibilities.
Catching whether or not the form has focus or is minimalized is your best bet, but I am not sure that hits all cases. In general, I would update regardless of whether the user is paying attention, unless it takes tons of cycles to get the information to the form, which I doubt. Setting up conditional bits in an application just adds another place for things to go wrong.
Let's examine this a bit. Minimized forms are one thing. If the form is minimized, you know the user is not even looking at it. But, if another form is in front, then you want to check if the form has focus. the problem here is a person can be using half the screen to watch while typing in word on the other half. Word has focus, so the form does not update, which is not your intention. Same could happen if you create another form in the application. the update no longer has focus.
THere is no magic "is the user looking at me" property in Windows.
This is never necessary. Windows won't generate the Paint event when a window isn't visible. If you implemented painting yourself then be sure to only do this in the Paint event and to call Invalidate() if there's a reason to repaint.
How often does the status change? It is probably better to update the status indicator when the status changes and not worry about visibility. Let's say that status changes on average every 5 minutes. The window/control may not be visible when the status changes but could easily become visible well before the next status update. In this case, the status indicator will be wrong until the next update because you avoided changing the indicator. Unless updating the status indicator is very expensive, it's probably better not to try to project what the user will do.
Edit after reviewing other comments:
I think you might be able to achieve better efficiency improvements by identifying a model for detecting/notifying status changes instead of calculating on demand. You may need to weigh the frequency of status changes against the frequency of visibility changes to your control.
Take a look at Control.Visible, and the Control.VisibleChanged event.

Windows Handle Issue

Facing an issue where in the user objects goes more that 10000 in windows app and the app crashes.
After much analysis we realized that we need to get rid of the panels that we use to align the controls and may be reduce the possibility of user objects reaching 10000.
Our App UI is dynamically generated driven by a configuration and it can vary. So all the UI generation is happening dynamically.
Any help would be much appreciated
This is an unfounded suggestion, but remember to make sure that unneeded Controls always detach themselves from events they are be subscribed to. A Control that's still subscribed to an event of an "active" (what's the right term?) object can't be cleaned up.
Just as a note, the Chrome development team hit this problem too, and the scroll bar arrows (among other things) weren't drawing anymore when some internal gdi limit was hit. It is quite possible to hit this limit in a complex enough gdi app.
You might want to do some research and see how they fixed it.
As an alternative, you could consider using a different platform, either gtk or wpf would do fine and they don't use gdi handles to draw.
from here,
If your program runs haywire, you will
find that it manages to create about
10,000 window manager objects and then
the system won't let it have any more.
Why stop at 10,000?
The first answer is "If you have to
ask, you're probably doing something
wrong." Programs shouldn't be creating
anywhere near ten thousands window
manager objects in the first place.
There is no need for that many handles. I think you need a new solution.
I'm guessing this from your question, but you're probably putting this large number of controls on a scrollable panel or a tab control with multiple tab pages, which means that most of these controls aren't actually visible to the user at any given point in time (because they couldn't possibly all be visible at once).
If you have all of these controls on a scrollable panel, one possible solution is to only load and display the controls that are on the visible portion as the user scrolls around in the panel. As the user scrolls, you would unload and dispose the controls that are no longer visible.
If you have all of these controls in a multi-page tab control, you can use a similar strategy and only load the controls on a tab page when that page is made visible (and unload the controls from the previous top-most tab page at the same time).
Another general strategy is to break up your one monster form into a large number of UserControls, and only show one of these UserControls at a time.

Categories

Resources