微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在windowless=true的条件下让silverlight输入中文


让silverlight在windowless=ture的条件下输入中文。大家都知道,silverligt2.0 和最新的3.0再windowless=true的条件下都无法输入中文,那么我们就必须采用一种迂回的方式解决

  有以下几种方式可以考虑:

  1、在代码执行过程中动态改变windowless 属性。最初的想法是党textBox获取焦点的时候,让windowless =flase,失去焦点的时候在还原回去 。很不幸,windowless 无法动态更改(只读属性)。

  2、用一个html的input元素来充当输入设备,漂浮在一个假的输入框上。经过我的尝试,效果很不错。足以以假乱真。

缺点是必须在宿主html页面上加两个css样式。我也不知道为什么sl动态生成的有些样式不起作用,只能从从html页面加载才可以。

  按照第二条想法,我封装了一个输入控件,在自己的项目中用,感觉还是可以解决问题。当然还是希望微软在日后把这个不支持输入中文的Bug修复。

  为了支持windowless=false,在程序中判断该属性,来决定是用内置的textBox作为输入设备还是使用input作为输入设备。

  截了两张图:

   输入的时候:

   显示的时候:

      实现代码如下:

  cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.browser;


namespace Sl.Input
{   
    /// <summary>
    /// 使用的时候请在sl宿主页面加入样式
    /// .inputcss
    /// {
    ///     border-collapse: collapse;
    ///     border: solid 0px Transparent; background-color: Transparent;
            
    /// }
    /// .divInputcss
    /// {
        
    ///     border: solid 0px Transparent; background-color:Transparent;
    ///      position: absolute; display: none; z-index:1000;
            
    /// }
    /// </summary>
    public partial class SLInput : UserControl
    {

        HtmlElement divIndicatorName;
        HtmlElement txtIndicatorNameElements;
        public delegate void KeyDownHandel(object sender,string keyCode);
        public event KeyDownHandel KeyDownHandelEvent;
        public SLinput()
        {
            InitializeComponent();
            System.Windows.Interop.SilverlightHost host = Application.Current.Host;
            System.Windows.Interop.Settings setting = host.Settings;
            bool iswindowless = setting.windowless;
            
            if (iswindowless == true)
            {
                CreateHtmlElement();
                this.SizeChanged += new SizeChangedEventHandler(EsmsInput_SizeChanged);
                this.txtBox.Visibility = Visibility.Collapsed;
                this.txtIndicatorName.Visibility = Visibility.Visible;

            }
        }
        /// <summary>
        /// 当这个控件大小发生了变化,需要重新调整input的大小
        /// </summary>
        void EsmsInput_SizeChanged(object sender,SizeChangedEventArgs e)
        {
            divIndicatorName.SetStyleAttribute("width",e.NewSize.Width.ToString() + "px");
            divIndicatorName.SetStyleAttribute("heght",e.NewSize.Height.ToString() + "px");
            txtIndicatorNameElements.SetStyleAttribute("width",e.NewSize.Width.ToString() + "px");
            txtIndicatorNameElements.SetStyleAttribute("heght",e.NewSize.Height.ToString() + "px");

        }
        /// <summary>
        /// 创建一个input 元素作为输入设备
        /// </summary>
        void CreateHtmlElement()
        {
            divIndicatorName = HtmlPage.Document.CreateElement("div");
            txtIndicatorNameElements = HtmlPage.Document.CreateElement("input");
            divIndicatorName.AppendChild(txtIndicatorNameElements);
            divIndicatorName.SetStyleAttribute("display","none");
            divIndicatorName.SetStyleAttribute("position","absolute");
            divIndicatorName.SetStyleAttribute("z-index","10000");
            divIndicatorName.SetStyleAttribute("left",string.Format("{0}px",0));
            divIndicatorName.SetStyleAttribute("top",0));
            //这个样式必须放在html中,动态生成的样式不起作用,原因不明
            divIndicatorName.CssClass = "divInputcss";
            txtIndicatorNameElements.SetStyleAttribute("background-color","Transparent");
            //这个样式必须放在html中,动态生成的样式不起作用,原因不明
            txtIndicatorNameElements.CssClass = "inputcss";
            HtmlPage.Document.Body.AppendChild(divIndicatorName);
            txtIndicatorNameElements.AttachEvent("onblur",new EventHandler(onLostFocus));

            //注册一个keydown事件用于托管代码调用
            txtIndicatorNameElements.AttachEvent("onkeydown",new EventHandler(onExecuteQueryByonKeyDown));
            //这是一个用border画的虚假的输入框,当它被点击的时候,显示input元素,并定位到这个border上面
            this.bdInputName.MouseLeftButtonDown += new MouseButtonEventHandler(bdInputName_MouseLeftButtonDown);
        }


        private void onLostFocus(object sender,EventArgs e)
        {
            hideHtmlElementByResize(null,null);
        }

        private void onExecuteQueryByonKeyDown(object sender,EventArgs e)
        {
            if (KeyDownHandelEvent != null)
            {
                string keyCode = HtmlPage.Window.Eval("event.keyCode").ToString();
                KeyDownHandelEvent(this,keyCode);
            }
        }

        private void hideHtmlElementByResize(object sender,EventArgs e)
        {
            divIndicatorName.SetStyleAttribute("display","none");
            divIndicatorName.SetStyleAttribute("left",0));
            this.txtIndicatorName.Text = txtIndicatorNameElements.GetAttribute("value");

            this.txtIndicatorName.Opacity = 1;
            Application.Current.Host.Content.Resized -= new EventHandler(hideHtmlElementByResize);
        }

        void bdInputName_MouseLeftButtonDown(object sender,MouseButtonEventArgs e)
        {
            Point posRoot = e.GetPosition(null);
            Point posRela = e.GetPosition(this.bdInputName);
            double left = posRoot.X - posRela.X + 2;
            double top = posRoot.Y - posRela.Y + 2;

            divIndicatorName.SetStyleAttribute("display","block");
            divIndicatorName.SetStyleAttribute("left",left));
            divIndicatorName.SetStyleAttribute("top",top));
            divIndicatorName.SetStyleAttribute("position","absolute");
            txtIndicatorNameElements.SetAttribute("value",this.txtIndicatorName.Text);
            txtIndicatorNameElements.Focus();
            this.txtIndicatorName.Opacity = 0;
            Application.Current.Host.Content.Resized += new EventHandler(hideHtmlElementByResize);
        }
        public double EsmsWidth
        {
            set
            {
                this.bdInputName.Width = value;
                EsmsInputWidth = value;
            }
            get
            {
                return this.bdInputName.Width;
            }
        }
        public double EsmsHeight
        {
            set
            {
                this.bdInputName.Height = value;
                EsmsInputHeight = value;
            }
            get
            {
                return this.bdInputName.Height;
            }
        }
        public double EsmsInputWidth
        {
            set
            {
                if (this.txtIndicatorNameElements != null)
                {
                    this.txtIndicatorNameElements.SetStyleAttribute("width",(value - 4).ToString());
                    this.divIndicatorName.SetStyleAttribute("width",(value - 4).ToString());
                    this.txtIndicatorName.Width = value;
                }
            }
            get
            {
                return this.bdInputName.Width;
            }
        }
        public double EsmsInputHeight
        {
            set
            {

                if (this.txtIndicatorNameElements != null)
                {
                    this.txtIndicatorNameElements.SetStyleAttribute("height",(value - 4).ToString());
                    this.divIndicatorName.SetStyleAttribute("height",(value - 4).ToString());
                }
            }
            get
            {
                return this.bdInputName.Height;
            }
        }
        public string Text
        {
            get
            {
                if (txtIndicatorNameElements != null)
                {
                    this.txtIndicatorName.Text = txtIndicatorNameElements.GetAttribute("value");
                }
                return this.txtIndicatorName.Text;
            }
            set
            {
                this.txtIndicatorName.Text = value;
                if (txtIndicatorNameElements != null)
                {
                    txtIndicatorNameElements.SetAttribute("value",value ?? "");
                }
            }
        }
    }
}

xaml:

<UserControl x:Class="Sl.Input.SLInput"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">     <Grid x:Name="LayoutRoot">         <Border MinWidth="50" MinHeight="22" Grid.Column="1" BorderThickness="1,1,1" CornerRadius="2,2,2" x:Name="bdInputName" ToolTipService.ToolTip="模糊查询" BorderBrush="#FF005D93">             <Border.Background>                 <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">                     <GradientStop Color="#FFEFFAFE"/>                     <GradientStop Color="#FFD6F0FA" Offset="1"/>                 </LinearGradientBrush>                              </Border.Background>             <Grid>             <TextBox x:Name="txtBox" Visibility="Visible"></TextBox>             <TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Height="Auto" Margin="2" x:Name="txtIndicatorName" Text="" Width="Auto" textwrapping="Nowrap" FontFamily="MS Reference Sans Serif" Visibility="Collapsed">                          </TextBlock>                 </Grid>         </Border>     </Grid> </UserControl>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐