Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / System / Windows / Controls / TabControl.cs / 1305600 / TabControl.cs
//---------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation. All rights reserved. // //--------------------------------------------------------------------------- using System.ComponentModel; using System.Collections; using System.Collections.Specialized; using System.Diagnostics; using System.Globalization; using System.Windows.Threading; using System.Windows.Data; using System.Windows.Input; using System.Windows; using System.Windows.Automation.Peers; using System.Windows.Media; using System.Windows.Controls.Primitives; using System.Windows.Markup; using MS.Utility; using System; namespace System.Windows.Controls { ////// TabControl allows a developer to arrange visual content in a compacted and organized form. /// The real-world analog of the control might be a tabbed notebook, /// in which visual content is displayed in discreet pages which are accessed /// by selecting the appropriate tab. Each tab/page is encapsulated by a TabItem, /// the generated item of TabControl. /// A TabItem has a Header property which corresponds to the content in the tab button /// and a Content property which corresponds to the content in the tab page. /// This control is useful for minimizing screen space usage while allowing an application to expose a large amount of data. /// The user navigates through TabItems by clicking on a tab button using the mouse or by using the keyboard. /// [StyleTypedProperty(Property = "ItemContainerStyle", StyleTargetType = typeof(TabItem))] [TemplatePart(Name = "PART_SelectedContentHost", Type = typeof(ContentPresenter))] public class TabControl : Selector { #region Constructors static TabControl() { DefaultStyleKeyProperty.OverrideMetadata(typeof(TabControl), new FrameworkPropertyMetadata(typeof(TabControl))); _dType = DependencyObjectType.FromSystemTypeInternal(typeof(TabControl)); IsTabStopProperty.OverrideMetadata(typeof(TabControl), new FrameworkPropertyMetadata(MS.Internal.KnownBoxes.BooleanBoxes.FalseBox)); KeyboardNavigation.DirectionalNavigationProperty.OverrideMetadata(typeof(TabControl), new FrameworkPropertyMetadata(KeyboardNavigationMode.Contained)); IsEnabledProperty.OverrideMetadata(typeof(TabControl), new UIPropertyMetadata(new PropertyChangedCallback(OnVisualStatePropertyChanged))); } ////// Default TabControl constructor /// ////// Automatic determination of current Dispatcher. Use alternative constructor /// that accepts a Dispatcher for best performance. /// public TabControl() : base() { } #endregion #region Properties ////// The DependencyProperty for the TabStripPlacement property. /// Flags: None /// Default Value: Dock.Top /// public static readonly DependencyProperty TabStripPlacementProperty = DependencyProperty.Register( "TabStripPlacement", typeof(Dock), typeof(TabControl), new FrameworkPropertyMetadata( Dock.Top, new PropertyChangedCallback(OnTabStripPlacementPropertyChanged)), new ValidateValueCallback(DockPanel.IsValidDock)); // When TabControl TabStripPlacement is changing we need to invalidate its TabItem TabStripPlacement private static void OnTabStripPlacementPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { TabControl tc = (TabControl)d; ItemCollection tabItemCollection = tc.Items; for (int i = 0; i < tabItemCollection.Count; i++) { TabItem ti = tc.ItemContainerGenerator.ContainerFromIndex(i) as TabItem; if (ti != null) ti.CoerceValue(TabItem.TabStripPlacementProperty); } } ////// TabStripPlacement specify how tab headers align relatively to content /// [Bindable(true), Category("Behavior")] public Dock TabStripPlacement { get { return (Dock)GetValue(TabStripPlacementProperty); } set { SetValue(TabStripPlacementProperty, value); } } private static readonly DependencyPropertyKey SelectedContentPropertyKey = DependencyProperty.RegisterReadOnly("SelectedContent", typeof(object), typeof(TabControl), new FrameworkPropertyMetadata((object)null)); ////// The DependencyProperty for the SelectedContent property. /// Flags: None /// Default Value: null /// public static readonly DependencyProperty SelectedContentProperty = SelectedContentPropertyKey.DependencyProperty; ////// SelectedContent is the Content of current SelectedItem. /// This property is updated whenever the selection is changed. /// It always keeps a reference to active TabItem.Content /// Used for aliasing in default TabControl Style /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public object SelectedContent { get { return GetValue(SelectedContentProperty); } internal set { SetValue(SelectedContentPropertyKey, value); } } private static readonly DependencyPropertyKey SelectedContentTemplatePropertyKey = DependencyProperty.RegisterReadOnly("SelectedContentTemplate", typeof(DataTemplate), typeof(TabControl), new FrameworkPropertyMetadata((DataTemplate)null)); ////// The DependencyProperty for the SelectedContentTemplate property. /// Flags: None /// Default Value: null /// public static readonly DependencyProperty SelectedContentTemplateProperty = SelectedContentTemplatePropertyKey.DependencyProperty; ////// SelectedContentTemplate is the ContentTemplate of current SelectedItem. /// This property is updated whenever the selection is changed. /// It always keeps a reference to active TabItem.ContentTemplate /// It is used for aliasing in default TabControl Style /// ///[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public DataTemplate SelectedContentTemplate { get { return (DataTemplate)GetValue(SelectedContentTemplateProperty); } internal set { SetValue(SelectedContentTemplatePropertyKey, value); } } private static readonly DependencyPropertyKey SelectedContentTemplateSelectorPropertyKey = DependencyProperty.RegisterReadOnly("SelectedContentTemplateSelector", typeof(DataTemplateSelector), typeof(TabControl), new FrameworkPropertyMetadata((DataTemplateSelector)null)); /// /// The DependencyProperty for the SelectedContentTemplateSelector property. /// Flags: None /// Default Value: null /// public static readonly DependencyProperty SelectedContentTemplateSelectorProperty = SelectedContentTemplateSelectorPropertyKey.DependencyProperty; ////// SelectedContentTemplateSelector allows the app writer to provide custom style selection logic. /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public DataTemplateSelector SelectedContentTemplateSelector { get { return (DataTemplateSelector)GetValue(SelectedContentTemplateSelectorProperty); } internal set { SetValue(SelectedContentTemplateSelectorPropertyKey, value); } } private static readonly DependencyPropertyKey SelectedContentStringFormatPropertyKey = DependencyProperty.RegisterReadOnly("SelectedContentStringFormat", typeof(String), typeof(TabControl), new FrameworkPropertyMetadata((String)null)); ////// The DependencyProperty for the SelectedContentStringFormat property. /// Flags: None /// Default Value: null /// public static readonly DependencyProperty SelectedContentStringFormatProperty = SelectedContentStringFormatPropertyKey.DependencyProperty; ////// ContentStringFormat is the format used to display the content of /// the control as a string. This arises only when no template is /// available. /// public String SelectedContentStringFormat { get { return (String) GetValue(SelectedContentStringFormatProperty); } internal set { SetValue(SelectedContentStringFormatPropertyKey, value); } } ////// The DependencyProperty for the ContentTemplate property. /// Flags: None /// Default Value: null /// public static readonly DependencyProperty ContentTemplateProperty = DependencyProperty.Register("ContentTemplate", typeof(DataTemplate), typeof(TabControl), new FrameworkPropertyMetadata((DataTemplate)null)); ////// ContentTemplate is the ContentTemplate to apply to TabItems /// that do not have the ContentTemplate or ContentTemplateSelector properties /// defined /// ///public DataTemplate ContentTemplate { get { return (DataTemplate)GetValue(ContentTemplateProperty); } set { SetValue(ContentTemplateProperty, value); } } /// /// The DependencyProperty for the ContentTemplateSelector property. /// Flags: None /// Default Value: null /// public static readonly DependencyProperty ContentTemplateSelectorProperty = DependencyProperty.Register("ContentTemplateSelector", typeof(DataTemplateSelector), typeof(TabControl), new FrameworkPropertyMetadata((DataTemplateSelector)null)); ////// ContentTemplateSelector allows the app writer to provide custom style selection logic. /// public DataTemplateSelector ContentTemplateSelector { get { return (DataTemplateSelector)GetValue(ContentTemplateSelectorProperty); } set { SetValue(ContentTemplateSelectorProperty, value); } } ////// The DependencyProperty for the ContentStringFormat property. /// Flags: None /// Default Value: null /// public static readonly DependencyProperty ContentStringFormatProperty = DependencyProperty.Register( "ContentStringFormat", typeof(String), typeof(TabControl), new FrameworkPropertyMetadata((String) null)); ////// ContentStringFormat is the format used to display the content of /// the control as a string. This arises only when no template is /// available. /// public String ContentStringFormat { get { return (String) GetValue(ContentStringFormatProperty); } set { SetValue(ContentStringFormatProperty, value); } } #endregion #region Overrided Methods internal override void ChangeVisualState(bool useTransitions) { if (!IsEnabled) { VisualStates.GoToState(this, useTransitions, VisualStates.StateDisabled, VisualStates.StateNormal); } else { VisualStateManager.GoToState(this, VisualStates.StateNormal, useTransitions); } base.ChangeVisualState(useTransitions); } ////// Creates AutomationPeer ( protected override AutomationPeer OnCreateAutomationPeer() { return new TabControlAutomationPeer(this); } ///) /// /// This virtual method in called when IsInitialized is set to true and it raises an Initialized event /// protected override void OnInitialized(EventArgs e) { base.OnInitialized(e); CanSelectMultiple = false; ItemContainerGenerator.StatusChanged += new EventHandler(OnGeneratorStatusChanged); } ////// Called when the Template's tree has been generated. When Template gets expanded we ensure that SelectedContent is in [....] /// public override void OnApplyTemplate() { base.OnApplyTemplate(); UpdateSelectedContent(); } ////// A virtual function that is called when the selection is changed. Default behavior /// is to raise a SelectionChangedEvent /// /// The inputs for this event. Can be raised (default behavior) or processed /// in some other way. protected override void OnSelectionChanged(SelectionChangedEventArgs e) { base.OnSelectionChanged(e); if (IsKeyboardFocusWithin) { // If keyboard focus is within the control, make sure it is going to the correct place TabItem item = GetSelectedTabItem(); if (item != null) { item.SetFocus(); } } UpdateSelectedContent(); if ( AutomationPeer.ListenerExists(AutomationEvents.SelectionPatternOnInvalidated) || AutomationPeer.ListenerExists(AutomationEvents.SelectionItemPatternOnElementSelected) || AutomationPeer.ListenerExists(AutomationEvents.SelectionItemPatternOnElementAddedToSelection) || AutomationPeer.ListenerExists(AutomationEvents.SelectionItemPatternOnElementRemovedFromSelection) ) { TabControlAutomationPeer peer = UIElementAutomationPeer.CreatePeerForElement(this) as TabControlAutomationPeer; if (peer != null) peer.RaiseSelectionEvents(e); } } ////// Updates the current selection when Items has changed /// /// Information about what has changed protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e) { base.OnItemsChanged(e); if (e.Action == NotifyCollectionChangedAction.Remove && SelectedIndex == -1) { // If we remove the selected item we should select the previous item int startIndex = e.OldStartingIndex + 1; if (startIndex > Items.Count) startIndex = 0; TabItem nextTabItem = FindNextTabItem(startIndex, -1); if (nextTabItem != null) nextTabItem.SetCurrentValueInternal(TabItem.IsSelectedProperty, MS.Internal.KnownBoxes.BooleanBoxes.TrueBox); } } ////// This is the method that responds to the KeyDown event. /// /// protected override void OnKeyDown(KeyEventArgs e) { TabItem nextTabItem = null; // Handle [Ctrl][Shift]Tab, Home and End cases // We have special handling here because if focus is inside the TabItem content we cannot // cycle through TabItem because the content is not part of the TabItem visual tree int direction = 0; int startIndex = -1; switch (e.Key) { case Key.Tab: if ((e.KeyboardDevice.Modifiers & ModifierKeys.Control) == ModifierKeys.Control) { startIndex = ItemContainerGenerator.IndexFromContainer(ItemContainerGenerator.ContainerFromItem(SelectedItem)); if ((e.KeyboardDevice.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift) direction = -1; else direction = 1; } break; case Key.Home: direction = 1; startIndex = -1; break; case Key.End: direction = -1; startIndex = Items.Count; break; } nextTabItem = FindNextTabItem(startIndex, direction); if (nextTabItem != null && nextTabItem != SelectedItem) { e.Handled = nextTabItem.SetFocus(); } if (!e.Handled) base.OnKeyDown(e); } private TabItem FindNextTabItem(int startIndex, int direction) { TabItem nextTabItem = null; if (direction != 0) { int index = startIndex; for (int i = 0; i < Items.Count; i++) { index += direction; if (index >= Items.Count) index = 0; else if (index < 0) index = Items.Count - 1; TabItem tabItem = ItemContainerGenerator.ContainerFromIndex(index) as TabItem; if (tabItem != null && tabItem.IsEnabled && tabItem.Visibility == Visibility.Visible) { nextTabItem = tabItem; break; } } } return nextTabItem; } ////// Return true if the item is (or is eligible to be) its own ItemUI /// protected override bool IsItemItsOwnContainerOverride(object item) { return (item is TabItem); } ///Create or identify the element used to display the given item. protected override DependencyObject GetContainerForItemOverride() { return new TabItem(); } #endregion #region private helpers internal ContentPresenter SelectedContentPresenter { get { return GetTemplateChild(SelectedContentHostTemplateName) as ContentPresenter; } } private void OnGeneratorStatusChanged(object sender, EventArgs e) { if (ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated) { if (HasItems && _selectedItems.Count == 0) { SetCurrentValueInternal(SelectedIndexProperty, 0); } UpdateSelectedContent(); } } private TabItem GetSelectedTabItem() { object selectedItem = SelectedItem; if (selectedItem != null) { // Check if the selected item is a TabItem TabItem tabItem = selectedItem as TabItem; if (tabItem == null) { // It is a data item, get its TabItem container tabItem = ItemContainerGenerator.ContainerFromIndex(SelectedIndex) as TabItem; // Due to event leapfrogging, we may have the wrong container. // If so, re-fetch the right container using a more expensive method. // (BTW, the previous line will cause a debug assert in this case) [Dev10 452711] if (tabItem != null && !Object.Equals(selectedItem, ItemContainerGenerator.ItemFromContainer(tabItem))) { tabItem = ItemContainerGenerator.ContainerFromItem(selectedItem) as TabItem; } } return tabItem; } return null; } // When selection is changed we need to copy the active TabItem content in SelectedContent property // SelectedContent is aliased in the TabControl style private void UpdateSelectedContent() { if (SelectedIndex < 0) { SelectedContent = null; SelectedContentTemplate = null; SelectedContentTemplateSelector = null; SelectedContentStringFormat = null; return; } TabItem tabItem = GetSelectedTabItem(); if (tabItem != null) { FrameworkElement visualParent = VisualTreeHelper.GetParent(tabItem) as FrameworkElement; if (visualParent != null) { KeyboardNavigation.SetTabOnceActiveElement(visualParent, tabItem); KeyboardNavigation.SetTabOnceActiveElement(this, visualParent); } SelectedContent = tabItem.Content; ContentPresenter scp = SelectedContentPresenter; if (scp != null) { scp.HorizontalAlignment = tabItem.HorizontalContentAlignment; scp.VerticalAlignment = tabItem.VerticalContentAlignment; } // Use tabItem's template or selector if specified, otherwise use TabControl's if (tabItem.ContentTemplate != null || tabItem.ContentTemplateSelector != null || tabItem.ContentStringFormat != null) { SelectedContentTemplate = tabItem.ContentTemplate; SelectedContentTemplateSelector = tabItem.ContentTemplateSelector; SelectedContentStringFormat = tabItem.ContentStringFormat; } else { SelectedContentTemplate = ContentTemplate; SelectedContentTemplateSelector = ContentTemplateSelector; SelectedContentStringFormat = ContentStringFormat; } } } #endregion private helpers #region private data // Part name used in the style. The class TemplatePartAttribute should use the same name private const string SelectedContentHostTemplateName = "PART_SelectedContentHost"; #endregion #region DTypeThemeStyleKey // Returns the DependencyObjectType for the registered ThemeStyleKey's default // value. Controls will override this method to return approriate types. internal override DependencyObjectType DTypeThemeStyleKey { get { return _dType; } } private static DependencyObjectType _dType; #endregion DTypeThemeStyleKey } } // 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
- HideDisabledControlAdapter.cs
- XPathEmptyIterator.cs
- SEHException.cs
- DragDeltaEventArgs.cs
- EntitySetBase.cs
- NullableIntAverageAggregationOperator.cs
- CodeSubDirectory.cs
- PhysicalAddress.cs
- StatusBarAutomationPeer.cs
- X509Extension.cs
- SocketPermission.cs
- AdornerDecorator.cs
- KnowledgeBase.cs
- HtmlLink.cs
- PageCopyCount.cs
- XmlCountingReader.cs
- DataControlButton.cs
- Matrix.cs
- ErrorView.xaml.cs
- DbTransaction.cs
- XmlIlVisitor.cs
- XmlNodeWriter.cs
- MediaScriptCommandRoutedEventArgs.cs
- DictionaryBase.cs
- HostedAspNetEnvironment.cs
- odbcmetadatafactory.cs
- BaseTemplateParser.cs
- CqlGenerator.cs
- ArrayExtension.cs
- RightsManagementEncryptedStream.cs
- CollectionChangedEventManager.cs
- PackageDigitalSignatureManager.cs
- FileDialog_Vista.cs
- IRCollection.cs
- AccessedThroughPropertyAttribute.cs
- BindingContext.cs
- ContainerUtilities.cs
- HotCommands.cs
- coordinatorscratchpad.cs
- HttpRequestWrapper.cs
- DataColumnPropertyDescriptor.cs
- DoubleSumAggregationOperator.cs
- WebPartDisplayModeEventArgs.cs
- CopyEncoder.cs
- ModifierKeysValueSerializer.cs
- CommandHelper.cs
- SQLByte.cs
- PageCatalogPart.cs
- ReadOnlyDataSourceView.cs
- BamlLocalizabilityResolver.cs
- PassportPrincipal.cs
- FileLogRecordHeader.cs
- HttpCapabilitiesBase.cs
- CompiledScopeCriteria.cs
- _CommandStream.cs
- ComplexBindingPropertiesAttribute.cs
- LocalizedNameDescriptionPair.cs
- GridSplitter.cs
- AnonymousIdentificationSection.cs
- DataServiceKeyAttribute.cs
- MetadataStore.cs
- XmlIlGenerator.cs
- SecurityHelper.cs
- DataGridViewColumnEventArgs.cs
- ManagementObject.cs
- AnimationTimeline.cs
- QueryableDataSourceView.cs
- InstanceCreationEditor.cs
- TableLayoutSettingsTypeConverter.cs
- ObjectCacheSettings.cs
- PropertyPushdownHelper.cs
- DictionaryManager.cs
- XmlSchemaNotation.cs
- WriteTimeStream.cs
- SchemaManager.cs
- GC.cs
- NetWebProxyFinder.cs
- TextChangedEventArgs.cs
- RoleManagerModule.cs
- TemplateEditingVerb.cs
- MLangCodePageEncoding.cs
- NetMsmqBinding.cs
- ApplicationId.cs
- UrlPath.cs
- Source.cs
- SplitterDesigner.cs
- ImageMetadata.cs
- ProxyGenerator.cs
- BoolExpressionVisitors.cs
- BuildResult.cs
- SimpleApplicationHost.cs
- TextProperties.cs
- SiteMapNodeItem.cs
- FormsAuthenticationTicket.cs
- DeviceSpecificChoiceCollection.cs
- X509CertificateStore.cs
- safex509handles.cs
- SecurityContextSecurityTokenAuthenticator.cs
- LocalizabilityAttribute.cs
- DetailsViewDeletedEventArgs.cs