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

UWP开发入门(四)——自定义CommandBar
原文:UWP开发入门(四)——自定义CommandBar

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

  话说为了在公司次世代平台级战略层产品上实现与水果和机器人一致的用户体验,美工把Win10 APPAppBar也画成左右分开的了,好看是好看了,问题原生的ComandBar控件不支持这么排列啊……头疼归头疼,只能再次展开山寨之路……

  初步思路是在CommandBar中塞进占位用的空白元素,我管它叫AppBarEmpty。那么能放进CommandBar中的元素需要符合什么样的规则呢?首先看一下CommandBar的用法:

<CommandBar><AppBarToggleButton Icon="Shuffle" Label="Shuffle" Click="AppBarButton_Click" /><AppBarToggleButton Icon="RepeatAll" Label="Repeat" Click="AppBarButton_Click"/><AppBarSeparator/><AppBarButton Icon="Back" Label="Back" Click="AppBarButton_Click"/><AppBarButton Icon="Stop" Label="Stop" Click="AppBarButton_Click"/><AppBarButton Icon="Play" Label="Play" Click="AppBarButton_Click"/><AppBarButton Icon="Forward" Label="Forward" Click="AppBarButton_Click"/><CommandBar.SecondaryCommands><AppBarButton Icon="Like" Label="Like" Click="AppBarButton_Click"/><AppBarButton Icon="Dislike" Label="Dislike" Click="AppBarButton_Click"/></CommandBar.SecondaryCommands><CommandBar.Content><TextBlock Text="Now playing..." Margin="12,14"/></CommandBar.Content>
</CommandBar>

上面这个常规的Command显示效果如下图:

  规律还是比较明显的,菜单“like”,“Dislike”均属于SecondaryCommands这个集合,和我们今天的主题关系不大。而最左侧的文字描述是放到CommandBarContent属性中,也无需理睬。我们需要实现的是将AppButton左右分开,这部分的按钮均属于PrimaryCommands这个集合,XAML没有看到是因为简化写法的缘故。

  既然属于PrimaryCommands集合的元素会被呈现在按钮区域,那么我们就检查一下该集合的类型定义:

public IObservableVector<ICommandBarElement> PrimaryCommands { get; }

  很明显该集合的元素需要实现接口ICommandBarElement,而该接口又非常简单:

    //// Summary://     Defines the compact view for command bar elements.[ContractVersion(typeof(UniversalApiContract), 65536)][GuidAttribute(1737592347, 62165, 17617, 139, 132, 146, 184, 127, 128, 163, 80)][WebHostHidden]public interface ICommandBarElement{//// Summary://     Gets or sets a value that indicates whether the element is shown with no label//     and reduced padding.//// Returns://     true if the element is shown in its compact state; otherwise, false. The default//     is false.System.Boolean IsCompact { get; set; }}

  这样我们的AppBarEmpty就好写了,仅仅需要实现一个IsCompact属性即可,而占位用的AppBarEmpty其实是没有内容的,连IsCompact的效果其实都省了……

    public class AppBarEmpty : FrameworkElement, ICommandBarElement{public bool IsCompact { get; set; }}

  是不是有种骗钱的感觉?别走啊,这里还是有讲究的,首先为什么是继承自FrameworkElement呢?

 1.AppEmpty是一个占位控件,基本不具备功能,应该从轻量级的基类继承

 2.FrameworkElement提供了占位所有的WidthHeight等属性,更基础的UIElement则没有这些

 3.FrameworkElement才开始支持的Binding

   搞清楚了以上这些之后,我们兴冲冲的把XAML补完了:

        <CommandBar><AppBarButton Icon="Accept" Label="Accept"></AppBarButton><AppBarButton Icon="Accept" Label="Accept"></AppBarButton><local:AppBarEmpty></local:AppBarEmpty><AppBarButton Icon="Accept" Label="Accept"></AppBarButton></CommandBar>

  行云流水编译一次通过,嗷嗷的按下F5运行……结果傻眼了……什么效果也没有……介个是为什么呢?

  只能通过Live Tree View来检查了(后面会写一篇介绍Live Tree View,这货简直是神器,现在没有它都不知道怎么调试了……),检查发现AppBarEmptyWidht0,而PrimaryCommands集合里的这些按钮又都是放在StackPanel里横向顺序排开的,悲剧的是StackPanleWidth就是几个AppBarButtonWidth总和,完全没有留给AppBarEmpty一丝丝的宽度……设置AppBarEmptyHorizontalAlignment=StretchStackPanel是然并卵……

  CommanBar模板PrimaryCommands部分节选:

              <ItemsControlx:Name="PrimaryItemsControl"HorizontalAlignment="Right"MinHeight="{ThemeResource AppBarThemeMinHeight}"IsTabStop="False"Grid.Column="1"><ItemsControl.ItemsPanel><ItemsPanelTemplate><StackPanel Orientation="Horizontal" /></ItemsPanelTemplate></ItemsControl.ItemsPanel></ItemsControl>

  悲剧啊!既然HorizontalAlignment不管用,无法自行撑开。那我们就只有给AppBarEmpty绑定一个确实的Width了。对应的XAML如下:

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"><Grid.RowDefinitions><RowDefinition></RowDefinition><RowDefinition Height="Auto"></RowDefinition><RowDefinition Height="Auto"></RowDefinition><RowDefinition x:Name="RowBottom" Height="Auto"></RowDefinition></Grid.RowDefinitions><TextBox Grid.Row="1"> </TextBox><CommandBar x:Name="commandBar" Grid.Row="2"><AppBarButton x:Name="appbarButton" Icon="Accept" Label="Accept"></AppBarButton><AppBarButton Icon="Accept" Label="Accept"></AppBarButton><local:AppBarEmpty Width="{x:Bind TestWidth,Mode=OneWay}"></local:AppBarEmpty><AppBarButton Icon="Accept" Label="Accept"></AppBarButton></CommandBar></Grid>

  为AppBarEmpty做了XBindTestWidth属性上,相应的Page的代码里定义了该属性,并在PageSizeChanged事件中计算了AppBarEmpty实际需要的宽度。

    public sealed partial class MainPage : Page, INotifyPropertyChanged{public double TestWidth { get; set; }public MainPage(){this.InitializeComponent();this.SizeChanged += MainPage_SizeChanged;}public event PropertyChangedEventHandler PropertyChanged;private void MainPage_SizeChanged(object sender, SizeChangedEventArgs e){int count = this.commandBar.PrimaryCommands.Count-1;double width = (this.commandBar.PrimaryCommands[0] as AppBarButton).ActualWidth;TestWidth = e.NewSize.Width - count* width -48;this.OnPropertyChanged("TestWidth");}public void OnPropertyChanged([CallerMemberName]string name = null){this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));}}

  代码中减掉的48CommandBar最右边“”按钮的宽度。实际显示如下图:

 

这里仍然存在几个问题:

 

1.有童鞋说为什么不自己写个RelativePanel,然后里面的按钮就可以随便对齐定位了。

  该方法确实可行,但等于抛弃了CommandBar,也无法集成到PageTopAppBarBottomAppBar中使用。有点偏离了我们自定义CommadBar的初衷。并且要想完整实现一套CommandBar的工作量还是不小的

 

2.实现的方式不够优美,竟然使用了SizeChanged事件来计算Width。简直返古到了WinForm的时代。

哼哼,兄弟我不想好解决方案敢写这篇被你们骂?当然是已经准备好了完美的解决方案才来写这篇钓鱼咯,乖乖给我点个推荐,然后我们下周见……

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted on 2017-09-20 13:24 NET未来之路 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/lonelyxmas/p/7560967.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/369196.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(转)Cobbler无人值守批量安装Linux系统

本文目录&#xff1a; 1.1 pxe安装系统 1.2 cobbler基本介绍 1.3 安装和配置cobbler 1.3.1 安装cobbler 1.3.2 配置dhcp和tftp 1.4 cobbler从本地光盘安装系统 1.4.1 生成distro 1.4.2 提供kickstart文件 1.4.3 提供profile 1.4.4 开始安装 1.5 比pxekickstart好的地方 1.6 让新…

Spring集成–从头开始应用程序,第1部分

开始之前 在本教程中&#xff0c;您将学习什么是Spring Integration &#xff0c;如何使用它以及有助于解决哪些问题。 我们将从头开始构建一个示例应用程序&#xff0c;并演示Spring Integration的一些核心组件。 如果您不熟悉Spring&#xff0c;请查看我编写的另一本有关Spri…

初学者Web介绍一些前端开发中的基本概念用到的技术

Web开发是比较费神的&#xff0c;需要掌握很多很多的东西&#xff0c;特别是从事前端开发的朋友&#xff0c;需要通十行才行。今天&#xff0c;本文向初学者介绍一些Web开发中的基本概念和用到的技术&#xff0c;从A到Z总共26项&#xff0c;每项对应一个概念或者技术。 初学者W…

Xcode 快捷键及代码格式化

按住apple键点击类名就可以定位到这个类中查看相关定义&#xff08;在日后的开发中我们会经常这么来做&#xff0c;毕竟要记住iOS开发中所有的API是不现实的&#xff0c;有些API我们可以通过这种方法来查找&#xff09; PS&#xff1a;下面都是网上百度后经过我自己整理&#x…

主席树学习小结(POJ 2104)

在高中的时候就听到过主席树了&#xff0c;感觉非常高端&#xff0c;在寒假的时候 winter homework中有一题是查找区间第K大的树&#xff0c;当时就开始百度这种网上的博客&#xff0c;发现主席树看不懂&#xff0c;因为那个root[i]&#xff0c;还有tx[x].l与tx[x].r是什么意思…

下拉菜单

<!Doctype html> <html> <head> <meta charset"utf-8"> <title>下拉菜单</title> <style> *{ margin:0; padding:0; } ul{ list-style:none; overflow:hidden; background-color:#333; } li{ float:left; } li a,.drop…

deepin下Clion连接mysql_CLion如何添加依赖库 ? 需要把mysql/Connector c++放入 用cpp连接数据库...

目前我把下载的mysql/Connector 下载后放在了project内 但是报错信息如下报错信息如下In file included from /Users/wsgdrfz/study/c/Libary_System/librarySystem/sqlConnection.h:/Users/wsgdrfz/study/c/Libary_System/librarySystem/sqlFiles/include/mysql_connection.h7…

[开源JVM] yvm - 自制Java虚拟机

中文 | English | | | YVM是用C写的一个Java虚拟机&#xff0c;现在支持Java大部分功能&#xff0c;以及一个基于标记清除算法的并发垃圾回收器. 不过还有很多bug等待修复。 感兴趣的朋友pull request/fork/star吧。 Github repo https://github.com/racaljk/yvm 已支持语言…

printf函数输出超出int时怎么办

int、long、long long在printf中的格式 https://blog.csdn.net/fz_ywj/article/details/8107582 蓝桥杯 2796. BASIC-11 十六进制转十进制 从键盘输入一个不超过8位的正的十六进制数字符串&#xff0c;将它转换为正的十进制数后输出。   注&#xff1a;十六进制数中的10~15…

升级glibc的影响_Java 11 升级:“债务”“危机”

导读&#xff1a;AJDK11(阿里内部基于openJDK11的定制版本)在19年3月左右发布&#xff0c;到现在也快1年了&#xff0c;不过目前整体使用的面还是比较窄&#xff0c;特性被了解的也不是很多&#xff0c;Java11作为OpenJDK发布的LTS版本&#xff0c;对我们来说&#xff0c;还是需…

The processing instruction target matching [xX][mM][lL] is not allowed.

原因&#xff1a;xml标签 必须在第一行。 转载于:https://www.cnblogs.com/wangkang0320/p/7569100.html

周五尾盘上涨,配合周末消息,周一套人的经典实例

吸取中国软件的教训&#xff1a;注意这次是温柔的&#xff0c;只是收了个十字星&#xff0c;因为前期上涨后的需要缓和调整一下&#xff0c;而不是为了出逃。以后注意找个出逃的例子1、上周五尾盘上涨2、周末利好消息3、周一开盘高开4、高开后快速下探&#xff08;5分钟内&…

Spring Data,MongoDB和JSF集成教程

示例应用程序简介&#xff08;MongoShop产品目录&#xff09; 在学习完本教程之后&#xff0c;将构建具有以下功能要求的示例应用程序&#xff08;MongoShop产品目录&#xff09;&#xff1a; 1.搜索具有不同条件的产品&#xff08;例如&#xff0c;sku&#xff0c;产品类型&am…

本人用python刷题时的错误总结

本人新手&#xff0c;在leetcode刷题过程中出现过很多问题&#xff0c;也发现了很多方法&#xff0c;故在此总结&#xff0c;不定时更新。 1、在创建一个二维列表的时候&#xff0c;我之前会用 a [[0] * 5] * 5, 但是这样输出的结果往往会跟期待的不一样&#xff0c;我一直以为…

增加 jQueryValidate的手机号验证功能

1、通过addMethod增加手机号的验证方法 &#xff08;位置&#xff1a;和$(form).validate({}) 同级别&#xff09; //增加手机号验证规则$.validator.addMethod("isMobile", function(value, element) {var length value.length;var mobile /^(13[0-9]{9})|(18[0-9…

Hibernate继承:每个类层次结构的表

在本教程中&#xff0c;我们将看到如何在hibernate中实现继承。有3种方法可以在hibernate中实现继承。在本文中&#xff0c;我们将看到其中一种&#xff0c;即每个类层次结构一个表。 休眠中的继承&#xff1a; Java是面向对象的语言&#xff0c;继承是Java的主要功能之一。关…

爬取新闻

import requests from bs4 import BeautifulSoup urlhttp://news.gzcc.cn/html/xiaoyuanxinwen/ resrequests.get(url) res.encodingutf-8 soupBeautifulSoup(res.text,html.parser) 1. 用requests库和BeautifulSoup库&#xff0c;爬取校园新闻首页新闻的标题、链接、正文。 fo…

平衡二叉树的自顶向下递归和自底向上递归

没太搞懂自顶向下和自底向上的递归区别

NI Multisim元件库:在Multisim中创建自定义元器件

转载于&#xff1a; http://www.ni.com/tutorial/3173/zhs/ 概览 「在Multisim中创建自定义元器件」与「在 NI Ultiboard中创建自定义元器件」为您提供了关于如何直观、快速地学习如何创建您自己的自定义元器件的信息资源。目录 引言步骤一&#xff1a;输入初始元器件信息步骤二…