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
- EntityClassGenerator.cs
- ZipIORawDataFileBlock.cs
- RuleRef.cs
- TypeDependencyAttribute.cs
- WebPartCollection.cs
- ToolStripPanel.cs
- followingquery.cs
- ReaderWriterLockSlim.cs
- Baml2006ReaderContext.cs
- CompensatableTransactionScopeActivity.cs
- BitmapInitialize.cs
- DBAsyncResult.cs
- CodeSnippetCompileUnit.cs
- TemplateField.cs
- InvalidCommandTreeException.cs
- ValidateNames.cs
- InputLanguageSource.cs
- HealthMonitoringSectionHelper.cs
- TextParagraphCache.cs
- WebPartHeaderCloseVerb.cs
- HtmlInputHidden.cs
- CellParaClient.cs
- UpdatePanelTrigger.cs
- AssemblyAssociatedContentFileAttribute.cs
- SamlConstants.cs
- WebPartZone.cs
- OdbcConnectionOpen.cs
- EUCJPEncoding.cs
- ProfileParameter.cs
- input.cs
- HTMLTagNameToTypeMapper.cs
- TimeEnumHelper.cs
- _CacheStreams.cs
- X509ThumbprintKeyIdentifierClause.cs
- RelationshipDetailsRow.cs
- TextParagraphView.cs
- MDIClient.cs
- TextProperties.cs
- PeerNameRecord.cs
- TypeDescriptorContext.cs
- PolicyValidationException.cs
- RayHitTestParameters.cs
- TemplatedMailWebEventProvider.cs
- EncodingTable.cs
- HtmlInputRadioButton.cs
- MaskedTextBox.cs
- UpdateManifestForBrowserApplication.cs
- TextBox.cs
- Debug.cs
- LogWriteRestartAreaAsyncResult.cs
- RangeBase.cs
- BypassElement.cs
- mda.cs
- XmlException.cs
- validationstate.cs
- XPathExpr.cs
- ScrollItemPattern.cs
- TargetParameterCountException.cs
- InteropAutomationProvider.cs
- DbCommandTree.cs
- SQLInt64Storage.cs
- CheckPair.cs
- InheritanceContextHelper.cs
- Error.cs
- ContextMenuAutomationPeer.cs
- CustomPopupPlacement.cs
- WebPartRestoreVerb.cs
- TextTrailingWordEllipsis.cs
- TextModifier.cs
- SystemNetworkInterface.cs
- InvokePatternIdentifiers.cs
- SynchronizationContext.cs
- LinqDataSource.cs
- PropagatorResult.cs
- PageAsyncTaskManager.cs
- MatrixAnimationUsingKeyFrames.cs
- EditingScopeUndoUnit.cs
- XmlUtil.cs
- UxThemeWrapper.cs
- XPathParser.cs
- ValidationHelpers.cs
- Point.cs
- SoapConverter.cs
- LongValidator.cs
- LocatorBase.cs
- ObjectDataSourceMethodEventArgs.cs
- PerformanceCounterPermissionAttribute.cs
- MembershipPasswordException.cs
- AdRotatorDesigner.cs
- SqlDependencyListener.cs
- ResourcePool.cs
- SQLString.cs
- TextEditorDragDrop.cs
- Tool.cs
- CallSiteHelpers.cs
- sqlnorm.cs
- SecurityAlgorithmSuiteConverter.cs
- FormatterServices.cs
- Debug.cs
- HtmlString.cs