none
Gridview 擴展一問(更新了問題)? RRS feed

  • 問題

  • 我想問各位前輩一些有關Gridview 擴展的問題

    我想在Gridview加一個功能可以產生自訂的欄位,以下是我的Code

        public class NewGridView : GridView
        {
           bool _SelectFunction = false;
    
            public bool SelectFunction
            {
                get
                {
                    if (this.ViewState["_SelectFunction"] == null)
                    {
                        return _SelectFunction;
                    }
                    else
                    {
                        return (bool)this.ViewState["_SelectFunction"];
                    }
                }
                set
                {
                    _SelectFunction = value;
                    this.ViewState["_SelectFunction"] = _SelectFunction;
                }
             }
    
           string _SelectImagepath = "~/Img/btn_Select.gif";
            public string SelectImagepath
            {
                get
                {
                    if (this.ViewState["_SelectImagepath"] == null)
                    {
                        return _SelectImagepath;
                    }
                    else
                    {
                        return (string)this.ViewState["_SelectImagepath"];
                    }
                }
                set
                {
                    _SelectImagepath = value;
                    this.ViewState["_SelectImagepath"] = _SelectImagepath;
                }
            }
    
            public void GeneDefaultCol()
            {
                GeneColum();
            }
    
            private void GeneColum()
            {
                if (this.SelectFunction == true)
                {
                    ImageButton btnSelect = new ImageButton();
                    btnSelect.CausesValidation = false;
                    btnSelect.CommandName = "Select";
                    btnSelect.ImageUrl = this.SelectImagepath;
    
                    TemplateField tf = new TemplateField();
                    tf.ShowHeader = true;
                    tf.HeaderTemplate = new btn_ITemplate("Select",DataControlRowType.Header);                tf.AlternatingItemTemplate = new btn_ITemplate(btnSelect, DataControlRowType.DataRow);
                    tf.ItemTemplate = new btn_ITemplate(btnSelect, DataControlRowType.DataRow);
                    tf.ItemStyle.HorizontalAlign = System.Web.UI.WebControls.HorizontalAlign.Center;
                    tf.ItemStyle.VerticalAlign = System.Web.UI.WebControls.VerticalAlign.Middle;
                    this.Columns.Insert(0, tf);
                }
            }
       }
    
        public class btn_ITemplate : ITemplate
        {
            string ItemHeadText;
            ImageButton Itembtn;
            DataControlRowType ItemRowType;
    
            public btn_ITemplate(ImageButton btn, DataControlRowType rowType)
            {
                Itembtn = new ImageButton();
                Itembtn = btn;
                ItemRowType = rowType;
            }
    
    
            public btn_ITemplate(string colHeadText, DataControlRowType rowType)
            {
                ItemHeadText = colHeadText;
                ItemRowType = rowType;
            }
    
            public void InstantiateIn(System.Web.UI.Control container)
            {
                switch (ItemRowType)
                {
                    case DataControlRowType.Header:
                        Literal Headtext = new Literal();
                        Headtext.Text = ItemHeadText;
                        container.Controls.Add(Headtext);
                        break;
    
                    case DataControlRowType.DataRow:
                        container.Controls.Add(Itembtn);
                        break;
                        
                    default:
                        break;
                }
            }
        }
    
    
    

       但是當我使用以上功能時,卻只有最後一行時才會出現自訂的欄位,我想問要如何解決這個問題?

       另外當我加上一個ItemTemplate,再進行Postback時,ItemTemplate內的控制項會消失,這個問題是由什麼原因引起和如何解決?

            <cc1:NewGridView ID="GridView1" runat="server" AllowPaging="True" AllowSorting="True"   AutoGenerateColumns="False" 
                DataSourceID="SqlDataSource1" EmptyDataText="Nill">
                <Columns>                                                
                     <ItemTemplate>
                        <asp:TextBox ID="txtText" runat="server" Text="0"></asp:TextBox></ItemTemplate>
                </Columns>
            </cc1:NewGridView> 
    <pre lang="x-aspx.cs">    protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                  GridView1.GeneDefaultCol();
             }
        }
    

           最後我想問一下base class(如:tableheadercell) 要如何把他序列化(Serializable)

          謝謝thx


    • 已編輯 OohenryoO 2011年12月6日 下午 02:08
    2011年11月26日 下午 05:23

解答

  • 稍微玩了一下您的程式碼

    建議伺服器控制項專案的NewGridView.cs改成這樣

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Web.UI.WebControls;
    using System.Web.UI;
    
    namespace KingControls
    {
        public class NewGridView : GridView
        {
             
            string _SelectImagepath = "http://l.yimg.com/f/i/tw/hp/mh/09purple.gif";
    
            
            public  NewGridView()//建構子
            {
    
                TemplateField tf = new TemplateField();
                tf.ShowHeader = true;
                tf.HeaderTemplate = new btn_ITemplate("Select", DataControlRowType.Header);
    
    
    
                ImageButton btnSelect = new ImageButton();
                btnSelect.CausesValidation = false;
                btnSelect.CommandName = "Select";
                btnSelect.ImageUrl = this._SelectImagepath;
                btnSelect.Width = 50;
                btnSelect.Height = 50;
                tf.ItemTemplate = new btn_ITemplate(btnSelect, DataControlRowType.DataRow);
               
    
                tf.ItemStyle.HorizontalAlign = System.Web.UI.WebControls.HorizontalAlign.Center;
                tf.ItemStyle.VerticalAlign = System.Web.UI.WebControls.VerticalAlign.Middle;
    
    
               
                this.Columns.Insert(0, tf);
            }
    
        
    
            
        }
    
        
    
        public class btn_ITemplate : ITemplate
        {
            string ItemHeadText;
            ImageButton Itembtn;
            DataControlRowType ItemRowType;
    
            public btn_ITemplate(string colHeadText, DataControlRowType rowType)
            {
                this.ItemHeadText = colHeadText;
                this.ItemRowType = rowType;
            }
    
            public btn_ITemplate(ImageButton btn, DataControlRowType rowType)
            {
                
                this.Itembtn = btn;
                this.ItemRowType = rowType;
            }
    
    
            
    
            public void InstantiateIn(System.Web.UI.Control container)
            {
                switch (this.ItemRowType)
                {
                    case DataControlRowType.Header:
                        Literal Headtext = new Literal();
                        Headtext.Text = ItemHeadText;
                        container.Controls.Add(Headtext);
                        break;
    
                    case DataControlRowType.DataRow:
                               ImageButton img_btn = new ImageButton();
                               img_btn.CausesValidation = Itembtn.CausesValidation;
                               img_btn.CommandName = Itembtn.CommandName;
                               img_btn.ImageUrl = Itembtn.ImageUrl;
                               img_btn.Width = Itembtn.Width;
                               img_btn.Height = Itembtn.Height;
                               container.Controls.Add(img_btn);
                        break;
    
                    
                }
            }
        }
    
    
    
    
    
    }
    
    
      編譯成ddl檔後,網站工具箱加入此dll檔

     <asp:SqlDataSource runat="server" ID="sds_test" ConnectionString="<%$ ConnectionStrings:ConnectionString %>"
            SelectCommand="SELECT [CategoryID], [CategoryName], [Description] FROM [Categories]" />
        <cc1:NewGridView ID="GridView1" runat="server" DataSourceID="sds_test" OnRowCommand="GridView1_RowCommand">
            <Columns>
                <asp:TemplateField>
                    <ItemTemplate>
                        <asp:TextBox ID="txtText" runat="server" Text="0"></asp:TextBox>
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
        </cc1:NewGridView>
    

    protected void Page_Load(object sender, EventArgs e)
        {
    
        }
    
    
    
    
    
        protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
        {
            if (e.CommandName=="Select")
            {
                Response.Write("Hello World!!");
            }
        }
    

    這樣就不會有你說的問題了

     


    Shadowと愉快なコード達
    • 已標示為解答 OohenryoO 2011年11月28日 下午 04:03
    • 已取消標示為解答 OohenryoO 2011年12月1日 下午 01:02
    • 已提議為解答 MIS2000 Lab. _ 2011年12月5日 上午 08:27
    • 已標示為解答 ChenBruceModerator 2011年12月6日 上午 03:43
    • 已取消標示為解答 ChenBruceModerator 2011年12月6日 上午 03:43
    • 已標示為解答 OohenryoO 2011年12月6日 上午 09:17
    2011年11月26日 下午 08:19
  • 你是怎麼加入編輯資料行的呢??

    我依照Shadow And Happy Code的做法做了一次,

    然後如果是利用設計模式->編輯資料行->新增CommandField的"編輯更新取消"時,他是會現兩欄的select,但觀察aspx.cs

    他除了多了一條<asp:CommandField ShowEditButton="True" />以外,

    還會自己產生一個select 的TemplateField,但是因為select的TemplateField其實已經在建構的時候插入在第一欄,

    所以這個自動產生的TemplateField直接拿掉就好,

    但如果要根治的話,應該還是要從伺服器控制項那邊下手了,

     

    至於把select加到最後一欄,可能要再看有沒有其他大大有辦法了@@

     





    2011年12月5日 上午 03:38

所有回覆

  • 稍微玩了一下您的程式碼

    建議伺服器控制項專案的NewGridView.cs改成這樣

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Web.UI.WebControls;
    using System.Web.UI;
    
    namespace KingControls
    {
        public class NewGridView : GridView
        {
             
            string _SelectImagepath = "http://l.yimg.com/f/i/tw/hp/mh/09purple.gif";
    
            
            public  NewGridView()//建構子
            {
    
                TemplateField tf = new TemplateField();
                tf.ShowHeader = true;
                tf.HeaderTemplate = new btn_ITemplate("Select", DataControlRowType.Header);
    
    
    
                ImageButton btnSelect = new ImageButton();
                btnSelect.CausesValidation = false;
                btnSelect.CommandName = "Select";
                btnSelect.ImageUrl = this._SelectImagepath;
                btnSelect.Width = 50;
                btnSelect.Height = 50;
                tf.ItemTemplate = new btn_ITemplate(btnSelect, DataControlRowType.DataRow);
               
    
                tf.ItemStyle.HorizontalAlign = System.Web.UI.WebControls.HorizontalAlign.Center;
                tf.ItemStyle.VerticalAlign = System.Web.UI.WebControls.VerticalAlign.Middle;
    
    
               
                this.Columns.Insert(0, tf);
            }
    
        
    
            
        }
    
        
    
        public class btn_ITemplate : ITemplate
        {
            string ItemHeadText;
            ImageButton Itembtn;
            DataControlRowType ItemRowType;
    
            public btn_ITemplate(string colHeadText, DataControlRowType rowType)
            {
                this.ItemHeadText = colHeadText;
                this.ItemRowType = rowType;
            }
    
            public btn_ITemplate(ImageButton btn, DataControlRowType rowType)
            {
                
                this.Itembtn = btn;
                this.ItemRowType = rowType;
            }
    
    
            
    
            public void InstantiateIn(System.Web.UI.Control container)
            {
                switch (this.ItemRowType)
                {
                    case DataControlRowType.Header:
                        Literal Headtext = new Literal();
                        Headtext.Text = ItemHeadText;
                        container.Controls.Add(Headtext);
                        break;
    
                    case DataControlRowType.DataRow:
                               ImageButton img_btn = new ImageButton();
                               img_btn.CausesValidation = Itembtn.CausesValidation;
                               img_btn.CommandName = Itembtn.CommandName;
                               img_btn.ImageUrl = Itembtn.ImageUrl;
                               img_btn.Width = Itembtn.Width;
                               img_btn.Height = Itembtn.Height;
                               container.Controls.Add(img_btn);
                        break;
    
                    
                }
            }
        }
    
    
    
    
    
    }
    
    
      編譯成ddl檔後,網站工具箱加入此dll檔

     <asp:SqlDataSource runat="server" ID="sds_test" ConnectionString="<%$ ConnectionStrings:ConnectionString %>"
            SelectCommand="SELECT [CategoryID], [CategoryName], [Description] FROM [Categories]" />
        <cc1:NewGridView ID="GridView1" runat="server" DataSourceID="sds_test" OnRowCommand="GridView1_RowCommand">
            <Columns>
                <asp:TemplateField>
                    <ItemTemplate>
                        <asp:TextBox ID="txtText" runat="server" Text="0"></asp:TextBox>
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
        </cc1:NewGridView>
    

    protected void Page_Load(object sender, EventArgs e)
        {
    
        }
    
    
    
    
    
        protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
        {
            if (e.CommandName=="Select")
            {
                Response.Write("Hello World!!");
            }
        }
    

    這樣就不會有你說的問題了

     


    Shadowと愉快なコード達
    • 已標示為解答 OohenryoO 2011年11月28日 下午 04:03
    • 已取消標示為解答 OohenryoO 2011年12月1日 下午 01:02
    • 已提議為解答 MIS2000 Lab. _ 2011年12月5日 上午 08:27
    • 已標示為解答 ChenBruceModerator 2011年12月6日 上午 03:43
    • 已取消標示為解答 ChenBruceModerator 2011年12月6日 上午 03:43
    • 已標示為解答 OohenryoO 2011年12月6日 上午 09:17
    2011年11月26日 下午 08:19
  • 謝謝你的回答

    我根據你的回答修改了我的程式,這個問題已經解決了,但是卻產生了另一個問題

    當我按下NewGridView的"編輯資料行"修改資料行時,卻會自行產生另一欄"select"(即變成二欄"select"),請問這個問題有沒有方法解決?

    另外我想把"select"的位置改為最後的一欄,應該要如何才能做到?

    THX 



    補充一下

    我嘗試了用以下的方法來更改"select"的位置,但是在POSTBACK後TemplateField的內容便會消失.......

            protected override void OnPreRender(EventArgs e)
            {
                int PoSelect = this.GetHeaderTextColumnIndex("Select ");

                if (PoSelect > -1)
                {
                    DataControlField dc = this.Columns[PoSelect ];
                    this.Columns.RemoveAt(PoSelect );
                    this.Columns.Insert(this.Columns.Count, dc);
                }
                base.OnPreRender(e);
            }

            public int GetHeaderTextColumnIndex(string columnHeaderText)
            {
                foreach (DataControlField column in this.Columns)
                {
                    if (column.HeaderText == columnHeaderText)
                    {
                        int columID = this.Columns.IndexOf(column);

                        return columID;
                    }
                }
                return -1;
            }


    • 已編輯 OohenryoO 2011年12月6日 下午 02:05
    2011年11月28日 下午 04:03
  • 你是怎麼加入編輯資料行的呢??

    我依照Shadow And Happy Code的做法做了一次,

    然後如果是利用設計模式->編輯資料行->新增CommandField的"編輯更新取消"時,他是會現兩欄的select,但觀察aspx.cs

    他除了多了一條<asp:CommandField ShowEditButton="True" />以外,

    還會自己產生一個select 的TemplateField,但是因為select的TemplateField其實已經在建構的時候插入在第一欄,

    所以這個自動產生的TemplateField直接拿掉就好,

    但如果要根治的話,應該還是要從伺服器控制項那邊下手了,

     

    至於把select加到最後一欄,可能要再看有沒有其他大大有辦法了@@

     





    2011年12月5日 上午 03:38