I have an table edit that won't save changes. It looks like the problem is that the RowState is not changing. The foreach loop is for debugging:
private void btnSave_Click(object sender, EventArgs e)
{
this.Validate();
bs.EndEdit();
dsEdit.Tables["broker"].GetChanges();
DataTable dtOut = dsEdit.Tables["broker"];
foreach (DataRow rOut in dtOut.Rows)
{
Console.WriteLine(rOut.RowState.ToString());
Console.WriteLine(rOut["contactfax"]);
rOut["contactfax"] = "change";
Console.WriteLine(rOut.RowState.ToString());
Console.WriteLine(rOut["contactfax"]);
}
int n = sdaBkr.Update(dsEdit.Tables["broker"]);
MessageBox.Show(n.ToString() + " record(s) saved.");
}
The Console output is as follow::
Unchanged
fax number here
Unchanged
change
What can cause this? I don't see any unusual properties set in the database.
Answer found here: EndEdit on BindingSource updates DataTable, but rowstate still unchanged
Calling EndEdit on each row as
rOut.EndEdit();
fixes the problem, but I don't understand, and I don't see that in any documentation.
Related
In my VS2015 Winform app, there is one DataGridView control bound to a BindingSource that is bound to a SQL database. The Grid has four columns: ID, URL, Name, Type. The URL column is DataGridViewLinkColumn whose ReadOnly property, by default, is set to False. I can edit the Name and Type columns but URL columns shows as ReadOnly. Why? How can I make URL column editable?
As Reza stated:
DataGridViewLinkColumn is not editable.
Therefore, to edit a cell in such a column you'll have to convert it to a DataGridViewTextBoxCell as needed. For instance, if I have subscribed to DataGridView.CellContentClick to handle clicking on a link, then I would handle CellDoubleClick for the cell conversion:
private void DataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
if (this.dataGridView1.Columns[e.ColumnIndex] == this.dataGridView1.Columns["URL"])
{
this.dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex] = new DataGridViewTextBoxCell();
this.dataGridView1.BeginEdit(true);
}
}
Once you've entered your value and left the cell, you should then use CellValidated to verify that the new value is a URI before converting the cell back to a DataGridViewLinkCell:
private void DataGridView1_CellValidated(object sender, DataGridViewCellEventArgs e)
{
if (this.dataGridView1.Columns[e.ColumnIndex] == this.dataGridView1.Columns["URL"])
{
DataGridViewCell cell = this.dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex];
if (Uri.IsWellFormedUriString(cell.EditedFormattedValue.ToString(), UriKind.Absolute))
{
cell = new DataGridViewLinkCell();
}
}
}
Caveat:
This only worked for me when the data for the "URL" column were strings and thus after binding, the column defaulted to a DataGridViewTextBoxColumn - forcing a manual conversion to link cells to begin with:
private void DataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
foreach (DataGridViewRow r in dataGridView1.Rows)
{
if (Uri.IsWellFormedUriString(r.Cells["URL"].Value.ToString(), UriKind.Absolute))
{
r.Cells["URL"] = new DataGridViewLinkCell();
}
}
}
Setting up the "URI" column as a DataGridViewLinkColumn from the beginning allowed for the conversion of cells to TextBox type successfully. But when converting back to link cells, debugging showed the conversion to happen, but the cell formatting and behavior failed.
How can i get data from devexress gridcontrol's detail row via double-click.
If i focused on child row gridview's double click event doesn't catch.
i tried this method, but my request is catching data by double click
private void gcOperasyonlar_FocusedViewChanged(object sender, DevExpress.XtraGrid.ViewFocusEventArgs e)
{
if (e.View != null && e.View.IsDetailView)
(e.View.ParentView as GridView).FocusedRowHandle = e.View.SourceRowHandle;
GridView detailView = gcOperasyonlar.FocusedView as GridView;
MessageBox.Show(detailView.GetFocusedRowCellValue("Kalip").ToString());
}
thanks for your help
There is also an easier way:
ColumnView cv = _gridControlxyz.FocusedView as ColumnView;
selectedRow row = cv.GetRow(cv.FocusedRowHandle)
I found this code on the forum, It might be useful as long as your grid is not editable (so that mouse click doesn't activate the editable field).
private void gridView1_DoubleClick(object sender, EventArgs e) {
GridView view = (GridView)sender;
Point pt = view.GridControl.PointToClient(Control.MousePosition);
DoRowDoubleClick(view, pt);
}
private static void DoRowDoubleClick(GridView view, Point pt) {
GridHitInfo info = view.CalcHitInfo(pt);
if(info.InRow || info.InRowCell) {
string colCaption = info.Column == null ? "N/A" : info.Column.GetCaption();
MessageBox.Show(string.Format("DoubleClick on row: {0}, column: {1}.", info.RowHandle, colCaption));
}
}
http://www.devexpress.com/Support/Center/Question/Details/A2934
Let's say you have two gridviews (I'm guessing you're using gridviews in your grid control): gvMaster and gvDetail.
You should implement event DoubleClick for your gvDetail in order to achieve desired functionality:
private void gvDetail_DoubleClick(object sender, EventArgs e) {
var gv = sender as GridView; // sender is not gvDetail! It's an instance of it. You have as many as there are rows in gvMaster
var row = gv.GetDataRow(e.FocusedRowHandle); // or use gv.GetRow(e.FocusedRowHandle) if your datasource isn't DataSet/DataTable (anything with DataRows in it)
MessageBox.Show(row["Kalip"].ToString());
}
How Can Add and Remove Rows based on the value of the numericupdown value??
i've tried creating this;
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
dataGridView1.Rows.Add();
}
It adds correctly, however, when I decrease the value it keeps adding again!!!
Yeah I know it is really wrong because it always add whenever the numericupdownvalue is altered.
What i'm asking is that is there a increase property and decrease property in a numeric control? Is there a way to solve my problem?
Btw, I've set the numericupdown value to 1 so that 1 is the default value.
PLEASE PLEASE!!!
Don't forget that numeric up down controls can be edited directly, so when the value changes there's no guarantee that you're just one row different from where you were before.
You need to change the number of rows until it matches the current value of the numeric control. Something like this:
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
// presuming numericUpDown1 cannot have a value below zero
// Note that when dataGridView1.Rows.Count == numericUpDown1.Value
// these loops will do nothing, as we would want...
while (dataGridView1.Rows.Count < numericUpDown1.Value)
{
dataGridView1.Rows.Add();
}
while (dataGridView1.Rows.Count > numericUpDown1.Value)
{
dataGridView1.Rows.RemoveAt(dataGridView1.Rows.Count - 1);
}
}
I have a XtraGrid with one GridView, with a column with checkbox repository item. Now I am handling the CellValueChanging event because I want to only allow the user to check or uncheck based on calculations on other column values on the same row hence I need the e.RowHandle and e.Column of this event and this cannot be done on the EditValueChanging of the repository control.
Now somewhere my calculations say that user cannot check a particular cell to and I throw a message box and try Me.BandedGridView1.SetRowCellValue(e.RowHandle, e.Column, False) but unfortunately this does not set the value to false of that cell.
I need to do it here and here only because of the huge number of calculations based on other column values and I need to set value of the current cell whose event I'm handling right.
Please help.
I'm using DevExpress 9.2 (no chance of upgrading to higher version)
Try this code it's working perfectly !
private void GridView1_CellValueChanged(object sender, CellValueChangedEventArgs e)
{
if (e.Column.Caption != "yourColumnCaption") return;
GridView1.SetFocusedRowCellValue("yourColumnFieldName", 1);
}
You might want to prevent updates by handling ShowingEditor event.
class TestData
{
public TestData(string caption, bool check)
{
Caption = caption;
Check = check;
}
public string Caption { get; set; }
public bool Check { get; set; }
}
Initialize some test data:
BindingList<TestData> gridDataList = new BindingList<TestData>();
gridDataList.Add(new TestData("First row", true));
gridDataList.Add(new TestData("Second row", true));
gridControl.DataSource = gridDataList;
Handle ShowingEditor. Check if user is allowed to change chechbox. If not, cancel the event.
private void gridView1_ShowingEditor(object sender, CancelEventArgs e)
{
GridView view = sender as GridView;
// Decision to allow edit using view.FocusedRowHandle and view.FocusedColumn
if (view.FocusedColumn.FieldName == "Check")
{
// Allow edit of odd rows only
bool allowEdit = view.FocusedRowHandle % 2 == 1;
e.Cancel = !allowEdit;
}
}
I have a GridView and I want when I change a cell to see if its new value is valid by mine function ValidateValue(string aValue) and if it is valid - to store the new value and old value as a pair in Struct S {string old,new}; How to do this?
Handle the GridView's ValidatingCell event for this purpose. Here is some sample code showing how to obtain new and old edit values:
private void gridView1_ValidatingEditor(object sender, DevExpress.XtraEditors.Controls.BaseContainerValidateEditorEventArgs e) {
BaseEdit edit = (sender as GridView).ActiveEditor;
object oldValue = edit.OldEditValue;
object newValue = e.Value;
}