siliverlight windowless=true 模式下禁止输入中文
微软官网说明:https://msdn.microsoft.com/zh-cn/library/cc838156(VS.95).aspx
让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:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Net; 5 using System.Windows; 6 using System.Windows.Controls; 7 using System.Windows.Documents; 8 using System.Windows.Input; 9 using System.Windows.Media; 10 using System.Windows.Media.Animation; 11 using System.Windows.Shapes; 12 using System.Windows.Browser; 13 14 namespace Sl.Input 15 { 16 /// <summary> 17 /// 使用的时候请在sl宿主页面加入样式 18 /// .inputcss 19 /// { 20 /// border-collapse: collapse; 21 /// border: solid 0px Transparent; background-color: Transparent; 22 23 /// } 24 /// .divInputcss 25 /// { 26 27 /// border: solid 0px Transparent; background-color:Transparent; 28 /// position: absolute; display: none; z-index:1000; 29 30 /// } 31 /// </summary> 32 public partial class SLInput : UserControl 33 { 34 HtmlElement divIndicatorName; 35 HtmlElement txtIndicatorNameElements; 36 public delegate void KeyDownHandel(object sender, string keyCode); 37 public event KeyDownHandel KeyDownHandelEvent; 38 public SLInput() 39 { 40 InitializeComponent(); 41 System.Windows.Interop.SilverlightHost host = Application.Current.Host; 42 System.Windows.Interop.Settings setting = host.Settings; 43 bool isWindowless = setting.Windowless; 44 45 if (isWindowless == true) 46 { 47 CreateHtmlElement(); 48 this.SizeChanged += new SizeChangedEventHandler(EsmsInput_SizeChanged); 49 this.txtBox.Visibility = Visibility.Collapsed; 50 this.txtIndicatorName.Visibility = Visibility.Visible; 51 } 52 } 53 /// <summary> 54 /// 当这个控件大小发生了变化,需要重新调整input的大小 55 /// </summary> 56 void EsmsInput_SizeChanged(object sender, SizeChangedEventArgs e) 57 { 58 divIndicatorName.SetStyleAttribute("width", e.NewSize.Width.ToString() + "px"); 59 divIndicatorName.SetStyleAttribute("heght", e.NewSize.Height.ToString() + "px"); 60 txtIndicatorNameElements.SetStyleAttribute("width", e.NewSize.Width.ToString() + "px"); 61 txtIndicatorNameElements.SetStyleAttribute("heght", e.NewSize.Height.ToString() + "px"); 62 } 63 /// <summary> 64 /// 创建一个input 元素作为输入设备 65 /// </summary> 66 void CreateHtmlElement() 67 { 68 divIndicatorName = HtmlPage.Document.CreateElement("div"); 69 txtIndicatorNameElements = HtmlPage.Document.CreateElement("input"); 70 divIndicatorName.AppendChild(txtIndicatorNameElements); 71 divIndicatorName.SetStyleAttribute("display", "none"); 72 divIndicatorName.SetStyleAttribute("position", "absolute"); 73 divIndicatorName.SetStyleAttribute("z-index", "10000"); 74 divIndicatorName.SetStyleAttribute("left", string.Format("{0}px", 0)); 75 divIndicatorName.SetStyleAttribute("top", string.Format("{0}px", 0)); 76 //这个样式必须放在html中,动态生成的样式不起作用,原因不明 77 divIndicatorName.CssClass = "divInputcss"; 78 txtIndicatorNameElements.SetStyleAttribute("background-color", "Transparent"); 79 //这个样式必须放在html中,动态生成的样式不起作用,原因不明 80 txtIndicatorNameElements.CssClass = "inputcss"; 81 HtmlPage.Document.Body.AppendChild(divIndicatorName); 82 txtIndicatorNameElements.AttachEvent("onblur", new EventHandler(onLostFocus)); 83 //注册一个keydown事件用于托管代码中调用 84 txtIndicatorNameElements.AttachEvent("onkeydown", new EventHandler(onExecuteQueryByonKeyDown)); 85 //这是一个用border画的虚假的输入框,当它被点击的时候,显示input元素,并定位到这个border上面 86 this.bdInputName.MouseLeftButtonDown += new MouseButtonEventHandler(bdInputName_MouseLeftButtonDown); 87 } 88 89 private void onLostFocus(object sender, EventArgs e) 90 { 91 hideHtmlElementByResize(null, null); 92 } 93 private void onExecuteQueryByonKeyDown(object sender, EventArgs e) 94 { 95 if (KeyDownHandelEvent != null) 96 { 97 string keyCode = HtmlPage.Window.Eval("event.keyCode").ToString(); 98 KeyDownHandelEvent(this, keyCode); 99 } 100 } 101 private void hideHtmlElementByResize(object sender, EventArgs e) 102 { 103 divIndicatorName.SetStyleAttribute("display", "none"); 104 divIndicatorName.SetStyleAttribute("left", string.Format("{0}px", 0)); 105 divIndicatorName.SetStyleAttribute("top", string.Format("{0}px", 0)); 106 this.txtIndicatorName.Text = txtIndicatorNameElements.GetAttribute("value"); 107 this.txtIndicatorName.Opacity = 1; 108 Application.Current.Host.Content.Resized -= new EventHandler(hideHtmlElementByResize); 109 } 110 void bdInputName_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 111 { 112 Point posRoot = e.GetPosition(null); 113 Point posRela = e.GetPosition(this.bdInputName); 114 double left = posRoot.X - posRela.X + 2; 115 double top = posRoot.Y - posRela.Y + 2; 116 divIndicatorName.SetStyleAttribute("display", "block"); 117 divIndicatorName.SetStyleAttribute("left", string.Format("{0}px", left)); 118 divIndicatorName.SetStyleAttribute("top", string.Format("{0}px", top)); 119 divIndicatorName.SetStyleAttribute("position", "absolute"); 120 txtIndicatorNameElements.SetAttribute("value", this.txtIndicatorName.Text); 121 txtIndicatorNameElements.Focus(); 122 this.txtIndicatorName.Opacity = 0; 123 Application.Current.Host.Content.Resized += new EventHandler(hideHtmlElementByResize); 124 } 125 public double EsmsWidth 126 { 127 set 128 { 129 this.bdInputName.Width = value; 130 EsmsInputWidth = value; 131 } 132 get 133 { 134 return this.bdInputName.Width; 135 } 136 } 137 public double EsmsHeight 138 { 139 set 140 { 141 this.bdInputName.Height = value; 142 EsmsInputHeight = value; 143 } 144 get 145 { 146 return this.bdInputName.Height; 147 } 148 } 149 public double EsmsInputWidth 150 { 151 set 152 { 153 if (this.txtIndicatorNameElements != null) 154 { 155 this.txtIndicatorNameElements.SetStyleAttribute("width", (value - 4).ToString()); 156 this.divIndicatorName.SetStyleAttribute("width", (value - 4).ToString()); 157 this.txtIndicatorName.Width = value; 158 } 159 } 160 get 161 { 162 return this.bdInputName.Width; 163 } 164 } 165 public double EsmsInputHeight 166 { 167 set 168 { 169 if (this.txtIndicatorNameElements != null) 170 { 171 this.txtIndicatorNameElements.SetStyleAttribute("height", (value - 4).ToString()); 172 this.divIndicatorName.SetStyleAttribute("height", (value - 4).ToString()); 173 } 174 } 175 get 176 { 177 return this.bdInputName.Height; 178 } 179 } 180 public string Text 181 { 182 get 183 { 184 if (txtIndicatorNameElements != null) 185 { 186 this.txtIndicatorName.Text = txtIndicatorNameElements.GetAttribute("value"); 187 } 188 return this.txtIndicatorName.Text; 189 } 190 set 191 { 192 this.txtIndicatorName.Text = value; 193 if (txtIndicatorNameElements != null) 194 { 195 txtIndicatorNameElements.SetAttribute("value", value ?? ""); 196 } 197 } 198 } 199 } 200 }
xaml:
1 <UserControl x:Class="Sl.Input.SLInput" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 4 <Grid x:Name="LayoutRoot"> 5 <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"> 6 <Border.Background> 7 <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> 8 <GradientStop Color="#FFEFFAFE"/> 9 <GradientStop Color="#FFD6F0FA" Offset="1"/> 10 </LinearGradientBrush> 11 12 </Border.Background> 13 <Grid> 14 <TextBox x:Name="txtBox" Visibility="Visible"></TextBox> 15 <TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Height="Auto" Margin="2" x:Name="txtIndicatorName" Text="" Width="Auto" TextWrapping="NoWrap" FontFamily="MS Reference Sans Serif" Visibility="Collapsed"> 16 17 </TextBlock> 18 </Grid> 19 </Border> 20 </Grid> 21 </UserControl>
引用代码:
1 <userControls:SLInput x:Name="txt" ></userControls:SLInput>
源文链接:http://blog.csdn.net/swqqcs/article/details/12233611