简体   繁体   中英

WPF: Bind Tab Control

I am using MVVM, and I am trying to bind a TabControl's ItemsSource , I used this code:

<TabControl ItemsSource="{Binding ProjectComponents}"
                    SelectedIndex="{Binding SelectedMenu, Mode=TwoWay}" Grid.Column="1" Margin="5">

And for the view model:

projectComponents = new ObservableCollection<TabItem>();
projectComponents.Add(new TabItem()
{

     Content = new ProjectComponentsView()
     {
          DataContext = new ProjectClientHandlerViewModel()
     }
});

I used this in a Silverlight project and it works just fine, but in WPF , I don't know why is it that the content of the TabItem does not show.

EDIT:

I edited my code to this:

View:

 <TabControl ItemsSource="{Binding ProjectComponents}" SelectedIndex="{Binding SelectedMenu, Mode=TwoWay}" Grid.Column="1" Margin="5">
        <TabControl.ContentTemplate>
            <DataTemplate >
                <this:ProjectComponentsView DataContext="{Binding}"/>
            </DataTemplate>
        </TabControl.ContentTemplate>
 </TabControl>

View model:

projectComponents = new ObservableCollection<ProjectComponentViewModel>();
projectComponents.Add(new ProductViewsHandlerViewModel());

Where ProjectComponentViewModel is a base class of ProductViewsHandlerViewModel , but it's still not working.

Here is a quick example to get you started

public class MainVm : VMBase
    {
        public ObservableCollection<TabVM> Items { get; set; }
        public VMBase SelectedItem {get;set;} 
        public MainVm()
        {
            Items = new ObservableCollection<TabVM>()
            {
                new TabVM(){Header="A",Content = new SomeVm()},
                new TabVM(){Header="B",Content = new SomeVm()},
                new TabVM(){Header="C",Content = new SomeVm()},
                new TabVM(){Header="D",Content = new OtherVm()}
            };
        }
    }

    public class TabVM : VMBase
    {
        public string Header { get; set; }
        public VMBase Content { get; set; }
    }

    public class SomeVm : VMBase{}
    public class OtherVm : VMBase{}
    public class VMBase { }


<TabControl ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}">
        <TabControl.Resources>
            <DataTemplate DataType="{x:Type local:SomeVm}">
                <TextBlock>SomeVm Template</TextBlock>
            </DataTemplate>
            <DataTemplate DataType="{x:Type local:OtherVm}">
                <TextBlock>OtherVm Template</TextBlock>
            </DataTemplate>
        </TabControl.Resources>
        <TabControl.ItemTemplate>
            <DataTemplate>
                    <TextBlock Text="{Binding Header}"></TextBlock>
            </DataTemplate>
        </TabControl.ItemTemplate>
        <TabControl.ContentTemplate>
            <DataTemplate>
                <ContentControl Content="{Binding Content}"></ContentControl>
            </DataTemplate>
        </TabControl.ContentTemplate>
    </TabControl>

templates get selected based on the ViewModel type as we set them up in the resources, you should also use a ViewModel that represents a TabItem , which is TabVM in the above snippet.

in the ItemTemplate of the tab control you set up the header template and in the ContentTemplate you put a ContentControl and bind its Content to the Content property of TabVM .

and don't forget to implement INotifyPropertyChanged .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM