Microsoft-ui-xaml: Добавление поддержки проверки ввода в UWP с помощью INotifyDataErrorInfo

Созданный на 14 янв. 2019  ·  50Комментарии  ·  Источник: microsoft/microsoft-ui-xaml

Предложение: добавить поддержку проверки ввода с помощью INotifyDataErrorInfo

Резюме

Добавьте поддержку проверки ввода с помощью INotifyDataErrorInfo, которая поддерживается x:Bind и Binding. Оба расширения разметки должны получить новое свойство ValidatesOnNotifyDataErrors, которое, как и в привязке WPF, имеет значение true по умолчанию.

Обоснование

В настоящее время UWP не имеет встроенной проверки входных данных. Но каждое направление бизнес-приложения требует проверки ввода. Это одна из самых важных функций для правильного корпоративного приложения. На uservoice есть запись, в которой говорится, что эта функция будет поставляться с WinUI, но я еще ничего не видел: https://wpdev.uservoice.com/forums/110705-universal-windows-platform/suggestions/13052589-uwp-input -Проверка

feature proposal needs-winui-3 team-Markup

Самый полезный комментарий

INDEI требует от вас реализации всех ваших сущностей и подсущностей.

Можете ли вы рассказать об этом подробнее?

Используя правила, никаких изменений не требуется, все работает автоматически, используя только атрибуты проверки.

По большей части все это работает автоматически при использовании ValidationAttributes и INotifyDataErrorInfo . Я покажу здесь некоторые фрагменты кода, которые есть в спецификации, чтобы мы (надеюсь) были на одной странице.

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

public class ValidationBase : INotifyPropertyChanged, INotifyDataErrorInfo
{
   public event PropertyChangedEventHandler PropertyChanged;
   public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;

   protected void SetValue<T>(ref T currentValue, T newValue, [CallerMemberName] string propertyName = "")
   {
       if (!EqualityComparer<T>.Default.Equals(currentValue, newValue))
       {
           currentValue = newValue;
           OnPropertyChanged(propertyName, newValue);
       }
   }

   readonly Dictionary<string, List<ValidationResult>> _errors = new Dictionary<string, List<ValidationResult>>();
   public bool HasErrors
   {
       get
       {
           return _errors.Any();
       }
   }
   public IEnumerable GetErrors(string propertyName)
   {
       return _errors[propertyName];
   }

   private void OnPropertyChanged(string propertyName, object value)
   {
       PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
       Validate(propertyName, value);
   }

   private void AddErrors(string propertyName, IEnumerable<ValidationResult> results)
   {
       if (!_errors.TryGetValue(propertyName, out List<ValidationResult> errors))
       {
           errors = new List<ValidationResult>();
           _errors.Add(propertyName, errors);
       }

       errors.AddRange(results);
       ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
   }

   private void ClearErrors(string propertyName)
   {
       if (_errors.TryGetValue(propertyName, out List<ValidationResult> errors))
       {
           errors.Clear();
           ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
       }
   }

   public void Validate(string memberName, object value)
   {
       ClearErrors(memberName);
       List<ValidationResult> results = new List<ValidationResult>();
       bool result = Validator.TryValidateProperty(
            value,
            new ValidationContext(this, null, null)
            {
                MemberName = memberName
            },
            results
            );

        if (!result)
        {
            AddErrors(memberName, results);
        }
    }
}

Затем ваша модель будет производной от этого класса и будет выглядеть так:

public class Person : ValidationBase
{
    private string name;
    [MinLength(4)]
    [MaxLength(6)]
    public string Name
    {   
        get { return name; }
        set { SetValue(ref name, value); }
    }
}

Предполагая, что для этого класса Person установлено свойство ViewModel в вашем Page , вы затем привязываетесь к нему, и проверка происходит автоматически:

<TextBox Text="{x:Bind ViewModel.Name, Mode=TwoWay}" />

Я понимаю, что это может немного отличаться от того, что вы делаете сегодня, но мы пытаемся не поддерживать два разных способа делать одно и то же, если нам это не нужно. Дайте мне знать, если это имеет смысл, или если вы думаете, что мы все еще что-то упускаем!

Все 50 Комментарий

@LucasHaines , как это связано с функциями проверки ввода, которые вы изучали?

@jevansaks Это напрямую связано с работой по проверке ввода, которую я излагаю.

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

image

Это тип проверки, упомянутый во время сборки 2018.

`
x:Name="UserName" Заголовок="Имя пользователя:"
Text="{x:Bind ViewModel.Person.UserName,
UpdateSourceTrigger=Измененное свойство,
Режим=Двусторонний}" />

x:Name="Пароль" Заголовок="Пароль:"
Password="{x:Bind ViewModel.Person.Password,
UpdateSourceTrigger=Потерянный фокус,
Режим=Двусторонний}"/>
`

@thomasclaudiushuber , насколько важно, по вашему мнению, сделать эту работу частью {Binding}? Я спрашиваю только потому, что технические проблемы там нетривиальны, а также потому, что он не может работать на более низком уровне. Наша первоначальная идея заключалась в том, чтобы просто поддерживать x:Bind, который потребует только изменений компилятора разметки и способен работать на более низком уровне.

Кроме того, мы планировали только поддержку парадигмы INotifyDataErrorInfo и DataAnnotations. Мы не собирались добавлять что-то аналогичное Binding.ValidationRules, и поэтому не чувствовали достаточной необходимости в ValidatesOnNotifyDataErrors.

Мы хотели бы получить ваши отзывы, поскольку мы продолжаем работать над этой функцией, чтобы она могла быть сделана правильно!

@стивенбрикс

Краткий ответ: Да, то, что вы думаете и планируете, звучит великолепно. Просто x:Bind подойдет, и просто INotifyDataErrorInfo тоже подойдет.

Длинная:

Просто х:Привязать? 👍

Во всех случаях WPF-LOB, о которых я могу думать, всегда была своего рода ViewModel, которая была известна во время компиляции, без утиного ввода, поэтому x: Bind в порядке. Я также написал {Binding} в этом выпуске, так как думал, что вы можете поддержать его, чтобы получить тот же синтаксис, что и в WPF. Но это скорее «приятно иметь», чем суперважно. И поскольку {Binding} и x:Bind - это две совершенно разные вещи за кулисами, а среда выполнения с {Binding} нетривиальна, как вы упомянули, забудьте о {Binding}. Я думаю, что иметь его только для x: Bind совершенно нормально, он будет работать для вариантов использования, которые я могу придумать. И из всех выступлений на конференциях, посвященных UWP и x:Bind, я могу сказать вам, что x:Bind — одна из самых любимых функций UWP среди всех разработчиков XAML, и я всем им говорил: «Предпочитайте x:Bind, а не Binding, где бы вы ни находились». может". :) Получение ошибок intellisense, perf, step-in-to-code и времени компиляции делает x:Bind новым значением по умолчанию в UWP, поэтому наличие поддержки проверки — это хорошо и хорошее решение imo.

Просто парадигма INotifyDataErrorInfo и DataAnnotations? 👍

Просто поддержка парадигмы INotifyDataErrorInfo и DataAnnotations звучит хорошо для меня. WPF не получает аннотации данных автоматически, вам нужно подключить их вручную в реализации INotifyDataErrorInfo с помощью класса Validator. Вы имеете в виду это, когда говорите «парадигма аннотаций данных», верно? Или вы планируете встроенную поддержку DataAnnotation, которая позволит разработчику просто поместить аннотацию к свойству, и это просто сработает? Как в ASP.NET Core MVC? Хотя это было бы здорово, я думаю, что в этом нет необходимости. Достаточно иметь классы ValidationContext, Validator и ValidationResult и другие классы из System.ComponentModel.DataAnnotations.

Добавить Binding.ValidationRules? Неееет ;-)

Нет, определенно не добавляйте это. INotifyDataErrorInfo достаточно, и это лучше всего. Я думаю, что никогда больше не использовал ValidationRules после того, как в WPF была добавлена ​​​​поддержка IDataErrorInfo (если я правильно помню, это было в .NET Framework 3.5). И когда INotifyDataErrorInfo был добавлен в .NET Framework 4.5, мои клиенты и я использовали этот интерфейс во всех проектах для проверки ввода. Поддержка только этого интерфейса в порядке.

Добавить ValidatesOnNotifyDataErrors? Нет, но...

Да, вам не нужно добавлять это. Но это не имеет ничего общего с Binding.ValidationRules. Это свойство напрямую связано с интерфейсом INotifyDataErrorInfo. В расширении разметки привязки WPF ValidatesOnNotifyDataErrors по умолчанию имеет значение true, что означает, что {Binding} выбирает реализованную проверку INotifyDataErrorInfo, если связанный объект реализует этот интерфейс. Если задать для свойства ValidatesOnNotifyDataErrors расширения разметки Binding значение false, то расширение разметки Binding не будет использовать реализацию INotifyDataErrorInfo для проверки. Итак, возможно, это не так сложно реализовать с помощью x:Bind, но, возможно, нам это не нужно. Так что нет, не делай этого. Это нормально, чтобы оставить это. Но позвольте мне описать сценарий, в котором мне это нужно было в прошлом:

Элементы управления WPF по умолчанию отображают красную рамку, которая определяется с помощью шаблона Validation.ErrorTemplate. Теперь предположим, что у вас есть реализация INotifyDataErrorInfo с классом, имеющим свойство FirstName. Это обязательно, поэтому вы возвращаете ошибку, если свойство FirstName имеет значение null или пусто. Теперь вы привязали TextBox к этому свойству FirstName. Когда пользователь удаляет это имя, появляется красная рамка. Отлично, именно то, что вы хотите. Но, возможно, у вас есть в другом месте пользовательского интерфейса другой элемент управления, который также привязан к свойству FirstName. Например, TextBlock в заголовке вкладки. WPF также будет отображать на этом TextBlock красную рамку, когда есть ошибка проверки. Но это может быть не то, что вы хотите. Вам нужна ошибка только в текстовом поле, где пользователь может изменить имя, но не в текстовом блоке в заголовке вкладки. Чтобы избавиться от красной рамки в TextBlock, вам не нужно редактировать ErrorTemplate TextBlock, вместо этого вы просто включаете проверку INotifyDataErrorInfo в TextBlock-FirstName-Binding, задав для свойства ValidatesOnNotifyDataErrors значение false. Это единственный вариант использования этого свойства, который у меня когда-либо был. :)

Надеюсь, это поможет.

Резюме

Да, я полностью согласен, иметь проверку ввода только на x: Bind с поддержкой INotifyDataErrorInfo — хороший план.

Нет, это фантастический план, я уже очень взволнован!

@thomasclaudiushuber спасибо за подробное продолжение! Основные сценарии, которые вы описываете, совпадают с тем, что мы считаем реальной движущей силой, и это приятно слышать. Общий дизайн этой функции и API постоянно менялся, в основном из-за предыдущей работы над WPF. Здесь нужно было отметить несколько основных моментов:

  1. Как обсуждалось выше, были некоторые аспекты системы проверки WPF, которые, по нашему мнению, не добавляли никакой ценности или были заменены лучшими шаблонами, и поэтому мы не планировали переносить их в UWP.

  2. Некоторые функции/функции системы проверки WPF используют преимущества основных функций WPF, которых нет в UWP. Наиболее примечательным здесь является слой декоративных элементов, который позволяет любому UIElement в WPF отображать визуальные элементы проверки, а не только элементы управления (путем добавления некоторой части шаблона).

  3. UWP Xaml в настоящее время не имеет концепции прикрепленных событий, и зеркальное отображение класса Validation добавит событие Validation.Error. Не то, чтобы это нарушило договоренность, просто то, что нужно вызвать, поскольку мы обычно опасаемся добавления новых концепций, поскольку это только добавляет сложности. Вдобавок ко всему, поскольку работа требует изменений в шаблоне элемента управления, только набор элементов управления, для которых мы предоставляем конкретные изменения шаблона, будет работать из коробки. Вообще говоря, наличие API, который кажется работающим, но не работает в некоторых сценариях, не является хорошей практикой, и поэтому мы подумали, что было бы лучше отказаться от этой модели. Это означало бы иметь что-то еще, например, общий интерфейс и/или атрибуты, которые управляют орудием.

Мы все еще находимся в процессе понимания того, как проводить обзоры API и спецификаций в новом и захватывающем мире открытого исходного кода. Мы хотели бы получить отзывы сообщества, поэтому надеемся, что вскоре мы сможем опубликовать предложения API, чтобы сообщество могло взглянуть и помочь нам создать то, что всех волнует!

@stevenbrix Когда вы начнете спецификацию с открытым исходным кодом для функций проверки, предоставите ли вы иллюстрации того, как будет выглядеть проверка, а также примеры сценариев, чтобы разговор мог быть немного шире для тех из нас, кто больше интересуется пользовательским интерфейсом. , чем кодирование :)

@mdtauk Абсолютно. Текущий пользовательский интерфейс, которым мы поделились, по-прежнему точен. Если у вас есть отзывы, не стесняйтесь оставлять их в этой теме.

@LucasHaines Пользовательский интерфейс мне нравится. Но интересно, как можно настроить отображение ошибок. Я ничего не нашел по этому поводу, и я не знаю, есть ли у вас уже чем поделиться в этой области. Будет ли что-то похожее на прикрепленное свойство Validation.ErrorTemplate из WPF?

Есть ли сроки, когда будет выпущена официальная спецификация/предложение для этого?
Что я могу сделать, чтобы это быстрее попало в продукт?

Я согласен с @mrlacey выше ... Я действительно мог бы использовать это сейчас, поэтому я рад помочь, где могу.

Мы работаем над открытой спецификацией, и я сообщу всем, что она доступна в репозитории спецификаций.

Вопрос: почему бы не поддерживать и IDataErrorInfo? Он поддерживается в стандарте .net, и было бы странно не поддерживать его? Это не должно влиять на производительность для людей, которые его не используют, поскольку можно даже проверить во время компиляции, какой интерфейс использовать для привязки?

Мы начали обзор открытых спецификаций для проверки входных данных в репозитории открытых спецификаций. https://github.com/Microsoft/microsoft-ui-xaml-specs/pull/26

Привет, ребята, как мы отслеживаем это - у нас есть ETA?

@knightmeister У нас есть открытая спецификация, созданная здесь . Пожалуйста, не стесняйтесь участвовать в обзоре и помогать формировать функцию. Мы планируем выпустить это как часть WinUI 3.0. Если вам нужна дополнительная информация о дорожной карте WinUI 3.0, ознакомьтесь с проблемой № 717.

Привет всем! Пожалуйста, взгляните на последние образцы в спецификации. @stevenbrix сделал несколько отличных обновлений образцов и ответил на другие отзывы.

Один вопрос: будет ли информация о проверке поступать в иерархию управления? Например, сможет ли элемент управления контейнера (например, TabView или Pivot) узнать, что есть дочерний элемент управления в недопустимом состоянии?

Подумайте о сложном представлении с несколькими элементами управления-контейнерами, где вы хотите выделить, какие части представления требуют внимания, например, изменив стиль заголовка сводки, когда какой-либо дочерний элемент управления находится в недопустимом состоянии.

Это критическая проблема для меня.
Вся моя система проверки XAML основана на правилах проверки WPF, она считывает модель поля и сущности из BindingExpression и создает правила проверки в соответствии с атрибутами проверки DA (см. это ).

Например, сможет ли элемент управления контейнера (например, TabView или Pivot) узнать, что есть дочерний элемент управления в недопустимом состоянии?

@tbolon да, это то, что можно сделать, хотя маловероятно, что в этих контейнерах для этого будет встроена поддержка. Мы думали о создании элемента управления Form , который бы имел эту встроенную функциональность, но, вероятно, на данный момент он находится в невыполненной работе. Как и в WPF, существует событие ValidationError (это имя может быть неправильным), которое срабатывает каждый элемент управления, когда он становится недействительным/действительным. Однако это событие не является маршрутизируемым, поэтому вам необходимо подписаться на каждый элемент, который вы хотите прослушать.

Вся моя система проверки XAML основана на правилах проверки WPF,

@weitzhandler в настоящее время мы не планируем добавлять что-то вроде ValidationRule в WinUI. Есть ли что-то, что использование этого дает вам использование ValidationAttributes и реализацию вашей модели INotifyDataErrorInfo ? Мне бы хотелось увидеть, как выглядят ваша модель и XAML, чтобы лучше понять ваш сценарий использования.

INDEI требует от вас реализации всех ваших сущностей и подсущностей.
Используя правила, никаких изменений не требуется, все работает автоматически, используя только атрибуты проверки.

INDEI требует от вас реализации всех ваших сущностей и подсущностей.

Можете ли вы рассказать об этом подробнее?

Используя правила, никаких изменений не требуется, все работает автоматически, используя только атрибуты проверки.

По большей части все это работает автоматически при использовании ValidationAttributes и INotifyDataErrorInfo . Я покажу здесь некоторые фрагменты кода, которые есть в спецификации, чтобы мы (надеюсь) были на одной странице.

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

public class ValidationBase : INotifyPropertyChanged, INotifyDataErrorInfo
{
   public event PropertyChangedEventHandler PropertyChanged;
   public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;

   protected void SetValue<T>(ref T currentValue, T newValue, [CallerMemberName] string propertyName = "")
   {
       if (!EqualityComparer<T>.Default.Equals(currentValue, newValue))
       {
           currentValue = newValue;
           OnPropertyChanged(propertyName, newValue);
       }
   }

   readonly Dictionary<string, List<ValidationResult>> _errors = new Dictionary<string, List<ValidationResult>>();
   public bool HasErrors
   {
       get
       {
           return _errors.Any();
       }
   }
   public IEnumerable GetErrors(string propertyName)
   {
       return _errors[propertyName];
   }

   private void OnPropertyChanged(string propertyName, object value)
   {
       PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
       Validate(propertyName, value);
   }

   private void AddErrors(string propertyName, IEnumerable<ValidationResult> results)
   {
       if (!_errors.TryGetValue(propertyName, out List<ValidationResult> errors))
       {
           errors = new List<ValidationResult>();
           _errors.Add(propertyName, errors);
       }

       errors.AddRange(results);
       ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
   }

   private void ClearErrors(string propertyName)
   {
       if (_errors.TryGetValue(propertyName, out List<ValidationResult> errors))
       {
           errors.Clear();
           ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
       }
   }

   public void Validate(string memberName, object value)
   {
       ClearErrors(memberName);
       List<ValidationResult> results = new List<ValidationResult>();
       bool result = Validator.TryValidateProperty(
            value,
            new ValidationContext(this, null, null)
            {
                MemberName = memberName
            },
            results
            );

        if (!result)
        {
            AddErrors(memberName, results);
        }
    }
}

Затем ваша модель будет производной от этого класса и будет выглядеть так:

public class Person : ValidationBase
{
    private string name;
    [MinLength(4)]
    [MaxLength(6)]
    public string Name
    {   
        get { return name; }
        set { SetValue(ref name, value); }
    }
}

Предполагая, что для этого класса Person установлено свойство ViewModel в вашем Page , вы затем привязываетесь к нему, и проверка происходит автоматически:

<TextBox Text="{x:Bind ViewModel.Name, Mode=TwoWay}" />

Я понимаю, что это может немного отличаться от того, что вы делаете сегодня, но мы пытаемся не поддерживать два разных способа делать одно и то же, если нам это не нужно. Дайте мне знать, если это имеет смысл, или если вы думаете, что мы все еще что-то упускаем!

Вы правы, но для этого требуется, чтобы ваши объекты не были POCO.
Я должен попробовать. Может быть не так уж плохо использовать класс EntityBase в бизнес-приложении. Я просто привык использовать POCO.

UWP не имеет *ИМЕЕТ валидацию* !!!!!!! Я только что начал проект. Вернемся к WPF через несколько лет.

@ rufw91 Я знаю, да?!

Каковы ваши временные ограничения? Первая реализация этого находится в альфа-версии WinUI3, и у нас должна быть предварительная версия для рабочего стола WinUI, которая скоро появится в периоде //Build. Планируем RTM'инг к концу года

UWP не имеет *ИМЕЕТ валидацию* !!!!!!! Я только что начал проект. Вернемся к WPF через несколько лет.

Я решил придерживаться WPF и в ближайшие годы. Я сделал все это (WPF, SL, WP, UWP и т. Д.), В конце концов, только 1 технология кажется надежной, а именно WPF. Возможно, через несколько лет было бы интересно проверить, где находится WinUI, но я устал переключаться на новые технологии и оставаться один в темноте. WPF является зрелым и прекрасно работает. Возможно, через несколько лет Windows как ОС вообще перестанет быть актуальной, так что давайте подождем этого, прежде чем делать какие-либо инвестиции в платформу.

Возможно, через несколько лет Windows как ОС вообще перестанет быть актуальной, так что давайте подождем этого, прежде чем делать какие-либо инвестиции в платформу.

Учитывая, что мы только что превысили 1 миллиард установок Windows 10, мне трудно поверить, что это когда-либо будет правдой. Но я определенно чувствую ваше разочарование и не виню вас за то, что вы остаетесь на WPF. FWIW, наша команда теперь становится владельцем WPF, поэтому дайте мне знать, если вы хотите, чтобы мы что-то сделали.

INDEI требует от вас реализации всех ваших сущностей и подсущностей.

Можете ли вы рассказать об этом подробнее?

С моим кодом все объекты POCO могут оставаться свободными от реализации этих интерфейсов и оставаться без базового класса. INPC автоматически реализуется с помощью Fody. Больше всего я бы реализовал IValidatableObject , когда требуется более точная проверка. И это работает и с подтипами.

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

Это не хорошо. Что, если у моих сущностей уже есть базовый класс? Вот почему я не такой большой поклонник INotifyDataErrorInfo . Свойства INPC уже сами по себе являются головной болью, особенно при работе с приложениями с массивными данными с множеством сущностей.

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

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

Да, именно поэтому мы работаем над этим :)

Это не хорошо. Что, если у моих сущностей уже есть базовый класс?

Я просто пытаюсь понять ваше использование здесь. Что такое базовый класс и может ли он быть производным от этого класса?

Да, именно поэтому мы работаем над этим :)

Спасибо, очень признателен. Это и остальные ваши работы.
Что означает ярлык need-winui-3 ?

Я просто пытаюсь понять ваше использование здесь. Что такое базовый класс и может ли он быть производным от этого класса?

Я использую OData Connected Service для получения сущностей, созданных на моем клиенте.
Сгенерированные объекты имеют следующий шаблон:

c# public abstract partial class ContactBase : Microsoft.OData.Client.BaseEntityType, INotifyPropertyChanged

Что означает ярлык need-winui-3?

@weitzhandler
Это означает, что входная проверка будет поставляться с WinUI 3. (3.0, как в настоящее время планируется). Вероятно, это не коснется WinUI 2, поскольку для этого потребуются изменения в XAML-коде ОС, который сейчас находится в режиме обслуживания.

Я использую UWP в приложении Uno Platform. Надеюсь, WinUI будет покрыт после его выпуска.
Спасибо за обновление!

Я просто пытаюсь понять ваше использование здесь. Что такое базовый класс и может ли он быть производным от этого класса?

Наличие базового класса часто требуется третьей стороной, например используемой вами структурой постоянства. UWP/WinUI также не требует базового класса только для проверки. Это должен быть интерфейс, чтобы быть полезным, ни одно из наших приложений не может использовать базовый класс. (Это не означает, что у вас не может быть базового класса для людей, которые хотят его использовать, просто он должен быть необязательным, а не единственным способом проверки.)

Наличие базового класса часто требуется третьей стороной, например используемой вами структурой постоянства. UWP/WinUI также не требует базового класса только для проверки. Это должен быть интерфейс, чтобы быть полезным, ни одно из наших приложений не может использовать базовый класс.

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

Все, что потребуется модели, — это реализовать System.ComponentModel.INotifyDataErrorInfo (или Windows.UI.Xaml.Data.INotifyDataErrorInfo для C++). Компилятор правильно сгенерирует код для подключения к вашему представлению при использовании {x:Bind} .

Класс ValidationBase , о котором я упоминал выше, является вспомогательным классом, который мы планировали добавить в инструментарий сообщества, реализующий это, вместе с классом INotifyPropertyChanged . Нет необходимости извлекать из него, если ваш вариант использования не позволяет этого.

Спасибо за ваше разъяснение @stevenbrix.

А как насчет атрибутов проверки и IValidatableObject , будут ли они учитываться средой выполнения UWP?

Как насчет других атрибутов, таких как атрибут MaxLength , о котором вы упоминали ранее, будет ли максимальная длина TextBox устанавливаться автоматически, как в ASP.NET?
То же самое с DataTypeAttribute , EditableAttribute .
Также DisplayAttribute для создания заголовков полей.
Насколько я помню, все они поддерживались в Silverlight.

(см. это ).

А как насчет атрибутов проверки и IValidatableObject, будут ли они учитываться средой выполнения UWP?

Итак, в настоящее время мы собираемся поддерживать атрибут Required . Некоторые элементы управления автоматически помещают небольшую звездочку рядом с текстом заголовка, когда это используется. Мы открыты для поддержки в будущем, если вы хотите. Пожалуйста, откройте отдельную проблему, если вы хотите увидеть больше, и просто для того, чтобы установить ожидания, любая дополнительная поддержка атрибутов вряд ли появится в первоначальном выпуске WinUI3.

Что касается IValidatableObject , я не уверен, как это сработает. Обобщая, наш движок работает, просто прослушивая событие INotifyDataErrorInfo.ErrorsChanged . Фактическая проверка модели зависит от разработчика приложения и обычно выполняется при передаче значения из цели в источник.

Возможно, в качестве альтернативы методу ValidationBase , который вы предложили, должен быть набор методов расширения, которые запускают процесс проверки с использованием Validator.TryValidateObject и вводят результаты проверки в объект, уведомляя об изменениях. ?
Таким образом, этого можно легко достичь, просто реализовав INotifyDataErrorInfo . У нас также может быть интерфейс, наследуемый от INotifyDataErrorInfo , который добавляет свойство, содержащее набор ошибок, чтобы среда выполнения UWP или набор инструментов могли вместо этого распознавать автоматически проверяемый объект и автоматически устанавливать свойство, если оно реализовано.

Может быть, в качестве альтернативы предложенному вами методу ValidationBase должен быть набор методов расширения, которые запускают процесс проверки с использованием Validator.TryValidateObject и вводят результаты проверки в объект, уведомляя об изменениях?

Эта великолепная идея :)

🦙 Хотите знать, могут ли здесь помочь новые парадигмы генератора исходного кода?

Да, @michael-hawker, мне нравятся твои мысли!

У меня были те же мысли некоторое время назад, когда я впервые прочитал о новых возможностях генератора исходного кода.

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

У меня есть курс WPF на Pluralsight, который делает именно это с T4, INotifyPropertyChanged и INotifyDataErrorInfo, включая аннотации данных для проверки: https://www.pluralsight.com/courses/wpf-mvvm-advanced-model-treatment
Курс также использует настраиваемые вложенные свойства для подключения вещей.
Цель этого курса — показать, как вы можете создать приложение MVVM WPF, которое показывает в каждом поле ввода, было ли оно изменено, и каково было исходное значение.

Так что, определенно, генерировать что-то и, возможно, в итоге получить библиотеку (возможно, как часть WCT) было бы здорово. И я бы с удовольствием переделал этот курс для WinUI. :)

@ rufw91 Я знаю, да?!

Каковы ваши временные ограничения? Первая реализация этого находится в альфа-версии WinUI3, и у нас должна быть предварительная версия для рабочего стола WinUI, которая скоро появится в периоде //Build. Планируем RTM'инг к концу года

@stevenbrix Надеюсь, мне пришлось вернуться к WPF, на самом деле я почти закончил.

Я открыл этот .

В продолжение этого, после разговора с @stevenbrix в Твиттере, я интегрировал базовую реализацию INotifyDataErrorInfo , которую он предоставил здесь , в новый класс ObservableValidator , включенный в новый набор инструментов MVVM (название Microsoft.Toolkit.Mvvm ), которая также реализует INotifyPropertyChanged и INotifyPropertyChanging 😄

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

Не могли бы вы дать нам обновленную информацию об этом? Любопытно, поддерживает ли UWP 10.0 18362 INotifyDataErrorInfo . Согласно следующей странице документации https://docs.microsoft.com/en-us/dotnet/api/system.componentmodel.inotifydataerrorinfo?view=netcore-3.1 INotifyDataErrorInfo «применяется» к UWP 10.0. Однако при установленной и целевой версии UWP 10.0 18362 в текстовых полях не отображаются проверки INotifyDataErrorInfo . Текстовые поля описаны в XAML следующим образом:

<TextBox Text="{x:Bind ViewModel.Username, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

И мы используем ReactiveValidationObject как реализацию INotifyDataErrorInfo здесь.

@worldbeater это доступно только в последних предварительных версиях WinUI3, вы используете это?

Спасибо @stevenbrix! Собираюсь попробовать WinUI3. Рад слышать, что INotifyDataErrorInfo и UWP наконец подружились ✨

@worldbeater , это все еще предварительный просмотр, поэтому мы будем рады получить ваши отзывы о нем! 💪

Кстати, @worldbeater , в документах говорится, что он доступен в UWP 10.0, но это не значит, что он им поддерживается. Документация недостаточно ясна.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги