在WPF中显示RichTextBox的行号

时间:2013-03-25 08:59:19

标签: c# wpf richtextbox line-numbers

我找到了一个示例,如何在Windows窗体中显示RichTextBox的LineNumbers。 http://www.codeproject.com/Articles/38858/Line-Numbers-for-RichText-Control-in-C

WPF 中有人举一个例子吗?

编辑:

是否有人与AvalonEdit合作,因为他想在他的程序中显示LineNumbers,并可以通过我的问题帮助我。

5 个答案:

答案 0 :(得分:7)

我只想添加一个简单的解决方案......

AvalonDownload)已被提及,以下是如何用它做行:

<avalon:TextEditor ShowLineNumbers="True" Width="500" Height="500"
                    Text="some more test&#10; some more test&#10; some more test&#10; some more test&#10; some more test&#10; some more test&#10; some more test&#10; some more test&#10; some more test&#10; ">
</avalon:TextEditor>  

这是一个非常强大的编辑器 - 我一直在用它和生产(自定义语言编译器等)做很多事情。它是免费的,所以它有它的'怪癖',但它允许你做你需要的任何东西。我不确定你在谈论哪种格式的文本 - 但是你需要的任何东西都可以完成,而且代码行数不多,如果你知道如何注入,你可以添加自己的发生器,变换器,几乎任何视觉效果,代码完整性等等 - 我对它没有任何既得利益:)

修改

用于语法高亮的小样本:

<avalon:TextEditor 
  ShowLineNumbers="True" 
  SyntaxHighlighting="C#" Width="500" Height="500"
  Text="void Test(int id, string name)&#10;{&#10;&#09;name = name + id.ToString();}" />  

据我所知,从代码中支持"XmlDoc", "C#", "JavaScript", "HTML", "ASP/XHTML", "Boo", "Coco", "CSS", "C+", "Java", "Patch", "PHP", "TeX", "VBNET", "XML"

如果您想要实现自己的自定义syntax highlighting(Avalon编辑器具有高度可扩展性 - 有关详细信息,请参阅code project article mentioned)...

您需要定义自己的IHighlightingDefinition,然后在代码中使用HighlightingManager进行注册 - 然后再添加一些内容来补充。但这本身就是一个很长的故事。

答案 1 :(得分:6)

只需为TextBox使用自定义模板;以下答案可能会对您有所帮助:

Visible line count of a TextBlock

<强>更新


更改答案以获得预期的OP。

<Style x:Key="Local_TextBox" TargetType="{x:Type TextBoxBase}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TextBoxBase}">
                <Border Name="Border" Background="{TemplateBinding Background}">
                    <ScrollViewer x:Name="PART_ContentHost" />
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

设计,

<DockPanel>
    <TextBlock Text="{Binding ElementName=uiTextBox, Path=(local:AttachedProperties.BindableLineCount)}"/>
    <TextBox x:Name="uiTextBox" TextWrapping="Wrap" local:AttachedProperties.HasBindableLineCount="True"
            AcceptsReturn="True" Text="{Binding LongText}" Style="{StaticResource Local_TextBox}" />
</DockPanel>

附属物,

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;

namespace Cmsn.Software.Tutorials.numberedTextBox
{
    public class AttachedProperties
    {
        #region BindableLineCount AttachedProperty
        public static string GetBindableLineCount(DependencyObject obj)
        {
            return (string)obj.GetValue(BindableLineCountProperty);
        }

        public static void SetBindableLineCount(DependencyObject obj, string value)
        {
            obj.SetValue(BindableLineCountProperty, value);
        }

        // Using a DependencyProperty as the backing store for BindableLineCount.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty BindableLineCountProperty =
            DependencyProperty.RegisterAttached(
            "BindableLineCount",
            typeof(string),
            typeof(AttachedProperties),
            new UIPropertyMetadata("1"));

        #endregion // BindableLineCount AttachedProperty

        #region HasBindableLineCount AttachedProperty
        public static bool GetHasBindableLineCount(DependencyObject obj)
        {
            return (bool)obj.GetValue(HasBindableLineCountProperty);
        }

        public static void SetHasBindableLineCount(DependencyObject obj, bool value)
        {
            obj.SetValue(HasBindableLineCountProperty, value);
        }

        // Using a DependencyProperty as the backing store for HasBindableLineCount.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty HasBindableLineCountProperty =
            DependencyProperty.RegisterAttached(
            "HasBindableLineCount",
            typeof(bool),
            typeof(AttachedProperties),
            new UIPropertyMetadata(
                false,
                new PropertyChangedCallback(OnHasBindableLineCountChanged)));

        private static void OnHasBindableLineCountChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            var textBox = (TextBox)o;
            if ((e.NewValue as bool?) == true)
            {
                textBox.SizeChanged += new SizeChangedEventHandler(box_SizeChanged);
                textBox.SetValue(BindableLineCountProperty, textBox.LineCount.ToString());
            }
            else
            {
                textBox.SizeChanged -= new SizeChangedEventHandler(box_SizeChanged);
            }
        }

        static void box_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            var textBox = (TextBox)sender;
            string x = string.Empty;
            for (int i = 0; i < textBox.LineCount; i++)
            {
                x += i + 1 + "\n";
            }
            textBox.SetValue(BindableLineCountProperty, x);
        }
        #endregion // HasBindableLineCount AttachedProperty
    }
}

答案 2 :(得分:3)

ScintillaNET是一个很好的组件。它是Scintilla的.NET版本,它是Notepad++编辑器(以及其他编辑器)中的关键组件。我不知道它与AvalonEdit的比较,但我发现在我的代码中实现相当容易,并且它具有您需要的功能(以及更多)。

在您installed the component并将其添加到表单后,您可以show line numbers转到控件的属性并设置边距&gt; Margin0&gt;宽度。您也可以通过编程方式进行设置:

scintilla1.Margins.Margin0.Width = 20;

如果您打算采用这条路线,您可能会发现ScintillaNet documentation很有用 - 我发现它在我开始时非常有用。

答案 3 :(得分:1)

最好的example you can find is in AvalonEdit。还有很多只是行编号,但你可以研究它是如何完成的,代码非常清晰。关注我们所谈论的内容可能是this CodeProject article

答案 4 :(得分:0)

这里有一个很好的CodeProject article,它显示了在TextBox控件中实现行号和一些其他漂亮的代码编辑功能的详细方法。如果您不关心它是如何构建的,只需下载示例文件并使用包含已编译控件的包含的dll。