从上下文菜单更改RichTextBox中选定文本的前景色

时间:2018-08-01 19:07:50

标签: c# wpf xaml richtextbox attached-properties

我的应用程序具有带有自定义上下文菜单的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 个答案:

答案 0 :(得分:0)

RichTextBox不支持数据绑定,因此您需要推出自己的解决方案(这不是一件容易的事)或使用一种开箱即用的商品,例如the one from the WPF Toolkit