使用ASP.NET Atlas ItemView控件显示集合中的单个数据

English Version: http://dflying.dflying.net/1/archive/114_display_one_item_in_a_collection_using_aspnet_atlas_itemview_control.html

在这个系列中,我将介绍一些Atlas Sys.UI.Data中较高级的控件,包括:

 

  1. Sys.UI.Data.ListView使用ASP.NET Atlas ListView控件显示列表数据
  2. Sys.UI.Data.ItemView使用ASP.NET Atlas ItemView控件显示集合中的单个数据
  3. Sys.UI.Data.DataNavigator使用 ASP.NET Atlas PageNavigator控件实现客户端分页导航 
  4. Sys.UI.Data.SortBehavior使用ASP.NET Atlas SortBehavior实现客户端排序
  5. Sys.UI.Data.XSLTView使用ASP.NET Atlas XSLTView控件用XSLT修饰并显示XML数据
这篇是其中的第二篇: 使用ASP.NET Atlas ItemView控件显示集合中的单个数据

 

有时候我们需要显示给用户列表中某一项的详细信息,例如,在购物程序中的产品详细情况。ASP.NET Atlas ItemView客户端控件为您提供了对这项功能的支持,就像ASP.NET服务器端控件DetailsView一样,但Atlas ItemView控件完全在客户端运行。

ItemView类(ListView类同样,见使用ASP.NET Atlas ListView控件显示列表数据 )继承于Sys.UI.Data.DataControl基类。该基类提供了一些公共的属性,包括:

  1. canMoveNext:当前记录后是否有下一条记录。
  2. canMovePrevious:当前记录前是否有前一条记录。
  3. data:控件包含的数据集合。
  4. dataIndex:当前记录的index。
  5. dataItem:基于dataIndex的当前的记录。
  6. length:记录的条目数。

同时还包括下列方法:

  1. addItem:添加一条记录到当前的数据集合中。
  2. deleteCurrentItem:删除基于dataIndex的当前记录。
  3. moveNext:如果canMoveNext为true,将dataIndex加1,指向下一条记录。
  4. movePrevious:如果canMovePrevious为true,将dataIndex减1,指向前一条记录。

 

请注意所有的以上操作都仅在客户端,也就是说只修改了客户端的数据。所以如果您希望将改变提交到服务器,则需要调用 DataSource 的相应方法。

ItemView通过继承获得了以上的属性和方法,并且还对基类有如下扩展:

  1. itemTemplate:指定项目模版。Atlas可以根据这个模版渲染您的内容。
  2. emptyTemplate:指定无数据时的模版。当数据集合为空或者DataSource还在取得数据的过程中时,Atlas会显示这个模版。

以上是ItemView的简要介绍。让我们通过一个例子来熟悉ItemView。这个程序基于Atlas官方发布的示例程序,并适当做了一些简化。

首先暴露一个Web Service以被Atlas使用。

定义item entry类:

ContractedBlock.gif ExpandedBlockStart.gif class Entry
None.gifpublic class Entry
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    
private string _name;
InBlock.gif    
private string _description;
InBlock.gif    
private int _id;
InBlock.gif
InBlock.gif    [DataObjectField(
truetrue)]
InBlock.gif    
public int Id
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
get dot.gifreturn _id; }
ExpandedSubBlockStart.gifContractedSubBlock.gif        
set dot.gif{ _id = value; }
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    [DataObjectField(
false)]
InBlock.gif    [DefaultValue(
"New row")]
InBlock.gif    
public string Name
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
get dot.gifreturn _name; }
ExpandedSubBlockStart.gifContractedSubBlock.gif        
set dot.gif{ _name = value; }
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    [DataObjectField(
false)]
InBlock.gif    [DefaultValue(
"")]
InBlock.gif    
public string Description
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
get dot.gifreturn _description; }
ExpandedSubBlockStart.gifContractedSubBlock.gif        
set dot.gif{ _description = value; }
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
public Entry()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        _id 
= -1;
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
public Entry(int id, string name, string description)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        _id 
= id;
InBlock.gif        _name 
= name;
InBlock.gif        _description 
= description;
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

 

定义 Web Methods 。我们需要提供 Select , Insert , Update 以及 Delete 方法以期对我们的数据集合进行完整的 CRUD 操作。注意到我们在初始化数据时使用了 System.Threading.Thread.Sleep(2000) 来模拟两秒钟的网络延迟,这样可以看到 emptyTemplate 中的内容。
ContractedBlock.gif ExpandedBlockStart.gif Data Service
None.gif[WebService(Namespace = "http://tempuri.org/")]
None.gif[WebServiceBinding(ConformsTo 
= WsiProfiles.BasicProfile1_1)]
None.gif
public class MyDataService : DataService
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    
static List<Entry> _data;
InBlock.gif    
static int _nextId;
InBlock.gif    
static object _dataLock = new object();
InBlock.gif
InBlock.gif    
private static List<Entry> Data
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
get
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if (_data == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
lock (_dataLock)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
if (_data == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        System.Threading.Thread.Sleep(
2000);
InBlock.gif                        
InBlock.gif                        _data 
= new List<Entry>();
InBlock.gif                        _data.Add(
new Entry(0"ListView""A control to display data using templates."));
InBlock.gif                        _data.Add(
new Entry(1"Window""A control to display dialogs."));
InBlock.gif                        _data.Add(
new Entry(2"Weather""A control to display local weather."));
InBlock.gif                        _nextId 
= 3;
ExpandedSubBlockEnd.gif                    }

ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

InBlock.gif            
return _data;
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    [DataObjectMethod(DataObjectMethodType.Delete)]
InBlock.gif    
public void DeleteRow(int id)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
foreach (Entry row in _data)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if (row.Id == id)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
lock (_dataLock)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    _data.Remove(row);
ExpandedSubBlockEnd.gif                }

InBlock.gif                
break;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    [DataObjectMethod(DataObjectMethodType.Select)]
InBlock.gif    
public Entry[] SelectRows()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
return MyDataService.Data.ToArray();
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    [DataObjectMethod(DataObjectMethodType.Insert)]
InBlock.gif    
public Entry InsertRow(string name, string description)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        Entry newRow;
InBlock.gif        
lock (_dataLock)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            newRow 
= new Entry(_nextId++, name, description);
InBlock.gif            _data.Add(newRow);
ExpandedSubBlockEnd.gif        }

InBlock.gif        
return newRow;
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    [DataObjectMethod(DataObjectMethodType.Update)]
InBlock.gif    
public void UpdateRow(Entry updateRow)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
foreach (Entry row in _data)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if (row.Id == updateRow.Id)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                row.Name 
= updateRow.Name;
InBlock.gif                row.Description 
= updateRow.Description;
InBlock.gif                
break;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}
然后,在 ASP.NET 中加入必须的标记,控件以及 ItemView 的模版。我们需要添加如下五部分的脚本:
  1. Atlas服务器端控件ScriptManager。所有的Atlas页面中都需要包含这个控件以装载Atlas所必须的JavaScript文件。
  2. id为detailsView的<div>,将被Atlas用来输出渲染后的内容。
  3. 导航部分,用于在在客户端集合中导航,以显示集合中不同的记录。
  4. 命令部分,用于修改,添加,删除记录(在客户端),并且提交到服务器。
  5. 模版部分,用于指定相应的ItemView模版。所有的模版将被置于一个隐藏的div中,这样不会在页面上显示出来。

None.gif <!--  ScriptManager  -->
None.gif
< atlas:ScriptManager  runat ="server"  ID ="scriptManager"   />
None.gif
None.gif
<!--  Element for ItemView (container)  -->
None.gif
< div  id ="detailsView" >
None.gif
</ div >
None.gif
None.gif
<!--  Navigators  -->
None.gif
< input  type ="button"  id ="previousButton"  value ="<"  title ="Go to previous row"   />
None.gif
< span  id ="rowIndexLabel" ></ span >
None.gif
< input  id ="nextButton"  type ="button"  value =">"  title ="Go to next row"   />
None.gif|
None.gif
None.gif
<!--  Commands  -->
None.gif
< input  type ="button"  id ="addButton"  value ="New"  title ="Create a new row"   />
None.gif
< input  type ="button"  id ="delButton"  value ="Delete"  title ="Delete the current row"   />
None.gif|
None.gif
< input  type ="button"  id ="saveButton"  value ="Save"  title ="Save all pending changes"   />
None.gif
< input  type ="button"  id ="refreshButton"  value ="Refresh"  title ="Discard pending changes and get the latest data from the server"   />
None.gif
None.gif
<!--  Templates  -->
None.gif
< div  style ="visibility: hidden; display: none" >
None.gif    
< div  id ="detailsTemplate" >
None.gif        Name:
None.gif        
< input  id ="nameField"  size ="30"   />< br  />
None.gif        Description:
< br  />
None.gif        
< textarea  id ="descriptionField"  rows ="4"  cols ="40" ></ textarea >< br  />
None.gif    
</ div >
None.gif    
< div  id ="emptyTemplate" >
None.gif        Getting Datadot.gif
None.gif    
</ div >
None.gif
</ div >

最后需要做的是在页面上添加Atlas脚本。

下面是DataSource的脚本:

None.gif < dataSource  id ="dataSource"  serviceURL ="MyDataService.asmx"  autoLoad ="true"   />

 

下面是 ItemView 的脚本。我们将绑定上面的 DataSource 控件作为数据源,并且将 ItemView 的 enabled 属性绑定到 DataSource 的 isReady 属性上,以期在数据源没有装载完成前禁用 ItemView 。同样为 ItemView 定义了 itemTemplate 和 emptyTemplate 。
None.gif < itemView  id ="detailsView" >
None.gif    
< bindings >
None.gif        
< binding  dataContext ="dataSource"  dataPath ="data"  property ="data" />
None.gif        
< binding  dataContext ="dataSource"  dataPath ="isReady"  property ="enabled" />
None.gif    
</ bindings >
None.gif    
< itemTemplate >
None.gif        
< template  layoutElement ="detailsTemplate" >
None.gif            
< textBox  id ="nameField" >
None.gif                
< bindings >
None.gif                    
< binding  dataPath ="Name"  property ="text"  direction ="InOut" />
None.gif                
</ bindings >
None.gif            
</ textBox >
None.gif            
< textBox  id ="descriptionField" >
None.gif                
< bindings >
None.gif                    
< binding  dataPath ="Description"  property ="text"  direction ="InOut" />
None.gif                
</ bindings >
None.gif            
</ textBox >
None.gif        
</ template >
None.gif    
</ itemTemplate >
None.gif    
< emptyTemplate >
None.gif        
< template  layoutElement ="emptyTemplate"   />
None.gif    
</ emptyTemplate >
None.gif
</ itemView >

下面是导航部分的脚本。我们提供了一个label用来显示当前的记录编号(记录index加上1,使用了Atlas的Add transformer。关于Atlas transformer,您可以参考:在ASP.NET Atlas中创建自定义的Transformer )。还提供了前后移动记录的导航按钮(通过使用Atlas的InvokeMethod action调用相应的ItemView的方法)。

None.gif < button  id ="previousButton" >
None.gif    
< bindings >
None.gif        
< binding  dataContext ="detailsView"  dataPath ="canMovePrevious"  property ="enabled" />
None.gif    
</ bindings >
None.gif    
< click >
None.gif        
< invokeMethod  target ="detailsView"  method ="movePrevious"   />
None.gif    
</ click >
None.gif
</ button >
None.gif
None.gif
< label  id ="rowIndexLabel" >
None.gif    
< bindings >
None.gif        
< binding  dataContext ="detailsView"  dataPath ="dataIndex"  property ="text"  transform ="Add"   />
None.gif    
</ bindings >
None.gif
</ label >
None.gif
None.gif
< button  id ="nextButton" >
None.gif    
< bindings >
None.gif        
< binding  dataContext ="detailsView"  dataPath ="canMoveNext"  property ="enabled" />
None.gif    
</ bindings >
None.gif    
< click >
None.gif        
< invokeMethod  target ="detailsView"  method ="moveNext"   />
None.gif    
</ click >
None.gif
</ button >

下面是命令部分的脚本。这里我们能够在客户端添加/删除记录,并将改变提交给服务器或者放弃提交。

None.gif < button  id ="addButton" >
None.gif    
< bindings >
None.gif        
< binding  dataContext ="dataSource"  dataPath ="isReady"  property ="enabled" />
None.gif    
</ bindings >
None.gif    
< click >
None.gif        
< invokeMethod  target ="detailsView"  method ="addItem"   />
None.gif    
</ click >
None.gif
</ button >
None.gif
None.gif
< button  id ="delButton" >
None.gif    
< bindings >
None.gif        
< binding  dataContext ="dataSource"  dataPath ="isReady"  property ="enabled" />
None.gif    
</ bindings >
None.gif    
< click >
None.gif        
< invokeMethod  target ="detailsView"  method ="deleteCurrentItem"   />
None.gif    
</ click >
None.gif
</ button >
None.gif
None.gif
< button  id ="saveButton" >
None.gif    
< bindings >
None.gif        
< binding  dataContext ="dataSource"  dataPath ="isDirtyAndReady"  property ="enabled" />
None.gif    
</ bindings >
None.gif    
< click >
None.gif        
< invokeMethod  target ="dataSource"  method ="save"   />
None.gif    
</ click >
None.gif
</ button >
None.gif
None.gif
< button  id ="refreshButton" >
None.gif    
< bindings >
None.gif        
< binding  dataContext ="dataSource"  dataPath ="isReady"  property ="enabled" />
None.gif    
</ bindings >
None.gif    
< click >
None.gif        
< invokeMethod  target ="dataSource"  method ="load"   />
None.gif    
</ click >
None.gif
</ button >

大功告成,可以在浏览器中测试了。

装载中:
itemview1.JPG

装载完成:
itemview2.JPG

记录间导航:
itemview3.JPG

修改并保存:
itemview4.JPG

上述示例代码可以在此处下载:http://files.cnblogs.com/dflying/AtlasItemViewDemo.zip

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RecyclerView 是 Android 开发常用的一个控件,用于实现列表显示。下面是实现 RecyclerView 列表的步骤: 1. 在布局文件添加 RecyclerView 控件: ```xml <androidx.recyclerview.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" /> ``` 2. 创建列表项的布局文件,例如 item_layout.xml: ```xml <TextView android:id="@+id/text_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="18sp" android:padding="16dp" /> ``` 3. 创建一个 Adapter 类,继承自 RecyclerView.Adapter,并实现以下方法: - onCreateViewHolder:创建 ViewHolder 对象,用于显示列表项。 - onBindViewHolder:将数据绑定到 ViewHolder 上,显示列表项的内容。 - getItemCount:返回列表项的数量。 ```java public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> { private List<String> mData; public MyAdapter(List<String> data) { mData = data; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout, parent, false); ViewHolder holder = new ViewHolder(view); return holder; } @Override public void onBindViewHolder(ViewHolder holder, int position) { String text = mData.get(position); holder.textView.setText(text); } @Override public int getItemCount() { return mData.size(); } static class ViewHolder extends RecyclerView.ViewHolder { TextView textView; public ViewHolder(View itemView) { super(itemView); textView = itemView.findViewById(R.id.text_view); } } } ``` 4. 在 Activity 或 Fragment 使用 RecyclerView: - 创建 RecyclerView 对象,并设置 LayoutManager(可以是 LinearLayoutManager、GridLayoutManager 等)。 - 创建 Adapter 对象,并设置给 RecyclerView。 - 给 RecyclerView 设置数据源。 ```java public class MainActivity extends AppCompatActivity { private RecyclerView mRecyclerView; private MyAdapter mAdapter; private List<String> mData = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mRecyclerView = findViewById(R.id.recycler_view); mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); mAdapter = new MyAdapter(mData); mRecyclerView.setAdapter(mAdapter); mData.add("Item 1"); mData.add("Item 2"); mData.add("Item 3"); mAdapter.notifyDataSetChanged(); } } ``` 通过以上步骤,就可以在 Android 应用使用 RecyclerView 实现列表显示了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值