【发布时间】:2016-06-16 08:10:36
【问题描述】:
我创建了一个 WPF 控件,它允许我正在开发的应用程序的用户轻松选择要连接的 SQL Server。在控件上,存在三种不同类别的 SQL Server:本地、最近和网络上的更多服务器。
本地:运行应用程序的计算机上的 SQL Server 实例。
最近:用户最近连接的 SQL Server 实例。
网络上的更多服务器:通过在本地网络上发送搜索请求发现的 SQL Server 实例。 “网络上的更多服务器”不会自动填充,因为有时需要一段时间才能填充。大多数情况下,用户连接到最近使用的 SQL Server 实例,不需要浏览网络。
简而言之,这个控件由几个模板化的 ListBox 和 TextBlock 控件组成,所有这些控件都嵌套在一个主 WPF ScrollViewer 控件内。 ScrollViewer 将增长到适合所有内容所需的任何大小,并且 ScrollViewer 将允许用户滚动到该内容的任何部分。由于整个控件的 XAML 相当冗长,因此我将其压缩为伪代码以了解要点:
<Grid>
<ScrollViewer x:name="mainScrollViewer">
<StackPanel>
<Grid>
<Grid.RowDefinitions>
...
<Grid.RowDefinitions />
<Textblock Text="Local" />
<ListBox />
</Grid>
<Grid>
...
<Textblock Text="Recent" />
<ListBox />
</Grid>
...
<StackPanel>
</ScrollViewer>
</Grid>
大门外,控件启动时是这样的:
如果用户需要在工作上浏览其他SQL Server实例,用户将单击“单击此处搜索本地网络”按钮。单击此按钮将生成一个单独的线程,该线程将执行搜索,同时保持 UI 响应。在此期间,控件会显示一个动画旋转的“等待” gif,如下所示:
当控件完成搜索后,用户将能够点击任何发现的服务器,就像在“本地”和“最近”部分中一样:
然而,根据本地网络环境和其他条件,搜索并不总是能找到所有可用的服务器。发生这种情况时,用户可以单击超链接按钮:“手动将服务器添加到此列表”。单击此超链接按钮时,DataTrigger 会折叠超链接并在其位置放置一个 TextBox,以便用户手动输入服务器名称:
出现文本框,允许用户输入用户名。文本框上有一个“KeyDown”事件的处理程序,用于侦听 ENTER 键。当按下 ENTER 键时,服务器被添加到列表中,文本框被折叠,并调用主 ScrollViewer 控件上的“ScrollToBottom()”方法并选择新添加的项。
以下是 KeyDown 处理程序的代码隐藏:
private void txtAddServer_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Escape)
{
this.AddServerToListIsShown = false;
}
else if (e.Key == Key.Enter)
{
if (this.MoreServers == null)
MoreServers = new ObservableCollection<DatabaseServer>();
if (this.AllSQLServerNames == null)
this.AllSQLServerNames = new ObservableCollection<string>();
if (!this.MoreServers.Any(x => string.Compare(txtAddServer.Text, x.Description, true) == 0))
{
this.AllSQLServerNames.Add(this.txtAddServer.Text.ToUpper());
this.MoreServers.Add(new DatabaseServer { Description = this.txtAddServer.Text.ToUpper(), ServerName = this.txtAddServer.Text.ToUpper() });
var foundItem = this.MoreServers.FirstOrDefault(x => string.Compare(x.Description, this.txtAddServer.Text, true) == 0);
if (foundItem != null)
{
this.SelectedServer = foundItem;
}
this.AddServerToListIsShown = false;
mainScrollViewer.ScrollToBottom();
}
}
}
问题:
问题是,当手动添加服务器名称时,ScrollViewer 通常不会像应有的那样一直滚动到底部。根据控件的大小和列表中有多少服务器,它通常会在中间或底部的某个位置滚动(但不是一直滚动),如下所示:
为什么 ScrollViewer 不能一直滚动到底部???
【问题讨论】:
标签: c# wpf scrollviewer dispatcher