Benutzersteuerelemente II



  • ich habe ein problem beim einbinden eines neuen steuerelements :
    ich habe mein neues steuerelement "test" genannt und eine property problemNr erstellt auf die in Form1.h zugegriffen werden soll!
    Allerdings bekomme ich die fehlermeldung :

    1. problemNr sei kein element von UserControl

    wie kann ich denn jetzt in diesem fall auf problemNr zugreifen ??

    test.h:

    #pragma once
    
    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;
    
    namespace erneuter_test {
    
    	/// <summary>
    	/// Zusammenfassung für test
    	/// </summary>
    	public ref class test : public System::Windows::Forms::UserControl
    	{
    	public:
    		test(void)
    		{
    			InitializeComponent();
    			//
    			//TODO: Konstruktorcode hier hinzufügen.
    			//
    		}	
    	protected:
    		/// <summary>
    		/// Verwendete Ressourcen bereinigen.
    		/// </summary>
    		~test()
    		{
    			if (components)
    			{
    				delete components;
    			}
    		}
    
    	private: System::Windows::Forms::Button^  button1;
    
    	protected: 
    
    	private:
    		/// <summary>
    		/// Erforderliche Designervariable.
    		/// </summary>
    		System::ComponentModel::Container ^components;
    
    #pragma region Windows Form Designer generated code
    		/// <summary>
    		/// Erforderliche Methode für die Designerunterstützung.
    		/// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden.
    		/// </summary>
    		void InitializeComponent(void)
    		{
    			this->button1 = (gcnew System::Windows::Forms::Button());
    			this->SuspendLayout();
    			// 
    			// button1
    			// 
    			this->button1->Location = System::Drawing::Point(3, 3);
    			this->button1->Name = L"button1";
    			this->button1->Size = System::Drawing::Size(75, 23);
    			this->button1->TabIndex = 0;
    			this->button1->Text = L"button1";
    			this->button1->UseVisualStyleBackColor = true;
    			this->button1->Click += gcnew System::EventHandler(this, &test::button1_Click);
    			// 
    			// test
    			// 
    			this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
    			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
    			this->Controls->Add(this->button1);
    			this->Name = L"test";
    			this->Size = System::Drawing::Size(370, 265);
    			this->Load += gcnew System::EventHandler(this, &test::test_Load);
    			this->ResumeLayout(false);
    
    		}
    #pragma endregion
    
    	private: static int problem = 5;
    	public: property int problemNr 
    			{
    				int get( ) { return problem; }
    				void set( int a ) { problem = a ; }
    			}
    	private: System::Void test_Load(System::Object^  sender, System::EventArgs^  e) {
    			 }
    	private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
    
    			 }
    	};
    }
    

    Form1.h

    #pragma once
    #include "test.h"
    namespace erneuter_test {
    
    	using namespace System;
    	using namespace System::ComponentModel;
    	using namespace System::Collections;
    	using namespace System::Windows::Forms;
    	using namespace System::Data;
    	using namespace System::Drawing;
    
    	/// <summary>
    	/// Zusammenfassung für Form1
    	/// </summary>
    	public ref class Form1 : public System::Windows::Forms::Form
    	{
    	public:
    		Form1(void)
    		{
    			InitializeComponent();
    			//
    			//TODO: Konstruktorcode hier hinzufügen.
    			//
    		}
    
    	protected:
    		/// <summary>
    		/// Verwendete Ressourcen bereinigen.
    		/// </summary>
    		~Form1()
    		{
    			if (components)
    			{
    				delete components;
    			}
    		}
    
    	private:
    		/// <summary>
    		/// Erforderliche Designervariable.
    		/// </summary>
    
    		System::Windows::Forms::UserControl^ testCtrl;
    	private: System::Windows::Forms::Label^  label1;
    			 System::ComponentModel::Container ^components;
    
    #pragma region Windows Form Designer generated code
    		/// <summary>
    		/// Erforderliche Methode für die Designerunterstützung.
    		/// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden.
    		/// </summary>
    		void InitializeComponent(void)
    		{
    			this->label1 = (gcnew System::Windows::Forms::Label());
    			this->SuspendLayout();
    			// 
    			// label1
    			// 
    			this->label1->AutoSize = true;
    			this->label1->Location = System::Drawing::Point(193, 187);
    			this->label1->Name = L"label1";
    			this->label1->Size = System::Drawing::Size(35, 13);
    			this->label1->TabIndex = 0;
    			this->label1->Text = L"label1";
    			// 
    			// Form1
    			// 
    			this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
    			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
    			this->ClientSize = System::Drawing::Size(284, 262);
    			this->Controls->Add(this->label1);
    			this->Name = L"Form1";
    			this->Text = L"Form1";
    			this->Load += gcnew System::EventHandler(this, &Form1::Form1_Load);
    			this->ResumeLayout(false);
    			this->PerformLayout();
    
    		}
    
    #pragma endregion
    
    	private: System::Void Form1_Load(System::Object^  sender, System::EventArgs^  e) {
    				 testCtrl = gcnew test;
    				 this->Controls->Add( testCtrl );
    				 testCtrl->Dock = System::Windows::Forms::DockStyle::Fill;
    				 label1->Text = Convert::ToString( testCtrl->problemNr );  
    			 }
    
    	};
    }
    


  • wie kann ich denn jetzt in diesem fall auf problemNr zugreifen ??

    Genau so wie Du es in Form1::Form1_Load(..) schon gemacht hast.

    label1->Text = Convert::ToString( testCtrl->problemNr );
    

    ABER:
    Du kannst nicht eine Form (hier test) einer andern Form (hier Form1) einfach als Control verkaufen. D.h.

    this->Controls->Add( testCtrl );
    

    etc. geht nicht! Du kannst die Form test einfach anzeigen mit Show(..) oder ShowDialog(..). Das macht aber wahrscheinlich keinen Sinn im Load Handler oder im Konstruktor - das müsste man z.B. per Knopfdruck machen. Ev. suchst Du doch eher ein Control?

    Anmerkung:
    test::problem muss nicht (= darf in deinem Fall nicht!!) static sein!!! Warum machst Du das???



  • Nur mal rein prinzipiell: Warum machst du sowas in C++/CLI!? Die Sprache ist dafür denkbar ungeeignet und du ziehst keinen Vorteil draus es nicht einfach in C# zu machen wo das alles sehr viel einfacher geht. Der Code da oben wird in der CLR laufen wie jeder .NET Code, d.h. es ist nicht so wie du vielleicht denkst dass du da irgendeinen Performancevorteil hättest nur weil deine Sprache ein C++ im Namen hat (C++/CLI ist nicht C++, nur um das klarzustellen). Abgesehen davon dass das bei so UI Geschichten sowieso eher keine Rolle spielt.



  • Hallo theta,

    du hast dich hier wohl verlesen: test ist hier ein UserControl (keine Form).

    Und auch hallo derLe0n,
    ich stimme @dot zu: C# ist hier um einiges besser geeignet!



  • Auja, stimmt - hatte wohl Tomaten auf den Augen. 😋

    Edit:
    Jetzt seh ich das Problem:
    in Form1 gibts ein Element testCtrl. Es ist vom Typ UserControl.
    UserControl hat aber KEIN Property (oder Element) mit Namen prolemNr. Denn problemNr ist ein Property von test!
    Also: Benutze test und nicht UserControl in Form1.

    ref class Form1 : public ...
    {
    private:
       //System::Windows::Forms::UserControl^ testCtrl;
       test^ testCtrl;
    };
    


  • ok vielen dank für die hilfe , theta 🙂
    und an die anderen beiden, ich benutze c code und kann nkeine wrapper - klassen erstellen 😉



  • [quote="theta"]

    Anmerkung:
    test::problem muss nicht (= darf in deinem Fall nicht!!) static sein!!! Warum machst Du das???

    weil ich die fehlermeldung bekomme , nur statische datennmember dürfen hier deklariert werden, und mit static klappt das zugreifen auf die Property auch 🙂



  • [quote="derLe0n"]

    theta schrieb:

    Anmerkung:
    test::problem muss nicht (= darf in deinem Fall nicht!!) static sein!!! Warum machst Du das???

    weil ich die fehlermeldung bekomme , nur statische datennmember dürfen hier deklariert werden, und mit static klappt das zugreifen auf die Property auch 🙂

    static macht hier aber kein Sinn und ist falsch.
    Initialisiere Member Variablen im Konstruktor!



  • [quote="theta"]

    derLe0n schrieb:

    theta schrieb:

    Anmerkung:
    test::problem muss nicht (= darf in deinem Fall nicht!!) static sein!!! Warum machst Du das???

    weil ich die fehlermeldung bekomme , nur statische datennmember dürfen hier deklariert werden, und mit static klappt das zugreifen auf die Property auch 🙂

    static macht hier aber kein Sinn und ist falsch.
    Initialisiere Member Variablen im Konstruktor!

    aber global kann ich trotzdem darauf zugreifen ??



  • Sofern Du eine Referenz auf das entsprechende Objekt hast: Ja.

    Mache Dir mal klar was es mit Klassen und Objekten von Klassen auf sich hat!



  • sag mir doch noch mal bitte schnell wie ich jetzt auf die Variable aus dem Konstruktor zugreife !! 🙂



  • ref class Form1 : public ...
    {
    public:
       Form1()
       {
          InitializeComponent();
    
          // Hier im Konstruktor deine Membervariablen initialisieren!
          myValue = 4711;
       }
    
    private:
       int myValue;
    
    public:
       property int MyValue
       {
          int get()
          {
             return myValue;
          }
    
          void set(int value)
          {
             myValue = value;
          }
       }
    };
    


  • ok , soweit alles geklärt 😃
    dankesehr :**



  • jetzt habe ich doch noch eine Frage : wie kann ich aus dem Steruelement auf einer Funktion der Form1.h zugreifen ??

    muss ich die Funktion als public und dann im steuerelement als extern definieren ??



  • Warum willst du auf eine Methode der Form zugreifen?



  • um mittels eines knopfes auf einem steuerelement eine funktion auf der hauptform aufzurufen... z.b. um einen Timer zu starten , der ein neues Steuerelement initialisiert 😉



  • Dafür verwendet man events.


Anmelden zum Antworten