WPF:如何通过OnRender绘制的ImageBrush填充? [英] WPF: How to fill by ImageBrush drawn by OnRender?

查看:205
本文介绍了WPF:如何通过OnRender绘制的ImageBrush填充?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目标:

1.创建画布。

2.创建MyImage:图像。

3.通过OnRender绘制MyImage。

4.将MyImage源设置为ImageBrush源。

5.将ImageBrush设置为Canvas.Background。



问题:画布被绘制为空而不是OnRender应该绘制的。

问题:如何使它绘制在OnRender中绘制的内容?

注意:

1.如果要通过链接添加图像,它会进入画笔。

2.如果要将MyImage作为子画面添加到Canvas.Children,它会使用画布,但不会画入画笔。您可以通过在代码中关闭注释来实现。



代码1(使用OnRender):

Goal:
1. Create Canvas.
2. Create MyImage : Image.
3. Draw MyImage by OnRender.
4. Set MyImage source to ImageBrush source.
5. Set ImageBrush to Canvas.Background.

Problem: The canvas gets drawn empty instead of what OnRender should draw.
Question: How to make it draw what is set to draw inside OnRender?
Notes:
1. It draws into Brush, if to add an image via a link.
2. It draws on Canvas, but not into Brush, if to add MyImage as child to Canvas.Children. You can do it by turning a comment off in the code.

Code 1 (using OnRender):

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

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

        MyImage myimage = new MyImage();
        myimage.InvalidateVisual();

        ImageBrush brush = new ImageBrush();
        brush.ImageSource = myimage.Source;
        canvas.Background = brush;

        //canvas.Children.Add(myimage); // Draws
    }
}

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

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





第二个选项结果相同。

代码2(使用DrawingVisual):



The second option results the same.
Code 2 (using DrawingVisual):

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

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

        MyImage myimage = new MyImage();
        myimage.InvalidateVisual();

        ImageBrush brush = new ImageBrush();
        brush.ImageSource = myimage.Source;
        canvas.Background = brush;

        //canvas.Children.Add(myimage); // Draws
    }
}

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

推荐答案

1。 OnRender不会在代码1中呈现,因为视觉 MyImage 未添加到可视树中。但是当你将它添加到画布的可视树中时它会呈现。

来源:

WPF:InvalidateVisual不会被OnRender绘制。 [ ^ ]



2.即使它在画布的表面上渲染,它也不会渲染到 ImageBrush ,因为画笔用于基于光栅的图像,但不用于矢量基于图像。这就是为什么当你通过一个链接添加它时渲染光栅图像。



3.你应该使用 VisualBrush [ ^ ]因为它是矢量基于图像。



4.即使您不添加,代码2中的 VisualCollection / DrawingVisual 也会呈现 MyImage 进入画布的视觉树。



代码:

1. OnRender doesn't render in the code 1 because the visual MyImage is not added into a visual tree. But it renders when you add it into the visual tree of Canvas.
Source:
WPF: InvalidateVisual doesn't draw by OnRender.[^]

2. Even if it renders on the surface of Canvas, it will not render into ImageBrush because the brush is for raster based images, but not for vector based images. That is why it renders a raster image when you add it via a link.

3. You should use VisualBrush[^] as it is for vector based images.

4. VisualCollection/DrawingVisual in the code 2 renders even if you don't add MyImage into the visual tree of Canvas.

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

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

        MyImage myimage = new MyImage();

        VisualBrush visualbrush = new VisualBrush();
        visualbrush.Visual = myimage;
        canvas.Background = visualbrush;
    }
}

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


这篇关于WPF:如何通过OnRender绘制的ImageBrush填充?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆