Laden...

Forenbeiträge von xKushGene Ingesamt 91 Beiträge

04.05.2018 - 19:34 Uhr

Okay, danke dir.

Ich habe mich auf dieser Seite belesen: http://www.datenbanken-verstehen.de/datenmodellierung/normalisierung/dritte-normalform/

Wo auch der Screenshot zu finden ist.

04.05.2018 - 17:51 Uhr

Ah okay, dann habe ich mich anhand folgenden Beispieles irritieren lassen.

Das heißt, dass ich den Ort wieder in die User Tabelle einfügen sollte ?

04.05.2018 - 17:24 Uhr

verwendetes Datenbanksystem: MySQL

Guten Tag, und zwar lerne ich gerade, wie ich eine Datenbank mit der 3. Normalform realisieren kann.

Dazu habe ich nun folgendes Beispiel:

Tabelle: User
Spalten:

  • UserID (PRIMARY KEY, AUTO_INCREMENT)
  • Vorname
  • Nachname
  • PLZ (INDEX, Foreign Key mit PLZ aus Postleitzahl)

Tabelle Postleitzahl

  • PLZ (PRIMARY KEY)
  • Ort
  1. Frage:
    Ich habe ein ganz normales User Erstellungsformular (Vorname, Name, PLZ, Ort).
    Wenn ich die Daten nun absende, wie verhält sich das dann? Prüft MySQL automatisch, ob ein Eintrag mit eingegebener PLZ vorhanden ist? Und was passiert, wenn die PLZ noch nicht existiert ? Muss ich selber mittels Querys prüfen, ob die PLZ vorhanden ist und wenn nicht, dann füge PLZ + Ort in die Postleitzahl Tabelle ein ?
    Wie geht man mit Fremdschlüsseln um ?

  2. Frage
    Wenn ich einen Kunden nun auslesen möchte, bekomme ich nur die PLZ heraus. Wie kann ich gleichzeitig auch den Ort mit angeben ? Ist ein LEFT JOIN nötig, oder wie macht man so etwas am besten mit Fremdschlüsseln?

Ich habe mir die 3. Normalform angeschaut und weiß nun, dass man alles trennen sollte und mehre Tabellen anlegen sollte. Dies habe ich in der oben genannten Datenbank getan.

Wie allerdings muss ich nun meine Querys schreiben?
Also was genau ist nun Vorteilhaft, die 3. NF zu benutzen? Klar, es soll Performanter sein und doppelte Einträge vermeiden.
Aber verstehe ich aktuell noch nicht, was passiert / was man macht wenn wie bspw. in den oben genannten Fragen, bestimmte Einträge noch nicht vorhanden sind.

Ich arbeite gerade an meinem IHK Abschlussprojekt, wo ich ein ER Modell in 3. NF erstellt habe.
Ich habe also sehr viele Tabellen getrennt und ausgelagert. Frage mich aber nun, wie ich das in der Praxis (Querys) verwende (Siehe Anhang)

13.04.2018 - 12:33 Uhr

Vielen Dank für die Ratschläge.

Meine Ausbildung ist recht speziell, wahrscheinlich werden 90% meiner Klassenkameraden nur sehr schwer durch kommen, da die letzten 3 Jahre in dieser Schule reinste Verschwendung war und man kaum was gelernt hatte. Der Lehrer ist auch sehr alt und dies ist zudem sein letztes Jahr, danach schließt er die Schule. Auf jeden Fall ist er sehr unzuverlässig, weshalb ich bei Prüfungsrelevanten Fragen immer die IHK direkt kontaktiere. Nur kann ich bei denen ja schlecht fragen, was denn so in der Prüfung vorkommen wird ^^

Zur Info: Ich musste meinem Ausbilder zeigen, dass es mittlerweile Entwicklungsumgebungen gibt, mit denen man ein UI auch per Drag & Drop oder bei C# mit XAML machen kann. Er hat uns das noch mit Pixel herumschieben erklärt und wusste nicht mal, dass es diese Möglichkeiten bisher gibt.

Im Endeffekt bringen wir uns alles übers Internet selber bei. Daher auch nun so viel zum nachholen.

11.04.2018 - 19:37 Uhr

Hallo miteinander,
und zwar bin ich derzeit im 3. Jahr meiner Ausbildung zum Anwendungsentwickler und schreibe in ca. 2-3 Wochen meine Prüfungen.

Ich wollte mal nachfragen, welche Themen in etwa alles rankommen, damit ich nun nicht ALLES lernen muss.

Ich kann mir vorstellen, dass Datenbanken, UML Diagramme und eben easy Pseudocode ran kommen.
Aber wie sieht es mit den sonstigen Themen aus ? Binärrechnung ? ASCI Tabelle etc. kommt das auch ran?

Vielleicht hat hier jemand ja schon etwas Erfahrung sammeln können, was die IHK so an Themen in ihre Prüfungen schmeißt.

Wäre extrem Nett dies zu erfahren, da ich etwas spät anfange zu lernen ^^

18.10.2017 - 11:18 Uhr

Fehlermeldung:
Zusätzliche Informationen: Die configSource-Datei "connections.config" kann nicht geöffnet werden.

Schau mal ob die Datei wirklich in deinem Anwendungsverzeichnis liegt und geöffnet werden kann.

Die connections.config ist im selben Ordner wie die App.config.

@MrSparkle
Danke für die Stichworte, ich werde mich ran setzen.

Wie schon erwähnt geht es in diesem Topic auch nicht um die Verschlüsselung selbst, sondern nur um den Fehler den ich nicht verstehe, das ich den connectionString von der App.config nicht in connections.config auslagern kann, obwohl ich das Tutorial von Microsoft 1 zu 1 verfolgt habe.
Allerdings bin ich anscheinend vom Thema abgeschweift weshalb wir uns auf einmal über die Sicherheit ausgetauscht haben.

Zwecks der Sicherheit werde ich mir die von MrSparkle genannten Stichworte gründlich anschauen. Aktuell verschlüssel ich nur das Passwort der Einloggdaten mit SHA251 und Salting. So wird in der user.config auch nicht das Passwort als Rohtext angezeigt, sondern als generierter Key, der ja dank dem salting immer anders ist.

17.10.2017 - 16:13 Uhr

Das mit der Verschlüsselung bekomme ich ja soweit hin. Nur mein Problem wie im Titel ist immer noch, dass ich nicht weiß, wie ich connectionStrings in connection.config auslagern kann, da ich immer nh Fehlermeldung bekomme, obwohl ich es genauso mache, wie bei Microsoft beschrieben:

https://msdn.microsoft.com/de-de/library/ms254494(v=vs.110).aspx#Arbeiten mit Anwendungskonfigurationsdateien

Ich habe meine app.config nun mit aspnet_regiis.exe "verschlüsselt" aber wie Abt schon meinte, ist das nicht die sicherste Variante. bzw. kann man die app.config mit aspnet_regiis.exe auch direkt wieder entschlüsseln.

Wie ich schon sagte, behebt das nicht direkt das Problem, aber es macht es schwieriger für Personen die nicht mal wissen, dass es sowas wie aspnet_regiis.exe gibt wie ich vorher zum Beispiel. Somit habe ich eine Angriffszielgruppe weniger.

Klar wird die NSA oder der BND immer noch an die Daten kommen.

17.10.2017 - 15:07 Uhr

Ich gebe die MysqlDaten ja nicht bei jedem Anwendungsstart ein. Deswegen werden diese in der app.config gespeichert.

Ich möchte das alles noch ändern, also sowas wie ein "First Start"-Fenster.
Das Konzept soll wie bei Wordpress sein. Man öffnet das erste mal die Anwendung, nun muss man die Verbindungsdaten zur MySQL Datenbank angeben und bei erfolgreicher Verbindung werden Tabellen und ein Admin Account erstellt.

Ich möchte ja ein Programm schreiben, indem man seine Kunden für einen Laden, einen Service oder so, verwalten zu können. Das heißt jeder Anwender benutzt eine andere Datenbank, wie bei wordpress eben. Da werden die Datenbank informationen ja auch auf dem installierten Webserver gespeichert.
So wie bei meinem Programm die MySQL Daten auf dem installierten PC gespeichert werden sollen.
Dann gibt es ja noch Fälle wie, "Chef gibt das Programm Praktikant XY um auch Kunden auf seine Datenbank einzutragen".
Das heißt, auch er muss auf die gleiche Datenbank zugreifen können, also kommt wieder das Fenster, wo man eine Verbindung zur Datenbank eingeben kann damit diese auch auf dem PC des Praktikanten gespeichert werden.

Ist der connectionString in der app.config also nicht NullOrEmpty, soll das Fenster zur Eingabe für die MySQL Daten auch nicht kommen. Allerdings kann es ja mal sein, dass man "umzieht" auf einen anderen Hoster und man andere MySQL Daten hat. Dafür soll es im programm dann eine Einstellung geben, diese MySQL Daten wieder zu ändern, also der Eintrag connectionString in der app.config soll überschrieben werden.

Natürlich muss das alles eben verschlüsselt sein. Und besser eine nicht perfekte und für einen erfahrenen Entwickler leicht knackbare Verschlüsselung, als roh-text in einer xml Datei welche im %appdata% Ordner liegt.

So verringere ich das Risiko, dass jemand an die Daten kommt, als es komplett für jedermann zu offen zu halten.

Ich hoffe, dass ist ein bisschen verständlicher, für das, was ich vor habe und warum ich das so mache, wie beschrieben ^^.

Was ist denn mit "einem dazwischen geschaltenen Service" gemeint ?

Ich habe mir da ein wenig was durchgelesen und erfahren, dass die Verbindungsdaten anscheinend auf einem Webserver gespeichert werden. Was mir bei meinem Programm aber nichts nützt, da wie erwähnt jeder Anwender eine andere Datenbank benutzt.

17.10.2017 - 14:39 Uhr

Ich bin wie schon mal woanders erwähnt derzeit in einer sehr schlechten Ausbildung und muss mir das meiste selber beibringen.

Dinge wie

Heute würde man einen entsprechenden Service dazwischen schalten, der Credentials zB. auf Token-Basis akzeptiert

sind mir eben neu.

Mein Rollensystem besteht zum Beispiel aus:


if(reader[4] == 0)
   return "Keine Rechte";
else if(reader[4] == 1)
   return "Er hat Rechte";

Also ich bin da noch nicht sonderlich professionell.

Das Ding ist, dass das Programm was ich schreibe auf eine Datenbank zugreift.
Da die Verbindung zu einer Datenbank immer anders sein kann, habe ich beim Login Fenster ein Popup Fenster eingebaut, wo man die MySQL Daten eingeben kann. Bei einem Klick auf speichern werden diese also in die app.config eingespeichert und das Programm wird neugestartet, damit die Änderungen auch wirksam gemacht werden.

Ich habe daher kein festen connectionString, da dieser eben von User zu User validieren kann.

Bisher hat die app.config ganz gut geklappt bis ich eben in %appdata% diese config Datei mit samt Inhalt gefunden habe und gesehen habe, dass die mysql Verbindungsdaten dort komplett unverschlüsselt ausgegeben werden.

Deswegen bin ich nun hier angelangt.

Die Frage ist jetzt. Wie kann ich den connectionString sicher machen, wenn es laut: DB-Passwort sicher speichern

gar nicht geht bzw. man immer noch die Daten herausfinden kann?

Den Link: https://msdn.microsoft.com/de-de/library/53tyfkaw(v=vs.110).aspx

habe ich mir schon vorgemerkt. Aber erst mal habe ich ja noch das Problem, dass ich connectionStrings nicht in connections.config auslagern kann wie hier beschrieben:
https://msdn.microsoft.com/de-de/library/ms254494(v=vs.110).aspx#Arbeiten mit Anwendungskonfigurationsdateien

17.10.2017 - 14:12 Uhr

Also so wie ich es derzeit habe?
Ich habe ja mysql_server usw. aber diese sind eben nicht verschlüsselt und in %appdata% ganz leicht auslesbar. Das will ich ja vermeiden weshalb ich nun diesen connectionStrings verwendet möchte weil man den ja verschlüsseln kann.

Ich lese mich da aktuell noch durch, blicken tue ich das ganze noch nicht ganz.

Edit:
Ich hab es aktuell schon mal hinbekommen, dass ich mich verbinden kann. Aber ich kann connectionStrings immer noch nicht in connections.config auslagern.> Fehlermeldung:

Zusätzliche Informationen: Die configSource-Datei "connections.config" kann nicht geöffnet werden.

17.10.2017 - 13:38 Uhr

Ich lese mir aktuell folgendes durch, um meine app.config zu sichern bzw. nur die Verbindungsdaten zu meiner Datenbank:

https://msdn.microsoft.com/de-de/library/ms254494(v=vs.110).aspx#Arbeiten mit Anwendungskonfigurationsdateien

Dort steht geschrieben, dass ich eine externe Konfigurationsdatei anlegen kann und diese dann in meine app.config einbinden kann:

connections.config


<?xml version="1.0" encoding="utf-8" ?>
<connectionStrings>
  <add name="myConnectionString"
       providerName="MySql.Data.MySqlClient;"
       connectionString="Server=MEINHOST.de;Database=myDataBase;Uid=root;Pwd=myPass;"/>
</connectionStrings>

Und in meiner app.config so verlinkt:


<configuration>
    <connectionStrings configSource="connections.config" />
    <configSections>
        <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
            <section name="ControlcenterWPF.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
        </sectionGroup>
    </configSections>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
    </startup>
    <userSettings>
        <ControlcenterWPF.Properties.Settings>
            <setting name="Username" serializeAs="String">
                <value />
            </setting>
            <setting name="Password" serializeAs="String">
                <value />
            </setting>
            <setting name="StayLoggedIn" serializeAs="String">
                <value />
            </setting>
            <setting name="mysql_server" serializeAs="String">
                <value />
            </setting>
            <setting name="mysql_user" serializeAs="String">
                <value />
            </setting>
            <setting name="mysql_password" serializeAs="String">
                <value />
            </setting>
            <setting name="mysql_database" serializeAs="String">
                <value />
            </setting>
            <setting name="firmenkundentabelle" serializeAs="String">
                <value />
            </setting>
        </ControlcenterWPF.Properties.Settings>
    </userSettings>
</configuration>

So sieht meine app.config aus wo ich allerdings auch nicht genau weiß, was die ersten Zeilen bedeuten und sie daher einfach so lasse.

Auf jeden Fall bekomme ich nun jedes mal einen Error:> Fehlermeldung:

Ein Ausnahmefehler des Typs "System.TypeInitializationException" ist in PresentationFramework.dll aufgetreten.

Zusätzliche Informationen: Der Typeninitialisierer für "System.Windows.Application" hat eine Ausnahme verursacht.

Wenn ich

<connectionStrings configSource="connections.config" />

wieder entferne, bekomme ich den Error nicht.

Weiß hier jemand vlt. woran das liegt? Mein Ziel ist es am Ende einen verschlüsselten connectionString zu haben, da wie man an meiner aktuellen app.config sehen kann, ich den connectionString derzeit folgendermaßen zusammenbaue:


string con = string.Format("Server={0}; DATABASE={1}; UID={2}; PWD={3};", Settings.Default.mysql_server, Settings.Default.mysql_database, Settings.Default.mysql_user, Settings.Default.mysql_password);

Und das ziemlich unsicher ist ^^.

Ich benutze MySQL Connector/Net um eine Verbindung zu meiner Datenbank herzustellen. Weshalb ich bei ProviderName auch Mysql.Data.MysqlClient angegebene habe (sofern das denn auch richtig ist).

06.10.2017 - 13:53 Uhr

In meinem Programm soll es dem User ermöglicht werden, eine Mysql Datenbank anzugeben.
Dafür muss ich irgendwo also die vom user eingegebenen MySQL Daten abspeichern.

Die App.config ist da ja eher weniger sinnvoll, da man diese ganz einfach auslesen kann.
Auch versuche ich mit MVVM zu arbeiten und habe in meiner Solution 2 Projekte, eins für meine Views und eins für meine ViewModels.

Demnach ist die App.config nur im View Projekt und kann vom ViewModel Projekt gar nicht darauf zugreifen.

Deswegen frage ich mich, wie große Firmen dass den machen. Bzw. wie man es normalerweise macht. Also Daten sicher abspeichern und auslesen.

Auch Dinge wie bool StayLoggedIn sollten abgespeichert werden oder andere User Settings.

Ich VERMUTE mal, dass man das über eine externe Datei macht die verschlüsselt ist?
In dem Fall weiß ich aber nicht, was für eine Datei?, Wie verschlüsseln? Das müsste ich dann irgendwo nachlesen deswegen frage ich hier, wie man das für gewöhnlich macht.

05.10.2017 - 16:05 Uhr

Heißt im Endeffekt, dass der Code also in das ViewModel kommt?
Dass habe ich nun getan. Allerdings fange ich langsam an, MVVM zu hassen, da man weder PasswordBox binden kann, noch eine MessageBox anzeigen kann. Alles muss unbedingt um 10 Stufen schwieriger gemacht werden damit ich am ende dann.. ja gut was habe ich eigentlich davon außer 10h an einer MessageBox / binden des Inhalts der PasswordBox zu sitzen?

05.10.2017 - 14:20 Uhr

Hallo,
ich bin gerade dabei, mir MVVM anzueignen und möchte mein bisheriges Code-Behind Projekt in MVVM "nachbauen". Nun habe ich also ein Datagrid und möchte in dieses Datagrid die Daten aus einer Datenbank packen.

Allerdings bin ich mir durch die ganzen Tutorials nun ein wenig unsicher, wie ich das ganze denn mache.
Ich frage mich:
Wo / Wie soll ich nun die Datenbank Verbindung aufbauen?
Ich vermute mal, dass das ganze im Model passieren soll. Denn wie ich das richtig verstanden habe, sind in ViewModel nur Eigenschaften und Commands und in Model dann eben die Methoden. Allerdings habe ich beim Tutorial, was ich verfolgt habe kaum bis gar nicht mit dem Model selber gearbeitet (das mvvm tutorial von codefreaks).

Und wo lege ich dann den Connection String fest, den ich dann überall aufrufen kann, sobald ich ihn eben brauche (also so ziemlich überall).

Auch weiß ich noch nicht, wie ich das Login System einbauen soll.

In meinem LoginViewModel habe ich bisher nur folgendes:


public class LoginViewModel : ViewModelBase, IDataErrorInfo
    {
        private Dictionary<string, string> Errors { get; } = new Dictionary<string, string>();
        private static List<PropertyInfo> _propertyInfo;
        public LoginViewModel()
        {
            LoginButton = new RelayCommand(() =>
            {
                Trace.TraceInformation("OK");
            },
            () => IsOk);
        }

        [Required(AllowEmptyStrings = false, ErrorMessage = "Benutzername erforderlich")]
        [MaxLength(15, ErrorMessage = "Es dürfen maximal 15 Zeichen verwendet werden")]
        public string Username { get; set; }
        public string Password { get; set; }
        public bool StayLoggedIn { get; set; }

        public RelayCommand LoginButton { get; private set; }

        public string this[string propertyName]
        {
            get
            {
                CollectErrors();
                return Errors.ContainsKey(propertyName) ? Errors[propertyName] : string.Empty;
            }
        }

        protected List<PropertyInfo> PropertyInfos
        {
            get
            {
                if (_propertyInfo == null)
                {
                    // TODO filter for other attributes
                    _propertyInfo = GetType()
                        .GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)
                        .Where(prop =>
                            prop.IsDefined(typeof(RequiredAttribute), true) || prop.IsDefined(typeof(MaxLengthAttribute), true) /*|| prop.IsDefined(typeof(MinLengthAttribute), true*/)
                        .ToList();
                }
                return _propertyInfo;
            }
        }

        private void CollectErrors()
        {
            Errors.Clear();
            PropertyInfos.ForEach(
                prop =>
                {
                    var currentValue = prop.GetValue(this);
                    var requiredAttr = prop.GetCustomAttribute<RequiredAttribute>();
                    var maxLenAttr = prop.GetCustomAttribute<MaxLengthAttribute>();
                    //var minLenAttr = prop.GetCustomAttribute<MinLengthAttribute>();
                    if (requiredAttr != null)
                    {
                        if (string.IsNullOrEmpty(currentValue?.ToString() ?? string.Empty))
                            Errors.Add(prop.Name, requiredAttr.ErrorMessage);
                    }
                    if (maxLenAttr != null)
                    {
                        if ((currentValue?.ToString() ?? string.Empty).Length > maxLenAttr.Length)
                            Errors.Add(prop.Name, maxLenAttr.ErrorMessage);
                    }
                    // further attributes
                    //if (minLenAttr != null)
                    //{
                    //    if ((currentValue?.ToString() ?? string.Empty).Length < minLenAttr.Length)
                    //        Errors.Add(prop.Name, minLenAttr.ErrorMessage);
                    //}

                });
            LoginButton.RaiseCanExecuteChanged();
        }

        public string Error => string.Empty;
        public bool HasErrors => Errors.Any();
        public bool IsOk => !HasErrors;

    }

Aber nun hakt es eben daran, dass ich nicht weiß wo/wie ich eine Verbindung zu Datenbank herstelle und wo ich den Code fürs Login hinpacken soll.

Edit:
Ich habe das PropertyChanged.Fody NuGet package installiert sowie MvvmLight

25.09.2017 - 12:55 Uhr

Ah danke, naja ich hatte vorher bei google auf deutsch und englisch gesucht. Wusste nicht, dass das ganze auch web.config genannt wird.

25.09.2017 - 12:33 Uhr

Ich habe ein Programm, wo der User selbst die Datenbankdaten im Programm angibt, um das Programm mit seiner Datenbank zu verbinden (ähnlich wie bei Wordpress).

Diese Daten habe ich einfach in die Visual Studio Settings eingebaut und rufe sie eben mit Settings.Default.mysqlserver als bsp. ab.

Nun habe ich gesehen, dass in %appdata% diese Settings ja komplett unverschlüsselt gespeichert werden. Man kann also DB passwort etc alles sehen.

Das heißt, dass der Settings Designer von VS nicht die richtige Lösung ist. Nun frage ich, was denn die gängigste Methode dafür ist.

Wie speichert man MySQL Daten in einer Datei die vom Programm ausgelesen werden kann, aber nicht von User XY. Oder im besten Fall, ist es möglich Settings.Default Einträge zu verschlüsseln und ist dies Sinnvoll?

20.09.2017 - 16:49 Uhr

Oh okay, dann funktioniert es wohl doch und ich habe mich vorhin nur verguckt oder ähnliches.

Habe eben auch noch mal beide Varianten getestet und bekam dasselbe Ergebnis ^^

20.09.2017 - 12:15 Uhr

Danke für die Ideen,

Ich habe das Problem erst mal mit ner weiteren Liste behoben:


List<double> netto_items = new List<double>();
foreach(Zahlungsliste item in itemList)
{
      netto_items.Add(item.StaticPreis / 1.19);
}

double ges_netto = netto_items.Sum();

Aber ob das effektiver ist, weiß ich leider nicht.

20.09.2017 - 11:32 Uhr

Guten Tag,
ich habe in meiner Liste mehrere Properties, darunter StaticPreis (Brutto).
Wenn ich nun mehrere items in der Liste habe mit StaticPreis = 139,02 134,23, 24,14

Möchte ich, die Summe von allen items.StaticPreis haben. Diese müssen vorher aber durch 1.19 geteilt werden (eben netto).

Folgendes habe ich versucht:

double ges_netto = itemList.Sum(item => item.StaticPreis / 1.19);

Wie kann ich, bevor die Summe errechnet wird, jedes einzelne Item durch 1.19 teilen und erst dann die Summe errechnen ?

24.04.2017 - 16:48 Uhr

Einen Link zu einer kompletten Anwendung mit MVVM habe ich dir schon mal hier gegeben.


>

Reaktion von dir => null

Weil ich irgendwann MVVM aufgegeben habe, da ich Code-Behind gewohnt bin durch Win Forms. Ich werde mir das (hoffentlich) mal in Ruhe durchlesen, auch wenn es dann heißt das ganze Projekt wieder von vorne anzufangen.

24.04.2017 - 16:01 Uhr

.. und hoffentlich ist das Passwort in der Datenbank entsprechend gesalzen und verschlüsselt.

Was meinst du mit gesalzen? Die Passwörter werden als md5 hash in der Datenbank gespeichert.

Ah, mit Interfaces habe ich noch gar nicht gearbeitet.
Ich mache auch alles Code-Behind trotz WPF weil ich MVVM zu kompliziert fand/finde als ich mit dem Projekt angefangen habe.

Ich frage mich aber, warum es diesbezüglich kaum Anleitungen im Internet gibt.

@Coffebean
Ich hatte mir nun eine Klasse gemacht gehabt, nun ist mir aber eingefallen, dass ich auf die Klasse nur zugreifen kann, wenn ich sie neu instanziere.

Wie kann ich eine permanente "Verbindung" zur Klasse aufbauen, ohne sie jedes mal neu zu instanzieren?

Das "Problem" (welches aber funktioniert) habe ich auch mit meiner Datenbankverbindung.
Auf jeder Seite füge ich ganz oben

config conf = new config();

ein und greife dann jedes mal wenn ich eine Verbindung haben möchte so auf sie zu:

connection = new MysqlConnection(conf.connection_string);

Ist denke ich auch der Falsche weg aber in dem Punkt funktioniert es.
Ich hoffe ich habe das einigermaßen verständlich erklärt, ich weiß dass das bei mir öfters schwierig ist.

24.04.2017 - 11:38 Uhr

Guten Tag,

ich möchte in mein Programm ein Rechtesystem einbauen, was heißt, dass das Programm permanent wissen muss "ja wer hat sich denn nun eingeloggt?".

Zurzeit ist mein Login System recht einfach. Ich gebe die Daten ein und es wird nur in der Datenbank überprüft, ob Nutzername und Passwort übereinstimmen.

Das wars. Danach öffnet sich das Programm, was aber weiterhin keine Ahnung hat, dass der Nutzer wessen Nutzername eingegeben wurde angemeldet ist.

Meine Frage ist, wie kann ich so etwas in die Realität umsetzen?
Hat jemand von euch vielleicht ein paar Hilfreiche Links dazu?

So wollte ich das ganze dann machen:
User X loggt sich ein -> Programm überprüft die eingegebenen Daten in der Datenbank -> Bei Erfolg erlangt User X Zugriff zum Programm -> Programm weiß, dass User X und nicht User Y,Z oder I eingeloggt ist -> Vielleicht eine Anzeige mit "Angemeldeter User: User X" als Bestätigung der Funktion.

Und wenn das Programm dann dauerhaft weiß, welcher User eingeloggt ist, dann kann ich das Rechtesystem in Angriff nehmen (würde das mit lauter Datenbankeinträgen regeln Nein = 0, Ja = 1).

10.04.2017 - 13:43 Uhr

Guten Tag.

Ich habe mehrere Kategorien, in denen ich weitere Kategorien hinzufügen will. Das läuft alles über die Datenbank.

Als erstes werden die Hauptkategorien als Expander im Code erstellt.
Nun sollen diese Expander ein TreeView bekommen, in denen die Unterkategorien hinein sollen.

Dafür habe ich bis jetzt folgenden Code:

while(reader.Read())
                    {
                        int categoryID = (int)reader["id"];

                        Expander cat_expander = new Expander();
                        cat_expander.ExpandDirection = ExpandDirection.Right;
                        TextBlock cat_name = new TextBlock();
                        cat_name.Text = reader["name"].ToString();
                        cat_name.RenderTransformOrigin = new Point(0.5, 0.5);
                        cat_name.LayoutTransform = new RotateTransform() { Angle = 90 };
                        cat_expander.Header = cat_name;

                        Thread t = new Thread( () => LoadUnderCategories(categoryID) );
                        t.Start();
                        t.Join();

                        Border border = new Border();
                        border.Width = 1;
                        border.VerticalAlignment = VerticalAlignment.Stretch;
                        border.SnapsToDevicePixels = true;
                        border.Background = (Brush)FindResource("MaterialDesignDivider");

                        cat_expander.Content = serviceList;
                        serviceListSP.Children.Add(cat_expander);
                        serviceListSP.Children.Add(border);

                        serviceList.Items.Clear();
                    }

Meine LoadUnderCategories sieht wie folgt aus:

private void LoadUnderCategories(int categoryID)
        {
            connection = new MySqlConnection(conf.connection_string);
            MySqlCommand cmd = new MySqlCommand();
            cmd.Connection = connection;
            cmd.CommandText = "SELECT * FROM auftrags_typ_childcategory WHERE category = @categoryID";
            cmd.Parameters.AddWithValue("@categoryID", categoryID);

            if(this.OpenConnection() == true)
            {
                try
                {
                    MySqlDataReader reader = cmd.ExecuteReader();
                    while(reader.Read())
                    {
                        TreeViewItem child_category = new TreeViewItem();
                        child_category.Header = reader["name"].ToString();
                        serviceList.Items.Add(child_category);
                    }
                }
                catch(MySqlException ex)
                {
                    MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
        }

Nun erkläre ich mein Vorgehen.
Ich möchte im hauptdurchgang (im ersten Code) den Code pausieren, weshalb ich einen Thread erstellt habe und mit Join pausiere. serviceList ist eine globale Variable (TreeView).
In dem Thread der aufgerufen wird, lese ich alle Items aus der Datenbank, welche den "category" wert der übermittelten id haben und packe sie in das TreeView. Wenn der Thread fertig ist, fügt die StartMethode noch einen Border hinzu und die added die controls den panels.

Sieht für mich eigentlich logisch aus, aber ich bekomme folgenden Fehler beim ausführen des Codes:

Fehlermeldung:
"System.InvalidOperationException" ist in PresentationCore.dll aufgetreten.

Zusätzliche Informationen: Beim aufrufenden Thread muss es sich um einen STA-Thread handeln, da dies für viele Komponenten der Benutzeroberfläche erforderlich ist.

Ich kann mit der Meldung leider überhaupt nichts anfangen.
Die Meldung wirft er mir bei:

TreeViewItem child_category = new TreeViewItem();

in LoadUnderCategories.

Hat hier vielleicht jemand eine Ahnung, wie ich diesen Fehler beheben kann?

30.03.2017 - 16:17 Uhr

Hmm Okay.
Kann damit leider nicht viel anfangen.
Habe noch ein Beispiel gefunden, womit ich leider auch nichts anfangen kann.

Mein Problem ist halt, dass ich nicht weiß, wie ich von MainWindow aus, auf eine Variable im UserControl zugreifen kann.

Folgenden Code habe ich jetzt:

public string Text
        {
            get
            {
                string s = (string)GetValue(TextProperty);
                return s;
            }
            set
            {
                if (Text != value)
                {
                    SetValue(TextProperty, value);
                }
            }
        }

        public static readonly DependencyProperty TextProperty =
            DependencyProperty.Register("Text", typeof(string), typeof(addMitarbeiter_Control), new PropertyMetadata(null, Text_PropertyChanged));

        private static void Text_PropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
        {
            ((addMitarbeiter_Control)source).vornameBox.Text = (string)e.NewValue;
        }


        void vorname_TextChanged(object sender, TextChangedEventArgs e)
        {
            Text = vornameBox.Text;
        }

Ich denke, dass funktioniert auch soweit. Aber wie kann ich String Text in MainWindow ausgeben?

29.03.2017 - 17:23 Uhr

Ich habe in einem Fenster 2 Tabitems, welche 2 UserControls beinhalten.
Im UserControl habe ich mehrere TextBoxes, welche ich über einen Klick auf einen Button, welcher in MainWindow ist über MessageBox ausgeben möchte.

Im UserControl habe ich dazu also folgende Properties:

public string Vorname
        {
            get { return vornameBox.Text; }
            set { vornameBox.Text = value; }
        }
        public string Nachname
        {
            get { return nachnameBox.Text; }
            set { nachnameBox.Text = value; }
        }

Wie komme ich nun von MainWindow aus an diese Properties heran um sie auszugeben? Wenn ich sie neu instanziere funktioniert es nicht.

24.03.2017 - 11:21 Uhr

Probiere mal

  
if(result == MessageBoxResult.No)  
{  
    e.Handled = true;  
}  
  

Funktioniert soweit.
Allerdings passiert nichts, wenn ich auf JA drücke. Habe es mal einfach zum testen mit

e.Handled = false 

versucht aber auch kein Erfolg gehabt.
Wenn man ja drückt soll sich der ToggleButton ändern.

Gibt es da auch irgendeine e.Methode ?

trenne bitte deinen Datenbank-Code vom UI-Code!

Ist für mich gerade kompliziert, weshalb ich auch beim Code-Behind bleibe und es so mache, dass es funktioniert. Auch wenn es gammlig ist 😄 Aber ich werde es sicherlich noch lernen. Mit MVVM und 3 Schichten Architektur komme ich durcheinander.

24.03.2017 - 10:44 Uhr

Ich habe eine Ja/Nein Abfrage gemacht, sobald man auf den ToggleButton klickt.
Ich möchte, dass wenn man auf Nein drückt, sich der Toggle Button NICHT ändern. Also er soll nicht von Checked auf Unchecked oder ansersherum wechseln.

Wenn JA geklickt wird, soll es allerdings passieren.

Gibt es eine Funktion, die dieses Event nicht aufruft?
Wenn ich auf Nein Drücke, ändert sich der ToggleButton trotzdem.

Meine Checked / Unchecked Events:


        private void customerTypeButton_Checked(object sender, RoutedEventArgs e)
        {
            if (customerIDBox.Text != null)
            {
                customerIDBox.Text = null;
            }
            // PrivateCustomer For Search
            PrivateCustomerChecked = true;
            FirmCustomerChecked = false;
            columns_sql = "SELECT * FROM " + privateCustomerTablename;
            if (comboboxSearch != null)
            {
                comboboxSearch.Items.Clear();
            }
            LoadColumnsComboBox();
        }
        private void customerTypeButton_Unchecked(object sender, RoutedEventArgs e)
        {
            if (customerIDBox.Text != null)
                {
                    customerIDBox.Text = null;
                }
                // FirmCustomer for search
                PrivateCustomerChecked = false;
                FirmCustomerChecked = true;
                columns_sql = "SELECT * FROM " + firmCustomerTablename;
                if (comboboxSearch != null)
                {
                    comboboxSearch.Items.Clear();
                }
                LoadColumnsComboBox();
        }

Und die Abfrage, die bisher noch leer ist (Hatte die Abfrage vorher an erster Stelle der beiden Events gepackt):


        private void customerTypeButton_Click(object sender, RoutedEventArgs e)
        {
            MessageBoxResult result = MessageBox.Show("Wenn Sie den Kunden-Typ verändern, wird die KundenID aus der Textbox entfernt. In der Kunden Suche werden Ihnen nur die Filter für den ausgewählten Kunden-Typ angezeigt. Wollen Sie den KundenTyp wirklich Ändern?", "Achtung!", MessageBoxButton.YesNo, MessageBoxImage.Warning);
            if(result == MessageBoxResult.Yes)
            {

            }
            if(result == MessageBoxResult.No)
            {

            }
        }
22.03.2017 - 10:08 Uhr

Zum testen habe ich nach dem Klick auf Speichern auch noch eine If-Anweisung gemacht.

if (Settings.Default.mysql_server == mysqlserverbox.Text && Settings.Default.mysql_user == mysqluserbox.Text && Settings.Default.mysql_password == mysqlpassbox.Text && Settings.Default.mysql_database == mysqldatabasebox.Text)
            {
                MessageBox.Show(Settings.Default.mysql_server);
                MessageBox.Show(Settings.Default.mysql_user);
                MessageBox.Show(Settings.Default.mysql_password);
                MessageBox.Show(Settings.Default.mysql_database);
                MessageBox.Show("Erfolg");
            }
            else
            {
                MessageBox.Show("Fehler");
            }

Und er gibt jedes mal die MessageBox aus, das heißt eigentlich sollten die Daten übernommen worden sein.

An sich habe ich für mein Login nicht viel Code.

Ein Click auf den Speichern Button führt die methode SaveMysqlData aus:

private void SaveMysqlData()
        {
            string mysqlserver = mysqlserverbox.Text;
            string mysqluser = mysqluserbox.Text;
            string mysqlpass = mysqlpassbox.Text;
            string mysqldatabase = mysqldatabasebox.Text;

            Settings.Default.mysql_server = mysqlserver;
            Settings.Default.mysql_user = mysqluser;
            Settings.Default.mysql_password = mysqlpass;
            Settings.Default.mysql_database = mysqldatabase;
            Settings.Default.Save();
            if (Settings.Default.mysql_server == mysqlserverbox.Text && Settings.Default.mysql_user == mysqluserbox.Text && Settings.Default.mysql_password == mysqlpassbox.Text && Settings.Default.mysql_database == mysqldatabasebox.Text)
            {
                MessageBox.Show(Settings.Default.mysql_server);
                MessageBox.Show(Settings.Default.mysql_user);
                MessageBox.Show(Settings.Default.mysql_password);
                MessageBox.Show(Settings.Default.mysql_database);
                MessageBox.Show("Erfolg");
            }
            else
            {
                MessageBox.Show("Fehler");
            }
        }

Die config Datei besteht auch nur aus dem Code, den ich geschrieben habe und eben den Connection String:

public string connection_string = string.Format("SERVER={0}; DATABASE={1}; UID={2}; PWD={3};", SERVER_ADRESS, DATABASE, UID, PWD);

Nun gut, ich dachte es gibt eine andere Methode, die vielleicht für solche Dinge vorgesehen ist. Beispielsweise eine Art config Datei die von hause aus schon "verschlüsselt" ist oder etwas ähnliches.

Stehen die geänderten Daten in der settings Datei aber diese werden bei einer neuen Verbindung nicht verwendet?

Genau. Die MessageBox bei der If-Anweisung gibt mir erfolgreich die geänderten Daten aus. Aber wenn ich mich dann verbinden möchte heißt es "MySQL Host nicht gefunden". Versuche ich das 1-2 mal oder starte das Programm und versuche dann nochmal mich einzuloggen funktioniert es. Das meine ich mit "manchmal funktioniert es und manchmal nicht". Aber die Settings werden meiner Ansicht nach immer gespeichert.

21.03.2017 - 17:31 Uhr

Zurzeit habe ich meine MySQL Daten in den Settings Gespeichert.
Sie werden also wie folgt ausgelesen:


        private static string SERVER_ADRESS = Settings.Default.mysql_server;
        private static string DATABASE = Settings.Default.mysql_database;
        private static string UID = Settings.Default.mysql_user;
        private static string PWD = Settings.Default.mysql_password;

Die Daten kann der Privatanwender auch ändern (falls er sich zu einer anderen Datenbank verbinden möchte):

string mysqlserver = mysqlserverbox.Text;
            string mysqluser = mysqluserbox.Text;
            string mysqlpass = mysqlpassbox.Text;
            string mysqldatabase = mysqldatabasebox.Text;

            Settings.Default.mysql_server = mysqlserver;
            Settings.Default.mysql_user = mysqluser;
            Settings.Default.mysql_password = mysqlpass;
            Settings.Default.mysql_database = mysqldatabase;
            Settings.Default.Save();

Allerdings läuft das nicht so ganz. Es funktioniert zwar, jedoch nur ab und zu. Das Mit den Settings ist also nicht die beste Lösung, da er oft nicht die Änderungen übernimmt, aber manchmal wiederum doch, ich verstehe das nicht.

Nun Frage ich mich also, gibt es einen anderen Weg, als dies über Settings zu machen?
Meine Idee war als erstes die Daten in eine XML Datei abzuspeichern und sie dann auszulesen. Und wenn der Anwender sich für eine andere Datenbank entscheidet, wird die XML einfach überschrieben. Sollte funktionieren, jedoch kann dann jeder x-beliebige die XML Datei öffnen und die MySQL Daten sehen. Ich denke auch nicht, dass das eine gute Lösung wäre.

Was könnte man stattdessen machen?

03.03.2017 - 11:26 Uhr

Guten Tage miteinander,

vielleicht bekomme ich hier ja ein wenig Hilfe zu MVVM. Ich verstehe MVVM einfach nicht.
Die Idee an sich verstehe ich, aber der Code dahinter ist noch etwas kompliziert.

Ich hab mir etliche Tutorials angeschaut aber komme nie weiter.

Habe mir nun ein Login / Authentication Tutorial mit MVVM angeschaut und versuche es umzusetzen (Der Typ, der das gemacht hat nutzt Als Login ein UserControl usw.
Ich Möchte ein Fenster als Loginfenster was bei Erfolg dann das Hauptfenster öffnet).
Weil der Typ viel bzw. fast alles mit UserControls gemacht hat, ist der Code etwas anders und ich kann die Dateien im View nicht 1 zu 1 übernehmen.

Falls sich jemand das mal anschauen möchte: https://code.msdn.microsoft.com/windowsdesktop/Easy-WPF-Login-Navigate-7a8d34a0/view/SourceCode#content

Helpers, Model und ViewModel habe ich 1 zu 1 übernommen.
Beim View habe ich mein eigenes Aussehen natürlich aber x:class etc. alles natürlich angepasst.

Der Typ hat beim MainWindow einiges an Code-Behind, was sich aber auf die UserControls bezieht.

Zu MVVM:
An sich habe ich ja nun die Grundlagen von MVVM in meinem Projekt. Aber weiß nicht, wie ich vorgehen soll, wenn ich eigene Sachen hinzufügen möchte.
Beispielsweise möchte ich später fast alles aus der Datenbank lesen. Also die Spalten einer Tabelle um den Inhalt (Personen) in einem DataGrid auszugeben.
Anschließend soll man die Personen auch bearbeiten/ löschen können und auch über das Programm die Spalten einer Tabelle bearbeiten/löschen und eigene hinzufügen können.

Ich kann mir vorstellen, dass das ziemlich schwer wird. Da der Code nicht weiß, wie viele und welche Tabellen in einer Datenbank sind.
Also kann ich im Model die Eigenschaften noch nicht festlegen wie es zum Beispiel in der User.cs vom geteilten Projekt der Fall ist wo Username und Password schon definiert wird.

Deswegen wird es höchste Zeit, zu verstehen wie man in MVVM programmiert und hoffe hier vielleicht etwas Hilfe zu bekommen.

28.02.2017 - 10:59 Uhr

Gegenfrage:
Woher weiß dein Command, welche Connection es nutzen soll?

Das ist mir jetzt aber peinlich..
Danke für den Hinweis funktioniert nun wieder.

28.02.2017 - 10:51 Uhr

Ich habe ein Login System, welches immer gecrashed ist, sobald

MySqlDataReader login = cmd.ExecuteReader();

erreicht wurde.
Darraufhin habe ich dadrüber einfach

connection.Open();

gepackt und es funktioniert auch (wenn MySQL ausgeschaltet ist).

Allerdings gibt er mir jetzt den Error, wenn ich mich einloggen will und MySql angeschaltet ist.

Die Connection ist doch aber geöffnet:

try
            {
                MySqlCommand cmd = new MySqlCommand();
                connection = new MySqlConnection(conf.connection_string);
                cmd.CommandText = $"SELECT username, password FROM users WHERE username=@user AND password=@pass";
                cmd.Parameters.AddWithValue("@user", user);
                cmd.Parameters.AddWithValue("@pass", pass);
                connection.Open();
                MySqlDataReader login;
                login = cmd.ExecuteReader();
                if (login.Read())
                {
                    connection.Close();
                    return true;
                }
                else
                {
                    connection.Close();
                    return false;
                }
            }

Wieso bekomme ich den Fehler also?

20.02.2017 - 17:22 Uhr

Ich habe mir das Tutorial von: https://www.codeproject.com/Tips/813345/Basic-MVVM-and-ICommand-Usage-Example angeschaut und stoße aber auf ein Problem.

Als erstes funktioniert das MessageBox bei mir nicht.
Was aber auch egal ist, da ich das nicht brauche.

Nun möchte ich, dass sich per Button Click der Content eines Frames ändert.

Meine XAML im Ui.Desktop Projekt sieht wie folgt aus:

<Frame NavigationUIVisibility="Hidden" Content="{Binding Content}" x:Name="Main" Background="Cyan" Grid.Row="0" Grid.Column="1" Grid.RowSpan="3">

Nun kommen wir zu meinem Logic.Ui Projekt.
In der MainViewModel steht der Code übernommen von dem Tutorial, welches oben verlinkt ist mit folgenden ergänzungen:

private ICommand content;
public ICommand Content
        {
            get { return content; }
            set { content = value; }
        }
public void ShowMessage(object obj)
        {
            Content =  
        }

Nun möchte ich Content = new Show.PrivateCustomers_show(); eingeben.
Aber natürlich kennt Logic.Ui nicht die Ordner und Seiten von Desktop.Ui.
Das soll ja nehme ich an auch so bleiben.

Wie kann ich das ganze also realisieren?
Beschäftige mich nun seit 2 Tagen damit und verstehe das ganze einfach nicht, da jede Anleitung anders ist. Beim Rheinwerk ebook wird es auch nicht super erklärt.

17.02.2017 - 15:42 Uhr

Bin leider immer noch nicht weitergekommen.
Auf Stackoverflow hat jemand folgendes geschrieben:

How about adding an event in privatecustomer_show.xaml that the MainWindow.xaml can subscribe to.

Like this

  public event EventHandler AddPrivateCustomer;

  protected virtual void OnAddPrivateCustomerEventArgs e) 
  {
     if (AddPrivateCustomer!= null)
        AddPrivateCustomer(this, e);
  }

Update: Please note the updated code, I made a copy'n'paste mistake in my first version.

Change your: private void privatecustomer_Click(object sender, RoutedEventArgs e)

To:

private void privatecustomer_Click(object sender, RoutedEventArgs e)
{
  var privateCustomerContent=new Privatecustomer.privatecustomer_show();
  privateCustomerContent.AddPrivateCustomer+=onClick_addPrivateCustomer;
  Main.Content = privateCustomerContent;
}

private onClick_addPrivateCustomer(object o,EventArgs e)
{
  // Change Main.Content
}

The idea is that your privatecustomer_show control sends events for when it want to change something outside of what it has access to. You MainWindow which has full control of all its child windows will then subscribe to each event.

Aber irgendwie buggt folgender Code rum:

protected virtual void OnAddPrivateCustomerEventArgs e) 
  {
     if (AddPrivateCustomer!= null)
        AddPrivateCustomer(this, e);
  }

habe es mit

protected virtual void OnAddPrivateCustomer(EventArgs e) 

probiert aber auch kein Erfolg.

Schaue mir auch Tutorials zu MVVM an. Aber so richtig verstehen tue ich auch nichts.
Gerade verfolge ich eine Tutorialreihe auf YouTube wo der Uploader MvvmLight benutzt. Komme mit dem ganzen aber ein wenig Durcheinander..

15.02.2017 - 15:45 Uhr

Ich verstehe das nicht so ganz.

Also mit:

 Privatkunden.privatkunden_show show = new Privatkunden.privatkunden_show();

Würde ich in MainWindow die Datei privatkunden_show instanzieren.
Das heißt, dass MainWindow, "privatkunden_show" kennt.

Hoffe der Ansatz ist schon mal richtig.
Soviel habe ich bisher zumindest verstanden.

Wie merkt MainWindow nun aber, dass auf privatkunden_show der Button "addPrivatkunde" getätigt wurde? Und wie lege ich in MainWindow dann fest, dass beim Klick von dem Button, das Frame Main den Content von privatkunden_add bekommt ?

Edit:
Bei deinem Artikel war ich etwas besser aufgehoben, allerdings verstehe ich hier auch noch ein paar Dinge nicht.

Mein privatkunden_show sieht nun wie folgt aus:

public partial class privatkunden_show : Page
    {
        public privatkunden_show()
        {
            InitializeComponent();
        }
        
        // TESTING
        public class TextEventArgs : EventArgs
        {
            public TextEventArgs(object text)
            {
                Text = text;
            }

            public object Text { get; set; }
        }

        public event EventHandler<TextEventArgs> UpdateText;

        public void addPrivatkunde(object sender, RoutedEventArgs e)
        {
            OnUpdateText(new TextEventArgs(new Privatkunden.privatkunden_add()));
        }

        protected virtual void OnUpdateText(TextEventArgs e)
        {
            EventHandler<TextEventArgs> ev = UpdateText;
            if (ev != null)
                ev(this, e);
        }
    }

Also in etwa wie bei deinem Tutorial.
(Hatte Jetzt einfach mal alles übernommen mit den Text, da es am Anfang bei mir fehlerhaft war.

Und in meinem MainWindow habe ich folgendes hinzugefügt:

 void UpdateLabelText(object sender, Privatkunden.privatkunden_show.TextEventArgs e)
        {
            Main.Content = e.Text;
        }

Allerdings funktioniert das nicht. Und ich weiß auch nicht, wie MainWindow bemerken kann, dass bei privatkunden_show der Button addPrivatkunde getätigt wurde.

15.02.2017 - 14:40 Uhr

Ich will ja auf das Frame im Hauptfenster zugreifen. In diesem Frame möchte ich nicht mehr privatkunden_show anzeigen (wie es zu dem Zeitpunkt der Fall ist) sondern beim Klick auf den Erstellen Button, privatkunden_add anzeigen.

Wie genau mach ich das, wenn nicht so?
Ich dachte mithilfe von


MainWindow mainwindow = new MainWindow();
mainwindow.Main.Content = new Privatkunden.privatkunden_add();

greife ich auf das Frame "Main" im Hauptfenster zu und ändere den Content dann dementsprechend.

15.02.2017 - 14:11 Uhr

Guten Tag.
Ich habe in meinem Programm mehrere Seiten, die auch funktionierend angezeigt werden:

 private void privatkunden_Click(object sender, RoutedEventArgs e)
        {
            Main.Content = new Privatkunden.privatkunden_show();
        }

Main ist der name vom Frame.

In der privatkunden_show habe ich einen button, welcher die Seite privatkunden_add aufrufen soll:

 private void addPrivatkunde(object sender, RoutedEventArgs e)
        {
            MainWindow mainwindow = new MainWindow();
            mainwindow.Main.Content = new Privatkunden.privatkunden_add();
        }

Allerdings, wird mir beim Klick auf den Button nichts angezeigt. Bzw. passiert einfach nichts.
Der Code sieht meiner Ansicht nach richtig aus und ich wüsste nun nicht, was ich anders machen muss.

Vielleicht kann mir hier ja jemand erklären, wieso die Seite privatkunden_add nicht aufgerufen wird.

04.02.2017 - 10:03 Uhr

Welche UI verwendest du denn (WinForms oder WPF)?
Ich tippe mal auf letzteres - wie sieht dann deine XAML und ViewModel dazu aus?

Jap. WPF.
Meine XML sieht wie folgt aus:

<Textures>
      <Texture Name="Default Block" Description="The Default Block" TexturePath="Resources/0.png" Selected="true" Default="true" Category="mainblocks" Subcategory="grassblocks"/>
      <Texture Name="Alternative Block" Description="An Alternative Block" TexturePath="Resources/1.png" Selected="false" Category="mainblocks" Subcategory="grassblocks" Default="false" />
      <Texture Name="Default Block STONE" Description="The Default Block" TexturePath="Resources/0.png" Selected="false" Default="true" Category="mainblocks" Subcategory="stone" />
      <Texture Name="Alternative Block STONE" Description="An Alternative Block" TexturePath="Resources/1.png" Selected="false" Default="false" Category="oreblocks" Subcategory="stone" />
</Textures>

Ich habe Category und Subcategory als Attribut gemacht, da ich das mit <Category name="mainblocks"> nicht hinbekommen habe. Also die Daten dann auszulesen. So funktioniert es ja.

Meinst du mit ViewModel den Code um das auszulesen?:

 textureList = (
                 from el in XDocument.Load(@"C:\Users\Kevin\documents\visual studio 2015\Projects\Ragecraft Customizer WPF\mainFrm\Textures.xml").Root.Elements("Texture")
                 where (string)el.Attribute("Category") == "mainblocks"
                 select new Texture
                 {
                     Name = (string)el.Attribute("Name"),
                     Description = (string)el.Attribute("Description"),
                     TexturePath = (string)el.Attribute("TexturePath"),
                     Selected = (bool)el.Attribute("Selected"),
                     Default = (bool)el.Attribute("Default"),
                     Category = (string)el.Attribute("Category"),
                     Subcategory = (string)el.Attribute("Subcategory")
                 }).ToList();
04.02.2017 - 03:03 Uhr

Guten Abend.

Ich möchte meine XML Elemente in einer Category geordnet haben. Dazu habe ich als Attribut "subcategory" festgelegt und möchte nun, dass alle Elemente, welche den gleichen Inhalt bei subcategory haben, ein Border bekommen, worin der Name der Subcategory drin steht.

Funktioniert soweit auch. Allerdings wird für jedes Element so ein Border erstellt. Ich möchte nur, dass ein Border für alle Elemente erstellt wird. Als Beispiel habe ich ein Screenshot gemacht.
Derzeit ist das in einer For Schleife (deswegen bekommt auch jedes Element diesen Border).

Mir fällt aber keine passende Schleife dazu ein, wie ich das so regeln kann das jetzt Default Block und Alternative Block in EINEM grassblock Border sind.

Ich glaube nicht, dass while, foreach oder for mir da weiterhelfen können und frage deshalb hier, wie ich das problem am besten lösen könnte.

mfg

01.02.2017 - 02:54 Uhr

Ich möchte mich von WinForms trennen und mit WPF anfangen Programme zu schreiben.
Doch wie genau style ich damit? Ich verstehe das mit den Dock Panels etc nicht. Bei Winforms kann ich mein Panel einfach an top andocken und schon ist es auch automatisch der Weite angepasst.

Das ist bei WPF nicht der Fall.
Ich kann auch nichts auf Google finden, Beispielsweise Tutorials, wie man Programme designed.

Als Beispiel habe ich mal etwas in den Anhang gepackt. Auf dem Bild sieht man super die Panels (anhand verschiedener Hintergrundfarben). Ganz Oben Habe ich 2 Panels. Das Hauptpanel (Top) und noch ein Panel im Toppanel was left ist (für das logo).

Alleine das (und die Navigation) in WPF scheinen mir derzeit noch unmöglich. Da DockPanel auch keine Dock Eigenschaft hat frage ich mich, wie ich die Programme nun designen kann und sich alles auch an die Grüße des Fensters anpasst.

Ich hoffe mir kann hier jemand zum Thema WPF und den Panels weiterhelfen.

18.01.2017 - 22:32 Uhr

Das lese ich ja. Ich bin jetzt bei Methoden und Parametern und so n kram. Das mit den Listen kam noch gar nicht.

18.01.2017 - 19:50 Uhr

Das Ding ist, dass ich, wenn ich die Liste ausgeben muss sie auch mit einer for-schleife ausgeben muss.

Das heißt, dass das Problem dann doch immer noch da ist.

Edit:

Und wie in deinem anderem Thema
>
von MrSparkle schon angesprochen solltest du eine Datenklasse anlegen, z.B.

  
class Texture  
{  
  public string Name { get; set; }  
  public string Description {  get; set; }  
}  
  

Verstehe ich nicht so ganz.

Ich habe da eine Liste angelegt:


public string[] ReadTextureFromXml()
        {
            XDocument textures = XDocument.Load(@"C:\Users\Kevin\Documents\Visual Studio 2015\Projects\Minecraft Customizer\Minecraft Customizer\textures\textures.xml");

            List<string> textureList = new List<string>();

            foreach (var texture in textures.Descendants("texture"))
            {
                textureList.Add(texture.Element("name").Value);
                textureList.Add(texture.Element("description").Value);
            }
            string[] array = textureList.ToArray();
            return array;

Sie dann als ein Array übergeben.

18.01.2017 - 19:16 Uhr

Guten Abend,

Ich habe Daten aus einer XML Datei gelesen und in ein Array gepackt.
Die XML sah wie folgt aus:

<texture>
    <name>Block 1</name>
    <description>Das ist Block 1</description>
</texture>
<texture>
    <name>Block 2</name>
    <description>Das ist Block 2</description>
</texture>

Im Array sieht das nun wie folgt aus:

Array[0] = Block 1 (Name)
Array[1] = Das ist Block 1 (Description)
Array[2] = Block 2 (Name)
Array[3] = Das ist Block 2 (Description)

Nun habe ich ein Panel erstellt was nur Name und Description anzeigen soll.
Allerdings macht er kein Panel mit:
Name: Block 1
Description: Das ist Block 1.

Sondern er macht
Name. Block 1
Description: Block 1

  1. Panel
    Name : Das ist Block 1
    Description: Das ist Block 1

usw.....

Irgendwas muss in meiner For-Schleife falsch sein, und ich weiß nicht wie ich das richtig machen soll.


TexturesOut hXML = new TexturesOut();
            string[] myarr = hXML.test().ToArray();
            int laenge = hXML.test().Length;

            for(int i = 0; i < laenge; i++)
            {
                Panel pan = new Panel();
                pan.Name = "paneltest" + i;
                pan.Size = new Size(239, 73);
                this.Controls.Add(pan);
                for(int j = 0; j < 2; j++)
                {
                    Label LblName = new Label();
                    LblName.Name = "lblname" + j;
                    LblName.Text = myarr[i];
                    LblName.AutoSize = true;
                    LblName.Location = new Point(73, 3);
                    LblName.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
                    LblName.Size = new System.Drawing.Size(39, 13);
                    this.Controls.Add(LblName);
                    pan.Controls.Add(LblName);

                    Label Description = new Label();
                    Description.Name = "lbldesc" + j;
                    Description.Text = myarr[i];
                    Description.Location = new Point(73, 21);
                    Description.AutoSize = true;
                    this.Controls.Add(Description);
                    pan.Controls.Add(Description);
                }
                flowLayoutPanel1.Controls.Add(pan);

So war jetzt meine idee dahinter. Allerdings funktioniert das nicht, ich weiß auch wieso, aber ich weiß nicht, wie ich das Problem lösen kann.
Hoffentlich kann mir hier jemand helfen.

18.01.2017 - 16:25 Uhr

Okay, also ich versuche es gerade ein wenig zu verstehen.

In der untersten Schicht habe ich es nun wie folgt abgeändert:


 public string[] ReadTextureFromXml()
        {
            XDocument textures = XDocument.Load(@"C:\Users\Chris\Documents\Visual Studio 2015\Projects\Minecraft Customizer\Minecraft Customizer\textures\textures.xml");

            List<string> textureList = new List<string>();

            foreach (var texture in textures.Descendants("texture"))
            {
                textureList.Add(texture.Element("name").Value);
            }
            string[] array = textureList.ToArray();
            return array;
 
        }

Dort bekomme ich keinen Fehler und ich hoffe, dass das soweit richtig ist (natürlich werden, wenn es funktioniert noch die anderen Elemente hinzugefügt)

In der Logik schicht nun:


public string[] test()
        {
            Textures t = new Textures();
            string[] textures = t.ReadTextureFromXml();
            return textures;
        }

Wie du es meintest. Auch hier soweit keine Fehlermeldung.

Mein Problem liegt nun darin, dass array in die Presentation Schicht auszugeben.
Habe dort jetzt nur:


TexturesOut hXML = new TexturesOut();
            hXML.test();

stehen. Habe Dinge probiert wie hXML.test().XXXXXX
Also versucht dort, wo das XXXX steht irgendwas zu finden was mein array ausgibt ( als Beispiel textures[0] aus der TexturesOut klasse )

Edit:
Habe es wie folgt hinbekommen:


TexturesOut hXML = new TexturesOut();
            string[] myarr = hXML.test().ToArray();


            label2.Text = myarr[0];
            label4.Text = myarr[1];

18.01.2017 - 15:34 Uhr

Guten Tag,

ich habe mir den 3 Schichten Artikel zu herzen genommen und möchte dies nun ausprobieren.

In meiner Data Schicht hole ich Die Informationen aus der XML Datei und packe Sie in ein Array:


public string[] ReadTextureFromXml(string name, string description, string category, string status, string path)
        {
            XDocument textures = XDocument.Load(@"C:\Users\Chris\Documents\Visual Studio 2015\Projects\Customizer\Customizer\textures\textures.xml");

            string[] xmlArray;

            foreach (var texture in textures.Descendants("texture"))
            {
                name = texture.Element("name").Value;
                description = texture.Element("description").Value;
                category = texture.Element("category").Value;
                status = texture.Element("status").Value;
                path = texture.Element("path").Value;

                xmlArray = new string[] { name, description, category, status, path };
            }
            return xmlArray;
 
        }

Allerdings habe ich das Problem, dass der das Array nicht wirklich zurück gibt.
Als Fehlermeldung bekomme ich:> Fehlermeldung:

Use of unassigned local variable 'xmlArray'

Aber das Array ist doch gar nicht Lokal deklariert ?

Anschließend übergebe ich das ganze an meine Logik schicht:


public void test()
        {
            Textures t = new Textures();
            t.ReadTextureFromXml();
        }

Was noch nicht funktioniert, da ich keine Parameter übergebe.

Und lass es in meiner Presentation anzeigen:


TexturesOut hXML = new TexturesOut();
            hXML.test();

Die 1. Frage ist, wie übergebe ich die XML Daten als Array an die anderen Schichten? (Ich dachte mir da, dass es mit solch Rückgabewerten funktionieren könnte)

Und die 2. Frage ist, ist der Grundgedanke, was die Schichten angeht so richtig?
(Also ist es richtig, dass das Lesen aus der XML in der Data Schicht ist, Das "verarbeiten" in der Logik schicht und die Ausgabe in der Presentation Schicht ist).

17.01.2017 - 14:09 Uhr

Alles klar, weil es wird im Buch geschrieben, dass man mit private eine Variable "verstecken" bzw. von außen nicht sichtbar gemacht werden kann.
Und mit diesen Eigenschaftsmethoden "umgeht" man das ganze doch ein wenig.

Da hab ich mir eben die Frage gestellt, ob das bei MySql Verbindungen auch sicher ist.

Wann genau sollte man diese Eigenschaftsmethoden zum Beispiel anwenden?

17.01.2017 - 13:58 Uhr

Guten Tag,
ich wollte mal fragen, in welchen Situationen man Eigenschaftsmethoden so benutzen soll.

Sollte man diese immer verwenden (bei allen Variablen etc) ?
Sind die sicher genug, um bspw. eine MySql Verbindung sicher von außen zu verstecken?

Als Beispiel habe ich (aus dem Buche Visual CSharp 2015 von Rheinwerk)


private int _Radius;

public int Radius
{
   get { return _Radius; }
   set
   {
       if(value >= 0)
           _Radius = value;
       else
           Console.WriteLine("Negativer Wert");
    }
}
12.01.2017 - 13:37 Uhr

Das heißt, ich soll jetzt das Programm einfach links liegen lassen, meinem Chef sagen "ja ich möchte gerne lernen und kann das Programm nicht weiter machen"

Wie auch immer er darauf reagieren wird.

Und dann jeden Tag das Visual C# 2012 von Andreas Kühnel Buch lesen und mir die Grundlagen beibringen.

So würde ich das jetzt machen wollen. Nur wenn ich das Buch jetzt durchgehe, weiß ich evtl. am ende des Buches nicht mehr, wie es am Anfang des Buches war, weil ich alles schnell durchgegangen bin, da ich das Ziel vor Augen habe schnell wieder am Programm arbeiten zu können um meinem Chef Ergebnisse meines daseins zu geben.

12.01.2017 - 13:30 Uhr

Naja er kann die Kunden dann einfach nur in eine Liste eintragen und halt sehen "ah der hat noch einen Auftrag offen, hätte ich doch fast vergessen".

Auftrag fertig:
"Ah, da ist ja der Kunde mal schauen wie ist die telefonnummer, ah da ist sie, mal eben anrufen um bescheid zu geben, dass der PC wieder abgeholt werden kann".

Mehr ist es auch nicht.
Das programm ist nicht total wichtig sage ich mal und wenn das Programm kaputt geht ist die Firma dahin. Bisher macht er das alles in Excel.

12.01.2017 - 13:26 Uhr

Weil mein Chef Ergebnisorientiert ist.
Ich bin jetzt zum 3. mal hier. Es ist ein kleiner PC Laden wo man halt PCs reparieren lassen kann und mein Chef ist ausgebildeter Systemsintegrator. Das heißt, von Programmierung an sich kann er mir nicht helfen. Das heißt, ich muss mir alles selber beibringen.

Aber was bringe ich ihm, wenn ich hier sitze und erstmal Bücher lese.
In dem Zeitraum wo ich für mich lerne, bringe ich ihm absolut gar nichts.

In den ersten beiden Praktikas habe ich PHP/HTML gemacht (wo ich mittlerweile das meiste vergessen habe, da nach praktikum nie benutzt worden)

Das heißt, die ersten beiden praktikas waren schonmal totale Zeitverschwendung, denn ich will ja Programmierer werden und kein Webdesigner.

In diesem Praktikum (start vor 1 Woche) habe ich ihn extra gefragt ob ich denn C# lernen kann, das hilft mir weiter, denn genau als das soll ich ja ausgebildet werden.

In dem Punkt habe ich sag ich mal einen Fortschritt gemacht.

Nun soll ich ihn ein programm schreiben, womit er Kunden verwalten kann. Also kunden hinzufügen, löschen bearbeiten, Aufträge erstellen, Rechnungen erstellen und drucken.
Das ganze mit den Spalten aus den Datenbank ziehen ist eben dazu da, falls er sag ich mal noch eine Spalte für Fax und Telefon sag ich mal hinzuzufügen, wenn er das denn will. Oder andere Spalten hinzuzufügen/löschen.

Demnach schreibe ich also das Programm und sobald ich etwas nicht weiß, was ich aber brauche google ich nach damit das fertig wird.

Wenn ich jetzt anfangen würde mir die Grundlagen etc beizubringen, dann war alles, was ich bisher gemacht habe umsonst, da der Code einfach (sorry) scheiße ist. Aber als Anfänger ist das doch normal.

Er wird keinen Kollegen sagen "füg hier mal etwas hinzu" da hier niemand sonst arbeitet, der Programmieren kann. Mein Chef leitet den Laden alleine. Demnach kann der code noch so gammlig sein, Hauptsache es funktioniert.

Edit:

* Du wirst hier immer weniger Hilfe von Leuten bekommen, wenn sie merken, Du willst gar nichts verstehen, sondern nur eine Lösung für Copy Paste. Die Leute lassen sich hier nicht ausnutzen.

Das Ding ist, dass ich die Leute hier nicht ausnutzen möchte, sondern lediglich nur vorankommen an meinem Problem. Wie zum Beispiel dieses array aus der Methode holen. Ich habe absolut keine Ahnung wie ich das anstellen soll und frage deshalb hier um Hilfe. Natürlich schaue ich vorher IMMER bei anderen Seiten nach und versuche dort die Dinge aus, die ich gefunden habe. Was auch manchmal funktioniert. Nur wenn auch das nicht hilft, dann, erst dann frage ich hier.
Natürlich habe ich das Gefühl, manchen ein wenig auf die Nerven zu gehen, wenn ich hier immer nachfrage. Aber wie schon gesagt, ich will einfach weiterkommen bei Dingen die für mich noch zu hoch sind.