【问题标题】:Swapping the binding on a ListBox when selecting a ViewModel in a List of ViewModels in Caliburn Micro?在 Caliburn Micro 的 ViewModel 列表中选择 ViewModel 时交换 ListBox 上的绑定?
【发布时间】:2013-03-20 15:54:44
【问题描述】:

我有一个 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 是当前列表框中的选中项。

现在我将Veg 设置为SelectedViewModel,并显示我的视图更新:

*Carrot*
Cabbage

Carrot 是当前列表框中的选定项。 现在,如果我将 Fruit 设置回 SelectedViewModel 我的视图应该更新为显示:

Apple
*Pear*

Pear 仍然是 ListBox 中的选定项。

【问题讨论】:

    标签: c# wpf viewmodel caliburn.micro


    【解决方案1】:

    这应该是可能的 - 最简单的功能是使用 CM 约定来绑定列表内容,并为列表提供 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}" />
    

    显然在此处设置您的项目模板以绑定到视图模型上的公共属性(例如 DisplayName 使用 IHaveDisplayName 接口以保持良好和集成)

    编辑:

    请注意:如果您的虚拟机本身不是 List 对象而是包含一个列表,那么您可能必须将列表项显式绑定到 ListBox 但这取决于您的 ItemTemplate(您可以让 CM 继续解析基于 ContentControl 约定绑定的虚拟机和虚拟机视图)

    <ListBox ItemsSource="{Binding SelectedViewModel.ListItems}" ...etc />
    

    【讨论】:

      猜你喜欢
      • 2019-12-11
      • 2020-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-01
      • 1970-01-01
      • 2013-12-30
      • 2012-03-23
      相关资源
      最近更新 更多