Laden...

Eine HandyButton-Klasse (Mehrfachclick)

Erstellt von s-sharp vor 15 Jahren Letzter Beitrag vor 15 Jahren 2.892 Views
S
s-sharp Themenstarter:in
162 Beiträge seit 2008
vor 15 Jahren
Eine HandyButton-Klasse (Mehrfachclick)

*** Wird derzeit umgeschrieben - Anhang daher entfernt *****

Hallo zusammen,

dieser Beitrag hat mich motiviert, eine HandyButton-Klasse zu schreiben.

Jeder, der ein Handy besitzt und schon einmal eine SMS damit geschrieben hat, kennt sicherlich die Mehrfachfunktion der einzelnen Tasten.

Je nach Modus und Handytyp, wird beim Druck auf eine Taste eine bestimmte Funktion ausgeführt.
Beim wählen einer Telefonnummer wird bspw. die 'Hauptfunktion' der Taste ausgeführt, nämlich das Setzen einer Zahl.

Schreibt man eine SMS, so wird die 'Nebenfunktion' der Taste ausgeführt, nämlich das Setzen eines Buchstabens oder Zeichens, wobei jeder Taste mehrere Buchstaben oder Zeichen zugeordnet sein können. Durch mehrfaches klicken einer Taste kann man so über sämtliche ihrer Funktionen iterieren.

Im Anhang befindet sich der Sourcecode der Klasse, sowie eine Beispielanwendung in Form einer vorgefertigten Handytastatur, ebenfalls inklusive SourceCode.

Das Ganze ist JustForFun entstanden, da ich es für mich als nettes Thema zur Einarbeitung in C# angesehen habe.

Wenn Ihr Lust hab, könnt Ihr die Klasse erweitern, verändern, oder was auch immer.

Über Feedback bin ich natürlich sehr dankbar (es hilft mir beim Lernen!)

Danke.

Noch eine kurze Erläuterung:
So ein Handybutton wird zur Laufzeit erzeugt. Im Konstruktor werden die dem Button zugeordneten Zeichen in Form eines Char-Arrays übergeben.
Das erste Element dieses Array wird als 'Hauptzeichen' angesehen,; vergleichbar zu den Zahlen auf der Handytastatur.
Die restlichen Elemente sind die 'Nebenzeichen'; sie werden etwas kleiner unter das 'Hauptzeichen' gezeichnet.

Desweiteren wird im Konstruktor ein Control angegeben, welches als Ziel für die Tastendrücke dienen soll; idealerweise eine Textbox.

Außerdem kann festgelegt werden, wieviele Zeichen auf einem Button sichtbar dargestellt werden sollen, unabhängig davon, wieviele Zeichen sich tatsächlich hinter dem Button befinden.

Es gibt zwei Eingabemodi: Zahlen und Text.

Die Containerklasse, auf der der Button erzeugt werden soll (Form, Panel...), muss das Interface IInputMode implementieren. Über die dazugehörige Eigenschaft 'InputMode' wird der entsprechende Eingabemodus abgefragt, der bspw. über RadioButtons auf dem Container festgelegt werden kann.

22

Gruß
s-sharp

S
s-sharp Themenstarter:in
162 Beiträge seit 2008
vor 15 Jahren

Besonders interessieren würde mich, ob es eine bessere Möglichkeit gibt als das Interface, sicherzustellen, dass das Parent-Control eine Möglichkeit bietet, den Eingabemodus zu ändern und zurückzugeben.

Gruß
s-sharp

Gelöschter Account
vor 15 Jahren

kleine anmerkungen zu deinem code:

1.

this.Parent = (Control)parentControl;

das hast du im konstruktor und im allemeinen verlangen es deine konstruktoren, das man den parent mitgibt. das problem hierbei bzw das sinnlose hierbei sit, das man durch das hinzufügen zu einer controlcollection, jegliche voreinstellung überschreibt, das innerhalb der add-methode der controlcollection der parent abermals gesetzt wird. von daher ist die anweisung innerhalb deines codes sinnlos.

2.
der konstruktorparameter buttonTopLeft sollte wie im framework einfach nur location sein, da zumindest ich das am anfang etwas verwirrend fand.

3.
ebenso vermisse ich die möglichkeit einen timer von außerhalb mitgeben zu können, damit man nicht für jedes control eine eigene instanz hat und damit man das intervall anpassen kann (z.b. auf dem touchscreen ein anderes als wenn die mouse zur verfügung steht)

4.

float xPoint = (this.ClientRectangle.Width - size.Width) / 2;

die berechnung dürfte ein int zurückgeben. ist das absicht?

5.

Font font = new Font(this.Font.Name, fontSize, fontStyle);

wird nirgends disposed.

mein persönlicher eindruck:
ich finde dein code ist sauber strukturiert und wirklich vorbildlich dokumentiert. wirklich sehenswerter code. respekt.

S
s-sharp Themenstarter:in
162 Beiträge seit 2008
vor 15 Jahren

Hallo JAck30lena,

vielen vielen Dank für Dein Feedback 👍

(ist ja leider nicht so üppig, was hier sonst so zurückkommt X( )

zu 1:
Das verstehe ich ehrlich gesagt nicht so ganz.
Da es sich bei der Klasse nicht um eine Komponente (heißt das in C# so?) handelt, die ich zur Designtime auf der Form platzieren kann, kann ich sie nur zur Runtime erzeugen.
Dabei muss ich dann doch angeben, welches das Parent-Control sein soll.

Meinst Du, es wäre besser, anstatt


HandyButton hb11 = new HandyButton(this, textBox1, new Point(xOffset + 2, yOffset + 2), new char[] { '1', '-', '.', '@', '!', '§', '%', '&', '?' }, 4);

den Button so zu erzeugen


this.Controls.Add(new HandyButton(textBox1, new Point(xOffset + 2, yOffset + 2), new char[] { '1', '-', '.', '@', '!', '§', '%', '&', '?' }, 4));

?

zu 2:
Hast Du recht - werde mich diesbezüglich dem Standard anpassen

zu 3:
Sehr gute Idee!

zu 4:
Also bei mir gibt die Berechnung schon eine Gleitkommazahl zurück

zu 5:
Stimmt, wird nachgeholt

zu Deinem Fazit:
Vielen Dank - soetwas baut auf und motiviert 🙂

Könntest Du noch etwas zu dem Einsatz des Interfaces sagen?
Ist es sinnvoll, das so umzusetzen, oder gibt es bessere Ansätze?

(Ziel ist, zu garantieren, dass die Form, das Panel, oder wo immer auch der HandyButton drauf liegt, die Möglichkeit bietet, den Eingabemodus festzulegen.)

Gruß
s-sharp

Gelöschter Account
vor 15 Jahren

zu 1:
nein. wenn du z.b. compilierst, dann sollte dieser button in der toolbox erscheinen.
außerdem :


HandyButton hb11 = new HandyButton(this, textBox1, new Point(xOffset + 2, yOffset + 2), new char[] { '1', '-', '.', '@', '!', '§', '%', '&', '?' }, 4); 
hb11.Size = new Size(500,500);
this.Controls.Add(hb11);

geht ja auch.
designzeit ist im prinzip eine vorschau der runtime-zeit und macht genau das selbe iwe in der runtimezeit auhc. daher kannst du alles was in den Design.cs drinn steht auch genausogut in jeder x-beliebigen methode auch machen.

zu 4:
ja war mein fehler. zize ist ja ein float;

Könntest Du noch etwas zu dem Einsatz des Interfaces sagen?
Ist es sinnvoll, das so umzusetzen, oder gibt es bessere Ansätze?

nicht sinnvoll, da wie gesagt volgendes passiert wenn man ihn zu einer controlcollection hinzufügt:

1.beim aktuellen parent wird das neue control entfernt
2. parent-eignschaft vom neuen control wird auf null gesetzt
3. parent-eigenschaft wird auf neuen parent gesetzt
4. control wird zur collection hinzugefügt.

demanch fliegt z.b. eine nullreferenceexception bei volgendem code, wenn man mit der toolbox deinen button auf eine standardoberfläche zieht:


actInputMode = (Parent as IInputMode).InputMode;

ich würde stattdesen eine property definieren, die jeder user anpassen kann und als dabei einen standardwert definieren. z.b. InputMode.Primary

S
s-sharp Themenstarter:in
162 Beiträge seit 2008
vor 15 Jahren

Ups,

mir war absolut nicht bewusst, dass es in C# so ohne weiteres möglich ist, aus einer Klasse eine Komponente (in Delphi heißt es so) zu machen, bzw. dass das automatisch geschieht 8o

Unter diesen Umständen ist natürlich vollkommen klar, was Du meinst.

Danke!

Gruß
s-sharp

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo s-sharp,

(ist ja leider nicht so üppig, was hier sonst so zurückkommt X( )

"Projekte" ist auch dafür da: "Vorstellung von eigenen Projekten zur freien Benutzung durch die Community". Hier sollte also der Nutzen der anderen im Vordergrund stehen, nicht der eigene. Entsprechend sind fachliche Diskussionen in "Projekte" nicht erwünscht. Jemand, der das Projekt benutzen will, sollte sich nicht durch für die Benutzung der Komponente irrelevante Diskussionen wühlen müssen.

Natürlich ist es ok, wenn sich einer die Komponente anschaut und Verbesserungsvorschläge postet. Aber daraus sollte sich keine Diskussion entwickeln.

herbivore

S
s-sharp Themenstarter:in
162 Beiträge seit 2008
vor 15 Jahren

Hallo herbivore,

entschuldige bitte.

Als ich allerdings letztes Mal mein Projekt in 'Basistechnologien und allgemeine .NET-Klassen' eingestellt habe, und gezielt um Diskussion zu meinem Quelltext gebeten habe, wurde das Thema dann nach 'Projekte' verschoben.

Das finde ich dann erhlich gesagt nicht gut, denn damit wäre die Diskussion dann ja vorbei.

Gruß
s-sharp

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo s-sharp,

ja, das ist schon eine zweischneidige Sache. Ein Projekt mit der Bitte um Kritik einzustellen, ist für die Community eine aufwändige Sache. So nützlich das für dich ist, so aufwändig ist es für andere. Daher sprengt so eine Bitte auch den Rahmen von "Basistechnologien" und daher wurde dein letztes Projekt auch nach "Projekte" verschoben. Anderseits ist auch "Projekte" aus den o.g. genannten Gründen nicht der perfekte Ort für "Mit der Bitte um Kritik"-Projekte. Das wollte ich deutlich machen.

Es freut mich, wenn du Projekte durchführst und das Ergebnis der Community zur Verfügung stellst. Nur solltest du dafür keine direkte Gegenleistung verlangen ... das ist das Prinzip des Projekte-Forums.

Wenn ich die Diskussion damit beende, ist das durchaus erwünscht. Ich habe ja begründet, warum solche Diskussionen unterbleiben sollen.

Das ändert nichts daran, dass du in "Rund um die Programmierung" Fragen zur Programmgestaltung und zum Programmaufbau stellen kannst. Nur eben nicht ein ganzes Projekt, dass dann andere für dich kostenlos durchsehen sollen.

herbivore