WinUI 3中如何实现图片重复平铺作为元素背景?
WinUI 3 实现位图平铺背景的可行方案
方案1:基于Composition API的简化实现
直接用WinUI 3内置的Composition能力,无需额外NuGet包,完美兼容BitmapImage,步骤如下:
- 准备好你的
BitmapImage资源(本地文件或应用内资源均可) - 等待图片加载完成后获取对应的
CompositionSurface - 创建
SpriteBrush并开启平铺模式 - 将Brush转换为XAML可用的Brush,应用到目标元素背景
示例代码:
using Microsoft.UI.Composition; using Microsoft.UI.Xaml.Media; // 目标矩形控件和BitmapImage实例 var targetRect = yourRectangleControl; var bitmapImage = new BitmapImage(new Uri("ms-appx:///Assets/your-tile-image.png")); // 等待图片加载完成 await bitmapImage.LoadAsync(); // 获取图片对应的CompositionSurface var surface = LoadedImageSurface.StartLoadFromUri( bitmapImage.UriSource, new Size(bitmapImage.PixelWidth, bitmapImage.PixelHeight) ); // 创建平铺Brush var compositor = ElementCompositionPreview.GetElementVisual(targetRect).Compositor; var tileBrush = compositor.CreateSpriteBrush(); tileBrush.Surface = surface; tileBrush.TileMode = CompositionTileMode.Tile; tileBrush.Stretch = CompositionStretch.None; // 应用到矩形背景 targetRect.Background = CompositionBrushExtensions.AsBrush(compositor, tileBrush);
说明:
- 所有API都是WinUI 3稳定版内置的,不需要额外依赖
- 直接复用
BitmapImage,解决了你提到的集成问题 - 逻辑清晰,比早期复杂方案简化不少
方案2:封装可复用的平铺背景控件
如果需要多次使用,把逻辑封装成自定义控件,避免重复代码:
using Microsoft.UI.Composition; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Media; public class TileBackgroundControl : Control { public static readonly DependencyProperty TileImageSourceProperty = DependencyProperty.Register( nameof(TileImageSource), typeof(ImageSource), typeof(TileBackgroundControl), new PropertyMetadata(null, OnTileImageSourceChanged) ); public ImageSource TileImageSource { get => (ImageSource)GetValue(TileImageSourceProperty); set => SetValue(TileImageSourceProperty, value); } private static async void OnTileImageSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var control = d as TileBackgroundControl; if (control == null || e.NewValue is not BitmapImage bitmap) return; await bitmap.LoadAsync(); var surface = LoadedImageSurface.StartLoadFromUri( bitmap.UriSource, new Size(bitmap.PixelWidth, bitmap.PixelHeight) ); var compositor = ElementCompositionPreview.GetElementVisual(control).Compositor; var tileBrush = compositor.CreateSpriteBrush(); tileBrush.Surface = surface; tileBrush.TileMode = CompositionTileMode.Tile; tileBrush.Stretch = CompositionStretch.None; control.Background = CompositionBrushExtensions.AsBrush(compositor, tileBrush); } }
XAML中直接使用:
<local:TileBackgroundControl TileImageSource="ms-appx:///Assets/your-tile-image.png" />
方案3:纯XAML的轻量替代方案
如果不想写C#代码,用DrawingBrush也能实现,适合简单场景:
<Rectangle Width="300" Height="300"> <Rectangle.Background> <DrawingBrush TileMode="Tile" Viewport="0,0,50,50" ViewportUnits="Absolute"> <DrawingBrush.Drawing> <ImageDrawing Rect="0,0,50,50" ImageSource="ms-appx:///Assets/your-tile-image.png" /> </DrawingBrush.Drawing> </DrawingBrush> </Rectangle.Background> </Rectangle>
注意Viewport的尺寸要和你的小图尺寸一致,保证平铺无错位。这个方法性能不如Composition API,但胜在零代码、易维护。
内容的提问来源于stack exchange,提问作者sjb-sjb
相关产品推荐
相关产品推荐

