Почему перемещение элемента в LongListSelector приводит к отсутствующим элементам

1

Я использую простой список в LongListSelector с ObservableCollection как ItemSource.

Первоначально все мелкие прокрутки до конца списка и обратно к началу не имеют проблем.

Но затем я вызываю ObservableCollection.Move(2, 1). И теперь, когда я прокручиваю до конца и вернусь к вершине (так что элементы снова реализованы), я получаю неполный список - случайное количество элементов из начала списка отсутствует (например: 1,2,3... 100 меняется до 1,3,42,43..100).

Я что-то делаю неправильно, или это ошибка в LongListSelector?

Вот минимальный пример моей проблемы:

TestPage.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using System.Collections.ObjectModel;

namespace myApp.Pages
{
    public class Item
    {
        public string Text { get; set; }
    }

    public class ItemsViewModel
    {
        public ObservableCollection<Item> UngroupedItems { get; set; }
    }

    public partial class TestPage : PhoneApplicationPage
    {
        ItemsViewModel _vm;
        public TestPage()
        {
            InitializeComponent();

            _vm  = new ItemsViewModel();
            _vm.UngroupedItems = new ObservableCollection<Item>();

            for (int i = 0; i < 100; i++)
            {
                _vm.UngroupedItems.Add(new Item() { Text = string.Format("- line {0}", _vm.UngroupedItems.Count + 1) });
            }

            DataContext = _vm;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            _vm.UngroupedItems.Move(2, 1);
        }
    }
}

TestPage.xaml

<phone:PhoneApplicationPage
    x:Class="myApp.Pages.TestPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    mc:Ignorable="d"
    shell:SystemTray.IsVisible="True">

    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <phone:LongListSelector ItemsSource="{Binding UngroupedItems}">
            <phone:LongListSelector.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Text}" Style="{StaticResource PhoneTextTitle2Style}"/>
                </DataTemplate>
            </phone:LongListSelector.ItemTemplate>
        </phone:LongListSelector>
        <Button VerticalAlignment="Bottom"  Content="Test" Click="Button_Click"></Button>
    </Grid>
</phone:PhoneApplicationPage>
  • 0
    ты решил свою проблему? Я сталкиваюсь с проблемой, как ты.
  • 0
    @ shamimreza Я закончил с удалением + вставкой, чтобы обойти это. Но я покинул платформу Windows, поэтому я не знаю о последних версиях.
Теги:
observablecollection
updating
windows-phone-8
longlistselector

1 ответ

1
Лучший ответ

Мне никогда не нравиться эта функция при привязке.

Вы можете видеть, что он даже не обновляет селектор длинного списка до тех пор, пока вы не перейдете обратно к части, которая изменилась, что не идеально.

На данный момент, я думаю, вы должны безопасно сделать ход самостоятельно, если у кого-то еще нет лучшей идеи.

private void Button_Click(object sender, RoutedEventArgs e)
{
    SafeMove(2, 1);
}

private void SafeMove(int old_index, int new_index)
{
     var saved_item = _vm.UngroupedItems[old_index];           
    _vm.UngroupedItems.RemoveAt(old_index);
    _vm.UngroupedItems.Insert(new_index, saved_item);
}

Версия шаблона

private void SafeMove<T>(ref ObservableCollection<T> collection, int old_index, int new_index)
{

    var saved_item = collection[old_index];
    collection.RemoveAt(old_index);
    collection.Insert(new_index, saved_item);  

}


Используя безопасный ход, вы увидите, что селектор длинного списка сразу обновляется.

  • 0
    Спасибо за ваш метод;) Да, я уже проверил таким образом. Но не уверен, что этот способ всегда без мерцания. Тем не менее, это похоже на обход некоторых магических проблем. Мне не нравится волшебство, и я хочу знать, является ли это проблемой LLS, или я что-то неправильно понимаю.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню