Hallo,
ich möchte durch einen Jumplist-Button bzw. Jumplist-Aufgabe eine neue Instanz eines Windows Öffnen, ich kann aber mithilfe der JumplistTasks nur Applications aufrufen, und möchte meine Applikation nicht Neustarten. In der MSDN habe ich dazu leider nichts gefunden, Habt ihr irgendwelche Ideen?
Gruß
Alex
Ich habs mir schon fast gedacht. Der Fehler kam weil ich dachte das DateTime.Tick == StopWatch.Tick, und dem ist nicht so.
Na dann bin ich wenigstens gleich schnell 😃) freut mich als C#-"Frischling" auch schon ^^ Ich lebe ja kaum so lange wie du schon programmierst^^ (bin 18 und programmiere ca. 1 Jahr).
Ich ändere allerdings bei jedem Durchlauf den Wert der Variable (test.ChangeVariableValue(0, i + 1) ), wodurch er den Endwert jedes mal neu Berechnet. Ich bin mir nicht sicher, aber macht dein Test das auch? Wenn man den Aufruf nämlich rausnimmt komme ich auch bei ~20-30 ms an(weil ja nur einmal berechnet und danach nur noch das Ergebnis zurückgegeben wird), das wäre aber als Speedtest nicht wirklich sinnvoll.
Ich werde jetzt aber mal einen AST implementieren, so dürfte noch etwas Performance erreicht werden.
Ich nheme mal an der Endeckte Fehler war das du keine "implizite Multiplikation" unterstützt?
Als Ausblick für jene, die es interessiert(Auch im Eingangspost):
=======
Roadmaps
=======
***** Ab hier nur Überlegungen, noch nicht auf wirkliche Sinnhaftigkeit geprüft *****
Hi,
So, ich habe soeben Beta 1 von MathExprParser 0.2 fertig gestellt.
Changelog:
unterstützung von E und pi/Pi/pI/PI für Math.E und Math.PI
neue Klasse Eval
Variablen können impliziet multipliziert werden: 3x = 3*x
(Klammern sollen das in Beta 2 auch beherrschen)
Fehlerbehandlung begonnen(Feinheiten fehlen noch)
EDIT:
Fehler behoben der verursachte das keine Variable am Anfang stehen konnte.
DivideByZeroException implementiert
(Alle Cahnges gelten atm leider nur für Eval, werden (soweit Sinnvoll) aber auch noch im statischen Parser für einfache Formeln integriert).
Eval ist gedacht um Formeln mit Variablen schnell zu parsen.
Die Nutzung ist recht Simpel:
Eval test = new Eval("1x+1", new Variable[] { new Variable('x', 1m) });
decimal MeinErgebnis = test.Resolve();
Wie schon zu sehen erwartet Eval im Regelfall eine Formel als string, und ein Array vom mitgelieferten Typ Variable welcher wiederum einen char (das Formelzeichen) und einen decimal-Wert erwartet. Resolve() löst die Formel komplett auf und gibt das Ergebnis als decimal zurück. Es Scannt falls IsScanned auf false steht, sonst nicht. Wen IsResolved auf true stand(weil bereits Resolved wurde aber sich nichts geändert hat) tut sie auch nichts, man kann das Ergebnis auch über .Result erreichen allerdings ist dies ein Decimal? Welches es am Anfang, sowie nach Änderung der Formel auf null steht.
Es existiert außerdem die Grundfunktion Scan() welche auf ohne Auflösen aufgerufen werden kann. Diese setzt IsScanned natürlich auf true, wenn IsScanned bereits auf true stand tut sie nichts. Wenn man die Werte der Variablen ändern will muss man ChangeVariable() aufrufen und den index(zukünftig anstelle dessen auch das Formelzeichen) und den neuen Wert übergeben.
Die Funktionsweise ähnelt dem des statischen Parsers, aber sofern nur die Variablen geändert werden so werden die Tokens beibehalten d.h. es muss kein ReScanning durchgeführt werden(was 80% der Zeit des normalen parsings beansprucht hat)
Momentan werden nur char.IsLetter==true als Formelzeichen angenommen, man kann also nur maximal 26 Variablen in einer Formel haben, findet ihr das reicht oder sollte ich lieber Unterstützung für Formelwörter ala "GeschwindigkeitDesZuges"( 😁 ) möglich machen(Man könnte solche Formeln ja auch zur Laufzeit und nicht vollständig vom User als Input erstellen)?
Ich habe wieder ein Speedtest-Projekt ängehängt und würde gerne wissen ob bei euch die Zeiten auch bei <500-1000 ms liegen und mein Test richtig ist ⚠. Ich traue mir nämlich gerade selbst nicht, da das für 100.000 Iterationen mit sich ändernder Variable einfach verdammt schnell ist(oder ?( )
Bei Fragen/Anmerkungen oder Verbesserungsvorschlägen gilt wie bisher: Immer her damit.
Gruß
Alex
AFAIK wird sie Sie wird mit in die Datei(eigentlich ne zip, aber .xap) reinkopiert. Kannst du dir auch einfach ansehen wenn du die xap in zip umbenennst und einfach mit winrar oder Konsorten aufmachst.
Gruß
Alex
Es ist doch nur Spaß 😉
Obgleich ich versuchen werde schneller zu bleiben/sein als du, aber wir werden sehen.
Ich würde gerne mal gegen "optimize" testen, wie kann ich es denn anschalten?
Auch wenn meine Todos implementiert sind, wird das Parsings eines Strings wie im Beispiel oben (hoffentlich) nicht sonderlich länger dauern, ich möchte ja die Geschwindigkeit beibehalten und würde nach Möglichkeit die Methoden als Extra-Methoden implementieren, sofern ich das ohne Redundanz hinbekomme. Wir werden sehen.
Schreib-Fehler behoben.
Gruß
Alex
Ahh ok. Ja kommt auch auf die Liste, Danke!
Gruß
Alex
Danke, ja am Compiler habe ich mich orientiert, ich habe neulich (weil ich gerne zum Üben eine ScriptSprache entwicklen möchte) nach "Compiler-Anleitungen" gesucht und bin auf Bernd Marquardt's Nightcast "Ein neuer Compiler in einer Stunde" gestoßen. Davon habe ich mich dann leiten lassen und meinen MatheParser komplett neugeschrieben(ich hatte eine alte Version die String-Basiert, doppelt so lang, halb so schnell und fast nicht erweiterbar war).
An den Variablen werde ich mich definitiv auch mal versuchen. Was meinst du mit dynamische Erweiterung um mehr Operatoren? Das verstehe ich nicht so ganz...
Gruß
Alex
Sowas hatte ich auch schon im Kopf, hatte es dann aber wieder verworfen weil ich es irgendwie nicht so recht hinbekommen wollte. Ich sehe auch gerade warum das so war: Ich habe alle Methoden statisch deklariert(ich füge mal flugs oben noch die Nutzung ein). Deshalb war das nicht so umzusetzen. Ich hab die Redundanz aber im Blick. Danke trotzdem, ich werde mich damit nochmal beschäftigen.
So geht es:
private static Dictionary<char, Operand> operands = new Dictionary<char, Operand> {
{ '+', Operand.Addieren },
{ '-', Operand.Subtrahieren },
{ '*', Operand.Multiplizieren },
{ '/', Operand.Dividieren },
{ '^', Operand.Potenzieren },
{ '(', Operand.OpenBacket },
{ ')', Operand.CloseBracket }
};
static private bool IsOperator(char c)
{
return operands.ContainsKey(c);
}
static private Operand ScanOperator(char c)
{
if (operands.ContainsKey(c))
{
return operands[c];
}
throw new FormatException("Dieser Operand ist nicht bekannt.");
}
Gruß
Alex
Beschreibung:
Ich habe einen relativ leicht erweiterbaren und im Moment noch recht simplen Formelparser für mathematische Formeln geschrieben.
Er unterstützt im Moment folgende Operanden: + | - | * | / | ^ | ( | )
Der Parser ist relativ Syntax-unabhängig soweit man das sagen kann:
Whitespaces werden ignoriert '.' als auch ',' werden für Komma-Zahlen akzeptiert.
Edit:
Nutzung:
using MathExprParser;
Parser.Parse("10.5-3.5+2.5*2.5+(3*4-(-7)*3)");
Die TODO-List für die nächste Zeit beinhaltet folgendes:
Scanner.cs:
namespace MathExprParser
{
public enum Operand
{
Addieren,
Subtrahieren,
Dividieren,
Multiplizieren,
Potenzieren,
OpenBracket,
CloseBracket
}
internal class Scanner
{
private static Dictionary<char, Operand> operands = new Dictionary<char, Operand> {
{ '+', Operand.Addieren },
{ '-', Operand.Subtrahieren },
{ '*', Operand.Multiplizieren },
{ '/', Operand.Dividieren },
{ '^', Operand.Potenzieren },
{ '(', Operand.OpenBracket },
{ ')', Operand.CloseBracket }
};
static internal List<object> Scan(string input)
{
List<object> Tokens = new List<object>();
bool Negotate = false;
if (input.Length < 3)
{
//Werfe ScannerException, String zu kurz.
}
for (int index = 0; index < input.Length; index++)
{
if (Char.IsDigit(input[index]))
{
if (Negotate)
{
Tokens.Add(Double.Parse("-" + ScanNumber(input, ref index)));
Negotate = false;
}
else
{
Tokens.Add(ScanNumber(input, ref index));
}
}
else if (IsOperator(input[index]))
{
if (Tokens.Count > 0)
{
if (Tokens[Tokens.Count - 1] is Operand)
{
Operand LastOp = (Operand)Tokens[Tokens.Count - 1];
if (ScanOperator(input[index]) == Operand.Subtrahieren)
{
Negotate = true;
}
else if (ScanOperator(input[index]) == Operand.OpenBracket || LastOp == Operand.CloseBracket)
{
Tokens.Add(ScanOperator(input[index]));
}
}
else
{
Tokens.Add(ScanOperator(input[index]));
}
}
else
{
if (ScanOperator(input[index]) == Operand.Subtrahieren)
{
Negotate = true;
}
else if (ScanOperator(input[index]) == Operand.OpenBracket)
{
Tokens.Add(Operand.OpenBracket);
}
}
}
}
return Tokens;
}
static private Double ScanNumber(string input, ref int index)
{
string temp = "";
for (int i = index; i < input.Length; i++)
{
if (char.IsDigit(input[i]) || input[i].Equals('.') || input[i].Equals(','))
{
if (input[i].Equals(','))
{
temp += '.';
continue;
}
temp += input[i];
index = i;
}
else
{
break;
}
}
return Double.Parse(temp, System.Globalization.CultureInfo.InvariantCulture);
}
static private bool IsOperator(char c)
{
return operands.ContainsKey(c);
}
static private Operand ScanOperator(char c)
{
if (operands.ContainsKey(c))
{
return operands[c];
}
throw new FormatException("Dieser Operand ist nicht bekannt.");
}
}
}
Parser.cs:
namespace MathExprParser
{
public class Parser
{
public static double Parse(string input)
{
List<object> Tokens = Scanner.Scan(input);
for (int i = 0; i < Tokens.Count; i++)
{
if (Tokens[i] is Operand)
{
Operand Op = (Operand)Tokens[i];
if (Op == Operand.OpenBracket)
{
for (int j = 0; j < Tokens.Count; j++)
{
if (Tokens[j] is Operand)
{
Op = (Operand)Tokens[j];
if (Op == Operand.OpenBracket)
{
i = j;
}
if (Op == Operand.CloseBracket)
{
Tokens[i] = ResolveExpression(Tokens.GetRange(i + 1, j - (i + 1)));
Tokens.RemoveRange(i + 1, j - (i));
i = -1;
break;
}
}
}
}
}
}
return ResolveExpression(Tokens);
}
static internal Double ResolveExpression(List<object> tokens)
{
ResolveExpressionHelper(ref tokens, Operand.Potenzieren);
ResolveExpressionHelper(ref tokens, Operand.Dividieren);
ResolveExpressionHelper(ref tokens, Operand.Multiplizieren);
ResolveExpressionHelper(ref tokens, Operand.Subtrahieren);
ResolveExpressionHelper(ref tokens, Operand.Addieren);
if (tokens.Count != 1)
{
//TODO: ParsingException werfen
}
return Double.Parse(tokens[0].ToString());
}
private static void ResolveExpressionHelper(ref List<object> tokens, Operand OpTarget)
{
for (int i = 0; i < tokens.Count; i++)
{
if (tokens[i] is Operand)
{
Operand Op = (Operand)tokens[i];
if (Op == OpTarget)
{
tokens[i - 1] = ResolveOperand(tokens[i - 1], Op, tokens[i + 1]);
tokens.RemoveRange(i, 2);
i = 0;
}
}
}
}
static private double ResolveOperand(object left, Operand op, object right)
{
switch (op)
{
case Operand.Addieren:
return Double.Parse(left.ToString()) + Double.Parse(right.ToString());
case Operand.Subtrahieren:
return Double.Parse(left.ToString()) - Double.Parse(right.ToString());
case Operand.Dividieren:
return Double.Parse(left.ToString()) / Double.Parse(right.ToString());
case Operand.Multiplizieren:
return Double.Parse(left.ToString()) * Double.Parse(right.ToString());
case Operand.Potenzieren:
return Math.Pow(Double.Parse(left.ToString()), Double.Parse(right.ToString()));
default:
throw new FormatException("Operand nicht auflösbar.");
}
}
}
}
Das sind bisher rund 250 Zeilen.
Zur Performance:
nach einigen schnellen und sicherlich unvollständigen Tests bin ich je nach Länge und Komplexität 10-40% schneller als Th69's Parser 😃)
Verbesserungsvorschläge sowie Ideen für Erweiterungen sind selbstverständlich erwünscht 😉
=======
Roadmaps
=======
***** Ab hier nur Überlegungen, noch nicht auf wirkliche Sinnhaftigkeit geprüft *****
Falls ich etwas wichtiges vergessen habe bitte ich um Nachsicht, es ist mein erstes Snippet 😃
Gruß Alex
P.S.: Im Anhang ist der Parser samt TestProjekt zum ausprobieren und/oder Debuggen.
Schlagwörter: Formelparser, Tokens, Scanner
hast du den Background im Browser via CSS oder via XAML schwarz gefärbt?
Wenn du via CSS vorgegangen bist könntest du überprüfen ob du OOB bist und dann den BG)via XAML) schwarz färben. -> http://silverlight.net/learn/videos/all/out-of-browser-experiences/
Das habe ich, ich habe nur einen Eintrag gefunden der gesagt hat das das gerade besprochen wurde wäre, aber keinen Link darin der darauf verwiesen hätte, möglichweise bin ich zu dumm zum sucher, aber die suche nach goto hat keinen relevanten Treffer ergeben....
Hallo liebes Forum,
ich bin bei Vorbereitungen zu einem Schulvortrag zu C# auf goto gestoßen, Ich persönlich finde goto recht nützlich um bsw. kleinere Rekursionen zu erstellen(Eingaben in Consolen-Apps bsw.) Ich frage mich aber ob goto guter Stil ist bzw. ob es Gute Gründe gibt es nicht zu verwenden - was würdet ihr dazu sagen?
Gruß
Alex
Leider kann ich diese Controls nicht anders Ansprechen, zumindest lässt mich mein Intellisense nicht. Die Methoden an sich sind nicht Sinnlos, nur der Weg auf dem ich auf die Controls zugreife ist sehr unbefriedigend.
das mit MainForm.Active==null war es. Danke.
Könnt ihr mir sagen welchen besseren Weg es gibt auf die 3 Textboxen zuzugreifen?
Gruß
Alex
EDIT:
while(!kopf.abstandZuWand==0)
{
kopf.abstandZuWand -= 10;
}
statische Methoden..... manchmal sieht man den Wald einfach nicht, ich hatte mich schon gewundert warum ich nicht auf die Controls zugreifen kann.
Sorry.
@ Th69
Ich glaube das deine Matheparser schon gut ist, aber es geht ja darum das ich soetwas selber hinbekomme und mich gleichzeitig mit dem Zeichnen unter Forms beschäftige. Im Moment erstmal um 2teres.
Hi,
Ich habe ein kleines Programm geschrieben das ein Koordinaten-System zeichnet und danach beliebige Graphen darauf darstellt. Funzt auch alles ganz wunderbar.
Wenn die Funktion zum Graph geändert wird invalidiere ich die komplette form, da sie nichts anderes beinhaltet.
Zum Problem:
Wenn ich das Fenster minimiere oder in eine andere Anwendung klicke und es dann wieder vorhole zeichnet es meine 3 Textboxn und dahinter in der gesamten Clientarea ein Großes Rotes X. Wie kann ich das verhindern bzw. wo liegt die Ursache dafür?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace DynamicGraph
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
base.OnPaint(e);
PaintEventArgs CoordinateSystemArgs = new PaintEventArgs(e.Graphics, new Rectangle(50, 50, 400, 400));
DrawCoordinateSystem(CoordinateSystemArgs, new Pen(Color.LightSteelBlue), 10);
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
DrawGraph(CoordinateSystemArgs, new Pen(Color.DarkSlateBlue));
}
private static void DrawCoordinateSystem(PaintEventArgs e, Pen pen, Int16 space)
{
pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
Point point1 = new Point();
Point point2 = new Point();
point1.X = e.ClipRectangle.Left; // Links Oben -> Max
point2.X = point1.X + e.ClipRectangle.Width; // Rechts Oben -> Max
for (int i = point1.X; i < point2.X + space; i += space)
{
point1.Y = i;
point2.Y = i;
e.Graphics.DrawLine(pen, point1, point2);
}
point1.Y = e.ClipRectangle.Top; // Links Unten -> Max
point2.Y = point1.Y + e.ClipRectangle.Height; // Rechts Unten -> Max
for (int i = point1.Y; i < point2.Y + space; i += space)
{
point1.X = i;
point2.X = i;
e.Graphics.DrawLine(pen, point1, point2);
}
pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;
//Horizontale Mittel-Linie
point1.X = e.ClipRectangle.Left;
point1.Y = e.ClipRectangle.Height / 2 + e.ClipRectangle.Top;
point2.X = point1.X + e.ClipRectangle.Width;
point2.Y = point1.Y;
e.Graphics.DrawLine(pen, point1, point2);
//Vertikale Mittel-Linie
point1.X = e.ClipRectangle.Left + e.ClipRectangle.Width / 2;
point1.Y = e.ClipRectangle.Top;
point2.X = point1.X;
point2.Y = point1.Y + e.ClipRectangle.Height;
e.Graphics.DrawLine(pen, point1, point2);
}
private void DrawGraph(PaintEventArgs e, Pen pen)
{
Point point1 = new Point();
point1.X = e.ClipRectangle.Left + e.ClipRectangle.Width / 2; //Mitte -> Horizontal
point1.Y = e.ClipRectangle.Top + e.ClipRectangle.Height / 2; //Mitte -> Vertical
for (int i = -40; i < 40; i++)
{
if (DrawGraphHelper(point1, i).Y >= e.ClipRectangle.Y
&& DrawGraphHelper(point1, i).X >= e.ClipRectangle.X
&& DrawGraphHelper(point1, i).Y <= e.ClipRectangle.Height + e.ClipRectangle.Y
&& DrawGraphHelper(point1, i).X <= e.ClipRectangle.Width + e.ClipRectangle.X
&& DrawGraphHelper(point1, i + 1).Y >= e.ClipRectangle.Y
&& DrawGraphHelper(point1, i + 1).X >= e.ClipRectangle.X
&& DrawGraphHelper(point1, i + 1).Y <= e.ClipRectangle.Height + e.ClipRectangle.Y
&& DrawGraphHelper(point1, i + 1).X <= e.ClipRectangle.Width + e.ClipRectangle.X) // Alte Lösung! e.Graphics.Clip nutzen!
{
e.Graphics.DrawLine(pen, DrawGraphHelper(point1, i), DrawGraphHelper(point1, i + 1));
}
}
}
private static Point DrawGraphHelper(Point point1, int i)
{
// x senken = nach links
// x erhöhen = nach rechts
// y senken = nach oben
// y erhöhen = nach unten
point1.X += i;
point1.Y -= (int)(Math.Pow(i, GetNumber()) / GetZoomFaktor() + GetExtension()); // Divisor bestimmt den Zoom.
return point1;
}
private static int GetNumber()
{
foreach (var item in MainForm.ActiveForm.Controls)
{
if (item is TextBox)
{
TextBox box = (TextBox)item;
if (box.Text != "")
{
if (box.Name == "PolynomTextBox")
{
int x;
if (int.TryParse(box.Text, out x))
{
return int.Parse(box.Text);
}
}
}
}
}
return 2;
}
private static int GetExtension()
{
foreach (var item in MainForm.ActiveForm.Controls)
{
if (item is TextBox)
{
TextBox box = (TextBox)item;
if (box.Text != "")
{
if (box.Name == "ExtensionsTextBox")
{
int x;
if (int.TryParse(box.Text, out x))
{
return int.Parse(box.Text);
}
}
}
}
}
return 0;
}
private static int GetZoomFaktor()
{
foreach (var item in MainForm.ActiveForm.Controls)
{
if (item is TextBox)
{
TextBox box = (TextBox)item;
if (box.Text != "")
{
if (box.Name == "ZoomTextBox")
{
int x;
if (int.TryParse(box.Text, out x))
{
return int.Parse(box.Text);
}
}
}
}
}
return 1;
}
private void Polynom_Changed(object sender, EventArgs e)
{
MainForm.ActiveForm.Invalidate();
}
private void MainForm_Activated(object sender, EventArgs e)
{
MainForm.ActiveForm.Invalidate();
}
}
}
Danke!
Das war das was ich gemeint hatte.
Hi,
wenn ich eine Linie von 0;0 nach 100;0 zeichne geht Sie standartmäßig 100px am ganz oberen Rand der ClientArea nach rechts. Ich möchte nun das sie 100px nach Rechts in einem Viereck meiner Wahl geht, also Quasi den Index für die Points ändern(hoffentlich versteht das jmd.) Geht das?
Gruß
Alex
Ok, jetzt wirds mir klar, Danke.
Dennoch hat er ja gar keine "Schülerlizenz", wenn er die ganz normale Express Edition hat. Damit ist das entwickeln kommerzieller Software ja ausdrücklich erlaubt. Trotzdem ist da noch die Gewerbe und Steuersache.
Warum sollte man denn absolute Positionierung vermeiden? = Canvas.Left, .Right, .Top, .Bottom
oder meinst du damit etwas anderes?
Das war das was ich gemeint und oben schon angeregt hatte.
Für ein ganz spezielles Regex sollte es kein Problem sein eine Umsetzung einzurichten.
Wenn nicht mi Try-Error könnte man ja (eingeschränkt) mit vorgefertigten Datensätzen arbeiten: Wenn du [0-9] willst, brauchst du eine Liste: 0,1,2,3,4,5,6,7,8,9 und daraus ziehst du mit Random einen Wert. Damit hast du keinen Error, musst aber deine Patterns sehr genau im Vorhinein Analysieren.
Gruß
Alex
da ist das vorgehen ganz klar:
-Datei schreiben(vllt kann man sogar schon den stream regexen?) bin mit der ganze IO Geschichte in C# nur bedingt vetraut
-Datei auslesen
-regex pattern(schlicht "<br/>")
-und einfach austauschen regex.replace("<br>"); (oder so)
fertig.
versuch es einfach mal durch den Validator zu schicken.
wenn andere Fehler auftreten müsstest du sie ähnlich einfach beheben können.
gruß
Alex
Edit:
Wenn du den doctype auf xhtml 1.0 transitional stellst hast du nur 2 Fehlertypen:
atm inkorrekter doctype(xmlns fehlt)
und deine img brauchen immer ein alt tag. und wenn es nur alt="" ist. das muss noch dazu dann ist die Version vom Server schon valide. Und das einzige was zählt ist der grüne Balken ;D
huhu,
Doch, es war schon zu "nur HTML" so, dass die Elemete auch per abschließendem /> geschlossen werden konnten, genauso wie ein <html></html> natürlich geht. Z.B. <br /> war schon immer so definiert. Das ist ja auch nur eine erlaubte verkürzte Schreibweise. Eigentlich heisst es <br></br>.
Das kann man so nicht ganz stehen lassen: Die verkürzte Schreibweise ist bei HTML 4 nur selten erlaubt. Bei divs sogar komplett invalide bzw. wird falsch ausgewertet(probiers mal aus, das Ergebnis ist sehr lustig.) bei XHTML 1.x ist sie deutlich öfter erlaubt. Zum Beispiel <br>: genau das ist eben nicht der Fall: http://www.w3.org/TR/html4/struct/text.html#edef-BR
Endtag: forbidden(!)
dasselbe Spielchen gilt für bsw. auch für <link> und viele andere. in XHTML ist es hingegen <br/>
hier die XHTML 1 Definition:
zu den Sonderzeichen: just utf-8!
sofern(eigentlich immer) der Server utf-8 unterstützt brauchst du Sonderzeichen nicht mehr(sofern ich mich richtig entsinne). Musst du dann aber natürlich definieren
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
Ich weis nicht ob ein <br> gegenüber einem <br> falsch interpretiert wird (vom Browser) ich meine aber das es nicht so war, es also dennoch funktioniert, wenn dein Kunde(hast du einen Kunden?) aber unbedingt will das du Valide arbeitest und das über eine anwendung generierst könntest du einfach nach dem schreiben die datei wieder einlesen und mit einer regex das / hinzufügen/entfernen brs kommen sowieso eher selten vor. Divs schliest man eigentlich auch nie impliziet(weshalb man es auch nicht darf(eine leere box..)) sonst fällt mir nicht ein wo Probleme auftauchen sollten, aber die lösung wäre eigentlich immer ein recht simples regex.
gruß
Alex
Arbeitest du jetzt mit dem XmlWriter oder dem XmlSerializer? Dein Code scheint da eine Mischung raus zu sein.
Aber wenn du dich davon nicht abbringen lässt:
wie gesagt: ich beschäftige mich gerade zum ersten mal mit dem ganzen Thema und habe noch keine "Anwendung" dafür, sondern nur Testcases aufgestellt und ausprobiert. Wenn man den Writer in verbindung mit dem Serializer nicht so verwendet -> gut zu wissen, bitte zeig mir aber doch wie man es besser macht!
zu der Omit property: auch dazu wäre ein Beispiel sehr schön, ich schaffe es leider nicht die Property mit Effekt zu setzen. Die Deklaration kommt trotzdem.
Immer eine List<Person> serialisieren. Wenn schon eine Datei vorhanden ist, dann diese erst deserialisieren, die neue Person anfügen, wieder in die Datei serialisieren. Dadurch verhinderst Du nicht nur die zusätzliche XMl-Deklaration, sondern erhältst zudem ein valides XML und kannst immer anfügen.
Ich soll also quasi erst die datei auslesen, in Objekte verwandeln, die Datei leeren und dann die neue Anzahl Objekte in die Datei schreiben?
Gruß
Alex
Der XMLWriter schreibt richtige xml dateien, ich würde die Methode von dem Link nutzen:
Damit müsste man recht einfach eine XHTML erstellen können, wie gesagt HTML warscheinlich weniger da tags so geschlosen werden:
<tag />
was HTML nicht unterstützt(meines Wissens). XHTML aber sehr wohl. Ich nehme an man kann nodes nur an ein document anhängen, nicht in den stream. Sieht aber recht einfach aus.
es geht eigentlich mehr um das Prinzip das wenn man eine vorhandene datei erweitern will, ein neuer doctype(kp ob das als doctype durchgeht) angelegt wird, was wiederum beim auslesen Probleme macht.
Das verstehe ich nicht. Meinst du das ich die Datei auslesen, löschen und neu schreiben soll? Das wäre aber böse ineffektiv....
http://www.tsql.de/csharp/csharp_xml_erzeugen.htm könnte hilfreich sein. Damit kannst du exact deine HTML zusammenbauen, du solltest aber XHTML 1.0 als Doctype nutzen. mit html 4.01 wirst nur schlecht weiterkommen(aufgrund der implizieten schliessung vieler tags)
Ich hoffe ich habe beim suchen im Forum nicht einen schon vorhandenen Fred dazu übersehen, ich beschäftige mich im moment mit dem serialisieren von Objekten und habe im Moment das Problem das wenn ich ein Objekt in eine schon vorhandene datei schreiben will folgendes passiert:
Alter code: (nachformatiert von mir)
<?xml version="1.0" encoding="utf-8"?>
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Vorname>Jeff</Vorname>
<Nachname>Price</Nachname>
</Person>
Neuer code: (nachformatiert von mir)
<?xml version="1.0" encoding="utf-8"?>
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Vorname>Jeff</Vorname>
<Nachname>Price</Nachname>
</Person>
<?xml version="1.0" encoding="utf-8"?>
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Vorname>Alexander</Vorname>
<Nachname>Trefz</Nachname>
</Person>
wie kann ich das 2te
<?xml version="1.0" encoding="utf-8"?>
verhindern?
mein Code dazu:
FileStream writestream = new FileStream(@"C:\test.txt", FileMode.Append);
using (XmlWriter writer = XmlWriter.Create(writestream))
{
serializer.Serialize(writer, person);
}
Danke im voraus
Gruß
Alex
P.S.: Ich bin auch für allgemeine Verbesserungsvorschläge zum Code offen 😁
Danke,
man kann fast alles was Guis können auch mit der Console machen :evil: 8) einfach weil die Gui ja auch nichts anderes als eine Oberfläche ist, die Funktionen sind gleich. das müsste ganz gut gehen, seh ich mir gleich mal an.
😁 ja die Erfahrung muss man mal gemacht haben :evil:
Wenn du (oder jmd. anderes der den Fred liest 😄) noch gute Aufgaben in der Preisklasse Primzahlenrechner oder Hangman hast, immer her damit, ich bin immer auf der Suche.
war jetzt ein schlechtes Beispiel, C# ist dahingehend natürlich wirklich einfach, aber nehmen wir einfach mal um es trotzdem zu nutzen das Geschlecht als property der Klasse customer, 1. Idee: String, 2.: Enum, weil typensicher besser, natürlich auch nur wenig mehraufwände 4 zeilen Code zu schreiben aber es gibt natürlich auch bessere Beispiele.
Wir sind uns aber ja dennoch einig: einfacher = besser.
unser Lehrer hat mal in c++ verlangt in einem Text alle ä ü ö durch ae ue oe zu ersetzen was in C++ wirklich nervig ist(2 entgegengesetzt laufende Schleifen sind die Lösung) aber ich habe einfach die ä,ö,ü die ja so nicht eingegeben werden können mit den Asciis eingefügt, das war 1. einfacher und 2. besser aber er fand es wäre "schwieriger" und lies diese Lösung am Anfang nicht zu, ich konnte ihn zwar überreden, aber 12/14 Schülern haben halt ne 5 bekommen weil sie nicht auf die 2 Schleifen gekommen sind und Asciis nicht als erlaubt erachteten.
Lehrer ist nicht so ganz richtig, Ich bin Schüler eine informatiker-Klasse aber der gesamten Klasse in Programmierung weit vorraus(Den Stoff des nächsten jahres hab ich schon intus) und helfe unserem (nicht so genialen Lehrer(VORALLEM bei der Aufgabestellung)). Ich habe aber sogar einen Schüler unserer Klasse der nur bei mir lernt und gute Fortschritte macht, und für den habe ich das Hangman und auch einen schönen Primzahlenrechner gemacht. Uns ist nämlich Freigestellt in C++ oder C# zu programmieren, er unterrichtet aber nur C++ deshalb lernt der Schüler bei mir 😄(er möchte gerne C# lernen und nicht C++ mit dem er nicht gut zurecht kam)
Danke für den Hinweis zu TryCatch, gut zu wissen das man es besser anders löst.
und ich stimme dir ganz klar zu: man sollte eher einfacher Programmieren, ABER natürlich auch auf diverse Dinge achte, z.B. ist es oft einfacher nicht typensicher zu programmieren, dennoch sollte man es tun.
Warum TryCatch unschön ist weis ich nicht genau, Aber ReadLine() bietet wie du selber sagtest Korrekturmögl, da man ja mit Enter bestätigen muss im Gegensatz zu ReadKey()
Kind, ich weis doch das ich mit ner GUI via Eventhandling und co. soetwas sehr einfach realisieren könnte, es geht aber um Schulaufgaben für eine Klasse die das Wort Gui noch nicht mal kennt, demnach suche ich nahch einer Lösung für ConsoleApps, die ich ja nun auch gefunden habe^^
Ich habe jetzt einfach eine rekursive Methode geschrieben, nicht optimal aber funzt wenigstens:
private static Char CharacterInput()
{
Char ActualChar = ' ';
try
{
ActualChar = Convert.ToChar(Console.ReadLine());
}
catch (FormatException)
{
Console.WriteLine();
Console.WriteLine("Bitte geben Sie nur einen Buchstaben ein!");
Console.WriteLine();
CharacterInput();
}
return ActualChar;
}
Ich brauche einen Char, also nur ein Zeichen, kann ich ReadLine in seiner Länge vllt beschränken?
Gut, dann reformuliere ich mal:
Es sollte doch möglich sein einen einzelnen Buchstaben mit Korrekturmöglichkeit auszulesen und dabei keien GUI zu benutzen, oder?
Mit GUI ginge es sicherlich, aber es kann ja nicht sein das man Read() quasi nicht benutzen kann, es muss doch eine "gute"/"elegante" Lösung geben...
Gruß
Alex
Danke das hat geklappt.
Allerdings nur mit
Console.ReadKey().KeyChar;
Fürs Archiv ;D
Leider kann man so nicht seine Eingabe korrigieren, wenn man sich vertippt ist der Character sofort eingegeben. Gibt es nicht vllt doch eine Möglichkeit den Stream einfach zu "trimmen" und die letzten 2 Zeichen zu löschen bzw. den Stream einfach zu leeren?
Beim Console.Read sind eben noch Zeichen vorhanden im Eingabestream oder werden alle nach und eingelesen.
Mfg
Also müsste ich quasi den Stream wieder leeren? Eigentlich tätige ich ja die Eingahe [72][13] im Eingabe-Stream, also "H" und dann Enter warum nimmt er dann das zeichen 3mal?
Hi,
Console.WriteLine("Bitte geben sie einen Buchstaben ein.");
word.CheckChar(Convert.ToChar(Console.Read()));
word.WriteWord();
Console.WriteLine();
Ich habe eine kleine Hangman Klasse geschrieben(word ist eine instanz davon) die mit CheckChar(Char value){} überprüft ob der Buchstabe vorhanden ist und mit WriteWord() den aktuellen Stand ausgibt(bsw: H______ wenn man H bei "Hangman" eingegeben hat).
Das funktioniert alles auch wunderbar, wenn ich aber den Buchstaben mit Console.Read() auslese, wird folgende Ausgabe getätigt:
Bitte geben sie einen Buchstaben ein.
H______
Bitte geben sie einen Buchstaben ein.
H______
Bitte geben sie einen Buchstaben ein.
H______
wenn ich das ganze mit ReadLine() versuche funktioniert die Ausgabe korrekt, also nur einmal.
Woran kann das liegen?
Gruß
Alex
Hi
auch auf das Risiko hin das ich mich damit hochgradig blamiere muss ich doch nochmal nachfragen:
wo liegt der Unterschied zwischen einer class und einem struct?
Ich sehe ihn einfach nicht und habe auch durch die Suche nichts wirklich aufschlussreiches gefunden(warscheinlich bin ich zu doof dafür).
Danke im voraus
Gruß
Alex
IClonable.Clone hatte ich noch nicht implementiert, seh ich mir aber gleich mal an.
Das Problem was du mit new beschreibst tritt bei mir nicht auf:
new public SubCustomer Clone()
{
return new SubCustomer(Vorname, Nachname, Geschlecht, Kontostand, Alter);
}
funktioniert einwandfrei.
oder habe ich dich da missverstanden?
Edit: jetzt hab ich s verstanden, mit der interface-Variante funktioniert es so nicht. die möchte ja auch ein Objekt zurückgeben.
Den thread über das für und wieder habe ich schon gelesen, es geht mir aber im Moment vielmehr darum ob es geht oder nicht, abgesehen davon tendiere ich zu der Meinung das man durchaus ab und an eine Kopie gebrauchen kann.
Edit2: http://blog.norberteder.com/index.php?entry=entry070103-082032
finde ich einen guten Ansatz.
Ich habe auch W7 x64, es stürz bei mir immer ab wenn ich den debugger über den Stop button beende, ansonsten läuft es gut und schnell, selten stürzt es noch aus unerfindlichen gründen ab. Die Probleme mit dem Editor habe ich nicht.(STRG und co funktionieren einwandfrei)
Danke für die schnellen Antworten.
Du solltest dir erstmal Grundlagen über Objekte und Refrenzen aneignen. Dann erübrigt sich die Frage von selbst.
Das versuche ich ja gerade, ich hatte diesen Vorgang nur nich gefunden. Wie immer ist mir aber natürlich 5 minuten nach dem posten noch eine einfach Lösung eingefallen(sofern man die Klasse selber geschrieben hat):
public Customer Clone()
{
Customer customer = new Customer(Vorname, Nachname, Geschlecht, Kontostand);
return customer;
}
einfach der Klasse hinzufügen. Will heissen, eine Funktion die ein neues Objekt mit den vorhanden werten kreiert und zurückgibt. Simpel. Ich weis nicht ob das besonders schnell oder langsahm ist, aber es funktioniert.
gruß
Alex
Edit: Dann mache ich ja quasi dasselbe wie ein Kopierkonstruktor.
Hi,
Ich habe folgendes Problem:
ich habe ein Objekt in einer funktion erstellt und in ein dictionary gespeichert. nun möchte ich in einer anderen funktion das objekt aus dem dictionary herausnehmen und in eine komplett neue variable speicher, es also kopieren. das funktioniert auch aber wenn ich nun die kopie verändere wir auch der wert in dem dictonary verändert - wie kann ich das verhindern?
Customers["Test"].Geschlecht = GeschlechtEnum.Weiblich;
Console.WriteLine(Customers["Test"].Geschlecht); // weiblich
Customer Schnickenfittich = Customers["Test"];
Schnickenfittich.Geschlecht = GeschlechtEnum.Männlich;
Console.WriteLine(Schnickenfittich.Geschlecht); // männlich
Console.WriteLine(Customers["Test"].Geschlecht); // männlich!
Ich bin mir nicht sicher, aber könnte man nicht einfach mithilfe eines styles dafür sorgen das bei einem window keine resize-cursors mehr kommen und dann mit min und maxheight die größe beschränken? das mit min und max geht, aber bei den cursorn bin ich nicht sicher...
mfg
Alex
Hallo,
ich bin auf der Suche nach einer Liste oder einem Array mit dem ich folgendes festlegen kann:
mein Array
{
"meine stelle" : "mein wert",
"meine nächste stelle" : "mein nächster wert",
"meine letzte stelle" : "mein letzter wert"
}
geht das in C#?
Danke im Voraus
Alexander