Подтвердить что ты не робот

Почему 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;
    }
}
4b9b3361

Ответ 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, и, возможно, есть секрет, чтобы эта работа работала в каждом случае.

Вместо того, чтобы пытаться индексировать возможную пустую коллекцию с индексом массива, добавьте конвертер, который возвращает первую ошибку в списке.