Autor Beitrag
flexray
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Di 03.04.12 10:57 
ich habe eine Klasse erstellt, die eine eigene Messagebox darstellen soll (ich weiß, dieses Thema wird 100.000mal diskutiert in Foren - brauche dennoch noch mal Hilfe).

Meine eigene Msgbox funktioniert, jedoch glaube ich habe ich von der C#-Struktur her ein ganz schönes Durcheinander erzeugt (bin neu in C#) - und bitte Euch um Hilfe und Tipps, Ordnung in meine Klassen zu bekommen.

Hier der Code: (Entschuldigung, jetzt kommt viel Code...)

-------------- Klasse MyMessagebox -----------------------------------

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
308:
309:
310:
311:
312:
313:
314:
315:
316:
317:
318:
319:
320:
321:
322:
323:
324:
325:
326:
327:
328:
329:
330:
331:
332:
 
public partial class MyMessagebox : Falcon.HForm
    {
        static MyMessagebox newMessageBox;
        static string Button_id;
        static string textYes = "Yes";
        static string textNo = "No";
        static string textOK = "OK";
        static string textCancel = "Cancel";
     
        // Buttons für die Messagebox
        public enum MSGBOX_KEYS
        {
            OK_ONLY = 0,
            OK_CANCEL = 1,
            YES_NO = 2,
            YES_NO_CANCEL = 3,
            NO_KEYS = 4
        };

        // Variablen für Msgbox-Größe
        UInt16 MsgboxLength = 252;
        UInt16 MsgboxHeight = 146;
        UInt16 MsgboxPosX = 10;
        UInt16 MsgboxPosY = 166;
        UInt16 MsgboxPosXQuer = 128;
        UInt16 MsgboxPosYQuer = 2;
        UInt16 MsgboxTextLength = 202;
        UInt16 MsgboxTextHeitht = 75;
        string MsgboxBackgrountImg = "\\FlashDisk\\Falcon\\Resources\\Msgbox_Logo_gelb146.png";      
        UInt16 MsgBoxButtonOKPosX = 40;
        UInt16 MsgBoxButtonOKPosY = 98;
        UInt16 MsgBoxButtonCancelPosX = 131;
        UInt16 MsgBoxButtonCancelPosY = 98;


        public delegate void CloseMyMessageboxDialogEvent();
        public event CloseMyMessageboxDialogEvent CloseMyMessageboxDialog;


        public MyMessagebox()
        {
            InitializeComponent();

            // Wenn Hochkant oder Sprache von MainMenu aus geändert wurde
            this.PropertyChanged += new PropertyChangedEventHandler(MyMessagebox_PropertyChanged);
        }

        /*
         * Messagebox anzeigen
         */

        public static string ShowBox(string txtMessage, string txtTitle, MyMessagebox.MSGBOX_KEYS MsgboxKeys) 
        { 
            newMessageBox                    = new MyMessagebox();
 
            //Msgbox erstellen / Positionen der labels und buttons festlegen
            newMessageBox.UpdateControls(txtTitle, txtMessage, MsgboxKeys);
            
            newMessageBox.ShowDialog(); 
            
            return Button_id; //Gedrückten Button zurück geben
        }

        private void MsgBox_Close()
        {
            //Msgbox schließen
            newMessageBox.Dispose();
        }

        /*
         * Button OK klick
         */

        private void MsgBoxButtonOK_Click(object sender, EventArgs e)
        {
            Button_id = "1";
            MsgBox_Close();
        }

        /*
         * Button Cancel klick
         */

        private void MsgBoxButtonCancel_Click(object sender, EventArgs e)
        {
            Button_id = "2";
            MsgBox_Close();
        }

        private void MyMessagebox_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            //Hochformat / Querformat
            if (e.PropertyName == "Hochkant")
            {
                // Controls werden von anderem Thread gedreht
                this.Invoke((System.Threading.ThreadStart)delegate
                {
                    //Handheld im Hochkantformat: Positionen festlegen
                    if (Hochkant)
                    {
                        //this.ClientSize = new System.Drawing.Size(MsgboxLength, MsgboxHeight);
                        //this.Location = new System.Drawing.Point(MsgboxPosX, MsgboxPosY);
                        newMessageBox.ClientSize = new System.Drawing.Size(newMessageBox.MsgboxLength, newMessageBox.MsgboxHeight);
                        newMessageBox.Location = new System.Drawing.Point(newMessageBox.MsgboxPosX, newMessageBox.MsgboxPosY);

                        tMsgboxHeader.Location = new System.Drawing.Point(1313);
                        tMsgboxText.Location = new System.Drawing.Point(2449);
                        MsgBoxButtonOK.Location = new System.Drawing.Point(newMessageBox.MsgBoxButtonOKPosX, newMessageBox.MsgBoxButtonOKPosY);
                        MsgBoxButtonCancel.Location = new System.Drawing.Point(newMessageBox.MsgBoxButtonCancelPosX, newMessageBox.MsgBoxButtonCancelPosY);
                    }
                    else //Handheld im Querformat: Positionen festlegen
                    {
                        //this.ClientSize = new System.Drawing.Size(MsgboxLength, MsgboxHeight);
                        //this.Location = new System.Drawing.Point(114, MsgboxPosYQuer);
                        newMessageBox.ClientSize = new System.Drawing.Size(newMessageBox.MsgboxLength, newMessageBox.MsgboxHeight);
                        newMessageBox.Location = new System.Drawing.Point(114, newMessageBox.MsgboxPosYQuer);

                        tMsgboxHeader.Location = new System.Drawing.Point(1313);
                        tMsgboxText.Location = new System.Drawing.Point(2449);
                        MsgBoxButtonOK.Location = new System.Drawing.Point(newMessageBox.MsgBoxButtonOKPosX, newMessageBox.MsgBoxButtonOKPosY);
                        MsgBoxButtonCancel.Location = new System.Drawing.Point(newMessageBox.MsgBoxButtonCancelPosX, newMessageBox.MsgBoxButtonCancelPosY);
                    }

                });
            }

            // Sprache geändert
            if (e.PropertyName == "Language")
            {
                // Controls werden von anderem Thread gedreht
                this.Invoke((System.Threading.ThreadStart)delegate
                {
                    //Text für Textbox und Header wird an Funktion MyMessagebox übergeben. Muss hier nicht angepasst werden
                    
                    //Texte der Buttons ändern
                    MsgBoxButtonOK.Text = rm.GetString("MyMessagebox_OK", ci);
                    MsgBoxButtonCancel.Text = rm.GetString("MyMessagebox_Cancel", ci);

                    textYes = rm.GetString("MyMessagebox_Yes", ci);
                    textNo = rm.GetString("MyMessagebox_No", ci);
                    textOK = rm.GetString("MyMessagebox_OK", ci);
                    textCancel = rm.GetString("MyMessagebox_Cancel", ci);

                });
            }
            

        }


        /// <summary>
        /// Anzeigen aktualisieren
        /// </summary>
        public void UpdateControls(string MsgboxHeader, string MsgboxText, MyMessagebox.MSGBOX_KEYS MsgboxKeys)
        {

                UInt16 ButtonHeight = 40//Button-Höhe auf 40 initialisieren
                
                System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MyMessagebox));

                // ÜBERSCHRIFT
                tMsgboxHeader.Text = MsgboxHeader;

                // MSGBOX-TEXT
                tMsgboxText.Text = MsgboxText;

                // HÖHE DER MSGBOX FESTLEGEN
                
                // Höhe für Buttons festlegen
                if (MsgboxKeys == MSGBOX_KEYS.NO_KEYS)
                    ButtonHeight = 0;
                
                // Textlänge < 38 Zeichen
                if (MsgboxText.Length < 28)
                {
                    MsgboxHeight = 146;
                    MsgboxPosX = 10;
                    MsgboxPosXQuer = 128;
                    MsgboxPosY = 166;
                    MsgboxPosYQuer = 50;
                    MsgboxBackgrountImg = "\\FlashDisk\\Falcon\\Resources\\Msgbox_Logo_gelb146.png";
                    MsgboxTextHeitht = (UInt16)(75 - ButtonHeight);
                    MsgBoxButtonOKPosX = 40;
                    MsgBoxButtonOKPosY = 98;
                    MsgBoxButtonCancelPosX = 131;
                    MsgBoxButtonCancelPosY = 98;
                }
                else if (MsgboxText.Length < 60)
                {
                    MsgboxHeight = 175;
                    MsgboxPosX = 10;
                    MsgboxPosXQuer = 128;
                    MsgboxPosY = 166;
                    MsgboxPosYQuer = 50;
                    MsgboxBackgrountImg = "\\FlashDisk\\Falcon\\Resources\\Msgbox_Logo_gelb286.png";
                    MsgboxTextHeitht = (UInt16)(104 - ButtonHeight);
                    MsgBoxButtonOKPosX = 40;
                    MsgBoxButtonOKPosY = 127;
                    MsgBoxButtonCancelPosX = 131;
                    MsgBoxButtonCancelPosY = 127;

                }
                else
                {
                    MsgboxHeight = 275;
                    MsgboxPosX = 10;
                    MsgboxPosXQuer = 128;
                    MsgboxPosY = 115;
                    MsgboxPosYQuer = 0;
                    MsgboxBackgrountImg = "\\FlashDisk\\Falcon\\Resources\\Msgbox_Logo_gelb275.png";
                    MsgboxTextHeitht = (UInt16)(206 - ButtonHeight);
                    MsgBoxButtonOKPosX = 40;
                    MsgBoxButtonOKPosY = 229;
                    MsgBoxButtonCancelPosX = 131;
                    MsgBoxButtonCancelPosY = 229;
                }


                //Msgbox Position und Größe festlegen
                if (Hochkant)
                {
//                    this.Location = new System.Drawing.Point(MsgboxPosX, MsgboxPosY);
                    newMessageBox.Location = new System.Drawing.Point(MsgboxPosX, MsgboxPosY);
                }
                else
                {
                    //this.Location = new System.Drawing.Point(MsgboxPosXQuer, MsgboxPosYQuer);
                    newMessageBox.Location = new System.Drawing.Point(MsgboxPosXQuer, MsgboxPosYQuer);
                }
                //this.Size = new System.Drawing.Size(MsgboxLength, MsgboxHeight);
                //this.BackgroundImage = new System.Drawing.Bitmap(MsgboxBackgrountImg);
                newMessageBox.Size = new System.Drawing.Size(MsgboxLength, MsgboxHeight);
                newMessageBox.BackgroundImage = new System.Drawing.Bitmap(MsgboxBackgrountImg);    
                tMsgboxText.Size = new System.Drawing.Size(MsgboxTextLength, MsgboxTextHeitht);
                MsgBoxButtonOK.Location = new System.Drawing.Point(MsgBoxButtonOKPosX, MsgBoxButtonOKPosY);
                MsgBoxButtonCancel.Location = new System.Drawing.Point(MsgBoxButtonCancelPosX, MsgBoxButtonCancelPosY);

                // Buttons anlegen
                switch(MsgboxKeys) 
                {    case MSGBOX_KEYS.NO_KEYS:
                        MsgBoxButtonOK.Visible = false;
                        MsgBoxButtonCancel.Visible = false;
                        MsgBoxTimer.Enabled = true;             //Timer starten für selbstschließende Msgbox
                        break;
                    case MSGBOX_KEYS.OK_CANCEL:
                        MsgBoxButtonOK.Visible = true;
                        MsgBoxButtonCancel.Visible = true;
                        break;
                    case MSGBOX_KEYS.OK_ONLY:
                        MsgBoxButtonOK.Visible = true;
                        MsgBoxButtonOKPosX = 84;
                        MsgBoxButtonOK.Location = new System.Drawing.Point(MsgBoxButtonOKPosX, MsgBoxButtonOKPosY);
                        MsgBoxButtonCancel.Visible = false;
                        break;
                    case MSGBOX_KEYS.YES_NO:
                        MsgBoxButtonOK.Text = textYes;
                        MsgBoxButtonOK.Visible = true;
                        MsgBoxButtonCancel.Text = textNo;
                        MsgBoxButtonCancel.Visible = true;
                        break;
                    case MSGBOX_KEYS.YES_NO_CANCEL:
                        break;
                    default:
                        break;
                }

                //Fokus auf OK-Button setzen
                MsgBoxButtonOK.Focus();
        }



        /// <summary>
        /// KeyDown Event auf der MsgBox Form
        /// </summary>
        /// <param name="sender">Senderobjekt</param>
        /// <param name="e">Key Event Argumente</param>
        private void MyMessagebox_KeyDown(object sender, KeyEventArgs e)
        {
            // esc
            if (e.KeyCode == Keys.Escape)
                MsgBox_Close();

            // Right
            if (e.KeyCode == Keys.Right)
                MsgBoxButtonCancel.Focus();
            
            // Left
            if (e.KeyCode == Keys.Left)
                MsgBoxButtonOK.Focus();

        }


        private void MsgBoxButtonOK_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Right)
                MsgBoxButtonCancel.Focus();
            
            if (e.KeyCode == Keys.Up)
                MsgBoxButtonOK.Focus();
            
            if (e.KeyCode == Keys.Down)
                MsgBoxButtonOK.Focus();

            if (e.KeyCode == Keys.Enter)
                MsgBoxButtonOK_Click(sender, e);
        }

        private void MsgBoxButtonCancel_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Left)
                MsgBoxButtonOK.Focus();

            if (e.KeyCode == Keys.Up)
                MsgBoxButtonCancel.Focus();

            if (e.KeyCode == Keys.Down)
                MsgBoxButtonCancel.Focus();

            if (e.KeyCode == Keys.Enter)
                MsgBoxButtonCancel_Click(sender, e);
        }

        private void MsgBoxTimer_Tick(object sender, EventArgs e)
        {
            // Timer für Msgbox deaktivieren
            MsgBoxTimer.Enabled = false;

            //Messagebox schließen
            MsgBox_Close();   
        }

    }

-------------- Ende Klasse MyMessagebox -----------------------------------

Aufgerufen wird die Messagebox so:

--------------- Form2 --------------------------------------

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
 
...
            OpenMyMessageboxDialog();
            //MOD02: Msgbox mit Show öffnen, Rückgabewert verarbeiten
            string btnClicked = MyMessagebox.ShowBox(rm.GetString("EditUseCase1_ResetMessage", ci),   //Msgbox Text 
                                                     rm.GetString("EditUseCase1_MessageTitle", ci),   //Msgbox Titel
                                                     MyMessagebox.MSGBOX_KEYS.YES_NO);                //Msgbox Buttons

            CloseMyMessageboxDialog();

            // Yes-Button geklickt
            if (btnClicked == "1")
...

--------------- Ende Form2 --------------------------------------

-------------- Mainform ------------------------------------------
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
 
...
        private void OpenMyMessageboxDialog()
        {
            // MyMessagebox Events hinzufügen
            MyMessageboxDialog.CloseMyMessageboxDialog += new MyMessagebox.CloseMyMessageboxDialogEvent(CloseMyMessageboxDialog);

            // MyMessagebox Dialog auf Fenster Stack legen
            OpenWindowStack.Push(Dialoge.MyMessageboxDialog);

            // Display Ausrichtung übergeben
            MyMessageboxDialog.Hochkant = this.Hochkant;
            MyMessageboxDialog.Language = this.Language;
        }

       private void CloseMyMessageboxDialog()
        {
            OpenWindowStack.Pop();

            // MyMessageboxDialog Events hinzufügen
            MyMessageboxDialog.CloseMyMessageboxDialog -= new MyMessagebox.CloseMyMessageboxDialogEvent(CloseMyMessageboxDialog);
        }
...

--------------- Ende Mainform --------------------------------------------

Zur Erklärung:
Das Open- und Close-Event benötige ich nur, damit ich den Messagebox-Dialog auf den Stack legen kann. Wenn dann die Sprache geändert wird oder der Bildschirm gedreht wird (hochkant -> querformat oder quer->hoch), dann wird der PropertyChanged-Event aufgerufen. Außerdem sollen gewisse Tasten des PDAs deaktiviert sein, wenn die Msgbox offen ist.

Wahrscheinlich schlagt ihr eh schon die Hände über Euren Köpfen zusammen, was ich da für ein Durcheinander programmiert habe.
Ich glaube, dass das Erzeugen von der Instanz newMessagebox an der falschen Stelle steht. Erzeugt wird diese Instanz in der Funktion ShowBox, verwendet wird diese Instanz aber auch z.B. in der PropertyChanged-Methode. Es funktioniert, aber kann das richtig sein?

Die Messagebox hat 3 verschiedene Größen und unterschiedliche Button-Optionen und je nachdem, ob der Bildschirm im Hoch- oder Querformat ist unterschiedliche Positionen am Bildschirm. Wenn keine Buttons gewünscht sind, schließt sie automatisch.

Vielen Dank für Eure Hilfe schon mal.

Grüße
Claudia (flexray)

Moderiert von user profile iconKha: csharp- durch cs-Tags ersetzt
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Di 03.04.12 12:23 
Zitat:
Es funktioniert, aber kann das richtig sein?


Es funktioniert solange du nur 1 MessageBox angezeigt hast. Bei mehreren ziehst du immer die Information von der zuletzt erzeugten was vermutlich unfug ist. Warum greifst du in deinem PropertyChanged EventHandler überhaupt auf newMessageBox zu? Das was ich für richtig halten würde (der Zugriff auf this) hast du aus irgendeinem Grund auskommentiert. Grundsätzlich sehe ich beim überfligen des Codes überhaupt keinen Grund für die Existenz von newMessageBox.
flexray Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Di 03.04.12 12:57 
wenn ich in PropertyChanged über this zugreife wird die falsche Größe (MsgboxHeight) herangezogen, nämlich die, die ich beim Anlegen der Variable initialisiere und nicht die, die ich bei UpdateControls() vergebe.
Beim Debuggen habe ich entdeckt, dass in newMessagebox.MsgboxHeight die richtige Größe steht, deshalb habe ich auf newMessagebox.ClientSize umgestellt.
--> Beim Drehen des Displays war die Msgbox zwar gedreht, aber abgeschnitten, da Größe falsch.

Du sagst also, man könnte die Instanz newMessagebox ganz weglassen? Ich werde das ausprobieren.
flexray Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Mi 04.04.12 11:09 
habe die Objektinstanz newMessagebox mal gelöscht.
Problem: die Methode ShowDialog() braucht wohl eine Objektinstanz. Ich muss also vorher eine Instanz mit new anlegen, richtig?
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Mi 04.04.12 11:36 
Richtig, wie du es bisher auch getan hast. Mach newMessagebox in dieser Methode einfach zur lokalen Variablen.

_________________
>λ=
flexray Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Mi 04.04.12 12:26 
habe nun newMsgbox als Instanz von MyMessagebox deklariert:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
public partial class MyMessagebox : Falcon.HForm
{
        public static MyMessagebox newMsgbox = new MyMessagebox();
        ...
}

und verweise überall mit newMsgbox.

Der Aufruf der Messagebox ist nun so: MyMessagebox.newMsgbox.ShowBox(...);

Ist das nun ein richtiger und sauberer Weg? (Kommt mir auf alle Fälle sauberer vor als das Vorherige).

Moderiert von user profile iconTh69: C#-Tags hinzugefügt


Zuletzt bearbeitet von flexray am Mi 04.04.12 12:56, insgesamt 1-mal bearbeitet
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mi 04.04.12 12:43 
Als lokale Variable in ShowBox. Die PropertyChanged Methode läuft dann im Context dieser MyMessagebox Instanz. Sie kann dann natürlich problemlos auf sich selbst (this) zugreifen.

Edit:

Zitat:

Die Methode ShowBox() habe ich als Nicht statisch deklariert, sonst Fehlermeldung (für das nicht statische Feld newMessagebox ist ein objektverweis erforderlich), dann kommt aber Fehlermeldung beim Aufruf von MyMessagebox.ShowBox - dass hier ein Objektverweis erforderlich ist.


Mache ShowBox wieder statisch. Wenn du eine MyMessagebox Instanz wirklich in der Methode an einer lokale Variable erzeugst und nicht an einer Feld der Klasse wird das funktionieren.
flexray Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Mi 04.04.12 12:58 
Entschuldigung Ralf,
hatte gerade meinen Beitrag editiert, während Du geantwortet hattest.