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).
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.
I have an application for the windows store that I need to make emulate the tabs like Internet Explorer. The problem is that I have one control and it won't load into both the AppBar and the main view.
Is there a way to setup the CacheMode in the constructor of the control and then pull a bitmap from the BitmapCache and load that in the tab view in the AppBar? Or am I going about this the wrong way. I don't want to use two different controls due to it being a hack I want this to work with one control.
I am writing this application in C# and XAML.
Any help is appreciated.
A control can only have one parent in all popular XAML technologies, so you can't put it in two places.
You can use RenderTargetBitmap to take a screenshot of a control and put it elsewhere in your layout, but there are plenty of problems with that
It uses additional memory to store the bitmap
You need to figure out when to take that screenshot - typically after all images load and after every layout or content update.
A bitmap is not interactive.
Your best bet might really be to have two copies of the same control. You can create a UserControl to encapsulate any functionality and properties and reuse that control in multiple places easily. If you reference an image by URI - the platform should automatically share the resources for the image used in multiple controls.
I got to a point where it's very difficult to get answers by debugging and tracing objects, so i need some help.
What I'm trying to do:
A history form for my screen capture pet project. The history must list all images as thumbnails (ex: picasa).
What I've done:
I created a HistoryItem:UserControl.
This history item has a few buttons, a check box, a label and a picture box. The buttons are for delete/edit/copy image. The check box is used for selecting one or more images and the label is for some info text. The picture box is getting the image from a public property that is a path and a method creates a proportional thumbnail to display it when the control has been loaded. This user control has two public events. One for deleting the image and one for bubbling the events for mouse enter and mouse leave trough all controls. For this I use EventBroadcastProvider. The bubbling is useful because wherever I move the mouse over the control, the buttons appear. The dispose method has been extended and I manually remove the events.
All images are loaded by looping a xml file that contains the path of all images. For each image in this XML I create a new HitoryItem that is added (after a little coding to sort and limit the amount of images loaded) to a flow layout panel.
The problem:
When I lunch the history form, and the flow layout panel is populated with my HistoryItem custom control, my memory usage increases drastically.From 14Mb to around 100MB with 100 images loaded. By closing the history form and disposing whatever I could dispose and even trying to call GC.Collect() the memory increase remain. I search for any object that could not be disposed properly like an image or event but wherever I used them they are disposed. The problem seams to be from multiple sources. One is that the events for bubbling are not disposing properly, and the other is from the picture box itself. All of this i could see by commenting all the code to a limited version when only the custom control without any image processing and even events is loaded. Without the events the memory consumption is reduced by axiomatically 20%.
So my real question is if this logic, flow layout panels and custom controls with picture boxes, is the best solution for displaying large amounts of images as thumbnails.
Thank you!
I have once done exactly this and it is terrible when it comes to memory management. For example, you are risking growing number GDI handles (e.g. if every control creates Font or other GDI object instance) and this problem cannot be solved with GC.Collect().
I work for ComponentOwl.com and we have developed a control for managing image thumbnails called Better Thumbnail Browser which can do also loading, resizing and caching thumbnails for you:
They have also a free component called Better ListView Express, which still have great support for image thumbnails.
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.