2012-01-18 68 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