diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridView.AccessibleObject.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridView.AccessibleObject.cs
index 4763f44de10..8df8f01df36 100644
--- a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridView.AccessibleObject.cs
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridView.AccessibleObject.cs
@@ -32,6 +32,26 @@ private bool IsModal
}
}
+ internal void ReleaseChildUiaProviders()
+ {
+ if (!OsVersion.IsWindows8OrGreater())
+ {
+ return;
+ }
+
+ if (_topRowAccessibilityObject is not null)
+ {
+ UiaCore.UiaDisconnectProvider(_topRowAccessibilityObject);
+ _topRowAccessibilityObject = null;
+ }
+
+ if (_selectedCellsAccessibilityObject is not null)
+ {
+ UiaCore.UiaDisconnectProvider(_selectedCellsAccessibilityObject);
+ _selectedCellsAccessibilityObject = null;
+ }
+ }
+
public override AccessibleRole Role
{
get
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridView.Methods.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridView.Methods.cs
index bc2ccbe39ee..a87cb463508 100644
--- a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridView.Methods.cs
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridView.Methods.cs
@@ -26104,6 +26104,44 @@ private void ReleaseMouse()
Capture = false;
}
+ internal override void ReleaseUiaProvider(IntPtr handle)
+ {
+ if (!IsAccessibilityObjectCreated)
+ {
+ return;
+ }
+
+ if (OsVersion.IsWindows8OrGreater())
+ {
+ foreach (DataGridViewRow row in Rows)
+ {
+ foreach (DataGridViewCell cell in row.Cells)
+ {
+ cell.ReleaseUiaProvider();
+ }
+
+ row.HeaderCell.ReleaseUiaProvider();
+ row.ReleaseUiaProvider();
+ }
+
+ foreach (DataGridViewColumn column in Columns)
+ {
+ column.HeaderCell.ReleaseUiaProvider();
+ }
+
+ _editingPanel?.ReleaseUiaProvider(IntPtr.Zero);
+ _editingPanelAccessibleObject = null;
+ _topLeftHeaderCell?.ReleaseUiaProvider();
+
+ if (AccessibilityObject is DataGridViewAccessibleObject accessibleObject)
+ {
+ accessibleObject.ReleaseChildUiaProviders();
+ }
+ }
+
+ base.ReleaseUiaProvider(handle);
+ }
+
private void RemoveIndividualReadOnlyCellsInColumn(int columnIndex)
{
int cellIndex = 0;
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewCell.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewCell.cs
index 2ece3e53deb..9839945c2be 100644
--- a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewCell.cs
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewCell.cs
@@ -491,6 +491,8 @@ public DataGridViewCellStyle InheritedStyle
}
}
+ internal bool IsAccessibilityObjectCreated => Properties.GetObject(s_propCellAccessibilityObject) is AccessibleObject;
+
///
/// Indicates whether or not the parent grid view for this element has an accessible object associated with it.
///
@@ -1292,8 +1294,9 @@ private bool AccessibleRestructuringNeeded
Type editingControlType = DataGridView.EditingControl.GetType();
return
- (editingControlType == typeof(DataGridViewComboBoxEditingControl) && !editingControlType.IsSubclassOf(typeof(DataGridViewComboBoxEditingControl))) ||
- (editingControlType == typeof(DataGridViewTextBoxEditingControl) && !editingControlType.IsSubclassOf(typeof(DataGridViewTextBoxEditingControl)));
+ IsAccessibilityObjectCreated &&
+ ((editingControlType == typeof(DataGridViewComboBoxEditingControl) && !editingControlType.IsSubclassOf(typeof(DataGridViewComboBoxEditingControl))) ||
+ (editingControlType == typeof(DataGridViewTextBoxEditingControl) && !editingControlType.IsSubclassOf(typeof(DataGridViewTextBoxEditingControl))));
}
}
@@ -4056,6 +4059,21 @@ public virtual Rectangle PositionEditingPanel(Rectangle cellBounds,
return new Rectangle(xEditingControl, yEditingControl, wEditingControl, hEditingControl);
}
+ internal virtual void ReleaseUiaProvider()
+ {
+ if (!IsAccessibilityObjectCreated)
+ {
+ return;
+ }
+
+ if (OsVersion.IsWindows8OrGreater())
+ {
+ UiaCore.UiaDisconnectProvider(AccessibilityObject);
+ }
+
+ Properties.SetObject(s_propCellAccessibilityObject, null);
+ }
+
protected virtual bool SetValue(int rowIndex, object value)
{
object originalValue = null;
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewColumnCollection.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewColumnCollection.cs
index 8fe4e851878..c596e5cac85 100644
--- a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewColumnCollection.cs
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewColumnCollection.cs
@@ -1109,6 +1109,17 @@ internal void RemoveAtInternal(int index, bool force)
Debug.Assert(!DataGridView.InDisplayIndexAdjustments);
DataGridViewColumn dataGridViewColumn = _items[index];
+
+ if (DataGridView.IsAccessibilityObjectCreated && OsVersion.IsWindows8OrGreater())
+ {
+ foreach (DataGridViewRow row in DataGridView.Rows)
+ {
+ row.Cells[index].ReleaseUiaProvider();
+ }
+
+ dataGridViewColumn.HeaderCell.ReleaseUiaProvider();
+ }
+
DataGridView.OnRemovingColumn(dataGridViewColumn, out Point newCurrentCell, force);
InvalidateCachedColumnsOrder();
_items.RemoveAt(index);
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewComboBoxCell.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewComboBoxCell.cs
index 81bafb606fb..2d60af10b07 100644
--- a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewComboBoxCell.cs
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewComboBoxCell.cs
@@ -2547,6 +2547,13 @@ public override object ParseFormattedValue(
}
}
+ internal override void ReleaseUiaProvider()
+ {
+ EditingComboBox?.ReleaseUiaProvider(IntPtr.Zero);
+
+ base.ReleaseUiaProvider();
+ }
+
///
/// Gets the row Index and column Index of the cell.
///
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewComboBoxEditingControl.DataGridViewComboBoxEditingControlAccessibleObject.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewComboBoxEditingControl.DataGridViewComboBoxEditingControlAccessibleObject.cs
index 2d58f053266..1efffb74e4e 100644
--- a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewComboBoxEditingControl.DataGridViewComboBoxEditingControlAccessibleObject.cs
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewComboBoxEditingControl.DataGridViewComboBoxEditingControlAccessibleObject.cs
@@ -26,6 +26,11 @@ public DataGridViewComboBoxEditingControlAccessibleObject(DataGridViewComboBoxEd
_ownerControl = ownerControl;
}
+ internal void ClearParent()
+ {
+ _parentAccessibleObject = null;
+ }
+
public override AccessibleObject? Parent
{
get
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewComboBoxEditingControl.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewComboBoxEditingControl.cs
index d4841ed5f45..58aa8c5d7ba 100644
--- a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewComboBoxEditingControl.cs
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewComboBoxEditingControl.cs
@@ -163,7 +163,20 @@ protected override void OnHandleCreated(EventArgs e)
base.OnHandleCreated(e);
// The null-check was added as a fix for a https://github.com/dotnet/winforms/issues/2138
- _dataGridView?.SetAccessibleObjectParent(AccessibilityObject);
+ if (_dataGridView?.IsAccessibilityObjectCreated == true)
+ {
+ _dataGridView.SetAccessibleObjectParent(AccessibilityObject);
+ }
+ }
+
+ internal override void ReleaseUiaProvider(nint handle)
+ {
+ if (TryGetAccessibilityObject(out AccessibleObject accessibleObject))
+ {
+ ((DataGridViewComboBoxEditingControlAccessibleObject)accessibleObject).ClearParent();
+ }
+
+ base.ReleaseUiaProvider(handle);
}
}
}
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewRow.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewRow.cs
index d28779448c5..f2f5760b1c8 100644
--- a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewRow.cs
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewRow.cs
@@ -242,6 +242,8 @@ public override DataGridViewCellStyle InheritedStyle
}
}
+ internal bool IsAccessibilityObjectCreated => Properties.GetObject(s_propRowAccessibilityObject) is AccessibleObject;
+
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsNewRow
@@ -1728,6 +1730,21 @@ protected internal virtual void PaintHeader(Graphics graphics,
}
}
+ internal void ReleaseUiaProvider()
+ {
+ if (!IsAccessibilityObjectCreated)
+ {
+ return;
+ }
+
+ if (OsVersion.IsWindows8OrGreater())
+ {
+ Interop.UiaCore.UiaDisconnectProvider(AccessibilityObject);
+ }
+
+ Properties.SetObject(s_propRowAccessibilityObject, null);
+ }
+
internal void SetReadOnlyCellCore(DataGridViewCell dataGridViewCell, bool readOnly)
{
Debug.Assert(Index == -1);
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewRowCollection.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewRowCollection.cs
index 11122450ff8..f02f5f56e0d 100644
--- a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewRowCollection.cs
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewRowCollection.cs
@@ -2259,6 +2259,17 @@ public virtual void RemoveAt(int index)
throw new InvalidOperationException(SR.DataGridView_ForbiddenOperationInEventHandler);
}
+ if (DataGridView.IsAccessibilityObjectCreated && OsVersion.IsWindows8OrGreater() && this[index] is DataGridViewRow row)
+ {
+ foreach (DataGridViewCell cell in row.Cells)
+ {
+ cell.ReleaseUiaProvider();
+ }
+
+ row.HeaderCell.ReleaseUiaProvider();
+ row.ReleaseUiaProvider();
+ }
+
if (DataGridView.DataSource is not null)
{
if (DataGridView.DataConnection.List is IBindingList list && list.AllowRemove && list.SupportsChangeNotification)
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewTextBoxEditingControl.DataGridViewTextBoxEditingControlAccessibleObject.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewTextBoxEditingControl.DataGridViewTextBoxEditingControlAccessibleObject.cs
index f6d0dd1b8f5..de1e1a5d04d 100644
--- a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewTextBoxEditingControl.DataGridViewTextBoxEditingControlAccessibleObject.cs
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewTextBoxEditingControl.DataGridViewTextBoxEditingControlAccessibleObject.cs
@@ -21,6 +21,11 @@ internal class DataGridViewTextBoxEditingControlAccessibleObject : TextBoxBaseAc
public DataGridViewTextBoxEditingControlAccessibleObject(DataGridViewTextBoxEditingControl ownerControl) : base(ownerControl)
{ }
+ internal void ClearParent()
+ {
+ _parentAccessibleObject = null;
+ }
+
public override AccessibleObject? Parent => _parentAccessibleObject;
public override string Name => Owner.AccessibleName ?? SR.DataGridView_AccEditingControlAccName;
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewTextBoxEditingControl.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewTextBoxEditingControl.cs
index fed54b5f74c..9294de5237f 100644
--- a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewTextBoxEditingControl.cs
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewTextBoxEditingControl.cs
@@ -90,8 +90,6 @@ public virtual bool RepositionEditingControlOnValueChange
}
}
- internal override bool SupportsUiaProviders => true;
-
public virtual void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
{
ArgumentNullException.ThrowIfNull(dataGridViewCellStyle);
@@ -287,6 +285,16 @@ protected override bool ProcessKeyEventArgs(ref Message m)
return base.ProcessKeyEventArgs(ref m);
}
+ internal override void ReleaseUiaProvider(nint handle)
+ {
+ if (TryGetAccessibilityObject(out AccessibleObject? accessibleObject))
+ {
+ ((DataGridViewTextBoxEditingControlAccessibleObject)accessibleObject).ClearParent();
+ }
+
+ base.ReleaseUiaProvider(handle);
+ }
+
private static HorizontalAlignment TranslateAlignment(DataGridViewContentAlignment align)
{
if ((align & AnyRight) != 0)
@@ -306,10 +314,11 @@ private static HorizontalAlignment TranslateAlignment(DataGridViewContentAlignme
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
- if (IsHandleCreated)
+
+ // The null-check was added as a fix for a https://github.com/dotnet/winforms/issues/2138
+ if (IsHandleCreated && _dataGridView?.IsAccessibilityObjectCreated == true)
{
- // The null-check was added as a fix for a https://github.com/dotnet/winforms/issues/2138
- _dataGridView?.SetAccessibleObjectParent(AccessibilityObject);
+ _dataGridView.SetAccessibleObjectParent(AccessibilityObject);
}
}
}