web-dev-qa-db-fra.com

Lier la clé et la valeur d'un dictionnaire dans une zone de liste avec wpf

J'essaie de lier la clé d'un dictionnaire à une ligne de la grille dans une zone de liste et de lier la valeur du dictionnaire à une autre ligne de la grille. le type de la clé est Book, une classe qui a été écrite et le type de la valeur est int. je veux écrire les éléments de la classe et la valeur entière dans la grille. Pouvez-vous m'aider à ce sujet? Je suis assez confus quant à la détermination de la source d'éléments et du type de données à lier. Merci pour ton aide

Edit: j'ai oublié de dire que j'utilise c # - wpf. =)


J'ai envoyé le dictionnaire en tant que itemsSource, et j'ai spécifié le dictionnaire en tant que type dans la balise objectdataprovider, et j'ai essayé d'envoyer la valeur (int) par ce code:

< TextBlock Text="{Binding Value, Mode=OneWay}" Grid.Row="1" Width="65" >

et l'élément sélectionné était affiché sous la forme [myNameSpace.Book, 4] au lieu de seulement 4.


BookListBox.ItemsSource = LibManager.Books;

c'est ce que j'ai écrit dans Window.xaml.cs et Books est un BookList, où BookList est un type de dictionnaire <Book, int>.

et le fichier xaml:

< ListBox Height="571" HorizontalAlignment="Left" Margin="444,88,0,0"
          Name="BookListBox" VerticalAlignment="Top" Width="383" >
        < ListBox.Resources>
            <ObjectDataProvider x:Key="BookData"
                                ObjectType="{x:Type local:BookList}"/>
        </ListBox.Resources>
        < ListBox.ItemTemplate>
            < DataTemplate>
                < Border BorderThickness="2" BorderBrush="Black" Margin="5"
                         CornerRadius="5" Width="350" >
                    < Grid DataContext="{StaticResource BookData}" >
                        < Grid.ColumnDefinitions>
                            < ColumnDefinition/>                        
                        </Grid.ColumnDefinitions>
                        < Grid.RowDefinitions>
                            < RowDefinition/>
                            < RowDefinition/>
                        < /Grid.RowDefinitions>
                        < Label Content="count: " />
                        < TextBlock Text="{Binding Value, Mode=OneWay}"
                                    Grid.Row="1" Width="65"/>
                    < /Grid>
                < /Border>
            < /DataTemplate>
        < /ListBox.ItemTemplate>
    < /ListBox>

il y a encore un problème avec mon code - je ne peux pas voir les éléments listés dans la liste. Je veux dire que je pourrais obtenir les valeurs par ListBox.SelectedItem mais impossible à voir dans la liste. ainsi je ne peux pas être sûr si je pourrais passer la valeur entière à l'endroit où je veux.

Je pense donc que j'ai également besoin d'aide pour ce problème d'abord ... J'écris une étiquette que j'écris à la main, et une autre étiquette qui devrait être remplie par la liaison de données dans la même ligne, mais je peux juste voir la première étiquette, mais je peux atteindre la valeur en code derrière.

14
cemregoksu

Le code ci-dessous affichera les éléments suivants:

1
Book 1
-------
2
Book 2
-------
3
Book 3

SelectedBookIndex sera défini sur l'index du livre sélectionné, au début le deuxième livre sera sélectionné.

XAML:

<Window x:Class="TestDemo.MainWindow"
    xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
    Height="300" Width="300">

    <StackPanel>
        <ListBox 
            ItemsSource="{Binding Path=Books}"
            SelectedValuePath="Value"
            SelectedValue="{Binding Path=SelectedBookIndex}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Border BorderBrush="Black" BorderThickness="2">
                        <StackPanel>
                            <TextBlock Text="{Binding Path=Value}" />
                            <TextBlock Text="{Binding Path=Key.Name}" />
                        </StackPanel>
                    </Border>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </StackPanel>
</Window>

Code derrière:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows;

namespace TestDemo
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            Books = new Dictionary<Book, int>();
            Books.Add(new Book() { Name = "Book 1"}, 1);
            Books.Add(new Book() { Name = "Book 2" }, 2);
            Books.Add(new Book() { Name = "Book 3" }, 3);

            SelectedBookIndex = 2;

            DataContext = this;
        }

        public Dictionary<Book, int> Books { get; set; }

        private int _selectedBookIndex;
        public int SelectedBookIndex
        {
            get { return _selectedBookIndex; }
            set
            {
                _selectedBookIndex = value;
                Debug.WriteLine("Selected Book Index=" + _selectedBookIndex);
            }
        }
    }

    public class Book
    {
        public string Name { get; set; }
    }
}
33

Retirer DataContext="{StaticResource BookData}" de l'élément Grid.

L'ObjectDataProvider créera une nouvelle BookList vide et votre TextBlock hérite de ce DataContext. Si vous supprimez cet attribut, le TextBlock obtiendra son DataContext de l'élément en cours dans le ItemsControl, qui sera le KeyValuePair pour cette ligne. Vous pouvez probablement supprimer complètement l'élément ObjectDataProvider puisque vous créez les données dans le code.

0
Quartermeister