Я нашел новое скручивание на "Визуальным к RenderTargetBitmap" вопрос!
Я представляю предварительные просмотры материала WPF для разработчика. Это означает, что я должен взять визуальное WPF и представить его к битовому массиву без этого визуального когда-либо быть отображенным. Заставил миленький метод делать, ему нравится видеть его здесь, он идет
private static BitmapSource CreateBitmapSource(FrameworkElement visual)
{
Border b = new Border { Width = visual.Width, Height = visual.Height };
b.BorderBrush = Brushes.Black;
b.BorderThickness = new Thickness(1);
b.Background = Brushes.White;
b.Child = visual;
b.Measure(new Size(b.Width, b.Height));
b.Arrange(new Rect(b.DesiredSize));
RenderTargetBitmap rtb = new RenderTargetBitmap(
(int)b.ActualWidth,
(int)b.ActualHeight,
96,
96,
PixelFormats.Pbgra32);
// intermediate step here to ensure any VisualBrushes are rendered properly
DrawingVisual dv = new DrawingVisual();
using (var dc = dv.RenderOpen())
{
var vb = new VisualBrush(b);
dc.DrawRectangle(vb, null, new Rect(new Point(), b.DesiredSize));
}
rtb.Render(dv);
return rtb;
}
Хорошо работает, за исключением одной leeetle вещи..., если мой FrameworkElement имеет VisualBrush, та кисть не заканчивается в финале, представленном битовым массивом. Что-то вроде этого:
<UserControl.Resources>
<VisualBrush
x:Key="LOLgo">
<VisualBrush.Visual>
<!-- blah blah -->
<Grid
Background="{StaticResource LOLgo}">
<!-- yadda yadda -->
Все остальное представляет к битовому массиву, но который просто не покажет VisualBrush. Очевидные решения Google были предприняты и перестали работать. Даже те, которые конкретно упоминают VisualBrushes, отсутствующий в битовых массивах RTB'd.
У меня есть подлое подозрение, это могло бы быть вызвано тем, что это - Ресурс, и что ленивый ресурс не встраивается. Таким образом, возможная фиксация была бы к, так или иначе (???), разрешение силы всех статических ссылок ресурса перед рендерингом. Но у меня нет абсолютно никакой идеи, как сделать это.
У кого-либо есть фиксация для этого?
У вас две проблемы:
Непосредственной причиной вашей проблемы является неспособность промыть очередь диспетчера, поскольку VisualBrush использует ее, но вы, вероятно, столкнетесь с проблемой PresentationSource в ближайшее время, поэтому я бы исправил обе эти проблемы.
Вот как я это делаю:
// Create the container
var container = new Border
{
Child = contentVisual,
Background = Brushes.White,
BorderBrush = Brushes.Black,
BorderThickness = new Thickness(1),
};
// Measure and arrange the container
container.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
container.Arrange(new Rect(container.DesiredSize));
// Temporarily add a PresentationSource if none exists
using(var temporaryPresentationSource = new HwndSource(new HwndSourceParameters()) { RootVisual = (VisualTreeHelper.GetParent(container)==null ? container : null) })
{
// Flush the dispatcher queue
Dispatcher.Invoke(DispatcherPriority.SystemIdle, new Action(() => { }));
// Render to bitmap
var rtb = new RenderTargetBitmap((int)b.ActualWidth, (int)b.ActualHeight, 96, 96, PixelFormats.Pbgra32);
rtb.Render(container);
return rtb;
}
К вашему сведению, поиск StaticResource никогда и ни при каких обстоятельствах не откладывается: Он обрабатывается в момент загрузки XAML и немедленно заменяется значением, полученным из ResourceDictionary. единственный способ, которым StaticResource может возможно быть связан, это если он подбирает неправильный ресурс, потому что два ресурса имеют одинаковый ключ. Я просто подумал, что должен объяснить это - это не имеет никакого отношения к вашей реальной проблеме.
Чтобы встроить это, вы можете просто сделать что-то вроде этого:
<Grid>
<Grid.Background>
<VisualBrush>
<VisualBrush.Visual>
<!-- blah blah -->
</VisualBrush.Visual>
</VisualBrush>
</Grid.Background>
</Grid>
Если это не сработает, я предполагаю, что это должно быть что-то особенное с Visual
, который вы используете (и для лучшей диагностики потребуется дополнительный код).