2012-01-18 87 views
3

我需要將方法綁定到xaml文件中的自定義控件,而不是方法的結果。將方法綁定到xaml控件

基本上,自定義控件在某些條件匹配時會幾次觸發該方法。

我該怎麼做?

我在互聯網上發現了一些解決方案,但其中大多數都將方法的結果綁定到xaml,這不是我尋找的解決方案。

非常感謝。

+0

感謝ColinE和ChrisBD的快速響應!但我認爲命令不適合我的情況,因爲我們仍然需要觸發定製控制中某些事件的命令基礎。不過,我發現了一個解決方案,我將在下面分享它。 – tzuhsun 2012-01-18 08:50:22

+0

是的,我從這裏得到了答案:http://stackoverflow.com/questions/5146946/binding-of-static-methode-function-to-funct-property-in-xaml/5156627#5156627。這個問題已經是我的答案。 :) – tzuhsun 2012-01-18 09:08:28

回答

0

你會想綁定到一個ICommand的實現,並調用你的類方法。

Here's a good blog描述了更多關於使用ICommand從WPF執行代碼的信息。

2

有兩種不同的走近它,你可以使用:

  • Commands,暴露其綁定到命令你的UI元素的屬性ICommand類型的屬性。
  • 使用行爲將UI事件連接到視圖模型中的方法,例如使用MVVM Light EventToCommandBehaviour
1

你可以更具體的條件是什麼? @ColineE和@ChrisBD正確地指出,在許多情況下ICommands和EventTocommandBehavior都會有所幫助,例如將按鈕單擊或鼠標懸停事件轉換爲ViewModel中的方法調用。 如果可以使用這些方法,我會主張使用這些方法,因爲它們被認爲是最佳方法

但是,有些情況下需要的東西稍微複雜一些。一種解決方案是使用代碼隱藏將DataContext轉換爲視圖模型類型並直接調用該方法。例如:

// Inside MyViewModel.cs 
public class MyViewModel : INotifyPropertyChanged 
{ 
    // ... 
} 

// ... 
// Inside MyControl.xaml.cs 
public class MyControl : UserControl 
{ 
    public MyControl() 
    { 
     InitializeComponent(); 
    } 

    pubilc void OnSomeConditionMatches() 
    { 
     var myViewModel = DataContext as MyViewModel; 
     if (myViewModel != null) 
     { 
       // Hacky, but it works 
       myViewModel.CallCustomMethod(); 
     } 
    } 
} 

這被認爲是一個小哈克,並在運行時視圖模型類型的知識污染的代碼隱藏。我們想要避免的事情是因爲它打破了View和ViewModel之間的關注點分離。

另一種方法是我在處理自定義控件時用過的自己,這種自定義控件很少或沒有數據綁定支持。通過使用視圖上的界面和附加屬性,您可以使用inject a view instance into the viewModel and manipulate it directly。我創造了MiVVM的混合MVVM/MVP模式。

UML

MiVVM UML Diagram

的XAML:

<!-- Assumes myViewModel is the viewmodel we are binding to --> 
<!-- which has property InjectedUserControl of type IMyControl --> 
<Example3:MyControl DataContext="{StaticResource myViewModel}" 
        Injector.InjectThisInto="InjectedUserControl"> 
</Example3:MyControl> 

代碼:

// Defines an interface to the usercontrol to 
// manipulate directly from ViewModel 
public interface IMyControl 
{ 
    // Our test method to call 
    void CallView(string message); 
} 

// Defines the usercontrol 
public partial class MyControl : UserControl, IMyControl 
{ 
    public MyControl() 
    { 
     InitializeComponent(); 
    } 

    public void CallView(string message) 
    { 
     MessageBox.Show(message); 
    } 
} 

public class MyViewModel 
{ 
    private IMyControl myControl; 

    public IMyControl InjectedUserControl 
    { 
     set 
     { 
      Debug.WriteLine(string.Format("Received Injected Control \"{0}\"", 
       value == null ? "NULL" : value.GetType().Name)); 

      this.myControl = value; 
      this.OnInjectedObjectsChanged(); 
     } 
    } 

    private void OnInjectedObjectsChanged() 
    { 
     // Directly access the view via its interface 
     if (this.myControl != null) 
      this.myControl.CallView("Hello From MyViewModel"); 
    } 
} 

有關可下載的演示文稿,其中包括注入器附屬資源的來源,請參閱this blog文章。也是this previous question這是相關的。

最好的問候,

+0

謝謝你,哈克解決方案給我關於我的問題的新想法,我也喜歡你以前的想法。但是我得到了答案,請在我的問題中查看我的評論。非常感謝! – tzuhsun 2012-01-18 09:11:33

+1

@tzuhsun完全沒問題 - 很高興你找到了你的答案! :) PS:來自麻省理工學院的黑客定義 - 「解決其他不可能問題的巧妙解決方案」 – 2012-01-18 09:12:25