在CaretPosition

我有一个WPF RichTextBox,带有一些用于文本样式的标准按钮。因为它们都应该以相同的方式工作,所以我将使用从现在开始使文本变为粗体的示例。 因此,我的目标是,用户可以单击粗体按钮,然后,无论此时插入符号的位置,他编写的文本都将以粗体显示。 必须在流程文档的内联中设置样式(因为我必须将包括样式在内的整个文本作为xaml字符串传输到另一个对象)。 在这一点上,我将发布我的代码。请注意,这是我创建的一个简单测试项目,旨在测试解决此特定问题的方法。

首先是xaml:

<Window x:Class="rtbTest.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:rtbTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"></RowDefinition>
            <RowDefinition Height="180"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
        </Grid.RowDefinitions>
        <DockPanel
            Grid.Row="0"
            LastChildFill="False">
            <StackPanel
            DockPanel.Dock="Left"    
            Orientation="Horizontal"
            Background="Gray">
                <TextBlock
                Foreground="#000000"
                FontWeight="Bold"
                VerticalAlignment="Center"
                Text="Font" 
             />
                <ComboBox 
                x:Name="fonts" 
                Margin="10,2,20,2"
                >
                </ComboBox>
                <TextBlock
                Foreground="#000000"
                FontWeight="Bold"
                VerticalAlignment="Center"
                Text="Size" 
             />
                <ComboBox 
                x:Name="fontsize" 
                Margin="10,2"
                >
                </ComboBox>
                <ToggleButton
                x:Name="bold"
                Content="B"
                Margin="0,5,2"
                Width="30">
                </ToggleButton>
                <ToggleButton
                x:Name="italic"
                Content="I"
                Margin="0,2"
                Width="30">
                </ToggleButton>
            </StackPanel>
        </DockPanel>

        <RichTextBox
            Name="textbox"
            Grid.Row="1" Grid.ColumnSpan="2" >
        </RichTextBox>

        <ScrollViewer
                Grid.Row="2"
                Grid.ColumnSpan="2"
                Margin="0,10,0"
                VerticalScrollBarVisibility="Auto">
            <StackPanel
                    Name="entrys"
                    Background="Black"
                    >
            </StackPanel>
        </ScrollViewer>
    </Grid>
</Window>

然后是代码:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using function = System.String;
namespace rtbTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.InitializeTextStyling();
        }

        private void InitializeTextStyling()
        {
            this.AddFonts();
            this.fonts.SelectedIndex = 1;
            this.textbox.IsInactiveSelectionHighlightEnabled = true;

            this.fonts.SelectionChanged += (s,a) =>
            {
                if (this.fonts.SelectedIndex != 0)
                {
                    if (this.textbox.Selection.IsEmpty)
                    {
                        this.textbox.Document.FontFamily = ((ComboBoxItem)this.fonts.SelectedItem).Content as FontFamily;
                    }
                    else
                    {
                        this.textbox.Selection.ApplyPropertyValue(TextBlock.FontFamilyProperty,((ComboBoxItem)this.fonts.SelectedItem).Content as FontFamily);
                    }
                }
            };


            for (double i = 10; i < 80; i = i + 1)
            {
                this.fontsize.Items.Add(i);
            }
            this.fontsize.SelectionChanged += (s,a) =>
            {
                if (this.textbox.Selection.IsEmpty)
                {
                    this.textbox.Document.FontSize = double.Parse(this.fontsize.SelectedItem.ToString());
                }
                else
                {
                    this.textbox.Selection.ApplyPropertyValue(TextBlock.FontSizeProperty,double.Parse(this.fontsize.SelectedItem.ToString()));
                }
            };
            this.fontsize.SelectedItem = 40.0;

            this.italic.Checked += (s,a) =>
            {
                if (this.textbox.Selection.IsEmpty)
                {
                    this.textbox.Document.FontStyle = FontStyles.Italic;
                }
                else
                {
                    this.textbox.Selection.ApplyPropertyValue(TextBlock.FontStyleProperty,FontStyles.Italic);
                }
            };

            this.italic.Unchecked += (s,a) =>
            {
                if (this.textbox.Selection.IsEmpty)
                {
                    this.textbox.Document.FontStyle = FontStyles.Normal;
                }
                else
                {
                    this.textbox.Selection.ApplyPropertyValue(TextBlock.FontStyleProperty,FontStyles.Normal);
                }
            };

            this.bold.Checked += (s,a) =>
            {
                this.textbox.Focus();
                if (this.textbox.Selection.IsEmpty)
                {
                    TextPointer tp = this.textbox.CaretPosition;
                    Run r = new Run("test",tp);
                    r.FontWeight = FontWeights.Bold;
                    this.textbox.CaretPosition = r.ElementStart;
                    r.Text = "";
                    string fds = XamlWriter.Save(this.textbox.Document);
                }
                else
                {
                    this.textbox.Selection.ApplyPropertyValue(TextBlock.FontWeightProperty,FontWeights.Heavy);
                }
            };

            this.bold.Unchecked += (s,a) =>
            {
                if (this.textbox.Selection.IsEmpty)
                {
                    this.textbox.Document.FontWeight = FontWeights.Normal;
                }
                else
                {
                    this.textbox.Selection.ApplyPropertyValue(TextBlock.FontWeightProperty,FontWeights.Normal);
                }
            };

            FlowDocument fd = new FlowDocument();
            fd.FontSize = double.Parse(this.fontsize.SelectedItem.ToString());
            fd.FontFamily = ((ComboBoxItem)this.fonts.SelectedItem).Content as FontFamily;
            fd.FontWeight = FontWeights.Normal;
            this.textbox.Document = fd;

        }

        private function GetStringFromStream(Stream stream)
        {
            using (StreamReader r = new StreamReader(stream))
            {
                return r.ReadToEnd();
            }
        }


        private void AddFonts()
        {
            //foreach (System.Drawing.FontFamily f in System.Drawing.FontFamily.Families)
            //{
            //    ComboBoxItem item = new ComboBoxItem();
            //    item.Content = new FontFamily(f.GetName(0));
            //    item.FontFamily = (FontFamily)item.Content;
            //    this.fonts.Items.Add(item);
            //}

            ComboBoxItem item = new ComboBoxItem();
            item.Content = new FontFamily("Arial");
            item.FontFamily = (FontFamily)item.Content;
            this.fonts.Items.Add(item);

            item = new ComboBoxItem();
            item.Content = new FontFamily("Corbel");
            item.FontFamily = (FontFamily)item.Content;
            this.fonts.Items.Add(item);

            item = new ComboBoxItem();
            item.Content = new FontFamily("Gabriola");
            item.FontFamily = (FontFamily)item.Content;
            this.fonts.Items.Add(item);

            item = new ComboBoxItem();
            item.Content = new FontFamily("MingLiU - ExtB");
            item.FontFamily = (FontFamily)item.Content;
            this.fonts.Items.Add(item);

            item = new ComboBoxItem();
            item.Content = new FontFamily("MV Boli");
            item.FontFamily = (FontFamily)item.Content;
            this.fonts.Items.Add(item);

            item = new ComboBoxItem();
            item.Content = new FontFamily("Noto Naskh Arabic UI");
            item.FontFamily = (FontFamily)item.Content;
            this.fonts.Items.Add(item);
        }
    }
}

此代码应足以立即进行测试。

现在,我的问题出在这部分:

this.bold.Checked += (s,a) =>
{
    this.textbox.Focus();
    if (this.textbox.Selection.IsEmpty)
    {
        TextPointer tp = this.textbox.CaretPosition;
        Run r = new Run("test",tp);
        r.FontWeight = FontWeights.Bold;
        this.textbox.CaretPosition = r.ElementStart;
        r.Text = "";
        string fds = XamlWriter.Save(this.textbox.Document);
    }
    else
    {
        this.textbox.Selection.ApplyPropertyValue(TextBlock.FontWeightProperty,FontWeights.Heavy);
    }
};

我实际上需要做的是插入一个Run,不带任何文本。但是,如果执行此操作,则会以<Run FontWeight="bold" />而不是<Run FontWeight="bold"></Run>.的方式插入运行 当我将构造函数与诸如“ test”之类的初始文本一起使用时,我可以获得第二个(我需要的),然后还可以将插入符号的位置设置为新创建的Run。但是然后我在我的实时出价中输入了我不想要的文本。我曾考虑过在构造函数中设置文本,然后再将文本设置为空,但是如果这样做,插入的Run会再次恢复为第一个版本,因此无法设置{{1}内的插入符号位置}。 有没有一种方法可以实现:在插入符位置插入一个新的空Run,文字样式为 bold ,并在此新行程内设置插入符位置?

请注意,run字符串仅被设置,因此在调试时我可以将流程文档视为XAML字符串。

jhfuuu 回答:在CaretPosition

暂时没有好的解决方案,如果你有好的解决方案,请发邮件至:iooj@foxmail.com
本文链接:https://www.f2er.com/3167007.html

大家都在问