using System; using System.Collections.Generic; using System.ComponentModel; using System.Windows; using System.Windows.Automation; using System.Windows.Automation.Peers; using System.Windows.Automation.Provider; using System.Windows.Controls; using EGC = ExtendedGrid.Microsoft.Windows.Controls; namespace ExtendedGrid.Microsoft.Windows.Controls { /// /// AutomationPeer for a cell item in a DataGridRow. /// Cell may not have a visual container if it is scrolled out of view. /// public sealed class DataGridCellItemAutomationPeer : AutomationPeer, IGridItemProvider, ITableItemProvider, IInvokeProvider, IScrollItemProvider, ISelectionItemProvider { #region Constructors /// /// AutomationPeer for an item in a DataGrid /// public DataGridCellItemAutomationPeer(object item, EGC.DataGridColumn dataGridColumn) : base() { if (item == null) { throw new ArgumentNullException("item"); } if (dataGridColumn == null) { throw new ArgumentNullException("dataGridColumn"); } _item = item; _column = dataGridColumn; } #endregion #region AutomationPeer Overrides /// protected override string GetAcceleratorKeyCore() { return (this.OwningCellPeer != null) ? this.OwningCellPeer.GetAcceleratorKey() : string.Empty; } /// protected override string GetAccessKeyCore() { return (this.OwningCellPeer != null) ? this.OwningCellPeer.GetAccessKey() : string.Empty; } /// protected override AutomationControlType GetAutomationControlTypeCore() { return AutomationControlType.Custom; } /// protected override string GetAutomationIdCore() { return (this.OwningCellPeer != null) ? this.OwningCellPeer.GetAutomationId() : string.Empty; } /// protected override Rect GetBoundingRectangleCore() { return (this.OwningCellPeer != null) ? this.OwningCellPeer.GetBoundingRectangle() : new Rect(); } /// protected override List GetChildrenCore() { return (this.OwningCellPeer != null) ? this.OwningCellPeer.GetChildren() : null; } /// protected override string GetClassNameCore() { return (this.OwningCellPeer != null) ? this.OwningCellPeer.GetClassName() : string.Empty; } /// protected override Point GetClickablePointCore() { return (this.OwningCellPeer != null) ? this.OwningCellPeer.GetClickablePoint() : new Point(double.NaN, double.NaN); } /// protected override string GetHelpTextCore() { return (this.OwningCellPeer != null) ? this.OwningCellPeer.GetHelpText() : string.Empty; } /// protected override string GetItemStatusCore() { return (this.OwningCellPeer != null) ? this.OwningCellPeer.GetItemStatus() : string.Empty; } /// protected override string GetItemTypeCore() { return (this.OwningCellPeer != null) ? this.OwningCellPeer.GetItemType() : string.Empty; } /// protected override AutomationPeer GetLabeledByCore() { return (this.OwningCellPeer != null) ? this.OwningCellPeer.GetLabeledBy() : null; } /// protected override string GetLocalizedControlTypeCore() { return (this.OwningCellPeer != null) ? this.OwningCellPeer.GetLocalizedControlType() : base.GetLocalizedControlTypeCore(); } /// protected override string GetNameCore() { // It is better to get the clipboard content instead of wrapper peer Name which is empty in most cases object cellValue = _column.OnCopyingCellClipboardContent(_item); if (cellValue != null) { return cellValue.ToString(); } return String.Empty; } /// protected override AutomationOrientation GetOrientationCore() { return (this.OwningCellPeer != null) ? this.OwningCellPeer.GetOrientation() : AutomationOrientation.None; } /// public override object GetPattern(PatternInterface patternInterface) { switch (patternInterface) { case PatternInterface.Invoke: if (!this.OwningDataGrid.IsReadOnly && !_column.IsReadOnly) { return this; } break; case PatternInterface.SelectionItem: case PatternInterface.ScrollItem: case PatternInterface.GridItem: case PatternInterface.TableItem: return this; } return null; } /// protected override bool HasKeyboardFocusCore() { return (this.OwningCellPeer != null) ? this.OwningCellPeer.HasKeyboardFocus() : false; } /// protected override bool IsContentElementCore() { return (this.OwningCellPeer != null) ? this.OwningCellPeer.IsContentElement() : true; } /// protected override bool IsControlElementCore() { return (this.OwningCellPeer != null) ? this.OwningCellPeer.IsControlElement() : true; } /// protected override bool IsEnabledCore() { return (this.OwningCellPeer != null) ? this.OwningCellPeer.IsEnabled() : true; } /// protected override bool IsKeyboardFocusableCore() { return (this.OwningCellPeer != null) ? this.OwningCellPeer.IsKeyboardFocusable() : false; } /// protected override bool IsOffscreenCore() { return (this.OwningCellPeer != null) ? this.OwningCellPeer.IsOffscreen() : true; } /// protected override bool IsPasswordCore() { return (this.OwningCellPeer != null) ? this.OwningCellPeer.IsPassword() : false; } /// protected override bool IsRequiredForFormCore() { return (this.OwningCellPeer != null) ? this.OwningCellPeer.IsRequiredForForm() : false; } /// protected override void SetFocusCore() { if (this.OwningCellPeer != null && this.OwningCellPeer.Owner.Focusable) { this.OwningCellPeer.SetFocus(); } } #endregion #region IGridItemProvider int IGridItemProvider.Column { get { return this.OwningDataGrid.Columns.IndexOf(this._column); } } int IGridItemProvider.ColumnSpan { get { return 1; } } IRawElementProviderSimple IGridItemProvider.ContainingGrid { get { return this.ContainingGrid; } } int IGridItemProvider.Row { get { return this.OwningDataGrid.Items.IndexOf(this._item); } } int IGridItemProvider.RowSpan { get { return 1; } } #endregion #region ITableItemProvider IRawElementProviderSimple[] ITableItemProvider.GetColumnHeaderItems() { if (this.OwningDataGrid != null && (this.OwningDataGrid.HeadersVisibility & EGC.DataGridHeadersVisibility.Column) == EGC.DataGridHeadersVisibility.Column && this.OwningDataGrid.ColumnHeadersPresenter != null) { EGC.DataGridColumnHeadersPresenter dataGridColumnHeadersPresenter = this.OwningDataGrid.ColumnHeadersPresenter; EGC.DataGridColumnHeader dataGridColumnHeader = dataGridColumnHeadersPresenter.ItemContainerGenerator.ContainerFromIndex(this.OwningDataGrid.Columns.IndexOf(_column)) as EGC.DataGridColumnHeader; if (dataGridColumnHeader != null) { AutomationPeer peer = UIElementAutomationPeer.CreatePeerForElement(dataGridColumnHeader); if (peer != null) { List providers = new List(1); providers.Add(ProviderFromPeer(peer)); return providers.ToArray(); } } } return null; } IRawElementProviderSimple[] ITableItemProvider.GetRowHeaderItems() { if (this.OwningDataGrid != null && (this.OwningDataGrid.HeadersVisibility & EGC.DataGridHeadersVisibility.Row) == EGC.DataGridHeadersVisibility.Row) { EGC.DataGridAutomationPeer dataGridAutomationPeer = UIElementAutomationPeer.CreatePeerForElement(this.OwningDataGrid) as EGC.DataGridAutomationPeer; EGC.DataGridItemAutomationPeer dataGridItemAutomationPeer = dataGridAutomationPeer.GetOrCreateItemPeer(_item); if (dataGridItemAutomationPeer != null) { AutomationPeer rowHeaderAutomationPeer = dataGridItemAutomationPeer.RowHeaderAutomationPeer; if (rowHeaderAutomationPeer != null) { List providers = new List(1); providers.Add(ProviderFromPeer(rowHeaderAutomationPeer)); return providers.ToArray(); } } } return null; } #endregion #region IInvokeProvider void IInvokeProvider.Invoke() { if (this.OwningDataGrid.IsReadOnly || _column.IsReadOnly) { return; } EnsureEnabled(); bool success = false; // If the current cell is virtualized - scroll into view if (this.OwningCell == null) { this.OwningDataGrid.ScrollIntoView(_item, _column); } if (this.OwningCell != null) { IEditableCollectionView iecv = (IEditableCollectionView)this.OwningDataGrid.Items; if (iecv.CurrentEditItem == _item) { success = this.OwningDataGrid.CommitEdit(); } else { this.OwningDataGrid.UnselectAll(); this.OwningCell.Focus(); success = this.OwningDataGrid.BeginEdit(); } } if (!success) { throw new InvalidOperationException(); } } #endregion #region IScrollItemProvider void IScrollItemProvider.ScrollIntoView() { this.OwningDataGrid.ScrollIntoView(_item, _column); } #endregion #region ISelectionItemProvider bool ISelectionItemProvider.IsSelected { get { return this.OwningDataGrid.SelectedCellsInternal.Contains(new EGC.DataGridCellInfo(_item, _column)); } } IRawElementProviderSimple ISelectionItemProvider.SelectionContainer { get { return this.ContainingGrid; } } void ISelectionItemProvider.AddToSelection() { // If item is already selected - do nothing EGC.DataGridCellInfo currentCellInfo = new EGC.DataGridCellInfo(_item, _column); if (this.OwningDataGrid.SelectedCellsInternal.Contains(currentCellInfo)) { return; } EnsureEnabled(); if (this.OwningDataGrid.SelectionMode == EGC.DataGridSelectionMode.Single && this.OwningDataGrid.SelectedCells.Count > 0) { throw new InvalidOperationException(); } this.OwningDataGrid.SelectedCellsInternal.Add(currentCellInfo); } void ISelectionItemProvider.RemoveFromSelection() { EnsureEnabled(); EGC.DataGridCellInfo currentCellInfo = new EGC.DataGridCellInfo(_item, _column); if (this.OwningDataGrid.SelectedCellsInternal.Contains(currentCellInfo)) { this.OwningDataGrid.SelectedCellsInternal.Remove(currentCellInfo); } } void ISelectionItemProvider.Select() { EnsureEnabled(); EGC.DataGridCellInfo currentCellInfo = new EGC.DataGridCellInfo(_item, _column); this.OwningDataGrid.SelectOnlyThisCell(currentCellInfo); } #endregion #region Private Methods private void EnsureEnabled() { if (!OwningDataGrid.IsEnabled) { throw new ElementNotEnabledException(); } } #endregion #region Private Properties private EGC.DataGrid OwningDataGrid { get { return _column.DataGridOwner; } } // This may be null if the cell is virtualized private EGC.DataGridCell OwningCell { get { return this.OwningDataGrid.TryFindCell(_item, _column); } } internal EGC.DataGridCellAutomationPeer OwningCellPeer { get { EGC.DataGridCellAutomationPeer cellPeer = null; EGC.DataGridCell cell = this.OwningCell; if (cell != null) { cellPeer = FrameworkElementAutomationPeer.CreatePeerForElement(cell) as EGC.DataGridCellAutomationPeer; cellPeer.EventsSource = this; } return cellPeer; } } private IRawElementProviderSimple ContainingGrid { get { AutomationPeer peer = UIElementAutomationPeer.CreatePeerForElement(OwningDataGrid); if (peer != null) { return ProviderFromPeer(peer); } return null; } } #endregion #region Data private object _item; private EGC.DataGridColumn _column; #endregion } }