2011-01-14 11 views
13


C'è un modo per rendere condizionale un attributo "Browsable", quindi la proprietà che lo applica a volte appare nella pagina delle proprietà e talvolta no?
grazie :)Attributo "Browsable" condizionale

risposta

7

Non esiste un modo semplice.

È possibile risolvere questo problema implementando ICustomTypeDescriptor. Ecco un buon articolo su implementing ICustomTypeDescriptor.

Oppure è possibile associare il proprio ControlDesigner alla classe e sovrascrivere il metodo PreFilterProperties per aggiungere o rimuovere proprietà visualizzate nella griglia delle proprietà.

Removing certain properties from property grid.

+2

il collegamento per l'implementazione di ICustomTypeDescriptor.got ha fatto riferimento a https://msdn.microsoft.com/magazine/msdn-magazine-issues. Penso che abbiano rimosso la pagina originale – gg89

6

È possibile eseguire questa operazione fornendo un modello di tipo personalizzato; al livello più semplice, è possibile fornire un valore personalizzato TypeDescriptor per il tipo derivato da ExpandableObjectConverter e semplicemente includere/escludere la proprietà data a caso - ma funziona solo con PropertyGrid - utilizzato dalla pagina delle proprietà. Un approccio più complesso è utilizzare ICustomTypeDescriptor/TypeDescriptionProvider - questo può quindi funzionare all'interno di cose come DataGridView

0

mi sono imbattuto in questo alla ricerca di un modo per dichiarare alcuni membri visibile o nascosto in IntelliSense ed essere in grado di cambiare una volta per tutte che doveva essere nascosta in fase di compilazione. Non posso dire se è quello che stavi cercando o no, ma ho trovato una risposta alla mia domanda ... immaginavo che non potesse ferire condividere.

Ho impostato un simbolo condizionale compilation (che si trova nella scheda Costruisci della proprietà del progetto) IS_VIS (valore essendo vero se si desidera alcuni membri per mostrare, false se il tuo vuole nascondere loro) e poi:

#if IS_VIS 
    public const System.ComponentModel.EditorBrowsableState isVis = 
     ComponentModel.EditorBrowsableState.Always; 
#else 
    public const System.ComponentModel.EditorBrowsableState isVis = 
     ComponentModel.EditorBrowsableState.Never; 
#endif 

si quindi fare riferimento alla variabile isVis nell'attributo:

[EditorBrowsable(isVis)] 
public string myMethod... 

ho fatto questo in VB e questo è stato frettolosamente convertito in C#. Se qualcosa non funziona, fammi sapere.

8

Non sono sicuro che questo si applica alla situazione, ma è possibile regolare la decorazione "Sfogliabile" in fase di esecuzione chiamando la funzione seguente.

/// <summary> 
/// Set the Browsable property. 
/// NOTE: Be sure to decorate the property with [Browsable(true)] 
/// </summary> 
/// <param name="PropertyName">Name of the variable</param> 
/// <param name="bIsBrowsable">Browsable Value</param> 
private void setBrowsableProperty(string strPropertyName, bool bIsBrowsable) 
{ 
    // Get the Descriptor's Properties 
    PropertyDescriptor theDescriptor = TypeDescriptor.GetProperties(this.GetType())[strPropertyName]; 

    // Get the Descriptor's "Browsable" Attribute 
    BrowsableAttribute theDescriptorBrowsableAttribute = (BrowsableAttribute)theDescriptor.Attributes[typeof(BrowsableAttribute)]; 
    FieldInfo isBrowsable = theDescriptorBrowsableAttribute.GetType().GetField("Browsable", BindingFlags.IgnoreCase | BindingFlags.NonPublic | BindingFlags.Instance); 

    // Set the Descriptor's "Browsable" Attribute 
    isBrowsable.SetValue(theDescriptorBrowsableAttribute, bIsBrowsable); 
} 
+0

Ciao. Sto cercando qualcosa di simile. Quando uso il tuo codice, ricevo un'eccezione nullValue nella prima riga 'PropertyDescriptor theDescriptor = TypeDescriptor.GetProperties (this.GetType()) [strPropertyName];'.Voglio sapere dove posizionare queste funzioni e come si riflette sulla griglia Proprietà (non ho visto un oggetto propertyGrid nella funzione). –

+1

Grazie mille per la soluzione, ho cambiato la riga in 'PropertyDescriptor theDescriptor = TypeDescriptor.GetProperties (vObject.GetType()) [strPropertyName];', dove vObject è l'oggetto che sto alterando. –

0

come un miglioramento alla risposta di @ neoikon sopra e al fine di evitare l'eccezione Ganesh citato nei commenti, qui è una versione che utilizza farmaci generici per ottenere il tipo:

/// <summary> 
    /// Set the Browsable property. 
    /// NOTE: Be sure to decorate the property with [Browsable(true)] 
    /// </summary> 
    /// <param name="PropertyName">Name of the variable</param> 
    /// <param name="bIsBrowsable">Browsable Value</param> 
    private void SetBrowsableProperty<T>(string strPropertyName, bool bIsBrowsable) 
    { 
     // Get the Descriptor's Properties 
     PropertyDescriptor theDescriptor = TypeDescriptor.GetProperties(typeof(T))[strPropertyName]; 

     // Get the Descriptor's "Browsable" Attribute 
     BrowsableAttribute theDescriptorBrowsableAttribute = (BrowsableAttribute)theDescriptor.Attributes[typeof(BrowsableAttribute)]; 
     FieldInfo isBrowsable = theDescriptorBrowsableAttribute.GetType().GetField("Browsable", BindingFlags.IgnoreCase | BindingFlags.NonPublic | BindingFlags.Instance); 

     // Set the Descriptor's "Browsable" Attribute 
     isBrowsable.SetValue(theDescriptorBrowsableAttribute, bIsBrowsable); 
    } 

È quindi possibile anche aggiungere una versione che prende un'istanza:

/// <summary> 
    /// Set the Browsable property. 
    /// NOTE: Be sure to decorate the property with [Browsable(true)] 
    /// </summary> 
    /// <param name="obj">An instance of the object whose property should be modified.</param> 
    /// <param name="PropertyName">Name of the variable</param> 
    /// <param name="bIsBrowsable">Browsable Value</param> 
    private void SetBrowsableProperty<T>(T obj, string strPropertyName, bool bIsBrowsable) 
    { 
     SetBrowsableProperty<T>(strPropertyName, bIsBrowsable); 
    } 

utilizzati:

class Foo 
    { 
     [Browsable(false)] 
     public string Bar { get; set; } 
    } 
    void Example() 
    { 
     SetBrowsableProperty<Foo>("Bar", true); 
     Foo foo = new Foo(); 
     SetBrowsableProperty(foo, "Bar", false); 
    }