1using System.ComponentModel;
2using CommunityToolkit.Maui.Converters;
3using Microsoft.Maui.Controls.Shapes;
4using Path =
Microsoft.Maui.Controls.Shapes.Path;
5using FormatedString =
Microsoft.Maui.Controls.FormattedString;
6using Microsoft.Maui.Graphics.Text;
17 protected Label label;
18 protected ContentView leftContentView;
19 protected ContentView centerContentView;
20 protected ContentView rightContentView;
21 protected Grid validationGrid;
22 protected Border border;
24 public bool CanShowValidation => !this.IsValid && !
string.IsNullOrEmpty(this.ValidationText);
25 public bool CanShowLabel => !
string.IsNullOrEmpty(this.LabelText);
31 Grid MainGrid =
new Grid
35 new RowDefinition { Height = GridLength.Auto },
36 new RowDefinition { Height = GridLength.Auto },
37 new RowDefinition { Height = GridLength.Auto }
41 MainGrid.RowSpacing = 2;
44 this.label =
new Label();
45 FormattedString Formatted =
new FormattedString();
48 Span LabelSpan =
new Span();
49 LabelSpan.SetBinding(Span.TextProperty,
new Binding(nameof(this.LabelText), source:
this));
52 LabelSpan.SetBinding(Span.TextColorProperty,
new Binding(nameof(this.label.TextColor), source:
this.label));
53 LabelSpan.SetBinding(Span.FontSizeProperty,
new Binding(nameof(this.label.FontSize), source:
this.label));
54 LabelSpan.SetBinding(Span.FontFamilyProperty,
new Binding(nameof(this.label.FontFamily), source:
this.label));
55 LabelSpan.SetBinding(Span.FontAttributesProperty,
new Binding(nameof(this.label.FontAttributes), source:
this.label));
56 LabelSpan.SetBinding(Span.TextDecorationsProperty,
new Binding(nameof(this.label.TextDecorations), source:
this.label));
57 LabelSpan.SetBinding(Span.CharacterSpacingProperty,
new Binding(nameof(this.label.CharacterSpacing), source:
this.label));
58 LabelSpan.SetBinding(Span.LineHeightProperty,
new Binding(nameof(this.label.LineHeight), source:
this.label));
59 LabelSpan.SetBinding(Span.TextTransformProperty,
new Binding(nameof(this.label.TextTransform), source:
this.label));
60 LabelSpan.SetBinding(Span.BackgroundColorProperty,
new Binding(nameof(this.label.BackgroundColor), source:
this.label));
61 LabelSpan.SetBinding(Span.FontAutoScalingEnabledProperty,
new Binding(nameof(this.label.FontAutoScalingEnabled), source:
this.label));
63 Formatted.Spans.Add(LabelSpan);
66 Span RequiredMarkerSpan =
new Span();
67 RequiredMarkerSpan.SetBinding(Span.TextProperty,
new Binding(nameof(this.RequiredMarker), source:
this));
69 Formatted.Spans.Add(RequiredMarkerSpan);
71 this.label.FormattedText = Formatted;
72 this.label.SetBinding(
Label.StyleProperty,
new Binding(nameof(this.
LabelStyle), source:
this));
73 this.label.SetBinding(
Label.IsVisibleProperty,
new Binding(nameof(this.CanShowLabel), source:
this));
75 MainGrid.Add(this.label, 0, 0);
78 Grid ContentGrid =
new Grid
82 new ColumnDefinition { Width = GridLength.Auto },
83 new ColumnDefinition { Width = GridLength.Star },
84 new ColumnDefinition { Width = GridLength.Auto }
91 this.leftContentView =
new ContentView();
92 this.leftContentView.SetBinding(ContentView.ContentProperty,
new Binding(nameof(this.LeftView), source:
this));
93 ContentGrid.Add(this.leftContentView, 0, 0);
96 this.centerContentView =
new ContentView();
97 this.centerContentView.SetBinding(ContentView.ContentProperty,
new Binding(nameof(this.CenterView), source:
this));
98 ContentGrid.Add(this.centerContentView, 1, 0);
101 this.rightContentView =
new ContentView();
102 this.rightContentView.SetBinding(ContentView.ContentProperty,
new Binding(nameof(this.RightView), source:
this));
103 ContentGrid.Add(this.rightContentView, 2, 0);
105 this.border =
new Border()
107 Content = ContentGrid,
108 StrokeThickness = 0.5f,
109 HorizontalOptions = LayoutOptions.Fill,
112 this.border.PropertyChanged += this.OnBorderPropertyChanged;
113 this.border.SetBinding(Border.StrokeProperty,
new Binding(nameof(this.BorderStroke), source:
this));
114 this.border.SetBinding(Border.StrokeShapeProperty,
new Binding(nameof(this.BorderStrokeShape), source:
this));
115 this.border.SetBinding(Border.BackgroundColorProperty,
new Binding(nameof(this.BorderBackground), source:
this));
116 this.border.SetBinding(Border.PaddingProperty,
new Binding(nameof(this.BorderPadding), source:
this));
117 MainGrid.Add(this.border, 0, 1);
120 this.validationGrid =
new Grid
124 new ColumnDefinition { Width = GridLength.Auto },
125 new ColumnDefinition { Width = GridLength.Star }
130 Path ValidationIcon =
new();
131 ValidationIcon.SetBinding(Path.DataProperty,
new Binding(nameof(this.ValidationIcon), source:
this));
132 ValidationIcon.SetBinding(Path.FillProperty,
new Binding(nameof(this.ValidationColor), source:
this));
133 ValidationIcon.VerticalOptions = LayoutOptions.Center;
134 this.validationGrid.Add(ValidationIcon, 0, 0);
137 ValidationLabel.SetBinding(
Label.TextProperty,
new Binding(nameof(this.ValidationText), source:
this));
138 ValidationLabel.SetBinding(
Label.TextColorProperty,
new Binding(nameof(this.ValidationColor), source:
this));
140 this.validationGrid.Add(ValidationLabel, 1, 0);
142 this.validationGrid.SetBinding(Grid.IsVisibleProperty,
new Binding(nameof(this.CanShowValidation), source:
this));
144 this.validationGrid.HorizontalOptions = LayoutOptions.Center;
146 this.validationGrid.ColumnSpacing =
AppStyles.SmallSpacing;
148 MainGrid.Add(this.validationGrid, 0, 2);
150 this.Content = MainGrid;
153 #region Bindable Properties
155 public static readonly BindableProperty RequiredProperty =
156 BindableProperty.Create(
161 propertyChanged: OnRequiredChanged);
165 get => (bool)this.GetValue(RequiredProperty);
166 set => this.SetValue(RequiredProperty, value);
170 public static readonly BindableProperty LabelTextProperty =
171 BindableProperty.Create(nameof(LabelText), typeof(
string), typeof(
CompositeInputView),
string.Empty, propertyChanged: OnLabelChanged);
173 public string LabelText
175 get => (string)this.GetValue(LabelTextProperty);
176 set => this.SetValue(LabelTextProperty, value);
180 public static readonly BindableProperty LeftViewProperty =
181 BindableProperty.Create(nameof(LeftView), typeof(View), typeof(
CompositeInputView),
null, propertyChanged: OnLeftViewChanged);
185 get => (View)this.GetValue(LeftViewProperty);
186 set => this.SetValue(LeftViewProperty, value);
190 public static readonly BindableProperty CenterViewProperty =
191 BindableProperty.Create(nameof(CenterView), typeof(View), typeof(
CompositeInputView),
null);
193 public View CenterView
195 get => (View)this.GetValue(CenterViewProperty);
196 set => this.SetValue(CenterViewProperty, value);
200 public static readonly BindableProperty RightViewProperty =
201 BindableProperty.Create(nameof(RightView), typeof(View), typeof(
CompositeInputView),
null, propertyChanged: OnRightViewChanged);
203 public View RightView
205 get => (View)this.GetValue(RightViewProperty);
206 set => this.SetValue(RightViewProperty, value);
210 public static readonly BindableProperty ValidationIconProperty =
213 public Geometry ValidationIcon
215 get => (Geometry)this.GetValue(ValidationIconProperty);
216 set => this.SetValue(ValidationIconProperty, value);
220 public static readonly BindableProperty ValidationTextProperty =
221 BindableProperty.Create(nameof(ValidationText), typeof(
string), typeof(
CompositeInputView),
string.Empty, propertyChanged: OnValidationChanged);
223 public string ValidationText
225 get => (string)this.GetValue(ValidationTextProperty);
226 set => this.SetValue(ValidationTextProperty, value);
260 public static readonly BindableProperty IsValidProperty =
261 BindableProperty.Create(nameof(IsValid), typeof(
bool), typeof(
CompositeInputView),
true, propertyChanged: OnValidationChanged);
265 get => (bool)this.GetValue(IsValidProperty);
266 set => this.SetValue(IsValidProperty, value);
284 public static readonly BindableProperty ValidationColorProperty =
287 public Color ValidationColor
289 get => (Color)this.GetValue(ValidationColorProperty);
290 set => this.SetValue(ValidationColorProperty, value);
292 public string RequiredMarker => this.Required ?
"*" :
string.Empty;
297 #region Border Bindable Properties
300 public static readonly BindableProperty BorderBackgroundProperty =
301 BindableProperty.Create(
302 nameof(BorderBackground),
304 typeof(CompositeInputView),
306 public Color BorderBackground {
get => (Color)this.GetValue(BorderBackgroundProperty);
set => this.SetValue(BorderBackgroundProperty, value); }
309 public static readonly BindableProperty BorderStrokeProperty =
310 BindableProperty.Create(
311 nameof(BorderStroke),
313 typeof(CompositeInputView),
316 public Color BorderStroke
318 get => (Color)this.GetValue(BorderStrokeProperty);
319 set => this.SetValue(BorderStrokeProperty, value);
323 public static readonly BindableProperty BorderStrokeShapeProperty =
324 BindableProperty.Create(
325 nameof(BorderStrokeShape),
327 typeof(CompositeInputView),
329 public Shape BorderStrokeShape
331 get => (Shape)this.GetValue(BorderStrokeShapeProperty);
332 set => this.SetValue(BorderStrokeShapeProperty, value);
336 public static readonly BindableProperty BorderShadowProperty =
337 BindableProperty.Create(
338 nameof(BorderShadow),
340 typeof(CompositeInputView),
343 public Shadow BorderShadow
345 get => (Shadow)this.GetValue(BorderShadowProperty);
346 set => this.SetValue(BorderShadowProperty, value);
350 public static readonly BindableProperty BorderPaddingProperty =
351 BindableProperty.Create(
352 nameof(BorderPadding),
354 typeof(CompositeInputView),
357 public Thickness BorderPadding
359 get => (Thickness)this.GetValue(BorderPaddingProperty);
360 set => this.SetValue(BorderPaddingProperty, value);
364 public static readonly BindableProperty BorderCornerRadiusProperty =
365 BindableProperty.Create(
366 nameof(BorderCornerRadius),
367 typeof(CornerRadius),
368 typeof(CompositeInputView),
369 new CornerRadius(5));
371 public CornerRadius BorderCornerRadius
373 get => (CornerRadius)this.GetValue(BorderCornerRadiusProperty);
374 set => this.SetValue(BorderCornerRadiusProperty, value);
379 private static void OnRequiredChanged(BindableObject Bindable,
object OldValue,
object NewValue)
381 CompositeInputView Control = (CompositeInputView)Bindable;
382 Control.OnPropertyChanged(nameof(RequiredMarker));
385 private void OnBorderPropertyChanged(Object? Sender, PropertyChangedEventArgs E)
390 private static void OnValidationChanged(BindableObject Bindable,
object OldValue,
object NewValue)
392 CompositeInputView Control = (CompositeInputView)Bindable;
395 Control.OnPropertyChanged(nameof(CanShowValidation));
397 Control.InvalidateMeasure();
400 private static void OnLabelChanged(BindableObject Bindable,
object OldValue,
object NewValue)
402 CompositeInputView Control = (CompositeInputView)Bindable;
403 Control.OnPropertyChanged(nameof(CanShowLabel));
406 private static void OnLeftViewChanged(BindableObject Bindable,
object OldValue,
object NewValue)
408 CompositeInputView Control = (CompositeInputView)Bindable;
409 bool HasLeft = NewValue is View;
411 Control.leftContentView.Margin = HasLeft ?
new Thickness(0, 0, 8, 0) : new Thickness(0);
414 private static void OnRightViewChanged(BindableObject Bindable,
object OldValue,
object NewValue)
416 CompositeInputView Control = (CompositeInputView)Bindable;
417 bool HasRight = NewValue is View;
419 Control.rightContentView.Margin = HasRight ?
new Thickness(8, 0, 0, 0) : new Thickness(0);
Static class that gives access to app-specific themed colors. All colors are fetched directly from th...
static Color ErrorBackground
Error Background Color.
Static class that gives access to app-specific styles
static Style RequiredFieldMarkerSpan
Style for required field marker spans
static Thickness SmallTopMargins
Top-only small margins
Static class containing SVG Paths for symbols used in the app.