我在WP7中创建了一个Scrollviewer,其中包含3个usercontrol,每个用户控件都作为其内容保存,XAML创建了UserControls。这很好用。此滚动查看器应该能够在这些项目之间滚动,但这使得用户无法滚动。因此,当单击其中一个内容中的项目时,滚动查看器将根据所选项目向左或向右滑动,并进入其中一个其他用户控件。我用一个中介来完成这个:
<Grid.Resources>
<Storyboard x:Name="ItemAnimation">
<DoubleAnimation x:Name="ItemAnimationContent"
Storyboard.TargetName="Mediator"
Storyboard.TargetProperty="ScrollableWidthMultiplier"/>
</Storyboard>
</Grid.Resources>
<ScrollViewer Name="ScrollableItemPanel"
Grid.Row="2"
Grid.RowSpan="3"
Grid.ColumnSpan="3"
VerticalScrollBarVisibility="Disabled"
HorizontalScrollBarVisibility="Disabled">
<StackPanel Orientation="Horizontal">
<UserControl Name="NewsListBoxControl" Width="480" />
<UserControl Name="DetailedItemControl" Width="480"/>
<UserControl Name="ExternalBrowserItemControl" Width="480"/>
</StackPanel>
</ScrollViewer>
<local:ScrollableItemAnimationMediator x:Name="Mediator"
ScrollViewer="{Binding ElementName=ScrollableItemPanel}"/>
基本上,这也可以正常工作,我可以在项目之间导航,并将内容作为用户控件加载到它们上面。但问题在于授予用户滚动的能力。在项目滚动之前,我将hittestvisibilty设置为true,并将horizontalscrollbarvisibility设置为可见。动画完成后,我想授予hittestvisibility并再次将horizontalscrollbarvisibility设置为Disabled。后者是问题所在:当我将horizontalscrollbarvisibility设置为Disabled时,scrollviewer会自动返回到stackpanel中三个项目中的第一个。我怎么能阻止这个?这是我用来滚动介体的代码:
private void CreateDetailedArticleItem( Dictionary<string, string> itemQuery )
{
_articleDetailPage.ItemQuery = itemQuery;
DetailedItemControl.Content = _articleDetailPage as UserControl;
Animate( _articleDetailPage, 0.0f, 0.5f, 250 );
}
private void Animate( IContentControl control, float from, float to, double milliseconds )
{
//this eventhandler will fire when the animation has completed
EventHandler handler = null;
//we take away the User Input just for the moment, so that we can animate without the user interfering. Also, we make horizontalScroll Visible
IsUserEnabled = false;
//we then set the content of the animation. Where from will it move, towards where and in what duration?
ItemAnimationContent.From = from;
ItemAnimationContent.To = to;
ItemAnimationContent.Duration = TimeSpan.FromMilliseconds( milliseconds );
//we start the animation
ItemAnimation.Begin( );
//we tell the new control that it will appear soon, so it can load its main content
control.ViewWillAppear( );
//also, we tell the currentcontrol that it will disappear soon, so it can unload its content and eventhandlers and so on
CurrentControl.ViewWillDisAppear( );
//the handler is a delegate. This way, it becomes rather easy and clean to fire the completed event, without creating a strong reference ( well, actually,
//we do create a strong reference, but as soon as it is fired, we remove it again, shhhh! ).
handler = delegate( object sender, EventArgs e )
{
//as stated, we remove the eventlistener again, so it won't keep firing all the time
ItemAnimation.Completed -= handler;
//after the animation, we tell the new control that it is now in screen, and can start downloading its data
control.ViewDidAppear( );
//at the same time, the "current" control has fully moved out of view, so it can now fully unload all its content.
CurrentControl.ViewDidDisAppear( );
//now, all we have to do is to make sure that the next time an item is being loaded, the new content is spoken to, not the old one
CurrentControl = control;
//and finally, enable the users input again, and remove the horizontal scrollbarvisibility
IsUserEnabled = true;
};
ItemAnimation.Completed += handler;
}
private bool IsUserEnabled
{
set
{
//when the user can control the scrollviewer, then the horizontal scrollvisibility is disabled, so that the user cannot move horizontally,
//otherwise, so we only make it visible when the program needs to animate.
ScrollableItemPanel.IsHitTestVisible = value;
ScrollableItemPanel.HorizontalScrollBarVisibility = value ? ScrollBarVisibility.Disabled : ScrollBarVisibility.Visible;
}
}
我已经问过这个问题,然后把它视为已回答,因为我认为要回答,即使用ScrollbarVisibility.Hidden而不是ScrollbarVisibility.Disabled,只有滚动条可见性保持可见,用户仍然可以滚动。是否有一种本地方式来处理这个问题?
非常感谢任何帮助。格尔茨
答案 0 :(得分:1)
不是打击本机控件的行为,而是使用自定义控件(包装其他控件)来操作项目的位置可能更容易,这些控件在不同的视觉状态之间激活(调整转换变换),具体取决于“选择“项目。