[英]Why does WPF Style to show validation errors in ToolTip work for a TextBox but fails for a ComboBox?
I am using a typical Style to display validation errors as a tooltip from IErrorDataInfo for a textbox as shown below and it works fine.我正在使用典型的样式将验证错误显示为来自 IErrorDataInfo 的文本框的工具提示,如下所示,它工作正常。
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self},
Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
But when i try to do the same thing for a ComboBox like this it fails但是当我尝试为这样的 ComboBox 做同样的事情时,它失败了
<Style TargetType="{x:Type ComboBox}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self},
Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
The error I get in the output window is:我在输出窗口中得到的错误是:
System.Windows.Data Error: 17 : Cannot get 'Item[]' value (type 'ValidationError') from '(Validation.Errors)' (type 'ReadOnlyObservableCollection`1'). System.Windows.Data 错误:17:无法从“(Validation.Errors)”(类型“ReadOnlyObservableCollection`1”)获取“Item[]”值(类型“ValidationError”)。 BindingExpression:Path=(0)[0].ErrorContent;
BindingExpression:Path=(0)[0].ErrorContent; DataItem='ComboBox' (Name='ownerComboBox');
DataItem='ComboBox' (Name='ownerComboBox'); target element is 'ComboBox' (Name='ownerComboBox');
目标元素是 'ComboBox' (Name='ownerComboBox'); target property is 'ToolTip' (type 'Object') ArgumentOutOfRangeException:'System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.Parameter name: index'
目标属性是“工具提示”(类型“对象”)ArgumentOutOfRangeException:'System.ArgumentOutOfRangeException:指定的参数超出了有效值的范围。参数名称:索引'
Oddly it also attempts to make invalid Database changes when I close the window if I change any ComboBox values (This is also when the binding error occurs)!!!奇怪的是,如果我更改任何 ComboBox 值(这也是发生绑定错误时),当我关闭窗口时,它也会尝试进行无效的数据库更改!!!
Cannot insert the value NULL into column 'EmpFirstName', table 'OITaskManager.dbo.Employees';无法将值 NULL 插入列“EmpFirstName”、表“OITaskManager.dbo.Employees”; column does not allow nulls.
列不允许空值。 INSERT fails.
插入失败。 The statement has been terminated.
该语句已终止。
Simply by commenting the style out everyting works perfectly.只需将样式注释掉,一切都完美无缺。 How do I fix this?
我该如何解决?
Just in case anyone needs it one of the comboBox' xaml follows:以防万一有人需要它,comboBox 的 xaml 之一如下:
<ComboBox ItemsSource="{Binding Path=Employees}"
SelectedValuePath="EmpID"
SelectedValue="{Binding Path=SelectedIssue.Employee2.EmpID,
Mode=OneWay, ValidatesOnDataErrors=True}"
ItemTemplate="{StaticResource LastNameFirstComboBoxTemplate}"
Height="28" Name="ownerComboBox" Width="120" Margin="2"
SelectionChanged="ownerComboBox_SelectionChanged" />
<DataTemplate x:Key="LastNameFirstComboBoxTemplate">
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{1}, {0}" >
<Binding Path="EmpFirstName" />
<Binding Path="EmpLastName" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
SelectionChanged: (I do plan to implement commanding before long but, as this is my first WPF project I have not gone full MVVM yet. I am trying to take things in small-medium sized bites) SelectionChanged :(我确实计划在不久之后实施命令,但是,由于这是我的第一个 WPF 项目,我还没有完全使用 MVVM。我正在尝试以中小型方式进行操作)
// This is done this way to maintain the DataContext Integrity
// and avoid an error due to an Object being "Not New" in Linq-to-SQL
private void ownerComboBox_SelectionChanged(object sender,
SelectionChangedEventArgs e)
{
Employee currentEmpl = ownerComboBox.SelectedItem as Employee;
if (currentEmpl != null &&
currentEmpl != statusBoardViewModel.SelectedIssue.Employee2)
{
statusBoardViewModel.SelectedIssue.Employee2 = currentEmpl;
}
}
Your getting this error because when you validation finds that there are no issues, the Errors collection returns with no items, and the following binding logic fails:您收到此错误是因为当您验证发现没有问题时,Errors 集合返回时没有任何项目,并且以下绑定逻辑失败:
Path=(Validation.Errors)[0].ErrorContent}"
you are accessing the validation collection by a specific index.您正在通过特定索引访问验证集合。 I'm currently working on a DataTemplate Suggestion for replacing this text.
我目前正在研究用于替换此文本的 DataTemplate 建议。
I love that Microsoft listed this in their standard example of a validation template.我喜欢微软在他们的验证模板标准示例中列出了这一点。
update so replace the code above with the following, and the binding logic will know how to handle the empty validationresult collection:更新因此将上面的代码替换为以下代码,绑定逻辑将知道如何处理空的验证结果集合:
Path=(Validation.Errors).CurrentItem.ErrorContent}"
(following xaml was added as a comment) (以下 xaml 被添加为评论)
<ControlTemplate x:Key="ValidationErrorTemplate" TargetType="Control">
<StackPanel Orientation="Horizontal">
<TextBlock Foreground="Red" FontSize="24" Text="*"
ToolTip="{Binding .CurrentItem}">
</TextBlock>
<AdornedElementPlaceholder>
</AdornedElementPlaceholder>
</StackPanel>
</ControlTemplate>
Update in 2019 2019年更新
As of currently, the correct path syntax to use is:目前,要使用的正确路径语法是:
Path=(Validation.Errors)/ErrorContent
I think this is the best way:我认为这是最好的方法:
Path=(Validation.Errors)/ErrorContent
/
is actually equal to CurrentItem
by @Nathan /
实际上等于 @Nathan 的CurrentItem
In my case, CurrentItem
is a no go.就我而言,
CurrentItem
是不行的。
尝试将转换器转换为多行字符串,如here所述
In my case, I was getting this exception when I tried to apply @Nation Tregillus ' solution:就我而言,当我尝试应用@Nation Tregillus的解决方案时遇到了这个异常:
Cannot resolve property 'CurrentItem' in data context of type 'System.Collections.ObjectModel.ReadOnlyObservableCollection'
无法在“System.Collections.ObjectModel.ReadOnlyObservableCollection”类型的数据上下文中解析属性“CurrentItem”
So I went with @Altiano Gerung 's solution instead, where my code ended up being:所以我改用 @Altiano Gerung的解决方案,我的代码最终是:
<ControlTemplate x:Key="ValidationErrorTemplate">
<DockPanel Margin="5,0,36,0">
<StackPanel Orientation="Horizontal" VerticalAlignment="Top" DockPanel.Dock="Right"
Margin="5,0,36,0"
ToolTip="{Binding ElementName=ErrorAdorner, Path=AdornedElement.(Validation.Errors)/ErrorContent}"
ToolTipService.ShowDuration="300000"
ToolTipService.InitialShowDelay="0"
ToolTipService.BetweenShowDelay="0"
ToolTipService.VerticalOffset="-75"
>
I've seen the code you're using posted in multiple places, but it seems odd to me that我已经看到您在多个地方发布的代码,但对我来说似乎很奇怪
Path=(Validation.Errors)[0].ErrorContent}
doesn't raise any red flags.不会引发任何危险信号。 But I'm also new to WPF and perhaps there is some secret to making that work in every case.
但我也是 WPF 的新手,也许在每种情况下都可以使用一些秘诀。
Rather than attempting to index a possibly empty collection with an array index, add a converter that returns the first error in the list.与其尝试使用数组索引对可能为空的集合进行索引,不如添加一个返回列表中第一个错误的转换器。
CurrentItem did not work for me either But @Nathtan's answer worked for my situation where I have a custom textBox resource. CurrentItem 对我也不起作用但是@Nathtan 的回答适用于我有自定义 textBox 资源的情况。 Thanks @Nathan I spent an hour on this.
谢谢@Nathan 我花了一个小时来解决这个问题。
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={x:Static RelativeSource.Self},
Path=(Validation.Errors)/ErrorContent}" />
</Trigger>
</Style.Triggers>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.