本文整理汇总了C#中System.Windows.Documents.TextPointer.SyncToTreeGeneration方法的典型用法代码示例。如果您正苦于以下问题:C# TextPointer.SyncToTreeGeneration方法的具体用法?C# TextPointer.SyncToTreeGeneration怎么用?C# TextPointer.SyncToTreeGeneration使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类System.Windows.Documents.TextPointer
的用法示例。
在下文中一共展示了TextPointer.SyncToTreeGeneration方法的10个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: InsertElementInternal
// InsertElement worker. Adds a TextElement to the tree.
// If element is already in a tree, we remove it, do a deep copy of its content,
// and insert that too.
internal void InsertElementInternal(TextPointer startPosition, TextPointer endPosition, TextElement element)
{
TextTreeTextElementNode elementNode;
int symbolOffset;
int childSymbolCount;
TextPointer startEdgePosition;
TextPointer endEdgePosition;
char[] elementText;
ExtractChangeEventArgs extractChangeEventArgs;
DependencyObject parentLogicalNode;
bool newElementNode;
int deltaCharCount;
Invariant.Assert(!this.PlainTextOnly);
Invariant.Assert(startPosition.TextContainer == this);
Invariant.Assert(endPosition.TextContainer == this);
DemandCreateText();
startPosition.SyncToTreeGeneration();
endPosition.SyncToTreeGeneration();
bool scopesExistingContent = startPosition.CompareTo(endPosition) != 0;
BeforeAddChange();
// Remove element from any previous tree.
// When called from a public method we already checked all the
// illegal cases in CanInsertElementInternal.
if (element.TextElementNode != null)
{
// This element is already in a tree. Remove it!
bool sameTextContainer = (this == element.TextContainer);
if (!sameTextContainer)
{
// This is a cross-tree extract.
// We need to start a change block now, so that we can
// raise a Changing event inside ExtractElementInternal
// before raising the LogicalTree events below.
// We'll make an EndChange call to wrap up below.
element.TextContainer.BeginChange();
}
bool exceptionThrown = true;
try
{
// ExtractElementInternal will raise LogicalTree events which
// could raise exceptions from external code.
elementText = element.TextContainer.ExtractElementInternal(element, true /* deep */, out extractChangeEventArgs);
exceptionThrown = false;
}
finally
{
if (exceptionThrown && !sameTextContainer)
{
// If an exception is thrown, make sure we close the
// change block we opened above before unwinding.
element.TextContainer.EndChange();
}
}
elementNode = element.TextElementNode;
deltaCharCount = extractChangeEventArgs.ChildIMECharCount;
if (sameTextContainer)
{
// Re-[....] the TextPointers in case we just extracted from this tree.
startPosition.SyncToTreeGeneration();
endPosition.SyncToTreeGeneration();
// We must add the extract change now, before we move on to the insert.
// (When !sameTextContainer we want to delay the notification in the extract
// tree until the insert tree is in an accessible state, ie at the end of this method.)
extractChangeEventArgs.AddChange();
// Don't re-raise the change below.
extractChangeEventArgs = null;
}
newElementNode = false;
}
else
{
// Allocate a node in the tree to hold the element.
elementText = null;
elementNode = new TextTreeTextElementNode();
deltaCharCount = 0;
newElementNode = true;
extractChangeEventArgs = null;
}
parentLogicalNode = startPosition.GetLogicalTreeNode();
// Invalidate any TextElementCollection that depends on the parent.
// Make sure we do that before raising any public events.
//.........这里部分代码省略.........
示例2: ValidateSetValue
// Validation for SetValue.
private void ValidateSetValue(TextPointer position)
{
TextElement element;
if (position.TextContainer != this)
{
throw new InvalidOperationException(SR.Get(SRID.NotInThisTree, "position"));
}
position.SyncToTreeGeneration();
element = position.Parent as TextElement;
if (element == null)
{
throw new InvalidOperationException(SR.Get(SRID.NoElement));
}
}
示例3: InsertTextInternal
// The InsertText worker. Adds text to the tree at a specified position.
// text is either a string or char[] to insert.
internal void InsertTextInternal(TextPointer position, object text)
{
TextTreeTextNode textNode;
SplayTreeNode containingNode;
TextPointer originalPosition;
int symbolOffset;
int textLength;
LogicalDirection direction;
Invariant.Assert(text is string || text is char[], "Unexpected type for 'text' parameter!");
textLength = GetTextLength(text);
if (textLength == 0)
return;
DemandCreateText();
position.SyncToTreeGeneration();
if (Invariant.Strict)
{
if (position.Node.SymbolCount == 0)
{
// We expect only TextTreeTextNodes ever have zero symbol counts.
// This can happen in two cases:
//
// <TextNode referencedEdge=BeforeStart symbolCount=1+/> <TextNode referencedEdge=AfterEnd symbolCount=0/>
// or
// <TextNode referencedEdge=BeforeStart symbolCount=0/> <TextNode referencedEdge=AfterEnd symbolCount=1+/>
//
Invariant.Assert(position.Node is TextTreeTextNode);
Invariant.Assert((position.Edge == ElementEdge.AfterEnd && position.Node.GetPreviousNode() is TextTreeTextNode && position.Node.GetPreviousNode().SymbolCount > 0) ||
(position.Edge == ElementEdge.BeforeStart && position.Node.GetNextNode() is TextTreeTextNode && position.Node.GetNextNode().SymbolCount > 0));
}
}
BeforeAddChange();
// During document load we won't have listeners and we can save
// an allocation on every insert. This can easily save 1000's of allocations during boot.
originalPosition = this.HasListeners ? new TextPointer(position, LogicalDirection.Backward) : null;
// Find a bordering TextTreeTextNode, if any.
// We know position already points to the current TextNode, if there is one, so
// we can't append text to that node (it would disrespect position's gravity to do so).
// So we either have to find a neighboring text node with no position references, or
// create a new node.
// Look for a bordering text node.
if (position.Edge == ElementEdge.BeforeStart || position.Edge == ElementEdge.BeforeEnd)
{
direction = LogicalDirection.Backward;
}
else
{
direction = LogicalDirection.Forward;
}
textNode = position.GetAdjacentTextNodeSibling(direction);
if (textNode != null)
{
// We can't use a text node that is already referred to by text positions.
// Doing so could displace the positions, since they expect to remain at
// the node edge no matter what happens.
if ((direction == LogicalDirection.Backward && textNode.AfterEndReferenceCount) ||
(direction == LogicalDirection.Forward && textNode.BeforeStartReferenceCount))
{
textNode = null;
}
}
if (textNode == null)
{
// No text node available. Create and insert one.
textNode = new TextTreeTextNode();
textNode.InsertAtPosition(position);
containingNode = textNode.GetContainingNode();
}
else
{
// We didn't insert a new node, so splay textNode to the root so
// we don't invalidate any LeftSymbolCounts of ancestor nodes.
textNode.Splay();
containingNode = textNode.ParentNode;
}
// Update the symbol counts.
textNode.SymbolCount += textLength; // This simultaneously updates textNode.IMECharCount.
UpdateContainerSymbolCount(containingNode, /* symbolCount */ textLength, /* charCount */ textLength);
// Insert the raw text.
symbolOffset = textNode.GetSymbolOffset(this.Generation);
TextTreeText.InsertText(_rootNode.RootTextBlock, symbolOffset, text);
// Handle undo.
TextTreeUndo.CreateInsertUndoUnit(this, symbolOffset, textLength);
//.........这里部分代码省略.........
示例4: DeleteContentInternal
// DeleteContent worker. Removes content from the tree.
internal void DeleteContentInternal(TextPointer startPosition, TextPointer endPosition)
{
TextTreeNode containingNode;
int symbolCount;
int charCount;
TextTreeUndoUnit undoUnit;
TextPointer deletePosition;
startPosition.SyncToTreeGeneration();
endPosition.SyncToTreeGeneration();
if (startPosition.CompareTo(endPosition) == 0)
return;
BeforeAddChange();
undoUnit = TextTreeUndo.CreateDeleteContentUndoUnit(this, startPosition, endPosition);
containingNode = startPosition.GetScopingNode();
// Invalidate any TextElementCollection that depends on the parent.
// Make sure we do that before raising any public events.
TextElementCollectionHelper.MarkDirty(containingNode.GetLogicalTreeNode());
int nextIMEVisibleNodeCharDelta = 0;
TextTreeTextElementNode nextIMEVisibleNode = GetNextIMEVisibleNode(startPosition, endPosition);
if (nextIMEVisibleNode != null)
{
// The node following the delete just became the first sibling.
// This might affect its ime char count.
nextIMEVisibleNodeCharDelta = -nextIMEVisibleNode.IMELeftEdgeCharCount;
nextIMEVisibleNode.IMECharCount += nextIMEVisibleNodeCharDelta;
}
// First cut: remove all top-level TextElements and their chilren.
// We need to put each TextElement in its own tree, so that any outside
// references can still play with the TextElements safely.
symbolCount = CutTopLevelLogicalNodes(containingNode, startPosition, endPosition, out charCount);
// Cut what's left.
int remainingCharCount;
symbolCount += DeleteContentFromSiblingTree(containingNode, startPosition, endPosition, nextIMEVisibleNodeCharDelta != 0, out remainingCharCount);
charCount += remainingCharCount;
Invariant.Assert(symbolCount > 0);
if (undoUnit != null)
{
undoUnit.SetTreeHashCode();
}
// Public tree event.
deletePosition = new TextPointer(startPosition, LogicalDirection.Forward);
AddChange(deletePosition, symbolCount, charCount, PrecursorTextChangeType.ContentRemoved);
if (nextIMEVisibleNodeCharDelta != 0)
{
RaiseEventForNewFirstIMEVisibleNode(nextIMEVisibleNode);
}
}
示例5: CutTopLevelLogicalNodes
// Does a deep extract of all top-level TextElements between two positions.
// Returns the combined symbol count of all extracted elements.
// Each extracted element (and its children) are moved into a private tree.
// This insures that outside references to the TextElement can still use
// the TextElements freely, inserting or removing content, etc.
//
// Also calls AddLogicalChild on any top-level UIElements encountered.
private int CutTopLevelLogicalNodes(TextTreeNode containingNode, TextPointer startPosition, TextPointer endPosition, out int charCount)
{
SplayTreeNode node;
SplayTreeNode nextNode;
SplayTreeNode stopNode;
TextTreeTextElementNode elementNode;
TextTreeObjectNode uiElementNode;
char[] elementText;
int symbolCount;
TextContainer tree;
TextPointer newTreeStart;
DependencyObject logicalParent;
object currentLogicalChild;
Invariant.Assert(startPosition.GetScopingNode() == endPosition.GetScopingNode(), "startPosition/endPosition not in same sibling tree!");
node = startPosition.GetAdjacentSiblingNode(LogicalDirection.Forward);
stopNode = endPosition.GetAdjacentSiblingNode(LogicalDirection.Forward);
symbolCount = 0;
charCount = 0;
logicalParent = containingNode.GetLogicalTreeNode();
while (node != stopNode)
{
currentLogicalChild = null;
// Get the next node now, before we extract any TextElementNodes.
nextNode = node.GetNextNode();
elementNode = node as TextTreeTextElementNode;
if (elementNode != null)
{
// Grab the IMECharCount before we modify the node.
// This value depends on the node's current context.
int imeCharCountInOriginalContainer = elementNode.IMECharCount;
// Cut and record the matching symbols.
elementText = TextTreeText.CutText(_rootNode.RootTextBlock, elementNode.GetSymbolOffset(this.Generation), elementNode.SymbolCount);
// Rip the element out of its sibling tree.
// textElementNode.TextElement's TextElementNode will be updated
// with a deep copy of all contained nodes. We need a deep copy
// to ensure the new element/tree has no TextPointer references.
ExtractElementFromSiblingTree(containingNode, elementNode, true /* deep */);
// Assert that the TextElement now points to a new TextElementNode, not the original one.
Invariant.Assert(elementNode.TextElement.TextElementNode != elementNode);
// We want to start referring to the copied node, update elementNode.
elementNode = elementNode.TextElement.TextElementNode;
UpdateContainerSymbolCount(containingNode, -elementNode.SymbolCount, -imeCharCountInOriginalContainer);
NextGeneration(true /* deletedContent */);
// Stick it in a private tree so it's safe for the outside world to play with.
tree = new TextContainer(null, false /* plainTextOnly */);
newTreeStart = tree.Start;
tree.InsertElementToSiblingTree(newTreeStart, newTreeStart, elementNode);
Invariant.Assert(elementText.Length == elementNode.SymbolCount);
tree.UpdateContainerSymbolCount(elementNode.GetContainingNode(), elementNode.SymbolCount, elementNode.IMECharCount);
tree.DemandCreateText();
TextTreeText.InsertText(tree.RootTextBlock, 1 /* symbolOffset */, elementText);
tree.NextGeneration(false /* deletedContent */);
currentLogicalChild = elementNode.TextElement;
// Keep a running total of how many symbols we've removed.
symbolCount += elementNode.SymbolCount;
charCount += imeCharCountInOriginalContainer;
}
else
{
uiElementNode = node as TextTreeObjectNode;
if (uiElementNode != null)
{
currentLogicalChild = uiElementNode.EmbeddedElement;
}
}
// Remove the child from the logical tree
LogicalTreeHelper.RemoveLogicalChild(logicalParent, currentLogicalChild);
node = nextNode;
}
if (symbolCount > 0)
{
startPosition.SyncToTreeGeneration();
endPosition.SyncToTreeGeneration();
}
return symbolCount;
//.........这里部分代码省略.........
示例6: InsertEmbeddedObjectInternal
// InsertEmbeddedObject worker. Adds a UIElement to the tree.
internal void InsertEmbeddedObjectInternal(TextPointer position, DependencyObject embeddedObject)
{
TextTreeNode objectNode;
int symbolOffset;
DependencyObject parentLogicalNode;
TextPointer insertPosition;
Invariant.Assert(!this.PlainTextOnly);
DemandCreateText();
position.SyncToTreeGeneration();
BeforeAddChange();
parentLogicalNode = position.GetLogicalTreeNode();
// Insert a node.
objectNode = new TextTreeObjectNode(embeddedObject);
objectNode.InsertAtPosition(position);
// Update the symbol count.
UpdateContainerSymbolCount(objectNode.GetContainingNode(), objectNode.SymbolCount, objectNode.IMECharCount);
// Insert the corresponding text.
symbolOffset = objectNode.GetSymbolOffset(this.Generation);
TextTreeText.InsertObject(_rootNode.RootTextBlock, symbolOffset);
NextGeneration(false /* deletedContent */);
// Handle undo.
TextTreeUndo.CreateInsertUndoUnit(this, symbolOffset, 1);
// Tell parent to update Logical Tree
LogicalTreeHelper.AddLogicalChild(parentLogicalNode, embeddedObject);
// Raise the public event.
// During document load we won't have listeners and we can save
// an allocation on every insert. This can easily save 1000's of allocations during boot.
if (this.HasListeners)
{
insertPosition = new TextPointer(this, objectNode, ElementEdge.BeforeStart);
AddChange(insertPosition, 1, 1, PrecursorTextChangeType.ContentAdded);
}
}
示例7: GetOffsetToPosition
/// <summary>
/// Returns the distance between this TextPointer and another.
/// </summary>
/// <param name="position">
/// TextPointer to compare.
/// </param>
/// <exception cref="System.ArgumentException">
/// Throws an ArgumentException if the TextPointer position is not
/// positioned within the same document as this TextPointer.
/// </exception>
/// <returns>
/// <para>The return value will be negative if the TextPointer position
/// preceeds this TextPointer, zero if the two TextPointers
/// are equally positioned, or positive if position follows this
/// TextPointer.</para>
/// </returns>
/// <remarks>
/// <para>The distance is represented as a number of "symbols"
/// between these two pointers.</para>
/// <para>Each opening and each closing tag of any TextElement
/// is considered as one symbol. So an empty TextElement contributes
/// two symbols - one for each of tags.</para>
/// <para>UIElement placed within InlineUIContainer or BlockUIContainer
/// represented as one symbol - independently of how complex
/// is its content. Even if the UIElement contains or is a
/// text container it is treated as atomic entity - single symbol.
/// This may be confusing especially if you do not pay
/// muchy attention to a difference between the <see cref="TextElement"/>
/// the <see cref="UIElement"/> class.</para>
/// <para>Each 16-bit unicode character inside a <see cref="Run"/> element
/// is considered as one symbol.</para>
/// <para>For instance, for the following xaml:
/// <Run>abc</Run><InlineUIContainer><Button>OK</Button></InlineUIContainer>
/// the offset from itw content start to content end will be 8 -
/// one for each of: (1) Run start, (2) "a", (3) "b", (4) "c", (5) Run end, (6) InlineUIContainer start,
/// (7) whole Button element, (8) InlineUIContainer end. Note that <c>Button</c>
/// element considered as one symbol even though it is represented
/// by two tags and two characters.</para>
/// </remarks>
/// <example>
/// <para>In this example we show how to use TextPointer offsets for
/// persisting positional information. Assuming that the content of
/// a RichTextBox is not changed between calls of
/// GetPersistedSelection and RestoreSelectionFromPersistedRange
/// methods, the selection will be restored to its original state.</para>
/// <code>
/// struct PersistedTextRange { int Start; int End; }
///
/// PersistedTextRange GetPersistedSelection(RichTextBox richTextBox)
/// {
/// PersistedTextRange persistedSelection;
///
/// TextPointer contentStart = richTextBox.Document.ContentStart;
/// persistedSelection.Start = contentStart.GetOffsetToPosition(richTextBox.Selection.Start);
/// persistedSelection.End = contentStart.GetOffsetToPosition(richTextBox.Selection.End);
///
/// return persistedSelection;
/// }
///
/// RestoreSelectionFromPersistedRange(RichTextBox richTextBox, PersistedTextRange persistedRange)
/// {
/// TextPointer contentStart = richTextBox.Document.ContentStart;
///
/// richTextBox.Selection.Select(
/// contentStart.GetPositionAtOffset(persistedRange.Start),
/// contentStart.GetPositionAtOffset(persistedRange.End));
/// }
///
/// </code>
/// </example>
public int GetOffsetToPosition(TextPointer position)
{
_tree.EmptyDeadPositionList();
ValidationHelper.VerifyPosition(_tree, position);
SyncToTreeGeneration();
position.SyncToTreeGeneration();
return (position.GetSymbolOffset() - GetSymbolOffset());
}
示例8: CompareTo
/// <summary>
/// Compares positions of this TextPointer with another TextPointer.
/// </summary>
/// <param name="position">
/// The TextPointer to compare with.
/// </param>
/// <returns>
/// Less than zero: this TextPointer preceeds position.
/// Zero: this TextPointer is at the same location as position.
/// Greater than zero: this TextPointer follows position.
/// </returns>
/// <exception cref="System.ArgumentException">
/// Throws ArgumentException if position does not belong to the same
/// text container as this TextPointer (you can use <see cref="TextPointer.IsInSameDocument"/>
/// method to detect whether comparison is possible).
/// </exception>
public int CompareTo(TextPointer position)
{
int offsetThis;
int offsetPosition;
int result;
_tree.EmptyDeadPositionList();
ValidationHelper.VerifyPosition(_tree, position);
SyncToTreeGeneration();
position.SyncToTreeGeneration();
offsetThis = GetSymbolOffset();
offsetPosition = position.GetSymbolOffset();
if (offsetThis < offsetPosition)
{
result = -1;
}
else if (offsetThis > offsetPosition)
{
result = +1;
}
else
{
result = 0;
}
return result;
}
示例9: InitializeOffset
//------------------------------------------------------
//
// Private Methods
//
//------------------------------------------------------
#region Private Methods
// Called by the TextPointer ctor. Initializes this instance.
private void InitializeOffset(TextPointer position, int distance, LogicalDirection direction)
{
SplayTreeNode node;
ElementEdge edge;
int offset;
bool isCaretUnitBoundaryCacheValid;
// We MUST [....] to the current tree, otherwise we could addref
// an orphaned node, resulting in a future unmatched release...
// Ref counts on orphaned nodes are only considered at the time
// of removal, not afterwards.
position.SyncToTreeGeneration();
if (distance != 0)
{
offset = position.GetSymbolOffset() + distance;
if (offset < 1 || offset > position.TextContainer.InternalSymbolCount - 1)
{
throw new ArgumentException(SR.Get(SRID.BadDistance));
}
position.TextContainer.GetNodeAndEdgeAtOffset(offset, out node, out edge);
isCaretUnitBoundaryCacheValid = false;
}
else
{
node = position.Node;
edge = position.Edge;
isCaretUnitBoundaryCacheValid = position.IsCaretUnitBoundaryCacheValid;
}
Initialize(position.TextContainer, (TextTreeNode)node, edge, direction, position.TextContainer.PositionGeneration,
position.CaretUnitBoundaryCache, isCaretUnitBoundaryCacheValid, position._layoutGeneration);
}
示例10: MoveToPosition
/// <summary>
/// Moves this TextPointer to another TextPointer's position.
/// </summary>
/// <param name="textPosition">
/// Position to move to.
/// </param>
/// <exception cref="System.ArgumentException">
/// Throws an ArgumentException if textPosition is not
/// positioned within the same document.
/// </exception>
/// <exception cref="System.InvalidOperationException">
/// Throws an InvalidOperationException if this TextPointer's IsFrozen
/// property is set true. Frozen TextPointers may not be repositioned.
/// </exception>
internal void MoveToPosition(TextPointer textPosition)
{
ValidationHelper.VerifyPosition(_tree, textPosition);
VerifyNotFrozen();
_tree.EmptyDeadPositionList();
SyncToTreeGeneration();
textPosition.SyncToTreeGeneration();
MoveToNode(_tree, textPosition.Node, textPosition.Edge);
}