Skript

Transcription

Skript
Visuelle Programmierung mit C#
Prof. Dr. Bayerlein
Schritt- für- Schritt Anleitung MS 2010 C#
Prof. Dr. Bayerlein WS 2012/13 Version 4.6 vom 15. Nov. 2012
Inhalt
Literatur .........................................................................................................................................2 Kurs Intro ......................................................................................................................................3 Erste Schritte Programm „Hello World“ ...................................................................................4 Vorbereitungen ......................................................................................................................5 Portieren der exe- Datei auf andere PC ....................................................................................8 Löschen von Komponenten und Source Code ..........................................................................8 Kurs 1 Spiel ...................................................................................................................................9 Zur Transparenz einige Infos: .............................................................................................15 Kurs 2 Rechnen, Multiwindowing ..............................................................................................17 Komma- Problematik ..............................................................................................................19 Mehrere Fenster.......................................................................................................................20 Kurs 3 Professionelles Design.....................................................................................................26 Menüs ......................................................................................................................................26 PopUp-Menüs mit ContextMenuStrip ....................................................................................27 StatusBar mit StatusStrip ........................................................................................................27 Hints mit ToolTips ..................................................................................................................28 Kurs 4 weitere Komponenten ......................................................................................................29 ToolStrip..................................................................................................................................29 TabControl ..............................................................................................................................30 Komponenten zur Gruppierung und Selektion........................................................................32 Kurs5 Textverarbeitung mit Stringlisten ....................................................................................34 Der Typ String .........................................................................................................................34 Der mehrzeilige Text ...............................................................................................................35 Sortieren ..................................................................................................................................38 Leerzeilen weg ........................................................................................................................38 Größe von StringListen ...........................................................................................................39 Wörter zählen ..........................................................................................................................40 Kurs 6 Projekt Diashow ..............................................................................................................41 Projektaufgabe 1 Diashowprogramm ..................................................................................43 Kurs 7 Zeichnen mit dem Graphics - Objekt ..............................................................................44 Das Graphics-Objekt ...............................................................................................................44 Kurs 8 Chart2D ...........................................................................................................................52 Kurs 9 DataTools - Einbinden von Tool- Units ..........................................................................56 Kurs 9a Zeichnen von Kurven mit Chart DotNet 4.0 .................................................................58 Kurs 10 Weitere Komponenten ...................................................................................................59 WebBrowser ............................................................................................................................59 Mediaplayer .............................................................................................................................60 Kurs 11 Email- Programm ..........................................................................................................62 Kurs 12 TreeView .......................................................................................................................62 Kurs 13 Drucken .........................................................................................................................66 Kurs 14 DLL ...............................................................................................................................68 Zusammenfassung AD- DA mit dll für ME2600, USB Orlowski: .........................................72 ME2600 ...............................................................................................................................72 USB- Orlowski – Karte – alte USB 1.1 - Version ..............................................................72 File: Kurs MS10C# Bayerlein4.6.docx
Seite 1
Visuelle Programmierung mit C#
Prof. Dr. Bayerlein
Neue DLL / Klassenbibliothek mit C# erzeugen ....................................................................73 Kurs 15 Zeitmessung und 1ms Timer .........................................................................................74 Kurs 16 RS232 ............................................................................................................................76 Kurs 17 bis 20 entfernt ................................................................................................................79 Kurs 21 DataGridView................................................................................................................79 Kurs 22 C# DirectX.....................................................................................................................82 Kurs 23 MySql und C#................................................................................................................82 Kurs 24 Meilhaus ME 4660 ........................................................................................................83 Kurs 25 NI mit NIDAQmx..........................................................................................................83 Kurs 26 USB- Orlowski 2.0 ........................................................................................................84 Kurs 27 Interface mit TCP/IP......................................................................................................84 WindfC#, mein großes Regelungstechnik- Toolprogramm. ......................................................85 Einige Hinweise ..........................................................................................................................86 Problematik mit Dock .............................................................................................................86 Parameter in Funktionsaufrufen und Arrays ...........................................................................86 Zeilennummern im Editor .......................................................................................................87 Literatur
[1]. Andreas Kühnel. Visual C# 2008 oder neuer. Galileo Computing.
[2]. Jürgen Bayer. Das C# 2008 Codebook oder neuer. Addison Wesley.
[3]. Frank Eller. Visual C# 2008 oder neuer. Addison Wesley.
[4]. Bernhard Volz. Einstieg in Visual C# 2008 oder neuer. Galileo Computing.
File: Kurs MS10C# Bayerlein4.6.docx
Seite 2
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Kurs Intro
Alle Scrreenshots siind mit dem
m MS Studioo 2008 IDE Visual C#, Prof. Versiion in deutscher
Menüveersion auf eiinem Vista-- Laptop auffgenommen
n worden. Aktuell
A
benuutzte Versio
on .NET
3.5 !!
Start deer IDE (Entw
wicklungsum
mgebung) m
mit
Dann inn Datei  Neu
N  Projeekt im folgeenden Bild
Window
ws Forms-A
Anwendung wählen.
gespeichertees Projekt zu
u laden, mu
uss man die Datei *.sln
Um ein angefangennes und abg
w Studio
o 2008 geöfffnet. Nur daann sieht
(„Solutiion“ = Projeektmappe“) doppelklickken. Dann wird
man nocch keine Daatei. Um den
n Form undd den Code – Editor zu öffnen, öffn
fne man mit Menu
„Ansichht“ den „Proojektmappen
n - Explorerr“. Darin kaann man dan
nn entweder
er die Form1
1.cs
anwähleen durch Dooppelklick. Dann sieht man das Fo
ormular. Miit F7 öffnet man dann den
d CodeEditor.
Noch eiin Hinweis zum
z
Editor: er unterstüützt die Blocckbildung von
v Strukturrblöcken z.B
B. von
einer if oder for- Anweisung.
A
Das
D Einrückken wird au
utomatisch durchgeführ
d
rt, so dass durch
d
diese Scchreibweisee das Prograamm besser lesbar wird
d.
if ...c
condition.
...)
{
...
.statement
t...
}
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 3
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Setzt man den Curssor vor einee geschweiffte Klammer „{„ oder hinter
h
eine geschlossen
ne
Klammeer „}“, so werden
w
die beiden
b
zu e inem Block
k gehörigen Klammernn grau eingefärbt und
stehen ddirekt untereeinander. Die
D folgendee oft gesehen
ne Syntax- Form lehnee ich ab:
if ...c
condition.
...){
...statem
ment...
}
Erste Schritte
e Program
mm „Helllo World
d“
Man sieeht dann folgendes Bild
d:
Komponnentenpalettte oder Too
olbox
Eigenscchaften Fensster zur Verränderung vvon Eigenscchaften / Eig
genschaftenn von Komp
ponenten
Leeres F
Formular.
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 4
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Vorbereitungen
n
Zu Begiinn sollte daas Projekt geespeichert und
u ein
Pfad festgelegt werden. Der Naame des Pro
ojektes
wird ansschließend der
d Program
mmname der exeDatei.
Bitte niccht auf ein über
ü Netz anngeschlosseenes
Laufwerrk, sondern immer auf llokaler Festtplatte
arbeiten
n, da z.T. doch große unnd viele Datteien hin
und her geschoben werden.
Bei mir wird in eineem Pfad D:M
MSC#/Kurss 0/
gespeich
hert, der auttomatische N
Name ist
Window
wsApplicatio
on9.
Unit- Soource Code
Alle Deesign- Inform
mationen dees Formularrs
Jetzt kannn die erstee Komponen
nte auf das F
Formular pllatziert werd
den. Dazu m
muss die To
oolbox
geöffnett werden (M
Menü Ansicht Toolboox)
Wir függen einen Laabel und ein
nen Button hhinzu und setzen sie irg
gendwo auff das leere Formular
F
Das Ergebnis:
E
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 5
Visuellee Programm
mierung mit C#
B
Prof. Dr. Bayerlein
Mit dem
m Eigenschaaften Fensteer können nnun Eigenschaften der einzelnen
e
K
Komponenteen
sichtbarr und veränddert werden
n. Im Beispiiel ist der bu
utton1 angew
wählt (Quaddratpunkte als
Objjektmarkieru
ungen) undd wir haben die
Eigenschaft „T
Text“ veränddert auf „Ersster
Tesst“. Z. B. ist Text immer
er die Besch
hriftung
eineer Komponeente, (Namee) der Namee, der CNam
menskonven
ntionen entssprechen mu
uss (z. B.
kein
ne Leer- odeer Sonderzeeichen). Mitt Name
kan
nn die Komp
ponenten im
m C- Sourcee-code
ang
gesprochen werden.
w
Diee ersten wicchtigsten
Eigenscchaften:
Top
op und
Lefft geben diee Pixel- Enttfernung
des obersten llinken Pixells der
Ko
omponente zzu der ConttainerKo
omponente aan (Contain
ner ist
hieer das Form
mular),
Wiidth und
Heeight sind diie Dimensio
onen der
Ko
omponente iin Pixel.
Diese Werte kkönnen allerrdings im
Eig
genschaftenn Fenster niicht direkt
ein
ngegeben w
werden, sond
dern dort
nu
ur über die E
Eigenschafteen Size
un
nd Location.. Im Program
mm
können dabei sowohl übeer Left
usw
w. als auch über Size oder
o
Lo
ocation Werrte veränderrt werden,
es ist Geschm
mackssache.
Selbstverständdlich werdeen auch
dies e Werte soffort verändeert, wenn ma
man per Mau
us mit
„Annfassen“ derr Komponen
nte die Lagee oder Größ
ße in
gew
wohnter Weiise verstellt.. Die Wertee werden dan
nn
autoomatisch akttualisiert.
Nocch ist keine einzige
e
Zeille C eingegeeben wordeen. Dies
gescchieht jetzt.
Gew
wünschte Fu
unktion: bei Druck auf die Taste so
oll im
Labeel- Text derr Schriftzug „Hello Woorld“ erscheeinen.
Allee Funktionen
n der Prograamme werdden über Ereeignisse
(Eveents) gesteu
uert. Jede Ko
omponente hat eine Lisste von
mögglichen Ereiignissen, diee in dem Eiggenschaften
n- Fenster
angeesprochen werden
w
könn
nen. Wir beenötigen den
n ClickEreiignis von bu
utton1. Man
n erzeugt auutomatisch eine
e
Ereigniss- Behandluungs- Funkttion durch D
Doppelklick
k auf den reechten Eintrrag neben deem Event:
Symboll für die Ereeignisse- Seite
Doppelkklick
Es öffneet sich der Editor
E
für deen C#- Sourrce- Code und
u man kan
nn jetzt denn C#- Sourcee
eingebeen, der ablauufen soll, wenn der Useer später im
m laufenden Programm auf die Taste klickt.
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 6
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Wir gebben folgenden rot umraandeten Texxt ein:
Nun kannn das erstee Programm
m kompiliertt werden, en
ntweder
mit F5 ooder mit Kliick auf
oder über Menü:
Das Prograamm wird neu
n
abgespeichhert, kompiliert,
gelinkt undd anschließend
gestartet. M
Man erhält
letztendlicch folgendess
Ergebnis:
Vor Kliick:
Nach
N
Klick
M
Es sindd nun eine Menge
neuer D
Dateien auff der
Festplaatte gelandeet:
Die exxe ist jetzt daas
ausfühhrbare Progrramm,
wohl loogo.
Die andderen Dateieen enthalten
n weitere Proojektinfos, welche, spielt hier erstt mal keine Rolle.
X
gescchlossen werden.
Das Prrogramm soollte normall über die X-Taste
Niemaals über denn Task- Man
nager, denn dann komm
mt die IDE
(Interg
grated Deveelopment En
nviroment) von
v C# durc
rcheinander und muss
neu geestartet werdden.
Bei En
ndlosschleiffen, die vom
m IDE gestaartet werdenn, ist ein Abbruch mit
Shift + F
F5 oder übber Menü Deebuggen/Deebugging beeenden mög
glich.
Noch eiin paar Tippps zum Zureechtfinden:
Öffnen des Source-- Codes mitt Menü Ansiicht  Cod
de (F7)
Öffnen des Form- Designers
D
mit
m Menü Annsicht Deesigner (Shiift+F7)
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 7
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Öffnen der Toolboxx mit den Komponente
K
en: Ansicht  Toolbox
x (Strg+w, ddann x)
Öffnen des Eigenscchaftenfenstters mit Annsicht  Eig
genschaften
nfenster (Strrg+w, dann p)
Portie
eren der exe- Dattei auf a ndere PC
C
Die Dattei erwartet einige DLL
L und die .N
Net- Umgebung auf dem
m Zielrechnner, die sie auf
a einem
andern P
PC ohne .N
Net nicht find
det. Will maan sein Prog
gramm anderen Usern ohne C# zu
ur
Verfüguung stellen, so muss maan alle Dateeien des Verrzeichnissess „bin“ kopiiert mitliefeern und
.Net. fallls auf Zielrrechner nich
ht vorhandeen als Redisttributable (k
kostenlos voon MS) mitt liefern.
Lösch
hen von Kompon
nenten un
nd Sourc
ce Code
Will maan Komponenten löschen, so ist ess einfach: Markieren
M
un
nd Taste „E
Entf“ / „Del““. Nur:
Hat mann Event – Source für diiese Kompoonenten geschrieben, bleiben diesee erhalten und
u man
hat totenn Source in seinem Pro
ogramm, deer nie wieder benutzt wird. Hat maan Programm
mtext
geschrieeben, der auuf Eigenschaften dieserr Komponen
nten zugreifft, dann wirrd es beim
Kompilieren Fehlermeldungen
n geben.
Also am
m Besten: Errst alle Verw
weise auf diiese Kompo
onente lösch
hen, dann allle Event- functions
fu
leeren, ddann erst diie Komponeente entfernnen.
Achtungg : Niemals Source löschen, den ddie IDE auto
omatisch erzzeugt hat. N
Nur Ihren Teext, den
Sie einggegeben habben löschen, sonst wirdd es schwierrig.
Also: inn obigem Prrogramm nu
ur die Zeile
Label1-->Caption=
="Hello Worrld";
löschenn, sonst nichhts mehr!
k
geelöscht habeen, erscheint nach F5
Wenn ees nun doch passiert ist und Sie diee Funktion komplett
folg
gende linke Fehlermeld
dung.
Jetzzt mit Strg+
+z (Undo) deen
gelö
öschten Texxt wiederholen und
nur Ihren Text löschen.
muss erst im
m
Diee function m
Eigenschaftenffenster im Event
E
Clicck entfernt w
werden, z. B.
B durch
u dann Reeset wählen.
rechten Mausklick auf Click und
a
OK.
Danach ist wieder alles
Ü
Jetzt nooch ein paar einfache Übungen:
Veerändern vo
on Lage
unnd Position des
Buuttons per Programm
P
übber Top / Lef
eft usw.
Das Gleeiche über Size
S und Loccation, der C
Code wird etwas
e
komp
plizierter:
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 8
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Man kannn jetzt sehhr gut die heervorragendde Unterstützzung mit deem „Code C
Completion Window“
nutzen. Jedes Mal, wenn man Code eingibbt, dann weerden intelligente Vorscchläge gemacht, die
dann miit den Tasteen Up/down
n selektiert uund mit der Return-Tasste ausgewäählt werden können.
Gibt maan in dieser Eventfuncttion/Ereigniisfunktion die
d neue Zeile
label1.
.Text = bu
utton1.Siz
ze.Height.
.ToString
g();
ein, so bbraucht mann nur einen Buchstabenn eingeben und
u schon erhält
e
man ssinnvoll Vorschläge.
Z.B
B. Nach Ein
ngabe von „ll“ sieht man
n linkes
Billd. Nur durcch Taste „Re
Return“ wähllt man
jetzzt label1 aus. Nach dem
m Punkt sieh
ht man
dan
nn den näch
hsten Vorschhlag usw.
Kurs 1 Spiell
In dieseem Kurs soll gezeigt weerden, wie eeinfach und
d schnell und
d mit wie w
wenig echtem
m C#Code scchon funktioonierende Programme
P
ggeschrieben
n werden kö
önnen.
Wir schhließen alless Vorherige und startenn eine neue Applikation
A
n (DateiN
NeuProjekkt), dann
Geben w
wir folgende Daten im Fenster “N
Neues Projek
kt“ ein
und wähhlen Window
ws Forms-A
Anwendungg. Dann wird
d alles
in dem V
Verzeichniss C:\Kurs1 Game gesppeichert.
Jetzt braauchen wir 2 Bilder, diie vom ftp--server gelad
den
und aucch dort auf die
d Festplattte kopiert w
werden sollteen. Es
können selbstverstäändlich auch
h eigene Biilder sein, ab
ber
nicht allle Formate arbeiten korrrekt. Hinteergrundbild::
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 9
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Blumen.JPG aus meinem
m
FTP
P- Verzeichnnis MS Stud
dio2008 C#//Kurs1# Spiiel und das
Mohrhuuhn grHuhnn5 echt.bmp.
Wer sicch das fertigge Spiel vorh
her mal anssehen und au
usprobieren
n möchte, deer lade sich die Datei
Window
wsApplicatioon1.exe aus dem VerzeeichnisWind
dowsApplica
ation1/bin/D
Debug vom Server
und starrte es. Man kann jetzt nach
n
Taste „„Start“ versuchen, auf das
d sich bew
wegende Moorhuhn
M
zu klickken. Die Treeffer und diee Fehlversuuche werden
n gezählt. Die Zeit zwisschen zwei
Beweguungen und die
d Größe dees Moorhuhhnes können
n verstellt werden.
w
Dieses S
Spiel wollenn wir jetzt programmie
p
eren. Dazu brauchen
b
wiir einige Koomponenten
n, die wir
auf das leere Formuular ziehen::
Erstt zwei Kom
mponenten P
PictureBox von
v der
Seitte Allgemeiine Steuerellemente.
picttureBox1 so
oll das Hinteergrundbild
d werden,
wir aktivieren die
d Eigenscchaft Imagee im
Objjektinspekto
or durch Kliicken auf diie Taste
mit den drei Pu
unkten und kkönnen nun
n unser
Bild
d Blumen.JP
PG mit „Lok
okale Ressou
urce“ und
Imp
portieren lad
den.
Nach Laaden sehen wir in der
Komponnente einenn Ausschnittt des geladeenen Bildes.. Erst ganz zum
z Schlus s wollen wiir dieses
Bild untter das ganzze komplette Formular legen.
Die
D zweite piictureBox2 füllen wir mit
m dem
Moorhuhn.
M
Wenn
W
es nacch dem ersteen Bild
au
uf das Form
mular gezogeen wurde, dann
d
liegt
ess über dem ersten
e
Bild..
Man
M kann diee Reihenfollge aber in dem
d
Po
opUp-Menu
u jeder Kom
mponente leicht
veerändern:
Dort
D kann maan „In den V
Vordergrun
nd“ oder
„IIn den Hinteergrund“ wä
wählen. Das
Moorhuhn
M
muss
m vor dem
m Hintergru
undbild
liegen.
Soll dass Bild die piictureBox vollkommenn ausfüllen, so setzt man
n die Eigennschaften SizzeMode
auf StreechImage. Den
D gleichen
n Effekt erhhält man, weenn man auf den kleineen Pfeil obeen rechts
in der P
PictureBox klickt
k
und dann
d
die SizzeMode/Grö
ößenmodus entsprechennd wählt.
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 10
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Übrigenns können Eigenschafte
E
en der Sortee Bool mit einem Dopp
pelklick auff true oder false
f
in
die jeweeils andere Eigenschaft
E
t geschaltet werden.
Will maan jetzt das Hintergrund
dbild formaatfüllend in der Form darstellen, auuch dort diee
SizeModde auf StrecchImage steellen und diee Dock- Pro
operty auf „F
Fill“ stellenn.
Soll dass Programm
m den Bildscchirm kompplett füllen, dann setzt man
m in der FForm die Eiigenschaft
Window
wsState auf Maximized.
M
Diese Voreeinstellungeen kann man
n auch proggrammieren
n, das
sieht daann so aus:
Hinter ppublic Form
m1() kann man
m Initialisiierungen du
urchführen, jedoch kannn man die Form
F
erst
auf Maxximized stelllen, wenn sie
s aktiviert ist. Die Ereeignisfunktion Form1_A
_Activated erzeugt
e
man durrch Markierren von Forrm1, selekti eren der Ev
vents im Pro
operty Manaager und daann
Doppelkklick hinterr Activated. Jetzt füllt ddas Bild mit den Blumeen allerdingss noch nicht die
volle Foorm aus, da es noch niccht „gestrechhed“ wurdee. Also auch
h in PictureB
Box1 die SiizeMode
anpasseen.
Jetzt weerden noch benötigt:
b
2 Labels, Transparrent geht no
och nicht, Foont-Eigenscchaft nach Geschmack
G
(ich mag
ComicS
SansMS), Scchriftgröße auf 14pt. Scchriftfarbe Rot
R stellt man
m in der E
Eigenschaft
ForeCoolor
ein. Diee gleichzeitiige Verändeerung von E
Eigenschafteen von mehrreren Kompponenten geeht, wenn
man diee Komponennten gemein
nsam anwähhlt. Die Anffasspunkte werden
w
dann
nn grau. Dass
gemeinssame Anwäählen geht mit
m z. B. geddrückter Shiift- Taste od
der mit andeeren Windo
owstypischeen Wegen. Den
D Text au
uf Hits=0 unnd Misses=
=0 in Eigenschaft Text ändern.
Weiter 2 Buttons, eine
e Name=
=buttonStartt, Text=Starrt, die anderre Taste Naame=buttonStop,
Text=Sttop.
Dann brrauchen wirr zwei Verstteller für Zaahlen, zu fin
nden in Allg
gemeine Steeuerelementte, dort
NumericcUpDown. Den voreingestellten W
Wert von Nu
umericUpDown1 in Vaalue auf 100
00 ändern.
Das gehht auf Anhieeb nicht, da der Maxim
malwert in Maximum
M
au
uf 100 steht.. Den also erst
e auf
2000 unnd dann Vallue auf 1000
0 und Increm
ment auf 10
00. Und den
n Value vonn NumericU
UpDown2
auf 100 verstellen. Beide mit einem
e
Labeel beschrifteen mit „ms“ und „size inn %“.Ergeb
bnis:
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 11
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Userfreuundliche Prrogrammiereer spendiereen noch ein
ne Close-Tasste. Diese isst mit einem
m Button
leicht zuu erreichen.. Habe diesee Taste butttonClose geenannt, Text auf Close uund in Imag
ge das
Bild cloose.jpg einbinden, TextA
Align auf M
MiddleRight und ImageA
Align auf M
MiddleLeft. In
I der
Click Fuunktion dannn folgenden
n Text:
Will maan aber mehhrere solcher Buttons m
mit Icons hab
ben, so warrte man auf die dafür viiel
bessere Komponennte ToolStrip
p.
Noch eiinen Hinweiis für Freun
nde der Steuuerung überr Tastatur. Macht
M
man iirgendwelch
he
Bediensschritte imm
mer wieder, dann ist dass Bedienen über Tastattur einfach sschneller un
nd
bequem
mer als mit Maus.
M
Dies wird
w auch hhier unterstü
ützt. Man sieht unten inn der Close-- Taste,
dass dass C unterstrrichen ist. Scchreibt mann in der Eigeenschaft Texxt ein & vorr dem Buch
hstaben C,
definierrt man dieseen Buchstab
ben als Shorrt-Cut- Taste. Wollen wir
w z. B. in uunserer Anw
wendung
die Starrt-Taste mit der Tastatu
ur über „a“ sschnell ansp
prechen (un
nd bei Stop zz. B. mit „o
o“), so
schreibeen wir in Teext vor dieseen Buchstabben ein „&““. Wir haben
n jetzt:
Diese T
Tasten lassenn sich jetzt z.
z B. mit AL
LT+“o“ bed
dienen.
Die Eig
genschaft Do
ock führt einne automatiische
Plazieru
ung und Verrgrößerung von Komponenten
durch. Man
M kann die
d Seiten deer Komponeenten
damit an
n die Seiten
n des „Contaainers“ kleb
ben. Bei
uns ist die
d Form1 der
d Containner. Mit Klicck auf den
Pfeil un
nten in der Eigenschaft
E
Dock öffneet sich ein
Fensterchen mit ein
nigen Tasteen. Klickt man
m z.B.
auf die Taste, auf die
d der rote Pfeil zeigt, dann
wird Do
ock auf Leftt gestellt unnd bei der
Komponente wird z. B. die linnke, obere und
u untere
bbar. Wir w
wollen alle vier
v
Seite ann den Container geklebtt, die rechtee Seite ist frrei verschieb
Seiten kkleben, das geht
g mit Klick auf die mittlere gro
oße Taste, Dock
D
wird ddann= Fill. Macht
M
man dieeses im Eigeenschaftenfe
fenster, hat ddas den Nacchteil, dass schon in deer IDE das Formular
F
ausgefüüllt wird undd die Form durch
d
Ankliicken nicht mehr selektiert werdenn kann. Bessser man
klebt erst nach dem
m Start des Programms,
P
, z. B. in dem dafür besstens geeignneten Eventt
„Form__Activated“,, wie oben bereits
b
schoon gezeigt.
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 12
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Danach sollte alles wie gewün
nscht aussehhen, nur es funktioniert
f
t noch nichtts.
Zu einem
m Spiel wirrd es erst mit den nächssten Schritteen.
Was solll passieren: Nach Startt soll die Poosition von PictureBox2
P
2 mit einem
m Zufallsgen
nerator
verändeert werden. Klickt
K
der User
U auf dass Bild Pictu
ureBox2, solll ein Zählerr inkrementtiert
werden,, trifft er danneben (also
o auf PictureeBox1), solllen diese veerfehlten Treeffer gezähllt werden.
Bei Stopp soll alles anhalten, beei Start die Z
Zähler wied
der auf null gesetzt werrden.
Dazu brrauchen wirr eine Timerr-Komponennte, die regelmäßige Ereignisse zuum Verstelllen der
Positionn erzeugen kann.
k
Diesee finden wirr in der Toollbox unter „Komponen
„
nten“ als Tim
mer. Er
hat die E
Eigenschaftt „Enabled““, die im Eiggenschaftsfeenster auf False
F
gesetzzt wird. Wen
nn
Enabledd auf True steht,
s
dann erzeugt
e
er aalle in Intervval spezifiziierten Millissekunden den Event
Tick. Allso folgendee Schritte siind zu tun:
timer1 aauf Form1 ziehen,
z
Ena
abled auf Faalse, Interva
al auf 1000.
Jetzt Staart und Stopp- Taste pro
ogrammierenn mit Dopp
pelklick auf die jeweiligge Taste und
d füllen
der Clicck- Funktionn mit untensstehendem rrot umrahm
mtem Text.
Im Ereiggnis timer1_Tick wird mit dem Zuufallszahlen
ngenerator Random()
R
di
die Position des
oberen P
Pixels vom Moorhuhn in PictureB
Box2 im erlaaubten Bereeich verändeert. Der erlaaubte
Bereichh berechnet sich aus derr freien inneeren Dimen
nsion der Fo
orm1 (abgeffragt in
ActiveF
Form.ClientSSize.Width und
u …Heigght) abzüglicch der Dimension derP
PictureBox2
2.
Der volllständige Code in timer1_Tick lauutet:
Random r
rand = new Random();
R
pictureB
Box2.Left = rand.Next(Fo
orm1.ActiveF
Form.ClientS
Size.Width - pictureBox
x2.Width);
pictureB
Box2.Top = rand.Next(For
r
rm1.ActiveFo
orm.ClientSi
ize.Height - pictureBox
x2.Height);
Mit der Methode .N
Next(zahl) wird
w eine Zuufallszahl zw
wischen 0 und
u zahl-1 eerzeugt.
oorhuhn muuss nach Staart über den Bildschirm
m springen.
Jetzt austesten mit F5. Das Mo
Jetzt fehhlen noch Zähler
Z
und Ergebnisaus
E
sgabe und Veränderung
V
g der
Beweguungsgeschw
windigkeit. Letztes
L
ist einfach: im ValueChang
V
ged- Ereignnis von
numericcUpDown1kkopiere man
n den Wert von numeriicUpDown1
1 .Value nacch Timer1.IInterval.
Code:
private
e void num
mericUpDow
wn1_ValueC
Changed(object sender, Even
ntArgs e)
{
time
er1.Interv
val = (int
t) numericUpDown1.Value;
}
Das exppliziete Castting auf int ist nötig, daa Value ein Typ „Decim
mal“ ist.
Den Zähhler realisieert man mit zwei Variabblen außerh
halb der Fun
nktionen. Diieses sind keine
k
globalenn Variablenn (gibt es in C# nicht m
mehr), sondeern zwei Varriablen des Objektes Form1.
.
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 13
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Ich macche es mit den
d beiden Variablen
V
cnntOK und cntNOK.
c
Also beei der Start- Taste auf null
n setzen, bbei Click au
uf pictureBox1 (danebeen) cntNOK
K ++, bei
Click auuf pictureBoox2 Treffer cntOK++ uund Ergebniis in label1 / 2 anzeigenn mit der Methode
M
ToStringg(), die denn Intergerweert in einen String umw
wandelt.
Fertigerr Source:
In timerr1_Tick:
l
label1.Tex
xt = "Hits
s= " + cnt
tOK.ToStri
ing();
l
label2.Tex
xt = "Miss
ses= " + c
cntNOK.ToS
String();
In pictuureBox2_Cliick
cntOK++
+;
In pictuureBox1_Cliick
cntNOK+
++;
hüsse auf nuull bleiben, wenn
Nun hatt diese Proggrammierweeise den Nacchteil, dass die Fehlsch
man nicchts tut. Wertet man ein
n Nichtstun auch als Feehlschuss, muss
m das Proogramm etw
was
abgeänddert werdenn. Zudem sollte in einem
m Durchgan
ng nur ein Klick
K
gezähllt werden, z.Zt.
z
kann
man proo Durchgangg mehrere Treffer
T
auslöösen. Im Tiimer wird in
n einer Booll- Variable namens
„free“ eein Schuss freigegeben
f
und schon m
mal ein Feh
hlschuss gezzählt. Nur inn pictureBo
ox2_Click
wird jettzt ein Trefffer gezählt, der Zähler ffür die Fehllschüsse korrrigiert und weiter Schü
üsse
blockierrt (siehe Koommentar).
Im neueen Source siind timer1_
_Tick und piictureBox2_
_Click unten
n abgebildett. Die Reiheenfolge
im Sourrce ist beliebbig verändeerbar. Im Edditor kann man
m vor jedeer Funktionn mit den + oder
o
–
Zeichenn mit quadraatischem Raahmen den C
Code verbeergen oder öffnen.
ö
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 14
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Zum Abbschluss dieeses ersten kleinen
k
Projjektes wird jetzt noch die
d Größe ddes Zieles vaariiert mit
numericUp
pDown2. D
Dort soll einee
Prozentzah
hl die tatsäcchliche Größ
ße
bestimmen
n. Steht dort
rt 50, so solllen
Height uund Width eben
e
nur 50
0% der ursprrünglichen Größe besittzen. Im Exp
xplorer kann
n man die
Größe ddes Bildes erkennen
e
miit 117* 226 Pixel. Im Ereignis
E
Cha
anged von nnumericUpD
Down2
wird dannn folgendeer Text hinzzugefügt:
Man beachte, dass vor Start diie Originalw
werte Heigh
ht=226 und Width=117 in pictureB
Box2
stehen ssollten und dass
d die Eig
genschaft SiizeMode au
uf StrechIma
age steht, soonst geht ess nicht.
Code:
private
e void num
mericUpDow
wn2_ValueC
Changed(object sender, Even
ntArgs e)
{
pict
tureBox2.W
Width = 11
17 / 100 * (int)numericUpDo
own2.Value
e;
226 / 100 * (int)numericUpD
pict
tureBox2.H
Height = 2
Down2.Valu
ue;
}
Ein letzzter Schönheeitsfehler wird
w beseitiggt. Wenn maan die Beweegung des Z
Zieles beobaachtet, so
erscheinnt ganz kurzz aber sichtb
bar das Ziell erst horizo
ontal neben der alten Poosition. Dass liegt
daran, ddass erst Lefft und dann Top verstelllt wird.
Abändeerung durch das Verstelllen von Loccation, dann
n werden x und y- Kooordinate gleichzeitig
verstelltt.
Code inn timer1_Ticck:
int lef
ft= rand.N
Next(Form1
1.ActiveFo
orm.ClientSize.Wid
dth - pict
tureBox2.W
Width);
rm.ClientSize.Height - pict
int top
p= rand.Ne
ext(Form1.
.ActiveFor
tureBox2.H
Height);
Point l
loc1 =new Point(lef
ft,top);
picture
eBox2.Loca
ation = lo
oc1;
Weitereer Variationen wie z. B. High Scorre Liste, ein
nstellbare Laaufzeit, mehhrere Ziele sind
s
keine G
Grenzen geseetzt.
Stellt m
man die Zeit auf <700 ms,
m so wird ees schon seh
hr schwierig
g, alle Zielee zu treffen.
Alle ferrtigen Dateien sind auf dem ftp-Seerver unter „Kurs1#Spi
„
el“ zu findeen. Dort hab
be ich
auch nooch den Titeel der Form (in Form1.T
Text) geänd
dert.
Jetzt fehhlt eine kleiine Schönheeitskorrektuur: Es ist diee Transparen
nz der Labeel und des Zieles,
Z
was nichht so triviall ist.
Z
Zur Transp
parenz
os:
e inige Info
Eiine Form haat die
Eiigenschaft Opacity,
O
diie zwischen
n 0 und
1000% eingesstellt
w
werden kann
n. Damit
w
werden alle Elemente
E
m
mehr oder weniger
duurchscheineend. Bei
500% sieht daas Spiel
z..B. so aus und der
Innhalt dahinter
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 15
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
schimm
mert schon mächtig
m
durcch. Dies ist für Auf- un
nd Abblendu
ungen beim
m Start wohl mal ganz
witzig.
Stellt man
m die Eig
genschaft TrransparencyyKey z.B.
auf Wh
hite, dann bekommt diee Anwendun
ng an
allen Stellen,
S
die weiß
w sind, L
Löcher und der
Hintergrund ist zu
u sehen. Sow
wohl in der
Überscchrift als auch die numeericUpDow
wn sind
jetzt sttellenweise durchsichtigg. Selbst die Maus
klickt durch
d
die Löcher
L
durchh. Das Close- Kreuz
ist auch durchsich
htig!
Nur leidder gilt dies nicht für eiin BMP, da s in eine picctureBox geeladen ist.
Transpaarenz ist mitt BMP- Bild
dern nicht m
möglich. Ab
ber dafür kaann man giff und png- Bilder
B
laden, uund die bringgen eine Trransparenz- Eigenschafft mit. Ich habe das Mooorhuhn- Bild in ein
GIF konnvertiert und die Außen
nfarbe als T
Transparenzz Farbe deklariert (das ggeht mit
einschläägigen Bildbbearbeitung
gsprogramm
men, z. B. ULead
U
Photo
oimpact). Ess heißt jetzt grHuhn5
echtweiß
iß3.gif. Dann muss man
n noch BackkColor von PictureBoxx2 auf Transsparent stelllen, dann
sollte ess gehen. Den TranpareencyKey derr Form wied
der auf eine Farbe stelleen, die nich
ht
vorkom
mmt, z.B. redd.
Nun solllte es gehenn. Damit beim Bewegeen des Moorrhuhns kein
ne weißen Feelder zu seh
hen sind,
stellt maan dann nocch die Eigen
nschaft DouubleBuffered
d von Form
m1 auf true..
Die Label
L
werdeen mit folgeendem Schritt gegen
das Blumenbild
B
transparentt: pictureBo
ox1
lösch
hen samt aller Verweisee darauf. Daas Bild
wird als Hinterg
grundbild deer Form
n so, wie im Bild setzenn. Dann in allen
a
eingebuunden. Dazuu setzt man dort die Eiggenschaften
Labels ddie Eigenschaft BackC
Color auf Traansparent setzen.
s
Diese
ist unterr „WEB“ zuu finden. Ich
h hab die Faarbe in ForeeColor auf
Yellow
w gesetzt,
dann sieht ein Label
so aus:
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 16
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Kurs 2 Rech
hnen, Multiwind
dowing
Es wirdd die Berechhnung, die Ein-sowie
E
A
Ausgabe von
n Zahlen gezzeigt sowie der Umgan
ng von
Projekteen mit mehrreren Fensteern.
Start miit neuer Anw
wendung. Es
E werden zw
wei TextBox- Kompon
nenten mit zzwei Beschrriftungen
(Label) auf das leerre Formularr platziert. B
Bei mir ist es
e WindowssApplicationn11.
Ändere
Ä
Labeel->Text Inhhalte und Ed
dit->Text
Eigenschafte
E
en wie linkss gezeigt.
Nach
N
Eingab
be einer Zahhl in Feld Radius
R
soll
die
d Fläche au
usgegeben w
werden und
d nach
Eingabe
E
der Fläche in A
Area soll derr Radius
berechnet
b
weerden. Die FFormeln lau
uten
bekanntlich:
b
A=
A πr2 sowiee r=(A/π).
Nun muuss überlegtt werden, in welchem E
Ereignis die Berechnun
ng durchgefü
führt werden
n soll. Es
soll keinn Button zuum Start derr Berechnunng geben.
Möglichhkeiten: 1. TextCanged
T
d der textBoox- Kompon
nenten. Nachteil: gibt m
man falsche Werte
ein (z. B
B. Buchstabben) führt diie Berechnuung sofort zu
u Fehlermeldung, da jaa sofort der
Stringinnhalt des Tex
ext- Feldes (.Text
(
ist einne Zeichenk
kette, Typ String) in einne Zahl kon
nvertiert
wird unnd der User keine
k
Chance hat, es zuu korrigiereen. Die Kon
nversion dess Strings in eine
Floatingg- Point – Zahl
Z geht miit Double.Pa
Parse() oderr mit Conveert.ToDoublle(). Auspro
obieren:
Code:
private
e void tex
xtBoxRadiu
us_TextCha
anged(object sender, EventA
Args e)
{
doub
ble radius
s=Double.P
Parse(text
tBoxRadius
s.Text);
doub
ble area = radius*r
radius*Mat
th.PI;
text
tBoxArea.T
Text = are
ea.ToStrin
ng();
}
Hinweisse zur Berecchnung: Diee Ein- und A
Ausgabe erffolgt über die
d Text- Eiggenschaft vo
om Typ
String. E
Es muss dannn eine Kon
nvertierung von Float nach
n
String und umgekkehrt durchg
geführt
werden.. Es wird hiier der Floatting-Point T
Typ „doublee“ benutzt (cca. 15 Stelleen), der viel genauer
ist als flloat (7 Stelllen). Die Ko
onstante π isst in der maathematischeen Bibliotheek Math zu finden.
2. Leavee: Dann wirrd das Ereig
gnis ausgelööst, sobald der
d Focus au
uf eine andeere Kompon
nente
übergehht, z. B. durcch Klick des Benutzerss auf textBo
ox2. Nur derr User musss das wissen
n.
Also Änndern von OnChange
O
auf
a Leave. D
Das geht so,, dass man das
d Feld hinnter dem Ereignis
Leave ddoppelklicktt, im Code den
d Inhalt vvon TextCha
anged in diee neue Funkktion Leave schiebt.
Jetzt niccht im Cod
de den Funk
ktionsaufruff löschen, so
ondern den Eintrag
E
im E
Eigenschaft
ftsfenster
unter TeextChangedd. Dann wird
d in der IDE
E automatissch der Funk
ktionsaufruff gelöscht.
private
e void tex
xtBoxRadiu
us_TextCha
anged(object sender, EventA
Args e)
{
NICHT LÖSCHEN
L
!!
!
}
private
e void tex
xtBoxRadiu
us_Leave(o
object sender, EventArgs e)
{
d
double rad
dius = Dou
uble.Parse
e(textBoxR
Radius.Text);
d
double are
ea = radiu
us * radiu
us * Math.
.PI;
t
textBoxAre
ea.Text = area.ToSt
tring();
}
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 17
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Diesen Einntrag Lösch
hen !
Oder Cursoor auf TextC
Change,
rechter Mauusknopf, daann
« Zurückseetzen »
3. Mögllichkeit. Naach Druck der
d Eingabee- Taste (aucch return- Taste
T
genannnt) auf dem
Keyboaard soll Bereechnung durrchgeführt w
werden. Daas ist nicht mit
m dem Ereeignis Enterr zu
realisierren (Enter wird
w ausgelö
öst, wenn diie jeweiligee Komponen
nte den Focuus bekomm
mt).
Dazu giibt es das Erreignis KeyP
Press. In deem Header der
d Funktio
on wird im PParameter e der
Char-W
Wert der Tastte in e.KeyC
Char überggeben, der besagt, welch
he Taste geedrückt word
den ist.
Die retuurn / Eingabbe- Taste haat den Wert HEX 0D. Also
A Code:
private
e void tex
xtBoxRadiu
us_KeyPres
ss(object sender, KeyPressE
EventArgs e)
{
if (e.KeyChar
(
r == 0x0d)
) textBoxR
Radius_Lea
ave(this,e
e);
}
Oder
private void textB
BoxRadius_K
KeyPress(ob
bject sender, KeyPress
sEventArgs e) { if (e.KeyChar ==
= (char)Key
ys.Return) t
textBoxRadi
ius_Leave(tthis, e); } Hinter dder if- Abfraage wird nu
un die Berecchnung ausg
gelöst. Hier könnte einee Kopie derr Zeilen
unter Leeave folgen, aber man kann
k
auch eeine existierrende Ereign
nisfunktionn direkt aufrrufen. Im
Zeiger „„sender“ wiird die Adreesse des auffrufenden Containers
C
üb
bergeben.
Vervollständigen Sie
S das Prog
gramm zur B
Berechnung
g auch noch des Radiuss aus der Flääche nach
Druck aauf die Einggabe- Taste, wenn die T
Textbox für „area“ den Focus hat.
Ein Hinnweis sei nooch getan: Die
D Ausgabee einer Floatting- point Zahl
Z kann aauch formattiert
erfolgenn, indem maan in der Methode ToS
String(IForm
matProvider) den IForm
matProviderr benutzt.
Beispielle: Ausgabee von
in einer Teextbox mit
ergibt x.ToString(); K
Keine Forma
atierung x.ToString("f2"); F
Festkomma 2
2 Stellen
x.ToString("g2");
2
2 Stellen „
„general“
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 18
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
x.ToString("c2"); „
„Currency“ 2 Stellen
x.ToString("e2"); „
„exponentia
al“
x.ToString("p2"); P
Prozent
Dann giibt es noch die Buchstaaben „d“ fürr Dezimalau
usgabe, dann muss x jeedoch ein Ty
yp
„decimaal“ sein.
Hexadeezimalausgaabe: x=255 führt mit xx.ToString("x10"); zuu Und mitt x.ToStringg("X10"); zu Das Erggebnis bis hierhin ist in
n Kurs 2a# B
Berechnung
g auf dem ftp
p zu findenn.
Komm
ma- Prob
blematik
Wenn m
man Texte / Strings in Fließkomma
F
azahlen um
mwandelt, gib
bt es ein gruundsätzliches
Problem
m: Auf deutsschen PCs ist
i der Dezim
maltrenner ein Kommaa, der Punktt ist für
Tausenddergruppierrung vorgeseehen. Bei U
US- Rechnerrn ist es gen
nau umgekeehrt. Da bei uns auch
meine P
Programme von US- Sttudierendenn benutzt weerden sollen
n, muss das PProgramm mit
beiden V
Versionen klarkommen
k
n. Werden T
Textdateien
n zwischen beiden
b
Natioonalitäten
ausgetauuscht, dannn gibt es imm
mer wieder Konflikte genau
g
deshaalb. Der deuutsche Rechn
ner
erzeugt Zahlen mitt Kommas z.B.
z 1,234, ddie dann von
n US- Rech
hnern als Taausendertren
nnzeichen
gelesen werden undd diese Zah
hl als 1234 liiest.
bstgeschriebbene eigene ConvertToDouble- Fuunktion. Weenn in
Eine Löösung bietett meine selb
einer Zaahl nur ein Trennzeiche
T
en auftauchht, wird dies als Dezimaaltrenner auufgefasst. Wenn
W
mehr
als ein T
Trenner aufftaucht, so isst das rechtee immer derr Dezimaltrenner, die lilinken immeer
Tausenddergruppierrungen. Also
o egal ob 1,,234.78 odeer 1.234,56 beide
b
Zahleen werden riichtig als
1234 Kommma 78 interrpretiert, wo
obei Komma dden Dezimalltrenner meint. Dabei i st es egal, auf
a was
für eineem Dezimalttrenner der PC gestellt ist, dies wiird vorher von der Funkktion geprüft.
Der einzzige nichtlöösbare Konfflikt taucht aauf, wenn der
d einzige Trenner
T
in eeiner Zahl ein
Tausenddertrenner sein
s soll. Beei dieser Funnktion wird
d er immer als
a Dezimalttrenner geleesen. Also
egal ob 1,234 oder 1.234, diese Zahl wirdd dann immer als 1 Komm
ma 234 gelessen.
Beispiellanwendungg:
Neues P
Projekt nachh Kurs 2c# erzeugen.
e
Z
Zum Projektt Hinzufügeen die Datei DataToolsM
Mini.cs:
Dann diiese Datei DataToolsM
D
Mini.cs sucheen und ausw
wählen.
Außerhaalb einer fuunction jetzt eine neue IInstanz von DataTools erzeugen, iindem man das Wort
DataToools eintippt und rechte Maustaste  Auflösen
n wählt:
Dann w
wird automattischer der namespace
n
von DataTo
ools hinzugeefügt, nämllich
WINDF
F7CSharp.
Weiter:
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 19
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
DataTools dt
t = new Dat
taTools();
Nun einne Textbox und
u ein Lab
bel hinzufüggen.
Hinter ddem Click- Ereignis des Labels daann folgendeen Code erg
gänzen:
double
e X = 0; dt.Con
nvertToDoub
ble(textBox
x1.Text, ref
f X); label1
1.Text = X.
.ToString() ; Dann kaann man das Programm
m ausprobieeren.
Mehre
ere Fens
ster
Ein Projjekt hat norrmalerweisee mehr als e in Fenster. Wir wollen
n jetzt ein Prrojekt mit drei
Fensternn generierenn. Ein Fenstter soll das eben entwicckelte sein, ein weiterees soll das
Hauptfeenster werdeen, von dem
m dieses geööffnet wird und
u ein dritttes soll ein Infofensterr sein.
Dazu füügen wir zw
wei Forms zu
u unserm Prrojekt hinzu
u. Am besten öffnet maan dazu den
Projektm
mappen-Expplorer (Strg
g+w,s). Dortt kann man das Projektt selektierenn (bei mir
Window
wsApplicatiion11), dann
n im Popup wählen „H
Hinzufügen“, dann „Neuues Element“, dann
eine Wiindows Form
m selektiereen. Die zweei Male wied
derholen. Nun
N alle Form
ms mit neueem
Namen versehen, so
s dass anscchließend w
wie im Bild die
d drei gew
wünschten FForms zu seh
hen sind.
nnen“ auch aauf
Die Abffrage, ob daas „Übernen
Verweisse wirken sooll, natürlich bejahen.
Name soowie Text der
d zweiten Form: Form
mMain, Nam
me sowie Text
T der dritttten Form: FormInfo.
F
Größen und Positioon etwa so wie
w im nächhsten Screen
nshot.
Nun wirrd allerdinggs beim Starrt immer no ch das alte Circle- Fen
nster geöffneet, nicht wiee
gewünscht FormM
Main. Dieses kann man äändern in deer Datei Pro
ogram.cs, ddie wir jetzt öffnen.
Dort in der Funktioon Main() siieht man follgenden Co
ode:
s
static voi
id Main()
{
Appl
lication.E
EnableVisu
ualStyles(
();
Appl
lication.S
SetCompati
ibleTextRe
enderingDe
efault(fal
lse);
Appl
lication.R
Run(new Ci
ircle());
}
Im rotenn Rahmen steht
s
der Naame der Form
m, die als erstes
e
sichtbar wird. Hieer einfach auf
a
FormMain ändern. Dann öffneet sich nachh Start unserr FormMain
n:
Applica
ation.Run(
(new FormM
Main());
Bevor w
wir jetzt weiitermachen,, sollte erstm
mal die Location der Fo
ormulare auuf verschied
dene
Werte ggestellt werdden, sonst liiegen alle F
Fenster genaau übereinan
nder. Also LLocation vo
on
FormM
Main lassen auf
a (0;0), Fo
ormInfo auff (200;200) und FormC
Circle auf (1100;100).
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 20
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Jetzt zw
wei Buttons auf das Hau
uptfenster, aalso in Form
mMain plazzieren, bescchriften mit Circle
und Infoo. Mit „Circcle“ soll jetzzt unser urspprünglichess Fenster geeöffnet werdden und zwaar
„nichtm
modal“, d. h.. der User kann
k
in andeere Fenster klicken.
k
Daas Info-Fensster soll „mo
odal“
geöffnett werden, d.h. der Userr muss erst ddieses Fensster schließeen, bevor err andere Fen
nster der
Applikaation erreichhen kann. Welche
W
Sortee sinnvoll isst, bestimmen Sie als PProgrammieerer. Die
Methodden zum Öfffnen der Forrms heißen einfach Sho
ow() und Sh
howDialog()
().Code:
FormInf
fo frminfo
o = new Fo
ormInfo();
;
Circle frmCircle
e = new Ci
ircle();
private
bject sender, EventArgs e)
e void but
ttonCircle
e_Click(ob
{
frmC
Circle.Sho
ow();
}
private
e void but
ttoninfo_C
Click(obje
Args e)
ect sender, EventA
{
frmi
info.ShowD
Dialog();
}
Erst werrden Instanzzen der Forrmulare erzeeugt mit new
w, dann kan
nn man dies e Formulare
ansprechen mit denn beiden Show- Methodden. Die Insstanziierung
g muss dabeei außerhalb
b einer
Funktioon erfolgen, damit der Name
N
der Innstanz (also z.B. frminffo) für andeere Funktion
nen
erreichbbar ist.
Jetzt solllte das Proggramm wie gewünschtt funktionierren. Auspro
obieren.
Man kannn jetzt beliiebig zwisch
hen Circle uund FormM
Main hin und
d her springgen, aber Fo
ormInfo
muss geeschlossen werden,
w
um
m wieder an Circle oderr FormMain
n zu gelangeen. Wird Fo
ormMain
geschlossen, werdeen die anderren Fenster auch geschlossen und aus dem Sppeicher entfe
fernt. Nun
gibt es eein Problem
m. Schließt man
m die Info
fo- Form, daann kann maan sie beliebbig oft wied
der
öffnen, die Instanz wird beim Schließen nnicht entfern
nt, sondern nur unsichttbar. Öffnet man aber
eine Forrm mit Show
w() und sch
hließt diese m
mit Close(), dann wird die Instanzz aus dem Speicher
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 21
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
entferntt. Beim nächhsten Klick auf die Tasste circle gib
bt es dann eine
e Fehlerm
meldung, daa auf eine
Instanz zugegriffenn wird, die es
e nicht mehhr gibt:
Übrigenns jetzt überr Menü Deb
bug nach Stoop Debuggiing gehen un
nd Program
mm beenden
n.
Abhilfe 1: Man verrlegt die Insstanziierungg in die Clicck- Funktion
n des Buttonns. Ergebnis ist, dass
nach jeddem Wiederröffnen von
n circle die D
Daten weg sind
s
und sch
hlimmer beei jedem Kliick auf
circle eiin neues Fennster aufgem
macht wird.. Im Bild un
nten gibt es jetzt 3 Fensster.
Abhilfe 2:
Man speendiert einee Close- Tasste auf Circlle, in der nu
ur die Form unsichtbar gemacht wird
w mit
Aufruf dder Methodde Hide().Co
ode in Circlle:
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 22
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
private
e void but
ttonClose_
_Click(obj
ject send
der, EventArgs e)
{
C
Circle.Act
tiveForm.H
Hide();
}
Dann soollte man abber die Closse- Taste im
m Kopf des Windows-R
W
Rahmens aucch verschwiinden
lassen zz. B. mit derr Property
ControllBox der Foorm, die dan
nn auf
False geesetzt wird.
Noch beesser: ContrrolBox lasseen (der Useer erwartet das
d ja irgend
dwie und keennt es) und
d den
Close- B
Befehl abfanngen mit fo
olgendem Evvent:
private
e void frm
mCircle_Fo
ormClosing
g(object sender, FormClosin
ngEventArg
gs e)
{
e.Ca
ancel = tr
rue;
Visi
ible = fal
lse;
}
Dann geeht es.
Schaut m
man jetzt auuf unser Pro
ojektverzeicchnis, so erk
kennt man folgende
f
Daateien links. Jedes
Fensteer hat eine .cs - Datei fü
für den Sourrce, eine
.Desig
gner.cs für das
d Design der Oberflääche, eine
.resx. Im Pfad „bin“ findet m
man dann diie exeDatei.. Bitte die .D
Designer.css nicht öffneen und
nicht verändern. Es ist eine vvom IDE
matisch erzeugte Textdaatei, die dass
autom
graph
hische Desig
gn festlegt.
Zwiscchen Code (.cs)
(
und Deesign nur mit Menü
View umschalten
n.
In FormIInfo soll miit Druck auff einen
Button der
d Inhalt voon
textBoxR
Radius.Text von Circle
herüberg
geholt werde
den. Realisieerung
folgendeermaßen:
Der Zugriff von einner Form auff
nts
Propertiees, Methodeen und Even
anderer Forms
F
ist m
möglich, sofe
fern man
von der Main
M Form auf die dorrt
instanzieerten Formss zugreifen will.
w Also
im obigeen Beispiel kkann man von
v
FormMa
ain auf frmC
Circe und frrmInfo
zugreifeen. Was muuss man tun:: Beispiel: A
Auf FormM
Main soll mitt einem Buttton
„buttonTransfer“ der
d Inhalt (.T
Text) von laabel1 auf Fo
ormInfo verrändert werdden. Versuccht man
24
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 23
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
es, so geeschieht ersst einmal folgendes: Einn Zugriff au
uf frminfo.la
abel1 ist niccht möglich
h und wird
im CodeeCompletioon- Fenster nicht
n
angebboten. Das liiegt daran, dass
d die Koomponente label1
l
als
„privatee“ deklariertt ist. Diese muss
m
auf „ppublic“ geän
ndert werdeen. Dies ist m
mit der Prop
perty
„.Modiffiers“ des laabel1möglicch. Also in F
FormInfo diiesen Modiffiers auf Puublic umstellen. Dann
ist ein Z
Zugriff auf label1
l
mögllich.
Jetzt wirrd in FormM
Main ein Zu
ugriff auf
label1 an
ngeboten. FFertiger Cod
de:
private
e void but
ttonTransf
fer_Click(
k(object sender, EventArgs e
e)
{
frmi
info.label
l1.Text = "This Message com
mes from F
FormMain";
}
Somit isst also ein Zugriff
Z
vom
m Hauptproggramm, in dem
d der Kon
nstruktor miit dem Schlüsselwort
new auffgerufen wirrd, problem
mlos möglichh.
Aber wiie kann jetzzt vom Sub- Fenster (Foorminfo odeer Circle) au
uf das Form
mMain oder von Sub
nach Suub zugegrifffen werden. Das geht foolgendermaaßen. Für deen Zugriff bbraucht das
Program
mm in der SubS
Form eine Referennz (ist natürlich so etwaas wie ein PPointer / Zeiiger).
Diese R
Referenz muuss vom Maain an die Suub- Fenster übergeben werden.
Dazu w
wollen wir jeetzt folgendees Beispiel realisieren. Ein Tasten
ndruck auf FFormInfo so
oll jetzt
den Inhalt einer TeextBox auf FormMain
F
aauslesen in ein Label. Ein
E zweiter Tastendrucck soll aus
Circle dden Radius aus
a der entssprechendenn Textbox auslesen
a
und
d in ein Labbel in FormIInfo
schreibeen.
In Form
mMain folgeende Veränd
derung
durchfüühren:
In Fo
ormInfo folgende Veräänderung
durchführen:
FormInf
fo frminfo
o;
Form
mMain mein
nMain;
public FormMain(
()
{
In
nitializeC
Component(
();
frminfo
o = new Fo
ormInfo(th
his);
}
publ
lic FormIn
nfo(FormMa
ain m)
{
Initia
alizeCompo
onent();
meinMa
ain = m;
}
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 24
Visuelle Programmierung mit C#
In der ersten Zeile wird ein globaler Zeiger
auf FormInfo ohne Konstruktor deklariert.
Im Konstruktor (nach new) wird jetzt mit
Schlüsselwort this der Zeiger auf
FormMain an den Konstruktor in FormInfo
übergeben
Prof. Dr. Bayerlein
In der ersten Zeile wird ein globaler Zeiger
auf FormMain ohne Konstruktor deklariert.
In der zweiten Zeile wird this in m
übergeben und in der Zeile meinMain=m
wird der globale Zeiger auf FormMain
gestellt. Ab dann ist FormMain über
meinMain erreichbar.
Mit der Zeile
label1.Text = meinMain.textBox1.Text;
Kann dann in FormInfo die Textbox auf FormMain ausgelesen werden.
Der Zugriff von FormInfo auf Circle geht jetzt nicht direkt, sondern über FormMain. Will man
den Radius von Circle nach FormInfo auslesen, geht das einfach mit
label1.Text =meinMain.frmCircle.textBoxRadius.Text ;
Das war‘s.
File: Kurs MS10C# Bayerlein4.6.docx
Seite 25
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Kurs 3 Profe
essione
elles Des
sign
In dieseem Kurs werden die Ko
omponentenn StatusBar,, Menu, Pop
pupMenu m
mit einigen wichtigen
w
Eigenscchaften wie ToolTips (ffrüher: Hint)
t) vorgestelllt.
Menü
üs
Wir wo
ollen mit deem Ende dess letzten Ku
urses startenn. Die Dateien sind
verfügb
bar auf dem
m FTP- Serv
ver studpub.ffh-luebeck.dde unter bayyerlej/MS
Studio2
2008/kurs2bb# Multiwin
ndows.
Wir wo
ollen als ersstes dem Haauptfenster FormMain
F
eein MenuSttrip
hinzufüügen. Diese Komponentte ist in der Toolbox „M
Menüs & Sy
ymbolleisteen“ zu findeen. Jetzt
wird miit einem Dooppelklick au
uf diese Koomponente der
d Menü- Designer
D
geeöffnet. Hier kann
man jetzzt seine Meenüstruktur bequem
b
deffinieren.
Wir wolllen zur Übuung einfach
h mal die errsten Einträg
ge des Menü
üs vom C# abkupfern,
allerdinngs vorerst mal
m ohne Ico
ons. Bevor man ein Meenü definierrt, muss maan sich als
mmierer sehhr genau diee Bedienphillosophie üb
berlegen. Diieses ist natüürlich nichtt
Program
Gegensttand dieser Vorlesung, wie man daas macht. Also
A erst maal das Menüü unter „Datei“
ansehenn und dann nach
n
und naach eingebeen:
Unter Datei findeen sich die
Einträg
äge Neu, Öff
ffnen,
Hinzuf
ufügen, Schlließen,
Quersttrich (einfacch Rechte
Mausttaste, dann Separator
S
einfüggen) usw. Man
M gebe
diese N
Namen sukzzessive
ein. Daas Menü istt im IDE
sofort auszutesten
n. Es
fehlen nocch die beideen Pfeile hin
nter Neu
und Öffneen, die ein SSubMenu öfffnen.
Dort dann
n weiter die entsprechen
nden
Menüeintrräge eingebben.
Die Verkn
nüpfungen ssind einzeln
ne
Eigenschaaften der Meenüeinträgee:
ShortcutK
Keys. Dort kkann man in
n einer
Liste den gewünschteen wählen.
Das Meenü ist natürrlich noch ohne
o
Funktioon. Jetzt mu
uss für jeden
n Menüeintr
trag natürlicch noch
ein OnC
Click- Ereiggnis definierrt werden. E
Entweder macht man eiinen Doppel
elklick auf einen
e
Menüeintrag, so daass die IDE ein Funktioonsaufruf errzeugt oder man wählt in der Ereig
gnisListe einn vorhandennes Ereignis aus. Wir eergänzen ein
nen dritten Hauptmenü
H
üeintrag „An
nsicht“
und erzeeugen darunnter die beid
den Menüs „Circle“ un
nd „Info“. Diesen
D
ordnee man dann die den
bisheriggen Tasten buttonCircle
b
e oder buttoonInfo_Clicck zugehörig
gen Click- E
Ereignis zu. Dann
können wir auch mit
m dem Men
nü die beideen anderen Fenster
F
öffn
nen.
Einige zzusätzliche Möglichkeiiten: Ein Meenü lässt sicch als Ein/ Ausschalter
A
r verwenden
n. Dann
muss diie Eigenschaaft CheckOn
nClick auf T
True stehen
n. Bei jedem
m Klick auf ddiesen Men
nupunkt
wird dannn die Eigeenschaft Cheecked zwiscchen true un
nd false umg
geschaltet, eerkennbar an
a einem
Häkchen vor dem Eintrag.
E
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 26
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Jeder M
Menüeintrag kann wie im
m Vorbild m
mit einem Iccon verseheen werden. D
Diese Iconss werden
mit Imaage einzeln geladen
g
. (IImageList auus Componeents funktio
oniert hier leeider nicht wie
w bei
BCB). F
Für ein Mennü sollten diiese Icons nnicht zu groß sein, sonsst sieht es häässlich aus. Ich habe
als Beisspiel aus einnem Window
ws- Ordner einige Icon
ns mit der Größe
G
16*166 Pixel
zusamm
mengesucht. Diese sind
d im Ordner Icons diesees Kurses zu
u finden.
PopUp
Up-Menüs
s mit Con
ntextMen
nuStrip
Die Arbbeit mit PoppUps ist sehr ähnlich. S
Soll Ihr Projekt solcher Art Menüs bekommen
n, dann
muss deer User das natürlich wissen.
w
Er m
muss dies ja mit
m einem rechten
r
Mauusklick aktiv
vieren.
Ich hatte mal ein Toolprogram
T
mm mit solchhen Popupss geschriebeen, aber aus Unwissenh
heit hat
keiner ddiese genutzzt. Also jetzzt ein ContexxtMenuStrip
p hinzufügeen (aus Mennüs & Toollbars).
Auch hiier kann maan leider keiine ImageLiist daran kn
nüpfen.
Daa nun jede Komponente
K
e ein eigenees PopUpMeenü haben kann,
k
muss m
man Kompo
onenten
übeer die Eigen
nschaft ConntextMenuSttrip
verrbinden. Do
ort kann mann vorhanden
ne
sellektieren. Wir
W wählen F
FormMain. Nach
Pro
ogrammstarrt mit F5 kan
ann man mitt
Rechtsklick au
uf FormMaiin das PopU
Up-Menü
auffrufen.
Status
sBar mitt StatusS
Strip
Diese Kom
mponente ist bei den meeisten üblichhen Program
mmen
auch vorhannden. Man findet sie in
n Menüs & T
Toolbars. Man
M ziehe
eine auf dass Hauptform
mular FormM
Main. Die E
Eigenschaftt Dock
steht autom
matisch auf Bottom,
B
som
mit ist sie glleich an der richtigen
Stelle. Willl man sie niccht weiter unterteilen
u
in so genann
nte
Panels,
P
dannn kann man
n den Ausgaabetext in ddie Eigensch
haft Text
schreiben. A
Aber meisteens nutzt maan die Unteerteilung in mehrere
m
Abschnitte.
A
. Diese kann
n man hinzu
ufügen mit ddem rot um
mkreisten
Symboll. Es werdenn vier Typen
n von Abschhnitten angeboten. Wirr fügen 2 SttatusLabel zur
z
Ausgabe von Text hinzu, dann
n eine ProgrressBar und
d ein DropD
DownButtonn. StatusLab
bel1
bekomm
mt den festeen Text (hierr „Version 1.0“in Eigenschaft Texxt), dann im
m nächsten die
d
aktuellee Uhrzeit (errstmal „timee“). In die D
DropDownB
Buttons gebe man ein ppaar Einträg
ge an,
einer soollte „Start Progress“
P
heeißen. Ergebbnis:
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 27
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Mit Dopppelklick auuf „Start Pro
ogress“ gebben wir dortt folgenden Text in die Click-Funk
ktion ein:
private
e void ghi
iToolStrip
pMenuItem_
m_Click(object send
der, Event
tArgs e)
{
tool
lStripProg
gressBar1.
.Value += 10;
}
So wirdd bei jedem Klick auf diesen
d
Eintraag zur Lauffzeit der Pro
ogress- Balkken weiter nach
n
links
wandernn.
Einen P
Panel- Text erreicht
e
man
n mit der Syyntax toolS
StripStatu
usLabel2.T
Text….
Hinter „„Label“ stehht die Numm
mer des Pannels beginneend links mit 1. Die Uhhrzeit wird alle
a
Sekundee mit einem
m Standard- Timer (in „„Komponen
nten“) im TimerTick- E
Ereignis- zum
m Panel
geschrieeben. Timerr- Eigenschaaften: Intervval auf 1000, Enabled auf true. Voom System erhält
man diee Systemzeit mit DateT
Time.Now, ddiese muss dann
d
noch in einen Striing konvertiert
werden:: Code:
private
e void tim
mer1_Tick(
(object se
ender, Ev
ventArgs e)
{
tool
lStripStat
tusLabel2.
.Text = DateTime.N
D
ing();
ow.ToStri
}
Hints mit ToollTips
Viele W
Windows- Sttandardprog
gramme wiee z. B. Word
d oder Paintt sind mit de
den kleinen gelben
g
Hinweisteexten (=Hin
nts oder Too
oltips) ausgeestattet, die beim
„Hooverinng“, also beim Bewegen des Mausszeigers z.B
B. über
Tasten, kuurz erschein
nen und dem
m Benutzer H
Hilfestellun
ng leisten
sollen (sieehe Beispiell
Paint). D
Dieses wirdd auch von C#
C unterstüttzt. Alle
Tooltip--fähigen Koomponenten
n, also alle ssichtbaren,
haben ddie Eigenschhaft ToolTip
p, in der einn Hilfetext
stehen kkann, das abber erst, wen
nn die Anw
wendung diee
Komponnente ToolT
Tip aus „Alllgemeine
Steuerellemente“ beekommt. Jettzt bei den bbeiden
Buttonss irgendeineen sinnvollen
n Text in To
ToolTip on
toolTip1 eiingeben, z. bb. in der Inffo- Taste:
Dieser wird mit gelbem
m Minifensster
angezeigt, wenn die E
Eigenschaft isBallon
auf true steeht, in Balloon- Design.
Jedes Prog
gramm solltee meiner Meinung
M
eine Mögliichkeit habeen, diese gelben
Dinger ausszuschalten.. Den erfahrrenen
User nerveen sie nur. H
Hat das Projekt aber
viele 1000 Komponennten mit ebeenso
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 28
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
vielen H
Hint- Textenn, ist es müh
hsam. Will man z. B. alle
a Tooltipss der gesamt
mten Applikaation an /
und ausschalten, daann muss man
m nur die E
Eigenschaftt Active in der
d Komponnente Tooltip
ip auf
false settzen.
Will maan per Progrramm den Inhalt des TooolTips verrändern so gibt
g es abhän
ängig von deer
Komponnente zwei Versionen, wie das gehht:
1. Steht im Eig
genschaften
n- Editor „T
ToolTip on toolTip1“,
t
dann
d
geht daas mit der Methode
M
SetToolTip( object,striing); Beispiiel:
t
toolTip1.S
SetToolTip
p(Button1,
, "Schließ
ßen");
2. Steht im Eiggenschaften
n- Editor TooolTipText, dann einfach z.B.
T
ToolButton
n11LoadFil
le.ToolTip
pText = "L
Lade Datei";
Mit folggendem Codde kann derr ToolTip- T
Text auch z..B. in der Sttatusleiste aangezeigt werden:
Tip1_Popup(
(object sen
nder, PopupEventArgs e
e) private void toolT
{ tripStatusL
Label1.Text
t = toolTip1
1.GetToolTi
ip(e.AssociiatedControl); toolSt
} Das gehht aber leideer nicht, wen
nn die toolT
Tips inaktiv
v sind (Activ
ve=false). D
D.h. wenn eiiner diese
ToolTipps abgeschaaltet hat, steh
ht auch nichhts in der Sttatusleiste.
Kurs 4 weite
ere Kom
mponentten
ToolS
Strip
Start dieeses Kursess mit leerer neuer
n
Anweendung.
Will maan auch einee ToolBar wie
w z. B. in W
Word haben
n, so ist dass leicht mögglich. Ich haab sie im
unteren Bild mal inn der ersten Zeile hinzuugefügt. Siee ist aber verraltet. Modeerner ist diee
Komponnente ToolS
Strip. Wir fü
ügen sie hinnzu.
Dort kannn man (sieehe jetzt im Bild in der zweiten Zeeile) mit hüb
bschen Verllaufsfarben ein
modernnes Design bekommen.
b
Von links nnach rechts sichtbar diee Möglichkeeiten der Ellemente:
toolStrippButton (noormale Tastte wie Toolbbar, jedoch ohne ImageeList- Mögllichkeit, son
ndern mit
Einzelbildchen), tooolStripLabeel für Textaausgabe / Beeschriftungeen, dann tooolStripSplitB
Button
und toolStripDropD
DownButton
n, mit denenn man ein Menübaum
M
designen
d
unnd öffnen kaann. Den
ht erkannt, eerscheint miit identischeer Funktion.. Dann sind
d noch
Unterscchied hab ichh noch nich
toolStrippTextBox und toolStrip
pProgressB
Bar möglich mit entspreechender Fuunktion. Da ist XP –
und Vissta- Design leicht möglich. Hinzu kkommt einee ComboBo
ox- Möglichhkeit.
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 29
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Beim H
Hinzufügen von
v Images zwei Hinw
weise: Zum Einen
E
muss die Bildgrööße passend
d sein zur
Bildgröße Imagesizze in der To
oolStrip- Koomponente, dann solltee sie als pngg oder gif mit
m
transparrenter Außeenfarbe verssehen werdeen.
Zum annderen musss man sich überlegen,
ü
oob diese Bild
dchen nichtt bei größereen Projekten
mehrfacch Verwenddung finden. Dann solltte man sie in
n die „Projeektresourcenndatei“ ein
nfügen
und stehht dann überall im Projekt zur Verrfügung. Naach Klick au
uf eigenschaaft „Image““ des
Buttonss dann so:
TabCo
ontrol
Mit der
TabConntrol- Kompponente kön
nnen Sie in eeinem Fenster die Oberrfläche mehhrfach nutzeen. Das
Umschaalten geschiieht wie in einem
e
Karteeikasten. So
o kann man solche Obeerflächen wiie in
typischeen Windowsprogramm
men program
mmieren.
Also auus dem Folder Containeer eine TabC
Control auf das Formullar ziehen. N
Normalerweeise wird
diese Komponente nach unten
n gedockt. D
Damit autom
matisch bei Fenstergrößßenänderun
ng die
einzelneen Elementee sich vernü
ünftig mit änndern, solltee man folgeende Strateggie anwendeen (hab
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 30
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
noch einn Panel als reservierte
r
Fläche
F
für T
Tasten oderr andere Elemente auf ddas Formulaar
gezogenn):
Oben ToolBar
auf To
op, dann
ToolS
Strip auf
1. Dock = Top
T
Top, dann
d
2. Dock = Top
Panell (eigener
Contaainer aus
33. Dock = Top
T
„Conttainers“)
wiedeer Top,
der kllebt dann
unter dem
ToolS
Strip.
Dann
n
StatussStrip auf
5. Dockk = Fill
Bottom
m und
zum Schluß
S
44. Dock = Bottom
B
TabC
Control auf
Fill.
Nun wieder
w
zurück zur
TabC
Control.
Neue Paages werdenn mit rechteem Mausklicck PopUp
UpMenu erzeeugt, dort „R
Registerkarrte
hinzufüggen“. Bitte jetzt
j
mal 7 neue
n
Pages erzeugen. Diese
D
heißeen automatissch tabpagee1 bis 7.
Jetzt achhte man darrauf, wie maan einzelne Pages im ID
DE anwähltt. Erst Klickk auf den Anfasser
A
(Tab), ddann ist aberr die TabCo
ontrol angew
wählt. Dann
n nochmal unten
u
auf diie Seite klicken. Man
achte auuf die weißeen kleinen Punkte.
P
Erstt dann ist diie Page selek
ktiert (Konttrolle im
Eigenscchaftenfenstter).
TabControl selektieert
Multilinne = false
Page seleektiert
Multiline
M
= true
Reicht ddie Seitengrröße für allee Pages nichht aus, so errscheinen diie von anderren Anwend
dungen
gewohnnten beiden Pfeile zur Verschiebun
V
ng der Anfaasser. Will man
m bei zu eengem Platzz mehrere
Zeilen ffür die Anfaasser vorseh
hen, so setzee man in derr TabControl (erst seleektieren!) diie
Eigenscchaft MultiL
Line auf truee.
Hier müüssen Imagees per ImageList ergänzzt werden, die
d Auswah
hl der Icons in den einzzelnen
Seiten w
wieder mit der
d Eigensch
haft ImageIIndex. Also vorher einee ImageListt auf die Forrm ziehen
und mitt einer Listee von Bildch
hen füllen. D
Die Größe der
d Icons in ImageList einstellen.
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 31
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Komp
ponenten
n zur Gru
uppierun
ng und Se
elektion
Jetzt solllen Kompoonenten zur Gruppierunng und Seleektion gezeig
gt werden.
Wir függen auf tabP
Page1 hinzu
u (alles Stanndard):
1 Gro
oupBox
1 Pan
nel
Auf taabPage1 3**RadioButto
on1-3
Auf groupBox1
g
3*RadioBu
utton4-6
Auf das
d Panel3** RadioButto
on7-9
Beweegt man nunn einen „Con
ntainer“,
z. B. das Panel, ddann beweg
gen sich
mente
die daarauf befinddlichen Elem
mit. Zuordnung
Z
ggeht mit
Hinen
nschieben,
Die CheckBox-e
C
en lassen ein
ne
einzelne Auswahhl zu. Ob an
ngewählt
C
zu sehen.
oder niccht, ist in Eiigenschaft Checked
Die RaddioButton haben
h
auch eine Eigensschaft Checkked, jedoch gilt hier: auuf einem Co
ontainer
kann nuur immer einn RadioButtton angewähhlt sein. Wäählt man ein
n anderes, w
wird automaatisch der
andere ddeselektiert. Dieser Zusammenhanng besteht nicht
n
zwisch
hen RadioBuuttons anderer
Containner, wodurchh der nützliche Sinn deer Containerr wohl hier zu erkennenn ist.
Panel uund GroupB
Box untersch
heiden sich eeigentlich nur
n in der Überschrift dder GroupBo
ox. Das
Ausseheen des Randdes von Pan
nel kann maan leider niccht gleich deem der GrooupBox macchen, dann
nehme m
man halt einne Group- Box
B und lössche die Besschriftung in
n Text.
Auf tabP
Page2 weittere Selektio
onsmechaniismen:
Weiteree Selektionsskomponentten sind ListtBox, Comb
boBox aus Standard
S
unnd CheckLisstBox aus
„Allgemein
„
ne Steuerelem
mente“.
Alle
A drei Koomponenten
n
enthalten
e
alls Textinhalt eine
Collection
C
ooder „Auflisstung“
namens
n
Item
ms. Alle Fun
nktionen,
die
d mit Colllections getan
werden
w
könnnen, sind au
uch hier
möglich
m
(daazu siehe sp
päteres
Kapitel).
K
Füüllen der ein
nzelnen
selektierbaren Zeileen mit dem Collectioneeditor im
Eigenscchaftenfenstter unter Items. Hier maal ein paar Zeilen
Z
Quatschhtext in alle drei Komponenten einngeben.
Bei der ComboBoxx sieht man das selektieerte Elemen
nt oben im EditE
Feld. E
Es benötigt nur
wenig Platzz, man muss es halt miit einem
zusätzlicheem Mausklicck aufmachhen.
Bei der LisstBox sieht man
m alle M
Möglichkeiten, wenn
die Kompo
onente groß genug ist. SSonst gibt es
e einen
Scrollbalkeen. Mit der Eigenschaft
E
ft Sorted=tru
ue lassen
sich die Ein
nträge alphaabetisch sorrtieren. Wen
nn
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 32
Visuelle Programmierung mit C#
Prof. Dr. Bayerlein
SelectionMode auf One steht, dann kann man nur ein Element selektieren. Bei MultiSimple
wird jede Zeile selektierbar und die Selektion toggelt, bei MultiExtended selektiert man wie
beim Explorer gewohnt, die Shift und Strg- Tasten sind dann auch möglich.
Die Abfrage, welche Zeile selektiert ist, kann man mit der Eigenschaft SelectedIndices[]
durchführen. Es ist eine Eigenschaft vom Typ int- Array und ist im Eigenschaftenfenster nicht
zu sehen. Jede Zeile startet bei Nr. 0. Ist z.B. Zeile 3 selektiert, dann ist der Wert von
SelectedIndices.Count gleich 1 und in SelectedIndices[0] steht die Nummer der Zeile, also
2. Dieses mache man sich deutlich mit folgendem einfachen Code in dem Ereignis
SelectedValueChanged.
private void listBox1_SelectedValueChanged(object sender, EventArgs e)
{
label1.Text = listBox1.SelectedIndices[0].ToString();
label2.Text = listBox1.SelectedIndices.Count.ToString();
}
In label1 wird die Nummer der ersten selektierten Zeile und in label2 die Anzahl der
selektierten Zeilen dargestellt.
Die CheckListBox ist ähnlich, nur man sieht vor jeder Zeile ein CheckBox- Feld. Diese kann
man wie bei einer CheckBox bei jedem Klick toggeln. Abfrage nun allerdings über
CheckedIndices[], auch hier ein Int Array mit den Zeilennummern. Auch ein kleines Programm
dazu: Nur wenn die dritte Zeile einen Pfeil trägt, ist die Farbe der tabPage rot, sonst
weiß.Code:
private void checkedListBox1_SelectedIndexChanged(object sender, EventArgs
e)
{
if ((checkedListBox1.CheckedIndices.Count==1)&&
(checkedListBox1.CheckedIndices[0] == 2))
tabPage2.BackColor=Color.Red;
else tabPage2.BackColor=Color.Transparent;
}
Der Zugriff auf den Text der Zeilen geht mit .Items[0] wie bei einem Array, die Nummer wird
einem NumericUpDown der Eigenschaft Value entnommen :
label2.Text = listBox1.Items[(int)numericUpDown1.Value].ToString(); label3.Text = checkedListBox1.Items[(int)numericUpDown1.Value].ToString(); Bei der CheckListBox kann man das Kästchen mit folgendem Befehl direkt setzen (true) oder
zurücksetzen (false):
checkedListBox1.SetItemChecked((int)numericUpDown1.Value, true); Abfragen mit
checkedListBox1.GetItemChecked((int)numericUpDown1.Value) liefert bool- Wert zurück.
Ergebnis: Siehe Kurs4# weitere Kompos.
File: Kurs MS10C# Bayerlein4.6.docx
Seite 33
Visuelle Programmierung mit C#
Prof. Dr. Bayerlein
Kurs5 Textverarbeitung mit Stringlisten
Das Visual C# - Entwicklungswerkzeug verfügt über mächtige Objekte zur Textverarbeitung.
Diese sind teilweise einfach aus der Verwandtschaft zu Borland entstanden. Ansi-C kennt nur
die Zeichenketten in Form von Char- Arrays, Textverarbeitung damit wird sehr mühsam.
Zum Start dieses Kurses öffnen Sie bitte eine neue Applikation und fügen eine TabControl
hinzu, Dock=Bottom, dann 4 pages hinzufügen. Namen alle so lassen. Abspeichern, bei mir
heißt diese „Projektmappe“ WindowsApplication14.
Der Typ String
Auf der ersten Seite TabPage1 werden zum Testen einiger Stringeigenschaften 8 Label
untereinander plaziert. Mit Doppelklick auf Label1 eine Click-Event-Funktion erzeugen, in der
einiges gemacht werden soll. Die Tooltip- oder Text- Eigenschaften der Komponenten sind
auch Eigenschaften vom Typ string. Will man eigene Variablen deklarieren, so verwende man
den Typbezeichner string (wohlgemerkt mit kleinem s!), String gibt es auch, ist Name der
Klasse!).
Als erstes folgende Zeilen in diese label1Click() eingeben, grüner Text kann natürlich weg,
dient nur zur Info, was nicht geht.
private void label1_Click(object sender, EventArgs e)
{
//char a[20]="12345678901234567890"; funktioniert in C# nicht
char[] a ={ '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2' };
string b = new String(a);
label1.Text=b; // ...=a; // ...=a.ToString(); funktioniert nicht
String...
}
Es wird in der ersten Zeile ein Char-Array deklariert und initialisiert. In der zweiten Zeile wird
dieses Array dem String b zugewiesen. Erst dann kann man diese Zeichenkette nach Text von
Label1 zuweisen.
Die Zuweisung anders herum geht allerdings so nicht. Versucht man dem char- Array einen
String zuzuweisen, geht es schief, da "a" ein Zeiger ist. Diese Zuweisung geht nur mit der
Methode ToCharArray etwa so:
a = b.ToCharArray();
Der ganz große Nachteil von Char- Arrays in Standard herkömmlichen C ist die statische
Größe. Das ist jetzt in C# anders. Das Char- Array wird mit dynamischer Größe gemanaged!!!
Siehe dazu folgender Code:
Die Länge eines Strings wird auch dynamisch verwaltet. Er kann beliebig lang sein. Beispiel:
Eine Schleife addiert immer 20 Zeichen hinzu. Der Operator „+“ ist ein einfacher
Verkettungsoperator, der zwei Strings zu einem neuen einfach verknüpfen kann. Folgender
Code liefert folgendes Ergebnis:
char[] a ={ '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2' };
string b = new String(a);
label1.Text=b; // ...=a; // ...=a.ToString(); funktioniert nicht
a = b.ToCharArray();
label2.Text = "dies ist ein probetext";
label3.Text = b + "geht dies auch?";
for (int i = 0; i < 1000; i++)
label4.Text = label4.Text + b;
label5.Text = label4.Text.Length.ToString();
File: Kurs MS10C# Bayerlein4.6.docx
Seite 34
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
a = la
abel4.Text
t.ToCharAr
rray();
label6
6.Text = a.Length.T
a
ToString()
);
D
Der String b mit 12
Zeeichen wird
d 1000
m
mal zu label4
4.Text
hiinzuaddiert,, dieser
haat anschließ
ßend (mit
Leength ) erm
mittelt
122006 Zeicheen.
A
Anschließend
d wird
laabel4 in das CharA
Array kopiert, auch
nn die
diieses hat dan
122006 Zeicheen.
Wichtigge Methodenn der String
gs sind nochh .Substring
g(x,y), wobei hier ein Teeilstring als
Ergebniis herauskom
mmt mit Staartzeichen bbei x anfang
gend mit 0 und
u Länge yy. Also liefeert
label7.
.Text = la
abel2.Text
t.Substrin
ng(13, 5);
als Ergeebnis das Wort
W “probe””. Die Methhode IndexO
Of(„suchstrin
ng“) kann ddie Position eines
Teilstrinngs suchen. So liefert die
d Zeile
label8.
.Text = la
abel2.Text
t.IndexOf(
("probe").ToString();
die Zahll 13, da in label2
l
der Teilstring
T
„pprobe“ bei Zeichen
Z
13 beginnt.
b
Weiteree Methoden finden Sie in der Hilfee: Cursor au
uf das Wort string, dannn F1:
ToLoweer() ersetzt alle
a Großbu
uchstaben duurch kleine
ToUppeer() dito durrch Großbucchstaben
Replacee() ersetzt eiinen Teilstrring.
Fazit strrings: niem
mals wieder sich mit Chhar-Arrays herumquäle
h
n.
Der m
mehrzeilig
ge Text
Die StriingList direkkt wie bei Borland
B
gibtt es in C# oder
o
.NET nicht. Aber äähnliche Strrukturen
sind mööglich. So giibt es die Klasse
K
Collecctions, die als
a Collectio
on beliebigeer Typen arrbeiten
kann, allso auch fürr strings. Daann sind einne Vielzahl von
v Method
den möglichh wie Insertt(),
Removee() Containss() Clear() usw.
u
Man kkann es dann
n einfach alss ein dynam
misch verwaaltetes
Array vvon AnsiStriings betrach
hten. Jede Z
Zeile dieser Collection ist
i wieder eein beliebig langer
String m
mit allen Meethoden wiee oben beschhrieben. Ab
b .NET V3 gibt es auchh die ArrayList mit
ähnlicheen Methodeen und Eigenschaften. M
Man kann aber
a
auch einfach ein SStringarray benutzen:
b
string[] abc = new
w string[5]
]; Nur ist ddie Anzahl der Elemen
nte dann fesst auf 5 und kann nicht verändert w
werden.
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 35
Visuelle Programmierung mit C#
Prof. Dr. Bayerlein
Besser wäre dann die Collection:
Collection<string> strcoll = new Collection<string>();
Fügt man diese Zeile in C# ein, so kennt es erstmal das Schlüsselwort Collection nicht, es ist
schwarz. Dann kann man aber mit rechtem Mausklick „Auflösen“ wählen und er fügt
automatisch die fehlende using hinzu, in diesem Fall using System.Collections.ObjectModel; Hinzufügen eines Elementes mit : strcoll.Add("12345"); Zugriff wie Array mit label2.Text = strcoll[(int)numericUpDown1.Value]; Die Größe wird dynamisch verwaltet.
Nun zu Komponenten mit mehrzeiligem Text:
Die TextBox wird mehrzeilig, wenn man die Eigenschaft Multiline auf true stellt. Wir ziehen
eine textBox auf tabPage2, und ein RichTextBox auf tabPage3 und setzen beide Dock=Fill.
Schauen wir uns zuerst einmal textBox1 an. Einige wichtige Eigenschaften:
 ->ReadOnly bestimmt, ob der User Text verändern kann (false) oder nur angezeigt wird
(true)
 ->Font bestimmt Schriftart Farbe etc
 ->ScrollBars bestimmt, ob diese vorhanden sind. Es sollte immer eine Vertikale
ScrollBar eingestellt werden
 ->WordWrap, wenn true, dann werden längere Zeilen umgebrochen, sonst
verschwinden sie rechts, sind mit Scrollbar aber zu erreichen: ich würde immer auf false
stellen, dann bleiben die Zeilenumbrüche von Originaltexten erhalten.
 Maxlength, steht defaultmäßig auf 32767, begrenzt die Anzahl der Zeichen des Users
auf diese Zahl. Sollte auf 0 stehen, dann ist die Grenze bei 2^32 = 4GByte Zeichen.
Die Vorbelegung des Textbereiches geschieht per Eigenschaftenfenster bei der Eigenschaft
Lines. Damit öffnet sich ein Texteditor zum Eingeben des Starttextes.
Wichtig zu wissen: Der Inhalt wird immer in einem einzigen string, nämlich Text gespeichert.
Ruft man die Eigenschaft .Lines auf, so wird intern der Einzelstring in ein Textarray
umgebrochen, was bei großen Texten sehr zeitraubend sein kann. Will man oft auf große Texte
per Lines zugreifen, dann am Besten vorher einmalig einen Umbruch erzwingen und dann auf
das lokale Textarray zugreifen:
string [] LocalArray = textBoxRadius.Lines; Wird der Text verändert, muss man dieses natürlich wiederholen.
Für das Programm in diesem Kurs sind zum Laden und Speichern noch zwei Dialoge wichtig:
in Dialogs findet man die Komponenten OpenDialog und SaveDialog. Bitte jetzt zwei Tasten
oben auf die Form, Name Load und Save. Dann die beiden Dialoge hinzufügen.
In der Click- Funktion von Load folgt jetzt der Standard- Code zum Öffnen von DateiAuswahl- Boxen, die dem üblichen Windows- Design entsprechen:
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{ // ………. Öffnen der Datei, Einlesen Abspeichern etc
}
Die Methode ShowDialog() öfffnet das typische Auswahlfenster. Nur wenn der User auf die
OK- Taste klickt, wird die Aktion ausgeführt, bei Taste Abbruch nicht.
Das Laden einer Text-Datei in die Textbox geschieht nun über die Klasse StreamReader mit
folgendem Code: (vorher oben mit using…):
using System.IO;
StreamReader myStream1 = new StreamReader(openFileDialog1.OpenFile());
textBox1.Text = myStream1.ReadToEnd();
File: Kurs MS10C# Bayerlein4.6.docx
Seite 36
Visuelle Programmierung mit C#
Prof. Dr. Bayerlein
myStream1.Close();
Mit der Methode ReadToEnd() wird dann der Textinhalt der Datei (muss eine ASCII sein) in
die textBox eingelesen. Problem mit dem Text gibt es allerdings mit den deutschen
Sonderzeichen ü, ö ä ß, die einfach ausgelassen werden. Dieses kann man verhindern, wenn
man die Instanziierung nach new mit folgender Ergänzung durchführt:
…new StreamReader(openFileDialog1.OpenFile(),Encoding.Default);
Tipp: Bei großen Texten dauert insbesondere das “scrolling“ der sich füllenden textbox sehr
lange, besser vor Einlesen Textbox Visible auf false, danach wieder auf true. Geht so viel
schneller.
Abspeichern mit der Save- Taste geht so:
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
StreamWriter myStream1 = new
StreamWriter(saveFileDialog1.OpenFile(),Encoding.Default);
myStream1.WriteLine(textBox1.Text);
myStream1.Close();
}
Die Dialoge sollten noch etwas angepasst werden: im openDialog1 folgende Eigenschaften
setzen:
Auf jeden Fall sollten die Filter gesetzt werden, z. B. so wie links. Immer sollte ein Filter
„Alle“ mit *.* dabei sein, damit man immer sehen kann, was alles auf dem Verzeichnis
vorhanden ist. Die Syntax ist: (*Bezeichner*)|*.xxx|(*Bezeichner*)|*.yyy usw. Also für Text
und C#- Files z. B.
Filter=Text|*.txt|C#|*.cs|All|*.*.
In InitialDir kann das Startverzeichnis gewählt werden, in Title die Überschrift der
FileSelectBox und in FileName der voreingestellt Name.
Ganz wichtig in der SaveDialog- Komponente ist DefaultExt, die den Suffix bestimmt, wenn
der User keinen eintippt. Dort sollte also immer .txt stehen, dann wird die Datei ohne Angabe
eine txt- Datei.
Ganz wichtig: der OverwritePrompt in Options sollte immer auf true gestellt werden, damit
der User vor Überschreiben gewarnt wird.
label9.Text = "Char= "+textBox1.Text.Length.ToString();
label10.Text = "Lines= " + textBox1.Lines.Length.ToString();
Mit den beiden oberen Zeilen werden sowohl Anzahl der Zeichen in Label9 und Anzahl der
Zeilen in Label10 ausgegeben. Lenght ist eine Eigenschaft vom typ int.
Man kann jetzt einzelne Zeilen erreichen durch Ansprechen der Eigenschaft Lines in der
Textbox.
Dabei benutzt man die Array- Indizierung mit [ ]. Folgender Code liest die Zeile in eine zweite
textBox2, dessen Zeilennummer startend mit Null von einem numericUpDown eingestellt wird.
Um Zugriffsfehler zu vermeiden, sollte vorher immer der Maximalwert des UpDown auf die
Zeilenzahl -1 gestellt werden.
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
numericUpDown1.Maximum = textBox1.Lines.Length-1;
File: Kurs MS10C# Bayerlein4.6.docx
Seite 37
Visuelle Programmierung mit C#
Prof. Dr. Bayerlein
textBox2.Text = textBox1.Lines[(int)numericUpDown1.Value];
}
Die textBox kann nur alle Zeichen mit einen einzigen Font darstellen, die RichTextBox
dagegen lässt Formatierungen für jedes einzelne Zeichen zu.
Nun noch ein bisschen Textverarbeitung:
Sortieren
Es sollen alle Zeilen alphabetisch sortiert werden. Nun lässt die Textbox dies direkt nicht zu.
Also muss man den Umweg über z.B. die Listbox machen, die kann sortieren. Eine Collection
leider auch nicht. Damit das nicht sichtbar wird, kann man die Listbox mit Visible=false
unsichtbar machen. Und natürlich in der Listbox die Eigenschaft Sorted=true.
Source hinter einer Taste Sort:
1 listBox1.Items.Clear();
2 for (int i = 0; i < textBox1.Lines.Length; i++)
3
{
4
label10.Text = "Lines= " + i.ToString();
5
listBox1.Items.Add(textBox1.Lines[i]);
6
Application.DoEvents();
7
}
8 textBox1.Clear(); textBox1.Visible = false;
9 for (int i = 0; i < listBox1.Items.Count-1; i++)
10
textBox1.AppendText(listBox1.Items[i] + "\x0d" + "\x0a");
11textBox1.AppendText(listBox1.Items[listBox1.Items.Count - 1].ToString());
Kommentar dazu:
Zeile 1: Zwischenspeicher Listbox leeren.
Zeile 2: for- Schleife zum Umschaufeln und gleichzeitigem Sortieren
Zeile 4: Fortschrittsanzeige, sinnvoll bei langen Texten, dann dauert es sehr lange
Zeile 5: Umschaufeln
Zeile 6: Dieser Befehl arbeitet alle Ereignisse ab, die während der Schleife auflaufen. Damit
wird auch ein Neuzeichnen des label10 erzwungen, sonst würde man den Fortschritt nicht
sehen.
Zeile 8 Start Zurüchschaufeln mit Leeren. Gleichzeitig wird die Textbox unsichtbar gemacht,
um das sehr zeitaufwendige Scrollen zu vermeiden.
Zeile 9: Schleife zum Zurückschaufeln
Zeile 10: Zurückschaufeln, leider hat Textbox kein .Add(), geht nur mit TextAppend, dann
muss aber Zeilenende mit CR und Linefeed per Escape Sequenz programmiert werden.
Zeil1 11: Die letzte Zeile des Textes soll kein Linefeed bekommen.
Leerzeilen weg
Code hinter einer Taste mit Namen „Leerzeilen weg“. Es wird als Zwischenspeicher hier mal
eine „Collection“ benutzt. Ginge aber auch mit Listbox wie oben.
Collection<string> strcoll = new Collection<string>();
for (int i = 0; i < textBox1.Lines.Length; i++)
if (textBox1.Lines[i].Length > 0) strcoll.Add(textBox1.Lines[i]);
textBox1.Clear();// copy Back to Textbox
for (int i = 0; i < strcoll.Count - 1; i++)
textBox1.AppendText(strcoll[i] + "\x0d" + "\x0a");
textBox1.AppendText(strcoll[strcoll.Count - 1]); // last line
File: Kurs MS10C# Bayerlein4.6.docx
Seite 38
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Größe
e von StrringListe
en
Die Grööße ist im Prrinzip nichtt begrenzt. W
Wir fügen Taste
T
hinzu, die textBoxx1 über
ListBoxx1immer verrdoppelt. Allso kopiere textbox1 naach Listbox1
1 und zurücck ohne zu sortieren
s
und Texxtbox zu leeeren. Anzeig
ge der Zeileen in Label9
9 und der Zeeichenzahl iin Label10:
listBox
x1.Items.C
Clear(); listBox1.S
l
Sorted = false;
s.Length; i++)
for (in
nt i = 0; i < textB
Box1.Lines
{
i.ToString();
l
label10.Te
ext = "Lin
nes= " + i
.Lines[i]);
l
listBox1.I
Items.Add(
(textBox1.
A
Applicatio
on.DoEvent
ts();
}
textBox
x1.Visible
e = false;
;
for (in
nt i = 0; i < listB
Box1.Items
ms.Count - 1; i++)
t
textBox1.A
AppendText
t(listBox1
1.Items[i] + "\x0d
d" + "\x0a
a");
textBox
x1.AppendT
Text(listB
Box1.Items
ms[listBox1.Items.Count - 1] .ToString
g());
textBox
x1.Visible
e = true;
label9.
.Text = "C
Char= " + textBox1.
.Text.Length.ToString();
x1.Lines.Length.ToString();
label10
0.Text = "Lines=
"
" + textBox
Beschleeunigen eventuell mit
string [] LocalArr
ray = textB
BoxRadius.L
Lines; TextBoxx und RichT
TextBox speiichern den T
Text in eineem
String[]] Array nam
mens .Lines. Es gibt zw
war eine
Methodde .CopyTo()
(), aber der Befehl
B
textBox
x1.Lines.C
CopyTo(ric
chTextBox1
1.Lines, 0);
wird ohhne Fehler kompiliert,
k
aber
a
es passsiert nicht daas erwartetee Kopieren, sondern nichts!!.
ListBoxx hat seine String
S
in Item
ms, das scheeint eine
Collection zu
z sein. Dortt gibt es einne CopyTo())
String C
– Methoode, sie funkktioniert ab
ber nicht so w
wie man daas als User wünscht.
w
Collect
tion<strin
ng> strcol
ll = new C
Collection<string>();
;// syntax error
listBox
x1.Items.C
CopyTo(str
rcoll, 0);
wird miit einer Fehllermeldung abgebrocheen und nich
ht kompiliert. Wieso niccht??
Noch eiin Tip, wie man
m herausbekommt, w
welche Usin
ng – Anweisung nötig iist. Gibt maan die
oberste Zeile mit „C
Collection““ ein, so ist ddas Wort zu
unächst schw
warz, da diee nötige Usiing –
Anweisuung fehlt. Mit
M Rechtsk
klick auf dass Wort kann
n man im Po
opUp unter „Auflösen““ die
passendde using- Annweisung „S
System.Col lections.Ob
bjectModel““ automatiscch hinzufüg
gen lassen.
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 39
Visuelle Programmierung mit C#
Prof. Dr. Bayerlein
Leider auch hier: eine Kopiermethode wie AddStrings oder meinetwegen auch CopyTo() von
String[] Array nach Collection gibt es nicht. Dabei sind die Daten einfach nur mehrzeilige
Texte.
Wörter zählen
Noch ein Codebeispiel, das oft nützlich ist: das Auffinden von Teilstrings. Damit kann man
z.B. zählen, wie oft ein Wort in einem Text vorkommt. Dazu ist die Methode .Substring(a,b)
der Strings noch zu beschreiben. Sie liefert einen String zurück, der im Ausgangsstring bei
Buchstabe an Position a (Start von Null) beginnt und b Zeichen enthält. Also nach Ausführung
folgenden Codes
label2.Text = "dies ist ein probetext";
label7.Text = label2.Text.Substring(13, 5);
steht in label7 das Wort “probe”. Ein Zeilenumbruch in Text sind zusätzlich noch einmal 2
Zeichen (\n\r).
Hinter der Taste z.B. „Item Search“ steht folgender Code, der in Textbox1 nachzählt, wie oft
dort der Begriff vorkommt, der in Textbox2 steht.
string item = textBox2.Text;
int len=item.Length;
int cnt = 0;
for (int j = 0; j < textBox1.Text.Length-len+1; j++)
if (textBox1.Text.Substring(j, len) == item) cnt++;
label9.Text = "Hits= " + cnt.ToString();
Das dauert aber leider bei großen Texten sehr lange. Sucht man in Bibel.txt (Auf ftp bei mir zu
finden) nach dem Wort „Gott“, so dauert es Stunden.
Etwa 5 sec dauert gleiche Suche mit folgendem leicht modifiziertem Programm:
string item = textBox2.Text;
string text = textBox1.Text;
int len=item.Length;
int textlen=text.Length-len+1;
int cnt = 0;
for (int j = 0; j < textlen; j++)
if (text.Substring(j, len) == item)
{
cnt++;
label9.Text = j.ToString();
label10.Text = cnt.ToString();
Application.DoEvents();
}
label9.Text = "Hits= " + cnt.ToString();
In der Schleife mit dem ca 4,6 Millionen Zeichen der Bibel wird nur in einem einfachen string
gesucht. Dauert bei meinem Lap ca. 5s.
Eine andere Alternative ist die Methode .IndexOf(a,b), die sehr schnell ist. Außerdem sind jetzt
die Ausgaben in die Label, die auch sehr zeitintensiv sind, weg. Neue for- Schleife:
for (int j = 0; j < textlen; j++) { startindex=text.IndexOf(item,j); if (startindex >=0) { cnt++; j = startindex+1; } File: Kurs MS10C# Bayerlein4.6.docx
Seite 40
Visuelle Programmierung mit C#
Prof. Dr. Bayerlein
} Jetzt merkt man die Rechenzeit kaum.
Alle diese Teilprogramme sind in dem Verzeichnis Kurs 5# Strings zu finden.
Kurs 6 Projekt Diashow
Ehemals früher als Hausaufgabe, jetzt als Projekt1 wollen wir ein Programm schreiben, das aus
einer Serie von Fotos (JPG, gif, Png in einem beliebigen Verzeichnis) in einer Diashow
darstellen.
Dazu braucht man als erstes einen Zugriff auf das Filesystem des Rechners. Dazu sind
Komponenten nützlich, die auch in Visual Basic benutzt wurden. Diese sind nicht Standard in
der Toolbox und man muss sie erst aktivieren. Das geht über das Menü „Extras 
Toolboxelemente auswählen“. Im kleinen Check-Kästchen markieren: FileListBox, DirListBox
und DriveListBox. Sie sind zwar schon etwas altbacken, aber die notwendigen Funktionen für
unseren Zweck stellen sie zur Verfügung. Meines Wissens will .NET diese Komponenten nicht
mehr unterstützen, es gibt aber auch keine Alternative: Danke liebe MS-Informatiker!
Die Plazierung der Komponenten soll jetzt so geschehen, dass ein automatisches Resizing
erfolgt, und der User selbst die Aufteilung noch mit der Maus per Splitter verändern kann. Also
folgendes Vorgehen ist zu tun:
FileListBox auf neue Seite eines TabControl, Dock=Left.
Dann Komponenten Splitter (Alle Windows Forms), voreingestellt ist schon passende
Dock=Left.
Mit einem Panel den Rest der Seite mit Dock=Fill ausfüllen.
Auf dieses Panel dann eine DirListBox plazieren, Dock=Top. Darunter auf das Panel dann die
Komponente DriveComboBox.
Die drei File- system- Kompos müssen noch verbunden werden. Das geht leider nicht mehr wie
bei Borland mit einfachem Setzen der Eigenschaften im Eigenschaftenfenster, sondern nur
noch programmiert z. B. in dem Ereignis Form_Activated. Warum einfach, wenn es auch
komplizert geht: Danke MS- Informatiker!
In dem Ereignis
private void driveListBox1_TextChanged(object sender, EventArgs e)
{
dirListBox1.Path = driveListBox1.Drive;
}
schreibt man das gewählte Laufwerk (es heißt nicht drive, sondern path!) nach dirListBox.
Um jetzt die Dateien im selektierten Verzeichnis darzustellen, muss man wieder tricksen. Die
Komponente dirListBox liefert zwei Informationen: in .Path den geöffneten (nicht selektierten
Path) und in .Text den selektierten Text ohne Pfadangabe. Daraus kann man dann mit
folgendem Programm im Ereignis den selektierten Pfad errechnen und nach fileListBox
schreiben. Man hat ja sonst nichts zu tun. Warum sollten die Informatiker auch diese
Information gleich fertig zur Verfügung stellen. Man muss dann eben schnell folgendes
Programm schreiben:
privatevoid dirListBox1_SelectedValueChanged(object sender, EventArgs e)
{
// in Text appears text of the selected line
// in path appears the open path. the selected path can now be constructed:
// if I select a path under open path: selpath=Path+/+Text
// if I select a path above open path: selpath= find pos of text, delete
// after text.
string selpath;
int pos=dirListBox1.Path.IndexOf(dirListBox1.Text);
File: Kurs MS10C# Bayerlein4.6.docx
Seite 41
Visuelle Programmierung mit C#
Prof. Dr. Bayerlein
//pos is Position of text, if -1 not found
if (pos < 0)
selpath = dirListBox1.Path + "\\" + dirListBox1.Text;
else
selpath = dirListBox1.Path.Substring(0, pos + dirListBox1.Text.Length);
fileListBox1.Path = selpath;
}
Will man an die Daten in der FileListBox drankommen, so geht das mit der Eigenschaft Items.
Folgende for- Schleife kopiert alle Dateien in eine TextBox:
for (int i=0;i<fileListBox1.Items.Count;i++)
textBox1.AppendText(fileListBox1.Items[i].ToString()+ "\x0d" + "\x0a");
Jetzt soll ein kleines Vorschaufenster programmiert werden. Wenn man auf eine Datei in
fileListBox1 klickt, soll in einer PictureBox eine Bildvorschau zu sehen sein. Also Plazieren
eines PictureBoxauf die Seite mit den obigen Komponenten. Größe 100*100 Pixel.
In fileListBox1.SelectedItem steht die Nummer der selektierten (blau eingefärbten) Datei. Jetzt
kann man in einem Event FileListBox1Click diese Bilddatei nach PictureBox1laden. Syntax:
string fn = fileListBox1.Text; // selected Line
int len=fn.Length;
string ext = fn.Substring(len - 4, 4).ToLower();
if ((ext == ".jpg") || (ext == ".png") || (ext == ".bmp"))
{
pictureBox1.Load(fileListBox1.Path + "\\" + fn);
}
es wird zuvor abgefragt, ob es sich um eine Bilddatei handelt. Die Methode .ToLower()
wandelt alle Großbuchstaben in kleine um. Der Substring- Befehl schneidet die letzten vier
zeichen heraus.
Der Dateiname wird mit fileListBox1.Text ausgelesen. Mit der Methode Load kann eine
Bilddatei vom Typ *.ico, *.bmp oder *.jpg in die pictureBox1 gelesen werden.
Die Bilder werden jetzt alle nur mit 100*100 Pixel angezeigt, man sieht nur einen Ausschnitt.
Das ganze Bild sieht man mit der Eigenschaft pictureBox1->SizeMode=StrechImage;
Die Originalbildgröße kann mit
label1.Text = pictureBox1.Image.Height.ToString();
label2.Text = pictureBox1.Image.Width.ToString();
in zwei Label dargestellt werden. Das Bild ist zwar in pictureBox1gestaucht, aber im Speicher
noch in Originalgröße erhalten.
Will man jetzt noch das Seitenverhältnis erhalten, dann stelle man die Eigenschaft „SizeMode“
der pictureBox1 auf Zoom.
Will man jetzt noch bei Verstellung der Selektion mit den Up- oder Down- Tasten ein neues
Bild sehen, dann wähle man in den Ereignissen der fileListBox1 „SelectedIndexChanged“ die
schon existierende Ereignisfunktion fileListBox1_Click. Testen Sie das Ergebnis. Wenn jetzt
eine Bilddatei gewählt ist, wird sie in pictureBox1 angezeigt. Wenn man mit den Pfeiltasten die
Selektion hoch und herunterbewegt, wird jeweils das aktuelle Bild angezeigt. Lädt man
allerdings eine Datei mit einer anderen als der erlaubten Endung, passiert natürlich nichts.
Siehe fertiges Programm in Kurs 6# Prepare HW1.
File: Kurs MS10C# Bayerlein4.6.docx
Seite 42
Visuelle Programmierung mit C#
Prof. Dr. Bayerlein
Projektaufgabe 1 Diashowprogramm
Schreiben sie jetzt ein Programm, dass alle Dateien aus dem gewählten Pfad in entweder
einstellbarer Zeit (mit einem Timer und mit in einem numericalUpDpwn- wählbaren Sekunden)
oder auf Mausklick hintereinander endlos möglichst groß (also in einem neuen Formular)
anzeigt. Abbruch mit einem ContextMenuStrip- Menu, das mit einem Eintrag „end“ das
Formular wieder schließt.
Hinweise:
Eigenschaften des neuen Formulars: Name=“FormDia“, FormBorderStyle=None; BackColor
auf Schwarz. WindowState=wsMaximized. Achtung, bevor Sie es starten und mit Show()
aufrufen, müssen Sie das Beenden programmiert haben (das ContextMenuStrip an das Formular
binden), da das Fenster nun keine Tasten dafür mehr hat. Sonst geht es nur über Alt F4 oder
andere Maßnamen, z. B. „Debugging beenden“ mit Shift + F5!
Beenden mit ContextMenuStrip- Menu. Ein Eintrag „end“, mit Doppelklick in der
Ereignisfunktion Click() das Schließen des Fensters auslösen z.B. mit Close();. In dem
Ereignis von FormDia namens FormClosing dann wie oben schon erwähnt den Befehl
e.Cancel=true; programmieren, damit wird das Schließen und Löschen der Instanz verhindert.
Stattdessen dort Hide(); programmieren.
Um den Zugriff von FormDia zurück auf das Hauptformular zu ermöglichen, muss man diese
Schritte tun:
In Form1, dem Hauptformular:
public Form1() { InitializeComponent(); frm2 = new FormDia(this); } FormDia frm2; In FormDia:
Bei den using muss der Namespace von Form1 angegeben werden. In meinem Beispiel – kann
bei ihnen anders heißen- : namespace WindowsApplication14 Also in Form Dia: using WindowsApplication14; Wenn nicht der namespace von FormDia nicht sowieso schon den gleichen namen hat.
Dann dort im Konstruktor die rot gerahmten Zeilen/ Teile ergänzen:
Form1 meinmain; public FormDia(Form1 m) { InitializeComponent(); meinmain = m; } Auf FormDia eine pictureBox- Komponente ziehen, diese mit Dock=fill auf das ganze
Formular ausdehnen. Dann auch an pictureBox1das ContextMenuStrip dranlinken.
Jetzt kann man in einem Ereignis MouseClick ein Bild aus der Liste von FileListBox laden.
Um an diese dranzukommen, muss sie erst im Modifier auf public gestellt werden.
Benötigt wird noch ein
public int diacnt = 0; mit dem der index der Filelistbox hochgezählt wird. File: Kurs MS10C# Bayerlein4.6.docx
Seite 43
Visuelle Programmierung mit C#
Prof. Dr. Bayerlein
Das Laden erfolgt wie schon gehabt, alles hinter ereignis MouseClick:
string fn = meinmain.fileListBox1.get_Items(diacnt); // selected Line int len = fn.Length; string ext = fn.Substring(len ‐ 4, 4).ToLower(); if ((ext == ".jpg") || (ext == ".png") || (ext == ".bmp")) { pictureBox1.Load(meinmain.fileListBox1.Path + "\\" + fn); } diacnt++; if (diacnt >= meinmain.fileListBox1.Items.Count) diacnt = 0; Jetzt sollte es schon gehen, nur in der FileListBox sollte das Pattern so gestellt werden, dass
dort nur Bilder drin stehen, also =*.jpg;*.png;*.bmp.
Damit gleich nach Druck auf Start-Buttom ein Bild gezeigt wird, im Click- Ereignis des
Buttons das MouseClick- Ereignis von FormDia aufrufen. Das geht erst, wenn man dieses
Ereignis public macht:
public void FormDia_MouseClick(object sender, MouseEventArgs e) dann in buttonStartDia_Click(…. .
frm2.FormDia_MouseClick(null, null); Benötigt wird auf FormDia noch ein Timer, Interval=2000, Modifier=public, damit er von
Form1 aus erreicht und aktiviert werden kann.
FormDia, dort picturebox1.Sizemode=Zoom;
Will man mit der ESC- Taste (Code 27) schließen, muss man auf dem Formular FormDia eine
KeyPress- Ereignisfunktion erzeugen und dort
if (e.KeyChar == 27) Visible=false ;
programmieren.
Nach Klick auf die Start- Taste muss der Timer bei aktivierter CheckBox für den Timer auf
Enabled=true geschaltet werden.
Nun nur noch im Timer_Tick – Ereignis das mouseClick- Ereigniss aufrufen.
FormDia_MouseClick(null, null); Beispiel des fertigen Programms in dem Verzeichnis HA1NeuV1, dort natürlich ohne Source.
Damit in der FileListBox nur Bilddateien aufgelistet werden, sollte vorher die Eigenschaft
.Pattern von der FileListBox auf ein passendes Filter gesetzt werden. Das Format dafür:
*.jpg , wenn ein Typ zugelassen werden soll, wenn es mehrere sind, mit Semikolon trennen:
*.jpg;*.gif;*.png;*.bmp.
Ein Problem sollte noch abgefangen werden: Wenn gar kein Bild in der FileListBox ist, gibt es
eine Fehlermeldung, diese wird noch nicht abgefangen.
Kurs 7 Zeichnen mit dem Graphics - Objekt
Das Graphics-Objekt
Das Objekt Graphics dient zum pixelorientierten Zeichnen auf Komponenten als
Ausgabeeinheiten. Jeder einzelne Pixel kann individuell definiert werden, mit komfortablen
Methoden ist ein Zeichnen von fast beliebigen Figuren (Linien, Rechtecken, Kreisen usw.)
File: Kurs MS10C# Bayerlein4.6.docx
Seite 44
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
möglichh. Auch Texxt kann der Zeichnung hinzugefüg
gt werden. Mit
M diesem O
Objekt lässtt sich ein
eigenes Paint- Proggramm leich
ht selber schhreiben.
Es gibt einige Kom
mponenten, die
d ein Grapphics- Objeekt haben:
 P
Panel
 P
PictureBox
 F
Form
Will maan auf dem Bildschirm
B
eine Grafikk erzeugen, so nehme man
m am bestten direkt die
d
Graphiccs der Form
m, will man später sein Werk als Bitmap speicchern, so muuss man erst eine
Bitmap definieren, doch dazu später. Diesse Bitmap verfügt
v
dann
n über die M
Methoden Load() und
Save().
Also plaatzieren wirr eine PicturreBox auf eeine neue Fo
orm einer neeuen Anwenndung. Obeen wird
wieder eein Panel1 und Dock=Top als Berreich für Taasten definieert, die pictuureBox1 fülllt den
Rest derr Form (Dock=Fill).
Wollen wir auf einem hübscheen Hintergruund malen, so laden wiir das Bild ((im
Eigenscchaftenfenstter die Eigen
nschaft Imaage) zu Beginn mit eineem Hintergrrundbild, z. B.
Wolkenn.bmp (in Pffad bayerlej\ MS Studioo2008 C#\ Images\).
I
Am alleereinfachsteen zeichnet man
m im Painnt-Ereignis, sofern in der
d Komponnente vorhaanden.
Einige B
Beispiele:
erzeugt von folgenddem Prograamm.
private
e void pic
ctureBox1_
_Paint(obj
ject send
der, PaintEventArgs
s e)
{
S
SolidBrush
h pbrush = new Soli
idBrush(Co
olor.Blue);
e
e.Graphics
s.FillRect
tangle(pbr
rush, 5, 5,
5 100, 100);
}
In den P
PaintEventA
Args wird deer Bezug auuf das Graph
hics- Objek
kt von der
Picturebbox1 übergeeben. Die Zeichenmeth
Z
hoden mit Fill
F vor dem Namen
erwartenn ein SolidB
Brush, mit dem
d die Fülllung definieert wird. Daas Rechteckk
selbst kann mit divversen Param
metern definniert werden
n, hier mit den
d beiden
Koordinnaten der Ecckpunkte ob
ben links (5 ,5) und unteen rechts (100,100).
Oder Ähhnliches miit dem Butto
on (auch derr hat ein Paaint- Event)::
Pen p = new Pen(
(Color.Red
d, 3);
Point p
poi1 = new
w Point(0,
, 5);
Point p
poi2 = new
w Point(80
0, 15);
e.Graph
hics.DrawL
Line(p, po
oi1, poi2)
);
DrawLiine() zeichnnet eine Liniie, hier mit dder Eigenscchaft von Peen, der mit FFarbe und
Strichdiicke definieert ist. Die Koordinaten
K
n diesmal mit zwei Poin
nt- Objektenn.
p1:
Oder maal in einem StatusStrip
Pen p = new Pen(
(Color.Gre
een, 1);
Rectang
gle rec = new Recta
angle(200,
, 3, 250, 15);
e.Graph
hics.DrawR
Rectangle(
(p, rec);
In Draw
wRectangle steht mit (2
200,3) die K
Koordinate oben
o
links und
u dann follgt Width und
Height.
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 45
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Allen diiesen Figureen werden jetzt sofort zzu Anfang beim
b
Start gezeichnet,
g
denn dann wird der
Paint- E
Ereignis ausgelöst.
Will maan in einem anderen Erreignis zeichhnen, z.B. in
n einem Cliick des Butttons, so gibtt es
natürlich die PaintE
EventArgs nicht.
n
Dannn kann der Bezug
B
folgen
ndermaßen erzeugt werden:
private
evoid butt
tonLine_Cl
lick(objec
ct sender, EventArgs e)
{
G
Graphics gPB
g
= Grap
phics.From
mHwnd(pict
tureBox1.Handle);
S
SolidBrush
h pbrush = new Soli
idBrush(Co
olor.LightSkyBlue);
;
g
gPB.FillRe
ectangle(p
pbrush, 0,
, 0, 100,1
100);
}
es wird eine lokale Instanz von
n Graphics (gPB) erzeu
ugt, die per Handle auff die pictureeBox1
zeigt. D
Der Rest gehht wie gehab
bt. Jetzt wirdd auf Click ein Rechtecck gezeichnnet. Die erstte Zeile
mit der Methode .F
FromHwnd kann auch vvöllig gleich
hbedeutend
d mit der Altternativcodiierung
werden. Beiides erfüllt den
d gleicheen Zweck:
ersetzt w
Graphic
cs gPB = pictureBox
p
x1.CreateG
Graphics();
Bei eineer solchen lookalen Instaanz sollte m
man nach deem Zeichenv
vorgang diee Graphics- Instanz
gPB wieeder entfernnen mit
gPB.Dis
spose();
Die Insttanziierung von gPB kaann auch gllobal erfolgeen, dann können andere
re Ereignisfu
unktionen
auch daarauf zugreiffen:
Erst gloobal- also auußerhalb ein
ner functionn, deklariereen:
public partial class
c
Form
m1 : Form
m
{
G
Graphics gPB;
g
S
SolidBrush
h pbrush = new Soli
idBrush(Co
olor.Blue);
.......
Dann innstanziieren:
public Form1()
{
Init
tializeCom
mponent();
;
gPB = Graphic
cs.FromHwn
nd(picture
eBox1.Hand
dle);
pbru
ush = new SolidBrus
sh(Color.LightSkyBlue);
B mit zweii Trackbars wird ein Piie gezeichnet, dessen U
Umrandung eine
Dann beenutzen, z. B.
Ellipse iist und die Randbegren
R
nzungen weerden mit ein
nem Winkeel (0-360°) ddefiniert, wo
obei 0°
nach recchts zeigt, von
v dort starrtet ein Kucchenstück mit
m der Wink
kelbreite einngestellt miit
trackBaar2:
private void
v
track
kBar1_Scro
oll(object
t sender, EventArgs
s e)
{
pbrush.Co
olor=Color
r.Red;
gPB.FillP
Pie(pbrush
h, 20, 30, 100, 200
0, trackBa
ar1.Value,
trackBar2.Value);
Links steht trackBar1 etwa auf 5°° und trackB
Bar2 auf 90°°
Nun wird direkt
d
auf diie Komponeenten gezeicchnet. Will m
man eine Zeichnung
Z
erzeugen, die
d man absppeichern kaann, so muss man mit eeiner Bitmap
p
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 46
Visuelle Programmierung mit C#
Prof. Dr. Bayerlein
arbeiten.
Der erste Versuch bietet sich an: Man nehme die fertige BitMap von PictureBox1 namens
Image.
Man kann zur Laufzeit ein Bild wie gehabt laden mit
pictureBox1.Load("Wolken.BMP");
wobei jetzt natürlich das Bild „Wolken.bmp“ im aktuellen Verzeichnis ….Debug stehen muss.
Führt man diese Zeile aus, so wird gleich wieder das blaue Rechteck darüber gemalt, da dies in
der Paint- Ereignisfunktion pictureBox1_Paint so programmiert ist. Beim Laden wird diese
natürlich ausgeführt.
Will man jetzt das Bild mit Zeichnung abspeichern, so stellt man erstaunt fest, dass
pictureBox1 keine Save- Methode hat. Man findet aber bei Image ein .Save, nur das
funktioniert nicht, warum weiß ich zurzeit nicht:
pictureBox1.Image.Save("test.bmp");
// Fehlermeldung
Mal ein Versuch mit einer Bitmap, z. B. so :
Bitmap pic = new Bitmap(200, 200);
erzeugt eine leere 200*200 Pixel große Bitmap,
Bitmap pic = new Bitmap("Blumen.jpg" );
lädt das Bild aus dem aktuellen Verzeichnis und definiert eine Bitmap in der Größe des Bildes.
Es darf kein indiziertes Farbformat sein (wie z.B. „Wolken.BMP“), dann gibt es einen
Laufzeitfehler. Es müssen TrueColor- Bilder sein.
Wie zeichnet man nun in eine Bitmap und speichert sie dann folgendermaßen ab:
Z.B. in einer Click-Funktion könnte man schreiben:
Graphics g1 = Graphics.FromImage(pic);
Rectangle rec = new Rectangle(0, 3, 25, 15);
g1.FillRectangle(pbrush, rec);
Jetzt wird ein Rechteck nach g1 gezeichnet, nur man sieht nichts. Man kann es aber
abspeichern, z. B. mit folgender Zeile:
pic.Save("testa.bmp", System.Drawing.Imaging.ImageFormat.Bmp);
Mit dem ImageFormat teilt man der Save- Methode mit, in welchem Format man es denn gerne
hätte. Als .jpg- Datei geht dann so:
pic.Save("testa.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
Wenn man sich diese Dateien mit Windows-Programmen ansieht, dann ist das Rechteck zu
erkennen, der Hintergrund ist aber schwarz, wenn man mit Bitmap(200,200) eröffnet hat, sonst
eben das geladene Bild. Will man die Zeichnung sehen, so muss man in ein Graphics- Object
zeichnen, das zu einer sichtbaren Komponente gehört, z.B. unser gPB, das auf die pictureBox1
zeichnet. Der Code dazu lautet:
gPB.DrawImage(pic,10,10);
File: Kurs MS10C# Bayerlein4.6.docx
Seite 47
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
wobei ddie beiden Koordinaten
K
n in diesem A
Aufruf den linken oberren Punkt vo
von pic festlegen.
Will maan jetzt g1 von
v oben niccht auf einee Bitmap, so
ondern auf das
d Image- O
Object von
pictureB
Box1 legen, so geht dass leider auchh nicht: Lau
ufzeitfehler
Graphic
cs g1PB = Graphics.
.FromImage
e(pictureBox1.Image);// ->L
Laufzeitfe
ehler
Man kannn nun Zeicchenfiguren
n mit verschhiedenen Meethoden erzeugen. Die wichtigsten
n sind:






D
DrawLine(iint X, int Y, int x1, int Y
Y1); zeichneet Linie von
n (X,Y) bis ((X1,Y1). Mit
M 4
vverschiedennen überladeenen Param
meterlisten, siehe
s
CodeC
Completionn- Fenster.
D
DrawRectangle(int X1, int Y1, int X2, int Y2); Zeichnet ein
e Rechtecck mit Ecke oben
llinks bei X11,Y1 und un
nten rechts bbei X2,Y2. Mit 3 verscchiedenen üüberladenen
n
P
Parameterliisten, siehe CodeComppletion- Fenster. FillRecctangle ähnnlich mit Fü
üllung
D
DrawEllipsse(int X1, in
nt Y1, int X22, int Y2); Zeichnet Kreeis oder Elliipse mit
uumgebendeem Rechteck
k mit den K
Koordinaten wie beim Rectangle.
R
D
DrawPie(innt X1, int Y1
1, int X2, intt Y2, int X3,, int Y3, int X4, int Y4);;s.o.
W
Weitere Meethoden von
n Graphics ssiehe CodeC
Completion
n
D
Die Methodden mit „Drraw…..“ erw
warten einen
n Pen, der mit
m new defi
finiert werdeen muss
uund legt denn Rand fest. Die Methooden mit „F
Fill….“ Erw
warten einenn Brush oderr
SolidBrush, ebenfalls mit
m new deffiniert, der die
d Fülleigeenschaften ffestlegt. Man sehe in
dden Beispieelcode hineiin.
Wir schhreiben nun zwei kleinee Programm
me, die folgeendes macheen: Mit Mauusklick folg
gt der Pen
der Mauus und zeichhnet eine freeihändige F
Figur. Mit Tastendruck
T
auf „Artwoork“ Start/StopBetrieb wird die Zeeichenflächee mit einer Serie von Rechtecken
R
gefüllt (mitt Timer gestteuert),
Größe und Position und Farbe mit eeinem Zufallsgeneratorr erzeugt weerden. Mit einer
e
deren G
Taste Saave soll dass Werk dann
n abgespeichhert werden
n.
Wir braauchen vier Tasten mit Text Artwoork, Save Picc, Pen-Colo
or und Fill-C
Color. Zum
Abspeicchern ist einn SaveDialo
og1 nötig, füür die Farbw
wahl ein ColorDialog, für die Stricchdicke
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 48
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
braucheen wir noch ein numericUpDown- Element, Default
D
Wertt für Value=
=1. Das sieh
ht dann
so aus:
Die Kom
mponenten haben folgeende Ereignnisfunktioneen:
Artworrk(Button1): Schaltet den
d timer1 aan und aus, Vorher
V
timeer1.Enabledd=false; als
Startzusstand festleggen.
if (tim
mer1.Enabl
led) timer
r1.Enabled
d = false; else timer1.Enab
bled = tru
ue;
Button2), es wird als .jp
pg abgespeicchert:
Save (B
if (sav
veFileDial
log1.ShowD
Dialog() =
== Dialog
gResult.OK)
pic.Sav
ve(saveFil
leDialog1.
.FileName,
,System.D
Drawing.Im
maging.Ima
ageFormat.Jpeg);
PenCollor und Bru
ushColor: Hinter
H
Buttoon3 und Buttton4 wird die
d Farbe dees Stiftes un
nd des
Pinsels eingestellt, p und pbrush sind globbale Instanzzen von Pen
n und SolidB
Brush:
if (col
lorDialog1
1.ShowDial
log() == D
DialogResult.OK)
alog1.Color;
p.Color = colorDia
if (col
lorDialog1
1.ShowDial
log() == D
DialogResult.OK)
lorDialog
pbrush.Co
olor = col
g1.Color;
Mit dem
m OnChangge-Event wirrd die Stiftddicke gewäh
hlt:
private
e void num
mericUpDow
wn1_ValueC
Changed(object sender, Even
ntArgs e)
{
p
p.Width = (int)nume
ericUpDown
wn1.Value; }
Zuerst jetzt die Freeihandmalfu
unktion. Dazzu lernen wir
w die Maussevents kennnen. Das Zeeichnen
gnis MouseM
Move, der Aufruf
A
sieht so aus:
selbst geschieht miit dem Ereig
private
e void pic
ctureBox1_
_MouseMove
ve(object sender, MouseEvent
M
tArgs e)
{
if (d
draw)
{
P
Point endp
p = e.Loca
ation;
g
g1pic.Draw
wLine(p, start,
s
end
dp);
c.Width, pic.Height); // Dr
g
gPB.DrawIm
mage(pic, 0, 0, pic
raw on scr
reen
s
start = en
ndp;
}
Die aktuuellen Mouse Koordinaaten werdenn in e überg
geben, z.B. in
i e.X und ee.Y oder in
e.Locatiion. Diese Funktion
F
wiird jedes Maal aufgerufeen, wenn die Maus sichh bewegt. Also
A wird
auch geezeichnet, wenn
w
man keeine Maustaaste drückt, also immerr. Deswegenn gibt es nun
n eine
b
Variab
blen draw. Sie wird im
m MouseDow
wn- Ereigniis auf true und
u im
Steueruung mit der boolMouseU
Up- Ereigniss zurück auff false gesettzt.
Dann w
wird wie obeen beschrieb
ben erst mit g1pic in die Bitmap pic
p gezeichnnet und dann
n mit gPB
in picturreBox1, dam
mit es auf den
d Bildschiirm gelangt.
Es wirdd immer einee Linie von start nach eendp gezeicchnet, wenn draw true iist. Desweg
gen muss
jetzt nocch im Ereiggnis MouseD
Down die gllobale Variaable start au
uf die aktueellen
Mauskooordinaten gesetzt
g
werd
den mit:
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 49
Visuelle Programmierung mit C#
Prof. Dr. Bayerlein
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
draw = true;
start = e.Location;
}
Ein paar Bemerkungen:
 Die Zeichenfläche wird beim ersten Zeichnen festgelegt. Ändert man sie hinterher,
findet keine Größenänderung mehr statt.
 Lädt man als Hintergrund das Bild „Wolken.BMP“, so gibt es einen Laufzeitfehler. Das
liegt daran, weil dieses Bild ein 256- Index-Farben-Bild ist. Wandelt man es in
truecolor, so geht es.
 Das Bild darf nicht auf SizeMode =StrechImage; gestellt werden, da dann die
Mauskoordinaten nicht mit der Position übereinstimmen.
Nun das Artwork. Im Timer sollen per Random- Generator farbige Rechtecke erzeugt werden.
In der Timer- Funktion steht bei mir:
Random r = new Random();
int
int
int
int
x1
y1
x2
y2
=
=
=
=
r.Next(0,
r.Next(0,
r.Next(0,
r.Next(0,
pic.Width);
pic.Height);
pic.Width-x1);
pic.Height-y1);
//x point top left
// y point top left
// width
// height
Rectangle rect = new Rectangle(x1, y1, x2, y2);
int red = r.Next(0, 255);
int green = r.Next(0, 255);
int blue = r.Next(0, 255);
//int alpha = r.Next(0, 255); // this value with trackbar1
pbrush.Color = Color.FromArgb(alpha,red, green, blue);
int red2 = r.Next(0, 255);
int green2 = r.Next(0, 255);
int blue2 = r.Next(0, 255);
p.Color = Color.FromArgb(alpha, red2, green2, blue2);
p.Width = r.Next(1, 10);
g1pic.FillRectangle(pbrush,rect);
g1pic.DrawRectangle(p, rect);
gPB.DrawImage(pic,0,0, pic.Width, pic.Height);//Draw on screen
File: Kurs MS10C# Bayerlein4.6.docx
Seite 50
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Die Recchtecke orieentieren sich
h an der Grööße von pic. Stellt man
n Interval voom timer1 auf
a 100
ms, dannn werden allle Sekundee 10 Rechteccke erzeugtt.
Die Farbben werdenn mit .FromA
Argb() erzeeugt. Schön ist auch, daass der Trannsparentwerrt alpha
hier aucch geändert werden kan
nn. alpha=0 heißt voll transparent,
t
also unsichhtbar, alphaa = 255
nicht traansparent. Im fertigen Programm
P
vverändert man
m alpha mit
m dem linke
ken trackBarr1. Das
Program
mm zeichnet erst die Fü
üllung und ddann einen Rahmen miit anderer Faarbe.
Die ferttigen Dateieen finden Sie in Kurs7## Graphics.
Viel Spaß bei weiteeren Experimenten.
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 51
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Kurs 8 Charrt2D
Siehe H
Hinweis auf die in DotN
Net 4.0 neu vverfügbare Komponen
nte Chart ab S. 85.
In dieseem und dem
m nächsten Kurs
K wird diie mächtigee Komponen
nte Chart2D
D vorgestelltt. Diese
Komponnente ist ann der FHL neeu entwickeelt worden und
u vollstän
ndig in C# ggeschrieben
n. Sie
ersetzt ddie alte bishher seit Jahrren benutztee Komponen
nte Chartfx,, die bei Bor
orland Verw
wendung
fand. Daamit ist der ganze Ärgeer mit ActivveX usw. en
ndlich vom Tisch.
Der Souurcecode lieegt auch vorr und Erweiiterungen sind damit jederzeit mögglich.
Einige E
Eigenschaftten: Hauptzw
weck ist dass Zeichnen von Diagraammen anhaand von z. B.
B
Messdaaten. Es können maximal 10 farbigge Kurven mit
m einer belliebigen Punnktzahl gezzeichnet
werden.. Es gibt einne Autoskalierung und mehrere To
oolbuttons, mit denen ddie Darstelllung
angepassst werden kann.
k
Eine Zoomfunkti
Z
ion, eine Ko
oordinatenaanzeige sow
wie eine Umschaltung
in einenn Punkteditoor per DataG
Grid rundenn die Funktionen ab. Hiier ein Beisppielscreensh
hot:
u Reloadeen sowie einn Ausdruck sind vorgessehen. Ich bbenutze diesse
Das Abspeichern und
Komponnente in meeinem Großp
projekt WinndfC#. Das erste Regellungstechnikk Praktikum
m damit
ist ohnee Probleme gelaufen
g
un
nd die Kindeerkrankheiten sind beseeitigt. Es sinnd für diesee
Komponnente 2 separate Dokum
mente verfüügbar. Auf studpub
s
find
det sich in
bayerlejj\ MS Studioo2008 C#\ Kurs
K
8 neu Chart2D vo
on Lars Seckler\
die Dateei Benutzerooberfläche von
v Chart2D
D_2.pdf . Diese
D
besch
hreibt für Annwender ein
nes
Program
mms die Beddienung derr Benutzerooberfläche.
Die Dattei Verwenddung der Ko
omponente C
Chart2D in C_2.pdf beeschreibt füür den
Program
mmierer, wiie man diesee Komponennte einbindet in seinen
n eigenen C##- Code. Deeswegen
soll hierr nur kurz beispielhaft
b
die Verwenndung besch
hrieben werden, weiteree Details en
ntnehme
man dieesen Dokum
menten.
Zur Insttallation bennötigt man die
d Datei Chhart2D.vsi. Diese darf nur bei aussgeschaltetem Visual
Studio ggestartet weerden. Danaach sollte diee Komponeente in der Toolbox
T
ersccheinen.
Das Erggebnis bei MS
M Studio 2010
2
sieht soo aus:
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 52
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Erstes kkleines Beispiel:
In einem
m neuen Proojekt erst ein
n Panel mitt Dock Top uns dann diiese Kompoonente auf die
d Form
ziehen m
mit Dock Fiill.
Dann eiinen Buttonn mit Namen
n ButtonSinn mit text sin
n ergänzen. Hinter dem
m Clickereig
gnis
dieser C
Code:
int i,
, nb = 100,
, serie = 1
1; i = 0; i < nb; i++) for (i
{ hart2D1.set
tPoint(0, i
i, Math.Sin(i / 16.0 *
* serie)); ch
} 2D1.startDr
rawing(); chart2
2D1.autoSca
aling(); chart2
Es siehtt nach Ausfü
führung dann
n so aus:
Mit Setppoint wird das
d interne dynamisch
d
verwaltete Datenarray gefüllt. Diee erste Zahll ist die
Nummeer der Kurvee (von 0 biss 9), die zweeite der x- Wert
W und diee dritte Zahhl der y- Weert eines
Punktess. Mit dem Befehl
B
startD
Drawing() w
wird die Ku
urve gezeich
hnet. Mit auutoScaling()) findet
eine auttomatische Skalierung
S
statt.
Die Anzzahl der Punnkte pro Ku
urve ist belieebig und kaann für jede Kurve indiividuell versschieden
sein.
Drückt m
man diese Taste
T
sin jed
doch ein zw
weites Mal, so
s erscheintt eine blaueer Querstrich
h. Das
liegt einnfach daran,, dass jetzt zwei
z
gleichee Kurven im
m Speicher hintereinannder liegen und
u alle
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 53
Visuelle Programmierung mit C#
Prof. Dr. Bayerlein
Punkte verbunden werden. Also wird der letzte Punkt der ersten Sin- Kurve mit dem ersten
Punkt der zweiten verbunden.
Um dies zu vermeiden, sollte vor dem Neuzeichnen erst alter Inhalt einer Kurve mit der
Methode clearLast() gelöscht werden.
Eine einfache Variation liegt jetzt hinter einer neuen Taste namens buttonMulti. Folgender
Code zeichnet immer neue Kurven:
Außerhalb einer function: short serie = 1; Dann innerhalb der Click-funktion:
int i, nb = 100; for (i = 0; i < nb; i++) { chart2D1.setPoint(serie ‐ 1, i, Math.Sin(i / 16.0 * serie)); } chart2D1.startDrawing(); chart2D1.autoScaling(); serie++; Nach der 10. ten Kurve wird nicht mehr gezeichnet.
Jetzt testen wir mal die Echtzeitzeichenfunktion: Hinzufügen eines Timers (Interval=20,
Enabled=false) und einer Taste ButStart.
Hinter diese Taste:
if (timer1.Enabled) timer1.Enabled = false; else { timer1.Enabled = true; chart2D1.clearAll(); chart2D1.XMax = 100; chart2D1.XGap = 10; chart2D1.YMax = 1; chart2D1.YMin = ‐1; chart2D1.YGap = 0.2; serie = 1; } Außerhalb: int itemp = 0; In timer1_Tick:
chart2D1.realTimeChart((serie ‐ 1), itemp, Math.Sin(itemp / 16.0 * serie)); itemp++; if (itemp > 100) { itemp = 0; serie++; } if (serie > 5) { serie = 1; chart2D1.clearAll(); } Dann werden nacheinander 5 Kurven in Echtzeit gezeichnet:
File: Kurs MS10C# Bayerlein4.6.docx
Seite 54
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
debeispiele:
Jetzt nooch einige eiinfache Cod
Änderunng eines Kuurvennamen
ns:
chart2
2D1.CurveNa
ames[0] = " Kurve 1"; 2D1.updateN
Names(); chart2
Titel: chhart2D1.ToppTitle = "Top Header TTitle"; Löschenn der letztenn Kurve: chart2D1.cleaarLast(); Ausblennden z.B. deer ToolTaste“ Lösche aalle Kurven
n“: chart2D1.AllClearBuutton = fallse; Abfragee der Anzahhl von Kurven: Counterr, keine Kurrve: -1
Abfragee der Punktee pro Kurvee: in CurveP
Points[], es ist
i ein int- Array.
A
Abfragee von Punkttkoordinaten
n: einmal geetPoint(i,j), wobei i diee Kurvennum
mmer und j die
Punktnuummer ist beide
b
starten
nd mit Null.. Beispiel:
double
e[] xy; chart2D1.ge
etPoint((in
nt)nudKurve.Value, (in
nt)nudPunktt.Value); xy = c
labelX
Xval.Text =
= xy[0].ToS
String(); Yval.Text =
= xy[1].ToS
String(); labelY
Natürlicch dürfen diie Werte in i und j die A
Arraygrößen nicht überrschreiten, ssonst Fehlerr. i und j
werden im Beispiell mit je eineem NumericcalUpDown
n eingestelltt. Der Typ vvon Value isst dort ein
decimall, deswegenn das „typecast“ mit (innt).
kdarstellungg mit der altten chartFX in C# (Balkken,
Will maan übrigens eine Grafik
Kuchenndiagrammee auch in 3D
D) so lese m
man diesen Skript
S
in ein
ner Version 3. Ab Versiion 4 ist
sie verschwunden, da die dort benutzte A
ActiveX groß
ße Installationsproblem
me verursach
ht und
außerdeem ein 64-B
Bit programm
mierung verrhindert. Ich
h bin froh, dass
d ich sie los bin.
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 55
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Kurs 9 DataT
Tools - Einbind
den von
n Tool- Units
U
In meinnem Regelunngstechnik- Tool- Proggramm WindfC# benutze ich Unitss zu finden dort in
DataTools.cs, mit deren
d
Hilfe man z.B. dden Inhalt eiiner Textbox
x, falls die eein bestimm
mtes
Format aufweist, komplett
k
als Kurve darsstellen kann
n. Das Form
mat sollte so sein, dass pro
p Punkt
u y in ein
ner Zeile steehen und miit einem Sep
parator (kannn Komma,, Tab oder
die Kooordinaten x und
Leerzeicchen sein) getrennt
g
sind.
Vorgeheensweise ähhnlich schon
n wie im Kuurs 2c#:
Neues P
Projekt nachh Kurs 9# ab
bspeichern.
Der Forrm ein Paneel mit Dock Top hinzuffügen.
Zweitess Panel mit dock
d
Left hinzufügen
h
Chart2D
D mit Dock Fill hinzufü
ügen.
Auf pannel1 ButtonT
TB2Chart hinzufügen
h
m
mit Text TB
B to Chart
Auf pannel2 Textbox hinzufügeen mit Dockk Fill.
Resultatt:
gen (außerhhalb des Konstruktors von
v Form1)):
Nun follgende Instaanzen erzeug
DataTools d
dt = new Da
ataTools(); LoadOpt lo
o = new Loa
adOpt(); CHMinMax m
mm = new CH
HMinMax();
Im Konnstruktor dannn :
public For
rm1() { alizeCompon
nent(); Initia
it(); lo.ini
it(); mm.ini
} Hinter dder Clickfunnction des Button
B
folgeenden Codee:
dt.ConvertTB2Cha
artAdd(ref chart2D1, textBox1,re
ef mm, lo);
; File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 56
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Jetzt maal folgendenn Inhalt in die
d rechte Teextbox tippen oder kop
pieren:
00
11
23
35
43
50
Ergebniis:
Nun kannn man gannze Dateien mit Messw
werten laden und so einffach grafiscch anzeigen.. Dazu ein
Load- B
Button spenddieren, noch
h einen opennFileDialog
g1 hinzufüg
gen und hintter die
Clickfunnctions des Loadbutton
ns dann wiee schon oben
n in Kurs 5#
# erklärt einne Datei lad
den mit:
if (op
penFileDial
log1.ShowDi
ialog() == D
DialogResul
lt.OK) { treamReader
r myStream1
1 = new Stre
eamReader(o
openFileDiaalog1.OpenFile(), St
; Encoding.Default);
extBox1.Tex
xt = myStre
eam1.ReadToEnd(); te
} Als Beispiel ist im Kurs 9 die Datei 2PT11_2.sim zu finden.
f
Die Grafik siehht dann so au
us:
In den L
LoadOptionns kann man
n dann auchh andere Datteiformate, logarithmissche Skalierrung etc
voreinsttellen.
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 57
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Kurs 9a Zeic
chnen von
v Kurrven mitt Chart DotNet 4.0
Seit DottNet 4.0 gibbt es nun en
ndlich eine K
Komponentte zum Zeich
hnen beliebbiger Grafik
ken von
Microsooft: Die Kom
mponente Chart:
C
Man ffindet sie in
n der Toolbo
ox unter Daaten:
Wenn m
man diese auuf das Form
mular zieht, ssieht es so aus:
a
Die Beffüllung mit Daten gesch
hieht so (Sinnuskurve mit
m 100 Punk
kten):
int i,
, nb = 100,
, serie = 1
1; chart1
1.Series[0]
].ChartType
e = SeriesChartType.Li
ine; for (i
i = 0; i < nb; i++) { hart1.Serie
es[0].Point
ts.AddXY(i, Math.Sin(i
i / 16.0 * serie)); ch
} Will maan eine neuee Kurve (geenannt serie)) hinzufügeen, so muss man dies m
machen:
chart1.Series.Add(
("Kurve 1);
; chart1.Series[1].C
ChartType =
= SeriesCha
artType.Line
e; Die einzzelnen Kurvven werden dann wie eein Array mit .Series[i] erreichbar.
Nur leidder gibt es die
d Toolbar nicht, die ddem User beei einem fertigen Progrramm auch
Möglichhkeiten gibtt, seine Darsstellung wäährend der Laufzeit
L
zu ändern.
ä
Alleerdings sind
d die
Darstelllungsmöglicchkeiten dieeser Chart – Komponen
nte gigantisch. Will maan nicht nurr Kurven,
sondernn beliebige Grafiken
G
daarstellen, so muss man sich mit dieeser sehr kom
omplexen
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 58
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Komponnenten auseeinander settzen. Eine seehr gute Ein
nführung beekommt man
an mit einem
m
Tutoriall, das ich beei Microsoftt gefunden hhabe und ess auf studpu
ub zur Verfüügung gesteellt habe:
Siehe baayerlej\ MSS Studio2010
0 C# WS20112_13\ DotN
NetChart\.
Entpackkt man die dort
d zu findeende Datei WinSampleesChart von MSDN(1).zzip, so kann
n man das
Program
mm WinForrmsChartSamples.exe sstarten und bekommt
b
eiine Einführuung in alle
Möglichhkeiten mit passenden Source – Coode Zeilen. Besser kan
nn man ein T
Tutorial niccht
aufbaueen und ich kann
k
dem niichts mehr hhinzufügen. Ich werde sicher auchh demnächstt mein
Toolproogramm Winndfc# damit ausstattenn, da insbeso
ondere auch
h Bodediagrramme damit sehr
gut darsstellbar werden, was bisher nicht gging. Folgeende Tabellee soll Entschheidungshillfe geben,
welche Komponente man wan
nn nehmen kkönnte:
Chart2D von Herrn Seckler
Source Code verfüggbar und daadurch
anpassbbar an eigenne Wünsche
Toolbarr für User während
w
Lau
ufzeit
Einfachhes Interfacee
Nur Kurrven, max. 10
Keine B
Bodediagram
mme
art in DotN
Net 4.0
Cha
Anp
passbar durcch tausendee Optionen
Kein
ne Toolbar
Kom
mplexes Inteerface
Beliiebige Grafi
fiken
Bod
dediagramm
me möglich
In Arbeeit ist zurzeit ein Projek
kt, welches ddie Vorteilee beider Kom
mponenten vereint. Es existiert
schon eiine Komponnente, die der
d DotNet- Chart mein
ne Toolbar verpasst.
v
Ess fehlt noch eine
Erweiteerung des Innterfaces, so
o dass ich inn meinen Pro
ogrammen einen einfacchen Austau
usch
vornehm
men kann, ohne
o
dort tau
usende Ändderungen vo
orzunehmen
n. Das könnt
nte ein nettess
Studiereenden – Proojekt sein. Bei
B Interessee bitte meld
den.
Kurs 10 Weitere Ko
ompone
enten
WebB
Browser
Mit der Komponennte WebBrow
wser (in Alllgemeine Stteuerelemen
nte) kann m
man sich sein
nen
eigenenn Browser basteln. In Anwendunge
A
en kann man
n dann dam
mit auf seinee eigene Hom
mepage
verweissen oder Hillfetexte anbieten. Da inn der Regel ein pdf- Reeader installiliert ist, kann man
mit diesser Komponnente dann auch
a
pdf- D
Dateien in seeiner Anwen
ndung anzeiigen. Wir sttarten mit
einer neeuen Anwenndung und platzieren
p
inn der oberen
n Hälfte ein Panel (Docck auf Top) für die
Bedieneelemente unnseres Brow
wsers und daarunter mit Dock
D
auf Fiill den WebB
Browser. Mit
M einer
textBoxx1 und einiggen Buttons lässt sich gganz einfach
h ein Browser zusammeenstellen.
Hinter dder Go- Tasste:
webBrow
wser1.Navi
igate(text
tBox1.Text
t);
Hinter dder Forwardd- Taste:
webBrow
wser1.GoFo
orward();
Hinter dder Back- Taste:
T
webBrow
wser1.GoBa
ack();
Hinter dder Home- Taste:
T
webBrow
wser1.GoHo
ome();
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 59
Visuelle Programmierung mit C#
Prof. Dr. Bayerlein
Hinter der Browse- Taste:
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
webBrowser1.Navigate(openFileDialog1.FileName);
}
Die Home- Seite ist die, die beim Internet- Explorer als Home definiert ist, die Browse- Taste
setzt eine Komponente openFileDialog1 voraus. Es läuft im Hintergrund wie zu erwarten eine
eingebettete Form des auf dem PC installierten IE in der entsprechenden Version. Lädt man mit
der Browse- Taste Dateien der Art pdf, doc, jpg usw., so wird je nach Installation auf dem
Rechner entweder die Anwendung selbst geöffnet, die der Datei zugeordnet ist oder ein Viewer
im IE wird aufgerufen und man verlässt die Anwendung nicht.
Mediaplayer
Es gibt nun keine Extra- Komponente als Mediaplayer, sondern nur ein Objekt, mit dem man
Mediendateien abspielen kann. In .NET heißt es SoundPlayer und ist verfügbar nach
Hinzufügen von dem Namespace System.Media :
using System.Media;
Hat man seinem Projekt eine Dialogkomponente openFileDialog1 hinzugefügt, dann kann man
mit folgendem Code eine *.wav- Datei laden und abspielen:
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
SoundPlayer player = new SoundPlayer();
player.SoundLocation = openFileDialog1.FileName;
player.Load();
player.Play();
}
mp3 oder videos gehen aber nicht.
Die gehen aber mit einem eingebetteten Widows- Media –Player. Dann kann man alles
machen, was der Media- Player auch kann:
Vorgehen:
1. Toolboxelemente auswählen COM , dort WindowsMediaPlayer suchen und wählen.
File: Kurs MS10C# Bayerlein4.6.docx
Seite 60
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
2. D
Dann Kompponente Windows Meddia Player in
n Toolbox suchen,
s
bei m
mir ganz un
nten, auf
F
Form ziehen
3. D
Dann ladenn einer Mediia- Datei annd abspielen
n mit
if (ope
enFileDial
log1.ShowD
Dialog() =
== Dialog
gResult.OK)
{
axWindows
sMediaPlay
yer1.URL=openFileDialog1.Fi
ileName;
axWindows
sMediaPlay
yer1.Ctlcontrols.play();
}
Der spieelt insbesonndere auch mp3,
m aber auuch Videos ab.
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 61
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Kurs 11 Ema
ail- Prog
gramm
Inzwiscchen hat ein Diplomand
d Erfahrunggen gesamm
melt mit dem
m Versendenn von Emaills ohne
externe Klassen. Ess ist jetzt mit
m DotNet- K
Klassen mö
öglich. Sie finden
f
einfac
ache
Beispiellprogrammee in StudPu
ub in MS Stuudio 2012 im
m Kurs 11. Dort sind eein einfachees Sendeund Em
mpfangs- Proogramm zu finden. Zum
m Test müsssen Sie allerdings eigenne Zugangssdaten
ihrer Em
mail- Konten eingeben,, sonst geht es natürlich
h nicht. In einer
e
Diplom
marbeit ist unter
u
anderem
m ein kleinees Emailprog
gramm (Veerzeichnis Email)
E
erarbeitet wordenn, in dem au
uch eine
Adressliste, ein HT
TML- Editor und die A
Arbeit mit Atttachments zum Einsattz kommen. Ein Test
dieses P
Programmess ist allerdin
ngs noch niccht erfolgt, eine Fehlerfreiheit kannn nicht garaantiert
werden..
Kurs 12 Tree
eView
Eine sehhr leistungsfähige Kom
mponente istt TreeView. Damit kan
nn man seinnen eigenen Explorer
bauen. IIn einem Prrojekt hab icch damit einn vereinfach
htes Dateisy
ystem benuttzt mit nur zwei
z
Ebenen (Anfänger-- Version).
Wir öffn
fnen ein neuues Projekt (ProTreeVie
(
ew) und plaatzieren ein Panel (Docck Top) eineen
TreeVieew (Dock Left)
L
und ein
ne FileListB
Box (erst über Menü „E
Extras -> Tooolboxelemeente
auswählen“ hinzufü
fügen, wenn
n nicht in TooolBox bereeits verfügbar) mit Docck Fill.
m Projekt hab
h ich von A
Andreas Kü
ühnel übern
nommen.
Die Ideeen zu diesem
Hinter ein
nem Buttonn wird nun der
d
folgende Text gelegtt:
string[
[] drives = Directo
ory.GetLog
gicalDriv
ves();
TreeNod
de node;
foreach
h (string drv in dr
rives)
{
e = treeVi
iew1.Nodes
s.Add(drv
v);
node
if (drv
(
== "C
C:\\")
// C: selektiere
s
en
t
treeView1.
.SelectedN
dNode = node;
Dann errfolgt nach Tastendruck
T
k obige Reaaktion, alle Drives werd
den untereinnander angeezeigt.
Die Klaasse Directoory wird erstt möglich nnach Einbind
dung von ussing System
m.IO . Zuerst werden
alle Lauufwerke in das
d Stringarrray drives eeingelesen, dann wird mit
m foreach dieses Strin
ngarray
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 62
Visuelle Programmierung mit C#
Prof. Dr. Bayerlein
durchgearbeitet. Mit .Add(drv) werden Einträge hinzugefügt, in drv stehen die einzelnen
Elemente des Stringarays.
Nach Einlesen wird noch der Node mit C: selektiert.
Jetzt generieren wir eine Funktion „ReadSubDirs“, die für jeden Knoten im Parameteraufruf
alle Unterverzeichnisse einliest. Code.
privatevoid ReadSubDirs(TreeNode node)
{
DirectoryInfo[] arrDirInfo; // Array für Subdirectories
DirectoryInfo dirinfo = new DirectoryInfo(node.FullPath);
try
{
arrDirInfo = dirinfo.GetDirectories();
}
catch
{
return;
}
foreach (DirectoryInfo DI in arrDirInfo)
{
node.Nodes.Add(DI.Name);
}
}
DirectoryInfo enthält dabei den vollen Namen eines Pfades, den man sich aus dem Node
auslesen kann mit .FullPath. Bindet man jetzt diese Funktion in die obere foreach- Schleife
ein, so sieht der Code so aus: Die Button Click- Funktion hab ich entfernt, alles wird jetzt im
Konstruktor von Form1() ausgeführt.
public Form1()
{
InitializeComponent();
treeView1.Sorted = true;
string[] drives = Directory.GetLogicalDrives();
TreeNode node;
foreach (string drv in drives)
{
node = treeView1.Nodes.Add(drv);
ReadSubDirs(node);
if (drv == "C:\\")
// C: selektieren
treeView1.SelectedNode = node;
}
}
File: Kurs MS10C# Bayerlein4.6.docx
Seite 63
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Außerdeem wird diee Sortieren- Eigenschafft von TreeV
View aktiviiert. Nach PProgrammstaart sieht
es dann so aus, die „plus“ Kässtchen öffneen dann Untterverzeichn
nisse der erssten Baumeebene.
Jetzt kannn man im Click- Ereig
gnis von TrreeView allee Dateien des selektiert
rten Pfades in
i
FileListtBox anzeiggen lassen mit
m
private
e void tre
eeView1_Cl
lick(objec
ct sender, EventArgs e)
{
TreeNod
de node;
node = treeVie
ew1.Select
tedNode;
fileL
de.FullPath;
ListBox1.P
Path = nod
fileL
ListBox1.U
Update();
}
Dann siieht man recchts die Datteien der sellektierten Pfade. Nur ganz zuverläässig funktio
oniert es
nicht, deenn manchm
mal muss man
m zweimaal klicken. Der
D Ereigniss scheint niccht der richttige zu
sein. Beesser ist der Ereignis:
private
e void tre
eeView1_No
odeMouseCl
lick(object sender,
TreeNod
deMouseCli
ickEventAr
rgs e)
{
file
.Node.FullPath;
eListBox1.
.Path = e.
file
eListBox1.
.Update();
;
}
dann wiird in e der angeklicktee Knoten übbergeben. Dann funktio
oniert es sichher. Jetzt feehlen noch
zwei Diinge, dann ist der Minieexplorer ferrtig. Bei jed
dem Öffnen eines Knote
tens sollten die
Unterveerzeichnissee dieses Kno
otens eingellesen werdeen, so dass man
m sich duurch den gessamten
Baum bbewegen kannn. Das geschieht in deem folgendeen Ereignis so:
private
e void tre
eeView1_Be
eforeExpan
nd(object sender,TreeViewCa
ancelEvent
tArgs e)
{
fore
each (Tree
eNode node
e in e.Nod
de.Nodes)
{
ReadSubDi
irs(node);
;
}
}
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 64
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Jetzt függen wir nocch hübsche Bildchen
B
hiinzu. Dies geschieht
g
miit einer ImaageListKomponnente, die mit
m der TreeeView- Kom
mponente veerlinkt wird in der Eigeenschaft „Im
mageList“
von treeeView1.
Bei mir sieht die im
mageList1 so aus:
Jetzt bekkommen scchon mal allle Einträge ddas Icon miit Nummer 0. Will mann bei geöffn
netem
Directorry das grüne Icon anzeigen, dann m
muss man allen
a
Knoten
n, die man m
mit Add hin
nzufügt,
mit
e.No
ode.Select
tedImageIn
ndex = 1;
dieses m
mitteilen. Ich hab diese Zeile im C
Click- Ereign
nis ergänzt.
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 65
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Kurs 13 Drucken
Diesen K
Kurs habe ich
i mehr od
der weniger direkt von Andreas Kü
ühnel [1], B
Beispiel 18
übernom
mmen. Was muss man tun:
1. H
Hinzufügenn der Print- Komponentten
2. u
using Syst
tem.Drawin
ng.Printin
ng;
3. IIm Konstruuktor:print
tDialog1.P
PrinterSet
ttings = new
n
Printe
erSettings
s();
4. D
Deklarationn folgender Variablen:
p
privateint
t startSei
ite;
p
privateint
t anzahlSe
eiten;
p
privateint
t seitenNu
ummer;
p
privatestr
ring strPr
rintText;
p
privatestr
ring strDa
ateiName;
// Anza
ahl der Dr
ruckseiten
n
//
/ aktuell
le Seitenz
zahl
//
/ zu druc
ckender Te
ext
ten Datei
// der
r Name der geöffnet
5. IIn einer Druuck- Funktion (hinter eeinem Butto
on Druck od
der so):
printDi
ialog1.All
lowSomePag
ges = true
e;
if (pri
intDialog1
1.ShowDial
log() == D
DialogResult.OK)
{
p
printDocum
ment1.Docu
umentName = "Dokume
ent";
sieren
/
// Startwe
erte abhän
ngig vom z
zu drucken
nden Text initialis
s
switch (pr
rintDialog
g1.Printer
rSettings.
.PrintRange)
{
case
e PrintRan
nge.AllPag
ges:
ox1.Text;
str
rPrintText
t = textBo
sta
artSeite = 1;
Dialog1.PrinterSettings.Max
anz
zahlSeiten
n = printD
ximumPage;
bre
eak;
case
e PrintRan
nge.SomePa
ages:
str
rPrintText
t = textBo
ox1.Text;
sta
artSeite = printDia
alog1.Prin
nterSettin
ngs.FromPa
age;
anz
zahlSeiten
n =printDi
ialog1.PrinterSettings.ToPa
age-startS
Seite+1;
bre
eak;
}
/
// Drucken
n starten
seitenNu
ummer = 1;
;
printDoc
cument1.Pr
rint();
}
6. IIn dem Ereiignis von PrrintDocumeent1_PrintPage() folg
genden Codde
tringForm
StringF
Format str
ringFormat
t = new St
mat();
Rectang
gleF rectF
FPapier, rectFText;
r
;
int int
tChars, in
ntLines;
// Ermi
den gesam
itteln des
s Rectangl
les, das d
mten Druckbereich
// besc
chreibt (i
inklusive Kopf- und
d Fusszeile)
r
rectFPapie
er = e.Mar
rginBounds
ds;
// Ermi
itteln des
s Rectangl
les, das d
den Bereich für den
h Kopf- und Fusszeile)
// Text
t beschrei
ibt (aussc
chließlich
rectFTe
ext = Rect
tangleF.In
nflate(rec
ctFPapier, 0, -2 *
s));
textBox
x1.Font.Ge
etHeight(e
e.Graphics
// eine
ilen ermitteln
e gerade Anzahl
A
von
n Druckzei
r(rectFText.Height /
int anz
zahlZeilen
n = (int)M
Math.Floor
s));
textBox
x1.Font.Ge
etHeight(e
e.Graphics
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 66
Visuelle Programmierung mit C#
Prof. Dr. Bayerlein
// die Höhe die textbeinhaltenden Rechtecks festlegen, damit die
// letzte Druckzeile nicht abgeschnitten wird
rectFText.Height = anzahlZeilen * textBox1.Font.GetHeight(e.Graphics);
// das StringFormat-Objekt festlegen, um den Text in einem Rechteck
// anzuzeigen - Text bis zum nächstliegenden Wort verkürzen
stringFormat.Trimming = StringTrimming.Word;
//
legt die Druckstartseite fest, wenn es sich nicht um die
// erste Dokumentenseite handelt
while ((seitenNummer < startSeite) && (strPrintText.Length > 0))
{
e.Graphics.MeasureString(strPrintText, textBox1.Font,
rectFText.Size, stringFormat, out intChars, out intLines);
strPrintText = strPrintText.Substring(intChars);
seitenNummer++;
}
// Druckjob beenden, wenn es keinen Text zum Drucken mehr gibt
if (strPrintText.Length == 0)
{
e.Cancel = true;
return;
}
// den Text an das Graphics-Objekt übergeben
e.Graphics.DrawString(strPrintText, textBox1.Font, Brushes.Black, rectFText,
stringFormat);
// Text für die nächste Seite
// intChars - Anzahl der Zeichen in der Zeichenfolge
// intLines - Anzahl der Zeilen in der Zeichenfolge
e.Graphics.MeasureString(strPrintText, textBox1.Font, rectFText.Size,
stringFormat, out intChars, out intLines);
strPrintText = strPrintText.Substring(intChars);
// StringFormat restaurieren
stringFormat = new StringFormat();
// Dateiname in der Kopfzeile anzeigen
stringFormat.Alignment = StringAlignment.Center;
e.Graphics.DrawString(this.strDateiName, textBox1.Font, Brushes.Black,
rectFPapier, stringFormat);
// Seitennummer in der Fusszeile anzeigen
stringFormat.LineAlignment = StringAlignment.Far;
e.Graphics.DrawString("Page " + seitenNummer, textBox1.Font,
Brushes.Black, rectFPapier, stringFormat);
// ermitteln, ob weitere Seiten zu drucken sind
seitenNummer++;
e.HasMorePages = (strPrintText.Length > 0) && (seitenNummer <
startSeite + anzahlSeiten);
// Neuinitialisierung
if (!e.HasMorePages)
{
strPrintText = textBox1.Text;
startSeite = 1;
anzahlSeiten = printDialog1.PrinterSettings.MaximumPage;
seitenNummer = 1;
}
File: Kurs MS10C# Bayerlein4.6.docx
Seite 67
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Zuvor m
müssen nochh bei den Komponenten
K
n printDialog1, printP
PreviewDiallog1 und
pageSettupDialog1 die Eigenscchaft Docum
ment auf prrintDocumen
nt1 gestellt werden.
Kurs 14 DLL
L
Das Einnbinden vonn DLL – ist relativ einfa
fach, wobei ich feststelllen muss, daass es verscchiedene
Typen vvon DLL- Dateien
D
gibt. Ich zeige zzuerst die Methode,
M
diee für die Dlll geeignet ist, die für
Nutzungg unter Visuual C++ odeer Borland C
C++ geschrrieben wurd
den. Dazu geehören in deer Regel
auch diee Interface – DLL von AD- Kartenn wie Orlow
wski- USB Karte,
K
Velleemann USB
B- Karte,
oder anddere Hardw
wareergänzu
ungen. Wennn allerdingss, wie vermeehrt zu beobbachten aucch C# DLLs ggeliefert werrden, benutzzt man natür
ürlich diese.
Dazu zuuerst einmall der Hinweeis auf die uunterschiedliche Bezeicchnung der V
Variablenty
ypen in
C/C++ uund C#. Hieer ein Auszu
ug aus Frannk Eller [3]: C#- Typen
n
h die gannzzahligen Datentypen
D
in C/C++:
Im Gegensatz dazuu sehen Sie hier
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 68
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Die Funnktionsaufruufe der DLL
L sind in derr Regel mit den C++ Datentypen
D
ddeklariert, da
d muss
man dannn aufpasseen. Z.B. ist der
d char in C ist 8 bit, der
d char in
n C# ist 16 B
Bit.
Die Heaader Dateienn, die meistt mit den DL
LL geliefertt werden, sind leider füür C# nicht direkt
d
nutzbar. Am sicherrsten ist die Erzeugungg einer Lib- Datei aus der DLL, auss der man dann
d
genau eentnehmen kann,
k
welch
he Funktioneen wirklich in der DLL
L verborgenn sind.
using S
System.Run
ntime.Inte
eropServic
ces;
Dann auußerhalb einner Funktion
n im Deklarrationsteil:
[DllImp
port("Proj
jecttestSq
qr.DLL")]
public extern st
tatic doub
ble sqr(do
double x);
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 69
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Diese D
Datei muss das
d Program
mm finden kkönnen, desh
halb am Ein
nfachsten koopieren nach
Projekt…\bin\debuug. Sollte nu
un der Fall aauftreten, daass C# diesee Funktion ssqr nicht fin
nden
kann, obbwohl Sie sicher
s
sind, dass diese F
Funktion drrin sein musss, dann hilfft nur die
Möglichhkeit, diese Dll zu unteersuchen. Icch habe in Foren den Hinweis auf eein Freewarre Tool
namens DependenccyWalker gefunden, m
mit dem eine DLL analy
ysiert werdeen kann. Maan lädt die
DLL unnd er listet alle
a möglich
hen exportieerten Funktiionen auf. Beispiel:
B
Hab
ab mit dem „alten
„
C++ Buuilder eine Dll
D erzeugt mit
m folgenddem Code:
double ___declspec((dllexport) sqr(doublee x)
{
retuurn (x*x);
}
Also einne einfache Quadratur der übergebbenen Zahl x.
Daraus hab ich die DLL nameens ProjecttTestSqr.d
dll
erzeugt.. In C# führrte dann derr normale A
Aufruf wie oben
o
beschriieben zu derr Fehlermelldung
Erst einne Suche mitt Dependen
ncyWalker bbrachte des Rätsels Lössung: Screennshot:
Der Nam
me der Funkktion ist dorrt mit „@sqqr$qd“ angeegeben. Dam
mit führte daann folgend
der Aufruf
zum Erffolg:
[DllImp
port("Proj
jectTestSq
qr.dll",En
ntryPoint="@sqr$qd
d")]
public extern st
tatic doub
ble sqr(do
double x);
private
e void but
tton1_Clic
ck(object sender, EventArgs e)
{
d
double y = Convert.
.ToDouble(
(textBox1.
.Text);
t
textBox1.T
Text = sqr
r(y).ToStr
ring("F5")
);
So zeigtte sich, dasss die DLL für
f das USB
B- ADC- Intterfaceboard
d von Prof. Dr. Orlowsski (in FH
erhältlicche) namenss „USBCard
dFH2.dll“ j etzt alle Naamen mit ein
nem Untersstrich davor wieder
findet: S
Screenshot Dependency
D
yWalker dieeser Dll:
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 70
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
d DLL der Vellemannn – USB- Karte
K
mit deer DLL K80055D liefertte
Die Anbbindungen der
folgenddes Bild, allee Namen tau
uchen wie iin der Doku
u auf:
mbar, wie ddie Parameterübergabe definiert istt, dass muss der
Natürlicch ist hier nicht entnehm
Doku odder der Heaader – Dateii der Dll enttnommen werden.
w
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 71
Visuelle Programmierung mit C#
Prof. Dr. Bayerlein
Zusammenfassung AD- DA mit dll für ME2600, USB Orlowski:
ME2600
Vorher einbinden von ME2600.dll. und using System.Runtime.InteropServices;
DA und AD haben 12 Bit Auflösung. Die übergebenen Werte bilden -10 bis +10 Volt ab in
iValue 0 bis 4095.
Initialisieren
[DllImport("ME2600.DLL")]
public extern static int me2600AOSetMode(int iBoardNumber, int iChannel, int
iRange, int iMode);
Beispiel
ex=me2600AOSetMode(0, 0, me2600Def.AO2600_MINUS_10,
me2600Def.AO2600_TRANSPARENT);
Auf DA Schreiben
[DllImport("ME2600.DLL")]
public extern static int me2600AOSingle (int iBoardNumber, int iChannel,
short iValue);
Beispiel
short outval = (short)numericUpDown1.Value;
int ex=me2600AOSingle(0, 0, outval);
Von DA Lesen
[DllImport("ME2600.DLL")]
public extern static int me2600AISingle(int iBoardNumber, int iChannel, int
iMode, refshort iValue);
Beispiel
short val=0;
int ex=me2600AISingle(0, (int)numericUpDownADChan.Value,
me2600Def.AI2600_MINUS_10 + me2600Def.AI2600_SINGLE_ENDED, ref val);
USB- Orlowski – Karte – alte USB 1.1 - Version
Vorher einbinden von der USBCardFH2.dll und
using System.Runtime.InteropServices;
Initialisieren
[DllImport("USBCardFH2.dll")]
public extern static bool _Init();
[DllImport("USBCardFH2.dll")]
public extern static bool _SetKanal2Bereich(byte a);
[DllImport("USBCardFH2.dll")]
public extern static bool _SetMode(byte a);
Beispiel
bool OK = _Init();
_SetKanal2Bereich(1);//bip1_4V=1, bipolar -4 bis +4Volt
_SetMode(2);
//StartRealtime=2
File: Kurs MS10C# Bayerlein4.6.docx
Seite 72
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Auf DA
A Schreib
ben
[DllImp
port("USBC
CardFH2.dl
ll")]
public extern st
tatic bool
l _SetAnal
logOut1(ushort a);
Beispiel
ushort Ua1=3000;
;
_SetAna
alogOut1(U
Ua1);
//
/ Einstell
len einer Spannung in 3V am
m D/A-Ausg
gang 1
Von D
DA Lesen
[DllImp
port("USBC
CardFH2.dl
ll")]
meData(ref float x);
public extern st
tatic bool
l _Realtim
Beispiel
float [
[] buf = new
n
float [8];
double fak = 10.
.0 / 4096.
.0;
_Realti
holen der Messwerte von Kan
imeData(re
ef buf[0])
); // Abh
nal 2;
fak).ToString("F3") + " V";
label2.
.Text = "U
Ua= " + (b
buf[1] * f
Neue DLL / Kllassenbib
bliothek mit C# erzeugen
e
n
Um einee eigenen neue Dll zu erzeugen,
e
ö ffne man eiin neues Pro
ojekt mit deer Eigenschaaft
Klassennbibliothek.
Ich habee dort die glleiche DLL
L mit der Quuadratfunktiion erzeugt wie mit dem
m Borland CBuilder:
C
Syntax:
namespa
ace ClassL
Library1
{
p
public cla
ass Class1
1
{
publ
lic static
c double s
sqrCSharp(
(double x)
)
{
return (x * x);
}
}
}
Wichtigg ist vor derr Methodend
definition daas Schlüsseelwort staticc, erst dann wird die Fu
unktion
sqrCShaarp exportieert und benu
utzbar.
Nach „B
Build Projecct“ ist eine DLL
D verfüggbar. Mit deefault – Nam
men sieht ess jetzt so aus:
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 73
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
LL in einem anderen Prrojekt benuttzen, so fügee man sie alls Verweis hinzu:
h
Will maan diese DL
(rechte M
Maus auf Verweise,
V
daann Verweiss hinzufügeen, dann kom
mmt linkes Bild.)
anschlieeßend ist daann die Funk
ktion sqrCSSarp verfügb
bar und kan
nn benutzt w
werden:
Beispiell:
double y = Conve
ert.ToDoub
ble(textBo
ox1.Text);
textBox
ss1.sqrCSharp(y).ToString(" F5"); ;
x1.Text = ClassLibr
rary1.Clas
Kurs 15 Zeittmessun
ng und 1ms Tim
mer
Die Zeittmessung kann
k
sehr geenau mit derr Klasse Sto
opwatch durrchgeführt w
werden. Mitt
Stopwat
tch stopwa
atch1 = ne
ew Stopwat
tch();
e
Mit der Eigensschaft Stopw
watch.Freq
quency kan
nn abgefrag
gt werden,
wird einne Instanz erzeugt.
mit welccher Frequeenz der Zäh
hler dieser S
Stopwatch hochläuft. Bei mir auf ddem PC warren es 2,6
GHz !!! Diese Zahll ist Motherrboard- abhäängig. Mit der
d Method
de .Start() lääuft der Zäh
hler los,
op() bleibt err stehen. Diie Eigenschhaft .Elapsed
dTicks enthäält dann diee Anzahl derr Takte
mit .Stop
zwischeen Start undd Abfrage . Die
D Zeit in sec bekom
mmt man dan
nn heraus duurch Divisio
on von
ElapseddTicks durchh Frequencyy. Laufzeiteen kann man
n dann messsen, indem man vor un
nd nach
dem zu messendenn Befehl .Ela
apsedTicks abfragt. Beispiel:
long dtstart = sto
opwatch1.El
lapsedTicks
s; dann koommt der Beefehl, von dem
d man diee Laufzeit messen
m
will…
long dtend = stop
pwatch1.Ela
apsedTicks; dann
long dt = (dtend ‐ dtstart)
); Anzeigee in Millisekkunden:
double dtsec = dt/
/ (double)S
Stopwatch.F requency * 1000; ufzeit= " +
+ dtsec.ToS
String("f2"); Label1.Text = "Lau
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 74
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Im Projekt „Test SttandardTim
mer mit Zeitm
messung Ba
ay“ wird nun
n die Perioddendauer dees SystemTimers gemessen. Dabei
D
läuft stopwatch endlos vor sich hin und
d im TimerTTick wird err lediglich
periodissch abgefraggt, die Absttände der Tiicks berechn
net und in einem
e
Speiccher TimeAv
vr
aufakkuumuliert, um
m den Durch
hschnittsweert zu bestim
mmen. Mit einem
e
zweitten Timer wird
w dann
zweimaal in der Sekkunde das Ergebnis
E
anggezeigt.
Man steellt fest, dass der System
m - Timer kkeine 1ms – Auflösung
g besitzt. Diie Periode kann
k
nur
in grobeen Schrittenn verstellt werden.
w
Bei m
meinem Deesktop ist dies etwa 15 ms, die Inteervallzeit
kann nuur ein Vielfaaches dieserr 15 ms betrragen.
Ich fragge mich, wiee es möglich
h ist, dass ddie C# -Entw
wickler wirk
klich einfachh nicht in der
d Lage
sind, dieesen Timer auf 1 ms geenau hinzubbekommen. Seit Jahrzeehnten (schoon bei Borland)
bietet m
man einen Tiimer an, in dem das Inttervall auf 1 ms verstelllt werden kkann, tatsäch
hlich ist
er in Wiirklichkeit nur 10 – 15
5 ms genau.
Ich bin froh, dass es
e meinem Drittherstell
D
ler Mario Prrantl (mario
[email protected])
genausoo geht wie mir.
m Er hattee für Borlannd einen 1 ms
m Timer en
ntwickelt, isst inzwischeen auch
auf C# uumgestiegenn und bietett auch dafürr seinen 1 ms
m Multimed
diatimer ann. Die FH haat eine
Campusslizenz für 150
1 € gekau
uft. Industrieenutzer müsssen sich eine eigene L
Lizenz besorrgen.
Dieser T
Timer ist alss DLL verfü
ügbar. Mann fügt ihn wiie in Kurs 14 schon besschrieben als
Referennz hinzu. Im
m Projekt „T
Test MMTim
mer mit Zeitm
messung Ba
ay“ findet m
man dann deen um
ddiesen Timeer erweiterteen Code. Naach Ergänzeen von
u
using MPS;
;
iinstanziiert man
m ihn mit
T
TMultimedi
iaTimer MM
MTimer1;
u
und initia
alisiert ihn
i
mit
M
MMTimer1 = new TMul
ltimediaTi
imer(null)
);
E
Er verfügt ebenfalls
e
über die Eigennschaft .Inteerval und
wird gestartet mit der
d Methodee .Enabled()
(). Interessan
nt sind der Zugriff
Z
undd die Erzeug
gung der
D es ja kein
ne Komponnente ist, son
ndern nur eiin Objekt eiiner Klasse,, kann
Ereignissfunktion. Da
man aucch auf keinee Eigenschaaften und Erreignisse im
m Property – oder Eigennschaftsfensster
zugreifeen.
Bei denn Email – Obbjekten ging
g dies mit
pop3.On
nWork +=ne
ew TWorkEv
vent(this.
.Work);
mit dem
m das Ereignnis Work daann verfügbbar war.
Hier wirrd dies mit „Delegates““, einem neeuen Konzep
pt von C# reealisiert. Daas Konzept ist
schwierrig zu versteehen (an dieeser Stelle nnicht nötig) die Durchfü
ührung siehht furchtbar einfach
aus. Mitt
MMTi
imer1.OnTi
imer = Eve
ventVomMMTimer;
wird diee Ereignisfuunktion EventVomMMTi mer erzeug
gt und kann dann wie ddie beim Staandard –
Timer bbekannte _T
Tick( ) – Ereeignisfunktiion benutzt werden:
void Ev
ventVomMMT
Timer(TMul
ltimediaTi
imer send
der)
{
……
…
}
Im Projekt erkennt man, dass jetzt
j
der Muultimediatim
mer eine Au
uflösung vonn 1 ms besitzt.
Eine gennaue Überpprüfung diesser Periodenndauer mit gemessener
g
r Zeit und eiinem eventu
uell
vorhanddenen Jitter (Schwanku
ung der Periiodendauer)) ist möglich
h, wenn mann mit diesem
m Timer
über einne AD- Kartte, die schnell genug isst, in jedem Event einen
n Impuls auuf einem DA
AAusganng erzeugt unnd mit einem
m Digitalsccope misst. Dies wird in
n dem Projeekt MMTim
mer mit
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 75
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
DA Imppuls auf ME
E2600 realisiiert. Dies Prrogramm lääuft natürlich nur mit eiiner ME260
00 –
Meilhauuskarte im PC.
P Aber mit einer andderen Karte (keiner USB
B, USB ist nnicht schnell genug)
ginge ess natürlich auch.
a
Das Verhalten
V
istt identisch dem
d Multim
mediatimer uunter Borlan
nd
CBuildeer. Es gibt eine
e von derr Last von W
Windows ab
bhängigen Schwankung
S
g, und statt 1 ms sind
es 10244 usec Perioddendauer au
uf einem „B
BlueChip – PC.
P
Kurs 16 RS2
232
Eine Veerbindung mit
m einer serriellen Schnnittstelle lässst sich
sehr einnfach aufbau
uen. Man beenutzt dazu die Kompo
onente
„SerialP
Port“. Über eine 3- Draaht- Verbinddung kann man
m jetzt
eine Vooll- Duplex- Verbindun
ng zweier Geeräte erreich
hen. Dies
bedeuteet eine gleich
hzeitige Üb
bertragung vvon Daten in
n beide
Richtunngen. Man muss
m
nur darauf achtenn, dass ersten
ns der
Sendeausg
gang („Trannsmit“) des einen Gerättes mit dem
m Sendeeingang
(„Receive““) des anderren Gerätess zusammen
ngeschaltet ssind. Zwei TransmitT
Ausgänge dürfen auf keinen Falll miteinandeer verbundeen werden. Bei
B dem 9
–poligen SubS
D Steccker eines PC sind dies die PIN 3 (Ausgang Transmit)
T
und PIN 2 (Eingang R
Receive). Die
D Ground- PIN müsseen natürlich auch
verbunden
n werden (P
PIN 5).
Will man 2 PCs miteiinander verb
binden, dan
nn benötigt m
man ein
„Nullmodeemkabel“, bbei dem PIN
N 2 und 3 üb
ber Kreuz vverbunden sind:
PIN 5
PIN 3
PIN 5
PIN 3
PIN 2
PIN 2
Damit ddie Geräte sich aber syn
nchronisiereen können, müssen die „Sendefreqquenzen“ glleich sein.
Diese w
werden mit der
d Eigensch
haft BaudR
Rate eingesteellt, Standarrdwert sind 9600 Baud
d, das sind
9600 Biits pro Sekuunde. Ebensso müssen P
Parity (Nonee,Odd, Even
n, Mark, Sppace) und Anzahl
A
der
StopBitss (One, Twoo, OnePointtFive) und die DataBits (7 oder 8) übereinstiimmen.
Dann giibt es noch Geräte (z.B
B. die Mikroocontroller) die nur eineen 0-5V TT
TL- Pegel au
uf der
seriellenn Leitung haben, die geenormte RS
S232 hat abeer einen Peg
gel von +155 V bis – 15V und ist
invertiert zu dem 0-5V
0
-Pegel. Will man ssolche Gerääte verbindeen, ist ein Peegelwandleer (z.B.
der Maxx232) nötig. Dort sind 2 Wandler ffür 2 Schnitttstellen mitt integrierteer
Spannunngserzeuguung zu finden. (Conrad Elektronik 1,50 €).
Hat ein PC keinen COM- Portt (das ist dieese serielle RS232)
R
meh
hr, dann kannn man sich
h einen
USB- Seriell – Adaapter kaufen
n (z.B. DIG
GITUS USB 2.0 SERIELL ADAPT
TER, bei Co
onrad 10
€).
Bevor m
man startet, kann man mit
m
foreach
h (string s in Seri
ialPort.Ge
etPortNam
mes())
cbPort.
.Items.Add
d(s);
z.B. in eeine CombooBox cbPortt alle auf deem PC verfü
ügbaren CO
OM- Ports errmitteln. Diie
tatsächlich angeschhlossene mu
uss dann in dder Eigenscchaft „PortN
Name“ eingeestellt werd
den, also
z.B.
serialP
Port1.Port
tName =“CO
OM1“
Dann kaann dieser Port
P mit .Op
pen() geöffnnet werden.
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 76
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Steht einn Text in eiinem string tx, so kann man nun eiinfach Dateen senden m
mit
serialP
Port1.Writ
te(tx);
Benutztt man WriteeLine, so wiird dem Texxt ein LineF
Feed (Hex0aa) anghängt,t, allerding kein
k
CarriageeReturn (Heex0d). In einer Textboxx wird dann
n kein Zeilenvorschub ggemacht. Also
A am
Besten nnur Write() benutzen und
u ggf. eineen Zeilenvo
orschub mit „\x0d“ undd „\x0a“ anh
hängen.
Empfanngene Datenn lesen kann
n man mit .R
ReadByte() oder .ReadC
Char(). Dam
mit keine Daten
verlorenn gehen, weenn der Eing
gangsbufferr voll ist, sollte man dieeses in einem
m Timer peeriodisch
z.B. allee 100 ms duurchführen. Erwartet m
man nur Tex
xt, so benutzzt man ReaddChar(), beei binären
Daten (zz.B. aus unsserem Scope) muss maan mit Read
dByte() lesen
n. Also in eiinem Timerr_Tick –
Event (iinp ist eine globale string- Variablle):
if (ser
rialPort1.
.BytesToRe
ead > 0)
{
for (int i = 0; i < se
erialPort1
1.BytesToR
Read; i++)
)
{
h=(char) s
serialPort
t1.ReadByt
te();
char ch
inp=inp
p+ch;
}
textBox
x1.AppendT
Text(inp);
;
inp = "";
"
}
Voreinggestellt ist eine
e ASCII – Codierungg, das heißt, deutsche Sonderzeich
S
hen gehen verloren,
v
im Emppfangenen Text
T steht do
ort ein “?”. W
nen, dann
Will an diese Sonderzeeichen auchh lesen könn
muss z.B
B. nach Inittialisierung der Befehl
serialP
Port1.Enco
oding = En
ncoding.De
efault;
ausgefüührt werden..
In der bbool - Eigennschaft .IsOp
pen kann m
man abfragen
n, ob ein Öfffnen geklapppt hat, denn andere
Prozesse können jaa auch einen
n COM- Porrt belegen.
B
veerändern, muss
m
zuvor der
d Prot gescchlossen weerden mit
Will maan Eigenschhaften wie BaudRate
.Close()).
Noch eiin Hinweis zur
z TextBoxx. Schreibt m
man die em
mpfangenen Zeichen in die Textboxx mit
AppenddText(), so wird
w dort nur eine neue Zeile gezeiichnet, wenn
n die Sondeerzeichen „\x0d“
„
und „\x00a“ hintereiinander aufttauchen odeer nur LineF
Feed („\x0a““) auftauchtt. Löst man dann
aber denn Text mit .Lines in ein
n String- arrray auf, dan
nn wird in diiesem Strinngarray auch
h schon
bei eineem CarriageeReturn - Zeeichen („\x00d“ ) eine neeue Zeile errzeugt. Willl man also auf
a
einzelnee Zeilen zuggreifen, kan
nn man sich verzählen. Beispiel:
Schreeibt man „H
Hello World
d“ + „\x0d“ +„Hello W
World“ in ein
ne
textB
Box1, so siehht man auf dem
d Bildsch
hirm linkes Bild, aber sowohl
s
in
textB
Box1.Lines[00] als auch in textBox1.Lines[1]steeht dann „H
Hello
Worlld“.
Will maan unsere Sccopes (z.B. Phillips Scoope PM339
94 oder baug
gleich PM 33380) auslessen, dann
muss m
man zuerst eiinen Befehl z.B. QW0001 mit einem
m anschließ
ßenden CarrriageReturn („\x0d“)
senden (kein LineF
Feed!!! hintterher). Die Nummer nach
n
QW gib
bt die Kanaalnummer an
n, 001
steht fürr Kanal a ussw.
Dann w
wird bei Fehllerfreiheit ein
e „0“ mit C
CarriageRetturn gesend
det, anschlieeßend komm
mt ein
ASCII – Header auus 17 mit Ko
omma getreennten Inforrmationen. Siehe
S
dazu H
Handbuch Kapitel
K
6
ab Seitee 6-33.
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 77
Visuelle Programmierung mit C#
Prof. Dr. Bayerlein
Anschließend nach diesem Header werden die Werte der Abtastpunkte in Binärform
übertragen. Das erste Byte ist ein vorzeichenbehaftetes High-Byte (Type sbyte), das zweite das
vorzeichenlose low-Byte (type byte). Der Spannungswert des Punktes ergibt sich zu
Y_zero+Y_resolution*(High*256+low) und der Zeitwert errechnet sich zu t=X_zero +
X_resolution*num, wobei num die Nummer des Abtastpunktes ist. Das Auslesen der seriellen
Schnittstelle muss hier mit ReadByte() durchgeführt werden.
Manche Multimeter benötigen als Sparversion für eine Pegelwandlung auf dem DTR- Signal
(PIN 4) eine positive Spannung, sonst geht gar nichts. Dies kann man erreichen, wenn man
serialPort1.DtrEnable = true;
einmal ausführt
Auszug aus Scope – Bedienanleitung siehe nächste Seite.
File: Kurs MS10C# Bayerlein4.6.docx
Seite 78
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Kurs 17 bis 20 entfe
ernt
Kurs 21 Data
aGridViiew
In dieseem Kurs soll die recht komplexe
k
K
Komponentee DatDataGridView einngeführt weerden.
Dazu starten wir eiin neues Pro
ojekt im Orddner Kurs 20#
2 und nen
nnen das Proojekt TestGrridView.
Dann eiine Komponnente DataG
GidView auuf das Formu
ular ziehen mit Dock T
Top.
Wir öffn
fnen den Spaalteneditor im
i Eigenschhaftenfensteer, dort unteer „Columnns“ die Aufliistung
öffnen:
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 79
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Dann füünf Spalten hinzufügen
n:
Das Forrmular siehtt dann so au
us:
ponente mit fest program
ammierter
Es soll ddiese Komp
Informaation gefülltt werden. Dazu den näcchsten
Program
mmabschnittt in ihr Prog
gramm außeerhalb des
Konstruuktors einfüg
gen:
string[] row0 = { "11
1/22/1968", "29", "Revolu tion 9", "Bea
atles", "The Beatles [Whiite Album]" }; string[] row1 = { "19
960", "6", "F
Fools Rush In ","Frank Sina
atra", "Nice 'N' Easy" };; string[] row2 = { "11
1/11/1971", "1", "One of These Days", "Pink Floyd"
", "Meddle" }}; string[] row3 = { "19
988", "7", "W
Where Is My M ind?", "Pixie
es", "Surfer Rosa" }; string[] row4 = { "5/
/1981", "9", "Can't Find MMy Mind","Cra
amps", "Psych
hedelic Junglle" }; string[] row5 = { "6/
/10/2003", "1
13", "Scatter brain. (As De
ead As Leaves
s.)","Radioheead","Hail to
o Thief"}; string[] row6 = { "6/
/30/1992", "3
3", "Dress", "P J Harvey", "Dry" }; Damit w
werden 7 strring- Arrayss vorbelegt mit je 5 Eleementen.
Hinter eeiner Taste mit
m Namen buttonLoadd dann folgeenden Text kopieren:
dataGr
ridView1.Ro
ows.Add(row
w0); ridView1.Ro
ows.Add(row
w1); dataGr
dataGr
ridView1.Ro
ows.Add(row
w2); ridView1.Ro
ows.Add(row
w3); dataGr
dataGr
ridView1.Ro
ows.Add(row
w4); ridView1.Ro
ows.Add(row
w5); dataGr
ridView1.Ro
ows.Add(row
w6); dataGr
ridView1.Co
olumns[1].H
HeaderText =
= "Name1";
dataGr
Nach Sttart und Klick auf dieseen button siieht dann die Form so aus:
a
Man beachte, wie die
d Spaltenü
überschrift dder zweiten
n Spalte mit dem Befehhl
dataGridView1.Colu
umns[1].Hea
aderText = "Name1"; verändeert werden kann,
k
also Zählung
Z
vonn Null.
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 80
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Fügt maan folgendee Zeile hinzu
u:
dataGridView1.Rows
s[3].Header
rCell.Value
e = "Zeile4"; Dann
D
wird sso auch einee Zeilenbescchriftung gaanz rechts möglich.
m
Man
M kann ddie Größe au
utomatisch einstellen
e
laassen mit z.B.
Oder
O
man giibt in der Eigenschaft „RowHeade
„
erWidth“ diie Größe
ng:
in Pixell an. Das geht aber nur so mit „EnaableResizin
Jetzt solllen die Datten aus der Komponent
K
te ausgeleseen werden. Wie
W kommtt man an diee Inhalte
dran: daazu bitte einne label3 un
nd eine textB
Box1 hinzuffügen und einen
e
Eventh
thandler hin
nter einem
CellClicck erzeugenn. Dann folg
genden Codde dort eingeeben:
Außerhaalb der funcction:
int c=0, r=0; Innerhaalb:
c = e.ColumnIndex;
; r = e.RowIndex; label3.Text="click
ked Row= "+
+r.ToString
g()+" Col= "+c.ToStri
ing(); )&&(c<dataG
GridView1.C
ColumnCount)&&(r<dataG
GridView1.RRowCount)) if ((c>=0)&&(r>=0)
textBox1.Tex
xt = dataGr
ridView1[c, r].Value.To
oString();
In dem Parameter e kann man den Spaltenn- und Zeileenindex abffragen, diesee werden naach c und
r geschrrieben und in
i label3 ausgegeben. D
Das Ausleseen geschieht wie bei einnem
zweidim
mensionalenn Array mit …[c,r] per Eigenschafft Value.
Ein Beispiel erkennnt man im nächsten
n
Scrreenshot, au
uch da hat die
d Zelle obeen links diee Zeile
Null
N und die Spalte Nulll:
Man
M kann jettzt z. B. in j eder Zelle einen
e
eiigenen Font einstellen. Beispielpro
ogramm
daazu hinter einer Taste bbuttonFont, vorher
eiinen FontDiialog auf diee Form zieh
hen:
if (fontDialog1.ShowDialog
g() == Dial
logResult.OK) aGridView1[
[c, r].Styl
le.Font = fo
ontDialog1.
.Font; data
t Comic San
ns MS, Schr
riftgröße 12 : Z.B. Zelle 2,2 mit
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 81
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Man muuss darauf achten,
a
dass keine Zellee angesprocchen wird, die
d es nicht ggibt, denn sonst
s
bricht ddas Program
mm mit Fehlermeldung ab. Da bieteet sich eine try – catch – Abfrage an.
Soll derr User Zeileen hinzufügeen können, dann muss folgende Eiigenschaft aauf true gesetzt
werden::
dataGridView1.Allo
owUserToAdd
dRows = tru
ue; dann gibbt es eine Leerzeile
L
am
m Ende der T
Tabelle. Weenn dort etw
was hineingeeschrieben wird,
w
sieht es so aus:
Nur dannn gibt es beei einem Klick in diesee neue Zeilee sofort einee Fehlermelddung, da deer Inhalt
sofort inn die Textboox geschrieb
ben werdenn soll. Dieseer existiert aber
a noch niicht. Die Eigenschaft
RowCouunt ist schoon um eins erhöht
e
wordden, aber fürr den Inhalt ist noch keein Speicherrbereich
zugewieesen wordenn. Das kann
n man abfanngen mit follgendem if:
if (dataG
GridView1[c, r].Value!=nu
ull) textBox1 .Text = dataG
GridView1[c, r].Value.ToSString(); Erst wennn die Zeilee verlassen wird, wird dder Inhalt aktualisiert
a
und
u der Sterrn verschwiindet.
Kurs 22 C# DirectX
D
Hier sinnd alle Inforrmationen und
u ein kleinnes Beispiellprogramm auf der Seitite
http://w
www.fhluebeckk.de/Inhalt/003_Hochsch
hulangehoerrige_Ch031/04_FB_Elektrotechnikk/04_Laborre_und_In
stitute/663_Labor_E
ESA_RT/Visual-C_/DirrectX_mit_
_C_/index.httml
zu findeen. Es wird eine x- Datei angezeiggt, die natürllich die 3D-- Bildinform
mation enthäält.
Solche D
Dateien kannn man mit dem Freew
wareprogram
mm Googlesketch erstelllen, das maan im
Internett findet. Auff der Seite sind
s
Screensshots des C# - Program
mmes und veergleichsweeise eines
DirektX
X- Viewers zusehen.
z
Kurs 23 MyS
Sql und C#
Auf derr Seite http:///www.fhluebeckk.de/Inhalt/003_Hochsch
hulangehoerrige_Ch031/04_FB_Elektrotechnikk/04_Laborre_und_In
stitute/663_Labor_E
ESA_RT/Visual-C_/MY
YSQL/index.html
findet m
man alles, was
w man wissen muss, uum mit C# eine
e mySL- Datenbankk anzusprech
hen. Dies
wurde inn einer Diplomarbeit von
v Frau Yaannan Shen erarbeitet, die
d dort aucch zur Verfü
ügung
gestellt wird. Ein Beispielprog
B
gramm vervvollständigt das Angebo
ot. Dort ist eein
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 82
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Anweseenheitszähleer mit Sourcce zu findenn, der es erm
möglicht, in einer Verannstaltung mit
m
Studiereenden den Barcode
B
dess Ausweisess zu scannen
n. Die Anwesenheitszeeit und Datu
um
werden dann in einner MySQL-- Tabelle unnd die Studiierendendatten in einer zweiten tab
belle einer
Datenbaank abgeleggt.
Kurs 24 Meilhaus ME
M 4660
0
Inzwiscchen sind auuch moderneere Versionnen der Meillhauskarte (ME
(
4660) uund der
Orlowskkikarte (US
SB 2.0 – Verrsion) entstaanden und im
i Labor veerfügbar. Ichh habe die
Anleitunngen dazu im
i Internet veröffentliccht.
ME46600: (geht sow
wohl mit 32
2.Bit als aucch mit 64 BitB Window
ws!)
http://w
www.fhluebeckk.de/Inhalt/003_Hochsch
hulangehoerrige_Ch031/04_FB_Elektrotechnikk/04_Laborre_und_In
stitute/663_Labor_E
ESA_RT/Visual-C_/Kuurs_24_AD_
_Meilhaus_
_4660/indexx.html
Kurs 25 NI mit
m NIDA
AQmx
Ab Winn7 ist nur nooch die neuee Interface- Version miit DAQmx zu
z verwendden, die veraaltete NI
– traditiional darf niicht mehr benutzt werdden. Diese hatte
h
zu Beg
ginn den Naachteil, dasss die
Rechenzzeit im Verggleich zu „ttraditional“ gut um den
n Faktor 10 größer ist. D
Dauert einee SingleAD-Abffrage mit „ttraditional“ ca 300 µsecc, so dauertte es auf dem
m gleichen PPC mit gleiicher
Karte 2--3 ms. Ein Takten
T
mit 1 ms ist dannn unmöglicch. Dies lag
g aber darann, dass ein Fehler
F
bei
unserem
m Programm
m vorhanden
n war. Eine Task muss gestartet werden,
w
dannn gehen die AD- DA
– Wanddlungen schnneller. Wir hatten den S
Startbefehl nicht gegeb
ben, so hat ddas Interface bei
jeder W
Wandlung diee Task gestaartet und daanach beend
det. Und ein
n Start dauerrt halt ein paar
p msec.
Eine ricchtige Lösunng für DAQ
Qmx gibt es in meinem Windfc#- Projekt
P
an V
Version 7.4.15 in der
Datei „H
Hardwaretoools /DAQm
mx_Basics_N
NChannel.ccs“, siehe do
ort.
Dazu zuuerst zwei Verweise
V
hin
nzufügen:
Anschliießend musss dann im Projektmapp
P
pen-Exploreer dann folgendes steheen:
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 83
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Dann
using NationalInst
truments.DA
AQmx; Und dannn sind folggende Befeh
hle möglich :
AD ausllesen:
double val = rscha
an.ReadSing
gleSample() ; Ausgabe auf DA
wschan.WriteSingle
eSample(tru
ue, val); zuvor m
muss man diie beiden Taasks rschan und wschan
n „kreieren““ mit
AnalogSing
gleChannelR
Reader rsch
han; gleChannelW
Writer wsch
han; AnalogSing
Und dass geht so: Erst
E die Instaanziierung dder AD- Tassks: (DA geeht ähnlich, siehe Dateii .cs):
Task taskAI = new Task("abci
i"); dann
taskAI.A
AIChannels.CreateVolt
tageChannel
l(actdev+"/a
ai0", "aiCh
hannel0", A
AITerminalC
Configurati
ion.Rse,Min
nI, MaxI, AIVoltageUni
its.Volts); Dann
rschan = new Analo
ogSingleCha
annelReader
r(taskAI.Stream); dann soollte es nachh taskAI.Staart(); gehenn.
Weiteree Hinweise kann
k
man auf
a den Interrnetseiten von
v mir zu diesem
d
Punkkt finden.
Kurs 26 USB
B- Orlow
wski 2.0
0
USB – O
Orlowski USB
U 2.0 Verrsion: (geht nur auf 32. Bit Window
ws)
http://w
www.fhluebeckk.de/Inhalt/003_Hochsch
hulangehoerrige_Ch031/04_FB_Elektrotechnikk/04_Laborre_und_In
stitute/663_Labor_E
ESA_RT/Visual-C_/Kuurs_26_AD--_USB_-_K
Karte_2_0_O
Orlowski/in
ndex.html
Kurs 27 Inte
erface mit
m TCP//IP
Viele G
Geräte komm
munizieren heute
h
über eeine schnellle Ethernet- Verbindunng oder überr Internet.
Das wirrd in C# aucch gut unterrstützt. Als B
Beispiel solll die Komm
munikation m
mit einer WAGOW
Klemmee gezeigt werden,
w
die in der Indusstrie als Anaalog – und DigitalD
Inteerface Verw
wendung
findet.
Man bennötigt Zugrriff auf dieseen Namespaace:
using System.Net.S
Sockets; dann kaann man einnen TCP – Client
C
instannziieren:
TcpClient tcpClien
ntWAGO = ne
ew TcpClien
nt(); Hinter eeinem Buttoon „Connectt“ kann mann dann mit folgendem
f
Programm
P
eeine Verbin
ndung
aufbaueen:
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 84
Visuelle Programmierung mit C#
Prof. Dr. Bayerlein
try { if (!tcpClientWAGO.Connected) { tcpClientWAGO.Connect("192.168.0.2",502);//tcpClient.Connect("193.175.124.132", 502); if (tcpClientWAGO.Connected) toolStripStatusLabel1.Text = "Wago is connected"; } else MessageBox.Show("Verbindung besteht bereits","TCP Connection Info", MessageBoxButtons.OK); } catch (SocketException) { MessageBox.Show("Verb.‐aufbau nicht möglich","TCP Connection Error", MessageBoxButtons.OK); } Dabei wird eine Nachricht in ein toolStripStatusLabel geschrieben, ein StatusStrip muss
natürlich dann vorhanden sein.
Wenn eine Verbindung gelungen ist, kann man Lesen und Schreiben mit einem
NetworkStream:
NetworkStream netStreamWAGO; Den muss man mit der Verbindung zusammenführen. Das Schreiben geht so:
netStreamWAGO = tcpClientWAGO.GetStream(); if (netStreamWAGO.CanWrite) { byte[] sendBytes = new byte[12]; //lokales Array mit Daten netStreamWAGO.Write(sendBytes, 0, sendBytes.Length); } Das Lesen geht so:
netStreamWAGO = tcpClientWAGO.GetStream(); if (netStreamWAGO.CanRead) { byte[] readBytes = new byte[tcpClientWAGO.ReceiveBufferSize]; netStreamWAGO.Read(readBytes, 0, (int)tcpClientWAGO.ReceiveBufferSize); } Anschließend sind im Byte –Array die Daten.
Um jetzt mit den Wago –Klemmen einen DA- Wert auszugeben, muss man das Mod- Bus –
Protokoll bedienen. Bei anderen Geräten muss man dann das entsprechend Protokoll den
Datenblättern entnehmen.
Das Wago- Protokoll ist den Versuchsunterlagen zu entnehmen und wird am Versuchstag zur
Verfügung gestellt.
WindfC#, mein großes Regelungstechnik- Toolprogramm.
Weitere Informationen kann man erhalten, wenn man sich das folgende Projekt, das auch als
Source- Code in C# erhältlich sind - quasi als Freeware – anschaut:
http://www.fhluebeck.de/Inhalt/03_Hochschulangehoerige_Ch031/04_FB_Elektrotechnik/04_Labore_und_In
stitute/63_Labor_ESA_RT/WindfCSharp/index.html
File: Kurs MS10C# Bayerlein4.6.docx
Seite 85
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Einig
ge Hinw
weise
Proble
ematik mit
m Dock
Werdenn zwei Elem
mente mit Do
ock auf Topp gesetzt, errhebt sich diie Frage, weelcher wirkllich
zuerst ooben und weelche dann darunter
d
plaatziert wird.. Beispiel ToolStrip und
nd Panel:
So soll ees sein. Manchmal abeer passiert ess, dass bei beiden
b
Elem
menten, die auf Docksty
yle.Top
gesetzt w
werden, einne falsche Platzierung eerfolgt, z.B.. so:
Es hänggt von der Reihenfolge
R
ab, mit der diese Elem
mente der Fo
orm bzw. deem Containeer
hinzugeefügt worden sind. Wiee kann man diese nachtträglich veräändern? So:: Man muss die Datei
„designner“, die norrmalerweisee nicht angeefasst wird, nun
n doch öfffnen. In deem Teil, derr oben
rechts aausgeschnittten ist, kann
n man die Zuuordnung erkennen.
e
Das Element,, das unter dem
d
anderenn steht, gewiinnt!
Param
meter in Funktion
F
nsaufrufe
en und Arrays
A
Dort gibbt es einige Änderungeen gegenübeer C++:
Beispielle:
Deklaraation von Arrrays:
C++
double
C#
xein[maxx2n]
doubl e[] xein = new dou
uble[max2n
n]
Funktioonsaufruf
C++
void xr__db(double&
& xrr, doub
ble p[10],
double&
& q[10], intt m)
File: Kuurs MS10C## Bayerlein
n4.6.docx
C#
void xr_db(ref double
e xrr, dou
uble[]
p, ref double[] q, in
nt m)
Seite 86
Visuellee Programm
mierung mit C#
Prof. Dr. Bayerlein
B
Xrr wirdd referenzieert aufgerufe
fen, damit köönnen Wertte zurückgegeben werdden, es wird
d nur der
Pointer übergeben. Das Array p wird in ddie Funktion
n hineingegeeben und voon der Funk
ktion nicht
verändeert. Das Arryy q wird wieder referennziert, also lediglich mit
m Pointer üb
übergeben un
nd kann
von der Funktion verändert
v
weerden.
Zeilen
nnummern im Ed
ditor
Manchm
mal helfen Zeilennumm
Z
mern im Texxteditor. Siee aktiviert man
m mit Mennü Debuggeen 
O
Optionen…
D
Dann im Tex
xt-Editor  Alle Spracchen
D
Dort Klick au
uf Zeilennu
ummern:
W
Weitere Projekte werde ich auf denn Internetseiiten unter
www.fhh-Luebeck.dde, Studieerende FB
B EI  Lab
bore & Institute,  Labbor
Regelunngstechnik  Visual-C
C# -Page odder Windfc#
#
demnäcchst in loser Folge veröffentlichen..
Stand N
November 2012
Prof. Drr. Bayerleinn
File: Kuurs MS10C## Bayerlein
n4.6.docx
Seite 87

Similar documents