2013-02-10 18 views
8

Ho due DataTemplates definiti all'interno del mio XAML, ciascuno utilizzato per un pannello ItemsControl separato.WrapPanel con orientamento orizzontale all'interno degli elenchi ItemsControl verticalmente

Il comando ItemsControl elenca gli oggetti Foo memorizzati all'interno di un oggetto ObservableCollection.

L'oggetto Foo stesso ha il proprio insieme di elementi memorizzati all'interno di un oggetto ObservableCollection.

Ho provato a definire lo XAML in un modo che consenta a ciascuno degli elementi ObservableCollection Foo di essere visualizzato con il suo nome in un'intestazione (Il primo ItemsControl). Da questo l'elenco all'interno di ogni oggetto Foo deve essere visualizzato orizzontalmente (utilizzando il secondo ItemsControl) con un campo correlato direttamente sotto. Se sono presenti abbastanza oggetti, allora dovrebbero avvolgere la riga successiva dove necessario.

Questo è come l'interfaccia utente si trova attualmente:

Incorrect UI

Questo è come vorrei l'interfaccia utente di apparire in realtà: controlli

Correct UI

mio Markup (pulsanti sono per un altro aspetto dell'interfaccia utente):

<Grid> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="*"/> 
      <ColumnDefinition Width="Auto"/> 
     </Grid.ColumnDefinitions> 
     <ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"> 
      <ItemsControl x:Name="ContentList" ItemTemplate="{StaticResource GameTemplate}" Grid.Column="0" /> 
     </ScrollViewer> 
     <StackPanel Grid.Column="1" Background="DarkGray"> 
      <Button Click="OnLoad">_Load</Button> 
      <Button Click="OnSave">_Save</Button> 
      <Button Click="OnAdd">_Add</Button> 
      <Button Click="OnDelete">_Delete</Button> 
     </StackPanel> 
    </Grid> 

DataTemplate per gli elementi Foo sfogliare:

<DataTemplate x:Key="GameTemplate"> 
      <Grid> 
       <Grid.RowDefinitions> 
        <RowDefinition Height="30" /> 
        <RowDefinition Height="*" /> 
       </Grid.RowDefinitions> 
       <Label Content="{Binding Name}" Grid.Row="0" Background="Gray" FontSize="16" /> 
       <ItemsControl x:Name="imageContent" 
           ItemsSource="{Binding FileList}" 
           ItemTemplate="{StaticResource GameImagesTemplate}" 
           Grid.Row="1" /> 
      </Grid> 
     </DataTemplate> 

DataTemplate messa in vendita di un oggetto all'interno di ogni elemento Foo:

<DataTemplate x:Key="GameImagesTemplate"> 
      <WrapPanel Orientation="Horizontal"> 
       <StackPanel Orientation="Vertical" > 
        <Image Source="{Binding FileInfo.FullName}" 
         Margin="8,8,8,8" 
         Height="70" 
         Width="70" /> 
        <Label Content="{Binding Name}" /> 
       </StackPanel> 
      </WrapPanel> 
     </DataTemplate> 

Sono abbastanza nuovo per WPF così ho la sensazione che sia un problema causato da come sto usando i controlli.

Quali modifiche WPF dovrei apportare per generare l'interfaccia utente che desidero?

+0

Non c'è cosa che salta fuori come va con il tuo XAML. Puoi pubblicare come stai popolando i dati? –

+0

Un'implementazione di esempio sia di scorrimento verticale che orizzontale per le visualizzazioni di elementi ItemsControl: http://www.technical-recipes.com/2017/how-to-orient-wrappanel-items-within-itemscontrol-lists-vertically-and- orizzontalmente/ – AndyUK

risposta

17

penso proprio perché si sta aggiungendo ogni elemento immagine in un nuovo WrapPanel in GameImagesTemplate, si dovrebbe solo avere per impostare il ItemsControlItemsPanelTemplate-WrapPanel nel GameTemplate

Esempio:

Xaml:

<Window x:Class="WpfApplication1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="252.351" Width="403.213" Name="UI" > 
    <Window.Resources> 

     <DataTemplate x:Key="GameImagesTemplate" > 
      <StackPanel> 
       <Image Source="{Binding FileInfo.FullName}" Margin="8,8,8,8" Height="70" Width="70" /> 
       <Label Content="{Binding Name}" /> 
      </StackPanel> 
     </DataTemplate> 

     <DataTemplate x:Key="GameTemplate"> 
      <StackPanel> 
       <Label Content="{Binding Name}" Grid.Row="0" Background="Gray" FontSize="16" /> 
       <ItemsControl x:Name="imageContent" ItemsSource="{Binding FileList}" ItemTemplate="{StaticResource GameImagesTemplate}" > 
        <ItemsControl.ItemsPanel> 
         <ItemsPanelTemplate> 
          <WrapPanel Orientation="Horizontal" ScrollViewer.HorizontalScrollBarVisibility="Disabled" /> 
         </ItemsPanelTemplate> 
        </ItemsControl.ItemsPanel> 
       </ItemsControl> 
      </StackPanel> 
     </DataTemplate> 
    </Window.Resources> 

    <Grid> 
     <ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled"> 
      <ItemsControl ItemsSource="{Binding ElementName=UI, Path=FileList}" Grid.Column="0" ItemTemplate="{StaticResource GameTemplate}" /> 
     </ScrollViewer> 
    </Grid> 
</Window> 

Codice:

public partial class MainWindow : Window 
{ 
    private ObservableCollection<Foo> _fileList = new ObservableCollection<Foo>(); 

    public MainWindow() 
    { 
     InitializeComponent(); 
     foreach (var item in Directory.GetDirectories(@"C:\StackOverflow")) 
     { 
      FileList.Add(new Foo 
      { 
       Name = item, 
       FileList = new ObservableCollection<Bar>(Directory.GetFiles(item).Select(x => new Bar { FileInfo = new FileInfo(x) })) 
      }); 
     } 
    } 

    public ObservableCollection<Foo> FileList 
    { 
     get { return _fileList; } 
     set { _fileList = value; } 
    } 
} 

public class Foo 
{ 
    public string Name { get; set; } 
    public ObservableCollection<Bar> FileList { get; set; } 
} 

public class Bar 
{ 
    public FileInfo FileInfo { get; set; } 
} 

Risultato

enter image description here

+0

Ah, vedo esattamente dove stavo sbagliando. Grazie per la risposta dettagliata - +1 e un accetto per te! –