web-dev-qa-db-fra.com

WPF MVVM: Lier un ViewModel différent à chaque TabItem?

J'ai une fenêtre principale avec un onglet de contrôle contenant 2 tabItems:

Main Window

J'ai actuellement 1 ViewModel quels services Tab1 & Tab2. Cette ViewModel devient un peu gonflée par un SOC flou. Je veux diviser la logique en 2 modèles de vue: ViewModel 1 & ViewModel2. Si j'ai bien compris, vous pouvez définir la variable DataContext de la fenêtre principale sur un ViewModel de base contenant une collection de ViewModels, puis d'affecter chaque TabItem à un ViewModel différent.

Les exemples que j'ai vus de ces ViewModels de base exposent une ObservableCOllection comme ceci:

private ObservableCollection<ViewModel1> _viewModelCollection
Public Observable Collection<ViewModel1> ViewModelCollection
{
   get { return _viewModelCollection; }
   set
     {
        _viewModelCollection = value;
        OnPropertyChanged("ViewModelCollection");
     }
}

public BaseViewModel()
{
  ViewModelCollection = new ObservableCollection<ViewModel1>();
  ViewModelCollection.Add(new ViewModel1(Tab1);
  ViewModelCollection.Add(new ViewModel1(Tab2);
}

Mais comment puis-je affecter un ViewModel différent à chaque TabItem? Je voudrais Tab1 = ViewModel1 & Tab2 = ViewModel2?

16
Hardgraf

Vous pouvez en effet ajouter les modèles de vue pour vos onglets à un modèle de vue principale. Vous pouvez ensuite vous connecter aux modèles de vue enfant dans le code XAML pour vos onglets.

Supposons que vous ayez trois modèles de vue: MainViewModel, Tab1ViewModel et Tab2ViewModel. Sur votre MainViewModel, vous conservez une collection de vos modèles de vue par onglet:

class MainViewModel
{
    ObservableCollection<object> _children;

    public MainViewModel()
    {
        _children = new ObservableCollection<object>();
        _children.Add(new Tab1ViewModel());
        _children.Add(new Tab2ViewModel());
    }

    public ObservableCollection<object> Children { get { return _children; } }
}

Après avoir défini la DataContext de votre fenêtre principale sur votre MainViewModel, vous pouvez lier la DataContext de vos onglets en référençant la propriété Children:

<TabControl>
    <TabItem DataContext="{Binding Children[0]}" x:Name="Tab1" Header="Tab1" >
      <!-- Tab content -->
    </TabItem>
    <TabItem DataContext="{Binding Children[1]}" x:Name="Tab2" Header="Tab2" >
      <!-- Tab content -->
    </TabItem>
</TabControl>
25

J'utilise un framework tel que Prism, qui vous permet de définir des régions et d'utiliser la variable RegionManager. Vous pouvez ensuite définir une ContentControl en tant que 'ui' pour la TabItem

Ensuite, vous pouvez utiliser le RegionManager.RequestNavigate pour remplir une région nommée avec une vue particulière (et nos vues importent un modèle de vue et définissent leur contexte de données).

3
Mashton
class MainViewModel
{
    ObservableCollection<object> _children;

    public MainViewModel()
    {
        _children = new ObservableCollection<object>();
        _children.Add(new Tab1ViewModel());
        _children.Add(new Tab2ViewModel());
    }

    public ObservableCollection<object> Children { get { return _children; } }
}

Maintenant, en XAML, liez les enfants à ItemsSource. Il générera chaque onglet pour chaque modèle de vue ajouté à la collection observable.

    <TabControl ItemsSource="{Binding Children}"/>
1
Varatharaj