This repository has been archived by the owner on Oct 29, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 149
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
86d19b7
commit 42d9b13
Showing
12 changed files
with
815 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
71 changes: 71 additions & 0 deletions
71
src/Microsoft.MobileBlazorBindings.Forms/CascadingEditContext.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT license. | ||
|
||
using Microsoft.AspNetCore.Components; | ||
using Microsoft.AspNetCore.Components.Forms; | ||
using Microsoft.AspNetCore.Components.Rendering; | ||
using System; | ||
|
||
namespace Microsoft.MobileBlazorBindings.Forms | ||
{ | ||
public class CascadingEditContext : ComponentBase | ||
{ | ||
private EditContext _editContext; | ||
private bool _hasSetEditContextExplicitly; | ||
|
||
[Parameter] | ||
public EditContext EditContext | ||
{ | ||
get => _editContext; | ||
set | ||
{ | ||
_editContext = value; | ||
_hasSetEditContextExplicitly = value != null; | ||
} | ||
} | ||
|
||
[Parameter] public object Model { get; set; } | ||
|
||
[Parameter] public RenderFragment<EditContext> ChildContent { get; set; } | ||
|
||
protected override void OnParametersSet() | ||
{ | ||
if (_hasSetEditContextExplicitly && Model != null) | ||
{ | ||
throw new InvalidOperationException($"{nameof(CascadingEditContext)} requires a {nameof(Model)} " + | ||
$"parameter, or an {nameof(EditContext)} parameter, but not both."); | ||
} | ||
else if (!_hasSetEditContextExplicitly && Model == null) | ||
{ | ||
throw new InvalidOperationException($"{nameof(CascadingEditContext)} requires either a {nameof(Model)} " + | ||
$"parameter, or an {nameof(EditContext)} parameter, please provide one of these."); | ||
} | ||
|
||
// Update _editContext if we don't have one yet, or if they are supplying a | ||
// potentially new EditContext, or if they are supplying a different Model | ||
if (Model != null && Model != _editContext?.Model) | ||
{ | ||
_editContext = new EditContext(Model!); | ||
} | ||
} | ||
|
||
protected override void BuildRenderTree(RenderTreeBuilder builder) | ||
{ | ||
if (builder is null) | ||
throw new ArgumentNullException(nameof(builder)); | ||
|
||
// If _editContext changes, tear down and recreate all descendants. | ||
// This is so we can safely use the IsFixed optimization on CascadingValue, | ||
// optimizing for the common case where _editContext never changes. | ||
builder.OpenRegion(_editContext.GetHashCode()); | ||
|
||
builder.OpenComponent<CascadingValue<EditContext>>(0); | ||
builder.AddAttribute(1, "IsFixed", true); | ||
builder.AddAttribute(2, "Value", _editContext); | ||
builder.AddAttribute(3, "ChildContent", ChildContent?.Invoke(_editContext)); | ||
builder.CloseComponent(); | ||
|
||
builder.CloseRegion(); | ||
} | ||
} | ||
} |
84 changes: 84 additions & 0 deletions
84
src/Microsoft.MobileBlazorBindings.Forms/InputViewWrapper.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT license. | ||
|
||
using Microsoft.AspNetCore.Components; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using XF = Xamarin.Forms; | ||
|
||
namespace Microsoft.MobileBlazorBindings.Forms | ||
{ | ||
public abstract class InputViewWrapper : ViewWrapper | ||
{ | ||
/// <summary> | ||
/// Gets or sets a value that indicates the number of device-independent units that should be in between characters in the text displayed by the Entry. Applies to Text and Placeholder. | ||
/// </summary> | ||
/// <value> | ||
/// The number of device-independent units that should be in between characters in the text. | ||
/// </value> | ||
[Parameter] public double? CharacterSpacing { get; set; } | ||
/// <summary> | ||
/// Gets or sets a value that indicates whether user should be prevented from modifying the text. Default is <see langword="false" />. | ||
/// </summary> | ||
/// <value> | ||
/// If <see langword="true" />, user cannot modify text. Else, <see langword="false" />. | ||
/// </value> | ||
[Parameter] public bool? IsReadOnly { get; set; } | ||
/// <summary> | ||
/// Gets or sets a value that controls whether spell checking is enabled. | ||
/// </summary> | ||
/// <value> | ||
/// <see langword="true" /> if spell checking is enabled. Otherwise <see langword="false" />. | ||
/// </value> | ||
[Parameter] public bool? IsSpellCheckEnabled { get; set; } | ||
/// <summary> | ||
/// Gets or sets the maximum allowed length of input. | ||
/// </summary> | ||
/// <value> | ||
/// An integer in the interval [0,<c>int.MaxValue</c>]. The default value is <c>Int.MaxValue</c>. | ||
/// </value> | ||
[Parameter] public int? MaxLength { get; set; } | ||
/// <summary> | ||
/// Gets or sets the text that is displayed when the control is empty. | ||
/// </summary> | ||
/// <value> | ||
/// The text that is displayed when the control is empty. | ||
/// </value> | ||
[Parameter] public string Placeholder { get; set; } | ||
/// <summary> | ||
/// Gets or sets the color of the placeholder text. | ||
/// </summary> | ||
/// <value> | ||
/// The color of the placeholder text. | ||
/// </value> | ||
[Parameter] public XF.Color? PlaceholderColor { get; set; } | ||
/// <summary> | ||
/// Gets or sets the text color. | ||
/// </summary> | ||
[Parameter] public XF.Color? TextColor { get; set; } | ||
[Parameter] public XF.TextTransform? TextTransform { get; set; } | ||
|
||
private IEnumerable<KeyValuePair<string, object>> InputViewProperties | ||
{ | ||
get | ||
{ | ||
yield return new KeyValuePair<string, object>(nameof(CharacterSpacing), CharacterSpacing); | ||
yield return new KeyValuePair<string, object>(nameof(IsReadOnly), IsReadOnly); | ||
yield return new KeyValuePair<string, object>(nameof(IsSpellCheckEnabled), IsSpellCheckEnabled); | ||
yield return new KeyValuePair<string, object>(nameof(MaxLength), MaxLength); | ||
yield return new KeyValuePair<string, object>(nameof(Placeholder), Placeholder); | ||
yield return new KeyValuePair<string, object>(nameof(PlaceholderColor), PlaceholderColor); | ||
yield return new KeyValuePair<string, object>(nameof(TextColor), TextColor); | ||
yield return new KeyValuePair<string, object>(nameof(TextTransform), TextTransform); | ||
} | ||
} | ||
|
||
protected override IEnumerable<KeyValuePair<string, object>> WrappedProperties | ||
{ | ||
get | ||
{ | ||
return base.WrappedProperties.Concat(InputViewProperties); | ||
} | ||
} | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
src/Microsoft.MobileBlazorBindings.Forms/Microsoft.MobileBlazorBindings.Forms.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<Project Sdk="Microsoft.NET.Sdk.Razor"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>netstandard2.0</TargetFramework> | ||
<RazorLangVersion>3.0</RazorLangVersion> | ||
<Description>Forms and validation support for Experimental Mobile Blazor Bindings.</Description> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\Microsoft.MobileBlazorBindings\Microsoft.MobileBlazorBindings.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
34 changes: 34 additions & 0 deletions
34
src/Microsoft.MobileBlazorBindings.Forms/SubmitButton.razor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
@inherits ViewWrapper | ||
|
||
<Button OnClick="OnButtonClick" @attributes="Properties" /> | ||
|
||
@code { | ||
[CascadingParameter] EditContext CascadedEditContext { get; set; } | ||
|
||
[Parameter] public EventCallback<EditContext> OnValidSubmit { get; set; } | ||
[Parameter] public EventCallback<EditContext> OnInvalidSubmit { get; set; } | ||
|
||
protected override void OnInitialized() | ||
{ | ||
if (CascadedEditContext is null) | ||
{ | ||
throw new InvalidOperationException($"{GetType()} requires a cascading parameter " + | ||
$"of type {nameof(EditContext)}. For example, you can use {GetType().FullName} inside " + | ||
$"an {nameof(CascadedEditContext)}."); | ||
} | ||
} | ||
|
||
private async Task OnButtonClick() | ||
{ | ||
CascadedEditContext.Validate(); | ||
|
||
if (CascadedEditContext.GetValidationMessages().Any()) | ||
{ | ||
await OnInvalidSubmit.InvokeAsync(CascadedEditContext).ConfigureAwait(false); | ||
} | ||
else | ||
{ | ||
await OnValidSubmit.InvokeAsync(CascadedEditContext).ConfigureAwait(false); | ||
} | ||
} | ||
} |
92 changes: 92 additions & 0 deletions
92
src/Microsoft.MobileBlazorBindings.Forms/SubmitButton.razor.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT license. | ||
|
||
using Microsoft.AspNetCore.Components; | ||
using System.Collections.Generic; | ||
using XF = Xamarin.Forms; | ||
|
||
namespace Microsoft.MobileBlazorBindings.Forms | ||
{ | ||
public partial class SubmitButton : ViewWrapper | ||
{ | ||
/// <summary> | ||
/// Gets or sets a color that describes the border stroke color of the button. This is a bindable property. | ||
/// </summary> | ||
/// <value> | ||
/// The color that is used as the border stroke color; the default is <see cref="XF.Color.Default" />. | ||
/// </value> | ||
[Parameter] public XF.Color? BorderColor { get; set; } | ||
/// <summary> | ||
/// Gets or sets the width of the border. This is a bindable property. | ||
/// </summary> | ||
/// <value> | ||
/// The width of the button border; the default is 0. | ||
/// </value> | ||
[Parameter] public double? BorderWidth { get; set; } | ||
[Parameter] public double? CharacterSpacing { get; set; } | ||
/// <summary> | ||
/// Gets or sets the corner radius for the button, in device-independent units. | ||
/// </summary> | ||
/// <value> | ||
/// The corner radius for the button, in device-independent units. | ||
/// </value> | ||
[Parameter] public int? CornerRadius { get; set; } | ||
/// <summary> | ||
/// Gets a value that indicates whether the font for the button text is bold, italic, or neither. | ||
/// </summary> | ||
[Parameter] public XF.FontAttributes? FontAttributes { get; set; } | ||
/// <summary> | ||
/// Gets the font family to which the font for the button text belongs. | ||
/// </summary> | ||
[Parameter] public string FontFamily { get; set; } | ||
/// <summary> | ||
/// Gets or sets the size of the font of the button text. | ||
/// </summary> | ||
[Parameter] public double? FontSize { get; set; } | ||
/// <summary> | ||
/// Allows you to display a bitmap image on the Button. | ||
/// </summary> | ||
[Parameter] public XF.ImageSource ImageSource { get; set; } | ||
/// <summary> | ||
/// Gets or sets the padding for the button. | ||
/// </summary> | ||
/// <value> | ||
/// The padding for the button. | ||
/// </value> | ||
[Parameter] public XF.Thickness? Padding { get; set; } | ||
/// <summary> | ||
/// Gets or sets the Text displayed as the content of the button. This is a bindable property. | ||
/// </summary> | ||
/// <value> | ||
/// The text displayed in the button. The default value is <see langword="null" />. | ||
/// </value> | ||
[Parameter] public string Text { get; set; } | ||
/// <summary> | ||
/// Gets or sets the <see cref="XF.Color" /> for the text of the button. This is a bindable property. | ||
/// </summary> | ||
/// <value> | ||
/// The <see cref="XF.Color" /> value. | ||
/// </value> | ||
[Parameter] public XF.Color? TextColor { get; set; } | ||
[Parameter] public XF.TextTransform? TextTransform { get; set; } | ||
|
||
protected override IEnumerable<KeyValuePair<string, object>> AdditionalProperties | ||
{ | ||
get | ||
{ | ||
yield return new KeyValuePair<string, object>(nameof(BorderColor), BorderColor); | ||
yield return new KeyValuePair<string, object>(nameof(BorderWidth), BorderWidth); | ||
yield return new KeyValuePair<string, object>(nameof(CharacterSpacing), CharacterSpacing); | ||
yield return new KeyValuePair<string, object>(nameof(CornerRadius), CornerRadius); | ||
yield return new KeyValuePair<string, object>(nameof(FontAttributes), FontAttributes); | ||
yield return new KeyValuePair<string, object>(nameof(FontFamily), FontFamily); | ||
yield return new KeyValuePair<string, object>(nameof(FontSize), FontSize); | ||
yield return new KeyValuePair<string, object>(nameof(ImageSource), ImageSource); | ||
yield return new KeyValuePair<string, object>(nameof(Padding), Padding); | ||
yield return new KeyValuePair<string, object>(nameof(Text), Text); | ||
yield return new KeyValuePair<string, object>(nameof(TextColor), TextColor); | ||
yield return new KeyValuePair<string, object>(nameof(TextTransform), TextTransform); | ||
} | ||
} | ||
} | ||
} |
59 changes: 59 additions & 0 deletions
59
src/Microsoft.MobileBlazorBindings.Forms/ValidatedEntry.razor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
@inherits InputViewWrapper | ||
|
||
<Entry @bind-Text="@CurrentText" | ||
OnUnfocused="OnUnfocused" | ||
@attributes="Properties" /> | ||
|
||
@code | ||
{ | ||
private FieldIdentifier _fieldIdentifier; | ||
[CascadingParameter] EditContext CascadedEditContext { get; set; } | ||
|
||
[Parameter] public string Text { get; set; } | ||
[Parameter] public EventCallback<string> TextChanged { get; set; } | ||
[Parameter] public Expression<Func<string>> TextExpression { get; set; } | ||
|
||
public bool IsValid => !CascadedEditContext.GetValidationMessages(_fieldIdentifier).Any(); | ||
|
||
private string CurrentText | ||
{ | ||
get => Text; | ||
set | ||
{ | ||
if (Text != value) | ||
{ | ||
Text = value; | ||
_ = TextChanged.InvokeAsync(value); | ||
|
||
// Reflect changes immediately only if field already has validations | ||
if (!IsValid) | ||
{ | ||
CascadedEditContext.NotifyFieldChanged(_fieldIdentifier); | ||
} | ||
} | ||
} | ||
} | ||
|
||
private void OnUnfocused() | ||
{ | ||
CascadedEditContext.NotifyFieldChanged(_fieldIdentifier); | ||
} | ||
|
||
protected override void OnInitialized() | ||
{ | ||
if (CascadedEditContext is null) | ||
{ | ||
throw new InvalidOperationException($"{GetType()} requires a cascading parameter " + | ||
$"of type {nameof(EditContext)}. For example, you can use {GetType().FullName} inside " + | ||
$"an {nameof(CascadedEditContext)}."); | ||
} | ||
|
||
if (TextExpression is null) | ||
{ | ||
throw new InvalidOperationException($"{GetType()} requires a value for the 'TextExpression' " + | ||
$"parameter. Normally this is provided automatically when using 'bind-Text'."); | ||
} | ||
|
||
_fieldIdentifier = FieldIdentifier.Create(TextExpression); | ||
} | ||
} |
Oops, something went wrong.