Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions controls/dev/TableView/TableViewAutomationPeer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
#include "common.h"
#include "TableView.h"
#include "TableViewRow.h"
#include "TableViewColumn.h"
#include "TableViewAutomationPeer.h"
#include "TableViewColumnHeaderAutomationPeer.h"
#include "TableViewCellAutomationPeer.h"
#include "TableViewAutomationHelpers.h"
#include "TableViewAutomationPeer.properties.cpp"
Expand Down Expand Up @@ -305,8 +305,8 @@ winrt::com_array<winrt::IRawElementProviderSimple> TableViewAutomationPeer::GetC
{
continue;
}
// TableView ownership allows pre-realization enumeration but shares RuntimeId.
auto headerPeer = winrt::make<TableViewColumnHeaderAutomationPeer>(tableView, column);
// TableView ownership allows pre-realization enumeration; the cached peer keeps RuntimeId stable.
auto const headerPeer = winrt::get_self<TableViewColumn>(column)->GetOrCreateHeaderAutomationPeerInternal(tableView);
headers.push_back(ProviderFromPeer(headerPeer));
}
}
Expand Down
4 changes: 2 additions & 2 deletions controls/dev/TableView/TableViewCellAutomationPeer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
#include "pch.h"
#include "common.h"
#include "TableView.h"
#include "TableViewColumn.h"
#include "TableViewTextColumn.h"
#include "TableViewRow.h"
#include "TableViewColumnHeaderAutomationPeer.h"
#include "TableViewCellAutomationPeer.h"
#include "TableViewAutomationHelpers.h"
#include "TableViewCellAutomationPeer.properties.cpp"
Expand Down Expand Up @@ -205,7 +205,7 @@ winrt::com_array<winrt::IRawElementProviderSimple> TableViewCellAutomationPeer::
{
if (auto const owner = winrt::get_self<TableViewRow>(row)->GetOwningTableView())
{
auto const headerPeer = winrt::make<TableViewColumnHeaderAutomationPeer>(owner, column);
auto const headerPeer = winrt::get_self<TableViewColumn>(column)->GetOrCreateHeaderAutomationPeerInternal(owner);
headers.push_back(ProviderFromPeer(headerPeer));
}
}
Expand Down
13 changes: 13 additions & 0 deletions controls/dev/TableView/TableViewColumn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "common.h"
#include "TableViewColumn.h"
#include "TableView.h"
#include "TableViewColumnHeaderAutomationPeer.h"

#include <algorithm>
#include <cmath>
Expand Down Expand Up @@ -291,6 +292,15 @@ void TableViewColumn::NotifyCellContentChanged()
}
}

winrt::AutomationPeer TableViewColumn::GetOrCreateHeaderAutomationPeerInternal(winrt::TableView const& owner)
{
if (!m_headerAutomationPeer)
{
m_headerAutomationPeer = winrt::make<TableViewColumnHeaderAutomationPeer>(owner, *this);
}
return m_headerAutomationPeer;
}

bool TableViewColumn::SetOwningTableViewInternal(winrt::TableView const& owner)
{
// Keep the owner weak to avoid TableView -> Columns -> Column -> TableView cycles.
Expand All @@ -310,6 +320,9 @@ bool TableViewColumn::SetOwningTableViewInternal(winrt::TableView const& owner)
else
{
m_owningTableView = nullptr;

// The cached peer holds the old owner; drop it so a reattach rebuilds it.
m_headerAutomationPeer = nullptr;
return true;
}
}
Expand Down
7 changes: 7 additions & 0 deletions controls/dev/TableView/TableViewColumn.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ class TableViewColumn :
void ResetDesiredWidthInternal();
double DesiredWidthInternal() const noexcept { return m_desiredWidth; }

// Returns this column's header automation peer, cached so the peer instance - and therefore its
// UIA RuntimeId - stays stable across enumeration, reorder and virtualization.
winrt::AutomationPeer GetOrCreateHeaderAutomationPeerInternal(winrt::TableView const& owner);

private:
// Write the resolved, clamped width into the read-only ActualWidth DP.
void UpdateActualWidth();
Expand All @@ -72,4 +76,7 @@ class TableViewColumn :
double m_desiredWidth{ 0.0 };

weak_ref<winrt::TableView> m_owningTableView{ nullptr };

// Cached header automation peer; see GetOrCreateHeaderAutomationPeerInternal.
winrt::AutomationPeer m_headerAutomationPeer{ nullptr };
};
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,7 @@ winrt::AutomationControlType TableViewColumnHeaderAutomationPeer::GetAutomationC

int32_t TableViewColumnHeaderAutomationPeer::GetPositionInSetCore()
{
// Every header peer shares the TableView owner, so their auto-generated UIA
// RuntimeIds collide (WinUI AutomationPeer has no overridable GetRuntimeIdCore).
// Expose the 1-based column position so AT (Narrator) can still distinguish and
// announce "column i of n"; combined with the distinct GetNameCore this makes each
// header individually identifiable.
// 1-based column position so AT can announce "column i of n".
const auto index = GetColumnIndex();
return index >= 0 ? index + 1 : -1;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
#include "TableViewColumnHeaderAutomationPeer.g.h"

// UIA peer for a TableView column header; reports header name, type, and bounds.
// Distinct per-column RuntimeIds are not yet implemented; peers share the TableView
// owner-derived identity. TableView ownership allows pre-realization enumeration.
// TableView ownership allows pre-realization enumeration. The peer is cached per column
// (TableViewColumn::GetOrCreateHeaderAutomationPeerInternal) so its RuntimeId stays stable.
class TableViewColumnHeaderAutomationPeer :
public ReferenceTracker<TableViewColumnHeaderAutomationPeer, winrt::implementation::TableViewColumnHeaderAutomationPeerT>
{
Expand All @@ -19,8 +19,7 @@ class TableViewColumnHeaderAutomationPeer :
hstring GetClassNameCore();
hstring GetNameCore();
winrt::AutomationControlType GetAutomationControlTypeCore();
// Header peers share the TableView owner, so RuntimeIds currently collide; expose
// visible column position so AT can distinguish columns until distinct RuntimeIds are implemented.
// PositionInSet/SizeOfSet announce "column i of n" for AT.
int32_t GetPositionInSetCore();
int32_t GetSizeOfSetCore();

Expand Down
Loading