I have an UltraWinGrid on one of my forms, which has 3 colums: Rate, Date From and Date To. It is used for setting up VAT rates, so I need to validate the grid in two ways.
1) When the user enters a value in the DateFrom column, the DateTo column's MinValue is the DateFrom value.AddDays(1)
2) And the flip side of this, when a value is entered into the DateTo column, the DateFrom MaxValue is DateTo value.AddDays(-1)
But, I can't work out how to do this. I tried using
e.Cell.Row.Cells("DateFrom").MaxValue, but this isn't a valid method/.
So how can I do this? I don't want it set for the full column, only for that cell on that row.
I have, at the top of the form class added inPublic Class frmSystemSettings
Implements IEditorDataFilter
But how can I use this/the Convert Function to set a Min/Max Value? (Language is vb.net)
Hi Gary,
There's no property to assign a MinValue or MaxValue on an individual cell.
So you have a few options. The simplest one I can think of is to simply set the MinValue/MaxValue on the entire column right before the cell in that column enters edit mode.
Private Sub UltraGrid1_BeforeEnterEditMode(sender As System.Object, e As System.ComponentModel.CancelEventArgs) Handles UltraGrid1.BeforeEnterEditMode Dim grid As UltraGrid = sender Dim activeCell As UltraGridCell = grid.ActiveCell Dim activeRow As UltraGridRow = activeCell.Row Dim band As UltraGridBand = activeCell.Band If activeCell.Column.Key = "DateFrom" Then Dim dateTo As DateTime = CType(activeRow.Cells("DateTo").Value, DateTime).Date band.Columns("DateFrom").MaxValue = dateTo.AddDays(-1) ElseIf activeCell.Column.Key = "DateTo" Then Dim dateFrom As DateTime = CType(activeRow.Cells("DateFrom").Value, DateTime).Date band.Columns("DateTo").MinValue = dateFrom.AddDays(1) End If End Sub
Private Sub UltraGrid1_BeforeEnterEditMode(sender As System.Object, e As System.ComponentModel.CancelEventArgs) Handles UltraGrid1.BeforeEnterEditMode Dim grid As UltraGrid = sender Dim activeCell As UltraGridCell = grid.ActiveCell Dim activeRow As UltraGridRow = activeCell.Row Dim band As UltraGridBand = activeCell.Band
If activeCell.Column.Key = "DateFrom" Then Dim dateTo As DateTime = CType(activeRow.Cells("DateTo").Value, DateTime).Date band.Columns("DateFrom").MaxValue = dateTo.AddDays(-1) ElseIf activeCell.Column.Key = "DateTo" Then Dim dateFrom As DateTime = CType(activeRow.Cells("DateFrom").Value, DateTime).Date band.Columns("DateTo").MinValue = dateFrom.AddDays(1) End If End Sub
Another option would be to try to use an editor and a DefaultEditorOwner, but this would be prohibitively expensive for performance because you'd have to create a new editor and owner for every cell in each column.
Another option would be to not use a MinValue/MaxValue, but just use an event and enforce this restriction in code. You could use the BeforeExitEditMode or BeforeCellUpdate events for this.
Hello Dave,
To handle this scenario you may use BeforeCellUpdate event of the grid. In this event check if the updated cell is under Date To (Date From column). If so check the date user provided in the cell. If date does not comply with your application constrains set the row error, or cancel the event and show a message box to user. If you chose to use data error note that in case of error the grid will automatically revert the old value of the cell. If you chose to cancel the event the user will not be able to leave the cell until correct value is provided. You can use code like this:
Private Sub UltraGrid1_BeforeCellUpdate(sender As Object, e As BeforeCellUpdateEventArgs) Handles UltraGrid1.BeforeCellUpdate If e.Cell.Column.Header.Caption = "Date To" Then Dim dateFrom = e.Cell.Row.GetCellValue("Date From") If dateFrom IsNot DBNull.Value Then Dim dateTo = Date.Parse(e.Cell.Text) If dateTo < dateFrom.AddDays(1) Then ' If provided date is less than date from plus one day set row error text ' The grid will automatically revert the old value and will not update the cell e.Cell.Row.DataErrorInfo.RowError = "Date To should be at least one day after Date From" Else ' Clear the row errors if provided date is ok e.Cell.Row.DataErrorInfo.ClearErrors() End If End If End IfEnd Sub
Attached is a small sample showing this approach. Please check my sample and let me know if this is what you are looking for, or if I am missing something.
Regarding IEditorDataFilter I am not sure why you need this. This interface has a single method Convert. This method gets called each time the grid needs to convert a value. For example when user types a new value in Date To cell and leave the cell the value she typed is Display value. As soon as she update this value Convert method gets called and it tries to convert value from Display to Editor. If it succeed it will try to store the value in the data source. This will fire againg Convert method from Editor to Owner. The same process will happen in back order when grid initialize cells - Owner will pass the cell value to the Editor, and the Editor will pass the cell value to Display. Each time Convert will be called. If you implement this interface you may change the way cell values are shown to the user, e.g. you may force the cell to show 'Today' instead of today date, but you cannot suppress user from entering invalid date as per your application logic. Use BeforeCellUpdate instead as shown above.
Hi Milko,
Thanks for the response - A couple of things though.
First thing, Dim dateFrom = e.Cell.Row.GetCellValue("Date From") gives me an error "Value of type 'String' cannot be converted to Infragistics.Win.UltraWinGrid.UltraWinGridColumn". I believe this is because I'm setting the DataSource as a DataSet of results that I'm taking from a database table, whereas in the sample project you created the DataTable dynamically. How would I set the column in this case?
Secondly, even with e.Layout.Override.SupportDataErrorInfo = SupportDataErrorInfo.RowsOnly in the InitializeLayout code of the grid, I'm still getting "'DataErrorInfo' is not a member of 'Infragistics.Win.UltraWinGrid.UltraWinGridRow'" on the e.Cell.Row.DataErrorInfo lines - Any idea why?
Please find bellow answers to your questions:
Please let me know if any additional questions arise.