我在UWP应用程序中遇到了一个问题,我正在研究......
GridView中的项目正确加载,但是不在视图范围内(在页面外且不可见)的项目没有分配DataContext,并且在分配DataContext时不会触发任何事件。各种绑定确实有效,因为绑定的TextBlock会更新,但正常的事件工作流和Loaded事件都会变得奇怪。
<GridView Grid.Row="1" Name="SearchGrid" ItemsSource="{Binding SearchItems}" ItemClick="SearchGrid_ItemClick">
<GridView.ItemTemplate>
<DataTemplate>
<local:RsrItemGridViewItem />
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
网格都正确显示,除了能够正确延迟加载某些项目,因为DataContext在加载时没有设置(并且在更新上下文时不会触发DataContextChanged事件)
当控件变得可见时,有没有人知道如何获得通知?这似乎是一个通知错误,或者有一些我错过的具有约束力的东西。
谢谢!
答案 0 :(得分:0)
当控件变得可见时,有没有人知道如何获得通知?
当RsrItemGridViewItem
变得可见时,您无法在此处使用FrameworkElement.Loaded event获取通知,此事件在构建FrameworkElement并添加到对象树时发生,并且已准备好进行交互
GirdView
控件实现UI virtualization以获得更好的UI性能,如果您的GridView
绑定到多个项目的集合,它可能只下载项目1-50,当用户滚动到附近时在列表的末尾,然后下载项目51-100,依此类推。但是,例如,现在只显示了20个项目,但它可能已经装载了45个项目,此时无法看到25个项目。
如果您更改ItemsPanel
GridView
的默认ItemsWrapGrid
,例如VariableSizedWrapGrid
,则GridView
将失去虚拟化,并且所有项目都将被加载与此同时,甚至大多数人都无法在一瞬间看到。
对于你的问题,我认为你可以尝试的是计算ScrollViewer
的VerticalOffset与你的GridView
的身高以及项目的数量显示,然后您就可以知道此时显示的是哪些项目。
例如:
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 });
}
}
由于GridView
控件的布局适应应用程序的大小,当前显示的计数是动态的,您可以尝试其他基于高度的属性(例如每个项目的高度) )和ScrollViewer
的VerticalOffset来计算,没有现成的方法来完成你的工作,计算起来有点复杂,但我认为目前还没有更好的解决方案。
答案 1 :(得分:-1)
用这个做了一些测试之后,我发现的工作(虽然它不是很干净,我相信有一个绑定错误)是将自定义控件添加到GridView,然后在网格视图中添加一个{ {1}}我希望收到有关更新的通知。
DataContext={Binding}
主控件不会收到DataContext更改的通知,但会通知子元素。