Система проверки WPF выполняет начальную проверку объекта (я имею в виду - все поля проверяются при изменении элемента данных, и результаты отображаются в пользовательском интерфейсе). Но это не работает, когда я динамически добавляю элемент управления. В таком случае происходит первоначальная проверка, но результаты не отображаются в пользовательском интерфейсе. Только после изменения некоторых свойств объекта с привязкой к данным все начинает работать корректно. Вот грубый образец.
Предположим, у нас есть класс MyObject
public class MyObject : INotifyPropertyChanged, IDataErrorInfo
{
public string Name { /*get, set implementation */}
// IDataErrorInfo
public string this[string columnName]
{
get
{
if (String.IsNullOrEmpty(Name)) return "Name can't be empty!";
return String.Empty;
}
}
/* etc. */
}
И некоторый пользовательский элемент управления, скажем, MyUserControl, который позволяет редактировать объекты MyObject. Это может выглядеть как-то так:
<UserControl x:Class="Test.MyUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Name: "/>
<TextBox Text="{Binding Name, ValidatesOnDataErrors=True}" Width="200"/>
</StackPanel>
</UserControl>
Теперь, когда этот элемент управления добавляется в главное окно в xaml (или в коде позади конструктора или события загрузки окна), чем когда MyCustomControl.DataContext установлен в новый экземпляр класса MyObject, поле Name проверяется немедленно и уведомление об ошибке отображается с использованием шаблона ошибки проверки. Но когда MyCustomControl добавляется динамически (скажем, после нажатия кнопки), происходит начальная проверка, но пользовательский интерфейс не показывает результаты (без красной рамки и т. д.)
Предположим, что окно приложения состоит из док-панели (dockPanel) и кнопки:
public Window1()
{
InitializeComponent();
button.Click +=new RoutedEventHandler(OnButtonClick);
/*
// in this case validation works correctly,
// when window is shown Name textbox already got a red border etc.
var muc = new MyUserControl();
dockPanel.Children.Add(muc);
muc.DataContext = new MyObject();
*/
}
private void OnButtonClick(object sender, RoutedEventArgs e)
{
// in this case validatation works, but no results are shown on the ui
// only after Name property is changed (then removed again) red border appears
var muc = new MyUserControl();
dockPanel.Children.Add(muc);
muc.DataContext = new MyObject();
}
Почему?