Good ... allows you to:
First of all, you must learn to think about your interface in an abstract way:
What is TabControl?
This is a graphical representation of the widget list in which the user can have 1 active widget at a time. These widgets have a title (tab element text), a visibility state, and an On / Off state.
What is a bunch of folded buttons? (toolbar if you want to call it)
This is a graphical representation of a list of actions that a user can perform at any given time. These actions have a description (the contents of the button), possibly an associated icon or graphic image, as well as the On / Off status.
What is ContextMenu or menu?
The same as above is a graphical representation of the list of actions that the user can perform.
How can I create a dynamic TabControl in WPF?
This is XAML for the WPC TabControl, which supports dynamic children:
<Window x:Class="WpfApplication4.Window12" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window12" Height="300" Width="300"> <Window.Resources> <BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter"/> </Window.Resources> <TabControl ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}"> <TabControl.ItemContainerStyle> <Style TargetType="TabItem"> <Setter Property="IsEnabled" Value="{Binding IsEnabled}"/> <Setter Property="Visibility" Value="{Binding IsVisible, Converter={StaticResource BoolToVisibilityConverter}}"/> <Setter Property="Header" Value="{Binding Title}"/> </Style> </TabControl.ItemContainerStyle> </TabControl> </Window>
ViewModel:
public class TabbedViewModel: ViewModelBase { private ObservableCollection<TabViewModel> _items; public ObservableCollection<TabViewModel> Items { get { return _items ?? (_items = new ObservableCollection<TabViewModel>()); } } private ViewModelBase _selectedItem; public ViewModelBase SelectedItem { get { return _selectedItem; } set { _selectedItem = value; NotifyPropertyChange(() => SelectedItem); } } } public class TabViewModel: ViewModelBase { private string _title; public string Title { get { return _title; } set { _title = value; NotifyPropertyChange(() => Title); } } private bool _isEnabled; public bool IsEnabled { get { return _isEnabled; } set { _isEnabled = value; NotifyPropertyChange(() => IsEnabled); } } private bool _isVisible; public bool IsVisible { get { return _isVisible; } set { _isVisible = value; NotifyPropertyChange(() => IsVisible); } } }
In this example, each element (TabItem) in the TabControl will be bound to one of the ViewModels, then it is just a matter of inheriting the base TabViewModel for each of your tabs and creating the correct DataTemplate for each.
As you can see in this example, I in no way create or manipulate any user interface elements in the code. This simplifies all A LOT code and helps maintain a clear separation between logic and user interface. You can apply the same concept to everything in WPF.
Federico berasategui
source share