为什么ItemClick事件处理程序返回上一个单击的项目?

时间:2015-11-24 19:36:25

标签: c# listview event-handling datatemplate win-universal-app

我有一个ListView,带有一个带有网格的ListView ItemTemplate。 我需要点击的行的信息,并在ListView上有IsItemClickEnabled=TrueItemClick事件处理程序带有显示行的id的调试。

我无法弄清楚为什么返回的项目总是我之前点击的项目,并且第一次点击不会产生任何结果。

这是ListView的标记

<ListView x:Name="ListCustomerView"  ItemsSource="{x:Bind CustomersFromDB}" Grid.Row="1" HorizontalAlignment="Center" IsItemClickEnabled="True" ItemClick="ListCustomerView_ItemClick">
    <ListView.ItemTemplate>
        <DataTemplate>
            <Grid IsTapEnabled="False">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition MinWidth="{StaticResource minColumnWidth}" MaxWidth="{StaticResource maxColumnWidth}"></ColumnDefinition>
                    <ColumnDefinition MinWidth="{StaticResource minColumnWidth}" MaxWidth="{StaticResource maxColumnWidth}"></ColumnDefinition>
                    <ColumnDefinition MinWidth="{StaticResource minColumnWidth}" MaxWidth="{StaticResource maxColumnWidth}"></ColumnDefinition>
                    <ColumnDefinition MinWidth="{StaticResource minColumnWidth}" MaxWidth="{StaticResource maxColumnWidth}"></ColumnDefinition>
                    <ColumnDefinition MinWidth="{StaticResource minColumnWidth}" MaxWidth="{StaticResource maxColumnWidth}"></ColumnDefinition>
                    <ColumnDefinition MinWidth="{StaticResource minColumnWidth}" MaxWidth="{StaticResource maxColumnWidth}"></ColumnDefinition>
                    <ColumnDefinition MinWidth="{StaticResource minColumnWidth}" MaxWidth="{StaticResource maxColumnWidth}"></ColumnDefinition>
                    <ColumnDefinition MinWidth="{StaticResource minColumnWidth}" MaxWidth="{StaticResource maxColumnWidth}"></ColumnDefinition>
                    <ColumnDefinition MinWidth="{StaticResource minColumnWidth}" MaxWidth="{StaticResource maxColumnWidth}"></ColumnDefinition>

                </Grid.ColumnDefinitions>
                <TextBlock Grid.Column="0" Text="{Binding CompanyName}"></TextBlock>
                <TextBlock Grid.Column="1" Text="{Binding FirstName}"></TextBlock>
                <TextBlock Grid.Column="2" Text="{Binding LastName}"></TextBlock>
                <TextBlock Grid.Column="3" Text="{Binding Phone}"></TextBlock>
                <TextBlock Grid.Column="4" Text="{Binding Email}"></TextBlock>
                <TextBlock Grid.Column="5" Text="{Binding Adress}"></TextBlock>
                <TextBlock Grid.Column="6" Text="{Binding PostCode}"></TextBlock>
                <TextBlock Grid.Column="7" Text="{Binding PostArea}"></TextBlock>
                <TextBlock Grid.Column="8" Text="{Binding Comment}"></TextBlock>
            </Grid>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

以下是CustomersFromDB ItemsSource的代码

public List<Customer> CustomersFromDB { get; set; }
var db = new Database();
CustomersFromDB = db.FetchCustomer();

public List<Customer> FetchCustomer()
{
    using (SQLiteConnection _connection = new SQLiteConnection(sqlitePlatform, dbFilePath))
    {
        List<Customer> customers = new List<Customer>();
        var _customers = _connection.Table<Customer>();
        if (_customers.Count() > 0)
        {
            foreach (Customer customer in _customers)
            {
                customers.Add(customer);
            }
        }
        return customers;
    }
}

插图 Illustration of list of customers from sqlite database displayed in the ListView using a DataTemplate with a Grid with textblocks.

和事件处理程序

private void ListCustomerView_ItemClick(object sender, ItemClickEventArgs e)
{
    // BUG! the selected item is not firing correctly ending up outputting the previous clicked item
    Debug.WriteLine((sender as ListView).SelectedItem);
}

如上图所示检索客户,但是当我点击一行时,id是之前点击的,如果是第一次点击则为null。

为什么会发生这种奇怪的行为?

2 个答案:

答案 0 :(得分:1)

那是因为您正在使用sender.SelectedItem来为您提供当前选择。新选择是您想要的,仅在click事件之后进行。要获取您刚刚点击的项目,请使用e参数:

private void ListCustomerView_ItemClick(object sender, ItemClickEventArgs e)
{
    Debug.WriteLine(e.ClickedItem.ToString());
}

或者,您可以使用SelectionChanged事件代替ItemClick事件。这将使用与您相同的代码为您提供新的选择:

private void ListCustomerView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    Debug.WriteLine((sender as ListView).SelectedItem.ToString());
}

答案 1 :(得分:0)

我还没有测试过,但我猜测点击事件发生在选择事件发生之前。因此,当您的click事件处理程序触发时,selecteditem是“先前”选择的任何内容。我相信你正在寻找ItemClickedEventArgs

上的ClickedItem属性