Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / System / Windows / Controls / DataGridComboBoxColumn.cs / 1305600 / DataGridComboBoxColumn.cs
//---------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation. All rights reserved. // //--------------------------------------------------------------------------- using System; using System.Collections; using System.ComponentModel; using System.Diagnostics; using System.Windows; using System.Windows.Data; using System.Windows.Input; namespace System.Windows.Controls { ////// A column that displays a drop-down list while in edit mode. /// public class DataGridComboBoxColumn : DataGridColumn { #region Constructors static DataGridComboBoxColumn() { SortMemberPathProperty.OverrideMetadata(typeof(DataGridComboBoxColumn), new FrameworkPropertyMetadata(null, OnCoerceSortMemberPath)); } #endregion #region Helper Type for Styling internal class TextBlockComboBox : ComboBox { static TextBlockComboBox() { DefaultStyleKeyProperty.OverrideMetadata(typeof(TextBlockComboBox), new FrameworkPropertyMetadata(DataGridComboBoxColumn.TextBlockComboBoxStyleKey)); KeyboardNavigation.IsTabStopProperty.OverrideMetadata(typeof(TextBlockComboBox), new FrameworkPropertyMetadata(false)); } } ////// Style key for TextBlockComboBox /// public static ComponentResourceKey TextBlockComboBoxStyleKey { get { return SystemResourceKey.DataGridComboBoxColumnTextBlockComboBoxStyleKey; } } #endregion #region Binding private static object OnCoerceSortMemberPath(DependencyObject d, object baseValue) { var column = (DataGridComboBoxColumn)d; var sortMemberPath = (string)baseValue; if (string.IsNullOrEmpty(sortMemberPath)) { var bindingSortMemberPath = DataGridHelper.GetPathFromBinding(column.EffectiveBinding as Binding); if (!string.IsNullOrEmpty(bindingSortMemberPath)) { sortMemberPath = bindingSortMemberPath; } } return sortMemberPath; } ////// Chooses either SelectedItemBinding, TextBinding, SelectedValueBinding or based which are set. /// private BindingBase EffectiveBinding { get { if (SelectedItemBinding != null) { return SelectedItemBinding; } else if (SelectedValueBinding != null) { return SelectedValueBinding; } else { return TextBinding; } } } ////// The binding that will be applied to the SelectedValue property of the ComboBox. This works in conjunction with SelectedValuePath /// ////// This isn't a DP because if it were getting the value would evaluate the binding. /// public virtual BindingBase SelectedValueBinding { get { return _selectedValueBinding; } set { if (_selectedValueBinding != value) { BindingBase oldBinding = _selectedValueBinding; _selectedValueBinding = value; CoerceValue(IsReadOnlyProperty); CoerceValue(SortMemberPathProperty); OnSelectedValueBindingChanged(oldBinding, _selectedValueBinding); } } } protected override bool OnCoerceIsReadOnly(bool baseValue) { if (DataGridHelper.IsOneWay(EffectiveBinding)) { return true; } // only call the base if we dont want to force IsReadOnly true return base.OnCoerceIsReadOnly(baseValue); } ////// The binding that will be applied to the SelectedItem property of the ComboBoxValue. /// ////// This isn't a DP because if it were getting the value would evaluate the binding. /// public virtual BindingBase SelectedItemBinding { get { return _selectedItemBinding; } set { if (_selectedItemBinding != value) { BindingBase oldBinding = _selectedItemBinding; _selectedItemBinding = value; CoerceValue(IsReadOnlyProperty); CoerceValue(SortMemberPathProperty); OnSelectedItemBindingChanged(oldBinding, _selectedItemBinding); } } } ////// The binding that will be applied to the Text property of the ComboBoxValue. /// ////// This isn't a DP because if it were getting the value would evaluate the binding. /// public virtual BindingBase TextBinding { get { return _textBinding; } set { if (_textBinding != value) { BindingBase oldBinding = _textBinding; _textBinding = value; CoerceValue(IsReadOnlyProperty); CoerceValue(SortMemberPathProperty); OnTextBindingChanged(oldBinding, _textBinding); } } } ////// Called when SelectedValueBinding changes. /// /// The old binding. /// The new binding. protected virtual void OnSelectedValueBindingChanged(BindingBase oldBinding, BindingBase newBinding) { NotifyPropertyChanged("SelectedValueBinding"); } ////// Called when SelectedItemBinding changes. /// /// The old binding. /// The new binding. protected virtual void OnSelectedItemBindingChanged(BindingBase oldBinding, BindingBase newBinding) { NotifyPropertyChanged("SelectedItemBinding"); } ////// Called when TextBinding changes. /// /// The old binding. /// The new binding. protected virtual void OnTextBindingChanged(BindingBase oldBinding, BindingBase newBinding) { NotifyPropertyChanged("TextBinding"); } #endregion #region Styling ////// The default value of the ElementStyle property. /// This value can be used as the BasedOn for new styles. /// public static Style DefaultElementStyle { get { if (_defaultElementStyle == null) { Style style = new Style(typeof(ComboBox)); // Set IsSynchronizedWithCurrentItem to false by default style.Setters.Add(new Setter(ComboBox.IsSynchronizedWithCurrentItemProperty, false)); style.Seal(); _defaultElementStyle = style; } return _defaultElementStyle; } } ////// The default value of the EditingElementStyle property. /// This value can be used as the BasedOn for new styles. /// public static Style DefaultEditingElementStyle { get { // return the same as that of DefaultElementStyle return DefaultElementStyle; } } ////// A style that is applied to the generated element when not editing. /// The TargetType of the style depends on the derived column class. /// public Style ElementStyle { get { return (Style)GetValue(ElementStyleProperty); } set { SetValue(ElementStyleProperty, value); } } ////// The DependencyProperty for the ElementStyle property. /// public static readonly DependencyProperty ElementStyleProperty = DataGridBoundColumn.ElementStyleProperty.AddOwner(typeof(DataGridComboBoxColumn), new FrameworkPropertyMetadata(DefaultElementStyle)); ////// A style that is applied to the generated element when editing. /// The TargetType of the style depends on the derived column class. /// public Style EditingElementStyle { get { return (Style)GetValue(EditingElementStyleProperty); } set { SetValue(EditingElementStyleProperty, value); } } ////// The DependencyProperty for the EditingElementStyle property. /// public static readonly DependencyProperty EditingElementStyleProperty = DataGridBoundColumn.EditingElementStyleProperty.AddOwner(typeof(DataGridComboBoxColumn), new FrameworkPropertyMetadata(DefaultEditingElementStyle)); ////// Assigns the ElementStyle to the desired property on the given element. /// private void ApplyStyle(bool isEditing, bool defaultToElementStyle, FrameworkElement element) { Style style = PickStyle(isEditing, defaultToElementStyle); if (style != null) { element.Style = style; } } ////// Assigns the ElementStyle to the desired property on the given element. /// internal void ApplyStyle(bool isEditing, bool defaultToElementStyle, FrameworkContentElement element) { Style style = PickStyle(isEditing, defaultToElementStyle); if (style != null) { element.Style = style; } } private Style PickStyle(bool isEditing, bool defaultToElementStyle) { Style style = isEditing ? EditingElementStyle : ElementStyle; if (isEditing && defaultToElementStyle && (style == null)) { style = ElementStyle; } return style; } ////// Assigns the Binding to the desired property on the target object. /// private static void ApplyBinding(BindingBase binding, DependencyObject target, DependencyProperty property) { if (binding != null) { BindingOperations.SetBinding(target, property, binding); } else { BindingOperations.ClearBinding(target, property); } } #endregion #region Clipboard Copy/Paste ////// If base ClipboardContentBinding is not set we use Binding. /// public override BindingBase ClipboardContentBinding { get { return base.ClipboardContentBinding ?? EffectiveBinding; } set { base.ClipboardContentBinding = value; } } #endregion #region ComboBox Column Properties ////// The ComboBox will attach to this ItemsSource. /// public IEnumerable ItemsSource { get { return (IEnumerable)GetValue(ItemsSourceProperty); } set { SetValue(ItemsSourceProperty, value); } } ////// The DependencyProperty for ItemsSource. /// public static readonly DependencyProperty ItemsSourceProperty = ComboBox.ItemsSourceProperty.AddOwner(typeof(DataGridComboBoxColumn), new FrameworkPropertyMetadata(null, DataGridColumn.NotifyPropertyChangeForRefreshContent)); ////// DisplayMemberPath is a simple way to define a default template /// that describes how to convert Items into UI elements by using /// the specified path. /// public string DisplayMemberPath { get { return (string)GetValue(DisplayMemberPathProperty); } set { SetValue(DisplayMemberPathProperty, value); } } ////// The DependencyProperty for the DisplayMemberPath property. /// public static readonly DependencyProperty DisplayMemberPathProperty = ComboBox.DisplayMemberPathProperty.AddOwner(typeof(DataGridComboBoxColumn), new FrameworkPropertyMetadata(string.Empty, DataGridColumn.NotifyPropertyChangeForRefreshContent)); ////// The path used to retrieve the SelectedValue from the SelectedItem /// public string SelectedValuePath { get { return (string)GetValue(SelectedValuePathProperty); } set { SetValue(SelectedValuePathProperty, value); } } ////// SelectedValuePath DependencyProperty /// public static readonly DependencyProperty SelectedValuePathProperty = ComboBox.SelectedValuePathProperty.AddOwner(typeof(DataGridComboBoxColumn), new FrameworkPropertyMetadata(string.Empty, DataGridColumn.NotifyPropertyChangeForRefreshContent)); #endregion #region Property Changed Handler protected internal override void RefreshCellContent(FrameworkElement element, string propertyName) { DataGridCell cell = element as DataGridCell; if (cell != null) { bool isCellEditing = cell.IsEditing; if ((string.Compare(propertyName, "ElementStyle", StringComparison.Ordinal) == 0 && !isCellEditing) || (string.Compare(propertyName, "EditingElementStyle", StringComparison.Ordinal) == 0 && isCellEditing)) { cell.BuildVisualTree(); } else { ComboBox comboBox = cell.Content as ComboBox; switch (propertyName) { case "SelectedItemBinding": ApplyBinding(SelectedItemBinding, comboBox, ComboBox.SelectedItemProperty); break; case "SelectedValueBinding": ApplyBinding(SelectedValueBinding, comboBox, ComboBox.SelectedValueProperty); break; case "TextBinding": ApplyBinding(TextBinding, comboBox, ComboBox.TextProperty); break; case "SelectedValuePath": DataGridHelper.SyncColumnProperty(this, comboBox, ComboBox.SelectedValuePathProperty, SelectedValuePathProperty); break; case "DisplayMemberPath": DataGridHelper.SyncColumnProperty(this, comboBox, ComboBox.DisplayMemberPathProperty, DisplayMemberPathProperty); break; case "ItemsSource": DataGridHelper.SyncColumnProperty(this, comboBox, ComboBox.ItemsSourceProperty, ItemsSourceProperty); break; default: base.RefreshCellContent(element, propertyName); break; } } } else { base.RefreshCellContent(element, propertyName); } } #endregion #region BindingTarget Helpers ////// Helper method which returns selection value from /// combobox based on which Binding's were set. /// /// ///private object GetComboBoxSelectionValue(ComboBox comboBox) { if (SelectedItemBinding != null) { return comboBox.SelectedItem; } else if (SelectedValueBinding != null) { return comboBox.SelectedValue; } else { return comboBox.Text; } } #endregion #region Element Generation /// /// Creates the visual tree for text based cells. /// protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem) { TextBlockComboBox comboBox = new TextBlockComboBox(); ApplyStyle(/* isEditing = */ false, /* defaultToElementStyle = */ false, comboBox); ApplyColumnProperties(comboBox); return comboBox; } ////// Creates the visual tree for text based cells. /// protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem) { ComboBox comboBox = new ComboBox(); ApplyStyle(/* isEditing = */ true, /* defaultToElementStyle = */ false, comboBox); ApplyColumnProperties(comboBox); return comboBox; } private void ApplyColumnProperties(ComboBox comboBox) { ApplyBinding(SelectedItemBinding, comboBox, ComboBox.SelectedItemProperty); ApplyBinding(SelectedValueBinding, comboBox, ComboBox.SelectedValueProperty); ApplyBinding(TextBinding, comboBox, ComboBox.TextProperty); DataGridHelper.SyncColumnProperty(this, comboBox, ComboBox.SelectedValuePathProperty, SelectedValuePathProperty); DataGridHelper.SyncColumnProperty(this, comboBox, ComboBox.DisplayMemberPathProperty, DisplayMemberPathProperty); DataGridHelper.SyncColumnProperty(this, comboBox, ComboBox.ItemsSourceProperty, ItemsSourceProperty); } #endregion #region Editing ////// Called when a cell has just switched to edit mode. /// /// A reference to element returned by GenerateEditingElement. /// The event args of the input event that caused the cell to go into edit mode. May be null. ///The unedited value of the cell. protected override object PrepareCellForEdit(FrameworkElement editingElement, RoutedEventArgs editingEventArgs) { ComboBox comboBox = editingElement as ComboBox; if (comboBox != null) { comboBox.Focus(); object originalValue = GetComboBoxSelectionValue(comboBox); if (IsComboBoxOpeningInputEvent(editingEventArgs)) { comboBox.IsDropDownOpen = true; } return originalValue; } return null; } internal override void OnInput(InputEventArgs e) { if (IsComboBoxOpeningInputEvent(e)) { BeginEdit(e); } } private static bool IsComboBoxOpeningInputEvent(RoutedEventArgs e) { KeyEventArgs keyArgs = e as KeyEventArgs; if ((keyArgs != null) && ((keyArgs.KeyStates & KeyStates.Down) == KeyStates.Down)) { bool isAltDown = (keyArgs.KeyboardDevice.Modifiers & ModifierKeys.Alt) == ModifierKeys.Alt; // We want to handle the ALT key. Get the real key if it is Key.System. Key key = keyArgs.Key; if (key == Key.System) { key = keyArgs.SystemKey; } // F4 alone or ALT+Up or ALT+Down will open the drop-down return ((key == Key.F4) && !isAltDown) || (((key == Key.Up) || (key == Key.Down)) && isAltDown); } return false; } #endregion #region Data private static Style _defaultElementStyle; private BindingBase _selectedValueBinding; private BindingBase _selectedItemBinding; private BindingBase _textBinding; #endregion } } // 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
- DTCTransactionManager.cs
- MouseCaptureWithinProperty.cs
- ExpressionNode.cs
- FixedSOMPageElement.cs
- CodeAttachEventStatement.cs
- ParsedAttributeCollection.cs
- ToolStripContextMenu.cs
- SqlDataSourceSelectingEventArgs.cs
- TrackingLocation.cs
- SurrogateChar.cs
- InternalConfigSettingsFactory.cs
- listitem.cs
- WithParamAction.cs
- _IPv6Address.cs
- AttributeProviderAttribute.cs
- CompositeFontInfo.cs
- AccessViolationException.cs
- XmlValidatingReaderImpl.cs
- NestedContainer.cs
- ToolStripDropDownClosingEventArgs.cs
- IndexedSelectQueryOperator.cs
- Permission.cs
- HttpWriter.cs
- HyperLinkStyle.cs
- UriSection.cs
- ToolStripScrollButton.cs
- PerspectiveCamera.cs
- TableLayout.cs
- BrushValueSerializer.cs
- ClassHandlersStore.cs
- DbConnectionHelper.cs
- InlineObject.cs
- AffineTransform3D.cs
- IgnoreSectionHandler.cs
- EventHandlerList.cs
- SrgsRule.cs
- WebPartDisplayModeEventArgs.cs
- SecurityContextKeyIdentifierClause.cs
- XamlPathDataSerializer.cs
- WindowInteractionStateTracker.cs
- HwndTarget.cs
- XPathBinder.cs
- PenCursorManager.cs
- TransportSecurityProtocol.cs
- FixedPageStructure.cs
- RoutedEventHandlerInfo.cs
- ItemsPresenter.cs
- JsonReader.cs
- EntityDataSourceQueryBuilder.cs
- XmlSchemaSequence.cs
- ContentHostHelper.cs
- MemberBinding.cs
- DependencyObject.cs
- BoundColumn.cs
- SqlRowUpdatedEvent.cs
- _NtlmClient.cs
- Animatable.cs
- DataListItemCollection.cs
- GenericUriParser.cs
- ProfileInfo.cs
- ActivityBuilder.cs
- ManualResetEventSlim.cs
- AsymmetricAlgorithm.cs
- RecordsAffectedEventArgs.cs
- HttpProfileGroupBase.cs
- TimeSpanStorage.cs
- ServiceOperation.cs
- ServiceModelConfigurationElementCollection.cs
- ReadOnlyState.cs
- EventListener.cs
- TextTreeFixupNode.cs
- BoundsDrawingContextWalker.cs
- TextParagraphCache.cs
- AppDomainManager.cs
- TableCell.cs
- CngKey.cs
- TreeNodeStyleCollection.cs
- RegionIterator.cs
- ControlDesignerState.cs
- PopupEventArgs.cs
- MediaEntryAttribute.cs
- UIElement3DAutomationPeer.cs
- RepeaterCommandEventArgs.cs
- UserPersonalizationStateInfo.cs
- GiveFeedbackEvent.cs
- MenuBase.cs
- TrustLevelCollection.cs
- DisplayNameAttribute.cs
- HashCodeCombiner.cs
- DataServiceRequestArgs.cs
- IntSecurity.cs
- FontInfo.cs
- TcpSocketManager.cs
- EventHandlers.cs
- LayoutUtils.cs
- ChtmlPhoneCallAdapter.cs
- SoapSchemaMember.cs
- DBParameter.cs
- MobileRedirect.cs
- SettingsProperty.cs