diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/AssemblyVersionInfo.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/AssemblyVersionInfo.cs index 6a1d0bb3..2d6c85ea 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/AssemblyVersionInfo.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/AssemblyVersionInfo.cs @@ -21,7 +21,7 @@ internal static class _XceedVersionInfo { [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] - public const string BaseVersion = "3.6"; + public const string BaseVersion = "3.7"; [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] public const string Version = BaseVersion + ".0.0"; diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/Theme.xaml b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/Theme.xaml index 293cb217..9295f896 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/Theme.xaml +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/Theme.xaml @@ -39,6 +39,10 @@ + + + + diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Debug/GeneratedInternalTypeHelper.g.i.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Debug/GeneratedInternalTypeHelper.g.i.cs deleted file mode 100644 index 8f77761a..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/obj/Debug/GeneratedInternalTypeHelper.g.i.cs +++ /dev/null @@ -1,62 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace XamlGeneratedNamespace { - - - /// - /// GeneratedInternalTypeHelper - /// - [System.Diagnostics.DebuggerNonUserCodeAttribute()] - [System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")] - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public sealed class GeneratedInternalTypeHelper : System.Windows.Markup.InternalTypeHelper { - - /// - /// CreateInstance - /// - protected override object CreateInstance(System.Type type, System.Globalization.CultureInfo culture) { - return System.Activator.CreateInstance(type, ((System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic) - | (System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.CreateInstance)), null, null, culture); - } - - /// - /// GetPropertyValue - /// - protected override object GetPropertyValue(System.Reflection.PropertyInfo propertyInfo, object target, System.Globalization.CultureInfo culture) { - return propertyInfo.GetValue(target, System.Reflection.BindingFlags.Default, null, null, culture); - } - - /// - /// SetPropertyValue - /// - protected override void SetPropertyValue(System.Reflection.PropertyInfo propertyInfo, object target, object value, System.Globalization.CultureInfo culture) { - propertyInfo.SetValue(target, value, System.Reflection.BindingFlags.Default, null, null, culture); - } - - /// - /// CreateDelegate - /// - protected override System.Delegate CreateDelegate(System.Type delegateType, object target, string handler) { - return ((System.Delegate)(target.GetType().InvokeMember("_CreateDelegate", (System.Reflection.BindingFlags.InvokeMethod - | (System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)), null, target, new object[] { - delegateType, - handler}, null))); - } - - /// - /// AddEventHandler - /// - protected override void AddEventHandler(System.Reflection.EventInfo eventInfo, object target, System.Delegate handler) { - eventInfo.AddEventHandler(target, handler); - } - } -} - diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/AssemblyVersionInfo.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/AssemblyVersionInfo.cs index 6a1d0bb3..2d6c85ea 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/AssemblyVersionInfo.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/AssemblyVersionInfo.cs @@ -21,7 +21,7 @@ internal static class _XceedVersionInfo { [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] - public const string BaseVersion = "3.6"; + public const string BaseVersion = "3.7"; [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] public const string Version = BaseVersion + ".0.0"; diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/Theme.xaml b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/Theme.xaml index 243809e8..c19aaa8e 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/Theme.xaml +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Metro/Theme.xaml @@ -37,6 +37,10 @@ + + + + diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/AssemblyVersionInfo.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/AssemblyVersionInfo.cs index 6a1d0bb3..2d6c85ea 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/AssemblyVersionInfo.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/AssemblyVersionInfo.cs @@ -21,7 +21,7 @@ internal static class _XceedVersionInfo { [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] - public const string BaseVersion = "3.6"; + public const string BaseVersion = "3.7"; [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] public const string Version = BaseVersion + ".0.0"; diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/Theme.xaml b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/Theme.xaml index c149c6e8..78dd2189 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/Theme.xaml +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.VS2010/Theme.xaml @@ -37,6 +37,10 @@ + + + + diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/AssemblyVersionInfo.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/AssemblyVersionInfo.cs index 6a1d0bb3..2d6c85ea 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/AssemblyVersionInfo.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/AssemblyVersionInfo.cs @@ -21,7 +21,7 @@ internal static class _XceedVersionInfo { [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] - public const string BaseVersion = "3.6"; + public const string BaseVersion = "3.7"; [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] public const string Version = BaseVersion + ".0.0"; diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DropTarget.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DropTarget.cs index 3d70f6e7..37643dab 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DropTarget.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DropTarget.cs @@ -110,12 +110,15 @@ namespace Xceed.Wpf.AvalonDock.Controls this.Drop( fwAsDocument ); } - Dispatcher.BeginInvoke( new Action( () => + if( currentActiveContent != null ) + { + Dispatcher.BeginInvoke( new Action( () => { currentActiveContent.IsSelected = false; currentActiveContent.IsActive = false; currentActiveContent.IsActive = true; } ), DispatcherPriority.Background ); + } } public virtual bool HitTest( Point dragPoint ) diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorablePaneGroupControl.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorablePaneGroupControl.cs index 04bceb4c..5de49b43 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorablePaneGroupControl.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorablePaneGroupControl.cs @@ -42,28 +42,28 @@ namespace Xceed.Wpf.AvalonDock.Controls protected override void OnFixChildrenDockLengths() { - //if( _model.Orientation == Orientation.Horizontal ) - //{ - // for( int i = 0; i < _model.Children.Count; i++ ) - // { - // var childModel = _model.Children[ i ] as ILayoutPositionableElement; - // if( !childModel.DockWidth.IsStar ) - // { - // childModel.DockWidth = new GridLength( 1.0, GridUnitType.Star ); - // } - // } - //} - //else - //{ - // for( int i = 0; i < _model.Children.Count; i++ ) - // { - // var childModel = _model.Children[ i ] as ILayoutPositionableElement; - // if( !childModel.DockHeight.IsStar ) - // { - // childModel.DockHeight = new GridLength( 1.0, GridUnitType.Star ); - // } - // } - //} + if( _model.Orientation == Orientation.Horizontal ) + { + for( int i = 0; i < _model.Children.Count; i++ ) + { + var childModel = _model.Children[ i ] as ILayoutPositionableElement; + if( !childModel.DockWidth.IsStar ) + { + childModel.DockWidth = new GridLength( 1.0, GridUnitType.Star ); + } + } + } + else + { + for( int i = 0; i < _model.Children.Count; i++ ) + { + var childModel = _model.Children[ i ] as ILayoutPositionableElement; + if( !childModel.DockHeight.IsStar ) + { + childModel.DockHeight = new GridLength( 1.0, GridUnitType.Star ); + } + } + } } #endregion diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentControl.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentControl.cs index 214aa148..50f23e8a 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentControl.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentControl.cs @@ -19,6 +19,8 @@ using System.Windows; using System.Windows.Controls; using System.Windows.Input; using Xceed.Wpf.AvalonDock.Layout; +using System.Collections; +using System; namespace Xceed.Wpf.AvalonDock.Controls { @@ -166,6 +168,34 @@ namespace Xceed.Wpf.AvalonDock.Controls } + #endregion + + #region Internal Methods + + internal void SetResourcesFromObject( FrameworkElement current ) + { + while( current != null ) + { + if( current.Resources.Count > 0 ) + { + var entries = new DictionaryEntry[ current.Resources.Count ]; + current.Resources.CopyTo( entries, 0 ); + entries.ForEach( x => + { + try + { + if( this.Resources[ x.Key ] == null ) + { + this.Resources.Add( x.Key, x.Value ); + } + } + catch( Exception ) { } + } ); + } + current = current.Parent as FrameworkElement; + } + } + #endregion #region Private Methods diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentPaneControl.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentPaneControl.cs index 43d96cee..f5508676 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentPaneControl.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentPaneControl.cs @@ -55,6 +55,34 @@ namespace Xceed.Wpf.AvalonDock.Controls #region Properties + + + + + + + + + + + + + + + + + + + + + + + + + + + #region Model + public ILayoutElement Model { get @@ -65,6 +93,8 @@ namespace Xceed.Wpf.AvalonDock.Controls #endregion + #endregion + #region Overrides protected override System.Collections.IEnumerator LogicalChildren @@ -113,5 +143,29 @@ namespace Xceed.Wpf.AvalonDock.Controls } #endregion + + + + + + + + + + + + + + + + + + + + + + + + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentPaneGroupControl.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentPaneGroupControl.cs index b3188045..6b12e453 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentPaneGroupControl.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentPaneGroupControl.cs @@ -42,29 +42,29 @@ namespace Xceed.Wpf.AvalonDock.Controls protected override void OnFixChildrenDockLengths() { - //if( _model.Orientation == Orientation.Horizontal ) - //{ - // for( int i = 0; i < _model.Children.Count; i++ ) - // { - // var childModel = _model.Children[ i ] as ILayoutPositionableElement; - // if( !childModel.DockWidth.IsStar ) - // { - // childModel.DockWidth = new GridLength( 1.0, GridUnitType.Star ); - // } - // } - //} - //else - //{ - // for( int i = 0; i < _model.Children.Count; i++ ) - // { - // var childModel = _model.Children[ i ] as ILayoutPositionableElement; - // if( !childModel.DockHeight.IsStar ) - // { - // childModel.DockHeight = new GridLength( 1.0, GridUnitType.Star ); - // } - // } - //} - // #endregion + if( _model.Orientation == Orientation.Horizontal ) + { + for( int i = 0; i < _model.Children.Count; i++ ) + { + var childModel = _model.Children[ i ] as ILayoutPositionableElement; + if( !childModel.DockWidth.IsStar ) + { + childModel.DockWidth = new GridLength( 1.0, GridUnitType.Star ); + } + } + } + else + { + for( int i = 0; i < _model.Children.Count; i++ ) + { + var childModel = _model.Children[ i ] as ILayoutPositionableElement; + if( !childModel.DockHeight.IsStar ) + { + childModel.DockHeight = new GridLength( 1.0, GridUnitType.Star ); + } + } + } + // #endregion } #endregion diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/DockingManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/DockingManager.cs index 07dc08fc..0fde8f4b 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/DockingManager.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/DockingManager.cs @@ -36,7 +36,7 @@ namespace Xceed.Wpf.AvalonDock { [ContentProperty( "Layout" )] [TemplatePart( Name = "PART_AutoHideArea" )] - public class DockingManager : Control, IOverlayWindowHost//, ILogicalChildrenContainer + public class DockingManager : Control, IOverlayWindowHost, IWeakEventListener//, ILogicalChildrenContainer { #region Members @@ -83,6 +83,12 @@ namespace Xceed.Wpf.AvalonDock #region Properties + + + + + + #region Layout /// @@ -2079,13 +2085,14 @@ namespace Xceed.Wpf.AvalonDock Dispatcher.BeginInvoke( new Action( () => { newFW.Show(); + + // Do not set the WindowState before showing or it will be lost + if( paneForExtensions != null && paneForExtensions.IsMaximized ) + { + newFW.WindowState = WindowState.Maximized; + } } ), DispatcherPriority.Send ); - // Do not set the WindowState before showing or it will be lost - if( paneForExtensions != null && paneForExtensions.IsMaximized ) - { - newFW.WindowState = WindowState.Maximized; - } return newFW; } @@ -2125,6 +2132,9 @@ namespace Xceed.Wpf.AvalonDock if( model is LayoutDocument ) { var templateModelView = new LayoutDocumentControl() { Model = model as LayoutDocument }; + + templateModelView.SetResourcesFromObject( this ); + return templateModelView; } @@ -2333,7 +2343,11 @@ namespace Xceed.Wpf.AvalonDock if( !_insideInternalSetActiveContent ) { +#if VS2008 this.ActiveContent = ( Layout.ActiveContent != null ) ? Layout.ActiveContent.Content : null; +#else + this.SetCurrentValue( DockingManager.ActiveContentProperty, ( Layout.ActiveContent != null ) ? Layout.ActiveContent.Content : null ); +#endif } } } @@ -2513,7 +2527,9 @@ namespace Xceed.Wpf.AvalonDock var documentsSourceAsNotifier = documentsSource as INotifyCollectionChanged; if( documentsSourceAsNotifier != null ) - documentsSourceAsNotifier.CollectionChanged += new NotifyCollectionChangedEventHandler( documentsSourceElementsChanged ); + { + CollectionChangedEventManager.AddListener( documentsSourceAsNotifier, this ); + } } private void documentsSourceElementsChanged( object sender, NotifyCollectionChangedEventArgs e ) @@ -2534,6 +2550,7 @@ namespace Xceed.Wpf.AvalonDock var documentsToRemove = Layout.Descendents().OfType().Where( d => e.OldItems.Contains( d.Content ) ).ToArray(); foreach( var documentToRemove in documentsToRemove ) { + //documentToRemove.Content = null; ( documentToRemove.Parent as ILayoutContainer ).RemoveChild( documentToRemove ); this.RemoveViewFromLogicalChild( documentToRemove ); @@ -2642,7 +2659,9 @@ namespace Xceed.Wpf.AvalonDock var documentsSourceAsNotifier = documentsSource as INotifyCollectionChanged; if( documentsSourceAsNotifier != null ) - documentsSourceAsNotifier.CollectionChanged -= new NotifyCollectionChangedEventHandler( documentsSourceElementsChanged ); + { + CollectionChangedEventManager.RemoveListener( documentsSourceAsNotifier, this ); + } } private void Close( LayoutContent contentToClose ) @@ -2749,7 +2768,9 @@ namespace Xceed.Wpf.AvalonDock var anchorablesSourceAsNotifier = anchorablesSource as INotifyCollectionChanged; if( anchorablesSourceAsNotifier != null ) - anchorablesSourceAsNotifier.CollectionChanged += new NotifyCollectionChangedEventHandler( anchorablesSourceElementsChanged ); + { + CollectionChangedEventManager.AddListener( anchorablesSourceAsNotifier, this ); + } } private void anchorablesSourceElementsChanged( object sender, NotifyCollectionChangedEventArgs e ) @@ -2892,7 +2913,9 @@ namespace Xceed.Wpf.AvalonDock var anchorablesSourceAsNotifier = anchorablesSource as INotifyCollectionChanged; if( anchorablesSourceAsNotifier != null ) - anchorablesSourceAsNotifier.CollectionChanged -= new NotifyCollectionChangedEventHandler( anchorablesSourceElementsChanged ); + { + CollectionChangedEventManager.RemoveListener( anchorablesSourceAsNotifier, this ); + } } private void RemoveViewFromLogicalChild( LayoutContent layoutContent ) @@ -3271,7 +3294,7 @@ namespace Xceed.Wpf.AvalonDock return fwc; } - #endregion +#endregion #region Events @@ -3380,5 +3403,36 @@ namespace Xceed.Wpf.AvalonDock } #endregion + + #region IWeakEventListener + + bool IWeakEventListener.ReceiveWeakEvent( Type managerType, object sender, EventArgs e ) + { + return this.OnReceiveWeakEvent( managerType, sender, e ); + } + + protected virtual bool OnReceiveWeakEvent( Type managerType, object sender, EventArgs e ) + { + if( typeof( CollectionChangedEventManager ) == managerType ) + { + var args = (NotifyCollectionChangedEventArgs)e; + if( sender == this.DocumentsSource ) + { + this.documentsSourceElementsChanged( sender, args ); + } + else if( sender == this.AnchorablesSource ) + { + this.anchorablesSourceElementsChanged( sender, args ); + } + } + else + { + return false; + } + + return true; + } + + #endregion } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutAnchorablePaneGroup.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutAnchorablePaneGroup.cs index 9d2a085a..a9fb6418 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutAnchorablePaneGroup.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutAnchorablePaneGroup.cs @@ -92,14 +92,14 @@ namespace Xceed.Wpf.AvalonDock.Layout base.OnDockHeightChanged(); } - protected override void OnChildrenCollectionChanged() - { - if( DockWidth.IsAbsolute && ChildrenCount == 1 ) - ( ( ILayoutPositionableElement )Children[ 0 ] ).DockWidth = DockWidth; - if( DockHeight.IsAbsolute && ChildrenCount == 1 ) - ( ( ILayoutPositionableElement )Children[ 0 ] ).DockHeight = DockHeight; - base.OnChildrenCollectionChanged(); - } + //protected override void OnChildrenCollectionChanged() + //{ + //if( DockWidth.IsAbsolute && ChildrenCount == 1 ) + // ( (ILayoutPositionableElement)Children[ 0 ] ).DockWidth = DockWidth; + //if( DockHeight.IsAbsolute && ChildrenCount == 1 ) + // ( ( ILayoutPositionableElement )Children[ 0 ] ).DockHeight = DockHeight; + //base.OnChildrenCollectionChanged(); + //} public override void WriteXml( System.Xml.XmlWriter writer ) { diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/generic.xaml b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/generic.xaml index 6f284ed1..cb7e4e4f 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/generic.xaml +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/generic.xaml @@ -32,6 +32,10 @@ + + + + diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/obj/Debug/GeneratedInternalTypeHelper.g.i.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/obj/Debug/GeneratedInternalTypeHelper.g.i.cs deleted file mode 100644 index 8f77761a..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/obj/Debug/GeneratedInternalTypeHelper.g.i.cs +++ /dev/null @@ -1,62 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace XamlGeneratedNamespace { - - - /// - /// GeneratedInternalTypeHelper - /// - [System.Diagnostics.DebuggerNonUserCodeAttribute()] - [System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")] - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public sealed class GeneratedInternalTypeHelper : System.Windows.Markup.InternalTypeHelper { - - /// - /// CreateInstance - /// - protected override object CreateInstance(System.Type type, System.Globalization.CultureInfo culture) { - return System.Activator.CreateInstance(type, ((System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic) - | (System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.CreateInstance)), null, null, culture); - } - - /// - /// GetPropertyValue - /// - protected override object GetPropertyValue(System.Reflection.PropertyInfo propertyInfo, object target, System.Globalization.CultureInfo culture) { - return propertyInfo.GetValue(target, System.Reflection.BindingFlags.Default, null, null, culture); - } - - /// - /// SetPropertyValue - /// - protected override void SetPropertyValue(System.Reflection.PropertyInfo propertyInfo, object target, object value, System.Globalization.CultureInfo culture) { - propertyInfo.SetValue(target, value, System.Reflection.BindingFlags.Default, null, null, culture); - } - - /// - /// CreateDelegate - /// - protected override System.Delegate CreateDelegate(System.Type delegateType, object target, string handler) { - return ((System.Delegate)(target.GetType().InvokeMember("_CreateDelegate", (System.Reflection.BindingFlags.InvokeMethod - | (System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)), null, target, new object[] { - delegateType, - handler}, null))); - } - - /// - /// AddEventHandler - /// - protected override void AddEventHandler(System.Reflection.EventInfo eventInfo, object target, System.Delegate handler) { - eventInfo.AddEventHandler(target, handler); - } - } -} - diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/obj/Debug/Xceed.Wpf.AvalonDock_MarkupCompile.i.lref b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/obj/Debug/Xceed.Wpf.AvalonDock_MarkupCompile.i.lref deleted file mode 100644 index 8fd57ed5..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/obj/Debug/Xceed.Wpf.AvalonDock_MarkupCompile.i.lref +++ /dev/null @@ -1,4 +0,0 @@ -D:\Dev\ExtendedWPFToolkit\Release\3.6.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock\obj\Debug\GeneratedInternalTypeHelper.g.i.cs - -FD:\Dev\ExtendedWPFToolkit\Release\3.6.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock\Themes\generic.xaml;; - diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit.LiveExplorer/CodeFiles/ColorView.xaml.txt b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit.LiveExplorer/CodeFiles/ColorView.xaml.txt index 347a8ccb..4c0104ec 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit.LiveExplorer/CodeFiles/ColorView.xaml.txt +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit.LiveExplorer/CodeFiles/ColorView.xaml.txt @@ -29,7 +29,9 @@ diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/CheckComboBox/Themes/Generic.xaml b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/CheckComboBox/Themes/Generic.xaml index b1bcf0ac..0bc40af7 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/CheckComboBox/Themes/Generic.xaml +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/CheckComboBox/Themes/Generic.xaml @@ -64,6 +64,7 @@ IsReadOnly="True" Focusable="False" Cursor="Arrow" + IsTabStop="{TemplateBinding IsTabStop}" BorderThickness="0" Background="Transparent" Margin="{TemplateBinding Padding}" @@ -109,7 +110,20 @@ + + + + + + + + @@ -203,6 +217,13 @@ + + + + + diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/ColorPicker/Themes/Generic.xaml b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/ColorPicker/Themes/Generic.xaml index 7b88bdc7..a1bdcebe 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/ColorPicker/Themes/Generic.xaml +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/ColorPicker/Themes/Generic.xaml @@ -330,8 +330,17 @@ Value="250" /> - + + + + + + + + diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/DateTimeUpDown/Implementation/DateTimeParser.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/DateTimeUpDown/Implementation/DateTimeParser.cs index 6566a8ad..d38278ec 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/DateTimeUpDown/Implementation/DateTimeParser.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/DateTimeUpDown/Implementation/DateTimeParser.cs @@ -139,7 +139,13 @@ namespace Xceed.Wpf.Toolkit dateParts[ "Year" ] = dateTimeParts[ i ] != "0" ? dateTimeParts[ i ] : "0000"; if( dateParts[ "Year" ].Length == 2 ) - dateParts[ "Year" ] = string.Format( "{0}{1}", currentDate.Year / 100, dateParts[ "Year" ] ); + { + var yearDigits = int.Parse( dateParts[ "Year" ] ); + var twoDigitYearMax = cultureInfo.Calendar.TwoDigitYearMax; + var hundredDigits = ( yearDigits <= twoDigitYearMax % 100 ) ? twoDigitYearMax / 100 : ( twoDigitYearMax / 100 ) - 1; + + dateParts[ "Year" ] = string.Format( "{0}{1}", hundredDigits, dateParts[ "Year" ] ); + } } else if( f.Contains( "hh" ) || f.Contains( "HH" ) ) { diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/MaskedTextBox/Implementation/MaskedTextBox.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/MaskedTextBox/Implementation/MaskedTextBox.cs index e24c252e..22e83bce 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/MaskedTextBox/Implementation/MaskedTextBox.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/MaskedTextBox/Implementation/MaskedTextBox.cs @@ -1907,11 +1907,6 @@ namespace Xceed.Wpf.Toolkit private string GetFormattedString( MaskedTextProvider provider, string text ) { - if( provider.Mask.StartsWith( ">" ) ) - return text.ToUpper(); - if( provider.Mask.StartsWith( "<" ) ) - return text.ToLower(); - //System.Diagnostics.Debug.Assert( provider.EditPositionCount > 0 ); @@ -1919,6 +1914,11 @@ namespace Xceed.Wpf.Toolkit string displayString = provider.ToString( false, includePrompt, true, 0, m_maskedTextProvider.Length ); + if( provider.Mask.StartsWith( ">" ) ) + return displayString.ToUpper(); + if( provider.Mask.StartsWith( "<" ) ) + return displayString.ToLower(); + return displayString; } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/NumericUpDown/Implementation/ByteUpDown.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/NumericUpDown/Implementation/ByteUpDown.cs index 27e9a2b3..f56fe6e3 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/NumericUpDown/Implementation/ByteUpDown.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/NumericUpDown/Implementation/ByteUpDown.cs @@ -26,6 +26,7 @@ namespace Xceed.Wpf.Toolkit static ByteUpDown() { UpdateMetadata( typeof( ByteUpDown ), ( byte )1, byte.MinValue, byte.MaxValue ); + MaxLengthProperty.OverrideMetadata( typeof(ByteUpDown), new FrameworkPropertyMetadata( 3 ) ); } public ByteUpDown() diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/Primitives/DateTimeUpDownBase.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/Primitives/DateTimeUpDownBase.cs index a1f37021..53202ed2 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/Primitives/DateTimeUpDownBase.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/Primitives/DateTimeUpDownBase.cs @@ -220,7 +220,7 @@ namespace Xceed.Wpf.Toolkit.Primitives protected virtual void PerformMouseSelection() { var dateTimeInfo = this.GetDateTimeInfo( TextBox.SelectionStart ); - if( (this.TextBox is MaskedTextBox) && ( dateTimeInfo != null) && (dateTimeInfo.Type == DateTimePart.Other) ) + if( ( dateTimeInfo != null) && (dateTimeInfo.Type == DateTimePart.Other) ) { this.Dispatcher.BeginInvoke( DispatcherPriority.Background, new Action( () => { @@ -255,7 +255,7 @@ namespace Xceed.Wpf.Toolkit.Primitives return _dateTimeInfoList.FirstOrDefault( ( info ) =>info.Type == part ); } - internal void Select( DateTimeInfo info ) + internal virtual void Select( DateTimeInfo info ) { if( (info != null) && !info.Equals( _selectedDateTimeInfo ) && ( this.TextBox != null) && !string.IsNullOrEmpty( this.TextBox.Text ) ) { diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/Primitives/Themes/Aero2/SelectorItem.xaml b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/Primitives/Themes/Aero2/SelectorItem.xaml index e10363a7..94fa915e 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/Primitives/Themes/Aero2/SelectorItem.xaml +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/Primitives/Themes/Aero2/SelectorItem.xaml @@ -19,48 +19,69 @@ xmlns:themes="clr-namespace:Xceed.Wpf.Toolkit.Themes" xmlns:primitives="clr-namespace:Xceed.Wpf.Toolkit.Primitives"> - - - + + + - + diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/Primitives/Themes/Generic/SelectorItem.xaml b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/Primitives/Themes/Generic/SelectorItem.xaml index 6d0687f1..80b91cd1 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/Primitives/Themes/Generic/SelectorItem.xaml +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/Primitives/Themes/Generic/SelectorItem.xaml @@ -16,56 +16,69 @@ + xmlns:primitives="clr-namespace:Xceed.Wpf.Toolkit.Primitives"> - - - + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/ObjectContainerHelperBase.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/ObjectContainerHelperBase.cs index c4e5efe4..5af13295 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/ObjectContainerHelperBase.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/ObjectContainerHelperBase.cs @@ -247,7 +247,7 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid this.GenerateSubPropertiesCore( this.UpdatePropertyItemsCallback ); } - private void UpdatePropertyItemsCallback( IEnumerable subProperties ) + protected internal virtual void UpdatePropertyItemsCallback( IEnumerable subProperties ) { foreach( var propertyItem in subProperties ) { @@ -274,6 +274,11 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid { propertyGrid.SelectedPropertyItem = this.DefaultProperty; } + + if( ObjectsGenerated != null ) + { + ObjectsGenerated( this, EventArgs.Empty ); + } } protected static List GetPropertyDescriptors( object instance, bool hideInheritedProperties ) @@ -468,7 +473,7 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid if( editorElement == null ) { - if( pd.IsReadOnly ) + if( propertyItem.IsReadOnly ) editor = new TextBlockEditor(); // Fallback: Use a default type editor. @@ -555,5 +560,6 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid || string.Equals( propertyName, PropertyItemCollection.PropertyOrderPropertyName ); } + internal event EventHandler ObjectsGenerated; } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/PropertyGrid.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/PropertyGrid.cs index f9485ccc..9e9710cc 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/PropertyGrid.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/PropertyGrid.cs @@ -521,7 +521,7 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid #region IsReadOnly - public static readonly DependencyProperty IsReadOnlyProperty = DependencyProperty.Register( "IsReadOnly", typeof( bool ), typeof( PropertyGrid ), new UIPropertyMetadata( false ) ); + public static readonly DependencyProperty IsReadOnlyProperty = DependencyProperty.Register( "IsReadOnly", typeof( bool ), typeof( PropertyGrid ), new UIPropertyMetadata( false, OnIsReadOnlyChanged ) ); public bool IsReadOnly { get @@ -534,6 +534,18 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid } } + private static void OnIsReadOnlyChanged( DependencyObject o, DependencyPropertyChangedEventArgs e ) + { + var propertyGrid = o as PropertyGrid; + if( propertyGrid != null ) + propertyGrid.OnIsReadOnlyChanged( (bool)e.OldValue, (bool)e.NewValue ); + } + + protected virtual void OnIsReadOnlyChanged( bool oldValue, bool newValue ) + { + this.UpdateContainerHelper(); + } + #endregion //ReadOnly #region SelectedObject @@ -1025,7 +1037,7 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid if( ( parentPropertyItem != null ) && parentPropertyItem.IsExpandable ) { //Rebuild Editor for parent propertyItem if one of its sub-propertyItem have changed. - this.RebuildEditor( parentPropertyItem ); + this.RebuildPropertyItemEditor( parentPropertyItem ); } } } @@ -1138,24 +1150,11 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid return null; } - private void RebuildEditor( PropertyItem propertyItem ) + private void RebuildPropertyItemEditor( PropertyItem propertyItem ) { - ObjectContainerHelperBase objectContainerHelperBase = propertyItem.ContainerHelper as ObjectContainerHelperBase; - //Re-build the editor to update this propertyItem - FrameworkElement editor = objectContainerHelperBase.GenerateChildrenEditorElement( propertyItem ); - if( editor != null ) + if( propertyItem != null ) { - // Tag the editor as generated to know if we should clear it. - ContainerHelperBase.SetIsGenerated( editor, true ); - propertyItem.Editor = editor; - - //Update Source of binding and Validation of PropertyItem to update - var be = propertyItem.GetBindingExpression( PropertyItem.ValueProperty ); - if( be != null ) - { - be.UpdateSource(); - propertyItem.SetRedInvalidBorder( be ); - } + propertyItem.RebuildEditor(); } } @@ -1182,11 +1181,16 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid } } + ObjectContainerHelperBase objectContainerHelper = null; - _containerHelper = new ObjectContainerHelper( this, SelectedObject ); - ( ( ObjectContainerHelper )_containerHelper ).GenerateProperties(); + objectContainerHelper = new ObjectContainerHelper( this, SelectedObject ); + objectContainerHelper.ObjectsGenerated += this.ObjectContainerHelper_ObjectsGenerated; + objectContainerHelper.GenerateProperties(); + } + private void FinalizeUpdateContainerHelper( ItemsControl childrenItemsControl ) + { if( _containerHelper != null ) { @@ -1254,6 +1258,21 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid #endregion //Methods + #region Event Handlers + + private void ObjectContainerHelper_ObjectsGenerated( object sender, EventArgs e ) + { + var objectContainerHelper = sender as ObjectContainerHelperBase; + if( objectContainerHelper != null ) + { + objectContainerHelper.ObjectsGenerated -= this.ObjectContainerHelper_ObjectsGenerated; + _containerHelper = objectContainerHelper; + this.FinalizeUpdateContainerHelper( objectContainerHelper.ChildrenItemsControl ); + } + } + + #endregion + #region Events #region PropertyChanged Event @@ -1319,8 +1338,6 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid - - #region PreparePropertyItemEvent Attached Routed Event /// diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/PropertyItem.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/PropertyItem.cs index 56be5a23..367f702b 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/PropertyItem.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/PropertyItem.cs @@ -43,7 +43,7 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid /// Identifies the IsReadOnly dependency property /// public static readonly DependencyProperty IsReadOnlyProperty = - DependencyProperty.Register( "IsReadOnly", typeof( bool ), typeof( PropertyItem ), new UIPropertyMetadata( false ) ); + DependencyProperty.Register( "IsReadOnly", typeof( bool ), typeof( PropertyItem ), new UIPropertyMetadata( false, OnIsReadOnlyChanged ) ); public bool IsReadOnly { @@ -51,6 +51,19 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid set { SetValue( IsReadOnlyProperty, value ); } } + private static void OnIsReadOnlyChanged( DependencyObject o, DependencyPropertyChangedEventArgs e ) + { + var propertyItem = o as PropertyItem; + if( propertyItem != null ) + propertyItem.OnIsReadOnlyChanged( (bool)e.OldValue, (bool)e.NewValue ); + } + + protected virtual void OnIsReadOnlyChanged( bool oldValue, bool newValue ) + { + this.RebuildEditor(); + } + + #endregion //IsReadOnly #region IsInValid @@ -218,6 +231,27 @@ namespace Xceed.Wpf.Toolkit.PropertyGrid } } + internal void RebuildEditor() + { + var objectContainerHelperBase = this.ContainerHelper as ObjectContainerHelperBase; + //Re-build the editor to update this propertyItem + var editor = objectContainerHelperBase.GenerateChildrenEditorElement( this ); + if( editor != null ) + { + // Tag the editor as generated to know if we should clear it. + ContainerHelperBase.SetIsGenerated( editor, true ); + this.Editor = editor; + + //Update Source of binding and Validation of PropertyItem to update + var be = this.GetBindingExpression( PropertyItem.ValueProperty ); + if( be != null ) + { + be.UpdateSource(); + this.SetRedInvalidBorder( be ); + } + } + } + #endregion #region Private Methods diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/TimeSpanUpDown/Implementation/TimeSpanUpDown.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/TimeSpanUpDown/Implementation/TimeSpanUpDown.cs index 7bfe5d99..5f0415d0 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/TimeSpanUpDown/Implementation/TimeSpanUpDown.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/TimeSpanUpDown/Implementation/TimeSpanUpDown.cs @@ -26,6 +26,21 @@ namespace Xceed.Wpf.Toolkit { public class TimeSpanUpDown : DateTimeUpDownBase { + #region Private Members + + private static int HoursInDay = 24; + private static int MinutesInDay = 1440; + private static int MinutesInHour = 60; + private static int SecondsInDay = 86400; + private static int SecondsInHour = 3600; + private static int SecondsInMinute = 60; + private static int MilliSecondsInDay = TimeSpanUpDown.SecondsInDay * 1000; + private static int MilliSecondsInHour = TimeSpanUpDown.SecondsInHour * 1000; + private static int MilliSecondsInMinute = TimeSpanUpDown.SecondsInMinute * 1000; + private static int MilliSecondsInSecond = 1000; + + #endregion + #region Constructors static TimeSpanUpDown() @@ -148,6 +163,26 @@ namespace Xceed.Wpf.Toolkit #region BaseClass Overrides + public override bool CommitInput() + { + var sync = this.SyncTextAndValueProperties( true, Text ); + + if( this.UpdateValueOnEnterKey && ( _selectedDateTimeInfo != null ) && ( _dateTimeInfoList != null ) ) + { + // Update SelectedDateTimeInfo and TextBox selection after sync is done. + var selectionInfo = _dateTimeInfoList.FirstOrDefault( x => ( x.Type == _selectedDateTimeInfo.Type ) && ( x.Type != DateTimePart.Other ) ); + _selectedDateTimeInfo = ( selectionInfo != null ) ? selectionInfo : _dateTimeInfoList.FirstOrDefault( x => x.Type != DateTimePart.Other ); + if( _selectedDateTimeInfo != null ) + { + _fireSelectionChangedEvent = false; + this.TextBox.Select( _selectedDateTimeInfo.StartPosition, _selectedDateTimeInfo.Length ); + _fireSelectionChangedEvent = true; + } + } + + return sync; + } + protected override void OnCultureInfoChanged( CultureInfo oldValue, CultureInfo newValue ) { var value = this.UpdateValueOnEnterKey @@ -197,27 +232,71 @@ namespace Xceed.Wpf.Toolkit return null; var timeSpan = TimeSpan.MinValue; - if( this.ShowDays ) + + var separators = text.Where( x => x == ':' || x == '.' ).ToList(); + var stringValues = text.Split( new char[] { ':', '.' } ); + if( ( stringValues.Count() <= 1 ) || stringValues.Any( x => string.IsNullOrEmpty( x ) ) ) { - timeSpan = TimeSpan.Parse( text ); + return this.ResetToLastValidValue(); } - else + + var intValues = new int[ stringValues.Count() ]; + for( int i = 0; i < stringValues.Count(); ++i ) { - var separators = text.Where( x => x == ':' || x == '.' ).ToList(); - var values = text.Split( new char[] { ':', '.' } ); - if( ( values.Count() >= 2 ) && !values.Any( x => string.IsNullOrEmpty( x ) ) ) + if( !int.TryParse( stringValues[ i ].Replace( "-", "" ), out intValues[ i ] ) ) { - bool haveMS = ( separators.Count() > 1 ) && ( separators.Last() == '.' ); - - timeSpan = new TimeSpan( 0, //Days - int.Parse( values[ 0 ].Replace("-", "") ), //Hours - int.Parse( values[ 1 ].Replace( "-", "" ) ), //Minutes - this.ShowSeconds ? int.Parse( values[ 2 ].Replace( "-", "" ) ) : 0, //Seconds - haveMS ? int.Parse( values.Last().Replace( "-", "" ) ) : 0 ); //Milliseconds - if( text.StartsWith( "-" ) ) - { - timeSpan = timeSpan.Negate(); - } + return this.ResetToLastValidValue(); + } + } + + if( intValues.Count() >= 2 ) + { + var haveMS = ( separators.Count() > 1 ) && ( separators.Last() == '.' ); + var haveDays = ( separators.Count() > 1 ) && ( separators.First() == '.' ) && ( intValues.Count() >= 3 ); + + if( this.ShowDays ) + { + var days = haveDays ? intValues[ 0 ] : intValues[ 0 ] / 24; + if( days > TimeSpan.MaxValue.Days ) + return this.ResetToLastValidValue(); + var hours = haveDays ? intValues[ 1 ] : intValues[ 0 ] % 24; + if( ( ( days * TimeSpanUpDown.HoursInDay ) + hours ) > TimeSpan.MaxValue.TotalHours ) + return this.ResetToLastValidValue(); + var minutes = haveDays ? intValues[ 2 ] : intValues[ 1 ]; + if( ( ( days * TimeSpanUpDown.MinutesInDay ) + ( hours * TimeSpanUpDown.MinutesInHour ) + minutes ) > TimeSpan.MaxValue.TotalMinutes ) + return this.ResetToLastValidValue(); + var seconds = this.ShowSeconds + ? haveDays && ( intValues.Count() >= 4 ) ? intValues[ 3 ] : ( intValues.Count() >= 3 ) ? intValues[ 2 ] : 0 + : 0; + if( ( ( days * TimeSpanUpDown.SecondsInDay ) + ( hours * TimeSpanUpDown.SecondsInHour ) + ( minutes * TimeSpanUpDown.SecondsInMinute ) + seconds ) > TimeSpan.MaxValue.TotalSeconds ) + return this.ResetToLastValidValue(); + var milliseconds = haveMS ? intValues.Last() : 0; + if( ( ( days * TimeSpanUpDown.MilliSecondsInDay ) + ( hours * TimeSpanUpDown.MilliSecondsInHour ) + ( minutes * TimeSpanUpDown.MilliSecondsInMinute ) + ( seconds * TimeSpanUpDown.MilliSecondsInSecond ) + milliseconds ) > TimeSpan.MaxValue.TotalMilliseconds ) + return this.ResetToLastValidValue(); + + timeSpan = new TimeSpan( days, hours, minutes, seconds, milliseconds ); + } + else + { + var hours = intValues[ 0 ]; + if( hours > TimeSpan.MaxValue.TotalHours ) + return this.ResetToLastValidValue(); + var minutes = intValues[ 1 ]; + if( ( ( hours * TimeSpanUpDown.MinutesInHour ) + minutes ) > TimeSpan.MaxValue.TotalMinutes ) + return this.ResetToLastValidValue(); + var seconds = this.ShowSeconds && ( intValues.Count() >= 3 ) ? intValues[ 2 ] : 0; + if( ( ( hours * TimeSpanUpDown.SecondsInHour ) + ( minutes * TimeSpanUpDown.SecondsInMinute ) + seconds ) > TimeSpan.MaxValue.TotalSeconds ) + return this.ResetToLastValidValue(); + var milliseconds = haveMS ? intValues.Last() : 0; + if( ( ( hours * TimeSpanUpDown.MilliSecondsInHour ) + ( minutes * TimeSpanUpDown.MilliSecondsInMinute ) + ( seconds * TimeSpanUpDown.MilliSecondsInSecond ) + milliseconds ) > TimeSpan.MaxValue.TotalMilliseconds ) + return this.ResetToLastValidValue(); + + timeSpan = new TimeSpan( 0, hours, minutes, seconds, milliseconds ); + } + + if( text.StartsWith( "-" ) ) + { + timeSpan = timeSpan.Negate(); } } @@ -264,28 +343,59 @@ namespace Xceed.Wpf.Toolkit TimeSpan result; // Validate when more than 60 seconds (or more than 60 minutes, or more than 24 hours) are entered. var separators = currentValue.Where( x => x == ':' || x == '.' ).ToList(); - var values = currentValue.Split( new char[] { ':', '.' } ); - if( ( values.Count() >= 2 ) && !values.Any( x => string.IsNullOrEmpty( x ) ) ) + var stringValues = currentValue.Split( new char[] { ':', '.' } ); + if( ( stringValues.Count() >= 2 ) && !stringValues.Any( x => string.IsNullOrEmpty( x ) ) ) { - bool haveDays = separators.First() == '.'; + bool haveDays = (separators.First() == '.') && ( stringValues.Count() >= 3); bool haveMS = ( separators.Count() > 1 ) && ( separators.Last() == '.' ); - result = new TimeSpan( haveDays ? int.Parse( values[ 0 ] ) : 0, //Days - haveDays ? int.Parse( values[ 1 ] ) : int.Parse( values[ 0 ] ), //Hours - haveDays ? int.Parse( values[ 2 ] ) : int.Parse( values[ 1 ] ), //Minutes - ( haveDays && this.ShowSeconds ) ? int.Parse( values[ 3 ] ) : this.ShowSeconds ? int.Parse( values[ 2 ] ) : 0, //Seconds - haveMS ? int.Parse( values.Last() ) : 0 ); //Milliseconds + var values = new int[ stringValues.Count() ]; + for( int i = 0; i < stringValues.Count(); ++i ) + { + if( !int.TryParse( stringValues[ i ], out values[ i ] ) ) + { + return; + } + } + + var days = haveDays ? Math.Abs( values[ 0 ] ): 0; + if( days > TimeSpan.MaxValue.Days ) + return; + var hours = haveDays ? Math.Abs( values[ 1 ] ) : Math.Abs( values[ 0 ] ); + if( ( ( days * TimeSpanUpDown.HoursInDay ) + hours) > TimeSpan.MaxValue.TotalHours ) + return; + var minutes = haveDays ? Math.Abs( values[ 2 ] ) : Math.Abs( values[ 1 ] ); + if( ( ( days * TimeSpanUpDown.MinutesInDay ) + ( hours * TimeSpanUpDown.MinutesInHour ) + minutes ) > TimeSpan.MaxValue.TotalMinutes ) + return; + var seconds = ( haveDays && this.ShowSeconds && ( values.Count() >= 4 ) ) ? Math.Abs( values[ 3 ] ) : this.ShowSeconds && ( values.Count() >= 3 ) ? Math.Abs( values[ 2 ] ) : 0; + if( ( ( days * TimeSpanUpDown.SecondsInDay ) + ( hours * TimeSpanUpDown.SecondsInHour ) + ( minutes * TimeSpanUpDown.SecondsInMinute ) + seconds ) > TimeSpan.MaxValue.TotalSeconds ) + return; + var milliseconds = haveMS ? Math.Abs( values.Last() ) : 0; + if( ( ( days * TimeSpanUpDown.MilliSecondsInDay ) + ( hours * TimeSpanUpDown.MilliSecondsInHour ) + (minutes * TimeSpanUpDown.MilliSecondsInMinute ) + (seconds * TimeSpanUpDown.MilliSecondsInSecond ) + milliseconds ) > TimeSpan.MaxValue.TotalMilliseconds ) + return; + + result = new TimeSpan( days, hours, minutes, seconds, milliseconds ); + if( values[ 0 ] < 0 ) + { + result = result.Negate(); + } currentValue = result.ToString(); } else { Debug.Assert( false, "Something went wrong when parsing TimeSpan." ); + return; } - // When text is typed, if UpdateValueOnEnterKey is true, - // Sync Value on Text only when Enter Key is pressed. - if( ( _isTextChangedFromUI && !this.UpdateValueOnEnterKey ) + var previousValues = ( previousValue != null ) ? previousValue.Split( new char[] { ':', '.' } ) : null; + var currentValues = ( currentValue != null ) ? currentValue.Split( new char[] { ':', '.' } ) : null; + var canSync = ( previousValues != null ) + && ( currentValues != null ) + && ( previousValues.Length == currentValues.Length ) // same number of time parts. + && ( currentValue.Length == previousValue.Length ); // same number of digits. + // When text is typed, Sync Value on Text only when UpdateValueOnEnterKey is false and time format is the same. + if( ( _isTextChangedFromUI && !this.UpdateValueOnEnterKey && canSync ) || !_isTextChangedFromUI ) { this.SyncTextAndValueProperties( true, currentValue ); @@ -308,10 +418,12 @@ namespace Xceed.Wpf.Toolkit protected override void PerformMouseSelection() { - var value = this.UpdateValueOnEnterKey - ? (this.TextBox != null) ? this.ConvertTextToValue( this.TextBox.Text ) : null - : this.Value; - this.InitializeDateTimeInfoList( value ); + if( !this.UpdateValueOnEnterKey ) + { + this.CommitInput(); + this.InitializeDateTimeInfoList( this.Value ); + } + base.PerformMouseSelection(); } @@ -414,6 +526,47 @@ namespace Xceed.Wpf.Toolkit return (value1.Value > value2.Value); } + internal override void Select( DateTimeInfo info ) + { + if( this.UpdateValueOnEnterKey ) + { + if( ( info != null ) && !info.Equals( _selectedDateTimeInfo ) && ( this.TextBox != null ) && !string.IsNullOrEmpty( this.TextBox.Text ) ) + { + var separatorToSkipCount = _dateTimeInfoList.IndexOf( info ) / 2; + if( separatorToSkipCount < 0 ) + { + base.Select( info ); + } + else + { + var textValues = this.Text.Split( new char[] { ':', '.' } ); + var selectionStart = textValues.Take( separatorToSkipCount ).Sum( x => x.Length ) + separatorToSkipCount; + var selectionLength = textValues[ separatorToSkipCount ].Length; + // Do not select the "-" sign when moving selection with arrows. + if( ( separatorToSkipCount == 0 ) && ( textValues.First().StartsWith( "-" ) ) ) + { + selectionStart += 1; + selectionLength -= 1; + } + + _fireSelectionChangedEvent = false; + this.TextBox.Select( selectionStart, selectionLength ); + _fireSelectionChangedEvent = true; + _selectedDateTimeInfo = info; +#if VS2008 + this.CurrentDateTimePart = info.Type; +#else + this.SetCurrentValue( DateTimeUpDownBase.CurrentDateTimePartProperty, info.Type ); +#endif + } + } + } + else + { + base.Select( info ); + } + } + #endregion @@ -566,18 +719,84 @@ namespace Xceed.Wpf.Toolkit // Sync Value on Text only when Enter Key is pressed. if( this.UpdateValueOnEnterKey ) { + var newTextBoxContent = string.Empty; var currentValue = this.ConvertTextToValue( this.TextBox.Text ); var newValue = currentValue.HasValue ? this.UpdateTimeSpan( currentValue, step ) : this.DefaultValue ?? TimeSpan.Zero; - if( newValue != null ) + if( newValue != null && ( _dateTimeInfoList != null) ) { - this.InitializeDateTimeInfoList( newValue ); - var selectionStart = this.TextBox.SelectionStart; - var selectionLength = this.TextBox.SelectionLength; + var selectionStart = 0; + var selectionLength = 0; - this.TextBox.Text = this.ParseValueIntoTimeSpanInfo( newValue, false ); + // Start with a negative sign. + if( ( newValue.Value.TotalMilliseconds < 0 ) && ( _dateTimeInfoList[ 0 ].Content != "-" ) ) + { + newTextBoxContent = "-"; + } + for( int i = 0; i < _dateTimeInfoList.Count; ++i ) + { + var timePart = _dateTimeInfoList[ i ]; + // Current timePart is the selected timePart, TextBox selection will start here. + if( ( _selectedDateTimeInfo != null ) && ( timePart.Type == _selectedDateTimeInfo.Type ) ) + { + selectionStart = newTextBoxContent.Length; + } + // Adjust time part start and length. + switch( timePart.Type ) + { + case DateTimePart.Day: + var dayText = Math.Abs( newValue.Value.Days ).ToString( new string( '0', timePart.Content.Length ) ); + timePart.StartPosition = newTextBoxContent.Length; + timePart.Length = dayText.Length; + newTextBoxContent += dayText; + break; + case DateTimePart.Hour24: + var hourText = ( i <= 1 ) + ? Math.Truncate( Math.Abs( newValue.Value.TotalHours ) ).ToString( new string( '0', timePart.Content.Length ) ) + : Math.Abs( newValue.Value.Hours) .ToString( new string( '0', timePart.Content.Length ) ); + timePart.StartPosition = newTextBoxContent.Length; + timePart.Length = hourText.Length; + newTextBoxContent += hourText; + break; + case DateTimePart.Minute: + var minuteText = ( i <= 1 ) + ? Math.Truncate( Math.Abs( newValue.Value.TotalMinutes ) ).ToString( new string( '0', timePart.Content.Length ) ) + : Math.Abs( newValue.Value.Minutes ).ToString( new string( '0', timePart.Content.Length ) ); + timePart.StartPosition = newTextBoxContent.Length; + timePart.Length = minuteText.Length; + newTextBoxContent += minuteText; + break; + case DateTimePart.Second: + var secondText = ( i <= 1 ) + ? Math.Truncate( Math.Abs( newValue.Value.TotalSeconds ) ).ToString( new string( '0', timePart.Content.Length ) ) + : Math.Abs( newValue.Value.Seconds ).ToString( new string( '0', timePart.Content.Length ) ); + timePart.StartPosition = newTextBoxContent.Length; + timePart.Length = secondText.Length; + newTextBoxContent += secondText; + break; + case DateTimePart.Millisecond: + var millisecondText = ( i <= 1 ) + ? Math.Truncate( Math.Abs( newValue.Value.TotalMilliseconds ) ).ToString( new string( '0', timePart.Content.Length ) ) + : Math.Abs( newValue.Value.Milliseconds ).ToString( new string( '0', timePart.Content.Length ) ); + timePart.StartPosition = newTextBoxContent.Length; + timePart.Length = millisecondText.Length; + newTextBoxContent += millisecondText; + break; + case DateTimePart.Other: + var otherText = ( ( i == 0 ) && ( newValue.Value.TotalMilliseconds >= 0 ) ) ? "" : timePart.Content; + timePart.StartPosition = newTextBoxContent.Length; + timePart.Length = otherText.Length; + newTextBoxContent += otherText; + break; + } + if( ( _selectedDateTimeInfo != null ) && ( timePart.Type == _selectedDateTimeInfo.Type ) ) + { + selectionLength = newTextBoxContent.Length - selectionStart; + } + } + this.TextBox.Text = newTextBoxContent; this.TextBox.Select( selectionStart, selectionLength ); } } @@ -622,6 +841,13 @@ namespace Xceed.Wpf.Toolkit this.SyncTextAndValueProperties( false, this.Text ); } + private TimeSpan? ResetToLastValidValue() + { + // Reset DateTimeInfoList with last valid value. + this.InitializeDateTimeInfoList( this.Value ); + return this.Value; + } + #endregion #region Event Handlers