2011-09-02 30 views
2

自己解決了。這是我初始化Settings集合的方式。將其註冊爲DependencyProperty時指定默認值會導致所有設置引用相同的集合對象。向類別添加構造函數並顯式初始化設置可解決問題。WPF TreeView中重複的孩子


類別類別指定名稱和Settings對象的集合。

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

namespace CasEdit 
{ 
    public class Categories : ObservableCollection<Category> { } 

    public class Category : DependencyObject 
    { 
    public string Caption 
    { 
     get { return (string)GetValue(CategoryProperty); } 
     set { SetValue(CategoryProperty, value); } 
    } 
    public static readonly DependencyProperty CategoryProperty = 
     DependencyProperty.Register("Caption", typeof(string), typeof(Category), 
     new UIPropertyMetadata("Category name not set")); 
    public Settings Settings 
    { 
     get { return (Settings)GetValue(SettingsProperty); } 
    } 
    public static readonly DependencyProperty SettingsProperty = 
     DependencyProperty.Register("Settings", typeof(Settings), typeof(Category), 
     new UIPropertyMetadata(new Settings())); 
    } 
} 

以下XAML定義了模板,UI和一些測試數據。

<Window x:Class="CasEdit.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:CasEdit="clr-namespace:CasEdit" 
     Title="MainWindow" Height="350" Width="525" > 
    <Window.Resources> 
    <HierarchicalDataTemplate DataType="{x:Type CasEdit:Category}" ItemsSource="{Binding Settings}"> 
     <StackPanel Orientation="Horizontal"> 
     <TextBlock Text="{Binding Caption}" /> 
     <Button Content="Gratuitous button" Margin="3" Click="Button_Click"/> 
     </StackPanel> 
    </HierarchicalDataTemplate> 
    <DataTemplate DataType="{x:Type CasEdit:Setting}" > 
     <StackPanel Orientation="Horizontal"> 
     <TextBlock Text="{Binding Caption}" Margin="3" /> 
     <TextBlock Text="{Binding Template}" Margin="3" /> 
     <TextBox Text="{Binding Editor}" Margin="3" /> 
     <TextBlock Text="{Binding CasDevice}" Margin="3" /> 
     </StackPanel> 
    </DataTemplate> 
    <CasEdit:Categories x:Key="cats"> 
     <CasEdit:Category Caption="1st category"> 
     <CasEdit:Category.Settings> 
      <CasEdit:Setting Caption="Setting 1-1" /> 
      <CasEdit:Setting Caption="Setting 1-2" /> 
     </CasEdit:Category.Settings> 
     </CasEdit:Category> 
     <CasEdit:Category Caption="2nd category" > 
     <CasEdit:Category.Settings> 
      <CasEdit:Setting Caption="Setting 2-1" /> 
     </CasEdit:Category.Settings>   
     </CasEdit:Category> 
     <CasEdit:Category Caption="3rd category" > 
     <CasEdit:Category.Settings> 
      <CasEdit:Setting Caption="Setting 3-1" /> 
     </CasEdit:Category.Settings>   
     </CasEdit:Category> 
    </CasEdit:Categories> 
    </Window.Resources> 
    <Grid> 
    <TreeView x:Name="tree" ItemsSource="{Binding Source={StaticResource cats}}" /> 
    </Grid> 
</Window> 

你會想到樹這樣

  • 第一類
    • 設置1-1
    • 設置1-2
  • 第二類
    • 設置2-1
  • 第三類
    • 設置3-1

但我得到的是這種

Screen snap

這是非常混亂。我迷失在哪裏,每個類別都顯示了所有的設置?

回答

1

這裏的最後一個參數告訴使得它使類別的每個實例有它的初始化指向同一個對象設置屬性:

public static readonly DependencyProperty SettingsProperty = 
     DependencyProperty.Register("Settings", typeof(Settings), typeof(Category),  
     new UIPropertyMetadata(new Settings())); 

相反,這樣做:

public static readonly DependencyProperty SettingsProperty = 
     DependencyProperty.Register("Settings", typeof(Settings), typeof(Category), 
     new UIPropertyMetadata(null)); 
    public Category() 
    { 
     Settings = new Settings(); 
    } 
+0

如果您看看問題的最後更新時間戳,你會發現我在發佈問題後幾乎立即得出了相同的結論,並在問題的頂部寫下了這個問題。但你是正確的,也是第一個回答,所以我很樂意給你任何。 –

+0

@PeterWone:僅供將來參考,你不應該編輯你的問題的答案,用適當的答案回答你自己的問題,並接受它。 –

+0

系統不會讓你在兩個小時內回答自己的問題。在這種情況下,答案在發佈問題後幾秒鐘就到了。 –