两次将相同的视图注册到具有不同行为的TabControl

时间:2019-02-16 07:56:20

标签: c# wpf unity-container prism ioc-container

我正在寻找一种智能方法来在Tab控件中实例化一个View和ViewModel多次,其行为略有不同。 最好使用Prism7.1

我当前的解决方案是;

在我的MainView中

        <TabControl
            ItemsSource="{Binding TabItemCollection}"
            SelectedItem="{Binding SelectedTabItem}"
            ItemContainerStyle="{DynamicResource ItemSize20_HeaderBinding}" 
            mah:TabControlHelper.Underlined="SelectedTabItem">
            <TabControl.Resources>
                <DataTemplate DataType="{x:Type vm:MaskingCreationViewModel}" >
                    <local:MaskingCreation/>
                </DataTemplate>
            </TabControl.Resources>
        </TabControl>

在我的MainViewModel中

    public class MainViewModel
    {
        public ObservableCollection<MaskingCreationViewModel> TabItemCollection { get; set; }
        public MaskingCreationViewModel SelectedTabItem { get; set; }

        public MainViewModel()
        {
            TabItemCollection = new ObservableCollection<MaskingCreationViewModel>();
            TabItemCollection.Add(new MaskingCreationViewModel(new TabBehaviorA()));
            TabItemCollection.Add(new MaskingCreationViewModel(new TabBehaviorB()));

            SelectedTabItem = TabItemCollection[0];
        }
    }

在这里,我想在ViewModel中注入“ TabBehavior”以提供不同的行为。我已经尝试过使用Prism通过Region在TabControl中注册“ MaskingCreation”,但是遇到了两个问题。

  1. 如果我正常在该区域注册视图,就没有机会注入我想要的行为。
            regionManager.RegisterViewWithRegion(Regions.Masking, typeof(MaskingCreation));
  1. 如果使用此功能,则此功能的每一行都有问题。
    • 我想从ServiceLocation获取一个具有TabTehavior的这种变体的新实例,但是我不知道这应该如何工作。
    • 因为我无法使用此Consturctor注入,所以我必须为TabBehavior类提供一个属性。
    • 最后也是最糟糕的事情。我必须在我的ViewModel中存储View的引用。我想避免在ViewModel中使用DataContext。
            regionManager.RegisterViewWithRegion(Regions.Masking, () => 
            {
                var vm = ServiceLocator.Current.GetInstance<MaskingCreationViewModel>();
                vm.Behavior = new TabBehaviorB();
                return vm.GetView();
            });

有人知道适合MVVM模式的智能解决方案吗?

1 个答案:

答案 0 :(得分:0)

在视图模型中,我将为MaskingCreationViewModel和所有选项卡行为注入一个工厂:

internal class MainViewModel : BindableBase
{
    public MainViewModel( IMaskingCreationViewModelFactory maskingCreationViewModelFactory, IEnumerable<ITabBehavior> tabBehaviors )
    {
        foreach (var tabBehavior in tabBehaviors)
            TabItemCollection.Add( maskingCreationViewModelFactory.Create( tabBehavior ) );

        SelectedTabItem = TabItemCollection.FirstOrDefault();
    }

    public ObservableCollection<MaskingCreationViewModel> TabItemCollection { get; } = new ObservableCollection<MaskingCreationViewModel>();
    public MaskingCreationViewModel SelectedTabItem { get => _selectedTabItem; set => SetProperty( ref _selectedTabItem, value ); }

    private MaskingCreationViewModel _selectedTabItem;
}