首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >绑定到ViewModel的WPF事件(用于非命令类)

绑定到ViewModel的WPF事件(用于非命令类)
EN

Stack Overflow用户
提问于 2011-06-22 02:34:30
回答 5查看 41.3K关注 0票数 24

我正在开发一个应用程序的第二个版本,作为重写的一部分,我必须迁移到MVVM架构。我承受着把每一段代码都放在视图模型类中的压力--在代码隐藏文件中使用c#是不受欢迎的。(我知道,我知道……我知道代码隐藏不是一件坏事,但这一次不是我说了算)。

对于实现命令接口的对象来说,这很容易。我已经找到了大量关于如何将这些对象的命令绑定到视图模型中的ICommand的信息。问题在于没有这个接口的对象,例如

代码语言:javascript
复制
<ListBox
   x:Name="myListBox"
   MouseDoubleClick="myCallbackFunction">

<!-- ... -->

</ListBox>

我想知道如何将列表框的MouseDoubleClick事件绑定到在视图模型中实现的myCallbackFunction。这有可能吗?

谢谢!

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2011-06-22 02:41:02

这不是直接可能的。这可以通过附加的属性或行为来完成,尽管找到和调用适当的方法仍然有些棘手(这可以通过反射相当容易地完成)。

也就是说,这通常是通过ICommand处理的-例如,MVVM Light有一个很棒的EventToCommand行为,可以将任何事件映射到ViewModel上的ICommand。使用ICommand的好处是,您仍然可以使用DataBinding,因为ICommand是作为属性公开的。

票数 11
EN

Stack Overflow用户

发布于 2016-07-06 02:14:27

从.NET 4.5开始,WPF支持事件的标记扩展。使用该功能,我实现了一个通用的方法绑定扩展,并在此处对其进行了介绍:

http://www.singulink.com/CodeIndex/post/building-the-ultimate-wpf-event-method-binding-extension

可用于绑定到使用完整属性路径语法的方法,支持将绑定和其他标记扩展作为参数,并自动路由到与所提供参数的签名匹配的方法。以下是一些使用示例:

代码语言:javascript
复制
<!--  Basic usage  -->
<Button Click="{data:MethodBinding OpenFromFile}" Content="Open" />

<!--  Pass in a binding as a method argument  -->
<Button Click="{data:MethodBinding Save, {Binding CurrentItem}}" Content="Save" />

<!--  Another example of a binding, but this time to a property on another element  -->
<ComboBox x:Name="ExistingItems" ItemsSource="{Binding ExistingItems}" />
<Button Click="{data:MethodBinding Edit, {Binding SelectedItem, ElementName=ExistingItems}}" />

<!--  Pass in a hard-coded method argument, XAML string automatically converted to the proper type  -->
<ToggleButton Checked="{data:MethodBinding SetWebServiceState, True}"
                Content="Web Service"
                Unchecked="{data:MethodBinding SetWebServiceState, False}" />
                
<!--  Pass in sender, and match method signature automatically -->
<Canvas PreviewMouseDown="{data:MethodBinding SetCurrentElement, {data:EventSender}, ThrowOnMethodMissing=False}">
    <controls:DesignerElementTypeA />
    <controls:DesignerElementTypeB />
    <controls:DesignerElementTypeC />
</Canvas>

    <!--  Pass in EventArgs  -->
<Canvas MouseDown="{data:MethodBinding StartDrawing, {data:EventArgs}}"
        MouseMove="{data:MethodBinding AddDrawingPoint, {data:EventArgs}}"
        MouseUp="{data:MethodBinding EndDrawing, {data:EventArgs}}" />

<!-- Support binding to methods further in a property path -->
<Button Content="SaveDocument" Click="{data:MethodBinding CurrentDocument.DocumentService.Save, {Binding CurrentDocument}}" />

查看模型方法签名:

代码语言:javascript
复制
public void OpenFromFile();
public void Save(DocumentModel model);
public void Edit(DocumentModel model);

public void SetWebServiceState(bool state);

public void SetCurrentElement(DesignerElementTypeA element);
public void SetCurrentElement(DesignerElementTypeB element);
public void SetCurrentElement(DesignerElementTypeC element);

public void StartDrawing(MouseEventArgs e);
public void AddDrawingPoint(MouseEventArgs e);
public void EndDrawing(MouseEventArgs e);

public class Document
{
    // Fetches the document service for handling this document
    public DocumentService DocumentService { get; }
}

public class DocumentService
{
    public void Save(Document document);
}
票数 7
EN

Stack Overflow用户

发布于 2011-06-22 04:15:41

为了直接回答你的问题,请参考Why to avoid the codebehind in WPF MVVM pattern?,它建议了你想要的两个可能的东西。

但是,为什么要将ListBox的MouseDoubleClick绑定到视图模型中的ICommand?

另一种方法是在代码后台中编写一个方法来注册MouseDoubleClick。由于以下事实,这并不是很糟糕。

  1. 有意义的数据绑定是视图和视图模型之间的交互。例如,当用户向TextBox输入一些文本时,视图模型也会更新。相反,如果视图模型从数据库中获取数据,它将显示在视图中。
  2. 当然,CanExcute的ICommand对你的视图模型很重要,但在很多情况下,它与视图模型无关或不相关。在这种情况下,ICommand绑定和编写代码隐藏之间的区别在于MouseDoubleClick事件与ICommand绑定或使用事件处理程序注册。
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6430256

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档