2012-01-21 3 views
3

Я пытаюсь реализовать пользовательский элемент управления.«Двумерный» UserControl

Рассмотрим ViewModels:

public class FileViewModel 
{ 
    public string Name { get; set; } 
    public BitmapSource Thumbnail { get; set; } 
} 

public class DirectoryViewModel 
{ 
    public string Name { get; set; } 
    public ObservableCollection<FileViewModel> Files { get; private set; } 
    public FileViewModel SelectedFile { get; set; } 
} 

Я хочу иметь UserControl, которые показывают такие ViewModels in this way (two ways):

1) Двумерный список типа управления.

2) Двухмерное покрытие-подобный контроль.

Обратите внимание, что каждый файл имеет миниатюру, и каждый каталог запоминает файл с последним просмотром. Директория должна отображать миниатюру последнего просмотра (как ее собственную), если каталог не выбран.

Выбор каталогов изменяется с помощью клавиш влево-вправо и соответствующих кнопок. Выбор файлов изменяется с помощью клавиш со стрелками вверх и соответствующих кнопок.

Кто-нибудь реализовал какой-то двумерный UserControl, как это?

С уважением, Серж.

ответ

0

Я могу придумать два способа приблизиться к нему, но у меня нет компилятора со мной прямо сейчас, чтобы проверить любой выход.

  • Метод один будет перезаписывать шаблон что-то вроде ListBox (так как вы хотите, чтобы отслеживать SelectedItem), так что SelectedItem всегда находится в том же самом месте. Изменение SelectedItem (с помощью мыши или клавиш со стрелками) просто переместит новый элемент в центр списка.

    Это может использоваться как файлами, так и каталогами. Заставьте каталоги использовать горизонтальную версию шаблона, и у него есть ItemTemplate для SelectedItem (используйте DataTrigger), чтобы найти Вертикальную версию шаблона для файлов.

  • Другим способом, который я мог бы придумать, является ItemsControls и подкатегория, показывающая следующие/предыдущие 3 файла/каталоги.

    Вы можете использовать операторы Linq для получения коллекций Previous/Next на основе начальной коллекции и текущего элемента. Например, MyCollection.Skip(MyCollection.IndexOf(SelectedItem)).Take(3)

<Grid> 
     <RowDefinitions> 
      <RowDefinition Height="*" /> 
      <RowDefintiion Height="Auto" /> 
      <RowDefinition Height="*" /> 
     </RowDefinitions> 
     <ColumnDefinitions> 
      <ColumnDefinition Height="*" /> 
      <ColumnDefinition Height="Auto" /> 
      <ColumnDefinition Height="*" /> 
     </ColumnDefinitions> 

     <!-- Previous 3 Files --> 
     <ItemsControl Grid.Row="0" Grid.Column="1" 
         ItemsSource="{Binding Previous3Files}" 
         ItemTemplate="{StaticResource FileTemplate}" 
         ItemsPanel="{Binding VerticalStackPanel}" /> 

     <!-- Next 3 Files -->  
     <ItemsControl Grid.Row="2" Grid.Column="1" 
         ItemsSource="{Binding Next3Files}" 
         ItemTemplate="{StaticResource FileTemplate}" 
         ItemsPanel="{Binding VerticalStackPanel}" /> 

     <!-- Previous 3 Directories--> 
     <ItemsControl Grid.Row="1" Grid.Column="0" 
         ItemsSource="{Binding Previous3Directories}" 
         ItemTemplate="{StaticResource DirectoryTemplate}" 
         ItemsPanel="{Binding HorizontalStackPanel}" /> 

     <!-- Next3 Directories--> 
     <ItemsControl Grid.Row="1" Grid.Column="2" 
         ItemsSource="{Binding Next3Directories}" 
         ItemTemplate="{StaticResource DirectoryTemplate}" 
         ItemsPanel="{Binding HorizontalStackPanel}" /> 

     <!-- Current Item --> 
     <ContentControl Grid.Row="1" Grid.Column="1" 
         Content="{Binding SelectedFile}" 
         ContentTemplate="{Binding FileTemplate}" /> 
     </ContentControl> 

    </Grid> 
+0

Рэйчел, спасибо большое за ответ. Не могли бы вы предоставить исходный код первого способа (вы описали)? –

+0

@Serge У меня нет исходного кода, хотя, по-моему, это будет что-то вроде 'ItemsControl' внутри' ScrollViewer' и некоторого кода для обеспечения того, чтобы 'SelectedItem' всегда был центрирован в' ScrollViewer' – Rachel