From 0c933c81241a893267f5d7c6c8043f74c33cb471 Mon Sep 17 00:00:00 2001 From: emartin_cp Date: Thu, 25 Oct 2012 16:36:10 +0000 Subject: [PATCH] 1.8.0 Release --- .../ExtendedWPFToolkit.sln | 25 + .../Views/HomeView.xaml | 30 +- .../DataGridModule.cs | 46 + .../Properties/AssemblyInfo.cs | 72 + .../Samples.Modules.DataGrid.csproj | 116 + .../Views/FullVersion.xaml | 103 + .../Views/FullVersion.xaml.cs | 46 + .../Views/HomeView.xaml | 54 + .../Views/HomeView.xaml.cs | 47 + .../Views/NavigationView.xaml | 32 + .../Views/NavigationView.xaml.cs} | 18 +- .../Views/HomeView.xaml | 11 +- .../Views/HomeView.xaml | 2 +- .../Views/HomeView.xaml | 126 +- .../Views/HomeView.xaml.cs | 15 +- .../Views/HomeView.xaml | 115 +- .../Samples.Modules.Pie/Views/PieChart.xaml | 1 - .../Views/PieProgress.xaml | 1 - .../Samples.Modules.PropertyGrid.csproj | 19 +- .../Views/DisplayLocalizationRes.Designer.cs | 180 + .../Views/DisplayLocalizationRes.fr.resx | 159 + .../Views/DisplayLocalizationRes.resx | 159 + .../Views/HomeView.xaml | 13 +- .../Views/HomeView.xaml.cs | 6 + .../Samples.Modules.Text.csproj | 7 + .../Samples.Modules.Text/TextModule.cs | 1 + .../Views/AutoSelectTextBoxView.xaml | 118 + .../Views/AutoSelectTextBoxView.xaml.cs} | 20 +- .../Views/MaskedTextBoxView.xaml | 26 +- .../Views/MaskedTextBoxView.xaml.cs | 6 + .../Views/MultiLineTextEditor.xaml | 3 +- .../Views/NavigationView.xaml | 4 +- .../Views/RichTextBoxView.xaml | 3 +- .../Src/Samples/Samples/App.config | 1 + .../Samples/Resources/TreeViewStyles.xaml | 14 + .../Src/Samples/Samples/Samples.csproj | 4 + .../AssemblyVersionInfo.cs | 2 +- .../Implementation/AutoSelectBehaviorEnum.cs | 31 + .../Implementation/AutoSelectTextBox.cs | 301 + .../Implementation/QueryMoveFocusEventArgs.cs | 76 + .../Implementation/CheckComboBox.cs | 22 +- .../ColorCanvas/Implementation/ColorCanvas.cs | 73 +- .../ColorCanvas/Themes/Generic.xaml | 2 +- .../ColorPicker/Implementation/ColorPicker.cs | 2 +- .../WizardPageButtonVisibilityConverter.cs | 4 +- .../Core/Input/IValidateInput.cs | 32 + .../Input/InputValidationErrorEventArgs.cs | 46 + .../Core/Primitives/CachedTextInfo.cs | 57 + .../Core/Primitives/Selector.cs | 557 +- .../Core/Primitives/SelectorItem.cs | 12 +- .../Core/Primitives/UpDownBase.cs | 113 +- .../Core/Primitives/ValueRangeTextBox.cs | 1192 +++ .../Core/QueryTextFromValueEventArgs.cs | 57 + .../Core/QueryValueFromTextEventArgs.cs | 70 + .../Core/Utilities/ColorUtilities.cs | 2 +- .../Utilities/NotifyPropertyChangedHelper.cs | 163 + .../Core/Utilities/ReflectionHelper.cs | 136 + .../Core/Utilities/TreeHelper.cs | 238 + .../Core/Utilities/ValueChangeHelper.cs | 153 + .../DateTimePicker/Themes/Generic.xaml | 10 +- .../Implementation/DateTimeUpDown.cs | 26 +- .../Magnifier/Implementation/Magnifier.cs | 4 +- .../AutoCompletingMaskEventArgs.cs | 108 + .../Implementation/InsertKeyModeEnum.cs | 32 + .../Implementation/MaskFormatEnum.cs | 33 + .../Implementation/MaskedTextBox.cs | 2116 ++++-- .../MessageBox/Implementation/MessageBox.cs | 80 +- .../MessageBox/Themes/Generic.xaml | 43 +- .../Implementation/ByteUpDown.cs | 55 + .../Implementation/CommonNumericUpDown.cs | 184 + .../Implementation/DecimalUpDown.cs | 86 +- .../Implementation/DoubleUpDown.cs | 86 +- .../Implementation/IntegerUpDown.cs | 87 +- .../Implementation/LongUpDown.cs | 55 + .../Implementation/NumericUpDown.cs | 15 - .../Implementation/SByteUpDown.cs | 55 + .../Implementation/ShortUpDown.cs | 55 + .../Implementation/SingleUpDown.cs | 55 + .../Implementation/UIntegerUpDown.cs | 55 + .../Implementation/ULongUpDown.cs | 55 + .../Implementation/UShortUpDown.cs | 55 + .../NumericUpDown/Themes/Generic.xaml | 67 +- .../Implementation/MaskedTextBox.cs | 726 ++ .../Properties/AssemblyInfo.cs | 2 + .../Converters/SelectedObjectConverter.cs | 92 + .../Implementation/Editors/UpDownEditors.cs | 52 + .../Implementation/IPropertyParent.cs | 36 + .../Implementation/PropertyGrid.cs | 344 +- .../Implementation/PropertyGridUtilities.cs | 85 +- .../Implementation/PropertyItem.cs | 282 +- .../Implementation/PropertyItemCollection.cs | 68 +- .../PropertyGrid/Themes/Generic.xaml | 42 +- .../RichTextBox/RichTextBox.cs | 28 +- .../WPFToolkit.Extended.csproj | 42 +- .../(DataVirtualization)/EmptyDataItem.cs | 288 + .../(DataVirtualization)/VirtualList.cs | 956 +++ .../VirtualListEnumerator.cs | 157 + .../VirtualListTableOfContent.cs | 172 + .../(DataVirtualization)/VirtualPage.cs | 658 ++ .../VirtualPageManager.cs | 867 +++ .../VirtualizedItemInfo.cs | 103 + .../VirtualizedItemValueCollection.cs | 156 + .../DataGridForeignKeyDescription.cs | 132 + .../DataTableForeignKeyDescription.cs | 124 + .../(CollectionView)/AsyncCommitInfo.cs | 190 + .../(CollectionView)/AsyncQueryInfo.cs | 339 + .../AsyncQueryInfoWeakComparer.cs | 56 + .../AutoFilterValuesChangedEventArgs.cs | 77 + .../BindingPathValueExtractor.cs | 220 + .../CollectionViewGroupExtensions.cs | 62 + .../(CollectionView)/CommitItemsEvent.cs | 58 + .../CustomDistinctValueItemConfiguration.cs | 74 + ...istinctValueItemConfigurationCollection.cs | 50 + .../CustomDistinctValueItemFilterEventArgs.cs | 53 + .../DataGridCollectionView.cs | 2820 +++++++ .../DataGridCollectionViewBase.cs | 3556 +++++++++ .../DataGridCollectionViewBaseDataProvider.cs | 198 + .../DataGridCollectionViewDataProvider.cs | 98 + .../DataGridCollectionViewEnumerator.cs | 166 + .../DataGridCollectionViewGroup.cs | 915 +++ .../DataGridCollectionViewGroupRoot.cs | 169 + .../DataGridCollectionViewGroupSort.cs | 60 + .../DataGridCollectionViewSort.cs | 87 + .../DataGridCollectionViewSource.cs | 147 + .../DataGridCollectionViewSourceBase.cs | 652 ++ .../DataGridCommittingNewItemEvent.cs | 60 + .../DataGridCreatingNewItemEvent.cs | 87 + .../DataGridDetailDescription.cs | 641 ++ .../DataGridDetailDescriptionCollection.cs | 113 + .../DataGridGroupDescription.cs | 128 + .../(CollectionView)/DataGridGroupInfo.cs | 74 + .../DataGridItemCancelEvent.cs | 56 + .../(CollectionView)/DataGridItemEvent.cs | 63 + .../DataGridItemHandledEvent.cs | 54 + ...erty.PropertyDescriptorFromItemProperty.cs | 71 + .../(CollectionView)/DataGridItemProperty.cs | 674 ++ ....PropertyDescriptorFromItemPropertyBase.cs | 120 + .../DataGridItemPropertyBase.cs | 771 ++ .../DataGridItemPropertyCollection.cs | 417 ++ .../DataGridItemPropertyCommittingValue.cs | 38 + .../DataGridItemPropertyDictionary.cs | 50 + .../DataGridItemPropertyQueryValueEvent.cs} | 20 +- .../DataGridItemRemovedEvent.cs | 46 + .../DataGridLINQPageManager.cs | 174 + .../(CollectionView)/DataGridPageManager.cs | 106 + .../DataGridPageManagerBase.cs | 587 ++ .../DataGridRemovingItemEvent.cs | 46 + .../DataGridSortDescriptionCollection.cs | 134 + .../DataGridUnboundItemProperty.cs | 156 + .../DataGridVirtualizingCollectionView.cs | 214 + .../DataGridVirtualizingCollectionViewBase.cs | 937 +++ ...dVirtualizingCollectionViewDataProvider.cs | 56 + ...DataGridVirtualizingCollectionViewGroup.cs | 148 + ...GridVirtualizingCollectionViewGroupBase.cs | 500 ++ ...GridVirtualizingCollectionViewGroupRoot.cs | 82 + ...ataGridVirtualizingCollectionViewSource.cs | 98 + ...ridVirtualizingCollectionViewSourceBase.cs | 166 + ...GridVirtualizingQueryableCollectionView.cs | 133 + ...zingQueryableCollectionViewDataProvider.cs | 57 + ...irtualizingQueryableCollectionViewGroup.cs | 286 + ...alizingQueryableCollectionViewGroupRoot.cs | 306 + ...rtualizingQueryableCollectionViewSource.cs | 85 + .../DataRelationDetailDescription.cs | 143 + .../DataRowColumnPropertyDescriptor.cs | 183 + .../(CollectionView)/DeferredOperation.cs | 219 + .../DeferredOperationManager.cs | 572 ++ .../DistinctValuesDictionary.cs | 82 + .../EmptyDataItemSafePropertyDescriptor.cs | 107 + .../EntityDetailDescription.cs | 121 + .../EnumerableDetailDescription.cs | 47 + .../GroupDescriptionCollection.cs | 92 + .../(CollectionView)/GroupNameCountPair.cs | 44 + .../(CollectionView)/GroupSortComparer.cs | 132 + .../JaggedArrayPropertyDescriptor.cs | 119 + .../ListSourceDetailDescription.cs | 50 + .../OptimizedReadOnlyObservableCollection.cs | 72 + .../PropertyDetailDescription.cs | 245 + .../PropertyRelationAttribute.cs | 31 + .../QueryAutoFilterDistinctValuesEvent.cs | 58 + .../QueryDistinctValueEventArgs.cs | 50 + .../QueryEntityDetailsEventArgs.cs | 64 + .../(CollectionView)/QueryGroupsEventArgs.cs | 151 + .../(CollectionView)/QueryItemCountEvent.cs | 93 + .../(CollectionView)/QueryItemsEvent.cs | 98 + .../(CollectionView)/QueryableExtensions.cs | 754 ++ .../(CollectionView)/RawItem.cs | 107 + .../(CollectionView)/RawItemIndexComparer.cs | 61 + .../(CollectionView)/RawItemSortComparer.cs | 127 + .../SelfPropertyDescriptor.cs | 105 + .../SortDescriptionsSyncContext.cs | 69 + .../(CollectionView)/SortedDescriptionInfo.cs | 120 + .../(CollectionView)/SourceItemCollection.cs | 242 + .../(CollectionView)/StatResultComparer.cs | 81 + .../(CollectionView)/UnboundDataItem.cs | 244 + .../UnboundDataRowPropertyDescriptor.cs | 144 + .../DataTableForeignKeyConverter.cs | 131 + .../(ForeignKeys)/ForeignKeyConfiguration.cs | 556 ++ .../(ForeignKeys)/ForeignKeyContentControl.cs | 242 + .../(ForeignKeys)/ForeignKeyConverter.cs | 52 + .../ForeignKeyGroupContentControl.cs | 210 + .../ForeignKeyScrollTipContentControl.cs | 170 + .../(Generator)/CollectionGeneratorNode.cs | 55 + .../ColumnActualWidthChangedHandler.cs | 66 + .../ColumnActualWidthEventManager.cs | 77 + .../(Generator)/ContainersRemovedEventArgs.cs | 51 + .../CurrentColumnChangedEventManager.cs | 77 + .../CustomGeneratorChangedEventArgs.cs | 131 + .../CustomItemContainerGenerator.cs | 6575 +++++++++++++++++ .../(Generator)/DetailGeneratorNode.cs | 85 + .../DistinctValuesRequestedEventArgs.cs | 56 + .../DistinctValuesRequestedEventManager.cs | 77 + .../(Generator)/ExpansionStateEventArgs.cs | 61 + .../(Generator)/GeneratorNode.cs | 155 + .../(Generator)/GeneratorNodeFactory.cs | 407 + .../(Generator)/GeneratorNodeHelper.cs | 1106 +++ .../(Generator)/GroupGeneratorNode.cs | 295 + .../(Generator)/GroupHeaderFooterItem.cs | 125 + .../GroupHeaderFooterItemTemplate.cs | 69 + .../(Generator)/GroupNamesTreeKey.cs | 97 + .../HeadersFootersGeneratorNode.cs | 358 + .../ICustomItemContainerGenerator.cs | 47 + .../IInhibitGenPosToIndexUpdating.cs | 31 + .../(Generator)/ItemContextVisitor.cs | 136 + .../(Generator)/ItemsGeneratorNode.cs | 330 + .../NamesTreeGroupFinderVisitor.cs | 94 + .../NotifyCollectionChangedGeneratorNode.cs | 42 + .../(Generator)/RangeSelectionVisitor.cs | 104 + .../RealizedContainersRequestedEventArgs.cs | 40 + ...RealizedContainersRequestedEventManager.cs | 77 + .../SaveRestoreDataGridContextStateVisitor.cs | 247 + .../SaveRestoreGlobalStateVisitor.cs | 124 + .../(Generator)/SaveRestoreStateVisitor.cs | 322 + .../(Generator)/SelectAllVisitor.cs | 126 + .../StickyContainerGeneratedComparer.cs | 55 + ...StickyContainerGeneratedReverseComparer.cs | 55 + .../StickyContainerGeneratedStruct.cs | 86 + .../VisibilityChangedEventManager.cs | 77 + .../VisibleColumnsUpdatedEventManager.cs | 77 + .../(Generator)/WeakDataGridContextKey.cs | 135 + .../(enums)/AutoFilterModeEnum.cs | 33 + .../CellEditorDisplayConditionsEnum.cs | 36 + .../(enums)/ColumnWidthUnitTypeEnum.cs | 29 + .../(enums)/CommitModeEnum.cs | 31 + .../(enums)/CompareResultEnum.cs | 31 + .../(enums)/ConnectionLineAlignmentEnum.cs | 34 + .../(enums)/DataGridConnectionStateEnum.cs | 33 + .../(enums)/DataGridContextVisitorTypeEnum.cs | 37 + .../DataGridUpdateSourceTriggerEnum.cs | 33 + .../DeletingSelectedItemErrorActionEnum.cs | 33 + .../(enums)/DistinctValuesConstraintEnum.cs | 31 + .../(enums)/DistinctValuesUpdateModeEnum.cs | 32 + .../(enums)/DropMarkAlignmentEnum.cs | 30 + .../(enums)/EditTriggersEnum.cs | 37 + .../(enums)/FilterCriteriaModeEnum.cs | 30 + .../(enums)/FilterOperatorPrecedenceEnum.cs | 53 + .../(enums)/FilterTokenPriorityEnum.cs | 54 + .../(enums)/GeneratorNodeTypeEnum.cs | 32 + .../(enums)/InsertionModeEnum.cs | 32 + .../(enums)/ItemScrollingBehaviorEnum.cs | 29 + .../(enums)/NavigationBehaviorEnum.cs | 33 + .../(enums)/PagingBehaviorEnum.cs | 29 + .../(enums)/PrimaryAxisEnum.cs | 31 + .../(enums)/ScrollDirectionEnum.cs | 33 + .../(enums)/ScrollOrientationEnum.cs | 31 + .../(enums)/SelectionUnitEnum.cs | 32 + .../(enums)/SortDirectionEnum.cs | 30 + .../(enums)/ValidationModeEnum.cs | 29 + .../Xceed.Wpf.DataGrid/ActivationGesture.cs | 16 +- .../ActivationGestureCollection.cs | 31 + .../AddingNewDataItemEvent.cs | 50 + .../AllowDetailToggleChangedEventManager.cs | 103 + .../Xceed.Wpf.DataGrid/AssemblyVersionInfo.cs | 44 + .../AssemblyVersionInfoCommon.cs | 25 + .../Automation/AutomationPeerExtensions.cs | 184 + .../Automation/AutomationQueryEvents.cs | 260 + .../Automation/CellAutomationPeer.cs | 170 + .../ColumnManagerCellAutomationPeer.cs | 157 + .../ColumnManagerRowAutomationPeer.cs | 53 + .../DataGridContextAutomationPeer.cs | 1290 ++++ .../DataGridControlAutomationPeer.cs | 117 + .../Automation/DataGridGroupAutomationPeer.cs | 658 ++ .../Automation/DataGridItemAutomationPeer.cs | 564 ++ .../DataGridItemCellAutomationPeer.cs | 442 ++ .../HeaderFooterItemAutomationPeer.cs | 415 ++ .../QueryAutomationIdRoutedEventArgs.cs | 47 + .../QueryHelpTextRoutedEventArgs.cs | 47 + .../QueryItemStatusRoutedEventArgs.cs | 47 + .../QueryItemTypeRoutedEventArgs.cs | 47 + .../Automation/QueryNameRoutedEventArgs.cs | 47 + .../Automation/RowAutomationPeer.cs | 52 + ...eCurrentWhenReadOnlyChangedEventManager.cs | 77 + .../Xceed.Wpf.DataGrid/CancelRoutedEvent.cs | 63 + .../Src/Xceed.Wpf.DataGrid/Cell.cs | 4460 +++++++++++ .../Src/Xceed.Wpf.DataGrid/CellCollection.cs | 130 + .../CellContentPresenter.cs | 88 + .../CellContentTemplateChangedEventManager.cs | 75 + .../Src/Xceed.Wpf.DataGrid/CellEditor.cs | 164 + .../Xceed.Wpf.DataGrid/CellEditorContext.cs | 106 + ...torDisplayConditionsChangedEventManager.cs | 75 + .../Src/Xceed.Wpf.DataGrid/CellState.cs | 162 + .../Xceed.Wpf.DataGrid/CellValidatingEvent.cs | 86 + .../CellValidationContext.cs | 53 + .../Xceed.Wpf.DataGrid/CellValidationError.cs | 81 + .../CellValidationErrorRoutedEvent.cs | 71 + ...GenericContentTemplateSelectorResources.cs | 31 + ...nericContentTemplateSelectorResources.xaml | 73 + .../Src/Xceed.Wpf.DataGrid/Column.cs | 282 + .../Src/Xceed.Wpf.DataGrid/ColumnBase.cs | 1838 +++++ .../Xceed.Wpf.DataGrid/ColumnCollection.cs | 418 ++ .../Xceed.Wpf.DataGrid/ColumnManagerCell.cs | 870 +++ .../Xceed.Wpf.DataGrid/ColumnManagerRow.cs | 197 + .../ColumnReorderingEvent.cs | 77 + .../ColumnVisibilePositionChangedEventArgs.cs | 67 + .../Src/Xceed.Wpf.DataGrid/ColumnWidth.cs | 125 + .../Xceed.Wpf.DataGrid/ContainerSizeState.cs | 105 + .../Converters/ColumnWidthConverter.cs | 167 + .../Converters/CurrencyConverter.cs | 69 + .../Converters/DefaultDataConverter.cs | 200 + .../EmptyStringToBooleanConverter.cs | 42 + .../FilterCriterionToForeignKeyConverter.cs | 59 + .../FilterCriterionToNullableBoolConverter.cs | 62 + .../Converters/GreaterThanZeroConverter.cs | 62 + .../Converters/ImageConverter.cs | 113 + .../Converters/IndexToOddConverter.cs | 70 + .../Converters/IntAdditionConverter.cs | 124 + .../Converters/InverseBooleanConverter.cs | 48 + .../Converters/LevelToOpacityConverter.cs | 139 + .../Converters/MultimodalResultConverter.cs | 73 + .../Converters/NegativeDoubleConverter.cs | 60 + .../Converters/NullToBooleanConverter.cs | 64 + .../SortingDirectionToBooleanConverter.cs | 47 + .../Converters/SourceDataConverter.cs | 113 + .../Converters/StatResultConverter.cs | 115 + .../Converters/StringFormatConverter.cs | 144 + .../SynchronizedScrollViewerMultiConverter.cs | 54 + .../Converters/ThicknessConverter.cs | 139 + .../Converters/TreeViewLineConverter.cs | 47 + .../Converters/TypeToBooleanConverter.cs | 78 + .../Converters/TypeToVisibilityConverter.cs | 92 + .../Converters/ValueToMaskedTextConverter.cs | 115 + .../Src/Xceed.Wpf.DataGrid/CurrencyManager.cs | 268 + .../Src/Xceed.Wpf.DataGrid/DataCell.cs | 251 + .../Xceed.Wpf.DataGrid/DataGridBindingInfo.cs | 279 + .../Xceed.Wpf.DataGrid/DataGridCheckBox.cs | 313 + .../Xceed.Wpf.DataGrid/DataGridCommands.cs | 78 + .../Src/Xceed.Wpf.DataGrid/DataGridContext.cs | 3933 ++++++++++ .../Src/Xceed.Wpf.DataGrid/DataGridControl.cs | 6384 ++++++++++++++++ .../DataGridControl.icon.16x16.bmp | Bin 0 -> 822 bytes ...ControlSelectionChangedWeakEventManager.cs | 83 + ...aGridControlTemplateChangedEventManager.cs | 90 + .../DataGridCurrentChangedEvent.cs | 65 + .../DataGridCurrentChangingEvent.cs | 71 + .../Xceed.Wpf.DataGrid/DataGridDatePicker.cs | 109 + .../Xceed.Wpf.DataGrid/DataGridException.cs | 51 + .../DataGridFocusException.cs | 51 + .../DataGridInternalException.cs | 56 + .../Xceed.Wpf.DataGrid/DataGridItemsHost.cs | 660 ++ .../DataGridSelectionChangedEvent.cs | 42 + .../DataGridSelectionChangingEvent.cs | 49 + .../DataGridValidationException.cs | 51 + .../DataGridVirtualizingPanel.cs | 274 + .../Src/Xceed.Wpf.DataGrid/DataRow.cs | 699 ++ .../DataRowEditableWrapper.cs | 55 + .../DefaultCellEditorSelector.xaml | 282 + .../DefaultCellEditorSelector.xaml.cs | 212 + .../DefaultDetailConfiguration.cs | 300 + ...eletingSelectedItemErrorRoutedEventArgs.cs | 105 + .../Xceed.Wpf.DataGrid/DetailConfiguration.cs | 1492 ++++ .../DetailConfigurationCollection.cs | 174 + .../Src/Xceed.Wpf.DataGrid/DetailIndicator.cs | 49 + .../DetailVisibilityChangedEventManager.cs | 99 + .../DetailsChangedEventManager.cs | 107 + .../Src/Xceed.Wpf.DataGrid/DropMarkAdorner.cs | 241 + .../(Clipboard)/ClipboardExporterBase.cs | 833 +++ .../(Clipboard)/CsvClipboardExporter.cs | 225 + .../Export/(Clipboard)/XceedDataObject.cs | 119 + .../Export/CsvFormatSettings.cs | 55 + .../Xceed.Wpf.DataGrid/Export/FormatHelper.cs | 252 + .../Export/FormatSettingsBase.cs | 54 + .../FieldNameGroupConfigurationSelector.cs | 75 + ...FieldNameGroupConfigurationSelectorItem.cs | 88 + ...roupConfigurationSelectorItemCollection.cs | 73 + .../FilterCriteria/AndFilterCriterion.cs | 212 + .../FilterCriteria/ContainsFilterCriterion.cs | 102 + .../CriterionDescriptorAttribute.cs | 62 + .../DifferentThanFilterCriterion.cs | 85 + .../FilterCriteria/EndsWithFilterCriterion.cs | 106 + .../FilterCriteria/EqualToFilterCriterion.cs | 84 + .../FilterCriteria/FilterCriterion.cs | 115 + .../GreaterThanFilterCriterion.cs | 83 + .../GreaterThanOrEqualToFilterCriterion.cs | 84 + .../FilterCriteria/LessThanFilterCriterion.cs | 83 + .../LessThanOrEqualToFilterCriterion.cs | 84 + .../FilterCriteria/NotFilterCriterion.cs | 160 + .../FilterCriteria/OrFilterCriterion.cs | 214 + .../RelationalFilterCriterion.cs | 234 + .../StartsWithFilterCriterion.cs | 106 + .../Src/Xceed.Wpf.DataGrid/FilterParser.cs | 812 ++ .../FilterParserTestWindow.cs | 309 + .../FilterParser_UnitTests.cs | 1465 ++++ ...eignKeyConfigurationChangedEventManager.cs | 75 + .../FrameworkElementUnloadedEventManager.cs | 105 + .../Xceed.Wpf.DataGrid/GlobalSuppressions.cs | 264 + .../Src/Xceed.Wpf.DataGrid/Group.cs | 538 ++ .../Src/Xceed.Wpf.DataGrid/GroupByControl.cs | 518 ++ .../Src/Xceed.Wpf.DataGrid/GroupByItem.cs | 542 ++ .../Xceed.Wpf.DataGrid/GroupConfiguration.cs | 250 + .../GroupConfigurationSelector.cs | 35 + ...onfigurationSelectorChangedEventManager.cs | 119 + .../Src/Xceed.Wpf.DataGrid/GroupExtensions.cs | 40 + .../Xceed.Wpf.DataGrid/GroupHeaderControl.cs | 308 + .../GroupHeaderFooterCollection.cs | 56 + .../GroupLevelConfiguration.cs | 125 + .../GroupLevelConfigurationCollection.cs | 33 + .../GroupLevelDescription.cs | 193 + .../GroupLevelDescriptionCollection.cs | 59 + .../Xceed.Wpf.DataGrid/GroupLevelIndicator.cs | 55 + .../GroupLevelIndicatorPane.cs | 431 ++ .../GroupNavigationButton.cs | 87 + .../GroupNavigationControl.cs | 436 ++ .../GroupNavigationControlItem.cs | 134 + .../Src/Xceed.Wpf.DataGrid/GroupingHelper.cs | 286 + .../Xceed.Wpf.DataGrid/HashedLinkedList.cs | 383 + .../Xceed.Wpf.DataGrid/HeaderFooterItem.cs | 558 ++ .../HierarchicalGroupByControl.cs | 689 ++ .../HierarchicalGroupByControlNode.cs | 913 +++ .../HierarchicalGroupByItem.cs | 944 +++ .../HierarchicalGroupLevelIndicatorPane.cs | 214 + .../ICustomVirtualizingPanel.cs | 30 + .../IDataGridContextVisitable.cs | 33 + .../IDataGridContextVisitor.cs | 37 + .../IDataGridItemContainer.cs | 29 + .../IDeferableScrollInfoRefresh.cs | 31 + .../InnerCellContentPresenter.cs | 65 + .../ItemPropertiesChangedEventManager.cs | 79 + .../ItemsHostUIElementCollection.cs | 238 + .../ItemsSourceChangedEventManager.cs | 75 + .../Xceed.Wpf.DataGrid/ItemsSourceHelper.cs | 1854 +++++ .../KeyActivationGesture.cs | 117 + .../LevelGroupConfigurationSelector.cs | 56 + .../LevelGroupConfigurationSelectorItem.cs | 89 + ...roupConfigurationSelectorItemCollection.cs | 73 + .../Src/Xceed.Wpf.DataGrid/Log.cs | 172 + .../Markup/CellContentBindingExtension.cs | 177 + .../Markup/CellEditorBindingExtension.cs | 276 + .../Markup/ClearGroupLevelConfigurations.cs | 20 +- .../Markup/ClearHeadersFooters.cs | 31 + .../Markup/ThemeConverter.cs | 113 + .../Src/Xceed.Wpf.DataGrid/Markup/ThemeKey.cs | 174 + .../Markup/ViewBindingExtension.cs | 246 + .../Markup/ViewConverter.cs | 106 + .../MaxGroupLevelsChangedEventManager.cs | 103 + .../MaxSortLevelsChangedEventManager.cs | 103 + .../Src/Xceed.Wpf.DataGrid/NoDrop.cur | Bin 0 -> 766 bytes .../Src/Xceed.Wpf.DataGrid/ObjectComparer.cs | 76 + .../Xceed.Wpf.DataGrid/Print/IPrintInfo.cs | 32 + .../Properties/AssemblyInfo.cs | 85 + .../ReadOnlyColumnCollection.cs | 66 + .../Xceed.Wpf.DataGrid/RecyclingManager.cs | 189 + .../Src/Xceed.Wpf.DataGrid/Row.cs | 2857 +++++++ .../Src/Xceed.Wpf.DataGrid/RowSelector.cs | 742 ++ .../Src/Xceed.Wpf.DataGrid/RowSelectorPane.cs | 380 + .../Src/Xceed.Wpf.DataGrid/RowState.cs | 75 + .../Xceed.Wpf.DataGrid/RowValidationError.cs | 80 + .../RowValidationErrorRoutedEvent.cs | 71 + .../ScrollChangedWeakEventManager.cs | 84 + .../Src/Xceed.Wpf.DataGrid/ScrollTip.cs | 803 ++ .../Xceed.Wpf.DataGrid/ScrollViewerHelper.cs | 714 ++ .../SelectedCellsStorage.cs | 528 ++ .../SelectedItemsStorage.cs | 532 ++ .../Xceed.Wpf.DataGrid/SelectionCellRange.cs | 219 + .../SelectionCellRangeCollection.cs | 308 + .../SelectionCellRangeWithItems.cs | 141 + .../SelectionChangedEventManager.cs | 81 + .../Xceed.Wpf.DataGrid/SelectionChanger.cs | 1265 ++++ .../Src/Xceed.Wpf.DataGrid/SelectionInfo.cs | 98 + .../SelectionItemCollection.cs | 362 + .../SelectionItemRangeCollection.cs | 335 + .../Xceed.Wpf.DataGrid/SelectionManager.cs | 1640 ++++ .../Src/Xceed.Wpf.DataGrid/SelectionRange.cs | 370 + .../SelectionRangeWithItems.cs | 211 + .../Settings/UserSettingsEnum.cs | 44 + .../Settings/XmlColumnWidthStruct.cs | 87 + .../Src/Xceed.Wpf.DataGrid/SortingHelper.cs | 243 + .../Src/Xceed.Wpf.DataGrid/StaircasePanel.cs | 368 + .../InvalidSourcePropertyNameException.cs | 76 + .../Stats/InvalidValueException.cs | 48 + .../Xceed.Wpf.DataGrid/Stats/StatFunction.cs | 328 + .../Stats/StatFunctionCollection.cs | 89 + .../Stats/StatFunctionComparer.cs | 40 + .../Xceed.Wpf.DataGrid/Stats/StatResult.cs | 19 +- .../TextInputActivationGesture.cs} | 18 +- .../ThemeChangedEventManager.cs | 78 + .../Src/Xceed.Wpf.DataGrid/UnboundColumn.cs | 283 + .../Utils/Collections/EnumerableWrapper.cs | 114 + .../Utils/Collections/IndexWeakHeapSort.cs | 133 + .../Collections/ListChangedEventManager.cs | 78 + .../Utils/Collections/ObservableHashList.cs | 340 + .../Utils/Collections/ObservableList.cs | 520 ++ .../Utils/Collections/ReadOnlyDictionary.cs | 175 + .../Collections/ReadOnlyObservableHashList.cs | 209 + .../Utils/Data/BoolDataStore.cs | 86 + .../Utils/Data/DataStore.cs | 35 + .../Utils/Data/ObjectDataStore.cs | 87 + .../Utils/Data/StringDataStore.cs | 61 + .../Utils/Data/ValueTypeDataStore.cs | 108 + .../Utils/Math/DoubleUtil.cs | 45 + .../Utils/WeakEventHandler.cs | 79 + .../Utils/Wpf/DispatcherHelper.cs | 56 + .../Utils/Wpf/DragDrop/DragDropHelper.cs | 86 + .../Utils/Wpf/DragDrop/DragSourceManager.cs | 862 +++ .../Wpf/DragDrop/DraggedElementAdorner.cs | 167 + .../Utils/Wpf/DragDrop/IDropTarget.cs | 39 + .../Wpf/Markup/XceedResourceDictionary.cs | 74 + .../Utils/Wpf/TreeHelper.cs | 238 + .../XmlSerializableBaseType.cs | 138 + .../ValidateInputWrapper.cs | 124 + .../CellContentBindingValidationRule.cs | 32 + .../CellEditorErrorValidationRule.cs | 39 + .../CellEditorValidationRule.cs | 47 + .../ValidationRules/CellValidationRule.cs | 36 + .../EventCellValidationRule.cs | 51 + .../FilterExpressionValidationRule.cs | 48 + .../PassthroughCellValidationRule.cs | 63 + .../SourceDataConverterValidationRule.cs | 57 + .../ViewChangedEventManager.cs | 75 + .../ColumnVirtualizationManager.cs | 260 + .../TableViewColumnVirtualizationManager.cs | 937 +++ .../UpdateMeasureRequiredEventArgs.cs | 65 + .../UpdateMeasureRequiredEventManager.cs | 90 + .../VirtualizingFixedCellSubPanel.cs | 152 + .../VirtualizingUICellCollection.cs | 312 + .../Views/(Enums)/ColumnStretchModeEnum.cs | 31 + .../Views/(Enums)/DropMarkOrientationEnum.cs | 32 + .../Views/(Enums)/PassiveLayoutAxisEnum.cs | 30 + .../SynchronizedScrollViewerPositionEnum.cs | 32 + .../Views/(Enums)/ViewPropertyModeEnum.cs | 33 + .../AnimatedDraggedElementAdorner.cs | 154 + .../ColumnReorderingDragSourceManager.cs | 2175 ++++++ .../(TableflowView)/IAnimatedScrollInfo.cs | 73 + .../(TableflowView)/LayoutedContainerInfo.cs | 75 + .../LayoutedContainerInfoList.cs | 79 + .../Views/(TableflowView)/OffsetAnimation.cs | 158 + .../Views/(TableflowView)/PointAnimation.cs | 170 + .../(TableflowView)/StickyContainerInfo.cs | 74 + .../StickyContainerInfoComparer.cs | 55 + .../StickyContainerInfoList.cs | 66 + .../StickyContainerInfoReverseComparer.cs | 55 + .../Views/(TableflowView)/TableflowView.cs | 512 ++ .../TableflowViewAnimationHelper.cs | 42 + .../(TableflowView)/TableflowViewItemsHost.cs | 3940 ++++++++++ .../TableflowViewUIElementCollection.cs | 228 + .../Views/(TableflowView)/ZOrderHelper.cs | 102 + .../Views/ColumnStretchingManager.cs | 327 + .../Views/DataGridControlBackgroundBrushes.cs | 174 + ...GridControlBackgroundBrushesResources.xaml | 1156 +++ ...dControlBackgroundBrushesResources.xaml.cs | 31 + .../Views/DataGridScrollViewer.cs | 1466 ++++ .../Views/FixedCellPanel.cs | 1461 ++++ .../Views/FixedCellSubPanel.cs | 289 + .../Views/FixedColumnSplitter.cs | 39 + .../Views/IVirtualizingCellsHost.cs | 45 + .../Views/PassiveLayoutDecorator.cs | 83 + .../Views/ScrollingCellsDecorator.cs | 212 + .../Views/SynchronizedScrollViewer.cs | 535 ++ .../Src/Xceed.Wpf.DataGrid/Views/TableView.cs | 857 +++ .../Views/TableViewHeaderFooterPanel.cs | 107 + .../Views/TableViewItemsHost.cs | 3054 ++++++++ .../Views/TableViewScrollViewer.cs | 287 + .../Views/TargetViewAttribute.cs | 47 + .../Src/Xceed.Wpf.DataGrid/Views/Theme.cs | 98 + .../Views/UICellCollection.cs | 528 ++ .../Xceed.Wpf.DataGrid/Views/UIViewBase.cs | 484 ++ .../Src/Xceed.Wpf.DataGrid/Views/ViewBase.cs | 536 ++ .../Views/ViewPropertyAttribute.cs | 43 + .../VirtualizingCellCollection.cs | 921 +++ ...lizingCellCollectionChangedEventManager.cs | 84 + .../VirtualizingStackPanel.cs | 2106 ++++++ .../VisibleColumnsUpdatingEventManager.cs | 77 + .../Src/Xceed.Wpf.DataGrid/Watermark.png | Bin 0 -> 3662 bytes .../Xceed.Wpf.DataGrid/WatermarkAdorner.cs | 102 + .../Xceed.Wpf.DataGrid.csproj | 966 +++ .../Src/Xceed.Wpf.DataGrid/sn.snk | Bin 0 -> 596 bytes .../themes/Aero/Resources/Aero.Resources.xaml | 41 + .../Resources/Aero.normalcolor.Resources.xaml | 462 ++ .../Resources/TableView.Aero.Graphics.xaml | 246 + .../Aero/TableView.Aero.normalcolor.xaml | 2718 +++++++ .../Aero/TableflowView.Aero.normalcolor.xaml | 3144 ++++++++ .../Classic/Resources/Classic.Resources.xaml | 36 + .../Classic.systemcolor.Graphics.xaml | 104 + .../Classic.systemcolor.Resources.xaml | 66 + .../TableView.Classic.systemcolor.xaml | 1486 ++++ .../TableflowView.Classic.systemcolor.xaml | 1844 +++++ .../themes/Common/Common.Resources.xaml | 515 ++ .../themes/Common/Graphics.xaml | 318 + .../TableView.GridElementTemplates.xaml | 1506 ++++ .../TableflowView.GridElementTemplates.xaml | 1554 ++++ .../Controls/FixedColumnSplitter.generic.xaml | 24 + .../TableViewScrollViewer.generic.xaml | 170 + .../themes/Luna/Resources/Luna.Resources.xaml | 41 + .../Resources/Luna.homestead.Resources.xaml | 70 + .../Resources/Luna.metallic.Resources.xaml | 70 + .../Resources/Luna.normalcolor.Resources.xaml | 70 + .../Resources/TableView.Luna.Graphics.xaml | 111 + .../themes/Luna/TableView.Luna.homestead.xaml | 1773 +++++ .../themes/Luna/TableView.Luna.metallic.xaml | 2061 ++++++ .../Luna/TableView.Luna.normalcolor.xaml | 2062 ++++++ .../Luna/TableflowView.Luna.homestead.xaml | 2192 ++++++ .../Luna/TableflowView.Luna.metallic.xaml | 2482 +++++++ .../Luna/TableflowView.Luna.normalcolor.xaml | 2477 +++++++ .../Royale/Resources/Royale.Resources.xaml | 36 + .../Royale.normalcolor.Resources.xaml | 71 + .../Resources/TableView.Royale.Graphics.xaml | 31 + .../Royale/TableView.Royale.normalcolor.xaml | 2027 +++++ .../TableflowView.Royale.normalcolor.xaml | 2444 ++++++ .../TableView.Windows7.Graphics.xaml | 862 +++ .../Windows7/Resources/Windows7.Controls.xaml | 2180 ++++++ .../Resources/Windows7.Resources.xaml | 452 ++ .../themes/Windows7/TableView.Windows7.xaml | 2692 +++++++ .../Windows7/TableflowView.Windows7.xaml | 3150 ++++++++ .../Resources/TableView.Zune.Graphics.xaml | 31 + .../themes/Zune/Resources/Zune.Resources.xaml | 36 + .../Resources/Zune.normalcolor.Resources.xaml | 70 + .../Zune/TableView.Zune.normalcolor.xaml | 1857 +++++ .../Zune/TableflowView.Zune.normalcolor.xaml | 2271 ++++++ .../themes/aero.normalcolor.xaml | 228 + .../Xceed.Wpf.DataGrid/themes/classic.xaml | 228 + .../Xceed.Wpf.DataGrid/themes/generic.xaml | 271 + .../themes/luna.homestead.xaml | 220 + .../themes/luna.metallic.xaml | 229 + .../themes/luna.normalcolor.xaml | 220 + .../themes/royale.normalcolor.xaml | 228 + .../themes/zune.normalcolor.xaml | 228 + .../Editors/DecimalUpDownEditor.cs | 34 - .../Utils/Exceptions/ThrowException.cs | 70 - 635 files changed, 194275 insertions(+), 1576 deletions(-) create mode 100644 ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.DataGrid/DataGridModule.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.DataGrid/Properties/AssemblyInfo.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.DataGrid/Samples.Modules.DataGrid.csproj create mode 100644 ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.DataGrid/Views/FullVersion.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.DataGrid/Views/FullVersion.xaml.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.DataGrid/Views/HomeView.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.DataGrid/Views/HomeView.xaml.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.DataGrid/Views/NavigationView.xaml rename ExtendedWPFToolkitSolution/Src/{WPFToolkit.Extended/PropertyGrid/Implementation/Editors/DoubleUpDownEditor.cs => Samples/Modules/Samples.Modules.DataGrid/Views/NavigationView.xaml.cs} (68%) create mode 100644 ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.PropertyGrid/Views/DisplayLocalizationRes.Designer.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.PropertyGrid/Views/DisplayLocalizationRes.fr.resx create mode 100644 ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.PropertyGrid/Views/DisplayLocalizationRes.resx create mode 100644 ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.Text/Views/AutoSelectTextBoxView.xaml rename ExtendedWPFToolkitSolution/Src/{WPFToolkit.Extended/PropertyGrid/Implementation/Editors/DecimalUpDownEditor.cs => Samples/Modules/Samples.Modules.Text/Views/AutoSelectTextBoxView.xaml.cs} (66%) create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/AutoSelectTextBox/Implementation/AutoSelectBehaviorEnum.cs create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/AutoSelectTextBox/Implementation/AutoSelectTextBox.cs create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/AutoSelectTextBox/Implementation/QueryMoveFocusEventArgs.cs create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Input/IValidateInput.cs create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Input/InputValidationErrorEventArgs.cs create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/CachedTextInfo.cs create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/ValueRangeTextBox.cs create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/QueryTextFromValueEventArgs.cs create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/QueryValueFromTextEventArgs.cs create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Utilities/NotifyPropertyChangedHelper.cs create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Utilities/ReflectionHelper.cs create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Utilities/TreeHelper.cs create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Utilities/ValueChangeHelper.cs create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/MaskedTextBox/Implementation/AutoCompletingMaskEventArgs.cs create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/MaskedTextBox/Implementation/InsertKeyModeEnum.cs create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/MaskedTextBox/Implementation/MaskFormatEnum.cs create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/NumericUpDown/Implementation/ByteUpDown.cs create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/NumericUpDown/Implementation/CommonNumericUpDown.cs create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/NumericUpDown/Implementation/LongUpDown.cs create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/NumericUpDown/Implementation/SByteUpDown.cs create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/NumericUpDown/Implementation/ShortUpDown.cs create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/NumericUpDown/Implementation/SingleUpDown.cs create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/NumericUpDown/Implementation/UIntegerUpDown.cs create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/NumericUpDown/Implementation/ULongUpDown.cs create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/NumericUpDown/Implementation/UShortUpDown.cs create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Obselete/MaskedTextBox/Implementation/MaskedTextBox.cs create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Converters/SelectedObjectConverter.cs create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Editors/UpDownEditors.cs create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/IPropertyParent.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(DataVirtualization)/EmptyDataItem.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(DataVirtualization)/VirtualList.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(DataVirtualization)/VirtualListEnumerator.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(DataVirtualization)/VirtualListTableOfContent.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(DataVirtualization)/VirtualPage.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(DataVirtualization)/VirtualPageManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(DataVirtualization)/VirtualizedItemInfo.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(DataVirtualization)/VirtualizedItemValueCollection.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(ForeignKeys)/DataGridForeignKeyDescription.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(ForeignKeys)/DataTableForeignKeyDescription.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/AsyncCommitInfo.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/AsyncQueryInfo.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/AsyncQueryInfoWeakComparer.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/AutoFilterValuesChangedEventArgs.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/BindingPathValueExtractor.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/CollectionViewGroupExtensions.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/CommitItemsEvent.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/CustomDistinctValueItemConfiguration.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/CustomDistinctValueItemConfigurationCollection.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/CustomDistinctValueItemFilterEventArgs.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionView.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewBase.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewBaseDataProvider.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewDataProvider.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewEnumerator.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewGroup.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewGroupRoot.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewGroupSort.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewSort.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewSource.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewSourceBase.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCommittingNewItemEvent.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCreatingNewItemEvent.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridDetailDescription.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridDetailDescriptionCollection.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridGroupDescription.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridGroupInfo.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemCancelEvent.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemEvent.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemHandledEvent.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemProperty.PropertyDescriptorFromItemProperty.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemProperty.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemPropertyBase.PropertyDescriptorFromItemPropertyBase.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemPropertyBase.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemPropertyCollection.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemPropertyCommittingValue.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemPropertyDictionary.cs rename ExtendedWPFToolkitSolution/Src/{WPFToolkit.Extended/PropertyGrid/Implementation/Editors/DateTimeUpDownEditor.cs => Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemPropertyQueryValueEvent.cs} (67%) create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemRemovedEvent.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridLINQPageManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridPageManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridPageManagerBase.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridRemovingItemEvent.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridSortDescriptionCollection.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridUnboundItemProperty.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingCollectionView.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingCollectionViewBase.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingCollectionViewDataProvider.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingCollectionViewGroup.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingCollectionViewGroupBase.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingCollectionViewGroupRoot.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingCollectionViewSource.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingCollectionViewSourceBase.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingQueryableCollectionView.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingQueryableCollectionViewDataProvider.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingQueryableCollectionViewGroup.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingQueryableCollectionViewGroupRoot.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingQueryableCollectionViewSource.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataRelationDetailDescription.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataRowColumnPropertyDescriptor.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DeferredOperation.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DeferredOperationManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DistinctValuesDictionary.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/EmptyDataItemSafePropertyDescriptor.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/EntityDetailDescription.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/EnumerableDetailDescription.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/GroupDescriptionCollection.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/GroupNameCountPair.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/GroupSortComparer.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/JaggedArrayPropertyDescriptor.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/ListSourceDetailDescription.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/OptimizedReadOnlyObservableCollection.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/PropertyDetailDescription.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/PropertyRelationAttribute.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/QueryAutoFilterDistinctValuesEvent.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/QueryDistinctValueEventArgs.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/QueryEntityDetailsEventArgs.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/QueryGroupsEventArgs.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/QueryItemCountEvent.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/QueryItemsEvent.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/QueryableExtensions.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/RawItem.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/RawItemIndexComparer.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/RawItemSortComparer.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/SelfPropertyDescriptor.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/SortDescriptionsSyncContext.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/SortedDescriptionInfo.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/SourceItemCollection.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/StatResultComparer.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/UnboundDataItem.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/UnboundDataRowPropertyDescriptor.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(ForeignKeys)/DataTableForeignKeyConverter.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(ForeignKeys)/ForeignKeyConfiguration.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(ForeignKeys)/ForeignKeyContentControl.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(ForeignKeys)/ForeignKeyConverter.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(ForeignKeys)/ForeignKeyGroupContentControl.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(ForeignKeys)/ForeignKeyScrollTipContentControl.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/CollectionGeneratorNode.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/ColumnActualWidthChangedHandler.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/ColumnActualWidthEventManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/ContainersRemovedEventArgs.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/CurrentColumnChangedEventManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/CustomGeneratorChangedEventArgs.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/CustomItemContainerGenerator.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/DetailGeneratorNode.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/DistinctValuesRequestedEventArgs.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/DistinctValuesRequestedEventManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/ExpansionStateEventArgs.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/GeneratorNode.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/GeneratorNodeFactory.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/GeneratorNodeHelper.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/GroupGeneratorNode.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/GroupHeaderFooterItem.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/GroupHeaderFooterItemTemplate.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/GroupNamesTreeKey.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/HeadersFootersGeneratorNode.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/ICustomItemContainerGenerator.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/IInhibitGenPosToIndexUpdating.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/ItemContextVisitor.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/ItemsGeneratorNode.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/NamesTreeGroupFinderVisitor.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/NotifyCollectionChangedGeneratorNode.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/RangeSelectionVisitor.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/RealizedContainersRequestedEventArgs.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/RealizedContainersRequestedEventManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/SaveRestoreDataGridContextStateVisitor.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/SaveRestoreGlobalStateVisitor.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/SaveRestoreStateVisitor.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/SelectAllVisitor.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/StickyContainerGeneratedComparer.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/StickyContainerGeneratedReverseComparer.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/StickyContainerGeneratedStruct.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/VisibilityChangedEventManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/VisibleColumnsUpdatedEventManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/WeakDataGridContextKey.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/AutoFilterModeEnum.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/CellEditorDisplayConditionsEnum.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/ColumnWidthUnitTypeEnum.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/CommitModeEnum.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/CompareResultEnum.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/ConnectionLineAlignmentEnum.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/DataGridConnectionStateEnum.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/DataGridContextVisitorTypeEnum.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/DataGridUpdateSourceTriggerEnum.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/DeletingSelectedItemErrorActionEnum.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/DistinctValuesConstraintEnum.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/DistinctValuesUpdateModeEnum.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/DropMarkAlignmentEnum.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/EditTriggersEnum.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/FilterCriteriaModeEnum.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/FilterOperatorPrecedenceEnum.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/FilterTokenPriorityEnum.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/GeneratorNodeTypeEnum.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/InsertionModeEnum.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/ItemScrollingBehaviorEnum.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/NavigationBehaviorEnum.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/PagingBehaviorEnum.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/PrimaryAxisEnum.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/ScrollDirectionEnum.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/ScrollOrientationEnum.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/SelectionUnitEnum.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/SortDirectionEnum.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/ValidationModeEnum.cs rename ExtendedWPFToolkitSolution_35/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Editors/IntegerUpDownEditor.cs => ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ActivationGesture.cs (68%) create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ActivationGestureCollection.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/AddingNewDataItemEvent.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/AllowDetailToggleChangedEventManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/AssemblyVersionInfo.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/AssemblyVersionInfoCommon.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Automation/AutomationPeerExtensions.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Automation/AutomationQueryEvents.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Automation/CellAutomationPeer.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Automation/ColumnManagerCellAutomationPeer.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Automation/ColumnManagerRowAutomationPeer.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Automation/DataGridContextAutomationPeer.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Automation/DataGridControlAutomationPeer.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Automation/DataGridGroupAutomationPeer.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Automation/DataGridItemAutomationPeer.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Automation/DataGridItemCellAutomationPeer.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Automation/HeaderFooterItemAutomationPeer.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Automation/QueryAutomationIdRoutedEventArgs.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Automation/QueryHelpTextRoutedEventArgs.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Automation/QueryItemStatusRoutedEventArgs.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Automation/QueryItemTypeRoutedEventArgs.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Automation/QueryNameRoutedEventArgs.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Automation/RowAutomationPeer.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CanBeCurrentWhenReadOnlyChangedEventManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CancelRoutedEvent.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Cell.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CellCollection.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CellContentPresenter.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CellContentTemplateChangedEventManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CellEditor.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CellEditorContext.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CellEditorDisplayConditionsChangedEventManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CellState.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CellValidatingEvent.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CellValidationContext.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CellValidationError.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CellValidationErrorRoutedEvent.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Column.GenericContentTemplateSelectorResources.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Column.GenericContentTemplateSelectorResources.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Column.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnBase.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnCollection.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnManagerCell.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnManagerRow.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnReorderingEvent.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnVisibilePositionChangedEventArgs.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnWidth.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ContainerSizeState.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/ColumnWidthConverter.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/CurrencyConverter.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/DefaultDataConverter.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/EmptyStringToBooleanConverter.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/FilterCriterionToForeignKeyConverter.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/FilterCriterionToNullableBoolConverter.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/GreaterThanZeroConverter.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/ImageConverter.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/IndexToOddConverter.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/IntAdditionConverter.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/InverseBooleanConverter.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/LevelToOpacityConverter.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/MultimodalResultConverter.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/NegativeDoubleConverter.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/NullToBooleanConverter.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/SortingDirectionToBooleanConverter.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/SourceDataConverter.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/StatResultConverter.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/StringFormatConverter.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/SynchronizedScrollViewerMultiConverter.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/ThicknessConverter.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/TreeViewLineConverter.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/TypeToBooleanConverter.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/TypeToVisibilityConverter.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/ValueToMaskedTextConverter.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CurrencyManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataCell.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridBindingInfo.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridCheckBox.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridCommands.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridContext.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridControl.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridControl.icon.16x16.bmp create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridControlSelectionChangedWeakEventManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridControlTemplateChangedEventManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridCurrentChangedEvent.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridCurrentChangingEvent.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridDatePicker.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridException.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridFocusException.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridInternalException.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridItemsHost.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridSelectionChangedEvent.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridSelectionChangingEvent.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridValidationException.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridVirtualizingPanel.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataRow.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataRowEditableWrapper.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DefaultCellEditorSelector.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DefaultCellEditorSelector.xaml.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DefaultDetailConfiguration.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DeletingSelectedItemErrorRoutedEventArgs.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DetailConfiguration.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DetailConfigurationCollection.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DetailIndicator.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DetailVisibilityChangedEventManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DetailsChangedEventManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DropMarkAdorner.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Export/(Clipboard)/ClipboardExporterBase.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Export/(Clipboard)/CsvClipboardExporter.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Export/(Clipboard)/XceedDataObject.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Export/CsvFormatSettings.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Export/FormatHelper.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Export/FormatSettingsBase.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/FieldNameGroupConfigurationSelector.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/FieldNameGroupConfigurationSelectorItem.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/FieldNameGroupConfigurationSelectorItemCollection.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/FilterCriteria/AndFilterCriterion.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/FilterCriteria/ContainsFilterCriterion.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/FilterCriteria/CriterionDescriptorAttribute.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/FilterCriteria/DifferentThanFilterCriterion.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/FilterCriteria/EndsWithFilterCriterion.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/FilterCriteria/EqualToFilterCriterion.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/FilterCriteria/FilterCriterion.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/FilterCriteria/GreaterThanFilterCriterion.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/FilterCriteria/GreaterThanOrEqualToFilterCriterion.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/FilterCriteria/LessThanFilterCriterion.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/FilterCriteria/LessThanOrEqualToFilterCriterion.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/FilterCriteria/NotFilterCriterion.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/FilterCriteria/OrFilterCriterion.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/FilterCriteria/RelationalFilterCriterion.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/FilterCriteria/StartsWithFilterCriterion.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/FilterParser.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/FilterParserTestWindow.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/FilterParser_UnitTests.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ForeignKeyConfigurationChangedEventManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/FrameworkElementUnloadedEventManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GlobalSuppressions.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Group.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupByControl.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupByItem.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupConfiguration.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupConfigurationSelector.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupConfigurationSelectorChangedEventManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupExtensions.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupHeaderControl.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupHeaderFooterCollection.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupLevelConfiguration.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupLevelConfigurationCollection.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupLevelDescription.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupLevelDescriptionCollection.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupLevelIndicator.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupLevelIndicatorPane.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupNavigationButton.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupNavigationControl.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupNavigationControlItem.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupingHelper.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/HashedLinkedList.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/HeaderFooterItem.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/HierarchicalGroupByControl.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/HierarchicalGroupByControlNode.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/HierarchicalGroupByItem.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/HierarchicalGroupLevelIndicatorPane.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ICustomVirtualizingPanel.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/IDataGridContextVisitable.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/IDataGridContextVisitor.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/IDataGridItemContainer.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/IDeferableScrollInfoRefresh.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/InnerCellContentPresenter.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ItemPropertiesChangedEventManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ItemsHostUIElementCollection.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ItemsSourceChangedEventManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ItemsSourceHelper.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/KeyActivationGesture.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/LevelGroupConfigurationSelector.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/LevelGroupConfigurationSelectorItem.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/LevelGroupConfigurationSelectorItemCollection.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Log.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/CellContentBindingExtension.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/CellEditorBindingExtension.cs rename ExtendedWPFToolkitSolution_35/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Editors/DateTimeUpDownEditor.cs => ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/ClearGroupLevelConfigurations.cs (66%) create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/ClearHeadersFooters.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/ThemeConverter.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/ThemeKey.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/ViewBindingExtension.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/ViewConverter.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/MaxGroupLevelsChangedEventManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/MaxSortLevelsChangedEventManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/NoDrop.cur create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ObjectComparer.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Print/IPrintInfo.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Properties/AssemblyInfo.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ReadOnlyColumnCollection.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/RecyclingManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Row.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/RowSelector.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/RowSelectorPane.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/RowState.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/RowValidationError.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/RowValidationErrorRoutedEvent.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ScrollChangedWeakEventManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ScrollTip.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ScrollViewerHelper.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectedCellsStorage.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectedItemsStorage.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionCellRange.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionCellRangeCollection.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionCellRangeWithItems.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionChangedEventManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionChanger.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionInfo.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionItemCollection.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionItemRangeCollection.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionRange.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionRangeWithItems.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Settings/UserSettingsEnum.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Settings/XmlColumnWidthStruct.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SortingHelper.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/StaircasePanel.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Stats/InvalidSourcePropertyNameException.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Stats/InvalidValueException.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Stats/StatFunction.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Stats/StatFunctionCollection.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Stats/StatFunctionComparer.cs rename ExtendedWPFToolkitSolution_35/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Editors/DoubleUpDownEditor.cs => ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Stats/StatResult.cs (69%) rename ExtendedWPFToolkitSolution/Src/{WPFToolkit.Extended/PropertyGrid/Implementation/Editors/IntegerUpDownEditor.cs => Xceed.Wpf.DataGrid/TextInputActivationGesture.cs} (68%) create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ThemeChangedEventManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/UnboundColumn.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/EnumerableWrapper.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/IndexWeakHeapSort.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/ListChangedEventManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/ObservableHashList.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/ObservableList.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/ReadOnlyDictionary.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/ReadOnlyObservableHashList.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Data/BoolDataStore.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Data/DataStore.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Data/ObjectDataStore.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Data/StringDataStore.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Data/ValueTypeDataStore.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Math/DoubleUtil.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/WeakEventHandler.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DispatcherHelper.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DragDrop/DragDropHelper.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DragDrop/DragSourceManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DragDrop/DraggedElementAdorner.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DragDrop/IDropTarget.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/Markup/XceedResourceDictionary.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/TreeHelper.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/XmlSerialization/XmlSerializableBaseType.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ValidateInputWrapper.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ValidationRules/CellContentBindingValidationRule.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ValidationRules/CellEditorErrorValidationRule.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ValidationRules/CellEditorValidationRule.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ValidationRules/CellValidationRule.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ValidationRules/EventCellValidationRule.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ValidationRules/FilterExpressionValidationRule.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ValidationRules/PassthroughCellValidationRule.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ValidationRules/SourceDataConverterValidationRule.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ViewChangedEventManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/ColumnVirtualizationManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/TableViewColumnVirtualizationManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/UpdateMeasureRequiredEventArgs.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/UpdateMeasureRequiredEventManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/VirtualizingFixedCellSubPanel.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/VirtualizingUICellCollection.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(Enums)/ColumnStretchModeEnum.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(Enums)/DropMarkOrientationEnum.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(Enums)/PassiveLayoutAxisEnum.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(Enums)/SynchronizedScrollViewerPositionEnum.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(Enums)/ViewPropertyModeEnum.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/AnimatedDraggedElementAdorner.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/ColumnReorderingDragSourceManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/IAnimatedScrollInfo.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/LayoutedContainerInfo.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/LayoutedContainerInfoList.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/OffsetAnimation.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/PointAnimation.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/StickyContainerInfo.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/StickyContainerInfoComparer.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/StickyContainerInfoList.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/StickyContainerInfoReverseComparer.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/TableflowView.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/TableflowViewAnimationHelper.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/TableflowViewItemsHost.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/TableflowViewUIElementCollection.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/ZOrderHelper.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/ColumnStretchingManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/DataGridControlBackgroundBrushes.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/DataGridControlBackgroundBrushesResources.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/DataGridControlBackgroundBrushesResources.xaml.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/DataGridScrollViewer.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/FixedCellPanel.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/FixedCellSubPanel.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/FixedColumnSplitter.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/IVirtualizingCellsHost.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/PassiveLayoutDecorator.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/ScrollingCellsDecorator.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/SynchronizedScrollViewer.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TableView.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TableViewHeaderFooterPanel.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TableViewItemsHost.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TableViewScrollViewer.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TargetViewAttribute.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/Theme.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/UICellCollection.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/UIViewBase.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/ViewBase.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/ViewPropertyAttribute.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/VirtualizingCellCollection.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/VirtualizingCellCollectionChangedEventManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/VirtualizingStackPanel.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/VisibleColumnsUpdatingEventManager.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Watermark.png create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/WatermarkAdorner.cs create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Xceed.Wpf.DataGrid.csproj create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/sn.snk create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Aero/Resources/Aero.Resources.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Aero/Resources/Aero.normalcolor.Resources.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Aero/Resources/TableView.Aero.Graphics.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Aero/TableView.Aero.normalcolor.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Aero/TableflowView.Aero.normalcolor.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Classic/Resources/Classic.Resources.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Classic/Resources/Classic.systemcolor.Graphics.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Classic/Resources/Classic.systemcolor.Resources.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Classic/TableView.Classic.systemcolor.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Classic/TableflowView.Classic.systemcolor.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Common/Common.Resources.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Common/Graphics.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Common/TableView.GridElementTemplates.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Common/TableflowView.GridElementTemplates.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Controls/FixedColumnSplitter.generic.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Controls/TableViewScrollViewer.generic.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Luna/Resources/Luna.Resources.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Luna/Resources/Luna.homestead.Resources.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Luna/Resources/Luna.metallic.Resources.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Luna/Resources/Luna.normalcolor.Resources.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Luna/Resources/TableView.Luna.Graphics.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Luna/TableView.Luna.homestead.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Luna/TableView.Luna.metallic.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Luna/TableView.Luna.normalcolor.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Luna/TableflowView.Luna.homestead.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Luna/TableflowView.Luna.metallic.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Luna/TableflowView.Luna.normalcolor.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Royale/Resources/Royale.Resources.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Royale/Resources/Royale.normalcolor.Resources.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Royale/Resources/TableView.Royale.Graphics.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Royale/TableView.Royale.normalcolor.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Royale/TableflowView.Royale.normalcolor.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Windows7/Resources/TableView.Windows7.Graphics.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Windows7/Resources/Windows7.Controls.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Windows7/Resources/Windows7.Resources.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Windows7/TableView.Windows7.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Windows7/TableflowView.Windows7.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Zune/Resources/TableView.Zune.Graphics.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Zune/Resources/Zune.Resources.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Zune/Resources/Zune.normalcolor.Resources.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Zune/TableView.Zune.normalcolor.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Zune/TableflowView.Zune.normalcolor.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/aero.normalcolor.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/classic.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/generic.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/luna.homestead.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/luna.metallic.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/luna.normalcolor.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/royale.normalcolor.xaml create mode 100644 ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/zune.normalcolor.xaml delete mode 100644 ExtendedWPFToolkitSolution_35/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Editors/DecimalUpDownEditor.cs delete mode 100644 ExtendedWPFToolkitSolution_35/Src/WPFToolkit.Extended/Utils/Exceptions/ThrowException.cs diff --git a/ExtendedWPFToolkitSolution/ExtendedWPFToolkit.sln b/ExtendedWPFToolkitSolution/ExtendedWPFToolkit.sln index 8b521022..a1c6307a 100644 --- a/ExtendedWPFToolkitSolution/ExtendedWPFToolkit.sln +++ b/ExtendedWPFToolkitSolution/ExtendedWPFToolkit.sln @@ -30,6 +30,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Samples.Modules.ChildWindow EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Samples.Modules.Color", "Src\Samples\Modules\Samples.Modules.Color\Samples.Modules.Color.csproj", "{A36AB9C9-D813-4018-B341-8729A9B5BD7D}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Samples.Modules.DataGrid", "Src\Samples\Modules\Samples.Modules.DataGrid\Samples.Modules.DataGrid.csproj", "{129477D9-F413-495F-BE05-D049575BC16C}" +EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Samples.Modules.DateTime", "Src\Samples\Modules\Samples.Modules.DateTime\Samples.Modules.DateTime.csproj", "{CAB850B9-1D47-4F45-A6A5-07B48599B5D7}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Samples.Modules.Numeric", "Src\Samples\Modules\Samples.Modules.Numeric\Samples.Modules.Numeric.csproj", "{CBED4977-79ED-4E46-AA00-0A4D83D333A6}" @@ -54,6 +56,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Samples.Modules.Magnifier", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Samples.Modules.MessageBox", "Src\Samples\Modules\Samples.Modules.MessageBox\Samples.Modules.MessageBox.csproj", "{C324395B-C1D1-407B-8745-4AAC39B8BFD9}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Xceed.Wpf.DataGrid", "Src\Xceed.Wpf.DataGrid\Xceed.Wpf.DataGrid.csproj", "{63648392-6CE9-4A60-96D4-F9FD718D29B0}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -254,6 +258,26 @@ Global {C324395B-C1D1-407B-8745-4AAC39B8BFD9}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {C324395B-C1D1-407B-8745-4AAC39B8BFD9}.Release|Mixed Platforms.Build.0 = Release|Any CPU {C324395B-C1D1-407B-8745-4AAC39B8BFD9}.Release|x86.ActiveCfg = Release|Any CPU + {63648392-6CE9-4A60-96D4-F9FD718D29B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {63648392-6CE9-4A60-96D4-F9FD718D29B0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {63648392-6CE9-4A60-96D4-F9FD718D29B0}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {63648392-6CE9-4A60-96D4-F9FD718D29B0}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {63648392-6CE9-4A60-96D4-F9FD718D29B0}.Debug|x86.ActiveCfg = Debug|Any CPU + {63648392-6CE9-4A60-96D4-F9FD718D29B0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {63648392-6CE9-4A60-96D4-F9FD718D29B0}.Release|Any CPU.Build.0 = Release|Any CPU + {63648392-6CE9-4A60-96D4-F9FD718D29B0}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {63648392-6CE9-4A60-96D4-F9FD718D29B0}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {63648392-6CE9-4A60-96D4-F9FD718D29B0}.Release|x86.ActiveCfg = Release|Any CPU + {129477D9-F413-495F-BE05-D049575BC16C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {129477D9-F413-495F-BE05-D049575BC16C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {129477D9-F413-495F-BE05-D049575BC16C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {129477D9-F413-495F-BE05-D049575BC16C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {129477D9-F413-495F-BE05-D049575BC16C}.Debug|x86.ActiveCfg = Debug|Any CPU + {129477D9-F413-495F-BE05-D049575BC16C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {129477D9-F413-495F-BE05-D049575BC16C}.Release|Any CPU.Build.0 = Release|Any CPU + {129477D9-F413-495F-BE05-D049575BC16C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {129477D9-F413-495F-BE05-D049575BC16C}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {129477D9-F413-495F-BE05-D049575BC16C}.Release|x86.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -278,5 +302,6 @@ Global {910A7A19-DD9F-4989-A001-BD7E5BAD2FE8} = {F927B3FE-820C-4EE1-921F-D10D3AE287AE} {C3D3FFAD-2DA3-4142-8DE8-7045E347B63A} = {F927B3FE-820C-4EE1-921F-D10D3AE287AE} {C324395B-C1D1-407B-8745-4AAC39B8BFD9} = {F927B3FE-820C-4EE1-921F-D10D3AE287AE} + {129477D9-F413-495F-BE05-D049575BC16C} = {F927B3FE-820C-4EE1-921F-D10D3AE287AE} EndGlobalSection EndGlobal diff --git a/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.CheckLists/Views/HomeView.xaml b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.CheckLists/Views/HomeView.xaml index 8ce4243c..61eb908b 100644 --- a/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.CheckLists/Views/HomeView.xaml +++ b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.CheckLists/Views/HomeView.xaml @@ -129,7 +129,6 @@ - - + IsDropDownOpen="{Binding ElementName=_isDropDownOpen, Path=IsChecked, Mode=TwoWay}" /> - - - diff --git a/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.DataGrid/DataGridModule.cs b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.DataGrid/DataGridModule.cs new file mode 100644 index 00000000..739d1bd7 --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.DataGrid/DataGridModule.cs @@ -0,0 +1,46 @@ +/************************************************************************ + + Extended WPF Toolkit + + Copyright (C) 2010-2012 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + This program can be provided to you by Xceed Software Inc. under a + proprietary commercial license agreement for use in non-Open Source + projects. The commercial version of Extended WPF Toolkit also includes + priority technical support, commercial updates, and many additional + useful WPF controls if you license Xceed Business Suite for WPF. + + Visit http://xceed.com and follow @datagrid on Twitter. + + **********************************************************************/ + +using Microsoft.Practices.Prism.Regions; +using Microsoft.Practices.Unity; +using Samples.Infrastructure; +using Samples.Infrastructure.Extensions; +using Samples.Modules.DataGrid.Views; + +namespace Samples.Modules.DataGrid +{ + public class DataGridModule : ModuleBase + { + public DataGridModule( IUnityContainer container, IRegionManager regionManager ) + : base( container, regionManager ) + { + } + + protected override void InitializeModule() + { + RegionManager.RegisterViewWithRegion( RegionNames.NavigationRegion, typeof( NavigationView ) ); + } + + protected override void RegisterViewsAndTypes() + { + Container.RegisterNavigationType( typeof( HomeView ) ); + Container.RegisterNavigationType( typeof( FullVersion ) ); + } + } +} diff --git a/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.DataGrid/Properties/AssemblyInfo.cs b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.DataGrid/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..b629e124 --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.DataGrid/Properties/AssemblyInfo.cs @@ -0,0 +1,72 @@ +/************************************************************************ + + Extended WPF Toolkit + + Copyright (C) 2010-2012 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + This program can be provided to you by Xceed Software Inc. under a + proprietary commercial license agreement for use in non-Open Source + projects. The commercial version of Extended WPF Toolkit also includes + priority technical support, commercial updates, and many additional + useful WPF controls if you license Xceed Business Suite for WPF. + + Visit http://xceed.com and follow @datagrid on Twitter. + + **********************************************************************/ + +using System.Reflection; +using System.Runtime.InteropServices; +using System.Windows; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle( "Extended WPF Toolkit DataGrid Sample" )] +[assembly: AssemblyDescription( "" )] +[assembly: AssemblyConfiguration( "" )] +[assembly: AssemblyCompany( "Xceed Software Inc." )] +[assembly: AssemblyProduct( "Extended WPF Toolkit DataGrid Sample" )] +[assembly: AssemblyCopyright( "Copyright © Xceed Software Inc. 2010-2012" )] +[assembly: AssemblyTrademark( "" )] +[assembly: AssemblyCulture( "" )] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible( false )] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion( "1.0.0.0" )] +[assembly: AssemblyFileVersion( "1.0.0.0" )] diff --git a/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.DataGrid/Samples.Modules.DataGrid.csproj b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.DataGrid/Samples.Modules.DataGrid.csproj new file mode 100644 index 00000000..bdaad47d --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.DataGrid/Samples.Modules.DataGrid.csproj @@ -0,0 +1,116 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {129477D9-F413-495F-BE05-D049575BC16C} + library + Properties + Samples.Modules.DataGrid + Samples.Modules.DataGrid + v4.0 + Client + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\Libs\Prism\Microsoft.Practices.Prism.dll + + + ..\..\..\..\Libs\Prism\Microsoft.Practices.Unity.dll + + + + + + + + + + 4.0 + + + + + + ..\..\..\..\Libs\Xceed.Wpf.DataGrid.Samples.SampleData.dll + + + + + Code + + + FullVersion.xaml + + + HomeView.xaml + + + NavigationView.xaml + + + + + Code + + + + + + {63648392-6CE9-4A60-96D4-F9FD718D29B0} + Xceed.Wpf.DataGrid + + + {A4A049A4-665A-4651-9046-7D06E9D0CCDC} + Samples.Infrastructure + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + + xcopy "$(TargetDir)*.*" "$(SolutionDir)Src\Samples\Samples\bin\$(ConfigurationName)\" /Y +xcopy "$(ProjectDir)Views" "$(SolutionDir)Src\Samples\Samples\bin\$(ConfigurationName)\Samples\$(ProjectName)\" /s /Y /I + + + \ No newline at end of file diff --git a/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.DataGrid/Views/FullVersion.xaml b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.DataGrid/Views/FullVersion.xaml new file mode 100644 index 00000000..e2703f39 --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.DataGrid/Views/FullVersion.xaml @@ -0,0 +1,103 @@ + + + + + + + The full featured version of the DataGrid available commercially will provide + you with extended features like: + + + + Master Details + + + Filter Row + + + Insertion Row + + + Excel Auto-Filtering + + + Column Chooser + + + CardView, CompactCardView + + + 3DView, MultiSurfaceView + + + Statistical Functions and Summary row + + + Print, Print Preview + + + Export to Excel + + + Fixed Column Splitter UI element + + + Persist User Settings + + + Design time support in Visual Studio and Expression Blend + + + Comprehensive documentation fully integrated into Visual Studio + + + Includes a variety of VB.NET and C# sample applications to get you started + + + Office 2007 Themes: Blue, Black, and Silver + + + The Xceed Live Explorer theme + + + Includes Xceed 3D Views for WPF + + + And many more.... + + + + + + + + Click here for more details about the full featured DataGrid control. + + + + + diff --git a/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.DataGrid/Views/FullVersion.xaml.cs b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.DataGrid/Views/FullVersion.xaml.cs new file mode 100644 index 00000000..06fcdf64 --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.DataGrid/Views/FullVersion.xaml.cs @@ -0,0 +1,46 @@ +/************************************************************************ + + Extended WPF Toolkit + + Copyright (C) 2010-2012 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + This program can be provided to you by Xceed Software Inc. under a + proprietary commercial license agreement for use in non-Open Source + projects. The commercial version of Extended WPF Toolkit also includes + priority technical support, commercial updates, and many additional + useful WPF controls if you license Xceed Business Suite for WPF. + + Visit http://xceed.com and follow @datagrid on Twitter. + + **********************************************************************/ + +using Microsoft.Practices.Prism.Regions; +using Samples.Infrastructure.Controls; +using Xceed.Wpf.DataGrid.Samples.SampleData; +using System.Data; +using Xceed.Wpf.DataGrid; +using System.Diagnostics; + +namespace Samples.Modules.DataGrid.Views +{ + /// + /// Interaction logic for FullVersion.xaml + /// + [RegionMemberLifetime( KeepAlive = false )] + public partial class FullVersion : DemoView + { + public FullVersion() + { + InitializeComponent(); + } + + private void Hyperlink_RequestNavigate( object sender, System.Windows.Navigation.RequestNavigateEventArgs e ) + { + Process.Start( new ProcessStartInfo( e.Uri.AbsoluteUri ) ); + e.Handled = true; + } + } +} diff --git a/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.DataGrid/Views/HomeView.xaml b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.DataGrid/Views/HomeView.xaml new file mode 100644 index 00000000..61fb391e --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.DataGrid/Views/HomeView.xaml @@ -0,0 +1,54 @@ + + + +The experience Xceed DataGrid for WPF provides centers on its Tableflow view, which lets you take advantage of a stunning, shaded appearance and capabilities such as inertial smooth scrolling and animated full-column reordering—which mimic the physics of real-life movement. Add to that the datagrid’s zero-lag data virtualization, and you have the fastest WPF datagrid around—in performance and feel. + +It's rock-solid and time-tested, so you can trust it in your most important applications. Constantly evolving—no other datagrid is updated as often—it has more features than any other offering and a flexible, extensible object model. It also provides unbeatable performance by handling millions of rows and thousands of columns, and integrates easily into any WPF app. It’s easy to understand why it’s the most-adopted WPF datagrid available and used by Microsoft in Visual Studio 2010 and by IBM U2 in SystemBuilder 4GL (SB+)! + + + + + + + + + + + + + + + + + + + + diff --git a/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.DataGrid/Views/HomeView.xaml.cs b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.DataGrid/Views/HomeView.xaml.cs new file mode 100644 index 00000000..4c56b5e3 --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.DataGrid/Views/HomeView.xaml.cs @@ -0,0 +1,47 @@ +/************************************************************************ + + Extended WPF Toolkit + + Copyright (C) 2010-2012 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + This program can be provided to you by Xceed Software Inc. under a + proprietary commercial license agreement for use in non-Open Source + projects. The commercial version of Extended WPF Toolkit also includes + priority technical support, commercial updates, and many additional + useful WPF controls if you license Xceed Business Suite for WPF. + + Visit http://xceed.com and follow @datagrid on Twitter. + + **********************************************************************/ + +using Microsoft.Practices.Prism.Regions; +using Samples.Infrastructure.Controls; +using Xceed.Wpf.DataGrid.Samples.SampleData; +using System.Data; +using Xceed.Wpf.DataGrid; + +namespace Samples.Modules.DataGrid.Views +{ + /// + /// Interaction logic for HomeView.xaml + /// + [RegionMemberLifetime( KeepAlive = false )] + public partial class HomeView : DemoView + { + public HomeView() + { + this.Orders = DataProvider.GetNorthwindDataSet().Tables[ "Orders" ]; + InitializeComponent(); + } + + public DataTable Orders + { + get; + private set; + } + + } +} diff --git a/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.DataGrid/Views/NavigationView.xaml b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.DataGrid/Views/NavigationView.xaml new file mode 100644 index 00000000..ae1a7d56 --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.DataGrid/Views/NavigationView.xaml @@ -0,0 +1,32 @@ + + + + + + + - - + + + + + ShowAdvancedOptions="{Binding IsChecked, ElementName=_showAdvancedOptions}" + IsReadOnly="{Binding IsChecked, ElementName=_isReadOnly}"/> diff --git a/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.PropertyGrid/Views/HomeView.xaml.cs b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.PropertyGrid/Views/HomeView.xaml.cs index 3745fa8f..a0a8d253 100644 --- a/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.PropertyGrid/Views/HomeView.xaml.cs +++ b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.PropertyGrid/Views/HomeView.xaml.cs @@ -19,6 +19,7 @@ using Microsoft.Practices.Prism.Regions; using Samples.Infrastructure.Controls; +using System; namespace Samples.Modules.PropertyGrid.Views { @@ -32,5 +33,10 @@ namespace Samples.Modules.PropertyGrid.Views { InitializeComponent(); } + + private void OnButtonClick( object sender, EventArgs e ) + { + _propertyGrid.SelectedObject = sender; + } } } diff --git a/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.Text/Samples.Modules.Text.csproj b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.Text/Samples.Modules.Text.csproj index 33091a37..6ce027d8 100644 --- a/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.Text/Samples.Modules.Text.csproj +++ b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.Text/Samples.Modules.Text.csproj @@ -69,6 +69,9 @@ Code + + AutoSelectTextBoxView.xaml + HomeView.xaml @@ -90,6 +93,10 @@ + + MSBuild:Compile + Designer + MSBuild:Compile Designer diff --git a/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.Text/TextModule.cs b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.Text/TextModule.cs index 5f056680..1f0db4f1 100644 --- a/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.Text/TextModule.cs +++ b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.Text/TextModule.cs @@ -44,6 +44,7 @@ namespace Samples.Modules.Text Container.RegisterNavigationType( typeof( MultiLineTextEditorView ) ); Container.RegisterNavigationType( typeof( RichTextBoxView ) ); Container.RegisterNavigationType( typeof( WatermarkTextBoxView ) ); + Container.RegisterNavigationType( typeof( AutoSelectTextBoxView ) ); } } } diff --git a/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.Text/Views/AutoSelectTextBoxView.xaml b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.Text/Views/AutoSelectTextBoxView.xaml new file mode 100644 index 00000000..c6b4a4bb --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.Text/Views/AutoSelectTextBoxView.xaml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AutoSelectBehavior: + + Controled by the "AutoSelectBehavior" property, the content of the AutoSelectTextBox will be selected or not when the control get the focus. + + + AutoMoveFocus: + + Effect with "MaxLength" property: + + + Setting the "MaxLenght" of the text box allow the focus to move from the AutoSelectTextBox once the max lenght has been reached. + In the following "Telephone Number" fields, the "MaxLenght" property of the control has been set to 3, 3 and 4, respectively + + + + + + + + + + + + + + + + + Effect with Arrow keys + + + The "AutoMoveFocus" at true also allow to navigate the focus thru the controls using the arrow keys to move the focus up, down, left or right. + You are no longer limited to the "left-right" scenario of the "Tab, Shift-Tab" keys. + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Editors/DecimalUpDownEditor.cs b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.Text/Views/AutoSelectTextBoxView.xaml.cs similarity index 66% rename from ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Editors/DecimalUpDownEditor.cs rename to ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.Text/Views/AutoSelectTextBoxView.xaml.cs index b778bcfc..6a7dc340 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Editors/DecimalUpDownEditor.cs +++ b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.Text/Views/AutoSelectTextBoxView.xaml.cs @@ -17,18 +17,20 @@ **********************************************************************/ -namespace Xceed.Wpf.Toolkit.PropertyGrid.Editors +using Microsoft.Practices.Prism.Regions; +using Samples.Infrastructure.Controls; + +namespace Samples.Modules.Text.Views { - public class DecimalUpDownEditor : TypeEditor + /// + /// Interaction logic for WatermarkTextBoxView.xaml + /// + [RegionMemberLifetime( KeepAlive = false )] + public partial class AutoSelectTextBoxView : DemoView { - protected override void SetControlProperties() - { - Editor.BorderThickness = new System.Windows.Thickness( 0 ); - } - - protected override void SetValueDependencyProperty() + public AutoSelectTextBoxView() { - ValueProperty = DecimalUpDown.ValueProperty; + InitializeComponent(); } } } diff --git a/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.Text/Views/MaskedTextBoxView.xaml b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.Text/Views/MaskedTextBoxView.xaml index b1171869..6aba50d4 100644 --- a/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.Text/Views/MaskedTextBoxView.xaml +++ b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.Text/Views/MaskedTextBoxView.xaml @@ -21,6 +21,8 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sample="clr-namespace:Samples.Infrastructure.Controls;assembly=Samples.Infrastructure" xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit" + xmlns:osb="clr-namespace:Xceed.Wpf.Toolkit.Obselete;assembly=WPFToolkit.Extended" + xmlns:s="clr-namespace:System;assembly=mscorlib" Title="MaskedTextBox" Description="The MaskedTextBox control lets you display and edit values based on a mask."> @@ -43,10 +45,12 @@ - + - + @@ -60,23 +64,25 @@ - + - + - + - + + diff --git a/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.Text/Views/MaskedTextBoxView.xaml.cs b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.Text/Views/MaskedTextBoxView.xaml.cs index 8663bd8e..6d9ff25b 100644 --- a/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.Text/Views/MaskedTextBoxView.xaml.cs +++ b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.Text/Views/MaskedTextBoxView.xaml.cs @@ -31,6 +31,12 @@ namespace Samples.Modules.Text.Views public MaskedTextBoxView() { InitializeComponent(); + _mask.TextChanged += new System.Windows.Controls.TextChangedEventHandler( _mask_TextChanged ); + } + + void _mask_TextChanged( object sender, System.Windows.Controls.TextChangedEventArgs e ) + { + _maskedTextBox.Value = null; } } } diff --git a/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.Text/Views/MultiLineTextEditor.xaml b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.Text/Views/MultiLineTextEditor.xaml index 3ef1a469..70dc3365 100644 --- a/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.Text/Views/MultiLineTextEditor.xaml +++ b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.Text/Views/MultiLineTextEditor.xaml @@ -16,6 +16,7 @@ Visit http://xceed.com and follow @datagrid on Twitter. ********************************************************************--> + + Description="The MultiLineTextEditor is a TextBox that allows you to edit text that is too long to display in a regular TextBox. The popup is resizable to accommodate any text."> diff --git a/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.Text/Views/NavigationView.xaml b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.Text/Views/NavigationView.xaml index 37538b50..e18d7a31 100644 --- a/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.Text/Views/NavigationView.xaml +++ b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.Text/Views/NavigationView.xaml @@ -20,12 +20,14 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:views="clr-namespace:Samples.Modules.Text.Views" - Header="Text" Tag="{x:Type views:HomeView}"> + Header="Text" Tag="{x:Type views:HomeView}" + Style="{StaticResource newFeature}" > + + + diff --git a/ExtendedWPFToolkitSolution/Src/Samples/Samples/Samples.csproj b/ExtendedWPFToolkitSolution/Src/Samples/Samples/Samples.csproj index 21cf80f7..b37c4d80 100644 --- a/ExtendedWPFToolkitSolution/Src/Samples/Samples/Samples.csproj +++ b/ExtendedWPFToolkitSolution/Src/Samples/Samples/Samples.csproj @@ -87,6 +87,10 @@ + + {72E591D6-8F83-4D8C-8F67-9C325E623234} + WPFToolkit.Extended + {A4A049A4-665A-4651-9046-7D06E9D0CCDC} Samples.Infrastructure diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/AssemblyVersionInfo.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/AssemblyVersionInfo.cs index 74011485..45843ae6 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/AssemblyVersionInfo.cs +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/AssemblyVersionInfo.cs @@ -22,7 +22,7 @@ internal static class _XceedVersionInfo { [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] - public const string BaseVersion = "1.7"; + public const string BaseVersion = "1.8"; [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] public const string Version = BaseVersion + _XceedVersionInfoCommon.Build; diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/AutoSelectTextBox/Implementation/AutoSelectBehaviorEnum.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/AutoSelectTextBox/Implementation/AutoSelectBehaviorEnum.cs new file mode 100644 index 00000000..2340995d --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/AutoSelectTextBox/Implementation/AutoSelectBehaviorEnum.cs @@ -0,0 +1,31 @@ +/************************************************************************ + + Extended WPF Toolkit + + Copyright (C) 2010-2012 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + This program can be provided to you by Xceed Software Inc. under a + proprietary commercial license agreement for use in non-Open Source + projects. The commercial version of Extended WPF Toolkit also includes + priority technical support, commercial updates, and many additional + useful WPF controls if you license Xceed Business Suite for WPF. + + Visit http://xceed.com and follow @datagrid on Twitter. + + **********************************************************************/ + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Xceed.Wpf.Toolkit +{ + public enum AutoSelectBehavior + { + Never, + OnFocus + } +} diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/AutoSelectTextBox/Implementation/AutoSelectTextBox.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/AutoSelectTextBox/Implementation/AutoSelectTextBox.cs new file mode 100644 index 00000000..87aa6d0b --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/AutoSelectTextBox/Implementation/AutoSelectTextBox.cs @@ -0,0 +1,301 @@ +/************************************************************************ + + Extended WPF Toolkit + + Copyright (C) 2010-2012 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + This program can be provided to you by Xceed Software Inc. under a + proprietary commercial license agreement for use in non-Open Source + projects. The commercial version of Extended WPF Toolkit also includes + priority technical support, commercial updates, and many additional + useful WPF controls if you license Xceed Business Suite for WPF. + + Visit http://xceed.com and follow @datagrid on Twitter. + + **********************************************************************/ + +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows; +using System.Windows.Automation; +using Xceed.Wpf.Toolkit.Core.Utilities; + +namespace Xceed.Wpf.Toolkit +{ + public class AutoSelectTextBox : TextBox + { + static AutoSelectTextBox() + { + AutomationProperties.AutomationIdProperty.OverrideMetadata( typeof( AutoSelectTextBox ), new UIPropertyMetadata( "AutoSelectTextBox" ) ); + } + + #region AutoSelectBehavior PROPERTY + + public AutoSelectBehavior AutoSelectBehavior + { + get + { + return ( AutoSelectBehavior )GetValue( AutoSelectBehaviorProperty ); + } + set + { + SetValue( AutoSelectBehaviorProperty, value ); + } + } + + public static readonly DependencyProperty AutoSelectBehaviorProperty = + DependencyProperty.Register( "AutoSelectBehavior", typeof( AutoSelectBehavior ), typeof( AutoSelectTextBox ), + new UIPropertyMetadata( AutoSelectBehavior.Never ) ); + + #endregion AutoSelectBehavior PROPERTY + + #region AutoMoveFocus PROPERTY + + public bool AutoMoveFocus + { + get + { + return ( bool )GetValue( AutoMoveFocusProperty ); + } + set + { + SetValue( AutoMoveFocusProperty, value ); + } + } + + public static readonly DependencyProperty AutoMoveFocusProperty = + DependencyProperty.Register( "AutoMoveFocus", typeof( bool ), typeof( AutoSelectTextBox ), new UIPropertyMetadata( false ) ); + + #endregion AutoMoveFocus PROPERTY + + #region QueryMoveFocus EVENT + + public static readonly RoutedEvent QueryMoveFocusEvent = EventManager.RegisterRoutedEvent( "QueryMoveFocus", + RoutingStrategy.Bubble, + typeof( QueryMoveFocusEventHandler ), + typeof( AutoSelectTextBox ) ); + #endregion QueryMoveFocus EVENT + + protected override void OnPreviewKeyDown( KeyEventArgs e ) + { + if( !this.AutoMoveFocus ) + { + base.OnPreviewKeyDown( e ); + return; + } + + if( ( e.Key == Key.Left ) + && ( ( Keyboard.Modifiers == ModifierKeys.None ) + || ( Keyboard.Modifiers == ModifierKeys.Control ) ) ) + { + e.Handled = this.MoveFocusLeft(); + } + + if( ( e.Key == Key.Right ) + && ( ( Keyboard.Modifiers == ModifierKeys.None ) + || ( Keyboard.Modifiers == ModifierKeys.Control ) ) ) + { + e.Handled = this.MoveFocusRight(); + } + + if( ( ( e.Key == Key.Up ) || ( e.Key == Key.PageUp ) ) + && ( ( Keyboard.Modifiers == ModifierKeys.None ) + || ( Keyboard.Modifiers == ModifierKeys.Control ) ) ) + { + e.Handled = this.MoveFocusUp(); + } + + if( ( ( e.Key == Key.Down ) || ( e.Key == Key.PageDown ) ) + && ( ( Keyboard.Modifiers == ModifierKeys.None ) + || ( Keyboard.Modifiers == ModifierKeys.Control ) ) ) + { + e.Handled = this.MoveFocusDown(); + } + + base.OnPreviewKeyDown( e ); + } + + protected override void OnPreviewGotKeyboardFocus( KeyboardFocusChangedEventArgs e ) + { + base.OnPreviewGotKeyboardFocus( e ); + + if( this.AutoSelectBehavior == AutoSelectBehavior.OnFocus ) + { + // If the focus was not in one of our child ( or popup ), we select all the text. + if( !TreeHelper.IsDescendantOf( e.OldFocus as DependencyObject, this ) ) + this.SelectAll(); + } + } + + protected override void OnPreviewMouseLeftButtonDown( MouseButtonEventArgs e ) + { + base.OnPreviewMouseLeftButtonDown( e ); + + if( this.AutoSelectBehavior == AutoSelectBehavior.Never ) + return; + + if( this.IsKeyboardFocusWithin == false ) + { + this.Focus(); + e.Handled = true; + } + } + + protected override void OnTextChanged( TextChangedEventArgs e ) + { + base.OnTextChanged( e ); + + if( !this.AutoMoveFocus ) + return; + + if( ( this.Text.Length != 0 ) + && ( this.Text.Length == this.MaxLength ) + && ( this.CaretIndex == this.MaxLength ) ) + { + if( this.CanMoveFocus( FocusNavigationDirection.Right, true ) == true ) + { + FocusNavigationDirection direction = ( this.FlowDirection == FlowDirection.LeftToRight ) + ? FocusNavigationDirection.Right + : FocusNavigationDirection.Left; + + this.MoveFocus( new TraversalRequest( direction ) ); + } + } + } + + private bool CanMoveFocus( FocusNavigationDirection direction, bool reachedMax ) + { + QueryMoveFocusEventArgs e = new QueryMoveFocusEventArgs( direction, reachedMax ); + this.RaiseEvent( e ); + return e.CanMoveFocus; + } + + private bool MoveFocusLeft() + { + if( this.FlowDirection == FlowDirection.LeftToRight ) + { + //occurs only if the cursor is at the beginning of the text + if( ( this.CaretIndex == 0 ) && ( this.SelectionLength == 0 ) ) + { + if( ComponentCommands.MoveFocusBack.CanExecute( null, this ) ) + { + ComponentCommands.MoveFocusBack.Execute( null, this ); + return true; + } + else if( this.CanMoveFocus( FocusNavigationDirection.Left, false ) ) + { + this.MoveFocus( new TraversalRequest( FocusNavigationDirection.Left ) ); + return true; + } + } + } + else + { + //occurs only if the cursor is at the end of the text + if( ( this.CaretIndex == this.Text.Length ) && ( this.SelectionLength == 0 ) ) + { + if( ComponentCommands.MoveFocusBack.CanExecute( null, this ) ) + { + ComponentCommands.MoveFocusBack.Execute( null, this ); + return true; + } + else if( this.CanMoveFocus( FocusNavigationDirection.Left, false ) ) + { + this.MoveFocus( new TraversalRequest( FocusNavigationDirection.Left ) ); + return true; + } + } + } + + return false; + } + + private bool MoveFocusRight() + { + if( this.FlowDirection == FlowDirection.LeftToRight ) + { + //occurs only if the cursor is at the beginning of the text + if( ( this.CaretIndex == this.Text.Length ) && ( this.SelectionLength == 0 ) ) + { + if( ComponentCommands.MoveFocusForward.CanExecute( null, this ) ) + { + ComponentCommands.MoveFocusForward.Execute( null, this ); + return true; + } + else if( this.CanMoveFocus( FocusNavigationDirection.Right, false ) ) + { + this.MoveFocus( new TraversalRequest( FocusNavigationDirection.Right ) ); + return true; + } + } + } + else + { + //occurs only if the cursor is at the end of the text + if( ( this.CaretIndex == 0 ) && ( this.SelectionLength == 0 ) ) + { + if( ComponentCommands.MoveFocusForward.CanExecute( null, this ) ) + { + ComponentCommands.MoveFocusForward.Execute( null, this ); + return true; + } + else if( this.CanMoveFocus( FocusNavigationDirection.Right, false ) ) + { + this.MoveFocus( new TraversalRequest( FocusNavigationDirection.Right ) ); + return true; + } + } + } + + return false; + } + + private bool MoveFocusUp() + { + int lineNumber = this.GetLineIndexFromCharacterIndex( this.SelectionStart ); + + //occurs only if the cursor is on the first line + if( lineNumber == 0 ) + { + if( ComponentCommands.MoveFocusUp.CanExecute( null, this ) ) + { + ComponentCommands.MoveFocusUp.Execute( null, this ); + return true; + } + else if( this.CanMoveFocus( FocusNavigationDirection.Up, false ) ) + { + this.MoveFocus( new TraversalRequest( FocusNavigationDirection.Up ) ); + return true; + } + } + + return false; + } + + private bool MoveFocusDown() + { + int lineNumber = this.GetLineIndexFromCharacterIndex( this.SelectionStart ); + + //occurs only if the cursor is on the first line + if( lineNumber == ( this.LineCount - 1 ) ) + { + if( ComponentCommands.MoveFocusDown.CanExecute( null, this ) ) + { + ComponentCommands.MoveFocusDown.Execute( null, this ); + return true; + } + else if( this.CanMoveFocus( FocusNavigationDirection.Down, false ) ) + { + this.MoveFocus( new TraversalRequest( FocusNavigationDirection.Down ) ); + return true; + } + } + + return false; + } + } +} + diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/AutoSelectTextBox/Implementation/QueryMoveFocusEventArgs.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/AutoSelectTextBox/Implementation/QueryMoveFocusEventArgs.cs new file mode 100644 index 00000000..b77d1772 --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/AutoSelectTextBox/Implementation/QueryMoveFocusEventArgs.cs @@ -0,0 +1,76 @@ +/************************************************************************ + + Extended WPF Toolkit + + Copyright (C) 2010-2012 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + This program can be provided to you by Xceed Software Inc. under a + proprietary commercial license agreement for use in non-Open Source + projects. The commercial version of Extended WPF Toolkit also includes + priority technical support, commercial updates, and many additional + useful WPF controls if you license Xceed Business Suite for WPF. + + Visit http://xceed.com and follow @datagrid on Twitter. + + **********************************************************************/ + +using System.Windows; +using System.Windows.Input; + +namespace Xceed.Wpf.Toolkit +{ + [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Design", "CA1003:UseGenericEventHandlerInstances" )] + public delegate void QueryMoveFocusEventHandler( object sender, QueryMoveFocusEventArgs e ); + + public class QueryMoveFocusEventArgs : RoutedEventArgs + { + //default CTOR private to prevent its usage. + private QueryMoveFocusEventArgs() + { + } + + //internal to prevent anybody from building this type of event. + internal QueryMoveFocusEventArgs( FocusNavigationDirection direction, bool reachedMaxLength ) + : base( AutoSelectTextBox.QueryMoveFocusEvent ) + { + m_navigationDirection = direction; + m_reachedMaxLength = reachedMaxLength; + } + + public FocusNavigationDirection FocusNavigationDirection + { + get + { + return m_navigationDirection; + } + } + + public bool ReachedMaxLength + { + get + { + return m_reachedMaxLength; + } + } + + public bool CanMoveFocus + { + get + { + return m_canMove; + } + set + { + m_canMove = value; + } + } + + private FocusNavigationDirection m_navigationDirection; + private bool m_reachedMaxLength; + private bool m_canMove = true; //defaults to true... if nobody does nothing, then its capable of moving focus. + + } +} diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/CheckComboBox/Implementation/CheckComboBox.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/CheckComboBox/Implementation/CheckComboBox.cs index be17afce..1b06dc3c 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/CheckComboBox/Implementation/CheckComboBox.cs +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/CheckComboBox/Implementation/CheckComboBox.cs @@ -22,11 +22,14 @@ using System.Linq; using System.Windows; using System.Windows.Input; using Xceed.Wpf.Toolkit.Primitives; +using Xceed.Wpf.Toolkit.Core.Utilities; namespace Xceed.Wpf.Toolkit { public class CheckComboBox : Selector { + private ValueChangeHelper _displayMemberPathValuesChangeHelper; + #region Constructors static CheckComboBox() @@ -37,6 +40,7 @@ namespace Xceed.Wpf.Toolkit public CheckComboBox() { Mouse.AddPreviewMouseDownOutsideCapturedElementHandler( this, OnMouseDownOutsideCapturedElement ); + _displayMemberPathValuesChangeHelper = new ValueChangeHelper( this.OnDisplayMemberPathValuesChanged ); } #endregion //Constructors @@ -98,7 +102,13 @@ namespace Xceed.Wpf.Toolkit protected override void OnDisplayMemberPathChanged( string oldDisplayMemberPath, string newDisplayMemberPath ) { base.OnDisplayMemberPathChanged( oldDisplayMemberPath, newDisplayMemberPath ); - UpdateText(); + this.UpdateDisplayMemberPathValuesBindings(); + } + + protected override void OnItemsSourceChanged( System.Collections.IEnumerable oldValue, System.Collections.IEnumerable newValue ) + { + base.OnItemsSourceChanged( oldValue, newValue ); + this.UpdateDisplayMemberPathValuesBindings(); } #endregion //Base Class Overrides @@ -114,6 +124,16 @@ namespace Xceed.Wpf.Toolkit #region Methods + private void UpdateDisplayMemberPathValuesBindings() + { + _displayMemberPathValuesChangeHelper.UpdateValueSource( ItemsCollection, this.DisplayMemberPath ); + } + + private void OnDisplayMemberPathValuesChanged() + { + this.UpdateText(); + } + private void UpdateText() { #if VS2008 diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/ColorCanvas/Implementation/ColorCanvas.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/ColorCanvas/Implementation/ColorCanvas.cs index 01a0031c..d0303af0 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/ColorCanvas/Implementation/ColorCanvas.cs +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/ColorCanvas/Implementation/ColorCanvas.cs @@ -25,17 +25,20 @@ using System.Windows.Media; using Xceed.Wpf.Toolkit.Core.Utilities; using Xceed.Wpf.Toolkit.Primitives; using System.IO; +using System; namespace Xceed.Wpf.Toolkit { [TemplatePart( Name = PART_ColorShadingCanvas, Type = typeof( Canvas ) )] [TemplatePart( Name = PART_ColorShadeSelector, Type = typeof( Canvas ) )] [TemplatePart( Name = PART_SpectrumSlider, Type = typeof( ColorSpectrumSlider ) )] + [TemplatePart( Name = PART_HexadecimalTextBox, Type = typeof( TextBox ) )] public class ColorCanvas : Control { private const string PART_ColorShadingCanvas = "PART_ColorShadingCanvas"; private const string PART_ColorShadeSelector = "PART_ColorShadeSelector"; private const string PART_SpectrumSlider = "PART_SpectrumSlider"; + private const string PART_HexadecimalTextBox = "PART_HexadecimalTextBox"; #region Private Members @@ -43,6 +46,7 @@ namespace Xceed.Wpf.Toolkit private Canvas _colorShadingCanvas; private Canvas _colorShadeSelector; private ColorSpectrumSlider _spectrumSlider; + private TextBox _hexadecimalTextBox; private Point? _currentColorPosition; private bool _surpressPropertyChanged; @@ -74,7 +78,7 @@ namespace Xceed.Wpf.Toolkit protected virtual void OnSelectedColorChanged( Color oldValue, Color newValue ) { - HexadecimalString = GetFormatedColorString( newValue ); + SetHexadecimalStringProperty( GetFormatedColorString( newValue ), false ); UpdateRGBValues( newValue ); UpdateColorShadeSelectorPosition( newValue ); @@ -237,6 +241,8 @@ namespace Xceed.Wpf.Toolkit string currentColorString = GetFormatedColorString( SelectedColor ); if( !currentColorString.Equals( newColorString ) ) UpdateSelectedColor( ( Color )ColorConverter.ConvertFromString( newColorString ) ); + + SetHexadecimalTextBoxTextProperty( newValue ); } private static object OnCoerceHexadecimalString( DependencyObject d, object basevalue ) @@ -251,16 +257,19 @@ namespace Xceed.Wpf.Toolkit private object OnCoerceHexadecimalString( object newValue ) { var value = newValue as string; + string retValue = value; + try { ColorConverter.ConvertFromString( value ); } catch { + //When HexadecimalString is changed via Code-Behind and hexadecimal format is bad, throw. throw new InvalidDataException( "Color provided is not in the correct format." ); } - return value; + return retValue; } #endregion //HexadecimalString @@ -289,7 +298,7 @@ namespace Xceed.Wpf.Toolkit protected virtual void OnUsingAlphaChannelChanged() { - HexadecimalString = GetFormatedColorString( SelectedColor ); + SetHexadecimalStringProperty( GetFormatedColorString( SelectedColor ), false ); } #endregion //UsingAlphaChannel @@ -342,17 +351,31 @@ namespace Xceed.Wpf.Toolkit if( _spectrumSlider != null ) _spectrumSlider.ValueChanged += SpectrumSlider_ValueChanged; + if( _hexadecimalTextBox != null ) + _hexadecimalTextBox.LostFocus -= new RoutedEventHandler( HexadecimalTextBox_LostFocus ); + + _hexadecimalTextBox = GetTemplateChild( PART_HexadecimalTextBox ) as TextBox; + + if( _hexadecimalTextBox != null ) + _hexadecimalTextBox.LostFocus += new RoutedEventHandler( HexadecimalTextBox_LostFocus ); + UpdateRGBValues( SelectedColor ); UpdateColorShadeSelectorPosition( SelectedColor ); + + // When changing theme, HexadecimalString needs to be set since it is not binded. + SetHexadecimalTextBoxTextProperty( GetFormatedColorString( SelectedColor ) ); } - protected override void OnPreviewKeyDown( KeyEventArgs e ) + protected override void OnKeyDown( KeyEventArgs e ) { - //hitting enter on textbox will update value of underlying source + base.OnKeyDown( e ); + + //hitting enter on textbox will update Hexadecimal string if( e.Key == Key.Enter && e.OriginalSource is TextBox ) { - BindingExpression be = ( ( TextBox )e.OriginalSource ).GetBindingExpression( TextBox.TextProperty ); - be.UpdateSource(); + TextBox textBox = ( TextBox )e.OriginalSource; + if( textBox.Name == PART_HexadecimalTextBox ) + SetHexadecimalStringProperty( textBox.Text, true ); } } @@ -404,6 +427,12 @@ namespace Xceed.Wpf.Toolkit } } + void HexadecimalTextBox_LostFocus( object sender, RoutedEventArgs e ) + { + TextBox textbox = sender as TextBox; + SetHexadecimalStringProperty( textbox.Text, true ); + } + #endregion //Event Handlers #region Events @@ -503,7 +532,7 @@ namespace Xceed.Wpf.Toolkit var currentColor = ColorUtilities.ConvertHsvToRgb( hsv.H, hsv.S, hsv.V ); currentColor.A = A; SelectedColor = currentColor; - HexadecimalString = GetFormatedColorString( SelectedColor ); + SetHexadecimalStringProperty( GetFormatedColorString( SelectedColor ), false ); } private string GetFormatedColorString( Color colorToFormat ) @@ -516,6 +545,34 @@ namespace Xceed.Wpf.Toolkit return ColorUtilities.FormatColorString( stringToFormat, UsingAlphaChannel ); } + private void SetHexadecimalStringProperty( string newValue, bool modifyFromUI ) + { + if( modifyFromUI ) + { + try + { + ColorConverter.ConvertFromString( newValue ); + HexadecimalString = newValue; + } + catch + { + //When HexadecimalString is changed via UI and hexadecimal format is bad, keep the previous HexadecimalString. + SetHexadecimalTextBoxTextProperty( HexadecimalString ); + } + } + else + { + //When HexadecimalString is changed via Code-Behind, hexadecimal format will be evaluated in OnCoerceHexadecimalString() + HexadecimalString = newValue; + } + } + + private void SetHexadecimalTextBoxTextProperty( string newValue ) + { + if( _hexadecimalTextBox != null ) + _hexadecimalTextBox.Text = newValue; + } + #endregion //Methods } } diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/ColorCanvas/Themes/Generic.xaml b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/ColorCanvas/Themes/Generic.xaml index 7164d0a0..4bb44947 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/ColorCanvas/Themes/Generic.xaml +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/ColorCanvas/Themes/Generic.xaml @@ -260,7 +260,7 @@ - + diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/ColorPicker/Implementation/ColorPicker.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/ColorPicker/Implementation/ColorPicker.cs index 42aca48a..899743e0 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/ColorPicker/Implementation/ColorPicker.cs +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/ColorPicker/Implementation/ColorPicker.cs @@ -343,7 +343,7 @@ namespace Xceed.Wpf.Toolkit { return ( bool )GetValue( UsingAlphaChannelProperty ); } - protected set + set { SetValue( UsingAlphaChannelProperty, value ); } diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Converters/WizardPageButtonVisibilityConverter.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Converters/WizardPageButtonVisibilityConverter.cs index 1c8bc7a9..317fafbf 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Converters/WizardPageButtonVisibilityConverter.cs +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Converters/WizardPageButtonVisibilityConverter.cs @@ -28,7 +28,9 @@ namespace Xceed.Wpf.Toolkit.Core.Converters public object Convert( object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture ) { Visibility wizardVisibility = ( Visibility )values[ 0 ]; - WizardPageButtonVisibility wizardPageVisibility = ( WizardPageButtonVisibility )values[ 1 ]; + WizardPageButtonVisibility wizardPageVisibility = ( (values[ 1 ] == null) || (values[ 1 ] == DependencyProperty.UnsetValue) ) + ? WizardPageButtonVisibility.Hidden + : ( WizardPageButtonVisibility )values[ 1 ]; Visibility visibility = Visibility.Visible; diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Input/IValidateInput.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Input/IValidateInput.cs new file mode 100644 index 00000000..15d600da --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Input/IValidateInput.cs @@ -0,0 +1,32 @@ +/************************************************************************ + + Extended WPF Toolkit + + Copyright (C) 2010-2012 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + This program can be provided to you by Xceed Software Inc. under a + proprietary commercial license agreement for use in non-Open Source + projects. The commercial version of Extended WPF Toolkit also includes + priority technical support, commercial updates, and many additional + useful WPF controls if you license Xceed Business Suite for WPF. + + Visit http://xceed.com and follow @datagrid on Twitter. + + **********************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Xceed.Wpf.Toolkit.Core.Input +{ + public interface IValidateInput + { + event InputValidationErrorEventHandler InputValidationError; + void CommitInput(); + } +} diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Input/InputValidationErrorEventArgs.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Input/InputValidationErrorEventArgs.cs new file mode 100644 index 00000000..312c90ce --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Input/InputValidationErrorEventArgs.cs @@ -0,0 +1,46 @@ +/************************************************************************ + + Extended WPF Toolkit + + Copyright (C) 2010-2012 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + This program can be provided to you by Xceed Software Inc. under a + proprietary commercial license agreement for use in non-Open Source + projects. The commercial version of Extended WPF Toolkit also includes + priority technical support, commercial updates, and many additional + useful WPF controls if you license Xceed Business Suite for WPF. + + Visit http://xceed.com and follow @datagrid on Twitter. + + **********************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Xceed.Wpf.Toolkit.Core.Input +{ + public delegate void InputValidationErrorEventHandler( object sender, InputValidationErrorEventArgs e ); + + public class InputValidationErrorEventArgs : EventArgs + { + public InputValidationErrorEventArgs( string errorMsg ) + { + _errorMessage = errorMsg; + } + + public string ErrorMessage + { + get + { + return _errorMessage; + } + } + + private string _errorMessage; + } +} diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/CachedTextInfo.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/CachedTextInfo.cs new file mode 100644 index 00000000..d887ffb8 --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/CachedTextInfo.cs @@ -0,0 +1,57 @@ +/************************************************************************ + + Extended WPF Toolkit + + Copyright (C) 2010-2012 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + This program can be provided to you by Xceed Software Inc. under a + proprietary commercial license agreement for use in non-Open Source + projects. The commercial version of Extended WPF Toolkit also includes + priority technical support, commercial updates, and many additional + useful WPF controls if you license Xceed Business Suite for WPF. + + Visit http://xceed.com and follow @datagrid on Twitter. + + **********************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Controls; + +namespace Xceed.Wpf.Toolkit.Primitives +{ + internal class CachedTextInfo : ICloneable + { + private CachedTextInfo( string text, int caretIndex, int selectionStart, int selectionLength ) + { + this.Text = text; + this.CaretIndex = caretIndex; + this.SelectionStart = selectionStart; + this.SelectionLength = selectionLength; + } + + public CachedTextInfo( TextBox textBox ) + : this( textBox.Text, textBox.CaretIndex, textBox.SelectionStart, textBox.SelectionLength ) + { + } + + public string Text { get; private set; } + public int CaretIndex { get; private set; } + public int SelectionStart { get; private set; } + public int SelectionLength { get; private set; } + + #region ICloneable Members + + public object Clone() + { + return new CachedTextInfo( this.Text, this.CaretIndex, this.SelectionStart, this.SelectionLength ); + } + + #endregion + } +} diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/Selector.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/Selector.cs index f8cfcd3f..12c902f4 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/Selector.cs +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/Selector.cs @@ -26,16 +26,28 @@ using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Input; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Reflection; +using Xceed.Wpf.Toolkit.Core.Utilities; namespace Xceed.Wpf.Toolkit.Primitives { - public class Selector : ItemsControl //should probably make this control an ICommandSource + public class Selector : ItemsControl, IWeakEventListener //should probably make this control an ICommandSource { #region Members - private bool _ignoreSetSelectedValue; - private bool _surpressSelectionChanged; - private bool _surpressSelectedValueChanged; + private bool _surpressItemSelectionChanged; + private bool _ignoreSelectedItemChanged; + private bool _ignoreSelectedValueChanged; + private int _ignoreSelectedItemsCollectionChanged; + private int _ignoreSelectedMemberPathValuesChanged; + private IList _selectedItems; + + private ValueChangeHelper _selectedMemberPathValuesHelper; + private ValueChangeHelper _valueMemberPathValuesHelper; + + #endregion //Members @@ -43,9 +55,11 @@ namespace Xceed.Wpf.Toolkit.Primitives public Selector() { - SelectedItems = new ObservableCollection(); - AddHandler( Selector.SelectedEvent, new RoutedEventHandler( Selector_ItemSelected ) ); - AddHandler( Selector.UnSelectedEvent, new RoutedEventHandler( Selector_ItemUnselected ) ); + this.SelectedItems = new ObservableCollection(); + AddHandler( Selector.SelectedEvent, new RoutedEventHandler( ( s, args ) => this.OnItemSelectionChangedCore( args, false ) ) ); + AddHandler( Selector.UnSelectedEvent, new RoutedEventHandler( ( s, args ) => this.OnItemSelectionChangedCore( args, true ) ) ); + _selectedMemberPathValuesHelper = new ValueChangeHelper( this.OnSelectedMemberPathValuesChanged ); + _valueMemberPathValuesHelper = new ValueChangeHelper( this.OnValueMemberPathValuesChanged ); } #endregion //Constructors @@ -88,7 +102,9 @@ namespace Xceed.Wpf.Toolkit.Primitives #endregion - public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register( "SelectedItem", typeof( object ), typeof( Selector ), new UIPropertyMetadata( null ) ); + #region SelectedItem property + + public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register( "SelectedItem", typeof( object ), typeof( Selector ), new UIPropertyMetadata( null, OnSelectedItemChanged ) ); public object SelectedItem { get @@ -101,22 +117,91 @@ namespace Xceed.Wpf.Toolkit.Primitives } } - //Since you cannot data bind to ReadOnly DependencyProperty, I am leaving this a public get/set DP. This will allow you to data bind to the SelectedItems from a ViewModel, but it is - //intended to be ReadOnly. So you MUST set the binding Mode=OneWayToSource. Otherwise it will not behave as expected. - public static readonly DependencyProperty SelectedItemsProperty = DependencyProperty.Register( "SelectedItems", typeof( IList ), typeof( Selector ), new UIPropertyMetadata( null ) ); + private static void OnSelectedItemChanged( DependencyObject sender, DependencyPropertyChangedEventArgs args ) + { + ( ( Selector )sender ).OnSelectedItemChanged( args.OldValue, args.NewValue ); + } + + private void OnSelectedItemChanged( object oldValue, object newValue ) + { + if( _ignoreSelectedItemChanged ) + return; + + _ignoreSelectedItemsCollectionChanged++; + SelectedItems.Clear(); + if( newValue != null ) + { + SelectedItems.Add( newValue ); + } + this.UpdateFromSelectedItems(); + _ignoreSelectedItemsCollectionChanged--; + } + + #endregion + + #region SelectedItems Property + public IList SelectedItems { get { - return ( IList )GetValue( SelectedItemsProperty ); + return _selectedItems; + } + private set + { + if( value == null ) + throw new ArgumentNullException( "value" ); + + INotifyCollectionChanged oldCollection = _selectedItems as INotifyCollectionChanged; + INotifyCollectionChanged newCollection = value as INotifyCollectionChanged; + + if( oldCollection != null ) + { + CollectionChangedEventManager.RemoveListener( oldCollection, this ); + } + + if( newCollection != null ) + { + CollectionChangedEventManager.AddListener( newCollection, this ); + } + + _selectedItems = value; + + this.UpdateFromSelectedItems(); + } + } + + #endregion SelectedItems + + + #region SelectedItemsOverride property + + public static readonly DependencyProperty SelectedItemsOverrideProperty = DependencyProperty.Register( "SelectedItemsOverride", typeof( IList ), typeof( Selector ), new UIPropertyMetadata( null, SelectedItemsOverrideChanged ) ); + public IList SelectedItemsOverride + { + get + { + return ( IList )GetValue( SelectedItemsOverrideProperty ); } set { - SetValue( SelectedItemsProperty, value ); + SetValue( SelectedItemsOverrideProperty, value ); } } - public static readonly DependencyProperty SelectedMemberPathProperty = DependencyProperty.Register( "SelectedMemberPath", typeof( string ), typeof( Selector ), new UIPropertyMetadata( null ) ); + private static void SelectedItemsOverrideChanged( DependencyObject sender, DependencyPropertyChangedEventArgs args ) + { + ( ( Selector )sender ).OnSelectedItemsOverrideChanged( ( IList )args.OldValue, ( IList )args.NewValue ); + } + + private void OnSelectedItemsOverrideChanged( IList oldValue, IList newValue ) + { + this.SelectedItems = ( newValue != null ) ? newValue : new ObservableCollection(); + } + + #endregion + + public static readonly DependencyProperty SelectedMemberPathProperty = DependencyProperty.Register( "SelectedMemberPath", typeof( string ), typeof( Selector ), new UIPropertyMetadata( null, OnSelectedMemberPathChanged ) ); public string SelectedMemberPath { get @@ -129,6 +214,11 @@ namespace Xceed.Wpf.Toolkit.Primitives } } + private static void OnSelectedMemberPathChanged( DependencyObject o, DependencyPropertyChangedEventArgs e ) + { + ( ( Selector )o ).UpdateSelectedMemberPathValuesBindings(); + } + #region SelectedValue public static readonly DependencyProperty SelectedValueProperty = DependencyProperty.Register( "SelectedValue", typeof( string ), typeof( Selector ), new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnSelectedValueChanged ) ); @@ -153,10 +243,10 @@ namespace Xceed.Wpf.Toolkit.Primitives protected virtual void OnSelectedValueChanged( string oldValue, string newValue ) { - if( _surpressSelectedValueChanged ) + if( _ignoreSelectedValueChanged ) return; - UpdateSelectedItemsFromSelectedValue(); + UpdateFromSelectedValue(); } #endregion //SelectedValue @@ -178,7 +268,20 @@ namespace Xceed.Wpf.Toolkit.Primitives private static void OnValueMemberPathChanged( DependencyObject o, DependencyPropertyChangedEventArgs e ) { - ( ( Selector )o ).UpdateSelectedValue(); + + ( ( Selector )o ).UpdateValueMemberPathValuesBindings(); + } + + #endregion + + #region ItemsCollection Property + + protected IEnumerable ItemsCollection + { + get + { + return ItemsSource ?? ( ( IEnumerable )Items ?? ( IEnumerable )new object[ 0 ] ); + } } #endregion @@ -199,79 +302,65 @@ namespace Xceed.Wpf.Toolkit.Primitives protected override void PrepareContainerForItemOverride( DependencyObject element, object item ) { - _surpressSelectionChanged = true; + base.PrepareContainerForItemOverride( element, item ); + + _surpressItemSelectionChanged = true; var selectorItem = element as FrameworkElement; - //first try resolving SelectorItem.IsSelected by data binding to the SelectedMemeberPath property - if( !String.IsNullOrEmpty( SelectedMemberPath ) ) + selectorItem.SetValue( SelectorItem.IsSelectedProperty, SelectedItems.Contains(item) ); + + _surpressItemSelectionChanged = false; + } + + protected override void OnItemsSourceChanged( IEnumerable oldValue, IEnumerable newValue ) + { + base.OnItemsSourceChanged( oldValue, newValue ); + + var oldCollection = oldValue as INotifyCollectionChanged; + var newCollection = newValue as INotifyCollectionChanged; + + if( oldCollection != null ) { - Binding selectedBinding = new Binding( SelectedMemberPath ) - { - Mode = BindingMode.TwoWay, - Source = item - }; - selectorItem.SetBinding( SelectorItem.IsSelectedProperty, selectedBinding ); + CollectionChangedEventManager.RemoveListener( oldCollection, this ); } - //now let's search the SelectedItems for the current item. If it's there then mark it as selected - if( SelectedItems != null ) + if( newCollection != null ) { - foreach( object selectedItem in SelectedItems ) - { - //a match was found so select it and get the hell out of here - if( item.Equals( selectedItem ) ) - { - selectorItem.SetValue( SelectorItem.IsSelectedProperty, true ); - break; - } - } + CollectionChangedEventManager.AddListener( newCollection, this ); } - base.PrepareContainerForItemOverride( element, item ); - _surpressSelectionChanged = false; + this.RemoveUnavailableSelectedItems(); + this.UpdateSelectedMemberPathValuesBindings(); + this.UpdateValueMemberPathValuesBindings(); } #endregion //Base Class Overrides #region Events - public static readonly RoutedEvent SelectedEvent = EventManager.RegisterRoutedEvent( "SelectedEvent", RoutingStrategy.Bubble, typeof( SelectedItemChangedEventHandler ), typeof( Selector ) ); - public static readonly RoutedEvent UnSelectedEvent = EventManager.RegisterRoutedEvent( "UnSelectedEvent", RoutingStrategy.Bubble, typeof( SelectedItemChangedEventHandler ), typeof( Selector ) ); + public static readonly RoutedEvent SelectedEvent = EventManager.RegisterRoutedEvent( "SelectedEvent", RoutingStrategy.Bubble, typeof( RoutedEventHandler ), typeof( Selector ) ); + public static readonly RoutedEvent UnSelectedEvent = EventManager.RegisterRoutedEvent( "UnSelectedEvent", RoutingStrategy.Bubble, typeof( RoutedEventHandler ), typeof( Selector ) ); - public static readonly RoutedEvent SelectedItemChangedEvent = EventManager.RegisterRoutedEvent( "SelectedItemChanged", RoutingStrategy.Bubble, typeof( SelectedItemChangedEventHandler ), typeof( Selector ) ); - public event SelectedItemChangedEventHandler SelectedItemChanged + public static readonly RoutedEvent ItemSelectionChangedEvent = EventManager.RegisterRoutedEvent( "ItemSelectionChanged", RoutingStrategy.Bubble, typeof( ItemSelectionChangedEventHandler ), typeof( Selector ) ); + public event ItemSelectionChangedEventHandler ItemSelectionChanged { add { - AddHandler( SelectedItemChangedEvent, value ); + AddHandler( ItemSelectionChangedEvent, value ); } remove { - RemoveHandler( SelectedItemChangedEvent, value ); + RemoveHandler( ItemSelectionChangedEvent, value ); } } #endregion //Events - #region Event Handlers - - protected virtual void Selector_ItemSelected( object sender, RoutedEventArgs e ) - { - OnItemSelected( e.OriginalSource, false ); - } - - protected virtual void Selector_ItemUnselected( object sender, RoutedEventArgs e ) - { - OnItemSelected( e.OriginalSource, true ); - } - - #endregion //Event Handlers - #region Methods protected object GetItemValue( object item ) { - if( !String.IsNullOrEmpty( ValueMemberPath ) && (item != null)) + if( !String.IsNullOrEmpty( ValueMemberPath ) && ( item != null ) ) { var property = item.GetType().GetProperty( ValueMemberPath ); if( property != null ) @@ -281,49 +370,86 @@ namespace Xceed.Wpf.Toolkit.Primitives return item; } - protected string GetDelimitedValue( object value ) + protected object ResolveItemByValue( string value ) { - return String.Format( "{0}{1}", value, Delimiter ); + if( !String.IsNullOrEmpty( ValueMemberPath ) ) + { + foreach( object item in ItemsCollection ) + { + var property = item.GetType().GetProperty( ValueMemberPath ); + if( property != null ) + { + var propertyValue = property.GetValue( item, null ); + if( value.Equals( propertyValue.ToString(), StringComparison.InvariantCultureIgnoreCase ) ) + return item; + } + } + } + + return value; } - protected virtual void OnItemSelected( object itemContainer, bool remove ) + private bool? GetSelectedMemberPathValue( object item ) { - object item = this.ItemContainerGenerator.ItemFromContainer( ( DependencyObject )itemContainer ); - Update( item, remove ); - RaiseSelectedItemChangedEvent( item, !remove ); //inverse the remove paramter to correctly reflect the IsSelected state + PropertyInfo prop = this.GetSelectedMemberPathProperty(item); + + return ( prop != null ) + ? ( bool )prop.GetValue( item, null ) + : ( bool? )null; } - protected virtual void RaiseSelectedItemChangedEvent( object item, bool isSelected ) + private void SetSelectedMemberPathValue( object item, bool value ) { - if( _surpressSelectionChanged ) - return; - - RaiseEvent( new SelectedItemChangedEventArgs( Selector.SelectedItemChangedEvent, this, item, isSelected ) ); + PropertyInfo prop = this.GetSelectedMemberPathProperty(item); - if( Command != null ) - Command.Execute( item ); + if( prop != null ) + { + prop.SetValue( item, value, null ); + } } - protected virtual void Update( object item, bool remove ) + private PropertyInfo GetSelectedMemberPathProperty(object item) { - UpdateSelectedItem( item ); - UpdateSelectedItems( item, remove ); - UpdateSelectedValue(); + PropertyInfo propertyInfo = null; + if( !String.IsNullOrEmpty( SelectedMemberPath ) && ( item != null ) ) + { + var property = item.GetType().GetProperty( SelectedMemberPath ); + if( property != null && property.PropertyType == typeof( bool ) ) + { + propertyInfo = property; + } + } + + return propertyInfo; } - private void UpdateSelectedItem( object item ) + /// + /// When SelectedItems collection implements INotifyPropertyChanged, this is the callback. + /// + /// + /// + private void OnSelectedItemsCollectionChanged( object sender, NotifyCollectionChangedEventArgs e ) { - SelectedItem = item; + if( _ignoreSelectedItemsCollectionChanged > 0 ) + return; + + // Keep it simple for now. Just update all + this.UpdateFromSelectedItems(); } - private void UpdateSelectedItems( object item, bool remove ) + private void OnItemSelectionChangedCore( RoutedEventArgs args, bool unselected ) { - if( SelectedItems == null ) - SelectedItems = new ObservableCollection(); + object item = this.ItemContainerGenerator.ItemFromContainer( ( DependencyObject )args.OriginalSource ); - if( remove ) + // When the item is it's own container, "UnsetValue" will be returned. + if( item == DependencyProperty.UnsetValue ) { - if( SelectedItems.Contains( item ) ) + item = args.OriginalSource; + } + + if( unselected ) + { + while( SelectedItems.Contains( item ) ) SelectedItems.Remove( item ); } else @@ -331,116 +457,263 @@ namespace Xceed.Wpf.Toolkit.Primitives if( !SelectedItems.Contains( item ) ) SelectedItems.Add( item ); } + + OnItemSelectionChanged( + new ItemSelectionChangedEventArgs( Selector.ItemSelectionChangedEvent, this, item, !unselected ) ); } - private void UpdateSelectedValue() + /// + /// When the ItemsSource implements INotifyPropertyChanged, this is the change callback. + /// + /// + /// + private void OnItemsSourceCollectionChanged( object sender, NotifyCollectionChangedEventArgs args ) { - //get out of here if we don't want to set the SelectedValue - if( _ignoreSetSelectedValue ) + this.RemoveUnavailableSelectedItems(); + this.UpdateSelectedMemberPathValuesBindings(); + this.UpdateValueMemberPathValuesBindings(); + } + + /// + /// This is called when any value of any item referenced by SelectedMemberPath + /// is modified. This may affect the SelectedItems collection. + /// + private void OnSelectedMemberPathValuesChanged() + { + if( _ignoreSelectedMemberPathValuesChanged > 0 ) return; - _surpressSelectedValueChanged = true; + this.UpdateFromSelectedMemberPathValues(); + } + + /// + /// This is called when any value of any item referenced by ValueMemberPath + /// is modified. This will affect the SelectedValue property + /// + private void OnValueMemberPathValuesChanged() + { + this.UpdateSelectedValue(); + } + + private void UpdateSelectedMemberPathValuesBindings() + { + _selectedMemberPathValuesHelper.UpdateValueSource( ItemsCollection, SelectedMemberPath ); + } + + private void UpdateValueMemberPathValuesBindings() + { + _valueMemberPathValuesHelper.UpdateValueSource( ItemsCollection, ValueMemberPath ); + } + /// + /// This method will be called when the "IsSelected" property of an SelectorItem + /// has been modified. + /// + /// + protected virtual void OnItemSelectionChanged( ItemSelectionChangedEventArgs args ) + { + if( _surpressItemSelectionChanged ) + return; + + RaiseEvent( args ); + + if( Command != null ) + Command.Execute( args.Item ); + } + + /// + /// Updates the SelectedValue property based on what is present in the SelectedItems property. + /// + private void UpdateSelectedValue() + { #if VS2008 string newValue = String.Join( Delimiter, SelectedItems.Cast().Select( x => GetItemValue( x ).ToString() ).ToArray() ); #else string newValue = String.Join( Delimiter, SelectedItems.Cast().Select( x => GetItemValue( x ) ) ); #endif if( String.IsNullOrEmpty( SelectedValue ) || !SelectedValue.Equals( newValue ) ) + { + _ignoreSelectedValueChanged = true; SelectedValue = newValue; - - _surpressSelectedValueChanged = false; + _ignoreSelectedValueChanged = false; + } } - private void UpdateSelectedItemsFromSelectedValue() + /// + /// Updates the SelectedItem property based on what is present in the SelectedItems property. + /// + private void UpdateSelectedItem() { - _surpressSelectionChanged = true; - - //first we have to unselect everything - ClearSelectedItems(); + if( !SelectedItems.Contains( SelectedItem ) ) + { + _ignoreSelectedItemChanged = true; + SelectedItem = ( SelectedItems.Count > 0 ) ? SelectedItems[ 0 ] : null; + _ignoreSelectedItemChanged = false; + } + } - if( !String.IsNullOrEmpty( SelectedValue ) ) + /// + /// Update the SelectedItems collection based on the values + /// refered to by the SelectedMemberPath property. + /// + private void UpdateFromSelectedMemberPathValues() + { + _ignoreSelectedItemsCollectionChanged++; + foreach( var item in ItemsCollection ) { - string[] values = SelectedValue.Split( new string[] { Delimiter }, StringSplitOptions.RemoveEmptyEntries ); - foreach( string value in values ) + bool? isSelected = this.GetSelectedMemberPathValue( item ); + if( isSelected != null ) { - var item = ResolveItemByValue( value ); - - if( item != null ) + if( isSelected.Value ) { - SelectedItems.Add( item ); - - //now try to select it in the list - var selectorItem = ItemContainerGenerator.ContainerFromItem( item ) as SelectorItem; - if( selectorItem != null ) + if( !SelectedItems.Contains( item ) ) + { + SelectedItems.Add( item ); + } + } + else + { + if( SelectedItems.Contains( item ) ) { - if( !selectorItem.IsSelected ) - selectorItem.IsSelected = true; + SelectedItems.Remove( item ); } } } } - - _surpressSelectionChanged = false; + _ignoreSelectedItemsCollectionChanged--; + this.UpdateFromSelectedItems(); } - private void ClearSelectedItems() + /// + /// Updates the following based on the content of SelectedItems: + /// - All SelectorItems "IsSelected" properties + /// - Values refered to by SelectedMemberPath + /// - SelectedItem property + /// - SelectedValue property + /// Refered to by the SelectedMemberPath property. + /// + private void UpdateFromSelectedItems() { - if( SelectedItems != null ) - SelectedItems.Clear(); - else - SelectedItems = new ObservableCollection(); + foreach( object o in ItemsCollection ) + { + bool isSelected = SelectedItems.Contains( o ); - UnselectAllInternal(); + _ignoreSelectedMemberPathValuesChanged++; + this.SetSelectedMemberPathValue(o, isSelected); + _ignoreSelectedMemberPathValuesChanged--; + + var selectorItem = ItemContainerGenerator.ContainerFromItem( o ) as SelectorItem; + if( selectorItem != null ) + { + selectorItem.IsSelected = isSelected; + } + } + + UpdateSelectedItem(); + UpdateSelectedValue(); } - private void UnselectAllInternal() + /// + /// Removes all items from SelectedItems that are no longer in ItemsSource. + /// + private void RemoveUnavailableSelectedItems() { - _ignoreSetSelectedValue = true; + _ignoreSelectedItemsCollectionChanged++; + HashSet hash = new HashSet( ItemsCollection.Cast() ); - if( ItemsSource != null ) + for( int i = 0; i < SelectedItems.Count; i++ ) { - foreach( object item in ItemsSource ) + if( !hash.Contains( SelectedItems[ i ] ) ) { - var selectorItem = ItemContainerGenerator.ContainerFromItem( item ) as SelectorItem; - if( selectorItem != null ) - { - if( selectorItem.IsSelected ) - selectorItem.IsSelected = false; - } + SelectedItems.RemoveAt( i ); + i--; } } + _ignoreSelectedItemsCollectionChanged--; - _ignoreSetSelectedValue = false; + UpdateSelectedItem(); + UpdateSelectedValue(); } - protected object ResolveItemByValue( string value ) + /// + /// Updates the SelectedItems collection based on the content of + /// the SelectedValue property. + /// + private void UpdateFromSelectedValue() { - if( !String.IsNullOrEmpty( ValueMemberPath ) ) + _ignoreSelectedItemsCollectionChanged++; + // Just update the SelectedItems collection content + // and let the synchronization be made from UpdateFromSelectedItems(); + SelectedItems.Clear(); + + if( !String.IsNullOrEmpty( SelectedValue ) ) { - if( ItemsSource != null ) + List selectedValues = SelectedValue.Split( new string[] { Delimiter }, StringSplitOptions.RemoveEmptyEntries ).ToList(); + ValueEqualityComparer comparer = new ValueEqualityComparer(); + + foreach( object item in ItemsCollection ) { - foreach( object item in ItemsSource ) + object itemValue = this.GetItemValue( item ); + + bool isSelected = ( itemValue != null ) + && selectedValues.Contains( itemValue.ToString(), comparer ); + + if( isSelected ) { - var property = item.GetType().GetProperty( ValueMemberPath ); - if( property != null ) - { - var propertyValue = property.GetValue( item, null ); - if( value.Equals( propertyValue.ToString(), StringComparison.InvariantCultureIgnoreCase ) ) - return item; - } + SelectedItems.Add( item ); } } } + _ignoreSelectedItemsCollectionChanged--; - return value; + this.UpdateFromSelectedItems(); } #endregion //Methods + + #region IWeakEventListener Members + + public bool ReceiveWeakEvent( Type managerType, object sender, EventArgs e ) + { + if( managerType == typeof( CollectionChangedEventManager ) ) + { + if( object.ReferenceEquals( _selectedItems, sender ) ) + { + this.OnSelectedItemsCollectionChanged( sender, ( NotifyCollectionChangedEventArgs )e ); + return true; + } + else if( object.ReferenceEquals( ItemsCollection, sender ) ) + { + this.OnItemsSourceCollectionChanged( sender, ( NotifyCollectionChangedEventArgs )e ); + } + } + + return false; + } + + #endregion + + #region ValueEqualityComparer private class + + private class ValueEqualityComparer : IEqualityComparer + { + public bool Equals( string x, string y ) + { + return string.Equals( x, y, StringComparison.InvariantCultureIgnoreCase ); + } + + public int GetHashCode( string obj ) + { + return 1; + } + } + + #endregion } - public delegate void SelectedItemChangedEventHandler( object sender, SelectedItemChangedEventArgs e ); - public class SelectedItemChangedEventArgs : RoutedEventArgs + + public delegate void ItemSelectionChangedEventHandler( object sender, ItemSelectionChangedEventArgs e ); + public class ItemSelectionChangedEventArgs : RoutedEventArgs { public bool IsSelected { @@ -453,7 +726,7 @@ namespace Xceed.Wpf.Toolkit.Primitives private set; } - public SelectedItemChangedEventArgs( RoutedEvent routedEvent, object source, object item, bool isSelected ) + public ItemSelectionChangedEventArgs( RoutedEvent routedEvent, object source, object item, bool isSelected ) : base( routedEvent, source ) { Item = item; diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/SelectorItem.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/SelectorItem.cs index ab70ae5b..9996902e 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/SelectorItem.cs +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/SelectorItem.cs @@ -64,9 +64,9 @@ namespace Xceed.Wpf.Toolkit.Primitives protected virtual void OnIsSelectedChanged( bool oldValue, bool newValue ) { if( newValue ) - RaiseSelectionChangedEvent( new RoutedEventArgs( Selector.SelectedEvent, this ) ); + this.RaiseEvent( new RoutedEventArgs( Selector.SelectedEvent, this ) ); else - RaiseSelectionChangedEvent( new RoutedEventArgs( Selector.UnSelectedEvent, this ) ); + this.RaiseEvent( new RoutedEventArgs( Selector.UnSelectedEvent, this ) ); } internal Selector ParentSelector @@ -95,13 +95,5 @@ namespace Xceed.Wpf.Toolkit.Primitives #endregion //Event Hanlders - #region Methods - - private void RaiseSelectionChangedEvent( RoutedEventArgs e ) - { - base.RaiseEvent( e ); - } - - #endregion //Methods } } diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/UpDownBase.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/UpDownBase.cs index 86893750..021995d8 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/UpDownBase.cs +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/UpDownBase.cs @@ -22,12 +22,14 @@ using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Input; +using Xceed.Wpf.Toolkit.Core; +using Xceed.Wpf.Toolkit.Core.Input; namespace Xceed.Wpf.Toolkit.Primitives { [TemplatePart( Name = PART_TextBox, Type = typeof( TextBox ) )] [TemplatePart( Name = PART_Spinner, Type = typeof( Spinner ) )] - public abstract class UpDownBase : InputBase + public abstract class UpDownBase : InputBase, IValidateInput { #region Members @@ -45,6 +47,7 @@ namespace Xceed.Wpf.Toolkit.Primitives /// Flags if the Text and Value properties are in the process of being sync'd /// private bool _isSyncingTextAndValueProperties; + private bool _isTextChangedFromUI; #endregion //Members @@ -114,7 +117,7 @@ namespace Xceed.Wpf.Toolkit.Primitives #region Value - public static readonly DependencyProperty ValueProperty = DependencyProperty.Register( "Value", typeof( T ), typeof( UpDownBase ), new FrameworkPropertyMetadata( default( T ), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnValueChanged, null, false, UpdateSourceTrigger.LostFocus ) ); + public static readonly DependencyProperty ValueProperty = DependencyProperty.Register( "Value", typeof( T ), typeof( UpDownBase ), new FrameworkPropertyMetadata( default( T ), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnValueChanged, OnCoerceValue, false, UpdateSourceTrigger.LostFocus ) ); public T Value { get @@ -127,6 +130,16 @@ namespace Xceed.Wpf.Toolkit.Primitives } } + private static object OnCoerceValue( DependencyObject o, object basevalue ) + { + return ( ( UpDownBase )o ).OnCoerceValue( basevalue ); + } + + protected virtual object OnCoerceValue( object newValue ) + { + return newValue; + } + private static void OnValueChanged( DependencyObject o, DependencyPropertyChangedEventArgs e ) { UpDownBase upDownBase = o as UpDownBase; @@ -136,9 +149,7 @@ namespace Xceed.Wpf.Toolkit.Primitives protected virtual void OnValueChanged( T oldValue, T newValue ) { - ValidateValue( newValue ); - - SyncTextAndValueProperties( ValueProperty, string.Empty ); + SyncTextAndValueProperties( false, null ); SetValidSpinDirection(); @@ -174,6 +185,12 @@ namespace Xceed.Wpf.Toolkit.Primitives base.OnApplyTemplate(); TextBox = GetTemplateChild( PART_TextBox ) as TextBox; + if( TextBox != null ) + { + TextBox.Text = Text; + TextBox.LostFocus += new RoutedEventHandler( TextBox_LostFocus ); + TextBox.TextChanged += new TextChangedEventHandler( TextBox_TextChanged ); + } if( Spinner != null ) Spinner.Spin -= OnSpinnerSpin; @@ -213,6 +230,20 @@ namespace Xceed.Wpf.Toolkit.Primitives } } + protected override void OnKeyDown( KeyEventArgs e ) + { + switch( e.Key ) + { + case Key.Enter: + { + // Commit Text on "Enter" to raise Error event + CommitInput(); + e.Handled = true; + break; + } + } + } + protected override void OnMouseWheel( MouseWheelEventArgs e ) { base.OnMouseWheel( e ); @@ -234,7 +265,10 @@ namespace Xceed.Wpf.Toolkit.Primitives protected override void OnTextChanged( string oldValue, string newValue ) { - SyncTextAndValueProperties( InputBase.TextProperty, newValue ); + if( !_isTextChangedFromUI ) + { + SyncTextAndValueProperties( true, Text ); + } } #endregion //Base Class Overrides @@ -251,6 +285,10 @@ namespace Xceed.Wpf.Toolkit.Primitives #region Events + public event InputValidationErrorEventHandler InputValidationError; + + #region ValueChanged Event + //Due to a bug in Visual Studio, you cannot create event handlers for generic T args in XAML, so I have to use object instead. public static readonly RoutedEvent ValueChangedEvent = EventManager.RegisterRoutedEvent( "ValueChanged", RoutingStrategy.Bubble, typeof( RoutedPropertyChangedEventHandler ), typeof( UpDownBase ) ); public event RoutedPropertyChangedEventHandler ValueChanged @@ -265,6 +303,8 @@ namespace Xceed.Wpf.Toolkit.Primitives } } + #endregion + #endregion //Events #region Methods @@ -302,38 +342,65 @@ namespace Xceed.Wpf.Toolkit.Primitives } } - protected void SyncTextAndValueProperties( DependencyProperty p, string text ) + private void TextBox_TextChanged( object sender, TextChangedEventArgs e ) + { + _isTextChangedFromUI = true; + + TextBox textBox = sender as TextBox; + Text = textBox.Text; + + _isTextChangedFromUI = false; + } + + private void TextBox_LostFocus( object sender, RoutedEventArgs e ) + { + CommitInput(); + } + + public void CommitInput() + { + this.SyncTextAndValueProperties( true, Text ); + } + + protected void SyncTextAndValueProperties(bool updateValueFromText, string text ) { - //prevents recursive syncing properties if( _isSyncingTextAndValueProperties ) return; _isSyncingTextAndValueProperties = true; + Exception error = null; - //this only occures when the user typed in the value - if( InputBase.TextProperty == p ) + if( updateValueFromText ) { - Value = ConvertTextToValue( text ); + try + { + Value = ConvertTextToValue( Text ); + } + catch( Exception e ) + { + error = e; + } } Text = ConvertValueToText(); -#if VS2008 - //there is a bug in .NET 3.5 which will not correctly update the textbox text through binding. - if ( TextBox != null ) + if( TextBox != null ) TextBox.Text = Text; -#endif + + if( updateValueFromText ) + { + if( ( error != null ) && ( InputValidationError != null ) ) + { + InputValidationErrorEventArgs args = new InputValidationErrorEventArgs( error.Message ); + InputValidationError( this, args ); + } + } _isSyncingTextAndValueProperties = false; } #region Abstract - /// - /// Coerces the value. - /// - protected abstract T CoerceValue( T value ); - /// /// Converts the formatted text to a value. /// @@ -360,12 +427,6 @@ namespace Xceed.Wpf.Toolkit.Primitives /// protected abstract void SetValidSpinDirection(); - /// - /// Validates the value and keeps it between the Min and Max values. - /// - /// The value. - protected abstract void ValidateValue( T value ); - #endregion //Abstract #endregion //Methods diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/ValueRangeTextBox.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/ValueRangeTextBox.cs new file mode 100644 index 00000000..7fcf8019 --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/ValueRangeTextBox.cs @@ -0,0 +1,1192 @@ +/************************************************************************ + + Extended WPF Toolkit + + Copyright (C) 2010-2012 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + This program can be provided to you by Xceed Software Inc. under a + proprietary commercial license agreement for use in non-Open Source + projects. The commercial version of Extended WPF Toolkit also includes + priority technical support, commercial updates, and many additional + useful WPF controls if you license Xceed Business Suite for WPF. + + Visit http://xceed.com and follow @datagrid on Twitter. + + **********************************************************************/ + +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Controls; +using System.Windows; +using System.Collections; +using System.Reflection; +using System.Windows.Input; +using System.Windows.Documents; +using System.Globalization; +using Microsoft.Win32; +using System.ComponentModel; +using System.Collections.Specialized; +using System.Diagnostics; +using System.Windows.Automation; +using Xceed.Wpf.Toolkit; +using Xceed.Wpf.Toolkit.Core; + +namespace Xceed.Wpf.Toolkit.Primitives +{ + public class ValueRangeTextBox : AutoSelectTextBox + { + static ValueRangeTextBox() + { + ValueRangeTextBox.TextProperty.OverrideMetadata( typeof( ValueRangeTextBox ), + new FrameworkPropertyMetadata( + null, + new CoerceValueCallback( ValueRangeTextBox.TextCoerceValueCallback ) ) ); + + ValueRangeTextBox.AcceptsReturnProperty.OverrideMetadata( typeof( ValueRangeTextBox ), + new FrameworkPropertyMetadata( + false, null, new CoerceValueCallback( ValueRangeTextBox.AcceptsReturnCoerceValueCallback ) ) ); + + ValueRangeTextBox.AcceptsTabProperty.OverrideMetadata( typeof( ValueRangeTextBox ), + new FrameworkPropertyMetadata( + false, null, new CoerceValueCallback( ValueRangeTextBox.AcceptsTabCoerceValueCallback ) ) ); + + AutomationProperties.AutomationIdProperty.OverrideMetadata( typeof( ValueRangeTextBox ), new UIPropertyMetadata( "ValueRangeTextBox" ) ); + } + + public ValueRangeTextBox() + { + } + + #region AcceptsReturn Property + + private static object AcceptsReturnCoerceValueCallback( DependencyObject sender, object value ) + { + bool acceptsReturn = ( bool )value; + + if( acceptsReturn ) + throw new NotSupportedException( "The ValueRangeTextBox does not support the AcceptsReturn property." ); + + return false; + } + + #endregion AcceptsReturn Property + + #region AcceptsTab Property + + private static object AcceptsTabCoerceValueCallback( DependencyObject sender, object value ) + { + bool acceptsTab = ( bool )value; + + if( acceptsTab ) + throw new NotSupportedException( "The ValueRangeTextBox does not support the AcceptsTab property." ); + + return false; + } + + #endregion AcceptsTab Property + + #region BeepOnError Property + + public bool BeepOnError + { + get + { + return ( bool )GetValue( BeepOnErrorProperty ); + } + set + { + SetValue( BeepOnErrorProperty, value ); + } + } + + public static readonly DependencyProperty BeepOnErrorProperty = + DependencyProperty.Register( "BeepOnError", typeof( bool ), typeof( ValueRangeTextBox ), new UIPropertyMetadata( false ) ); + + #endregion BeepOnError Property + + #region FormatProvider Property + + public IFormatProvider FormatProvider + { + get + { + return ( IFormatProvider )GetValue( FormatProviderProperty ); + } + set + { + SetValue( FormatProviderProperty, value ); + } + } + + public static readonly DependencyProperty FormatProviderProperty = + DependencyProperty.Register( "FormatProvider", typeof( IFormatProvider ), typeof( ValueRangeTextBox ), + new UIPropertyMetadata( null, + new PropertyChangedCallback( ValueRangeTextBox.FormatProviderPropertyChangedCallback ) ) ); + + private static void FormatProviderPropertyChangedCallback( DependencyObject sender, DependencyPropertyChangedEventArgs e ) + { + ValueRangeTextBox valueRangeTextBox = ( ValueRangeTextBox )sender; + + if( !valueRangeTextBox.IsInitialized ) + return; + + valueRangeTextBox.OnFormatProviderChanged(); + } + + internal virtual void OnFormatProviderChanged() + { + this.RefreshConversionHelpers(); + this.RefreshCurrentText( false ); + this.RefreshValue(); + } + + #endregion FormatProvider Property + + #region MinValue Property + + public object MinValue + { + get + { + return ( object )GetValue( MinValueProperty ); + } + set + { + SetValue( MinValueProperty, value ); + } + } + + public static readonly DependencyProperty MinValueProperty = + DependencyProperty.Register( "MinValue", typeof( object ), typeof( ValueRangeTextBox ), + new UIPropertyMetadata( + null, + null, + new CoerceValueCallback( ValueRangeTextBox.MinValueCoerceValueCallback ) ) ); + + private static object MinValueCoerceValueCallback( DependencyObject sender, object value ) + { + ValueRangeTextBox valueRangeTextBox = sender as ValueRangeTextBox; + + if( !valueRangeTextBox.IsInitialized ) + return DependencyProperty.UnsetValue; + + if( value == null ) + return value; + + Type type = valueRangeTextBox.ValueDataType; + + if( type == null ) + throw new InvalidOperationException( "An attempt was made to set a minimum value when the ValueDataType property is null." ); + + if( valueRangeTextBox.IsFinalizingInitialization ) + value = ValueRangeTextBox.ConvertValueToDataType( value, valueRangeTextBox.ValueDataType ); + + if( value.GetType() != type ) + throw new ArgumentException( "The value is not of type " + type.Name + ".", "MinValue" ); + + IComparable comparable = value as IComparable; + + if( comparable == null ) + throw new InvalidOperationException( "MinValue does not implement the IComparable interface." ); + + // ValidateValueInRange will throw if it must. + object maxValue = valueRangeTextBox.MaxValue; + + valueRangeTextBox.ValidateValueInRange( value, maxValue, valueRangeTextBox.Value ); + + return value; + } + + #endregion MinValue Property + + #region MaxValue Property + + public object MaxValue + { + get + { + return ( object )GetValue( MaxValueProperty ); + } + set + { + SetValue( MaxValueProperty, value ); + } + } + + public static readonly DependencyProperty MaxValueProperty = + DependencyProperty.Register( "MaxValue", typeof( object ), typeof( ValueRangeTextBox ), + new UIPropertyMetadata( + null, + null, + new CoerceValueCallback( MaxValueCoerceValueCallback ) ) ); + + private static object MaxValueCoerceValueCallback( DependencyObject sender, object value ) + { + ValueRangeTextBox valueRangeTextBox = sender as ValueRangeTextBox; + + if( !valueRangeTextBox.IsInitialized ) + return DependencyProperty.UnsetValue; + + if( value == null ) + return value; + + Type type = valueRangeTextBox.ValueDataType; + + if( type == null ) + throw new InvalidOperationException( "An attempt was made to set a maximum value when the ValueDataType property is null." ); + + if( valueRangeTextBox.IsFinalizingInitialization ) + value = ValueRangeTextBox.ConvertValueToDataType( value, valueRangeTextBox.ValueDataType ); + + if( value.GetType() != type ) + throw new ArgumentException( "The value is not of type " + type.Name + ".", "MinValue" ); + + IComparable comparable = value as IComparable; + + if( comparable == null ) + throw new InvalidOperationException( "MaxValue does not implement the IComparable interface." ); + + object minValue = valueRangeTextBox.MinValue; + + // ValidateValueInRange will throw if it must. + valueRangeTextBox.ValidateValueInRange( minValue, value, valueRangeTextBox.Value ); + + return value; + } + + #endregion MaxValue Property + + #region NullValue Property + + public object NullValue + { + get + { + return ( object )GetValue( NullValueProperty ); + } + set + { + SetValue( NullValueProperty, value ); + } + } + + public static readonly DependencyProperty NullValueProperty = + DependencyProperty.Register( "NullValue", typeof( object ), typeof( ValueRangeTextBox ), + new UIPropertyMetadata( + null, + new PropertyChangedCallback( ValueRangeTextBox.NullValuePropertyChangedCallback ), + new CoerceValueCallback( NullValueCoerceValueCallback ) ) ); + + private static object NullValueCoerceValueCallback( DependencyObject sender, object value ) + { + ValueRangeTextBox valueRangeTextBox = sender as ValueRangeTextBox; + + if( !valueRangeTextBox.IsInitialized ) + return DependencyProperty.UnsetValue; + + if( ( value == null ) || ( value == DBNull.Value ) ) + return value; + + Type type = valueRangeTextBox.ValueDataType; + + if( type == null ) + throw new InvalidOperationException( "An attempt was made to set a null value when the ValueDataType property is null." ); + + if( valueRangeTextBox.IsFinalizingInitialization ) + value = ValueRangeTextBox.ConvertValueToDataType( value, valueRangeTextBox.ValueDataType ); + + if( value.GetType() != type ) + throw new ArgumentException( "The value is not of type " + type.Name + ".", "NullValue" ); + + return value; + } + + private static void NullValuePropertyChangedCallback( DependencyObject sender, DependencyPropertyChangedEventArgs e ) + { + ValueRangeTextBox valueRangeTextBox = sender as ValueRangeTextBox; + + if( e.OldValue == null ) + { + if( valueRangeTextBox.Value == null ) + valueRangeTextBox.RefreshValue(); + } + else + { + if( e.OldValue.Equals( valueRangeTextBox.Value ) ) + valueRangeTextBox.RefreshValue(); + } + } + + #endregion NullValue Property + + #region Value Property + + public object Value + { + get + { + return ( object )GetValue( ValueProperty ); + } + set + { + SetValue( ValueProperty, value ); + } + } + + public static readonly DependencyProperty ValueProperty = + DependencyProperty.Register( "Value", typeof( object ), typeof( ValueRangeTextBox ), + new FrameworkPropertyMetadata( + null, + FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, + new PropertyChangedCallback( ValueRangeTextBox.ValuePropertyChangedCallback ), + new CoerceValueCallback( ValueRangeTextBox.ValueCoerceValueCallback ) ) ); + + private static object ValueCoerceValueCallback( object sender, object value ) + { + ValueRangeTextBox valueRangeTextBox = sender as ValueRangeTextBox; + + if( !valueRangeTextBox.IsInitialized ) + return DependencyProperty.UnsetValue; + + if( valueRangeTextBox.IsFinalizingInitialization ) + value = ValueRangeTextBox.ConvertValueToDataType( value, valueRangeTextBox.ValueDataType ); + + if( !valueRangeTextBox.IsForcingValue ) + valueRangeTextBox.ValidateValue( value ); + + return value; + } + + private static void ValuePropertyChangedCallback( object sender, DependencyPropertyChangedEventArgs e ) + { + ValueRangeTextBox valueRangeTextBox = sender as ValueRangeTextBox; + + if( valueRangeTextBox.IsForcingValue ) + return; + + // The ValueChangedCallback can be raised even though both values are the same since the property + // datatype is Object. + if( object.Equals( e.NewValue, e.OldValue ) ) + return; + + valueRangeTextBox.IsInValueChanged = true; + try + { + valueRangeTextBox.Text = valueRangeTextBox.GetTextFromValue( e.NewValue ); + } + finally + { + valueRangeTextBox.IsInValueChanged = false; + } + } + + #endregion Value Property + + #region ValueDataType Property + + public Type ValueDataType + { + get + { + return ( Type )GetValue( ValueDataTypeProperty ); + } + set + { + SetValue( ValueDataTypeProperty, value ); + } + } + + public static readonly DependencyProperty ValueDataTypeProperty = + DependencyProperty.Register( "ValueDataType", typeof( Type ), typeof( ValueRangeTextBox ), + new UIPropertyMetadata( + null, + new PropertyChangedCallback( ValueRangeTextBox.ValueDataTypePropertyChangedCallback ), + new CoerceValueCallback( ValueRangeTextBox.ValueDataTypeCoerceValueCallback ) ) ); + + private static object ValueDataTypeCoerceValueCallback( DependencyObject sender, object value ) + { + ValueRangeTextBox valueRangeTextBox = sender as ValueRangeTextBox; + + if( !valueRangeTextBox.IsInitialized ) + return DependencyProperty.UnsetValue; + + Type valueDataType = value as Type; + + try + { + valueRangeTextBox.ValidateDataType( valueDataType ); + } + catch( Exception exception ) + { + throw new ArgumentException( "An error occured while trying to change the ValueDataType.", exception ); + } + + return value; + } + + private static void ValueDataTypePropertyChangedCallback( DependencyObject sender, DependencyPropertyChangedEventArgs e ) + { + ValueRangeTextBox valueRangeTextBox = sender as ValueRangeTextBox; + + Type valueDataType = e.NewValue as Type; + + valueRangeTextBox.IsNumericValueDataType = ValueRangeTextBox.IsNumericType( valueDataType ); + + valueRangeTextBox.RefreshConversionHelpers(); + + valueRangeTextBox.ConvertValuesToDataType( valueDataType ); + } + + internal virtual void ValidateDataType( Type type ) + { + // Null will always be valid and will reset the MinValue, MaxValue, NullValue and Value to null. + if( type == null ) + return; + + // We use InvariantCulture instead of the active format provider since the FormatProvider is only + // used when the source type is String. When we are converting from a string, we are + // actually converting a value from XAML. Therefore, if the string will have a period as a + // decimal separator. If we were using the active format provider, we could end up expecting a coma + // as the decimal separator and the ChangeType method would throw. + + object minValue = this.MinValue; + + if( ( minValue != null ) && ( minValue.GetType() != type ) ) + minValue = System.Convert.ChangeType( minValue, type, CultureInfo.InvariantCulture ); + + object maxValue = this.MaxValue; + + if( ( maxValue != null ) && ( maxValue.GetType() != type ) ) + maxValue = System.Convert.ChangeType( maxValue, type, CultureInfo.InvariantCulture ); + + object nullValue = this.NullValue; + + if( ( ( nullValue != null ) && ( nullValue != DBNull.Value ) ) + && ( nullValue.GetType() != type ) ) + { + nullValue = System.Convert.ChangeType( nullValue, type, CultureInfo.InvariantCulture ); + } + + object value = this.Value; + + if( ( ( value != null ) && ( value != DBNull.Value ) ) + && ( value.GetType() != type ) ) + { + value = System.Convert.ChangeType( value, type, CultureInfo.InvariantCulture ); + } + + if( ( minValue != null ) || ( maxValue != null ) + || ( ( nullValue != null ) && ( nullValue != DBNull.Value ) ) ) + { + // Value comparaisons will occur. Therefore, the aspiring data type must implement IComparable. + + Type iComparable = type.GetInterface( "IComparable" ); + + if( iComparable == null ) + throw new InvalidOperationException( "MinValue, MaxValue, and NullValue must implement the IComparable interface." ); + } + } + + private void ConvertValuesToDataType( Type type ) + { + if( type == null ) + { + this.MinValue = null; + this.MaxValue = null; + this.NullValue = null; + + this.Value = null; + + return; + } + + object minValue = this.MinValue; + + if( ( minValue != null ) && ( minValue.GetType() != type ) ) + this.MinValue = ValueRangeTextBox.ConvertValueToDataType( minValue, type ); + + object maxValue = this.MaxValue; + + if( ( maxValue != null ) && ( maxValue.GetType() != type ) ) + this.MaxValue = ValueRangeTextBox.ConvertValueToDataType( maxValue, type ); + + object nullValue = this.NullValue; + + if( ( ( nullValue != null ) && ( nullValue != DBNull.Value ) ) + && ( nullValue.GetType() != type ) ) + { + this.NullValue = ValueRangeTextBox.ConvertValueToDataType( nullValue, type ); + } + + object value = this.Value; + + if( ( ( value != null ) && ( value != DBNull.Value ) ) + && ( value.GetType() != type ) ) + { + this.Value = ValueRangeTextBox.ConvertValueToDataType( value, type ); + } + } + + #endregion ValueDataType Property + + #region Text Property + + private static object TextCoerceValueCallback( object sender, object value ) + { + ValueRangeTextBox valueRangeTextBox = sender as ValueRangeTextBox; + + if( !valueRangeTextBox.IsInitialized ) + return DependencyProperty.UnsetValue; + + if( value == null ) + return string.Empty; + + return value; + } + + protected override void OnTextChanged( TextChangedEventArgs e ) + { + // If in IME Composition, RefreshValue already returns without doing anything. + this.RefreshValue(); + + base.OnTextChanged( e ); + } + + #endregion Text Property + + #region HasValidationError Property + + private static readonly DependencyPropertyKey HasValidationErrorPropertyKey = + DependencyProperty.RegisterReadOnly( "HasValidationError", typeof( bool ), typeof( ValueRangeTextBox ), new UIPropertyMetadata( false ) ); + + public static readonly DependencyProperty HasValidationErrorProperty = ValueRangeTextBox.HasValidationErrorPropertyKey.DependencyProperty; + + public bool HasValidationError + { + get + { + return ( bool )this.GetValue( ValueRangeTextBox.HasValidationErrorProperty ); + } + } + + private void SetHasValidationError( bool value ) + { + this.SetValue( ValueRangeTextBox.HasValidationErrorPropertyKey, value ); + } + + #endregion HasValidationError Property + + #region HasParsingError Property + + private static readonly DependencyPropertyKey HasParsingErrorPropertyKey = + DependencyProperty.RegisterReadOnly( "HasParsingError", typeof( bool ), typeof( ValueRangeTextBox ), new UIPropertyMetadata( false ) ); + + public static readonly DependencyProperty HasParsingErrorProperty = ValueRangeTextBox.HasParsingErrorPropertyKey.DependencyProperty; + + public bool HasParsingError + { + get + { + return ( bool )this.GetValue( ValueRangeTextBox.HasParsingErrorProperty ); + } + } + + internal void SetHasParsingError( bool value ) + { + this.SetValue( ValueRangeTextBox.HasParsingErrorPropertyKey, value ); + } + + #endregion HasParsingError Property + + #region IsValueOutOfRange Property + + private static readonly DependencyPropertyKey IsValueOutOfRangePropertyKey = + DependencyProperty.RegisterReadOnly( "IsValueOutOfRange", typeof( bool ), typeof( ValueRangeTextBox ), new UIPropertyMetadata( false ) ); + + public static readonly DependencyProperty IsValueOutOfRangeProperty = ValueRangeTextBox.IsValueOutOfRangePropertyKey.DependencyProperty; + + public bool IsValueOutOfRange + { + get + { + return ( bool )this.GetValue( ValueRangeTextBox.IsValueOutOfRangeProperty ); + } + } + + private void SetIsValueOutOfRange( bool value ) + { + this.SetValue( ValueRangeTextBox.IsValueOutOfRangePropertyKey, value ); + } + + #endregion IsValueOutOfRange Property + + #region IsInValueChanged property + + internal bool IsInValueChanged + { + get + { + return m_flags[ ( int )ValueRangeTextBoxFlags.IsInValueChanged ]; + } + private set + { + m_flags[ ( int )ValueRangeTextBoxFlags.IsInValueChanged ] = value; + } + } + + #endregion + + #region IsForcingValue property + + internal bool IsForcingValue + { + get + { + return m_flags[ ( int )ValueRangeTextBoxFlags.IsForcingValue ]; + } + private set + { + m_flags[ ( int )ValueRangeTextBoxFlags.IsForcingValue ] = value; + } + } + + #endregion + + #region IsForcingText property + + internal bool IsForcingText + { + get + { + return m_flags[ ( int )ValueRangeTextBoxFlags.IsForcingText ]; + } + private set + { + m_flags[ ( int )ValueRangeTextBoxFlags.IsForcingText ] = value; + } + } + + #endregion + + #region IsNumericValueDataType property + + internal bool IsNumericValueDataType + { + get + { + return m_flags[ ( int )ValueRangeTextBoxFlags.IsNumericValueDataType ]; + } + private set + { + m_flags[ ( int )ValueRangeTextBoxFlags.IsNumericValueDataType ] = value; + } + } + + #endregion + + #region IsTextReadyToBeParsed property + + internal virtual bool IsTextReadyToBeParsed + { + get + { + return true; + } + } + + #endregion + + #region IsInIMEComposition property + + internal bool IsInIMEComposition + { + get + { + return m_imePreCompositionCachedTextInfo != null; + } + } + + #endregion + + #region IsFinalizingInitialization Property + + private bool IsFinalizingInitialization + { + get + { + return m_flags[ ( int )ValueRangeTextBoxFlags.IsFinalizingInitialization ]; + } + set + { + m_flags[ ( int )ValueRangeTextBoxFlags.IsFinalizingInitialization ] = value; + } + } + + #endregion + + #region TEXT FROM VALUE + + public event EventHandler QueryTextFromValue; + + internal string GetTextFromValue( object value ) + { + string text = this.QueryTextFromValueCore( value ); + + QueryTextFromValueEventArgs e = new QueryTextFromValueEventArgs( value, text ); + + this.OnQueryTextFromValue( e ); + + return e.Text; + } + + protected virtual string QueryTextFromValueCore( object value ) + { + if( ( value == null ) || ( value == DBNull.Value ) ) + return string.Empty; + + IFormatProvider formatProvider = this.GetActiveFormatProvider(); + + CultureInfo cultureInfo = formatProvider as CultureInfo; + + if( cultureInfo != null ) + { + TypeConverter converter = TypeDescriptor.GetConverter( value.GetType() ); + + if( converter.CanConvertTo( typeof( string ) ) ) + return ( string )converter.ConvertTo( null, cultureInfo, value, typeof( string ) ); + } + + try + { + string result = System.Convert.ToString( value, formatProvider ); + + return result; + } + catch + { + } + + return value.ToString(); + } + + private void OnQueryTextFromValue( QueryTextFromValueEventArgs e ) + { + if( this.QueryTextFromValue != null ) + this.QueryTextFromValue( this, e ); + } + + #endregion TEXT FROM VALUE + + #region VALUE FROM TEXT + + public event EventHandler QueryValueFromText; + + internal object GetValueFromText( string text, out bool hasParsingError ) + { + object value = null; + bool success = this.QueryValueFromTextCore( text, out value ); + + QueryValueFromTextEventArgs e = new QueryValueFromTextEventArgs( text, value ); + e.HasParsingError = !success; + + this.OnQueryValueFromText( e ); + + hasParsingError = e.HasParsingError; + + return e.Value; + } + + protected virtual bool QueryValueFromTextCore( string text, out object value ) + { + value = null; + + Type validatingType = this.ValueDataType; + + text = text.Trim(); + + if( validatingType == null ) + return true; + + if( !validatingType.IsValueType && ( validatingType != typeof( string ) ) ) + return false; + + try + { + value = System.Convert.ChangeType( text, validatingType, this.GetActiveFormatProvider() ); + } + catch + { + return false; + } + + return true; + } + + private void OnQueryValueFromText( QueryValueFromTextEventArgs e ) + { + if( this.QueryValueFromText != null ) + this.QueryValueFromText( this, e ); + } + + #endregion VALUE FROM TEXT + + protected override void OnPreviewKeyDown( KeyEventArgs e ) + { + if( ( e.ImeProcessedKey != Key.None ) && ( !this.IsInIMEComposition ) ) + { + // Start of an IME Composition. Cache all the critical infos. + this.StartIMEComposition(); + } + + base.OnPreviewKeyDown( e ); + } + + protected override void OnGotFocus( RoutedEventArgs e ) + { + base.OnGotFocus( e ); + + this.RefreshCurrentText( true ); + } + + protected override void OnLostFocus( RoutedEventArgs e ) + { + base.OnLostFocus( e ); + + this.RefreshCurrentText( true ); + } + + protected override void OnTextInput( TextCompositionEventArgs e ) + { + if( this.IsInIMEComposition ) + this.EndIMEComposition(); + + base.OnTextInput( e ); + } + + [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly" )] + protected virtual void ValidateValue( object value ) + { + if( value == null ) + return; + + Type validatingType = this.ValueDataType; + + if( validatingType == null ) + throw new InvalidOperationException( "An attempt was made to set a value when the ValueDataType property is null." ); + + if( ( value != DBNull.Value ) && ( value.GetType() != validatingType ) ) + throw new ArgumentException( "The value is not of type " + validatingType.Name + ".", "Value" ); + + this.ValidateValueInRange( this.MinValue, this.MaxValue, value ); + } + + internal static bool IsNumericType( Type type ) + { + if( type == null ) + return false; + + if( type.IsValueType ) + { + if( ( type == typeof( int ) ) || ( type == typeof( double ) ) || ( type == typeof( decimal ) ) + || ( type == typeof( float ) ) || ( type == typeof( short ) ) || ( type == typeof( long ) ) + || ( type == typeof( ushort ) ) || ( type == typeof( uint ) ) || ( type == typeof( ulong ) ) + || ( type == typeof( byte ) ) + ) + { + return true; + } + } + + return false; + } + + internal void StartIMEComposition() + { + Debug.Assert( m_imePreCompositionCachedTextInfo == null, "EndIMEComposition should have been called before another IME Composition starts." ); + + m_imePreCompositionCachedTextInfo = new CachedTextInfo( this ); + } + + internal void EndIMEComposition() + { + CachedTextInfo cachedTextInfo = m_imePreCompositionCachedTextInfo.Clone() as CachedTextInfo; + m_imePreCompositionCachedTextInfo = null; + + this.OnIMECompositionEnded( cachedTextInfo ); + } + + internal virtual void OnIMECompositionEnded( CachedTextInfo cachedTextInfo ) + { + } + + internal virtual void RefreshConversionHelpers() + { + } + + internal IFormatProvider GetActiveFormatProvider() + { + IFormatProvider formatProvider = this.FormatProvider; + + if( formatProvider != null ) + return formatProvider; + + return CultureInfo.CurrentCulture; + } + + internal CultureInfo GetCultureInfo() + { + CultureInfo cultureInfo = this.GetActiveFormatProvider() as CultureInfo; + + if( cultureInfo != null ) + return cultureInfo; + + return CultureInfo.CurrentCulture; + } + + internal virtual string GetCurrentText() + { + return this.Text; + } + + internal virtual string GetParsableText() + { + return this.Text; + } + + internal void ForceText( string text, bool preserveCaret ) + { + this.IsForcingText = true; + try + { + int oldCaretIndex = this.CaretIndex; + + this.Text = text; + + if( ( preserveCaret ) && ( this.IsLoaded ) ) + { + try + { + this.SelectionStart = oldCaretIndex; + } + catch( NullReferenceException ) + { + } + } + } + finally + { + this.IsForcingText = false; + } + } + + internal bool IsValueNull( object value ) + { + if( ( value == null ) || ( value == DBNull.Value ) ) + return true; + + Type type = this.ValueDataType; + + if( value.GetType() != type ) + value = System.Convert.ChangeType( value, type ); + + object nullValue = this.NullValue; + + if( nullValue == null ) + return false; + + if( nullValue.GetType() != type ) + nullValue = System.Convert.ChangeType( nullValue, type ); + + return nullValue.Equals( value ); + } + + internal void ForceValue( object value ) + { + this.IsForcingValue = true; + try + { + this.Value = value; + } + finally + { + this.IsForcingValue = false; + } + } + + internal void RefreshCurrentText( bool preserveCurrentCaretPosition ) + { + string displayText = this.GetCurrentText(); + + if( !string.Equals( displayText, this.Text ) ) + this.ForceText( displayText, preserveCurrentCaretPosition ); + } + + internal void RefreshValue() + { + if( ( this.IsForcingValue ) || ( this.ValueDataType == null ) || ( this.IsInIMEComposition ) ) + return; + + object value; + bool hasParsingError; + + if( this.IsTextReadyToBeParsed ) + { + string parsableText = this.GetParsableText(); + + value = this.GetValueFromText( parsableText, out hasParsingError ); + + if( this.IsValueNull( value ) ) + value = this.NullValue; + } + else + { + // We don't consider empty text as a parsing error. + hasParsingError = !this.GetIsEditTextEmpty(); + value = this.NullValue; + } + + this.SetHasParsingError( hasParsingError ); + + bool hasValidationError = hasParsingError; + try + { + this.ValidateValue( value ); + + this.SetIsValueOutOfRange( false ); + } + catch( Exception exception ) + { + hasValidationError = true; + + if( exception is ArgumentOutOfRangeException ) + this.SetIsValueOutOfRange( true ); + + value = this.NullValue; + } + + if( !object.Equals( value, this.Value ) ) + this.ForceValue( value ); + + this.SetHasValidationError( hasValidationError ); + } + + internal virtual bool GetIsEditTextEmpty() + { + return this.Text == string.Empty; + } + + private static object ConvertValueToDataType( object value, Type type ) + { + // We use InvariantCulture instead of the active format provider since the FormatProvider is only + // used when the source type is String. When we are converting from a string, we are + // actually converting a value from XAML. Therefore, if the string will have a period as a + // decimal separator. If we were using the active format provider, we could end up expecting a coma + // as the decimal separator and the ChangeType method would throw. + if( type == null ) + return null; + + if( ( ( value != null ) && ( value != DBNull.Value ) ) + && ( value.GetType() != type ) ) + { + return System.Convert.ChangeType( value, type, CultureInfo.InvariantCulture ); + } + + return value; + } + + private void CanEnterLineBreak( object sender, CanExecuteRoutedEventArgs e ) + { + e.CanExecute = false; + e.Handled = true; + } + + private void CanEnterParagraphBreak( object sender, CanExecuteRoutedEventArgs e ) + { + e.CanExecute = false; + e.Handled = true; + } + + private void ValidateValueInRange( object minValue, object maxValue, object value ) + { + if( this.IsValueNull( value ) ) + return; + + Type type = this.ValueDataType; + + if( value.GetType() != type ) + value = System.Convert.ChangeType( value, type ); + + // Validate the value against the range. + if( minValue != null ) + { + IComparable minValueComparable = ( IComparable )minValue; + + if( ( maxValue != null ) && ( minValueComparable.CompareTo( maxValue ) > 0 ) ) + throw new ArgumentOutOfRangeException( "minValue", "MaxValue must be greater than MinValue." ); + + if( minValueComparable.CompareTo( value ) > 0 ) + throw new ArgumentOutOfRangeException( "minValue", "Value must be greater than MinValue." ); + } + + if( maxValue != null ) + { + IComparable maxValueComparable = ( IComparable )maxValue; + + if( maxValueComparable.CompareTo( value ) < 0 ) + throw new ArgumentOutOfRangeException( "maxValue", "Value must be less than MaxValue." ); + } + } + + #region ISupportInitialize + + protected override void OnInitialized( EventArgs e ) + { + this.IsFinalizingInitialization = true; + try + { + this.CoerceValue( ValueRangeTextBox.ValueDataTypeProperty ); + + this.IsNumericValueDataType = ValueRangeTextBox.IsNumericType( this.ValueDataType ); + this.RefreshConversionHelpers(); + + this.CoerceValue( ValueRangeTextBox.MinValueProperty ); + this.CoerceValue( ValueRangeTextBox.MaxValueProperty ); + + this.CoerceValue( ValueRangeTextBox.ValueProperty ); + + this.CoerceValue( ValueRangeTextBox.NullValueProperty ); + + this.CoerceValue( ValueRangeTextBox.TextProperty ); + } + catch( Exception exception ) + { + throw new InvalidOperationException( "Initialization of the ValueRangeTextBox failed.", exception ); + } + finally + { + this.IsFinalizingInitialization = false; + } + + base.OnInitialized( e ); + } + + #endregion ISupportInitialize + + private BitVector32 m_flags; + private CachedTextInfo m_imePreCompositionCachedTextInfo; + + [Flags] + private enum ValueRangeTextBoxFlags + { + IsFinalizingInitialization = 1, + IsForcingText = 2, + IsForcingValue = 4, + IsInValueChanged = 8, + IsNumericValueDataType = 16 + } + } +} diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/QueryTextFromValueEventArgs.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/QueryTextFromValueEventArgs.cs new file mode 100644 index 00000000..c2c15882 --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/QueryTextFromValueEventArgs.cs @@ -0,0 +1,57 @@ +/************************************************************************ + + Extended WPF Toolkit + + Copyright (C) 2010-2012 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + This program can be provided to you by Xceed Software Inc. under a + proprietary commercial license agreement for use in non-Open Source + projects. The commercial version of Extended WPF Toolkit also includes + priority technical support, commercial updates, and many additional + useful WPF controls if you license Xceed Business Suite for WPF. + + Visit http://xceed.com and follow @datagrid on Twitter. + + **********************************************************************/ + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Xceed.Wpf.Toolkit.Core +{ + public class QueryTextFromValueEventArgs : EventArgs + { + public QueryTextFromValueEventArgs( object value, string text ) + { + m_value = value; + m_text = text; + } + + #region Value Property + + private object m_value; + + public object Value + { + get { return m_value; } + } + + #endregion Value Property + + #region Text Property + + private string m_text; + + public string Text + { + get { return m_text; } + set { m_text = value; } + } + + #endregion Text Property + } +} diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/QueryValueFromTextEventArgs.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/QueryValueFromTextEventArgs.cs new file mode 100644 index 00000000..53ae9960 --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/QueryValueFromTextEventArgs.cs @@ -0,0 +1,70 @@ +/************************************************************************ + + Extended WPF Toolkit + + Copyright (C) 2010-2012 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + This program can be provided to you by Xceed Software Inc. under a + proprietary commercial license agreement for use in non-Open Source + projects. The commercial version of Extended WPF Toolkit also includes + priority technical support, commercial updates, and many additional + useful WPF controls if you license Xceed Business Suite for WPF. + + Visit http://xceed.com and follow @datagrid on Twitter. + + **********************************************************************/ + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Xceed.Wpf.Toolkit.Core +{ + public class QueryValueFromTextEventArgs : EventArgs + { + public QueryValueFromTextEventArgs( string text, object value ) + { + m_text = text; + m_value = value; + } + + #region Text Property + + private string m_text; + + public string Text + { + get { return m_text; } + } + + #endregion Text Property + + #region Value Property + + private object m_value; + + public object Value + { + get { return m_value; } + set { m_value = value; } + } + + #endregion Value Property + + #region HasParsingError Property + + private bool m_hasParsingError; + + public bool HasParsingError + { + get { return m_hasParsingError; } + set { m_hasParsingError = value; } + } + + #endregion HasParsingError Property + + } +} diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Utilities/ColorUtilities.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Utilities/ColorUtilities.cs index db088862..c1b0549b 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Utilities/ColorUtilities.cs +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Utilities/ColorUtilities.cs @@ -184,7 +184,7 @@ namespace Xceed.Wpf.Toolkit.Core.Utilities } - return Color.FromArgb( 255, ( byte )( r * 255 ), ( byte )( g * 255 ), ( byte )( b * 255 ) ); + return Color.FromArgb( 255, ( byte )( Math.Round(r * 255) ), ( byte )( Math.Round(g * 255) ), ( byte )( Math.Round(b * 255) ) ); } /// diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Utilities/NotifyPropertyChangedHelper.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Utilities/NotifyPropertyChangedHelper.cs new file mode 100644 index 00000000..58a27f75 --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Utilities/NotifyPropertyChangedHelper.cs @@ -0,0 +1,163 @@ +/************************************************************************ + + Extended WPF Toolkit + + Copyright (C) 2010-2012 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + This program can be provided to you by Xceed Software Inc. under a + proprietary commercial license agreement for use in non-Open Source + projects. The commercial version of Extended WPF Toolkit also includes + priority technical support, commercial updates, and many additional + useful WPF controls if you license Xceed Business Suite for WPF. + + Visit http://xceed.com and follow @datagrid on Twitter. + + **********************************************************************/ + +using System; +using System.ComponentModel; +using System.Diagnostics; +using System.Linq.Expressions; + +namespace Xceed.Wpf.Toolkit.Core.Utilities +{ + [DebuggerStepThrough] + internal sealed class NotifyPropertyChangedHelper + { + #region Constructor + + internal NotifyPropertyChangedHelper( + INotifyPropertyChanged owner, + Action notifyPropertyChangedDelegate ) + { + if( owner == null ) + throw new ArgumentNullException( "owner" ); + + if( notifyPropertyChangedDelegate == null ) + throw new ArgumentNullException( "notifyPropertyChangedDelegate" ); + + m_owner = owner; + m_delegate = notifyPropertyChangedDelegate; + } + + #endregion + + internal static bool PropertyChanged( string propertyName, PropertyChangedEventArgs e, bool targetPropertyOnly ) + { + string target = e.PropertyName; + if( target == propertyName ) + return true; + + return ( !targetPropertyOnly ) + && ( string.IsNullOrEmpty( target ) ); + } + + internal static bool PropertyChanged( + Expression> expression, + PropertyChangedEventArgs e, + bool targetPropertyOnly ) + { + var body = expression.Body as MemberExpression; + if( body == null ) + throw new ArgumentException( "The expression must target a property or field.", "expression" ); + + return NotifyPropertyChangedHelper.PropertyChanged( body, typeof( TOwner ), e, targetPropertyOnly ); + } + + internal static bool PropertyChanged( + Expression> expression, + PropertyChangedEventArgs e, + bool targetPropertyOnly ) + { + var body = expression.Body as MemberExpression; + if( body == null ) + throw new ArgumentException( "The expression must target a property or field.", "expression" ); + + return NotifyPropertyChangedHelper.PropertyChanged( body, typeof( TOwner ), e, targetPropertyOnly ); + } + + internal void RaisePropertyChanged( string propertyName ) + { + ReflectionHelper.ValidatePropertyName( m_owner, propertyName ); + + this.InvokeDelegate( propertyName ); + } + + internal void RaisePropertyChanged( Expression> expression ) + { + if( expression == null ) + throw new ArgumentNullException( "expression" ); + + var body = expression.Body as MemberExpression; + if( body == null ) + throw new ArgumentException( "The expression must target a property or field.", "expression" ); + + var propertyName = NotifyPropertyChangedHelper.GetPropertyName( body, m_owner.GetType() ); + + this.InvokeDelegate( propertyName ); + } + + internal void HandleReferenceChanged( Expression> expression, ref TMember localReference, TMember newValue ) where TMember : class + { + if( localReference != newValue ) + { + this.ExecutePropertyChanged( expression, ref localReference, newValue ); + } + } + + internal void HandleEqualityChanged( Expression> expression, ref TMember localReference, TMember newValue ) + { + if( !object.Equals( localReference, newValue ) ) + { + this.ExecutePropertyChanged( expression, ref localReference, newValue ); + } + } + + private void ExecutePropertyChanged( Expression> expression, ref TMember localReference, TMember newValue ) + { + TMember oldValue = localReference; + localReference = newValue; + this.RaisePropertyChanged( expression ); + } + + internal static string GetPropertyName( Expression> expression, Type ownerType ) + { + var body = expression.Body as MemberExpression; + if( body == null ) + throw new ArgumentException( "The expression must target a property or field.", "expression" ); + + return NotifyPropertyChangedHelper.GetPropertyName( body, ownerType ); + } + + private static bool PropertyChanged( MemberExpression expression, Type ownerType, PropertyChangedEventArgs e, bool targetPropertyOnly ) + { + var propertyName = NotifyPropertyChangedHelper.GetPropertyName( expression, ownerType ); + + return NotifyPropertyChangedHelper.PropertyChanged( propertyName, e, targetPropertyOnly ); + } + + private static string GetPropertyName( MemberExpression expression, Type ownerType ) + { + var targetType = expression.Expression.Type; + if( !targetType.IsAssignableFrom( ownerType ) ) + throw new ArgumentException( "The expression must target a property or field on the appropriate owner.", "expression" ); + + return ReflectionHelper.GetPropertyOrFieldName( expression ); + } + + private void InvokeDelegate( string propertyName ) + { + m_delegate.Invoke( propertyName ); + } + + #region Private Fields + + private readonly INotifyPropertyChanged m_owner; + private readonly Action m_delegate; + + #endregion + } +} diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Utilities/ReflectionHelper.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Utilities/ReflectionHelper.cs new file mode 100644 index 00000000..4960c8db --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Utilities/ReflectionHelper.cs @@ -0,0 +1,136 @@ +/************************************************************************ + + Extended WPF Toolkit + + Copyright (C) 2010-2012 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + This program can be provided to you by Xceed Software Inc. under a + proprietary commercial license agreement for use in non-Open Source + projects. The commercial version of Extended WPF Toolkit also includes + priority technical support, commercial updates, and many additional + useful WPF controls if you license Xceed Business Suite for WPF. + + Visit http://xceed.com and follow @datagrid on Twitter. + + **********************************************************************/ + +using System; +using System.ComponentModel; +using System.Diagnostics; +using System.Linq.Expressions; +using System.Reflection; + +namespace Xceed.Wpf.Toolkit.Core.Utilities +{ + internal static class ReflectionHelper + { + /// + /// Check the existence of the specified public instance (i.e. non static) property against + /// the type of the specified source object. If the property is not defined by the type, + /// a debug assertion will fail. Typically used to validate the parameter of a + /// RaisePropertyChanged method. + /// + /// The object for which the type will be checked. + /// The name of the property. + [System.Diagnostics.Conditional( "DEBUG" )] + internal static void ValidatePublicPropertyName( object sourceObject, string propertyName ) + { + if( sourceObject == null ) + throw new ArgumentNullException( "sourceObject" ); + + if( propertyName == null ) + throw new ArgumentNullException( "propertyName" ); + + System.Diagnostics.Debug.Assert( sourceObject.GetType().GetProperty( propertyName, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.FlattenHierarchy | System.Reflection.BindingFlags.Public ) != null, + string.Format( "Public property {0} not found on object of type {1}.", propertyName, sourceObject.GetType().FullName ) ); + } + + /// + /// Check the existence of the specified instance (i.e. non static) property against + /// the type of the specified source object. If the property is not defined by the type, + /// a debug assertion will fail. Typically used to validate the parameter of a + /// RaisePropertyChanged method. + /// + /// The object for which the type will be checked. + /// The name of the property. + [System.Diagnostics.Conditional( "DEBUG" )] + internal static void ValidatePropertyName( object sourceObject, string propertyName ) + { + if( sourceObject == null ) + throw new ArgumentNullException( "sourceObject" ); + + if( propertyName == null ) + throw new ArgumentNullException( "propertyName" ); + + System.Diagnostics.Debug.Assert( sourceObject.GetType().GetProperty( propertyName, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.FlattenHierarchy | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic ) != null, + string.Format( "Public property {0} not found on object of type {1}.", propertyName, sourceObject.GetType().FullName ) ); + } + + internal static bool TryGetEnumDescriptionAttributeValue( Enum enumeration, out string description ) + { + try + { + FieldInfo fieldInfo = enumeration.GetType().GetField( enumeration.ToString() ); + DescriptionAttribute[] attributes = fieldInfo.GetCustomAttributes( typeof( DescriptionAttribute ), true ) as DescriptionAttribute[]; + if( ( attributes != null ) && ( attributes.Length > 0 ) ) + { + description = attributes[ 0 ].Description; + return true; + } + } + catch + { + } + + description = String.Empty; + return false; + } + + [DebuggerStepThrough] + internal static string GetPropertyOrFieldName( MemberExpression expression ) + { + string propertyOrFieldName; + if( !ReflectionHelper.TryGetPropertyOrFieldName( expression, out propertyOrFieldName ) ) + throw new InvalidOperationException( "Unable to retrieve the property or field name." ); + + return propertyOrFieldName; + } + + [DebuggerStepThrough] + internal static string GetPropertyOrFieldName( Expression> expression ) + { + string propertyOrFieldName; + if( !ReflectionHelper.TryGetPropertyOrFieldName( expression, out propertyOrFieldName ) ) + throw new InvalidOperationException( "Unable to retrieve the property or field name." ); + + return propertyOrFieldName; + } + + [DebuggerStepThrough] + internal static bool TryGetPropertyOrFieldName( MemberExpression expression, out string propertyOrFieldName ) + { + propertyOrFieldName = null; + + if( expression == null ) + return false; + + propertyOrFieldName = expression.Member.Name; + + return true; + } + + [DebuggerStepThrough] + internal static bool TryGetPropertyOrFieldName( Expression> expression, out string propertyOrFieldName ) + { + propertyOrFieldName = null; + + if( expression == null ) + return false; + + return ReflectionHelper.TryGetPropertyOrFieldName( expression.Body as MemberExpression, out propertyOrFieldName ); + } + } +} diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Utilities/TreeHelper.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Utilities/TreeHelper.cs new file mode 100644 index 00000000..e410dbee --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Utilities/TreeHelper.cs @@ -0,0 +1,238 @@ +/************************************************************************ + + Extended WPF Toolkit + + Copyright (C) 2010-2012 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + This program can be provided to you by Xceed Software Inc. under a + proprietary commercial license agreement for use in non-Open Source + projects. The commercial version of Extended WPF Toolkit also includes + priority technical support, commercial updates, and many additional + useful WPF controls if you license Xceed Business Suite for WPF. + + Visit http://xceed.com and follow @datagrid on Twitter. + + **********************************************************************/ + +using System; +using System.Windows; +using System.Windows.Media; +using System.Windows.Controls.Primitives; + +namespace Xceed.Wpf.Toolkit.Core.Utilities +{ + internal static class TreeHelper + { + /// + /// Tries its best to return the specified element's parent. It will + /// try to find, in this order, the VisualParent, LogicalParent, LogicalTemplatedParent. + /// It only works for Visual, FrameworkElement or FrameworkContentElement. + /// + /// The element to which to return the parent. It will only + /// work if element is a Visual, a FrameworkElement or a FrameworkContentElement. + /// If the logical parent is not found (Parent), we check the TemplatedParent + /// (see FrameworkElement.Parent documentation). But, we never actually witnessed + /// this situation. + public static DependencyObject GetParent( DependencyObject element ) + { + return TreeHelper.GetParent( element, true ); + } + + private static DependencyObject GetParent( DependencyObject element, bool recurseIntoPopup ) + { + if( recurseIntoPopup ) + { + // Case 126732 : To correctly detect parent of a popup we must do that exception case + Popup popup = element as Popup; + + if( ( popup != null ) && ( popup.PlacementTarget != null ) ) + return popup.PlacementTarget; + } + + Visual visual = element as Visual; + DependencyObject parent = ( visual == null ) ? null : VisualTreeHelper.GetParent( visual ); + + if( parent == null ) + { + // No Visual parent. Check in the logical tree. + FrameworkElement fe = element as FrameworkElement; + + if( fe != null ) + { + parent = fe.Parent; + + if( parent == null ) + { + parent = fe.TemplatedParent; + } + } + else + { + FrameworkContentElement fce = element as FrameworkContentElement; + + if( fce != null ) + { + parent = fce.Parent; + + if( parent == null ) + { + parent = fce.TemplatedParent; + } + } + } + } + + return parent; + } + + /// + /// This will search for a parent of the specified type. + /// + /// The type of the element to find + /// The node where the search begins. This element is not checked. + /// Returns the found element. Null if nothing is found. + public static T FindParent( DependencyObject startingObject ) where T : DependencyObject + { + return TreeHelper.FindParent( startingObject, false, null ); + } + + /// + /// This will search for a parent of the specified type. + /// + /// The type of the element to find + /// The node where the search begins. + /// Should the specified startingObject be checked first. + /// Returns the found element. Null if nothing is found. + public static T FindParent( DependencyObject startingObject, bool checkStartingObject ) where T : DependencyObject + { + return TreeHelper.FindParent( startingObject, checkStartingObject, null ); + } + + /// + /// This will search for a parent of the specified type. + /// + /// The type of the element to find + /// The node where the search begins. + /// Should the specified startingObject be checked first. + /// Provide a callback to check additional properties + /// of the found elements. Can be left Null if no additional criteria are needed. + /// Returns the found element. Null if nothing is found. + /// Button button = TreeHelper.FindParent<Button>( this, foundChild => foundChild.Focusable ); + public static T FindParent( DependencyObject startingObject, bool checkStartingObject, Func additionalCheck ) where T : DependencyObject + { + T foundElement; + DependencyObject parent = ( checkStartingObject ? startingObject : TreeHelper.GetParent( startingObject, true ) ); + + while( parent != null ) + { + foundElement = parent as T; + + if( foundElement != null ) + { + if( additionalCheck == null ) + { + return foundElement; + } + else + { + if( additionalCheck( foundElement ) ) + return foundElement; + } + } + + parent = TreeHelper.GetParent( parent, true ); + } + + return null; + } + + /// + /// This will search for a child of the specified type. The search is performed + /// hierarchically, breadth first (as opposed to depth first). + /// + /// The type of the element to find + /// The root of the tree to search for. This element itself is not checked. + /// Returns the found element. Null if nothing is found. + public static T FindChild( DependencyObject parent ) where T : DependencyObject + { + return TreeHelper.FindChild( parent, null ); + } + + /// + /// This will search for a child of the specified type. The search is performed + /// hierarchically, breadth first (as opposed to depth first). + /// + /// The type of the element to find + /// The root of the tree to search for. This element itself is not checked. + /// Provide a callback to check additional properties + /// of the found elements. Can be left Null if no additional criteria are needed. + /// Returns the found element. Null if nothing is found. + /// Button button = TreeHelper.FindChild<Button>( this, foundChild => foundChild.Focusable ); + public static T FindChild( DependencyObject parent, Func additionalCheck ) where T : DependencyObject + { + int childrenCount = VisualTreeHelper.GetChildrenCount( parent ); + T child; + + for( int index = 0; index < childrenCount; index++ ) + { + child = VisualTreeHelper.GetChild( parent, index ) as T; + + if( child != null ) + { + if( additionalCheck == null ) + { + return child; + } + else + { + if( additionalCheck( child ) ) + return child; + } + } + } + + for( int index = 0; index < childrenCount; index++ ) + { + child = TreeHelper.FindChild( VisualTreeHelper.GetChild( parent, index ), additionalCheck ); + + if( child != null ) + return child; + } + + return null; + } + + /// + /// Returns true if the specified element is a child of parent somewhere in the visual + /// tree. This method will work for Visual, FrameworkElement and FrameworkContentElement. + /// + /// The element that is potentially a child of the specified parent. + /// The element that is potentially a parent of the specified element. + public static bool IsDescendantOf( DependencyObject element, DependencyObject parent ) + { + return TreeHelper.IsDescendantOf( element, parent, true ); + } + + /// + /// Returns true if the specified element is a child of parent somewhere in the visual + /// tree. This method will work for Visual, FrameworkElement and FrameworkContentElement. + /// + /// The element that is potentially a child of the specified parent. + /// The element that is potentially a parent of the specified element. + public static bool IsDescendantOf( DependencyObject element, DependencyObject parent, bool recurseIntoPopup ) + { + while( element != null ) + { + if( element == parent ) + return true; + + element = TreeHelper.GetParent( element, recurseIntoPopup ); + } + + return false; + } + } +} diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Utilities/ValueChangeHelper.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Utilities/ValueChangeHelper.cs new file mode 100644 index 00000000..1a94f382 --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Utilities/ValueChangeHelper.cs @@ -0,0 +1,153 @@ +/************************************************************************ + + Extended WPF Toolkit + + Copyright (C) 2010-2012 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + This program can be provided to you by Xceed Software Inc. under a + proprietary commercial license agreement for use in non-Open Source + projects. The commercial version of Extended WPF Toolkit also includes + priority technical support, commercial updates, and many additional + useful WPF controls if you license Xceed Business Suite for WPF. + + Visit http://xceed.com and follow @datagrid on Twitter. + + **********************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows; +using System.Collections; +using System.Windows.Data; + +namespace Xceed.Wpf.Toolkit.Core.Utilities +{ + /// + /// This helper class will raise events when a specific + /// path value on one or many items changes. + /// + internal class ValueChangeHelper : DependencyObject + { + + #region Value Property + /// + /// This private property serves as the target of a binding that monitors the value of the binding + /// of each item in the source. + /// + private static readonly DependencyProperty ValueProperty = DependencyProperty.Register( "Value", typeof( object ), typeof( ValueChangeHelper ), new UIPropertyMetadata( null, OnValueChanged ) ); + private object Value + { + get + { + return ( object )GetValue( ValueProperty ); + } + set + { + SetValue( ValueProperty, value ); + } + } + + private static void OnValueChanged( DependencyObject sender, DependencyPropertyChangedEventArgs args ) + { + ( ( ValueChangeHelper )sender ).RaiseValueChanged(); + } + #endregion + + public event EventHandler ValueChanged; + + #region Constructor + + public ValueChangeHelper(Action changeCallback) + { + if( changeCallback == null ) + throw new ArgumentNullException( "changeCallback" ); + + this.ValueChanged += ( s, args ) => changeCallback(); + } + + #endregion + + #region Methods + + public void UpdateValueSource( object sourceItem, string path ) + { + BindingBase binding = null; + if( sourceItem != null && path != null ) + { + binding = new Binding( path ) { Source = sourceItem }; + } + + this.UpdateBinding( binding ); + } + + public void UpdateValueSource( IEnumerable sourceItems, string path ) + { + BindingBase binding = null; + if( sourceItems != null && path != null ) + { + MultiBinding multiBinding = new MultiBinding(); + multiBinding.Converter = new BlankMultiValueConverter(); + + foreach( var item in sourceItems ) + { + multiBinding.Bindings.Add( new Binding( path ) { Source = item } ); + } + + binding = multiBinding; + } + + this.UpdateBinding( binding ); + } + + private void UpdateBinding( BindingBase binding ) + { + if( binding != null ) + { + BindingOperations.SetBinding( this, ValueChangeHelper.ValueProperty, binding ); + } + else + { + this.ClearBinding(); + } + } + + private void ClearBinding() + { + BindingOperations.ClearBinding( this, ValueChangeHelper.ValueProperty ); + } + + private void RaiseValueChanged() + { + if( this.ValueChanged != null ) + { + this.ValueChanged( this, EventArgs.Empty ); + } + } + + #endregion + + #region BlankMultiValueConverter private class + + private class BlankMultiValueConverter : IMultiValueConverter + { + public object Convert( object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture ) + { + // We will not use the result anyway. We just want the change notification to kick in. + // Return a new object to have a different value. + return new object(); + } + + public object[] ConvertBack( object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture ) + { + throw new InvalidOperationException(); + } + } + + #endregion + } +} diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/DateTimePicker/Themes/Generic.xaml b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/DateTimePicker/Themes/Generic.xaml index 92bb3a18..ef7cfd18 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/DateTimePicker/Themes/Generic.xaml +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/DateTimePicker/Themes/Generic.xaml @@ -36,7 +36,14 @@ - + + + + + + + + @@ -88,6 +95,7 @@ + + diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Obselete/MaskedTextBox/Implementation/MaskedTextBox.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Obselete/MaskedTextBox/Implementation/MaskedTextBox.cs new file mode 100644 index 00000000..ee15e423 --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Obselete/MaskedTextBox/Implementation/MaskedTextBox.cs @@ -0,0 +1,726 @@ +/************************************************************************ + + Extended WPF Toolkit + + Copyright (C) 2010-2012 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + This program can be provided to you by Xceed Software Inc. under a + proprietary commercial license agreement for use in non-Open Source + projects. The commercial version of Extended WPF Toolkit also includes + priority technical support, commercial updates, and many additional + useful WPF controls if you license Xceed Business Suite for WPF. + + Visit http://xceed.com and follow @datagrid on Twitter. + + **********************************************************************/ + +using System; +using System.ComponentModel; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; + +namespace Xceed.Wpf.Toolkit.Obselete +{ + [Obsolete("Legacy implementation of MaskedTextBox. Use Xceed.Wpf.Toolkit.MaskedTextBox instead", false)] + public class MaskedTextBox : TextBox + { + #region Members + + /// + /// Flags if the Text and Value properties are in the process of being sync'd + /// + private bool _isSyncingTextAndValueProperties; + private bool _isInitialized; + private bool _convertExceptionOccurred = false; + + #endregion //Members + + #region Properties + + protected MaskedTextProvider MaskProvider + { + get; + set; + } + + #region IncludePrompt + + public static readonly DependencyProperty IncludePromptProperty = DependencyProperty.Register( "IncludePrompt", typeof( bool ), typeof( MaskedTextBox ), new UIPropertyMetadata( false, OnIncludePromptPropertyChanged ) ); + public bool IncludePrompt + { + get + { + return ( bool )GetValue( IncludePromptProperty ); + } + set + { + SetValue( IncludePromptProperty, value ); + } + } + + private static void OnIncludePromptPropertyChanged( DependencyObject o, DependencyPropertyChangedEventArgs e ) + { + MaskedTextBox maskedTextBox = o as MaskedTextBox; + if( maskedTextBox != null ) + maskedTextBox.OnIncludePromptChanged( ( bool )e.OldValue, ( bool )e.NewValue ); + } + + protected virtual void OnIncludePromptChanged( bool oldValue, bool newValue ) + { + ResolveMaskProvider( Mask ); + } + + #endregion //IncludePrompt + + #region IncludeLiterals + + public static readonly DependencyProperty IncludeLiteralsProperty = DependencyProperty.Register( "IncludeLiterals", typeof( bool ), typeof( MaskedTextBox ), new UIPropertyMetadata( true, OnIncludeLiteralsPropertyChanged ) ); + public bool IncludeLiterals + { + get + { + return ( bool )GetValue( IncludeLiteralsProperty ); + } + set + { + SetValue( IncludeLiteralsProperty, value ); + } + } + + private static void OnIncludeLiteralsPropertyChanged( DependencyObject o, DependencyPropertyChangedEventArgs e ) + { + MaskedTextBox maskedTextBox = o as MaskedTextBox; + if( maskedTextBox != null ) + maskedTextBox.OnIncludeLiteralsChanged( ( bool )e.OldValue, ( bool )e.NewValue ); + } + + protected virtual void OnIncludeLiteralsChanged( bool oldValue, bool newValue ) + { + ResolveMaskProvider( Mask ); + } + + #endregion //IncludeLiterals + + #region Mask + + public static readonly DependencyProperty MaskProperty = DependencyProperty.Register( "Mask", typeof( string ), typeof( MaskedTextBox ), new UIPropertyMetadata( "<>", OnMaskPropertyChanged ) ); + public string Mask + { + get + { + return ( string )GetValue( MaskProperty ); + } + set + { + SetValue( MaskProperty, value ); + } + } + + private static void OnMaskPropertyChanged( DependencyObject o, DependencyPropertyChangedEventArgs e ) + { + MaskedTextBox maskedTextBox = o as MaskedTextBox; + if( maskedTextBox != null ) + maskedTextBox.OnMaskChanged( ( string )e.OldValue, ( string )e.NewValue ); + } + + protected virtual void OnMaskChanged( string oldValue, string newValue ) + { + ResolveMaskProvider( newValue ); + UpdateText( 0 ); + } + + #endregion //Mask + + #region PromptChar + + public static readonly DependencyProperty PromptCharProperty = DependencyProperty.Register( "PromptChar", typeof( char ), typeof( MaskedTextBox ), new UIPropertyMetadata( '_', OnPromptCharChanged ) ); + public char PromptChar + { + get + { + return ( char )GetValue( PromptCharProperty ); + } + set + { + SetValue( PromptCharProperty, value ); + } + } + + private static void OnPromptCharChanged( DependencyObject o, DependencyPropertyChangedEventArgs e ) + { + MaskedTextBox maskedTextBox = o as MaskedTextBox; + if( maskedTextBox != null ) + maskedTextBox.OnPromptCharChanged( ( char )e.OldValue, ( char )e.NewValue ); + } + + protected virtual void OnPromptCharChanged( char oldValue, char newValue ) + { + ResolveMaskProvider( Mask ); + } + + #endregion //PromptChar + + #region SelectAllOnGotFocus + + public static readonly DependencyProperty SelectAllOnGotFocusProperty = DependencyProperty.Register( "SelectAllOnGotFocus", typeof( bool ), typeof( MaskedTextBox ), new PropertyMetadata( false ) ); + public bool SelectAllOnGotFocus + { + get + { + return ( bool )GetValue( SelectAllOnGotFocusProperty ); + } + set + { + SetValue( SelectAllOnGotFocusProperty, value ); + } + } + + #endregion //SelectAllOnGotFocus + + #region Text + + private static void OnTextChanged( DependencyObject o, DependencyPropertyChangedEventArgs e ) + { + MaskedTextBox inputBase = o as MaskedTextBox; + if( inputBase != null ) + inputBase.OnTextChanged( ( string )e.OldValue, ( string )e.NewValue ); + } + + protected virtual void OnTextChanged( string oldValue, string newValue ) + { + if( _isInitialized ) + SyncTextAndValueProperties( MaskedTextBox.TextProperty, newValue ); + } + + #endregion //Text + + #region Value + + public static readonly DependencyProperty ValueProperty = DependencyProperty.Register( "Value", typeof( object ), typeof( MaskedTextBox ), new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnValueChanged ) ); + public object Value + { + get + { + return ( object )GetValue( ValueProperty ); + } + set + { + SetValue( ValueProperty, value ); + } + } + + private static void OnValueChanged( DependencyObject o, DependencyPropertyChangedEventArgs e ) + { + MaskedTextBox maskedTextBox = o as MaskedTextBox; + if( maskedTextBox != null ) + maskedTextBox.OnValueChanged( ( object )e.OldValue, ( object )e.NewValue ); + } + + protected virtual void OnValueChanged( object oldValue, object newValue ) + { + if( _isInitialized ) + SyncTextAndValueProperties( MaskedTextBox.ValueProperty, newValue ); + + RoutedPropertyChangedEventArgs args = new RoutedPropertyChangedEventArgs( oldValue, newValue ); + args.RoutedEvent = MaskedTextBox.ValueChangedEvent; + RaiseEvent( args ); + } + + #endregion //Value + + #region ValueType + + public static readonly DependencyProperty ValueTypeProperty = DependencyProperty.Register( "ValueType", typeof( Type ), typeof( MaskedTextBox ), new UIPropertyMetadata( typeof( String ), OnValueTypeChanged ) ); + public Type ValueType + { + get + { + return ( Type )GetValue( ValueTypeProperty ); + } + set + { + SetValue( ValueTypeProperty, value ); + } + } + + private static void OnValueTypeChanged( DependencyObject o, DependencyPropertyChangedEventArgs e ) + { + MaskedTextBox maskedTextBox = o as MaskedTextBox; + if( maskedTextBox != null ) + maskedTextBox.OnValueTypeChanged( ( Type )e.OldValue, ( Type )e.NewValue ); + } + + protected virtual void OnValueTypeChanged( Type oldValue, Type newValue ) + { + if( _isInitialized ) + SyncTextAndValueProperties( MaskedTextBox.TextProperty, Text ); + } + + #endregion //ValueType + + #endregion //Properties + + #region Constructors + + static MaskedTextBox() + { + TextProperty.OverrideMetadata( typeof( MaskedTextBox ), new FrameworkPropertyMetadata( OnTextChanged ) ); + } + + public MaskedTextBox() + { + CommandBindings.Add( new CommandBinding( ApplicationCommands.Paste, Paste ) ); //handle paste + CommandBindings.Add( new CommandBinding( ApplicationCommands.Cut, null, CanCut ) ); //surpress cut + } + + #endregion //Constructors + + #region Base Class Overrides + + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + ResolveMaskProvider( Mask ); + UpdateText( 0 ); + } + + protected override void OnInitialized( EventArgs e ) + { + base.OnInitialized( e ); + + if( !_isInitialized ) + { + _isInitialized = true; + SyncTextAndValueProperties( ValueProperty, Value ); + } + } + + protected override void OnGotKeyboardFocus( KeyboardFocusChangedEventArgs e ) + { + if( SelectAllOnGotFocus ) + { + SelectAll(); + } + + base.OnGotKeyboardFocus( e ); + } + + protected override void OnPreviewKeyDown( KeyEventArgs e ) + { + if( !e.Handled ) + { + HandlePreviewKeyDown( e ); + } + + base.OnPreviewKeyDown( e ); + } + + protected override void OnPreviewTextInput( TextCompositionEventArgs e ) + { + if( !e.Handled ) + { + HandlePreviewTextInput( e ); + } + + base.OnPreviewTextInput( e ); + } + + #endregion //Base Class Overrides + + #region Events + + public static readonly RoutedEvent ValueChangedEvent = EventManager.RegisterRoutedEvent( "ValueChanged", RoutingStrategy.Bubble, typeof( RoutedPropertyChangedEventHandler ), typeof( MaskedTextBox ) ); + public event RoutedPropertyChangedEventHandler ValueChanged + { + add + { + AddHandler( ValueChangedEvent, value ); + } + remove + { + RemoveHandler( ValueChangedEvent, value ); + } + } + + #endregion //Events + + #region Methods + + #region Private + + private void UpdateText() + { + UpdateText( SelectionStart ); + } + + private void UpdateText( int position ) + { + MaskedTextProvider provider = MaskProvider; + if( provider == null ) + throw new InvalidOperationException(); + + Text = provider.ToDisplayString(); + SelectionLength = 0; + SelectionStart = position; + } + + private int GetNextCharacterPosition( int startPosition ) + { + int position = MaskProvider.FindEditPositionFrom( startPosition, true ); + return position == -1 ? startPosition : position; + } + + private void ResolveMaskProvider( string mask ) + { + //do not create a mask provider if the Mask is empty, which can occur if the IncludePrompt and IncludeLiterals properties + //are set prior to the Mask. + if( String.IsNullOrEmpty( mask ) ) + return; + + MaskProvider = new MaskedTextProvider( mask ) + { + IncludePrompt = this.IncludePrompt, + IncludeLiterals = this.IncludeLiterals, + PromptChar = this.PromptChar, + ResetOnSpace = false //should make this a property + }; + } + + private object ConvertTextToValue( string text ) + { + object convertedValue = null; + + Type dataType = ValueType; + + string valueToConvert = MaskProvider.ToString().Trim(); + + try + { + if( valueToConvert.GetType() == dataType || dataType.IsInstanceOfType( valueToConvert ) ) + { + convertedValue = valueToConvert; + } +#if !VS2008 + else if( String.IsNullOrWhiteSpace( valueToConvert ) ) + { + convertedValue = Activator.CreateInstance( dataType ); + } +#else + else if ( String.IsNullOrEmpty( valueToConvert ) ) + { + convertedValue = Activator.CreateInstance( dataType ); + } +#endif + else if( null == convertedValue && valueToConvert is IConvertible ) + { + convertedValue = Convert.ChangeType( valueToConvert, dataType ); + } + } + catch + { + //if an excpetion occurs revert back to original value + _convertExceptionOccurred = true; + return Value; + } + + return convertedValue; + } + + private string ConvertValueToText( object value ) + { + if( value == null ) + value = string.Empty; + + if( _convertExceptionOccurred ) + { + value = Value; + _convertExceptionOccurred = false; + } + + //I have only seen this occur while in Blend, but we need it here so the Blend designer doesn't crash. + if( MaskProvider == null ) + return value.ToString(); + + MaskProvider.Set( value.ToString() ); + return MaskProvider.ToDisplayString(); + } + + private void SyncTextAndValueProperties( DependencyProperty p, object newValue ) + { + //prevents recursive syncing properties + if( _isSyncingTextAndValueProperties ) + return; + + _isSyncingTextAndValueProperties = true; + + //this only occures when the user typed in the value + if( MaskedTextBox.TextProperty == p ) + { + if( newValue != null ) + SetValue( MaskedTextBox.ValueProperty, ConvertTextToValue( newValue.ToString() ) ); + } + + SetValue( MaskedTextBox.TextProperty, ConvertValueToText( newValue ) ); + + _isSyncingTextAndValueProperties = false; + } + + private void HandlePreviewTextInput( TextCompositionEventArgs e ) + { + if( !IsReadOnly ) + { + this.InsertText( e.Text ); + } + + e.Handled = true; + } + + private void HandlePreviewKeyDown( KeyEventArgs e ) + { + if( e.Key == Key.Delete ) + { + e.Handled = IsReadOnly + || HandleKeyDownDelete(); + } + else if( e.Key == Key.Back ) + { + e.Handled = IsReadOnly + || HandleKeyDownBack(); + } + else if( e.Key == Key.Space ) + { + if( !IsReadOnly ) + { + InsertText( " " ); + } + + e.Handled = true; + } + else if( e.Key == Key.Return || e.Key == Key.Enter ) + { + if( !IsReadOnly && AcceptsReturn ) + { + this.InsertText( "\r" ); + } + + // We don't want the OnPreviewTextInput to be triggered for the Return/Enter key + // when it is not accepted. + e.Handled = true; + } + else if( e.Key == Key.Escape ) + { + // We don't want the OnPreviewTextInput to be triggered at all for the Escape key. + e.Handled = true; + } + else if( e.Key == Key.Tab ) + { + if( AcceptsTab ) + { + if( !IsReadOnly ) + { + this.InsertText( "\t" ); + } + + e.Handled = true; + } + } + } + + private bool HandleKeyDownDelete() + { + ModifierKeys modifiers = Keyboard.Modifiers; + bool handled = true; + + if( modifiers == ModifierKeys.None ) + { + if( !RemoveSelectedText() ) + { + int position = SelectionStart; + + if( position < Text.Length ) + { + RemoveText( position, 1 ); + UpdateText( position ); + } + } + else + { + UpdateText(); + } + } + else if( modifiers == ModifierKeys.Control ) + { + if( !RemoveSelectedText() ) + { + int position = SelectionStart; + + RemoveTextToEnd( position ); + UpdateText( position ); + } + else + { + UpdateText(); + } + } + else if( modifiers == ModifierKeys.Shift ) + { + if( RemoveSelectedText() ) + { + UpdateText(); + } + else + { + handled = false; + } + } + else + { + handled = false; + } + + return handled; + } + + private bool HandleKeyDownBack() + { + ModifierKeys modifiers = Keyboard.Modifiers; + bool handled = true; + + if( modifiers == ModifierKeys.None || modifiers == ModifierKeys.Shift ) + { + if( !RemoveSelectedText() ) + { + int position = SelectionStart; + + if( position > 0 ) + { + int newPosition = position - 1; + + RemoveText( newPosition, 1 ); + UpdateText( newPosition ); + } + } + else + { + UpdateText(); + } + } + else if( modifiers == ModifierKeys.Control ) + { + if( !RemoveSelectedText() ) + { + RemoveTextFromStart( SelectionStart ); + UpdateText( 0 ); + } + else + { + UpdateText(); + } + } + else + { + handled = false; + } + + return handled; + } + + private void InsertText( string text ) + { + int position = SelectionStart; + MaskedTextProvider provider = MaskProvider; + + bool textRemoved = this.RemoveSelectedText(); + + position = GetNextCharacterPosition( position ); + + if( !textRemoved && Keyboard.IsKeyToggled( Key.Insert ) ) + { + if( provider.Replace( text, position ) ) + { + position += text.Length; + } + } + else + { + if( provider.InsertAt( text, position ) ) + { + position += text.Length; + } + } + + position = GetNextCharacterPosition( position ); + + this.UpdateText( position ); + } + + private void RemoveTextFromStart( int endPosition ) + { + RemoveText( 0, endPosition ); + } + + private void RemoveTextToEnd( int startPosition ) + { + RemoveText( startPosition, Text.Length - startPosition ); + } + + private void RemoveText( int position, int length ) + { + if( length == 0 ) + return; + + MaskProvider.RemoveAt( position, position + length - 1 ); + } + + private bool RemoveSelectedText() + { + int length = SelectionLength; + + if( length == 0 ) + return false; + + int position = SelectionStart; + + return MaskProvider.RemoveAt( position, position + length - 1 ); + } + + #endregion //Private + + #endregion //Methods + + #region Commands + + private void Paste( object sender, RoutedEventArgs e ) + { + if( IsReadOnly ) + return; + + object data = Clipboard.GetData( DataFormats.Text ); + if( data != null ) + { + string text = data.ToString().Trim(); + if( text.Length > 0 ) + { + int position = SelectionStart; + + MaskProvider.Set( text ); + + UpdateText( position ); + } + } + } + + private void CanCut( object sender, CanExecuteRoutedEventArgs e ) + { + e.CanExecute = false; + e.Handled = true; + } + + #endregion //Commands + } +} diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Properties/AssemblyInfo.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Properties/AssemblyInfo.cs index ad13a5f6..f541a0f9 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Properties/AssemblyInfo.cs +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Properties/AssemblyInfo.cs @@ -75,6 +75,8 @@ using System.Windows.Markup; [assembly: XmlnsDefinition("http://schemas.xceed.com/wpf/xaml/toolkit", "Xceed.Wpf.Toolkit")] [assembly: XmlnsDefinition("http://schemas.xceed.com/wpf/xaml/toolkit", "Xceed.Wpf.Toolkit.Core.Converters" )] [assembly: XmlnsDefinition("http://schemas.xceed.com/wpf/xaml/toolkit", "Xceed.Wpf.Toolkit.Core.Input" )] +[assembly: XmlnsDefinition("http://schemas.xceed.com/wpf/xaml/toolkit", "Xceed.Wpf.Toolkit.Core.Utilities")] +[assembly: XmlnsDefinition("http://schemas.xceed.com/wpf/xaml/toolkit", "Xceed.Wpf.Toolkit.Chromes")] [assembly: XmlnsDefinition("http://schemas.xceed.com/wpf/xaml/toolkit", "Xceed.Wpf.Toolkit.Primitives")] [assembly: XmlnsDefinition("http://schemas.xceed.com/wpf/xaml/toolkit", "Xceed.Wpf.Toolkit.PropertyGrid")] [assembly: XmlnsDefinition("http://schemas.xceed.com/wpf/xaml/toolkit", "Xceed.Wpf.Toolkit.PropertyGrid.Attributes")] diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Converters/SelectedObjectConverter.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Converters/SelectedObjectConverter.cs new file mode 100644 index 00000000..7b062a58 --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Converters/SelectedObjectConverter.cs @@ -0,0 +1,92 @@ +/************************************************************************ + + Extended WPF Toolkit + + Copyright (C) 2010-2012 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + This program can be provided to you by Xceed Software Inc. under a + proprietary commercial license agreement for use in non-Open Source + projects. The commercial version of Extended WPF Toolkit also includes + priority technical support, commercial updates, and many additional + useful WPF controls if you license Xceed Business Suite for WPF. + + Visit http://xceed.com and follow @datagrid on Twitter. + + **********************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Data; +using System.Globalization; +using System.ComponentModel; +using System.Windows; +using System.Reflection; + +namespace Xceed.Wpf.Toolkit.PropertyGrid.Converters +{ + public class SelectedObjectConverter : IValueConverter + { + private const string ValidParameterMessage = @"parameter must be one of the following strings: 'Type', 'TypeName'"; + #region IValueConverter Members + + public object Convert( object value, Type targetType, object parameter, CultureInfo culture ) + { + if( parameter == null ) + throw new ArgumentNullException( "parameter" ); + + if( !( parameter is string ) ) + throw new ArgumentException( SelectedObjectConverter.ValidParameterMessage ); + + if( this.CompareParam(parameter, "Type") ) + { + return this.ConvertToType( value, culture ); + } + else if( this.CompareParam( parameter, "TypeName" ) ) + { + return this.ConvertToTypeName( value, culture ); + } + else + { + throw new ArgumentException( SelectedObjectConverter.ValidParameterMessage ); + } + } + + private bool CompareParam(object parameter, string parameterValue ) + { + return string.Compare( ( string )parameter, parameterValue, true ) == 0; + } + + private object ConvertToType( object value, CultureInfo culture ) + { + return ( value != null ) + ? value.GetType() + : null; + } + + private object ConvertToTypeName( object value, CultureInfo culture ) + { + if( value == null ) + return string.Empty; + + Type newType = value.GetType(); + + DisplayNameAttribute displayNameAttribute = newType.GetCustomAttributes( false ).OfType().FirstOrDefault(); + + return (displayNameAttribute == null) + ? newType.Name + : displayNameAttribute.DisplayName; + } + + public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture ) + { + throw new NotImplementedException(); + } + + #endregion + } +} diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Editors/UpDownEditors.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Editors/UpDownEditors.cs new file mode 100644 index 00000000..994ad9d8 --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Editors/UpDownEditors.cs @@ -0,0 +1,52 @@ +/************************************************************************ + + Extended WPF Toolkit + + Copyright (C) 2010-2012 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + This program can be provided to you by Xceed Software Inc. under a + proprietary commercial license agreement for use in non-Open Source + projects. The commercial version of Extended WPF Toolkit also includes + priority technical support, commercial updates, and many additional + useful WPF controls if you license Xceed Business Suite for WPF. + + Visit http://xceed.com and follow @datagrid on Twitter. + + **********************************************************************/ + +using Xceed.Wpf.Toolkit.Primitives; +using System; +namespace Xceed.Wpf.Toolkit.PropertyGrid.Editors +{ + public class UpDownEditor : TypeEditor where TEditor : UpDownBase, new() + { + protected override void SetControlProperties() + { + Editor.BorderThickness = new System.Windows.Thickness( 0 ); + } + protected override void SetValueDependencyProperty() + { + ValueProperty = UpDownBase.ValueProperty; + } + } + + public class ByteUpDownEditor : UpDownEditor { } + + public class DecimalUpDownEditor : UpDownEditor { } + + public class DoubleUpDownEditor : UpDownEditor { } + + public class IntegerUpDownEditor : UpDownEditor { } + + public class LongUpDownEditor : UpDownEditor { } + + public class ShortUpDownEditor : UpDownEditor { } + + public class SingleUpDownEditor : UpDownEditor { } + + public class DateTimeUpDownEditor : UpDownEditor { } + +} diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/IPropertyParent.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/IPropertyParent.cs new file mode 100644 index 00000000..18804b01 --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/IPropertyParent.cs @@ -0,0 +1,36 @@ +/************************************************************************ + + Extended WPF Toolkit + + Copyright (C) 2010-2012 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + This program can be provided to you by Xceed Software Inc. under a + proprietary commercial license agreement for use in non-Open Source + projects. The commercial version of Extended WPF Toolkit also includes + priority technical support, commercial updates, and many additional + useful WPF controls if you license Xceed Business Suite for WPF. + + Visit http://xceed.com and follow @datagrid on Twitter. + + **********************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Xceed.Wpf.Toolkit.PropertyGrid.Attributes; + +namespace Xceed.Wpf.Toolkit.PropertyGrid +{ + internal interface IPropertyParent + { + bool IsReadOnly { get; } + + object ValueInstance { get; } + + EditorDefinitionCollection EditorDefinitions { get; } + } +} diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyGrid.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyGrid.cs index 5c0d65c3..c46bdb3e 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyGrid.cs +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyGrid.cs @@ -30,20 +30,23 @@ using Xceed.Wpf.Toolkit.PropertyGrid.Commands; using System.Collections.Specialized; using System.Windows.Media; using Xceed.Wpf.Toolkit.PropertyGrid.Attributes; +using System.Collections.ObjectModel; namespace Xceed.Wpf.Toolkit.PropertyGrid { [TemplatePart( Name = PART_DragThumb, Type = typeof( Thumb ) )] - public class PropertyGrid : Control, ISupportInitialize + public class PropertyGrid : Control, ISupportInitialize, IPropertyParent { private const string PART_DragThumb = "PART_DragThumb"; #region Members private Thumb _dragThumb; - private List _propertyItemsCache; private bool _hasPendingSelectedObjectChanged; private int _initializationCount; + private PropertyItemCollection _properties; + private PropertyDefinitionCollection _propertyDefinitions; + private EditorDefinitionCollection _editorDefinitions; #endregion //Members @@ -68,7 +71,7 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid #region AutoGenerateProperties - public static readonly DependencyProperty AutoGeneratePropertiesProperty = DependencyProperty.Register( "AutoGenerateProperties", typeof( bool ), typeof( PropertyGrid ), new UIPropertyMetadata( true ) ); + public static readonly DependencyProperty AutoGeneratePropertiesProperty = DependencyProperty.Register( "AutoGenerateProperties", typeof( bool ), typeof( PropertyGrid ), new UIPropertyMetadata( true, OnAutoGeneratePropertiesChanged ) ); public bool AutoGenerateProperties { get @@ -81,8 +84,16 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid } } + private static void OnAutoGeneratePropertiesChanged( DependencyObject o, DependencyPropertyChangedEventArgs e ) + { + ( ( PropertyGrid )o ).UpdateProperties( true ); + } + #endregion //AutoGenerateProperties + + + #region ShowSummary public static readonly DependencyProperty ShowSummaryProperty = DependencyProperty.Register( "ShowSummary", typeof( bool ), typeof( PropertyGrid ), new UIPropertyMetadata( true ) ); @@ -102,26 +113,20 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid #region EditorDefinitions - public static readonly DependencyProperty EditorDefinitionsProperty = DependencyProperty.Register( "EditorDefinitions", typeof( EditorDefinitionCollection ), typeof( PropertyGrid ), new UIPropertyMetadata( null, OnEditorDefinitionsChanged) ); public EditorDefinitionCollection EditorDefinitions { get { - return ( EditorDefinitionCollection )GetValue( EditorDefinitionsProperty ); + return _editorDefinitions; } set { - SetValue( EditorDefinitionsProperty, value ); + EditorDefinitionCollection oldValue = _editorDefinitions; + _editorDefinitions = value; + this.OnEditorDefinitionsChanged( oldValue, value ); } } - private static void OnEditorDefinitionsChanged( DependencyObject o, DependencyPropertyChangedEventArgs e ) - { - PropertyGrid propertyGrid = o as PropertyGrid; - if( propertyGrid != null ) - propertyGrid.OnEditorDefinitionsChanged( ( EditorDefinitionCollection )e.OldValue, ( EditorDefinitionCollection )e.NewValue ); - } - protected virtual void OnEditorDefinitionsChanged( EditorDefinitionCollection oldValue, EditorDefinitionCollection newValue ) { if( oldValue != null ) @@ -130,7 +135,12 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid if( newValue != null ) newValue.CollectionChanged += new NotifyCollectionChangedEventHandler( OnEditorDefinitionsCollectionChanged ); - RefreshPropertyGrid(); + UpdateProperties( true ); + } + + private void OnEditorDefinitionsCollectionChanged( object sender, NotifyCollectionChangedEventArgs e ) + { + UpdateProperties( true ); } #endregion //EditorDefinitions @@ -159,8 +169,7 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid protected virtual void OnFilterChanged( string oldValue, string newValue ) { - if( Properties != null ) - Properties.Filter( newValue ); + Properties.Filter( newValue ); } #endregion //Filter @@ -206,7 +215,9 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid protected virtual void OnIsCategorizedChanged( bool oldValue, bool newValue ) { - InitializePropertyGrid( newValue ); + this.UpdateProperties( false ); + this.UpdateThumb(); + } #endregion //IsCategorized @@ -235,23 +246,19 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid protected virtual void OnNameColumnWidthChanged( double oldValue, double newValue ) { - ( ( TranslateTransform )_dragThumb.RenderTransform ).X = newValue; + if( _dragThumb != null ) + ( ( TranslateTransform )_dragThumb.RenderTransform ).X = newValue; } #endregion //NameColumnWidth #region Properties - private static readonly DependencyPropertyKey PropertiesPropertyKey = DependencyProperty.RegisterReadOnly( "Properties", typeof( PropertyItemCollection ), typeof( PropertyGrid ), new UIPropertyMetadata( null ) ); public PropertyItemCollection Properties { get { - return ( PropertyItemCollection )GetValue( PropertiesPropertyKey.DependencyProperty ); - } - private set - { - SetValue( PropertiesPropertyKey, value ); + return _properties; } } @@ -259,26 +266,20 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid #region PropertyDefinitions - public static readonly DependencyProperty PropertyDefinitionsProperty = DependencyProperty.Register( "PropertyDefinitions", typeof( PropertyDefinitionCollection ), typeof( PropertyGrid ), new UIPropertyMetadata( null, OnPropertyDefinitionsChanged ) ); public PropertyDefinitionCollection PropertyDefinitions { get { - return ( PropertyDefinitionCollection )GetValue( PropertyDefinitionsProperty ); + return _propertyDefinitions; } set { - SetValue( PropertyDefinitionsProperty, value ); + PropertyDefinitionCollection oldValue = _propertyDefinitions; + _propertyDefinitions = value; + this.OnPropertyDefinitionsChanged( oldValue, value ); } } - private static void OnPropertyDefinitionsChanged( DependencyObject o, DependencyPropertyChangedEventArgs e ) - { - PropertyGrid propertyGrid = o as PropertyGrid; - if( propertyGrid != null ) - propertyGrid.OnPropertyDefinitionsChanged( ( PropertyDefinitionCollection )e.OldValue, ( PropertyDefinitionCollection )e.NewValue ); - } - protected virtual void OnPropertyDefinitionsChanged( PropertyDefinitionCollection oldValue, PropertyDefinitionCollection newValue ) { if( oldValue != null ) @@ -287,11 +288,45 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid if( newValue != null ) newValue.CollectionChanged += new NotifyCollectionChangedEventHandler( OnPropertyDefinitionsCollectionChanged ); - RefreshPropertyGrid(); + UpdateProperties( true ); + } + + private void OnPropertyDefinitionsCollectionChanged( object sender, NotifyCollectionChangedEventArgs e ) + { + UpdateProperties( true ); } #endregion //PropertyDefinitions + #region IsReadOnly + + public static readonly DependencyProperty IsReadOnlyProperty = DependencyProperty.Register( "IsReadOnly", typeof( bool ), typeof( PropertyGrid ), new UIPropertyMetadata( false, OnIsReadOnlyChanged ) ); + public bool IsReadOnly + { + get + { + return ( bool )GetValue( IsReadOnlyProperty ); + } + set + { + SetValue( IsReadOnlyProperty, value ); + } + } + + private static void OnIsReadOnlyChanged( DependencyObject o, DependencyPropertyChangedEventArgs e ) + { + PropertyGrid propertyGrid = o as PropertyGrid; + if( propertyGrid != null ) + { + foreach( PropertyItem propertyItem in propertyGrid.Properties ) + { + propertyItem.Editor.IsEnabled = !propertyGrid.IsReadOnly; + } + } + } + + #endregion //ReadOnly + #region SelectedObject public static readonly DependencyProperty SelectedObjectProperty = DependencyProperty.Register( "SelectedObject", typeof( object ), typeof( PropertyGrid ), new UIPropertyMetadata( null, OnSelectedObjectChanged ) ); @@ -317,20 +352,15 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid protected virtual void OnSelectedObjectChanged( object oldValue, object newValue ) { // We do not want to process the change now if the grid is initializing (ie. BeginInit/EndInit). - _hasPendingSelectedObjectChanged = IsInitializing(); - - if( IsInitializing() ) - return; - - if( newValue == null ) - ResetPropertyGrid(); - else + if( _initializationCount != 0 ) { - SetSelectedObjectNameBinding( newValue ); - SelectedObjectType = newValue.GetType(); - _propertyItemsCache = GetObjectProperties( newValue ); - InitializePropertyGrid( IsCategorized ); + _hasPendingSelectedObjectChanged = true; + return; } + + this.UpdateProperties( true ); + + RaiseEvent( new RoutedPropertyChangedEventArgs( oldValue, newValue, PropertyGrid.SelectedObjectChangedEvent ) ); } #endregion //SelectedObject @@ -344,7 +374,7 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid { return ( Type )GetValue( SelectedObjectTypeProperty ); } - private set + set { SetValue( SelectedObjectTypeProperty, value ); } @@ -359,13 +389,6 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid protected virtual void OnSelectedObjectTypeChanged( Type oldValue, Type newValue ) { - if( newValue == null ) - SelectedObjectTypeName = string.Empty; - else - { - DisplayNameAttribute displayNameAttribute = newValue.GetCustomAttributes( false ).OfType().FirstOrDefault(); - SelectedObjectTypeName = displayNameAttribute == null ? newValue.Name : displayNameAttribute.DisplayName; - } } #endregion //SelectedObjectType @@ -379,7 +402,7 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid { return ( string )GetValue( SelectedObjectTypeNameProperty ); } - private set + set { SetValue( SelectedObjectTypeNameProperty, value ); } @@ -389,19 +412,31 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid #region SelectedObjectName - public static readonly DependencyProperty SelectedObjectNameProperty = DependencyProperty.Register( "SelectedObjectName", typeof( string ), typeof( PropertyGrid ), new UIPropertyMetadata( string.Empty, OnSelectedObjectNameChanged ) ); + public static readonly DependencyProperty SelectedObjectNameProperty = DependencyProperty.Register( "SelectedObjectName", typeof( string ), typeof( PropertyGrid ), new UIPropertyMetadata( string.Empty, OnSelectedObjectNameChanged, OnCoerceSelectedObjectName ) ); public string SelectedObjectName { get { return ( string )GetValue( SelectedObjectNameProperty ); } - private set + set { SetValue( SelectedObjectNameProperty, value ); } } + private static object OnCoerceSelectedObjectName( DependencyObject o, object baseValue ) + { + PropertyGrid propertyGrid = o as PropertyGrid; + if( propertyGrid != null ) + { + if( (propertyGrid.SelectedObject is FrameworkElement) && ( String.IsNullOrEmpty( ( String )baseValue ) )) + return ""; + } + + return baseValue; + } + private static void OnSelectedObjectNameChanged( DependencyObject o, DependencyPropertyChangedEventArgs e ) { PropertyGrid propertyGrid = o as PropertyGrid; @@ -411,7 +446,6 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid protected virtual void SelectedObjectNameChanged( string oldValue, string newValue ) { - } #endregion //SelectedObjectName @@ -443,10 +477,10 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid if( oldValue != null ) oldValue.IsSelected = false; - //if (newValue != null) - // newValue.IsSelected = true; + if( newValue != null ) + newValue.IsSelected = true; - RaiseEvent( new RoutedEventArgs( PropertyGrid.SelectedPropertyItemChangedEvent, newValue ) ); + RaiseEvent( new RoutedPropertyChangedEventArgs( oldValue, newValue, PropertyGrid.SelectedPropertyItemChangedEvent ) ); } #endregion //SelectedPropertyItem @@ -530,8 +564,11 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid public PropertyGrid() { + _properties = new PropertyItemCollection( new ObservableCollection() ); EditorDefinitions = new EditorDefinitionCollection(); PropertyDefinitions = new PropertyDefinitionCollection(); + + AddHandler( PropertyItem.ItemSelectionChangedEvent, new RoutedEventHandler( OnItemSelectionChanged ) ); CommandBindings.Add( new CommandBinding( PropertyGridCommands.ClearFilter, ClearFilter, CanClearFilter ) ); } @@ -560,6 +597,8 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid TranslateTransform _moveTransform = new TranslateTransform(); _moveTransform.X = NameColumnWidth; _dragThumb.RenderTransform = _moveTransform; + + this.UpdateThumb(); } protected override void OnPreviewKeyDown( KeyEventArgs e ) @@ -579,7 +618,23 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid #region Event Handlers - void DragThumb_DragDelta( object sender, DragDeltaEventArgs e ) + private void OnItemSelectionChanged( object sender, RoutedEventArgs args ) + { + PropertyItem item = ( PropertyItem )args.OriginalSource; + if( item.IsSelected ) + { + SelectedPropertyItem = item; + } + else + { + if( object.ReferenceEquals( item, SelectedPropertyItem ) ) + { + SelectedPropertyItem = null; + } + } + } + + private void DragThumb_DragDelta( object sender, DragDeltaEventArgs e ) { NameColumnWidth = Math.Max( 0, NameColumnWidth + e.HorizontalChange ); } @@ -602,123 +657,77 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid #region Methods - private void InitializePropertyGrid( bool isCategorized ) - { - LoadProperties( isCategorized ); - SetDragThumbMargin( isCategorized ); - } - - private void LoadProperties( bool isCategorized ) + private void UpdateProperties( bool regenerateItems ) { - if( _propertyItemsCache == null ) - return; + IEnumerable newProperties = null; + if( regenerateItems ) + { + newProperties = this.GeneratePropertyItems( this.SelectedObject ); - //clear any filters first - Filter = String.Empty; + string defaultPropertyName = PropertyGridUtilities.GetDefaultPropertyName( this.SelectedObject ); + this.SelectedPropertyItem = newProperties.FirstOrDefault( ( prop ) => prop.Name.Equals( defaultPropertyName ) ); + } - if( isCategorized ) - Properties = PropertyGridUtilities.GetCategorizedProperties( _propertyItemsCache ); - else - Properties = PropertyGridUtilities.GetAlphabetizedProperties( _propertyItemsCache ); + Properties.Update( newProperties, IsCategorized, Filter ); } - private List GetObjectProperties( object instance ) + private List GeneratePropertyItems(object instance) { var propertyItems = new List(); - if( instance == null ) - return propertyItems; - try + if( instance != null ) { - PropertyDescriptorCollection descriptors = PropertyGridUtilities.GetPropertyDescriptors( instance ); - - if( !AutoGenerateProperties ) + try { - List specificProperties = new List(); - if( PropertyDefinitions != null ) + PropertyDescriptorCollection descriptors = PropertyGridUtilities.GetPropertyDescriptors( instance ); + + if( !AutoGenerateProperties ) { - foreach( PropertyDefinition pd in PropertyDefinitions ) + List specificProperties = new List(); + if( PropertyDefinitions != null ) { - foreach( PropertyDescriptor descriptor in descriptors ) + foreach( PropertyDefinition pd in PropertyDefinitions ) { - if( descriptor.Name == pd.Name ) + foreach( PropertyDescriptor descriptor in descriptors ) { - specificProperties.Add( descriptor ); - break; + if( descriptor.Name == pd.Name ) + { + specificProperties.Add( descriptor ); + break; + } } } } + + descriptors = new PropertyDescriptorCollection( specificProperties.ToArray() ); } - descriptors = new PropertyDescriptorCollection( specificProperties.ToArray() ); + foreach( PropertyDescriptor descriptor in descriptors ) + { + if( descriptor.IsBrowsable ) + propertyItems.Add( PropertyGridUtilities.CreatePropertyItem( descriptor, this ) ); + } } - - foreach( PropertyDescriptor descriptor in descriptors ) + catch( Exception ) { - if( descriptor.IsBrowsable ) - propertyItems.Add( PropertyGridUtilities.CreatePropertyItem( descriptor, instance, this, descriptor.Name ) ); + //TODO: handle this some how } } - catch( Exception ) - { - //TODO: handle this some how - } return propertyItems; } - private void SetSelectedObjectNameBinding( object selectedObject ) + private void UpdateThumb() { - if( selectedObject is FrameworkElement ) + if( _dragThumb != null ) { - var binding = new Binding( "Name" ); - binding.Source = selectedObject; - binding.Mode = BindingMode.OneWay; - BindingOperations.SetBinding( this, PropertyGrid.SelectedObjectNameProperty, binding ); + if( IsCategorized ) + _dragThumb.Margin = new Thickness( 6, 0, 0, 0 ); + else + _dragThumb.Margin = new Thickness( -1, 0, 0, 0 ); } } - private void SetDragThumbMargin( bool isCategorized ) - { - if( _dragThumb == null ) - return; - - if( isCategorized ) - _dragThumb.Margin = new Thickness( 6, 0, 0, 0 ); - else - _dragThumb.Margin = new Thickness( -1, 0, 0, 0 ); - } - - private void ResetPropertyGrid() - { - SelectedObjectName = String.Empty; - SelectedObjectType = null; - _propertyItemsCache = null; - SelectedPropertyItem = null; - Properties = null; - } - - private void OnEditorDefinitionsCollectionChanged( object sender, NotifyCollectionChangedEventArgs e ) - { - RefreshPropertyGrid(); - } - - private void OnPropertyDefinitionsCollectionChanged( object sender, NotifyCollectionChangedEventArgs e ) - { - RefreshPropertyGrid(); - } - - private void RefreshPropertyGrid() - { - _propertyItemsCache = GetObjectProperties( SelectedObject ); - InitializePropertyGrid( IsCategorized ); - } - - private bool IsInitializing() - { - return _initializationCount != 0; - } - /// /// Updates all property values in the PropertyGrid with the data from the SelectedObject /// @@ -747,8 +756,8 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid } } - public static readonly RoutedEvent SelectedPropertyItemChangedEvent = EventManager.RegisterRoutedEvent( "SelectedPropertyItemChanged", RoutingStrategy.Bubble, typeof( RoutedEventHandler ), typeof( PropertyGrid ) ); - public event RoutedEventHandler SelectedPropertyItemChanged + public static readonly RoutedEvent SelectedPropertyItemChangedEvent = EventManager.RegisterRoutedEvent( "SelectedPropertyItemChanged", RoutingStrategy.Bubble, typeof( RoutedPropertyChangedEventHandler ), typeof( PropertyGrid ) ); + public event RoutedPropertyChangedEventHandler SelectedPropertyItemChanged { add { @@ -760,6 +769,19 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid } } + public static readonly RoutedEvent SelectedObjectChangedEvent = EventManager.RegisterRoutedEvent( "SelectedObjectChanged", RoutingStrategy.Bubble, typeof( RoutedPropertyChangedEventHandler ), typeof( PropertyGrid ) ); + public event RoutedPropertyChangedEventHandler SelectedObjectChanged + { + add + { + AddHandler( SelectedObjectChangedEvent, value ); + } + remove + { + RemoveHandler( SelectedObjectChangedEvent, value ); + } + } + #endregion //Events #region Interfaces @@ -786,12 +808,32 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid if( _hasPendingSelectedObjectChanged ) { //This will update SelectedObject, Type, Name based on the actual config. - OnSelectedObjectChanged( SelectedObject, SelectedObject ); + this.UpdateProperties( true ); + _hasPendingSelectedObjectChanged = false; } } #endregion + #region IPropertyParent Members + + bool IPropertyParent.IsReadOnly + { + get { return this.IsReadOnly; } + } + + object IPropertyParent.ValueInstance + { + get { return this.SelectedObject; } + } + + EditorDefinitionCollection IPropertyParent.EditorDefinitions + { + get { return this.EditorDefinitions; } + } + + #endregion + #endregion } diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyGridUtilities.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyGridUtilities.cs index b8ffc753..2cf14c37 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyGridUtilities.cs +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyGridUtilities.cs @@ -34,34 +34,17 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid { internal static T GetAttribute( PropertyDescriptor property ) where T : Attribute { - foreach( Attribute att in property.Attributes ) - { - var tAtt = att as T; - if( tAtt != null ) - return tAtt; - } - return null; + return property.Attributes.OfType().FirstOrDefault(); } - internal static PropertyItemCollection GetAlphabetizedProperties( List propertyItems ) - { - PropertyItemCollection propertyCollection = new PropertyItemCollection( propertyItems ); - propertyCollection.SortBy( "DisplayName", ListSortDirection.Ascending ); - return propertyCollection; - } - internal static PropertyItemCollection GetCategorizedProperties( List propertyItems ) + internal static string GetDefaultPropertyName( object instance ) { - PropertyItemCollection propertyCollection = new PropertyItemCollection( propertyItems ); - propertyCollection.GroupBy( "Category" ); - propertyCollection.SortBy( "Category", ListSortDirection.Ascending ); - - propertyCollection.SortBy( "PropertyOrder", ListSortDirection.Ascending ); - propertyCollection.SortBy( "DisplayName", ListSortDirection.Ascending ); - return propertyCollection; + AttributeCollection attributes = TypeDescriptor.GetAttributes( instance ); + DefaultPropertyAttribute defaultPropertyAttribute =( DefaultPropertyAttribute )attributes[ typeof( DefaultPropertyAttribute ) ]; + return defaultPropertyAttribute != null ? defaultPropertyAttribute.Name : null; } - internal static PropertyDescriptorCollection GetPropertyDescriptors( object instance ) { PropertyDescriptorCollection descriptors; @@ -83,33 +66,31 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid return descriptors; } - internal static PropertyItem CreatePropertyItem( PropertyDescriptor property, object instance, PropertyGrid grid, string bindingPath ) + internal static PropertyItem CreatePropertyItem( PropertyDescriptor property, IPropertyParent propertyParent ) { - return CreatePropertyItem(property, instance, grid, bindingPath, 0); + return CreatePropertyItem( property, propertyParent, 0 ); } - internal static PropertyItem CreatePropertyItem( PropertyDescriptor property, object instance, PropertyGrid grid, string bindingPath, int level ) + internal static PropertyItem CreatePropertyItem( PropertyDescriptor property, IPropertyParent propertyParent, int level ) { - PropertyItem propertyItem = new PropertyItem( instance, property, grid, bindingPath, level ); + PropertyItem propertyItem = new PropertyItem( property, propertyParent, level ); - var binding = new Binding( bindingPath ) + var binding = new Binding( property.Name ) { - Source = instance, + Source = propertyParent.ValueInstance, ValidatesOnExceptions = true, ValidatesOnDataErrors = true, Mode = propertyItem.IsReadOnly ? BindingMode.OneWay : BindingMode.TwoWay }; propertyItem.SetBinding( PropertyItem.ValueProperty, binding ); - propertyItem.Editor = PropertyGridUtilities.GetTypeEditor( propertyItem - , grid.EditorDefinitions - ); + propertyItem.Editor = PropertyGridUtilities.GetTypeEditor( propertyItem, propertyParent.EditorDefinitions ); return propertyItem; } - internal static FrameworkElement GetTypeEditor( PropertyItem propertyItem - , EditorDefinitionCollection editorDefinitions - ) + internal static FrameworkElement GetTypeEditor( + PropertyItem propertyItem, + EditorDefinitionCollection editorDefinitions ) { FrameworkElement editor = null; @@ -125,6 +106,7 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid if( editor == null ) editor = PropertyGridUtilities.CreateDefaultEditor( propertyItem ); + editor.IsEnabled = !propertyItem.PropertyParent.IsReadOnly; return editor; } @@ -188,6 +170,22 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid editor = new DoubleUpDownEditor(); else if( propertyItem.PropertyType == typeof( int ) || propertyItem.PropertyType == typeof( int? ) ) editor = new IntegerUpDownEditor(); + else if( propertyItem.PropertyType == typeof( short ) || propertyItem.PropertyType == typeof( short? ) ) + editor = new ShortUpDownEditor(); + else if( propertyItem.PropertyType == typeof( long ) || propertyItem.PropertyType == typeof( long? ) ) + editor = new LongUpDownEditor(); + else if( propertyItem.PropertyType == typeof( float ) || propertyItem.PropertyType == typeof( float? ) ) + editor = new SingleUpDownEditor(); + else if( propertyItem.PropertyType == typeof( byte ) || propertyItem.PropertyType == typeof( byte? ) ) + editor = new ByteUpDownEditor(); + else if( propertyItem.PropertyType == typeof( sbyte ) || propertyItem.PropertyType == typeof( sbyte? ) ) + editor = new UpDownEditor(); + else if( propertyItem.PropertyType == typeof( uint ) || propertyItem.PropertyType == typeof( uint? ) ) + editor = new UpDownEditor(); + else if( propertyItem.PropertyType == typeof( ulong ) || propertyItem.PropertyType == typeof( ulong? ) ) + editor = new UpDownEditor(); + else if( propertyItem.PropertyType == typeof( ushort ) || propertyItem.PropertyType == typeof( ushort? ) ) + editor = new UpDownEditor(); else if( propertyItem.PropertyType == typeof( DateTime ) || propertyItem.PropertyType == typeof( DateTime? ) ) editor = new DateTimeUpDownEditor(); else if( ( propertyItem.PropertyType == typeof( Color ) ) ) @@ -198,11 +196,16 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid editor = new TimeSpanEditor(); else if( propertyItem.PropertyType == typeof( FontFamily ) || propertyItem.PropertyType == typeof( FontWeight ) || propertyItem.PropertyType == typeof( FontStyle ) || propertyItem.PropertyType == typeof( FontStretch ) ) editor = new FontComboBoxEditor(); + else if( propertyItem.PropertyType == typeof( object ) ) + // If any type of object is possible in the property, default to the TextBoxEditor. + // Useful in some case (e.g., Button.Content). + // Can be reconsidered but was the legacy behavior on the PropertyGrid. + editor = new TextBoxEditor(); else { - Type listType = CollectionEditor.GetListItemType(propertyItem.PropertyType); + Type listType = CollectionEditor.GetListItemType( propertyItem.PropertyType ); - if(listType != null) + if( listType != null ) { if( !listType.IsPrimitive && !listType.Equals( typeof( String ) ) ) editor = new Xceed.Wpf.Toolkit.PropertyGrid.Editors.CollectionEditor(); @@ -210,7 +213,15 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid editor = new Xceed.Wpf.Toolkit.PropertyGrid.Editors.PrimitiveTypeCollectionEditor(); } else - editor = new TextBoxEditor(); + { + // If the type is not supported, check if there is a converter that supports + // string conversion to the object type. Use TextBox in theses cases. + // Otherwise, return a TextBlock editor since no valid editor exists. + TypeConverter typeConverter = propertyItem.PropertyDescriptor.Converter; + editor = ( typeConverter != null && typeConverter.CanConvertFrom( typeof( string ) ) ) + ? ( ITypeEditor )new TextBoxEditor() + : ( ITypeEditor )new TextBlockEditor(); + } } return editor.ResolveEditor( propertyItem ); diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyItem.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyItem.cs index 1684b3e4..0ecdb32a 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyItem.cs +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyItem.cs @@ -28,50 +28,73 @@ using System.Windows.Input; using System.Windows.Markup.Primitives; using Xceed.Wpf.Toolkit.PropertyGrid.Attributes; using Xceed.Wpf.Toolkit.PropertyGrid.Commands; +using System.Collections.ObjectModel; +using Xceed.Wpf.Toolkit.Core.Utilities; namespace Xceed.Wpf.Toolkit.PropertyGrid { - public class PropertyItem : Control + public class PropertyItem : Control, INotifyPropertyChanged, IPropertyParent { #region Members - private DependencyPropertyDescriptor _dpDescriptor; - private MarkupObject _markupObject; + private readonly DependencyPropertyDescriptor _dpDescriptor; + private readonly MarkupObject _markupObject; + private readonly NotifyPropertyChangedHelper _propertyChangedHelper; + + private string _displayName; + private string _description; + private string _category; + private int _categoryOrder; + private int _propertyOrder; #endregion //Members #region Properties - public string BindingPath - { - get; - private set; - } #region Category - public static readonly DependencyProperty CategoryProperty = DependencyProperty.Register( "Category", typeof( string ), typeof( PropertyItem ), new UIPropertyMetadata( string.Empty ) ); public string Category { get { - return ( string )GetValue( CategoryProperty ); + return _category; } set { - SetValue( CategoryProperty, value ); + _propertyChangedHelper.HandleEqualityChanged( () => Category, ref _category, value ); } } #endregion //Category + #region CategoryOrder + + public int CategoryOrder + { + get + { + return _categoryOrder; + } + set + { + _propertyChangedHelper.HandleEqualityChanged( () => CategoryOrder, ref _categoryOrder, value ); + } + } + + #endregion // CategoryOrder + #region Description public string Description { get { - return PropertyDescriptor.Description; + return _description; + } + set + { + _propertyChangedHelper.HandleEqualityChanged( () => Description, ref _description, value ); } } @@ -79,16 +102,15 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid #region DisplayName - public static readonly DependencyProperty DisplayNameProperty = DependencyProperty.Register( "DisplayName", typeof( string ), typeof( PropertyItem ), new UIPropertyMetadata( null ) ); public string DisplayName { get { - return ( string )GetValue( DisplayNameProperty ); + return _displayName; } set { - SetValue( DisplayNameProperty, value ); + _propertyChangedHelper.HandleEqualityChanged( () => DisplayName, ref _displayName, value ); } } @@ -129,18 +151,10 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid #region Instance - private object _instance; public object Instance { - get - { - return _instance; - } - private set - { - _instance = value; - _markupObject = MarkupWriter.GetMarkupObjectFor( _instance ); - } + get; + private set; } #endregion //Instance @@ -154,7 +168,7 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid { get { - var dependencyObject = Instance as DependencyObject; + var dependencyObject = PropertyParent.ValueInstance as DependencyObject; if( dependencyObject != null && _dpDescriptor != null ) return BindingOperations.GetBindingExpressionBase( dependencyObject, _dpDescriptor.DependencyProperty ) != null; @@ -203,7 +217,7 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid protected virtual void OnIsExpandedChanged( bool oldValue, bool newValue ) { - if( newValue && ( Properties == null || Properties.Count == 0 ) ) + if( newValue && Properties.Count == 0 ) { GetChildProperties(); } @@ -247,8 +261,10 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid public bool IsReadOnly { - get; - private set; + get + { + return PropertyDescriptor.IsReadOnly; + } } #region IsSelected @@ -275,75 +291,66 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid protected virtual void OnIsSelectedChanged( bool oldValue, bool newValue ) { - if( newValue ) - PropertyGrid.SelectedPropertyItem = this; + this.RaiseItemSelectionChangedEvent(); } #endregion //IsSelected #region Level - public static readonly DependencyProperty LevelProperty = DependencyProperty.Register( "Level", typeof( int ), typeof( PropertyItem ), new UIPropertyMetadata( 0 ) ); public int Level { - get - { - return ( int )GetValue( LevelProperty ); - } - set - { - SetValue( LevelProperty, value ); - } + get; + private set; } #endregion //Level #region Properties - public static readonly DependencyProperty PropertiesProperty = DependencyProperty.Register( "Properties", typeof( PropertyItemCollection ), typeof( PropertyItem ), new UIPropertyMetadata( null ) ); public PropertyItemCollection Properties { - get - { - return ( PropertyItemCollection )GetValue( PropertiesProperty ); - } - set - { - SetValue( PropertiesProperty, value ); - } + get; + private set; } #endregion //Properties #region PropertyDescriptor - private PropertyDescriptor _propertyDescriptor; public PropertyDescriptor PropertyDescriptor { - get - { - return _propertyDescriptor; - } - private set - { - _propertyDescriptor = value; - _dpDescriptor = DependencyPropertyDescriptor.FromProperty( _propertyDescriptor ); - } + get; + private set; } #endregion //PropertyDescriptor - public PropertyGrid PropertyGrid + #region PropertyParent + + internal IPropertyParent PropertyParent { get; private set; } + #endregion + + #region PropertyOrder + public int PropertyOrder { - get; - set; - } //maybe make a DP + get + { + return _propertyOrder; + } + set + { + _propertyChangedHelper.HandleEqualityChanged( () => PropertyOrder, ref _propertyOrder, value ); + } + } + + #endregion #region PropertyType @@ -357,12 +364,16 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid #endregion //PropertyType + #region ResetValueCommand + public ICommand ResetValueCommand { get; private set; } + #endregion + #region Value public static readonly DependencyProperty ValueProperty = DependencyProperty.Register( "Value", typeof( object ), typeof( PropertyItem ), new UIPropertyMetadata( null, OnValueChanged ) ); @@ -391,7 +402,7 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid { if( IsInitialized ) { - PropertyGrid.RaiseEvent( new PropertyValueChangedEventArgs( PropertyGrid.PropertyValueChangedEvent, this, oldValue, newValue ) ); + RaiseEvent( new PropertyValueChangedEventArgs( PropertyGrid.PropertyValueChangedEvent, this, oldValue, newValue ) ); } } @@ -406,7 +417,7 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid { get { - var dependencyObject = Instance as DependencyObject; + var dependencyObject = PropertyParent.ValueInstance as DependencyObject; if( _dpDescriptor != null && dependencyObject != null ) return DependencyPropertyHelper.GetValueSource( dependencyObject, _dpDescriptor.DependencyProperty ).BaseValueSource; @@ -418,6 +429,25 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid #endregion //Properties + #region Events + + public event PropertyChangedEventHandler PropertyChanged; + + #region ItemSelectionChanged + + internal static readonly RoutedEvent ItemSelectionChangedEvent = EventManager.RegisterRoutedEvent( + "ItemSelectedEvent", RoutingStrategy.Bubble, typeof( RoutedEventHandler ), typeof( PropertyItem ) ); + + // This method raises the Tap event + private void RaiseItemSelectionChangedEvent() + { + RaiseEvent( new RoutedEventArgs( PropertyItem.ItemSelectionChangedEvent ) ); + } + + #endregion + + #endregion + #region Constructors static PropertyItem() @@ -425,18 +455,26 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid DefaultStyleKeyProperty.OverrideMetadata( typeof( PropertyItem ), new FrameworkPropertyMetadata( typeof( PropertyItem ) ) ); } - public PropertyItem( object instance, PropertyDescriptor property, PropertyGrid propertyGrid, string bindingPath, int level ) + internal PropertyItem( PropertyDescriptor property, IPropertyParent propertyParent, int level ) { + _propertyChangedHelper = new NotifyPropertyChangedHelper( this, RaisePropertyChanged ); + Properties = new PropertyItemCollection( new ObservableCollection() ); + PropertyParent = propertyParent; PropertyDescriptor = property; - PropertyGrid = propertyGrid; - Instance = instance; - BindingPath = bindingPath; Level = level; - SetPropertyDescriptorProperties(); - ResolveParenthesisPropertyName(); - ResolveExpandableObject(); - ResolvePropertyOrder(); + + Name = PropertyDescriptor.Name; + Category = PropertyDescriptor.Category; + CategoryOrder = 0; + + Description = ResolveDescription(); + DisplayName = ResolveDisplayName(); + HasChildProperties = ResolveExpandableObject(); + PropertyOrder = ResolvePropertyOrder(); + + _dpDescriptor = DependencyPropertyDescriptor.FromProperty( PropertyDescriptor ); + _markupObject = MarkupWriter.GetMarkupObjectFor( PropertyParent.ValueInstance ); CommandBindings.Add( new CommandBinding( PropertyItemCommands.ResetValue, ExecuteResetValueCommand, CanExecuteResetValueCommand ) ); AddHandler( Mouse.PreviewMouseDownEvent, new MouseButtonEventHandler( PropertyItem_PreviewMouseDown ), true ); @@ -457,8 +495,8 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid private void ExecuteResetValueCommand( object sender, ExecutedRoutedEventArgs e ) { - if( PropertyDescriptor.CanResetValue( Instance ) ) - PropertyDescriptor.ResetValue( Instance ); + if( PropertyDescriptor.CanResetValue( PropertyParent.ValueInstance ) ) + PropertyDescriptor.ResetValue( PropertyParent.ValueInstance ); //TODO: notify UI that the ValueSource may have changed to update the icon } @@ -467,7 +505,7 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid { bool canExecute = false; - if( PropertyDescriptor.CanResetValue( Instance ) && !PropertyDescriptor.IsReadOnly ) + if( PropertyDescriptor.CanResetValue( PropertyParent.ValueInstance ) && !PropertyDescriptor.IsReadOnly ) { canExecute = true; } @@ -479,6 +517,14 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid #region Methods + private void RaisePropertyChanged( string propertyName ) + { + if( this.PropertyChanged != null ) + { + this.PropertyChanged( this, new PropertyChangedEventArgs( propertyName ) ); + } + } + private void GetChildProperties() { if( Value == null ) @@ -494,7 +540,7 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid { if( descriptor.IsBrowsable ) { - PropertyItem childPropertyItem = PropertyGridUtilities.CreatePropertyItem( descriptor, Instance, PropertyGrid, String.Format( "{0}.{1}", BindingPath, descriptor.Name ), Level + 1 ); + PropertyItem childPropertyItem = PropertyGridUtilities.CreatePropertyItem( descriptor, this, Level + 1 ); propertyItems.Add( childPropertyItem ); } } @@ -504,45 +550,89 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid //TODO: handle this some how } - Properties = PropertyGridUtilities.GetAlphabetizedProperties( propertyItems ); + Properties.Update( propertyItems, false, null ); } - private void ResolveParenthesisPropertyName() + private string ResolveDescription() { - var attribute = PropertyGridUtilities.GetAttribute( PropertyDescriptor ); + //We do not simply rely on the "Description" property of PropertyDescriptor + //since this value is cached bye PropertyDescriptor and the localized version + //(eg. LocalizedDescriptionAttribute) value can dynamicaly change + DescriptionAttribute descriptionAtt = GetAttribute(); + return ( descriptionAtt != null ) + ? descriptionAtt.Description + : PropertyDescriptor.Description; + } + + + + + + + + + private string ResolveDisplayName() + { + string displayName = PropertyDescriptor.DisplayName; + var attribute = GetAttribute(); if( (attribute != null) && attribute.NeedParenthesis ) { - DisplayName = "(" + DisplayName + ")"; + displayName = "(" + displayName + ")"; } + + return displayName; } - private void ResolveExpandableObject() + private bool ResolveExpandableObject() { - var attribute = PropertyGridUtilities.GetAttribute( PropertyDescriptor ); + bool isExpandable = false; + var attribute = GetAttribute(); if( attribute != null ) { - HasChildProperties = true; - IsReadOnly = true; + isExpandable = true; } + + return isExpandable; } - private void ResolvePropertyOrder() + private int ResolvePropertyOrder() { - var attrs = PropertyDescriptor.Attributes.OfType(); - if( attrs.Any() ) - PropertyOrder = attrs.First().Order; - else - PropertyOrder = 0; + var attribute = GetAttribute(); + + // Max Value. Properties with no order will be displayed last. + return ( attribute != null ) + ? attribute.Order + : int.MaxValue; } - private void SetPropertyDescriptorProperties() + private T GetAttribute() where T : Attribute { - Name = PropertyDescriptor.Name; - DisplayName = PropertyDescriptor.DisplayName; - Category = PropertyDescriptor.Category; - IsReadOnly = PropertyDescriptor.IsReadOnly; + return PropertyGridUtilities.GetAttribute( PropertyDescriptor ); } #endregion //Methods + + #region Interfaces + + #region IPropertyParent Members + + bool IPropertyParent.IsReadOnly + { + get { return PropertyParent.IsReadOnly; } + } + + object IPropertyParent.ValueInstance + { + get { return Value; } + } + + EditorDefinitionCollection IPropertyParent.EditorDefinitions + { + get { return PropertyParent.EditorDefinitions; } + } + + #endregion + + #endregion } } diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyItemCollection.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyItemCollection.cs index 53961ee1..f18b064c 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyItemCollection.cs +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyItemCollection.cs @@ -21,26 +21,23 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Windows.Data; +using System; +using System.Collections.Specialized; +using System.Diagnostics; namespace Xceed.Wpf.Toolkit.PropertyGrid { - public class PropertyItemCollection : ObservableCollection + public class PropertyItemCollection : ReadOnlyObservableCollection { - public PropertyItemCollection() - { - - } + private bool _preventNotification; - public PropertyItemCollection( List list ) - : base( list ) + public PropertyItemCollection(ObservableCollection editableCollection) + :base(editableCollection) { - + EditableCollection = editableCollection; } - public PropertyItemCollection( IEnumerable collection ) - : base( collection ) - { - } + public ObservableCollection EditableCollection { get; private set; } private ICollectionView GetDefaultView() { @@ -68,5 +65,52 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid return property.DisplayName.ToLower().StartsWith( text.ToLower() ); }; } + + protected override void OnCollectionChanged( NotifyCollectionChangedEventArgs args ) + { + if( _preventNotification ) + return; + + base.OnCollectionChanged( args ); + } + + internal void Update( IEnumerable newItems, bool isCategorized, string filter ) + { + using( GetDefaultView().DeferRefresh() ) + { + _preventNotification = true; + + // Replace the collection content with the new items. + if( newItems != null ) + { + EditableCollection.Clear(); + foreach( var item in newItems ) + { + this.EditableCollection.Add( item ); + } + } + + // Clear view values + ICollectionView view = this.GetDefaultView(); + view.GroupDescriptions.Clear(); + view.SortDescriptions.Clear(); + view.Filter = null; + + // Update view values + if( isCategorized ) + { + GroupBy( "Category" ); + SortBy( "Category", ListSortDirection.Ascending ); + } + + SortBy( "PropertyOrder", ListSortDirection.Ascending ); + SortBy( "DisplayName", ListSortDirection.Ascending ); + + Filter( filter ); + + _preventNotification = false; + OnCollectionChanged( new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Reset ) ); + } + } } } diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Themes/Generic.xaml b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Themes/Generic.xaml index 2f8c6e0c..41db4dfd 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Themes/Generic.xaml +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Themes/Generic.xaml @@ -24,7 +24,8 @@ xmlns:conv="clr-namespace:Xceed.Wpf.Toolkit.Core.Converters" xmlns:pgconv="clr-namespace:Xceed.Wpf.Toolkit.PropertyGrid.Converters" xmlns:utilities="clr-namespace:Xceed.Wpf.Toolkit.Core.Utilities" - xmlns:commands="clr-namespace:Xceed.Wpf.Toolkit.PropertyGrid.Commands"> + xmlns:commands="clr-namespace:Xceed.Wpf.Toolkit.PropertyGrid.Commands" + xmlns:sys="clr-namespace:System;assembly=mscorlib"> @@ -36,6 +37,8 @@ + + @@ -358,7 +361,7 @@ - + @@ -392,18 +395,27 @@ - + + + + + + + + + + + + + + + +Here, you can test various expression that will be parsed. +The result of the parsing will be shown in the second TextBox. +Don't forget to check the Output Window for errors that could have occured during the +automated tests. Untested expressions by the automated tests should be added when found. + + + + + + + + + + + + + + + + + + + + + + + + + + + Invariant + fr-FR + en-US + + + + + + + + + + + + + + + +