Eigene MessageBox bzw. Form in Form



  • Hallo Leute,

    ich möchte zum Anzeigen von ein paar Simplen Texten ne Message Box ohne Buttons machen.
    Mein Ansatz war ne neue Form in der bestehenden Form zu erzeugen und darin meinen Text als Label anzuzeigen.

    Problem bei meinem Code ist, das Label wird zwar erzeugt aber es wird kein Text angezeigt. Ich glaub das nicht viel fehlt, aber ich probier jetzt schon ne Stunde rum und komm nicht wirklich drauf.

    private void button1_Click(object sender, EventArgs e) {
    
                Form test = new Form();
    
                test.Size = new Size(300, 150);  
                test.StartPosition = FormStartPosition.CenterScreen;
    
                Label lab = new Label();
                lab.AutoSize = true;
                lab.Location = new Point(50, 50);
                lab.Visible = true;             
    
                lab.Text = "This is a Test";
                lab.ForeColor = Color.Red;
    
                test.Controls.Add(lab);
                test.Visible = true;
    
                Thread.Sleep(2500);
    
                test.Visible = false;
    
            }
    

    Das Label wird nur als weißer "Balken" angezeigt.... Was mach ich da falsch ? Danke schonmal !



  • Hallo,

    ich habe deinen Code mal getestet. Bei mir wird der Text in rot angezeigt. Das Problem in deinem Code ist das "Thread.Sleep()". Das blockiert natürlich den GUI Thread und verhindert somit, dass das Label korrekt gezeichnet wird.

    Schau lieber nach einer alternative (z.B. einen Timer) über die du das Form nach der angegebenen Zeit wieder ausblendest.



  • Ok, danke erstmal. Werde das heute mal mit einem Timer versuche, evtl. klappts dann mit dem Text auch....



  • Ein Timer ist der richtige Weg. Hier der Code:

    // Eigene MessageBox
    
        public partial class Form2 : Form
        {
            private string text;
            private double zeit;
            // timer1 und timer1_tick im Designer festgelegt
    
            public Form2(string txt, double z)
            {
                InitializeComponent();
                text = txt;
                zeit = z;
                label1.Text = text;
                label1.ForeColor = Color.Red;
                this.Width  = 250;
                this.Height = 200;
                this.ControlBox = false;
                this.FormBorderStyle = FormBorderStyle.FixedDialog;
                this.StartPosition = FormStartPosition.CenterScreen;
                timer1.Enabled = true;
                timer1.Interval = 100;
            }
    
            private void timer1_Tick(object sender, EventArgs e)
            {
                zeit -= 100;
                if (zeit < 0) this.Close();
            }
    
            // Aufruf:
    
            private void button1_Click(object sender, EventArgs e)
            {
                // dies ist der Text für die eigene MessageBox
                string text = "Hallo\n\nSchön dich zu sehen!";
                double zeit = 2500;
                // Aufruf über speziellen Konstruktor
                form2 = new Form2(text, zeit);
                form2.Show();
            }
    


  • Ok, danke ich arbeite dran.

    Zu dem Code :

    public Form2(string txt, double z)
            {
                InitializeComponent();   // => Bringt bei mir immer Fehler 
                text = txt;
                zeit = z;
                label1.Text = text;
    

    InitializeComponent bringt mir immer : ".. ist im aktuellen Kontex nicht vorhanden" .

    Bspl:

    public partial class Form1 : Form {
            public Form1() {
                InitializeComponent();
            }
        }//END_Class
    
        public partial class MSGbox : Form {
    
            public MSGbox() {
    
                InitializeComponent();
            }
    


  • So, ich habs fast hinbekommen. Hab mich eher von der MSDN Seite "inspirieren" lassen, nur das Form schließen haut nicht hin. Ich vermute ich habe die Refernz auf den Aufrufenden Thread bzw. Form irgendwie verloren.

    Auf jeden Fall löst es eine Ausnahme aus, da bräuchte ich nochmal bisschen hilfe....

    Hier der Code

    public partial class MyMSG : Form {
    
            private string _text;
            private uint  _time;
            private double _ctr;
            private bool _timer_use = false;
            System.Timers.Timer t1;
    
            public MyMSG(string text, uint value, bool timer_use = false) {
    
                _text = text;
                _time = value;
    
                Label label = new Label();
                label.Text = _text;
                label.Font = new Font( "Microsoft Sans Serif",  10); // 8,25pt)
                label.AutoSize = true;
                label.Location = new Point(10, 10);
                label.ForeColor = Color.Blue;
    
                this.Width = 200;
                this.Height = 125;
                this.ControlBox = false;
                this.FormBorderStyle = FormBorderStyle.FixedDialog;
                this.StartPosition = FormStartPosition.CenterScreen;
                this.AutoSize = true;
    
                this.Controls.Add(label);
    
                if (timer_use) {
                    _timer_use = true;
                    t1 = new System.Timers.Timer(_time);
                    t1.Elapsed += new ElapsedEventHandler(tick);
                     _ctr = (_time / 15);
                     t1.Interval = _ctr;
                     t1.Enabled = true;               
                }
    
            }
    
     public void tick(Object sender, ElapsedEventArgs e) {
    
                _time -= 100;  Convert.ToUInt32(_ctr);
    
                if (_time <= 0) {
                    MessageBox.Show("Problem", "nix");
                    // HIER IST DER HUND BEGRABEN::
                    this.Close()   // kaboom
                }
    
            }
    


  • Sollte mal jemand das gleiche Problem haben :

    1.) Benutzt den Windows Forms Timer, er ist wesentlich einfacher zu handeln

    2.) Die Lösung für den System Timer ist :

    this.Invoke((Action)delegate() { Close(); });
    


  • Es macht ja auch gar keinen Sinn einen Timer aus System.Timers zu verwenden. Es ging dir nur um die GUI und da ist der Timer aus System.Windows.Forms immer der Typ der Wahl.



  • Ja, da hast du natürlich Recht, das hab ich zu spät gecheckt. Naja, wieder was gelernt.

    BTW. :

    Muss ich irgendwas beachten wenn ich z.B. nen Button_Click auf async stelle oder kann ich das ohne "schlechtes Gewissen" sooft wie ich will machen ?

    private  async void Button_1_click(....){
    
    Do_sth();
    
     await Task.Delay(2000);
    
    Do_sth_else();
    }
    

    Hab mich jetzt da nicht eingelesen sondern diese Vorgehensweise "blind" aus Stackoverflow übernommen....



  • Ja, du musst beachten dass dein Fenster während das await Task.Delay(2000); läuft munter weiter Nachrichten dispatched.
    Und man daher weiter auf alle möglichen Buttens klicken kann, und auch weiter die Handlerfunktionen dafür aufgerufen werden. Inklusive Button_1/Button_1_click.

    Und du solltest beachten dass async/await eine ziemlich krasse Sache ist mit der man zwar sehr cool arbeiten kann, sich aber auch wunderbar in den Fuss schiessen kann.

    => Du solltest dich IMO *sehr* gut über async/await informieren und auch mehr als nur "ein wenig" damit rumexperimentieren bevor du es produktiv verwendest.


Anmelden zum Antworten