Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / System / Windows / Documents / Run.cs / 1305600 / Run.cs
//---------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation. All rights reserved. // // Description: Run class - Text node in Flow content (text run) // //--------------------------------------------------------------------------- using MS.Internal; // Invariant.Assert using System.Windows.Markup; // ContentProperty using System.Windows.Controls; using MS.Internal.Documents; namespace System.Windows.Documents { ////// A terminal element in text flow hierarchy - contains a uniformatted run of unicode characters /// [ContentProperty("Text")] public class Run : Inline { //------------------------------------------------------------------- // // Constructors // //------------------------------------------------------------------- #region Constructors ////// Initializes an instance of Run class. /// public Run() { } ////// Initializes an instance of Run class specifying its text content. /// /// /// Text content assigned to the Run. /// public Run(string text) : this(text, null) { } ////// Creates a new Run instance. /// /// /// Optional text content. May be null. /// /// /// Optional position at which to insert the new Run. May /// be null. /// public Run(string text, TextPointer insertionPosition) { if (insertionPosition != null) { insertionPosition.TextContainer.BeginChange(); } try { if (insertionPosition != null) { // This will throw InvalidOperationException if schema validity is violated. insertionPosition.InsertInline(this); } if (text != null) { // No need to duplicate the string data in TextProperty here. TextContainer will // set the property to a deferred reference. this.ContentStart.InsertTextInRun(text); } } finally { if (insertionPosition != null) { insertionPosition.TextContainer.EndChange(); } } } #endregion Constructors //-------------------------------------------------------------------- // // Public Properties // //------------------------------------------------------------------- #region Public Properties ////// Dependency property backing Text. /// ////// Note that when a TextRange that intersects with this Run gets modified (e.g. by editing /// a selection in RichTextBox), we will get two changes to this property since we delete /// and then insert when setting the content of a TextRange. /// public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(Run), new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(OnTextPropertyChanged), new CoerceValueCallback(CoerceText))); ////// The content spanned by this TextElement. /// public string Text { get { return (string)GetValue(TextProperty); } set { SetValue(TextProperty, value); } } #endregion Public Properties //-------------------------------------------------------------------- // // Internal Methods // //-------------------------------------------------------------------- #region Internal Methods ////// Updates TextProperty when it is no longer in [....] with the backing store. Called by /// TextContainer when a change affects the text contained by this Run. /// ////// If a public TextChanged event is added, we need to raise the event only when the /// outermost call to this function exits. /// internal override void OnTextUpdated() { // If the value of Run.Text comes from a local value without a binding expression, we purposely allow the // redundant roundtrip property set here. (SetValue on Run.TextProperty causes a TextContainer change, // which causes this notification, and we set the property again.) We want to avoid keeping duplicate string // data (both in the property system and in the backing store) when Run.Text is set, so we replace the // original string property value with a deferred reference. This causes an extra property changed // notification, but this is better than duplicating the data. ValueSource textPropertySource = DependencyPropertyHelper.GetValueSource(this, TextProperty); if (!_isInsideDeferredSet && (_changeEventNestingCount == 0 || (textPropertySource.BaseValueSource == BaseValueSource.Local && !textPropertySource.IsExpression))) { _changeEventNestingCount++; _isInsideDeferredSet = true; try { // Use a deferred reference as a performance optimization. Most of the time, no // one will even be watching this property. SetCurrentDeferredValue(TextProperty, new DeferredRunTextReference(this)); } finally { _isInsideDeferredSet = false; _changeEventNestingCount--; } } } ////// Increments the reference count that prevents reentrancy during TextContainer changes. /// ////// Adding/removing elements from the logical tree will cause bindings on Run.Text to get /// invalidated. We don't want to indirectly cause a TextContainer change when that happens. /// internal override void BeforeLogicalTreeChange() { _changeEventNestingCount++; } ////// Decrements the reference count that prevents reentrancy during TextContainer changes. /// ////// Adding/removing elements from the logical tree will cause bindings on Run.Text to get /// invalidated. We don't want to indirectly cause a TextContainer change when that happens. /// internal override void AfterLogicalTreeChange() { _changeEventNestingCount--; } // // This property // 1. Finds the correct initial size for the _effectiveValues store on the current DependencyObject // 2. This is a performance optimization // internal override int EffectiveValuesInitialSize { get { return 13; } } ////// This method is used by TypeDescriptor to determine if this property should /// be serialized. /// [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] public bool ShouldSerializeText(XamlDesignerSerializationManager manager) { return manager != null && manager.XmlWriter == null; } #endregion Internal Methods //------------------------------------------------------------------- // // Private Methods // //-------------------------------------------------------------------- #region Private Methods ////// Changed handler for the Text property. /// /// The source of the event. /// A PropertyChangedEventArgs that contains the event data. ////// We can't assume the value is a string here -- it may be a DeferredRunTextReference. /// private static void OnTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { Run run = (Run)d; // Return if this update was caused by a TextContainer change or a reentrant change. if (run._changeEventNestingCount > 0) { return; } Invariant.Assert(!e.NewEntry.IsDeferredReference); // CoerceText will have already converted null -> String.Empty, but our default // CoerceValueCallback could be overridden by a derived class. So check again here. string newText = (string)e.NewValue; if (newText == null) { newText = String.Empty; } // Run.TextProperty has changed. Update the backing store. run._changeEventNestingCount++; try { TextContainer textContainer = run.TextContainer; textContainer.BeginChange(); try { TextPointer contentStart = run.ContentStart; if (!run.IsEmpty) { textContainer.DeleteContentInternal(contentStart, run.ContentEnd); } contentStart.InsertTextInRun(newText); } finally { textContainer.EndChange(); } } finally { run._changeEventNestingCount--; } // We need to clear undo stack if we are in a RichTextBox and the value comes from // data binding or some other expression. FlowDocument document = run.TextContainer.Parent as FlowDocument; if (document != null) { RichTextBox rtb = document.Parent as RichTextBox; if (rtb != null && run.HasExpression(run.LookupEntry(Run.TextProperty.GlobalIndex), Run.TextProperty)) { UndoManager undoManager = rtb.TextEditor._GetUndoManager(); if (undoManager != null && undoManager.IsEnabled) { undoManager.Clear(); } } } } ////// Coercion callback for the Text property. /// /// The object that the property exists on. /// The new value of the property, prior to any coercion attempt. ///The coerced value. ////// We can't assume the value is a string here -- it may be a DeferredRunTextReference. /// private static object CoerceText(DependencyObject d, object baseValue) { if (baseValue == null) { baseValue = string.Empty; } return baseValue; } #endregion Private Methods //----------------------------------------------------- // // Private Fields // //----------------------------------------------------- #region Private Fields // Number of nested TextContainer change notifications. private int _changeEventNestingCount; // If we are inside a property set caused by a backing store change. private bool _isInsideDeferredSet; #endregion Private Fields } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //---------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation. All rights reserved. // // Description: Run class - Text node in Flow content (text run) // //--------------------------------------------------------------------------- using MS.Internal; // Invariant.Assert using System.Windows.Markup; // ContentProperty using System.Windows.Controls; using MS.Internal.Documents; namespace System.Windows.Documents { ////// A terminal element in text flow hierarchy - contains a uniformatted run of unicode characters /// [ContentProperty("Text")] public class Run : Inline { //------------------------------------------------------------------- // // Constructors // //------------------------------------------------------------------- #region Constructors ////// Initializes an instance of Run class. /// public Run() { } ////// Initializes an instance of Run class specifying its text content. /// /// /// Text content assigned to the Run. /// public Run(string text) : this(text, null) { } ////// Creates a new Run instance. /// /// /// Optional text content. May be null. /// /// /// Optional position at which to insert the new Run. May /// be null. /// public Run(string text, TextPointer insertionPosition) { if (insertionPosition != null) { insertionPosition.TextContainer.BeginChange(); } try { if (insertionPosition != null) { // This will throw InvalidOperationException if schema validity is violated. insertionPosition.InsertInline(this); } if (text != null) { // No need to duplicate the string data in TextProperty here. TextContainer will // set the property to a deferred reference. this.ContentStart.InsertTextInRun(text); } } finally { if (insertionPosition != null) { insertionPosition.TextContainer.EndChange(); } } } #endregion Constructors //-------------------------------------------------------------------- // // Public Properties // //------------------------------------------------------------------- #region Public Properties ////// Dependency property backing Text. /// ////// Note that when a TextRange that intersects with this Run gets modified (e.g. by editing /// a selection in RichTextBox), we will get two changes to this property since we delete /// and then insert when setting the content of a TextRange. /// public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(Run), new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(OnTextPropertyChanged), new CoerceValueCallback(CoerceText))); ////// The content spanned by this TextElement. /// public string Text { get { return (string)GetValue(TextProperty); } set { SetValue(TextProperty, value); } } #endregion Public Properties //-------------------------------------------------------------------- // // Internal Methods // //-------------------------------------------------------------------- #region Internal Methods ////// Updates TextProperty when it is no longer in [....] with the backing store. Called by /// TextContainer when a change affects the text contained by this Run. /// ////// If a public TextChanged event is added, we need to raise the event only when the /// outermost call to this function exits. /// internal override void OnTextUpdated() { // If the value of Run.Text comes from a local value without a binding expression, we purposely allow the // redundant roundtrip property set here. (SetValue on Run.TextProperty causes a TextContainer change, // which causes this notification, and we set the property again.) We want to avoid keeping duplicate string // data (both in the property system and in the backing store) when Run.Text is set, so we replace the // original string property value with a deferred reference. This causes an extra property changed // notification, but this is better than duplicating the data. ValueSource textPropertySource = DependencyPropertyHelper.GetValueSource(this, TextProperty); if (!_isInsideDeferredSet && (_changeEventNestingCount == 0 || (textPropertySource.BaseValueSource == BaseValueSource.Local && !textPropertySource.IsExpression))) { _changeEventNestingCount++; _isInsideDeferredSet = true; try { // Use a deferred reference as a performance optimization. Most of the time, no // one will even be watching this property. SetCurrentDeferredValue(TextProperty, new DeferredRunTextReference(this)); } finally { _isInsideDeferredSet = false; _changeEventNestingCount--; } } } ////// Increments the reference count that prevents reentrancy during TextContainer changes. /// ////// Adding/removing elements from the logical tree will cause bindings on Run.Text to get /// invalidated. We don't want to indirectly cause a TextContainer change when that happens. /// internal override void BeforeLogicalTreeChange() { _changeEventNestingCount++; } ////// Decrements the reference count that prevents reentrancy during TextContainer changes. /// ////// Adding/removing elements from the logical tree will cause bindings on Run.Text to get /// invalidated. We don't want to indirectly cause a TextContainer change when that happens. /// internal override void AfterLogicalTreeChange() { _changeEventNestingCount--; } // // This property // 1. Finds the correct initial size for the _effectiveValues store on the current DependencyObject // 2. This is a performance optimization // internal override int EffectiveValuesInitialSize { get { return 13; } } ////// This method is used by TypeDescriptor to determine if this property should /// be serialized. /// [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] public bool ShouldSerializeText(XamlDesignerSerializationManager manager) { return manager != null && manager.XmlWriter == null; } #endregion Internal Methods //------------------------------------------------------------------- // // Private Methods // //-------------------------------------------------------------------- #region Private Methods ////// Changed handler for the Text property. /// /// The source of the event. /// A PropertyChangedEventArgs that contains the event data. ////// We can't assume the value is a string here -- it may be a DeferredRunTextReference. /// private static void OnTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { Run run = (Run)d; // Return if this update was caused by a TextContainer change or a reentrant change. if (run._changeEventNestingCount > 0) { return; } Invariant.Assert(!e.NewEntry.IsDeferredReference); // CoerceText will have already converted null -> String.Empty, but our default // CoerceValueCallback could be overridden by a derived class. So check again here. string newText = (string)e.NewValue; if (newText == null) { newText = String.Empty; } // Run.TextProperty has changed. Update the backing store. run._changeEventNestingCount++; try { TextContainer textContainer = run.TextContainer; textContainer.BeginChange(); try { TextPointer contentStart = run.ContentStart; if (!run.IsEmpty) { textContainer.DeleteContentInternal(contentStart, run.ContentEnd); } contentStart.InsertTextInRun(newText); } finally { textContainer.EndChange(); } } finally { run._changeEventNestingCount--; } // We need to clear undo stack if we are in a RichTextBox and the value comes from // data binding or some other expression. FlowDocument document = run.TextContainer.Parent as FlowDocument; if (document != null) { RichTextBox rtb = document.Parent as RichTextBox; if (rtb != null && run.HasExpression(run.LookupEntry(Run.TextProperty.GlobalIndex), Run.TextProperty)) { UndoManager undoManager = rtb.TextEditor._GetUndoManager(); if (undoManager != null && undoManager.IsEnabled) { undoManager.Clear(); } } } } ////// Coercion callback for the Text property. /// /// The object that the property exists on. /// The new value of the property, prior to any coercion attempt. ///The coerced value. ////// We can't assume the value is a string here -- it may be a DeferredRunTextReference. /// private static object CoerceText(DependencyObject d, object baseValue) { if (baseValue == null) { baseValue = string.Empty; } return baseValue; } #endregion Private Methods //----------------------------------------------------- // // Private Fields // //----------------------------------------------------- #region Private Fields // Number of nested TextContainer change notifications. private int _changeEventNestingCount; // If we are inside a property set caused by a backing store change. private bool _isInsideDeferredSet; #endregion Private Fields } } // 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
- AccessDataSource.cs
- WebPartCatalogAddVerb.cs
- InstanceData.cs
- ContainerParaClient.cs
- WebServiceTypeData.cs
- CodeAttributeDeclaration.cs
- Win32.cs
- formatter.cs
- LineServices.cs
- Roles.cs
- WebReferenceOptions.cs
- UniqueEventHelper.cs
- TokenFactoryFactory.cs
- InvokeGenerator.cs
- SchemaAttDef.cs
- WebPartExportVerb.cs
- documentation.cs
- BamlRecordHelper.cs
- RTLAwareMessageBox.cs
- DateTimePicker.cs
- AssemblyResolver.cs
- Random.cs
- BinaryCommonClasses.cs
- WebConfigurationHost.cs
- DictationGrammar.cs
- PolyQuadraticBezierSegmentFigureLogic.cs
- StorageAssociationSetMapping.cs
- TableColumnCollectionInternal.cs
- Touch.cs
- PrivateUnsafeNativeCompoundFileMethods.cs
- LingerOption.cs
- DataTablePropertyDescriptor.cs
- TypedDataSetSchemaImporterExtension.cs
- webbrowsersite.cs
- TraceUtility.cs
- DesignerPerfEventProvider.cs
- CapabilitiesRule.cs
- ControlPropertyNameConverter.cs
- ResourceDictionaryCollection.cs
- XsltOutput.cs
- Attributes.cs
- SqlClientFactory.cs
- dbenumerator.cs
- WebResourceUtil.cs
- SynchronizedDispatch.cs
- PartialCachingAttribute.cs
- GradientSpreadMethodValidation.cs
- XmlSchemaObjectCollection.cs
- DataServiceRequestOfT.cs
- DetailsView.cs
- WebPartConnectionsCloseVerb.cs
- MiniConstructorInfo.cs
- SHA256Managed.cs
- IPeerNeighbor.cs
- DataGridLengthConverter.cs
- DbXmlEnabledProviderManifest.cs
- DBCommandBuilder.cs
- AnimationStorage.cs
- XmlAttributeOverrides.cs
- DataGridColumnsPage.cs
- XmlSchemaSimpleTypeUnion.cs
- EnumBuilder.cs
- SmiContextFactory.cs
- ToolStripPanel.cs
- Exceptions.cs
- ServiceInstallComponent.cs
- ToolStripItemClickedEventArgs.cs
- EmptyStringExpandableObjectConverter.cs
- BStrWrapper.cs
- ReadingWritingEntityEventArgs.cs
- InvalidChannelBindingException.cs
- DataGridViewRowHeightInfoNeededEventArgs.cs
- StringExpressionSet.cs
- StylusButton.cs
- FormViewInsertEventArgs.cs
- FieldMetadata.cs
- RequestUriProcessor.cs
- EndPoint.cs
- UnconditionalPolicy.cs
- XmlSerializerAssemblyAttribute.cs
- BindingMAnagerBase.cs
- DecimalAnimation.cs
- WebReferenceOptions.cs
- SoapSchemaMember.cs
- PackageDocument.cs
- ServiceRouteHandler.cs
- ResourceWriter.cs
- CodeExpressionCollection.cs
- ImageDrawing.cs
- DataListDesigner.cs
- ExpressionEditorAttribute.cs
- FacetEnabledSchemaElement.cs
- RegexCode.cs
- WhitespaceSignificantCollectionAttribute.cs
- SafeEventLogWriteHandle.cs
- ResizeGrip.cs
- StyleHelper.cs
- DataPagerFieldCollection.cs
- LayoutTable.cs
- EmissiveMaterial.cs