【发布时间】:2013-12-13 20:00:14
【问题描述】:
我是泛型的新手,所以我可能只是这样做完全错误,但这里是:
我有一小部分控件,我将它们组合成一个用户控件。看起来它会按预期工作,但 uc 需要是通用的。在 uc 中,我有几个列表框(和一些按钮)。那些列表框和 uc 必须能够接受任意数量的通用列表。 (即List<user>、List<group>、List<platform> 等,然后将更改返回到该通用列表。我想我可以接受通用列表,但不知道如何取回通用列表。
控制:
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="AddRemoveList.ascx.cs" Inherits="NSDC_Supply.UserControls.AddRemoveList" %>
<table>
<tr>
<td><asp:ListBox ID="ListBox1" Width="150px" Height="100px" SelectionMode="Single" runat="server" /></td>
<td><asp:Button ID="AddUser" runat="server" Text="<<" CausesValidation="false" onclick="AddUser_Click" /></td>
<td><asp:Button ID="RemoveUser" runat="server" Text=">>" CausesValidation="false" onclick="RemoveUser_Click" /></td>
<td><asp:ListBox ID="ListBox2" Width="150px" Height="100px" SelectionMode="Single" runat="server" /></td>
</tr>
</table>
代码背后:
public partial class AddRemoveList : System.Web.UI.UserControl
{
public T EditedList { get; set; } //Obviously this won't work
protected void Page_Load(object sender, EventArgs e)
{}
public void FillListBox<T>(T collection1, T collection2, string val, string text)
{
ListBox1.DataSource = collection1;
ListBox1.DataTextField = text;
ListBox1.DataValueField = val;
ListBox1.DataBind();
ListBox2.DataSource = collection2;
ListBox2.DataTextField = text;
ListBox2.DataValueField = val;
ListBox2.DataBind();
}
protected void AddItem_Click(object sender, EventArgs e)
{
if (ListBox2.SelectedIndex > -1)
{
ListBox1.Items.Add(ListBox2.SelectedItem);
EditedList.Add(ListBox2.SelectedItem);
ListBox2.Items.RemoveAt(ListBox2.SelectedIndex);
ListBox1.ClearSelection();
}
}
protected void RemoveItem_Click(object sender, EventArgs e)
{
if (ListBox1.SelectedIndex > -1)
{
ListBox2.Items.Add(ListBox1.SelectedItem);
EditedList.Remove(ListBox2.SelectedItem);
ListBox1.Items.RemoveAt(ListBox1.SelectedIndex);
ListBox2.ClearSelection();
}
}
}
所以首先我填充 uc:
private void GridView1_SelectedIndexChanged(...)
{
List<user> myUsers = selectedGroup.users.ToList();
List<user> masterUserList = uc.GetAllUsers().OrderBy(g => g.full_name).ToList();
UserControls.AddRemoveList ucarl = ((UserControls.AddRemoveList)FormView1.Controls[0].FindControl("ucAddRemoveList"));
ucarl.FillListBox(myUsers, masterUserList, "id", "full_name");
}
然后在 uc 中编辑列表框后,我尝试更新实体:
protected void FormView1_ItemUpdate(Object sender, FormViewUpdateEventArgs e)
{
network_group editedGroup = new network_group();
editedGroup.id = Convert.ToInt32(((Label)selectedControls.FindControl("lblid")).Text);
editedGroup.full_name = ((TextBox)selectedControls.FindControl("txtfull_name")).Text;
editedGroup.distribution_list_email = ((TextBox)selectedControls.FindControl("txtemail")).Text;
UserControls.AddRemoveList ucarl = ((UserControls.AddRemoveList)FormView1.Controls[0].FindControl("ucAddRemoveList"));
editedGroup.users.Add(ucarl); //psudocode here
ctx.SaveChanges();
}
如果我删除对 EditedList 的所有调用,它可以工作,但我如何从 uc 中获取通用 EditedList?
更新: 我得到的答案似乎是他们试图解决一个不同的问题……我想。所以这是我正在尝试做的更新:
我目前在一个页面上有两个 ListBox。我将从 EntityFramework 实体填充的对象列表绑定到 ListBoxes。 ListBox1 是我当前正在查看的实体对象的实体对象的子集合。 ListBox2 是子实体对象中所有可能条目的集合。因此,对于这个示例,我正在查看 Group 实体的一个实例。 ListBox1 是与该 Group 关联的所有用户,ListBox2 是公司中的所有用户。
在列表框之间是添加/删除按钮,用于在两者之间来回移动项目。 (所以我可以使用 AddItem_Click 和 RemoveItem_Click 事件将用户添加到组/从组、设备到/从站点等中添加或删除。然后在 FormView1_ItemUpdate 事件中,我获取 ListBox1 中的集合(已编辑的用户列表)并将其保存到数据库。
但是因为我将执行几乎完全相同的功能 9 次以上,所以我试图将 4 个控件抽象为一个 uc。通过这种方式,我可以传入任何两个 List 集合,我想为任何给定对象绑定的文本和值字段,进行添加/删除,然后返回修改后的 List。
所以我的问题不是关于从一个 ListBox 中获取项目到另一个,而是关于在我完成后从 ListBox1 中获取已编辑的 List 集合。这有帮助吗?它会改变任何答案吗?对不起,如果我太含糊了。
【问题讨论】:
-
这也不起作用,因为
EditedList将在每个页面请求上被清除。请记住,网络是无状态的。 -
嗯,我没想到。除了单个回发之外,我不需要跟踪 EditedList。一旦 FormView1_ItemUpdate(...) 被触发,我就会记录更改并转到另一个页面。
标签: c# asp.net generics user-controls generic-list