I am auto-generating code that creates a winform dialog based on configuration (textboxes, dateTimePickers etc). The controls on these dialogs are populated from a saved datas开发者_开发知识库et and
needs to Set and Get properties for various control objects (custom or other).
//Upon opening of form - populate control properties with saved values
MyObject.Value = DataSource.GetValue("Value");
//Upon closing of form, save values of control properties to dataset.
DataSource.SetValue("Value") = MyObject.Value;
Now this is all fine, but what of readOnly properties? I wish to save the result of the property but need to know when to NOT generate code that will attempt to populate it.
//Open form, attempt to populate control properties.
//Code that will result in 'cannot be assigned to -- it is read only'
MyObject.HasValue = DataSource.GetValue("HasValue");
MyObject.DerivedValue = DataSource.GetValue("Total_SC2_1v1_Wins");
//Closing of form, save values.
DataSource.SetValue("HasValue") = MyObject.HasValue;
Remember that I do not know the type of object I've instantiate until runtime.
How can I (at runtime) identify a readonly property?
With PropertyDescriptor
, check IsReadOnly
.
With PropertyInfo
, check CanWrite
(and CanRead
, for that matter).
You may also want to check [ReadOnly(true)]
in the case of PropertyInfo
(but this is already handled with PropertyDescriptor
):
ReadOnlyAttribute attrib = Attribute.GetCustomAttribute(prop,
typeof(ReadOnlyAttribute)) as ReadOnlyAttribute;
bool ro = !prop.CanWrite || (attrib != null && attrib.IsReadOnly);
IMO, PropertyDescriptor
is a better model to use here; it will allow custom models.
I noticed that when using PropertyInfo, the CanWrite
property is true even if the setter is private. This simple check worked for me:
bool IsReadOnly = prop.SetMethod == null || !prop.SetMethod.IsPublic;
Also - See Microsoft Page
using System.ComponentModel;
// Get the attributes for the property.
AttributeCollection attributes =
TypeDescriptor.GetProperties(this)["MyProperty"].Attributes;
// Check to see whether the value of the ReadOnlyAttribute is Yes.
if(attributes[typeof(ReadOnlyAttribute)].Equals(ReadOnlyAttribute.Yes)) {
// Insert code here.
}
I needed to use this for different classes, so I created this generic function:
public static bool IsPropertyReadOnly<T>(string PropertyName)
{
MemberInfo info = typeof(T).GetMember(PropertyName)[0];
ReadOnlyAttribute attribute = Attribute.GetCustomAttribute(info, typeof(ReadOnlyAttribute)) as ReadOnlyAttribute;
return (attribute != null && attribute.IsReadOnly);
}
精彩评论