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";
}
}
Related
I'm trying to allow the user to upload existing information to a data table. Here's what the code is for the upload:
private void label30_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() == DialogResult.OK)
{
StreamReader read = new StreamReader(File.OpenRead(ofd.FileName));
string[] lines = File.ReadAllLines(ofd.FileName);
string[] values;
for (int i = 31; i < lines.Length; i++)
{
values = lines[i].ToString().Split(',');
string[] row = new string[values.Length];
for (int j = 0; j < values.Length; j++)
{
row[j] = values[j].Trim();
}
stkSheetdgv.Rows.Add(row);
read.Close();
read.Dispose();
}
}
}
There is a lot of other information inside the text file, hence the reason int i = 31. I'm getting System.InvalidOperationException: 'Rows cannot be programmatically added to the DataGridView's rows collection when the control is data-bound.'
Can someone tell me what is missing to make this work? I can add more code for the dt if necessary. Let me know.
stkSheetdgv.AutoGenerateColumns = false;
DataTable dt = new DataTable();
dt.Columns.Add("Wire", typeof(String));
dt.Columns.Add("Pole", typeof(String));
dt.Columns.Add("Primary Unit", typeof(String));
dt.Columns.Add("Down Guy", typeof(String));
dt.Columns.Add("Anchor", typeof(String));
dt.Columns.Add("Transformer", typeof(String));
dt.Columns.Add("Ground", typeof(String));
dt.Columns.Add("Riser/Disconnect", typeof(String));
dt.Columns.Add("Misc.", typeof(String));
DataGridViewComboBoxColumn wire = new DataGridViewComboBoxColumn();
var wirelist = new List<string>() {"AAC 1/0 POPPY", "AAC 477 COSMOS"};
wire.DataSource = wirelist;
wire.HeaderText = "Wire";
wire.DataPropertyName = "Wire";
DataGridViewComboBoxColumn pole = new DataGridViewComboBoxColumn();
var polelist = new List<string>() {"30C4 CCA", "30C5 CCA"};
pole.DataSource = polelist;
pole.HeaderText = "Pole";
pole.DataPropertyName = "Pole";
DataGridViewComboBoxColumn primary = new DataGridViewComboBoxColumn();
var primarylist = new List<string>() {"C1-LD", "C2-LD"};
primary.DataSource = primarylist;
primary.HeaderText = "Primary Unit";
primary.DataPropertyName = "Primary Unit";
DataGridViewComboBoxColumn down = new DataGridViewComboBoxColumn();
var downlist = new List<string>() {"E1-5-144", "E1-5-144P"};
down.DataSource = downlist;
down.HeaderText = "Down Guy";
down.DataPropertyName = "Down Guy";
DataGridViewComboBoxColumn anch = new DataGridViewComboBoxColumn();
var anchlist = new List<string>() {"F1-2 Expansion", "F1-2 Plate"};
anch.DataSource = anchlist;
anch.HeaderText = "Anchor";
anch.DataPropertyName = "Anchor";
DataGridViewComboBoxColumn trans = new DataGridViewComboBoxColumn();
var translist = new List<string>() { "G311-15kVA", "G311-25kVA"};
trans.DataSource = translist;
trans.HeaderText = "Transformer";
trans.DataPropertyName = "Transformer";
DataGridViewComboBoxColumn ground = new DataGridViewComboBoxColumn();
var groundlist = new List<string>() { "M2-12", "M2-11" };
ground.DataSource = groundlist;
ground.HeaderText = "Ground";
ground.DataPropertyName = "Ground";
DataGridViewComboBoxColumn rise = new DataGridViewComboBoxColumn();
var riserlist = new List<string>() { "M8-60-10'", "M8-100-10'"};
rise.DataSource = riserlist;
rise.HeaderText = "Riser/Disconnect";
rise.DataPropertyName = "Riser/Disconnect";
DataGridViewComboBoxColumn misc = new DataGridViewComboBoxColumn();
var misclist = new List<string>() { "M5-5LD", "M5-5HD"};
misc.DataSource = misclist;
misc.HeaderText = "Misc.";
misc.DataPropertyName = "Misc.";
stkSheetdgv.DataSource = dt;
stkSheetdgv.Columns.AddRange(wire, pole, primary, down, anch, trans, ground, rise, misc);
stkSheetdgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
There are two different ways to resolve this issue, either by removing the assignment of the DataSource (e.g. remove stkSheetdgv.DataSource = dt;) on the DataGridView, or adding to the DataSource explicitly:
Code
private void label30_Click(object sender, EventArgs e)
{
DataTable dataTable = (DataTable)stkSheetdgv.DataSource;
OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() == DialogResult.OK)
{
using (StreamReader read = new StreamReader(File.OpenRead(ofd.FileName)))
{
string[] lines = File.ReadAllLines(ofd.FileName);
string[] values;
for (int i = 31; i < lines.Length; i++)
{
values = lines[i].ToString().Split(',');
var dataRow = dataTable.NewRow();
for (int j = 0; j < values.Length; j++)
{
dataRow[j] = values[j].Trim();
}
dataTable.Rows.Add(dataRow);
dataTable.AcceptChanges();
}
}
}
}
Edit
The reason that you're receiving the error is due to the csv having more columns than specified on the DataTable. The CSV file that I used was:
AAC 1/0 POPPY,30C4 CCA,C1-LD,E1-5-144,F1-2 Expansion,G311-15kVA,M2-12,M8-60-10',M5-5LD
AAC 477 COSMOS,30C5 CCA,C2-LD,E1-5-144P,F1-2 Plate,G311-25kVA,M2-11,M8-100-10',M5-5HD
Which worked perfectly fine for me.
this question has been asked but mine has a different approach link 1
l have a datatable with the following data
DataTable dtProduct = new DataTable();
dtProduct.Columns.Add("productId");
dtProduct.Columns.Add("name");
DataRow dataRow = dtProduct.NewRow();
dataRow["productId"] = 1;
dataRow["name"] = "Burger";
dtProduct.Rows.Add(dataRow);
DataRow dataRow2 = dtProduct.NewRow();
dataRow2["productId"] = 2;
dataRow2["name"] = "Chicken";
dtProduct.Rows.Add(dataRow2);
DataTable dtSales = new DataTable();
dtSales.Columns.Add("productId");
dtSales.Columns.Add("saleId");
dtSales.Columns.Add("month");
dtSales.Columns.Add("quantity");
DataRow dataSalesRow = dtSales.NewRow();
dataSalesRow["productId"] = 1;
dataSalesRow["saleId"] = "1";
dataSalesRow["month"] = "Jan";
dataSalesRow["quantity"] = 3433;
dtSales.Rows.Add(dataSalesRow);
DataRow drSales2 = dtSales.NewRow();
drSales2["productId"] = 1;
drSales2["saleId"] = "2";
drSales2["month"] = "Feb";
drSales2["quantity"] = 56;
dtSales.Rows.Add(drSales2);
DataRow drSales3 = dtSales.NewRow();
drSales3["productId"] = 1;
drSales3["saleId"] = "3";
drSales3["month"] = "Mar";
drSales3["quantity"] = 34522;
dtSales.Rows.Add(drSales3);
DataRow drSales4 = dtSales.NewRow();
drSales4["productId"] = 2;
drSales4["saleId"] = "4";
drSales4["month"] = "Feb";
drSales4["quantity"] = 345;
dtSales.Rows.Add(drSales4);
And another sample 2
DataTable dtStudents = new DataTable();
dtStudents.Columns.Add("studentId");
dtStudents.Columns.Add("fullname");
DataRow drStudentrow = dtStudents.NewRow();
drStudentrow["studentId"] = 1;
drStudentrow["fullname"] = "Bil";
dtStudents.Rows.Add(drStudentrow);
DataRow drStudentrow2 = dtStudents.NewRow();
drStudentrow2["studentId"] = 2;
drStudentrow2["fullname"] = "Paul";
dtStudents.Rows.Add(drStudentrow2);
DataTable dtStudentExam = new DataTable();
dtStudentExam.Columns.Add("studentId");
dtStudentExam.Columns.Add("subjectId");
dtStudentExam.Columns.Add("mark");
DataRow dataStudentExamRow = dtStudentExam.NewRow();
dataStudentExamRow["studentId"] = 1;
dataStudentExamRow["subjectId"] = "E123";
dataStudentExamRow["mark"] = 34;
dtStudentExam.Rows.Add(dataStudentExamRow);
DataRow dataStudentExamRow2 = dtStudentExam.NewRow();
dataStudentExamRow2["studentId"] = 2;
dataStudentExamRow2["subjectId"] = "E123";
dataStudentExamRow2["mark"] = 90;
dtStudentExam.Rows.Add(dataStudentExamRow2);
DataRow dataStudentExamRow3 = dtStudentExam.NewRow();
dataStudentExamRow3["studentId"] = 1;
dataStudentExamRow3["subjectId"] = "E155";
dataStudentExamRow3["mark"] = 78;
dtStudentExam.Rows.Add(dataStudentExamRow3);
DataRow dataStudentExamRow4 = dtStudentExam.NewRow();
dataStudentExamRow4["studentId"] = 1;
dataStudentExamRow4["subjectId"] = "E101";
dataStudentExamRow4["mark"] = 12;
dtStudentExam.Rows.Add(dataStudentExamRow4);
DataRow dataStudentExamRow5 = dtStudentExam.NewRow();
dataStudentExamRow5["studentId"] = 1;
dataStudentExamRow5["subjectId"] = "E234";
dataStudentExamRow5["mark"] = 42;
dtStudentExam.Rows.Add(dataStudentExamRow5);
DataTable products(dtProduct ) has a productId which is the key and another data table sales (dtSales) has sales for the product based on month . and has a column productId .
what l want to achieve is merge this two tables to this
Same Applies for students
l have a data table student (dtStudents) but l however l have student exam marks data tables (dtStudentExam) for each subject
and combine to something like this
So my question is can l do this dynamically . l tried the following below
public static System.Data.DataTable MergeRowsToColumns(DataTable rowDataTable, string rowDataTableIdColumnName, string friendlyName, DataTable columData)
{
List<string> columnsToAdd = new List<string>();
if (rowDataTable == null)
{
return null;
}
DataTable finalDataTable = new DataTable();
finalDataTable.Columns.Add(friendlyName.ToLower());
finalDataTable.Columns.Add(rowDataTableIdColumnName.ToLower());
foreach (DataColumn column in columData.Columns)
{
if (column.ColumnName.ToString() == rowDataTableIdColumnName.ToString())
{
continue;
}
else
{
finalDataTable.Columns.Add(column.ColumnName.ToString());
columnsToAdd.Add(column.ColumnName.ToString());
}
}
foreach (DataRow row in rowDataTable.Rows)
{
DataRow newRow = finalDataTable.NewRow();
newRow[rowDataTableIdColumnName] = row[rowDataTableIdColumnName];
newRow[friendlyName] = row[friendlyName];
foreach (DataRow columnRows in columData.Rows)
{
foreach (string column in columnsToAdd)
{
var value = columnRows[column].ToString();
newRow[column] = value;
}
}
finalDataTable.Rows.Add(newRow);
}
return finalDataTable;
}
Algorithm logic
Table 1 holds the key information
Table 2 holds the value data for table
using a column name from table one for id which will be the same on table 2
can l do it generically
in one function like
var dtMergedProducts = HelperDataTable.MergeRowsToColumns(dtProduct, "productId", "name", dtSales);
var dtStudents = HelperDataTable.MergeRowsToColumns(dtStudents, "studentId", "fullname", dtStudentExam);
Please am retrieving the data as is hence can not group by in table 2 and also table two does not have a friendly name that will be displayed.
Most of the data that is loaded is not more than 100 000
this is the link of the helper utility am making git hub
Edit One
DataTable 2 will have column value one for column and the other for value
For example
dtSales
1- month : shown vertically
2- quantity: will be cell value
Sample 2
dtStudentExam
1- subjectId : shown vertically
2- mark : will be the student mark
l got it working this morning
here if the method
public static System.Data.DataTable MergeRowsToColumns(DataTable rowDataTable, string rowDataTableIdColumnName, string friendlyName, DataTable dataAllValue , string dataColumnValue , string dataColumnKey)
{
List<string> columnsToAdd = new List<string>();
if (rowDataTable == null)
{
return null;
}
DataTable finalDataTable = new DataTable();
finalDataTable.Columns.Add(friendlyName.ToLower());
finalDataTable.Columns.Add(rowDataTableIdColumnName.ToLower());
foreach (DataRow row in dataAllValue.Rows)
{
if (row[rowDataTableIdColumnName].ToString() == rowDataTableIdColumnName.ToString())
{
continue;
}
else
{
var isExistColumnValue = columnsToAdd.Where(c => c == row[dataColumnKey].ToString()).FirstOrDefault();
if(isExistColumnValue == null)
{
columnsToAdd.Add(row[dataColumnKey].ToString());
finalDataTable.Columns.Add(row[dataColumnKey].ToString());
}
}
}
foreach (DataRow row in rowDataTable.Rows)
{
DataRow newRow = finalDataTable.NewRow();
newRow[rowDataTableIdColumnName] = row[rowDataTableIdColumnName];
newRow[friendlyName] = row[friendlyName];
foreach (DataRow columnRows in dataAllValue.Rows)
{
if(row[rowDataTableIdColumnName].ToString() != columnRows[rowDataTableIdColumnName].ToString())
{
continue;
}
var columnName = columnRows[dataColumnKey].ToString();
var columnValue = columnRows[dataColumnValue].ToString();
newRow[columnName] = columnValue;
}
finalDataTable.Rows.Add(newRow);
}
return finalDataTable;
}
it looked like l was failing on adding the column names before merging
you can just call like
var dt = HelperDataTable.MergeRowsToColumns(dtProduct, "productId", "name", dtSales , "quantity", "month");
var dt2 = HelperDataTable.MergeRowsToColumns(dtStudents, "studentId", "fullname", dtStudentExam , "mark", "subjectId");
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.
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];
}
I would like to do a plot with time function of data by using ultrachart , infragistics.
I have found this sample :
DataTable Recap = MarketData.Tables.Add("Recap");
// on ajoute des column a recap ne pas oublier de typer les colonnes
Recap.Columns.Add("Date", typeof(DateTime));
Recap.Columns.Add("Move Ticker price", typeof(double));
Recap.Columns.Add("Move Index price", typeof(double));
Recap.Columns.Add("Alpha",typeof (double));
// on remplie recap
for (int i = 0; i < TickerPrice.Rows.Count; i++)
{
DataRow destRow = Recap.NewRow();
destRow["Move Ticker price"] = TickerPrice.Rows[i]["CHG_PCT_1D"];
destRow["Move Index price"] = IndexPrice.Rows[i]["CHG_PCT_1D"];
destRow["Date"] = TickerPrice.Rows[i]["Date"];
Recap.Rows.Add(destRow);
}
// calcul du alpha
foreach (DataRow dr in Recap.Rows)
dr["Alpha"] = ((double)dr["Move Index price"]) * 1.5 - (double)dr["Move Ticker price"];
// remplir le feed alpha
FeedAlpha.DataSource = Recap;
// faire un plot
ChartPureAlpha.ChartType = Infragistics.UltraChart.Shared.Styles.ChartType.Composite;
ChartArea myChartArea = new ChartArea();
ChartPureAlpha.CompositeChart.ChartAreas.Add(myChartArea);
// Defines axes
AxisItem axisX = new AxisItem();
axisX.DataType = Infragistics.UltraChart.Shared.Styles.AxisDataType.Numeric;
axisX.Labels.ItemFormatString = "<DATA_VALUE:0.00>";
axisX.SetLabelAxisType = SetLabelAxisType.ContinuousData;
axisX.OrientationType = Infragistics.UltraChart.Shared.Styles.AxisNumber.X_Axis;
axisX.RangeType = AxisRangeType.Custom;
axisX.RangeMin = -1;
axisX.RangeMax = 1;
myChartArea.Axes.Add(axisX);
AxisItem axisY = new AxisItem();
axisY.DataType = Infragistics.UltraChart.Shared.Styles.AxisDataType.Numeric;
axisY.Labels.ItemFormatString = "<DATA_VALUE:0.00>";
axisY.Labels.HorizontalAlign = StringAlignment.Far;
axisY.SetLabelAxisType = SetLabelAxisType.ContinuousData;
axisY.OrientationType = Infragistics.UltraChart.Shared.Styles.AxisNumber.Y_Axis;
axisY.RangeType = AxisRangeType.Custom;
axisY.RangeMin = -1;
axisY.RangeMax = 1;
myChartArea.Axes.Add(axisY);
// Create and add series
XYSeries BPLseries = new XYSeries();
BPLseries.Label = "Blood L";
for (int i = 0; i < Recap.Rows.Count; i++)
BPLseries.Points.Add(new XYDataPoint((double)(Recap.Rows[i][2]), (double)Recap.Rows[i][1], "", false));
// Add a chartLayerAppearance
ChartLayerAppearance myScatterLayer = new ChartLayerAppearance();
myScatterLayer.ChartType = Infragistics.UltraChart.Shared.Styles.ChartType.ScatterChart;
myScatterLayer.ChartArea = myChartArea;
myScatterLayer.AxisX = axisX;
myScatterLayer.AxisY = axisY;
myScatterLayer.Series.Add(BPLseries);
ScatterChartAppearance sca1 = new ScatterChartAppearance();
sca1.ConnectWithLines = true;
sca1.Icon = SymbolIcon.None;
myScatterLayer.ChartTypeAppearance = sca1;
ChartPureAlpha.Series.Add(BPLseries);
ChartPureAlpha.CompositeChart.ChartLayers.Add(myScatterLayer);
CompositeLegend myLegend = new CompositeLegend();
myLegend.ChartLayers.Add(myScatterLayer);
myLegend.Bounds = new Rectangle(88, 2, 11, 15);
myLegend.BoundsMeasureType = MeasureType.Percentage;
myLegend.PE.ElementType = PaintElementType.Gradient;
myLegend.PE.FillGradientStyle = GradientStyle.ForwardDiagonal;
myLegend.PE.Fill = Color.CornflowerBlue;
myLegend.PE.FillStopColor = Color.Transparent;
myLegend.Border.CornerRadius = 10;
myLegend.Border.Thickness = 1;
ChartPureAlpha.CompositeChart.Legends.Add(myLegend);
It is working fine if I have data vs data but what I want is time (dd/mm/yyy) vs (double).
Please let me know if you have any idea.
Thanks
You can use the following code to get a time vs data chart:
using Infragistics.Win.UltraWinChart;
using Infragistics.UltraChart.Resources.Appearance;
DataTable dt = new DataTable();
dt.Columns.Add("Value", typeof(double));
dt.Columns.Add("Date", typeof(DateTime));
dt.Rows.Add(1.0, DateTime.Parse("04/20/2012"));
dt.Rows.Add(0.5, DateTime.Parse("04/21/2012"));
dt.Rows.Add(0.25, DateTime.Parse("04/22/2012"));
dt.Rows.Add(0.125, DateTime.Parse("04/23/2012"));
dt.Rows.Add(0.0625, DateTime.Parse("04/24/2012"));
dt.Rows.Add(0.03125, DateTime.Parse("04/25/2012"));
dt.Rows.Add(0.015625, DateTime.Parse("04/26/2012"));
dt.Rows.Add(0.0, DateTime.Parse("04/27/2012"));
NumericTimeSeries series = new NumericTimeSeries();
series.DataBind(dt, "Date", "Value");
UltraChart ultraChart = new UltraChart();
ultraChart.Data.SwapRowsAndColumns = true;
ultraChart.Dock = DockStyle.Fill;
ultraChart.ChartType = Infragistics.UltraChart.Shared.Styles.ChartType.LineChart;
ultraChart.DataSource = dt;
this.Controls.Add(ultraChart);