蜀黍我做的工作跟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的更多相关文章

  1. UWP开发入门(十六)——常见的内存泄漏的原因

    本篇借鉴了同事翔哥的劳动成果,在巨人的肩膀上把稿子又念了一遍. 内存泄漏的概念我这里就不说了,之前<UWP开发入门(十三)——用Diagnostic Tool检查内存泄漏>中提到过,即使有 ...

  2. UWP开发入门系列笔记之(一):UWP初览

    标签: 随着微软Build2015带来的好消息,Win10正式版发布的日子已经离我们越来越近了,我们也终于欣喜地看到:一个统一的Windows平台对于开发人员来说充满了吸引力,这局棋下的好大的说--于 ...

  3. UWP开发入门(十)——通过继承来扩展ListView

    本篇之所以起这样一个名字,是因为重点并非如何自定义控件,不涉及创建CustomControl和UserControl使用的Template和XAML概念.而是通过继承的方法来扩展一个现有的类,在继承的 ...

  4. UWP开发入门(四)——自定义CommandBar

    各位好,再次回到UWP开发入门系列,刚回归可能有些不适应,所以今天我们讲个简单的,自定义CommandBar,说通俗点就是自定义类似AppBarButton的东西,然后扔到CommandBar中使用. ...

  5. UWP开发入门(25)——通过Radio控制Bluetooth, WiFi

    回顾写了许久的UWP开发入门,竟然没有讲过通过Windows.Devices.Radios.Radio来控制Bluetooth和WiFi等功能的开关.也许是因为相关的API设计的简单好用,以至于被我给 ...

  6. UWP开发入门(二十一)——保持Ui线程处于响应状态

    GUI的程序有时候会因为等待一个耗时操作完成,导致界面卡死.本篇我们就UWP开发中可能遇到的情况,来讨论如何优化处理. 假设当前存在点击按钮跳转页面的操作,通过按钮打开的新页面,在初始化过程中存在一些 ...

  7. UWP开发入门(十一)——Attached Property的简单应用

    UWP中的Attached Property即附加属性,在实际开发中是很常见的,比如Grid.Row: <Grid Background="{ThemeResource Applica ...

  8. UWP开发入门(二十三)——WebView

    本篇讨论在UWP开发中使用WebView控件时常见的问题,以及一些小技巧. WebView是实际开发中常用的控件,很多大家抱怨的套网页的应用都是通过WebView来实现的.这里要澄清一个问题,套网页的 ...

  9. UWP开发入门(七)——下拉刷新

    本篇意在给这几天Win10 Mobile负面新闻不断的某软洗地,想要证明实现一个简单的下拉刷新并不困难.UWP开发更大的困难在于懒惰,缺乏学习的意愿.而不是“某软连下拉刷新控件都没有”这样的想法. 之 ...

随机推荐

  1. 打包.a 文件时, build phases- Link Binary With Libraries

    打包.a 文件时, 如果是两个Targets那么可运行调试的  build phases-  Link Binary With Libraries  如果加入.a 文件. 那么就不需要在Compile ...

  2. 神舟K650c i7(W350STQ)上成功装好Mac OS X 10.9,兼谈如何安装WinXP、7、8.1、OSX、Ubuntu五系统(Chameleon、MBR)

    作者:zyl910 参考教程——http://bbs.pcbeta.com/viewthread-1432534-1-4.html笔记本SNB和IVY平台Win7/Win8/Win8.1安装OS X ...

  3. ASP.NET Core 获取控制器上的自定义属性

    /// <summary> /// 参考代码Microsoft.AspNetCore.Mvc.Internal.AuthorizationApplicationModelProvider ...

  4. Android上面安装Linux的方法

    方法一: 并行安装Linux(不在Android操作系统之上运行,需要设备已经unlocked并且rooted) 我还没玩过.放两个书签: How to Install Ubuntu on Andro ...

  5. 查看SqlAzure和SQLServer中的每个表数据行数

    SqlAzure中的方式: select t.name ,s.row_count from sys.tables t join sys.dm_db_partition_stats s ON t.obj ...

  6. Oracle 10gR2 & 10.2.0.5 的百度网盘下载地址 :)

    如题: https://pan.baidu.com/s/1eSI770m

  7. [ linux ] pad远程

    ---恢复内容开始--- ssh: serverauditor vnc:vnc viewer ubuntu: sudo apt-get install x11vnc sudo apt-get inst ...

  8. [AX2012 R3]在SSRS报表中使用QR二维码

    AX2012是自带生成QR二维码的类,可以很方便的用在SSRS报表中,下面演示如何在RDP的报表中使用二维码,首先从定义临时表开始: 字段URL是要用于二维码的字符串,QrCode是container ...

  9. mvc 分页视图 js 失效

    MVC的分页视图确实是好东西,比ajax直观,可是联动后 之前绑定的js事件失效,所以我们在绑定的时候,要注意使用jquery的 动态绑定功能 最常见的用法应该是 select 的 change 事件 ...

  10. [原创]Android Handler使用Message的一个注意事项

    最近发现了一个莫名其妙的问题,在使用Handler.post(Runnable)这个接口时,Runnable有时候没有运行,非常奇怪,后来发现是因为调用Handler.removeMessage()时 ...