473,396 Members | 1,886 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Hiding properties in classes with Properties control?

I've got a class which contains properties. I can supply this class to the
Properties control, and it will properly display the properties and allow
the user to edit them, etc. I would like to be able to programmatically
control at runtime which properties are displayed.

I've looked at the System.Windows.Forms.Design.ControlDesigner, and
specifically looked at the PreFilterProperties() override, but that seems to
only work for controls. Is there a way to programmatically change a
property's attributes at at runtime?
Cheers, Jon
Aug 14 '07 #1
5 2539
I can supply this class to the Properties control
I assume you mean PropertyGrid? If not, then let me know ;-p
I would like to be able to programmatically
control at runtime which properties are displayed.
To get past the default filters, you can actually create a custom tab
for the PropertyGrid (and remove the 2 that it provides) - there is a
full example of this on MSDN. You can then override GetProperties() to
do whatever you want and apply whatever filters you like to the
properties. I can't find the MSDN example, but there is one on
CodeProject that covers lots of other things too:

http://www.codeproject.com/cs/miscct...ExWinForms.asp
Is there a way to programmatically change a
property's attributes at at runtime?
Do you really mean a properties attributes? i.e. the "my description"
below:
[Description("my description")]
public string Name {get {return "Fred";}}

If so, then yes and no... although you can often tweak the attributes
on a PropertyDescriptor, the default reflective view on the component-
model will not respect this and you are likely to get the originals
back the next time you ask for them (since the original are burnt into
the class model). To do what you want (with full control - i.e. add/
remove attributes, work with any attribute) you probably need to
implement a custom PropertyDescriptor with bespoke (static?) storage
of the attributes. This would involve TypeDescriptionProvider (best
option) or ICustomTypeDescriptor (not quite as powerful). However,
this approach is not for the faint hearted, and you *really* need to
understand the System.ComponentModel before setting out...

If you only want to adjust a handful of attribute *values*, then
*sometimes* you can use a few tricks - i.e. I'm confident I could get
[Description], [DisplayName], [Category] all working [for edit, not
add/remove] by subclassing the attribute and providing bespoke storage
- similar to how MS manage i18n on these attributes.

Of course, to display and edit them in the PropertyGrid would need
another tab, with some custom virtual PropertyDescriptor entries that
write back to the entries... yet again, not for the faint hearted, but
it can be done.

Marc

Aug 15 '07 #2
I just thought of another (simpler) approach; an easier option would
be to write a wrapper object that accepts any instance and a list of
names, and applies ICustomTypeDescriptor to filter; you then use the
regular PropertyGrid but give it the wrapper rather than your object,
i.e.

myGrid.SelectedObject = PropertyFilter(myObject,"Name", "Age",
"ShoeSize");

I reckon I could get that working in about 5 minutes if you want me to
have a bash at it ;-p

Marc

Aug 15 '07 #3
Seems to work:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.ComponentModel;

static class Program
{
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(fals e);
using(Form f = new Form())
using (PropertyGrid grid = new PropertyGrid())
{
grid.Dock = DockStyle.Fill;
f.Controls.Add(grid);
grid.SelectedObject = new MemberFilter(new Person(),
"Forename", "DateOfBirth", "DoesNotExist");
Application.Run(f);
}
}
}

public class Person
{
string forename, surname;
public string Forename { get { return forename; } set
{ forename = value; } }
public string Surname { get { return surname; } set { surname
= value; } }
DateTime dob;
public DateTime DateOfBirth { get { return dob; } set { dob =
value; } }
}

public sealed class MemberFilter : ICustomTypeDescriptor
{
private readonly IDictionary<string, stringmembers;
private readonly object component;

public MemberFilter(object component, params string[]
members) :
this(component, false, members)
{ }
public MemberFilter(object component, bool caseSensitive,
params string[] members)
{
if (component == null) throw new
ArgumentNullException("component");
if (members == null) throw new
ArgumentNullException("members");

this.component = component;
// use invariant for property names (makes sense to me at
least...)
this.members = new Dictionary<string,
string>(caseSensitive ?
StringComparer.InvariantCulture :
StringComparer.InvariantCultureIgnoreCase);
foreach (string member in members)
{
this.members[member] = member;
}
}
AttributeCollection ICustomTypeDescriptor.GetAttributes()
{
return TypeDescriptor.GetAttributes(component);
}

string ICustomTypeDescriptor.GetClassName()
{
return TypeDescriptor.GetClassName(component);
}

string ICustomTypeDescriptor.GetComponentName()
{
return TypeDescriptor.GetComponentName(component);
}

TypeConverter ICustomTypeDescriptor.GetConverter()
{
return TypeDescriptor.GetConverter(component);
}

EventDescriptor ICustomTypeDescriptor.GetDefaultEvent()
{
EventDescriptor result =
TypeDescriptor.GetDefaultEvent(component);
return (result != null &&
members.ContainsKey(result.Name)) ? result : null;

}

PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty()
{
PropertyDescriptor result =
TypeDescriptor.GetDefaultProperty(component);
return (result != null &&
members.ContainsKey(result.Name)) ? result : null;
}

object ICustomTypeDescriptor.GetEditor(Type editorBaseType)
{
return TypeDescriptor.GetEditor(component,
editorBaseType);
}

EventDescriptorCollection
ICustomTypeDescriptor.GetEvents(Attribute[] attributes)
{
return GetEvents(); // don't filter on attribute; we're
calling the shots...
}
EventDescriptorCollection ICustomTypeDescriptor.GetEvents()
{
return GetEvents();
}
private EventDescriptorCollection GetEvents()
{
EventDescriptorCollection master =
TypeDescriptor.GetEvents(component);
List<EventDescriptorlist = new
List<EventDescriptor>(master.Count);
foreach (EventDescriptor evt in master)
{
if (members.ContainsKey(evt.Name)) list.Add(evt);
}
return new EventDescriptorCollection(list.ToArray());
}
PropertyDescriptorCollection
ICustomTypeDescriptor.GetProperties(Attribute[] attributes)
{
return GetProperties(); // don't filter on attribute;
we're calling the shots...
}

PropertyDescriptorCollection
ICustomTypeDescriptor.GetProperties()
{
return GetProperties();
}
private PropertyDescriptorCollection GetProperties()
{
PropertyDescriptorCollection master =
TypeDescriptor.GetProperties(component);
List<PropertyDescriptorlist = new
List<PropertyDescriptor>(master.Count);
foreach (PropertyDescriptor prop in master)
{
if (members.ContainsKey(prop.Name)) list.Add(prop);
}
return new PropertyDescriptorCollection(list.ToArray());
}

object
ICustomTypeDescriptor.GetPropertyOwner(PropertyDes criptor pd)
{
return component;
}
}

Aug 15 '07 #4
[additional] actually, the last few lines should probably be:

object
ICustomTypeDescriptor.GetPropertyOwner(PropertyDes criptor pd)
{
ICustomTypeDescriptor ctd = component as
ICustomTypeDescriptor;
return ctd == null ? component : ctd.GetPropertyOwner(pd);
}

In case component itself is forwarding - i.e. perhaps we have a filter
on a filter on a component.
The other alternative would be to return (instead of the vanilla
members) wrappers around the PropertyDescriptor etc that impersonate
the original, but forward to component internally... again, it gets
messy...

Aug 15 '07 #5
You rock. I definitely have a lot to think about and research. Thanks for
your help.

Jon

"Marc Gravell" <ma**********@gmail.comwrote in message
news:11*********************@57g2000hsv.googlegrou ps.com...
[additional] actually, the last few lines should probably be:

object
ICustomTypeDescriptor.GetPropertyOwner(PropertyDes criptor pd)
{
ICustomTypeDescriptor ctd = component as
ICustomTypeDescriptor;
return ctd == null ? component : ctd.GetPropertyOwner(pd);
}

In case component itself is forwarding - i.e. perhaps we have a filter
on a filter on a component.
The other alternative would be to return (instead of the vanilla
members) wrappers around the PropertyDescriptor etc that impersonate
the original, but forward to component internally... again, it gets
messy...

Aug 15 '07 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Alexander | last post by:
I am building a little unique dialog editor and have derived some new classes like DButton, DLabel and DTextBox. The user adds these Controls to a panel which is part of a class Document which is...
7
by: Baski | last post by:
Base class: class AssetBase { string _clli; public string CLLI { get
17
by: Bob Weiner | last post by:
What is the purpose of hiding intead of overriding a method? I have googled the question but haven't found anything that makes any sense of it. In the code below, the only difference is that...
1
by: Amber | last post by:
The DataGrid allows you to make columns visible or invisible on demand - even edit and other special columns. This article will show you how it is done. Some developers have reported problems...
7
by: Dennis | last post by:
I have a class named myclass that inheirits from "baseclass". There is a property of "baseclass" that I don't want exposed in the IDE. The MSDN documentation says" "A derived type can hide an...
1
by: Christophe Peillet | last post by:
I have a CompositeControl with two types of properties: 1.) Mapped Properties that map directly to a child control's properties (ex.: this.TextboxText = m_txt.Text). These properties are handled...
10
by: Smokey Grindle | last post by:
i want to inherit the list view class, but in the inherited class, hide the Header style property and the view property (basically its a detailed list with always clickable headers) how do I keep...
14
by: Dom | last post by:
Hi all I'm developing a control, and I need to hide some properties to the user. For example, suppose I need Text property to be completely inacessible (from a Form/Code that is into another...
162
by: Sh4wn | last post by:
Hi, first, python is one of my fav languages, and i'll definitely keep developing with it. But, there's 1 one thing what I -really- miss: data hiding. I know member vars are private when you...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.