Preámbulo

Estoy haciendo esta pregunta porque a pesar de que he leído a través de un montón de ListView recursos, todavía no estoy ‘getting’ it.

De fondo

Tengo un montón de Foo‘s que tienen una lista de elementos asociados con ellos (conocido como Bar), y estoy tirando de ellos a partir de los Datos de Acceso/capa de Lógica de Negocios como de Diccionario que contiene un Foo y sus asociados Bars. Me gustaría escupirle estos objetos en la Página web en un ListView que tiene el Foo.Name a la izquierda, y el List<Bar> a la derecha en un dropdownlist. (Se muestra con la belleza de mi arte ASCII a continuación):

ListView

------------------------------------------------------------------ 
| Nombre Del Artículo | DropDownList (de la Lista de<T>) | 
|---------------------------------| _____________________ | 
| foo1 | | bar1 | v | | 
| | |_______________|___| | 
------------------------------------------------------------------ 
| | DropDownList (de la Lista de<T>) | 
| | _____________________ | 
| foo2 | | bar2 | v | | 
| | |_______________|___| | 
------------------------------------------------------------------ 

Muy bien, aquí es lo que está pasando. Este es un ListView; Los elementos se extraen de una base de datos en un Dictionary<Foo, List<Bar>>. Estoy tratando de obtener el Valor de la Clave del diccionario para mostrar bajo el Nombre de Elemento’, y estoy tratando de sacar la Lista de<T> Bar’ para mostrar como un DropDownList en el lado derecho de la ListView.

Diagramas De Clase

----------------- ----------------- 
| Foo | Bar | | 
----------------- ----------------- 
| Id | | ItemName | 
| Nombre | | ItemValue | 
| BarID | | | 
----------------- ----------------- 

Así que para recapitular, quiero colocar el Diccionario.Clave «Nombre» en el lado izquierdo de la vista de lista, y el Diccionario.Valor (que pasa a ser una lista) en un DropdownList en el lado derecho.

De modo que, para cada par Clave/Valor, no tendría que ser un Nombre y una lista desplegable que la casa de cada Valor de la Clave.

Pero estoy ejecutando en problemas (obviamente), y estoy esperando que alguien me puede decir qué estoy haciendo mal.

Código Detrás De:

  protected Dictionary<Foo, List<Bar>> FooDictionary
        {
            get; 
            set; 
        }

protected void DataBindFooList(List<int> SelectedFoos)
        {
            System.Web.UI.WebControls.ListView lv = lvFooList;

try
            {
                Dictionary<Foo, List<Bar>> fooDictionary =
                    new Dictionary<Foo, List<Bar>>();

                foreach (int Foo in SelectedFoos)
                {
                 //Build List of Foos to add as Dictionary.Keys
                 fooDictionary.Add(fooScalar, Bar)                     
                }
                FooDictionary = fooDictionary;
                lv.DataSource = FooDictionary;
                lv.DataBind();
                ddlListOfBars.DataSource = FooDictionary;
                ddlListOfBars.DataValueField = "ItemValue";
                ddlListOfBars.DataTextField = "ItemName";
                ddlListOfBars.DataBind();
            }
            catch (Exception ex)
            {
                SetMessage(divFooMsg, "Unable to retrieve Foos: " + 
                ex.Message, true, true);
            }

El ListView Código:

<asp:ListView ID="lvFooList" runat="server">
   <LayoutTemplate>
      <asp:PlaceHolder runat="server" ID="itemPlaceholder"></asp:PlaceHolder>
   </LayoutTemplate>
      <ItemSeparatorTemplate>
         <hr />
      </ItemSeparatorTemplate>
   <ItemTemplate>
      <%#Eval("Name") %>
      <asp:DropDownList ID="ddlListOfBars" runat="server"></asp:DropDownList>
    </ItemTemplate>
   </asp:ListView>

La Pregunta(s):

  1. Es posible el uso de un Diccionario de esta manera?
  2. Cualquier punteros en donde me estoy equivocando? (Recursos, sugerencias, etc. sería de ayuda)
  3. Hay una manera mejor de hacer esto?
  4. Si esta pregunta es tan claro como el barro, por favor deje un comentario para que yo pueda averiguar cómo mejorarlo.
  • +1 para los muy bien la pregunta escrita. Apenas podía encontrar nada de hack and slash!
  • ¿De dónde FooDictionary provienen y por qué asignar FooDictionary = fooDictionary; y lv.DataSource = FooDictionary;?
  • Manu: Hay un montón de vudú en la instrucción foreach. Esencialmente se pasa a través de y crea un diccionario de los Foo y las Barras asociadas con la que foo. Sólo me mostró el producto final de la facilidad. No debería el datasource ser el FooDictionary así se puede obtener el nombre?

2 Comentarios

  1. 9

    El problema surge porque no tiene sentido databind ddlListOfBars en DataBindFooList(), porque no hay un DropDownList para databind. Cuando usted llame a lv.DataBind(), el control ListView, se crea una copia de tu plantilla ItemTemplate para cada uno de los Foo, cada uno con un ddlListOfBars. Usted necesita decirle a enlazar cada una de las Desplegable a la derecha de la Lista de<Bar> como va. Usted puede hacerlo mediante la configuración del origen de datos de ddlListOfBars con las expresiones de enlace de datos en lugar de en el código detrás de:

    <ItemTemplate>
      <%#Eval("Key.Name") %>
      <asp:DropDownList
            ID="ddlListOfBars"
            runat="server"
            DataSource='<%#Eval("Value")%>'
            DataValueField="ItemValue"
            DataTextField="ItemName" />
    </ItemTemplate>

    Tenga en cuenta que también es necesario el uso de Claves».Nombre» para obtener el nombre de la propiedad de su Foo. El individuo diccionario de elementos que son vinculantes son KeyValuePair<Foo,Lista de<Bar>>, que tiene una propiedad Clave y un Valor de propiedad para acceder a los Foo y Lista de<Bar> respectivamente.

    Editar

    Si tienes mucho que hacer en su ItemTemplate que puede ser útil para mover el contenido en un control de usuario. El control de usuario puede tener un establecimiento inflexible de tipos de propiedad para acceder a la DataItem, y cuenta con establecimiento inflexible de tipos de acceso a sus controles secundarios. Esto da la flexibilidad de el evento ItemDataBound sin todas las de la fundición y el FindControl() ruido. Yo la duda que me gustaría molestar en este caso, pero sería algo como

    <asp:ListView ID="lvFooList" runat="server">
    <LayoutTemplate>
      <asp:PlaceHolder runat="server" ID="itemPlaceholder"></asp:PlaceHolder>
    </LayoutTemplate>
      <ItemSeparatorTemplate>
         <hr />
      </ItemSeparatorTemplate>
    <ItemTemplate>
      <uc:ListViewContents DataItem='<%# Container.DataItem %>' />
    </ItemTemplate>

    ListViewContents.ascx…

    <asp:Label ID="lbName" runat="server"/>
    <asp:DropDownList ID="ddlListOfBars" runat="server"></asp:DropDownList>

    ListViewContents.ascx.cs…

    public KeyValuePair<Foo,List<Bar>> DataItem
    {
        get; set;
    }
    
    protected override void OnDataBinding(EventArgs e)
    {
        base.OnDataBinding(e);
    
        lbName.Text = DataItem.Key.Name;
    
        ddlListOfBars.DataTextField = "ItemName";
        ddlListOfBars.DataValueField = "ItemValue";
        ddlListOfBars.DataSource = DataItem.Value;
        ddlListOfBars.DataBind();   
    }
  2. 4

    Es algo como esto lo que usted desea:

       <asp:ListView ID="lvFooList" runat="server">
        <LayoutTemplate>
          <asp:PlaceHolder runat="server" ID="itemPlaceholder"></asp:PlaceHolder>
        </LayoutTemplate>
          <ItemSeparatorTemplate>
             <hr />
          </ItemSeparatorTemplate>
        <ItemTemplate>
          <asp:Label ID="lbName" runat="server"/>
          <asp:DropDownList ID="ddlListOfBars" runat="server"></asp:DropDownList>
        </ItemTemplate>
       </asp:ListView>

    Luego escribí muy rápido desagradable prueba

        public class Foo
    {
    public string Name;
    }
    public class Bar
    {
    public string ItemName { get; set; }
    public string ItemValue { get; set; }
    }
    protected void Page_Load(object sender, EventArgs e)
    {
    var fooKey1 = new Foo() {Name = "foo1"};
    var barList1 = new List<Bar>()
    {
    new Bar() {ItemName = "bar1", ItemValue = "barV1"},
    new Bar() {ItemName = "bar2", ItemValue = "barV2"}
    };
    var fooKey2 = new Foo() {Name = "foo2"};
    var barList2 = new List<Bar>()
    {
    new Bar() {ItemName = "bar3", ItemValue = "barV3"},
    new Bar() {ItemName = "bar4", ItemValue = "barV4"}
    };
    var dicFooBar = new Dictionary<Foo, List<Bar>>() {{fooKey1, barList1}, {fooKey2, barList2}};
    lvFooList.ItemDataBound += lvFooList_ItemDataBound;
    lvFooList.DataSource = dicFooBar;
    lvFooList.DataBind();
    }
    void lvFooList_ItemDataBound(object sender, ListViewItemEventArgs e)
    {
    var dataItem = (ListViewDataItem)e.Item;
    var fooBarList = (KeyValuePair<Foo, List<Bar>>)dataItem.DataItem;
    ((Label) dataItem.FindControl("lbName")).Text = fooBarList.Key.Name;
    var ddlListOfBars = (DropDownList) dataItem.FindControl("ddlListOfBars");
    ddlListOfBars.DataTextField = "ItemName";
    ddlListOfBars.DataValueField = "ItemValue";
    ddlListOfBars.DataSource = fooBarList.Value;
    ddlListOfBars.DataBind();
    }

    Parece hacer lo que quieras, pero mi código es sólo rápido el código de la prueba, por lo que se advierte. Se hizo representar como se esperaba, aunque.

Dejar respuesta

Please enter your comment!
Please enter your name here