I have SSN column in data grid and i want to mask it like *****1234 this. But when user type type SSN it should not mask it. Is there any way to mask cell in data grid.
I only know one way to do this, though there may be a simpler one*. You can host custom editing control in your datagridview cells. This contor only appears while you are editing the cell, and the value of the cell is visible otherwise. You can read more about this here:
https://msdn.microsoft.com/en-us/library/7tas5c80.aspx
You can implement this in a way, that the cell itself holds only the masked value, and the editing control holds the full value.
*There is indeed a simpler one, see Vincent's answer.
You can do this by creating an event handler for the CellFormatting event of the DataGridView. For example like this:
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (e.Value != null && e.Value.ToString() != "SSN")
{
if (!(dataGridView1.CurrentCell != null && dataGridView1.IsCurrentCellInEditMode && dataGridView1.CurrentCell.RowIndex == e.RowIndex && dataGridView1.CurrentCell.ColumnIndex == e.ColumnIndex))
{
e.Value = "****1234";
e.FormattingApplied = true;
}
}
}
Related
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.
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";
}
}
For example: if I'm changing MRP column, it should multiply that value with another column value called No_of_Units and the result should be stored in column called Total, Thanks in advance
You mean something like this ?
private void DataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == index of column MRP)
{
int value = (int)DataGridView1.Rows[e.RowIndex].Cells["NO_OF_UNITS"].Value * (int)DataGridView1.Rows[e.RowIndex].Cells["MRP"].Value;
DataGridView1.Rows[e.RowIndex].Cells["TARGET_COLUMN"].Value = value;
}
}
This answer is simplified, you might need some additional checks, like check on null values and that kind of stuff. But it should get you on your way.
In your comment you asked:
How to get the index of column MRP ?
Click on the datagrid. Find the property Columns and click on the little button in the list of columns, find the column MRP and copy the Name property. This could be MRP but it also be DataGridColumn1 or something.
Suppose the name property is 'MRP' than you can do:
if (e.ColumnIndex == MRP.ColumnIndex)
i have a datagrid with the following cell formatting
datagrid.rows[0].cells[0].Value =1;
datagrid.rows[0].cells[0].Style.Format ="#k";
this works fine and the output will be 1k, however when the user edit the cell value example to 2 then cell formatting will not take effect?
question is how can i retain the cell formatting after user edit?
thanks
I guess you are not working with an underlying datasource. You are inserting DataGridViewRows manually into the DataGridView.
If you were using a datasource, if the column datatype was numeric, the styling will work in both edit and readonly modes.
In your case, you need to handle the CellFormatting event of the DataGridView and set the format of your cell there:
void dataGridView1_CellFormatting(object sender,
DataGridViewCellFormattingEventArgs e)
{
if (e.ColumnIndex == 0 && e.RowIndex == 0)
{
// if the underlying type is int
int value;
if(e.Value != null && int.TryParse(e.Value.ToString(), out value))
{
e.Value = value.ToString("#k");
/*** OR ***
e.Value = value;
e.CellStyle.Format = "#k";
*/
}
}
}
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
}