Pizza Xamarin

Vi piace l'immagine che correda questo articolo ??? E' una mia creazione ! Per far parlare Xamarin anche un pò italiano.... In realtà stavo studiando Xamarin e avevo voglia di una pizza....... così ho pensato di unire le due cose !

Quando si lavora con il pattern MVVM come noto occorre sempre lavorare con il Binding, ed è molto importante centellinare e ottimizzare la sottoscrizione agli eventi degli oggetti grafici utilizzati: inoltre è tassativo farlo usando sempre proprietà bindable e "tutto il mondo" offerto da ICommand.

Questo argomento è oggettivamente complesso e articolato: sicuramente scriverò qualcosa nei prossimi post. Trovo infatti che la documentazione che si trova in giro sia estremamente noiosa e prolissa su questo argomento: io invece penso che tutta questa parte sia interessante e stimolante, una volta capiti i meccanismi di base.

Quindi in definitiva torniamo all'oggetto di questo post: ovviare al fatto che la ListView non propone di default una proprietà bindable per gestire l'evento della selezione di un item.

Infatti l'oggettopropone un semplice evento, ma come detto quando si lavora con il pattern MVVM non è buona cosa sottoscriverlo direttamente e gestirlo in tal modo.

Qui esporrò uno dei metodi corretti per gestire "la cosa": una list view che espone una proprietà bindable di tipo ICommand (che espone l'evento item selezionato), e una ViewModel che espone anch'essa una proprietà di tale genere. Nel costruttore della pagina queste due proprietà vengono messe in contatto (bindate), e quindi alla selezione di un item verrà richiamato direttamente il metodo della ViewModel ! Più facile vedere il codice che spiegarlo in parole.

Per iniziare esponiamo nella sua bellezza il viewmodel.

public class ArticoliListaViewModel : INotifyPropertyChanged
{
	private List _ListaArticoli;

	public ArticoliListaViewModel()
	{
		_ListaArticoli = new List();
		_ListaArticoli.Clear();
		for (int i = 0; i < 1800; i++)
		{
			_ListaArticoli.Add(new Articolo()
			{
				CodArt = "Articolo" + i.ToString(),
				Descrizione = "Descrizione" + i.ToString()
			});
		}
	}

	public List ListaArticoli
	{
		get { return _ListaArticoli; }

		set
		{
			_ListaArticoli = value;
			OnPropertyChanged("ListaArticoli");
		}
	}

	public ICommand ItemSelezionatoCommand
	{
		get { return new Command(ItemSelezionato); }
	}

	async void ItemSelezionato(Articolo _articoloSelezionato)
	{
		System.Diagnostics.Debug.WriteLine(">>Item Selezionato - Tipo " + _articoloSelezionato.GetType().ToString());
		System.Diagnostics.Debug.WriteLine(">>Item Selezionato - Cod Art " + _articoloSelezionato.CodArt);

	}

	public event PropertyChangedEventHandler PropertyChanged;
	public void OnPropertyChanged(string propertyName)
	{
		if (this.PropertyChanged != null)
		{
			PropertyChangedEventArgs e = new PropertyChangedEventArgs(propertyName);
			this.PropertyChanged(this, e);
		}
	}
}

Nulla di esotico: la solita List che viene riempita nel costruttore, e quindi un proprietà di tipo ICommand che espone il command da chiamare quando si seleziona un articolo. Ecco la nostra versione della ListView che propone una proprietà bindabile a cui associare un Command che sarà richiamato quando si seleziona un item nella lista.

public class ListViewExt:ListView
{
	public ListViewExt()
	{
		ItemSelected += OnItemSelected;
	}

	public static BindableProperty ItemSelezionatoCommandProperty =
		BindableProperty.Create(nameof(ItemSelezionatoCommand),
		                        typeof(ICommand),
		                        typeof(ListViewExt),
		                        null);
	
	public ICommand ItemSelezionatoCommand
	{
		get { return (ICommand)GetValue(ItemSelezionatoCommandProperty); }
		set { SetValue(ItemSelezionatoCommandProperty, value); }
	}

	private void OnItemSelected(object sender, SelectedItemChangedEventArgs e)
	{
		var item = e.SelectedItem;
		if (item != null && ItemSelezionatoCommand != null
			&& ItemSelezionatoCommand.CanExecute(item))
		{
			ItemSelezionatoCommand.Execute(e.SelectedItem);
		}
		SelectedItem = null;
	}
}

Qui sopra nella definizione della ListView personalizzata è esposto il punto principale: in pratica sia crea la proprietà bindable di tipo ICommand, che poi viene gestita all'interno della classe stessa. All'interno della view per "mettere in comunicazione" il Command della ViewModel con la ViewList basta il seguente comando.

listView.SetBinding(ListViewExt.ItemSelezionatoCommandProperty, x=>x.ItemSelezionatoCommand, BindingMode.OneWay);

 Spero Vi sia stato utile !

Linkografia

GitHub Giampaolo Tucci