Saltar al contenido

Abriendo una nueva ventana en MVVM WPF

Te traemos el resultado a este enigma, al menos eso esperamos. Si tienes inquietudes puedes escribirlo en el apartado de comentarios, que sin dudarlo te responderemos

Solución:

Usted dice que “crear una instancia de ventana y mostrar la ventana desde el modelo de vista es una violación de MVVM”. Esto es correcto.

Ahora está intentando crear una interfaz que tome un tipo de vista especificado por la máquina virtual. Esto es igual de violatorio. Es posible que haya abstraído la lógica de creación detrás de una interfaz, pero aún está solicitando creaciones de vista desde dentro de la VM.

Las máquinas virtuales solo deberían preocuparse por crear máquinas virtuales. Si realmente necesita una nueva ventana para alojar la nueva VM, proporcione una interfaz como lo ha hecho, pero que NO tenga una vista. ¿Por qué necesitas la vista? La mayoría de los proyectos MVVM (máquina virtual primero) usan plantillas de datos implícitas para asociar una vista con una máquina virtual en particular. La máquina virtual no sabe nada acerca de ellos.

Me gusta esto:

class WindowService:IWindowService

    public void ShowWindow(object viewModel)
    
        var win = new Window();
        win.Content = viewModel;
        win.Show();
    

Obviamente, debe asegurarse de tener su VM-> Ver plantillas implícitas configuradas en app.xaml para que esto funcione. Esto es solo VM estándar primero MVVM.

p.ej:


    

        
            
        

    

Una posibilidad es tener esto:

class WindowService:IWindowService

 public void showWindow(object DataContext) where T: Window, new() 
 
  ChildWindow window=new T();
  window.Datacontext=DataContext;
  window.show();
 

Entonces puedes hacer algo como:

windowService.showWindow(windowThreeDataContext);

Para obtener más información sobre la nueva restricción, consulte http://msdn.microsoft.com/en-gb/library/sd2w2ew5.aspx

Nota la new() constraint solo funciona donde la ventana tendrá un constructor sin parámetros (¡pero me imagino que esto no debería ser un problema en este caso!) En una situación más general, consulte ¿Crear instancia de tipo genérico? por posibilidades.

Podrías escribir una función como esta:

class ViewManager

    void ShowView(ViewModelBase viewModel)
        where T : ViewBase, new()
    
        T view = new T();
        view.DataContext = viewModel;
        view.Show(); // or something similar
    


abstract class ViewModelBase

    public void ShowView(string viewName, object viewModel)
    
        MessageBus.Post(
            new Message 
            
                Action = "ShowView",
                ViewName = viewName,
                ViewModel = viewModel 
            );
    

Asegúrese de que ViewBase tenga una propiedad DataContext. (Podrías heredar UserControl)

En general, crearía algún tipo de bus de mensajes y haría que un ViewManager escuche los mensajes que solicitan una vista. ViewModels enviaría un mensaje solicitando que se muestre una vista y los datos para mostrar. El ViewManager luego usaría el código anterior.

Para evitar que el modelo de vista de llamada conozca los tipos de vista, puede pasar un string/nombre lógico de la vista a ViewManager y haga que ViewManager traduzca el nombre lógico a un tipo.

Valoraciones y comentarios

Si guardas algún titubeo y disposición de acrecentar nuestro sección puedes realizar una nota y con gusto lo estudiaremos.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *