Проблемы привязки данных в Windows Phone 7 - PullRequest
1 голос
/ 10 марта 2011

У меня есть приложение для Windows Phone 7 с локальной «базой данных» наблюдаемых коллекций, которые сохраняются в изолированном хранилище.Когда приложение запускается впервые, оно проверяет, существуют ли какие-либо данные, если данных нет, затем извлекает данные из службы WCF и загружает их в наблюдаемые коллекции.Таймер сбрасывает данные из наблюдаемых коллекций в изолированное хранилище каждые 10 секунд.Я просто создаю прототип приложения, поэтому думал, что я буду отображать данные из наблюдаемых коллекций в нескольких простых списках в сводном элементе управления, используя привязку данных.У меня проблема в том, что в начальном сценарии, когда данные извлекаются из службы WCF, некоторые списки отображают свои данные, а некоторые нет.(Есть 6 списков, и кажется последовательным, что те же самые 2 не показывают свои данные).Если я затем закрою приложение и снова открою его, тогда все списки покажут свои данные, как и ожидалось.Разница в том, что теперь данные просто загружаются в наблюдаемые коллекции из изолированного хранилища - их не нужно извлекать из службы WCF.

Класс, который содержит наблюдаемые коллекции, выглядит следующим образом:

public sealed class Database : INotifyPropertyChanged
{
    //Declare Instance
    private static Database instance;// = new Database();
    private static object syncRoot = new Object();

    //Private Constructor
    private Database() 
    {
        Categories = new ObservableCollection<Category>();
        CategoryTypes = new ObservableCollection<CategoryType>();
        Customers = new ObservableCollection<Customer>();
        Tasks = new ObservableCollection<Task>();
        TimePeriods = new ObservableCollection<TimePeriod>();
        RecentTasks = new ObservableCollection<RecentTask>();
    }

    /// <summary>
    /// The entry point into this Database
    /// </summary>
    public static Database Instance
    {
        get
        {
            if (instance == null)
            {
                lock (syncRoot)
                {
                    if (instance == null)
                    {
                        //custom code
                        instance = new Database();
                    }
                }
            }

            return instance;
        }
    }

    #region Properties

    public ObservableCollection<Category> Categories { get; set; }
    public ObservableCollection<CategoryType> CategoryTypes { get; set; }
    public ObservableCollection<Customer> Customers { get; set; }
    public ObservableCollection<Task> Tasks { get; set; }
    public ObservableCollection<TimePeriod> TimePeriods { get; set; }
    public ObservableCollection<RecentTask> RecentTasks { get; set; }.....

Кажется, что это какая-то проблема с уведомлением или синхронизацией, но я изо всех сил пытаюсь ее отследить.

Я установил контекст данных страницы, отображающей данные, следующим образом в Page_Loadedevent:

this.DataContext = Database.Instance;

xaml для одного из списков выглядит следующим образом:

<ListBox x:Name="AllTasksListBox" 
                     Margin="0,0,-12,0"
                     ItemsSource="{Binding Tasks}"
                     DisplayMemberPath="Name">
</ListBox>

Одно из событий, которое загружает данные из службы WCF в наблюдаемые коллекции, выглядит следующим образом:

void OpenReadCompletedTasks(object sender, OpenReadCompletedEventArgs e)
    {
        DataContractSerializer ser = null;

        try
        {
            ser = new DataContractSerializer(typeof(ObservableCollection<Task>));
            Database.Instance.Tasks = ser.ReadObject(e.Result) as ObservableCollection<Task>;
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

Это событие находится в классе Database.

Возможно ли, что проблема представляет собой какую-то проблему с многопоточностью, связанную с обработчиком событий OpenReadCompleted?

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

Есть мысли о том, как отследить это или что я делаю неправильно?

Ответы [ 2 ]

2 голосов
/ 10 марта 2011

Я думаю, проблема в том, как вы обновляете ObservableCollection

ObservableCollection будет предоставлять уведомления при добавлении / удалении / изменении отдельных записей.

Однако, когда вы заменяете всю коллекцию, вам нужно уведомить слушателей о том, что вся коллекция изменилась - в противном случае они останутся привязанными к старым коллекциям - например, реализовать как:

private ObservableCollection<Task> _tasks;
public ObservableCollection<Task> Tasks
{
   get
   {
       return _tasks;
   }
   set
   {
      _tasks = value;
      if (PropertyChanged != null)
          PropertyChanged(this, new PropertyChangedEventArgs("Tasks");
   }
} 
1 голос
/ 10 марта 2011

Почему вы сбрасываете в хранилище каждые 10 секунд?Вам просто нужна последовательность событий

  1. Если полученные данные в iso store goto end

  2. Настройка обратного вызова для списка загрузки 1 async

  3. вызов списка загрузки 1 асинхронный

  4. обратный вызов для списка загрузки 1 асинхронный - сохранение данных в iso store

повторшаги с 1 по 3 для каждого списка

конец.Загрузка списков из магазина iso

...