如何自定义XamlCompositionBrushBase实现图片平铺
admin
2023-02-15 02:20:05
0次

这篇文章运用简单易懂的例子给大家介绍自定义XamlCompositionBrushBase实现图片平铺的方法,文章内容步步紧凑,希望大家根据这篇文章可以有所收获。

1. 背景

我早就想试试自定义XamlCompositionBrushBase,但一直没机会。上一篇文章介绍到使用Win2D的BorderEffect实现图片的平铺功能,原理很简单,但每次都要写这些代码很繁琐,正好就用这个作为例子试试XamlCompositionBrushBase。

CompositionBrush灵活多变,它的基本用法如下:

  1. 通过Compositor创建CompositionBrush;
  2. 配置CompositionBrush;
  3. 创建SpriteVisual并将它的Brush设置为CompositionBrush;
  4. 使用ElementCompositionPreview.SetElementChildVisual 将SpriteVisual设置到某个UIElement的可视化层里。

这些步骤很繁琐,而且不能用在XAML中。XamlCompositionBrushBase提供了将CompositionBrush用在XAML中一个桥梁,他继承自Brush类,可以直接像普通的XAML 画笔(如SolidColorBrush)那样直接用在XAML中。

Windows Community Toolkit中已经提了很不少XamlCompositionBrushBase的实现,它们的使用方式已经有很多文章介绍,这里不一一列举。

2. 自定义XamlCompositionBrushBase

这篇文章将介绍一个自定义的画笔:TiledImageBrush,它的主要目标是实现ImageBrush没有的图片平铺功能,并且它可以在XAML中使用,使用方式如下:


    
        
    

顺便复习下普通的ImageBrush的用法:


    
        
    

看起来TiledImageBrush的用法是不是和ImageBrush很像?接下来讲解TiledImageBrush的实现步骤。TiledImageBrush继承自XamlCompositionBrushBase,而实现XamlCompositionBrushBase的一般步骤如下:

protected override void OnConnected()
{
    // Delay creating composition resources until they're required.
    if (CompositionBrush == null)
    {
         CompositionBrush = CreateCompositionBrush();//Create A CompositionBrush.
    }
}

protected override void OnDisconnected()
{
    // Dispose of composition resources when no longer in use.
    if (CompositionBrush != null)
    {
        CompositionBrush.Dispose();
        CompositionBrush = null;
    }
}

首先重写OnConnected,当画笔在屏幕上首次用于绘制元素时会调用这个函数。在这个函数里创建CompositionBrush并赋值给XamlCompositionBrushBase.CompositionBrush。

然后重写OnDisconnected,它在画笔不再用于绘制任何元素时被调用。在这个函数里尽可能地释放各种资源,例如CompositionBrush。这两步就是实现XamlCompositionBrushBase的基本步骤。

创建CompositionBrush有很多种玩法,我之前写过两篇文章分别介绍 CompositionBrush入门及 在CompositionBrush上使用Effect。这里使用使用Win2D的BorderEffect实现图片的平铺功能这篇文章里介绍到的代码,首先使用LoadedImageSurface.StartLoadFromUri创建CompositionSurfaceBrush,然后加入到BorderEffect里实现图片平铺,然后把产生的CompositionEffectBrush赋值给XamlCompositionBrushBase.CompositionBrush。

TiledImageBrush中添加了Source属性用于设置图片Uri(实际上是个ImageSource类型),模仿ImageBrush,这里的Source也是一个ImageSource类型的属性,虽然实际上使用的是它的UriSource。详细代码如下:

public ImageSource Source
{
    get => (ImageSource)GetValue(SourceProperty);
    set => SetValue(SourceProperty, value);
}

private void UpdateSurface()
{
    if (Source != null && _surfaceBrush != null)
    {
        var uri = (Source as BitmapImage)?.UriSource ?? new Uri("ms-appx:///");
        _surface = LoadedImageSurface.StartLoadFromUri(uri);
        _surfaceBrush.Surface = _surface;
    }
}

OnConnected的详细代码如下:

protected override void OnConnected()
{
    base.OnConnected();

    if (CompositionBrush == null)
    {
        _surfaceBrush = Compositor.CreateSurfaceBrush();
        _surfaceBrush.Stretch = CompositionStretch.None;

        UpdateSurface();

        _borderEffect = new BorderEffect()
        {
            Source = new CompositionEffectSourceParameter("source"),
            ExtendX = Microsoft.Graphics.Canvas.CanvasEdgeBehavior.Wrap,
            ExtendY = Microsoft.Graphics.Canvas.CanvasEdgeBehavior.Wrap
        };

        _borderEffectFactory = Compositor.CreateEffectFactory(_borderEffect);
        _borderEffectBrush = _borderEffectFactory.CreateBrush();
        _borderEffectBrush.SetSourceParameter("source", _surfaceBrush);
        CompositionBrush = _borderEffectBrush;
    }
}

上文描述的就是自定义XamlCompositionBrushBase实现图片平铺的方法,具体使用情况还需要大家自己动手实验使用过才能领会。如果想了解更多相关内容,欢迎关注行业资讯频道!

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...