You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UWP应用中是否存在类似WinForms OnPaint的自定义组件绘制方法?

UWP自定义UI组件绘制:替代WinForms的OnPaint方法

UWP中没有和WinForms OnPaint完全等价的方法,要实现自定义绘制逻辑,最实用的方案是使用Win2D(微软官方的2D图形库),它的API设计和WinForms的Graphics类非常接近,能轻松迁移你的绘制逻辑。以下是针对你提供的WinForms按钮绘制代码,给出的UWP实现方案:

步骤1:安装Win2D NuGet包

在你的UWP项目中,安装Microsoft.Graphics.Win2D.Uwp包,这是实现自定义绘制的基础。

步骤2:创建自定义控件并实现绘制逻辑

继承UserControl,内部嵌入CanvasControl,并在其Draw事件中实现绘制逻辑,对应WinForms的OnPaint方法:

using Microsoft.Graphics.Canvas;
using Microsoft.Graphics.Canvas.Geometry;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;

public class CustomButton : UserControl
{
    private CanvasControl _canvas;
    public enum Mode { True, False }

    // 定义对应WinForms中的属性
    public ImageSource Image { get; set; }
    public Mode ImageOnly { get; set; }
    public Color ButtonColor { get; set; } = Colors.LightGray;
    public Color Foreground { get; set; } = Colors.Black;
    public string Text { get; set; }
    public CanvasTextFormat ButtonFont { get; set; } = new CanvasTextFormat
    {
        FontSize = 14,
        HorizontalAlignment = CanvasHorizontalAlignment.Left,
        VerticalAlignment = CanvasVerticalAlignment.Top
    };

    public CustomButton()
    {
        _canvas = new CanvasControl();
        _canvas.Draw += Canvas_Draw;
        this.Content = _canvas;
        // 监听控件尺寸变化,触发重绘
        this.SizeChanged += (s, e) => _canvas.Invalidate();
    }

    private void Canvas_Draw(CanvasControl sender, CanvasDrawEventArgs args)
    {
        var session = args.DrawingSession;
        float buttonHeight = (float)ActualHeight;
        float buttonWidth = (float)ActualWidth;

        float imgHeight = buttonHeight;
        float imgWidth = buttonHeight;
        float textPadding = (buttonHeight - (float)ButtonFont.FontSize) / 2;
        float textStartX = imgWidth + textPadding;
        float textStartY = textPadding - 3;

        // 绘制圆角背景(对应WinForms的FillRoundedRectangle)
        var rect = CanvasGeometry.CreateRoundedRectangle(session, 0, 0, buttonWidth, buttonHeight, 10, 10);
        session.FillGeometry(rect, ButtonColor);

        if (Image == null) return;

        // 转换ImageSource为CanvasBitmap
        var bitmap = CanvasBitmap.LoadAsync(session, Image as Windows.UI.Xaml.Media.Imaging.BitmapImage).GetAwaiter().GetResult();

        if (ImageOnly == Mode.True)
        {
            // 居中绘制图片
            float imgX = (buttonWidth - imgWidth) / 2;
            float imgY = (buttonHeight - imgHeight) / 2;
            session.DrawImage(bitmap, imgX, imgY, imgWidth, imgHeight);
        }
        else
        {
            // 左图右文
            session.DrawImage(bitmap, 0, 0, imgWidth, imgHeight);
            session.DrawText(Text, textStartX, textStartY, Foreground, ButtonFont);
        }
    }

    // 控件卸载时释放CanvasControl资源
    protected override void OnUnloaded(object sender, RoutedEventArgs e)
    {
        _canvas.RemoveFromVisualTree();
        _canvas = null;
        base.OnUnloaded(sender, e);
    }
}

关键对应点说明

  • WinForms的PaintEventArgs.Graphics对应UWP中Win2D的CanvasDrawingSession,所有绘制操作都通过它完成
  • 圆角矩形绘制:用CanvasGeometry.CreateRoundedRectangle替代自定义的FillRoundedRectangle
  • 图片绘制:DrawImage方法参数和WinForms类似,需要先将ImageSource转换为CanvasBitmap
  • 文本绘制:DrawText替代DrawString,用CanvasTextFormat控制字体样式

如果你不想依赖Win2D,也可以继承CustomControl并重写OnRender方法,使用XAML的DrawingContext进行绘制,但这种方式的API功能有限,复杂图形(比如圆角、自定义图片布局)实现起来不如Win2D便捷。

内容的提问来源于stack exchange,提问作者Borisonekenobi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 00:05:24