I am developing a project that needs to look like the attached screenshot.
I have a WinForm with VideoPanelCtl panel on top of it. The panel's handle is passed to the instantiated VLC component/control that results in video displayed on that panel.
I also tried to put another panel on top of the VideoPanelCtl at the upper end of the video panel and make it transparent and the controls that are sitting on top of this top panel also should have transparent background as shown in attached screenshot. However, my approach did not work despite that I used a a custom panel derived from panel control with bkg repainting (see code below) The panel that I was creating in code like this simply was obscured by the video...and if I had put controls on it (buttons and labels) they probably would be obscured too...
I call this from form's Load handler of the WinForm:
private void InitTopPanel()
{
mExtendedPanelTop = new ExtendedPanel();
mExtendedPanelTop.Opacity = 50; // totally transparent
videoPanelCtl.Controls.Add(mExtendedPanelTop);
mExtendedPanelTop.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
mExtendedPanelTop.Dock = System.Windows.Forms.DockStyle.Top;
mExtendedPanelTop.Location = new System.Drawing.Point(0, 0);
mExtendedPanelTop.Name = "ExtendedPanelTop";
mExtendedPanelTop.Size = new System.Drawing.Size(1090, 48);
mExtendedPanelTop.TabIndex = 0;
//mExtendedPanelTop.Paint += mExtendedPanelTop_Paint;
}
public class ExtendedPanel : Panel
{
private const int WS_EX_TRANSPARENT = 0x20;
public ExtendedPanel()
{
SetStyle(ControlStyles.Opaque, true);
}
private int opacity = 50;
//[DefaultValue(50)]
public int Opacity
{
get
{
return this.opacity;
}
set
{
if (value < 0 || value > 100)
throw new ArgumentException("value must be between 0 and 100");
this.opacity = value;
}
}
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle = cp.ExStyle | WS_EX_TRANSPARENT;
return cp;
}
}
protected override void OnPaint(PaintEventArgs e)
{
using (var brush = new SolidBrush(Color.FromArgb(this.opacity * 255 / 100, this.BackColor)))
{
e.Graphics.FillRectangle(brush, this.ClientRectangle);
}
base.OnPaint(e);
}
}
How do I achieve the controls on top of video that sit on transparent panel and also have transparent background?
How do I achieve semi-transparent label on top of video with text (red label background) that says "Video Connection Lost"? (see attached)
I resolved it by using WPF control that contains the Canvas and the Canvas containing MediaElement and Label (or other controls). Then setting ZIndex of Label higher to cause visibility. Thus, I get visible label on running video (within MediaElement) with Label having transparent background.
I'm trying to create a program within winForm in C# where an image will follow the mouse outside the application.
I have no clue how to draw an image outside of the form, let alone have it follow the mouse. My solution was going to be - create a borderless form and have the it follow the mouse - but this solution will not work because I cannot move a form via code.
The mouse needs to be able to click and function independently from this image.
How would I go about doing this?
it must do so without changing the way the mouse is used.
Set WS_EX_TRANSPARENT for the extended styles to make your form ignore mouse clicks. Set TopMost to True and Opacity to something less than 100% to make it semi-transparent. Move your form with a Timer. Something like:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.Opacity = .5;
this.TopMost = true;
this.BackColor = Color.Yellow;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
// Makes the form circular:
System.Drawing.Drawing2D.GraphicsPath GP = new System.Drawing.Drawing2D.GraphicsPath();
GP.AddEllipse(this.ClientRectangle);
this.Region = new Region(GP);
}
const int WS_EX_TRANSPARENT = 0x20;
protected override System.Windows.Forms.CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle = cp.ExStyle | WS_EX_TRANSPARENT;
return cp;
}
}
private void timer1_Tick(object sender, EventArgs e)
{
Point pt = Cursor.Position;
pt.Offset(-1 * this.Width / 2, -1 * this.Height / 2);
this.Location = pt;
}
}
check this thread :
How to drag and move winform using mouse
seems you want to do something like this.
Hope this helps!
I need to draw transparent PNG image on WinForms. I have a base class:
public abstract class BaseSkinable : Panel
{
protected BaseSkinable()
{
this.SetStyle(ControlStyles.DoubleBuffer, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.UserPaint, true);
this.SetStyle(ControlStyles.ResizeRedraw, true);
}
protected abstract void OnDraw(Graphics graphics);
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x00000020;
return cp;
}
}
protected override void OnPaintBackground(PaintEventArgs e) { }
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.TextRenderingHint =
System.Drawing.Text.TextRenderingHint.AntiAlias;
e.Graphics.InterpolationMode =
System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
e.Graphics.PixelOffsetMode =
System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
e.Graphics.SmoothingMode =
System.Drawing.Drawing2D.SmoothingMode.HighQuality;
OnDraw(e.Graphics);
}
}
In inherited class:
protected override void OnDraw(Graphics graphics)
{
Image toDraw = SelectImageToDraw();
if (toDraw == null)
{
NoImageDraw(graphics);
return;
}
int width = toDraw.Size.Width;
int height = toDraw.Size.Height;
Rectangle rect = new Rectangle(0, 0, width, height);
graphics.DrawImage(toDraw, rect);
}
I need to redraw image if user move mouse over control. But the problem is against drawing overlay old image. Like we draw layers. Winforms possible not clear Graphics and my method draws over old picture. How to solve it, possible im doing something wrong.
Hard to understand what your question is -- but are you trying to clear the background before drawing something?
Using the Graphics object, you can call Clear off of it with the background color. If there is another image behind it, I can see some of your frustration -- but I would think you'd just need to set a transparent color (and supply the Transparent color to the Clear method). That, in my mind, should clean everything up.
http://msdn.microsoft.com/en-us/library/system.drawing.graphics.clear%28v=vs.110%29.aspx
Hope that helps or answers the question you were looking to get answered.
Is it possible to appear an outer shadow for my control when the mouse move over it? in winforms?
I can change its appearance, but a shadow?
public class MyButton : Button
{
protected override void OnPaint(PaintEventArgs pevent)
{
GraphicsPath path = new GraphicsPath();
path.AddEllipse(0, 0, ClientSize.Width, ClientSize.Height);
this.Region = new Region(path);
base.OnPaint(pevent);
}
}
I am the asker. I can add another label behind the control, and make it appear as a shadow when mouse hover.
I have derived a TabControl with the express purpose of enabling double buffering, except nothing is working as expected. Here is the TabControl code:
class DoubleBufferedTabControl : TabControl
{
public DoubleBufferedTabControl() : base()
{
this.DoubleBuffered = true;
this.SetStyle
(
ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.ResizeRedraw |
ControlStyles.OptimizedDoubleBuffer |
ControlStyles.SupportsTransparentBackColor,
false
);
}
}
This Tabcontrol is then set with it's draw mode as 'OwnerDrawnFixed' so i can changed the colours. Here is the custom drawing method:
private void Navigation_PageContent_DrawItem(object sender, DrawItemEventArgs e)
{
//Structure.
Graphics g = e.Graphics;
TabControl t = (TabControl)sender;
TabPage CurrentPage = t.TabPages[e.Index];
//Get the current tab
Rectangle CurrentTabRect = t.GetTabRect(e.Index);
//Get the last tab.
Rectangle LastTab = t.GetTabRect(t.TabPages.Count - 1);
//Main background rectangle.
Rectangle BackgroundRect = new Rectangle(LastTab.Width, t.Bounds.Y - 4, t.Width - (LastTab.Width), t.Height);
//Tab background rectangle.
Rectangle TabBackgroundRect = new Rectangle(0, LastTab.Y + LastTab.Height, LastTab.Width, t.Bounds.Height - (LastTab.Y + LastTab.Height));
//Set anitialiasing for the text.
e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
//String format for the text.
StringFormat StringFormat = new StringFormat();
StringFormat.Alignment = StringAlignment.Center;
StringFormat.LineAlignment = StringAlignment.Center;
//Fill the background.
g.FillRectangle(Brushes.LightGray, BackgroundRect);
g.FillRectangle(Brushes.Bisque, TabBackgroundRect);
//Draw the selected tab.
if(e.State == DrawItemState.Selected)
{
g.FillRectangle(Brushes.White, e.Bounds);
Rectangle SelectedTabOutline = new Rectangle(e.Bounds.X + 2, e.Bounds.Y + 2, e.Bounds.Width, e.Bounds.Height - 4);
g.DrawRectangle(new Pen(Brushes.LightGray, 4f), SelectedTabOutline);
g.DrawString(CurrentPage.Text, new Font("Arial", 12f, FontStyle.Bold, GraphicsUnit.Point), new SolidBrush(Color.FromArgb(70, 70, 70)), CurrentTabRect, StringFormat);
}
else
{
g.FillRectangle(new SolidBrush(Color.FromArgb(230, 230, 230)), e.Bounds);
g.DrawString(CurrentPage.Text, new Font("Arial", 12f, FontStyle.Regular, GraphicsUnit.Point), Brushes.Gray, CurrentTabRect, StringFormat);
}
}
All to no avail however, as this control is not double buffered and still flickers when resized.
Any ideas?
If you read the documentation, it says, "This member is not meaningful for this control." If you want the control to be drawn utilizing double-buffering, you'll have to implement it yourself. Besides the fact that if you owner-draw the control, you would have to implement double-buffering yourself anyhow.
First of all, you can get rid of your TabControl code—you turn on buffering, and then immediately turn it off, so it's not actually doing anything useful.
Part of your problem is that you're trying to paint just part of the TabControl.
The easiest solution that gives about a 90% solution (it's still possible to get a flicker) is to add this to your form class:
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000;
return cp;
}
}
If you want to be very sure of getting no flicker, you'll need to draw the entire TabControl yourself, and make sure to ignore background painting requests.
Edit: Note that this will only work in XP and later.
I've had problems with double buffering on controls in the past and the only way to stop the flicker was to ensure the inherited OnPaintBackground method was not being called. (See code below) You will also need to ensure the entire backgound is painted during your paint call.
protected override void OnPaintBackground( PaintEventArgs pevent )
{
//do not call base - I don't want the background re-painted!
}
Not sure, but you might try double-buffering the control that contains the tab control.
I looked around quite a bit, tried your code and whatever else I could think of, but I don't see a way to get rid of the flicker. Unfortunately, in my tests even a regular (non-owner-drawn) tab control flickers during resizing.
For what it's worth, turning off "Show window contents while dragging" will fix it, but I realize that may not be helpful.
I think it doesn't work because you are disabling double buffering!
All this.DoubleBuffered = true does is set ControlStyles.OptimizedDoubleBuffer to true. Since you are disabling that flag in the next line of your program, you are really doing nothing. Remove ControlStyles.OptimizedDoubleBuffer (and perhaps ControlStyles.AllPaintingInWmPaint) and it should work for you.