Tôi đã tìm thấy câu trả lời, vì vậy tôi sẽ trả lời bản thân mình.
1) Làm thế nào để làm cho cuộn ListBox suôn sẻ:
Vấn đề này đã không xảy ra trong Silverlight 2, và nó chỉ xảy ra với Silverlight 3, trong đó VirtualizedStackPanel đã được giới thiệu.
Các VirtualizedStackPanel cho phép nhanh hơn nhiều làm mới trong trường hợp danh sách khổng lồ (như chỉ các yếu tố có thể nhìn thấy được rút)
Có một workaround cho điều này (hãy cẩn thận, nó không nên được sử dụng trên danh sách khổng lồ): bạn xác định lại của ListBox ItemPanelTemplate, vì vậy mà nó sử dụng 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) Làm thế nào để programatically thay đổi vị trí di chuyển
Xem các lớp con của ListBox bên dưới: nó cung cấp một accessor để ScrollViewer nội bộ của ListBox
3) Làm thế nào để bắt MouseDown/Move/Up sự kiện trong listbox:
Tạo một lớp con của ListBox như hình dưới đây. 3 phương pháp:
internal void MyOnMouseLeftButtonDown(MouseButtonEventArgs e)
protected override void OnMouseMove(MouseEventArgs e)
protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
sẽ được gọi và bạn có thể làm bất cứ điều gì bạn muốn với chúng. Có một thủ thuật tinh tế đó là phương thức OnMouseLeftButtonDown của ListBox không bao giờ được gọi là: bạn cần triển khai một lớp con của ListBoxItem, nơi bạn có thể xử lý sự kiện này.
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);
}
}
}
}
Nguồn
2009-08-30 22:32:52