开发者

Repeated children in WPF TreeView

Solved it myself. It was the way I initialised the Settings collection. Specifying a default when registering it as a DependencyProperty causes all of the Settings to refer to the same collection object. Adding a constructor to Category and explicitly initialising Settings resolves the issue.


A class Category specifies a name and a collection of Settings objects.

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()));
  }
}

The following XAML defines templates, UI and some test data.

<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>

You would expect a tree like this

  • 1st category
    • Setting 1-1
    • Setting 1-2
  • 2nd Category
    • Setting 2-1
  • 3rd category
    • Setting 3-1

but what I get is this

Repeated children in WPF TreeView

which is very confusing. Where have I gone astray, that each category shows all of the settings?


The last parameter here is telling making it so that every instance of Category has it's Settings property initialized to point to the same object:

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

Instead, do this:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜