Improve shared MAUI controls and tests
This commit is contained in:
@@ -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.
|
||||
/// <summary>Shared random-number generator for common MAUI code.</summary>
|
||||
public static Random Random { get; set; } = new Random();
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Localisation.
|
||||
// --- Localisation ---
|
||||
/// <summary>Application-wide culture settings used by consumers that opt in.</summary>
|
||||
public static class Locale
|
||||
{
|
||||
/// <summary>The culture used for application-level formatting.</summary>
|
||||
public static CultureInfo CultureInfo { get; set; } = CultureInfo.CurrentCulture;
|
||||
/// <summary>Text rules associated with <see cref="CultureInfo"/>.</summary>
|
||||
public static TextInfo TextInfo { get; set; } = CultureInfo.TextInfo;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Visuals.
|
||||
// --- Visuals ---
|
||||
/// <summary>Supported positions for optional page content.</summary>
|
||||
public enum DisplayPosition { None, Left, Middle, Right }
|
||||
|
||||
/// <summary>Shared visual defaults for common MAUI components.</summary>
|
||||
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 ---
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
|
||||
@@ -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 ---
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace Sarand.Net.Mobile.Maui.Controls
|
||||
{
|
||||
// --- Definitions ---
|
||||
public interface ISamControl
|
||||
{
|
||||
void SetControlActivity(bool enabled);
|
||||
|
||||
// --- The End ---
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
namespace Sarand.Net.Mobile.Maui.Controls
|
||||
{
|
||||
// --- Native control styling ---
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public interface ISamNativeControlStyle
|
||||
{
|
||||
/// <summary>Removes the native control border where supported.</summary>
|
||||
bool NativeNoBorder { get; set; }
|
||||
/// <summary>Removes an Android-style underline where supported; other platforms may have no equivalent.</summary>
|
||||
bool NativeNoUnderline { get; set; }
|
||||
/// <summary>Makes the native control background transparent where supported.</summary>
|
||||
bool NativeBackgroundClear { get; set; }
|
||||
|
||||
// --- The End ---
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>Control configuration that can be changed dynamically.</summary>
|
||||
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<CheckedChangedEventArgs>? 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 ---
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
|
||||
@@ -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 ---
|
||||
|
||||
/// <summary>Control configuration that can be changed dynamically.</summary>
|
||||
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<FocusEventArgs>? Focused;
|
||||
protected void Control_Focused(object? sender, FocusEventArgs e)
|
||||
{
|
||||
if (Focused != null) Focused.Invoke(sender, e);
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
public new event EventHandler<FocusEventArgs>? 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 ---
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
|
||||
@@ -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
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>Control configuration that can be changed dynamically.</summary>
|
||||
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<TextChangedEventArgs>? 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 ---
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
|
||||
@@ -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
|
||||
/// <summary>
|
||||
/// Application button extension point. It currently adds no behavior beyond
|
||||
/// the MAUI <see cref="Button"/> contract.
|
||||
/// </summary>
|
||||
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 ---
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
|
||||
@@ -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
|
||||
/// <summary>
|
||||
/// Application check-box extension point. It currently adds no behavior
|
||||
/// beyond the MAUI <see cref="CheckBox"/> contract.
|
||||
/// </summary>
|
||||
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 ---
|
||||
}
|
||||
//======================================================================
|
||||
}
|
||||
|
||||
@@ -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<DateChangedEventArgs>? 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 ---
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
|
||||
@@ -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<DateChangedEventArgs>? DateSelected;
|
||||
//-------------------------------------------------------------------
|
||||
private void PickerTime_TimeChanged(object? sender, SamTimePicker.TimeChangedEventArgs e)
|
||||
{
|
||||
if (TimeChanged != null) TimeChanged.Invoke(sender, e);
|
||||
}
|
||||
public event EventHandler<SamTimePicker.TimeChangedEventArgs>? TimeChanged;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// --- The End ---
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
|
||||
@@ -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 ---
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
|
||||
@@ -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 ---
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
|
||||
@@ -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
|
||||
/// <summary>
|
||||
/// Application image-button extension point. It currently adds no active
|
||||
/// behavior beyond the MAUI <see cref="ImageButton"/> contract.
|
||||
/// </summary>
|
||||
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 ---
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
|
||||
@@ -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 ---
|
||||
|
||||
|
||||
/// <summary>Default (initial) font size.</summary>
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Font size proportion.</summary>
|
||||
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 ---
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
|
||||
@@ -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<SamPickerItem> pickerItems = new List<SamPickerItem>();
|
||||
// --- Data Members ---
|
||||
|
||||
private readonly SamPickerItemCollection pickerItems = new SamPickerItemCollection();
|
||||
|
||||
// --- Construction ---
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamPicker()
|
||||
{
|
||||
DefaultFontSize = FontSize;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
// --- Properties ---
|
||||
|
||||
public double DefaultFontSize { get; }
|
||||
/// <summary>Whether the picker is currently replacing its item list.</summary>
|
||||
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 ---
|
||||
|
||||
/// <summary>
|
||||
/// Does the list contain an item with the same Id.
|
||||
/// <para>NB Invalid Id values are matched.</para>
|
||||
/// </summary>
|
||||
public bool ContainsItemId(SysId id)
|
||||
{
|
||||
return pickerItems.Exists(item => SysId.ToInt(item.Id) == SysId.ToInt(id));
|
||||
return pickerItems.ContainsId(id);
|
||||
}
|
||||
/// <summary>
|
||||
/// Does the list contain an item with the same code.
|
||||
@@ -65,9 +64,8 @@ namespace Sarand.Net.Mobile.Maui.Controls
|
||||
/// </summary>
|
||||
public bool ContainsItemCode(String code)
|
||||
{
|
||||
return pickerItems.Exists(item => item.Code.EqualsCI(code));
|
||||
return pickerItems.ContainsCode(code);
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>Remove all items from the picker.</summary>
|
||||
public void ClearItems()
|
||||
{
|
||||
@@ -75,22 +73,31 @@ namespace Sarand.Net.Mobile.Maui.Controls
|
||||
ItemsSource = null;
|
||||
pickerItems.Clear();
|
||||
}
|
||||
/// <summary>Replace existing picker item list.</summary>
|
||||
/// <summary>Replace existing picker item list and raise <see cref="Populated"/>.</summary>
|
||||
public void SetItems(List<SamPickerItem> 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();
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>
|
||||
/// Add an item identified by a SysId value.
|
||||
/// <para>NB Fails if an item already exists with the same id.</para>
|
||||
/// </summary>
|
||||
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
|
||||
/// </summary>
|
||||
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 ---
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
|
||||
@@ -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<SamTabPanel> tabPanels = new List<SamTabPanel>();
|
||||
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 ---
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
|
||||
@@ -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:";
|
||||
/// <summary>Gets or sets the HTML displayed by the web view.</summary>
|
||||
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 ---
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
|
||||
@@ -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 ---
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
/// <summary>
|
||||
/// Remove borders around entry and picker controls.
|
||||
/// Apply configured native styling to Sam entry, editor, and picker controls.
|
||||
/// <para>Also make background transparent.</para>
|
||||
/// </summary>
|
||||
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 ---
|
||||
}
|
||||
//========================================================================
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 ---
|
||||
}
|
||||
}
|
||||
@@ -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 ---
|
||||
}
|
||||
}
|
||||
@@ -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<SamPicker.SamPickerItem> items = new List<SamPicker.SamPickerItem>();
|
||||
|
||||
public List<SamPicker.SamPickerItem> Items { get { return items; } }
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
items.Clear();
|
||||
}
|
||||
|
||||
public void Replace(IEnumerable<SamPicker.SamPickerItem> 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<Element> GetElements(Element? root)
|
||||
{
|
||||
if (root == null) yield break;
|
||||
yield return root;
|
||||
foreach (Element descendant in root.GetVisualTreeDescendants())
|
||||
yield return descendant;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
@@ -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<bool> 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<bool>();
|
||||
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 ---
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Microsoft.Maui.Graphics;
|
||||
using Microsoft.Maui.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
@@ -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 ---
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
|
||||
@@ -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 ---
|
||||
|
||||
/// <summary>Invoke task on main thread.</summary>
|
||||
public static void InvokeOnMainThread(Action taskFn)
|
||||
/// <summary>Invoke an action on the main thread without waiting for completion.</summary>
|
||||
public static void PostToMainThread(Action taskFn)
|
||||
{
|
||||
MainThread.BeginInvokeOnMainThread(() =>
|
||||
{
|
||||
@@ -32,38 +27,32 @@ namespace Sarand.Net.Mobile.Maui.Utils
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>Invoke task on main thread and wait for completion.</summary>
|
||||
public static void InvokeOnMainThreadSync(Action taskFn)
|
||||
// --- Awaitable dispatch ---
|
||||
|
||||
/// <summary>Invoke an action on the main thread and await its completion.</summary>
|
||||
public static Task InvokeOnMainThreadAsync(Action taskFn)
|
||||
{
|
||||
var tcs = new TaskCompletionSource<Object>();
|
||||
MainThread.BeginInvokeOnMainThread(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
taskFn();
|
||||
tcs.SetResult(true);
|
||||
}
|
||||
catch (Exception ex) { tcs.SetException(ex); }
|
||||
});
|
||||
return MainThread.InvokeOnMainThreadAsync(taskFn);
|
||||
}
|
||||
|
||||
/// <summary>Invoke task on main thread and wait for completion.</summary>
|
||||
public static T InvokeOnMainThreadSync<T>(Func<T> taskFn)
|
||||
/// <summary>Invoke an asynchronous function on the main thread and await its completion.</summary>
|
||||
public static Task InvokeOnMainThreadAsync(Func<Task> taskFn)
|
||||
{
|
||||
var tcs = new TaskCompletionSource<T>();
|
||||
MainThread.BeginInvokeOnMainThread(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = taskFn();
|
||||
tcs.SetResult(result);
|
||||
}
|
||||
catch (Exception ex) { tcs.SetException(ex); }
|
||||
});
|
||||
return tcs.Task.Result;
|
||||
return MainThread.InvokeOnMainThreadAsync(taskFn);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>Invoke a function on the main thread and await its result.</summary>
|
||||
public static Task<T> InvokeOnMainThreadAsync<T>(Func<T> taskFn)
|
||||
{
|
||||
return MainThread.InvokeOnMainThreadAsync(taskFn);
|
||||
}
|
||||
|
||||
/// <summary>Invoke an asynchronous function on the main thread and await its result.</summary>
|
||||
public static Task<T> InvokeOnMainThreadAsync<T>(Func<Task<T>> taskFn)
|
||||
{
|
||||
return MainThread.InvokeOnMainThreadAsync(taskFn);
|
||||
}
|
||||
|
||||
// --- The End ---
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@@ -18,7 +18,7 @@ namespace Sarand.Net.Mobile.Maui.Views
|
||||
/// </summary>
|
||||
void ConfigureComponents();
|
||||
|
||||
void SetControlActivity();
|
||||
void SetControlActivity(bool enabled);
|
||||
|
||||
void SetControlsReadOnly();
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
||||
namespace Sarand.Net.Mobile.Maui.Views
|
||||
{
|
||||
//=======================================================================
|
||||
public class SamBorder : Border
|
||||
public class SamBorder : Border, ISamView
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
@@ -32,8 +32,9 @@ namespace Sarand.Net.Mobile.Maui.Views
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Control activity.
|
||||
public virtual void SetControlActivity()
|
||||
public virtual void SetControlActivity(bool enabled)
|
||||
{
|
||||
if (IsEnabled != enabled) IsEnabled = enabled;
|
||||
SetControlsReadOnly();
|
||||
}
|
||||
public virtual void SetControlsReadOnly()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@@ -32,8 +32,9 @@ namespace Sarand.Net.Mobile.Maui.Views
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Control activity.
|
||||
public virtual void SetControlActivity()
|
||||
public virtual void SetControlActivity(bool enabled)
|
||||
{
|
||||
if (IsEnabled != enabled) IsEnabled = enabled;
|
||||
SetControlsReadOnly();
|
||||
}
|
||||
public virtual void SetControlsReadOnly()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Sarand.Net.Mobile.Maui.Utils;
|
||||
using Sarand.Net.Mobile.Maui.Utils;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -33,7 +33,7 @@ namespace Sarand.Net.Mobile.Maui.Views
|
||||
public bool ReadOnly
|
||||
{
|
||||
get { return readOnly; }
|
||||
set { if (readOnly == value) return; readOnly = value; SetControlActivity(); }
|
||||
set { if (readOnly == value) return; readOnly = value; SetControlActivity(IsEnabled); }
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
@@ -44,8 +44,9 @@ namespace Sarand.Net.Mobile.Maui.Views
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Control activity.
|
||||
public virtual void SetControlActivity()
|
||||
public virtual void SetControlActivity(bool enabled)
|
||||
{
|
||||
if (IsEnabled != enabled) IsEnabled = enabled;
|
||||
SetControlsReadOnly();
|
||||
}
|
||||
public virtual void SetControlsReadOnly()
|
||||
@@ -60,7 +61,7 @@ namespace Sarand.Net.Mobile.Maui.Views
|
||||
base.OnPropertyChanged(propertyName);
|
||||
if (propertyName.EqualsCI(IsEnabledProperty.PropertyName))
|
||||
{
|
||||
SetControlActivity();
|
||||
SetControlActivity(IsEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@@ -32,8 +32,9 @@ namespace Sarand.Net.Mobile.Maui.Views
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Control activity.
|
||||
public virtual void SetControlActivity()
|
||||
public virtual void SetControlActivity(bool enabled)
|
||||
{
|
||||
if (IsEnabled != enabled) IsEnabled = enabled;
|
||||
SetControlsReadOnly();
|
||||
}
|
||||
public virtual void SetControlsReadOnly()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@@ -32,8 +32,9 @@ namespace Sarand.Net.Mobile.Maui.Views
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Control activity.
|
||||
public virtual void SetControlActivity()
|
||||
public virtual void SetControlActivity(bool enabled)
|
||||
{
|
||||
if (IsEnabled != enabled) IsEnabled = enabled;
|
||||
SetControlsReadOnly();
|
||||
}
|
||||
public virtual void SetControlsReadOnly()
|
||||
|
||||
Reference in New Issue
Block a user