Autor |
Beitrag |
Csharp-programmierer 
      
Beiträge: 696
Erhaltene Danke: 10
Windows 8.1
C# (VS 2013)
|
Verfasst: Mi 09.12.15 17:30
Der Namespace ist: Web_Studio
Und die Klasse der XML- Datein: XML_Datein
Ich habe die Klasse, die die Speichern- Funktion beinhaltet, in der KLasse XML_Datein
|
|
Th69
      

Beiträge: 4798
Erhaltene Danke: 1059
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Mi 09.12.15 17:43
Und Settings ist dann eine Unterklasse dieser Hauptklasse?
Dann muß diese für die Serialisierung (anscheinend) auch public sein.
Aber warum packst du die Settings-Klasse nicht in einen eigenen Namensbereich (und in eine eigene Datei)?
PS: u.a. wegen den komischen (übersetzten) Fehlermeldungen benutze ich das VS nur auf englisch (auch im Web findet man bei den englischen Fehlermeldungen mehr und bessere Lösungen).
PPS: Es heißt Dateien.
|
|
Csharp-programmierer 
      
Beiträge: 696
Erhaltene Danke: 10
Windows 8.1
C# (VS 2013)
|
Verfasst: Mi 09.12.15 18:33
Vielen Dank. Jetzt haut es hin und die XML- Datei wird erstellt, obwohl ich nicht so genau weiß, warum die Klasse public gemacht werden muss.
Vielen Dank =)
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mi 09.12.15 18:35
Weil der XmlSerializer nur das Serialisieren kann wo er auch rann kommt und wenn die Klasse private oder internal ist kann der die nicht sehen.
|
|
Csharp-programmierer 
      
Beiträge: 696
Erhaltene Danke: 10
Windows 8.1
C# (VS 2013)
|
Verfasst: Mi 09.12.15 20:48
Ich habe jetzt nur noch ein Problem
Ich muss ja für die Laufzeit des Programms neue Objekte (RichTextBox, TabPage) erstellen, für die ich die Werte in der Klasse Settings brauche. Ich habe verucht im Namespace diese Klasse zu instanzieren:
C#-Quelltext 1:
| var settings = XML-Datein.Settings.Load(); |
Jedoch kennt er var da nicht
Aber ich kann ja jetzt nicht in jeder kleinen Funktion die Load- Funktion ausführen. Das ist doch quatsch, oder?
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mi 09.12.15 20:56
Zitat: | Ich habe verucht im Namespace diese Klasse zu instanzieren: |
Code steckt immer in Methoden und Methoden gehören zu Klassen.
Zitat: | Aber ich kann ja jetzt nicht in jeder kleinen Funktion die Load- Funktion ausführen. Das ist doch quatsch, oder? |
Mach aus settings eine Klassenvariable und rufe Load am Anfang einfach einmal auf. Auf settings kannst du dann von überall in der Klasse/Form aus auf zugreifen.
Wenn du aus mehreren Klassen/Formen auf Settings zugreifen willst implementiere in der Settings Klasse eine Singleton Instanz von Settings.
|
|
Csharp-programmierer 
      
Beiträge: 696
Erhaltene Danke: 10
Windows 8.1
C# (VS 2013)
|
Verfasst: Mi 09.12.15 21:06
Und wie deklariere ich eine Klassemvariable?
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mi 09.12.15 21:31
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| public partial class MeinLiebeForm : Form { Settings settings = null; public MeinLiebeForm() { InitializeComponent();
settings = Settings.Load(); }
private void button1_Click(object sender, EventArgs e) { if (!settings.Zumerstenmalgeladen) { } } } |
|
|
Csharp-programmierer 
      
Beiträge: 696
Erhaltene Danke: 10
Windows 8.1
C# (VS 2013)
|
Verfasst: Mi 09.12.15 21:47
Ich habe die Klassenvariable jetzt so deklariert: MaiLet_Webstudio_2015.XML_Datein.Settings settings = null;.
Das haut jetzt auch endlich hin. Das Programm heißt bei VS nur so (also MaiLet_Webstudio_2015). Wenn ich es jetzt unter einem anderen Namen veröffentlichen will, verfällt dann praktisch dieser Name und das Programm funktioniert nicht?
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Do 10.12.15 11:53
Wie das Programm nachher heißt hat nix mit den intern benutzten Namespace Namen zu tun. Die sind zu Anfang wenn du ein Projekttemplate ausführst gleich muß aber nicht so sein und kannst die belibieg in den Projekteinstellungen ändern.
|
|
Csharp-programmierer 
      
Beiträge: 696
Erhaltene Danke: 10
Windows 8.1
C# (VS 2013)
|
Verfasst: Do 10.12.15 17:15
Okay, vielen Dank.
Jetzt habe ich gerade germerkt, dass die XML- Datei gar nicht die ganzen Pfade beinhaltet. Wenn ich den Quellcode richtig verstanden habe, wird der Code ausgeführt, wenn die XML- Datei nicht existiert:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
| public static Settings Load() { if (!File.Exists(Path.Combine(DefaultPath, "Settings.xml"))) return new Settings() { BackGroundColor = Color.White, Font1 = new Font(SystemFonts.DefaultFont, FontStyle.Regular), Sekundärfarbe = Color.Black, Statusstrip = true, Werkzeugleiste = true, WordWrap = true, AutomatischAktualisieren = true, SyntaxHighlighting = true, ToolStrip = true };
XmlSerializer serializer = new XmlSerializer(typeof(Settings)); using (var file = File.OpenRead(Path.Combine(DefaultPath, "Settings.xml"))) { return (Settings)serializer.Deserialize(file); } } |
Obwohl ich nun auf meinem Desktop in dem Programmordner die Datei finde 
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Do 10.12.15 23:55
Zitat: | Wenn ich den Quellcode richtig verstanden habe, wird der Code ausgeführt, wenn die XML- Datei nicht existiert: |
Wenn nicht gefunden bekommst du ein Object mit den im Code gesetzten Defaults oder die Datei wird gelesen (halt wenn sie existiert).
Zitat: | Obwohl ich nun auf meinem Desktop in dem Programmordner die Datei finde  |
Die Bemerkung verstehe ich nicht.
|
|
Csharp-programmierer 
      
Beiträge: 696
Erhaltene Danke: 10
Windows 8.1
C# (VS 2013)
|
Verfasst: Fr 11.12.15 16:32
Das Programm ertsllt auf dem Desktop einen Ordner, in dem alle Unterorder erhalten sind, die das Programm benptigt:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| [XmlElement("HauptPfad")] public string pHauptPfad { get; set; } [XmlElement("Farbkombination")] public string pFarbkombination { get; set; } [XmlElement("Tags")] public string pTags { get; set; } [XmlElement("Tags-HTML")] public string pTags_HTML { get; set; } [XmlElement("pTags_CSS")] public string pTags_CSS { get; set; } [XmlElement("pTags_JS")] public string pTagsJS { get; set; } |
Das sollen die Pfade der Ordner gespeichert werden. Und ich diesem Ordner, der vom Programm auf dem Desktop erstellt wurde, befindet sich auch die Settings-XML-Datei. Aber anscheindend wird der Code ausgeführt, wenn die XML-Datei nicht gefunden wurde, obwohl sie existiert.
EDIT: Ich habe nun anhand des Debuggerprotokolls erkannt, dann in dem Form-Load-Event eine NullReferenceExeption aufgetreten ist, welche ich durch eine MessageBox abgefangen habe. Ich habe nun
settings = MaiLet_Webstudio_2015.XML_Datein.Settings.Load(); in den Konstruktor eingebunden und somit den Fehler behoben. Am Debuggerprotokoll kann ich nun keinen Fehler mehr entdecken, jedoch wird die XML-Datei mit den ganzen Booleans erstellt, die Pfade fehlen dort jedoch noch
Außerdem stand in diesem Protokoll noch: PDB-Datei wurde nicht gefunden oder konnte nicht geöffnet werden.
Moderiert von Th69: Beitragsformatierung überarbeitet.
|
|
Csharp-programmierer 
      
Beiträge: 696
Erhaltene Danke: 10
Windows 8.1
C# (VS 2013)
|
Verfasst: Do 17.12.15 15:56
Hallo meine Lieben. Ich habe den Fehler nun erkannt. Er war mal wieder typisch für mich
Ich habe in der OrdnerLaden- Funktion eine Extra Klassenvariable benutzt. Ich habe sie nun durch die Hauptklassenvariable ausgetauscht und schon funktioniert die Anwendung wieder.
MFG für die super Hilfe 
|
|
Csharp-programmierer 
      
Beiträge: 696
Erhaltene Danke: 10
Windows 8.1
C# (VS 2013)
|
Verfasst: Sa 19.12.15 23:04
Nur noch eine kleine Nebenfrage. Ich habe die Klassenvariable der Mainform nun statisch gemacht, damit ich von allen Formen problemlos darauf zugreifen kann. Was meint ihr? Ist das so gut oder nicht?
|
|
Th69
      

Beiträge: 4798
Erhaltene Danke: 1059
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: So 20.12.15 10:51
Das ist überhaupt nicht gut, da untergeordnete Forms keinen Zugriff auf übergeordnete (Haupt-)Forms haben sollten.
Pack die Variable (wenn es überhaupt eine statische sein muß) besser in eine eigene unabhängige Klasse - alternativ könntest du dafür die Settings-Klasse des WinForms-Projekt benutzen (Zugriff darauf dann per Properties.Settings.Default).
Oder so wie Ralf schon geschrieben hat:
Ralf Jansen hat folgendes geschrieben: | Wenn du aus mehreren Klassen/Formen auf Settings zugreifen willst implementiere in der Settings Klasse eine Singleton Instanz von Settings. |
|
|
Csharp-programmierer 
      
Beiträge: 696
Erhaltene Danke: 10
Windows 8.1
C# (VS 2013)
|
Verfasst: So 20.12.15 20:26
Okay. Und wenn ich diese Klassenvariable nun auf protected setzt und die einzelnen Klassen dann davon erben?
Da mir eine extra Klasse für diese Variable übertrieben erscheint. Und wie man eine Klasse implentiert, weiß ich nicht. Was halten Sie von dem protected?
C#-Quelltext 1:
| public partial class Form2 : Form1 |
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: So 20.12.15 20:58
Zitat: | Da mir eine extra Klasse für diese Variable übertrieben erscheint |
Du hast die Klasse wo das hingehört bereits  Ansonsten Klassen fressen kein Brot da muss man nicht zwanghaft sparen. Eine sinnlose Vererbung ist da viel problematischer. Faustformel die meisten Dinge lassen sich durch Klassenbeziehung besser lösen als durch Vererbung. Vererbung also vorsichtig einsetzen.
Du hast ja am Anfang die Standardklasse vom Framework benutzt. Hast du dich mal gefragt wenn du dort sowas aufrufst wie Settings.Default.Save() was das Default an der Settings Klasse soll?
Gib deiner Settings Klasse einfach eine passende Property um an eine einzelne (ein Singleton) Instanz zu kommen. Wenn du nicht möchtest das man anders als über die Default Property an die Settings kommt könntest du jetzt die Load Methode auf private setzen. Dann hast du einen echten Singleton gebaut.
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| private static Settings defaultInstance; public static Settings Default { get { if (defaultInstance == null) defaultInstance = Settings.Load(); return defaultInstance; } } |
Zuletzt bearbeitet von Ralf Jansen am So 20.12.15 22:57, insgesamt 1-mal bearbeitet
|
|
Csharp-programmierer 
      
Beiträge: 696
Erhaltene Danke: 10
Windows 8.1
C# (VS 2013)
|
Verfasst: So 20.12.15 22:33
Wenn ich nun ihren Code eingebe, dann wird mir defaultInstance rot unterstrichen und als Fehler steht: Für das nicht statische Feld ist ein Objektverweis erforderlich.
Könnten Sie mir bitte noch erklären, was ein Singleton ist?
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: So 20.12.15 22:59
Die Variable muss statisch sein das habe ich vergessen. Sorry. Im Code korrigiert.
Zitat: | Könnten Sie mir bitte noch erklären, was ein Singleton ist? |
a.) Erst nachdem du es ergoogelt hast und es dir dann noch nichts sagt und b.) du es dann mit dem du weiter probierst.
|
|