/// <summary>
        /// Given the instance <paramref name="obj"/> and the <paramref name="memberName"/>,
        /// this method searches the best matching member on the instance. It first searches
        /// a property with name [PropertyName]Property, casts it to
        /// <see cref="AbstractProperty"/> and returns a <see cref="DependencyPropertyDataDescriptor"/>
        /// for it in the parameter <paramref name="dd"/>. If there is no such property, this method
        /// searches a simple property with the given name, returning a property descriptor for it.
        /// Then, the method will search for a field with the specified name, returning a
        /// <see cref="FieldDataDescriptor"/> for it.
        /// If there is no member found with the given name, this method returns false and a
        /// <c>null</c> value in <paramref name="dd"/>.
        /// </summary>
        /// <param name="obj">The object where to search the member with the
        /// specified <paramref name="memberName"/>.</param>
        /// <param name="memberName">The name of the member to be searched.</param>
        /// <param name="dd">Data descriptor which will be returned for the property or member,
        /// if it was found, else a <c>null</c> value will be returned.</param>
        /// <returns><c>true</c>, if a member with the specified name was found, else <c>false</c>.</returns>
        public static bool FindMemberDescriptor(object obj, string memberName, out IDataDescriptor dd)
        {
            if (obj == null)
            {
                throw new NullReferenceException("Property target object 'null' is not supported");
            }
            DependencyPropertyDataDescriptor dpdd;

            if (DependencyPropertyDataDescriptor.CreateDependencyPropertyDataDescriptor(
                    obj, memberName, out dpdd))
            {
                dd = dpdd;
                return(true);
            }
            SimplePropertyDataDescriptor spdd;

            if (SimplePropertyDataDescriptor.CreateSimplePropertyDataDescriptor(
                    obj, memberName, out spdd))
            {
                dd = spdd;
                return(true);
            }
            FieldDataDescriptor fdd;

            if (FieldDataDescriptor.CreateFieldDataDescriptor(obj, memberName, out fdd))
            {
                dd = fdd;
                return(true);
            }
            dd = null;
            return(false);
        }
Beispiel #2
0
        public static bool CreateDependencyPropertyDataDescriptor(object targetObj,
                                                                  string propertyName, out DependencyPropertyDataDescriptor result)
        {
            result = null;
            if (targetObj == null)
            {
                throw new NullReferenceException("Target object 'null' is not supported");
            }
            AbstractProperty prop;

            if (!FindDependencyProperty(targetObj, ref propertyName, out prop))
            {
                return(false);
            }
            result = new DependencyPropertyDataDescriptor(targetObj, propertyName, prop);
            return(true);
        }
Beispiel #3
0
 /// <summary>
 /// Returns the information if the specified <paramref name="other"/> descriptor
 /// is targeted at the same property on the same object.
 /// </summary>
 /// <param name="other">Other descriptor whose target object and property should be compared.</param>
 public bool TargetEquals(DependencyPropertyDataDescriptor other)
 {
     return(_obj.Equals(other._obj) && _propertyName.Equals(other._propertyName));
 }
Beispiel #4
0
        public bool Evaluate(IDataDescriptor source, out IDataDescriptor result)
        {
            result = null;
            Type       type;
            object     obj;
            MemberInfo mi;

            if (!ExtractWorkingData(source, _memberName + "Property", out type, out obj, out mi))
            {
                if (!ExtractWorkingData(source, _memberName, out type, out obj, out mi))
                {
                    return(false);
                }
            }
            if (mi is FieldInfo)
            { // Field access
                result = new FieldDataDescriptor(obj, (FieldInfo)mi);
                return(true);
            }
            if (mi is PropertyInfo)
            { // Property access
                PropertyInfo pi = (PropertyInfo)mi;
                // Handle indexed property
                object[] convertedIndices = null;
                // Check property indexer
                bool indicesOnProperty = _indices != null && _indices.Length > 0 &&
                                         ReflectionHelper.ConsumeParameters(_indices, pi.GetIndexParameters(),
                                                                            false, out convertedIndices);
                if (!indicesOnProperty)
                {
                    convertedIndices = null;
                }
                if (pi.PropertyType == typeof(AbstractProperty))
                { // Property value -> request value and return DependencyPropertyDataDescriptor
                    object val = pi.GetValue(obj, convertedIndices);
                    if (val == null)
                    {
                        return(false);
                    }
                    result = new DependencyPropertyDataDescriptor(obj, _memberName, (AbstractProperty)val);
                }
                else
                { // Simple property
                    result = new SimplePropertyDataDescriptor(obj, pi);
                    if (convertedIndices != null && convertedIndices.Length > 0)
                    {
                        ((SimplePropertyDataDescriptor)result).Indices = convertedIndices;
                    }
                }
                if (_indices != null && _indices.Length > 0 && !indicesOnProperty)
                {
                    // Item or collection index -> handle index expression per IndexerPathSegment
                    return(new IndexerPathSegment(_indices).Evaluate(result, out result));
                }
                return(true);
            }
            if (mi is MethodInfo)
            {
                // Method invocation is not supported in evaluation
                return(false);
            }
            // Unsupported member type
            return(false);
        }
 /// <summary>
 /// Returns the information if the specified <paramref name="other"/> descriptor
 /// is targeted at the same property on the same object.
 /// </summary>
 /// <param name="other">Other descriptor whose target object and property should be compared.</param>
 public bool TargetEquals(DependencyPropertyDataDescriptor other)
 {
   return _obj.Equals(other._obj) && _propertyName.Equals(other._propertyName);
 }
 public static bool CreateDependencyPropertyDataDescriptor(object targetObj,
     string propertyName, out DependencyPropertyDataDescriptor result)
 {
   result = null;
   if (targetObj == null)
     throw new NullReferenceException("Target object 'null' is not supported");
   AbstractProperty prop;
   if (!FindDependencyProperty(targetObj, ref propertyName, out prop))
     return false;
   result = new DependencyPropertyDataDescriptor(targetObj, propertyName, prop);
   return true;
 }
    /// <summary>
    /// Does the lookup for our binding source data. This includes evaluation of our source
    /// properties and the lookup for the data context.
    /// </summary>
    /// <remarks>
    /// During the lookup, change handlers will be attached to all relevant properties
    /// on the search path to the binding source. If one of the properties changes,
    /// this binding will re-evaluate.
    /// </remarks>
    /// <param name="result">Resulting source descriptor, if it could be resolved.</param>
    /// <returns><c>true</c>, if the binding source could be found and evaluated,
    /// <c>false</c> if it could not be resolved (yet).</returns>
    protected bool GetSourceDataDescriptor(out IDataDescriptor result)
    {
      ResetChangeHandlerAttachments();
      result = null;
      try
      {
        switch (_typeOfSource)
        {
          case SourceType.DataContext:
            return FindDataContext(out result);
          case SourceType.SourceProperty:
#if DEBUG_BINDINGS
            if (Source == null)
              DebugOutput("GetSourceDataDescriptor doesn't have a Source", Source);
#endif
            result = new DependencyPropertyDataDescriptor(this, "Source", _sourceProperty);
            return true;
          case SourceType.RelativeSource:
            DependencyObject current = _contextObject;
            if (current == null)
              return false;
            switch (RelativeSource.Mode)
            {
              case RelativeSourceMode.Self:
                result = new ValueDataDescriptor(current);
                return true;
              case RelativeSourceMode.TemplatedParent:
                while (current != null)
                {
                  DependencyObject last = current;
                  FindParent(last, out current, FindParentMode.HybridPreferVisualTree);
                  UIElement lastUIElement = last as UIElement;
                  if (lastUIElement != null)
                  {
                    AttachToSourcePathProperty(lastUIElement.TemplateNameScopeProperty);
                    if (lastUIElement.IsTemplateControlRoot)
                    {
                      result = new ValueDataDescriptor(current);
                      return true;
                    }
                  }
                }
#if DEBUG_BINDINGS
            DebugOutput("GetSourceDataDescriptor didn't find TemplateParent");
#endif
                return false;
              case RelativeSourceMode.FindAncestor:
                if (FindAncestor(current, out current, FindParentMode.HybridPreferVisualTree,
                    RelativeSource.AncestorLevel, RelativeSource.AncestorType))
                {
                  result = new ValueDataDescriptor(current);
                  return true;
                }
                return false;
                //case RelativeSourceMode.PreviousData:
                //  // TODO: implement this
                //  throw new NotImplementedException(RelativeSourceMode.PreviousData.ToString());
              default:
                // Should never occur. If so, we have forgotten to handle a RelativeSourceMode
                throw new NotImplementedException(
                    string.Format("RelativeSourceMode '{0}' is not implemented", RelativeSource.Mode));
            }
          case SourceType.ElementName:
            INameScope nameScope;
            if (!FindNameScope(out nameScope))
              return false;
            object obj = nameScope.FindName(ElementName) as UIElement;
            if (obj == null)
            {
#if DEBUG_BINDINGS
              DebugOutput("GetSourceDataDescriptor didn't find object with name '{0}'", ElementName);
#endif
              return false;
            }
            result = new ValueDataDescriptor(obj);
            return true;
          default:
            // Should never occur. If so, we have forgotten to handle a SourceType
            throw new NotImplementedException(
                string.Format("SourceType '{0}' is not implemented", _typeOfSource));
        }
      }
      finally
      {
        AttachToSource(result);
        IObservable observable = result == null ? null : result.Value as IObservable;
        if (observable != null)
          AttachToSourceObservable(observable);
      }
    }