I have a panel that has a collection of custom drawn controls. I know how to programmically scroll the panel but the problem is how the controls draw when scrolling. when scrolling right the control shows as normal but when scrolling left it is not looking correctly. This just the start of the complete application so I just have some basic testing in place right now. Need to find a way for the control to draw correctly when scrolling.
Form code:
public partial class Form1 : Form
{
Panel pn;
private int location = 0;
public Form1()
{
InitializeComponent();
pn = new Panel()
{
Width = this.ClientRectangle.Width - 20,
Height = 120,
BackColor = Color.Black,
Left = 5,
Top = 20
};
pn.AutoScroll = false;
pn.VerticalScroll.Maximum = 100;
pn.HorizontalScroll.Maximum = this.ClientRectangle.Width - 100;
pn.VerticalScroll.Visible = false;
pn.HorizontalScroll.Visible = false;
pn.AutoScrollPosition = new Point(0, 0);
pn.AutoScroll = true;
this.KeyPreview = true;
this.KeyDown += new KeyEventHandler(keyPress);
for(int i = 0; i<10;i++)
{
CustomControl1 cc = null;
if (i % 2 != 0)
cc = new CustomControl1()
{
isOdd = true,
Width = 100,
Height = 100,
Left = (100*i)+5,
Top = 0
};
else
cc = new CustomControl1()
{
isOdd = false,
Width = 100,
Height = 100,
Left = (100 * i) + 5,
Top = 0
};
pn.Controls.Add(cc);
}
this.Controls.Add(pn);
}
private void keyPress(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.A:
if(location - 20 >0)
{
location -= 20;
pn.HorizontalScroll.Value = location;
}
else
{
location = 0;
pn.AutoScrollPosition = new Point(location, 0);
}
break;
case Keys.D:
if(location +20 < pn.HorizontalScroll.Maximum)
{
location += 20;
pn.HorizontalScroll.Value = location;
}
else
{
location = pn.VerticalScroll.Maximum;
pn.AutoScrollPosition = new Point(location, 0);
}
break;
}
foreach(Control c in pn.Controls)
{
c.Invalidate();
}
}
}
Control Code:
public partial class CustomControl1 : Control
{
public bool isOdd { get; set; }
public CustomControl1()
{
InitializeComponent();
}
protected override void OnPaint(PaintEventArgs pe)
{
Graphics gr = pe.Graphics;
Rectangle rc = new Rectangle(pe.ClipRectangle.X,pe.ClipRectangle.Y,100,100);
Brush br = new SolidBrush(Color.Red);
if (isOdd)
br = new SolidBrush(Color.Yellow);
gr.FillEllipse(br, rc);
base.OnPaint(pe);
}
protected override void OnPaintBackground(PaintEventArgs pe)
{
base.OnPaintBackground(pe);
}
}
Don't clip your drawing:
//Rectangle rc = new Rectangle(pe.ClipRectangle.X, pe.ClipRectangle.Y, 100, 100);
Rectangle rc = new Rectangle(0, 0, 100, 100);
Related
I'm using a theme with a custom TabControl control.
The control draws text for each tab using the DrawString method like so:
using (SolidBrush B = new SolidBrush(FC))
{
G.DrawString(TabPages[i].Text, Theme.GlobalFont(FontStyle.Regular, 10), B, new Point(TabRect.X + 50, TabRect.Y + 12));
}
After changing the text to Hebrew, and changing the control's RightToLeftLayout to true, the text is flipped like so:
I tried to search online and found out that you can use Transform to modify the text, however I believe this is not the case since it should be a simple task. Here's the full class for the control:
class FirefoxMainTabControl : TabControl
{
#region " Private "
private Graphics G;
private Rectangle TabRect;
#endregion
private Color FC = Color.Blue;
#region " Control "
public FirefoxMainTabControl()
{
DoubleBuffered = true;
ItemSize = new Size(43, 152);
Alignment = TabAlignment.Left;
SizeMode = TabSizeMode.Fixed;
}
protected override void OnCreateControl()
{
base.OnCreateControl();
SetStyle(ControlStyles.UserPaint, true);
}
protected override void OnControlAdded(ControlEventArgs e)
{
base.OnControlAdded(e);
try
{
for (int i = 0; i <= TabPages.Count - 1; i++)
{
TabPages[i].BackColor = Color.White;
TabPages[i].ForeColor = Color.FromArgb(66, 79, 90);
TabPages[i].Font = Theme.GlobalFont(FontStyle.Regular, 10);
}
}
catch
{
}
}
protected override void OnPaint(PaintEventArgs e)
{
G = e.Graphics;
G.SmoothingMode = SmoothingMode.HighQuality;
G.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
base.OnPaint(e);
G.Clear(Color.FromArgb(66, 79, 90));
for (int i = 0; i <= TabPages.Count - 1; i++)
{
TabRect = GetTabRect(i);
if (SelectedIndex == i)
{
using (SolidBrush B = new SolidBrush(Color.FromArgb(52, 63, 72)))
{
G.FillRectangle(B, TabRect);
}
FC = Helpers.GreyColor(245);
using (SolidBrush B = new SolidBrush(Color.FromArgb(255, 175, 54)))
{
G.FillRectangle(B, new Rectangle(TabRect.Location.X - 3, TabRect.Location.Y + 1, 5, TabRect.Height - 2));
}
}
else
{
FC = Helpers.GreyColor(192);
using (SolidBrush B = new SolidBrush(Color.FromArgb(66, 79, 90)))
{
G.FillRectangle(B, TabRect);
}
}
using (SolidBrush B = new SolidBrush(FC))
{
G.DrawString(TabPages[i].Text, Theme.GlobalFont(FontStyle.Regular, 10), B, new Point(TabRect.X + 50, TabRect.Y + 12));
}
if ((ImageList != null))
{
if (!(TabPages[i].ImageIndex < 0))
{
G.DrawImage(ImageList.Images[TabPages[i].ImageIndex], new Rectangle(TabRect.X + 19, TabRect.Y + ((TabRect.Height / 2) - 10), 18, 18));
}
}
}
}
#endregion
}
I have a RichTextBox in my project which is for Jabber chatroom where i get all chat of users and maself.
I want to embed smileys in my project.i want a panel containing all smileys.and when click any smiley it must be sent.
like :) displays smile face
:# is angry face
They must be shown in richtextbox also in form of smiley not symbols like :)
How can i do this in c#.
I had found this code on stack overflow.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.SuspendLayout();
List<Bitmap> Smiles = new List<Bitmap>(); //Add images
ToolStripSplitButton _toolStripSplitButton = new ToolStripSplitButton();
_toolStripSplitButton.Size = new Size(23, 23);
//_toolStripSplitButton.Image = myImage; //Add the image of the stripSplitButton
ToolStrip _toolStrip = new ToolStrip();
_toolStrip.Size = new Size(ClientSize.Width, 10);
_toolStrip.Location = new Point(0, this.ClientSize.Height - _toolStrip.Height);
_toolStrip.BackColor = Color.LightGray;
_toolStrip.Dock = DockStyle.Bottom;
_toolStrip.Items.AddRange(new ToolStripItem[] { _toolStripSplitButton });
SmileBox smilebox = new SmileBox(new Point(_toolStripSplitButton.Bounds.Location.X, _toolStrip.Location.Y - 18), 6);
smilebox.Visible = false;
Controls.Add(smilebox);
foreach (Bitmap bmp in Smiles)
smilebox.AddItem(bmp);
_toolStripSplitButton.Click += new EventHandler(delegate(object sender, EventArgs e)
{
smilebox.Visible = true;
});
Click += new EventHandler(delegate(object sender, EventArgs e)
{
smilebox.Visible = false;
});
this.Controls.Add(_toolStrip);
this.ResumeLayout();
}
void Form1_Click(object sender, EventArgs e)
{
throw new NotImplementedException();
}
}
class SmileBox : Panel
{
public List<Item> Items
{
get;
set;
}
Size _ItemSpace = new Size(20, 20);
Point _ItemLocation;
int _rowelements = 0;
public SmileBox(Point Location, int RowElements)
{
BackColor = Color.LightGray;
Height = _ItemSpace.Height;
Width = _ItemSpace.Width * RowElements;
this.Location = new Point(Location.X, Location.Y - Height);
_ItemLocation = new Point(0, 0);
_rowelements = RowElements;
}
int count = 1;
public void AddItem(Bitmap Image)
{
Item item = new Item(_ItemSpace, _ItemLocation, Image);
if (_ItemLocation.X + _ItemSpace.Width >= Width)
_ItemLocation = new Point(0, _ItemLocation.Y);
else
_ItemLocation = new Point(_ItemLocation.X + _ItemSpace.Width, _ItemLocation.Y);
if (count == _rowelements)
{
_ItemLocation = new Point(_ItemLocation.X, _ItemLocation.Y + _ItemSpace.Height);
Height += _ItemSpace.Height;
Location = new Point(Location.X, Location.Y - _ItemSpace.Height);
count = 0;
}
count++;
Controls.Add(item);
}
}
class Item : PictureBox
{
int _BorderSpace = 2;
public Item(Size Size, Point Location, Bitmap Image)
{
this.Size = new Size(Size.Width - 2 * _BorderSpace, Size.Height - 2 * _BorderSpace);
this.Location = new Point(Location.X + _BorderSpace, Location.Y + _BorderSpace);
this.Image = new Bitmap(Image, this.ClientSize);
Click += new EventHandler(delegate(object sender, EventArgs e)
{
//Here what do you want to do when the user click on the smile
});
MouseEnter += new EventHandler(delegate(object sender, EventArgs e)
{
Focus();
Invalidate();
});
}
protected override void OnMouseDown(MouseEventArgs e)
{
this.Focus();
base.OnMouseDown(e);
}
protected override void OnEnter(EventArgs e)
{
this.Invalidate();
base.OnEnter(e);
}
protected override void OnLeave(EventArgs e)
{
this.Invalidate();
base.OnLeave(e);
}
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
if (this.Focused)
{
ClientRectangle.Inflate(-1, -1);
Rectangle rect = ClientRectangle;
ControlPaint.DrawFocusRectangle(pe.Graphics, rect);
}
}
}
The above code is not working for me as its too messy to understand.
Thanks in advance.
Try this code - this guy has written exactly the same:
http://www.codeproject.com/Articles/4544/Insert-Plain-Text-and-Images-into-RichTextBox-at-R
I've created a custom control in C#. A highly-simplified version of it is shown below:
class WellControl : Control
{
Pen circlePen = new Pen(Color.Black, 5);
Brush wellShader = new SolidBrush(Color.BlueViolet);
Brush wellBlanker = new SolidBrush(Color.LightGray);
public WellControl(int wellNum)
{
InitializeComponent();
}
private void DrawWell()
{
using (Graphics well = this.CreateGraphics())
{
this.Size = new Size(WellSize, WellSize);
if (this.selected)
{
well.FillEllipse(wellShader, ellipseCoords);
}
else
{
well.FillEllipse(wellBlanker, ellipseCoords);
}
well.DrawEllipse(circlePen, ellipseCoords);
using (Font wellNumberFont = new Font("Arial", 14, FontStyle.Bold))
{
well.DrawString(WellNum.ToString(), wellNumberFont, Brushes.Black, new Point(13, 13));
}
}
}
private void WellPaintEventHandler(object sender, EventArgs e)
{
DrawWell();
}
private void InitializeComponent()
{
this.SuspendLayout();
this.Paint += new System.Windows.Forms.PaintEventHandler(WellPaintEventHandler);
this.ResumeLayout();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
//dispose all the custom stuff
}
}
}
When I add it to a form, it renders properly (again, simplified example):
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
for (int i = 0; i < 4; i++)
{
WellControl newWell = new WellControl(i + 1);
newWell.Location = new Point(15, 50 * i);
newWell.Size = new System.Drawing.Size(45, 45);
this.Controls.Add(newWell);
}
}
}
I have another custom control, "Plate", which is intended to hold many "Wells". The code intended to draw the wells evenly across the plate probably sucks right now but I'm just trying to see something:
class PlateControl : Control
{
Pen blackPen = new Pen(Color.Black, 3);
public PlateControl()
{
this.Size = new Size(600, 800);
List<WellControl> plateWells = new List<WellControl>();
int column = 1;
int row = 0;
for (int i = 1; i <= 96; i++)
{
column = Convert.ToInt32(Math.Ceiling(Convert.ToDecimal(i / 8)));
row = i % 8;
WellControl newWell = new WellControl(i + 1);
newWell.Name = "wellControl" + i;
newWell.Location = new Point(column * 50, row * 50);
newWell.Size = new System.Drawing.Size(45, 45);
newWell.TabIndex = i;
newWell.WellSize = 45;
plateWells.Add(newWell);
newWell.Visible = true;
}
InitializeComponent();
}
private void InitializeComponent()
{
this.SuspendLayout();
this.Paint += new System.Windows.Forms.PaintEventHandler(PlatePaintEventHandler);
this.ResumeLayout();
}
private void DrawPlate()
{
using (Graphics plate = this.CreateGraphics())
{
Point topLeft = new Point(0, 0);
Point topRight = new Point(600, 0);
Point bottomRight = new Point(600, 400);
Point bottomLeft = new Point(0, 400);
plate.DrawLine(blackPen, topLeft, topRight);
plate.DrawLine(blackPen, topRight, bottomRight);
plate.DrawLine(blackPen, bottomRight, bottomLeft);
plate.DrawLine(blackPen, bottomLeft, topLeft);
}
}
private void PlatePaintEventHandler(object sender, EventArgs e)
{
DrawPlate();
}
}
If I add this control to a Winform using this.Controls.Add(new PlateControl()), the rectangle renders, but not the WellControls I added to the PlateControl in the constructor loop. What am I doing incorrectly?
You need to add List of WallControl to plate control.
public PlateControl()
{
this.Size = new Size(600, 800);
List<WellControl> plateWells = new List<WellControl>();
int column = 1;
int row = 0;
for (int i = 1; i <= 96; i++)
{
column = Convert.ToInt32(Math.Ceiling(Convert.ToDecimal(i / 8)));
row = i % 8;
WellControl newWell = new WellControl(i + 1);
newWell.Name = "wellControl" + i;
newWell.Location = new Point(column * 50, row * 50);
newWell.Size = new System.Drawing.Size(45, 45);
newWell.TabIndex = i;
newWell.WellSize = 45;
plateWells.Add(newWell);
newWell.Visible = true;
}
this.Controls.AddRange(plateWells.ToArray());
InitializeComponent();
}
This is the code:
private void hsMagnfier_OnMouseDown(object sender)
{
int x = mLastCursorPosition.X;
int y = mLastCursorPosition.Y;
MagnifierForm magnifier = new MagnifierForm(mConfiguration, System.Windows.Forms.Cursor.Position);//mLastCursorPosition);
magnifier.Show();
}
This code above is in a Form which I can drag over the screen.
Then when I click on an icon it's doing the magnifier.Show(); and the magnifier form is shown up where the mouse current position is.
But if I click on it again so now the position of the new form the magnifier is in my Form1 center. And not where the mouse current position as in the first time.
This is the MagnifierForm code maybe first time it's in the current mouse position but in the next time/s it's in the center of Form1 ?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.IO;
using System.Drawing.Imaging;
namespace ScreenVideoRecorder
{
public partial class MagnifierForm : Form
{
public MagnifierForm(Configuration configuration, Point startPoint)
{
InitializeComponent();
//--- My Init ---
mConfiguration = configuration;
FormBorderStyle = FormBorderStyle.None;
ShowInTaskbar = mConfiguration.ShowInTaskbar;
TopMost = mConfiguration.TopMostWindow;
Width = mConfiguration.MagnifierWidth;
Height = mConfiguration.MagnifierHeight;
// Make the window (the form) circular
GraphicsPath gp = new GraphicsPath();
gp.AddEllipse(ClientRectangle);
Region = new Region(gp);
mImageMagnifier = Properties.Resources.magnifierGlass;
mTimer = new Timer();
mTimer.Enabled = true;
mTimer.Interval = 20;
mTimer.Tick += new EventHandler(HandleTimer);
mScreenImage = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height);
mStartPoint = startPoint;
mTargetPoint = startPoint;
if (mConfiguration.ShowInTaskbar)
ShowInTaskbar = true;
else
ShowInTaskbar = false;
}
protected override void OnShown(EventArgs e)
{
RepositionAndShow();
}
private delegate void RepositionAndShowDelegate();
private void RepositionAndShow()
{
if (InvokeRequired)
{
Invoke(new RepositionAndShowDelegate(RepositionAndShow));
}
else
{
// Capture the screen image now!
Graphics g = Graphics.FromImage(mScreenImage);
g.CopyFromScreen(0, 0, 0, 0, new Size(mScreenImage.Width, mScreenImage.Height));
g.Dispose();
if (mConfiguration.HideMouseCursor)
Cursor.Hide();
else
Cursor = Cursors.Cross;
Capture = true;
if (mConfiguration.RememberLastPoint)
{
mCurrentPoint = mLastMagnifierPosition;
Cursor.Position = mLastMagnifierPosition;
Left = (int)mCurrentPoint.X - Width / 2;
Top = (int)mCurrentPoint.Y - Height / 2;
}
else
{
mCurrentPoint = Cursor.Position;
}
Show();
}
}
void HandleTimer(object sender, EventArgs e)
{
float dx = mConfiguration.SpeedFactor * (mTargetPoint.X - mCurrentPoint.X);
float dy = mConfiguration.SpeedFactor * (mTargetPoint.Y - mCurrentPoint.Y);
if (mFirstTime)
{
mFirstTime = false;
mCurrentPoint.X = mTargetPoint.X;
mCurrentPoint.Y = mTargetPoint.Y;
Left = (int)mCurrentPoint.X - Width / 2;
Top = (int)mCurrentPoint.Y - Height / 2;
return;
}
mCurrentPoint.X += dx;
mCurrentPoint.Y += dy;
if (Math.Abs(dx) < 1 && Math.Abs(dy) < 1)
{
mTimer.Enabled = false;
}
else
{
// Update location
Left = (int)mCurrentPoint.X - Width / 2;
Top = (int)mCurrentPoint.Y - Height / 2;
mLastMagnifierPosition = new Point((int)mCurrentPoint.X, (int)mCurrentPoint.Y);
}
Refresh();
}
protected override void OnMouseDown(MouseEventArgs e)
{
mOffset = new Point(Width / 2 - e.X, Height / 2 - e.Y);
mCurrentPoint = PointToScreen(new Point(e.X + mOffset.X, e.Y + mOffset.Y));
mTargetPoint = mCurrentPoint;
mTimer.Enabled = true;
}
protected override void OnMouseUp(MouseEventArgs e)
{
if (mConfiguration.CloseOnMouseUp)
{
Close();
mScreenImage.Dispose();
}
Cursor.Show();
Cursor.Position = mStartPoint;
}
protected override void OnMouseMove(MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
mTargetPoint = PointToScreen(new Point(e.X + mOffset.X, e.Y + mOffset.Y));
mTimer.Enabled = true;
}
}
protected override void OnPaintBackground(PaintEventArgs e)
{
if (mConfiguration.DoubleBuffered)
{
// Do not paint background (required for double buffering)!
}
else
{
base.OnPaintBackground(e);
}
}
protected override void OnPaint(PaintEventArgs e)
{
if (mBufferImage == null)
{
mBufferImage = new Bitmap(Width, Height);
}
Graphics bufferGrf = Graphics.FromImage(mBufferImage);
Graphics g;
if (mConfiguration.DoubleBuffered)
{
g = bufferGrf;
}
else
{
g = e.Graphics;
}
if (mScreenImage != null)
{
Rectangle dest = new Rectangle(0, 0, Width, Height);
int w = (int)(Width / mConfiguration.ZoomFactor);
int h = (int)(Height / mConfiguration.ZoomFactor);
int x = Left - w / 2 + Width / 2;
int y = Top - h / 2 + Height / 2;
g.DrawImage(
mScreenImage,
dest,
x, y,
w, h,
GraphicsUnit.Pixel);
}
if (mImageMagnifier != null)
{
g.DrawImage(mImageMagnifier, 0, 0, Width, Height);
}
if (mConfiguration.DoubleBuffered)
{
e.Graphics.DrawImage(mBufferImage, 0, 0, Width, Height);
}
}
//--- Data Members ---
#region Data Members
private Timer mTimer;
private Configuration mConfiguration;
private Image mImageMagnifier;
private Image mBufferImage = null;
private Image mScreenImage = null;
private Point mStartPoint;
private PointF mTargetPoint;
private PointF mCurrentPoint;
private Point mOffset;
private bool mFirstTime = true;
private static Point mLastMagnifierPosition = Cursor.Position;
#endregion
}
}
The first time the new Form the magnifier is shown up where my mouse cursour is.
The next time i click on it's showing the magnifier form in the center of Form1 and not where the mouse cursour is.
Why is that ? When i clikc on the icon again it's still doing the
System.Windows.Forms.Cursor.Position
Again. Strange.
Consider you have two forms - Master and Child
If you are calling Child from Master on MouseUp event(for example), write the code in MouseUp event of Master form
ChildForm obj=new ChildForm();
obj.pntLocation = new Point(Cursor.Position.X, Cursor.Position.Y);
obj.ShowDialog();
Declare a variable inside the Child for location
public Point pntLocation;
Now set location inside the Form_Load of Child
this.Location = pntLocation;
Ok found that the part that doing it is here in the Magnifier form:
mConfiguration.RememberLastPoint = false;
if (mConfiguration.RememberLastPoint)
{
mCurrentPoint = mLastMagnifierPosition;
Cursor.Position = mLastMagnifierPosition;
Left = (int)mCurrentPoint.X - Width / 2;
Top = (int)mCurrentPoint.Y - Height / 2;
}
else
{
mCurrentPoint = Cursor.Position;
}
So I added for now the line: mConfiguration.RememberLastPoint = false; which did the job for now.
I would like to create a control the floats (potentially) outside the bounds of it's containing form. Is this possible? How may I do it?
This would function much like Context Menu's only I need to be able to add other controls to it such as buttons and images.
You want a Form with it's FormBorderStyle set to None, if you want it to behave like a context menu then you'll need to tie showing it to the appropriate event handler in your main form. Simple example below of setting the location and calling show from a mouse click event handler.
MyForm form = new MyForm();
form.Location = PointToScreen(new Point(e.X, e.Y));
form.Show();
It is possible, the TopLevel property controls this. However, the designer doesn't support them well, hard to keep control over controls that are also top-level windows at design time.
Beyond components like ToolTip and ContextMenuStrip, there is exactly one class that is top-level by design, the Form class. Set its FormBorderStyle to None and ControlBox to False to create a basic top-level window that you can use and populate with other controls.
Take a look at the DockPanel Suite source and adopt the technique.
here is u can made for all Control floating Style
private void Panel_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
Panel.Left += e.X - PanelMouseDownLocation.X;
Panel.Top += e.Y - PanelMouseDownLocation.Y;
}
}
private void Panel_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left) PanelMouseDownLocation = e.Location;
}
public Point PanelMouseDownLocation { get; set; }
It would need to be a separate window (much like a context menu actually is) -- you could wrap it as a control, that displays a modeless form (which would even give you the option for non rectangular windows if you really wanted to). As you could create the window from a non-visible control from the parent form, you can maintain a reference to the child for handling inter-form communication.
Have your UserControl override CreateParams. For example:
[DllImport("user32.dll", EntryPoint = "GetDesktopWindow")]
public static extern IntPtr GetDesktopWindow();
protected override CreateParams CreateParams
{
get
{
var cp = base.CreateParams;
cp.ExStyle &= 0x00080000; // WS_EX_LAYERED
cp.Style = 0x40000000 | 0x4000000; // WS_CHILD | WS_CLIPSIBLINGS
cp.Parent = GetDesktopWindow();
return cp;
}
}
This may have unintended effects (including not working well with Designer). I am choosing to follow one of the above patterns, but I thought it was worth mentioning here. Lookup CreateParams to see its purpose. (This option was gleaned from this page.)
This worked for me
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Windows.Forms;
using LollipopUIControls.UIManagers;
namespace Gamasis.Apps.Controls
{
public class FloatingButton : Button
{
public FloatingButton()
{
SetStyle((ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.SupportsTransparentBackColor | ControlStyles.UserPaint), true);
DoubleBuffered = true;
Size = new Size(50, 50);
BackColor = Color.Transparent;
SF.Alignment = StringAlignment.Center;
SF.LineAlignment = StringAlignment.Center;
AnimationTimer.Tick += new EventHandler(AnimationTick);
}
#region Variables
Timer AnimationTimer = new Timer { Interval = 1 };
FontManager font = new FontManager();
StringFormat SF = new StringFormat();
Rectangle StringRectangle;
bool Focus = false;
int margintop = 0, marginleft = 0, marginright = 0, marginBottom = 0;
int xx;
int yy;
float SizeAnimation = 0;
float SizeIncNum;
string fontcolor = "#FAFAFA";
string Backcolor = "#039BE5";
Color EnabledBGColor;
Color EnabledBorderColor;
Color StringColor;
Color DisabledBGColor = ColorTranslator.FromHtml("#B0BEC5");
Color DisabledStringColor = ColorTranslator.FromHtml("#FAFAFA");
Color NonColor = ColorTranslator.FromHtml("#e3e5e7");
Image bGImage = null;
#endregion
#region Properties
[Category("Custom")]
public string BGColor
{
get { return Backcolor; }
set
{
Backcolor = value;
Invalidate();
}
}
[Category("Custom")]
public string FontColor
{
get { return fontcolor; }
set
{
fontcolor = value;
Invalidate();
}
}
[Browsable(false)]
public Font Font
{
get { return base.Font; }
set { base.Font = value; }
}
[Browsable(false)]
public Color ForeColor
{
get { return base.ForeColor; }
set { base.ForeColor = value; }
}
[Category("Custom")]
public Image BGImage
{
get { return bGImage; }
set { bGImage = value; }
}
ImageSizeLevel bGimgSize = ImageSizeLevel.peque2;
public ImageSizeLevel BGimgSize
{
get { return bGimgSize; }
set { bGimgSize = value; }
}
#endregion
#region Events
protected override void OnMouseEnter(EventArgs e)
{
base.OnMouseEnter(e);
EnabledBGColor = Color.FromArgb(30, ColorTranslator.FromHtml(BGColor));//StringColor);
EnabledBorderColor = Color.FromArgb(20, ColorTranslator.FromHtml(BGColor));//StringColor);
Refresh();
}
protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
EnabledBGColor = ColorTranslator.FromHtml(BGColor);
EnabledBorderColor = ColorTranslator.FromHtml(BGColor);
Refresh();
}
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
EnabledBGColor = Color.FromArgb(30, StringColor);
Refresh();
xx = e.X;
yy = e.Y;
Focus = true;
AnimationTimer.Start();
Invalidate();
}
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
Focus = false;
AnimationTimer.Start();
Invalidate();
}
protected override void OnTextChanged(System.EventArgs e)
{
base.OnTextChanged(e);
Invalidate();
}
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
//StringRectangle = new Rectangle(3, 0, Width - 6, Height - 6);
}
#endregion
protected override void OnResize(System.EventArgs e)
{
base.OnResize(e);
//SizeIncNum = Width / 34;
SizeIncNum = Width / 10;
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
var G = e.Graphics;
#region Default rectangle
//G.SmoothingMode = SmoothingMode.HighQuality | SmoothingMode.AntiAlias;
//G.Clear(Parent.BackColor);
//StringColor = ColorTranslator.FromHtml(fontcolor);
//var BG = DrawHelper.CreateRoundRect(1, 1, Width - 3, Height - 3, 1);
//Region region = new Region(BG);
//G.FillPath(new SolidBrush(Enabled ? EnabledBGColor : Color.White), BG);
//G.DrawPath(new Pen(Enabled ? EnabledBorderColor : Color.White), BG);
//G.SetClip(region, CombineMode.Replace);
////The Ripple Effect
//G.FillEllipse(new SolidBrush(Color.FromArgb(30, StringColor)), xx - (SizeAnimation / 2), yy - (SizeAnimation / 2), SizeAnimation, SizeAnimation);
//G.DrawString(Text, font.Roboto_Medium10, new SolidBrush(Enabled ? StringColor : DisabledStringColor), R, SF);
#endregion
#region Circle
//G.SmoothingMode = SmoothingMode.AntiAlias;
//G.Clear(BackColor);
//GraphicsPath bgbtn = new GraphicsPath();
//bgbtn.AddEllipse(0, 0, Width - 5, Height - 5);
//GraphicsPath bgShadow = new GraphicsPath();
//bgShadow.AddEllipse(0, 0, Width - 2, Height - 2);
//G.FillPath(new SolidBrush(NonColor), bgShadow);
//G.DrawPath(new Pen(NonColor), bgShadow);
//G.FillPath(new SolidBrush(Color.DeepSkyBlue), bgbtn);
//G.DrawPath(new Pen(Color.DeepSkyBlue), bgbtn);
#endregion
///----------------------------
G.SmoothingMode = SmoothingMode.AntiAlias;
G.Clear(Parent.BackColor);
StringColor = ColorTranslator.FromHtml(fontcolor);
//var BG = DrawHelper.CreateRoundRect(1, 1, Width - 3, Height - 3, 1);
//Círculo principal
GraphicsPath bgbtn = new GraphicsPath();
bgbtn.AddEllipse(2, 0, Width - 6, Height - 6);
//Círculo para la sombra
GraphicsPath bgShadow = new GraphicsPath();
bgShadow.AddEllipse(2, 4, Width - 6, Height - 6);
// se dibuja la sombra
G.FillPath(new SolidBrush(NonColor), bgShadow);
G.DrawPath(new Pen(NonColor), bgShadow);
//sedibuja el círculo principal sobre la sombra
G.FillPath(new SolidBrush(Enabled ? ColorTranslator.FromHtml(BGColor) : DisabledBGColor), bgbtn);
G.DrawPath(new Pen(Enabled ? ColorTranslator.FromHtml(BGColor) : DisabledBGColor), bgbtn);
// Se da a la región forma de círculo/elipse
Region region = new Region(bgbtn);//BG);
G.SetClip(region, CombineMode.Replace);
//The Ripple Effect
if (Enabled)
G.FillEllipse(new SolidBrush(Color.FromArgb(30, EnabledBGColor)), xx - (SizeAnimation / 2), yy - (SizeAnimation / 2), SizeAnimation, SizeAnimation);
StringRectangle = new Rectangle((int)bgbtn.GetBounds().Location.X, (int)bgbtn.GetBounds().Location.Y,
(int)bgbtn.GetBounds().Size.Width, (int)bgbtn.GetBounds().Size.Height);
G.DrawString(Text, font.Roboto_Medium15, new SolidBrush(Enabled ? StringColor : DisabledStringColor), StringRectangle, SF);
if (bGImage != null)
{
float imgX = 0, imgY = 0;
imgY = (bgbtn.GetBounds().Size.Height - (int)bGimgSize) / 2;
imgX = ((bgbtn.GetBounds().Size.Width - (int)bGimgSize) + 2) / 2;
G.DrawImage(bGImage, imgX, imgY, (float)bGimgSize, (float)bGimgSize);
}
}
protected void AnimationTick(object sender, EventArgs e)
{
if (Focus)
{
if (SizeAnimation < Width + 250)
{
SizeAnimation += SizeIncNum;
this.Invalidate();
}
}
else
{
if (SizeAnimation > 0)
{
SizeAnimation = 0;
this.Invalidate();
}
}
}
public enum ImageSizeLevel
{
peque = 12, peque1 = 24, peque2 = 32,
maso = 48, maso1 = 56, maso2 = 64,
grande = 72, grande1 = 86, grande2 = 96,
monstruo = 128, monstruo1 = 256, monstruo2 = 512
}
}
}