1)如何以编程方式设置ListBox的滚动位置
ListBox不提供其内部ScrollViewer的访问器,因此您无法将其滚动到任何您想要的位置.
2)如何准确设置垂直滚动(即如何平滑滚动)?
默认情况下,无法通过一次滚动一个完整元素来滚动其他列表(列表框将始终确保第一个元素完全显示)
在大多数情况下这种行为是可以的,但不是我的:我想要一个平稳的运动…),
WPF有这个问题的解决方案,但Silverlight没有(见问题“is-it-possible-to-implement-smooth-scroll-in-a-wpf-listview”).
3)如何捕获MouseDown和MouseUp事件:
如果您继承ListBox,则可能能够捕获MouseUp和MouseMove事件.但是,MouseUp事件永远不会被触发(我怀疑它被ListBox子元素吃掉了)
解决方法
1)如何使ListBox平滑滚动:
这个问题在SilverLight 2中没有发生,它只发生在SilverLight 3中,其中引入了VirtualizedStackPanel.
VirtualizedStackPanel可以在巨大的列表中实现更快的刷新(因为只绘制了可见元素)
有一个解决方法(请注意,它不应该在大型列表中使用):重新定义ListBox的ItemPanelTemplate,以便它使用StackPanel:
<navigation:Page.Resources> <ItemsPanelTemplate x:Key="ItemsPanelTemplate"> <StackPanel/> </ItemsPanelTemplate> </navigation:Page.Resources> <StackPanel Orientation="Vertical" x:Name="LayoutRoot"> <ListBox x:Name="list" ItemsPanel="{StaticResource ItemsPanelTemplate}"> </ListBox> </StackPanel>
2)如何以编程方式更改滚动位置
请参阅下面的ListBox的子类:它提供了ListBox的内部ScrollViewer的访问器
3)如何捕获列表框中的MouseDown / Move / Up事件:
internal void MyOnMouseLeftButtonDown(MouseButtonEventArgs e) protected override void OnMouseMove(MouseEventArgs e) protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
将被召唤,你可以随心所欲地做任何事情.有一个微妙的技巧是从不调用ListBox的OnMouseLeftButtonDown方法:您需要实现ListBoxItem的子类,您可以在其中处理此事件.
using System; using System.Collections.Generic; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; namespace MyControls { //In order for this class to be usable as a control,you need to create a folder //named "generic" in your project,and a "generic.xaml" file in this folder //(this is where you can edit the default look of your controls) // /* * Typical content of an "empty" generic.xaml file : <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:VideoControls"> </ResourceDictionary> */ public class MyListBox : ListBox { public MyListBox() { DefaultStyleKey = typeof(ListBox); } public override void OnApplyTemplate() { base.OnApplyTemplate(); } #region ScrollViewer / unlocking access related code private ScrollViewer _scrollHost; public ScrollViewer ScrollViewer { get { if (_scrollHost == null) _scrollHost = FindVisualChildOfType<ScrollViewer>(this); return _scrollHost; } } public static childItemType FindVisualChildOfType<childItemType>(DependencyObject obj) where childItemType : DependencyObject { // Search immediate children first (breadth-first) for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++) { DependencyObject child = VisualTreeHelper.GetChild(obj,i); if (child != null && child is childItemType) return (childItemType)child; else { childItemType childOfChild = FindVisualChildOfType<childItemType>(child); if (childOfChild != null) return childOfChild; } } return null; } #endregion //Modify MyListBox so that it uses MyListBoxItem instead of ListBoxItem protected override DependencyObject GetContainerForItemOverride() { MyListBoxItem item = new MyListBoxItem(this); if (base.ItemContainerStyle != null) { item.Style = base.ItemContainerStyle; } return item; } //OnMouseLeftButtonUp is never reached,since it is eaten by the Items in the list... /* protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) { base.OnMouseLeftButtonDown(e); e.Handled = false; } */ internal void MyOnMouseLeftButtonDown(MouseButtonEventArgs e) { } protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); } protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e) { base.OnMouseLeftButtonUp(e); } } public class MyListBoxItem : ListBoxItem { MyListBox _customListBoxContainer; public MyListBoxItem() { } public MyListBoxItem(MyListBox customListBox) { this._customListBoxContainer = customListBox; } protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) { base.OnMouseLeftButtonDown(e); if (this._customListBoxContainer != null) { this._customListBoxContainer.MyOnMouseLeftButtonDown(e); } } } }