AvaloniaEdit 实现binding

组件:Avalonia.AvaloniaEdit

最近项目有需要用到富文本框,主要记录一下binding的使用过程

1.binding Document

 View代码:

<avaloniaEdit:TextEditor
Grid.Column="0"
VerticalAlignment="Stretch"
Background="#FFEEEEEE"
Document="{Binding Model.DataMap.WriteStringText}"
SyntaxHighlighting="{x:Null}"
WordWrap="True" />

model:

     public TextDocument WriteStringText { get; set; } = new TextDocument();

        这种方式是通过绑定了一个TextDocument 对象,此时后续对富文本框的编辑就需要引出TextDocument.Text属性,来实现富文本框的内容刷新,实际经常使用富文本框来显示Model的string属性,此时使用操作存在一定局限性binding无法直接与document交互,不做推荐。

2. 附加属性实现binding

View:

                    <avaloniaEdit:TextEditor
                        Name="reqViewText"
                        Grid.Column="0"
                        VerticalAlignment="Stretch"
                        common:TextEditorHelper.IsSubscribed="True"
                        common:TextEditorHelper.Text="{Binding Model.InterFace.SelectInterFace.Interface_ExReqData, Mode=TwoWay}"
                        Background="#FFEEEEEE"
                        SyntaxHighlighting="{x:Null}"
                        WordWrap="True">
                    </avaloniaEdit:TextEditor>

Model:

    private string _iterface_ExReqData;
 
        public string Interface_ExReqData
        {
            get { return _iterface_ExReqData; }
            set
            {
                _iterface_ExReqData = value;
                OnPropertyChanged(nameof(Interface_ExReqData));
            }
        }

这里通过附加属性此时就可以直接binding到model的string属性上,方便快捷。

附加属性类:

    public class TextEditorHelper
    {
        /// <summary>
        /// 定义Text附加属性
        /// </summary>
        public static readonly AttachedProperty<string> TextProperty =
            AvaloniaProperty.RegisterAttached<TextEditorHelper, TextEditor, string>(
                "Text",
                default,
                false,
                BindingMode.TwoWay);

        /// <summary>
        /// 订阅状态附加属性
        /// </summary>
        private static readonly AttachedProperty<bool> IsSubscribedProperty =
            AvaloniaProperty.RegisterAttached<TextEditorHelper, TextEditor, bool>(
                "IsSubscribed",
                default);

        private static readonly Dictionary<TextEditor, bool> _updating = new();

        static TextEditorHelper()
        {
            TextProperty.Changed.AddClassHandler<TextEditor>(OnTextPropertyChanged);
            IsSubscribedProperty.Changed.AddClassHandler<TextEditor>(OnIsSubscribedChanged);
        }

        /// <summary>
        /// Text属性变更处理
        /// </summary>
        private static void OnTextPropertyChanged(TextEditor editor, AvaloniaPropertyChangedEventArgs args)
        {
            if (_updating.TryGetValue(editor, out var isUpdating) && isUpdating)
                return;

            try
            {
                _updating[editor] = true;
                var newValue = args.GetNewValue<string>();
                if (editor.Text != newValue)
                {
                    editor.Text = newValue;
                }
            }
            finally
            {
                _updating[editor] = false;
            }
        }

        /// <summary>
        /// TextEditor内容变更处理
        /// </summary>
        private static void OnTextChanged(object sender, EventArgs e)
        {
            if (sender is TextEditor editor)
            {
                if (_updating.TryGetValue(editor, out var isUpdating) && isUpdating)
                    return;

                try
                {
                    _updating[editor] = true;
                    SetText(editor, editor.Text ?? string.Empty);
                }
                finally
                {
                    _updating[editor] = false;
                }
            }
        }

        /// <summary>
        /// 订阅状态变更处理
        /// </summary>
        private static void OnIsSubscribedChanged(TextEditor editor, AvaloniaPropertyChangedEventArgs args)
        {
            var isSubscribed = args.GetNewValue<bool>();
            if (isSubscribed)
            {
                editor.TextChanged += OnTextChanged;
            }
            else
            {
                editor.TextChanged -= OnTextChanged;
            }
        }

        /// <summary>
        /// 设置Text附加属性
        /// </summary>
        public static void SetText(TextEditor element, string value)
        {
            element.SetValue(TextProperty, value);
            SetIsSubscribed(element, true); // 自动启用订阅
        }

        /// <summary>
        /// 获取Text附加属性
        /// </summary>
        public static string GetText(TextEditor element) =>
            element.GetValue(TextProperty);

        /// <summary>
        /// 获取订阅状态
        /// </summary>
        public static bool GetIsSubscribed(TextEditor element) =>
            element.GetValue(IsSubscribedProperty);

        /// <summary>
        /// 设置订阅状态
        /// </summary>
        public static void SetIsSubscribed(TextEditor element, bool value) =>
            element.SetValue(IsSubscribedProperty, value);
    }

其实还有第三种方法,通过Interaction.Behaviors行为,也可以binding到text上

 



posted @ 2025-08-04 18:16  南柯思一梦  阅读(163)  评论(0)    收藏  举报