【问题标题】:How to override an inherited property from RichTextBox?如何覆盖从 RichTextBox 继承的属性?
【发布时间】:2010-08-25 12:54:14
【问题描述】:

我用 C# 编写了一个继承自 RichTextBox 的自定义控件。此控件的目的是包含所有改进和更改,例如修改的行号和让控件仅在需要时重新绘制自身。

昨天,我在访问此控件的 Lines 属性时注意到内存峰值(通常是 OOM 异常)(有时控件中有 600,000 多行)。我编写了不再涉及它的变通办法,但我仍然想完全删除它,以便将来使用我的控件的人不要使用它。

Lines 属性是 System.Windows.Forms.TextBoxBase.Lines。理想情况下,我希望这个属性的 string[] 永远不会被触及;当我在控件中加载文本时,我不希望控件执行任何操作来填充此行属性(因为它完全没有意义,并且会消耗一些时间和资源)。

有人有什么想法吗?

编辑:我试过了

公共覆盖字符串 [] 行 { 得到{返回空; } 放 { ; } // 没做什么 }

但是 VS 说“不能覆盖继承的成员 System.Windows.Forms.TextBoxBase.Lines.get 因为它没有被标记为虚拟、抽象或覆盖。

所以看起来我无法覆盖或删除它。我认为 RichTextBox 正在设置属性,因为它在更改文本后被填充。有没有办法让我捕获和处理该消息?

【问题讨论】:

    标签: c# .net richtextbox overriding


    【解决方案1】:

    哎呀,它只会让一个体面的程序员减慢不超过 5 分钟:

    string[] lines = ((RichTextBox)myEditor1).Lines;
    

    它会吹得一样猛烈。试图阻止使用无论如何都可以使用的类没有多大意义。 Lines 属性应该对使用您的编辑器的任何人都有用,它涵盖了能够检索已编辑文本的非常基本的需求。不要把婴儿和洗澡水一起扔掉。

    这里真正的问题是 RTB 使用了太多非托管内存来存储文本,剩下的垃圾收集堆所剩无几。一旦您将数千条线注入其中,它也会变得非常慢。任何组件都不应被允许占用所有可用内存的一半。限制允许编辑的行数或使用更好的编辑器,例如 ScintillaNET。

    做一个务实的程序员也很重要。除了不必要地隐藏财产。一个文本框中的 600,000 行是一个巨大的数字。圣经中有 3/4 百万字,您在文本框中显示 6 份圣经。没有理智的人会读到它,他们只会非常不喜欢你的程序。不仅因为它无法有效使用,还因为它是一个崩溃桶。

    【讨论】:

    • +1 删除了我赞成的答案,我认为这是一个更好的答案。
    • "Lines 属性应该对使用您的编辑器的任何人都有用,它涵盖了检索已编辑文本的基本需求。"好吧,通常用户不会编辑文本。该控件主要用于查看具有一堆小功能(格式化某些文本等)。每当程序需要当前行时,我都会使用一个从 SelectionStart 开始的临时变量,然后返回到前一个换行符。然后我连接字符串直到下一个换行符。这比调用 editor.Lines[GetLineFromCharIndex(editor.SelectionStart)] 更快。
    • 另外,当我做我的解决方法时,内存使用量并没有飙升。几个月前,我花了几个星期试图找到一个更好的编辑器,但他们都有很多问题。 ScintillaNET 的唯一问题是更改文本时的内存泄漏(导致 OOM)。虽然这个项目已经完成并且被认为非常令人满意,但我仍然想找到改进它的方法:)
    • 如果项目完成了,那么几乎没有人会尝试使用 Lines 属性?
    • 控件将被重用。并且看起来 TextBoxBase.Lines 属性是由 RichTextBox 在加载时设置的,它正在使用一些资源。这也是我想删除它的另一个原因。
    【解决方案2】:

    您是否尝试过隐藏该属性?

    public new string[] Lines
    {
       get { throw new Exception("Not supported"); }
       set { throw new Exception("Not supported"); }
    }
    

    【讨论】: