#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
и добавить туда правила проверки вместо того, чтобы оборачивать его.