Caliburn.micro,WPF和两个组合框

时间:2018-12-10 12:57:42

标签: c# wpf xaml mvvm caliburn.micro

我想用我的Caliburn.Micro + wpf项目解决Master-> Detail问题。

我在 TaskManagerView.xaml 中有两个这样编码的comboboxes

<ComboBox x:Name="ProjectsList" SelectedValuePath="{Binding Path=SelectedProjectsList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

<ComboBox x:Name="TasksList"/>

第一个组合框ProjectsList正常工作,我可以得到想要的东西。第二个有点复杂。我正确获得了SelectedProjectList(在按钮上进行即时调试时,我看到了我选择的内容)。 ProjectsListnew Project()类中的项目的名称。我在Project中存储Task的列表。但是当我想填写TasksList时,我会得到例外。

现在,我的 TaskManagerViewModel

    class TaskManagerViewModel : Screen //constructor of ViewModel
    {
        public BindableCollection<string> ProjectsList { get; set; } //first CB
        public BindableCollection<string> TasksList { get; set; } //secondCB
        public string SelectedProjectsList { get; set; }//selected item from first combobox

        public TaskManagerViewModel(FakeData context) //constructor
        {
            this.context = context;
            //it works fine, i get Project.Name here from List<Project>
            ProjectsList = context.GetProjectsName();

            //i selected project name from combobox,
            //now i want to get tasks stored in List<Project> 
            //where SelectedProjectsList == Project.Name
            tasks = context.GetProjectsTasks(SelectedProjectsList); 
            foreach (Task task in tasks)
            {
                TasksList.Add(task.TaskName);
                NotifyOfPropertyChange(() => TasksList);
            }
        }


        public void CancelButton() => TryClose();

        private FakeData context;
        private List<Task> tasks;
    }

我的问题是,代码帮助程序在哪里以及如何获得List<Task>'s名称?我知道我在这里做的不好,因为我在ViewModel的construcotr中做所有事情,但我想向你展示,我想做什么。

现在,我得到NullReferenceException,因为SelectedProjectsList为空。如何提升ComboBox中所选项目上的事件?我选择了项目名称,然后立即希望从所选项目中获得任务(我知道我可以轻松地通过按钮来完成任务,但是我想达到的目标不是这样)

感谢您的任何建议!

编辑:

当然,如果我将VM编辑为以下形式:

class TaskManagerViewModel : Screen
{
    public BindableCollection<string> ProjectsList { get; set; }
    public BindableCollection<string> TasksList{ get; set; }
    public string SelectedProjectsList { get; set; }

    public TaskManagerViewModel(FakeData context)
    {
        this.context = context;
        ProjectsList = context.GetProjectsName();
        TasksList = new BindableCollection<string>();
        //i moved initializing new combobox to AcceptButton()
    }

    public void AcceptButton()
    {
        //initializing tasks list on button click
        tasks = context.GetProjectsTasks(SelectedProjectsList);
        TasksList = new BindableCollection<string>();
        foreach (Task task in tasks)
        {
            TasksList.Add(task.TaskName);
            NotifyOfPropertyChange(() => TasksList);
        }
    }

    public void CancelButton() => TryClose();

    private FakeData context;
    private List<Task> tasks;
}

我想做的是从第一个组合框中选择一个项目,第二个任务列表显示出来。我不想从第一个组合框中选择项目,单击按钮,然后从第二个组合框中选择项目

1 个答案:

答案 0 :(得分:1)

因为这是MVVM,所以您的ViewModel不知道组合框或其事件,因此您无法直接订阅控件的事件。

当您在项目列表中选择一个项目时,它会为SelectedProjectsList属性设置一个值,您可以使用以下方法:

private string _selectedProjectsList;
public string SelectedProjectsList
{
    get
    {
        return _selectedProjectsList;
    }
    set
    {
        _selectedProjectsList = value;
        // project selection has been changed, populate your task list now!
        // upd: actual code for populating the list
        tasks = context.GetProjectsTasks(SelectedProjectsList);
        TasksList = new BindableCollection<string>();
        foreach (Task task in tasks)
        {
            TasksList.Add(task.TaskName);
        }
        NotifyOfPropertyChange(() => TasksList);
    }
}