您的位置:首页 > 其它

[Silverlight学习笔记]如何滚动没有滚动条的ListBox?

2010-11-14 18:53 411 查看
一个ListBox是由好几个部件组成的,系统默认的构成为:Grid--Border--ScrollViewer--ItemsPresenter还有ValidationErrorElement等几个部件组成,如图:在新建的ListBox中点击右键并选择“编辑模板”就可以编辑ListBox的ControlTemplate了,如上图所示。我给Grid,Border,ScrollViewer等部件都起了名,以便之后能够通过Name属性来查找到相应的部件。如:listBoxCustomer的ControlTemplate相应的XAML代码如下:
<ControlTemplate TargetType="ListBox">
<Grid x:Name="myGrid">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ValidationStates">
<VisualState x:Name="Valid"/>
<VisualState x:Name="InvalidUnfocused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="ValidationErrorElement">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="InvalidFocused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="ValidationErrorElement">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="IsOpen" Storyboard.TargetName="validationTooltip">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<System:Boolean>True</System:Boolean>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="myBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="2">
<Grid x:Name="subGrid">
<RepeatButton x:Name="repeatBtnUp" Content="Up" Height="22" Width="60" Margin="97,8,104,0" VerticalAlignment="Top" Canvas.ZIndex="2"/>
<ScrollViewer x:Name="myScrollViewer" BorderBrush="Transparent" BorderThickness="0" Padding="{TemplateBinding Padding}" TabNavigation="{TemplateBinding TabNavigation}"  HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" Background="#FF372E2E">
<ItemsPresenter Height="466" Width="259"/>
</ScrollViewer>
<RepeatButton x:Name="repeatBtnDown" Content="Down" Width="60" Height="22" Margin="92,0,109,6" VerticalAlignment="Bottom" Canvas.ZIndex="2"/>
</Grid>
</Border>
<Border x:Name="ValidationErrorElement" BorderBrush="#FFDB000C" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="2" Visibility="Collapsed">
<ToolTipService.ToolTip>
<ToolTip x:Name="validationTooltip" DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}" Placement="Right" PlacementTarget="{Binding RelativeSource={RelativeSource TemplatedParent}}" Template="{StaticResource ValidationToolTipTemplate}">
<ToolTip.Triggers>
<EventTrigger RoutedEvent="Canvas.Loaded">
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="IsHitTestVisible" Storyboard.TargetName="validationTooltip">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<System:Boolean>true</System:Boolean>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ToolTip.Triggers>
</ToolTip>
</ToolTipService.ToolTip>
<Grid Background="Transparent" HorizontalAlignment="Right" Height="10" Margin="0,-4,-4,0" VerticalAlignment="Top" Width="10">
<Path Data="M 1,0 L6,0 A 2,2 90 0 1 8,2 L8,7 z" Fill="#FFDC000C" Margin="-1,3,0,0"/>
<Path Data="M 0,0 L2,0 L 8,6 L8,8" Fill="#ffffff" Margin="-1,3,0,0"/>
</Grid>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
我们将myScrollViewer的HorizontalScrollBarVisibility和VerticalScrollBarVisibility属性设置为Hidden,此时myScrollViewer的水平和竖直滚动条都隐藏起来了,那么我们怎么在界面中滚动myScrollViewer中的内容呢?有两种方法:1.通过鼠标中间的滚轮来滚动2.通过ScrollViewer的ScrollToHorizontalOffset和ScrollToVerticalOffset两个方法来分别滚动相应的水平位移或者竖直位移。我们使用ScrollToVerticalOffset来做个示范,代码如下:
private Point m_mousePosition;
private double m_scrollOffset = 0;
private ScrollViewer m_listScroll;

//名为listBoxCustomer的ListBox的MouseMove事件
private void listBoxCustomer_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
{
ListBox element = sender as ListBox;
ScrollViewer myScrollViewer = GetListBoxScrollViewer(element);
m_mousePosition = e.GetPosition(element);
if (m_mousePosition.Y > (element.ActualHeight / 2))
{
m_scrollOffset++;
myScrollViewer.ScrollToVerticalOffset(m_scrollOffset);//通过ScrollToVerticalOffset可以滚动它里面的内容
}
else
{
m_scrollOffset--;
myScrollViewer.ScrollToVerticalOffset(m_scrollOffset);
}
}

//从listBoxCustomer的构成部件中获取在ControlTemplate中定义的myScrollViewer部件
protected ScrollViewer GetListBoxScrollViewer(ListBox element)
{
//由于Template的名称范围(在DataTemplate,ContentTemplate,ControlTemlate等Template中定义的部
//件仅在该Template加载(一般是包含该Template的部件加载的时候该Template才被加载,所以最终还是得在
//该部件加载的时候才能获得它所对应的Template中定义的子部件)的时候才能获取,它们的名称范围(类似与
//参数或局部变量的作用域)仅限于各Template根元素内的限制,只有当ListBox被Loaded时才能获取该ListBox
//的构成部件,即element得从listBoxCustomer传进来才能获取listBoxCustomer中的部件(因为
//listBoxCustomer已被加载),如果把E行换为:
//Grid myGrid = VisualTreeHelper.GetChild(listBoxCustomer, 0) as Grid;
//也是能获取到myGrid部件,如果换为:
//ListBox list=new ListBox();
//Grid myGrid = VisualTreeHelper.GetChild(list, 0) ;
//则获取不到myGrid
Grid myGrid = VisualTreeHelper.GetChild(element, 0) as Grid;//E 行
Border myBorder = myGrid.FindName("myBorder") as Border;
Grid subGrid = myBorder.Child as Grid;
ScrollViewer myScrollViewer = subGrid.FindName("myScrollViewer") as ScrollViewer;
return myScrollViewer;
}
[/code]

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐