我在将 TextBox.Text
属性数据绑定(bind)到对象的方法时遇到问题。这个想法是允许用户在 TextBox
中写入文件名,然后让 TextBlock
输出该文件的扩展名。
class GetFileInfo
{
public string GetFileExtension(string fileName)
{
return Path.GetExtension(fileName);
}
}
这是我的 XAML:
<Window.Resources>
<ObjectDataProvider x:Key="getFileInfo" MethodName="GetFileExtension" ObjectType="{x:Type local:GetFileInfo}">
<ObjectDataProvider.MethodParameters>
<sys:String>abc.text</sys:String>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>
<StackPanel>
<TextBox Name="textBox1">
<TextBox.Text>
<Binding Source="{StaticResource getFileInfo}" Path="MethodParameters[0]" BindsDirectlyToSource="True" UpdateSourceTrigger="PropertyChanged" />
</TextBox.Text>
</TextBox>
<TextBlock Name="textBlock1" Text="{Binding Source={StaticResource getFileInfo}}"/>
</StackPanel>
出于某种原因,它没有做任何事情。 Anyknow可以指出可能是什么原因吗? 这是我在设计器和运行应用程序时看到的:
下面是当我尝试在运行时设置其他文本时发生的情况:
System.Windows.Data Error: 8 : Cannot save value from target back to source. BindingExpression:Path=MethodParameters[0]; DataItem='ObjectDataProvider' (HashCode=2207369); target element is 'TextBox' (Name='textBox1'); target property is 'Text' (type 'String') ArgumentException:'System.ArgumentException: Object of type 'MS.Internal.Data.PropertyPathWorker+IListIndexerArg' cannot be converted to type 'System.Int32'. at System.RuntimeType.TryChangeType(Object value, Binder binder, CultureInfo culture, Boolean needsSpecialCast) at System.RuntimeType.CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr) at System.Reflection.MethodBase.CheckArguments(Object[] parameters, Binder binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture) at MS.Internal.Data.PropertyPathWorker.SetValue(Object item, Object value) at MS.Internal.Data.ClrBindingWorker.UpdateValue(Object value) at System.Windows.Data.BindingExpression.UpdateSource(Object value)'
最佳答案
虽然可以使用 Binding
调用方法并获取其返回值,但这并不简单。绑定(bind)到属性,并结合使用绑定(bind)和更改通知来获得您要查找的结果,要简单得多。
创建一个具有两个属性的类,Filename
和 Extension
。 Filename
只是一个读/写字符串属性。 Extension
是一个只读字符串属性,其 getter 调用您尝试调用的方法。
现在让那个类实现INotifyPropertyChanged
,因为如果一个属性可以在代码中改变,它需要一种方法来告诉绑定(bind)它已经改变了。使 Filename
属性的 setter 通知绑定(bind) Extension
属性已更改。
使用 TwoWay
模式将 Binding
添加到绑定(bind)到 Filename
属性的 TextBox
。使用默认的 OneWay
模式将 Binding
添加到绑定(bind)到 Extension
的 TextBox
。
事件的顺序是:
- 用户在绑定(bind)的
TextBox
中键入新的Filename
并按 TAB 键。 TextBox
失去焦点。- 因为
Binding
的模式是TwoWay
,并且它使用在目标失去焦点时更新源的默认行为,这就是它的作用。 Binding
通过调用Filename
setter 更新源。Filename
setter 引发了PropertyChanged
。Binding
处理PropertyChanged
,查看其参数,发现Extension
属性已更改。Binding
调用Extension
属性的 getter。Extension
属性的 getter 调用方法来确定Filename
的扩展名,并将其返回给Binding
。Binding
使用Extension
的新值更新其目标TextBox
。
这是数据绑定(bind)和 MVVM 模式的核心概念。一旦你理解它,它就会成为第二天性,WPF 开发将变得简单一千万倍。
关于c# - 数据绑定(bind)到 WPF 中的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2305203/