★★★请问怎样在DataGrid中使用UserControl作为模板列???

ameng007 2003-03-17 10:54:52
我想通过LoadControl给DataGrid动态增加UserControl作为模板列,却总不成功,有谁能指点一二吗?
...全文
46 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
chyich 2003-03-21
  • 打赏
  • 举报
回复

给一个实际的例子,拷到你机子上,机子必须装了ms sql server, 然后修改一个连接数据库的字符串就可以运行,看能不能满足你的要求:
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>

<html>
<title>Dynamic Columns</title>
<style>
hr {height:2px;color:black;}
.StdText {font-family:verdana;font-size:9pt;font-weight:bold;}
.StdTextBox {font-family:verdana;font-size:9pt;border:solid 1px black;filter:progid:DXImageTransform.Microsoft.dropshadow(OffX=2, OffY=2, Color='gray', Positive='true')}
.Shadow {filter:progid:DXImageTransform.Microsoft.dropshadow(OffX=2, OffY=2, Color='gray', Positive='true')}
.Link {font-weight:bold;}
</style>


<script runat=server>
const String TEMPLATEFILE = "tplvb.ascx";

public void Page_Load(Object sender, EventArgs e)
{
// Initialize only the first time...
if (!Page.IsPostBack)
{
lblURL.Text = Request.Url + "<hr>";
grid.Attributes["ExtraColumns"] = "";
}
else
{
RestoreDynamicColumns();
}
}

public DataTable CreateDataSource()
{
SqlConnection conn = new SqlConnection(txtConn.Text);
SqlDataAdapter da = new SqlDataAdapter(txtCommand.Text, conn);

DataSet ds = new DataSet();
da.Fill(ds, "MyTable");
return ds.Tables["MyTable"];
}

public void OnLoadData(Object sender, EventArgs e)
{
grid.DataSource = CreateDataSource();
grid.DataBind();
}

public void OnAddColumnPosition(Object sender, EventArgs e)
{
AddBoundColumn("title", "Position");
grid.Attributes["ExtraColumns"] += "1,";
grid.DataSource = CreateDataSource();
grid.DataBind();
}

public void OnAddColumnCountry(Object sender, EventArgs e)
{
AddBoundColumn("country", "Country");
grid.Attributes["ExtraColumns"] += "2,";
grid.DataSource = CreateDataSource();
grid.DataBind();
}


public void OnAddColumnMore(Object sender, EventArgs e)
{
AddButtonColumn("More", "moreinfo");
grid.Attributes["ExtraColumns"] += "3,";
grid.DataSource = CreateDataSource();
grid.DataBind();
}

public void OnAddTemplateColumn(Object sender, EventArgs e)
{
AddTemplateColumnFromFile("Template", TEMPLATEFILE);
grid.Attributes["ExtraColumns"] += "4,";
grid.DataSource = CreateDataSource();
grid.DataBind();
}

public void AddTemplateColumnFromFile(String strHeader, String strFile)
{
TemplateColumn bc = new TemplateColumn();
bc.HeaderText = strHeader;
bc.ItemTemplate = Page.LoadTemplate(strFile);
grid.Columns.Add(bc);
}

public void AddBoundColumn(String strField, String strHeader)
{
BoundColumn bc = new BoundColumn();
bc.DataField = strField;
bc.HeaderText = strHeader;
grid.Columns.Add(bc);
}

public void AddButtonColumn(String strText, String strCmd)
{
ButtonColumn bc = new ButtonColumn();
bc.Text = strText;
bc.CommandName = strCmd;
grid.Columns.Add(bc);
}

public void OnReset(Object sender, EventArgs e)
{
grid.Attributes["ExtraColumns"] = "";
grid.Columns.Clear();
grid.DataSource = CreateDataSource();
grid.DataBind();
}

public void OnPostBack(Object sender, EventArgs e)
{
}

public void RestoreDynamicColumns()
{
// 1 - means column Position
// 2 - means column Country
// 3 - means column More

String buf = grid.Attributes["ExtraColumns"];

Char[] aSplitterChar = new Char[] {','};
String[] arrCols = buf.Split(aSplitterChar);

try {
foreach(String colCode in arrCols)
{
switch(colCode)
{
case "1":
AddBoundColumn("title", "Position");
break;
case "2":
AddBoundColumn("country", "Country");
break;
case "3":
AddButtonColumn("More", "moreinfo");
break;
case "4":
AddTemplateColumnFromFile("Template", TEMPLATEFILE);
break;
}
}
} catch {}
}

</script>


<body bgcolor="ivory" style="font-family:arial;font-size:9pt">

<!-- ASP.NET topbar -->
<h2>Adding Columns Programmatically - Templates from ASCX</h2>
<asp:Label runat="server" cssclass="StdText" font-bold="true">Current path: </asp:label>
<asp:Label runat="server" id="lblURL" cssclass="StdText" style="color:blue"></asp:label>

<form runat=server>

<table>
<tr>
<td><asp:label runat="server" text="Connection String" cssclass="StdText" /></td>
<td><asp:textbox runat="server" id="txtConn"
Enabled="false"
cssclass="StdTextBox"
width="400px"
text="DATABASE=Northwind;SERVER=localhost;UID=sa;PWD=;" /></td></tr>

<tr>
<td><asp:label runat="server" text="Command Text" cssclass="StdText"/></td>
<td><asp:textbox runat="server" id="txtCommand"
Enabled="false"
width="400px"
cssclass="StdTextBox"
text="SELECT * FROM Employees" /></td></tr></table>

<br>
<asp:linkbutton runat="server" id="btnLoad" text="Go get data..." onclick="OnLoadData" />

<hr>
<asp:linkbutton runat="server" text="Add column 'Position' ..." onclick="OnAddColumnPosition" cssclass="link" />
   
<asp:linkbutton runat="server" text="Add column 'Country' ..." onclick="OnAddColumnCountry" cssclass="link" />
   
<asp:linkbutton runat="server" text="Add column 'More' ..." onclick="OnAddColumnMore" cssclass="link" />
   
<asp:linkbutton runat="server" text="Add template column ..." onclick="OnAddTemplateColumn" cssclass="link" />
    |    
<asp:linkbutton runat="server" text="Post-back..." onclick="OnPostBack" cssclass="link" />
   
<asp:linkbutton runat="server" text="Reset ..." onclick="OnReset" cssclass="link" />

<hr>
<asp:label runat="server" id="lblOutput" />

<asp:DataGrid id="grid" runat="server" visible="true"
AutoGenerateColumns="false"
CssClass="Shadow" BackColor="white"
CellPadding="2" CellSpacing="2" GridLines="none"
BorderStyle="solid" BorderColor="black" BorderWidth="1"
font-size="x-small" font-names="verdana">

<AlternatingItemStyle BackColor="palegoldenrod" />
<ItemStyle BackColor="beige" />
<HeaderStyle ForeColor="white" BackColor="brown" Font-Bold="true" />

<columns>
<asp:BoundColumn runat="server" DataField="employeeid" HeaderText="ID" />
<asp:BoundColumn runat="server" DataField="firstname" HeaderText="First Name" />
<asp:BoundColumn runat="server" DataField="lastname" HeaderText="Last Name" />
</columns>
</asp:DataGrid>

</form>

</body>
</html>
ameng007 2003-03-21
  • 打赏
  • 举报
回复
属性需要赋值的,所以不能直接使用bc.ItemTemplate = Page.LoadTemplate(strFile);
而必需通过
MyUserControl EditControl=(MyUserControl)(APage.LoadControl("MyUserControl.ascx"));
EditControl.属性=“字段名”;
才可以呀
chyich 2003-03-20
  • 打赏
  • 举报
回复
在ascx中可以这样绑定数据啊
<%@ Language="VB" %>
<%#
DataBinder.Eval( _
CType(Container, DataGridItem).DataItem, "TitleOfCourtesy") + _
"<b>" + _
DataBinder.Eval( _
CType(Container, DataGridItem).DataItem, "LastName") + _
"</b>, " + _
DataBinder.Eval( _
CType(Container, DataGridItem).DataItem, "FirstName")
%>
ameng007 2003-03-20
  • 打赏
  • 举报
回复
to chyich() :
我不能直接 这样使用:bc.ItemTemplate = Page.LoadTemplate(strFile);
因为还要做数据绑定的工作。

chyich 2003-03-20
  • 打赏
  • 举报
回复
一样啊,你设一个属性,专门相存字段名就可以了.
DataBinder.Eval( _
CType(Container, DataGridItem).DataItem, "用属性替代")
chyich 2003-03-20
  • 打赏
  • 举报
回复
不能用loadcontrol方法,要用LoadTemplate方法,
strFile为你的用户usercontrol的虚拟路径(必须是虚拟路径)

TemplateColumn bc = new TemplateColumn();
bc.HeaderText = strHeader;
bc.ItemTemplate = Page.LoadTemplate(strFile);
grid.Columns.Add(bc);
ameng007 2003-03-20
  • 打赏
  • 举报
回复
谢谢 chyich() 。
因为这个UserControl是公用的,字段需要从外部传递才能使用。
ameng007 2003-03-19
  • 打赏
  • 举报
回复
大家不理我啦?!
ameng007 2003-03-18
  • 打赏
  • 举报
回复
UP
ameng007 2003-03-18
  • 打赏
  • 举报
回复
不好意思,我使用了一个类专门用于生成模板列,代码片断如下:
创建模板列时:
public void InstantiateIn(Control container)
{
if (使用usercontrol) //如果是普通控件就没问题!
{

MyUserControl EditControl=(MyUserControl)(APage.LoadControl("MyUserControl.ascx"));
EditControl.DataBinding += new EventHandler(this.BindData);
container.Controls.Add(EditControl);
}
else
{
...
}
}

数据绑定时:
public void BindData(object sender, EventArgs e)
{
if (使用usercontrol) //如果是普通控件就没问题!
{
MyUserControl EditControl=(MyUserControl) sender;
DataGridItem container = (DataGridItem)EditControl.NamingContainer;
string strValue = ((DataRowView) container.DataItem)["字段名"].ToString();
EditControl.Text = strValue;
}
{
...
}
}


当调用过程
private void DataGrid1_EditCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
DataGrid1.EditItemIndex = e.Item.ItemIndex;
DataGrid1.DataBind();
}

时,BindData过程的
EditControl.Text = strValue;
语句出错,调试信息:“未将对象引用设置到对象的实例”,好象模板列没创建似的!
gOODiDEA 2003-03-17
  • 打赏
  • 举报
回复
UserControl usercontrol1 = (UserControl) LoadControl ("xxx.ascx") ;
this.Controls.Add(usercontrol1);
gOODiDEA 2003-03-17
  • 打赏
  • 举报
回复
首先在aspx页面加入usercontrol的定义

然后在后值代码中:
UserControl usercontrol1 = (UserControl) LoadControl ("xxx.ascx") ;
this.Controls.Add(myusercontrol);
icyer 2003-03-17
  • 打赏
  • 举报
回复
in ItemDataBound event:

if (e.Item.ItemIndex >= 0)
{
//将User Control1加入到第一列中
e.Item.Cells[0].Controls.Add(Page.LoadControl("UserControl1.ascx"));
}
wanderzhou 2003-03-17
  • 打赏
  • 举报
回复
你的代码?错误是什么?没有详细说明,谁能帮你?
ameng007 2003-03-17
  • 打赏
  • 举报
回复
帮帮忙啦!

62,046

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧