【问题标题】:Displaying Html.ListBoxFor for association class with one additional property为具有一个附加属性的关联类显示 Html.ListBoxFor
【发布时间】:2014-09-07 00:14:14
【问题描述】:

编辑和部分回答:我不知道如何显示多列,但如果不是这样,您必须在 Call 类中覆盖 ToString。


我有一个班级Person(他们接电话):

 public class Person {
        public int Id { get; set; }

        [DisplayName("First Name")]
        public string FirstName { get; set; }

        [DisplayName("Last Name")]
        public string LastName { get; set; }

        public virtual ICollection<Call> ReceivedCalls { get; set; }
    }

一个班级ApplicationUser(他们打电话):

 public class ApplicationUser : IdentityUser {
        public virtual ICollection<Call> MadeCalls { get; set; }
 }

以及它们之间的关联类Call:

 public class Call {
        public int Id { get; set; }
        public virtual Person Callee { get; set; }
        public virtual ApplicationUser Caller { get; set; }
        public DateTime TimeStamp { get; set; } //Additional Attribute
    }

他们在数据库中合作得很好。但是我在使用@Html.ListBoxFor 方法来显示一个ListBox 时遇到了麻烦,其中的每一行都会显示谁来电以及何时调用:Caller.UserName | Call.TimeStamp 用于收到的每个电话(由人员)。

我想在 Razor View 中显示那些强类型化的信息:

@model WebApplication2.Models.Person

我试过这个:

@Html.ListBoxFor(m => m.ReceivedCalls, new MultiSelectList(Model.ReceivedCalls, "TimeStamp" ), new {Multiple = "multiple"})

它正在被翻译(输出 HTML)为:

<select Multiple="multiple" id="ReceivedCalls" multiple="multiple" name="ReceivedCalls"><option selected="selected">System.Data.Entity.DynamicProxies.Call_2FC3E1C25C19BA21E6B64CAB2894602434775435359AAB76E58C6F8411451A49</option>
<option selected="selected">System.Data.Entity.DynamicProxies.Call_2FC3E1C25C19BA21E6B64CAB2894602434775435359AAB76E58C6F8411451A49</option>
</select>

它看起来像:

问题:如何在每行显示谁来电以及何时调用的 ListBox:Caller.UserName | Call.TimeStamp 显示每个接听电话(按人)。


**编辑:**

有一些语法错误:

        // Create collection of anonymous objects (adjust format to suit your needs)
        var receivedCalls = person.ReceivedCalls.Select(c => new {
            ID = c.Id,
            DisplayName = string.Format("{0}: {1:D}", c.Caller.UserName, c.TimeStamp)
        });
        // Initialise view model
        PersonVM model = new PersonVM();
        // Map properties from person to model

        // Assign select list
        model.CallList = new MultiSelectList(receivedCalls, "ID", "DisplaName");

查看:

@Html.ListBoxFor(m => m.ReceivedCalls, new MultiSelectList(Model.ReceivedCalls))

如果我只是覆盖 Call 中的 ToString,结果完全一样:

   public override string ToString() {
            if (Caller != null)
                return Caller.UserName + " called at " + TimeStamp;
            return "called at " + TimeStamp;
        }

@Html.ListBoxFor(m => m.ReceivedCalls, new MultiSelectList(Model.ReceivedCalls, "TimeStamp"), new { Multiple = "multiple", style = "width: 100%;" })

所以我认为它仍然依赖于 ToString。

【问题讨论】:

    标签: c# asp.net-mvc linq entity-framework razor


    【解决方案1】:

    你应该创建一个视图模型来显示和绑定你的属性

    查看模型

    public class PersonVM
    {
      public int Id { get; set; }
      public string FirstName { get; set; }
      public string LastName { get; set; }
      public int[] ReceivedCalls { get; set; } // this will bind to the selected calls
      public MultiSelectList CallList { get; set; } // to display the calls   
    }
    

    控制器

    // Create collection of anonymous objects (adjust format to suit your needs)
    var receivedCalls = person.ReceivedCalls.Select(c => new 
    {
      ID = c.ID,
      DisplayName = string.Format("{0}: {1:D}", c.Callee.UserName, c.TimeStamp)
    }
    // Initialise view model
    PersonVM model = new PersonVM();
    // Map properties from person to model
    ...
    // Assign select list
    model.CallList  = new MultiSelectList(receivedCalls , "ID", "DisplaName");
    return View(model);
    

    查看

    @model YourAssembly.PersonVM
    ....
    @Html.ListBoxFor(m => m.ReceivedCalls, Model.CallList)
    

    编辑

    根据 OP 的要求,即最近调用的集合仅用于显示(不用于编辑),调整视图以使用无序列表(基于 OP 的模型,而不是上面建议的视图模型)

    @model WebApplication2.Models.Person
    ....
    <ul>
      @foreach(var call in Model.ReceivedCalls)
      {
        <li>@call</li> // this will use the .ToString() method
      }
    </ul>
    

    然后根据需要设置元素的样式,例如设置固定高度并使其可滚动且不带项目符号

    <style>
      ul {
        height:60px;
        overflow-y:scroll;
      }
      li {
        list-style:none;
      }
    </style>
    

    【讨论】:

    • 请看我的编辑。我修复了一些语法错误,但可能会破坏其他东西。我得到的结果与我只留下覆盖的 ToString 相同。谢谢。
    • 什么语法错误?你做了我展示的吗?你的编辑有@Html.ListBoxFor(m =&gt; m.ReceivedCalls, new MultiSelectList(Model.ReceivedCalls)),但它应该是@Html.ListBoxFor(m =&gt; m.ReceivedCalls, Model.CallList)CallList 已经是 MultiSelectList,因此您无需再次创建它。
    • 也有点不清楚你在这里通过使用&lt;select&gt; 元素来实现什么。您是否希望用户能够选择一些 Calls 并将这些选择保存到数据库中,或者您只想在页面上显示人员 Calls 的集合(在这种情况下使用 &lt;select&gt; 是不合适)
    • 我只想在可滚动容器中显示最近的调用,这就是我选择 ListBox 的原因(类似于 Android 中的 JList 和 ListSomething)。相反的顺序是否容易实现(列表上的最后一个调用)?
    • 在这种情况下,不需要使用&lt;select&gt; 控件,该控件用于回发数据。我会尽快更新答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多