How can I make my window not have a title bar but appear in the task bar with some descriptive text?
If you set the Form's .Text property then .net gives it a title bar, which I don't want.
this.ControlBox = false;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.ShowInTaskbar = true;
this.Text = "My title for task bar";
I've found a partial solution, to override CreateParams:
protected override System.Windows.Forms.CreateParams CreateParams
{
get
{
System.Windows.Forms.CreateParams cp = base.CreateParams;
cp.Style &= ~0x00C00000; // WS_CAPTION
return cp;
}
}
However this causes my window to be resized as if they have a title bar, ie it's taller than it should be. Is there any good solution to this?
In my case I have a Form with FormBorderStyle = FormBorderStyle.SizableToolWindow and the following CreateParams override did the trick (i.e. I now have a form without caption and without additional margin for the title, but it keeps the title in the task bar):
protected override System.Windows.Forms.CreateParams CreateParams
{
get
{
var parms = base.CreateParams;
parms.Style &= ~0x00C00000; // remove WS_CAPTION
parms.Style |= 0x00040000; // include WS_SIZEBOX
return parms;
}
}
One approach to look into might be to set the FormBorderStyle property of your Form to None (instead of FixedDialog).
The drawback to this approach is that you lose the borders of your window as well as the Titlebar. A result of this is that you lose the form repositioning/resizing logic that you normally get "for free" with Windows Forms; you would need to deal with this by implementing your own form move/resize logic in the form's MouseDown and MouseMove event handlers.
I would also be interested to hear about better solutions.
Just set the border style to None.
this.FormBorderStyle = FormBorderStyle.None;
Once you have removed the borders with the FormBorderStyle, as mentioned already, you can make it draggable fairly easily. I describe this at http://www.blackwasp.co.uk/DraggableBorderless.aspx.
Related
I'm developing winform app with C#. And I created custom button inherent from UserControl as shown below:
public partial class UserButton : UserControl
{
public UserButton(string UserID)
{
this.Size = new Size(32, 50);
this.BackColor = Color.Transparent;
}
protected override void OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
Img = WaseelaMonitoring.Properties.Resources.T;
g.DrawImage(Img, 0, 0, this.Size.Width, this.Size.Height);
}
}
Note: this is button png image (Click here)
Now, I want to show some buttons on picture box using this code:
UserButton TagButton1 = new UserButton("Button1");
TagButton1.Location = Points[0];
UserButton TagButton2 = new UserButton("Button2");
TagButton2.Location = Points[1];
UserButton TagButton3 = new UserButton("Button3");
TagButton1.Location = Points[2];
Picturebox1.Controls.Add(TagButton1);
Picturebox1.Controls.Add(TagButton2);
Picturebox1.Controls.Add(TagButton2);
Picturebox1.Invalidate();
Okay, when show only one button on the picture box, the background button is transparent(as I want) like this:
But if I want to show two or more buttons beside together the background button is white not transparent like this:
I'm using invalidate picture box and trying invalidate button also, but is not solve that problem.
WinForms does not support true Z-ordering of components; windowed controls (such as Button and UserControl) cannot have true alpha-channel support, and the this.Background - Color.Transparent trick is actually a special-case where the control will re-paint its parent's Background image or color to itself first.
If you are after a more flexible user-experience, I suggest switching to WPF, or doing all of your painting within a single WinForms Control.
I solved this problem by added this line to initializing constructor:
SetStyle(ControlStyles.Opaque, true);
And overridden this function:
protected override CreateParams CreateParams
{
get
{
const int WS_EX_TRANSPARENT = 0x00000020;
CreateParams cp = base.CreateParams;
cp.ExStyle |= WS_EX_TRANSPARENT;
return cp;
}
}
I've created a simple program and now i'm in the stages of doing my designing. I've got a multiple Panels which i make visible / invisible to switch between "tabs" (EG. 1 panel for the login screen and 1 panel for the create account screen). Now i've made these panels invisible because i want them just as containers to be able to quickly move around controls and create buttons in.
My problem is that i've set my forms background image to a image i made in photoshop and whenever i switch between panels it flickers, whenever i just use a system color (white,black) this doesn't happen.
Is there any way for me to remove the flickering?
i've tried :
Setting double buffer to true
protected overrideing OnPaint, CreateBackground, and Createparam
my code is extremely basic :
private void btnNewAcc_Click(object sender, EventArgs e)
{
PanelNewAccount.Visible = true;
PanelLogin.Visible = false;
}
Try to setting the form property DoubleBuffered to true, in winforms the flickering usually happens because the GDI+ is trying to draw the control(s) a lot of times so DoubleBuffering you graphics should help in such cases
form.DoubleBuffered = true;
Thanks to Patrick i've solved my problem,
instead of using panels i'm using a TabControl and i assigned the same background to each tab.
Just as easy to add dynamic buttons as well.
Same features as panels but without the flickering.
#region .. Double Buffered function ..
public static void SetDoubleBuffered(System.Windows.Forms.Control c)
{
if (System.Windows.Forms.SystemInformation.TerminalServerSession)
return;
System.Reflection.PropertyInfo aProp = typeof(System.Windows.Forms.Control).GetProperty("DoubleBuffered", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
aProp.SetValue(c, true, null);
}
#endregion
#region .. code for Flucuring ..
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000;
return cp;
}
}
#endregion
Even though i am late but if somebody else is also suffering from the same problem then this code fixed the flickering for me even though i dont know how it works.
I found it here.
Add the above code snippet in your program and in the contructor of your app add this line:
SetDoubleBuffered(YourPanelName);
protected override CreateParams CreateParams {
get {
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000;
return cp;
}
}
code copy from codeproject solved my problem.
I'm developing an application and I want it to be full screen. As I want to change between different screens, I created a MDIParent and some MDIChilds. But when I say that I want to see it full screen I have this screen:
I have set properties to:
Form border style: None
Windows state: Maximized
And I have:
Maximize box: False
Minimize box: False
control box: False
for both MDIParent and MDIChild. But I still have that control box showing...
How can I hide it??
You may be able to do this by overriding the Control.CreateParams method.
Check out the Window styles that you can apply.
Also check out the Window Class Styles that you can apply.
For example (not answering your question but showing you how to change window styles):
protected override CreateParams CreateParams
{
get
{
CreateParams param = base.CreateParams;
const int CS_DROPSHADOW = 0x00020000;
const int WS_CAPTION = 0xC00000;
param.ClassStyle = param.ClassStyle | CS_DROPSHADOW; // Turn on window shadow.
param.Style = param.Style & ~WS_CAPTION; // Turn off caption.
return param;
}
}
This is a strange thing I'm doing, but how can I set the title of a winform form in the taskbar, but not in its titlebar?
A possible solution (it works fine for me) it's to override the CreateParams property and set the caption to be displayed in the taskbar:
protected override CreateParams CreateParams
{
get
{
new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
// Extend the CreateParams property of the Button class.
CreateParams cp = base.CreateParams;
// Update the button Style.
cp.Style &= ~0xC00000; //WS_CAPTION;
cp.Caption = PRODUCT_NAME;
return cp;
}
}
I hope that works for you,
Lisa
Okay, so my temporary work around is this:
At runtime/design-time, Clear the Text Property for the Form (Form1, or whatever form this applies to), and when the Minimize, or Hide() events are triggered, change the Text Property to display a Title. So, when the form is hidden or minimized, you won't be able to see the titlebar anyway, but you will be able to see the caption on the Taskbar! And when the Form is later maximized, or when the Form.WindowState == WindowState.Normal, then clear the Text Property again. :-)
I wonder if this is the approach MS took!?
Edit:
Okay, sweet, I've got some working code of yumminess:
If you're using Visual Studio, go to Design View, select the Form control, open the Properties Pane, click the Events Tab, then double-click the Resize event. The Code View should display. Inside the Resize() code that was just created, type this:
private void Form_Resize( object sender, System.EventArgs e )
{
if( this.WindowState == FormWindowState.Minimized )
this.Text "Some uber-awesome title.";
}
Step 2:
When you want to show/maximize the form again, simply edit the above so it looks like this:
private void Form_Resize( object sender, System.EventArgs e )
{
if( this.WindowState == FormWindowState.Minimized )
this.Text "Some uber-awesome title.";
else if(this.WindowState == FormWindowState.Normal || this.WindowState == FormWindowState.Maximized)
{
this.Text = String.Empty; // Or, you can use: this.Text = "";
}
}
However, this does not completely solve my problem yet. It still doesn't display the Title in the Taskbar when the Form is Visible to the user (because the Text property of the Titlebar is empty.
A workaround could be drawing your own form title bar. That way you won't need to change the actual title that's shown in Taskbar.
This question is about WPF rather than Winforms but it's applicable: Set a taskbar text different from the Window title in wpf
How can I set the protected DoubleBuffered property of the controls on a form that are suffering from flicker?
Here's a more generic version of Dummy's solution.
We can use reflection to get at the protected DoubleBuffered property, and then it can be set to true.
Note: You should pay your developer taxes and not use double-buffering if the user is running in a terminal services session (e.g. Remote Desktop) This helper method will not turn on double buffering if the person is running in remote desktop.
public static void SetDoubleBuffered(System.Windows.Forms.Control c)
{
//Taxes: Remote Desktop Connection and painting
//http://blogs.msdn.com/oldnewthing/archive/2006/01/03/508694.aspx
if (System.Windows.Forms.SystemInformation.TerminalServerSession)
return;
System.Reflection.PropertyInfo aProp =
typeof(System.Windows.Forms.Control).GetProperty(
"DoubleBuffered",
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance);
aProp.SetValue(c, true, null);
}
Check this thread
Repeating the core of that answer, you can turn on the WS_EX_COMPOSITED style flag on the window to get both the form and all of its controls double-buffered. The style flag is available since XP. It doesn't make painting faster but the entire window is drawn in an off-screen buffer and blitted to the screen in one whack. Making it look instant to the user's eyes without visible painting artifacts. It is not entirely trouble-free, some visual styles renderers can glitch on it, particularly TabControl when its has too many tabs. YMMV.
Paste this code into your form class:
protected override CreateParams CreateParams {
get {
var cp = base.CreateParams;
cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED
return cp;
}
}
The big difference between this technique and Winform's double-buffering support is that Winform's version only works on one control at at time. You will still see each individual control paint itself. Which can look like a flicker effect as well, particularly if the unpainted control rectangle contrasts badly with the window's background.
System.Reflection.PropertyInfo aProp = typeof(System.Windows.Forms.Control)
.GetProperty("DoubleBuffered", System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance);
aProp.SetValue(ListView1, true, null);
Ian has some more information about using this on a terminal server.
public void EnableDoubleBuffering()
{
this.SetStyle(ControlStyles.DoubleBuffer |
ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint,
true);
this.UpdateStyles();
}
One way is to extend the specific control you want to double buffer and set the DoubleBuffered property inside the control's ctor.
For instance:
class Foo : Panel
{
public Foo() { DoubleBuffered = true; }
}
nobugz gets the credit for the method in his link, I'm just reposting. Add this override to the Form:
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000;
return cp;
}
}
This worked best for me, on Windows 7 I was getting large black blocks appearing when I resize a control heavy form. The control now bounce instead! But it's better.
Extension method to turn double buffering on or off for controls
public static class ControlExtentions
{
/// <summary>
/// Turn on or off control double buffering (Dirty hack!)
/// </summary>
/// <param name="control">Control to operate</param>
/// <param name="setting">true to turn on double buffering</param>
public static void MakeDoubleBuffered(this Control control, bool setting)
{
Type controlType = control.GetType();
PropertyInfo pi = controlType.GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic);
pi.SetValue(control, setting, null);
}
}
Usage (for example how to make DataGridView DoubleBuffered):
DataGridView _grid = new DataGridView();
// ...
_grid.MakeDoubleBuffered(true);
Before you try double buffering, see if SuspendLayout()/ResumeLayout() solve your problem.
This caused me a lot of grief for two days with a third party control until I tracked it down.
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000;
return cp;
}
}
I recently had a lot of holes (droppings) when re-sizing / redrawing a control containing several other controls.
I tried WS_EX_COMPOSITED and WM_SETREDRAW but nothing worked until I used this:
private void myPanel_SizeChanged(object sender, EventArgs e)
{
Application.DoEvents();
}
Just wanted to pass it on.
vb.net version of this fine solution....:
Protected Overrides ReadOnly Property CreateParams() As CreateParams
Get
Dim cp As CreateParams = MyBase.CreateParams
cp.ExStyle = cp.ExStyle Or &H2000000
Return cp
End Get
End Property
You can also inherit the controls into your own classes, and set the property in there. This method is also nice if you tend to be doing a lot of set up that is the same on all of the controls.
I have found that simply setting the DoubleBuffered setting on the form automatically sets all the properties listed here.
FWIW
building on the work of those who've come before me:
Dummy's Solution, Ian Boyd's Solution, Amo's Solution
here is a version that sets double buffering via SetStyle in PowerShell using reflection
function Set-DoubleBuffered{
<#
.SYNOPSIS
Turns on double buffering for a [System.Windows.Forms.Control] object
.DESCRIPTION
Uses the Non-Public method 'SetStyle' on the control to set the three
style flags recomend for double buffering:
UserPaint
AllPaintingInWmPaint
DoubleBuffer
.INPUTS
[System.Windows.Forms.Control]
.OUTPUTS
None
.COMPONENT
System.Windows.Forms.Control
.FUNCTIONALITY
Set Flag, DoubleBuffering, Graphics
.ROLE
WinForms Developer
.NOTES
Throws an exception when trying to double buffer a control on a terminal
server session becuase doing so will cause lots of data to be sent across
the line
.EXAMPLE
#A simple WinForm that uses double buffering to reduce flicker
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
$Pen = [System.Drawing.Pen]::new([System.Drawing.Color]::FromArgb(0xff000000),3)
$Form = New-Object System.Windows.Forms.Form
Set-DoubleBuffered $Form
$Form.Add_Paint({
param(
[object]$sender,
[System.Windows.Forms.PaintEventArgs]$e
)
[System.Windows.Forms.Form]$f = $sender
$g = $e.Graphics
$g.SmoothingMode = 'AntiAlias'
$g.DrawLine($Pen,0,0,$f.Width/2,$f.Height/2)
})
$Form.ShowDialog()
.LINK
https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.control.setstyle?view=net-5.0
.LINK
https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.controlstyles?view=net-5.0
#>
param(
[parameter(mandatory=$true,ValueFromPipeline=$true)]
[ValidateScript({$_ -is [System.Windows.Forms.Control]})]
#The WinForms control to set to double buffered
$Control,
[switch]
#Override double buffering on a terminal server session(not recomended)
$Force
)
begin{try{
if([System.Windows.Forms.SystemInformation]::TerminalServerSession -and !$Force){
throw 'Double buffering not set on terminal server session.'
}
$SetStyle = ([System.Windows.Forms.Control]).GetMethod('SetStyle',
[System.Reflection.BindingFlags]::NonPublic -bor [System.Reflection.BindingFlags]::Instance
)
$UpdateStyles = ([System.Windows.Forms.Control]).GetMethod('UpdateStyles',
[System.Reflection.BindingFlags]::NonPublic -bor [System.Reflection.BindingFlags]::Instance
)
}catch {$PSCmdlet.ThrowTerminatingError($PSItem)}
}process{try{
$SetStyle.Invoke($Control,#(
([System.Windows.Forms.ControlStyles]::UserPaint -bor
[System.Windows.Forms.ControlStyles]::AllPaintingInWmPaint -bor
[System.Windows.Forms.ControlStyles]::DoubleBuffer
),
$true
))
$UpdateStyles.Invoke($Control,#())
}catch {$PSCmdlet.ThrowTerminatingError($PSItem)}}
}