Windows Phone 8.1 ListView.ReorderMode не уведомява ObservableCollection

В приложение за Windows Phone 8.1 (насочено към Runtime, а не към Silverlight), имам ObservableCollection, свързан към ListView, дефиниран по следния начин:

<ListView ItemsSource="{Binding ListItems, Mode=TwoWay}" CanReorderItems="True" ReorderMode="Enabled">
    <ListView.ItemTemplate>
        ...etc...

В конструктора на ViewModel също имам

ListItems.CollectionChanged += ListItems_CollectionChanged;

което повдига събитието всеки път, когато се добавят и изтриват елементи - обаче, всичко това се обработва от VM, а не от View. За съжаление, събитието не се повдига, когато артикулите се пренареждат. Настроих това, преместих някои елементи, добавих точка на прекъсване в манипулатора на събития и добавих елемент и мога да видя, че основният ред на ObservableCollection се е променил като контролиран от изгледа. Така че защо събитието не се повишава? И ако не стане, каква е най-добрата практика за запазване на реда на ListView в базата данни?

АКТУАЛИЗАЦИЯ:

Проблемът всъщност е по-голям, отколкото си мислех... изглежда, че събитието ListView.CollectionChanged също не се задейства при добавяне на елемент! Това става, когато приложението се стартира и ги зарежда от базата данни, но не и когато се добавят от потребител от потребителския интерфейс. Това е много странно, защото добавянето на елементи се извършва по абсолютно същия метод. От базата данни:

private ViewModel MapFromModel(Item model, SQLiteAsyncConnection connection)
    {
        var viewModel = new ViewModel
        {
            Id = model.Id,
            Text = model.Text,
            Description = model.Description,
            Added = model.Added,
            Completed = model.Completed,
            DueOn = model.DueOn,
            ParentId = model.ParentId,
            DisplayOrderNumber = model.DisplayOrderNumber,
            IsNew = false
        };

        foreach (
            var childViewModel in
                connection.Table<Item>()
                    .Where(ci => ci.ParentId == viewModel.Id)
                    .ToListAsync()
                    .Result.Select(childItem => MapFromModel(childItem, connection)))
        {
            if (!_cache.Contains(childViewModel))
                _cache.Add(childViewModel);
            viewModel.AddItem(childViewModel);
        }
        return viewModel;
    }

Виждате, че този рекурсивен метод извиква метода AddItem() на ViewModel, за да добави деца (които са от същия тип). Също така имам ICommand, свързан с бутон за добавяне на други елементи:

    public void Execute(object parameter)
    {
        var viewModel = parameter as ViewModel;
        if (viewModel == null) return;

        AddItem(viewModel);
    }
public static void AddItem(ViewModel viewModel)
    {
        // The DisplayOrderNumber of the new item needs to be the max of the current collection + 1.
        var displayOrderNumber = viewModel.ListItems.Any()
            ? viewModel.ListItems.Max(ci => ci.DisplayOrderNumber) + 1
            : 0;
        var newText = string.Format("{0} {1}",
            viewModel.Id == Guid.Empty ? "List" : "Item", displayOrderNumber + 1);
        var newItem = new ViewModel
        {
            Text = newText,
            NewText = newText,
            ParentId = viewModel.Id,
            InEditMode = true,
            Added = DateTime.Now,
            DisplayOrderNumber = displayOrderNumber,
            IsNew = true
        };
        viewModel.AddItem(newItem);
        viewModel.Save();
    }

Така че защо методът AddItem() трябва да повдига събитието, когато се извиква от Service Layer, но не и от самия ViewModel слой?


person MrShoes    schedule 15.07.2014    source източник


Отговори (1)


Оказва се, както обикновено, грешката е изцяло моя.

Това се случваше, защото методът за обработка на събитията ListItems_CollectionChanged беше прекъснат. Причината за това беше поради метод за сортиране, който заместваше основната връзка. Заобиколих този проблем, като добавих манипулатора на събития, ако е необходимо, в сетера за свойството (и разбира се премахнах всички неизползвани манипулатори на събития).

person MrShoes    schedule 16.07.2014