【问题标题】:Caliburn.micro, WPF and two comboboxesCaliburn.micro、WPF 和两个组合框
【发布时间】:2018-12-10 12:57:41
【问题描述】:

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

我在 TaskManagerView.xaml 中有两个 comboboxes 编码如下:

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

<ComboBox x:Name="TasksList"/>

第一个 Combobox ProjectsList 工作正常,我可以得到我想要的。二是有点复杂。我得到SelectedProjectList 正确(当我在按钮上调试时,我看到我选择了什么)。 ProjectsList 是来自 new 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&lt;Task&gt;'s 名称的代码助手功能在哪里以及如何使用?我知道我在这里做的很糟糕,因为我在 ViewModel 的构造中做了所有事情,但我想向你展示我想做的事情。

现在,我得到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;
}

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

【问题讨论】:

    标签: c# wpf xaml mvvm caliburn.micro


    【解决方案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);
        }
    }
    

    【讨论】:

    • 请看我的编辑,你的回答不是关于我的问题,但我给你+1的尝试,谢谢!
    • 我仍然不明白这不能回答你的问题。当您的用户在项目列表组合框中选择一个项目时,您的 SelectProjectsList 属性将被设置。如果您的设置器过载,您可以立即填充您的任务列表组合框。
    • 这就是这个解决方案的作用:它“监听”到 SelectedProjectsList 上的设置。您能否更具体地说明“不工作”的部分。究竟是什么不工作?
    • 对不起,我没有看到你编辑了你的答案。现在很好用,谢谢!但是为什么当我尝试处理SelectedProjectListsget { return this.SelectedProjectLists } 等...)时我得到StackOverflowException?现在使用私有财产似乎很老套
    • 你得到 StackOverflowException 的原因是通过调用“return this.SelectedProjectLists”你实际上又调用了 SelectedProjectsList 的 getter。再次调用它。再次调用它。以此类推,直到没有剩余的堆栈。自动属性只是语法糖;过多的糖分可能对您的健康有害。
    猜你喜欢
    • 2013-06-05
    • 1970-01-01
    • 2013-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-02
    相关资源
    最近更新 更多