title: Generics and User Controls
body: <p>I'm new to generics so I'm probably just doing this completely wrong but here goes:
  I have a small collection of controls that I'm combining together into a user control.  It looks like it'll work as expected but the uc needs to be generic.  Within the uc I have couple listboxes (and some buttons).  Those list boxes and the uc must be able to take any number of generic lists.  (Ie <code>List&lt;user&gt;</code>, <code>List&lt;group&gt;</code>, <code>List&lt;platform&gt;</code>, etc and then return the changes to that generic list.  I think I have it accepting the generic list alright but not sure how to get a generic list back.  </p>
  
  <p>Control:</p>
  
  <pre><code>&lt;%@ Control Language="C#" AutoEventWireup="true" CodeBehind="AddRemoveList.ascx.cs" Inherits="NSDC_Supply.UserControls.AddRemoveList" %&gt;
  &lt;table&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;asp:ListBox ID="ListBox1" Width="150px" Height="100px" SelectionMode="Single" runat="server" /&gt;&lt;/td&gt;
          &lt;td&gt;&lt;asp:Button ID="AddUser" runat="server" Text="&lt;&lt;" CausesValidation="false" onclick="AddUser_Click" /&gt;&lt;/td&gt;
          &lt;td&gt;&lt;asp:Button ID="RemoveUser" runat="server" Text="&gt;&gt;" CausesValidation="false" onclick="RemoveUser_Click" /&gt;&lt;/td&gt;
          &lt;td&gt;&lt;asp:ListBox ID="ListBox2" Width="150px" Height="100px" SelectionMode="Single" runat="server" /&gt;&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/table&gt;
  </code></pre>
  
  <p>Code Behind:</p>
  
  <pre><code>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&lt;T&gt;(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 &gt; -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 &gt; -1)
          {
              ListBox2.Items.Add(ListBox1.SelectedItem);
              EditedList.Remove(ListBox2.SelectedItem);
              ListBox1.Items.RemoveAt(ListBox1.SelectedIndex);
              ListBox2.ClearSelection();
          }
      }
  
  }
  </code></pre>
  
  <p>So first I populating the uc:</p>
  
  <pre><code>private void GridView1_SelectedIndexChanged(...)
  {
      List&lt;user&gt; myUsers = selectedGroup.users.ToList();
      List&lt;user&gt; masterUserList = uc.GetAllUsers().OrderBy(g =&gt; g.full_name).ToList();
  
      UserControls.AddRemoveList ucarl = ((UserControls.AddRemoveList)FormView1.Controls[0].FindControl("ucAddRemoveList"));
      ucarl.FillListBox(myUsers, masterUserList, "id", "full_name");
  }
  </code></pre>
  
  <p>Then after editing the listboxes in the uc, I try updating the entity:</p>
  
  <pre><code>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();
  }
  </code></pre>
  
  <p>If I remove all calls to EditedList, it works but how do I get the generic EditedList out of the uc?</p>
  
  <p><strong>UPDATE:</strong>
  The answers  I’m getting seem like they’re trying to solve a different issue…I think.  So here’s an update of what I’m trying to do:</p>
  
  <p>I currently have two ListBoxes on a page.  I bind a list of objects populated from EntityFramework entities to the ListBoxes.  ListBox1 is a child collection of entity objects for the entity object I’m currently looking at.  ListBox2 is a collection of all the entries possible in the child entity object.  So for this example, I’m looking at an instance of the Group entity.  ListBox1 is all the Users associated with this Group and ListBox2 is all the Users in the company.</p>
  
  <p>Between the ListBoxes are add/remove buttons to move items back and forth between the two.  (So I can add or remove Users to/from Groups, Devices to/from Sites, etc using the AddItem_Click and RemoveItem_Click events.  Then on FormView1_ItemUpdate event I'm grabbing the collection in ListBox1 (the edited list of Users) and saving it to the DB.  </p>
  
  <p>But because I will be doing this almost exact functionality 9+ times, I'm trying to abstract the 4 controls into a uc.  This way I can pass in any two List collections, the text and value fields I want to bind for any given object, do my adding/removing and then get a modified List back.  </p>
  
  <p>So my question isn’t about getting the items from one ListBox to the other, it’s about getting the edited List collection from ListBox1 back when I’m done.  Does this help?  Does it change any of the answers?  Sorry if I was too vague.</p>