Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >打造一把UWP像素尺

打造一把UWP像素尺

作者头像
Edi Wang
发布于 2019-07-10 09:23:35
发布于 2019-07-10 09:23:35
1.1K00
代码可运行
举报
文章被收录于专栏:汪宇杰博客汪宇杰博客
运行总次数:0
代码可运行

在特定应用里,我们需要用标尺来标识屏幕上的像素。然而唯一内置的尺是在InkToolbar控件里的,我们没法拿出来用。今天我就教大家如何自己打造一把UWP引用里随处可用的像素尺。

样例应用

新建一个名为PixelRulerUwp的UWP应用,版本设置为Windows 10, version 1803 (10.0; Build 17134)。

// 不用1809是因为这个版本实在是人类历史上最可怕的药丸啊,微软别打我,这行注释了你们看不见……

Win2D

官方文档描述

Win2D is an easy-to-use Windows Runtime API for immediate mode 2D graphics rendering with GPU acceleration. It is available to C#, C++ and VB developers writing apps for the Windows Universal Platform (UWP). It utilizes the power of Direct2D, and integrates seamlessly with XAML and CoreWindow.

我们将使用Win2D绘制标尺。使用NuGet将Win2D安装到我们的工程里:

Install-Package Win2D.uwp

创建PixelRuler用户控件

在工程里添加一个名为“PixelRuler.xaml”的用户控件

Win2D能够在CanvasControl上绘制图形,因此我们需要添加一个名为“RulerCanvas”的CanvasControl,之后我们会在它上面绘制像素尺。

UserControl属性里加入一个新的命名空间

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
xmlns:xaml="using:Microsoft.Graphics.Canvas.UI.Xaml"

然后添加CanvasControl

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<xaml:CanvasControl x:Name="RulerCanvas"                     VerticalAlignment="Top" />

这不是最终的XAML代码,我们将继续完成它。

创建绑定属性

这把尺至少需要一个宽度和一个背景色,在PixelRuler.xaml.cs中加入它们。

实现INotifyPropertyChanged接口来进行数据绑定

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
using System.ComponentModel;

然后

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public sealed partial class PixelRuler : UserControl, INotifyPropertyChanged

实现接口

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
private void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

然后创建RulerWidth属性

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public static readonly DependencyProperty RulerWidthProperty = DependencyProperty.Register(
    nameof(RulerWidth),
    typeof(int),
    typeof(PixelRuler),
    new PropertyMetadata(null)
);
public int RulerWidth
{
    get => (int)GetValue(RulerWidthProperty);
    set => SetValue(RulerWidthProperty, value);
}

DependencyProperty通常用于UserControl里,这样使用者能够对你的UserControl进行属性的设定。

类似的,添加BackgroundColor属性。

加入命名空间

using Windows.UI;

加入属性

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public static readonly DependencyProperty BackgroundColorProperty = DependencyProperty.Register(
    nameof(BackgroundColor),
    typeof(Color),
    typeof(PixelRuler),
    new PropertyMetadata(null)
);
public Color BackgroundColor
{
    get => (Color)GetValue(BackgroundColorProperty);
    set { SetValue(BackgroundColorProperty, value); OnPropertyChanged(); }
}

在构造函数里给它们设置默认值

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public PixelRuler()
{
    this.InitializeComponent();
    RulerWidth = 50;
    BackgroundColor = Color.FromArgb(128, 238, 238, 238);
}

现在,修改PixelRuler.xaml,绑定这两个属性

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<xaml:CanvasControl x:Name="RulerCanvas" 
                    Height="{x:Bind RulerWidth, Mode=OneWay}"
                    ClearColor="{x:Bind BackgroundColor, Mode=OneWay}"
                    VerticalAlignment="Top" />

PixelRuler用户控件添加到MainPage.xaml里

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<local:PixelRuler HorizontalAlignment="Stretch"
                  VerticalAlignment="Top" />

绘制尺

要在CanvasControl上绘制图形,使用Draw事件,处理函数命名为RulerCanvas_OnDraw

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<xaml:CanvasControl x:Name="RulerCanvas" 
                    VerticalAlignment="Top" 
                    Height="{x:Bind RulerWidth, Mode=OneWay}"
                    ClearColor="{x:Bind BackgroundColor, Mode=OneWay}"
                    Draw="RulerCanvas_OnDraw" />

为了教程目的,我暂时使用硬编码来写

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private void RulerCanvas_OnDraw(CanvasControl sender, CanvasDrawEventArgs args)
{
    var session = args.DrawingSession;
    session.DrawLine(0, 0, 1920, 0, Colors.Black, 1);
    session.DrawLine(0, RulerWidth, 1920, RulerWidth, Colors.Black, 1);
}

方法签名是这样的

public void DrawLine(float x0, float y0, float x1, float y1, Color color, float strokeWidth);

这里,1920是屏幕的宽度,(x0, y0)是线条起点坐标,(x1, y1)是线条终点坐标,0是画布的左上角位置

运行这个工程,你会得到一个带上下边和背景色的空尺子:

现在你了解了如何使用Win2D在CanvasControl上绘制图形并在一个应用页面里使用的过程,让我们来更深入的完成这把尺子。

绘制刻度

一把尺有小刻度和大刻度,我们允许用户自定义刻度的步长。

加入代表这两种刻度的属性

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public static readonly DependencyProperty LargeStepsProperty = DependencyProperty.Register(
    nameof(LargeSteps),
    typeof(int),
    typeof(PixelRuler),
    new PropertyMetadata(null)
);
public int LargeSteps
{
    get => (int)GetValue(LargeStepsProperty);
    set => SetValue(LargeStepsProperty, value);
}
public static readonly DependencyProperty SmallStepsProperty = DependencyProperty.Register(
    nameof(SmallSteps),
    typeof(int),
    typeof(PixelRuler),
    new PropertyMetadata(null)
);
public int SmallSteps
{
    get => (int)GetValue(SmallStepsProperty);
    set => SetValue(SmallStepsProperty, value);
}

在构造函数里设置默认值

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public PixelRuler()
{
    // …
    LargeSteps = 50;
    SmallSteps = 10;
}

为了教程目的,我依然暂时使用硬编码,现在RulerCanvas_OnDraw 的代码为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private void RulerCanvas_OnDraw(CanvasControl sender, CanvasDrawEventArgs args)
{
    var session = args.DrawingSession;
    session.DrawLine(0, 0, 1920, 0, Colors.Black, 1);
    session.DrawLine(0, RulerWidth, 1920, RulerWidth, Colors.Black, 1);
    for (int x = 0; x < 1920; x += LargeSteps)
    {
        for (int x1 = x + SmallSteps; x1 < x + LargeSteps; x1 += SmallSteps)
        {
            session.DrawLine(x1, 0, x1, 10, Colors.Black, 1);
        }
        session.DrawLine(x, 0, x, 20, Colors.Black, 1);
    }
}

这里10代表小刻度的长度,20代表大刻度的长度。

运行工程,你能看见一把带有大、小刻度的尺

绘制数值文本

一把尺也需要在大刻度上标明数值,将下面代码添加到RulerCanvas_OnDraw事件处理函数里:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for (int x = 0; x < 1920; x += LargeSteps)
{
    session.DrawText(x.ToString(), x, 30, Colors.Black, new CanvasTextFormat()
    {
        FontSize = (float)FontSize,
        FontFamily = FontFamily.Source,
        HorizontalAlignment = CanvasHorizontalAlignment.Center,
        VerticalAlignment = CanvasVerticalAlignment.Center
    });
}

其中30代表尺的顶端到文本的距离,等于大刻度的长度加10个像素。

FontSizeFontFamily不需要额外创建两个属性,它们继承于UserControl本身,所以用户已经可以控制这两者的值了,例如在MainPage.xaml里:

<local:PixelRuler HorizontalAlignment="Stretch"

VerticalAlignment="Top" FontSize="12" FontFamily="Consolas" />

运行工程,你会得到一个带有刻度和数字的尺

现在你已经完成了像素尺的基本功能,我们来让它更加完善。

更完美的功能

我们的UserControl需要在不同场景下使用,因此我们要让用户能尽可能自定义每一处设置,而不是硬编码进程序里。

例如,关于屏幕宽度,我之前硬编码了1920。我们把它设置为用户屏幕分辨率的大边。获取屏幕分辨率的简单方法可以安装我的UWP助手库获得:

Install-Package Edi.UWP.Helpers

现在你可以把每一处1920都改成largePixel了:

var pixelW = Edi.UWP.Helpers.UI.GetScreenWidth();

var pixelH = Edi.UWP.Helpers.UI.GetScreenHeight();

var largePixel = pixelW > pixelH ? pixelW : pixelH;

session.DrawLine(0, 0, (int)largePixel, 0, Colors.Black, 1);

session.DrawLine(0, RulerWidth, (int)largePixel, RulerWidth, Colors.Black, 1);

我也添加了如下的属性帮助自定义这把尺

  • DrawBorder (是否绘制边框)
  • ScaleMarkPosition (刻度位置:左、右、两者都要)
  • ScaleMarkLength (刻度长度)
  • ScaleMarkColor (刻度颜色)
  • TextColor (数字颜色)
  • TextMargin (数字边距)

你可以深度自定义像素尺

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<local:PixelRuler HorizontalAlignment="Stretch"
                  VerticalAlignment="Top"
                  RulerWidth="80"
                  LargeSteps="50"
                  SmallSteps="10"
                  ScaleMarkLength="20"
                  FontSize="12"
                  ScaleMarkPosition="Both"
                  ScaleMarkColor="#CCC"
                  TextColor="#CCC"
                  FontFamily="Segoe UI"
                  TextMargin="10"
                  BackgroundColor="#333" 
                  DrawBorder="True"
                  Height="80" />

完整的案例代码在我的GitHub上:

https://github.com/EdiWang/PixelRulerUwp

你也可以在微软应用商店找到样例APP:

https://www.microsoft.com/en-us/p/pixelruleruwp-demo/9nblggh5fjhn

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-11-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 汪宇杰博客 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
解决AMD CPU 启动Android模拟器时无法安装Intel HAXM 的问题
在网上一搜,说是Android Studio已经支持AMD CPU的,后面在Android SDK配置项中终于发现有这么一项。
全栈程序员站长
2022/09/13
6.1K0
解决AMD CPU 启动Android模拟器时无法安装Intel HAXM 的问题
解决AMD电脑Android Studio模拟器无法安装Intel HAXM的问题
我的电脑是magicbook 14 R5的版本,今天在运行AS模拟器的时候遇到了无法安装Intel HAXM 的问题。
可定
2020/06/22
7.7K0
Android Studio 3.2 都有哪些更新?这些关键点不要错过
点击这里即刻下载 Android Studio 3.2。 Android Studio 3.2 是应用开发者切入最新的 Android 9 Pie 发布版和构建新的 Android App Bundle 的最佳途径。自从 2018 年 Google I/O 大会 Android Studio 宣布更新后,我们精炼和完善了 20 多项新功能,并集中力量提升 Android Studio 3.2 稳定版的质量。
Android 开发者
2018/10/22
2K0
Android Studio 3.2 都有哪些更新?这些关键点不要错过
解决win10在安装Android-studio时提示HAXM无法安装问题[通俗易懂]
错误提示:This computer does not support Intel Virtualization Technology (VT-x) or it is being exclusively used by Hyper-V. HAXM cannot be installed. Please ensure Hyper-V is disabled in Windows Features, or refer to the Intel HAXM documentation for more information.
全栈程序员站长
2022/09/13
4.8K0
解决win10在安装Android-studio时提示HAXM无法安装问题[通俗易懂]
Hyper-V虚拟机安装和使用
最近在研究人工智能AI模型的相关内容。需要一个稳定可靠的Linux环境来运行数据模型,但是我的电脑操作系统是windows操作系统,一开始我想使用VMware,但是它是收费的,而且安装起来也比较麻烦,后来我发现微软的Hyper-V虚拟机非常方便,关键是免费的。所以选择使用Hyper-V,在这里记录下Hyper-V虚拟机的安装和使用过程。通过分享我的经验,希望能够对其他人在使用Hyper-V虚拟机时提供帮助和指导。
九仞山
2023/10/14
3.7K0
Hyper-V虚拟机安装和使用
使用 Intel HAXM 为 Android 模拟器加速,媲美真机
Android 模拟器一直以运行速度慢著称, 本文介绍使用 Intel HAXM 技术为 Android 模拟器加速, 使模拟器运行度媲美真机, 彻底解决模拟器运行慢的问题。
beginor
2020/08/10
2K0
使用 Intel HAXM 为 Android 模拟器加速,媲美真机
Android Studio 中Intel HAXM安装与模拟器创建「建议收藏」
Intel HAXM (Hardware Accelerated Execution Manager) 使用基于 Intel(R) Virtualization Technology (VT) 的硬件加速, 因此需要 CPU 支持 VT , 而且仅限于 Intel CPU, 与 AMD CPU 无缘, Intel HAXM 的描述如下:
全栈程序员站长
2022/08/03
4.5K0
Android Studio 中Intel HAXM安装与模拟器创建「建议收藏」
XEN、VMware ESXi、Hyper-V以及KVM架构解析
XEN 有简化虚拟模式,不需要设备驱动,能够保证每个虚拟用户系统相互独立,依赖于 service domains 来完成一些功能; Vmware ESXI 与 XEN 比较类似,包含设备驱动以及管理栈
CSDN技术头条
2018/02/09
11K1
XEN、VMware ESXi、Hyper-V以及KVM架构解析
Android Studio中 HAXM安装失败的问题(Intel HAXM installation failed. To install Intel HAXM follow the…)
问题描述:安装Android Studio中 在最后一步出现 Intel HAXM installation failed. To install Intel HAXM follow the instructions found at:xxxx
全栈程序员站长
2022/09/13
9.6K0
Hyper-v 实现桌面虚拟化
为了方便对公司办公机桌面系统进行管理,所以需要 Hyper-v 虚拟化平台对桌面进行部署。 Hyper-v 是微软的一款虚拟化产品,是微软第一个采用 VMware 和 Citrix 一样的基于 hypervisor 的技术。 Hyper-v 角色可以利用内置于 Windows server 中的虚拟化技术创建和管理虚拟化的计算机环境。
小手冰凉
2019/09/10
3.6K0
Hyper-v 实现桌面虚拟化
《如何为Android Studio安装HAXM》「建议收藏」
注意:当你在Android studio直接下载sdk和HAXM一些安卓环境依赖的文件时,会出现haxm文件已经下载,但未安装,导致启动avd模拟器不成功!
全栈程序员站长
2022/09/13
3.9K0
《如何为Android Studio安装HAXM》「建议收藏」
Android Q Beta 6 终极测试版发布!
其中,Android的更新速度要比iOS更快,系统的功能也更加丰富多样。从推出至今,Android已经发布更迭了10个系统版本。Android Q Beta 6 已发布,这是 Android Q 的最后一个 Beta 测试版,Android Q 正式版即将到来。
终端研发部
2019/08/16
1.5K0
React Native学习笔记(一)—— Win11安卓子系统的安装与使用 - Windows Subsystem for Android - WSA
写这篇文章的目的是为了学习React Native开发打基础,能够更好的运行、测试原生应用,带来比模拟器更好的体验。
张果
2023/03/14
2.9K0
React Native学习笔记(一)—— Win11安卓子系统的安装与使用 - Windows Subsystem for Android - WSA
android 模拟器 haxm,Android模拟器不使用HAXM
我遇到HAXM问题.在我使用Windows 7之前,一切都很好,但升级到Win8.1 Pro后,当我从AVD屏幕启动模拟器时,我看不到haxm启动消息. HAXM安装并正常工作,我安装了x86的图像,我的设备使用它但仍然无法在启动窗口中看到Emulator正在使用haxm的确认消息.
全栈程序员站长
2022/09/13
2.1K0
基于Eclipse+SDK+ADT+DDMS的安卓开发环境完整搭建过程
虫无涯
2023/11/27
9302
Android Monkey压力测试
在“我的电脑”-“属性”-“高级”-“环境变量”中,单击新建,填充变量称为JAVA_HOME,变量替换JAVA安装的路径。
顾翔
2020/09/04
1.8K0
Android Monkey压力测试
安卓夜神模拟器关闭Hyper-v了 还是蓝屏
平时都是用安卓模拟器的百度云盘看考研视频的,但是今天开模拟器之后居然蓝屏了......
可定
2020/04/20
3.4K0
安卓夜神模拟器关闭Hyper-v了 还是蓝屏
Hypervisor, KVM, QEMU总结
Hypervisor——一种运行在基础物理服务器和操作系统之间的中间软件层,可允许多个操作系统和应用共享硬件。也可叫做VMM( virtual machine monitor ),即虚拟机监视器。
战神伽罗
2019/07/24
11K1
Hypervisor, KVM, QEMU总结
如何使用 Android Studio 设置 Genymotion 模拟器
Genymotion 模拟器 是 最常用的 Android Studio 插件之一,您可以在其中部署和测试您的移动应用程序。在这里,我们提供了一步一步的教程来下载、设置和使用 Genymotion 和 Android Studio。
鲸落c
2022/11/14
3.4K0
如何使用 Android Studio 设置 Genymotion 模拟器
AMD CPU 的电脑运行 Android Studio 模拟器时报错 Failed to install Intel HAXM
AMD CPU 的电脑运行 Android Studio 模拟器时报错 Failed to install Intel HAXM
可定
2020/04/20
9330
AMD CPU 的电脑运行 Android Studio 模拟器时报错 Failed to install Intel HAXM
推荐阅读
相关推荐
解决AMD CPU 启动Android模拟器时无法安装Intel HAXM 的问题
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验