12

I am using Telerik Gridview for displaying list of records and i have more than 10 pages on which i am using this gridview with this following common events code copy pasted(with some minor changes) on all this pages:

protected void Page_Load(object sender, EventArgs e)
{
    DisplayRecords()
}

public void DisplayRecords()
{
    //Grid view names are different on different pages.
    GridView1.DataSource=Fetching records from database.
    GridView1.DataBind();
}

protected void GridView1_SortCommand(object sender, GridSortCommandEventArgs e)
{
    DisplayRecords()
}

protected void GridView1_PageIndexChanged(object sender, GridPageChangedEventArgs e)
{
    var index = e.NewPageIndex;
    DisplayRecords()
}

protected void GridView1_PageSizeChanged(object sender, GridPageSizeChangedEventArgs e)
{
    var size = e.NewPageSize;
    DisplayRecords()
}

This is my one page which inherits from following page:

public partial class LoadSettings : ParentPage
{
    //Load events and other events
}

[Serializable]
public class ParentPage: RadAjaxPage
{

}

Page 1:**ttt.aspx**
public void DisplayRecords()
    {
        //Grid view names are different on different pages.
        GridView1.DataSource=this.GetAlltttData()
        GridView1.DataBind();
    }

    public DataTable GetAlltttData()
            {
                using (var context = new MyDataContext())
                {
                    var data = from c in context.ttt select c;
                    return MyDataContext.LINQToDataTable(data);
                }
            }


Page 2:**bbb.aspx**
public void DisplayRecords()
    {
        //Grid view names are different on different pages.
        GridView1.DataSource=this.GetAllbbbData()
        GridView1.DataBind();
    }

    public DataTable GetAllbbbData()
            {
                using (var context = new MyDataContext())
                {
                    var data = from c in context.bbb select c;
                    return MyDataContext.LINQToDataTable(data);
                }
            }

protected void rgbbb_SortCommand(object sender, GridSortCommandEventArgs e)
        {
           DisplayRecords()
        }
protected void rgbbb_PageIndexChanged(object sender, GridPageChangedEventArgs e)
        {
            var index = e.NewPageIndex;
            DisplayRecords()
        }

 protected void rgbbb_PageSizeChanged(object sender, GridPageSizeChangedEventArgs e)
        {
           var size = e.NewPageSize;
           DisplayRecords()
        }

So is this possible that i can place all this events in this ParentPage page and just call from every child page instead of polluting my every page with this events??

Note:In some of my pages this DisplayRecords methods can contains some parameters but rest all events are just common.

I Love Stackoverflow
  • 6,738
  • 20
  • 97
  • 216
  • 1
    can't you create a masterpage which alreay contains this control? you can also do it using a parent Page class but you would need to add the control dynamically to its parent control on `Init` event so its lifecycle would still works – Luizgrs Dec 21 '15 at 10:53
  • @Luizgrs:I cant keep it on my master page as because grid definitions differs on every page so how i will maintain that so i dont think master page solution is good. – I Love Stackoverflow Dec 21 '15 at 11:00
  • 1
    Masterpages can be "chained", I mean you can have anoter masterpage which uses the main one, and only these 10 pages would use this second master page – Luizgrs Dec 21 '15 at 11:31
  • @Luizgrs:can you please post any solution which describe this.please so this can help me and others too – I Love Stackoverflow Dec 21 '15 at 11:41
  • @Luizgrs:Can you check out the asnwer posted on this question – I Love Stackoverflow Dec 28 '15 at 04:23

2 Answers2

4

May be you can put you common logic inside abstract class with method (or property) that returns reference on concrete GridView and inherit from this class. Then on each page your just have to implement that method.

Something like this:

public abstract class ParentPage
{
    public virtual void DisplayRecords()
    {
        var gridView = this.GetGridView();
        gridView.DataSource = this.GetAllData();
        gridView.DataBind();
    }

    protected abstract  DataTable GetAllData();

    protected string GetSortOrder()
    {
        if (this.sortOrder != GridSortOrder.Assending)
            return string.Format("{0} DESC", this.sortExpression)
        return this.sortExpression;
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        DisplayRecords();
    }

    protected void GridView1_SortCommand(object sender, GridSortCommandEventArgs e)
    {
        if (!e.Item.OwnerTableView.SortExpressions.ContainsExpression(e.SortExpression))
        {
            GridSortExpression sortExpr = new GridSortExpression();
            sortExpr.FieldName = e.SortExpression;
            sortExpr.SortOrder = GridSortOrder.Ascending;
            e.Item.OwnerTableView.SortExpressions.AddSortExpression(sortExpr);
        }
    }

    protected void GridView1_PageIndexChanged(object sender, GridPageChangedEventArgs e)
    {
        e.Item.OwnerTableView.PageIndex = e.NewPageIndex;
        DisplayRecords();
    }

    protected void GridView1_PageSizeChanged(object sender, GridPageSizeChangedEventArgs e)
    {
        e.Item.OwnerTableView.PageSize = e.NewPageSize;
        DisplayRecords();
    }
}

Page 1:**ttt.aspx**
public class **tttPage : BasePage 
{
    protected override GridView GetGridView()
    {
        //return GridView of this page 
        return GridView1;
    }

    protected override  DataTable GetAllData()
    {
        using (var context = new MyDataContext())
        {
            var data = c in context.ttt select c;
            return MyDataContext.LINQToDataTable(data);
        }
    }
}

Page 1:**bbb.aspx**
public class **bbbPage : BasePage
{
    protected override GridView GetGridView()
    {
        //return GridView of this page 
        return GridView1;
    }

    protected override  DataTable GetAllData()
    {
        using (var context = new MyDataContext())
        {
            var data = c in context.bbb select c;
            return MyDataContext.LINQToDataTable(data);
        }
    }
}

Or you can put you common logic inside base class with virtual methods where use event args for getting GridView like e.Item.OwnerTableView.

By making it virtual you will be able to override this logic in any page class

Something like this:

public abstract class ParentPage<TEntity>
{
    public virtual void DisplayRecords(GridView gridView)
    {
        gridView.DataSource = this.GetAllData();
        gridView.DataBind();
    }

    protected abstract  DataTable GetAllData();

    protected void Page_Load(object sender, EventArgs e)
    {
        DisplayRecords(e.Item.OwnerTableView);
    }

    protected void GridView_SortCommand(object sender, GridSortCommandEventArgs e)
    {
        DisplayRecords(e.Item.OwnerTableView);
    }

    protected void GridView_PageIndexChanged(object sender, GridPageChangedEventArgs e)
    {
        DisplayRecords(e.Item.OwnerTableView);
    }

    protected void GridView_PageSizeChanged(object sender, GridPageSizeChangedEventArgs e)
    {
        DisplayRecords(e.Item.OwnerTableView);
    }
}

public class **tttPage : ParentPage 
{
    protected override  DataTable GetAllData()
    {
        using (var context = new MyDataContext())
        {
            var data = c in context.ttt select c;
            return MyDataContext.LINQToDataTable(data);
        }
    }
}

public class **bbbPage : ParentPage 
{
    protected override  DataTable GetAllData()
    {
        using (var context = new MyDataContext())
        {
            var data = c in context.bbb select c;
            return MyDataContext.LINQToDataTable(data);
        }
    }
}

Also you can use generic parameter for getting values from db.

Andrey Tretyak
  • 3,043
  • 2
  • 20
  • 33
  • As i have multiple pages so displaying records on all this pages would have different tables to display records from so how i will handle that multiple tables in your DisplayRecords method? – I Love Stackoverflow Dec 28 '15 at 04:21
  • 1
    @Learning using method `GetGridView` that is override on every page you can always get table of current page and work with it. So you can put logic that general for every page in `DisplayRecords` method of abstract class and add custom logic using override version of 'DisplayRecords' in page class. May be you can provide code of couple your's 'DisplayRecords' methods and I'll try to show it on example? – Andrey Tretyak Dec 28 '15 at 07:10
  • See my updated question i have added some pages with codes – I Love Stackoverflow Dec 29 '15 at 04:19
  • 1
    @Learning I've updated my answer, now all logic connected with getting data in separate abstract method and you can implement it as you need on each page. – Andrey Tretyak Dec 29 '15 at 06:53
  • What about gridview other evenst like sort command,pageindex changez and page size change? – I Love Stackoverflow Dec 29 '15 at 09:14
  • @Learning could you please add in your example code that is problematic to move into `BasePage` class? and will try to suggest solution – Andrey Tretyak Dec 29 '15 at 10:22
  • Suppose i want to fire page size event or sort command event for ttt page then how i will use Base page Sort event to acheive such and consider my gridview name for page ttt as gridtt,bbb as gridbbb.In short different page would have grid with different name. – I Love Stackoverflow Dec 29 '15 at 10:48
  • 1
    @Learning I've added in the example variables where event could set required state (page size, index, sort expression), this variables should be used in `BaseClass` inside `DisplayRecords` method to create result items set. If you could add code how it's done for any of your page, I will show how to do it in general, or I can write my variant base on selection from db context if you don't have code. – Andrey Tretyak Dec 29 '15 at 11:38
  • Question updated and See i have written code for sortcommand,page size,page index change for page bbb.aspx.Same way this code will come for page ttt.aspx with gridview name rgttt – I Love Stackoverflow Dec 30 '15 at 04:37
  • @Learning If your page will be inherited from BasePage they all will have methods `GridView1_SortCommand`,`GridView1_PageIndexChanged`,... so you can use it on any page as event handlers. In your example I did not understand why do you need lines like this `var index = e.NewPageIndex;` and how do use those values. My previous question was about how do you apply sorting and paging to your query on stage of creating db request or you just set some properties for `GridView`? – Andrey Tretyak Dec 30 '15 at 07:02
  • actually i am new to telerik so you are asking about var index = e.NewPageIndex;size index variable is not used in paging of query bt still i dont know how this sorting pagesize change,pageindex change is working and working successfully.I am just fetching all records from my database and telerik is doing paging automatically but still i am not sre about this.i think if you have time then you can also give it a try and check that it is working or not – I Love Stackoverflow Dec 30 '15 at 08:42
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/99287/discussion-between-andrey-tretyak-and-learning). – Andrey Tretyak Dec 30 '15 at 09:02
2

There are many principles that you generally apply when trying to refactor code. Currently you are trying to refactor your code as to not violate the DRY principle (DRY = don't repeat yourself).
But, some other principals might come in to play that you might want to consider. The single responsibility principle would suggest that each method does only one unambiguous thing.

As per your scenario, You need to generate whole GridView dynamically or runtime with custom columns and custom GridView configuration logic which will be more expensive than writing those events in each page.

Also all events must be tied up to 'GridView' to trigger properly. You can not separate those events to other files otherwise events will not fire.

You have another option of using ASP.Net user controls but again you need to write logic to manipulate GridView custom columns and custom GridView configuration logic. So again making it more expensive. So I won't recommend to do so. It's better off as to keep methods individually for each page.

Rahul Nikate
  • 6,192
  • 5
  • 42
  • 54