2012-01-13 64 views
1

可能重复:
WPF ListBox - Display properties of the ItemSource列表框显示“Namespace.Accounts”,而不是实际的文本

我想实现一个解决方案添加它们后,将显示在ListBox项目通过一个文本框和添加按钮...作为WPF的新手,我几乎得到了这个想法(经过了一个星期的头撞我的桌子...大声笑)

问题是,列表框是正在填充“WinBudget.Accounts”而不是输入到列表框中的实际项目。

请帮忙。

模型

// the model is the basic design of an object containing properties 
// and methods of that object. This is an account object. 

public class Account : INotifyPropertyChanged 
{ 
    private string m_AccountName; 

    public event PropertyChangedEventHandler PropertyChanged; 

    public string AccountName 
    { 
     get { return m_AccountName;} 
     set 
     { 
      m_AccountName = value; 
      OnPropertyChanged("AccountName"); 
     } 
    } 

    protected void OnPropertyChanged(string name) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(name)); 
     } 
    } 
} 

列表框XAML

<ListBox Name="MyAccounts" /> 

后面的代码

// create a collection of accounts, then whenever the button is clicked, 
//create a new account object and add to the collection. 

public partial class Window1 : Window 
{ 
    private ObservableCollection<Account> AccountList = new ObservableCollection<Account>(); 

    public Window1() 
    { 
     InitializeComponent(); 
     AccountList.Add(new Account{ AccountName = "My Account" }); 
     this.MyAccounts.ItemsSource = AccountList; 
    } 
    private void okBtn_Click(object sender, RoutedEventArgs e) 
    { 
     AccountList.Add(new Account{ AccountName = accountaddTextBox.Text}); 
    } 
} 
+0

@lance,提到那个线程。 DisplayMemberPath =“AccountName”工作......非常感谢! – Woody 2012-01-13 15:24:36

回答

0

默认情况下,ListBox的项目模板显示是针对对象调用ToString()的结果。所以你必须覆盖Account.ToString(),或者提供一个不同的模板。

+2

我更喜欢使用ToString()来显示诊断信息,而不是UI需求。 – lance 2012-01-13 15:24:38

3

WPF的UI可以包含任何类型的对象,甚至类如Account。如果WPF在UI中遇到一个对象并不理解,它将使用包含对象的.ToString()TextBlock来呈现它。

在你的情况下,ListBox.Item是一个Account对象,所以它得到呈现与Account.ToString(),它返回类的名称。

处理此问题的方法有很多种。我的首选方法通常是使用DataTemplate。这将创建一个应用程序范围的模板,告诉WPF如何绘制特定类型的对象。

<Window.Resources> 
    <DataTemplate TargetType="{x:Type local:Account}"> 
     <TextBlock Text="{Binding AccountName}" /> 
    </DataTemplate> 
</Window.Resources> 

另一种方法是覆盖ListBox.ItemTemplate指定要使用什么ItemTemplateListBox。我通常会用这个,如果我想指定要使用的模板此ListBox

<ListBox Name="MyAccounts"> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <TextBlock Text="{Binding AccountName}" /> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

如果你的模板是简单的,如所示的,你也可以设定ListBox的DisplayMemberPath这使得默认模板的样子如上所示,用任何你放在DisplayMemberPath

<ListBox Name="MyAccounts" DisplayMemberPath="AccountName" /> 

当然的约束力指点的人,你也可以覆盖你Account对象的ToString()方法返回AccountName而不是默认的ClassNa我,但我不会在这种情况下推荐它。

+1

好东西。谢谢瑞秋。 – Woody 2012-01-13 15:31:31

0

这是更好地做一个结合Account::AccountName属性,但如果你不wnat或不能以任何理由,快速和肮脏的解决办法是

公共类账户:INotifyPropertyChanged的 { 私人字符串m_AccountName ;

public event PropertyChangedEventHandler PropertyChanged; 

public string AccountName 
{ 
    get { return m_AccountName;} 
    set 
    { 
     m_AccountName = value; 
     OnPropertyChanged("AccountName"); 
    } 
} 

protected void OnPropertyChanged(string name) 
{ 
    PropertyChangedEventHandler handler = PropertyChanged; 
    if (handler != null) 
    { 
     handler(this, new PropertyChangedEventArgs(name)); 
    } 
} 




    //NEW 
    public override string ToString() 
    { 
     return AccountName; 
    } 

} 
相关问题