So I have a ultragrid with a list of custom objects as it's datasource. Two of the columns have ultracombos for drop down selection. The first column is for warehouse and is not filtered. The second column is bin and it is filtered based on the selection of the first combo. I have this working on the BeforeCellActivate event where I add a filter. However, I also need this to work when the data loads. So the process is below
Set Datasource to list of custom objects. The bin property (column) has values in it.
Set combo to editor of column
Data appears but it shows the wrong Text value. It's wrong because it's actually the wrong item.
So sample data in the bin Column - The values are duplicated when not filtered so it looks like below. The combo is filtered off another column that is not shown called Warehouse. So if the value in Bin column is 01, it gets the first item in the list but it is not filtered, so it gets 01 Bin. I need to get 01 Primary. I tried to set the filters when the data loads but that didn't work. I tried actually looping through the values and matching them against the combo value that it should get and tried changing to empty string then the correct value so the valuechanged event would fire, but that didn't work either.
Is there anyway to have the correct item selected (i.e. the correct Text value displaying) when first loading the datasource for a grid?
VM/DM
01 Bin
01 Primary
01 Seconday
02 Primary
Here is my code for the filter.
UltraGridBand rootBand = cmbPriBin.DisplayLayout.Bands[0]; rootBand.ColumnFilters.ClearAllFilters(); rootBand.ColumnFilters["WarehouseCode"].FilterConditions.Add(FilterComparisionOperator.Equals, args.Cell.Row.Cells["PrimWhse"].Value);
Hello Mike,
I have been investigating into the behavior you are looking to achieve in this case, and I would like to offer an alternative approach to the cascading UltraCombo scenario within an UltraGrid.
Rather than using a single instance of UltraCombo for your grid, you can loop through the Rows collection in the InitializeLayout event and get the UltraGridCell for the column you would like to apply an UltraCombo to from the UltraGridRow.Cells collection and then apply a separate instance of a combo to that UltraGridCell.EditorComponent. This allows you to keep an external collection of UltraCombos to use for a particular filter so that you can switch them out as needed, and I would recommend doing the switch at runtime within the InitializeRow event so that you can catch when your filter has potentially changed.
The benefit of this is that it allows you to perform the filtering on your data rather than having to do it whenever the active cell changes. It also gives you further control of what is displayed in the cell at what particular time, as you can change your underlying data to respect the new filter.
With your current approach, you may run into issues with the filtering as it does not appear that your filtering “keys” are unique in this case. I may have misunderstood your VM/DM diagram in this case, though.
I am attaching a sample project to demonstrate the multiple-UltraCombo cascading scenario. I hope this helps.
Please let me know if you have any other questions or concerns on this matter.
UltraGridCascadingComboDemo.zip
Just to expand a little bit on what Andrew wrote here...
The approach you are taking here of using Filtering is generally a good approach, but it will not work in a case where you have duplicate keys.
This approach is fine if you have a list that contains all possible values and you are changing the filtering in Before/AfterEnterEditMode, because you can filter the list that the user sees when they drop it down, and the grid also still have access to all of the other (filtered-out) values for the other cells. That last part is important, because if you mouse over a cell or a cell in the grid paints for any reason, it needs to be able to get the matching DisplayText for the DataValue of the cell. And it can do that because even though the values are filtered out of the Combo, they are still there. In a case with duplicate keys, though, the grid is going to end up painting the wrong text into the cells. For example: Let's say the user picks a value (01) from the combo in the first row of the grid. The combo is filtered based on your hidden column, so that's fine. Next, the user goes to row 2. The hidden column here has a different value, so the user sees a dropdown list with different filtered options. They choose a value that also happens to be (01).
Everything would be fine up to that point, until the cell in the first row paints (if the user mouses over it, for example). What happens then is that the grid asks the combo for the DisplayText for a value of (01) and since the cell never entered edit mode, the combo is still filtered for the second row and so it will find a match for the wrong value.
That's just one example of how things can go wrong if your keys are not unique. Of course, the other problem is the initial display of the grid - which is what you are asking about in your post here. What happens in that case is that all the cells on the screen paint and there is no filtering applied so it just matches up with the first item on the list that it finds. In order for that to work, you would have to change the filtering of the combo immediately before the cell paints, every time it paints. Theoretically, this is possible. You could use a DrawFilter and try to trap when the cell paints it's text, but it's a bad idea - it would be horribly inefficient and also pretty tricky to get it right. So Andrew's solution is probably a much better way to go. An even better way to go would be: make your key values unique. But I understand that you might not be able to change or control the data at this point in your application development.
Yeah I can't change the data unfortunately. Bin table is linked to warehouse table and the they users that entered the data used the same IDs for most bins even though the warehouse was different. They could do that because warehouse was also a key in the bin table.
I'm going to try the suggested approach and see if that works. Thanks guys. I will post an update after I try it.
So this worked but it also created a couple of minor issues that I can't seem to figure out. Below is my code
UltraCombo uc = new UltraCombo(); uc.DataSource = GetBins(); uc.ValueMember = "BinNum"; uc.DisplayMember = "Description"; HideColumnsInCombo(uc, "Description"); uc.DisplayLayout.BorderStyle = UIElementBorderStyle.None; uc.AutoCompleteMode = Infragistics.Win.AutoCompleteMode.Suggest; uc.DropDownStyle = UltraComboStyle.DropDown; UltraGridBand rootBand = uc.DisplayLayout.Bands[0]; rootBand.ColumnFilters.ClearAllFilters(); rootBand.ColumnFilters["WarehouseCode"].FilterConditions.Add(FilterComparisionOperator.Equals, args.Row.Cells["PrimWhse"].Value);args.Row.Cells["PrimBin"].EditorComponent = uc;
Two things...
First - The BeforeCellActivate event doesn't fire anymore when I select the drop down in the grid. Is that expected behavior?
Second - I can't get the grid lines in the combo to hide on all the rows (it only hides on first row) even though I thought I set it above. Also the width of the combo is really narrow and cuts off the display text. Is there a way to auto size the width to the possible display text values to users can see all the values or do I need to set the width manually?
Thanks for your help!
I have modified the code in my sample to be similar to yours, but in doing so I cannot seem to reproduce the behavior that the BeforeCellActivate event of the grid is not firing. On my end, this fires on click of each cell.
Regarding the gridlines in the combo to hide, I would recommend instead using the UltraCombo.DisplayLayout.Override.RowAppearance.BorderColor property. If you set this to be Color.White, it should make the UltraCombo’s rows appear to be borderless.
Regarding the width of the combo, I would expect that if the UltraCombo is used as your EditorComponent within your UltraGridColumn that it would expand to the size of the cells in that column. As such, the sizing of the UltraCombo should be determined based on the size of the UltraGridColumn that owns it.
I am attaching a modified version of the sample project I originally sent you in which the above pieces are implemented. If this sample project is not indicative of what you are doing in your application, can you please modify it and send it back such that it reproduces the issue you are seeing where the BeforeCellActivate event is not firing correctly? Alternatively, if you have an isolated sample project of your own where this is reliably reproduced and you can attach that here, I would gladly take a look at that instead.
6177.UltraGridCascadingComboDemo.zip