代码之家  ›  专栏  ›  技术社区  ›  user9145305

如何使用递归构建自定义控件?

  •  0
  • user9145305  · 技术社区  · 7 年前

    我正在尝试构建一个相当复杂的自定义控件。

    我想在视图模型中使用递归来构建控件。我会尽量说清楚的。

    我有两个类,Publisher和Developer

    Publisher类如下所示:

    public class Publisher
    {
      public Publisher()
      {
        SubPublishers.CollectionChanged += SubPublishers_CollectionChanged;
        ChildDevelopers.CollectionChanged += SubPublishers_CollectionChanged;
      }
    
      private ObservableCollection<Publisher> subPublishers;
      public ObservableCollection<Publisher> SubPublishers
      {
        get
        {
           if (subPublishers == null)
               subPublishers = new ObservableCollection<Publisher>();
           return subPublishers;
        }
      }
    
      private ObservableCollection<Developer> childDevelopers;
      public ObservableCollection<Developer> ChildDevelopers
      {
        get
        {
           if (childDevelopers == null)
               childDevelopers = new ObservableCollection<Developer>();
           return childDevelopers;
        }
      }
    

    我的开发人员类如下所示:

    public class Developer : NotifyPropertyChanged
    {
       public Developer(string Title)
       {
         this.Title = Title;
       }
    
       private string title;
       public string Title
       {
         get
         {
           return this.title;
         }
         set
         {
           this.title = value;
           OnPropertyChanged("Title");
         }
       }
    

    所以,是的,Publisher是n层的。它可以有一个开发人员集合,每个开发人员都可以有自己的开发人员集合。

    转到我的主视图模型:

    public class MainViewModel : NotifyPropertyChanged
    {
       public MainViewModel()
       {
         this.ParentPublisher = new ParentPublisher();
         BuildData();
       }
    
       private Publisher parentPublisher;
       public Publisher ParentPublisher
       {
         get
         {
           return this.parentPublisher;
          }
         set
         {
           this.parentPublisher = value;
           OnPropertyChanged("ParentPublisher"); 
          }
        }
    
       public void BuildData()
       {
         Publisher firstPublisher = new Publisher();
         firstPublisher.ChildDevelopers.Add(new Developer("HAL"));
         firstPublisher.ChildDevelopers.Add(new Developer("Retro Games"));
         firstPublisher.ChildDevelopers.Add(new Developer("Nintendo"));
    
         Publisher secondPublisher = new Publisher();
         secondPublisher.ChildDevelopers.Add(new Developer("343"));
         secondPublisher.ChildDevelopers.Add(new Developer("Playground Games"));
         secondPublisher.SubPublishers.Add(new Publisher());
    
         secondPublisher.SubPublishers.FirstOrDefault().ChildDevelopers.Add(new Developer("Coalition"));
         secondPublisher.SubPublishers.FirstOrDefault().ChildDevelopers.Add(new Developer("Remedy"));
         secondPublisher.SubPublishers.FirstOrDefault().SubPublishers.Add(new Publisher());
    
         secondPublisher.SubPublishers.FirstOrDefault().SubPublishers.FirstOrDefault().ChildDevelopers.Add(new Developer("Insomniac"));
         secondPublisher.SubPublishers.FirstOrDefault().SubPublishers.FirstOrDefault().ChildDevelopers.Add(new Developer("Criterion"));
         secondPublisher.SubPublishers.FirstOrDefault().SubPublishers.FirstOrDefault().ChildDevelopers.Add(new Developer("EA"));
    
        ParentPublisher.Add(firstPublisher);
        ParentPublisher.Add(secondPublisher);
      }
     }
    }
    

    因此,您可以在这里看到可能的情况。现在,我正试图找出如何根据这些数据构建控件。

    我想实际绑定到ParentPublisher,因为添加的所有内容(子发布者和子开发人员)最终都将是父级的扩展。

    我会使用ObservableCollection并将ItemSource用于此ParentPublisher吗?

    如有任何提示或建议,将不胜感激。

    1 回复  |  直到 7 年前
        1
  •  0
  •   Michael Puckett II    7 年前

    一种方法是 UserControl 这就不包括作为数据模板的第一层。然后在 DataTemplate 根据需要。内部 数据模板 参考 用户控件 再次使用内部数据。

    示例:显然,修改布局是为了让您受益,但为了简单起见,我是这样做的。

    <UserControl x:Class="WPF_Question_Answer_App.PublisherView"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                 xmlns:local="clr-namespace:WPF_Question_Answer_App"
                 mc:Ignorable="d"
                 d:DesignHeight="450"
                 d:DesignWidth="800">
    
        <UserControl.Resources>
            <DataTemplate x:Key="DeveloperTemplate">
                <TextBlock Text="{Binding Title}" /> <!--show the developer data-->
            </DataTemplate>
    
            <DataTemplate x:Key="PublisherTemplate">
                <local:PublisherView /> <!-- reference ourself for recursion-->
            </DataTemplate>
        </UserControl.Resources>
    
        <StackPanel>
            <ItemsControl ItemsSource="{Binding ChildDevelopers}"
                          ItemTemplate="{StaticResource DeveloperTemplate}" />
            <ItemsControl ItemsSource="{Binding SubPublishers}"
                          ItemTemplate="{StaticResource PublisherTemplate}" />
        </StackPanel>
    </UserControl>