| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956 | using System;using System.Collections.Generic;using System.Threading.Tasks;using System.Threading;using System.Linq;using Xamarin.Forms;using XF.Material.Forms.UI.Dialogs;using InABox.Core;using InABox.Clients;using System.IO;using InABox.Mobile;using Syncfusion.XForms.SignaturePad;using comal.timesheets.Tasks;using Comal.Classes;using PRSClasses;namespace comal.timesheets.QAForms{    public class QAFormViewer : Grid, IDFRenderer    {        #region Fields        public Dictionary<DFLayoutField, View> pairs = new Dictionary<DFLayoutField, View>();        public Dictionary<String, String> results = new Dictionary<String, String>();        public Dictionary<String, String> propertyResults = new Dictionary<String, String>();        Dictionary<String, String> loadData = new Dictionary<String, String>();        public Dictionary<DFLayoutLookupField, Dictionary<Guid, string>> dfLayoutLookupFieldLookupOptions = new Dictionary<DFLayoutLookupField, Dictionary<Guid, string>>();        DFLayout dfLayout = null;        public IDigitalFormDataModel model = null;        const string nullOrInvalidType = "Null or Invalid Type";        int rbGroup;        private Guid userID;        bool isRequired = false;        bool readOnly = false;        bool isSecure = false;        bool loadRetainedForm = false;        List<string> useSavedSignatures = new List<string>();        public List<string> errors = new List<string>();        public bool isRequiredEmpty { get; set; }        public string isRequiredMessage { get; set; }        InABox.Core.Location location = new InABox.Core.Location();        Guid digitalFormID = Guid.Empty;        Color isRequiredColor = Color.DarkOrange;        public string FormData = "";        public DateTime FormCompleted = DateTime.MinValue;        public Guid JobID = Guid.Empty;        DateTime timeStarted = DateTime.MinValue;        List<DigitalFormsHeader> headersToCollapse = new List<DigitalFormsHeader>();        int collapsedHeaderCount = 1;        #endregion        #region Constructor        public QAFormViewer(IDigitalFormDataModel _model, DFLayout _dfLayout, bool newForm, bool _readOnly, Guid _jobid = default(Guid))        {            GetLocation();            timeStarted = DateTime.Now;            userID = ClientFactory.UserGuid;            model = _model;            dfLayout = _dfLayout;            dfLayout.Renderer = this;            readOnly = _readOnly;            isRequiredEmpty = false;            loadRetainedForm = false;            isRequiredMessage = "";            JobID = _jobid;            if (RetainedResults.IsFormRetained)            {                loadRetainedForm = true;            }            if (newForm)            {                LoadForm();            }            else if (!newForm)            {                loadData.Clear();                Dictionary<String, Object> data = Serialization.Deserialize<Dictionary<String, Object>>(model.Instance.FormData);                if (data != null)                {                    foreach (KeyValuePair<string, object> keyValuePair in data)                    {                        loadData.Add(keyValuePair.Key, keyValuePair.Value.ToString());                    }                }                LoadForm();            }        }        #endregion        #region Location        private async void GetLocation()        {            await Task.Run(() =>            {                LocationServices locationServices = new LocationServices();                locationServices.OnLocationFound += LocationFound;                locationServices.OnLocationError += LocationError;                locationServices.GetLocation();            });        }        private async void LocationFound(LocationServices sender)        {            location.Latitude = sender.Latitude;            location.Longitude = sender.Longitude;        }        private async void LocationError(LocationServices sender, Exception error)        {            errors.Add("Location error: " + error.Message);        }        #endregion Location        #region Load Form Layout        private async void LoadForm()        {            using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Loading Form"))            {                LoadRowsAndColumns();                LoadElements();            }        }        private async void LoadRowsAndColumns()        {            LoadRows();            LoadColumns();        }        private void LoadRows()        {            foreach (var row in dfLayout.RowHeights)            {                RowDefinition def = new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) };                if (int.TryParse(row, out int rowHeight))                {                    def = new RowDefinition { Height = new GridLength(rowHeight, GridUnitType.Absolute) };                    if (def.Height.Value < 60)                    {                        def.SetValue(RowDefinition.HeightProperty, 60);                    }                }                else if (row == "*")                {                    def = new RowDefinition { Height = new GridLength(1, GridUnitType.Star) };                }                Device.BeginInvokeOnMainThread(() => { RowDefinitions.Add(def); });            }        }        private void LoadColumns()        {            foreach (var col in dfLayout.ColumnWidths)            {                ColumnDefinition def = new ColumnDefinition { Width = new GridLength(1, GridUnitType.Auto) };                if (int.TryParse(col, out int colWidth))                    def = new ColumnDefinition { Width = new GridLength(colWidth, GridUnitType.Absolute) };                else if (col == "*")                {                    def = new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) };                }                Device.BeginInvokeOnMainThread(() => { ColumnDefinitions.Add(def); });            }        }        private async void LoadElements()        {            rbGroup = 0; //used for customboolean - has to be outside of foreach loop            foreach (DFLayoutControl element in dfLayout.Elements)            {                if (!string.IsNullOrEmpty(element.Description))                {                    LoadViewAccordingToElement(element);                }            }            Task.Run(() =>             {                Thread.Sleep(1000);                foreach (var header in headersToCollapse)                {                    Device.BeginInvokeOnMainThread(() =>                     {                        AdjustHeaderSection(header, false);                        header.Collapse();                    });                                   }            });                   }        #endregion        #region Load Element Methods        private void LoadViewAccordingToElement(DFLayoutControl element)        {            View view = null;            isSecure = false;            string value = "";            if (element is DFLayoutBooleanField)            {                var tuple = LoadCustomBoolean(view, element, value);                FormatAndAddView(tuple.Item1, element, tuple.Item2);            }            else if (element is DFLayoutLabel)            {                var tuple = LoadLabel(view, element);                FormatAndAddView(tuple.Item1, element, tuple.Item2);            }            else if (element is DFLayoutStringField || element is DFLayoutIntegerField || element is DFLayoutDoubleField)            {                var tuple = LoadEditor(view, element, value);                FormatAndAddView(tuple.Item1, element, tuple.Item2);            }            else if (element is DFLayoutDateField)            {                var tuple = LoadDatePicker(view, element, value);                FormatAndAddView(tuple.Item1, element, tuple.Item2);            }            else if (element is DFLayoutTimeField)            {                var tuple = LoadTimePicker(view, element, value);                FormatAndAddView(tuple.Item1, element, tuple.Item2);            }            else if (element is DFLayoutOptionField)            {                var tuple = LoadOptionPicker(view, element, value);                FormatAndAddView(tuple.Item1, element, tuple.Item2);            }            else if (element is DFLayoutImage)            {                var tuple = LoadImage(view, element);                FormatAndAddView(tuple.Item1, element, tuple.Item2);            }            else if (element is DFLayoutLookupField)            {                var tuple = LoadLookupPicker(view, element, value);                FormatAndAddView(tuple.Item1, element, tuple.Item2);            }            else if (element is DFLayoutSignaturePad)            {                var tuple = LoadSignaturePad(view, element, value);                FormatAndAddView(tuple.Item1, element, tuple.Item2);            }            else if (element is DFLayoutEmbeddedImage)            {                var tuple = LoadEmbeddedImage(view, element, value);                FormatAndAddView(tuple.Item1, element, tuple.Item2);            }            else if (element is DFLayoutMultiImage)            {                var tuple = LoadMultiImage(view, element, value);                FormatAndAddView(tuple.Item1, element, tuple.Item2);            }            else if (element is DFLayoutMultiSignaturePad)            {                var tuple = LoadMultiSignaturePad(view, element, value);                FormatAndAddView(tuple.Item1, element, tuple.Item2);            }            else if (element is DFLayoutAddTaskField)            {                var tuple = LoadAddTaskField(view, element, value);                FormatAndAddView(tuple.Item1, element, tuple.Item2);            }            else if (element is DFLayoutHeader)            {                FormatAndAddView(LoadHeader(view, element), element, false);            }        }        private View LoadHeader(View view, DFLayoutControl element)        {            DFLayoutHeader dFLayoutHeader = (DFLayoutHeader)element;            DigitalFormsHeader header = new DigitalFormsHeader(dFLayoutHeader.Collapsed);            if (dFLayoutHeader.Collapsed)                header = AddNumberToHeader(header);                           header.SetHeaderValue(dFLayoutHeader.Header);            header.OnTapped += (bCollapsed) =>            {                AdjustHeaderSection(header, bCollapsed);            };            view = header;            return view;        }        private DigitalFormsHeader AddNumberToHeader(DigitalFormsHeader header)        {            header.Number = collapsedHeaderCount;            collapsedHeaderCount++;            return header;        }        private void AdjustHeaderSection(DigitalFormsHeader header, bool collapsed)        {            var thisHeaderRow = GetRow(header);            var headerRows = GetOtherHeaders(thisHeaderRow);            if (headerRows.Any())                AdjustHeightsToNextHeader(headerRows, thisHeaderRow, collapsed);            else                AdjustHeightsBelowHeader(headerRows, thisHeaderRow, collapsed);        }        private List<int> GetOtherHeaders(int thisHeaderRow)        {            List<int> headerRows = new List<int>();            foreach (var child in Children)            {                if (child is DigitalFormsHeader)                {                    var dfheader = (DigitalFormsHeader)child;                    if (GetRow(dfheader) > thisHeaderRow)                    {                        headerRows.Add(GetRow(dfheader));                    }                }            }            return headerRows;        }        private void AdjustHeightsToNextHeader(List<int> headerRows, int thisHeaderRow, bool collapsed)        {            headerRows.Sort();            int nextHeaderRow = headerRows[0];            for (int i = thisHeaderRow + 1; i < nextHeaderRow; i++)            {                AdjustHeight(i, collapsed);            }        }        private void AdjustHeightsBelowHeader(List<int> headerRows, int thisHeaderRow, bool collapsed)        {            for (int i = thisHeaderRow + 1; i < RowDefinitions.Count; i++)            {                AdjustHeight(i, collapsed);            }        }        private async void AdjustHeight(int i, bool collapsed)        {            var rowdef = RowDefinitions[i];            if (collapsed)            {                rowdef.Height = 60;                AnimateChildren(i, 0, 250);            }            else            {                AnimateChildren(i, -60, 500);                rowdef.Height = 0;            }        }        private async void AnimateChildren(int i, int movement, int length)        {            foreach (var child in Children)            {                if (GetRow(child) == i)                {                    await child.TranslateTo(0, movement, 250);                }            }        }        private Tuple<View, Boolean> LoadCustomBoolean(View view, DFLayoutControl element, String value)        {            rbGroup++;            CustomBoolean item = new CustomBoolean(rbGroup);            DFLayoutBooleanField dfLayoutBooleanField = element as DFLayoutBooleanField;            if (!string.IsNullOrWhiteSpace(dfLayoutBooleanField.Properties.TrueValue))                item.trueBtn.Content = dfLayoutBooleanField.Properties.TrueValue;            if (!string.IsNullOrWhiteSpace(dfLayoutBooleanField.Properties.FalseValue))                item.falseBtn.Content = dfLayoutBooleanField.Properties.FalseValue;            if (loadData.TryGetValue(dfLayoutBooleanField.Name, out value))            {                item.Value = bool.Parse(value);            }            if (loadRetainedForm)            {                if (RetainedResults.Results.TryGetValue(dfLayoutBooleanField.Name, out value))                {                    item.Value = bool.Parse(value);                }            }            if (dfLayoutBooleanField.Properties.Required)            {                item.trueBtn.BackgroundColor = isRequiredColor;                item.falseBtn.BackgroundColor = isRequiredColor;            }            item.OnCustomBooleanValueChanged += (boolvalue) =>            {                dfLayout.ChangeField(dfLayoutBooleanField.Name);            };            view = item;            return new Tuple<View, Boolean>(view, dfLayoutBooleanField.Properties.Required);        }        private Tuple<View, Boolean> LoadLabel(View view, DFLayoutControl element)        {            DFLayoutLabel label = element as DFLayoutLabel;            Label item = new Label();            item.Text = label.Caption;            item.FontSize = Device.GetNamedSize(NamedSize.Medium, item);            item.TextColor = Color.Black;            item.LineBreakMode = LineBreakMode.WordWrap;            item.VerticalOptions = LayoutOptions.FillAndExpand;            item.VerticalTextAlignment = TextAlignment.Center;            item.MinimumHeightRequest = 60;            if (ColumnDefinitions.Count == 1)            {                item.HorizontalOptions = LayoutOptions.CenterAndExpand;                item.HorizontalTextAlignment = TextAlignment.Center;            }            view = item;            return new Tuple<View, Boolean>(view, false);        }        private Tuple<View, Boolean> LoadEditor(View view, DFLayoutControl element, string value)        {            Editor item = new Editor();            var isrequired = false;            var issecure = false;            if (element is DFLayoutStringField)            {                DFLayoutStringField dfLayoutStringField = element as DFLayoutStringField;                item.TextColor = Color.Black;                item.Placeholder = "Enter answer";                isrequired = dfLayoutStringField.Properties.Required;                issecure = dfLayoutStringField.Properties.Secure;                if (loadData.TryGetValue(dfLayoutStringField.Name, out value))                {                    item.Text = value;                }                if (loadRetainedForm)                {                    if (RetainedResults.Results.TryGetValue(dfLayoutStringField.Name, out value))                    {                        item.Text = value;                    }                }                item.TextChanged += (object sender, TextChangedEventArgs e) =>                {                    dfLayout.ChangeField(dfLayoutStringField.Name);                };                view = item;            }            else if (element is DFLayoutIntegerField)            {                DFLayoutIntegerField dfLayoutIntegerField = element as DFLayoutIntegerField;                item.TextColor = Color.Black;                item.Placeholder = "Enter number";                item.Keyboard = Keyboard.Numeric;                isrequired = dfLayoutIntegerField.Properties.Required;                issecure = dfLayoutIntegerField.Properties.Secure;                if (loadData.TryGetValue(dfLayoutIntegerField.Name, out value))                {                    item.Text = value;                }                if (loadRetainedForm)                {                    if (RetainedResults.Results.TryGetValue(dfLayoutIntegerField.Name, out value))                    {                        item.Text = value;                    }                }                item.TextChanged += (object sender, TextChangedEventArgs e) =>                {                    dfLayout.ChangeField(dfLayoutIntegerField.Name);                };                view = item;            }            else if (element is DFLayoutDoubleField)            {                DFLayoutDoubleField dfLayoutDoubleField = element as DFLayoutDoubleField;                item.TextColor = Color.Black;                item.Placeholder = "Enter number";                item.Keyboard = Keyboard.Numeric;                isrequired = dfLayoutDoubleField.Properties.Required;                issecure = dfLayoutDoubleField.Properties.Secure;                if (loadData.TryGetValue(dfLayoutDoubleField.Name, out value))                {                    item.Text = value;                }                if (loadRetainedForm)                {                    if (RetainedResults.Results.TryGetValue(dfLayoutDoubleField.Name, out value))                    {                        item.Text = value;                    }                }                item.TextChanged += (object sender, TextChangedEventArgs e) =>                {                    dfLayout.ChangeField(dfLayoutDoubleField.Name);                };                view = item;            }            if (isrequired) view.BackgroundColor = isRequiredColor;            if (readOnly || issecure)            {                Label label = new Label();                label.Text = item.Text;                label.FontSize = Device.GetNamedSize(NamedSize.Medium, item);                label.TextColor = Color.DarkGray;                label.LineBreakMode = LineBreakMode.WordWrap;                label.MaxLines = 5;                label.VerticalTextAlignment = TextAlignment.Center;                label.HorizontalTextAlignment = TextAlignment.Center;                label.MinimumHeightRequest = 60;                label.VerticalOptions = LayoutOptions.FillAndExpand;                label.Margin = 9;                view = label;            }            return new Tuple<View, Boolean>(view, isrequired);        }        private Tuple<View, Boolean> LoadDatePicker(View view, DFLayoutControl element, string value)        {            DFLayoutDateField dfLayoutDateField = element as DFLayoutDateField;            DatePicker item = new DatePicker();            item.Format = "dd MMM yyyy";            if (dfLayoutDateField.Properties.Required)                item.BackgroundColor = isRequiredColor;            item.HorizontalOptions = LayoutOptions.CenterAndExpand;            if (loadData.TryGetValue(dfLayoutDateField.Name, out value))            {                item.Date = DateTime.Parse(value);            }            if (loadRetainedForm)            {                if (RetainedResults.Results.TryGetValue(dfLayoutDateField.Name, out value))                {                    item.Date = DateTime.Parse(value);                }            }            item.DateSelected += (object sender, DateChangedEventArgs e) =>            {                dfLayout.ChangeField(dfLayoutDateField.Name);            };            view = item;            return new Tuple<View, Boolean>(view, dfLayoutDateField.Properties.Required);        }        private Tuple<View, Boolean> LoadTimePicker(View view, DFLayoutControl element, string value)        {            DFLayoutTimeField dfLayoutTimeField = element as DFLayoutTimeField;            TimePicker item = new TimePicker();            if (dfLayoutTimeField.Properties.Required)                item.BackgroundColor = isRequiredColor;            item.HorizontalOptions = LayoutOptions.Center;            if (loadData.TryGetValue(dfLayoutTimeField.Name, out value))            {                item.Time = DateTime.Parse(value).TimeOfDay;            }            if (loadRetainedForm)            {                if (RetainedResults.Results.TryGetValue(dfLayoutTimeField.Name, out value))                {                    item.Time = DateTime.Parse(value).TimeOfDay;                }            }            item.PropertyChanged += (object sender, System.ComponentModel.PropertyChangedEventArgs e) =>            {                if (e.PropertyName == "Time")                    dfLayout.ChangeField(dfLayoutTimeField.Name);            };            view = item;            return new Tuple<View, Boolean>(view, dfLayoutTimeField.Properties.Required);        }        private Tuple<View, Boolean> LoadOptionPicker(View view, DFLayoutControl element, string value)        {            var isrequired = false;            DFLayoutOptionField dfLayoutOptionField = element as DFLayoutOptionField;            isrequired = dfLayoutOptionField.Properties.Required;            if (GlobalVariables.DeviceString == "i" || GlobalVariables.DeviceString == "I")            {                CustomPickeriOS item = new CustomPickeriOS();                string s = dfLayoutOptionField.Properties.Options;                string[] substrings = s.Split(',');                var optionList = substrings.ToList();                item.AddItems(optionList);                if (!string.IsNullOrEmpty(dfLayoutOptionField.Properties.Default))                {                    int index = optionList.IndexOf(dfLayoutOptionField.Properties.Default);                    item.SelectedIndex = index;                    item.SelectedItem = optionList[index];                    item.SetDefault(optionList[index]);                }                if (loadData.TryGetValue(dfLayoutOptionField.Name, out value))                {                    int index = optionList.IndexOf(value);                    item.SelectedIndex = index;                    item.SelectedItem = optionList[index];                    item.SetDefault(optionList[index]);                }                if (loadRetainedForm)                {                    if (RetainedResults.Results.TryGetValue(dfLayoutOptionField.Name, out value))                    {                        int index = optionList.IndexOf(value);                        item.SelectedIndex = index;                        item.SelectedItem = optionList[index];                        item.SetDefault(optionList[index]);                    }                }                if (isrequired)                {                    item.BackgroundColor = isRequiredColor;                    item.SetBackGroundColor(isRequiredColor);                }                item.CustomPickeriOSValueChanged += () =>                {                    dfLayout.ChangeField(dfLayoutOptionField.Name);                };                view = item;            }            else            {                Picker picker = new Picker();                picker.Title = "Select an option";                picker.VerticalTextAlignment = TextAlignment.Center;                picker.HorizontalTextAlignment = TextAlignment.Center;                string s = dfLayoutOptionField.Properties.Options;                string[] substrings = s.Split(',');                var optionList = substrings.ToList();                picker.ItemsSource = optionList;                if (!string.IsNullOrEmpty(dfLayoutOptionField.Properties.Default))                {                    int index = optionList.IndexOf(dfLayoutOptionField.Properties.Default);                    picker.SelectedIndex = index;                    picker.SelectedItem = optionList[index];                }                if (loadData.TryGetValue(dfLayoutOptionField.Name, out value))                {                    int index = optionList.IndexOf(value);                    picker.SelectedIndex = index;                    picker.SelectedItem = optionList[index];                }                if (loadRetainedForm)                {                    if (RetainedResults.Results.TryGetValue(dfLayoutOptionField.Name, out value))                    {                        int index = optionList.IndexOf(value);                        picker.SelectedIndex = index;                        picker.SelectedItem = optionList[index];                    }                }                if (isrequired)                {                    picker.BackgroundColor = isRequiredColor;                }                picker.SelectedIndexChanged += (object sender, EventArgs e) =>                {                    dfLayout.ChangeField(dfLayoutOptionField.Name);                };                view = picker;            }            return new Tuple<View, Boolean>(view, isrequired);        }        private Tuple<View, Boolean> LoadImage(View view, DFLayoutControl element)        {            DFLayoutImage dfLayoutImage = element as DFLayoutImage;            Image img = new Image();            CoreTable table = new Client<Document>().Query(                    new Filter<Document>(x => x.ID).IsEqualTo(dfLayoutImage.Image.ID),                    null,                    null);            if (table.Rows.Any())            {                CoreRow row = table.Rows.FirstOrDefault();                byte[] data = row.Get<Document, byte[]>(x => x.Data);                ImageSource src = ImageSource.FromStream(() => new MemoryStream(data));                img.MinimumHeightRequest = 150;                img.MinimumWidthRequest = 150;                img.Aspect = Aspect.AspectFit;                img.Source = src;                img.HorizontalOptions = LayoutOptions.FillAndExpand;                img.VerticalOptions = LayoutOptions.FillAndExpand;                img.GestureRecognizers.Add(new TapGestureRecognizer                {                    Command = new Command(OnTap),                    CommandParameter = src,                    NumberOfTapsRequired = 1                });                if (img != null)                {                    view = img;                }            }            return new Tuple<View, Boolean>(view, false);        }        private void OnTap(object obj)        {            ImageViewer viewer = new ImageViewer(obj as ImageSource);            Navigation.PushAsync(viewer);        }        private Tuple<View, Boolean> LoadLookupPicker(View view, DFLayoutControl element, string value)        {            DFLayoutLookupField dfLayoutLookupField = element as DFLayoutLookupField;            var isrequired = dfLayoutLookupField.Properties.Required;            Dictionary<Guid, string> lookupFieldOptions = new Dictionary<Guid, string>();            string type = dfLayoutLookupField.Properties.LookupType;            Type lookuptype = CoreUtils.GetEntity(type);            if (lookuptype == typeof(DrawingTemplate))            {                view = LoadDrawingTemplateLookupButton(lookuptype, dfLayoutLookupField, lookupFieldOptions, element);            }            else if (!string.IsNullOrWhiteSpace(dfLayoutLookupField.Properties.Filter))            {                view = LoadGenericLookupButton(lookuptype, dfLayoutLookupField, lookupFieldOptions, element);            }            else if (lookuptype == typeof(Product))            {                view = LoadProductLookupPicker(view, dfLayoutLookupField, value);            }            else if (lookuptype != null)            {                view = LoadGenericLookupButton(lookuptype, dfLayoutLookupField, lookupFieldOptions, element);            }            return new Tuple<View, Boolean>(view, isrequired);        }        private View LoadGenericLookupButton(Type lookuptype, DFLayoutLookupField dfLayoutLookupField, Dictionary<Guid, string> lookupFieldOptions, DFLayoutControl element)        {            string value = "";            CoreTable table = new CoreTable();            var client = ClientFactory.CreateClient(lookuptype);            var columns = LookupFactory.DefineColumns(lookuptype);            var sort = LookupFactory.DefineSort(lookuptype);            var filter = LookupFactory.DefineFilter(lookuptype);            if (!string.IsNullOrWhiteSpace(dfLayoutLookupField.Properties.Filter))                filter = ReturnFilter(dfLayoutLookupField, lookuptype);            if (lookuptype == typeof(ProductStyle) && JobID != Guid.Empty)                table = ReturnJobStyleProducts(table, client, columns, sort);            if (table.Rows.Count == 0)                table = client.Query(filter, columns, sort); // do generic query if a specific one hasn't already been done            foreach (var row in table.Rows)            {                Guid id = row.Get<Guid>("ID");                Dictionary<string, object> values = row.ToDictionary(new string[] { "ID" });                string display = LookupFactory.FormatLookup(lookuptype, values, new string[] { });                lookupFieldOptions[id] = display;            }            dfLayoutLookupFieldLookupOptions[element as DFLayoutLookupField] = lookupFieldOptions;            List<string> itemList = lookupFieldOptions.Values.ToList();            DataButtonControl button = new DataButtonControl()            {                Text = "Choose Option",                HorizontalOptions = LayoutOptions.FillAndExpand,                VerticalOptions = LayoutOptions.Center,                Margin = 0,                BackgroundColor = Color.FromHex("#15C7C1"),                FontAttributes = FontAttributes.Bold,                TextColor = Color.White,                CornerRadius = 5,                Padding = 1,            };            button.Clicked += (object sender, EventArgs eventArgs) =>            {                ListSelectionPage selectionPage = new ListSelectionPage(itemList);                selectionPage.OnItemTapped += (s) =>                {                    button.Data = s;                    button.Text = s;                    dfLayout.ChangeField(dfLayoutLookupField.Name);                };                Navigation.PushAsync(selectionPage);            };            if (loadData.TryGetValue(dfLayoutLookupField.Name, out value))            {                button.Data = value;                button.Text = value;            }            if (loadRetainedForm)            {                if (RetainedResults.Results.TryGetValue(dfLayoutLookupField.Name, out value))                {                    button.Data = value;                    button.Text = value;                }            }            if (isRequired)            {                button.BackgroundColor = isRequiredColor;            }            return button;        }        private View LoadDrawingTemplateLookupButton(Type lookuptype, DFLayoutLookupField dfLayoutLookupField, Dictionary<Guid, string> lookupFieldOptions, DFLayoutControl element)        {            string value = "";            var columns = new Columns<DrawingTemplate>(x => x.Code, x => x.Document.ID);            CoreTable table = new Client<DrawingTemplate>().Query(null, columns);            Dictionary<string, Guid> dictionary = new Dictionary<string, Guid>();            foreach (var row in table.Rows)            {                List<object> list = row.Values;                if (list[0] != null && list[1] != null)                    dictionary.Add(list[0].ToString(), Guid.Parse(list[1].ToString()));            }            DataButtonControl button = new DataButtonControl()            {                Text = "Choose Option",                HorizontalOptions = LayoutOptions.FillAndExpand,                VerticalOptions = LayoutOptions.Center,                Margin = 0,                BackgroundColor = Color.FromHex("#15C7C1"),                FontAttributes = FontAttributes.Bold,                TextColor = Color.White,                CornerRadius = 5,                Padding = 1,            };            button.Clicked += (object sender, EventArgs eventArgs) =>            {                ListSelectionPage selectionPage = new ListSelectionPage(dictionary);                selectionPage.OnItemTapped += (s) =>                {                    button.Data = s;                    button.Text = s;                    dfLayout.ChangeField(dfLayoutLookupField.Name);                };                Navigation.PushAsync(selectionPage);            };            if (loadData.TryGetValue(dfLayoutLookupField.Name, out value))            {                button.Data = value;                button.Text = value;            }            if (loadRetainedForm)            {                if (RetainedResults.Results.TryGetValue(dfLayoutLookupField.Name, out value))                {                    button.Data = value;                    button.Text = value;                }            }            if (isRequired)            {                button.BackgroundColor = isRequiredColor;            }            return button;        }        private IFilter ReturnFilter(DFLayoutLookupField dfLayoutLookupField, Type lookuptype)        {            var propertyFilter = dfLayoutLookupField.Properties.Filter;            var filtertype = typeof(Filter<>).MakeGenericType(lookuptype);            var deserialised = Serialization.Deserialize(filtertype, propertyFilter);            IFilter filter = deserialised as IFilter;            return filter;        }        private CoreTable ReturnJobStyleProducts(CoreTable table, IClient client, IColumns columns, ISortOrder sort)        {            CoreTable jobStyleTable = new Client<JobStyle>().Query(new Filter<JobStyle>(x => x.Job.ID).IsEqualTo(JobID),                    new Columns<JobStyle>(x => x.Style.ID));            if (jobStyleTable.Rows.Any())            {                Guid firstID = Guid.Parse(jobStyleTable.Rows.FirstOrDefault().Values[0].ToString());                var stylefilter = new Filter<ProductStyle>(x => x.ID).IsEqualTo(firstID);                foreach (CoreRow jobStyleRow in jobStyleTable.Rows)                {                    if (jobStyleRow != jobStyleTable.Rows.FirstOrDefault())                    {                        stylefilter = stylefilter.Or(x => x.ID).IsEqualTo(Guid.Parse(jobStyleRow.Values[0].ToString()));                    }                }                table = client.Query(stylefilter, columns, sort);            }            return table;        }        private View LoadProductLookupPicker(View view, DFLayoutLookupField dfLayoutLookupField, string value)        {            FrameButton framebutton = new FrameButton();            if (loadData.TryGetValue(dfLayoutLookupField.Name, out value))            {                framebutton.SetButtonText(value);                framebutton.Data = value + "," + (GlobalVariables.ProductShells.FirstOrDefault(x => x.Code == value)).ID.ToString();                CoreTable productTable = new Client<Product>().Query(new Filter<Product>(x => x.Code).IsEqualTo(value),                    new Columns<Product>(x => x.Image.ID));                if (productTable.Rows.Any())                {                    CoreTable imageTable1 = new Client<Document>().Query(new Filter<Document>(x => x.ID).IsEqualTo(Guid.Parse(productTable.Rows.First().Values[0].ToString())),                            new Columns<Document>(x => x.Data));                    CoreRow docrow = imageTable1.Rows.FirstOrDefault();                    if (docrow != null)                    {                        byte[] data = docrow.Get<Document, byte[]>(x => x.Data);                        ImageSource src = ImageSource.FromStream(() => new MemoryStream(data));                        if (src != null)                        {                            framebutton.SetImage(src);                        }                    }                }            }            framebutton.OnFrameButtonClicked += (() =>            {                ProductList productList = new ProductList(GlobalVariables.ProductShells, true);                productList.OnProductSelected += () =>                {                    framebutton.SetButtonText(productList.SelectedProduct.Code);                    framebutton.Data = productList.SelectedProduct.Code + "," + productList.SelectedProduct.ID.ToString();                    CoreTable imageTable = new Client<Document>().Query(new Filter<Document>(x => x.ID).IsEqualTo(productList.SelectedProduct.ImageID),                        new Columns<Document>(x => x.Data));                    CoreRow docrow = imageTable.Rows.FirstOrDefault();                    if (docrow != null)                    {                        byte[] data = docrow.Get<Document, byte[]>(x => x.Data);                        ImageSource src = ImageSource.FromStream(() => new MemoryStream(data));                        if (src != null)                        {                            framebutton.SetImage(src);                        }                    }                    dfLayout.ChangeField(dfLayoutLookupField.Name);                };                Navigation.PushAsync(productList);            });            view = framebutton;            return view;        }        private Tuple<View, Boolean> LoadSignaturePad(View view, DFLayoutControl element, string value)        {            DFLayoutSignaturePad dFLayoutSignaturePad = element as DFLayoutSignaturePad;            var isrequired = dFLayoutSignaturePad.Properties.Required;            if (loadData.TryGetValue(dFLayoutSignaturePad.Name, out value))            {                EmbeddedImageCapture embeddedImageCapture = new EmbeddedImageCapture();                byte[] data = Convert.FromBase64String(value);                embeddedImageCapture.DataToImage(data);                view = embeddedImageCapture;                view.IsEnabled = false;            }            else            {                SfSignaturePad signaturePad = new SfSignaturePad();                EmbeddedImageCapture hiddenEmbeddedImageCapture = new EmbeddedImageCapture() { HeightRequest = 200, IsVisible = false, IsEnabled = false };                if (isrequired) signaturePad.BackgroundColor = isRequiredColor;                signaturePad.MinimumHeightRequest = 200;                signaturePad.MinimumStrokeWidth = 0.2;                signaturePad.MaximumStrokeWidth = 17;                Button clearButton = new Button()                {                    Text = "Clear",                    HorizontalOptions = LayoutOptions.FillAndExpand,                    VerticalOptions = LayoutOptions.End,                    Margin = 0,                    BackgroundColor = Color.FromHex("#15C7C1"),                    FontAttributes = FontAttributes.Bold,                    TextColor = Color.White,                    CornerRadius = 5,                    Padding = 1                };                clearButton.Clicked += (object sender, EventArgs e) =>                {                    signaturePad.IsVisible = true;                    hiddenEmbeddedImageCapture.IsVisible = false;                    useSavedSignatures.Remove(dFLayoutSignaturePad.Name);                    signaturePad.Clear();                };                Grid.SetColumn(clearButton, 2);                Button signNowButton = new Button()                {                    Text = "Apply Saved",                    HorizontalOptions = LayoutOptions.FillAndExpand,                    VerticalOptions = LayoutOptions.End,                    Margin = 0,                    BackgroundColor = Color.FromHex("#15C7C1"),                    FontAttributes = FontAttributes.Bold,                    TextColor = Color.White,                    CornerRadius = 5,                    Padding = 1                };                signNowButton.Clicked += (object sender, EventArgs e) =>                {                    if (Application.Current.Properties.ContainsKey("SavedSignature"))                    {                        Task.Run(() =>                        {                            hiddenEmbeddedImageCapture.DataToImage((Application.Current.Properties["SavedSignature"]) as byte[]);                        });                        Thread.Sleep(1000);                        signaturePad.IsVisible = false;                        hiddenEmbeddedImageCapture.IsVisible = true;                        if (!useSavedSignatures.Contains(dFLayoutSignaturePad.Name))                            useSavedSignatures.Add(dFLayoutSignaturePad.Name);                    }                };                Grid.SetColumn(signNowButton, 1);                Button createSignatureButton = new Button()                {                    Text = "Save New",                    HorizontalOptions = LayoutOptions.FillAndExpand,                    VerticalOptions = LayoutOptions.End,                    Margin = 0,                    BackgroundColor = Color.FromHex("#15C7C1"),                    FontAttributes = FontAttributes.Bold,                    TextColor = Color.White,                    CornerRadius = 5,                    Padding = 1                };                createSignatureButton.Clicked += (object sender, EventArgs e) =>                {                    SignatureSaver saver = new SignatureSaver();                    saver.OnSignatureSaved += () =>                    {                        Task.Run(() =>                        {                            hiddenEmbeddedImageCapture.DataToImage((Application.Current.Properties["SavedSignature"]) as byte[]);                        });                        Thread.Sleep(1000);                        signaturePad.IsVisible = false;                        hiddenEmbeddedImageCapture.IsVisible = true;                        if (!useSavedSignatures.Contains(dFLayoutSignaturePad.Name))                            useSavedSignatures.Add(dFLayoutSignaturePad.Name);                    };                    Navigation.PushAsync(saver);                };                Grid.SetColumn(createSignatureButton, 0);                Grid buttonsGrid = new Grid { Margin = 0, Padding = 0, VerticalOptions = LayoutOptions.End };                buttonsGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });                buttonsGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });                buttonsGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });                buttonsGrid.Children.Add(createSignatureButton);                buttonsGrid.Children.Add(signNowButton);                buttonsGrid.Children.Add(clearButton);                Grid grid = new Grid() { Margin = 0, Padding = 0 };                grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(200, GridUnitType.Absolute) });                Grid.SetRow(signaturePad, 0);                Grid.SetRow(hiddenEmbeddedImageCapture, 0);                grid.Children.Add(hiddenEmbeddedImageCapture);                grid.Children.Add(signaturePad);                grid.Children.Add(buttonsGrid);                view = grid;            }            return new Tuple<View, Boolean>(view, isrequired);        }        private Tuple<View, Boolean> LoadEmbeddedImage(View view, DFLayoutControl element, string value)        {            bool disableLibrary = false;            DFLayoutEmbeddedImage dfLayoutEmbeddedImage = element as DFLayoutEmbeddedImage;            try            {                disableLibrary = dfLayoutEmbeddedImage.Properties.DisableLibrary;            }            catch { }            EmbeddedImageCapture embeddedImageCapture = new EmbeddedImageCapture(disableLibrary);            if (disableLibrary)                embeddedImageCapture.LibraryButton.BackgroundColor = Color.LightGray;            if (loadData.TryGetValue(dfLayoutEmbeddedImage.Name, out value))            {                byte[] data = Convert.FromBase64String(value);                embeddedImageCapture.DataToImage(data);            }            else            {                if (dfLayoutEmbeddedImage.Properties.Required)                {                    embeddedImageCapture.CameraButton.BackgroundColor = isRequiredColor;                    embeddedImageCapture.CameraButton.BorderWidth = 1;                    embeddedImageCapture.CameraButton.BorderColor = Color.Black;                    if (!disableLibrary)                    {                        embeddedImageCapture.LibraryButton.BackgroundColor = isRequiredColor;                        embeddedImageCapture.LibraryButton.BorderWidth = 1;                        embeddedImageCapture.LibraryButton.BorderColor = Color.Black;                    }                }            }            view = embeddedImageCapture;            return new Tuple<View, Boolean>(view, dfLayoutEmbeddedImage.Properties.Required);        }        private Tuple<View, Boolean> LoadMultiImage(View view, DFLayoutControl element, string value)        {            bool disableLibrary = false;            DFLayoutMultiImage dfLayoutMultiEmbeddedImage = element as DFLayoutMultiImage;            try            {                disableLibrary = dfLayoutMultiEmbeddedImage.Properties.DisableLibrary;            }            catch { }            MultiImageCapture multiImageCapture = new MultiImageCapture(disableLibrary);            if (loadData.TryGetValue(dfLayoutMultiEmbeddedImage.Name, out value))            {                List<string> values = Serialization.Deserialize<List<string>>(value);                foreach (string s in values)                {                    byte[] data = Convert.FromBase64String(s);                    multiImageCapture.DataToImage(data);                }            }            view = multiImageCapture;            return new Tuple<View, bool>(view, dfLayoutMultiEmbeddedImage.Properties.Required);        }        private Tuple<View, bool> LoadMultiSignaturePad(View view, DFLayoutControl element, string value)        {            DFLayoutMultiSignaturePad dfLayoutMultiSignaturePad = element as DFLayoutMultiSignaturePad;            DataButtonControl button = new DataButtonControl            {                Text = "Add Signatures",                TextColor = Color.White,                HorizontalOptions = LayoutOptions.FillAndExpand,                CornerRadius = 0,                BackgroundColor = Color.FromHex("#15C7C1"),                FontAttributes = FontAttributes.Bold            };            if (loadData.TryGetValue(dfLayoutMultiSignaturePad.Name, out value))            {                button.Data = value;            }            MultiSignaturePad multiSignaturePad = new MultiSignaturePad(button.Data);            multiSignaturePad.OnMultiSignatureSaved += (result) =>            {                button.Data = result;            };            button.Clicked += (object sender, EventArgs e) =>            {                Navigation.PushAsync(multiSignaturePad);            };            view = button;            return new Tuple<View, bool>(view, dfLayoutMultiSignaturePad.Properties.Required);        }        private Tuple<View, bool> LoadAddTaskField(View view, DFLayoutControl element, string value)        {            DFLayoutAddTaskField field = element as DFLayoutAddTaskField;            DFCreateTaskView taskView = new DFCreateTaskView();            taskView.OnAddTaskButtonClicked += () =>            {                AddEditTask addEditTask = new AddEditTask(Guid.Empty, "New task from Digital Form");                if (field.Properties.TaskType != null)                {                    addEditTask.kanban.Type.ID = field.Properties.TaskType.ID;                    try                    {                        addEditTask.kanban.Type.Description = new Client<KanbanType>().Query                        (new Filter<KanbanType>(x => x.ID).IsEqualTo(field.Properties.TaskType.ID),                        new Columns<KanbanType>(x => x.Description)).Rows.FirstOrDefault().Values[0].ToString();                    }                    catch { }                    addEditTask.UpdateScreen(true);                }                addEditTask.OnTaskSaved += (taskNumber) =>                {                    taskView.DisableButton();                    taskView.TaskNumber = taskNumber.ToString();                };                Navigation.PushAsync(addEditTask);            };            if (loadData.TryGetValue(field.Name, out value))            {                taskView.TaskNumber = value;                taskView.DisableButton();            }            return new Tuple<View, bool>(taskView, field.Properties.Required);        }        private void FormatAndAddView(View view, DFLayoutControl element, bool isrequired)        {            if (element is DFLayoutField)            {                pairs[element as DFLayoutField] = view;                if (isSecure || readOnly)                    view.IsEnabled = false;                Frame frame = new Frame                {                    Content = view,                    BorderColor = Color.FromHex("#15C7C1"),                    BackgroundColor = Color.Default,                    CornerRadius = 5,                    Padding = 2,                    HasShadow = false,                };                if (readOnly || isSecure)                {                    frame.BorderColor = Color.Gray;                    frame.BackgroundColor = Color.LightGray;                    frame.VerticalOptions = LayoutOptions.FillAndExpand;                    frame.MinimumHeightRequest = 60;                }                if (isrequired)                {                    frame.BackgroundColor = isRequiredColor;                }                view = frame;            }            if (element.Row > 0) SetRow(view, element.Row - 1); //rows and columns coming in from the desktop designer start from 1, not 0 (most of the time??)            else if (element.Row == 0) SetRow(view, dfLayout.RowHeights.Count + 1);            if (element.RowSpan > 0) SetRowSpan(view, element.RowSpan);            else if (element.RowSpan == 0) SetRowSpan(view, 1);            if (element.Column > 0) SetColumn(view, element.Column - 1); //rows and columns coming in from the desktop designer start from 1, not 0 (most of the time??)            if (element.ColumnSpan > 0) SetColumnSpan(view, element.ColumnSpan);            if (element.ColumnSpan > 1)            {                view.HorizontalOptions = LayoutOptions.FillAndExpand;                if (view is Label)                {                    view.HorizontalOptions = LayoutOptions.CenterAndExpand;                    Label lblView = view as Label;                    lblView.HorizontalTextAlignment = TextAlignment.Center;                    view = lblView;                }            }            else if (element.ColumnSpan == 0) SetColumnSpan(view, 1);            view.SetValue(Grid.MarginProperty, 0.01);            if (element is DFLayoutSignaturePad)            {                view.Margin = new Thickness(25, 0, 25, 0);            }            Device.BeginInvokeOnMainThread(() => { Children.Add(view); });            if (element is DFLayoutHeader)                if ((element as DFLayoutHeader).Collapsed)                    headersToCollapse.Add(view as DigitalFormsHeader);        }        #endregion        #region Save         public void SaveData(bool saveForLater)        {            try            {                results.Clear();                propertyResults.Clear();                isRequiredEmpty = false;                isRequiredMessage = "";                foreach (DFLayoutField field in pairs.Keys)                {                    View view = pairs[field];                    String userInput = AddResultsToDictionary(field, view);                    if (isRequiredEmpty)                    {                        if (!saveForLater)                            return;                    }                    AddPropertyToDictionary(field, userInput);                }                UpdateInstanceAndModel(saveForLater);            }            catch (Exception ex)            {                errors.Add(ex.Message);            }        }        #region Adding Results to dictionaries        private string AddResultsToDictionary(DFLayoutField field, View view, bool AddToDictionary = true) //"results" dictionary is the data to be saved in Form.Data        {            string userInput = "";            if (field is DFLayoutStringField || field is DFLayoutIntegerField || field is DFLayoutDoubleField)            {                userInput = (view as Editor).Text;            }            else if (field is DFLayoutBooleanField)            {                if ((view as CustomBoolean).ValueChanged)                {                    userInput = (view as CustomBoolean).Value.ToString();                }            }            else if (field is DFLayoutDateField)            {                userInput = ((view as DatePicker).Date).ToString("dd-MM-yyyy");            }            else if (field is DFLayoutTimeField)            {                userInput = ((view as TimePicker).Time).ToString("c");            }            else if (field is DFLayoutOptionField)            {                userInput = GetStringFromOptionField(view);            }            else if (field is DFLayoutLookupField)            {                if (view is DataButtonControl)                {                    var button = view as DataButtonControl;                    userInput = FindIDForDesignLookupField(button); //userinput is used to set guid later on for properties, but will not get added to form data only for lookupfields                                 results.Add(field.Name, button.Data);                    if (RetainedResults.IsFormRetained)                        if ((field as DFLayoutLookupField).Properties.Retain)                            RetainedResults.Results.Add(field.Name, button.Data);                }                else if (view is FrameButton) //currently only used for Products - we already have the Product.ID in Framebutton.Data (saved as Code,ID)                {                    FrameButton framebutton = view as FrameButton;                    if (!string.IsNullOrWhiteSpace(framebutton.Data))                    {                        string[] buttonData = framebutton.Data.Split(',');                        if (AddToDictionary)                            results.Add(field.Name, buttonData[0]); //[0] is product.code                        userInput = buttonData[1]; //[1] is product id as string                        if (RetainedResults.IsFormRetained)                            if ((field as DFLayoutLookupField).Properties.Retain)                                RetainedResults.Results.Add(field.Name, buttonData[0]);                    }                }            }            else if (field is DFLayoutSignaturePad)            {                string value = "";                var grid = view as Grid;                var signaturePad = grid.Children.OfType<SfSignaturePad>().FirstOrDefault();                DFLayoutSignaturePad dFLayoutSignaturePad = field as DFLayoutSignaturePad;                if (loadData.TryGetValue(dFLayoutSignaturePad.Name, out value))                {                    userInput = value;                }                else                {                    if (useSavedSignatures.Contains(dFLayoutSignaturePad.Name))                    {                        ImageSource src = ImageSource.FromStream(() => new MemoryStream((Application.Current.Properties["SavedSignature"]) as byte[]));                        userInput = ImageSourceToBase64(src);                    }                    else                    {                        signaturePad.Save();                        if (signaturePad.ImageSource != null)                        {                            userInput = ImageSourceToBase64(signaturePad.ImageSource);                        }                    }                }            }            else if (field is DFLayoutEmbeddedImage)            {                var embeddedImage = view as EmbeddedImageCapture;                if (embeddedImage.Image.Source != null)                {                    try                    {                        userInput = ImageSourceToBase64(embeddedImage.Image.Source);                    }                    catch (Exception e)                    {                        userInput = "";                    }                }            }            else if (field is DFLayoutMultiImage)            {                var multiImage = view as MultiImageCapture;                if (multiImage.Images.Count > 0)                {                    try                    {                        userInput = ImagesToBase64(multiImage.Images);                    }                    catch (Exception e)                    {                        userInput = "";                    }                }            }            else if (field is DFLayoutAddTaskField)            {                var addTaskButton = view as DFCreateTaskView;                if (!string.IsNullOrWhiteSpace(addTaskButton.TaskNumber))                {                    userInput = addTaskButton.TaskNumber;                }            }            else if (field is DFLayoutMultiSignaturePad)            {                var databutton = view as DataButtonControl;                if (!string.IsNullOrWhiteSpace(databutton.Data))                    userInput = databutton.Data;            }            //add the field name and input to 'results' dictionary for processing outside of QAFormViewer            if (!String.IsNullOrWhiteSpace(userInput) && AddToDictionary)            {                if (field is DFLayoutLookupField)                { /*do nothing as results have already been added*/ }                else                {                    try                    {                        results.Add(field.Name, userInput);                    }                    catch (Exception e)                    {                        errors.Add(e.Message);                    }                    if (RetainedResults.IsFormRetained)                    {                        AddRetainedToDictionary(field, userInput);                    }                }            }            else CheckRequired(field);            return userInput;        }        private void AddPropertyToDictionary(DFLayoutField field, String userInput)        {            if (!string.IsNullOrWhiteSpace(userInput))            {                try                {                    string property = "";                    if (field is DFLayoutStringField)                        property = (field as DFLayoutStringField).Properties.Property;                    else if (field is DFLayoutIntegerField)                        property = (field as DFLayoutIntegerField).Properties.Property;                    else if (field is DFLayoutDoubleField)                        property = (field as DFLayoutDoubleField).Properties.Property;                    else if (field is DFLayoutBooleanField)                        property = (field as DFLayoutBooleanField).Properties.Property;                    else if (field is DFLayoutDateField)                        property = (field as DFLayoutDateField).Properties.Property;                    else if (field is DFLayoutTimeField)                        property = (field as DFLayoutTimeField).Properties.Property;                    else if (field is DFLayoutOptionField)                        property = (field as DFLayoutOptionField).Properties.Property;                    else if (field is DFLayoutLookupField)                        property = (field as DFLayoutLookupField).Properties.Property;                    //'propertyResults' dictionary for processing outside of QAFormViewer                    if (!string.IsNullOrWhiteSpace(property)) propertyResults.Add(property, userInput);                }                catch (Exception e)                {                    errors.Add(e.Message);                    return;                }            }        }        private async void AddRetainedToDictionary(DFLayoutField field, string userInput)        {            await Task.Run(() =>            {                try                {                    if (field is DFLayoutStringField)                    {                        if ((field as DFLayoutStringField).Properties.Retain)                            RetainedResults.Results.Add(field.Name, userInput);                    }                    else if (field is DFLayoutIntegerField)                    {                        if ((field as DFLayoutIntegerField).Properties.Retain)                            RetainedResults.Results.Add(field.Name, userInput);                    }                    else if (field is DFLayoutDoubleField)                    {                        if ((field as DFLayoutDoubleField).Properties.Retain)                            RetainedResults.Results.Add(field.Name, userInput);                    }                    else if (field is DFLayoutBooleanField)                    {                        if ((field as DFLayoutBooleanField).Properties.Retain)                            RetainedResults.Results.Add(field.Name, userInput);                    }                    else if (field is DFLayoutDateField)                    {                        if ((field as DFLayoutDateField).Properties.Retain)                            RetainedResults.Results.Add(field.Name, userInput);                    }                    else if (field is DFLayoutTimeField)                    {                        if ((field as DFLayoutTimeField).Properties.Retain)                            RetainedResults.Results.Add(field.Name, userInput);                    }                    else if (field is DFLayoutOptionField)                    {                        if ((field as DFLayoutOptionField).Properties.Retain)                            RetainedResults.Results.Add(field.Name, userInput);                    }                }                catch (Exception e)                {                    errors.Add("Retained results error: " + e.Message);                }            });        }        #endregion        #region Checks / Custom methods        private void CheckRequired(DFLayoutField field)        {            if (field is DFLayoutStringField)            {                if ((field as DFLayoutStringField).Properties.Required)                {                    isRequiredEmpty = true;                    isRequiredMessage = (field as DFLayoutStringField).Description;                }            }            else if (field is DFLayoutIntegerField)            {                if ((field as DFLayoutIntegerField).Properties.Required)                {                    isRequiredEmpty = true;                    isRequiredMessage = (field as DFLayoutIntegerField).Description;                }            }            else if (field is DFLayoutDoubleField)            {                if ((field as DFLayoutDoubleField).Properties.Required)                {                    {                        isRequiredEmpty = true;                        isRequiredMessage = (field as DFLayoutIntegerField).Description;                    }                }            }            else if (field is DFLayoutBooleanField)            {                if ((field as DFLayoutBooleanField).Properties.Required)                {                    {                        isRequiredEmpty = true;                        isRequiredMessage = (field as DFLayoutBooleanField).Description;                    }                }            }            else if (field is DFLayoutDateField)            {                if ((field as DFLayoutDateField).Properties.Required)                {                    {                        isRequiredEmpty = true;                        isRequiredMessage = (field as DFLayoutDateField).Description;                    }                }            }            else if (field is DFLayoutTimeField)            {                if ((field as DFLayoutTimeField).Properties.Required)                {                    {                        isRequiredEmpty = true;                        isRequiredMessage = (field as DFLayoutTimeField).Description;                    }                }            }            else if (field is DFLayoutOptionField)            {                if ((field as DFLayoutOptionField).Properties.Required)                {                    {                        isRequiredEmpty = true;                        isRequiredMessage = (field as DFLayoutOptionField).Description;                    }                }            }            else if (field is DFLayoutLookupField)            {                if ((field as DFLayoutLookupField).Properties.Required)                {                    {                        isRequiredEmpty = true;                        isRequiredMessage = (field as DFLayoutLookupField).Description;                    }                }            }            else if (field is DFLayoutSignaturePad)            {                if ((field as DFLayoutSignaturePad).Properties.Required)                {                    {                        isRequiredEmpty = true;                        isRequiredMessage = (field as DFLayoutSignaturePad).Description;                    }                }            }            else if (field is DFLayoutEmbeddedImage)            {                if ((field as DFLayoutEmbeddedImage).Properties.Required)                {                    {                        isRequiredEmpty = true;                        isRequiredMessage = (field as DFLayoutEmbeddedImage).Description;                    }                }            }            else if (field is DFLayoutMultiImage)            {                if ((field as DFLayoutMultiImage).Properties.Required)                {                    {                        isRequiredEmpty = true;                        isRequiredMessage = (field as DFLayoutMultiImage).Description;                    }                }            }            else if (field is DFLayoutMultiSignaturePad)            {                if ((field as DFLayoutMultiSignaturePad).Properties.Required)                {                    {                        isRequiredEmpty = true;                        isRequiredMessage = (field as DFLayoutMultiSignaturePad).Description;                    }                }            }        }        private string ImagesToBase64(List<Image> images)        {            List<string> strings = new List<string>();            foreach (Image image in images)            {                strings.Add(ImageSourceToBase64(image.Source));            }            return Serialization.Serialize(strings);        }        private string ImageSourceToBase64(ImageSource source)        {            StreamImageSource streamImageSource = (StreamImageSource)source;            System.Threading.CancellationToken cancellationToken = System.Threading.CancellationToken.None;            Task<Stream> task = streamImageSource.Stream(cancellationToken);            Stream stream = task.Result;            byte[] bytes = new byte[stream.Length];            stream.Read(bytes, 0, bytes.Length);            string s = Convert.ToBase64String(bytes, Base64FormattingOptions.InsertLineBreaks);            return s;        }        private string FindIDForDesignLookupField(DataButtonControl button)        {            try            {                string userInputValue = button.Data;                string guidString = "";                if (userInputValue != nullOrInvalidType)                {                    foreach (KeyValuePair<DFLayoutLookupField, Dictionary<Guid, string>> pair in dfLayoutLookupFieldLookupOptions)                    {                        foreach (KeyValuePair<Guid, string> innerPair in pair.Value)                        {                            if (innerPair.Value == userInputValue)                            {                                guidString = innerPair.Key.ToString();                            }                        }                    }                }                return guidString;            }            catch            {                return "";            }        }        #endregion        #region Save Completion        //point of determination for whether or not QA form gets completed or saved for later        private void UpdateInstanceAndModel(bool saveForLater)        {            if (results.Count != 0)            {                if (!saveForLater)                {                    CompleteForm();                }                model.Instance.FormCompletedBy.ID = userID;                if (digitalFormID != Guid.Empty) model.Instance.Form.ID = digitalFormID;                model.Instance.FormData = Serialization.Serialize(results);                FormData = model.Instance.FormData;                if (model.Instance.FormStarted == DateTime.MinValue)                {                    model.Instance.FormStarted = timeStarted;                }                TimeSpan span = DateTime.Now - timeStarted;                model.Instance.FormOpen = model.Instance.FormOpen + span;                model.Update(null);            }        }        private void CompleteForm()        {            model.Instance.FormCompleted = DateTime.Now;            FormCompleted = model.Instance.FormCompleted;            model.Instance.Location.Longitude = location.Longitude;            model.Instance.Location.Latitude = location.Latitude;            model.Instance.Location.Timestamp = model.Instance.FormCompleted;        }        #endregion        #endregion        #region Expressions        public object GetFieldValue(string field)        {            try            {                Tuple<DFLayoutField, View> tuple = FindView(field);                return GetValueFromView(tuple.Item1, tuple.Item2);            }            catch            {                return "";            }        }        public void SetFieldValue(string field, object value)        {            try            {                Tuple<DFLayoutField, View> tuple = FindView(field);                SetValueOfView(tuple.Item1, tuple.Item2, value);            }            catch { }        }        private void SetValueOfView(DFLayoutField field, View view, object value)        {            if (field is DFLayoutBooleanField)                (view as CustomBoolean).Value = (bool)value;            else if (field is DFLayoutStringField || field is DFLayoutIntegerField || field is DFLayoutDoubleField)                (view as Editor).Text = value.ToString();            else if (field is DFLayoutDateField)                (view as DatePicker).Date = (DateTime)(value as DateTime?);            else if (field is DFLayoutDateTimeField)                (view as TimePicker).Time = (TimeSpan)(value as TimeSpan?);            else if (field is DFLayoutOptionField)                AssignPickerOption(view, field as DFLayoutOptionField, value as string);            else if (field is DFLayoutLookupField)                AssignLookupOption(view, value as string);        }        private void AssignLookupOption(View view, string value)        {            if (view is DataButtonControl)            {                (view as DataButtonControl).Text = value;                (view as DataButtonControl).Data = value;            }            else if (view is FrameButton) //currently only used for Products - we already have the Product.ID in Framebutton.Data (saved as Code,ID)            {                (view as FrameButton).SetButtonText(value);                (view as FrameButton).Data = value + "," + Guid.Empty.ToString();            }        }        private Tuple<DFLayoutField, View> FindView(string field)        {            DFLayoutField dflayoutfield = pairs.Keys.FirstOrDefault(x => x.Name == field);            View view = pairs[dflayoutfield];            return new Tuple<DFLayoutField, View>(dflayoutfield, view);        }        private void AssignPickerOption(View view, DFLayoutOptionField field, string value)        {            string s = field.Properties.Options;            string[] substrings = s.Split(',');            var optionList = substrings.ToList();            if (GlobalVariables.DeviceString == "i" || GlobalVariables.DeviceString == "I")            {                var iOSPicker = view as CustomPickeriOS;                iOSPicker.SelectedIndex = optionList.IndexOf(value);            }            else            {                var picker = view as Picker;                picker.SelectedIndex = optionList.IndexOf(value);            }        }        private object GetValueFromView(DFLayoutField field, View view)        {            if (field is DFLayoutBooleanField)                return (view as CustomBoolean).Value;            if (field is DFLayoutStringField)                return (view as Editor).Text;            else if (field is DFLayoutIntegerField)                return int.Parse((view as Editor).Text);            else if (field is DFLayoutDoubleField)                return double.Parse((view as Editor).Text);            else if (field is DFLayoutDateField)                return (view as DatePicker).Date;            else if (field is DFLayoutDateTimeField)                return (view as TimePicker).Time;            else if (field is DFLayoutOptionField)                return GetStringFromOptionField(view);            else if (field is DFLayoutLookupField)                return GetStringFromLookupField(view);            else if (field is DFLayoutSignaturePad)                return GetByteArrayFromSignaturePad(view, field.Name);            else if (field is DFLayoutEmbeddedImage)                return GetByteArrayFromEmbeddedImage(view);            else if (field is DFLayoutMultiImage)                return GetByteArrayListFromMultiImage(view);            else return "";        }        private object GetByteArrayListFromMultiImage(View view)        {            List<byte[]> list = new List<byte[]>();            var multiImage = view as MultiImageCapture;            if (multiImage.Images.Count > 0)            {                foreach (Image image in multiImage.Images)                {                    string base64 = ImageSourceToBase64(image.Source);                    list.Add(Convert.FromBase64String(base64));                }            }            return list;        }        private object GetByteArrayFromEmbeddedImage(View view)        {            var embeddedImage = view as EmbeddedImageCapture;            if (embeddedImage.Image.Source != null)            {                string base64 = ImageSourceToBase64(embeddedImage.Image.Source);                return Convert.FromBase64String(base64);            }            else                return null;        }        private byte[] GetByteArrayFromSignaturePad(View view, string name)        {            var grid = view as Grid;            var signaturePad = grid.Children.OfType<SfSignaturePad>().FirstOrDefault();            if (useSavedSignatures.Contains(name))            {                return Application.Current.Properties["SavedSignature"] as byte[];            }            else            {                signaturePad.Save();                if (signaturePad.ImageSource != null)                {                    string base64 = ImageSourceToBase64(signaturePad.ImageSource);                    return Convert.FromBase64String(base64);                }                else                    return null;            }        }        private object GetStringFromLookupField(View view)        {            string value = "";            if (view is DataButtonControl)            {                var button = view as DataButtonControl;                value = FindIDForDesignLookupField(button); //userinput is used to set guid later on for properties, but will not get added to form data only for lookupfields                                                      }            else if (view is FrameButton) //currently only used for Products - we already have the Product.ID in Framebutton.Data (saved as Code,ID)            {                FrameButton framebutton = view as FrameButton;                if (!string.IsNullOrWhiteSpace(framebutton.Data))                {                    string[] buttonData = framebutton.Data.Split(',');                    value = buttonData[1]; //[1] is product id as string                }            }            return value;        }        private string GetStringFromOptionField(View view)        {            if (GlobalVariables.DeviceString == "i" || GlobalVariables.DeviceString == "I")            {                var iOSPicker = view as CustomPickeriOS;                if (iOSPicker.SelectedIndex != -1)                {                    return iOSPicker.SelectedItem.ToString();                }                else                    return "";            }            else            {                var picker = view as Picker;                if (picker.SelectedIndex != -1)                {                    return picker.SelectedItem.ToString();                }                else                    return "";            }        }        public object GetFieldData(string fieldName, string dataField)        {            return new object();        }        #endregion    }}
 |