I have following data in a lookup table.
I have an editable UltraGrid that allows users to select a category for each row, using a column having UltraComboEditor to display categories.
Users can only select categories that are not deleted i.e. Electronics and Smartphones. However, if the row already has a record that references deleted category (Personal care, Id=2), it should be added to the list of items in the UltraComboEditor
For all new rows, it UltraComboEditor should only contain non-deleted categories.
My Category column is similar to EmployeeID column in the following snapshot:
How can I accomplish that?
Thanks
- Talha Anwer
Hello,
In order to make sure that I understand your requirement correctly I have several questions:
Answering these questions is going to be highly appreciated.
Thank you for your cooperation.
Looking forward to hearing from you.
Sincerely,
Teodosia Hristodorova
Associate Software Developer
I would like users to be able to keep/select deleted categories for existing rows, but once they have modified the existing record and selected a non-deleted category, they should not be able to go back to select the deleted category. For all new rows, user should not be able to selected a deleted category.
I have been looking into your requirement, however, since hiding or disabling items in UltraComoEditor is currently not provided out of the box I can suggest to modify the data that is bound to the list by adding or removing items from it depending on the grid's cell value. This could be done in the UltraGrid's BeforeCellListDropDown event that fires just before the drop-down for each cell is expanded. There we can remove all rows that have deleted value equals to true an in case the cell value is a category that is deleted we could add it to the data again.
private void ultraGrid1_BeforeCellListDropDown(object sender, Infragistics.Win.UltraWinGrid.CancelableCellEventArgs e) { var cellValue = e.Cell.Value; for (int i = ((DataTable)ultraComboEditor1.DataSource).Rows.Count - 1; i >= 0; i--) { DataRow dr = ((DataTable)ultraComboEditor1.DataSource).Rows[i]; if (dr.ItemArray[2].ToString() == "True") { dr.Delete(); } } ((DataTable)ultraComboEditor1.DataSource).AcceptChanges(); if (cellValue != null) { var row = getRowIfTrue(cellValue.ToString()); if(row != null) { ((DataTable)ultraComboEditor1.DataSource).ImportRow(row); ((DataTable)ultraComboEditor1.DataSource).DefaultView.Sort = "ID desc"; } } }
Additionally, if you require to hide or disable the item, instead of modifying the data source, I can recommend using UltraCombo instead of UltraComboEditor. UltraCombo is like a WinGrid and the Rows within it can be disabled using the Activation property on the row or their hidden property could be changed.
I have attached a sample application, that uses the above approach.
Please test it on your side and let me know if I may be of any further assistance.
8838.UltraGrid_UltraComboEditor.zip
Removing the items from the data source is probabaly not a good idea - because if your UltraComboEditor is translating DataValue to DisplayText, then this will mean that existing rows that are pointing to deleted values will no longer get translated. And since the UltraComboEditor services the entire column, this will affect other cells in the column in addition to the one you happen to have dropped down.
A better solution would be to use UltraDropDown instead of UltraComboEditor. UltraDropDown allows you to hide rows without removing them. So you can simply hide the rows for options that are deleted. But since they are still on the list and just hidden, the grid will still be able to translate those DisplayText and DataValues. And the user wont be able to select the deleted/hidden options on the list.
I don't want to force users to modify records that already reference deleted records. They should be able to select all the active records, plus one deleted record that is currently being referenced by the row.
In a scenario where we have two active categories (say IDs 1 and 2) and two deleted categories (IDs 3 and 4). And we have two rows, first referencing deleted category 3 and the other referencing deleted category 4. So for first row, I would like to list categories 1, 2 and 3. For second row, I'd like users to be able to select from categories 1, 2, and 4.Thanks
So then what I would do is use UltraDropDown (instead of UltraComboEditor) and handle the InitializeRow event of the control.
Handle the CellListDopDown event of the grid. Loop through the rows of the UltraDropDown and set the Hidden property on each row. If the row is Deleted and it's value does not match the current value of the cell, hide it.
But you will need to store the value of the current cell when the user enters that cell in case they drop down more than once. You could use AfterCellActivate for that.
I was able to use UltraComboEditor by using the DataFilter (implementing IEditorDataFilter). My Convert() method looks like this:
I went for this because it looks simple, and we were already using UltraComboEditor. So we don't need to modify a lot of code that depended on UltraComboEditor.
I appreciate your help and suggestions on this issue
It is possible to achieve a required behavior using the UltraDropDown's InitializeRow, BeforeDropDown, and AfterCloseUp events. This will eliminate the need to create a new control derived from UltraDropDown.
The InitializeRow gets fired for every row in the UltraDropDown and there you could hide the row depending on its Deleted value.
The BeforeDropDown gets fired right before the drop down is about to drop down and there you could get the value in the grid's cell and make this row in the drop-down visible.
The AfterCloseUp gets fired after the drop-down has closed up and there could hide the deleted row from the drop-down if you keep it in a global variable.
Additionally, the UltraDropDown could be styled to look exactly as UltraComboEditor using the InitializeLayout where could be hidden the ID and Deleted columns, all column headers and set the width of the Category column to the value of the grid's cell, and set the border of the UltraDropDown's rows and cells to Transparent.
I have modified the previous sample in order to demonstrate this behavior and it could be found attached below. Please test it on your side and let me know if I may be of any further assistance.
3513.UltraGrid_UltraDropDown.zip
Yes, this approach actually works. However, I am wondering if I could write a control, maybe derived from UltraDropDown and use the control's events to achieve the same behavior. Without having to bind to UltraGrid events.