using System;
using System.Data;
using System.Collections;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Diagnostics;
namespace CustomControls
{
#region Slider
public class Slider : Control
{
#region Local Variables
private const string HelpIconName = "sldHelpIcon_";
private const string LockIconName = " sldLockIcon_";
private const string DescriptionName = "sldDescription_";
private const string DescriptionPanelName = "sldDescriptionPanel_";
private const string SliderBarName = "sldBar_";
private const string ValueName = "sldValue_";
private bool IsMouseDown=false;
private int MinSliderBar=0;
private int MaxSliderBar=0;
private int CurrentIndex=0;
private SliderPanel ActiveBar;
private SliderRow[] SliderRows;
private SliderRow CurrentRow;
private SliderStyle CurrentStyle;
protected CustomControls.ScrollablePanel PanelReference;
#endregion
#region Event Declarations
public event System.Windows.Forms.MouseEventHandler SliderDescriptionMouseUp;
public event System.Windows.Forms.MouseEventHandler SliderDescriptionMouseDown;
public event System.Windows.Forms.MouseEventHandler SliderLockMouseUp;
public event System.Windows.Forms.MouseEventHandler SliderLockMouseDown;
public event System.Windows.Forms.MouseEventHandler SliderHelpMouseUp;
public event System.Windows.Forms.MouseEventHandler SliderHelpMouseDown;
public event System.Windows.Forms.MouseEventHandler SliderBarMouseUp;
#endregion
#region Constructor
public Slider()
{
}
#endregion
#region Description Mouse Events
public void OnSliderDescriptionMouseDown(object sender, MouseEventArgs e)
{
CustomControls.SliderPanel oPanel;
CustomControls.SliderLabel oLabel;
try
{
if (sender.GetType().ToString() == "CustomControls.SliderPanel")
{
// Event occured while running under the .NET Compact Framework.
oPanel = (CustomControls.SliderPanel)sender;
oLabel = (CustomControls.SliderLabel)oPanel.Controls[0];
}
else
{
// Event occured while running a PC windows application.
oLabel = (CustomControls.SliderLabel)sender;
}
CurrentIndex = int.Parse(oLabel.ControlName.Replace(DescriptionName,""));
CurrentRow = SliderRows[CurrentIndex];
SliderDescriptionMouseDown(oLabel, e);
}
catch (Exception) { throw; }
}
public void OnSliderDescriptionMouseUp(object sender, MouseEventArgs e)
{
try
{
SliderDescriptionMouseUp(sender, e);
}
catch (Exception) { throw; }
}
#endregion
#region Lock Mouse Events
public void OnSliderLockMouseDown(object sender, MouseEventArgs e)
{
try
{
if (!CurrentStyle.RaiseLockEvents) { return; }
CustomControls.SliderPictureBox oControl = (CustomControls.SliderPictureBox)sender;
CurrentIndex = int.Parse(oControl.ControlName.Replace(LockIconName,""));
CurrentRow = SliderRows[CurrentIndex];
CurrentRow.IsLocked = !CurrentRow.IsLocked;
SliderRows[CurrentIndex] = CurrentRow;
if (CurrentRow.IsLocked) { oControl.Image = CurrentStyle.LockOnIcon; }
else { oControl.Image = CurrentStyle.LockOffIcon; }
SliderLockMouseDown(oControl, e);
}
catch (Exception) { throw; }
}
public void OnSliderLockMouseUp(object sender, MouseEventArgs e)
{
try
{
if (!CurrentStyle.RaiseLockEvents) { return; }
SliderLockMouseUp(sender, e);
}
catch (Exception) { throw; }
}
#endregion
#region Help Mouse Events
public void OnSliderHelpMouseDown(object sender, MouseEventArgs e)
{
try
{
if (!CurrentStyle.RaiseHelpEvents) { return; }
CustomControls.SliderPictureBox oControl = (CustomControls.SliderPictureBox)sender;
CurrentRow = SliderRows[int.Parse(oControl.ControlName.Replace(HelpIconName,""))];
SliderHelpMouseDown(oControl, e);
}
catch (Exception) { throw; }
}
public void OnSliderHelpMouseUp(object sender, MouseEventArgs e)
{
try
{
if (!CurrentStyle.RaiseHelpEvents) { return; }
SliderHelpMouseUp(sender, e);
}
catch (Exception) { throw; }
}
#endregion
#region Bar Mouse Events
private void OnSliderBarMouseDown(object sender, MouseEventArgs e)
{
try
{
IsMouseDown = true;
ActiveBar = (CustomControls.SliderPanel)sender;
CurrentIndex = int.Parse(ActiveBar.ControlName.Replace(SliderBarName,""));
if (!ValidateSliderBarsUnlocked()) { IsMouseDown = false; return; }
CurrentRow = SliderRows[CurrentIndex];
if (CurrentRow.IsLocked) { IsMouseDown=false; }
}
catch (Exception) { throw; }
}
public void OnSliderBarMouseUp(object sender, MouseEventArgs e)
{
try
{
IsMouseDown=false;
// Exit out if Range1To9 because it ignore the refresh on mouse up only flag.
// Exit out if we refreshed other bars as the selected bar was moving.
if ((!CurrentStyle.RefreshValueOnMouseUpOnly) || (CurrentStyle.Type == SliderType.Range1To9))
{
SliderBarMouseUp(sender, e);
return;
}
RedistributeValues();
MoveOtherSliderBars();
RefreshSliderValueLabels();
this.Invalidate();
SliderBarMouseUp(sender, e);
}
catch (Exception) { throw; }
}
private void OnSliderBarMouseMove(object sender, MouseEventArgs e)
{
try
{
if (!IsMouseDown) { return; }
MoveSliderBar(ActiveBar,e.X,CurrentIndex,CurrentRow,true);
ActiveBar.Invalidate();
// If true, refresh this bar's label. The others will be addressed in OnMouseUp.
// Range1To9 doesn't alter other sliders so exit out after refreshing this bar's label.
if ((CurrentStyle.RefreshValueOnMouseUpOnly) || (CurrentStyle.Type == SliderType.Range1To9))
{
RefreshSliderValueLabel(CurrentIndex);
return;
}
RedistributeValues();
MoveOtherSliderBars();
RefreshSliderValueLabels();
}
catch (Exception) { throw; }
}
#endregion
#region Load
public void Load(ref CustomControls.ScrollablePanel SliderPanel,
CustomControls.SliderStyle Style,
CustomControls.SliderRow[] Rows)
{
try
{
this.PanelReference = SliderPanel;
this.SliderRows = null;
this.SliderRows = Rows;
CurrentStyle = Style;
this.LoadRows();
}
catch (Exception) { throw; }
}
#endregion
#region ReSize
public void ReSize()
{
try
{
this.Enabled = false;
this.LoadRows();
}
catch (Exception) { throw; }
finally { this.Enabled = true; }
}
#endregion
#region Load Rows
private void LoadRows()
{
int Top=2;
int ControlBuffer = 3;
try
{
this.PanelReference.Contents.Controls.Clear();
// There is a refreshing problem on .NET CF devices.
// Force the scroll to be high enough to repaint new
// controls properly. Then, reset the scroll afterwards.
this.PanelReference.SetScrollHeight(this.Height + 10);
if (this.SliderRows == null) { return; }
if (this.SliderRows.Length < 1) { return; }
for(int i=0;i<this.SliderRows.Length;i++)
{
if (i==0) { CurrentRow = this.SliderRows[i]; }
CreateRow(ref this.SliderRows[i],Top,i);
Top += CurrentStyle.RowHeight + ControlBuffer;
}
// Remove the scroll bar if unneeded.
this.PanelReference.SetScrollHeight(Top);
}
catch (Exception) { throw; }
}
#endregion
#region Create Row
private void CreateRow(ref SliderRow Row,int Top,int SliderIndex)
{
try
{
CustomControls.SliderPictureBox oHelp = new CustomControls.SliderPictureBox();
oHelp.ControlName = HelpIconName + SliderIndex.ToString();
oHelp.Width = CurrentStyle.HelpTextIcon.Width;
oHelp.Height = CurrentStyle.RowHeight;
if (CurrentStyle.RaiseHelpEvents) { oHelp.Image = CurrentStyle.HelpTextIcon; }
oHelp.Location = new Point(1,Top);
oHelp.MouseDown += new MouseEventHandler(OnSliderHelpMouseDown);
oHelp.MouseUp += new MouseEventHandler(OnSliderHelpMouseUp);
Row.ControlIndexHelp = this.PanelReference.Contents.Controls.Count;
this.PanelReference.Contents.Controls.Add(oHelp);
CustomControls.SliderPictureBox oLock = new CustomControls.SliderPictureBox();
oLock.ControlName = LockIconName + SliderIndex.ToString();
oLock.Width = CurrentStyle.LockOffIcon.Width;
oLock.Height = CurrentStyle.RowHeight;
if ((Row.IsLocked == true) || (CurrentStyle.RaiseLockEvents == false))
{
oLock.Image = CurrentStyle.LockOnIcon;
}
else { oLock.Image = CurrentStyle.LockOffIcon; }
oLock.Location = new Point(oHelp.Left + oHelp.Width,Top);
oLock.MouseDown += new MouseEventHandler(OnSliderLockMouseDown);
oLock.MouseUp += new MouseEventHandler(OnSliderLockMouseUp);
Row.ControlIndexLock = this.PanelReference.Contents.Controls.Count;
this.PanelReference.Contents.Controls.Add(oLock);
// The Label control can raise mouse events in a PC based application
// but not in a .NET Compact Framework application (at the time of this writing).
// However, a .NET CF app will raise the mouse events for a Panel. So, we'll
// place our Label control on a Panel and use its mouse events while still
// showing the Label to the user. When the events are raised, we'll check
// what type of control the "sender" is and act accordingly.
CustomControls.SliderLabel oDescription = new SliderLabel();
oDescription.ControlName = DescriptionName + SliderIndex.ToString();
oDescription.Width = CurrentStyle.DescriptionWidth;
oDescription.Height = CurrentStyle.RowHeight;
oDescription.Location = new Point(0,0);
oDescription.Font = Row.Font;
oDescription.TextAlign = System.Drawing.ContentAlignment.TopLeft;
oDescription.Text = Row.Description;
oDescription.ForeColor = Row.ForeColor;
oDescription.MouseDown += new MouseEventHandler(OnSliderDescriptionMouseDown);
oDescription.MouseUp += new MouseEventHandler(OnSliderDescriptionMouseUp);
oDescription.SendToBack();
CustomControls.SliderPanel oDescriptionPanel = new SliderPanel();
oDescriptionPanel.ControlName = DescriptionPanelName + SliderIndex.ToString();
oDescriptionPanel.Width = CurrentStyle.DescriptionWidth;
oDescriptionPanel.Height = CurrentStyle.RowHeight;
oDescriptionPanel.Location = new Point(oLock.Left + oLock.Width,Top);
oDescriptionPanel.MouseDown += new MouseEventHandler(OnSliderDescriptionMouseDown);
oDescriptionPanel.MouseUp += new MouseEventHandler(OnSliderDescriptionMouseUp);
oDescriptionPanel.BringToFront();
oDescriptionPanel.Controls.Add(oDescription);
Row.ControlIndexBar = this.PanelReference.Contents.Controls.Count;
this.PanelReference.Contents.Controls.Add(oDescriptionPanel);
CustomControls.SliderPanel oBar = new SliderPanel();
oBar.ControlName = SliderBarName + SliderIndex.ToString();
oBar.Location = new Point(oDescriptionPanel.Left + oDescriptionPanel.Width + 2,Top);
oBar.Width = this.GetBarWidth(oBar.Left);
oBar.Height = CurrentStyle.RowHeight;
oBar.BackColor = Row.SliderBarColor;
oBar.MouseDown += new MouseEventHandler(OnSliderBarMouseDown);
oBar.MouseUp += new MouseEventHandler(OnSliderBarMouseUp);
oBar.MouseMove += new MouseEventHandler(OnSliderBarMouseMove);
Row.ControlIndexBar = this.PanelReference.Contents.Controls.Count;
MinSliderBar = 1;
MaxSliderBar = oBar.Width;
oBar.Width = this.ConvertValueToWidth(Row.Value);
this.PanelReference.Contents.Controls.Add(oBar);
CustomControls.SliderLabel oValue = new SliderLabel();
oValue.ControlName = ValueName + SliderIndex.ToString();
oValue.Width = CurrentStyle.ValueWidth;
oValue.Height = CurrentStyle.RowHeight;
oValue.Font = Row.Font;
oValue.TextAlign = System.Drawing.ContentAlignment.TopRight;
oValue.Location = new Point(this.GetValueLeft(),Top);
oValue.Text = System.Math.Round(Row.Value,CurrentStyle.DecimalPoints).ToString();
oValue.ForeColor = Row.ForeColor;
Row.ControlIndexValue = this.PanelReference.Contents.Controls.Count;
this.PanelReference.Contents.Controls.Add(oValue);
}
catch (Exception) { throw; }
}
#endregion
#region Move Slider Bar
private void MoveSliderBar(CustomControls.SliderPanel oBar,
int Width,int SliderIndex,
SliderRow Row,bool ResetValue)
{
try
{
oBar.Width = ValidateSliderBarWidth(Width);
if (ResetValue) { Row.Value = ConvertWidthToValue(oBar.Width); }
this.SliderRows[SliderIndex] = Row;
}
catch (Exception) { throw; }
}
#endregion
#region Redistribute Values
private void RedistributeValues()
{
double TotalAllValues = 0;
double TotalNonExcludedValues = 0;
double TotalBase=100;
bool ZerosAdjusted=false;
double Delta = 0;
double AdjustableItems = 0;
double Adjuster = 0;
// This method should only be called with SliderType.Percent. It grabs
// the selected bar's value and evenly distributes the remaining values
// across the other sliders either increase or decreasing their values.
CustomControls.SliderRow Row;
try
{
for(int i=0;i<this.SliderRows.Length;i++)
{
Row = this.SliderRows[i];
TotalAllValues += Row.Value;
if ((!Row.IsLocked) && (i !=CurrentIndex))
{
TotalNonExcludedValues += Row.Value;
AdjustableItems++;
}
}
if (AdjustableItems == 0) { return; }
if (TotalNonExcludedValues == 0)
{
ZerosAdjusted = true;
}
Delta = (TotalBase - TotalAllValues);
for(int i=0;i<this.SliderRows.Length;i++)
{
Row = this.SliderRows[i];
if ((!Row.IsLocked) && (i !=CurrentIndex))
{
if (ZerosAdjusted) // Selected bar reached 100.
{
Row.Value = Delta / AdjustableItems;
}
else // All other conditions
{
Row.Value = Row.Value + ((Row.Value / TotalNonExcludedValues) * Delta);
}
// In odd number situations, the total of all bars may not always equal 100. In
// these rare cases, we'll tack on the extra to the selected bar and redraw it.
if (Row.Value < 0.0001) { Adjuster += Row.Value; Row.Value = 0; }
this.SliderRows[i] = Row;
}
}
if (Adjuster == 0 ) { return; } // All bars totaled 100. No need to redraw the selected bar.
this.SliderRows[CurrentIndex].Value += Adjuster;
CustomControls.SliderPanel CurPanel;
CurPanel = (CustomControls.SliderPanel)
this.PanelReference.Contents.Controls[CurrentRow.ControlIndexBar];
int ThisWidth = this.ConvertValueToWidth(this.SliderRows[CurrentIndex].Value);
MoveSliderBar(CurPanel,ThisWidth,CurrentIndex, this.SliderRows[CurrentIndex],false);
}
catch (Exception) { throw; }
}
#endregion
#region Move Other Slider Bars
private void MoveOtherSliderBars()
{
CustomControls.SliderRow Row;
CustomControls.SliderPanel CurPanel;
try
{
for(int i=0;i<this.SliderRows.Length;i++)
{
Row = this.SliderRows[i];
if ((Row.IsLocked) || (i==CurrentIndex)) { continue; }
CurPanel = (CustomControls.SliderPanel)this.PanelReference.Contents.Controls[Row.ControlIndexBar];
MoveSliderBar(CurPanel,this.ConvertValueToWidth(Row.Value),i,Row,false);
}
}
catch (Exception) { throw; }
}
#endregion
#region Convert Width To Value
private double ConvertWidthToValue(int Width)
{
double Ret = 0;
try
{
switch (CurrentStyle.Type)
{
case SliderType.Percent:
Ret = ((double)Width / (double)MaxSliderBar) * 100;
if (Width==1) { Ret = 0; }
break;
case SliderType.Range1To9:
Ret = ((double)Width / (double)MaxSliderBar) * 9;
if (Ret < 1) { Ret = 1; }
break;
}
}
catch (Exception) { throw; }
return Ret;
}
#endregion
#region Convert Value To Width
private int ConvertValueToWidth(double Weight)
{
int Ret = 0;
// Take passed in value and turn it into pixel width for the bar.
// Essentionally, take the Weight as a percentage of the maximum size
// the bar is allowed to return pixel width.
try
{
switch (CurrentStyle.Type)
{
case SliderType.Percent:
if (Weight == 0 ) { Weight = 0.01; }
Ret = int.Parse(System.Math.Round(MaxSliderBar * (Weight / 100),0).ToString());
break;
case SliderType.Range1To9:
if ((Weight < 1) || (Weight > 9)) { Weight = 1;}
Ret = int.Parse(System.Math.Round(MaxSliderBar * (Weight / 9),0).ToString());
break;
}
}
catch (Exception) { throw; }
return Ret;
}
#endregion
#region Validate Slider Bar Width
private int ValidateSliderBarWidth(int Width)
{
// Make sure the slider stays in bounds
if (Width < MinSliderBar) { Width = 1; }
if (Width > MaxSliderBar) { Width = MaxSliderBar; }
return Width;
}
#endregion
#region Validate Slider Bars Unlocked
private bool ValidateSliderBarsUnlocked()
{
try
{
for(int i=0;i<this.SliderRows.Length;i++)
{
if (i==CurrentIndex) { continue; }
if (this.SliderRows[i].IsLocked == false)
{
return true;
}
}
}
catch (Exception) { throw; }
return false;
}
#endregion
#region Refresh Slider Value Labels
private void RefreshSliderValueLabels()
{
try
{
for(int i=0;i<this.SliderRows.Length;i++)
{
this.RefreshSliderValueLabel(i);
}
}
catch (Exception) { throw; }
}
#endregion
#region Refresh Slider Value Label
private void RefreshSliderValueLabel(int RowIndex)
{
try
{
SliderRow Row = this.SliderRows[RowIndex];
double ThisValue = System.Math.Round(Row.Value,CurrentStyle.DecimalPoints);
if (ThisValue >= 100) { ThisValue = 100; }
SliderLabel oValue = (SliderLabel)this.PanelReference.Contents.Controls[Row.ControlIndexValue];
oValue.Text = ThisValue.ToString();
oValue.Invalidate();
}
catch (Exception) { throw; }
}
#endregion
#region Get ValueLeft
private int GetValueLeft()
{
return((this.PanelReference.Contents.Width - 3) - CurrentStyle.ValueWidth);
}
#endregion
#region Get Bar Width
private int GetBarWidth(int BarLeft)
{
return GetValueLeft() - BarLeft;
}
#endregion
#region Public Properties
public SliderRow SelectedRow
{
get { return this.CurrentRow; }
}
public SliderRow[] SelectedRows
{
get { return this.SliderRows; }
}
#endregion
}
#endregion
#region Slider Type
public enum SliderType
{
Percent = 1,
Range1To9 = 2
}
#endregion
#region Slider Row
public class SliderRow
{
private double WeightValue = 0;
private bool Locked = false;
public SliderRow()
{
this.IsDirty=false;
}
public int ID;
public int SelectedIndex;
public int ControlIndexHelp;
public int ControlIndexLock;
public int ControlIndexDescription;
public int ControlIndexBar;
public int ControlIndexValue;
public int Width;
public int Height;
public bool HasHelpText;
public bool IsDirty;
public string Description;
public System.Drawing.Font Font;
public System.Drawing.Color ForeColor;
public System.Drawing.Color SliderBarColor;
public bool IsLocked
{
get { return Locked; }
set { this.IsDirty = true; Locked = value; }
}
public double Value
{
get { return WeightValue; }
set { this.IsDirty = true; WeightValue = value; }
}
}
#endregion
#region Slider Style
public struct SliderStyle
{
public int RowHeight;
public int DescriptionWidth;
public int ValueWidth;
public int DecimalPoints;
public bool RaiseLockEvents;
public bool RaiseHelpEvents;
public bool RefreshValueOnMouseUpOnly;
public SliderType Type;
public System.Drawing.Image HelpTextIcon;
public System.Drawing.Image LockOnIcon;
public System.Drawing.Image LockOffIcon;
}
#endregion
#region Slider Label
public class SliderLabel : System.Windows.Forms.Label
{
public SliderLabel() { }
public string ControlName = "";
}
#endregion
#region Slider Panel
public class SliderPanel : System.Windows.Forms.Panel
{
public SliderPanel() { }
public string ControlName = "";
}
#endregion
#region Slider PictureBox
public class SliderPictureBox : System.Windows.Forms.PictureBox
{
public SliderPictureBox() { }
public string ControlName = "";
}
#endregion
}
|