У меня есть привязка данных, настроенная с помощью конвертера, для преобразования неудобного источника XML в удобное для отображения и редактирования дерево внутренних классов. Все отлично работает для чтения из источника XML, но у меня дьявольское время, пытаясь заставить изменения, внесенные во внутренние классы, распространяться обратно в источник XML.
Вот XAML для сайта использования:
<local:SampleConverter x:Key="SampleConverter" />
<Expander Header="Sample" >
<local:SampleControl
Sample="{Binding Path=XmlSource,
Converter={StaticResource SampleConverter},
Mode=TwoWay}" />
</Expander>
XmlSource - это свойство чтения-записи CLR (не DependencyProperty) родительского объекта, связанного с данными. Это тип .NET, сгенерированный из XSD.
SampleConverter реализует IValueConverter
. Метод Convert
вызывается и возвращает ненулевые данные, но метод ConvertBack
никогда не вызывается.
SampleControl - это UserControl, который инкапсулирует взаимодействие пользовательского интерфейса с деревом данных образца. Это XAML выглядит так:
<UserControl x:Class="SampleControl">
[... other stuff ...]
<UserControl.Content>
<Binding Path="Sample" RelativeSource="{RelativeSource Mode=Self}" Mode="TwoWay" TargetNullValue="{StaticResource EmptySampleText}" />
</UserControl.Content>
<UserControl.ContentTemplateSelector>
<local:BoxedItemTemplateSelector />
</UserControl.ContentTemplateSelector>
</UserControl>
Свойство Sample является свойством DependencyProperty в коде SampleControl:
public static readonly DependencyProperty SampleProperty =
DependencyProperty.Register("Sample", typeof(SampleType), typeof(SampleControl), new PropertyMetadata(new PropertyChangedCallback(OnSampleChanged)));
public SampleType Sample
{
get { return (SampleType)GetValue(SampleProperty); }
set { SetValue(SampleProperty, value); }
}
private static void OnSampleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue != null)
{
((INotifyPropertyChanged)e.NewValue).PropertyChanged += ((SampleControl)d).MyPropertyChanged;
}
else if (e.OldValue != null)
{
((INotifyPropertyChanged)e.OldValue).PropertyChanged -= ((SampleControl)d).MyPropertyChanged;
}
}
private void MyPropertyChanged(object sender, PropertyChangedEventArgs e)
{
; // breakpoint here shows change notices are happening
}
Внутренние классы, которые XmlSource преобразует для реализации INotifyPropertyChanged и отправляют уведомления об изменениях вверх по дереву, как указано точкой останова в MyPropertyChanged выше.
Итак, если данные сообщают, что они изменились, почему WPF не вызывает метод ConvertBack моего конвертера?