gpt4 book ai didi

wpf - 如何在 WPF 中扩展控件以为 ErrorTemplate 中的错误消息腾出空间?

转载 作者:行者123 更新时间:2023-12-05 00:44:01 29 4
gpt4 key购买 nike

我有一个使用验证的 WPF 窗口。我创建了一个错误模板,它在验证失败的元素周围放置了一个红色边框,并在下面显示错误消息。这可以正常工作,但错误消息会呈现在带有错误的控件下方的任何控件之上。我能说的最好的情况是,发生这种情况是因为错误模板呈现在装饰层上,装饰层位于其他一切之上。我希望发生的事情是让其他所有内容都向下移动以为错误消息腾出空间。有没有办法做到这一点?网络上的所有示例似乎都使用了工具提示,并使用了一个简单的指示符,例如星号或感叹号,不会占用太多空间。

这是模板:

<ControlTemplate x:Key="ValidationErrorTemplate">
<StackPanel>
<Border BorderBrush="Red" BorderThickness="2" CornerRadius="2">
<AdornedElementPlaceholder x:Name="placeholder"/>
</Border>
<TextBlock Foreground="Red" FontSize="10" Text="{Binding ElementName=placeholder, Path=AdornedElement.(Validation.Errors)[0].ErrorContent, FallbackValue=Error!}"></TextBlock>
</StackPanel>
</ControlTemplate>

以下是使用模板的控件(我输入了其中的一些,因此请忽略任何语法错误):
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBox Name="Account" Grid.Row="0" Validation.ErrorTemplate="{StaticResource ValidationErrorTemplate}" Width="200">
<TextBox.Text>
<Binding Path="AccountNumber">
<Binding.ValidationRules>
<validators:RequiredValueValidationRule/>
<validators:NumericValidationRule/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<TextBox Name="Expiration" Grid.Row="1" Validation.ErrorTemplate="{StaticResource ValidationErrorTemplate}" Width="100" Margin="0,2,5,2">
<TextBox.Text>
<Binding Path="ExpirationDate">
<Binding.ValidationRules>
<validators:ExpirationDateValidationRule/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
</Grid>

最佳答案

编辑:好吧,我不肯定这是最好的解决方案(我当然希望有人能提供更好的解决方案),但它是这样的:

您可以添加一些 TextBlock 并将它们绑定(bind)到 Validation.HasError 和 (Validation.Errors)[0].ErrorContent,而不是使用 Validation.ErrorTeplate,后者将在 AdornerLayer 中呈现所有视觉效果,使用客户 IValueConverter 转换Validation.HasError bool 到 Visibility 值。它看起来像下面这样:

窗口1.cs:

<Window x:Class="WpfApplicationTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:local="clr-namespace:WpfApplicationTest"
Title="Window1" Height="300" Width="300">
<Grid Margin="10">
<Grid.Resources>
<!-- The person we are binding to -->
<local:Person x:Key="charles" Name="Charles" Age="20" />
<!-- The convert to use-->
<local:HasErrorToVisibilityConverter x:Key="visibilityConverter" />
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- The name -->
<TextBox Name="NameTextBox" Grid.Row="0" Text="{Binding Source={StaticResource charles}, Path=Name, ValidatesOnDataErrors=true}" />
<TextBlock Grid.Row="1"
Foreground="Red"
Text="{Binding ElementName=NameTextBox, Path=(Validation.Errors)[0].ErrorContent}"
Visibility="{Binding ElementName=NameTextBox, Path=(Validation.HasError), Converter={StaticResource visibilityConverter}}" />

<!-- The age -->
<TextBox Name="AgeTextBox" Grid.Row="2" Text="{Binding Source={StaticResource charles}, Path=Age, ValidatesOnExceptions=true}" />
<TextBlock Grid.Row="3"
Foreground="Red"
Text="{Binding ElementName=AgeTextBox, Path=(Validation.Errors)[0].ErrorContent}"
Visibility="{Binding ElementName=AgeTextBox, Path=(Validation.HasError), Converter={StaticResource visibilityConverter}}" />
</Grid>
</Window>

个人.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Text.RegularExpressions;

namespace WpfApplicationTest
{
public class Person : IDataErrorInfo
{
public string Name { get; set; }
public int Age { get; set; }

#region IDataErrorInfo Members

string IDataErrorInfo.Error
{
get { throw new NotImplementedException(); }
}

string IDataErrorInfo.this[string columnName]
{
get
{
switch (columnName)
{
case ("Name"):
if (Regex.IsMatch(this.Name, "[^a-zA-Z ]"))
{
return "Name may contain only letters and spaces.";
}
else
{
return null;
}
default:
return null;
}
}
}

#endregion
}
}

HasErrorToVisibilityConverter.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Data;
using System.Windows;

namespace WpfApplicationTest
{
[ValueConversion(typeof(bool), typeof(Visibility))]
public class HasErrorToVisibilityConverter : IValueConverter
{
#region IValueConverter Members

object IValueConverter.Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
bool hasError = (bool)value;
return hasError ? Visibility.Visible : Visibility.Collapsed;
}

object IValueConverter.ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}

#endregion
}
}

它的扩展性不如您可以在所有控件中引用的单个 ControlTemplate,但它是我找到的唯一解决方案。我感觉到你的痛苦——几乎我能找到的关于 WPF 验证主题的每个示例都非常简单,并且几乎总是使用“!”或 '*' 在控件之前,工具提示绑定(bind)到 (Validation.Errors)[0].ErrorContent...

祝你好运!如果我找到更好的解决方案,我会更新这个;)

关于wpf - 如何在 WPF 中扩展控件以为 ErrorTemplate 中的错误消息腾出空间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/474173/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com