Autor Beitrag
lapadula
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 180
Erhaltene Danke: 10



BeitragVerfasst: Sa 03.09.16 10:24 
Hallo, ich brauche wieder Hilfe :)

Ich soll ein zum Teil fertiges Datenkonvertierungstool erweitern. Es wird eine eigene Komponente in das Formular hinzugefügt. Diese Komponente soll selbständig Labels und Textboxes, je nach anzahl der Objekten in einem dictionary hinzufügen.
In diesem Dictionary sind Tabellen einer Datenbank. Später sollen auch die Inhalte der Tabellen in der Komponente abgebildet werden aber erstmal die Tabellen.

Ich komme bei der foreach-Schleife in der EntryViewer-Klasse nicht weiter. Habe da ein wenige Pseudo-Code reingeschrieben. Ich will dort auf das dictionary aus der Klasse TEntry zugreifen, dort die Objekte holen und in die Textboxes schreiben, mit einem Label davor.

Vllt hat jemand ein Tip für mich?

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:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using abc.Model.Entry;

namespace WindowsApplication2.Components
{
    public partial class EntryViewer : UserControl
    {
        public EntryViewer()
        {
            InitializeComponent();
        }
        private void AddIntField(int value)
        {
            Label Bez = new Label();
            //Bez.Location
            //Bez.Text = ""
            this.Controls.Add(Bez);
            TextBox Box = new TextBox();
            Box.Location = new Point(11);
            Box.Text = value.ToString();
            this.Controls.Add(Box);
        }

        private void AddStringField(string value)
        {
            Label Bez = new Label();
            //Bez.Location
            //Bez.Text = ""
            this.Controls.Add(Bez);
            TextBox Box = new TextBox();
            Box.Location = new Point (1,22);
        }

        public void ViewEntry(TEntry Entry)
        {
            foreach (KeyValuePair<stringobject> Information in Entry.Information)
            {
                switch (aktuellesobject.GetType().ToString())
                {
                    case "int":
                        AddIntField(aktuellesobject);
                        break;
                    case "string":
                        AddStringField();
                        break;
                }
            }
        }
    }
}


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:
using System;
using System.Collections.Generic;
using Hades.Exceptioin;
using System.IO;
namespace Hades.Model.Entry
{
    public abstract class TEntry
    {       
        public Dictionary<stringobject> Informations;
        public object GetValue(string sKey) {
            if (Informations.ContainsKey(sKey)) {
                try {
                    return Informations[sKey];
                } catch (Exception Ex) {
                    throw TEntryException.Unknown("bla", sKey);
                }

            } else {
                throw TEntryException.WrongKey("bla", sKey);
            }
        }
        public void SetValue(string sKey, object Value) {
            if (Informations.ContainsKey(sKey)) {
                try 
                {
                    if(Value == DBNull.Value) TEntryException.DbNullConvert("bla",sKey);
                    Informations[sKey] = Value;
                } 
                catch (Exception Ex) 
                {
                    throw TEntryException.Unknown("bla", sKey);
                }
                
            } else {
                throw TEntryException.WrongKey("bla", sKey);
            }
        }

        public int Id {
            get { return (int)GetValue("ID"); }
            set { SetValue("ID", value); }
        }
        public int OrgId {
            get { return (int)GetValue("ORGID"); }
            set { SetValue("ORGID", value); }
        }
        public string Bemerkung {
            get { return (string)GetValue("BEMERKUNG"); }
            set { SetValue("BEMERKUNG", value); }
        }
        public DateTime SYS_INSERT {
            get { return (DateTime)GetValue("SYS_INSERT"); }
            set { SetValue("SYS_INSERT", value); }
        }
        public DateTime SYS_UPDATE {
            get { return (DateTime)GetValue("SYS_UPDATE"); }
            set { SetValue("SYS_UPDATE", value); }
        }
        public bool SYS_DELETE {
            get { return (bool)GetValue("SYS_DELETE"); }
            set { SetValue("SYS_DELETE", value); }
        }
        public int SYS_LOCKED{
            get { return (int)GetValue("SYS_LOCKED"); }
            set { SetValue("SYS_LOCKED", value); }
        }

        protected TEntry() {
            Informations = new Dictionary<stringobject>();
            Informations.Add("ID"int.MinValue);
            Informations.Add("ORGID"int.MinValue);
            Informations.Add("BEMERKUNG"string.Empty);
            Informations.Add("SYS_INSERT", DateTime.MinValue);
            Informations.Add("SYS_UPDATE", DateTime.MinValue);
            Informations.Add("SYS_DELETE"bool.FalseString);
            Informations.Add("SYS_LOCKED"int.MinValue);
            
        }
        public static Predicate<TEntry> ByValue(string sKey, object Value) {
            return new Predicate<TEntry>(delegate(TEntry Entry) {
                return Entry.GetValue(sKey) == Value;
            });
        }
        public static Predicate<TEntry> ById(int Id) {
            return new Predicate<TEntry>(delegate(TEntry Entry) {
                return (int)Entry.GetValue("ID") == Id;
            });
        }
        public static Predicate<TEntry> ByOrgId(int OrgId) {
            return new Predicate<TEntry>(delegate(TEntry Entry) {
                return (int)Entry.GetValue("ORGID") == OrgId;
            });
        }
        public static Predicate<TEntry> BySysInsert(DateTime SysInsert) {
            return new Predicate<TEntry>(delegate(TEntry Entry) {
                return (DateTime)Entry.GetValue("SYSINSERT") == SysInsert;
            });
        }
        public static Predicate<TEntry> BySysUpdate(DateTime SysUpdate) {
            return new Predicate<TEntry>(delegate(TEntry Entry) {
                return (DateTime)Entry.GetValue("SYSUPDATE") == SysUpdate;
            });
        }
        public static Predicate<TEntry> BySysDelete(DateTime SysDelete) {
            return new Predicate<TEntry>(delegate(TEntry Entry) {
                return (DateTime)Entry.GetValue("SYSDELETE") == SysDelete;
            });
        }
    }
}


Moderiert von user profile iconTh69: Titel (leicht) geändert.
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Sa 03.09.16 10:46 
Hallo,

fehlt dir die Definition von aktuellesobject?
ausblenden C#-Quelltext
1:
object aktuellesobject = Information.Value;					

Besser wäre es aber wohl mittels typeof(...) den Vergleich der Datentypen durchzuführen (denn statt "int" wäre System.Int32 richtig).

PS: Es ist verwirrend, wenn ein Datentyp mit einem großen T anfängt (wie TEntry), aber kein generischer Datentyp-Parameter ist...

Für diesen Beitrag haben gedankt: lapadula
lapadula Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 180
Erhaltene Danke: 10



BeitragVerfasst: Sa 03.09.16 14:33 
Die Definition fehlt noch. Hab's hingeschrieben um zu zeigen was ich meine.

Was genau meinst du mit typeof? Kann man typeof in dem Switch Block überhaupt benutzen?
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Sa 03.09.16 14:42 
Sorry, aber ich scheine dein genaues Problem nicht zu verstehen.

Und typeof geht zwar nicht per switch, aber per if ... else if-Kaskade.
lapadula Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 180
Erhaltene Danke: 10



BeitragVerfasst: So 04.09.16 17:19 
Ich komm nicht drauf wie ich die Objekte aus dem Dictionary ansprechen kann.
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: So 04.09.16 17:33 
Du musst deutlicher werden. Dein Code, auch wenn kaputt, zeigt doch schon wie du/man auf das Dictionary zugreift. Es ist alles da. Wenn du noch ein Problem hast solltest du das genauer ansprechen.

Für diesen Beitrag haben gedankt: lapadula
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: So 04.09.16 18:24 
Hallo lapadula,

ich habe dir doch den Source-Code dafür gegeben. Und mittels Key kommst du dann an den Schlüsselwert des Dictionaries (in deinem Fall also an den Namen), s.a. KeyValuePair<TKey, TValue>-Struktur.

Für diesen Beitrag haben gedankt: lapadula
lapadula Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 180
Erhaltene Danke: 10



BeitragVerfasst: Mo 05.09.16 14:51 
Sorry für meine Blödheit :D Hab das jetzt folgendermaßen gelöst.
Ich bin mir sicher, das es nicht sehr elegant ist, vorallem wie ich die Textboxes positioniere:

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:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using abc.Model.Entry;

namespace WindowsApplication2.Components
{
    public partial class EntryViewer : UserControl
    {
        int tbY = 1;
        int tbX = 1;

        public EntryViewer()
        {
            InitializeComponent();
        }
        private void AddIntField(int value)
        {
            if (tbY < 400)
            {
                tbY = tbY + 20;
                TextBox Box = new TextBox();
                Box.Location = new Point(1 + (tbX), 1 + (tbY));
                Box.Text = value.ToString();
                this.Controls.Add(Box);
            }
            if (tbY >= 400)
            {
                tbX = tbX + 100;
                tbY = tbY + 20;
                TextBox Box = new TextBox();
                Box.Location = new Point(1 + (tbX), 1 + (tbY));
                Box.Text = value.ToString();
                this.Controls.Add(Box);
            }

        }
        private void AddStringField(string value)
        {
            if (tbY < 400)
            {
                tbY = tbY + 20;
                TextBox Box = new TextBox();
                Box.Location = new Point(1 + (tbX), 1 + (tbY));
                Box.Text = value.ToString();
                this.Controls.Add(Box);
            }
            if (tbY >= 400)
            {
                tbX = tbX + 100;
                tbY = 20;
                TextBox Box = new TextBox();
                Box.Location = new Point(1 + (tbX), 1 + (tbY));
                Box.Text = value.ToString();
                this.Controls.Add(Box);
            }

        }
        

        public void ViewEntry(TEntry Entry)
        {
            foreach (object aktuellesobject in Entry.Attributes.Values)
              {
                  switch (aktuellesobject.GetType().ToString())
                  {
                      case "System.Int32":
                          AddIntField((int)aktuellesobject);
                          break;
                      case "System.String":
                          AddStringField((string)aktuellesobject);
                          break;
                  }
              }
        }
 
    }
        
        
}
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mo 05.09.16 15:16 
AddIntField und AddStringField sind irgendwie identisch :gruebel: Code Duplizierung ist doof. Warum nicht z.B. einfach

ausblenden C#-Quelltext
1:
2:
3:
4:
private void AddIntField(int value)
{
    AddStringField(value.ToString());
}

Für diesen Beitrag haben gedankt: lapadula
lapadula Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 180
Erhaltene Danke: 10



BeitragVerfasst: Mo 05.09.16 15:28 
Ja es ist doppelt, weil ich in der switch anweisung unterscheide zwischen int und string.

Später kommt noch dateTime, bool, char usw. dazu.
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Mo 05.09.16 15:50 
Trotzdem brauchst du ja nicht den Code dafür duplizieren, denn in den Methoden nutzt du ja nur die ToString()-Funktionalität der verschiedenen Datentypen.

Du bräuchtest bisher sogar gar keine Fallunterscheidung:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
private void AddField(object value)
{
   // ...
   Box.Text = value.ToString();
   // ...
}

(denn das funktioniert dann automatisch für alle Datentypen, sofern diese die ToString-Methode dann sinnvoll implementiert haben).
Aber die Methode von Ralf ist wahrscheinlich die beste, also nur die string-Methode zu implementieren und für alle anderen dann entweder beim Aufruf den passenden string-Parameter zu setzen oder aber wenn es denn explizit sein soll, daraus dann eine eigene Methode zu machen (evtl. dann zusätzlich überladen mit object als Fallback).

Für diesen Beitrag haben gedankt: lapadula
lapadula Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 180
Erhaltene Danke: 10



BeitragVerfasst: Mo 05.09.16 19:47 
Ich habe das erstmal so gemacht, weil es für mich leichter ist. Wie ich das ganze kürzer schreiben kann muss ich mir noch überlegen. Wobei ich auch zugeben muss, dass es immer unübersichtlicher wird :D

Die Klasse sieht im Moment nun so aus. Diesmal auch mit Label neben der Textbox und den Key und Value Wert aus dem Dictionary:

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:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using abc.Model.Entry;

namespace WindowsApplication2.Components
{
    public partial class EntryViewer : UserControl
    {
        int tbY = 1;
        int tbX = 1;

        int labelY = 1;
        int labelX = 1;

        public EntryViewer()
        {
            InitializeComponent();
        }
        private void AddIntField(int value, string Key)
        {

            if (tbY < 400)
            {
                tbY = tbY + 20;
                TextBox Box = new TextBox();
                Box.Location = new Point(100 + (tbX), 1 + (tbY));
                Box.Text = value.ToString();
                this.Controls.Add(Box);

                Label label = new Label();
                label.Location = new Point(tbX -labelX, tbY);
                label.Text = Key.ToString() + " (int)";
                label.BackColor = Color.Gray;
                label.BorderStyle = BorderStyle.FixedSingle;
                this.Controls.Add(label);
            }
            if (tbY >= 400)
            {
                tbX = tbX + 200;
                tbY = 20;
                TextBox Box = new TextBox();
                Box.Location = new Point(100 + (tbX), 1 + (tbY));
                Box.Text = value.ToString();
                this.Controls.Add(Box);

                Label label = new Label();
                label.Location = new Point(tbX - labelX, tbY);
                label.Text = Key.ToString() + " (int)";
                label.BackColor = Color.Gray;
                label.BorderStyle = BorderStyle.FixedSingle;
                this.Controls.Add(label);
            }

        }
        private void AddStringField(string value)
        {
            if (tbY < 400)
            {
                tbY = tbY + 20;
                TextBox Box = new TextBox();
                Box.Location = new Point(100 + (tbX), 1 + (tbY));
                Box.Text = value.ToString();
                this.Controls.Add(Box);

                Label label = new Label();
                label.Location = new Point(tbX - labelX, tbY);
                label.Text = "string";
                label.BackColor = Color.Gray;
                label.BorderStyle = BorderStyle.FixedSingle;
                this.Controls.Add(label);
            }
            if (tbY >= 400)
            {
                tbX = tbX + 200;
                tbY = 20;
                TextBox Box = new TextBox();
                Box.Location = new Point(100 + (tbX), 1 + (tbY));
                Box.Text = value.ToString();
                this.Controls.Add(Box);

                Label label = new Label();
                label.Location = new Point(tbX - labelX, tbY);
                label.Text = "string";
                label.BackColor = Color.Gray;
                label.BorderStyle = BorderStyle.FixedSingle;
                this.Controls.Add(label);
            }



        }
        public void AddDateTimeField(DateTime value)
        {
            if (tbY < 400)
            {
                tbY = tbY + 20;
                TextBox Box = new TextBox();
                Box.Location = new Point(100 + (tbX), 1 + (tbY));
                Box.Text = value.ToString("dd.MM.yyyy");
                this.Controls.Add(Box);

                Label label = new Label();
                label.Location = new Point(tbX - labelX, tbY);
                label.Text = "dateTime";
                label.BackColor = Color.Gray;
                label.BorderStyle = BorderStyle.FixedSingle;
                this.Controls.Add(label);
            }
            if (tbY >= 400)
            {
                tbX = tbX + 200;
                tbY = 20;
                TextBox Box = new TextBox();
                Box.Location = new Point(100 + (tbX), 1 + (tbY));
                Box.Text = value.ToString("dd.MM.yyyy");
                this.Controls.Add(Box);

                Label label = new Label();
                label.Location = new Point(tbX - labelX, tbY);
                label.Text = "dateTime";
                label.BackColor = Color.Gray;
                label.BorderStyle = BorderStyle.FixedSingle;
                this.Controls.Add(label);
            }
        }

        public void AddBoolTimeField(bool value)
        {
            if (tbY < 400)
            {
                tbY = tbY + 20;
                TextBox Box = new TextBox();
                Box.Location = new Point(100 + (tbX), 1 + (tbY));
                Box.Text = value.ToString();
                this.Controls.Add(Box);

                Label label = new Label();
                label.Location = new Point(tbX - labelX, tbY);
                label.Text = "boolean";
                label.BackColor = Color.Gray;
                label.BorderStyle = BorderStyle.FixedSingle;
                this.Controls.Add(label);
            }
            if (tbY >= 400)
            {
                tbX = tbX + 200;
                tbY = 20;
                TextBox Box = new TextBox();
                Box.Location = new Point(100 + (tbX), 1 + (tbY));
                Box.Text = value.ToString();
                this.Controls.Add(Box);

                Label label = new Label();
                label.Location = new Point(tbX - labelX, tbY);
                label.Text = "boolean";
                label.BackColor = Color.Gray;
                label.BorderStyle = BorderStyle.FixedSingle;
                this.Controls.Add(label);
            }
        }

        public void ViewEntry(TEntry Entry)
        {
            foreach (KeyValuePair<string,object> aktuellesobject in Entry.Attributes)
              {
                  switch (aktuellesobject.Value.GetType().ToString())
                  {
                      case "System.Int32":
                          AddIntField((int)aktuellesobject.Value, aktuellesobject.Key);
                          break;
                      case "System.String":
                          AddStringField((string)aktuellesobject.Value);
                          break;
                      case "System.DateTime":
                          AddDateTimeField((DateTime)aktuellesobject.Value);
                          break;
                      case "System.Boolean":
                          AddBoolTimeField((bool)aktuellesobject.Value);
                          break;
                  }
              }
        }
 
    }
        
        
}
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mo 05.09.16 20:30 
Zitat:
Wie ich das ganze kürzer schreiben kann muss ich mir noch überlegen. Wobei ich auch zugeben muss, dass es immer unübersichtlicher wird


Kurz oder lang ist kein Problem. Aber Code doppelt zu haben ist ein Problem und verursacht viele dumme Fehler. Z.b. wenn du die Position doch ein klein wenig anders haben willst musst du das an n stellen machen. Wahrscheinlich machst du das dann aber doch nur an einer Stelle und kopierst dann die Codeänderungen. Mit einer gewissen Wahrscheinlichkeit ist der kopierte Code aber nur ähnlich und nicht wirklich gleich und du hast die reinen Bug eingebaut. Schlechter Code ist üblicherweise durchsät mit solchen Copy&Paste Fehlern. Ja erstmal muss der Code funktionieren und dann kann man ihn schön machen bestimmte Dinge sollte man aber nicht aufschieben weil man sie dann letztendlich doch nicht tut.

Einmal solltest du die Vereinfachung so wie schon gezeigt vornehmen. Und zusätzlich würde ich noch ein UserControl schreiben das aus Label und TextBox besteht und du auf deinem EntryViewer Control nutzen kannst. Da richtest du einmal die beiden richtig zueinander aus und kannst dir die Rechnerei sparen die du gerade anstellt. Insbesondere dann wenn du zum anzeigen eines der LayoutPanels (Flow oder Table) verwendest auf das du dieses neue UserControl wirfst. Deine Rechnerei wird dir vermutlich um die Ohren fliegen wenn die Windows Skalierung ins Spiel kommt. Oder hast du dir die DPI Setting deiner Controls schon genau überlegt ;) und mal ausprobiert wenn du den Zoom von Windows auf z.B. 175% stellst wie das dann aussieht? Wenn du das hast dann kannst du anfangen das UserControl mit TextBox,Label durch andere UserControls passend zu ergänzen. Z.B. durch eine mit einer CheckBox anstatt Label,TextBox wenn es ein Bool ist. Oder einen DateTumePicker für DateTime.

Für diesen Beitrag haben gedankt: lapadula
lapadula Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 180
Erhaltene Danke: 10



BeitragVerfasst: Di 06.09.16 15:45 
Hallo, ja du hast schon recht. Mir ist erstmal wichtig, dass das Programm compiliert wird und das tut was ich will.

Die Lupe von Windows und verschiedene auflösungen habe ich ausprobiert, es wird immer korrekt dargestellt.

Kannst du vllt näher erläutern, wie du das mit dem UserControl, bestehend aus Label und Textbox meinst.
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Di 06.09.16 17:17 
EntryViewer ist ein UserControl deshalb bin ich war davon ausgegangen das du weißt was ein UserControl ist. Lag ich da falsch?

Auf dem EntryViewer schmeißt du in deinen AddIrgendwas Methoden immer TextBox und Label einzeln auf das EntryViewer UserControl, posititionierst die relativ zueinander und positionierst die auch relativ zu den anderen TextBox,Label Paaren. Das kann man sich sparen wenn man einmal ein UserControl erzeugt das bereits aus TextBox und Label besteht und auch schon die passende Größe hat so das man einfach weitere dieser UserControls nebeneinander bzw. untereinander anordnen kann so das sie dann quasi natürlich richtig ausgerichtet sind ohne im Code irgendwie merkwürdig mit magischen Zahlen rumrechnen zu müssen.

Für diesen Beitrag haben gedankt: lapadula
lapadula Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 180
Erhaltene Danke: 10



BeitragVerfasst: Mi 07.09.16 12:10 
Ahso aber wenn ich denn ein UserControl habe, mit einem Label und einer Textbox, dann muss ich dieses UserControl dennoch irgendwie in meiner EntryView platzieren und da kenne ich nur die Möglichkeit mit x.Location = new Point(). Aber dann spare ich mir natürlich auch den doppelten Code beim erstellen der Labels und Textboxes

Moderiert von user profile iconTh69: C#-Tags hinzugefügt
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Mi 07.09.16 13:03 
Du könntest auch einfach ein TableLayoutPanel oder FlowLayoutPanel in deinem EntryView-UserControl verwenden und dann die Label/TextBox-UserControls dort hinzufügen.
Aber solange du keine komplizierte Berechnung bei der Positionierung benötigst, ist das manuelle Setzen der Location genauso passend (mache ich bei meinen privaten Spieleprojekten genauso, daß ich sogar alle Controls per Code erzeuge - dafür habe ich dann eine Factory-Klasse mit entsprechenden Create-Methoden, z.B. CreatePanel, CreateButton etc.).

Für diesen Beitrag haben gedankt: lapadula
lapadula Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 180
Erhaltene Danke: 10



BeitragVerfasst: Mi 07.09.16 16:38 
Ich habe nun ein User Control mit einem Label und einer TextBox. Auf dem Formular habe ich ein tableLayoutpanel mit Autosize auf true und einem Button mit dem Code:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
 
private void button2_Click(object sender, EventArgs e)
        {
            tableLayoutPanel1.SuspendLayout();
            foreach(KeyValuePair<string,object> Atr in test.Attributes)
            {
                ULabelTb tmp = new ULabelTb();
                tmp.label1.Text = Atr.Key;
                tmp.textBox1.Text = Atr.Value.ToString();
                tableLayoutPanel1.Controls.Add(tmp, 0, tableLayoutPanel1.RowCount);
            }
            tableLayoutPanel1.ResumeLayout(false);
            tableLayoutPanel1.PerformLayout();
        }


Nun macht er all das (und in ordentlicher) was er vorher mit der EntryViewer-Klasse gemacht hat, in dem bisschen Code von button2.

Danke an alle für die Ratschläge!
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mi 07.09.16 17:15 
So gefällt mir das ;)

Ein kleiner Punkt. Veröffentliche nicht die interna deines UserControls das macht üblicherweise später Probleme.
Verpass dem UserControl einfach eine Methode und/oder erweitere den Construktor um Key/Value zu setzen.

Beispiel:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
// Constructor für ULabelTb 
public ULabelTb(string key, string value) : this()
{
    tmp.label1.Text = key;
    tmp.textBox1.Text = value;   
}

// und dann einfach nur 
ULabelTb tmp = new ULabelTb(Atr.Key, Atr.Value.ToString());
tableLayoutPanel1.Controls.Add(tmp, 0, tableLayoutPanel1.RowCount);

Für diesen Beitrag haben gedankt: lapadula