¿Cómo puedo vincular un TabControl a una colección de ViewModels?

Básicamente tengo en mi MainViewModel.cs:

ObservableCollection MyTabs { get; private set; } 

Sin embargo, tengo que ser capaz de no solo crear las tabs, sino también tener el contenido de tabs cargado y vinculado a sus modelos de vista apropiados mientras mantengo MVVM.

Básicamente, ¿cómo puedo obtener un control de usuario para cargar como el contenido de un tabitem y tener ese control de usuario conectado a un modelo de vista apropiado? La parte que hace esto difícil es que ViewModel no debe construir los elementos de la vista real, ¿verdad? O puede?

Básicamente, ¿esto sería MVVM apropiado?

 UserControl address = new AddressControl(); NotificationObject vm = new AddressViewModel(); address.DataContext = vm; MyTabs[0] = new TabItem() { Content = address; } 

Solo pregunto porque, bueno, estoy construyendo una View (AddressControl) desde dentro de ViewModel, lo que para mí suena como un MVVM no-no.

Esto no es MVVM. No debería crear elementos UI en su modelo de vista.

Debería vincular ItemsSource de la pestaña a su ObservableCollection, y eso debería contener modelos con información sobre las tabs que deberían crearse.

Aquí están la VM y el modelo que representa una página de tabs:

 public sealed class ViewModel { public ObservableCollection Tabs {get;set;} public ViewModel() { Tabs = new ObservableCollection(); Tabs.Add(new TabItem { Header = "One", Content = "One's content" }); Tabs.Add(new TabItem { Header = "Two", Content = "Two's content" }); } } public sealed class TabItem { public string Header { get; set; } public string Content { get; set; } } 

Y así es como se ven los enlaces en la ventana:

                    

(Tenga en cuenta que si desea elementos diferentes en tabs diferentes, use DataTemplates . O bien el modelo de vista de cada pestaña debe ser de su propia clase, o cree un DataTemplateSelector personalizado para elegir la plantilla correcta).

Oh, mira, un UserControl dentro de la plantilla de datos:

               

En Prism, generalmente haces que la pestaña controle una región para que no tengas que tomar el control de la colección de páginas de tabs atadas.

  

Ahora las vistas se pueden agregar registrándose en la región MainRegion:

 RegionManager.RegisterViewWithRegion( "MainRegion", ( ) => Container.Resolve( ).View ); 

Y aquí puedes ver una especialidad de Prism. La Vista es instanciada por ViewModel. En mi caso, resuelvo ViewModel a través de un contenedor de inversión de control (por ejemplo, Unity o MEF). El ViewModel obtiene la Vista inyectada a través de la inyección del constructor y se establece como el contexto de datos de la Vista.

La alternativa es registrar el tipo de vista en el controlador de región:

 RegionManager.RegisterViewWithRegion( "MainRegion", typeof( MyView ) ); 

El uso de este enfoque le permite crear las vistas más tarde durante el tiempo de ejecución, por ejemplo, mediante un controlador:

 IRegion region = this._regionManager.Regions["MainRegion"]; object mainView = region.GetView( MainViewName ); if ( mainView == null ) { var view = _container.ResolveSessionRelatedView( ); region.Add( view, MainViewName ); } 

Como ha registrado el tipo de Vista, la vista se coloca en la región correcta.

Tengo un convertidor para desacoplar la interfaz de usuario y ViewModel, ese es el punto a continuación:

      

La pestaña es una enumeración en mi TabItemViewModel y el TabItemConverter la convierte a la IU real.

En TabItemConverter, solo obtenga el valor y Devuelva el control de usuario que necesita.

Intereting Posts