数据验证错误文本出现在模板控件内,但内部的文本框没有边框

后端开发 2026-07-12

我在Avalonia中使用自定义的TemplatedControl。将其属性绑定到我的ViewModel时会进行数据验证,但我没有看到完整的验证错误可视化效果。控件内部TextBox上会显示错误文本,但边框却没有出现。

Themes/Generic.axaml:

<?xml version="1.0" encoding="utf-8"?>
<Styles xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:Dashavalanche.UI.Controls">
  <Style Selector="local|PathBox">
    <Setter Property="Template">
      <ControlTemplate>
        <DataValidationErrors>
          <TextBox Text="{Binding Path, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" Watermark="{TemplateBinding Watermark}" x:Name="PART_TextBox"/>
        </DataValidationErrors>
      </ControlTemplate>
    </Setter>
  </Style>
</Styles>

Controls/PathBox.cs:

using System;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Data;

namespace Dashavalanche.UI.Controls;

public class PathBox : TemplatedControl
{
  public static readonly DirectProperty<PathBox, string?> PathProperty =
      AvaloniaProperty.RegisterDirect<PathBox, string?>(
          nameof(Path), o => o.Path, (o, v) => o.Path = v, defaultBindingMode: BindingMode.TwoWay, enableDataValidation: true);
  private string? _path;

  public string? Path
  {
    get => _path;
    set => SetAndRaise(PathProperty, ref _path, value);
  }

  public static readonly StyledProperty<string?> WatermarkProperty =
    AvaloniaProperty.Register<PathBox, string?>(nameof(Watermark));

  public string? Watermark
  {
    get => GetValue(WatermarkProperty);
    set => SetValue(WatermarkProperty, value);
  }

  protected override void UpdateDataValidation(AvaloniaProperty property, BindingValueType state, Exception? error)
  {
    base.UpdateDataValidation(property, state, error);

    if (property == PathProperty)
    {
      DataValidationErrors.SetError(this, error);
    }
  }
}

用法:

<local:PathBox Watermark="Откуда" Path="{Binding SourcePath, Mode=TwoWay}"/>

在截图中,PathBox 位于顶部,底部是一个普通的 TextBox,绑定到具有相同数据验证的属性。

截图

在DevTools的逻辑树和视觉树中,PathBox 拥有 :error 伪类,但内部的 TextBox 没有。

使用Avalonia 11.3.12、.NET 8。

解决方案

你需要自行为 :error 伪类指定 BorderBrush。在你的场景中你需要添加:

Themes/Generic.axaml :

<?xml version="1.0" encoding="utf-8"?>
<Styles xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:Dashavalanche.UI.Controls">
  <Style Selector="local|PathBox">
    <Setter Property="Template">
      <ControlTemplate>
        <DataValidationErrors>
          <TextBox Text="{Binding Path, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" Watermark="{TemplateBinding Watermark}" x:Name="PART_TextBox"/>
        </DataValidationErrors>
      </ControlTemplate>
    </Setter>

    <Style Selector="^:error /template/ TextBox#PART_TextBox /template/ Border#PART_BorderElement">
      <Setter Property="BorderBrush" Value="Red"></Setter>
    </Style>
  </Style>
</Styles>

或者如果你想要主题相关的错误笔刷,请使用 <Setter Property="BorderBrush" Value="{DynamicResource SystemControlErrorTextForegroundBrush}"/>

此外,为了调试方便,你可以在你的 PathBox 类中添加 [PseudoClasses(":error")] 指令。

namespace Dashavalanche.UI.Controls;

[PseudoClasses(":error")]
public class PathBox : TemplatedControl
{
   ...
}

我在这里看到的解决方案 这里.

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章