views:

3133

answers:

2

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

+1  A: 

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

    }
}
A: 

What I would do is create a button that uses the command pattern for click handling. In the .NET 4 framework you can bind commands to those that exist on the view model.

Nate Zaugg