我一直在使用this example在xamarin中构建一个移动应用程序以与我的聊天机器人进行交互。我遇到的问题是,显示bot和用户之间的消息的ListView在其中显示新消息时不会自动滚动到底部。这是代码:
<ContentPage.Content>
<StackLayout Margin="5">
<ListView x:Name="ChatListView"
VerticalOptions="FillAndExpand"
SelectedItem="{Binding SelectedMessage}"
ItemsSource="{Binding BotMessages, Mode=TwoWay}"
BackgroundColor="Azure"
HasUnevenRows="True"
SeparatorVisibility="None"
ItemTemplate="{StaticResource ChatDataTemplateSelector}"/>
<StackLayout Orientation="Horizontal">
<Entry Placeholder="Ask a question.."
Margin="5"
Keyboard="Chat"
Text="{Binding CurrentMessage, Mode=TwoWay}"
HorizontalOptions="FillAndExpand"
Completed="Entry_Completed"/>
<Button Text="Send" Command="{Binding SendCommand}"/>
</StackLayout>
</StackLayout>
</ContentPage.Content>
是否有某种方法可以使收到新邮件时Listview自动滚动到底部?
答案 0 :(得分:1)
要滚动到某个项目,您要做的就是:
ChatListView.ScrollTo(item, ScrollToPosition.MakeVisible, true);
如果您想要一个列表,当与可观察的集合一起使用时将自动滚动到新的/更新的项目,则可以尝试使用此扩展名:
namespace Your.Namespace.For.Custom.Controls
{
public class AutoScrollListView : ListView
{
private INotifyCollectionChanged _previousObservableCollection;
public AutoScrollListView(ListViewCachingStrategy cachingStrategy)
: base(cachingStrategy)
{
}
public AutoScrollListView()
: base()
{
}
protected override void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
base.OnPropertyChanged(propertyName);
if (propertyName == nameof(ItemsSource))
{
if (_previousObservableCollection != null)
{
_previousObservableCollection.CollectionChanged -= OnItemsSourceCollectionChanged;
_previousObservableCollection = null;
}
if (ItemsSource is INotifyCollectionChanged newObservableCollection)
{
_previousObservableCollection = newObservableCollection;
newObservableCollection.CollectionChanged += OnItemsSourceCollectionChanged;
}
}
}
private void OnItemsSourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add || e.Action == NotifyCollectionChangedAction.Replace)
{
foreach (var item in e.NewItems)
{
// Scroll to the item that has just been added/updated to make it visible
ScrollTo(item, ScrollToPosition.MakeVisible, true);
}
}
}
}
}
要使用它,请记住将其命名空间添加到XAML文件中:
<Page
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:custom="clr-namespace:Your.Namespace.For.Custom.Controls"
x:Class="Your.Namespace.YourPage">
...
<ContentPage.Content>
<StackLayout Margin="5">
<custom:AutoScrollListView
x:Name="ChatListView"
VerticalOptions="FillAndExpand"
SelectedItem="{Binding SelectedMessage}"
ItemsSource="{Binding BotMessages, Mode=TwoWay}"
BackgroundColor="Azure"
HasUnevenRows="True"
SeparatorVisibility="None"
ItemTemplate="{StaticResource ChatDataTemplateSelector}" />
<StaLayout Orientation="Horizontal">
<Entry
Placeholder="Ask a question.."
Margin="5"
Keyboard="Chat"
Text="{Binding CurrentMessage, Mode=TwoWay}"
HorizontalOptions="FillAndExpand"
Completed="Entry_Completed"/>
<Button Text="Send" Command="{Binding SendCommand}" />
</StackLayout>
</StackLayout>
</ContentPage.Content>
...
</Page>
请记住,如上所述,仅当属性ItemsSource
绑定到可观察的集合时,此自定义列表才会自动滚动。
希望对您有帮助!