Infragistics UltraGrid : Unable to enter edit mode for focused column - c#

Info:
I am working with a C#.NET 3.5 winforms application and using Infragistics ultrgrid 8.2 in it. The grid has 5 columns, of which first three are readonly and 4th and 5th are valuelisted dropdowns. The 4th column is called "From".
What do I want to achieve:
When form launches, I want to set focus to first row cell for "From" column and also have it in edit mode.
What have I coded :
I have written following function
private void SetFocus()
{
_grid.Focus();
_grid.ActiveCell = _grid.Rows[0].Cells["From"];
_grid.PerformAction(UltraGridAction.EnterEditMode);
_grid.DisplayLayout.Bands[0].Columns["From"].Editor.Focus();
}
Which when called through form's paint event, works fine. But it is irritating to see the control get focus on each paint. Calling this on load, gets the focus right; but does not set the control in edit mode.
Thanks already
Jyotsna

I am not sure but I did a little Googling and maybe,
_grid.Rows[0].Cells["From"].Activate();
instead of calling
_grid.ActiveCell = _grid.Rows[0].Cells["From"];
Can't be sure if it will make a difference but give it a try.

Solved here: link
var cell = ... // Get the cell
if (cell != null)
{
BeginInvoke(new MethodInvoker(() =>
{
cell.Activate();
bugGrid.PerformAction(UltraGridAction.EnterEditMode);
}));
}

Related

How to display datagridview rows and items in designtime

I would like to display DataGridView rows during designmode/designtime. Is there a way to achieve this?
I have tried using this function: datagridview1.Rows.Add(); in the control's constructor but the rows and their items are displayed only in runtime.
The reason why i need to display rows and their items in designtime is that i am customizing the appearance of the datagridview control. So each time i make changes like changing the AlternatingRowColor, RowFont, etc i will have to run the control to see the changes.
This eats up time.
If i could display all the rows in designtime/designmode then i would be able to see changes immediately as i make them which will save much time.
I am customizing the appearance of the Datagridview Control in Windows Forms and I'm using C#.
I am not defining the control in code but rather have dragged-n-dropped the control from the Controls Tab and onto a Winform.
Thanks.
I'd add a designer verb to the context menu of the DataGridView and assign it by desired behavior. For example (as a start point to preview with dummy data):
using System;
using System.ComponentModel.Design;
using System.Linq;
using System.Windows.Forms;
using System.Windows.Forms.Design;
public class MyDataGridView : DataGridView
{
private IDesignerHost designerHost;
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
if (DesignMode && Site != null)
{
designerHost = Site.GetService(typeof(IDesignerHost)) as IDesignerHost;
var designer = (ControlDesigner)designerHost?.GetDesigner(this);
designer?.Verbs?.Add(new DesignerVerb("Preview with dummy data", (o, a) =>
{
//Some logic to add dummy rows, just for example
this.Rows.Clear();
if (Columns.Count > 0)
{
var values = Columns.Cast<DataGridViewColumn>()
.Select(x => GetDummyData(x)).ToArray();
for (int i = 0; i < 2; i++)
Rows.Add(values);
}
}));
designer?.Verbs?.Add(new DesignerVerb("Clear data", (o, a) =>
{
this.Rows.Clear();
}));
}
}
private object GetDummyData(DataGridViewColumn column)
{
//You can put some logic to generate dummy data based on column type, etc.
return "Sample";
}
}
Then as a result, you will see two menu items added to the context menu and by clicking on "Preview with dummy data", you will see two dummy rows added to the control at design time:
I think it's not possible in WinForms DataGridView, only in WPF. Maybe you can achieve this by extending it somehow, but it's probably not easy and doesn't worth it.
https://social.msdn.microsoft.com/Forums/windows/en-US/bc6c84c1-0a3a-4c97-8966-30be371576d9/how-to-add-some-row-to-datagridview-control-at-design-time?forum=winforms
Adding rows to the DataGridView in design time is not supported. Based on my understanding, this is because we often bind a data source to the DataGridView to generate rows, not add them directly.
As pointed out in the answer of Alex P., it is not possible. With a bit of experience, you'll be able to foretell the appearance.
If you have a lot of visual designing (i.e. due to your customer's detailed requirements), you can also design a little test application, where you can have i.e. a color list and font picker and apply selected properties to the DataGridView properties like DefaultCellStyle.BackColor, .ForeColor, Font, etc. at runtime. Simply using button or .SelectionChanged event for each property. You could probably find something finished on CodeProject or Github (this is related).

UWP CustomRenderer for Checkbox: Pointer over Checkbox changes style?

I'm working with Xamarin.Forms and I made a CustomRenderer for Checkbox in UWP. When I set all the Checkboxes of my items in the ListView to true by clicking the button "Alle", the Checkboxes are displayed correctly with the check inside the box:
However, if I hover my mouse over the Checkboxes, they immediately change their appearence (the check disappears but it's still selected). In the following screenshot, I moved my cursor over the 3rd - 7th Checkboxes:
This is my overridden OnElementChanged method in the CustomRenderer:
protected override void OnElementChanged(ElementChangedEventArgs<EvaCheckbox> e)
{
base.OnElementChanged(e);
var model = e.NewElement;
if (model == null)
{
return;
}
nativeCheckbox = new CheckBox();
CheckboxPropertyChanged(model, null);
model.PropertyChanged += OnElementPropertyChanged;
nativeCheckbox.Checked += (object sender, Windows.UI.Xaml.RoutedEventArgs eargs) =>
{
model.IsChecked = (bool)nativeCheckbox.IsChecked;
};
nativeCheckbox.Unchecked += (object sender, Windows.UI.Xaml.RoutedEventArgs eargs) =>
{
model.IsChecked = (bool)nativeCheckbox.IsChecked;
};
SetNativeControl(nativeCheckbox);
}
I tried to override the PointerEntered event of nativeCheckbox. It works, for example if I set the model.IsChecked to true on this event, it will be set to true:
nativeCheckbox.PointerEntered += (s, args) =>
{
model.IsChecked = true;
};
But I don't know how to (if even at this place) prevent the checkbox from changing it's appearance when moving the cursor above the Checkbox. Just leaving the triggered event with empty code like this won't change anything about the described behaviour:
nativeCheckbox.PointerEntered += (s, args) => { };
How can I prevent the Checkbox from changing it's appearance when I move my cursor over it?
Update:
I've created a sample project for this issue. You can find the repository here: https://github.com/Zure1/CustomCheckbox
It has the exact same described behavior. In the following screenshot I pressed the button "All" on the bottom of the screen and then the checkboxes look like correct with a check inside of them:
After moving the mouse cursor over the bottom 3 checkboxes, their change their appearance:
Information: I'm debugging on my desktop (Windows 10). I don't know if this issue exists on WinPhone. Just in case you're wondering why my checkboxes are red: My system color in Windows is red.
This is a tricky one as I have been struggling with this issue for a while, I'll try my best to answer this.
TL;DR: It's caused by ViewCell.
The issue comes down to Xamarin Forms ListView and ViewCell.
I haven't been able to track down the cause yet for many months and the way I get around this issue is by refreshing the ListView every time a change happens forcing a redraw of the entire ListView which can really impact performance.
My educated guess on what the cause could be is the rendering code for the ViewCell is missing something.
As for your particular issue, I have created a CheckBoxCell which you can use to display a list of checkboxes with a title. I forked your project and made the changes.
This will display something similar to what you are trying to achieve and doesn't have rendering issues so will be a good starting point. You are able to customize this to display images and the like but you'll have to do that in the platform-specific layout code.
Please note that I have only created the code for UWP and that should be enough to get you going for the other platforms.
I hope this helps somewhat.

DevExpress DXGrid column header double click event

I have to check / uncheck all the checkboxes (toggle) in a column when the user double clicks the column header.
How can I implement this behaviour in the DevExpress DxGrid control?
I have searched the DevExpress support forum but I haven't found a solution.
Also, i am working on MVVM Pattern.
This case works for WinForms, not tested in WPF yet, I posted might it direct you to some lights:
There is a workaround to accomplish this behave, you have to implement yourGrid_DoubleClick Event Handler, then calculate the hit Info of the mouse click, the hit info object will tell you if the double click was on a column, something like:
private void yourGridViewName_DoubleClick(object sender, EventArgs e)
{
DevExpress.XtraGrid.Views.Grid.GridView sndr =
sender as DevExpress.XtraGrid.Views.Grid.GridView;
DevExpress.Utils.DXMouseEventArgs dxMouseEventArgs =
e as DevExpress.Utils.DXMouseEventArgs;
DevExpress.XtraGrid.Views.Grid.ViewInfo.GridHitInfo hitInfo =
sndr.CalcHitInfo(dxMouseEventArgs.Location);
if (hitInfo.InColumn)
{
string x = hitInfo.Column.Name;
//Rest of your logic goes here after getting the column name,
//You might now loop over your grid's data and do your logic
}
}
but you have to notice that this action will not prevent the sorting that column's header do, you might need to disable sorting for this grid
Hope this helped.

How to maintain selected row of XtraGrid control

I'm developing an application of the xtragridview control in that application when i'll double click on row from the xtragridview that time one popup form opens . then the focus of the parent window changes & focus is assigned to the another form which is popup . and that time my selected row changes it's state & it focus/select the default 1st row from the xtrgridview.
but i want to maintain the focused/selected row as it is if user changes the focus from one form to another pop up form.
Is there any solution on this solution? what properties of xtragridview control should i've to set for this problem?
thanxs.....
Generally, the approach you are using does not require you to write an additional code. The XtraGrid does not reset its FocusedRow if you open a form by doubleclicking a grid row. So, I would suggest that you determine the cause of this behavior. This can be done by using the following approach:
1) handle the GridView's FocusedRowChanged event and set a breakpoint in it.
2) reproduce the issue and check which code forces the gridView to focus the first row.
This should give an idea on why this happens.
Also, I would suggest that you review the How to create the PopupForm for editing rows in the GridView and automatically create editors based on the column editors. example where the required functionality is implemented.
I think I know the cause of this problem. It appears because you are changing the DataView's RowFilter property. I think you want your editors to point to the clicked record. The best solution is to do not filter the DataView but to assign the BindingContext as it is done in the example above. Here is the code from it:
public EditForm(Point location, GridColumnCollection columns, object dataSource, BindingContext context)
: this() {
StartPosition = FormStartPosition.Manual;
Location = location;
BindingContext = context; // <<<<<<
allowTrackValueChanges = false;
this.dataSource = dataSource;
...
}
Mehod 1:
In the double click event handler just mention
return;
after all processes (Opening of another form etc.) are done.
After understanding your question better, I suggest to try method 2 I hope it surely works.
Method 2:
First record the current selected index before it opens another form or dialog ..
int index = datagridview.SelectedRows[0].Index; //or xdatagrid.SelectedRows[0].Index;**
Then after completion of form opening or other procedure add the following line
datagridview.Rows[index].Selected = true; //or xdatagrid.Rows[index].Selected = true;**
**N.B.: I have never used xdatagrid, but suggesting the solutions depending on my datagridview experience.
I use
GridView view = (GridView) sender;
Point pt = view.GridControl.PointToClient(Control.MousePosition);
var info = DoRowDoubleClick(view, pt);
when DoRowDoubleClick is:
private static GridHitInfo 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));
return info;
}
return null;
}

Set selected WPF DataGridCell to focused and editable upon event

Woot, first Stack Overflow post! I've been asked to work on a desktop application to improve an inventory process for my company. I dabbled with WPF in school and I figured I'd start there. After researching some, I learned about MVVM, put a design together, and forged ahead. Finally, I'm stuck and looking for some help and also a sanity check to see if I'm on the right path.
I have single-column DataGrid bound to an observable collection. Users of the application use a scan gun to enter values in. One potential value that I catch in my "Cell" model object is a "MoveNextColumn" value. This raises a custom event in my model that is handled in the View Model. The handler is supposed to simulate blank entries for all remaining rows in that column, set focus on the last row, and wait for input before moving on. So here is what I have so far:
private void dummyCell_MoveToNextColumn(object sender, RoutedEventArgs e) {
e.Handled = true;
// Cell is the model object containing the parsing rules and raising events
var lSender = sender as Cell;
var gridItems = ViewGridReference.Items;
var lastItem = gridItems[gridItems.Count - 1];
if (lSender == lastItem) {
// We are at the bottom of the column
// Move the program on to the next column
CurrentColumn++;
OnPropertyChanged("ItemPositions");
} else {
// Simulate "empty position" input for this cell and all cells down the column
// Cells are validating themselves as the simulation progresses
foreach (Cell item in ViewGridReference.Items) {
item.ActualItemCode = string.Empty;
}
// ViewGridReference is a reference to my DataGrid set from the view
ViewGridReference.Focus();
ViewGridReference.SelectedIndex = gridItems.Count - 1;
ViewGridReference.CurrentCell = new DataGridCellInfo(lastItem, ViewGridReference.Columns[0]);
((DataGridCell)ViewGridReference.SelectedItem).Focus();
}
}
All of this seems to be working as expected: all rows receive blank input and are validated (I use color properties in the cell to which the view binds to signify the validity of the entry).
Unfortunately, though the focus is on the last row as desired, it is not editable and the user cannot submit another "MoveNextColumn" value which would move the program on. The goal here is to minimize any keyboard interaction. Everything should be done with scan guns and barcodes.
Any ideas on how to make the selected cell editable after this code executes?
Any "hey, your design sucks" feedback would be cool too. This is new to me and I'm open to constructive criticism.
I have made some progress with this. The entire grid was left at an uneditable state in the code above. This now leaves focus on the last cell in my column and allows me to submit input with the scan gun.
This seems to work, but I'd still appreciate some feedback on whether there is a better way.
private void dummyCell_MoveToNextColumn(object sender, RoutedEventArgs e) {
e.Handled = true;
// Cell is the model object containing the parsing rules and raising events
var lSender = sender as Cell;
var gridItems = ViewGridReference.Items;
var lastItem = gridItems[gridItems.Count - 1];
if (lSender == lastItem) {
// We are at the bottom of the column
// Move the program on to the next column
CurrentColumn++;
OnPropertyChanged("ItemPositions");
} else {
// Simulate "empty position" input for this cell and all cells down the column
// Cells are validating themselves as the simulation progresses
foreach (Cell item in ViewGridReference.Items) {
item.ActualItemCode = string.Empty;
}
ViewGridReference.SelectedIndex = gridItems.Count - 1;
ViewGridReference.CurrentCell = new DataGridCellInfo(lastItem, ViewGridReference.Columns[0]);
(ViewGridReference.ItemsSource as ListCollectionView).EditItem(ViewGridReference.SelectedItem);
((DataGridCell)ViewGridReference.SelectedItem).Focus();
}
}
Updated 12/2/2010
Hey, there is an important update to this. The first thing to note is that text entry is being done with a scan gun in my scenario, so 'Enter' keys are sent down with each pull of the trigger. It shoots down each character followed by the Enter key all at once.
WPF sees this enter and wants to set the focus to the DataGridCell directly beneath the cell in which the Enter key input was received. The code above sets the focus to the last cell, but then the Enter key event still fires and is handled by DataGrid after this code is run. The effect is that the focus is reset back to the subsequent cell, not the last cell like I want.
So I need to either figure out how to eat the Enter key for just that scan, or I need to break how WPF handles Enter keys. The last line up there actually throws an exception. We are trying to use a Model class (Class.cs) as a DataGridCell, and there is nothing to handle that cast. Because of that, the Focus() method tries to operate on a null object and we get a NullReferenceException. This was really confusing me because Visual Studio 2010 would sometimes break to alert me about this, but sometimes it wouldn't. However, if I run the executable outside of Visual Studio, it works just fine. That's because unhandled, non-fatal exceptions are ignored and the Enter key behavior fails to operate as normal.
So it works, but in a pretty gross way. I either need to figure out how to do one-time handling of the Enter key and override the default WPF handler, or just leave it like it is and grimace.

Categories