Почему WPF Style демонстрирует ошибки проверки в ToolTip для TextBox, но не работает для ComboBox?
Я использую типичный стиль для отображения ошибок проверки как всплывающую подсказку из 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>
Но когда я пытаюсь сделать то же самое для 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>
Ошибка, которую я получаю в окне вывода:
Ошибка System.Windows.Data: 17: невозможно получить значение "Item []" (введите "ValidationError" ) из "(Validation.Errors)" (введите "ReadOnlyObservableCollection`1" ). BindingExpression: Путь = (0) [0].ErrorContent; DataItem = 'ComboBox' (Name= 'ownerComboBox'); целевым элементом является "ComboBox" (Name= "ownerComboBox" ); target property - это "ToolTip" (тип "Object" ). ArgumentOutOfRangeException: "System.ArgumentOutOfRangeException: указанный аргумент был вне диапазона допустимых значений .Parameter name: index '
Как ни странно, он также пытается сделать недопустимые изменения базы данных, когда я закрываю окно, если я изменяю любые значения ComboBox (это также происходит при ошибке привязки)!!!
Невозможно вставить значение NULL в столбец "EmpFirstName", таблицу "OITaskManager.dbo.Employees"; столбец не допускает нулей. INSERT терпит неудачу.
Заявление завершено.
Просто комментируя стиль, он отлично работает. Как это исправить?
На всякий случай, если кому-то это понадобится, один из 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: (Я планирую реализовать командование до конца, но, поскольку это мой первый проект 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;
}
}
Ответы
Ответ 1
Получив эту ошибку, потому что, когда вы проверяете, что нет проблем, коллекция ошибок возвращается без элементов, и следующая логика привязки не выполняется:
Path=(Validation.Errors)[0].ErrorContent}"
вы получаете доступ к коллекции проверки по определенному индексу. В настоящее время я работаю над предложением DataTemplate для замены этого текста.
Мне нравится, что Microsoft указала это в своем стандартном примере шаблона проверки.
поэтому замените приведенный выше код следующим, и логика привязки будет знать, как обрабатывать пустой сбор данных validationresult:
Path=(Validation.Errors).CurrentItem.ErrorContent}"
(после добавления xaml в качестве комментария)
<ControlTemplate x:Key="ValidationErrorTemplate" TargetType="Control">
<StackPanel Orientation="Horizontal">
<TextBlock Foreground="Red" FontSize="24" Text="*"
ToolTip="{Binding .CurrentItem}">
</TextBlock>
<AdornedElementPlaceholder>
</AdornedElementPlaceholder>
</StackPanel>
</ControlTemplate>
Ответ 2
Попробуйте конвертер для преобразования в многострочную строку, как описано здесь
Ответ 3
Я видел код, который вы используете, размещен в нескольких местах, но мне кажется странным, что
Path=(Validation.Errors)[0].ErrorContent}
не создает никаких красных флагов. Но я также новичок в WPF, и, возможно, есть секрет, чтобы эта работа работала в каждом случае.
Вместо того, чтобы пытаться индексировать возможную пустую коллекцию с индексом массива, добавьте конвертер, который возвращает первую ошибку в списке.