我已经设置了一个带有转换器的数据绑定(bind),可以将笨拙的 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 是父数据绑定(bind)对象的 CLR 读写属性(不是 DependencyProperty)。它是从 XSD 生成的 .NET 类型。
SampleConverter 实现IValueConverter
。 Convert
方法被调用并返回非空数据,但 ConvertBack
方法从未被调用。
SampleControl 是一个 UserControl,它封装了 UI 与 Sample 数据树的交互。它的 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属性是后面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 方法?
最佳答案
根据几个类似问题的提示和 SO 上的几乎答案,我有一个保留绑定(bind)的有效解决方案。您可以手动强制绑定(bind)在战略性放置的事件中更新源,例如 LostFocus:
private void mycontrol_LostFocus(object sender, RoutedEventArgs e)
{
if (mycontrol.IsModified)
{
var binding = mycontrol.GetBindingExpression(MyControl.SampleProperty);
binding.UpdateSource();
}
}
关于c# - 与转换器的双向数据绑定(bind)不更新源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6363883/