/// <summary>
        /// Forwards the <paramref name="source" /> changes to the <paramref name="target" />.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source">The source observable list.</param>
        /// <param name="target">The target binding list.</param>
        /// <param name="includeItemChanges">if set to <c>true</c> individual items' changes will be propagated to the
        /// <paramref name="target" /> via replacing the item completely.</param>
        /// <param name="includeMoves">if set to <c>true</c> move operations will be replicated to the <paramref name="target" />.</param>
        /// <param name="scheduler">The scheduler.</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentNullException">source
        /// or
        /// target</exception>
        /// <exception cref="System.InvalidOperationException">Source and Target Lists must contain exactly the same element(s) at
        /// the exact same index position(s)</exception>
        public static IDisposable ForwardListChangesTo <T>(
            this IObservableList <T> source,
            IEnhancedBindingList <T> target,
            bool includeItemChanges = true,
            bool includeMoves       = false,
            IScheduler scheduler    = null)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }

            if (includeMoves && (source.Except(target).Any() ||
                                 target.Except(source).Any() ||
                                 source.Any(element => source.IndexOf(element) != target.IndexOf(element))))
            {
                throw new InvalidOperationException("Source and Target Lists must contain exactly the same element(s) at the exact same index position(s)");
            }

            IObservable <IObservableListChange <T> > sourceObservable = scheduler != null
                ? source.ListChanges.ObserveOn(scheduler)
                : source.ListChanges;

            return(sourceObservable.ForwardListChangesTo(target, includeItemChanges, includeMoves));
        }
예제 #2
0
        /// <summary>
        /// Render a new list item element
        /// </summary>
        /// <param name="itemData"></param>
        /// <param name="dataSource"></param>
        /// <param name="itemTemplate"></param>
        /// <param name="list"></param>
        internal void RenderListItem(object itemData, string dataSource, XmlElement itemTemplate, IObservableList list)
        {
            // Create the new item based on the item template for this list
            var element = (XmlElement)GameObject.Instantiate(itemTemplate);
            var parent  = currentListElement.listElement;

            // Add the new item to the list container
            parent.AddChildElement(element);

            // The template will be inactive by default, we need to make it active
            element.SetAttribute("active", "true");

            // Get/Add the List Item component and add it to the element
            var listItemComponent = element.gameObject.GetComponent <XmlLayoutListItem>() ?? element.gameObject.AddComponent <XmlLayoutListItem>();

            listItemComponent.guid = list.GetGUID(itemData);

            // Add this list item to the list's item collection
            var index = list.IndexOf(itemData);

            currentListElement.listItems.Insert(index, listItemComponent);

            // Load the data from 'itemData' and apply it to our new list element
            ApplyViewModelData(element, itemData, dataSource, itemTemplate, list, null, true, true);

            // apply our attributes (especially necessary for things like event handlers and the like)
            element.Initialise(currentXmlLayoutInstance, element.rectTransform, element.tagHandler);
            element.ApplyAttributes();

            element.AnimationDuration = currentListElement.itemAnimationDuration;
            element.ShowAnimation     = currentListElement.itemShowAnimation;
            element.HideAnimation     = currentListElement.itemHideAnimation;

            if (element.ShowAnimation != "None")
            {
                element.Show();
            }

            // Rebuild the layout at the end of the frame
            XmlLayoutTimer.AtEndOfFrame(() => LayoutRebuilder.MarkLayoutForRebuild(element.rectTransform), element);

#if UNITY_5_4
            // Due to differences in how 5.4 and 5.5 handle layout rebuilds, we sometimes have to manually notify child TableLayouts to update
            XmlLayoutTimer.DelayedCall(0.05f, () =>
            {
                var tableLayouts = element.GetComponentsInChildren <UI.Tables.TableLayout>();
                foreach (var tableLayout in tableLayouts)
                {
                    tableLayout.UpdateLayout();
                }
            }, element);
#endif
        }
예제 #3
0
        public TreePath PathFromNode(object aNode)
        {
            TreePath tp = new TreePath();

            if ((aNode == null) || (sourceList == null) || (sourceList.Count == 0))
            {
                return(tp);
            }

            int i = sourceList.IndexOf(aNode);

            if (i > -1)
            {
                tp.AppendIndex(i);
            }
            return(tp);
        }
예제 #4
0
        void HandleTwoWayBinding(XmlElement element, string dataSource, IObservableList list, object itemData, List <ListItemAttributeMatch> attributes)
        {
            if (element.HasAttribute("__twoWayBindingSetupComplete"))
            {
                return;
            }

            var tagHandler = element.tagHandler;

            if (tagHandler is IHasXmlFormValue)
            {
                var attribute = attributes.FirstOrDefault(a => a.bindingType == ViewModelBindingType.TwoWay &&
                                                          (a.attribute.Equals("value", StringComparison.OrdinalIgnoreCase) ||
                                                           a.attribute.Equals("text", StringComparison.OrdinalIgnoreCase) ||
                                                           a.attribute.Equals("ison", StringComparison.OrdinalIgnoreCase)));

                if (attribute != null)
                {
                    var memberName = attribute.field;

                    tagHandler.SetInstance(element.rectTransform, currentXmlLayoutInstance);

                    if (tagHandler.primaryComponent == null)
                    {
                        return;
                    }

                    var componentType            = tagHandler.primaryComponent.GetType();
                    var onValueChangedMemberInfo = componentType.GetMember("onValueChanged").FirstOrDefault();


                    if (onValueChangedMemberInfo != null)
                    {
                        var onValueChangedListener = onValueChangedMemberInfo.GetMemberValue(tagHandler.primaryComponent);
                        var addListenerMethod      = onValueChangedListener.GetType().GetMethod("AddListener");

                        var eventType     = addListenerMethod.GetParameters()[0].ParameterType;
                        var parameterType = eventType.GetGenericArguments()[0];

                        var controller = (XmlLayoutControllerMVVM)currentXmlLayoutInstance.XmlLayoutController;

                        // I tried to implement this more generically with reflection but had no luck. I'm sure there is a way to do it...
                        // I'll try again at a later date.
                        if (parameterType == typeof(float))
                        {
                            ((UnityEvent <float>)onValueChangedListener).AddListener((v) => controller.SetViewModelListItemValue(dataSource, list.IndexOf(itemData), memberName, v, true));
                        }
                        else if (parameterType == typeof(int))
                        {
                            ((UnityEvent <int>)onValueChangedListener).AddListener((v) => controller.SetViewModelListItemValue(dataSource, list.IndexOf(itemData), memberName, v, true));
                        }
                        else if (parameterType == typeof(string))
                        {
                            ((UnityEvent <string>)onValueChangedListener).AddListener((v) => controller.SetViewModelListItemValue(dataSource, list.IndexOf(itemData), memberName, v, true));
                        }
                        else if (parameterType == typeof(bool))
                        {
                            ((UnityEvent <bool>)onValueChangedListener).AddListener((v) => controller.SetViewModelListItemValue(dataSource, list.IndexOf(itemData), memberName, v, true));
                        }

                        // Mark this element as having its binding setup complete (so that we don't repeat this)
                        element.SetAttribute("__twoWayBindingSetupComplete", string.Empty);
                    }
                }
            }
        }
예제 #5
0
 public int IndexOf(T item)
 {
     return(list.IndexOf(item));
 }