Silverlight 中的弹出搜索表单控件
Silverlight 是一款强大且新颖的浏览器插件,可在 Mac OS、Windows 和 Linux 上运行。它可以帮助您创建安全、可靠且可跨平台扩展的富 Web 应用程序。本文将使用 Visual Studio 2008 来创建 Silverlight 弹出搜索表单控件。
引言
Silverlight 是一款强大且新颖的浏览器插件,可在 Mac OS、Windows 和 Linux 上运行。它可以帮助您创建安全、可靠且可跨平台扩展的富 Web 应用程序。本文将使用 Visual Studio 2008 来创建 Silverlight 弹出搜索表单控件。
系统要求
- 此应用程序要求用户拥有 Visual Studio 2008
- Microsoft Silverlight 2 Tools for Visual Studio 2008 SP1 (http://www.microsoft.com/downloads/details.aspx?FamilyId=c22d6a7b-546f-4407-8ef6-d60c8ee221ed&displaylang=en)
- Northwind 数据库(MS SQL Server)
本文假定您熟悉 C# 以及使用 Visual Studio 2008 创建 Silverlight 应用程序。对 WCF、Web Service、LINQ 的基本了解将有所帮助,但并非完全理解本文内容的必要条件。
设计要求
主控件结合了两个文本框和一个按钮,如图 1 所示。第一个文本框能够显示和输入数据。按钮将弹出搜索表单。第二个文本框仅用于显示数据。
弹出搜索表单控件具有一个数据网格用于显示数据,并且具有搜索功能,如图 2 所示。
有两种方式可以将数据从数据网格传回主控件。
- 双击数据网格
- 单击“确定”按钮
有一种无需弹出搜索表单即可提取数据的方式。
- 在第一个文本框中输入正确的 ID(键)以显示 Name(值)数据。
创建 Silverlight 和 WCF 项目
了解了控件的功能后,我们现在可以在 Visual Studio 2008 中开始创建我们的项目。让我们创建所有需要的项目,然后逐一处理以达成目标。
**请下载代码并对照每个步骤进行学习**
步骤 1. 创建 Silverlight 应用程序
在 Visual Studio 2008 中,选择“文件”->“新建”->“项目”,然后选择“Silverlight 应用程序”。您可以随意命名。在此示例中,我将其命名为 popFormDemo,如图 5 所示。
单击步骤 1 中的“确定”后,您应该会看到一个向导窗口。我们将按图 6 中的默认设置保留。
在 PopFormDemo 项目下添加一个名为 CusControl 的新文件夹,如图 7 所示。
在 CusControl 文件夹下,添加一个名为 PopForm 的新 Silverlight 用户控件,如图 8 所示。
图 8. 在 CusControl 文件夹中添加新的 Silverlight 用户控件
步骤 2. 创建 WCF 服务项目
有几种从数据库向 Silverlight 控件传递数据的方式。常用的技术是 Web 服务或 WCF。在此示例中,我将使用 WCF。
在解决方案下,添加一个新的 ASP.NET Web 应用程序并重命名为 DaoWcf,如图 9 所示。
在 DaoWcf Web 项目下,添加一个新的 WCF 服务并重命名为 PopDataService,如图 10 所示。(您可以删除 Default.aspx,也可以保留它。)
现在,您应该在 DaoWcf 项目中看到 IPopDataService.cs 和 PopDataService.svc,如图 11 所示。
步骤 3. 在 WCF 服务项目中进行配置
在 DaoWcf 项目中,右键单击“属性”。您需要在“Web”选项卡中使用“本地 IIS Web 服务器”,如图 12 所示。
在 web.config 中,将 NorthWindDb 连接字符串添加到 connectionStrings 标记中,如图 13 所示。
在 web.config 中,将服务绑定从 wsHttpBinding(默认)修改为 basicHttpBinding,如图 14 所示。
注意:支持 Silverlight 的 WCF 服务与“普通”WCF 服务非常相似。唯一的区别是 Silverlight 只支持调用配置为 BasicHttpBinding 的 WCF 服务。目前不支持更高级的配置文件。也可以将一个“普通”WCF 服务重新配置为与 BasicHttpBinding 一起工作,然后从 Silverlight 调用它。
步骤 4. 在 WCF 服务项目中实现代码
在 PopDataSerivce.svc.cs 中,PopFormClass 具有 ID 和 NAME 属性,并带有 DataContract 属性。DataContract 属性描述了服务用于与客户端通信的数据结构。
[DataContract()]
public class PopFormClass
{
[DataMember]
public string ID { get; set; }
[DataMember]
public string NAME { get; set; }
}
在 IPopDataService.cs 中,IPopDataService 接口具有 3 个抽象方法,并带有 ServiceContract 属性。ServiceContract 描述了服务实现的功能操作。
[ServiceContract]
public interface IPopDataService
{
[OperationContract]
List<PopFormClass> GetSqlCustomersData();
[OperationContract]
List<PopFormClass> GetSqlEmployeesData();
[OperationContract]
List<PopFormClass> GetSqlProductsData();
}
在 `PopDataService.svc.cs` 中实现 `IPopDataService` 接口。
public class PopDataService : IPopDataService
{
private string SqlConString;
public PopDataService()
{
SqlConString = ConfigurationManager.ConnectionStrings["NorthWindDb"].ConnectionString;
}
public List<PopFormClass> GetSqlCustomersData()
{
List<PopFormClass> list = new List<PopFormClass>();
try
{
list = GetPopData("select CustomerID, CompanyName from Customers order by 1");
}
catch (Exception ex)
{
throw ex;
}
return list;
}
public List<PopFormClass> GetSqlProductsData()
{
List<PopFormClass> list = new List<PopFormClass>();
try
{
list = GetPopData("select ProductID, ProductName from Products order by 1");
}
catch (Exception ex)
{
throw ex;
}
return list;
}
public List<PopFormClass> GetSqlEmployeesData()
{
List<PopFormClass> list = new List<PopFormClass>();
try
{
list = GetPopData("select EmployeeID, LastName, FirstName from Employees order by 1");
}
catch (Exception ex)
{
throw ex;
}
return list;
}
GetPopData(string strSql) 方法将从数据库获取数据,然后将数据插入到 List<PopFormClass> 中。
private List<PopFormClass> GetPopData(string strSql)
{
List<PopFormClass> list = new List<PopFormClass>();
using (SqlConnection con = new SqlConnection(SqlConString))
{
con.Open();
SqlCommand com = new SqlCommand(strSql, con);
IDataReader dr = com.ExecuteReader();
while (dr.Read())
{
PopFormClass pf = new PopFormClass();
pf.ID = Convert.ToString(dr[0]);
pf.NAME = Convert.ToString(dr[1]);
list.Add(pf);
}
} return list;
}
步骤 5. 检查 WCF 服务是否正常工作
现在,您可以使用 IE 来检查 WCF 是否正常工作。右键单击 DaoWcf 项目,然后选择“设为启动项目”。运行“启动但不调试”(Ctrl-F5)。您应该会看到服务 Web,如图 15 所示。
单击 svcutil.exe 文本旁边的 URL。您应该会看到类似于图 16 的 XML。
步骤 6. 在 Silverlight 项目中添加服务引用
要调用 WCF 服务,首先需要生成一个配置文件和代理类,然后编写使用代理类调用服务的代码。在 PopFormDemo 项目中,右键单击“引用”,然后从上下文菜单中选择“添加服务引用”,如图 17 所示。这将启动一个对话框,如图 18 所示。
在“地址”中,输入您之前创建的服务 URL,然后单击“转到”。此对话框会调用 svcutil 工具来创建一个实现代理类的源文件。
它还会创建一个 app.config 文件,其中包含一个 <system.serviceMode> 节点,用于存储调用终结点所需的地址、绑定和合同信息,如图 19 所示。
步骤 7. 创建弹出搜索表单控件 UI
在主控件中,创建 2 个文本框和 1 个按钮,如图 20 所示。
弹出搜索表单位于 Border 控件内部,如图 21 所示。因此,可以使用 Visibility 来隐藏或显示弹出搜索表单。
最初,弹出搜索表单控件设置为 Visibility = "Collapsed",如图 22 所示。
我使用资源来定义右上角关闭按钮的样式,如图 23 所示。(它类似于 Web 应用程序的 CSS。)
我在 App.xaml 中定义了资源,如图 24 所示。因为每个元素都可以访问这些资源。您也可以在页面级别定义资源,然后该页面上的所有元素都可以使用它。
步骤 8. 在 Silverlight 项目中实现代码
PopForm.xaml.cs 中有 5 个主要属性,如下所示
public string DataProvider { get; set; }
public string TitleName { get; set; }
public string PopId { get; set; }
public string PopName { get; set; }
public string OpacityValue { get; set; }
DataProvider:它指示您希望在弹出搜索表单上显示什么数据
TitleName:弹出搜索表单顶部的标题名称
PopId:弹出搜索表单上的 Label ID 文本
PopName:弹出搜索表单上的 Label NAME 文本
OpacityValue:弹出搜索表单的透明度级别
如前所述,有两种获取数据的方式
1. 从弹出搜索表单
a. 单击“确定”按钮
private void btnPopEnter_Click(object sender, RoutedEventArgs e)
{
if (popBoder.Visibility == Visibility.Visible)
{
PopFormClass pf = dgPop.SelectedItem as PopFormClass;
txtId.Text = pf.ID;
txtName.Text = pf.NAME;
popBoder.Visibility = Visibility.Collapsed;
}
}
b. 双击数据网格。双击的想法来源于 MouseClickManager。在构造函数中将双击事件分配给 ResultSelected,如下所示:
public PopForm()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(PopForm_Loaded);
_gridClickManager = new MouseClickManager(200);
_gridClickManager.DoubleClick += new MouseButtonEventHandler(ResultSelected);
}
private void ResultSelected(object sender, MouseButtonEventArgs e)
{
if (popBoder.Visibility == Visibility.Visible)
{
PopFormClass pf = dgPop.SelectedItem as PopFormClass;
txtId.Text = pf.ID;
txtName.Text = pf.NAME;
popBoder.Visibility = Visibility.Collapsed;
}
}
在数据网格的每一行上分配双击事件,如下所示
private void dgPop_LoadingRow(object sender, DataGridRowEventArgs e) { e.Row.MouseLeftButtonUp -= _gridClickManager.HandleClick; e.Row.MouseLeftButtonUp += _gridClickManager.HandleClick; }2. 从文本框
private void txtId_MouseLeave(object sender, MouseEventArgs e) { if (!string.IsNullOrEmpty(txtId.Text)) { var eData = from eFilter in popData where eFilter.ID == txtId.Text select eFilter; if (eData.Count() > 0) { txtName.Text = eData.First().NAME; } else { txtName.Text = string.Empty; } } }
使用代理类调用服务的代码。
private void dgPop_Loaded(object sender, RoutedEventArgs e)
{
lblPopTitle.Text = string.IsNullOrEmpty(TitleName) ? "" : TitleName;
lblPopId.Text = string.IsNullOrEmpty(PopId) ? "ID: " : PopId;
lblPopName.Text = string.IsNullOrEmpty(PopName) ? "NAME: " : PopName;
if (!string.IsNullOrEmpty(DataProvider))
{
switch (DataProvider)
{
case "GetSqlCustomersData":
daoWcf = new PopDataServiceClient();
daoWcf.GetSqlCustomersDataCompleted += new EventHandler<GetSqlCustomersDataCompletedEventArgs>(daoWcf_GetSqlCustomersDataCompleted);
daoWcf.GetSqlCustomersDataAsync();
break;
case "GetSqlProductsData":
daoWcf = new PopDataServiceClient();
daoWcf.GetSqlProductsDataCompleted += new EventHandler<GetSqlProductsDataCompletedEventArgs>(daoWcf_GetSqlProductsDataCompleted);
daoWcf.GetSqlProductsDataAsync();
break;
case "GetSqlEmployeesData":
daoWcf = new PopDataServiceClient();
daoWcf.GetSqlEmployeesDataCompleted += new EventHandler<GetSqlEmployeesDataCompletedEventArgs>(daoWcf_GetSqlEmployeesDataCompleted);
daoWcf.GetSqlEmployeesDataAsync();
break;
default:
break;
}
}
}
步骤 9. 将弹出搜索表单控件应用到页面
首先,我们需要将弹出搜索表单控件的命名空间映射到 Page.xaml,如下所示
<UserControl x:Class="PopFormDemo.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PopFormDemo.CusControl"
>
我在 Page.xaml 中应用了 3 个弹出搜索表单控件,如下所示
展望未来
我将此代码置于公共领域,不设任何限制。它可能不是最佳的模式设计或编码风格。任何人都可以将其用于任何目的,包括商业产品。如果您能够改进代码,甚至使其更加清晰,请告诉我。我将更新代码以使其更有用。谢谢大家。
历史
- 2009 年 8 月 7 日 - 更新代码(Bug 修复)。为 Silverlight 3.0 添加代码