WPF DataTemplate绑定到对象函数的事件

时间:2010-06-04 14:23:33

标签: wpf data-binding events datatemplate

我正在为我的自定义类型编写DataTemplate,可以说是FootballPlayer。在这个模板中,我想把ie。单击按钮并使该按钮调用一些FootballPlayer函数,例如。运行()。

是否有任何简单或复杂但干净的方式来实现这种行为?

我相信DataTemplate知道有关我的对象的所有信息,因为DataType已设置且包含了clr-namespace。

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

</DataTemplate>

我想有一种干净的方法来实现这一目标。谁能告诉我怎么样?

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

2 个答案:

答案 0 :(得分:3)

是的,有一种干净的方法可以做到这一点。在WPF中使用Model-View-ViewModel pattern的一个方面(不是你必须使用它)是命令WPF Commanding reference

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

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
}
}

您的数据源(例如,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); }
    }

在同一个FootballPlayer类中,实现函数可以如下所示:

    /// <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...");
    }

最后,您的XAML具有以下数据绑定:

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

(因为你正在使用DataTemplate,所以需要调整绑定的来源;但这就是它的要点。我在类项目中使用它非常成功 - 它允许非常清晰地分离逻辑和用户界面。)

答案 1 :(得分:1)

如果为事件设置了通用处理程序: <Button Click="FootballPlayer_Run"/> 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;
        }