| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056 | 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 = DigitalForm.DeserializeFormData(model.Instance);                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 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 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)        {            try            {                var thisHeaderRow = GetRow(header);                var headerRows = GetOtherHeaders(thisHeaderRow);                if (headerRows.Any())                    AdjustHeightsToNextHeader(headerRows, thisHeaderRow, collapsed);                else                    AdjustHeightsBelowHeader(headerRows, thisHeaderRow, collapsed);            }            catch            {            }        }        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 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 (bool.Parse(value) == false)                    item.SetFalseValue();            }            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();            item.AutoSize = EditorAutoSizeOption.TextChanges;            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.GetEntityOrNull(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);            else if (lookuptype == null)                view = new Label { Text = "Null lookup selected", HorizontalOptions = LayoutOptions.Center, HorizontalTextAlignment = TextAlignment.Center };            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);            foreach (var property in dfLayoutLookupField.Properties.AdditionalPropertiesList)            {                columns.Add(property);            }            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            Dictionary<Guid, Dictionary<string, object>> additionalPropertyValues = new Dictionary<Guid, Dictionary<string, object>>();            foreach (var row in table.Rows)            {                Guid id = row.Get<Guid>("ID");                Dictionary<string, object> values = row.ToDictionary(new string[] { "ID" });                additionalPropertyValues.Add(id, values);                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,                ExtraData = additionalPropertyValues,                LookupFieldOptions = lookupFieldOptions            };            button.Clicked += (object sender, EventArgs eventArgs) =>            {                ListSelectionPage selectionPage = new ListSelectionPage(lookupFieldOptions);                selectionPage.OnSimpleListTapped += (s) =>                {                    button.Data = s;                    button.Text = s;                    dfLayout.ChangeField(dfLayoutLookupField.Name);                };                selectionPage.OnDictionaryItemTapped += (id, s) =>                {                    button.Data = s;                    button.Text = s;                    button.ChosenID = id;                    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.OnSimpleListTapped += (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)        {            try            {                if (element is DFLayoutField)                {                    pairs[element as DFLayoutField] = view;                    if (isSecure || readOnly || !string.IsNullOrWhiteSpace((element as DFLayoutField).GetPropertyValue<string>("Expression")))                        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);            }            catch            { }        }        #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;                DigitalForm.SerializeFormData(model.Instance, QueryVariables(model.Instance), results.ToDictionary(x => x.Key, x => x.Value as object));                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);            }        }        public List<DigitalFormVariable> QueryVariables(IDigitalFormInstance form)        {            List<DigitalFormVariable> variables = new List<DigitalFormVariable>();            var table = new Client<DigitalFormVariable>().Query(                    new Filter<DigitalFormVariable>(x => x.Form.ID).IsEqualTo(form.Form.ID),                    new Columns<DigitalFormVariable>(x => x.Code, x => x.Parameters, x => x.Description, x => x.VariableType),                    null                    );            foreach (CoreRow coreRow in table.Rows)            {                var variable = coreRow.ToObject<DigitalFormVariable>();                variables.Add(variable);            }            return variables;        }        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);            else if (field is DFLayoutEmbeddedImage)                AssignImage(view, value as byte[]);        }        private void AssignImage(View view, byte[] bytes)        {            var imageCapture = view as EmbeddedImageCapture;            imageCapture.DataToImage(bytes);        }        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)        {            Tuple<DFLayoutField, View> tuple = FindView(fieldName);            try            {                if (tuple.Item1 is DFLayoutLookupField)                {                    DFLayoutLookupField field = tuple.Item1 as DFLayoutLookupField;                    string type = field.Properties.LookupType;                    Type lookuptype = CoreUtils.GetEntityOrNull(type);                    if (lookuptype == typeof(Product))                    {                        var framebutton = tuple.Item2 as FrameButton;                        string[] buttonData = framebutton.Data.Split(',');                        string id = buttonData[1]; //[1] is product id as string                        CoreTable table = new Client<Product>().Query(new Filter<Product>(x => x.ID).IsEqualTo(Guid.Parse(id)), new Columns<Product>(x => x.Image.ID));                        if (table.Rows.Any())                        {                            Guid returnid = table.Rows.FirstOrDefault().Get<Product, Guid>(x => x.Image.ID);                            return returnid;                        }                        else                            return null;                    }                    else                    {                        var button = tuple.Item2 as DataButtonControl;                        Dictionary<string, object> dict = button.ExtraData[button.ChosenID];                        return dict[dataField];                    }                }                else                    return null;            }            catch            {                return null;            }        }        public void SetFieldColour(string field, System.Drawing.Color? colour = null)        {                    }        #endregion    }}
 |