【问题标题】:Repeated children in WPF TreeViewWPF TreeView 中的重复子项
【发布时间】:2011-11-08 20:16:06
【问题描述】:

自己解决了。这是我初始化设置集合的方式。在将其注册为 DependencyProperty 时指定默认值会导致所有设置引用同一个集合对象。向 Category 添加构造函数并显式初始化 Settings 即可解决此问题。


类 Category 指定名称和 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

但我得到的是这个

这很令人困惑。我在哪里误入歧途,每个类别都显示了所有设置?

【问题讨论】:

    标签: wpf binding treeview


    【解决方案1】:

    这里的最后一个参数告诉我们要让每个 Category 实例的 Settings 属性初始化为指向同一个对象:

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

    【讨论】:

    • 如果您查看问题的最后更新时间戳,您会发现我在发布问题后几乎立即得出了相同的结论,并将其写在问题的顶部。但是您是正确的,并且是第一个回答的,所以无论如何我很乐意将其提供给您。
    • @PeterWone:仅供参考,您不应该将答案编辑到您的问题中,使用正确的答案回答您自己的问题并接受它。
    • 系统在两个小时内不允许您回答自己的问题。在这种情况下,我在发布问题几秒钟后就得到了答案。
    猜你喜欢
    • 1970-01-01
    • 2020-01-08
    • 1970-01-01
    • 2016-11-20
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多