繁体   English   中英

简单的文本框文本绑定失败WPF

[英]Simple TextBox Text Binding Fails WPF

我们正在将一个应用程序从Silverlight转换为WPF。 这是一个相当复杂的应用程序,但是代码共享约为95%以上。 除了XML名称空间定义等之外,XAML几乎相同。现在大约90%的应用程序都可以运行,但是有一些明显的问题使我感到困惑。 一个就是这个有约束力的问题。

我们有一个名为TaskInfo的模型对象。 它具有一个称为TaskNo的属性。 在Silverlight和WPF中,我们像这样绑定到此属性

<TextBox IsReadOnly="True" Grid.Column="0"  Grid.Row="0" Margin="1" Text="{Binding Path=TaskNo}" Height="28"  Background="#CAECF4" VerticalAlignment="Center" VerticalContentAlignment="Center"  />

在WPF和Silverlight中,当TaskInfo模型首次设置为DataContext时,可以正确显示TaskNo。 在Silverlight中,如果我们创建一个新的TaskInfo,将其发送到服务器进行保存,然后返回带有新TaskNo的模型,则会成功显示TaskNo。 但是,在WPF中,从服务器返回保存的TaskInfo时,它仅显示0。 绑定存在一些问题。 这是我在输出窗口中看到的绑定错误:

System.Windows.Data信息:10:无法使用绑定来检索值,并且不存在有效的后备值;请参阅参考资料。 使用默认值代替。 BindingExpression:Path = TaskNo; DataItem = null; 目标元素是'TextBlock'(Name =''); 目标属性为“文本”(类型为“字符串”)

我检查了可视树,并按预期将TextBox的DataContext设置为TaskInfo。

因此,我关闭了绑定并尝试了此代码。 它是TextBox上DataContextChanging的事件处理程序。 此代码可以正常工作。 保存并返回新任务后,将在此处成功显示TaskNo:

    private void TaskNoBox_DataContextChanging(object sender, DependencyPropertyChangedEventArgs e)
    {
        var task = TaskNoBox.DataContext as TaskInfo;
        if (task == null)
        {
            throw new Exception("Ouch!");
        }
        TaskNoBox.Text = task.TaskNo.ToString();
    }

为了进一步调试此问题,我在文本框中为GotFocus事件添加了此事件处理程序。 因此,在将任务保存在服务器端并返回并设置为DataContext之后,单击控件内部以触发此事件处理程序。 当我单步执行此代码时,可以看到DataContext是正确的,并且具有正确的TaskNo。 调用此代码仍然不会导致绑定发生。

    private void TextBox_GotFocus(object sender, RoutedEventArgs e)
    {
        var textBox = (TextBox)sender;
        var be = textBox.GetBindingExpression(TextBox.TextProperty);
        be.UpdateSource();
        be.UpdateTarget();
    }

TextBox文本绑定属性: 在此处输入图片说明

TextBox属性的DataContext: 在此处输入图片说明

如何理解此绑定错误? Silverlight和WPF之间的绑定陷阱是什么? 我需要某种解决方法吗? 为什么绑定不起作用?

如果以前的DataContext根据Equals方法等效于新的DataContext,则WPF中的绑定永远不会更新。

Silverlight和WPF之间的区别似乎是,当DataContext更改时,WPF似乎使用Equals方法评估对象之间的差异,而Silverlight使用引用。 这意味着WPF与Xamarin.Forms相同。

我尝试了此代码,它导致TaskNo正确显示。 我认为正在发生的事情是因为调用Equals时,以前的DataContext等效于新的DataContext。 因此,这可以解决此问题。

    private async void TaskPageHeader_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        TaskNoBox.DataContext = new object();
        TaskNoBox.DataContext = CurrentTask;
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM