Laden...
Avatar #avatar-4122.png
LaTino myCSharp.de - Experte
Softwareentwickler Thüringen Dabei seit 03.04.2006 3.003 Beiträge
Benutzerbeschreibung

Forenbeiträge von LaTino Ingesamt 3.003 Beiträge

27.07.2016 - 12:01 Uhr

Das sind, äh, alle Postings, die nur aus dem Ursprungsposting bestehen. Also alle Themen ohne Antwort.

So kann man auf einen Blick feststellen, welche Fragen garantiert noch offen sind.

LaTino

27.07.2016 - 07:37 Uhr

Neuinstallation hat das Problem beseitigt. Ist zwar keine wirkliche Lösung, aber funktioniert wenigstens.

LaTino

26.07.2016 - 15:33 Uhr

Moin,

habe ein kleines Problem, das mich in den Wahnsinn treibt - seit ein paar Tagen findet VS keinen Test mehr.

(Anm: Resharper findet zumindest die nunit-Tests, allerdings würde ich ganz gern bei den tests nicht auf Resharper zurückgreifen)

Habe bereits die Vorschläge hier (Cache leeren, temp. Verzeichnisse leeren, etc.) ausprobiert - nichts hilft.

Kennt jemand das Problem und hat eine Lösung?

LaTino
(nur froh, dass VS2015 nicht die Produktiv-IDE ist...)
EDIT: zur Klarifizierung: neue Projektmappe anlegen -> Typ Komponententest -> neuen test anlegen -> Rebuild -> Textexplorer bleibt leer. x64 für's Testprojekt einstellen hilft auch nix.

26.07.2016 - 13:41 Uhr

@Abt: ist hier nicht die Ursache - ohne CSS gehts in Chrome/IE/Edge/FF, mit CSS in keinem. Irgendwas macht die History kaputt. Bzw. ist es vermutlich beabsichgtes Verhalten für dieses spezielle CSS. Wo der Knackpunkt ist - sieht hoffentlich jemand.

LaTino
EDIT: btw. in HTML 5 sind anchor auch für andere Elemente erlaubt. Hauptsache id.

26.07.2016 - 13:31 Uhr

Kann ich nur raten. Ich tippe darauf, dass absolutes Positionieren von Elementen dazu führt, dass der Browser den Anzeigezustand bei Ankern nicht mehr zuordnen kann. Und wenn er das nicht kann, wird er wohl die History auch nicht mehr entsprechend füllen. Was sich wiederum auf die Back/Forward-Funktionalität auswirkt.

Aber wie gesagt, das ist nur geraten und klingt in meinen Ohren halbwegs plausibel.

LaTino

26.07.2016 - 13:13 Uhr

Firefox 47.0.1 tut das auch so. Liegt dein Problem möglicherweise ganz woanders?

LaTino

26.07.2016 - 12:46 Uhr

Bei dem von dir geposteten HTML funktioniert der Back (und auch der Forward-)Button so, wie du es willst. Jedenfalls in Chrome und IE 11.

LaTino

22.07.2016 - 12:29 Uhr

Ja. Im Prinzip ist das aber auch genau, was man "von Hand" machen würde, nur abstrahiert.

LaTino

22.07.2016 - 11:25 Uhr

Kurze Recherche nach deiner Ausnahme ergab, dass mit deiner Formel (die ohne den Backslah vor dem =) alles in Ordnung ist, Excel aber offenbar speichertechnisch überfordert ist. Siehe Adding formula to cell Exception from HRESULT: 0x800A03EC. Mit den Hinweisen dort sowie dem dort verlinkten Beitrag solltest du dein Problem lösen können.

LaTino

22.07.2016 - 09:56 Uhr

Diese beiden Strings sind identisch:


@"=WURZEL(SUMMEWENN(E2:E501; ""<15"";E2:E501))"
"=WURZEL(SUMMEWENN(E2:E501; \"<15\";E2:E501))"

Das String-Literal (gekennzeichnet durch @) wird erst an seinem Ende interpretiert und entsprechend escaped. Doppelt Anführungszeichen werden dann zu &quot;, und das wiederum sollte beim Interpretieren dann als " angenommen werden. Das das funktioniert, zeigt dein Beitrag von oben, wo vier aufeinanderfolgende Anführungszeichen als &quot;&quot; und im Excel dann als "" interpretiert werden. Da der funktioniert - jedenfalls keine Ausnahme erzeugt - gehe ich davon aus, dass die Ursache für die Ausnahme anderswo liegt.

In deinem Fall: wenn du das @ weglässt, schreib einfache Anführungszeichen als &quot;, und wenn du es vor die Zeichenkette stellst, schreib sie als "".

LaTino

22.07.2016 - 09:22 Uhr

Immer noch nicht richtig escaped.


xlWorkSheet.Cells[1, 8] = @"=WURZEL(SUMMEWENN(E2:E501; ""<15"";E2:E501))" ;

LaTino

22.07.2016 - 07:24 Uhr

[Edit] Da es wohl sehr dynamisch ist, sicher das die Objekt auch gezeichnet werden auf der Oberfläche? [/Edit]

Da würde ich das Problem verorten...'ne Menge Controls, die zwar erstellt, aber nirgends der Form hinzugefügt werden.

LaTino

21.07.2016 - 08:21 Uhr

So, wie der Code für mich aussieht, möchte du lediglich in einem Array die Positionen der #-Zeichen, und in einem Array die Positionen der Fragezeichen in deinem labarray speichern.

Falls das so ist, hast du ein paar grundlegende Verständnisprobleme.

1.
Wenn du die Positionen speichern willst, brauchst du nicht zwei Klassen "Hash" und "Fragezeichen", sondern eine Klasse, "Position", die die Information über den zweidimensionalen Index der Fundstelle speichern kann. Von dieser Klasse benötigst du dann zwei Arrays, die du einmal zB "foundHashes" und einmal "foundFragezeichen" [1] nennen kannst.


class Position
{
    public int X { get; }
    public int Y { get; }

    public Position(int a, int b)
    {
        X = a;
        Y = b;
    }
}

static Position[] foundHashes; //Anm. [2]
static Position[] foundFragezeichen;

Die Dimensionen eines zweidimensionalen Arrays solltest du nicht fest vorgeben mit 20, 30, sondern dynamisch rausfinden.

3.
Weil du nicht weisst, wieviele Fragezeichen oder Rauten in deinem Ursprungsarray sind, kannst du auch nicht von vornherein wissen, wie groß foundHashes und foundFragezeichen sein müssen. Das ist das Problem mit Arrays: sie haben eine feste Größe, die man beim Erstellen angeben muss. Arbeite stattdessen mit Listen, und wenn du fertig bist, wandelst du die Listen in Arrays um.

4.
Zu deinen Schleifen wurde ja schon was gesagt. Zusätzlich noch: "else continue" als letzte Zeile in einer Schleife ist so nützlich wie ein Kropf. Kannst du weglassen.


static void Objekteerzeugen(string[,] labarray)
{
    //Dimensionen des Arrays rausfinden, damit wir nicht mehr mit 20, 30 arbeiten müssen
    int arrayWidth = labarray.GetLength(0);
    int arrayHeight = labarray.GetLength(1);

    List<Position> hashes = new List<Position>();
    List<Position> fragezeichen = new List<Position>();

    for (int j = 0; j < arrayHeight; j++)
    {
        for (int i = 0; i != arrayWidth; i++)
        {
            if (labarray[i, j] == "#")
            {
                hashes.Add(new Position(i, j));
            }
            else if (labarray[i, j] == "?")
            {
                fragezeichen.Add(new Position(i, j));
            }
        }
    }

    //jetzt Umwandlung zu Arrays:
    foundHashes = hashes.ToArray();
    foundFragezeichen = fragezeichen.ToArray();
}

Was du eigentlich vorhast, und wieso du überhaupt mit einem zweidimensionalen Stringarray hantierst [3], ist aber immer noch unklar.

LaTino

[1] ich übernehme mal das wilde Mischmasch aus deutsch und englisch. Sollte man aber nicht machen.
[2] static ist auch zu vermeiden, auch das übernehme ich trotzdem einfach mal.

[3] ist mal jemandem aufgefallen, dass fast ausschließlich Anfänger mit mehrdimensionalen Arrays arbeiten, und immer wieder Probleme damit bekommen? Woher kommt der Wunsch, unbedingt mehrere Dimensionen in einem Array zu halten?

21.07.2016 - 07:49 Uhr

Zeig mal die Zeile, wo du den StreamReader erstellst. (Vielleicht auch mal ein Beispiel-CSV, damit man dein Problem nachstellen kann.)

LaTino

21.07.2016 - 07:35 Uhr

Ihr schiesst da beide ein wenig über das Ziel hinaus mit euern Aussagen.

@Palladin: selbstverständlich ändert Code-Behind nicht allein, weil er da ist, das zugrunde liegende UI-Pattern (MVVM). MVVM definiert lediglich drei Schichten und schreibt die Art der Entkopplung dieser Schichten fest. Im Beispiel von Christoph1972 wird keine der beiden Vorgaben verletzt - lediglich die Art der (Einbahn-)Kommunikation zwischen View und VM ist anders. In den meisten Anwendungsfällen kann WPF diese Kommunikation per Databinding erreichen. Die Vorteile liegen auf der Hand - vollständige Austauschbarkeit der Komponenten auch zur Laufzeit, hat Abt ja auch schon erwähnt. Das hätte Christoph1972 ebenfalls im Code-Behind machen können - dann aber mit mehr Aufwand, obwohl WPF selbst schon ein bequemes Databinding anbietet. Wenn man die Vorteile des Databinding-Modellls von WPF haben will - und meistens will man - ist der Aufruf der VM-Methode, so wie er das macht, also suboptimal.

Für die (seltenen) Fälle, wo das Databinding-Modell von WPF nicht weit genug geht - Drag and Drop ist so ein Thema - ist man mehr oder weniger gezwungen, Code-Behind zu schreiben. Möchte man weiterhin austauschbare Komponenten haben, wird's schnell ziemlich abartig. Aber selbst, wenn man die komplette UI-Logik im Code-Behind schreiben würde, ist das immer noch MVVM. Nur eben nicht auf die Art und Weise, wie WPF das forciert, mit den entsprechenden Nachteilen.

Ganz so schwarz-weiß ist das Thema nicht 😉. Wobei die Verwendung von Code-Behind meistens darauf hindeutet, dass man das Databinding von WPF (oder gar die ganze Trennung zwischen V und VM) nicht ganz verstanden hat. Scheint mir hier aber nicht der Fall zu sein.

LaTino

20.07.2016 - 11:10 Uhr
   
byte[] bytes = Encoding.UTF8.GetBytes(_unit);  
return Encoding.ASCII.GetString(bytes);  

ASCII kennt 127 Zeichen, µ ist nicht dabei.

The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)

LaTino

20.07.2016 - 07:27 Uhr

Bei solchen Fragen lohnt ein Blick in den Framework-Quellcode. GetDefaultView initialisiert das DataBinding, im Gegensatz zum einfachen Konstruktor.

LaTino

19.07.2016 - 13:59 Uhr

Welche Referenzen VS benutzt und welche nicht, steht in der Projektdatei. "Woher sie gekommen ist" verstehe ich nicht. Wieso sie da ist? Na, weil du sie eingebunden hast? oO

LaTino

19.07.2016 - 13:54 Uhr

??? Was meinst du mit "woher sie kommt"? Die quelle der Referenz steht in ihren Eigenschaften im Visual Studio.

Außer nuget und GAC gibt's noch ne Menge weitere mögliche Quellen für Bibliotheken. Für die Anwendung ist egal, woher sie kommt, die muss nur wissen, wo sie sie findet, und diese Information hält die Verweisliste in deinem Projekt.

LaTino
EDIT: Screenshot

19.07.2016 - 13:45 Uhr

Warum sollten statische Methoden nicht ordentlich testbar sein?
Kann ich nicht ganz nachvollziehen.
Wenn ich meine Methoden debugge, spielt es keine Rolle ob static oder nicht.
Oder beziehst du dich auf einen bestimmten Kontext?

Wenn ich antworten darf:

Lets do a mental exercise. Suppose your application has nothing but static methods. (Yes, code like that is possible to write, it is called procedural programming.) Now imagine the call graph of that application. If you try to execute a leaf method, you will have no issue setting up its state, and asserting all of the corner cases. The reason is that a leaf method makes no further calls. As you move further away from the leaves and closer to the root main() method it will be harder and harder to set up the state in your test and harder to assert things. Many things will become impossible to assert. Your tests will get progressively larger. Once you reach the main() method you no longer have a unit-test (as your unit is the whole application) you now have a scenario test. Imagine that the application you are trying to test is a word processor. There is not much you can assert from the main method.

(http://misko.hevery.com/2008/12/15/static-methods-are-death-to-testability/)

LaTino

18.07.2016 - 17:52 Uhr

Hey,

sag wieso bist du im App.xaml??

Weil er das Template als Resource im Applikationskontext erstellt hat. Ist relativ normal 😃.

LaTino

18.07.2016 - 16:36 Uhr

MVC/MVP ist bei WinForms wesentlich besser geeignet. Das ist aber eine Mülleimer-Diskussion, weil, wenn ich nicht völlig auf dem Holzweg bin, der TE eine XML-Datei in ein DataSet klopft und also gar nicht wirklich mit Objekten arbeitet. Selbst die Sache mit dem Proxyobjekt geht so nicht wirklich gut. Insofern ist wahrscheinlich toms3n am nahesten an einer praktikablen Lösung, i.e., Datenquelle von Hand anpassen.

LaTino

18.07.2016 - 16:06 Uhr

MVVM wird in deinem WinForms-Szenario schwierig sauber aufzuziehen sein. Du kannst ein Proxy-Objekt benutzen, um zusätzliche Eigenschaften an die Ursprungsobjekte zu pappen.

LaTino

15.07.2016 - 13:03 Uhr

myTextBox.DataBindings.Add("Text", myDataRow, "Attributname");

Siehst du, das ist der Grund, wieso hier viele glauben, dass du dich gar nicht damit beschäftigt hast.

LaTino
edit, @ErfinderDesRades, ja, ist nicht perfekt, aber seine Anforderungen kann man untypisiert abbilden - ein dgv gehörte nicht dazu. Zum Binden an zwei Comboboxen und eine TextBox reicht es allemal, in beide Richtungen. Ich hätte ein untypisiertes DataSet auch nicht vorgeschlagen, aber für das, was er vorhat, ist es die Alternative mit der flachsten Lernkurve.

15.07.2016 - 12:43 Uhr

Ich bin mir nicht sicher, was ErfinderDesRades da falsch verstanden hat, ehrlich gesagt. Du kannst das DataSet laden, ändern, wieder speichern. Und ja, das ist ein DataSet, das heisst nicht nur so 😉.

LaTino

15.07.2016 - 12:36 Uhr

Du arbeitest doch mit DataSet, nein? Was willst du dann mit Linq to Xml? Entweder-Oder.


//DataSet
DataRow result = dataSet.Tables["Real"].Select("ScalarVariable_id = 0").First();

//linq to XML
var realElements = XDocument.Load(filename).Root.Descendants("Real"); //Liste aller Real-Knoten

Das DataSet macht aus allen Knoten desselben Typs eine Tabelle. Handelt es sich um Unterknoten, dann wird eine Tabelle des Hauptknotens angelegt, und eine des Unterknotens, und die Tabelle der Unterknoten erhält eine zusätzliche ID, die die Verknüpfung auf den zugehörigen Hauptknoten herstellt.

Bei LinqToXml hat man die Zuordnung für jedes Unterknoten-Element in seiner Parent-Property, ohne ID.

Wenn du DataSet einsetzt, wird die Struktur des XML in "flachen" Tabellen abgebildet, und du musst u.U. mit den angelegten IDs arbeiten. Dafür bekommst du DataBinding gratis, weshalb du das verwenden solltest, wenn du eine WinForms-Oberfläche benutzt.

Wenn du Linq To Xml einsetzt, bleiben die Hierarchien erhalten. Dafür ist das DataBinding umständlicher.

Beide Technologien vermischen geht. Du bekommst dann die Nachteile von beiden, und die Vorteile von keinem.

LaTino

15.07.2016 - 12:13 Uhr

Google-Suche nach "get specific row of datatable", erster Treffer:


DataRow result = dataSet.Tables[5].Select("ScalarVariable_id = 0").First();

LaTino

15.07.2016 - 11:30 Uhr

Deshalb wollte ich am liebsten eine Linq Abfrage haben hierfür ähnlich dieser hier:

  
comboBox_Modelica_Variable.DataSource = Modelica.dataSet.Tables[3];  
comboBox_Modelica_Variable.DisplayMember = "name";  
  

Das ist kein linq, sondern Databinding an ein DataSet. 🤔 Es würde sehr helfen, wenn du dir wenigstens die Grundbegriffe von dem, was du machst, einprägen würdest.

Der Debugger, den du dich anscheinend hartnäckig weigerst, zu benutzen, hätte dir für die Tabellen, die er kennt, das angezeigt, was untem im ersten Bild zu sehen ist. Im zweiten Bild siehst du die Spalten der Tabelle "Real", und dort siehst du auch die Verknüpfung zur ScalarVariable_Id.

Benutz den Debugger! (verdammt nochmal!

LaTino
Edit: @ErfinderDesRades, er benutzt ein DataSet, das füllt für Unterknoten automatisch eine ID aus. Hätte er in <10 Sekunden selbst rausfinden können, wenn er mal die Ratschläge beherzigen würde.

15.07.2016 - 07:40 Uhr

Die einfachste Möglichkeit wäre wohl, an die Bilddatei die fehlende Menge an Null-Bytes anzufügen. Ich hab das gerade mal mit einer beliebigen JPG-Datei ausprobiert.

Du hast Recht - manchmal übersieht man den Wald vor lauter Bäumen. Hätte auch nicht erwartet, dass das jpg danach noch "gültig" ist.


string fileName, alteredFileName; //setzen
int expectedSize; //setzen

//funktioniert nur für manche Dateitypen
var original = File.ReadAllBytes(fileName);
var altered = original.Concat(new byte[expectedSize - original.Length]);
File.WriteAllBytes(alteredFileName, altered.ToArray());

LaTino

14.07.2016 - 19:17 Uhr

Hängt vom Dateityp ab. Bei JPEG würde ich im Applicatzion specific Sektor so viele Bytes einfügen, bis die Größe passt - ABER imo ist das Metafeld für die appn-Größe zwei Bytes, dh. pro Appn maximal 64 kB zusätzliche Daten - bei (glaube ich) 16 erlaubten Appn-Sektoren. Das reicht natürlich niemals, um ein 15kb-File auf 6 MB aufzublasen, aber eine andere Möglichkeit sehe ich auch nicht. Das JPEG-Format ist nunmal standardisiert.

Eine Möglichkeit für beliebige Dateitypen würde ich direkt komplett ausschließen, egal, ob du da mit .NET, Fortran oder Assembler rangehst.

LaTino
EDIT: (definitiv die schrägste Frage seit langer Zeit...

14.07.2016 - 08:26 Uhr

https://www.xamarin.com/forms, bisschen runter scrollen bis zu "Which Xamarin approach is best for your app?"

LaTino

13.07.2016 - 12:59 Uhr

icher bin ich nicht, aber angenommen dieses hier:

>

Tickt aber von vorne bis hinten anders als alles, was hier angesprochen wurde - es wird nicht gecastet, und auch mit String-Schlüsseln wird nichts angefangen.

laden, verändern, rückspeichern komplexer Daten, und Databinding - das tutes.

Glaube, das war's. Die Sache ist, dass der Focus des Threads weg ging vom reinen XML-Editieren (weil der Anwendungsfall ganz anders war, als zuerst gedacht) und in diesem Fall das Arbeiten mit DataSets deutlich schneller zu entwickeln und sicherer ist (glaube ich).

Weil das Tut sind 3 Artikel, und die Erklärungen sind am Beispiel vb.net (für c# ebenso gültig) - da winkt man als c#-ler vlt. schnell ab, auch weil nicht wissend, was man dafür bekommt 😉

Na, ist doch völlig klar: Pickel! Pickel kriegt man! 😁

LaTino

13.07.2016 - 12:35 Uhr

Ich weiß nicht. - Auf der Suche nach Guidelines für höhere .NET Versionen taucht der Punkt irgendwie nicht mehr mit auf.

Nur noch implizit, das ist wahr.

 DO name classes and structs with nouns or noun phrases, using PascalCasing. (hier)

Und PascalCase kennt nunmal keine underscores. Nicht, dass MS sich selbst überall dran halten würde, (subjektiv) hässlich bleibt's 😉.

LaTino

12.07.2016 - 16:34 Uhr

Ob das wirklich richtiger ist halte ich für Fragwürdig.
IMHO hat eine Initialisierung in einem Property nix verloren.

Autsch. Genau das war einer der Gründe für das Einführen von Properties, lazy initialization zu vereinfachen.

Und übrigens:

Do not use the underscore character (_).

(MSDN)

LaTino

12.07.2016 - 16:25 Uhr

Ich habe nicht das Gefühl, dass du irgendwie versuchst, mit den Datenstrukturen, die du hast, zu arbeiten. Stattdessen baust du dir immer und immer wieder irgendwelche Arrays von Zeichenketten.


comboBox2.DataSource = dataSet.Tables[3].Columns.Cast<DataColumn>().ToList();
comboBox2.DisplayMember = "ColumnName";

So hält die Combobox als Einträge nicht etwa die einzelnen Zeichenketten der Spaltennamen, sondern jeweils das komplette Objekt, das für eine Spalte steht. C# ist eine objektorientierte Programmiersprache, da macht es irgendwie Sinn, auch mit Objekten zu arbeiten, nicht?

LaTino
EDIT: ich klink mich an der Stelle aus. Es ist frustrierend, mit einer Wand zu reden, zudem ist mein Geduldsfaden heute auch nicht sonderlich lang.

12.07.2016 - 13:08 Uhr

Es ist nur eine Tabelle, nämlich Nummer 4 (index 3) im DataSet mit dem schönen Namen ScalarVariable. Die in ihr enthaltenen DataRows sind die Datenquelle für die erste Combobox.

Die in ihr enthaltenen Spalten sind die Datenquelle für die zweite Combobox. (das Dataset hat einfach aus allen Knoten eine Tabelle gemacht, ein Knoten pro Zeile, eine Spalte pro Attribut)

Die Datenquelle für die Textbox ist:

  • in erster Combobox ausgewählte Zeile
  • von dieser Zeile der Wert, der in der Spalte steht, die in der zweiten Combobox ausgewählt ist.

Das sind aber Sachen, die du sofort gesehen hättest, wenn du das getan hättest, was ich dir gesagt habe:

breakpoint auf die Zeile nach dem ReadXml, und dann das Dataset mal etwas durchstöbern.

Der Debugger ist nicht nur zur Fehlersuche brauchbar, sondern auch sonst ein ziemlich nützliches Werkzeug, das man kennen & nutzen sollte. Ist aber eine andere Baustelle.

Zur Realisierung braucht es so wenig Code, dass du dir den einfach mal selber erarbeiten musst. Alternativ postet jemand eben die 10 Zeilen, aber ehrlich gesagt habe ich keine Motivation, dir Arbeit und Lerneffekt abzunehmen.

LaTino
EDIT: Bildanhang zur Motivation 8)

12.07.2016 - 11:11 Uhr

Musst mal ein bisschen im Forum suchen, ErfinderDesRades verlinkt immer mal ein paar seiner Tutorials zum Thema Databinding/DataSet/Xml. Vielleicht liest er das auch und weiss, welches ich meine 😃. "onClick" irgendwas setzen ist aber auch schon wieder kein Databinding ((du bist auf Gedeih und Verderb darauf aus, dir das Leben schwer zu machen, oder?)

Zu deiner Frage...breakpoint auf die Zeile nach dem ReadXml, und dann das Dataset mal etwas durchstöbern. Sollte viele Fragen beantworten.

LaTino

12.07.2016 - 10:18 Uhr

Ich möchte eine Applikation schreiben, welche das bereits bestehende XML einliest und dem Benutzer die entsprechenden Parameter in einem Dropdown zur Auswahl anbietet.

Anschließend soll der Benutzer deren Werte verändern können um anschließend die Simulation mit veränderten Parametern durchführen zu können.

Soweit, so gut.

Da die Formatierung nicht immer identisch ist (mal mehr oder weniger Parameter zur Verfügung stehen), macht es wenig Sinn mit hardgecodeten Attributnamen zu arbeiten.

Das hat nur leider nicht wirklich viel mit dem Absatz oben zu tun. XML kannst du direkt an Steuerelemente binden. Oder du lädst dein XML in ein DataSet und bindest das an Steuerelemente (ist bequemer, weil genau dafür entworfen). In keinem Fall wäre der richtige Weg, das XML von Hand auseinander zu frickeln (erst recht nicht so, wie du dir das überlegt hast).


//untypisiertes DataSet, angelegt über die Toolbox im Designer.
using (XmlReader xmlFile = XmlReader.Create(fileName, new XmlReaderSettings()))
{
    dataSet = new DataSet();
    dataSet.ReadXml(xmlFile);
    comboBox1.DataSource = dataSet.Tables[3];
    comboBox1.DisplayMember = "name"; //nur, damit man in der Cobobox auch was hat, was man lesen kann
}

Binde die SelectedItem-Eigenschaft der Combobox und die Text-Eigenschaften deiner Edit-Controls entsprechend auch an das DataSet/die DataTable, und du bist fertig.

Oder natürlich du behandelst das XML weiter wie eine Textdatei.

LaTino

11.07.2016 - 20:07 Uhr

Das ist zuallererst, genauso wie bei deinem Versuch oben, eine schlechte Idee. Denn XML muss die Reihenfolge der Elemente nicht zwingend einhalten - genau dafür werden Knoten in XML benannt oder mit Index-Attributen (wie "name" in deinem XML) versehen. Sich auf die Reihenfolge zu verlassen ist eine "wird schon gut gehen"-Einstellung - wenn's schief geht, merkt man das leider nicht sofort, sondern erst, wenn es viel zu spät ist. Von daher: lass es. XML strukturiert dir deine Daten, wirf diese Struktur bitte nicht völlig planlos einfach weg.

Ich kann dich natürlich nicht davon abhalten, aber wenn du dir einen Finger abschneiden willst, erwarte nicht, dass ich dir das Messer reiche. 5 Minuten Beschäftigung mit Linq, und du kannst dir die Frage aber selber beantworten 😉.

LaTino

11.07.2016 - 16:41 Uhr

Nimm's mir nicht krumm, aber Linq To Xml (XDocument) so verwendet zu sehen, verursacht beinahe körperliche Schmerzen. Das ist wirklich, wirklich übel.


var allAttributes = XDocument
    .Load(InputFileName)
    .Root
    .Descendants("ScalarVariable")
    .ToDictionary(p => p.Attribute("name").Value, p => p.Attributes().ToList());

allAttributes["inductor1.i"][1].Value = "test";

Wenn es denn mit einer Liste von Attributen sein soll. Besser wäre die Deserialisierung in ein komplettes Objekt.

LaTino
EDIT: die linq-Anweisung der Übersichtlichkeit halber mal auf mehrere Zeilen gestreckt.

08.07.2016 - 10:23 Uhr

Und wenn Du zufällig noch einen Tipp hast, wie man das zeichnen von komplexen Daten irgendwie übersichtlich gestalten kann, wäre ich darüber auch froh 😄 Wenn man so einiges beachten muss und für zig Sonderfälle irgendwas anders zeichnet, wird der Code leider schnell recht umfangreich und unübersichtlich 😕

Strategie sollte dir helfen, deine verschiedenen Zeichen-Algorithmen zu organisieren.

LaTino

07.07.2016 - 14:52 Uhr

Meine Lösung arbeitet mit vieren, Abt. Zwei Gleichungen mit vier Unbekannten => eine Gleichung mit dreien.

LaTino
EDIT: habs zur Verdeutlichung nochmal in die Ausgabe mit reingepackt.
Beschränkt man die mittlere Schleife auf b < 711-a, und die innere auf c < 711-a-b, und macht man ein continue für % a und %b != 0, dann ist die Laufzeit übrigens im selben Bereich.

Ich bestehe aber darauf, dass das eine Matheaufgabe ist, und keine Programmieraufgabe. Das Problem analytisch komplett lösen ist wesentlich interessanter als paar blöde Schleifen zu durchlaufen.

EDIT 2: analytische Lösung, und das ist mal echt abgefahren 😃

07.07.2016 - 14:47 Uhr

Das hat weniger mit Programmieren, und mehr mit simpler Mathe zu tun.

Zu deinen Fragen:

  1. wenn man die Beträge als Cent versteht, muss man jeden Betrag mit 100 multiplizieren.
    Ist ein Betrag 1,23€ und der andere 2,50€, ist ihr Produkt 3,075 €². Arbeitet man mit Cent, ist das also 123 * 250 = 30750 Cent². Bei vier Faktoren halt mehr nullen.

  2. weil das der letzte Summand ist. Summe soll nach Möglichkeit ja 711 sein.

  3. weil man den umgedrehten Weg geht und Stück für Stück die Kandidaten von 711 abzieht.

Wenn du einen übersichtlicheren, aber langsameren Weg bevorzugst:

a+b+c +d = 711 => d = 711 - (a+b+c)
Eingesetzt in abc*d = 711000000 und normalisiert:

a²bc + ab²c + abc² - 711abc + 711000000 = 0
Daraus dann drei verschachtelte Schleifen ohne Optimierungen wie in deinem Code:


for (int a = 1; a < 711; a++)
{
    for (int b = 1; b < 711; b++)
    {
        for (int c = 1; c < 711; c++)
        {
            var d = a * a * b * c + a * b * b * c + a * b * c * c - 711 * a* b* c + 711000000;
            if (d == 0)
                return string.Format("{0} {1} {2} {3}", a, b, c, 711 - (a+b+c));
        }
    }
}

Ausführungszeit ist immer noch < 0.3 Sekunden, also vertretbar. Und Optimieren geht immer.

LaTino
EDIT: ausprobiert:
meine Lösung: 00:00:00.2535265
deine Lösung: 00:00:00.0024536
Faktor 100. Optimieren lohnt also 😉

07.07.2016 - 07:30 Uhr

Üblicherweise mit einem Mock, etwa wie in How to mock membership provider (konkrete Implementierung hängt davon ab, was du wie testen möchtest).

LaTino

07.07.2016 - 06:47 Uhr

Ein absolutes no-go: async await mit Thread.Sleep. Dafür existiert Task.Delay.

Async void sollte ausschließlich für Eventhandling (UI) benutzt werden (wie th69 auch schrieb). Also, in deinem Code-Gebälk knarzt es noch gewaltig.

LaTino

06.07.2016 - 16:25 Uhr

Ob das jetzt sauber ist, oder nicht, darüber könnte man prima streiten. Wenn du mich fragst: ich halte die Art und Weise, wie MaskedTextbox ihren Inhalt "validiert" (eigentlich: interpretiert/parst), für groben Unfug. Andere sehen vielleicht kein Problem damit, dass eine Exception stillschweigend erwartet UND geschluckt wird. Die Tatsache, dass der Debugger in seiner Standardeinstellung darüber stolpert, würde ich als Argument für meine Sicht der Dinge herhalten lassen 😉.

Das ändert aber nichts an der Tatsache, dass die Vorgehensweise für dieses Control nunmal so ist, wie sie ist. Wenn's arg stört, kann man sich immer noch ein eigenes Control von Textbox ableiten.

Im Normalfall ist man mit den drei Schritten gut bedient:

  • Klasse schreiben mit statische Parse-Methode schreiben
  • MaskedTextBox.ValidationType einstellen
  • TypeValidationCompleted behandeln

Manche Dinge nimmt man besser einfach hin, wenn der Aufwand, sie zu korrigieren, in keinem Verhältnis zum Nutzen steht. Und dem Benutzer wird herzlich egal sein, wie deine TextBox da nun genau funktioniert.

LaTino
PS: der default-Zweig dürfte, wenn ich den Quellcode mal so durchstöbere, in allen üblichen Fällen nicht erreicht werden. Ist nur als FallBack für Unvorhergesehenes gedacht.

06.07.2016 - 14:59 Uhr

Nein, es liegt daran, dass dein Visual Studio bei in deinem Code unbehandelten Ausnahmen anhält. Das ist eine debugger-Einstellung. Ich weiss auch nicht, wo du eine Rückgabe von null siehst oO.

LaTino
EDIT: um's nochmal klar zu sagen, der Code oben von mir ist direkt aus einem funktionierenden Beispiel-WinForms-Projekt. "Geht nicht" lass ich nicht gelten.

06.07.2016 - 13:13 Uhr

Doppelpost, weil das in einem Edit nicht untergehen soll:

  • die Signatur der Parse-Methode sollte object Parse(string value) sein
  • der eingehende String in der Methode wird der komplette String inkl. Platzhalter der MaskedTextBox sein
  • FormatException() funktioniert bei mir wunderbar, wobei ich andere jetzt gar nicht ausprobiert habe

//code-behind des Forms
 public Form1()
{
    InitializeComponent();
    maskedTextBox1.ValidatingType = typeof(IbanString);
}
private void maskedTextBox1_TypeValidationCompleted(object sender, TypeValidationEventArgs e)
{
    var result = e.ReturnValue as IbanString;
    button1.Text = result.Value;
}

//Klasse IbanString
public class IbanString
{
    private string _value;

    public static object Parse(string value)
    {
        if(value.Length != 20) //simpelster vergleich, die maskedtextbox hat 16 zeichen+4 platzhalter
            throw new FormatException("kdhji");
        return new IbanString(value.Replace(" ", ""));
    }

    public IbanString(string value)
    {
        _value = value;
    }

    public string Value => _value.Substring(0,12);
}

LaTino
EDIT: bisschen formatierung