我有一个用作搜索结果框的 silverlight 列表框。我正在使用动态搜索(搜索框中的按键导致事件触发以过滤此列表框的内容)。我遇到的问题是,如果用户在未过滤框时向下滚动,然后进行搜索,列表框的重新绑定不会导致滚动回到顶部,使结果看起来只有一个其中的价值。
到目前为止,我对列表框的代码是这样的(这是一个简化版本):
XAML:
<Grid x:Name="MainGrid" Rows="2">
<StackPanel Orientation="Horizontal" Grid.Row="0">
<TextBlock text="Search" Grid.Row="0" />
<Textbox x:name="textboxSearch" Keyup="textBoxSearch_KeyUp" width="200"
Height="25"/>
</StackPanel>
<ListBox x:Name="SearchResultBox" Visibility="Visible" Grid.Row="1"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalscrollbarVisibility="Auto">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding ReportName}" />
<TextBlock Text="{Binding ReportDescription}" />
</StackPanel>
</DataTemplate>
</Listbox.ItemTemplate>
</ListBox>
</Grid>
VB:
Imports System.Threading
Imports System.Collections.ObjectModel
Imports System.ComponentModel
Partial Public Class ucSearch
Inherits UserControl
Private WithEvents BGwork As New BackgroundWorker()
Private mReportList as New List(Of cFilter)
Public Sub New()
InitializeComponent()
FillReportList()
NewFilterList()
End Sub
Private Sub FillReportList()
mReportList.Add(new cFilter("Report A", "Report A desc")
mReportList.Add(new cFilter("Report B", "Report B desc")
mReportList.Add(new cFilter("Report C", "Report C desc")
mReportList.Add(new cFilter("Report D", "Report D desc")
mReportList.Add(new cFilter("Report E", "Report E desc")
mReportList.Add(new cFilter("Report F", "Report F desc")
mReportList.Add(new cFilter("Report G", "Report G desc")
mReportList.Add(new cFilter("Report H", "Report H desc")
mReportList.Add(new cFilter("Report I", "Report I desc")
mReportList.Add(new cFilter("Report J", "Report J desc")
mReportList.Add(new cFilter("Report K", "Report K desc")
mReportList.Add(new cFilter("Report L", "Report L desc")
mReportList.Add(new cFilter("Report M", "Report M desc")
End Sub
Private Sub textboxSearch_KeyUp(ByVal sender as System.Object, _
ByVal e as System.Windows.Input.KeyeventArgs)
NewFilterList()
End Sub
Private Sub NewFilterList()
If BGwork.IsBusy Then
If Not BGWork.cancellationPending Then BGwork.CancelAsync()
Exit Sub
End If
With BGwork
.WorkerSupportsCancellation = True
.RunWorkerAsync(textboxSearch.Text)
End With
End Sub
Private Sub BGwork_DoWork(ByVal sender as Object, _
ByVal e as System.ComponentModel.DoWorkEventArgs) _
Handles BGwork.DoWork
Dim Filtered as New List(of cFilter)
If textboxSearch.Text.Length > 0
dim q = FROM ri In mReportList Where ri.Reportname.ToLower.contains(textboxSearch.Text.ToLower) Select ri
Filtered = q
Else
Filtered = mReportList
End If
Dim RTN as List(Of cFilter) = Filtered
e.Cancel = False
e.Result = RTN
End Sub
Private Sub BGwork_RunWorkerCompleted(ByVal sender As Object_
ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) _
Handles BGwork.RunWorkerCompleted
If e.Cancelled Then
NewFilterList()
Exit Sub
End If
Dim RTN as cFilter = TryCast(e.Result, cFilter)
If IsNothing(RTN) Then Exit Sub
SearchResultBox.ItemsSource = RTN
SearchResultBox.InvalidateArrange()
End Sub
End Class
Public Class cFilter
Inherits BaseDataClass
Private mReportName as String = ""
Private mReportDescription as String = ""
Public Sub New()
mReportName = ""
mReportDescription = ""
End Sub
Public Sub New(ByVal reportName as String, ByVal reportDescription as String)
mReportName = reportName
mReportDescription = reportDescription
End Sub
Public Property ReportName() as String
Get
Return mReportName
End Get
Set(ByVal value as String)
mReportName = value
End Set
End Property
Public Property ReportDescription() as String
Get
Return mReportDescription
End Get
Set(ByVal value as String)
mReportDescription = value
End Set
End Property
End Class
这再次大大简化了正在发生的事情(我去数据库获取报告名称等)。当我重新绑定列表框时,如何让它一直滚动到列表顶部的第一项?由于我无法从 ListBox 对象中访问 scrollviewer 控件,我是否必须制作一个围绕列表框的 scrollviewer 控件,然后从那里设置它的视图位置?