IDateErrorInfo Multi Validation.ErrorTemplate

时间:2016-03-04 11:45:56

标签: c# wpf validation mvvm idataerrorinfo

我已将IDataErrorInfo实施到我的自定义控件'ViewModel。一切正常(边框被绘制为红色,错误的工具提示正在被修剪),但我想知道是否有办法让错误和警告有两个不同的Validation.ErrorTemplate

我的自定义控件样式(使用Validation.ErrorTemplate)

        <Style TargetType="{x:Type controls:CustomTextBoxNumeric}">
        <Setter Property="TextAlignment" Value="Right"/>
        <Setter Property="Validation.ErrorTemplate">
            <Setter.Value>
                <ControlTemplate>
                    <DockPanel LastChildFill="True">
                        <Border BorderBrush="Red" BorderThickness="1">
                            <AdornedElementPlaceholder />
                        </Border>
                    </DockPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <Trigger Property="Validation.HasError" Value="true">
                <Setter Property="ToolTip"
                        Value="{Binding RelativeSource={RelativeSource Self}, 
                        Path=(Validation.Errors).CurrentItem.ErrorContent}"/>
            </Trigger>
        </Style.Triggers>
    </Style>

我的自定义控件ViewModel(INotifyPropertyChanged在基础ViewModel上实现)

public class CustomTextBoxNumericViewModel : BaseComponentViewModel, IDataErrorInfo
{
    private decimal? decimalValue;
    private bool hasErrors;
    private bool hasWarnings;

    public CustomTextBoxNumericViewModel()
    {

    }

    [DataMember(EmitDefaultValue = false)]
    public decimal? DecimalValue
    {
        get { return this.decimalValue; }
        set { this.decimalValue = value; this.Changed("DecimalValue"); this.Changed("HasErrors"); }
    }

    [DataMember(EmitDefaultValue = false)]
    public bool HasErrors
    {
        get { return this.hasErrors; }
        set { this.hasErrors = value; this.Changed("HasErrors"); this.Changed("DecimalValue"); }
    }

    [DataMember(EmitDefaultValue = false)]
    public bool HasWarnings
    {
        get { return this.hasWarnings; }
        set { this.hasWarnings = value; this.Changed("HasWarnings"); this.Changed("DecimalValue"); }
    }

    #region IDataErrorInfo Implementation

    public string Error
    {
        get
        {
            throw new NotImplementedException();
        }
    }

    public string this[string propertyName]
    {
        get
        {
            if (propertyName == "DecimalValue")
            {
                if (HasErrors)
                {
                    return this.ErrorsField;
                }
                if (HasWarnings)
                {
                    return this.WarningsField;
                }
                if (DecimalValue < 0)
                {
                    return "Must be greater than 0";
                }
            }
            return string.Empty;
        }
    }

    #endregion
}

1 个答案:

答案 0 :(得分:1)

我设法使用ControlTemplate资源解决了我的问题。

我的风格改为:

<Style TargetType="{x:Type controls:CustomTextBoxNumeric}">
        <Setter Property="TextAlignment" Value="Right"/>
        <Setter Property="Validation.ErrorTemplate">
            <Setter.Value>
                <ControlTemplate>
                    <DockPanel LastChildFill="True">
                        <Border BorderBrush="Red" BorderThickness="1">
                            <AdornedElementPlaceholder />
                        </Border>
                    </DockPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <Trigger Property="Validation.HasError" Value="true">
                <Setter Property="ToolTip"
                        Value="{Binding RelativeSource={RelativeSource Self}, 
                        Path=(Validation.Errors).CurrentItem.ErrorContent}"/>
            </Trigger>
            <DataTrigger Binding="{Binding Path=ViewModel.HasWarnings, RelativeSource={RelativeSource Self}}" Value="True">
                <Setter Property="Validation.ErrorTemplate" Value="{DynamicResource EntypoWarningTemplate}" />
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=ViewModel.HasErrors, RelativeSource={RelativeSource Self}}" Value="True">
                <Setter Property="Validation.ErrorTemplate" Value="{DynamicResource EntypoErrorTemplate}" />
            </DataTrigger>
        </Style.Triggers>
    </Style>

ControlTemplates

        <ControlTemplate x:Key="MyErrorTemplate" TargetType="{x:Type Control}">
        <DockPanel LastChildFill="True">
            <Border BorderBrush="Red" BorderThickness="1">
                <AdornedElementPlaceholder />
            </Border>
        </DockPanel>
    </ControlTemplate>

    <ControlTemplate x:Key="MyWarningTemplate" TargetType="{x:Type Control}">
        <DockPanel LastChildFill="True">
            <Border BorderBrush="Orange" BorderThickness="1">
                <AdornedElementPlaceholder />
            </Border>
        </DockPanel>
    </ControlTemplate>