Treating multiple tabs as separate Views with sepa

2019-07-21 05:44发布

In WPF, I have one Window containing a TabControl with four TabItems. Each TabItem has a Grid:

<TabItem Header="Input" Name="tabItem1">
   <Grid></Grid>
</TabItem>

In my codebehind I need to specify a datacontext pointing to a ViewModel. Rather than having one ViewModel to handle all four tabs, I would like a ViewModel for each Tab. This would mean having different DataContexts for each time.

Is there a way to achieve this in a clean way?

1条回答
Fickle 薄情
2楼-- · 2019-07-21 06:22

You can set DataContext in XAML only by declaring instance in XAML only and bind DataContext to that instance.

But since you asked for cleaner way, so ideal would be to bind ItemsSource of TabControl to collection of ViewModels so that all tabItems automatically have different DataContext.


First create DummyViewModel and have ObservableCollection<DummyViewModel> collection in your main window ViewModel.

public class MainWindowViewModel : INotifyPropertyChanged
{
    public MainWindowViewModel()
    {
        ViewModelCollection = new ObservableCollection<DummyViewModel>();
        ViewModelCollection.Add(new DummyViewModel("Tab1", "Content for Tab1"));
        ViewModelCollection.Add(new DummyViewModel("Tab2", "Content for Tab2"));
        ViewModelCollection.Add(new DummyViewModel("Tab3", "Content for Tab3"));
        ViewModelCollection.Add(new DummyViewModel("Tab4", "Content for Tab4"));
    }

    public ObservableCollection<DummyViewModel> ViewModelCollection { get; set; }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

public class DummyViewModel
{
    public DummyViewModel(string name, string description)
    {
        Name = name;
        Description = description;
    }
    public string Name { get; set; }
    public string Description { get; set; }
}

and bind with collection in XAML like this:

<TabControl ItemsSource="{Binding ViewModelCollection}">
    <TabControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Name}"/>
        </DataTemplate>
    </TabControl.ItemTemplate>
    <TabControl.ContentTemplate>
        <DataTemplate>
            <Grid>
                <TextBlock Text="{Binding Description}"/>
            </Grid>
        </DataTemplate>
    </TabControl.ContentTemplate>
</TabControl>

ItemTemplate is defined for header of tab items and ContentTemplate is defined for content of individual tabItems.

Four tab items will be created with each tab item DataContext is set to separate instance of DummyViewModel.


SnapShot:

enter image description here

查看更多
登录 后发表回答