Data Binding issue

sebastienhengysebastienhengy USMember ✭✭
edited October 2018 in Xamarin.Forms

Dear all,
I am stucked with a data binding problem.
In my project, a simple TCP connnection checker, I create a TCPListener that handles connection of other devices.
Now what I want to do is adding the connected devices information into a ListView

The Model contains the AsynchronousSocketListener class which handles correctly the connections.
The ViewModel contains a list of TCPConnectedDevices and generates associated propertychange events.
The View (TCPPage class) creates the AsynchronousSocketListener, and a timer checks every second the list of TCPConnectedDevices updated in the Model.

When creating the Model, I insert some "test" connectedDevices into the list, this works fine, the devices are shown on the view.

Nevertheless, when a new connection occurs, the new list elements generated in the AcceptCallback are not shown.

One strange thing is that the PropertyChanged is raised in the viewmodel, and when setting breakpoints in the code (when the timer calls checkForConnectedDevices), I can see that the tcpViewModel.ConnectedDevices has 6 elements (the 5 "test" items that are shown on the view, and the new device that is not shown on the view)

Do you have an idea of what I do wrong?
Thanks in advance.
By the way, the test is done on an android device

The code follows ....

Code in the Model :

    private List<TCPConnectedItem> connectedItems = new List<TCPConnectedItem>();

    public AsynchronousSocketListener()
        {
            for (int k=0;k<5;k++)
            { 
        // "test" connectedDevices
                TCPConnectedItem tmpItem = new TCPConnectedItem();
                tmpItem.IPAdress = "127.0.0." + k.ToString();
                tmpItem.MACAdress = "MAC 1";// 127.0.0.1";
                tmpItem.color = Color.Green;
                connectedItems.Add(tmpItem);//*/
            }
        }

    public List<TCPConnectedItem> getConnectedDevices()
        {
            return connectedItems;
        }

        public void AcceptCallback(IAsyncResult ar)
        {   
        //Accepts connections and updates the model's list of connected devices 

        // Update the list: 

                TCPConnectedItem newItem = new TCPConnectedItem();
                newItem.IPAdress = listener.LocalEndPoint.ToString();
                newItem.MACAdress = listener.LocalEndPoint.ToString();
                newItem.color = Color.Green;

                connectedItems.Add(newItem);
        }

Code in the View:

    public TCPPage()
        {
                InitializeComponent();

           tcpViewModel = new TCPViewModel();

            // Set binding context:
                BindingContext = tcpViewModel;

                myIP = App.IP;

                tcpViewModel.MyIP = App.IP;             // This works fine

                // Start server socket for listening to entering connections
                myAsyncSocketListener = new AsynchronousSocketListener();

                Thread listenerThread = new Thread(new ThreadStart(myAsyncSocketListener.StartListening));

                listenerThread.Start();

                //Timer
                Device.StartTimer(TimeSpan.FromSeconds(1), () =>
                {
                if (myAsyncSocketListener!=null)
                    { checkForConnectedDevices(); }


                    return true;
        });
        }

        private void checkForConnectedDevices()
        {
                List<TCPConnectedItem> updatedList= myAsyncSocketListener.getConnectedDevices();
                tcpViewModel.ConnectedDevices = updatedList;
        }

Code in the viewmodel:

    public class TCPViewModel : INotifyPropertyChanged
    {

         public TCPViewModel()
         {
                ConnectedDevices = new List<TCPConnectedItem>();
         }

        public event PropertyChangedEventHandler PropertyChanged;


        private List<TCPConnectedItem> connectedDevices;
        public List<TCPConnectedItem> ConnectedDevices
        {
                get { return connectedDevices; }
                    set { connectedDevices = value; RaisePropertyChanged(); }
         }

        protected virtual void RaisePropertyChanged([CallerMemberName] string caller = "")
        {
                if (PropertyChanged!=null)
                {
                // Call the change
                PropertyChanged(this, new PropertyChangedEventArgs(caller));
                }
        }
    }   

Xaml code:

    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="TCP.Views.TCPPage">


        <ContentPage.Content>
            <StackLayout Orientation="Vertical">

                <ListView x:Name="lv" ItemsSource="{Binding ConnectedDevices}"><!--IsVisible="{Binding IsWiFiEnabled}">-->
                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <ViewCell>
                                <StackLayout Orientation="Horizontal">
                                    <BoxView Color="{Binding color}" HeightRequest="40" WidthRequest="40"></BoxView>
                                    <Label Text="{Binding Name}" ></Label>
                                    <Label Text="{Binding IPAdress}" HorizontalOptions="EndAndExpand"></Label>
                                    <Label Text="{Binding MACAdress}" HorizontalOptions="EndAndExpand"></Label>
                                </StackLayout>
                            </ViewCell>
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>
            </StackLayout>
        </ContentPage.Content>
    </ContentPage>
Tagged:

Posts

Sign In or Register to comment.