WPF MVVM组合框选择已更改

时间:2018-10-01 20:06:14

标签: wpf mvvm

我有两个comboBoxes,名称分别为Jobs和Departments作为ItemSource。

jobComboBox项:m_job1,m_job2,n_job1,n_job2 departmentComboBox项:m_dep,n_dep

(这种命名只是为了理解)

因此,m_job不能位于n_dep中,n_job不能位于m_dep中。

由于departmentComboBox.SelectedItem,我希望jobComboBox.ItemSource由相关作业组成,而没有事件处理。

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 :(得分:0)

我将为部门创建一个班级。部门类将具有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}"/>

答案 1 :(得分:0)

您可能想使用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个类JobDepartment用于存储有关职位和部门的信息。在ViewModel中,我正在初始化带有少量虚拟值的列表,并在使用CollectionViewSource.GetDefaultView获取列表的默认ICollectionView实例。请注意,我为JobsView应用了过滤器,该过滤器将使用SelectedDepartment函数基于JobsViewFilterPredicate过滤数据。

希望这会有所帮助!