简单的问题,我有一个 Windows Phone 页面,其中包含 a ,其中包含 a scrollviewer
、image
atextblock
和 a richtextbox
。
现在,当用户开始滚动时,我想在页面滚动到页面外textblock
时将视图保持在顶部image
。
所以效果是,用户开始向上滚动,一切都向上滚动,当图像在页面之外时,文本块停留在页面顶部,但richtextbox继续向上滚动。
有什么想法吗?
简单的问题,我有一个 Windows Phone 页面,其中包含 a ,其中包含 a scrollviewer
、image
atextblock
和 a richtextbox
。
现在,当用户开始滚动时,我想在页面滚动到页面外textblock
时将视图保持在顶部image
。
所以效果是,用户开始向上滚动,一切都向上滚动,当图像在页面之外时,文本块停留在页面顶部,但richtextbox继续向上滚动。
有什么想法吗?
我自己找到了一个可行的解决方案……完整的详细信息可在我的博客上找到……它还包含指向我在 GitHub 上的演示项目的链接。
诀窍是抓住VerticallScrollBar
内部ScrollViewer
并将其设置为ManipulationMode
在Control
UI 线程上获得足够的反馈。使用滚动条的滚动偏移信息,我们可以为要保持在视图中的特定 ui 元素设置动画。
这是达到此结果的一种方法:
一是布局。我设置了一个网格,有两行。第一个是空的,当我们需要冻结它时将托管标题。第二行包含滚动查看器。
在滚动查看器中,我将控件放在网格中,但您可以使用任何适合您的容器。
<ScrollViewer Grid.Row="1"
Margin="0"
Padding="0"
x:Name="ParentScroll"
ManipulationMode="Control"
MouseMove="ParentScroll_MouseMove">
<Grid x:Name="ChildGrid">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Image Source="Picture.jpg" Grid.Row="0"/>
<TextBlock Text="Header" Grid.Row="1" x:Name="TextHeader" />
<RichTextBox Grid.Row="2" x:Name="RichText">
<Paragraph>
<Bold>RichTextBox</Bold>
<!-- More stuff -->
</Paragraph>
</RichTextBox>
</Grid>
</ScrollViewer>
我使用MouseMove
事件来通知滚动事件。您还可以深入了解模板、提取ScrollBar
控件并订阅ValueChanged
事件,如下所述:http: //social.msdn.microsoft.com/Forums/wpapps/en-US/81fcd34e-6ec9-48d0-891e- c53a53344553/scrollviewer-同步
请注意,您需要设置ManipulationMode
为,Control
否则控件的位置将不会以平滑的速率更新。我想这是由于一些内部优化。
在后面的代码中,我使用该TransformToVisual
方法来计算控件与 ScrollViewer 的相对位置。这样,我可以知道标题何时消失。当它发生时,我将其从子网格中删除,并将其放在父网格中的 ScrollViewer 之外。当 RichTextBox 的顶部看不见时,我将标题放回 ScrollViewer:
private void ParentScroll_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
{
if (Grid.GetRow(this.TextHeader) == 1)
{
var generalTransform = TextHeader.TransformToVisual(ParentScroll);
var childToParentCoordinates = generalTransform.Transform(new Point(0, 0));
if (childToParentCoordinates.Y < 0)
{
this.ChildGrid.Children.Remove(this.TextHeader);
this.ParentGrid.Children.Add(this.TextHeader);
Grid.SetRow(this.TextHeader, 0);
}
}
else
{
var generalTransform = RichText.TransformToVisual(ParentScroll);
var childToParentCoordinates = generalTransform.Transform(new Point(0, 0));
if (childToParentCoordinates.Y > 0)
{
this.ParentGrid.Children.Remove(this.TextHeader);
this.ChildGrid.Children.Add(this.TextHeader);
Grid.SetRow(this.TextHeader, 1);
}
}
可能有一些不那么棘手的方法可以达到相同的结果,但这个解决方案似乎在模拟器中运行顺利。