Пример #1
0
        /// <summary>
        /// Dynamically generate repeat items, reusing existing instances if available.
        /// </summary>
        /// <returns></returns>
        public void Update()
        {
            // refresh binding
            if (Binding != null)
            {
                Binding.Recalculate();
            }

            // configure listener for instance alterations
            if (Binding != null &&
                Binding.Context != null)
            {
                if (listener == null)
                {
                    var target = Binding.Context.Instance.Element.Parent.Interface <EventTarget>();

                    // find existing listener
                    listener =
                        InterfaceEventListener.GetListener(target, Events.Insert, true, Update) ??
                        InterfaceEventListener.GetListener(target, Events.Delete, true, Update);

                    // register listener
                    if (listener == null)
                    {
                        listener = InterfaceEventListener.Create(Update);
                        target.Register(Events.Insert, listener, true);
                        target.Register(Events.Delete, listener, true);
                    }
                }
            }

            // store current index item
            var indexPrev = Index;
            var indexItem = Element
                            .Elements()
                            .FirstOrDefault(i => i.AnnotationOrCreate <RepeatItemState>().Index == Index);

            // build new list of properly ordered nodes
            var items = Binding != null?Binding.ModelItems.Select(i => i.Xml).ToArray() : new XObject[0];

            var nodes = Element.Elements().ToArray();
            var sorts = new XElement[items.Length];

            for (int index = 0; index < items.Length; index++)
            {
                // model item at current index
                var item = items[index];

                // get existing item or create new
                var indx = Array.FindIndex(nodes, i => i.AnnotationOrCreate <RepeatItemState>().ModelObjectId == item.GetObjectId());
                var node = indx >= 0 ? nodes[indx] : null;
                if (node == null)
                {
                    node = new XElement(
                        Constants.XForms_1_0 + "group",
                        Template.GetNamespacePrefixAttributes(),
                        Template.Nodes());
                }

                // set node into output list
                sorts[index] = node;

                // configure item state
                var anno = node.AnnotationOrCreate <RepeatItemState>();
                anno.ModelObjectId = item.GetObjectId();
                anno.Index         = index + 1;
                anno.Size          = items.Length;
            }

            // new sequence is different from old sequence
            if (sorts.Length != nodes.Length ||
                sorts.SequenceEqual(nodes) == false)
            {
                // replace all children
                Element.RemoveNodes();
                Element.Add(sorts);

                // set of elements that were added
                var added = sorts
                            .Except(nodes)
                            .ToArray();

                // model-construct-done sequence applied to new children
                foreach (var node in added)
                {
                    foreach (var i in GetAllExtensions <IOnRefresh>(node))
                    {
                        i.RefreshBinding();
                    }
                }

                // discard refresh events
                foreach (var node in added)
                {
                    foreach (var i in GetAllExtensions <IOnRefresh>(node))
                    {
                        i.DiscardEvents();
                    }
                }

                // final refresh
                foreach (var node in added)
                {
                    foreach (var i in GetAllExtensions <IOnRefresh>(node))
                    {
                        i.Refresh();
                    }
                }
            }

            // restore or reset index
            var length = Element.Elements().Count();

            if (indexItem != null &&
                indexItem.Parent != null)
            {
                Index = indexItem.AnnotationOrCreate <RepeatItemState>().Index;
            }
            else if (indexPrev > 0)
            {
                Index = indexPrev <= length ? indexPrev : length;
            }
            else if (length > 0)
            {
                Index = 1;
            }
            else
            {
                Index = 0;
            }
        }
Пример #2
0
        /// <summary>
        /// Refreshes all properties.
        /// </summary>
        public void Refresh()
        {
            var oldItemType = DataType;
            var oldRelevant = Relevant;
            var oldReadOnly = ReadOnly;
            var oldRequired = Required;
            var oldValid    = Valid;
            var oldValue    = Value;

            if (binding != null)
            {
                binding.Recalculate();

                if (modelItem != binding.ModelItem)
                {
                    modelItem = binding.ModelItem;
                }
            }

            if (modelItem != null)
            {
                State.DataType = modelItem.ItemType;
                State.Relevant = modelItem.Relevant;
                State.ReadOnly = modelItem.ReadOnly;
                State.Required = modelItem.Required;
                State.Valid    = modelItem.Valid;
                State.Value    = modelItem.Value;
            }
            else
            {
                // default values
                State.DataType = null;
                State.Relevant = true;
                State.ReadOnly = false;
                State.Required = false;
                State.Valid    = true;
                State.Value    = null;
            }

            // mark all required events
            var valueChanged = Value != oldValue;

            if (valueChanged)
            {
                State.DispatchValueChanged = true;
            }

            if (Relevant != oldRelevant || valueChanged)
            {
                if (Relevant)
                {
                    State.DispatchEnabled = true;
                }
                else
                {
                    State.DispatchDisabled = true;
                }
            }

            if (ReadOnly != oldReadOnly || valueChanged)
            {
                if (ReadOnly)
                {
                    State.DispatchReadOnly = true;
                }
                else
                {
                    State.DispatchReadWrite = true;
                }
            }

            if (Required != oldRequired || valueChanged)
            {
                if (Required)
                {
                    State.DispatchRequired = true;
                }
                else
                {
                    State.DispatchOptional = true;
                }
            }

            if (Valid != oldValid || valueChanged)
            {
                if (Valid)
                {
                    State.DispatchValid = true;
                }
                else
                {
                    State.DispatchInvalid = true;
                }
            }
        }