Show LineNumbers from the RichTextBox in WPF

2019-02-07 06:20发布

I found an example, how to show the LineNumbers from a RichTextBox in Windows Forms. http://www.codeproject.com/Articles/38858/Line-Numbers-for-RichText-Control-in-C

Have somebody an example for it in WPF?

Edit:

Does someone have work with AvalonEdit, because he wanted to show LineNumbers in his Programm and can help me by my Problem.

5条回答
我只想做你的唯一
2楼-- · 2019-02-07 06:20

I thought just to add a simple solution...

Avalon (Download) has been mentioned, here is how to do row lines with it:

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

It's a very powerful editor - and I've been doing a lot with it and in production (custom language compilers etc.). It's free so it has its 'quirks' but it's allowing you to do pretty much anything you need. I'm not sure which formatted text are you talking about - but anything you need can be done, and in not too many lines of code, if you know how, where to inject (you can add your own generators, transformers, pretty much any visuals, code completition etc. - and I have no vested interest in it:)

Edit

Small sample for syntax highlighting:

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

Supported is "XmlDoc", "C#", "JavaScript", "HTML", "ASP/XHTML", "Boo", "Coco", "CSS", "C+", "Java", "Patch", "PHP", "TeX", "VBNET", "XML" as far as I can tell from the code.

If you'd like to implement your own custom syntax highlighting (Avalon editor is highly extendable - for details see that code project article mentioned)...

You'd need to define your own IHighlightingDefinition, then register that with the HighlightingManager from the code - and then add some more things to complement. But that's a long story on its own.

查看更多
Luminary・发光体
3楼-- · 2019-02-07 06:22

ScintillaNET is a good component to try. It's the .NET version of Scintilla which is a key component in the Notepad++ editor (among others). I don't know how it compares to AvalonEdit, but I found it fairly easy to implement in my code and it has the feature you require (and many more).

Once you've installed the component and added it to your form, you can show line numbers by going to the properties of the control and setting Margins>Margin0>Width. You can also set this programmatically:

scintilla1.Margins.Margin0.Width = 20;

You might find the ScintillaNet documentation useful if you plan to take this route - I found it really helpful when I started.

查看更多
放荡不羁爱自由
4楼-- · 2019-02-07 06:27

Here's a nice CodeProject article that shows a detailed approach to implementing line numbers and a handful of other nice code editing features in a TextBox control. If you don't care about how it's built, just download the sample file and use the included dll that contains the compiled control.

查看更多
我想做一个坏孩纸
5楼-- · 2019-02-07 06:31

Just use a custom template for your TextBox; the following answer may help you:

Visible line count of a TextBlock

Update


Changing the answer to get works as OP expected.

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

Designer,

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

Attached property,

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
    }
}
查看更多
趁早两清
6楼-- · 2019-02-07 06:33

The best example you can find is in AvalonEdit. There is lot more anyway that just line numbering, but you can study how it is done, code is very clear. A staring point to see what we are talking about can be this CodeProject article.

查看更多
登录 后发表回答