【问题标题】:Sorting a list with asp.net usercontrols by property value按属性值对带有 asp.net 用户控件的列表进行排序
【发布时间】:2014-04-07 18:57:56
【问题描述】:

我正在用许多用户控件填充一个 div,现在它们是按照从数据库中读取它们的顺序添加的。 UserControls 标记如下所示:

<div class="Content_Thumb">

    <div class="Video_pic">
        <a href="tutorialname.aspx">
        <asp:Label ID="TutInfo" CssClass="CoverLbl_top" runat="server" Text="Label"></asp:Label>
        <asp:Label ID="TutInfo2" CssClass="CoverLbl_bottom" runat="server" Text="Description..."></asp:Label>
        <asp:Image ID="ThumbPic" CssClass="Thumb_Pic" runat="server" ImageUrl="/Images/Video_Thumb.png" />
        </a>
    </div>

    <div class="Thumb_Info">
        <asp:Label ID="Views" CssClass="ViewsLbl" runat="server" Text="680"></asp:Label>
        <asp:Label ID="Comments" CssClass="CommentsLbl" runat="server" Text="11"></asp:Label>
        <asp:Label ID="Likes" CssClass="LikesLbl" Style="TEXT-ALIGN: right" runat="server" Text="133"></asp:Label>
    </div>

    <div class="Thumb_Border">
            <asp:Image ID="UserPic" CssClass="Thumb_UploaderPic" runat="server" ImageUrl="/Images/Profile_Placeholder.png" />
            <a href="google.com">
                <asp:Label ID="UserLbl" CssClass="Thumb_UploaderInfo" runat="server" Text="Label"></asp:Label>
            </a>
    </div>

然后我得到了绑定到标签的这些属性(有些被删除,因为我不想弄乱帖子)。

        public string TutorialInfo 
    { 
        get; 
        set; 
    }

    public int TutorialViews
    {
        get;
        set;  
    }

    public override void DataBind()
    {
        TutInfo.Text = TutorialInfo;
        Views.Text = TutorialViews.ToString();
        Comments.Text = TutorialComments.ToString();
        Likes.Text = TutorialLikes.ToString();
        UserLbl.Text = TutorialUploader;
        base.DataBind();
    }

现在,我想要对这些控件执行的操作是按属性值对它们进行排序。 (最高数量的视图首先加载等)。我目前正处于将它们添加到列表中的阶段,现在我正在尝试使用 LINQ 的 OrderBy 对该列表进行排序,就像我在此处的帖子中看到的那样。

List<UserControl> controls = new List<UserControl>();

        foreach (var Tutorial in dataconnection.Tutorial)
        {
            var control = LoadControl("~/WebUserControl1.ascx") as WebUserControl1;

            control.TutorialInfo = Tutorial.Title;
            control.TutorialComments = (int)Tutorial.Comments;
            control.TutorialViews = (int)Tutorial.Views;
            control.TutorialLikes = (int)Tutorial.Likes;
            control.TutorialUploader = Tutorial.Uploader;
            control.DataBind();
            //base.OnPreRender(e);
            ThumbTest.Controls.Add(control);
            controls.Add(control);
            var testcount = controls.Count();
            control.Visible = false;

        }

        var SortedList = controls.OrderBy(o => o.TutorialViews).ToList();

但是,即使它们是公开的,我也无法访问这些属性? “o.TutorialViews”正在引发错误。那么如何对这些控件进行排序呢?

总的来说,我对编程还很陌生,所以如果这是一个愚蠢的错误,我深表歉意。

TLDR:如何按属性值对用户控件进行排序。

【问题讨论】:

    标签: c# asp.net linq user-controls sql-order-by


    【解决方案1】:

    您的列表是UserControl 对象的列表,这是 ASP.NET 提供的通用用户控件:

    List<UserControl> controls = new List<UserControl>();
    

    UserControl 对象没有名为TutorialViews 的属性,因此您无法访问该类型的该属性。但是,您正在向列表中添加自定义用户控件:

    var control = LoadControl("~/WebUserControl1.ascx") as WebUserControl1;
    

    如果列表中的每个项目都是WebUserControl1 类型,那么您可以使用该类型声明列表本身:

    List<WebUserControl1> controls = new List<WebUserControl1>();
    

    由于WebUserControl1确实定义了该属性,因此您将能够访问它。

    另一种方法可能是在您访问它时强制转换它,如下所示:

    controls.OrderBy(o => ((WebUserControl1)o).TutorialViews)
    

    但这有点乱,不应该是必要的。最好一开始就使用正确的类型。

    本质上,这是 C#(和许多其他语言)的静态类型性质的症状。 B 类继承自 A 类,因此 B 的每个实例都是 A 的实例。但并非 A 的每个实例都是 B 的实例,因此您不能在 A 的实例上调用 B 属性。

    想一个类比...您有一个Shape 对象列表,并用Circle 对象填充它。这行得通,因为Circles 是Shapes。但随后您尝试访问该列表中某个元素的Radius 属性,您会收到错误消息。这是因为它是Shapes 的列表,并不是每个形状都有Radius。您需要将其设为Circles 的列表,或者将该元素转换为Circle,以便编译器知道存在Radius

    有关该主题的更多进一步阅读,请查看PolymorphismLiskov Substitution Principle

    【讨论】:

    • 这很神奇!你确实是人中的神,大卫。 :) 非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-13
    • 1970-01-01
    相关资源
    最近更新 更多