формы c# — Предоставляют массив в редакторе свойств для пользовательского управления

#c# #winforms

Вопрос:

У меня есть пользовательский элемент управления, в котором я хочу ввести список/массив/коллекцию строк, которые пользователь может редактировать с помощью редактора свойств. У меня есть код, в котором вы можете редактировать массив с помощью редактора свойств, но при запуске массив всегда пуст.

     string[] _validDescriptions = new string[] { };
    [Description("Valid descriptions to select from"), Category("Behavior")]
    public string[] ValidDescriptions
    {
        get 
        {
            if (_validDescriptions == null)
                return new string[0];
            else
                return _validDescriptions; 
        }
        set 
        {
            _validDescriptions = value;
        }
    }
 

Свойство действительно появляется в редакторе, и я могу добавлять значения, но во время выполнения оно всегда пустое

введите описание изображения здесь

Комментарии:

1. Чем вы ожидаете, что он будет заполнен? Вы создаете экземпляр пустого массива.

2. Я хочу, чтобы он был заполнен значениями, введенными в редакторе свойств. Поэтому, когда элемент управления впервые добавляется в другую форму или элемент управления, массив будет пуст. Но затем пользователь может добавлять любые строки, которые ему нужны.

3. Я протестировал его, код, который вы показываете, в порядке. Я могу поместить пользовательский элемент управления с этим кодом в форму, отредактировать значения в конструкторе, прочитать их во время выполнения, и они все еще там. Может быть, покажите нам пример кода, как вы считываете значения во время выполнения.

4. Обнаружена проблема, свойство было пустым только при ссылке в конструкторе. Опубликовал полный ответ, но он отлично работает, когда на него ссылаются в событии загрузки.

Ответ №1:

Обнаружены проблемы, имущество работает нормально. Я пытался сослаться на свойство в конструкторе, которое было пустым. Если я свяжу его с событием загрузки, он будет работать правильно.

     string[] _validDescriptions = new string[] { };
    [Description("Valid descriptions to select from"), Category("Behavior")]
    public string[] ValidDescriptions
    {
        get
        {
            if (_validDescriptions == null)
                return new string[0];
            else
                return _validDescriptions;
        }
        set
        {
            _validDescriptions = value;
        }
    }
    public ArrayControl()
    {
        InitializeComponent();

        // Added 4 values using the properties editor
        Console.WriteLine("Count in Constructor: "   _validDescriptions.Length); // will be 0
    }

    private void ArrayControl_Load(object sender, EventArgs e)
    {
        Console.WriteLine("Count in Load: "   _validDescriptions.Length); // will be correct value
    }

    private void button1_Click(object sender, EventArgs e)
    {
        richTextBox1.Clear();

        foreach (string s in _validDescriptions)
        {
            richTextBox1.AppendText(s   "n"); // correctly populates text box.
        }
    } 
 

Ответ №2:

Просто дополнение к проблеме, которую вы нашли:
Значения, заданные в конструкторе, просто записываются в метод формы InitializeComponent() (формы, в которой размещен пользовательский элемент управления).
Вы можете посмотреть его там — и понять, почему он должен быть пустым в конструкторе элемента управления:

     private void InitializeComponent()
    {
        this.ucOne1 = new Test_Project.ucOne(); 
//↑↑ call to the UserControl's constructor
        this.SuspendLayout();
        // 
        // 
        // [... maybe other control inits]
        
        // ucOne1
        // 
        this.ucOne1.Location = new System.Drawing.Point(454, 301);
        this.ucOne1.Name = "ucOne1";
        this.ucOne1.Size = new System.Drawing.Size(416, 230);
        this.ucOne1.TabIndex = 1;
//↓↓ This is where the design-time-defined values are assigned:
        this.ucOne1.ValidDescriptions = new string[] {
    "Value1",
    "Value2",
    "Value3"};