2016-07-15 24 views
2

Ich versuche derzeit, einseitige Datenbindung in einer Listview zu machen, so dass beim Starten meiner Anwendung eine Methode geöffnet wird, nach eingehenden Paketen gesucht wird, eine Liste gefüllt wird und binden Sie diese Liste an eine Listenansicht, die dann jedes Paket mit seinen Informationen anzeigt. Aus irgendeinem Grund füllt das ListView jedoch nicht wirklich auf. Ich habe debugged, und der gesamte Backend-Code funktioniert einwandfrei - die lokalen Variablen, wie die Paketmodelle und die Liste der Modelle, füllen sich perfekt. Das ListView enthält jedoch keinen Inhalt, und wenn ich auf die lokale Variable schaue, wird jedes Inhaltselement als vollständig leer angezeigt.UWP - Bindende Daten funktionieren nicht - Leere ListView

Hier ist mein Code:

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"/>

Dies ist offensichtlich nicht der gesamte Code in jedem Dokument, aber es sind die wichtigen Teile. Ich frage mich, was ich falsch mache? Die listView verweigert das Auffüllen.

+1

Versuchen Sie, 'shipments' ein [ObservableCollection] (https://msdn.microsoft.com/en-us /library/ms668604(v=vs.110).aspx) –

+0

Hey, danke! Das hat perfekt funktioniert. Wenn es Ihnen nichts ausmacht, können Sie mir erklären, warum das Wechseln von List <> zu ObservableCollection <> funktioniert? – msiegs

+0

Ja, Sie brauchen ObservableCollection. Sehen Sie den Unterschied hier. http://stackoverflow.com/a/4197068/4585476 – AVK

Antwort

2

Wie Sie anhand der obigen Kommentare bemerkt haben, müssen Sie ObservableCollection<T> verwenden, um dies zu erreichen. Der Grund ist jedoch ein wenig unklar.

Wenn Sie die DataContext -Eigenschaft Ihrer Ansicht festlegen, wird die Ansicht an die gebundenen Eigenschaften gebunden und bindet sie einmal ... Wenn also bei der Initialisierung der DataContext nichts in Ihrer Sammlung ist, werden Sie nichts bekommen in der Ansicht.

Um dies zu beheben, implementieren wir diese Schnittstelle INotifyPropertyChanged genannt. Wir verwenden dies für ViewModels und Models.

Mit dieser Schnittstelle erhalten Sie einen Ereignishandler, mit dem Sie die Benutzeroberfläche aktualisieren können. Sie senden den Namen Ihrer Eigenschaft in dem Ereignis und wenn die UI ihn behandelt, erfasst sie den Eigenschaftsnamen, überprüft, ob etwas an diese Eigenschaft gebunden ist, und wenn dies der Fall ist, geht sie aus und aktualisiert sie mit dem neuen Wert.

Hier kommt ObservableCollection ins Spiel. Ihre ObservableCollection wird die für Sie aktualisieren, so dass Sie Ihre Eigenschaft nicht ändern Ereignis aufrufen müssen.

Wie Sie aus dem MSDN Documentation on ObservableCollection<T> sehen können, es Implementiert INotifyPropertyChanged

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

Hatten Sie eine Eigenschaft geänderte Ereignis aufgerufen, nachdem die Elemente Ihrer Liste hinzugefügt haben, würden Sie nicht einen ObservableCollection entweder benötigen.Hier

ist ein Article on How DataBinding works

Hier ist die MSDN Documentation on INotifyPropertyChanged

Hier ist ein example on how to implement INotifyPropertyChanged