您的位置:首页 > 其它

Ext.Net 1.2.0_利用 Ext.Net 自定义 GridPanel Ajax 控件

2011-10-09 21:08 447 查看

本文内容

概述
演示:利用 Ext.Net 自定义简单的 GridPanel 控件
   不封装的程序
   封装后的程序
修改记录
 

概述

最近研究 Ext.Net 的 Demo,看到 SimpleTask 例子,该例子利用 Ext.Net 自己封装了三个控件来使用,感觉不错。

其实,这种方式在 .NET 里很常见,但是由于 Ext.Net 自定义的 Ajax 控件,综合使用了 DOM、CSS 和 JavaScript,还是有一定难度。但是从另外一个角度来看,却比 .NET 简单很多。是不是很奇怪,因为 Ext.Net 有现成的操作 DOM、CSS 和 JavaScript 的框架,你只需要将它们集成到一起。

 

演示:利用 Ext.Net 自定义 GridPanel 控件

本节演示利用 Ext.Net 自定义简单的 GridPanel 控件。

不封装的程序 首先看看,在不封装的情况下,使用 GridPanel 控件。用于改变某行、或某列的的式样。代码如下:

[code]<%@ Page Language="C#" %>


 


<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


<html xmlns="http://www.w3.org/1999/xhtml">


<head runat="server">


<title>Ext.Net GridPanel 改变某行、或某列的的式样</title>


<style type="text/css">


.indoor-t


{


color: #fb223a;


}


.indoor-f


{


text-decoration: line-through;


color: gray;


}


</style>


 


<script type="text/javascript"> 
// 改变行式样
var getRowClass = function(r) {
var d = r.data;
 
if (d.Indoor) {
return "indoor-t";
}
else {
return "indoor-f";
}
 };
// 改变列式样
var template = '<span style="color:{0};">{1}</span>';
var changePriceStyle = function(value) {
return String.format(template, (value >= 5) ? "green" : "red", value);
 }; 
</script>
 
 
<script runat="server">
    protected void Chg_Click(object sender, DirectEventArgs e)
 {
   string Id = e.ExtraParams["Id"];
   string common = e.ExtraParams["Common"];
   bool indoor = Convert.ToBoolean(e.ExtraParams["Indoor"].ToString());
 
   // TODO 
   // Server-Side
 
   this.Store1.SuspendEvents(false);
 
   this.Store1.UpdateRecordField((object)Id, "Indoor", !indoor);
   this.Store1.ResumeEvents();
   this.Store1.FireEvent("datachanged", new JRawValue(this.Store1.ClientID));
 }   
</script>

 


</head>


<body>


<form id="form1" runat="server">


<ext:ResourceManager ID="ResourceManager1" runat="server" />


<ext:GridPanel ID="GridPanel1" runat="server" Width="600" Height="500" AutoExpandColumn="Common"


   Title="植物" Frame="true">


   <Store>


  <ext:Store ID="Store1" runat="server" GroupField="Light">


 <Proxy>


<ext:HttpProxy Method="GET" Url="Data/PlantService.asmx/Plants" />


 </Proxy>


 <Reader>


<ext:XmlReader Record="Plant" IDPath="Id">


    <Fields>


   <ext:RecordField Name="Id" />


   <ext:RecordField Name="Common" />


   <ext:RecordField Name="Botanical" />


   <ext:RecordField Name="Zone" Type="Int" />


   <ext:RecordField Name="ColorCode" />


   <ext:RecordField Name="Light" />


   <ext:RecordField Name="Price" Type="Float" />


   <ext:RecordField Name="Availability" Type="Date" />


   <ext:RecordField Name="Indoor" Type="Boolean" />


    </Fields>


</ext:XmlReader>


 </Reader>


 <SortInfo Field="Common" Direction="ASC" />


  </ext:Store>


   </Store>


   <ColumnModel ID="ColumnModel1" runat="server">


  <Columns>


 <ext:Column ColumnID="Id" Header="Key" DataIndex="Id" Width="10" />


 <ext:Column ColumnID="Common" Header="Common Name" DataIndex="Common" Width="220" />


 <ext:Column Header="Light" DataIndex="Light" Width="130" />


 <ext:Column Header="Price" DataIndex="Price" Width="70" Align="right" Groupable="false">


<Renderer Format="UsMoney" />


 </ext:Column>


 <ext:Column Header="Price" DataIndex="Price" Width="70" Align="right" Groupable="false">


<Renderer Fn="changePriceStyle" />


 </ext:Column>


 <ext:DateColumn Header="Available" DataIndex="Availability" Width="95" Groupable="false"


Format="yyyy-MM-dd" />


 <ext:Column Header="Indoor?" DataIndex="Indoor" Width="55" />


 <ext:ImageCommandColumn Width="110">


<Commands>


    <ext:ImageCommand CommandName="Change" Icon="TableEdit" Text="改变">


   <ToolTip Text="改变" />


    </ext:ImageCommand>


</Commands>


 </ext:ImageCommandColumn>


  </Columns>


   </ColumnModel>


   <DirectEvents>


  <Command OnEvent="Chg_Click">


 <ExtraParams>


<ext:Parameter Name="Id" Value="record.id" Mode="Raw">


</ext:Parameter>


<ext:Parameter Name="Common" Value="record.data.Common" Mode="Raw">


</ext:Parameter>


<ext:Parameter Name="Indoor" Value="record.data.Indoor" Mode="Raw">


</ext:Parameter>


 </ExtraParams>


  </Command>


   </DirectEvents>


   <LoadMask ShowMask="true" />


   <SelectionModel>


  <ext:RowSelectionModel ID="RowSelectionModel1" runat="server" />


   </SelectionModel>


   <View>


  <ext:GroupingView ID="GroupingView1" HideGroupedColumn="true" runat="server" ForceFit="true"


 StartCollapsed="true">


 <GetRowClass Fn="getRowClass" />


  </ext:GroupingView>


   </View>


   <Buttons>


  <ext:Button ID="btnToggleGroups" runat="server" Text="展开/收起分组" Icon="TableSort" Style="margin-left: 6px;"


 AutoPostBack="false">


 <Listeners>


<Click Handler="#{GridPanel1}.getView().toggleAllGroups();" />


 </Listeners>


  </ext:Button>


   </Buttons>


</ext:GridPanel>


</form>


</body>


</html>

[/code]

运行界面:





图1 不封装的 GridPanel

[code]<webServices>


<protocols>


<add name="HttpGet"/>


<add name="HttpPost"/>


</protocols>


</webServices>

[/code]

Store 还规定了 GridPanel 分组的字段,"GroupField="Light"。并且规定 Store 的主键,"<ext:XmlReader Record="Plant" IDPath="Id">";

2,服务器端事件。为了改变某行的式样,需要根据行ID,更新 Store 的记录,并触发 Store 的 datachanged 事件。

 

封装后的程序

接下来,看看如何封装这个功能。先看界面,然后再说明如何实现。

[code]
[code]<%@ Page Language="C#" %>


 


<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>


<%@ Register Assembly="ExtNetCustomControl" Namespace="ExtNetCustomControl.MyCustom"


TagPrefix="MyControl" %>


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


<html xmlns="http://www.w3.org/1999/xhtml">


<head runat="server">


<title>Ext.Net GridPanel 改变某行、或某列的的式样</title>


<ext:ResourcePlaceHolder ID="ResourcePlaceHolder1" runat="server" Mode="ScriptFiles" />


<link href="resources/main.css" rel="stylesheet" type="text/css" />


<style type="text/css">


.indoor-t


{


color: #fb223a;


}


.indoor-f


{


text-decoration: line-through;


color: gray;


}


</style>


 


<script src="resources/myGrid.js" type="text/javascript"></script>


 


</head>


<body>


<form id="form1" runat="server">


<ext:ResourceManager ID="ResourceManager1" runat="server" InitScriptMode="Linked"


   DirectEventUrl="MyCustomGrid.aspx" RemoveViewState="true" IDMode="Explicit" />


<ext:Panel ID="Panel1" runat="server" Width="600" Height="600" AutoScroll="true">


   <Items>


  <MyControl:MyGrid ID="MyGrid1" runat="server" AutoHeight="true" />


   </Items>


</ext:Panel>


</form>


</body>


</html>

[/code]
[/code]

说明:

1,这个界面比之前简单多了。

定义 MyGrid 分部类,分别实现控件的 UI 和逻辑代码,如下所示:

[code]using System;


using System.Collections.Generic;


using System.ComponentModel;


using System.Linq;


using System.Xml.Serialization;


using Ext.Net;


using Newtonsoft.Json;


 


namespace ExtNetCustomControl.MyCustom


{


public partial class MyGrid : GridPanel


{


   private Store store;


 


   public MyGrid()


{


  this.Title = "植物";


  this.Width = System.Web.UI.WebControls.Unit.Pixel(600);


  this.Height = System.Web.UI.WebControls.Unit.Pixel(500);


  this.Frame = true;


  this.AutoExpandColumn = "Common";


 


  this.LoadMask.ShowMask = true;


 


  this.SelectionModel.Add(new RowSelectionModel());


 


  this.View.Add(new GroupingView


{


 HideGroupedColumn = true,


 ForceFit = true,


 StartCollapsed = true,


 GetRowClass = { Fn = MyGrid.SCOPE + ".getRowClass" }


});


 


  this.BuildStore();


  this.BuildColumnModel();


  this.InitLogic();


}


 


   private void BuildColumnModel()


{


  ColumnModel cm = this.ColumnModel;


  cm.Columns.Add(new Column


  {


    ColumnID = "Id",


    Header = "Key",


    Width = 10,


    DataIndex = "Id"


  });


 


  cm.Columns.Add(new Column


  {


    ColumnID = "Common",


    Header = "Common Name",


    Width = 220,


    DataIndex = "Common"


  });


 


  cm.Columns.Add(new Column


  {


    Header = "Light",


    Width = 130,


    DataIndex = "Light"


  });


 


  cm.Columns.Add(new Column


  {


    Header = "Price",


    Width = 70,


    DataIndex = "Price",


    Align = Ext.Net.Alignment.Right,


    Groupable = false,


    Renderer = new Renderer { Format = Ext.Net.RendererFormat.UsMoney }


  });


 


  cm.Columns.Add(new Column


{


 Header = "Price",


 Width = 70,


 DataIndex = "Price",


 Align = Ext.Net.Alignment.Right,


 Groupable = false,


 Renderer = new Renderer { Fn = MyGrid.SCOPE + ".changePriceStyle" }


});


  cm.Columns.Add(new DateColumn


{


 Header = "Available",


 Width = 95,


 DataIndex = "Availability",


 Format = "yyyy-MM-dd",


 Groupable = false


});


  cm.Columns.Add(new Column


{


 Header = "Indoor?",


 Width = 55,


 DataIndex = "Indoor"


});


  cm.Columns.Add(new ImageCommandColumn


{


 Commands = 


{ 


new ImageCommand 


{ 


    CommandName = "Change", 


    Icon = Icon.TableEdit, 


    Text = "改变"


} 


}


});


}


 


   private void BuildStore()


{


  this.store = new Store


{


  Reader =


 {


 new Ext.Net.XmlReader


{


Record="Plant",


IDPath="Id",


Fields =


{


    new RecordField("Id"),


    new RecordField("Common"),


    new RecordField("Botanical"),


    new RecordField("Zone",RecordFieldType.Int),


    new RecordField("ColorCode"),


    new RecordField("Light"),


    new RecordField("Price", RecordFieldType.Float),


    new RecordField("Availability", RecordFieldType.Date),


    new RecordField("Indoor", RecordFieldType.Boolean)


}


}


 },


  SortInfo =


 {


 Field = "Common",


 Direction = SortDirection.ASC


 },


  GroupField = "Light",


  Proxy =


 {


 new HttpProxy { Method=Ext.Net.HttpMethod.GET,Url="Data/PlantService.asmx/Plants"}


 }


};


  this.Store.Add(this.store);


}


}


}

[/code]

[code]using System;


using System.Collections.Generic;


using System.Linq;


 


using Ext.Net.Utilities;


using Ext.Net;


 


namespace ExtNetCustomControl.MyCustom


{


[DirectMethodProxyID(IDMode = DirectMethodProxyIDMode.None)]


public partial class MyGrid


{


   public const string SCOPE = "MyCustom.MyGrid";


 


   private void InitLogic()


{


  this.Listeners.Render.Fn = MyGrid.SCOPE + ".init";


  this.Listeners.Render.Scope = MyGrid.SCOPE;


 


  ComponentDirectEvent command = this.DirectEvents.Command;


  command.Event += Command_Event;


  command.ExtraParams.Add(new Parameter("Id", "record.id", ParameterMode.Raw));


  command.ExtraParams.Add(new Parameter("Common", "record.data.Common", ParameterMode.Raw));


  command.ExtraParams.Add(new Parameter("Indoor", "record.data.Indoor", ParameterMode.Raw));


 


  Ext.Net.Button button = new Button();


  button.ID = "btnToggleGroups";


  button.Text = "展开/收起分组";


  button.Icon = Icon.TableSort;


  button.AutoPostBack = false;


  button.Listeners.Click.Handler = MyGrid.SCOPE + ".toggleAllGroups();";


  this.Buttons.Add(button);


}


   protected void Command_Event(object sender, DirectEventArgs e)


{


  string Id = e.ExtraParams["Id"];


  string common = e.ExtraParams["Common"];


  bool indoor = Convert.ToBoolean(e.ExtraParams["Indoor"].ToString());


 


  // TODO 


  // Server-Side


 


  this.store.SuspendEvents(false);


 


  this.store.UpdateRecordField((object)Id, "Indoor", !indoor);


  this.store.ResumeEvents();


  this.store.FireEvent("datachanged", new JRawValue(this.store.ClientID));


}


 


   protected override void OnLoad(EventArgs e)


{


  if (!Ext.Net.X.IsAjaxRequest)


{


 this.ResourceManager.AddDirectMethodControl(this);


}


}


}


}

[/code]

说明:

以上两段代码实现的是同一个类,分别用来实现控件的UI和逻辑。UI部分完成创建控件的标记;逻辑部分完成控件的事件,包括客户端事件和服务器端事件;

注意 InitLogic 函数的前两行。当该控件实例化、并呈现后,调用客户端脚本 MyCustom.MyGrid.init 函数,用该实例化的控件初始化客户端脚本 MyGrid 对象的全局变量 grid。同时,还设置了该控件的作用域。

但光有这个类还不够,还要跟它配合的客户端脚本,如下所示:

[code]Ext.ns("MyCustom");


 


// ------------------MyGrid----------------------------------


MyCustom.MyGrid = {


init: function(grid) {


   this.grid = grid;


},


 


getRowClass: function(r) {


   var d = r.data;


   if (d.Indoor) {


  return "indoor-t";


}


   else {


  return "indoor-f";


}


   return "";


},


 


changePriceStyle: function(value) {


   var template = '<span style="color:{0};">{1}</span>';


   return String.format(template, (value >= 5) ? "green" : "red", value);


},


 


toggleAllGroups: function() {


   this.grid.getView().toggleAllGroups();


}


};

[/code]

说明:

该客户端脚本,创建了一个命名空间 MyCustom,并在该命名空间里创建 MyGrid 对象。

值得注意的是 init 函数。当在页面引入 <%@ Register Assembly="ExtNetCustomControl" Namespace="ExtNetCustomControl.MyCustom" TagPrefix="MyControl" %> 标记,那么 Web 应用程序运行时,自定义控件 MyGrid 被实例化。在客户端呈现后,会调用客户端脚本 MyCustom.MyGrid.init 方法,从而初始化 MyCustom.MyGrid 的 grid 属性,以便之后在客户端用脚本操作该自定义控件。

另外,MyCustom.MyGrid 的 grid 属性被初始化后,它是 Ext.Net.GridPanel 类的一个实例。

 

修改记录

第一次 2011-12-23 [UPDATE] 封装后的程序小节的说明部分。

 

下载 Demo
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: