c# - Richtextbox wpf 绑定(bind)

标签 c# wpf data-binding richtextbox

要在 WPF RichtextBox 中对 Document 进行数据绑定(bind),到目前为止我看到了 2 个解决方案,它们是从 RichtextBox 派生的,并且添加DependencyProperty,以及带有“代理”的解决方案。

第一个和第二个都不令人满意。有人知道另一种解决方案,或者是一个能够数据绑定(bind)的商业 RTF 控件吗?普通的 TextBox 不是替代方案,因为我们需要文本格式。

有什么想法吗?

最佳答案

还有更简单的方法!

您可以轻松创建附加的 DocumentXaml(或 DocumentRTF)属性,该属性将允许您绑定(bind) RichTextBox 的文档。它的使用方式如下,其中 Autobiography 是数据模型中的字符串属性:

<TextBox Text="{Binding FirstName}" />
<TextBox Text="{Binding LastName}" />
<RichTextBox local:RichTextBoxHelper.DocumentXaml="{Binding Autobiography}" />
瞧!完全可绑定(bind) RichTextBox 数据!

此属性的实现非常简单:设置该属性后,将 XAML(或 RTF)加载到新的 FlowDocument 中。当FlowDocument更改时,更新属性值。

这段代码应该可以解决问题:

using System.IO;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
public class RichTextBoxHelper : DependencyObject
{
    public static string GetDocumentXaml(DependencyObject obj)
    {
        return (string)obj.GetValue(DocumentXamlProperty);
    }

    public static void SetDocumentXaml(DependencyObject obj, string value)
    {
        obj.SetValue(DocumentXamlProperty, value);
    }

    public static readonly DependencyProperty DocumentXamlProperty =
        DependencyProperty.RegisterAttached(
            "DocumentXaml",
            typeof(string),
            typeof(RichTextBoxHelper),
            new FrameworkPropertyMetadata
            {
                BindsTwoWayByDefault = true,
                PropertyChangedCallback = (obj, e) =>
                {
                    var richTextBox = (RichTextBox)obj;

                    // Parse the XAML to a document (or use XamlReader.Parse())
                    var xaml = GetDocumentXaml(richTextBox);
                    var doc = new FlowDocument();
                    var range = new TextRange(doc.ContentStart, doc.ContentEnd);

                    range.Load(new MemoryStream(Encoding.UTF8.GetBytes(xaml)),
                          DataFormats.Xaml);

                    // Set the document
                    richTextBox.Document = doc;

                    // When the document changes update the source
                    range.Changed += (obj2, e2) =>
                    {
                        if (richTextBox.Document == doc)
                        {
                            MemoryStream buffer = new MemoryStream();
                            range.Save(buffer, DataFormats.Xaml);
                            SetDocumentXaml(richTextBox,
                                Encoding.UTF8.GetString(buffer.ToArray()));
                        }
                    };
                }
            });
}

相同的代码可用于 TextFormats.RTF 或 TextFormats.XamlPackage。对于 XamlPackage,您将拥有 byte[] 类型的属性,而不是 string

与普通 XAML 相比,XamlPackage 格式具有多个优点,特别是能够包含图像等资源,并且比 RTF 更灵活且更易于使用。

很难相信这个问题已经搁置了 15 个月而没有人指出实现此目的的简单方法。

关于c# - Richtextbox wpf 绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/343468/

相关文章:

c# - 是否在模型中包含 View 特定信息

c# - 实现快捷方式编辑器文本框的最佳方法是什么?

asp.net - 有没有一种简单的方法可以将 "--Select--"选项添加到 DataBound DropDownList 中?

c# - 使用 Canvas 作为 ItemsPanelTemplate 和绑定(bind) Canvas.Top 不起作用

c# - 使用C#制作Maemo应用程序(代码转QT)

c# - 如何限制每个客户端的 WCF 服务

c# - 异步无效方法如何报告 ASP.NET Core 应用程序中的进度

c# - 通过 Storyboard更改时数据绑定(bind)不更新?

c# - 1到100亿之间有多少个数字包含14

c# - 我可以将 IFormatProvider 与 WPF 绑定(bind)一起使用到自定义类型吗?