Попытка визуализировать ListViewItem для растрового изображения внутри UserControl не работает

Я работаю над универсальным приложением, в котором я пытаюсь сгенерировать растровое изображение из выделенного фрагмента, чтобы я мог показать необычную анимацию выбранного объекта, перемещающегося изнутри SettingsFlyout, в новое место на экране, в то время как SettingsFlyout с просмотр списка переведен на "детализацию".

Я видел этот код, предложенный в другом месте, но, похоже, он не работает. Я получаю System.ArgumentException, за которым следует "Значение не попадает в ожидаемый диапазон". при вызове RenderAsync. Любая идея, почему это происходит? пошаговое выполнение кода показывает, что ListViewItem правильно найден, но рендеринг не работает. Я видел еще одно упоминание ItemContainerGenerator, но он генерировал исключение NullReferenceException.

private async void AnimateSelection(object sender, SelectionChangedEventArgs e)
{   
    var container =
        (sender as ListView).ContainerFromItem((sender as ListView).SelectedItem);

    var bitmap = new RenderTargetBitmap();
    await bitmap.RenderAsync(container as FrameworkElement);

    // go on to animate this by copying it to another grid
}

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

РЕДАКТИРОВАТЬ: По предложению другого разработчика, я попытался отрисовать панель стека pageRoot и другой TextBox с той же страницы, и это тоже не удалось. Я думаю, что проблема заключается в самом рендере - могу ли я заменить этот код чем-то другим?

var bitmap = new RenderTargetBitmap();
await bitmap.RenderAsync(container as FrameworkElement);

РЕДАКТИРОВАТЬ: dev предложил диспетчер может быть проблемой, оказывается, диспетчер обрабатывается по-разному в универсальных приложениях, поэтому я попытался использовать его через это - без изменений

var container =
            (sender as ListView).ContainerFromItem((sender as ListView).SelectedItem);

        await this.dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
        {
            var bitmap = new RenderTargetBitmap();
            await bitmap.RenderAsync(container as FrameworkElement);

            var vm = this.DataContext as PersonViewModel;
            vm.TransitionImageSource = bitmap;
        });

2 ответа

Я решил эту проблему, изменив SettingsFlyout на UserControl и имитировав эффекты SettingsFlyout, которые нарушают стандартное поведение в процессе. Похоже, что это не совсем ответ, но, безусловно, проблема с SettingsFlyout и требует тщательного изучения.

Спасибо Мэтт

Без воспроизведения вашего кода я не могу сказать, что не так, но в вашем подходе нет ничего принципиально неправильного.

Следующие работы:

  • Создайте новое пустое универсальное приложение.
  • Разделить главную страницу между обоими целями
  • Добавьте этот XAML:

    <StackPanel>
        <TextBlock>Some text</TextBlock>
        <Button Click="ChangeColor_OnClick">change color</Button>
        <ListBox x:Name="ListBox">
            <ListBoxItem>item 1</ListBoxItem>
            <ListBoxItem>item 2</ListBoxItem>
            <ListBoxItem>item 3</ListBoxItem>
        </ListBox>
    
        <Button Click="TakeScreenshot_OnClick">take screenshot</Button>
        <Button Click="TakeScreenshotOfSelected_OnClick">take screenshot of just selected item</Button>
        <Image x:Name="DisplayedScreenshot" Height="200" />
    </StackPanel>
    
  • Добавьте этот код позади:

    private void ChangeColor_OnClick(object sender, RoutedEventArgs e)
    {
        var rand = new Random();
    
        this.Background = new SolidColorBrush(new Color { A = 255, R = (byte)rand.Next(1, 255), G = (byte)rand.Next(1, 255), B = (byte)rand.Next(1, 255) });
    }
    
    private async void TakeScreenshot_OnClick(object sender, RoutedEventArgs e)
    {
        RenderTargetBitmap rtb = new RenderTargetBitmap();
    
        await rtb.RenderAsync(this as FrameworkElement);
    
        this.DisplayedScreenshot.Source = rtb;
    }
    
    private async void TakeScreenshotOfSelected_OnClick(object sender, RoutedEventArgs e)
    {
        RenderTargetBitmap rtb = new RenderTargetBitmap();
    
        await rtb.RenderAsync(this.ListBox.SelectedItem as UIElement);
    
        this.DisplayedScreenshot.Source = rtb;
    }
    
Другие вопросы по тегам