Frage


Gibt es eine Möglichkeit, eine „Browsable“ Attribut abhängig zu machen, so dass die Eigenschaft, dass es manchmal gilt in der Eigenschaftenseite erscheint und manchmal nicht?
Dank:)

War es hilfreich?

Lösung

Es gibt keinen einfachen Weg.

Sie können dies möglicherweise funktionieren durch ICustomTypeDescriptor implementieren. Hier ist ein guter Artikel über ICustomTypeDescriptor implementieren.

Sie können auch Ihre eigenen Control mit Ihrer Klasse und überschreiben Sie die Entfernen bestimmte Eigenschaften von Immobilien Raster.

Andere Tipps

Ich bin nicht sicher, ob dies auf Ihre Situation zutrifft, aber Sie können durch den Aufruf der Funktion unten.

die „Browsable“ Dekoration zur Laufzeit anpassen
/// <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);
}

Sie können dies tun, indem Sie einen benutzerdefinierten Typ-Modell bereitstellt; bei der einfachste Ebene, können Sie eine benutzerdefinierte TypeDescriptor für Ihre Art von ExpandableObjectConverter abgeleiteten Informationen hinausgehen und einfach include / die gegebene Eigenschaft nach Lust und Laune ausschließen - aber das funktioniert nur mit PropertyGrid - von der Eigenschaftenseite verwendet. Ein komplexerer Ansatz ist die Verwendung ICustomTypeDescriptor / TypeDescriptionProvider - dies kann dann Arbeit im Inneren Dinge wie DataGridView

Als Verbesserung auf @ neoikon Antwort oben und die Ausnahme Ganesh in den Kommentaren erwähnt zu vermeiden, ist hier eine Version, dass Anwendungen Generika, die Art zu erhalten:

    /// <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);
    }

Sie können dann auch eine Version, die eine Instanz nimmt:

    /// <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);
    }

Verbrauch:

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

Ich kam in dieser auf der Suche nach einer Möglichkeit, bestimmte Mitglieder sichtbar oder in IntelliSense versteckt zu erklären und in der Lage sein, es zu ändern, wenn für alle, die bei der Kompilierung versteckt werden müssen. Ich kann nicht sagen, ob das, was Sie für oder nicht suchen, aber ich fand eine Antwort auf meine Frage ... dachte, es nicht zu teilen schaden könnte.

richte ich eine bedingte Kompilierung-Symbol (im Register Erstellen Projekteigenschaften gefunden) IS_VIS (Wert wahr, wenn Sie bestimmte Mitglieder wollen zeigen, falsch, wenn Ihr wollen, sie zu verstecken), und dann:

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

Sie dann die isVis Variable im Attribute verweisen:

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

Ich tat dies in VB und dies wurde in aller Eile zu c # umgewandelt. Wenn etwas nicht richtig funktioniert, lassen Sie es mich wissen.

John Cummings Lösung im Grunde für mich gearbeitet, hatte aber die folgenden zwei Probleme wegen seiner Einführung des Generics (was recht klug, obwohl war):

1- die Version SetBrowsableProperty<T>(T obj, string strPropertyName, bool bIsBrowsable) wird fehlschlagen, wenn eine Sammlung als Parameter obj übergeben wird, weil T, in diesem Fall wird eine Implementierung von IEnumerable (zB Liste, Array etc.) und nicht die Art der Sammlung, die tatsächlich war vorgesehen.

2- Es ermöglicht auch in den primitiven Typen vorbei, was in diesem Fall sinnlos und wird fast immer fehlschlagen.

Komplett überarbeitete Lösung:

Hier also ist die überarbeitete Lösung, dass diese Probleme Tackles und hat für mich gearbeitet: (Ich habe die Methoden leicht umbenannt und die Variablen)

Als erstes die tatsächlichen Methode, die die Hauptaufgabe hat, den Browsable Attributwert zu ändern:

/// <summary>
/// Sets the Browsable attribute value of a property of a non premitive type.
/// NOTE: The class property must be decorated with [Browsable(...)] attribute.
/// </summary>
/// <param name="type">The type that contains the property, of which the Browsable attribute value needs to be changed</param>
/// <param name="propertyName">Name of the type property, of which the Browsable attribute value needs to be changed</param>
/// <param name="isBrowsable">The new Browsable value</param>
public static void SetBrowsableAttributeOfAProperty(Type type, string propertyName, bool isBrowsable)
{
    //Validate type - disallow primitive types (this will eliminate problem-2 as mentioned above)
    if (type.IsEnum || BuiltInTypes.Contains(type))
        throw new Exception($"The type '{type.Name}' is not supported");

    var objPropertyInfo = TypeDescriptor.GetProperties(type);

    // Get the Descriptor's Properties
    PropertyDescriptor theDescriptor = objPropertyInfo[propertyName];

    if (theDescriptor == null)
        throw new Exception($"The property '{propertyName}' is not found in the Type '{type}'");

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

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

Nun ist die Variante vorgeschlagen, in John Cummings Lösung mit <T>:

public static void SetBrowsableAttributeOfAProperty<T>(string propertyName, bool isBrowsable)
{
    SetBrowsableAttributeOfAProperty(typeof(T), propertyName, isBrowsable);
}

Nun ist die Überlastung, die das Problem nicht hatte. 1, aber die folgende Modifikation Greift es jetzt:

/// <summary>
/// Sets the Browsable attribute value of a property of a non premitive type.
/// NOTE: The class property must be decorated with [Browsable(...)] attribute.
/// </summary>
/// <param name="obj">An instance of the type that contains the property, of which the Browsable attribute value needs to be changed.</param>
/// <param name="propertyName">Name of the type property, of which the Browsable attribute value needs to be changed</param>
/// <param name="isBrowsable">Browsable Value</param>
public static void SetBrowsableAttributeOfAProperty<T>(T obj, string propertyName, bool isBrowsable)
{
    if (typeof(T).GetInterface("IEnumerable") != null && typeof(T) != typeof(string))   //String type needs to be filtered out as String also implements IEnumerable<char> but its not a normal collection rather a primitive type
    {
        //Get the element type of the IEnumerable collection
        Type objType = obj.GetType().GetGenericArguments()?.FirstOrDefault();       //when T is a collection that implements IEnumerable except Array
        if (objType == null) objType = obj.GetType().GetElementType();              //when T is an Array

        SetBrowsableAttributeOfAProperty(objType, propertyName, isBrowsable);
    }
    else
        SetBrowsableAttributeOfAProperty(typeof(T), propertyName, isBrowsable);

und hier ist Nutzenfunktion alle C # System zu erhalten eingebaut (primitive) Typen:

    public static List<Type> BuiltInTypes
        {
            get
            {
                if (builtInTypes == null)                
                    builtInTypes = Enum.GetValues(typeof(TypeCode)).Cast<TypeCode>().Select(t => Type.GetType("System." + Enum.GetName(typeof(TypeCode), t)))
                                   .ToList();

                return builtInTypes;
            }
        }

Verwendung:

 class Foo
{
    [Browsable(false)]
    public string Bar { get; set; }
}
void Example()
{
    SetBrowsableAttributeOfAProperty<Foo>("Bar", true);     //works

    Foo foo = new Foo();
    SetBrowsableAttributeOfAProperty(foo, "Bar", false);    //works

    List<Foo> foos = new List<Foo> { foo, new Foo { Bar = "item2" } };
    SetBrowsableAttributeOfAProperty(foos, "Bar", true);    //works now, whereas it would crash with an exception in John Cummings's solution
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top