【问题标题】:WPF ListView grouping by 2 columns but display only 1 group headerWPF ListView 按 2 列分组,但仅显示 1 个组标题
【发布时间】:2013-10-13 20:39:57
【问题描述】:

ListView 显示以下类的集合:

public class Employee
{
    private string _department;
    private string _manager;
    private string _name;
    private string _address;

    public string Department
    {
        get { return _department; }
    }
    public string Manager
    {
        get { return _manager; }
    }
    public string Name
    {
        get { return _name; }
    }
    public string Address
    {
        get { return _address; }
    }
}

部门和经理之间存在一对一的关系,因此具有相同部门的任何 2 行也将具有相同的经理。

我想按部门/经理分组,组标题显示“部门(经理)”。

我的 CollectionViewSource 看起来像

    <CollectionViewSource x:Key="cvsEmployees" Source="{Binding Employees}">
        <CollectionViewSource.GroupDescriptions>
            <PropertyGroupDescription PropertyName="Department" />
            <PropertyGroupDescription PropertyName="Manager" />
        </CollectionViewSource.GroupDescriptions>
    </CollectionViewSource>

计划是不显示第一级标题(部门),并以某种方式从第二级标题绑定到部门(第一级)和经理(第二级)。

3 个问题:

  1. 为避免显示第一级标题,我在 groupstyle 中有一个空的数据模板:

    <GroupStyle>
        <GroupStyle.HeaderTemplate>
           <DataTemplate>
           </DataTemplate>
        </GroupStyle.HeaderTemplate>
    </GroupStyle>
    

    这看起来很笨重。有没有更优雅的方式来跳过组头?

  2. 如何从2级标题(经理)绑定到1级分组属性(部门)以实现所需的“部门(经理)”?

  3. 有没有比创建 2 个分组级别更好的方法?

谢谢

【问题讨论】:

  • 您能否为 ListView 显示您的 ItemsSource,即构成您的 ItemsSource 的实际 .cs 类。
  • 在原始问题中添加的类

标签: wpf listview grouping


【解决方案1】:

解决了主要的绊脚石,上面的问题 2:如何从组头绑定到不是分组属性的属性。

解决方法是将数据上下文更改为:{Binding Items}。然后可以使用 ItemSource 属性

<GroupStyle>
    <GroupStyle.HeaderTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal" Margin="0,10,0,3" DataContext="{Binding Items}" >
                <TextBlock Text="{Binding Path=Department}" FontWeight="Bold" Margin="3"/>
                <TextBlock Text="{Binding Path=Manager, StringFormat='({0})'}" Margin="3"/>
            </StackPanel>
        </DataTemplate>
    </GroupStyle.HeaderTemplate>
</GroupStyle>

【讨论】:

  • 但仍然希望能回答问题 1 和 3。谢谢
【解决方案2】:

我将创建另一个模型部件,它代表您需要进行的双重分组:

模型类:

public class EmployeeModel {

        private readonly Employee _Employee;

        public DepartmentManager ManagementInfo { get; private set; }

        public string Name {
            get { return _Employee.Name; }
        }
        public string Address {
            get { return _Employee.Address; }
        }

        public EmployeeModel(Employee employee) {
            this._Employee = employee;
            this.ManagementInfo = new DepartmentManager(employee.Department, employee.Manager);
        }
    }

    public class DepartmentManager {

        public string Department { get; private set; }
        public string Manager { get; private set; }

        public DepartmentManager(string dept, string manager) {
            this.Department = dept;
            this.Manager= manager;
        }

        public override bool Equals(object obj) {
            var model = obj as DepartmentManager;
            if(null == model)
                return false;

            return Department.Equals(model.Department, StringComparison.InvariantCultureIgnoreCase) && 
                Manager.Equals(model.Manager, StringComparison.InvariantCultureIgnoreCase);
        }
    }

XAML:

    <CollectionViewSource x:Key="cvsEmpsModel" Source="{Binding EmployeesModel}">
        <CollectionViewSource.GroupDescriptions>
            <PropertyGroupDescription PropertyName="ManagementInfo" />
        </CollectionViewSource.GroupDescriptions>
    </CollectionViewSource>

    <DataTemplate DataType="{x:Type models:EmployeeModel}">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding Name}" />
            <TextBlock Text="{Binding Address}" />
        </StackPanel>
    </DataTemplate>

...
    <ListView ItemsSource="{Binding Source={StaticResource cvsEmpsModel}}">
            <ListView.GroupStyle>
                <GroupStyle>
                    <GroupStyle.HeaderTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal" Margin="0,10,0,3" DataContext="{Binding Items}">
                                <TextBlock Text="{Binding Path=ManagementInfo.Manager}" FontWeight="Bold" Margin="3" />
                                <TextBlock Text="{Binding Path=ManagementInfo.Department, StringFormat='({0})'}" Margin="3" />
                            </StackPanel>
                        </DataTemplate>
                    </GroupStyle.HeaderTemplate>
                </GroupStyle>
            </ListView.GroupStyle>
        </ListView>

然后在您的 Window/ViewModel 中:

this.EmployeesModel = new ObservableCollection<EmployeeModel>(MyListOfEmployersFromDB.Select(e => new EmployeeModel(e)));

注意,我在DepartmentManager 类中覆盖了Equals,但没有覆盖GetHashCode,理想情况下您应该对此进行自定义实现。我必须覆盖 equals 以便分组视图源将正确分组相同的条目。您可以摆脱这种需求,购买为集合之外的相同员工构建DepartmentManager,并将它们传递给EmployeeModel ctr。

【讨论】:

    猜你喜欢
    • 2019-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多