Eigenes UserControl

Tim Bureck

Erfahrenes Mitglied
Ich habe mich jetzt den ganzen Tag damit aufgehalten, ein eigenes UserControl zu schreiben, das auch über die VS ToolBox bedienbar ist. Leider ohne wirklichen Erfolg. Ich kann das Control nirgends sehen oder aktivieren... Sämtliche Tutorials/Codeschnipsel haben mich kein Stück weiter gebracht, keine Ahnung was ich falsch mache.

Im Folgenden mal das, was ich gemacht habe:

NFZDrawPanel.cs
C#:
    [ToolboxItem(typeof(NFZDrawPanelToolboxItem))]
    [ToolboxBitmap("DrawPanel.bmp")]
    public partial class NFZDrawPanel : UserControl {

        public static readonly int ZOOM_STANDARD = 1;
        public static readonly int ZOOM_MINIMUM = 1;
        public static readonly int ZOOM_MAXIMUM = 16;

        private NFZCarView carView;

        private int zoomLevel;

        public NFZDrawPanel() {
            this.carView = null;
            this.ZoomLevel = NFZDrawPanel.ZOOM_STANDARD;

            InitializeComponent();
        }

        #region Event handling
        protected override void OnPaint(PaintEventArgs pe) {
            base.OnPaint(pe);
        }

        protected override void OnMouseClick(MouseEventArgs e) {
            base.OnMouseClick(e);
        }

        protected override void OnMouseWheel(MouseEventArgs e) {
            base.OnMouseWheel(e);
        }
        #endregion

        #region Properties
        public int ZoomLevel {
            get { return this.zoomLevel; }
            set {
                if (value < NFZDrawPanel.ZOOM_MINIMUM || value > NFZDrawPanel.ZOOM_MAXIMUM) {
                    throw new ArgumentException("The zoom level must be between " +
                        NFZDrawPanel.ZOOM_MINIMUM + " and " + NFZDrawPanel.ZOOM_MAXIMUM + ".");
                }

                this.zoomLevel = value;
            }
        }

        public NFZCarView CarView {
            get { return this.carView; }
            set {
                if (value == null) {
                    throw new ArgumentNullException("The car view may not be null.");
                }

                this.carView = value;
            }
        }
        #endregion

    }

NFZDrawPanelToolboxItem.cs
C#:
    [Serializable]
    public class NFZDrawPanelToolboxItem : ToolboxItem {

        public NFZDrawPanelToolboxItem() : base(typeof(NFZDrawPanel)) { }

        public NFZDrawPanelToolboxItem(SerializationInfo info, StreamingContext context) {
            this.Deserialize(info, context);
        }

        protected override IComponent[] CreateComponentsCore(IDesignerHost host) {
            NFZDrawPanel drawPanel = ((NFZDrawPanel) host.CreateComponent(typeof(NFZDrawPanel)));

            return new IComponent[] { drawPanel };
        }

    }

Weiterhin gibt es noch eine NFZDrawPanel.bmp, die als Bildchen angezeigt werden soll. Der Codeaufbau orientiert sich an dieses Tutorial, aber irgendwie will es nicht so...

Bin für jede Hilfe dankbar,
Best regards
 
Kennt vielleicht jemand Bücher, in denen z.B. so etwas näher behandelt wird? Bin Java-erfahren und möchte meinen Horizont etwas erweitern. ;)
 
Ok, ich hab's hinbekommen. Es ist unbedingt notwendig das Control in einer eigenen Library zu kapseln (es gibt einen Projekttyp Windows Forms Control Library, keine Ahnung ob der sich von einer normalen Class Library nochmal unterscheidet?). Die resultierende DLL kann man dann über den "Choose Toolbox Items"-Dialog laden.

Nun habe ich aber ein anderes Problem. Ich habe mein Control zwar jetzt auf dem Schirm, jedoch erschließt sich mir nicht ganz die Malerei. ;) Ich habe die OnPaint-Methode überschrieben:

C#:
public NFZDrawPanel : UserControl {

  protected override void OnPaint(PaintEventArgs pe) {
    base.OnPaint(pe);
    Graphics g = pe.Graphics;
    
    if (this.CarView != null) {
      Color c = ((NFZColor32) this.CarView.Pixels[0, 0]).Color; // Gibt ein System.Drawing.Color-Objekt zurück
      g.DrawLine(new Pen(c), this.Location.X, this.Location.Y, this.Location.X + this.Width, this.Location.Y + this.Height);
    }
  }

}

Ich würde jetzt erwarten, dass mein Control eine Linie von links oben nach rechts unten malt, tut sie aber nicht. Das Control bleibt leer. Weiß hier jemand Rat?

PS: CarView ist auf keinen Fall null. Die Pixel sind ebenfalls auf jeden Fall gesetzt, es wird ja auch keine Exception geworfen. Es muss also an etwas anderem liegen...
 
Wird OnPaint aufgerufen (im Debugger testen)? Die verwendete Farbe 'this.CarView.Pixels[0, 0]).Color' ist auch wirklich eine andere, als die Hintergrundfarbes des UserControls?

Gruß
MCoder
 
Habe mal testweise

C#:
Console.WriteLine(c.ToString());

unter dem Draw-Befehl eingefügt und er gibt mir genau die Farbe aus, die gesetzt wurde (FFFF00 in hex), die sich wohl eindeutig vom normalen Grau abheben sollte. Ach und da er es ausgibt, wird OnPaint ja auch aufgerufen ;)
 
Ich sehe gerade: Location ist ja die Position des Controls bezogen auf seinen Container. Setze die Startwerte auf 0 und für den Endpunkt reichen die Angaben 'Width' und 'Height'.

Gruß
MCoder
 
Wunderbar, es funktioniert! :) Das war es zwar nicht direkt, aber ich hab noch einen Fehler gefunden, bei der Typumwandlung von NFZColor32 in Color. Man sollte vielleicht einen Alphawert wählen, damit man auch was sieht. *rolleyes*

Danke!
 
Zurück