Доступ к ошибкам проверки INotifyDataErrorInfo из шаблона ошибки XAML с использованием композиции

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

Я создал конкретную реализацию INotifyDataErrorInfo, которую я могу включить в свои модели представлений, требующие проверки (включен только соответствующий код):

public class NotifyDataErrorInfo : INotifyDataErrorInfo
{
    public readonly Dictionary<string, string> ValidationErrorsByPropertyName = new Dictionary<string, string>();

    public IEnumerable GetErrors(string propertyName)
    {
        ...
    }

    public bool HasErrors { get; }
    public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
}

Когда MyViewModel имеет ошибки проверки, он получает/устанавливает их через экземпляр объекта NotifyDataErrorInfo. (В моей первоначальной версии ViewModel реализовал INotifyDataErrorInfo. Это больше не так, поскольку я пытаюсь добиться тех же результатов с помощью композиции.)

public class MyViewModel : ViewModel
{
    public NotifyDataErrorInfo NotifyDataErrorInfo { get; } = new NotifyDataErrorInfo();
}

Вот текстовое поле, которое сообщает об ошибках проверки в установщике свойства MaxDaysText и задает шаблон ошибки проверки.

<TextBox        
    Text="{Binding MaxDaysText, UpdateSourceTrigger=PropertyChanged}"
    Validation.ErrorTemplate="{StaticResource TextBoxValidationErrorTemplate}" />

Теперь мне нужно обновить шаблон ошибки проверки, чтобы получить доступ к ошибкам в свойстве NotifyDataErrorInfo, но я не знаю, как это сделать.

<ControlTemplate x:Key="TextBoxValidationErrorTemplate">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Border
            Grid.Row="0"
            HorizontalAlignment="Left"
            BorderBrush="{StaticResource ErrorMessageBorderBrush}"
            BorderThickness="1">
            <AdornedElementPlaceholder x:Name="_adornedElementPlaceholder" />
        </Border>
        <ItemsControl
            Grid.Row="1"
            ItemsSource="{Binding}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <TextBox
                        Style="{StaticResource ErrorMessageStyle}"
                        Text="{Binding Path=ErrorContent, Mode=OneWay}" />
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>
</ControlTemplate>

Я попытался изменить все привязки для поиска NotifyDataErrorInfo, но безуспешно. Какие изменения мне нужно внести в шаблон, чтобы получить доступ к ошибкам проверки в свойстве NotifyDataErrorInfo MyViewModel?

РЕДАКТИРОВАТЬ: кажется, что в подходе композиции ErrorsChanged всегда имеет значение null, и представление никогда не уведомляется. Я предполагаю, что когда сама модель представления реализует INotifyDataErrorInfo, фреймворк назначает делегата с помощью ErrorsChangedEventManager. Но теперь я оставляю это в стороне. Таким образом, кажется, что композиция не будет работать для этого подхода. Верна ли эта оценка?


person NielW    schedule 01.02.2021    source источник


Ответы (1)


Свойство называется «NotifyDataErrorInfo», вам необходимо привязать ItemsSource к этому свойству.

<ItemsControl
            Grid.Row="1"
            ItemsSource="{Binding NotifyDataErrorInfo}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <TextBox
                        Style="{StaticResource ErrorMessageStyle}"
                        Text="{Binding Path=ErrorContent, Mode=OneWay}" />
                </DataTemplate>
            </ItemsControl.ItemTemplate>
 </ItemsControl>

Если шаблон управления не извлекает контекст данных, вам нужно добавить его.

<ControlTemplate DataContext={Binding DataContext, 
RelativeSource={RelativeSource AncestorType={x:Type views:YourView}}} x:Key="TextBoxValidationErrorTemplate">
person gadnandev    schedule 01.02.2021
comment
Благодарим за ваше предложение. Я попробовал это, но потом понял, что ErrorsChanged никогда не устанавливается. Смотрите мое последнее редактирование. Дайте мне знать, если у вас есть еще идеи. Спасибо! - person NielW; 02.02.2021