簡體   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