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

如何对可编辑ComboBox的输入、选择操作实现IDataErrorInfo校验

问题核心原因

你的代码存在3个关键问题导致校验无法触发:

  1. 可编辑ComboBox的手动输入内容对应Text属性,你仅绑定了SelectedValue,只有下拉选择时才会更新源属性,手动输入时源属性不会变化,自然不会触发校验
  2. ItemTemplate绑定上下文错误,下拉项的DataContext是ValuesList的单个元素,不是ViewModel,这个模板完全写错了,还会干扰正常显示
  3. ViewModel的校验逻辑中errorMessaage始终为空,就算触发校验也不会返回错误信息

第一步:调整XAML代码

<ComboBox x:Name="Cbx2" 
          IsEditable="True"
          Grid.Row="5" Grid.Column="2"                                
          HorizontalAlignment="Stretch"
          ItemsSource="{Binding ValuesList, Mode=OneWay}"   
          <!-- 绑定Text属性覆盖手动输入+下拉选择两种场景,原SelectedValue绑定可以删除 -->
          Text="{Binding SelectedCbxValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnValidationError=True, ValidatesOnDataErrors=True}"
          <!-- 没有特殊业务逻辑的话这两个事件可以删掉 -->
          SelectionChanged="OnSelectionChanged"
          LostFocus="TxtBox_LostFocus">
    <!-- 删掉错误的ItemTemplate,字符串类型的ItemsSource用默认模板即可 -->
</ComboBox>

UpdateSourceTrigger=PropertyChanged可以保证输入或选择的同时立刻触发校验,不需要额外处理事件。


第二步:调整ViewModel校验逻辑

public class SOViewModel : ViewModelBase, IDataErrorInfo
{
    private ObservableCollection<string> _valuesList;
    public ObservableCollection<string> ValuesList
    {
        get => _valuesList;
        set => SetProperty(ref _valuesList, value);
    }

    private bool _isValid;
    public bool IsValid { get => _isValid; set => SetProperty(ref _isValid, value); }

    private string _selectedCbxValue;
    public string SelectedCbxValue { get => _selectedCbxValue; set => SetProperty(ref _selectedCbxValue, value); }

    #region IDataErrorInfo properties
    private string _error;
    public string Error { get => _error; set => SetProperty(ref _error, value); }

    public string this[string propName]
    {
        get
        {
            return ValidateProperty(propName);
        }
    }

    private string ValidateProperty(string propName)
    {
        string errorMessaage = string.Empty;
        // 每次校验前重置IsValid状态,避免历史错误残留
        IsValid = true;
        
        bool ValidateValue(string valueToValid)
        {
            // 示例校验逻辑:不能为空,且必须在可选列表中,可根据业务需求修改
            if (string.IsNullOrWhiteSpace(valueToValid))
            {
                errorMessaage = "选项不能为空";
                return false;
            }
            if (!ValuesList.Contains(valueToValid))
            {
                errorMessaage = "输入内容不在可选范围内";
                return false;
            }
            return true;
        }

        if (propName == nameof(SelectedCbxValue))
        {
           IsValid = ValidateValue(SelectedCbxValue);
        }

        Error = string.IsNullOrEmpty(errorMessaage) ? null : errorMessaage;
        return errorMessaage;
    }
    #endregion
}

可选:自定义错误提示样式

如果默认的红色边框不符合UI需求,可以给ComboBox添加Validation.ErrorTemplate自定义错误提示样式,比如直接展示错误文本:

<ComboBox>
    <Validation.ErrorTemplate>
        <ControlTemplate>
            <StackPanel>
                <AdornedElementPlaceholder x:Name="placeholder"/>
                <TextBlock Text="{Binding [0].ErrorContent}" Foreground="Red" FontSize="12"/>
            </StackPanel>
        </ControlTemplate>
    </Validation.ErrorTemplate>
</ComboBox>

内容的提问来源于stack exchange,提问作者On The Net Again

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 00:51:04