我已经找到了答案,所以我会回答自己。
1)如何使ListBox平滑滚动:
这个问题在SilverLight 2中没有出现,在SilverLight 3中引入了VirtualizedStackPanel,只有在使用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)如何在listbox中捕获MouseDown / Move / Up事件:
创建一个ListBox的子类,如下所示。三个方法:
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
{
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
{
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
protected override DependencyObject GetContainerForItemOverride()
{
MyListBoxItem item = new MyListBoxItem(this);
if (base.ItemContainerStyle != null)
{
item.Style = base.ItemContainerStyle;
}
return item;
}
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);
}
}
}
}