Example #1
0
 /// <summary>
 /// Returns a TextPointer at a new position by a specified symbol
 /// count.
 /// </summary>
 /// <param name="offset">
 /// Number of symbols to advance.  offset may be negative, in which
 /// case the TextPointer is moved backwards.
 /// </param>
 /// <param name="direction">
 /// LogicalDirection desired for a returned TextPointer.
 /// </param>
 /// <returns>
 /// TextPointer located at requested position in case if requested position
 /// does exist, otherwize returns null. LogicalDirection of the TextPointer
 /// returned is as specified by a <paramref name="direction"/>.
 /// </returns>
 /// <remarks>
 /// <para>This method, like all other TextPointer methods, defines a symbol
 /// as one of:</para>
 /// <para>- 16 bit Unicode character.</para>
 /// <para>- opening or closing tag of a <see cref="TextElement"/>.</para>
 /// <para>- the whole <see cref="UIElement"/> as atomic embedded object.</para>
 /// <para>See examples in <seealso cref="TextPointer.GetPositionAtOffset(int)"/> method with one parameter.</para>
 /// </remarks>
 public TextPointer GetPositionAtOffset(int offset, LogicalDirection direction)
 {
     TextPointer position = new TextPointer(this, direction);
     int actualCount = position.MoveByOffset(offset);
     if (actualCount == offset)
     {
         position.Freeze();
         return position;
     }
     else
     {
         return null;
     }
 }
        // Notify our TextContainer that a typographic property has changed
        // value on this TextElement.
        // This has the side effect of invalidating layout.
        internal void NotifyTypographicPropertyChanged(bool affectsMeasureOrArrange, bool localValueChanged, DependencyProperty property)
        {
            if (!this.IsInTree) // No work to do if no one's listening.
            {
                return;
            }

            TextContainer tree;
            TextPointer beforeStart;

            tree = EnsureTextContainer();

            // Take note that something layout related has changed.
            tree.NextLayoutGeneration();

            // Notify any external listeners.
            if (tree.HasListeners)
            {
                // Get the position before the start of this element.
                beforeStart = new TextPointer(tree, _textElementNode, ElementEdge.BeforeStart, LogicalDirection.Forward);
                beforeStart.Freeze();

                // Raise ContentAffected event that spans entire TextElement (from BeforeStart to AfterEnd).
                tree.BeginChange();
                try
                {
                    tree.BeforeAddChange();
                    if (localValueChanged)
                    {
                        tree.AddLocalValueChange();
                    }
                    tree.AddChange(beforeStart, _textElementNode.SymbolCount, _textElementNode.IMECharCount,
                        PrecursorTextChangeType.PropertyModified, property, !affectsMeasureOrArrange);
                }
                finally
                {
                    tree.EndChange();
                }
            }
        }
Example #3
0
        /// <summary>
        /// Returns a TextPointer at the start of line after skipping
        /// a given number of line starts in forward or backward direction.
        /// </summary>
        /// <param name="count">
        /// Offset of the destination line.  Negative values specify preceding
        /// lines, zero specifies the current line, positive values specify
        /// following lines.
        /// </param>
        /// <param name="actualCount">
        /// The offset of the line moved to.  This value may be less than
        /// requested if the beginning or end of document is encountered.
        /// </param>
        /// <returns>
        /// TextPointer positioned at the begining of a line requested
        /// (with LogicalDirection set to Forward).
        /// If there is no sufficient lines in requested direction,
        /// returns a position at the beginning of a farthest line
        /// in this direction. In such case out parameter actualCount
        /// gets a number of lines actually skipped.
        /// Unlike the other override in this case the returned pointer is never null.
        /// </returns>
        /// <remarks>
        /// If this TextPointer is at an otherwise ambiguous position, exactly
        /// between two lines, the LogicalDirection property is used to determine
        /// current position.  So a TextPointer with backward LogicalDirection
        /// is considered to be at the end of line, and calling MoveToLineBoundary(0)
        /// would reposition it at the start of the preceding line.  Making the
        /// same call with forward LogicalDirection would leave the TextPointer
        /// positioned where it started -- at the start of the following line.
        /// </remarks>
        public TextPointer GetLineStartPosition(int count, out int actualCount)
        {
            this.ValidateLayout();

            TextPointer position = new TextPointer(this);

            if (this.HasValidLayout)
            {
                actualCount = position.MoveToLineBoundary(count);
            }
            else
            {
                actualCount = 0;
            }

            position.SetLogicalDirection(LogicalDirection.Forward);
            position.Freeze();

            return position;
        }