简单的文本框文本绑定失败 WPF
Simple TextBox Text Binding Fails WPF
我们正在将应用程序从 Silverlight 转换为 WPF。这是一个相当复杂的应用程序,但代码共享率约为 95% +。 XAML 几乎完全相同,除了 XML 命名空间定义等。现在大约 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,发送到服务器进行保存,并且return模型中有一个新的TaskNo,那么TaskNo就成功显示了。但是,在 WPF 中,当保存的 TaskInfo 从服务器 returned 时,它只显示 0。绑定有一些问题。这是我在输出 window:
中看到的绑定错误
System.Windows.Data Information: 10 : Cannot retrieve value using the
binding and no valid fallback value exists; using default instead.
BindingExpression:Path=TaskNo; DataItem=null; target element is
'TextBlock' (Name=''); target property is 'Text' (type 'String')
我检查了可视化树,TextBox 的 DataContext 按预期设置为 TaskInfo。
所以,我关闭了绑定并尝试了这段代码。它是 TextBox 上 DataContextChanging 的事件处理程序。此代码工作正常。保存新任务并 returned 时,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 事件添加了这个事件处理程序。因此,在任务保存在服务器端并被 returned 并设置为 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;
}
我们正在将应用程序从 Silverlight 转换为 WPF。这是一个相当复杂的应用程序,但代码共享率约为 95% +。 XAML 几乎完全相同,除了 XML 命名空间定义等。现在大约 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,发送到服务器进行保存,并且return模型中有一个新的TaskNo,那么TaskNo就成功显示了。但是,在 WPF 中,当保存的 TaskInfo 从服务器 returned 时,它只显示 0。绑定有一些问题。这是我在输出 window:
中看到的绑定错误System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=TaskNo; DataItem=null; target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
我检查了可视化树,TextBox 的 DataContext 按预期设置为 TaskInfo。
所以,我关闭了绑定并尝试了这段代码。它是 TextBox 上 DataContextChanging 的事件处理程序。此代码工作正常。保存新任务并 returned 时,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 事件添加了这个事件处理程序。因此,在任务保存在服务器端并被 returned 并设置为 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;
}