2

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. 如何从第二级标题(经理)绑定到第一分组级别属性(部门)以实现所需的“部门(经理)”?

  3. 有没有比创建 2 个分组级别更好的方法来做到这一点?

谢谢

4

2 回答 2

3

解决了主要的绊脚石,上面的问题 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>

于 2013-10-07T18:06:58.150 回答
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)));

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

于 2013-10-07T19:08:37.547 回答