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

Support DataTemplateSelectors for CollectionView #114

Merged
merged 3 commits into from
Mar 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions samples/ControlGallery/AppShell.razor
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
<GridLayoutPage />
<SelectionPage />
<InfiniteScrollPage />
<DynamicItemsPage />
</ShellSection>
<PickerPage />
<TableViewPage />
Expand Down Expand Up @@ -84,8 +85,8 @@
</Shell>

@code {
Color _backgroundColor;
Color _foregroundColor;
Color _unselectedColor;
Color _tabBarTitleColor;
Color _backgroundColor;
Color _foregroundColor;
Color _unselectedColor;
Color _tabBarTitleColor;
}
4 changes: 4 additions & 0 deletions samples/ControlGallery/ControlGallery.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@
<MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="UraniumUI.Icons.FontAwesome" Version="2.3.1" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\BlazorBindings.Maui.SkiaSharp\BlazorBindings.Maui.SkiaSharp.csproj" />
<ProjectReference Include="..\..\src\BlazorBindings.Maui\BlazorBindings.Maui.csproj" />
Expand Down
4 changes: 4 additions & 0 deletions samples/ControlGallery/MauiProgram.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using BlazorBindings.Maui;
using SkiaSharp.Views.Maui.Controls.Hosting;
using UraniumUI;

namespace ControlGallery;

Expand All @@ -18,8 +19,11 @@ public static MauiApp CreateMauiApp()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFontAwesomeIconFonts();
});

builder.Services.AddSingleton<IMediaPicker>(MediaPicker.Default);

return builder.Build();
}
}
Expand Down
5 changes: 4 additions & 1 deletion samples/ControlGallery/Platforms/Android/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true"></application>
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:supportsRtl="true"></application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Border BackgroundColor="Colors.LightBlue"
Margin="8"
Padding="8"
CornerRadius="4">

<Image Source="Item.ImageSource" MaximumHeightRequest="400" />

</Border>

@code {
[Parameter] public ImageItemModel Item { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
namespace ControlGallery.Views.Collections.CollectionView.DynamicItems;

public record ItemModel;
public record TextItemModel(string Text) : ItemModel;
public record ImageItemModel(ImageSource ImageSource) : ItemModel;

public static class Items
{
public static ItemModel[] GetItems()
{
var items = new ItemModel[] {
new ImageItemModel("https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885_960_720.jpg"),
new TextItemModel(".NET Multi-platform App UI (.NET MAUI) is a cross-platform framework for creating mobile and desktop apps with C# and XAML. Using .NET MAUI, you can develop apps that can run on Android, iOS, iPadOS, macOS, and Windows from a single shared codebase."),
new ImageItemModel("https://cdn.pixabay.com/photo/2014/02/27/16/10/flowers-276014_960_720.jpg"),
new TextItemModel("ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux."),
new ImageItemModel("https://cdn.pixabay.com/photo/2015/06/19/21/24/avenue-815297_960_720.jpg"),
new ImageItemModel("https://cdn.pixabay.com/photo/2013/10/02/23/03/mountains-190055_960_720.jpg"),
new TextItemModel(".NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps."),
new TextItemModel("Visual Studio Code is a code editor redefined and optimized for building and debugging modern web and cloud applications. ")
};

var repeatedItems = Enumerable.Repeat(items, 100).SelectMany(i => i).ToArray();

return repeatedItems;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Border BackgroundColor="Colors.LightBlue"
Margin="8"
Padding="8"
CornerRadius="4">

<Label Text="@Item.Text" />

</Border>

@code {
[Parameter] public TextItemModel Item { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
@using System.Collections.ObjectModel;
@using ControlGallery.Views.Collections.CollectionView.DynamicItems;
@using ControlGallery.Views.Shared
@using UraniumUI.Icons.FontAwesome;

<ContentPage Title="Dynamic">
<Grid RowDefinitions="Auto, *">
<Grid Grid.Row="0" ColumnDefinitions="*,Auto,Auto" ColumnSpacing="6" Margin="6">

<Entry Grid.Column="0" @bind-Text="enteredText"
Placeholder="Type something"
OnCompleted="AddText" />

<FAIcon Grid.Column="1" Glyph="@Solid.Camera" OnTap="CapturePhoto" Color="Colors.LightBlue" />
<FAIcon Grid.Column="2" Glyph="@Solid.Images" OnTap="SelectPhoto" Color="Colors.LightBlue" />

</Grid>

<CollectionView Grid.Row="1" ItemsSource="items">

<ItemTemplateSelector>
@if (context is TextItemModel text)
{
<TextItem Item="text" />
}
else if (context is ImageItemModel image)
{
<ImageItem Item="image" />
}
</ItemTemplateSelector>

</CollectionView>
</Grid>
</ContentPage>

@code {
[Inject] private IMediaPicker MediaPicker { get; set; }

ObservableCollection<ItemModel> items = new(Items.GetItems());
string enteredText;

async Task SelectPhoto()
{
var photo = await MediaPicker.PickPhotoAsync();

if (photo != null)
items.Insert(0, new ImageItemModel(ImageSource.FromFile(photo.FullPath)));
}

async Task CapturePhoto()
{
var photo = await MediaPicker.CapturePhotoAsync();

if (photo != null)
items.Insert(0, new ImageItemModel(ImageSource.FromFile(photo.FullPath)));
}

void AddText()
{
items.Insert(0, new TextItemModel(enteredText));
enteredText = "";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,18 @@
ObservableCollection<int> _intItems = new(Enumerable.Range(1, 20));
bool _loading;

async Task RefreshItems()
{
async Task RefreshItems() {
await Task.Delay(1000);
_intItems = new(Enumerable.Range(_intItems.Min() + 5, 20));
}

async Task LoadItems()
{
if (!_loading)
{
async Task LoadItems() {
if (!_loading) {
_loading = true;

await Task.Delay(1000);

foreach (var item in Enumerable.Range(_intItems.Max() + 1, 20))
{
foreach (var item in Enumerable.Range(_intItems.Max() + 1, 20)) {
_intItems.Add(item);
}

Expand Down
25 changes: 25 additions & 0 deletions samples/ControlGallery/Views/Shared/FAIcon.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
@using UraniumUI.Icons.FontAwesome;
<Image Source="fontImageSource" OnTap="OnTap" @attributes="Attributes" />

@code {
[Parameter] public Color Color { get; set; }
[Parameter] public double? Size { get; set; }
[Parameter] public string Glyph { get; set; }
[Parameter] public EventCallback<TappedEventArgs> OnTap { get; set; }

[Parameter(CaptureUnmatchedValues = true)]
public Dictionary<string, object> Attributes { get; set; }

FontImageSource fontImageSource = new() { FontFamily = "FASolid" };

protected override void OnParametersSet()
{
fontImageSource.Glyph = Glyph;

if (Color != null)
fontImageSource.Color = Color;

if (Size != null)
fontImageSource.Size = Size.Value;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ protected override RenderFragment GetChildContent()
{
foreach (var itemRoot in _itemRoots)
{
builder.OpenComponent<InitializedVerticalStackLayout>(1);
builder.OpenComponent<InitializedContentView>(1);

builder.AddAttribute(2, nameof(InitializedVerticalStackLayout.NativeControl), itemRoot);
builder.AddAttribute(2, nameof(InitializedContentView.NativeControl), itemRoot);
builder.AddAttribute(3, "ChildContent", (RenderFragment)(builder =>
{
Template.Invoke(builder);
Expand All @@ -35,11 +35,11 @@ protected override RenderFragment GetChildContent()
[Parameter] public Action<T, MC.DataTemplate> SetDataTemplateAction { get; set; }
[Parameter] public RenderFragment Template { get; set; }

private readonly List<MC.VerticalStackLayout> _itemRoots = new();
private readonly List<MC.ContentView> _itemRoots = new();

private MC.View AddTemplateRoot()
{
var templateRoot = new MC.VerticalStackLayout();
var templateRoot = new MC.ContentView();
_itemRoots.Add(templateRoot);
StateHasChanged();

Expand Down Expand Up @@ -67,7 +67,7 @@ void INonPhysicalChild.RemoveFromParent(object parentElement) { }
void IElementHandler.ApplyAttribute(ulong attributeEventHandlerId, string attributeName, object attributeValue, string attributeEventUpdatesAttributeName) { }
void IMauiContainerElementHandler.AddChild(MC.BindableObject child, int physicalSiblingIndex) { }
void IMauiContainerElementHandler.RemoveChild(MC.BindableObject child) { }
int IMauiContainerElementHandler.GetChildIndex(MC.BindableObject child) => _itemRoots.IndexOf((MC.VerticalStackLayout)child);
int IMauiContainerElementHandler.GetChildIndex(MC.BindableObject child) => _itemRoots.IndexOf((MC.ContentView)child);
MC.BindableObject IMauiElementHandler.ElementControl => null;
object IElementHandler.TargetElement => null;
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ protected override RenderFragment GetChildContent() => builder =>
{
foreach (var itemRoot in _itemRoots)
{
builder.OpenComponent<InitializedVerticalStackLayout>(1);
builder.OpenComponent<InitializedContentView>(1);

builder.AddAttribute(2, nameof(InitializedVerticalStackLayout.NativeControl), itemRoot);
builder.AddAttribute(2, nameof(InitializedContentView.NativeControl), itemRoot);
builder.AddAttribute(3, "ChildContent", (RenderFragment)(builder =>
{
builder.OpenComponent<DataTemplateItemComponent<TItem>>(4);
Expand All @@ -31,11 +31,11 @@ protected override RenderFragment GetChildContent() => builder =>
[Parameter] public Action<TControl, MC.DataTemplate> SetDataTemplateAction { get; set; }
[Parameter] public RenderFragment<TItem> Template { get; set; }

private readonly List<MC.VerticalStackLayout> _itemRoots = new();
private readonly List<MC.ContentView> _itemRoots = new();

public MC.View AddTemplateRoot()
{
var templateRoot = new MC.VerticalStackLayout();
var templateRoot = new MC.ContentView();
_itemRoots.Add(templateRoot);
StateHasChanged();
return templateRoot;
Expand All @@ -54,6 +54,6 @@ void INonPhysicalChild.RemoveFromParent(object parentElement) { }
object IElementHandler.TargetElement => null;
void IMauiContainerElementHandler.AddChild(MC.BindableObject child, int physicalSiblingIndex) { }
void IMauiContainerElementHandler.RemoveChild(MC.BindableObject child) { }
int IMauiContainerElementHandler.GetChildIndex(MC.BindableObject child) => _itemRoots.IndexOf((MC.VerticalStackLayout)child);
int IMauiContainerElementHandler.GetChildIndex(MC.BindableObject child) => _itemRoots.IndexOf((MC.ContentView)child);
void IElementHandler.ApplyAttribute(ulong attributeEventHandlerId, string attributeName, object attributeValue, string attributeEventUpdatesAttributeName) { }
}
Loading