重新绑定Silverlight Listbox控件后,如何使它的listbox滚动回到顶部? [英] After rebinding Silverlight Listbox control how do you get it listbox to scroll to back to the top?
问题描述
我有一个Silverlight列表框,它被用作搜索结果框.我正在使用动态搜索(搜索框中的键入会触发事件以过滤此列表框的内容).我遇到的问题是,如果用户在未过滤框的情况下向下滚动,然后进行搜索,则重新绑定列表框不会导致滚动回到顶部,从而导致结果看起来只有一个价值.
I have a silverlight listbox that is being used as a search result box. I'm using dynamic searching (keyups in the search box cause the events to fire to filter this list box's contents). The issue I'm running into is if the user scrolls down when the box is unfiltered, then does the search, the rebinding of the listbox does not cause the scroll to go back up to the top making the results look like there is only one value in it.
到目前为止,我在列表框中使用的代码是这样的(这是简化版本):
the code I have so far for the listbox is this (This is a simplified version):
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控件,然后设置从那里查看的位置?
Again this is simplified greatly from what is going on (I go to database to get report names, etc). When I rebind the listbox, how do I get it to scroll all the way to have the first item at the top of the list? Since I don't have access to the scrollviewer control from within the ListBox object, do I have to make a scrollviewer control that surrounds the listbox and then set where it's view is from there?
推荐答案
看完这篇文章
我尝试了以下方法,对我来说效果很好.
I tried the following and it worked fine for me.
theListBox.ItemsSource = data;
theListBox.UpdateLayout();
theListBox.ScrollIntoView(theListBox.Items[0]);
这篇关于重新绑定Silverlight Listbox控件后,如何使它的listbox滚动回到顶部?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!