Самый простой способ отключить `свойство из другого свойства` в PropertyGrid - PullRequest
0 голосов
/ 09 мая 2019

Я знаю, что это простой вопрос, и я нашел некоторые решения в сети и 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();

        }
    }
}

Я использовал эту статью для создания своего кода.

Ну, нет ошибки, но после изменения IsAutoSaveEnabled он отключается сам вместо Autosave_Duration: \ Кроме того, когда я нажимаю на все другие несвязанные свойства в propertyGrid, он тоже отключается ...

Некоторые библиотеки делают это, но я не хочу добавлять какие-либо дополнительные dll в свое приложение, так что чистый и рабочий способ был бы великолепен!

Уточнение: от отключения Я имею в виду невозможность редактирования или только чтение.

1 Ответ

1 голос
/ 10 мая 2019

Я попробовал ваш код и нашел проблему! Вы сказали, что написали свой код из статьи:

Я использовал эту статью , чтобы создать свой код. Ну, нет ошибки, но после смены ...

Infact, Вы просто взяли часть этого и попытались сделать это по-своему , и именно поэтому почему вы потерпели неудачу!

Пожалуйста, прочитайте статью с деталями, и это никогда не повторится:)

Вот рабочий код, я прокомментировал ваши ошибки:

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(...)]

Ошибка 2: Вы также пропустили атрибут readonly, и поэтому неправильные свойства отключаются: [ReadOnly(true)]

...