private void GetArrayIndex(object sender, ExtendSourceEventArgs e) // Handles ExtendCustomSource { ICustomSourceInfo info = e.SourceInfo; // This event has the Lowest priority, which means that it only fires if reflection fails. // We want to see if there is an "Index" property that was supplied. if (info.Selector.Equals("index", StringComparison.OrdinalIgnoreCase)) { if (info.Current is IList) { // This might occur if we have 2 lists that we are trying to sync. IList list = info.Current as IList; if (0 <= CollectionIndex & CollectionIndex < list.Count) { info.Current = list[CollectionIndex]; } else { // Not a valid index!!! Cannot synchronize these lists. } } else { // We want the Index to be inserted: info.Current = CollectionIndex; } } }
/// <summary> /// This allows an integer to be used as a selector to index an array (or list). /// Doesn't support ICollection because ICollection doesn't implement indexed items. /// /// This is better described using an example: /// CustomFormat("{Dates.2.Year}", {#1/1/2000#, #12/31/2999#, #9/9/9999#}) = "9999" /// The ".2" selector is used to reference Dates(2). /// </summary> private void GetArraySource(object sender, ExtendSourceEventArgs e) { ICustomSourceInfo info = e.SourceInfo; int itemIndex; if (info.Current is IList && int.TryParse(info.Selector, out itemIndex) && itemIndex < ((IList)info.Current).Count) { info.Current = ((IList)info.Current);//[itemIndex]; } }
private static void _GetDefaultSource(object source, ExtendSourceEventArgs e) { ICustomSourceInfo info = e.SourceInfo; // If it wasn't handled, let's evaluate the source on our own: // We will see if it's an argument index, dictionary key, or a property/field/method. // Maybe source is the global index of our arguments? int argIndex; if (info.SelectorIndex == 0 && int.TryParse(info.Selector, out argIndex)) { if (argIndex < info.Arguments.Length) { info.Current = info.Arguments[argIndex]; } else { // The index is out-of-range! } return; } // Maybe source is a Dictionary? if (info.Current is IDictionary && ((IDictionary)info.Current).Contains(info.Selector)) { info.Current = ((IDictionary)info.Current)[info.Selector]; return; } // REFLECTION: // Let's see if the argSelector is a Property/Field/Method: var sourceType = info.Current.GetType(); MemberInfo[] members = sourceType.GetMember(info.Selector); foreach (MemberInfo member in members) { switch (member.MemberType) { case MemberTypes.Field: // Selector is a Field; retrieve the value: FieldInfo field = member as FieldInfo; info.Current = field.GetValue(info.Current); return; case MemberTypes.Property: case MemberTypes.Method: MethodInfo method; if (member.MemberType == MemberTypes.Property) { // Selector is a Property PropertyInfo prop = member as PropertyInfo; // Make sure the property is not WriteOnly: if (prop.CanRead) { method = prop.GetGetMethod(); } else { continue; } } else { // Selector is a Method method = member as MethodInfo; } // Check that this method is valid -- it needs to be a Function (return a value) and has to be parameterless: // We are only looking for a parameterless Property/Method: if ((method.GetParameters().Length > 0)) { continue; } // Make sure that this method is not a Sub! It has to be a Function! if ((method.ReturnType == typeof(void))) { continue; } // Retrieve the Property/Method value: info.Current = method.Invoke(info.Current, new object[0]); return; } } // If we haven't returned yet, then the item must be invalid. }
public ExtendSourceEventArgs(ICustomSourceInfo sourceInfo) { SourceInfo = sourceInfo; }