Guten Abend,
bisher habe ich bei DataGridViews zum Ein-/Ausblenden der Spalten und Anpassen des
HeaderText
immmer folgende Vorgehensweise verwendet
dg.Columns["Id"].Visible = false;
dg.Columns["Name"].Visible = false;
dg.Columns["Vorname"].Visible = false;
dg.Columns["Text"].HeaderText = "Anderer Text";
Nun habe ich gesehen, dass ich das ganze ja über die Attribute in der Klasse steuern kann.
[Browsable(false)]
public int Id { get; set; }
[DisplayName("Anderer Text")]
public string Text { get; set; }
-Steuert man das grundsätzlich über die Klasse?
-Wenn ich eine Eigenschaft
[Browsable(false)]
setzte, gibt es dann bei der tatsächlichen Anzeige der Daten noch die Möglichkeit, es z.B. für eine View anzeigen zu lassen?
-Wird die Vorgehensweise oben überhaupt so eingesetzt?
Danke mal für Eure Tipps! Habe versucht alles entsprechend umzusetzen (100 durch 100m ersetzt, keine Rundun beim Abschlag bzw. erst am Ende runden) - dennoch erhalte ich nicht das, was ich gerne möchte.
public static decimal RabattiertenPreisBerechnen(decimal preis, decimal rabatt)
{
decimal abschlag = preis * (rabatt / 100m);
decimal rabattpreis = preis - abschlag;
decimal d;
//d = Math.Round(rabattpreis, 2, MidpointRounding.AwayFromZero); =>5,67
d = Math.Round(rabattpreis, 2, MidpointRounding.ToEven); =5,67
return d;
}
Den erhofften Wert von 5,7 erhalte ich nur, wenn ich
d = Math.Round(rabattpreis, 1, MidpointRounding.ToEven); =5,67
mit einer Dezimalstelle zurückgebe.
Muss ich das in der Tat so machen, oder runde ich weiter falsch?
Guten Abend,
ich weiß, zu dem Thema gibt es bereits viele Einträge und ich habe auch bereits viel probiert. Leider kommt ich aber nicht auf mein gewünschtes Ergebnis.
Preis: 6,30
Rabatt: 10%
Abschlag: 0,63
Ergebnis: 5,67
Im ersten Beispiel runde ich auf 0,25, ergibt dann 5,75, was passt.
Im zweiten Beispiel runde ich auf 0,5, da erhalte ich immer 5,5. Warum wird hier nicht aufgerundet auf 5,7?
public static decimal RabattiertenPreisBerechnen(decimal preis, decimal rabatt)
{
decimal abschlag = Math.Round(preis * (rabatt / 100), 2, MidpointRounding.ToEven);
decimal rabattpreis = preis - abschlag;
// Um auf 0,25 zu runden, funktioniert folgende Zeile zu meinem Beispiel = 5,75.
//rabattpreis = Math.Round(rabattpreis * 4, MidpointRounding.ToEven) / 4;
// Um auf 0,5 zu runden => erhalte ich in beiden Fällen 5,5.
rabattpreis = Math.Round(rabattpreis * 2, MidpointRounding.ToEven) / 2;
//rabattpreis = Math.Round(rabattpreis * 2, MidpointRounding.AwayFromZero) / 2;
//rabattpreis = Math.Round(rabattpreis, MidpointRounding.AwayFromZero); => 5,67
//rabattpreis = Math.Round(rabattpreis, MidpointRounding.ToEven); => 6
return rabattpreis;
}
Die beiden DataTable
erstelle ich manuell und weise dabei den Datentyp zu.
Die Spalten der DataGridView
sind dann autogeneriert.
Das ganze betrifft auch nur 2 Spalten, die restlichen Spalten (also Werte) werden angezeigt.
Hallo,
folgende Ausgangssituation:
dt1.Merge(dt2);
//dvOverview = new DataView(dt1);
//dg.DataSource = dvOverview;
dg.DataSource = dt1;
Ich habe zwei DataTables welche ich über Merge zusammen führe.
Binde ich diese Daten wie oben direkt an eine DataGridView werden in allen Spalten Werte angezeigt.
Verwende ich zum Anzeigen allerdings eine DataView (wie oben auskommentiert) enthalten manche Spalten keine Werte mehr.
Was kann die Ursache sein? Bzw. in welche Richtung muss ich suchen, um das Problem zu lösen?
DataView wäre mir von der Anbindung lieber, da ich dann einfacher eine Filterfunktion umsetzen kann.
Danke für Deine Antwort. So etwas in die Richtung habe ich befürchtet.
Das Problem ist, dass das Projekt mit .NET 4.0 und VS2010 erstellt wurde und auch so läuft.
Darin wurde auch das Entity Framework verwendet.
Aber einfach auf eine neuere VS Version upgraden geht ja leider nicht so einfach. Daher
war eine Überlegung, die Datenbankabfragen nicht mehr über das EF zu machen, sondern direkt
per SQL. Dat hat auch bei Abfragen zu einer deutichen Verbesserung der Performance geführt.
So könnte dann auch einfacher auf eine neuere Version des Visual Studio umgestellt werden.
Hab ich sonst noch eine Möglichkeit, unter meinen gegeben Umständen ein Objekt <T>
und/oder eine List<T> zurückgeben zu lassen?
Hallo,
ich versuche eine SQL Abfrage als List<T> zurückzugeben.
private void button1_Click(object sender, EventArgs e)
{
List<Produkte> a = null;
MySqlConnection conn = new MySqlConnection(connection);
MySqlCommand cmd = new MySqlCommand(query, conn);
using (conn)
{
MySqlDataReader dbReader;
conn.Open();
dbReader = cmd.ExecuteReader();
a = GetList<Produkte>(dbReader);
}
if (a != null)
{
dataGridView1.DataSource = a;
}
}
public static List<T> GetList<T>(IDataReader reader)
{
List<T> list = new List<T>();
while (reader.Read())
{
var type = typeof(T);
T obj = (T)Activator.CreateInstance(type);
foreach (var prop in type.GetProperties())
{
var propType = prop.PropertyType;
prop.SetValue(obj, Convert.ChangeType(reader[prop.Name].ToString(), propType));
}
list.Add(obj);
}
return list;
}
Allerdings erhalte ich die Fehlermeldung: > Fehlermeldung:
Keine Überladung für die SetValue-Methode nimmt 2 Argumente an.
Kann mir bitte jemand helfen, wie ich das Problem lösen kann??
@Abt / @Th69 Danke für eure Hilfe! Hat nun geklappt!
@Th69 an der BindingList bin ich nun dran ...
Hallo,
ich habe zwei Listen.
Eine Liste mit allen Produktnummern und eine weitere mit nur ein paar Nummern.
Nun möchte ich gerne, wenn ich beide Listen miteinander vergleiche, dass ich nur die Werte aus der ersten Liste erhalten, welche NICHT in der zweiten Liste vorkommen.
List<Nummern> firstNotSecond = lstAlleNummern.Except(lstNummernzuordnung).ToList();
Wenn ich folgenden Code ausführe, erhalte ich jedoch weiterhin alle Werte; also auch alle, welche in der lstNummernzuordnung enthalten sind.
Ist meine Vorgehensweise falsch?
Weshalb würde bei diesem try/catch kein Fehler angezeigt werden, wenn ich den Debugger verwende?
Ein ResetBindings hilft auch nicht.
Das DataSource der BindingSource habe ich eine BindingList<T>.
Die Nummer ist hier statsächlich ein String, da auch Zeichen in der Nummer enthalten sein können. (z.B. KEN-002)
Hmm, ich bin mit dem Debugger durchgegangen und dieser hat keinen Fehler angezeigt.
Hmm, ich bin mit dem Debugger durchgegangen und dieser hat keinen Fehler angezeigt.
Hallo,
ich gebe meiner DataGridView als Datenquelle eine BindingSource.
dataGridView1.DataSource = bsUebersicht;
Nun soll über eine Textbox gefiltert werden können.
private void textBox1_TextChanged(object sender, EventArgs e)
{
try
{
bsUebersicht.Filter = "Nummer " + string.Format(" LIKE '%{0}%'", textBox1.Text);
}
catch {}
}
Es erscheint keine Fehlermeldung, allerdings werden auch keine Daten gefiltert.
Habe ich etwas vergessen?
Hallo,
ich habe eine Datenbankabfrage erstellt.
Eine Eigenschaft (Version), die ich nun gerne füllen möchte, sollte ich dazu aus einer ANDEREN Datenbank abrufen.
Wie kann ich dies entsprechend einbauen?
var query = from a in ctx.tblartikel
select new Artikel
{
ArtikelNr = a.Nummer
ArtikelName = a.Bezeichnung
// hier => Version = DB.VersionAbrufen(a.Nummer)
};
DataTable tbl = IEnumerableToDataTable.ToDataTable(query.ToList());
return tbl;
public static string VersionAbrufen(string sNummer)
{
try
{
using (xxx ctx = new xxx())
{
var query = "SELECT MAX(version) AS Version " +
"FROM dataparts p " +
"WHERE p.number= " + sNummer +
" AND p.type = 'a'";
return ctx.ExecuteStoreQuery<String>(query).FirstOrDefault();
}
}
catch (Exception ex)
{
return string.Empty;
}
}
Verwendetes Datenbanksystem: <MySQL>
@MrSparkle
Das Problem, mit der StackOverflowException konnte ich lösen.
Mein Problem ist "nur" noch, wie ich eine weitere Vertiefung des TreeView erreiche?
Ich habe nun den Fehler gefunden, dieser lag an der DB-Abfrage.
Soweit so gut. Nun enthält mein TreeView eine weitere Ebene.
Wie muss ich nun meine Aufrufe weiter fortführen, um den Baum maximal zu vertiefen?
Muss ich dan Baum durchlaufen, dann jeweils due Subelemente als Parent übergeben und wieder die Schleife rekursiv durchlaufen?
Ich habe nun nochmals einiges geändert. Leider erhalte ich weiterhin eine StackOverflowException.
Leider komme ich nicht weiter.
Was mache ich falsch??
Hier meine Klasse:
public class p_ident
{
public string ident;
public string ben1;
}
public class c_ident : p_ident
{
public string pos_nr;
public string count;
}
void rek_CreateNode(TreeNodeCollection nodes, p_ident ident)
{
TreeNode new_node = new TreeNode();
c_ident child_product = ident as c_ident;
if (child_product != null)
{
new_node.Text = child_product.ident + " " + child_product.ben1;
}
else
{
new_node.Text = ident.ident + " " + ident.ben1;
}
nodes.Add(new_node);
List<c_ident> child_products = DB.Childs_BaugruppenListe(ident.ident);
foreach (c_ident c in child_products)
{
rek_CreateNode(new_node.Nodes, c);
}
}
void AufrufTree(string parent)
{
treeViewBaugruppenliste.Nodes.Clear();
List<p_ident> parent_products = DB.Top_Baugruppenliste(parent);
foreach (p_ident p in parent_products)
{
rek_CreateNode(treeViewBaugruppenliste.Nodes, p);
}
}
Hallo Th69,
danke für deine Antwort.
In meiner DataTable filtere ich auf die "7500" (Auswahl des Nutzers). Dann sollte es doch passen, welche Einträge durchlaufen werden?
außerdem bei der Zuweisung zu myNode.Name ebenso.
Dein Teil verstehe ich leider nicht, was du damit meinst.
Hallo,
ich stehe gerade echt auf dem Schlauch, wie ich mein TreeView (rekursiv?) befüllt bekomme.
Die Datenstruktur in meiner DB-Tabelle sieht so aus:
Spalten
parent_nr
parent_version
child_nr
child_version
count
Dies sieht dann etwa so aus:
"7500";"a";"1200";"0";1
"7500";"a";"2200";"0";2
"7500";"a";"2250";"0";1
"1200";"0";"1100";"0";1
"1200";"0";"1300";"0";1
"1300";"0";"1000";"0";1
Nun hätte ich gerne, dass es im TreeView korrekt aufgelistet wird. Zum Anzeigen wird nur ein "main"-Parent benötigt, da der Nutzer dies zuvor auswählen soll. Wie im oben Beispiel wäre das dann die 7500.
Somit sollte es wie folgt aussehen
Leider erhalte ich mit meinem Versuch immer eine StackOverflowException
TreeNode parentNode = new TreeNode("7500");
nummer = "7500";
public voidTreeViewErzeugen(string nummer, TreeNode parentNode)
{
parentNode.Name = nummer;
try
{
string child;
foreach (DataRow row in dt.Rows)
{
child = row["child_nr"].ToString();
TreeNode myNode = new TreeNode(child);
myNode.Name = row["child_nr"].ToString();
parentNode.Nodes.Add(myNode);
PopulateTreeView(row["child_nr"].ToString(), myNode);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
}
Würde mich freuen, wenn mir jemand helfen könnte. Danke.
Auf meiner Hauptform habe ich bei der Eigenschaft MainMenuStrip "keine" ausgewählt - da ich dies auch nicht möchte.
Setze ich diese Eigenschaft allerdings auf meine Menüleiste, die auch das Item Fenster enthält, so werden die Child Forms korrekt in der WindowList aufgeführt.
Gibt es da einen Workaround, damit die WindowList dennoch angezeigt wird?
Ja, diese Eigenschaft ist gesetzt.
Gibt es sonst noch Eigenschaften, die die Anzeige verhindern können?
Guten Morgen,
auf meiner Hauptform habe ich einen MenuStrip eingefügt, mit einem Item "Fenster".
Dem MenuStrip habe ich bei der Eigenschaft "MdiWindowListItem" wiederum fensterToolStripMenuItem zugewiesen.
Starte ich nun das Projekt und öffne Forms, so werden diese nicht in der Liste angezeigt.
Hier mal noch das Öffnen einer Form:
private void artikelstammToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
Cursor.Current = Cursors.WaitCursor;
foreach (Form frm in this.MdiChildren)
{
if (frm is Form_Personen)
{
if (frm.WindowState == FormWindowState.Minimized)
frm.WindowState = FormWindowState.Normal;
frm.Focus();
return;
}
}
Form_Personen frm = new Form_Personen();
frm.MdiParent = this;
frm.Show();
}
finally
{
Cursor.Current = Cursors.Default;
}
}
Hat jemand eine Idee an was es liegen könnte, dass die Forms nicht in der WindowList aufgeführt werden?
Super!
Danke - so klappt es.
Hallo,
ich mache über eine TextBox einen Filter auf eine DataView. Aktuell werden nur Daten abgefragt, die vom Typ string sind.
Nun würde ich aber gerne noch einen weiteren Wert in den Filter aufnehmen. Dieser ist vom Typ Integer.
Bei der Abfrage direkt auf die DB klappt des auch. Bei meinem Filter allerdings nicht. Dort erhalte ich die Meldung Undefinierter Funktionsaufruf CAST().
Hier mal noch mein Code:
dv.RowFilter = string.Format("Name LIKE '%{0}%' OR Strasse LIKE '%{0}%' OR Ort LIKE '%{0}%' OR Land LIKE '%{0}%' OR CAST(Personennummer as CHAR) LIKE '%{0}%'", textBox1.Text);
Wie kann ich sowohl die String-Werte als auch den Integer in den Filter mit aufnehmen?
Beim aktuellen Projekt soll das Hauptmenü geändert werden.
Die aufgerufenen Forms sollen dazu in ein Hauptfenster.
Hierzu haben wir nun die beiden Varianten:
isMdiContainer
setzten
2) ein Panel auf der Startform, welches als Container fungiert
Meine Frage dazu, welche Variante ist zu bevorzugen?
Was sind die jeweiligen Vor- und Nachteile?
Unser Projekt soll nun in einen Container eingebettet werden.
Ein Test war in einem MDI-Container, beim anderen wurde ein Panel als Container verwendet.
Hat (eigentlich) auch beides geklappt.
Nun haben wir aber - bei beiden Varianten - festegestellt, dass die Darstellung nicht immer korrekt ist.
Z.B. wird eine DataGridView aufgerufen, bei dieser bestimmte Zellen abhängig vom Datum, farblich markiert werden.
Die farbliche Darstellung wird aber in beiden Fällen nicht dargestellt. Beim "normalen" Aufruf der Form allerdings schon.
An was liegt das? Muss an der Aufrufreihenfolge etwas geändert werden?
Und welche Variante des Containers ist zu bevorzugen? Die von VS vorgeschlagene Variante über IsMdiContainer oder über das Panel?
Hallo, gibt es eine Möglichkeit, die Hintergrundfarbe beim Hover Event zu ändern? Bzw auch das komplette Menü, das aufklappt, sollte dann ebenfalls eine andere Farbe bekommen. Wo werden diese Eigenschaften festgelegt?
Entschuldigung! Mit "es geht nicht" wollte ich sagen, dass einfach nichts passiert, d.h. wie wenn es keinen Filter gibt. Die Daten werden nicht gefiltert.
P.S.: Danke für den Hinweis bzgl. m_
Hallo,
leider klappt das Filtern meiner BindingSource nicht und ich weiß leider nicht, wie ich das Problem lösen kann.
Ich möchte gerne, beim Eingabe in die Textbox entsprechend filtern. Ich hoffe, es kann mir jemand helfen?! Danke!
private void SetDataSource()
{
List<Inventar> list = D_Inventur.ListeInventarBestandAbrufen(i_Id);
m_BindingList = new BindingList<Inventar>(list);
m_BindingSource.DataSource = m_BindingList;
}
private void LoadDataGridView()
{
if (m_BindingSource == null) { return; }
if (dgInventar.DataSource != null)
{
dgInventar.DataSource = null;
dgInventar.Rows.Clear();
dgInventar.Columns.Clear();
}
dgInventar.AutoGenerateColumns = true;
dgInventar.DataSource = m_BindingSource;
}
private void tbFilterArtikelnummer_TextChanged(object sender, EventArgs e)
{
m_BindingSource.Filter = string.Empty;
string sReplaced = EscapeLikeValues.EscapeLikeValue(tbFilterArtikelnummer.Text);
m_BindingSource.Filter = string.Format("(Nummer LIKE '%{0}%' OR Bezeichnung LIKE '%{0}%')", sReplaced);
}
verwendetes Datenbanksystem: <MySQL>
Hallo zusammen,
ich habe folgende Abfrage:
string sQuery = @SELECT a.artikelnummer, a.Bezeichnung_deutsch, lv.lagerplatznummer, l.anzahljeeinheit, l.einheit
FROM tblartikel a
LEFT JOIN tbl_lager lv ON a.artikelnummer = lv.artikelnummer
LEFT JOIN tbllagerplaetze l ON lv.lagerplatznummer = l.lagerplatzid
LEFT JOIN tbllagergrunddaten i ON a.artikelnummer= i.artikelnummer
WHERE a.bestandsgefuehrt = true";
var result = ctx.ExecuteStoreQuery<Lager>(sQuery).ToList();
DataTable tbl = IEnumerableToDataTable.ToDataTable(result);
Nun habe ich das Problem, dass es Werte gibt, die in der Tabelle tbllagergrundlagen nicht enthalten sind und somit bei der Abfrage NULL ergeben.
Dies kann ich so allerdings nicht als DataTable zurückgeben, da ich eine Exception wegen der NULL-Werte erhalte.
Wie muss ich entsprechend die Abfrage anpassen, damit die Abfrage ausgeführt wird bzw. die Daten dann in der DataGridView angezeigt werden?
Danke für eure Hilfe!
Nun habe ich es mit einer CollectionView versucht, Grid bleibt aber nach Eingabe eines Zeichens in der Textbox leer.
{
...
// GetPersonen() ist jetzt vom Typ List<Person>
CollectionView cv = (CollectionView)CollectionViewSource.GetDefaultView(Datanbankabfragen.GetPersonen());
dataGrid1.ItemsSource = cv;
}
private void textBox1_TextChanged(object sender, TextChangedEventArgs e)
{
CollectionView cv = (CollectionView)CollectionViewSource.GetDefaultView(Datanbankabfragen.GetPersonen());
cv.Filter = new Predicate<object>(FilterPerson);
dataGrid1.ItemsSource = cv;
}
private bool FilterPerson(object item)
{
Person p = item as Person;
return p.Name.Contains(textBox1.Text);
}
Hallo,
ich möchte gerne meinen DataGrid über eine Textbox durchsuchen, also eine Art Freitextsuche.
Leider funktioniert* das nicht und ich verstehe nicht, was ich falsch mache.
*Es kommt keine Fehlermeldung, alles was passiert ist, dass nach dem Tippen eines Zeichens der komplette DataGrid leer ist.
Durchsuchen
Hier mal die Datanbankabfrage
public static DataTable GetPersonen()
{
OleDbConnection conn = null;
OleDbDataReader reader = null;
List<Person> lstPersonen = new List<Person>();
Person person = new Person();
try
{
conn = new OleDbConnection(
"Provider=Microsoft.Jet.OLEDB.4.0; " +
"Data Source=xxx\\Testdatenbank.mdb");
conn.Open();
OleDbCommand cmd = new OleDbCommand("Select * FROM tblpersonen ORDER BY name", conn);
reader = cmd.ExecuteReader();
while (reader.Read())
{
person = new Person();
person.Ident = reader["Ident"].ToString();
person.Name = reader.GetValue(1).ToString();
// Pfad später aus Tabelle auslesen.
string sUrl = @"xxx\Personen\Foto\";
person.BildUrl = sUrl + person.Ident + ".png";
lstPersonen.Add(person);
}
conn.Dispose();
DataTable dt = ConvertListToDataTable.ConvertToDatatable(lstPersonen);
return dt;
}
catch (Exception ex)
{
MessageBox.Show("DB Fehler: GetPersonen\n" + ex.InnerException.Message);
return null;
}
}
Anbindung an DataGrid
DataView dv = new DataView();
dv = Datanbankabfragen.GetPersonen().DefaultView;
dataGrid1.ItemsSource = dv;
Suche über die Textbox
private void textBox1_TextChanged(object sender, TextChangedEventArgs e)
{
dv.RowFilter = string.Format("Name LIKE '%{0}%'", textBox1);
}
Doppelklicken
Zum einen würde ich die Anweisungen gerne ich eine separate Funktion auslegen, damit ich diese auch von einem anderen Bereich aus aufrufen könnte.
Wie muss ich dazu object sender anpassen?
private void dataGrid1_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
try
{
if (dataGrid1.SelectedItem == null) return;
DataRowView dr = dataGrid1.SelectedItem as DataRowView;
DataRow dr1 = dr.Row;
tbName.Text = dr1.ItemArray[0].ToString();
}
catch (Exception ex)
{
MessageBox.Show(ex.InnerException.Message);
}
}
Und ist es möglich die Daten, anstatt über den Index auch über den Namen abzurufen?
tbName.Text = dr1.ItemArray[0].ToString();
// z.B. so: tbName.Text = dr1.ItemArray["Name"].ToString();
Hoffe ihr könnte mir helfen! Danke Euch schon mal!
Bonaqua
Super, ich danke Euch beiden!
Ich verwende einfach mal den bestehenden Thread:
Ist eine solche Abfrage (mit variabler Paramteranzahl) auch über Linq möglich?
Wie könnte das dann aussehen?
Bspw. möchte ich eine unterschiedliche Anzahl an Artikelnummern vorab auswählen können und für diese Nummern dann eben entsprechend die Abfrage durchführen.
Hallo,
bin neu hier bzw. auch in der C# Thematik ...
Folgende Frage: Wenn ich mein Projekt veröffentliche sehe ich auf der "Bestätigung" eine Version ... z.B. 1.0.0.7
Auf meiner GUI wollte ich mir nun ebenfalls die Version anzeigen lassen, erhalte aber immer etwas in der Art: 1.0.42425.244374
lblVersion.Text = "Version: " + System.Reflection.Assembly.GetExecutingAssembly ().GetName ().Version.ToString ();
Rufe ich eine "falsche" Version ab bzw. warum stimmt das nicht mal annähernd überein?
Bonaqua