问题
Hi and thanks for looking!
Background
First, I am an absolute n00b to WPF/Silverlight/XAML.
I have a wrappanel into which I add a bunch of image thumbnails at runtime. This works well.
When the wrap panel is populated, it runs the thumbnails horizontally and then wraps on the next row repeatedly so that after all thumbnails are loaded, I have several out of view below the screen.
In my app, the a scrollbar looks to wonky, so I would like to add an "up" and "down" button above the wrap panel.
Problem
When the up or down buttons are clicked, how do I slide the content/children of the wrappanel up or down? Ideally, I would like to incorporate a nice easing effect so that the transition is fast at first and slows to a stop.
Many thanks!
Matt
回答1:
Here are 2 ways to do this, one is more WPF-like and other may be easier to understand.
Approach 1.
Use ScrollViewer
and restyle it as you need. WPF-like approach - you need to scroll, so use ScrollViewer
, need custom appearance or layout - redefine its template.
<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>
Approach 2.
More straightforward solution - write a method that scrolls content, and call it from button click event handlers (or wrap it in ICommand). You can use Storyboard
to apply animation effects for smooth scrolling.
Use the following simple layout (it doesn't include up/down buttons - place them as you like, nothing special about them here):
<Canvas>
<WrapPanel x:Name="MyContent"
Width="{Binding ActualWidth,
RelativeSource={RelativeSource AncestorType={x:Type Canvas}}}">
</WrapPanel>
</Canvas>
Canvas
is used instead of ScrollContentPresenter
because Canvas.Top
property can be animated.
And following method to scroll content:
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();
}
Method usage:
// scroll down 30 units animating for 100ms
AnimateScroll(MyContent, -30, new TimeSpan(0, 0, 0, 0, 100));
来源:https://stackoverflow.com/questions/8691394/how-do-i-slide-child-items-up-or-down-inside-a-wpf-wrappanel