繁体   English   中英

使用 WPF 在 DataGrid 的 RichTextBox 中使文本的特定部分加粗

[英]Making specific part of Text bold in RichTextBox in a DataGrid using WPF

我正在制作一个 C# WPF 应用程序,目前有一个 DataGrid,其中包含各种元素,包括 RichTextBox,以便用户可以编辑文本。 但是,我还想提供将 RichTextBox 中包含的文本的特定部分设为粗体的选项。 这应该通过选择 TextBox 中的部分文本并按下按钮来完成,这将使所选文本变为粗体。

因此,当按下按钮时,突出显示的“Lorem ipsum dolor sit amet”将变为粗体。

我的 XAML 是这样设置的:

<DataGrid Grid.Row="1" AutoGenerateColumns="False" Name="DescriptionGrid"
      RowHeaderWidth="15"
      ItemsSource="{Binding Descriptions}"
      VirtualizingPanel.IsVirtualizing="False">
<DataGrid.Columns>
    <DataGridTemplateColumn Header="Description" Width="300">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <RichTextBox Width="Auto" AcceptsReturn="True">
                    <FlowDocument>
                        <Paragraph>
                            <Run Text="{Binding desc, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
                        </Paragraph>
                    </FlowDocument>
                </RichTextBox>
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
</DataGrid.Columns>

我没有包括每一列,但它应该让我了解我正在处理的内容。

到目前为止,我已经设法获得突出显示的文本。 然后我尝试在所选文本周围添加各种粗体标记,但是这些标记只显示在文本框中。

但是,我还想提供将 RichTextBox 中包含的文本的特定部分设为粗体的选项。 这应该通过选择 TextBox 中的部分文本并按下按钮来完成,这将使所选文本变为粗体

有几种方法可以实现这一点。 目前看来您正在使用带绑定的mvvm ,这是使用wpf时的首选方式。 考虑到这一点,您可以创建一个新的 class 来继承RichTextBox并实现您需要的行为。

这是一个示例 class,它可以满足您的需要:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;

namespace ChangeFontSelectionGridWPF
{
    public class RichTextSelection : RichTextBox
    {
        public static readonly DependencyProperty DoBoldSelectionProperty = DependencyProperty.Register(
                                                                                                    "DoBoldSelection", typeof(bool),
                                                                                                    typeof(RichTextSelection),
                                                                                                    new FrameworkPropertyMetadata(false, new PropertyChangedCallback(OnBoldSelectionChanged))
                                                                                                    );

        public bool DoBoldSelection
        {
            get => (bool)GetValue(DoBoldSelectionProperty);
            set => SetValue(DoBoldSelectionProperty, value);
        }

        public RichTextSelection()
            : base()
        {
        }

        private static void OnBoldSelectionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            RichTextSelection rchTextSel = (RichTextSelection)d;
            if (rchTextSel.Selection != null)
                rchTextSel.Selection.ApplyPropertyValue(TextElement.FontWeightProperty, FontWeights.Bold);
        }
    }
}

重新编译后,您可以将其添加为该列的DataTemplate ,例如:

<DataTemplate>
             <local:RichTextSelection Width="Auto"
                 AcceptsReturn="True"
                 DoBoldSelection="{Binding AllowBoldHighlight}"
                                                     >
                                <FlowDocument>
                                    <Paragraph>
                                        <Run Text="{Binding desc, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
                                    </Paragraph>
                                </FlowDocument>
                            </local:RichTextSelection>
                        </DataTemplate>

您会注意到一个依赖属性: DoBoldSelection 此属性处理更改所选文本的字体粗细。 在上面的示例中,该属性绑定到我的List<DescriptionObject>中的一个属性,即AllowBoldHighlight

我的DescriptionObject class 看起来像:

public class DescriptionObject : INotifyPropertyChanged
    {
        public string desc { get; set; } = string.Empty;

        private bool allowHighlight = false;
        public bool AllowBoldHighlight
        {
            get => allowHighlight;
            set => SetProperty(ref allowHighlight, value);
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propName = "")
        {
            if (EqualityComparer<T>.Default.Equals(storage, value)) return false;
            storage = value;
            OnPropertyChanged(propName);
            return true;
        }

    }

MainWindow.xaml看起来像:

<Window x:Class="ChangeFontSelectionGridWPF.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:local="clr-namespace:ChangeFontSelectionGridWPF"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        Title="MainWindow"
        Width="800"
        Height="450"
        mc:Ignorable="d"
        >
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Button Grid.Row="0"
                Grid.Column="1"
                Margin="10"
                Click="Button_Click"
                Content="Bold"
                />
        <DataGrid x:Name="DescriptionGrid"
                  Grid.Row="1"
                  Grid.ColumnSpan="2"
                  AutoGenerateColumns="False"
                  ItemsSource="{Binding Descriptions}"
                  >
            <DataGrid.Columns>
                <DataGridTemplateColumn Width="300" Header="Description">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <local:RichTextSelection Width="Auto"
                                                     AcceptsReturn="True"
                                                     DoBoldSelection="{Binding AllowBoldHighlight}"
                                                     >
                                <FlowDocument>
                                    <Paragraph>
                                        <Run Text="{Binding desc, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
                                    </Paragraph>
                                </FlowDocument>
                            </local:RichTextSelection>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>

    </Grid>
</Window>

MainWindow.cs看起来像:

public partial class MainWindow : Window
    {
        public List<DescriptionObject> Descriptions { get; set; } = new List<DescriptionObject>();

        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
            Descriptions.Add(new DescriptionObject() { desc = "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?" });
            Descriptions.Add(new DescriptionObject() { desc = "rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?" });
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            if (DescriptionGrid.SelectedItem is DescriptionObject dobj)
            {
                dobj.AllowBoldHighlight = true;
                dobj.AllowBoldHighlight = false;
            }
        }

    }

您会注意到,在Button_Click中,您可以处理更改所选文本的FontWeight 基本示例。 这样做的主要驱动因素是dobj.AllowBoldHighlight = true 发生的事情是当您选择/突出显示文本然后单击按钮时, dobj.AllowBoldHighlight属性会发生变化,这会触发RichTextSelection OnBoldSelectionChanged中的 OnBoldSelectionChanged。上面的示例使您可以灵活地关闭和打开每个对象/实例你的网格。

这是它工作的一个简短片段:

在此处输入图像描述

希望这有助于解决您的问题,如果有任何问题,请告诉我。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM