在Caliburn Micro的ViewModel列表中选择ViewModel时,在ListBox上交换绑定?

时间:2013-03-20 15:54:45

标签: c# wpf viewmodel caliburn.micro

我有一个ViewModel列表,每个ViewModel都包含一个列表。

我想将此列表绑定到视图中的ListBox,以便我可以设置SelectedViewModel,并且视图中的ListBox现在显示新SelectedViewModel中的条目。这也应该保留选择。

是否可以使用当前的Caliburn Micro惯例执行此操作,还是必须明确说明这一点?

例如:

我有一个名为vmList的ViewModel列表,其中包含两个ViewModel,FruitVeg

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中的选定项目。

1 个答案:

答案 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