zainmaster
zainmaster

Reputation: 63

Show different ViewModels with TabControl (MVVM)

I worte an application with different ViewModels, one for Users, Groups and Machines. Every ViewModel hast their own View. I am using Caliburn.Micro. Right now I switch between the Views with Buttons like this:

XAML:

     <StackPanel Orientation="Horizontal">
                <Button VerticalAlignment="Top" Margin="5" Height="30" x:Name="ShowUsers" Content="Users"/>
                <Button VerticalAlignment="Top" Margin="5" Height="30" x:Name ="ShowGroups" Content="Groups"/>
                <Button VerticalAlignment="Top" Margin="5" Height="30" x:Name ="ShowMachines" Content="Machines"/>
            </StackPanel>
<ContentControl Grid.Row="1" x:Name="ActiveItem"/>

C#:

public AdminViewModel(GroupManagementViewModel groupManagementViewMode, MachineManagementViewModel machineManagementViewModel, UserManagementViewModel userManagementViewModel)
        {
            this._groupManagementViewModel = groupManagementViewMode;
            this._machineManagementViewModel = machineManagementViewModel;
            this._userManagementViewModel = userManagementViewModel;
        }

        protected override void OnActivate()
        {
            base.OnActivate();
            ShowUsers();
        }

        public void ShowUsers()
        {
            ActivateItem(_userManagementViewModel);
        }

        public void ShowGroups()
        {
            ActivateItem(_groupManagementViewModel);
        }

        public void ShowMachines()
        {
            ActivateItem(_machineManagementViewModel);

I would like to change those Buttons with using a TabControl and I tried several things and now my code looks like this:

XAML(with Tabcontrol):

<TabControl>
            <TabItem Header="User" x:Name="ShowUsers">
               
            </TabItem>
            
            <TabItem Header="Groups" x:Name="ShowGroups">
                
            </TabItem>
            <TabItem Header="Machines" x:Name="ShowMachines">
              
            </TabItem>
           
        </TabControl>
        <ContentControl Grid.Row="1" x:Name="ActiveItem"/>

So I gave the TabItems the x:Name of the command in my ViewModel but it only shows the same viewmodel for every TAB

I would be very thankful for every hint.

Best Regards

Zain

Upvotes: 0

Views: 707

Answers (2)

mm8
mm8

Reputation: 169420

Using Caliburn.Micro, the XAML markup in the view should be as simple as this:

<TabControl x:Name="Items" />

The view model should then inherit from Conductor<T>.Collection.OneActive and add the tab view models to the Items property:

public class AdminViewModel : Conductor<object>.Collection.OneActive
{
    public AdminViewModel(GroupManagementViewModel groupManagementViewMode, 
        MachineManagementViewModel machineManagementViewModel, 
        UserManagementViewModel userManagementViewModel)
    {
        Items.Add(groupManagementViewMode);
        Items.Add(machineManagementViewModel);
        Items.Add(userManagementViewModel);
    }
}

The tab view model should inherit from Screen. You can then set the DisplayName property of them to modify the tab header.

Upvotes: 1

NadaHacker
NadaHacker

Reputation: 83

The TabControl element has an ItemSource property that can be used to make this work. For instance:

You could bind ItemSource to an observable collection of a type that is a base class to all three of your viewModels you want to use in the tab control:

public ObservableCollection<BaseViewModel> TabControlViewModels { get; }

ItemSource would be binded to this.

Looking into the TabControl (ItemsControl) might be helpful for things such as: SelectedIndex, ItemsPanel, ItemTemplate, and ItemContainerStyle to make it look the way you want.

Also see here for more details: How do I bind a TabControl to a collection of ViewModels?

Upvotes: 1

Related Questions