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
- SchemaMapping.cs
- ValueTable.cs
- SQLBoolean.cs
- MaskDesignerDialog.cs
- SerializationSectionGroup.cs
- TreeBuilderXamlTranslator.cs
- RemotingSurrogateSelector.cs
- SQLMoneyStorage.cs
- MimeWriter.cs
- BreakRecordTable.cs
- XmlElementAttributes.cs
- httpserverutility.cs
- Substitution.cs
- ZipQueryOperator.cs
- XmlSchemaExternal.cs
- baseaxisquery.cs
- ADMembershipProvider.cs
- BookmarkNameHelper.cs
- HttpServerChannel.cs
- InteropEnvironment.cs
- ZeroOpNode.cs
- PassportPrincipal.cs
- DataGrid.cs
- SpecularMaterial.cs
- DataFormat.cs
- MultipartContentParser.cs
- AppSettingsExpressionBuilder.cs
- BinHexEncoding.cs
- FileRecordSequenceHelper.cs
- RequestCachePolicyConverter.cs
- CryptoKeySecurity.cs
- SpeakProgressEventArgs.cs
- PropertyGrid.cs
- SetStoryboardSpeedRatio.cs
- HttpResponseHeader.cs
- PolicyManager.cs
- NextPreviousPagerField.cs
- ByteAnimationBase.cs
- FixedPageStructure.cs
- RawStylusInputCustomData.cs
- ImageAttributes.cs
- ScrollContentPresenter.cs
- ProcessHost.cs
- UserValidatedEventArgs.cs
- SkewTransform.cs
- DecimalConverter.cs
- ItemCollection.cs
- LocalBuilder.cs
- HttpWebRequestElement.cs
- MappingException.cs
- DeclarativeExpressionConditionDeclaration.cs
- DataColumn.cs
- securitycriticaldata.cs
- WebBrowserNavigatedEventHandler.cs
- SimpleMailWebEventProvider.cs
- HttpModuleCollection.cs
- ListSourceHelper.cs
- While.cs
- MemoryMappedFileSecurity.cs
- DataColumnMappingCollection.cs
- EncryptedXml.cs
- handlecollector.cs
- GenericEnumConverter.cs
- EntityParameter.cs
- LinkConverter.cs
- ArgumentOutOfRangeException.cs
- ChannelTraceRecord.cs
- UserControlDocumentDesigner.cs
- ModelUtilities.cs
- FeatureManager.cs
- ErrorEventArgs.cs
- CatalogZone.cs
- DesignerCalendarAdapter.cs
- LocalizationParserHooks.cs
- SqlBooleanMismatchVisitor.cs
- ExceptionRoutedEventArgs.cs
- DataGridViewColumnHeaderCell.cs
- isolationinterop.cs
- WebReferencesBuildProvider.cs
- SystemDiagnosticsSection.cs
- DiagnosticsConfiguration.cs
- DataServiceEntityAttribute.cs
- BufferedOutputStream.cs
- BooleanFunctions.cs
- ModuleConfigurationInfo.cs
- Splitter.cs
- Paragraph.cs
- CatalogZoneBase.cs
- SqlTriggerAttribute.cs
- ParameterEditorUserControl.cs
- WebPartConnectionsEventArgs.cs
- Environment.cs
- SqlSupersetValidator.cs
- HttpBufferlessInputStream.cs
- UserControl.cs
- TimeSpanStorage.cs
- ExtenderProviderService.cs
- WebRequestModuleElementCollection.cs
- CursorEditor.cs
- ResourceAttributes.cs