在WPF中创建一个带行号的RichTextBox
可以通过自定义控件或使用第三方库来实现。以下是一种常见的方法,使用自定义控件结合RichTextBox
和ListBox
来显示行号。
RichTextBox
和ListBox
。RichTextBox
和行号ListBox
的滚动位置一致。RichTextBox
的内容变化调整行号显示。以下是一个简单的示例,展示如何实现带行号的RichTextBox
。
<UserControl x:Class="LineNumberRichTextBox.LineNumberRichTextBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- 行号ListBox -->
<ListBox x:Name="lineNumberBox"
Grid.Column="0"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
SelectionMode="None"
IsHitTestVisible="False"
Background="LightGray"/>
<!-- RichTextBox -->
<RichTextBox x:Name="richTextBox"
Grid.Column="1"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
TextChanged="RichTextBox_TextChanged"/>
</Grid>
</UserControl>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
namespace LineNumberRichTextBox
{
public partial class LineNumberRichTextBox : UserControl
{
public LineNumberRichTextBox()
{
InitializeComponent();
UpdateLineNumbers();
}
private void UpdateLineNumbers()
{
// 清空行号ListBox
lineNumberBox.Items.Clear();
// 获取文档块
var blocks = richTextBox.Document.Blocks;
int lineCount = blocks.Count;
for (int i = 1; i <= lineCount; i++)
{
lineNumberBox.Items.Add(i.ToString());
}
}
private void RichTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
UpdateLineNumbers();
}
protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
{
base.OnRenderSizeChanged(sizeInfo);
// 同步滚动
SyncScroll();
}
private void SyncScroll()
{
// 获取RichTextBox的垂直滚动位置
var richTextBoxScrollViewer = GetScrollViewer(richTextBox);
if (richTextBoxScrollViewer != null)
{
double verticalOffset = richTextBoxScrollViewer.VerticalOffset;
lineNumberBox.ScrollIntoView(lineNumberBox.Items[(int)verticalOffset]);
}
}
private ScrollViewer GetScrollViewer(DependencyObject o)
{
if (o is ScrollViewer)
return (ScrollViewer)o;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(o); i++)
{
var child = VisualTreeHelper.GetChild(o, i);
var result = GetScrollViewer(child);
if (result != null)
return result;
}
return null;
}
}
}
在你的主窗口或页面中使用这个自定义的LineNumberRichTextBox
控件:
<Window x:Class="YourNamespace.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:LineNumberRichTextBox"
Title="MainWindow" Height="450" Width="800">
<Grid>
<local:LineNumberRichTextBox/>
</Grid>
</Window>
ListBox
用于显示行号,根据RichTextBox
中的文本块数量动态生成行号。RichTextBox
的滚动位置,并相应地滚动ListBox
,实现行号与文本内容的同步滚动。RichTextBox
内容发生变化(如输入、粘贴)时,调用UpdateLineNumbers
方法更新行号。通过以上步骤,你可以创建一个带行号的RichTextBox
,提升用户在编辑长文档时的体验。
领取专属 10元无门槛券
手把手带您无忧上云