/// <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)); }
/// <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 }
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); }
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); } } } }
public int IndexOf(T item) { return(list.IndexOf(item)); }