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
- XpsImage.cs
- DebugView.cs
- XappLauncher.cs
- RouteItem.cs
- BitmapEffectDrawingContent.cs
- Registry.cs
- AvTraceDetails.cs
- SecureConversationVersion.cs
- DataChangedEventManager.cs
- InfoCardArgumentException.cs
- ProxyWebPartConnectionCollection.cs
- RegistryPermission.cs
- DebuggerAttributes.cs
- RuntimeWrappedException.cs
- EventRouteFactory.cs
- MetadataWorkspace.cs
- InkCanvasAutomationPeer.cs
- DiagnosticTraceSource.cs
- Semaphore.cs
- ScriptManager.cs
- CompleteWizardStep.cs
- WebPartConnectionsCancelEventArgs.cs
- BamlTreeMap.cs
- StatusBarItem.cs
- GroupQuery.cs
- DataGridViewCellStyleChangedEventArgs.cs
- EpmContentDeSerializer.cs
- GeneratedContractType.cs
- contentDescriptor.cs
- RuntimeConfigurationRecord.cs
- RuleAttributes.cs
- Binding.cs
- TemplateField.cs
- WebBrowserProgressChangedEventHandler.cs
- SpinWait.cs
- ComNativeDescriptor.cs
- Stylesheet.cs
- _SSPISessionCache.cs
- RegistryConfigurationProvider.cs
- _ProxyRegBlob.cs
- ChainOfResponsibility.cs
- IIS7WorkerRequest.cs
- ZoneButton.cs
- SchemaMerger.cs
- PageSetupDialog.cs
- BrowserInteropHelper.cs
- DataServiceConfiguration.cs
- AssemblyBuilder.cs
- NamedPermissionSet.cs
- FormViewDeleteEventArgs.cs
- DelayDesigner.cs
- PropertyIDSet.cs
- MetafileHeaderWmf.cs
- WebEventCodes.cs
- EmptyTextWriter.cs
- SamlAssertionKeyIdentifierClause.cs
- DynamicValidatorEventArgs.cs
- BamlTreeUpdater.cs
- XmlSchemaSimpleTypeRestriction.cs
- QilInvokeEarlyBound.cs
- GenericsInstances.cs
- FacetValues.cs
- MediaTimeline.cs
- StorageMappingItemLoader.cs
- BoundField.cs
- TemplateBaseAction.cs
- login.cs
- SqlInternalConnectionSmi.cs
- GradientBrush.cs
- FontNamesConverter.cs
- EntityRecordInfo.cs
- DataGridViewRowDividerDoubleClickEventArgs.cs
- WebPartPersonalization.cs
- StoreItemCollection.cs
- ParameterDataSourceExpression.cs
- QueryHandler.cs
- PartitionResolver.cs
- BamlStream.cs
- GACMembershipCondition.cs
- OperationResponse.cs
- FactoryGenerator.cs
- HandlerBase.cs
- PageBuildProvider.cs
- PartialCachingControl.cs
- BooleanAnimationBase.cs
- FontNamesConverter.cs
- Vector3DConverter.cs
- LinkedResource.cs
- SendMailErrorEventArgs.cs
- HttpProxyCredentialType.cs
- DurableInstanceContextProvider.cs
- GenericsNotImplementedException.cs
- ProviderException.cs
- MgmtResManager.cs
- ApplicationManager.cs
- ContentPlaceHolder.cs
- ExpressionQuoter.cs
- DropDownList.cs
- CompilerState.cs
- KnownTypesProvider.cs