performance in C# Application - winforms

i use some pictures in my 'MainForm' And My Windows Application was writing by c sharp.
i use this form to start other forms in my project.
And I use some label and panel with Transparent Color.
but when the program started i see many blink in transparent label and panel.
And it is very bad.
How I Can Fix this problem?

Enabling DoubleBuffered as stax suggested above is helpful but it may not be sufficient.
In your form, add the following method override:
protected override void OnPaintBackground(PaintEventArgs e) {}
And, in the OnPaint method, paint the background yourself instead. If you don't do this, drawing the background and painting are separate events, and background painting has higher priority, meaning that it will happen earlier.
Furthermore, if you add child controls (like labels), they receive their own paint background/paint events. You may be able to disable the Label's background. If I do stuff like this, I tend to not use controls but paint the text and the images in one OnPaint.

did you test it on multiple machines.
did you use an updated machine with all the .net service packs needed.
etc

Related

MFC: how to render an Aero-style combo box for owner draw?

I have inherited a large MFC application which contains a CComboBox subclass that overrides OnPaint. Currently it does all its drawing by hand (with lines and rectangles), and renders a combo box that looks decidedly Windows 98-style. However, it otherwise works great and provides a lot of useful custom functionality that we rely on, and rewriting the entire control is probably not an option.
I would like to modernize it so that the OnPaint draws in Aero style where available (falling back to the old code when modern theming is unavailable). I've done this with some other custom controls we have, like buttons, and it works great for our purposes. I know there are some tiny behaviors that it won't get right, like gentle highlights on mouse-hover, but that's not a big deal for this app.
I have access to the CVisualStylesXP ckass, so I've already got the infrastructure to make calls like OpenThemeData, GetThemeColor or DrawThemeBackground pretty easily (via LoadLibrary so we don't force Vista as a min-system). Unfortunately, I don't know the proper sequence of calls to get a nice looking combo box with the theme-appropriate border and drop-down button.
Anyone know what to do here?
Honestly, I don't know why they originally tried to override OnPaint. Is there a good reason? I'm thinking that at least 99% of the time you are just going to want to override the drawing of the items in the ComboBox. For that, you can override DrawItem, MeasureItem, and CompareItem in a derived combo box to get the functionality you want. In that case, the OS will draw the non-user content specific to each OS correctly.
I think you best shot without diving in the depth of xp theming and various system metrics is take a look at this project: http://www.codeproject.com/Articles/2584/AdvComboBox-Version-2-1
Check the OnPaint of the CAdvComboBox class - there is a full implementation of the control repainting including xp theme related issues.
Not sure if it's the same situation - but when I faced this problem (in my case with subclassed CButtons), solving it only required changing the control declaration to a pointer and creating the control dynamically.
Let's assume that your subclassed control is called CComboBoxExt.
Where you had
CComboBoxExt m_cComboBoxExt;
You'll now have
CComboBoxExt* m_pcComboBoxExt;
And on the OnInitDialog of the window where the control is placed, you create it using
m_pcComboBoxExt = new CComboBoxExt();
m_pcComboBoxExt->Create(...)
Since this is now a pointer, don't forget to call DestroyWindow() and delete the pointer on termination.
This solved my particular problem - if your control is declared in the same way, consider giving it a try.

Painting in a custom control and the invalidate mechanism

A custom control I am creating needs to draw many "items" in its client space. A call to Invalidate() would trigger a new paint cycle wherein all items would be redrawn.
Now when there are many items and a lot of navigation happens within the control, things need to be optimized; so I need to trigger a paint cycle where only one or two items are drawn. I store references to these items so that the paint method (OnPaint) knows it's a "quicky".
The difficulty is that when OnPaint is executed, it is hard to know if other Invalidate() calls have been made in the meantime. In that case it should do a "normal", complete paint.
I do make use of the clip rectangle. Of course I could check if the clip rectangle in OnPaint has become the whole of the client rectangle, a sign that Invalidate() was called, but this is not 100% safe. I thought of other similar solutions but they seem hacky.
What is the way this problem is usually, or best, solved?
The solution here would be to employ a double buffering approach with the BufferedGraphics class. This way you won't have so much tricky stuff going on in your OnPaint and you'll be able to paint whenever, whatever.
MSDN: Double Buffered Graphics (under "Manually Managing Buffered Graphics")
Here's a useful example:
Custom Drawing Controls in C# – Manual Double Buffering

Window transparency in WPF vs Winforms

Why is it that I have to set the WindowStyle property to None on a WPF form to get transparency, but in Winforms I can do it on any form, and retain borders, standard buttons, etc? Clearly the API supports this, so I'm not clear on what's special about WPF that would make this an issue.
I'm guessing that WPF is jumping through some DirectX or OpenGL hoops, while Winforms is just setting the alpha for the window via the API, but I could be way off base.
Agreed, this is heavy handed:
private void VerifyConsistencyWithAllowsTransparency(WindowStyle style)
{
if (AllowsTransparency && style != WindowStyle.None)
{
throw new InvalidOperationException(SR.Get(SRID.MustUseWindowStyleNone));
}
}
WPF uses the exact same mechanism to implement this as Windows Forms, layered windows. There is no obvious reason it wouldn't work the same way in WPF. The code snippet, lifted from Window.cs, simply rules it out. There is however one hint from the UsesPerPixelOpacity property:
When you enable per-pixel opacity, the system no longer draws the non-client area. This is because the intended purpose of UsesPerPixelOpacity is to show non-rectangular top-level UI that works in interoperation scenarios, and showing the rectangular non-client area defeats that purpose.
"interoperation scenarios", I guess.

Display an Adorner over a WebBrowser control

I'm using the System.Windows.Controls.WebBrowser for various things in my app and I've noticed that adorners are cut off when they are supposed to appear over a WebBrowser. I realize that the WebBrowser control is really a wrapper around a COM component and probably renders differently, but I wondered if anyone figured out how to solve this.
This is the problem I'm seeing. Here I have just a sample adorner that is supposed to draw a big red circle in the top corner of something (as a sample).
When I adorn the WebBrowser with this, I get this result:
I expect to see the full circle.
Here's the code for this worthless adorner, in case that is helpful:
public class SillyAdorner : Adorner
{
public SillyAdorner(UIElement element) : base(element)
{
}
protected override void OnRender(DrawingContext drawingContext)
{
drawingContext.DrawEllipse(new SolidColorBrush(Colors.Red), new Pen(), new Point(7, 7), 30, 30);
base.OnRender(drawingContext);
}
}
And here is how I apply it to the browser in the OnRender method of the host control:
protected override void OnRender(DrawingContext drawingContext)
{
base.OnRender(drawingContext);
var layer = AdornerLayer.GetAdornerLayer(browser);
layer.Add(new SillyAdorner(browser));
}
Anyone have any hacks or workarounds for this?
Edit: I'm using .NET 4.0, if that makes a difference.
Edit #2: WebBrowser appears to inherit from HwndHost, which I've seen another question or two regarding adorners and hwndsources, but I'm not seeing anything that looks like I could implement it for the WebControl, but hopefully this is useful information for someone.
I don't think that will work with an Adroner, but you can float content over a WebBroswer control using a transparent Popup control. More details and a code sample can be found here.
Here's my blog post introducing a library I wrote for layering a WPF adorner over any hwnd. A simple web browser demo looks like this:
This is caused by airspace issues. Since a WebBrowser is a native, non-WPF control, there is no way to directly render adorners (or other WPF content) on top of it.
In order to do this, you need to use a separate window of some sort, and put the content into that separate window. This typically means using a transparent WPF window layered over the top of your main window. Unfortunately, this will not be as integrated of a solution as a true native WPF control would provide.
Try use another transparent TOP LEVEL overlay window. Only supported on Windows 2000 or higher of course, Win9x does not have layered windows.

WinForms floating windows (like Delphi7 IDE)

I want to setup my WinForm to look like the Delphi7 IDE. Basically that means the window has no background (the desktop shows through), and child windows float around.
Here's a sample image:
I can handle the floating windows, but how would I go for the main window (the menu bar and the toolbar)? What are the WinForm properties required to get this layout? I can't seem to be able to get rid of the window's client area.
Thank you
Why can't you get rid of the client area? Just resize the main form so that it's as thin as you can make it.
You may be implementing the floating windows as UserControls in the main form's Controls collection. If so, there are two ways you can deal with this:
Implement the floating windows as actual windows. Show them using "frmToolWindows.Show(this);" (this will keep them always on top of your main form).
If you need to keep the floaters as UserControls, you can make the client area of your main form transparent by setting the form's TransparencyKey property to some arbitrary color (Color.Red, for example) and then setting the form's BackColor property to the same color. This will make your form transparent and able to be clicked through.
Please don't make a UI like this. It is very non-standard, and doesn't gain anything in the realm of usability. You could simplify things by keeping it all in one window like Visual Studio.

Resources