c # WPF linq GroupПрисоединиться к DataGrid - PullRequest
0 голосов
/ 05 мая 2019

У меня есть списки с emps и depts.Мне нужно показать в DataGrid все depts (в том числе без emps) с их emps.

На данный момент я показываю все depts в DataGrid, но я понятия не имею, как добавить emp и показать его в DataGrid.

Возможно, мне нужно что-то подобное в DataGrid:

-dept1
    -emp1
    -emp2
-dept2
    -emp3
...
List<Emp> Emps = new List<Emp>();
List<Dept> Depts = new List<Dept>();
DataGrid.ItemsSource = Depts.GroupJoin(Emps, dept => dept.Deptno, emp => emp.Deptno, 
                (dept, emp) => dept);
<DataGrid Name="DataGrid" Grid.Row="1" Grid.RowSpan="2">

</DataGrid>

1 Ответ

0 голосов
/ 05 мая 2019

Я предлагаю создать третий простой класс модели (помимо 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

РЕДАКТИРОВАТЬ:

Подход без каких-либо дополнительных классов:

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) });

    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...