Video link: https://drive.google.com/open?id=1pErIL2TcE_wMNYaH0FlWxuijqSwbkYY3
There is something that I cannot translate the problem/bug as I don't know how to address this kind of problem. When the font family selection change, all the label inside the groupbox will be changed too. The code for it as per below:-
private void ScreenPage_FontFamilyCombobox_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
if (ScreenPage_FontFamilyCombobox.Text != "")
{
ScreenPage_FontFamilyNotInstalled.Visible = false;
UpdateScreenSample();
}
}
catch (Exception ex)
{
UpdateEvents("Exception ScreenPage_FontFamilyCombobox_SelectedIndexChanged. " + ex.Message);
}
}
private void UpdateScreenSample()
{
try
{
//foreach (var TransLabels in ScreenPage_SampleGroupbox.Controls.OfType<GroupBox>().SelectMany(groupBox => groupBox.Controls.OfType<CodeMess.TransparentLabel>()))
//{
// float fntSize = TransLabels.Font.Size;
// FontStyle fntStyle = TransLabels.Font.Style;
// TransLabels.Font = new Font(ScreenPage_FontFamilyCombobox.Text, fntSize, fntStyle);
//}
var TransLabels = ScreenPage_SampleGroupbox.Controls.OfType<CodeMess.TransparentLabel>();
foreach (CodeMess.TransparentLabel tL in TransLabels)
{
float fntSize = tL.Font.Size;
FontStyle fntStyle = tL.Font.Style;
tL.Font = new Font(ScreenPage_FontFamilyCombobox.Text, fntSize, fntStyle);
}
//foreach (Control control in ScreenPage_SampleGroupbox.Controls)
//{
// if (control is ApplizoneConfiguration.CodeMess.TransparentLabel transLabel)
// {
// float fntSize = control.Font.Size;
// control.Font = new Font(ScreenPage_FontFamilyCombobox.Text, fntSize, FontStyle.Regular);
// }
//}
}
catch (Exception ex)
{
UpdateEvents("Exception UpdateScreenSample. " + ex.Message);
}
}
There is 3 code that I try to see if there any change but seems not. The font shadow trail will be disappear if I change to another tab and go back to the ScreenPage tab again.
The code for Transparent Label class is below which I use to transparent the background as it has dock fill image inside the groupbox on the bottom of all label:-
using System;
using System.Windows.Forms;
namespace ApplizoneConfiguration.CodeMess
{
public class TransparentLabel : Label
{
public TransparentLabel()
{
this.SetStyle(ControlStyles.Opaque, true);
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, false);
}
protected override CreateParams CreateParams
{
get
{
CreateParams parms = base.CreateParams;
parms.ExStyle |= 0x20; // Turn on WS_EX_TRANSPARENT
return parms;
}
}
}
}
There is a way to overcome this?
I have go through code by #Jimi answer linked from comment. And modified the code combined with solution from here and it a bit OK. Here is the full code with commenting
Sample Screen2Gif from solutions by Reza Aghaei here result with delay effect:-
Combine with solutions from Jimi + Reza result with these:-
Code:-
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Globalization;
using System.ComponentModel;
using System.Windows.Forms;
using System.Linq;
namespace Configuration.CodeMess
{
public class TransparentLabel : Label, INotifyPropertyChanged
{
internal int WS_EX_TRANSPARENT = 0x00000020;
//internal Font m_CustomFont = new Font("Segoe UI", 9, FontStyle.Regular, GraphicsUnit.Pixel);
//internal Color m_BackGroundColor;
//internal int m_InnerPadding = 20;
//internal int m_FontPadding = 5;
//internal int m_Opacity = 50;
public event PropertyChangedEventHandler PropertyChanged;
public TransparentLabel() => InitializeComponent();
public void InitializeComponent()
{
this.SetStyle(ControlStyles.Opaque |
ControlStyles.SupportsTransparentBackColor |
ControlStyles.ResizeRedraw, true);
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, false);
this.Refresh();
}
//protected override void OnPaint(PaintEventArgs e)
//{
// if (Parent != null)
// {
// using (var bmp = new Bitmap(Parent.Width, Parent.Height))
// {
// Parent.Controls.Cast<Control>()
// .Where(c => Parent.Controls.GetChildIndex(c) > Parent.Controls.GetChildIndex(this))
// .Where(c => c.Bounds.IntersectsWith(this.Bounds))
// .OrderByDescending(c => Parent.Controls.GetChildIndex(c))
// .ToList()
// .ForEach(c => c.DrawToBitmap(bmp, c.Bounds));
// e.Graphics.DrawImage(bmp, -Left, -Top);
// using (var b = new SolidBrush(Color.FromArgb(this.Opacity, this.TransparentBackColor)))
// {
// e.Graphics.FillRectangle(b, this.ClientRectangle);
// }
// e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
// TextRenderer.DrawText(e.Graphics, this.Text, this.Font, this.ClientRectangle, this.ForeColor, Color.Transparent);
// }
// }
//}
private int opacity;
public int Opacity
{
get { return opacity; }
set
{
if (value >= 0 && value <= 255)
opacity = value;
this.Invalidate();
}
}
public Color transparentBackColor;
public Color TransparentBackColor
{
get { return transparentBackColor; }
set
{
transparentBackColor = value;
this.Invalidate();
}
}
[Browsable(false)]
public override Color BackColor
{
get
{
return Color.Transparent;
}
set
{
base.BackColor = Color.Transparent;
}
}
//public new Font Font
//{
// get => this.m_CustomFont;
// set
// {
// this.FontAdapter(value);
// NotifyPropertyChanged(nameof(this.Font));
// }
//}
//public int InnerPadding
//{
// get => this.m_InnerPadding;
// set
// {
// this.m_InnerPadding = CheckValue(value, 0, this.ClientRectangle.Height - 10);
// NotifyPropertyChanged(nameof(this.InnerPadding));
// }
//}
//public int FontPadding
//{
// get => this.m_FontPadding;
// set
// {
// this.m_FontPadding = CheckValue(value, 0, this.ClientRectangle.Height - 10);
// NotifyPropertyChanged(nameof(this.FontPadding));
// }
//}
//public int Opacity
//{
// get => this.m_Opacity;
// set
// {
// this.m_Opacity = CheckValue(value, 0, 255);
// this.BackColor = Color.FromArgb(this.m_Opacity, this.BackColor);
// NotifyPropertyChanged(nameof(this.Opacity));
// }
//}
//public override Color BackColor
//{
// get => this.m_BackGroundColor;
// set
// {
// this.m_BackGroundColor = Color.FromArgb(this.m_Opacity, value);
// base.BackColor = this.m_BackGroundColor;
// NotifyPropertyChanged(nameof(this.BackColor));
// }
//}
//private void NotifyPropertyChanged(string PropertyName)
//{
// this.Refresh();
// PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
//}
//protected override void OnLayout(LayoutEventArgs evt)
//{
// base.OnLayout(evt);
// base.AutoSize = false;
// this.Opacity = this.m_Opacity;
//}
protected override void OnPaint(PaintEventArgs e)
{
StringFormat format = new StringFormat(StringFormatFlags.LineLimit, CultureInfo.CurrentUICulture.LCID)
{
LineAlignment = StringAlignment.Center,
Alignment = StringAlignment.Center
};
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
TextRenderer.DrawText(e.Graphics, this.Text, this.Font, this.ClientRectangle, this.ForeColor, Color.Transparent);
//using (SolidBrush CircleBrush = new SolidBrush(this.BackColor))
//using (SolidBrush ForeBrush = new SolidBrush(this.ForeColor))
//{
// this.FontAdapter(this.m_CustomFont);
// RectangleF rect = InnerRectangle();
// e.Graphics.FillEllipse(CircleBrush, rect);
// e.Graphics.DrawString(this.Text, this.m_CustomFont, format);
//}
}
//private RectangleF InnerRectangle()
//{
// Tuple<decimal, decimal> refSize = GetMinMax(this.ClientRectangle.Height, this.ClientRectangle.Width);
// SizeF size = new SizeF((float)refSize.Item1 - (this.m_InnerPadding / 2),
// (float)refSize.Item1 - (this.m_InnerPadding / 2));
// PointF position = new PointF((this.ClientRectangle.Width - size.Width) / 2,
// (this.ClientRectangle.Height - size.Height) / 2);
// return new RectangleF(position, size);
//}
//private void FontAdapter(Font font)
//{
// RectangleF rect = InnerRectangle();
// float FontSize = (CheckValue((int)(rect.Height - this.m_FontPadding), 6,
// (int)(rect.Height - this.m_FontPadding)) / 1.4F);
// using (Font customfont = new Font(font.FontFamily, FontSize, font.Style, GraphicsUnit.Pixel))
// this.m_CustomFont = (Font)customfont.Clone();
//}
//private int CheckValue(int Value, int Min, int Max)
//{
// return (Value < Min) ? Min : ((Value > Max) ? Max : Value);
//}
//private Tuple<decimal, decimal> GetMinMax(ValueType Value1, ValueType Value2)
//{
// if ((Value1 is Enum) || (Value1.GetType().IsNested)) return null;
// if ((Value2 is Enum) || (Value2.GetType().IsNested)) return null;
// return new Tuple<decimal, decimal>(Math.Min(Convert.ToDecimal(Value1), Convert.ToDecimal(Value2)),
// Math.Max(Convert.ToDecimal(Value1), Convert.ToDecimal(Value2)));
//}
protected override CreateParams CreateParams
{
get
{
CreateParams parms = base.CreateParams;
parms.ExStyle |= 0x20; // Turn on WS_EX_TRANSPARENT
return parms;
}
}
}
}
Open to any amendment for improvement.
Related
There is a "Custom Trackbar", which can take negative and positive values. If you set Min = -50, Max = 100, the slider moves outside the scrollbar. I need it to behave in the same way as "Standard Trackbar" (it should not go beyond the scrollbar boundaries). How to do it?
The screenshot shows 2 Trackbars for both I set (Minimum = -50, Maximum = 100, Value = -50), but after building the project I got the following picture:
If we set (Minimum = 0, Maximum = 100, Value = 25), we get the following:
[Code Custom Trackbar]
[DefaultEvent("ValueChanged")]
public class HandyHTrackbarWorked : Control {
#region Установка начальных параметров
public HandyHTrackbarWorked() {
SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint
| ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw, true); UpdateStyles();
Size = new Size(250, 12);
ThumbSize = new Size(ThumbRect.Width = 15, ThumbRect.Height = 12);
}
#endregion
#region Основные свойства
private double _value;
public double Value {
get { return _value; }
set {
_value = value;
//if (_value < Minimum) { _value = Minimum; }
//if (_value > Maximum) { _value = Maximum; }
OnScroll(); Refresh();
}
}
private double minimum;
public double Minimum {
get { return minimum; }
set { minimum = value; Invalidate(); }
}
private double maximum = 100;
public double Maximum {
get { return maximum; }
set { maximum = value; Invalidate(); }
}
private double smallStep = 1;
public double SmallStep {
get { return smallStep; }
set {
smallStep = (value > 0) ? value : 1;
}
}
#endregion
#region Свойства, отвечающие за оформление
[Description("Размер ползунка")]
private Size thumbSize;
public Size ThumbSize {
get { return thumbSize; }
set {
thumbSize = value;
//if (thumbSize.Width % 2 == 0 && thumbSize.Width > 0) thumbSize.Width += 1;
Invalidate();
}
}
[Description("Цвет ползунка")]
private Color thumbBackColor = Color.FromArgb(255, 255, 255);
public Color ThumbBackColor {
get { return thumbBackColor; }
set { thumbBackColor = value; Invalidate(); }
}
private Color trackBackColor = Color.Transparent;
public Color TrackBackColor {
get { return trackBackColor; }
set { trackBackColor = value; Invalidate(); }
}
private Color trackBorderColor = Color.FromArgb(221, 0, 49);
public Color TrackBorderColor {
get { return trackBorderColor; }
set { trackBorderColor = value; Invalidate(); }
}
private Color trackBorderColor2 = Color.FromArgb(64, 64, 64);
public Color TrackBorderColor2 {
get { return trackBorderColor2; }
set { trackBorderColor2 = value; Invalidate(); }
}
[Description("Толщина")]
private int trackThickness = 2;
public int TrackThickness {
get { return trackThickness; }
set { trackThickness = value; Invalidate(); }
}
public new Padding Padding {
get { return base.Padding; }
set { base.Padding = value; Invalidate(); }
}
public Rectangle ThumbRect;
#endregion
#region Основные события
public event EventHandler ValueChanged;
#endregion
#region Обработчики событий
private Point startMouseClickPosition;
private Point currentMousePosition;
protected override void OnCreateControl() {
base.OnCreateControl();
this.MouseDown += (sender, e) => {
// When clicking on the ScrollBar, center the Thumb relative to the mouse cursor
if (!ThumbRect.Contains(e.Location)) {
MoveThumb(e, false);
}
// When clicking on Thumb, determine the startMouseClickPosition
if (ThumbRect.Contains(e.Location)) {
startMouseClickPosition.X = e.X - ThumbRect.Left; // OR ... - ThumbRect.X
ThumbBackColor = Color.Green;
}
};
this.MouseMove += (sender, e) => {
ThumbBackColor = ThumbRect.Contains(e.Location)
? ThumbBackColor = Color.Orange : ThumbBackColor = Color.Gray;
if (e.Button == MouseButtons.Left) {
ThumbBackColor = Color.Green; MoveThumb(e);
}
};
this.MouseLeave += (sender, e) => { ThumbBackColor = Color.Gray; };
}
int PaddingLR = 10;
// padding(left/right) must be the same,
// if the orientation of the scroll bar is HORIZONTAL
private void MoveThumb(MouseEventArgs e, bool useStartMouseClickPosition = true) {
double newValue;
if (useStartMouseClickPosition) {
currentMousePosition.X = e.X - startMouseClickPosition.X;
// works correctly
newValue = Maximum * (currentMousePosition.X - (ThumbSize.Width / 2) + (ThumbSize.Width / 2) - PaddingLR)
/ (Width - ThumbSize.Width - PaddingLR * 2);
} else {
newValue = Maximum * (e.X - ThumbSize.Width / 2 - PaddingLR)
/ (Width - ThumbSize.Width - PaddingLR * 2);
}
// does NOT work correctly (although the calculation result is the same)
//double newValue = Maximum * (newThumbLeft + (ThumbSize.Width / 2) - PaddingLR) /
// (Width - ThumbSize.Width - PaddingLR * 2);
Value = Math.Max(0, Math.Min(Maximum, newValue));
}
public void OnScroll() {
ValueChanged?.Invoke(this, EventArgs.Empty);
}
#endregion
#region Отрисовка элементов управления
protected override void OnPaint(PaintEventArgs e) {
ThumbRect = new Rectangle(
Convert.ToInt32(Value * (Width - ThumbSize.Width - Padding.Left * 2) / Maximum + Padding.Right),
0 + Padding.Top,
ThumbSize.Width, // fixed slider width
Height - Padding.Bottom - Padding.Top // dynamic slider height
// (example) Height - 4, means to move the slider by 2 px above and below
);
// Filling the scroll bar
using (SolidBrush brush = new SolidBrush(TrackBackColor)) {
e.Graphics.FillRectangle(brush, new Rectangle(0, 0, Width, Height));
}
// The colored line in front of the slider
using (Pen pen = new Pen(TrackBorderColor2, TrackThickness)) {
e.Graphics.DrawLine(pen, Padding.Left, Height / 2, Width - Padding.Right, Height / 2);
}
// The colored line following the slider
using (Pen pen = new Pen(TrackBorderColor, TrackThickness)) {
e.Graphics.DrawLine(pen, Padding.Left, Height / 2, ThumbRect.Right, Height / 2);
}
// Filling the slider
using (SolidBrush brush2 = new SolidBrush(Color.FromArgb(100, 0, 0, 0))) {
e.Graphics.FillRectangle(brush2, ThumbRect);
}
}
#endregion
}
Thanks to the help of user #IVSoftware, in writing auxiliary methods calcValueFromPosition() and calcXfromValue(), the following solution was obtained, which allows you to set different paddings:
[Code Custom Trackbar]
namespace Handy_UI.Controls.Trackbars {
[DefaultEvent("ValueChanged")]
public class HandyHTrackbarWorked : Control {
#region Setting the initial parameters
public HandyHTrackbarWorked() {
SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint
| ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw, true); UpdateStyles();
Size = new Size(250, 12);
ThumbSize = new Size(15, 12);
}
#endregion
#region Main features
private double _value;
public double Value {
get { return _value; }
set {
_value = value;
OnScroll(); Refresh();
}
}
private double minimum;
public double Minimum {
get { return minimum; }
set { minimum = value; Invalidate(); }
}
private double maximum = 100;
public double Maximum {
get { return maximum; }
set { maximum = value; Invalidate(); }
}
private double smallStep = 1;
public double SmallStep {
get { return smallStep; }
set {
smallStep = (value > 0) ? value : 1;
}
}
#endregion
#region Properties responsible for design
private Size thumbSize;
public Size ThumbSize {
get { return thumbSize; }
set {
thumbSize = value;
Invalidate();
}
}
private Color thumbBackColor = Color.FromArgb(255, 255, 255);
public Color ThumbBackColor {
get { return thumbBackColor; }
set { thumbBackColor = value; Invalidate(); }
}
private Color trackBackColor = Color.Transparent;
public Color TrackBackColor {
get { return trackBackColor; }
set { trackBackColor = value; Invalidate(); }
}
private Color trackBorderColor = Color.FromArgb(221, 0, 49);
public Color TrackBorderColor {
get { return trackBorderColor; }
set { trackBorderColor = value; Invalidate(); }
}
private Color trackBorderColor2 = Color.FromArgb(64, 64, 64);
public Color TrackBorderColor2 {
get { return trackBorderColor2; }
set { trackBorderColor2 = value; Invalidate(); }
}
private int trackThickness = 2;
public int TrackThickness {
get { return trackThickness; }
set { trackThickness = value; Invalidate(); }
}
public new Padding Padding {
get { return base.Padding; }
set { base.Padding = value; Invalidate(); }
}
#endregion
#region Key Events
public event EventHandler ValueChanged;
#endregion
#region Обработчики событий
private Point startMouseClickPosition;
private Point currentMousePosition;
protected override void OnCreateControl() {
base.OnCreateControl();
this.MouseDown += (sender, e) => {
// When clicking on the ScrollBar, center the Thumb relative to the mouse cursor
if (!ThumbRect.Contains(e.Location)) {
MoveThumb(e, false);
}
// When clicking on Thumb, determine the startMouseClickPosition
if (ThumbRect.Contains(e.Location)) {
startMouseClickPosition.X = e.X - ThumbRect.Left; // OR ... - ThumbRect.X
ThumbBackColor = Color.Green;
}
};
this.MouseMove += (sender, e) => {
ThumbBackColor = ThumbRect.Contains(e.Location)
? ThumbBackColor = Color.Orange : ThumbBackColor = Color.Gray;
if (e.Button == MouseButtons.Left) {
ThumbBackColor = Color.Green; MoveThumb(e);
}
};
this.MouseLeave += (sender, e) => { ThumbBackColor = Color.Gray; };
//this.SizeChanged += (sender, e) => { TrackThickness = Height - Padding.Bottom - Padding.Top; };
}
private void MoveThumb(MouseEventArgs e, bool useStartMouseClickPosition = true) {
Point currentMousePosition = new Point(0, 0);
if (useStartMouseClickPosition) {
currentMousePosition.X = e.X - startMouseClickPosition.X + ThumbSize.Width / 2
- Padding.Right - (Padding.Left - Padding.Right);
} else currentMousePosition.X = e.X - Padding.Left;
Value = calcValueFromPosition(currentMousePosition);
}
private double calcValueFromPosition(Point e) {
var mouseRange = Width - (Padding.Left + Padding.Right);
var pct = e.X / (double)mouseRange;
var controlRange = Maximum - Minimum;
var relative = pct * controlRange;
var value = Minimum + relative;
value = Math.Max(Minimum, value);
value = Math.Min(Maximum, value);
return value;
}
public void OnScroll() {
ValueChanged?.Invoke(this, EventArgs.Empty);
}
#endregion
#region Drawing controls
public int calcXfromValue() {
var range = Maximum - Minimum;
var relative = Value - Minimum;
var pct = relative / range;
var width = Width - (Padding.Left + Padding.Right);
var pos = pct * width;
var x = pos + Padding.Left - (ThumbSize.Width / 2);
if (x < 0 + Padding.Left) x = 0 + Padding.Left;
else if (x > Width - ThumbSize.Width - Padding.Right) x = Width - ThumbSize.Width - Padding.Right;
return (int)x;
}
public Rectangle ThumbRect => new Rectangle(
x: calcXfromValue(), y: 0 + Padding.Top,
width: ThumbSize.Width, // fixed slider width
height: Height - Padding.Bottom - Padding.Top // dynamic slider width
);
protected override void OnPaint(PaintEventArgs e) {
// Filling the scroll bar
using (SolidBrush brush = new SolidBrush(TrackBackColor)) {
e.Graphics.FillRectangle(brush, new Rectangle(0, 0, Width, Height));
}
// The colored line in front of the slider
using (Pen pen = new Pen(TrackBorderColor2, TrackThickness)) {
e.Graphics.DrawLine(pen, Padding.Left, Height / 2, Width - Padding.Right, Height / 2);
}
// The colored line following the slider
using (Pen pen = new Pen(TrackBorderColor, TrackThickness)) {
e.Graphics.DrawLine(pen, Padding.Left, Height / 2, ThumbRect.Right, Height / 2);
}
// Filling the slider
using (SolidBrush brush2 = new SolidBrush(Color.FromArgb(100, 0, 0, 0))) {
e.Graphics.FillRectangle(brush2, ThumbRect);
}
}
#endregion
}
}
I'm using MaterialSkin UI controls , how can I change the control properties to Right to left, because it's by default Left to Right.
I think this is the code should be edited :
private void UpdateTabRects()
{
_tabRects = new List<Rectangle>();
//If there isn't a base tab control, the rects shouldn't be calculated
//If there aren't tab pages in the base tab control, the list should just be empty which has been set already; exit the void
if (_baseTabControl == null || _baseTabControl.TabCount == 0) return;
//Calculate the bounds of each tab header specified in the base tab control
using (var b = new Bitmap(1, 1))
{
using (var g = Graphics.FromImage(b))
{
_tabRects.Add(new Rectangle(SkinManager.FormPadding, 0, TabHeaderPadding * 2 + (int)g.MeasureString(_baseTabControl.TabPages[0].Text, SkinManager.Font_Size11).Width, Height));
for (int i = 1; i < _baseTabControl.TabPages.Count; i++)
{
_tabRects.Add(new Rectangle(_tabRects[i - 1].Right, 0, TabHeaderPadding * 2 + (int)g.MeasureString(_baseTabControl.TabPages[i].Text , SkinManager.Font_Size11).Width , Height));
}
}
}
}
and this is the full code for the control :
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Text;
using System.Windows.Forms;
using MaterialSkin.Animations;
namespace MaterialSkin.Controls
{
public class MaterialTabSelector : Control, IMaterialControl
{
[Browsable(false)]
public int Depth { get; set; }
[Browsable(false)]
public MaterialSkinManager SkinManager => MaterialSkinManager.Instance;
[Browsable(false)]
public MouseState MouseState { get; set; }
private MaterialTabControl _baseTabControl;
public MaterialTabControl BaseTabControl
{
get { return _baseTabControl; }
set
{
_baseTabControl = value;
if (_baseTabControl == null) return;
_previousSelectedTabIndex = _baseTabControl.SelectedIndex;
_baseTabControl.Deselected += (sender, args) =>
{
_previousSelectedTabIndex = _baseTabControl.SelectedIndex;
};
_baseTabControl.SelectedIndexChanged += (sender, args) =>
{
_animationManager.SetProgress(0);
_animationManager.StartNewAnimation(AnimationDirection.In);
};
_baseTabControl.ControlAdded += delegate
{
Invalidate();
};
_baseTabControl.ControlRemoved += delegate
{
Invalidate();
};
}
}
private int _previousSelectedTabIndex;
private Point _animationSource;
private readonly AnimationManager _animationManager;
private List<Rectangle> _tabRects;
private const int TabHeaderPadding = 24;
private const int TabIndicatorHeight = 2;
public MaterialTabSelector()
{
SetStyle(ControlStyles.DoubleBuffer | ControlStyles.OptimizedDoubleBuffer, true);
Height = 48;
_animationManager = new AnimationManager
{
AnimationType = AnimationType.EaseOut,
Increment = 0.04
};
_animationManager.OnAnimationProgress += sender => Invalidate();
}
protected override void OnPaint(PaintEventArgs e)
{
var g = e.Graphics;
g.TextRenderingHint = TextRenderingHint.AntiAlias;
g.Clear(SkinManager.ColorScheme.PrimaryColor);
if (_baseTabControl == null) return;
if (!_animationManager.IsAnimating() || _tabRects == null || _tabRects.Count != _baseTabControl.TabCount)
UpdateTabRects();
var animationProgress = _animationManager.GetProgress();
//Click feedback
if (_animationManager.IsAnimating())
{
var rippleBrush = new SolidBrush(Color.FromArgb((int)(51 - (animationProgress * 50)), Color.White));
var rippleSize = (int)(animationProgress * _tabRects[_baseTabControl.SelectedIndex].Width * 1.75);
g.SetClip(_tabRects[_baseTabControl.SelectedIndex]);
g.FillEllipse(rippleBrush, new Rectangle(_animationSource.X - rippleSize / 2, _animationSource.Y - rippleSize / 2, rippleSize, rippleSize));
g.ResetClip();
rippleBrush.Dispose();
}
//Draw tab headers
foreach (TabPage tabPage in _baseTabControl.TabPages)
{
var currentTabIndex = _baseTabControl.TabPages.IndexOf(tabPage);
Brush textBrush = new SolidBrush(Color.FromArgb(CalculateTextAlpha(currentTabIndex, animationProgress), SkinManager.ColorScheme.TextColor));
g.DrawString(tabPage.Text.ToUpper(), SkinManager.Font_Size11, textBrush, _tabRects[currentTabIndex], new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
textBrush.Dispose();
}
//Animate tab indicator
var previousSelectedTabIndexIfHasOne = _previousSelectedTabIndex == -1 ? _baseTabControl.SelectedIndex : _previousSelectedTabIndex;
var previousActiveTabRect = _tabRects[previousSelectedTabIndexIfHasOne];
var activeTabPageRect = _tabRects[_baseTabControl.SelectedIndex];
var y = activeTabPageRect.Bottom - 2;
var x = previousActiveTabRect.X + (int)((activeTabPageRect.X - previousActiveTabRect.X) * animationProgress);
var width = previousActiveTabRect.Width + (int)((activeTabPageRect.Width - previousActiveTabRect.Width) * animationProgress);
g.FillRectangle(SkinManager.ColorScheme.AccentBrush, x, y, width, TabIndicatorHeight);
}
private int CalculateTextAlpha(int tabIndex, double animationProgress)
{
int primaryA = SkinManager.ActionBarText.A;
int secondaryA = SkinManager.ActionBarTextSecondary.A;
if (tabIndex == _baseTabControl.SelectedIndex && !_animationManager.IsAnimating())
{
return primaryA;
}
if (tabIndex != _previousSelectedTabIndex && tabIndex != _baseTabControl.SelectedIndex)
{
return secondaryA;
}
if (tabIndex == _previousSelectedTabIndex)
{
return primaryA - (int)((primaryA - secondaryA) * animationProgress);
}
return secondaryA + (int)((primaryA - secondaryA) * animationProgress);
}
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
if (_tabRects == null) UpdateTabRects();
for (var i = 0; i < _tabRects.Count; i++)
{
if (_tabRects[i].Contains(e.Location))
{
_baseTabControl.SelectedIndex = i;
}
}
_animationSource = e.Location;
}
private void UpdateTabRects()
{
_tabRects = new List<Rectangle>();
//If there isn't a base tab control, the rects shouldn't be calculated
//If there aren't tab pages in the base tab control, the list should just be empty which has been set already; exit the void
if (_baseTabControl == null || _baseTabControl.TabCount == 0) return;
//Calculate the bounds of each tab header specified in the base tab control
using (var b = new Bitmap(1, 1))
{
using (var g = Graphics.FromImage(b))
{
_tabRects.Add(new Rectangle(SkinManager.FormPadding, 0, TabHeaderPadding * 2 + (int)g.MeasureString(_baseTabControl.TabPages[0].Text, SkinManager.Font_Size11).Width, Height));
for (int i = 1; i < _baseTabControl.TabPages.Count; i++)
{
_tabRects.Add(new Rectangle(_tabRects[i - 1].Right, 0, TabHeaderPadding * 2 + (int)g.MeasureString(_baseTabControl.TabPages[i].Text , SkinManager.Font_Size11).Width , Height));
}
}
}
}
}
}
If you're using windows forms you would go into the properties of the tab control and make:
RightToLeft = Yes
and
RightToLeftLayout = True.
This is also a duplicate question:
How to make Managed Tab Control (MTC) appear right to left
I am working on a project wherein I need to add a Control with the shape of a Circle with some text in the middle.
My problem is the circle is too small, when I resize it, it overlaps other controls. I want to draw the circle same width as the square.
Otherwise. how can I make the Control's background transparent?
I am using the code below:
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
using (Bitmap bitmap = new Bitmap(this.Width, this.Height))
{
using (Graphics graphics = Graphics.FromImage(bitmap))
{
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.Clear(this.BackColor);
using (SolidBrush brush = new SolidBrush(this._FillColor))
{
graphics.FillEllipse(brush, 0x18 - 6, 0x18 - 6, (this.Width - 0x30) + 12, (this.Height - 0x30) + 12);
}
Brush FontColor = new SolidBrush(this.ForeColor);
SizeF MS = graphics.MeasureString(Convert.ToString(Convert.ToInt32((100 / _Maximum) * _Value)), Font);
graphics.DrawString(Convert.ToString(Convert.ToInt32((100 / _Maximum) * _Value)), Font, FontColor, Convert.ToInt32((Width / 2 - MS.Width / 2) + 2), Convert.ToInt32((Height / 2 - MS.Height / 2) + 3));
bitmap.MakeTransparent(this.BackColor);
e.Graphics.DrawImage(bitmap, 0, 0);
graphics.Dispose();
bitmap.Dispose();
}
}
}
This is a Custom Control derived from Control, which can be made translucent.
The interface is a colored circle which can contain a couple of numbers.
The Control exposes these custom properties:
Opacity: The level of opacity of the control BackGround [0, 255]
InnerPadding: The distance between the inner rectangle, which defines the circle bounds and the control bounds.
FontPadding: The distance between the Text and the Inner rectangle.
Transparency is obtained overriding CreateParams, then setting ExStyle |= WS_EX_TRANSPARENT;
The Control.SetStyle() method is used to modify the control behavior, adding these ControlStyles:
▶ ControlStyles.Opaque: prevents the painting of a Control's BackGround, so it's not managed by the System. Combined with CreateParams to set the Control's Extended Style to WS_EX_TRANSPARENT, the Control becomes completely transparent.
▶ ControlStyles.SupportsTransparentBackColor the control accepts Alpha values for it's BackGround color. Without also setting ControlStyles.UserPaint it won't be used to simulate transparency. We're doing that ourselves with other means.
To see it at work, create a new Class file, substitute all the code inside with this code preserving the NameSpace and build the Project/Solution.
The new Custom Control will appear in the ToolBox. Drop it on a Form. Modify its custom properties as needed.
A visual representation of the control:
Note and disclaimer:
This is a prototype Control, the custom Designer is missing (cannot post that here, too much code, also connected to a framework).
As presented here, it can be used to completely overlap other Controls in a Form or other containers. Partial overlapping is not handled in this simplified implementation.
The Font is hard-coded to Segoe UI, since this Font has a base-line that simplifies the position of the text in the middle of the circular area.
Other Fonts have a different base-line, which requires more complex handling.
See: TextBox with dotted lines for typing for the base math.
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Windows.Forms;
[DesignerCategory("Code")]
public class RoundCenterLabel : Label, INotifyPropertyChanged, ISupportInitialize
{
private const int WS_EX_TRANSPARENT = 0x00000020;
private bool IsInitializing = false;
private Point MouseDownLocation = Point.Empty;
private readonly int fontPadding = 4;
private Font m_CustomFont = null;
private Color m_BackGroundColor;
private int m_InnerPadding = 0;
private int m_FontPadding = 25;
private int m_Opacity = 128;
public event PropertyChangedEventHandler PropertyChanged;
public RoundCenterLabel() => InitializeComponent();
private void InitializeComponent()
{
SetStyle(ControlStyles.Opaque |
ControlStyles.SupportsTransparentBackColor |
ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, false);
m_CustomFont = new Font("Segoe UI", 50, FontStyle.Regular, GraphicsUnit.Pixel);
BackColor = Color.LimeGreen;
ForeColor = Color.White;
}
protected override CreateParams CreateParams {
get {
var cp = base.CreateParams;
cp.ExStyle |= WS_EX_TRANSPARENT;
return cp;
}
}
public new Font Font
{
get => m_CustomFont;
set {
m_CustomFont = value;
if (IsInitializing) return;
FontAdapter(value, DeviceDpi);
NotifyPropertyChanged();
}
}
public override string Text {
get => base.Text;
set { base.Text = value;
NotifyPropertyChanged();
}
}
public int InnerPadding {
get => m_InnerPadding;
set {
if (IsInitializing) return;
m_InnerPadding = ValidateRange(value, 0, ClientRectangle.Height - 10);
NotifyPropertyChanged(); }
}
public int FontPadding {
get => m_FontPadding;
set {
if (IsInitializing) return;
m_FontPadding = ValidateRange(value, 0, ClientRectangle.Height - 10);
NotifyPropertyChanged();
}
}
public int Opacity {
get => m_Opacity;
set { m_Opacity = ValidateRange(value, 0, 255);
UpdateBackColor(m_BackGroundColor);
NotifyPropertyChanged();
}
}
public override Color BackColor {
get => m_BackGroundColor;
set { UpdateBackColor(value);
NotifyPropertyChanged();
}
}
protected override void OnLayout(LayoutEventArgs e)
{
base.OnLayout(e);
base.AutoSize = false;
}
private void NotifyPropertyChanged([CallerMemberName] string PropertyName = null)
{
InvalidateParent();
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
}
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
MouseDownLocation = e.Location;
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if (e.Button == MouseButtons.Left) {
var loc = new Point(Left + (e.X - MouseDownLocation.X), Top + (e.Y - MouseDownLocation.Y));
InvalidateParent();
BeginInvoke(new Action(() => Location = loc));
}
}
private void InvalidateParent()
{
Parent?.Invalidate(Bounds, true);
Invalidate();
}
protected override void OnPaint(PaintEventArgs e)
{
using (var format = new StringFormat(StringFormatFlags.LineLimit | StringFormatFlags.NoWrap, CultureInfo.CurrentUICulture.LCID))
{
format.LineAlignment = StringAlignment.Center;
format.Alignment = StringAlignment.Center;
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
using (var circleBrush = new SolidBrush(m_BackGroundColor))
using (var foreBrush = new SolidBrush(ForeColor))
{
FontAdapter(m_CustomFont, e.Graphics.DpiY);
RectangleF rect = InnerRectangle();
e.Graphics.FillEllipse(circleBrush, rect);
e.Graphics.DrawString(Text, m_CustomFont, foreBrush, rect, format);
};
};
}
public void BeginInit() => IsInitializing = true;
public void EndInit()
{
IsInitializing = false;
Font = new Font("Segoe UI", 50, FontStyle.Regular, GraphicsUnit.Pixel);
FontPadding = m_FontPadding;
InnerPadding = m_InnerPadding;
}
private RectangleF InnerRectangle()
{
(float Min, _) = GetMinMax(ClientRectangle.Height, ClientRectangle.Width);
var size = new SizeF(Min - (m_InnerPadding / 2), Min - (m_InnerPadding / 2));
var position = new PointF((ClientRectangle.Width - size.Width) / 2,
(ClientRectangle.Height - size.Height) / 2);
return new RectangleF(position, size);
}
private void FontAdapter(Font font, float dpi)
{
RectangleF rect = InnerRectangle();
float fontSize = ValidateRange(
(int)(rect.Height - m_FontPadding), 6,
(int)(rect.Height - m_FontPadding)) / (dpi / 72.0F) - fontPadding;
m_CustomFont.Dispose();
m_CustomFont = new Font(font.FontFamily, fontSize, font.Style, GraphicsUnit.Pixel);
}
private void UpdateBackColor(Color color)
{
m_BackGroundColor = Color.FromArgb(m_Opacity, Color.FromArgb(color.R, color.G, color.B));
base.BackColor = m_BackGroundColor;
}
private int ValidateRange(int Value, int Min, int Max)
=> Math.Max(Math.Min(Value, Max), Min); // (Value < Min) ? Min : ((Value > Max) ? Max : Value);
private (float, float) GetMinMax(float Value1, float Value2)
=> (Math.Min(Value1, Value2), Math.Max(Value1, Value2));
}
public static Boolean TextBoxValidation(TextBox txt, String AdditionalMsg)
{
if (txt.Text.Trim() == "")
{
MessageBox.Show("Please Enter " + AdditionalMsg);
return false;
}
return true;
}
This is my code; when the user does not fill some entry then a message is shown. I want something more creative: when the user does not fill some entry into the textbox, a red border blinks around my textbox and a message is shown to user just like a tooltip.
Refer to the picture I have uploaded:
I kind of wanted something like that for a while and this is what I come up with:
Since you can't set border color for TextBox, I made a UserControl with textbox inside:
public partial class UCTextBoxCustomcs : UserControl
{
private ToolTip _errorToolTip;
// keep original background color so you can change it when txet value is OK
private Color _orgBgColor;
public new Color BackColor
{
get { return _orgBgColor; }
set
{
base.BackColor = value;
_orgBgColor = value;
}
}
public new string Text
{
get { return this.txbContent.Text; }
set { this.txbContent.Text = value; }
}
public Color InvalidBgColor { get; set; }
private bool _IsValid;
public bool IsValid
{
get { return _IsValid; }
set
{
_IsValid = value;
if (value)
{
base.BackColor = _orgBgColor;
_errorToolTip.SetToolTip(this.txbContent, "");
_errorToolTip.ShowAlways = false;
_errorToolTip.Hide(this.txbContent);
}
else
{
base.BackColor = InvalidBgColor;
_errorToolTip.ShowAlways = true;
this._errorToolTip.BackColor = InvalidBgColor;
_errorToolTip.Show(this.ErrorText, this.txbContent,this.txbContent.Width +3 ,0);
}
}
}
private string _ErrorText;
public string ErrorText
{
get
{
return _ErrorText;
}
set
{
_ErrorText = value;
if (value == null || value.Length == 0) IsValid = true;
else IsValid = false;
}
}
public UCTextBoxCustomcs()
{
this._errorToolTip = new ToolTip();
// BackColor in ToolTip is ignored, so if you want to change it,
// you have to draw it yourself
this._errorToolTip.OwnerDraw = true;
_errorToolTip.Draw += new DrawToolTipEventHandler(_errorToolTip_Draw);
_errorToolTip.Popup += new PopupEventHandler(_errorToolTip_Popup);
// white background so it looks like TextBox
this.BackColor = Color.White;
InitializeComponent();
this.txbContent.BorderStyle = BorderStyle.None;
// Intelisense tells you this property isn't there, but it is
// you have to set it to false so TextBox height can be changed
// when MultiLine is set to false
this.txbContent.AutoSize = false;
this.txbContent.Multiline = false;
// Leave 1 pixel around TextBox for pseudo-border
this.Padding = new Padding(1);
this.txbContent.Dock = DockStyle.Fill;
this.InvalidBgColor = Color.Red;
this.IsValid = true;
}
void _errorToolTip_Popup(object sender, PopupEventArgs e)
{
using (Font f = new Font("Calibri", 9))
{
Size ttSize = TextRenderer.MeasureText(
_errorToolTip.GetToolTip(e.AssociatedControl), f);
e.ToolTipSize = new Size(ttSize.Width + 6, ttSize.Height + 6);
}
}
void _errorToolTip_Draw(object sender, DrawToolTipEventArgs e)
{
// In this case a simple rectangle is drawn, but you can draw whatever you want
// Draw the custom background.
e.Graphics.FillRectangle(new SolidBrush(this.InvalidBgColor), e.Bounds);
// Draw the standard border.
e.DrawBorder();
// Draw the custom text.
// The using block will dispose the StringFormat automatically.
using (StringFormat sf = new StringFormat())
{
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
sf.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.None;
sf.FormatFlags = StringFormatFlags.NoWrap;
using (Font f = new Font("Calibri", 9))
{
Rectangle textBounds = new Rectangle(
e.Bounds.Left+3,
e.Bounds.Top+3,
e.Bounds.Width-6,
e.Bounds.Height-6);
e.Graphics.DrawString(e.ToolTipText, f,
SystemBrushes.ActiveCaptionText, e.Bounds, sf);
}
}
}
protected override void OnValidating(CancelEventArgs e)
{
this.ValidateChildren();
base.OnValidating(e);
}
}
How to use:
private void ucTextBoxCustomcs1_Validating(object sender, CancelEventArgs e)
{
if (ucTextBoxCustomcs1.Text.Length == 0)
{
ucTextBoxCustomcs1.ErrorText = "Cant be empty";
}
else ucTextBoxCustomcs1.ErrorText = null;
}
It looks like this:
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
}
}
}