WPF MVVM ComboBox SelectionChanged - PullRequest
0 голосов
/ 01 октября 2018

У меня есть два комбинированных списка, с именами заданий и отделов в качестве ItemSource.

элементы jobComboBox: m_job1, m_job2, n_job1, n_job2 DepartmentComboBox items: m_dep, n_dep

(такое именование простодля понимания)

Итак, m_job не может быть в n_dep, а n_job не может быть в m_dep.

Я хочу, чтобы jobComboBox.ItemSource состоял из соответствующих заданий, так как департаментComboBox.SelectedItem без события.обработка.

Код ViewModel:

private static List<string> job_names = new List<string>();
public List<string> Job_names
{
    get { return job_names; }
    set
    {
        job_names = value;
    }
}


private static List<string> dep_names = new List<string>();
public List<string> Dep_names
{
    get { return dep_names; }
    set
    {
        dep_names = value;
    }
}

Здесь я добавляю несколько заданий и отделов в конструктор ViewModel.

public ViewModel()
{
    foreach (Jobs j in init_jobs)
    {
        if (j.fee == null)
        {
            job_names.Add(j.job_name);
        }
    }

    foreach (Departments d in init_deps)
    {
        if (d.workers_amount == null)
        {
            dep_names.Add(d.department_name);
        }
    }
}

Код XAML:

<ComboBox Grid.Column="0" Grid.Row="1" x:Name="departmentComboBox" 
           ItemsSource="{Binding Dep_names}" 
           SelectedItem="{Binding Selected_dep_name}"/>

<ComboBox Grid.Column="1" Grid.Row="1" x:Name="jComboBox"
           ItemsSource="{Binding Job_names}"
           SelectedItem="{Binding Selected_job_name}"/>

Скажите, пожалуйста, правильно ли мое связывание или нет.Пожалуйста, помогите мне решить эту проблему.

Ответы [ 2 ]

0 голосов
/ 02 октября 2018

Возможно, вы захотите использовать ICollectionView, как я использовал в приведенном ниже коде: (Этот код только для информации, измените его в соответствии с вашими требованиями.)

Просмотр:

<Grid Margin="10">
    <Grid.RowDefinitions>
        <RowDefinition Height="auto" />
        <RowDefinition Height="auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <ComboBox ItemsSource="{Binding DepartmentsView}"
            Grid.Row="0" Margin="10"
            DisplayMemberPath="Name" SelectedItem="{Binding SelectedDepartment}" />

    <ComboBox ItemsSource="{Binding JobsView}"
            Grid.Row="1" Margin="10"
            DisplayMemberPath="Name" />
</Grid>

ViewModel и родственные классы:

public abstract class DropDownItem
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class Job : DropDownItem
{

}

public class Department : DropDownItem
{
    public bool DoesJobBelongsToDepartment(Job job)
    {
        return job?.Id % Id == 0;
    }
}

public class ViewModel : ViewModelBase
{
    private List<Job> jobs;
    private List<Department> departments;

    public ICollectionView JobsView { get; }
    public ICollectionView DepartmentsView { get; }

    private Department selectedDepartment;
    public Department SelectedDepartment
    {
        get { return selectedDepartment; }
        set
        {
            selectedDepartment = value;
            JobsView.Refresh();
            RaisePropertyChanged(nameof(SelectedDepartment));
        }
    }

    public ViewModel()
    {
        jobs = new List<Job>(Enumerable.Range(1, 21).Select(x => new Job { Id = x, Name = $"Job {x}" }));
        departments = new List<Department>(Enumerable.Range(1, 5).Select(x => new Department{ Id = x, Name = $"Department {x}" }));

        DepartmentsView = CollectionViewSource.GetDefaultView(departments);

        JobsView = CollectionViewSource.GetDefaultView(jobs);
        JobsView.Filter = JobsViewFilter;
    }

    private bool JobsViewFilterPredicate(Object obj)
    {
        var job = obj as Job;
        return SelectedDepartment == null ? false
                                            : SelectedDepartment.DoesJobBelongsToDepartment(job);
    }
}

Объяснение:

В приведенном выше коде яесть 2 класса Job и Department для хранения информации о работе и отделе.В ViewModel я инициализирую списки несколькими фиктивными значениями и использую CollectionViewSource.GetDefaultView, чтобы получить экземпляр по умолчанию ICollectionView для списков.Обратите внимание, я применил фильтр для JobsView, который будет фильтровать данные на основе SelectedDepartment с использованием функции JobsViewFilterPredicate.

Надеюсь, это поможет!

0 голосов
/ 01 октября 2018

Я бы создал класс для отделов.Класс отдела будет иметь свойство JobNames, содержащее список всех имен должностей для конкретного отдела.Класс Отдела также будет содержать имя свойства для отдела.Dep_names станет List<Department>.

Тогда вы можете изменить свой XAML на:

<ComboBox Grid.Column="0" Grid.Row="1" x:Name="departmentComboBox" 
           ItemsSource="{Binding Dep_names}"
           DisplayMemberPath="Name" 
           SelectedItem="{Binding Selected_dep_name}"/>

<ComboBox Grid.Column="1" Grid.Row="1" x:Name="jComboBox"
           ItemsSource="{Binding ElementName=departmentComboBox, Path=SelectedItem.JobNames}"
           SelectedItem="{Binding Selected_job_name}"/>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...