-
Jun 7th, 2011, 03:11 PM
#1
Thread Starter
Junior Member
Custom TabPage/TabItem
Hello,
I have a TabControl on my main window and I would like it to have two types of tabs. One tab will have several textboxes on them. How do I create a general Tab Page. i.e. create an XAML file to go with my tab:
Code:
Public Class MyTab : Inherits TabItem
CustomText_TextChanged(...)
End Class
Public Class CustomText : Inherits TextBox
End Class
Code:
<Resource>
<Type:MyTab>
<CustomText Name="CT1"/>
<CustomText Name="CT2"/>
</Type:MyTab>
</Resource>
<MainTabControl>
<MyTab Header="Custom Tab" />
</MainTabControl>
I am really bad at XAML, so the XAML part will have to be explained.
Last edited by UWGRAD; Jun 7th, 2011 at 04:28 PM.
-
Jun 8th, 2011, 09:24 PM
#2
Re: Custom TabPage/TabItem
You don't really need to create special classes for each Tab page, you can define them in the TabControl itself:
xml Code:
<TabControl> <TabItem Header="Custom Tab"> <StackPanel> <TextBox x:Name="CT1"/> <TextBox x:Name="CT2"/> </StackPanel> </TabItem> <TabItem Header="Tab 2"> <Rectangle Fill="AntiqueWhite" Height="30" HorizontalAlignment="Stretch" /> </TabItem> </TabControl>
What are you trying to achieve? Some kind of reuse of standard UI panels? You probably want to define a UserControl that represents the content of your tab page in that case, and then use that UserControl in your TabControl->TabItem XAML.
-
Jun 8th, 2011, 09:27 PM
#3
Thread Starter
Junior Member
Re: Custom TabPage/TabItem
The tabs are added dynamically and I need some code to run behind them, hence, I need a class.
-
Jun 8th, 2011, 10:57 PM
#4
Re: Custom TabPage/TabItem
The dynamic code - is it dealing with the behaviour of the tabs? If not, you can have the code-behind in the UserControl.
To add a tab dynamically, bind the ItemsSource property of your TabControl to a Collection of objects that represent your tab pages. As you add/remove from this collection, the TabControl will add/remove tabs.
For example, assuming this class as representing your tab pages:
csharp Code:
public class MyTabPageViewModel : INotifyPropertyChanged { private string m_headerText; private string m_customText1; private string m_customText2; public string HeaderText { get { return m_headerText; } set { if (m_headerText != value) { m_headerText = value; OnPropertyChanged("HeaderText"); } } } public string CustomText1 { get { return m_customText1; } set { if (m_customText1 != value) { m_customText1 = value; OnPropertyChanged("CustomText1"); } } } public string CustomText2 { get { return m_customText2; } set { if (m_customText2 != value) { m_customText2 = value; OnPropertyChanged("CustomText2"); } } } #region Implementation of INotifyPropertyChanged protected virtual void OnPropertyChanged(string propertyName) { var handler = PropertyChanged; if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); } public event PropertyChangedEventHandler PropertyChanged; #endregion }
and that you have a window view model looking something like this:
csharp Code:
public class MyWindowViewModel { private readonly ObservableCollection<MyTabPageViewModel> m_tabPages; private readonly ReadOnlyObservableCollection<MyTabPageViewModel> m_readonlyTabPages; public MyWindowViewModel() { m_tabPages = new ObservableCollection<MyTabPageViewModel>(); m_readonlyTabPages = new ReadOnlyObservableCollection<MyTabPageViewModel>(m_tabPages); m_addTabCommand = new DelegateCommand(AddATab); AddATab(); AddATab(); } private int i = 1; private ICommand m_addTabCommand; private void AddATab() { MyTabPageViewModel myTabPageViewModel = new MyTabPageViewModel() { HeaderText = string.Format("Tab Page {0}", i++) }; m_tabPages.Add(myTabPageViewModel); } public ReadOnlyObservableCollection<MyTabPageViewModel> TabPages { get { return m_readonlyTabPages; } } public ICommand AddTabCommand { get { return m_addTabCommand; } } } internal class DelegateCommand : ICommand { private readonly Action m_onExecute; public DelegateCommand(Action onExecute) { m_onExecute = onExecute; } #region Implementation of ICommand public void Execute(object parameter) { m_onExecute(); } public bool CanExecute(object parameter) { return true; } public event EventHandler CanExecuteChanged; #endregion }
Then you need to firstly define a template for what the tab page looks like:
xml Code:
<DataTemplate DataType="{x:Type local:MyTabPageViewModel}"> <StackPanel> <TextBox Text="{Binding CustomText1}" /> <TextBox Text="{Binding CustomText2}" /> </StackPanel> </DataTemplate>
(this is a default template, you might want to give it a key and then reference it explicitly in the TabControl...)
Then you can bind you TabControl thus:
xml Code:
<TabControl ItemsSource="{Binding TabPages}"> <TabControl.ItemContainerStyle> <Style TargetType="TabItem"> <Setter Property="Header" Value="{Binding HeaderText}" /> </Style> </TabControl.ItemContainerStyle> </TabControl>
This uses the TabPages property from the Window view model (that is set as the DataContext of the window) as the ItemsSource, so each TabItem in the TabControl gets an element from that collection as its DataContext. We use a style to define the Header property of each TabItem as bound to the HeaderText property of the TabPageViewModel so that we get the correct text in the header. The Content of each TabItem remains as the whole TabPageViewModel, which is rendered using the DatATemplate we defined earlier. The AddTabCommand can be wired up to a button on your window to test adding tab pages:
xml Code:
<Button Command="{Binding AddTabCommand}">Add a Tab</Button>
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|