Search code examples
c#xamarin.formsandroid-sqlite

Is there a way to avoid duplicates in a picker


I'm creating an app for listing books that I own and want.. this app has a Sqlite Database. Each book has a row with columns ID, Author and Title. My issue is when i'm adding a new book I wanted to give this user the option to type in a new author name or get one from the picker. The picker ItemsSource is coming from the Authors column. My problem is because each author can have more then one book, the authors names are showing multiple times in the picker

Xaml

<StackLayout Orientation="Horizontal">
    <Entry x:Name="authorName" HorizontalOptions="FillAndExpand" Text="{Binding Author}"
       Keyboard="Text" 
       StyleClass="entry"/>

    <StackLayout>
        <Button x:Name="PickAuthor" Text="..." WidthRequest="40"
        Clicked="PickAuthor_Clicked"/>
    </StackLayout>

    <Picker x:Name="ExistingAuthors"
            Title="Select Author"
            IsVisible="False"
            SelectedIndexChanged="ExistingAuthors_SelectedIndexChanged">
        <Picker.ItemDisplayBinding>
            <Binding Path="Author" />
        </Picker.ItemDisplayBinding>
    </Picker>
</StackLayout>

Code Behind

protected override async void OnAppearing()
{
    await _connection.CreateTableAsync<WishList>();
    var book = await _connection.Table<WishList>().ToListAsync();
    _book = new ObservableCollection<WishList>(book);
    base.OnAppearing();
}

private void PickAuthor_Clicked(object sender, EventArgs e)
{
    ExistingAuthors.ItemsSource = _book.Distinct().ToList();
    ExistingAuthors.Focus();
}

private void ExistingAuthors_SelectedIndexChanged(object sender, EventArgs e)
{
    authorName.Text = ExistingAuthors.Items[ExistingAuthors.SelectedIndex];
}

I don't want the picker to displace duplicates.


Solution

  • To remove duplicates from a list you can use Linq. The method below groups the collection by the duplicate field and selects the first group.

    private void PickAuthor_Clicked(object sender, EventArgs e)
    {
        ExistingAuthors.ItemsSource = _book.GroupBy(b => b.Author)    // group by Author
                                           .Select(g => g.First())    // select first group
                                           .ToList();
        ExistingAuthors.Focus();
    }
    

    This will return a list of your entity type.