6

PropertyGridヘルパー クラスでプロパティを表示するために使用した があります。PropertyGridヘルパー クラスを次のように割り当てます。

myPropertyGrid.SelectedObject = mySettingsHelper;

ReadOnlyAttributeヘルパー クラスでは、設計時に次のように割り当てます。

[DisplayName("DisplayExA"),
Description("DescriptionExA"),
ReadOnlyAttribute(true)]
public string PropertyA { get; set; }

[DisplayName("DisplayExB"),
Description("DescriptionExB"),
ReadOnlyAttribute(false)]
public string PropertyB { get; set; }

[DisplayName("DisplayExC"),
Description("DescriptionExC"),
ReadOnlyAttribute(true)]
public string PropertyC { get; set; }

しかし、実行時に個々のプロパティのこの属性を動的に変更できるようにする必要があります。特定の基準に基づいて、これらのプロパティの一部を読み取り専用にするか、読み取り専用でなくする必要がある場合があります。実行時に動的に変更するにはどうすればよいですか?

編集:

次のコードを試してみましたが、これはオブジェクトのすべてのインスタンスに ReadOnly 属性を設定します! 私はオブジェクトごとにそれをしたい。場合によっては、あるオブジェクトの PropertyA が読み取り専用である一方で、2 番目のオブジェクトの PropertyA が読み取り専用ではないことがあります。

public static class PropertyReadOnlyHelper
{
    public static  void SetReadOnly(object container, string name, bool value)
    {
        try
        {
            PropertyDescriptor descriptor = TypeDescriptor.GetProperties(container.GetType())[name];
            ReadOnlyAttribute attribute = (ReadOnlyAttribute)descriptor.Attributes[typeof(ReadOnlyAttribute)];
            FieldInfo fieldToChange = attribute.GetType().GetField("isReadOnly",
                                                System.Reflection.BindingFlags.NonPublic |
                                                System.Reflection.BindingFlags.Instance);
            fieldToChange.SetValue(attribute, value);
        }
        catch { }
    }
}
4

5 に答える 5

1

このCodeProject記事のライブラリを使用して、まさに必要なこと (読み取り専用属性のオブジェクト レベルの割り当て) を行うことができました。すばらしいのは、.NET を引き続き使用しPropertyGrid、カスタム属性を使用して動的設定を処理できることです。

于 2013-10-29T17:40:48.760 に答える
0

リフレクションを使用してクラスのインスタンス参照を取得し、そのインスタンスのプロパティをReadOnlyAttribute切り替えます。IsReadOnly最後に、必要に応じて SelectedObjects を null に設定してからリセットすることにより、PropertyGrid 内の項目を再選択します。PropertyGridRefreshTabsメソッドを使用してこれを行うこともできますが、わかりません。

編集:

残念ながら、IsReadOnly プロパティ自体は読み取り専用です。この場合、リフレクションを使用して、IsReadOnly プロパティのバッキング フィールドの値を変更する必要があります。

于 2013-10-28T17:23:09.167 に答える
0
Please try the code below.


  
[CategoryAttribute("2. LINE"), DisplayNameAttribute("Spline Line Tension"),
 DescriptionAttribute("Chart's Spline Line Tension "), ReadOnlyAttribute(false)]
public float _PG_SplineTension
{
    get
    {
        bool lbReadyOnly = true;
        SetPropertyReadOnly("_PG_SplineTension", lbReadyOnly);
        return this.cfSplineTension;
   }
    set { this.cfSplineTension = value; }
}



private void SetPropertyReadOnly(string lsProperty, bool lbIsReadOnly)
{
    PropertyDescriptor descriptor = TypeDescriptor.GetProperties(this.GetType())[lsProperty];
    ReadOnlyAttribute attribute = (ReadOnlyAttribute)

    descriptor.Attributes[typeof(ReadOnlyAttribute)];
    FieldInfo fieldToChange = attribute.GetType().GetField("isReadOnly",
        System.Reflection.BindingFlags.NonPublic |
        System.Reflection.BindingFlags.Instance);
    fieldToChange.SetValue(attribute, lbIsReadOnly);
}
于 2021-01-10T00:02:12.293 に答える
0

PropertyGrid 内のプロパティの参照可能または読み取り専用属性を動的に設定することは、しばしば一緒に必要とされ、同様の仕事でもあります

いくつかのタッチの後、「実行時に PropertyGrid の一部のプロパティを非表示にする」に関するReza Aghaeiの優れた回答は、読み取り専用属性の操作にも適用できます。

public class CustomObjectWrapper : CustomTypeDescriptor
{
    public object WrappedObject { get; private set; }
    public List<string> BrowsableProperties { get; private set; }
    public List<string> ReadonlyProperties { get; private set; }

    public CustomObjectWrapper(object o)
        : base(TypeDescriptor.GetProvider(o).GetTypeDescriptor(o))
    {
        WrappedObject = o;
        BrowsableProperties = new List<string>() { "Text", "BackColor" };
        ReadonlyProperties = new List<string>() { "Font" };
    }
    public override PropertyDescriptorCollection GetProperties()
    {
        return this.GetProperties(new Attribute[] { });
    }
    public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
    {
        List<PropertyDescriptor> result = new List<PropertyDescriptor>();

        IEnumerable<PropertyDescriptor> properties = base.GetProperties(attributes).Cast<PropertyDescriptor>()
            .Where(p => BrowsableProperties.Contains(p.Name));//unbrowsable filtering

        foreach (var p in properties)
        {
            PropertyDescriptor resultPropertyDescriptor = null;

            //handle being readonly 
            if (ReadonlyProperties.Contains(p.Name))
            {
                List<Attribute> atts = p.Attributes.Cast<Attribute>().ToList();
                atts.RemoveAll(a => a.GetType().Equals(typeof(ReadOnlyAttribute)));//remove any readonly attribute
                atts.Add(new ReadOnlyAttribute(true));//add "readonly=true" attribute

                resultPropertyDescriptor = TypeDescriptor.CreateProperty(WrappedObject.GetType(), p, atts.ToArray());
            }
            else
            {
                resultPropertyDescriptor = TypeDescriptor.CreateProperty(WrappedObject.GetType(), p, p.Attributes.Cast<Attribute>().ToArray());
            }

            if (resultPropertyDescriptor != null)
                result.Add(resultPropertyDescriptor);

        }

        return new PropertyDescriptorCollection(result.ToArray());
    }
}

と使用法:

propertyGrid1.SelectedObject = new CustomObjectWrapper(myobject);
于 2020-06-19T08:19:20.910 に答える