Эквивалент ItemAppearing в xamarin UWP

У меня есть привязка ListView к списку BitmapImage. Я хочу, чтобы Индекс текущего изображения был в фокусе, когда я прокручиваю этот список. Но я заметил, что свойства ItemAppearing нет в UWP, но оно есть в Xamarin Forms. Как я могу получить индекс текущего элемента в поле зрения?

Спасибо!

<ScrollViewer Grid.Row="0" ZoomMode="{x:Bind ZoomMode, Mode=OneWay}" HorizontalScrollMode="Enabled"                       HorizontalScrollBarVisibility="Auto">
    <ListView HorizontalAlignment="Center" ItemsSource="{x:Bind ImagePages, Mode=OneWay}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate x:DataType="BitmapImage">
                        <Image Source="{x:Bind }" Margin="0 2" />
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ListView>
        </ScrollViewer>

person XamDev    schedule 21.08.2017    source источник
comment
Не существует такой вещи, как Xamarin.UWP — приложение UWP — это просто приложение UWP.   -  person Jason    schedule 22.08.2017
comment
@Jason, имеется в виду приложение UWP, созданное из проекта Xamarin Forms. Это действительно возможно.   -  person AQuirky    schedule 24.08.2017


Ответы (1)


Во-первых, свойство ItemAppearing — это не то поведение, которое вам нужно. Событие ItemAppearing для ListView в Xamarin Forms запускается при отображении элемента списка. Для небольшого списка это событие будет запущено сразу для всех элементов. Эквивалентным событием в UWP является событие ListView.ChoosingItemContainer, которое, как и событие ItemAppearing, запускается для всех элементов в списке, если ListView не виртуализирован. Даже для большого виртуализированного списка он запускается для нескольких страниц элементов.

Это не то, что вы хотите. Насколько я понимаю, вы хотите знать изображение, которое видно вверху списка при прокрутке списка. Вот как это сделать.

Прежде всего. Избавьтесь от ScrollViewer. Внутри ListView уже есть ScrollViewer.

        <ListView x:Name="listViewImage" Grid.Row="0" HorizontalAlignment="Center" ItemsSource="{x:Bind ImagePages, Mode=OneWay}"
                   Loaded="listViewImage_Loaded">
            <ItemsControl.ItemTemplate>
                <DataTemplate x:DataType="BitmapImage">
                    <Image Source="{x:Bind }" Margin="0 2"/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ListView>

Обратите внимание, что я назвал ListView и добавил обработчик событий Loaded. В этом обработчике найдите ScrollViewer внутри ListView и прикрепите обработчик к событию ViewChanged.

    private void listViewImage_Loaded(object sender, RoutedEventArgs e)
    {
        Border b = VisualTreeHelper.GetChild(listViewImage, 0) as Border;
        ScrollViewer sv = b.Child as ScrollViewer;
        sv.ViewChanged += Sv_ViewChanged;
    }

В обработчике изменения представления найдите первый видимый ListViewItem и получите его индекс в коллекции. Это то, что вы хотите.

    private void Sv_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
    {
        ScrollViewer sv = sender as ScrollViewer;
        GeneralTransform gt = sv.TransformToVisual(this);
        Point p = gt.TransformPoint(new Point(0, 0));
        List<UIElement> list = new List<UIElement>(VisualTreeHelper.FindElementsInHostCoordinates(p, sv));
        ListViewItem item = list.OfType<ListViewItem>().FirstOrDefault();
        if(item != null)
        {
            int index = listViewImage.IndexFromContainer(item);
            Debug.WriteLine("Visible item at top of list is " + index);
        }
    }
person AQuirky    schedule 24.08.2017
comment
Спасибо за решение. Я попробую это. - person XamDev; 26.08.2017