0

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

在我的联系人类中,我重写了 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;
       }
}

它完美地工作。

4

3 回答 3

2

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

我可以在您的代码中看到,在ToString()您 returnFirstName中,但在更改SelectedContact中是SecondName-您之前是否填写了名字?

你在评论中写了试图访问第一个元素,但在代码中你取了第二个元素ContactList

而且,以这种方式使用绑定是不正确的。如果您想访问 LastName,请使用以下方式:

   <TextBox Text="{Binding Path=SelectedContact.LastName, Mode=OneTime}" />

并删除ToString()覆盖。

编辑:与默认情况下绑定的其他控件不同,OneWay默认TextBox情况TwoWay下。这样做是因为本机行为TextBox是显示和编辑值(不仅像在其他控件中那样显示)。此外,如果您不打算更改值(您不打算,因为ContactModel不实施INotifyPropertyChanged),建议使用OneTime模式(为了性能)。

TwoWay有一些限制 - 你不能将它用于只读属性(SelectedContact在你的代码中是只读的)。因为在这种情况下绑定不能改变值 - 有意义。奇怪的是,应用程序在您的情况下午餐并且TextBox是空的,因为在我的情况下,我收到错误“ A TwoWay 或 OneWayToSource 绑定无法对'WpfApplication1.ContactViewModel'类型的只读属性'SelectedContact'起作用。 ”直到我改变中的绑定模式TextBox

于 2013-11-13T21:36:20.013 回答
1

我猜你在 MSDN 上关注了这篇文章:http: //msdn.microsoft.com/en-us/library/ms742521%28v=vs.110%29.aspx

尽管文章说,ListBox 的标准表示是其内容的 ToString 表示的列表,但并非所有其他元素都是如此。

我强烈建议为您的 Contact 类创建一个 DataBinding 模板,这是一种比覆盖 ToString 更简洁的方法来实现此行为。

于 2013-11-13T21:02:24.863 回答
0

啊,找到了,我只需要将我的 TextBox 更改为 TextBlock,现在一切正常!

似乎 TextBlock 确实了解如何显示对象,但 TextBox 不了解。

于 2013-11-13T20:58:21.170 回答