views:

247

answers:

1

Hello,

I'm currently writing DataTemplate for my custom type lets say FootballPlayer. In this template I would like to put ie. Button and make that button when clicked call some of FootballPlayer functions eg. Run().

Is there any simple or complex, but clean way to achieve this kind of behaviour?

The DataTemplate I believe is aware of all the information about my object because DataType is set and clr-namespace is included.

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

</DataTemplate>

I suppose there is a clean way to achieve this. Can anyone tell me how?

Thanks in advance kubal5003

//edit The solution doesn't have to be clean. Now, after some investigation I'm just looking for any solution that can make a call to function / raise an event on the object being bound.

+2  A: 

Hello,

Yes, there is a clean way to do this. One aspect of using the Model-View-ViewModel pattern in WPF (not that you have to use this) is commanding. WPF Commanding reference

Here is a simplistic but clean and fairly type-safe framework class for exposing commands from your data source object:

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

Your data source (e.g., FootballPlayer class) then exposes a command property as follows:

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

The implementation function, in the same FootballPlayer class, can then look like this:

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

Finally, your XAML has the following databinding:

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

(Since you're using a DataTemplate, the sources of the bindings would need to be adjusted; but that's the gist of it. I've used this with great success in a class project (WikiShelf) - it allowed a very clean separation between the logic and the UI.)

Lars Kemmann
Thank you very much! This is certainly a great solution. I was, to tell you the truth, expecting something supported by WPF 'out of the box' that would allow to bind events the same way ordinary properties are bound, but I guess it's to much to expect.
kubal5003