如何将公共属性绑定到WPF TextBox.Text属性

问题描述:

我一直在努力将TextBox.Text绑定到某个对象的公共属性,但不幸的是我还没有完成。如何将公共属性绑定到WPF TextBox.Text属性

实际XAML看起来像:

<Window 
    <!-- skipped --> 
    xmlns:local="clr-namespace:Dotnet.Samples.Foobar" 
    xmlns:system="clr-namespace:System;assembly=mscorlib"> 

    <Window.Resources> 
     <local:Foobar x:Key="foobar" Foo="Lorem" Bar="Ipsum" 
    </Window.Resources> 
    <!-- skipped --> 

     <TextBox Text="{Binding Source={StaticResource foobar}, Path=Foo}"> 
     <TextBox Text="{Binding Source={StaticResource foobar}, Path=Bar}"> 
     <!-- skipped --> 
</Window> 

与数据提供程序对象是简单:

public class Foobar 
{ 
    public string Foo { get; set; } 
    public string Bar { get; set; } 

    public Foobar() 
    { 

    } 
} 

我想我是那种与WPF的各种绑定选项的困惑和我米可能混合起来,所以任何建议将肯定赞赏。

编辑 - 所有的绑定工作正常,剩下的挑战是通知从模型到ViewModel(另一种方式工作)的变化。我已经犯下的“破”的代码来替代回购: http://nanotaboada.svn.beanstalkapp.com/dotnet/trunk/Dotnet.Samples.Rijndael/

随意签,我会很高兴听到这个任何反馈。非常感谢

尽管您的构造函数方法参数是可选的,XAML绑定引擎仍未找到要使用的合适构造函数。因此,您必须传入构造函数的值,或创建一个将Foo的值设置为默认值的无参数构造函数,或根本不使用ObjectDataProvider,并直接创建类型的实例作为资源。

... 
xmlns:system="clr-namespace:System;assembly=mscorlib" 
... 

<!-- Either create an instance of your type, and you can initialise the property values, this will require a default parameterless constructor --> 
<abc:Foobar x:Key="foobar2" Foo="Foo" /> 

<!-- or pass the optional parameter values into your existing constructor --> 
<ObjectDataProvider x:Key="foobar" ObjectType="{x:Type abc:Foobar}"> 
    <ObjectDataProvider.ConstructorParameters> 
    <system:String>Foo</system:String> 
    <system:String>Bar</system:String> 
    </ObjectDataProvider.ConstructorParameters> 
</ObjectDataProvider> 

注意,您只需要实现INotifyPropertyChanged如果你的绑定将在代码中无效,你需要通知UI。如果你不喜欢在你的模型类型上实现这个接口,那么你可以在你的视图模型(假设你使用MVVM)上做到这一点,但是当你的模型需要找到另一种机制来通知你的视图模型值改变。

+0

@devdigital:非常感谢您的详细解释!通过'Window.Resources'实现的类型实例化/构造在(我正在更新原始代码)上工作正常,但仍然没有得到它们的属性集。让我猜 - 我应该实现'INotifyPropertyChanged'吗? – 2011-03-13 21:10:09

+1

不,您不需要在这种情况下 - 只需要通知UI已更改代码,而不是相反方式,只需要通知属性更改。你确定安装者没有被解雇吗?默认情况下,TextBox只会更新失去焦点的属性。如果要在更改属性的同时更改此属性,请在TextBox中键入属性值,然后将绑定表达式中的UpdateSourceTrigger属性值设置为PropertyChanged。请参阅http://msdn.microsoft.com/en-us/library/system.windows.data.binding.updatesourcetrigger.aspx – devdigital 2011-03-13 21:36:50

+0

@devdigital:再次感谢您的回复 - 我已尝试'UpdateSourceTrigger = PropertyChanged'和'Mode = TwoWay'没有更好的运气。 – 2011-03-13 23:34:55

这看起来很好,除了我不认为ObjectDataProvider能够读取默认参数。尝试创建一个没有任何参数的Foobar构造函数。

如果失败了,您能否给我们提供您所看到的错误?

+0

@Rob:感谢您的评论 - 目前它编译好,没有错误,但TextBox.Text没有显示任何值,所以我会继续尝试,没有默认参数。 – 2011-03-13 16:10:55

+0

@Rob:我刚刚尝试删除默认值并构建对象,但没有奏效。 – 2011-03-13 16:15:28

+0

在输出窗口中是否有任何绑定错误? – 2011-03-13 16:23:01

“不完全在那里”是什么意思?除了你在Foobar课中缺少变更通知外,一切看起来都很好。改变它,使其正确实施INotifyPropertyChanged,一切都应该正常工作。

+0

@Kent,感谢您的评论,“不完全在那里”我的意思是“它没有按预期工作”,我会尝试您的建议,尽管我不确定是否应该将System.ComponentModel接口添加到与UI无关的类 - 应该有另一种方式来做到这一点。 – 2011-03-13 18:09:08

+0

我想我会尝试http://updatecontrols.codeplex.com/ – 2011-03-13 19:26:45

+0

@Nano:'System.ComponentModel'与UI无关。 – 2011-03-13 23:10:29

我认为这是在构造函数中的参数问题。如果你真的需要他们,你可以把它写这样的:

这也将需要这个补充说:xmlns:sys="clr-namespace:System;assembly=mscorlib"

然后是Foobar的类将是这样的:

public class Foobar 
{ 
    public string Foo { get; set; } 
    public string Bar { get; set; } 

    public Foobar Foobar1(string param1 = "foo", string param2 = "bar") 
    { 
     Foobar f = new Foobar(); 
     f.Foo = param1; 
     f.Bar = param2; 
     return f; 
    } 
} 

摆脱/根据需要在XAML中添加参数。