Изменение расширенного текста RichTextBox в конструкторе не работает - PullRequest
0 голосов
/ 11 февраля 2019

У меня есть следующий класс:

public partial class RichTextBoxEx : RichTextBox
{
    public RichTextBoxEx()
    {
        InitializeComponent();
        Text = "Some Text";
    }
}

Однако, когда я помещаю его в форму и запускаю программу, RichTextBox становится пустым.В чем проблема и как я могу это исправить?

enter image description here

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

Ответы [ 4 ]

0 голосов
/ 12 февраля 2019

Значения свойств, которые вы устанавливаете в конструкторе элемента управления, обычно соблюдаются.Но для свойства Text дело обстоит несколько иначе.Я уже описал это в другом ответе .Фактически это конструктор элемента управления, который устанавливает свойство Text элемента управления в InitializeNewComponent.

Как вариант, вы можете создать и зарегистрировать новый конструктор элементов управления, переопределить InitializeNewComponent и захватить значение свойства Text перед вызовом метода base.InitializeNewComponent.Затем после вызова базового метода снова установите для свойства Text значение по умолчанию.

using System.ComponentModel;
using System.Windows.Forms;
using System.Windows.Forms.Design;
[Designer(typeof(RichTextBoxExDesigner))]
public class RichTextBoxEx : RichTextBox
{
    public RichTextBoxEx ()
    {
        Text = "Some Text";
    }
}
public class RichTextBoxExDesigner : ControlDesigner
{
    public override void InitializeNewComponent(System.Collections.IDictionary defaultValues)
    {
        var txt = Control.Text;
        base.InitializeNewComponent(defaultValues);
        Control.Text = txt;
    }
}

Примечание: Не забудьте добавить ссылку на System.Design сборку.

Примечание: Не для Text свойства, но для других подобных случаев, когда вы видите, что значение свойства не учитывается при установке в конструкторе, другой подозреваемый - CreateComponentsCore из ToolboxItem изконтроль.Для пример для AutoSize свойство Label.

0 голосов
/ 11 февраля 2019

Свойство Text сбрасывается после InitializeComponent формы.

Когда вы посмотрите на файл Designer.cs Form, вы должны найти строку, подобную следующей:

private void InitializeComponent()
{
    this.richTextBoxEx1 = new WindowsFormsApp1.RichTextBoxEx(); //<-- RichTextBoxEx gets initialized and ITS constructor and InitializeComponent gets called
    this.SuspendLayout();
    // 
    // richTextBoxEx1
    // 
    this.richTextBoxEx1.Location = new System.Drawing.Point(322, 106);
    this.richTextBoxEx1.Name = "richTextBoxEx1";
    this.richTextBoxEx1.Size = new System.Drawing.Size(100, 96);
    this.richTextBoxEx1.TabIndex = 0;
    this.richTextBoxEx1.Text = ""; //<-- Text Property gets reseted
    // 
    // Form1
    // 
    this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
    this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
    this.ClientSize = new System.Drawing.Size(800, 450);
    this.Controls.Add(this.richTextBoxEx1);
    this.Name = "Form1";
    this.Text = "Form1";
    this.ResumeLayout(false);

}

Вы можете преодолеть это, переопределив OnCreateControl

Так что измените свой контроль следующим образом:

public class RichTextBoxEx : RichTextBox
{
    protected override void OnCreateControl()
    {
        Text = "Hello World";
        base.OnCreateControl();
    }
}

Если OnCreateControl вызывается несколько раз -хотя его определение в состояниях MSDN:

Метод OnCreateControl вызывается при первом создании элемента управления

Затем вы можете принудительно вызвать его один раз, используялогическое, чтобы отслеживать, если он был вызван или нет, поэтому попробуйте следующее:

public class RichTextBoxEx : RichTextBox
{
    private bool _initialized = false;
    protected override void OnCreateControl()
    {
        if (!_initialized)
        {
            _initialized = true;
            Text = "Hello World";
        }

        base.OnCreateControl();
    }
}
0 голосов
/ 11 февраля 2019

Мне не было ясно, как вы создавали экземпляр RichTextBox, поэтому это может или не может быть полезным ...

Когда вы написали, что поместили элемент управления RichTextBox "над формой", яПредполагается, что это означает, что вы перетащите элемент управления из панели инструментов на поверхность конструктора.Если бы вы сделали это, вы бы получили экземпляр RichTextBox, а не RichTextBoxEx.

Чтобы получить экземпляр RichTextBoxEx, вы можете скомпилировать его в DLL и добавить в свою панель инструментов.

Альтернативный подход, дающий вам больший контроль над созданием / инициализацией объекта, заключается в том, чтобы создать его экземпляр в коде и таким образом добавить в форму.В конструкторе формы вы можете сделать это:

var richTextBoxEx = new RichTextBoxEx();
// set your richTextBoxEx properties here
richTextBoxEx.Top = 100;
richTextBoxEx.Left = 100;

this.Controls.Add(richTextBoxEx);

Хотя вы можете установить свойства, как показано выше, вы также можете сделать это (как и вы) в конструкторе элемента управления подкласса.

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

0 голосов
/ 11 февраля 2019

Я не уверен, как вы реализовали свой класс.Когда я попытался воспроизвести вашу проблему, я создал класс, а затем добавил с помощью System.Windows.Forms и создал класс.Как и вы, но я не получил ни открытый класс частичного класса, ни метод InitializeComponent (), вызываемый в моем конструкторе (который мне пришлось написать).

Код:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace FormTester
{
    public class RichTextboxEx : RichTextBox
    {
        public RichTextboxEx() : base()
        {
            Text = "Some Text";
        }
    }
}

Я считаю, что это сработало так, как вы и планировали.Попробуйте.

...