You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Prism中如何在ObservableCollection中使用ViewModel?

解决方案:在ListView的DataTemplate中绑定子项ViewModel的属性

当然可行!这其实是MVVM模式里非常常见的做法,核心就是把你的ObservableCollection存储的对象从Model换成子项的ViewModel,这样就能直接在ListView的DataTemplate里绑定子ViewModel的属性了。我给你一步步拆解怎么实现:

1. 调整集合类型:存储子ViewModel而非Model

把PickList ViewModel中原来的ObservableCollection<PickLineModel>改成ObservableCollection<PickLineViewModel>。这样ListView的每个数据源元素都是子ViewModel,而非原始Model。

2. 实现子ViewModel(PickLineViewModel)

让子ViewModel持有对应的PickLineModel,并在内部处理展示逻辑(比如你需要的QuantityString)。记得实现INotifyPropertyChanged接口,保证属性变化能同步到视图:

public class PickLineViewModel : INotifyPropertyChanged
{
    private readonly PickLineModel _model;

    public PickLineViewModel(PickLineModel model)
    {
        _model = model;
        // 监听Model的属性变化,同步更新ViewModel的展示属性
        _model.PropertyChanged += (sender, args) =>
        {
            if (args.PropertyName is nameof(PickLineModel.PickedQuantity) or nameof(PickLineModel.OpenQuantity))
            {
                OnPropertyChanged(nameof(QuantityString));
            }
        };
    }

    // 你需要的组合字符串属性
    public string QuantityString => $"{_model.PickedQuantity} / {_model.OpenQuantity}";

    // 实现INotifyPropertyChanged
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

3. 初始化PickList ViewModel的集合

在PickList ViewModel中,把加载到的PickLineModel转换成PickLineViewModel,加入集合:

public class PickListViewModel : INotifyPropertyChanged
{
    public ObservableCollection<PickLineViewModel> PickLines { get; } = new();

    public PickListViewModel()
    {
        // 模拟从数据源加载Model列表
        var pickLineModels = LoadPickLineModels();
        foreach (var model in pickLineModels)
        {
            PickLines.Add(new PickLineViewModel(model));
        }
    }

    private List<PickLineModel> LoadPickLineModels()
    {
        // 替换成你的实际数据加载逻辑
        return new List<PickLineModel>
        {
            new() { PickedQuantity = 3, OpenQuantity = 10 },
            new() { PickedQuantity = 0, OpenQuantity = 5 }
        };
    }

    // INotifyPropertyChanged实现...
}

4. 在XAML中直接绑定子ViewModel的属性

现在你可以在ListView的DataTemplate里直接绑定QuantityString了,因为每个Item的DataContext就是PickLineViewModel:

<ListView ItemsSource="{Binding PickLines}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <Label Text="{Binding QuantityString}" />
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

额外说明

  • 这种方式完全符合MVVM的职责分离:视图只负责展示,ViewModel负责处理展示逻辑(比如字符串拼接),Model只存储原始数据。
  • 如果后续需要修改QuantityString的格式(比如添加单位、改变分隔符),只需要修改PickLineViewModel的属性即可,不用改动XAML。
  • 关于导航传递数据:如果需要在选中项后传递数据到其他页面,你可以直接传递PickLineViewModel(它持有Model),或者从ViewModel中取出Model传递,灵活度很高。

内容的提问来源于stack exchange,提问作者Christoph Mett

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:45:16