从字符串到TextBox的XAML绑定不起作用

我是一名C#新手,他在理解为什么他第一次尝试理解XAML绑定无法正常工作时遇到了问题。 我正在关注微软的数据绑定概述 。

我有一个TextBox,最终将作为状态窗口。 现在我只想能够将任意文本字符串写入其中。 我还有一个我正在测试的命令模式的实例。 我的命令涉及向累加器添加随机数并将结果打印到状态视图。

这是我的主应用程序窗口的XAML:

         

而代表我数据的类:

 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Experiment { public class StatusViewText { public StringBuilder statusText { get; set; } public String statusTextString { get; set; } public StatusViewText() { statusText = new StringBuilder(); } public void Append(string s) { if (s != null) { statusText.Append(s); } statusTextString = statusText.ToString(); } public void AppendLine(string s) { if (s != null) { statusText.AppendLine(s); } statusTextString = statusText.ToString(); } } } 

最后我会在StringBuilder中使用一个合适的转换器,但是我想在探索这种复杂性之前先解决这个问题。

如果我的理解是正确的(显然不是),这一切都应该有效。 绑定目标是TextBox,target属性是Text属性。 绑定源是StatusViewText类的statusTextString属性。 然而,当我运行命令(并调试并查看正在更新的StatusViewText.statusTextString)时,TextBox不会更新。

我认为我可能需要自己显式添加绑定,所以我尝试在主窗口构造函数中的InitializeComponent()之后添加它:

  statusViewText = new StatusViewText(); Binding statusViewTextBinding = new Binding("statusTextString"); statusViewTextBinding.Source = statusViewText; statusText.SetBinding(TextBlock.TextProperty, statusViewTextBinding); 

但那也不起作用。

我是否需要触发PropertyChanged事件? 我认为绑定框架的全部内容是事件在幕后自动触发和消耗; 但也许我也错了。

输出窗口中没有明显的错误,这让我相信我的绑定语法是正确的; 我只是遗漏了别的东西。

HALP!

编辑13:14 EDT谢谢mben

好的,我做到了。 添加以下内容:

 public class StatusViewText : INotifyPropertyChanged { public void Append(string s) { if (s != null) { statusText.Append(s); } statusTextString = statusText.ToString(); NotifyPropertyChanged("statusTextString"); } public void AppendLine(string s) { if (s != null) { statusText.AppendLine(s); } statusTextString = statusText.ToString(); NotifyPropertyChanged("statusTextString"); } public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(String info) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(info)); } } } 

我调试validation它是通过这个代码路径,它是。 但仍然没有运气。 还有其他想法吗?

您仍需要在StatusViewText上实现INotifyPropertyChanged。 绑定系统不会持续检查值,您需要在事情发生变化时通知它。

以下是您必须应用的更改才能使其正常工作。

这是ViewModel的代码:

 public class StatusViewText : INotifyPropertyChanged { public StatusViewText() { // At least, I have a default value this.StatusTextString = "Hello world"; } public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged(string propertyName) { if (this.PropertyChanged != null) this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } private string statusTextString; public string StatusTextString { get { return this.statusTextString; } set { this.statusTextString = value; this.OnPropertyChanged("StatusTextString"); } } } 

您必须指定窗口的DataContext。 代码隐藏是一个解决方案:在MainWindow的ctor中,填写数据上下文:

 this.DataContext = new StatusViewText(); 

在XAML中,您应该说明对属性StatusTextString的绑定。 它的工作原理是因为数据上下文是StatusViewText的一个实例。

 Text="{Binding Path=StatusTextString}" 

请注意,您在代码中创建的实例与Xaml中表达的实例不同。 您可以通过在StatusViewText的构造函数中设置断点来certificate这一点。

将此片段放入MainWindow的构造函数中……

  StatusViewText o = (StatusViewText)FindResource("statusViewText") as StatusViewText; if(o!=null) { o.Append("hello"); } 

这将影响您的类的正确实例。

你也应该改变你的课程,看起来像这样……

 public class StatusViewText:INotifyPropertyChanged { public StringBuilder statusText { get; set; } private string _statusTextString; public String statusTextString { get { return _statusTextString; } set { _statusTextString = value; OnPropertyChanged("statusTextString"); } } public StatusViewText() { statusText = new StringBuilder(); } public void Append(string s) { if (s != null) { statusText.Append(s); } statusTextString = statusText.ToString(); } public void AppendLine(string s) { if (s != null) { statusText.AppendLine(s); } statusTextString = statusText.ToString(); } public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged(string prop) { if(PropertyChanged!=null) { PropertyChanged(this, new PropertyChangedEventArgs(prop)); } } }