473,395 Members | 1,941 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,395 software developers and data experts.

Changing property attributes at runtime

Hi is there a way to change propertys attribute from the code?

Let´s say that i have the following property in my class:

[DisplayName("Number of cars")]
public int Count[
get { . . . }
set { . . . ]
}

Is there a way to change the displayname, from my code, at runtime to
"Number of bikes".

thx!

Kimmo Laine
Oct 13 '06 #1
5 57739
Yes; kind of... but not trivial... I guess it comes down to "why?" as to
whether it is worth the effort... are you using this on a property grid or
something? Because if this is just for a column heading on a grid, I suspect
you can override that text on the grid control...

You could try just obtaining the reflective attribute via GetType and
GetProperty, but IIRC this doesn't "stick".

However, for the /component/ model (which Forms binding uses) you can
actually do pretty much anything... invent properties on the fly, rename
them, change the attributes, etc:
You can implement the ICustomTypeDescriptor interface; forward most of the
methods to the TypeDescriptor equivalents (using GetType(), not "this" as
the parameter); for GetProperties, call the TypeDescriptor version, but then
change the results for the property you care about... instead of returning
the (reflective) PropertyDescriptor you get, you should be able to return a
bespoke one that changes the Attributes.

Too much there for a short example, but I have useed the above (as part of a
complex system) with great success (for dynamic properties similar to
DataSet columnns).

Marc
Oct 13 '06 #2
MMA
Try this may require a little tweaking but should be close:

using System;
using System.Reflection;

// A custom attribute to allow a target to have a display value.
public class DisplayName: Attribute {
// The constructor is called when the attribute is set.
public AnimalTypeAttribute(String Value) {
_value = Value;
}

// Keep a variable internally ...
protected string _value;

// .. and show a copy to the outside world.
public string Value {
get { return _value; }
set { _value = value; }
}
}

// A test class where property has its own display value.
class DisplayNameTestClass {
[DisplayName("Number of cars")]
public int Count
{
get { . . . }
set { . . . }
}

}

class DemoClass {
static void Main(string[] args) {
DisplayNameTestClass testClass = new DisplayNameTestClass
Type type = testClass.GetType();
FieldInfo myFieldInfo = type.GetField("Count")
DisplayName att =
(DisplayName)Attribute.GetCustomAttribute(myFieldI nfo,Type.GetType("DisplayName"));
att.Value = "Number of bikes";
}
}

"Kimmo Laine" wrote:
Hi is there a way to change propertys attribute from the code?

Let´s say that i have the following property in my class:

[DisplayName("Number of cars")]
public int Count[
get { . . . }
set { . . . ]
}

Is there a way to change the displayname, from my code, at runtime to
"Number of bikes".

thx!

Kimmo Laine
Oct 13 '06 #3
Well, to my mind, the main use of the [DisplayName] is for the component
model - otherwise the OP could just use a static property of
"CountDisplayName" or similar and read it at runtime.

For this to be useful, it would have to return the correct value to the
following (which is what 99% of callers will be using):

string displayName = // wrap
TypeDescriptor.GetProperties(testClass)["Count"].DisplayName;

The code posted won't satisfy this, since the component model will simply
ignore the new "DisplayName" attribute, using the pucka DisplayNameAttribute
from the System.ComponentModel namespace instead.

Additionally, the DisplayNameAttribute.DisplayName property is readonly, so
you can't tweak it with reflection. In short, I don't think this will behave
as expected.

Marc
Oct 13 '06 #4
OK, here's the full version; obviously you can change other discreet
values via the PropertyDescriptor implementation, or any attribute via
GetAttributes. I have implemented it as a static instance here, but you
could merrily recreate for each instance, or even on each call.
Personally I use an extenstion of this in a dynamic property bag
approach.

Most of the code is boiler-plate; ForwardingPropertyDescriptor just
allows a daisy-chain. I've chucked in a demo to illustrate it working
with a property-grid and data-grid-view.

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

class Program {
static void Main() {
SomeClass test = new SomeClass();
ShowObject(test, "Before");
SomeClass.CountDisplayName = "Toadstool count";
ShowObject(test, "After");
}
private static void ShowObject(SomeClass item, string title) {
using (Form form = new Form())
using (PropertyGrid propGrid = new PropertyGrid())
using (DataGridView gridView = new DataGridView()) {
form.Height = 500;
form.Text = title;
propGrid.Dock = DockStyle.Fill;
gridView.Dock = DockStyle.Bottom;
form.Controls.Add(propGrid);
form.Controls.Add(gridView);
propGrid.SelectedObject = item;
List<SomeClassitems = new List<SomeClass>();
items.Add(item);
gridView.DataSource = items;
form.ShowDialog();
}
}
}
class SomeClass : ICustomTypeDescriptor {
private int count = 5;
[DisplayName("Count of something"), DefaultValue(5)]
public int Count {
get {return count;}
set {count = value;}
}
private string somethingElse = "Empty";
[DisplayName("Another Property"), DefaultValue("Empty")]
public string SomethingElse {
get { return somethingElse; }
set { somethingElse = value; }
}
AttributeCollection ICustomTypeDescriptor.GetAttributes() {
return TypeDescriptor.GetAttributes(GetType());
}

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

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

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

EventDescriptor ICustomTypeDescriptor.GetDefaultEvent() {
return TypeDescriptor.GetDefaultEvent(GetType());
}

PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty() {
return TypeDescriptor.GetDefaultProperty(GetType());
}

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

EventDescriptorCollection
ICustomTypeDescriptor.GetEvents(Attribute[] attributes) {
return TypeDescriptor.GetEvents(GetType(), attributes);
}

EventDescriptorCollection ICustomTypeDescriptor.GetEvents() {
return TypeDescriptor.GetEvents(GetType());
}

PropertyDescriptorCollection
ICustomTypeDescriptor.GetProperties(Attribute[] attributes) {
return HackProperties(TypeDescriptor.GetProperties(GetTyp e(),
attributes));
}

PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties()
{
return HackProperties(TypeDescriptor.GetProperties(GetTyp e()));
}

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

private PropertyDescriptorCollection
HackProperties(PropertyDescriptorCollection properties) {
List<PropertyDescriptorpropList = new
List<PropertyDescriptor>();
foreach (PropertyDescriptor prop in properties) {
if (prop.Name == "Count")
propList.Add(CountPropertyDescriptor);
else
propList.Add(prop);
}
return new PropertyDescriptorCollection(propList.ToArray(),
true);
}
private static readonly DisplayNamePropertyDescriptor
CountPropertyDescriptor;
public SomeClass() { }
public static string CountDisplayName {
get { return CountPropertyDescriptor.DisplayName; }
set { CountPropertyDescriptor.SetDisplayName(value); }
}
static SomeClass() {
CountPropertyDescriptor = new
DisplayNamePropertyDescriptor(TypeDescriptor.GetPr operties(typeof(SomeClass))["Count"]);
}
}
public class DisplayNamePropertyDescriptor :
ForwardingPropertyDescriptor {
private string displayName;
public void SetDisplayName(string displayName) {
this.displayName = displayName;
}
public DisplayNamePropertyDescriptor(PropertyDescriptor root)
: base(root) {
SetDisplayName(root.DisplayName);
}
public override string DisplayName {
get { return displayName; }
}

}

public abstract class ForwardingPropertyDescriptor : PropertyDescriptor
{
private readonly PropertyDescriptor _root;
protected PropertyDescriptor Root { get { return _root; } }
protected ForwardingPropertyDescriptor(PropertyDescriptor root)
: base(root) {
_root = root;
}
public override void AddValueChanged(object component, EventHandler
handler) {
Root.AddValueChanged(component, handler);
}
public override AttributeCollection Attributes {
get {
return Root.Attributes;
}
}
public override bool CanResetValue(object component) {
return Root.CanResetValue(component);
}
public override string Category {
get {
return Root.Category;
}
}
public override Type ComponentType {
get { return Root.ComponentType; }
}
public override TypeConverter Converter {
get {
return Root.Converter;
}
}
public override string Description {
get {
return Root.Description;
}
}
public override bool DesignTimeOnly {
get {
return Root.DesignTimeOnly;
}
}
public override string DisplayName {
get {
return Root.DisplayName;
}
}
public override bool Equals(object obj) {
return Root.Equals(obj);
}
public override PropertyDescriptorCollection
GetChildProperties(object instance, Attribute[] filter) {
return Root.GetChildProperties(instance, filter);
}
public override object GetEditor(Type editorBaseType) {
return Root.GetEditor(editorBaseType);
}
public override int GetHashCode() {
return Root.GetHashCode();
}
public override object GetValue(object component) {
return Root.GetValue(component);
}
public override bool IsBrowsable {
get {
return Root.IsBrowsable;
}
}
public override bool IsLocalizable {
get {
return Root.IsLocalizable;
}
}
public override bool IsReadOnly {
get { return Root.IsReadOnly; }
}
public override string Name {
get {
return Root.Name;
}
}
public override Type PropertyType {
get { return Root.PropertyType; }
}
public override void RemoveValueChanged(object component,
EventHandler handler) {
Root.RemoveValueChanged(component, handler);
}
public override void ResetValue(object component) {
Root.ResetValue(component);
}
public override void SetValue(object component, object value) {
Root.SetValue(component, value);
}
public override bool ShouldSerializeValue(object component) {
return Root.ShouldSerializeValue(component);
}
public override bool SupportsChangeEvents {
get {
return Root.SupportsChangeEvents;
}
}
public override string ToString() {
return Root.ToString();
}
}

Oct 13 '06 #5
Thx for your replys! I used the Marc´s method and did the following:

// Data which is shown in the propertygrid. It inherits from my custom
descriptor
class MyData : MyCustomDescriptor {
// Property which i need to localize. Custom attribute holds the string
ID which is loaded from the resource file
[MyAttribute(123)]
public int Count{ . . . }
}

// Custom descriptor. Used when propertygrid is inspecting my class - MyData
class MyCustomDescriptor : ICustomTypeDescriptor {
public PropertyDescriptorCollection GetProperties() {
PropertyDescriptorCollection orgPdc =
TypeDescriptor.GetProperties(this, true);
PropertyDescriptorCollection newPdc = new
PropertyDescriptorCollection(null);

foreach(PropertyDescriptor t in orgPdc) {
// See if the property name needs to be changed
MyAttribute ma = (MyAttribute)t.Attributes[typeof(MyAttribute)];
if (ma != null) {
// Create custom description object - explained later
newPdc.Add(new MyDescription(t, ma.MsgID));
} else {
// Use normal
newPdc.Add(t);
}
}

return newPdc;
}
}

// Custom description object - the actual work is done here
class MyDescription : PropertyDescriptor {
private PropertyDescriptor m_PD = null;
private int m_MsgID = 0;

public MyDescription(PropertyDescriptor pd, int msgID) : base(pd)
{
m_PD = pd;
m_MsgID = msgID;
}

public override string DisplayName {
get {
return // Load the resource (m_MsgID) from somewhere
}
}
}
-K
Oct 16 '06 #6

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

Similar topics

1
by: Tom Rahav | last post by:
Hello. I use visual basic .net 2003 and Crystal Reports for creating win-reports. My question is if there is any possibility to set font properties (type, color and size) of a text control or...
1
by: Hans Bampel | last post by:
Hello group, i want to overwrite or manipulate a attribute of a property in a derived class. I use a attribute DBInfo via reflection on my properties to set the parameters in a SQL-statement...
2
by: Luis Arvayo | last post by:
Is there some way to attach an editor to a property of a class at runtime ? Ex.; public class MyClass { public int BitmapIndex
1
by: O.A.Haugum | last post by:
Hi I want to use a lot of icons in panels in a status bar. The icons shall show the current status of operations and has to be changed programmatically. Is it possible to store the icons...
2
by: Jason Richmeier | last post by:
Perhaps it is because it is the end of the day and my eyes are tired of looking at code but I cannot seem to figure out what I am doing wrong and what I can do (if anything) to fix it. On a...
2
by: tfsimes | last post by:
Hi, I am a long time ASP developer learning .NET, so please bear with me. I am trying to find an article or such that will help me understand how to change control properties at runtime based on...
2
by: Ray Cassick | last post by:
I am looking for a way to hide a property I created on a user control from a property grid at runtime but allow it to be seen at design time. Any ideas? I tried setting the category of the...
2
by: Radu | last post by:
Hi, I have a "select" control named "cboSelectScorecardType", defined as <select id="cboSelectScorecardType" size="1" runat="server"> </select> which shows a list of files on my drive. It...
0
by: Nathan Sokalski | last post by:
I am attempting to add Attributes to my ASP.NET Controls & Properties. Here is what my Controls look like: <ToolboxData("<{0}:Parameter runat=""server""/>")_ Public Class Parameter : Inherits...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
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
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...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

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.