WPF DataTemplate事件绑定到对象函数

WPF DataTemplate事件绑定到对象函数,wpf,data-binding,events,datatemplate,Wpf,Data Binding,Events,Datatemplate,我目前正在为我的自定义类型(比如足球运动员)编写数据模板。在这个模板中,我想放置ie.按钮,并在单击时使该按钮调用一些足球运动员函数,例如Run() 有没有简单或复杂但干净的方法来实现这种行为 我相信DataTemplate知道关于我的对象的所有信息,因为设置了DataType,并且包含了clr名称空间 <DataTemplate DataType="{x:Type my:FootballPlayer}"> </DataTemplate> 我想有一个干净的方法来实

我目前正在为我的自定义类型(比如足球运动员)编写数据模板。在这个模板中,我想放置ie.按钮,并在单击时使该按钮调用一些足球运动员函数,例如Run()

有没有简单或复杂但干净的方法来实现这种行为

我相信DataTemplate知道关于我的对象的所有信息,因为设置了DataType,并且包含了clr名称空间

<DataTemplate DataType="{x:Type my:FootballPlayer}">

</DataTemplate>

我想有一个干净的方法来实现这一点。谁能告诉我怎么做

//编辑
解决方案不必是干净的。现在,经过一些调查之后,我正在寻找任何可以调用函数/在被绑定对象上引发事件的解决方案。

是的,有一种干净的方法可以做到这一点。在WPF中使用命令的一个方面(不是您必须使用它)是命令

下面是一个简单但干净且相当类型安全的框架类,用于公开数据源对象中的命令:

using System;
using System.Windows.Input;

namespace MVVM
{
/// <summary>
/// Defines a command that can be bound to from XAML and redirects to a handler function.
/// </summary>
public class ViewModelCommand : ICommand
{
    private Action _handler;


    public ViewModelCommand(Action handler)
    {
        _handler = handler;
    }


    #region ICommand Members

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
        _handler();
    }

    #endregion
}

/// <summary>
/// Defines a command that can be bound to from XAML and redirects to a handler function.
/// </summary>
public class ViewModelCommand<T> : ICommand
    where T : class
{
    private Action<T> _handler;


    public ViewModelCommand(Action<T> handler)
    {
        _handler = handler;
    }


    #region ICommand Members

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
        _handler(parameter as T);
    }

    #endregion
}
}
使用系统;
使用System.Windows.Input;
名称空间MVVM
{
/// 
///定义可以从XAML绑定到的命令,并重定向到处理程序函数。
/// 
公共类viewmodel命令:ICommand
{
私人行动;
公共ViewModelCommand(操作处理程序)
{
_handler=handler;
}
#区域ICommand成员
公共布尔CanExecute(对象参数)
{
返回true;
}
公共事件处理程序CanExecuteChanged;
public void Execute(对象参数)
{
_handler();
}
#端区
}
/// 
///定义可以从XAML绑定到的命令,并重定向到处理程序函数。
/// 
公共类viewmodel命令:ICommand
T:在哪里上课
{
私人行动;
公共ViewModelCommand(操作处理程序)
{
_handler=handler;
}
#区域ICommand成员
公共布尔CanExecute(对象参数)
{
返回true;
}
公共事件处理程序CanExecuteChanged;
public void Execute(对象参数)
{
_handler(参数为T);
}
#端区
}
}
然后,您的数据源(例如FootballPlayer类)将公开一个命令属性,如下所示:

    /// <summary>
    /// Tell the player to run.  This particular command takes a string as a parameter.
    /// </summary>
    public ICommand RunCommand
    {
        get { return new ViewModelCommand<string>(run); }
    }
//
///告诉玩家快跑。此特定命令将字符串作为参数。
/// 
公共ICommand运行命令
{
获取{returnnewviewmodelcommand(run);}
}
同一足球运动员类中的实现函数可以如下所示:

    /// <summary>
    /// Tell the player to run.  This particular command takes a string as a parameter.
    /// </summary>
    public void search(string destination)
    {
        System.Windows.MessageBox.Show(destination, "Running to destination...");
    }
//
///告诉玩家快跑。此特定命令将字符串作为参数。
/// 
公共无效搜索(字符串目标)
{
System.Windows.MessageBox.Show(目的地,“运行到目的地…”);
}
最后,您的XAML具有以下数据绑定:

<Button Content="{Binding PlayerName}" FontSize="16" CommandParameter="{Binding Text, ElementName=txtDestination}" Command="{Binding RunCommand, Source={StaticResource ViewModelDataSource}}" />


(因为您使用的是DataTemplate,所以需要调整绑定的源;但这就是它的要点。我在一个类项目中非常成功地使用了它-它允许逻辑和UI之间有一个非常清晰的分离。)

如果您为事件设置了一个通用处理程序:
e.OriginalSource的DataContext将是用于绑定的FootballPlayer对象。然后可以在该对象上调用Run

private void FootballPlayer_Run(object sender, RoutedEventArgs e)
        {
            FrameworkElement ele = e.OriginalSource as FrameworkElement;
            if (ele != null)
            {
                FootballPlayer fp = ele.DataContext as FootballPlayer;
                if (fp != null)
                {
                    fp.Run();
                }
            }
            e.Handled = true;
        }

非常感谢你!这当然是一个很好的解决方案。说实话,我期待WPF“开箱即用”支持的东西,它允许以绑定普通属性的方式绑定事件,但我想这是非常值得期待的。