Is it possible for us to turn WS_EX_COMPOSITED on ONLY when a Panel/Container Control is being scrolled, then turning it off? Having it activated for the whole lifespan of the application, affects every controls surrounding my application, I only need it activated when the Panel it's being scrolled.
Something like that:
private int originalExStyle = -1;
private bool _scrolling = false;
protected override CreateParams CreateParams
{
get
{
if (originalExStyle == -1)
originalExStyle = base.CreateParams.ExStyle;
CreateParams cp = base.CreateParams;
if (_scrolling)
cp.ExStyle |= 0x02000000; // Turn on
else
cp.ExStyle = originalExStyle; // Reset to original state
return cp;
}
}
protected override void OnScrollBegin(ScrollEventArgs se)
{
base.OnScrollBegin(se);
_scrolling = true;
RecreateHandle();
}
protected override void OnScrollEnd(ScrollEventArgs se)
{
base.OnScrollEnd(se);
_scrolling = false;
RecreateHandle();
}
Related
When I resize the Winform UI (which has lot of child controls), flickering happens.
I used the below code, which is not working for Resize.
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.Style &= ~0x02000000;// Turn off WS_CLIPCHILDREN
return cp;
}
}
Create a Panel which will be the root of all children in your Form, and in your Form.OnResizeBegin() method, call Control.SuspendLayout(); in Form.OnResizeEnd(), call Control.ResumeLayout().
class MainForm: Form {
public MainForm()
{
this.Build();
}
void Build()
{
this.root = new Panel { Dock = DockStyle.Fill };
// create all controls and add them to root
this.Controls.Add( root );
this.ResizeBegin += (obj, args) => this.OnResizeBegin();
this.ResizeEnd += (obj, args) => this.OnResizeEnd();
}
void OnResizeBegin()
{
this.root.SuspendLayout();
}
void OnResizeEnd()
{
this.root.ResumeLayout( true );
}
Panel root;
}
Hope this helps.
I think you should change the ExStyle not the Style to get the double buffered effect
Also you should use |= in stead of &=
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000; // turn on WS_EX_COMPOSITED
return cp;
}
}
If there are still parts on your form that keep flickering then maybe this post can help
I overrided a form(System.Windows.Forms.Form and I will call it Form0)'s CreateParams property like this
protected override CreateParams CreateParams
{
get
{
CreateParams _CreateParams = base.CreateParams;
_CreateParams.ExStyle |= (WS_EX_NOACTIVATE | WS_EX_TOOLWINDOW);
_CreateParams.Parent = IntPtr.Zero;
return _CreateParams;
}
}
This window should not be able to be activated(WS_EX_NOACTIVATE) and have no icon shown in the taskbar(WS_EX_TOOLWINDOW).
It works WELL when I use
Application.Run(new Form0());
But it doesn't work as what I expected when I use
Form0.Show()
I want to know why and how to make it take effect while using Show().
You should disable the WS_EX_APPWINDOW style of your window. You don't need to add the WS_EX_TOOLWINDOW. WS_EX_NOACTIVATE takes care of it by default:
protected override CreateParams CreateParams
{
get
{
CreateParams _CreateParams = base.CreateParams;
_CreateParams.ExStyle |= WS_EX_NOACTIVATE;
_CreateParams.ExStyle &= (~WS_EX_APPWINDOW); //<----
_CreateParams.Parent = IntPtr.Zero;
return _CreateParams;
}
}
In my WinForm Application, I am needing to layer some images. However, I'm having trouble getting a transparent control to place the image in. I have done some research and came up with the following class:
public class TransparentPicture : PictureBox
{
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x20;
return cp;
}
}
protected override void OnPaintBackground(PaintEventArgs e)
{
// do nothing
}
protected override void OnMove(EventArgs e)
{
RecreateHandle();
}
}
This seems to work fine until I close Visual Studios and reopen the Solution. Then my controls all disappear in the designer. They show when I run the program, but I need them to show in designer too where I can continue to design my application.
I know this isn't everything I need to do, because these controls are always causing my program to freeze up for a few seconds and stuff.
So my question is..does anybody know where I can find code for a transparent control, or how to fix the one I've thrown together?
Make the TransparentPicture be a regular PictureBox, until an IsTransparent property is set to true.
Set the property to false on design time, and to true in FormLoad event (which will only happen when you actually run the application).
That way, on design time, they will behave as regular picture boxes, but when you run the application, they will become transparent.
public class TransparentPicture : PictureBox
{
public bool IsTransparent { get; set; }
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
if (this.IsTransparent)
{
cp.ExStyle |= 0x20;
}
return cp;
}
}
protected override void OnPaintBackground(PaintEventArgs e)
{
if (!this.IsTransparent)
{
base.OnPaintBackground(e);
}
}
protected override void OnMove(EventArgs e)
{
if (this.IsTransparent)
{
RecreateHandle();
}
else
{
base.OnMove(e);
}
}
}
Then, on your FormLoad event, you should do:
for (var i = 0; i < this.Controls.Count; i++)
{
var tp = this.Controls[i] as TransparentPicture;
if (tp != null)
{
tp.IsTransparent = true;
}
}
Or if you only have a few:
tp1.IsTransparent = tp2.IsTransparent = tp3.IsTransparent = true;
I've created a transparent label control and the transparency works great. However, I find when I update the control's Text field, the original Text doesn't clear before it paints the new text. So if I change the control's Text field several times, it soon becomes unreadable.
Any clues? Thanks!
public partial class TransLabel : Label
{
public TransLabel()
{
InitializeComponent();
this.SetStyle(ControlStyles.Opaque, true);
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, false);
this.Font = new Font("Franklin Gothic Book", 12f, FontStyle.Regular);
this.ForeColor = Color.White;
this.BackColor = Color.Transparent;
}
public override string Text
{
get
{
return base.Text;
}
set
{
base.Text = value;
this.Invalidate(); // seems to have no effect
this.Refresh(); // seems to have no effect
}
}
protected override void OnPaintBackground(PaintEventArgs pevent)
{
//do nothing
}
protected override void OnMove(EventArgs e)
{
RecreateHandle();
}
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle = 0x00000020; //WS_EX_TRANSPARENT
return cp;
}
}
}
Try changing your Text property to this:
public override string Text {
get {
return base.Text;
}
set {
base.Text = value;
if (this.Parent != null)
this.Parent.Invalidate(this.Bounds, false);
}
}
Since WinForms doesn't have true support for transparency, I think you have to invalidate the parent container.
Also, when inheriting a control, you usually don't have an InitializeComponent() method.
I am creating some always-on-top toasts as forms and when I open them I'd like them not to take away focus from other forms as they open. How can I do this?
Thanks
protected override bool ShowWithoutActivation
{
get
{
return true;
}
}
Override this property in your form code and it should do the trick for you.
It took me a few minutes using Adam's & Aaron's info above, but I finally got it to work for me. The one thing I had to do was make sure the form's Top Most property is set to false. Here is the code I used...
protected override bool ShowWithoutActivation { get { return true; } }
protected override CreateParams CreateParams
{
get
{
//make sure Top Most property on form is set to false
//otherwise this doesn't work
int WS_EX_TOPMOST = 0x00000008;
CreateParams cp = base.CreateParams;
cp.ExStyle |= WS_EX_TOPMOST;
return cp;
}
}