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