using System; using System.Collections.Specialized; using System.Reactive.Disposables; using System.Reactive.Linq; using Avalonia.Controls; using Avalonia.Markup.Xaml; using AuroraDesk.Presentation.ViewModels.Pages; using ReactiveUI; using ReactiveUI.Avalonia; namespace AuroraDesk.Presentation.Views.Pages; public partial class UdpClientPageView : ReactiveUserControl { private ListBox? _receivedMessagesListBox; public UdpClientPageView() { InitializeComponent(); this.WhenActivated(disposables => { _receivedMessagesListBox ??= this.FindControl("ReceivedMessagesListBox"); if (_receivedMessagesListBox is null) { return; } _receivedMessagesListBox.SelectedIndex = -1; IDisposable? messagesSubscription = null; IDisposable? autoScrollSubscription = null; var viewModelSubscription = this.WhenAnyValue(x => x.ViewModel) .Subscribe(vm => { messagesSubscription?.Dispose(); autoScrollSubscription?.Dispose(); if (vm is null) { return; } var currentVm = vm; NotifyCollectionChangedEventHandler handler = (_, __) => { if (currentVm.IsAutoScrollToBottom) { ScrollToBottom(); } }; currentVm.ReceivedMessages.CollectionChanged += handler; messagesSubscription = Disposable.Create(() => { currentVm.ReceivedMessages.CollectionChanged -= handler; }); autoScrollSubscription = currentVm.WhenAnyValue(x => x.IsAutoScrollToBottom) .Subscribe(isEnabled => { if (isEnabled) { ScrollToBottom(); } }); if (currentVm.IsAutoScrollToBottom) { ScrollToBottom(); } }) ; disposables.Add(viewModelSubscription); disposables.Add(Disposable.Create(() => { messagesSubscription?.Dispose(); autoScrollSubscription?.Dispose(); })); }); } private void InitializeComponent() { AvaloniaXamlLoader.Load(this); } private void ScrollToBottom() { if (_receivedMessagesListBox is null) { return; } var messages = ViewModel?.ReceivedMessages; if (messages is null || messages.Count == 0) { return; } var lastItem = messages[messages.Count - 1]; _receivedMessagesListBox.ScrollIntoView(lastItem); _receivedMessagesListBox.SelectedIndex = -1; } }