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
- AlphabetConverter.cs
- ImageMapEventArgs.cs
- MethodBody.cs
- TypedDatasetGenerator.cs
- wpf-etw.cs
- XmlReader.cs
- CollectionsUtil.cs
- StyleSheet.cs
- ColorBlend.cs
- GridViewHeaderRowPresenterAutomationPeer.cs
- ClientSponsor.cs
- Italic.cs
- SqlXml.cs
- RegionInfo.cs
- GlyphRunDrawing.cs
- AsyncCompletedEventArgs.cs
- ObjectListFieldCollection.cs
- HttpBrowserCapabilitiesWrapper.cs
- SqlMethodAttribute.cs
- SchemaContext.cs
- SqlUDTStorage.cs
- FactoryGenerator.cs
- IPPacketInformation.cs
- PanelStyle.cs
- RecordConverter.cs
- CharKeyFrameCollection.cs
- TableLayoutCellPaintEventArgs.cs
- SR.Designer.cs
- ItemsControlAutomationPeer.cs
- WindowsListViewItem.cs
- StrongName.cs
- StylusTouchDevice.cs
- altserialization.cs
- DefaultValueConverter.cs
- IncrementalHitTester.cs
- PropertyMappingExceptionEventArgs.cs
- SyndicationLink.cs
- ThreadPoolTaskScheduler.cs
- AnimationClock.cs
- RootBrowserWindowProxy.cs
- Validator.cs
- ConversionContext.cs
- _IPv4Address.cs
- HandlerBase.cs
- Encoding.cs
- ImageConverter.cs
- PropertyRecord.cs
- MarkupCompilePass1.cs
- HtmlFormWrapper.cs
- WinInet.cs
- BoolExpression.cs
- ReadOnlyPermissionSet.cs
- Ref.cs
- Compensation.cs
- SecUtil.cs
- TrackingQuery.cs
- ExplicitDiscriminatorMap.cs
- StylusPoint.cs
- SplineKeyFrames.cs
- SafeHandles.cs
- SegmentTree.cs
- XmlNamespaceManager.cs
- NaturalLanguageHyphenator.cs
- RelationshipFixer.cs
- Identity.cs
- PrincipalPermission.cs
- SimpleLine.cs
- ServiceMemoryGates.cs
- StreamUpdate.cs
- EraserBehavior.cs
- CodeComment.cs
- XmlBinaryWriter.cs
- HeaderedContentControl.cs
- WebBrowserUriTypeConverter.cs
- AspCompat.cs
- BinaryUtilClasses.cs
- SizeF.cs
- ConnectionProviderAttribute.cs
- TriState.cs
- XmlAnyAttributeAttribute.cs
- RegistryConfigurationProvider.cs
- FileInfo.cs
- IntSecurity.cs
- EntityProviderFactory.cs
- TypefaceCollection.cs
- StylusOverProperty.cs
- XmlSchemaProviderAttribute.cs
- MsmqProcessProtocolHandler.cs
- ReadWriteSpinLock.cs
- ClientFormsAuthenticationMembershipProvider.cs
- Stroke2.cs
- InputReferenceExpression.cs
- VersionedStreamOwner.cs
- RenderData.cs
- Tablet.cs
- SqlUDTStorage.cs
- DBConnection.cs
- Delay.cs
- PrintDialog.cs
- FamilyTypefaceCollection.cs