コード例 #1
0
 /// <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);
 }
コード例 #2
0
 /// <summary>
 /// Returns the information if the specified <paramref name="other"/> descriptor
 /// references the same <see cref="Value"/>.
 /// </summary>
 /// <param name="other">Other descriptor whose <see cref="Value"/> should be compared.</param>
 public bool ValueEquals(ValueDataDescriptor other)
 {
     return(_value == null ? (other == null) : _value.Equals(other._value));
 }
コード例 #3
0
 /// <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;
 }
コード例 #4
0
 /// <summary>
 /// Returns the information if the specified <paramref name="other"/> descriptor
 /// references the same <see cref="Value"/>.
 /// </summary>
 /// <param name="other">Other descriptor whose <see cref="Value"/> should be compared.</param>
 public bool ValueEquals(ValueDataDescriptor other)
 {
   return _value == null ? (other == null) : _value.Equals(other._value);
 }
コード例 #5
0
    /// <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);
      }
    }
コード例 #6
0
 protected IDataDescriptor GetDataDescriptor(UIElement element)
 {
   string targetName = Storyboard.GetTargetName(this);
   object targetObject = null;
   if (targetName == null)
     targetObject = element;
   else
   {
     INameScope ns = element.FindNameScope();
     if (ns != null)
       targetObject = ns.FindName(targetName);
     if (targetObject == null)
       targetObject = element.FindElement(new NameMatcher(targetName));
     if (targetObject == null)
       return null;
   }
   try
   {
     IDataDescriptor result = new ValueDataDescriptor(targetObject);
     if (_propertyExpression != null && _propertyExpression.Evaluate(result, out result))
       return result;
   }
   catch (XamlBindingException e)
   {
     ServiceRegistration.Get<ILogger>().Warn("PropertyAnimationTimeline: Error evaluating expression '{0}' on target object '{1}'", e, _propertyExpression, targetObject);
   }
   return null;
 }