Obtain Mixed Text Attribute Details Using UI Automation

Note

This documentation is intended for .NET Framework developers who want to use the managed UI Automation classes defined in the System.Windows.Automation namespace. For the latest information about UI Automation, see Windows Automation API: UI Automation.

This topic shows how to use Microsoft UI Automation to obtain text attribute details from a text range that spans multiple attribute values. A text range can correspond to the current location of the caret (or degenerate selection) within a document, a contiguous selection of text, a collection of disjoint text selections, or the entire textual content of a document.

Example

The following code example demonstrates how to obtain the FontNameAttribute from a text range where GetAttributeValue returns a MixedAttributeValue object.

///--------------------------------------------------------------------
/// <summary>
/// Display the target selection with attribute details in client.
/// </summary>
/// <param name="selectedText">The current target selection.</param>
///--------------------------------------------------------------------
private void DisplaySelectedTextWithAttributes(string selectedText)
{
    targetSelection.Text = selectedText;
    // We're only interested in the FontNameAttribute for the purposes
    // of this sample.
    targetSelectionAttributes.Text =
        ParseTextRangeByAttribute(
        selectedText, TextPattern.FontNameAttribute);
}

///--------------------------------------------------------------------
/// <summary>
/// Parse the target selection based on the text attribute of interest.
/// </summary>
/// <param name="selectedText">The current target selection.</param>
/// <param name="automationTextAttribute">
/// The text attribute of interest.
/// </param>
/// <returns>
/// A string representing the requested attribute details.
/// </returns>
///--------------------------------------------------------------------
private string ParseTextRangeByAttribute(
    string selectedText,
    AutomationTextAttribute automationTextAttribute)
{
    StringBuilder attributeDetails = new StringBuilder();
    // Initialize the current attribute value.
    string attributeValue = "";
    // Make a copy of the text range.
    TextPatternRange searchRangeClone = searchRange.Clone();
    // Collapse the range to the starting endpoint.
    searchRangeClone.Move(TextUnit.Character, -1);
    // Iterate through the range character by character.
    for (int x = 1; x <= selectedText.Length; x++)
    {
        searchRangeClone.Move(TextUnit.Character, 1);
        // Get the attribute value of the current character.
        string newAttributeValue =
            searchRangeClone.GetAttributeValue(automationTextAttribute).ToString();
        // If the new attribute value is not equal to the old then report
        // the new value along with its location within the range.
        if (newAttributeValue != attributeValue)
        {
            attributeDetails.Append(automationTextAttribute.ProgrammaticName)
                .Append(":\n<")
                .Append(newAttributeValue)
                .Append("> at text range position ")
                .AppendLine(x.ToString());
            attributeValue = newAttributeValue;
        }
    }
    return attributeDetails.ToString();
}
'--------------------------------------------------------------------
' Display the target selection with attribute details in client.
' <param name="selectedText">The current target selection.</param>
'--------------------------------------------------------------------
Private Sub DisplaySelectedTextWithAttributes(ByVal selectedText As String)
    targetSelection.Text = selectedText
    ' We're only interested in the FontNameAttribute for the purposes
    ' of this sample.
    targetSelectionAttributes.Text = _
        ParseTextRangeByAttribute( _
        selectedText, TextPattern.FontNameAttribute)
End Sub

'--------------------------------------------------------------------
' Parse the target selection based on the text attribute of interest.
' <param name="selectedText">The current target selection.</param>
' <param name="automationTextAttribute">
' The text attribute of interest.
' A string representing the requested attribute details.
'--------------------------------------------------------------------
Function ParseTextRangeByAttribute( _
ByVal selectedText As String, _
ByVal automationTextAttribute As AutomationTextAttribute) As String
    Dim attributeDetails As StringBuilder = New StringBuilder()
    ' Initialize the current attribute value.
    Dim attributeValue As String = ""
    ' Make a copy of the text range.
    Dim searchRangeClone As TextPatternRange = searchRange.Clone()
    ' Collapse the range to the starting endpoint.
    searchRangeClone.Move(TextUnit.Character, -1)
    ' Iterate through the range character by character.
    Dim x As Integer
    For x = 1 To selectedText.Length
        searchRangeClone.Move(TextUnit.Character, 1)
        ' Get the attribute value of the current character.
        Dim newAttributeValue As String = _
            searchRangeClone.GetAttributeValue(automationTextAttribute).ToString()
        ' If the new attribute value is not equal to the old then report
        ' the new value along with its location within the range.
        If (newAttributeValue <> attributeValue) Then
            attributeDetails.Append(automationTextAttribute.ProgrammaticName) _
            .Append(":") _
            .Append(vbLf) _
            .Append("<") _
            .Append(newAttributeValue) _
            .Append("> at text range position ") _
            .AppendLine(x.ToString())
            attributeValue = newAttributeValue
        End If
    Next
    Return attributeDetails.ToString()
End Function

The TextPattern control pattern, in tandem with the TextPatternRange class, supports basic text attributes, properties, and methods. For control-specific functionality that is not supported by TextPattern or TextPatternRange, the AutomationElement class provides methods for a UI Automation client to access the corresponding native object model.

See also