在PropertyGrid中禁用另一个属性的最简单方法

时间:2019-05-09 20:53:56

标签: c# propertygrid

我知道这是一个简单的问题,并且我在net和Stackoverflow上找到了一些解决方案,但是它们不起作用。

我有一个bool属性'IsAutoSaveEnabled'和一个int属性'Autosave_Duration'

我需要禁用'Autosave_Duration'  当'IsAutoSaveEnabled'false时。

以下代码:

using System;
using System.ComponentModel;
using System.Reflection;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1() { InitializeComponent();}

        class WrapperAutoSave
        {
            private bool _IsAutoSaveEnabled;
            [DisplayName("Use Autosave ?")]
            public bool IsAutoSaveEnabled
            {
                get { return _IsAutoSaveEnabled; }
                set
                {
                    _IsAutoSaveEnabled = value;
                    PropertyDescriptor descriptor = 
                    TypeDescriptor.GetProperties(this.GetType())["Autosave_Duration"];

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

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

                    fieldToChange.SetValue(attribute, _IsAutoSaveEnabled == false);
                }
            }

            [DisplayName("Auto Save Duration")]
            public int Autosave_Duration { get; set; }

        }

        private void Form1_Load(object sender, EventArgs e)
        {
           propertyGrid1.SelectedObject = new WrapperAutoSave();

        }
    }
}

我使用this article来创建代码。

好吧,没有错误,但是更改IsAutoSaveEnabled后,它将禁用自身而不是Autosave_Duration:\另外,当我单击propertyGrid中的所有其他不相关属性时,它也会禁用...

有一些库正在执行此操作,但是我不想在应用程序中添加任何额外的dll,因此干净而有效的方式将是很棒的!

澄清:来自禁用我的意思是无法编辑或只读。

1 个答案:

答案 0 :(得分:1)

我尝试了您的代码并发现了问题!您说您是从文章中编写代码的:

  

我使用了本文来创建我的代码。好吧,没有错误,但是   更改后...

事实上,您只是将其中的一部分折磨了,然后尝试以自己的方式这样做,这就是失败的原因!

请阅读文章的详细信息,这将不再发生:)

这是工作代码,我评论了您的错误:

using System;
using System.ComponentModel;
using System.Reflection;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1() { InitializeComponent();}

        class WrapperAutoSave
        {
            private bool _IsAutoSaveEnabled;
            [RefreshProperties(System.ComponentModel.RefreshProperties.All)] //// MISTAKE 1 : You missed refresh attribute!
            [DisplayName("Use Autosave ?")]
            public bool IsAutoSaveEnabled
            {
                get { return _IsAutoSaveEnabled; }
                set
                {
                    _IsAutoSaveEnabled = value;
                    PropertyDescriptor descriptor = 
                    TypeDescriptor.GetProperties(this.GetType())["Autosave_Duration"];

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

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

                    fieldToChange.SetValue(attribute, _IsAutoSaveEnabled == false);
                }
            }



            [DisplayName("Auto Save Duration")]
            [ReadOnly(true)] //// MISTAKE 2 : You missed read-only attribute
            public int Autosave_Duration { get; set; }

        }

        private void Form1_Load(object sender, EventArgs e)
        {
           propertyGrid1.SelectedObject = new WrapperAutoSave();

        }
    }
}

错误1::您错过了刷新的重要属性。 [RefreshProperties(...)]

Mistake 2::您也错过了readonly属性,这就是为什么错误的属性将被禁用的原因:[ReadOnly(true)]