1

我使用 C# 和 XAML 为 Windows 8 制作了某种聊天应用程序。

对于聊天列表,我使用与 ObservableCollection 绑定的 ListView。对于我使用自定义控件的消息项,包含 RichTextBlock。

我想将 ListView 滚动到底部,以使新消息可见。我遇到的问题: ScrollIntoView方法不会使整个消息项可见,它仅使消息项的顶部可见。

所以,我也尝试了WinRT XAML Toolkit的解决方案:Get ListView's ScrollViewer and use ScrollViewer's methods

public static void ScrollToBottom(this ListView listView)
{
   var scrollViewer = listView.GetFirstDescendantOfType<ScrollViewer>();
   scrollViewer.ScrollToVerticalOffset(scrollViewer.ScrollableHeight);
}

public static void ScrollToBottom(this ListView listView)
{
   var scrollViewer = listView.GetFirstDescendantOfType<ScrollViewer>();
   scrollViewer.ScrollToVerticalOffset(scrollViewer.ExtentHeight);
}

具有相同的效果。某些消息项未完全滚动。

我还尝试在滚动之前进行延迟: new ManualResetEvent(false).WaitOne(2000);

我没有更多的想法如何制作可自动滚动的聊天列表。我怎么能做到这一点?

看来,什么 Windows 消息应用程序不使用 ListView (StackPanel??): Windows 聊天示例

使用 StackPanel 会更容易吗?

4

1 回答 1

1

我假设您的代码如下所示,您正在向 observablecollection 添加新的聊天消息

var newChatMsg = new ChatMsg("foo foo bar bar");
messageObservableColllection.Add(newChatMsg);

您需要做的就是将以下代码行添加到 Add() 之后

this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
            {
                listbox1.ScrollIntoView(newChatMsg);
            });

这将调用将 ListView 滚动到调度程序队列上最近添加的聊天消息,这将在 INofityProperty 触发并使用新消息更新 ListView 后的某个时间点触发。如果在添加或删除项目时需要运行任何动画,这很重要。

最后,如果项目没有完全滚动到视图中,您可能会遇到项目高度问题。ScrollIntoView 有一个替代项,可让您指定要对齐内容的框架边缘。如果您希望显示特定的子元素,您还可以手动指定额外的滚动量。有关详细信息,请参阅此 MSDN 论坛帖子:

http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/24e91a3e-6cd3-468b-97eb-c90f39532aba

于 2012-08-27T18:13:36.593 回答