Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Framework / System / Windows / Controls / TabControl.cs / 1 / 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)); } ////// 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); } } ////// 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); } } #endregion #region Overrided Methods ////// 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 sync /// 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.IsSelected = true; } } ////// 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) { SelectedIndex = 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; } 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; 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) { SelectedContentTemplate = tabItem.ContentTemplate; SelectedContentTemplateSelector = tabItem.ContentTemplateSelector; } else { SelectedContentTemplate = ContentTemplate; SelectedContentTemplateSelector = ContentTemplateSelector; } } } #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
- PrinterUnitConvert.cs
- LambdaCompiler.Lambda.cs
- SimpleHandlerBuildProvider.cs
- TypeContext.cs
- SchemaTableColumn.cs
- DotExpr.cs
- AnnotationResource.cs
- PersonalizationState.cs
- RtType.cs
- SimpleTypeResolver.cs
- ServiceManager.cs
- HtmlSelect.cs
- AuthenticationModulesSection.cs
- CounterSampleCalculator.cs
- SystemBrushes.cs
- CheckBoxPopupAdapter.cs
- ResourceReferenceExpression.cs
- TriState.cs
- MouseActionValueSerializer.cs
- GenericsNotImplementedException.cs
- AdapterSwitches.cs
- DataRecordObjectView.cs
- CursorInteropHelper.cs
- HashAlgorithm.cs
- PeekCompletedEventArgs.cs
- PageRanges.cs
- EntityDataSourceQueryBuilder.cs
- Control.cs
- AuditLevel.cs
- DataStreamFromComStream.cs
- DefaultValueMapping.cs
- _ProxyChain.cs
- cache.cs
- LoaderAllocator.cs
- RoleServiceManager.cs
- BuilderInfo.cs
- _AutoWebProxyScriptWrapper.cs
- QuinticEase.cs
- TakeQueryOptionExpression.cs
- DefaultConfirmation.cs
- WhitespaceRule.cs
- JsonClassDataContract.cs
- LookupBindingPropertiesAttribute.cs
- QueryResponse.cs
- AsymmetricKeyExchangeDeformatter.cs
- SecurityRuntime.cs
- Soap12FormatExtensions.cs
- MenuItemBinding.cs
- PasswordRecovery.cs
- FormsAuthenticationUser.cs
- LabelLiteral.cs
- panel.cs
- HuffCodec.cs
- BamlBinaryReader.cs
- ActivityExecutionFilter.cs
- MergePropertyDescriptor.cs
- BitmapPalette.cs
- XmlBinaryReaderSession.cs
- Assembly.cs
- TypeUnloadedException.cs
- HealthMonitoringSectionHelper.cs
- DetailsViewUpdateEventArgs.cs
- ProfileSection.cs
- MachineKeySection.cs
- SemanticResolver.cs
- TypeLibConverter.cs
- IPAddress.cs
- DefaultWorkflowSchedulerService.cs
- EditableRegion.cs
- webclient.cs
- RoleGroup.cs
- DesignTimeResourceProviderFactoryAttribute.cs
- PatternMatcher.cs
- AsyncPostBackTrigger.cs
- SqlNodeTypeOperators.cs
- XmlSchemaComplexType.cs
- NextPreviousPagerField.cs
- PeerCollaborationPermission.cs
- SourceInterpreter.cs
- StylusEventArgs.cs
- AddingNewEventArgs.cs
- ProgramPublisher.cs
- RightsManagementInformation.cs
- CommonGetThemePartSize.cs
- TreeNodeMouseHoverEvent.cs
- IndicFontClient.cs
- MachineKeyValidationConverter.cs
- ImageClickEventArgs.cs
- BufferAllocator.cs
- ItemsControlAutomationPeer.cs
- BitVector32.cs
- MenuScrollingVisibilityConverter.cs
- HttpListener.cs
- Error.cs
- WindowsSecurityToken.cs
- OutputCacheSettingsSection.cs
- DispatcherProcessingDisabled.cs
- TdsEnums.cs
- TdsParserHelperClasses.cs
- DetailsViewPagerRow.cs