SilverLight3 Cool开发(一) BingAPI实现手写搜索框
前言
此实例由Csdn讲师栾轩开发,本人也只是初学SilverLight,出于学习目的将此自己的开发过程与大家分享,并提供源码,欢迎共同探讨进步。
第一步:创建一个SilverLightApplication
创建后会出现一个对话框,SilverLight版本可以选择2.0或3.0,这里选择3.0。Project Type选择默认(如果仅做一个插件就不需要Web支持)。确认,项目已经建成了。
第二步,UI设计
将Grid改为StackPanel,StackPanel用于水平或垂直排列控件,支持嵌套。
InkPresenter,这是手写输入的模块,注意这是的MouseMove等事件的方法名在VS2008中通过Tab调出,在这里输入=号后会出现提
示,这里选择New Events Handle,后台会自动生成此事件的方法。
ProgressBar 进度条 通过Visibility属性控制是否滚动显示
ScrollViewer 自适应容器,由于手写输入的识别相似结果会很多,这里用到可以自适应高度
ListBox 用来显示通过Bing Api查询出的结果
1 | <StackPanel x:Name="LayoutRoot" Orientation="Vertical"> |
2 | <InkPresenter x:Name="InkCanvas" Height="150" Background="LightBlue" |
3 | MouseMove="InkCanvas_MouseMove" |
4 | MouseLeftButtonDown="InkCanvas_MouseLeftButtonDown" |
5 | MouseLeftButtonUp="InkCanvas_MouseLeftButtonUp" |
6 | MouseLeave="InkCanvas_MouseLeave" |
7 | /> |
8 | <StackPanel Orientation="Horizontal"> |
9 | <ProgressBar x:Name="PROGRESS" |
10 | Visibility="Collapsed" |
11 | IsIndeterminate="True" |
12 | Width="40"/> |
13 | <Button x:Name="Clear" Content="清空" Click="Clear_Click"/> |
14 | <ScrollViewer HorizontalScrollBarVisibility="Auto" |
15 | VerticalScrollBarVisibility="Hidden"> |
16 | <StackPanel x:Name="Results" |
17 | Orientation="Horizontal" |
18 | Margin="30,0,0,0"/> |
19 | </ScrollViewer> |
20 | </StackPanel> |
21 | <ListBox x:Name="SearchResultPanel"></ListBox> |
22 | </StackPanel> |
预览效果如下
第三步,手写识别
1.手写识别是WCF才有的,我们只能通过WebService来处理这些结果,然后传给页面。新建一个WCF Service,用默认的命名就可以了
2.打开服务的CodeBehind
添加引用
using System.Windows.Ink;
using System.Windows.Input;
打到当前系统下的"IAWinFX.dll" "IACore.dll"(如图) ,C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin下的IALoader.dll,C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\WindowsBase.dll
C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\PresentationCore.dll
总共是5个dll,在VS2008里只引用前三个就够了,没想到VS2010里面会这么多,在这里卡壳了,最终还是找到了这个PresentationCore.dll。
Code:将客户端传入的手写数据转换为字符串数组
将DoWork方法改为:
1 | public List<string> ConvertInkToString(List<List<List<double>>> Data) |
2 | { |
3 | try |
4 | { |
5 | // 还原Data |
6 | StrokeCollection sc = new StrokeCollection();//WCF识别的笔画集,silverlight识别的WCF识别的笔画集类型相同,但里面的架构信息不同 |
7 | foreach (var strokeData in Data) |
8 | { |
9 | StylusPointCollection SPCData = new StylusPointCollection();//添加点集 |
10 | foreach (var PointData in strokeData) |
11 | { |
12 | StylusPoint sPoint = new StylusPoint(PointData[0], PointData[1]);//添加点 |
13 | SPCData.Add(sPoint); |
14 | } |
15 | Stroke StrokeInstanse = new Stroke(SPCData);//添加笔画 |
16 | sc.Add(StrokeInstanse); |
17 | } |
18 | InkAnalyzer Core = new InkAnalyzer();//笔画分析的实例 |
19 | //Core.SetStrokeLanguageId(sc,0x0804);//设置中文 |
20 | Core.AddStrokes(sc); |
21 | var result = Core.Analyze(); |
22 | if (result.Successful) |
23 | { |
24 | List<string> Returning = new List<string>();//添加最相似字符串 |
25 | Returning.Add(Core.GetRecognizedString()); |
26 | foreach (var s in Core.GetAlternates()) //添加类似字符串 |
27 | { |
28 | Returning.Add(s.RecognizedString); |
29 | } |
30 | return Returning; |
31 | } |
32 | else |
33 | { |
34 | return new List<string> { "不能识别!" }; |
35 | } |
36 | } |
37 | catch |
38 | { |
39 | return new List<string> { "错误!" }; |
40 | } |
41 | } |
public Page() |
{ |
InitializeComponent(); |
c.ConvertInkToStringCompleted+=new EventHandler<SLSearch2010.ServiceReference1.ConvertInkToStringCompletedEventArgs>(c_ConvertInkToStringCompleted); |
search.SearchCompleted += new EventHandler<SLSearch2010.ServiceReference2.SearchCompletedEventArgs>(search_SearchCompleted); |
} |
/// <summary> |
/// 搜索完成后的绑定 |
/// </summary> |
/// <param name="sender"></param> |
/// <param name="e"></param> |
void search_SearchCompleted(object sender, SLSearch2010.ServiceReference2.SearchCompletedEventArgs e) |
{ |
PROGRESS.Visibility = Visibility.Collapsed; |
SearchResultPanel.Items.Clear(); |
foreach (var i in e.Result.Web.Results) |
{ |
ListBoxItem L = new ListBoxItem(); |
StackPanel s = new StackPanel(); |
//设置标题 |
TextBlock Title = new TextBlock(); |
Title.Text = i.Title; |
Title.FontSize = 19; |
Title.Foreground = new SolidColorBrush(Colors.Gray); |
//添加内容 |
TextBlock Content = new TextBlock(); |
Content.FontSize = 15; |
Content.Text = i.Description; |
Content.Foreground = new SolidColorBrush(Colors.Black); |
//添加地址超链接 |
TextBlock uri = new TextBlock(); |
uri.FontSize =13; |
uri.Text = i.DisplayUrl; |
//StackPanel中添加结果 |
s.Orientation = Orientation.Vertical; |
s.Children.Add(Title); |
s.Children.Add(Content); |
s.Children.Add(uri); |
L.Content = s; |
SearchResultPanel.Items.Add(L); |
L.Tag = uri.Text; |
L.MouseLeftButtonUp += new MouseButtonEventHandler(L_MouseLeftButtonUp);//点击前往搜索目标 |
} |
} |
/// <summary> |
/// 打开新的页面 |
/// </summary> |
/// <param name="sender"></param> |
/// <param name="e"></param> |
void L_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) |
{ |
System.Windows.Browser.HtmlPage.PopupWindow(new UriBuilder((sender as ListBoxItem).Tag.ToString()).Uri, "", new System.Windows.Browser.HtmlPopupWindowOptions()); |
} |
//手写输入停止时,输出识别结果 |
void c_ConvertInkToStringCompleted(object sender, SLSearch2010.ServiceReference1.ConvertInkToStringCompletedEventArgs e) |
{ |
PROGRESS.Visibility=Visibility.Collapsed; |
Results.Children.Clear(); |
foreach (string i in e.Result) |
{ |
Button B=new Button(); |
B.Content=i; |
B.FontSize=18; |
B.Click+=new RoutedEventHandler(B_Click); |
B.Tag=i; |
Results.Children.Add(B); |
} |
} |
//点击识别后的结果,进入搜索 |
void B_Click(object sender, RoutedEventArgs e) |
{ |
SearchRequest S = new SearchRequest(); |
S.AppId = "8350DD458AD2C27C0200A2D743DE34FC7A853599"; |
S.Version = "2.0"; |
S.Sources =new SourceType[]{SourceType.Web}; |
S.Query=(sender as Button).Tag.ToString(); |
S.Web = new SLSearch2010.ServiceReference2.WebRequest() |
{ |
CountSpecified=true, |
Count=50 |
}; |
PROGRESS.Visibility=Visibility.Visible; |
search.SearchAsync(S); |
} |
ServiceReference1.Service1Client c = new SLSearch2010.ServiceReference1.Service1Client(); //手写识别服务 |
ServiceReference2.LiveSearchPortTypeClient search = new SLSearch2010.ServiceReference2.LiveSearchPortTypeClient(); //Bing搜索服务 |
bool Tracking = false; |
Stroke Current;//当前一笔 |
private void InkCanvas_MouseMove(object sender, MouseEventArgs e) |
{ |
if (Tracking) |
{ |
Current.StylusPoints.Add(e.StylusDevice.GetStylusPoints(InkCanvas)); |
} |
} |
/// <summary> |
/// 按下鼠标 |
/// </summary> |
/// <param name="sender"></param> |
/// <param name="e"></param> |
private void InkCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) |
{ |
Tracking = true; |
Current=new Stroke(); |
InkCanvas.Strokes.Add(Current); |
//Point > GetPosition(...); |
Current.StylusPoints.Add(e.StylusDevice.GetStylusPoints(InkCanvas)); |
} |
/// <summary> |
/// 松开鼠标左键 |
/// </summary> |
/// <param name="sender"></param> |
/// <param name="e"></param> |
private void InkCanvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) |
{ |
try |
{ |
Current.StylusPoints.Add(e.StylusDevice.GetStylusPoints(InkCanvas)); |
Tracking = false; |
Current = null; |
PROGRESS.Visibility = Visibility.Visible; |
c.ConvertInkToStringAsync(ConvertData(InkCanvas)); |
} |
catch |
{ } |
} |
//清空手写板 |
private void Clear_Click(object sender, RoutedEventArgs e) |
{ |
InkCanvas.Strokes.Clear(); |
} |
//离开InkCavas |
private void InkCanvas_MouseLeave(object sender, MouseEventArgs e) |
{ |
//Current.StylusPoints.Add(e.StylusDevice.GetStylusPoints(InkCanvas)); |
if (Tracking) |
{ |
Tracking = false; |
Current = null; |
PROGRESS.Visibility = Visibility.Visible; |
} |
} |
/// <summary> |
/// 将笔画信息去掉结构中的多余信息 |
/// </summary> |
/// <param name="Target"></param> |
/// <returns></returns> |
private ObservableCollection<ObservableCollection<ObservableCollection<double>>> ConvertData(InkPresenter Target) |
{ |
ObservableCollection<ObservableCollection<ObservableCollection<double>>> Data = new ObservableCollection<ObservableCollection<ObservableCollection<double>>>(); |
foreach (Stroke S in Target.Strokes) |
{ |
ObservableCollection<ObservableCollection<double>> CurrentStroke = new ObservableCollection<ObservableCollection<double>>(); |
foreach (StylusPoint P in S.StylusPoints) |
{ |
CurrentStroke.Add(new ObservableCollection<double>() { P.X, P.Y }); |
} |
Data.Add(CurrentStroke); |
} |
return Data; |
} |
错误: Sys.InvalidOperationException: InitializeError error #2106 in control 'XamlError': 无法加载此应用程序。它是使用过时的 Silverlight 版本生成的