Imagine we have:
1) some parent MainForm;
2) some child NewItemForm (called often).
What I think is: why would I use new NewItemForm() every time I need the form if I could create it once and set it's Visible property to true/false after on need (clearing the previous input ofc).
What I would want to know: personally I did not notice any difference however my sketchy knowledges tell me there should be some (memory allocation, controls initialization); support me please with your skill in
my doubts.
If the child controls are more or some third party controls pasted on the Winforms then it will take some seconds to load/initialize the form. If there is no control pasted or only .net controls then it is okay. Otherwise it will have performance issue while painting hide and show.
I know this may seem like an odd question, but I am after the information queried in the title.
So far I have tried LayoutRoot.Loaded, but found that LayoutRoot.LayoutUpdated happens even later.
My motivation for this knowledge is the ability to have one component interact with another in code, but for this to happen I must be guaranteed they both exist.
Any ideas?
Clarification of what I'm attempting to do:
I have a collapsing gridsplitter control. From here
When the main page loads I make it collapse; which shrinks the object preceding it to width 0. If that object isn't 'loaded' yet then it doesn't collapse and the gridsplitter is in an odd state where it thinks it has collapsed the item but needs two clicks to effectively do that.
LayoutUpdated is the last event raised in the control object initialization timeline. However keep in mind that LayoutUpdated will be raised multiple time subsequently as required. Maybe you can share a little more detail on what you are trying to do.
A Windows Form is a type of Control, and Controls are UI elements that have a Size property along with size-related methods such as OnResize and OnSizeChanged.
But Forms also have OnResizeBegin (and OnResizeEnd), which are not found in Control. Is this omission an oversight, a prescient design decision, or something else entirely?
OnResizeBegin event is raised when form size is changed by user, not by programmaticaly changing Form properties (like Size). Most of controls can't be sized in such way, so it hasn't OnResizeBegin event.
When you add something to a base class like Control that has such a huge number of descendents, it's going to get inherited by everything whether it makes sense or not (e.g. would many programmers care that a radio button is starting to get resized?). Every method, property and event you add makes an API that much more complicated.
Now there are plenty of other examples of things in Control that don't make sense for every child (e.g. a Leave event on a Label control), but that's part of the contradictory morass that is Forms. The attached property system used in WPF is much more elegant.
I've got a list of UserControl objects; when a menu option is clicked to go to another section of the application it does the following:
Set the currently displayed usercontrol to visible
Clear the main panel's Controls list
New up the requested control (if not already created in the list)
Add the new control to the main panels' Controls list
Dock the new control to fill
Set the new control to visible
I did this because, previously all of the areas of the application were not user controls and they were just collections of controls in a TabControl. The underlying code was monstrous (the code in frmMain was 13000+ lines).
It works well. All controls (what each tab page would have been before) manage their own behaviour, each control has a small code footprint. I can have a sexy menu. All good things.
However, obviously there's a problem. Before, the tabcontrol would load on startup, and all tabs would render (but weren't seen). One tab page in particular has a scheduling control on it and it takes a good 3-4 seconds to draw and adjust its layout. Now that controls are loaded and shown as they're needed, the first time you view this particular control, you see it load and adjust its size/formatting/etc. Which is hardly esthetically pleasing.
My question is, how can I load and render this control so that it'll render and figure out its layout, but without it actually showing the user?
I've tried simple things like:
ScheduleWindow scheduler = new ScheduleWindow() { Visible = false; }
mainPanel.Controls.Add(scheduler);
scheduler.Visible = true;
I've tried creating and loading the control on its own thread (with numerous difficulties) and it still didn't do anything...
Is there any way to achieve what I'm looking for?
Try using the SuspendLayout() and ResumeLayout() methods on the main form? When you call SuspendLayout(), you can do whatever you need to do with the controls you are adding, such as docking, resizing, etc. When you call ResumeLayout(), all changes will be applied at once, and should happen instantaneously.
Alternatively, some controls have a BeginUpdate() and EndUpdate() method, which suspend redraws for that control, allowing you to do heavy work (such as adding thousands of items to a ListView) without seeing the updates happen live. This also improves performance, as rather than redrawing every time the control is changed, you batch changes, then redraw once.
Try calling scheduler.Handle.ToString() and/or scheduler.Refresh().
In my application I have a DataGridView control that displays data for the selected object. When I select a different object (in a combobox above), I need to update the grid. Unfortunately different objects have completely different data, even different columns, so I need to clear all the existing data and columns, create new columns and add all the rows. When this is done, the whole control flickers horribly and it takes ages. Is there a generic way to get the control in an update state so it doesn't repaint itself, and then repaint it after I finish all the updates?
It is certainly possible with TreeViews:
myTreeView.BeginUpdate();
try
{
//do the updates
}
finally
{
myTreeView.EndUpdate();
}
Is there a generic way to do this with other controls, DataGridView in particular?
UPDATE: Sorry, I am not sure I was clear enough. I see the "flickering", because after single edit the control gets repainted on the screen, so you can see the scroll bar shrinking, etc.
People seem to forget a simple fix for this:
Object.Visible = false;
//do update work
Object.Visible = true;
I know it seems weird, but that works. When the object is not visible, it won't redraw itself. You still, however, need to do the begin and end update.
The .NET control supports the SuspendLayout and ResumeLayout methods. Pick the appropriate parent control (i.e. the control that hosts the controls you want to populate) and do something like the following:
this.SuspendLayout();
// Do something interesting.
this.ResumeLayout();
Double buffering won't help here since that only double buffers paint operations, the flickering the OP is seeing is the result of multiple paint operations:
Clear control contents -> repaint
Clear columns -> repaint
Populate new columns -> repaint
Add rows -> repaint
so that's four repaints to update the control, hence the flicker. Unfortunately, not all the standard controls have the BeginUpdate/EndUpdate which would remove all the repaint calls until the EndUpdate is called. Here's what you can do:
Have a different control for each data set and Show/Hide the controls,
Remove the control from its parent, update and then add the control again,
Write your own control.
Options 1 and 2 would still flicker a bit.
On the .Net GUI program I'm working on, I created a set of custom controls that eliminated all flicker.
Rather than adding the rows of the data grid one at a time, use the DataGridView.Rows.AddRange method to add all the rows at once. That should only update the display once. There's also a DataGridView.Columns.AddRange to do the same for the columns.
This worked for me.
http://www.syncfusion.com/faq/windowsforms/search/558.aspx
Basically it involves deriving from the desired control and setting the following styles.
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.DoubleBuffer, true);
Sounds like you want double-buffering:
http://www.codeproject.com/KB/graphics/DoubleBuffering.aspx
Although this is mainly used for individual controls, you can implement this in your Windows Forms control or Form.
Unfortunatly, I think that thins might just be a by-product of the .net framework. I am experiencing similar flickering albeit with custom controls. Many of the reference material I have read indicates this, alongside the fact the the double buffering method failed to remove any flickering for me.
You may also try this, its work.
public static void DoubleBuffered(Control formControl, bool setting)
{
Type conType = formControl.GetType();
PropertyInfo pi = conType.GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic);
pi.SetValue(formControl, setting, null);
}