WPF ListView with buttons on each line

2019-01-13 13:21发布

问题:

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.

回答1:

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


回答2:

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.

  • WPF Commands Part 1: Basics
  • WPF Commands Part 2: Command Bindings and Gestures
  • MSDN Understanding Routed Events and Commands In WPF (ADVANCED)

HTH,



回答3:

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
    }