UWP ListView SelectedItem сбрасывается, когда ListView находится в другом ListView с большими данными - PullRequest
0 голосов
/ 25 октября 2018

Когда большой DataTemplate ListView содержит маленький ListView, SelectedItem малого ListView сбрасывается.
Я создал пример приложения, которое выбирает страну каждого человека из трех вариантов.Я выбрал «Индия» в последнем небольшом элементе 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 голосов
/ 26 октября 2018
  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";
        }
    }

Также, пожалуйста, обратитесь к этому сообщению для получения подробной информации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...