如何在WP7上实现相机应用风格的照片条?
我在创建与相机应用程序中的照片条非常相似的效果时遇到了许多问题。
我想要做的就是显示一行网格,每个网格的尺寸与屏幕相同(无论是纵向还是横向)。我已经不得不做一些 hacky 并 创建网格宽度和高度属性绑定的依赖属性 以保持纵横比。
这很好用。但是,当我为条带创建一个 StackPanel 并实现导航(或者只是使用 z-index 变换缩放)时,我发现我的 StackPanel 无法显示大于屏幕尺寸的内容(它被裁剪为只有一个网格的大小) 。我以为我找到了一篇描述这个问题的帖子,但现在找不到了 - 如果您知道我正在考虑哪个帖子或者您了解更多有关此限制的信息,请发帖。
我发现的唯一解决方法是使用 ScrollViewer,这绝对不是我想要的行为,但它允许 StackPanel 比屏幕更宽。
我真正的问题是 ScrollViewer 行为 - 因为我需要从一个网格跳到另一个网格(就像照片带一样)而不是自由滚动,并且据我所知 HorizontalOffset 不是一个可设置动画的属性。我可以通过每 15 毫秒调用 ScrollToHorizontalOffset 来强制它进行动画处理,基本上是手动实现我自己的缓动效果。这看起来像是一个巨大的黑客行为,并且行为非常小故障(要么我没有在每次我期望的时候收到 ManipulationCompleted 事件 - 在每次滑动操作结束时 - 或者 ScrollViewer 的内置惯性物理干扰了我的效果)。
有谁知道我遇到的问题的更好解决方法,或者完全不同的方式来获得 Silverlight 中相机照片条的体验?
我考虑过使用枢轴控件,但这并不完全是我想要的(如果我希望每个项目在下一个项目进入之前完全动画化,而不是看起来全部附加到一个条带上,那么应该有更少的约束实现这一目标的方法)。更重要的是,条带只是我希望能够动态实现的众多效果之一。我想要交替使用类似于 CoolIris 的 3d 倾斜功能或 FlipPad 样式的翻页功能。我相信,如果我能让当前的设置很好地工作,那么实现这些其他效果(作为主题过渡)就会很容易。致力于像 Pivot 这样的控件并不会让我更接近这个愿景。
这是我的 XAML:
<Grid x:Name="LayoutRoot" Background="Transparent" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" Width="{Binding RealWidth, ElementName=phoneApplicationPage}" HorizontalAlignment="Left" VerticalAlignment="Top">
<ScrollViewer x:Name="SlideScroller" VerticalScrollBarVisibility="Disabled" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" Margin="0,0,0,-31" ScrollViewer.HorizontalScrollBarVisibility="Auto" HorizontalAlignment="Left" VerticalAlignment="Top">
<StackPanel x:Name="SlidePanel" Orientation="Horizontal" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" VerticalAlignment="Top" HorizontalAlignment="Left">
<Grid x:Name="Slide0" Margin="0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="{Binding RealWidth, ElementName=phoneApplicationPage}" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" Background="#FFCCCCCC">
<Image x:Name="Photo0" Width="{Binding RealWidth, ElementName=phoneApplicationPage}" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" VerticalAlignment="Top" HorizontalAlignment="Left" Stretch="UniformToFill"/>
</Grid>
<Grid x:Name="Slide1" Margin="0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="{Binding RealWidth, ElementName=phoneApplicationPage}" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" Background="#FFCCCCCC">
<Image x:Name="Photo1" Width="{Binding RealWidth, ElementName=phoneApplicationPage}" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" VerticalAlignment="Top" HorizontalAlignment="Left" Stretch="UniformToFill"/>
</Grid>
<Grid x:Name="Slide2" Margin="0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="{Binding RealWidth, ElementName=phoneApplicationPage}" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" Background="#FFCCCCCC">
<Image x:Name="Photo2" Width="{Binding RealWidth, ElementName=phoneApplicationPage}" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" VerticalAlignment="Top" HorizontalAlignment="Left" Stretch="UniformToFill"/>
</Grid>
</StackPanel>
</ScrollViewer>
</Grid>
I'm running into a number of problems creating an effect very similar to the photo strip in the Camera app.
All I want to do is display a row of grids that each have the same dimensions as the screen (whether in portrait or landscape). Already, I had to do something hacky and create dependency properties that the grids width and height properties bind to to maintain the aspect ratio.
And this works fine. But when I create a StackPanel for my strip and implement my navigation (or just zoom back with the z-index transform) I see that my StackPanel can't display larger than the screen dimensions (it's clipped to the size of just one grid). I thought I found a post describing this issue but I can't find it now - please post if you know which post I'm thinking of or if you know more about this limitation.
The only workaround I've found is to use a ScrollViewer, which is absolutely not the behavior I want, but it allows the StackPanel to be wider than the screen.
My real problem is with the ScrollViewer behavior - because I need to hop from grid to grid (just like the photo strip does) instead of freely scrolling, and as far as I can tell the HorizontalOffset is not an animatable property. I can force it to animate by calling ScrollToHorizontalOffset every 15 milliseconds, basically implementing my own easing effect manually. This seems like a huge hack, and the behavior is very glitchy (either I'm not getting the ManipulationCompleted event every time I expect it - at the end of every swipe action - or the built in inertia physics of ScrollViewer is interfering with my effect).
Does anyone know better workarounds for the issues I've run into, or a completely different way to get the experience of the Camera Photo strip in Silverlight?
I have considered using the Pivot control, but it isn't quite what I want (if I wanted each item to animate out completely before the next one comes in, instead of appearing to be all attached to one strip, there should be less constraining ways to achieve that). More importantly, the strip is just one of many effects I want to be able to do dynamically. I'd like to alternately have a CoolIris-like 3d-tilt, or a FlipPad style page turn. I believe if I could get my current setup working nicely it would be easy to implement these other effects (as themable transitions). Committing to a control like Pivot won't get me any closer to that vision.
Here is my XAML:
<Grid x:Name="LayoutRoot" Background="Transparent" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" Width="{Binding RealWidth, ElementName=phoneApplicationPage}" HorizontalAlignment="Left" VerticalAlignment="Top">
<ScrollViewer x:Name="SlideScroller" VerticalScrollBarVisibility="Disabled" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" Margin="0,0,0,-31" ScrollViewer.HorizontalScrollBarVisibility="Auto" HorizontalAlignment="Left" VerticalAlignment="Top">
<StackPanel x:Name="SlidePanel" Orientation="Horizontal" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" VerticalAlignment="Top" HorizontalAlignment="Left">
<Grid x:Name="Slide0" Margin="0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="{Binding RealWidth, ElementName=phoneApplicationPage}" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" Background="#FFCCCCCC">
<Image x:Name="Photo0" Width="{Binding RealWidth, ElementName=phoneApplicationPage}" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" VerticalAlignment="Top" HorizontalAlignment="Left" Stretch="UniformToFill"/>
</Grid>
<Grid x:Name="Slide1" Margin="0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="{Binding RealWidth, ElementName=phoneApplicationPage}" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" Background="#FFCCCCCC">
<Image x:Name="Photo1" Width="{Binding RealWidth, ElementName=phoneApplicationPage}" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" VerticalAlignment="Top" HorizontalAlignment="Left" Stretch="UniformToFill"/>
</Grid>
<Grid x:Name="Slide2" Margin="0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="{Binding RealWidth, ElementName=phoneApplicationPage}" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" Background="#FFCCCCCC">
<Image x:Name="Photo2" Width="{Binding RealWidth, ElementName=phoneApplicationPage}" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" VerticalAlignment="Top" HorizontalAlignment="Left" Stretch="UniformToFill"/>
</Grid>
</StackPanel>
</ScrollViewer>
</Grid>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
事实证明,如果我只是防止 ScrollViewer 被用户直接操作并手动定位它,我描述的设置效果很好。这消除了导致我提到的大部分故障的物理效应。
XAML
代码隐藏
为了清晰起见,这被简化了一点(我还在我的应用程序中使用垂直滑动,并且我省略了如何为 ScrollViewer 制作动画 - 可能值得它自己的帖子)。
我很想听听您对此可以提供的任何改进,或者关于更好的实施方法的建议。也许扩展面板类或作为自定义行为。想法?
It turns out the setup I described works pretty well if I just prevent the ScrollViewer from getting manipulated directly by the user and position it manually. This eliminates the physics effects that were causing most of the glitchiness I mentioned.
XAML
Codebehind
This is simplified a bit for clarity (I also use vertical swipe for something in my app and I omitted how I'm animating the ScrollViewer - probably worthy of it's own post).
I'd love to hear any improvements you can offer to this, or suggestions on better ways to implement it altogether. Perhaps extending the Panel Class or as a custom Behavior. Thoughts?