在构造函数中更改扩展的RichTextBox文本不起作用

问题描述 投票:2回答:4

我有以下课程:

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

但是,当我将它放在表单上并运行程序时,RichTextBox为空。有什么问题,我该如何解决?

enter image description here

我假设这里有一些基本的东西,但是我无法弄清楚是什么,而且我没有找到任何关于此的信息。

c# .net winforms richtextbox windows-forms-designer
4个回答
2
投票

通常会遵循您在控件的构造函数中设置的属性值。但对于Text财产,案件有点不同。我已经在另一个answer中描述了它。事实上,它是控制设计师在Text中设置控件的InitializeNewComponent属性。

作为一个选项,您可以创建并注册一个新的控件设计器,覆盖InitializeNewComponent并在调用Text方法之前捕获base.InitializeNewComponent属性值。然后在调用base方法之后,再次将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属性,但是对于其他类似的情况,当您在构造函数中设置时,您看到属性值不受尊重,另一个嫌疑人是控件的CreateComponentsCoreToolboxItem。对于example AutoSizeLabel属性。


1
投票

Text财产被重置在表格的InitializeComponent上。

当您查看Designer.csForm文件时,您应该找到如下所示的行:

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
投票

我不确定你是如何实施你的课程的。当我尝试重现您的问题时,我创建了一个类,然后添加了使用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";
        }
    }
}

我相信这有效。试试看。


0
投票

我不清楚你是如何实例化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);

虽然您可以如上所示设置属性,但您也可以在子类控件的构造函数中执行此操作(就像您一样)。

我希望这提供了另一种方法来解决这个问题。

© www.soinside.com 2019 - 2024. All rights reserved.