2010-09-13 10 views
8

Tengo un problema al llamar a un método en un UserControl. escúchame:Llamar a un método de UserControl en MVVM

  1. tengo un control de usuario en someControl SomeView.xaml

  2. DataContext de SomeView.xaml es SomeViewModel.cs

  3. Quiero ser capaz de llamar a someControl.DoStuff() alguna manera, en algún lugar.

  4. DoStuff no es la interfaz de usuario específico (Me podría haber llamado DoStuff desde el código subyacente de SomeView.Xaml.Cs si era la interfaz de usuario específica, pero en este caso, no puede ser.)

¿Alguna idea?

Gracias!

Respuesta

5

Probablemente no le va a gustar la respuesta, pero su ViewModel no debería tener conocimiento de su UI. Si tiene un método que no es de UI en su UserControl, probablemente esté en el lugar equivocado.

Lo único que se me ocurre es que quizás desee implementar algún tipo de mensaje (como el que tienen en MVVM Light) que podría desencadenar la ejecución.

Es eso o reconsidere cómo ha diseñado su código.

+0

Entiendo de dónde vienes y créeme, he pensado en esto. Pero llega un momento en el que realmente necesitas llamar a un método. Por ejemplo, el método en el control del usuario puede estar expuesto y es posible que no tenga la fuente para el control del usuario, por lo que no puedo modificarlo para adaptarlo a mi caso. –

+0

+1 por sugerencia, tiene razón, ViewModel no debería tener conocimiento de la Vista. –

+0

En ese caso, vaya al código detrás, tal vez? – Robaticus

0

En el diseño de MVVM, la idea generalmente no es tener CUALQUIER código en su UserControl (el archivo xaml.cs) (en un mundo ideal). Toda la interacción entre la interfaz de usuario y ViewModel debe manejarse a través de comandos y enlaces ... ¿por qué necesita DoStuff en su control de usuario?

Es posible que tenga algo así como

<Button Command="{Binding myCommandOnTheDataContextViewModel}" Content="{Binding somePropertyOnTheViewModel}" /> 
3

Parece que usted quiere DoStuff suceda en respuesta a algunos datos o lógica en la máquina virtual, en cuyo caso el método más limpio, probablemente sería utilizar un acontecimiento originario de su máquina virtual y manejado por DoStuff. Si el desencadenante es más parecido a un cambio de estado, también podría vincular los datos de VM apropiados a una nueva Propiedad de dependencia en su UserControl y llamar a DoStuff desde el controlador de cambios del DP.

0

Tal vez su UserControl realmente debería ser una Vista, que luego debería tener un ViewModel, que contendría el método DoStuff(). SomeViewModel habrá creado una instancia (se utilizarán casados ​​para ser instanciados) SomeControlViewModel, y así podrá invocar un método en él.

0

Si tiene el enfoque Vista previa (y su VM está instanciada como Recurso en XAML) puede usar algunos eventos normales para conectar su método DoStuff de control con algún evento en VM (en evento Cargado).

0

Si el método DoStuff(); hace alguna lógica específica de UI, entonces el método está en el lugar correcto. Cuando no, entonces debería estar en otro objeto (por ejemplo, SomeViewModel).

SomeViewModel puede llamar a un método en SomeView cuando está separado a través de una interfaz. Cómo se puede lograr esto se muestra en el WPF Application Framework (WAF).

1

Uno del SO respuesta a achive este por desacopla el conocimiento del modelo de vista sobre View es mediante el uso de los delegados de acción respondidas por Merthere

Pegado su código aquí, si el enlace se rompe por casualidad.

class MyCodeBehind 
{ 
    public MyCodeBehind() 
    { 
     Action action = new Action(()=> this.SomeMethodIWantToCall()); 
     var myVM = new MyVM(action); // This is your ViewModel 
     this.DataContext = myVM; 
    } 

    private void SomeMethodIWantToCall(){...} 
} 

class MyVM 
{ 
    private Action action; 

    public MyVM(Action someAction) 
    { 
     this.action = someAction; 
    } 

    private void SomeMethodInVM() 
    { 
     this.action(); // Calls the method SomeMethodIWantToCall() in your code behind 
    } 
} 
Cuestiones relacionadas