Jeppe Christensen
Jeppe Christensen

Reputation: 1890

Observablecollection from interface add to listview via binding

I have an application that draws use of Xabre.ble plugin.

When the application scans for devices, once a device is discovered the application appends it to an ObservableCollection which derives from an interface.

I have made a Data template in Xaml that i wish to populate, but for some reason i can't seem to get the BindingContext right.

Basically, what I want to achieve, is to add device objects to my ObservableCollection IDevice, and fetch just the name of the individual devices in the bindingcontext for the user to see in the listview

Xaml:

<ListView x:Name="deviceList">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/> 
                        <ColumnDefinition Width="Auto"/>
                   </Grid.ColumnDefinitions>
                   <local:IconView Grid.Row="0" Grid.Column="0" Source="BLE.png" Foreground="#3b5998" WidthRequest="30" HeightRequest="30"/>
                   <Label Grid.Row="1" Text="{Binding DeviceName}" TextColor="Teal"/>
                </Grid>
            </ViewCell>
        </DataTemplate> 
    </ListView.ItemTemplate>
</ListView>

Cs:

public ObservableCollection<IDevice> Devices { get; set; }
IAdapter adapter = CrossBluetoothLE.Current.Adapter;
public ObservableCollection<string> DeviceName { get; set; }

public MainPage()
{
    //Instantiate observable collection
    Devices = new ObservableCollection<IDevice>();
    DeviceName = new ObservableCollection<string>();

    //Appending peripherals to list
    BindingContext = DeviceName;
    deviceList.ItemsSource = BindingContext;
    Content = deviceList;
    Refreshcmd();
}
public void Refreshcmd()
{
//DeviceDiscovered is an event, when it discovers a device, we fire the eventhandler
    adapter.DeviceDiscovered += (s, a) =>
    {
        if (a.Device.Name != null)
        {
            Devices.Add(a.Device);               
            DeviceName.Add(a.Device.Name);
        }
    };
    adapter.StartScanningForDevicesAsync();
}

As you can see, I have tried to make an object which contains a string with just the name of the IDevice. However, it doesn't append to my databinding DeviceName.

Furthermore, I don't really like this solution, as I would much rather be able to access the Devices.Name from the interface, but that is not allowed apparently. - the reason why I would much rather like that solution is that the user eventually will have to connect to a device from the list, meaning that it is much easier to have one object for all the "behind the scenes" details.

Upvotes: 0

Views: 829

Answers (1)

Bruno Caceiro
Bruno Caceiro

Reputation: 7199

You should refactor your code, to a MVVM approach.

namespace YourNameSpace.ViewModels
{
    public class YourViewModel
    {

        private ObservableCollection<IDevice> devices;
        public ObservableCollection<IDevice> Devices
        {
            get { return devices; }
            set
            {
                devices = value;
            }
        }
        public YourViewModel()
        {
            Devices = new ObservableCollection<IDevice>();
        }
    }
}

In your Page.xaml.cs

public partial class YourPage : ContentPage
    {
        public YourPage()
        {
            InitializeComponent();
            BindingContext = new YourViewModel();
        }
    }

    public void Refreshcmd()
{
//DeviceDiscovered is an event, when it discovers a device, we fire the eventhandler
    adapter.DeviceDiscovered += (s, a) =>
    {
        if (a.Device.Name != null)
        {
            (YourViewModel)Devices.Add(a.Device);               
            //DeviceName.Add(a.Device.Name);
        }
    };
    adapter.StartScanningForDevicesAsync();
}

Then in Page.xaml

 <ListView ItemsSource="{Binding Devices}"
              CachingStrategy="RecycleElement">

Upvotes: 2

Related Questions