Autor Beitrag
Suras78
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Di 07.06.11 14:38 
Hey,
ich mache einen kleinen Terminkalender. Hierzu wird beim Drücken auf einen Button ein neues Objekt einer "Termin"-Klasse erstellt, die in ihrem Konstruktor eine Form erstellt, in der man dann Name, Uhrzeit und Beschreibung eingeben kann, welche dann in den Fields des Objekts gespeichert werden. Das Speichern soll aber erst über einen "Speichern" Button geschehen, nicht im Konstruktor (geht ja auch kaum). Außerdem soll es dann einen Abbruch Button geben, der das Fenster einfach schließt und nichts weiter macht. Hier aber liegt das Problem: durch

ausblenden C#-Quelltext
1:
newAppointment.Close()					


wird die Form zwar geschlossen, aber weiterhin von Windows dargestellt, eben bis ich mit der Maus oder einem anderen Fester drüberfahre. Invalidate und dispose habe ich schon probiert... woran könnte das liegen?.

Danke
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19314
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 07.06.11 14:58 
Ich schätze einmal, dass das Fenster dahinter sich aus irgendeinem Grund schlicht nicht aktualisiert. :nixweiss:

Hast du vielleicht ein Testprojekt?
Suras78 Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Di 07.06.11 15:36 
Naja,
habs mit Firefox, dem Desktop und VS im Hintergrund probiert, denke nicht, dass es daran liegt. EinTestprojekt kann ich leider nicht schicken, da ich die dafür benutzen Grafiken nicht "veröffentlichen" will.
Suras78 Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Mi 08.06.11 12:15 
Gibt es denn einen Befehl, mit dem ich ganz Windows Invalidate()" sagen kann=
thepaine91
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 763
Erhaltene Danke: 27

Win XP, Windows 7, (Linux)
D6, D2010, C#, PHP, Java(Android), HTML/Js
BeitragVerfasst: Mi 08.06.11 13:12 
Dr. Hallo
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 110
Erhaltene Danke: 13

XP
C/C++/C#
BeitragVerfasst: Mi 08.06.11 14:04 
Zitat:
Gibt es denn einen Befehl, mit dem ich ganz Windows Invalidate()" sagen kann=

:D wow, das ist dann aber die brachial-methode. da gibt es mit sicherheit bessere möchlichkeiten.
da ich dein code nicht kenne kann ich aber nichts weiter dazu sagen. ich weiß nich obs usus ist ein formular
im konstruktor zu erstellen. im zweifel separates formular.

Moderiert von user profile iconChristian S.: C#- durch Quote-Tags ersetzt
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4798
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Mi 08.06.11 14:22 
Hallo Suras78,

Sura78 hat folgendes geschrieben:

Hierzu wird beim Drücken auf einen Button ein neues Objekt einer "Termin"-Klasse erstellt, die in ihrem Konstruktor eine Form erstellt, ...

Dies hört sich nach einem unsauberen Design an. Trennung von GUI und Logik (Daten) ist oberste Prämisse.

Und zu
Sura78 hat folgendes geschrieben:

Gibt es denn einen Befehl, mit dem ich ganz Windows Invalidate()" sagen kann

Nicht an den Symptomen herumdoktorn, sondern die Ursachen suchen und behandeln ;-)

Am besten du zeigst mal deinen Code, wie du das Formular aufrufst.

Als generelle Leselektüre kann ich dir meinen Artikel Kommunikation von 2 Forms empfehlen...
Suras78 Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Mi 08.06.11 14:40 
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:
namespace Terminkalender {
    class Termin {
        public string name;
        public int hours;
        public int minutes;
        public string discription;
        public int importance;
        public int date;

        private string oldTextHours = "";
        private string oldTextMinutes = "";
        public Boolean alerted1 = false;
        public Boolean alerted2 = false;
        private TextBox timeM = new TextBox();
        private RichTextBox text = new RichTextBox();
        private TextBox timeH = new TextBox();
        private TextBox title = new TextBox();

        public Termin(int day) {
            date = day;
            name = "unknown";
            hours = 12;
            minutes = 00;
            discription = "Beschreibung";
            importance = 0;
            Form newAppointment = new Form();
            newAppointment.Text = "Neuer Termin";
            newAppointment.Size = new Size(250335);
            newAppointment.FormBorderStyle = FormBorderStyle.FixedToolWindow;
            newAppointment.MaximizeBox = false;
            newAppointment.BackgroundImage = Terminkalender.Properties.Resources.bg_bright;
            newAppointment.Deactivate += new EventHandler(turnTrans);
            newAppointment.Activated += new EventHandler(turnVis);

            Label captions = new Label();
            captions.Size = new Size(22530);
            captions.Location = new Point(5,33);
            captions.BackColor = Color.Transparent;
            captions.Text = "Titel:                                                 :         Uhr";
            newAppointment.Controls.Add(captions);

            Label header = new Label();
            header.Text = "Neuer Termin für den " + (day + 1) + ". Juni";
            header.Size = new Size(25030);
            header.Font = new Font(header.Font.FontFamily.Name, 12, FontStyle.Bold);
            header.BackColor = Color.Transparent;
            header.Location = new Point(11);
            header.BorderStyle = BorderStyle.None;
            newAppointment.Controls.Add(header);

            timeH.Location = new Point(15130);
            timeH.Size = new Size(255);
            timeH.MaxLength = 2;
            timeH.TextChanged += new EventHandler(hoursChanged);
            timeH.TextAlign = HorizontalAlignment.Right;
            newAppointment.Controls.Add(timeH);
            timeH.BringToFront();

            timeM.Location = new Point(18230);
            timeM.Size = new Size(255);
            timeM.MaxLength = 2;
            timeM.TextChanged += new EventHandler(minutesChanged);
            timeM.TextAlign = HorizontalAlignment.Right;
            newAppointment.Controls.Add(timeM);
            timeM.BringToFront();

            title.Location = new Point(3530);
            title.Size = new Size(10030);
            newAppointment.Controls.Add(title);
            title.Focus();
            title.KeyPress += new KeyPressEventHandler(titleChanged);
            title.BringToFront();
            title.MaxLength = 300;
            title.Focus();

            text.Text = "Beschreibung";
            text.Location = new Point(1060);
            text.Size = new Size(220200);
            timeM.TextChanged += new EventHandler(textChanged);
            newAppointment.Controls.Add(text);
            text.BringToFront();

            Label alertCaption = new Label();
            alertCaption.Text = "Benachrichtigen:";
            alertCaption.Location = new Point(20280);
            newAppointment.Controls.Add(alertCaption);



            PictureBox save = new PictureBox();
            save.BackgroundImage = Terminkalender.Properties.Resources.yesbg;
            save.Size = new Size(5050);
            save.BackgroundImageLayout = ImageLayout.Stretch;
            save.Location = new Point(120260);
            save.MouseEnter += delegate(System.Object o, System.EventArgs e) {
                (o as PictureBox).BackgroundImage = Terminkalender.Properties.Resources.yebgact;
            };
            save.MouseLeave += delegate(System.Object o, System.EventArgs e) {
                (o as PictureBox).BackgroundImage = Terminkalender.Properties.Resources.yesbg;
            };
            save.Click += delegate(System.Object o, System.EventArgs e) {
                if (title.Text == "" || timeH.Text == "" || timeM.Text == "") {
                    MessageBox.Show("Bitte füllen Sie die Felder für Titel und Uhrzeit aus.");
                }
                else {
                    name = title.Text;
                    discription = text.Text;
                    importance = 1;
                    date = day;
                    hours = Convert.ToInt32(timeH.Text);
                    minutes = Convert.ToInt32(timeM.Text);

                    Terminkalender.Form1.appointments.Add(this);
                    Terminkalender.Form1.load();
                    newAppointment.Close();
                }
            };
            newAppointment.Controls.Add(save);

            PictureBox abort = new PictureBox();
            abort.BackgroundImage = Terminkalender.Properties.Resources.nobg;
            abort.Size = new Size(5050);
            abort.MouseEnter += delegate(System.Object o, System.EventArgs e) {
                (o as PictureBox).BackgroundImage = Terminkalender.Properties.Resources.nobgact;
            };
            abort.MouseLeave += delegate(System.Object o, System.EventArgs e) {
                (o as PictureBox).BackgroundImage = Terminkalender.Properties.Resources.nobg;
            };
            abort.BackgroundImageLayout = ImageLayout.Stretch;
            abort.Location = new Point(180260);
            abort.Click += new EventHandler(closeNewAppointment);

            newAppointment.Controls.Add(abort);
            
            newAppointment.Show();

            title.Focus();
        }


Der Konstruktor ;)

ausblenden C#-Quelltext
1:
2:
3:
4:
        private void closeNewAppointment(object sender, EventArgs e) {
            Form oldForm = (sender as PictureBox).FindForm();
            oldForm.Close();
        }

die Methode (innerhalb der gleichen Klasse), die die Form schließen soll. Bei "save" passsiert das Ganze, wie man sehen kann, direkt in einer anonymen Methode, eben zum ausprobieren. Macht aber leider keinen Unterschied.
Suras78 Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Mi 08.06.11 16:23 
Nebenbei:
Welches "System" würdet ihr mir für das Speichern empfehlen? Außer dem Grafikbug ist es jetzt fast fertig. Allerdings halten die Termine nur bis zum beenden des Programms. Als nächstes möchte ich die Termine also speichern können, was ich leider noch nie gemacht hab. Deswegen meine Frage: Wie speicher ich sie am besten? Hab mal ein wenig geschaut, aber es gibt ja viele veschiedene Möglichkeiten... Textdateien, Ini, Reistry, DB... aber was ist für meinen Kalender (und für einen Anfänger) am besten? Falls das wichtig ist: Ich möchte aus der Datei neue Objekte meiner Termin klasse erzeugen, die einen naderen Konstruktor hat, also kein Form erstellt sondern die Werte (6 Variablen) eben aus dem Speicher kriegt.
Dr. Hallo
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 110
Erhaltene Danke: 13

XP
C/C++/C#
BeitragVerfasst: Do 09.06.11 01:33 
Das da..

ausblenden C#-Quelltext
1:
Form newAppointment = new Form();					


nicht innerhalb sonder außerhalb des konstruktors definieren. dann könnte es klappen.
so wie dus da hast existiert deine form nur konstruktorweit. :
norman2306
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 222
Erhaltene Danke: 16

Win XP, Win 7 64-Bit
C# 4.0 (VS2010)
BeitragVerfasst: Do 09.06.11 07:02 
Für das Speichern würde ich dir einen Serializer vorschlagen. Da bietet dir .NET gleich zwei an:

1. eine XmlSerializer - der produziert lesbaren XML-Code

2. ein BinSerializer - der produziert schlecht lesbare Binär-Files

Hier mal ein Beispiel:

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:
   using System.IO;
   using System.Runtime.Serialization.Formatters.Binary;

   [Serializable]
   public class ItemToSave
   {
        public DateTime Date { get; set;}
        public string FirstName { get; set;}
        public string LastName { get; set;}
        public string Description { get; set;}
   }

   public class MainClass
   {
        .
        .
        .

        public MainClass()
        {
            var item = new ItemToSave() 
            { 
              Date = DateTime.Now, 
              FirstName = "Norman-Hendrik"
              LastName = "Schulz",
              Description = "Danke sagen"
            } 

            SaveItem("c:\\myFile.abc", item);

            var item2 = OpenItem("c:\\myFile.abc"as ItemToSave;

            MessageBox.Show(item2.Date.ToString(), string.Format("Nicht vergessen: {0} {1} {3}!", item2.FirstName, item2.LastName, item2.Description));
        }


        private void SaveItem(string path, object item)
        {
            using (var fileStream = new FileStream(path, FileMode.Create))
            {
                 var bf = new BinaryFormatter();
                 bf.Serialize(fileStream, item);
            }
        }


        private object OpenItem(string path)
        {
            using (var fileStream = new FileStream(path, FileMode.Create))
            {
                 var bf = new BinaryFormatter();
                 return bf.Deserialize(fileStream);
            }
        }
   }
Suras78 Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Do 09.06.11 08:38 
@ Dr. Hallo: Danke, hat aber leider nichts geändert.
@ Norman2306: Danke, werd ich jetzt probieren (habs gerade mit einem DataSet versucht, das scheint aber eher ungeeignet zu sein)
norman2306
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 222
Erhaltene Danke: 16

Win XP, Win 7 64-Bit
C# 4.0 (VS2010)
BeitragVerfasst: Do 09.06.11 09:16 
Dafür ist es auch ungeeignet. Die zu speichernde Klasse muss mit dem Attribut [Serializable] gekennzeichnet sein. Das trifft für ein DataSet nicht zu. Um ein DataSet zu serialisieren, müsste man einen serialisierbaren Wrapper basteln. Das ist zwar nicht sonderlich schwer, aber unnötig. Ein DataSet hat eine eigene Speicherfunktion, dafür muss man keine schreiben.

Ein DataSet kann man so schreiben:

ausblenden C#-Quelltext
1:
2:
3:
4:
using(var filestream = new FileStream(path, FileMode.Create)
{
   myDataSet.WriteXML(filestream);   
}
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4798
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Do 09.06.11 09:36 
Hallo Suras78,

dein Code entspricht leider genau meinen Befürchtungen.
Du solltest deinen Code dringend so ändern, daß du einzelne Klassen für die GUI (Forms) und Logik (z.B. Termine) erstellst.

So eigenartige Konstrukte wie
ausblenden C#-Quelltext
1:
2:
3:
Terminkalender.Form1.appointments.Add(this);
Terminkalender.Form1.load();
newAppointment.Close();

können nur zu komischem Verhalten führen (hast du etwa 'appointments' sowie die 'load'-Methode als 'static' deklariert???).

Mein Beispielprojekt 'PersonManagement' (ganz unten bei meinem Artikel) zeigt, wie man ein Projekt richtig im Sinne der OOP aufsetzt.

Ich weiß, daß es für einen Anfänger schwierig ist, gleich ein "perfektes" Programm zu erstellen, aber wenn schon der Grundaufbau des Projektes falsch ist, dann führen alle weiteren Änderungen in die falsche Richtung (und es treten Probleme auf - wie bei dir -, die es sonst nicht gibt ;-).
Suras78 Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Do 09.06.11 10:05 
Danke, Th69,
ich werde das in Zukunft berücksichtigen, allerdigns funktioniert mein Aufbau sonst sehr gut und ist auch halbwegs durchdacht ;) Deswegen möchte ich das ganz zu ändern nur als letzte Möglichkeit in Betracht ziehen.

Nochmal zu XML: ich erzeuge mit dem Code
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
        private void saveData(object o, EventArgs e) {
            XmlTextWriter myXmlTextWriter = new XmlTextWriter("appointments.xml", System.Text.Encoding.UTF8);
            myXmlTextWriter.Formatting = Formatting.Indented;
            myXmlTextWriter.WriteStartDocument(false);

            for (int i = 0; i < appointments.Count; i++) {
                Termin currentAppointment = (Termin)appointments[i];
                myXmlTextWriter.WriteStartElement("appointment");
                    myXmlTextWriter.WriteElementString("name", currentAppointment.name);
                    myXmlTextWriter.WriteElementString("hours", Convert.ToString(currentAppointment.hours));
                    myXmlTextWriter.WriteElementString("minutes", Convert.ToString(currentAppointment.hours));
                    myXmlTextWriter.WriteElementString("description", currentAppointment.description);
                    myXmlTextWriter.WriteElementString("importance",  Convert.ToString(currentAppointment.importance));
                    myXmlTextWriter.WriteElementString("date",  Convert.ToString(currentAppointment.date));
                myXmlTextWriter.WriteEndElement();
            }

            myXmlTextWriter.Flush();
            myXmlTextWriter.Close(); 
        }


Diese XML Datei:

ausblenden XML-Daten
1:
2:
3:
4:
5:
6:
7:
8:
9:
  <?xml version="1.0" encoding="utf-8" standalone="no" ?> 
- <appointment>
  <name>Test</name
  <hours>13</hours
  <minutes>13</minutes
  <description>sdaf asdasf dfsd asdf fasd fasdf asdf f sdf asddfasfasd asdf asdf asfas dfasdfasdfasdfasd</description
  <importance>1</importance
  <date>0</date
  </appointment>


Kann ich das i dieser Form gebrauchen? Wenn ja, wie lese ich es dnn korrekt aus?

Danke nochmal

EDIT: Danke, habs schon =) Konnte mir nur nicht richtig vorstellen, wie ich die einzelnen untergruppen von jedem Appointment ansprechen soll und mir dieses appointment aus den vieles erstmal heraussuchen soll... Aber scheinbar kann er das mit foreach selbst ;)