2010-09-13 25 views
8

我在调用UserControl上的方法时遇到问题。听我说:在MVVM中调用UserControl的方法

  1. 我有一个用户控件someControl在SomeView.xaml

  2. SomeView.xaml的DataContext的是SomeViewModel.cs

  3. 我希望能够调用someControl.DoStuff()不知何故,某处。

  4. DoStuff不特定的用户界面(我可能只是叫DoStuff从SomeView.Xaml.Cs的代码隐藏,如果它是特定的用户界面,但在这种情况下,它可能不是。)

任何想法?

谢谢!

回答

5

你可能不会喜欢这个答案,但是你的ViewModel应该不知道你的UI。如果您的UserControl上有非UI方法,则可能是错误的。

我能想到的唯一的事情就是你可能想要实现某种类型的消息(比如他们在MVVM Light中)可能触发执行。

这是要么,要么重新思考你如何构建你的代码。

+0

我明白你来自哪里并相信我,我曾考虑过这一点。但是有一段时间你确实需要调用一个方法。例如,用户控件上的方法可能会暴露,并且我可能没有用户控件的源代码,所以我无法修改它以适应我的情况。 – 2010-09-14 00:08:36

+0

虽然对于这个建议+1,但你是对的,ViewModel不应该有视图的知识。 – 2010-09-14 00:16:16

+0

在这种情况下,可能会转到隐藏代码? – Robaticus 2010-09-14 00:27:04

0

在MVVM设计中,这个想法通常不是在你的UserControl(xaml.cs文件)(在理想世界中)有任何代码。 UI和ViewModel之间的所有交互应该通过命令和绑定来处理......那么为什么你需要在你的用户控件中使用DoStuff呢?

你可能有这样的事情

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

这听起来像你想DoStuff为响应在你的虚拟机的一些数据或逻辑发生,在这种情况下,清洁的方法很可能是使用事件起源于您的VM并由DoStuff处理。如果触发器更像是状态更改,则还可以将相应的VM数据绑定到UserControl上的新Dependency属性,并从DP的更改处理程序中调用DoStuff。

0

也许你的UserControl应该是一个View,然后应该有一个ViewModel,它将包含DoStuff()方法。 SomeViewModel将实例化(在租用时被实例化)SomeControlViewModel,因此能够调用它的一个方法。

0

如果您有View-first方法(并且您的VM在XAML中实例化为Resource),则可以使用一些常规事件将控制DoStuff方法与VM上的某个事件(Loaded事件)相连接。

0

如果方法DoStuff();做一些用户界面特定的逻辑,那么该方法是在正确的地方。如果不是那么它应该在另一个对象中(例如SomeViewModel)。

SomeViewModel被允许在通过接口分离时调用SomeView上的方法。 WPF Application Framework (WAF)显示了这可以如何实现。

1

一个由SO答案实现这一目标解耦视图模型的知识有关View通过粘贴在这里他的代码中使用回答的行动代表通过Merthere

,万一链路中断。

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 
    } 
} 
相关问题