显示 WPF RichtextBox 的格式标记

display formatting marks for WPF RichtextBox

看来我之前的问题没说清楚。所以我重新讨论它:我有一个 richtextbox(WPF,C#),我希望当用户在 运行 时间在其中键入文本时,格式标记会动态显示。也就是说,像 MSWord 一样,用点代替空格,用 -> 代替制表,用相应的标记代替段尾。在此,我希望得到的:

您可以使用虚拟机在此庄园中进行格式化,也可以使用 IValueConverter

例如

XAML

<Window x:Class="WPF_ScratchPad.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WPF_ScratchPad"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <local:TextFormatter x:Key="TextFormatter"/>
    </Window.Resources>
    <Window.DataContext>
        <local:VM/>
    </Window.DataContext>
    <StackPanel>
        <GroupBox Header="Stored Text">
            <TextBox MaxLines="50" MinLines="5" Text="{Binding Text}" AcceptsReturn="True" AcceptsTab="True" TextWrapping="Wrap" />
        </GroupBox>
        <GroupBox Header="Converter Formatter">
            <TextBox MaxLines="50" MinLines="5" Text="{Binding Text, Converter={StaticResource TextFormatter}}" AcceptsReturn="True" AcceptsTab="True" TextWrapping="Wrap" />
        </GroupBox>

        <CheckBox IsChecked="{Binding ShowForattnig}">Show Format Marks</CheckBox>
        <GroupBox Header="VM Formatted">
            <TextBox MaxLines="50" MinLines="5" Text="{Binding DisplayText}" AcceptsReturn="True" AcceptsTab="True" TextWrapping="Wrap" />
        </GroupBox>
    </StackPanel>
</Window>

查看模型

public class VM:BindableBase
{
    public TextFormatter Formmatter { get; } = new TextFormatter();
    private string _Text;

    public string Text
    {
        get { return _Text; }
        set
        {
            if(SetProperty(ref _Text, value))
            {
                RaisePropertyChanged(nameof(DisplayText));
            }
        }
    }


    public string DisplayText
    {
        get
        {
            if (ShowForattnig)
                return Formmatter.Convert(Text);
            else
                return Text;
        }
        set
        {
            if (ShowForattnig)
                Text = Formmatter.ConvertBack(value);
            else
                Text = value;

        }
    }


    private bool _ShowForattnig;

    public bool ShowForattnig
    {
        get { return  _ShowForattnig; }
        set
        {
            if(SetProperty(ref _ShowForattnig, value))
            {
                RaisePropertyChanged(nameof(Text));
                RaisePropertyChanged(nameof(DisplayText));
            }
        }
    }

}

注意:反正我在做值转换器时我已经引用了它,但你可以直接将代码放入

数值转换器

public class TextFormatter : IValueConverter
{
    public Dictionary<string, string> Replacements { get; } = new Dictionary<string, string>()
    {
        {Environment.NewLine,$"¶{Environment.NewLine}" },
        {" ","•" }
    };
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        => Convert(value?.ToString());

    public string Convert(string value)
    {
        StringBuilder format = new StringBuilder( value);
        foreach (var item in Replacements)
        {
            format = format.Replace(item.Key, item.Value);
        }
        return format.ToString();
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        => ConvertBack(value?.ToString());

    public string ConvertBack(string value)
    {
        StringBuilder format = new StringBuilder(value);
        foreach (var item in Replacements)
        {
            format = format.Replace(item.Value, item.Key);
        }
        return format.ToString();
    }
}

注意:此处使用 Prism 样板