Skip to content

Latest commit

 

History

History
217 lines (181 loc) · 6.53 KB

autocomplete-tokens-mvvm.md

File metadata and controls

217 lines (181 loc) · 6.53 KB
title description type page_title slug tags res_type
Manage the Tokens Collection in .NET MAUI AutoComplete
Learn how to add and delete items from the AutoComplete's tokens collection.
how-to
How to Manage the Tokens collection of the RadAutoComplete for .NET MAUI in MVVM approach
autocomplete-tokens-collection-mvvm
autocomplete, .net maui, tokens, collection, mvvm
kb

Environment

Version Product Author
7.1.0 Telerik UI for .NET MAUI AutoComplete Dobrinka Yordanova

Description

This article explains how to manage the tokens collection of the AutoComplete in MVVM scenario.

Solution

The Tokens collection of the AutoComplete is a read-only collection:

public ObservableCollection<object> Tokens { get; }

To add or remove tokens using an MVVM setup, create a custom behavior.

1. Create a TokensBehavior class that inherits from Behavior<RadAutoComplete>:

public class TokensBehavior : Behavior<RadAutoComplete>
{
    public static readonly BindableProperty TokensProperty =
        BindableProperty.Create(nameof(Tokens), typeof(ObservableCollection<object>), typeof(TokensBehavior), null, propertyChanged: OnTokensPropertyChanged);

    private RadAutoComplete acv;

    public ObservableCollection<object> Tokens
    {
        get
        {
            return (ObservableCollection<object>)this.GetValue(TokensProperty);
        }
        set
        {
            this.SetValue(TokensProperty, value);
        }
    }
    protected override void OnAttachedTo(BindableObject bindable)
    {
        base.OnAttachedTo(bindable);
        this.acv = (RadAutoComplete)bindable;
    }

    protected override void OnDetachingFrom(BindableObject bindable)
    {
        base.OnDetachingFrom(bindable);
    }

    private static void OnTokensPropertyChanged(BindableObject bindable, object oldValue, object newValue)
    {
        var oldCollection = oldValue as INotifyCollectionChanged;
        if (oldCollection != null)
        {
            oldCollection.CollectionChanged -= ((TokensBehavior)bindable).Tokens_CollectionChanged;
        }

        var collection = newValue as INotifyCollectionChanged;
        if (collection != null)
        {
            ((TokensBehavior)bindable).UpdateTransfer(newValue);
            collection.CollectionChanged += ((TokensBehavior)bindable).Tokens_CollectionChanged;
        }
    }

    private void UpdateTransfer(object tokens)
    {
        Transfer((ObservableCollection<object>)tokens, this.acv.Tokens);
        this.acv.Tokens.CollectionChanged += Tokens_CollectionChanged1;
    }

    private void Tokens_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        this.UnsubscribeFromEvents();
        Transfer(this.Tokens, this.acv.Tokens);
        this.SubscribeToEvents();
    }

    private void Tokens_CollectionChanged1(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.Action == NotifyCollectionChangedAction.Add)
        {
            this.UnsubscribeFromEvents();
            Transfer(this.acv.Tokens, this.Tokens);
            this.SubscribeToEvents();
        }
    }

    private void SubscribeToEvents()
    {
        this.acv.Tokens.CollectionChanged += this.Tokens_CollectionChanged1;
        if (this.Tokens != null)
        {
            this.Tokens.CollectionChanged += this.Tokens_CollectionChanged;
        }
    }

    private void UnsubscribeFromEvents()
    {
        this.acv.Tokens.CollectionChanged -= this.Tokens_CollectionChanged1;
        if (this.Tokens != null)
        {
            this.Tokens.CollectionChanged -= this.Tokens_CollectionChanged;
        }
    }

    public static void Transfer(ObservableCollection<object> source, ObservableCollection<object> target)
    {
        if (source == null || target == null)
            return;

        target.Clear();
        foreach (var o in source)
        {
            target.Add(o);
        }
    }
}

2. Set the behavior to the AutoComplete control:

<VerticalStackLayout>
    <telerik:RadAutoComplete x:Name="autoCompleteView"
                                        ItemsSource="{Binding Source}"
                                        TextSearchPath="Name" 
                                        DisplayMode="Tokens">
        <telerik:RadAutoComplete.Behaviors>
            <local:TokensBehavior BindingContext="{Binding Source={x:Reference autoCompleteView}, Path=BindingContext}"
                                    Tokens="{Binding SelectedTokens}"/>
        </telerik:RadAutoComplete.Behaviors>
    </telerik:RadAutoComplete>
    <Button Text="Select Token" Command="{Binding SelectTokenCommand}"/>
    <Button Text="Remove Token" Command="{Binding RemoveTokenCommand}"/>
</VerticalStackLayout>

3. Add the telerik namespace:

xmlns:telerik="http://schemas.telerik.com/2022/xaml/maui"

4. Add a sample model:

public class Customer
{
    public Customer(string name, string email)
    {
        this.Name = name;
        this.Email = email;
    }
    public string Name { get; set; }
    public string Email { get; set; }
}

5. Add the ViewModel:

public class ViewModel
{
    public ObservableCollection<Customer> Source { get; set; }
    public ViewModel()
    {
        this.Source = new ObservableCollection<Customer>()
            {
                new Customer("Freda Curtis", "[email protected]"),
                new Customer("Jeffery Francis", "[email protected]"),
                new Customer("Eva Lawson", "[email protected]"),
                new Customer("Emmett Santos", "[email protected]"),
                new Customer("Theresa Bryan", "[email protected]"),
                new Customer("Jenny Fuller", "[email protected]"),
                new Customer("Terrell Norris", "[email protected]"),
            };

        this.SelectTokenCommand = new Command(OnSelectTokenCommandExecuted);
        this.RemoveTokenCommand = new Command(OnRemoveTokenCommandExecuted);

        this.SelectedTokens = new ObservableCollection<object>();
    }

    public ICommand SelectTokenCommand { get; set; }
    public ICommand RemoveTokenCommand { get; set; }

    public ObservableCollection<object> SelectedTokens { get; set; }

    private void OnSelectTokenCommandExecuted(object obj)
    {
        this.SelectedTokens.Add(this.Source[0]);
    }

    private void OnRemoveTokenCommandExecuted(object obj)
    {
        var item = this.SelectedTokens.FirstOrDefault();
        if (item != null)
        {
            this.SelectedTokens.Remove(item);
        }
    }
}