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
- CodeMethodInvokeExpression.cs
- PageParserFilter.cs
- PageBreakRecord.cs
- FormsAuthenticationTicket.cs
- DependencyPropertyChangedEventArgs.cs
- SerializationAttributes.cs
- DeferredBinaryDeserializerExtension.cs
- VectorAnimation.cs
- UnionCqlBlock.cs
- Cloud.cs
- XDRSchema.cs
- WebPartTracker.cs
- ZipIOExtraFieldZip64Element.cs
- AnimatedTypeHelpers.cs
- PerformanceCounterLib.cs
- SqlXmlStorage.cs
- Knowncolors.cs
- ResourceLoader.cs
- PtsPage.cs
- OrthographicCamera.cs
- Lease.cs
- ConfigurationValues.cs
- MaskDescriptor.cs
- Utils.cs
- DataGridViewCellCancelEventArgs.cs
- JavaScriptSerializer.cs
- StringValueSerializer.cs
- IPeerNeighbor.cs
- NetMsmqBinding.cs
- ClientCultureInfo.cs
- DataSourceExpressionCollection.cs
- Speller.cs
- RelationshipEntry.cs
- Registry.cs
- CodeAttributeArgument.cs
- LocalBuilder.cs
- oledbconnectionstring.cs
- UnwrappedTypesXmlSerializerManager.cs
- Symbol.cs
- DbConnectionFactory.cs
- DoubleIndependentAnimationStorage.cs
- SymbolMethod.cs
- PropertyNames.cs
- DependsOnAttribute.cs
- TargetFrameworkAttribute.cs
- DetailsViewPagerRow.cs
- ScaleTransform3D.cs
- MexNamedPipeBindingCollectionElement.cs
- SamlNameIdentifierClaimResource.cs
- PersonalizableTypeEntry.cs
- DaylightTime.cs
- Popup.cs
- ProgressBarRenderer.cs
- ZoneButton.cs
- IxmlLineInfo.cs
- mactripleDES.cs
- WorkflowServiceBehavior.cs
- ApplicationProxyInternal.cs
- TransportConfigurationTypeElement.cs
- WorkflowRuntimeServicesBehavior.cs
- RealizationContext.cs
- StickyNoteContentControl.cs
- CellRelation.cs
- ToolStripDropDown.cs
- Parser.cs
- ReceiveMessageRecord.cs
- ResXDataNode.cs
- DropShadowEffect.cs
- InfiniteIntConverter.cs
- ParserContext.cs
- FilterRepeater.cs
- GuidelineCollection.cs
- BoundsDrawingContextWalker.cs
- Annotation.cs
- AuthorizationRuleCollection.cs
- DataGridViewCellCollection.cs
- CapabilitiesUse.cs
- Pair.cs
- WebConfigurationManager.cs
- RegistrySecurity.cs
- UpDownEvent.cs
- AuthenticationSection.cs
- HttpListenerContext.cs
- SecurityStateEncoder.cs
- TypeLibConverter.cs
- IntegerValidatorAttribute.cs
- IpcPort.cs
- GestureRecognitionResult.cs
- NetworkInterface.cs
- ParserContext.cs
- MenuAutomationPeer.cs
- VectorAnimationBase.cs
- XPathScanner.cs
- ErrorInfoXmlDocument.cs
- _SingleItemRequestCache.cs
- D3DImage.cs
- TypeBuilderInstantiation.cs
- BitmapEffectGroup.cs
- ListBoxItemAutomationPeer.cs
- WSHttpSecurity.cs