数据绑定到WPF中的方法

我无法将TextBox.Text属性数据绑定到对象的方法。 这个想法是允许用户在TextBox写入一个文件名,然后使用TextBlock输出该文件的扩展名。

 class GetFileInfo { public string GetFileExtension(string fileName) { return Path.GetExtension(fileName); } } 

这是我的XAML:

    abc.text            

由于某种原因,它没有做任何事情。 任何可以指出可能是什么原因? 这是我在设计师和运行应用程序时看到的内容:

替代文字http://img64.imageshack.us/img64/6922/f0rki14feo3oa3groxm5kgm.png

以下是我在运行时尝试设置其他文本时会发生的情况:

alt text http://img684.imageshack.us/img684/1057/b52pnq1dm4i23qivizvpaqq.png以下是de debugger在运行时尝试设置其他文本时给出的错误:

System.Windows.Data错误:8:无法将目标值保存到源。 BindingExpression:路径= MethodParameters [0]; DataItem =’ObjectDataProvider’(HashCode = 2207369); target元素是’TextBox’(Name =’textBox1’); target属性为’Text’(类型’String’)ArgumentException:’System.ArgumentException:’MS.Internal.Data.PropertyPathWorker + IListIndexerArg’类型的对象无法转换为’System.Int32’类型。 System.Reflection.MethodBase.CheckArguments(Object [])中System.RuntimeType.CheckValue(对象值,Binder活页夹,CultureInfo文化,BindingFlags invokeAttr)的System.RuntimeType.TryChangeType(Object value,Binder binder,CultureInfo culture,Boolean needsSpecialCast) System.Reflection.RuntimeMethodInfo中的System.Reflection.RuntimeMethodInfo.Invoke(Object obj,BindingFlags invokeAttr,Binder binder,Object []参数,CultureInfo culture,Boolean skipVisibilityChecks)中的参数,Binder binder,BindingFlags invokeAttr,CultureInfo culture,Signature sig)。在MS的System.Reflection.RuntimePropertyInfo.SetValue(Object obj,Object value,BindingFlags invokeAttr,Binder binder,Object [] index,CultureInfo culture)中调用(Object obj,BindingFlags invokeAttr,Binder binder,Object []参数,CultureInfo文化) System.Windows.Data.BindingExpre上MS.Internal.Data.ClrBindingWorker.UpdateValue(Object value)的.Internal.Data.PropertyPathWorker.SetValue(Object item,Object value) ssion.UpdateSource(Object value)’

虽然可以使用Binding来调用方法并获取其返回值,但这并不简单。 绑定到属性以及使用绑定和更改通知的组合来获取您正在寻找的结果简单得多。

创建一个具有两个属性FilenameExtensionFilename只是一个读/写字符串属性。 Extension是一个只读字符串属性,其getter调用您尝试调用的方法。

现在让该类实现INotifyPropertyChanged ,因为如果一个属性可以在代码中改变,它需要一种告诉绑定它已经这样做的方法。 使Filename属性的setter通知绑定Extension属性已更改。

使用TwoWay模式将Binding添加到BindingFilename属性的TextBox 。 使用默认的OneWay模式将Binding添加到绑定到ExtensionTextBox

事件的顺序是:

  1. 用户在绑定的TextBox键入新的Filename并按下TAB。
  2. TextBox失去焦点。
  3. 因为Binding的模式是TwoWay ,并且当目标失去焦点时它使用更新源的默认行为,这就是它的作用。
  4. Binding通过调用Filename setter来更新源。
  5. Filename setter引发PropertyChanged
  6. Binding处理PropertyChanged ,查看其参数,并看到Extension属性已更改。
  7. Binding调用Extension属性的getter。
  8. Extension属性的getter调用该方法来确定Filename的扩展Filename ,并将其返回给Binding
  9. Binding使用Extension的新值更新其目标TextBox

这是数据绑定和MVVM模式的核心概念。 一旦你理解了它,它就变成了第二天性,WPF开发变得容易了大约一千万次。

看起来你需要了解MVVM,请查看这篇经典文章http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

数据绑定需要在更新源时调用NotifyPropertyChanged事件。 在这种情况下,您希望将此函数调用包装在get / set中,如下所示:

public class FileWrapper: System.ComponentModel.INotifyPropertyChanged{ private string m_filename; public string FileExtension{ get{ return GetFileExtension(FileName);} } public string FileName{ get{ return m_filename;} set{ m_filename = value; OnPropertyChanged("FileName"); OnPropertyChanged( "FileExtension"); } public string GetFileExtension( string filename){ //implementation } public event System.ComponentModel.NotifyPropertyChangedEvent PropertyChanged = (a,b)=>{}; protected void OnPropertyChanged(string property){ PropertyChanged( this, new System.ComponentModel.PropertyChangedEventArgs( property )); } }
public class FileWrapper: System.ComponentModel.INotifyPropertyChanged{ private string m_filename; public string FileExtension{ get{ return GetFileExtension(FileName);} } public string FileName{ get{ return m_filename;} set{ m_filename = value; OnPropertyChanged("FileName"); OnPropertyChanged( "FileExtension"); } public string GetFileExtension( string filename){ //implementation } public event System.ComponentModel.NotifyPropertyChangedEvent PropertyChanged = (a,b)=>{}; protected void OnPropertyChanged(string property){ PropertyChanged( this, new System.ComponentModel.PropertyChangedEventArgs( property )); } } 

好吧,这似乎是运行WPF 4.0时的一个错误,这可以在这里的评论中看到 。

Woops,我有点仓促..只要您为3.5框架编译它(在VS 2010中),该示例就可以正常工作。 但是,如果将其转换为WPF 4.0项目,则在编辑文本框时,无法在odp2上调用ObjectDataProvider上的WeightOnPlanet方法。 我试图在Binding或ObjectDataProvider上找到任何新的属性 – 但到目前为止还没有任何结果……

在3.5中编译时,它在这里工作正常。

DataContext是否已设置? 在您的代码隐藏中,您是否将TextBlock的值设置为“saadsas”(我只能猜测),这会破坏您的数据绑定?