Dado un diccionario de <string, Drink>, ¿cómo se unen los dictionary.Values para WPF ListBox, de forma que los elementos de uso de la .Name propiedad?

struct Drink
{
    public string Name { get; private set; }
    public int Popularity { get; private set; }

    public Drink ( string name, int popularity )
        : this ( )
    {
        this.Name = name;
        this.Popularity = popularity;
    }
}
InformationsquelleAutor Joan Venge | 2010-03-22

2 Comentarios

  1. 47

    Configuración de la ItemsSource en un control de elementos crea un enlace a la enumerador para el objeto de origen. El enumerador de un Dictionary<T1, T2> es de tipo IEnumerable<KeyValuePair<T1, T2>>. Así que en tu plantilla de elemento, usted puede unirse a la Key y Value propiedades, y el uso de la sintaxis de ruta de acceso para obtener propiedades específicas de la clave y el valor.

    He aquí un ejemplo. Primero el código que crea y rellena el diccionario y se agrega al diccionario de recursos (hay un montón de maneras diferentes que usted puede exponer el diccionario de enlace de datos; esto es simple):

    namespace WpfApplication17
    {
        ///<summary>
        ///Interaction logic for Window1.xaml
        ///</summary>
        public partial class Window1 : Window
        {
            public Window1()
            {
                Dictionary<string, Drink> d = new Dictionary<string, Drink>();
                d.Add("A", new Drink("Nehi", 0));
                d.Add("B", new Drink("Moxie", 1));
                d.Add("C", new Drink("Vernor's", 2));
                d.Add("D", new Drink("Canfield's", 3));
    
                Resources["Drinks"] = d;
    
                InitializeComponent();
            }
    
            public class Drink
            {
                public Drink(string name, int popularity)
                {
                    Name = name;
                    Popularity = popularity;
                }
                public string Name { get; set; }
                public int Popularity { get; set; }
            }
        }
    }

    Ahora el código XAML para rellenar un ListBox (aunque un ListView sería más fácil, porque usted no tiene que definir una plantilla de este complicado para que se vea bonito):

    <Window x:Class="WpfApplication17.Window1"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Window1"
            Height="300"
            Width="300">
        <Grid Margin="10">
            <ListBox ItemsSource="{DynamicResource Drinks}" Grid.IsSharedSizeScope="True">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition SharedSizeGroup="Key" />
                                <ColumnDefinition SharedSizeGroup="Name" />
                                <ColumnDefinition SharedSizeGroup="Popularity" />
                            </Grid.ColumnDefinitions>
                            <TextBlock Margin="2" Text="{Binding Key}" Grid.Column="0"/>
                            <TextBlock Margin="2" Text="{Binding Value.Name}" Grid.Column="1"/>
                            <TextBlock Margin="2"  Text="{Binding Value.Popularity}" Grid.Column="2"/>
                        </Grid>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </Grid>
    </Window>

    El código XAML de una ListView es mucho más sencillo, y muestra más bien para arrancar:

    <ListView ItemsSource="{DynamicResource Drinks}">
        <ListView.View>
            <GridView>
                <GridViewColumn Header="Key"
                                DisplayMemberBinding="{Binding Key}" />
                <GridViewColumn Header="Name"
                                DisplayMemberBinding="{Binding Value.Name}" />
                <GridViewColumn Header="Popularity"
                                DisplayMemberBinding="{Binding Value.Popularity}" />
            </GridView>
        </ListView.View>
     </ListView>

    Para responder a sus preguntas de seguimiento:

    Recomiendo Adam Nathan Windows Presentation Foundation Desatado. El capítulo sobre diseño con paneles explica cómo funciona la Cuadrícula en considerable detalle. El Grid‘s bastante contra-intuitivo en un montón de maneras. Usted piensa que usted desea crear una sola Grid que contiene muchos elementos, pero el número de filas y columnas en una Grid no es dinámica. Entonces, ¿qué puedes hacer en su lugar es crear un Grid para cada elemento y, a continuación, usar el tamaño de la funcionalidad para asegurarse de que las columnas en cada Grid son del mismo tamaño. El ListView ha peculiaridades de su propio, pero es mucho más sencillo para el común de «mostrar varios elementos en una cuadrícula caso de uso».

    DynamicResource es una extensión de marcado que funciona en gran medida como StaticResource. La diferencia es que cuando el XAML analizador resuelve StaticResource como analiza si el recurso referenciado no está en el diccionario de recursos, se lanza una excepción. DynamicResource resuelve la referencia si el elemento se ha añadido al diccionario más tarde. Hay un poco de un costo de rendimiento para esto, pero es insignificante en la mayoría de los casos. El código que he publicado funciona si uso StaticResource, porque el XAML obtiene analiza en InitializeComponent. Pero no me gusta tener que recordar que, por lo que utilizar DynamicResource por defecto, si estoy de unión a algo que voy a agregar al diccionario de recursos en el código y simplemente no preocuparse acerca de si se ha creado, antes o después de que el XAML obtiene analiza.

    Y como para la caja de herramientas: tal vez voy a empezar a utilizar que en VS2010, pero me parece que el uno en el 2008 unusably buggy. Y no muy útil de todos modos. Yo casi todos los de mi trabajo de diseño en el editor, y algunos en Kaxaml. Creo que el editor visual en 2008 en realidad hace que el aprendizaje de WPF más difícil, porque imponía una capa de abstracción entre mí y el XAML (que en sí es una capa de abstracción entre el yo y el objeto de WPF modelo). Y no es una muy buena capa de abstracción: las decisiones de diseño que iba a decidir lo que debe ser ocultado y lo que debe ser visible, no son, me parece, el derecho queridos. También está plagado de errores como el infierno.

    • Gracias Robert, eres impresionante. Realmente funciona muy bien. Soy muy nuevo en wpf, así que esto es muy útil para mí para tratar de entender. Tengo un par de preguntas si no te importa. 1. ¿Cómo se puede encontrar más información sobre la sintaxis xaml? Por ejemplo, lo del DynamicResource, de la Cuadrícula.IsSharedSizeScope, SharedSizeGroup, etc? También me di cuenta que cuando yo primero crear un control arrastrando desde el cuadro de herramientas, me sale algo como: <ListView … </> por lo tanto debo de tipo </ListView> insertar nuevas líneas en él. Es eso normal? Tal vez eso no ocurrirá si el tipo de todo en lugar de utilizar la caja de herramientas.
    • Véase mi edición de respuestas.
    • +1 para un bien explicado seguimiento. Y un buen ejemplo así 😉
    • Gracias Robert, eres un gran maestro. Me gustaría poder aprender este tipo de información privilegiada para las nuevas cosas que quiero aprender. Si yo pudiera darle más puntos, lo haría.
    • Una de las formas principales en las que yo he aprendido de todo esto es respondiendo a preguntas sobre ESO. Alguien hace una pregunta que yo sé que tal vez la mitad de la respuesta, y me puso el tiempo en la figura de la otra mitad fuera, y ahora entiendo el tema mejor que yo hice al principio. Diferentes personas aprenden las cosas de formas diferentes, por supuesto, pero esto realmente funciona para mí. Como hace dos semanas, yo no tenía ninguna idea de cómo utilizar ListView, pero alguien hizo una pregunta, y, bueno, ahora tengo que hacer.
    • Buena idea, Robert. Yo soy el opuesto, yo aprender haciendo (muchas) preguntas :O
    • Respuestas de este tipo son siempre muy apreciada thx 🙂

  2. 1

    ListBox.DisplayMemberPath = "Name";

    Que dirá el cuadro de lista para utilizar el ‘Nombre’ de la propiedad de la DataContext

    • Leí su pregunta como para decir que se va a enlazar directamente al diccionario.Los valores que acaba de ser IEnumerable<Beber>, si se unen a todo el diccionario, eso es correcto.
    • Sí sólo .Valores. Pero es el código de arriba lo suficiente como para enlazarlo? Puede usted por favor enviar xaml para ello, ya que esto es lo que estoy tratando de aprender. Gracias.

Dejar respuesta

Please enter your comment!
Please enter your name here