Wie wird beim einfachen Cast, z.B.
SOP = (DateTime)DR["SOP"];
Zahl = (Double)DR["Zahl"];
die
CultureInfo.InvariantCulture
berücksichtigt? Dabei fällt mir auf, dass ich das auch nicht bei einem doppelten Konvertieren wüsste?!?
Verwendetes Datenbanksystem: ADO.net
Hallo Forum,
mich beschäftigt gerade wieder eine Frage: Ich habe ein DataSet mit typisiertem DataTable, das ich in eine Xml schreibe. Diese Xml lese ich zu einem späteren Zeitpunkt wieder ein und ich möchte die Daten in eine List<T> eintragen. Das Ganze funktioniert auch. Leider geht die Typzuordnung verloren. In Summe besteht die DataRow aus 50+ Columns mit unterschiedlichen Datentypen.
Hier das anbgespeckte Beispiel mit nur 2 Columns:
public DataSet ProjektDataSet = new DataSet();
public DataTable ProjekteDataTable = new DataTable();
DataColumn IDNrHaupt = new DataColumn("IDNrHaupt", typeof(Int32));
ProjekteDataTable.Columns.Add(IDNrHaupt);
DataColumn IDNrNeben = new DataColumn("IDNrNeben", typeof(Int32));
ProjekteDataTable.Columns.Add(IDNrNeben);
ProjekteDataTable.TableName = "Projekte";
ProjektDataSet.ReadXml(Anwendungsdaten2, XmlReadMode.ReadSchema);
foreach (DataRow DR in ProjektDataSet.Tables["Projekte"].Rows)
{
Projekte.Add(new ClassProjekt()
{
IDNrHaupt = DR["IDNrHaupt"],
IDNrNeben = Int32.Parse(DR["IDNrNeben"].ToString())
});
}
Warum versteht C# nicht, dass das Feld DR["IDNrHaupt"] ein Int32 ist? Dort wird ein Fehler "Cannot iplicity convert type 'object' to 'int'" ausgegeben. Warum muss ich wie bei IDNrNeben gezeigt, den Weg der doppelten Konvertierung über ToString nach INT32 gehen mit dem Risiko der Missinterpretation von Kommas bei Double Variablen? Wie muss ich meinen Code gestalten, damit die doppelte Konvertierung überflüssig wird?
Danke für Euren Support.
NoSonOfMine
Hallo Community,
habe wieder einmal ein Thema auf das ich keine Antwort finde.
Ich habe ein DataGrid und erzeuge dort in XAML selbst Spalten. In der Spalte "Qualität" können die Zahlen 0,1 uns 2 stehen. Abhängig vom Zellwert färbe ich den Zellhintergrund entsprechend ein.
Nun möchte ich nicht die Zahlen sehen, sondern die Zahlen durch einen roten Kreis in Form einer "Ampel" visualisieren. D.h. 0 = roter Kreis (Ellipse), 1 = gelber Kreis , 2 = grüner Kreis. Wie realisiere ich das in XAML?
Hier mein aktueller Code:
<DataGrid Name="Dtg_MitarbeiterEntwicklungsProjekte" MouseDoubleClick="Dtg_Vorschauen_DoubleClick" AutoGenerateColumns="True">
<DataGrid.Columns>
<DataGridTextColumn Header="ID" Binding="{Binding ID}"/>
<DataGridTextColumn Header="Qualität" Binding="{Binding ProQuali}">
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding ProQuali}" Value="0">
<Setter Property="Background" Value="#FF0000"/>
</DataTrigger>
<DataTrigger Binding="{Binding ProQuali}" Value="1">
<Setter Property="Background" Value="#FFFF00"/>
</DataTrigger>
<DataTrigger Binding="{Binding ProQuali}" Value="2">
<Setter Property="Background" Value="#00FF00"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridCheckBoxColumn Header="Überfällig" Binding="{Binding Ueberfaellig, Mode=OneWay}"/>
<DataGridTextColumn Header="Vertriebler" Binding="{Binding Vertriebler}"/>
<DataGridTextColumn Header="Kunde" Binding="{Binding Kunde}"/>
<DataGridTextColumn Header="Projekt" Binding="{Binding Projekt}"/>
<DataGridTextColumn Header="Fortschritt" Binding="{Binding Fortschritt}"/>
</DataGrid.Columns>
</DataGrid>
Hallo alle zusammen,
einfach cool, wieviel Zeit Ihr in die Lösung meines Problems investiert habt. Ohne Euch wäre ich sicher nicht zu einer funktionierenden Lösung gekommen.
Die Dummy-Spalten-Lösung habe ich konzeptionell verstanden und setze ich in einem anderen Kontext so schon um. Hatte nur nicht daran gedacht, dass es hier auch gehen könnte.
Wahrscheinlich bin ich noch von meinen ersten Programmierversuchen zu Zeiten eines Apple 2 mit Compiler-Pascal verseucht: Bevorzuge eine Lösung dann, wenn die Laufzeit bzw. der Anzahl der Codezeilen am geringsten ist. Und die scheint mir bei meiner manuellen Generierung der Spalten ideal. Werde die Lösung erst einmal so verwenden.
Vielen Dank noch einmal für Euere Unterstützung.
Hallo perlfred,
super lieben Dank für den Support und Deine Lösung inklusive der Erklärung.
Hatte mich jetzt mehrere Tage nicht mehr um das Projekt gekümmert, da ich mit anderen Jahresendspurtthemen meiner eigentlichen beruflichen Tätigkeit mehr als gut eingespannt war.
Das Durchdringen und überarbeiten wird sicherlich ein Teil meines Weihnachtsurlaubs.
Melde mich sicher wieder bei Fragen.
Wünsche Euch allen schon mal eine ruhige und besinnliche Weihnacht.
Hallo und Danke für die tatkräftige Unterstützung.
<DataGrid AutoGenerateColumns="False" />
hat hier geholfen.
Habe mich während dem Einwühlen in die Programmierung an der ein- oder anderen Stelle gefragt was die Entwickler von Microsoft da geraucht haben oder was muss ich rauchen muss, um die Denkstruktur zu verstehen.
Da ich ja nicht alle Spalten rechtsbündig formatiert haben will, habe die Formatierung zwischenzeitlich so gelöst:
Style s = new Style();
s.Setters.Add(new Setter(TextBlock.TextAlignmentProperty, TextAlignment.Right));
for (int j = ProgStartJahr; j <= ProgEndJahr; j++)
{
Spalte = new DataGridTextColumn()
{
Header = j,
Width = 80,
Binding = new Binding(string.Format("[{0}].Volumen", j - ProgStartJahr)),
CellStyle = s
};
Dtg_Umsatzvorschau.Columns.Add(Spalte);
}
Wer kann denn auch erahnen, dass die Textausrichtung in Cellstyle.TextBlock versteckt ist?
Die Formatierung mit Punkten mache ich nun eben früher und übergebe schon fertig formatierte Strings in die DataGridTextColumns.
Habe eine Lösung gefunden. Habe anstatt im XAML den Programmcode ergänzt mit:
Dtg_Umsatzvorschau.ItemsSource = ProjektUmsatzTabelle;
Was mir noch nicht gefällt, ist, dass im DataGrid nun 2x die Spalten stehen: die ersten Spalten (Kunde, Projekt, Vertriebler, [1 .. x]Jahre) sind programmtechnisch erzeugt.
Danach werden allerdings noch einmal die Spalten (Kunde, Projekt, Vertriebler, Collection) angehängt. Kann diese auch im ersten Durchgagn der Erzeugung durch RemoveAt() nicht löschen.
Zusätzlich: wie bekomme ich hier die Daten formatiert?
Spalte = new DataGridTextColumn()
{
Header = j,
Width = 80,
Binding = new Binding(string.Format("[{0}].Volumen", j - ProgStartJahr))
};
Ich möchte 1.000er Punkte setzen und alle Nachkommastellen abschneiden. Zusätzlich den Spalteninhalt rechtsbündig ausrichten. Wenn ich das richtig gelesen habe, muss das alles in die Binding -Zeile rein.
Hallo,
das Thema macht mich echt fertig. Hier sieht man den VB.net + Forms Hobbyprogrammierer, der sich jetzt in C# versucht. Komme mit der Bindung nicht klar. Habe kein MVVM gebastelt, sondern einfach nur ObservableCollections:
public ObservableCollection<JahresTabelle> ProjektUmsatzTabelle = new ObservableCollection<JahresTabelle>();
public class JahresTabelle: ObservableCollection<VolumenDetails>
{
public JahresTabelle(String m_Kunde, String m_Projekt, String m_Vertriebler)
{
Kunde = m_Kunde;
Projekt = m_Projekt;
Vertriebler = m_Vertriebler;
}
public String Kunde { get; set; }
public String Projekt { get; set; }
public String Vertriebler { get; set; }
}
public class VolumenDetails
{
public VolumenDetails(int m_Jahr, double m_Volumen)
{
Jahr = m_Jahr;
Volumen = m_Volumen;
}
public Int32 Jahr { get; private set; }
public Double Volumen { get; private set; }
}
im XAML Dokument habe ich folgende Bindung:
<DataGrid Name="Dtg_Umsatzvorschau" IsReadOnly="True" ItemsSource="{Binding Source=ProjektUmsatzTabelle}"/>
und die Spalten versuche ich so zu befüllen:
foreach (Projekt Pro in ZKUmsatzPro)
{
Pro.QuartaleBerechnen();
JahresTabelle JaTab = new JahresTabelle(Pro.Kundenname, Pro.Projektname, Pro.Vertriebler);
for (int j = ProgStartJahr; j < ProgEndJahr; j++)
{
Double Vol = Pro.QuartalsZahlen.Where(x => x.Jahr == j).Sum(x => x.EntwicklungsU + x.ProduktU);
JaTab.Add(new VolumenDetails(j, Vol));
}
ProjektUmsatzTabelle.Add(JaTab);
var Spalte = new DataGridTextColumn() { Header = "Vertriebler",Binding = new Binding("Vertriebler") };
Dtg_Umsatzvorschau.Columns.Add(Spalte);
Ich sehe die Spaltenüberschriften und eine (nicht in Zusammenhang mit der Zeilenanzahl von ProjektUmsatzTabelle stehenden) Anzahl von Leerzeilen, allerdings ohne Inhalt. Könnt Ihr mir die korrekte Bindung im XAML und bei der Spalte nennen?
Hallo zusammen,
hat etwas gebraucht bis ich dazu gekommen bin den Vorschlag umzusetzen. Dabei habe ich erst gemerkt, warum jbrown das Aussehen nicht nachvollziehen konnte. Mein Programmcode ist massiv mit meiner Beschreibung kollidiert. Habe nun den Code etwas angepasst. Leider bekomme ich das Binding nicht hin. Könnt Ihr mir hier noch einmal auf die Sprünge helfen? Hier der neue Code:
public class JahresTabelle: ObservableCollection<VolumenDetails>
{
public JahresTabelle(String m_Kunde, String m_Projekt, String m_Vertriebler)
{
Kunde = m_Kunde;
Projekt = m_Projekt;
Vertriebler = m_Vertriebler;
}
public String Kunde { get; set; }
public String Projekt { get; set; }
public String Vertriebler { get; set; }
}
public class VolumenDetails
{
public VolumenDetails(int m_Jahr, double m_Volumen)
{
Jahr = m_Jahr;
Volumen = m_Volumen;
}
public Int32 Jahr { get; private set; }
public Double Volumen { get; private set; }
}
und hier der Code zum Erzeugen und (leider Nicht-)Befüllen der Spalten. Wie muss das Binding aussehen? Ach ja, habe die ColumnCollection durch das DataGrid selbst ersetzt. Sollte doch trotzdem gehen?
public List<JahresTabelle> ProjektUmsatzTabelle = new List<JahresTabelle>();
foreach (Projekt Pro in ZKUmsatzPro)
{
JahresTabelle JaTab = new JahresTabelle(Pro.Kundenname, Pro.Projektname, Pro.Vertriebler);
for (int j = ProgStartJahr; j < ProgEndJahr; j++)
{
Double Vol = Pro.QuartalsZahlen.Where(x => x.Jahr == j).Sum(x => x.EntwicklungsU + x.ProduktU);
JaTab.Add(new VolumenDetails(j, Vol));
}
ProjektUmsatzTabelle.Add(JaTab);
}
DataGridTextColumn Spalte;
{
Spalte = new DataGridTextColumn() { Header = "Kunde", Binding = new Binding("ProjektUmsatzTabelle.Kunde") };
Dgd_Umsatzvorschau.Columns.Add(Spalte);
Spalte = new DataGridTextColumn() { Header = "Projekt", Binding = new Binding("ProjektUmsatzTabelle.Projekt") };
Dgd_Umsatzvorschau.Columns.Add(Spalte);
Spalte = new DataGridTextColumn() { Header = "Vertriebler", Binding = new Binding("ProjektUmsatzTabelle.Vertriebler") };
Dgd_Umsatzvorschau.Columns.Add(Spalte);
for (int j = ProgStartJahr; j <= ProgEndJahr; j++)
{
Spalte = new DataGridTextColumn()
{
Header = j,
Binding = new Binding(string.Format("ProjektUmsatzTabelle.[{0}].Volumen", j - ProgStartJahr))
};
Dgd_Umsatzvorschau.Columns.Add(Spalte);
}
}
Viiiiiiiieeeelen Dank
Hallo,
mir ist klar, dass es so nicht funktionieren kann, habe aber keine bessere Idee. Deshalb hier mal der Code.
Irgendwie muss ich eine Structure oder Class mit Properties für die einzelnen Spalten von "Volumen" erstellen. Aber wie?
Ein nachträgliches Anfügen von Spalten macht hier einfach keinen Sinn.
Bin planlos...
Binden:
Dgd_Umsatzvorschau.ItemsSource = ProjektBezeichnungsTabelle;
ProjektBezeichnungsTabelle.Clear();
foreach (Projekt Pro in ZKUmsatzPro)
{
JahresTabelle Tab = new JahresTabelle();
Tab.Kunde = Pro.Kundenname;
Tab.Projekt = Pro.Projektname;
List<Double> Vol = new List<double>();
for (int j = ProgStartJahr; j <= ProgEndJahr; j++)
{
Vol.Add(...Abfrage...);
}
Tab.Volumen = Vol;
ProjektBezeichnungsTabelle.Add(Tab);
}
for (int j = ProgStartJahr; j <= ProgEndJahr; j++)
{
DataGridTextColumn Spalte = new DataGridTextColumn();
Spalte.Header = j.ToString();
Binding SpalteBinding = new Binding(string.Format("ProjektBezeichnungsTabelle.Volumen[{0}]", j - ProgStartJahr));
Spalte.Binding = SpalteBinding;
Dgd_Umsatzvorschau.Columns.Add(Spalte);
}
Leider bin ich zu doof es umzusetzen. Probiere noch rum...
Hallo jbrown,
so wie im 1. Teil Deines Posts:
Spalte Kunde | Spalte Projekt | Volumen[0] | Volumen[1] | Volumen[2] | Volumen[...]
Hoffe so habe ich es verständlicher ausgedrückt.
Gruß und Danke
Hallo Forum,
habe eine Klasse mit folgenden Properties:
public class JahresTabelle
{
public String Kunde { get; set; }
public String Projekt { get; set; }
public List<Double> Volumen;
}
Daraus erzeuge ich eine Liste:
public List<JahresTabelle> UmsatzJahresTabelle = new List<JahresTabelle>();
Wobei Volumen eine undefinierte Anzahl von Elementen (Anzahl Jahre) darstellt. Das kann von 1 bis 40 alles sein. Wichtig: die Anzahl aller Elemente der Liste Volumen sind immer gleich viele, können aber von Prozedurdurchlauf zu Durchlauf variieren. Deshalb brauche ich eine Variabilität in der Darstellung:
Nun möchte ich diese Liste an mein WPF DataGrid binden. Habe allerdings keine Ahnung wie (oder ob das überhaupt) gehen kann.
Vielleicht habe ich auch den falschen Lösungsweg gewählt?
Danke und Gruß
Hallo Abt,
vielen Dank für die superschnelle Antwort. Zur Korrektur meinte vorherigen Beitrags: Ich meinte natürlich eine vierstellige Summe.
Jetzt habe ich die Möglichkeit weitere Wochen in die Programmierung eines Diagramms mit allen Umrechnungen/Skalierungen zu stecken. Nicht umsonst sind die Bibliotheken entsprechend teuer. Werde voraussichtlich für ein gute Darstellung mächtig viel Zeit brauchen. Die habe ich leider nicht zur Verfügung. Die andere Option ist hier aufzugeben - beides wiederstrebt mir massiv.
Bin echt gerade mächtig geknickt. Mal sehen welche Gedanken über Nacht reifen werden...
Gruß und gute Nacht.
Hallo Forum,
habe vor ca. 4 Wochen von VB.net Forms auf C# WPF gewechselt. Inzwischen habe ich lustig programmiert in der Annahme, dass WPF die Weiterentwicklung und Verbesserung von Forms ist.
Nun wollte ich entspannt ein Balkendiagramm einfügen und musste mit Entsetzen feststellen, dass selbst einfache Diagramme nicht verfügbar sind. Ist das wirklich so, dass ich jedes Diagramm selbst zeichnen muss? Das wäre ja ein massiver Rückschritt.
Nach nun mehreren Stunden Recherche bin ich auf keine zufriedenstellende Lösung gestoßen - leider auch nicht hier im Form. Hier finde ich nicht einmal das Thema über die Suche? Wenn ich über Google suche, dann bekomme ich hauptsächlich Links auf ein ehemaliges Freeware-Tool "WPF Toolkit", das inzwischen kommerzialisiert wurde. Da ich das Programm nur zur eigenen Verwendung brauche, möchte ich auch keinen sechsstelligen Betrag ausgeben um eine kommerzielle Library zu kaufen.
Bringt mich zum Verzweifeln. Ich möchte doch mein Programm nicht wieder auf Forms umstricken, speziell da dort der größte Aufwand wieder in der Umgestaltung stecken wird.
Kann mir jemand mit Tipps aus der Patsche helfen?
Danke für Eure Hilfe.
Hallo Abt,
ja, es ist die Version B.
Funktioniert bestimmt, muss ich mir erst einmal genauer anschauen und verstehen, wie ich das bei mir integriere.
1:1 lässt sich das nicht ad hoc übertragen. Bekomme ich aber bestimmt hin.
Vielen Dank schon mal.
Edit: Habe verstanden, dass es sich hierbei um eine (Sorted)List mit Key handelt. Das würde den Teil der IDMaxPaares ersetzen. Vielleicht erwarte ich auch zu viel, aber kann ich nicht direkt in der List<Projekt> sortieren und gruppieren?
Hallo Forum,
bin neu hier und "Hobby"-Programmierer. Das erklärt wahrscheinlich auch warum ich Fachbegriffe ggf. falsch verwende.
Habe aktuell eine "List<Projekt> Projekte = new List<Projekt>()" mit ca. 30 Properties, wobei jedes Projekt durch eine Kombination von 2 Properties eindeutig beschrieben ist.
Die "List<IDmaxPaar> IDmaxSuchprojekte = new List<IDmaxPaar>()"nutze ich als Hilfsliste.
public class Projekt
{
public int IDNrHaupt { get; set; }
public int IDNrNeben { get; set; }
public String blabla { get; set; }
.....
}
public class IDmaxPaar
{
public int IDNrHaupt { get ; set; }
public int IDNrNeben { get ; set; }
}
Dabei kommt für jedes IDNrHaupt die IDNrNeben mehrfach vor. Die IDNrNeben wird im Programmablauf bei bestimmten Aktionen fortlaufend hochgezählt:
Projekt[0]: IDNrHaupt=1, IDNrNeben=1
Projekt[1]: IDNrHaupt=1, IDNrNeben=2
Projekt[2]: IDNrHaupt=1, IDNrNeben=3
Projekt[3]: IDNrHaupt=2, IDNrNeben=1
Projekt[4]: IDNrHaupt=2, IDNrNeben=2
Projekt[5]: IDNrHaupt=3, IDNrNeben=1
Projekt[6]: IDNrHaupt=4, IDNrNeben=1
...
Nun möchte ich aus der List<T> Projekte einen Auszug als List<T> SuchProjekte erstellen, bei dem alle Projekte mit der IDNrHaupt einmalig und jeweils die höchste dazugehörige IDNrNeben eingetragen ist.
Momentan habe ich eine ziemlich unschöne Hilfskonstruktion gebaut, die die Aufgabe löst.
List<int> IndexHaupt = new List<int>();
List<int> IndexNeben = new List<int>();
foreach (Projekt Pro in Projekte) { IndexHaupt.Add(Pro.IDNrHaupt); }
IndexHaupt = IndexHaupt.Distinct().ToList();
List<Projekt> ProjekteSelbeID = new List<Projekt>();
IDmaxSuchprojekte.Clear();
foreach (int i in IndexHaupt)
{
IndexNeben.Clear();
ProjekteSelbeID = Projekte.FindAll(x => x.IDNrHaupt == i).ToList();
foreach (Projekt Pro in ProjekteSelbeID) { IndexNeben.Add(Pro.IDNrNeben); }
IDmaxSuchprojekte.Add(new IDmaxPaar() { IDNrHaupt = i, IDNrNeben = IndexNeben.Max() });
}
foreach (IDmaxPaar IP in IDmaxSuchprojekte)
{
SuchProjekte.Add(Projekte.Find(x => x.IDNrHaupt == IP.IDNrHaupt && x.IDNrNeben == IP.IDNrNeben));
}
Das sollte doch irgendwie mit Linq einfacher gehen. Hatte auf eine Lösung ähnlich der unten stehenden Zeile gehofft:
SuchProjekte = Projekte.FindAll(x => x.IDNrHaupt.Distinct() & x.IDNrNeben.Max()).ToList();
Dass die Zeile natürlich so nicht funktioniert ist mir klar. Aber vielleicht geht's so ähnlich?
Hoffe Ihr könnt mir helfen.
Gruß und vielen Dank.