Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Proposal] Add ItemsView Extensions #51

Closed
10 tasks done
brminnick opened this issue Apr 10, 2022 · 5 comments · Fixed by #53
Closed
10 tasks done

[Proposal] Add ItemsView Extensions #51

brminnick opened this issue Apr 10, 2022 · 5 comments · Fixed by #53
Assignees
Labels
approved champion A member of the .NET MAUI Toolkit core team has chosen to champion this feature documentation approved proposal A fully fleshed out proposal describing a new feature in syntactic and semantic detail

Comments

@brminnick
Copy link
Collaborator

brminnick commented Apr 10, 2022

Add ItemsView Extensions

Link to Discussion

#50

Summary

This PR adds fluent extension methods for ItemsView.

These extensions will work for both CarouselView and CollectionView, both of which inherit from ItemsView.

Motivation

To improve the developer workflow around initializing CollectionView and CarouselView

Detailed Design

using System.Collections;
using System.Windows.Input;
using Microsoft.Maui;
using Microsoft.Maui.Controls;

namespace CommunityToolkit.Maui.Markup;

/// <summary>
/// Fluent extension methods for <see cref="ItemsView"/>
/// </summary>
public static class ItemsViewExtensions
{
	/// <summary>
	/// Assigns the <see cref="ItemsView.EmptyView"/> property
	/// </summary>
	/// <typeparam name="TItemsView"></typeparam>
	/// <param name="itemsView"></param>
	/// <param name="view"></param>
	/// <returns>ItemsView with Empty View</returns>
	public static TItemsView EmptyView<TItemsView>(this TItemsView itemsView, object view) where TItemsView : ItemsView
	{
		itemsView.EmptyView = view;
		return itemsView;
	}

	/// <summary>
	/// Assigns the <see cref="ItemsView.EmptyViewTemplate"/> property
	/// </summary>
	/// <typeparam name="TItemsView"></typeparam>
	/// <param name="itemsView"></param>
	/// <param name="view"></param>
	/// <returns>ItemsView with Empty View Template</returns>
	public static TItemsView EmptyViewTemplate<TItemsView>(this TItemsView itemsView, DataTemplate view) where TItemsView : ItemsView
	{
		itemsView.EmptyViewTemplate = view;
		return itemsView;
	}

	/// <summary>
	/// Assigns the <see cref="ItemsView.ItemsSource"/> property
	/// </summary>
	/// <typeparam name="TItemsView"></typeparam>
	/// <param name="itemsView"></param>
	/// <param name="itemsSource"></param>
	/// <returns>ItemsView with ItemSource</returns>
	public static TItemsView ItemsSource<TItemsView>(this TItemsView itemsView, IEnumerable itemsSource) where TItemsView : ItemsView
	{
		itemsView.ItemsSource = itemsSource;
		return itemsView;
	}

	/// <summary>
	/// Assigns the <see cref="ItemsView.HorizontalScrollBarVisibility"/> property
	/// </summary>
	/// <typeparam name="TItemsView"></typeparam>
	/// <param name="itemsView"></param>
	/// <param name="visibility"></param>
	/// <returns>ItemsView with updated Horiztonal Scroll Bar Visibility</returns>
	public static TItemsView HorizontalScrollBarVisibility<TItemsView>(this TItemsView itemsView, ScrollBarVisibility visibility) where TItemsView : ItemsView
	{
		itemsView.HorizontalScrollBarVisibility = visibility;
		return itemsView;
	}

	/// <summary>
	/// Assigns the <see cref="ItemsView.VerticalScrollBarVisibility"/> property
	/// </summary>
	/// <typeparam name="TItemsView"></typeparam>
	/// <param name="itemsView"></param>
	/// <param name="visibility"></param>
	/// <returns>ItemsView with updated Vertical Scroll Bar Visibility</returns>
	public static TItemsView VerticalScrollBarVisibility<TItemsView>(this TItemsView itemsView, ScrollBarVisibility visibility) where TItemsView : ItemsView
	{
		itemsView.VerticalScrollBarVisibility = visibility;
		return itemsView;
	}

	/// <summary>
	/// Assigns the <see cref="ItemsView.VerticalScrollBarVisibility"/> and <see cref="ItemsView.HorizontalScrollBarVisibility"/> properties
	/// </summary>
	/// <typeparam name="TItemsView"></typeparam>
	/// <param name="itemsView"></param>
	/// <param name="visibility"></param>
	/// <returns>ItemsView with updated Horiztonal + Vertical Scroll Bar Visibility</returns>
	public static TItemsView ScrollBarVisibility<TItemsView>(this TItemsView itemsView, ScrollBarVisibility visibility) where TItemsView : ItemsView
	{
		return itemsView.HorizontalScrollBarVisibility(visibility).VerticalScrollBarVisibility(visibility);
	}

	/// <summary>
	/// Assigns the <see cref="ItemsView.RemainingItemsThreshold"/> property
	/// </summary>
	/// <typeparam name="TItemsView"></typeparam>
	/// <param name="itemsView"></param>
	/// <param name="threshold"></param>
	/// <returns>ItemsView with updated Remaining Items Threshold</returns>
	public static TItemsView RemainingItemsThreshold<TItemsView>(this TItemsView itemsView, int threshold) where TItemsView : ItemsView
	{
		itemsView.RemainingItemsThreshold = threshold;
		return itemsView;
	}

	/// <summary>
	/// Assigns the <see cref="ItemsView.RemainingItemsThresholdReachedCommand"/>  ans <see cref="ItemsView.RemainingItemsThresholdReachedCommandParameter"/>properties
	/// </summary>
	/// <typeparam name="TItemsView"></typeparam>
	/// <param name="itemsView"></param>
	/// <param name="command"></param>
	/// <param name="parameter"></param>
	/// <returns>ItemsView with updated Remaining Items Threshold Reached Command + CommandParameter</returns>
	public static TItemsView RemainingItemsThresholdReachedCommand<TItemsView>(this TItemsView itemsView, ICommand command, object? parameter) where TItemsView : ItemsView
	{
		return itemsView.RemainingItemsThresholdReachedCommand(command).RemainingItemsThresholdReachedCommandParameter(parameter);
	}

	/// <summary>
	/// Assigns the <see cref="ItemsView.RemainingItemsThresholdReachedCommand"/> property
	/// </summary>
	/// <typeparam name="TItemsView"></typeparam>
	/// <param name="itemsView"></param>
	/// <param name="command"></param>
	/// <returns>ItemsView with updated Remaining Items Threshold Reached Command</returns>
	public static TItemsView RemainingItemsThresholdReachedCommand<TItemsView>(this TItemsView itemsView, ICommand command) where TItemsView : ItemsView
	{
		itemsView.RemainingItemsThresholdReachedCommand = command;
		return itemsView;
	}

	/// <summary>
	/// Assigns the <see cref="ItemsView.RemainingItemsThresholdReachedCommandParameter"/> property
	/// </summary>
	/// <typeparam name="TItemsView"></typeparam>
	/// <param name="itemsView"></param>
	/// <param name="parameter"></param>
	/// <returns>ItemsView with updated Remaining Items Threshold Reached Command Parameter</returns>
	public static TItemsView RemainingItemsThresholdReachedCommandParameter<TItemsView>(this TItemsView itemsView, object? parameter) where TItemsView : ItemsView
	{
		itemsView.RemainingItemsThresholdReachedCommandParameter = parameter;
		return itemsView;
	}

	/// <summary>
	/// Assigns the <see cref="ItemsView.ItemTemplate"/> property
	/// </summary>
	/// <typeparam name="TItemsView"></typeparam>
	/// <param name="itemsView"></param>
	/// <param name="template"></param>
	/// <returns>ItemsView with updated Item Template</returns>
	public static TItemsView ItemTemplate<TItemsView>(this TItemsView itemsView, DataTemplate template) where TItemsView : ItemsView
	{
		itemsView.ItemTemplate = template;
		return itemsView;
	}

	/// <summary>
	/// Assigns the <see cref="ItemsView.ItemsUpdatingScrollMode"/> property
	/// </summary>
	/// <typeparam name="TItemsView"></typeparam>
	/// <param name="itemsView"></param>
	/// <param name="mode"></param>
	/// <returns>ItemsView with updated ItemsUpdatingScrollMode</returns>
	public static TItemsView ItemsUpdatingScrollMode<TItemsView>(this TItemsView itemsView, ItemsUpdatingScrollMode mode) where TItemsView : ItemsView
	{
		itemsView.ItemsUpdatingScrollMode = mode;
		return itemsView;
	}
}

Usage Syntax

C# Usage

Content = new CollectionView()
                  .ItemSource(new [] { "Hello", "World" })
                  .ItemTemplate(new DataTemplate(() => new Label().Bind(Label.TextProperty, "."));

Drawbacks

No known drawbacks

Alternatives

Currently, the properties need to be set using initializers, leading to a combination of properties + extension methods:

Content = new CollectionView
{
  ItemTemplate = new DataTemplate(() => new Label().Bind(Label.TextProperty, "."))
}.Bind(CollectionView.ItemSourceProperty, nameof(ViewModel.ItemSource));

Unresolved Questions

No known questions

@brminnick brminnick added proposal A fully fleshed out proposal describing a new feature in syntactic and semantic detail new labels Apr 10, 2022
@ghost ghost added this to Proposal Submitted in New Feature Proposals Apr 10, 2022
@brminnick brminnick moved this from Proposal Submitted to Proposal Championed in New Feature Proposals Apr 10, 2022
@brminnick brminnick self-assigned this Apr 10, 2022
@ghost ghost added champion A member of the .NET MAUI Toolkit core team has chosen to champion this feature pending documentation This feature requires documentation and removed new labels Apr 10, 2022
@VladislavAntonyuk
Copy link
Contributor

Approve.
Just a small question. Does EmptyView type is Object? can we set a more specific type like String or IView?

public static TItemsView EmptyView<TItemsView>(this TItemsView itemsView, string emptyViewContent) where TItemsView : ItemsView
	
public static TItemsView EmptyView<TItemsView>(this TItemsView itemsView, IView view) where TItemsView : ItemsView

@brminnick
Copy link
Collaborator Author

brminnick commented Apr 11, 2022

Thanks! Yea, I thought the same thing about EmptyView's type. But ItemsView.EmptyView is in fact object in .NET MAUI. I assumed it would be IView too.

@pictos
Copy link
Member

pictos commented Apr 12, 2022

I approve this feature ✅

@brminnick
Copy link
Collaborator Author

I also approve ✅

@brminnick brminnick moved this from Proposal Championed to Proposal Approved in New Feature Proposals Apr 12, 2022
@ghost ghost added approved help wanted This proposal has been approved and is ready to be implemented labels Apr 12, 2022
@brminnick brminnick removed the help wanted This proposal has been approved and is ready to be implemented label Apr 12, 2022
@brminnick brminnick mentioned this issue Apr 12, 2022
6 tasks
@brminnick brminnick moved this from Proposal Approved to Pull Request Approved (Pending Documentation) in New Feature Proposals Apr 13, 2022
@brminnick brminnick moved this from Pull Request Approved (Pending Documentation) to Documentation Approved in New Feature Proposals Apr 14, 2022
@ghost ghost added documentation approved and removed pending documentation This feature requires documentation labels Apr 14, 2022
@ghost ghost reopened this Apr 14, 2022
@ghost
Copy link

ghost commented Apr 14, 2022

Reopening Proposal.

Only Proposals moved to the Closed Project Column and Completed Project Column can be closed.

@brminnick brminnick moved this from Documentation Approved to Completed in New Feature Proposals Apr 15, 2022
@ghost ghost closed this as completed Apr 15, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved champion A member of the .NET MAUI Toolkit core team has chosen to champion this feature documentation approved proposal A fully fleshed out proposal describing a new feature in syntactic and semantic detail
Projects
Development

Successfully merging a pull request may close this issue.

3 participants