diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..882434f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,34 @@
+# Visual Studio crap
+Release
+bin
+obj
+*.ncb
+*.vcproj*
+*.suo
+*.user
+*.sln.cache
+
+
+#binary stuff
+!*.dll
+*.pdb
+*.mdb
+*.exe
+
+# backup files by various editors
+*~
+*.orig
+
+#monodevelop
+*.pidb
+*.userprefs
+
+# osx crap
+.DS_Store
+
+# more crap
+_ReSharper.*
+
+
+*.config
+# *.resources
\ No newline at end of file
diff --git a/RangeBar/RangeBar.sln b/RangeBar/RangeBar.sln
new file mode 100644
index 0000000..82b8609
--- /dev/null
+++ b/RangeBar/RangeBar.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30611.23
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UserControllerLib", "RangeBar\UserControllerLib.csproj", "{134EA45A-DAF8-4B73-83A8-6EF89E26D635}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {134EA45A-DAF8-4B73-83A8-6EF89E26D635}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {134EA45A-DAF8-4B73-83A8-6EF89E26D635}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {134EA45A-DAF8-4B73-83A8-6EF89E26D635}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {134EA45A-DAF8-4B73-83A8-6EF89E26D635}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {DC80DC3E-7189-4607-9A10-33C7AED0925F}
+ EndGlobalSection
+EndGlobal
diff --git a/RangeBar/RangeBar/Properties/AssemblyInfo.cs b/RangeBar/RangeBar/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..8d0047c
--- /dev/null
+++ b/RangeBar/RangeBar/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 有关程序集的一般信息由以下
+// 控制。更改这些特性值可修改
+// 与程序集关联的信息。
+[assembly: AssemblyTitle("RangeBar")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("RangeBar")]
+[assembly: AssemblyCopyright("Copyright © 2021")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 将 ComVisible 设置为 false 会使此程序集中的类型
+//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
+//请将此类型的 ComVisible 特性设置为 true。
+[assembly: ComVisible(false)]
+
+// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
+[assembly: Guid("134ea45a-daf8-4b73-83a8-6ef89e26d635")]
+
+// 程序集的版本信息由下列四个值组成:
+//
+// 主版本
+// 次版本
+// 生成号
+// 修订号
+//
+//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
+//通过使用 "*",如下所示:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/RangeBar/RangeBar/RangeBar.Designer.cs b/RangeBar/RangeBar/RangeBar.Designer.cs
new file mode 100644
index 0000000..1ae0551
--- /dev/null
+++ b/RangeBar/RangeBar/RangeBar.Designer.cs
@@ -0,0 +1,4 @@
+namespace RangeBar
+{
+
+}
diff --git a/RangeBar/RangeBar/RangeBar.cs b/RangeBar/RangeBar/RangeBar.cs
new file mode 100644
index 0000000..90d1e14
--- /dev/null
+++ b/RangeBar/RangeBar/RangeBar.cs
@@ -0,0 +1,687 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace RangeBar
+{
+ public class RangeBar : UserControl
+ {
+ // delegate to handle range changed
+ public delegate void RangeChangedEventHandler(object sender, EventArgs e);
+
+ // delegate to handle range is changing
+ public delegate void RangeChangingEventHandler(object sender, EventArgs e);
+
+
+ ///
+ /// designer variable
+ ///
+ private System.ComponentModel.Container components = null;
+
+ public RangeBar()
+ {
+ InitializeComponent();
+ }
+
+ ///
+ /// Clean up the resources used.
+ ///
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ if (components != null)
+ {
+ components.Dispose();
+ }
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+ private void InitializeComponent()
+ {
+ //
+ // RangeBar
+ //
+ this.Name = "RangeBar";
+ this.Size = new System.Drawing.Size(344, 64);
+ this.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.OnKeyPress);
+ this.Resize += new System.EventHandler(this.OnResize);
+ this.Load += new System.EventHandler(this.OnLoad);
+ this.SizeChanged += new System.EventHandler(this.OnSizeChanged);
+ this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.OnMouseUp);
+ this.Paint += new System.Windows.Forms.PaintEventHandler(this.OnPaint);
+ this.Leave += new System.EventHandler(this.OnLeave);
+ this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.OnMouseMove);
+ this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.OnMouseDown);
+
+ }
+ #endregion
+
+ public enum ActiveMarkType { none, left, right };
+ public enum TopBottomOrientation { top, bottom, both };
+
+ private Color colorInner = Color.DarkGray;
+ private Color colorRange = Color.FromKnownColor(KnownColor.MenuHighlight);
+ private Color colorEdgeLight = Color.FromKnownColor(KnownColor.ControlLightLight);
+ private Color colorEdgeDark = Color.FromKnownColor(KnownColor.ScrollBar);
+ private int sizeEdge = 1;
+ private double Minimum = 0;
+ private double Maximum = 10;
+ private double rangeMin = 0;
+ private double rangeMax = 0;
+ private ActiveMarkType ActiveMark = ActiveMarkType.none;
+
+
+ private TopBottomOrientation orientationScale = TopBottomOrientation.bottom;
+ private int BarHeight = 8; // Height of Bar
+ private int MarkWidth = 8; // Width of mark
+ private int MarkHeight = 24; // total height of mark
+ private int TickHeight = 6; // Height of axis tick
+ private int numAxisDivision = 10;
+
+ private int PosL = 0, PosR = 0; // Pixel-Position of mark buttons
+ private int XPosMin, XPosMax;
+
+ private Point[] LMarkPnt = new Point[5];
+ private Point[] RMarkPnt = new Point[5];
+
+ private bool MoveLMark = false;
+ private bool MoveRMark = false;
+
+ //------------------------------------
+ // Properties
+ //------------------------------------
+
+ ///
+ /// set or get tick height
+ ///
+ public int HeightOfTick
+ {
+ set
+ {
+ TickHeight = Math.Min(Math.Max(0, value), BarHeight);
+ Invalidate();
+ Update();
+ }
+ get
+ {
+ return TickHeight;
+ }
+ }
+
+ ///
+ /// set or get mark height
+ ///
+ public int HeightOfMark
+ {
+ set
+ {
+ MarkHeight = Math.Max(BarHeight + 2, value);
+ Invalidate();
+ Update();
+ }
+ get
+ {
+ return MarkHeight;
+ }
+ }
+
+
+ ///
+ /// set/get height of mark
+ ///
+ public int HeightOfBar
+ {
+ set
+ {
+ BarHeight = Math.Min(value, MarkHeight - 2);
+ Invalidate();
+ Update();
+ }
+ get
+ {
+ return BarHeight;
+ }
+
+ }
+
+
+ ///
+ /// set or get scale orientation
+ ///
+ public TopBottomOrientation ScaleOrientation
+ {
+ set
+ {
+ orientationScale = value;
+ Invalidate();
+ Update();
+ }
+ get
+ {
+ return orientationScale;
+ }
+ }
+
+ ///
+ /// set or get right side of range
+ ///
+ public int RangeMaximum
+ {
+ set
+ {
+ rangeMax = (double)value;
+ if (rangeMax < Minimum)
+ rangeMax = Minimum;
+ else if (rangeMax > Maximum)
+ rangeMax = Maximum;
+ if (rangeMax < rangeMin)
+ rangeMax = rangeMin;
+ Range2Pos();
+ Invalidate(true);
+ }
+ get { return (int)rangeMax; }
+ }
+
+
+ ///
+ /// set or get left side of range
+ ///
+ public int RangeMinimum
+ {
+ set
+ {
+ rangeMin = (double)value;
+ if (rangeMin < Minimum)
+ rangeMin = Minimum;
+ else if (rangeMin > Maximum)
+ rangeMin = Maximum;
+ if (rangeMin > rangeMax)
+ rangeMin = rangeMax;
+ Range2Pos();
+ Invalidate(true);
+ }
+ get
+ {
+ return (int)rangeMin;
+ }
+ }
+
+
+ ///
+ /// set or get right side of total range
+ ///
+ public int TotalMaximum
+ {
+ set
+ {
+ Maximum = (double)value;
+ if (rangeMax > Maximum)
+ rangeMax = Maximum;
+ Range2Pos();
+ Invalidate(true);
+ }
+ get { return (int)Maximum; }
+ }
+
+
+ ///
+ /// set or get left side of total range
+ ///
+ public int TotalMinimum
+ {
+ set
+ {
+ Minimum = (double)value;
+ if (rangeMin < Minimum)
+ rangeMin = Minimum;
+ Range2Pos();
+ Invalidate(true);
+ }
+ get { return (int)Minimum; }
+ }
+
+
+ ///
+ /// set or get number of divisions
+ ///
+ public int DivisionNum
+ {
+ set
+ {
+ numAxisDivision = value;
+ Refresh();
+ }
+ get { return numAxisDivision; }
+ }
+
+
+ ///
+ /// set or get color of inner range
+ ///
+ public Color InnerColor
+ {
+ set
+ {
+ colorInner = value;
+ Refresh();
+ }
+ get { return colorInner; }
+ }
+
+
+ ///
+ /// set selected range
+ ///
+ /// left side of range
+ /// right side of range
+ public void SelectRange(int left, int right)
+ {
+ RangeMinimum = left;
+ RangeMaximum = right;
+ Range2Pos();
+ Invalidate(true);
+ }
+
+
+ ///
+ /// set range limits
+ ///
+ /// left side of range limit
+ /// right side of range limit
+ public void SetRangeLimit(double left, double right)
+ {
+ Minimum = left;
+ Maximum = right;
+ Range2Pos();
+ Invalidate(true);
+ }
+
+
+ // paint event reaction
+ private void OnPaint(object sender, System.Windows.Forms.PaintEventArgs e)
+ {
+ int h = this.Height;
+ int w = this.Width;
+ int baryoff, markyoff, tickyoff1, tickyoff2;
+ double dtick;
+ int tickpos;
+ Pen penRange = new Pen(colorRange);
+ Pen penEdgeLight = new Pen(colorEdgeLight);
+ Pen penEdgeDark = new Pen(colorEdgeDark);
+ SolidBrush brushEdgeLight = new SolidBrush(colorEdgeLight);
+ SolidBrush brushEdgeDark = new SolidBrush(colorEdgeDark);
+ SolidBrush brushInner;
+ SolidBrush brushRange;
+
+ if (this.Enabled == true)
+ {
+ brushInner = new SolidBrush(colorInner);
+ brushRange = new SolidBrush(colorRange);
+ }
+ else
+ {
+ brushInner = new SolidBrush(colorInner);
+ brushRange = new SolidBrush(Color.FromKnownColor(KnownColor.ControlDark));
+ }
+
+
+ // range
+ XPosMin = MarkWidth + 1;
+ XPosMax = w - MarkWidth - 1;
+
+ // range check
+ if (PosL < XPosMin) PosL = XPosMin;
+ if (PosL > XPosMax) PosL = XPosMax;
+ if (PosR > XPosMax) PosR = XPosMax;
+ if (PosR < XPosMin) PosR = XPosMin;
+
+ Range2Pos();
+
+
+ // draw rangebar
+ baryoff = (h - BarHeight) / 2;
+ markyoff = baryoff + (BarHeight - MarkHeight) / 2 - 1;
+
+ // total range bar frame
+ e.Graphics.FillRectangle(brushEdgeDark, 0, baryoff, w - 1, sizeEdge); // top
+ e.Graphics.FillRectangle(brushEdgeDark, 0, baryoff, sizeEdge, BarHeight - 1); // left
+ e.Graphics.FillRectangle(brushEdgeDark, 0, baryoff + BarHeight - 1 - sizeEdge, w - 1, sizeEdge); // bottom
+ e.Graphics.FillRectangle(brushEdgeDark, w - 1 - sizeEdge, baryoff, sizeEdge, BarHeight - 1); // right
+
+
+ // inner region
+ e.Graphics.FillRectangle(brushInner, PosL, baryoff + sizeEdge, PosR - PosL, BarHeight - 1 - 2 * sizeEdge);
+
+ // scale
+ if (orientationScale == TopBottomOrientation.bottom)
+ {
+ tickyoff1 = tickyoff2 = baryoff + BarHeight + 2;
+ }
+ else if (orientationScale == TopBottomOrientation.top)
+ {
+ tickyoff1 = tickyoff2 = baryoff - TickHeight - 4;
+ }
+ else
+ {
+ tickyoff1 = baryoff + BarHeight + 2;
+ tickyoff2 = baryoff - TickHeight - 4;
+ }
+
+ if (numAxisDivision > 1)
+ {
+ dtick = (double)(XPosMax - XPosMin) / (double)numAxisDivision;
+ for (int i = 0; i < numAxisDivision + 1; i++)
+ {
+ tickpos = (int)Math.Round((double)i * dtick);
+ if (orientationScale == TopBottomOrientation.bottom
+ || orientationScale == TopBottomOrientation.both)
+ {
+ e.Graphics.DrawLine(penEdgeDark, MarkWidth + 1 + tickpos,
+ tickyoff1,
+ MarkWidth + 1 + tickpos,
+ tickyoff1 + TickHeight);
+ }
+ if (orientationScale == TopBottomOrientation.top
+ || orientationScale == TopBottomOrientation.both)
+ {
+ e.Graphics.DrawLine(penEdgeDark, MarkWidth + 1 + tickpos,
+ tickyoff2,
+ MarkWidth + 1 + tickpos,
+ tickyoff2 + TickHeight);
+ }
+ }
+ }
+
+ // left mark
+ LMarkPnt[0].X = PosL - MarkWidth; LMarkPnt[0].Y = markyoff;
+ LMarkPnt[1].X = PosL; LMarkPnt[1].Y = markyoff;
+ LMarkPnt[2].X = PosL; LMarkPnt[2].Y = markyoff + MarkHeight;
+ LMarkPnt[3].X = PosL - MarkWidth; LMarkPnt[3].Y = markyoff + 2 * MarkHeight / 3;
+ LMarkPnt[4].X = PosL - MarkWidth; LMarkPnt[4].Y = markyoff;
+ e.Graphics.FillPolygon(brushRange, LMarkPnt);
+
+ if (ActiveMark == ActiveMarkType.left)
+ {
+ e.Graphics.DrawLine(penEdgeLight, LMarkPnt[3].X - 1, LMarkPnt[3].Y, LMarkPnt[1].X - 1, LMarkPnt[2].Y); // lower left edge
+ e.Graphics.DrawLine(penEdgeLight, LMarkPnt[0].X - 1, LMarkPnt[0].Y, LMarkPnt[0].X - 1, LMarkPnt[3].Y); // left edge
+ e.Graphics.DrawLine(penEdgeLight, LMarkPnt[0].X - 1, LMarkPnt[0].Y, LMarkPnt[1].X - 1, LMarkPnt[1].Y); // upper edge
+ e.Graphics.DrawLine(penEdgeLight, LMarkPnt[1].X, LMarkPnt[1].Y + 1, LMarkPnt[1].X, LMarkPnt[2].Y); // right edge
+ }
+
+
+
+ // right mark
+ RMarkPnt[0].X = PosR + MarkWidth; RMarkPnt[0].Y = markyoff;
+ RMarkPnt[1].X = PosR; RMarkPnt[1].Y = markyoff;
+ RMarkPnt[2].X = PosR; RMarkPnt[2].Y = markyoff + MarkHeight;
+ RMarkPnt[3].X = PosR + MarkWidth; RMarkPnt[3].Y = markyoff + 2 * MarkHeight / 3;
+ RMarkPnt[4].X = PosR + MarkWidth; RMarkPnt[4].Y = markyoff;
+ e.Graphics.FillPolygon(brushRange, RMarkPnt);
+
+ if (ActiveMark == ActiveMarkType.right)
+ {
+ e.Graphics.DrawLine(penEdgeLight, RMarkPnt[1].X - 1, RMarkPnt[1].Y + 1, RMarkPnt[2].X - 1, RMarkPnt[2].Y); // left edge
+ e.Graphics.DrawLine(penEdgeLight, RMarkPnt[2].X, RMarkPnt[2].Y, RMarkPnt[3].X, RMarkPnt[3].Y); // lower right edge
+ e.Graphics.DrawLine(penEdgeLight, RMarkPnt[0].X, RMarkPnt[0].Y, RMarkPnt[1].X, RMarkPnt[1].Y); // upper edge
+ e.Graphics.DrawLine(penEdgeLight, RMarkPnt[0].X, RMarkPnt[0].Y + 1, RMarkPnt[3].X, RMarkPnt[3].Y); // right edge
+ }
+ }
+
+
+ // mouse down event
+ private void OnMouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
+ {
+ if (this.Enabled)
+ {
+ Rectangle LMarkRect = new Rectangle(
+ Math.Min(LMarkPnt[0].X, LMarkPnt[1].X), // X
+ Math.Min(LMarkPnt[0].Y, LMarkPnt[3].Y), // Y
+ Math.Abs(LMarkPnt[2].X - LMarkPnt[0].X), // width
+ Math.Max(Math.Abs(LMarkPnt[0].Y - LMarkPnt[3].Y), Math.Abs(LMarkPnt[0].Y - LMarkPnt[1].Y))); // height
+ Rectangle RMarkRect = new Rectangle(
+ Math.Min(RMarkPnt[0].X, RMarkPnt[2].X), // X
+ Math.Min(RMarkPnt[0].Y, RMarkPnt[1].Y), // Y
+ Math.Abs(RMarkPnt[0].X - RMarkPnt[2].X), // width
+ Math.Max(Math.Abs(RMarkPnt[2].Y - RMarkPnt[0].Y), Math.Abs(RMarkPnt[1].Y - RMarkPnt[0].Y))); // height
+
+ if (LMarkRect.Contains(e.X, e.Y))
+ {
+ this.Capture = true;
+ MoveLMark = true;
+ ActiveMark = ActiveMarkType.left;
+ Invalidate(true);
+ }
+
+ if (RMarkRect.Contains(e.X, e.Y))
+ {
+ this.Capture = true;
+ MoveRMark = true;
+ ActiveMark = ActiveMarkType.right;
+ Invalidate(true);
+ }
+ }
+ }
+
+
+ // mouse up event
+ private void OnMouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
+ {
+ if (this.Enabled)
+ {
+ this.Capture = false;
+
+ MoveLMark = false;
+ MoveRMark = false;
+
+ Invalidate();
+
+ OnRangeChanged(EventArgs.Empty);
+ }
+ }
+
+
+ // mouse move event
+ private void OnMouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
+ {
+ if (this.Enabled)
+ {
+ int h = this.Height;
+ int w = this.Width;
+ double r1 = (double)rangeMin * (double)w / (double)(Maximum - Minimum);
+ double r2 = (double)rangeMax * (double)w / (double)(Maximum - Minimum);
+ Rectangle LMarkRect = new Rectangle(
+ Math.Min(LMarkPnt[0].X, LMarkPnt[1].X), // X
+ Math.Min(LMarkPnt[0].Y, LMarkPnt[3].Y), // Y
+ Math.Abs(LMarkPnt[2].X - LMarkPnt[0].X), // width
+ Math.Max(Math.Abs(LMarkPnt[0].Y - LMarkPnt[3].Y), Math.Abs(LMarkPnt[0].Y - LMarkPnt[1].Y))); // height
+ Rectangle RMarkRect = new Rectangle(
+ Math.Min(RMarkPnt[0].X, RMarkPnt[2].X), // X
+ Math.Min(RMarkPnt[0].Y, RMarkPnt[1].Y), // Y
+ Math.Abs(RMarkPnt[0].X - RMarkPnt[2].X), // width
+ Math.Max(Math.Abs(RMarkPnt[2].Y - RMarkPnt[0].Y), Math.Abs(RMarkPnt[1].Y - RMarkPnt[0].Y))); // height
+
+ if (LMarkRect.Contains(e.X, e.Y) || RMarkRect.Contains(e.X, e.Y))
+ {
+ this.Cursor = Cursors.SizeWE;
+ }
+ else this.Cursor = Cursors.Arrow;
+
+ if (MoveLMark)
+ {
+ this.Cursor = Cursors.SizeWE;
+ PosL = e.X;
+ if (PosL < XPosMin)
+ PosL = XPosMin;
+ if (PosL > XPosMax)
+ PosL = XPosMax;
+ if (PosR < PosL)
+ PosR = PosL;
+ Pos2Range();
+ ActiveMark = ActiveMarkType.left;
+ Invalidate(true);
+
+ OnRangeChanging(EventArgs.Empty);
+ }
+ else if (MoveRMark)
+ {
+
+ this.Cursor = Cursors.SizeWE;
+ PosR = e.X;
+ if (PosR > XPosMax)
+ PosR = XPosMax;
+ if (PosR < XPosMin)
+ PosR = XPosMin;
+ if (PosL > PosR)
+ PosL = PosR;
+ Pos2Range();
+ ActiveMark = ActiveMarkType.right;
+ Invalidate(true);
+
+ OnRangeChanging(EventArgs.Empty);
+ }
+ }
+ }
+
+
+ ///
+ /// transform pixel position to range position
+ ///
+ private void Pos2Range()
+ {
+ int w;
+ int posw;
+
+ w = this.Width;
+
+ posw = w - 2 * MarkWidth - 2;
+
+ rangeMin = Minimum + (int)Math.Round((double)(Maximum - Minimum) * (double)(PosL - XPosMin) / (double)posw);
+ rangeMax = Minimum + (int)Math.Round((double)(Maximum - Minimum) * (double)(PosR - XPosMin) / (double)posw);
+ }
+
+
+ ///
+ /// transform range position to pixel position
+ ///
+ private void Range2Pos()
+ {
+ int w;
+ int posw;
+
+ w = this.Width;
+
+ posw = w - 2 * MarkWidth - 2;
+
+ PosL = XPosMin + (int)Math.Round((double)posw * (double)(rangeMin - Minimum) / (double)(Maximum - Minimum));
+ PosR = XPosMin + (int)Math.Round((double)posw * (double)(rangeMax - Minimum) / (double)(Maximum - Minimum));
+ }
+
+
+ ///
+ /// method to handle resize event
+ ///
+ /// object that sends event to resize
+ /// event parameter
+ private void OnResize(object sender, System.EventArgs e)
+ {
+ Invalidate(true);
+ }
+
+
+ ///
+ /// method to handle key pressed event
+ ///
+ /// object that sends key pressed event
+ /// event parameter
+ private void OnKeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
+ {
+ if (this.Enabled)
+ {
+ if (ActiveMark == ActiveMarkType.left)
+ {
+ if (e.KeyChar == '+')
+ {
+ rangeMin++;
+ if (rangeMin > Maximum)
+ rangeMin = Maximum;
+ if (rangeMax < rangeMin)
+ rangeMax = rangeMin;
+ OnRangeChanged(EventArgs.Empty);
+ }
+ else if (e.KeyChar == '-')
+ {
+ rangeMin--;
+ if (rangeMin < Minimum)
+ rangeMin = Minimum;
+ OnRangeChanged(EventArgs.Empty);
+ }
+ }
+ else if (ActiveMark == ActiveMarkType.right)
+ {
+ if (e.KeyChar == '+')
+ {
+ rangeMax++;
+ if (rangeMax > Maximum)
+ rangeMax = Maximum;
+ OnRangeChanged(EventArgs.Empty);
+ }
+ else if (e.KeyChar == '-')
+ {
+ rangeMax--;
+ if (rangeMax < Minimum)
+ rangeMax = Minimum;
+ if (rangeMax < rangeMin)
+ rangeMin = rangeMax;
+ OnRangeChanged(EventArgs.Empty);
+ }
+ }
+ Invalidate(true);
+ }
+ }
+
+
+ private void OnLoad(object sender, System.EventArgs e)
+ {
+ // use double buffering
+ SetStyle(ControlStyles.DoubleBuffer, true);
+ SetStyle(ControlStyles.AllPaintingInWmPaint, true);
+ SetStyle(ControlStyles.UserPaint, true);
+ }
+
+ private void OnSizeChanged(object sender, System.EventArgs e)
+ {
+ Invalidate(true);
+ Update();
+ }
+
+ private void OnLeave(object sender, System.EventArgs e)
+ {
+ ActiveMark = ActiveMarkType.none;
+ }
+
+
+ public event RangeChangedEventHandler RangeChanged; // event handler for range changed
+ public event RangeChangedEventHandler RangeChanging; // event handler for range is changing
+
+ public virtual void OnRangeChanged(EventArgs e)
+ {
+ if (RangeChanged != null)
+ RangeChanged(this, e);
+ }
+
+ public virtual void OnRangeChanging(EventArgs e)
+ {
+ if (RangeChanging != null)
+ RangeChanging(this, e);
+ }
+ }
+}
diff --git a/RangeBar/RangeBar/UserControllerLib.csproj b/RangeBar/RangeBar/UserControllerLib.csproj
new file mode 100644
index 0000000..5480679
--- /dev/null
+++ b/RangeBar/RangeBar/UserControllerLib.csproj
@@ -0,0 +1,55 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {134EA45A-DAF8-4B73-83A8-6EF89E26D635}
+ Library
+ RangeBar
+ RangeBar
+ v4.7.2
+ 512
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UserControl
+
+
+ RangeBar.cs
+
+
+
+
+
+
\ No newline at end of file