2016-04-23 9 views
0

Ich habe ein Problem mit einem Gridview in einer UWP-Anwendung, die ich gerade arbeite ...Windows-10 UWP - Gridview-Positionen ohne Datacontext, wenn nicht sichtbar

Angebote im Gridview Last richtig, jedoch Elemente, die Außerhalb der Ansicht (außerhalb der Seite und nicht sichtbar) ist kein DataContext zugewiesen, und bei Zuweisung des DataContext wird kein Ereignis ausgelöst. Verschiedene Bindungen funktionieren wie TextBlocks, die gebunden aktualisiert werden, aber der normale Ereignisworkflow und geladene Ereignisse werden alle merkwürdig.

Null DataContext in Loaded Event

<GridView Grid.Row="1" Name="SearchGrid" ItemsSource="{Binding SearchItems}" ItemClick="SearchGrid_ItemClick"> 
     <GridView.ItemTemplate> 
      <DataTemplate> 
       <local:RsrItemGridViewItem /> 
      </DataTemplate> 
     </GridView.ItemTemplate> 
    </GridView> 

Die Gitter zeigen alle richtig, mit der Ausnahme, für richtig in der Lage Last einige Elemente zu verzögern, da die Datacontext nicht zum Zeitpunkt der Last (und ein Datacontextchanged Ereignis gesetzt wird, wird nicht gefeuert wenn der Kontext aktualisiert wird).

Hat jemand irgendwelche Ideen, wie man benachrichtigt wird, wenn die Kontrolle sichtbar wird? Das scheint ein Benachrichtigungsfehler zu sein, oder es gibt verbindliche Dinge, die mir fehlen.

Vielen Dank!

Antwort

0

Hat jemand irgendwelche Ideen wie man benachrichtigt wird, wenn die Kontrolle sichtbar wird?

Sie nicht FrameworkElement.Loaded event hier verwenden können, erhalten benachrichtigt, wenn Ihr RsrItemGridViewItem sichtbar wird, tritt dieses Ereignis, wenn ein Framework konstruiert wurde und zu dem Objektbaum, und ist für die Interaktion bereit.

GirdView Steuerung implementiert UI virtualization für eine bessere UI Leistung, wenn Ihr GridView auf eine Sammlung von vielen Elementen gebunden ist, kann es nur Elemente 1-50, herunterladen, wenn der Benutzer einen Bildlauf in der Nähe des Ende der Liste, dann Artikel 51-100 werden heruntergeladen und so weiter. Aber zum Beispiel werden jetzt nur noch 20 Gegenstände gezeigt, aber es hat vielleicht 45 Gegenstände geladen, 25 Gegenstände konnten in diesem Moment nicht gesehen werden.

Wenn Sie den Standard ItemsPanel von GridView ändern, die ItemsWrapGrid zu beispielsweise ist VariableSizedWrapGrid wird GridView Virtualisierung verlieren, und alle Einzelteile zur gleichen Zeit auch die meisten von ihnen geladen werden können nicht in einem Moment zu sehen.

Für Sie Problem, ich denke, was Sie versuchen können, ist die Berechnung der ScrollViewer VerticalOffset mit Ihrer GridView Höhe und die Anzahl der Elemente werden angezeigt, und dann können Sie wissen, welche Elemente in diesem Moment angezeigt werden.

Zum Beispiel hier:

private ObservableCollection<MyList> list = new ObservableCollection<MyList>(); 

public MainPage() 
{ 
    this.InitializeComponent(); 
    this.Loaded += MainPage_Loaded; 
} 

private double viewheight; 

private void MainPage_Loaded(object sender, RoutedEventArgs e) 
{ 
    var scrollViewer = FindChildOfType<ScrollViewer>(gridView); 
    scrollViewer.ViewChanged += ScrollViewer_ViewChanged; 
    viewheight = gridView.ActualHeight; 
} 

private void ScrollViewer_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e) 
{ 
    var scrollViewer = sender as ScrollViewer; 
    var Y = scrollViewer.VerticalOffset; 
    //calculate here to get the displayed items. 
} 

public static T FindChildOfType<T>(DependencyObject root) where T : class 
{ 
    var queue = new Queue<DependencyObject>(); 
    queue.Enqueue(root); 
    while (queue.Count > 0) 
    { 
     DependencyObject current = queue.Dequeue(); 
     for (int i = 0; i < VisualTreeHelper.GetChildrenCount(current); i++) 
     { 
      var child = VisualTreeHelper.GetChild(current, i); 
      var typedChild = child as T; 
      if (typedChild != null) 
      { 
       return typedChild; 
      } 
      queue.Enqueue(child); 
     } 
    } 
    return null; 
} 

protected override void OnNavigatedTo(NavigationEventArgs e) 
{ 
    list.Clear(); 
    for (int i = 0; i < 200; i++) 
    { 
     list.Add(new MyList { text = "Item " + i }); 
    } 
} 

Seit GridView Kontrolle des Layout der App-Größe adaptiv ist, ist die aktuell angezeigte Zählung dynamisch, können Sie andere Höhe basierend Eigenschaften versuchen (zB jedes Höhe des Elements) und die ScrollViewer 's VerticalOffset zu berechnen, gibt es keine fertige Methode, um Ihre Arbeit zu erledigen, es ist ein wenig komplex zu berechnen, aber ich denke, es gibt keine bessere Lösung für den Moment.

+0

Nach einigen Tests mit diesem, was ich herausgefunden habe funktioniert (obwohl es nicht sehr sauber ist, und ich glaube, es gibt einen Fehler mit Bindings) war das benutzerdefinierte Steuerelement zum GridView hinzufügen, dann in der Rasteransicht ein 'hinzufügen DataContext = {Binding} 'zum Image Ich wollte über ein Update informiert werden. '' Das Hauptsteuerelement wird nicht über eine DataContext-Änderung benachrichtigt, aber die untergeordneten Elemente werden benachrichtigt. – Josh

+0

@Josh, das Problem ist, selbst wenn es einen DataContext hat, bedeutet das nicht, dass das Element in diesem Moment gesehen werden kann. –

+0

Yeah ... Aber ich denke, das eigentliche Problem ist, dass wenn die Kinder DataContextChanged Benachrichtigungen erhalten, der Elternteil, der an denselben Kontext gebunden ist, diese Benachrichtigungen nicht erhält. In meinem obigen Beispiel erhalten die untergeordneten Elemente von RsrItemGridViewItem eine DataContextChanged-Benachrichtigung, aber das Haupt-RsrItemGridViewItem empfängt die Benachrichtigung nicht. – Josh

-1

Nach einigen Tests mit diesem, was ich herausgefunden habe funktioniert (obwohl es nicht sehr sauber ist, und ich glaube, es gibt einen Fehler mit Bindungen) war das benutzerdefinierte Steuerelement zum GridView hinzufügen, dann in der Rasteransicht ein Hinzufügen DataContext={Binding} zu dem Image Ich möchte über ein Update informiert werden.

Das Hauptsteuerelement wird nicht über eine DataContext-Änderung benachrichtigt, aber die untergeordneten Elemente werden benachrichtigt.