3. Formanty ComboBox i ListBox
Transkrypt
3. Formanty ComboBox i ListBox
7 3. Formanty ComboBox i ListBox 1.1. Źródła danych Pojedyncze elementy Rekordset Pojedyncze elementy złożone W tym podrozdziale rozpatrzymy taką sytuację, w której na formularzu umieszczone jest pole kombo (powiedzmy, że o nazwie cboProdukty), które ma wyświetlać listę oferowanych produktów. Załóżmy dalej, że informacja wyświetlana ma zawierać nie tylko nazwę produktu, ale także kilka informacji dodatkowych (wielkość opakowania, cenę jednostkową, ewentualnie nazwę producenta). Załóżmy też, że po wyborze danego produktu będziemy chcieli uzyskać takie informacje o nim, jak: jego identyfikator, nazwę, liczbę dostępnych pozycji, cenę jednostkową, stawkę podatku VAT. Wprowadzimy jeszcze jedno, dodatkowe, ale bardzo ważne założenie: w sytuacji, w której liczba dostępnych pozycji spadnie do zera musimy dany produkt usunąć z kolekcji elementów pola kombo czy listy. To ostatnie założenie powoduje, że jako źródła danych nie możemy wykorzystać rekordsetu, ponieważ wymagałoby to zmian w bazie danych (a może być jeszcze za wcześnie na ich dokonanie). W takiej sytuacji można zaproponować następujące podejście: • Pobieramy z bazy danych rekordset zawierający potrzebne informacje; • W pętli tworzymy obiekt złożony (klasę lub strukturę), który dodajemy do kolekcji elementów danego formantu. Rozpatrzymy taką sytuację na przykładzie formularza frmSprzedaz rozwiązania (projektu) Fifo. Formularz ten ma ułatwić obsługę kupujących różnego rodzaju produkty żywnościowe w hurtowni zajmującej się dystrybucją tego typu produktów. Procedura przechowywana o nazwie pDajDostepneProdukty utworzona w przykladowej bazie o nazwie Fifo zwraca rekordset o polach pokazanych poniżej. 8 Przed utworzeniem z każdego wiersza informacji złożonej (instancji klasy) musimy utworzyć odpowiednią klasę w rozwiązaniu VisualStudio. W naszym przypadku jest to klasa o nazwie CProdukty utworzona w pliku CSprzedaz.vb. Kod tej klasy pokazany jest poniżej. Public Class CProdukty Private midp As Integer Private mProdukt As String Private mVat As Decimal Private mCena As Decimal Private mIle As Integer ' konstruktor bezparametrowy Public Sub New() End Sub ' konstruktor z parametrami Public Sub New(ByVal idp As Integer, ByVal nazwa As String, _ ByVal cena As Decimal, ByVal vat As Decimal, _ ByVal ile As Integer) midp = idp mProdukt = nazwa mCena = cena mVat = vat mIle = ile End Sub ' seria właściwości zwracających wartości zmiennych prywatnych Public ReadOnly Property Idp() As Integer Get Return midp End Get End Property Public ReadOnly Property Produkt() As String Get Return mProdukt End Get End Property Public ReadOnly Property StawkaVat() As Decimal Get Return mVat End Get End Property Public ReadOnly Property Cena() As Decimal Get Return mCena End Get 9 End Property ' właściwość zwracająca lub ustawiająca zmienną mIle Public Property IleJest() As Integer Get Return mIle End Get Set(ByVal value As Integer) mIle = value End Set End Property ' nadpisanie funkcji ToStgring Public Overrides Function ToString() As String Return mProdukt End Function End Class Procedura przechowywana pDajDostepneProdukty wywoływana jest przez metodę PrzygotujSprzedaz zdefiniowaną w klasie CSprzedaz. Rekordset przypisywany jest do obiektu typu DataTable, który z kolei jest źródłem danych dla formantu typu DataGridView umieszczonego na formularzu frmSprzedaz. Procedura zdarzenia Load tego formularza przegląda wiersze tego formantu (pomocniczego gridu o nazwie dgvPomoc), tworzy instancje klasy CProdukty i dodaje je do kolekcji elementów kombo cboProdukty. Dodatkowo utworzony obiekt dodawany jest do kolekcji, przy czym kluczem jest numer pozycji (podany jako string). Private Sub frmSprzedaz_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Load ' deklaracja prywatnych zmiennych procedury Dim w As CProdukty, i As Integer ' przeglądamy rekordy dgvPomoc, tworzymy obiekty klasy CProdukt, ' dodajemy je do cboProdukty oraz do kolekcji With Me.dgvPomoc For i = 0 To Me.dgvPomoc.RowCount - 1 w = New CProdukty(CInt(.Rows(i).Cells(0).Value), _ .Rows(i).Cells(1).Value, .Rows(i).Cells(3).Value, _ .Rows(i).Cells(4).Value, .Rows(i).Cells(2).Value) ' dodajemy element do cboProdukty Me.cboProdukty.Items.Add(w) ' dodajemy element do kolekcji z kluczem od "0" do "n-1" jgKol.Add(w, i.ToString) Next End With w = Nothing End Sub 10 Sposób odebrania informacji wybranej w polu kombo, do którego dodano elementy będące instancjami pewnej klasy demonstruje procedura obsługująca zdarzenie SelectedIndexChange formantu cboProdukty. Procedura uzależnia swoje działanie od tego, czy zmienna publiczna bFlaga jest prawdą, jeżeli nie, to kończy swoje działanie. Własciwość SelectedItem formantu cboProdukty zwraca informację wybraną w polu kombi, ale aby można było z niej wydzielić potrzebne informacje to musimy ją skonwertować na typ CProdukty (bo takie obiekty były dodawane do tego formantu). Zadanie to realizuje funkcja CType. Z formantu cboProdukty dany obiekt (produkt) może być usunięty, dlatego do ustalenie jego pierwotnego indeksu (położenia) w kolekcji wykorzystywany jest pomocniczy grid dgvPomoc i prywatna funkcja UstalIndex. Po ustaleniu indeksu z kolekcji (instancji klasy CProdukty) pobierany jest odpowiedni element, z którego odczytywana jest informacja o liczbie (dostępnych) opakowań danego produktu (korzystamy z właściwości IleJest). Jest ona przypisywana do właściwości Maximum formantu typu NumericUpDown o nazwie nupIle. Private Sub cboProdukty_SelectedIndexChanged(ByVal sender _ As Object, _ByVal e As System.EventArgs) _ Handles cboProdukty.SelectedIndexChanged ' jeżeli bFlaga=False to wyjdź z procedury If Not bFlaga Then Exit Sub 'deklaracja zmiennych prywatnych procedury Dim w As New CProdukty, ip As Integer ' do obiektu w przypisujemy wybraną pozycję w cboProdukty, ' funkcja CType konwertują ją na typ CProdukty w = CType(Me.cboProdukty.SelectedItem, CProdukty) ' prywatna funkcja UstalIndex ustala, jaki jest indeks wybranego ' produktu w dgvPomoc ip = UstalIndex(w.Produkt) ' zmienna klasy przyjmuje cenę wybranego produktu cena = w.Cena ' deklarujemy obiekt CProdukty i przypisujemy mu element kolekcji ' wskazany kluczem ip.ToString Dim u As CProdukty = jgKol.Item(ip.ToString) ' blokujemy możliwość obsługi zdarzenia SelectedValueChange ' formantu nupIle bFlaga = False With Me.nupIle .Minimum = 1 .Maximum = u.IleJest .Increment = 1 .Value = .Minimum ' funkcja KwotaPolska wypisuje kwotę uzupełnioną o symbol zł Me.txtNetto.Text = KwotaPolska((.Value * cena).ToString) End With 11 ' odblokowujemy możliwość obsługi zdarzenia SelectedValueChange ' formantu nupIle bFlaga = True End Sub