Actualización dinámica del contenido de TabControl en tiempo de ejecución

Así que aquí está el problema. Tengo una ventana dividida en tres paneles. El medio contiene una superficie de dibujo y el izquierdo contiene un control de pestaña. La pestaña del control de tabs se compone de una lista de botones que debe abrir nuevos menús en el panel derecho. No puedo entender cómo hacer esto en el código, así que recurrí a la creación individual de cada botón en tiempo de ejecución en C #. Parece que tiene que haber una mejor manera de hacerlo. Actualmente llamo a la función siguiente para los eventos de clic de botón para dibujar diferentes menús en el Panel derecho llamado tabctrl “tabctrl” en el tiempo de ejecución. Se necesita un argumento de cadena para especificar qué conjunto de menús dibujar, aunque en este punto solo he escrito el código de uno de los menús. Debajo está el código para la función y el xml. ¿Hay una mejor manera de hacerlo?

xml:

   

do#:

 private void menuOpen(string menuSelected) { //Logic statement for what menu is being opened switch (menuSelected) { case "BackGround": { //Remove Current Tabs //Initialize Tab Item, set title, and add tab item to tab control TabItem BackGround = new TabItem(); BackGround.Header = "BackGround"; tabctrl.Items.Insert(1, BackGround); BackGround.Height = 38; //Initialize Stack Panel, set orientation, and add to tab control StackPanel panel = new StackPanel(); panel.Orientation = Orientation.Vertical; BackGround.Content = panel; //Initialize Menu Items Button AddMap = new Button(); Button AddDemoMap = new Button(); Button RemoveMap = new Button(); Button MoveSelected = new Button(); Button Properties = new Button(); Button ScaleBackground = new Button(); //Define Button Text AddMap.Content = "Add Map"; AddDemoMap.Content = "Add Demo Map"; RemoveMap.Content = "Remove Map"; MoveSelected.Content = "Move Selected Map to Top of List"; Properties.Content = "Properties"; ScaleBackground.Content = "Scale Background to Pipes"; AddMap.Height = 50; AddDemoMap.Height = 50; RemoveMap.Height = 50; MoveSelected.Height = 50; Properties.Height = 50; ScaleBackground.Height = 50; //Add Buttons to StackPanel panel.Children.Add(AddMap); panel.Children.Add(AddDemoMap); panel.Children.Add(RemoveMap); panel.Children.Add(MoveSelected); panel.Children.Add(Properties); panel.Children.Add(ScaleBackground); } break; 

Vale, veamos:

Antes que nada, debes aprender a pensar tu UI de una manera abstracta :

¿Qué es un TabControl?

Es una representación gráfica de una Lista de widgets, donde el usuario puede tener 1 widget activo a la vez. Estos widgets tienen un Título (el texto del elemento de pestaña), un estado de Visibilidad y un estado Habilitado / Inhabilitado.

¿Qué es un montón de botones astackdos? (barra de herramientas, si quieres llamarlo así)

Es una representación gráfica de una Lista de acciones que el usuario puede realizar en cualquier momento. Estas acciones tienen una Descripción (el contenido del botón), posiblemente un ícono asociado o una imagen gráfica, y un Estado habilitado / deshabilitado.

¿Qué es un ContextMenu, o un Menú?

Lo mismo que arriba, es una representación gráfica de una lista de Acciones que el usuario puede realizar.

¿Cómo podría crear un TabControl dynamic en WPF?

Este es el XAML para un WPF TabControl que admite niños dynamics:

           

ViewModel:

  public class TabbedViewModel: ViewModelBase { private ObservableCollection _items; public ObservableCollection Items { get { return _items ?? (_items = new ObservableCollection()); } } 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); } } } 

Con este ejemplo, cada elemento (TabItem) en el TabControl se vinculará a uno de los Modelos de Vista, entonces es solo una cuestión de heredar el TabViewModel base para cada una de sus tabs y crear un DataTemplate adecuado para cada una.

Como puede ver en este ejemplo, de ninguna manera creo o manipulo CUALQUIER elemento de UI en el código. Esto simplifica todo el código MUCHO, y ayuda a mantener una clara separación entre la lógica y la IU. Puede aplicar este mismo concepto a todo en WPF.