Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / MS / Internal / Data / ObjectRef.cs / 1305600 / ObjectRef.cs
//---------------------------------------------------------------------------- // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // Description: ObjectRef is a general way to name objects used in data binding // // See spec at http://avalon/connecteddata/Specs/Data%20Binding.mht // //--------------------------------------------------------------------------- using System; using System.Collections; using System.Diagnostics; using System.Globalization; using System.Reflection; using System.Windows; using System.Windows.Media; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Markup; using MS.Internal; using MS.Internal.Utility; namespace MS.Internal.Data { #region ObjectRefArgs // args to GetObject and GetDataObject internal class ObjectRefArgs { internal bool IsTracing { get; set; } internal bool ResolveNamesInTemplate { get; set; } internal bool NameResolvedInOuterScope { get; set; } } #endregion ObjectRefArgs #region ObjectRef ///Abstract object reference. internal abstract class ObjectRef { //----------------------------------------------------- // // Constructors // //----------------------------------------------------- ///Constructor is protected - you can only create subclasses. protected ObjectRef() {} //------------------------------------------------------ // // Public Methods // //----------------------------------------------------- ///Returns the referenced object. /// Element defining context for the reference. /// See ObjectRefArgs internal virtual object GetObject(DependencyObject d, ObjectRefArgs args) { return null; } ///Returns the data object associated with the referenced object. /// Often this is the same as the referenced object. /// /// Element defining context for the reference. /// See ObjectRefArgs internal virtual object GetDataObject(DependencyObject d, ObjectRefArgs args) { return GetObject(d, args); } ///true if the ObjectRef really needs the tree context internal bool TreeContextIsRequired(DependencyObject target) { return ProtectedTreeContextIsRequired(target); } ///true if the ObjectRef really needs the tree context protected virtual bool ProtectedTreeContextIsRequired(DependencyObject target) { return false; } ////// true if the ObjectRef uses the mentor of the target element, /// rather than the target element itself. /// internal bool UsesMentor { get { return ProtectedUsesMentor; } } ////// true if the ObjectRef uses the mentor of the target element, /// rather than the target element itself. /// protected virtual bool ProtectedUsesMentor { get { return true; } } ////// identify this ObjectRef to the user - used by extended tracing /// internal abstract string Identify(); } #endregion ObjectRef #region ElementObjectRef ///Object reference to a DependencyObject via its Name. internal sealed class ElementObjectRef : ObjectRef { //------------------------------------------------------ // // Constructors // //------------------------------------------------------ ///Constructor. /// Name of the referenced Element. ///name is a null reference internal ElementObjectRef(string name) { if (name == null) throw new ArgumentNullException("name"); _name = name.Trim(); } //----------------------------------------------------- // // Public Methods // //------------------------------------------------------ ///Returns the referenced object. /// Element defining context for the reference. /// See ObjectRefArgs internal override object GetObject(DependencyObject d, ObjectRefArgs args) { if (d == null) throw new ArgumentNullException("d"); object o = null; if (args.ResolveNamesInTemplate) { // look in container's template (if any) first FrameworkElement fe = d as FrameworkElement; if (fe != null && fe.TemplateInternal != null) { o = Helper.FindNameInTemplate(_name, d); if (args.IsTracing) { TraceData.Trace(TraceEventType.Warning, TraceData.ElementNameQueryTemplate( _name, TraceData.Identify(d))); } } if (o == null) { args.NameResolvedInOuterScope = true; } } FrameworkObject fo = new FrameworkObject(d); while (o == null && fo.DO != null) { DependencyObject scopeOwner; o = fo.FindName(_name, out scopeOwner); // if the original element is a scope owner, supports IComponentConnector, // and has a parent, don't use the result of FindName. The // element is probably an instance of a Xaml-subclassed control; // we want to resolve the name starting in the next outer scope. // (bug 1669408) // Also, if the element's NavigationService property is locally // set, the element is the root of a navigation and should use the // inner scope (bug 1765041) if (d == scopeOwner && d is IComponentConnector && d.ReadLocalValue(System.Windows.Navigation.NavigationService.NavigationServiceProperty) == DependencyProperty.UnsetValue) { DependencyObject parent = LogicalTreeHelper.GetParent(d); if (parent == null) { parent = Helper.FindMentor(d.InheritanceContext); } if (parent != null) { o = null; fo.Reset(parent); continue; } } if (args.IsTracing) { TraceData.Trace(TraceEventType.Warning, TraceData.ElementNameQuery( _name, TraceData.Identify(fo.DO))); } if (o == null) { args.NameResolvedInOuterScope = true; // move to the next outer namescope. // First try TemplatedParent of the scope owner. FrameworkObject foScopeOwner = new FrameworkObject(scopeOwner); DependencyObject dd = foScopeOwner.TemplatedParent; // if that doesn't work, we could be at the top of // generated content for an ItemsControl. If so, use // the (visual) parent - a panel. if (dd == null) { Panel panel = fo.FrameworkParent.DO as Panel; if (panel != null && panel.IsItemsHost) { dd = panel; } } // next, see if we're in a logical tree attached directly // to a ContentPresenter. This is the m---- equivalent of // having the ContentPresenter as the TemplatedParent. if (dd == null && scopeOwner == null) { // go to the top of the logical subtree DependencyObject parent; for (dd = fo.DO;;) { parent = LogicalTreeHelper.GetParent(dd); if (parent == null) { parent = Helper.FindMentor(dd.InheritanceContext); } if (parent == null) break; dd = parent; } // if it's attached to a ContentPresenter, move to the CP ContentPresenter cp = VisualTreeHelper.IsVisualType(dd) ? VisualTreeHelper.GetParent(dd) as ContentPresenter : null; dd = (cp != null && cp.TemplateInternal.CanBuildVisualTree) ? cp : null; } fo.Reset(dd); } } if (o == null) { o = DependencyProperty.UnsetValue; args.NameResolvedInOuterScope = false; } return o; } public override string ToString() { return String.Format(CultureInfo.InvariantCulture, "ElementName={0}", _name); } internal override string Identify() { return "ElementName"; } //----------------------------------------------------- // // Private Fields // //----------------------------------------------------- string _name; } #endregion ElementObjectRef #region RelativeObjectRef ///Object reference relative to the target element. /// internal sealed class RelativeObjectRef : ObjectRef { //----------------------------------------------------- // // Constructors // //------------------------------------------------------ ///Constructor. /// RelativeSource. ///relativeSource is a null reference internal RelativeObjectRef(RelativeSource relativeSource) { if (relativeSource == null) throw new ArgumentNullException("relativeSource"); _relativeSource = relativeSource; } //----------------------------------------------------- // // Public Methods // //------------------------------------------------------ public override string ToString() { string s; switch (_relativeSource.Mode) { case RelativeSourceMode.FindAncestor: s = String.Format(CultureInfo.InvariantCulture, "RelativeSource {0}, AncestorType='{1}', AncestorLevel='{2}'", _relativeSource.Mode, _relativeSource.AncestorType, _relativeSource.AncestorLevel); break; default: s = String.Format(CultureInfo.InvariantCulture, "RelativeSource {0}", _relativeSource.Mode); break; } return s; } ///Returns the referenced object. /// Element defining context for the reference. /// See ObjectRefArgs ///d is a null reference internal override object GetObject(DependencyObject d, ObjectRefArgs args) { return GetDataObjectImpl(d, args); } ///Returns the data object associated with the referenced object. /// Often this is the same as the referenced object. /// /// Element defining context for the reference. /// See ObjectRefArgs ///d is a null reference internal override object GetDataObject(DependencyObject d, ObjectRefArgs args) { object o = GetDataObjectImpl(d, args); DependencyObject el = o as DependencyObject; if (el != null && ReturnsDataContext) { // for generated wrappers, use the ItemForContainer property instead // of DataContext, since it's always set by the generator o = el.GetValue(ItemContainerGenerator.ItemForItemContainerProperty); if (o == null) o = el.GetValue(FrameworkElement.DataContextProperty); } return o; } private object GetDataObjectImpl(DependencyObject d, ObjectRefArgs args) { if (d == null) return null; switch (_relativeSource.Mode) { case RelativeSourceMode.Self: break; // nothing to do case RelativeSourceMode.TemplatedParent: d = Helper.GetTemplatedParent(d); break; case RelativeSourceMode.PreviousData: return GetPreviousData(d); case RelativeSourceMode.FindAncestor: d = FindAncestorOfType(_relativeSource.AncestorType, _relativeSource.AncestorLevel, d, args.IsTracing); if (d == null) { return DependencyProperty.UnsetValue; // we fell off the tree } break; default: return null; } if (args.IsTracing) { TraceData.Trace(TraceEventType.Warning, TraceData.RelativeSource( _relativeSource.Mode, TraceData.Identify(d))); } return d; } internal bool ReturnsDataContext { get { return (_relativeSource.Mode == RelativeSourceMode.PreviousData); } } ///true if the ObjectRef really needs the tree context protected override bool ProtectedTreeContextIsRequired(DependencyObject target) { return ( (_relativeSource.Mode == RelativeSourceMode.FindAncestor || (_relativeSource.Mode == RelativeSourceMode.PreviousData))); } protected override bool ProtectedUsesMentor { get { switch (_relativeSource.Mode) { case RelativeSourceMode.TemplatedParent: case RelativeSourceMode.PreviousData: return true; default: return false; } } } internal override string Identify() { return String.Format(System.Windows.Markup.TypeConverterHelper.InvariantEnglishUS, "RelativeSource ({0})", _relativeSource.Mode); } //------------------------------------------------------ // // Private Method // //----------------------------------------------------- private object GetPreviousData(DependencyObject d) { // move up to the next containing DataContext scope for (; d != null; d = FrameworkElement.GetFrameworkParent(d)) { if (BindingExpression.HasLocalDataContext(d)) { // special case: if the element is a ContentPresenter // whose templated parent is a ContentControl or // HeaderedItemsControl, and both have the same // DataContext, we'll use the parent instead of the // ContentPresenter. In this case, the DataContext // of the CP is set by various forwarding rules, and // shouldn't count as a new scope. // Similarly, do the same for a FE whose parent // is a GridViewRowPresenter; this enables Previous bindings // inside ListView. FrameworkElement parent, child; ContentPresenter cp; if ((cp = d as ContentPresenter) != null) { child = cp; parent = cp.TemplatedParent as FrameworkElement; if (!(parent is ContentControl || parent is HeaderedItemsControl)) { parent = cp.Parent as System.Windows.Controls.Primitives.GridViewRowPresenterBase; } } else { child = d as FrameworkElement; parent = ((child != null) ? child.Parent : null) as System.Windows.Controls.Primitives.GridViewRowPresenterBase; } if (child != null && parent != null && Object.Equals(child.DataContext, parent.DataContext)) { d = parent; if (!BindingExpression.HasLocalDataContext(parent)) { continue; } } break; } } if (d == null) return DependencyProperty.UnsetValue; // we fell off the tree // this only makes sense within generated content. If this // is the case, then d is now the wrapper element, its visual // parent is the layout element, and the layout's ItemsOwner // is the govening ItemsControl. Visual v = d as Visual; DependencyObject layout = (v != null) ? VisualTreeHelper.GetParent(v) : null; ItemsControl ic = ItemsControl.GetItemsOwner(layout); if (ic == null) { if (TraceData.IsEnabled) TraceData.Trace(TraceEventType.Error, TraceData.RefPreviousNotInContext); return null; } // now look up the wrapper's previous sibling within the // layout's children collection Visual v2 = layout as Visual; int count = (v2 != null) ? v2.InternalVisualChildrenCount : 0; int j = -1; Visual prevChild = null; //child at j-1th index if (count != 0) { j = IndexOf(v2, v, out prevChild); } if (j > 0) { d = prevChild; } else { d = null; if ((j < 0) && TraceData.IsEnabled) TraceData.Trace(TraceEventType.Error, TraceData.RefNoWrapperInChildren); } return d; } private DependencyObject FindAncestorOfType(Type type, int level, DependencyObject d, bool isTracing) { if (type == null) { if (TraceData.IsEnabled) TraceData.Trace(TraceEventType.Error, TraceData.RefAncestorTypeNotSpecified); return null; } if (level < 1) { if (TraceData.IsEnabled) TraceData.Trace(TraceEventType.Error, TraceData.RefAncestorLevelInvalid); return null; } // initialize search to start at the parent of the given DO FrameworkObject fo = new FrameworkObject(d); fo.Reset(fo.GetPreferVisualParent(true).DO); while (fo.DO != null) { if (isTracing) { TraceData.Trace(TraceEventType.Warning, TraceData.AncestorLookup( type.Name, TraceData.Identify(fo.DO))); } if (type.IsInstanceOfType(fo.DO)) // found it! { if (--level <= 0) break; } fo.Reset(fo.PreferVisualParent.DO); } return fo.DO; } private int IndexOf(Visual parent, Visual child, out Visual prevChild) { Visual temp; bool foundIndex = false; prevChild = null; int count = parent.InternalVisualChildrenCount; int i; for(i = 0; i < count; i++) { temp = parent.InternalGetVisualChild(i); if(child == temp) { foundIndex = true; break; } prevChild = temp; } if (foundIndex) return i; else return -1; } //------------------------------------------------------ // // Private Fields // //----------------------------------------------------- RelativeSource _relativeSource; } #endregion RelativeObjectRef #region ExplicitObjectRef ///Explicit object reference. internal sealed class ExplicitObjectRef: ObjectRef { //----------------------------------------------------- // // Constructors // //----------------------------------------------------- ///Constructor. internal ExplicitObjectRef(object o) { if (o is DependencyObject) _element = new WeakReference(o); else _object = o; } //------------------------------------------------------ // // Public Methods // //----------------------------------------------------- ///Returns the referenced object. /// Element defining context for the reference. /// See ObjectRefArgs internal override object GetObject(DependencyObject d, ObjectRefArgs args) { return (_element != null) ? _element.Target : _object; } ////// true if the ObjectRef uses the mentor of the target element, /// rather than the target element itself. /// protected override bool ProtectedUsesMentor { get { return false; } } internal override string Identify() { return "Source"; } //------------------------------------------------------ // // Private Fields // //------------------------------------------------------ object _object; WeakReference _element; // to DependencyObject (bug 986435) } #endregion ExplicitObjectRef } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- TextEndOfParagraph.cs
- SectionVisual.cs
- Expression.cs
- MetaForeignKeyColumn.cs
- TemplatedAdorner.cs
- TaskExtensions.cs
- Renderer.cs
- ConsoleEntryPoint.cs
- HelpProvider.cs
- ImageIndexConverter.cs
- RawStylusSystemGestureInputReport.cs
- ObjectListSelectEventArgs.cs
- IdleTimeoutMonitor.cs
- Tuple.cs
- BitmapDecoder.cs
- GB18030Encoding.cs
- ElapsedEventArgs.cs
- UTF8Encoding.cs
- AccessControlEntry.cs
- ReflectionUtil.cs
- PageBorderless.cs
- RegexFCD.cs
- PeerChannelFactory.cs
- QueryCacheManager.cs
- KeyManager.cs
- ListDictionaryInternal.cs
- EmptyCollection.cs
- ListBoxChrome.cs
- ToolboxControl.cs
- OdbcInfoMessageEvent.cs
- OleServicesContext.cs
- XPathNodeList.cs
- Executor.cs
- _IPv6Address.cs
- XmlSchemaValidationException.cs
- TextTreeNode.cs
- HtmlInputPassword.cs
- PathFigureCollectionConverter.cs
- FloaterParagraph.cs
- Line.cs
- FixedSOMGroup.cs
- SecurityContext.cs
- OleAutBinder.cs
- _SingleItemRequestCache.cs
- Query.cs
- ArgumentException.cs
- MultiBindingExpression.cs
- ListContractAdapter.cs
- XsdCachingReader.cs
- ClipboardData.cs
- TemplateEditingVerb.cs
- AuthenticationSection.cs
- EntityAdapter.cs
- BinaryConverter.cs
- XmlSequenceWriter.cs
- XmlToDatasetMap.cs
- TextCompositionManager.cs
- ComponentCommands.cs
- ResourceProviderFactory.cs
- ZipFileInfo.cs
- SchemaNamespaceManager.cs
- FacetValueContainer.cs
- CrossSiteScriptingValidation.cs
- WebEvents.cs
- BaseParaClient.cs
- XmlIgnoreAttribute.cs
- HMACSHA1.cs
- HttpCapabilitiesEvaluator.cs
- WindowsFormsHost.cs
- PrefixQName.cs
- RSAProtectedConfigurationProvider.cs
- StrongNamePublicKeyBlob.cs
- ScriptDescriptor.cs
- Registry.cs
- ResourceProviderFactory.cs
- unsafenativemethodsother.cs
- DiscreteKeyFrames.cs
- SplineKeyFrames.cs
- SqlInternalConnection.cs
- Encoder.cs
- CommandManager.cs
- DesignerVerb.cs
- SecurityPermission.cs
- QilName.cs
- UTF7Encoding.cs
- ExpressionConverter.cs
- X509ThumbprintKeyIdentifierClause.cs
- ImageCreator.cs
- ObjectListItem.cs
- ListBoxItem.cs
- ServiceDebugBehavior.cs
- AutoResetEvent.cs
- EntityContainerEntitySetDefiningQuery.cs
- GeneralTransform3D.cs
- RenderCapability.cs
- PolicyLevel.cs
- UnsafeCollabNativeMethods.cs
- TiffBitmapEncoder.cs
- MarkupWriter.cs
- EditorPartChrome.cs