Frage

Ich habe eine neue Variante der „Visual in Rendertargetbitmap“ Frage gefunden!

Ich bin Rendering-Vorschau von WPF Sachen für einen Designer. Das heißt ich brauche eine WPF visuelle zu nehmen und machen es zu einem Bitmap ohne dass visuelle immer angezeigt wird. Haben Sie eine nette kleine Methode, es zu tun mag es hier zu sehen, es geht

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;
}

funktioniert gut, mit Ausnahme einer leeetle Sache ... wenn mein Framework eine VisualBrush hat, ist, dass Bürste nicht in der endgültigen gerenderte Bitmap enden. So etwas wie folgt aus:

<UserControl.Resources>
    <VisualBrush
        x:Key="LOLgo">
        <VisualBrush.Visual>
            <!-- blah blah -->
<Grid 
    Background="{StaticResource LOLgo}">
<!-- yadda yadda -->

Alles macht sonst auf die Bitmap, aber das VisualBrush einfach nicht zeigen. Die offensichtlichen google Lösungen wurden versucht und sind gescheitert. Selbst diejenigen, die speziell VisualBrushes fehlt RTB'd Bitmaps erwähnen.

Ich habe einen hinterhältigen Verdacht könnte dies durch die Tatsache verursacht wird, dass es eine Ressource, und dass faule Ressource nicht inlined wird. So eine mögliche Lösung sein würde, irgendwie (???), Kraft Auflösung aller statischen Ressourcenreferenzen vor Rendering. Aber ich habe absolut keine Ahnung, wie das zu tun.

Wer für diese ein Update haben?

War es hilfreich?

Lösung

Sie haben zwei Probleme:

  1. Sie haben keinen PresentationSource auf Ihrer visuellen so Loaded Ereignisse gesetzt wird nicht ausgelöst.
  2. Sie haben die Dispatcher-Warteschlange nicht spülen. Ohne die Dispatcher-Warteschlange Spülung, jede Funktionalität, dass Anwendungen Dispatcher Rückrufe werden nicht funktionieren.

Die unmittelbare Ursache des Problems Ausfall ist die Dispatcher-Warteschlange zu leeren, da VisualBrush es verwendet, aber Sie werden wahrscheinlich in das PresentationSource Problem laufen, bevor lang, damit ich diese beide beheben würde.

Hier ist, wie ich es tun:

// 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;
}

FYI, ist Static Lookup unter keinen Umständen verzögert: Es verarbeitet wird, um den Moment der XAML geladen und sofort mit dem Wert aus dem Resource abgerufen ersetzt. Die nur Weg Static könnte möglicherweise zusammenzuhängen, wenn es die falsche Ressource aufgenommen, weil zwei Ressourcen den gleichen Schlüssel hatte. Ich dachte nur, soll ich das erklären - es hat nichts mit dem eigentlichen Problem zu tun

.

Andere Tipps

Nun, es inline, könnte man nur so etwas tun:

<Grid>
    <Grid.Background>
        <VisualBrush>
            <VisualBrush.Visual>
                <!-- blah blah -->
            </VisualBrush.Visual>
        </VisualBrush>
    </Grid.Background>
</Grid>

Wenn das nicht funktioniert, meine Vermutung wäre, dass es etwas Bestimmtes mit der Visual Instanz sein muss, die Sie verwenden (und das wird weiter Code zu einem besseren Diagnose erforderlich ist).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top