当ListView在其他具有大量数据的ListView中时,将重置UWP ListView的SelectedItem

时间:2018-10-25 12:04:15

标签: c# listview uwp

当大型ListView的DataTemplate包含小型ListView时,将重置小型ListView的SelectedItem。
我已经制作了示例应用程序,可以从三个选项中选择每个人的国家。 我从后面的代码中选择了最后一个小的ListView项目(索引:999)为“印度”。
但是当我向下滚动时,什么也没有选择,调试日志如下。

[调试日志]

添加:印度,已删除:

已添加:,已删除:印度

[MainPage.xaml]

<ListView ItemsSource="{x:Bind People}" SelectionMode="None">
    <ListView.ItemTemplate>
        <DataTemplate x:DataType="local:Person">
            <StackPanel BorderBrush="Black" BorderThickness="0,0,0,1">
                <TextBlock Text="{x:Bind Country, Mode=OneWay}"/>
                <ListView x:Name="CountryList"
                            ItemsSource="{x:Bind Countries, Mode=OneWay}"
                            SelectedItem="{x:Bind Country, Mode=TwoWay}"
                            SelectionChanged="CountryList_SelectionChanged">
                </ListView>
            </StackPanel>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

[MainPage.xaml.cs]

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);
    GenerateSampleData();
}

private void GenerateSampleData()
{
    for (int i = 0; i < 1000; i++)
    {
        People.Add(new Person
        {
            Countries = new List<string> { "China", "India", "USA" },
        });
    }
    People[999].Country = "India";
}

private void CountryList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    StringBuilder sb = new StringBuilder("Added:");
    foreach (var added in e.AddedItems)
    {
        if (added is string country)
        {
            sb.Append($" {country,-5}");
        }
    }

    sb.Append(", Removed:");
    foreach (var removed in e.RemovedItems)
    {
        if (removed is string country)
        {
            sb.Append($" {country,-5}");
        }
    }
    Debug.WriteLine(sb);
}

完整的来源如下。
 https://github.com/tokane888/ListViewQuestion

我不确定是否相关,但是一些小的ListView显示为灰色,如下所示。
(即使是后面的代码,也没有用手触摸过这个小的ListView。)
Gray ListView

1 个答案:

答案 0 :(得分:0)

  1. 未选择ListView项的原因是,您要在实际加载ListView之前设置属性。最好在ListView Loaded事件中设置选定的项目。

  2. 您看到的是灰色区域,原因是ListView虚拟化,因为您的ListView包含大量数据。

为了解决这两个问题,请按如下所示修改您的代码:

XAML:

<ListView ItemsSource="{x:Bind People}" SelectionMode="None">
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="local:Person">
                    <StackPanel BorderBrush="Black" BorderThickness="0,0,0,1">
                        <TextBlock Text="{x:Bind Country, Mode=OneWay}"/>
                        <ListView x:Name="CountryList"
                                    ItemsSource="{x:Bind Countries, Mode=OneWay}"
                                    SelectedItem="{x:Bind Country, Mode=TwoWay}"
                                    SelectionChanged="CountryList_SelectionChanged"
                                    Loaded="CountryList_Loaded"
                                  >
                            <ListView.ItemsPanel>
                                <ItemsPanelTemplate>
                                    <VirtualizingStackPanel/>
                                </ItemsPanelTemplate>
                            </ListView.ItemsPanel>
                        </ListView>

                    </StackPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
</ListView>

后面的代码:

 public sealed partial class MainPage : Page
    {
        public ObservableCollection<Person> People { get; } = new ObservableCollection<Person>();

        public MainPage()
        {
            this.InitializeComponent();
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);
            GenerateSampleData();
        }

        private void GenerateSampleData()
        {
            for (int i = 0; i < 1000; i++)
            {
                People.Add(new Person
                {
                    Countries = new List<string> { "China", "India", "USA" },
                });
            }

        }

        private void CountryList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            StringBuilder sb = new StringBuilder("Added:");
            foreach (var added in e.AddedItems)
            {
                if (added is string country)
                {
                    sb.Append($" {country,-5}");
                }
            }

            sb.Append(", Removed:");
            foreach (var removed in e.RemovedItems)
            {
                if (removed is string country)
                {
                    sb.Append($" {country,-5}");
                }
            }
            Debug.WriteLine(sb);
        }

        private void CountryList_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
           People[999].Country = "India";
        }
    }

另外,请参阅this帖子以了解详细信息。