Laden...
Avatar #avatar-1538.jpg
roland myCSharp.de - Member
Fachinformatiker für Anwendungsentwicklung Deutschland Dabei seit 28.06.2004 257 Beiträge
Benutzerbeschreibung

Forenbeiträge von roland Ingesamt 257 Beiträge

14.09.2006 - 11:08 Uhr

Hallo,

ich habe leider keine Antwort zu diesem Thema gefunden, deshalb frage ich hier einmal nach.

Ich möchte selber eine generische List von List ableiten, diese soll um ein paar spezielle Methoden erweitert werden.

Beim ableiten von List wird allerdings ein Typ verlangt, aber das möchte ich ja nicht weil auch meine Klasse generisch sein soll.

Kann mir jemand sagen wie das geht, bzw. ob es überhaupt möglich ist?

07.11.2005 - 16:55 Uhr

Also ich würde ein UserControl und eine TabPage entwerfen.

Das UserControl kannst du im Designer zusammenklicken.

Dann musst du das UserControl nur noch deiner TabPage-Klasse
hinzufügen und fertig.

Damit sparst du dir einerseits viel Schreibarbeit, wenn du die
TabPage händisch erstellst und andererseits musst du das
UserControl nicht immer wieder händisch deiner TabPage
zuweisen.

07.11.2005 - 11:26 Uhr

Hallo alle,

ich suche dringend eine Klasse, die den Export von Überweisungen in eine DTAUS-Datei macht. Da ich momentan sehr unter Zeitdruck stehe, frage ich lieber hier mal, bevor ich eine Klasse selber schreiben muss.

Viele Grüße

Roland

05.11.2005 - 02:28 Uhr

@herbivore:

Ich habe dieses Konstrukt schon mehrmals verwendet und es funktioniert einwandfrei, mit Refresh wird auf jedenfall das Control aktualisiert.

Das einzige was passieren kann ist, wenn du Refresh sehr oft in sehr kurzen Intervallen aufrufst, dann kann das Control anfangen zu flackern.

Das muss man dann ausprobieren.

04.11.2005 - 16:13 Uhr

Das kommt darauf an welches DBMS du verwendest.

Bei MySQL gibt es z.Bsp. den SQL-Befehl LIMIT index, count

Du führst also dein Statement wie normal aus, sortierst die Ausgabe auch im SQL und hängst dann die Beschränkung hinten dran.

Eine Ähnliche Syntax gibt es auch für andere DBMS, da musst du halt nur in die Doku schauen.

04.11.2005 - 16:09 Uhr

Hast du schon mal BeginEdit und EndEdit weggelassen?

Diese Methoden benötigst du gar nicht bei einem Delete.

04.11.2005 - 15:08 Uhr

Oder kürzer:


object result = cmd.ExecuteScalar();

ExecuteScalar liefert den Inhalt der ersten Spalte des ersten Datensatzes.

04.11.2005 - 15:02 Uhr

Dann sollte das doch eigentlich recht einfach klappen!

Schreibe dir eine statische Methode die die Anzeige und Berechnung übernimmt und füge dem Formular eine Eigenschaft (ArrayList) hinzu, die du an dein Control bindest.

Wie soll das ganze jetzt aussehen?


public class MyForm : System.Windows.Forms.Form
{
    // Hier nur die statische Methode, den Rest kannst du dir ja denken.
    public void AnzeigenUndBerechnen(string path)
    {
        MyForm form = new MyForm();
        form.Show();
        // Datei öffnen
        ArrayList lines = ... // Datei in eine ArrayList füllen
        // Für jede Zeile die Berechnung durchführen und das Formular aktualisieren
        foreach (string line in lines)
        {
            // Berechnung durchführen
            string calculatedLine = ... // Berechnung durchführen
            form.List.Add(calculatedLine);
            form.Refresh();
        }
    }
}

Das müsste dann eigentlich funktionieren.

Viele Grüße

Roland

04.11.2005 - 14:46 Uhr

Du kannst doch bestimmt den Typ des Datensatzes identifizieren, dann brauchst du nur noch die entsprechende Konfigurationsdatei einlesen. Um das ganze natürlich wieder voll dynamsich zu halten und if bzw. switch Bedingungen zu vermeiden, nennst du die Konfigurationsdateien einfach so, wie der Typ des Datensatzes ist. Damit hast du eine Abhängigkeit entworfen die dynamisch ohne Änderung des Sourcecodes funktioniert.

04.11.2005 - 14:42 Uhr

Bitte poste doch mal den genauen Text der Fehlermeldung. Denn es sollte ohne weiteres möglich sein mehrere Controls an einen DataSource zu binden.

Ich vermute eher, das das Objekt welches gebunden wird Probleme damit hat.

04.11.2005 - 14:31 Uhr

Du kannst praktisch fast alles von Parametern abhängig machen. Doch sollten die Definitionen wie Typ, Position, Größe usw. nicht in derselben Xml-Datei stehen, wo auch die Daten enthalten sind. Speichere dafür lieber zwei Xml-Dateien, eine für die Daten und eine für die Konfiguration des Forms.

04.11.2005 - 14:27 Uhr

Ich kann weder deine Gedanken lesen noch habe ich deinen Quellcode geklaut! 🙂

Meine Lösung resultiert aus der logischen Konsequenz deiner Aussage, das du ein
Control gleich zwei mal anzeigen willst. Wo macht das schon Sinn, wenn nicht in
zwei TabPages oder sonstigen verdeckten Controls. 😉

04.11.2005 - 13:39 Uhr

Das heisst du willst die selbe Instanz eines Control in zwei verschiedenen Panels
anzeigen? Das geht meiner Meinung nach nicht gleichzeitig, da ein Control nur
einem Parant haben kann. Aber du kannst ja ein wenig tricksen! 🙂

Wenn du z. Bsp. TabPages benutzt, dann kannst du ja beim aktivieres der TabPage schnell das Control hinzufügen.

Sonst fällt mir da auf die schnelle nichts ein!

04.11.2005 - 12:10 Uhr

Also ich würde den Type lieber direkt in die Xml-Definition schreiben.

Also anstatt 1 für TextBox schreibst du System.Windows.Forms.TextBox.

Das spart in deinem Parser die Entscheidung was für ein Control du denn
jetzt erzeugen musst. Du nimmst einfach den String und erzeugst mit dem
Activator das Control, danach setzt du die Parameter wie Position, Größe,
Font, Farben, eventuell sogar DataBinding wenn nötig. Somit kannst du
praktisch jedes Control direkt über Xml definieren.

04.11.2005 - 09:10 Uhr

Dann ist der Weg den herbivore vorgeschlagen hat goldrichtig.

So wie ich das verstehe sind in der Xml Datei alle Informationen enthalten um die Controls für einen bestimmten Datensatztyp zu instanziieren. Du musst nur die Xml Datei parsen, die Controls on the fly erstellen und sie dem Formular hinzufügen. Wenn du sogar den Controltyp in der Xml-Datei stehen hast, dann kannst du dir das Control mit dem Activator erstellen.

Viele Grüße

Roland

P.S. Da fällt mir aber noch ein, du sagst das alle Datensätze ähnlich sind. Dann kannst du dir auch ein Form schreiben indem alle Controls enthalten sind, die auch in jedem Datensatz vorkommen und dann mittels Vererbung die speziellen Forms erstellen. So hast du zwar wieder mehrere Forms, die sind aber schneller entwickelt und du musst nicht so viel Aufwand betreiben.

28.10.2005 - 16:39 Uhr

Ja du hast Recht, es laufen zwei Threads. Auch wenn das Beispiel einwandfrei funktioniert ist es doch ein Fehler es so zu machen. Ich bin dir nicht böse, ein wenig Kritik kann ich schon verkraften. 🙂

28.10.2005 - 16:19 Uhr

Ich weis auch das man aus einem Thread nicht direkt auf Controls zugreifen sollte. Doch in diesem Falle wird nur ein Thread ausgeführt und dann geht das auch einwandfrei. Ausserdem war das ja auch nur ein schnelles Beispiel wie man einen Thread aufruft.

28.10.2005 - 16:07 Uhr

Hallo,

ich habe dir mal ein kleines Beispiel gepostet, wie du das ganze mit einem Thread realisieren könntest.


private void Form1_Load(object sender, System.EventArgs e)
{
	Thread thread = new Thread(new ThreadStart(FillLines));
	thread.Start();
}
private void FillLines()
{
	string[] strings = new string[1000000];
	for (int i = 0; i < strings.Length; i++)
	{
		strings[i] = "Dies ist die Zeil Nr.: " + i.ToString();
	}
	this.textBox1.Lines = strings;
}

Hierbei wird zuerst das Form angezeigt und anschliessend die TextBox gefüllt.

28.10.2005 - 15:31 Uhr

Hallo!

DataTable hat keine RowFilter-Eigenschaft, die findest du in DataView.

Und diese Eigenschaft wird folgendermassen gesetzt:

dv.RowFilter = "ItemName LIKE 'product*'";

Das hat mich eine Minute in der Doku lesen gekostet. Einfach RowFilter im Index angeben und schon bekommst du alles was nötig ist.

28.10.2005 - 08:31 Uhr

Ob du ein Form oder ein UserControl implementierst ist wirklich egal. Es ist der gleiche Aufwand. Deshalb möchte ich dir noch einen Tipp mit auf dem Weg geben.

Implementiere zwei Interface Methoden und das UserControl.

Die erste Methode ShowControl(ScrollableControl theControl) ist wie oben beschrieben mit dem ScollableControl Parameter versehen.

Die zwei Methode z.Bsp. ShowDialog() ruft intern ShowControl auf und übergibt einfach eine neue Instanz eines Forms welches du on the fly instanziierst.

Somit bist du ganz frei und hast sehr wenig Aufwand.

Hier ein Code-Schnipsel zum Verständnis:


class MyAddOn : IAddOn
{
  public void ShowControl(ScrollableControl theControl)
  {
    theControl.Controls.Add(new MyAddOnControl());
  }

  public void ShowDialog()
  {
    Form form = new Form();
    form.FormBorderStyle = FormBorderStyle.FixedDialog;
    form.Size = new Size(400, 300);
    form.StartPosition = FormStartPosition.CenterScreen;
    this.ShowControl(form);
    form.ShowDialog();
  }
}

27.10.2005 - 17:02 Uhr

Hi,

also ich würde der Methode ein Argument vom Typ ScrollableControl mitgeben und für jedes AddOn ein UserControl entwerfen welches im ScrollableControl dann angezeigt wird. Damit ist es egal, ob du ein Form, ein Panel oder eine TabPage mitgibst. Das gilt natürlich für alle von ScrollableControl abgeleiteten Klassen.

In deiner Methode kannst du dann ja überprüfen ob das ScrollableControl auch auf Scrollable eingestellt ist.

Viele Grüße

Roland

19.10.2005 - 16:51 Uhr

panel.Controls.Clear();
YourControl yourControl = new YourUserControl();
// yourControl initialisieren
panel.Controls.Add(yourControl);

13.10.2005 - 22:28 Uhr

Du könntest das Enum als statisch deklarieren und über den Klassennamen drauf zugreifen.

Oder du definierst die Enums ausserhalb der Klasse.

13.10.2005 - 16:40 Uhr

Klar gibt es da Namespaces, die sind aber nicht im .NET Framework enthalten, dafür muss man schon spezielle Assemblies einbinden.

13.10.2005 - 16:26 Uhr

Er möchte doch eine MySQL-Server ansprechen, da wird SqlCommand aus dem Namespace System.Data.SqlClient nicht so gut funktionieren, da dies eine Komponente für den MSSQL-Server ist.

Es gibt verschiedene Komponenten im Netz die du dafür verwenden kannst. Google mal danach.

13.10.2005 - 16:17 Uhr

Ja, oder so...,

mir ist Keys nicht mehr eingefallen! 🙂

13.10.2005 - 16:09 Uhr

private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
  if (e.KeyCode.ToString() == "Enter")
  {
    // Do something...
  }
}

Mist, da war ich wohl zu langsam.

13.10.2005 - 15:57 Uhr

Könntest du in diesem Fall nicht einfach ein Label verwenden und dabei den Rahmen und die Hintergrundfarbe setzen, so das es aussieht wie eine TextBox?

Dann kann dir keiner den Text herauskopieren.

13.10.2005 - 15:53 Uhr

Original von taaz
Hat sich erledigt, danke.

Wollte nämlich direkt in einer if-Anweisung abbrechen.
Da hab ich dann den rest des Codes einfach in einen else-Anweisungblick gesetzt und fertig.

Taaz

Du hättest auch einfach nur mit return die Methode verlassen können.

13.10.2005 - 15:49 Uhr

Hast du auch System.ComponentModel eingebunden?

13.10.2005 - 15:25 Uhr

Sorry, aber dein Ansatz ist in der Tat falsch!

Was ich meinte, ist das du dir eine DAL aufbaust in der die gesamte Kommunikation mit der Datenbank stattfindet.

Deine Anwendung arbeitet aber nur mit der abstrakten Schicht, so das du später einfach nur eine andere spezielle DAL instanziieren musst um mit einem anderen DBMS zu kommunizieren.

Nochmal ein anderes klitzekleines Beispiel zur Verdeutlichung. In diesem Fall gehe ich aber mit Absicht mal einen etwas anderen Weg.

Du hast eine Tabelle Adressen in deiner DB die du verwalten willst.

Für den Zugriff baust du dir nun eine abstrakte (DBMS unabhängige) DAL-Klasse,
die nur die Methoden zur Verfügung stellt, die du in deiner Anwendung benötigst.


public abstract class DAL
{
  public abstract void Load(DataSet dataSet);
  public abstract void Save(DataSet dataSet);
}

Dann baust du dir eine spezielle (DBMS abhängige) DAL-Klasse.


public class OleDbDAL : DAL
{
  private OleDbConnection   _conn;
  private OleDbDataAdapter _data;

  public OleDbDAL()
  {
    _conn = new OleDbConnection("ConnectionString");
    OleDbCommand cmd = new OleDbCommand("SELECT * FROM Adressen", _conn);
    _data = new OleDbDataAdapter(cmd);
    // weitere Command für Insert, Update, Delete erzeugen
   ...
  }

  public void Load(DataSet dataSet)
  {
    _data.Fill(dataSet);
  }

  public void Save(DataSet dataSet)
  {
    _data.Update(dataSet);
  }
}

Deine Anwendung arbeitet nur mit deiner DAL.


public class App
{
  [STAThread]
  static void Main() 
  {
    DAL dal = new OleDbDAL();
    DataSet dataSet = new DataSet();
    dal.Load(dataSet);
    // Daten bearbeiten...
    dal.Save(dataSet);
  }
}

13.10.2005 - 14:32 Uhr

Das kommt darauf an wann du dir sicher bist das die Bearbeitung zu Ende ist!

Wenn du z.Bsp. den Datensatz speichern willst, wenn der Button "Speichern" gedrückt wurde, dann sieht das folgendermassen aus:


private void button1_Click(object sender, System.EventArgs e)
{
	this.BindingContext[this.dataSource].EndCurrentEdit();
	this.dataAdapter.Update(this.dataSet);
}

13.10.2005 - 13:47 Uhr

Hallo,

du kannst dir doch eine abstrakte Klasse stricken, die Methoden für das Speichern
und Laden von Daten übernimmt.

Diese Klasse leitest du dann ab, um eine spezielle Db anzusprechen.

Ein klitzekleines Beispiel, schliesslich sollst du daraus ja lernen und nicht abpinnen.
🙂


public abstract class DbLayer
{
  public abstract IDbCommand GetCommand();
}

public class OleDbLayer : DbLayer
{
  private OleDbConnection _conn = null;

  public OleDbLayer()
  {
    _conn = new OleDbConnection("Dein connection String");
  }

  public IDbCommand GetCommand()
  {
    OleDbCommand cmd = _conn.CreateCommand();
    cmd.CommandText = "SELECT feld FROM tabelle";
    return cmd;
  }
}


13.10.2005 - 12:44 Uhr

Du wendest es an, sobald du sicher bist, das die Bearbeitung zu Ende ist.

Dies geschieht in der Regel kurz vorm Speichern der Daten in der DB.

Z.Bsp.

Du hast ein Formular welches Daten eines Datensatzes einliesst und sie per
DataBinding in den zuständigen Controls anzeigt.

Jetzt soll beim Schliessen des Formulares die Daten gespeichert werden.

Dafür reagierst du dann auf das Closing() Ereignis des Forms und
rufst BindingContext[dataSource].EndCurrentEdit() auf.

Danach führst du
dann die Update Methode deinen DataAdapters aus.

13.10.2005 - 11:42 Uhr

Rufts du vor dem Speichern auch BindingContext[].EndCurrentEdit() auf?

13.10.2005 - 11:34 Uhr

Hallo, auf die schnelle kann ich dir nur sagen das du auf
BindingContext[].PositionChanged regieren kannst und
dann fragst, ob die aktuelle Row neu ist.

13.10.2005 - 09:19 Uhr

Du kannst es auch mit ExecuteScalar machen.


object result = cmd.ExecuteScalar();

Damit steht in der Variablen result der Wert den das SQL Statement zurückgibt.

12.10.2005 - 17:05 Uhr

Hallo, ich nehme mal Anschluss an die Antwort von herbivore.

Das Form sollte eine MyClass-Instanz besitzen.

Deine UserControls solltest du einfach um eine Methode erweitern, die
Values an ein Objekt vom Typ MyClass anhängt, das im Parameter
übergeben wird.

Z.Bsp. so:


public class MyUserControl : UserControl
{
  public void AddValues(MyClass myClass)
  {
    myClass.AddValue(textBox1.Text);
    myClass.AddValue(textBox2.Text);
  }
}

Somit hast du auch eine saubere Trennung und benötigst eigentlich keine weiteren Events.

06.10.2005 - 17:08 Uhr

Wenn es sich um Daten aus einer Tabelle handelt geht das eigentlich recht einfach.

Am besten schaust du mal in die Hilfe unter DataAdapter, da ist eigentlich alles sehr gut beschrieben und du findest auch Beispiele.

06.10.2005 - 12:14 Uhr

Vorausgesetzt, das die DataRows des Status Neu haben, kannst du einen DataAdapter benutzer der dir dann die Daten in die Tabelle schreibt.

Alternativ kannst du dir auch ein Command mit entsprechdem SQL erstellen und dann mit foreach jede DataRow durchgehen, die Parameter setzen und den Command ausführen.

Eine andere Möglichkeit sehe ich da nicht.

04.10.2005 - 23:44 Uhr

Hi,

also wenn du immer die gleiche TabPage mit den selben Controls benötigst, dann solltest du lieber eine TabPage ableiten, dies mit den Controls befüllen und alle initialisierungen in der neuen TabPage vornehmen. Damit du dann die Controls später noch von aussen beeinflussen kannst (falls gewünscht), dann stellst du einfach ein paar Eigenschaften nach aussen zur Verfügung.

Hier mal ein Beispiel welches ich auch verwendet habe:


public class GridTabPage : TabPage
{
  private DataGrid dataGrid;

  public DataGrid DataGrid
  {
    get{return this.dataGrid;}
  }

  public GridTabPage()
  {
    this.dataGrid = new DataGrid();
    ... // Hier initialisieren
    this.Controls.Add(this.dataGrid);
  }
}

public class GridTabControl : TabControl
{
  public GridTabControl()
  {
  }

  public GridTabPage CreateTabPage()
  {
    GridTabPage gtp = new GridTabPage();
    this.TabPages.Add(gtp);
    return gtp;
  }
}

// Wenn du dieses TabControl einsetzt, musst du nur noch
this.GridTabControl.CreateTabPage();
// aufrufen um eine neue TabPage zu erstellen.

Damit verlagerst du den Code aus deinem Formular heraus und hast gleichzeitig eine neue Komponente erschaffen die du in anderen Forms einsetzen kannst, ohne wieder denselben Code programmieren zu müssen.

04.10.2005 - 15:54 Uhr

Du musst die Persistenten Klassen nicht rauswerfen, du kannst sie einfach mit dem Attribut NonPersistent markieren um sie aus der Persistenz auszuschliessen.

Wo ich dir Recht gebe, ist bei dem Problem eine bereits exitierende Klasse aus einer anderen Assembly zu persistieren. Das geht leider nicht so einfach.

Zum Glück habe ich das bis jetzt noch nie benötigt! 🙂

Ansonsten muss mal Wohl oder Übel eine Mapper-Klasse für das Form bauen.

04.10.2005 - 15:19 Uhr

Es muss doch nur die Urklasse von XPObject erben, z.Bsp. so:


[NonPersistent]
public abstract class BusinessObject : XPObject
{
  ...
}

public class Company : BusinessObject
{
  [Size(100)]
  public string Name;
  [Association("CompanyEmployees", typeof(Employee), Aggregated]
  public XPCollection Employees
  {
    get{GetCollection("Employees");}
  }
  ...
}

[NonPersistent]
public abstract class Person : BusinessObject
{
  public string Vorname;
  public string Nachname;
  ...
}

public class Employee : Person
{
  [Association("CompanyEmployees")]
  public Company Company;
  ...
}

Man benutzt doch die Attribute um die Persistenz zu kontrollieren.

04.10.2005 - 14:41 Uhr

Original von Syks
@ roland:

ich bin gerade dabei mir .net einzuverleiben stosse mich aber immer
an dem immensen zeitaufwand für entwicklungen mit datenbanken,
vielleicht sollt ich sagen das immo auf delphi7 arbeite 🙂
= Query - Dataset - Grid
ein simples und schnelles system

du sprichst oben systeme an welche meinst du zb?
gibt es vergleichbares in .net? (vorallem wenn partialDataloading ne rolle spielt)

tnx for help 🙂

Hi, ich komme auch ursprünglich von der Delphi-Fraktion. 🙂

Muss aber sagen, das wenn man sich mal mit .NET und C# auskennt, die Entwicklung nicht langsamer ist als in Delphi, dafür aber um einiges flexibler.

In diesem Thread handelt es sich um Komponenten die Relationale Daten mit Klassen mappen. Man benutzt in der Applikation dann keine Datensätze mehr, sondern nur noch Objekte (Mal abgesehen das DataRow auch ein Objekt ist).

04.10.2005 - 14:36 Uhr

Und warum sollte deine Fachklasse nicht von XPObject erben?


[NonPersistent]
public class Fachklasse : XPObject
{
   // Fachklasse initialisieren...
}

public class Contact : Fachklasse
{
  public string FirstName;
  public string LastName;
  public string PhoneNumber;
  public string Email;
}

Mit dem Attribute NonPersistent schaltest du die Persistenz für diese Klasse ab, damit keine Tabelle explizit für diese Klasse erstellt wird. So werden alle Informationen aus der Fachklasse in der Tabelle Contact gespeichert.

Ich frage mich halt wieso man die Fachklassen nicht von XPObject ableiten sollte und dann noch zusätzlich Interfaces für weitere Funktionen benutzt.

04.10.2005 - 14:06 Uhr

Vielleicht verstehe ich dich nicht richtig, aber man kann doch eine komplette Vererbungshirarchie mit den PersistentObjects aufbauen. Das sind dann doch die (BusinessObjects) Fachklassen in der Applikation.

Ich werde mir mal andere Frameworks ansehen, damit ich verstehe was du genau meinst.

04.10.2005 - 12:12 Uhr

Dem kann ich nicht ganz zustimmen, denn du kannst deine Datensätze nun ganz easy mit deinen Fachlichen Informationen und Funktionen spicken.

Meine Entwicklungszeit für DbApps hat sich seitdem halbiert. Also ich bin davon begeistert und setze nichts anderes mehr ein.

Aber es steht ja jedem frei nach seinem Geschmack zu wählen! 🙂

03.10.2005 - 22:53 Uhr

Hallo c#pler,

hat jemand von euch schon Erfahrungen mit den PersistentObjects von DevExpress gemacht?

Ich setze diese Komponenten seit einiger Zeit ein und bin hellauf begeistert. Teilt jemand die selbe Meinung mit mir?

Übrigens die anderen Komponenten sind auch richtig gut, da lohnt sich nicht mehr noch eigene zu entwickeln.

Viele Grüße

roland

03.10.2005 - 22:48 Uhr

Dieser Artikel klingt interessant, es ist eigentlich so ähnlich wie ich mir das vorgestellt hatte. Allerdinge glaube ich das hier Probleme mit der Performance auftauchen werden. Deshalb habe ich mich dazu entschieden doch lieber ArrayLists und Collections zu verwenden.