Можете ли вы использовать правило проверки привязки в пределах 1 строки в xaml?

#c# #wpf #validation #data-binding #datagridtextcolumn

#wpf #xaml

Вопрос:

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

Этот xaml, который я знаю, работает:

 <TextBox>
  <TextBox.Text>
    <Binding Path="Location" UpdateSourceTrigger="PropertyChanged">
      <Binding.ValidationRules>
        <domain:NotEmptyValidationRule ValidatesOnTargetUpdated="True"/>
      </Binding.ValidationRules>
    </Binding>
  </TextBox.Text>
</TextBox>
  

Но это довольно многословно. Я хотел бы сделать это способом, подобным этому…

 <TextBox Text={Binding Path=Location, UpdateSourceTrigger=PropertyChanged,
                       ValidationRules={domain:NotEmptyValidationRuleMarkup ValidateOnTargetUpdated=True}}"/>
  

Я создал класс с именем, NotEmptyValidationRuleMarkup который возвращает экземпляр NotEmptyValidationRule , и это вроде как работает. Проект отлично собран, он работает просто отлично, все работает именно так, как я ожидаю. Однако я больше не могу просматривать свое окно в конструкторе. Это выдает мне недопустимую ошибку разметки, потому что The property "ValidationRules" does not have an accessible setter. . И это правда, у ValidationRules нет установщика. Если я пытаюсь установить правила проверки с помощью кода на C #, я получаю ошибку компиляции. Но по какой-то причине, когда я назначаю его в XAML, он действительно создается и запускается просто отлично. Я в замешательстве. Есть ли способ заставить это работать, не поднимая дизайн моего окна?

Комментарии:

1. Давайте начнем с того, почему это работает в XAML … ValidationRules это коллекция, поэтому вместо вызова ее установщика он просто Add добавит новые элементы в коллекцию. Я не знаю о переносе инициализации коллекции в расширение разметки.

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

Ответ №1:

Даже если интерпретатор xaml случайно превращает расширение разметки во что-то рабочее, на самом деле это не поддерживается.

Смотрите MSDN — Расширение разметки привязки

Ниже приведены свойства привязки, которые нельзя задать с помощью расширения разметки привязки / формы выражения{Binding}.

  • ValidationRules: свойство принимает общую коллекцию объектов ValidationRule. Это может быть выражено как элемент свойства в элементе объекта привязки, но не имеет легкодоступной техники синтаксического анализа атрибутов для использования в выражении привязки. Смотрите справочный раздел о правилах проверки.

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

 [ContentProperty("Binding")]
[MarkupExtensionReturnType(typeof(object))]
public class BindingEnhancementMarkup : MarkupExtension
{
    public BindingEnhancementMarkup()
    {

    }
    public BindingEnhancementMarkup(Binding binding)
    {
        Binding = binding;
    }

    [ConstructorArgument("binding")]
    public Binding Binding { get; set; }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        Binding.ValidationRules.Add(new NotEmptyValidationRule());
        return Binding.ProvideValue(serviceProvider);
    }
}
  

И используйте следующим образом:

 <TextBox Text="{local:BindingEnhancementMarkup {Binding Path=Location, UpdateSourceTrigger=PropertyChanged}}"/>
  

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

Комментарии:

1. Кстати: вы можете с таким же успехом расширить Binding и добавить туда правила проверки вместо того, чтобы оборачивать его.