diff --git a/SaCommonVS.sln b/SaCommonVS.sln
index b64ba15..d899eee 100644
--- a/SaCommonVS.sln
+++ b/SaCommonVS.sln
@@ -22,6 +22,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SacsStandardProc", "SacsSta
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SacsMobileMaui", "SacsMobileMaui\SacsMobileMaui.csproj", "{F167BCF8-8B99-4103-A710-D4B8FD5518A7}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SacsMobileMauiTests", "SacsMobileMauiTests\SacsMobileMauiTests.csproj", "{D7B6206D-6D7B-4A67-9F32-B09FCD6E8EAA}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SacsMobileMauiTestHost", "SacsMobileMauiTestHost\SacsMobileMauiTestHost.csproj", "{52B726C9-13B2-49DF-9352-90563709259B}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -56,6 +60,14 @@ Global
{F167BCF8-8B99-4103-A710-D4B8FD5518A7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F167BCF8-8B99-4103-A710-D4B8FD5518A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F167BCF8-8B99-4103-A710-D4B8FD5518A7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D7B6206D-6D7B-4A67-9F32-B09FCD6E8EAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D7B6206D-6D7B-4A67-9F32-B09FCD6E8EAA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D7B6206D-6D7B-4A67-9F32-B09FCD6E8EAA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D7B6206D-6D7B-4A67-9F32-B09FCD6E8EAA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {52B726C9-13B2-49DF-9352-90563709259B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {52B726C9-13B2-49DF-9352-90563709259B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {52B726C9-13B2-49DF-9352-90563709259B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {52B726C9-13B2-49DF-9352-90563709259B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/SacsMobileMaui/Maui/App/Sam.cs b/SacsMobileMaui/Maui/App/Sam.cs
index 938b6ea..21ac75c 100644
--- a/SacsMobileMaui/Maui/App/Sam.cs
+++ b/SacsMobileMaui/Maui/App/Sam.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
@@ -8,15 +8,18 @@ using System.Threading.Tasks;
namespace Sarand.Net.Mobile.Maui.App
{
- //=======================================================================
// Colour references:
// http://www.html-color-names.com/skyblue.php
// http://www.html-color-names.com/lightsteelblue.php
- //=======================================================================
+
public static class Sam
{
- //-------------------------------------------------------------------
- // Definitions.
+ // --- Configuration ---
+ // Values in this class are intended to be configured during application
+ // startup. Controls normally copy visual defaults when they are created;
+ // changing a value later does not automatically update existing controls.
+
+ // --- Definitions ---
public enum Platform
{
Unknown = 0,
@@ -25,26 +28,30 @@ namespace Sarand.Net.Mobile.Maui.App
MacCatalyst,
Windows
}
- // Utilities.
+ /// Shared random-number generator for common MAUI code.
public static Random Random { get; set; } = new Random();
- //-------------------------------------------------------------------
- // Localisation.
+ // --- Localisation ---
+ /// Application-wide culture settings used by consumers that opt in.
public static class Locale
{
+ /// The culture used for application-level formatting.
public static CultureInfo CultureInfo { get; set; } = CultureInfo.CurrentCulture;
+ /// Text rules associated with .
public static TextInfo TextInfo { get; set; } = CultureInfo.TextInfo;
}
- //-------------------------------------------------------------------
- // Visuals.
+ // --- Visuals ---
+ /// Supported positions for optional page content.
public enum DisplayPosition { None, Left, Middle, Right }
+
+ /// Shared visual defaults for common MAUI components.
public static class Visuals
{
- // Application styling.
+ // --- Application styling ---
public static class Application
{
- // Application bar.
+ // --- Application bar ---
public static class Bar
{
public static double Height { get; set; } = 28;
@@ -54,7 +61,7 @@ namespace Sarand.Net.Mobile.Maui.App
public static Color BorderColor { get; set; } = Colors.DarkSlateBlue;
public static double BorderBottom { get; set; } = 1.0;
}
- // Menu.
+ // --- Menu ---
public static class Menu
{
public static Color BorderColor { get; set; } = Colors.DarkSlateBlue;
@@ -63,28 +70,28 @@ namespace Sarand.Net.Mobile.Maui.App
public static Color HeaderBackgroundColor { get; set; } = Color.FromArgb("#E0E0E0");
}
}
- // Page layout.
+ // --- Page layout ---
public static class Page
{
public static Color BaseColor { get; set; } = Color.FromArgb("#c8e8f5");
public static Color BackgroundColor { get; set; } = Color.FromArgb("#e9f6fb");
- // Header.
+ // --- Header ---
public static class Header
{
- // Text.
+ // --- Text ---
public static String TextLeft { get; set; } = "";
public static String TextRight { get; set; } = "";
- // Toolbar.
+ // --- Toolbar ---
public static DisplayPosition ToolbarDisplay { get; set; } = Sam.DisplayPosition.None;
public static bool Display_ToolbarItem_Back { get; set; } = false;
- // Styling.
+ // --- Styling ---
public static Color BackgroundColor { get; set; } = Colors.Honeydew;
public static Color BorderColor { get; set; } = Colors.LightSlateGray;
public static double BorderStrokeWidthTop { get; set; } = 2.0;
public static double BorderStrokeWidthBottom { get; set; } = 1.0;
public static Thickness Padding { get; set; } = new Thickness(8, 4);
}
- // Caption.
+ // --- Caption ---
public static class Caption
{
public static Color BackgroundColor { get; set; } = Color.FromArgb("#558395");
@@ -93,7 +100,7 @@ namespace Sarand.Net.Mobile.Maui.App
public static Color TextColor { get; set; } = Color.FromArgb("#f8f8f8");
public static double TextSizeRatio { get; set; } = 1.25;
}
- // Navigation.
+ // --- Navigation ---
public static class Navigation
{
public static double BorderTopWidth { get; set; } = 0.75;
@@ -101,13 +108,13 @@ namespace Sarand.Net.Mobile.Maui.App
public static Color BorderColor { get; set; } = Color.FromArgb("#808080");
public static Color BackgroundColor { get; set; } = Color.FromArgb("#e9f6fb");
}
- // Body.
+ // --- Body ---
public static class Body
{
public static double PaddingVerticalMin { get; set; } = 4.0;
public static double PaddingHorizontalMin { get; set; } = 4.0;
}
- // Footer.
+ // --- Footer ---
public static class Footer
{
public static String TextLeft { get; set; } = "";
@@ -122,18 +129,20 @@ namespace Sarand.Net.Mobile.Maui.App
public static Thickness Padding { get; set; } = new Thickness(8, 4);
}
}
- // Fonts.
+ // --- Fonts ---
public static class Fonts
{
- // Dynamic font sizing.
+ // Values are calculated from the current device dimensions and are not
+ // copied from a mutable setting.
+ // --- Dynamic font sizing ---
public static string HtmlFontSize
{
get
{
- if (SamApplication.MinDeviceDimension > 2000) return "14pt";
- if (SamApplication.MinDeviceDimension > 1600) return "13pt";
- if (SamApplication.MinDeviceDimension > 1200) return "12pt";
- if (SamApplication.MinDeviceDimension > 1000) return "11pt";
+ if (SamApplication.MinDeviceDimensionPx > 2000) return "14pt";
+ if (SamApplication.MinDeviceDimensionPx > 1600) return "13pt";
+ if (SamApplication.MinDeviceDimensionPx > 1200) return "12pt";
+ if (SamApplication.MinDeviceDimensionPx > 1000) return "11pt";
return "10pt";
}
}
@@ -141,25 +150,25 @@ namespace Sarand.Net.Mobile.Maui.App
{
get
{
- if (SamApplication.MinDeviceDimension > 2000) return 1.75;
- if (SamApplication.MinDeviceDimension > 1600) return 1.50;
- if (SamApplication.MinDeviceDimension > 1200) return 1.25;
+ if (SamApplication.MinDeviceDimensionPx > 2000) return 1.75;
+ if (SamApplication.MinDeviceDimensionPx > 1600) return 1.50;
+ if (SamApplication.MinDeviceDimensionPx > 1200) return 1.25;
return 1.0;
}
}
}
- // Data display visuals.
+ // --- Data display visuals ---
public static class Data
{
- // Item list.
+ // --- Item list ---
public static class ItemList
{
public static double HeaderBorderWidth { get; set; } = 2.0;
- public static float HeaderBorderRadius = 6.0f;
- public static Color HeaderBorderColor = Sam.Visuals.Application.Bar.BackgroundColor;
- public static Color HeaderBackgroundColor = Color.FromArgb("#F0F0F0");
+ public static float HeaderBorderRadius { get; set; } = 6.0f;
+ public static Color HeaderBorderColor { get; set; } = Sam.Visuals.Application.Bar.BackgroundColor;
+ public static Color HeaderBackgroundColor { get; set; } = Color.FromArgb("#F0F0F0");
}
- // Associated items panel.
+ // --- Associated items panel ---
public static class AssociatedItems
{
public static Color CaptionBackgroundColor { get; set; } = Color.FromArgb("#becee4");
@@ -168,30 +177,30 @@ namespace Sarand.Net.Mobile.Maui.App
public static Color BackgroundColor { get; set; } = Color.FromArgb("#dbe4f0");
}
}
- // Form.
+ // --- Form ---
public static class Form
{
public static Color BackgroundColor { get; set; } = Color.FromArgb("#e9f6fb");
public static double GridRowSpacing { get; set; } = 4.0;
public static double GridColumnSpacing { get; set; } = 4.0;
- // Label.
+ // --- Label ---
public static class Label
{
public static Thickness Margin { get; set; } = new Thickness(8.0, 4.0, 8.0, 2.0);
}
- // Controls.
+ // --- Controls ---
public static class Controls
{
public static Thickness Padding { get; set; } = new Thickness(4.0, 2.0, 4.0, 1.0);
public static Color BackgroundColor { get; set; } = Color.FromArgb("#F8F8F8");
public static Color BorderColor { get; set; } = Color.FromArgb("#E0E0E0");
public static double BorderWidth { get; set; } = 0.5;
- // Native behaviour modified by SamHandler.
+ // --- Native behaviour modified by SamHandler ---
public static bool NativeNoBorder { get; set; } = false;
public static bool NativeNoUnderline { get; set; } = false;
public static bool NativeBackgroundClear { get; set; } = false;
}
- // Tab controls.
+ // --- Tab controls ---
public static class TabControl
{
public static Color HeaderBackgroundColor { get; set; } = Colors.Transparent;
@@ -202,7 +211,6 @@ namespace Sarand.Net.Mobile.Maui.App
}
}
- //-------------------------------------------------------------------
+ // --- The End ---
}
- //=======================================================================
}
diff --git a/SacsMobileMaui/Maui/App/SamApplication.cs b/SacsMobileMaui/Maui/App/SamApplication.cs
index 947bc94..9491c4d 100644
--- a/SacsMobileMaui/Maui/App/SamApplication.cs
+++ b/SacsMobileMaui/Maui/App/SamApplication.cs
@@ -1,4 +1,4 @@
-using Sarand.Net.Standard.Base.App;
+using Sarand.Net.Standard.Base.App;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -7,20 +7,19 @@ using System.Threading.Tasks;
namespace Sarand.Net.Mobile.Maui.App
{
- //=======================================================================
+ // --- Shared MAUI application base ---
public class SamApplication : Application
{
- //-------------------------------------------------------------------
- // Definitions.
+ // --- Data Members ---
- //-------------------------------------------------------------------
- // Data members.
- private Sam.Platform platform;
+ private readonly Sam.Platform platform;
+
+ // --- Construction ---
- //-------------------------------------------------------------------
protected SamApplication()
{
- // Determine platform.
+ // --- Platform ---
+
#if ANDROID
platform = Sam.Platform.Android;
#elif IOS
@@ -31,30 +30,30 @@ namespace Sarand.Net.Mobile.Maui.App
platform = Sam.Platform.Windows;
#endif
- // Log environment.
+ // --- Startup diagnostics ---
+
SaLogger.Debug("Platform: " + platform.ToString());
SaLogger.Debug("AppInfo.AppName: " + AppInfo.Name);
SaLogger.Debug("AppInfo.PackageName: " + AppInfo.PackageName);
SaLogger.Debug("AppInfo.Version: " + AppInfo.VersionString);
SaLogger.Debug("AppInfo.Build: " + AppInfo.BuildString);
- SaLogger.Debug("DeviceWidth: " + DeviceWidth);
- SaLogger.Debug("DeviceHeight: " + DeviceHeight);
+ SaLogger.Debug("DeviceWidth: " + DeviceWidthPx);
+ SaLogger.Debug("DeviceHeight: " + DeviceHeightPx);
SaLogger.Debug("DeviceDensity: " + DeviceDisplay.MainDisplayInfo.Density);
}
- //-------------------------------------------------------------------
- // Properties.
+ // --- Properties ---
public Sam.Platform Platform { get { return platform; } }
- // Device screen size and orientation.
- public static bool Landscape => DeviceWidth > DeviceHeight;
- public static double DeviceWidth => DeviceDisplay.MainDisplayInfo.Width;
- public static double DeviceHeight => DeviceDisplay.MainDisplayInfo.Height;
- public static double MinDeviceDimension => Math.Min(DeviceWidth, DeviceHeight);
- public static double MaxDeviceDimension => Math.Max(DeviceWidth, DeviceHeight);
+ // --- Display ---
- //-------------------------------------------------------------------
+ public static bool Landscape => DeviceWidthPx > DeviceHeightPx;
+ public static double DeviceWidthPx => DeviceDisplay.MainDisplayInfo.Width;
+ public static double DeviceHeightPx => DeviceDisplay.MainDisplayInfo.Height;
+ public static double MinDeviceDimensionPx => Math.Min(DeviceWidthPx, DeviceHeightPx);
+ public static double MaxDeviceDimensionPx => Math.Max(DeviceWidthPx, DeviceHeightPx);
+
+ // --- The End ---
}
- //=======================================================================
}
diff --git a/SacsMobileMaui/Maui/Base/SamComponents.cs b/SacsMobileMaui/Maui/Base/SamComponents.cs
index 868951a..d24bc25 100644
--- a/SacsMobileMaui/Maui/Base/SamComponents.cs
+++ b/SacsMobileMaui/Maui/Base/SamComponents.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -41,7 +41,7 @@ namespace Sarand.Net.Mobile.Maui.Base
//-------------------------------------------------------------------
// C o n t r o l A c t i v i t y
//-------------------------------------------------------------------
- protected virtual void SetControlActivity()
+ protected virtual void SetControlActivity(bool enabled)
{
}
protected virtual void SetControlsReadOnly()
diff --git a/SacsMobileMaui/Maui/Consoles/SamWebServiceConsole.cs b/SacsMobileMaui/Maui/Consoles/SamWebServiceConsole.cs
index eee48d3..b84fec6 100644
--- a/SacsMobileMaui/Maui/Consoles/SamWebServiceConsole.cs
+++ b/SacsMobileMaui/Maui/Consoles/SamWebServiceConsole.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
diff --git a/SacsMobileMaui/Maui/Controls/ISamControl.cs b/SacsMobileMaui/Maui/Controls/ISamControl.cs
new file mode 100644
index 0000000..4179f57
--- /dev/null
+++ b/SacsMobileMaui/Maui/Controls/ISamControl.cs
@@ -0,0 +1,10 @@
+namespace Sarand.Net.Mobile.Maui.Controls
+{
+ // --- Definitions ---
+ public interface ISamControl
+ {
+ void SetControlActivity(bool enabled);
+
+ // --- The End ---
+ }
+}
diff --git a/SacsMobileMaui/Maui/Controls/ISamNativeControlStyle.cs b/SacsMobileMaui/Maui/Controls/ISamNativeControlStyle.cs
new file mode 100644
index 0000000..3b33b85
--- /dev/null
+++ b/SacsMobileMaui/Maui/Controls/ISamNativeControlStyle.cs
@@ -0,0 +1,19 @@
+namespace Sarand.Net.Mobile.Maui.Controls
+{
+ // --- Native control styling ---
+ ///
+ /// Exposes native styles applied when a MAUI handler is mapped. These plain properties
+ /// are read during handler mapping and changes made afterward do not automatically reapply them.
+ ///
+ public interface ISamNativeControlStyle
+ {
+ /// Removes the native control border where supported.
+ bool NativeNoBorder { get; set; }
+ /// Removes an Android-style underline where supported; other platforms may have no equivalent.
+ bool NativeNoUnderline { get; set; }
+ /// Makes the native control background transparent where supported.
+ bool NativeBackgroundClear { get; set; }
+
+ // --- The End ---
+ }
+}
diff --git a/SacsMobileMaui/Maui/Controls/Panels/SamCheckBoxPanel.cs b/SacsMobileMaui/Maui/Controls/Panels/SamCheckBoxPanel.cs
index 48210cc..ccbab0b 100644
--- a/SacsMobileMaui/Maui/Controls/Panels/SamCheckBoxPanel.cs
+++ b/SacsMobileMaui/Maui/Controls/Panels/SamCheckBoxPanel.cs
@@ -1,4 +1,4 @@
-using Sarand.Net.Mobile.Maui.Controls.Views;
+using Sarand.Net.Mobile.Maui.Controls.Views;
using Sarand.Net.Standard.Base.Utils;
using System;
using System.Collections.Generic;
@@ -9,19 +9,15 @@ using System.Threading.Tasks;
namespace Sarand.Net.Mobile.Maui.Controls.Panels
{
- //=======================================================================
public class SamCheckBoxPanel : SamControlPanel
{
- //-------------------------------------------------------------------
- // Definitions.
+ // --- Data Members ---
- //-------------------------------------------------------------------
- // Data members.
private readonly SamCheckBox checkbox = new SamCheckBox() { };
private readonly TapGestureRecognizer gestureSuffixTap = new TapGestureRecognizer() { };
- //-------------------------------------------------------------------
- // Construction.
+ // --- Construction ---
+
public SamCheckBoxPanel()
{
// View configuration.
@@ -40,11 +36,11 @@ namespace Sarand.Net.Mobile.Maui.Controls.Panels
LabelSuffix.GestureRecognizers.Add(gestureSuffixTap);
ConfigureComponents();
- SetControlActivity();
+ SetControlActivity(IsEnabled);
}
- //-------------------------------------------------------------------
- // Properties.
+ // --- Properties ---
+
protected override View ControlView { get { return checkbox; } }
public bool IsChecked
{
@@ -57,41 +53,16 @@ namespace Sarand.Net.Mobile.Maui.Controls.Panels
set { checkbox.HorizontalOptions = value; ReadOnlyLabel.HorizontalOptions = checkbox.HorizontalOptions; }
}
- //-------------------------------------------------------------------
- // C o n f i g u r e C o m p o n e n t s
- //-------------------------------------------------------------------
- /// Control configuration that can be changed dynamically.
- public override void ConfigureComponents()
- {
- base.ConfigureComponents();
- }
+ // --- Control events ---
- //-------------------------------------------------------------------
- // C o n t r o l A c t i v i t y
- //-------------------------------------------------------------------
- public override void SetControlActivity()
- {
- base.SetControlActivity();
- SetControlsReadOnly();
- }
- public override void SetControlsReadOnly()
- {
- base.SetControlsReadOnly();
- }
-
- //-------------------------------------------------------------------
- // C o n t r o l E v e n t s
- //-------------------------------------------------------------------
private void Entry_Focused(object? sender, FocusEventArgs e)
{
Control_Focused(sender, e);
}
- //-------------------------------------------------------------------
private void Entry_Unfocused(object? sender, FocusEventArgs e)
{
Control_Unfocused(sender, e);
}
- //-------------------------------------------------------------------
// Checked changed.
public event EventHandler? CheckedChanged;
private void Checkbox_CheckedChanged(object? sender, CheckedChangedEventArgs e)
@@ -106,42 +77,6 @@ namespace Sarand.Net.Mobile.Maui.Controls.Panels
checkbox.IsChecked = !checkbox.IsChecked;
}
- //-------------------------------------------------------------------
- // V i e w E v e n t s
- //-------------------------------------------------------------------
- protected override void OnParentSet()
- {
- base.OnParentSet();
- }
-
- //-------------------------------------------------------------------
- protected override void OnPropertyChanging([CallerMemberName] string propertyName = "")
- {
- base.OnPropertyChanging(propertyName);
- }
- protected override void OnPropertyChanged([CallerMemberName] string propertyName = "")
- {
- base.OnPropertyChanged(propertyName);
- //Logger.Debug(GetType().Name + ".OnPropertyChanged Name=" + propertyName);
- }
-
- //-------------------------------------------------------------------
- protected override void OnChildAdded(Element child)
- {
- base.OnChildAdded(child);
- }
- protected override void OnChildRemoved(Element child, int oldLogicalIndex)
- {
- base.OnChildRemoved(child, oldLogicalIndex);
- }
-
- //-------------------------------------------------------------------
- protected override void OnSizeAllocated(double width, double height)
- {
- base.OnSizeAllocated(width, height);
- }
-
- //-------------------------------------------------------------------
+ // --- The End ---
}
- //=======================================================================
}
diff --git a/SacsMobileMaui/Maui/Controls/Panels/SamControlPanel.cs b/SacsMobileMaui/Maui/Controls/Panels/SamControlPanel.cs
index 7d780a0..c9575c6 100644
--- a/SacsMobileMaui/Maui/Controls/Panels/SamControlPanel.cs
+++ b/SacsMobileMaui/Maui/Controls/Panels/SamControlPanel.cs
@@ -1,4 +1,4 @@
-using Sarand.Net.Mobile.Maui.App;
+using Sarand.Net.Mobile.Maui.App;
using Sarand.Net.Mobile.Maui.Views;
using Sarand.Net.Standard.Base.Utils;
using System;
@@ -10,14 +10,10 @@ using System.Threading.Tasks;
namespace Sarand.Net.Mobile.Maui.Controls.Views
{
- //=======================================================================
public abstract class SamControlPanel : SamContentView
{
- //-------------------------------------------------------------------
- // Definitions.
+ // --- Data Members ---
- //-------------------------------------------------------------------
- // Data members.
// Components.
private HorizontalStackLayout controlLayout = new HorizontalStackLayout();
private SamContentView controlBorder = new SamContentView();
@@ -27,8 +23,8 @@ namespace Sarand.Net.Mobile.Maui.Controls.Views
private Color controlBorderColor = Sam.Visuals.Form.Controls.BorderColor;
private Color controlBackgroundColor = Sam.Visuals.Form.Controls.BackgroundColor;
- //-------------------------------------------------------------------
- // Construction.
+ // --- Construction ---
+
protected SamControlPanel()
{
// Control layout: [Border[Panel]] [Suffix].
@@ -36,14 +32,12 @@ namespace Sarand.Net.Mobile.Maui.Controls.Views
controlLayout.Add(controlBorder);
controlLayout.Add(LabelSuffix);
- // Main layout.
+ // --- Main layout ---
Content = controlLayout;
-
- SetControlActivity();
}
- //-------------------------------------------------------------------
- // Properties.
+ // --- Properties ---
+
// Label.
public SamLabel Label { get; } = new SamLabel() { Margin = Sam.Visuals.Form.Label.Margin };
@@ -92,9 +86,8 @@ namespace Sarand.Net.Mobile.Maui.Controls.Views
set { if (ReadOnlyLabel.Text.Equals(value)) return; ReadOnlyLabel.Text = value; }
}
- //-------------------------------------------------------------------
- // C o n f i g u r e C o m p o n e n t s
- //-------------------------------------------------------------------
+ // --- Component configuration ---
+
/// Control configuration that can be changed dynamically.
public override void ConfigureComponents()
{
@@ -104,13 +97,8 @@ namespace Sarand.Net.Mobile.Maui.Controls.Views
controlPanel.BackgroundColor = controlBackgroundColor;
}
- //-------------------------------------------------------------------
- // C o n t r o l A c t i v i t y
- //-------------------------------------------------------------------
- public override void SetControlActivity()
- {
- base.SetControlActivity();
- }
+ // --- Control activity ---
+
public override void SetControlsReadOnly()
{
base.SetControlsReadOnly();
@@ -118,24 +106,21 @@ namespace Sarand.Net.Mobile.Maui.Controls.Views
else controlPanel.Content = ControlView;
}
- //-------------------------------------------------------------------
- // C o n t r o l E v e n t s
- //-------------------------------------------------------------------
+ // --- Control events ---
+
public new event EventHandler? Focused;
protected void Control_Focused(object? sender, FocusEventArgs e)
{
if (Focused != null) Focused.Invoke(sender, e);
}
- //-------------------------------------------------------------------
public new event EventHandler? Unfocused;
protected void Control_Unfocused(object? sender, FocusEventArgs e)
{
if (Unfocused != null) Unfocused.Invoke(sender, e);
}
- //-------------------------------------------------------------------
- // V i e w E v e n t s
- //-------------------------------------------------------------------
+ // --- View events ---
+
protected override void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
base.OnPropertyChanged(propertyName);
@@ -156,7 +141,6 @@ namespace Sarand.Net.Mobile.Maui.Controls.Views
}
}
- //-------------------------------------------------------------------
+ // --- The End ---
}
- //=======================================================================
}
diff --git a/SacsMobileMaui/Maui/Controls/Panels/SamEntryPanel.cs b/SacsMobileMaui/Maui/Controls/Panels/SamEntryPanel.cs
index 6a6ee41..35b50c1 100644
--- a/SacsMobileMaui/Maui/Controls/Panels/SamEntryPanel.cs
+++ b/SacsMobileMaui/Maui/Controls/Panels/SamEntryPanel.cs
@@ -1,4 +1,4 @@
-using Sarand.Net.Standard.Base.Utils;
+using Sarand.Net.Standard.Base.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -8,18 +8,14 @@ using System.Threading.Tasks;
namespace Sarand.Net.Mobile.Maui.Controls.Views
{
- //=======================================================================
public class SamEntryPanel : SamControlPanel
{
- //-------------------------------------------------------------------
- // Definitions.
+ // --- Data Members ---
- //-------------------------------------------------------------------
- // Data members.
private readonly SamEntry entry = new SamEntry() { HorizontalOptions = LayoutOptions.Fill };
- //-------------------------------------------------------------------
- // Construction.
+ // --- Construction ---
+
public SamEntryPanel()
{
// View configuration.
@@ -34,11 +30,12 @@ namespace Sarand.Net.Mobile.Maui.Controls.Views
entry.TextChanged += Entry_TextChanged;
entry.Completed += Entry_Completed;
- SetControlActivity();
+ ConfigureComponents();
+ SetControlActivity(IsEnabled);
}
- //-------------------------------------------------------------------
- // Properties.
+ // --- Properties ---
+
protected override View ControlView { get { return entry; } }
public int MaxLength
{
@@ -86,41 +83,16 @@ namespace Sarand.Net.Mobile.Maui.Controls.Views
set { entry.HorizontalTextAlignment = value; ReadOnlyLabel.HorizontalTextAlignment = entry.HorizontalTextAlignment; }
}
- //-------------------------------------------------------------------
- // C o n f i g u r e C o m p o n e n t s
- //-------------------------------------------------------------------
- /// Control configuration that can be changed dynamically.
- public override void ConfigureComponents()
- {
- base.ConfigureComponents();
- }
+ // --- Control events ---
- //-------------------------------------------------------------------
- // C o n t r o l A c t i v i t y
- //-------------------------------------------------------------------
- public override void SetControlActivity()
- {
- base.SetControlActivity();
- SetControlsReadOnly();
- }
- public override void SetControlsReadOnly()
- {
- base.SetControlsReadOnly();
- }
-
- //-------------------------------------------------------------------
- // C o n t r o l E v e n t s
- //-------------------------------------------------------------------
private void Entry_Focused(object? sender, FocusEventArgs e)
{
Control_Focused(sender, e);
}
- //-------------------------------------------------------------------
private void Entry_Unfocused(object? sender, FocusEventArgs e)
{
Control_Unfocused(sender, e);
}
- //-------------------------------------------------------------------
// Text changed.
public event EventHandler? TextChanged;
private void Entry_TextChanged(object? sender, TextChangedEventArgs e)
@@ -129,7 +101,6 @@ namespace Sarand.Net.Mobile.Maui.Controls.Views
if (ReadOnly) return;
if (TextChanged != null) TextChanged.Invoke(sender, e);
}
- //-------------------------------------------------------------------
// Completed.
public event EventHandler? Completed;
private void Entry_Completed(object? sender, EventArgs e)
@@ -138,42 +109,6 @@ namespace Sarand.Net.Mobile.Maui.Controls.Views
if (Completed != null) Completed.Invoke(sender, e);
}
- //-------------------------------------------------------------------
- // V i e w E v e n t s
- //-------------------------------------------------------------------
- protected override void OnParentSet()
- {
- base.OnParentSet();
- }
-
- //-------------------------------------------------------------------
- protected override void OnPropertyChanging([CallerMemberName] string propertyName = "")
- {
- base.OnPropertyChanging(propertyName);
- }
- protected override void OnPropertyChanged([CallerMemberName] string propertyName = "")
- {
- base.OnPropertyChanged(propertyName);
- //Logger.Debug(GetType().Name + ".OnPropertyChanged Name=" + propertyName);
- }
-
- //-------------------------------------------------------------------
- protected override void OnChildAdded(Element child)
- {
- base.OnChildAdded(child);
- }
- protected override void OnChildRemoved(Element child, int oldLogicalIndex)
- {
- base.OnChildRemoved(child, oldLogicalIndex);
- }
-
- //-------------------------------------------------------------------
- protected override void OnSizeAllocated(double width, double height)
- {
- base.OnSizeAllocated(width, height);
- }
-
- //-------------------------------------------------------------------
+ // --- The End ---
}
- //=======================================================================
}
diff --git a/SacsMobileMaui/Maui/Controls/SamButton.cs b/SacsMobileMaui/Maui/Controls/SamButton.cs
index a6ef2f1..71031c4 100644
--- a/SacsMobileMaui/Maui/Controls/SamButton.cs
+++ b/SacsMobileMaui/Maui/Controls/SamButton.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -6,31 +6,30 @@ using System.Threading.Tasks;
namespace Sarand.Net.Mobile.Maui.Controls
{
- //=======================================================================
- public class SamButton : Button
+ ///
+ /// Application button extension point. It currently adds no behavior beyond
+ /// the MAUI contract.
+ ///
+ public class SamButton : Button, ISamControl
{
- //-------------------------------------------------------------------
- // Definitions.
+ // --- Construction ---
- //-------------------------------------------------------------------
- // Data members.
-
- //-------------------------------------------------------------------
- // Construction.
public SamButton()
{
DefaultFontSize = FontSize;
}
- //-------------------------------------------------------------------
- // Properties.
+ // --- Component state ---
+
+ public void SetControlActivity(bool enabled)
+ {
+ if (IsEnabled != enabled) IsEnabled = enabled;
+ }
+
+ // --- Properties ---
+
public double DefaultFontSize { get; }
- //-------------------------------------------------------------------
- // C o n t r o l E v e n t s
- //-------------------------------------------------------------------
-
- //-------------------------------------------------------------------
+ // --- The End ---
}
- //=======================================================================
}
diff --git a/SacsMobileMaui/Maui/Controls/SamCheckBox.cs b/SacsMobileMaui/Maui/Controls/SamCheckBox.cs
index 04a4b93..9ca6ae8 100644
--- a/SacsMobileMaui/Maui/Controls/SamCheckBox.cs
+++ b/SacsMobileMaui/Maui/Controls/SamCheckBox.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -6,28 +6,25 @@ using System.Threading.Tasks;
namespace Sarand.Net.Mobile.Maui.Controls
{
- //======================================================================
- public class SamCheckBox : CheckBox
+ ///
+ /// Application check-box extension point. It currently adds no behavior
+ /// beyond the MAUI contract.
+ ///
+ public class SamCheckBox : CheckBox, ISamControl
{
- //-------------------------------------------------------------------
- // Definitions.
+ // --- Construction ---
- //-------------------------------------------------------------------
- // Data members.
-
- //-------------------------------------------------------------------
- // Construction.
public SamCheckBox()
{
}
- //-------------------------------------------------------------------
- // Properties.
+ // --- Component state ---
- //-------------------------------------------------------------------
- // Control events.
+ public void SetControlActivity(bool enabled)
+ {
+ if (IsEnabled != enabled) IsEnabled = enabled;
+ }
- //-------------------------------------------------------------------
+ // --- The End ---
}
- //======================================================================
}
diff --git a/SacsMobileMaui/Maui/Controls/SamDatePicker.cs b/SacsMobileMaui/Maui/Controls/SamDatePicker.cs
index bea61e6..f76987a 100644
--- a/SacsMobileMaui/Maui/Controls/SamDatePicker.cs
+++ b/SacsMobileMaui/Maui/Controls/SamDatePicker.cs
@@ -1,4 +1,5 @@
using Sarand.Net.Mobile.Maui.Layouts;
+using Sarand.Net.Mobile.Maui.Logic;
using Sarand.Net.Mobile.Maui.Views;
using Sarand.Net.Standard.Base.Utils;
using System;
@@ -9,24 +10,17 @@ using System.Threading.Tasks;
namespace Sarand.Net.Mobile.Maui.Controls
{
- //=======================================================================
public class SamDatePicker : SamContentView
{
- //-------------------------------------------------------------------
- // Definitions.
-
- //-------------------------------------------------------------------
- // Data members.
+ // --- Data Members ---
private bool allowInvalidDate = false;
- private bool invalidDate = true;
- private DateTime previousDate = DateTime.MinValue;
+ private SamDateValueState dateState = new SamDateValueState();
private SamStackLayout controlLayout = new SamStackLayout() { Orientation = StackOrientation.Horizontal, HorizontalOptions = LayoutOptions.Fill };
private DatePicker pickerDate = new DatePicker() { IsVisible = false };
private SamEntry entryDate = new SamEntry() { HorizontalOptions = LayoutOptions.FillAndExpand, VerticalOptions = LayoutOptions.Fill };
private SamLabel labelResetDate = new SamLabel() { Text = "X", FontAttributes = FontAttributes.Bold, TextColor = Colors.Red, HorizontalOptions = LayoutOptions.Center, VerticalTextAlignment = TextAlignment.Center };
- //-------------------------------------------------------------------
- // Construction.
+ // --- Construction ---
public SamDatePicker()
{
// Initialise controls.
@@ -58,17 +52,16 @@ namespace Sarand.Net.Mobile.Maui.Controls
RefreshDateDisplay();
}
- //-------------------------------------------------------------------
- // Properties.
- // Configuration.
+ // --- Properties ---
public Boolean AllowInvalid
{
get { return allowInvalidDate; }
set
{
- if (allowInvalidDate = value) return;
+ if (allowInvalidDate == value) return;
allowInvalidDate = value;
- if (!allowInvalidDate) invalidDate = false;
+ if (!allowInvalidDate && dateState.IsInvalid)
+ dateState.SetDate(pickerDate.Date ?? DateTime.Today);
RefreshDateDisplay();
}
}
@@ -91,34 +84,29 @@ namespace Sarand.Net.Mobile.Maui.Controls
get { return pickerDate.MaximumDate ?? DateTime.MaxValue; }
set { pickerDate.MaximumDate = value; }
}
- //-------------------------------------------------------------------
- // Date value.
+ // --- Date value ---
public DateTime Date
{
get
{
- if (invalidDate) return DateTime.MinValue;
- return pickerDate.Date ?? DateTime.MinValue;
+ return dateState.Date;
}
set
{
- if (Date.Equals(value)) return;
- if (!DateUtil.IsValid(value))
+ if (!dateState.SetDate(value)) return;
+ if (dateState.IsInvalid)
{
- invalidDate = true;
pickerDate.Date = DateTime.Today;
}
else
{
- invalidDate = false;
pickerDate.Date = value;
}
- previousDate = value;
+ RefreshDateDisplay();
}
}
- public String FormattedDate { get { return !invalidDate ? DateUtil.Format(Date, pickerDate.Format) : ""; } }
- //-------------------------------------------------------------------
- // Font.
+ public String FormattedDate { get { return !dateState.IsInvalid ? DateUtil.Format(Date, pickerDate.Format) : ""; } }
+ // --- Font ---
public double DefaultFontSize { get; }
public double FontSize
{
@@ -161,8 +149,7 @@ namespace Sarand.Net.Mobile.Maui.Controls
}
}
- //-------------------------------------------------------------------
- // Utilities.
+ // --- Utilities ---
private void RefreshDateDisplay()
{
if (allowInvalidDate)
@@ -178,44 +165,36 @@ namespace Sarand.Net.Mobile.Maui.Controls
labelResetDate.IsVisible = false;
}
String dateValue = "";
- if (!invalidDate)
+ if (!dateState.IsInvalid)
dateValue = DateUtil.Format(Date, pickerDate.Format);
entryDate.Text = dateValue;
}
- //-------------------------------------------------------------------
- // C o n t r o l E v e n t s
- //-------------------------------------------------------------------
+ // --- Control events ---
private void PickerDate_DateSelected(object? sender, DateChangedEventArgs e)
{
// Date has changed in control.
- invalidDate = !DateUtil.IsValid(e.NewDate);
+ dateState.SetDate(e.NewDate ?? DateTime.MinValue);
RefreshDateDisplay();
if (DateSelected != null) DateSelected.Invoke(sender, e);
}
public event EventHandler? DateSelected;
- //-------------------------------------------------------------------
private void EntryDate_Focused(object? sender, FocusEventArgs e)
{
// Control has gained focus.
entryDate.Unfocus();
pickerDate.Focus();
- invalidDate = false;
+ dateState.SetDate(pickerDate.Date ?? DateTime.Today);
RefreshDateDisplay();
}
- //-------------------------------------------------------------------
private void LabelValidDate_Tapped(object? sender, EventArgs e)
{
// 'Valid' label tapped.
- if (invalidDate) return;
- invalidDate = true;
- DateTime oldDate = previousDate;
+ if (!dateState.TryInvalidate(out DateTime oldDate)) return;
RefreshDateDisplay();
if (DateSelected != null) DateSelected.Invoke(sender, new DateChangedEventArgs(oldDate, Date));
- previousDate = Date;
}
- //-------------------------------------------------------------------
+ // --- The End ---
}
- //=======================================================================
}
diff --git a/SacsMobileMaui/Maui/Controls/SamDateTimePicker.cs b/SacsMobileMaui/Maui/Controls/SamDateTimePicker.cs
index 443cdb9..c6cf769 100644
--- a/SacsMobileMaui/Maui/Controls/SamDateTimePicker.cs
+++ b/SacsMobileMaui/Maui/Controls/SamDateTimePicker.cs
@@ -9,22 +9,18 @@ using System.Threading.Tasks;
namespace Sarand.Net.Mobile.Maui.Controls
{
- //=======================================================================
public class SamDateTimePicker : SamContentView
{
- //-------------------------------------------------------------------
- // Definitions.
+ // --- Data Members ---
+
// Control layout.
private SamStackLayout layoutControl = new SamStackLayout() { Orientation = StackOrientation.Horizontal };
private SamDatePicker pickerDate = new SamDatePicker();
private SamLabel labelTimePrefix = new SamLabel();
private SamTimePicker pickerTime = new SamTimePicker();
- //-------------------------------------------------------------------
- // Data members.
+ // --- Construction ---
- //-------------------------------------------------------------------
- // Construction.
public SamDateTimePicker()
{
DefaultFontSize = pickerDate.FontSize;
@@ -39,8 +35,8 @@ namespace Sarand.Net.Mobile.Maui.Controls
pickerTime.TimeChanged += PickerTime_TimeChanged;
}
- //-------------------------------------------------------------------
- // Properties.
+ // --- Properties ---
+
public string DateFormat
{
get { return pickerDate.Format; }
@@ -50,6 +46,11 @@ namespace Sarand.Net.Mobile.Maui.Controls
pickerDate.Format = value;
}
}
+ public bool AllowInvalid
+ {
+ get { return pickerDate.AllowInvalid; }
+ set { pickerDate.AllowInvalid = value; }
+ }
public DateTime MinimumDate
{
get { return pickerDate.MinimumDate; }
@@ -69,7 +70,7 @@ namespace Sarand.Net.Mobile.Maui.Controls
pickerTime.Format = value;
}
}
- // Control value.
+ // --- Control value ---
public DateTime DateTime
{
get { return pickerDate.Date.Date + (pickerTime.Time ?? TimeSpan.Zero); }
@@ -81,8 +82,15 @@ namespace Sarand.Net.Mobile.Maui.Controls
}
}
public String DateTimeDelim { get; set; } = " ";
- public String FormattedDateTime { get { return pickerDate.FormattedDate + DateTimeDelim + pickerTime.FormattedTime; } }
- // Styling.
+ public String FormattedDateTime
+ {
+ get
+ {
+ if (StringUtil.IsEmpty(pickerDate.FormattedDate)) return "";
+ return pickerDate.FormattedDate + DateTimeDelim + pickerTime.FormattedTime;
+ }
+ }
+ // --- Styling ---
public double DefaultFontSize { get; }
public double FontSize
{
@@ -101,9 +109,8 @@ namespace Sarand.Net.Mobile.Maui.Controls
set { value = StringUtil.TrimAll(value); if (labelTimePrefix.Text.Equals(value)) return; labelTimePrefix.Text = value; ConfigureComponents(); }
}
- //-------------------------------------------------------------------
- // C o n f i g u r e C o m p o n e n t s
- //-------------------------------------------------------------------
+ // --- Component configuration ---
+
public override void ConfigureComponents()
{
base.ConfigureComponents();
@@ -127,34 +134,30 @@ namespace Sarand.Net.Mobile.Maui.Controls
}
}
- //-------------------------------------------------------------------
- // C o n t r o l A c t i v i t y
- //-------------------------------------------------------------------
- public override void SetControlActivity()
+ // --- Control activity ---
+
+ public override void SetControlActivity(bool enabled)
{
- base.SetControlActivity();
+ base.SetControlActivity(enabled);
}
public override void SetControlsReadOnly()
{
base.SetControlsReadOnly();
}
- //-------------------------------------------------------------------
- // C o n t r o l E v e n t s
- //-------------------------------------------------------------------
+ // --- Control events ---
+
private void PickerDate_DateSelected(object? sender, DateChangedEventArgs e)
{
if (DateSelected != null) DateSelected.Invoke(sender, e);
}
public event EventHandler? DateSelected;
- //-------------------------------------------------------------------
private void PickerTime_TimeChanged(object? sender, SamTimePicker.TimeChangedEventArgs e)
{
if (TimeChanged != null) TimeChanged.Invoke(sender, e);
}
public event EventHandler? TimeChanged;
- //-------------------------------------------------------------------
+ // --- The End ---
}
- //=======================================================================
}
diff --git a/SacsMobileMaui/Maui/Controls/SamEditor.cs b/SacsMobileMaui/Maui/Controls/SamEditor.cs
index 7a83494..893e0ac 100644
--- a/SacsMobileMaui/Maui/Controls/SamEditor.cs
+++ b/SacsMobileMaui/Maui/Controls/SamEditor.cs
@@ -1,4 +1,4 @@
-using Sarand.Net.Mobile.Maui.App;
+using Sarand.Net.Mobile.Maui.App;
using Sarand.Net.Standard.Base.Utils;
using System;
using System.Collections.Generic;
@@ -8,19 +8,15 @@ using System.Threading.Tasks;
namespace Sarand.Net.Mobile.Maui.Controls
{
- //=======================================================================
- public class SamEditor : Editor
+ public class SamEditor : Editor, ISamNativeControlStyle, ISamControl
{
- //-------------------------------------------------------------------
- // Definitions.
+ // --- Data Members ---
- //-------------------------------------------------------------------
- // Data members.
private bool trimTextOnCompletion = true;
private int NumberOfLinesPrevious = 0;
- //-------------------------------------------------------------------
- // Construction.
+ // --- Construction ---
+
public SamEditor()
{
DefaultFontSize = FontSize;
@@ -29,8 +25,15 @@ namespace Sarand.Net.Mobile.Maui.Controls
Completed += SamEditor_Completed;
}
- //-------------------------------------------------------------------
- // Properties.
+ // --- Component state ---
+
+ public void SetControlActivity(bool enabled)
+ {
+ if (IsEnabled != enabled) IsEnabled = enabled;
+ }
+
+ // --- Properties ---
+
public double DefaultFontSize { get; }
@@ -44,14 +47,13 @@ namespace Sarand.Net.Mobile.Maui.Controls
}
}
- // Native behaviour modified by SamHandler.
+ // --- Native styling ---
public bool NativeNoBorder { get; set; } = Sam.Visuals.Form.Controls.NativeNoBorder;
public bool NativeNoUnderline { get; set; } = Sam.Visuals.Form.Controls.NativeNoUnderline;
public bool NativeBackgroundClear { get; set; } = Sam.Visuals.Form.Controls.NativeBackgroundClear;
- //-------------------------------------------------------------------
- // C o n t r o l E v e n t s
- //-------------------------------------------------------------------
+ // --- Control events ---
+
// Key Press event is not supported directly in Xamarin.
// Requires O/S specific implementation.
// See: Sarand.LogisticsMgr.Mobile.Droid.Forms.Renderers.SlmEditorRenderer
@@ -60,7 +62,6 @@ namespace Sarand.Net.Mobile.Maui.Controls
// Resize control based on entered text.
InvalidateMeasure();
}
- //-------------------------------------------------------------------
private void SamEditor_TextChanged(object? sender, TextChangedEventArgs e)
{
// If the number of lines of text has changed, resize the control.
@@ -78,7 +79,6 @@ namespace Sarand.Net.Mobile.Maui.Controls
InvalidateMeasure();
}
- //-------------------------------------------------------------------
+ // --- The End ---
}
- //=======================================================================
}
diff --git a/SacsMobileMaui/Maui/Controls/SamEntry.cs b/SacsMobileMaui/Maui/Controls/SamEntry.cs
index 2738565..9ffb6d9 100644
--- a/SacsMobileMaui/Maui/Controls/SamEntry.cs
+++ b/SacsMobileMaui/Maui/Controls/SamEntry.cs
@@ -1,4 +1,5 @@
-using Sarand.Net.Mobile.Maui.App;
+using Sarand.Net.Mobile.Maui.App;
+using Sarand.Net.Mobile.Maui.Logic;
using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Utils;
using System;
@@ -10,11 +11,10 @@ using System.Threading.Tasks;
namespace Sarand.Net.Mobile.Maui.Controls
{
- //=======================================================================
- public class SamEntry : Entry
+ public class SamEntry : Entry, ISamNativeControlStyle, ISamControl
{
- //-------------------------------------------------------------------
- // Definitions.
+ // --- Definitions ---
+
public enum TextCaseType
{
Normal,
@@ -23,16 +23,16 @@ namespace Sarand.Net.Mobile.Maui.Controls
Title
}
- //-------------------------------------------------------------------
- // Data members.
+ // --- Data Members ---
+
private bool trimTextOnCompletion = true;
private TextInfo textInfo = CultureInfo.CurrentCulture.TextInfo;
private TextCaseType textCase = TextCaseType.Normal;
private bool numericOnly = false;
private byte decimals = 0;
- //-------------------------------------------------------------------
- // Construction.
+ // --- Construction ---
+
public SamEntry()
{
DefaultFontSize = FontSize;
@@ -40,8 +40,15 @@ namespace Sarand.Net.Mobile.Maui.Controls
Completed += SamEntry_Completed;
}
- //-------------------------------------------------------------------
- // Properties.
+ // --- Component state ---
+
+ public void SetControlActivity(bool enabled)
+ {
+ if (IsEnabled != enabled) IsEnabled = enabled;
+ }
+
+ // --- Properties ---
+
public bool TrimText
{
get { return trimTextOnCompletion; }
@@ -95,52 +102,26 @@ namespace Sarand.Net.Mobile.Maui.Controls
}
}
- // Native behaviour modified by SamHandler.
+ // --- Native styling ---
public bool NativeNoBorder { get; set; } = Sam.Visuals.Form.Controls.NativeNoBorder;
public bool NativeNoUnderline { get; set; } = Sam.Visuals.Form.Controls.NativeNoUnderline;
public bool NativeBackgroundClear { get; set; } = Sam.Visuals.Form.Controls.NativeBackgroundClear;
- //-------------------------------------------------------------------
- // F o r m a t T e x t
- //-------------------------------------------------------------------
+ // --- Format text ---
+
private void FormatText(bool trimText = false)
{
String fn = GetType().Name + ".FormatText";
String originalText = Text;
- String formattedText = originalText;
- if (StringUtil.IsEmpty(formattedText)) return;
- if (trimText)
- formattedText = StringUtil.TrimAll(formattedText);
-
- if (numericOnly)
+ SamEntryTextFormatOptions options = new SamEntryTextFormatOptions()
{
- if (decimals > 0)
- {
- decimal value = StringUtil.ToDecimal(formattedText);
- if (value != 0.0m)
- formattedText = value.ToString("N" + decimals);
- else if (!formattedText.Equals("0"))
- formattedText = "";
- }
- else
- {
- long value = StringUtil.ToLong(formattedText);
- if (value != 0)
- formattedText = value.ToString();
- else if (!formattedText.Equals("0"))
- formattedText = "";
- }
- }
- else
- {
- if (textCase == TextCaseType.Upper)
- formattedText = textInfo.ToUpper(formattedText);
- else if (textCase == TextCaseType.Lower)
- formattedText = textInfo.ToLower(formattedText);
- else if (textCase == TextCaseType.Title)
- formattedText =
- StringUtil.ToTitleCase(formattedText, textInfo);
- }
+ TextCase = textCase,
+ NumericOnly = numericOnly,
+ Decimals = decimals,
+ TrimText = trimText,
+ TextInfo = textInfo
+ };
+ String formattedText = SamEntryTextFormatter.Format(originalText, options);
if (!originalText.Equals(formattedText))
{
@@ -149,9 +130,8 @@ namespace Sarand.Net.Mobile.Maui.Controls
}
}
- //-------------------------------------------------------------------
- // C o n t r o l E v e n t s
- //-------------------------------------------------------------------
+ // --- Control events ---
+
private void SamEntry_TextChanged(object? sender, TextChangedEventArgs e)
{
if (FormatTextOnChange) FormatText();
@@ -161,7 +141,6 @@ namespace Sarand.Net.Mobile.Maui.Controls
FormatText(trimTextOnCompletion);
}
- //-------------------------------------------------------------------
+ // --- The End ---
}
- //=======================================================================
}
diff --git a/SacsMobileMaui/Maui/Controls/SamImageButton.cs b/SacsMobileMaui/Maui/Controls/SamImageButton.cs
index 2ee174f..c163442 100644
--- a/SacsMobileMaui/Maui/Controls/SamImageButton.cs
+++ b/SacsMobileMaui/Maui/Controls/SamImageButton.cs
@@ -1,4 +1,4 @@
-using Sarand.Net.Standard.Base.App;
+using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Utils;
using System;
using System.Collections.Generic;
@@ -8,33 +8,32 @@ using System.Threading.Tasks;
namespace Sarand.Net.Mobile.Maui.Controls
{
- //=======================================================================
- public class SamImageButton : ImageButton
+ ///
+ /// Application image-button extension point. It currently adds no active
+ /// behavior beyond the MAUI contract.
+ ///
+ public class SamImageButton : ImageButton, ISamControl
{
- //-------------------------------------------------------------------
- // Definitions.
+ // --- Construction ---
- //-------------------------------------------------------------------
- // Data members.
-
- //-------------------------------------------------------------------
- // Construction.
public SamImageButton()
{
- //Clicked += Button_Clicked;
}
- //-------------------------------------------------------------------
- // Properties.
+ // --- Component state ---
+
+ public void SetControlActivity(bool enabled)
+ {
+ if (IsEnabled != enabled) IsEnabled = enabled;
+ }
+
+ // --- Events ---
- //-------------------------------------------------------------------
- // Events.
protected virtual void Button_Clicked(object? sender, EventArgs e)
{
SaLogger.Info(SysUtil.Fn + " Button clicked.");
}
- //-------------------------------------------------------------------
+ // --- The End ---
}
- //=======================================================================
}
diff --git a/SacsMobileMaui/Maui/Controls/SamLabel.cs b/SacsMobileMaui/Maui/Controls/SamLabel.cs
index ec1eb24..ada292a 100644
--- a/SacsMobileMaui/Maui/Controls/SamLabel.cs
+++ b/SacsMobileMaui/Maui/Controls/SamLabel.cs
@@ -1,4 +1,4 @@
-using Sarand.Net.Standard.Base.Utils;
+using Sarand.Net.Standard.Base.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -8,19 +8,16 @@ using System.Threading.Tasks;
namespace Sarand.Net.Mobile.Maui.Controls
{
- //=======================================================================
- public class SamLabel : Label
+ public class SamLabel : Label, ISamControl
{
- //-------------------------------------------------------------------
- // Definitions.
+ // --- Data Members ---
- //-------------------------------------------------------------------
- // Data members.
private double fontSize;
private double fontSizeProportion = 1.0;
+ private bool applyingFontSize;
+
+ // --- Construction ---
- //-------------------------------------------------------------------
- // Construction.
public SamLabel()
{
fontSize = base.FontSize;
@@ -28,8 +25,8 @@ namespace Sarand.Net.Mobile.Maui.Controls
Text = "";
}
- //-------------------------------------------------------------------
- // Properties.
+ // --- Properties ---
+
/// Default (initial) font size.
public double FontSizeDefault { get; private set; }
@@ -37,42 +34,54 @@ namespace Sarand.Net.Mobile.Maui.Controls
public new double FontSize
{
get { return fontSize; }
- set { fontSize = value; base.FontSize = fontSize * fontSizeProportion; }
+ set
+ {
+ if (fontSize == value) return;
+ fontSize = value;
+ ApplyFontSize();
+ }
}
/// Font size proportion.
public double FontSizeProportion
{
get { return fontSizeProportion; }
- set { fontSizeProportion = value; base.FontSize = fontSize * fontSizeProportion; }
+ set
+ {
+ if (fontSizeProportion == value) return;
+ fontSizeProportion = value;
+ ApplyFontSize();
+ }
}
- //-------------------------------------------------------------------
- // Control events.
+ // --- Font sizing ---
- //-------------------------------------------------------------------
- // View events.
-
- protected override void OnPropertyChanging([CallerMemberName] string propertyName = "")
+ private void ApplyFontSize()
{
- base.OnPropertyChanging(propertyName);
- if (propertyName.EqualsCI("FontSize"))
- {
- }
+ applyingFontSize = true;
+ base.FontSize = fontSize * fontSizeProportion;
+ applyingFontSize = false;
}
protected override void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
base.OnPropertyChanged(propertyName);
- if (propertyName.EqualsCI("FontSize"))
+ if (propertyName.EqualsCI("FontSize") && !applyingFontSize)
{
if (FontSizeDefault <= 0)
FontSizeDefault = base.FontSize;
- fontSize = base.FontSize;
+ if (fontSizeProportion != 0)
+ fontSize = base.FontSize / fontSizeProportion;
}
}
- //-------------------------------------------------------------------
+ // --- Component state ---
+
+ public void SetControlActivity(bool enabled)
+ {
+ if (IsEnabled != enabled) IsEnabled = enabled;
+ }
+
+ // --- The End ---
}
- //=======================================================================
}
diff --git a/SacsMobileMaui/Maui/Controls/SamPicker.cs b/SacsMobileMaui/Maui/Controls/SamPicker.cs
index 2481afe..d7a75e0 100644
--- a/SacsMobileMaui/Maui/Controls/SamPicker.cs
+++ b/SacsMobileMaui/Maui/Controls/SamPicker.cs
@@ -1,4 +1,5 @@
-using Sarand.Net.Mobile.Maui.App;
+using Sarand.Net.Mobile.Maui.App;
+using Sarand.Net.Mobile.Maui.Logic;
using Sarand.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.Utils;
using System;
@@ -9,11 +10,10 @@ using System.Threading.Tasks;
namespace Sarand.Net.Mobile.Maui.Controls
{
- //=======================================================================
- public class SamPicker : Picker
+ public class SamPicker : Picker, ISamNativeControlStyle, ISamControl
{
- //-------------------------------------------------------------------
- // Definitions.
+ // --- Definitions ---
+
public class SamPickerItem
{
public SysId Id { get; set; } = new SysId();
@@ -26,38 +26,37 @@ namespace Sarand.Net.Mobile.Maui.Controls
}
}
- //-------------------------------------------------------------------
- // Data members.
- private readonly List pickerItems = new List();
+ // --- Data Members ---
+
+ private readonly SamPickerItemCollection pickerItems = new SamPickerItemCollection();
+
+ // --- Construction ---
- //-------------------------------------------------------------------
- // Construction.
public SamPicker()
{
DefaultFontSize = FontSize;
}
- //-------------------------------------------------------------------
- // Properties.
+ // --- Properties ---
public double DefaultFontSize { get; }
+ /// Whether the picker is currently replacing its item list.
public bool BeingPopulated { get; protected set; } = false;
- // Native behaviour modified by SamHandler.
+ // --- Native styling ---
public bool NativeNoBorder { get; set; } = Sam.Visuals.Form.Controls.NativeNoBorder;
public bool NativeNoUnderline { get; set; } = Sam.Visuals.Form.Controls.NativeNoUnderline;
public bool NativeBackgroundClear { get; set; } = Sam.Visuals.Form.Controls.NativeBackgroundClear;
- //-------------------------------------------------------------------
- // P o p u l a t e I t e m s
- //-------------------------------------------------------------------
+ // --- Item population ---
+
///
/// Does the list contain an item with the same Id.
/// NB Invalid Id values are matched.
///
public bool ContainsItemId(SysId id)
{
- return pickerItems.Exists(item => SysId.ToInt(item.Id) == SysId.ToInt(id));
+ return pickerItems.ContainsId(id);
}
///
/// Does the list contain an item with the same code.
@@ -65,9 +64,8 @@ namespace Sarand.Net.Mobile.Maui.Controls
///
public bool ContainsItemCode(String code)
{
- return pickerItems.Exists(item => item.Code.EqualsCI(code));
+ return pickerItems.ContainsCode(code);
}
- //-------------------------------------------------------------------
/// Remove all items from the picker.
public void ClearItems()
{
@@ -75,22 +73,31 @@ namespace Sarand.Net.Mobile.Maui.Controls
ItemsSource = null;
pickerItems.Clear();
}
- /// Replace existing picker item list.
+ /// Replace existing picker item list and raise .
public void SetItems(List pickerItems)
{
- ClearItems();
- this.pickerItems.AddRange(pickerItems);
- RefreshPickerItems();
+ BeingPopulated = true;
+ bool populated = false;
+ try
+ {
+ ClearItems();
+ this.pickerItems.Replace(pickerItems);
+ RefreshPickerItems();
+ populated = true;
+ }
+ finally
+ {
+ BeingPopulated = false;
+ if (populated) InvokePopulatedEvent();
+ }
}
- //-------------------------------------------------------------------
///
/// Add an item identified by a SysId value.
/// NB Fails if an item already exists with the same id.
///
public bool AddItem(SysId id, String caption)
{
- if (ContainsItemId(id)) return false;
- pickerItems.Add(new SamPickerItem() { Id = id, Caption = caption });
+ if (!pickerItems.AddById(new SamPickerItem() { Id = id, Caption = caption })) return false;
RefreshPickerItems();
return ContainsItemId(id);
}
@@ -100,25 +107,20 @@ namespace Sarand.Net.Mobile.Maui.Controls
///
public bool AddItem(String code, String caption)
{
- if (ContainsItemCode(code)) return false;
- pickerItems.Add(new SamPickerItem() { Code = code, Caption = caption });
+ if (!pickerItems.AddByCode(new SamPickerItem() { Code = code, Caption = caption })) return false;
RefreshPickerItems();
return ContainsItemCode(code);
}
- //-------------------------------------------------------------------
private void RefreshPickerItems()
{
- //SetBinding(Picker.ItemsSourceProperty, BindableProperty.Create());
- //ItemDisplayBinding = new Binding("Caption");
- // Picker items doesn't automatically keep up to date with teh ItemsSource list.
- // So clear it and reset to force the refresh.
+ // Picker items do not automatically keep the ItemsSource display in sync.
+ // Clear and reset the source to force a refresh.
ItemsSource = null;
- ItemsSource = pickerItems;
+ ItemsSource = pickerItems.Items;
}
- //-------------------------------------------------------------------
- // I t e m S e l e c t i o n
- //-------------------------------------------------------------------
+ // --- Item selection ---
+
public SamPickerItem? SelectedPickerItem
{
get
@@ -143,7 +145,7 @@ namespace Sarand.Net.Mobile.Maui.Controls
}
set
{
- SelectedPickerItem = pickerItems.Find(item => item.Id.Equals(value));
+ SelectedPickerItem = pickerItems.FindById(value);
}
}
public String SelectedItemCode
@@ -155,13 +157,12 @@ namespace Sarand.Net.Mobile.Maui.Controls
}
set
{
- SelectedPickerItem = pickerItems.Find(item => item.Code.EqualsCI(value));
+ SelectedPickerItem = pickerItems.FindByCode(value);
}
}
- //-------------------------------------------------------------------
- // C o n t r o l E v e n t s
- //-------------------------------------------------------------------
+ // --- Control events ---
+
// Picker population completed.
public class PopulatedEventArgs : EventArgs { }
public delegate void PopulatedEventHandler(object? sender, PopulatedEventArgs e);
@@ -172,7 +173,13 @@ namespace Sarand.Net.Mobile.Maui.Controls
if (Populated != null) Populated.Invoke(this, new PopulatedEventArgs() { });
}
- //-------------------------------------------------------------------
+ // --- Component state ---
+
+ public void SetControlActivity(bool enabled)
+ {
+ if (IsEnabled != enabled) IsEnabled = enabled;
+ }
+
+ // --- The End ---
}
- //=======================================================================
}
diff --git a/SacsMobileMaui/Maui/Controls/SamTabControl.cs b/SacsMobileMaui/Maui/Controls/SamTabControl.cs
index 29a2841..e9a8ad8 100644
--- a/SacsMobileMaui/Maui/Controls/SamTabControl.cs
+++ b/SacsMobileMaui/Maui/Controls/SamTabControl.cs
@@ -1,5 +1,6 @@
-using Microsoft.Maui;
+using Microsoft.Maui;
using Microsoft.Maui.Layouts;
+using Sarand.Net.Mobile.Maui.App;
using Sarand.Net.Mobile.Maui.Layouts;
using Sarand.Net.Mobile.Maui.Panels;
using Sarand.Net.Mobile.Maui.Views;
@@ -11,14 +12,10 @@ using System.Threading.Tasks;
namespace Sarand.Net.Mobile.Maui.Controls
{
- //=======================================================================
- public class SamTabControl : ContentView
+ public class SamTabControl : ContentView, ISamView
{
- //-------------------------------------------------------------------
- // Definitions.
+ // --- Data Members ---
- //-------------------------------------------------------------------
- // Data members.
private readonly List tabPanels = new List();
private short currentTabIdx = -1;
// Main layout to host header and body.
@@ -28,39 +25,40 @@ namespace Sarand.Net.Mobile.Maui.Controls
// Body - Content view to host tab panel.
private SamContentView bodyPanel = new SamContentView();
- //-------------------------------------------------------------------
- // Construction.
+ // --- Construction ---
+
public SamTabControl()
{
- // Main layout - vertical stack with two rows.
- // 1. Header - tab panel captions.
- // 2. Body - current tab panel.
+ // --- Main layout ---
+
VerticalOptions = LayoutOptions.FillAndExpand;
- //BackgroundColor = Color.LightSkyBlue;
mainLayout.VerticalOptions = LayoutOptions.FillAndExpand;
mainLayout.Spacing = 2.0;
Content = mainLayout;
- // Header panel - tab captions.
- //headerPanel.HorizontalOptions = LayoutOptions.Fill;
+ // --- Header panel ---
+
+ headerPanel.BackgroundColor = Sam.Visuals.Form.TabControl.HeaderBackgroundColor;
mainLayout.Children.Add(headerPanel);
- // Default label font size.
+ // --- Default font size ---
+
DefaultHeaderFontSize = new Label().FontSize;
HeaderFontSize = DefaultHeaderFontSize;
- // Body panel.
+ // --- Body panel ---
+
bodyPanel.HorizontalOptions = LayoutOptions.Fill;
bodyPanel.VerticalOptions = LayoutOptions.FillAndExpand;
- bodyPanel.BackgroundColor = Colors.LightYellow;
+ bodyPanel.BackgroundColor = Sam.Visuals.Form.TabControl.BodyBackgroundColor;
mainLayout.Children.Add(bodyPanel);
}
- //-------------------------------------------------------------------
- // Properties.
+ // --- Properties ---
+
// Header.
public Color HeaderBackgroundColor { get { return headerPanel.BackgroundColor; } set { headerPanel.BackgroundColor = value; } }
- public Color CaptionBackgroundColor { get; set; } = Colors.Transparent;
+ public Color CaptionBackgroundColor { get; set; } = Sam.Visuals.Form.TabControl.CaptionBackgroundColor;
public double DefaultHeaderFontSize { get; }
public double HeaderFontSize { get; set; }
public double HeaderMarginBottom
@@ -84,9 +82,8 @@ namespace Sarand.Net.Mobile.Maui.Controls
set { ChangeTabPanel(value); }
}
- //-------------------------------------------------------------------
- // T a b P a n e l s
- //-------------------------------------------------------------------
+ // --- Tab panels ---
+
public void ClearPanels()
{
tabPanels.Clear();
@@ -106,9 +103,8 @@ namespace Sarand.Net.Mobile.Maui.Controls
RefreshLayout();
}
- //-------------------------------------------------------------------
- // R e f r e s h L a y o u t
- //-------------------------------------------------------------------
+ // --- Refresh layout ---
+
private void RefreshLayout()
{
// Clear existing components.
@@ -152,9 +148,8 @@ namespace Sarand.Net.Mobile.Maui.Controls
ChangeTabPanel(currentTabIdx);
}
- //-------------------------------------------------------------------
- // C h a n g e T a b P a n e l
- //-------------------------------------------------------------------
+ // --- Change tab panel ---
+
private void ChangeTabPanel(short tabPanelIdx)
{
// Validate requested panel index.
@@ -183,11 +178,16 @@ namespace Sarand.Net.Mobile.Maui.Controls
currentTabIdx = tabPanelIdx;
}
- //-------------------------------------------------------------------
- // C o n t r o l E v e n t s
- //-------------------------------------------------------------------
+ // --- Component state ---
- //-------------------------------------------------------------------
+ public void ConfigureComponents() { }
+ public void SetControlActivity(bool enabled)
+ {
+ if (IsEnabled != enabled) IsEnabled = enabled;
+ SetControlsReadOnly();
+ }
+ public void SetControlsReadOnly() { }
+
+ // --- The End ---
}
- //=======================================================================
}
diff --git a/SacsMobileMaui/Maui/Controls/SamTimePicker.cs b/SacsMobileMaui/Maui/Controls/SamTimePicker.cs
index 3ebaade..8e6da4a 100644
--- a/SacsMobileMaui/Maui/Controls/SamTimePicker.cs
+++ b/SacsMobileMaui/Maui/Controls/SamTimePicker.cs
@@ -9,7 +9,7 @@ using System.Threading.Tasks;
namespace Sarand.Net.Mobile.Maui.Controls
{
//=======================================================================
- public class SamTimePicker : TimePicker
+ public class SamTimePicker : TimePicker, ISamControl
{
//-------------------------------------------------------------------
// Definitions.
@@ -47,6 +47,13 @@ namespace Sarand.Net.Mobile.Maui.Controls
base.OnPropertyChanged(propertyName);
}
+ // --- Component state ---
+
+ public void SetControlActivity(bool enabled)
+ {
+ if (IsEnabled != enabled) IsEnabled = enabled;
+ }
+
//-------------------------------------------------------------------
}
//=======================================================================
diff --git a/SacsMobileMaui/Maui/Controls/SamWebView.cs b/SacsMobileMaui/Maui/Controls/SamWebView.cs
index cedb4f1..4bb561d 100644
--- a/SacsMobileMaui/Maui/Controls/SamWebView.cs
+++ b/SacsMobileMaui/Maui/Controls/SamWebView.cs
@@ -1,4 +1,4 @@
-using Sarand.Net.Standard.Base.App;
+using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Utils;
using System;
using System.Collections.Generic;
@@ -8,36 +8,33 @@ using System.Threading.Tasks;
namespace Sarand.Net.Mobile.Maui.Controls
{
- //=======================================================================
- public class SamWebView : WebView
+ public class SamWebView : WebView, ISamControl
{
- //-------------------------------------------------------------------
- // Definitions.
+ // --- Data Members ---
- //-------------------------------------------------------------------
- // Data members.
public String html = "";
- private HtmlWebViewSource htmlSource;
- private UrlWebViewSource aboutBlankSource = new UrlWebViewSource() { Url = "about:blank" };
- // Managers.
+ private readonly HtmlWebViewSource htmlSource;
+ private readonly UrlWebViewSource aboutBlankSource = new UrlWebViewSource() { Url = "about:blank" };
+
+ // --- Construction ---
- //-------------------------------------------------------------------
- // Construction.
public SamWebView()
{
- // Events.
+ // --- Events ---
+
Navigating += WebView_Navigating;
Navigated += WebView_Navigated;
- // HTML source.
+ // --- HTML source ---
+
htmlSource = new HtmlWebViewSource() { Html = html };
Source = aboutBlankSource;
}
- //-------------------------------------------------------------------
- // Properties.
- // HTML Panel.
+ // --- Properties ---
+
public static String AppActionPrefix => "App:";
+ /// Gets or sets the HTML displayed by the web view.
public String Html
{
get { return html; }
@@ -51,9 +48,8 @@ namespace Sarand.Net.Mobile.Maui.Controls
}
}
- //-------------------------------------------------------------------
- // N a v i g a t i o n
- //-------------------------------------------------------------------
+ // --- Navigation ---
+
public class AppNavigatingEventArgs : EventArgs
{
public AppNavigatingEventArgs(String appAction)
@@ -70,13 +66,12 @@ namespace Sarand.Net.Mobile.Maui.Controls
}
private String GetAppAction(String location)
{
- if (!location.StartsWithCI(AppActionPrefix)) return "";
+ if (String.IsNullOrEmpty(location) || !location.StartsWithCI(AppActionPrefix)) return "";
return location.Right(location.Length - AppActionPrefix.Length);
}
- //-------------------------------------------------------------------
- // C o n t r o l E v e n t s
- //-------------------------------------------------------------------
+ // --- Control events ---
+
private void WebView_Navigating(object? sender, WebNavigatingEventArgs e)
{
String appAction = GetAppAction(e.Url);
@@ -97,7 +92,13 @@ namespace Sarand.Net.Mobile.Maui.Controls
}
}
- //-------------------------------------------------------------------
+ // --- Component state ---
+
+ public void SetControlActivity(bool enabled)
+ {
+ if (IsEnabled != enabled) IsEnabled = enabled;
+ }
+
+ // --- The End ---
}
- //=======================================================================
}
diff --git a/SacsMobileMaui/Maui/Handlers/SamFormHandler.cs b/SacsMobileMaui/Maui/Handlers/SamFormHandler.cs
index 433fdca..8b34bae 100644
--- a/SacsMobileMaui/Maui/Handlers/SamFormHandler.cs
+++ b/SacsMobileMaui/Maui/Handlers/SamFormHandler.cs
@@ -1,4 +1,4 @@
-#if ANDROID
+#if ANDROID
using Microsoft.Maui.Controls.Compatibility.Platform.Android;
#endif
using Sarand.Net.Mobile.Maui.Controls;
@@ -10,26 +10,25 @@ using System.Threading.Tasks;
namespace Sarand.Net.Mobile.Maui.Handlers
{
- //========================================================================
// Ref. https://dev.to/vhugogarcia/remove-entry-and-picker-borders-in-net-maui-2pk2
// Ref. https://github.com/dotnet/maui/issues/7906
+
public static class SamFormHandler
{
- //--------------------------------------------------------------------
- // Definitions.
+ // --- Control handler registration ---
- //--------------------------------------------------------------------
///
- /// Remove borders around entry and picker controls.
+ /// Apply configured native styling to Sam entry, editor, and picker controls.
/// Also make background transparent.
///
public static void AssignControlHandlers()
{
- //---------------------------------------------------------------
- // Entry handler.
+ // --- Entry handler ---
+
Microsoft.Maui.Handlers.EntryHandler.Mapper.AppendToMapping("SamEntryHandler", (handler, view) =>
{
- if ((view as SamEntry)?.NativeNoBorder ?? false)
+ if (view is not ISamNativeControlStyle style) return;
+ if (style.NativeNoBorder)
{
#if ANDROID
handler.PlatformView.BackgroundTintList = Android.Content.Res.ColorStateList.ValueOf(Colors.Transparent.ToAndroid());
@@ -40,15 +39,17 @@ namespace Sarand.Net.Mobile.Maui.Handlers
handler.PlatformView.BorderThickness = new Microsoft.UI.Xaml.Thickness() { Bottom = 0, Top = 0, Left = 0, Right = 0, };
#endif
}
- if ((view as SamEntry)?.NativeNoUnderline ?? false)
+ if (style.NativeNoUnderline)
{
#if ANDROID
handler.PlatformView.BackgroundTintList = Android.Content.Res.ColorStateList.ValueOf(Colors.Transparent.ToAndroid());
#elif IOS || MACCATALYST
+ // UITextField/UITextView do not expose a separate Android-style underline.
#elif WINDOWS
+ // WinUI text controls use a border, not a separate underline; use NativeNoBorder to remove it.
#endif
}
- if ((view as SamEntry)?.NativeBackgroundClear ?? false)
+ if (style.NativeBackgroundClear)
{
#if ANDROID
handler.PlatformView.Background = null;
@@ -56,34 +57,37 @@ namespace Sarand.Net.Mobile.Maui.Handlers
#elif IOS || MACCATALYST
handler.PlatformView.BackgroundColor = UIKit.UIColor.Clear;
#elif WINDOWS
+ handler.PlatformView.Background = new Microsoft.UI.Xaml.Media.SolidColorBrush(Microsoft.UI.Colors.Transparent);
#endif
}
});
- //---------------------------------------------------------------
- // Editor handler.
+ // --- Editor handler ---
+
Microsoft.Maui.Handlers.EditorHandler.Mapper.AppendToMapping("SamEditorHandler", (handler, view) =>
{
- if ((view as SamEditor)?.NativeNoBorder ?? false)
+ if (view is not ISamNativeControlStyle style) return;
+ if (style.NativeNoBorder)
{
#if ANDROID
handler.PlatformView.BackgroundTintList = Android.Content.Res.ColorStateList.ValueOf(Colors.Transparent.ToAndroid());
#elif IOS || MACCATALYST
handler.PlatformView.Layer.BorderWidth = 0;
- //handler.PlatformView.BorderStyle = UIKit.UITextViewBorderStyle.None;
#elif WINDOWS
handler.PlatformView.BorderThickness = new Microsoft.UI.Xaml.Thickness() { Bottom = 0, Top = 0, Left = 0, Right = 0, };
#endif
}
- if ((view as SamEntry)?.NativeNoUnderline ?? false)
+ if (style.NativeNoUnderline)
{
#if ANDROID
handler.PlatformView.BackgroundTintList = Android.Content.Res.ColorStateList.ValueOf(Colors.Transparent.ToAndroid());
#elif IOS || MACCATALYST
+ // UITextView has no separate underline to remove.
#elif WINDOWS
+ // WinUI text controls use a border, not a separate underline; use NativeNoBorder to remove it.
#endif
}
- if ((view as SamEntry)?.NativeBackgroundClear ?? false)
+ if (style.NativeBackgroundClear)
{
#if ANDROID
handler.PlatformView.Background = null;
@@ -91,15 +95,17 @@ namespace Sarand.Net.Mobile.Maui.Handlers
#elif IOS || MACCATALYST
handler.PlatformView.BackgroundColor = UIKit.UIColor.Clear;
#elif WINDOWS
+ handler.PlatformView.Background = new Microsoft.UI.Xaml.Media.SolidColorBrush(Microsoft.UI.Colors.Transparent);
#endif
}
});
- //---------------------------------------------------------------
- // Picker handler.
- Microsoft.Maui.Handlers.PickerHandler.Mapper.AppendToMapping("Borderless", (handler, view) =>
+ // --- Picker handler ---
+
+ Microsoft.Maui.Handlers.PickerHandler.Mapper.AppendToMapping("SamPickerHandler", (handler, view) =>
{
- if ((view as SamEditor)?.NativeNoBorder ?? false)
+ if (view is not ISamNativeControlStyle style) return;
+ if (style.NativeNoBorder)
{
#if ANDROID
handler.PlatformView.BackgroundTintList = Android.Content.Res.ColorStateList.ValueOf(Colors.Transparent.ToAndroid());
@@ -110,15 +116,17 @@ namespace Sarand.Net.Mobile.Maui.Handlers
handler.PlatformView.BorderThickness = new Microsoft.UI.Xaml.Thickness() { Bottom = 0, Top = 0, Left = 0, Right = 0, };
#endif
}
- if ((view as SamEntry)?.NativeNoUnderline ?? false)
+ if (style.NativeNoUnderline)
{
#if ANDROID
handler.PlatformView.BackgroundTintList = Android.Content.Res.ColorStateList.ValueOf(Colors.Transparent.ToAndroid());
#elif IOS || MACCATALYST
+ // The native picker has a full border, not a separate underline; use NativeNoBorder to remove it.
#elif WINDOWS
+ // The WinUI picker has a full border, not a separate underline; use NativeNoBorder to remove it.
#endif
}
- if ((view as SamEntry)?.NativeBackgroundClear ?? false)
+ if (style.NativeBackgroundClear)
{
#if ANDROID
handler.PlatformView.Background = null;
@@ -126,14 +134,13 @@ namespace Sarand.Net.Mobile.Maui.Handlers
#elif IOS || MACCATALYST
handler.PlatformView.BackgroundColor = UIKit.UIColor.Clear;
#elif WINDOWS
+ handler.PlatformView.Background = new Microsoft.UI.Xaml.Media.SolidColorBrush(Microsoft.UI.Colors.Transparent);
#endif
}
});
- //---------------------------------------------------------------
}
- //--------------------------------------------------------------------
+ // --- The End ---
}
- //========================================================================
}
diff --git a/SacsMobileMaui/Maui/Layouts/SamAbsoluteLayout.cs b/SacsMobileMaui/Maui/Layouts/SamAbsoluteLayout.cs
index 6b6b6b2..4b3bb1e 100644
--- a/SacsMobileMaui/Maui/Layouts/SamAbsoluteLayout.cs
+++ b/SacsMobileMaui/Maui/Layouts/SamAbsoluteLayout.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
diff --git a/SacsMobileMaui/Maui/Layouts/SamFlexLayout.cs b/SacsMobileMaui/Maui/Layouts/SamFlexLayout.cs
index 8b8ba34..38f6a69 100644
--- a/SacsMobileMaui/Maui/Layouts/SamFlexLayout.cs
+++ b/SacsMobileMaui/Maui/Layouts/SamFlexLayout.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
diff --git a/SacsMobileMaui/Maui/Layouts/SamGrid.cs b/SacsMobileMaui/Maui/Layouts/SamGrid.cs
index 7935ffb..086c73c 100644
--- a/SacsMobileMaui/Maui/Layouts/SamGrid.cs
+++ b/SacsMobileMaui/Maui/Layouts/SamGrid.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
diff --git a/SacsMobileMaui/Maui/Layouts/SamStackLayout.cs b/SacsMobileMaui/Maui/Layouts/SamStackLayout.cs
index b1aea8b..b533186 100644
--- a/SacsMobileMaui/Maui/Layouts/SamStackLayout.cs
+++ b/SacsMobileMaui/Maui/Layouts/SamStackLayout.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
diff --git a/SacsMobileMaui/Maui/Layouts/SamWrapLayout.cs b/SacsMobileMaui/Maui/Layouts/SamWrapLayout.cs
index b1903d6..bf006ec 100644
--- a/SacsMobileMaui/Maui/Layouts/SamWrapLayout.cs
+++ b/SacsMobileMaui/Maui/Layouts/SamWrapLayout.cs
@@ -1,4 +1,4 @@
-using Microsoft.Maui.Controls.Compatibility;
+using Microsoft.Maui.Controls.Compatibility;
namespace Sarand.Net.Mobile.Maui.Layouts
{
@@ -184,17 +184,13 @@ namespace Sarand.Net.Mobile.Maui.Layouts
{
child = c,
size = c.Measure(widthConstraint, heightConstraint)
- });
+ }).ToList();
- var nextChildren = visibleChildren.Skip(1).ToList();
- nextChildren.Add(null); //make element count same
-
- var zipChildren = visibleChildren.Zip(nextChildren, (c, n) => new { current = c, next = n });
-
- foreach (var childBlock in zipChildren)
+ for (var childIndex = 0; childIndex < visibleChildren.Count; childIndex++)
{
- var child = childBlock.current.child;
- var size = childBlock.current.size;
+ var childBlock = visibleChildren[childIndex];
+ var child = childBlock.child;
+ var size = childBlock.size;
var itemWidth = size.Width;
var itemHeight = size.Height;
@@ -210,7 +206,7 @@ namespace Sarand.Net.Mobile.Maui.Layouts
LayoutChildIntoBoundingRegion(child, region);
}
- if (childBlock.next == null)
+ if (childIndex == visibleChildren.Count - 1)
{
totalHeight += rowHeight;
totalWidth = Math.Max(totalWidth, rowWidth);
@@ -218,7 +214,7 @@ namespace Sarand.Net.Mobile.Maui.Layouts
}
xPos += itemWidth + SpacingX;
- var nextWitdh = childBlock.next.size.Width;
+ var nextWitdh = visibleChildren[childIndex + 1].size.Width;
if (xPos + nextWitdh - x > widthConstraint)
{
diff --git a/SacsMobileMaui/Maui/Logic/SamDateValueState.cs b/SacsMobileMaui/Maui/Logic/SamDateValueState.cs
new file mode 100644
index 0000000..cd15ff7
--- /dev/null
+++ b/SacsMobileMaui/Maui/Logic/SamDateValueState.cs
@@ -0,0 +1,44 @@
+using Sarand.Net.Standard.Base.Utils;
+using System;
+
+namespace Sarand.Net.Mobile.Maui.Logic
+{
+ // --- Date value state ---
+ public sealed class SamDateValueState
+ {
+ private DateTime date = DateTime.MinValue;
+ private bool invalid = true;
+
+ public DateTime Date { get { return invalid ? DateTime.MinValue : date; } }
+ public bool IsInvalid { get { return invalid; } }
+
+ public bool SetDate(DateTime value)
+ {
+ if (Date.Equals(value)) return false;
+ if (DateUtil.IsValid(value))
+ {
+ date = value;
+ invalid = false;
+ }
+ else
+ {
+ date = DateTime.MinValue;
+ invalid = true;
+ }
+ return true;
+ }
+
+ public bool TryInvalidate(out DateTime previousDate)
+ {
+ if (invalid)
+ {
+ previousDate = DateTime.MinValue;
+ return false;
+ }
+ previousDate = date;
+ date = DateTime.MinValue;
+ invalid = true;
+ return true;
+ }
+ }
+}
diff --git a/SacsMobileMaui/Maui/Logic/SamEntryTextFormatOptions.cs b/SacsMobileMaui/Maui/Logic/SamEntryTextFormatOptions.cs
new file mode 100644
index 0000000..daa9b54
--- /dev/null
+++ b/SacsMobileMaui/Maui/Logic/SamEntryTextFormatOptions.cs
@@ -0,0 +1,18 @@
+using Sarand.Net.Mobile.Maui.Controls;
+using System;
+using System.Globalization;
+
+namespace Sarand.Net.Mobile.Maui.Logic
+{
+ // --- Entry text format options ---
+ public sealed class SamEntryTextFormatOptions
+ {
+ public SamEntry.TextCaseType TextCase { get; init; } = SamEntry.TextCaseType.Normal;
+ public bool NumericOnly { get; init; }
+ public byte Decimals { get; init; }
+ public bool TrimText { get; init; }
+ public TextInfo TextInfo { get; init; } = CultureInfo.CurrentCulture.TextInfo;
+
+ // --- The End ---
+ }
+}
diff --git a/SacsMobileMaui/Maui/Logic/SamEntryTextFormatter.cs b/SacsMobileMaui/Maui/Logic/SamEntryTextFormatter.cs
new file mode 100644
index 0000000..f4942c8
--- /dev/null
+++ b/SacsMobileMaui/Maui/Logic/SamEntryTextFormatter.cs
@@ -0,0 +1,48 @@
+using Sarand.Net.Standard.Base.Utils;
+using System;
+
+namespace Sarand.Net.Mobile.Maui.Logic
+{
+ // --- Entry text formatting ---
+ public static class SamEntryTextFormatter
+ {
+ public static String Format(String? text, SamEntryTextFormatOptions options)
+ {
+ String originalText = text ?? "";
+ String formattedText = originalText;
+ if (StringUtil.IsEmpty(formattedText)) return formattedText;
+ if (options.TrimText)
+ formattedText = StringUtil.TrimAll(formattedText);
+
+ if (options.NumericOnly)
+ {
+ if (options.Decimals > 0)
+ {
+ decimal value = StringUtil.ToDecimal(formattedText);
+ if (value != 0.0m)
+ formattedText = value.ToString("N" + options.Decimals);
+ else if (!formattedText.Equals("0"))
+ formattedText = "";
+ }
+ else
+ {
+ long value = StringUtil.ToLong(formattedText);
+ if (value != 0)
+ formattedText = value.ToString();
+ else if (!formattedText.Equals("0"))
+ formattedText = "";
+ }
+ }
+ else if (options.TextCase == Controls.SamEntry.TextCaseType.Upper)
+ formattedText = options.TextInfo.ToUpper(formattedText);
+ else if (options.TextCase == Controls.SamEntry.TextCaseType.Lower)
+ formattedText = options.TextInfo.ToLower(formattedText);
+ else if (options.TextCase == Controls.SamEntry.TextCaseType.Title)
+ formattedText = StringUtil.ToTitleCase(formattedText, options.TextInfo);
+
+ return formattedText;
+ }
+
+ // --- The End ---
+ }
+}
diff --git a/SacsMobileMaui/Maui/Logic/SamPickerItemCollection.cs b/SacsMobileMaui/Maui/Logic/SamPickerItemCollection.cs
new file mode 100644
index 0000000..f90330a
--- /dev/null
+++ b/SacsMobileMaui/Maui/Logic/SamPickerItemCollection.cs
@@ -0,0 +1,61 @@
+using Sarand.Net.Mobile.Maui.Controls;
+using Sarand.Net.Standard.Base.Bus;
+using Sarand.Net.Standard.Base.Utils;
+using System;
+using System.Collections.Generic;
+
+namespace Sarand.Net.Mobile.Maui.Logic
+{
+ // --- Picker item collection ---
+ public sealed class SamPickerItemCollection
+ {
+ private readonly List items = new List();
+
+ public List Items { get { return items; } }
+
+ public void Clear()
+ {
+ items.Clear();
+ }
+
+ public void Replace(IEnumerable replacementItems)
+ {
+ items.Clear();
+ items.AddRange(replacementItems);
+ }
+
+ public bool ContainsId(SysId id)
+ {
+ return items.Exists(item => SysId.ToInt(item.Id) == SysId.ToInt(id));
+ }
+
+ public bool ContainsCode(String code)
+ {
+ return items.Exists(item => item.Code.EqualsCI(code));
+ }
+
+ public bool AddById(SamPicker.SamPickerItem item)
+ {
+ if (ContainsId(item.Id)) return false;
+ items.Add(item);
+ return true;
+ }
+
+ public bool AddByCode(SamPicker.SamPickerItem item)
+ {
+ if (ContainsCode(item.Code)) return false;
+ items.Add(item);
+ return true;
+ }
+
+ public SamPicker.SamPickerItem? FindById(SysId id)
+ {
+ return items.Find(item => item.Id.Equals(id));
+ }
+
+ public SamPicker.SamPickerItem? FindByCode(String code)
+ {
+ return items.Find(item => item.Code.EqualsCI(code));
+ }
+ }
+}
diff --git a/SacsMobileMaui/Maui/Logic/SamViewTreeUtil.cs b/SacsMobileMaui/Maui/Logic/SamViewTreeUtil.cs
new file mode 100644
index 0000000..a8270a1
--- /dev/null
+++ b/SacsMobileMaui/Maui/Logic/SamViewTreeUtil.cs
@@ -0,0 +1,36 @@
+using Sarand.Net.Mobile.Maui.Views;
+using Sarand.Net.Mobile.Maui.Controls;
+using System.Collections.Generic;
+
+namespace Sarand.Net.Mobile.Maui.Logic
+{
+ // --- Sam view tree operations ---
+ public static class SamViewTreeUtil
+ {
+ public static void ConfigureChildren(Element? root)
+ {
+ foreach (Element element in GetElements(root))
+ if (element is ISamView samView)
+ samView.ConfigureComponents();
+ }
+
+ public static void SetChildControlActivity(Element? root, bool enabled)
+ {
+ foreach (Element element in GetElements(root))
+ {
+ if (element is ISamView samView)
+ samView.SetControlActivity(enabled);
+ if (element is ISamControl samControl)
+ samControl.SetControlActivity(enabled);
+ }
+ }
+
+ private static IEnumerable GetElements(Element? root)
+ {
+ if (root == null) yield break;
+ yield return root;
+ foreach (Element descendant in root.GetVisualTreeDescendants())
+ yield return descendant;
+ }
+ }
+}
diff --git a/SacsMobileMaui/Maui/Pages/SamContentPage.cs b/SacsMobileMaui/Maui/Pages/SamContentPage.cs
index 57a2f15..db6bb49 100644
--- a/SacsMobileMaui/Maui/Pages/SamContentPage.cs
+++ b/SacsMobileMaui/Maui/Pages/SamContentPage.cs
@@ -1,4 +1,5 @@
-using Microsoft.Maui.Controls;
+using Microsoft.Maui.Controls;
+using Sarand.Net.Mobile.Maui.Logic;
using Sarand.Net.Mobile.Maui.Views;
using Sarand.Net.Standard.Base.Utils;
using System;
@@ -11,7 +12,7 @@ using System.Threading.Tasks;
namespace Sarand.Net.Mobile.Maui.Pages
{
//=======================================================================
- public abstract class SamContentPage : ContentPage
+ public abstract class SamContentPage : ContentPage, ISamView
{
//-------------------------------------------------------------------
// Definitions.
@@ -38,61 +39,35 @@ namespace Sarand.Net.Mobile.Maui.Pages
protected virtual void ConfigureChildComponents()
{
- // Configure child components.
- if (Content != null)
- {
- ConfigureChildComponent(Content);
- foreach (var descendent in Content.GetVisualTreeDescendants())
- {
- View? childView = descendent as View;
- if (childView != null)
- ConfigureChildComponent(childView);
- }
- }
- }
-
- private void ConfigureChildComponent(View view)
- {
- if (view is ISamView)
- {
- ISamView? samView = view as ISamView;
- if (samView != null)
- samView.ConfigureComponents();
- }
+ SamViewTreeUtil.ConfigureChildren(Content);
}
//-------------------------------------------------------------------
// C o n t r o l A c t i v i t y
//-------------------------------------------------------------------
- protected virtual void SetControlActivity()
+ protected virtual void SetControlActivity(bool enabled)
{
+ if (IsEnabled != enabled) IsEnabled = enabled;
SetControlsReadOnly();
-
- // Child component control activity.
- if (Content != null)
- {
- SetChildControlActivity(Content);
- foreach (var descendent in Content.GetVisualTreeDescendants())
- {
- View? childView = descendent as View;
- if (childView != null)
- SetChildControlActivity(childView);
- }
- }
- }
- private void SetChildControlActivity(View view)
- {
- if (view is ISamView)
- {
- ISamView? samView = view as ISamView;
- if (samView != null)
- samView.SetControlActivity();
- }
+ SamViewTreeUtil.SetChildControlActivity(Content, enabled);
}
protected virtual void SetControlsReadOnly()
{
}
+ void ISamView.ConfigureComponents()
+ {
+ ConfigureComponents();
+ }
+ void ISamView.SetControlActivity(bool enabled)
+ {
+ SetControlActivity(enabled);
+ }
+ void ISamView.SetControlsReadOnly()
+ {
+ SetControlsReadOnly();
+ }
+
//-------------------------------------------------------------------
// P o p u p M e s s a g e s
//-------------------------------------------------------------------
@@ -107,7 +82,7 @@ namespace Sarand.Net.Mobile.Maui.Pages
String cancel = "OK";
if (alertMode == AlertMode.Close)
cancel = "Close";
- return DisplayAlert(title, message, cancel);
+ return DisplayAlertAsync(title, message, cancel);
}
public enum ConfirmMode
{
@@ -124,7 +99,7 @@ namespace Sarand.Net.Mobile.Maui.Pages
accept = "OK";
cancel = "Cancel";
}
- return await DisplayAlert(title, message, accept, cancel);
+ return await DisplayAlertAsync(title, message, accept, cancel);
}
//-------------------------------------------------------------------
diff --git a/SacsMobileMaui/Maui/Panels/SamPanel.cs b/SacsMobileMaui/Maui/Panels/SamPanel.cs
index 7bda81f..b341212 100644
--- a/SacsMobileMaui/Maui/Panels/SamPanel.cs
+++ b/SacsMobileMaui/Maui/Panels/SamPanel.cs
@@ -1,4 +1,4 @@
-using Sarand.Net.Mobile.Maui.Views;
+using Sarand.Net.Mobile.Maui.Views;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -37,11 +37,13 @@ namespace Sarand.Net.Mobile.Maui.Panels
//-------------------------------------------------------------------
// C o n t r o l A c t i v i t y
//-------------------------------------------------------------------
- public override void SetControlActivity()
+ public override void SetControlActivity(bool enabled)
{
+ base.SetControlActivity(enabled);
}
public override void SetControlsReadOnly()
{
+ base.SetControlsReadOnly();
}
//-------------------------------------------------------------------
diff --git a/SacsMobileMaui/Maui/Panels/SamPanel_ItemFilter.cs b/SacsMobileMaui/Maui/Panels/SamPanel_ItemFilter.cs
index 9f3904f..e7b2466 100644
--- a/SacsMobileMaui/Maui/Panels/SamPanel_ItemFilter.cs
+++ b/SacsMobileMaui/Maui/Panels/SamPanel_ItemFilter.cs
@@ -1,4 +1,4 @@
-using Sarand.Net.Mobile.Maui.Layouts;
+using Sarand.Net.Mobile.Maui.Layouts;
using System;
using System.Collections.Generic;
using System.Linq;
diff --git a/SacsMobileMaui/Maui/Panels/SamPanel_ItemFilterProperty.cs b/SacsMobileMaui/Maui/Panels/SamPanel_ItemFilterProperty.cs
index 539e703..9722b12 100644
--- a/SacsMobileMaui/Maui/Panels/SamPanel_ItemFilterProperty.cs
+++ b/SacsMobileMaui/Maui/Panels/SamPanel_ItemFilterProperty.cs
@@ -1,4 +1,4 @@
-using Sarand.Net.Mobile.Maui.Controls;
+using Sarand.Net.Mobile.Maui.Controls;
using Sarand.Net.Mobile.Maui.Layouts;
using Sarand.Net.Standard.Base.Utils;
using System;
diff --git a/SacsMobileMaui/Maui/Panels/SamPanel_ItemListHeader.cs b/SacsMobileMaui/Maui/Panels/SamPanel_ItemListHeader.cs
index a3083ae..90dc57e 100644
--- a/SacsMobileMaui/Maui/Panels/SamPanel_ItemListHeader.cs
+++ b/SacsMobileMaui/Maui/Panels/SamPanel_ItemListHeader.cs
@@ -1,4 +1,4 @@
-using Sarand.Net.Mobile.Maui.Controls;
+using Sarand.Net.Mobile.Maui.Controls;
using Sarand.Net.Mobile.Maui.Layouts;
using Sarand.Net.Mobile.Maui.Utils;
using Sarand.Net.Mobile.Maui.Views;
diff --git a/SacsMobileMaui/Maui/Panels/SamPanel_ItemListSummary.cs b/SacsMobileMaui/Maui/Panels/SamPanel_ItemListSummary.cs
index ffb4111..b29f156 100644
--- a/SacsMobileMaui/Maui/Panels/SamPanel_ItemListSummary.cs
+++ b/SacsMobileMaui/Maui/Panels/SamPanel_ItemListSummary.cs
@@ -1,4 +1,4 @@
-using Sarand.Net.Mobile.Maui.Controls;
+using Sarand.Net.Mobile.Maui.Controls;
using Sarand.Net.Mobile.Maui.Layouts;
using Sarand.Net.Mobile.Maui.Utils;
using Sarand.Net.Mobile.Maui.Views;
diff --git a/SacsMobileMaui/Maui/Panels/SamPanel_Messages.cs b/SacsMobileMaui/Maui/Panels/SamPanel_Messages.cs
index 99c1985..72f77ae 100644
--- a/SacsMobileMaui/Maui/Panels/SamPanel_Messages.cs
+++ b/SacsMobileMaui/Maui/Panels/SamPanel_Messages.cs
@@ -1,4 +1,4 @@
-using Sarand.Net.Mobile.Maui.Controls;
+using Sarand.Net.Mobile.Maui.Controls;
using Sarand.Net.Mobile.Maui.Layouts;
using Sarand.Net.Standard.Base.Core;
using System;
diff --git a/SacsMobileMaui/Maui/Panels/SamPanel_Page_Footer.cs b/SacsMobileMaui/Maui/Panels/SamPanel_Page_Footer.cs
index fced510..70d8590 100644
--- a/SacsMobileMaui/Maui/Panels/SamPanel_Page_Footer.cs
+++ b/SacsMobileMaui/Maui/Panels/SamPanel_Page_Footer.cs
@@ -1,4 +1,4 @@
-using Sarand.Net.Mobile.Maui.App;
+using Sarand.Net.Mobile.Maui.App;
using Sarand.Net.Mobile.Maui.Controls;
using Sarand.Net.Mobile.Maui.Layouts;
using Sarand.Net.Mobile.Maui.Utils;
diff --git a/SacsMobileMaui/Maui/Panels/SamPanel_Page_Header.cs b/SacsMobileMaui/Maui/Panels/SamPanel_Page_Header.cs
index 9cc4c8b..a7f84cc 100644
--- a/SacsMobileMaui/Maui/Panels/SamPanel_Page_Header.cs
+++ b/SacsMobileMaui/Maui/Panels/SamPanel_Page_Header.cs
@@ -1,4 +1,4 @@
-using Microsoft.Maui.Controls.Internals;
+using Microsoft.Maui.Controls.Internals;
using Sarand.Net.Mobile.Maui.App;
using Sarand.Net.Mobile.Maui.Controls;
using Sarand.Net.Mobile.Maui.Layouts;
diff --git a/SacsMobileMaui/Maui/Panels/SamPanel_Progress.cs b/SacsMobileMaui/Maui/Panels/SamPanel_Progress.cs
index bf36767..5a71b3b 100644
--- a/SacsMobileMaui/Maui/Panels/SamPanel_Progress.cs
+++ b/SacsMobileMaui/Maui/Panels/SamPanel_Progress.cs
@@ -1,4 +1,4 @@
-using Sarand.Net.Mobile.Maui.Controls;
+using Sarand.Net.Mobile.Maui.Controls;
using Sarand.Net.Mobile.Maui.Layouts;
using Sarand.Net.Mobile.Maui.Views;
using System;
diff --git a/SacsMobileMaui/Maui/Panels/SamPanel_PropertySummary.cs b/SacsMobileMaui/Maui/Panels/SamPanel_PropertySummary.cs
index 631e691..a514d84 100644
--- a/SacsMobileMaui/Maui/Panels/SamPanel_PropertySummary.cs
+++ b/SacsMobileMaui/Maui/Panels/SamPanel_PropertySummary.cs
@@ -1,4 +1,4 @@
-using Sarand.Net.Mobile.Maui.Controls;
+using Sarand.Net.Mobile.Maui.Controls;
using Sarand.Net.Mobile.Maui.Layouts;
using Sarand.Net.Mobile.Maui.Views;
using System;
diff --git a/SacsMobileMaui/Maui/Panels/SamPanel_Tab.cs b/SacsMobileMaui/Maui/Panels/SamPanel_Tab.cs
index f1a906d..58dfa38 100644
--- a/SacsMobileMaui/Maui/Panels/SamPanel_Tab.cs
+++ b/SacsMobileMaui/Maui/Panels/SamPanel_Tab.cs
@@ -1,4 +1,4 @@
-
+
using Sarand.Net.Mobile.Maui.Views;
using System;
using System.Collections.Generic;
@@ -38,11 +38,13 @@ namespace Sarand.Net.Mobile.Maui.Panels
//-------------------------------------------------------------------
// C o n t r o l A c t i v i t y
//-------------------------------------------------------------------
- public override void SetControlActivity()
+ public override void SetControlActivity(bool enabled)
{
+ base.SetControlActivity(enabled);
}
public override void SetControlsReadOnly()
{
+ base.SetControlsReadOnly();
}
//-------------------------------------------------------------------
diff --git a/SacsMobileMaui/Maui/Panels/SamPanel_Tabbed.cs b/SacsMobileMaui/Maui/Panels/SamPanel_Tabbed.cs
index 912f923..28b9d38 100644
--- a/SacsMobileMaui/Maui/Panels/SamPanel_Tabbed.cs
+++ b/SacsMobileMaui/Maui/Panels/SamPanel_Tabbed.cs
@@ -1,4 +1,4 @@
-using Sarand.Net.Mobile.Maui.Views;
+using Sarand.Net.Mobile.Maui.Views;
using Sarand.Net.Standard.Base.Utils;
using System;
using System.Collections.Generic;
@@ -165,11 +165,13 @@ namespace Sarand.Net.Mobile.Maui.Panels
//-------------------------------------------------------------------
// C o n t r o l A c t i v i t y
//-------------------------------------------------------------------
- public override void SetControlActivity()
+ public override void SetControlActivity(bool enabled)
{
+ base.SetControlActivity(enabled);
}
public override void SetControlsReadOnly()
{
+ base.SetControlsReadOnly();
}
//-------------------------------------------------------------------
diff --git a/SacsMobileMaui/Maui/Panels/SamTabPanel.cs b/SacsMobileMaui/Maui/Panels/SamTabPanel.cs
index 0235740..f7348dc 100644
--- a/SacsMobileMaui/Maui/Panels/SamTabPanel.cs
+++ b/SacsMobileMaui/Maui/Panels/SamTabPanel.cs
@@ -1,4 +1,4 @@
-using Sarand.Net.Mobile.Maui.Views;
+using Sarand.Net.Mobile.Maui.Views;
using System;
using System.Collections.Generic;
using System.Linq;
diff --git a/SacsMobileMaui/Maui/Utils/SamElementUtil.cs b/SacsMobileMaui/Maui/Utils/SamElementUtil.cs
index c5b69aa..c94790d 100644
--- a/SacsMobileMaui/Maui/Utils/SamElementUtil.cs
+++ b/SacsMobileMaui/Maui/Utils/SamElementUtil.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
diff --git a/SacsMobileMaui/Maui/Utils/SamFormUtil.cs b/SacsMobileMaui/Maui/Utils/SamFormUtil.cs
index bc07216..fd686c6 100644
--- a/SacsMobileMaui/Maui/Utils/SamFormUtil.cs
+++ b/SacsMobileMaui/Maui/Utils/SamFormUtil.cs
@@ -1,9 +1,6 @@
-using Sarand.Net.Standard.Base.App;
+using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Utils;
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
using System.Threading.Tasks;
namespace Sarand.Net.Mobile.Maui.Utils
@@ -11,39 +8,28 @@ namespace Sarand.Net.Mobile.Maui.Utils
//=======================================================================
public static class SamFormsUtil
{
- //-------------------------------------------------------------------
- // D i s p l a y A l e r t a n d W a i t
- //-------------------------------------------------------------------
- public static void DisplayAlertSync(String title, String message, String cancel = "OK")
+ // --- Display dialogs ---
+ public static Task DisplayAlertAsync(String title, String message, String cancel = "OK")
{
- if (Application.Current?.MainPage == null)
+ Page? mainPage = Application.Current?.Windows.FirstOrDefault()?.Page;
+ if (mainPage == null)
{
SaLogger.Warn(SysUtil.Fn + " Null main page. Message: " + message);
- return;
+ return Task.CompletedTask;
}
- SamThreadUtil.InvokeOnMainThreadSync(async () => await Application.Current.MainPage.DisplayAlert(title, message, cancel));
+ return SamThreadUtil.InvokeOnMainThreadAsync(() => mainPage.DisplayAlertAsync(title, message, cancel));
}
- public static bool DisplayConfirmSync(String title, String message, String accept = "Yes", String cancel = "No")
+ public static Task DisplayConfirmAsync(String title, String message, String accept = "Yes", String cancel = "No")
{
- if (Application.Current?.MainPage == null)
+ Page? mainPage = Application.Current?.Windows.FirstOrDefault()?.Page;
+ if (mainPage == null)
{
SaLogger.Warn(SysUtil.Fn + " Null main page. Message: " + message);
- return false;
+ return Task.FromResult(false);
}
- var tcs = new TaskCompletionSource();
- MainThread.BeginInvokeOnMainThread(async () =>
- {
- try
- {
- bool result = await Application.Current.MainPage.DisplayAlert(title, message, accept, cancel);
- tcs.SetResult(result);
- }
- catch (Exception ex) { tcs.SetException(ex); }
- });
- return tcs.Task.Result;
+ return SamThreadUtil.InvokeOnMainThreadAsync(() => mainPage.DisplayAlertAsync(title, message, accept, cancel));
}
- //-------------------------------------------------------------------
+ // --- The End ---
}
- //=======================================================================
}
diff --git a/SacsMobileMaui/Maui/Utils/SamImageUtil.cs b/SacsMobileMaui/Maui/Utils/SamImageUtil.cs
index cb78529..fa6aa39 100644
--- a/SacsMobileMaui/Maui/Utils/SamImageUtil.cs
+++ b/SacsMobileMaui/Maui/Utils/SamImageUtil.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
diff --git a/SacsMobileMaui/Maui/Utils/SamPageUtil.cs b/SacsMobileMaui/Maui/Utils/SamPageUtil.cs
index b2fbd2d..522a5ac 100644
--- a/SacsMobileMaui/Maui/Utils/SamPageUtil.cs
+++ b/SacsMobileMaui/Maui/Utils/SamPageUtil.cs
@@ -1,4 +1,4 @@
-using Microsoft.Maui.Graphics;
+using Microsoft.Maui.Graphics;
using System;
using System.Collections.Generic;
using System.Linq;
diff --git a/SacsMobileMaui/Maui/Utils/SamResourceUtil.cs b/SacsMobileMaui/Maui/Utils/SamResourceUtil.cs
index 3985cbe..a9ad411 100644
--- a/SacsMobileMaui/Maui/Utils/SamResourceUtil.cs
+++ b/SacsMobileMaui/Maui/Utils/SamResourceUtil.cs
@@ -1,61 +1,42 @@
-using Sarand.Net.Standard.Base.App;
+using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Utils;
using System;
-using System.Collections.Generic;
-using System.Linq;
+using System.IO;
using System.Reflection;
-using System.Text;
-using System.Threading.Tasks;
namespace Sarand.Net.Mobile.Maui.Utils
{
- //=======================================================================
public class SamResourceUtil
{
- //-------------------------------------------------------------------
- // Resource as Stream.
-
+ // --- Resource stream ---
public static Stream? GetResourceStream(String resourcePath)
{
return GetResourceStream(Assembly.GetExecutingAssembly(), resourcePath);
}
- //-------------------------------------------------------------------
public static Stream? GetResourceStream(Assembly assembly, String resourcePath)
{
+ if (String.IsNullOrWhiteSpace(resourcePath)) return null;
+
Stream? stream = assembly.GetManifestResourceStream(resourcePath);
if (stream != null) return stream;
- foreach (var res in assembly.GetManifestResourceNames())
+ foreach (String resourceName in assembly.GetManifestResourceNames())
{
- //SaLogger.Info(SysUtil.Fn + $" Resource: {res.ToString()}");
-
- // Read source file
- stream = assembly.GetManifestResourceStream(res);
- //using var reader = new StreamReader(stream);
- //var content = reader.ReadToEnd();
-
- // generate target path inside data folder
- //string targetFile = System.IO.Path.Combine(FileSystem.Current.AppDataDirectory, res);
-
- // write file into data folder
- //using FileStream outputStream = System.IO.File.OpenWrite(targetFile);
- //using StreamWriter streamWriter = new StreamWriter(outputStream);
-
- //streamWriter.Write(content);
+ if (!resourceName.EndsWith(resourcePath, StringComparison.OrdinalIgnoreCase)) continue;
+ return assembly.GetManifestResourceStream(resourceName);
}
+
return null;
}
- //-------------------------------------------------------------------
- // Log resources.
+ // --- Resource diagnostics ---
public static void LogResources(Assembly assembly)
{
- foreach (var res in assembly.GetManifestResourceNames())
- SaLogger.Info(SysUtil.Fn + $" Resource: {res.ToString()}");
+ foreach (String resourceName in assembly.GetManifestResourceNames())
+ SaLogger.Info(SysUtil.Fn + $" Resource: {resourceName}");
}
- //-------------------------------------------------------------------
+ // --- The End ---
}
- //=======================================================================
}
diff --git a/SacsMobileMaui/Maui/Utils/SamThreadUtil.cs b/SacsMobileMaui/Maui/Utils/SamThreadUtil.cs
index 2502347..5b9ee9f 100644
--- a/SacsMobileMaui/Maui/Utils/SamThreadUtil.cs
+++ b/SacsMobileMaui/Maui/Utils/SamThreadUtil.cs
@@ -1,7 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
+using System;
using System.Threading.Tasks;
namespace Sarand.Net.Mobile.Maui.Utils
@@ -19,12 +16,10 @@ namespace Sarand.Net.Mobile.Maui.Utils
return MainThread.IsMainThread;
}
- //-------------------------------------------------------------------
- // I n v o k e o n M a i n T h r e a d a n d W a i t
- //-------------------------------------------------------------------
+ // --- Fire-and-forget dispatch ---
- /// Invoke task on main thread.
- public static void InvokeOnMainThread(Action taskFn)
+ /// Invoke an action on the main thread without waiting for completion.
+ public static void PostToMainThread(Action taskFn)
{
MainThread.BeginInvokeOnMainThread(() =>
{
@@ -32,38 +27,32 @@ namespace Sarand.Net.Mobile.Maui.Utils
});
}
- /// Invoke task on main thread and wait for completion.
- public static void InvokeOnMainThreadSync(Action taskFn)
+ // --- Awaitable dispatch ---
+
+ /// Invoke an action on the main thread and await its completion.
+ public static Task InvokeOnMainThreadAsync(Action taskFn)
{
- var tcs = new TaskCompletionSource