65.9K
CodeProject 正在变化。 阅读更多。
Home

如何:在 WPF 分层 DataTemplate 中使用主-明细模式

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.88/5 (24投票s)

2014年4月7日

CPOL

2分钟阅读

viewsIcon

36356

downloadIcon

1775

本文展示了一种在分层 DataTemplate 中实现主-明细模式的简单方法

引言

本文展示了一种使用分层DataTemplate实现主/从模式的实用且简单的方法。

背景

主/从模式是计算机科学和信息系统中经常使用的模式。几乎每个面向数据的项目都在使用这种模式。其原理非常简单,即通过选定的主项显示详细信息列表

我们可以通过多种方式来实现主/从模式,在我看来,在WPF中最简单的方法是使用DataTemplate

表示分层数据

每个主/从模式都需要一个数据结构。作为一个分层数据结构的例子,我选择使用以下假设的高科技公司

该公司由三个部门组成

  • 管理: 首席执行官 (CEO),首席技术官 (CTO),质量保证副总裁 (VP.QA)
  • 开发: CTO 和开发团队的下属
  • 质量保证: 质量保证副总裁和质量保证团队的下属

在本示例中,我选择采用部门的方面,即视图中的每一行都是不同的部门

让我们看看这些类

public class Employee
{
    public Employee()
    {
        Subordinates = new List<Employee>();
    }

    public List<Employee> Subordinates { get; set; }

    public string Name
    {
        get;
        set;
    }

    public override string ToString()
    {
        return this.Name;
    }
} 

每个员工都包含“subordinates”(下属),这是一个员工集合。

public class Department : INotifyPropertyChanged
{
    public Department()
    {
        Employees = new List<Employee>();
    }

    public List<Employee> Employees { get; set; }

    protected int m_EmployeesSelectedIndex = 0;

    public int EmployeesSelectedIndex
    {
        get
        {
            return m_EmployeesSelectedIndex;
        }
        set
        {
            m_EmployeesSelectedIndex = value;
            NotifyPropertyChanged("Subordinates");
        }
    }

    public List<Employee> Subordinates
    {
        get
        {
            List<Employee> res = null;
            if (Employees.Count > 0)
            {
                res = Employees[EmployeesSelectedIndex].Subordinates;
            }

            return res;
        }
    }

    public string Name
    {
        get;
        set;
    }

    public override string ToString()
    {
        return this.Name;
    }

    // This method is called by the Set accessor of each property. 
    // The CallerMemberName attribute that is applied to the optional propertyName 
    // parameter causes the property name of the caller to be substituted as an argument. 
    private void NotifyPropertyChanged(String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
} 

每个部门都包含在该部门工作的员工集合。

Department 类还包含以下成员

  1. EmployeesSelectedIndex
  2. 下属列表
  3. NotifyPropertyChanged 机制

所有这些都用于实现主/从逻辑,将在下面的“主/从逻辑”部分中进行解释。

展示数据 (UI)

为了简单起见,我们在 ItemsControl 中展示数据

<!-- Data rows -->
<ItemsControl ItemsSource="{Binding Items}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal" MinWidth="320">                    
                <TextBlock Width="130" Text="{Binding Name}"/>          
                <ComboBox Width="130" ItemsSource="{Binding Employees}" SelectedIndex="{Binding EmployeesSelectedIndex}" />         
                <ComboBox Width="130" ItemsSource="{Binding Subordinates}" />            
            </StackPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl> 

因此,我们在这里处理的只是一个 DataTemplate,其中包含

  • TextBlock - 用于部门名称。
  • ComboBox - 用于部门员工姓名
  • ComboBox - 用于选定员工的下属

请注意:在附件的下载代码示例中,每个数据项还包含标题、边框和其他简单的 UI 装饰,但逻辑是相同的。

它应该看起来像这样

主/从逻辑

我们需要将特定员工的选择连接到该员工的下属列表

这就是 Department 类包含的原因

  1. EmployeesSelectedIndex
  2. 下属列表
  3. NotifyPropertyChanged 机制

让我们看看它是如何工作的

关于下载示例

下载示例有点复杂

Master-Detail Simple 文件还包含

  • 每个数据项的标题、边框和其他简单的 UI 装饰。
  • 下属的 Selected-Index 用于默认选择下属 ComboBox 中的第一个索引。
  • 下属的 Is-Enabled 用于在没有项目时禁用下属 ComboBox。

Master-Detail Advanced 文件还包含

  • 以上所有 (来自 Simple 示例)
  • 员工-图像 & 下属-图像

© . All rights reserved.