如何将公共属性绑定到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)上做到这一点,但是当你的模型需要找到另一种机制来通知你的视图模型值改变。
这看起来很好,除了我不认为ObjectDataProvider能够读取默认参数。尝试创建一个没有任何参数的Foobar构造函数。
如果失败了,您能否给我们提供您所看到的错误?
@Rob:感谢您的评论 - 目前它编译好,没有错误,但TextBox.Text
没有显示任何值,所以我会继续尝试,没有默认参数。 –
2011-03-13 16:10:55
@Rob:我刚刚尝试删除默认值并构建对象,但没有奏效。 – 2011-03-13 16:15:28
在输出窗口中是否有任何绑定错误? – 2011-03-13 16:23:01
“不完全在那里”是什么意思?除了你在Foobar
课中缺少变更通知外,一切看起来都很好。改变它,使其正确实施INotifyPropertyChanged
,一切都应该正常工作。
@Kent,感谢您的评论,“不完全在那里”我的意思是“它没有按预期工作”,我会尝试您的建议,尽管我不确定是否应该将System.ComponentModel接口添加到与UI无关的类 - 应该有另一种方式来做到这一点。 – 2011-03-13 18:09:08
我想我会尝试http://updatecontrols.codeplex.com/ – 2011-03-13 19:26:45
@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中添加参数。
@devdigital:非常感谢您的详细解释!通过'Window.Resources'实现的类型实例化/构造在(我正在更新原始代码)上工作正常,但仍然没有得到它们的属性集。让我猜 - 我应该实现'INotifyPropertyChanged'吗? – 2011-03-13 21:10:09
不,您不需要在这种情况下 - 只需要通知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
@devdigital:再次感谢您的回复 - 我已尝试'UpdateSourceTrigger = PropertyChanged'和'Mode = TwoWay'没有更好的运气。 – 2011-03-13 23:34:55