【问题标题】:After rebinding Silverlight Listbox control how do you get it listbox to scroll to back to the top?重新绑定 Silverlight 列表框控件后,如何让列表框滚动到顶部?
【发布时间】:2009-12-03 21:19:21
【问题描述】:

我有一个用作搜索结果框的 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 控件,然后从那里设置它的视图位置?

【问题讨论】:

    标签: silverlight listbox scrollviewer


    【解决方案1】:

    看完这篇文章

    Automatic Scrolling in a Silverlight List Box

    我尝试了以下方法,对我来说效果很好。

     theListBox.ItemsSource = data;
     theListBox.UpdateLayout();
     theListBox.ScrollIntoView(theListBox.Items[0]);
    

    【讨论】:

    • 这就是我所缺少的。 UpdateLayout 让 ScrollIntoView (我过去一直在努力工作)来做它需要做的事情。谢谢!
    • 太棒了。我尝试了几种不同的方法,这一种非常适合我的需求。
    【解决方案2】:

    你试过了吗

    mReportList.SelectedIndex = 0
    

    【讨论】:

    • 我尝试使用 SearchResultBox 执行此操作,但没有任何反应,它仍然滚动到框顶部的最后一个值,滚动条位于框的最底部。当我尝试执行 mReportList.SelectedIndex 时,它不是 mReportList 的有效属性。
    猜你喜欢
    • 2011-05-02
    • 1970-01-01
    • 2012-03-03
    • 2013-01-25
    • 1970-01-01
    • 2017-12-04
    • 1970-01-01
    • 2011-05-27
    • 1970-01-01
    相关资源
    最近更新 更多