Search Results

Search found 12 results on 1 pages for 'icustomtypedescriptor'.

Page 1/1 | 1 

  • WPF DataGrid AutoColumn generation via ICustomTypeDescriptor.

    - by panamack
    In a test project I've managed to AutoGenerate WPF DataGrid columns in the following scenario, where the data is stored in a Dictionary and binding is performed via PropertyDescriptors: public class People:List<Person>{ ... } public class Person:Dictionary<string,string>,INotifyPropertyChanged,ICustomTypeDescriptor { } The problem I'm having is in my real life project I'm using MVVM so it's *People*ViewModel which inherits ViewModelBase and hence can't inherit List<Person>. I've tried implementing IList<Person> instead with an internal List<Person> and explicitly setting the DataContext to an IList<Person> reference but that didn't work. I've seen a similar post on binding a win forms DataGridView here, so I'm wondering if the same sort of logic applies in WPF and primarily, what exactly causes the ICustomTypeDescriptor implementation to be picked up when inheriting List<T> that is missing when you simply implement IList<T> instead.

    Read the article

  • How do I get around this lambda expression outer variable issue?

    - by panamack
    I'm playing with PropertyDescriptor and ICustomTypeDescriptor (still) trying to bind a WPF DataGrid to an object, for which the data is stored in a Dictionary. Since if you pass WPF DataGrid a list of Dictionary objects it will auto generate columns based on the public properties of a dictionary (Comparer, Count, Keys and Values) my Person subclasses Dictionary and implements ICustomTypeDescriptor. ICustomTypeDescriptor defines a GetProperties method which returns a PropertyDescriptorCollection. PropertyDescriptor is abstract so you have to subclass it, I figured I'd have a constructor that took Func and an Action parameters that delegate the getting and setting of the values in the dictionary. I then create a PersonPropertyDescriptor for each Key in the dictionary like this: foreach (string s in this.Keys) { var descriptor = new PersonPropertyDescriptor( s, new Func<object>(() => { return this[s]; }), new Action<object>(o => { this[s] = o; })); propList.Add(descriptor); } The problem is that each property get's its own Func and Action but they all share the outer variable s so although the DataGrid autogenerates columns for "ID","FirstName","LastName", "Age", "Gender" they all get and set against "Gender" which is the final resting value of s in the foreach loop. How can I ensure that each delegate uses the desired dictionary Key, i.e. the value of s at the time the Func/Action is instantiated? Much obliged. Here's the rest of my idea, I'm just experimenting here these are not 'real' classes... // DataGrid binds to a People instance public class People : List<Person> { public People() { this.Add(new Person()); } } public class Person : Dictionary<string, object>, ICustomTypeDescriptor { private static PropertyDescriptorCollection descriptors; public Person() { this["ID"] = "201203"; this["FirstName"] = "Bud"; this["LastName"] = "Tree"; this["Age"] = 99; this["Gender"] = "M"; } //... other ICustomTypeDescriptor members... public PropertyDescriptorCollection GetProperties() { if (descriptors == null) { var propList = new List<PropertyDescriptor>(); foreach (string s in this.Keys) { var descriptor = new PersonPropertyDescriptor( s, new Func<object>(() => { return this[s]; }), new Action<object>(o => { this[s] = o; })); propList.Add(descriptor); } descriptors = new PropertyDescriptorCollection(propList.ToArray()); } return descriptors; } //... other other ICustomTypeDescriptor members... } public class PersonPropertyDescriptor : PropertyDescriptor { private Func<object> getFunc; private Action<object> setAction; public PersonPropertyDescriptor(string name, Func<object> getFunc, Action<object> setAction) : base(name, null) { this.getFunc = getFunc; this.setAction = setAction; } // other ... PropertyDescriptor members... public override object GetValue(object component) { return getFunc(); } public override void SetValue(object component, object value) { setAction(value); } }

    Read the article

  • Creating WCF DataContracts dynamically from code

    - by Fredrik Tonn
    Given the fact that I have a fully dynamic object model, that is, I have no concrete classes defined anywhere in code, but I still want to be able to create WCF DataContracts for them so I can use them in operations. How can I achieve this? My concrete class "Entity" implements ICustomTypeDescriptor which is used to present the various properties to the outside world, but my expeimentation with WCF suggests that WCF does not care about ICustomTypeDescriptor. Is this correct or have I missed something? Is this possible? It cannot be so that the only way to create a DataContract is to actually have a concrete harcoded class, can it?

    Read the article

  • Serializing WPF DataTemplates and {Binding Expressions} (from PowerShell?)

    - by Jaykul
    Ok, here's the deal: I have code that works in C#, but when I call it from PowerShell, it fails. I can't quite figure it out, but it's something specific to PowerShell. Here's the relevant code calling the library (assuming you've added a reference ahead of time) from C#: public class Test { [STAThread] public static void Main() { Console.WriteLine( PoshWpf.XamlHelper.RoundTripXaml( "<TextBlock Text=\"{Binding FullName}\" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"/>" ) ); } } Compiled into an executable, that works fine ... but if you call that method from PowerShell, it returns with no {Binding FullName} for the Text! add-type -path .\PoshWpf.dll [PoshWpf.Test]::Main() I've pasted below the entire code for the library, all wrapped up in a PowerShell Add-Type call so you can just compile it by pasting it into PowerShell (you can leave off the first and last lines if you want to paste it into a new console app in Visual Studio. To output (from PowerShell 2) as an executable, just change the -OutputType parameter to ConsoleApplication and the -OutputAssembly to PoshWpf.exe (or something). Thus, you can see that running the SAME CODE from the executable gives you the correct output. But running the two lines as above or manually calling [PoshWpf.XamlHelper]::RoundTripXaml or [PoshWpf.XamlHelper]::ConvertToXaml from PowerShell just doesn't seem to work at all ... HELP?! Add-Type -TypeDefinition @" using System; using System.ComponentModel; using System.Globalization; using System.Linq; using System.Windows; using System.Windows.Data; using System.Windows.Markup; namespace PoshWpf { public class Test { [STAThread] public static void Main() { Console.WriteLine( PoshWpf.XamlHelper.RoundTripXaml( "<TextBlock Text=\"{Binding FullName}\" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"/>" ) ); } } public class BindingTypeDescriptionProvider : TypeDescriptionProvider { private static readonly TypeDescriptionProvider _DEFAULT_TYPE_PROVIDER = TypeDescriptor.GetProvider(typeof(Binding)); public BindingTypeDescriptionProvider() : base(_DEFAULT_TYPE_PROVIDER) { } public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance) { ICustomTypeDescriptor defaultDescriptor = base.GetTypeDescriptor(objectType, instance); return instance == null ? defaultDescriptor : new BindingCustomTypeDescriptor(defaultDescriptor); } } public class BindingCustomTypeDescriptor : CustomTypeDescriptor { public BindingCustomTypeDescriptor(ICustomTypeDescriptor parent) : base(parent) { } public override PropertyDescriptorCollection GetProperties(Attribute[] attributes) { PropertyDescriptor pd; var pdc = new PropertyDescriptorCollection(base.GetProperties(attributes).Cast<PropertyDescriptor>().ToArray()); if ((pd = pdc.Find("Source", false)) != null) { pdc.Add(TypeDescriptor.CreateProperty(typeof(Binding), pd, new Attribute[] { new DefaultValueAttribute("null") })); pdc.Remove(pd); } return pdc; } } public class BindingConverter : ExpressionConverter { public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { return (destinationType == typeof(MarkupExtension)) ? true : false; } public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { if (destinationType == typeof(MarkupExtension)) { var bindingExpression = value as BindingExpression; if (bindingExpression == null) throw new Exception(); return bindingExpression.ParentBinding; } return base.ConvertTo(context, culture, value, destinationType); } } public static class XamlHelper { static XamlHelper() { // this is absolutely vital: TypeDescriptor.AddProvider(new BindingTypeDescriptionProvider(), typeof(Binding)); TypeDescriptor.AddAttributes(typeof(BindingExpression), new Attribute[] { new TypeConverterAttribute(typeof(BindingConverter)) }); } public static string RoundTripXaml(string xaml) { return XamlWriter.Save(XamlReader.Parse(xaml)); } public static string ConvertToXaml(object wpf) { return XamlWriter.Save(wpf); } } } "@ -language CSharpVersion3 -reference PresentationCore, PresentationFramework, WindowsBase -OutputType Library -OutputAssembly PoshWpf.dll Again, you can get an executable by just altering the last line like so: "@ -language CSharpVersion3 -reference PresentationCore, PresentationFramework, WindowsBase -OutputType ConsoleApplication -OutputAssembly PoshWpf.exe

    Read the article

  • How does the Control class, provide the ForeColor, BackColor and Font default values?

    - by Miguel Angelo
    I know that component-model indicates whether a property has a default value or not, by means of ShouldSerializeValue method of PropertyDescriptor. The base windows-forms Control class, has some properties like ForeColor, BackColor and Font, that defaults to the same value of the parent, but I could not find any TypeDescriptor or PropertyDescriptor that provides these default values. The Control class does not implement ICustomTypeDescriptor nor has a TypeDescriptionProviderAttribute. How does the Control class indicates that these properties should be serialized or not? Where does it provide the PropertyDescriptors for these properties?? Thanks!!!

    Read the article

  • Injecting (INotifyPropertyChanged functionality) to an instance of an class

    - by no9
    Hi ! I have a class that implements INotifyPropertyChanged. I create an instance of a class in some viewModel. Is it possible to remove this functionality from the class and inject it after the instance was created? I heard that ICustomTypeDescriptor would make this happen, but i dont know how to use it. public class C : ICustomNotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public int _id; public string _name; public int Id { get { return _id; } set { if (_id == value) { return; } _id = value; OnPropertyChanged("Id"); } } public string Name { get { return _name; } set { if (_name == value) { return; } _name = value; OnPropertyChanged("Name"); } } public void OnPropertyChanged(string name) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(name)); } }

    Read the article

  • How can I bind dynamic data to DataGridTemplateColumn in code?

    - by TuomoT
    I'm using DataGrid from CodePlex. I have objects (ICustomTypeDescriptor) that have properties 'name' 'description' 'c' 'd' and so on (the names are dynamic, and so is the value) and they have information behind them. I have templates for different types. And if I have to list the properties of a single element I can just bind to the values in xaml and use datatemplateselector (in datagridtemplatecolumn) which will pick the correct template. However, when I'm listing several of the elements, how can I use the selectors and the templates? How do I get the correct property bound to the template (two-way)? When ignoring the need for different templates, using DataGridTextColumn with bindings is very simple (and works, see example below), is there any way to use similar approach with the DataGridTemplateColumn? foreach (String propertyName in listOfPropertyNames) { DataGridTextColumn textColumn = new DataGridTextColumn() { Header = propertyName, Binding = new Binding() { Path = new PropertyPath(propertyName) } }; DataGrid.Columns.Add(textColumn); }

    Read the article

  • How can I bind dynamic data to DataGridTemplateColun in code?

    - by TuomoT
    I'm using DataGrid from CodePlex. I have objects (ICustomTypeDescriptor) that have properties 'name' 'description' 'c' 'd' and so on (the names are dynamic, and so is the value) and they have information behind them. I have templates for different types. And if I have to list the properties of a single element I can just bind to the values in xaml and use datatemplateselector (in datagridtemplatecolumn) which will pick the correct template. However, when I'm listing several of the elements, how can I use the selectors and the templates? How do I get the correct property bound to the template (two-way)? When ignoring the need for different templates, using DataGridTextColumn with bindings is very simple (and works, see example below), is there any way to use similar approach with the DataGridTemplateColumn? foreach (String propertyName in listOfPropertyNames) { DataGridTextColumn textColumn = new DataGridTextColumn() { Header = propertyName, Binding = new Binding() { Path = new PropertyPath(propertyName) } }; DataGrid.Columns.Add(textColumn); }

    Read the article

  • WPF Designer has bug with parsing generic control with overrided property

    - by Ivan Laktyunkin
    I've created a generic lookless control with virtual property: public abstract class TestControlBase<TValue> : Control { public static readonly DependencyProperty ValueProperty; static TestControlBase() { ValueProperty = DependencyProperty.Register("Value", typeof(TValue), typeof(TestControlBase<TValue>)); } protected TestControlBase() { Focusable = false; Value = default(TValue); } public virtual TValue Value { get { return (TValue)GetValue(ValueProperty); } set { SetValue(ValueProperty, value); } } } Then I've made a control derived from it and overrided Value property: public class TestControl : TestControlBase<int> { public override int Value { get { return base.Value; } set { base.Value = value; } } } So I use it in a Window XAML: <TestControls:TestControl /> When I open window in designer all is OK, but when I put mouse cursor to this line, or to this control in designer I receive exception: Exception has been thrown by the target of an invocation. at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner) at System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks) at System.Delegate.DynamicInvokeImpl(Object[] args) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter) at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler) Ambiguous match found. at System.RuntimeType.GetPropertyImpl(String name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers) at System.Type.GetProperty(String name) at MS.Internal.ComponentModel.DependencyPropertyKind.get_IsDirect() at MS.Internal.ComponentModel.DependencyPropertyKind.get_IsAttached() at MS.Internal.ComponentModel.APCustomTypeDescriptor.GetProperties(Attribute[] attributes) at MS.Internal.ComponentModel.APCustomTypeDescriptor.GetProperties() at System.ComponentModel.TypeDescriptor.TypeDescriptionNode.DefaultExtendedTypeDescriptor.System.ComponentModel.ICustomTypeDescriptor.GetProperties() at System.ComponentModel.TypeDescriptor.GetPropertiesImpl(Object component, Attribute[] attributes, Boolean noCustomTypeDesc, Boolean noAttributes) at System.ComponentModel.TypeDescriptor.GetProperties(Object component) at MS.Internal.Model.ModelPropertyCollectionImpl.GetProperties(String propertyNameHint) at MS.Internal.Model.ModelPropertyCollectionImpl.<GetEnumerator>d__0.MoveNext() at MS.Internal.Designer.PropertyEditing.Model.ModelPropertyMerger.<GetFirstProperties>d__0.MoveNext() at MS.Internal.Designer.PropertyEditing.PropertyInspector.UpdateCategories(Selection selection) at MS.Internal.Designer.PropertyEditing.PropertyInspector.OnSelectionChangedIdle() Who know this problem? Please explain :) I have no ideas except that WPF Designer doesn't like generics. If I replace generics by Object all is OK.

    Read the article

  • How to use CodeDomSerializer to serialize an object in .Net?

    - by user341127
    I have a class, which is defined as the following: [ToolboxItem(false)] [DesignTimeVisible(false)] [DesignerSerializer("DevExpress.XtraEditors.Design.RepositoryItemCodeDomSerializer, DevExpress.XtraEditors.v10.1.Design", "System.ComponentModel.Design.Serialization.CodeDomSerializer, System.Design")] [Designer("DevExpress.XtraEditors.Design.BaseRepositoryItemDesigner, DevExpress.XtraEditors.v10.1.Design")] [LicenseProvider(typeof(DXEditorLicenseProvider))] public class RepositoryItem : Component, ISupportInitialize, ICustomTypeDescriptor, IImageCollectionHelper {......} I tried the following code to serialize the object of this class. DesignerSerializationManager m = new System.ComponentModel.Design.Serialization.DesignerSerializationManager(); m.CreateSession(); DevExpress.XtraEditors.Design.RepositoryItemCodeDomSerializer s = m.GetSerializer(typeof(RepositoryItem), typeof(DevExpress.XtraEditors.Design.RepositoryItemCodeDomSerializer)) as DevExpress.XtraEditors.Design.RepositoryItemCodeDomSerializer; RepositoryItem i = persistentRepository1.Items[0]; //m.Container.Add(i); s.Serialize(m,i );// An error "Object reference not set to an instance of an object." happended here. For I am not familiar with CodeDom, I have spent one day to get the way out. I guess the above code has some stupid mistakes. Please give me a hand to show how to serialize AND DeSelialize such objects of the class of Repository. BTW, the reason I don't use any other serializer is that I am supposed not to have rights to know the source code of RepositoryItem and others could inherit RepositoryItem at the same time. And actually I have to deal with RepositoryItem and its descendants. Thank you in advance. Ying

    Read the article

  • How to modify PropertyGrid at runtime (add/remove property and dynamic types/enums)

    - by salle55
    How do you modify a propertygrid at runtime in every way? I want to be able to add and remove properties and add "dynamic types", what I mean with that is a type that result in a runtime generated dropdown in the propertygrid using a TypeConverter. I have actually been able to do both those things (add/remove properties and add dynamic type) but only separately not at the same time. To implement the support to add and remove properties at runtime I used this codeproject article and modified the code a bit to support different types (not just strings). private System.Windows.Forms.PropertyGrid propertyGrid1; private CustomClass myProperties = new CustomClass(); public Form1() { InitializeComponent(); myProperties.Add(new CustomProperty("Name", "Sven", typeof(string), false, true)); myProperties.Add(new CustomProperty("MyBool", "True", typeof(bool), false, true)); myProperties.Add(new CustomProperty("CaptionPosition", "Top", typeof(CaptionPosition), false, true)); myProperties.Add(new CustomProperty("Custom", "", typeof(StatesList), false, true)); //<-- doesn't work } /// <summary> /// CustomClass (Which is binding to property grid) /// </summary> public class CustomClass: CollectionBase,ICustomTypeDescriptor { /// <summary> /// Add CustomProperty to Collectionbase List /// </summary> /// <param name="Value"></param> public void Add(CustomProperty Value) { base.List.Add(Value); } /// <summary> /// Remove item from List /// </summary> /// <param name="Name"></param> public void Remove(string Name) { foreach(CustomProperty prop in base.List) { if(prop.Name == Name) { base.List.Remove(prop); return; } } } etc... public enum CaptionPosition { Top, Left } My complete solution can be downloaded here. It works fine when I add strings, bools or enums, but when I try to add a "dynamic type" like StatesList it doesn't work. Does anyone know why and can help me to solve it? public class StatesList : System.ComponentModel.StringConverter { private string[] _States = { "Alabama", "Alaska", "Arizona", "Arkansas" }; public override System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) { return new StandardValuesCollection(_States); } public override bool GetStandardValuesSupported(ITypeDescriptorContext context) { return true; } public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) { return true; } } The method of using a TypeConverter works fine when you don't try to add the property at runtime, for example this code works without any problem, but I want to be able to do both. Please take a look at my project. Thanks!

    Read the article

  • custom collection in property grid

    - by guyl
    Hi guys. I'm using this article as a reference to use custom collection in propertygrid: LINK When I open the collectioneditor and remove all items then I press OK, I get an exception if null. How can i solve that ? I am using: public T this[int index] { get { if (List.Count == 0) { return default(T); } else { return (T)this.List[index]; } } } as a getter for an item, of course if I have no object how can i restart the whole collection ? this is the whole code /// <summary> /// A generic folder settings collection to use in a property grid. /// </summary> /// <typeparam name="T">can be import or export folder settings.</typeparam> [Serializable] [TypeConverter(typeof(FolderSettingsCollectionConverter)), Editor(typeof(FolderSettingsCollectionEditor), typeof(UITypeEditor))] public class FolderSettingsCollection_New<T> : CollectionBase, ICustomTypeDescriptor { private bool m_bRestrictNumberOfItems; private int m_bNumberOfItems; private Dictionary<string, int> m_UID2Idx = new Dictionary<string, int>(); private T[] arrTmp; /// <summary> /// C'tor, can determine the number of objects to hold. /// </summary> /// <param name="bRestrictNumberOfItems">restrict the number of folders to hold.</param> /// <param name="iNumberOfItems">The number of folders to hold.</param> public FolderSettingsCollection_New(bool bRestrictNumberOfItems = false , int iNumberOfItems = 1) { m_bRestrictNumberOfItems = bRestrictNumberOfItems; m_bNumberOfItems = iNumberOfItems; } /// <summary> /// Add folder to collection. /// </summary> /// <param name="t">Folder to add.</param> public void Add(T t) { if (m_bRestrictNumberOfItems) { if (this.List.Count >= m_bNumberOfItems) { return; } } int index = this.List.Add(t); if (t is WriteDataFolderSettings || t is ReadDataFolderSettings) { FolderSettingsBase tmp = t as FolderSettingsBase; m_UID2Idx.Add(tmp.UID, index); } } /// <summary> /// Remove folder to collection. /// </summary> /// <param name="t">Folder to remove.</param> public void Remove(T t) { this.List.Remove(t); if (t is WriteDataFolderSettings || t is ReadDataFolderSettings) { FolderSettingsBase tmp = t as FolderSettingsBase; m_UID2Idx.Remove(tmp.UID); } } /// <summary> /// Gets ot sets a folder. /// </summary> /// <param name="index">The index of the folder in the collection.</param> /// <returns>A folder object.</returns> public T this[int index] { get { //if (List.Count == 0) //{ // return default(T); //} //else //{ return (T)this.List[index]; //} } } /// <summary> /// Gets or sets a folder. /// </summary> /// <param name="sUID">The UID of the folder.</param> /// <returns>A folder object.</returns> public T this[string sUID] { get { if (this.Count == 0 || !m_UID2Idx.ContainsKey(sUID)) { return default(T); } else { return (T)this.List[m_UID2Idx[sUID]]; } } } /// <summary> /// /// </summary> /// <param name="sUID"></param> /// <returns></returns> public bool ContainsItemByUID(string sUID) { return m_UID2Idx.ContainsKey(sUID); } /// <summary> /// /// </summary> /// <returns></returns> public String GetClassName() { return TypeDescriptor.GetClassName(this, true); } /// <summary> /// /// </summary> /// <returns></returns> public AttributeCollection GetAttributes() { return TypeDescriptor.GetAttributes(this, true); } /// <summary> /// /// </summary> /// <returns></returns> public String GetComponentName() { return TypeDescriptor.GetComponentName(this, true); } /// <summary> /// /// </summary> /// <returns></returns> public TypeConverter GetConverter() { return TypeDescriptor.GetConverter(this, true); } /// <summary> /// /// </summary> /// <returns></returns> public EventDescriptor GetDefaultEvent() { return TypeDescriptor.GetDefaultEvent(this, true); } /// <summary> /// /// </summary> /// <returns></returns> public PropertyDescriptor GetDefaultProperty() { return TypeDescriptor.GetDefaultProperty(this, true); } /// <summary> /// /// </summary> /// <param name="editorBaseType"></param> /// <returns></returns> public object GetEditor(Type editorBaseType) { return TypeDescriptor.GetEditor(this, editorBaseType, true); } /// <summary> /// /// </summary> /// <param name="attributes"></param> /// <returns></returns> public EventDescriptorCollection GetEvents(Attribute[] attributes) { return TypeDescriptor.GetEvents(this, attributes, true); } /// <summary> /// /// </summary> /// <returns></returns> public EventDescriptorCollection GetEvents() { return TypeDescriptor.GetEvents(this, true); } /// <summary> /// /// </summary> /// <param name="pd"></param> /// <returns></returns> public object GetPropertyOwner(PropertyDescriptor pd) { return this; } /// <summary> /// /// </summary> /// <param name="attributes"></param> /// <returns></returns> public PropertyDescriptorCollection GetProperties(Attribute[] attributes) { return GetProperties(); } /// <summary> /// Called to get the properties of this type. /// </summary> /// <returns></returns> public PropertyDescriptorCollection GetProperties() { // Create a collection object to hold property descriptors PropertyDescriptorCollection pds = new PropertyDescriptorCollection(null); // Iterate the list of employees for (int i = 0; i < this.List.Count; i++) { // Create a property descriptor for the employee item and add to the property descriptor collection CollectionPropertyDescriptor_New<T> pd = new CollectionPropertyDescriptor_New<T>(this, i); pds.Add(pd); } // return the property descriptor collection return pds; } public T[] ToArray() { if (arrTmp == null) { arrTmp = new T[List.Count]; for (int i = 0; i < List.Count; i++) { arrTmp[i] = (T)List[i]; } } return arrTmp; } } /// <summary> /// Enable to display data about a collection in a property grid. /// </summary> /// <typeparam name="T">Folder object.</typeparam> public class CollectionPropertyDescriptor_New<T> : PropertyDescriptor { private FolderSettingsCollection_New<T> collection = null; private int index = -1; /// <summary> /// /// </summary> /// <param name="coll"></param> /// <param name="idx"></param> public CollectionPropertyDescriptor_New(FolderSettingsCollection_New<T> coll, int idx) : base("#" + idx.ToString(), null) { this.collection = coll; this.index = idx; } /// <summary> /// /// </summary> public override AttributeCollection Attributes { get { return new AttributeCollection(null); } } /// <summary> /// /// </summary> /// <param name="component"></param> /// <returns></returns> public override bool CanResetValue(object component) { return true; } /// <summary> /// /// </summary> public override Type ComponentType { get { return this.collection.GetType(); } } /// <summary> /// /// </summary> public override string DisplayName { get { if (this.collection[index] != null) { return this.collection[index].ToString(); } else { return null; } } } public override string Description { get { return ""; } } /// <summary> /// /// </summary> /// <param name="component"></param> /// <returns></returns> public override object GetValue(object component) { if (this.collection[index] != null) { return this.collection[index]; } else { return null; } } /// <summary> /// /// </summary> public override bool IsReadOnly { get { return false; } } public override string Name { get { return "#" + index.ToString(); } } /// <summary> /// /// </summary> public override Type PropertyType { get { return this.collection[index].GetType(); } } public override void ResetValue(object component) { } /// <summary> /// /// </summary> /// <param name="component"></param> /// <returns></returns> public override bool ShouldSerializeValue(object component) { return true; } /// <summary> /// /// </summary> /// <param name="component"></param> /// <param name="value"></param> public override void SetValue(object component, object value) { // this.collection[index] = value; } }

    Read the article

1