Lab1 Ανάπτυξη απλής εφαρµογής. Solutions, Projects, GUI, Events, Debugging. Έργα : *.vbproj (1 έργο - project) Λύση : *.sol (πολλά έργα -solution) Περιβάλλον Controls Κάθε control/στοιχείο έχει ιδιότητες (ορατές / αόρατες) ορισµένη στο χρόνο σχεδίασης µέσα στο κώδικα ώστε να γίνει ενώ το πρόγραµµα εκτελείται ιαδικασίες Οι εντολές είναι συγκεντρωµένες σε διαδικασίες π.χ. subroutines. Οι διαδικασίες εκτελούνται όταν λάβουν χώρα κάποια συµβάντα /events π.χ. το πάτηµα ενός κουµπιού. Eκτελέσιµο αρχείο *.exe debug build αυτόµατα στο bin/debug release build βελτιωµένα στο bin/release Τυχαίοι αριθµοί µεταξύ του 0..9 Label1.Text = CStr (Int (Rnd() * 10) ) Rnd() -> τυχαίος αριθµός µεταξύ του 0 και του 1 Ετοιµη Φόρµα µηνύµατος MsgBox ΚουµπίπουΠατήθηκε = MsgBox(Μήνυµα, Κουµπιά, Τίτλος) MsgBox("Your points are:" & CStr(Counter7),, "GameOver") Lab2 Ανάπτυξη user control. Χρήση διαφόρων control & libraries Eπιλογή τύπου project από το template Windows Form Control Library. Πρόσθεση standard controls στο UserControl1. π.χ. στο UserControl1 µπορεί να τοποθετηθεί ένα Textbox: Για πρόσθεση λειτουργικότητας στο UserControl1 επέµβαση στην Public κλάση του π.χ. µε επιλογή από τα events του Τextbox1 για τα συµβάντα enter και leave Public Class UserControl1 Private Sub TextBox1_Enter(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles TextBox1.Enter Me.BackColor = Color.Cyan Private Sub TextBox1_Leave(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles TextBox1.Leave Me.BackColor = Color.White End Class
Eλεγχος του UserControl προσθέτοντας νέo Project στην υπάρχουσα λύση: File/Add New Project /Windows form Application και επιλογή της φόρµας (Form1) του νέου project σαν Startup φόρµας αλλά και του Project as Startup Project. Βuild το UserControl1- To build process θα δηµιουργήσει ένα DLL αρχείο. Το UserControl1 συµπεριλήφθη µέσα στο Toolbox και εποµένως µπορεί να µπει πάνω στην φόρµ µα Form1 (Eπέµβαση στην partial κλάση του UserControl (αρχείο UserControl1.Designer.vb) Αν π.χ. στο UserControl1 σχεδιαστεί ένα Textbox: Partial Class UserControl1 Inherits System.Windows..Forms.UserControl =>ΑΛΛΑΓΗ σε Inherits System.Windows.Forms.Textbox ιαγραφή των σχετικών µε Αutosize εντολών.) Μπορούν να προστεθούν και νέες ιδιότητες επέµβαση στην Public κλάση του π.χ. ME ΕΞΙ ΚΛΙΚ (Insert Snippet) MΠΑΙΝΟΥΝ ΕΤΟΙΜΑ Patterns Στην public κλάση µπορούν να δηλωθούν µεταβλητές, ιδιότητες, ρουτίνες κ.α.. Όταν αλλάζει ο κώδικας του control πρέπει να γίνει πάλι build. Μια νέα ιδιότητα µπαίνει στο Properties Windows του control στην κατηγορία MISC (αλλά µπορεί και να αλλαχθεί η κατηγορία). Lab3 Resources organization. Database Programming ΜDI φόρµα Μέσα σε ένα project ( *.vbproj) µπορώ να προσθέσω µια ή περισσότερες νέες φόρµες(*.vb) από το επιθυµητό template. Αυτό µπορεί να γίνει από τον Solution Explorer µε κλικ στο όνοµα του Project και Add/Windows Form. Μια από αυτές τις φόρµες θα είναι η πρώτη του έργου (Startup form). Αυτό µπορεί να γίνει και από τον Solution Explorer µε κλικ στο όνοµα του Project και Properties/Application/StartupForm. Το template µιας φόρµας µπορεί να είναι π.χ. (Common Items/) Windows Application Form Mdi Parent Form Control κ.α. H Mdi φόρµα έχει την ιδιότητα ΙsMdiContainer true και έχει και ένα έτοιµο MenuStrip, που µπορεί να αλλαχθεί µε το βελάκι: smart-tag glyph ( )) -στα περισσότερα control υπάρχει αυτό το βελάκι. Με το που φορτώνεται η MDIparent φόρµα µπορούν να τις ανατεθούν τα παιδιά της πχ.
Form1.MdiParent = Me Form2.MdiParent = Me... (αν Form, Form2 είναι Children) Σύνδεση µε βάση Αccess Για να χρησιµοποιήσουµε µια υπάρχουσα Αccess Βάση εδοµένων στο πρόγραµµά µας µπορούµε να προσθέσουµε ένα dataset µέσω του µενού Data / Add New Data Source και µέσω Wizard στην επιλογή Νew Connection να δώσουµε το path που βρίσκεται η βάση (να το τεστάρουµε) και αν θέλουµε να την αντιγράψουµε και µέσα στο project µας. Στο dataset επιλέγουµε τους επιθυµητούς πίνακες και τα πεδία που θέλουµε να έχουµε. Στο dataset.xsd φαίνεται το σχήµα που επιλέξαµε µε τους πίνακες τα πεδία τους και τις σχέσεις µεταξύ τους. Σε µια φόρµα τώρα µπορούµε να βάλουµε ένα πίνακα του dataset (από το παράθυρο Data Sources) είτε σε Details είτε σε DataGridView. Επιλέγουµε συνήθως το Details. Oταν όµως έχουµε δυο πίνακες που συνδέονται, τον πρώτο πίνακα-master- σε Details τον δεύτερο πίνακα-details- σε DataGridView). Όταν ένας πίνακας π.χ. Categories µπει πάνω σε µια φόρµα στο Components tray θα δηµιουργηθούν τα ακόλουθα components: CategoriesBindingSource CategoriesTableAdapter NorthwindDataSet TableAdapterManager ProductsBindingNavigator Όταν ένας δεύτερος πίνακας π.χ. Products µπει πάνω σε µια φόρµα στο Components tray θα δηµιουργηθούν µόνο τα: ProductsBindingSource ProductsTableAdapter Αν θέλουµε οι δυο πίνακες να συνδέονται θα πρέπει ο δεύτερος πίνακας να επιλεχθεί από την συλλογή του πρώτου (αυτό είναι ουσιαστικά το πεδίο που τους ενώνει) Η εντολή που µπορεί να εκτελεστεί µε το που φορτώνεται µια φόρµα, είναι να γεµίσουν (Fill) τα πεδία των πινάκων της φόρµας π.χ. Me.CategoriesTableAdapter.Fill(Me.NorthwindDataSet.Categories) Me.ProductsTableAdapter.Fill(Me.NorthwindDataSet.Products) Πρώτα ο master και µετά ο detail πίνακας
Lab4 Database Programming PostgreSQL Για να συνδέουµε µια PostgreSQlL Βάση εδοµένων στο πρόγραµµά µας, πρέπει να εγκαταστήσουµε τα: pgadmin3-1.8.4 (pgadmin3.msi) psqlodbc_09_00_0101.zip (psqlodbc.msi) createnorth (create.sql σκριπτάκι που δηµιουργεί την Νorthwind στην PostgreSQL & triggers.sql) Κατόπιν στο Αdd New Data Sources/Database/Dataset/New Connection στο DataSource επιλέξτε Change για να αλλάξτε από την Microsoft Access (που είχατε) σε ΟDBC έτσι επιλέξτε Μicrosoft ODBC Data Source. Στο DatαSource Specification /Use user or system data source επιλέξτε PostgreSQL35W και ελέγξτε την σύνδεση σας µε Τest Connection. Επιλέξτε τον DataSet Designer. Παρατηρήστε ότι δεν υπάρχουν οι σχέσεις µεταξύ των πινάκων και βάλτε τις (επιλέγοντας τα επιθυµητό πεδία και σύροντας το ποντίκι ή µε Αdd/Relation). O adapter του πίνακα π.χ. Categories γεµίζει fill- τον πίνακα µε µια query της µορφής SELECT CategoryID, CategoryName, Description FROM ade504.categories Εστω ότι θέλουµε να γίνει αναζήτηση κατηγορίας µε κριτήρια παραµετρικά (που δίνονται από τον χρήστη). Θα φτιάξουµε µια query έστω FillByCompanyName SELECT CategoryID, CategoryName, Description FROM ade504.categories ( WHERE CategoryName LIKE?) Το κτίσιµο της νέας query γίνεται στον adapter µε add/query Κάθε νέα query εµφανίζεται στο σχήµα στο κουτί του adapter κάτω από την query Fill. Η προεπειλεχθείσα Fill µπορεί να αλλαχθεί όταν φορτώνεται η φόρµα µε την FillByCompanyName ώστε να δώσει όλες τις κατηγορίες που στο όνοµα περιέχουν π.χ. ένα γράµµα έστω το e Me.CategoriesTableAdapter.FillByCompanyName(Me.Adelab5DataSet.Categories, "%e%") Στο σχήµα µπορεί να προστεθεί νέος TableAdapter (µε δεξί κλικ) και εποµένως νέος πίνακας στο dataset µας. Lab5 Data Validation FORM LEVEL VALIDATION - DATA LEVEL VALIDATION - σε επίπεδο φόρμας σε επίπεδο dataset Validation σε επίπεδο φόρµας. O έλεγχος σωστής εισαγωγής σε ένα Textbox1 γίνεται με το event Validating:
Private Sub ΤextBox1_Validating( ByVal sender As Object,ByVal e As _ System.ComponentModel.CancelEventArgs) Handles TextBox1.Validating If ΤextBox1.Text = String.Empty OrElse Not Decimal.TryParse(ΤextBox1.Text, 0D) Then 0Decimal MessageBox.Show("Please enter a price", "Products", MessageBoxButtons.OK, MessageBoxIcon.Error) e.cancel = True Return If Convert.ToDecimal(ΤextBox1.Text) <= 0 Then MessageBox.Show("Price must be higher than 0", "Products", MessageBoxButtons.OK, MessageBoxIcon.Error) e.cancel = True Έλεγχος σωστών δεδομένων σε μια φόρμα με το event FormClosing για την περίπτωση που κλείνουμε την φόρμα χωρίς να πατηθεί το SAVE. Private Sub Form1_FormClosing(ByVal sender As System.Object, ByVal e As _ System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing If ValidateData() Then If Me.NorthwindDataSet.Products.GetChanges IsNot Nothing Then Dim response As Integer response =MessageBox.Show("Do you want to save your changes?", _ "Changes have been made", MessageBoxButtons.YesNoCancel, _ MessageBoxIcon.Warning) If response = DialogResult.Yes Then If SaveChanges() Then MessageBox.Show("Your changes were saved", "Products", _ MessageBoxButtons.OK) Else e.cancel = True ElseIf response = DialogResult.Cancel Then e.cancel = True Private Function ValidateData() As Boolean If Me.Validate() Then Try Me.ProductsBindingSource.EndEdit() Return True Catch ex As Exception If MessageBox.Show("Invalid data was entered. Cancel edits?", _,MessageBoxButtons.YesNo,MessageBoxIcon.Error) = _ DialogResult.Yes Then ProductsBindingSource.CancelEdit() End Try End Function
Private Function SaveChanges() As Boolean If ValidateData() Then If ReorderLevelTextBox.Text <> String.Empty Then If Convert.ToDecimal(UnitPriceTextBox.Text) > 25 And _ Convert.ToInt32(ReorderLevelTextBox.Text) > 100 Then MessageBox.Show("Products that cost more than $25 " & _ "must have a reorder level below 100","Products", _ MessageBoxButtons.OK,MessageBoxIcon.Information) Me.TableAdapterManager.UpdateAll( Me.NorthwindDataSet) Return True End Function Το Validation σε επίπεδο DATASET, γίνεται χρησιµοποιώντας τα events των DataTables TableNewRow, ColumnChanging - RowChanging και βάζοντας τον ΕrrorProvider πάνω στην φόρµα Partial Class NorthwindDataSet Partial Class ProductsDataTable Private Sub ProductsDataTable_ColumnChanging(ByVal sender As Object, ByVal e As System.Data.DataColumnChangeEventArgs) Handles Me.ColumnChanging If e.column.columnname = "UnitPrice" Then If Convert.ToDecimal(e.ProposedValue) <= 0 Then e.row.setcolumnerror(e.column, _ "Please enter a price greater than $0.") Else e.row.setcolumnerror(e.column, String.Empty) Private Sub ProductsDataTable_ProductsRowChanging( ByVal sender As Object, ByVal e As ProductsRowChangeEvent) Handles Me.ProductsRowChanging If e.row.rowstate <> DataRowState.Deleted Then If e.row.unitprice > 25 And e.row.reorderlevel > 100 Then e.row.rowerror ="Products that cost more than $25 must " & "have a reorder level below 100" Else e.row.clearerrors() Private Sub ProductsDataTable_TableNewRow(ByVal sender As Object,
ByVal e As System.Data.DataTableNewRowEventArgs) Handles Me.TableNewRow End Class Dim productrow As NorthwindDataSet.ProductsRow = _ CType(e.Row, NorthwindDataSet.ProductsRow) productrow.discontinued = False Κάθε πίνακας έχει την ΗasErrors property. Κάθε γραµµή- εγγραφή ενός πίνακα έχει την RowError property. Private Function DataHasErrors() As Boolean Dim errorstring As New System.Text.StringBuilder If Me.NorthwindDataSet.Products.HasErrors Then For Each row As DataRow In Me.NorthwindDataSet.Products If row.haserrors Then errorstring.append(row.rowerror & vbcrlf) Next MessageBox.Show( "The following errors occurred: " & vbcrlf & vbcrlf & errorstring.tostring,"products", MessageBoxButtons.OK, MessageBoxIcon.Error) Return True End Function Private Function SaveChanges() As Boolean If ValidateData() Then If Not DataHasErrors() Then Me.TableAdapterManager.UpdateAll( Me.NorthwindDataSet) Return True End Function Ο αρχικός κώδικας του Save button µε τις τρεις µεθόδους: Validate, EndEdit και UpdateAll, θα αντικατασταθεί µε την function SaveChanges: Private Sub ProductsBindingNavigatorSaveItem_Click(ByVal sender As _ System.Object,ByVal e As System.EventArgs) Handles _ ProductsBindingNavigatorSaveItem.Click If SaveChanges() Then MessageBox.Show("Your changes were saved", "Products", MessageBoxButtons.OK)
Lab6 Project Properties / Publishing the application Lab7 Namespaces (My.Application, My.Computer, others) Lab8 Files and Folders Lab9 Threads