Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Show LineNumbers from the RichTextBox in WPF

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.

like image 708
Karl_Schuhmann Avatar asked Mar 25 '13 08:03

Karl_Schuhmann


3 Answers

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.

like image 80
NSGaga-mostly-inactive Avatar answered Oct 17 '22 23:10

NSGaga-mostly-inactive


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
    }
}
like image 29
Chamika Sandamal Avatar answered Oct 17 '22 22:10

Chamika Sandamal


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.

like image 2
Ben Catterall Avatar answered Oct 17 '22 23:10

Ben Catterall