简体   繁体   English

在构造函数中向RichTextBox添加文本

[英]Adding text to a RichTextBox in the constructor

I'm creating a special kind of textbox, by inheriting from RichTextBox. 我通过继承RichTextBox来创建一种特殊的文本框。 I would like to be able to set the initial text in the box, which I thought I could do in the constructor as follows: 我希望能够在框中设置初始文本,我认为我可以在构造函数中进行如下操作:

class SpecialTextBox : RichTextBox
{
    public SpecialTextBox()
    {
        BackColor = System.Drawing.Color.ForestGreen;
        AppendText("Initial Text...");
        Text += "and some more initial text.";
    }
}

The constructor in the above code sets the background colour, but the initial text does not appear. 上面的代码中的构造函数设置背景色,但不显示初始文本。 My question is, why doesn't the text appear, and how can I achieve this? 我的问题是,为什么文本不出现?如何实现呢? I might want the initial text to be configurable (perhaps passed in to the constructor). 我可能希望初始文本是可配置的(也许传递给构造函数)。

I can successfully add text later, by calling 我可以稍后通过调用来成功添加文本

specialTextBox1.AppendText("This text will appear.")

Why doesn't the constructor text appear? 为什么没有显示构造函数文本?

Windows is overwriting the text inside the FlowDocument when it loads the XAML for it. Windows在为其加载XAML时将覆盖FlowDocument的文本。 This happens after the constructor for the RichTextBox is called. 在调用RichTextBox的构造函数之后,会发生这种情况。

Try adding the text a bit later, for instance in the Loaded event: 稍后再尝试添加文本,例如在Loaded事件中:

public class SpecialTextBox : RichTextBox
{
    public SpecialTextBox()
    {
        Background = new SolidColorBrush(System.Windows.Media.Color.FromArgb(
            System.Drawing.Color.ForestGreen.A,
            System.Drawing.Color.ForestGreen.R,
            System.Drawing.Color.ForestGreen.G,
            System.Drawing.Color.ForestGreen.B));

        this.Loaded += new RoutedEventHandler(SpecialTextBox_Loaded);
    }

    void SpecialTextBox_Loaded(object sender, RoutedEventArgs e)
    {
        AppendText("Initial Text...");
    }
}

Update: you might only want to do this if the XAML that got loaded has no initial text: 更新:您可能只想在加载的XAML没有初始文本的情况下执行此操作:

    void SpecialTextBox_Loaded(object sender, RoutedEventArgs e)
    {
        var range = new TextRange(Document.ContentStart, Document.ContentEnd);
        if (range.IsEmpty)
        {
            AppendText("Initial Text...");
        }
    }

Update 更新资料

OK, WinForms. 好的,WinForms。 WinForms sets the initial text in the c# code generated by the designer. WinForms在设计器生成的c#代码中设置初始文本。 You should see something like this: 您应该会看到以下内容:

        this.richTextBox1 = new WinformsRichTextBox.SpecialTextBox();
        this.SuspendLayout();
        // 
        // richTextBox1
        // 
        this.richTextBox1.Location = new System.Drawing.Point(12, 2);
        this.richTextBox1.Name = "richTextBox1";
        this.richTextBox1.Size = new System.Drawing.Size(1233, 507);
        this.richTextBox1.TabIndex = 0;
        this.richTextBox1.Text = "";

That last line is what defeats your constructor. 最后一行是击败您的构造函数的原因。 You can hack around this by overriding the Text method and rejecting the initial setting: 您可以通过重写Text方法并拒绝初始设置来解决此问题:

public class SpecialTextBox : RichTextBox
{
    bool suppressInitialSetText = true;

    public SpecialTextBox()
    {
        BackColor = System.Drawing.Color.ForestGreen;
        AppendText("Initial Text...");

        this.VisibleChanged += new EventHandler(SpecialTextBox_VisibleChanged);
    }

    void SpecialTextBox_VisibleChanged(object sender, EventArgs e)
    {
        // Just in case, once the control becomes visible disable the kludge.
        if (Visible)
            suppressInitialSetText = false;
    }

    public override string Text
    {
        get
        {
            return base.Text;
        }
        set
        {
            if (!suppressInitialSetText || !string.IsNullOrEmpty(value) || Parent != null)
                base.Text = value;
            suppressInitialSetText = false;
        }
    }
}

In this scheme the "Initial Text..." only appears if the "Text" line in the forms designer is empty. 在此方案中,仅当表单设计器中的“文本”行为空时,才会显示“初始文本...”。 Otherwise the text in the forms designer overrides the text in the constructor. 否则,表单设计器中的文本将覆盖构造函数中的文本。

Seems sort of fragile and kludgy though. 虽然看起来有些脆弱和笨拙。

So "Initial Text..." does not appear, but "and some more initial text." 因此,不会出现“初始文本...”,而是“还有更多初始文本”。 does? 有吗 At first glance, it would appear that you're clobbering the first string by assigning the second...except that you're using the += operator and not =. 乍一看,似乎是通过分配第二个字符串来破坏第一个字符串...除了使用+ =运算符而不是=之外。

I've never used the AppendText method, but I can offer some guesses: 我从未使用过AppendText方法,但是我可以提供一些猜测:

  1. Maybe AppendText doesn't work if the Text property is blank? 如果Text属性为空,也许AppendText不起作用? So the result of calling it here is nothing? 那么在这里调用它的结果是什么呢?
  2. Maybe AppendText changes the display, but not the Text property? 也许AppendText更改显示,但不更改Text属性? So Text is still blank when you add the second string, which then updates the display to show Text? 所以当您添加第二个字符串时,Text仍为空白,然后更新显示以显示Text?

Try commenting out the Text += ... line and see if it displays the first one. 尝试注释掉Text + = ...行,看看它是否显示第一行。 Also put a breakpoint just before and after AppendText to see what happens to Text. 还要在AppendText前后放置一个断点,以查看Text发生了什么。

In the constructor you can set the initial text as 在构造函数中,您可以将初始文本设置为

base.Text = "Text what ever you want"; base.Text =“根据需要输入文字”;

I added your class to a Windows Forms project and added it to a form in the Load event. 我将您的类添加到Windows Forms项目中,并将其添加到Load事件中的表单中。 It seems to work as expected. 它似乎按预期工作。 How are you added the SpecialTextBox to your form? 如何将SpecialTextBox添加到窗体?

This is what my Load event looks like. 这就是我的Load事件的样子。

    private void Form1_Load(object sender, EventArgs e)
    {
        SpecialTextBox stb = new SpecialTextBox();
        this.Controls.Add(stb);
        stb.Visible = true;
    }

This is what the class looks like. 这是该类的样子。

    class SpecialTextBox : System.Windows.Forms.RichTextBox
    {
        public SpecialTextBox()
        {
            BackColor = System.Drawing.Color.ForestGreen;
            AppendText("Initial Text...");
            Text += "and some more initial text.";
        }
    }

It's caused by the designer-generated code in the .designer.cs of your form containing your SpecialTextBox . 这是由包含SpecialTextBox的表单的.designer.cs中的设计器生成的代码引起的。

To customize that code, you can define a custom ControlDesigner and override InitializeNewComponent as followings: 要自定义该代码,可以定义一个自定义ControlDesigner并重写InitializeNewComponent ,如下所示:

internal class SpecialTextBoxDesigner
 : System.Windows.Forms.Design.ControlDesigner
{
    public override void InitializeNewComponent(
        System.Collections.IDictionary defaultValues)
    {
        base.InitializeNewComponent(defaultValues);
        this.Control.Text = "Initial Text...";
    }
}

Then apply that by DesignerAttribute to your SpecialTextBox : 然后通过DesignerAttribute将其应用于您的SpecialTextBox

[System.ComponentModel.Designer(typeof(SpecialTextBoxDesigner))]
public partial class SpecialTextBox : RichTextBox

You need to add a reference to System.Designer into your project beforehand. 您需要事先在项目中添加对System.Designer的引用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM