loading a datagridview and adding comboboxes - c#

Here is a method I am using to create a datagridview and then add 2 comboboxes. Three DataTables get loaded from other classes.
public void GetWorkorderItems()
{
Workorders wo = new Workorders();
ItemTable = wo.LoadWorkorderItemsTable(_ID);
this.datagridWorkorderItems.DataSource = ItemTable;
this.datagridWorkorderItems.AutoGenerateColumns = true;
this.datagridWorkorderItems.Columns[0].Visible = false;
this.datagridWorkorderItems.Columns[1].HeaderText = "Qty";
this.datagridWorkorderItems.Columns[1].Width = 100;
this.datagridWorkorderItems.Columns[2].HeaderText = "Part";
this.datagridWorkorderItems.Columns[2].Width = 100;
this.datagridWorkorderItems.Columns[3].HeaderText = "Labor";
this.datagridWorkorderItems.Columns[3].Width = 100;
this.datagridWorkorderItems.Columns[4].HeaderText = "Price";
this.datagridWorkorderItems.Columns[4].Width = 150;
this.datagridWorkorderItems.Columns[5].HeaderText = "Description";
this.datagridWorkorderItems.Columns[5].Width = 150;
Parts part = new Parts();
DataTable partdata = new DataTable();
partdata = part.LoadPartTable();
DataGridViewComboBoxColumn pcb = (DataGridViewComboBoxColumn)this.datagridWorkorderItems.Columns[2];
pcb.DataSource = partdata;
pcb.DisplayMember = "PartName";
pcb.ValueMember = "PartID";
datagridWorkorderItems.Columns.Add(pcb);
Labor labor = new Labor();
DataTable data = new DataTable();
data = labor.LoadLaborTable();
DataGridViewComboBoxColumn cb = (DataGridViewComboBoxColumn)this.datagridWorkorderItems.Columns[3];
cb.DataSource = data;
cb.DisplayMember = "LaborItem";
cb.ValueMember = "LaborID";
datagridWorkorderItems.Columns.Add(cb);
}
When the code gets to the creation of the DataGridViewComboBox object the code exits the method and does not add or load the comboboxes. There is no exception thrown either.
Any help?
EDIT****
DataGridViewTextBoxColumn col0 = (DataGridViewTextBoxColumn)this.datagridWorkorderItems.Columns[0];
this.datagridWorkorderItems.Columns[0].DataPropertyName = "WOItemID";
this.datagridWorkorderItems.Columns[0].Visible = false;
this.datagridWorkorderItems.Columns.Add(col0);
DataGridViewTextBoxColumn col1 = (DataGridViewTextBoxColumn)this.datagridWorkorderItems.Columns[1];
this.datagridWorkorderItems.Columns[1].DataPropertyName = "Quantity";
this.datagridWorkorderItems.Columns[1].HeaderText = "Qty";
this.datagridWorkorderItems.Columns[1].Width = 100;
this.datagridWorkorderItems.Columns.Add(col1);
DataGridViewComboBoxColumn pcb = (DataGridViewComboBoxColumn)this.datagridWorkorderItems.Columns[2];
pcb.DataSource = partdata;
pcb.DisplayMember = "PartName";
pcb.ValueMember = "PartID";
datagridWorkorderItems.Columns.Add(pcb);
This might be the way to build the columns if I understand.
***Fixed code that works******
public void GetWorkorderItems()
{
Workorders wo = new Workorders();
ItemTable = wo.LoadWorkorderItemsTable(_ID);
Parts part = new Parts();
DataTable partdata = new DataTable();
partdata = part.LoadPartTable();
Labor labor = new Labor();
DataTable data = new DataTable();
data = labor.LoadLaborTable();
this.datagridWorkorderItems.AutoGenerateColumns = false;
DataGridViewTextBoxColumn col0 = new DataGridViewTextBoxColumn();
col0.DataPropertyName = "WOItemID";
col0.Visible = false;
this.datagridWorkorderItems.Columns.Add(col0);
DataGridViewTextBoxColumn col1 = new DataGridViewTextBoxColumn();
col1.DataPropertyName = "Quantity";
col1.HeaderText = "Qty";
col1.Width = 100;
this.datagridWorkorderItems.Columns.Add(col1);
DataGridViewComboBoxColumn col2 = new DataGridViewComboBoxColumn();
col2.DataPropertyName = "PartID";
col2.DataSource = partdata;
col2.DisplayMember = "PartName";
col2.ValueMember = "PartID";
col2.HeaderText = "Part";
datagridWorkorderItems.Columns.Add(col2);
DataGridViewComboBoxColumn col3 = new DataGridViewComboBoxColumn();
col3.DataPropertyName = "LaborID";
col3.DataSource = data;
col3.DisplayMember = "LaborItem";
col3.ValueMember = "LaborID";
col3.HeaderText = "Labor";
datagridWorkorderItems.Columns.Add(col3);
DataGridViewTextBoxColumn col4 = new DataGridViewTextBoxColumn();
col4.DataPropertyName = "Price";
col4.HeaderText = "Price";
col4.Width = 100;
this.datagridWorkorderItems.Columns.Add(col4);
DataGridViewTextBoxColumn col5 = new DataGridViewTextBoxColumn();
col5.DataPropertyName = "Description";
col5.HeaderText = "Description";
col5.Width = 100;
this.datagridWorkorderItems.Columns.Add(col5);
this.datagridWorkorderItems.DataSource = ItemTable;
}

Try something like this:
public ExampleForm()
{
InitializeComponent();
datagridWorkorderItems.AutoGenerateColumns = false;
DataGridViewTextBoxColumn qtyColumn = new DataGridViewTextBoxColumn();
qtyColumn.DataPropertyName = "Qty";
qtyColumn.HeaderText = "Qty";
datagridWorkorderItems.Columns.Add(qtyColumn);
DataGridViewComboBoxColumn partColumn = new DataGridViewComboBoxColumn();
partColumn.Items.Add(new Part() { ID = 0, PartName = "Tire" });
partColumn.Items.Add(new Part() { ID = 1, PartName = "Motor" });
partColumn.HeaderText = "Part";
partColumn.DataPropertyName = "PartID";
partColumn.ValueMember = "ID";
partColumn.DisplayMember = "PartName";
datagridWorkorderItems.Columns.Add(partColumn);
List<WorkOrder> workOrders = new List<WorkOrder>();
workOrders.Add(new WorkOrder() { Qty = 0, PartID = 0});
workOrders.Add(new WorkOrder() { Qty = 2, PartID = 1});
datagridWorkorderItems.DataSource = workOrders;
}
}
public class WorkOrder
{
public int Qty { get; set; }
public int PartID { get; set; }
}
public class Part
{
public int ID { get; set; }
public string PartName { get; set; }
}

Related

How i can update my second combobox when "SelectedItem" is changed

I've two comboboxes in a form, the first combobox display each "mark" of truck and second may display the models of each "mark". For example if mark is volvo the second combobox may display "FH, FH6 ...", otherwise if mark is "MAN" the second combobox may display "TGX, TGX 38" ...
I've try to do a cycle to refesh my second combobox, each time, that the first combobox is changed.
while (comboBox1.SelectedIndex == -1)
{
comboBox2.Items.Clear();
if (comboBox1.SelectedIndex == 1)
{
comboBox2.DisplayMember = "Modelo";
comboBox2.DataSource = d.Tables["Modelos-MAN"].DefaultView;
}
if (comboBox1.SelectedIndex == 2)
{
comboBox2.DisplayMember = "ModeloV";
comboBox2.DataSource = d.Tables["Modelos-VOLVO"].DefaultView;
comboBox2.Refresh();
}
}
if (comboBox1.SelectedIndex==1)
{
comboBox2.DisplayMember = "Modelo";
comboBox2.DataSource = d.Tables["Modelos-MAN"].DefaultView;
}
if(comboBox1.SelectedIndex == 2)
{
comboBox2.DisplayMember = "ModeloV";
comboBox2.DataSource = d.Tables["Modelos-VOLVO"].DefaultView;
comboBox2.Refresh();
}
Happens that if i select "MAN", it shows "MAN" models and then if i change, and select "Volvo", the second combobox show me "System.Data.DataRowView".
What is happening?How i can solve this?
Note: I've also, a method to generate truck "mark" and "models":
public DataSet LoadMarkAndModel()
{
var marcas = new string[6];
marcas[0] = "Marca ...";
marcas[1] = "MAN";
marcas[2] = "Volvo";//Linha 2 coluna 2
marcas[3] = "DAF";
marcas[4] = "Renault";//Linha 4 coluna 2
marcas[5] = "Mercedes-Benz";
var modelosMAN = new string[7];
var modelosVolvo = new string[5];
modelosMAN[0] = "TGX";
modelosMAN[1] = "TGX D38";
modelosMAN[2] = "TGX EfficientLine 2";
modelosMAN[3] = "TGS";
modelosMAN[4] = "TGA";
modelosMAN[5] = "TGA-WW";
modelosMAN[6] = "TGM";
modelosVolvo[0] = "FH16";
modelosVolvo[1] = "FH";
modelosVolvo[2] = "FM";
modelosVolvo[3] = "FE";
modelosVolvo[4] = "FL";
DataSet data = new DataSet("DataSetOfTrucks");
DataTable table = new DataTable("Marcas");
DataColumn colunaID = new DataColumn("ID", typeof(int));
DataColumn colunaMarca = new DataColumn("Marca", typeof(string));
//table.Columns.Add("Description", typeof(string));
table.Columns.Add(colunaID);
table.Columns.Add(colunaMarca);
for (int i = 0; i < marcas.Length; i++)
{
DataRow manyMark = table.NewRow();
manyMark["ID"] = i + 1;
manyMark["Marca"] = marcas[i];
table.Rows.Add(manyMark);
}
data.Tables.Add(table);
DataTable modelsTable = new DataTable("Modelos-MAN");
DataColumn modelsIDParent = new DataColumn("IDP", typeof(int));
DataColumn modelo = new DataColumn("Modelo", typeof(string));
modelsTable.Columns.Add(modelsIDParent);
modelsTable.Columns.Add(modelo);
int m = 0;
while (m<modelosMAN.Length)
{
DataRow manyModelsMAN = modelsTable.NewRow();
manyModelsMAN["IDP"] = 1;
manyModelsMAN["Modelo"] = modelosMAN[m];
modelsTable.Rows.Add(manyModelsMAN);
m++;
//if (m > modelosMAN.Length)
// break;
}
data.Tables.Add(modelsTable);
////vOLVO
DataTable modelsTableVOLVO = new DataTable("Modelos-VOLVO");
DataColumn modelsIDParentVOLVO = new DataColumn("IDPVolvo", typeof(int));
DataColumn modeloVolvo = new DataColumn("ModeloV", typeof(string));
modelsTableVOLVO.Columns.Add(modelsIDParentVOLVO);
modelsTableVOLVO.Columns.Add(modeloVolvo);
int count = 0;
while (count < modelosVolvo.Length)
{
DataRow manyModelsVolvo = modelsTableVOLVO.NewRow();
manyModelsVolvo["IDPVolvo"] = 2;
manyModelsVolvo["ModeloV"] = modelosVolvo[count];
modelsTableVOLVO.Rows.Add(manyModelsVolvo);
count++;
}
data.Tables.Add(modelsTableVOLVO);
return data;
}
comboBox1_SelectedIndexChanged()
{
comboBox2.DataSource =null;
if (comboBox1.SelectedIndex==1)
{
comboBox2.DataSource = d.Tables["Modelos-MAN"];
comboBox2.ValueMember="Modelo";
comboBox2.DisplayMember = "Modelo";
}
if(comboBox1.SelectedIndex == 2)
{
comboBox2.DataSource = d.Tables["Modelos-VOLVO"];
comboBox2.DisplayMember = "ModeloV";
comboBox2.ValueMember = "ModeloV";
}
}

Getting selected value of dynamic textboxes and comboboxes

I have a winform in c# that I dynamically created two comboboxes and a textbox. When a user selects say the month and year and enters a value in the text box I want get the related comboboxes values when the button is clicked to save. By default the month and year combobox will have the current month and year selected.
There is also another part in the same screen where data will be populated for the previous month like Jan to March for the current year in the comboboxes and the text boxes if available.
I am not sure whether this approach is correct or I should go with a datagridview. Below is the screenshot and my code. Any suggestions on how I can do this.
Screenshot
Code
private void createComboMonths()
{
int width = 79;
int height = 24;
int spacing = 28;
ComboBox[] SubMonths = new ComboBox[12];
for (int i = 0; i <= 11; ++i)
{
SubMonths[i] = new ComboBox();
SubMonths[i].Name = "SubMonths";
SubMonths[i].DropDownStyle = ComboBoxStyle.DropDownList;
SubMonths[i].Size = new Size(width, height);
SubMonths[i].Location = new Point(56, (i * height) + spacing);
SubMonths[i].Items.Add("January");
SubMonths[i].Items.Add("February");
SubMonths[i].Items.Add("March");
SubMonths[i].Items.Add("April");
SubMonths[i].Items.Add("May");
SubMonths[i].Items.Add("June");
SubMonths[i].Items.Add("July");
SubMonths[i].Items.Add("August");
SubMonths[i].Items.Add("September");
SubMonths[i].Items.Add("October");
SubMonths[i].Items.Add("November");
SubMonths[i].Items.Add("December");
SubMonths[i].SelectedItem = DateTime.Today.ToString("MMMM");
plSubscription.Controls.Add(SubMonths[i]);
}
}
private void createComboYears()
{
int width = 79;
int height = 24;
int spacing = 28;
ComboBox[] SubYears = new ComboBox[12];
for (int i = 0; i <= 11; ++i)
{
SubYears[i] = new ComboBox();
SubYears[i].Name = "SubYears";
SubYears[i].DropDownStyle = ComboBoxStyle.DropDownList;
SubYears[i].Size = new Size(width, height);
SubYears[i].Location = new Point(145, (i * height) + spacing);
plSubscription.Controls.Add(SubYears[i]);
fillComboData(SubYears[i]); // Function to fill the last 5 years
}
}
private void createTextBoxes()
{
int width = 79;
int height = 24;
int spacing = 28;
TextBox[] subAmt = new TextBox[12];
for (int i = 0; i <= 11; ++i)
{
subAmt[i] = new TextBox();
subAmt[i].Name = "SubAmt" + i;
subAmt[i].Border.Class = "TextBoxBorder";
subAmt[i].Size = new Size(width, height);
subAmt[i].Margin = new Padding(10, 10, 10, 10);
subAmt[i].Location = new Point(279, (i * height) + spacing);
subAmt[i].KeyPress += new KeyPressEventHandler(txtJanAmt_KeyPress);
plSubscription.Controls.Add(subAmt[i]);
}
}
private void btnSave_Click(object sender, EventArgs e)
{
DataTable dtSubs = new DataTable();
dtSubs.Columns.Add("SubscriberID", typeof(string));
dtSubs.Columns.Add("Month", typeof(string));
dtSubs.Columns.Add("Year", typeof(string));
dtSubs.Columns.Add("SubAmt", typeof(string));
DataRow row = dtSubs.NewRow();
foreach (Control c in plSubscription.Controls)
{
//<- Not sure how do I get the selected row as in the screenshot
}
}
EDIT 1
I used the below code that gets the data from the datatable but not able to do the following
How do I set the value of the comboboxes as selected when I get it from the datatable
For the textbox how do I get the value from the datatable
Whenever there is data available I want that row to be readonly.
Thanks in advance
Changed code
for (int i = 0; i < dt.Rows.Count; i++)
{
#region Grid Column Names
DataGridViewComboBoxColumn mntCmb = new DataGridViewComboBoxColumn();
mntCmb.HeaderText = "Month";
mntCmb.Name = "Month";
mntCmb.DataSource = dt;
mntCmb.DisplayMember = "paidformonth";
mntCmb.ValueMember = "paidformonth";
// <-How do I set the column as selected.
DataGridViewComboBoxColumn yearCmb = new DataGridViewComboBoxColumn();
yearCmb.HeaderText = "Year";
yearCmb.Name = "Year";
yearCmb.DisplayMember = "paidforyear";
yearCmb.ValueMember = "paidforyear";
// <-How do I set the column as selected.
DataGridViewTextBoxColumn amount = new DataGridViewTextBoxColumn();
amount.HeaderText = "Subscription Amount";
amount.Name = "Subscription Amount";
amount.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
// <-How do I set this column with the value from the datatable
#endregion
dgvSubscriptions.Columns.AddRange(mntCmb, yearCmb, amount);
}
Edit 2
I seem to be confused as to why I am getting 3 rows with 6 columns. The datatable only has 2 rows and 3 columns. I am using the above code. I added the ID column just to see what happens. See the screenshot below. I have
dgvSubscriptions.AllowUserToAddRows = true
as I want the user to add rows and enter more data to save. What I am trying to do here is to get a subscription list of months/years that were paid and allow users to add subscription for say May, June assuming Jan to April was paid.
Edit 3
I even set the DataPropertyName instead of the ValueMember still no changes
Edited Code
DataGridViewComboBoxColumn yearCmb = new DataGridViewComboBoxColumn();
yearCmb.HeaderText = "Year";
yearCmb.Name = "Year";
//yearCmb.DataSource = dt;
yearCmb.DisplayMember = "paidforyear";
//yearCmb.ValueMember = "paidforyear";
yearCmb.DataPropertyName= "paidforyear";
yearCmb.DefaultCellStyle.NullValue = dt.Rows[i][2].ToString();
yearCmb.ReadOnly = true;
dgvSubscriptions.Columns.Add(yearCmb);
Edit 4
Below is the actual code that is causing the duplicate columns
dgvSubscriptions.AutoGenerateColumns = false;
dgvSubscriptions.ColumnCount = 1;
dgvSubscriptions.Columns[0].Name = "ID";
dgvSubscriptions.Rows.Clear();
for (int i = 0; i <dt.Rows.Count; i++)
{
dgvSubscriptions.Rows.Add();
#region Grid Column Names
DataGridViewComboBoxColumn mntCmb = new DataGridViewComboBoxColumn();
mntCmb.HeaderText = "Month";
mntCmb.Name = "Month";
//mntCmb.DataSource = dt;
mntCmb.DisplayMember = "paidformonth";
mntCmb.DataPropertyName = "paidformonth";
//mntCmb.ValueMember = "paidformonth";
mntCmb.DefaultCellStyle.NullValue = dt.Rows[i][1].ToString();
mntCmb.ReadOnly = true;
dgvSubscriptions.Columns.Add(mntCmb);
DataGridViewComboBoxColumn yearCmb = new DataGridViewComboBoxColumn();
yearCmb.HeaderText = "Year";
yearCmb.Name = "Year";
//yearCmb.DataSource = dt;
yearCmb.DisplayMember = "paidforyear";
//yearCmb.ValueMember = "paidforyear";
yearCmb.DataPropertyName= "paidforyear";
yearCmb.DefaultCellStyle.NullValue = dt.Rows[i][2].ToString();
yearCmb.ReadOnly = true;
dgvSubscriptions.Columns.Add(yearCmb);
DataGridViewTextBoxColumn amount = new DataGridViewTextBoxColumn();
amount.HeaderText = "Subscription Amount";
amount.Name = "Subscription Amount";
amount.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
//amount.DataPropertyName = dt.Rows[i][2].ToString();
amount.DataPropertyName="subamount";
amount.DefaultCellStyle.NullValue = dt.Rows[i][0].ToString();
amount.ReadOnly = true;
dgvSubscriptions.Columns.Add(amount);
#endregion
}
Edit 5
I used IRSOG code with some modification and below is the full working code.
Working Code
public struct Data
{
public List<string> Mon { get; set; }
public List<string> Year { get; set; }
}
private void fillGridData(DataTable dt)
{
List<string> Mon = new List<string>() { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };
List<string> Year = new List<string>();
int CurrentYear = DateTime.UtcNow.Year;
int NextYear = CurrentYear + 1;
int LastFiveYears = CurrentYear - 5;
for (int i = LastFiveYears; i <= NextYear; i++)
{
Year.Add(i.ToString());
}
List<Data> _Data = new List<Data>();
for (int i = 1; i <= 12; i++)
{
_Data.Add(new Data() { Mon = Mon, Year = Year });
}
dgvSubscriptions.Rows.Clear();
dgvSubscriptions.Refresh();
dgvSubscriptions.Visible = true;
dgvSubscriptions.ColumnHeadersDefaultCellStyle.Font = new Font("Trebuchet MS", 8F, FontStyle.Regular);
dgvSubscriptions.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
dgvSubscriptions.AutoResizeColumns();
dgvSubscriptions.AllowUserToResizeColumns = true;
dgvSubscriptions.AllowUserToOrderColumns = true;
dgvSubscriptions.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
dgvSubscriptions.Dock = DockStyle.None;
dgvSubscriptions.BackgroundColor = this.BackColor;
dgvSubscriptions.BorderStyle = BorderStyle.None;
dgvSubscriptions.AllowUserToAddRows = true;
// If dt.Rows.Count > 0 then show the data - do not allow to change existing data
if (dt.Rows.Count > 0)
{
dgvSubscriptions.Rows.Clear();
dgvSubscriptions.Refresh();
#region Grid Column Names
dgvSubscriptions.AutoGenerateColumns = false;
dgvSubscriptions.Rows.Clear();
DataGridViewComboBoxColumn mntCmb = new DataGridViewComboBoxColumn();
mntCmb.HeaderText = "Month";
mntCmb.Name = "Month";
mntCmb.DataSource = Mon;
mntCmb.DefaultCellStyle.NullValue = "";
dgvSubscriptions.Columns.Add(mntCmb);
DataGridViewComboBoxColumn yearCmb = new DataGridViewComboBoxColumn();
yearCmb.HeaderText = "Year";
yearCmb.Name = "Year";
yearCmb.DataSource = Year;
yearCmb.DefaultCellStyle.NullValue = "";
dgvSubscriptions.Columns.Add(yearCmb);
DataGridViewTextBoxColumn amount = new DataGridViewTextBoxColumn();
amount.HeaderText = "Subscription Amount";
amount.Name = "Subscription Amount";
amount.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
amount.DefaultCellStyle.NullValue = "";
dgvSubscriptions.Columns.Add(amount);
#endregion
#region Populate Grid
for (int i = 0; i <dt.Rows.Count; i++)
{
dgvSubscriptions.Rows.Add();
dgvSubscriptions.Rows[i].Cells[0].Value = dt.Rows[i][1].ToString(); // Month
dgvSubscriptions.Rows[i].Cells[0].ReadOnly = true; // do not allow the user to make changes
dgvSubscriptions.Rows[i].Cells[1].Value = dt.Rows[i][2].ToString(); // Year
dgvSubscriptions.Rows[i].Cells[1].ReadOnly = true; // do not allow the user to make changes
dgvSubscriptions.Rows[i].Cells[2].Value = dt.Rows[i][0].ToString(); // Subscription amount
dgvSubscriptions.Rows[i].Cells[2].ReadOnly = true; // do not allow the user to make changes
}
#endregion
}
else // We come here if dt.Rows.Count is 0 we allow the user to select and save
{
#region Grid Column Names
DataGridViewComboBoxColumn mntCmb = new DataGridViewComboBoxColumn();
mntCmb.HeaderText = "Month";
mntCmb.Name = "Month";
mntCmb.DataSource = Mon;
DataGridViewComboBoxColumn yearCmb = new DataGridViewComboBoxColumn();
yearCmb.HeaderText = "Year";
yearCmb.Name = "Year";
yearCmb.DataSource = Year;
DataGridViewTextBoxColumn amount = new DataGridViewTextBoxColumn();
amount.HeaderText = "Subscription Amount";
amount.Name = "Subscription Amount";
amount.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
#endregion
dgvSubscriptions.Columns.AddRange(mntCmb, yearCmb, amount);
dgvSubscriptions.DataSource = _Data;
}
dgvSubscriptions.RowsDefaultCellStyle.Font = new Font("Trebuchet MS", 8F, FontStyle.Regular);
}
Instead of using this,use DataGridView
Try this:
With Calling GetCurrentRowValues method you can get selected row information's.
Complete Code
public Form1()
{
InitializeComponent();
dataGridView1.MultiSelect = false;
}
private void Form1_Load(object sender, EventArgs e)
{
List<string> Mon = new List<string>() { "January", "February", "March", "April", "May", " June", "July", "August", "September", "October", "November", "December" };
List<string> Year = new List<string>() { "2001", "2002", "2003", "2004", "2005", "2006" };
List<Data> _Data = new List<Data>();
for (int i = 1; i <= 12; i++)
{
_Data.Add(new Data() { Mon = Mon, Year = Year });
}
DataGridViewComboBoxColumn moonCmb = new DataGridViewComboBoxColumn();
moonCmb.HeaderText = "Month";
moonCmb.Name = "Month";
moonCmb.DataSource = Mon;
DataGridViewComboBoxColumn yearCmb = new DataGridViewComboBoxColumn();
yearCmb.HeaderText = "Year";
yearCmb.Name = "Year";
yearCmb.DataSource = Year;
DataGridViewTextBoxColumn amount = new DataGridViewTextBoxColumn();
amount.HeaderText = "Amount";
amount.Name = "Amount";
dataGridView1.Columns.AddRange(moonCmb, yearCmb, amount);
dataGridView1.DataSource = _Data;
}
private void GetCurrentRowValues()
{
var mon = dataGridView1.CurrentRow.Cells["Month"].Value;
var year = dataGridView1.CurrentRow.Cells["Year"].Value;
var amont = dataGridView1.CurrentRow.Cells["Amount"].Value;
}
}
public struct Data
{
public List<string> Mon { get; set; }
public List<string> Year { get; set; }
}
Result
New edit-From data table
#region Grid Column Names
dgvSubscriptions.AutoGenerateColumns = false;
dgvSubscriptions.ColumnCount = 1;
dgvSubscriptions.Columns[0].Name = "ID";
dgvSubscriptions.Rows.Clear();
DataGridViewComboBoxColumn mntCmb = new DataGridViewComboBoxColumn();
mntCmb.HeaderText = "Month";
mntCmb.Name = "Month";
//mntCmb.DataSource = dt;
mntCmb.DisplayMember = "paidformonth";
mntCmb.DataPropertyName = "paidformonth";
//mntCmb.ValueMember = "paidformonth";
mntCmb.DefaultCellStyle.NullValue = "";
mntCmb.ReadOnly = true;
mntCmb.Items.Add("april");
mntCmb.Items.Add("jun");
mntCmb.Items.Add("jull");
dgvSubscriptions.Columns.Add(mntCmb);
DataGridViewComboBoxColumn yearCmb = new DataGridViewComboBoxColumn();
yearCmb.HeaderText = "Year";
yearCmb.Name = "Year";
//yearCmb.DataSource = dt;
yearCmb.DisplayMember = "paidforyear";
//yearCmb.ValueMember = "paidforyear";
yearCmb.DataPropertyName = "paidforyear";
yearCmb.DefaultCellStyle.NullValue = "";
yearCmb.Items.Add("2001");
yearCmb.Items.Add("2002");
yearCmb.Items.Add("2003");
yearCmb.ReadOnly = true;
dgvSubscriptions.Columns.Add(yearCmb);
DataGridViewTextBoxColumn amount = new DataGridViewTextBoxColumn();
amount.HeaderText = "Subscription Amount";
amount.Name = "Subscription Amount";
amount.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
//amount.DataPropertyName = dt.Rows[i][2].ToString();
amount.DataPropertyName = "subamount";
amount.DefaultCellStyle.NullValue = "";
amount.ReadOnly = true;
dgvSubscriptions.Columns.Add(amount);
#endregion
Fill it
for (int i = 0; i < dt.Rows.Count; i++)
{
dgvSubscriptions.Rows.Add();
dgvSubscriptions.Rows[i].Cells[0].Value = dt.Rows[i][0].ToString();
dgvSubscriptions.Rows[i].Cells[1].Value = dt.Rows[i][1].ToString();
dgvSubscriptions.Rows[i].Cells[2].Value = dt.Rows[i][2].ToString();
dgvSubscriptions.Rows[i].Cells[3].Value = dt.Rows[i][0].ToString();
}
The forms ActiveControl property can help you.
var focusedCtrl = this.ActiveControl;
var siblings = Controls.Where(c => c.Location.Y == focusedCtrl.Location.Y).ToList();
foreach (Control c in siblings)
{
// all thise controls are on the same row, providede that the allign
}
Still I would sugget the DataGridView. It seems to be a better choise for a structure that looks like yours.
I’d go with the DataGridView but if you still want to keep this structure you might want to update KeyPressed event handler to look something like this
private string lastUsedTextBox = string.Empty;
private string lastEnteredValue = string.Empty;
private void txtJanAmt_KeyPress(object sender, KeyPressEventArgs e)
{
lastUsedTextBox = (sender as TextBox).Name;
lastEnteredValue = (sender as TextBox).Text;
}
And then when you press the save button you have everything stored here.
If you need to save all the data you can use dictionary or something like that.

How to display hierarchical class fields in Telerik RadGrid?

GetEmployeeDetails() method returns the value of type Employee. I need to display that value in Telerik RadGrid such a way that, when we click on Employee rows it should expands related Address class fields row under the Employee row. Below is the structure of Employee class.
class Employee
{
string EmpId;
string Name;
int Age;
List<Address> address;
}
class Address
{
string Street;
string City;
int Zip;
}
I have written below code to display Employee details at run time in ASP page using Telerik RadGrid. But its displaying only first level- Employee class fields and Address fields with empty. Could you please help me to come out of this issue...?
protected void Page_Load(object sender, EventArgs e)
{
List<Employee> empList = GetEmployeeDetails();
DataSet dataset = new DataSet("DataSet");
System.Data.DataTable dt1 = new System.Data.DataTable();
dt1.TableName = "Employee";
dt1.Columns.Add("EmpId");
dt1.Columns.Add("Name");
dt1.Columns.Add("Age");
dataset.Tables.Add(dt1);
System.Data.DataTable dt2 = new System.Data.DataTable();
dt2.TableName = "Address";
dt2.Columns.Add("EmpId");
dt2.Columns.Add("Street");
dt2.Columns.Add("City");
dt2.Columns.Add("Zip");
dataset.Tables.Add(dt2);
foreach (Employee emp in empList)
{
dt1.Rows.Add(new object[] { emp.empId, emp.name, emp.age });
foreach (Address add in emp.address)
{
dt2.Rows.Add(new object[] {emp.empId, add.street, add.city, add.zip });
}
}
DataRelation rel = new DataRelation("rel", dataset.Tables["Employee"].Columns["EmpId"], dataset.Tables["Address"].Columns["EmpId"]);
dataset.Relations.Add(rel);
RadGrid1.DataSource = dataSet;
RadGrid1.DataBind();
}
Per the Telerik site, you must use the "RadGrid1_NeedDataSource" event to do your binding if you wish to have a hierarchy.
I got it to work by doing the following. (BTW I used your classes and code so it should be easy to mimic as I will post all the code. You also left out the method GetEmployeeDetails(), so I made my own:
private List<Employee> GetEmployeeDetails()
{
List<Employee> myEmployees = new List<Employee>();
Employee Steve = new Employee()
{
Address = new List<Address>() { new Address { City = "op", Street = "thatstreet", Zip = 23312 } },
Age = 23,
EmpId = "Emp1",
Name = "SteveIsTheName"
};
Employee Carol = new Employee()
{
Address = new List<Address>() {
new Address { City = "op2", Street = "thatstreet2", Zip = 23313 },
new Address { City = "op3", Street = "thatstreet3", Zip = 23314 }},
Age = 24,
EmpId = "Emp2",
Name = "CarolIsTheName"
};
myEmployees.Add(Steve);
myEmployees.Add(Carol);
return myEmployees;
}
Step 1: Define the grid's hierarchy view:
protected void RadGrid1_Init(object sender, EventArgs e)
{
DefineGridStructure();
}
private void DefineGridStructure()
{
RadGrid1.MasterTableView.DataKeyNames = new string[] { "EmpId" };
RadGrid1.Width = Unit.Percentage(98);
RadGrid1.PageSize = 3;
RadGrid1.AllowPaging = true;
RadGrid1.AllowSorting = true;
RadGrid1.PagerStyle.Mode = GridPagerMode.NextPrevAndNumeric;
RadGrid1.AutoGenerateColumns = false;
RadGrid1.ShowStatusBar = true;
RadGrid1.MasterTableView.PageSize = 3;
//Add columns
GridBoundColumn boundColumn;
boundColumn = new GridBoundColumn();
boundColumn.DataField = "EmpId";
boundColumn.HeaderText = "EmpId";
RadGrid1.MasterTableView.Columns.Add(boundColumn);
boundColumn = new GridBoundColumn();
boundColumn.DataField = "Name";
boundColumn.HeaderText = "Name";
RadGrid1.MasterTableView.Columns.Add(boundColumn);
boundColumn = new GridBoundColumn();
boundColumn.DataField = "Age";
boundColumn.HeaderText = "Age";
RadGrid1.MasterTableView.Columns.Add(boundColumn);
//Detail table - Orders (II in hierarchy level)
GridTableView tableViewOrders = new GridTableView(RadGrid1);
tableViewOrders.Width = Unit.Percentage(100);
tableViewOrders.DataKeyNames = new string[] { "EmpId" };
GridRelationFields relationFields = new GridRelationFields();
relationFields.MasterKeyField = "EmpId";
relationFields.DetailKeyField = "EmpId";
tableViewOrders.ParentTableRelation.Add(relationFields);
RadGrid1.MasterTableView.DetailTables.Add(tableViewOrders);
//Add columns
boundColumn = new GridBoundColumn();
boundColumn.DataField = "Street";
boundColumn.HeaderText = "Street";
tableViewOrders.Columns.Add(boundColumn);
boundColumn = new GridBoundColumn();
boundColumn.DataField = "City";
boundColumn.HeaderText = "City";
tableViewOrders.Columns.Add(boundColumn);
boundColumn = new GridBoundColumn();
boundColumn.DataField = "Zip";
boundColumn.HeaderText = "Zip";
tableViewOrders.Columns.Add(boundColumn);
}
Step 2: Set your data sources: (No need for DataBind method to be called or relations added, that's done by the grid)
protected void RadGrid1_NeedDataSource(object sender, GridNeedDataSourceEventArgs e)
{
List<Employee> empList = GetEmployeeDetails();
DataSet dataset = new DataSet("DataSet");
System.Data.DataTable dt1 = new System.Data.DataTable();
dt1.TableName = "Employee";
dt1.Columns.Add("EmpId");
dt1.Columns.Add("Name");
dt1.Columns.Add("Age");
dataset.Tables.Add(dt1);
System.Data.DataTable dt2 = new System.Data.DataTable();
dt2.TableName = "Address";
dt2.Columns.Add("EmpId");
dt2.Columns.Add("Street");
dt2.Columns.Add("City");
dt2.Columns.Add("Zip");
dataset.Tables.Add(dt2);
foreach (Employee emp in empList)
{
dt1.Rows.Add(new object[] { emp.EmpId, emp.Name, emp.Age });
foreach (Address add in emp.Address)
{
dt2.Rows.Add(new object[] { emp.EmpId, add.Street, add.City, add.Zip });
}
}
RadGrid1.MasterTableView.DataSource = dataset.Tables["Employee"];
RadGrid1.MasterTableView.DetailTables[0].DataSource = dataset.Tables["Address"];
}
Step 3: Run it.
Obviously you may need to make adjustments to your casing as there may be slight capitalization differences. I also adjusted you classes to allow setting of variable data, nothing big:
class Employee
{
public List<Address> Address { get; set; }
public int Age { get; set; }
public string Name { get; set; }
public string EmpId { get; set; }
}
class Address
{
public string Street { get; set; }
public string City { get; set; }
public int Zip { get; set; }
}
Hope this helps.
-JJ

Bind DataGridviewComboBoxCell into DataGridViw

I have to bind each cell of rows with different data like.
ProductID Color(DataGridviewComboBoxColumn)
1 Red - (ComboboxCell having value only Red,Black,Green and Red is Selected)
....
4 Yellow- (ComboboxCell having value only Yellow,Gold and Yellow is Selected)
When I bind Items of cell and debug it will show Items in DataGridviewComboBoxCell but when going to run application it will display blank on select Combobox.
What can i do for this?
Form Design
private void InitializeComponent()
{
this.dataGridView2 = new System.Windows.Forms.DataGridView();
this.ProductId = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Color = new System.Windows.Forms.DataGridViewComboBoxColumn();
this.ColorIds = new System.Windows.Forms.DataGridViewTextBoxColumn();
((System.ComponentModel.ISupportInitialize)(this.dataGridView2)).BeginInit();
this.SuspendLayout();
//
// dataGridView2
//
this.dataGridView2.AllowUserToAddRows = false;
this.dataGridView2.AllowUserToDeleteRows = false;
this.dataGridView2.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridView2.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.ProductId,
this.Color,
this.ColorIds});
this.dataGridView2.Location = new System.Drawing.Point(12, 12);
this.dataGridView2.Name = "dataGridView2";
this.dataGridView2.Size = new System.Drawing.Size(704, 312);
this.dataGridView2.TabIndex = 1;
//
// ProductId
//
this.ProductId.DataPropertyName = "ProductId";
this.ProductId.HeaderText = "ProductId";
this.ProductId.Name = "ProductId";
//
// Color
//
this.Color.HeaderText = "Color";
this.Color.Name = "Color";
this.Color.Resizable = System.Windows.Forms.DataGridViewTriState.True;
this.Color.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic;
//
// ColorIds
//
this.ColorIds.DataPropertyName = "ColorIds";
this.ColorIds.HeaderText = "ColorIds";
this.ColorIds.Name = "ColorIds";
this.ColorIds.Visible = false;
}
Code :
dataGridView2.AutoGenerateColumns = false;
DataTable dt = //data from Product Table
dataGridView2.DataSource = dt;
DataTable dtColors = //data from Color Table
for (int i = 0; i < dataGridView2.Rows.Count; i++)
{
String ColorIds = dataGridView2.Rows[i].Cells["ColorIds"].Value.ToString();
DataTable dtfiltered = dtColors.Select("ColorId IN (" + ColorIds + ")").CopyToDataTable();
DataGridViewComboBoxCell col = (DataGridViewComboBoxCell)dataGridView2.Rows[i].Cells["Color"];
col.Items.Clear();
foreach (DataRow dr in dtfiltered.Rows)
{
col.Items.Add(new ComboBoxItem(dr["ColorId"].ToString(), dr["Color"].ToString()));
}
col.Value = col.Items[0];
}

How to display two table rows on single click in Telerik RadGrid

I have one class which contains two more classes like hierarchy. When I'm displaying in Telerik RadGrid it should display like, when we click on first class row then it should display two rows of related classes as in below figure. Could help me to do this..?
As I answered your previous post, I just took my other answer and modified it to do what you are looking for. The following is the addition of a class that stores hobby info. I then added the needed structure and relations (the different colored squares denote the different classes):
Note: The changes here are minimal and the changes are commented as //New something// so they should be easy to see.
protected void Page_Load(object sender, EventArgs e)
{
}
protected void RadGrid1_Init(object sender, EventArgs e)
{
DefineGridStructure();
}
private void DefineGridStructure()
{
RadGrid1.MasterTableView.DataKeyNames = new string[] { "EmpId" };
RadGrid1.Width = Unit.Percentage(98);
RadGrid1.PageSize = 5;
RadGrid1.AllowPaging = true;
RadGrid1.AllowSorting = true;
RadGrid1.PagerStyle.Mode = GridPagerMode.NextPrevAndNumeric;
RadGrid1.AutoGenerateColumns = false;
RadGrid1.ShowStatusBar = true;
RadGrid1.MasterTableView.PageSize = 5;
//Add columns
GridBoundColumn boundColumn;
boundColumn = new GridBoundColumn();
boundColumn.DataField = "EmpId";
boundColumn.HeaderText = "EmpId";
RadGrid1.MasterTableView.Columns.Add(boundColumn);
boundColumn = new GridBoundColumn();
boundColumn.DataField = "Name";
boundColumn.HeaderText = "Name";
RadGrid1.MasterTableView.Columns.Add(boundColumn);
boundColumn = new GridBoundColumn();
boundColumn.DataField = "Age";
boundColumn.HeaderText = "Age";
RadGrid1.MasterTableView.Columns.Add(boundColumn);
//Detail table - Orders (II in hierarchy level)
GridTableView tableViewOrders = new GridTableView(RadGrid1);
tableViewOrders.Width = Unit.Percentage(100);
tableViewOrders.DataKeyNames = new string[] { "EmpId" };
GridRelationFields relationFields = new GridRelationFields();
relationFields.MasterKeyField = "EmpId";
relationFields.DetailKeyField = "EmpId";
tableViewOrders.ParentTableRelation.Add(relationFields);
RadGrid1.MasterTableView.DetailTables.Add(tableViewOrders);
//Add columns
boundColumn = new GridBoundColumn();
boundColumn.DataField = "Street";
boundColumn.HeaderText = "Street";
tableViewOrders.Columns.Add(boundColumn);
boundColumn = new GridBoundColumn();
boundColumn.DataField = "City";
boundColumn.HeaderText = "City";
tableViewOrders.Columns.Add(boundColumn);
boundColumn = new GridBoundColumn();
boundColumn.DataField = "Zip";
boundColumn.HeaderText = "Zip";
tableViewOrders.Columns.Add(boundColumn);
//New Detail Table #2 - adds in a another class that stores data
GridTableView tableViewOrders2 = new GridTableView(RadGrid1);
tableViewOrders2.Width = Unit.Percentage(100);
tableViewOrders2.DataKeyNames = new string[] { "EmpId" };
GridRelationFields relationFields2 = new GridRelationFields();
relationFields2.MasterKeyField = "EmpId";
relationFields2.DetailKeyField = "EmpId";
tableViewOrders2.ParentTableRelation.Add(relationFields2);
RadGrid1.MasterTableView.DetailTables.Add(tableViewOrders2);
//Add columns
boundColumn = new GridBoundColumn();
boundColumn.DataField = "HobbyName";
boundColumn.HeaderText = "HobbyName";
tableViewOrders2.Columns.Add(boundColumn);
}
protected void RadGrid1_NeedDataSource(object sender, GridNeedDataSourceEventArgs e)
{
List<Employee> empList = GetEmployeeDetails();
DataSet dataset = new DataSet("DataSet");
System.Data.DataTable dt1 = new System.Data.DataTable();
dt1.TableName = "Employee";
dt1.Columns.Add("EmpId");
dt1.Columns.Add("Name");
dt1.Columns.Add("Age");
dataset.Tables.Add(dt1);
System.Data.DataTable dt2 = new System.Data.DataTable();
dt2.TableName = "Address";
dt2.Columns.Add("EmpId");
dt2.Columns.Add("Street");
dt2.Columns.Add("City");
dt2.Columns.Add("Zip");
dataset.Tables.Add(dt2);
//New datatable that stores the new classes' data
DataTable dt3 = new DataTable();
dt3.TableName = "Hobby";
dt3.Columns.Add("EmpId");
dt3.Columns.Add("HobbyName");
dataset.Tables.Add(dt3);
foreach (Employee emp in empList)
{
dt1.Rows.Add(new object[] { emp.EmpId, emp.Name, emp.Age });
foreach (Address add in emp.Address)
{
dt2.Rows.Add(new object[] { emp.EmpId, add.Street, add.City, add.Zip });
}
//New data add loop
foreach (Hobby hob in emp.Hobby)
{
dt3.Rows.Add(new object[] { emp.EmpId, hob.HobbyName });
}
}
RadGrid1.MasterTableView.DataSource = dataset.Tables["Employee"];
RadGrid1.MasterTableView.DetailTables[0].DataSource = dataset.Tables["Address"];
//Add the new table to the grid
RadGrid1.MasterTableView.DetailTables[1].DataSource = dataset.Tables["Hobby"];
}
private List<Employee> GetEmployeeDetails()
{
List<Employee> myEmployees = new List<Employee>();
Employee Steve = new Employee()
{
Address = new List<Address>() { new Address { City = "op", Street = "thatstreet", Zip = 23312 } },
Hobby = new List<Hobby>() { new Hobby() { HobbyName = "Skating" } },
Age = 23,
EmpId = "Emp1",
Name = "SteveIsTheName"
};
Employee Carol = new Employee()
{
Address = new List<Address>() {
new Address { City = "op2", Street = "thatstreet2", Zip = 23313 },
new Address { City = "op3", Street = "thatstreet3", Zip = 23314 }},
Hobby = new List<Hobby>() { new Hobby() { HobbyName = "Fishing" } },
Age = 24,
EmpId = "Emp2",
Name = "CarolIsTheName"
};
myEmployees.Add(Steve);
myEmployees.Add(Carol);
return myEmployees;
}
}
class Employee
{
public List<Address> Address { get; set; }
public List<Hobby> Hobby { get; set; }
public int Age { get; set; }
public string Name { get; set; }
public string EmpId { get; set; }
}
class Address
{
public string Street { get; set; }
public string City { get; set; }
public int Zip { get; set; }
}
class Hobby
{
public string HobbyName { get; set; }
}

Categories

Resources