这个问题反复在论坛出现,其实这个问题在MSDN上早就有答案
1。英文版:Top Questions about the DataGrid Web Server Control(Mike Pope and Nikhil Kothari)
2。中文版:DataGrid Web 伺服器控制项的常见问题

可惜,论坛上的风气不太好,你即使给了连接,真正去看的人大概并不多

诀窍是,如果动态添加了列的话,需要在下一次PostBack时,在LoadViewState或更早把这些列重新添加。原因是,在Page类递归调用LoadViewState时,会调用DataGrid的CreateChildControls,而DataGrid的(实际上是它的父类的实现)CreateChildControls会调用DataGrid的CreateControlHierarchy()方法。在其中,DataGrid会根据当前的列的数目构造DataGridItem里的东西,然后从ViewState里恢复原来的数据。如果你没有重新添加你的动态列的话,你的动态列在PostBack后就会消失,更不用谈触发列里的控件的事件了

检验你的动态控件在PostBack后是否还在的一个方法是,加一个按钮看PostBack后的行为

下面是一个简单的测试

 

 1<html>
 2<body>
 3<form runat="server">
 4<asp:DataGrid id="DataGrid1" runat="server" 
 5GridLines="Both" AutoGenerateColumns="false"
 6OnItemCommand="DataGrid1_ItemCommand">
 7 <Columns>
 8 <asp:ButtonColumn HeaderText="Static Button" Text="Click Me" 
 9 CommandName="Static"/>
10 <asp:TemplateColumn HeaderText="Data">
11  <ItemTemplate><%#Container.DataItem%></ItemTemplate>
12 </asp:TemplateColumn>
13 </Columns>
14</asp:DataGrid>
15<asp:Button id="btnAddAColumn" runat="server" Text="Add a column" OnClick="AddButtonColumn"/>
16<asp:Button id="btnRefresh" runat="server" Text="Refresh" />
17</form>
18</body>
19</html>
20<script language="C#" runat="server">
21void BindGrid()
22{
23 DataGrid1.DataSource = new string[] {"a","b","c"};
24 DataGrid1.DataBind();
25}

26
27void Page_Load(object sender, EventArgs e)
28{
29  if (!IsPostBack)
30  {
31 BindGrid();
32  }

33}

34
35void DataGrid1_ItemCommand(Object sender, DataGridCommandEventArgs e)
36{
37 Response.Write("ItemCommand is called<BR>");
38 LinkButton btn = e.CommandSource as LinkButton;
39 if (btn != null)
40  Response.Write(String.Format("{0} is clicked on row {1}", btn.CommandName, e.Item.ItemIndex));
41         
42}

43
44//lifted from the original post
45public void CreateGridColumn(DataGrid OperationDataGrid)
46{
47   ButtonColumn NewButCol = new ButtonColumn() ;
48   NewButCol.Text = "编辑" ;
49   NewButCol.HeaderText = "操作" ;
50   NewButCol.CommandName = "Edit" ;
51   NewButCol.ButtonType = ButtonColumnType.LinkButton;
52   NewButCol.Visible = true ;
53   OperationDataGrid.Columns.Add(NewButCol) ;
54   //OperationDataGrid.Columns.AddAt(1,NewButCol) ;
55}

56
57bool ButtonAdded
58{
59 get 
60  object o = ViewState["ButtonAdded"]; 
61  if (o == null
62   return false
63  else return (bool)o;
64     }

65 set { ViewState["ButtonAdded"= value;}
66}

67
68void AddButtonColumn(object sender, EventArgs e)
69{
70 CreateGridColumn(DataGrid1);
71 ButtonAdded = true;
72 BindGrid();
73 btnAddAColumn.Visible = false;
74}

75
76protected override void LoadViewState(object savedState)
77{
78 base.LoadViewState(savedState);
79 
80//在这里重新添加,假如已经添加的话
81 if (ButtonAdded)
82 CreateGridColumn(DataGrid1); 
83}

84
</script>
85