这次我们的目标是直接继承Control并重写OnRender 函数以实现自定义UI外观的绘制功能,最终我们将自己实现一个圆角的按钮,并包含Hover 动画效果,Click 点击事件等特性。

代码直达:链接

先简单介绍下Control 在WPF窗体中绘制的过程:

  1. 首先明确所有的控件都是在Layout 布局系统下布局的,因此在绘制时我们肯定需要考虑WPFMeasureArrange过程
  2. 在完成布局中进行测量和排布过程其实就是确定了OnRender 函数中需要用到的如控件实际大小等尺寸信息。在OnRender函数中就根据这些参数绘制对应的UI效果就可以。

对于布局类型如Panel则需要自己实现MeasureOverrideArrangeOverride 以实现对子组件的尺寸测量和布局。

因此我们就简单实现OnRender函数即可, 首先绘制一个填充的圆角矩形作为按钮外边框。然后绘制按钮内部的文本内容。

protected override void OnRender(DrawingContext drawingContext)
{
    // Draw border
    Brush brush = Brushes.Red;
    Pen pen = new Pen(Brushes.Black, 2.0);
    
    double radiusX = 5;
    double radiusY = 5;
    Rect rectangle = new Rect(new Size(this.ActualWidth, this.ActualHeight));
    drawingContext.DrawRoundedRectangle(brush, pen, rectangle, radiusX, radiusY);

    // Draw text
    FormattedText formattedText = new FormattedText("Click",
        CultureInfo.CurrentCulture,
        FlowDirection.LeftToRight,
        new Typeface(FontFamily, FontStyle, FontWeight, FontStretch),
        16,
        Brushes.Black);

    double width = formattedText.Width;
    double height = formattedText.Height;
    double centerX = this.ActualWidth / 2 - width / 2;
    double centerY = this.ActualHeight / 2 - height / 2;

    drawingContext.DrawText(formattedText, new Point(centerX, centerY));
}

绘制效果

2qklNP69yBsfQsh_XKpxCc1749eOq2HgQkrUSCYYuAc.png

后续

后面将会实现Click 路由事件的绑定和处理,并对绘制的画笔颜色、填充效果、圆角半径等建立DependencyObject 以达到在Xaml 中设置的效果。

WPF教程十三:自定义控件进阶可视化状态与自定义Panel

WPF教程十四:了解元素的渲染OnRender()如何使用