• UWP中实现自定义标题栏


    UWP中实现自定义标题栏

    0x00 起因

    在UWP开发中,有时候我们希望实现自定义标题栏,例如在标题栏中加入搜索框、按钮之类的控件。搜了下资料居然在一个日文网站找到了一篇介绍这个主题的文章:

    http://www.atmarkit.co.jp/ait/articles/1510/14/news022.html

    看了下本想着翻译过来分享,但有些地方说的不是特别明确,所以自己实现了下,结合自己的体会总结了这篇文章。

    0x01 UWP中的标题栏

    一个普通的UWP窗口如下图所示:

     

    我们可以通过两种方式获取不同的标题栏对象,不同对象操作侧重点不同。

    var coreTitleBar = Windows.ApplicationModel.Core.CoreApplication.GetCurrentView().TitleBar;

    这种方式获取的是一个CoreApplicationViewTitleBar对象,主要控制标题栏扩展等相关功能。后面的coreTitleBar指的就是这个对象。

    var appTitleBar = Windows.UI.ViewManagement.ApplicationView.GetForCurrentView().TitleBar;

    这种方式获取的是一个ApplicationViewTitleBar对象,主要用于控制标题栏背景色,最小化、最大化、关闭等按钮的颜色、背景色等。后面的appTitleBar指的就是这个对象。

    我们自定义标题栏时这两个对象都会用到。

    0x02 实现自定义标题栏

    coreTitleBar中有一个属性为ExtendViewIntoTitleBar,将其设置为true就允许将我们在窗体中用XAML定义的视图扩展至标题栏区域

    coreTitleBar.ExtendViewIntoTitleBar = true;

    这个设置后标题栏原有的地方就消失了,我们定义的试图扩展了过去,如下图所示:

     

    看上去离我们的目标近了一些,标题栏消失了,我们在XAML中定义的Grid上移占据了原有标题栏的位置,原有的appTitleBar上的最大化、最小化、关闭按钮都可用。如果只是一副图片扩展至标题栏用作背景的话貌似可以了,不过我们希望在标题栏上加个搜索栏,所以还是存在几个问题的:

    appTitleBar的背景色不协调。

    要解决这个问题,我们需要把appTitleBar上按钮的背景色设置为透明:

    appTitleBar.ButtonBackgroundColor = Colors.Transparent;

    设置后窗体就变成这样了:

     

    按钮背景色变成了透明,但系统标题栏上的按钮和我们自定义标题栏上的搜索框重叠了。要解决这个问题我们可以利用coreTitleBar上的属性SystemOverlayLeftInset和SystemOverlayRightInset,分别表示了coreTitleBar嵌入时的左边距和右边距,我们可以通过设置自定义标题栏的Padding属性达到目的:

    //TitleBar为我们自己的标题栏
    TitleBar.Height = coreTitleBar.Height;
    TitleBar.Padding = new Thickness(
        coreTitleBar.SystemOverlayLeftInset,
        0,
        coreTitleBar.SystemOverlayRightInset,
        0 );

    那么在什么时候进行这个设置比较好呢,coreTitleBar有一个事件叫做LayoutMetricsChanged,当页面布局发生变化时触发,例如屏幕旋转导致页面重新布局就会触发这个事件。我们可以吧标题栏Padding属性的设置放在这个事件里。设置好后运行程序标题栏如下图所示:

     

    这样似乎好多了,但是当我想在搜索栏输入点内容时发现根本点不进去啊,放大镜按钮也没法点,按住搜索栏还能拖动窗口,看来是我们自己的标题栏被系统标题栏遮挡在下面了。

     

    大概就是上图这么一种感觉。

    对于这个问题,我们可以使用Window对象中的SetTitleBar()方法只把文字区域设置为标题栏:

    Window.Current.SetTitleBar(TitleText);

    其中TitleText是我们自定义标题栏中的文本控件的区域,这个方法就把TitleText这个控件设置为了标题栏。效果就是TitleText控件可以拖动窗体,双击可以最大化/恢复等。这样其他需要接收输入的控件就不属于标题栏,就可以正常接收输入了。

    另外我还考虑了一种方式就是重叠两层Grid,底层通过SetTitleBar设置为标题栏,放置不需要接收输入的控件如文本、图片等,上层放置需要接收输入的控件,如TextBox等,不过没有实际测试。

    除此之外还可以考虑给标题栏加入返回按钮,按钮调用Frame.GoBack()方法,根据Frame.CanGoBack属性决定返回按钮是否显示。这个也很容易实现,就不作说明了。

    程序最后运行效果如图所示,其中手机终端本身就不显示标题栏

    0x03 相关下载

    https://github.com/durow/TestArea/tree/master/UWPTest/TitleBarTest


    更多内容欢迎访问我的博客:http://www.durow.vip

  • 相关阅读:
    mysql_query()
    list()
    mysql_num_rows()
    当工程师戈登·摩尔提出摩尔定律的时候,电脑还像冰箱那样笨重,然而这条定律最终成为了整个硅谷的基石
    人机大战结束:AlphaGo 4:1 击败李世石
    云栖小镇—阿里特色的云计算生态系统
    2015年云栖大会:85天盖起来的大会,逾2万人参会,“计算为了无法计算的价值”
    [2015舟山马拉松]王坚:从云栖小镇到舟山马拉松,看中国经济中心的迁移
    云栖小镇的未来
    马云办“穷人银行”,阿里小贷问世,在线的信用成为财富
  • 原文地址:https://www.cnblogs.com/durow/p/4897773.html
Copyright © 2020-2023  润新知