2013-05-10 12 views
5

Ich habe eine Control lblDate in User Control MainScreen. Ich möchte es in einer Methode in Klasse Date ändern, die in einem anderen Projekt AoWLibrary ist. Ich kann nicht darauf verweisen, da AoWLibrary vom ersten Projekt abhängig ist.Windows Forms Control von einem anderen Projekt ändern

Ich versuchte lblDate statisch zu machen, aber der Compiler gehalten Fehler bei mir zu werfen, und ich habe ein öffentliches Eigentum, das Datum nicht zugänglich scheinen:

public Label LabelDate 
    { 
     get { return lblDate; } 
     set { lblDate = value; } 
    } 

In der Klasse Date, ich brauche öffentliche Methode CalculateDate die Eigenschaft Text von lblDate

public static void CalculateDate() 
    { 
     GameDate = month.ToString() + "/" + displayDay.ToString() + "/" + year.ToString(); 

    // LabelDate.Text = GameDate; 
    // This is essentially what I need to do 
    } 

auch ich kann nicht einmal Zugang lblDate in anderen Steuerungen im selben Projekt zu ändern.

+2

Sie können Steuerelemente aus einer anderen Klasse ändern, wenn Sie ein instanziiertes Objekt in der Controller-Klasse haben. – lexeRoy

+0

Tut der Designer das nicht automatisch? –

+0

Können Sie den Code anzeigen lassen (oder ein Codebeispiel würde ausreichen), wo Sie ein anderes Formular aufrufen? – lexeRoy

Antwort

1

So ist die allgemeine Idee ist, dass Sie den Überblick behalten müssen, was in ihrem Umfang ist. Es gibt viele Möglichkeiten, um das zu tun, was Sie tun möchten, aber einige von ihnen sind darauf angewiesen, dass Objekte sich gegenseitig auf eine Weise referenzieren, die Sie vielleicht noch nicht ganz verstehen. Mach dir keine Sorgen - jeder muss das irgendwann durcharbeiten.

Der Grund, warum der Compiler sich beschwert hat, als Sie versucht haben, dieses Member statisch zu machen, liegt daran, dass das Label selbst nicht statisch ist. Da es an eine einzelne MainScreen-Instanz gebunden ist, hat es in einem statischen Kontext keine Bedeutung, der definitionsgemäß ein Bereich ohne eine inhärente Referenz auf eine bestimmte MainForm ist.

Ihre Date-Klasse ist natürlich auch ein völlig anderer Kontext, aber ihre nicht statischen Member haben Zugriff auf eine Instanz von Date. Zwischen diesen beiden Kontexten gibt es keinen Pfad, bis Sie ihn erstellen. Die statische Route hätte tatsächlich funktioniert (schauen Sie sich das Singleton-Muster an: die Idee ist, dass Sie die erste und einzige Instanz einer Klasse statisch speichern und von woanders darauf verweisen), aber wahrscheinlich kein gutes Design. Andere Möglichkeiten, dies zu tun, sind das Übergeben einer Instanz von MainScreen an Date (vorzugsweise über eine Schnittstelle) oder sogar LabelDate selbst. Alle diese könnten die zwei Stücke bekommen, die Sie zusammen brauchen, um zu sprechen.

Allerdings möchte ich vorschlagen, dass Sie darüber nachdenken, wo Ihr Spielzustand gespeichert wird. Ist es in der Bibliothek oder in der konsumierenden Versammlung? Im ersten Fall sollten Sie darüber nachdenken, ein vollständiges GUI-loses Modell der Daten zu erstellen, die in der Bibliotheksklasse gespeichert und bearbeitet werden müssen, und diese vorgefertigten Daten nur so zu verwenden, wie sie in der Hauptanwendung vorhanden sind. Die andere Alternative besteht darin, dass sich Ihr Modell in der Hauptanwendung befindet und nur bei Bedarf zu Ihrer Bibliothek zurückruft. In diesem Fall sollten Sie wahrscheinlich vorerst die Bibliothek um Antworten bitten (oder höchstens auf Ereignisse in der Bibliothek achten) und NICHT erwarten, dass sie allein auf die Anwendung zurückgreift (ob Sie Informationen erhalten oder bereitstellen).

Wenn Sie herausfinden, wie Sie dies tun, werden Sie wahrscheinlich feststellen, dass Ihre Probleme mit der Bereichsverwaltung viel einfacher zu handhaben sind. Sogar ein bisschen gute Architektur kann einen langen Weg zurücklegen.

Aber wenn das alles ein wenig überwältigend ist, betonen Sie es nicht zu sehr. Es hört sich so an, als würdest du das aus Spaß machen, was eine tolle Art zu lernen ist. Sie werden auf solche Probleme stoßen und entweder auf ein gutes Design oder ein nicht so gutes treffen, aber so oder so, Sie kämpfen mit wichtigen Konzepten und werden besser dafür kommen.

+0

Ich habe gerade Singleton ausgecheckt und es in meinen Code implementiert, und ich bin sehr zufrieden damit, wie es funktioniert. Danke für deinen Rat. Es sollte mir eine große Hilfe sein. –

0

Die Eigenschaft LabelDate stammt aus der Klasse Ihres userControl MainScreen, aber Sie richten kein userControl ein. Welche MainScreen-Instanz möchten Sie dann ändern?

sollten Sie

this.controlMainScreen.LabelDate = GameDate; 

Berücksichtigung tun, dass Sie in Ihren Kommentaren sagen, dass Sie

FormMain.Designer.cs there is: this.controlMainScreen = new Adventurers_of_Wintercrest.UserControls.MainScreen(); 
+0

In FormMain.Designer.cs gibt es: this.controlMainScreen = new Abenteurer_of_Wintercrest.UserControls.MainScreen(); Muss das nicht passieren? –

+0

Siehe meine Bearbeitung. Das geht natürlich davon aus, dass sich Ihr Code in FormMain befindet (Sie geben nie an, wo es ist) –

+0

Das erste Bit, das ich gepostet habe, befindet sich in MainScreen.cs, das sich im Namespace Adventurers_of_Wintercrest.UserControls befindet. Das zweite Bit befindet sich in Date.cs, das sich im AoWLibrary-Namespace befindet. –

0

haben würde ich eher empfehlen Ihnen, Ihre GameDate Methode machen einen String zurück dann rufen Sie es aus Ihr Hauptprojekt, die im Wesentlichen sind, für welche Bibliotheken bestimmt sind. z.B .:

public static string CalculateDate() 
{ 
    return month.ToString() + "/" + displayDay.ToString() + "/" + year.ToString(); 
} 

//in your main project 
LabelDate.Text = myLibrary.CalculateDate(); 

Für ihn von anderen Kontrollen im selben Projekt zugreifen, sollten Sie einen Delegaten verwenden - einen Delegierten schaffen, die den Zusatz führt, den Delegaten deklarieren und die Funktion von Ihrem CaculateDate aufrufen. Beispiel:

public delegate void dateSet(string); 

public void setDate(string date) 
{ 
    labelDate.Text = date; 
} 

dann in Ihrer CaculateDate Methode:

labeldate.Invoke(new MainForm.dateSet(), GameDate); 
+0

Wohin soll der Delegierte gehen? –

+0

Der Delegat sollte in Ihrem Hauptprojekt, in dem das Label existiert, deklariert werden. –