Как сдвинуть дочерние элементы вверх или вниз внутри WPF-оболочки? - PullRequest
1 голос
/ 01 января 2012

Привет и спасибо за поиск!

Фон

Во-первых, я абсолютный n00b для WPF / Silverlight / XAML.

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

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

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

Проблема

Когданажимаются кнопки «вверх» или «вниз», как сдвинуть содержимое / дочерние элементы панели вверх или вниз?В идеале я хотел бы включить приятный эффект замедления, чтобы сначала переход был быстрым и замедлялся до остановки.

Большое спасибо!

Мэтт

1 Ответ

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

Вот два способа сделать это: один более похож на WPF, а другой может быть проще для понимания.

Подход 1.

Использование ScrollViewerи переделайте это, как вам нужно.WPF-подобный подход - вам нужно прокрутить, поэтому используйте ScrollViewer, нужен собственный внешний вид или макет - переопределите его шаблон.

<ScrollViewer>
    <ScrollViewer.Template>
        <ControlTemplate TargetType="{x:Type ScrollViewer}">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition />
                </Grid.RowDefinitions>
                <ScrollBar Grid.Row="0"
                           x:Name="PART_VerticalScrollBar"
                           Width="{TemplateBinding ActualWidth}"
                           Orientation="Vertical">
                    <ScrollBar.Template>
                        <ControlTemplate TargetType="{x:Type ScrollBar}">
                            <StackPanel Orientation="Horizontal">
                                <RepeatButton Content="Up"
                                              Margin="2"
                                              Command="ScrollBar.LineUpCommand"/>
                                <RepeatButton Content="Down"
                                              Margin="2"
                                              Command="ScrollBar.LineDownCommand"/>
                            </StackPanel>
                        </ControlTemplate>
                    </ScrollBar.Template>
                </ScrollBar>
                <ScrollContentPresenter Grid.Row="1"
                                        x:Name="PART_ScrollContentPresenter" />
            </Grid>
        </ControlTemplate>
    </ScrollViewer.Template>
    <WrapPanel x:Name="MyContent">
        <!-- your data items are here -->
    </WrapPanel>
</ScrollViewer>

Подход 2.

Более простое решение - написать метод, который прокручивает содержимое, и вызывать его из обработчиков событий нажатия кнопки (или обернуть его в ICommand).Вы можете использовать Storyboard для применения анимационных эффектов для плавной прокрутки.

Используйте следующую простую раскладку (она не включает кнопки вверх / вниз - размещайте их по своему усмотрению, ничего особенного в них нет):

<Canvas>
    <WrapPanel x:Name="MyContent"
               Width="{Binding ActualWidth,
                               RelativeSource={RelativeSource AncestorType={x:Type Canvas}}}">
    </WrapPanel>
</Canvas>

Canvas используется вместо ScrollContentPresenter, поскольку свойство Canvas.Top может быть анимировано.

И следующий метод для прокрутки содержимого:

static void AnimateScroll(UIElement element, double amount, TimeSpan duration)
{
    var sb = new Storyboard();
    var position = Canvas.GetTop(element);
    if(double.IsNaN(position)) position = 0;
    var animation =
        new DoubleAnimation
        {
            // fine-tune animation here
            From = position,
            To = position + amount,
            Duration = new Duration(duration),
        };
    Storyboard.SetTarget(animation, element);
    Storyboard.SetTargetProperty(animation, new PropertyPath(Canvas.TopProperty));
    sb.Children.Add(animation);
    sb.Begin();
}

Методиспользование:

// scroll down 30 units animating for 100ms
AnimateScroll(MyContent, -30, new TimeSpan(0, 0, 0, 0, 100));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...