Click here to Skip to main content
15,903,203 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Goal: To use OnRender to draw into ImageBrush by RenderTargetBitmap.
Problem: It doesn't draw.
Question: How to do it using OnRender without adding Control as child to Canvas.Children?
Notes:
1. It works, if to add Control as child to Canvas.Children. You can do by turning the comment off.
2. It works even without calling InvalidateVisual, if to use VisualCollection.
3. The goal is to do it using OnRender without adding Control as child to Canvas.Children.
Code:
C#
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        Canvas canvas = new Canvas();
        this.Content = canvas;
        canvas.Background = Brushes.Black;

        MyImage myimage = new MyImage();
        myimage.InvalidateMeasure();
        myimage.InvalidateArrange();
        myimage.InvalidateVisual();
        myimage.UpdateLayout();

        //canvas.Children.Add(myimage); // Works

        canvas.MouseDown += delegate
        {
            RenderTargetBitmap target = new RenderTargetBitmap(100, 100, 96, 96, PixelFormats.Default);
            target.Render(myimage);

            ImageBrush brush = new ImageBrush();
            brush.ImageSource = target;
            canvas.Background = brush;
        };

    }
}

class MyImage : Image
{
    protected override void OnRender(DrawingContext dc)
    {
        base.OnRender(dc);

        dc.DrawRectangle(Brushes.Red, null, new Rect(0, 0, 100, 100));
    }
}
Posted

1 solution

OnRender doesn't get called until a visual gets added into a visual tree.
If the goal is to get the image without adding the visual to the visual tree, you can use VisualCollection/DrawingVisual.

Code:
C#
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        Canvas canvas = new Canvas();
        this.Content = canvas;
        canvas.Background = Brushes.Black;

        MyImage myimage = new MyImage();
        myimage.InvalidateMeasure();
        myimage.InvalidateArrange();
        myimage.InvalidateVisual();
        myimage.UpdateLayout();

        //canvas.Children.Add(myimage); // You no longer need it

        canvas.MouseDown += delegate
        {
            RenderTargetBitmap target = new RenderTargetBitmap(100, 100, 96, 96, PixelFormats.Default);
            target.Render(myimage);

            ImageBrush brush = new ImageBrush();
            brush.ImageSource = target;
            canvas.Background = brush;
        };

    }
}

class MyImage : Image
{
    public MyImage()
    {
        visuals = new VisualCollection(this);
        visual = new DrawingVisual();
        visuals.Add(visual);

        Draw();
    }

    private void Draw()
    {
        using (DrawingContext dc = visual.RenderOpen())
            dc.DrawRectangle(Brushes.Red, null, new Rect(0, 0, 100, 100));
    }

    VisualCollection visuals;
    DrawingVisual visual;

    protected override Visual GetVisualChild(int index)
    {
        return visuals[index];
    }
    protected override int VisualChildrenCount
    {
        get { return visuals.Count; }
    }
}


Source:
https://social.msdn.microsoft.com/Forums/en-US/81ccabb8-4f38-46ba-827c-d0a2b66372de/wpf-can-onrender-render-if-a-control-is-not-added-as-child[^]
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900