You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WinForms ErrorProvider的Avalonia替代方案及自定义实现咨询

Avalonia中替代WinForms ErrorProvider的方案及自定义实现指导

一、现有替代方案

  • Avalonia内置验证系统:Avalonia原生支持数据验证,通过DataValidationErrors附加属性结合样式配置,可实现控件错误标记效果。你可以在ViewModel中实现INotifyDataErrorInfo接口定义验证逻辑,再通过样式绑定显示错误图标和提示文本。
  • 社区第三方控件:部分Avalonia社区库封装了类似ErrorProvider的功能,比如Avalonia.Controls.DataValidation系列组件,可直接通过NuGet搜索安装使用。

二、自定义实现步骤

如果没有合适的第三方库,可通过附加属性+样式模板的方式自定义实现等效功能:

1. 定义附加属性

创建静态类,用于存储控件的错误信息和显示状态:

using Avalonia;
using Avalonia.Controls;

public static class ErrorProvider
{
    // 存储错误文本的附加属性
    public static readonly AttachedProperty<string> ErrorProperty =
        AvaloniaProperty.RegisterAttached<ErrorProvider, Control, string>("Error");

    // 控制是否显示错误图标的附加属性
    public static readonly AttachedProperty<bool> ShowErrorProperty =
        AvaloniaProperty.RegisterAttached<ErrorProvider, Control, bool>("ShowError");

    // 属性访问器
    public static string GetError(Control control) => control.GetValue(ErrorProperty);
    public static void SetError(Control control, string value) => control.SetValue(ErrorProperty, value);

    public static bool GetShowError(Control control) => control.GetValue(ShowErrorProperty);
    public static void SetShowError(Control control, bool value) => control.SetValue(ShowErrorProperty, value);
}

2. 编写错误显示样式

在应用全局资源字典(如App.axaml)中添加样式,为带错误标记的控件追加图标和Tooltip:

<Application xmlns="https://github.com/avaloniaui"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:YourAppNamespace">
    <Application.Styles>
        <FluentTheme Mode="Light" />
        <Style Selector="Control[local:ErrorProvider.ShowError=True]">
            <Setter Property="Template">
                <ControlTemplate>
                    <Grid>
                        <!-- 保留原控件内容 -->
                        <ContentPresenter Content="{TemplateBinding Content}" />
                        <!-- 错误图标容器 -->
                        <Border HorizontalAlignment="Right" VerticalAlignment="Top"
                                Margin="0 0 8 8"
                                Visibility="{TemplateBinding local:ErrorProvider.ShowError, Converter={StaticResource BooleanToVisibilityConverter}}">
                            <!-- 用Path绘制内置错误图标,也可替换为自定义图片 -->
                            <Path Data="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"
                                  Fill="Red" Width="16" Height="16"
                                  ToolTip.Tip="{TemplateBinding local:ErrorProvider.Error}" />
                        </Border>
                    </Grid>
                </ControlTemplate>
            </Setter>
        </Style>
    </Application.Styles>
</Application>

3. 在界面中使用

在XAML控件上绑定错误信息和显示状态:

<TextBox x:Name="UsernameInput"
         local:ErrorProvider.Error="{Binding UsernameValidationError}"
         local:ErrorProvider.ShowError="{Binding IsUsernameInvalid}" />

4. 结合MVVM自动验证(可选)

让ViewModel实现INotifyDataErrorInfo接口,可自动触发错误状态更新:

public class LoginViewModel : ViewModelBase, INotifyDataErrorInfo
{
    private readonly Dictionary<string, List<string>> _errors = new();
    private string _username;

    public string Username
    {
        get => _username;
        set
        {
            _username = value;
            ValidateUsername();
            OnPropertyChanged();
        }
    }

    public bool HasErrors => _errors.Any();

    public event EventHandler<DataErrorsChangedEventArgs>? ErrorsChanged;

    public IEnumerable GetErrors(string? propertyName)
    {
        if (string.IsNullOrEmpty(propertyName) || !_errors.ContainsKey(propertyName))
            return Enumerable.Empty<string>();
        return _errors[propertyName];
    }

    private void ValidateUsername()
    {
        var errors = new List<string>();
        if (string.IsNullOrWhiteSpace(Username))
            errors.Add("用户名不能为空");
        else if (Username.Length < 3)
            errors.Add("用户名长度不能少于3位");

        if (errors.Any())
            _errors["Username"] = errors;
        else
            _errors.Remove("Username");

        ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs("Username"));
        IsUsernameInvalid = errors.Any();
    }

    public bool IsUsernameInvalid { get; set; }
}

补充说明

  • 错误图标可替换为自定义图片或FontAwesome等图标库内容;
  • ToolTip样式可通过自定义ToolTip控件模板调整;
  • 全局样式可统一放在资源字典中,避免重复编写。

内容的提问来源于stack exchange,提问作者judex_gauss

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 17:05:19