在我的MVVM测试项目中,我想将文本框绑定到viewmodel中的对象:
public class ContactViewModel : BaseNotifyPropertyChanged
{
Contact _selectedItem;
public ContactViewModel()
{
ContactModel contactModel = new ContactModel();
_selectedItem = contactModel.ContactList[1]; // this contains first contact from the list;
}
}
public Contact SelectedContact
{
get
{
return _selectedItem;
}
}
在我的Contact类中,我重写了ToString方法,以便显示第一个联系人的名字:
public override string ToString()
{
return _firstName.ToString();
}
这是我的XAML绑定:
<TextBox Height="23" HorizontalAlignment="Left" Name="SelectedItemTextBox" Text="{Binding Path=SelectedContact}" VerticalAlignment="Top" Width="120" />
由于某种原因,此文本框始终为空。但是,如果我改变
public String SelectedContact
{
get
{
return _selectedItem.LastName;
}
}
它完美无缺。
答案 0 :(得分:2)
ToString()
应用于您的Contact
对象。如果您覆盖ToString()
,则必须显示此方法的返回值。 我创建了测试应用,它以这种方式工作!
我在您的代码中看到的内容,在ToString()
中您返回FirstName
,但在更改后的SelectedContact
中SecondName
- 您之前是否填写了第一个名字?
您在评论中写道,试图访问第一个元素,但在代码中您使用ContactList
的第二个元素
此外,以这种方式使用绑定是不正确的。如果您想使用下一个方式访问LastName:
<TextBox Text="{Binding Path=SelectedContact.LastName, Mode=OneTime}" />
删除ToString()
覆盖。
编辑:与默认情况下OneWay
默认绑定为TextBox
的其他控件不同,默认情况下为TwoWay
。这样做是因为TextBox
的原生行为是显示和编辑值(不仅像在其他控件中那样显示)。此外,如果您不打算更改值(您没有计划,因为ContactModel
未实现INotifyPropertyChanged
),建议使用OneTime
模式(以提高性能)。
TwoWay
有一些限制 - 您不能将其用于只读属性(SelectedContact
在您的代码中是只读的)。因为在这种情况下绑定不能改变值 - 有意义。奇怪的是,在你的情况下发布的应用程序和TextBox
是空的,因为在我的情况下我得到错误“一个TwoWay或OneWayToSource绑定无法在'WpfApplication1'类型的只读属性'SelectedContact'上工作.ContactViewModel'。“直到我在TextBox
更改了绑定模式。
答案 1 :(得分:1)
我猜你在MSDN上关注了这篇文章: http://msdn.microsoft.com/en-us/library/ms742521%28v=vs.110%29.aspx
所有文章都说,ListBox的标准表示是其内容的ToString表示的List,而不是每个其他元素的情况。
我强烈建议您为Contact类创建一个DataBinding模板,实现此行为比覆盖ToString更简洁。
答案 2 :(得分:0)
啊,发现它,我只需要将TextBox更改为TextBlock,现在一切正常!
看起来TextBlock确实理解如何显示对象,但TextBox却没有。