public bool Evaluate(IDataDescriptor source, out IDataDescriptor result) { result = null; object value = source.Value; if (value == null) { return(false); } ParameterInfo[] indexerParams = IndexerDataDescriptor.GetIndexerTypes(value.GetType()); object[] convertedIndices; // Search indexer on source type if (indexerParams != null && ReflectionHelper.ConsumeParameters(_indices, indexerParams, false, out convertedIndices)) { // Index on Item property result = new IndexerDataDescriptor(value, convertedIndices); return(true); } if (ReflectionHelper.ConvertTypes(_indices, new Type[] { typeof(int) }, out convertedIndices)) { // Collection index if (!ReflectionHelper.GetEnumerationEntryByIndex(value, (int)convertedIndices[0], out result)) { throw new XamlBindingException("Index '{0}' cannot be applied on '{1}'", ToString(), value); } return(true); } return(false); }
public IDataDescriptor Retarget(object newTarget) { if (newTarget == null) { throw new NullReferenceException("Target object 'null' is not supported"); } if (!IndicesCompatible(newTarget.GetType(), _indices)) { throw new InvalidOperationException( "Type of new target object is not compatible with the indices of this property descriptor"); } IndexerDataDescriptor result = new IndexerDataDescriptor(newTarget, _indices); return(result); }
/// <summary> /// Returns a data descriptor for the access to a collection-like instance /// <paramref name="maybeCollection"/> with an <paramref name="index"/>. /// </summary> /// <param name="maybeCollection">Instance which may be collection-like, like an /// <see cref="IList{T}"/>, <see cref="ICollection{T}"/> or <see cref="IEnumerable{T}"/>. /// The returned data descriptor will allow to read the value, and for an /// <see cref="IList{T}"/> it will also be writeable.</param> /// <param name="index">Index to access the collection-like instance.</param> /// <param name="result">Returns the data descriptor for the access to the /// <paramref name="index"/>th entry in <paramref name="maybeCollection"/>.</param> /// <returns><c>true</c>, if <paramref name="maybeCollection"/> is a collection-like /// instance and could be accessed by the specified <paramref name="index"/>, else /// <c>false</c>.</returns> public static bool GetEnumerationEntryByIndex(object maybeCollection, int index, out IDataDescriptor result) { if (maybeCollection is IList) { result = new IndexerDataDescriptor(maybeCollection, new object[] { index }); return(true); } if (maybeCollection is IEnumerable) { int i = 0; foreach (object o in (IEnumerable)maybeCollection) { if (i++ == index) { result = new ValueDataDescriptor(o); return(true); } } throw new XamlBindingException("Index '{0}' is out of range (# elements={1})", index, i); } result = null; return(false); }
/// <summary> /// Returns the information if the specified <paramref name="other"/> descriptor /// is targeted at the same list index on the same list. /// </summary> /// <param name="other">Other descriptor whose target object and property should be compared.</param> public bool TargetEquals(IndexerDataDescriptor other) { return(_target.Equals(other._target) && IndicesEquals(other._indices)); }
/// <summary> /// Returns a data descriptor for the access to a collection-like instance /// <paramref name="maybeCollection"/> with an <paramref name="index"/>. /// </summary> /// <param name="maybeCollection">Instance which may be collection-like, like an /// <see cref="IList{T}"/>, <see cref="ICollection{T}"/> or <see cref="IEnumerable{T}"/>. /// The returned data descriptor will allow to read the value, and for an /// <see cref="IList{T}"/> it will also be writeable.</param> /// <param name="index">Index to access the collection-like instance.</param> /// <param name="result">Returns the data descriptor for the access to the /// <paramref name="index"/>th entry in <paramref name="maybeCollection"/>.</param> /// <returns><c>true</c>, if <paramref name="maybeCollection"/> is a collection-like /// instance and could be accessed by the specified <paramref name="index"/>, else /// <c>false</c>.</returns> public static bool GetEnumerationEntryByIndex(object maybeCollection, int index, out IDataDescriptor result) { if (maybeCollection is IList) { result = new IndexerDataDescriptor(maybeCollection, new object[] { index }); return true; } if (maybeCollection is IEnumerable) { int i = 0; foreach (object o in (IEnumerable)maybeCollection) { if (i++ == index) { result = new ValueDataDescriptor(o); return true; } } throw new XamlBindingException("Index '{0}' is out of range (# elements={1})", index, i); } result = null; return false; }
/// <summary> /// Returns the information if the specified <paramref name="other"/> descriptor /// is targeted at the same list index on the same list. /// </summary> /// <param name="other">Other descriptor whose target object and property should be compared.</param> public bool TargetEquals(IndexerDataDescriptor other) { return _target.Equals(other._target) && IndicesEquals(other._indices); }
public IDataDescriptor Retarget(object newTarget) { if (newTarget == null) throw new NullReferenceException("Target object 'null' is not supported"); if (!IndicesCompatible(newTarget.GetType(), _indices)) throw new InvalidOperationException( "Type of new target object is not compatible with the indices of this property descriptor"); IndexerDataDescriptor result = new IndexerDataDescriptor(newTarget, _indices); return result; }