Jetzt habe ich leider wieder ein Problem mit dem Sortieren eines Datums in einer DataGridView.
So habe ich wie von Th69 vorgeschlagen, nun die Daten der Klasse an eine List gebunden
List<Position> list = DB_Abfrage.PositionenListe(iId);
dataGridView1.DataSource = list;
Allerdings konnte ich dann gar nicht sortieren. Ebenso wenn ich Daten als BindingSource gebunden habe.
Bedeutet das, dass ich dann immer eine eigene Sort Methode schreiben muss? Oder habe ich etwas grundsätzlich falsch bei der Datenbindung gemacht?
Als weitere Frage noch: Eigentlich habe ich bisher die Daten mit foreach zeilenweise hinzugefügt, da ich zu jeder Position noch eine separate DB Abfrage mache, um ebenfalls den Wert zu ermitteln. Ist dies grundsätzlich schlecht bzw. sollten diese Daten eigentlich schon in der ersten Klasse ermittelt werden?
Danke euch beiden. Wenn ich es nun richtig verstanden habe, ist Lieferant/Kunde nicht direkt eine Adresse, daher würde ich sagen - nein -.
Und nachdem hustbaer noch erwähnt hat, dass man abgeleitete Klassen nur wohl überlegt und spärlich einsetzen soll, lass ich mal meine Finger davon.
Mechanics schrieb:
giggle schrieb:
so dass es einen "profesionelleren" Eindruck macht.
Zusätzlich zu dem was Th69 geschrieben hat - für mich hört es eigentlich schon auf, wenn ich deutsche Bezeichner sehe.
...
dann schaut es für mich von vornherein amateurhaft aus.
Wenn in einer Firma die Vorgabe entsprechend ist, kannst du das gerne als amateurhaft bezeichnen, ist aber noch immer besser als schlechtes englisch das keiner versteht.
Nee Positionen der Daten kenne ich leider nicht. Hatte gehofft das ich dies an Hand eines Bytes finden und unterscheiden kann. Die Datei stammt aus einem alten DOS Programm (16Bit Anwendung). Ist leider auch kein Programm "von der Stange"!
testomat schrieb:
Ich habe eine Methode, welche ungefähr 100 Parameter übergeben bekommt.
Äh, ja, kann ja mal vorkommen...
Naja, kannst den Aufruf aber mit params wrappen.
Mit einem array, sollte dir das dann nicht mehr schwer fallen, passend umusetzen.
p.s.: "Aufgrund von Performancegründen"
Daran wird sich natürlich nichts ändern. Wer weiss woher das kommt. Sicherlich nicht von den 100 IFs.
Ich weiß, keine direkte Antworten, ABER:
Falls Du nur xlsx-Dateien auslesen musst, nimm EPPlus. Das Auslesen geht schneller und so viel problemfreier.
Ansonsten:
- Wenn Du nur lesen willst, bringt vielleicht eine Einschränkung Vorteile: Mode=Read;
- Mit dem Process Explorer von Sysinternals kannst Du per Find herausfinden, ob tatsächlich kein Zugriff auf der Datei ist.
[Esterik-An]
- Vielleicht ist die Datei aus OLEDB-Sicht Buggy - Schmeiß mal ein paar MB Daten aus der Tabelle und schau mal, ob es dann geht. Wenn ja, ist es leider kein "Format-Fehler".
-Versuch mal, den String in dieser Art aufzubauen:
string connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=\"" + file + "\";Mode=Read;Extended Properties=\"Excel 12.0 Xml;HDR=No;IMEX=1;ImportMixedTypes=Text\"";
[Esoterik-Aus]
Viel Glück noch!
Kannst du mal dein komplettes Projekt hochladen? Es fehlt hier z. B. die Implementierung der InitializeComponent() und ich kann mir anhand des Codes immer noch nicht erklären, wieso der Click-Handler doppelt ausgeführt wird.
Ich habe einige Beispiele versucht zu machen und nachzuvollziehen. Nun habe ich versucht ein eigenes kleines Programm zu machen, welches noch ein paar Fragen für mich aufwirft.
Meine Fragen habe ich direkt im Code kommentiert.
public class Rechnung
{
#region Eigenschaften
// Wann string/String; double/Double ... verwenden?
// string mit = ""; oder mit string.Empty(); initialisieren?
private String _rechnungsnummer;
private DateTime _rechnungsdatum;
private Double _menge;
private Decimal _einzelpreis;
/// <summary>
/// Get und set der Rechnungsnummer
/// </summary>
public String Rechnungsnummer
{
get { return _rechnungsnummer; }
set {
if (value == "")
{
return;
}
_rechungsnummer = value;
}
}
/// <summary>
/// Get und set der Rechungsdatum
/// </summary>
public DateTime Rechungsdatum
{
get { return _rechnungsdatum; }
set {
_rechnungsdatum = value;
}
}
/// <summary>
/// Get und set der Menge
/// </summary>
public Double Menge
{
get { return _menge; }
set {
if (value < 0)
{
return;
}
_menge = value;
}
}
/// <summary>
/// Get und set des Einzeplreis
/// </summary>
public Decimal Einzelpreis
{
get { return _einzelpreis; }
set {
if (value < 0)
{
return;
}
_einzelpreis = value;
}
}
/// <summary>
/// Gesamtpreis einer Position berechnen.
/// </summary>
public Decimal GesamtpreisPosition(double anzahl, decimal einzelpreis)
{
_anzahl = anzahl;
_einzelpreis = einzelpreis;
// Convert so in einer Methode machen?
// Oder besser mit Parse/TryParse?
// Wie kann man das sonst lösen, wenn die Variablen unterschiedliche Typen sind?
decimal gesamtpreis= Convert.ToDecimal(Convert.ToDecimal(_anzahl) * _einzelpreis);
return gesamtpreis;
}
#endregion
}
// Ausgabe der Daten funktioniert
// Aber ist es "richtig", nur die Methode GesamtpreisPosition(...) dem Objekt rechnung zu übergeben?
// Oder zunächst jedes item an das Objekt binden: rechnung.Menge = item.Menge?
// Oder die Daten an den Konstruktor übergeben?
void RechnungAnzeigen()
{
List<Rechnung> liste = DatenAnzeigen();
int r = 0;
foreach (var item in liste)
{
Rechnung rechnung = new Rechnung();
dataGridView1.Rows.Add();
dataGridView1["Rechnungsnummer", r].Value = item.RechnungsNummer;
dataGridView1["Rechnungsdatum", r].Value = item.Datum.ToShortDateString();
dataGridView1["Menge", r].Value = item.Menge;
dataGridView1["Einzelpreis", r].Value = item.LieferArtikelBezeichnung;
dataGridView1["Gesamtpreis", r].Value = rechnung.GesamtpreisPosition(item.Anzahl, item.Einzelpreis);
r++;
}
}
void RechnungEinlesen()
{
// Wie werden die Daten wieder richtig in eine Liste geschrieben?
foreach (DatagridViewRow dr in dataGridView.Rows)
{
List<Rechnung> liste = new List<Rechnung>();
Rechnung rechnungInListe = new Rechnung();
string col1 = dr.Cells["Rechnungsnummer"].Value.ToString();
rechnungInListe.Rechnungsnummer = col1;
...
liste.Add(rechnungInListe);
}
}
Ich habe eine mögliche Lösung... wenn ich Dispatcher.CurrentDispatcher.Invoke statt ProgressBar.Dispatcher.Invoke nehme um den Wert der ProgressBar hoch zu zählen, dann funktioniert es wie gewünscht. Keine Ahnung warum und ob das jetzt der wirklich gute Weg ist, aber für den Moment reicht mir das ;).
Ich habe gerade diesen Beitrag gefunden, da ich das selbe Problem habe. Nach dem Hinweis von inflames2k wie denn der Standard-Eintrag aussieht, habe ich bei mir nachgeschaut. Ich rufe die Daten für die ComboBoxColumn aus der Datenbank ab.
DataGridViewComboBoxColumn cmb = new DataGridViewComboBoxColumn();
cmb.HeaderText = "Mitarbeiter";
cmb.Name = "mitarbeiter";
cmb.MaxDropDownItems = 3;
cmb.DataSource = AuskunftListe(AlleMitarbeiterAnzeigen());
cmb.DisplayMember = "Login";
cmb.ValueMember = "Login";
dgAuskunft.Columns.Add(cmb);
In C++ wäre es ja einfach
Klasse2 *test2 = new Klasse2*[5];
und auch dabei wären die Inhalte des Arrays ja noch undefiniert (außer als globale Variable, denn dann wären die Inhalte auch Nullzeiger - C# hat den Vorteil, daß sie immer mit 'null' initialisiert werden).
Hallo Th69,
das hat mir sehr weitergeholfen! Vielen Dank. An das set und get muss ich mich noch gewöhnen Aber das größte Problem war, dass in meiner Vorstellung mit DateTime birthday birthday schon ein Objekt von DateTime ist, und ich nicht zusätzlich noch birthday= new DateTime(...) machen muss.
Grüße,
Erano1
Hallo zusammen,
ist es möglich, die Spalten eines DataGrids mit unterschiedlichen List-Objekten zu binden? Zur Erklärung:
Ich möchte Parameterdaten in unterschiedlichen Listen verwalten. Die Strukur der Parameter ist bei allen Listen gleich, jedoch können sich die Werte darin unterscheiden. Damit man visuell erkennen kann, wo sich diese Werte unterscheiden, möchte ich ein DataGrid nutzen um die Werte gegeneinander darzustellen. Die erste Spalte soll der Name der Parameter sein, die für alle immer gleich sind. Die weiteren Spalten sollen dann jeweils mit einer der Liste gebunden werden.
Reicht es aus, wenn diese Listen in einer "Hauptklasse" gekapselt sind, und man die ItemsSource des DataGrid auf eine Instanz der Hauptklasse zuweist?
Wie muss man in XAML die Zuweisung auf die entsprechenden Listen vornehmen?
Vielen Dank für eure Hilfe
Gruß
Die Mischung von statischen und nicht-statischen Methoden ist bei dieser Klasse nicht zu empfehlen.
Überlege dir, ob es gleichzeitig mehrere MessageBoxen geben kann (dann darfst du aber keine "static MyMessageBox"-Variable benutzen, da diese ja dann immer wieder überschrieben werden würde!). Ansonsten die ganze Klasse 'static' setzen.
Und das 'Dispose' bei dem Button-Click ist auch keine gute Idee...
Die NullReferenceException findest du wohl mit dem Debugger raus.
Wer ist denn so mutig, sich einen komplett unformatierten code durchzulesen?
Und dann noch sowas:
else
//labi[posI][posJ]=1;
return 0; //weg gesperrt
So wird das nix, mein Lieber. Du gehörst //weg gesperrt.
Hallo
Die Datenquelle einer Combobox weist u.a. "/" und "\" -Zeichen auf.
Wir per Mausklick ein solches Element ausgewählt, wird der Text vollständig (=alle weiteren Zeichen nach dem Slash) angezeigt.
Bei der Auswahl per Tastatur werden die Zeichen nach dem Slash jedoch abgeschnitten.
https://msdn.microsoft.com/de-de/library/system.windows.forms.combobox.autocompletemode.aspx
In der MSDN hab ich nun unter Hinweis gefunden, dass dies abhängig vom Betriebssystem ist.
Bedeutet dies nun, dass ich das Abschneiden der Zeichen bei der Auswahl per Tastatur einfach akzepieren muss, oder kann ich es dennoch ermöglichen, dass alle Zeichen angezeigt werden?