如何在ListView绑定中创建/注册view / vewmodel的多个实例?

时间:2019-07-18 13:14:36

标签: c# wpf mvvm unity-container prism

使用带有棱镜和统一性的mvvm编写C#wpf应用程序,我找不到如何解决应该是常见的恕我直言的情况的答案:

在具有(xaml)绑定的ListView中显示多个视图。

在视图模型中具有一个名为MainTableItemsControl / MainTableItemsControlViewModel的View / ViewModel,并具有一个集合:

public WpfObservableRangeCollection<base_main> BaseData { get; set; }

我想做的是: 使用硬编码的xaml ,而不是,并带有视图(包括viewmodel)显示BaseData Collection中的每个对象。

问题:

应如何完成(MVVM最好采用棱镜和统一的方式)

(如何为集合中的每个对象创建视图/视图模型对的单独实例,并将其与xaml中的绑定一起使用)

也许需要一种完全不同的方法?经过数小时的测试和调查,我找不到面对这种情况的单个示例。

到目前为止,我使用了一种解决方法。我对此表示满意,因为它起作用了...直到我遇到不允许我进行操作的新问题(例如,我无法获取/通过区域管理器以进一步为每个实例定义视图/视图模型)。

我不满意的解决方法(不是应该用MVVM的方式):

每个base_main对象(在模型中)都将其自身的视图模型作为其构造的蜜蜂来创建:

public class base_main :INotifyPropertyChanged
{
  public ViewModels.SingleArticleItemViewModel single_vm { get; set; }
  public base_main()
  {
     single_vm = new ViewModels.SingleArticleItemViewModel(this);
  }
//(...)
}

MainTableItemsControlViewModel

中引用了一个集合
public class MainTableItemsControlViewModel : INotifyPropertyChanged
{
public MainTableItemsControlViewModel(IRegionManager RegionManager, IEventAggregator eventAggregator)
        {
            _regionManager = RegionManager;
            _eventAggregator = eventAggregator;

            BaseDataCollection = Model.MySingletonBaseDataCollection;

            BaseDataViews = (ListCollectionView)CollectionViewSource.GetDefaultView(BaseDataCollection);
        }
}

,并且该集合在MainTableItemsControl中用于创建类型为SingleArticleItem的视图的列表(绑定集合:ItemsSource="{Binding BaseDataViews}"并提供数据上下文:DataContext="{Binding Path=single_vm}"

<ListView VirtualizingStackPanel.IsVirtualizing="True" ScrollViewer.CanContentScroll="True" 
                  ItemsSource="{Binding BaseDataViews}" SelectedItem="{Binding SelectedItem, Mode=TwoWay}" IsSynchronizedWithCurrentItem="True">
            <ItemsControl.ItemTemplate>
                <DataTemplate DataType="{x:Type views:SingleArticleItem}">
                    <views:SingleArticleItem DataContext="{Binding Path=single_vm}" Margin="0"/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
            //(...)
</ListView>

这样,我为每个base_main对象构造一个View / ViewModel对,设置数据上下文以直接连接ViewModel(SingleArticleItem xaml不会自动连接:prism:ViewModelLocator.AutoWireViewModel="False"

即使它是“有效的”,它也不是mvvm的方法,并且有其局限性,因为进一步的解决方法有其局限性。例如。 在产生的SingleArticleItem实例中,我无法及时获得RegionManager(不是实例化)。对于事件聚合器,可以在任何属性更改事件上调用它

if (_eventAggregator == null && ServiceLocator.IsLocationProviderSet)
  {
    _eventAggregator = ServiceLocator.Current.GetInstance<IEventAggregator>();
   InformUpdateCommand = new DelegateCommand(InformUpdate);
 }

1 个答案:

答案 0 :(得分:0)

  

每个base_main对象(在模型中)都会创建自己的视图模型作为其构建的蜜蜂:

public class base_main : INotifyPropertyChanged
{
    public ViewModels.SingleArticleItemViewModel single_vm { get; set; }
    public base_main()
    {
        single_vm = new ViewModels.SingleArticleItemViewModel(this);
    }
}

那是错误的方法,反之亦然。不是模型创建视图模型,而是视图模型包含对该模型的引用。视图模型是为一种或多种类型的一个或多个模型创建的,甚至不必是一对一的关系。

因此带您去收集模型,并在想要显示该模型的视图模型中从中创建视图模型的集合。另外,如果用户可以创建新模型或新模型来自原始模型来源,请添加代码以同步两个集合。提示:如果您无法帮助,请仅执行完全双向同步,因为这将需要大量代码和更多测试...