I have the following code:
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Data;
using System.Text;
using System.Windows.Forms;
namespace ControlLibrary
{
public partial class Basin : UserControl
{
List<string> OPCTagNamesList;
public Basin()
{
InitializeComponent();
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.UserPaint, true);
this.UpdateStyles();
AnimationTimer.Enabled = false;
OPCTagNamesList = new List<string>(25);
OPCTagNamesList.Add(_Level_DataSource);
ClipUnwantedPortionsOfUserControl();
}
#region Properties
private int _AnimationSpeed = 500;
public int AnimationSpeed
{
get
{
return _AnimationSpeed;
}
set
{
if (value >= 50)
{
_AnimationSpeed = value;
AnimationTimer.Interval = value;
AnimationTimer.Stop();
AnimationTimer.Start();
Refresh();
}
}
}
private HatchStyle _BorderFillStyle = HatchStyle.Weave;
public HatchStyle BorderFillStyle
{
get
{
return _BorderFillStyle;
}
set
{
_BorderFillStyle = value;
Refresh();
}
}
private Color _BorderBackColor = Color.Yellow;
public Color BorderBackColor
{
get
{
return _BorderBackColor;
}
set
{
_BorderBackColor = value;
Refresh();
}
}
private Color _BorderForeColor = Color.Red;
public Color BorderForeColor
{
get
{
return _BorderForeColor;
}
set
{
_BorderForeColor = value;
Refresh();
}
}
private Color _BorderLineColor = Color.Red;
public Color BorderLineColor
{
get
{
return _BorderLineColor;
}
set
{
_BorderLineColor = value;
Refresh();
}
}
private Color _BasinBackColor = Color.Black;
public Color BasinBackColor
{
get
{
return _BasinBackColor;
}
set
{
_BasinBackColor = value;
Refresh();
}
}
private Color _BasinFillColor = Color.Blue;
public Color BasinFillColor
{
get
{
return _BasinFillColor;
}
set
{
_BasinFillColor = value;
Refresh();
}
}
private bool _ShowAnimation = false;
public bool ShowAnimation
{
get
{
return _ShowAnimation;
}
set
{
_ShowAnimation = value;
AnimationTimer.Enabled = value;
Refresh();
}
}
float _ScaledHeight = 15.0f;
public float ScaledHeight
{
get
{
return _ScaledHeight;
}
set
{
if (value > 0)
{
_ScaledHeight = value;
Refresh();
}
}
}
private string _Level_DataSource, _Level_DataSourceOld;
public string Level_DataSource
{
get
{
return _Level_DataSource;
}
set
{
if (_Level_DataSource != value)
{
_Level_DataSource = value;
UpdateOPCTagNamesList(_Level_DataSourceOld, _Level_DataSource);
_Level_DataSourceOld = value;
}
}
}
private string _Display_Level_As = "Level: {Level} Ft";
public string Display_Level_As
{
get
{
return _Display_Level_As;
}
set
{
if (_Display_Level_As != value)
{
_Display_Level_As = value;
Refresh();
}
}
}
private string _Display_LevelPercentage_As = "Level: {LevelPercentage} %";
public string Display_LevelPercentage_As
{
get
{
return _Display_LevelPercentage_As;
}
set
{
if (_Display_LevelPercentage_As != value)
{
_Display_LevelPercentage_As = value;
Refresh();
}
}
}
private Color _TextForeColor = Color.WhiteSmoke;
public Color TextForeColor
{
get
{
return _TextForeColor;
}
set
{
_TextForeColor = value;
Refresh();
}
}
#endregion
void UpdateOPCTagNamesList(string OldVal, string NewVal)
{
// If the new name is NOT EMPTY
if (!String.IsNullOrEmpty(NewVal))
{
// If it is already in the list then update
if (OPCTagNamesList.Contains(OldVal))
{
OPCTagNamesList[OPCTagNamesList.IndexOf(OldVal)] = NewVal;
}
else
{
// Add to the list
OPCTagNamesList.Add(NewVal);
}
}
else
{
// If the new value is empty then remove the old one from the list
if (OPCTagNamesList.Contains(OldVal))
{
OPCTagNamesList.RemoveAt(OPCTagNamesList.IndexOf(OldVal));
}
}
}
void ClipUnwantedPortionsOfUserControl()
{
int cx = ClientRectangle.Width;
int cy = ClientRectangle.Height;
Pen pen1 = new Pen(Brushes.Black, 1);
GraphicsPath gp = new GraphicsPath();
Rectangle OuterRect = new Rectangle(1, 1, cx - 2, cy - 2);
Rectangle InnerRect = new Rectangle();
InnerRect = OuterRect;
InnerRect.Inflate(-(int)(0.04 * cx), -(int)(0.04 * cy));
gp.StartFigure();
gp.AddLine(OuterRect.Left - 1, InnerRect.Top - 1, OuterRect.Left - 1, OuterRect.Bottom + 2);
gp.AddLine(OuterRect.Right + 2, OuterRect.Bottom + 2, OuterRect.Right + 2, InnerRect.Top - 1);
gp.CloseFigure();
this.Region = new Region(gp);
}
private void Basin_Paint(object sender, PaintEventArgs e)
{
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
int cx = ClientRectangle.Width;
int cy = ClientRectangle.Height;
Pen pen1 = new Pen(Brushes.Black, 1);
GraphicsPath gp = new GraphicsPath();
Rectangle OuterRect = new Rectangle(1, 1, cx - 2, cy - 2);
Rectangle InnerRect = new Rectangle();
InnerRect = OuterRect;
InnerRect.Inflate(-(int)(0.04 * cx), -(int)(0.04 * cy));
gp.StartFigure();
gp.AddLine(OuterRect.Left, InnerRect.Top, OuterRect.Left, OuterRect.Bottom);
gp.AddLine(OuterRect.Right, OuterRect.Bottom, OuterRect.Right, InnerRect.Top);
gp.AddLine(InnerRect.Right, InnerRect.Top, InnerRect.Right, InnerRect.Bottom);
gp.AddLine(InnerRect.Left, InnerRect.Bottom, InnerRect.Left, InnerRect.Top);
gp.CloseFigure();
e.Graphics.FillPath(new HatchBrush(BorderFillStyle, _BorderForeColor, _BorderBackColor), gp);
e.Graphics.DrawPath(new Pen(new SolidBrush(_BorderLineColor), 2), gp);
e.Graphics.FillRectangle(new SolidBrush(BasinBackColor), InnerRect);
int Height = InnerRect.Height;
int StartY = InnerRect.Bottom;
int EndY = InnerRect.Top;
float WaterLevel = Height / ScaledHeight;
Rectangle WaterLevelRect = new Rectangle();
WaterLevelRect.Width = InnerRect.Width;
WaterLevelRect.Height = (int)(WaterLevel * Level);
WaterLevelRect.X = InnerRect.X;
WaterLevelRect.Y = InnerRect.Top + (Height - WaterLevelRect.Height); ;
e.Graphics.FillRectangle(new SolidBrush(BasinFillColor), WaterLevelRect);
StringFormat strFmt = new StringFormat();
strFmt.Alignment = StringAlignment.Center;
strFmt.LineAlignment = StringAlignment.Center;
if (!String.IsNullOrEmpty(Display_Level_As))
{
string DisplayLevel = Level.ToString("00.0") + "'";
int StartPos = Display_Level_As.IndexOf('{');
int EndPos = Display_Level_As.IndexOf('}');
if (StartPos >= 0 && EndPos > 0)
{
string propName = Display_Level_As.Substring(StartPos + 1, EndPos - StartPos - 1);
Type type = this.GetType();
System.Reflection.BindingFlags flags = System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance;
System.Reflection.PropertyInfo propInfo = type.GetProperty(propName, flags);
if (propInfo != null)
{
object obj1 = propInfo.GetValue(this, null);
if (obj1 != null)
{
float propValue = 0.0f;
try
{
propValue = Convert.ToSingle(obj1);
DisplayLevel = Display_Level_As.Replace("{" + propInfo.Name+ "}", propValue.ToString("00.0"));
}
catch (Exception eConvert)
{
}
}
}
}
Rectangle LevelFeetRect = new Rectangle();
LevelFeetRect = InnerRect;
using (Font f2 = new Font(this.Font.FontFamily, GlobalRoutines.BestFontSize(e.Graphics, InnerRect.Size, Font, DisplayLevel), this.Font.Style))
e.Graphics.DrawString(DisplayLevel, f2, new SolidBrush(TextForeColor), InnerRect, strFmt);
}
strFmt.LineAlignment = StringAlignment.Far;
if (!String.IsNullOrEmpty(Display_LevelPercentage_As))
{
string DisplayLevelPercentage = "0 %";
int StartPos = Display_LevelPercentage_As.IndexOf('{');
int EndPos = Display_LevelPercentage_As.IndexOf('}');
if (StartPos >= 0 && EndPos > 0)
{
string propName = Display_LevelPercentage_As.Substring(StartPos + 1, EndPos - StartPos - 1);
Type type = this.GetType();
System.Reflection.BindingFlags flags = System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance;
System.Reflection.PropertyInfo propInfo = type.GetProperty(propName, flags);
if (propInfo != null)
{
object obj1 = propInfo.GetValue(this, null);
if (obj1 != null)
{
float propValue = 0.0f;
try
{
propValue = Convert.ToSingle(obj1);
DisplayLevelPercentage = Display_LevelPercentage_As.Replace("{"+ propInfo.Name + "}", propValue.ToString("00.0"));
}
catch (Exception eConvert)
{
}
}
}
}
using (Font f2 = new Font(this.Font.FontFamily, GlobalRoutines.BestFontSize(e.Graphics, InnerRect.Size, Font, DisplayLevelPercentage), this.Font.Style))
e.Graphics.DrawString(DisplayLevelPercentage, f2, new SolidBrush(TextForeColor), InnerRect, strFmt);
}
// Clean Up
pen1.Dispose();
gp.Dispose();
}
private void Basin_Resize(object sender, EventArgs e)
{
ClipUnwantedPortionsOfUserControl();
Refresh();
}
private Random R = new Random();
private List<Point> pts = new List<Point>();
float _Level = 0;
public float Level
{
get
{
return _Level;
}
set
{
if (_Level != value && value >= 0 && value <= ScaledHeight)
{
_Level = value;
_LevelPercentage = ((Level / ScaledHeight) * 100);
Refresh();
}
}
}
float _LevelPercentage = 0;
public float LevelPercentage
{
get
{
return _LevelPercentage;
}
}
private void AnimationTimer_Tick(object sender, EventArgs e)
{
_Level += 0.5f;
if (Level > ScaledHeight) Level = 0;
_LevelPercentage = ((Level / ScaledHeight) * 100);
Refresh();
}
public List<string> GetAllOPCTagsInTheControl()
{
List<string> x = new List<string>(10);
for (int i = 0; i < OPCTagNamesList.Count; i++)
{
if (!string.IsNullOrEmpty(OPCTagNamesList[i]))
x.Add(OPCTagNamesList[i]);
}
return x;
}
public void OPCTagValueUpdates(string TagName, object value)
{
bool DataChanged = false;
//int SwCaseNum = OPCTagNamesList.IndexOf(TagName);
int SwCaseNum = 0;
if (TagName == _Level_DataSource)
SwCaseNum = 0;
else // Invalid tag
{
return;
}
object _ValueReceived;
try
{
//_ValueReceived = kvp.Value;
_ValueReceived = value;
if (_ValueReceived == null || String.IsNullOrEmpty(_ValueReceived.ToString())) return; // Added 02/15/11 to reject EMPTY values
// If received data contains ?? then it is an invalid tag
if (_ValueReceived.ToString().Contains("?"))
return;
else
{
switch (SwCaseNum)
{
case 0:
try
{
Single Level_Temp = Convert.ToSingle(_ValueReceived);
if (Level != Level_Temp)
{
Level = Level_Temp;
DataChanged = true;
}
}
catch
{
}
break;
}
}
}
catch
{
// Item not found
}
if (DataChanged)
Refresh();
}
public void OPCTagValueUpdates(Dictionary<string, object> TagNameValueDict)
{
foreach (KeyValuePair<string, object> kvp in TagNameValueDict)
{
if (kvp.Key != null && kvp.Value != null)
OPCTagValueUpdates(kvp.Key, kvp.Value);
}
}
}
}
When converted to WPF, it should look alike and be scalable and re-sizable as needed.
The output will be somewhat similar to this:
Thank You