Изменить цвет переднего плана выделенного текста в RichTextBox из контекстного меню

Мое приложение имеет RichTextBox с пользовательским контекстным меню. Я могу получить выделенный текст, используя вложенное свойство TextBoxSelectionHelper, однако я не могу установить цвет переднего плана (красный или зеленый) этого выделенного текста, когда пользователь нажимает на пункт меню "Вопрос". Ниже моя работа в этом отношении, я следую за паттерном MVVM.

<RichTextBox Margin="50" BorderThickness="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
                ScrollViewer.CanContentScroll="True"
                ScrollViewer.VerticalScrollBarVisibility="Visible"
                AcceptsReturn="True"
                VerticalScrollBarVisibility="Auto"
                utils:TextBoxSelectionHelper.SelectedText="{Binding Selectedknowlwdge,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
            <FlowDocument>
                <Paragraph>
                    <Run Text="{Binding KnowledgeText, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
                </Paragraph>
            </FlowDocument>
            <RichTextBox.ContextMenu>
        <ContextMenu>
            <MenuItem Command="{Binding MarkQuestion}" Header="_Question">
                <MenuItem.Icon>
                    <materialDesign:PackIcon  Kind="CommentQuestionOutline" />
                </MenuItem.Icon>
            </MenuItem>
            <MenuItem Command="{Binding MarkQuestion}" Header="_Answer">
                <MenuItem.Icon>
                    <materialDesign:PackIcon  Kind="LightbulbOnOutline" />
                </MenuItem.Icon>
            </MenuItem>
            <MenuItem Command="{Binding MarkQuestion}" Header="_Clear">
                <MenuItem.Icon>
                    <materialDesign:PackIcon  Kind="FormatClear" />
                </MenuItem.Icon>
            </MenuItem>
            <MenuItem Command="Cut" Header="_Cut">
                <MenuItem.Icon>
                    <materialDesign:PackIcon  Kind="ContentCut" />
                </MenuItem.Icon>
            </MenuItem>
            <MenuItem Command="Copy" Header="_Copy">
                <MenuItem.Icon>
                    <materialDesign:PackIcon  Kind="ContentCopy" />
                </MenuItem.Icon>
            </MenuItem>
            <MenuItem Command="Paste" Header="_Paste">
                <MenuItem.Icon>
                    <materialDesign:PackIcon  Kind="ContentPaste" />
                </MenuItem.Icon>
            </MenuItem>
        </ContextMenu>
    </RichTextBox.ContextMenu>
</RichTextBox>




using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;

namespace Test.Utils
{
    public class TextBoxSelectionHelper
    {
        public static string GetSelectedText(DependencyObject obj)
        {
            return (string)obj.GetValue(SelectedTextProperty);
        }

        public static void SetSelectedText(DependencyObject obj, string value)
        {
            obj.SetValue(SelectedTextProperty, value);

        }

        // Using a DependencyProperty as the backing store for SelectedText.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty SelectedTextProperty =
            DependencyProperty.RegisterAttached(
                "SelectedText",
                typeof(string),
                typeof(TextBoxSelectionHelper),
                new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, SelectedTextChanged));

        private static void SelectedTextChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            RichTextBox tb = obj as RichTextBox;
            if (tb != null)
            {
                if (e.OldValue == null && e.NewValue != null)
                {
                    tb.SelectionChanged += tb_SelectionChanged;
                }
                else if (e.OldValue != null && e.NewValue == null)
                {
                    tb.SelectionChanged -= tb_SelectionChanged;
                }

                string newValue = e.NewValue as string;

                if (newValue != null && newValue != tb.Selection.Text)
                {
                    tb.Selection.Text = newValue as string;


                }
            }
        }

        static void tb_SelectionChanged(object sender, RoutedEventArgs e)
        {
            RichTextBox tb = sender as RichTextBox;
            if (tb != null)
            {
                SetSelectedText(tb, tb.Selection.Text);
            }
        }
    }
}



public ICommand MarkQuestion
{
    get { return new RelayCommand(param => QuestionMarker()); }
}

void QuestionMarker()
{
    //here it should change foreground color of selected text to RED.
}



private string _SelectedText="";
public string Selectedknowlwdge
{
    get { return _SelectedText; }
    set
    {
    _SelectedText = value;
    OnPropertyChanged();
    }
}

private string _KnowledgeText="";
public string KnowledgeText
{
    get { return _KnowledgeText; }
    set
    {
    _KnowledgeText = value;
    OnPropertyChanged();
    }
}

1 ответ

RichTextBox не поддерживает привязку данных, поэтому вам нужно либо развернуть свое собственное решение (это не тривиальная вещь), либо использовать одно из готовых, например, из WPF Toolkit.

Другие вопросы по тегам