Skip to content
This repository was archived by the owner on May 1, 2024. It is now read-only.

Add VSM to ValidationBehavior #955

Merged
merged 12 commits into from
Mar 3, 2021
Merged
Show file tree
Hide file tree
Changes from 5 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
Original file line number Diff line number Diff line change
@@ -1,69 +1,91 @@
<?xml version="1.0" encoding="UTF-8" ?>
<pages:BasePage xmlns="http://xamarin.com/schemas/2014/forms"
<pages:BasePage x:Name="Page"
x:Class="Xamarin.CommunityToolkit.Sample.Pages.Behaviors.CharactersValidationBehaviorPage"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
xmlns:pages="clr-namespace:Xamarin.CommunityToolkit.Sample.Pages"
x:Name="Page"
x:Class="Xamarin.CommunityToolkit.Sample.Pages.Behaviors.CharactersValidationBehaviorPage">
xmlns:pages="clr-namespace:Xamarin.CommunityToolkit.Sample.Pages">

<pages:BasePage.Resources>
<Style x:Key="InvalidEntryStyle"
TargetType="Entry">
<Setter Property="TextColor"
Value="Red" />
<Setter Property="TextColor" Value="Red"/>
</Style>

<Style x:Key="ValidEntryStyle"
TargetType="Entry">
<Setter Property="TextColor" Value="Green"/>
</Style>
</pages:BasePage.Resources>

<StackLayout Padding="{StaticResource ContentPadding}"
Spacing="25"
VerticalOptions="StartAndExpand">
<Label Text="Text color will change accordingly to the style that is configured when an invalid string is entered." />
<Label Text="Text color will change accordingly to the style that is configured when an invalid string is entered."/>
<Frame Margin="{StaticResource ContentPadding}"
CornerRadius="10">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Text="CharacterType" />
<Picker x:Name="CharacterTypePicker"
<Label Text="CharacterType"/>
<Picker x:Name="CharacterTypePicker" Grid.Column="1"
Title="CharacterType"
Grid.Column="1"
ItemsSource="{Binding CharacterTypes,
Source={x:Reference Page}}"
SelectedIndex="1" />
ItemsSource="{Binding CharacterTypes, Source={x:Reference Page}}"
SelectedIndex="1"/>
<Label Grid.Row="1"
Text="MinimumCharacterCountEntry" />
<Entry x:Name="MinimumCharacterCountEntry"
Grid.Row="1"
Grid.Column="1"
Text="MinimumCharacterCountEntry"/>
<Entry x:Name="MinimumCharacterCountEntry" Grid.Row="1" Grid.Column="1"
Keyboard="Numeric"
Text="2" />
Text="2"/>
<Label Grid.Row="2"
Text="MaximumCharacterCountEntry" />
<Entry x:Name="MaximumCharacterCountEntry"
Grid.Row="2"
Grid.Column="1"
Text="MaximumCharacterCountEntry"/>
<Entry x:Name="MaximumCharacterCountEntry" Grid.Row="2" Grid.Column="1"
Keyboard="Numeric"
Text="20" />
Text="20"/>
</Grid>
</Frame>
<Label Text="Type characters for validation behavior according to the settings you set upon." />
<Label Text="Type characters for validation behavior according to the settings you set upon."/>
<Entry Placeholder="Type characters...">
<Entry.Behaviors>
<xct:CharactersValidationBehavior CharacterType="{Binding SelectedItem,
Source={x:Reference CharacterTypePicker}}"
<xct:CharactersValidationBehavior CharacterType="{Binding SelectedItem, Source={x:Reference CharacterTypePicker}}"
InvalidStyle="{StaticResource InvalidEntryStyle}"
MaximumCharacterCount="{Binding Text,
Source={x:Reference MaximumCharacterCountEntry}}"
MinimumCharacterCount="{Binding Text,
Source={x:Reference MinimumCharacterCountEntry}}" />
ValidStyle="{StaticResource ValidEntryStyle}"
MaximumCharacterCount="{Binding Text, Source={x:Reference MaximumCharacterCountEntry}}"
MinimumCharacterCount="{Binding Text, Source={x:Reference MinimumCharacterCountEntry}}"/>
</Entry.Behaviors>
</Entry>

<Label Text="The same but styling handled by visual state manager."/>
<Entry Placeholder="Type characters...">
<Entry.Behaviors>
<xct:CharactersValidationBehavior Flags="ValidateOnValueChanging"
CharacterType="{Binding SelectedItem, Source={x:Reference CharacterTypePicker}}"
MaximumCharacterCount="{Binding Text, Source={x:Reference MaximumCharacterCountEntry}}"
MinimumCharacterCount="{Binding Text, Source={x:Reference MinimumCharacterCountEntry}}"/>
</Entry.Behaviors>

<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Valid">
<VisualState.Setters>
<Setter Property="TextColor" Value="Green"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Invalid">
<VisualState.Setters>
<Setter Property="TextColor" Value="IndianRed"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Entry>

</StackLayout>
</pages:BasePage>
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;
using System.Linq;


namespace Xamarin.CommunityToolkit.Behaviors.Internals
{
Expand All @@ -11,6 +13,9 @@ namespace Xamarin.CommunityToolkit.Behaviors.Internals
/// </summary>
public abstract class ValidationBehavior : BaseBehavior<VisualElement>
{
const string validVisualState = "Valid";
const string invalidVisualState = "Invalid";

/// <summary>
/// Backing BindableProperty for the <see cref="IsNotValid"/> property.
/// </summary>
Expand Down Expand Up @@ -291,12 +296,28 @@ async ValueTask UpdateStateAsync(bool isForced, CancellationToken? parentToken =

void UpdateStyle()
{
if (View == null || (ValidStyle ?? InvalidStyle) == null)
if (View == null)
{
return;
}

View.Style = IsValid
? ValidStyle
: InvalidStyle;
if ((ValidStyle ?? InvalidStyle) != null)
{
View.Style = IsValid
? ValidStyle
: InvalidStyle;
return; // either use VSM or styles?
}

var vsmGroupsList = VisualStateManager.GetVisualStateGroups(View);
if (vsmGroupsList.Count > 0)
{
var vsmGroupsstates = vsmGroupsList[0].States;
if (vsmGroupsstates.All(x => x.Name.Equals(validVisualState) || x.Name.Equals(invalidVisualState)))
{
VisualStateManager.GoToState(View, IsValid ? validVisualState : invalidVisualState);
}
}
}

void ResetValidationTokenSource(CancellationTokenSource newTokenSource)
Expand All @@ -305,4 +326,4 @@ void ResetValidationTokenSource(CancellationTokenSource newTokenSource)
validationTokenSource = newTokenSource;
}
}
}
}