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, ...
Related
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.
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/
I have a form that contains a lot of runtime generated controls (image, button, panel,...), about 100 controls (I'm making a card matching game so there is a lot of controls in the form).
I place the generating code into the constructor and each time the app starts, it took about 3-5s to load all the controls completely.
If I bring another window on top and then back to my app, the controls will be redrawn again.
How can I prevent the controls from being redrawn? If you don't mind, please give me a simple example in C#.
Any help is appreciated!
I found this article that explains how to do this in .NET by calling the WIN API SET_MESSAGE function to set the WM_SETREDRAW flag for the control you do not want updated. Although you can stop certain controls from updating, are you sure you can't approach this issue by reducing the number of controls on the page? 100 Controls seems like a lot and may be an indication that you need to have multiple views.
Enjoy!
My suggestion is to use the form as a drawing surface and draw your card bitmaps directly onto the form. Its not hard to do.
You can add a handler to the form Paint event which will give you parameters with a Graphics object. Use graphics.DrawImageUnscaled to draw each card at the location you want.
This will make the app much much faster.
Preventing a control from redrawing is fairly pointless. You'll get a hole where a control was supposed to appear, your user won't have any use for that hole.
It redraws slowly simply because you have too many controls. You can only get it to redraw faster by using less controls. Or by using controls that can display multiple items in one window, like ListBox, ListView, TreeView, DataGridView.
Note that your specific issue is fixed in Vista and Windows 7. The Aero theme uses off-screen buffering for windows. Which means that windows don't need to repaint themselves anymore when they are obscured by another window. You will however still get slow redraws when the user minimizes the window and restores it.
You might want to consider using a single data table control. A ListView (or something like ObjectListView) may be a good option.
If your data isn't really a list/table, you should split the controls into separate tab pages, which would improve both performance and usability.
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).
I've a form and I'm doing databinding of my datagridview in the event "form load", the problem is, that the form takes a little (or a lot depends on the size of information) to load, because my data has a lot of binary information (photos) to binding there.
In some sites, we can see a picture saying "loading", which is cool and is good to the user, because I knows that is loading and not stoped. So, I wanted to simulate something like that to desktop application when I'm doing databinding to the table, can you help me?
You can't do much about the actual binding itself, since forms have thread affinity. However, you can load the data (from the database or where-ever) on a separate thread - look at BackgroundWorker, for example.
If the db-load is fast, but the binding is slow, you can look at things like "virtual mode" that exists for many standard list-based controls. This can reduce the time taken to bind by only looking at the immediately visible data.
Other than that, you can do things like changing the cursor, showing a splash on another thread, etc. It really depends where the time is being spent (have you profiled?).
You could show the 'loading' form in a different thread.
Also consider hard whether you need all of the data loaded with the form - could any of this data be loaded after the form load?
Try and give your application a feeling of perceived speed.
Sometimes is not our decision to load the data after a user action. My client wants the data loaded without user action.
Thanks you for your answers :)