SilverLight3 Cool开发(一) BingAPI实现手写搜索框

前言

此实例由Csdn讲师栾轩开发,本人也只是初学SilverLight,出于学习目的将此自己的开发过程与大家分享,并提供源码,欢迎共同探讨进步。

第一步:创建一个SilverLightApplication

1

创建后会出现一个对话框,SilverLight版本可以选择2.0或3.0,这里选择3.0。Project Type选择默认(如果仅做一个插件就不需要Web支持)。确认,项目已经建成了。

3

 

第二步,UI设计

将Grid改为StackPanel,StackPanel用于水平或垂直排列控件,支持嵌套。

InkPresenter,这是手写输入的模块,注意这是的MouseMove等事件的方法名在VS2008中通过Tab调出,在这里输入=号后会出现提
示,这里选择New Events Handle,后台会自动生成此事件的方法。

ProgressBar 进度条 通过Visibility属性控制是否滚动显示

ScrollViewer 自适应容器,由于手写输入的识别相似结果会很多,这里用到可以自适应高度

ListBox 用来显示通过Bing Api查询出的结果

  <StackPanel x:Name="LayoutRoot" Orientation="Vertical">
        <InkPresenter x:Name="InkCanvas" Height="150" Background="LightBlue"
                      MouseMove="InkCanvas_MouseMove" 
                      MouseLeftButtonDown="InkCanvas_MouseLeftButtonDown" 
                      MouseLeftButtonUp="InkCanvas_MouseLeftButtonUp"
                      MouseLeave="InkCanvas_MouseLeave"
                      />
        <StackPanel Orientation="Horizontal">
            <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

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。

image

Code:将客户端传入的手写数据转换为字符串数组

将DoWork方法改为:

        public List<string> ConvertInkToString(List<List<List<double>>> Data)
        {
            try
            {
                // 还原Data
                StrokeCollection sc = new StrokeCollection();//WCF识别的笔画集,silverlight识别的WCF识别的笔画集类型相同,但里面的架构信息不同
                foreach (var strokeData in Data) 
                {
                    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          }
3.在xaml项目中右键选择 Add Service Reference,点击下图的Discovery
image
查看高级选项,确认Collection type选中的是
image
第四步:Bing搜索 api服务引用
1.申请api Id
进入www.bing.com/developer,选择Get An AppId,用自己的Msn申请一个。
 
2.添加服务引用
重复上面的引用操作,将Address改为http://api.search.live.net/search.wsdl?AppId=填写申请的Bing Id
第五步:完成Page.xaml.cs后台代码
 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;
        }
结果:运行与调试成功,没有任何问题,但最终还是看不到结果,注释会在找到原因后尽快添加,应该是环境配置问题。。。现在只能提供在VS2008下完成并且成功的源码,大哥前辈们,谁能救救我!!

 

错误: Sys.InvalidOperationException: InitializeError error #2106 in control 'XamlError': 无法加载此应用程序。它是使用过时的 Silverlight 版本生成的

源码下载save

posted @ 2009-08-26 15:30  -飛天蟲  阅读(1028)  评论(2编辑  收藏  举报