Caliburn.micro、WPF 和两个组合框
Caliburn.micro, WPF and two comboboxes
我想解决我的 Caliburn.Micro + wpf 项目的 Master -> Detail 问题。
我有两个 comboboxes
在 TaskManagerView.xaml:
中这样编码
<ComboBox x:Name="ProjectsList" SelectedValuePath="{Binding Path=SelectedProjectsList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<ComboBox x:Name="TasksList"/>
第一个 Combobox ProjectsList
工作正常,我可以得到我想要的。二是有点复杂。我得到 SelectedProjectList
正确(当我在按钮上调试时,我看到了我选择的内容)。 ProjectsList
是 new Project()
class 中的项目名称。在 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 的构造中做了所有事情,但我想告诉你我想做什么。
目前,我得到 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;
}
我想要做的是从第一个组合框中选择项目,然后立即显示第二个中的任务列表。我不想从第一个组合框中选择项目,单击按钮然后从第二个组合框中选择项目
因为这是 MVVM,您的 ViewModel 不知道组合框或它们的事件,所以您不能直接订阅控件的事件。
当您 select 项目列表中的项目时,它会为 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);
}
}
我想解决我的 Caliburn.Micro + wpf 项目的 Master -> Detail 问题。
我有两个 comboboxes
在 TaskManagerView.xaml:
<ComboBox x:Name="ProjectsList" SelectedValuePath="{Binding Path=SelectedProjectsList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<ComboBox x:Name="TasksList"/>
第一个 Combobox ProjectsList
工作正常,我可以得到我想要的。二是有点复杂。我得到 SelectedProjectList
正确(当我在按钮上调试时,我看到了我选择的内容)。 ProjectsList
是 new Project()
class 中的项目名称。在 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 的构造中做了所有事情,但我想告诉你我想做什么。
目前,我得到 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;
}
我想要做的是从第一个组合框中选择项目,然后立即显示第二个中的任务列表。我不想从第一个组合框中选择项目,单击按钮然后从第二个组合框中选择项目
因为这是 MVVM,您的 ViewModel 不知道组合框或它们的事件,所以您不能直接订阅控件的事件。
当您 select 项目列表中的项目时,它会为 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);
}
}