2016-07-15 2 views
2

В настоящее время я пытаюсь выполнить одностороннюю привязку данных внутри списка, так что, когда мое приложение запустится, оно откроет метод, проверит наличие входящих пакетов, заполнит список , и привяжите этот список к списку, который затем покажет каждый пакет с его информацией. По какой-то причине, однако, ListView фактически не заполняется. Я отлаживал, и весь внутренний код работает нормально - локальные переменные, такие как модели пакетов и список моделей, все заполняются отлично. Однако ListView не содержит никакого содержимого, и когда я смотрю на локальную переменную, он показывает каждую часть контента как полностью пустую.UWP - данные привязки не работают - Empty ListView

Вот мой код:

DeliveryPlannerData.cs

public static List<ShipmentModel> shipments { get; set; } = new List<ShipmentModel>(); 

    public async static void populateDeliveryPlanner(string startDate, string endDate) 
    { 
     var deliveryPlanner = await DeliveryPlanner.DeliveryPlannerRequest(startDate, endDate); 
     //if (panel.Children.Count > 0) 
     // panel.Children.Clear(); 

     try 
     { 
      List<string> trackingNumber = deliveryPlanner["trackingNumber"]; 
      List<string> lastScanDate = deliveryPlanner["lastScanDate"]; 
      List<string> scheduledDelivery = deliveryPlanner["scheduledDelivery"]; 
      List<string> status = deliveryPlanner["status"]; 


      for (int i = 0; i < trackingNumber.Count; i++) 
      { 
       shipments.Add(new ShipmentModel(
        trackingNumber[i], lastScanDate[i], scheduledDelivery[i], getStatus(status[i]) 
       )); 
       var v = shipments; 
      } 

     } 
     catch (NullReferenceException e) 
     { 
      var error = e; 
     } 
    } // populateDeliveryPlanner 

ShipmentModel.cs

public class ShipmentModel : INotifyPropertyChanged 
{ 
    public string TrackingNumber; 
    public string LastScanDate; 
    public string ScheduledDelivery; 
    public string Status; 
    public event PropertyChangedEventHandler PropertyChanged = delegate { }; 

    public ShipmentModel(string trackingNumber, string lastScanDate, string scheduledDelivery, string status) 
    { 
     TrackingNumber = trackingNumber; 
     LastScanDate = lastScanDate; 
     ScheduledDelivery = scheduledDelivery; 
     Status = status; 
    } 

    public string trackingNumber 
    { 
     get { return this.TrackingNumber; } 
     set 
     { 
      this.TrackingNumber = value; 
      this.OnPropertyChanged(); 
     } 
    } 

DeliveryPlanner.xaml

<ListView x:Name="listView" ItemTemplate="{StaticResource ShipmentModelTemplate1}" ItemsSource="{Binding shipments, Mode=OneWay}" Margin="19,12,19,0" Grid.Row="1" VerticalAlignment="Bottom"/>

Это, очевидно, не весь код в каждом документе, но это важные детали. Мне интересно, что я делаю неправильно? ListView отказывается заполнять.

+1

попробовать сделать 'shipments' [ObservableCollection] (https://msdn.microsoft.com/en-us /library/ms668604(v=vs.110).aspx) –

+0

Эй, спасибо! Это сработало отлично. Если вы не возражаете, не могли бы вы объяснить, почему переход из списка <> в ObservableCollection <> сделал эту работу? – msiegs

+0

Да, вам нужно ObservableCollection. См. Разницу здесь. http://stackoverflow.com/a/4197068/4585476 – AVK

ответ

2

Как вы заметили, основываясь на приведенных выше замечаниях, вам необходимо использовать ObservableCollection<T>, чтобы заставить это работать. Причина, однако, немного неясна.

Когда вы устанавливаете свойство View DataContext, представление переходит к связанным свойствам и связывает их один раз ... Так что если при инициализации DataContext в вашей коллекции ничего нет, вы ничего не получите в представлении.

Чтобы исправить это, мы реализуем этот интерфейс под названием INotifyPropertyChanged. Мы используем это в ViewModels и Models.

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

Здесь вы найдете ObservableCollection. Ваш ObservableCollection обновит для вас UI, так что вам не нужно вызывать событие измененного свойства.

Как вы можете видеть из MSDN Documentation on ObservableCollection<T>, это Реализует INotifyPropertyChanged

[SerializableAttribute] 
public class ObservableCollection<T> : Collection<T>, INotifyCollectionChanged, 
    INotifyPropertyChanged 

Если бы вы назвали свойство измененное событие после добавления элементов в список, вам не нужно будет в ObservableCollection либо.

Вот Article on How DataBinding works

Вот MSDN Documentation on INotifyPropertyChanged

Вот example on how to implement INotifyPropertyChanged

Смежные вопросы