Как объединить две ObservableCollection (WPF)

279
28 октября 2018, 17:40

Подскажите, пожалуйста, как можно объединить две коллекции в одну, чтобы получилась не сплошная строка например:

У меня есть основная коллекция Employee данная коллекция имеет базовые параметры: Name, SurName, Age;

Также есть вторая коллекция, которая выводит список отделов departments, далее коллекций может быть множество.

   public MainWindowViewModel()
    {
        employees = new ObservableCollection<Employee>(Employee.GetEmployees());
        departments = new ObservableCollection<Department>(Department.GetDepartments());
        var result2 = employees.Zip(departments,
                      (Employee, Department) => new
                      {
                          Name = Employee.Name,
                          SurName = Employee.SurName,
                          Age = Employee.Age,
                          DepName = Department.DepName
                      });
        employees = new ObservableCollection<Employee>(result2);
    }

employees = new ObservableCollection<Employee>(result2); - не работает.

Итог: Есть коллекция Employee и Department, для каждого (сотрудника)Employee должно быть задано одно поле DepName из Department, при этом обращение к DepName, в дальнейшем должно быть из Employee. Т.е к сотруднику прибавляется поле из Department и если я вызываю сотрудника получаю поля из Employee и новое поле DepName из Department

P.S. изучаю патерн MVVM, пока решения не нашел.

Примеры классов (Employee):

/// <summary>
/// Сотрудник
/// </summary>
public class Employee : INotifyPropertyChanged
{
    static Random r = new Random();
    private string _name;
    private string _surname;
    private int _age;
    /// <summary>
    /// Имя
    /// </summary>
    /// 
    public string Name
    {
        get { return _name; }
        set { _name = value;
            OnPropertyChanged("Name");
        }
    }
    /// <summary>
    /// Фамилия
    /// </summary>
    public string SurName
    {
        get { return _surname; }
        set
        {
            _surname = value;
            OnPropertyChanged("SurName");
        }
    }
    /// <summary>
    /// Возвраст
    /// </summary>
    public int Age
    {
        get { return _age; }
        set
        {
            _age = value;
            OnPropertyChanged("Age");
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    public static Employee[] GetEmployees()
    {
        var result = new Employee[]
        {
            new Employee() { Name = $"User_name_0", SurName = $"SurName_0", Age = r.Next(20, 30) },
            new Employee() { Name = $"User_name_1", SurName = $"SurName_1", Age = r.Next(20, 30) },
            new Employee() { Name = $"User_name_2", SurName = $"SurName_2", Age = r.Next(20, 30) },
            new Employee() { Name = $"User_name_3", SurName = $"SurName_3", Age = r.Next(20, 30) },
        };
        return result;
    }
    void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

Примеры классов (Department):

/// <summary>
/// Отдел
/// </summary>
class Department : INotifyPropertyChanged
{
    private string _DepName;
    public event PropertyChangedEventHandler PropertyChanged;
    /// <summary>
    /// Название отдела
    /// </summary>
    /// 
    public string DepName
    {
        get { return _DepName; }
        set
        {
            _DepName = value;
            OnPropertyChanged("DepName");
        }
    }
    public static Department[] GetDepartments()
    {
        var result = new Department[]
        {
            new Department() { DepName = $"Dep_name_0" },
            new Department() { DepName = $"Dep_name_1" },
            new Department() { DepName = $"Dep_name_2" },
            new Department() { DepName = $"Dep_name_3" },
        };
        return result;
    }
    public override string ToString()
    {
        return $"{DepName}";
    }

    void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

В итоге необходимо чтобы к классу Employee, добавилось поле Department(DepName)

И в дальнейшем обращаться только к Employee и его дополнительным полям.

Answer 1

Необходимо использовать 2 коллекции, для клиентов/пользователей/пр. и для отделов:

View:
<Window.DataContext>
    <local:MainVM/>
</Window.DataContext>
<StackPanel>
    <ComboBox ItemsSource="{Binding ComboBoxSource}" 
              SelectedItem="{Binding ComboBoxSelectedItem}"
              Width="100"/>
    <ListBox ItemsSource="{Binding ListBoxSource}"/>
</StackPanel>
ViewModel:
class MainVM : ViewModelBase
{
    /// <summary>
    /// Employee (например).
    /// </summary>
    public ObservableCollection<int> ComboBoxSource { get; set; } = new ObservableCollection<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    /// <summary>
    /// Department (например).
    /// </summary>
    public ObservableCollection<object> ListBoxSource { get; set; }
    int comboBoxSelectedItem;
    public int ComboBoxSelectedItem
    {
        get => comboBoxSelectedItem;
        set
        {
            comboBoxSelectedItem = value;
            RaisePropertyChanged(); // Реализация INotifyPropertyChanged
            LoadData(); //Загрузка данных для ListBox'a
        }
    }
    /// <summary>
    /// Можно сделать асинхронным, если будет подгрузка из базы и пр.
    /// </summary>
    private void LoadData()
    {
        ListBoxSource = new ObservableCollection<object>
        {
            $"ComboBoxSource: {ComboBoxSelectedItem}",
            1,2,3,4,5,6,7,8,9
        };
        RaisePropertyChanged(nameof(ListBoxSource)); // Реализация INotifyPropertyChanged
    }
READ ALSO
Не могу обратится к ListBox С# MVVM WPF

Не могу обратится к ListBox С# MVVM WPF

Цель - сделать отчет в CSV файл

168
Исключение типа StackOverflow C#

Исключение типа StackOverflow C#

В строке определения переменной text возникает ошибка StackOverflow и не знаю как можно избавиться от его потому что условие обязательное

165
Странное поведение if-else

Странное поведение if-else

Метод обрабатывает нажатие клавишы на клавиатуре (глобальный хук) и скрывает элементы на экранеОднако почему-то после активации if(!SomeOpened)...

192
Cбой операции во время установки NLog.Configuration

Cбой операции во время установки NLog.Configuration

Cбой во время установки НЛог там говориться что оно уже установлено но как можно включить это в референсес в Visual Studio 2012 Идет попытка разрешить...

207