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; }
}
}
部门和经理之间存在一对一的关系,因此具有相同部门的任何两行也将具有相同的经理。
我想按部门/经理进行分组,组头显示“部门(经理)”。
我的CollectionViewSource看起来像
<CollectionViewSource x:Key="cvsEmployees" Source="{Binding Employees}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="Department" />
<PropertyGroupDescription PropertyName="Manager" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
计划是不显示第一级标题(Department)并以某种方式从第二级标题绑定到Department(第1级)和Manager(第2级)。
3个问题:
为了避免显示第一级标题,我在groupstyle中有一个空数据模板:
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
这看起来非常笨重。有没有更优雅的方法来跳过组头?
如何从第二级标题(Manager)绑定到第一个分组级别属性(部门)以获得所需的“部门(经理)”?
有没有比创建2个分组级别更好的方法?
由于
答案 0 :(得分: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>
答案 1 :(得分: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)));
请注意,我已在Equals
课程中覆盖DepartmentManager
,但未覆盖GetHashCode
,理想情况下,您应该对其进行自定义实施。我必须重写equals,以便分组视图源能够正确地对相同的条目进行分组。您可以摆脱这种需求,为集合外的相同Employees构建DepartmentManager
,并将它们传递到EmployeeModel
ctr。