将文本框从viewmodel绑定到对象

时间:2013-11-13 20:50:08

标签: c# .net wpf mvvm

在我的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;
       }
}

它完美无缺。

3 个答案:

答案 0 :(得分:2)

斯坦尼斯拉夫,你在其他地方犯了一个错误。您尝试绑定到对象,绑定不知道要显示什么并将ToString()应用于您的Contact对象。如果您覆盖ToString(),则必须显示此方法的返回值。 我创建了测试应用,它以这种方式工作

我在您的代码中看到的内容,在ToString()中您返回FirstName,但在更改后的SelectedContactSecondName - 您之前是否填写了第一个名字?

您在评论中写道,试图访问第一个元素,但在代码中您使用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却没有。