Laden...
Avatar #avatar-2316.jpg
JuyJuka myCSharp.de - Experte
Fachinformatiker: Anwendungsentwicklung Deutschland Dabei seit 30.11.2005 2.187 Beiträge
Benutzerbeschreibung
Ich liebe OO und vor allem OOD. Mit Klassen, Interfaces, Assoziaitonen, Vererbung, Kapselung, Patterns und und und verbring ich meine Arbeits- und meine Freizeit. *stahl*

Forenbeiträge von JuyJuka Ingesamt 2.187 Beiträge

08.06.2012 - 17:59 Uhr

Hallo gfoidl,

Also auf gut Deutsch: Es ist in IL einfach nicht vorgesehen virtuell in die Vererbungshirarchie zu rufen. Es müsste ein spezieller IL-Befehl genau für diesen aufruf existieren. Und das lässt sich nicht einfach so einfügen.

Gruß
Juy Juka

08.06.2012 - 17:54 Uhr

Hallo WPF_Noob,

also wenn du es nutzen kannst, dann nim eine externe Bibliothek. Ist viel einfacher als selber schreiben.

Entity Framework (das Abt genannt hat) kenne ich persönlich nicht so genau aber Oracle und .Net 2.0 sind da schlechte Voraussetzungen (Entity Framewokr gibt's da nur in Version 1 und das auch nur mit SP1 und .Net 3.5 - was eigentlich 2.0 mit aufsatz ist).

NHibernate würde dein Anforderungen locker abdecken, aber der Lernaufwand am anfang ist Höllisch. Du kannst mit Castle ActiveRecord etwas weg nehmen, aber das wird dir nicht lange helfen und wenn was nicht geht hast du noch mehr probleme.

Eigenwerbung 😃
Hier im Forum gibts auch noch ORMs zum benutzen, einer ist z.B. |Aisys| O/R Mapper , er funktioniert mit einigen Oracle-Datenbanken, aber bei Oracle kann man soooo viel mist einstellen, dass ich hier nicht die Hand in's feuer Legen würde.

Gruß
Juy Juka

08.06.2012 - 17:45 Uhr

Hallo Sm|_|,

das einfachste ist (auch wenn es evtl. nicht so wirkt) ein eigenes Event zu deklarieren, welches alle UserControls haben. Die UserControls reagieren auf button_click und so weiter ganz normal und lösen als reaktion (zusätzlich oder nur, wie du willst) das selbst definierte Event aus.

Du brauchst:

  1. Ein interface welches das Event deklariert.
  2. In jedem User Control eine Implementation des Events (am besten mit einer On...-Methode).
  3. Einen Aufruf des Events (oder besser der On...-Methode) in jedem Event/EventHandler den du "weiter leiten" möchtest.

Siehe hier unter Namen für Ereignisse
Events Tutorial (C#)

Gruß
Juy Juka

07.06.2012 - 16:29 Uhr

Hallo WPF_Noob,

hoffentlich habe ich den Thread richtig verstanden. Ich habe den späteren teil nur überflogen und versuche mit deinen Anforderungen einen Vorschlag zu machen:

  1. Du hast eine Haupt-UI die die anderen UI-Elemente dynamisch einbindet.
  2. Die UI-Elemente besitzen jeweil eigene Daten-Elemente.
  3. Die Daten-Elemente müssen auf die Datenbank zugreifen.

1 und 2 sind schon mal gut und funktionieren. Ich würde das UI-Assembly jeweils Präsentationsschicht und das Daten-Assembly Funktionsschicht nennen, da dass die mir bekannten Fachbegriffe sind.

Der Haupt-UI ist es schon zweimal egal woher die Daten kommen, den UI-Elementen ist es ebenfalls egal. Im moment kümmern sich die Daten-Elemente um den Datenzugriff. Jetzt merkt man, dass du vom 3-Schichten-Model nur Präsentations- und Funktionsschicht hast. Du benötigst jetzt also den 3. Teil, die Datenzugriffsschicht.

Wie Abt und MrSparkle schon gesagt haben sollen die Daten-Elemente (aka. Businessschicht) nicht selbst auf die Datenbank zugreifen sonden über eine Datenschicht (aka. die Daten-Elemente dürfen kein SQL erzeugen). Weleche konkrete Dateneschicht du verwendest ist nicht so wichtig. So oder so ist deine Anwendung auf jeden Fall so groß, dass es nicht eine zentrale Klasse/Repository/etc. geben kann. Viel mehr wirst du verschieden Daten-Zugriffs-Assemblies/Klassen/Repositories/etc. benötigen die intern eine gemeinsame Basis-Funktionalität haben (z.B. über Vererbung oder auch über eine Singelton, etc.).

Gruß
Juy Juka

PS: Wenn du uns/mir einige Konkrete PlugIns nennen würdest, könnte man das auch besser darstellen.
PPS: Kannst du eine externe DLL als Datenzugriffsschicht verwenden oder musst du es selber schreiben?

07.06.2012 - 15:41 Uhr

Hallo xell83,

wie FZelle schon sagte ist das eine Entscheidung die man von Fall zu Fall treffen sollte und kann generell eigentlich nicht beantwortet werden.

mcsharp.de ist alleine keine ausreichende Quelle um all Möglichkeiten zu vergleichen und zu bewerten, aber einige Threads zu dem Thema kenn ich und wer weiter lesen will kann es dort:
Daten direkt in Formularfelder spielen oder mittels einer eigenen Klasse?
typed oder untyped Dataset
3-Schichten-Design?? [harte vs. weiche (Daten-)Objekte / OOP vs. ActiveRecods]
((es gibt bestimmt noch mehr interesante Threads zu diesen Themen, die man über die Suche finden kann))

Gruß
Juy Juka

07.06.2012 - 15:29 Uhr

Hallo Norman9494,

Man kann den Typ auch in einer *.settings-Datei (was anderes verbigt sich nicht hinter dem was du da benutzt) manuell eingeben. Es ist ein bischen umständlich, aber in 2 dimensionales Array in Properties.Settings? hab ich es beschrieben.

Gruß
Juy Juka

30.01.2012 - 21:21 Uhr

Hallo boon,

hab es jetzt selber nicht ausprobiert aber vermutlich ist ds DropDown-Ereignis schon zuspät. Er "reserviert" den Platz wo das DropDown gezeichnet wird vermutlich schon früher und wenn dort/dann die DropDown-Höhe noch 0 oder so ist sieht man das geöffnete DropDown nicht.

Also entweder suchst du dir ein Ereignis das vorher auftritt oder musst das DropDown noch mal auslösen nach dem die DropDown-Höhe neu berechnet ist.

Gruß
Juy Juka

30.01.2012 - 15:19 Uhr

Hallo @All,

mit etwas Verzögerung bin ich jetzt einen Schritt (aka. ein Framework) weiter und habe WF4.1 getestet.
Meine Anforderungen werden soweit ich das sehen/ausprobieren konnte nicht ganz erfüllt (06., 07. und 09. werden nur mit Einschränkungen unterstütz).
Aber viel wichtiger ist eh was ich in dem Thread Windows Workflow Foundation 4.1 ; Statemachine ohne Trigger noch offen habe.

Ich hoffe immer noch, dass jemand zu diesen Frameworks mehr erzählen kann/will. Weitere Vorschläge sind ebenfalls herzlich willkommen.

Gruß
Juy Juka

30.01.2012 - 14:51 Uhr

Hallo @All,

mit .Net 4.1 gibt es in der Windows Workflow Foundation auch eine Statemachine aka. State-Pattern. Das gefällt mir so weit ganz gut aber eine Sache gibt mir zu Denken:
Warum gibt es diese komischen Trigger?
Ich könnte auch auf dem Objekt, welches den Status hat, eine Methode aufrufen, um die Transition auszulösen. Das wäre einfacher (kein Threadding) und vermutlich sogar performanter.

Gibt es ein möglichkeit die Statemachine ohne Trigger zu verwenden?

Gruß
Juy Juka

WF, WWF, Statemachine, State-Pattern

26.01.2012 - 14:35 Uhr

Hallo Amosius,

am besten bin ich bis jetzt gefahren in dem ich extra "Deployment-Projekt" angelegt hab, diese haben keinen eigenen Code und löschen die erzeugte Assembly per PostBuild-Befehl aus der Ausgabe, enthalten also nur Verweise und Dateien die ich je Version in's Ausgabe-Verzeichnis kopieren lasse.

Gruß
Juy Juka

26.01.2012 - 14:29 Uhr

Halloo Ahrimaan,

Also eigentlich gibt es nur 3 Möglichkeiten die Klassen von A nach B zu bekommen:

  1. Als Übergabeparameter (Konstruktor oder Methode).
  2. Über eine Konfiguration.
  3. Die ISessionFactoryManager-Implementation sucht selber per Reflection nach den Typen.

1 und 2 liesen sich Sinnvollste kombinieren in dem du deinem Mikrocernel/ServiceLocator/DependencyInjection-Container/Factory über eine Konfiguration mitteilst welche Klassen/Typen beim Instanziieren der ISessionFactoryManager-Implementation übergeben werden sollten.

3 Erfordert keine Konfiguration und funktioniert automatisch, kostet aber am Anfang einen haufen Zeit, da du erst alle Assemblies finden, lesen und reflektieren musst.

Gruß
Juy Juka

26.01.2012 - 13:56 Uhr

Hallo chillic,

Ah, schade, dann ist es doch ein anderer Fehler.

Also folgenden Lösungen gibt es und ich sehe auch keinen Grund keine davon zu nutzen:

  1. Auswahl am GridView aufheben bevor man eine neue Zeile hinzufügt.
  2. view.Table erst auf null setzen (was auch die Auswhahl aufhebt).
  3. Im EventHandler den Index prüfen.

Gruß
Juy Juka

26.01.2012 - 12:02 Uhr

Hallo chilic, Hallo herbivore,

ja, das ist genau das Problem was ich auch schon kenne.

Hier wird im DataBoundItem-Property eine Exception abgefangen, welche das VisualStudio aber bemerkt und den Entwickler informiert, aber die Exception wird nicht wirklich geworfen und die Anwendung stürtzt auch nicht ab, des Property gibt einfach nur null zurück.

Es gibt als nicht wirklich ein Problem, hier hat Microsoft einfach nur try{...}catch(..){return null;} im Quell-Code stehen und das meckert nur Visual Studio an, im Echtbetrieb passiert hier einfach garnix und die Software läuft weiter.

Gruß
Juy Juka

26.01.2012 - 11:40 Uhr

Hallo @All,

Für unsere Firma suchen wir jetzt ein Framework was uns erlaubt das State-Pattern umzusetzen und da habe ich an Workflow-Frameworks gedacht. Hier habe ich bis jetzt nicht viele gefunden und muss diese mir auch noch genauer anschauen, wobei ich bei inigen die ich gefunden habe diese schon jetzt ausschließe (warum schreibe ich mit hin).

Falls hier jemand schon Erfahrungen mit den jeweiligen Frameworks hat würde ich bitten meine Ausschluss-Kriterien zu berichtigen falls ich etwas falsch verstanden habe und falls man das sagen kann ob die Frameworks meine Anforderungen (sieh Kasten unten)

  • Workflowgen
    Ist Raus, weil es fest mit der UI (WebForms) verbunden ist und wir ein Framework für die Funktions-Schicht suchen.

  • Windows Workflow Foundation (.Net 4.0)

  • Stateless

  • K2[blackpearl]
    Ist wegen der Lizenz pro Installation raus (keine Entwicklungs-Lizenz).

  • objectflow

Gruß
Juy Juka


Anforderungen an das Workflow-System/State-Pattern:

01. Statis müssen frei definierbar sein.
02. Zu jedem Status müssen frei mögliche Aktionen/Operatione definierbar sein.
03. Einer Aktion/Operation muss eine konfigurierbare Bedingung voraus gehen, die verhindert das die Aktion ausgeführt wird.
04. Einer Aktion/Operation muss Quell-Code hinterlegt werden (am besten als Klasse).
05. Einer Aktion/Operation muss eine Konfiguration für den hinterlegten Quell-Code mitgegeben werden (Konfigurations-Zeit).
06. Einer Aktion/Operation muss vor/während der Ausführung Parameter/Eingaben anfordern können (Lauf-Zeit).
07. Der einer Aktion/Operation hinterlegter Quell-Code muss eine beliebige anzahl Ergebnisse zurück liefern können.
08. Pro Ergebniss müssen viele Folge-Stati hinterlegt werden können, die Anhand einer konfigurierbaren Bedingung ausgewählt werden.
09. Muss mehr als ein Stück Quell-Code pro Akton/Operation ohne zutun des Benutzers ausgeführt werden, soll dies gut sichtbar im Workflow sein*.
10. Namen von Statis und Aktionen/Operationen müssen frei vergeben werden können (Doppelt usw.).
11. Es müssen mehrer Prozesse/Workflows gleichzeitig hinterlegbar sein.
12. (optional) Der Vortschritt der Workflow-Items im Prozess/Workflow soll protokolliert werden.

\* Hinterlegt werden kann es ja sowieso (durch Dekorator-Pattern oder so), wenn Anforderung 04 erfüllt ist.

PS: Ich hoffe das diese Anfrage nicht zu allgemein ist, bin mir nicht ganz sicher ob ich so was hier im Forum fragen darf.

26.01.2012 - 10:09 Uhr

Hallo wickedcsharper,

also Reflection ist nicht OldSchool, man kann davon ausgehen, dass alle .Net ORM Reflection einsetzen. Wir hatten auch einen selbst geschriebenen ORM und als wir dann auf NHibernate/ActiveRecord umgestiegen sind musste ich so lachen weil die Klassen/Methoden/etc. zu 99% gleich mit meinem ORM waren (von der Funktionalität her, die Namen waren leicht abweichend).

ORMs wie NHibernate und EntityFramework usw. haben einfach den Vorteil, dass viele Leute daran schon gearbeitet haben und die ganzen nützlichen Funktionen die man sich für seinen eigenen ORM wünscht (aber nicht so wichtig sind dass man sie sofort einbaut) schon eingebaut hatt:

  • Chaching (für SQL-Abfragen und Objekte)
  • SqlParameter
  • IDisposable
  • System.Reflection.Emit
  • Chaching (für Reflection-Informationen)

Also ich empfehle dir Hardnäckig zu bleiben und deinem Kollegen zu sagen, dass die ORMs eben das gleiche machen wie seiner nur ausgearbeiteter.

Gruß
Juy Juka

26.01.2012 - 10:00 Uhr

Hallo chilic,

Dieses Verhalten glaube ich zu kennen.
Kannst du dich erinnern ob im Debugger wenn er an dieser Stelle angehalten hat die Code-Zeile grün oder gelb markiert war?

Gruß
Juy Juka

22.01.2012 - 18:03 Uhr

Hallo @All,

Über IList<T>, IEnumerable<T> und BindingList<T> wurde ja schon genug erzählt aber INotifyPropertyChanged wurde hier völligst ignoriert.

Die Liste implementiert INotifyPropertyChanged vermutlich nicht aber die Objekte/Klassen die eine Assembly zurück gibt könnten dieses Interface implementieren, da es ansonsten ein unglaublicher aufwand ist wenn die Objekte an einer stelle eingesetzt werden wo dieses Obeserver-Pattern verwendet wird (z.B. Win-Forms). Nicht jede Klasse muss INotifyPropertyChanged implementieren, aber bei jeder Klasse ist es eine Überlegung wert es zu tun (meiner Meinung nach).

@Lothi: Sind die geparsten Objekte die du zurück gibst von einer Klasse aus deinem Assembly oder von extern? Wenn ja würde ich wirklich mal überlegen ob INotifyPropertyChanged implementiert werden soll.

Gruß
Juy Juka

17.01.2012 - 16:17 Uhr

Hallo nevermind10844,

In dem du Form2 ein öffentliches Property oder eine öffentliche Methode gibst, die das gesuchte Objekt erstellt/zurückg gibt.

Gruß
Juy Juka

17.01.2012 - 06:11 Uhr

Hallo HappyLil,

Du scheinst alles schon richtig verstanden zu haben. Vielen dank für die Mühe.

Eine eigene art von Transaktion ist mein Workaround und funktioniert auch im moment. Es ist halt ein riesen Aufwand mit einem dutzend If-Anweisungen und fast genauso vielen zusätzlichen Properties die ich speichern muss. Ich hatte einfach auf eine elegantere Methode gehofft.

Gruß
Juy Juka

12.01.2012 - 07:23 Uhr

Hallo @All,

neuerdings arbeite ich mit Controls von ComponentOne und hier mit dem C1.Win.C1TrueDBGrid.C1TrueDBGrid.
Wenn ich einfach nur meine BindingList<T> anbinde funktioniert es aber wenn ich vorher Spalten mit new C1DataColumn() manuell erzeuge wird nichts angezeigt (keine Zeilen, keine Splaten).

Ich habe schon die Methode SetBindings gefunden und wie folgt benutzt, was aber leider keine Veränderung bewirkt hat.


this.c1TrueDBGrid.SetDataBinding(Mikrokern.Erstellen<BindingList<T>>(), null, true);
((BindingList<T>)this.c1TrueDBGrid.DataSource) += (sl, el) => {
  object o = this.c1TrueDBGrid.DataSource;
  this.c1TrueDBGrid.DataSource = null;
  this.c1TrueDBGrid.SetDataBinding(o, null, true);
  };

Ich hab auch versucht auf einer Test-Form das Steuerelement per Designer zu erstellen und die Spalten hinzuzufügen, diese werden dann auch angezeigt (wenn ich SetDataBinding(...,...,true) verwende) aber leider kann ich leider im QuellCode des Designers nichts sehen, da die Columns nicht als C#-Code sondern als XML hinterlegt werden (und im XML stehen auch nur die Properties Caption und DataField die ich auch setze).

Kennt sich jemand mit dem C1TrueDBGrid aus und kann mir hier bei helfen?

Gruß
Juy Juka

12.01.2012 - 07:07 Uhr

Hallo el_vital,

Das hört sich nach dem Bilderbuch-Fall für XSLT (XML Transformation) an, wobei man in einem XML (<-Konfigurierbar) Soll- und Ist-Zustand beschreibt und der XSLT-Transformator (.Net hat einen mit dabei) das ganze Umbauen übernimmt.

Lass dir hier mal von Google, Wiki und Co. helfen.

Gruß
Juy Juka

[EDIT]
XSL Transformation
[/EDIT]

09.01.2012 - 12:30 Uhr

Hallo macFish,

Für eine Id-Abfrage gibt es viel besser Methoden in NHibernate:


NHibernate.ISession s = ...; 
return s.Get<T>(id); 
// oder
return s.Load<T>(id);

(Eine von beiden Macht garkeinen SQL wenn das Objekt schon in der Session geladen ist, das andere fragt noch mal in der DB an.)

Gruß
Juy Juka

07.01.2012 - 15:43 Uhr

Hallo inflames2k,

Wieso keine Aufgabenplanung, wenn's eh auf dem Server läuft?
Ich hab damit noch keine Probleme gehabt.

Gruß
Juy Juka

06.01.2012 - 23:26 Uhr

Hallo inflames2k,

So was hatte ich auch schon und hab es dadurch gelöst, meine "threads" über Windows-Aufgaben-Planung (früher Geplante Tasks) starten zu lassen. Diese können ja auch Zyklisch laufen, können überwachen und im notfall neu starten.

Leider bin ich mit bei deinem Problem nicht sicher ob sich das anwenden lässt, ich hatte den vorteil das auf dem Server einzurichten und die Ergebnisse einfach in der Datenbank zu speichern, bei dir sieht's ja ehr nach Client-Seite aus.

Gruß
Juy Juka

06.01.2012 - 05:23 Uhr

Hallo Quaneu,

Wenn du mit "Typ" wirklich die Klasse meinst, dann wär ein Singelton mit statischem Property und so schon die sauberstes Lösung.
Aber ich hab die vermutung, dass du eben nicht die Klasse meinst.

So oder so, wollte ich hier noch die System.Windows.Forms.Application.OpenForms Collection erwähnen, immer sehr nützlich bei solchen Themen.

Gruß
Juy Juka

05.01.2012 - 09:33 Uhr

Hallo Gonzo,

Ich glaube du suchst SystemColors.
Vermutlich SystemColors.Control, aber das probierst du lieber mal selber aus.

Gruß
Juy Juka

04.01.2012 - 01:15 Uhr

Hallo Pentrit,

Am besten würde sich das ganze dadurch lösen lassen, dass du die einzulesenden Resourcen an deine DLL übergeben lässt, wer auch immer die DLL nutzt ruft ja irgend wo eine Methode/einen Type/etc. aus ihr auf.

Ansonsten müsste System.Reflection.Assembly.GetManifestResourceNames und System.Reflection.Assembly.GetExecutingAssembly eine hilfe für dich sein. Das ganze hat aber eben mehr Einschränkungen als wenn du die Resourcen übergiebst.

Gruß
Juy Juka

03.01.2012 - 00:00 Uhr

Hallo WinstonSmith,

es gibt noch eine Möglichkeit wie man die Kommandos Gruppieren kann.
Man kann jedes Kommando als eine eigene Klasse schreiben.
Gruppiert wird per Namensraum.
Gemeinsame Eigenschaften landen in einer Basisklasse von der alle Kommandos erben (Ich würde auch noch ein Interface IKommando empfehlen).
Zum Übertragen kann man allen Kommandos eine ToCharArray()-Mehtode geben.

Gruß
Juy Juka


public interface IKommando
{
  char[] ToUebertragung();
}

public abstract class Kommando : IKomando
{
  ... //was halt alle haben
}

public class PauseKommando : Kommand 
//Ich erfinde hier einfach mal eine Paus-Funktion als Beispiel
{
  public TimeSpan PausenLaenge{get;set;} // Variable Teile können dann als Properties implementiert werden, müssen nur in der ToUebertargung()-Mehtode berücksichtigt werden
}

02.01.2012 - 22:58 Uhr

verwendetes Datenbanksystem: NHibernate/ActiveRecord

Hallo @All,

wiedermal hab ich ein NHibernate/Castle.AcvtiveRecord Problem.

  • Ich habe ein Do/Undo-Szenario.
  • Es werden mehrer Objekte "gleichzeitig" erzeugt.
  • Eines der erzeugten Objekte verweist auf ein anderes erzegutes Objekt.
  • Die Do/Undo-Befehle sind genauso wie die Objekte die angelegt werden Persisten.
  • Die erzeugten Objekte werden ehr aus der Datenbank gelöscht als die Do/Undo-Befehle, deshalb haben die Do/Undo-Objekte keine refernz auf die erzeugten Objekte, sondern nur die Primärschlüssel.

Das Problem ist jetzt, wenn ich das "zweite" Objekt erzeuge muss ich irgend wie auf das "erste" Objekt zugreifen, welches im besten Fall transient ist und im schlimmsten Fall noch nicht angelegt!
Wenn ich also ein Select/Load mit NHibernate/ActiveRecord mache findet er mir das "erste" Objekt nicht (egal ob transient oder garnicht existent).

Was ich suche ist jetzt ein Best-Practice oder so etwas, bevor ich ein riesen Workaround für das ganze schreibe. (oder Suchbegriffe mit denen ich die Suchmaschienen noch füttern könnte.)

Gruß
Juy Juka

PS: Falls sich jemand für das Workaround interesiert, bitte per PN melden.

16.12.2011 - 00:42 Uhr

Hallo @All,

Nur Controls tanzen zu lassen war mir zu langweilig. 😉
Also hab ich gleich weiter gemacht und Version 1.1.0.0 gemacht. 😁

Ich habe ein Fluent-Interface für die Bewegungen hinzugefügt:


JuyJuka.ControlBewegung.Fluent.
Neue.Bewegung()
  .NachXMinusUm(100)
  .NachYPlusUm(100)
  .NachXPlusUm(100)
  .NachYMinusUm(100)
  .In(this.bewegungAusfuehrer1)
  .OhneParrentSperre()
  .BeschleunigtMit(30)
  .PausiertUm(10)
.GefolgtVon()
  .NachXMinusUm(100)
  .NachYPlusUm(100)
  .NachXPlusUm(100)
  .NachYMinusUm(100)
  .Von(this.button1)
  .OhneParrentSperre()
  .PausiertUm(10)
  .BeschleunigtMit(3)
  .Starten();

Und weil's so schön ist gleich auch noch eine Skriptsprache angefügt. Skripte kann man mit dem neuen BewegungsParser ein- und ausgeben lassen.


x+ 100 / 1
y+ 99 / 33
x- 100 / 10
y- 99 

y+ 0 / 0 Alternativ gibt es noch eine schreibweise mit Pfeilen (siehe Anhang)

Bei dem ganzen ist auch noch eine hübschere ToString-Methode für die BewegungsSchritt-Klasse rausgesprungen, die man auf dem Screen-Shot oben bewundern kann. 😉

Alle Downloads wurden aktualisiert und immer noch gilt: Ich freu mich über Kritik, Verbesserungsvoschläge und Verbesserungen (als Quellcode hochgeladen).

Gruß
Juy Juka

15.12.2011 - 22:29 Uhr

Hallo @All,

und weil ich euch kenne 😉 und weil ich hoffe, dass ihr meine Fehler im Code noch findet, kommt hier die Projekt-Mappe.

Gruß
Juy Juka

PS: falls jemand Bilder zu einem animierten Gif zusammen setzen kann, würd ich mich freuen wenn er ein Gif von der Demo-Applikation machen könnte. Danke.

15.12.2011 - 22:27 Uhr

Hallo,

wie immer schade um den Dopplepost, aber zwei Dateianhänge brauchen zwei Posts.

Man kann mit der Komponente einstellen *(Control)Welches Control wandern soll. *(Schritte) Ist ein Array von Schritten die nach einander durchlaufen. *(Schritte.Richtung)Wohin es wandern soll
-XPlus = Rechts
-XMinus = Links
-YPlus = Unten
-YMinus = Oben

*(Schritte.GesamtLaenge)Wie weit es wandern soll *(Schritte.EinzelLaenge) Wie weit es auf einmal wandern soll *(DisableParent)Bestimmt ob das Übergeordnete Control ebenfalls wärend der Wanderung deaktiviert ist (sicher ist sicher) *(EinzelSchrittZeit)Bestimmt wie lange das Control wartet bis es noch einen Bewegung mach, bis es den gesamte Bewegung des Schrittes beendet hat. *(Vorgaenge)Wie man mit dem Array von Schritten mehrer Bewegungen für ein Control machen kann, so kann man durch das Anhängen einer weiteren BewegungAusfuehrung mehrer Kontrols wandern lassen. *(Wartezeit) Wenn mann nach dem aufrufen von Start noch etwas verzögern will.

Alle Zeit-Angaben sind in Millisekunden.

**Tipp:**Sollen die Controls hintereinander her, einfach die ersten BewegungAusfuehrung konfigurieren und dann mit Strg+C und Strg+V für die Anderen Controls kopieren und mit Vorgaenger verknüpfen.
**Tipp:**Wenn man den Vorgaenger auf sichselbst setzt, wandert das Control unaufhöhrlich.

Wenn alles fertig Konfiguriert ist, einfach mit .Start() (z.B. in Form_Load oder Button_Click) los laufen lassen.

Gruß
Juy Juka

15.12.2011 - 22:14 Uhr

Hallo @All,
Beschreibung:

Gerade hatte ich etwas Zeit und Lust zu Programmieren und da hat mich folgender Thread Bewegen mehrerer Controls per Schleife und Timer auf die Idee gebracht eine Komponente zu schreiben, welche es ermöglicht die Bewegung eines Controls über die Maske zu definieren und auch auszuführen.

Eine kleine Demo und die DLL findet Ihr als Anhang.

Gruß
Juy Juka

Schlagwörter: System.Windows.Forms, Control, Bewegen

15.12.2011 - 21:11 Uhr

Hallo UNeverNo,

Du kannst DataBinding auch dynamisch erstellen:


checkBox.DataBindings.Add("Checked",objekt,propertyName);

D.h. du musst beim dynamischen Erzeugen eh die Properties durch gehen und kannst dann gleich die Zeile mit ausführen. (Wobei hier ein UserControl aus ImmageBox und CheckBox vielleicht sinnvoll wäre.)

Gruß
Juy Juka

11.12.2011 - 23:34 Uhr

Gibt es keine besseren Lösungen für Windows Forms und WPF?

Der Designer erzeugt (automatisch) einzelne Variablen, eine für jede TextBox, ComboBox, ..., eben für jedes Steuerelement. Das kann man nicht umgehen, es sei denn, man verzichtet auf den Designer. Natürlich könnte man den Inhalt der einzelnen Variablen - wie oben gezeigt - in ein Array oder eine Liste schreiben, aber zuerst müssen wir uns einige Fragen stellen.

Kommt man mit einem Listen-Control einfacher und besser ans Ziel?

Windows Forms und auch die Windows Presentation Foundation (WPF) haben für die häufigsten Aufgaben, die man mit einem Array von Steuerelementen lösen könnte, eine bessere Lösung mit nur einem Steuerelement. Diese Steuerelemente nennt man Listen-Controls, da sie eben Listen von Daten darstellen und/oder bearbeiten können. Diese Steuerelemente sind für den Programmierer einfacher zu handhaben, für die Benutzer vertrauter und für das System einfacher/performanter darzustellen als eine Menge einzelner Steuerelemente.

Welche Listen-Controls gibt es und wofür eignen sie sich am besten?

Hier folgt eine Auflistung der Windows Forms Listen-Controls, zusammen mit einer kurzen Zusammenfassung was das Steuerelement kann und was der typische Anwendungsfall ist. Für WPF gibt es immer vergleichbare Steuerelemente, oft sogar mit dem gleichen Namen. Man muss sich also nur noch fragen: Welches dieser Steuerelement passt für meinen Anwendungsfall am besten?
*ListBox

Die ListBox kann eine Liste von Werten anzeigen und erlaubt dem Benutzer einen oder mehrere Werte zu markieren (normal: blauer Hintergrund) und damit auszuwählen. Direkt ändern kann der Benutzer die Werte nicht.

Tipp: Mehrspaltig? Gleich zu DataGridView (oder ListView im Details-Modus) gehen.

*ComboBox

Die ComboBox erlaubt wie eine TextBox eine Eingabe über die Tastatur und über eine ausklappbare Liste ähnlich einer ListBox eine Auswahl aus vorhandenen Werten. Der Name erklärt sich aus der Kombination einer TextBox mit einer (ausklappbaren) ListBox.

Üblicherweise wird die ComboBox verwendet, um dem Benutzer zu erlauben ein einzelnes Element auszuwählen, ohne dabei viel Platz auf dem Form zu verbrauchen. Zur reinen Anzeige einer Liste ist das Steuerelement nicht geeignet. Es fällt also etwas aus der Reihe der anderen Listen-Controls heraus.

Tipp: Mit ComboBox.DropDownStyle = DropDownList kann die ComboBox so eingestellt werden, dass der Benutzer nur auswählen kann, aber nichts eingeben.

*CheckedListBox

Die CheckedListBox arbeitet wie eine ListBox, aber mit der Erweiterung um eine CheckBox für jedes Element. Der Benutzer kann also Elemente auswählen wie in einer ListBox, aber auch Elemente mit einem Häkchen markieren/auswählen. Dies hat den Vorteil, dass die Auswahl per Häkchen nicht durch einen unbedachten Klick verloren gehen kann, wie die das bei einer normalen Markierung (blauer Hintergrund) der Fall ist.

Üblicherweise wird die CheckedListBox verwendet, wenn man eine Liste von Optionen hat und/oder der Benutzer eine Mehrfachauswahl treffen soll.

Tipp: Mit CheckedListBox.CheckOnClick = true kann der Benutzer auch auf den Text klicken, um das Häkchen für das Element zu setzen oder zu entfernen.

*ListView

Das ListView kann eine Liste von Elementen in verschiedenen Ansichten darstellen, mit Icons, Gruppen und zusätzlichen Informationen und mehr.

Üblicherweise wird eine Auswahl von Elementen, die detaillierte Informationen haben oder zusätzlich gruppiert werden müssen, hiermit dargestellt, z.B. die Dateien im Windows-Explorer. Das ListView dient überwiegend zur Anzeige von Daten. Ändern kann der Benutzer nur die Informationen in der ersten Spalte und auch das nur dann, wenn der Programmierer das durch ListView.LabelEdit = true erlaubt hat.

Tipp: Die verschiedenen Ansichten werden über ListView.View eingestellt.

Tipp: Bei ListView.View = Details sieht man erst dann etwas, wenn man mindestens eine Spalte in ListView.Columns definiert hat.

*DataGridView

Das DataGridView kann Daten als Liste mit mehreren Spalten darstellen und auch bearbeiten, wobei beim Bearbeiten sogar andere Steuerelemente in die Zelle eingeblendet werden können (z.B. ComboBox).

Üblicherweise wird das DataGridView immer für mehrspaltige Ansichten verwendet. Mit dem DataGridView können alle Arten von tabellarischen Daten angezeigt und bearbeitet werden. Es ist (vom PropertyGrid abgesehen) das einzige Listen-Control, das eine direkte Bearbeitung aller Daten durch den Benutzer ermöglicht.

*TreeView

Das TreeView kann eine hierarchische/baumartige Struktur von Elementen darstellen, deren Unterelemente man aufklappen und einklappen kann.

Üblicherweise werden mit dem TreeView nur hierarchische Darstellungen abgebildet, z.B. die Ordner im Windows-Explorer.

Tipp: Die Elemente im TreeView, die TreeNodes, haben eine Tag-Property, in welcher man die Daten, die zu dem Element gehören, ablegen und so einfach darauf zugreifen kann.

Tipp: Im Event AfterSelect des TreeViews kann man auf die Auswahl eines TreeNode reagieren und z.B. dynamisch weitere TreeNodes hinzufügen (lazy loading).

*PropertyGrid

Das PropertyGrid fällt etwas aus der Reihe. Es stellt nicht eine Liste von (gleichartigen) Daten dar, sondern eine Liste von (unterschiedlichen) Properties eines Objekts.

Üblicherweise kommt das PropertyGrid in Programmen für Endanwender selten zum Einsatz, wobei es sich für das Anzeigen und Ändern von Einstellungen/Optionen und auch in vielen anderen Fällen durchaus gut eignen würde.

Tipp: Die Anzeige des PropertyGrid kann sehr umfassend beeinflusst werden, nicht nur in Bezug auf die angezeigten Namen für die Properties, Kategorien usw., sondern man kann sogar eigene Editoren für bestimmte Arten von Properties definieren, z.B. für eine Farbauswahl.

**
Was wenn keins der Listen-Controls für meinen Anwendungsfall passt?**

Das ist unwahrscheinlich! Insbesondere mit dem DataGridView lässt sich fast alles realisieren, was mit der Anzeige, dem Auswählen und dem Anzeigen von tabellarischen Informationen zu tun hat.

Bevor man daran denkt, ein Form aus einer Menge einzelner, gleichartiger Controls auszubauen, sollte man wissen, dass es unter Windows Forms schon ab wenigen hundert Controls, zu ernsthaften Performance-Problemen und anderen Schwierigkeiten kommen. Man sollte also auf die Vorgehensweise, die oben für den allgemeinen Fall beschrieben wurde, überhaupt nur dann zurückgreifen, wenn die Anzahl der Controls überschaubar ist und bleibt. Ansonsten sollte man auf Listen-Controls zurückgreifen oder erwägen, den Inhalt der Forms selber zu zeichnen, siehe [Tutorial] Zeichnen in Windows-Forms-Programmen.

Wie kann man - alle Warnungen im Sinn - die Designer Elemente in ein Array übertragen?

Da Steuerelemente Referenztypen sind, kann man sie in mehrere Variablen gleichzeitig speichern. Jede Variable referenziert dann dasselbe(!) Steuerelement, d.h. der Designer erzeugt seine Variablen textBox1, textBox2, ... und wir übernehmen anschließend eine Referenz darauf in unsere Liste:


   // Hier wird das Array in nur einer Anweisung initialisiert und befüllt
   // Vorteilhaft ist das vor allem, weil der Compiler die Anzahl der Elemente
   // selbst erkennt, sodass nachträgliches Einfügen/Entfernen keine Gefahr 
   // einer Falsch-Dimensionierung birgt.
   TextBox[] textBoxes = new TextBox[] { this.textBox1, this.textBox2, this.textBox3 };

   string gesammelterText = string.Empty;
   for(int i = 0; i < textBoxes.Length; i++)
   {
      gesammelterText += textBoxes[i].Text;
   }
   MessageBox.Show(gesammelterText);  

Das ist nur ein Beispiel. Man kann noch viel mehr machen, als nur den Text auszulesen.

Ganz wichtig: Die Textboxen kann man erst in die Liste packen, nachdem der Designer sie erzeugt hat, also nach dem Aufruf von InitializeComponent()

Kann man nicht direkt auf die Controls-Collection zugreifen?

Das könnte man zwar, aber mehrere Gründe sprechen dagegen:
*Die Elemente der Controls-Collection habe den (statischen) Typ Control. Um auf spezielle Eigenschaften z.B. einer TextBox zugreifen zu können, muss man erst casten, was nicht nur unschönen und sperrigen Code erfordert, sondern auch immer das Risiko eines InvalidCastException birgt. *In der Controls-Collection sind alle (Arten von) Controls enthalten, die sich direkt auf dem Form befinden und nicht nur die ausgewählten, die wir in dem obigen Beispiel explizit in das Array übertragen haben. Das ist nicht nur störend, wenn von von Anfang an andere Controls vorhanden sind, sondern verschiebt auch die Indizes, wenn später weitere Controls hinzukommen. *Anderseits kann man über die Controls-Collection dann nicht direkt auf alle Steuerelemente zugreifen, wenn diese auf Container-Controls (Panel, GroupBox, SplitContainer, ...) platziert sind, deren Controls-Collection man nun ebenfalls berücksichtigen müsste (Rekursion). *Beim unschönen Zugriff über den Namen der Controls muss man diesen erst als String zusammensetzen. Das ist fehleranfällig, wird erst zur Laufzeit geprüft und ist insgesamt nicht besonders professionell.

Die Controls-Collection ist eher für das Framework gedacht, und man sollte sie besser nicht im eigenen Code benutzen, es sei denn, man erstellt dynamisch zur Laufzeit Steuerelemente. Dann muss man diese natürlich der Controls-Collection hinzufügen, damit sie angezeigt werden.

Wie kann man - weiter alle Warnungen im Sinn - dynamisch Controls erstellen?

In seltenen Fällen kann es sinnvoll sein, Controls dynamisch zu erstellen. Wie das geht, zeigt der folgende Code. Im Grunde wird dabei nur der Code, den Visual Studio für die Erzeugung eines einzelnen Controls generiert, in eine Schleife gepackt. Dabei sollte man aber weiter alle oben genannten Warnungen im Sinn behalten und diese Technik insbesondere nicht als Ersatz für ein Listen-Control verwenden.


   List<Button> buttons = new List<Button> ();

   for(int i = 0; i < 10; i++)
   {
      buttons.Add (new Button ());
      buttons[i].Text = "Aktion " + i;
      buttons[i].Location = new Point (10, 10 + i * buttons[i].Height * 3 / 2)
      buttons[i].Click += AllButtonsClick;
      this.Controls.Add(buttons[i]);
   }

protected void AllButtonsClick (Object sender, EventArgs e)
{
   Button buttonClicked = (Button)sender;
   // ...
}

**
Welche der gezeigten Möglichkeiten sollte man wählen?**

Die erste Wahl sollte immer die Verwendung des passenden Listen-Controls sein.

In Fällen, wo dies nach gründlicher Prüfung nicht in Frage kommt, hängt es ein bisschen von der Art und Anzahl der Controls ab. Die Anzahl sollte wie gesagt, eng begrenzt sein und auf keinen Fall darf sie beliebig wachsen. Wenn man mehr als 100 Controls erstellen will, ist es definitiv der falsche Weg. Ein Array von PictureBoxen zum Anzeigen eines Fotoalbums, das beliebig viele Bilder enthalten kann, ist selbst dann der falsche Weg, wenn die meisten Fotoalben nur einige wenige Bilder enthalten. Maßgeblich ist also immer die Zahl der Controls im Worst Case.

Wenn es um relative wenige Controls der gleichen Art geht (vielleicht 3 bis 5), deren Anzahl zudem fest ist, kann man diese mit dem Designer erzeugen und dann wie oben gezeigt in eine Liste füllen.

Wenn es um eine etwas größere Menge von gleichartigen Controls geht (vielleicht 6 bis 20) oder deren Anzahl variabel, aber begrenzt ist, sollte man diese besser wie gezeigt dynamisch in einer Schleife erzeugen.

Wenn es um noch größere Mengen an Controls ginge, dann sollte man diese weder mit dem Designer noch dynamisch erzeugen, sondern ganz vermeiden, z.B. indem mal alles selber zeichnet.

Die Autoren

Dieser Text ist eine Gemeinschaftsproduktion von herbivore und JuyJuka. Darin sind Verbesserungsvorschläge von FZelle, gfoidl und Th69 eingeflossen. Alle Namen in alphabetischer Reihenfolge.

06.12.2011 - 16:18 Uhr

Hallo BloodyLove,

suche mal (Google) nach NHibernate, dass sollte mit jedem VisualStudio 2010 funktionieren.
Oder wenn du magst kannst du auch meinen ORM |Aisys| O/R Mapper verwenden.

Gruß
Juy Juka

06.12.2011 - 14:12 Uhr

Hallo BloodyLove,

Alles habe ich nicht verstanden, aber erst mal einen OR-Mapper zu verwenden ist sinnvolle und ist überhaupt kein grund zum schämen.

Gruß
Juy Juka

06.12.2011 - 04:29 Uhr

Hallo BloodyLove,

Das IDictionary<int,?> ist nich immer falsch aber das kommt ganz auf die Sichtbarkeit/den Gültigkeitsbereich an.
Normalerweise sollte ich mir immer nur die Objekte laden, welche ich auch wirklich brauche (wird auch Lazy Loading genann), daher muss ich nicht in den geladenen Listen im Arbeitsspeicher suchen.
d.h. wenn dein IDictionar<int,?> static ist, ist sein Gültigkeitsbereich viel zu groß. Wenn dein IDictionar<int,?> eine Instanz-Variable ist oder sogar nur lokal in enier Methode geladen wird, muss man das immer noch überlege, aber die Warscheinlichkeit dass es richtig ist ist höher.

((Pseudo Beispiel Code


public class Bausatz : IBausatz
{
  private IList<IBauteil> _BauteilListe;
  public virtual IList<IBauteil> BauteilListe
  {
    get
    {
      if(this._BauteilListe==null) this._BauteilLiset = this.LadeBauteilListe();
      return this._BauteilListe;
    }
  }
  
  private IList<IBauteilListe> LadeBauteilListe()
  {
     // Alle Bauteile die zu diesem Bausatz gehören laden, nicht alle möglihcen Bauteile
     ...
  }
}

Ich empfehle dir einen fertigen O/R Mapper zu verwenden, da hier viele Fehler eben gleich vermieden werden. Aber aus OO-Sicht ist es eigentlich egal wie du an deine Objekte kommst, darfst diese natürlich selber zusammen bauen, wenn du einen Grund dafür hast.

Und mach dir keine Sorgen wegen 3-Schichten beim ersten Projekt, ja das Projekt wird länger dauern ABER du wirst es schaffen und danach wissen wie man es macht und das ist es wert.

Gruß
Juy Juka

04.12.2011 - 04:02 Uhr

Hallo joshua,

wegen der Vollständigkeit sei erwähnt, dass es beide Varianten gibt.
Details findet man utner folgenden Links:
typed oder untyped Dataset
3-Schichten-Design?? [harte vs. weiche (Daten-)Objekte / OOP vs. ActiveRecods]

Gruß
Juy Juka

01.12.2011 - 15:53 Uhr

Hallo FZelle,

Das es an meinem Code liegt ist mir klar. Ich kann nur mit dem StackTrace nix anfangen. Ich finde den Teil meines Codes nicht der nicht funktioniert (bzw. den DataGridView an jener stelle dazu bringt den Fehler zu werfen).
Mein Code liest in der DB, öffnet ein Fenster wenn das Ergebnis nicht eindeutig ist und ändert dann ein anderes Property des gebundenen Objektes (implementiert kein INotifyPropertyChanged) mit dem eindeutige/ausgewählten Ergebnis. Die Rückgabe des Parsing wird dann auch noch so angepasst wie die Auswahl/das Ergebnis ist.

Gruß
Juy Juka

01.12.2011 - 11:45 Uhr

Hallo herbivore,

Da hab ich mich zu undeutlich ausgedrückt.
Das AddingNew hab ich vorher behandelt und das Element selbst erzeugt.
Wollte nur wissen ob da was schief gehen kann.

Gruß
Juy Juka

01.12.2011 - 10:35 Uhr

Hallo @All,

Ich habe mich an CellParsing einer Zelle im DataGridView angehängt. Mein Parsing-Code läuft auch erfolgreich durch, aber so bald sich der DataGridView danach neu Zeichnet schmiert mir das ganzes System ab und ich lande in meiner Main-Methode.


ArgumentOutOfRangeException {"Der Index lag außerhalb des Bereichs. Er muss nicht negativ und kleiner als die Auflistung sein.\r\nParametername: index"}

   bei System.Collections.ArrayList.get_Item(Int32 index)
   bei System.Windows.Forms.DataGridViewRowCollection.SharedRow(Int32 rowIndex)
   bei System.Windows.Forms.DataGridViewRowCollection.get_Item(Int32 index)
   bei System.Windows.Forms.DataGridView.PushFormattedValue(DataGridViewCell& dataGridViewCurrentCell, Object formattedValue, Exception& exception)
   bei System.Windows.Forms.DataGridView.CommitEdit(DataGridViewCell& dataGridViewCurrentCell, DataGridViewDataErrorContexts context, DataGridViewValidateCellInternal validateCell, Boolean fireCellLeave, Boolean fireCellEnter, Boolean fireRowLeave, Boolean fireRowEnter, Boolean fireLeave)
   bei System.Windows.Forms.DataGridView.EndEdit(DataGridViewDataErrorContexts context, DataGridViewValidateCellInternal validateCell, Boolean fireCellLeave, Boolean fireCellEnter, Boolean fireRowLeave, Boolean fireRowEnter, Boolean fireLeave, Boolean keepFocus, Boolean resetCurrentCell, Boolean resetAnchorCell)
   bei System.Windows.Forms.DataGridView.CommitEditForOperation(Int32 columnIndex, Int32 rowIndex, Boolean forCurrentCellChange)
   bei System.Windows.Forms.DataGridView.ScrollIntoView(Int32 columnIndex, Int32 rowIndex, Boolean forCurrentCellChange)
   bei System.Windows.Forms.DataGridView.TabToNextCell()
   bei System.Windows.Forms.DataGridView.ProcessTabKey(Keys keyData)
   bei System.Windows.Forms.DataGridView.ProcessDialogKey(Keys keyData)
   bei System.Windows.Forms.Control.ProcessDialogKey(Keys keyData)
   bei System.Windows.Forms.Control.ProcessDialogKey(Keys keyData)
   bei System.Windows.Forms.TextBoxBase.ProcessDialogKey(Keys keyData)
   bei System.Windows.Forms.Control.PreProcessMessage(Message& msg)
   bei System.Windows.Forms.Control.PreProcessControlMessageInternal(Control target, Message& msg)
   bei System.Windows.Forms.Application.ThreadContext.PreTranslateMessage(MSG& msg)
   bei System.Windows.Forms.Application.ThreadContext.System.Windows.Forms.UnsafeNativeMethods.IMsoComponent.FPreTranslateMessage(MSG& msg)
   bei System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
   bei System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
   bei System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
   bei System.Windows.Forms.Application.Run(Form mainForm)
   bei aisys.xStorage.UI.Program.Run() 
   bei aisys.xStorage.Klassenbbibliothek.Programm.Main() 

Falls jemand fragt: Wenn ich andere Datensätze darstelle, die schon den "ge-parsten" wert haben und nicht ändere geht das.

Hat jemand eine Idee wie ich an mehr informationen komme? Wurde hier evtl. der StackTrace abgeschnitten? Hat es etwas mit BindingList.AddingNew zu tun?

Gruß
Juy Juka

01.12.2011 - 00:47 Uhr

Hallo picnik,

Du kannst auch komplexere Objekte in XML oder sogar der App.config/User.config ablegen, z.B.


<Programm>
  <!-- Name zum Anzeigen -->
  <Name>Call of Duty 4 - Modern Warfare</Name>
  <Pfad>C:\Program Files (x86)\Activision\Call of Duty 4 - Modern Warfare\iw3mp.exe {0}</Pfad>
  <!-- {0} wird durch dich ausgefüllten Parameter ersetzt -->
  <ParameterListe>
    <ArrayOfParameter>
      <Parameter>
        <!-- Name zum Anzeigen -->
        <Name>Host</Name>
        <Format>+connect {0}</Format>
        <!-- Hier wird {0} durch die Eingabe des Benutzers ersetzt. -->
      </Parameter>
    </ArrayOfParameter>
  </ParameterListe>
</Programm>

Dann musst du nur noch die Liste deiner Programm-Objekte anzeigen und je nach ausgewähltem Objekt die Text-Boxen dynamisch erstellen. Und nach dem Button-Click baust du dein Process/StartInfo dynamisch mist string.Format zusammen.

Gruß
Juy Juka

[edit]
Ein paar Links:
[Tutorial] Konfigurationsmodell im .NET Framework
"Propertie- Datei" in C#
2 dimensionales Array in Properties.Settings?
[/edit]

30.11.2011 - 15:59 Uhr

Hallo G-Shark,

Weil die Beiden Generischen-Teile keine Properties sondern öffentliche Felder sind.

Öffentliche Felder sollten nicht verwendet werden, da sie keine Kapselung ermöglichen.

Gruß
Juy Juka

30.11.2011 - 12:47 Uhr

Hallo el_vital,

Es gibt ein fertiges Programm, welches alles dll's in deiner fertigen (normalen) Anwendung einbindet.
.Netz
Ich habe es selbst noch nicht probiert, ob das auch mit den Sateliten-Assemblies für Lokalisierung funktioniert.

Gruß
Juy Juka

30.11.2011 - 00:08 Uhr

Hallo Andybritten,

Wie kann ich es schaffen dass der GUI Thread wartet bis der Berechnungsthread fertig ist, aber trotzdem nicht einfriert?

Die Kurze Antwort ist: Nicht.
Wenn der GUI-Thread weiter läuft, wird auch den Quellcode ausgeführt und wenn nicht friert die GUI ein. (≤Punkt)

Aber: Du kannst deine ganze Maske sperren (disabeln, readonly, Panel drüber, etc.) und das was du normal nach den Berechnungen machst mit in deinen ThreadStart legen und zusätzlich das entsperren der GUI auch, diesen Teil musst du dann wiederaum aus dem Thread mit Control.Invoke ausführen.

Sieht ein bischen komisch aus, da du einen Thread machst und dann von dort aus wieder in den "alten" Thread zurück greifst, aber meines Wissens nach ist das die einzige Möglichkeit.

Gruß
Juy Juka

29.11.2011 - 20:22 Uhr

Hallo FZelle,

Jetzt hast du mich echt zum Grübeln gebracht, deine letzten zwei Posts haben sich richtig und gleichzeitig verwirrend/falsch für mich angehört, aber ich glaube jetzt hab ich geblickt wo wir an einander vorbei reden.

Für mich gehören VM/P/C (falls du ViewModel, Presender und Controler meinst) noch zur UI schicht und du betrachtest das ganze scheinbar noch feiner als ich. Da ich das noch mit zähle und du nicht, wiedersprechen sich unsere Aussagen garnicht.

Bevor wir uns gleich wieder falsch verstehen: VM/P/C können sich mehrer verschiedene Views (WindowsForms, WPF, Silverlight, ASP.Net, etc.) teilen, wenn das Framework gut genug ist.

Hab ich dich jetzt verstanden?

Gruß
Juy Juka

29.11.2011 - 16:48 Uhr

Hallo Theo,

Erstelle die Spalten selbst als DataGridViewColumn-Objekte und lasse Sie dir nicht automatisch Generieren, dann kannst du auch bestimmen was wie angezeigt wird.

Gruß
Juy Juka

29.11.2011 - 16:06 Uhr

Hallo FZelle,

Bei Workflows hast du recht aber es gibt (zumindest bei uns) mehr Masken/Views ohne Workflow, die einfach immer die selben Menüs ausgeben (Speichern, Drucken, etc.).

Aber selbst bei Workflows könnte das UI-Framework eine Schnittstelle definieren, über die der/die Workflows die möglichen Aktionen/Buttons/Enabled-Disabled-Informationen liefert (Microsoft hat sowas ja im PropertyGrid eingebaut).
Daher könnte das UI-Framework "in der Luft hängen".
((Muss aber nicht, hätte ich hier halt gerne.))

Gruß
Juy Juka

29.11.2011 - 14:27 Uhr

Guten Tag FZelle,

Danke für die Links so etwas habe ich gesucht. Das da noch was dran hängt, muss ich mir anschauen, ist aber schon mal gut zu wissen.

Auch ist die Annahme das Menüstrip Aufbau und Verhalten von Steuerelementen gänzlich vom UI Framework abhängt auch nicht wirklich richtig.

Aber zu der Aussage muss ich noch mal nachfragen: Was meinst du damit? Natürlich ist die UI dafür verantwortlich die Menüstrips zu erstellen anzuzeigen und so weiter. Das Verhalten ist natürlich auch in der UI definiert/ausgewählt, nur dort nicht programmiert. Meinst du jetzt dynamische Menü-Einträge?

Mit freundlichem Gruß
Juy Juka