如果FirstName值为null或为空,我正在抛出ApplicationException,并且我试图在TextBlock中显示错误消息,该消息是ErrorTemplate的一部分。但它始终显示“异常已被抛出调用目标”。
public string FirstName
{
get { return _firstName;}
set
{
if(String.IsNullOrEmpty(value))
throw new ApplicationException("FirstName cannot be null or empty!");
_firstName = value;
OnPropertyChanged("FirstName");
}
}
<Style x:Key="TextBoxStyle" TargetType="TextBox">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<DockPanel LastChildFill="True">
<TextBlock DockPanel.Dock="Right"
Foreground="Orange"
FontSize="12pt"
Text="{Binding ElementName=MyAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">
</TextBlock>
<Border BorderBrush="Green" BorderThickness="1">
<AdornedElementPlaceholder Name="MyAdorner" />
</Border>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
最后这里是TextBox控件:
<TextBox Name="txtFirstName" Style="{StaticResource TextBoxStyle}" Grid.Column="1" Grid.Row="0" Height="20" Width="100" Margin="10">
<TextBox.Text>
<Binding Path="FirstName">
<Binding.ValidationRules>
<ExceptionValidationRule />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
答案 0 :(得分:5)
前几天我经历了这个问题,最后我把这个例外从房产中取出并使用了验证课。
<TextBox Name="txtFirstName" Style="{StaticResource TextBoxStyle}" Grid.Column="1" Grid.Row="0" Height="20" Width="100" Margin="10">
<TextBox.Text>
<Binding Path="FirstName" >
<Binding.ValidationRules>
<validators:StringRangeValidationRule
MinimumLength="1"
MaximumLength="40"
ErrorMessage="Required" />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
从您的媒体资源中移除异常,因此它看起来像这样......
private string _firstName;
public string FirstName
{
get { return _firstName; }
set
{
_firstName = value;
OnPropertyChanged("FirstName");
}
}
继承验证课程(我在某处从互联网上挖走了这个)......
public class StringRangeValidationRule : ValidationRule
{
private int _minimumLength = -1;
private int _maximumLength = -1;
private string _errorMessage;
public int MinimumLength
{
get { return _minimumLength; }
set { _minimumLength = value; }
}
public int MaximumLength
{
get { return _maximumLength; }
set { _maximumLength = value; }
}
public string ErrorMessage
{
get { return _errorMessage; }
set { _errorMessage = value; }
}
public override ValidationResult Validate(object value,
CultureInfo cultureInfo)
{
ValidationResult result = new ValidationResult(true, null);
string inputString = (value ?? string.Empty).ToString();
if (inputString.Length < this.MinimumLength ||
(this.MaximumLength > 0 &&
inputString.Length > this.MaximumLength))
{
result = new ValidationResult(false, this.ErrorMessage);
}
return result;
}
}
你需要在你的xaml中添加一个命名空间引用到验证类所在的地方,称为验证器(我确定你知道这一点,但仅仅是为了完整性)
像...一样的东西。
xmlns:validators="clr-namespace:WpfApplication1"
希望这有帮助!
干杯,
安迪
答案 1 :(得分:3)
同样,本周我完成了同样的事情!我在网上找到了以下内容,将文本框包装在此...
<validators:ValidatedContent Name="Validator" >
<!-- All your textboxes here -->
</validators:ValidatedContent>
将下面的类添加到您放置另一个的相同位置...然后您可以通过单击按钮或任何您想要的地方调用Validator.Validate()。您还可以使用IsContentValid属性来决定是否要保存等。
public class ValidatedContent : Decorator
{
#region Public Constructors
/// <summary>
/// Initializes a new instance of ValidatedContent
/// </summary>
public ValidatedContent()
{
ErrorMessages = new ObservableCollection<string>();
Loaded += new RoutedEventHandler(OnValidatedContentLoaded);
}
#endregion
#region Event Handlers
/// <summary>
/// Handles the loaded event
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnValidatedContentLoaded(object sender, RoutedEventArgs e)
{
Queue<DependencyObject> elementQueue = new Queue<DependencyObject>();
elementQueue.Enqueue(this.Child);
// Iterate over all the child elements
while (elementQueue.Count > 0)
{
// Dequeue the first element in the queue
DependencyObject element = elementQueue.Dequeue();
if (element != null)
{
foreach (var childElement in LogicalTreeHelper.GetChildren(element))
{
if (childElement is DependencyObject)
elementQueue.Enqueue((DependencyObject)childElement);
}
}
Control control = element as Control;
// Mark the element as valid if it is a control
if (control != null && GetIsRequired(element))
{
control.SetValue(Control.StyleProperty, RequiredControlStyle);
}
}
}
#endregion
#region Dependency Properties
public static readonly DependencyProperty IsContentValidProperty =
DependencyProperty.Register("IsContentValid", typeof(bool),
typeof(ValidatedContent), new UIPropertyMetadata(false));
public static readonly DependencyProperty ErrorMessagesProperty =
DependencyProperty.Register("ErrorMessages", typeof(ObservableCollection<string>),
typeof(ValidatedContent), new UIPropertyMetadata(null));
public static readonly DependencyProperty RequiredControlStyleProperty =
DependencyProperty.Register("RequiredControlStyle", typeof(Style),
typeof(ValidatedContent), new UIPropertyMetadata(null));
public static readonly DependencyProperty IsRequiredProperty =
DependencyProperty.RegisterAttached("IsRequired", typeof(bool),
typeof(ValidatedContent), new UIPropertyMetadata(false));
#endregion
#region Public Properties
/// <summary>
/// Gets or sets the style to mark a required control
/// </summary>
public Style RequiredControlStyle
{
get { return (Style)GetValue(RequiredControlStyleProperty); }
set { SetValue(RequiredControlStyleProperty, value); }
}
/// <summary>
/// Gets or sets the error messages for the validated content
/// </summary>
public ObservableCollection<string> ErrorMessages
{
get { return (ObservableCollection<string>)GetValue(ErrorMessagesProperty); }
private set { SetValue(ErrorMessagesProperty, value); }
}
/// <summary>
/// Gets if the content is valid
/// </summary>
public bool IsContentValid
{
get { return (bool)GetValue(IsContentValidProperty); }
private set { SetValue(IsContentValidProperty, value); }
}
#endregion
#region Public Methods
/// <summary>
/// Validates the content of the decorator
/// </summary>
public void Validate()
{
IsContentValid = true;
ErrorMessages.Clear();
Queue<DependencyObject> elementQueue = new Queue<DependencyObject>();
elementQueue.Enqueue(this.Child);
// Iterate over all the child elements
while (elementQueue.Count > 0)
{
// Dequeue the first element in the queue
DependencyObject element = elementQueue.Dequeue();
foreach (var childElement in LogicalTreeHelper.GetChildren(element))
{
if (childElement is DependencyObject)
elementQueue.Enqueue((DependencyObject)childElement);
}
// Validate the bindings of the element
ValidateBindings(element);
}
}
#endregion
#region Private Methods
/// <summary>
/// Validates the bindings of the dependency object
/// </summary>
/// <param name="element"></param>
private void ValidateBindings(DependencyObject element)
{
if (element != null)
{
Type elementType = element.GetType();
FieldInfo[] dependencyPropertyFields = elementType.GetFields(
BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly);
// Iterate over all dependency properties
foreach (FieldInfo dependencyPropertyField in dependencyPropertyFields)
{
DependencyProperty dependencyProperty =
dependencyPropertyField.GetValue(element) as DependencyProperty;
if (dependencyProperty != null)
{
Binding binding = BindingOperations.GetBinding(element, dependencyProperty);
BindingExpression bindingExpression = BindingOperations.GetBindingExpression(element, dependencyProperty);
// Issue 1822 - Extra check added to prevent null reference exceptions
if (binding != null && bindingExpression != null)
{
// Validate the validation rules of the binding
foreach (ValidationRule rule in binding.ValidationRules)
{
ValidationResult result = rule.Validate(element.GetValue(dependencyProperty),
CultureInfo.CurrentCulture);
bindingExpression.UpdateSource();
if (!result.IsValid)
{
ErrorMessages.Add(result.ErrorContent.ToString());
}
IsContentValid &= result.IsValid;
}
}
}
}
}
}
#endregion
#region Static Methods
/// <summary>
/// Gets the value for the IsRequired attached property
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static bool GetIsRequired(DependencyObject obj)
{
return (bool)obj.GetValue(IsRequiredProperty);
}
/// <summary>
/// Sets the value for the IsRequired attached property
/// </summary>
/// <param name="obj"></param>
/// <param name="value"></param>
public static void SetIsRequired(DependencyObject obj, bool value)
{
obj.SetValue(IsRequiredProperty, value);
}
#endregion
}
答案 2 :(得分:0)
我也遇到了一些问题,所以我发布了我的解决方法,以防有人帮忙。 Text块中显示的消息不正确,因为代码中触发的Exception被包装到TargetInvocationException中。因此显示的错误消息是该异常之一,即“在调用目标处抛出了异常”。
您想要显示的异常实际上可以在TargetInvocationException的InnerException中访问,因此您可以在XAML中使用以下语句显示它消息
Text="{Binding ElementName=MyAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent.InnerException.Message}"
我很确定必须有一种方法,ErrorContent字段中包含的错误是正确的,但我还没有挖掘到足以理解的方法。