datagridview beginedit on new row automatically - c#

i'm trying to set a cell to edit mode. The cell is in the new row (NewRowIndex). Everwhere else it works well, but if i try to set the edit mode in the NewRowIndex, it doesn't get into edit mode as supposed. I simply want that i f user enters a new row (NewRowIndex), the first cell get into edit mode. I've tried (on RowEnter):
dgvList.CurrentCell = dgvList["myColName", dgvList.NewRowIndex]; dgvList.BeginEdit(true);
Thank you!

I dont think you really need to utilize the NewRowIndex property. Just begin edit by setting the current cell:
private void dgvList_CellEnter(object sender, DataGridViewCellEventArgs e)
{
dgvList.CurrentCell = dgvList[e.ColumnIndex, e.RowIndex];
dgvList.BeginEdit(true);
}
If you want the cell to go in edit mode only for new rows, then:
private void dgvList_CellEnter(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex != dgvList.NewRowIndex)
return;
dgvList.CurrentCell = dgvList[e.ColumnIndex, e.RowIndex];
dgvList.BeginEdit(true);
}
Edit: If you want the new row to start being in edit mode upon keydown, then that's a feature already available for datagridviews. You can manually set it like this:
dgvList.EditMode = DataGridViewEditMode.EditOnKeystrokeOrF2;
//or
dgvList.EditMode = DataGridViewEditMode.EditOnKeystroke;
If you want the cell to be in edit mode upon keydown only for new rows, then you will have to override the default behaviour, by hooking KeyDown event, which I believe is a bad way f doing GUI. May be like this:
Initialize: dgvList.EditMode = DataGridViewEditMode.EditOnF2; //or whatever you prefer
to override the default excel style editing upon keystroke. And then
private void dgvList_KeyDown(object sender, KeyEventArgs e)
{
if (dgvList.CurrentCell.RowIndex != dgvList.NewRowIndex)
return;
dgvList.BeginEdit(true);
}

Related

Call CellFormatting when DataGridView is populated

I need to trim the cells in the DataGridView when it's populated with data.
I can't figure out how to call the CellFormatting event from within the DataBindingComplete Event. Surely it's as simple as;
private void iCBOMHDataGridView_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
iCBOMHDataGridView_CellFormatting();
}
I am doing something similar that might help. In my case, I am setting an inactive user's whole row to gray text, but it is still cell formatting:
dgvUsers.CellFormatting += new System.Windows.Forms.DataGridViewCellFormattingEventHandler(this.dgvUsers_CellFormatting);
this.Controls.Add(dgvUsers);
The lines above happen before you dgvUsers.Enabled = true; The grid has been loaded, but not displayed. Then the handler that gets called is:
private void dgvUsers_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
DataRowView row = dgvUsers.Rows[e.RowIndex].DataBoundItem as DataRowView;
if (row != null && row.Row.ItemArray[7].Equals("N"))
{
e.CellStyle.ForeColor = Color.Gray;
dgvUsers.Invalidate();
}
}
The main difference between the cell styling I do and yours is that I am not working with the actual values in the cells, just their styling.

How can i change the background cell color after the user edited some text

Going from the previous question i had asked that related to color text change after edit. Now it has been requested that i should not highlight the edited text but change the background color.
This is what i want now.
Load existing file with the data to the DataGridView
After loading, DataGridView will populate data
The user will edit text from any cell
After editing the text,
Background color of the edited cell will change color to red,
Only for the edited cell,
How can i change the background color of the edited cell in the DataGridView ?
This is what i tried by changing the background color of the cell.
private void Gridview_Output_CellBeginEdit_1(object sender, DataGridViewCellCancelEventArgs e)
{
DataGridViewCell cell = Gridview_Output[e.ColumnIndex, e.RowIndex];
cell.Tag = cell.Value != null ? cell.Value : "";
if (cell.OwningColumn.Name == "ValueOut")
cell.Style.BackColor = Color.Yellow;
}
global
List<DataGridViewCell> dgvc_List = new List<DataGridViewCell>();
Save button
private void btnSave_Click(object sender, EventArgs e)
{
dgvc_List.Add(cell);
foreach (DataGridViewCell d in dgvc_List)
{
d.Style.BackColor = Color.White;
}
dgvc_List.Clear();
}
You might want to use the TextChanged event ( https://msdn.microsoft.com/en-us/library/system.windows.forms.control.textchanged(v=vs.110).aspx ) to detect whenever the user is changing the content of the TextBox (you might want to apply some logic here to avoid to trigger it when loading the data in the control). When the even triggers, you can then change the Background color of the control ( https://msdn.microsoft.com/en-us/library/s2kh9x59(v=vs.110).aspx )
Add a new event on CellEndEdit instead:
private void Gridview_Output_CellEndEdit_1(object sender, DataGridViewCellCancelEventArgs e)
{
DataGridViewCell cell = Gridview_Output[e.ColumnIndex, e.RowIndex];
cell.Tag = cell.Value != null ? cell.Value : "";
if (cell.OwningColumn.Name == "ValueOut")
cell.Style.BackColor = Color.Yellow;
}
This is because you invoke the event before the editing is done, instead what you really want is show a different color when the job is done.
Just to further what Donbabbeo has answered...
I take it you only want to change the background ONLY IF the cell value has actually been changed. Using Donbabbeo's answer will change the BackColor regardless every time editing occurs irrespective of whether the value has changed or not.
I suggest you use both the CellBeginEdit and CellEndEdit events together.
To begin with you need to 'remember' the original value of the cell being edited.
string originalValue; // Define a global outside
private void Gridview_Output_CellBeginEdit_1(object sender, DataGridViewCellCancelEventArgs e)
{
originalValue = Gridview_Output[e.ColumnIndex, e.RowIndex].Value.ToString();
}
And then when you complete the edit you check back against the originalValue, only changing the background color if changes had actually been made
private void Gridview_Output_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
DataGridViewCell cell = Gridview_Output[e.ColumnIndex, e.RowIndex];
if (cell.Value.ToString() != originalValue)
{
cell.Style.BackColor = Color.Red;
}
}
If you still want to check that the OwningColumn.Name is a specific value or any other checks for that matter then add a further if statement after you check against the original value.
UPDATE
Changing the cell colors back to their original should be done exactly as Donbabbeo has described in his comment UNLESS you are dealing with a very large DataGridView and then it would be much more efficient to create a generic list of cells to be added to when the change complets & then when saved iterate only through the List<> to revert.
It would be implemented something like this.
First of all the list would need to be declared outside
List<DataGridViewCell> dgvc_List = new List<DataGridViewCell>();
Once the list is declared you would then add specific cells once you were sure that the value was different to the original and that the the BackColor had been changed.
In saying that the following would then be added directly after the color change in the CellEndEdit event.
dgvc_List.Add(cell);
The list will then continue to grow with every confirmed edit until you were ready to do something with it upon the save method, or whatever other method you wanted really, where you would call the following
foreach (DataGridViewCell d in dgvc_List)
{
d.Style.BackColor = Color.White; // Or Any Color
}
dgvc_List.Clear(); // Clears the list ready to go again
Its a little more to code but much more efficient in the long run.

How to activate combobox on first click (Datagridview)

In winforms, you need to click the combobox twice to properly activate it - the first time to focus it, the second time to actually get the dropdown list.
How do I change this behavior so that it activates on the very first click?
This is for DATAGRIDVIEW combobox.
I realize this is an old question, but I figured I would give my solution to anyone out there that may need to be able to do this.
While I couldn't find any answers to do exactly this... I did find an answer to a different question that helped me.
This is my solution:
private void datagridview_CellEnter(object sender, DataGridViewCellEventArgs e)
{
bool validClick = (e.RowIndex != -1 && e.ColumnIndex != -1); //Make sure the clicked row/column is valid.
var datagridview = sender as DataGridView;
// Check to make sure the cell clicked is the cell containing the combobox
if(datagridview.Columns[e.ColumnIndex] is DataGridViewComboBoxColumn && validClick)
{
datagridview.BeginEdit(true);
((ComboBox)datagridview.EditingControl).DroppedDown = true;
}
}
private void datagridview_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
datagridview.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
The above code must be tied into the CellEnter event of the datagridview.
I hope this helps!
edit: Added a column index check to prevent crashing when the entire row is selected.
Thanks, Up All Night for the above edit
edit2: Code is now to be tied to the CellEnter rather than the CellClick event.
Thanks, HaraldDutch for the above edit
edit3: Any changes will committed immediately, this will save you from clicking in another cell in order to update the current combobox cell.
Set the following on your DataGridView:
EditMode = EditOnEnter
This is probably the easiest solution and has been the workaround for many users here on SO when this question gets asked.
EDIT :
Per here do the following:
Set the Editmode:
EditMode = EditOnKeystrokeOrF2
Modify the EditingControlShowing event on the datagridview:
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
ComboBox ctl = e.Control as ComboBox;
ctl.Enter -= new EventHandler(ctl_Enter);
ctl.Enter += new EventHandler(ctl_Enter);
}
void ctl_Enter(object sender, EventArgs e)
{
(sender as ComboBox).DroppedDown = true;
}
This will get you your desired results. Let me know if that doesn't do it.
I changed only the EditMode property of the datagridview to EditOnEnter and it's working perfectly.
EditMode = EditOnEnter
If you set the entire grid to EditOnEnter, you can get some pretty funky activity when you are on a text column. Here's my solution, which should be self explanatory. If you did not know the column names, you could just check the cell type on mousemove.
Private Sub GridView_CellMouseMove(sender As Object, e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles GridView.CellMouseMove
Select Case GridView.Columns(e.ColumnIndex).Name
Case "Ad_Edit", "Size_Caption", "Demo_Code"
GridView.EditMode = DataGridViewEditMode.EditOnEnter
Case Else
GridView.EditMode = DataGridViewEditMode.EditOnKeystrokeOrF2
End Select
End Sub
Set the DropDownStyle property of your combo box to DropDownList...
Perhaps old.. But make sure to set ReadOnly property to false, else the cell wont enter editmode and therefore the EditingControl returns null and casting DroppedDown = true will cast a NullReferencException.

datagridview using a datatable with a column href link

I'm trying to figure out how to get a bounded datagridview column in my c# winform project to show up like an href link. The thing is that the link click works but any average user wouldn't realize that they can click the field since it's displayed as a string. I need the field to show up as blue, with underlines, the mouse pointer turns into a hand ...etc.
I was able to accomplish this previously when I was using Datasets with my Datagrid. I went to the designer and selected "Add Column" and added it as a 'DataGridViewLinkColumn". I've recently changed the project to use datatables and I realized that the fields no longer show up as clickable (if I click it does work though).
Any ideal how to accomplish this with relative ease? I've searched and I'm somewhat surprised that I cannot seem to find a simple solution.
Change the type of the cells that are links to be a DataGridViewLinkCell and then handle the click on the cell, like this:
void dataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
foreach (DataGridViewRow r in dataGridView1.Rows)
{
if (System.Uri.IsWellFormedUriString(r.Cells["Links"].Value.ToString(), UriKind.Absolute))
{
r.Cells["Links"] = new DataGridViewLinkCell();
DataGridViewLinkCell c = r.Cells["Links"] as DataGridViewLinkCell;
}
}
}
// And handle the click too
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex] is DataGridViewLinkCell)
{
System.Diagnostics.Process.Start( dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value as string);
}
}
This might help:
DataGridViewLinkColumn col1 = new DataGridViewLinkColumn();
dataGridView1.Columns.Add(col1);
dataGridView1.Columns[0].Name = "Links";
DataGridViewRow dgvr = new DataGridViewRow();
dgvr.CreateCells(dataGridView1);
DataGridViewCell linkCell = new DataGridViewLinkCell();
linkCell.Value = #"http:\\www.google.com";
dgvr.Cells[0] = linkCell;
dataGridView1.Rows.Add(dgvr);
it creates a col and then a cell of type link.
you can use foreach loops to do this more orderly and faster for more items.
Good Luck!
Take a look at the DataGridViewLinkColumn.LinkBehavior Property. It can be set to AlwaysUnderline.
As for color, simply use the *LinkColor properties on the DataGridViewLinkColumn.
Cheers
You could just colour that column in the datagridview. You could do this in a DataBindingComplete event like so:
private void dataGridView1_DataBindingComplete(object sender,
DataGridViewBindingCompleteEventArgs e)
{
if(this.mydatagridview.Columns["YourLinkColumnName"] != null)
{
this.mydatagridview.Columns["YourLinkColumnName"].DefaultCellStyle.Font = ...
this.mydatagridview.Columns["YourLinkColumnName"].DefaultCellStyle.ForeColor = ...
}
}
You can set the font to be however you like it (ie. underlined, colored, etc.).
Alternatively, you can change the default cell style in the designer if you have the columns premade (not autogeneratedcolumns).

How can I prevent cells in the "new" datagridview row from being selected if there are multiple datagridview rows selected?

Don't ask why, but I need a way to prevent the user from entering a cell in the 'new' datagridview row WHILE they've got multiple rows selected.
Currently, the cell in the first column of the row that the mouse is hovering over during the click and drag is being selected. If you click on the cell, then the rows aren't selected anymore, so you can't use any cell click events or anything.
Any suggestions are welcome.
P.S. don't try editing the currentcell from the selectionchanged event, already tried that!
Thanks,
Isaac
I have an idea that the DataGridView control has a RowState property. When your row is selected, check the state. I'm not sure what the states are (if I'm even in the ballpark) ... anyway, you may be able to check that route.
I'm looking for more info ...
Okay ... think I found a decent way to do this:
void DataGridView1_RowsAdded (object sender, DataGridViewRowsAddedEventArgs e)
{
currentNewRow = e.RowIndex;
}
void DataGridView1_CellMouseClick(Object sender, DataGridViewCellMouseEventArgs e)
{
if (e.RowIndex == currentNewRow)
{
// don't add to Selection
}
}
Use CellStateChanged event:
private void dataGridView_CellStateChanged(object sender, DataGridViewCellStateChangedEventArgs e) {
if (e.Cell.OwningRow.IsNewRow && dataGridView.SelectedRows.Count > 1)
e.Cell.Selected = false;
}

Categories