我有一个数据绑定设置与转换器将一个尴尬的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)。它是从XSD生成的.NET类型。
SampleConverter实施IValueConverter
。调用Convert
方法并返回非空数据,但从不调用ConvertBack
方法。
SampleControl是一个UserControl,它封装了与Sample数据树的UI交互。它的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>
样品属性在后面的SampleControl代码的DependencyProperty:
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方法?
属性更改您的代码示例仅表示该样品的特性正在发生变化,而不是样品本身。 – Ragepotato 2011-06-15 20:52:30
@Ragepotato:你是说数据绑定只适用于新实例分配给Sample属性,但如果Sample属性引用的现有实例的属性发生更改并通过INotifyPropertyChanged发信号通知它们,则不适用? – dthorpe 2011-06-15 21:20:41
是的。该示例从未改变。它是同一个对象。它内的属性已更改。 你可以测试这个。在加载完所有内容后,将一个按钮放在控件上,Sample从虚拟机获取它的初始分配。然后将Sample指定给新的SampleType。记住它必须是正确的类型,否则绑定引擎会忽略它。如果你设置好双向绑定,你会看到你的转换被调用。 – Ragepotato 2011-06-16 05:56:14