How should I manage my screens in WinForms? - c#

So I'm rewriting a windows forms project.
The old project had few issues. These are some I'm trying to fix right now.
My problems:
Everything was on panels on one form. Switching screens in the code was done by hiding/unhiding these panels.
General slow performance across screens.
Poor data coupling.
My solutions:
Break up screens into user controls (hereon just refered to as 'screen(s)'). My main form has 3 components on it, a nav bar, title bar and 'view port'(an empty, docked, panel).
I will keep only one screen/user control (hereon just refered to as 'screen') in memory and docked in the view port. This is done by just initializing a screen and popping it into the view port panel on the main form. Changing screens will simply be destroying the current screen in the view port and initializing a new one in it's place. This isn't to reduce memory usage but rather active components, as what I understand, slows down the old winforms project, is the fact that winforms uses the cpu to render.
This is where the subjectively fun part comes in. If a controller/presenter(from mvc/mvp type patterns)/code changes business data, the screen that is displaying that data needs to be updated. Since there will be only one screen displayed at one time, I will now need to go check if the screen affected by the data is currently initialized and update the screen. I think checking which screen uses a piece of data and checking if that screen is active and then changing the appropriate visual component, for each piece of data will be moronic.
So when I initialize a screen I will just bind (with data binding) all of it's controls to my global state. This feels perfect since I will have some services impacting my state with their own controller, and the changes will be handled the same as a ui event changing the data. This is also great since my data layer will need to propegate to rather (for me) complex databases, so keeping the data layer clean will help.
My questions:
Am I managing my screens properly? Is it a good solution to slow performing winforms software?
Should I use data binding to achieve this? In this case it will be my sole source of view data, and I've read that data binding should be used in moderation. What am I missing.
I'm quite green and this job is my first C# bout. Although I have done java and flutter/dart before.
Also if there is a better place to ask these types of questions, I would appreciate a point in the right direction. There isn't any/other/senior/superior software engineers at work who I can ask these types of questions.

Working with relatively complex software, communicating over ethernet with hardware devices here.
I prefer having many many small windows that save their position when closed and restore their previous position when opened so that users can arrange them as needed.
Since I work with relatively slowly updating data, I periodically keep updating the data in the controls, unless they are focused (eg. potentially currently being edited).
Sure, with this, the data might be inconsistent sometimes, but no one will notice in the 50ms timeframe until the next update.
Since this is done for practically all my controls, the logic can also be centralized beautifully.
This, of course, goes against the binding paradigm but it's my development style which also works well for other programming languages.

Related

Keeping UserControl in memory

My application is a window with a main grid which will contain my pages (the User Controls).
I want to be able to navigate in the history of the previous user controls displayed.
That's why I'm storing in the memory the last 30 user control displayed. My code looks like this when displaying a new UC :
MyHistoryPage page = new MyHistoryPage();
page.AssociatedUC = (UserControl)this.mainGrid.Children[0];
this.mainGrid.Children.Clear();
this.mainGrid.Children.Add(new MyCustomUC());
All my "MyHistoryPage" are stored in a static list.
This works great, I'm able to get the previous Ucs in the same state (same sort, same checkboxes checked, same scroll, same tab selected etc.) and give the user a good experience.
However it seems to cause memory leaks or at least it seems to slow down my application. The mouse over effects are becoming slower and slower.
Dot Memory obviously tells me that the memory used has become bigger.
Is it good to store a lot of UI components in the memory to use them later ? What would be a better solution to manage history and have my UCs in the same state ?
What about trying to migrate your application to a MVVM pattern?
The ViewModels are not recreated everytime you access to a previous userControl, so the state could be the same and you will not have memory issues.
If you are not used to work with this pattern you can use many of the available toolkits to start like MVVM Light, Caliburn.Micro, ...

Create Single Window Navigation in WPF

I want to create a kiosk mode application using WPF. I want to use a single window because the user should not be able to exit this fullscreen application.
The application should guide the user trough a process. When the user proceeds trough the process, the screen should constantly change and show him the next step.
Usually I just create a single window and use a "state machine" to switch UserControls containing the information for the current step. Is there a better way to achieve this functionality? Maybe I would get a better result using multiple windows or Pages (never used them).
The reason why I am asking is that in future I want to have a simple, clean way of switching the content inside a single window. i.e. I am planning to implement some sort of animation when switching content (like sliding to the next / previous step). I don't want to put more effort into my current approach if it isn't the most flexible and clean one.
Any ideas?
PS: This is about desktop applications. Today I come from the Winforms environment and am experimenting with WPF.
There's a few ways you can achieve this.
First would be to use a Page based application, this will allow you to use a single window. Here is a pretty interesting tutorial
A bonus of using this approach is that navigation between pages is built in.
Your requirements are that you need to use animation for transitioning between pages, as far as I'm aware, using a Page based application cannot achieve this (I may be wrong). So your other option would be to use a UserControl MVVM approach.
This probably won't make a lot of sense now, but here goes:
You can use a single master view model which will hold multiple child view models, each of these could have a visibility property which dictates the visibility of the associated view. The master view model would simply be responsible for displaying the appropriate view model depending on where the user currently is in the application.
Using some clever XAML, you can create storyboards (animations) when the view becomes visible, which will allow you to achieve the crazy awesome animations that you require.
Anyway, that probably didn't make any sense, so here's a tutorial to get you started with MVVM.

Kind of live debugging possible? (Especially UI manipulation)

I would like to know if there is a way to manipulate an App's UI live while running?
I am not a designer and I have many problems sometimes regarding matching colours etc.
The next problem is that anytime I would like to change e.g. the colour of a control I have to quit the App then go to VS2012, apply my changes, build and execute it again to see simple changes.
I know that I see any changes in the designer but I have to see the resulting screen to get an impression of the whole.
Is there a way to achieve this?
Add a secret keypress while Debug flag is set, that raises a form and allows you to select controls and expose a property sheet for them. Be a bit of work to get right, and a good stick of code even using reflection. Might be better off with a storyboard type app to do your designing.
Unlike styles in WPF which can be dynamically adjusted (which made this type of run-time adjustment simple), there isn't as elegant of a solution for Windows Store apps. Ideally, you'd have all of your UI and colors, etc. defined in XAML files and not settable through other means (as it becomes a longer term maintenance issue).
I'd suggest just adding enough test data and configuration so that you can see the look and feel of the pages (with colors, etc.) at design-time. Blend and Visual Studio are now quite good at showing a very reasonable near final rendering of the elements of the application. It's generally not too difficult to do anymore.
One thing I've done in the past was to make a single page/form that contained all of the styles and controls in a large scroll viewer. Then, we set it so it was configurable to the be the first thing to run. The tweak/build cycle was pretty fast, and the results were still very manageable.

How to change into different sections of your application easily

Im currently trying to create an application that will require 10+ different "pages" with different content and controls, and i need to switch back and forth between them on particular events.
What ive been doing, is just creating all the different sections in grids, and setting their visibility to collapsed, and then when i need to show them, just switch out the visible grid to the new one.
This has several drawbacks, im assuming its very poor from a coding standpoint, and this pretty much dis-allows me from using the designer at all. (i have no idea what performance implications it has, either)
on top of that, every time i switch to the new page, i need to reset all the components (textbox's etc) to their default states, as they dont get reset by becoming invisible :P
on to my question: i need a way to map out all the different pages, provide visually attractive transitions between them, and be able to use a designer to create them (and i dont mean designing it somewhere and then just copying the xaml)
I had looked around, and ran into SketchFlow and it seemed like the perfect solution, i could fade between pages and map everything on a flow chart easily, and then i realized it was only for app prototypes and i couldnt actually compile it as a normal application... and i needed to inherit from a custom Window class aswell.
is there something out there that allows me to do this? or how can i code this to work properly?
note: this ABSOLUTELY needs to stay within one window. i cant venture out into having 10+ different windows that pop up every time i need to change to something. as this happens very frequently
Split the separate sections in individual user controls. This would allow you to design each of them easily. Then on your form use code to create and load a new instance of particular user control that represents the section you need to show, and when transitioning, load the new section and unload the current. this would allow your form to stay relatively lightweight.
An alternative is to create a navigation application and split your sections into separate XAML view and use the standard navigation service to switch between them.
WPF Navigation Overview
Creating Navigation Applications video tutorial
You might wanna convert your "Pages" to usercontrols and use some transitions like mentioned in the below link to switch between controls
http://www.tanguay.info/web/index.php?pg=codeExamples&id=280
for more on using transitions look here
http://www.japf.fr/2009/04/adding-transitions-to-a-mvvm-based-dialog/
or
http://www.japf.fr/2008/07/8/comment-page-1/

GDI handles with icons . l

i have a winforms application. i have a user control with a lot of icons. the user can load this control on a form many times (in a tabbed layout). right now i am loading the icons each time the control is created (could be up to 50 times in teh app). is there any way to cache these icons in the application. if i did this, would that decrease the number of gdi handles that i am using as this is becoming an issue.
You can make a singleton class for each icon. The first reference it creates the handle. Subsequent calls uses the existing handle.
Without knowing more about your user control my next suggestion can be only be very general. But you could have a single bitmap layer on which you draw all your icons. The remaining elements of your user control would exists above and around this bitmap.
Unfortunately this idea may be problematic performance wise. Require you to refactor the code you all ready use for arranging icons. Finally it is non-institutive from how frameworks with a control-form structure ideally works.
We ran into a resource problem with entry forms for the parameteric shape we ship with our CAM software. Too many text entries caused various forms of strangeness and leaks. So we instead created labels with borders that looked like text entries and had ONE text entry (and a combo box entry too). When the user tabs, enters, or clicked the single text entry moved to the new entry and the label was setup for the previous entry.
This is totally a non-intuitive setup than how you would normally code this but it was the only way to deal with our resource problem.
In my experience it seems that GUI Frameworks have issues when you have to deal with dozens or hundreds of entries and that you have to approach the problem using a different design.
If the issue is the number of "icons" (not sure what you mean here) you can use Image-Lists. For example, a Listview control can reference icons in an image-list, instead of keeping a full copy for each item (not sure if this applies to your case though).

Categories