UI 자동화를 사용하여 표의 콘텐츠 노출

참고 항목

이 설명서는 System.Windows.Automation 네임스페이스에 정의된 관리되는 UI 자동화 클래스를 사용하려는 .NET Framework 개발자를 위한 것입니다. UI 자동화에 대한 최신 정보는 Windows 자동화 API: UI 자동화를 참조하세요.

이 항목에서는 Microsoft UI 자동화를 사용하여 테이블 형식 컨트롤 내에서 각 셀의 콘텐츠 및 내장 속성을 노출하는 방법을 보여 줍니다.

예시

다음 코드 예제에서는 테이블 셀의 콘텐츠를 나타내는 AutomationElement를 가져오는 방법을 보여 줍니다. 행 및 열 인덱스, 행 및 열 범위, 행 및 열 머리글 정보 등의 셀 속성도 가져옵니다. 이 예제에서는 포커스 변경 이벤트 처리기를 사용하여 UI 자동화를 구현하는 테이블 형식 컨트롤의 키보드 이동을 시뮬레이트합니다. 각 테이블 항목에 대한 정보는 포커스 변경 이벤트에 노출됩니다.

참고 항목

포커스 변경은 전역 데스크톱 이벤트이므로 테이블 외부의 포커스 변경 이벤트를 필터링해야 합니다. 관련 구현은 TrackFocus 샘플을 참조하세요.

/// -------------------------------------------------------------------
/// <summary>
/// Starts the target application and returns the AutomationElement
/// obtained from the targets window handle.
/// </summary>
/// <param name="exe">
/// The target application.
/// </param>
/// <param name="filename">
/// The text file to be opened in the target application
/// </param>
/// <returns>
/// An AutomationElement representing the target application.
/// </returns>
/// -------------------------------------------------------------------
private AutomationElement StartTarget(string exe, string filename)
{
    // Start text editor and load with a text file.
    Process p = Process.Start(exe, filename);

    // targetApp --> the root AutomationElement
    AutomationElement targetApp =
        AutomationElement.FromHandle(p.MainWindowHandle);

    return targetApp;
}
''' -------------------------------------------------------------------
''' <summary>
''' Starts the target application and returns the AutomationElement 
''' obtained from the targets window handle.
''' </summary>
''' <param name="exe">
''' The target application.
''' </param>
''' <param name="filename">
''' The text file to be opened in the target application
''' </param>
''' <returns>
''' An AutomationElement representing the target application.
''' </returns>
''' -------------------------------------------------------------------
Private Function StartTarget(ByVal exe As String, ByVal filename As String) As AutomationElement
    ' Start text editor and load with a text file.
    Dim p As Process = Process.Start(exe, filename)

    ' targetApp --> the root AutomationElement
    Dim targetApp As AutomationElement = _
    AutomationElement.FromHandle(p.MainWindowHandle)

    Return targetApp
End Function
/// -------------------------------------------------------------------
/// <summary>
/// Obtain the table control of interest from the target application.
/// </summary>
/// <param name="targetApp">
/// The target application.
/// </param>
/// <returns>
/// An AutomationElement representing a table control.
/// </returns>
/// -------------------------------------------------------------------
private AutomationElement GetTableElement(AutomationElement targetApp)
{
    // The control type we're looking for; in this case 'Document'
    PropertyCondition cond1 =
        new PropertyCondition(
        AutomationElement.ControlTypeProperty,
        ControlType.Table);

    // The control pattern of interest; in this case 'TextPattern'.
    PropertyCondition cond2 =
        new PropertyCondition(
        AutomationElement.IsTablePatternAvailableProperty,
        true);

    AndCondition tableCondition = new AndCondition(cond1, cond2);

    AutomationElement targetTableElement =
        targetApp.FindFirst(TreeScope.Descendants, tableCondition);

    // If targetTableElement is null then a suitable table control
    // was not found.
    return targetTableElement;
}
''' -------------------------------------------------------------------
''' <summary>
''' Obtain the table control of interest from the target application.
''' </summary>
''' <param name="targetApp">
''' The target application.
''' </param>
''' <returns>
''' An AutomationElement representing a table control.
''' </returns>
''' -------------------------------------------------------------------
Private Function GetTableElement(ByVal targetApp As AutomationElement) As AutomationElement
    ' The control type we're looking for; in this case 'Document'
    Dim cond1 As PropertyCondition = _
        New PropertyCondition( _
        AutomationElement.ControlTypeProperty, _
        ControlType.Table)

    ' The control pattern of interest; in this case 'TextPattern'.
    Dim cond2 As PropertyCondition = _
        New PropertyCondition( _
        AutomationElement.IsTablePatternAvailableProperty, _
        True)

    Dim tableCondition As AndCondition = New AndCondition(cond1, cond2)

    Dim targetTableElement As AutomationElement = _
    targetApp.FindFirst(TreeScope.Descendants, tableCondition)

    ' If targetTableElement is null then a suitable table control 
    ' was not found.
    Return targetTableElement
End Function
///--------------------------------------------------------------------
/// <summary>
/// Obtains a TableItemPattern control pattern from an
/// AutomationElement.
/// </summary>
/// <param name="targetControl">
/// The AutomationElement of interest.
/// </param>
/// <returns>
/// A TableItemPattern object.
/// </returns>
///--------------------------------------------------------------------
private TableItemPattern GetTableItemPattern(
    AutomationElement targetControl)
{
    TableItemPattern tableItemPattern = null;

    try
    {
        tableItemPattern =
            targetControl.GetCurrentPattern(
            TableItemPattern.Pattern)
            as TableItemPattern;
    }
    // Object doesn't support the
    // TableItemPattern control pattern
    catch (InvalidOperationException)
    {
        return null;
    }

    return tableItemPattern;
}
'''--------------------------------------------------------------------
''' <summary>
''' Obtains a TableItemPattern control pattern from an 
''' AutomationElement.
''' </summary>
''' <param name="targetControl">
''' The AutomationElement of interest.
''' </param>
''' <returns>
''' A TableItemPattern object.
''' </returns>
'''--------------------------------------------------------------------
Private Function GetTableItemPattern( _
ByVal targetControl As AutomationElement) As TableItemPattern
    Dim tableItemPattern As TableItemPattern = Nothing

    Try
        tableItemPattern = DirectCast( _
        targetControl.GetCurrentPattern(tableItemPattern.Pattern), TableItemPattern)
    Catch exc As InvalidOperationException
        ' Object doesn't support the 
        ' GridPattern control pattern
        Return Nothing
    End Try

    Return tableItemPattern

End Function 'GetTableItemPattern    
///--------------------------------------------------------------------
/// <summary>
/// Obtains a TablePattern control pattern from an
/// AutomationElement.
/// </summary>
/// <param name="targetControl">
/// The AutomationElement of interest.
/// </param>
/// <returns>
/// A TablePattern object.
/// </returns>
///--------------------------------------------------------------------
private TablePattern GetTablePattern(
    AutomationElement targetControl)
{
    TablePattern tablePattern = null;

    try
    {
        tablePattern =
            targetControl.GetCurrentPattern(
            TablePattern.Pattern)
            as TablePattern;
    }
    // Object doesn't support the
    // TablePattern control pattern
    catch (InvalidOperationException)
    {
        return null;
    }

    return tablePattern;
}
'''--------------------------------------------------------------------
''' <summary>
''' Obtains a TablePattern control pattern from an 
''' AutomationElement.
''' </summary>
''' <param name="targetControl">
''' The AutomationElement of interest.
''' </param>
''' <returns>
''' A TablePattern object.
''' </returns>
'''--------------------------------------------------------------------
Private Function GetTablePattern( _
ByVal targetControl As AutomationElement) As TablePattern
    Dim tablePattern As TablePattern = Nothing

    Try
        tablePattern = DirectCast( _
        targetControl.GetCurrentPattern(tablePattern.Pattern), _
        TablePattern)
    Catch exc As InvalidOperationException
        ' Object doesn't support the 
        ' TablePattern control pattern
        Return Nothing
    End Try

    Return tablePattern

End Function 'GetTablePattern    
///--------------------------------------------------------------------
/// <summary>
/// Set up table item event listeners.
/// </summary>
/// <remarks>
/// The event listener is essentially a focus change listener.
/// Since this is a global desktop listener, a filter would be required
/// to ignore focus change events outside the table.
/// </remarks>
///--------------------------------------------------------------------
private void SetTableItemEventListeners()
{
    AutomationFocusChangedEventHandler tableItemFocusChangedListener =
        new AutomationFocusChangedEventHandler(OnTableItemFocusChange);
    Automation.AddAutomationFocusChangedEventHandler(
        tableItemFocusChangedListener);
}
'''--------------------------------------------------------------------
''' <summary>
''' Set up table item event listeners.
''' </summary>
''' <remarks>
''' The event listener is essentially a focus change listener.
''' Since this is a global desktop listener, a filter would be required 
''' to ignore focus change events outside the table.
''' </remarks>
'''--------------------------------------------------------------------
Private Sub SetTableItemEventListeners( _
ByVal targetControl As AutomationElement)
    Dim tableItemFocusChangedListener As AutomationFocusChangedEventHandler = _
    AddressOf OnTableItemFocusChange
    Automation.AddAutomationFocusChangedEventHandler( _
    tableItemFocusChangedListener)

End Sub
///--------------------------------------------------------------------
/// <summary>
/// Event handler for table item focus change.
/// Can be used to track traversal of individual table items
/// within a table.
/// </summary>
/// <param name="src">Object that raised the event.</param>
/// <param name="e">Event arguments.</param>
///--------------------------------------------------------------------
private void OnTableItemFocusChange(
    object src, AutomationFocusChangedEventArgs e)
{
    // Make sure the element still exists. Elements such as tooltips
    // can disappear before the event is processed.
    AutomationElement sourceElement;
    try
    {
        sourceElement = src as AutomationElement;
    }
    catch (ElementNotAvailableException)
    {
        return;
    }

    // Get a TableItemPattern from the source of the event.
    TableItemPattern tableItemPattern =
        GetTableItemPattern(sourceElement);

    if (tableItemPattern == null)
    {
        return;
    }

    // Get a TablePattern from the container of the current element.
    TablePattern tablePattern =
        GetTablePattern(tableItemPattern.Current.ContainingGrid);

    if (tablePattern == null)
    {
        return;
    }

    AutomationElement tableItem = null;
    try
    {
        tableItem = tablePattern.GetItem(
        tableItemPattern.Current.Row,
        tableItemPattern.Current.Column);
    }
    catch (ArgumentOutOfRangeException)
    {
        // If the requested row coordinate is larger than the RowCount
        // or the column coordinate is larger than the ColumnCount.
        // -- OR --
        // If either of the requested row or column coordinates
        // is less than zero.
        // TO DO: error handling.
    }

    // Further event processing can be done at this point.
    // For the purposes of this sample we can just record item properties.
    string controlType =
        tableItem.Current.ControlType.LocalizedControlType;
    AutomationElement[] columnHeaders =
        tableItemPattern.Current.GetColumnHeaderItems();
    AutomationElement[] rowHeaders =
        tableItemPattern.Current.GetRowHeaderItems();
    int itemRow = tableItemPattern.Current.Row;
    int itemColumn = tableItemPattern.Current.Column;
    int itemRowSpan = tableItemPattern.Current.RowSpan;
    int itemColumnSpan = tableItemPattern.Current.ColumnSpan;
}

///--------------------------------------------------------------------
/// <summary>
/// Handles the application shutdown.
/// </summary>
/// <param name="args">Event arguments.</param>
///--------------------------------------------------------------------
protected override void OnExit(System.Windows.ExitEventArgs args)
{
    Automation.RemoveAllEventHandlers();
    base.OnExit(args);
}
'''--------------------------------------------------------------------
''' <summary>
''' Event handler for table item focus change.
''' Can be used to track traversal of individual table items 
''' within a table.
''' </summary>
''' <param name="src">Object that raised the event.</param>
''' <param name="e">Event arguments.</param>
'''--------------------------------------------------------------------
Private Sub OnTableItemFocusChange( _
ByVal src As Object, ByVal e As AutomationFocusChangedEventArgs)
    ' Make sure the element still exists. Elements such as tooltips
    ' can disappear before the event is processed.
    Dim sourceElement As AutomationElement
    Try
        sourceElement = DirectCast(src, AutomationElement)
    Catch exc As ElementNotAvailableException
        Return
    End Try

    ' Get a TableItemPattern from the source of the event.
    Dim tableItemPattern As TableItemPattern = _
    GetTableItemPattern(sourceElement)

    If tableItemPattern Is Nothing Then
        Return
    End If

    ' Get a TablePattern from the container of the current element.
    Dim tablePattern As TablePattern = _
    GetTablePattern(tableItemPattern.Current.ContainingGrid)

    If tablePattern Is Nothing Then
        Return
    End If

    Dim tableItem As AutomationElement = Nothing
    Try
        tableItem = tablePattern.GetItem( _
        tableItemPattern.Current.Row, tableItemPattern.Current.Column)

    Catch exc As ArgumentOutOfRangeException
        ' If the requested row coordinate is larger than the RowCount 
        ' or the column coordinate is larger than the ColumnCount.
        ' -- OR --
        ' If either of the requested row or column coordinates 
        ' is less than zero.
        ' TO DO: error handling.
    End Try

    ' Further event processing can be done at this point.
    ' For the purposes of this sample we can just record item properties.
    Dim controlType As String = _
        tableItem.Current.ControlType.LocalizedControlType
    Dim columnHeaders As AutomationElement() = _
    tableItemPattern.Current.GetColumnHeaderItems()
    Dim rowHeaders As AutomationElement() = _
    tableItemPattern.Current.GetRowHeaderItems()
    Dim itemRow As Integer = tableItemPattern.Current.Row
    Dim itemColumn As Integer = tableItemPattern.Current.Column
    Dim itemRowSpan As Integer = tableItemPattern.Current.RowSpan
    Dim itemColumnSpan As Integer = tableItemPattern.Current.ColumnSpan

End Sub


'''--------------------------------------------------------------------
''' <summary>
''' Handles the application shutdown.
''' </summary>
''' <param name="args">Event arguments.</param>
'''--------------------------------------------------------------------
Protected Overrides Sub OnExit(ByVal args As System.Windows.ExitEventArgs)
    Automation.RemoveAllEventHandlers()
    MyBase.OnExit(args)

End Sub

참고 항목