It's supposed to be a very common workflow, so I am surprised that neither C# gridview or DevExpress provides an easy way to do it.
Example:
MyColumn is a field of combobox type column. When a user tries to edit value in this field, he will have to choose a value in the dropdown list. When the grid has 1 row, he can choose from "value A", "value B" or "value C". If the user has chosen "value A" in the 1st row, then in the 2nd row the available values for MyColumn become "value B" and "value C".
Currently I am doing it in a dirty way with DevExpress , where I calculate the combobox repository (modify RepositoryItemComboBox.Items property) everytime after a delete, insert or modify operation, and in the CustomRowCellEdit event handler I assign the updated repository to the column. The code is very convoluted and brittle.
------update------
I just came up with a better example of a use case:
Say that the grid asks the user to select his 5 most favorite US states. So the column State is a combobox type column that initially has a list of 50 states. If the user selects CA for the 1st row, then in the 2nd row he will have only 49 states available to select. In this case, you always want values to be unique in each row or it would not make sense.
You might have thought of it; but just in case if you haven't:
I believe, rather than trying to change the repository every time, better to actually validate the selected value in the combo (in the onchange event of the combobox) and override the user selection for this item in case it is a duplicate.
Note: Also, changing the repository, I think, will have it's own share of issues; as changing the DataSource after every delete, insert or modify will alter the data in other combo boxes (Obviously, here I am assuming that all combos uses the same Datasource).
I've got a solution.
Handle the CustomRowCellEditForEditing event. In the handler, traverse all rows and get all selected items, and remove the selected items from the repositoryItemComboBox1.Items (suppose that's your column editor).
Of course, the logic is a little more complicated because you will also have to change the Items collection when user edits or deletes a row.
Caution:
CustomRowCellEdit is the wrong way to go. Because everytime RepositoryItemComboBox.Items is changed the event will fire.
Related
quick question, let's say I have a combobox in a windows form, that get's filled with data from a sql table, and when a value is selected, it fills, let's say a textbox or a label with data from the same row. What I need (and can't get to make it work properly) is that each time I select a different value on the combobox, it will reflect those changes on the hypothetical textbox or label, without pressing any extra control, just by changing values on the combobox. For example:
Let's say I have this data on an SQL column and it's showing on a combobox on a windows form:
London
New York
Paris
etc.
and each time I select one city from the combobox, I want get that data from sql and show those changes on a textbox that has the data of the zip code, country, etc of each city.
What I'm currently using is the SelectedValue property that works fine th first time you select an item but doesn't change the data on the other controls when you select another value the second time.
Do you have any idea on how to implement this or a better way to do it?
Thanks!
I have a DataGridView with several TextBoxColumns and one ComboBox column called 'combo' that holds the client type. The problem is that I'd like to show both the currently selected client-type value along with the dropdown client-type list to validate future changes by the user. In SQL Server, I have a DB with two table columns, 'client_type_dropdown.name' and 'clients.client_type'. The 'client_type_dropdown.name' column is a validation list. The 'clients.client_type' column contains the current client type for clients in the database. Is there a way to show in 'combo' both 'client_type_dropdown.name' and 'clients.client_type' , i.e., one source for the ComboBoxColumn dropdown and a different source for the textbox part of 'combo'? Or do I need to have two columns in my grid?
I appreciate your help.
I'm using a third party grid, but I usually handle this by setting the combo drop down style to DropDown instead of DropDownList. This will allow your original database value to display, even if it isn't in the list.
This also allows free typing of values into the combo field, so the trick after that is to validate the user input to make sure it matches a value in the list before you allow them to save updated values. You could play around with the LimitToList property of the combo to possibly save you doing the validation manually, but with most controls I have worked with it will give you more grief than help.
I am working with a DataGridView and have a column of type DataGridViewComboBox and I have stumbled across a problem. Basically, depending on the value of the cell, i would like to set the .Items to a certain set of strings, but when the value is changed, i would like to change the .Items list. But with this, I will occasionally remove a string from the list that is currently being occupied by another DataGridViewCell, this changes all the values that were equal to the removed item, until i re-add it back to the list (after i have finished editing).
So basically, I am wondering if there is a way of hiding some of the items from the combo box Drop Down list, so that when a certain cell is selected, they can't choose an item that isn't allowed.
Thanks,
Lloyd
Instead of databinding the entire column, databind each row's DataGridViewComboBoxCell individually. That way, you don't have .items from one row affecting .items from another row.
I have a table Resource with a field Type. Type is a lookup into the table ResourceType.
So for instance ResourceType might have:
1: Books
2: Candy
3: Both
And Resource might have
1: Tom's Grocery, 2
2: Freds News, 3
It would display as: Tom's Grocery Candy
Now lets say I am using a databound combobox for the resource type and the third record is deleted from ResourceType, we of course get an error when Fred's News is displayed. I could simply put a marker in (perhaps an asterisk), indicating that it has been deleted, rather than actually delete it. It shows up as **Both* in the textbox portion of the combo and I am content.
However, I would not want it to show up as an option in the dropdown. Is this too much to ask from databound fields? Must I write my own code to load the drop down?
Add a bit Deleted column to the lookup table. When you delete a type, set Deleted = 1. When you pull back ResourceTypes, only pull out ResourceTypes where Deleted = 0 and then bind to the dropdown.
Edit:
How are you getting the dataset that you're binding to the dropdownlist? Are you using drag and drop datasets? I really haven't worked with datasets like that in years, but I'm pretty sure you can change the Get sql to what you need it to be.
OK, I already have most of that built into the solution - but I must be binding wrong. If I only pull back records where deleted = 0, I get exceptions - I'm guessing because the textbox can't be filled from the record set.
I guess I'm not sure how to bind the textbox display to one dataset - the one with all the records - and the dropdown to a filtered dataset.
Simply adding a deleted column was not enough - there had to be a way to see a deleted record in the text portion of a combo box while at the same time filtering out deleted records in the drop down.
In the end, I wrote a custom user control to handle this.
I have a DataGridViewComboBoxColumn in a DataGridView in a windows application. The user can change settings elsewhere to potentially invalidate a selection in a DataGridViewComboBoxColumn. I have a requirement to retain/display the invalid item while only leaving valid items selectable in the list.
Without correcting the selection an exception is thrown:
DataGridViewComboBoxCell value is not valid.
Catching and ignoring the setting reverts the selected value to the first valid item in the list.
Is there a way to provide a value to a DataGridViewComboBoxColumn so that it does not show up in the list of selectable values?
I found a very strange solution:
Set the autosizecolumnmode to none...
Here's an explaination
http://www.kebabshopblues.co.uk/2007/03/24/more-on-that-datagridviewcombobox-error/
I'm going to use an example that the values in the drop-down list are colors, and the DataGridView has a list of t-shirts in your closet.
Have you tried inserting the invalid color into the list object that is bound to the ComboBox column? Perhaps you can insert something into the list whose key matches your invalid color but shows "(Invalid)" (or other similar text). You'd have to respond to the CellValidating event if someone were to try and choose it after your initial binding.
If the invalid colors come by altering a lookup somewhere else in the application so that the DataGridView's values (the t-shirts) are no longer valid, you have some options. Perhaps you could change that logic to look up the data that goes to the list of t-shirts and see if there are any existing t-shirts with that color -- then prompt the user to say "You have deactivated Red, but you have Red T-shirts; what do you want to do?" You could stop deactivating Red, change the T-shirts, or delete the T-shirts.
If the invalid colors come from a source you don't control, you could prompt the user when they try to look at the list of t-shirts, "Red is no longer a valid color for T-shirts, what do we do with the Red t-shirts?"
We have a similar constraint in our application. We dropped the combo boxes and use CellValidating instead.
Presumably your bound datasource to populate the combobox is read only. If so, why not just temporarily insert the invalid value into the underlying datasource. That way it would still be displayed. You could add a temporary column to flag invalid items and not allow the user to leave it selected and then delete it when the user navigated off of the cell. I've never done this with a datagridview but we did something very similar with a different 3rd party grid. Good Luck!