Handle empty cells in DataGridView - c#

I want to write a condition for when some cells of DataGridView are null or empty.
For example if cells[1] isn't null or empty , a method must be run and ...
I wrote it in some way , but some of them didn't work, and one of them work but its not good solution for my problem.As you now ,empty and null are different in DataGridView.
Additionally , My DataGridView has not been bound to database.
How can i do that in best way?
Regards.

DataGridViewCell object has "Value" method which returns callvalue as object, That value you can convert to string then check this string against null or empty.
string val = this.dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value as string;
if(string.isNullorEmpty(val) ==false)
{
// your method run.
}

Cell value is a Object. Empty cell Value is null.
DataTable / DataView uses DbNull.Value when Empty.
Strings with Length = 0 are String.Empty
You need verify three options.

if your columns and row layout is fixed then you may call out your function in the cell validating event of the datagrid
void dataGridView2_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
e.Cancel = false;
if (e.RowIndex == 1 && e.ColumnIndex == 0)
{
if(string.IsNullorEmpty(e.FormattedValue.ToString())
// method call
}
}

//just replace from Value to FormattedValue like that
string val = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].FormattedValue as string;
if(string.isNullorEmpty(val))
{
// cell is empty
}
else
{
// cell is not empty
}

Related

How to exclusively set the value of a DataGridViewCheckBoxCell?

I have a List<Car> objects that have a bool property named Marked.
I want to check / uncheck the Cell corresponding to this property, in a way that only one Car can be selected at the same time.
I want that the value of this property is updated in the bank.
Sample table:
Car Name
Marked
a
 
b
 
The problem is I can't check the state of CheckBox Cells.
This is what I tried, but it's not working:
Example 1:
DataGridViewCheckBoxCell dataGridViewCheckBoxCell = DataGridView1.Rows[e.RowIndex].Cells["Marked"] as DataGridViewCheckBoxCell;
if(Convert.ToBoolean(dataGridViewCheckBoxCell.Value) == true)
{
//some code
}
else if(Convert.ToBoolean(dataGridViewCheckBoxCell.Value) == false)
{
//some code
}
Example 2:
foreach (DataGridViewRow row in DataGridView1.Rows)
{
DataGridViewCheckBoxCell chk =(DataGridViewCheckBoxCell)row.Cells["Marked"];
if (chk.Value == chk.TrueValue)
{
chk.Value = chk.FalseValue;
}
else
{
chk.Value = chk.TrueValue;
}
}
how can I do it?
You can handle the CellContentClick (or CellClick) event of your DataGridView to set the state of a DataGridViewCheckBoxCell that should be a single choice (hence behaving as a RadioButton).
Store the Cell object currently selected when the Cell meets the criteria (its OwningColumn is a DataGridViewCheckBoxColumn named Marked).
Change the state of this Cell if it's the one currently selected, or reset it back to false if it's not.
In this case, set the current Cell to the one just selected and set its state to true.
Then you don't need to loop all the Rows each time a CheckBox changes value.
If you need to, call [DataGridView].EndEdit() to update the value immediately.
For example:
DataGridViewCheckBoxCell currentCheckBoxCell = null;
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex < 0 || e.RowIndex < 0) return;
var dgv = sender as DataGridView;
if (dgv[e.ColumnIndex, e.RowIndex] is DataGridViewCheckBoxCell cell &&
cell.OwningColumn.Name == "Marked")
{
if (currentCheckBoxCell is null) currentCheckBoxCell = cell;
if (cell == currentCheckBoxCell) {
cell.Value = !(bool)cell.Value;
}
else {
currentCheckBoxCell.Value = false;
currentCheckBoxCell = cell;
}
// Affects CellValueChanged
// dgv.EndEdit();
}
}
This is how it works:
See also DataGridView CheckBox selection bug to select a CheckBox Cell by clicking anywhere in a Row and while immediately update the data source.
It is unclear “where” the first code snippet is called from so I will focus on the second snippet of code.
One of the problems you will have comes from the if statement…
if (chk.Value == chk.TrueValue) …
This condition chk.Value == chk.TrueValue may not throw an error, HOWEVER… this is checking two different OBJECTS… chk.Value is an OBJECT as is chk.TrueValue … so it makes sense that the two “different” OBJECTS would NEVER be equal.
One way to solve this is to simply “cast” those OBJECTS to bool values like…
if ((bool)chk.Value == (bool)chk.TrueValue) {…
HOWEVER the above line of code will ONLY work “IF”… the check box columns TrueValue AND FalseValue properties have been SET like…
CheckBoxColumn.TrueValue = true;
CheckBoxColumn.FalseValue = false;
IF you have NOT set the Check box column’s two properties TrueValue AND FalseValue like above… then the Check box columns TrueValue and FalseValue will be null and this will cause the line of code … if ((bool)chk.Value == (bool)chk.TrueValue) … to throw an exception since chk.TrueValue is null and the cast to a bool will throw a null exception.
Therefore, if you DO SET the Check box columns TrueValue and FalseValue then you will have to “cast” the objects to bool values in order for the comparison to work as shown above.
Given all this… you may want to re-consider using the Check box columns TrueValue and FalseValue as the intended purpose of those properties is to allow you to “change” the actual true and false values to something else that is not necessarily a true or false value.
It is unimportant how you would use these properties in that context as it appears very clear that in this context… setting the Check box columns TrueValue and FalseValue properties to true and false is somewhat superfluous and creates more work for you.
So in this case, I suggest you completely drop using the Check box columns TrueValue and FalseValue properties.
If you want to ensure that only ONE check box is checked in the column… then you could wire up the grids CellContentClick event. If the check box value changed, then simply “uncheck” all the cells in that column.
Fortunately, the grids CellContentClick will fire “before” it actually sets the check box cell, so unchecking them all works out fine for both checked and unchecked states. Crude yes, but it should work.
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e) {
if (dataGridView1.Columns[e.ColumnIndex].Name == "Marked") {
foreach (DataGridViewRow row in dataGridView1.Rows) {
if (!row.IsNewRow) {
row.Cells["Marked"].Value = false;
}
}
}
}
I hope this makes sense and helps.

Show 0/1 as yes/no in DevExpress XtraGrid?

I had this code for a regular DataGridView, and I'm having trouble getting the same effect on the XtraGrid:
private void RosterGridView_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (e.ColumnIndex == 7 && e.Value is long)
{
e.Value = (long)e.Value == 0 ? "No" : "Yes";
}
}
The issue is I am using SQLite and it doesn't have any true boolean data type, or else this would be easy. The column is set up in the DB to only accept 0 and 1, kind of a makeshift boolean.
With DevExpress you can set up the specific column to use the RepositoryItemCheckEdit:
// Assign a repository item to a column
RepositoryItemCheckEdit checkEdit = new RepositoryItemCheckEdit();
gridControl.RepositoryItems.Add(checkEdit);
gridView.Columns["Mark"].ColumnEdit = checkEdit;
After that, you can set up the ValueChecked, ValueUnchecked and ValueGrayed properties specify the values that correspond to the editor's checked, unchecked and indeterminate state, respectively. The default values of the ValueChecked, ValueUnchecked and ValueGrayed properties are true, false and null, respectively. You can assign custom values to these properties as your logic requires:
checkEdit.ValueChecked = (long)1;
checkEdit.ValueUnchecked = (long)0;
With this approach, you can avoid any value conversion operations when displaying and editing values in GridView.
Another possibility is to use the CustomColumnDisplayText event on the gridView
private void gridView1_CustomColumnDisplayText(object sender, DevExpress.XtraGrid.Views.Base.CustomColumnDisplayTextEventArgs e)
{
if (e.Column = <yourColumn>)
{
e.DisplayText = (long) e.Value == 1 ? "Yes" : "No";
}
}

Searching a name in a gridview C#

This is the table. On the right are the namesI have a gridview that shows a table from the database. I want to search a name in the gridview using a textbox and a button. This is what i have so far. When i want to search I get in a messagebox this: object reference is not set on an instance of an object.
private void btn_zoek_Click(object sender, EventArgs e)
{
string searchValue = tb_SearchOverzicht.Text;
metroGrid1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
try
{
foreach (DataGridViewRow row in metroGrid1.Rows)
{
if (row.Cells[2].Value.ToString().Equals(searchValue))
{
row.Selected = true;
break;
}
}
}
catch (Exception exc)
{
MessageBox.Show(exc.Message);
}
}
Check if the values and object you are trying to work with are filled with data and not null.
In your row
if (row.Cells[2].Value.ToString().Equals(searchValue))
you should check first, if the cell exists and has value, like this:
if(row.Cells[2] != null && row.Cells[2].Value.ToString() == searchValue)
{
// Some code
}
and just to be sure, check if your searchValue is not empty or without any chars or maybe even correct formatted:
if(!String.IsNullOrWhiteSpace(searchValue))
but I dont think this is necessary here, just nice to have.
The goal here is: Not all values have to be filled. It can appear that a cell doesnt have value in that column, the row may be the filter row or even empty, or worst: the grid isn't even initialized. So please try to check if values or objects are filled before using them.

Pass the Selected Value in DataGridView to ComboBox

When I clicked on a cell in my DataGridView, the values are passed on my Textboxes, but I have a problem when it comes to my combobox, it just stays null. I've already tried SelectedItem and SelectedIndex but it stays null. I've manage to place the value in my combobox using SelectedText but once I've updated my database, I'm getting a NullReferenceException in my combobox, here's my code:
private void dgvStudentRecord_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex >= 0)
{
DataGridViewRow row = this.dgvStudentRecord.Rows[e.RowIndex];
txtStudNum.Text = row.Cells["studentId"].Value.ToString();
txtStudName.Text = row.Cells["studentName"].Value.ToString();
cboSection.SelectedText = row.Cells["section"].Value.ToString();
numPrelim.Value = Convert.ToDecimal(row.Cells["prelim"].Value);
numMidterm.Value = Convert.ToDecimal(row.Cells["midterm"].Value);
numFinals.Value = Convert.ToDecimal(row.Cells["finals"].Value);
}
}
You're going to have some headache doing it the way you are approaching it because the ComboBox does not handle unexpected values well at all, and the SelectText property it not doing what you think its doing (its NOT selecting an item from its internal list when you set that property) (see: https://msdn.microsoft.com/en-us/library/system.windows.forms.combobox.selectedtext(v=vs.110).aspx)
You are going to be better of writing something like:
int index = cboSection.FindString(row.Cells["section"].Value.ToString());
if(index > -1)
{
cboSection.SelectedIndex = index;
}
else
{
object newSection = row.Cells["section"].Value.ToString();
cboSection.Items.Add(newSection);
cboSection.SelectedItem = newSection;
}
Edited to show conditional select or add.
Final edit... Doh.
Try this, ComboBox.Text property
combobox1.Text=row.Cells[cellIndex].Value.ToString();

c# how do i check if datasource is null?

i have a control on a winform called chart1.
i would like to know whether chart1.DataSource is empty
how do i check it?
If the DataSource is a DataTable, you can check first that the DataTable is not null, and secondly that its Rows.Count > 0.
If the DataSource is a DataSet, you check for null, then tables, then rows.
Check to see if it is null.
if(chart1.DataSource == null)
{
// Do something
}
If you know what the DataSource is, then you can cast it and check to see if it is empty or not. For example:
List<String> strings = new List<String>() { "a", "b" };
// Set chart1.DataSource to strings... then later on
if(chart1.DataSource != null)
{
List<String> boundStrings = chart1.DataSource as List<String>;
if(boundStrings != null && boundStrings.Count > 0)
{
// do something
}
}
personally id check the datasource for null BEFORE I bind it to chart so I don't have to worry about chart1 dealing with a null datasource
if (chart1.DataSource == null)
{
// The DataSource is empty
}

Categories

Resources