Laden...

UserControl - Frage

Erstellt von Harown vor 17 Jahren Letzter Beitrag vor 17 Jahren 1.771 Views
Harown Themenstarter:in
19 Beiträge seit 2007
vor 17 Jahren
UserControl - Frage

Hallo,
ich hoffe ihr könnt mir helfen:
Ich versuche ein UserControl zu bauen, das eine unterschiedliche Anzahl an TextBoxen aufnehmen kann. Wieviel das sind,
hängt vor allem von der DataSource ab. Man kann aber auch manuell welche hinzufügen. Im Prinzip also genauso wie beim
DataGrid mit seinen Spalten, nur dass es sich hierbei um TextBoxen handelt.
Nachdem im DataGrid die Spalten festgelegt wurden, werden in InitializeComponent der WindowsForm, die das Grid enthält, die einzelnen Spalten deklariert und initialisiert à la


this.ortDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
...	    
// 
// ortDataGridViewTextBoxColumn
// 
this.ortDataGridViewTextBoxColumn.DataPropertyName = "Ort";
this.ortDataGridViewTextBoxColumn.HeaderText = "Ort";
this.ortDataGridViewTextBoxColumn.Name = "ortDataGridViewTextBoxColumn"; 

und zum Grid hinzugefügt über AddRange.

Wie funktioniert das? Wie sagt das DataGrid nach dem Festlegen seiner Columns der WindowsForm, dass es die Zeilen in seine InitializeComponent Methode schreiben soll?
Wäre sehr dankbar für Antworten.

Mathias

2.921 Beiträge seit 2005
vor 17 Jahren

Erklär mal das bitte genauer. Ansonsten müßtest Du eine abgeleitete Klasse machen bei der Du im Konstruktor das ganze entsprechend der Datagrid-Quelle initialisierst.

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.

Harown Themenstarter:in
19 Beiträge seit 2007
vor 17 Jahren

Die Komponente ist von UserControl abgeleitet und soll dem Entwickler eine bestimmte Anzahl an TextBoxen zur Verfügung stellen. Er kann also welche hinzufügen und entfernen. Das klappt zur Design-Zeit auch ganz gut, nur sind die Textboxen Bestandteil meines UserControls. Ich möchte aber, dass die Boxen Bestandteile des Forms werden, die das UserControl enthält. Deswegen das Beispiel mit dem DataGrid. Fügt man eine Spalte zu diesem hinzu, so befindet sich die Deklarierung und Initialisierung dieser Spalte in der Form. Zusätzlich wird dann diese Spalte zusammen mit den anderen über AddRange dem DataGrid hinzugefügt (auch wieder in InitializeComponent der Form). Ist es möglich, sowas auch für eigene UserControls zu schreiben?

P
56 Beiträge seit 2006
vor 17 Jahren

So, mit der Problematik hab ich mich auch längere Zeit beschäftigt.

Erstmal einen Verweis auf System.Design

Dann eine Klasse von ParentControlDesigner ableiten (geht vielleicht auch mit ControlDesigner, keine ahnung), z.B. TextBoxGridDesigner

Deine UserControl Deklaration so werweitern:


[Designer(typeof(TextBoxGridDesigner))]
class TextBoxGrid : UserControl
{

}

So sollte die Sache funktionieren.

Allerdings gibts so (glaub ich) kein Rückgängig/Undo in Visual Studio. Ich weiß wies gehen sollte, nur fällts mir grad nicht genau ein. Irgendwas mit Transaction

Diesen kleinen Pfeil kriegst du hin, wenn du die Eigenschaft Verbs überschreibst.

Leider gibts nicht viele Tutorials dazu, aber wenn du nach den richtigen Wörtern suchst, findest du sie.

Ich hab jetzt leider keine Zeit/Lust in meinem Projekt nachzuschauen, wenn du doch mehr wissen willst, frag grad nochmal.

PS:

Wenn dus so machst, werden die Textboxen auch deinem TextBoxGrid zugeordnet.

Also in der Intialisize Methode steht nicht

this.Controls.Add(bla);

sondern

this.TextBoxGrid1.Controls.Add(bla); // steht dann nicht am Ende sondern bei den Eigenschaftszuweisungen des TextBoxGrid1

Hoffe ich konnte dir helfen. Das sollte der richtige Weg sein, wenn ich dich auch richtig verstanden habe

Gruß Phaiax

//edit: c#-code-tags ergänzt!!!

Harown Themenstarter:in
19 Beiträge seit 2007
vor 17 Jahren

Hey Phaiax,
vielen Dank für deine Antwort. Du hattest mich richtig verstanden, genau das was du als Beispiel aufgeführt hast, habe ich nun auch erreicht. Allerdings nicht mit dem ParentControlDesigner, sondern durch das Setzen von

[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]

über die Liste-Property (die die TextBoxen enthalten soll). Sieht jetzt also so aus:
Im UserControl:

[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[Editor("System.Windows.Forms.Design.CollectionEditor,System.Design",
"System.Drawing.Design.UITypeEditor, System.Drawing")]
        public List<EinsItem> Items
        {
            get
            {
                return _items;
            }
        }

Im WindowsForm:

 this.senderControl.Items.Add(this.einsItem1);

(EinsItem ist ne Klasse, die jeweils 1 TextBox enthält, schrieb bislang von TextBoxen um's einfacher zu halten)

Wie kann ich jetzt erreichen, dass neben Add auch AddRange geschrieben wird, und zwar immer dann wenn die DataSource gesetzt wird? Meine DataSource-Property im UserControl sieht im Moment so aus:

public BindingSource DataSource
        {
            get { return _dataSource; }
            set
            {
                _dataSource = value;
                createItems(); 
            }
        }

In createItems() werden anhand der DataSource dann schleifenmäßig die EinsItems erzeugt und meiner Liste _items hinzugefügt. Dass dadurch nicht AddRange im WindowsForm serialisiert wird, ist klar. Nur wie könnte man das erreichen? Irgendeine Idee?

Danke schön!

J
3.331 Beiträge seit 2006
vor 17 Jahren
Off-Topic

Hallo Mathias,

stellst Du Deine Erkenntnisse auch den Lesern beim Entwickler-Forum zur Verfügung? Jürgen

P
56 Beiträge seit 2006
vor 17 Jahren

klar, hatt ich ganz vergessen ...

Noch so eine kleine Bemerkung:

Wenn man bei einem Usercontrol schon während der Anzeige im Designer funktionierende Buttons haben will, die Funktion EnableDesignMode() in oben erwähntem ParentControlDesigner benutzen. (nur so als Memo, falls ich mal wieder selbst vor diesem Problem stehe)