From 1a1c8e71fcd14858f595029f089b2d4a00202b32 Mon Sep 17 00:00:00 2001
From: ogi <Administrator@S-OGI-PC>
Date: Fri, 05 Dec 2025 09:24:16 +0900
Subject: [PATCH] プロジェクトファイルを追加。

---
 HotelPms.Client.Blazor/ViewModel/ValidModelEx.cs |  731 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 731 insertions(+), 0 deletions(-)

diff --git a/HotelPms.Client.Blazor/ViewModel/ValidModelEx.cs b/HotelPms.Client.Blazor/ViewModel/ValidModelEx.cs
new file mode 100644
index 0000000..0958dfe
--- /dev/null
+++ b/HotelPms.Client.Blazor/ViewModel/ValidModelEx.cs
@@ -0,0 +1,731 @@
+using HotelPms.Client.Blazor.Pages.UseDetail;
+using HotelPms.Client.Blazor.Services;
+using HotelPms.Client.Blazor.Util;
+using HotelPms.Share.IO;
+using HotelPms.Share.Util;
+using Microsoft.AspNetCore.Components.Forms;
+using Microsoft.AspNetCore.Components.Web;
+using Microsoft.JSInterop;
+using System.Collections.Concurrent;
+using System.Reflection.Metadata;
+using System.Text;
+
+namespace HotelPms.Client.Blazor.ViewModel
+{
+    /// <summary>
+    /// ViewModelExとして使って、
+    /// Windows Fromスタイルの入力チェック方式
+    /// C# Call jsは遅いため、逆にjsよりCallBackと使用する
+    /// ※@bind-value使わない
+    /// </summary>
+    public abstract class ValidModelEx : IDisposable
+    {
+        #region  ★★★★★ Declartions ★★★★★
+
+        public delegate void ValidEventHandler(ValidField sender, ValidEventArgs e);
+        public delegate Task<bool> ValidResultEventHandler(ValidField sender, ValidEventArgs e);
+
+        public event ValidResultEventHandler BeforeAutoNextFocus;
+        public event ValidEventHandler AfterAutoNextFocus;
+        public event ValidEventHandler AfterEnter;
+        public event ValidEventHandler AfterLeave;
+        public event ValidResultEventHandler ValueChanged;
+        public event ValidResultEventHandler ShowList;
+        public event ValidResultEventHandler BusinessValid;
+
+        public static string Chr_Num = "0123456789";
+        public static string Chr_Alpha_S = "abcdefghijklmnopqrstuvwxyz ";
+        public static string Chr_Alpha_C = "ABCDEFGHIJKLMNOPQRSTUVWXYZ ";
+        public static string Chr_Kana = "ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙゚ ";
+        public static string Chr_Alpha = Chr_Alpha_S + Chr_Alpha_C;
+        public static string Chr_NumAlpha = Chr_Num + Chr_Alpha;
+        public static string Chr_ANK = Chr_NumAlpha + Chr_Kana;
+
+        #endregion
+
+        #region  ★★★★★ Property ★★★★★
+
+        /// <summary>
+        /// ID毎のインスタンス格納
+        /// </summary>
+        public static ConcurrentDictionary<string, ValidModelEx> Storage { get; set; } = new ConcurrentDictionary<string, ValidModelEx>();
+
+        public IJSRuntime JSRuntime { get; set; }
+
+        public List<ValidField> Fields { get; set; } = new List<ValidField>();
+        private Dictionary<string, ValidField> dict = new Dictionary<string, ValidField>();
+
+        public Action ErrRefresh { get; set; }
+
+        /// <summary>
+        /// Enterキーを押したかどうか
+        /// </summary>
+        public bool EnterPush { get; set; }
+
+        /// <summary>
+        /// Upキー押したかどうか
+        /// </summary>
+        public bool ArrowUpPush { get; set; }
+
+        /// <summary>
+        /// 0.新規 1.編集 2.削除
+        /// </summary>
+        public int EditMode { get; set; }
+
+        /// <summary>
+        /// 全体のエラー
+        /// </summary>
+        public string ErrText { get; set; }
+
+        /// <summary>
+        /// 一覧表示の検索キー対象項目一覧
+        /// </summary>
+        public List<string> FilterFields { get; set; } = new List<string>();
+
+        /// <summary>
+        /// 一覧表示の順番対象項目一覧
+        /// </summary>
+        public SortedList<int, string> OrderFields { get; set; } = new SortedList<int, string>();
+
+        /// <summary>
+        /// Guid
+        /// </summary>
+        public string ID { get; set; } = string.Empty;
+
+        public bool DisableKeyboard { get; set; } = false;
+
+        #endregion
+
+        #region  ★★★★★ Class Event ★★★★★
+
+        public ValidModelEx(IJSRuntime js)
+        {
+            JSRuntime = js;
+            ID = Guid.NewGuid().ToString();
+            Storage[ID] = this;
+        }
+
+        public void Dispose()
+        {
+            Storage.TryRemove(ID, out ValidModelEx model);
+        }
+
+        #endregion
+
+        #region  ★★★★★ Control Event ★★★★★
+
+        /// <summary>
+        /// ①フォーカス入る
+        /// ※BlazorのBugでEnterのパラメータ変数できない
+        /// </summary>
+        /// <param name="index"></param>
+        public void Enter(int index, JsInputCoreEventArgs e)
+        {
+            EnvironmentSetting.Debug($"Enter:{index}⇒OrgText={e.OrgText},Text={e.Text}");
+
+            Fields[index].OrgText = e.OrgText;
+            if ((Fields[index].ShowStyle & SystemEnum.EShowStyle.ThousandSeparator) == SystemEnum.EShowStyle.ThousandSeparator && Fields[index].Text.Length > 0)
+            {
+                Fields[index].Text = Fields[index].Text.Replace(",", string.Empty); //コントロールの値連動する                
+            }
+            e.ResultNo = 0;
+
+            if (AfterEnter != null) { AfterEnter(Fields[index], new ValidEventArgs()); }
+        }
+
+        /// <summary>
+        /// ※IMEでもここに通る
+        /// 例:「おぎ」を打つ時、[O]⇒e.Key="Proess"、e.KeyCode="KeyO"、e.Type="KeyDown"
+        /// ②Enter⇒KeyDown⇒KeyPress⇒Leave
+        /// </summary>
+        /// <param name="index"></param>
+        /// <param name="e"></param>
+        /// <returns></returns>
+        public async Task KeyUp(int index, JsInputCoreEventArgs e)
+        {
+            if(DisableKeyboard) { return; }
+
+            if (e.Key == "ArrowUp")
+            {
+                try
+                {
+                    EnvironmentSetting.Debug($"KeyUp⇒ArrowUp:{index}");
+                    if (!await SetAutoNextFocus(index, false, e)) { return; }
+                    e.ResultNo = 0;
+                }
+                catch { }
+                finally
+                {
+                }
+            }
+            else if (e.Key == "End")
+            {
+                EnvironmentSetting.Debug($"KeyUp⇒End:{index}");
+                if (ShowList != null) 
+                {
+                    DisableKeyboard = true;
+                    ValidEventArgs eventArgs = new();
+                    bool ret = await ShowList(Fields[index], eventArgs);
+                    DisableKeyboard = false;
+                    if (!eventArgs.Cancel) { await SetAutoNextFocus(index, true, e); }
+                }
+                e.Text = Fields[index].Text;
+                e.ResultNo = 0;
+            }
+            else if (e.Key == "Enter")
+            {
+                await KeyEnter(index, e);
+            }
+        }
+
+        /// <summary>
+        /// ※注意:IMEモードではここに通らない
+        /// e.Codeだと、二つEnterが違う
+        /// ※※注意:ここで@bind-Valueを変更しても、直ぐにinputへ反映しない
+        /// 必ずjs側で強制的にtextをセットする
+        /// 整合性を保るため、@bind-Valueも同じでセットする
+        /// </summary>
+        /// <param name="index"></param>
+        /// <param name="e"></param>
+        /// <returns></returns>
+        public async Task KeyEnter(int index, JsInputCoreEventArgs e)
+        {
+            try
+            {
+                FormatInput(index, e);
+                string text = e.Text;
+                EnvironmentSetting.Debug($"Return:{index}⇒{text}");
+
+                //値変更したら、イベント発生
+                if (await IsValueChanged(index, text, true, e))
+                {
+                    //通常チェックを行う
+                    Fields[index].Error = false;
+                    Fields[index].ErrorText = string.Empty;
+                    if (!IsCorrectText(index, text, true)) { return; }
+
+                    bool bvRet = true;
+                    if (BusinessValid != null)
+                    {
+                        //業務チェックを行う
+                        ValidEventArgs vea = new ValidEventArgs() { Text = text, EnterPush = true };
+                        bvRet = await BusinessValid(Fields[index], vea);
+                        EnvironmentSetting.Debug($"BusinessValid結果(Enter):{bvRet},Error:{Fields[index].Error},index={index}");
+                    }
+                    EnterPush = true;   //Enterを押した知らせ                     
+                    if (bvRet) { SetOrgText(index, text); } else { return; } //BusinessValid結果:OK⇒OrgTextを反映する NG⇒前へ進まない 
+                    Fields[index].Text = text;   //入力値確定
+                    e.ResultNo = 0;
+                }
+                else
+                {
+                    //必須判断:初期表示時:OrgTextは空白のため、値変更しないまま
+                    if (text.Trim().Length == 0 && Fields[index].Required)
+                    {
+                        Fields[index].Error = true;
+                        Fields[index].ErrorText = "内容を入力してください。";
+                        return;
+                    }
+                    e.ResultNo = 1;
+                }
+
+                if (!await SetAutoNextFocus(index, true, e)) { e.ResultNo = 9; return; }
+            }
+            catch { }
+            finally
+            {
+                if (ErrRefresh != null && Fields[index].Error) 
+                {
+                    EnvironmentSetting.Debug($"Error:{Fields[index].Error},ErrorText={Fields[index].ErrorText}");
+                    ErrRefresh(); 
+                }   
+            }
+        }
+
+        public void FormatInput(int index, JsInputCoreEventArgs e)
+        { 
+            try
+            {
+                if (Fields[index].InputStyle == SystemEnum.EInputStyle.Date)
+                {
+                    e.Text = CConvert.ParseDate(e.Text, Fields[index].OrgText);
+                }
+                else if (Fields[index].InputStyle == SystemEnum.EInputStyle.Time)
+                {
+                    e.Text = CConvert.ParseTime(e.Text, Fields[index].OrgText);
+                }
+            }
+            catch { }
+        }
+
+        /// <summary>
+        /// そのタイミングbind反映したはず
+        /// </summary>
+        /// <param name="index"></param>
+        /// <returns></returns>
+        //private async Task LeaveMud(int index)
+        public async Task Leave(int index, JsInputCoreEventArgs e)
+        {
+            string text = string.Empty;
+            bool refresh = false;
+            try
+            {
+                EnvironmentSetting.Debug($"Leave:{index}⇒OrgText={Fields[index].OrgText},Text={Fields[index].Text}");
+                FormatInput(index, e);
+                text = e.Text;
+
+                if (EnterPush)
+                {
+                    //Enterキーを押した時にも既にチェック済
+                    EnterPush = false;
+                }
+                else
+                {
+                    //値変更したら、イベント発生
+                    if (!await IsValueChanged(index, text, false, e)) 
+                    {
+                        //必須判断:初期表示時:OrgTextは空白のため、値変更しないまま
+                        Fields[index].Error = false;
+                        Fields[index].ErrorText = string.Empty;
+                        e.ResultNo = 1; 
+                        return; 
+                    }
+
+                    //通常チェックを行う
+                    Fields[index].Error = false;
+                    Fields[index].ErrorText = string.Empty;
+                    if (IsCorrectText(index, text, false))
+                    {
+                        if (BusinessValid != null)
+                        {
+                            //業務チェックを行う
+                            ValidEventArgs vea = new ValidEventArgs() { Text = text };
+                            bool bvRet = await BusinessValid(Fields[index], vea);
+                            EnvironmentSetting.Debug($"BusinessValid結果:{bvRet},Error:{Fields[index].Error},index={index}");
+                            if (!bvRet)
+                            {
+                                Fields[index].Error = true;
+                            }
+                        }
+                    }
+                }
+
+                if (Fields[index].Error)
+                {
+                    EnvironmentSetting.Debug($"元値に復元する↓:Error={Fields[index].Error},index={index}");
+                    //エラーの場合、元値に復元する
+                    Fields[index].Text = Fields[index].OrgText;
+                    e.Text = Fields[index].OrgText;
+                    Fields[index].Error = false;
+                    Fields[index].ErrorText = string.Empty;
+                    EnvironmentSetting.Debug($"元値に復元する↑:Error={Fields[index].Error},ErrorText={Fields[index].ErrorText},Text={Fields[index].Text},index={index}");
+                    refresh = true;
+                    return;
+                }
+
+                Fields[index].Text = text;  //確定
+                e.Text = text;
+                SetOrgText(index, text);
+                e.ResultNo = 0;
+            }
+            catch (Exception ex)
+            {
+                OperationLog.Instance.WriteLog(ex.Message);
+            }
+            finally
+            {
+                if ((Fields[index].ShowStyle & SystemEnum.EShowStyle.ThousandSeparator) == SystemEnum.EShowStyle.ThousandSeparator && text.Length > 0)
+                {
+                    text = CConvert.ToThousandSeparator(CConvert.ToDecimal(text), Fields[index].ThousandFormat); //コントロールの値連動する (小数点!!!!)
+                    Fields[index].Text = text;
+                    e.Text = text;
+                }
+                else if ((Fields[index].ShowStyle & SystemEnum.EShowStyle.ZeroPad) == SystemEnum.EShowStyle.ZeroPad && text.Length > 0)
+                {
+                    text = text.PadLeft(Fields[index].MaxLenth, '0');
+                    Fields[index].Text = text;
+                    e.Text = text;
+                }
+
+                if (AfterLeave != null) { AfterLeave(Fields[index], new ValidEventArgs()); }
+                if (ArrowUpPush) { ArrowUpPush = false; }
+                if (refresh && ErrRefresh != null) { ErrRefresh(); }
+            }
+        }
+
+        #endregion
+
+        #region  ★★★★★ Private Function ★★★★★
+
+        private async Task<bool> SetAutoNextFocus(int index, bool isEnter, JsInputCoreEventArgs e)
+        {
+            try
+            {
+                if (BeforeAutoNextFocus != null)
+                {
+                    ValidEventArgs args = new ValidEventArgs() { EnterPush = isEnter };
+                    if (!await BeforeAutoNextFocus(Fields[index], args)) { return false; }
+                }
+
+                int hitIdx = -1;
+                if (isEnter)
+                {
+                    for (int i = index + 1; i < Fields.Count; i++)
+                    {
+                        if (!Fields[i].Disabled)
+                        {
+                            hitIdx = i;
+                            break;
+                        }
+                    }
+
+                    if (hitIdx == -1) { return false; }
+                }
+                else
+                {
+                    if (index == 0) { return true; }
+
+                    for (int i = index - 1; i >= 0; i--)
+                    {
+                        if (!Fields[i].Disabled)
+                        {
+                            hitIdx = i;
+                            break;
+                        }
+                    }
+
+                    if (hitIdx == -1) { return false; }
+                }
+                e.NextFocus = $"{e.ID}-{hitIdx}";
+                return true;
+            }
+            catch
+            {
+                return false;
+            }
+            finally
+            {
+                if (AfterAutoNextFocus != null) { AfterAutoNextFocus(Fields[index], new ValidEventArgs() { EnterPush = isEnter }); }
+            }
+        }
+
+        private async Task<bool> IsValueChanged(int index, string inputText, bool isEnter, JsInputCoreEventArgs e)
+        {
+            string newInputValue = string.Empty;
+            if ((Fields[index].ShowStyle & SystemEnum.EShowStyle.ThousandSeparator) == SystemEnum.EShowStyle.ThousandSeparator && inputText.Length > 0)
+            {
+                newInputValue = CConvert.ToThousandSeparator(CConvert.ToDecimal(inputText), Fields[index].ThousandFormat);   //※OrgTextはカンマ区切りのまま
+            }
+            else
+            {
+                newInputValue = inputText;
+            }
+
+            EnvironmentSetting.Debug($"CheckValueChanged:{index}⇒inputText={newInputValue},OrgText={Fields[index].OrgText}");
+            if (newInputValue.Equals(Fields[index].OrgText))
+            {
+                return false;
+            }
+
+            //値変更したかどうか
+            if (ValueChanged != null)
+            {
+                ValidEventArgs vce = new ValidEventArgs() { Text = inputText, EnterPush = isEnter };
+                if (!await ValueChanged(Fields[index], vce))
+                {
+                    //元の値に戻す
+                    if (vce.ResetOrgValue)
+                    {
+                        //※元の値に戻す且つフォーカス移動必要
+                        Fields[index].Text = Fields[index].OrgText;
+                        e.Text = Fields[index].OrgText;
+                    }
+                    return false;  //外から強制的に値変らないようにする
+                }
+            }
+            return true;
+        }
+
+        private void SetOrgText(int index, string inputText)
+        {
+            if ((Fields[index].ShowStyle & SystemEnum.EShowStyle.ThousandSeparator) == SystemEnum.EShowStyle.ThousandSeparator)
+            {
+                Fields[index].OrgText = CConvert.ToThousandSeparator(CConvert.ToDecimal(inputText), Fields[index].ThousandFormat);   //※OrgTextはカンマ区切りのまま
+            }
+            else
+            {
+                Fields[index].OrgText = inputText;
+            }
+        }
+
+        private bool IsCorrectValue(int index, string inputText)
+        {
+            string wsChkStr = "";
+            SystemEnum.EInputChar wlErrFlg = 0;
+            try
+            {
+                string text = (Fields[index].ShowStyle & SystemEnum.EShowStyle.ThousandSeparator) == SystemEnum.EShowStyle.ThousandSeparator ? inputText.Replace(",", string.Empty) : inputText;
+
+                SystemEnum.EInputChar inputType = Fields[index].InputChar;
+                //半角チェック
+                if ((inputType & SystemEnum.EInputChar.Half) == SystemEnum.EInputChar.Half && !CConvert.IsHalf(text))
+                {
+                    Fields[index].Error = true;
+                    Fields[index].ErrorText = "半角入力してください。";
+                    return false;
+                }
+
+                //全角チェック
+                if ((inputType & SystemEnum.EInputChar.Full) == SystemEnum.EInputChar.Full && !CConvert.IsFull(text))
+                {
+                    Fields[index].Error = true;
+                    Fields[index].ErrorText = "全角入力してください。";
+                    return false;
+                }
+
+                //数字
+                if ((inputType & SystemEnum.EInputChar.Num) == SystemEnum.EInputChar.Num)
+                {
+                    wsChkStr = wsChkStr + Chr_Num;
+                    wlErrFlg = wlErrFlg | SystemEnum.EInputChar.Num;
+                }
+
+                //.
+                if ((inputType & SystemEnum.EInputChar.Dot) == SystemEnum.EInputChar.Dot)
+                {
+                    wsChkStr = wsChkStr + ".";
+                    wlErrFlg = wlErrFlg | SystemEnum.EInputChar.Dot;
+                }
+
+                //[/]
+                if ((inputType & SystemEnum.EInputChar.Slash) == SystemEnum.EInputChar.Slash)
+                {
+                    wsChkStr = wsChkStr + "/";
+                    wlErrFlg = wlErrFlg | SystemEnum.EInputChar.Slash;
+                }
+
+                //Space
+                if ((inputType & SystemEnum.EInputChar.Space) == SystemEnum.EInputChar.Space)
+                {
+                    wsChkStr = wsChkStr + " ";
+                    wlErrFlg = wlErrFlg | SystemEnum.EInputChar.Space;
+                }
+
+                //-
+                if ((inputType & SystemEnum.EInputChar.Subtract) == SystemEnum.EInputChar.Subtract)
+                {
+                    wsChkStr = wsChkStr + "-";
+                    wlErrFlg = wlErrFlg | SystemEnum.EInputChar.Subtract;
+                }
+
+                //:
+                if ((inputType & SystemEnum.EInputChar.Colon) == SystemEnum.EInputChar.Colon)
+                {
+                    wsChkStr = wsChkStr + ":";
+                    wlErrFlg = wlErrFlg | SystemEnum.EInputChar.Colon;
+                }
+
+                //,
+                if ((inputType & SystemEnum.EInputChar.Comma) == SystemEnum.EInputChar.Comma)
+                {
+                    wsChkStr = wsChkStr + ",";
+                    wlErrFlg = wlErrFlg | SystemEnum.EInputChar.Colon;
+                }
+
+                //小英
+                if ((inputType & SystemEnum.EInputChar.Alpha_C) == SystemEnum.EInputChar.Alpha_C)
+                {
+                    wsChkStr = wsChkStr + Chr_Alpha_C;
+                    wlErrFlg = wlErrFlg | SystemEnum.EInputChar.Alpha_C;
+                }
+
+                //大英
+                if ((inputType & SystemEnum.EInputChar.Alpha_S) == SystemEnum.EInputChar.Alpha_S)
+                {
+                    wsChkStr = wsChkStr + Chr_Alpha_S;
+                    wlErrFlg = wlErrFlg | SystemEnum.EInputChar.Alpha_S;
+                }
+
+                //カナ
+                if ((inputType & SystemEnum.EInputChar.Kana) == SystemEnum.EInputChar.Kana)
+                {
+                    wsChkStr = wsChkStr + Chr_Kana;
+                    wlErrFlg = wlErrFlg | SystemEnum.EInputChar.Kana;
+                }
+                if (wsChkStr.Length > 0)
+                {
+                    if (CConvert.IsInOwnStr(text, wsChkStr) == false)
+                    {
+                        Fields[index].Error = true;
+                        if (wlErrFlg == SystemEnum.EInputChar.Num)
+                        {
+                            Fields[index].ErrorText = "数字を入力してください。";
+                        }
+                        else if (wlErrFlg == SystemEnum.EInputChar.Kana)
+                        {
+                            Fields[index].ErrorText = "半角カナを入力してください。";
+                        }
+                        else if (wlErrFlg == SystemEnum.EInputChar.Alpha_S)
+                        {
+                            Fields[index].ErrorText = "小英文字を入力してください。";
+                        }
+                        else if (wlErrFlg == SystemEnum.EInputChar.Alpha_C)
+                        {
+                            Fields[index].ErrorText = "大英文字を入力してください。";
+                        }
+                        else
+                        {
+                            Fields[index].ErrorText = "正しい値を入力してください。";
+                        }
+                        return false;
+                    }
+                }
+                return true;
+            }
+            catch (Exception ex)
+            {
+                OperationLog.Instance.WriteLog($"IsCorrectValue:{ex.Message}");
+                return false;
+            }
+        }
+
+        private bool IsCorrectText(int index, string inputText, bool isEnter)
+        {
+            //必須判断
+            if (inputText.Trim().Length == 0 && Fields[index].Required)
+            {
+                Fields[index].Error = true;
+                Fields[index].ErrorText = "内容を入力してください。";
+                return false;
+            }
+
+            //入力文字判断
+            if (!IsCorrectValue(index, inputText)) { return false; }
+
+            //日付判断
+            if (Fields[index].InputStyle == SystemEnum.EInputStyle.Date)
+            {
+                if (!CConvert.IsDate(CConvert.ToInt(inputText.Replace("/", string.Empty).Replace("-", string.Empty)).ToString().PadLeft(8, '0')))
+                {
+                    Fields[index].Error = true;
+                    Fields[index].ErrorText = "正しい日付を入力してください。";
+                    return false;
+                }
+            }
+
+            //範囲判断
+            if (Fields[index].Range.Length > 0)
+            {
+                if (CConvert.IsOutOfRange(inputText, Fields[index].Range))
+                {
+                    Fields[index].Error = true;
+                    Fields[index].ErrorText = "入力範囲以外です。";
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        #endregion
+
+        #region  ★★★★★ Public  Function ★★★★★
+
+        public void Add(ValidField field)
+        {
+            field.Index = Fields.Count;
+            Fields.Add(field);
+            dict.Add(field.Name, field);
+            if (field.GridFilter) { FilterFields.Add(field.Name); }
+            if (field.GridOrder > 0) { OrderFields.Add(field.GridOrder, field.Name); }
+        }
+
+        public void RemoveAt(int index)
+        {
+            string key = Fields[index].Name;
+            if (Fields[index].GridFilter) { FilterFields.Remove(key); }
+            if (Fields[index].GridOrder > 0) { OrderFields.Remove(Fields[index].GridOrder); }
+            dict.Remove(key);
+            Fields.RemoveAt(index);
+            for (int i = index; i < Fields.Count; i++) { Fields[i].Index -= 1; }
+        }
+
+        public void Remove(ValidField field)
+        {
+            RemoveAt(field.Index);
+        }
+
+        public void Remove(string key)
+        {
+            ValidField field = dict[key];
+            RemoveAt(field.Index);
+        }
+
+        public ValidField GetField(string key)
+        {
+            return dict[key];
+        }
+
+        public void SetField(string key, string value)
+        {
+            dict[key].Text = value;
+        }
+
+        public void SetField(string key, string value, string disp)
+        {
+            dict[key].Text = value;
+            dict[key].DispText = disp;
+        }
+
+        public void Clear()
+        {
+            ErrText = string.Empty;
+            EnterPush = false;
+            ArrowUpPush = false;
+
+            foreach (ValidField field in Fields)
+            {
+                field.Clear();
+            }
+        }
+
+        public async Task<bool> IsValidAll()
+        {
+            try
+            {
+                ErrText = string.Empty;
+                foreach (ValidField field in Fields)
+                {
+                    string text = field.Text;
+                    if (!IsCorrectText(field.Index, text, false))
+                    {
+                        ErrText = field.ErrorText;
+                        return false;
+                    }
+
+                    if (BusinessValid != null)
+                    {
+                        ValidEventArgs e = new ValidEventArgs() { Text = text, IsAll = true };
+                        if (!await BusinessValid(field, e))
+                        {
+                            ErrText = field.ErrorText;
+                            return false;
+                        }
+                    }
+                }
+
+                return true;
+            }
+            catch
+            {
+                return false;
+            }
+            finally
+            {
+                if (ErrText.Length > 0 && ErrRefresh != null) { ErrRefresh(); }
+            }
+        }
+
+        #endregion
+
+    }
+}

--
Gitblit v1.10.0