如何创建工具提示来显示单个控件的多个验证错误?

2024-04-06

我试图通过控件上的工具提示来显示控件的多个验证错误,但没有找到实现此目的的方法。

我可以通过具有如下样式的工具提示轻松显示控件的单个验证错误:

<Style TargetType="TextBox">
        <Style.Triggers>
            <Trigger Property="Validation.HasError" Value="True">
                <Setter Property="ToolTip" Value="{Binding Path=(Validation.Errors).CurrentItem.ErrorContent, RelativeSource={x:Static RelativeSource.Self}}"/>
            </Trigger>
        </Style.Triggers>
</Style>

但是,这种方法只能让我显示第一个验证错误。我尝试在工具提示中获取验证错误列表,但该列表从未显示。以下是我尝试过的方法:

将 ItemsControl 放置在工具提示中,使用 Validation.Errors 作为 ItemsSource,使用 CurrentItem.ErrorContent 作为要显示的文本:

<Style TargetType="TextBox">
        <Style.Triggers>
            <Trigger Property="Validation.HasError"
                     Value="True">
                <Setter Property="ToolTip">
                    <Setter.Value>
                        <ItemsControl>
                            <ItemsControl.ItemsSource>
                                <Binding Path="(Validation.Errors)" RelativeSource="{x:Static RelativeSource.Self}" />
                            </ItemsControl.ItemsSource>
                            <ItemsControl.ItemTemplate>
                                <DataTemplate>
                                    <TextBlock Text="{Binding CurrentItem.ErrorContent}" Foreground="Red"/>
                                </DataTemplate>
                            </ItemsControl.ItemTemplate>
                        </ItemsControl>
                    </Setter.Value>
                </Setter>
            </Trigger>
        </Style.Triggers>
    </Style>

我还尝试使用 Validation.Errors.CurrentItem 作为 ItemsSource,并使用 ErrorContent 作为要显示的文本:

<Style TargetType="TextBox">
        <Style.Triggers>
            <Trigger Property="Validation.HasError"
                     Value="True">
                <Setter Property="ToolTip">
                    <Setter.Value>
                        <ItemsControl>
                            <ItemsControl.ItemsSource>
                                <Binding Path="(Validation.Errors).CurrentItem" RelativeSource="{x:Static RelativeSource.Self}" />
                            </ItemsControl.ItemsSource>
                            <ItemsControl.ItemTemplate>
                                <DataTemplate>
                                    <TextBlock Text="{Binding ErrorContent}" Foreground="Red"/>
                                </DataTemplate>
                            </ItemsControl.ItemTemplate>
                        </ItemsControl>
                    </Setter.Value>
                </Setter>
            </Trigger>
        </Style.Triggers>
    </Style>

这些方法中的任何一种都会导致显示空的工具提示:

我可以使用 Validation.ErrorTemplate 将控件的验证错误列表显示为控件外部的列表:

<Style TargetType="TextBox">
        <Setter Property="Validation.ErrorTemplate">
            <Setter.Value>
                <ControlTemplate>
                    <StackPanel>
                        <AdornedElementPlaceholder/>
                        <ItemsControl ItemsSource="{Binding}">
                            <ItemsControl.ItemTemplate>
                                <DataTemplate>
                                    <TextBlock Text="{Binding ErrorContent}" Foreground="Red"/>
                                </DataTemplate>
                            </ItemsControl.ItemTemplate>
                        </ItemsControl>
                    </StackPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

This https://stackoverflow.com/questions/4161523/wpf-validation-errors-setting-tooltip-with-error-message/14550973#14550973答案展示了如何使用 ErrorTemplate 将错误放置在单独的元素工具提示中。似乎在 ErrorTemplate 中,您可以访问完整的错误列表,而我在上面尝试的工具提示样式中似乎没有这些列表。答案中的第一个解决方案使控件不可点击,这是我不想要的。我在这里尝试了答案中的第二个解决方案:

<Style TargetType="TextBox">
        <Setter Property="Validation.ErrorTemplate">
            <Setter.Value>
                <ControlTemplate>
                    <Grid>
                        <Ellipse Fill="Red" Opacity="0.8" Width="10" Height="10" HorizontalAlignment="Right" VerticalAlignment="Top">
                            <Ellipse.ToolTip>
                                <ItemsControl ItemsSource="{Binding}">
                                    <ItemsControl.ItemTemplate>
                                        <DataTemplate>
                                            <TextBlock Text="{Binding ErrorContent}" Foreground="Red"/>
                                        </DataTemplate>
                                    </ItemsControl.ItemTemplate>
                                </ItemsControl>
                            </Ellipse.ToolTip>
                        </Ellipse>
                        <AdornedElementPlaceholder />
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

这确实给了我一个工具提示,其中包含控件的所有错误:

但是,您必须将鼠标悬停在红色圆圈上才能显示工具提示。我的目标是当您将鼠标悬停在控件上时出现工具提示,我认为这对用户来说会更直观。我似乎不知道如何将多个错误放入实际的控制工具提示中。这可能吗?


我知道这个问题是不久前发布的,但我遇到了同样的问题,想分享我的解决方案(希望它可以帮助其他人;))。

经过一番谷歌搜索后,我发现了一个post https://connect.microsoft.com/VisualStudio/feedback/details/785207/wpf-validation-does-only-show-the-first-element-from-inotifydataerrorinfo-geterrors这描述了这个问题。他们建议用多重绑定来解决这个问题,我就是这样做的。我只使用了一种样式来做到这一点
这里是样式的代码:

<Style TargetType="TextBox">
        <Style.Triggers>
            <Trigger Property="Validation.HasError" Value="true">
                <Setter Property="BorderBrush" Value="Red" /> 
                <Setter Property="ToolTip">
                    <Setter.Value>
                        <MultiBinding Converter="{StaticResource conv}">
                            <Binding RelativeSource="{RelativeSource Self}" Path="(Validation.Errors)" />
                            <Binding RelativeSource="{RelativeSource Self}" Path="(Validation.Errors).Count" />
                        </MultiBinding>
                    </Setter.Value>
                </Setter>
            </Trigger>
        </Style.Triggers>
    </Style>

问题是 (Validation.Errors) 为您提供一个 ReadOnlyObservableCollection 并且该集合将随着时间的推移而被填充。但是当您绑定到 (Validation.Errors) 时,它只会注意到第一项。这就是第二个绑定 (Validation.Errors).Count 的原因,以便每次更改计数时都会调用您的转换器。
现在我们终于需要转换器了:

public class MultiLineConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (!(values[0] is IEnumerable<ValidationError>))
            return null;

        var val = values[0] as IEnumerable<ValidationError>;

        string retVal = "";

        foreach (var itm in val)
        {
            if (retVal.Length > 0)
                retVal += "\n";
            retVal += itm.ErrorContent;

        }
        return retVal;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

它只使用值[0],因为那是集合。然后它会为所有 ErrorContents 创建一个字符串。

希望这可以帮助。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何创建工具提示来显示单个控件的多个验证错误? 的相关文章

随机推荐