Laden...

Forenbeiträge von Phaiax Ingesamt 56 Beiträge

11.06.2006 - 21:04 Uhr

schon klar,

ich meinte z.B. irgendeine Variable oder Funktion zum Überschreiben, um während der ausführung des Codes an dem Rumzubasteln, was der Designer (class ParentControlDesigner) ausgibt (und dann in die .Designer Datei schreibt).

11.06.2006 - 18:38 Uhr

Hallo

Meine Situation:

Ich habe ein Usercontrol (die Klasse "Rahmen"), das Designerfunktionen unterstützen soll.

Was ist ein Designer?
Der Designer sorgt dafür, dass man z.B. ein Panel programieren kann. Wenn eine Komponente einen Designer hat, kann der Bereich in der Komponente im Editorfenster benutzt werden.
Das funktioniert auch mit verschachtelten Designern: Zum Beispiel lässt sich im SplitControl sowohl in die Linke als auch in die rechte Hälfte ein Element setzen, das der jeweiligen Seite im SplitControl gehört, und nicht dem Splitcontrol. Schaut man sich im Eigenschaftfenster eine der Seiten von SplitControl an, sieht man, dass die Seiten Panel1 und Panel2 heißen.

Hat eine Komponente keinen Designer, z.B. der Button passiert folgendes:
Plaziert man auf einem übergroßen Button ein Label und verkleinert dann den Button immer weiter, sieht man, dass das Label auch noch sichtbar ist, wenn der Button schon nicht mehr hinter dem Label ist.
Bei einem Panel verschwindet das Label dann "im verkleinerten Bereich".

Deshalb wird der Designer, der als Unterklasse von Rahmen deklariert ist, der Klasse Rahmen zugeordnet:
[Designer(typeof(Rahmen.MyControlDesigner))]

In der Klasse Rahmen gibt es eigentlich 3 Unterelemente (alle ähnlich der Komponente "Panel"), die ich allerdings wegen der Übersichtlichkeit auf 1 (dieses eine ist mein Problemfall) gekürzt habe.

Dieses eine Unterelement der Klasse Rahmen heist InnerControl (Klasse Mitte) und befindet sich angedockt auf der ganzen Fläche von Rahmen. Es(=InnerControl) soll ebenfalls Designerfunktionen unterstützen.
Deshalb ist der Kasse Mitte ist auch ein Designer zugeordnet:
[Designer(typeof(Mitte.MyControlDesigner))]

Die Funktion EnableKinds() in der Klasse Rahmen.MyControlDesigner führt für alle in "Rahmen.DesignerControlObjects" angegebenen Controls die Funktion "EnableDesignMode(var, var.Name);" aus. Diese Funktion soll laut Dokumentation Vorgänge im Designer-Editor-Fenster gegebenenfalls an den Designer der Instanz von Mitte, also InnerControl weiterleiten.

Erstellt man ein Form-Objekt zum testen und plaziert eine Instanz von Rahmen darauf, sollte man auf der Rahmen-Instanz, wie bei einem "Panel", z.B. einen Button plazieren können.
Das geht gut, solange man sich in der Designeransicht befindet. Startet man allerdings das Form, erscheint der Button nicht.
Das liegt daran, dass in der Form1.Designer-Datei im Bereich "#region Vom Windows Form-Designer generierter Code" diese Zeile nicht hinzugefügt wird.
this.rahmen1.InnerControl.Controls.Add(this.button1);

Bei einem Split-Container wird das anstandslos hinzugefügt.

Die Zeilen
this.rahmen1.SuspendLayout(); und
this.rahmen1.ResumeLayout(false);
, die für die Layoutlogik zuständig sind, fügt der Designer aber hinzu.

Hier der Code ...

... der Klasse Rahmen:

    [Designer(typeof(Rahmen.MyControlDesigner))]
    public partial class Rahmen : UserControl
    {

        // Deklaration der Steuerelemente
        public Mitte InnerControl;

        public Rahmen()
        {
            //InitializeComponent();
            SetzeControlEigenschaften();

            DesignerLayoutNeuZeichnen(true, true, true);
        }

         /// <summary>
        /// Intialisiert dieses Steuerelement mit untergeordneten Steuerelementen
        /// </summary>
        private void SetzeControlEigenschaften()
        {
            #region Speicher reservieren
                this.InnerControl = new Mitte();
            #endregion

            this.SuspendLayout();

            #region InnerControl / Mitte
                this.InnerControl.Location = new System.Drawing.Point(0, 0);
                this.InnerControl.Name = "InnerControl";
                this.InnerControl.Size = this.Size;
                this.InnerControl.TabIndex = 0;
	    #endregion


        }


        
        /// <summary>
        /// Bestimmt die Größe der Elemente neu und erklährt das Layout für ungültig
        /// </summary>
        /// <param name="Rechts">Rechte Leiste an/ausschalten</param>
        /// <param name="Links">Linke Leiste an/ausschalten</param>
        /// <param name="Unten">Untere Leiste an/ausschalten</param>
        public void DesignerLayoutNeuZeichnen(bool Rechts, bool Links, bool Unten)
        {
            // Layoutlogik anhalten
            this.SuspendLayout();

            
            #region Mitte Größe korregieren
                // Mittelbereich festlegen
//......
                  // § Innercontrol ist immer als Container enthalten
            #endregion
            

            // Layout neu zeichen
            this.Invalidate(true);
            this.PerformLayout();
            this.ResumeLayout(true);

        }

        /// <summary>
        /// Objekte, für die der Designer aktiviert werden soll
        /// </summary>
        internal Control[] DesignerControlObjects
        {
            get
            {
                return new Control[] { this.InnerControl };
            }
        }

        // Resize Fubktion überschreiben
        protected override void OnPaint(PaintEventArgs e)
        {
            DesignerLayoutNeuZeichnen();
        }



        /// <summary>
        /// ParentControlDesigner Ableitung für die Rahmen Klasse
        /// </summary>
        internal class MyControlDesigner : System.Windows.Forms.Design.ParentControlDesigner
        {
            // Intialisieren
            public override void Initialize(IComponent component)
            {
                base.Initialize(component);
                EnableKinds();
            }

            // Resize-Funktionen
            public override System.Windows.Forms.Design.SelectionRules SelectionRules
            {
                get
                {
                    if (this.Control.Dock == DockStyle.Fill)
                    {
                        return
                            System.Windows.Forms.Design.SelectionRules.Locked;
                    }
                    else
                    {
                        return
                            System.Windows.Forms.Design.SelectionRules.Visible |
                            System.Windows.Forms.Design.SelectionRules.Moveable |
                            System.Windows.Forms.Design.SelectionRules.AllSizeable;
                    }
                }
            }

            // Keine Elemente Akzeptieren
            public override bool CanParent(Control control)
            {
                return false;
            }

 
            /// <summary>
            /// Aktiviert den Designer für Kindobjekte
            /// </summary>
            private void EnableKinds()
            {
                Rahmen uc = (Rahmen)this.Component;
                foreach (Control var in uc.DesignerControlObjects)
                {
                    EnableDesignMode(var, var.Name);
                    this.EnableDragDrop(true);
                }
            }

        }


    }


... der Klasse Mitte


    [Designer(typeof(Mitte.MyControlDesigner))]
    public partial class Mitte : System.Windows.Forms.UserControl
    {
        string _Text;
        public string Text
        {
            get { return _Text; }
            set { _Text = Text; }
        }


        /// <summary>
        /// Ableitung von ParentControlDesigner zum Nichtanzeigen der Größenänderungspfeile
        /// </summary>
        internal class MyControlDesigner : System.Windows.Forms.Design.ParentControlDesigner
        {

            public override void Initialize(IComponent component)
            {
                base.Initialize(component);
                this.EnableDragDrop(true);
            }

            // Anfasspunkte bestimmen d.h. verbieten
            public override System.Windows.Forms.Design.SelectionRules SelectionRules
            {
                get
                {
                    return System.Windows.Forms.Design.SelectionRules.Locked;
                }
            }

            // Fügt eine gestrichelte Linie hinzu
            protected override void OnPaintAdornments(PaintEventArgs pe)
            {
                Pen p = new Pen(Color.DarkGray);
                p.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
                Rectangle r = new Rectangle(0, 0, this.Control.Size.Width - 1, this.Control.Size.Height - 1);
                pe.Graphics.DrawRectangle(p, r);
                base.OnPaintAdornments(pe);
            }
        }

    }

Ich habe leider nur die Express-Version von VS 2005, deswegen fehlt mir eine Hostumgebung zum testen von Komponenten.

Zum Schluss noch eine Frage, die mir auch weiterhelfen könnte:
In allen FormX.Designer-Dateien steht immer
#region Vom Windows Form-Designer generierter Code
[....]
#endregion
Gibt es eine Möglichkeit, an diesen Code dranzukommen, das heist ihn zu manipulieren, bevor er in die Datei hineingeschrieben wird?

Ich hoffe ich habe mein Problem detailiert genug beschrieben.

Freundliche Grüße, Phaiax

Edit: Ich hab alles mal etwas genauer formuliert...

22.05.2006 - 17:38 Uhr

olala, vielen, vielen Dank.

Wie kommt man auf sowas?^^ (eigentlich rethorische Frage, interessieren tuts mich aber doch)

22.05.2006 - 17:13 Uhr

Leider siehts bei mir so aus:
Das bild gibts leider nicht mehr

Naja.

Ist vielleicht jemand so nett , leitet eine Klasse von ParentControlDesigner ab und schickt sie mir als DLL (der Quellcode nütuzt mir nichts)?

EDIT: Ich frag jetzt mal die Onlineuser
EDIT2: Meine Emailadd: phaiax@online.de

21.05.2006 - 21:30 Uhr

Ich hab jetzt noch ein wenig gesucht und ParentControlDesigner gefunden.

laut http://msdn2.microsoft.com/de-de/library/system.windows.forms.design.parentcontroldesigner_members(d=ide).aspx
sollte die sich System.Windows.Forms.Design verbergen, oder?

Wenn ich aber
using System.Windows.Forms.Design mache, gibt es kein ParentControlDesigner.
Ich programmiere noch nicht so lange C# (2 Monate vielleicht), aber mache ich irgentetwas falsch?? (Ich benutze MS V C# 2005 EE).

21.05.2006 - 20:51 Uhr

Hallo,

ich suche einen Weg, wie man Komponenten in einen Bereich einer anderen selbstgeschriebenen Komponente hineinsetzten kann. So wie bei Panel, TabControl, FlowLayoutPanel, TableLayoutpanel...

Dabei soll nur ein Bereich in meiner Komponente "Ablage" für andere Komponenten sein.

Genauer: Ich will mir ein Toolbar-Docking System basteln. Also sozusagen ein ToolStripContainer nicht nur für MenüStrips.

Grüße, Phaiax