Вот два способа сделать это: один более похож на 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));