Skip to content

Commit 1ea488c

Browse files
VladislavAntonyukTheCodeTravelerpictos
authored
Expander (#478)
* Expander initial commit Add samples Fix BindingContext is null Android Expander iOS Configure Header Do not arrange content on expanded change More samples, fix Android InvalidateMeasure, add animation Animation Android. fix WIndows build Update sample Fix PR comments Fix Apple animation Fix pipeline Expander tests Summary * Add Command and CommandParameter * Detect cell and force update size * Expander2 * Register Expander page * Remove Expander Handler * Fix formatting * Remove animation * Use StackLayout instead of Grid because it wraps content * Add docs * Update samples * Fix Expander content is not wrapped * Fix tests * listview resize * Fix formatting * Remove incorrect namespace * Update Sample, Use Static Methods * Update ExpanderPageCS.cs * Ensure Command Fires * Remove Children Before Creating New Grid * Add `InvalidEnumArgumentException` Test * Avoid Re-initializing Grid * Fixes Expander crash when Header or Content is null * Add `Title` * Disable `ListView` + `CollectionView` support Co-authored-by: Brandon Minnick <[email protected]> Co-authored-by: Pedro Jesus <[email protected]>
1 parent cda2fbe commit 1ea488c

File tree

14 files changed

+558
-5
lines changed

14 files changed

+558
-5
lines changed

samples/CommunityToolkit.Maui.Sample/AppShell.xaml.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ public partial class AppShell : Shell
102102
CreateViewModelMapping<AvatarViewShapesPage, AvatarViewShapesViewModel, ViewsGalleryPage, ViewsGalleryViewModel>(),
103103
CreateViewModelMapping<AvatarViewSizesPage, AvatarViewSizesViewModel, ViewsGalleryPage, ViewsGalleryViewModel>(),
104104
CreateViewModelMapping<DrawingViewPage, DrawingViewViewModel, ViewsGalleryPage, ViewsGalleryViewModel>(),
105+
CreateViewModelMapping<ExpanderPage, ExpanderViewModel, ViewsGalleryPage, ViewsGalleryViewModel>(),
105106
CreateViewModelMapping<MultiplePopupPage, MultiplePopupViewModel, ViewsGalleryPage, ViewsGalleryViewModel>(),
106107
CreateViewModelMapping<PopupAnchorPage, PopupAnchorViewModel, ViewsGalleryPage, ViewsGalleryViewModel>(),
107108
CreateViewModelMapping<PopupPositionPage, PopupPositionViewModel, ViewsGalleryPage, ViewsGalleryViewModel>(),

samples/CommunityToolkit.Maui.Sample/CommunityToolkit.Maui.Sample.csproj

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
44
<TargetFrameworks>net6.0-ios;net6.0-android;net6.0-maccatalyst</TargetFrameworks>
@@ -60,8 +60,15 @@
6060
<ProjectReference Include="..\..\src\CommunityToolkit.Maui.Analyzers.CodeFixes\CommunityToolkit.Maui.Analyzers.CodeFixes.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
6161
</ItemGroup>
6262

63-
<PropertyGroup Condition="$(TargetFramework.Contains('-android'))">
63+
<PropertyGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)'))=='android'">
6464
<RuntimeIdentifiers>android-arm;android-arm64;android-x86;android-x64</RuntimeIdentifiers>
6565
</PropertyGroup>
6666

67+
<PropertyGroup Condition="$([MSBuild]::IsOSPlatform('windows'))=='false' and $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)'))=='maccatalyst' and $(Configuration) == 'Debug'">
68+
<RuntimeIdentifiers>maccatalyst-arm64;maccatalyst-x64</RuntimeIdentifiers>
69+
</PropertyGroup>
70+
71+
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net6.0-ios|AnyCPU'">
72+
<CreatePackage>false</CreatePackage>
73+
</PropertyGroup>
6774
</Project>

samples/CommunityToolkit.Maui.Sample/MauiProgram.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ static void RegisterViewsAndViewModels(in IServiceCollection services)
137137
// Add Extensions Pages + ViewModels
138138
services.AddTransientWithShellRoute<ColorAnimationExtensionsPage, ColorAnimationExtensionsViewModel>();
139139

140-
// Add ImageSources pages + ViewModels
140+
// Add ImageSources Pages + ViewModels
141141
services.AddTransientWithShellRoute<GravatarImageSourcePage, GravatarImageSourceViewModel>();
142142

143143
// Add Layouts Pages + ViewModels
@@ -147,6 +147,7 @@ static void RegisterViewsAndViewModels(in IServiceCollection services)
147147

148148
// Add Views Pages + ViewModels
149149
services.AddTransientWithShellRoute<DrawingViewPage, DrawingViewViewModel>();
150+
services.AddTransientWithShellRoute<ExpanderPage, ExpanderViewModel>();
150151
services.AddTransientWithShellRoute<MultiplePopupPage, MultiplePopupViewModel>();
151152
services.AddTransientWithShellRoute<PopupAnchorPage, PopupAnchorViewModel>();
152153
services.AddTransientWithShellRoute<PopupPositionPage, PopupPositionViewModel>();
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<pages:BasePage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
4+
xmlns:mct="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
5+
x:Class="CommunityToolkit.Maui.Sample.Pages.Views.ExpanderPage"
6+
xmlns:pages="clr-namespace:CommunityToolkit.Maui.Sample.Pages"
7+
xmlns:viewModels="clr-namespace:CommunityToolkit.Maui.Sample.ViewModels.Views"
8+
x:TypeArguments="viewModels:ExpanderViewModel"
9+
x:DataType="viewModels:ExpanderViewModel"
10+
Title="Expander">
11+
12+
<ScrollView>
13+
<VerticalStackLayout Spacing="10">
14+
<Button Text="Navigate to C# Sample" Clicked="GoToCSharpSampleClicked"/>
15+
16+
<Label Text="Simple expander" FontSize="24" FontAttributes="Bold"/>
17+
18+
<mct:Expander>
19+
<mct:Expander.Header>
20+
<Label Text="Simple Expander (Tap Me)" FontSize="16" FontAttributes="Bold"/>
21+
</mct:Expander.Header>
22+
23+
<mct:Expander.Content BackgroundColor="LightGray">
24+
<VerticalStackLayout>
25+
<Label Text="Item 1"/>
26+
<Label Text="Item 2"/>
27+
</VerticalStackLayout>
28+
</mct:Expander.Content>
29+
</mct:Expander>
30+
31+
<Label Text="Multi-level expander" FontSize="24" FontAttributes="Bold"/>
32+
33+
<mct:Expander Direction="Up">
34+
<mct:Expander.Header>
35+
<Label Text="Multi-Level Expander (Tap Me)" FontSize="16" FontAttributes="Bold"/>
36+
</mct:Expander.Header>
37+
<mct:Expander.Content BackgroundColor="LightGray">
38+
<mct:Expander Direction="Down" BackgroundColor="LightGray">
39+
<mct:Expander.Header>
40+
<Label Text="Nested Expander (Tap Me)" FontSize="14" FontAttributes="Bold"/>
41+
</mct:Expander.Header>
42+
<mct:Expander.Content>
43+
<Label Text="Item 1" />
44+
</mct:Expander.Content>
45+
</mct:Expander>
46+
</mct:Expander.Content>
47+
</mct:Expander>
48+
</VerticalStackLayout>
49+
</ScrollView>
50+
</pages:BasePage>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using CommunityToolkit.Maui.Alerts;
2+
using CommunityToolkit.Maui.Sample.ViewModels.Views;
3+
4+
namespace CommunityToolkit.Maui.Sample.Pages.Views;
5+
6+
public partial class ExpanderPage : BasePage<ExpanderViewModel>
7+
{
8+
public ExpanderPage(ExpanderViewModel viewModel) : base(viewModel)
9+
{
10+
InitializeComponent();
11+
}
12+
13+
async void Expander_ExpandedChanged(object sender, Core.ExpandedChangedEventArgs e)
14+
{
15+
var collapsedText = e.IsExpanded ? "expanded" : "collapsed";
16+
await Toast.Make($"Expander is {collapsedText}").Show(CancellationToken.None);
17+
}
18+
19+
async void GoToCSharpSampleClicked(object sender, EventArgs e)
20+
{
21+
await Navigation.PushAsync(new ExpanderPageCS());
22+
}
23+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
using CommunityToolkit.Maui.Core;
2+
using CommunityToolkit.Maui.Views;
3+
using CommunityToolkit.Maui.Markup;
4+
5+
namespace CommunityToolkit.Maui.Sample.Pages.Views;
6+
7+
public class ExpanderPageCS : ContentPage
8+
{
9+
public ExpanderPageCS()
10+
{
11+
Title = "Expander Page, C# UI";
12+
13+
Content = new VerticalStackLayout()
14+
{
15+
Spacing = 12,
16+
17+
Children =
18+
{
19+
new Label()
20+
.Text("Expander C# Sample")
21+
.Font(bold: true, size: 24)
22+
.CenterHorizontal(),
23+
24+
new Picker() { ItemsSource = Enum.GetValues<ExpandDirection>(), Title = "Direction" }
25+
.CenterHorizontal().TextCenter()
26+
.Assign(out Picker picker),
27+
28+
new Expander
29+
{
30+
Header = new Label()
31+
.Text("Expander (Tap Me)")
32+
.Font(bold: true, size: 18),
33+
34+
Content = new VerticalStackLayout()
35+
{
36+
new Image()
37+
.Source("https://avatars.githubusercontent.com/u/9011267?v=4")
38+
.Size(120)
39+
.Aspect(Aspect.AspectFit),
40+
41+
new Label()
42+
.Text(".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.")
43+
.Font(italic: true)
44+
45+
}.Padding(10)
46+
47+
}.CenterHorizontal()
48+
.Bind(Expander.DirectionProperty, nameof(Picker.SelectedIndex), source: picker, convert: (int selectedIndex) => Enum.IsDefined(typeof(ExpandDirection), selectedIndex) ? (ExpandDirection)selectedIndex : default)
49+
}
50+
};
51+
}
52+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using System.Collections.ObjectModel;
2+
using CommunityToolkit.Mvvm.ComponentModel;
3+
4+
namespace CommunityToolkit.Maui.Sample.ViewModels.Views;
5+
6+
public partial class ExpanderViewModel : BaseViewModel
7+
{
8+
public ObservableCollection<ContentCreator> ContentCreators { get; } = new();
9+
10+
public ExpanderViewModel()
11+
{
12+
ContentCreators.Add(new ContentCreator("Brandon Minnick", "https://codetraveler.io/", "https://avatars.githubusercontent.com/u/13558917"));
13+
ContentCreators.Add(new ContentCreator("Gerald Versluis", "https://blog.verslu.is/", "https://avatars.githubusercontent.com/u/939291"));
14+
ContentCreators.Add(new ContentCreator("Kym Phillpotts", "https://kymphillpotts.com", "https://avatars.githubusercontent.com/u/1327346"));
15+
ContentCreators.Add(new ContentCreator("Pedro Jesus", "https://github.com/pictos", "https://avatars.githubusercontent.com/u/20712372"));
16+
ContentCreators.Add(new ContentCreator("Shaun Lawrence", "https://github.com/bijington", "https://avatars.githubusercontent.com/u/17139988"));
17+
ContentCreators.Add(new ContentCreator("Vladislav Antonyuk", "https://vladislavantonyuk.azurewebsites.net", "https://avatars.githubusercontent.com/u/33021114"));
18+
}
19+
}
20+
21+
public record ContentCreator(string Name, string Resource, string Image);

samples/CommunityToolkit.Maui.Sample/ViewModels/Views/ViewsGalleryViewModel.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using CommunityToolkit.Maui.Sample.Models;
1+
using CommunityToolkit.Maui.Sample.Models;
22
using CommunityToolkit.Maui.Sample.ViewModels.Views.AvatarView;
33

44
namespace CommunityToolkit.Maui.Sample.ViewModels.Views;
@@ -20,9 +20,10 @@ public ViewsGalleryViewModel()
2020
SectionModel.Create<AvatarViewShapesViewModel>("AvatarView Shapes Page", Colors.Red, "A page demonstrating AvatarViews with various shape options."),
2121
SectionModel.Create<AvatarViewSizesViewModel>("AvatarView Sizes Page", Colors.Red, "A page demonstrating AvatarViews with various size options."),
2222
SectionModel.Create<DrawingViewViewModel>("DrawingView", Colors.Red, "DrawingView provides a canvas for users to \"paint\" on the screen. The drawing can also be captured and displayed as an Image."),
23+
SectionModel.Create<ExpanderViewModel>("Expander Page", Colors.Red, "Expander allows collapse and expand content."),
2324
SectionModel.Create<MultiplePopupViewModel>("Mutiple Popups Page", Colors.Red, "A page demonstrating multiple different Popups"),
2425
SectionModel.Create<PopupPositionViewModel>("Custom Positioning Popup", Colors.Red, "Displays a basic popup anywhere on the screen using VerticalOptions and HorizontalOptions"),
25-
SectionModel.Create<PopupAnchorViewModel>("Anchor Popup", Colors.Red, "Popups can be anchored to other view's on the screen"),
26+
SectionModel.Create<PopupAnchorViewModel>("Anchor Popup", Colors.Red, "Popups can be anchored to other view's on the screen")
2627
})
2728
{
2829
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
namespace CommunityToolkit.Maui.Core;
2+
3+
/// <summary>
4+
/// Allows collapse and expand content.
5+
/// </summary>
6+
public interface IExpander : IContentView
7+
{
8+
/// <summary>
9+
/// Expander header.
10+
/// </summary>
11+
public IView? Header { get; }
12+
13+
/// <summary>
14+
/// Gets or sets expand direction.
15+
/// </summary>
16+
public ExpandDirection Direction { get; }
17+
18+
/// <summary>
19+
/// Gets or sets Expander collapsible state.
20+
/// </summary>
21+
public bool IsExpanded { get; set; }
22+
23+
/// <summary>
24+
/// Action when <see cref="IsExpanded"/> changes
25+
/// </summary>
26+
void ExpandedChanged(bool isExpanded);
27+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
namespace CommunityToolkit.Maui.Core;
2+
3+
/// <summary>
4+
/// Expander expand direction.
5+
/// </summary>
6+
public enum ExpandDirection
7+
{
8+
/// <summary>
9+
/// Expander expands down
10+
/// </summary>
11+
Down,
12+
13+
/// <summary>
14+
/// Expander expands up
15+
/// </summary>
16+
Up
17+
}

0 commit comments

Comments
 (0)