2016-10-02 28 views
0

我是WPF的新手,所以我嘗試了一些教程。現在在我的第二個項目有一些東西讓我瘋狂......C#WPF數據綁定 - 爲什麼WPF顯示單個字母而不是列表的內容

這裏是C#代碼:

using System.Windows; 
using System.Collections.Generic; 
using System.Collections.ObjectModel; 

namespace WpfDataBindingTest1 
{ 
    public partial class MainWindow : Window 
    { 
     private ICollection<TestClass> testClassCollection; 
     public ICollection<TestClass> TestClassCollection 
     { 
      get { return this.testClassCollection; } 
      set { if (this.testClassCollection != value) { this.testClassCollection = value; } } 
     } 
     public MainWindow() 
     { 
      InitializeComponent(); 

      this.testClassCollection = new ObservableCollection<TestClass>() 
      { 
       new TestClass() {ID = 1, Name = "Name1" }, 
       new TestClass() {ID = 2, Name = "Name2" }, 
       new TestClass() {ID = 3, Name = "Name3" } 
      }; 
     } 
    } 

    public class TestClass 
    { 
     public int ID { get; set; } 
     public string Name { get; set; } 
    } 
} 

這裏是XAML代碼:

<Window x:Class="WpfDataBindingTest1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:local="clr-namespace:WpfDataBindingTest1" 
     mc:Ignorable="d" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <ListBox 
      x:Name="lbTestClassItems" 
      ItemsSource="{Binding Source=TestClassCollection}"> 

     </ListBox> 
    </Grid> 
</Window> 

所以,編譯時和運行這個,我只在XAML文件中定義的列表框的一個新行中顯示Word的每個字母「TestClassCollection」。

在定義列表框的時候添加DisplayMemberPath="ID"時,什麼也沒有顯示。

一些搜索後,我發現這一點:why is it displaying class name instead of property?

但這並沒有幫助。

編輯:神祕如果我通過代碼(設置itemsource和DisplayMemberPath),它顯示正確的數據。但如果我通過XAML進行操作,請參閱上面的

在此先感謝!

+0

爲什麼你在'ItemsSource'中使用'Source'而不是'Path'? – rbr94

+1

你必須使用正確的'ItemTemplate'。列表框本身並不知道你的裝訂項目應該如何顯示 – lokusking

+0

@ rbr94:同樣的結果,沒有任何顯示 – Radinator

回答

1

您需要使用Path而不是Source否則你綁定到字符串TestClassCollection每個項目因此您的一個字母。理想情況下,如果你的項目是一個複雜的對象,你也將任設DisplayMemberPath或使用ItemTemplate

<ListBox 
    x:Name="lbTestClassItems" 
    ItemsSource="{Binding Path=TestClassCollection}" 
    DisplayMemberPath="Name"/> 

另一個問題是,你沒有設置任何地方DataContext。綁定上下文中的所有綁定工作。

public MainWindow() 
{ 
    InitializeComponent();   
    this.testClassCollection = ...; 
    this.DataContext = this; 
} 

你需要做的是在這等,因爲你的MainWindow沒有實現INotifyPropertyChanged接口TestClassCollection財產不會引發PropertyChanged事件。之後,你可以添加/刪除到TestClassCollection,它應該被用戶界面拾取,因爲ObservableCollection<T> implements INotifyCollectionChanged界面

+0

非常感謝!這有所幫助。 :D只是忘了調用'this.DataContext = this;' – Radinator

1

嘗試使用ItemTemplate

<ListBox x:Name="lbTestClassItems" ItemsSource="{Binding Path=TestClassCollection}"> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
     <StackPanel Orientation="Horizontal"> 
      <Label Content="{Binding Id}" /> 
     </StackPanel> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 
+0

sry,但是這樣做沒有幫助。現在列表框不見了 – Radinator

1

你需要一個DataContext。而不是讓你的「視圖模型」代碼放在主窗口的代碼中,把它放在一個單獨的類中。像這樣:

public class ViewModel 
{ 
    public ViewModel() 
    { 
     this.testClassCollection = new ObservableCollection<TestClass>() 
     { 
      new TestClass() {ID = 1, Name = "Name1" }, 
      new TestClass() {ID = 2, Name = "Name2" }, 
      new TestClass() {ID = 3, Name = "Name3" } 
     }; 
    } 

    private ICollection<TestClass> testClassCollection; 
    public ICollection<TestClass> TestClassCollection 
    { 
     get { return this.testClassCollection; } 
     set { if (this.testClassCollection != value) { this.testClassCollection = value; } } 
    } 

    public class TestClass 
    { 
     public int ID { get; set; } 
     public string Name { get; set; } 
    } 

} 

然後創建一個ViewModel類的實例作爲數據上下文。

<Grid> 
    <ListBox 
     x:Name="lbTestClassItems" 
     ItemsSource="{Binding TestClassCollection}" > 
     <ListBox.DataContext> 
      <local:ViewModel/> 
     </ListBox.DataContext> 
    </ListBox> 
</Grid> 

我相信與你原來的執行情況是,它被綁定到屬性名的ToString。一個字符串被認爲是一個char數組,因此每個列表項目都會得到一個字母。

理想情況下,您可能不會爲列表框創建單獨的數據上下文。它更可能繼承它的父母。 (即窗口)但是這說明了這個概念。