My code is creating multiple instances of a form with different controls and events. This is done while incrementing i
to the total amount of forms. The aim is to add an event to a button control in the form. My forms are instances of Ticker
, the subclass of Form
that I have created.
The issue I have is that when I click on the button at run-time, the event handler kicks in and i
is out of bounds as the loop has already finished.
A snippet of the code is below, the event handler is integrated into a loop incrementing i
which also houses the switches. Any way for thisObject
to be equal to the current active ticker while still keeping the event handler in the loop? EDIT: I've provided the full class for better clarity. The section in question follows through the action_set>>email>>trigger>>click cases.
public partial class DesktopTickers : Form
{
public DesktopTickers(List<string> tickerArgs)
{
InitializeComponent();
this.Opacity = 0;
this.ShowInTaskbar = false;
int totalTickers = tickerArgs.Count();
Rectangle screenBounds = GetDpiSafeResolution();
Size iconSizeDefault = this.Size;
string iconDirectory = @"\\server\Tickers\";
string iconSuffix = "_icon.png";
string configDirectory = @"\\server\Tickers\";
string configSuffix = ".txt";
char paramDelimiter = ':';
char controlDelimiter = '=';
char[] controlSeparatorL = {'('};
char controlSeparatorR = ')';
char actionDelimiter = '=';
char[] actionSeparatorL = {'('};
char actionSeparatorR = ')';
char propertyDelimiter = '-';
int maxWidthDefault = iconSizeDefault.Width;
int maxHeightDefault = iconSizeDefault.Height;
Ticker[] tickers = new Ticker[tickerArgs.Count()];
List<Control> controls = new List<Control>();
for (int i = 0; i < tickerArgs.Count(); i++)
{
string tickerArg = tickerArgs[i];
string tickerConfigPath = configDirectory + tickerArg + configSuffix;
string tickerResourcePath = iconDirectory + @"\" + tickerArg + @"\";
string tickerIconPath = tickerResourcePath + tickerArg + iconSuffix;
tickers[i] = new Ticker(screenBounds, tickerArg, i+1, tickerArgs.Count(), iconSizeDefault,
maxHeightDefault, maxWidthDefault, tickerIconPath);
string[] tickerConfigContents = File.ReadAllLines(tickerConfigPath);
for (int j = 0; j < tickerConfigContents.Length; j++)
{
string thisConfigLine = tickerConfigContents[j];
int configParamEnd = thisConfigLine.IndexOf(paramDelimiter);
if (configParamEnd < 0) { configParamEnd = 0; }
string tickerConfigParam = thisConfigLine.Substring(0, configParamEnd);
string tickerConfigValue = thisConfigLine.Substring(configParamEnd + 1);
switch (tickerConfigParam.ToLower())
{ //TICKER LEVEL PARAMETERS
case "icon_width":
tickers[i].iconWidth = Convert.ToInt32(tickerConfigValue);
break;
case "icon_height":
tickers[i].iconHeight = Convert.ToInt32(tickerConfigValue);
break;
case "max_width":
tickers[i].maxWidth = Convert.ToInt32(tickerConfigValue);
break;
case "max_height":
tickers[i].maxHeight = Convert.ToInt32(tickerConfigValue);
break;
case "control_set":
for (int k = j + 1; k < tickerConfigContents.Length; k++)
{ //CONTROL LEVEL PARAMETERS
string thisControlLine = tickerConfigContents[k];
if(thisControlLine == "end") { break; }
int controlParamEnd = thisControlLine.IndexOf(controlDelimiter);
string thisControlType = thisControlLine.Substring(0, controlParamEnd);
string thisControlDetails = thisControlLine.Substring(controlParamEnd+ 1);
thisControlDetails = thisControlDetails.Replace(controlSeparatorR.ToString(), "");
string[] controlProperties = thisControlDetails.Split(controlSeparatorL, StringSplitOptions.RemoveEmptyEntries);
switch (thisControlType.ToLower())
{ //CONTROL TYPE LEVEL PARAMETERS
case "image":
PictureBox thisImage = new PictureBox();
for (int l = 0; l < controlProperties.Length; l++)
{
string thisProperty = controlProperties[l];
int propertyParamEnd = thisProperty.IndexOf(propertyDelimiter);
string propertyType = thisProperty.Substring(0, propertyParamEnd - 1);
string propertyValue = thisProperty.Substring(propertyParamEnd + 2);
switch (propertyType.ToLower())
{ //PROPERTY LEVEL PARAMETERS
case "file":
try { thisImage.BackgroundImage = Image.FromFile(tickerResourcePath + propertyValue); }
catch { thisImage.BackgroundImage = thisImage.ErrorImage; }
break;
case "bounds":
char[] pointDelimiter = { ',' };
string[] boundsValues = propertyValue.Split(pointDelimiter);
Rectangle bounds = new Rectangle(
new Point(Convert.ToInt32(boundsValues[0]), Convert.ToInt32(boundsValues[1])),
new Size(Convert.ToInt32(boundsValues[2]), Convert.ToInt32(boundsValues[3])));
thisImage.Bounds = bounds;
break;
case "layout":
switch(propertyValue.ToLower())
{
case "stretch":
thisImage.BackgroundImageLayout = ImageLayout.Stretch;
break;
case "zoom":
thisImage.BackgroundImageLayout = ImageLayout.Zoom;
break;
case "tile":
thisImage.BackgroundImageLayout = ImageLayout.Tile;
break;
case "center":
thisImage.BackgroundImageLayout = ImageLayout.Center;
break;
default:
thisImage.BackgroundImageLayout = ImageLayout.None;
break;
}
break;
case "id":
thisImage.Name = propertyValue;
break;
}
tickers[i].Controls.Add(thisImage);
thisImage.Show();
}
break;
case "label":
Label thisLabel = new Label();
for (int l = 0; l < controlProperties.Length; l++)
{
string thisProperty = controlProperties[l];
int propertyParamEnd = thisProperty.IndexOf(propertyDelimiter);
string propertyType = thisProperty.Substring(0, propertyParamEnd - 1);
string propertyValue = thisProperty.Substring(propertyParamEnd + 2);
thisLabel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
switch (propertyType.ToLower())
{ //PROPERTY LEVEL PARAMETERS
case "text":
thisLabel.Text = propertyValue;
break;
case "font":
char fontDelimiter = ',';
int fontSplitIndex = propertyValue.IndexOf(fontDelimiter);
string fontName = propertyValue.Substring(0, fontSplitIndex);
string fontSize = propertyValue.Substring(fontSplitIndex + 1);
int fontSizeNum = int.Parse(fontSize);
thisLabel.Font = new Font(propertyValue, fontSizeNum);
break;
case "bounds":
char[] pointDelimiter = {','};
string[] boundsValues = propertyValue.Split(pointDelimiter);
Rectangle bounds = new Rectangle(
new Point(Convert.ToInt32(boundsValues[0]), Convert.ToInt32(boundsValues[1])),
new Size(Convert.ToInt32(boundsValues[2]), Convert.ToInt32(boundsValues[3])));
thisLabel.Bounds = bounds;
break;
case "id":
thisLabel.Name = propertyValue;
break;
}
thisLabel.Show();
tickers[i].Controls.Add(thisLabel);
}
break;
case "button":
Button thisButton = new Button();
for (int l = 0; l < controlProperties.Length; l++)
{
string thisProperty = controlProperties[l];
int propertyParamEnd = thisProperty.IndexOf(propertyDelimiter);
string propertyType = thisProperty.Substring(0, propertyParamEnd - 1);
string propertyValue = thisProperty.Substring(propertyParamEnd + 2);
switch (propertyType.ToLower())
{
case "text":
thisButton.Text = propertyValue;
break;
case "font":
char fontDelimiter = ',';
int fontSplitIndex = propertyValue.IndexOf(fontDelimiter);
string fontName = propertyValue.Substring(0, fontSplitIndex);
string fontSize = propertyValue.Substring(fontSplitIndex + 1);
int fontSizeNum = int.Parse(fontSize);
thisButton.Font = new Font(propertyValue, fontSizeNum);
break;
case "bounds":
char[] pointDelimiter = { ',' };
string[] boundsValues = propertyValue.Split(pointDelimiter);
Rectangle bounds = new Rectangle(
new Point(Convert.ToInt32(boundsValues[0]), Convert.ToInt32(boundsValues[1])),
new Size(Convert.ToInt32(boundsValues[2]), Convert.ToInt32(boundsValues[3])));
thisButton.Bounds = bounds;
break;
case "id":
thisButton.Name = propertyValue;
break;
}
thisButton.Show();
tickers[i].Controls.Add(thisButton);
}
break;
case "textbox":
TextBox thisTextBox = new TextBox();
for (int l = 0; l < controlProperties.Length; l++)
{
string thisProperty = controlProperties[l];
int propertyParamEnd = thisProperty.IndexOf(propertyDelimiter);
string propertyType = thisProperty.Substring(0, propertyParamEnd - 1);
string propertyValue = thisProperty.Substring(propertyParamEnd + 2);
thisTextBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
switch (propertyType.ToLower())
{ //PROPERTY LEVEL PARAMETERS
case "text":
thisTextBox.Text = propertyValue;
break;
case "font":
char fontDelimiter = ',';
int fontSplitIndex = propertyValue.IndexOf(fontDelimiter);
string fontName = propertyValue.Substring(0, fontSplitIndex);
string fontSize = propertyValue.Substring(fontSplitIndex + 1);
int fontSizeNum = int.Parse(fontSize);
thisTextBox.Font = new Font(propertyValue, fontSizeNum);
break;
case "bounds":
char[] pointDelimiter = { ',' };
string[] boundsValues = propertyValue.Split(pointDelimiter);
Rectangle bounds = new Rectangle(
new Point(Convert.ToInt32(boundsValues[0]), Convert.ToInt32(boundsValues[1])),
new Size(Convert.ToInt32(boundsValues[2]), Convert.ToInt32(boundsValues[3])));
thisTextBox.Bounds = bounds;
break;
case "id":
thisTextBox.Name = propertyValue;
break;
}
thisTextBox.Show();
tickers[i].Controls.Add(thisTextBox);
}
break;
}
}
break;
case "action_set":
for (int k = j + 1; k < tickerConfigContents.Length; k++)
{ //ACTION LEVEL PARAMETERS
string thisActionLine = tickerConfigContents[k];
if (thisActionLine == "end") { break; }
int actionParamEnd = thisActionLine.IndexOf(actionDelimiter);
string thisActionType = thisActionLine.Substring(0, actionParamEnd);
string thisActionDetails = thisActionLine.Substring(actionParamEnd + 1);
thisActionDetails = thisActionDetails.Replace(actionSeparatorR.ToString(), "");
string[] actionProperties = thisActionDetails.Split(actionSeparatorL, StringSplitOptions.RemoveEmptyEntries);
Control thisObject = new Control();
switch (thisActionType.ToLower())
{ //ACTION TYPE LEVEL PARAMETERS
case "email":
//email requires trigger, objectid, action to send email, email action params
for (int l = 0; l < actionProperties.Length; l++)
{
string thisProperty = actionProperties[l];
int propertyParamEnd = thisProperty.IndexOf(propertyDelimiter);
string propertyType = thisProperty.Substring(0, propertyParamEnd - 1);
string propertyValue = thisProperty.Substring(propertyParamEnd + 2);
string emailDomain = "";
string emailServer = "";
int emailPort = 0;
string emailTemplate = "";
string emailRecipient = "";
switch (propertyType.ToLower())
{
case "domain":
emailDomain = propertyValue;
break;
case "server":
emailServer = propertyValue;
break;
case "port":
emailPort = Convert.ToInt32(propertyValue);
break;
case "file":
emailTemplate = tickerResourcePath + propertyValue;
break;
case "recipient":
emailRecipient = propertyValue;
break;
case "object":
thisObject = tickers[i].Controls.Find(propertyValue, false).FirstOrDefault() as Control;
//thisObject = objects[0];
break;
case "trigger":
tickers[i].SetEmailProperties(emailDomain, emailServer, emailPort, emailTemplate, emailRecipient);
switch(propertyValue.ToLower())
{
case "click":
thisObject.MouseDown += new MouseEventHandler((sender, e)
=> tickers[i].SendEmail_Event(sender, e));
break;
}
break;
}
}
break;
}
}
break;
}
}
tickers[i].Show();
}
}
private Rectangle GetDpiSafeResolution()
{
using (Graphics graphics = this.CreateGraphics())
{
return new Rectangle(new Point(0, 0), new Size((Screen.PrimaryScreen.Bounds.Width * (int)graphics.DpiX) / 96
, (Screen.PrimaryScreen.Bounds.Height * (int)graphics.DpiY) / 96));
}
}
}