multiple ultragrids bound to the same datasource - c#

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;

Related

Datagridview Select all

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;

How to get current row of datagridview values when clicking on button?

I have a View Model in which my data is stored to be used on the presenter and window. However, I now need to get (when pressing a button) the current row's results on the grid into my view model. I first used the mouse double click event, but the requirements changed from that to a button on the form:
private void dgvResults_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
{
if (this.colOrderNo.Index != e.ColumnIndex || e.RowIndex < 0) return;
var auditOrder = (PurchaseOrdersTrackingViewModel) this.dgvResults.Rows[e.RowIndex].DataBoundItem;
this.AuditOrderKey = $"{auditOrder.OrderNo}|{auditOrder.ItemNo}|{auditOrder.WarehouseId}|{auditOrder.ItemSequence}";
}
That's my old code. Now I need that here:
private void btnAuditLog_Click(object sender, EventArgs e)
Not sure how to refer to the RowIndex without the DataGridViewCellMouseEventArges event. I tried the CurrentRow property, but it doesn't do the job.
Just another question on the fly, if someone could assist with that as well, how do I get a value from one form to another, spesifically a properties value. It's not on the grid, in a control. It's basically just public string order that's all. I set the value on one form, then need it for query filtering on another. Let me know if you need anything else.
You want to use the SelectedRows property of the DataGridView. It tells which row is selected. In this case, you seem to want the first selected row (since you have a single property called this.AuditOrderKey).
The column order no to longer matters in this context.
if (dgvResults.SelectedRows.Count == 0) return;
var auditOrder = (PurchaseOrdersTrackingViewModel) dgvResults.SelectedRows[0].DataBoundItem;
this.AuditOrderKey = $"{auditOrder.OrderNo}|{auditOrder.ItemNo}|{auditOrder.WarehouseId}|{auditOrder.ItemSequence}";
If you don't have selected rows, CurrentRow is an option:
if (dgvResults.CurrentRow == null) return;
var auditOrder = (PurchaseOrdersTrackingViewModel) dgvResults.CurrentRow.DataBoundItem;
this.AuditOrderKey = $"{auditOrder.OrderNo}|{auditOrder.ItemNo}|{auditOrder.WarehouseId}|{auditOrder.ItemSequence}";
Use the SelectedRows property of the DataGridView. Assuming that you set your DataGridView as MultiSelect = false; and SelectionMode = FullRowSelect;
if (dgvResults.SelectedRows.Count > 0)
{
dgvResults.SelectedRows[0].Cells["yourColumnName"].Value.ToString();
}
In your button click event, it will look like this. (Assuming that your button name is btnEdit)
private void btnEdit_Click(object sender, EventArgs e)
{
if (dgvResults.SelectedRows.Count > 0)
{
string selectedValue = dgvResults.SelectedRows[0].Cells["yourColumnName"].Value.ToString();
}
}

Reset DataGrid.SelectedIndex after user has selected another

In the UI I'm working with, in a DataGrid, there are cases where the user might select a different row, but after a dialog interaction, the old row needs to be shown as being selected once again. If I simply try
BundleQueueDG.SelectedIndex = currentBundleIndex;
that does not do anything and in fact, once the SelectionChanged method exits, it changes to the new value. What is the best way to "re-select" the previously-selected row?
Try setting the SelectedItem property. Preserve what was selected before and set the SelectedItem with what was previously selected in your event.
Something like this:
private void DgDataGrid_OnSelectedCellsChanged(object sender, SelectedCellsChangedEventArgs e)
{
int newIndex = (sender as DataGrid).SelectedIndex / 2;
if (Convert.ToInt32(newIndex) >= 1)
(sender as DataGrid).SelectedItem = previous;
else
{
previous = (sender as DataGrid).CurrentItem;
}
}

How to expand the ComboBox in a (WPF) DataGridComboBoxColumn?

In my C# WPF application (.NET 4.0) I have a DataGrid dynamically filled from code including a DataGridComboBoxColumn:
public static DataGridComboBoxColumn getCboCol(string colName, Binding textBinding)
{
List<string> statusItemsList = new StatusList();
DataGridComboBoxColumn cboColumn = new DataGridComboBoxColumn();
cboColumn.Header = colName;
cboColumn.SelectedItemBinding = textBinding;
cboColumn.ItemsSource = statusItemsList;
return cboColumn;
}
Using the BeginningEdit event different checks are performed.
If the checks return okay, I want to expand the combobox directly, otherwise edit mode is cancelled:
void dataGrid_BeginningEdit(object sender, DataGridBeginningEditEventArgs e)
{
...
if(notOK)
e.Cancel;
else {
DataGridComboBoxColumn dgCboCol = (DataGridComboBoxColumn)e.Column;
// expand dgCboCol
}
...
}
Questions: How to expand the combobox programmatically? Is BeginningEdit event the right place to do that?
Answer:
void dataGrid_PreparingCellForEdit(object sender, DataGridPreparingCellForEditEventArgs e)
{
if (e.EditingElement.GetType().Equals(typeof(ComboBox)))
{
ComboBox box = (ComboBox)e.EditingElement;
box.IsDropDownOpen = true;
}
}
Take a look at this
Try setting edit mode on the grid to a single click and then use the CellClick event to obtain the comboBox and expand it.
dataGrid.BeginEdit(true);
ComboBox comboBox = (ComboBox)dataGrid.EditingControl;
comboBox.IsDropDownOpen = true;
From DataGridBeginningEditEventArgs, you could access the generated element for the cell about to be edited like this:
var contentComboBox = e.Column.GetCellContent(e.Row) as ComboBox;
However, I'm not sure that this will get the actual ComboBox you need. DataGrids can generate two different elements for each cell, depending on whether they are in edit mode (read-only and read-write elements). Since BeginningEdit happens just before entering edit mode, this will get the read-only element.
The better event to handle this in would probably be PreparingCellForEdit, which will fire after BeginEdit is actually called on the data item (in other words, if BeginningEdit was not canceled). In that event, you can access the element directly through the EditingElement property.

How do I make a DataGridView immediately commit edits?

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.

Categories

Resources