将方法绑定到xaml控件

时间:2012-01-18 08:19:47

标签: wpf xaml binding

我需要将方法绑定到xaml文件中的自定义控件,而不是方法的结果。

基本上,当某些条件匹配时,自定义控件会触发该方法几次。

我该怎么做?

我在互联网上找到了一些解决方案,但大多数都将方法的结果绑定到xaml中,这不是我想要的解决方案。

非常感谢。

4 个答案:

答案 0 :(得分:2)

您可以使用两种不同的方法:

  • Commands,公开您绑定到UI元素的Command属性的ICommand类型的属性。
  • 使用行为将UI事件连接到视图模型中的方法,例如使用MVVM Light EventToCommandBehaviour

答案 1 :(得分:2)

找到了这个很棒的答案:

Binding of static method/function to Func<T> property in XAML

Simon Rasmussen已经在他的问题示例代码中展示了我所需要的一切。

答案 2 :(得分: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();  
         }
    } 
}

这被认为是一个有点hacky并且在运行时通过ViewModel类型的知识污染代码隐藏。我们想要避免的事情,因为它打破了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"); 
    } 
}

有关包含Injector附加属性源的可下载演示,请参阅this blog帖子。另外this previous question也是相关的。

致以最诚挚的问候,

答案 3 :(得分:0)

您希望绑定到ICommand的实现,并调用您的类方法。

Here's a good blog描述了有关使用ICommand从WPF执行代码的更多信息。