Entwickler-Ecke
Basistechnologien - Wert "umbauen"
Talemantros - So 16.11.14 15:19
Titel: Wert "umbauen"
Hallo,
ich habe eine Modellklasse, die ich fülle mit Werten aus einer Datenbank
Die Property "ShowText" wird mit einer 0 oder 1 gefüllt und sollte eigentlich per DAtabinding dafür sorgen, dass eine Checkbox ein oder ausgeschaltet wird.
Da dies nur mit dem Wert False oder true geht müsste ich das ja irgendwie umbauen.
Leider komme ich da nicht weiter:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24:
| private int showText; public int ShowText { get { return showText; } set { showText = value; } }
public string ShowTextAsString { get { return showText ? true : false; } set { showText = value == true; } } |
Kann mir da jemand helfen?
VG
Daniel
Christian S. - So 16.11.14 15:25
Dir ist aber schon klar, dass true und false Werte von Typ bool sind und nicht string? :zwinker:
Und dass showText nicht alleine stehend im ?-Operator genutzt werden kann, weil's ein int ist?
jfheins - So 16.11.14 15:26
Bist du sicher, dass du das als String brauchst?
Wenn ja, warum benutzt du dann bools? (Strings sind ja immer in Anführungszeichen "")
Dann wären Fehlermeldungen auch noch schön, und der obligatorische Hinweis: Das Fragment ? true : false; ist vollständig überflüssig.
Ach, und ich würde dann die "Hauptproperty" vom typ bool machen, und die int-Property davon abhängig. Und etwas kürzer geht es dann mit Auto-Properties.
Talemantros - So 16.11.14 16:09
Hi,
also bei dem String Argument ist mir klar :-(
Scheiß Copy Paste Fehler . Sorry
Den Rest muss ich mal versuchen nachzuvollziehen.
Komme da bei euren Kommentaren gerade noch nicht so mit.
Probiere es mal.
Danke
Gruß
Daniel
Edit:
Sorry aber ich komme da nicht mit, könntet ihr mir das mal aufzeigen?
jfheins - So 16.11.14 16:50
Naja, also was halt komisch ist, ist das hier:
C#-Quelltext
1: 2: 3: 4: 5: 6:
| public string ShowTextAsString { get { return showText ? true : false; } |
showText ist das Fals, also vom Typ int. Ein Wert vom Typ int kann aber niemals "einfach so" vor dem Fragezeichen stehen. Genau so beim if:
if (3) {} ist eben doch ein klarer Fehler. Und Das ? : ist ja nichts anderes als eine Kurzversion des if-Statements.
Dann kommt noch dazu: Das Ergebnis deines Ausdrucks ist ja entweder
true oder
false, also Werte vom Typ
bool. Oben hast du aber deklariert, dass diese Property vom Typ string sei:
public string ShowTextAsString
Mit anderen Worten: Dein Quelltext passt hinten und vorne nicht. Ist dir denn ungefähr bewusst, was die verschiedenen Typen sind und warum
true kein string ist?
Ralf Jansen - So 16.11.14 17:03
| Zitat: |
| Sorry aber ich komme da nicht mit, könntet ihr mir das mal aufzeigen? |
Fangen wir am besten vorne an um es gleich richtig zumachen. Warum ist ShowText ein Integer? Und wenn du uns erklärst warum gleich am besten zeigen wie du denn da rein bekommen hast.
Talemantros - So 16.11.14 17:26
Hallo Ralf,
ich habe eine Checkbox für die der Wert gespeichert werden soll.
Da meine MySQL Datenbank keine boolischen Werte speichern kann hatte ich von euch "gelernt" bzw habe es so in Erinnerung, dass ich mit 0 und 1 arbeiten soll.
Daher habe ich nun ein Datenbank Feld welches ganze Zahlen fast und eine Property passend dazu zum Typ int.
So die Grundidee, die dahinter steckt.
Und da ich die 0 und 1 nicht an die Checkbox weiter geben kann und ihr mal sowas angerissen hattet, dass man das dann "umbauen" kann, dachte ich aus 0 = false und 1 = true zu machen?!
Gruß
Daniel
jfheins - So 16.11.14 17:30
Stimmt soweit. Aber wo kommen da jetzt Strings ins Spiel?
false und true sind ja Boolean Werte. D.h. man könnte ja direkt sowas schreiben:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| public bool ShowTextAsBool { get { return showText != 0; } set { showText = value ? 1 : 0; } } |
Ich würde es aber wie gesagt andersherum machen: Die eigentlichen Daten als bool ablegen und dann für die Datenbank eine extra Property die den bool in einen int umwandelt.
Talemantros - So 16.11.14 18:24
Hallo jfheins,
Wie oben geschrieben war der String Teil ein copy&paste Fehler und so nicht gewünscht.
Ich habe deinen Teil jetzt gesehen verstehe aber nicht was er da macht und wo er da Boot auswertet?!
Könntest du mir das andersherum mal zeigen mit Erklärung?!
Oder nimmt er hier 0 automatisch als False?!
Gruß
Danke schonmal für eure Erklärung/Hilfe
Ralf Jansen - So 16.11.14 18:36
| Zitat: |
| Die eigentlichen Daten als bool ablegen und dann für die Datenbank eine extra Property die den bool in einen int umwandelt. |
0/1 ist die Darstellungmethode deiner Persistenzschicht (letztlich der DB) und true/false die Darstellungsweise deiner UI bzw. deiner Klasse die die per Databinding benutzen willst. Beides solltest du nicht in in dieser Datenklasse mischen. An irgendeinem Punkt musst du die Daten aus der Datenbank in die gezeigte Klasse gebracht haben (und umgekehrt) und dort solltest du es lösen (beim Mapping) aber nicht in dieser Klasse selbst. Also zeig uns doch mal wie du das machst.
jfheins - So 16.11.14 18:56
Talemantros hat folgendes geschrieben : |
Hallo jfheins,
Wie oben geschrieben war der String Teil ein copy&paste Fehler und so nicht gewünscht. |
Dann wäre es sinnvoll, wenn du nicht den falschen Code da stehen lässt, sondern korrigierst. Entweder, indem du den ersten Post bearbeitest, oder indem du den richtigen Code postest. Zu einer guten Frage gehören dann eigentlich auch noch die Fehlermeldungen, falls welche kommen.
Talemantros hat folgendes geschrieben : |
Ich habe deinen Teil jetzt gesehen verstehe aber nicht was er da macht und wo er da Boot auswertet?!
Oder nimmt er hier 0 automatisch als False?! |
Automatisch nicht. Aber der Code ist so geschrieben, dass 0 mit
false gekoppelt ist und
alles andere mit
true.
Der getter muss ja ein bool zurückliefern. showText ist ein int. Also wird der int mit einem anderen int vergleichen, um einen booleschen Wert zu erhalten:
return showText != 0; Ergibt false, wenn die Zahl 0 ist und sonst true. Klar soweit?
Beim setter ist das dann umgekehrt: Wir bekommen einen bool und müssen den als int speichern. Da bietet sich der ?: Operator an: Wenn true geschrieben werden soll, speichern wir eine 1, sonst 0.
Talemantros hat folgendes geschrieben : |
| Könntest du mir das andersherum mal zeigen mit Erklärung?! |
Klar:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| public bool ShowText{ get; set; } public int ShowTextAsInt { get { return ShowText ? 1 : 0; } set { ShowText = value != 0; } } |
@Ralf: Man kann ja ein Model haben, das einerseits zur GUI gegeben wird zum anzeigen, und andererseits in die DB persistiert wird. Ist doch eigentlich normal? Man kann auch noch ein ViewModel machen, falls die Anzeige nicht 1:1 die Daten wiedergibt. Aber machst du dann noch ein DB-Model? Ergibt das nicht irre viel Mapper-Code?
Ralf Jansen - So 16.11.14 19:03
| Zitat: |
| @Ralf: Man kann ja ein Model haben, das einerseits zur GUI gegeben wird zum anzeigen, und andererseits in die DB persistiert wird. Ist doch eigentlich normal? Man kann auch noch ein ViewModel machen, falls die Anzeige nicht 1:1 die Daten wiedergibt. Aber machst du dann noch ein DB-Model? Ergibt das nicht irre viel Mapper-Code? |
Nein. Hier gibt es sicherlich bereits Mappercode von der DB in diese Klasse warum sollte dieser Code nicht dabei auch zwischen Integer und Bool mappen? Das eine konkrete Datenbank kein bool hat schreit ja fast schon nach einer generischen Lösung beim mappen. Ich könnte mir sogar vorstellen, je nachdem was da für eine Technik zum Einsatz kommt, das es entsprechenden Code bereits gibt aber von Talemantros ~übersehen~ wurde.
Talemantros - So 16.11.14 19:40
Hallo,
also leider kann ich eurer Unterhaltung inhaltlich nicht mehr folgen :-(
Ganz im Gegenteil verwirrt sie mich zusätzlich :-)
Also ich gehe hier jetzt mal näher darauf ein, was ich als Anfänger mir gedacht habe, unabhängig davon, dass ich ja jetzt schon weiß, dass es falsch ist.
Also ich habe eine Tabelle in einer MySQl Datenbank mit folgenden Feldern:
barcodeid = bigint = Auto_increment
hoehe = Bigint
breite = double
abstand = double
textoben = varchar
textunten = varchar
text = varchar
zeigetext = tinyint
in dem Letzten Feld möchte ich eigentlich abbilden, ob eine Checkbox ausgewählt ist, oder nicht.
Da mySQl aber keinen Wert für Bool hat, habe ich da ein TinyInt genommen um 0 oder 1 abzubilden.
Dann habe ich mir eine Klasse gemacht für die Einstellungen des Barcodes:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35:
| public class Barcode { public int High { get; set; } public decimal Width { get; set; } public decimal Range { get; set; } public string TextAbove { get; set; } public string TextBelow { get; set; } public string EncodingText { get; set; }
private int showText; public int ShowText { get { return showText; } set { showText = value; } }
} |
Und habe dem USerControl ein DataBinding hinzugefügt über welches ich die Daten anzeigen lassen wollte.
Nun habe ich ja in der Eigenschaft "ShowTExt" 0 oder 1 stehen statt True oder false und kann deswegen die Checkbox nicht aktivieren.
Beim starten des UserControls
C#-Quelltext
1: 2: 3: 4: 5:
| private void BarcodeNeuUserControl_Load(object sender, EventArgs e) { localBarcode = BarcodeMethods.GetAllBarcodeData(); bsBarcode.DataSource = localBarcode; } |
und dahinter steckt
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62:
| public class BarcodeMethods { static string strSql = string.Empty; static string connStr = DbInfo.GetMySqlConnStr();
public static Barcode GetAllBarcodeData() { Barcode myBarcode = new Barcode();
strSql = "Select * from barcode";
using (MySqlConnection conn = new MySqlConnection(connStr)) { using (MySqlCommand cmd = new MySqlCommand(strSql, conn)) { conn.Open();
MySqlDataReader dr = cmd.ExecuteReader();
while (dr.Read()) { myBarcode.High = Convert.ToInt16(dr["hoehe"]); myBarcode.Width = Convert.ToDecimal(dr["breite"]); myBarcode.Range = Convert.ToInt16(dr["abstand"]); myBarcode.TextAbove = (dr["textoben"]).ToString(); myBarcode.TextBelow = (dr["textunten"].ToString()); myBarcode.EncodingText = (dr["text"]).ToString(); myBarcode.ShowText = Convert.ToInt16(dr["zeigetext"]); }
conn.Close(); } }
return myBarcode; }
public static void UpdateAllBarcodeData(Barcode barcode) { strSql = "Update barcode SET hoehe=?hoehe, breite=?breite, abstand=?abstand, textoben=?textoben, textunten=?textunten, text=?text, zeigetext=?zeigetext";
using (MySqlConnection conn = new MySqlConnection (connStr)) { using (MySqlCommand cmd = new MySqlCommand (strSql, conn)) { conn.Open();
cmd.Parameters.AddWithValue("?hoehe", barcode.High); cmd.Parameters.AddWithValue("?breite", barcode.Width); cmd.Parameters.AddWithValue("?abstand", barcode.Range); cmd.Parameters.AddWithValue("?textoben", barcode.TextAbove); cmd.Parameters.AddWithValue("?textunten", barcode.TextBelow); cmd.Parameters.AddWithValue("?text", barcode.EncodingText); cmd.Parameters.AddWithValue("?zeigetext", barcode.ShowText);
cmd.ExecuteNonQuery();
conn.Close(); } } } } |
Vielleicht können wir das nochmal erötern. WÜrde es gern verstehen oder auch gern ganz anders machen, wenn es einen "richigeren" Ansatz gibt.
Danke
Gruß
Daniel
Ralf Jansen - So 16.11.14 19:48
Ändere in der Klasse ShowText von Integer nach Boolean.
Von DB nach Klasse dann via
C#-Quelltext
1:
| myBarcode.ShowText = dr.GetBoolean("zeigetext"); |
umgekehrt
C#-Quelltext
1:
| cmd.Parameters.AddWithValue("?zeigetext", barcode.ShowText.ToSByte()); |
Edit:
| Zitat: |
| Vielleicht können wir das nochmal erötern. WÜrde es gern verstehen oder auch gern ganz anders machen, wenn es einen "richigeren" Ansatz gibt. |
Es gibt da kein absolutes richtig und falsch also auch kein richtiger oder falscher. Man kann eventuell zwischen angemessen und unangemessen unterscheiden.
Wenn der Code nicht um Faktoren steigt und du dieses Muster auf eine 3-stellige Anzahl ähnlicher Objekte anwenden willst oder größerer Abhängigkeiten lösen musst (z.B Updatereihenfolgen mehrerer beteiligter Objekte) ist das absolut ok so. Nur da du schon am Anfang davon sprachst dieses Modell zum Databinding zu verwenden also es UI nah siehst solltest du versuchen es von irgendwelchen DB Besonderheiten frei zu halten. Und in diesem Fall ist das ja leicht möglich.
Talemantros - So 16.11.14 21:07
Ok danke
Teste ich morgen aus
Wie muss ich mir den dieses ? Wert : Wert ausgeschrieben vorstellen?
Nur als Nachfrage weil es hier vorkam und hieß es sei ein if?!
Palladin007 - So 16.11.14 21:18
Die ?:-Operator ist im Grunde nur Compiler-Zucker.
Beispiel:
C#-Quelltext
1: 2:
| var auswahl = true; var wert = auswahl ? "Ja" : "Nein"; |
Das ist das Gleiche wie:
C#-Quelltext
1: 2: 3: 4: 5: 6:
| var auswahl = true; string wert; if (auswahl) wert = "Ja"; else wert = "Nein"; |
Nur eben Kürzer und angenehmer zu verwenden.
Etwas Ähnliches gibt es im Übrigen auf nur null-Werte:
C#-Quelltext
1: 2:
| string value = null; var notNullValue = auswahl ?? "not null"; |
Talemantros - Mo 17.11.14 21:37
Vielen Dank an alle
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!