I would like to update row of datagrid when selection is changed.
private void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
Strint rowID = ((String)((DataGrid)sender).SelectedValue);
RadekTabulky row = Client.getRadek(rowID);
if(row != null)
{
dataGrid.SelectionChanged -= DataGrid_SelectionChanged;
int index = dataGrid.SelectedIndex;
viewModel.Sumy = new SumStorage(viewModel.Soubor, viewModel.Radky);
dataGrid.SelectedIndex = index;
dataGrid.SelectionChanged += DataGrid_SelectionChanged;
}
}
I wrote this simple code. But when I click on row, the row is selected, updated but it looks like grid lost focus and I cannot see which row is selected. When I click again at same row, it will get that blue color indicating it is selected.
Is there a way how to update viewModel without losing this focus?
Related
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());
}
I have a datagrid with DatagridComboboxcolumn as one of the column in winforms.
Combobox is contain two items Y,N.
If user select Y,I need to change the value for the two columns of same row.
Same thing will happen when User select "N".
I have tried to register ComboBox_SelectedIndexChanged as follows.
But not able to get the row index or coulmn index for the selected row and change the values of the same row columns.
Please help me asap.
private void gridTesr_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
ComboBox combo = e.Control as ComboBox;
if(combo != null)
{
// Remove an existing event-handler, if present, to avoid
// adding multiple handlers when the editing control is reused.
combo.SelectedIndexChanged -=new EventHandler(ComboBox_SelectedIndexChanged);
// Add the event handler.
combo.SelectedIndexChanged +=new EventHandler(ComboBox_SelectedIndexChanged);
}
}
private void ComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
}
Try declaring your own method to handle the ComboBox.SelectedIndexChanged event.
private void gridTesr_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
ComboBox combo = e.Control as ComboBox;
if(combo != null)
{
// Remove an existing event-handler, if present
combo.SelectedIndexChanged -= this.MyComboEventHandler;
// Add the event handler
combo.SelectedIndexChanged += this.MyComboEventHandler;
}
}
private void MyComboEventHandler(object sender, EventArgs e)
{
string myValue = ((ComboBox)sender).SelectedItem.ToString();
DataGridViewCell cell = gridTesr.CurrentCell;
MessageBox.Show(string.Format("The current ComboBox resides in the Row {0} and Column {1} and it currently has the {3} value.",
cell.RowIndex, cell.ColumnIndex, myValue));
}
I have a WPF Datagrid and I'm implementing drag and drop functionality.
The datagrid has a list of "files" and the user can drag them and copy the file to the desktop.
This is done like this:
string[] files = new String[myDataGrid.SelectedItems.Count];
int ix = 0;
foreach (object nextSel in myDataGrid.SelectedItems)
{
files[ix] = ((Song)nextSel).FileLocation;
++ix;
}
string dataFormat = DataFormats.FileDrop;
DataObject dataObject = new DataObject(dataFormat, files);
DragDrop.DoDragDrop(this.myDataGrid, dataObject, DragDropEffects.Copy);
I have two questions:
1. When I want to drag multiple items- this is a problem because after I select a couple and start clicking on one to start dragging- only that gets selected and the other items get deselected. I tried the solution that is given here but for some reason it doesn't work.
2. I want to remove the dragged item from the datagrid after it is copied. The problem is that I don't know how to check if the file was copied or whether the user just dragged it on the screen without copying it.
I hope you can help me solve these problems.
Thanks!
I think this i what you are looking for:
add this code to the DataGrid__PreviewMouseLeftButtonDown event handler:
private void DataGrid_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
this.startingPosition = e.GetPosition(null);
DependencyObject dep = (DependencyObject)e.OriginalSource;
// iteratively traverse the visual tree until get a row or null
while ((dep != null) && !(dep is DataGridRow))
{
dep = VisualTreeHelper.GetParent(dep);
}
//if this is a row (item)
if (dep is DataGridRow)
{
//if the pointed item is already selected do not reselect it, so the previous multi-selection will remain
if (songListDB.SelectedItems.Contains((dep as DataGridRow).Item))
{
// now the drag will drag all selected files
e.Handled = true;
}
}
}
and now the draging won't change you selection.
Have a good luck!
I used that article to write my answer
Improved on finding the row.
Also selecting the clicked row when not dragging is added.
This now behaves exactly as other Microsoft selectors (eg Outlook)
public TreeDataGrid()
{
Loaded += TreeDataGrid_Loaded;
LoadingRow += new EventHandler<DataGridRowEventArgs>(TreeDataGrid_LoadingRow);
}
#region MultiSelect Drag
object toSelectItemOnMouseLeftButtonUp;
void TreeDataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
{
e.Row.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(Row_PreviewMouseLeftButtonDown);
e.Row.PreviewMouseLeftButtonUp += new MouseButtonEventHandler(Row_PreviewMouseLeftButtonUp);
}
void Row_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
DataGridRow row = (DataGridRow)sender;
toSelectItemOnMouseLeftButtonUp = null; // always clear selecteditem
if (SelectedItems.Contains(row.Item)) //if the pointed item is already selected do not reselect it, so the previous multi-selection will remain
{
e.Handled = true; // this prevents the multiselection from disappearing, BUT datagridcell still gets the event and sets DataGrid's private member _selectionAnchor
toSelectItemOnMouseLeftButtonUp = row.Item; // store our item to select on MouseLeftButtonUp
}
}
void Row_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
DataGridRow row = (DataGridRow)sender;
if (row.Item == toSelectItemOnMouseLeftButtonUp) // check if it's set and concerning the same row
{
if (SelectedItem == toSelectItemOnMouseLeftButtonUp) SelectedItem = null; // if the item is already selected whe need to trigger a change
SelectedItem = toSelectItemOnMouseLeftButtonUp; // this will clear the multi selection, and only select the item we pressed down on
typeof(DataGrid).GetField("_selectionAnchor", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(this, new DataGridCellInfo(row.Item, ColumnFromDisplayIndex(0))); // we need to set this anchor for when we select by pressing shift key
toSelectItemOnMouseLeftButtonUp = null; // handled
}
}
#endregion
We have a problem for focus a cell of DataGrid after Its data of bounded collection has Refreshed.
for example we set a filter for its collection and then we want to refocus a stored cell of stored column.
Is it true that we think a call to ScrollIntoView is synchronized it means after call it our desired row and cell are created and we can set focus? (again it means after we call to ScrollIntoView , Is it true we think that Itemsgenerator finished its work and we can surly find our desired cell)
$
//set filter of DataGrid Collection
DataGrid_Standard.ScrollIntoView(rowNumber,cellNumber);
//we sure our desired cell are created now
DataGridRow row = (DataGridRow)DataGrid_Standard.ItemContainerGenerator.ContainerFromIndex(index);
if (row == null)
{
// may be virtualized, bring into view and try again
DataGrid_Standard.ScrollIntoView(DataGrid_Standard.Items[index]);
row = (DataGridRow)DataGrid_Standard.ItemContainerGenerator.ContainerFromIndex(index);
}
DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(rowContainer);
// try to get the cell but it may possibly be virtualized
DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
// now try to bring into view and retreive the cell
DataGrid_Standard.ScrollIntoView(rowContainer, DataGrid_Standard.Columns[column]);
cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column); cell.focus();
Related
Here's a datagrid Selection changed event handler that moves a virtualized row into view and then sets the focus to that row. This works for me:
private void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
DataGrid dg = (DataGrid)sender;
if (dg.SelectedItem == null) return;
dg.ScrollIntoView(dg.SelectedItem);
DataGridRow dg_row = (DataGridRow)dg.ItemContainerGenerator.ContainerFromItem(dg.SelectedItem);
if (dg_row == null) return;
dg_row.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
}
EDIT: Using the dg_row.MoveFocus method had an undesriable effect (a checkbox column required two clicks to set instead of one) and it worked better for me to just use
dg_row.Focus();
Action action = () =>
{
dg .ScrollIntoView(dg .SelectedItem);
var item = dg.ItemContainerGenerator.ContainerFromIndex(index) as DataGridRow;
if (item == null) return;
item.Focus();
};
Dispatcher.BeginInvoke(DispatcherPriority.Background, action);
This should work fine for your case.
I desperately try to figure how to change the background color of a single cell in a winforms dataGridView. I have two columns: if i change content in the second column, i want the cell in the first column of this row to change the background accordingly.
private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (e.ColumnIndex != 0 || e.RowIndex == -1)
return;
if (dataGridView1.Rows[e.RowIndex].Cells[1].Value.ToString() == "Red")
e.CellStyle.BackColor = Color.Red;
else
e.CellStyle.BackColor = Color.White;
}
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex != 1 || e.RowIndex == -1)
return;
// dataGridView1.Rows[e.RowIndex].Cells[0]. ???
}
The first event handler sets the backColor of the cells in the first column if they are painted. The second event handler should tell the first cell to paint if the value is changed. If i change the columns width it paints the correct color, so the first handler does the work. But how to trigger the cell painting?
Thanx for help.
I would have thought that the edit would have triggered a repaint, but if that event isn't being run after the edit then you should be able to force the issue with something like:
dataGridView1.InvalidateCell(e.RowIndex, 1);
OK, here is the bad hack:
If i insert
var x = dataGridView1.Columns[0].DefaultCellStyle;
dataGridView1.Columns[0].DefaultCellStyle = null;
dataGridView1.Columns[0].DefaultCellStyle = x;
in the CellValueChanged event handler, the whole first column is repainted. So my cell is repainted as well. But that't dirty, isnt't it?
You have to create a new cell style object, set it to the color you want and then apply it to the current cell.
private DataGridViewCellStyle CellStyleGreenBackgnd;
CellStyleGreenBackgnd.BackColor = Color.LightGreen;
dataGridView.CurrentCell.Style.ApplyStyle(CellStyleGreenBackgnd);
Try this.
dataGridView1.Rows[indexhere].Cells[indexhere].Style.ForeColor = Color.Yellow;