绑定来自另一个类的转发器控件

时间:2013-12-23 21:23:53

标签: c# asp.net binding repeater

我正在开发一个使用数据库查询来使用转发器控件显示数据的应用程序。

我的转发器控件放在我的页面“show.aspx”上,我有另一个类,我有数据绑定方法。

那么从我的数据类中绑定转发器的最佳方法是什么?

另外,我为转发器做了一个扩展方法,称为BindTable(); 通过在“show.cs”类中调用此方法(我的意思是表单加载),我很容易绑定数据。此方法将sql查询作为参数,所有内容都通过扩展方法在后台完成。

rptDisplay.BindTable("select * from table");

但我正在寻找更好的方法。我无法从我的所有数据绑定方法所在的数据类中访问我的转发器吗?

2 个答案:

答案 0 :(得分:1)

根据您的评论,您的目标是将表单中的数据绑定代码分解出来,以保持表单代码的清洁。这很好,因为检索和绑定数据的代码可能是文件背后代码的重要组成部分 首先,我认为像你已经做的那样创建一个扩展方法是一种非常好 - 而且优雅 - 的方法。它适用于页面上的多个转发器和不同的SQL语句。那你怎么能进一步改善这个呢?
现在,您直接在后面的代码中向扩展方法提供SQL语句。这是有效的,但为了真正清晰地分离关注点,我不建议直接在UI代码中包含语句,因为它是使用SQL的数据访问的详细信息。如果您决定在稍后提供数据的时间段引入服务层,则必须对UI代码进行大量更改。您可以自行决定是否在您的环境中这是一个值得付出努力的现实场景 步骤如下:

  1. 创建包含与UI相关的数据的数据传输对象(DTO)。
  2. 创建不返回DataTables / Sets的数据访问类(也称为存储库类),但使用GetById,GetAll,GetByName等描述相关数据库查询的方法创建集合或单个DTO。 MicroORM(例如Dapper.NET)可以在数据库对象(DataTables,DataReaders)到DTO的(无聊)映射过程中为您提供支持。还包括更新数据库的方法。
  3. 在表单中,通过调用存储库来检索数据,并将转发器绑定到DTO集合。
  4. 在您介绍了这些更改之后,您会发现数据绑定代码不是使您的代码隐藏在文件后面,而是数据访问代码。将此代码移动到存储库后,数据绑定只是设置DataSource属性和对DataBind()的调用。因此,您的扩展方法将非常小,看起来类似于:

    public static void Bind<T>(this Repeater rpt, IEnumerable<T> data)
    {
        rpt.DataSource = data;
        rpt.DataBind();
    }
    

    这种方法需要一些努力,但提供了更好的关注点分离,因为UI独立数据访问逻辑位于一个单独的位置(也许您也可以与不同客户的其他项目共享数据访问代码,例如WPF或的WinForms)。此外,我确信您将能够识别许多其他位置(除了数据绑定),您还可以使用存储库而不是直接访问数据。这也将使您的代码更短。

答案 1 :(得分:0)

你可以在abc类中有一个函数,它接受一个转发器作为参数并将数据绑定到它。

编辑:您可能希望为不同的转发器切换数据源。在这种情况下,您可以向BindTable方法添加另一个参数,并在该方法内部检查参数以切换到正确的数据源。

编辑2: BindTable有两个参数,Repeater和枚举MyEnum

这是我将如何做到的。我有一个页面, Show.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Show.aspx.cs" Inherits="RepeaterTestOne.Show" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Repeater ID="rptDisplay" runat="server">
            <HeaderTemplate>
                <table>
            </HeaderTemplate>
            <ItemTemplate>
                <tr>
                    <td>
                        <asp:Label ID="lblID" runat="server" Text='<%#Eval("ID") %>'></asp:Label>
                    </td><td>
                        <asp:Label ID="lblName" runat="server" Text='<%#Eval("Name") %>'></asp:Label>
                    </td>
                </tr>
            </ItemTemplate>
            <FooterTemplate>
                </table>
            </FooterTemplate>
        </asp:Repeater>
        <asp:Button ID="Button1" runat="server" Text="First One" OnClick="Button1_Click" />
        <asp:Button ID="Button2" runat="server" Text="First Four" OnClick="Button2_Click" />
        <asp:Button ID="Button3" runat="server" Text="All" OnClick="Button3_Click" />
    </div>
    </form>
</body>
</html>

在代码中我调用我的数据类(MyDataClass)的BindTable()方法并传递转发器。我的 Show.aspx.cs 如下所示:

using System;

namespace RepeaterTestOne
{
    public partial class Show : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            MyDataClass.BindTable(rptDisplay, MyEnum.FirstOne);
        }

        protected void Button2_Click(object sender, EventArgs e)
        {
            MyDataClass.BindTable(rptDisplay,MyEnum.FirstFour);
        }

        protected void Button3_Click(object sender, EventArgs e)
        {
            MyDataClass.BindTable(rptDisplay, MyEnum.AllItems);
        }
    }
}

在我的MyDataClass中,我有代码(带有用于测试的虚拟代码),如下所示:

using System.Collections.Generic;
using System.Web.UI.WebControls;

namespace RepeaterTestOne
{
    public static class MyDataClass
    {
        public static void BindTable(Repeater rpt, MyEnum mySelection = MyEnum.AllItems)
        {

            //Replace this part with custom sql
            List<MyData> lst = new List<MyData>()
            {
                new MyData{ID=1, Name="Item 1"},
                new MyData{ID=2, Name="Item 2"},
                new MyData{ID=3, Name="Item 3"},
                new MyData{ID=4, Name="Item 4"},
                new MyData{ID=5, Name="Item 5"}
            };
            switch (mySelection)
            {
                case MyEnum.FirstOne:
                    lst = new List<MyData>(){new MyData{ID=1, Name="Item 1"}};
                    break;
                case MyEnum.FirstFour:
                    lst = new List<MyData>()
                    {
                        new MyData{ID=1, Name="Item 1"},
                        new MyData{ID=2, Name="Item 2"},
                        new MyData{ID=3, Name="Item 3"},
                        new MyData{ID=4, Name="Item 4"}
                    };
                    break;
                default:
                    lst = new List<MyData>()
                    {
                        new MyData{ID=1, Name="Item 1"},
                        new MyData{ID=2, Name="Item 2"},
                        new MyData{ID=3, Name="Item 3"},
                        new MyData{ID=4, Name="Item 4"},
                        new MyData{ID=5, Name="Item 5"}
                    };
                    break;
            }
            //Replace this part with custom sql

            rpt.DataSource = lst;
            rpt.DataBind();
        }

    }
    public class MyData
    {
        public int ID { get; set; }
        public string Name { get; set; }
    }
}

这是我的枚举MyEnum

namespace RepeaterTestOne
{
    public enum MyEnum
    {
        AllItems = 1,
        FirstOne = 2,
        FirstFour = 3
    }
}