Match the columns using a data dictionary in C# winForm - c#

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();
}

Related

How to bind dynamically created text box?

I'm trying to create pricelist for hotel. I'm having a list of dates, and list of room types in hotel. That lists can contain random number of elements. That is created dynamically, and here is the code:
private void CreateControls() { var colIndex = 0;
var vrsteSoba = _Presenter.VrstaSobeDto.ToArray();
foreach (var bindingItem in vrsteSoba)
{
var lbl = new Label()
{
Width = LABEL_WIDTH,
Height = LABEL_HEIGHT - 5,
Left = 10,
Top = 30 + colIndex * (EDIT_BOX_HEIGHT + SPACE_BETWEEN_CONTROL),
Text = bindingItem
};
_dataPanel.Controls.Add(lbl);
colIndex++;
}
int a = 1;
foreach (var date in _Presenter.CeneTarifa)
{
int y = 0;
var panel = new Panel
{
Height = PANEL_HEIGHT * (vrsteSoba.Length-4),
Width = EDIT_BOX_WIDTH,
Left = a * (EDIT_BOX_WIDTH + SPACE_BETWEEN_CONTROL + 50),
Top = 5
};
_dataPanel.Controls.Add(panel);
var label = new Label
{
Height = EDIT_BOX_HEIGHT,
Location = new Point(0, 10),
Text = date.Datum,
Margin = new Padding(0)
};
panel.Controls.Add(label);
int index = 0;
foreach (var item in date.VrstaSobeCena)
{
var box = new TextBox();
panel.Controls.Add(box);
box.Height = EDIT_BOX_HEIGHT;
box.Width = EDIT_BOX_WIDTH;
box.Location = new Point(0, 30 + y * (EDIT_BOX_HEIGHT + SPACE_BETWEEN_CONTROL));
box.DataBindings.Add(new Binding(nameof(box.Text), date, date.Cena[index].Cena1));
y++;
index++;
}
++a;
}
_dataPanel.AutoScroll = true;
}`
Here is image of that representation.
Now I'm facing a problem of data binding. I need to bind price, two way, for each text box. And I'm stuck.
I have tried to bind it to property name, but then all boxes get same value. If I try to bind it to value via index, I'm getting error
Cannot bind to the property or column 34 on the DataSource. Parameter name: dataMember
Code below is used to fill model that is used in presenter
` private void FillCenePoTarifi() { var sobeArr = VrstaSobeDto.ToArray();
foreach (var datum in Datumi)
{
var dictionary = new Dictionary<string, decimal>();
var cene = new List<Cena>();
foreach (var item in sobeArr)
{
var tarif = _Tarife.Where(x => x.SifTarife == item).FirstOrDefault();
if (tarif != null)
_SastavTarife = HotelierServerLocal.Default.TarifaViewBlo.GetSastaveTarife(tarif.IdTarife);
//proveriti ovu logiku
var cena = _SastavTarife.Where(x => x.Cena1 != 0).Select(c => c.Cena1).FirstOrDefault();
cene.Add(new Cena { Cena1 = cena.ToString()});
dictionary.Add(item, cena);
}
var model = new CenePoTarifi
{
Datum = datum,
VrstaSobeCena = dictionary,
Cena = cene
};
CeneTarifa.Add(model);
}
}`
Finally here are classes that use as model.
` public class CenePoTarifi{
public Dictionary<string, decimal> VrstaSobeCena { get; set; } = new Dictionary<string, decimal>();
public string Datum { get; set; }
private List<Cena> _Cena;
public List<Cena> Cena
{
get => _Cena;
set
{
_Cena = value;
NotifyPropertyChanged("Cena");
}
}
public class Cena :
{
private string _Cena1;
public string Cena1
{
get => _Cena1;
set
{
_Cena = value;
NotifyPropertyChanged("Cena1");
}
}
}`
Does anyone has any suggestions?
Your question is: How to bind dynamically created text box. Here is one tested way for accomplishing that specific task.
First create some textboxes dynamically:
public MainForm()
{
InitializeComponent();
buttonRandom.Click += (sender, e) => generateRandomList();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
List<TextBox> tmp = new List<TextBox>();
for (int column = 1; column < tableLayoutPanel.ColumnCount; column++)
{
for (int row = 1; row < tableLayoutPanel.RowCount; row++)
{
TextBox textBox = new TextBox { Anchor = (AnchorStyles)0xF };
tableLayoutPanel.Controls.Add(textBox, column, row);
tmp.Add(textBox);
textBox.KeyDown += onAnyTextBoxKeyDown;
}
}
_textboxes = tmp.ToArray();
// Generate first dataset
generateRandomList();
}
TextBox[] _textboxes = null;
Then, whenever a new random list is generated, clear any old text and databindings from every TextBox before creating a new data binding for it.
public static Random Rando { get; } = new Random(2);
private void generateRandomList()
{
// Clear ALL the data + bindings for ALL the textboxes.
foreach (var textbox in _textboxes)
{
textbox.Clear();
textbox.DataBindings.Clear();
}
// Generate and create new bindings
int count = Rando.Next(1, 79);
for (int i = 0; i < count; i++)
{
var textbox = _textboxes[i];
VrstaSobeCena vrstaSobeCena =
new VrstaSobeCena{ Sobe = (Sobe)tableLayoutPanel.GetRow(textbox) };
textbox.Tag = vrstaSobeCena;
textbox.DataBindings.Add(
new Binding(
nameof(TextBox.Text),
vrstaSobeCena,
nameof(VrstaSobeCena.Cena),
formattingEnabled: true,
dataSourceUpdateMode: DataSourceUpdateMode.OnPropertyChanged,
null,
"F2"
));
// TO DO
// ADD vrstaSobeCena HERE to the Dictionary<string, decimal> VrstaSobeCena
}
}
The classes shown in your code as binding sources may not bind correctly. One issue I noticed is that the property setters are failing to check whether the value has actually changed before firing the notification. Here's an example of doing that correctly. (For testing purposes I'm showing a Minimal Reproducible Sample "mock" version of a class that implements INotifyPropertyChanged.)
enum Sobe { APP4 = 1, APP5, STUDIO, SUP, APP6, STAND, STDNT, COMSTU, LUXSTU, APP4C, APP4L, APP62, APP6L }
class VrstaSobeCena : INotifyPropertyChanged
{
decimal _price = 100 + (50 * (decimal)Rando.NextDouble());
public decimal Cena
{
get => _price;
set
{
if (!Equals(_price, value))
{
_price = value;
OnPropertyChanged();
}
}
}
Sobe _sobe = 0;
public Sobe Sobe
{
get => _sobe;
set
{
if (!Equals(_sobe, value))
{
_sobe = value;
OnPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Finally, one way to test the two-way binding is to intercept the [Enter] key.
private void onAnyTextBoxKeyDown(object sender, KeyEventArgs e)
{
if ((e.KeyCode == Keys.Enter) && (sender is TextBox textbox))
{
e.SuppressKeyPress = e.Handled = true;
VrstaSobeCena vrstaSobeCena = (VrstaSobeCena)textbox.Tag;
string msg = $"Price for {vrstaSobeCena.Sobe} is {vrstaSobeCena.Cena.ToString("F2")}";
BeginInvoke((MethodInvoker)delegate {MessageBox.Show(msg); });
SelectNextControl(textbox, forward: true, tabStopOnly: true, nested: false, wrap: true);
}
}
Create a List for storing the textbox:
List<TextBox> lstTextbox = new List<TextBox>();
Create a class object that stores the values of "Date" and "room type"
public class RoomTypeDate
{
public string RoomType = "";
public string DateRange = "";
}
Immediately after you created the textbox, assigned the RoomTypeDate info to the tag, add it to lstTextbox.
foreach (var item in date.VrstaSobeCena)
{
var box = new TextBox();
panel.Controls.Add(box);
box.Height = EDIT_BOX_HEIGHT;
box.Width = EDIT_BOX_WIDTH;
box.Location = new Point(0, 30 + y * (EDIT_BOX_HEIGHT + SPACE_BETWEEN_CONTROL));
box.DataBindings.Add(new Binding(nameof(box.Text), date, date.Cena[index].Cena1));
// add the box to the list
lstTextbox.Add(box);
// mark the box with RoomType and DateRange
RoomTypeDate rtd = new RoomTypeDate();
rtd.RoomType = "APP4"; // get the room type
rtd.DateRange = "1.6 - 30.6"; // get date range
box.Tag = rtd;
y++;
index++;
}
Now, to get and set the room price:
public void SetRoomPrice(decimal price, string roomType, string dateRange)
{
foreach (var tb in lstTextBox)
{
var rtd = (RoomTypeDate)tb.Tag;
if(rtd.RoomType == roomType && rtd.DateRange == dateRange)
{
tb.Text = price.ToString();
return;
}
}
}
public decimal GetRoomPrice(string roomType, string dateRange)
{
foreach (var tb in lstTextBox)
{
var rtd = (RoomTypeDate)tb.Tag;
if(rtd.RoomType == roomType && rtd.DateRange == dateRange)
{
return Convert.ToDecimal(rt.Text);
}
}
return 0m;
}
*code untested, might contains bugs

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

c# pass different variables to button onClick event

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.

List<> ends up being null; can't seem to .Add properly

I have a GridView with CheckBoxes and I wish to retrieve Cell[1] in every row that was checked. The list always end up being 'null'. The code is below. I added a string to display the output and that works fine. So I'm probably Adding it incorrectly but I don't know what. Any help would be appreciated. Cheers~
List<int> indices = new List<int>();
CheckBox cb = new CheckBox();
string text = "";
foreach (GridViewRow row in GV0.Rows)
{
if (((CheckBox)row.FindControl("CheckBox1")).Checked)
{
text += row.Cells[1].Text;
indices.Add(int.Parse(row.Cells[1].Text));
}
}
Label1.Text = text;
Session["indicesList"] = indices;
Response.Redirect("About.aspx");
The code for the page that is being redirected to:
List<List<string>> all = new List<List<string>>();
List<string> fields = new List<string>();
List<Type> fieldtypes = new List<Type>();
List<int> indices = new List<int>();
int show = 0;
if (!Page.IsPostBack)
{
all = (List<List<string>>)Session["all"];
fields = (List<string>)Session["fields"];
fieldtypes = (List<Type>)Session["fieldtypes"];
indices = (List<int>)Session["indiceslist"];
show = (int)Session["show"];
}
int j = 0;
List<List<string>> dupes = new List<List<string>>();
for (int i = 0; i < show; i++)
{
if (j < indices.Count)
{
if (int.Parse(all[i][0]) == indices[j])
{
dupes.Add(all[i]);
j++;
}
}
}
You're setting your list in the session with a key of indicesList but you're retrieving it with a key of indiceslist (Note the difference in case on the letter "L").
I would suggest creating a property for your list that gets and sets from the session. It makes it much easier to manage.
public List<int> Indices
{
get
{
var val = Session["indicesList"] as List<int>;
if(val == null)
{
val = new List<int>();
Session["indicesList"] = val;
}
return val;
}
set
{
Session["indicesList"] = value;
}
}

Categories