Попытка визуализировать 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; }