WPF ListView with buttons on each line
Asked Answered
P

3

24

I have a list of Games which just has an ID, a Date, and a Time. I am setting this list as the DataContext.

I then have a DataTemplate for these games that is:

 <DataTemplate DataType="{x:Type loc:Game}">
     <Grid>
         <Grid.RowDefinitions>
             <RowDefinition Height="auto"></RowDefinition>
         </Grid.RowDefinitions>
         <Grid.ColumnDefinitions>
             <ColumnDefinition Width="100"></ColumnDefinition>
             <ColumnDefinition Width="100"></ColumnDefinition>
             <ColumnDefinition Width="100"></ColumnDefinition>
         </Grid.ColumnDefinitions>
         <TextBlock Name="dateBlock" Grid.Column="0" Grid.Row="1"
                    Text="{Binding Date,  StringFormat=d}"></TextBlock>
         <TextBlock Name="TimeBlock" Grid.Column="1" Grid.Row="1"
                    Text="{Binding Time}"></TextBlock>
         //need to but a button here for each row
     </Grid>
 </DataTemplate>

To use the template, I am simply just doing this:

    <ListBox ItemsSource="{Binding}"></ListBox>    

I need to add a Button to each line in this list view that have the same click event, but will somehow pass the ID of the game for which button is being clicked.

How can I do this? I am stuck. If it doesn't make sense let me know and I will try to explain better.

Paragraph answered 19/8, 2011 at 22:8 Comment(0)
A
50

For the first part, add a Button to the DataTemplate and subscribe to the Click event

<DataTemplate DataType="{x:Type loc:Game}">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"></RowDefinition>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="100"></ColumnDefinition>
            <ColumnDefinition Width="100"></ColumnDefinition>
            <ColumnDefinition Width="100"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <TextBlock Name="dateBlock" Grid.Column="0" Grid.Row="1" Text="{Binding Date,  StringFormat=d}"></TextBlock>
        <TextBlock Name="TimeBlock" Grid.Column="1" Grid.Row="1" Text="{Binding Time}"></TextBlock>
        <Button Click="Button_Click">X</Button>
    </Grid>
</DataTemplate>

In the code behind event handler, you can get the DataContext of the clicked Button and find out the Id like

private void Button_Click(object sender, RoutedEventArgs e)
{
    Button button = sender as Button;
    Game game = button.DataContext as Game;
    int id = game.ID;
    // ...
}
Ake answered 19/8, 2011 at 22:19 Comment(1)
did you mean Grid.Row="0"?Ammerman
G
17

Easily. Add a Button to your DataTemplate, give it a Command and then set the CommandParameter="{Binding}". The DataContext within a DataTemplate is the object.

As requested, some links to using commands.

HTH,

Goebel answered 19/8, 2011 at 22:20 Comment(5)
It is a neater solution. Since I've been writing MVVM code I do even think to use event handlers in code behind (i.e. xaml.cs). It is just so much nicer.Goebel
Dennis, a code example of how to do the rest of the Command Binding (or at least a link to an existing one) would be really helpful in your answer. In these cases, I also prefer using Commands with the parameter using Binding.Rheology
@Ether: I would usually throw together an example when it is required, however as Commands are such well covered topic I will do the Google search and add a few of the better results to my answer.Goebel
Thanks guys, this may be neater but I was getting confused with the commands. I may change it later, but for now the other answer was easier for me :) thanks!Paragraph
It's better explained here #5063808Designate
K
4

With a ListBox.ItemTemplate. Then in your click event you can get the object via DataContext.

    <ListBox.ItemTemplate>
        <DataTemplate>
            <Button Content="^" IsEnabled="{Binding Path=IsNotFirst, Mode=OneWay}" 
             Click="btnMoveFDAup"/>
        </DataTemplate>
    </ListBox.ItemTemplate>


    private void btnMoveFDAup(object sender, RoutedEventArgs e)
    {
        Button btn = ((Button)sender);
        // btn.DataContext will get you to the row object where you can retrieve the ID
    }
Kantianism answered 19/8, 2011 at 22:21 Comment(1)
How would I get the values from btn.DataContext? For example, in the debugger I can see that btn.DataContext is pointing to my class of data (LVDATA) and what I need is the value in string Name. How do I access this?Aristotelianism

© 2022 - 2024 — McMap. All rights reserved.