Is it possible to bind an Event in a Silverlight DataTemplate?

Yttrium picture Yttrium · Mar 26, 2009 · Viewed 9.6k times · Source

Is it possible to bind an Event in a Silverlight DataTemplate? If so, what is the best way to do it?

For example, say you've created a DataTemplate that has a Button in it, like this:

<UserControl.Resources>
  <DataTemplate x:Key="MyDataTemplate" >
     <Grid>
        <Button Content="{Binding ButtonText}" Margin="4" />
     </Grid>
  </DataTemplate>
</UserControl.Resources>

Then, you apply it to a ListBox ItemTemplate, like this:

<Grid x:Name="LayoutRoot" Background="White">
  <ListBox x:Name="lbListBox" ItemTemplate="{StaticResource MyDataTemplate}" />    
</Grid>

If you set the ListBox's ItemSource to a list of objects of the class:

public class MyDataClass
{
  public string ButtonText{ get; set; }
}

How then do you catch the button click from each button from the DataTemplate in the list? Can you use binding to bind the Click event to a method in "MyButtonClass", like this:

<UserControl.Resources>
  <DataTemplate x:Key="MyDataTemplate" >
     <Grid>
        <Button Click="{Binding OnItemButtonClick}" Content="{Binding ButtonText}" Margin="4" />
     </Grid>
  </DataTemplate>
</UserControl.Resources>

Would this work? If so, what should I put in the "MyDataClass" to catch the event?

Thanks, Jeff

Answer

Matt Weyland picture Matt Weyland · Mar 26, 2009

There are a couple of options.

One. make a custom control that is bound the data object for that row. On that custom control add the handler for the bound object.

I dont think your binding on the click will work. Sans the Binding Statment and just declare your click to a string.

Add the handler on the page where the control is housed. Keep in mind that if you bind this way you will only be able to work with the sender of that item (button) and it's properties. If you need to get at specific attributes on an object you maybe better off pursuing the first option.

Small Example demonstrating the functionality by adding 10 buttons to a list box with click events. HTH

DataTemplate XAML

<UserControl.Resources>
    <DataTemplate x:Name="MyDataTemplate">
        <Grid>
            <Button Click="Button_Click" Content="{Binding ItemText}"/>
        </Grid>
    </DataTemplate>
</UserControl.Resources>

ListBox XAML

<ListBox x:Name="ListBoxThingee" ItemTemplate="{StaticResource MyDataTemplate}"/>

Code Behind (I just plugged this all into the page.xaml file

public class MyClass
{
    public string ItemText { get; set; }
}


public partial class Page : UserControl
{
    ObservableCollection<MyClass> _Items;
    public Page()
    {
        InitializeComponent();

        _Items = new ObservableCollection<MyClass>();

        for (int i = 0; i < 10; i++)
        {
            _Items.Add(new MyClass() {ItemText= string.Format("Item - {0}", i)});
        }

        this.ListBoxThingee.ItemsSource = _Items;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Button _b = sender as Button;
        if (_b != null)
        {
            string _s = _b.Content as string;
            MessageBox.Show(_s);
        }

    }
}