get index of DataTable column with name - c#

I have some code which sets the value of cells in a DataRow by column name i.e.
row["ColumnName"] = someValue;
I want to also set the value for this row in the column immediately to the right of the one found above. Clearly if I was getting the cell by index rather than by column name this would be easy. So is there a way of getting the column index from the column name thus allowing me to do:
row[index + 1] = someOtherValue;
i.e. do I need create some kind of dictionary of column index and column names when the table is initially created, or can I get the index from the column name later on without doing this?

You can use DataColumn.Ordinal to get the index of the column in the DataTable. So if you need the next column as mentioned use Column.Ordinal + 1:
row[row.Table.Columns["ColumnName"].Ordinal + 1] = someOtherValue;
Warning:
This code returns the next column, so the one after ColumnName, as requested in the question.

Try this:
int index = row.Table.Columns["ColumnName"].Ordinal;

You can simply use DataColumnCollection.IndexOf
So that you can get the index of the required column by name then use it with your row:
row[dt.Columns.IndexOf("ColumnName")] = columnValue;

I wrote an extension method of DataRow which gets me the object via the column name.
public static object Column(this DataRow source, string columnName)
{
var c = source.Table.Columns[columnName];
if (c != null)
{
return source.ItemArray[c.Ordinal];
}
throw new ObjectNotFoundException(string.Format("The column '{0}' was not found in this table", columnName));
}
And its called like this:
DataTable data = LoadDataTable();
foreach (DataRow row in data.Rows)
{
var obj = row.Column("YourColumnName");
Console.WriteLine(obj);
}

Related

Properly getting string values from DataRow at specific column

I am trying to get a value from a DataRow in a specific column in a DataTable. It should return values like "abc12345", but instead returns "ListViewSubItem: {abc12345}", according to the debugger. Why is this?
foreach (DataRow row in itemsTable.Rows)
{
// the required data is in the first column of the DataTable
// both of the following have been tried:
string myValue = row[0].ToString();
string myValue = row.Field<string>(0);
}
You are doing it wrong. It should be string myValue = row[columnIndex].Text; and you are trying to get the value of the first column. You can use row["columnName"] also .
Note: I have used Text property.

Show Total of column values in dataGridView

I am a newbie in C# so I don't know if I will address my problem correctly so please bear with me.
I have a dataGridView named dgvShowAllData which has a data source coming from my sqlServer. there are a column named Price.
I want to add a new row at the end of the rows in my dataGridView to show the total of the Price column values.
I've tried multiple solutions and got several errors.
I have found a solution that the sum will execute from the sqlServer.
like below,
Select Sum(Price) from tblProduct
but I got stuck there too. I don't exactly know how to execute two data source in a dataGridview.
Please show me a better way so than I can get the total at the very end of my dataGridView.
use a data table as a data source for your DataGridView. Then add a data row to your data table, Data Table has a compute function.
An example of how I would work this around;
DataTable dt;
dt = yourDataSource; //add your data source to the Data Table
DataRow dr = dt.NewRow();
dr("Price") = dt.Compute("Sum(Price)", "");
dt.Rows.Add(dr);
dgvShowAllData.DataSource = dt;
In your code, create a custom footer row for your dataGridView and populate total value in element within footer row.
Ngengis' solution worked for my implementation. My app does not know the name, type, or number of columns in advance, so I needed to tweak it a bit. I made use of an extension method (by Dmytrii Nagirniak) to check that a DataColumn.DataType is numeric:
public static bool IsNumeric(this DataColumn col)
{
if (col == null)
return false;
var numericTypes = new[] { typeof(Byte), typeof(Decimal), typeof(Double), typeof(Int16), typeof(Int32), typeof(Int64), typeof(SByte), typeof(Single), typeof(UInt16), typeof(UInt32), typeof(UInt64)};
return numericTypes.Contains(col.DataType);
}
And I used a loop to create the total row. I needed to catch a SyntaxErrorException in case the column name didn't work with the Compute() method (aggregated columns with parenthesis in them fail; using a column alias fixes that problem)
//Total Row
if (MakeTotalRow == true)
{
DataRow dr = dt.NewRow();
for (int j = 0; j < dt.Columns.Count; j++)
{
var colName = dt.Columns[j].ColumnName;
if (dt.Columns[j].IsNumeric()) //ensure column data can be summed
{
try
{
dr[j] = dt.Compute("Sum(" + colName + ")", "");
}
catch (SyntaxErrorException e)
{
//possible syntax error in the column name
}
}
}
dt.Rows.Add(dr);
}
At the first you must use LINQ entityframework and then:
You should test these code it`s will you handle, for example, your field in database named by 'Price', so try :
step by step ,
1.Make A List<> from your Database :
List<Database.tblProduct> Lst=new List<Database.tblProduct>;
So you Could Use Query From C#,
Textblock.text=lst.Where(w=>w.PriceId==1).sum(w=>w.Price).tostring("#,##");
it Could Help you.

adding a column to a specific row in dataset

I have a dataset.
I want to iterate it and add a column (currently not in my dataset) with different value to every row. More specificly, i want it to be at 0 index.
I want to check the value in "fullname" column, and then add a new column with Id.
What do i need to write?
I iterate like this:
foreach (DataRow theRow in mesakem.Tables["fullname"].Rows)
foreach(oved o in ovdimlist)
if(o.name==theRow.ToString())
add column(o.id)......
Ty very much!
I think you meant to insert a new column at index 0 and then add id values to cell for each row where current name cell value matches your object name. If I'm right, it should look like this:
DataColumn col = mesakem.Tables["fullname"].Columns.Add("Id");
col.SetOrdinal(0);
foreach (DataRow row in mesakem.Tables["fullname"].Rows)
{
foreach (oved o in ovdimlist)
{
if (o.name == row["Name"].ToString())
row["Id"] = o.id;
}
}

How to set Cell value of DataGridViewRow by column name?

In windows forms, I'm trying to fill a DataGridView manually by inserting DataGridViewRows to it, so my code looks like this:
DataGridViewRow row = new DataGridViewRow();
row.CreateCells(dgvArticles);
row.Cells[0].Value = product.Id;
row.Cells[1].Value = product.Description;
.
.
.
dgvArticles.Rows.Add(row);
However, I would like to add the Cell value by column name instead of doing it by the index, something like this:
row.Cells["code"].Value = product.Id;
row.Cells["description"].Value = product.Description;
But doing it like that throws an error saying it couldn't find the column named "code".
I'm setting the DataGridView columns from the designer like this:
Am I doing something wrong? How can I accomplish what I want to do?
So in order to accomplish the approach you desire it would need to be done this way:
//Create the new row first and get the index of the new row
int rowIndex = this.dataGridView1.Rows.Add();
//Obtain a reference to the newly created DataGridViewRow
var row = this.dataGridView1.Rows[rowIndex];
//Now this won't fail since the row and columns exist
row.Cells["code"].Value = product.Id;
row.Cells["description"].Value = product.Description;
I tried it too and got the same result. This is a little verbose, but it works:
row.Cells[dataGridView1.Columns["code"].Index].Value = product.Id;
When you use the ColumnName indexer of the DataGridViewCellCollection, internally it tries to get the column index using the ColumnName from the owning/parent DataGridView of this DataGridViewRow instance. In your case the row hasn't been added to the DataGridView and hence the owning DataGridView is null. That's why you get the error that It couldn't find the column named code.
IMO the best approach (same as Derek's) would be to the add the row in the DataGridView and use the returned index to the get the row instance from the grid and then use the column name to access the cells.
The problem is that referencing cells by name doesn't work until the row is added to the DataGridView. Internally it uses the DataGridViewRow.DataGridView property to get at the column names, but that property is null until the row is added.
Using C#7.0's local function feature, the code can be made halfway readable.
DataGridViewRow row = new DataGridViewRow();
row.CreateCells(dgvArticles);
DataGridViewCell CellByName(string columnName)
{
var column = dgvArticles.Columns[columnName];
if (column == null)
throw new InvalidOperationException("Unknown column name: " + columnName);
return row.Cells[column.Index];
}
CellByName("code").Value = product.Id;
CellByName("description").Value = product.Description;
.
.
.
dgvArticles.Rows.Add(row);
Another alternative:
Suppose the name of your DataGridView is dataGridView1.
var row = new DataGridViewRow();
// Initialize Cells for this row
row.CreateCells(_dataGridViewLotSelection);
// Set values
row.Cells[dataGridView1.Columns.IndexOf(code)].Value = product.Id;
row.Cells[dataGridView1.Columns.IndexOf(description)].Value = product.Description;
// Add this row to DataGridView
dataGridView1.Rows.Add(row);

getting index of a column having a given column header c#

guys i am trying to get the index of a column with a specific column header.
Till now i got to
int index_of = grid_statement.Columns[the_name].Index;
But it throws a NullReference exception.
Is there any other ways to get that index ?
(the_name is a variable having the column header)
If your are trying to get column by it's name, then either your grid is null, or there is no column with name equal to the_name in your grid. In both cases you will not be able to get index of non-existing column. To avoid exception in case there is no column with provided name, you can check if column exists before trying to get its index.
var column = grid_statement.Columns[the_name];
int index_of = column == null ? -1 : column.Index;
If you are trying to get column by it's header text (which is not same as column name) you should search for column with same header. And if column was found, get it's index:
var column = grid_statement.Columns
.Cast<DataGridViewColumn>()
.FirstOrDefault(c => c.HeaderText == the_name);
int index_of = column == null ? -1 : column.Index;
try this it will helps you
int index_of = grid_statement.CurrentRow.Cells["ColumnName"].ColumnIndex;
You are probably trying to access the columns collection before binding the data source. At this time gridview wont have any columns. Assign dataSource and bind the grid and then check the index of column.
grid_statement.DataSource = dataTable;
grid_statement.DataBind();
int index_of = grid_statement.Columns[the_name].Index;
To avoid exception you should first check if you got column then get its index.
int index_of = -1;
if(grid_statement.Columns[the_name] != null)
index_of = grid_statement.Columns[the_name].Index;

Categories

Resources