Skip to content

Commit

Permalink
Last changes
Browse files Browse the repository at this point in the history
  • Loading branch information
albyrock87 committed Sep 25, 2024
1 parent e658842 commit 0952ba9
Show file tree
Hide file tree
Showing 19 changed files with 283 additions and 212 deletions.
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,29 +38,29 @@ ValueTask<bool> CanLeaveAsync() => { ... ask the user };

There is an embedded **leak-detector** to help you identify memory leaks in your application.

Find out more at [Nalu Website](https://nalu-development.github.io/nalu/).
**Find out more at [Nalu Website](https://nalu-development.github.io/nalu/).**

### Layouts [![Nalu.Maui.Layouts NuGet Package](https://img.shields.io/nuget/v/Nalu.Maui.Layouts.svg)](https://www.nuget.org/packages/Nalu.Maui.Layouts/) [![Nalu.Maui NuGet Package Downloads](https://img.shields.io/nuget/dt/Nalu.Maui.Layouts)](https://www.nuget.org/packages/Nalu.Maui.Layouts/)

Cross-platform layouts and utilities for MAUI applications simplify dealing with templates and `BindinginContext` in XAML.

- Have you ever dreamed of having an `if` statement in XAML?
```csharp
<layouts:ConditionedTemplate Value="{Binding HasPermission}"
TrueTemplate="{StaticResource AdminFormTemplate}"
FalseTemplate="{StaticResource PermissionRequestTemplate}" />
<nalu:ToggleTemplate Value="{Binding HasPermission}"
WhenTrue="{StaticResource AdminFormTemplate}"
WhenFalse="{StaticResource PermissionRequestTemplate}" />
```
- Do you want to scope the binding context of a content?
```csharp
<layouts:Component ContentBindingContext="{Binding SelectedAnimal}"
IsVisible="{Binding IsSelected}">
<nalu:ViewBox ContentBindingContext="{Binding SelectedAnimal}"
IsVisible="{Binding IsSelected}">
<views:AnimalView x:DataType="models:Animal" />
</layouts:Component>
</nalu:ViewBox>
```
- And what about rendering a `TemplateSelector` directly like we do on a `CollectionView`?
```csharp
<layouts:TemplatedComponent ContentTemplateSelector="{StaticResource AnimalTemplateSelector}"
ContentBindingContext="{Binding CurrentAnimal}" />
<nalu:TemplateBox ContentTemplateSelector="{StaticResource AnimalTemplateSelector}"
ContentBindingContext="{Binding CurrentAnimal}" />
```

Find out more at [Nalu Website](https://nalu-development.github.io/nalu/).
**Find out more at [Nalu Website](https://nalu-development.github.io/nalu/).**
26 changes: 13 additions & 13 deletions Samples/Nalu.Maui.Sample/Pages/FivePage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,36 +20,36 @@
</Label.FormattedText>
</Label>
<Button Text="Navigate to /One/Three" Command="{Binding GoToThreeCommand}" />
<nalu:ConditionedTemplate Value="True" ContentBindingContext="A true statement">
<nalu:ConditionedTemplate.TrueTemplate>
<nalu:ToggleTemplate Value="True" ContentBindingContext="A true statement">
<nalu:ToggleTemplate.WhenTrue>
<DataTemplate x:DataType="x:String">
<Label Text="{Binding .}" />
</DataTemplate>
</nalu:ConditionedTemplate.TrueTemplate>
<nalu:ConditionedTemplate.FalseTemplate>
</nalu:ToggleTemplate.WhenTrue>
<nalu:ToggleTemplate.WhenFalse>
<DataTemplate>
<Label Text="This is false" />
</DataTemplate>
</nalu:ConditionedTemplate.FalseTemplate>
</nalu:ConditionedTemplate>
</nalu:ToggleTemplate.WhenFalse>
</nalu:ToggleTemplate>
<Border BindingContext="Hello world"
BackgroundColor="LightBlue"
StrokeShape="RoundRectangle 24">
<nalu:Component Padding="16,8" x:DataType="x:String">
<nalu:ViewBox Padding="16,8" x:DataType="x:String">
<Label Text="{Binding .}"/>
</nalu:Component>
</nalu:ViewBox>
</Border>
<nalu:TemplatedComponent>
<nalu:TemplatedComponent.ContentTemplate>
<nalu:TemplateBox>
<nalu:TemplateBox.ContentTemplate>
<DataTemplate>
<HorizontalStackLayout>
<Label Text="Projected => " />
<nalu:ProjectContainer />
<nalu:TemplateContentPresenter />
</HorizontalStackLayout>
</DataTemplate>
</nalu:TemplatedComponent.ContentTemplate>
</nalu:TemplateBox.ContentTemplate>
<Label Text="I'm here!" />
</nalu:TemplatedComponent>
</nalu:TemplateBox>
</VerticalStackLayout>
</ContentPage.Content>
</ContentPage>
4 changes: 2 additions & 2 deletions Samples/Nalu.Maui.Sample/Pages/OnePage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@
</Label.FormattedText>
</Label>

<layouts:Component ContentBindingContext="{Binding Animal}">
<layouts:ViewBox ContentBindingContext="{Binding Animal}">
<Label Text="{Binding Name}" x:DataType="pageModels:AnimalModel" />
</layouts:Component>
</layouts:ViewBox>

<Button Command="{Binding PushThreeCommand}"
Text="Push Three"
Expand Down
71 changes: 0 additions & 71 deletions Source/Nalu.Maui.Layouts/Layouts/ConditionedTemplate.cs

This file was deleted.

16 changes: 0 additions & 16 deletions Source/Nalu.Maui.Layouts/Layouts/ProjectContainer.cs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
namespace Nalu;

/// <summary>
/// A <see cref="Component"/> that uses a <see cref="DataTemplate"/> to render content.
/// A <see cref="ViewBox"/> that uses a <see cref="DataTemplate"/> or <see cref="DataTemplateSelector"/> to render content.
/// </summary>
public class TemplatedComponent : TemplatedComponentBase
public class TemplateBox : TemplateBoxBase
{
/// <summary>
/// Bindable property for <see cref="ContentTemplate"/> property.
/// </summary>
public static readonly BindableProperty ContentTemplateProperty = BindableProperty.Create(
nameof(ContentTemplate),
typeof(DataTemplate),
typeof(TemplatedComponent),
typeof(TemplateBox),
propertyChanged: ContentTemplateChanged);

/// <summary>
Expand All @@ -25,9 +25,9 @@ public DataTemplate? ContentTemplate

private static void ContentTemplateChanged(BindableObject bindable, object? oldvalue, object? newvalue)
{
if (bindable is TemplatedComponent templateLayout)
if (bindable is TemplateBox templateBox)
{
templateLayout.SetTemplate(newvalue as DataTemplate);
templateBox.SetTemplate(newvalue as DataTemplate);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
namespace Nalu;

/// <summary>
/// A <see cref="Component"/> base class that uses a <see cref="DataTemplate"/> to render content.
/// A <see cref="ViewBox"/> base class that uses a <see cref="DataTemplate"/> to render content.
/// </summary>
[ContentProperty(nameof(ProjectedContent))]
public abstract class TemplatedComponentBase : ComponentBase
[ContentProperty(nameof(TemplateContent))]
public abstract class TemplateBoxBase : ViewBoxBase
{
/// <summary>
/// Bindable property for <see cref="ProjectedContent"/> property.
/// Bindable property for <see cref="TemplateContent"/> property.
/// </summary>
public static readonly BindableProperty ProjectedContentProperty = BindableProperty.Create(
nameof(ProjectedContent),
public static readonly BindableProperty TemplateContentProperty = BindableProperty.Create(
nameof(TemplateContent),
typeof(IView),
typeof(TemplatedComponent));
typeof(TemplateBox));

private bool _changingTemplate;

/// <summary>
/// Gets or sets the content to be projected through `ProjectContainer`.
/// Gets or sets the content to be projected through <see cref="TemplateContentPresenter"/> component.
/// </summary>
public IView? ProjectedContent
public IView? TemplateContent
{
get => (IView?)GetValue(ProjectedContentProperty);
set => SetValue(ProjectedContentProperty, value);
get => (IView?)GetValue(TemplateContentProperty);
set => SetValue(TemplateContentProperty, value);
}

/// <summary>
Expand Down
16 changes: 16 additions & 0 deletions Source/Nalu.Maui.Layouts/Layouts/TemplateContentPresenter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace Nalu;

/// <summary>
/// A <see cref="ViewBox"/> to display the <see cref="TemplateBoxBase.TemplateContent" />.
/// </summary>
public class TemplateContentPresenter : ViewBox
{
/// <summary>
/// Initializes a new instance of the <see cref="TemplateContentPresenter"/> class.
/// </summary>
public TemplateContentPresenter()
{
var binding = new Binding(nameof(TemplateBox.TemplateContent), source: new RelativeBindingSource(RelativeBindingSourceMode.FindAncestor, typeof(TemplateBoxBase)));
SetBinding(ContentProperty, binding);
}
}
71 changes: 71 additions & 0 deletions Source/Nalu.Maui.Layouts/Layouts/ToggleTemplate.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
namespace Nalu;

/// <summary>
/// A <see cref="ViewBox"/> that uses a <see cref="DataTemplate"/> to render content based on a boolean value.
/// </summary>
public class ToggleTemplate : TemplateBoxBase
{
/// <summary>
/// Bindable property for <see cref="WhenTrue"/> property.
/// </summary>
public static readonly BindableProperty WhenTrueProperty =
BindableProperty.Create(nameof(WhenTrue), typeof(DataTemplate), typeof(ToggleTemplate), propertyChanged: ConditionChanged);

/// <summary>
/// Bindable property for <see cref="WhenFalse"/> property.
/// </summary>
public static readonly BindableProperty WhenFalseProperty =
BindableProperty.Create(nameof(WhenFalse), typeof(DataTemplate), typeof(ToggleTemplate), propertyChanged: ConditionChanged);

/// <summary>
/// Bindable property for <see cref="Value"/> property.
/// </summary>
public static readonly BindableProperty ValueProperty = BindableProperty.Create(nameof(Value), typeof(bool?), typeof(ToggleTemplate), propertyChanged: ConditionChanged);

/// <summary>
/// Gets or sets the <see cref="DataTemplate"/> to use when the value is false.
/// </summary>
public DataTemplate? WhenFalse
{
get => (DataTemplate?)GetValue(WhenFalseProperty);
set => SetValue(WhenFalseProperty, value);
}

/// <summary>
/// Gets or sets the <see cref="DataTemplate"/> to use when the value is true.
/// </summary>
public DataTemplate? WhenTrue
{
get => (DataTemplate?)GetValue(WhenTrueProperty);
set => SetValue(WhenTrueProperty, value);
}

/// <summary>
/// Gets or sets the value to determine which template to use.
/// </summary>
public bool? Value
{
get => (bool?)GetValue(ValueProperty);
set => SetValue(ValueProperty, value);
}

private void SetTemplateFromValue()
{
var template = Value switch
{
true => WhenTrue,
false => WhenFalse,
_ => null,
};

SetTemplate(template);
}

private static void ConditionChanged(BindableObject bindable, object oldvalue, object newvalue)
{
if (bindable is ToggleTemplate toggleTemplate)
{
toggleTemplate.SetTemplateFromValue();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ namespace Nalu;
/// Can be used as a replacement of <see cref="ContentView"/> (which as-of .NET 8 uses Compatibility.Layout).
/// </remarks>
[ContentProperty(nameof(Content))]
public class Component : ComponentBase
public class ViewBox : ViewBoxBase
{
/// <summary>
/// Bindable property for <see cref="Content"/> property.
/// </summary>
public static readonly BindableProperty ContentProperty = BindableProperty.Create(nameof(Content), typeof(IView), typeof(Component), propertyChanged: OnContentPropertyChanged);
public static readonly BindableProperty ContentProperty = BindableProperty.Create(nameof(Content), typeof(IView), typeof(ViewBox), propertyChanged: OnContentPropertyChanged);

/// <summary>
/// Gets or sets the content of the layout.
Expand All @@ -30,5 +30,5 @@ public IView? Content
protected override void SetContent(IView? content) => SetValue(ContentProperty, content);

private static void OnContentPropertyChanged(BindableObject bindable, object? oldValue, object? newValue)
=> ((Component)bindable).OnContentPropertyChanged((IView?)oldValue, (IView?)newValue);
=> ((ViewBox)bindable).OnContentPropertyChanged((IView?)oldValue, (IView?)newValue);
}
Loading

0 comments on commit 0952ba9

Please sign in to comment.