UWP开发入门(十七)——判断设备类型及响应VirtualKey
蜀黍我做的工作跟IM软件有关,UWP同时会跑在电脑和手机上。电脑和手机的使用习惯不尽一致,通常我倾向于根据窗口尺寸来进行布局的变化,但是特定的操作习惯是依赖于设备类型,而不是屏幕尺寸的,比如聊天窗口的发送消息。假设如下场景,desktop运行时要求回车键直接发送消息,而mobile版则要求回车键换行,仅能通过点击按钮发送消息。
第一段的铺垫是为了今天提到的两个主题,判断设备类型和处理Shift+Enter的组合。
首先判断设备类型我们使用的是Windows.System.Profile命名空间下的AnalyticsInfo类,通过AnalyticsInfo.VersionInfo.DeviceFamily这个属性我们可以拿到当前的设备类型,小屏幕的设备类型是"Windows.Mobile",其他还是有Windows.Desktop,Windows.Xbox等。这里我们只希望单独区分小屏幕设备,不关心其他设备类型。同时需要指出的是,随之今后Windows设备类型的不断扩充,该属性可能出现的值会不断变化,所以在使用时需要考虑到变化是否会产生bug。
public bool IsAcceptReturn
{
get
{
return AnalyticsInfo.VersionInfo.DeviceFamily == "Windows.Mobile";
}
}
我们根据设备类型来定义了一个属性IsAcceptReturn来标识是否接受回车键换行。
接下来进行Shift+Enter组合键的响应了。UWP在这一点上果然又开了历史倒车,没记错的话连WinForm也无需如此麻烦,竟然要额外地储存一个标志位来标识VirtualKey.Shift是否被按下,在此基础之上再进一步判断是否有Enter键被触发。实际的代码中,我使用了KeyDown事件来记录Shift键的按下,同时通过KeyU事件来进行Enter键触发的判断。
private void KeyUp(KeyRoutedEventArgs e)
{
if (e.Key == VirtualKey.Enter)
{
if (_isShiftKeyPressed)
{
int oldIndex = Index;
InputText = InputText.Replace(Environment.NewLine, "\n").Insert(Index, "\n");
Index = oldIndex + ;
}
else if (IsAcceptReturn == false)
{
SendMessage();
}
}
_isShiftKeyPressed = false;
} private void KeyDown(KeyRoutedEventArgs e)
{
if (e.Key == VirtualKey.Shift)
{
_isShiftKeyPressed = true;
}
}
在KeyUp事件中如果涉及Enter键的触发,将判断_isShiftKeyPressed字段的值,同时根据IsAcceptReturn来判断是否不处理换行,直接发送消息。这里值得一提的是Environment.NewLine在Windows下对应的“\r\n”符号,计算字符串索引时仅作为1位处理,导致我很尴尬总是算不对Shift+Enter换行后的光标位置。无奈出下策将其替换成"\n",其中奥妙各位一试便知。程序对应的XAML如下:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ListView Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" ItemsSource="{Binding Messages}"/>
<TextBox Grid.Row="1" Grid.Column="0" Text="{Binding InputText, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" SelectionStart="{Binding Index, Mode=TwoWay}"
MaxHeight="100" AcceptsReturn="{Binding IsAcceptReturn}" TextWrapping="Wrap">
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="KeyUp">
<Core:InvokeCommandAction Command="{Binding KeyUpCommand,Mode=OneTime}"/>
</Core:EventTriggerBehavior>
<Core:EventTriggerBehavior EventName="KeyDown">
<Core:InvokeCommandAction Command="{Binding KeyDownCommand,Mode=OneTime}"/>
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</TextBox>
<Button Grid.Row="1" Grid.Column="1" Width="80" Command="{Binding SendMessageCommand}" Content="Send"/>
</Grid>
ListView模拟聊天窗口,TextBox的Text属性Binding到了InpuText,同时SlectionStar属性Binding到Index,用于Shift+Enter换行时,插入\n换行符号,及确定光标位置。AcceptsReturn属性在Mobile设备上是true,而在其他设备上就会无视回车键来。TextWrapping属性也很重要,如果不设置为Wrap,即使实际的字符串是包含“\n”等换行符号,但在TextBox中也不会显示出来。


求看到这里的各位评论一下嗨,让俺知道还有人在看Windows UWP。
Behaviors的使用我计划后续的篇章再介绍,同时本篇的代码使用了Mvvmlight框架,我想是时候把Mvvmlight的介绍也拾起来了!最后是完整代码在GitHub的地址,欢迎看了批评指正哈。
https://github.com/manupstairs/UWPSamples/tree/master/UWPSamples/DeviceFamilyAndVirtualKey
UWP开发入门(十七)——判断设备类型及响应VirtualKey的更多相关文章
- UWP开发入门(十六)——常见的内存泄漏的原因
本篇借鉴了同事翔哥的劳动成果,在巨人的肩膀上把稿子又念了一遍. 内存泄漏的概念我这里就不说了,之前<UWP开发入门(十三)——用Diagnostic Tool检查内存泄漏>中提到过,即使有 ...
- UWP开发入门系列笔记之(一):UWP初览
标签: 随着微软Build2015带来的好消息,Win10正式版发布的日子已经离我们越来越近了,我们也终于欣喜地看到:一个统一的Windows平台对于开发人员来说充满了吸引力,这局棋下的好大的说--于 ...
- UWP开发入门(十)——通过继承来扩展ListView
本篇之所以起这样一个名字,是因为重点并非如何自定义控件,不涉及创建CustomControl和UserControl使用的Template和XAML概念.而是通过继承的方法来扩展一个现有的类,在继承的 ...
- UWP开发入门(四)——自定义CommandBar
各位好,再次回到UWP开发入门系列,刚回归可能有些不适应,所以今天我们讲个简单的,自定义CommandBar,说通俗点就是自定义类似AppBarButton的东西,然后扔到CommandBar中使用. ...
- UWP开发入门(25)——通过Radio控制Bluetooth, WiFi
回顾写了许久的UWP开发入门,竟然没有讲过通过Windows.Devices.Radios.Radio来控制Bluetooth和WiFi等功能的开关.也许是因为相关的API设计的简单好用,以至于被我给 ...
- UWP开发入门(二十一)——保持Ui线程处于响应状态
GUI的程序有时候会因为等待一个耗时操作完成,导致界面卡死.本篇我们就UWP开发中可能遇到的情况,来讨论如何优化处理. 假设当前存在点击按钮跳转页面的操作,通过按钮打开的新页面,在初始化过程中存在一些 ...
- UWP开发入门(十一)——Attached Property的简单应用
UWP中的Attached Property即附加属性,在实际开发中是很常见的,比如Grid.Row: <Grid Background="{ThemeResource Applica ...
- UWP开发入门(二十三)——WebView
本篇讨论在UWP开发中使用WebView控件时常见的问题,以及一些小技巧. WebView是实际开发中常用的控件,很多大家抱怨的套网页的应用都是通过WebView来实现的.这里要澄清一个问题,套网页的 ...
- UWP开发入门(七)——下拉刷新
本篇意在给这几天Win10 Mobile负面新闻不断的某软洗地,想要证明实现一个简单的下拉刷新并不困难.UWP开发更大的困难在于懒惰,缺乏学习的意愿.而不是“某软连下拉刷新控件都没有”这样的想法. 之 ...
随机推荐
- 三、oracle 体系结构
1.oracle内存由SGA+PGA所构成 2.oracle数据库体系结构数据库的体系结构是指数据库的组成.工作过程与原理,以及数据在数据库中的组织与管理机制. oracle工作原理: 1).在数据库 ...
- 分布式Hadoop安装(二)
二.集群环境安装Zookeeper 1. hadoop0,namenode机器下,配置zookeeper,先解压安装包. 使用命令:tar -zxvf zookeeper-3.4.4. ...
- AngularJS指令嵌套时link函数执行顺序的问题
今天研究指令嵌套时,发现子指令的link函数先于父指令的link函数执行. 这样和预想的顺序不一样. 也就是说,如果子指令的某个scope变量依赖于父指令传来的参数时,可能一直是undefinded比 ...
- [算法导论]BFS @ Python
class Graph: def __init__(self): self.V = [] class Vertex: def __init__(self, x): self.key = x self. ...
- xml转换之
1.XStream public static <T> T toBean(String xmlStr, Class<T> cls) { XStream xstream = ne ...
- Sublime Text 3103 Crack 破解 注册码(亲测有效)
随机复制下面的几四个注册码 粘贴到sublime text 3(Build 3103)注册框 就可以了! 第一个--first licence key : ====================== ...
- Scala 深入浅出实战经典 第49课 Scala中Variance代码实战(协变)
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...
- Android开发(三十一)——重复引用包错误Conversion to Dalvik format failed
错误:Conversion to Dalvik format failed: Unable to execute dex: Multiple dex files define Landroid/sup ...
- Android开发(二十六)——Application
application package com.lgaoxiao.application; import java.util.LinkedList; import java.util.List; im ...
- 【jquery】jquery.cookie.js 的使用指南
之前有写过一篇原生 js 的 cookie 介绍,并且最后封装成 cookie.js 具体内容点击传送门. jquery.cookie.js 是一款轻量级的 cookie 插件,可以读取,写入和删除 ...