我正在为我的自定义类型编写DataTemplate,可以说是FootballPlayer。在这个模板中,我想把ie。单击按钮并使该按钮调用一些FootballPlayer函数,例如。运行()。
是否有任何简单或复杂但干净的方式来实现这种行为?
我相信DataTemplate知道有关我的对象的所有信息,因为DataType已设置且包含了clr-namespace。
<DataTemplate DataType="{x:Type my:FootballPlayer}">
</DataTemplate>
我想有一种干净的方法来实现这一目标。谁能告诉我怎么样?
//编辑 解决方案不一定要干净。现在,经过一些调查后,我只是在寻找任何可以调用函数/在被绑定对象上引发事件的解决方案。
答案 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;
}