c# pass different variables to button onClick event - c#

I would need different variables on button_Click event. For each button I need different billDetail and rowAmount values. Actually every button is giving the last values of the var Size.
I think is a easy problem but I'm doing this as hobby...please help me!
private void CashCounter_Load(object sender, EventArgs e)
{
var posXbutton = 120;
var posYbutton = 10;
var gapXbutton = 105;
var gapYbutton = 65;
var posXlabel = 5;
var posYlabel = 28;
var gapYlabel = 65;
using (var db = new GelatoProjectDBEntities())
{
#region working code
var items = (from x in db.ProductsLists
select new { x.Id, x.Product, x.Category, x.Size, x.Price, x.Market, x.Image }
).Where(x => x.Market == "Retail")
.ToArray();
var categories = (from x in items
select x.Category)
.Distinct();
foreach (var category in categories)
{
TabPage TabProduct = new TabPage(category);
TabProduct.BackColor = System.Drawing.Color.White;
tabControl1.TabPages.Add(TabProduct);
var products = (from i in items
where i.Category == category
select i.Product)
.Distinct()
.ToList();
foreach (var product in products)
{
string labelName = "label" + product;
var label = new Label();
label.AutoSize = false;
label.Location = new System.Drawing.Point(posXlabel, posYlabel);
label.Name = labelName;
label.Size = new System.Drawing.Size(110, 17);
label.TabIndex = 0;
label.Text = product;
label.RightToLeft = RightToLeft.Yes;
posYlabel = posYlabel + gapYlabel;
TabProduct.Controls.Add(label);
var sizes = (from i in items
where i.Product == product
//select i.Size)
select new { i.Id, i.Product, i.Category, i.Size, i.Price, i.Market, i.Image })
.Distinct()
.ToList();
foreach (var size in sizes)
{
BillDetail = size.Size+" "+product;
BillTotal = "£ "+size.Price;
RowAmount = size.Price;
string buttonName = "button" + product;
var button = new Button();
button.Location = new Point(posXbutton, posYbutton);
button.Name = buttonName;
button.Size = new Size(100, 50);
button.Text = size.Size;
button.BackColor = System.Drawing.Color.LightGray;
button.Click += new System.EventHandler(button_Click);
posXbutton = posXbutton + gapXbutton;
TabProduct.Controls.Add(button);
}
posXbutton = 120;
posYbutton = posYbutton + gapYbutton;
}
posXbutton = 120;
posYbutton = 10;
gapXbutton = 105;
gapYbutton = 65;
posXlabel = 5;
posYlabel = 28;
gapYlabel = 65;
}
}
#endregion
}
private void button_Click (object sender, EventArgs e)
{
ListViewItem NewBillProduct = new ListViewItem(BillDetail);
NewBillProduct.SubItems.Add("£");
NewBillProduct.SubItems.Add(RowAmount.ToString("F"));
listViewBillDetail.Items.Add(NewBillProduct);
BillTotalAmount = BillTotalAmount + double.Parse(RowAmount.ToString("F"));
ItemsTotal = ItemsTotal + 1;
textBoxTotal.Text = (BillTotalAmount.ToString("C", nfi)).ToString();
textBoxItems.Text = (ItemsTotal).ToString();
}

You can use Tag property of Button to store related Size object there:
button.Tag = size;
Then in click event handler you can retrieve this object:
private void button_Click (object sender, EventArgs e)
{
var button = (Button)sender;
var size = (Size)button.Tag;
// use size.Size or size.Price
// etc
}
Note: You can store several objects in Tag if you'll put them into array or list.

Related

Match the columns using a data dictionary in C# winForm

private void Dewery_Decimal_System_Load(object sender, EventArgs e)
{
Random random = new Random();
Dictionary<int,string > dictionary = new Dictionary<int, string>();
dictionary.Add(000, "Genral Knowlege");
dictionary.Add(100, "philosophy & Psycology");
dictionary.Add(200, "Religion");
dictionary.Add(300, "Social Sciences");
dictionary.Add(400, "Languages");
dictionary.Add(500, "Science");
dictionary.Add(600, "Techynology");
dictionary.Add(700, "Arts & Recriation");
dictionary.Add(800, "Litrature");
dictionary.Add(900, "History and geography");
for (int i = 0; i < 9; ++i)
{
int index = random.Next(dictionary.Count);
KeyValuePair<int, string> pair = dictionary.ElementAt(index);
Console.WriteLine("key: " + pair.Key + ", value: " + pair.Value);
label28.Text = (dictionary[pair.Key]);
}
for (int i = 0; i < 9; ++i)
{
int index = random.Next(dictionary.Count);
KeyValuePair<int, string> pair = dictionary.ElementAt(index);
label29.Text = (dictionary[pair.Key]);
}
for (int i = 0; i < 9; ++i)
{
int index = random.Next(dictionary.Count);
KeyValuePair<int, string> pair = dictionary.ElementAt(index);
label30.Text = (dictionary[pair.Key]);
}
for (int i = 0; i < 9; ++i)
{
int index = random.Next(dictionary.Count);
KeyValuePair<int, string> pair = dictionary.ElementAt(index);
label31.Text = (dictionary[pair.Key]);
}
}
private void button15_Click(object sender, EventArgs e)
{
}
**I would want my end result to be that the application displays 4 call numbers from the dictionary and lets the user select the corresponding description **
I've never worked with a data dictionary before so I'm sorry for the mess iv created but I'm trying to better my skills doing these challenges but this particular one is really giving me grief
Based on the questions and comments, your request is to allow a user selecting a value from a set of predefined key-value pairs within a dictionary.
I will assume that the component you are using on the windows form is a combobox.
Dictionary<int, string> dictionary = new Dictionary<int, string>();
dictionary.Add(000, "Genral Knowlege");
dictionary.Add(100, "philosophy & Psycology");
dictionary.Add(200, "Religion");
dictionary.Add(300, "Social Sciences");
dictionary.Add(400, "Languages");
dictionary.Add(500, "Science");
dictionary.Add(600, "Techynology");
dictionary.Add(700, "Arts & Recriation");
dictionary.Add(800, "Litrature");
dictionary.Add(900, "History and geography");
//Repeat this step for all your comboboxes
foreach (KeyValuePair<int, string> item in dictionary)
{
comboBox1.Items.Add(item.Value);
comboBox1.ValueMember = item.Value.ToString();
comboBox1.DisplayMember = item.Key.ToString();
comboBox1.SelectedIndex = 0;
}
Now, each combobox is filled with the dictionary values, the user can either type or choose from the suggested value.
Ok here is the answer I promised without knowing the details in comment. This is a working and quick throw at it. You should really think about the purpose of what you are doing twice.
Note the repetition in code, it could be made not to repeat (in a loop) but I left that you for now and wanted to be more explicit:
void Main()
{
Dictionary<string, string> dictionary = new Dictionary<string, string>();
dictionary.Add("000", "Genral Knowlege");
dictionary.Add("100", "philosophy & Psycology");
dictionary.Add("200", "Religion");
dictionary.Add("300", "Social Sciences");
dictionary.Add("400", "Languages");
dictionary.Add("500", "Science");
dictionary.Add("600", "Techynology");
dictionary.Add("700", "Arts & Recriation");
dictionary.Add("800", "Litrature");
dictionary.Add("900", "History and geography");
Form f = new Form();
var label28 = new Label { Top = 10, Left = 10, Width = 100 };
var label29 = new Label { Top = 40, Left = 10, Width = 100 };
var label30 = new Label { Top = 70, Left = 10, Width = 100 };
var label31 = new Label { Top = 100, Left = 10, Width = 100 };
var cmb28 = new ComboBox { Top = 10, Left = 130, DataSource = dictionary.ToList(), DisplayMember = "Key", ValueMember = "Key" };
var cmb29 = new ComboBox { Top = 40, Left = 130, DataSource = dictionary.ToList(), DisplayMember = "Key", ValueMember = "Key" };
var cmb30 = new ComboBox { Top = 70, Left = 130, DataSource = dictionary.ToList(), DisplayMember = "Key", ValueMember = "Key" };
var cmb31 = new ComboBox { Top = 100, Left = 130, DataSource = dictionary.ToList(), DisplayMember = "Key", ValueMember = "Key" };
f.Controls.AddRange(new Control[] { label28, label29, label30, label31, cmb28, cmb29, cmb30, cmb31 });
f.Load += (sender, args) => {
var randomTop4 = dictionary.ToList().OrderBy(d => Guid.NewGuid()).Take(4).ToList();
cmb28.SelectedValue = randomTop4[0].Key;
label28.Text = randomTop4[0].Value;
cmb28.SelectedValueChanged += (s, a) => {
var v = (string)(s as ComboBox).SelectedValue;
if (v != null)
{
label28.Text = dictionary[v];
}
};
cmb29.SelectedValue = randomTop4[1].Key;
label29.Text = randomTop4[1].Value;
cmb29.SelectedValueChanged += (s, a) =>
{
var v = (string)(s as ComboBox).SelectedValue;
if (v != null)
{
label29.Text = dictionary[v];
}
};
cmb30.SelectedValue = randomTop4[2].Key;
label30.Text = randomTop4[2].Value;
cmb30.SelectedValueChanged += (s, a) =>
{
var v = (string)(s as ComboBox).SelectedValue;
if (v != null)
{
label30.Text = dictionary[v];
}
};
cmb31.SelectedValue = randomTop4[3].Key;
label31.Text = randomTop4[3].Value;
cmb31.SelectedValueChanged += (s, a) =>
{
var v = (string)(s as ComboBox).SelectedValue;
if (v != null)
{
label31.Text = dictionary[v];
}
};
};
f.Show();
}

Where is data updated in a DataGridView?

I am creating a tab page entirley programatically from a button press in the root page of a tabbed control. At present all the page initialisation takes place in the button click method. After all the instantiation, data capture from file and so on, I finally want to adjust the column widths in the data grid view, so that all the row data appears without having to have horizontal scroll bars. With the help of all your contributors I have managed to get it all working but the last step. Running at full speed it appears the DataGridView is accessed before the data load from the table is complete as it fails with an exception because the count derived from RegistersGrid.ColumnCount (local variable l) is zero. It all works fine if I step through the code. I am assuming that I need to put a Mutex of some form to wait for the transfer to complete, but I can't work out where that is taking place in order to reset the flag! If someone can point me in the right direction or if there is better more structured way to approach this I would deeply appreciate the help :-)
I have included all the code in the method just in case, I am afraid I date back a long way so if this looks like the awkward child of assembler,pascal and c with a little c# thrown in, my apologies....it's my age :-)
private void AddModuleButton_Click(object sender, EventArgs e)
{
string ModuleID = null;
string ModuleTypeFileNumber = null;
string ModuleType = null;
int TabID = 0;
openFileDialog1.Filter = "Text Files (.txt)|*.txt";
DialogResult result = openFileDialog1.ShowDialog();
if (result == DialogResult.OK)
using (StreamReader reader = new StreamReader(openFileDialog1.FileName))
{
string newline;
if ((newline = reader.ReadLine()) != null)
{
string[] values = newline.Split((char)9);
ModuleTypeFileNumber = values[1];
}
if ((newline = reader.ReadLine()) != null)
{
string[] values = newline.Split();
ModuleID = values[0];
ModuleType = values[1];
}
bool AbsorbLines = true;
while (AbsorbLines && ((newline = reader.ReadLine()) != null))
{
string[] values = newline.Split();
if (values[0] == "Readings") AbsorbLines = false;
}
string[] columnnames = { "Summary", "access", "register", "Module & Name", "Value", "unit", "type", "Res" };
string[] columntypes = { "System.Boolean", "System.String", "System.Int32", "System.String", "System.Int32", "System.String", "System.String", "System.String" };
int[] columnwidth = { 1,2,3,35,10,5,5,5 };
DataTable dt = new DataTable();
for(int i =0; i < columnnames.Length; i++)
{
DataColumn colString = new DataColumn(columnnames[i]);
colString.DataType = System.Type.GetType(columntypes[i]);
dt.Columns.Add(colString);
}
while (ImportTable("Controls", reader.ReadLine(), dt, "RO")) { } // Import the "readings" section
while (ImportTable("Status bits", reader.ReadLine(), dt, "RW")) { } // Import the "controls" section
reader.Close();
registerTables.Add(ModuleID, dt);
// create a new tab page
TabPage page = new TabPage(ModuleID);
InterbusRegisters.TabPages.Add(page);
//
// tabPage1
//
Button ResizeButton = new Button();
Button RemoveButton = new Button();
Label VersionLabel = new Label();
Label SerialNolabel = new Label();
TextBox VersionNoTB = new TextBox();
TextBox SerialNoTB = new TextBox();
DataGridView RegistersGrid = new DataGridView();
//
// Set the properties of the DataGrid.
//
RegistersGrid.AccessibleName = ModuleID + "Grid";
RegistersGrid.Location = new System.Drawing.Point(3,29);
RegistersGrid.Width = page.Width - 6;
RegistersGrid.Height = page.Height - 29;
RegistersGrid.Anchor = (AnchorStyles.Top | AnchorStyles.Left);
RegistersGrid.DataSource = dt;
RegistersGrid.Dock = (DockStyle)2;
//
// RemoveButtonRegistersGrid
//
RemoveButton.BackColor = System.Drawing.Color.Red;
RemoveButton.Location = new System.Drawing.Point(3, 4);
RemoveButton.Name = "RemoveButton";
RemoveButton.Size = new System.Drawing.Size(75, 25);
RemoveButton.TabIndex = 0;
RemoveButton.Text = "Remove";
RemoveButton.UseVisualStyleBackColor = false;
RemoveButton.Click += new System.EventHandler(this.RemoveButton_Click);
//
// ResizeButton
//
ResizeButton.BackColor = System.Drawing.Color.DarkOrange;
ResizeButton.Location = new System.Drawing.Point(81, 4);
ResizeButton.Name = "ResizeButton";
ResizeButton.Size = new System.Drawing.Size(75, 25);
ResizeButton.TabIndex = 6;
ResizeButton.Text = "Resize";
ResizeButton.UseVisualStyleBackColor = false;
ResizeButton.Click += new System.EventHandler(this.ResizeButton_Click);
//
// SerialNolabel
//
SerialNolabel.AutoSize = true;
SerialNolabel.Location = new System.Drawing.Point(159, 10);
SerialNolabel.Name = "SerialNolabel";
SerialNolabel.Size = new System.Drawing.Size(53, 13);
SerialNolabel.TabIndex = 4;
SerialNolabel.Text = "Serial No:";
//
// SerialNoTB
//
SerialNoTB.Location = new System.Drawing.Point(215, 7);
SerialNoTB.Name = "SerialNoTB";
SerialNoTB.Size = new System.Drawing.Size(100, 20);
SerialNoTB.TabIndex = 1;
//
// VersionLabel
//
VersionLabel.AutoSize = true;
VersionLabel.Location = new System.Drawing.Point(318, 10);
VersionLabel.Name = "VersionLabel";
VersionLabel.Size = new System.Drawing.Size(45, 13);
VersionLabel.TabIndex = 5;
VersionLabel.Text = "Version:";
//
// VersionTB
//
VersionNoTB.Location = new System.Drawing.Point(366, 7);
VersionNoTB.Name = "VersionTB";
VersionNoTB.Size = new System.Drawing.Size(100, 20);
VersionNoTB.TabIndex = 2;
page.Controls.Add(ResizeButton);
page.Controls.Add(RemoveButton);
page.Controls.Add(VersionLabel);
page.Controls.Add(VersionNoTB);
page.Controls.Add(SerialNolabel);
page.Controls.Add(SerialNoTB);
page.Controls.Add(RegistersGrid);
page.Location = new System.Drawing.Point(4, 22);
page.Size = new System.Drawing.Size(716, 554);
page.TabIndex = 1;
page.UseVisualStyleBackColor = true;
page.Update(); // the following code fails
int k = dt.Columns.Count;
int l = RegistersGrid.ColumnCount;
for (int j = 0; j <= RegistersGrid.ColumnCount - 1; j++)
RegistersGrid.Columns[j].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
RegistersGrid.Columns[3].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
//datagrid has calculated it's widths so we can store them
for (int i = 0; i <= RegistersGrid.ColumnCount - 1; i++)
{
int colw = RegistersGrid.Columns[i].Width; //store autosized widths
RegistersGrid.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.None; //remove autosizing
RegistersGrid.Columns[i].Width = colw; //set width to calculated by autosize
}
}
}

How to find specific dynamic control and get value

I am making student attendance system. I am creating dynamic control and assigning values from database. Now I want to know how to find desired dynamic control and how I will get value from it.
I don't know how I can find desired control using a foreach loop.
This is my code for creating dynamic controls.
public void genControl(StudentAttendence sta)
{
StudentAttendenceBSLDAL stabd = new StudentAttendenceBSLDAL();
List<string[]> liName = stabd.takStudent(sta);
counts = Convert.ToInt16(stabd.takStudent(sta).Count);
for (int i=0; i< stabd.takStudent(sta).Count;i++)
{
for(int j = 0; j<liName[i].Count();j++)
{
Label lblStudentname = new Label();
Label lblStId = new Label();
lblStId.Name = "lblStId"+i.ToString()+j.ToString();
lblStudentname.Name = "liName"+i.ToString()+j.ToString();
lblStId.AutoSize = true;
lblStudentname.AutoSize = true;
if (j==0)
{
lblStId.Text = liName[i][j].ToString();
}
if(j==1)
{
lblStudentname.Text = liName[i][j].ToString();
}
lblStId.AutoSize = true;
lblStudentname.AutoSize = true;
if (i == 1)
{
lblStId.Location = new Point(41, 229);
lblStudentname.Location = new Point(153, 7);
}
else
{
lblStId.Location = new Point(3, 7 + 20);
lblStudentname.Location = new Point(153, 7 + 20);
}
this.Controls.Add(lblStId);
panel1.Controls.Add(lblStudentname);
}
CheckBox cba = new CheckBox();
cba.Name = "cba" + i.ToString() ;
cba.Text = "A";
cba.AutoSize = true;
CheckBox cbp = new CheckBox();
cbp.Name = i.ToString() ;
cbp.Text = "P";
cbp.AutoSize = true;
CheckBox cbl = new CheckBox();
cbl.Name = "cbl" + i.ToString() ;
cbl.Text = "L";
cbl.AutoSize = true;
if (i == 1)
{
cbp.Location = new Point(590, 3);
cba.Location = new Point(631, 3);
cbl.Location = new Point(670, 3);
}
else
{
cbp.Location = new Point(590, 3 + 23);
cba.Location = new Point(631, 3 + 23);
cbl.Location = new Point(670, 3 + 23);
}
panel1.Controls.Add(cbp);
panel1.Controls.Add(cba);
panel1.Controls.Add(cbl);
}
}
This is button control event in which I am trying to find control and get it value.
private void button2_Click(object sender, EventArgs e)
{
StudentAttendence sta = new StudentAttendence();
StudentAttendenceBSLDAL stabd = new StudentAttendenceBSLDAL();
// List<string[]> liName = stabd.takStudent(sta);
for (int i=0;i<counts;i++)
{
CheckBox cbP = panel1.Controls.OfType<CheckBox>().FirstOrDefault(b => b.Name.Equals("cbp"+i.ToString()));
// Label stid = panel1.Controls.Find("lblStId" + i.ToString(), false).First() as Label;
if(!cbP.IsChecked)
{
MessageBox.Show("control found");
}
}
}
You can save your control list into a SortedList.
You can use this sorted list for further processing

New line in FlowLayoutPanel

I am using following code to generate controls dynamically inside a FlowLayoutPanel (win forms - c#). I want to add line break after completion of inner foreach.
var fullText = textBox1.Text;
List<string> listPoints = fullText.Split('#').ToList();
foreach (var listPoint in listPoints)
{
if (listPoint.Contains('^'))
{
var listTextboxes = listPoint.Split('^');
int textBoxCount = listTextboxes.Count();
int index = 1;
foreach (var listTextbox in listTextboxes)
{
CheckBox ck = new CheckBox();
ck.Text = listTextbox;
ck.AutoSize = true;
ck.CheckStateChanged += new EventHandler(this.CheckBox_CheckedChanged);
flowLayoutPanel1.Controls.Add(ck);
if (index < textBoxCount)
{
TextBox tb = new TextBox();
tb.AutoSize = true;
tb.TextChanged += new EventHandler(this.TextBox_TextChanged);
flowLayoutPanel1.Controls.Add(tb);
}
index++;
}
// code for New line break
}
else
{
CheckBox ck = new CheckBox();
ck.Text = listPoint;
ck.AutoSize = true;
ck.CheckStateChanged += new EventHandler(this.CheckBox_CheckedChanged);
flowLayoutPanel1.Controls.Add(ck);
flowLayoutPanel1.
}
Use the SetFlowBreak method:
Control lastControl = null;
if (listPoint.Contains('^')) {
var listTextboxes = listPoint.Split('^');
int textBoxCount = listTextboxes.Count();
int index = 1;
foreach (var listTextbox in listTextboxes) {
CheckBox ck = new CheckBox();
ck.Text = listTextbox;
ck.AutoSize = true;
ck.CheckStateChanged += new EventHandler(this.CheckBox_CheckedChanged);
flowLayoutPanel1.Controls.Add(ck);
if (index < textBoxCount) {
TextBox tb = new TextBox();
tb.AutoSize = true;
tb.TextChanged += new EventHandler(this.TextBox_TextChanged);
flowLayoutPanel1.Controls.Add(tb);
lastControl = tb;
} else {
lastControl = ck;
}
index++;
}
if (lastControl != null) {
flowLayoutPanel1.SetFlowBreak(lastControl, true);
}

Access different columns from LINQ resultset

I have a query which returns multiple columns from the database using LINQ
var donors = from d2 in db.Donors
where d2.Status == "Pending"
select new { donorID = d2.donorID, bloodGroup = d2.bloodGroup, contactNo = d2.contactMobile, status = d2.Status };
now I want to display the results in different Labels accessing one column value from donors resultset.
ex:
Label1.Text = donorID;
Label2.Text = bloodGroup; ...and so on
please help me achieve this.
If you're going to set a label to a value, you'll need a single record. Currently you're selecting a sequence of records. Let's suppose you're only interested in the first value. You could write:
var donors = from d2 in db.Donors
where d2.Status == "Pending"
select new { d2.donorID, d2.bloodGroup,
contactNo = d2.contactMobile, status = d2.Status };
var firstDonor = donors.FirstOrDefault();
if (firstDonor != null)
{
Label1.Text = firstDonor.donorID;
Label2.Text = firstDonor.bloodGroup;
// ...
}
else
{
// There weren't any matching donors
}
If you want to display all the donor details, you'll want something more like a grid.
If you insist in keeping the labels, you could do something like this
var donors = from d2 in db.Donors
where d2.Status == "Pending"
select d2;
List<Donors> myDonors = donors.ToList();
int x = 0;
int y = 0;
foreach (var donor in donors)
{
Label myLabel = new Label();
myLabel.Top = x;
myLabel.Left = y;
myLabel.Text = donor.donorID.ToString();
panel1.Controls.Add(myLabel);
y += myLabel.Width + 5;
myLabel = new Label();
myLabel.Top = x;
myLabel.Left = y;
myLabel.Text = donor.blodGroup.ToString();
panel1.Controls.Add(myLabel);
y += myLabel.Width + 5;
myLabel = new Label();
myLabel.Top = x;
myLabel.Left = y;
myLabel.Text = donor.contactNo.ToString();
panel1.Controls.Add(myLabel);
y += myLabel.Width + 5;
myLabel = new Label();
myLabel.Top = x;
myLabel.Left = y;
myLabel.Text = donor.status.ToString();
panel1.Controls.Add(myLabel);
y += myLabel.Width + 5;
y = 0;
x += myLabel.Height + 5;
}

Categories