使用自定义控件转换货币值

分享于 

20分钟阅读

Web开发

  繁體

介绍

本文描述构造自定义 ASP.NET 2.0复合控件的详细信息,该控件用于将一种货币转换为另一种形式。 控件使用 public web服务计算汇率,并使用从web服务返回的汇率计算已经交换货币的值。

控件的操作很简单,要交换的钱量,然后使用下拉列表设置交换的货币类型。 提交时,控件将引发web服务,并将两种货币格式传递给它;然后,web服务返回汇率。 然后,控件使用汇率计算转换为新货币类型的货币的值。 然后将这些信息显示给最终用户。

作为复合控件,它可以能被丢到任何网页上,并用于向页面提供不需要额外编码的功能。

演示控制库只包含单个控件;控件本身通过使用 ASP.NET 2.0控件状态保持状态。 控件的呈现保持简单。 附加文件还包括一个示例网站,该网站仅用作演示控件的容器。

下图( 图 1 ) 提供了在网页上使用的控件的示例。

图 1: 使用中的货币转换自定义控件

入门

包含的文件包括一个网页控制库项目和一个示范网站。 要开始,打开包含的压缩文件并将两个项目安装到你的文件系统中。 打开IIS并为web应用程序创建一个虚拟目录。 将解决方案打开到可视化 2005并进行任何必要的更改以使两个项目都进入解决方案。 配置好后,解决方案资源管理器应该显示这些项目,引用和文件:

图 2: 带有Web应用程序和控件库的解决方案资源管理器

在检查解决方案时,注意"currencyconvertcontrol"控件库只包含一个控件,该控件称为"moneychanger"。 这个项目还包括指向 http://www.webservicex.net 站点的站点引用;这个站点提供并支持用于计算不同类型货币之间的汇率的免费web服务。

web应用程序只包含一个网页( Default.aspx ),并包含对"currencyconvertcontrol"动态链接库的引用。

web应用程序用作用于测试自定义控件的容器。

代码:MoneyChanger

创建自定义复合控件,以便在初始化时从网络服务检索信息,并使用该信息显示当前汇率,并计算从一种货币类型转换到另一种货币类型之后的货币转换。 控件支持 150种不同的货币类型。

服务接受arguments货币类型和货币类型交换到;,service exchange double double double service服务返回两个货币,即对该货币的sensitive,计算sensitive货币转换为。

在检查代码时,注意类中只包含默认导入。 类本身从 CompositeControl 类继承。

Imports System.Collections.GenericImports System.ComponentModelImports System.TextImports System.WebImports System.Web.UIImports System.Web.UI.WebControls
<ToolboxData("<{0}:MoneyChanger" & _ 
 "runat="server"></{0}:MoneyChanger>")> _PublicClass MoneyChanger
 Inherits CompositeControl

按照类声明,将创建一个标题为"声明"的区域,该区域是该控件中使用的所有对象的声明。 可以序列化结构用于保持控件状态;结构包含控件使用的成员变量。 除这里之外,声明一个事件与提交按钮一起使用,创建一个可以序列化结构( CurrentProperties )的实例,声明web服务。

#Region"Declarations" 
 PublicEvent Change(ByVal Sender AsObject, ByVal E As EventArgs)
 Private mCurrentProps AsNew CurrentProperties
 Public ddlFromCurrency As DropDownList
 Public ddlToCurrency As DropDownList
 Public txtExchangeRate As TextBox
 Public txtAmountToExchange As TextBox
 Public txtExchangedAmount As TextBox
 Public btnSubmit As Button
 Private mXchange As net.webservicex.www.CurrencyConvertor
 <Serializable()> _
 PrivateStructure CurrentProperties
 Dim mFromCurr AsIntegerDim mToCurr AsIntegerDim mResult AsDoubleDim mAmountToExchange AsDecimalDim mExchangedAmount AsDecimalEndStructure#End Region

变量声明之后,还定义了另一个区域( 方法),该区域是用来驱动控件的代码。

方法区域中包含的代码如下所示:

#Region"Methods" 
 PrivateSub MoneyChanger_Init(ByVal sender AsObject, _
 ByVal e As System.EventArgs) HandlesMe.Init
 ' required to enable control state Page.RegisterRequiresControlState(Me)
 EndSub

控件中使用的第一个子例程是初始化事件处理程序;这里处理程序用于设置 ASP.NET 2.0控件状态。 方法区域中包含的下一个子例程是用于处理提交按钮单击的按钮单击事件处理程序。 这个子程序连接到web服务并根据用户提供的货币选择请求汇率。 处理程序还执行根据两种货币类型之间的汇率转换货币金额所需的计算。 接收到汇率并计算转换后,处理程序将更新显示给用户的信息。

PrivateSub btnSubmit_Click(ByVal Sender AsObject, ByVal E As EventArgs)
 'update the to and from currency values from the drop down lists SetFromCurrency()
 SetToCurrency()
 'capture the amount to be exchanged into a property AmountToExchange = Convert.ToDecimal(txtAmountToExchange.Text)
 ' instance and call the web service to get the conversion rate mXchange = New net.webservicex.www.CurrencyConvertor
 Dim dblTemp AsDouble dblTemp = mXchange.ConversionRate(FromCurrency, ToCurrency)
 Result = dblTemp.ToString()
 'update the exchange rate textbox 'to show the returned change rate txtExchangeRate.Text = Result
 txtExchangeRate.Enabled = True'calculate the value of the money once 'converted to the new currency'type and then store it into a property ExchangedAmount = AmountToExchange * Result
 'convert the ExchangedAmount variable to the proper format'and display it in the control txtExchangedAmount.Text = ExchangedAmount.ToString("##.00")
 txtExchangedAmount.Enabled = True OnChange(EventArgs.Empty)EndSub

接下来的三个子程序很简单,很简单:

ProtectedSub OnChange(ByVal E As EventArgs)
 RaiseEvent Change(Me, E)EndSubProtectedOverridesFunction SaveControlState() AsObjectReturnMe.mCurrentPropsEndFunctionProtectedOverridesSub LoadControlState(ByVal savedState AsObject)
 mCurrentProps = New CurrentProperties
 mCurrentProps = CType(savedState, CurrentProperties)EndSub

OnChange 用于引发事件;这是与处理提交按钮单击事件相关的代码的一部分。 其他两个子例程用于在回发之间保存和加载控件状态。

下一步是 CreateChildControls 子程序的重写版本;在这个子例程中,所有控件都是实例化。填充并添加到控件中。 注释描述子程序的每个部分。

ProtectedOverridesSub CreateChildControls()
 ' create the dropdown list used to display' the from currency types ddlFromCurrency = New DropDownList
 ddlFromCurrency.ID = "ddlFromCurrency"'populates DDL with currency types LoadDropDownList(ddlFromCurrency)
 Me.Controls.Add(ddlFromCurrency)
 ' create the dropdown list used to display' the to currency types ddlToCurrency = New DropDownList
 ddlToCurrency.ID = "ddlToCurrency"'populates DDL with currency types LoadDropDownList(ddlToCurrency)
 Me.Controls.Add(ddlToCurrency)
 ' create the textbox used to display' the exchange rate txtExchangeRate = New TextBox
 txtExchangeRate.ID = "txtExchangeRate" txtExchangeRate.Enabled = False'display result value if any txtExchangeRate.Text = Me.mCurrentProps.mResult
 Me.Controls.Add(txtExchangeRate)
 ' create the textbox used to capture and display' the number of units of one type of currency' to convert into another type of currency.' Defaults to enabled = false since it will' not contain any data and the user won't manually' enter this calculated value txtAmountToExchange = New TextBox
 txtAmountToExchange.ID = "txtAmountToExchange" txtAmountToExchange.Text = _
 Me.mCurrentProps.mAmountToExchange
 Me.Controls.Add(txtAmountToExchange)
 ' create the textbox used to display the exchange' rate calculated and returned by the web service txtExchangedAmount = New TextBox
 txtExchangedAmount.ID = "txtExchangedAmount" txtExchangedAmount.Enabled = False txtExchangedAmount.Text = _
 Me.mCurrentProps.mExchangedAmount
 Me.Controls.Add(txtExchangedAmount)
 ' creats the submit button and assigns it a handler btnSubmit = New Button
 btnSubmit.Text = "Submit"AddHandler btnSubmit.Click, _
 AddressOf btnSubmit_Click
 Me.Controls.Add(btnSubmit)EndSub

接下来是用于设置 ToCurrencyFromCurrency 属性的子例程,这些属性用于每个下拉列表中所显示的用户值。 这些属性在内部用于控件,表示传递到web服务的货币参数的to和 from。 由于web服务用来表示货币类型的一些问题,需要将每个下拉列表项填充为整数。 实际的To 属性和 FromCurrency 属性设置为读取值而不是每个下拉列表中包含的索引或者文本。

PrivateSub SetFromCurrency()
 FromCurrency = ddlFromCurrency.SelectedValueEndSubPrivateSub SetToCurrency()
 ToCurrency = ddlToCurrency.SelectedValueEndSub

下一个子程序用于填充用于显示货币类型和货币类型的下拉列表;由于在很大程度上重复,所以我不显示整个子例程。 子程序接受下拉列表控件作为参数,并在调用该子例程时清除并填充下拉列表。

PrivateSub LoadDropDownList(ByVal ddl As DropDownList)
 ddl.Items.Clear()
 ddl.Items.Add("AED-UAE Dirham")
 ddl.Items(0).Value = 139 ddl.Items.Add("AFA-Afghanistan Afghani")
 ddl.Items(1).Value = 0 ddl.Items.Add("ALL-Albanian Lek")
 ddl.Items(2).Value = 1...

代码中定义的下一个区域称为"属性";这个部分包含控件使用的属性。 在这种情况下,所有属性都被声明为 private,因为所有的属性都只在控件内部使用。 如果希望这些显示在属性编辑器中,则需要将它们转换为 public 属性并应用适当的属性( 类别,可以浏览,描述,等等 )。 注意,对 EnsureChildControlsSaveControlState的调用都包含在每个属性中。 这两个调用都是为了保持控件在控件中更新到日期,并保持控件状态与属性所做的更改。

#Region"Properties" 
 PrivateProperty Result() AsDoubleGet EnsureChildControls()
 Return mCurrentProps.mResult
 EndGetSet(ByVal value AsDouble)
 EnsureChildControls()
 mCurrentProps.mResult = value
 SaveControlState()
 EndSetEndPropertyPrivateProperty FromCurrency() AsIntegerGet EnsureChildControls()
 Return mCurrentProps.mFromCurr
 EndGetSet(ByVal value AsInteger)
 EnsureChildControls()
 mCurrentProps.mFromCurr = value
 SaveControlState()
 EndSetEndPropertyPrivateProperty ToCurrency() AsIntegerGet EnsureChildControls()
 Return mCurrentProps.mToCurr
 EndGetSet(ByVal value AsInteger)
 EnsureChildControls()
 mCurrentProps.mToCurr = value
 SaveControlState()
 EndSetEndPropertyPrivateProperty AmountToExchange() AsDecimalGet EnsureChildControls()
 Return mCurrentProps.mAmountToExchange
 EndGetSet(ByVal value AsDecimal)
 EnsureChildControls()
 mCurrentProps.mAmountToExchange = value
 SaveControlState()
 EndSetEndPropertyPrivateProperty ExchangedAmount() AsDecimalGet EnsureChildControls()
 Return mCurrentProps.mExchangedAmount
 EndGetSet(ByVal value AsDecimal)
 EnsureChildControls()
 mCurrentProps.mExchangedAmount = value
 SaveControlState()
 EndSetEndProperty#End Region

用来呈现控件的代码非常简单;HtmlTextWriter 用来定义一个 table,并设置它的特性( 本示例中的单元格 padding ),table的每一行包含两个单元格,每个单元格中都放置一个标签。 一旦所有数据都写入到 table 中,就会呈现结束标记,并且控件完成。

自然,你可以更改 table的配置,或者通过在 HtmlTextWriter 中定义的HTML定义来删除从web服务返回的数据。 通过使用 HtmlTextWriter,重写 RenderContents 子例程并在这个子例程中格式化 HTML。

#Region"Rendering"ProtectedOverridesSub RenderContents(ByVal _
 output As HtmlTextWriter)
 Try output.AddAttribute(HtmlTextWriterAttribute.Cellpadding, "3")
 output.RenderBeginTag(HtmlTextWriterTag.Table)
 ' Amount to Exchange output.RenderBeginTag(HtmlTextWriterTag.Tr)
 output.RenderBeginTag(HtmlTextWriterTag.Td)
 output.AddAttribute(HtmlTextWriterAttribute.For, _
 txtAmountToExchange.ClientID)
 output.RenderBeginTag(HtmlTextWriterTag.Label)
 output.Write("Amount to Exchange:")
 output.RenderEndTag()
 output.RenderBeginTag(HtmlTextWriterTag.Td)
 output.AddStyleAttribute(HtmlTextWriterStyle.FontFamily, _
 Me.Font.Name)
 output.AddAttribute(HtmlTextWriterAttribute.Size, _
 Me.Font.Size.ToString())
 txtAmountToExchange.RenderControl(output)
 output.RenderEndTag()
 output.RenderEndTag()
 output.RenderEndTag()
 ' from currency output.RenderBeginTag(HtmlTextWriterTag.Tr)
 output.RenderBeginTag(HtmlTextWriterTag.Td)
 output.AddAttribute(HtmlTextWriterAttribute.For, _
 Me.ddlFromCurrency.ClientID)
 output.RenderBeginTag(HtmlTextWriterTag.Label)
 output.Write("Convert from this currency:")
 output.RenderEndTag()
 output.RenderBeginTag(HtmlTextWriterTag.Td)
 output.AddStyleAttribute(_
 HtmlTextWriterStyle.FontFamily, Me.Font.Name)
 output.AddAttribute(HtmlTextWriterAttribute.Size, _
 Me.Font.Size.ToString())
 ddlFromCurrency.RenderControl(output)
 output.RenderEndTag()
 output.RenderEndTag()
 output.RenderEndTag()
 ' to currency output.RenderBeginTag(HtmlTextWriterTag.Tr)
 output.RenderBeginTag(HtmlTextWriterTag.Td)
 output.AddAttribute(HtmlTextWriterAttribute.For, _
 Me.ddlToCurrency.ClientID)
 output.RenderBeginTag(HtmlTextWriterTag.Label)
 output.Write("Convert to this currency:")
 output.RenderEndTag()
 output.RenderBeginTag(HtmlTextWriterTag.Td)
 output.AddStyleAttribute(_
 HtmlTextWriterStyle.FontFamily, Me.Font.Name)
 output.AddAttribute(HtmlTextWriterAttribute.Size, _
 Me.Font.Size.ToString())
 ddlToCurrency.RenderControl(output)
 output.RenderEndTag()
 output.RenderEndTag()
 output.RenderEndTag()
 ' exchange rate output.RenderBeginTag(HtmlTextWriterTag.Tr)
 output.RenderBeginTag(HtmlTextWriterTag.Td)
 output.AddAttribute(HtmlTextWriterAttribute.For, _
 Me.txtExchangeRate.ClientID)
 output.RenderBeginTag(HtmlTextWriterTag.Label)
 output.Write("Exchange Rate:")
 output.RenderEndTag()
 output.RenderBeginTag(HtmlTextWriterTag.Td)
 txtExchangeRate.Text = mCurrentProps.mResult
 output.AddStyleAttribute(_
 HtmlTextWriterStyle.FontFamily, Me.Font.Name)
 output.AddAttribute(HtmlTextWriterAttribute.Size, _
 Me.Font.Size.ToString())
 txtExchangeRate.RenderControl(output)
 output.RenderEndTag()
 output.RenderEndTag()
 output.RenderEndTag()
 ' Exchanged Amount output.RenderBeginTag(HtmlTextWriterTag.Tr)
 output.RenderBeginTag(HtmlTextWriterTag.Td)
 output.AddAttribute(HtmlTextWriterAttribute.For, _
 txtExchangedAmount.ClientID)
 output.RenderBeginTag(HtmlTextWriterTag.Label)
 output.Write("Amount After Exchange:")
 output.RenderEndTag()
 output.RenderBeginTag(HtmlTextWriterTag.Td)
 output.AddStyleAttribute(_
 HtmlTextWriterStyle.FontFamily, Me.Font.Name)
 output.AddAttribute(HtmlTextWriterAttribute.Size, _
 Me.Font.Size.ToString())
 txtExchangedAmount.RenderControl(output)
 output.RenderEndTag()
 output.RenderEndTag()
 output.RenderEndTag()
 ' submit button output.RenderBeginTag(HtmlTextWriterTag.Tr)
 output.RenderBeginTag(HtmlTextWriterTag.Td)
 output.AddAttribute(HtmlTextWriterAttribute.For, _
 Me.btnSubmit.ClientID)
 output.AddStyleAttribute(HtmlTextWriterStyle.FontFamily, _
 Me.Font.Name)
 output.AddAttribute(HtmlTextWriterAttribute.Size, _
 Me.Font.Size.ToString())
 output.RenderBeginTag(HtmlTextWriterTag.Label)
 output.Write("Retrieve Exchange Rate:")
 output.RenderEndTag()
 output.RenderBeginTag(HtmlTextWriterTag.Td)
 output.AddStyleAttribute(HtmlTextWriterStyle.FontFamily, _
 Me.Font.Name)
 output.AddAttribute(HtmlTextWriterAttribute.Size, _
 Me.Font.Size.ToString())
 btnSubmit.RenderControl(output)
 output.RenderEndTag()
 output.RenderEndTag()
 output.RenderEndTag()
 output.RenderEndTag()
 Catch output.Write("Money Changer Custom Control")
 EndTryEndSub#End Region

代码:站点页面的演示默认

演示站点中包含的Default.aspx 页面只为控件提供一个测试容器。 页面只包含用于描述页面和控件本身的一行文本。 在浏览器中显示 Default.aspx 页面将启用对控件的测试。

摘要

这里项目旨在描述一个有用的。易于生成的自定义复合控件。 这里示例仅限于描述货币变换器自定义组合控件,同样应用的方法也会使用多种自定义组合控件。 它提供了一个在自定义控件中消耗web服务的示例,该方法可以用于显示任何web服务的信息。 本演示中使用的web服务不受控制,我可以预测服务的寿命。


相关文章