我有一个ViewModel列表,每个ViewModel都包含一个列表。
我想将此列表绑定到视图中的ListBox,以便我可以设置SelectedViewModel
,并且视图中的ListBox现在显示新SelectedViewModel
中的条目。这也应该保留选择。
是否可以使用当前的Caliburn Micro惯例执行此操作,还是必须明确说明这一点?
例如:
我有一个名为vmList
的ViewModel列表,其中包含两个ViewModel,Fruit
和Veg
。
ViewModel Fruit
包含列表["Apple", "Pear"]
。
ViewModel Veg
包含列表["Carrot", "Cabbage"]
。
Fruit
是当前的SelectedViewModel
,因此我的视图的ListBox目前应显示:
Apple
*Pear*
Pear
当前是ListBox中的选定项目。
现在我将Veg
设为SelectedViewModel
,将我的查看更新设为:
*Carrot*
Cabbage
Carrot
当前是ListBox中的选定项。
现在,如果我将Fruit
设置回SelectedViewModel
我的视图应更新为显示:
Apple
*Pear*
其中Pear
仍然是ListBox中的选定项目。
答案 0 :(得分:1)
这应该是可能的 - 最简单的功能是使用CMs约定来绑定列表内容,并为列表提供SelectedItem
绑定。由于您要跟踪每个VM中最后选择的项目,因此您需要密切关注它(在VM本身或主VM中)
所以解决办法可能是:
public class ViewModelThatHostsTheListViewModel
{
// All these properties should have property changed notification, I'm just leaving it out for the example
public PropertyChangedBase SelectedViewModel { get; set; }
public object SelectedItem { get; set; }
// Dictionary to hold last selected item for each VM - you might actually want to track this in the child VMs but this is just one way to do it
public Dictionary<PropertyChangedBase, object> _lastSelectedItem = new Dictionary..etc()
// Keep the dictionary of last selected item up to date when the selected item changes
public override void NotifyOfPropertyChange(string propertyName)
{
if(propertyName == "SelectedItem")
{
if(_lastSelectedItem.ContainsKey(SelectedViewModel))
_lastSelectedItem[SelectedViewModel] = SelectedItem;
else
_lastSelectedItem.Add(SelectedViewModel, SelectedItem);
}
}
}
然后在你的XAML中
<ListBox x:Name="SelectedViewModel" SelectedItem="{Binding SelectedItem, Mode=TwoWay}" />
显然,在这里将项目模板设置为绑定到viewmodel上的公共属性(例如使用DisplayName
接口的IHaveDisplayName
以保持良好和集成)
编辑:
快速说明一下:如果您的虚拟机本身不是List
个对象而是包含一个列表,那么您可能必须明确地将列表项绑定到ListBox
,但这取决于您的{ {1}}(您可以让CM根据ItemTemplate
约定绑定继续解析VM的VM和视图)
ContentControl