I'm facing an issue when trying to verify if a cell of a wpf datagrid is null, I always get a null reference exception even when I try to verify if it's null, can anyone help me here?
code bellow
for (int i = 0; i < commandeDataGrid.Items.Count; i++)
{
DataRowView row = commandeDataGrid.Items[i] as DataRowView;
if (row["Prix Total TTC"]!=null)
{
count = count + Convert.ToInt16(row["Prix Total TTC"]);
}
}
You should check whether the as operator actually returns a DataRowView:
for (int i = 0; i < commandeDataGrid.Items.Count; i++)
{
DataRowView row = commandeDataGrid.Items[i] as DataRowView;
if (row != null && row["Prix Total TTC"] != null)
{
count = count + Convert.ToInt16(row["Prix Total TTC"]);
}
}
Or better yet iterate through the ItemsSource:
DataView dataView = commandeDataGrid.ItemsSource as DataView;
if (dataView != null)
{
foreach (DataRowView row in dataView)
{
if (row["Prix Total TTC"] != null)
{
count = count + Convert.ToInt16(row["Prix Total TTC"]);
}
}
}
Related
In this example I am looping through each cell individually.
However, I have a name column and another optional column which I want to avoid. So I'd rather want to loop through a specific set of columns without the optional one instead but I'm not sure how.
This is how I did the thorough sweep:
foreach (DataGridViewRow row in DGVExcel.Rows)
{
for (int i = 0; i < row.Cells.Count; i++)
{
if (row.Cells[i].Value == null || row.Cells[i].Value == DBNull.Value ||
String.IsNullOrWhiteSpace(row.Cells[i].Value.ToString()))
{
row.Cells[i].Value = 0;
//DGVExcel.RefreshEdit();
}
}
}
However, I have a name column [...] so I'd rather'd loop through specific columns instead
If I understand you correctly you could get the index of the column and you can skip one for-loop:
int colindex = DGVExcel.Columns["SpecificColumnName"].Index;
foreach (var row in DGVExcel.Rows)
{
if (row.Cells[colindex].Value == null || row.Cells[colindex].Value == DBNull.Value ||
String.IsNullOrWhiteSpace(row.Cells[colindex].Value.ToString()))
{
row.Cells[colindex].Value = 0;
//DGVExcel.RefreshEdit();
}
}
EDIT
Is there a way to list the excluded columns instead of the included ones, because listing each one would be messy
In this case I would leave it with 2 for-loops. Basically you could save all the names in a List and check whether it contains the name of the current column and if it doesn't then you can do your 0 replacement.
List<string> ExcludedColumnsList = new List<string> { "ExcludedColumnName_1", "ExcludedColumnName_2" };
foreach (DataGridViewRow row in DGVExcel.Rows)
{
for (int i = 0; i < row.Cells.Count; i++)
{
if (!ExcludedColumnsList.Contains(DGVExcel.Columns[i].Name))
{
if (row.Cells[i].Value == null || row.Cells[i].Value == DBNull.Value ||
String.IsNullOrWhiteSpace(row.Cells[i].Value.ToString()))
{
row.Cells[i].Value = 0;
//DGVExcel.RefreshEdit();
}
}
}
}
Another option could also be to use linq. Get all indices except the excluded columns and foreach only through those:
List<string> ExcludedColumnsList = new List<string> { "ExcludedColumnName_1", "ExcludedColumnName_2" };
List<int> indexList = dataGridView1.Columns.Cast<DataGridViewColumn>()
.Where(x => !ExcludedColumnsList.Contains(x.Name))
.Select(x => x.Index).ToList();
foreach (DataGridViewRow row in DGVExcel.Rows)
{
foreach (int i in indexList)
{
if (row.Cells[i].Value == null || row.Cells[i].Value == DBNull.Value ||
String.IsNullOrWhiteSpace(row.Cells[i].Value.ToString()))
{
row.Cells[i].Value = 0;
//DGVExcel.RefreshEdit();
}
}
}
I am trying set icon to datagridview cells per my db vaules that are 1,0
i am use this code (copied from this site!)
foreach (DataGridViewRow row in DataGridView1.Rows)
{ DataGridViewImageCell cell = row.Cells[8] as DataGridViewImageCell;
if row.Cells[8]==1)
cell.Value = (System.Drawing.Image)Properties.Resources.ok;
if row.Cells[8]==0)
cell.Value = (System.Drawing.Image)Properties.Resources.notOK;
}
but compiler shows this error:
System.NullReferenceException was unhandled by user code
Message="Object reference not set to an instance of an object.
What is wrong in that code?
Try this. I think you want this
foreach (DataGridViewRow row in DataGridView1.Rows)
{
if (row.Cells[8]==1)
{
row.Cells[8]=new DataGridViewImageCell();
row.Cells[8].Value = (System.Drawing.Image)Properties.Resources.ok;
}
if (row.Cells[8]==0)
{
row.Cells[8]=new DataGridViewImageCell();
row.Cells[8].Value = (System.Drawing.Image)Properties.Resources.notOK;
}
}
EDIT
dataGridView1.Columns.Add("a", "Image");
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
if (dataGridView1.Rows[i].Cells[8].ToString() == "1")
{
dataGridView1.Rows[i].Cells["a"] = new DataGridViewImageCell();
dataGridView1.Rows[i].Cells["a"].Value = (System.Drawing.Image)Properties.Resources.Config;
}
else
{
dataGridView1.Rows[i].Cells["a"].Value = (System.Drawing.Image)Properties.Resources.Config;
}
}
DT.Columns.Add("c",System.Windows.Forms.DataGridViewImageCell);
for (int i = 0; i < DT.Rows.Count; i++) { if (DT.Rows[i][8].ToString() == "1")
DT.Rows[i]["a"] = (System.Drawing.Image)Properties.Resources.ok;
else
row.Cells[8].Value = (System.Drawing.Image)Properties.Resources.notOK;
So i'm importing an excel doc into my project
DataSet result = excelReader.AsDataSet();
if (result != null)
{
foreach (System.Data.DataTable t in result.Tables)
{
if (t != null && t is System.Data.DataTable)
{
System.Data.DataTable table = t as System.Data.DataTable;
Items Lastitem = new Items();
foreach (System.Data.DataRow r in t.Rows)
{
if (r != null && r is System.Data.DataRow)
{
//new ItemType
if (r.ItemArray[0] != null)
{
Then I run checks to check which column is empty when I get the empty column i then want to get the empty row.
I have tried:
if (checkIfColumnisEmpty(r.ItemArray[0]) && !checkIfColumnisEmpty(r.ItemArray[1]))
{
throw new ImportBOQException("Error importing document: First column is empty at row " + r);
r being the datarow, the telesense allows me rowError, rowState etc... but not row Number....any ideas please? }
You could use a For Loop instead of Foreach when iterating through your rows as follows :
for (int i = 0; i < t.Rows.Count; i++)
{
// Do Your Null Checking and throw the exception with iteration number + 1
if (checkIfColumnisEmpty(t.Rows[i].ItemArray[0]) && !checkIfColumnisEmpty(t.Rows[i].ItemArray[1]))
{
throw new ImportBOQException("Error importing document: First column is empty at row " + (i + 1));
}
}
I want to search for a string in DataTable if it starts with "null" delete this string, if this row has no values then erase this row too. Can someone show me how to do it?
ID Name Comment
2 lola hallo
5 miky hi
null0 // delete null0 and remove this row
null1 ko // delete null1 but do not remove this row
1 hub why
3 null2 //delete null2 but do not remove this row
I tried to delete "null" but it doesn't work.
My Code:
int ct1 = 0;
for (int i = 0; i < resE1.Rows.Count; i++ )
{
if(resE1.Rows[i]["SignalName"].ToString() == "null" + ct1)
{
resE1.Rows[i].SetField<String>(2, "");
}
ct1++;
}
I find a solution to replace "null*" with empty spaces, but now I want to erase this row if the cells values of this row are empty, how can i do it?
int ct1 = 0;
for (int i = 0; i < resE1.Rows.Count; i++)
{
string fix = resE1.Rows[i]["SignalName"].ToString();
if(fix.Contains("null"))
{
resE1.Rows[i].SetField<String>(2, "");
}
ct1++;
}
I tried this. Works for me.
List<DataRow> rowsToRemove = new List<DataRow>();
foreach (DataRow dr in resE1.Rows)
{
if (dr["Name"].ToString().IndexOf("null") == 0)
{
dr.SetField("Name", "");
}
bool hasValue = false;
for (int i = 0; i < dr.ItemArray.Count(); i++)
{
if (!dr[i].ToString().Equals(String.Empty))
hasValue = true;
}
if (!hasValue) rowsToRemove.Add(dr);
}
foreach(DataRow dr in rowsToRemove)
{
dr.Delete();
}
Here is your code changed so it works although I don't like how it is written. Check the answer:
int ct1 = 0;
int i = 0;
while(i < dt.Rows.Count)
{
if ( dt.Rows[i]["Name"].ToString() == "null" + ct1)
{
if ((dt.Rows[i][0] == null || dt.Rows[i][0].ToString() == string.Empty) && (dt.Rows[i][2] == null || dt.Rows[i][2].ToString() == string.Empty))
{
dt.Rows.RemoveAt(i);
i--;
}
else
{
dt.Rows[i].SetField<String>(1, "");
}
ct1++;
}
i++;
}
Assuming your DataTable has column "Name" of type string you can achieve it like this:
private DataTable RemoveUnwanted(DataTable source)
{
var rowsEnu = source.Rows.GetEnumerator();
while (rowsEnu.MoveNext())
{
((DataRow)rowsEnu.Current)["Name"] = ((DataRow)rowsEnu.Current)["Name"].ToString().StartsWith("null") ? string.Empty : ((DataRow)rowsEnu.Current)["Name"];
}
return (from i in source.AsEnumerable()
where !(i.ItemArray.All(o => string.IsNullOrEmpty(o.ToString())))
select i).CopyToDataTable();
}
You will also need reference to System.Data.DataSetExtensions.
To answer one of your questions, to delete the entire row do something like this:
if(resE1.Rows[i].Contains("null") && (resE1.Rows[i]["ID"].ToString() == "") && (resE1.Rows[i]["Comment"].ToString() == ""))
{
resE1.Rows[i].Delete();
}
bool emptyFlag = false;
if(resE1.Rows[i].Contains("null"))
{
for(int j = 0; j < resE1.Columns.Count; j++)
{
if(resE1.Rows[i][j].Equals(""))
emptyFlag = true;
else
emptyFlag = false;
}
if(emptyFlag)
resE1.Rows[i].Delete();
}
You need something like this:
String test = "Null01";
if (test.IndexOf("Null") == 0)
{
test = test.Replace("Null", String.Empty);
}
For second part of your question, just check if Comments are null or empty then replace the string too.
Arrange code according to your own requirement.
I have a dataGridView that has 3 columns: SystemId, FirstName, LastName that is bound using database information. I would like to highlight a certain row, which I would do using:
dataGridView1.Rows[????].Selected = true;
The row ID I however do not know and the bindingsource keeps changing, thus row 10 could be "John Smith" in one instance but not even exist in another (I have a filter that filters out the source based on what user enters, so typing in "joh" would yield all rows where first / last name have "joh" in them, thus my list can go from 50 names to 3 in a click).
I want to find a way how I can select a row based on SystemId and a corresponding number. I can get the system ID using the following method:
systemId = dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells["SystemId"].Value.ToString();
Now I just need to apply it to the row selector. Something like dataGridView1.Columns["SystemId"].IndexOf(systemId} but that does not work (nor does such method exist). Any help is greatly appreciated.
This will give you the gridview row index for the value:
String searchValue = "somestring";
int rowIndex = -1;
foreach(DataGridViewRow row in DataGridView1.Rows)
{
if(row.Cells[1].Value.ToString().Equals(searchValue))
{
rowIndex = row.Index;
break;
}
}
Or a LINQ query
int rowIndex = -1;
DataGridViewRow row = dgv.Rows
.Cast<DataGridViewRow>()
.Where(r => r.Cells["SystemId"].Value.ToString().Equals(searchValue))
.First();
rowIndex = row.Index;
then you can do:
dataGridView1.Rows[rowIndex].Selected = true;
The above answers only work if AllowUserToAddRows is set to false. If that property is set to true, then you will get a NullReferenceException when the loop or Linq query tries to negotiate the new row. I've modified the two accepted answers above to handle AllowUserToAddRows = true.
Loop answer:
String searchValue = "somestring";
int rowIndex = -1;
foreach(DataGridViewRow row in DataGridView1.Rows)
{
if (row.Cells["SystemId"].Value != null) // Need to check for null if new row is exposed
{
if(row.Cells["SystemId"].Value.ToString().Equals(searchValue))
{
rowIndex = row.Index;
break;
}
}
}
LINQ answer:
int rowIndex = -1;
bool tempAllowUserToAddRows = dgv.AllowUserToAddRows;
dgv.AllowUserToAddRows = false; // Turn off or .Value below will throw null exception
DataGridViewRow row = dgv.Rows
.Cast<DataGridViewRow>()
.Where(r => r.Cells["SystemId"].Value.ToString().Equals(searchValue))
.First();
rowIndex = row.Index;
dgv.AllowUserToAddRows = tempAllowUserToAddRows;
Or you can use like this. This may be faster.
int iFindNo = 14;
int j = dataGridView1.Rows.Count-1;
int iRowIndex = -1;
for (int i = 0; i < Convert.ToInt32(dataGridView1.Rows.Count/2) +1; i++)
{
if (Convert.ToInt32(dataGridView1.Rows[i].Cells[0].Value) == iFindNo)
{
iRowIndex = i;
break;
}
if (Convert.ToInt32(dataGridView1.Rows[j].Cells[0].Value) == iFindNo)
{
iRowIndex = j;
break;
}
j--;
}
if (iRowIndex != -1)
MessageBox.Show("Index is " + iRowIndex.ToString());
else
MessageBox.Show("Index not found." );
Try this:
string searchValue = textBox3.Text;
int rowIndex = -1;
dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
try
{
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (row.Cells["peseneli"].Value.ToString().Equals(searchValue))
{
rowIndex = row.Index;
dataGridView1.CurrentCell = dataGridView1.Rows[rowIndex].Cells[0];
dataGridView1.Rows[dataGridView1.CurrentCell.RowIndex].Selected = true;
break;
}
}
}
catch (Exception exc)
{
MessageBox.Show(exc.Message);
}
If you just want to check if that item exists:
IEnumerable<DataGridViewRow> rows = grdPdfs.Rows
.Cast<DataGridViewRow>()
.Where(r => r.Cells["SystemId"].Value.ToString().Equals(searchValue));
if (rows.Count() == 0)
{
// Not Found
}
else
{
// Found
}
This builds on the above answer from Gordon--not all of it is my original work.
What I did was add a more generic method to my static utility class.
public static int MatchingRowIndex(DataGridView dgv, string columnName, string searchValue)
{
int rowIndex = -1;
bool tempAllowUserToAddRows = dgv.AllowUserToAddRows;
dgv.AllowUserToAddRows = false; // Turn off or .Value below will throw null exception
if (dgv.Rows.Count > 0 && dgv.Columns.Count > 0 && dgv.Columns[columnName] != null)
{
DataGridViewRow row = dgv.Rows
.Cast<DataGridViewRow>()
.FirstOrDefault(r => r.Cells[columnName].Value.ToString().Equals(searchValue));
rowIndex = row.Index;
}
dgv.AllowUserToAddRows = tempAllowUserToAddRows;
return rowIndex;
}
Then in whatever form I want to use it, I call the method passing the DataGridView, column name and search value. For simplicity I am converting everything to strings for the search, though it would be easy enough to add overloads for specifying the data types.
private void UndeleteSectionInGrid(string sectionLetter)
{
int sectionRowIndex = UtilityMethods.MatchingRowIndex(dgvSections, "SectionLetter", sectionLetter);
dgvSections.Rows[sectionRowIndex].Cells["DeleteSection"].Value = false;
}
Those who use WPF
for (int i = 0; i < dataGridName.Items.Count; i++)
{
string cellValue= ((DataRowView)dataGridName.Items[i]).Row["columnName"].ToString();
if (cellValue.Equals("Search_string")) // check the search_string is present in the row of ColumnName
{
object item = dataGridName.Items[i];
dataGridName.SelectedItem = item; // selecting the row of dataGridName
dataGridName.ScrollIntoView(item);
break;
}
}
if you want to get the selected row items after this, the follwing code snippet is helpful
DataRowView drv = dataGridName.SelectedItem as DataRowView;
DataRow dr = drv.Row;
string item1= Convert.ToString(dr.ItemArray[0]);// get the first column value from selected row
string item2= Convert.ToString(dr.ItemArray[1]);// get the second column value from selected row
string text = "param";
var rows = dataGridViewlist.Rows.OfType<DataGridViewRow>()
.Select(x => new { Value = x.Cells[6].Value.ToString(), Index = x.Index }).ToList();
var index= rows.Where(w => w.Value == text).Select(s => s.Index).FirstOrDefault();
You can try:
string DT = string.Empty;
try
{
DT = $"{dataGridView1.SelectedRows[0].Cells[1].Value}-{dataGridView1.SelectedRows[0].Cells[2].Value}-{dataGridView1.SelectedRows[0].Cells[3].Value}-{dataGridView1.SelectedRows[0].Cells[4].Value}";
}
catch { }
try
{
dataGridView1.Rows.Cast<DataGridViewRow>().Where(x => $"{x.Cells[1].Value}-{x.Cells[2].Value}-{x.Cells[3].Value}-{x.Cells[4].Value}" == DT).ToList()[0].Selected = true;
}
catch (Exception ex) { }