none
die usercontrol Eigenschaftenliste bei PropertyGrid als eine combobox anzeigen lassen RRS feed

  • Frage

  • Hallo,

     

    ich habe einen UserControl geschrieben. Er hat eine "Feldname"-Eigenschaft als string . Diese soll im View Design unter PropertyGrid aus einer ComboBox-Liste ausgewählt werden können. Die Items für diese ComboBox will ich dynamisch auffüllen.

    Wie kann man in einem usercontrol die Eigenschaften als items einer combobox anzeigen lassen? So, dass man die ComboBox aufklappen kann und einen Wert auswählen.

     

    Danke!

    Montag, 28. Juni 2010 13:35

Antworten

  • Hallo,

    Du könntest einen UITypeEditor verwenden. Etwa so:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.Drawing.Design;
    using System.Windows.Forms.Design;
    
    namespace UiTypeEditTest
    {
      public partial class UserControl1 : UserControl
      {
        private List<string> _list = new List<string>() { "one", "two", "three" };
        [Browsable(false)]
        public List<string> StringList
        {
          get { return _list; }
          set { _list = value; }
        }
        
        public UserControl1()
        {
          InitializeComponent();
        }
    
        [Editor(typeof(MyDropDownEditor), typeof(UITypeEditor))]
        public string MyProperty { get; set; }
      }
    
      class MyDropDownEditor : UITypeEditor
      {
        private string _value;
        private IWindowsFormsEditorService _edsv = null;
        private ListBox _list = new ListBox();
    
        public MyDropDownEditor()
        {
          _list.SelectedValueChanged += _list_SelectedValueChanged;
        }
    
        void _list_SelectedValueChanged(object sender, EventArgs e)
        {
          _value = _list.SelectedItem.ToString();
          _edsv.CloseDropDown();
        }
    
        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
        {
          return UITypeEditorEditStyle.DropDown;
        }
    
        public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
        {
          _list.Items.Clear();
          _list.Items.AddRange((context.Instance as UserControl1).StringList.ToArray());
    
          _value = (string)value;
          _edsv = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
          _edsv.DropDownControl(_list);
          return _value;
        }
      }
    }
    

    Wenn Du die Liste der angezeigten Werte ändern willst, mußt Du nur userControl1.StringList = new List<string>() {"four", "five", "six"} ändern.

    Marcel

    • Als Antwort markiert Reticent77 Dienstag, 29. Juni 2010 13:04
    Montag, 28. Juni 2010 15:32
    Moderator
  • Hallo,

    wie schon angedeutet : Über das ITypeDescriptorContext Argument.
    Voraussetzung ist dabei das der TypeConverter in einer Umgebung eingesetzt wird,
    die diesen Kontext setzt. Das ist im PropertyGrid zur Entwurfszeit der Fall und
    auch zur Laufzeit der Fall, wenn Du Dein Steuerelement SelectedObject zuweist.

    Einen UITypeEditor wie ihn Marcel zeigt braucht man gemeinhin  nicht.
    Denn das PropertyGrid ist schon "schlau" genug eine ComboBox darzustellen,
    wenn StandardValues bereitgestellt werden.
    Der wäre erst erforderlich wenn Du mehr an der Optik drehen willst.

    Das Beispiel von gestern (was aus einem älteren Projekt stammte) für ein UserControl umgedeutet:

    using System;
    using System.ComponentModel;
    using System.Windows.Forms;
    
    namespace ElmarBoye.Samples.Forms
    {
      public partial class FeldNamenUserControl : UserControl
      {
        private string _feldName;
        public event EventHandler FeldNameChanged;
    
        public FeldNamenUserControl()
        {
          InitializeComponent();
        }
    
        /// <summary>Liste der Feldnamen für den TypeConverter</summary>
        internal string[] FeldNamen
        {
          get 
          {
            // Ein wenig variiert um die Herkunft zu verdeutlichen
            if (this.DesignMode)
              return new[] { "5. Wert", "6. Wert", "7. Wert" };
            else
              return new[] { "4. Wert", "5. Wert", "6. Wert" };
          }
        }
    
    
        [TypeConverter(typeof(FeldNameConverter))]
        public string FeldName
        {
          get { return this._feldName; }
          set
          {
            if (this._feldName != value)
            {
              this._feldName = value;
    
              OnFeldNameChanged(EventArgs.Empty);
            }
          }
        }
    
        protected virtual void OnFeldNameChanged(EventArgs e)
        {
          // Zur Verwendung bringen...
          this.label1.Text = this.FeldName;
    
          var handler = this.FeldNameChanged;
          if (handler != null)
            handler(this, e);
        }
      }
    
      public class FeldNameConverter : System.ComponentModel.StringConverter
      {
        private StandardValuesCollection _standardValues = null;
    
        public FeldNameConverter()
        {
        }
    
        /// <summary>Auflistung mit Standardwerten zurückliefern</summary>
        public override TypeConverter.StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
        {
          if (context != null)
          {
            FeldNamenUserControl control = context.Instance as FeldNamenUserControl;
    
            if (control != null)
              return new StandardValuesCollection(control.FeldNamen);
          }
    
          // Irgendeine andere Vorgabe (ggf. auch leer)
          // ...hier wie gestern...
          TypeConverter.StandardValuesCollection values = this._standardValues;
          if (this._standardValues == null)
          {
            this._standardValues = new StandardValuesCollection(new[] { "1. Wert", "2. Wert", "3. Wert" });
          }
          return this._standardValues;
        }
    
        /// <summary>GetStandardValues wird unterstützt.</summary>
        public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
        {
          return true;
        }
      }
    }
    

    Ich habe die Rückgaben etwas variiert, damit man besser den Context erkennt.
    Willst Du das Konzept universeller einsetzen, solltest Du eine Schnittstelle verwenden,
    denn derzeit ist durch context.Instance as FeldNamenUserControl; eine direkte Bindung
    an das Steuerelement gegeben.

    Gruß Elmar

    P. S.: Bitte keine Fullquotes -
    am besten auf Zitate ganz verzichten, das Forum ist eh schon träge genug.

     

     

     

    • Als Antwort markiert Reticent77 Dienstag, 29. Juni 2010 13:00
    Dienstag, 29. Juni 2010 08:51
    Beantworter
  • Hallo,

    Hier ein funktionsfähiges Projekt [VS 2010] diesbezüglich, das eine dynamische DropDown-Liste für eine string-Eigenschaft: "FeldName" ermöglicht:  [Download]. Implementation im Prinzip gemäß: [Optimale Nutzung des PropertyGrid-Steuerelements in .NET Framework] aber mit ein paar (wichtigen) Zusätzen, die nicht im Artikel stehen.


    ciao Frank
    • Als Antwort markiert Reticent77 Dienstag, 29. Juni 2010 13:44
    Montag, 28. Juni 2010 20:55

Alle Antworten

  • Hallo,

    ich habe einen UserControl geschrieben. Er hat eine "Feldname"-Eigenschaft als string . Diese soll im View Design unter PropertyGrid aus einer ComboBox-Liste ausgewählt werden. Die Items für diese ComboBox will ich dynamisch auffüllen.

    Wie kann man in einem usercontrol die Eigenschaften als items einer combobox anzeigen lassen?

    wenn es nicht vollständig dynamisch sein muss, kann man die Eigenschaft, statt String mit einem eigenen Enum deklarieren. Im PropertyGrid werden dann automatisch die möglichen Werte dieses Enum in einer ComboBox vorgeschlagen.

      public enum CustomEnum
      {
        Entry1,
        Entry2
      }
    
      public class Foo
      {
        public Foo()
        {
        }
    
        public CustomEnum CustomProperty { get; set; }
      }
    

    Möchtest Du dagegen völlig dynamische Werte anzeigen, wird es aufwändiger. Schau Dir dazu mal folgenden Artikel in der MSDN an:

    Getting the Most Out of the .NET Framework PropertyGrid Control
    http://msdn.microsoft.com/en-us/library/aa302326.aspx
    => Adding Domain List and Simple Drop-down Property Support



    Thorsten Dörfler
    Microsoft MVP Visual Basic
    vb-faq.de
    • Als Antwort vorgeschlagen Frank Dzaebel Dienstag, 29. Juni 2010 13:21
    Montag, 28. Juni 2010 14:53
    Beantworter
  • Hallo,

    erstelle dafür einen TypeConverter , dort überschreibst Du GetStandardValues
    und GetStandardValuesSupported und ggf. GetStandardValuesExclusive.
    Am einfachsten wäre eine Ableitung von System.ComponentModel.StringConverter.

    Ein einfaches Beispiel:

      public class StringPropertyConverter : System.ComponentModel.StringConverter
      {
        private StandardValuesCollection _standardValues = null;
    
        public StringPropertyConverter()
        {
        }
    
        /// <summary>Auflistung mit Standardwerten zurückliefern</summary>
        public override TypeConverter.StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
        {
          TypeConverter.StandardValuesCollection values = this._standardValues;
          if (this._standardValues == null)
          {
            this._standardValues = new StandardValuesCollection(new[] { "1. Wert", "2. Wert", "3. Wert" });
          }
          return this._standardValues;
        }
    
        /// <summary>GetStandardValues wird unterstützt.</summary>
        public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
        {
          return true;
        }
      }
    

    Und bei der Eigenschaft gibst Du dann den TypeConverter an:

        string _stringProperty;
    
        [TypeConverter(typeof(StringPropertyConverter))]
        public string StringProperty
        {
          get { return this._stringProperty; }
          set
          {
            if (this._stringProperty != value)
            {
              this._stringProperty = value;
              RaisePropertyChanged("StringProperty");
            }
          }
        }
    

    Soll die Liste dynamisch ausfallen, mußt Du den ITypeDescriptorContext auswerten.
    Mehr siehe: Gewusst wie: Implementieren eines Typkonverters

    Gruß Elmar

    Montag, 28. Juni 2010 14:59
    Beantworter
  • danke schön. Den Artikel schaue ich mir mal an.

     

    Eigentlich will ich die möglichen Werte als eine Liste übergeben, weil sie nicht vorhersehbar sind. D.h. es muss schon dynamisch sein.

    Genauer gesagt, ich will nur, dass die Werte so wie z.B. bei der Farbauswahl angezeigt werden.

     

     

    Montag, 28. Juni 2010 15:03
  • Hallo,

    Du könntest einen UITypeEditor verwenden. Etwa so:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.Drawing.Design;
    using System.Windows.Forms.Design;
    
    namespace UiTypeEditTest
    {
      public partial class UserControl1 : UserControl
      {
        private List<string> _list = new List<string>() { "one", "two", "three" };
        [Browsable(false)]
        public List<string> StringList
        {
          get { return _list; }
          set { _list = value; }
        }
        
        public UserControl1()
        {
          InitializeComponent();
        }
    
        [Editor(typeof(MyDropDownEditor), typeof(UITypeEditor))]
        public string MyProperty { get; set; }
      }
    
      class MyDropDownEditor : UITypeEditor
      {
        private string _value;
        private IWindowsFormsEditorService _edsv = null;
        private ListBox _list = new ListBox();
    
        public MyDropDownEditor()
        {
          _list.SelectedValueChanged += _list_SelectedValueChanged;
        }
    
        void _list_SelectedValueChanged(object sender, EventArgs e)
        {
          _value = _list.SelectedItem.ToString();
          _edsv.CloseDropDown();
        }
    
        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
        {
          return UITypeEditorEditStyle.DropDown;
        }
    
        public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
        {
          _list.Items.Clear();
          _list.Items.AddRange((context.Instance as UserControl1).StringList.ToArray());
    
          _value = (string)value;
          _edsv = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
          _edsv.DropDownControl(_list);
          return _value;
        }
      }
    }
    

    Wenn Du die Liste der angezeigten Werte ändern willst, mußt Du nur userControl1.StringList = new List<string>() {"four", "five", "six"} ändern.

    Marcel

    • Als Antwort markiert Reticent77 Dienstag, 29. Juni 2010 13:04
    Montag, 28. Juni 2010 15:32
    Moderator
  • Hallo,

    Hier ein funktionsfähiges Projekt [VS 2010] diesbezüglich, das eine dynamische DropDown-Liste für eine string-Eigenschaft: "FeldName" ermöglicht:  [Download]. Implementation im Prinzip gemäß: [Optimale Nutzung des PropertyGrid-Steuerelements in .NET Framework] aber mit ein paar (wichtigen) Zusätzen, die nicht im Artikel stehen.


    ciao Frank
    • Als Antwort markiert Reticent77 Dienstag, 29. Juni 2010 13:44
    Montag, 28. Juni 2010 20:55
  • Hallo,

    Du könntest einen UITypeEditor verwenden. Etwa so:

    
    
    

    Wenn Du die Liste der angezeigten Werte ändern willst, mußt Du nur userControl1.StringList = new List<string>() {"four", "five", "six"} ändern.

    Marcel

    genau so wollte ich das. Aber es tritt ein Fehler "Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt." auf bei der Zeile
    _list.Items.AddRange((context.Instance as UserControl1).StringList.ToArray());
    Ich verstehe nicht wieso...
    Dienstag, 29. Juni 2010 07:37
  • Hallo,

    erstelle dafür einen TypeConverter , dort überschreibst Du GetStandardValues
    und GetStandardValuesSupported und ggf. GetStandardValuesExclusive.
    Am einfachsten wäre eine Ableitung von System.ComponentModel.StringConverter.

    Ein einfaches Beispiel:

     

     
    

     

    Soll die Liste dynamisch ausfallen, mußt Du den ITypeDescriptorContext auswerten.
    Mehr siehe: Gewusst wie: Implementieren eines Typkonverters

    Gruß Elmar

    kann man hier irgendwie die Standardwerte zur Laufzeit setzen?
    • Bearbeitet Reticent77 Dienstag, 29. Juni 2010 13:01
    Dienstag, 29. Juni 2010 07:38
  • Ich vermute, dass StringList null ist. Aber setze mal einen Haltepunkt auf die Zeile (F9) und debugge die Anwendung (F5).

     

    Dienstag, 29. Juni 2010 07:45
    Moderator
  • :)

    Das ist es ja genau das! XD

    bloß wieso ist die Variable null? Sie wird gesetzt t1.StringList = new List<string>() { "1", "2", "3" };   ,

    aber wenn ich die Liste im PropertyGrid ausfallen lasse, dann ist sie null!

    Dienstag, 29. Juni 2010 07:52
  • Dann wird StringList irgendwo im Code zwischenzeitlich erneut auf null gesetzt. Mach mal bitte folgendes: Entferne alle Haltepunkte. Erstelle eine neue Form mit einem PropertyGrid, ziehe das UserControl  auf den Form Designer und im Load-Handler setze dann propertyGrid1.SelectedObject = t1. Starte die Anwendung.

     

    Dienstag, 29. Juni 2010 08:10
    Moderator
  • ähm... macht es einen Unterschied, wenn ich einfach eine eigene Klasse von Control ableite und nicht einen UserControl benutze?

    Ich arbeite mit Form Designer. Wenn ich mein Control auf meine Form platziere, erscheinen alle eigenschaften im PropertyGrid. Nur wenn ich die Liste von MyProperty ausfallen lassen möchte, bekomme ich den Fehler. Wenn ich natürlich im Konstruktor von MyDropDownEditor die _list mit Werten fülle, dann funktioniert es. Es klappt nur nicht zur Laufzeit die Listenelemente zu verändern... :(

    Dienstag, 29. Juni 2010 08:22
  • Es klappt nur nicht zur Laufzeit die Listenelemente zu verändern... :(


    Das glaube ich einfach nicht. Aber machen wir's einfach: Lade mal bitte Dein Testcode auf SkyDrive hoch (oder anderswo) und poste einen Link hier. Ich schau es mir an und melde mich bei Dir. Es wird sicherlich eine Lösung geben.

    Marcel

    Dienstag, 29. Juni 2010 08:34
    Moderator
  • HALT!

     

    habe gerade festgestellt, dass es nicht die StringLiest null ist, sondern (context.Instance as transLabel) ist null!

    hopla, wieso denn das? hm... was mache ich falsch?

    Dienstag, 29. Juni 2010 08:34
  • Einige Überprüfungen sind nicht ganz fehl am Platz:

    if (context != null)
    {
      if (context.Instance != null)
      {
        UserControl1 uc1 = context.Instance as UserControl1;
    
        if (uc1 != null)
          _listBox.Items.AddRange(uc1.StringList.ToArray());
        else
          throw (new NullReferenceException("uc1 war null in UserControl1.EditValue()"));
      }
      else
      {
        throw (new NullReferenceException("context.Instance war null in UserControl1.EditValue()"));
      }
    }
    else
    {
      throw (new NullReferenceException("ITypeDescriptorContext war null in UserControl1.EditValue()"));
    }
    

    Überprüfe auch den Typ von context.Instance (falls es nicht null ist).

    Marcel

    Dienstag, 29. Juni 2010 08:44
    Moderator
  • Hallo,

    wie schon angedeutet : Über das ITypeDescriptorContext Argument.
    Voraussetzung ist dabei das der TypeConverter in einer Umgebung eingesetzt wird,
    die diesen Kontext setzt. Das ist im PropertyGrid zur Entwurfszeit der Fall und
    auch zur Laufzeit der Fall, wenn Du Dein Steuerelement SelectedObject zuweist.

    Einen UITypeEditor wie ihn Marcel zeigt braucht man gemeinhin  nicht.
    Denn das PropertyGrid ist schon "schlau" genug eine ComboBox darzustellen,
    wenn StandardValues bereitgestellt werden.
    Der wäre erst erforderlich wenn Du mehr an der Optik drehen willst.

    Das Beispiel von gestern (was aus einem älteren Projekt stammte) für ein UserControl umgedeutet:

    using System;
    using System.ComponentModel;
    using System.Windows.Forms;
    
    namespace ElmarBoye.Samples.Forms
    {
      public partial class FeldNamenUserControl : UserControl
      {
        private string _feldName;
        public event EventHandler FeldNameChanged;
    
        public FeldNamenUserControl()
        {
          InitializeComponent();
        }
    
        /// <summary>Liste der Feldnamen für den TypeConverter</summary>
        internal string[] FeldNamen
        {
          get 
          {
            // Ein wenig variiert um die Herkunft zu verdeutlichen
            if (this.DesignMode)
              return new[] { "5. Wert", "6. Wert", "7. Wert" };
            else
              return new[] { "4. Wert", "5. Wert", "6. Wert" };
          }
        }
    
    
        [TypeConverter(typeof(FeldNameConverter))]
        public string FeldName
        {
          get { return this._feldName; }
          set
          {
            if (this._feldName != value)
            {
              this._feldName = value;
    
              OnFeldNameChanged(EventArgs.Empty);
            }
          }
        }
    
        protected virtual void OnFeldNameChanged(EventArgs e)
        {
          // Zur Verwendung bringen...
          this.label1.Text = this.FeldName;
    
          var handler = this.FeldNameChanged;
          if (handler != null)
            handler(this, e);
        }
      }
    
      public class FeldNameConverter : System.ComponentModel.StringConverter
      {
        private StandardValuesCollection _standardValues = null;
    
        public FeldNameConverter()
        {
        }
    
        /// <summary>Auflistung mit Standardwerten zurückliefern</summary>
        public override TypeConverter.StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
        {
          if (context != null)
          {
            FeldNamenUserControl control = context.Instance as FeldNamenUserControl;
    
            if (control != null)
              return new StandardValuesCollection(control.FeldNamen);
          }
    
          // Irgendeine andere Vorgabe (ggf. auch leer)
          // ...hier wie gestern...
          TypeConverter.StandardValuesCollection values = this._standardValues;
          if (this._standardValues == null)
          {
            this._standardValues = new StandardValuesCollection(new[] { "1. Wert", "2. Wert", "3. Wert" });
          }
          return this._standardValues;
        }
    
        /// <summary>GetStandardValues wird unterstützt.</summary>
        public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
        {
          return true;
        }
      }
    }
    

    Ich habe die Rückgaben etwas variiert, damit man besser den Context erkennt.
    Willst Du das Konzept universeller einsetzen, solltest Du eine Schnittstelle verwenden,
    denn derzeit ist durch context.Instance as FeldNamenUserControl; eine direkte Bindung
    an das Steuerelement gegeben.

    Gruß Elmar

    P. S.: Bitte keine Fullquotes -
    am besten auf Zitate ganz verzichten, das Forum ist eh schon träge genug.

     

     

     

    • Als Antwort markiert Reticent77 Dienstag, 29. Juni 2010 13:00
    Dienstag, 29. Juni 2010 08:51
    Beantworter
  • Hallo,

    ggf. propiere doch einfach mal meinen [Download], den ich Dir gepostet hatte.
    Und Deine Frage an Elmar: "ob man da auch Werte zur Laufzeit zufügen kann" ist mit ja zu beantworten, denn mein Download zeigt gerade dies :-)

     


    ciao Frank
    Dienstag, 29. Juni 2010 08:52
  • Leute, danke euch allen für die Hilfe. Hier ist echt der beste Forum, den ich je gesehen habe.

    Ich werde jetzt die Vorschlage erstmal durchgehen. Irgendwo ist bei mir der Hacken vergraben. Den muss ich finden...

    Dienstag, 29. Juni 2010 09:19
  • Hallo Elmar,

    Einen UITypeEditor wie ihn Marcel zeigt braucht man gemeinhin nicht.

    Auch Porsches braucht man gemeinhin nicht, ein Fahrrad reicht aus. LOL.

    Gruss
    Marcel

    Dienstag, 29. Juni 2010 09:29
    Moderator
  • Hallo Marcel,

    ich hole meine Brötchen zu Fuß solange es noch geht -
    ein wenig Bewegung schadet bekanntlich nicht...
    In einen UITypeEditor steige ich erst ein, wenn es bunt hergehen soll,
    und nicht nur eine popelige Käfer-ListBox werden soll ;-))

    Gruß Elmar

    Dienstag, 29. Juni 2010 09:35
    Beantworter
  • also, alle eure Vorschläge sind richtig (wie gedacht) und funktionieren solange man einen UserControl im Designer-Modus auf die Form bringt.

    Ich benutze den Form Designer  (mithilfe von DesignSurfaceExt-Klasse) um meine Forms zur Laufzeig erstellen zu können.

    Ein Control wird immer mit einem <IDesignerHost> .CreateControl( Type ComponentClass) erstellt. Und genau das ist der Hacken!

    Jetzt muss ich schauen wie man eure Vorschläge in dem Fall umsetzen kann...

    Dienstag, 29. Juni 2010 09:46
  • Hallo,

    wenn Du damit den CodeProject Artikel meinst:
    Have a Great DesignTime Experience with a Powerful DesignSurface (Extended) Class
    so sollte das funktionieren - solange Du nicht irgendwo dran gedreht hast.

    Ich habe das FeldNamenUserControl von vorhin mal in die Demo unter CreateDesignSurface integriert

    var uc = (FeldNamenUserControl)surface.CreateControl(typeof(FeldNamenUserControl), new Size( 100, 40 ), new Point( 50, 50 ));
    Dort wird das Steuerelement gefunden und als im DesignMode behandelt.

    Gruß Elmar

    Dienstag, 29. Juni 2010 10:10
    Beantworter
  • wenn Du damit den CodeProject Artikel meinst:
    Have a Great DesignTime Experience with a Powerful DesignSurface (Extended) Class
    so sollte das funktionieren - solange Du nicht irgendwo dran gedreht hast.


    absolut richtig! Genau das meine ich.

    Ich habe niergendwas gedreht. und genau so erstelle ich mein Control. Das Steuerelement wird ja auch im DesindMode behandelt. Angezeigt werden aber nur folgende Werte 

      this._standardValues = new StandardValuesCollection(new[] { "1. Wert", "2. Wert", "3. Wert" }

    und die "5.Wert" usw. sind niergends zu finden.

    Welche Werte siehst du bei dir im DesignMode?

     

    Dienstag, 29. Juni 2010 10:20
  • Hallo,

    ich sehe eben die für den DesignMode:

     return new[] { "5. Wert", "6. Wert", "7. Wert" };
    

    und ich hatte das Projekt auf VS2010/ .NET 4.0 hochgezogen.

    Gruß Elmar

    Dienstag, 29. Juni 2010 10:24
    Beantworter
  • Und mit meinem Code funktioniert es auch:

    // In: DemoConsoleForDesignSurfaceExt
    // private void CreateDesignSurface ( int n ) 
    
    case 1:
     {
     rootComponent = (Form)surface.CreateRootComponent(typeof(Form), new Size(400, 400));
     rootComponent.BackColor = Color.Gray;
     rootComponent.Text = "Root Component hosted by the DesignSurface N.1";
     //- step.3
     //- create some Controls at DesignTime
     UserControl1 u1 = (UserControl1)surface.CreateControl(typeof(UserControl1), new Size(200, 20), new Point(10, 200));
     u1.BackColor = Color.Orange;
     }
    

    Getestet habe ich sowohl unter VS 2010 / .NET 4.0 als auch unter VS 2008 / .NET 3.5.

    Gruß
    Marcel

     

    The DesignSurface (Extended) Class is Back, Together with a DesignSurfaceManager (Extended) Class and a Form Designer Demo!
    By Paolo Foti | 24 Feb 2010:
    http://www.codeproject.com/KB/miscctrl/DesignSurfaceManager_Ext.aspx

     

    Dienstag, 29. Juni 2010 10:29
    Moderator
  • tatsächlich! Wenn ich das Projekt so wie es ist benutze und den UserControl einfüge, dann funktioniert es so wie ihr sagt!!

    Nur in meinem eigenen Projekt funktioniert nicht richtig :(

    oh man, oh man, oh man.... Was habe ich nur falsch gemacht?

    Ich schau mal lieber genauer hin und geh jede Zeile am besten noch mal durch...

    Dienstag, 29. Juni 2010 10:59
  • Vielleicht noch eine Hilfe zur den gezeigten Codes hier.
    Gern wird DesignMode benutzt. DesignMode ist aber u.a. in Konstruktoren und verschachtelten UserControls oft nicht wirksam - es gibt aber Alternativen. Aus der C# Gruppe kann ich da über die Jahre ein Lied von [singen]. In meinem [Download] von gestern ist übrigens noch eine [DesignerSerializationVisibility.Hidden] enthalten.

     


    ciao Frank
    Dienstag, 29. Juni 2010 11:26
  • habe den Problemverursacher gefunden. Es liegt nicht an dem DesignerSurfaceExt, sondern an FilteredPropertyGrid ( hier gefunden ). Ich benutze es um nur bestimmte Eigenschaften anzuzeigen... Na so was.

    Jetzt bin ich an dem dran... Anscheinen funktioniert es irgend wie nicht ganz richtig.

    Dienstag, 29. Juni 2010 12:02
  • der FilteredPropertyGrid benutzt einen wrapper um die Eigenschaften zu filtern. Der wrapper übernimmt die im UserControl angelegten Sachen nicht richtig.

    Jetzt überlege ich mir wieder zum standard PropertyGrid zu wechseln. Nur wie kann ich dort nur bestimmte Properties anzeigen lassen. Bis jetzt weiss  ich nur wie man die BrowsableAttribute benutzt.

     

    propertyGrid.BrowsableAttributes = new AttributeCollection(new Attribute[] { new CategoryAttribute("Layout") });
    aber wenn ich z.B. 2 Attribute anzeigen möchte

     

     

    propertyGrid.BrowsableAttributes = new AttributeCollection(new Attribute[] { new CategoryAttribute("Layout"), new CategoryAttribute("Darstellung") });
    dann bleibt der PropertyGrid leer.Außerdem wie kann ich hier bestimmte einzellne Eigenschaften ausblenden?

     

    Was ist jetzt besser? Wieder zum standard-PropertyGrid zu wechseln oder den Filtered zu fixen?

    Dienstag, 29. Juni 2010 13:11
  • DANKE DANKE DANKE an alle die mitgeholfen haben! Ihr seid die Besten!

     

    ich mache zu PropertyGrid lieber eine neue Frage auf...

    Dienstag, 29. Juni 2010 13:17
  • Nur als Referenz für andere später.

    Die geposteten Codeteile von Elmar entsprechen zum Großteil meinem zuvor geposteten Download in meinem ersten Posting, der ein funktionierendes Projekt für das angesprochene Thema implementiert.

     


    ciao Frank
    Dienstag, 29. Juni 2010 13:35
  • Hallo Thorsten,

    wenn es nicht vollständig dynamisch sein muss, kann man die Eigenschaft, statt String mit einem eigenen Enum deklarieren. Im PropertyGrid werden dann automatisch die möglichen Werte dieses Enum in einer ComboBox vorgeschlagen.

     public enum CustomEnum
     {
     Entry1,
     Entry2
     }
    
     public CustomEnum CustomProperty { get; set; }

    bei einem ähnliches Problem hat mir deine Antwort sehr geholfen!

    Gruß Klaus

    Dienstag, 29. Juni 2010 15:22