Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / System / Windows / Automation / Peers / CalendarAutomationPeer.cs / 1477467 / CalendarAutomationPeer.cs
//---------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation. All rights reserved. // //--------------------------------------------------------------------------- using System; using System.Collections.Generic; using System.Globalization; using System.Security; using System.Windows; using System.Windows.Automation; using System.Windows.Automation.Provider; using System.Windows.Controls; using System.Windows.Controls.Primitives; using MS.Internal.Automation; namespace System.Windows.Automation.Peers { ////// AutomationPeer for Calendar Control /// public sealed class CalendarAutomationPeer : FrameworkElementAutomationPeer, IGridProvider, IMultipleViewProvider, ISelectionProvider, ITableProvider, IItemContainerProvider { ////// Initializes a new instance of the CalendarAutomationPeer class. /// /// Owning Calendar public CalendarAutomationPeer(System.Windows.Controls.Calendar owner) : base(owner) { } #region Private Properties private System.Windows.Controls.Calendar OwningCalendar { get { return this.Owner as System.Windows.Controls.Calendar; } } private Grid OwningGrid { get { if (this.OwningCalendar != null && this.OwningCalendar.MonthControl != null) { if (this.OwningCalendar.DisplayMode == CalendarMode.Month) { return this.OwningCalendar.MonthControl.MonthView; } else { return this.OwningCalendar.MonthControl.YearView; } } return null; } } #endregion Private Properties #region Public Methods ////// Gets the control pattern that is associated with the specified System.Windows.Automation.Peers.PatternInterface. /// /// A value from the System.Windows.Automation.Peers.PatternInterface enumeration. ///The object that supports the specified pattern, or null if unsupported. public override object GetPattern(PatternInterface patternInterface) { switch (patternInterface) { case PatternInterface.Grid: case PatternInterface.Table: case PatternInterface.MultipleView: case PatternInterface.Selection: case PatternInterface.ItemContainer: { if (this.OwningGrid != null) { return this; } break; } default: break; } return base.GetPattern(patternInterface); } #endregion Public Methods #region Protected Methods ////// Gets the control type for the element that is associated with the UI Automation peer. /// ///The control type. protected override AutomationControlType GetAutomationControlTypeCore() { return AutomationControlType.Calendar; } protected override ListGetChildrenCore() { if (OwningCalendar.MonthControl == null) { return null; } List peers = new List (); Dictionary newChildren = new Dictionary (); // Step 1: Add previous, header and next buttons AutomationPeer buttonPeer; buttonPeer = FrameworkElementAutomationPeer.CreatePeerForElement(OwningCalendar.MonthControl.PreviousButton); if (buttonPeer != null) { peers.Add(buttonPeer); } buttonPeer = FrameworkElementAutomationPeer.CreatePeerForElement(OwningCalendar.MonthControl.HeaderButton); if (buttonPeer != null) { peers.Add(buttonPeer); } buttonPeer = FrameworkElementAutomationPeer.CreatePeerForElement(OwningCalendar.MonthControl.NextButton); if (buttonPeer != null) { peers.Add(buttonPeer); } // Step 2: Add Calendar Buttons depending on the Calendar.DisplayMode DateTime date; DateTimeAutomationPeer peer; foreach (UIElement child in this.OwningGrid.Children) { int childRow = (int)child.GetValue(Grid.RowProperty); // first row is day titles if (OwningCalendar.DisplayMode == CalendarMode.Month && childRow == 0) { AutomationPeer dayTitlePeer = UIElementAutomationPeer.CreatePeerForElement(child); peers.Add(dayTitlePeer); } else { Button owningButton = child as Button; if (owningButton != null && owningButton.DataContext is DateTime) { date = (DateTime)owningButton.DataContext; peer = GetOrCreateDateTimeAutomationPeer(date, OwningCalendar.DisplayMode, /*addParentInfo*/ false); peers.Add(peer); DateTimeCalendarModePair key = new DateTimeCalendarModePair(date, OwningCalendar.DisplayMode); newChildren.Add(key, peer); } } } DateTimePeers = newChildren; return peers; } /// /// Called by GetClassName that gets a human readable name that, in addition to AutomationControlType, /// differentiates the control represented by this AutomationPeer. /// ///The string that contains the name. protected override string GetClassNameCore() { return this.Owner.GetType().Name; } protected override void SetFocusCore() { System.Windows.Controls.Calendar owner = OwningCalendar; if (owner.Focusable) { if (!owner.Focus()) { DateTime focusedDate; // Focus should have moved to either SelectedDate or DisplayDate if (owner.SelectedDate.HasValue && DateTimeHelper.CompareYearMonth(owner.SelectedDate.Value, owner.DisplayDateInternal) == 0) { focusedDate = owner.SelectedDate.Value; } else { focusedDate = owner.DisplayDate; } DateTimeAutomationPeer focusedItem = GetOrCreateDateTimeAutomationPeer(focusedDate, owner.DisplayMode, /*addParentInfo*/ false); FrameworkElement focusedButton = focusedItem.OwningButton; if (focusedButton == null || !focusedButton.IsKeyboardFocused) { throw new InvalidOperationException(SR.Get(SRID.SetFocusFailed)); } } } else { throw new InvalidOperationException(SR.Get(SRID.SetFocusFailed)); } } #endregion Protected Methods #region InternalMethods private DateTimeAutomationPeer GetOrCreateDateTimeAutomationPeer(DateTime date, CalendarMode buttonMode) { return GetOrCreateDateTimeAutomationPeer(date, buttonMode, /*addParentInfo*/ true); } ////// Security Critical - Calls a Security Critical operation AddParentInfo which adds parent peer and provides /// security critical Hwnd value for this peer created asynchronously. /// SecurityTreatAsSafe - It's being called from this object which is real parent for the item peer. /// [SecurityCritical, SecurityTreatAsSafe] private DateTimeAutomationPeer GetOrCreateDateTimeAutomationPeer(DateTime date, CalendarMode buttonMode, bool addParentInfo) { // try to reuse old peer if it exists either in Current AT or in WeakRefStorage of Peers being sent to Client DateTimeCalendarModePair key = new DateTimeCalendarModePair(date, buttonMode); DateTimeAutomationPeer peer = null; DateTimePeers.TryGetValue(key, out peer); if (peer == null) { peer = GetPeerFromWeakRefStorage(key); if (peer != null && !addParentInfo) { // As cached peer is getting used it must be invalidated. addParentInfo check ensures that call is coming from GetChildrenCore peer.AncestorsInvalid = false; peer.ChildrenValid = false; } } if( peer == null ) { peer = new DateTimeAutomationPeer(date, OwningCalendar, buttonMode); // Sets hwnd and parent info if (addParentInfo) { if(peer != null) peer.TrySetParentInfo(this); } } // Set EventsSource if visual exists AutomationPeer wrapperPeer = peer.WrapperPeer; if (wrapperPeer != null) { wrapperPeer.EventsSource = peer; } return peer; } // Provides Peer if exist in Weak Reference Storage private DateTimeAutomationPeer GetPeerFromWeakRefStorage(DateTimeCalendarModePair dateTimeCalendarModePairKey) { DateTimeAutomationPeer returnPeer = null; WeakReference weakRefEP = null; WeakRefElementProxyStorage.TryGetValue(dateTimeCalendarModePairKey, out weakRefEP); if (weakRefEP != null) { ElementProxy provider = weakRefEP.Target as ElementProxy; if (provider != null) { returnPeer = PeerFromProvider(provider as IRawElementProviderSimple) as DateTimeAutomationPeer; if (returnPeer == null) WeakRefElementProxyStorage.Remove(dateTimeCalendarModePairKey); } else WeakRefElementProxyStorage.Remove(dateTimeCalendarModePairKey); } return returnPeer; } // Called by DateTimeAutomationPeer internal void AddProxyToWeakRefStorage(WeakReference wr, DateTimeAutomationPeer dateTimePeer) { DateTimeCalendarModePair key = new DateTimeCalendarModePair(dateTimePeer.Date, dateTimePeer.ButtonMode); if (GetPeerFromWeakRefStorage(key) == null) WeakRefElementProxyStorage.Add(key, wr); } internal void RaiseSelectionEvents(SelectionChangedEventArgs e) { int numSelected = OwningCalendar.SelectedDates.Count; int numAdded = e.AddedItems.Count; if (AutomationPeer.ListenerExists(AutomationEvents.SelectionItemPatternOnElementSelected) && numSelected == 1 && numAdded == 1) { DateTimeAutomationPeer peer = GetOrCreateDateTimeAutomationPeer((DateTime)e.AddedItems[0], CalendarMode.Month); if (peer != null) { peer.RaiseAutomationEvent(AutomationEvents.SelectionItemPatternOnElementSelected); } } else { if (AutomationPeer.ListenerExists(AutomationEvents.SelectionItemPatternOnElementAddedToSelection)) { foreach (DateTime date in e.AddedItems) { DateTimeAutomationPeer peer = GetOrCreateDateTimeAutomationPeer(date, CalendarMode.Month); if (peer != null) { peer.RaiseAutomationEvent(AutomationEvents.SelectionItemPatternOnElementAddedToSelection); } } } } if (AutomationPeer.ListenerExists(AutomationEvents.SelectionItemPatternOnElementRemovedFromSelection)) { foreach (DateTime date in e.RemovedItems) { DateTimeAutomationPeer peer = GetOrCreateDateTimeAutomationPeer(date, CalendarMode.Month); if (peer != null) { peer.RaiseAutomationEvent(AutomationEvents.SelectionItemPatternOnElementRemovedFromSelection); } } } } #endregion InternalMethods #region IGridProvider int IGridProvider.ColumnCount { get { if (this.OwningGrid != null) { return this.OwningGrid.ColumnDefinitions.Count; } return 0; } } int IGridProvider.RowCount { get { if (this.OwningGrid != null) { if (this.OwningCalendar.DisplayMode == CalendarMode.Month) { // In Month DisplayMode, since first row is DayTitles, we return the RowCount-1 return Math.Max(0, this.OwningGrid.RowDefinitions.Count - 1); } else { return this.OwningGrid.RowDefinitions.Count; } } return 0; } } IRawElementProviderSimple IGridProvider.GetItem(int row, int column) { if (this.OwningCalendar.DisplayMode == CalendarMode.Month) { // In Month DisplayMode, since first row is DayTitles, we increment the row number by 1 row++; } if (this.OwningGrid != null && row >= 0 && row < this.OwningGrid.RowDefinitions.Count && column >= 0 && column < this.OwningGrid.ColumnDefinitions.Count) { foreach (UIElement child in this.OwningGrid.Children) { int childRow = (int)child.GetValue(Grid.RowProperty); int childColumn = (int)child.GetValue(Grid.ColumnProperty); if (childRow == row && childColumn == column) { object dataContext = (child as FrameworkElement).DataContext; if (dataContext is DateTime) { DateTime date = (DateTime)dataContext; AutomationPeer peer = GetOrCreateDateTimeAutomationPeer(date, OwningCalendar.DisplayMode); return ProviderFromPeer(peer); } } } } return null; } #endregion IGridProvider #region IMultipleViewProvider int IMultipleViewProvider.CurrentView { get { return (int)this.OwningCalendar.DisplayMode; } } int[] IMultipleViewProvider.GetSupportedViews() { int[] supportedViews = new int[3]; supportedViews[0] = (int)CalendarMode.Month; supportedViews[1] = (int)CalendarMode.Year; supportedViews[2] = (int)CalendarMode.Decade; return supportedViews; } string IMultipleViewProvider.GetViewName(int viewId) { switch (viewId) { case 0: { return SR.Get(SRID.CalendarAutomationPeer_MonthMode); } case 1: { return SR.Get(SRID.CalendarAutomationPeer_YearMode); } case 2: { return SR.Get(SRID.CalendarAutomationPeer_DecadeMode); } } // return String.Empty; } void IMultipleViewProvider.SetCurrentView(int viewId) { this.OwningCalendar.DisplayMode = (CalendarMode)viewId; } #endregion IMultipleViewProvider #region ISelectionProvider bool ISelectionProvider.CanSelectMultiple { get { return this.OwningCalendar.SelectionMode == CalendarSelectionMode.SingleRange || this.OwningCalendar.SelectionMode == CalendarSelectionMode.MultipleRange; } } bool ISelectionProvider.IsSelectionRequired { get { return false; } } IRawElementProviderSimple[] ISelectionProvider.GetSelection() { Listproviders = new List (); foreach (DateTime date in OwningCalendar.SelectedDates) { AutomationPeer peer = GetOrCreateDateTimeAutomationPeer(date, CalendarMode.Month); providers.Add(ProviderFromPeer(peer)); } if (providers.Count > 0) { return providers.ToArray(); } return null; } #endregion ISelectionProvider #region IItemContainerProvider IRawElementProviderSimple IItemContainerProvider.FindItemByProperty(IRawElementProviderSimple startAfterProvider, int propertyId, object value) { DateTimeAutomationPeer startAfterDatePeer = null; if (startAfterProvider != null) { startAfterDatePeer = PeerFromProvider(startAfterProvider) as DateTimeAutomationPeer; // if provider is not null, peer must exist if (startAfterDatePeer == null) { throw new InvalidOperationException(SR.Get(SRID.InavalidStartItem)); } } DateTime? nextDate = null; CalendarMode currentMode = 0; if( propertyId == SelectionItemPatternIdentifiers.IsSelectedProperty.Id) { currentMode = CalendarMode.Month; nextDate = GetNextSelectedDate(startAfterDatePeer, (bool)value); } else if (propertyId == AutomationElementIdentifiers.NameProperty.Id) { // finds the button for the given DateTime DateTimeFormatInfo format = DateTimeHelper.GetCurrentDateFormat(); DateTime parsedDate; if (DateTime.TryParse((value as string), format, System.Globalization.DateTimeStyles.None, out parsedDate)) { nextDate = parsedDate; } if( !nextDate.HasValue || (startAfterDatePeer != null && nextDate <= startAfterDatePeer.Date) ) { throw new InvalidOperationException(SR.Get(SRID.CalendarNamePropertyValueNotValid)); } currentMode = (startAfterDatePeer != null) ? startAfterDatePeer.ButtonMode : OwningCalendar.DisplayMode; } else if (propertyId == 0 || propertyId == AutomationElementIdentifiers.ControlTypeProperty.Id) { // propertyId = 0 returns the button next to the startAfter or the DisplayDate if startAfter is null // All items here are buttons, so same behaviour as propertyId = 0 if (propertyId == AutomationElementIdentifiers.ControlTypeProperty.Id && (int)value != ControlType.Button.Id) { return null; } currentMode = (startAfterDatePeer != null) ? startAfterDatePeer.ButtonMode : OwningCalendar.DisplayMode; nextDate = GetNextDate(startAfterDatePeer, currentMode); } else { throw new ArgumentException(SR.Get(SRID.PropertyNotSupported)); } if (nextDate.HasValue) { AutomationPeer nextPeer = GetOrCreateDateTimeAutomationPeer(nextDate.Value, currentMode); if (nextPeer != null) { return ProviderFromPeer(nextPeer); } } return null; } private DateTime? GetNextDate(DateTimeAutomationPeer currentDatePeer, CalendarMode currentMode) { DateTime? nextDate = null; DateTime startDate = (currentDatePeer != null) ? currentDatePeer.Date : OwningCalendar.DisplayDate; if (currentMode == CalendarMode.Month) nextDate = startDate.AddDays(1); else if (currentMode == CalendarMode.Year) nextDate = startDate.AddMonths(1); else if (currentMode == CalendarMode.Decade) nextDate = startDate.AddYears(1); return nextDate; } private DateTime? GetNextSelectedDate(DateTimeAutomationPeer currentDatePeer, bool isSelected) { DateTime startDate = (currentDatePeer != null) ? currentDatePeer.Date : OwningCalendar.DisplayDate; if (isSelected) { // If SelectedDates is empty or startDate is beyond last SelectedDate if (!OwningCalendar.SelectedDates.MaximumDate.HasValue || OwningCalendar.SelectedDates.MaximumDate <= startDate) { return null; } // startDate is before first SelectedDate if (OwningCalendar.SelectedDates.MinimumDate.HasValue && startDate < OwningCalendar.SelectedDates.MinimumDate) { return OwningCalendar.SelectedDates.MinimumDate; } } while (true) { startDate = startDate.AddDays(1); if (OwningCalendar.SelectedDates.Contains(startDate) == isSelected) { break; } } return startDate; } #endregion IItemContainerProvider #region ITableProvider RowOrColumnMajor ITableProvider.RowOrColumnMajor { get { return RowOrColumnMajor.RowMajor; } } IRawElementProviderSimple[] ITableProvider.GetColumnHeaders() { if (this.OwningCalendar.DisplayMode == CalendarMode.Month) { List providers = new List (); foreach (UIElement child in this.OwningGrid.Children) { int childRow = (int)child.GetValue(Grid.RowProperty); if (childRow == 0) { AutomationPeer peer = CreatePeerForElement(child); if (peer != null) { providers.Add(ProviderFromPeer(peer)); } } } if (providers.Count > 0) { return providers.ToArray(); } } return null; } // If WeekNumber functionality is supported by Calendar in the future, // this method should return weeknumbers IRawElementProviderSimple[] ITableProvider.GetRowHeaders() { return null; } #endregion ITableProvider /// /// Used to cache realized peers. We donot store references to virtualized peers. /// private DictionaryDateTimePeers { get { return _dataChildren; } set { _dataChildren = value; } } private Dictionary WeakRefElementProxyStorage { get { return _weakRefElementProxyStorage; } } #region Private Data private Dictionary _dataChildren = new Dictionary (); private Dictionary _weakRefElementProxyStorage = new Dictionary (); #endregion Private Data } internal struct DateTimeCalendarModePair { internal DateTimeCalendarModePair(DateTime date, CalendarMode mode) { ButtonMode = mode; Date = date; } CalendarMode ButtonMode; DateTime Date; } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- SqlNodeAnnotation.cs
- WriteTimeStream.cs
- HttpUnhandledOperationInvoker.cs
- ClaimComparer.cs
- EventMappingSettingsCollection.cs
- PanelDesigner.cs
- LocalizeDesigner.cs
- HashCoreRequest.cs
- X509Certificate2Collection.cs
- ListViewItem.cs
- DataGridViewCellCollection.cs
- PropertyEmitterBase.cs
- ProviderConnectionPoint.cs
- DeflateEmulationStream.cs
- FontStyleConverter.cs
- ValueType.cs
- WriteFileContext.cs
- MinMaxParagraphWidth.cs
- AsyncParams.cs
- UpdateDelegates.Generated.cs
- SQLGuidStorage.cs
- ContextStaticAttribute.cs
- DeliveryRequirementsAttribute.cs
- NativeMethods.cs
- HierarchicalDataBoundControlAdapter.cs
- DragCompletedEventArgs.cs
- DocumentViewerAutomationPeer.cs
- OLEDB_Enum.cs
- RightsManagementUser.cs
- SystemFonts.cs
- PropertyBuilder.cs
- MetadataAssemblyHelper.cs
- InvalidEnumArgumentException.cs
- Task.cs
- ZipIOBlockManager.cs
- KeyConverter.cs
- ProxyDataContractResolver.cs
- FilterQueryOptionExpression.cs
- _TimerThread.cs
- JsonClassDataContract.cs
- Assembly.cs
- TextDocumentView.cs
- OutputCacheProfile.cs
- SessionEndedEventArgs.cs
- ConfigPathUtility.cs
- ManipulationCompletedEventArgs.cs
- ResourceDisplayNameAttribute.cs
- DecimalFormatter.cs
- TemplateApplicationHelper.cs
- AsymmetricKeyExchangeFormatter.cs
- WriteTimeStream.cs
- XPathAncestorIterator.cs
- BitmapEffectGeneralTransform.cs
- LinearGradientBrush.cs
- WorkflowRuntimeElement.cs
- WorkflowPageSetupDialog.cs
- versioninfo.cs
- HopperCache.cs
- ValidationHelpers.cs
- DataGridViewRowEventArgs.cs
- TreeViewDesigner.cs
- Misc.cs
- DataRecordInfo.cs
- ProgressiveCrcCalculatingStream.cs
- ExtenderProvidedPropertyAttribute.cs
- SpAudioStreamWrapper.cs
- IisTraceWebEventProvider.cs
- RuntimeTrackingProfile.cs
- Menu.cs
- RepeatButton.cs
- COM2PictureConverter.cs
- BaseValidator.cs
- GrammarBuilderWildcard.cs
- InfoCardTraceRecord.cs
- ErrorStyle.cs
- DefaultTextStoreTextComposition.cs
- ProxyAttribute.cs
- GridViewPageEventArgs.cs
- ImageCodecInfoPrivate.cs
- CreatingCookieEventArgs.cs
- FlowLayoutPanel.cs
- ActivityBindForm.Designer.cs
- NamedPipeWorkerProcess.cs
- DescendantBaseQuery.cs
- TextRangeEditTables.cs
- _NegoStream.cs
- MenuItemCollection.cs
- LicenseManager.cs
- ExtensionDataObject.cs
- GenericUI.cs
- RadioButtonList.cs
- FragmentQuery.cs
- ISFTagAndGuidCache.cs
- PeerName.cs
- DataViewListener.cs
- ScrollEventArgs.cs
- RoutedPropertyChangedEventArgs.cs
- IPAddress.cs
- AuthenticationSection.cs
- Select.cs