首先请注意,我并未提及任何特定的框架或技术,例如XAML。
问题是如何使用ICommand
实现MvvM模式以选择列表中的项目(=单击一行)?
我有一个视图模型(伪代码):
class ListViewModel
{
// Items in the list.
public ObservableCollection<T> Items {};
// Command for item selection.
public ICommand ItemSelectedCommand
{
...
}
// Select an item in the list.
public void SelectItem(int index)
{
...
}
// The current selected item.
public T SelectedItem
{
get { ... };
}
}
我现在如何“手动”将我的UI连接到该视图模型?比如说,在iOS应用程序中。
我可能会有UITableViewController
,获取视图模型的实例并从中填充UITableView
内容。然后我会从ICommand
方法触发RowSelected()
。
这就是我不明白的事情:视图模型现在如何知道选择了哪个项目索引?我不想打电话给SelectItem()
,因为那时我根本不需要松散耦合的ICommand
。
也许在这里我们必须看看如何在XAML中解决它以理解这个技巧?
答案 0 :(得分:0)
来自XAML和WPF,有两个选项可以将选择更改从UI转发到ViewModel(因为我理解您的问题,您并没有问过另一种方式 - 将ViewModel中的更改反馈给用户界面 - 这里):
带有效负载的命令
ICommand
s Execute
方法有一个有效负载参数。执行没有有效负载的命令可以通过null传递:
SomeCommand.Execute(null);
在您的情况下,将所选项目作为事件处理程序中的参数传递是有意义的:
vm.ItemSelectedCommand.Execute(eventArgs.SelectedItem);
或
vm.ItemSelectedCommand.Execute(myList.SelectedItem);
在命令的执行方法中,您可以处理该参数。请注意,此处不直接涉及您的ViewModel属性SelectedItem
。如果您需要明确选择所选索引(通常不是这种情况),我会检查Items
集合中所选项目的索引。
将所选列表项绑定到ViewModel属性
选项B是&#39;绑定&#39;列表的选定项目到ViewModel上的不同属性,在您的情况下,列表的事件处理程序中的 SelectedItem 属性:
vm.SelectedItem = myList.SelectedItem;
该命令有点冗余,尽管您可以在ViewModel上设置SelectedItem后在没有有效负载的情况下调用它。我宁愿在ViewModel上的属性的set访问器中处理所选项的更改。
注意:XAML和WPF提供了大量开箱即用的基础设施代码。如果没有适当的框架来实际处理以松散耦合方式绑定UI和ViewModel的MVVM,MVVM是没有意义的。你很快就会得到很多额外的工作和很少的好处,因为你仍然保持着严格的依赖关系。结论:我建议在实际实现之前获取或编写适当的MVVM框架。