c# - 与转换器的双向数据绑定(bind)不更新源

标签 c# wpf xaml data-binding two-way-binding

我已经设置了一个带有转换器的数据绑定(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 实现IValueConverterConvert 方法被调用并返回非空数据,但 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/

相关文章:

c# - LINQ 连接两个字符串数组中的元素

更改可见性时 WPF 触发动画?

c# - 如何在 XAML 代码中创建支持其中其他元素的 UserControl

c# - 绑定(bind)到项目而不是列表框中的属性

c# - 我应该如何阻止用户修改我的数据文件?

c# - ASP.NET MVC 2 - 绑定(bind)到抽象模型

c# - 具有虚拟化的 WPF TreeView - 选择项目并将其置于 View 中

c# - 附加属性绑定(bind)不起作用

c# - 如何在 Nuke.Build 6.2.1 中查找和使用 DotNetRestore、DotNetBuild 等方法

c# - 嵌套 UserControl 事件在 MVVM/WPF 场景中不适用于 EventTrigger/InvokeCommandAction