C# WPF MVVM:绑定RichTextBox文档?

C# WPF MVVM:绑定RichTextBox文档?,c#,wpf,xaml,mvvm,C#,Wpf,Xaml,Mvvm,我正在尝试将一个当前位于代码隐藏中的方法重构为视图模型。有一个btn click事件,它从RichTextBox Rtf构建一个TextRange,然后执行一些文本格式: private void btn1_Click(object sender, RoutedEventArgs e) { TextRange rangeOfText = new TextRange(richTextBoxArticleBody.Document.ContentStart, richTex

我正在尝试将一个当前位于代码隐藏中的方法重构为视图模型。有一个btn click事件,它从RichTextBox Rtf构建一个TextRange,然后执行一些文本格式:

 private void btn1_Click(object sender, RoutedEventArgs e)
    {
        TextRange rangeOfText = new TextRange(richTextBoxArticleBody.Document.ContentStart, richTextBoxArticleBody.Document.ContentEnd);

        if (richTextBoxArticleBody.Text.Contains("trowd"))
        {
            blah blah
我尝试使用此答案使用deependency对象将文档绑定到视图模型中的字符串属性:

依赖项属性类:

public class RichTextBoxHelper : DependencyObject
{
    private static HashSet<Thread> _recursionProtection = new HashSet<Thread>();

    public static string GetDocumentXaml(DependencyObject obj)
    {
        return (string)obj.GetValue(DocumentXamlProperty);
    }

    public static void SetDocumentXaml(DependencyObject obj, string value)
    {
        _recursionProtection.Add(Thread.CurrentThread);
        obj.SetValue(DocumentXamlProperty, value);
        _recursionProtection.Remove(Thread.CurrentThread);
    }

    public static readonly DependencyProperty DocumentXamlProperty = DependencyProperty.RegisterAttached(
        "DocumentXaml",
        typeof(string),
        typeof(RichTextBoxHelper),
        new FrameworkPropertyMetadata(
            "",
            FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
            (obj, e) =>
            {
                if (_recursionProtection.Contains(Thread.CurrentThread))
                    return;

                var richTextBox = (RichTextBox)obj;

                // Parse the XAML to a document (or use XamlReader.Parse())

                try
                {
                    var stream = new MemoryStream(Encoding.UTF8.GetBytes(GetDocumentXaml(richTextBox)));
                    var doc = (FlowDocument)XamlReader.Load(stream);

                    // Set the document
                    richTextBox.Document = doc;
                }
                catch (Exception)
                {
                    richTextBox.Document = new FlowDocument();
                }

                // When the document changes update the source
                richTextBox.TextChanged += (obj2, e2) =>
                {
                    RichTextBox richTextBox2 = obj2 as RichTextBox;
                    if (richTextBox2 != null)
                    {
                        SetDocumentXaml(richTextBox, XamlWriter.Save(richTextBox2.Document));
                    }
                };
            }
        )
    );
}
ViewModel属性:

private string _RichTextBoxBody;
    public string RichTextBoxBody
    {
        get { return _RichTextBoxBody; }
        set
        {
            _RichTextBoxBody = value;
            OnPropertyChanged("RichTextBoxBody");
        }
    }
字符串已成功传递到视图模型中。最后,这里是我的视图模型按钮命令方法。我被困在这里,因为我无法将字符串值放入TextRange:


这是否值得追求,甚至是可能的,如果可以的话,我真的想去掉隐藏的代码…

你的问题似乎有点误导。您可以将问题重新表述为如何从VM中的字符串构造TextRange?。如果你这样看的话,你可能会问我是想要一个TextRange,还是应该看看现有函数的用途,在没有TextRange的情况下实现我的需求。TextRange似乎与UI元素非常耦合,所以如果您必须使用一个,为什么不在一个行为中使用整个功能并保持您的虚拟机干净呢。我可能必须在代码中保留这一点,因为我需要获取RTB文档,格式化文本,不加粗,大小为10 Arial等,并将其与视图重新绑定。在代码隐藏之外,找不到一种干净的方法来执行此操作。扩展WPF工具包提供了TextFormatter接口,但我无法让它返回格式化文本。格式化文本不加粗,大小为10 Arial等。是的,我想你是对的。只是不喜欢在代码中隐藏按钮单击事件,除非绝对必要。
private string _RichTextBoxBody;
    public string RichTextBoxBody
    {
        get { return _RichTextBoxBody; }
        set
        {
            _RichTextBoxBody = value;
            OnPropertyChanged("RichTextBoxBody");
        }
    }
 private void FormatCommandAction()
    {

        TextRange rangeOfText = new TextRange(RichTextBoxBody.ContentStart, RichTextBoxBody.ContentEnd);

         if (ModelviewArticle.ArticleBody.Contains("trowd"))
        {
            blah blah