Вы можете написать оболочку для вашей сущности, которая реализует ICustomTypeDescriptor
. Таким образом, вы могли бы решить, какие свойства доступны только для чтения или нет ... но это довольно много работы для не такого сложного сценария.
Более простым решением было бы изменить DataSourceUpdateMode
привязки на Never
, если вы хотите, чтобы свойство было доступно только для чтения.
ОБНОВЛЕНИЕ: вот базовая оболочка, реализующая ICustomTypeDescriptor
:
class EntityWrapper<T> : CustomTypeDescriptor
{
public EntityWrapper(T entity)
{
this.Entity = entity;
var properties = TypeDescriptor.GetProperties(typeof(T))
.Cast<PropertyDescriptor>()
.ToArray();
ReadOnly = properties.ToDictionary(p => p.Name, p => p.IsReadOnly);
_properties = new PropertyDescriptorCollection(properties
.Select(p => new WrapperPropertyDescriptor(p, this))
.ToArray());
}
public T Entity { get; private set; }
public Dictionary<string, bool> ReadOnly { get; private set; }
public override PropertyDescriptorCollection GetProperties()
{
return _properties;
}
public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
return _properties;
}
private PropertyDescriptorCollection _properties;
private class WrapperPropertyDescriptor : PropertyDescriptor
{
private EntityWrapper<T> _entityWrapper;
private PropertyDescriptor _property;
public WrapperPropertyDescriptor(PropertyDescriptor property, EntityWrapper<T> entityWrapper)
: base(property)
{
_property = property;
_entityWrapper = entityWrapper;
}
public override bool CanResetValue(object component)
{
return _property.CanResetValue(component);
}
public override Type ComponentType
{
get { return _property.ComponentType; }
}
public override object GetValue(object component)
{
return _property.GetValue(component);
}
public override bool IsReadOnly
{
get
{
return _entityWrapper.ReadOnly[this.Name];
}
}
public override Type PropertyType
{
get { return _property.PropertyType; }
}
public override void ResetValue(object component)
{
_property.ResetValue(component);
}
public override void SetValue(object component, object value)
{
_property.SetValue(component, value);
}
public override bool ShouldSerializeValue(object component)
{
return _property.ShouldSerializeValue(component);
}
}
}
Как видите, можно сделать свойство доступным только для чтения только для одного экземпляра:
MyEntity a = new MyEntity { Foo = "hello", Bar = 42 };
MyEntity b = new MyEntity { Foo = "world", Bar = 5 };
EntityWrapper<MyEntity> wa = new EntityWrapper<MyEntity>(a);
EntityWrapper<MyEntity> wb = new EntityWrapper<MyEntity>(b);
var fooA = wa.GetProperties()["Foo"];
var fooB = wb.GetProperties()["Foo"];
wa.ReadOnly["Foo"] = false;
wb.ReadOnly["Foo"] = true;
Console.WriteLine("Property Foo of object a is read-only : {0}", fooA.IsReadOnly);
Console.WriteLine("Property Foo of object b is read-only : {0}", fooB.IsReadOnly);