【问题标题】:How to build a custom control using recursion?如何使用递归构建自定义控件?
【发布时间】:2018-09-09 14:54:29
【问题描述】:

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

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

我有两个类,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,因为添加的所有内容(SubPublishers 和 Child Developers)最终都将是 Parent 的扩展。

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

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

【问题讨论】:

  • 我在代码中看不到任何显示“Developer 是 n 层”的内容。另一方面,Publisher...
  • 你说得对,我编辑了它。很抱歉。
  • 我认为您最好在视图中使用递归来构建控件。这是分层数据模板的用途,也是树视图的工作方式。例如。你错过了解释中一个特别重要的部分。如果我看到风景,它会是什么样子?

标签: c# wpf recursion mvvm


【解决方案1】:

一种方法是创建一个UserControl,将第一层除外作为DataTemplate。然后根据需要在DataTemplate 中显示数据。在DataTemplate 内部再次使用内部数据引用UserControl

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-03
    • 1970-01-01
    • 2010-09-12
    • 1970-01-01
    • 2011-07-31
    • 1970-01-01
    • 2012-04-05
    • 2012-08-02
    相关资源
    最近更新 更多