the following code works but the code I wrote to select all does not work. does not give any error. this code is not working ( dataGridView2.SelectAll(); )
using System.data;
private void CaO()
{
DataTable tbl = new System.Data.DataTable();
new OleDbDataAdapter("SELECT * FROM [Sayfa1$]", #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\ikinciexcel.xlsx; Extended Properties='Excel 12.0 xml;HDR=YES;'")
.Fill(tbl);
DataTable dtCloned = tbl.Clone();
dtCloned.Columns[1].DataType = typeof(float);
foreach (DataRow row in tbl.Rows)
{
dtCloned.ImportRow(row);
}
var f = new Form();
var dgv = new DataGridView
{
DataSource = dtCloned,
Dock = DockStyle.Fill,
SelectionMode = DataGridViewSelectionMode.FullRowSelect
};
dtCloned.DefaultView.RowFilter = "CaO >= 9 and CaO <= 11";
dataGridView2.Controls.Add(dgv);
dataGridView2.SelectAll();
}
Your SelectAll() method works fine, but You can't see it on the DataGridView object becuase you are calling it from place, where DataSource property is binded and selection can't be drawed. First of all change dataGridView2.SelectAll(); to dgv.SelectAll(); just like #NineBerry mentioned in comment (datasource is binded to dgv). For test please place this line of code just below dgv.SelectAll(); and place breakpoint (F9) on it:
var selectionTest = dgv.SelectedCells;
Code execution will stop on breakpoint and after pressing F10 VS will step to another line. Right click on selectionTest object and choose "Quick Watch" option. In appeared window you can watch all selected cells in proper collection object structure.
If you want to draw selection on your grid, please add some button to your form and call dgv.SelectAll(); in it's event mthod. Sample code:
private void btnSelectAll_Click(object sender, EventArgs e)
{
dgv.SelectAll();
}
This calling will draw selection on the dgv as well.
Conclusion: your code works fine, but you can be a little confused because no selection visual effect is visible as should be when row/cell is selected. Just call it from other place when binding and all other creating operations are completed.
Make sure that MultiSelect of dataGridView2 is set to true:
dataGridView2.MultiSelect = true;
Related
I have a DataGridView with a list of firewall rules. I have a button to update/reload the DataGridView, but I want to keep the last cell I selected active (and visible) when I reload.
With the code I currently am using it only keeps it highlighted, but not exactly active/usable. Here is the snippet:
int x = DataGridView1.CurrentRow.Index;
updateTable();
DataGridView1.Rows[x].Cells[0].Selected = true;
And here's the updateTable() code:
public void updateTable()
{
DataGridView1.DataSource = null;
DataGridView1.Rows.Clear();
DataTable dt = new DataTable();
dt = myDLL.getFirewallRules();
DataGridView1.DataSource = dtFirewall;
DataGridView1.Columns["OriginalIndex"].Visible = false;
}
(being that the ["Original Index"] column represents a fixed index I want hidden.)
I've found the code on how to keep it as the first in the scroll list (if that makes sense), but can't make it selected and ready to use, it always defaults to the first cell of the first row.
How can I do this?
You can use the CurrentCell property for what you are trying to accomplish I believe.
Here is a similar issue already solved.
Datagridview: How to set a cell in editing mode?
if you have issues with the BeginEdit function try:
dataGridView1.EditMode = DataGridViewEditMode.EditOnKeystrokeOrF2;
I hope any of this helps.
I'm having a slight problem getting a DataGridView to work properly. Currently, I have a DataSource to bind my data (in this case a List<T> of objects) and have the following method to bind the data to the control:
private void Bind(List<CAMPDomainLayer.FeeDefinition> fees)
{
BindingSource bs = new BindingSource(fees, null);
dgvFees.AutoGenerateColumns = false;
var colDesc = new DataGridViewTextBoxColumn
{
HeaderText = "Description",
DataPropertyName = "Description",
ReadOnly = true,
AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCellsExceptHeader
};
var colAmount = new DataGridViewTextBoxColumn
{
HeaderText = "Amount",
DataPropertyName = "FeeAmount",
ReadOnly = false,
};
var colDelete = new DataGridViewButtonColumn
{
HeaderText = string.Empty,
Text = "Delete",
};
dgvFees.Columns.AddRange(new DataGridViewColumn[] { colDesc, colAmount, colDelete });
dgvFees.DataSource = bs;
}
Notice, that I'm adding a button column for a delete button, I'm currently handling that with the following event:
private void dgvFees_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if(dgvFees.Columns[e.ColumnIndex] is DataGridViewButtonColumn && e.RowIndex >= 0)
{
int index = e.RowIndex;
dgvFees.Rows.RemoveAt(index);
dgvFees.Refresh();
CalculateTotal(Fees, PaymentAmount);
}
}
This seems to work fine. The dgvFees.Rows.RemoveAt(index); line removes the row from the control and the item from the underlying List<T>. The problem comes if I try to add a new row. Right now, I have a refresh button that grabs a list from the server and re-binds using the above Bind() method. The code to do that is:
Fees = fees;
Bind(Fees);
Where Fees is just a List<T>. When this is run, and I delete a row (right now there's) everything works fine. The row is deleted and the underlying list has nothing in it. But when I try to refresh (hence adding new rows), I get this:
The hat first row is duplicated, and appended horizontally to the first row. What stmpus me is right before we rebind, we can see that the DataSource only has one item:
Even after binding, I can inspect and see that there is still on 1 item in that datasource:
So my question is, why, if there is only one item in the DataSource, can I see a duplicate row. Is the old DataSource somehow "phantomed" in there? Is this an issue becuase of my biding approach (which admittedly, I don't know much about Winforms) or is this some bug in the framework?
In a Win forms application I have a problem with data binding and showing a command button column in the DataGridView as the last column allowing users to save each records after editing the content.
This is the binding part done in the presenter class
private void ShowEarnings()
{
BindingSource BS = new BindingSource();
var wageInfo = _WageManager.PrepareEarnings(_Model); // wageInfo contains a list of earnings objects.
BS.DataSource = wageInfo.GetEarnigsList(); //Earnings List contained in WageInfo object is returned.
_View.EarningDetails = BS;
}
In the form_load event I add a command button column to the DGV as follows
private void ShowSaveEarningsButton()
{
DataGridViewButtonColumn col = new DataGridViewButtonColumn();
col.UseColumnTextForButtonValue = true;
col.Text = "SAVE";
col.Name = "ACTION";
dgEmployeeEarnings.Columns.Add(col);
}
When the form is loaded the last column is shown with the header ACTION and a blank button is shown in the cell (first screen shot). When the ShowEarnings() method is called, the DGV is populated and now the button column is shown as the 3rd column (second screen shot). But it should be shown as the last column always!.
How to sort this out please?
Please see the screen shots.
EDIT: if I add the column after the binding it is shown properly. But I want it first!
Subscribe the DataBindingComplete event and reset the DisplayIndex property.
void dataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
dgEmployeeEarnings.Columns["ACTION"].DisplayIndex = dgEmployeeEarnings.Columns.Count - 1;
}
I have a master-detail layout with a section of popup menus (the Details) and a section with a DataGridView which holds the rows.
The popup-menu state is updated when the selected row in the DataGridView changes and the state in the DGV's selected row should update when the popup-menu changes.
All of this works except the row in the DataGridView doesn't immediately update when I change the value of the popup-menu. I have to select a different row in order to see my edits.
I'm assuming this is because the edit hasn't been committed until the selection changes.
My question is: How do I make the change to the popup become immediately reflected in the DataGridView?
I have experimented with calling EndEdit() in the SelectionChangeCommitted handler for the popup-menu, but this has no effect. I'm interested in a technique that would allow me to create a DataGridView that would behave as if there were no Undo mechanism to begin with. Ideally the solution would be generic and transplantable to other projects.
It looks like existing answers work well with BindingSource. In my case, where DataTable was directly used as a DataSource, they didn't work for some reason.
// Other answers didn't work in my setup...
private DataGridView dgv;
private Form1()
{
var table = new DataTable();
// ... fill the table ...
dgv.DataSource = table;
}
After some hair-pulling, I got it work without adding BindingSource indirection:
// Add this event handler to the DataGridView
private void dgv_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
dgv.BindingContext[dgv.DataSource].EndCurrentEdit();
}
private Form1()
{
dgv.CellEndEdit += dgv_CellEndEdit;
// ...
}
Here's what was going on. The answer was in the properties of the ComboBox instances. I needed to change their DataSourceUpdateMode from OnValidation to OnPropertyChanged. This makes sense. The DataGridView was very likely showing the current state of the data. It was just that the data hadn't been edited yet because focus had not left the ComboBox, validating the input.
Thanks to everyone for your responses.
this works well for me:
private void CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
var dgw = (DataGridView) sender;
dgw.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
Use this extension method. It works for all columns types, not just ComboBoxes:
public static void ChangeEditModeToOnPropertyChanged(this DataGridView gv)
{
gv.CurrentCellDirtyStateChanged += (sender, args) =>
{
gv.CommitEdit(DataGridViewDataErrorContexts.Commit);
if (gv.CurrentCell == null)
return;
if (gv.CurrentCell.EditType != typeof(DataGridViewTextBoxEditingControl))
return;
gv.BeginEdit(false);
var textBox = (TextBox)gv.EditingControl;
textBox.SelectionStart = textBox.Text.Length;
};
}
This method commits every change just after the change is made.
When we have a text column, after typing a character, its value will commit to the DataSource and the editmode of the cell will end.
Therefore current cell should return to edit mode, and position of the cursor set to end of text in order to enable user to continue typing reminder of the text.
Call the DataGridView.EndEdit method.
following will work
_dataGrid.EndEdit()
s fine once you set the value.
I'm using ultraTextEditors to embed multiselect ultragrids. I set up the datasource in the form_load event. The facilities is a list.
ultraGrid1.DataSource = facilities;
ultraGrid2.DataSource = facilities;
The grid loads fine, but if I select rows in the first grid, the selected rows are set in the second grid. How do I disable this?
Also, I can't get selected row into the text editor from ultragrid2. I use AfterEditorButtonCloseUp event to do this. The first grid has the same code and it works fine. What am I missing here?
private void utxtExcludeReport_AfterEditorButtonCloseUp(object sender, Infragistics.Win.UltraWinEditors.EditorButtonEventArgs e)
{
if (ultraGrid2.Selected.Rows.Count == 0)
utxtExcludeReportLab.Text = string.Empty;
else if (ultraGrid2.Selected.Rows.Count == 1)
utxtExcludeReportLab.Text = ultraGrid2.Selected.Rows[0].Cells[0].Text;
else
utxtExcludeReportLab.Text = "<multiple>";
}
Before you set the datasource for the second ultragrid, you need to create a new BindingContext for it, otherwise events raised by the datasource will be propagated to both grids.
For example (off the top of my head, so it may need refining:
ultraGrid2.BindingContext = new BindingContext();
ultraGrid2.DataSource = facilities;