2012-04-17 114 views
2

的控制我在WPF是新的,我想就如何對這個對象綁定到WPF控件快速意見,我不知道我應該使用控制:綁定的對象爲WPF

public class Parent 
{ 
    public string Name{get; set;} 
    public List<Child> Childs {get; set;} 
} 

public class Child 
{ 
    public string Name{get; set;} 
    public int Age {get; set;} 
} 

public class ParentFactory 
{ 
    public List<Parent> Parents {get; set;} 

    public ParentFactory() 
    { 
     Child child1 = new Child() {Name="Peter", Age=10;}; 
     Child child2 = new Child() {Name="Mary", Age=9;}; 
     Child child3 = new Child() {Name="Becky", Age=12;}; 

     Parent parent1 = new Parent(){Name="Adam", Childs = new List<Child<>(){child1, child2}}; 
     Parent parent2 = new Parent(){Name="Kevin", Childs = new List<Child<>(){child3}}; 

     Parents = new List<Parent>(){parent1, parent2}; 
    } 
} 

創建此實例後:

ParentFactory parentFactory = new ParentFactory();

我想將parentFactory.Parents()綁定到WPF中的控件。我希望看到這樣的事情:


亞當

- 彼得,10

- 瑪麗,9

凱文

- 貝基,12


它們都顯示在文本框上,我可以更改它們。

在此先感謝。

+0

問題的性質似乎誘導每一位家長也是一個孩子,而這些應該顯示在[TreeView控件](http://msdn.microsoft.com/en-我們/庫/ system.windows.controls.treeview.aspx)。 – Clemens 2012-04-17 13:35:00

+0

你可能需要一個treeview。這裏解釋如何在數據綁定中使用WPF中的treeview http://www.codeproject.com/Articles/26288/Simplifying-the-WPF-TreeView-by-Using-the-ViewMode – Klaus78 2012-04-17 13:35:18

+0

實現[INotifyPropertyChange](http:// msdn.microsoft.com/en-us/library/ms229614.aspx)上的Parent和Child或基類,並從中派生。 – LPL 2012-04-17 13:36:52

回答

4

使用具有HierarchicalDataTemplate的TreeView。

但是請注意,如果沒有在模型上實現INotifyPropertyChanged,那麼綁定將不會更新任何屬性更改。另外,如果不用ObservableCollections替換你的列表,當你向列表中添加更多的項目時,你的視圖不會更新。

像這樣的事情應該工作,首先定義你的模板:

<Window.Resources> 
    <HierarchicalDataTemplate DataType="{x:Type local:Parent}" ItemsSource="{Binding Childs}"> 
     <TextBlock Text="{Binding Name}"/> 
    </HierarchicalDataTemplate> 
    <DataTemplate DataType="{x:Type local:Child}"> 
     <StackPanel Orientation="Horizontal"> 
      <TextBlock Text="{Binding Name}"/> 
      <TextBlock>, </TextBlock> 
      <TextBlock Text="{Binding Age}"/> 
     </StackPanel> 
    </DataTemplate> 
</Window.Resources> 

然後你可以用這樣一個TreeView使用它們(假設父母是在TreeView的DataContext的一個屬性):

<TreeView ItemsSource="{Binding Parents}"/> 

如果你不想一個TreeView,你可以很容易地做一些事情清單這與一個ListView,改變你的DataTemplates這樣:

<DataTemplate DataType="{x:Type local:Parent}"> 
     <StackPanel> 
      <TextBlock Text="{Binding Name}"/> 
      <ListView ItemsSource="{Binding Childs}"/> 
     </StackPanel> 
    </DataTemplate> 
    <DataTemplate DataType="{x:Type local:Child}"> 
     <StackPanel Orientation="Horizontal"> 
      <TextBlock Text="{Binding Name}"/> 
      <TextBlock>, </TextBlock> 
      <TextBlock Text="{Binding Age}"/> 
     </StackPanel> 
    </DataTemplate> 

然後你就可以綁定像這樣:

<ListView ItemsSource="{Binding Parents}"/> 

注意:您可能需要反覆折騰的風格一點,因爲出的現成,這看起來有點廢話。至少,您可能會想要縮進子ListView(父DataTemplate中定義的那個)並刪除它的邊框。

另請注意:用於名稱和年齡的StackPanel佈局多個TextBlocks也不理想,但它很快且很髒。你可能想要以不同的方式處理。您可以使用(多)轉換器對其進行格式化,使用StringFormat或將其他屬性添加到模型中以供顯示,甚至可以僅在子類上覆蓋ToString。

另一個編輯

使用DataGrid的快速(和難看)例如:

<DataGrid ItemsSource="{Binding Parents}" AutoGenerateColumns="False"> 
    <DataGrid.RowDetailsTemplate> 
     <DataTemplate> 
      <DataGrid ItemsSource="{Binding Childs}"/> 
     </DataTemplate> 
    </DataGrid.RowDetailsTemplate> 
    <DataGrid.Columns> 
     <DataGridTextColumn Binding="{Binding Name}"/> 
    </DataGrid.Columns> 
</DataGrid> 

這使得數據網格使用行細節模板數據網格內。如果您單擊一行,它將顯示子行作爲行詳細信息。如果您想要始終可用的詳細信息,則可以刪除RowDetailsTemplate並將DataGridTextColumn替換爲DataGridTemplateColumn,然後爲您的數據定義模板。

+0

有什麼我可以使用Grid:與綁定? – olidev 2012-04-17 13:46:59

+0

@devn:如果你不想要一個TreeView,你可以使用一個ListView。但它不會自動與HieracrchicalDataTemplate一起工作,因此您需要做的是爲您的父級設置DataTemplate以爲您的孩子添加另一個ListView。 – 2012-04-17 13:56:04

+0

@devn:是的,如果你想要,你可以用TextBox代替TextBlocks並指定雙向綁定。但請注意先前有關實現INotifyPropertyChanged的評論。雖然如果這是隻綁定*這些值的地方,並且這是隻有*這些值可以更改的方式,那麼您可能會在沒有INotifyPropertyChanged困擾的情況下離開。 – 2012-04-17 14:05:00

3

如果你不希望樹視圖(這可能是最好的,因爲你有一個層次結構 - 雖然它只是一個深層次,所以你可能仍然有一個列表的情況下)...
你可以做這樣的事情(這是一個大致的輪廓,你應該在點滿)...

<ItemsControl ItemsSource="{Binding AllNodes}"> 
</ItemsControl> 

...併爲每個類型定義明確,像馬特還提到模板...

<DataTemplate DataType="{x:Type namespace:Child}"> 
... 
</DataTemplate> 

<DataTemplate DataType="{x:Type namespace:Parent}"> 
... 
</DataTemplate> 

...而AllNodes是你的名單d,以flatten從你的層次結構,您可以使用此...

var allnodes = Parents.SelectMany(p => new object[]{p}.Concat(p.Childs)); 

...和揭露allnodes中類似於父母財產 - 你只需要正確實施INotifyPropertyChanged的視圖模型的建議。

希望這有助於

+0

很好的答案。使用ItemsControl更好。非常感謝! – olidev 2012-04-17 14:15:19

+0

使用ItemControl時,如果在單擊某個項目時有行,則選中整行。我如何禁用它?或者有另一個控制器比ItemsControl更好? – olidev 2012-04-17 14:16:43

+0

不會說更好:)也許更容易 - 層次結構更強大,@Matt - 對目標應該如何處理。 ItemsControl不會'選擇'東西--ListBox可以做到這一點 - 所以只需使用ItemsControl,你應該沒問題。這是http://stackoverflow.com/questions/9069374/how-to-highlight-selected-item-in-itemscontrol上的鏈接 – NSGaga 2012-04-17 14:19:07