WPF ListView 每行带有按钮的实现

24

我有一个包含IDDateTimeGames列表。 将此列表设置为DataContext

然后我有一个适用于这些游戏的DataTemplate

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

为了使用这个模板,我只需要这样做:

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

我需要在此列表视图的每一行中添加一个按钮,该按钮具有相同的单击事件,但将以某种方式传递被点击的游戏的ID。

我应该如何做?我卡住了。如果不清楚,请告诉我,我会尽力解释得更好。

3个回答

50

对于第一部分,将一个Button添加到DataTemplate并订阅Click事件。

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

在代码后端的事件处理程序中,你可以获取被点击的 ButtonDataContext 并找出其中的 Id,例如:

private void Button_Click(object sender, RoutedEventArgs e)
{
    Button button = sender as Button;
    Game game = button.DataContext as Game;
    int id = game.ID;
    // ...
}

你是指 Grid.Row="0" 吗? - Kappacake

17

4
这是一种更简洁的解决方案。自从我开始编写MVVM代码后,我甚至不考虑在代码后面使用事件处理程序(即xaml.cs)。这只是更加优雅。 - Dennis
1
Dennis,能否提供一个如何完成命令绑定的代码示例(或至少是现有示例的链接)将会对你的回答非常有帮助。在这些情况下,我也更喜欢使用带参数绑定的命令。 - EtherDragon
@Ether:通常情况下,如果需要的话我会编写一个示例,但是由于命令是一个被广泛涵盖的主题,我将进行谷歌搜索,并将一些更好的结果添加到我的答案中。 - Dennis
谢谢大家,这可能更整洁,但我对命令感到困惑。我以后可能会改变它,但目前为止,另一个答案对我来说更容易:) 谢谢! - twaldron
1
这里有更好的解释:https://dev59.com/ZW445IYBdhLWcg3wDWAP - user585968

4
使用ListBox.ItemTemplate。然后在单击事件中,您可以通过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
    }

我该如何从btn.DataContext中获取值?例如,在调试器中,我可以看到btn.DataContext指向我的数据类(LVDATA),我需要的是字符串Name中的值。我该如何访问它? - zetar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接