在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", string.Format("{0}px", 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", string.Format("{0}px", 0));
            divIndicatorName.SetStyleAttribute("top", string.Format("{0}px", 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", string.Format("{0}px", left));
            divIndicatorName.SetStyleAttribute("top", string.Format("{0}px", 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,1" CornerRadius="2,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>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值