Я предлагаю создать третий простой класс модели (помимо Emp
и Dept
), который будет содержать Deptno
и список всех имен его сотрудников.Давайте назовем это EmpsByDept
.Итак, теперь у нас есть:
public class Emp
{
public String Name { get; private set; }
public String Deptno { get; private set; }
public Emp(String name, String deptno)
{
Name = name;
Deptno = deptno;
}
}
public class Dept
{
public String Deptno { get; private set; }
public Dept(String deptno)
{
Deptno = deptno;
}
}
public class EmpsByDept
{
public String Deptno { get; private set; }
public String Emps { get; private set; }
public EmpsByDept(String deptno, IEnumerable<String> emps)
{
Deptno = deptno;
Emps = ConcatEmps(emps);
}
private String ConcatEmps(IEnumerable<String> emps)
{
StringBuilder sb = new StringBuilder();
foreach(var e in emps)
{
sb.AppendLine(e);
}
return sb.ToString();
}
}
Также я предлагаю использовать шаблон проектирования MVVM и создать модель представления для вашего окна, которая будет содержать два списка с исходными данными и ObservableCollection
, которые мы будем использовать в качествеItemsSource
DataGrid
:
class TestViewModel
{
public readonly List<Emp> Emps = new List<Emp> { new Emp("emp1", "dept1"), new Emp("emp2", "dept1"), new Emp("emp3", "dept2") };
public readonly List<Dept> Depts = new List<Dept> { new Dept("dept1"), new Dept("dept2"), new Dept("dept3") };
public ObservableCollection<EmpsByDept> EmpsByDepts { get; private set; }
public TestViewModel()
{
EmpsByDepts = new ObservableCollection<EmpsByDept>(Depts.GroupJoin(Emps,
d => d.Deptno,
e => e.Deptno,
(dept, emps) =>
new EmpsByDept(dept.Deptno, emps.Select(e => e.Name))));
}
}
В конструкторе TestViewModel
мы инициализируем ObservableCollection
с результатами запроса LINQ.Теперь мы должны установить экземпляр TestViewModel
как DataContext
вашего окна:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new TestViewModel();
}
}
И связать ItemsSource
из DataGrid
с экземпляром нашего ObservableCollection
:
<Grid>
<DataGrid ItemsSource="{Binding Path=EmpsByDepts}"
AutoGenerateColumns="True"/>
</Grid>
Результат будет: ![enter image description here](https://i.stack.imgur.com/4BmEn.png)
РЕДАКТИРОВАТЬ:
Подход без каких-либо дополнительных классов:
public partial class MainWindow : Window
{
public readonly List<Emp> Emps = new List<Emp> { new Emp("emp1", "dept1"), new Emp("emp2", "dept1"), new Emp("emp3", "dept2") };
public readonly List<Dept> Depts = new List<Dept> { new Dept("dept1"), new Dept("dept2"), new Dept("dept3") };
public MainWindow()
{
InitializeComponent();
EmpsBuDeptDataGrid.ItemsSource = Depts.GroupJoin(Emps,
d => d.Deptno,
e => e.Deptno,
(dept, emps) =>
new { Deptno = dept.Deptno, Ems = emps.Select(e => e.Name).Aggregate(string.Empty, (s1, s2) => s1 + Environment.NewLine + s2) });
}
}