如何实现在Edit框内按回车触发按钮就执行Button按钮里的语句?

【已解决】android中点击其他的(如Button等)但是EditText却没有失去焦点
android的app中,在对于EditText已经实现了:
OnFocusChangeListener mFocusChangedL
EditText variableValueView = (EditText) variableLayout.findViewById(R.id.variableValue);
EditText variableValueView = (EditText) variableLayout.findViewById(R.id.variableValue);
mFocusChangedListener = new OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if(hasFocus){
而且也是达到预期的,当点击可编辑的EditText时,得到focus,
点击其他(已经被设置为不可编辑,但是可点击,可以获得焦点的)EditText时,焦点是可以失去的。
但是有个问题:
当点击其他(菜单)按钮时,EditText却没有像所希望的失去焦点。
【解决过程】
android edittext not lose focus when click other button
edittext click other not lost focus
倒是想到:
对于此处,希望的是,点击Menu的菜单的话,则可以对于那些Button或Menu,去复写对应的
事件,然后其中取消掉当前的EditText的焦点(如果当前的焦点是处于在某个EditText上面的话)
应该就可以了。
2.不过,对于此种做法,对于我当前的app来说,还不是最优的做法。
所以,还要先去试试:
把EditText中的值,如果有任何改动,就都调用我此处程序中的validate,然后同时获得反馈,并更新对应的UI(即variable的status)
这样,就不用关系EditText是否获得或失去focus了。
3.但是由于此处程序的逻辑有些特殊,会导致死循环,所以暂时放弃上面办法,还是继续此处的办法:
当EditText点击到别的Button或Menu时,让其失去焦点,从而使得变量值可以得到校验是否有效。
然后去看了看,此处不是button,所以没法复写onClick,然后只能在原先的menu的onOptionsItemSelected中去加代码,如下:
public boolean onOptionsItemSelected(MenuItem item) {
//clear current var value EditText focus
View curView = getCurrentFocus();
//if((null != curView) && (curView instanceof EditText) && (curView.isEnabled())){
if(isEditableEditText(curView)){
//being in Edit Mode
curView.clearFocus();
// Handle item selection
switch (item.getItemId()) {
case R.id.menu_discard:
case R.id.menu_send:
case R.id.menu_settings:
return super.onOptionsItemSelected(item);
但是还是不能解决我此处问题:
希望是,在点击了Menu后,在onOptionsItemSelected之前,就能够clear掉之前EditText的focus,
这样才能有机会去validate,然后接着调用到onOptionsItemSelected时,对于R.id.menu_send,才能去执行对应的send的动作,去写入新的值。
4.所以还要再去,找到如何在Menu的onOptionsItemSelected之前,就将EditText的焦点的办法。
android activity click
android activity onclick event
另外通过:
找到官网的:
但是却没有找到任何和click有关的
去尝试给ActionBarActionBar(?)中,加上onClick
但是另外搜:
android menu onclick
是可以给每个menu的item的xml中加上:
android:onClick=&doThis&
但是很明显,对于每个都加,显得效率很低。
所以暂时不用这个办法。
中的解释:
对于&item&来说,有个:
android:onClick
Method name. The method to call when this menu item is clicked. The method must be declared in the activity as public and accept a
as its only parameter, which indicates the item clicked. This method takes precedence over the standard callback to . See the example at the bottom.
以及对应的示例代码:
&menu xmlns:android=&/apk/res/android&&
&item android:id=&@+id/item1&
android:title=&@string/item1&
android:icon=&@drawable/group_item1_icon&
android:showAsAction=&ifRoom|withText&/&
&group android:id=&@+id/group&&
&item android:id=&@+id/group_item1&
android:onClick=&onGroupItemClick&
android:title=&@string/group_item1&
android:icon=&@drawable/group_item1_icon& /&
&item android:id=&@+id/group_item2&
android:onClick=&onGroupItemClick&
android:title=&@string/group_item2&
android:icon=&@drawable/group_item2_icon& /&
&item android:id=&@+id/submenu&
android:title=&@string/submenu_title&
android:showAsAction=&ifRoom|withText& &
&item android:id=&@+id/submenu_item1&
android:title=&@string/submenu_item1& /&
public void onGroupItemClick(MenuItem item) {
// One of the group items (using the onClick attribute) was clicked
// The item parameter passed here indicates which item it is
// All other menu item clicks are handled by onOptionsItemSelected()
所以此处就可以去:
将我此处所关心的几个menu的item,弄到一个group中,
然后对于整个的group,弄一个onClick
在其中,做自己需要的处理:clear掉当前EditText的focus
这样估计就可以了。
&menu xmlns:android=&/apk/res/android& &
&group android:id=&@+id/menu_group_edit&&
android:id=&@+id/menu_discard&
android:icon=&@drawable/error_white&
android:orderInCategory=&1&
android:showAsAction=&ifRoom|withText&
android:onClick=&onMenuGroupEditClick&
android:title=&@string/discard&/&
android:id=&@+id/menu_send&
android:icon=&@drawable/forward_white&
android:orderInCategory=&2&
android:showAsAction=&ifRoom|withText&
android:onClick=&onMenuGroupEditClick&
android:title=&@string/send&/&
android:id=&@+id/menu_settings&
android:icon=&@drawable/settings&
android:orderInCategory=&3&
android:showAsAction=&ifRoom|withText&
android:title=&@string/settings&/&
然后去实现。
但是折腾期间,结果发现问题:
代码中的注释:
// One of the group items (using the onClick attribute) was clicked
// The item parameter passed here indicates which item it is
// All other menu item clicks are handled by onOptionsItemSelected()
的含义很清楚:
如果此处menu的item实现了自己的onClick,那么,其的确是先于
onOptionsItemSelected
去处理的,但是却导致
onOptionsItemSelected不会被调用了。。。
只会被你自己的onClick事件所处理
所以导致结果是:
即使此处实现了group中的item的onClick事件,那么其中要处理的内容(取消EditText的focus)和后续
类似于onOptionsItemSelected中的switch..case中处理对应item的内容,
也是先后顺序就执行了,中间就没有间隔了。
而这不是我要的,我要的是,先(取消EditText的focus)后(更新对应的值)
中间必须有间隔才行的。。。
7.目前实在很无奈的是,只能去试试:
public boolean onOptionsItemSelected(MenuItem item) {
//clear current var value EditText focus
View curView = getCurrentFocus();
//if((null != curView) && (curView instanceof EditText) && (curView.isEnabled())){
if(isEditableEditText(curView)){
curView.clearFocus();
// Handle item selection
switch (item.getItemId()) {
case R.id.menu_discard:
//Toast.makeText(MainActivity.this, &Menu Discard cliked&, Toast.LENGTH_SHORT).show();
clearEditedVarValues();
case R.id.menu_send:
//Toast.makeText(MainActivity.this, &Menu Send cliked&, Toast.LENGTH_SHORT).show();
writeEditedVarValues();
case R.id.menu_settings:
return super.onOptionsItemSelected(item);
中的clearFocus,能否直接触发系统事件,从而导致别的相关代码(EditText的OnFocusChangeListener)被调用
然后再回来继续去执行对应的writeEditedVarValues等内容。
结果发现是可以的:
当执行了:
curView.clearFocus();
接着会执行到对应的EditText的OnFocusChangeListener的,其中会去执行validate
然后接着可以再执行onOptionsItemSelected中的writeEditedVarValues了。
此处,是间接实现最原始的目的:
当点击Menu中的一个子菜单item时,原先的EditText并没有失去焦点
的,办法是:
当点击了Menu的item时,此时去获得当前焦点,判断是所关心的EditText时,再去调用clearFocus去主动失去焦点,即可。
共享此文章:
免费的格式化Javascript源码的网站
查询Unicode字符,且还带Oct,Decimal,Hex,HTML Entity
HTML和Javascript都支持,很好用。&&&&android 按回车键 将EditText 变化为 Button
&android 按回车键 将EditText 变化为 Button
实现原理: 当在某一个EditText 中输入文本后按回车键,系统将EditTex隐藏,并在EditText的位置显示一个按钮,按钮的文本就是在EditText 中输入的文本
若举报审核通过,可奖励20下载分
被举报人:
举报的资源分:
请选择类型
资源无法下载
资源无法使用
标题与实际内容不符
含有危害国家安全内容
含有反动***等内容
含广告内容
版权问题,侵犯个人或公司的版权
*详细原因:
VIP下载&&免积分60元/年(1200次)
您可能还需要
Q.为什么我点的下载下不了,但积分却被扣了
A. 由于下载人数众多,下载服务器做了并发的限制。若发现下载不了,请稍后再试,多次下载是不会重复扣分的。
Q.我的积分不多了,如何获取积分?
A. 获得积分,详细见。
完成任务获取积分。
论坛可用分兑换下载积分。
第一次绑定手机,将获得5个C币,C币可。
关注并绑定CSDNID,送10个下载分
下载资源意味着您已经同意遵守以下协议
资源的所有权益归上传用户所有
未经权益所有人同意,不得将资源中的内容挪作商业或盈利用途
CSDN下载频道仅提供交流平台,并不能对任何下载资源负责
下载资源中如有侵权或不适当内容,
本站不保证本站提供的资源的准确性,安全性和完整性,同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
移动开发下载排行
您当前C币:0&&&可兑换 0 下载积分
兑换下载分:&
消耗C币:0&
立即兑换&&
兑换成功你当前的下载分为 。前去下载资源
你下载资源过于频繁,请输入验证码
如何快速获得积分?
你已经下载过该资源,再次下载不需要扣除积分
android 按回车键 将EditText 变化为 Button
所需积分:1
剩余积分:0
扫描微信二维码精彩活动、课程更新抢先知
VIP会员,免积分下载
会员到期时间:日
剩余下载次数:1000
android 按回车键 将EditText 变化为 Button
剩余次数:&&&&有效期截止到:
你还不是VIP会员VIP会员享免积分 . 专属通道极速下载
VIP下载次数已满VIP会员享免积分 . 专属通道极速下载,请继续开通VIP会员
你的VIP会员已过期VIP会员享免积分 . 专属通道极速下载,请继续开通VIP会员许多报表方案都涉及到报表数据的只读访问,对于那些具有能够根据显示的数据来完成各种操作功能的报表来说也很常见。
通常这涉及到使用报表中所示的每一条记录添加一个按钮、链接按钮(LinkButton) 或 Web 位图按钮控件,当这些控件或按钮被单击后,会引起回传或激活某些服务端的代码。最常见的例子是按逐条记录的原则编辑和删除数据。事实上,从&教程开始,编辑和删除就非常常见,所以无需写一行代码, GridView 、 DetailsView 和 FormView 控件就可以支持这些功能。
除了编辑按钮和删除按钮,GridView 、DetailsView 和 FormView 控件还包含一些(工具)按钮、链接按钮 (LinkButton) 或位图按钮 (ImageButton) ,当这些按钮被单击后,会执行一些用户自定义的服务端逻辑。本教程着眼于如何为 GridView 控件或 DetailView 控件的模板和字段添加自定义按钮。另外,我们还将单独创建一个界面,这个界面拥有一个 FormView 控件,用户通过这个控件可以浏览各个供应商。对于一个特定供应商,FormView 控件会显示该供应商的相关信息和一个 Web 按钮控件,如果单击该控件,当产品断货时 FormView 控件会标记出所有的相关产品。另外,Gridview 会列出这些由选定的供应商提供的产品,并且每一列都包含&增加价格&和&折扣价格&按钮,单击这些按钮后将会增加或降低产品单元价格的百分之十。(请参见插图 1 )
图 1 :包含用于执行自定义操作的按钮的 FormView 控件和 GridView 控件
步骤1 :添加按钮教程 Web 页面
在探求如何添加自定义按钮之前,让我们先花一些时间在本教程需要的 Web 站点项目中创建一个 ASP.NET 页面。开始先添加一个文件夹,命名为 CustomButtons 。
接下来,将以下 ASP.NET 页面添加到该文件夹,确保每个页面与 Site.master 主页页面相关联:
Default.aspx
CustomButtons.aspx
图 2 :为与自定义按钮相关的教程添加 ASP.NET 页面
和其他文件夹中的一样,在 CustomButtons 文件夹中的& Default.aspx 页面将会列出它所在章节的教程。回想一下, SectionLevelTutorialListing.ascx 用户控件提供本功能。所以通过拖拉的方法将该用户控件从解决方案管理器中拖拉到页面设计视图中,从而将该用户控件添加到 Default.aspx 页面中。
图3 :将SectionLevelTutorialListing.ascx 用户控件添加到 Default.aspx 页面中
最后,将页面按条目添加到 Web.sitemap 文件中。具体来说,在进行分页和排序之后添加以下标示文字 &siteMapNode& :
&siteMapNode&&&&&title="Adding&Custom&Buttons"&&&&&description="Samples&of&Reports&that&Include&Buttons&for&Performing&&&&&&&&&&&&&&&&&&&Server-Side&Actions"&&&&&url="~/CustomButtons/Default.aspx"&&&&&&&&siteMapNode&&&&&&&&&title="Using&ButtonFields&and&Buttons&in&Templates"&&&&&&&&&description="Examines&how&to&add&custom&Buttons,&LinkButtons,&&&&&&&&&&&&&&&&&&&&&&&or&ImageButtons&as&ButtonFields&or&within&templates."&&&&&&&&&url="~/CustomButtons/CustomButtons.aspx"&/&&&&/siteMapNode&
更新 Web.sitemap 后,花点时间用浏览器查看一下教程网站。现在,左边的菜单包含用于编辑、插入和删除教程的各项。
图4 :包含自定义按钮教程入口的站点地图
步骤2 :添加一个 FormView 控件,列出各个供应商
本教程中,让我们从添加一个 FormView 控件,并列出各个供应商开始。正如介绍一节中所介绍的那样, FormView 控件允许用户浏览各个产品供应商,并在 GridView 中显示由各个供应商提供的产品。另外,FormView 控件还拥有一个按钮,单击这个按钮后,断货时会标记出供应商的所有产品。在我们关心如何为& FormView 控件添加自定义按钮前,首先让我们先创建一个 FormView 控件,以便显示供应商信息。
开始,先打开 CustomButtons 文件夹中的 CustomButtons.aspx 页面,为该页面添加一个 FormView 控件(通过拖拉的方法将其从工具箱中拖拉到设计器 中),并为其设置 ID 属性和供应商。从 FormView 控件的智能标记中选择创建一个新的对象数据源 ( ObjectDataSource ),命名为 SuppliersDataSource 。
图5 :创建一个新的对象数据源 (ObjectDataSource) ,命名为供应商数据源 (SuppliersDataSource)
需要配置这个新的对象数据源,因为使用 SupplierBLL 类的 GetSupplier() 方法时要用到该数据源(请参见图6 )因为& FormView 控件不提供用于更新供应商信息的界面,所以请在 UPDATE 选项卡上的下拉菜单列表中选择选项 (None) 。
图6 :配置数据源,以使用 SuppliersBLL 类的 GetSuppliers () 方法
对象数据源(ObjectDataSource) 配置完成后,Visual Studio 会为 FormView 控件生成一个插入条目模板(InsertItemTemplate) 编辑条目模板 (EditItemTemplate) 和条目模板 (ItemTemplate) . 移除插入条目模板和编辑条目模板并修改条目模板,这样 FormView 控件就只显示供应商的公司名称和***号码。最后,在它的智能标记上检查选中允许分页检查框 (或将其 AllowPaging 属性赋值为真 ( TRUE ),为 FormView 控件打开分页支持。完成这些更改之后,您的页面的公开的标示文字应该和以下文字相似:
&asp:FormView&ID="Suppliers"&runat="server"&DataKeyNames="SupplierID"&&&&&DataSourceID="SuppliersDataSource"&EnableViewState="False"&AllowPaging="True"&&&&&&&ItemTemplate&&&&&&&&&&&h3&&&&&&&&&&&&&&&asp:Label&ID="CompanyName"&runat="server"&&&&&&&&&&&&&&&&&Text='&%#&Bind("CompanyName")&%&'&/&&&&&&&&&&&/h3&&&&&&&&&&&b&Phone:&/b&&&&&&&&&&&asp:Label&ID="PhoneLabel"&runat="server"&Text='&%#&Bind("Phone")&%&'&/&&&&&&&/ItemTemplate&&&/asp:FormView&&&&asp:ObjectDataSource&ID="SuppliersDataSource"&runat="server"&&&&&OldValuesParameterFormatString="original_{0}"&&&&&SelectMethod="GetSuppliers"&TypeName="SuppliersBLL"&&&/asp:ObjectDataSource&
图7 通过浏览器浏览 CustomButtons.aspx 页面
图7 :FormView 控件列出了当前选中的供应商的公司名称和***号码字段
步骤3 :添加一个GridView 控件列出所选供应商的各种产品
在我们为FormView 控件的模板添加 &Discontinue All Products& 按钮之前,先让我们在FormView 控件的下面添加一个 GridView 控件,列出所选供应商的各种产品。为了完成这个过程,您需要为页面添加一个 GridView 控件,将其 ID 属性赋值为供应商产品 ( SuppliersProducts ),并且还需要添加一个数据源对象,并将其命名为供应商产品数据源 ( SuppliersProductsDataSource )。
图8 :创建一个新的对象数据源 (ObjectDataSource) ,将其命名为供应商产品数据源 (SuppliersProductsDataSource)
配置该对象数据源,来使用 ProductsBLL 类的GetProductsBySupplierID (supplierID) 方法(请参见图 9 )。尽管考虑到 GridView 控件可能需要对产品价格进行调整,但是它不会使用 GridView 控件内置的编辑或删除功能。因此,我们可以将对象数据源的 UPDATE 、INSERT 和 DELETE 选项卡上的下拉菜单列表选项设置为 ( None )。
图9 :配置数据源,以使用 ProductsBLL 类的GetProductsBySupplierID (supplierID) 方法
因为 GetProductsBySupplierID (supplierID) 方法需要一个输入参数,所以对象数据源向导会提示我们为该数据源提供一个参数值。为了从 FormView 控件中传递 SupplierID 参数值,请将参数源下拉菜单列表设置为 Control ,将 ControID 下拉菜单列表设置为 Suppliers (在步骤 2 中创建了 FormView 控件的 ID )。
图10 :指示supplierID&应该来自供应商 FormView 控件
完成对象数据源向导后,GridView 将会为产品的每一个数据字段包含一个BoundField 或 CheckBoxField 。让我们把这个裁掉只显示 ProductName 、 UnitPrice BoundFields 以及 Discontinued CheckBoxField ;并且将 UnitPrice BoundField 进行格式化处理,将其格式化转换为货币单位。您的 GridView 控件和SuppliersProductsDataSource 对象数据源的公开标示文字应该和以下文字相似:
&asp:GridView&ID="SuppliersProducts"&AutoGenerateColumns="False"&&&&&DataKeyNames="ProductID"&DataSourceID="SuppliersProductsDataSource"&&&&&EnableViewState="False"&runat="server"&&&&&&&Columns&&&&&&&&&&&asp:BoundField&DataField="ProductName"&HeaderText="Product"&&&&&&&&&&&&&SortExpression="ProductName"&/&&&&&&&&&&&asp:BoundField&DataField="UnitPrice"&HeaderText="Price"&&&&&&&&&&&&&SortExpression="UnitPrice"&DataFormatString="{0:C}"&&&&&&&&&&&&&HtmlEncode="False"&/&&&&&&&&&&&asp:CheckBoxField&DataField="Discontinued"&HeaderText="Discontinued"&&&&&&&&&&&&&SortExpression="Discontinued"&/&&&&&&&/Columns&&&/asp:GridView&&&&asp:ObjectDataSource&ID="SuppliersProductsDataSource"&runat="server"&&&&&OldValuesParameterFormatString="original_{0}"&&&&&SelectMethod="GetProductsBySupplierID"&TypeName="ProductsBLL"&&&&&&&SelectParameters&&&&&&&&&&&asp:ControlParameter&ControlID="Suppliers"&Name="supplierID"&&&&&&&&&&&&&PropertyName="SelectedValue"&Type="Int32"&/&&&&&&&/SelectParameters&&&/asp:ObjectDataSource&
在这里,我们的教程手册显示了一个主/ 明细报表,允许用户从顶端的 FormView 控件中捡取一个供应商并通过底部的 GridView 控件浏览该供应商提供的各种产品。 图11 显示从 FormView 控件中选择 Tokyo Traders 时的一个截屏画面
图11 :在 GridView 控件中显示选定的供应商的产品
步骤4 :创建 DAL 和 BLL 方法,停售某个供应商的所有产品
我们可以为FormView 控件添加一个按钮,单击该按钮,停售该供应商的所有产品,要做到这一步,我们首先应该为 DAL 和 BLL 添加一个方法来执行这个操作。具体来说,该方法命名为 DiscontinueAllProductsForSupplier (supplierID) 。单击 FormView 控件的按钮后,将会在业务逻辑层激活该方法,并传递选定的供应商的 SupplierID ;接着 BLL 会调用到相应的数据访问层方法,该方法会调用 UPDATE 语句更新数据库从而停售指定供应商的产品。
如同在前面所做的那样,我们可以使用 自底而上手段 来创建 DAL 方法,接着再创建 BLL ,最终在 ASP.NET 页面中执行该功能。打开 App_Code/DAL 文件夹中的 Northwind.xsd 强类型 DataSet,为 ProductsTableAdapter 添加一个新的方法(在 ProductsTableAdapter 上单击右键,选择 Add Query )。这样做会引出 TableAdapter Query 配置向导,该向导会知道我们完成这个新方法的添加过程。首先需要指出的是我们的 DAL 方法会使用特别的 SQL 语句。
图12 :使用 Ad-Hoc SQL 语句创建 DAL 方法
接下来,向导会提示我们创建何种类型的查询 (Query) 。因为 DiscontinueAllProductsForSupplier (supplierID) 方法需要更新产品数据库表,将所有由指定的supplierID&供应商提供的产品的 Discontinued 字段赋值为 1 ,所以我们需要创建一个查询 ( Query ) 用来更新数据。
图13 :选择 UPDATE 查询类型
下一个向导画面显示的是 TableAdapter 的已有的 UPDATE 语句,这个语句可以更新产品数据表中定义的每一个字段。将这条查询语句替换为以下语句:
UPDATE [Products] SET Discontinued = 1 WHERE SupplierID = @SupplierID
输入该条语句后,单击下一步 (Next) ,最后一个向导画面会要求您提供新方法的名称,请使用 DiscontinueAllProductsForSupplier 。单击完成按钮完成整个向导。返回到 DataSet 设计器,你会在 ProductsTableAdapter 中看到一个名字为 DiscontinueAllProductsForSupplier (@SupplierID) 的新方法。
图14 :将新的 DAL 方法命名为 DiscontinueAllProductsForSupplier
有了在数据访问层创建的DiscontinueAllProductsForSupplier (supplierID) 方法,我们的下一个任务就是在业务逻辑层 (BLL) 创建DiscontinueAllProductsForSupplier (supplierID) 方法。添加这个方法需要打开 ProductsBLL 类文件,加入以下语句:
public&int&DiscontinueAllProductsForSupplier(int&supplierID)&{&&&&&return&Adapter.DiscontinueAllProductsForSupplier(supplierID);&}
该方法可以在数据访问层完全调用DiscontinueAllProductsForSupplier (supplierID) 方法,并传递提供的supplierID&参数值。如果有业务规则规定供应商的产品只能在某些情况下断货,那么这些规则应该在 BLL 中执行。
注意:与在 ProductsBLL 类中重载的 UpdateProduct 方法不同,DiscontinueAllProductsForSupplier (supplierID) 方法符号并不包含 DataObjectMethodAttribute 属性(&ponentModel.DataObjectMethodAttribute (ponentModel.DataObjectMethodType.Update,&Boolean) &) 。这样就可以在 UPDATE 选项卡中将 DiscontinueAllProductsForSupplier (supplierID) 方法 从对象数据源配置数据向导的下拉菜单列表中排除。我已经忽略了这个属性,因为我们直接从 ASP.NET 页面的 Event Handler 中调用 DiscontinueAllProductsForSupplier (supplierID) 方法。
步骤5 :为 FormView 控件添加&Discontinue All Products&按钮
在业务逻辑层和数据访问层中创建DiscontinueAllProductsForSupplier (supplierID) 方法后,为选定的供应商添加停售所有产品功能的最后一步是为FormView 控件的条目模板添加 Web 按钮控件。在供应商的***号码下方添加该按钮,按钮上的文字为 &Discontinue All Products& ,按钮的 ID 属性值为 DiscontinueAllProductsForSupplier 。您可以通过设计器单击 FormView 控件的智能标记(请参见图 15 )中的编辑模板或直接通过声明语句来添加 Web 按钮控件。
图15 :为 FormView 控件的条目模板添加 &Discontinue All Products& Web 按钮 控件
当访问该页面的用户单击该按钮时,会发生回传操作,紧接着FormView 控件的 ItemCommand 事件被触发。为了能够在单击该按钮时执行自定义代码,我们可以为该事件创建一个 Event Handler。可以这样理解,只要 FormView 控件内的任何按钮、链接按钮或位图按钮被单击,ItemCommand 事件都会被触发。这意味着当用户在 FormView 控件内从一个页面转移到另一个页面时,ItemCommand 事件会被触发。同样当用户单击支持插入、更新或删除的& FormView 控件内的新建 ( New )、编辑 ( Edit ) 或删除 ( Delete ) 按钮时,ItemCommand 事件也会被触发。
因为在 Event Handler 中,不管什么按钮被单击,ItemCommand 事件都会被触发,所以我们需要一种方法来确定是 &Discontinue All Products& 按钮被单击还是别的其它的按钮被单击。要做到这一点,我们可以将 Web 按钮控件的 CommandName 属性设置成某个标识值。当该按钮被单击后,该 CommandName 值被传递给 ItemCommand Event Handler,这样我们就可以判断是否是 &Discontinue All Products& 按钮被单击。将 &Discontinue All Products& 按钮的 CommandName 属性设置为 &DiscontinueProducts& 。
最后,我们可以使用一个客户端的确认对话框来确认用户是否确实想停售选定用户的产品。正如我们在&&教程中所看到的那样,这个功能也可以使用很少的 JavaScript 代码来实现。 特别需要注意的是需要将 Web 按钮控件的 OnClientClick 属性设置为 &return confirm('This will mark _all_ of this supplier\'s products as discontinued.Are you sure you want to do this?');"
完成这些操作后,FormView 控件的声明语句看起来 类似 下面的语句:
&asp:FormView&ID="Suppliers"&runat="server"&DataKeyNames="SupplierID"&&&&&DataSourceID="SuppliersDataSource"&EnableViewState="False"&&&&&AllowPaging="True"&&&&&&&ItemTemplate&&&&&&&&&&&h3&&asp:Label&ID="CompanyName"&runat="server"&&&&&&&&&&&&&Text='&%#&Bind("CompanyName")&%&'&&/asp:Label&&/h3&&&&&&&&&&&b&Phone:&/b&&&&&&&&&&&asp:Label&ID="PhoneLabel"&runat="server"&Text='&%#&Bind("Phone")&%&'&/&&&&&&&&&&&br&/&&&&&&&&&&&asp:Button&ID="DiscontinueAllProductsForSupplier"&runat="server"&&&&&&&&&&&&&CommandName="DiscontinueProducts"&Text="Discontinue&All&Products"&&&&&&&&&&&&&OnClientClick="return&confirm('This&will&mark&_all_&of&this&supplier\'s&&&&&&&&&&&&&&&&&products&as&discontinued.&Are&you&certain&you&want&to&do&this?');"&/&&&&&&&/ItemTemplate&&&/asp:FormView&
接下来,为FormView 控件的ItemCommand 事件创建一个 Event Handler 。在这个 Event Handler 中我们首先需要判断&Discontinue All Products& 按钮是否被单击。如果被单击,我们要创建一个 ProductsBLL 类的实例,并激活它的 DiscontinueAllProductsForSupplier (supplierID) 方法,传递选定的 FormView 控件的 SupplierID 值:
protected&void&Suppliers_ItemCommand(object&sender,&FormViewCommandEventArgs&e)&{&&&&&if&(pareTo("DiscontinueProducts")&==&0)&&&&&{&&&&&&&&&//&The&"Discontinue&All&Products"&Button&was&clicked.&&&&&&&&&//&Invoke&the&ProductsBLL.DiscontinueAllProductsForSupplier(supplierID)&method&&&&&&&&&&//&First,&get&the&SupplierID&selected&in&the&FormView&&&&&&&&&int&supplierID&=&(int)Suppliers.SelectedV&&&&&&&&&&//&Next,&create&an&instance&of&the&ProductsBLL&class&&&&&&&&&ProductsBLL&productInfo&=&new&ProductsBLL();&&&&&&&&&&//&Finally,&invoke&the&DiscontinueAllProductsForSupplier(supplierID)&method&&&&&&&&&productInfo.DiscontinueAllProductsForSupplier(supplierID);&&&&&}&}
注意,可以使用 FormView 控件的&&来访问当前在 FormView 控件中选定的 SupplierID 。 SelectedValue 属性返回 FormView 控件中显示的记录的第一数据键值。 FormView 控件的&, 指示说明了数据键值来自哪些数据字段,并且在前面的步骤 2 中当将对象数据源绑定到 FormView 控件时 Visual Studio 可以将该属性自动设置为 SupplierID 。
创建 ItemCommand Event Handler后,花点时间测试一下页面。浏览 Cooperativa de Quesos 'Las Cabras' 供应商(对我来说他是 FormView 控件中的第十五个供应商)。该供应商提供两种产品,Queso Cabrales 和 Queso Manchego La Pastora ,这两种产品都没有断货。
假设 Cooperativa de Quesos 'Las Cabras' 已经停止该产品的生产业务,那么他的产品将会断货。单击&&Discontinue All Products& 按钮。将会显示客户端的确认对话框 ( 请参见图 16) 。
图16 :Cooperativa de Quesos &Las Cabras 提供两种现行的产品
如果您单击客户端的确认对话框中的 OK 按钮,那么会继续提交表格,并引起回传,在该回传操作中,FormView 控件的 ItemCommand 事件将会被触发。接着我们创建的Event Handler 将会被执行,激活 DiscontinueAllProductsForSupplier (supplierID) 方法并停售 Queso Cabrales 和 Queso Manchego La Pastora 这两个产品。
如果您已经关闭了 GridView 控件的浏览状态,那么 GridView 控件会被重新绑定到存储在每一个回传操作上的底层数据上,并且会被立刻更新,以便及时反映这两个产品现在断货 ( 请参见图 17) . 但是如果您没有关闭 GridView 的浏览状态,您需要在完成这些更改后手动将数据绑定到Gridview 控件上。要做到这一点,您只需在激活 DiscontinueAllProductsForSupplier (supplierID) 方法后立刻调用 GridView 控件 DataBind () 方法即可。
图17 :单击 &Discontinue All Products& 按钮后,供应商的产品被相应的更新
步骤6 :在业务逻辑层创建一个 UpdateProduct 重载来调整产品价格
与FormView 控件具有 &Discontinue All Products& 按钮一样,为了增加用于提高或降低 Gridview 控件产品价格的按钮,我们首先需要添加合适的数据访问层和业务逻辑层方法。因为我们已经有一个方法能够更新数据访问层中的一行产品,所以我们可以在业务逻辑层 ( BLL ) 为 UpdateProduct 方法创建一个新的重载函数来提供该功能。
我们前面进行 UpdateProduct 重载包含了一些复合产品字段,将这些字段作为输入值,接着为指定产品更新这些字段。对于这个重载,我们稍微更改一下这个标准,而是传递产品的 ProductID 和调整 UnitPrice 的百分数(与传递的新建的已调整的 UnitPrice 本身相反)。这种方法可以简化需要我们写入 ASP.NET 页面代码文件类,因为我们不用再费功夫来确定当前产品的 UnitPrice 。
本教程中,UpdateProduct 方法重载如下:
public&bool&UpdateProduct(decimal&unitPriceAdjustmentPercentage,&int&productID)&{&&&&&Northwind.ProductsDataTable&products&=&Adapter.GetProductByProductID(productID);&&&&&if&(products.Count&==&0)&&&&&&&&&//&no&matching&record&found,&return&false&&&&&&&&&return&&&&&&&Northwind.ProductsRow&product&=&products[0];&&&&&&//&Adjust&the&UnitPrice&by&the&specified&percentage&(if&it's¬&NULL)&&&&&if&(!product.IsUnitPriceNull())&&&&&&&&&product.UnitPrice&*=&unitPriceAdjustmentP&&&&&&//&Update&the&product&record&&&&&int&rowsAffected&=&Adapter.Update(product);&&&&&&//&Return&true&if&precisely&one&row&was&updated,&otherwise&false&&&&&return&rowsAffected&==&1;&}
这个重载可以通过数据访问层的 GetProductByProductID (productID) 方法获取指定产品的信息。接着检查产品的 UnitPrice 是否被赋予了一个数据库 NULL 值。如果赋予了一个 NULL 值,那么价格照旧不变。如果是一个非 NULL 的 UnitPrice 值,该方法会按照指定百分数更新产品的 UnitPrice (unitPriceAdjustmentPercent)& .
步骤7 :为GridView 控件添加增加(Increase) 和降低(Decrease) 按钮
GridView 控件和 DetailsView 控件都是由一个字段集组成的。除了 BoundFields 字段、CheckBoxFields 字段和 TemplateFields 字段外,ASP.NET 页面还包括 ButtonField 字段,该字段正如它的名字所指的那样,为每一行呈递一列按钮、链接按钮或位图按钮。与 FormView 控件相似,单击 GridView 控件内的任何按钮:分页按钮、编辑按钮或删除按钮,筛选按钮等等,都会引起数据回发操作,并产生 GridView 控件的&&。
ButtonField 字段有一个 CommandName 属性,该属性为其每一个按钮的 CommandName 属性分配一个指定的值。与 FormView 控件一样,RowCommand Event Handler使用 CommandName 值来确定哪一个按钮被单击。
让我们为 GridView 控件添加两个新的按钮字段,一个按钮为 &Price +10%& ,另一个按钮为 &Price -10%& 。要添加这些 ButtonFields 字段,请单击 GridView 控件智能标记上的 Edit Columns 链接,从左上角的列表中选择 ButtonField 字段类型,然后单击 Add& 按钮。
图18 :为 GridView 添加两个 ButtonFields 按钮
首先移动这两个 ButtonFields 字段,这样它们就会成为 GridView 控件的前两个字段。接下来,将这两个字段的文本属性分别设置为 &Price +10%& 和 &Price -10%& ,将 CommandName 属性分别设置为 &IncreasePrice& 和 &DecreasePrice& 。默认情况下, ButtonField 会将它的按钮列作为链接按钮 ( LinkButtons )。当然,您可以更改这个设置,您只需通过 ButtonField 字段的 ButtonType 属性 就可以更改。现在我们要把这两个 ButtonFields 作为普通的按压按钮 ( Push Button ),所以需要为它设置 ButtonType 属性。图 19 显示的是字段对话框,该对话框出现在这些变更完成之后,接下来的是 GridView 控件的声明标记。
图19 :配置 ButtonFields 的文本、 CommandName 和 ButtonType 属性
&asp:GridView&ID="SuppliersProducts"&runat="server"&AutoGenerateColumns="False"&&&&&DataKeyNames="ProductID"&DataSourceID="SuppliersProductsDataSource"&&&&&EnableViewState="False"&&&&&&&Columns&&&&&&&&&&&asp:ButtonField&ButtonType="Button"&CommandName="IncreasePrice"&&&&&&&&&&&&&Text="Price&+10%"&/&&&&&&&&&&&asp:ButtonField&ButtonType="Button"&CommandName="DecreasePrice"&&&&&&&&&&&&&Text="Price&-10%"&/&&&&&&&&&&&asp:BoundField&DataField="ProductName"&HeaderText="Product"&&&&&&&&&&&&&SortExpression="ProductName"&/&&&&&&&&&&&asp:BoundField&DataField="UnitPrice"&HeaderText="Price"&&&&&&&&&&&&&SortExpression="UnitPrice"&DataFormatString="{0:C}"&&&&&&&&&&&&&HtmlEncode="False"&/&&&&&&&&&&&asp:CheckBoxField&DataField="Discontinued"&HeaderText="Discontinued"&&&&&&&&&&&&&SortExpression="Discontinued"&/&&&&&&&/Columns&&&/asp:GridView&
这些 ButtonFields 创建之后,最后一步就是为GridView 控件的RowCommand 事件创建一个Event Handler 。如果因为单击了 &Price +10%& 按钮或 &Price -10%& 按钮,触发了该 Event Handler,那么该句柄需要确定按钮被单击的那一行的 ProductID ,然后激活 ProductsBLL 类的 UpdateProduct 方法,并传递对应的 UnitPrice 调整百分数和 ProductID 。以下代码执行这些任务:
protected&void&SuppliersProducts_RowCommand(object&sender,&GridViewCommandEventArgs&e)&{&&&&&if&(pareTo("IncreasePrice")&==&0&||&&&&&&&&&pareTo("DecreasePrice")&==&0)&&&&&{&&&&&&&&&//&The&Increase&Price&or&Decrease&Price&Button&has&been&clicked&&&&&&&&&&//&Determine&the&ID&of&the&product&whose&price&was&adjusted&&&&&&&&&int&productID&=&&&&&&&&&&&&&(int)SuppliersProducts.DataKeys[Convert.mandArgument)].V&&&&&&&&&&//&Determine&how&much&to&adjust&the&price&&&&&&&&&decimal&percentageA&&&&&&&&&if&(pareTo("IncreasePrice")&==&0)&&&&&&&&&&&&&percentageAdjust&=&1.1M;&&&&&&&&&else&&&&&&&&&&&&&percentageAdjust&=&0.9M;&&&&&&&&&&&//&Adjust&the&price&&&&&&&&&ProductsBLL&productInfo&=&new&ProductsBLL();&&&&&&&&&productInfo.UpdateProduct(percentageAdjust,&productID);&&&&&}&}
为了确定&Price +10%& 按钮和 &Price -10%& 按钮被单击的那一行的 ProductID ,我们需要查阅 GridView 控件的 DataKeys 集合。该集合为 GridView 的每一行保存了指定的 DataKeyNames 属性中的各个字段的值。因为在将对象数据源绑定到 Gridview 控件时, GridView 控件的 DataKeyNames 属性被 Visual Stdio 设置为 ProductID ,所以 DataKeys (rowIndex).Value 为 ProductID 提供指定的&rowIndex&索引。
ButtonField 会自动通过 e.CommandArgument 参数传递按钮被单击的那一行的rowIndex&索引&。所以,为了确定是哪一行的 &Price +10%& 按钮或 &Price -10%& 按钮被单击的 ProductID ,我们使用:Convert.ToInt32(SuppliersProducts.DataKeys(Convert.mandArgument)).Value) .
如同 &Discontinue All Products& 按钮,如果您关闭了GridView 控件的视图状态,那么 GridView 控件会被重新绑定到每一个存储在回传操作上的底层数据上,并且会被立刻更新,以显示价格变化(因为单击其中一个按钮产生的变化)。但是如果您没有关闭 GridView 控件的视图状态,您需要在完成这些更改之后手动将数据重新绑定到 GridView 控件上。要完成这个绑定过程,您只需在激活 UpdateProduct 方法后立刻调用 GridView 控件的 DataBind() 方法即可。
图20 图示了由 Grandma Kelly's Homestead 供应的产品。图 21 图示了为 Grandma's Boysenberry Spread 单击两次&Price&+10%& 按钮的结果和为Northwoods Cranberry Sauce 单击两次 "Price&-10%& 按钮的结果。
图20 :含有 &Price&+10%& 按钮和 &Price&-10%& 按钮的 GridView 控件
图21 :第一个和第三个产品的价格已经通过 &Price&+10%& 按钮和&Price&-10%& 按钮进行了更新
注意:GridView 控件(和 DetailsView 控件)也可以将按钮、链接按钮或位图按钮添加到他们的TemplateFields 字段中。如同 BoundField 字段,单击这些按钮之后会引起回传操作,并产生 GridView 控件的 RowCommand 事件。尽管如此,当您在 TemplateField 字段中添加按钮时,按钮的 CommandArgument 不能自动设置为行的索引(当该按钮正在使用 ButtonFields 时)。如果您需要在 RowCommand Event Handler中确定被单击的按钮的行索引时,您需要在位于 TemplateField 内的声明语句中手动设置按钮的 CommandArgument 属性,使用代码如下:&asp:Button runat="server" ...CommandArgument='&%# CType(Container, GridViewRow).RowIndex %&'&/&.
GridView 控件、DetailsView 控件和 FormView 控件都可以包含按钮、链接按钮 (LinkButtons) 或位图按钮 (ImageButtons) 。当单击这些按钮时,都会引起回传操作并会在FormView& 控件和 DetailsView 控件中产生相应的 ItemCommand 事件,在 GridView 控件中产生 RowCommand 事件。这些 Web 数据控件具有一些内置的功能,这些功能可以处理一些常见的与命令相关的操作,例如删除或编辑记录。另外,我们还可以使用自定义的按钮,当单击这些按钮时会自动执行我们自己定义的代码,并做出响应。
要做到这一点,我们需要为 ItemCommand 事件或 RowCommand 事件创建一个 Event Handler 。在该 Event Handler 中,我们首先要检查引入的 CommandName 值,通过该值来确定哪一个按钮被单击,接着执行相应的用户自定义操作。在本教程中,我们了解了怎样使用按钮和 ButtonFields 来停售指定供应商的所有产品和按百分之十的幅度增加或减少每特定产品的价格。
快乐编程!
阅读(...) 评论() &

参考资料

 

随机推荐