web-dev-qa-db-fra.com

Comment faire en sorte que WPF listview affiche les images et les étiquettes de manière dynamique

J'ai de la difficulté à créer l'interface utilisateur d'une fenêtre WPF. J'essaie d'afficher (dynamiquement) un groupe d'affiches de film avec le nom du film directement sous l'image. ItemsSource est assigné à une liste d'images via l'itération foreach. Les fichiers image eux-mêmes peuvent avoir différentes tailles, mais comme indiqué ci-dessous, je vais définir une taille uniforme.

Fondamentalement, mon objectif est que cela ressemble à ceci:

enter image description here

Jusqu'à présent, Mon code n'affiche qu'une fenêtre avec une grande ligne horizontale (?) Avec l'image au centre et aucune étiquette. Voici mon code XAML:

<Window x:Name="TVWindow" x:Class="PACS_Pre_Alpha.TV"
    xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
    Title="TV" Height="746" Width="1000" ResizeMode="NoResize">
<Grid x:Name="TVGrid">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition />
    </Grid.RowDefinitions>
    <ListView x:Name="TvBox" HorizontalAlignment="Left" Height="648" VerticalAlignment="Top" Width="994" Grid.Row="5" Grid.Column="5">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <UniformGrid Columns="5" />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ListView.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Vertical" VerticalAlignment="Stretch">
                    <Image Source="{Binding ImageData}" HorizontalAlignment="Center" VerticalAlignment="Top" />
                    <TextBlock Text="{Binding Title}" HorizontalAlignment="Center" VerticalAlignment="Bottom" />
                </StackPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Grid>

Mes films sont ajoutés avec ce code C #:

foreach (string tvf in ContentFiles)
{
            string ContentTitle = System.IO.Path.GetFileNameWithoutExtension(tvf);
            MovieData cnt = new MovieData();
            cnt.ImageData = LoadImage(ActualImage);
            cnt.Title = ContentTitle;
            ContentDataList.Add(cnt);

}
        TvBox.ItemsSource = ContentDataList;

Edit: j’ai modifié ma balise XAML comme l’a suggéré @MarkFeldman, mais rien ne s’affiche. Edit: Il se présente comme suit: enter image description here

5
Luke Dinkler

Vous allez fournir plus d'informations sur les données elles-mêmes, c'est-à-dire leur format, leur affectation à ItemsSource, etc. Pour une chose, vous ne définissez pas ItemTemplate. Par exemple, si vous avez une classe contenant vos données de film qui ressemble à ceci:

public class MovieData
{
    private string _Title;
    public string Title
    {
        get { return this._Title; }
        set { this._Title = value; }
    }

    private BitmapImage _ImageData;
    public BitmapImage ImageData
    {
        get { return this._ImageData; }
        set { this._ImageData = value; }
    }

}

Ensuite, vous l'afficheriez avec quelque chose comme ceci:

<ListView.ItemTemplate>
    <DataTemplate>
        <StackPanel Orientation="Vertical" VerticalAlignment="Stretch">
            <Image Source="{Binding ImageData}" HorizontalAlignment="Center" VerticalAlignment="Top"/>
            <TextBlock Text="{Binding Title}" HorizontalAlignment="Center" VerticalAlignment="Bottom"/>
        </StackPanel>
    </DataTemplate>
</ListView.ItemTemplate>

METTRE À JOUR:

Désolé, je pensais qu'il était évident que vous deviez encore utiliser UniformGrid. Voici à quoi devrait ressembler votre XAML complet:

<ListView x:Name="TvBox" HorizontalAlignment="Stretch" VerticalAlignment="Top">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Columns="5" HorizontalAlignment="Stretch"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ListView.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Vertical" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
                <Image Source="{Binding ImageData}" HorizontalAlignment="Stretch" VerticalAlignment="Top" Stretch="UniformToFill" />
                <TextBlock Text="{Binding Title}" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" />
            </StackPanel>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Je vous ai déjà fourni la classe MovieData, alors voici à quoi votre code Windows devrait ressembler:

public partial class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();

        this.TvBox.ItemsSource = new MovieData[]
        {
            new MovieData{Title="Movie 1", ImageData=LoadImage("image.jpg")},
            new MovieData{Title="Movie 2", ImageData=LoadImage("image.jpg")},
            new MovieData{Title="Movie 3", ImageData=LoadImage("image.jpg")},
            new MovieData{Title="Movie 4", ImageData=LoadImage("image.jpg")},
            new MovieData{Title="Movie 5", ImageData=LoadImage("image.jpg")},
            new MovieData{Title="Movie 6", ImageData=LoadImage("image.jpg")}
        };
    }

    // for this code image needs to be a project resource
    private BitmapImage LoadImage(string filename)
    {
        return new BitmapImage(new Uri("pack://application:,,,/" + filename));
    }
}

Dans cet exemple, je suppose qu'il existe dans votre projet une image intitulée "image.jpg" qui a été définie pour créer l'action "Ressource". Si vos images proviennent d'ailleurs, vous devrez modifier le code LoadImage en conséquence.

14
Mark Feldman

J'ai fait quelque chose de très similaire avec UniformGrid Je vois que vous n'avez pas défini les rangées de votre UniformGrid. Je l'ai fait dans mon jeu App. Bonne approche mais difficile à obtenir. Définir un ItemTemplate. Et essayez un objet extérieur ItemsControl au lieu de listview

<ItemsControl  IsEnabled="{Binding GameBoardEnabled}" 
                x:Name="_board" 
                ItemsSource ="{Binding Board}" 
                ItemTemplate= "{DynamicResource GamePieceTemplate}"  >
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <!--<StackPanel/>-->
                        <UniformGrid                          
                            Columns="{Binding Columns}" 
                            Rows   ="{Binding Rows}"  />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>
1
Mark Wardell