Νομίζω πως η λύση είναι πιο απλή στο παραπάνω πρόβλημα και δεν χρειάζεται να γίνονται αναφορές στο control της φόρμας.
Ο κώδικας που θα γράψω παρακάτω όπως θα δείτε δεν αναφέρεται καθόλου στο DataGridView αλλά απλά μόνο στον μηχανισμό Binding. Επίσης αντί για Datatable χρησιμοποιώ BindingList και φυσικά ένα custom object Product με τα εξής properties. (Το ότι χρησιμοποιώ BindingList δεν σημαίνει ότι το DataTable δεν παίζει με την λύση αυτή.)
- Name
- Price
- Quantity
- ReadOnly TotalPrice (=Price*Quantity)
Δημιουργούμε την φόρμα με ένα DataGridView και δύο BindingSources τα οποία θα κάνουν Bind σε δύο διαφορετικές λίστες BindingList(Of Product)
Ας πούμε το πρώτο SelectedGridProductsBindingSource και το δεύτερο AvailableComboProductsBindingSource.
Δεν θα αναφερθώ στο setup του grid με τα columns νομίζω τα γνωρίζουμε αυτά. Απλά θέλω να τονίσω ότι στο ValueMember του ComboBox δεν έχω βάλει τιμή, γιατί θέλω το ComboBox να μου επιστρέφει το object που επίλέχθηκε και όχι κάποια τιμή του.
'Οταν λοιπόν ξεκινάμε το project η λίστα που δείχνει το SelectedGridProductsBindingSource θα είναι κενή, εφόσων δεν έχουμε επειλέξει ακόμα κάποιο προιόν, αντιθέτως η λίστα η οποία βλέπει το ComboBox μέσω του BindingSource φορτώνεται με όλα τα διαθέσιμα προιόντα.
Στο τέλος με Addhandler κάνουμε subscribe στο event PositionChanged του AvailableComboProductsBindingSource και γράφουμε το εξής :
SelectedGridProductsBindingSource.Item(SelectedGridProductsBindingSource.Position) = AvailableComboProductsBindingSource.current
Αυτό που γίνεται είναι ότι μόλις επιλέξουμε κάποιο προιόν από το combobox αμέσως ενημερώνεται η τρέχουσα γραμμή του DataGridView με το προιόν που επιλέξαμε. (Δενχρειάζεται δηλαδή να βγούμε από το κελί για να δούμε τις αλλαγές)
Ο κώδικας δεν αναφέρεται σε κανένα control οπότε ότι χρησιμοποιήσουμε στο UI και υποστηρίζει databinding θα παίξει μια χαρά. (Ουσιαστικά μπορούμε να φτιάξουμε μία γενική ρουτίνα και να την χρησιμοποιούμε σε όσα projects θέλουμε.)
Νομίζω ότι είναι μία αρκετά καλή λύση.