zoukankan      html  css  js  c++  java
  • Windows Phone 虚拟键盘导致页面推动解决

    相信几乎所有的Windows Phone开发者都会遇到这种情况:

    在页面试用了可输入的控件比如TextBox,当TextBox获取到焦点时,无可厚非虚拟键盘会从屏幕底部滑动出现。有时候就会出现“诡异”的现象(做久一点的WP开发者已经习惯了)—整个页面也会向上推动,导致呢一些控件已经移动出了屏幕的显示边界。这种结果不论是开发者还是用户都会觉得在体验上不是太好。

    对于这种情况,通常的做法是压缩TextBox的高度,尽量降低屏幕整体上推的可能性。这样虽然可以通过不断的调整,最终找到一个平衡的高度使页面基本不上推。但总是感觉到受制于人—有输入框页面的设计都要去考虑到这种情况。

    为了最终解决此种情况,不得不使用别的小技巧去实现。废话不多说,上码:

    using Microsoft.Phone.Controls;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Data;
    using System.Windows.Media;
    
    namespace SinaWeibo.UserControls.CustomPage
    {
        /// <summary>
        /// 需要虚拟键盘的页面.避免虚拟键盘出现的时候整个页面向上移动,导致某些区域不在可见区域.
        /// </summary>
        public class SIPPage : PhoneApplicationPage
        {
            private bool isSIPVisibleGuess = false;
            private PhoneApplicationFrame frame;
    
            public SIPPage()
            {
                BindingSIP();
            }
    
            private void BindingSIP()
            {
                frame = (App.Current as App).RootFrame;
                Binding yTransfrom = new Binding("Y");
                yTransfrom.Source = (frame.RenderTransform as TransformGroup).Children[0] as TranslateTransform;
                SetBinding(RootFrameTransformProperty, yTransfrom);
            }
    
            public double RootFrameTransform
            {
                get { return (double)GetValue(RootFrameTransformProperty); }
                set { SetValue(RootFrameTransformProperty, value); }
            }
    
            // Using a DependencyProperty as the backing store for RootFrameTransform.  This enables animation, styling, binding, etc...
            public static readonly DependencyProperty RootFrameTransformProperty =
                DependencyProperty.Register("RootFrameTransform", typeof(double), typeof(SIPPage), new PropertyMetadata(OnRootFrameTransformChanged));
    
            static void OnRootFrameTransformChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
            {
                double newValue = (double)e.NewValue;
                SIPPage sipView = source as SIPPage;
                if (newValue < 0.0)
                {
                    sipView.isSIPVisibleGuess = true;
    
                    if (sipView.frame != null)
                    {
                        // 恢复已经移动的距离.
                        var trans = (sipView.frame.RenderTransform as TransformGroup).Children[0] as TranslateTransform;
                        trans.Y += Math.Abs(newValue);
                    }
                }
                else if (newValue == 0)
                {
                    sipView.isSIPVisibleGuess = false;
                }
    #if DEBUG
                else
                    System.Diagnostics.Debug.Assert(false, "I assumed this would never happen, let me know if it does");
    #endif
            }
        }
    }

    可以观察得到,我们新建一个页面时。都是继承自PhoneApplicationPage,为了更加通用,这里的SIPPage也继承自PhoneApplicationPage。由于上述情况中,页面发生位置偏移,说明是触发了页面级的TranslateTransform。此段代码中首先是查找到RootFrame的TranslateTransform,并将竖直方向的偏移量绑定到一个自定义的依赖属性上。声明依赖属性的目的也是为了监听到页面界别TranslateTransform在竖直方向的偏移量。在OnRootFrameTransformChanged中就能得知竖直位移量。如果发生了位置移动,仅需此时再把偏移量给抵消掉,页面就不会再发生移动了。一开始的问题也就得到了比较好的解决。

    以后只要是有输入框的页面全都继承自SIPPage就行了,记得还要修改Xaml中的页面申明:

    <customPage:SIPPage
        x:Class="Any.Do.View.TestAppBar"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
        xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:customPage="clr-namespace:Any.Do.CustomPage"
        FontFamily="{StaticResource PhoneFontFamilyNormal}"
        FontSize="{StaticResource PhoneFontSizeNormal}"
        Foreground="{StaticResource PhoneForegroundBrush}"
        SupportedOrientations="Portrait" Orientation="Portrait"
        mc:Ignorable="d"
        shell:SystemTray.IsVisible="True">
    <!--Xaml goes here-->
    </phone:PhoneApplicationPage>

    最后,对于此类问题,如果微软能够在系统底层彻底解决或许才是终极解决方案,可是MS的步调去总是那么慢,所以Enjoy this code!

    参考文章原文地址:http://blogs.msdn.com/b/jaimer/archive/2010/11/05/guessing-if-the-sip-is-visible-in-a-windows-phone-application.aspx

  • 相关阅读:
    汉字乱码、加密后结果字符串不一致
    msgpack和TParams互相转换
    unigui监听会话开始和结束
    System.JSON.Builders.pas
    保证最终一致性的模式
    使用 Delta Sharing 协议进行数据共享
    dremio 16 升级问题
    graylog 4.0 运行
    supabase 开源firebase 可选工具
    cube.js 最新playground 说明
  • 原文地址:https://www.cnblogs.com/navigator/p/3030089.html
Copyright © 2011-2022 走看看