«Двумерный» UserControl - PullRequest
       16

«Двумерный» UserControl

3 голосов
/ 21 января 2012

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

Давайте рассмотрим 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 таким образом (два способа) :

1) Двумерное управление в виде списка.

2) Двумерное управление в виде покрытия потока.

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

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

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

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

1 Ответ

0 голосов
/ 23 января 2012

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

  • Первый способ - переписать шаблон чего-то вроде 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>
...