2010-09-13 26 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 
    } 
} 
相關問題