How to update list of online users

granicusgranicus Member ✭✭

Heyo, newbie to Xamarin.Forms, and among all my searching I cannot seem to find an answer to this (seemingly) simple question... How do I show a list of online users of my service, and update that list as users log on and off? The scenario I am trying to accomplish is that the user is sitting on the page that shows the list of users currently online, and I would like to see this binding updated dynamically as other users log on and off (i.e., the user sees names being added to and removed from the page).

For the details of my implementation...

When my user logs into my app, a signalR connection is made which passes back a list of other users who are online. This list is stored as a static variable that is defined in App.xaml.cs and is used to populate an ObservableCollection called UsersOnlineList that is then bound to my ListView.

ChatUser.cs

    public class ChatUser
    {
        public int UserId {get; set;}
        public string UserName { get; set; }

        public ChatUser()
        {

        }
    }

App.xaml.cs

public static List<ChatUser> ConnectedUsers { get; set; }

GroupedList.cs

    public class GroupedList: List<ChatUser>
    {
        public string GroupHeader { get; set; }
        public List<ChatUser> Users => this;
    }

UsersOnlineViewModel.cs

        public ObservableCollection<GroupedList> UsersOnlineList { get; set; }

UsersOnlinePage.xaml

<ContentPage.Content>
        <StackLayout>
            <ListView x:Name="MyListView" 
                ItemsSource="{Binding UsersOnlineList}"
                      IsGroupingEnabled="True"
                VerticalOptions="FillAndExpand"
                 HasUnevenRows="true"
                      RefreshCommand="{Binding LoadUsersCommand}"
                      IsPullToRefreshEnabled="true"
                      IsRefreshing="{Binding IsBusy, Mode=TwoWay}"
                 CachingStrategy="RecycleElement"
                 ItemSelected="OnItemSelected">
                <ListView.GroupHeaderTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <Label Text="{Binding GroupHeader}" />
                        </ViewCell>
                    </DataTemplate>
                </ListView.GroupHeaderTemplate>
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <StackLayout Padding="10">
                                <Label Text="{Binding UserName}" 
                       LineBreakMode="NoWrap" 
                       Style="{DynamicResource ListItemTextStyle}" 
                       FontSize="16" />
                            </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </StackLayout>
    </ContentPage.Content>

FYI, the reason I am going from the "global" App.ConnectedUsers List to the ObservableCollection is so that I can define a heading for grouping purpose, as well as do a little re-organization of the list of online users before it is displayed in the app.

If another user logs on or off, a signalR call will be sent to all connected clients denoting the user that logged on or off.

HubManager.cs

            AppHubProxy.On<ChatUser>("onUserDisconnected", (cu) =>
            {
                int cuIdx = App.ConnectedUsers.FindIndex(obj => obj.UserId == cu.UserId);
                if (cuIdx > -1)
                {
                    App.ConnectedUsers.RemoveAt(cuIdx);
                }
            });

What I am missing is how do I go from the onUserDisconnected callback occurring to updating the UsersOnlineList that binds to the ListView?

As a newbie, I am 100% open to different implementations that accomplish what I am trying to do more efficiently

Thank you in advance!

Answers

  • AnubhavRanjanAnubhavRanjan INXamarin Team Xamurai
    edited April 25

    @granicus I guess all you have to do is have a setter for App.ConnectedUsers which when invoked would just invoke the setter for UsersOnlineList, thereby updating the List in the View.

    I am not sure of your entire implementation, but you can definitely try it out.
    Now in order to achieve this, I would highly recommend making use of MessagingCenter.
    https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/messaging-center

    With the help of this, all you have to do is Send a message to the ViewModel which hold the UsersOnlineList subscribing to the AppPage for Messages. Once done, all the ViewModel has to do is, reassign the Users from App.ConnectedUsers to UsersOnlineList.

    Just an ordinary approach, probably you can make it better.
    Pardon me, if there are any syntactical errors, have just typed it in here, showing the approach :smile:

    public class App
    {
        private static List<ChatUser> connectedUsers;
        public static List<ChatUser> ConnectedUsers { 
        get {
            if(connectedUsers == null)
                connectedUsers = new List<ChatUser>();
            return connectedUsers;
        } 
        set {
            MessagingCenter.Send<App> (this, "UsersUpdated");   
        } 
    }
    

    .

    .

    .



    Looking for Free* Microsoft Support on Xamarin Issues, visit https://aka.ms/xamarinsupport


Sign In or Register to comment.