在用户控件中创建一个子类化的GridView

4

我正在尝试对位于UserControl中的GridView进行子类化。我希望能够在另一个页面上处理由此引起的事件。

基本上,我的代码如下所示:

我的UserControl包含一个GridView:

<%@ Control Language="C#" AutoEventWireup="false" CodeBehind="StdList.ascx.cs" Inherits="UCS_Web.uP.UserControls.StdList" %>
<div>
<asp:Panel ID="Panel1" runat="server">

<asp:GridView ID="_gridView" runat="server" PageSize="6" 
        GridLines="None" AutoGenerateColumns="False" 
        OnRowCommand="_gridView_RowCommand" AutoGenerateEditButton="false" 
        OnDataBound="_gridView_DataBound" OnPreRender="_gridView_PreRender">

        <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
        <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" HorizontalAlign="Left" CssClass="gridViewHdr" />
        <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" />

    </asp:GridView>
</asp:Panel>

使用 UserControl 的页面会像这样:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="BypassReasonsPage.aspx.cs" Inherits="UCS_Web.uP.Tools.BypassReasonsPage" %>

<%@ Register Src="~/uP/UserControls/StdList.ascx" TagName="List" TagPrefix="uc" %>

<body>
<form id="form1" runat="server">
    <div>
        <uc:List ID="uc_list" runat="server" />
    </div>
</form>

这是代码后端:

uc_list.GridView.DataSource = this.TCW.Copy.bypassReasons;
uc_list.GridView.DataBind();

为了让这个页面正常工作,我包含了一个文件来设置哪些列是数据绑定的等等。
public class BypassReasonsByToolTable : UCS_Web.uP.UserControls.StdList.ICustomTable
{      
  public DataControlField[] Columns
  {
     get
     {
         BoundField col1 = new BoundField();
         col1.DataField = "Code";
         col1.HeaderText = "Code";
         col1.SortExpression = "Code";
         col1.ItemStyle.Width = new Unit(50, UnitType.Percentage);

         BoundField col2 = new BoundField();
         col2.DataField = "Text";
         col2.HeaderText = "Text";
         col2.SortExpression = "Text";
         col2.ItemStyle.Width = new Unit(50, UnitType.Percentage);

         TemplateField editReason = new TemplateField();
         editReason.ItemTemplate = new addTemplate();

         return new DataControlField[] { col1, col2, editReason };
     }
  }

我希望能够将OnRowCommand、OnRowDelete和其他所有事件处理程序存储在一个单独的文件中,而不是在UserControl的CodeBehind中。 有什么办法可以实现这一点吗?

我尝试将它们作为虚拟类,并在使用它们的页面上重写它们,但这并没有起作用。还有其他方法可以实现这一点吗?

编辑:UserControl CodeBehind

namespace UCS_Web.uP.UserControls
{
   public partial class StdList : UserControl
   {
      private ICustomTable m_custom = null;

protected void _gridView_DataBound(object sender, EventArgs e)
  {
      if (_gridView.Rows.Count > 0)
      {
          for (int i = _gridView.Rows.Count + 1; i <= _gridView.PageSize - 1; i++)
          {
              GridViewRow row = new GridViewRow(
                      0,
                      0,
                      DataControlRowType.DataRow,
                  //(i % 2 > 0) ? datacontrolrowstate.normal : datacontrolrowstate.alternate);
                      DataControlRowState.Alternate);

              foreach (DataControlField field in _gridView.Columns)
              {
                  TableCell cell = new TableCell();
                  cell.Text = "&nbsp;";
                  row.Cells.Add(cell);
              }
        //row.Attributes.Add("OnClick", "javascript:alert();");
              row.BackColor = System.Drawing.ColorTranslator.FromHtml("#ffffff");
              _gridView.Controls[0].Controls.AddAt(i, row);
          }
      }

  }

protected void _gridView_RowCommand(object sender, GridViewCommandEventArgs e)
  {

      if (e.CommandName == "Delete")
      {
          //DO MY DELETE STUFF FOR THIS SPECIFIC PAGE
      }
  }
}

编辑:我在.cs文件中添加了新的重写函数(尝试了很多变化,但这是当前的版本)

namespace UCS_Web.uP.UserControls
{
public class MyStdList : StdList
{
    protected override void _gridView_RowCommand(object sender, GridViewCommandEventArgs e){
        Response.Redirect("HERPA DERP!");
    }
}

}


请检查 http://www.codeproject.com/Articles/19345/Event-handling-in-a-Gridview-User-Control,以了解GridView用户控件中的事件处理。 - kbvishnu
1个回答

5

您的用户控件是partial class,对吗?

请看C#中的partial关键字:

可以将类、结构、接口或方法的定义拆分成两个或多个源文件。每个源文件都包含类型或方法定义的一部分,在应用程序编译时将所有部分组合在一起。

可能会看起来像这样:

// MyOtherFile.cs:

namespace MyWebSite.UserControls
{
    public partial class MyUserControl : System.Web.UI.UserControl
    {
        protected override void OnInit(System.EventArgs e)
        {
            base.OnInit(e);

            _gridView.OnRowCommand += _gridBiew_RowCommand;
            _gridView.OnDataBound += _gridView_DataBound;
        }

        // events here...
    }
}

为了在子类中重写你的方法,基类 StdList 需要有 virtual 方法和/或属性。
参见 C# 的 virtual 关键字:

使用 virtual 关键字来修改方法、属性、索引器或事件声明,并允许其在派生类中被重写。例如,任何继承它的类都可以重写此方法:

  namespace UCS_Web.uP.UserControls
  {
      public partial class StdList : UserControl
      {
          private ICustomTable m_custom = null;

      }

      protected virtual void _gridView_DataBound(object sender, EventArgs e)
      {
          if (_gridView.Rows.Count > 0)
          {
              for (int i = _gridView.Rows.Count + 1; i <= _gridView.PageSize - 1; i++)
              {
                  GridViewRow row = new GridViewRow(
                          0,
                          0,
                          DataControlRowType.DataRow,
                      //(i % 2 > 0) ? datacontrolrowstate.normal : datacontrolrowstate.alternate);
                          DataControlRowState.Alternate);

                  foreach (DataControlField field in _gridView.Columns)
                  {
                      TableCell cell = new TableCell();
                      cell.Text = "&nbsp;";
                      row.Cells.Add(cell);
                  }
            //row.Attributes.Add("OnClick", "javascript:alert();");
                  row.BackColor = System.Drawing.ColorTranslator.FromHtml("#ffffff");
                  _gridView.Controls[0].Controls.AddAt(i, row);
              }
          }
      }

      protected virtual void _gridView_RowCommand(object sender, GridViewCommandEventArgs e)
      {
              // I do nothing for now... A subclass could override me and do very nice stuff
      } 
  }

并且...

  namespace UCS_Web.uP.UserControls
  {
      public partial class SpecialStdList : StdList { }

      protected override void _gridView_RowCommand(object sender, GridViewCommandEventArgs e)
      {
          // I do very nice stuff
      } 
  }

所以我已经将这个部分类添加到驱动我的.aspx页面的.cs文件中。这段代码不能直接工作,但是我尝试了类似于_gridView.RowCommand += _gridView_RowCommand的东西,它说这是不明确的,但是如果我使用一个唯一的名称,它永远都不会运行。你能否给出一个类似上述事件工作的示例呢? - ImGreg
是的,我猜我误解了你的问题 :p.. 我更新了我的答案! - maxbeaudoin
我从来不太擅长表达问题,但这看起来很棒!正是我想要的工作方式。虽然它还没有开始运行,但我会花一些时间来尝试并希望成功。感谢您的帮助! - ImGreg
还有些问题没有解决。我已经设置了我的覆盖函数和将用于覆盖的部分类,但它们仍然从未运行!无论如何,旧的虚拟函数都会运行,我似乎无法让它工作:( 有什么想法吗? - ImGreg
你好像只是创建了一个子类,但没有将其用作用户控件的代码后台,对吗? - maxbeaudoin
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接