2010-03-20 14 views
9

Tengo una clase con un conjunto de propiedades Como se indica a continuación.Eliminar el atributo C# de una propiedad dinámicamente

class ContactInfo 
{ 
    [ReadOnly(true)] 
    [Category("Contact Info")] 
    public string Mobile { get; set; } 

    [Category("Contact Info")] 
    public string Name{ get; set; } 
} 

Los objetos de esta clase se asigna a una red de propiedad, por lo que los usuarios pueden actualizar un contacto existente. puede ver que Mobile está marcado como ReadOnly.

Pero, cuando quiero agregar un contacto completamente nuevo, me gustaría que los usuarios también puedan editar el contacto móvil. Para eso necesito eliminar la propiedad Readonly dinámicamente del tipo, antes de asignar el objeto a la cuadrícula de propiedades. ¿Es posible?

Respuesta

7

No se puede quitar el atributo en tiempo de ejecución, pero se puede utilizar la reflexión para cambiar el campo respaldo privada de sólo lectura del atributo de sólo lectura en Falso. Por lo que es el equivalente a [sólo lectura (falso)]

Consulte este artículo para obtener más información:

http://codinglight.blogspot.com/2008/10/changing-attribute-parameters-at.html

Editar: enlace fijo

+0

Esto es exactamente lo que quería en mi caso. – SysAdmin

+0

El enlace está muerto. – grimmig

+0

@grimmig: enlace fijo – andreialecu

1

que no es posible en este momento para eliminar atributos dinamycally (en tiempo de ejecución)

como una sugerencia que puede hacer 2 clases: uno con los atributos y otra sin

+1

No es necesario realizar 2 clases, la reflexión se puede usar para modificar el campo booleano del atributo ReadOnly y cambiarlo a falso (no solo de lectura). – andreialecu

+0

hmm, buena idea, no pensé en eso :) – Omu

2

Estoy de acuerdo w/Omu; en realidad estás hablando de dos clases (ver modelos) en este caso, para apoyar tus dos vistas diferentes. Algo así como

CreateContactViewModel y EditContactViewModel

0

he seguido la sugerencia de Legenden. Esto es lo que ocurrió con

class ContactInfo 
{ 
     [ReadOnly(true)] 
     [Category("Contact Info")] 
     public string Mobile { get; set; } 

     [Category("Contact Info")] 
     public string Name{ get; set; } 

     public void SetMobileEdit(bool allowEdit) 
     { 
      PropertyDescriptor descriptor = TypeDescriptor.GetProperties(this.GetType())["Mobile"]; 

      ReadOnlyAttribute attrib = (ReadOnlyAttribute)descriptor.Attributes[typeof(ReadOnlyAttribute)]; 

      FieldInfo isReadOnly = attrib.GetType().GetField("isReadOnly", BindingFlags.NonPublic | BindingFlags.Instance); 

      isReadOnly.SetValue(attrib, !allowEdit); 
     } 
} 
+0

Creo que si bien esto funciona, no es un buen diseño. Las responsabilidades sangran. – Paul

0

El blog CodingLight.com trasladó a Blogspot (el enlace anterior se rompe). Ver http://codinglight.blogspot.com/2008/10/changing-attribute-parameters-at.html.

Además, el seguimiento de SysAdmin no mencionó el atributo [RefreshProperties(RefreshProperties.All)] que parece ser necesario para una solución realmente funcional.

Por último, creo que incluso David Morton (autor del artículo citado) perdió una cosa muy importante: si la clase (ContactInfo, en el ejemplo de seguimiento del Administrador del sistema) no tiene al menos una propiedad con el atributo [ReadOnly] definido en tiempo de compilación, cuando FieldInfo "isReadOnly" se establece en true en tiempo de ejecución, el resultado es que toda la clase se convierte en de solo lectura.

Cuestiones relacionadas