Kap 1.1 Interakt. grafiska gränssnitt

Transcription

Kap 1.1 Interakt. grafiska gränssnitt
Kapitel 1
Windowsprogrammering
1.1
Interaktiva grafiska gränssnitt
‐ Controls
‐ Händelsemetoder
1.2
TextBoxar, Buttons & Labels
1.3
Checkboxar och radioknappar
1.4
Färgtest med kontrollen HscrollBar
1.5
Geometriska figurer
1.6
Bågar och vinklar
1.7
En räntekalkylator med multiline TextBox
1.8
Gränssnitt mot Internet
‐ En första webbläsare
‐ En mer utvecklad webbläsare
‐ Dialogrutan Navigate
‐ Menyn Navigate
1.9
Listboxar
1.10 Gränssnitt mot kalendern
1.11 Grafiskt gränssnitt med menyval
1.12 Multiple Document Interface
Övningar till kapitel 1
9
10
11
15
16
18
22
26
29
31
35
43
39
40
42
45
47
49
53
57
Interaction
PassWdTextBox
Bartender
FärgTest
Rita
Bågar
Räntekalkylator
MyFirstBrowser
DevBrowser
ListBoxar
Leveransdatum
Menyer
MDI
1.1 Interaktiva grafiska gränssnitt
Windowsprogrammering är nästan synonym med det vi i Programmering 1 kallade Visuell programmering och innebär att utveckla program som involverar både text och
grafik samt producerar fönster och dialogrutor av olika slag. Dessutom ska användaren
kunna kommunicera med sådana program via ett grafiskt gränssnitt som man bygger
både med förprogrammerade komponenter som finns i Visual Studio och med egen C#kod. Så detta kapitel är en direkt fortsättning och samtidigt en fördjupning på Windows
Forms Applications som introducerades i Programmering 1 (Progr1, 3).
Ett grafiskt gränssnitt är en yta som vi kan använda för att kommunicera med programmet när det körs. Och detta i båda riktningar, från användaren till programmet och tvärtom. Det är en slags användarvänlig mellanskikt (gräns) mellan användaren och den icke-användarvänliga koden. För att kunna kommunicera måste vi väcka de grafiska komponenterna till liv och interagera med dem, när applikationen körs, vilket kräver att vi
förser dem med egenskriven kod och/eller med komponenter som är förprogrammerade
i Visual Studio. I regel ingår i sådana program mer grafik än kod. En konsekvens av
denna nya form av program blir att körningen till skillnad från konsolapplikationer inte
längre till 100% är förbestämd av utvecklarens kod utan kan även styras – åtminstone
delvis – av användaren under programmets körning genom musklickningar och tangenttryckningar, s.k. händelser. Även andra typer av händelser är tänkbara. Därför pratar
man om händelsestyrd programmering. Händelser som initieras av programmets användare, påverkar både programförloppet och avslutningen i en mycket större utsträckning
än det är möjligt med rent textbaserade program, s.k. Console Applications (Progr1, 2.4).
I detta avsnitt vill vi bygga en Windows Forms Application som reagerar på musklickning och sedan visar ett meddelande i ett separat fönster. Närmare bestämt ska den göra
det, varje gång man klickar på en knapp, en s.k. Button, i applikationens grafiska yta,
det s.k. formfönstret, kort kallat formen. Nedan visas applikationens körresultat. Sedan
ska vi gå in på hur man bygger den:
10
Fördelen med att visa körresultatet först är att man får klart för sig vad man ska jobba
mot. Förfarandet kan inspirera oss att alltid först rita en slags utkast av det vi vill ha ut
från programmet. Denna ritning kan tjäna som en modell för att sedan utveckla en plan
för programmeringen. Detta är jämförbart med att beskriva en algoritm med flödesplan
som behandlades i Progr1, kap 1. I implementeringsfasen kan modellen användas för att
strukturera upplägget och skriva koden.
I vårt exempel ska applikationen producera två fönster, se förra sidan: Till vänster har vi
formfönstret, som i sin tur innehåller en knapp med texten Detta är en Button, som man
kan klicka på för att få en s.k. MessageBox. Den kompletta bilden uppstår endast om
man klickar på knappen. Annars kommer bara formfönstret till vänster att visas, men inte MessageBoxen till höger. Här ser man att körningen till skillnad från konsolapplikationer inte längre till 100% bestäms av utvecklarens kod utan även delvis av användarens aktion – just det vi kallade händelsestyrd programmering (sid 10): Klickar man inte
på knappen visas bara ett fönster. Klickar man, får man båda fönster.
Controls
Knappen som nämndes ovan är en s.k. Control i Visual Studio. Den ingår i en stor grupp
av återanvändbara grafiska komponenter i verktygslådan Toolbox. Vi kommer i fortsättningen även att använda det svenska ordet kontroll. Ett exempel en på sådan Control är
Button – en klickbar knapp som finns i Toolbox och som man med musen kan placera i
formfönstret. MessageBox däremot är ingen Control och kan inte heller konstrueras
visuellt med musen. För att få fram den måste vi skriva kod ”bakom” Button och lägga
den i applikationen. Vilken kod och framför allt var någonstans den måste skrivas samt i
vilken kontext den ska läggas, ska vi gå igenom nu.
Till skillnad från konsolapplikationer skapar vi för varje program ett nytt projekt av typ
Windows Forms Application med val av rätt alternativ i dialogrutan New Project:
11
Starta Visual Studio och klicka på länken New Project … i Start Page:s vänstra kolumn
för att få fram dialogrutan på förra sidan. Döp det nya projektet till Interaction under
Name och spara det i mappen C:\C# under Location. Avbocka den lilla rutan Create directory for solution. Avsluta dialogrutan New Project med OK-knappen. Du får fram en
miljö med bl.a. formfönstret (formen). Markera formen och ändra i Properties-fönstret
formen Form1:s egenskap Text så här: Markera med mus Text-egenskapens defaultvärde
Form1 och ändra det till Interaction. Formens rubriktext ändras till Interaction.
Gå med musen över Toolboxfliken längst till vänster under menyraden eller alternativt:
 View  Toolbox och dubbelklicka under Common Controls på kontrollen Button, så att
den hamnar i formfönstret. Stäng sedan Toolbox-fönstret. Du borde nu få fram följande
utseende på din miljö i Visual Studio:
Markera den nya kontrollen button1 på din form, för att få fram dess egenskaper i Properties-fönstret. Konfigurera (ändra) button1-egenskapernas värden enligt följande:
Egenskap
AutoSize
Text
Font
Location
Värde
True
Detta är en Button
Tahoma; 12pt; style=Bold
56; 45
Även om egenskaperna i Properties-fönstret by default är alfabetiskt ordnade, för att lättare kunna hitta dem, står deras nya värden i tabellen ovan i en ordning i vilken det ur
praktisk synpunkt är rimligt att utföra dem. Men i princip är ordningen inte av betydelse. De tekniska detaljerna i denna konfigurering är ganska liknande de anvisningar som
gavs för konfigurering av formens och Labelns egenskaper i programmet WindowsForm
12
(Progr1, 3.5). Vi upprepar dem inte här, eftersom de ger inget nytt. Har du svårigheter att
utföra dem, är det bäst att du genomför eller rekapitulerar dem i WindowsForm.
Om man i detta läge kör applikationen Interaction får man formfönstret med knappen
som visar texten Detta är en Button. Men när man klickar på knappen händer ingenting,
För att få ut den önskade meddelanderutan, när man klickar, gör så här:
Markera i designläge knappen som texten Detta är en Button står på och dubbelklicka
på den. För första gången får vi in kod i editfönstret. Koden lagras i filen Form1.cs och
är en del av klassen Form1:s deklaration, en klass som beskriver formen. Skriv på det
stället där markören står och blinkar, de tre rader kod som är markerade på denna bild:
Titta på nästa sida om den markerade koden på bilden som du ska lägga in inte är tydlig.
Kompilera med  Build  Build Solution och kör med  Debug  Start Without Debugging
applikationen Interaction. Klicka på knappen i körläget för att få fram detta:
I resten av detta avsnitt förklaras den markerade koden på bilden ovan och den kontext i
vilken den står. Kontexten är den automatiskt genererade koden för klassen Form1 som
13
inte är markerad på bilden. Vi tar fram den för att studera den närmare. Både den automatiskt genererade och den egenskrivna markerade koden, inklusive kommentarerna
står i filen Form1.cs och gås igenom i detalj på de följande sidorna.
// Form1.cs
using System;
using System.Windows.Forms;
namespace Interaction
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
// Namnutrymme
// Form1 ärver Form
// Klassens konstruktor
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show( "Detta är en MessageBox som visas " +
"varje gång man klickar på Button i formen." ,
"MessageBox: Egenvald rubrik" );
}
}
}
Kommentaren på första raden säger att koden lagras i filen Form1.cs. Klassen Form1
deklareras både i denna fil och i filen Form1.Designer.cs, i båda dessa två filer, en del i
den ena, en del i den andra. Det är fullt möjligt i C#: Ordet partial i klasshuvudet antyder att det som står här, är en del av klassen Form1.
I C# är namespace ett reserverat ord som skapar ett namnutrymme, en slags behållare
för klasser. C#:s programbibliotek är organiserat i sådana namnutrymmen som innehåller fördefinierade klasser. De automatiskt genererade klasserna i Visual Studio placeras
också i namnutrymmen som får samma namn som projektet. Därmed blir alla namn i
vårt projekt Interaction tillgängliga via punktnotation först efter behållarens namn.
T.ex. kan man komma åt klassen Form1 endast med Interaction.Form1 osv. Namnutrymmen är ett bra och – i vissa fall – nödvändigt skydd mot namnkonflikter.
De using-direktiven i början inkluderar två namnutrymmen ur C#:s programbibliotek
som behövs för att kompilera denna enkla grafiska applikation. Ursprungligen genererar
Visual Studio sex till using-direktiv som vi tagit bort, för de visar sig vara onödiga.
Klasshuvudet public partial class Form1 : Form säger för det första att koden är
en del av klassdeklarationen, därför partial. För det andra talar det om att klassen
Form1 som vi skapar ärver biblioteksklassen Form, därför : som i C# är koden för arv
(sid 63 & 145). Klassen Form i sin tur är deklarerad i namnutrymmet System.Windows.Forms. Det finns en hel del fördefinierad kod där som behövs för att skapa formfönstret. Alla klasser som skapar formfönstret måste ärva denna fördefinierade kod. Den
del av klassen Form1 som deklareras här, innehåller endast två metoder (sid 61 & 107).
14
Den första är klassens konstruktor Form1() som är en automatisk metod för att initiera
klassen Form1:s egenskaper (sid 63 & 85). Den andra metod i vilken vi lade tre rader
egen kod, heter button1_Click(). Denna kod gör att MessageBoxen visas vid musklickning när man kör programmet. button1_Click() en helt ny typ av metod som
kallas händelsemetod. Sådana metoder förekommer inte i konsolapplikationer utan är ett
verktyg för händelsestyrning och därför typiska för interaktiva grafiska applikationer.
Händelsemetoder
Vanliga metoder deklareras först och anropas sedan. Både deklarationen och anropet
sker med kod. En händelsemetod (eng.: event handler) deklareras också precis som en
vanlig metod, men anropas inte med kod utan genom en s.k. händelse. En händelse är
en aktion som utförs antingen av användaren eller av ett program, vare sig en applikation eller datorns operativsytem. Exempel på en händelse är musklickning. Men även en
tangenttryckning kan vara en händelse. När händelsen inträffar, anropas metoden som är
associerad med händelsen. Metoden button1_Click() är associerad med musklickning på button1, en kontroll av typ Button. Så snart vi skapar en sådan kontroll i formen,
t.ex. button1 (sid 12), genereras kod: Huvudet till metoden button1_Click() i klassen
Form1 (filen Form1.cs). Med dubbelklick på den nya kontrollen (i designläge) får vi
fram denna kod i editfönstret och kan skriva kroppen till metoden. Vi är fria att skriva
där vilken kod som helst, för att få den exekverad när man i körläge klickar på knappen
button1. Eftersom vi vill få ut ett meddelande i ett fönster, skriver vi ett anrop av metoden MessageBox.Show() som vi stiftade bekantskap med tidigare. Händelsemetoden
button1_Click() har två parametrar som vi dock inte använder i kroppen i just denna
applikation. Ändå måste vi ha dem med i metodens huvud, för huvudet är fördefinierat i
superklassen Form och får inte ändras.
Metoden MessageBox.Show()
Till skillnad från button1_Click() är metoden Show() ingen händelsemetod, utan en
vanlig metod, fördefinierad i klassen MessageBox. Därför anropas den med kod, inte
med en händelse (musklickning). Den anropande koden står i händelsemetoden button1_Click(). Musklick på knappen Detta är en Button (i körläge) anropar händelsemetoden och den i sin tur metoden Show(). I den version som används här har metoden MessageBox.Show() två parametrar: Den första står för själva meddelandet som
ska visas i den lilla rutan, den andra för rubriken som ska stå på rutans ram. Att vi i koden med + konkatenerar två strängar på den 1:a parameterplatsen, beror på att meddelandet vi vill skriva ut, inte ryms på en rad i editfönstret resp. på sidan i boken. I koden
är det som vanligt kommat som skiljer åt metodens två parametrar.
Det intressanta med denna metod är att den är användbar både i konsol- och grafiska applikationer. I programmet MessageBox (Progr1, 3) som var en konsolapplikation, hade
vi använt en annan variant av Show() som endast hade en parameter. Att en metod kan
finnas i två (eller flera) varianter, en gång med en, en gång med flera parametrar, är
ganska vanligt i programmering – ett koncept som kallas överlagring av metoder och
behandlas senare (sid 127).
15