Laden...
K
kingBob myCSharp.de - Member
Student Rheinland-Pfalz Dabei seit 25.03.2007 53 Beiträge
Benutzerbeschreibung

Forenbeiträge von kingBob Ingesamt 53 Beiträge

05.09.2007 - 21:36 Uhr

Hi,

passt schon, war nur neben der Spur!!!

Danke nochmals,

schreibe grad an meiner Ausarbeitung. Einer von euch müsste mir mal kräftig in den Arsch tretten, damit ich endlich mal voran komme.

Gruß

05.09.2007 - 20:58 Uhr

Hi, danke für die zügige Antwort.

Das ist es eigentlich nicht. Ich meinte die Properties mit Get- und Set-Accessor.

Aber ich glaub, so gehts doch auch.

KingBob

05.09.2007 - 20:21 Uhr

Hallo,

wie stellt man Klassen-Properties in einem UML 2.0 Klassendiagramm dar?

Gruß,

KingBob

16.08.2007 - 10:37 Uhr

Hallo Forum,

ich hänge noch immer an diesem Problem. Kann mir denn keiner bitte helfen?
Wenigstens einen Tipp oder Hinweis..

Danke,

Gruß,
Kingbob

15.08.2007 - 11:25 Uhr

Hi Forum,
hab da ein ähnliches, wenn nicht gleiches Problem:

Habe eine Main-Form aus der ich einen Dialog aufrufen kann. Dieser Dialog besitzt eine Ip-Textbox, die ich per


//...
m_BindingSource.DataSource = m_ApplicationSetting;
m_ConnectToDlg.ipTextBox.DataBindings.Add("Text", BindingSource, "IPAddress", true);

//...

an die IPAddress-Eigenschaft einer anwendungsspezifischen Anwendungs-Einstellungs-Klasse binde.

So, dass Problem:
Sobald der Dialog geöffnet wird, wird auch die richtige IP-Adresse in der IP-Textbox des Dialogs anzegeigt. Ändere ich jedoch die IP-Adresse der Textbox im Dialog, so wird diese Änderung nicht an die Property IPAddress der Anwendungsklasse übergeben/übernommen.

Warum? Kann das PropertyChanges-Ereignis der Eigenschaft Text der Ip-Textbox nicht im Hauptformular empfangen werden, damit der Databinding-Mechanismus die Aktualisierung durchführen kann?

Hoffe, ihr könnt mir weiterhelfen.

Gruß, KingBob

P.s: Das ganze funktioniert einwandfrei, wenn ich die IP-Textbox im Hauptfenster habe, also dort, wo auch der Databinding-Mechanismus abläuft.
Übrigens: Die IP-Textbox ist ne normale Textbox.

31.07.2007 - 19:31 Uhr

Hallo Herbivore,

die Aktualisierung einer asynchronen Anfrage dauert ca. 60 Millisekunden.

Aber hinter einen Button-Click, können sich im Eventhandler mehrere solcher Akualisierungsanfragen befinden.

Das mit der Erzeugung eines Extra-Thread pro Aktualisierungsaufruf wäre schon besser. Nur macht es wirklich Sinn, also bzgl. der CPU-Auslastung, immer einen Service-Thread zu erzeugen?

Der Updateter Thread läuft ja auch unabhängig vom GUI-Thread. Ruft er nun die Aktualisierungsfunktion all 20 Millisekunden auf, so wir von der Aktualisierungsfunktion der Service-Thread erzeugt.

Meinst du nicht, dass das ziehmlich CPU-Lastig wäre?

Wäre gut, wenn du mich damit beruhigen könntest, dass das kein Problem wäre für die Auslastung.

Gruß und thx

Kingbob

31.07.2007 - 13:52 Uhr

Hi Programmierhans,

danke, jetzt wirds mir klarer --> WaitOne();

Thx Mr.X

Gruß

31.07.2007 - 13:27 Uhr

Hi,

das war, ist und wird mir klar bleiben. Nur, warum schmiert mir die Kiste dann bei Invoke() nicht wenigstens ab oder wirft ne Exception wenn er die Zugriff auf einen schlafenden GUI-Thread nicht bewerkstelligen kann.

Naja, dann werde ich es wohl so loesen muessen, dass bei Aufruf der Aktualisierungsfunktion, jedesmal ein Service-Thread erzeugt wird. Dieser wird dann alle 20Millisekunen aufgerufen werden müssen. Egal ob synchron durch den Updater-Thread oder asynchron durch den GUI-Thread.

Nur, ist es wirklich ratsam für die Aktualisierungsfunktion jedesmal, alle 20Milli, einen Service-Thread zu erzeugen? Die Erzeugung eines Thread verschlingt ja schon einige Prozessorzyklen. Und wenn das jetzt noch alle 20 Millisekunden erfolgen solll, ja, dann steigt die Prozessorauslastung durch meine Anwendung.

Was meint ihr? Ist es schon in Orndung für das System ca. alle 20 Millisekunden einen neuen Service-Thread zu erzeugen.

Client-Server-System im Web sind ja auch so aufgebaut. Abhängig von der Implementierung des Web-Server(Demand-Driven-Concurreny, Predeterminend-Concurreny, Iterativ oder Pre-Allocated-Concurreny) werden ja auch Thread erzeugt. Aber ich glaube nicht, dass ein Web-Server alle 20 Millisekunden nen Client-Anfrage empfängt.

Gruß und danke schonmal

31.07.2007 - 12:47 Uhr

Hi,

hab ein weiteres Problem:

Hab zwei Threads: GUI-Thread und Updater-Thread.

Im Updater-Thread wird zyklisch eine Aktualisierungsfunktion aufgerufen und anschließend die Ergebnisse der Aktualisierung z.B. an eine TextBox übergeben.
Der Zugriff auf die TextBox läuft bei der Ergebnisübergabe durch den Updater-Thread per Invoke.

So, nun biete ich auch den Benutzer die Aktualisierung auch asynchronen, also durch einen Buttonclick durchzuführen.

Die Aktualisierungsfunktion, die spezielle Informationen vom Netz saugt, wird von mir per Monitor.Enter(lockVar) und Monitor.Exit(lockVar) geschützt. Diese Aktualisierungsfunktion wird ja synchron vom Updater-Thread und asynchron vom GUI-Thread(Benutzer drück auf Button) genutzt.

So, mein Problem:

Wenn der Updater-Thread in die Akualisierungsfunktion eintritt, so wird durch Monitor.Enter(..) der Zugriff durch einen anderen Thread(hier GUI-Thread) bis zum Aufruf von Monitor.Exit(..)ausgeschlossen. So, sobald der Benutzer den Button betätigt und somit einen asynchronen Zugriff auf die Aktualisierungsfunktion startet, bleibt die GUI solange in Monitor.Enter(..) hängen, bis der Updater-Thread die Aktualisierungsfunktion durch Monitor.Exit(..) verlässt hängen.

Das Problem: Da der Updater-Thread jetzt die Ergebnisse hat und somit diese der Textbox per Invoke übergeben möchte, tritt ein Deadlock auf, weil der Invoke-Aufruf ja dazu führt, dass die Ergebniss-Übergabe im GUI-Thread erfolgt. DER SCHLÄFT ABER und somit kehrt die Funktion des Updater-Thread, innerhalb deren invoke aufgerufen wird, nicht mehr zurück, da der GUI-Thread schläft.
Da die Funktion nicht mehr zurückkehrt, kann somit auch nicht Monitor.Exit aufgerufen werden. Folge: die GUI bleibt eingefroren, da der asynchrone-Vorgang noch in Monitor.Enter(..) hängt.

So, meine Frage: Wie kann ich auf einen schlafenden GUI-Thread zugreifen.
Invoke(..) schmiert ab. Das Prolem ist Invoke

Gruß



            //MessageBox.Show("Wrapper");
            if (m_PendCBF == null)
                return;
            // Diesem Delegaten zugrundeliegende Instanz ermitteln
            object control = m_PendCBF.Target;

            if (control == null)
                return;

            // Array für Funktionsübergabeparameter
            object[] param = new object[3];

            param[0] = rspStatus;
            param[1] = paramIndex;
            param[2] = paramValue;
            try
            {
                // Ist es notwendig diese Rückruffunktion im Kontext des GUI-Threads aufzurufen?
                if (((Control)control).InvokeRequired)
                {
                    //MessageBox.Show("Wrapper: in if");
                    //HIER SCHMIERT MIR DIE FUNKTION AB, WENN DER GUI-THREAD SCHLAEFT
                    ((Control)control).Invoke(m_PendCBF, param);
                }
                else
                {
                    //MessageBox.Show("Wrapper: in else");
                    m_PendCBF(rspStatus, paramIndex, paramValue);
                }
            }

            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
27.07.2007 - 19:31 Uhr

Hallo Forum,

habe ein Programm mit GUI geschrieben. Die Gui bietet einen Button namens "Connect to Remotehost" an. Sobald der Button gedrückt wird, wird versucht, eine Verbindung zu einem Remotehost herzustellen.

Meine Programmlogik ist so ausprogrammiert, dass die Klasse, die für die Verbindungsherstellung zum Remotehost eine Exception wirft, wenn der Remothost die Verbindungsaufnahme verweigert. Grund kann der sein, dass der Remotehost inaktiv ist.

Sobald ich über den besagten GUI-Button ne Verbindung herstellen möchte und der Remotehost ausgeschaltet ist, so dauer es ewig, bis der TCPClient und dessen Methode Connect es rafft, dass kein Verbindungsaufbau möglich ist. Er wirft dann eine Exception die ich abfange und es der GUI mit meiner eigenen Exception mitteile.

Problem: Die GUI friert beim Verbindungsaufbauversuch nach 1/10 Sek ein.

Also: Wie könnte ich es am geschicktesten bewerkstelligen, dass nach Druck des Verbinddungsaufbau-Button meine GUI nicht einfriert, wenn der Remotehost down ist?

Soll ich den Verbindungsaufbau einem Thread überlassen, der bei erfolgreicher Verbindungsherstellung dem GUI-Thread dem zugrundeliegenden Socket übergibt?

Keine Ahnung.

Wie macht ihr das?

Oder gibt es ne Möglichkeit die Zeitspanne, über die versucht wird eine Verbindung zum Remotehost über einen Socket herzustellen zu ändern?

Gruß und Danke im Voraus.

KingBob.

25.07.2007 - 17:08 Uhr

Habs!

Lag am Pfad. Der Designer akzeptierte keine bmp-files außerhalb des Projektes

gruß und thx

25.07.2007 - 16:51 Uhr

Hi Forum,

hab eine Problem mit der Einbindung eines Bildes für ein neues Steuerelement.

Mein entworfenes Steuerelement soll in die ToolBox von VS 2005 eingebunden werden. Das funktioniert auch wunderbar, nur zeigt er mit nur das Standardbild(Zahnrad) für mein Steuerelement in der Toolbox an.

Hab das Bildchen mit dem Designer von VS 2005 erstellt und als Resource in das Steuerelement eingebunden. Das BMP-File ist 16x16 Pixel groß.

Des Weiteren habe ich es auch noch mit dem Attribute "ToolBoxBitmap" versucht. Brachte auch keinen Erfolg.

Hat jemand schon ähnliche Probleme gehabt? Und wenn ja, dann bitte ich um Rat.

Gruß,

KingBob.

P.S.: Hab einige Schlagwörter für die Forensuche verwendet. Bin jedoch auf keine passenden Ergebnis gestoßen.

25.07.2007 - 15:43 Uhr

@programmierhans: daran hab ich auch schon gedacht, nur würde es meine GUI zum einfrieren bringen, da die Update-Funktion ne Zeit braucht und ich außerdem sehr, sehr of update - alle 80ms.

@herbivore: Ist auch ne Möglichkeit. Mal schauen.

Gruß und thx

25.07.2007 - 14:46 Uhr

Hi, hab den "Bug".

Der Nicht-GUI-Thread hat die Aufgabe, Textboxen zu aktualisieren. Er aktualisiert diese nur dann nicht, wenn diese grade den Focus haben. Das überprüfe ich
folgendermaßen:


if(!this.Focused)
 aktualisierungsfunktion()
//...

Es lag am "this.Focused".

Jetzt hab ich aber ein neues Problem. Wie soll ich den aus einen anderen Thread überprüfen, ob diese TextBox fokusiert wird oder net, wenn ich doch nicht drauf zugreifen darf.

Vlt. muss ich die Überprüfung verschieben. Die Überprüfung müsste ich dann in die Funktion hereinpacken, die per Invok aufgerufen wird. Aber dann hätte ich ne unnötige Aktualisierung gemacht, wenn die Textbox den Fokus hat.

Deshalb hab ich ja die Überprüfung vorher gemacht.

muss mir etwas einfallen lassen.

gruß,

KingBob.

25.07.2007 - 14:13 Uhr

Hi, das mit dem anderen Thread ist ausgeschlossen, da ich nur den GUI-Thread habe und den "Control-Aktualisierungsthread".

Ich schaue mir mal die StackTrace an.

Mom.

gruß

25.07.2007 - 14:07 Uhr

Hi,

wo wir gleich beim Thema sind.

Hab auch ein Problem mit dem Zugriff auf Controls aus einen anderen Thread als dem GUI-Thread.

Obwohl ich Invoke verwende, und InvokeRequired immer true ist, wird beim Setzen einer TextBox im GUI-Thread die Exception geworfen.

Hier mein Code:

//...
if((Control)control).InvokeRequire)
{
/* Hier wird reingesprungen, da Invoke gebraucht. Trotz allem, dass auf das
Control per Invoke zugegriffen wird, wird die bekannte Exception beim Setzen
des TextControls im GUI-Thread ausgelöst.*/
((Control)control).Invoke(m_PendCBF, param);
}
else
{
m_PendCBF(rspStatus, paramIndex, paramValue);
}
//..

Woran liegt das?

Gruß,

Rafael

22.07.2007 - 22:00 Uhr

Hi, ja, werde ich wohl können müssen....

Also..

22.07.2007 - 21:49 Uhr

Hi,

es geht doch!

siehe dazu:

http://blogs.msdn.com/jfoscoding/archive/2005/12/23/507164.aspx

Jedoch reagiert er nicht auf PropertyChanged-Events.

Muss da noch nachhacken.

Gruß

22.07.2007 - 21:24 Uhr

Hi,

ich krieg gleich die Krise.

Jetzt will ich doch ne Datenbindung zwischen einen ToolStrip-Element, z.b. ToolStripButton und einem bool-Property herstellen, um in Abhängigkeit der bool-property den ToolSTripButton zu deaktivieren/aktivieren. Aber nein, ToolStrip-Elemente unterstützen kein Databinding, obwohl es mir soviel Code ersparen würde. Jetzt muss ich, wenn ich die besagte bool-Property änder, auch gleich noch ToolSTripButton.Enable = false/true setzen. Was für ein Umstand.

Hab ich etwas übersehen oder geht das überhaupt nicht?
Habt ihr Tipps/Alternativen?

Gruß,

KingBob

22.07.2007 - 13:15 Uhr

Hi, danke!

Habs gelöst!

Ich Simpel hab die if-Abfrage vergessen. Also:

 if(PropertyChanged != null)
{
PropertyChanged(this, new ...));
}

Thx,

22.07.2007 - 13:10 Uhr

Hi.

Hab das jetzt mit der Implementierung der Schnittstelle INotifyPropertyChanged versucht:

Nun sagt mir der Compiler beim kompilieren, dass der Objektverweis für das Event PropertyChanged nicht auf eine Objektinstanz festgelegt wurde.


public class Customer: INotifyPropertyChanged
    {

        /* Private variables */
        private int _id;
        private string _name;
        private Decimal _rate;

 public event PropertyChangedEventHandler PropertyChanged;

        /* Constructor */
        public Customer()
        {
            this.ID = -1;
            this.Name = string.Empty;
            this.Rate = 0.0M;
            
        }

        public Customer(int id, string name, Decimal rate)
        {
            this.ID = id;
            this.Name = name;
            this.Rate = rate;
        }
        /* Public API */
        public int ID
        {
            get { return _id; }
            set
            {
                _id = value;

                // Hier wird die Exception ausgelöst. Das ist doch ein Event, das oben definiert wurde. Warum tritt hier ne NullReferenceException auf?
                PropertyChanged(this, new PropertyChangedEventArgs("ID"));
               
            }
        }


Was mach ich falsch?

Gruß

KingBob

21.07.2007 - 16:52 Uhr

Servus Herbivore,

danke für die Antwort. Werde mir das Zeug mal antun.

Gruß.

21.07.2007 - 16:34 Uhr

Hallo Forum,

hab da mal wieder eine Frage. All diese Fragen kommen aufgrund der fehlenden C#-Erfahrung.

Naja, egal.

Habe ein Problem mit simplen Databinding, auf das ich beim experimentieren gestoßen bin.

Habe auf meiner Form eine Textbox platziert. Diese Textbox binde ich an das Property Name einer Klasse.

Ändere ich nun den Inhalt der Textbox, so ändert sich auch das Property Name. Aber wenn ich das Property Name ändere, so ändert sich nicht der Inhalt der Textbox. Muss ich irgendeine Notification-Message weggschicken, damit die Binding-Laufzeit meine Textbox ändert?

 namespace databindingtest
{
    public partial class Form1 : Form
    {

       public Customer cust;
        public Form1()
        {
            InitializeComponent();
            this.textBox2.DataBindings.Add("Text", cust, "Name", true);//, DataSourceUpdateMode.OnPropertyChanged);
           
        }

        public void button1_Click(object sender, EventArgs e)
        {
           // Wenn ich nun das Property Name auf kingBob ändere
           // so ändert sich der Inhalt der Textbox nicht. Warum?
           // Was fällt hier?
            cust.Name = "kingBob";
        }
    }

    public class Customer
    {
        /* Private variables */
        private int _id;
        private string _name;
        private Decimal _rate;

        /* Constructor */
        public Customer()
        {
            this.ID = -1;
            this.Name = string.Empty;
            this.Rate = 0.0M;
        }

        public Customer(int id, string name, Decimal rate)
        {
            this.ID = id;
            this.Name = name;
            this.Rate = rate;
        }

        /* Public API */
        public int ID
        {
            get { return _id; }
            set { _id = value; }
        }

        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        public Decimal Rate
        {
            get { return _rate; }
            set { _rate = value; }
        }
    }

}

Sorry, mag vlt. ein simples Problem sein, dass auf falschen Verständnis des C#-Bindings basiert. Der DDX/DDV-Machnismus in der MFC-Programmierung ist da wesentlich verständlicher.

Hoffe, ihr könnt mir auf die Sprünge helfen.

Danke,

Kingbob

18.07.2007 - 21:06 Uhr

Hi, danke für den Ansatz.

Werde ich mir mal anschauen.

kingBob

18.07.2007 - 20:19 Uhr

Hallo Forum,

Die MFC bietet bei SDI/MDI-Projekten in der Klasse CDocument eine boolsche Variable, welche den Änderungszustand eines Dokumentes seit der letzten Sicherung(Speichern in ner Datei) verwaltet. Mit der Methode SetModifiedFlag() lässt sich diese Variable setzten bzw. zurücksetzen.

Möchte man nun die Hauptanwendung schließen, so wird dem Benutzer eine Benutzerabfrage zum Sichern des Dokumentes angezeigt.

Meine Frage:

Gibt es sowas aus für Windows-Forms-Anwendungen? Wie sieht die alternative aus?

Oder setzt ihr bei Änderungen von Daten eine bool-Variable, die ihr dann beim Schließen der Anwendung abfrägt, um somit vlt. das Speichern-Dialog dem Benutzer anzuzeigen. So könnte man das in etwa machen.

Bietet .Net da eine vergleichbare Möglichkeit zu der MFC und einer Dokument-Ansichtenarchitektur?

Gruß,

KingBob

18.07.2007 - 09:23 Uhr

Halol Forum,

wenn man eine MDI-Anwendung schreibt, so gibt es ein Host-Fenster und mehrere Child-Fenster. Diese Child-Fenster werden im MDI-Container des Host-Fensters verwaltet. Nun bietet eine MDI-Anwendung die Möglichkeit an, die angezeigten Child-Fenster(Child-Forms) per

this.LayoutMdi(MdiLayout.TileHorizontal);
this.LayoutMdi(MdiLayout.TileVertical);

im Host-Fenster ausrichten zu lassen.

Nun hab ich eine Anwendung geschrieben, die *UserControl-Fenster in Clientbereich des Hauptfensters(MainForm) anzeigt. Diese UserControl-Fenster wurden von mir mit Eigenschaften versehen, die mir das freie Bewegen der UserControl-Fenster im Hauptfenster ermöglichen.

Nun kann es dazu kommen, dass im Hauptfenster viele UserControl-Fenster angezeigt werden und wild durcheinander in diesem angeordnet sind.

Diese willkürliche Annordnung/Ausrichtung der UserControl-Fenster im Hauptenster soll durch einen Mechanismus zum selben Ergebnis führen, wie es per

this.LayoutMdi(MdiLayout.TileHorizontal);
this.LayoutMdi(MdiLayout.TileVertical);[/

in einer MDI-Anwendung ermöglicht wird.

Gibt es eine Möglichkeit, das MDI-Fenster-Anordnungsverhalten auf UserControl-Fenster zu übertragen?

Gruß

kingBob.

*Damit bezeichne ich zunächst einfach mal einen leeren Hintergrund eines UserControls -mehr nicht. Dieses leere UserControl kann ich um weitere Controls erweitern -->UserControl-Fenster(keine Form!).

16.07.2007 - 15:07 Uhr

Hi.

@herbivore: Damit bezeichne ich zunächst einfach mal einen leeren Hintergrund eines UserControls-mehr nicht. Dieses leere UserControl kann ich um weitere Controls erweitern -->UserControl-Fenster(keine Form!).

@Schamese: Danke für den Ansatz. Das mit dem "selbst zeichnen" würde eleganter sein. Weiß leider nicht, wie ich das genau anstellen soll. Werde mich mal genauer in GDI+ einlesen müssen.

Thx.

KingBob

16.07.2007 - 14:19 Uhr

Hallo Forum,

gibt es eine Möglichkeit in einem eigenen UserControl-Fenster in der rechten oberen Ecke ein "Schließen-Kreuz" zu malen?

Mein UserControl wird im Hauptfenster gehostet. Nun soll es ne Möglichkeit geben, per Klick auf das Schließen-Kreuz des ausgewählten UserControl-Fenster dieses eben zu schließen. Dazu bräuchte ich aber zunacht ein kleines Kreuz in der Ecke.

Falls dass nicht funktioniert, werde ich wohl einen Menüeintrag "Close" im Contextmenü meines UserControls zum Schließen verwenden müssen.

Hoffe aber, dass ihr mir da weiterhelfen könnte. Möglicherweise muss ich mir so ein Kreuz selbst per GDI zeichnen lassen.

Naja, mal abwarten was ihr dazu meint.

Gruß,

KingBob

14.07.2007 - 21:20 Uhr

Hi,

hallo, wollte euch beiden für die ausführlichen Beiträge bedanken -kostet ja alles Zeit.

Der Ansatz mit dem Hauptfenster als quasi Controller wäre für mein Softwarekonzept soweit in Ordnung.

Danke nochmals.

Gruß

Kingbob

14.07.2007 - 16:47 Uhr

Hi,

@herbivore:

Ich würde trotzdem das Hauptfenster als grafische Repräsentation des Controllers verstehen, so hat es auch Rainbird in seinem Beispiel gemacht, siehe den entsprechenden Kommenta im xml-tag:

namespace Rainbird.MVCExample.GUI
{
	/// <summary>
	/// Das Hauptfenster der Anwendung.
	/// 
	/// Diese Klasse ist der Controller.
	/// </summary>
	public partial class MainForm : Form
	{
		#region Deklarationen
		
		// Lieferantenliste
		private Model _model; // Model

		#endregion

		#region Konstruktor

		/// <summary>
		/// Standardkonstruktor.
		/// </summary>
		public MainForm()
		{
			// Steuerelemente konfigurieren
			InitializeComponent();

			// Model erzeugen
			_model = new Model();

			// Model Ereignisse abonnieren
			_model.SupplierLoaded += new EventHandler(_model_SupplierLoaded);
			_model.BeforeCancelSupplierChanges += new BeforeCancelSupplierChangesEventHandler(_model_BeforeCancelSupplierChanges);
			_model.SupplierCreated += new EventHandler(_model_SupplierCreated);
		}				

Mein Problem ist folgendes: Ich habe eine recht komplexes Softwarekonzept erstellt. Jedemenge Klassen und die damit verbundenen Beziehungen. Ich weiß einfach nicht, aufgrund fehlender Erfahrung, wo ich die Herstellung der Klassenbeziehungen in einer Windows-Forms-Anwendungen packen soll. Soll etwa alles im Konstruktor des Hauptformulars erfolgen. Das würde für mich in Ordnung sein. Denn wenn der Controller die Anwendungslogik in Form der Forms-Klasse darstellt, dann gehört das da auch rein.

Deshalb mein Frage zu MVC und Windows-Forms.

Ratschläge, Tipps?

Gruß

14.07.2007 - 16:16 Uhr

Hallo Forum,

habe eine Frage zu MVC in Kombination mit Windows-Forms.

Was ist der Controller in einer Windows-Forms-Anwendung?

Ich würde das so verstehen, dass der Controller dem Hauptformular entspricht, über das der Controller Benutzereingaben entgegennimmt und somit die Geschäftslogik kontrolliert.

So würde z.b. das Hauptformular ein Button besitzen, über den der Controller eine View im Hauptfenster anzeigen würde. Das Hauptformular ist die grafische Repräsentation des Controllers. Ist das so richtig verstanden?

Ist der Controller das Hauptformular in einer Windows-Forms-Anwendung?

Gruß,

KingBob

04.07.2007 - 13:30 Uhr

Hi,

Variante 3 entspricht doch dem CamelCase. Und CamelCase gilt, soviel ich weiß, für Parameternamen von Methoden.

Ich würde eher Variante 1 bzw. 4 vorziehen.

Variante 1 doch eher, da mein Control Label eben ein Member einer Form ist.

Oder?

gruß

04.07.2007 - 13:11 Uhr

Hallo Forum,

Gibt es eine grundlegende Namenskonvention für Controls?

Was ist "richtiger":


// 1. Variante:
private Label m_InfoLabel;
// 2. Variante:
private Label m_infoLabel;
// 3. Variante:
private Label infoLabel;
// 4. Variante:
pirvate Label InfoLabel;

Gruß,

kingBob

29.06.2007 - 08:35 Uhr

Hallo,

wollte mich nur für die Ideen bedanken.

Werde es gleich mal implementieren.

Gruß

28.06.2007 - 22:41 Uhr

Hallo Forum,

sorry für die etwas magere Problemstellung. Mir ist auf die Schnelle keine bessere Problemstellung aufgefallen. Jetzt, da ich Zeit habe, werde ich mich etwas deutlicher Ausdrücken.

Es sei folgende Struktur gegeben:


public struct Person
{
public string Name;
public int Alter;
}

Nun will ich es ermöglichen, wenn's denn auch sprachtechnisch funktioniert, dass es einen Typen gibt, dem ich per '+=' und '-=' Operatoren Instanzen des oben definierten Strukturtypes zuordnen kann. Dieser mir noch nicht bekannte Typ muesste also so implementiert sein, dass er per '+=' die Instanz des Strukturtypes 'Person' aufnimmt und irgendwie in einem Feld verwaltet. Sobald ich den Operator '-=' verwende, so soll eine Instanz vom Typ 'Person' wieder aus diesem Feld entnommen werden.

Hoffe, dass ihr mich ungefähr verstehen könnt. Eigentlich ist es mein Ziel, ein ähnliches Verhalten, wie es für die Registrierung/Deregistrierung von Eventhandlern für Ereignisse gemacht wird, zu erhalten:

Dem Click-Ereignis eines Button können doch beliebig viele Eventhandler per '+=' zugewiesen werden. Erfolgt nun ein Druck auf den Button, so wird eine interne Logik alle Eventhandler die sich fuer das Click-Ereignis registriert haben, ausgefuehrt. Die Eventhandler muessen ja irgendwie zwischengespeichert werden --> Array. Dieses Array ist von einem Delegate-Typ und enthaelt eben die sich fuer das Click-Ereignis registrierten Eventhandler. Dieses Array wird durchlaufen und somit jeder Eventhandler aufgerufen.

Gibt es in C# eine Möglichkeit das fuer eigene Typen nachzubilden?

Gruß

28.06.2007 - 17:52 Uhr

Hallo Forum,

gibt es in C# eine Möglichkeit folgende Verhaltensweise zur Registrierung und Deregestrierung von Eventhandler für eigene Typen nachzubilden?
//Registrierung

this.Button1.Click += new System.EventHandler(this.Button_Click); 

//Deregistrierung


this.Button2.Click -= new System.EventHandler(this.Button_Click);

D.h. ich definiere mir eine Klasse und überlade die Operatorn += und -= dermaßen, dass sie den selben Effekt haben wie oben kurz beschrieben.

Gruß

22.06.2007 - 09:26 Uhr

Sorry herbivore(Planzenfresser)🙂,

der Beitrag hat sich überschnitten.

Danke für die zahlreichen Kommentare.

Werde mein Model(=Anwendungsschicht) in separate Files hacken und eben die GUI davon trennen. Letztendlich ist die GUI dann austauschbar.

Danke

22.06.2007 - 09:21 Uhr

Wie soll's denn aber ohne WPF gehen?

Es gibt prinzipiell nie eine reine Trennung zwischen GUI und Anwendungsschicht-.

22.06.2007 - 09:13 Uhr

Letzte Frage:

Darf die Anwendungsschicht beim auftreten von Fehlern eine MessageBox anzeigen oder macht das die GUI anhand eines Rückgabewertes den sie von der Anwendungsschicht bekommen hat?

Sorry für diese sturren, aber auch langsam ins nervige übergehenden Fragen. Muss einfach ne eindeutige Vorstellung von der Trennung haben. Hab einfach zu wenig Erfahrung.

Gruß

22.06.2007 - 08:23 Uhr

Hallo herbivore,

danke für die Antwort.

Das Zitat ist nicht ganz 1:1 richtig. Aber sinngemäß hab ich das so verstanden, als ich deine Aussagen zu MVC gelesen habe.

Die Trennung von so View und Controller kann bei weniger komplexen Anwendungen jedenfalls vernachlässigt werden.

Aber das mit dem Options-Dialog(Config Settings) müsste dann also so laufen, dass das Dialog-Fenster bei Änderungen der IP-Adresse und der Port-Nr. der Anwendungsschicht dies übermittelt? Natürlich muss aber auch das Dialog-Fenster lokale Variablen zur Ablage der obengenanten Informationen besitzen, um damit eben z.b. die Textboxen für IP-Adresse und Port-Nr. zu füllen.

Da ich ziehmlich neu in diesem Business bin, stelle ich diese Fragen. Bisher habe ich eigentlilch nur Konsolenanwendungen gehackt. Also entschuligt bitte, dass ich immer wieder nachhackte. Dies dient letztendlich nur meiner sturren gewohnheit alles zu 100Prozent richtig machen zu wollen.

gruß

21.06.2007 - 23:39 Uhr

Hallo parsifal,

danke für deine Anregung!!!

Die Möglichkeit mit dem Property ist ein guter Ansatz, aber es folgt daraus eine weitere Schwierigkeit:

Nun wird eine UserControl der Toolbar ausgewählt und per click im Main-Fenster instanziiert. Nun aber möchte auch die anwendungsschicht darüber informieren, dass ein oder zwei oder beliebig viele usercontrols von der gui instanziiert wurden, damit die Anwendungsschicht dies protokollieren kann und das in eine log-Datei packen kann.

Grundsätzlich ist es dann so, dass die GUI ständig von den Möglichkeiten der Anwendungsschicht bescheid weiß.

Gruß und danke nochmals

21.06.2007 - 22:58 Uhr

Hi,

erstmals danke für die rasche Antwort.

Muss aber zu deiner Antwort sagen, dass sie mich nicht befriedigt.

Gut. Ich will noch ein weiteres Beispiel bringen:

Ein weiteres Projekt besteht auch diesmal wieder aus einer GUI und der zugehörigen Anwendungslogik. Diesmal soll die Toolbar der GUI um UserControls erweitert werden.
Das UserControl für sich wird in EINE Assembly hineinkompiliert.

Beim start der Anwendung soll ein zuvor festgelegtes Verzeichnis nach Assemblies durchsucht werden und bei vorhanden sein von Assemblies sollen diese ausgewertet werden(Typ, Name, Icon werden aus dem Manifest entnommen) und das UserControl per "toolItem.Item.Add(...)" in die Toolbar geaddet.

Meine Frage an euch:

Welche dieser Varianten ist architektonisch sinnvoller:

1: Die Anwendungsschicht besitzt die Logik beim Anwendungsstart das entsprechende Verzeichnis nach Assemblies zu durchsuchen und die aus den einzelnen Assembly extrahierten Typen(UserControls) per "GUI.toolbar.Item.Add(...)" an die Toolbar der GUI zu hängen? Des Weiteren besitzt die Anwendungsschicht einen Container mit den Typen der im Verzeichnis gefundenen Assemblies --> Diese Variante setzt voraus, dass die Anwendungsschicht von der GUI bescheid weiss.

2: Die GUI besitzt die Logik beim Anwendungsstart das entsprechende Verzeichnis nach Assemblies zu durchsuchen und ... --> Diese Variante ist unabhaengig von der Anwendungsschicht. ABER: Entgegen der obenstehenden Antwort von herbivore, waere die GUI eigentlich ziehmlich intelligent.

Stehe ziehmlich auf den Schlauch.Habe keine Ahnung was architektonisch sauberer waere. Mann kann nicht immer sagen, dass die GUI die Anwendungsschicht steuert. Was ist denn, wenn nun die Anwendungsschicht ueber die Typen der Assemblies bescheid wissen muss? Dann muss sie doch irgendwie an den Container, der ja von der GUI verwaltet wird, heran kommen. Meiner Meinung nach hat die GUI von der Anwendungsschicht ne Ahnung und die Anwendungsschicht von der GUI. Wobei wir hier wieder bei herbivore wären: Zitat: "Ich würde Forms und Anwendungslogik nicht trennen, bezogen auf MVC".

Ideen? Anregungen?

Gruß

21.06.2007 - 22:01 Uhr

Hi Forum,

habe eine allgemeine Frage zur Software-Architektur bei grafischen Programmen.

Ich möchte eine 3-Schichten-Software-Architektur für mein Projekt nutzen.

  1. Schicht: GUI (Darstellungschicht/Anwenderschnittstelle)
  2. Schicht: Anwendungslogik(Fängt die Benutzereingaben ab und handelt entsprechen)
  3. Schicht: Datenbank(Stellt eine Verbindung zu einen Datenbankserver per TCP/IP her)

Meine GUI wird ein Menü-Item "Settings" besitzen. "Settings" hat wiederum ein Item "Config Connection".

Sobald man "Config-Connection" per Mausklick aktiviert, soll dich ein Dialog-Fenster öffnen, das mir die Möglichkeit bieten soll, die Ip-Adresse und Port-Nr in eine Textbox einzugeben.

<Meine Fragen>

  1. Soll die Anwendungslogik das Mausereignis beim klick auf das "Config-Connection"-Item abfangen und somit in dem Eventhandler das öffnen des Dialog-Fenster(Options-Fensters) sorgen. Oder ist die Gui so intelligent zu gestallten, dass sie das Event abfängt und somit für das Anzeigen dieses Dialog-Fenster(Options-Fensters) sorgt?

  2. Und wie soll die Anwendungsschicht auf Ip-Adresse und die Port-Nr. zugreifen. Sollte das Dialog-Fenster(Options-Fenster) nicht öffentliche Variablen zur Speicherung der IP-Adresse und Port-Nr. bereitstellen auf die dann die Anwendungsschicht zugreifen kann?

Also, ruft die Anwendungsschicht das Dialog-Fenster auf nachdem sie sich für das Click-Event des "Config-Connection"-Item registriert hat? Oder ist die Gui so intelligent zu gestallten, dass sie auf das Click-Event reagiert und das Fenster zum Vorschein bringt?

  1. Sollte die GUI denn nicht immer "dumm" implementiert werden. D.h. sie schmeist nur Events, für die sich die Anwendungsschicht(Controller (MVC)) registriert hat?
    Die Anwendungsschicht wiederum sagt dann der GUI, dass sie zum Beispiel irgendein Control "disablen" soll!
    </Meine Fragen>

<Allgemeines>
Ich sitze schon seit einer Woche vor diesem Problem. Hab mich ausgiebig mit MVC und M-VC beschäftigt etc. Wobei ich sagen muss, dass ich es nicht für richtig halte, dass man Forms und Controller vereinen sollte aufgrund der dadurch entstehenden starken Kopplung.
</Allgemeines>

Hoffe, ihr könnte mir helfen und mir vlt. sagen, wie ihr denn die Trennung zwischen GUI und Anwendungslogik löst, wenn ihr sie tatsächlich durchführt!

Gruß,

kingBob

16.06.2007 - 17:53 Uhr

Hallo Forum,

habe da ein Verständnisproblem bzgl. dem MVC-Pattern:

Habe vor eine Software zu schreiben, die Daten unterschiedlich darstellen soll.

  • Die Datenhaltung entspricht dem Model von MVC
  • Die Visualisierung der Daten soll durch verschiedene Views erfolgen. Diese enstprechen den Views von MVC.

Was ist aber der Controller? Ist der Controller die Komponente, die z.B. auf das Drücken des Menü-Eintrages "Erzeuge neue Histogramm-View" reagiert? Ist die grafische Oberfläche der C#-Anwenung, innerhalb der z.B. das View "Histogramm" als Fenster erscheint, als Controller zu verstehen?

Ich würde den Controller so sehen und umsetzen: Das Model besitzt eine Funktion, über alle Daten gelöscht werden können. Nun würde ich einen Menüeintrag in meiner Anwendung "Lösche Daten" erstellen und nach dessen Betätigung einen eine Weiterleitung an die Controller-Funktion "LöscheModellDaten" durchführen. Diese Controller-Funktion würde dann die entsprechende Model-Funktion zum löschen der Daten aufrufen.

Das ist ungefähr mein Verständnis über das MVC-Pattern.

Hoffe, ihr könnt mir eine kleinen Verständnis-Kick verpassen.

Gruß

24.05.2007 - 12:45 Uhr

THX herbivore.

24.05.2007 - 10:53 Uhr

Hi,

hab noch ein weiteres Problem:

Der TCP-Thread ruft bei Ankunft von Daten eine CallBack-Funktion auf. Diese Callback-Funktion läuft in einem GUI-Thread innerhalb dessen ich eine Funktion aufrufe, die mir eine Text-Box aktualisiert. Diese Textbox ist Member des Gui-Threads(Main-Thread). Nun tritt eben der allseits bekannte Fehler mit dem Threadübergreifendenzugriff auf ein Control auf.

Problem: Warum tritt dieser Fehler denn auf, wenn ich doch die Aktualisierung-Funktions der Textbox aus einer Funktion des GUI-Thread aufrufe. Die Aktualisierungs-Funktion liegt doch im GUI-Thread.

Möglicherweise liegt es eben daran, dass die Funktionsaufrufe(Callback-Funktionsaufruf aus dem TCP-Thread-->CallBack-Funktion des GUI-Thread-->Aktualisierungsfunktion der Textbox innerhalb des GUI-Threads) alle im Kontext des TCP-Thread ablaufen.

Was meint ihr?

Ich probiers mal mit Events, erwarte aber dieselben Probleme. Lösung:Invoke

24.05.2007 - 10:27 Uhr

Hi, danke für die Hilfe.

Die EventHandler im Thread laufen doch nur, wenn ich auch im Thread selbst ein EventHandler für dieses Ereignis implementiert habe. Bei meiner Implementierung hab ich nur im Main-Thread für dieses Ereignis EventHandler registriert.

23.05.2007 - 11:38 Uhr

Hallo Forum.

Habe eine Hauptanwendung geschrieben, die einen Polling-Thread erzeugt. Innerhalb dieses PollingThread wird auf eingehende TCP-Pakete gewartet. Kommt nun ein Paket an, so wird eine vorgebene CallBack-Funktion vom PollingThread aufgerufen.

Möchte ich nun der Hauptanwendung mitteilen, dass die Socket-Verbindung vom Remote-Host geschlossen wurde und der Polling-Thread somit gecancelt werden muss, so gibt es doch zwei Möglichkeiten, um dies der Hauptanwendung mitzuteilen:

  1. Ich werfe eine Exception, die von der Hauptanwendung abgefangen wird oder,

  2. Der Polling-Thread löst ein Ereignis aus, das von der Hauptanwendung registriert wird.

Meine Frage: Was ist eleganter oder gibts ne andere Möglichkeit?

Gruß

21.05.2007 - 14:41 Uhr

Hi Forum,

hab da ein Problem mit der Deklaration von Strukturen und IntelliSense.

Wenn ich das unten aufgeführte Code-Fragment meinem Visual-Studio-Prof. überlasse, so löst die integrierte Namensauflösung nicht die Struktur auf. Es werden lediglich die Members "dat" und "dat2" mit IntelliSense aufgelöst.

Woran könnte das liegen? Oder welchen Anfängerfehler mach ich hier?

public struct Frame{
public int dat1;
public int dat2;

public struct Blubb{

public int value;
}

}

Danke für eure Hilfe.

Gruß