I have a GridView in which i have this column :
bandedGridColumn.ColumnEdit = InitEdit_Material();
Here is the InitEdit_Material method :
public static RepositoryItemLookUpEdit InitEdit_Material()
{
RepositoryItemLookUpEdit riMaterial = new RepositoryItemLookUpEdit();
riMaterial.Columns.Add(new LookUpColumnInfo("ID", "ID"));
riMaterial.Columns.Add(new LookUpColumnInfo("CustomsMaterial.Name", "Name"));
riMaterial.DataSource = Service.GetAll(svc.EntityTypeToGet.Material).Data.All_Material;
riMaterial.DisplayMember = "MaterialFullname";
riMaterial.ValueMember = "ID";
riMaterial.AutoSearchColumnIndex = 1;
riMaterial.BestFitMode = BestFitMode.BestFitResizePopup;
riMaterial.NullText = "";
return riMaterial;
}
This is what it looks like :
I want to perform some actions (set other cell's value based on current cell value) whenever user choose a new value in this cell, but the problem is all the possible event i know only fires once the cell lost focus, i've tried :
private void vwVD_ValidatingEditor(object sender, BaseContainerValidateEditorEventArgs e)
{
if (vwVD.FocusedColumn.Name == "colMaterialID")
MessageBox.Show("only show when focus lost");
return;
}
private void vwVD_CellValueChanged(object sender, CellValueChangedEventArgs e)
{
if (e.Column.Name != "colMaterialID") return;
MessageBox.Show("only show when focus lost");
}
You can try to use GridView.CellValueChanging event:
private void vwVD_CellValueChanging(object sender, CellValueChangedEventArgs e)
{
if (vwVD.FocusedColumn.Name == "colMaterialID")
{
//Perform some actions. Use e.Value.
}
}
Related
I found lot of answers on Stack Overflow how to disable specific cell in DataGrid in Windows Forms or WPF. Now I want to ask same question in DevExpress. Thank you for your answers!
My current somehow working code prevent user to check specific checkbox in grid but this checkbox dosen't look like it is disabled. How can I visually disable this field making it gray or none visible at all?
bool expression = ... // some expresssion
private void grid_ShownEditor(object sender, EventArgs e)
{
GridView view sender as GridView;
if(view.FocusedColumn.FieldName == "specific column name with checkbox cells")
{
var row = view.GetRow(view.FocusedRowHandle);
view.ActiveEditor.Enabled = expression;
}
}
Use GridView.ShowingEditor and GridView.CustomDrawCell to do what you're after. See:
private bool isDisabled = false;
private bool IsDisabled(int row, GridColumn col)
{
if (col.FieldName == "somename")
return isDisabled;
return false;
}
private void GridView_ShowingEditor(object sender, CancelEventArgs e)
{
var gv = sender as GridView;
e.Cancel = IsDisabled(gv.FocusedRowHandle, gv.FocusedColumn);
}
private void GridView_CustomDrawCell(object sender, RowCellCustomDrawEventArgs e)
{
if(IsDisabled(e.RowHandle, e.Column))
{
e.Appearance.BackColor = Color.Gray;
e.Appearance.Options.UseBackColor = true;
}
}
If you would like to not show a checkbox at all, you can do this:
private static RepositoryItemTextEdit _nullEdit;
public static RepositoryItemTextEdit NullEdit
{
get
{
if (_nullEdit == null)
{
_nullEdit = new RepositoryItemTextEdit();
_nullEdit.ReadOnly = true;
_nullEdit.AllowFocused = false;
_nullEdit.CustomDisplayText += (sender, args) => args.DisplayText = "";
}
return _nullEdit;
}
}
private void GridView_CustomRowCellEdit(object sender, CustomRowCellEditEventArgs e)
{
if(IsDisabled(e.RowHandle,e.Column))
{
e.RepositoryItem = NullEdit;
}
}
I have a DataGridView and an Edit button. When I click the Edit button and change a field, I press Save and the DataGridView comes up again. The problem is that my changes aren't showing.
Using the debugger, I have looked in the DGV and in the BindingSource and the correct data is there. It is just not displaying in the DGV.
Here is my code - I do realize that it is semi-redundant but, at this point, I'm four hours into it and am willing to try anything.
this.iSOXTableAdapter.FillByISOX(this.MSDataSet.ISOX);
BindingSource bindingSource = new BindingSource();
bindingSource.DataSource = iSOXBindingSource;
iSOXDataGridView.DataSource = null;
iSOXDataGridView.DataSource = bindingSource;
bindingSource.ResetBindings(false);
this.iSOXDataGridView.Refresh();
I have looked at the following questions (and many others) and tried their suggestions to no avail:
Datagridview not updating correctly
dataGridView not updating c#?
DataGridView not updating in c#
Best way to refresh DataGridView when you update the base data source
How to refresh or show immediately in datagridview after inserting?
I appreciate any help or suggestions or ideas for workarounds. Thank you so much for looking at this.
***************** EDIT *******************
Here is the code for the save button - I know it is working because after I requery the data, it is in the binding source and in the DGV. This code is in a separate add/edit form:
private void BtnSave_Click(object sender, EventArgs e)
{
if (ValidateForm())
{
ISOXBindingNavigatorSaveItem_Click(sender, e);
this.Close();
}
else
{
MessageBox.Show("Not Validated - Could not Save");
}
}
Here is full code for the user control with the DGV on it:
public partial class FindISOXControl : UserControl
{
private bool gridInitialized = false;
public delegate void ItemHasBeenSelected(object sender, SelectedItemEventArgs e);
public event ItemHasBeenSelected SelectedItem;
public class SelectedItemEventArgs : EventArgs
{
public int SelectedChoice { get; set; }
}
public bool First = true;
public FindISOXControl()
{
InitializeComponent();
FillTableAdapter();
iSOXDataGridView.Columns.Cast<DataGridViewColumn>().ToList().ForEach(f => f.SortMode = DataGridViewColumnSortMode.NotSortable);
}
public void FillTableAdapter()
{
this.iSOXTableAdapter.FillByISOX(this.MSDataSet.ISO);
BindingSource bindingSource = new BindingSource();
bindingSource.DataSource = iSOXBindingSource;
iSOXDataGridView.DataSource = null;
iSOXDataGridView.DataSource = bindingSource;
bindingSource.ResetBindings(false);
this.iSOXDataGridView.Refresh();
setGridData();
}
public void UpdateISOXText(string pISOX = "")
{
this.txtFind.Text = pISOX;
txtFind.Refresh();
}
DataTable dt = new DataTable();
public void btnFind_Click(object sender, EventArgs e)
{
{
setGridData();
}
}
public void setGridData()
{
GetData();
if (iSOXDataGridView.RowCount > 0)
{
EventArgs e = new EventArgs();
iSOXDataGridView_SelectionChanged(null, e);
}
}
public void txtISOX_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Return || e.KeyCode == Keys.Tab)
{
setGridData();
}
}
//Query database
public void GetData()
{
String searchValue = txtFind.Text.Trim().ToUpper();
int rowIndex = -1;
foreach (DataGridViewRow row in iSOXDataGridView.Rows)
{
if (row.Cells[0].Value.ToString().Contains(searchValue))
{
rowIndex = row.Index;
break;
}
}
if (rowIndex == -1)
{
foreach (DataGridViewRow row in iSOXDataGridView.Rows)
{
if (row.Cells[4].Value.ToString().ToUpper().Contains(searchValue))
{
rowIndex = row.Index;
break;
}
}
}
if (rowIndex == -1)
{
if (searchValue != null && searchValue !="")
{
MessageBox.Show(searchValue + " Not Found");
}
}
else
{
iSOXDataGridView.Rows[rowIndex].Selected = true;
iSOXDataGridView.CurrentCell = iSOXDataGridView.Rows[rowIndex].Cells[0];
}
}
public void iSOXDataGridView_SelectionChanged(object sender, EventArgs e)
{
if (iSOXDataGridView.CurrentRow != null)
{
int Row = iSOXDataGridView.CurrentRow.Index;
if (gridInitialized)
{
txtFind.Text = iSOXDataGridView[0, Row].Value.ToString();
// 6 is the ID column
DataGridViewCellEventArgs ev = new DataGridViewCellEventArgs(6, Row);
iSOXDataGridView_CellDoubleClick(sender, ev);
}
}
}
private void iSOXDataGridView_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex >= 0 && e.RowIndex < iSOXDataGridView.RowCount)
{
// 6 == id column
int choice = (int)iSOXDataGridView[6, First ? 0 : e.RowIndex].Value;
this.SelectedItem(this, new SelectedItemEventArgs { SelectedChoice = choice });
}
}
private void iSOXDataGridView_RowEnter(object sender, DataGridViewCellEventArgs e)
{
// 6 is the ID column
DataGridViewCellEventArgs ev = new DataGridViewCellEventArgs(6, e.RowIndex);
if (e.RowIndex != 0)
{
First = false;
iSOXDataGridView_CellDoubleClick(sender, ev);
}
}
private void iSOXDataGridView_RowLeave(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex == 0 && e.ColumnIndex == 0)
{ First = true; }
}
}
Here is the code from the main form with the user control on it after it returns from the edit:
uc.FillTableAdapter();
********* EDIT --> Code that is opening Edit form:
AddEditISOX aeix = new AddEditISOX("E", currentISOX);
aeix.ShowDialog();
ISOX_Load(sender, e);
ISOX_Load() calls uc.FillTableAdapter();
A DataGridView sets up bindings the first time you assign the DataSource. The problem is that subsequent DataSource assignments, if the assignments have a different structure from the initial assignment, will fail because the bindings are now "off"
You need to reset the DataGridView thusly so that the data is bound a new. (The link is for VB but you just need to know the methods to call. Even copy/paste would be overkill.)
Maybe you don't have proper update sql commands in the adapter
add these commands to your intialize method
iSOXTableAdapter.Adapter.MissingSchemaAction = MissingSchemaAction.Error;
iSOXTableAdapter.Adapter.MissingMappingAction = MissingMappingAction.Error;
maybe the generated error will tell you what are you missing there
bind your data to the View of table and it would automatically get updates.
I finally figured this blasted thing out. In my Edit Button Click method, I need to call the user control fill table adapter method again.
private void BtnEdit_Click(object sender, EventArgs e)
{
if (currentISOX != 0)
{
AddEditISO aei = new AddEditISOX("E", currentISOX);
aei.ShowDialog();
findISOXControl1.FillTableAdapter();
}
else
{
MessageBox.Show("Please Make a Selection First");
}
}
Thanks for everyone's thoughts, advice and input. It was very helpful and eventually led me to the solution.
i'm just new to c# and visual studio
so i figured how to mask the password in my datagridview with this
private void dataGridView_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (e.ColumnIndex == 5 && e.Value != null)
{
dataGridView.Rows[e.RowIndex].Tag = e.Value;
e.Value = new String('\u25CF', e.Value.ToString().Length);
}
}
Now i wanted to show the password again when i click on the cell, i figured it would be on dataGridView_CellClick event but i can't figure how to make it show up again. do i assign it to e.Value again?
use a textbox by design in that column of gridview and from source add a checkbox too !
then use this code
private void FromSourceAddedCheckBox_CheckedChanged(object sender, EventArgs e)
{
if (FromSourceAddedCheckBox.Checked == true)
{
GridviewTextboxID.UseSystemPasswordChar = true;
}
else
{
GridviewTextboxID.UseSystemPasswordChar = false;
}
}
I use objectlistview (2.9.1), I want to rollback the value of CellEditor.Text when the input is not qualified, and display on UI immediately.
Code:
private void olv_CellEditFinishing(object sender, CellEditEventArgs e)
{
int iQuantity = 0;
int iPreviousQuantity = order.Quantity.HasValue ? order.Quantity.Value : 0;
string sCellText = ((ObjectListView)sender).CellEditor.Text;
if (Int32.TryParse(sCellText, out iQuantity) && iQuantity >100)
{
// pop up a message box
//Here I want to rollback the previouse quantity
((ObjectListView) sender).CellEditor.Text = iPreviousQuantity.ToString();
//display the previous quantity immedidatly
this.olv.RefreshItem(e.ListViewItem);
}
}
but this does not work.
Make sure you register the event :
this.DBTLviewAfter.CellEditFinishing += new BrightIdeasSoftware.CellEditEventHandler(this.DBTLviewAfter_CellEditFinishing);
and here is my event function:
private void DBTLviewAfter_CellEditFinishing(object sender, CellEditEventArgs e)
{
string toBeEditingStr = (string)e.NewValue;
if(toBeEditingStr == "")
{
e.Cancel = true;
}
}
If the value after edited is empty, the cell won't be changed.
I programmatically create a Form with two textboxes. My goal is to disable one textbox if I type something in the second one and contrariwise. I managed to disable second textbox on first textbox textchange,but can't figure out how enable it when the first textbox.Text is empty.
Here is the code :
private void metaName_TextChanged(object sender,EventArgs e)
{
var ctrl = (Control)sender;
var frm = ctrl.FindForm();
TextBox metaTxt = null;
foreach (var ctr in frm.Controls)
{
if (ctr is TextBox)
{
metaTxt = (TextBox)ctr;
if (metaTxt.Name == "metaHTTPEquiv")
{
metaTxt.Enabled = false;
}
else
if (?)
{
}
}
}
}
I want to make something like this :
if(textBox3.Text == String.Empty)
{
textBox4.Enabled = true;
}
else
if(textBox3.Text != String.Empty)
{
textBox4.Enabled = false;
}
You can check only the textchanged event for each one like the following:
private void textBox1_TextChanged(object sender, EventArgs e)
{
textBox2.Enabled = !(textBox1.Text.Length >= 1);
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
textBox1.Enabled = !(textBox2.Text.Length >= 1);
}
The self textbox has some values, then the enabled will be false for the other one
First set a flag to enable or disable the second control based on the content of the metaName textbox that raises the event, then search for the second textbox using a bit of Linq.
private void metaName_TextChanged(object sender,EventArgs e)
{
TextBox ctrl = sender as TextBox;
if(ctrl != null)
{
bool enable = !string.IsNullOrEmpty(ctrl.Text);
TextBox secondOne = this.Controls
.OfType<TextBox>()
.FirstOrDefault(x => x.Name == "metaHTTPEquiv");
if(secondOne != null)
secondOne.Enabled = enable;
}
}
The same code, reversing the textboxes roles, could be used as the event handler of the second textbox.
Forget about control events and use data binding.
Take the following helper method
static void Bind(Control target, string targetProperty, object source, string sourceProperty, Func<object, object> expression)
{
var binding = new Binding(targetProperty, source, sourceProperty, true, DataSourceUpdateMode.Never);
binding.Format += (sender, e) => e.Value = expression(e.Value);
target.DataBindings.Add(binding);
}
and just add something like this in your form load event
Bind(textBox2, "Enabled", textBox1, "Text", value => string.IsNullOrEmpty((string)value));