diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/AeroColors.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/AeroColors.cs index ec5cb4b8..f3277f08 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/AeroColors.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/AeroColors.cs @@ -1,14 +1,15 @@ /************************************************************************************* + + Toolkit for WPF - Extended WPF Toolkit + Copyright (C) 2007-2020 Xceed Software Inc. - Copyright (C) 2007-2013 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 is provided to you under the terms of the XCEED SOFTWARE, INC. + COMMUNITY LICENSE AGREEMENT (for non-commercial use) as published at + https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/AeroTheme.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/AeroTheme.cs index 0d3b20a4..1ff53e6e 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/AeroTheme.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/AeroTheme.cs @@ -1,14 +1,15 @@ /************************************************************************************* + + Toolkit for WPF - Extended WPF Toolkit + Copyright (C) 2007-2020 Xceed Software Inc. - Copyright (C) 2007-2013 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 is provided to you under the terms of the XCEED SOFTWARE, INC. + COMMUNITY LICENSE AGREEMENT (for non-commercial use) as published at + https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids @@ -21,13 +22,16 @@ using System.Text; namespace Xceed.Wpf.AvalonDock.Themes { - public class AeroTheme : Theme + public class AeroTheme : Theme + { + public override Uri GetResourceUri() { - public override Uri GetResourceUri() - { - return new Uri( - "/Xceed.Wpf.AvalonDock.Themes.Aero;component/Theme.xaml", - UriKind.Relative); - } + string assemblyName = "Xceed.Wpf.AvalonDock.Themes.Aero"; + + + return new Uri( + "/" + assemblyName + ";component/Theme.xaml", + UriKind.Relative ); } + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/AssemblyVersionInfo.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/AssemblyVersionInfo.cs deleted file mode 100644 index 2c57bb8b..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/AssemblyVersionInfo.cs +++ /dev/null @@ -1,32 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -#pragma warning disable 0436 -[assembly: System.Reflection.AssemblyVersion( _XceedVersionInfo.Version )] -#pragma warning restore 0436 - -internal static class _XceedVersionInfo -{ - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] - public const string BaseVersion = "3.5"; - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] - public const string Version = BaseVersion + - ".0.0"; - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] - public const string PublicKeyToken = "ba83ff368b7563c6"; - - -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/AssemblyVersionInfoCommon.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/AssemblyVersionInfoCommon.cs deleted file mode 100644 index 3316fb13..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/AssemblyVersionInfoCommon.cs +++ /dev/null @@ -1,22 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -internal static class _XceedVersionInfoCommon -{ -[System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] - public const string Build = ".*"; - -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/Brushes.xaml b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/Brushes.xaml index 3606e3ee..f6924f56 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/Brushes.xaml +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock.Themes.Aero/Brushes.xaml @@ -1,14 +1,15 @@  @@ -328,6 +331,7 @@ IsItemsHost="true" Grid.Row="1" KeyboardNavigation.TabIndex="1" + KeyboardNavigation.DirectionalNavigation="Cycle" Panel.ZIndex="1" /> @@ -369,8 +373,7 @@ + Background="{TemplateBinding Background}"> - - - - - - - + + @@ -338,6 +341,7 @@ IsItemsHost="true" Grid.Row="1" KeyboardNavigation.TabIndex="1" + KeyboardNavigation.DirectionalNavigation="Cycle" Panel.ZIndex="1" /> @@ -378,8 +382,7 @@ BorderBrush="{TemplateBinding BorderBrush}" Margin="4" BorderThickness="0,2,0,0" - Background="{TemplateBinding Background}" - Padding="{TemplateBinding Padding}"> + Background="{TemplateBinding Background}"> - - - - - - - + + @@ -419,6 +424,7 @@ IsItemsHost="true" Grid.Row="1" KeyboardNavigation.TabIndex="1" + KeyboardNavigation.DirectionalNavigation="Cycle" Panel.ZIndex="1" /> @@ -459,8 +465,7 @@ BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1,0,1,1" CornerRadius="0,0,2,2" - Background="{TemplateBinding Background}" - Padding="{TemplateBinding Padding}"> + Background="{TemplateBinding Background}"> - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/DictionaryTheme.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/DictionaryTheme.cs index 6857768b..c02a357a 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/DictionaryTheme.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/DictionaryTheme.cs @@ -1,14 +1,15 @@ /************************************************************************************* + + Toolkit for WPF - Extended WPF Toolkit + Copyright (C) 2007-2020 Xceed Software Inc. - Copyright (C) 2007-2013 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 is provided to you under the terms of the XCEED SOFTWARE, INC. + COMMUNITY LICENSE AGREEMENT (for non-commercial use) as published at + https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/Generic/Images/PinAutoHide_White.png b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/Generic/Images/PinAutoHide_White.png new file mode 100644 index 00000000..2828964b Binary files /dev/null and b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/Generic/Images/PinAutoHide_White.png differ diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/Generic/Images/PinClose_White.png b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/Generic/Images/PinClose_White.png new file mode 100644 index 00000000..1b7b7cdf Binary files /dev/null and b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/Generic/Images/PinClose_White.png differ diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/Generic/Images/PinDocMenu_White.png b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/Generic/Images/PinDocMenu_White.png new file mode 100644 index 00000000..afd82d9d Binary files /dev/null and b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/Generic/Images/PinDocMenu_White.png differ diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/Generic/Images/PinMaximize_White.png b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/Generic/Images/PinMaximize_White.png new file mode 100644 index 00000000..6f745b4d Binary files /dev/null and b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/Generic/Images/PinMaximize_White.png differ diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/Generic/Images/PinMenu_White.png b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/Generic/Images/PinMenu_White.png new file mode 100644 index 00000000..520f3d2f Binary files /dev/null and b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/Generic/Images/PinMenu_White.png differ diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/Generic/Images/PinRestore_White.png b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/Generic/Images/PinRestore_White.png new file mode 100644 index 00000000..27171227 Binary files /dev/null and b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/Generic/Images/PinRestore_White.png differ diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/GenericTheme.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/GenericTheme.cs index 857cd20c..af2a9e84 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/GenericTheme.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/GenericTheme.cs @@ -1,14 +1,15 @@ /************************************************************************************* + + Toolkit for WPF - Extended WPF Toolkit + Copyright (C) 2007-2020 Xceed Software Inc. - Copyright (C) 2007-2013 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 is provided to you under the terms of the XCEED SOFTWARE, INC. + COMMUNITY LICENSE AGREEMENT (for non-commercial use) as published at + https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids @@ -22,7 +23,10 @@ namespace Xceed.Wpf.AvalonDock.Themes { public override Uri GetResourceUri() { - return new Uri( "/Xceed.Wpf.AvalonDock;component/Themes/generic.xaml", UriKind.Relative ); + string uri; + uri = "Xceed.Wpf.AvalonDock"; + + return new Uri( "/" + uri + ";component/Themes/generic.xaml", UriKind.Relative ); } } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/Theme.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/Theme.cs index 88abbfc0..12fce8ab 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/Theme.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/Theme.cs @@ -1,14 +1,15 @@ /************************************************************************************* + + Toolkit for WPF - Extended WPF Toolkit + Copyright (C) 2007-2020 Xceed Software Inc. - Copyright (C) 2007-2013 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 is provided to you under the terms of the XCEED SOFTWARE, INC. + COMMUNITY LICENSE AGREEMENT (for non-commercial use) as published at + https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/generic.xaml b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/generic.xaml index af82ccb4..7804e2af 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/generic.xaml +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Themes/generic.xaml @@ -1,14 +1,15 @@  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"> + + + diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Win32Helper.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Win32Helper.cs index 2106dd9b..f443c635 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Win32Helper.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Win32Helper.cs @@ -1,14 +1,15 @@ /************************************************************************************* + + Toolkit for WPF - Extended WPF Toolkit + Copyright (C) 2007-2020 Xceed Software Inc. - Copyright (C) 2007-2013 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 is provided to you under the terms of the XCEED SOFTWARE, INC. + COMMUNITY LICENSE AGREEMENT (for non-commercial use) as published at + https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids @@ -138,6 +139,8 @@ namespace Xceed.Wpf.AvalonDock [DllImport( "user32.dll" )] internal static extern IntPtr SetFocus( IntPtr hWnd ); + internal const int NCCALCSIZE = 0x0083; + internal const int WM_WINDOWPOSCHANGED = 0x0047; internal const int WM_WINDOWPOSCHANGING = 0x0046; internal const int WM_NCMOUSEMOVE = 0xa0; diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/WindowHelper.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/WindowHelper.cs index efd95082..c09e85f4 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/WindowHelper.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/WindowHelper.cs @@ -1,14 +1,15 @@ /************************************************************************************* + + Toolkit for WPF - Extended WPF Toolkit + Copyright (C) 2007-2020 Xceed Software Inc. - Copyright (C) 2007-2013 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 is provided to you under the terms of the XCEED SOFTWARE, INC. + COMMUNITY LICENSE AGREEMENT (for non-commercial use) as published at + https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Xceed.Wpf.AvalonDock.csproj b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Xceed.Wpf.AvalonDock.csproj index 3e1a745a..fbee76a2 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Xceed.Wpf.AvalonDock.csproj +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Xceed.Wpf.AvalonDock.csproj @@ -58,8 +58,12 @@ - - + + AssemblyVersionInfo.cs + + + AssemblyVersionInfoCommon.cs + @@ -74,6 +78,7 @@ + @@ -160,6 +165,7 @@ + @@ -199,6 +205,16 @@ Code + + Resources.ja-JP.resx + True + True + + + Resources.cs-CZ.resx + True + True + True True @@ -257,8 +273,21 @@ + + Utils\Exceptions\ThrowException.cs + + + PublicResXFileCodeGenerator + Resources.ja-JP.Designer.cs + Designer + + + PublicResXFileCodeGenerator + Resources.cs-CZ.Designer.cs + Designer + PublicResXFileCodeGenerator Resources.hu.Designer.cs @@ -346,6 +375,10 @@ + + Designer + MSBuild:Compile + Designer MSBuild:Compile @@ -357,12 +390,28 @@ Xceed.Wpf.Toolkit + + + + + + + + + + + + + + + + - - \ No newline at end of file + 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 136dd1ba..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 4df65fb1..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.5.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock\obj\Debug\GeneratedInternalTypeHelper.g.i.cs - -FD:\Dev\ExtendedWPFToolkit\Release\3.5.0\OpenSource\Generated\Src\Xceed.Wpf.AvalonDock\Themes\generic.xaml;; - diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(DataVirtualization)/EmptyDataItem.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(DataVirtualization)/EmptyDataItem.cs deleted file mode 100644 index 358fad4b..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(DataVirtualization)/EmptyDataItem.cs +++ /dev/null @@ -1,285 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.ComponentModel; - -namespace Xceed.Wpf.DataGrid -{ - /// - /// This object is used as the dataItem of a VirtualItemInfo when creating a VirtualItemPage and waiting for the - /// fetch callback. - /// - internal class EmptyDataItem : INotifyPropertyChanged, ICustomTypeDescriptor - { - #region CONSTRUCTORS - - internal EmptyDataItem() - : base() - { - } - - internal EmptyDataItem( int index, VirtualList parentVirtualList ) - : base() - { - if( index < 0 ) - throw new ArgumentException( "Index must be greater than or equal to zero.", "index" ); - - if( parentVirtualList == null ) - throw new ArgumentNullException( "parentVirtualList" ); - - m_index = index; - m_parentVirtualList = parentVirtualList; - } - - #endregion CONSTRUCTORS - - #region Index Property - - public int Index - { - get - { - return m_index; - } - } - - #endregion Index Property - - #region INTERNAL PROPERTIES - - internal VirtualList ParentVirtualList - { - get - { - return m_parentVirtualList; - } - } - - #endregion INTERNAL PROPERTIES - - #region Indexer - - [EditorBrowsable( EditorBrowsableState.Never )] - public object this[ object parameter ] - { - get - { - return null; - } - set - { - } - } - - #endregion - - #region PRIVATE FIELDS - - private int m_index; - private VirtualList m_parentVirtualList; - - #endregion PRIVATE FIELDS - - #region CONSTANTS - - private static readonly EmptyDataItemPropertyDescriptorCollection DefaultEmptyDataItemPropertyDescriptorCollection = new EmptyDataItemPropertyDescriptorCollection(); - - #endregion CONSTANTS - - #region ICustomTypeDescriptor Members - - public AttributeCollection GetAttributes() - { - return TypeDescriptor.GetAttributes( this ); - } - - public string GetClassName() - { - return TypeDescriptor.GetClassName( this ); - } - - public string GetComponentName() - { - return TypeDescriptor.GetComponentName( this ); - } - - public TypeConverter GetConverter() - { - return TypeDescriptor.GetConverter( this ); - } - - public EventDescriptor GetDefaultEvent() - { - return TypeDescriptor.GetDefaultEvent( this ); - } - - public PropertyDescriptor GetDefaultProperty() - { - return TypeDescriptor.GetDefaultProperty( this ); - } - - public object GetEditor( Type editorBaseType ) - { - return TypeDescriptor.GetEditor( this, editorBaseType ); - } - - public EventDescriptorCollection GetEvents( Attribute[] attributes ) - { - return TypeDescriptor.GetEvents( this, attributes ); - } - - public EventDescriptorCollection GetEvents() - { - return TypeDescriptor.GetEvents( this ); - } - - public PropertyDescriptorCollection GetProperties( Attribute[] attributes ) - { - // We use a custom PropertyDescriptorCollection that will return the same instance - // of an EmptyDataItemPropertyDescriptor for ANY property that will be ask. This is to avoid - // BindingErrors when an EmptyDataItem is used in the grid. - return EmptyDataItem.DefaultEmptyDataItemPropertyDescriptorCollection; - } - - public PropertyDescriptorCollection GetProperties() - { - return this.GetProperties( null ); - } - - public object GetPropertyOwner( PropertyDescriptor pd ) - { - return this; - } - - #endregion ICustomTypeDescriptor Members - - #region EmptyDataItemPropertyDescriptorCollection Class - - private class EmptyDataItemPropertyDescriptorCollection : PropertyDescriptorCollection - { - private static readonly EmptyDataItemPropertyDescriptor DefaultEmptyDataItemPropertyDescriptor = new EmptyDataItemPropertyDescriptor(); - - private static readonly EmptyDataItemPropertyDescriptor[] DefaultEmptyDataItemPropertyDescriptorArray = new EmptyDataItemPropertyDescriptor[] - { - EmptyDataItemPropertyDescriptorCollection.DefaultEmptyDataItemPropertyDescriptor, - }; - - public EmptyDataItemPropertyDescriptorCollection() - : base( EmptyDataItemPropertyDescriptorCollection.DefaultEmptyDataItemPropertyDescriptorArray ) - { - } - - public override PropertyDescriptor Find( string name, bool ignoreCase ) - { - return EmptyDataItemPropertyDescriptorCollection.DefaultEmptyDataItemPropertyDescriptor; - } - - public override PropertyDescriptor this[ int index ] - { - get - { - return EmptyDataItemPropertyDescriptorCollection.DefaultEmptyDataItemPropertyDescriptor; - } - } - - public override PropertyDescriptor this[ string name ] - { - get - { - return EmptyDataItemPropertyDescriptorCollection.DefaultEmptyDataItemPropertyDescriptor; - } - } - } - - #endregion EmptyDataItemPropertyDescriptorCollection Class - - #region EmptyDataItemPropertyDescriptor Class - - private class EmptyDataItemPropertyDescriptor : PropertyDescriptor - { - private const string DefaultPropertyName = "Empty"; - private static readonly Type ObjectType = typeof( object ); - - public EmptyDataItemPropertyDescriptor() - : base( EmptyDataItemPropertyDescriptor.DefaultPropertyName, null ) - { - } - - public override bool CanResetValue( object component ) - { - return false; - } - - public override Type ComponentType - { - get - { - return EmptyDataItemPropertyDescriptor.ObjectType; - } - } - - public override object GetValue( object component ) - { - return null; - } - - public override bool IsReadOnly - { - get - { - return false; - } - } - - public override Type PropertyType - { - get - { - return EmptyDataItemPropertyDescriptor.ObjectType; - } - } - - public override void ResetValue( object component ) - { - } - - public override void SetValue( object component, object value ) - { - } - - public override bool ShouldSerializeValue( object component ) - { - return false; - } - } - - #endregion EmptyDataItemPropertyDescriptor Class - - #region INotifyPropertyChanged Members - - event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged - { - add { } - remove { } - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(DataVirtualization)/VirtualList.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(DataVirtualization)/VirtualList.cs deleted file mode 100644 index d0eecffc..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(DataVirtualization)/VirtualList.cs +++ /dev/null @@ -1,892 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Collections.Specialized; -using System.Diagnostics; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - internal class VirtualList : IList, IList, INotifyCollectionChanged, IDisposable - { - public VirtualList( VirtualPageManager pagingManager ) - : this( pagingManager, -1 ) - { - } - - public VirtualList( VirtualPageManager pagingManager, int virtualCount ) - { - if( pagingManager == null ) - throw new ArgumentNullException( "pagingManager" ); - - pagingManager.ManageList( this ); - - m_tableOfContent = new VirtualListTableOfContent( 8 ); - - m_virtualCount = virtualCount; - } - - #region VirtualPagingManager Property - - public VirtualPageManager PagingManager - { - get - { - return m_pagingManager; - } - } - - #endregion - - #region VirtualCount Property - - public int VirtualCount - { - get - { - if( this.IsDisposed ) - return 0; - - if( m_virtualCount == -1 ) - this.QueryAndSetVirtualCount(); - - return m_virtualCount; - } - } - - #endregion - - #region TableOfContent Property - - internal VirtualListTableOfContent TableOfContent - { - get - { - return m_tableOfContent; - } - } - - #endregion - - #region VirtualPagingManager Property - - internal VirtualPageManager VirtualPagingManager - { - get - { - return m_pagingManager; - } - set - { - // null is an acceptable value when disposing the list - if( ( m_pagingManager != null ) && ( value != null ) ) - throw new InvalidOperationException( "An attempt was made to set a VirtualPageManager when one has already been provided." ); - - m_pagingManager = value; - } - } - - #endregion - - #region IsDisposed Property - - internal bool IsDisposed - { - get - { - return m_flags[ ( int )VirtualItemBookFlags.Disposed ]; - } - private set - { - m_flags[ ( int )VirtualItemBookFlags.Disposed ] = value; - } - } - - #endregion - - #region IsRestarting Property - - internal bool IsRestarting - { - get - { - return m_flags[ ( int )VirtualItemBookFlags.Restarting ]; - } - private set - { - m_flags[ ( int )VirtualItemBookFlags.Restarting ] = value; - } - } - - #endregion - - #region HasPagePendingCommit Property - - internal bool HasPagePendingCommit - { - get - { - foreach( VirtualPage page in m_tableOfContent.VirtualPages ) - { - if( page.IsCommitPending ) - return true; - } - - return false; - } - } - - #endregion - -#if DEBUG - public override string ToString() - { - StringBuilder builder = new StringBuilder(); - - ReadOnlyCollection virtualPages = m_tableOfContent.VirtualPages; - int pageCount = virtualPages.Count; - - for( int i = 0; i < pageCount; i++ ) - { - VirtualPage page = virtualPages[ i ]; - - builder.Append( i.ToString() + ": Page " + page.ToString() + Environment.NewLine ); - } - - return builder.ToString(); - } -#endif - - internal int IndexOf( object item ) - { - if( ( item == null ) || ( this.IsDisposed ) ) - return -1; - - EmptyDataItem emptyDataItem = item as EmptyDataItem; - - if( emptyDataItem != null ) - { - if( ( emptyDataItem.ParentVirtualList == this ) && ( emptyDataItem.Index < m_virtualCount ) ) - return emptyDataItem.Index; - - return -1; - } - - return m_tableOfContent.IndexOf( item ); - } - - internal bool IsPageDirty( int index ) - { - VirtualPage page = this.GetPageOrDefaultForItemIndex( index, true ); - - return ( page == null ) ? false : page.IsDirty; - } - - internal bool IsItemDirty( object item ) - { - int localIndex = this.IndexOf( item ); - - if( localIndex == -1 ) - return false; - - VirtualizedItemInfo virtualizedItemInfo = this.GetVirtualizedItemInfoAtIndex( localIndex, false, true ); - - return ( virtualizedItemInfo == null ) ? false : virtualizedItemInfo.IsDirty; - } - - internal VirtualizedItemValueCollection GetCachedValuesForItemAtIndex( int index ) - { - VirtualizedItemInfo virtualizedItemInfo = this.GetVirtualizedItemInfoAtIndex( index, false, true ); - - return ( virtualizedItemInfo == null ) ? null : virtualizedItemInfo.OldValues; - } - - internal void SetCachedValuesForItemAtIndex( int index, string[] names, object[] values ) - { - VirtualizedItemInfo virtualizedItemInfo = this.GetVirtualizedItemInfoAtIndex( index, false, true ); - - if( virtualizedItemInfo == null ) - throw new ArgumentOutOfRangeException( "index", index, "No VirtualizedItemInfo can be found at the specified index." ); - - virtualizedItemInfo.OldValues = new VirtualizedItemValueCollection( names, values ); - } - - internal void ClearCachedValuesForItemAtIndex( int index ) - { - VirtualizedItemInfo virtualizedItemInfo = this.GetVirtualizedItemInfoAtIndex( index, false, true ); - - if( virtualizedItemInfo == null ) - throw new ArgumentOutOfRangeException( "index", index, "No VirtualizedItemInfo can be found at the specified index." ); - - virtualizedItemInfo.OldValues = null; - } - - internal object GetItemAt( int index ) - { - if( ( index < 0 ) || ( index >= m_virtualCount ) ) - throw new ArgumentOutOfRangeException( "Index", index, "index must be greater than or equal to zero and less than count." ); - - VirtualizedItemInfo virtualizedItemInfo = this.GetVirtualizedItemInfoAtIndex( index, true, false ); - return virtualizedItemInfo.DataItem; - } - - internal VirtualizedItemInfo GetVirtualizedItemInfoAtIndex( int index, bool createPageIfLineNotFound, bool preventMovePageToFront ) - { - VirtualizedItemInfo virtualizedItemInfo = null; - - VirtualPage page = this.GetPageOrDefaultForItemIndex( index, preventMovePageToFront ); - - if( page != null ) - { - virtualizedItemInfo = page.GetVirtualizedItemInfoAtIndex( index ); - - Debug.Assert( virtualizedItemInfo != null ); - } - else if( createPageIfLineNotFound ) - { - page = this.CreateNewPage( index ); - - virtualizedItemInfo = page.GetVirtualizedItemInfoAtIndex( index ); - m_pagingManager.AddPage( page, VirtualPageManager.PageInsertPosition.Front ); - } - - return virtualizedItemInfo; - } - - internal void LockPageForLocalIndex( int sourceIndex ) - { - Debug.Assert( m_tableOfContent.ContainsPageForSourceIndex( sourceIndex ) ); - Debug.Assert( this.GetPageOrDefaultForItemIndex( sourceIndex, true ) != null ); - - VirtualPage page; - if( m_tableOfContent.TryGetPageForSourceIndex( sourceIndex, out page ) ) - { - if( page.LockPage() ) - { - Debug.WriteLineIf( VirtualPageManager.DebugDataVirtualization, "List: " + this.GetHashCode().ToString() + " - LOCKING PAGE: " + page.ToString() + " for index: " + sourceIndex.ToString() + " NEW LOCKED PAGES COUNT: " + this.GetLockedPageCount().ToString() ); - } - - this.PreEmptiveLoadPages( sourceIndex, page ); - } - } - - internal void UnlockPageForLocalIndex( int sourceIndex ) - { - if( this.IsDisposed ) - return; - - VirtualPage page; - - if( m_tableOfContent.TryGetPageForSourceIndex( sourceIndex, out page ) ) - { - if( page.UnlockPage() ) - { - Debug.Assert( this.GetLockedPageCount() >= 0 ); - Debug.WriteLineIf( VirtualPageManager.DebugDataVirtualization, "List: " + this.GetHashCode().ToString() + " - UN-LOCKING PAGE: " + page.ToString() + " for index: " + sourceIndex.ToString() + " NEW LOCKED PAGES COUNT: " + this.GetLockedPageCount().ToString() ); - - m_pagingManager.CleanUpAndDisposeUnused(); - } - } - } - - private void PreEmptiveLoadPages( int sourceIndex, VirtualPage page ) - { - // The VirtualList is disposed or part of a PagingManager that will be disposed (only disconnected when dispose is required) - if( !this.PagingManager.IsConnected ) - return; - - Debug.Assert( !this.IsDisposed ); - - double preemptivePageQueryRatio = m_pagingManager.PreemptivePageQueryRatio; - int pageSize = m_pagingManager.PageSize; - - double pageRatio = ( preemptivePageQueryRatio > 0.5 ) ? 0.5 : ( preemptivePageQueryRatio < 0.0 ) ? 0 : preemptivePageQueryRatio; - - double boundariesItemCount = ( pageRatio * pageSize ); - - int preEmptivePageStartIndex = -1; - - if( ( page.StartDataIndex > 0 ) && ( sourceIndex < ( page.StartDataIndex + boundariesItemCount ) ) ) - { - // Pre emptively load the previous page. - preEmptivePageStartIndex = page.StartDataIndex - pageSize; - } - else if( ( page.EndDataIndex < ( m_virtualCount - 1 ) ) && ( sourceIndex > ( page.EndDataIndex - boundariesItemCount ) ) ) - { - // Pre emptively load the next page. - preEmptivePageStartIndex = page.EndDataIndex + 1; - } - - if( preEmptivePageStartIndex != -1 ) - { - VirtualPage preEmptivePage = null; - - // We do not want to move the pre-emptive page to the front if it is already created since it does not count as a legitimate user-acess. - preEmptivePage = this.GetPageOrDefaultForItemIndex( preEmptivePageStartIndex, true ); - - if( preEmptivePage == null ) - { - // The pre-emptive page is not yet created. Let's do it and add it to the back since it is not really accessed at the moment. - preEmptivePage = this.CreateNewPage( preEmptivePageStartIndex ); - m_pagingManager.AddPage( preEmptivePage, VirtualPageManager.PageInsertPosition.Back ); - } - } - } - - internal bool IsAsyncCommitQueuedForItem( object item ) - { - VirtualPage virtualPage; - - if( m_tableOfContent.TryGetPageForItem( item, out virtualPage ) ) - return virtualPage.IsAsyncCommitInfoQueuedForItem( item ); - - return false; - } - - internal void CommitAll() - { - foreach( VirtualPage page in m_tableOfContent.VirtualPages ) - { - Debug.Assert( page != null ); - Debug.Assert( page.ParentVirtualList == this ); - - if( page.IsDirty ) - { - m_pagingManager.QueueCommitData( page ); - } - } - } - - internal void Restart() - { - if( this.IsRestarting ) - return; - - Debug.WriteLineIf( VirtualPageManager.DebugDataVirtualization, "Restart VirtualList requested, checking for pages to commit or abort..." ); - - this.IsRestarting = true; - m_pagingManager.OnVirtualListRestarting( this ); - - // We must keep a copy since restarting can remove pages from table of content - int virtualPagesCount = m_tableOfContent.VirtualPages.Count; - - if( virtualPagesCount == 0 ) - { - this.EndRestart(); - } - else - { - // Restart every pages this VirtualList contains. - // Keep a reference to the pages that need to restart in order to know when this VirtualList is restarted - m_restartingPages.AddRange( m_tableOfContent.VirtualPages ); - - for( int i = virtualPagesCount - 1; i >= 0; i-- ) - { - VirtualPage page = m_tableOfContent.VirtualPages[ i ]; - Debug.Assert( !page.IsDisposed ); - - if( !page.IsRestarting ) - { - page.Restart(); - } - } - } - } - - internal void OnVirtualPageRestarting( VirtualPage page ) - { - // Notify the VirtualPageManager that this page is restarted to ensure it commits its data or aborts the QueryItems if already invoked - Debug.Assert( m_restartingPages.Contains( page ) ); - m_pagingManager.OnVirtualListPageRestarting( this, page ); - } - - internal void OnVirtualPageRestarted( VirtualPage page ) - { - Debug.Assert( m_restartingPages.Contains( page ) ); - - // The page is restarted, remove it from the restarting pages - m_restartingPages.Remove( page ); - - // Notify the manager that this page is restarted in order to let it remove it from its m_pageNodes and also from this VirtualList TableOfContent. - // NOTE: We do not remove it from the TableOfContent immediately to avoid have to insert a condition in VirtualPageManager.RemovePage since this method - // used widely to ensure a page is removed from the TableOfContent and from the m_pageNodes list. - m_pagingManager.OnVirtualListPageRestarted( this, page ); - - // Ensure all restarted pages completed their commit or abort operation before notifying that this list is restarted - if( m_restartingPages.Count == 0 ) - { - Debug.WriteLineIf( VirtualPageManager.DebugDataVirtualization, "Cleared VirtualList" ); - this.EndRestart(); - } - } - - internal void FillEmptyPage( AsyncQueryInfo asyncQueryInfo, object[] fetchedItems ) - { - // The VirtualList is disposed or part of a PagingManager that will be disposed (only disconnected when dispose is required) - if( !this.PagingManager.IsConnected ) - return; - - Debug.Assert( !this.IsDisposed ); - Debug.Assert( !asyncQueryInfo.IsDisposed ); - - // We do not want to move the page we are about to fill to the front since it does not count as a legitimate user-acess. It will get moved to the front when one of its item is accessed. - VirtualPage page = null; - page = this.GetPageOrDefaultForItemIndex( asyncQueryInfo.StartIndex, true ); - - // Although extremely rare, this situation could occur if we are calling RemovePageNode and the QueryData Dispatcher Operation - // which has been asyncronously invoked in CreateNewPage is raising the QueryData event at the exact moment when we - // try to abort the dispatcher operation. This means that the customer will have queued an async request for data - // for a page we no longer care about, and have already removed from the Table of Content and our LinkedList. - // This should NOT occur if the user did not abort the request and called the AsyncQueryInfo EndQuery method since AsyncQueryInfo should - // not have invoked the EndQueryAction if its ShouldAbort property was set to true. - if( page == null ) - return; - - Debug.Assert( !page.IsFilled ); - Debug.Assert( this.GetPageStartingIndexForItemIndex( asyncQueryInfo.StartIndex ) == asyncQueryInfo.StartIndex ); - - Debug.Assert( fetchedItems.Length <= page.Count ); - - if( fetchedItems.Length == page.Count ) - { - object[] oldItems = page.ToItemArray(); - - m_tableOfContent.RemovePage( page ); - - page.EndQueryItems( asyncQueryInfo, fetchedItems ); - - m_tableOfContent.AddPage( page ); - - Debug.WriteLineIf( VirtualPageManager.DebugDataVirtualization, "Replaced TOC items/index for page: " + page.ToString() ); - - this.OnCollectionChanged( new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Replace, fetchedItems, oldItems, asyncQueryInfo.StartIndex ) ); - } - else - { - // The expected count was not met. Maybe the user told us the source was bigger than it really is, or maybe there were delete operations made on the source since the last restart. - // Let's refresh the CollectionView. This will restart the VirtualItemBook and raise the CollectionView's OnCollectionChanged Reset notification. - this.OnCollectionChanged( new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Reset ) ); - } - } - - internal void NotifyCommitComplete( AsyncCommitInfo asyncCommitInfo ) - { - if( asyncCommitInfo.VirtualizedItemInfos.Length < 1 ) - throw new DataGridInternalException( "VirualizedItemInfos is empty." ); - - int indexForItemInPage = asyncCommitInfo.VirtualizedItemInfos[ 0 ].Index; - - // We do not want to move the page we are about to flag has committed to the front since it does not count as a legitimate user-access. - // It will get moved to the front when one of its items is accessed. - VirtualPage page = null; - page = this.GetPageOrDefaultForItemIndex( indexForItemInPage, true ); - - if( page == null ) - throw new InvalidOperationException( "An attempt was made to retrieve a page does not exist." ); - - if( ( !this.HasPagePendingCommit ) || ( !page.IsCommitPending ) ) - throw new InvalidOperationException( "An attempt was made to commit a page that does not have a pending commit operation." ); - - Debug.Assert( page.IsDirty ); - - page.EndCommitItems( asyncCommitInfo ); - - // If we no longer have any pages pending commit. - if( !this.HasPagePendingCommit ) - { - // CleanUp and queue a request to fill empty pages from the start of the queue. - m_pagingManager.CleanUpAndDisposeUnused(); - - // This is a failsafe, to make sure that during the clean-up other commit were not queued. - if( !this.HasPagePendingCommit ) - { - if( !this.IsRestarting ) - { - // After the call to cleanup, there should only be LOCKED pending fill pages remaining. Those are the one to refetch. - List lockedPages = this.GetLockedPages(); - int lockedPageCount = lockedPages.Count; - - for( int i = 0; i < lockedPageCount; i++ ) - { - VirtualPage lockedPage = lockedPages[ i ]; - - if( lockedPage.IsFilled ) - continue; - - // The locked page has been created while commit was pending. Let's queue its query data operation. - m_pagingManager.QueueQueryData( lockedPage ); - } - } - else - { - this.Restart(); - } - } - } - } - - private void EndRestart() - { - Debug.Assert( m_restartingPages.Count == 0 ); - - m_virtualCount = -1; - this.IsRestarting = false; - - Debug.WriteLineIf( VirtualPageManager.DebugDataVirtualization, "VirtualList restarted" ); - - m_pagingManager.OnVirtualListRestarted( this ); - - this.Dispose(); - } - - private int GetPageStartingIndexForItemIndex( int itemIndex ) - { - int pageSize = m_pagingManager.PageSize; - return ( itemIndex / pageSize ) * pageSize; - } - - private VirtualPage CreateNewPage( int itemIndex ) - { - Debug.Assert( !m_tableOfContent.ContainsPageForSourceIndex( itemIndex ) ); - - int pageStartIndex = this.GetPageStartingIndexForItemIndex( itemIndex ); - - int pageSize = m_pagingManager.PageSize; - - int expectedItemCount = Math.Min( pageSize, ( m_virtualCount - pageStartIndex ) ); - expectedItemCount = Math.Max( 0, expectedItemCount ); - - VirtualPage page = VirtualPage.CreateEmptyPage( this, pageStartIndex, expectedItemCount ); - - m_tableOfContent.AddPage( page ); - - // If we have a pending commit page, this brandly new created page will get its query data queued when we are notified of a commit completed and that we no longer have any pages awaiting commiting. - if( !this.HasPagePendingCommit ) - { - m_pagingManager.QueueQueryData( page ); - } - - Debug.WriteLineIf( VirtualPageManager.DebugDataVirtualization, "Creating VirtualItemPlaceHolder for page: " + page.ToString() ); - - return page; - } - - private VirtualPage GetPageOrDefaultForItemIndex( int index, bool preventMoveToFront ) - { - VirtualPage page = null; - - if( m_tableOfContent.TryGetPageForSourceIndex( index, out page ) ) - { - if( !preventMoveToFront ) - m_pagingManager.MovePageToFront( page ); - } - - return page; - } - - private int GetLockedPageCount() - { - int lockedPageCount = 0; - - foreach( VirtualPage page in m_tableOfContent.VirtualPages ) - { - Debug.Assert( page != null ); - - if( ( page != null ) && ( page.IsLocked ) ) - lockedPageCount++; - } - - return lockedPageCount; - } - - private List GetLockedPages() - { - List lockedPages = new List(); - - foreach( VirtualPage page in m_tableOfContent.VirtualPages ) - { - Debug.Assert( page != null ); - - if( ( page != null ) && ( page.IsLocked ) ) - { - lockedPages.Add( page ); - } - } - - return lockedPages; - } - - private void QueryAndSetVirtualCount() - { - int count = m_pagingManager.OnQueryItemCount( this ); - - Debug.WriteLineIf( VirtualPageManager.DebugDataVirtualization, ( count != -1 ) ? "QUERY VIRTUAL COUNT: " + count.ToString() : "QUERY VIRTUAL COUNT NOT HANDLED, SETTING COUNT TO ZERO." ); - - if( count == -1 ) - { - count = 0; - } - - m_virtualCount = count; - } - - private void OnCollectionChanged( NotifyCollectionChangedEventArgs e ) - { - var handler = this.CollectionChanged; - if( handler == null ) - return; - - handler.Invoke( this, e ); - } - - #region IList Members - - int IList.IndexOf( object item ) - { - return this.IndexOf( item ); - } - - void IList.Insert( int index, object item ) - { - throw new NotImplementedException(); - } - - void IList.RemoveAt( int index ) - { - throw new NotImplementedException(); - } - - object IList.this[ int index ] - { - get - { - return this.GetItemAt( index ); - } - set - { - throw new NotImplementedException(); - } - } - - #endregion - - #region ICollection Members - - void ICollection.Add( object item ) - { - throw new NotImplementedException(); - } - - void ICollection.Clear() - { - throw new NotImplementedException(); - } - - bool ICollection.Contains( object item ) - { - return ( this.IndexOf( item ) != -1 ); - } - - void ICollection.CopyTo( object[] array, int arrayIndex ) - { - throw new NotImplementedException(); - } - - int ICollection.Count - { - get - { - return this.VirtualCount; - } - } - - bool ICollection.IsReadOnly - { - get - { - return true; - } - } - - bool ICollection.Remove( object item ) - { - throw new NotImplementedException(); - } - - #endregion - - #region IEnumerable Members - - IEnumerator IEnumerable.GetEnumerator() - { - return new VirtualListEnumerator( this ); - } - - #endregion - - #region IEnumerable Members - - IEnumerator IEnumerable.GetEnumerator() - { - return ( ( IEnumerable )this ).GetEnumerator(); - } - - #endregion - - #region INotifyCollectionChanged Members - - public event NotifyCollectionChangedEventHandler CollectionChanged; - - #endregion - - #region IList Members - - int IList.Add( object value ) - { - throw new NotImplementedException(); - } - - void IList.Clear() - { - throw new NotImplementedException(); - } - - bool IList.Contains( object value ) - { - return this.IndexOf( value ) != -1; - } - - int IList.IndexOf( object value ) - { - return this.IndexOf( value ); - } - - void IList.Insert( int index, object value ) - { - throw new NotImplementedException(); - } - - bool IList.IsFixedSize - { - get - { - return true; - } - } - - bool IList.IsReadOnly - { - get - { - return true; - } - } - - void IList.Remove( object value ) - { - throw new NotImplementedException(); - } - - void IList.RemoveAt( int index ) - { - throw new NotImplementedException(); - } - - object IList.this[ int index ] - { - get - { - return this.GetItemAt( index ); - } - set - { - throw new NotImplementedException(); - } - } - - #endregion - - #region ICollection Members - - void ICollection.CopyTo( Array array, int index ) - { - throw new NotImplementedException(); - } - - int ICollection.Count - { - get - { - return this.VirtualCount; - } - } - - bool ICollection.IsSynchronized - { - get - { - throw new NotImplementedException(); - } - } - - object ICollection.SyncRoot - { - get - { - throw new NotImplementedException(); - } - } - - #endregion - - #region IDisposable Members - - public void Dispose() - { - - if( m_tableOfContent != null ) - { - Debug.Assert( m_tableOfContent.VirtualPages.Count == 0 ); - - m_tableOfContent.Dispose(); - m_tableOfContent = null; - } - - m_pagingManager = null; - this.IsDisposed = true; - - } - - #endregion - - private List m_restartingPages = new List(); - private VirtualPageManager m_pagingManager; - private BitVector32 m_flags; - private int m_virtualCount; - private VirtualListTableOfContent m_tableOfContent; - - [Flags] - private enum VirtualItemBookFlags - { - Restarting = 1, - Disposed = 2, - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(DataVirtualization)/VirtualListEnumerator.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(DataVirtualization)/VirtualListEnumerator.cs deleted file mode 100644 index 9d20c42b..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(DataVirtualization)/VirtualListEnumerator.cs +++ /dev/null @@ -1,153 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; - -namespace Xceed.Wpf.DataGrid -{ - internal class VirtualListEnumerator : IEnumerator, IEnumerator - { - public VirtualListEnumerator( VirtualList virtualList ) - { - if( virtualList == null ) - throw new ArgumentNullException( "virtualList" ); - - m_virtualList = virtualList; - - m_version = m_virtualList.PagingManager.Version; - - m_orderedFilledVirtualPages = - m_virtualList.TableOfContent.VirtualPages.OrderBy( - virtualPage => virtualPage.StartDataIndex ).Where( - virtualPage => virtualPage.IsFilled ).ToArray(); - } - - #region INTERNAL PROPERTIES - - internal bool BeforeStart - { - get - { - return m_beforeStart; - } - } - - internal bool AfterEnd - { - get - { - return m_afterEnd; - } - } - - #endregion INTERNAL PROPERTIES - - #region IDisposable Members - - public void Dispose() - { - m_currentItemInfo = null; - m_orderedFilledVirtualPages = null; - m_virtualList = null; - } - - #endregion IDisposable Members - - #region IEnumerator Members - - public object Current - { - get - { - return ( m_currentItemInfo == null ) ? null : m_currentItemInfo.DataItem; - } - } - - #endregion IEnumerator Members - - #region IEnumerator Members - - object IEnumerator.Current - { - get - { - return ( m_currentItemInfo == null ) ? null : m_currentItemInfo.DataItem; - } - } - - public bool MoveNext() - { - if( m_version != m_virtualList.PagingManager.Version ) - throw new InvalidOperationException( "Collection was modified." ); - - if( m_beforeStart ) - m_beforeStart = false; - - if( m_currentPageIndex < m_orderedFilledVirtualPages.Length ) - { - VirtualPage virtualPage = m_orderedFilledVirtualPages[ m_currentPageIndex ]; - - m_currentItemInfo = virtualPage[ m_currentItemIndex ]; - - m_currentItemIndex++; - - if( m_currentItemIndex >= virtualPage.Count ) - { - m_currentItemIndex = 0; - m_currentPageIndex++; - } - - return true; - } - else - { - m_currentItemInfo = null; - m_afterEnd = true; - - return false; - } - } - - public void Reset() - { - m_currentItemInfo = null; - m_currentItemIndex = 0; - m_currentPageIndex = 0; - m_afterEnd = false; - m_beforeStart = true; - } - - #endregion IEnumerator Members - - #region PRIVATE FIELDS - - private VirtualList m_virtualList; - private VirtualPage[] m_orderedFilledVirtualPages; - - private int m_version; - private VirtualizedItemInfo m_currentItemInfo; - private int m_currentPageIndex; - private int m_currentItemIndex; - - private bool m_beforeStart; - private bool m_afterEnd; - - #endregion PRIVATE FIELDS - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(DataVirtualization)/VirtualListTableOfContent.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(DataVirtualization)/VirtualListTableOfContent.cs deleted file mode 100644 index 3f60ff8b..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(DataVirtualization)/VirtualListTableOfContent.cs +++ /dev/null @@ -1,169 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Diagnostics; -using System.Collections.ObjectModel; - -namespace Xceed.Wpf.DataGrid -{ - internal class VirtualListTableOfContent : IDisposable - { - internal VirtualListTableOfContent( int initialCapacity ) - { - m_virtualPages = new List(); - m_readonlyVirtualPages = new ReadOnlyCollection( m_virtualPages ); - - m_objectVersusIndexDictionary = new Dictionary( initialCapacity ); - m_indexVersusPageDictionary = new Dictionary( initialCapacity ); - } - - public void AddPage( VirtualPage page ) - { - Debug.Assert( !m_virtualPages.Contains( page ) ); - - m_virtualPages.Add( page ); - - int itemCount = page.Count; - - for( int i = 0; i < itemCount; i++ ) - { - VirtualizedItemInfo virtualizedItemInfo = page[ i ]; - - Debug.Assert( !m_objectVersusIndexDictionary.ContainsKey( virtualizedItemInfo.DataItem ) ); - Debug.Assert( !m_indexVersusPageDictionary.ContainsKey( virtualizedItemInfo.Index ) ); - - m_objectVersusIndexDictionary.Add( virtualizedItemInfo.DataItem, virtualizedItemInfo.Index ); - m_indexVersusPageDictionary.Add( virtualizedItemInfo.Index, page ); - } - } - - public void RemovePage( VirtualPage page ) - { - Debug.Assert( m_virtualPages.Contains( page ) ); - - int itemCount = page.Count; - - for( int i = 0; i < itemCount; i++ ) - { - VirtualizedItemInfo virtualizedItemInfo = page[ i ]; - - Debug.Assert( m_objectVersusIndexDictionary.ContainsKey( virtualizedItemInfo.DataItem ) ); - Debug.Assert( m_indexVersusPageDictionary.ContainsKey( virtualizedItemInfo.Index ) ); - - Debug.Assert( m_indexVersusPageDictionary[ virtualizedItemInfo.Index ] == page ); - - m_objectVersusIndexDictionary.Remove( virtualizedItemInfo.DataItem ); - m_indexVersusPageDictionary.Remove( virtualizedItemInfo.Index ); - } - - m_virtualPages.Remove( page ); - } - - public int IndexOf( object item ) - { - int index; - - if( m_objectVersusIndexDictionary.TryGetValue( item, out index ) ) - return index; - - return -1; - } - - public bool TryGetPageForItem( object item, out VirtualPage page ) - { - page = null; - - int index; - - if( m_objectVersusIndexDictionary.TryGetValue( item, out index ) ) - return m_indexVersusPageDictionary.TryGetValue( index, out page ); - - return false; - } - - public bool TryGetPageForSourceIndex( int sourceIndex, out VirtualPage page ) - { - return m_indexVersusPageDictionary.TryGetValue( sourceIndex, out page ); - } - - public bool ContainsPageForItem( object item ) - { - int index; - - if( m_objectVersusIndexDictionary.TryGetValue( item, out index ) ) - return m_indexVersusPageDictionary.ContainsKey( index ); - - return false; - } - - public bool ContainsPageForSourceIndex( int sourceIndex ) - { - return m_indexVersusPageDictionary.ContainsKey( sourceIndex ); - } - - public int Count - { - get - { - Debug.Assert( m_objectVersusIndexDictionary.Count == m_indexVersusPageDictionary.Count ); - return m_objectVersusIndexDictionary.Count; - } - } - - public ReadOnlyCollection VirtualPages - { - get - { - return m_readonlyVirtualPages; - } - } - - private Dictionary m_objectVersusIndexDictionary; - private Dictionary m_indexVersusPageDictionary; - - private List m_virtualPages; - private ReadOnlyCollection m_readonlyVirtualPages; - - #region IDisposable Members - - public void Dispose() - { - while( m_virtualPages.Count > 0 ) - { - // Remove the page from every Dictionaries and - // also from m_virtualPages - VirtualPage page = m_virtualPages[ 0 ]; - this.RemovePage( page ); - page.Dispose(); - } - - Debug.Assert( m_objectVersusIndexDictionary.Count == 0 ); - Debug.Assert( m_indexVersusPageDictionary.Count == 0 ); - Debug.Assert( m_virtualPages.Count == 0 ); - - m_objectVersusIndexDictionary.Clear(); - m_indexVersusPageDictionary.Clear(); - m_virtualPages.Clear(); - - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(DataVirtualization)/VirtualPage.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(DataVirtualization)/VirtualPage.cs deleted file mode 100644 index 2dc5900c..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(DataVirtualization)/VirtualPage.cs +++ /dev/null @@ -1,671 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Diagnostics; -using System.Windows.Threading; - -namespace Xceed.Wpf.DataGrid -{ - internal class VirtualPage : List, IDisposable - { - internal static VirtualPage CreateEmptyPage( VirtualList parentVirtualList, int startSourceIndex, int entryCount ) - { - if( parentVirtualList == null ) - throw new ArgumentNullException( "parentVirtualList" ); - - if( startSourceIndex < 0 ) - throw new ArgumentOutOfRangeException( "startSourceIndex", startSourceIndex, "startSourceIndex must be greater than or equal to zero." ); - - if( entryCount < 0 ) - throw new ArgumentOutOfRangeException( "entryCount", entryCount, "entryCount must be greater than or equal to zero." ); - - EmptyDataItem[] emptyDataItems = new EmptyDataItem[ entryCount ]; - for( int i = 0; i < entryCount; i++ ) - { - emptyDataItems[ i ] = new EmptyDataItem( startSourceIndex + i, parentVirtualList ); - } - - VirtualPage emptyDataItemPage = new VirtualPage( parentVirtualList, startSourceIndex, emptyDataItems ); - emptyDataItemPage.IsFilled = false; - - return emptyDataItemPage; - } - - private VirtualPage( VirtualList parentVirtualList, int startSourceIndex, object[] dataItems ) - : base( dataItems.Length ) - { - if( parentVirtualList == null ) - throw new ArgumentNullException( "parentVirtualList" ); - - if( startSourceIndex < 0 ) - throw new ArgumentOutOfRangeException( "startSourceIndex", startSourceIndex, "startSourceIndex must be greater than or equal to zero." ); - - m_startDataIndex = startSourceIndex; - m_asyncCommitInfoList = new List(); - - m_parentVirtualList = parentVirtualList; - - int length = dataItems.Length; - for( int i = 0; i < length; i++ ) - { - Debug.Assert( dataItems[ i ] != null ); - this.Add( new VirtualizedItemInfo( m_startDataIndex + i, dataItems[ i ] ) ); - } - - this.IsFilled = true; - } - - #region RemoveAfterOperation Property - - public bool RemoveAfterOperation - { - get; - set; - } - - #endregion - - #region IsAborting Property - - public bool IsAborting - { - get; - private set; - } - - #endregion - - #region IsRestarting Property - - public bool IsRestarting - { - get; - private set; - } - - #endregion - - #region IsEmpty Property - - public bool IsEmpty - { - get - { - return ( this.Count == 0 ); - } - } - - #endregion - - #region IsFilled Property - - public bool IsFilled - { - get - { - return m_flags[ ( int )VirtualItemPageFlags.IsFilled ]; - } - private set - { - // Wether we are setting PendingFill to True or to False, we should not be touching this property if we are pending commit. - Debug.Assert( !this.IsCommitPending ); - - m_flags[ ( int )VirtualItemPageFlags.IsFilled ] = value; - } - } - - #endregion - - #region IsDisposed Read-Only Property - - public bool IsDisposed - { - get - { - return m_flags[ ( int )VirtualItemPageFlags.IsDisposed ]; - } - private set - { - m_flags[ ( int )VirtualItemPageFlags.IsDisposed ] = value; - } - } - - #endregion - - #region IsCommitPending Property - - public bool IsCommitPending - { - get - { - return m_asyncCommitInfoList.Count > 0; - } - } - - #endregion - - #region IsDirty Property - - public bool IsDirty - { - get - { - if( !this.IsFilled ) - return false; - - int count = this.Count; - - for( int i = 0; i < count; i++ ) - { - if( this[ i ].IsDirty ) - return true; - } - - return false; - } - } - - #endregion - - #region IsLocked Property - - public bool IsLocked - { - get - { - return ( m_lockCount > 0 ); - } - } - - #endregion - - #region IsRemovable Property - - public bool IsRemovable - { - get - { - // A page which IsPendingFill is removable since it hasn't even been filled yet. - return ( ( !this.IsLocked ) && ( !this.IsCommitPending ) ); - } - } - - #endregion - - #region ParentVirtualList Property - - public VirtualList ParentVirtualList - { - get - { - return m_parentVirtualList; - } - } - - #endregion - - #region StartDataIndex Property - - public int StartDataIndex - { - get - { - return m_startDataIndex; - } - } - - #endregion - - #region EndDataIndex Property - - public int EndDataIndex - { - get - { - return m_startDataIndex + ( this.Count - 1 ); - } - } - - #endregion - - public VirtualizedItemInfo GetVirtualizedItemInfoAtIndex( int sourceIndex ) - { - int index = this.SourceIndexToPageEntryIndex( sourceIndex ); - - if( index != -1 ) - return this[ index ]; - - return null; - } - -#if DEBUG - public override string ToString() - { - string representation = string.Empty; - - if( !this.IsFilled ) - { - representation += "Fill Pending - "; - } - - if( this.IsEmpty ) - { - representation += m_startDataIndex.ToString() + " - EMPTY."; - } - else - { - representation += m_startDataIndex.ToString() + " - " + this.EndDataIndex.ToString(); - } - - return representation; - } -#endif - - public object[] ToItemArray() - { - int count = this.Count; - - object[] items = new object[ count ]; - - for( int i = 0; i < count; i++ ) - { - items[ i ] = this[ i ].DataItem; - } - - return items; - } - - internal bool LockPage() - { - m_lockCount++; - - // Returns True if the page just became locked (and is not up for removal) or False if the call simply incremented the lock count. - return m_lockCount == 1; - } - - internal bool UnlockPage() - { - if( m_lockCount > 0 ) - { - m_lockCount--; - } - else - { - // Safety Net. We return False, even though the lock count is reinitialized to zero, since the page did not just become unlocked. - // This can occur when the DataGridVirtualizingCollectionView hits ForceRefresh method restarts the VirtualItemBook, thus getting rid - // of locked and unlocked pages and THEN, the Generator's WeakEventListener of CollectionChanged cleans up its containers which in turn - // tries to unlock a source index which isn't locked at all (since it was cleared when the virtual item book reseted). - m_lockCount = 0; - return false; - } - - // Returns True if the page just became unlocked (and is up for removal) or False if the call simply decremented the lock count. - return m_lockCount == 0; - } - - internal void AbortQueryDataOperation() - { - Debug.Assert( !this.IsDisposed ); - - if( this.IsFilled ) - throw new InvalidOperationException( "An attempt was made to abort a query that has already completed." ); - - if( m_asyncQueryInfo != null ) - { - // This method can be reentered by another thread, while it's already being processed, with the result that the AbortQuery delegate may not be trigged by the CollectionView, - // and hence the client code not prevented it must abort the query/operation/connection. - lock( this ) - { - if( this.IsAborting ) - return; - - this.IsAborting = true; - } - - m_asyncQueryInfo.AbortQuery(); - } - } - - internal void QueueQueryData( Dispatcher dispatcher ) - { - Debug.Assert( !this.IsDisposed ); - Debug.Assert( m_asyncQueryInfo == null ); - - m_asyncQueryInfo = new AsyncQueryInfo( - dispatcher, - new Action( this.AsyncQueryInfo_BeginQueryItems ), - new Action( this.AsyncQueryInfo_AbortQueryItems ), - new Action( this.AsyncQueryInfo_EndQueryItems ), - new Action( this.AsyncQueryInfo_QueryErrorChanged ), - new Action( this.AsyncQueryInfo_BuiltInAbort ), - m_startDataIndex, - this.Count ); - - m_asyncQueryInfo.QueueQuery(); - } - - internal void EndQueryItems( AsyncQueryInfo asyncQueryInfo, object[] items ) - { - Debug.Assert( !this.IsDisposed ); - - // This can occur when the user notify us that the QueryData is completed for an AsyncQueryInfo.StartIndex that refers to a Page which does exists - // but that was removed, then re-created thus creating another asyncQueryInfo and queuing another QueryData. - // The only way to get rid of this situation would be to keep a ref to the queued asyncQueryInfo even if we get rid of the page and re-link the same instance to the newly - // created page. This optimization could be done in a future version. For now, let's return and the second asyncQueryInfo will take care of filling the newly created page. - if( m_asyncQueryInfo != asyncQueryInfo ) - { - Debug.Assert( false ); - - return; - } - - if( this.IsFilled ) - throw new InvalidOperationException( "An attempt was made to fill a virtual page that is already filled." ); - - if( items == null ) - throw new ArgumentNullException( "items" ); - - for( int i = 0; i < items.Length; i++ ) - { - VirtualizedItemInfo virtualizedItemInfo = this[ i ]; - - Debug.Assert( virtualizedItemInfo.DataItem is EmptyDataItem ); - Debug.Assert( virtualizedItemInfo.Index == ( m_startDataIndex + i ) ); - - this[ i ].DataItem = items[ i ]; - } - - this.IsFilled = true; - - Debug.WriteLineIf( VirtualPageManager.DebugDataVirtualization, "Page Filled - " + this.ToString() ); - } - - internal void QueueCommitData( Dispatcher dispatcher ) - { - Debug.Assert( !this.IsDisposed ); - - int count = this.Count; - - List dirtyItemInfoNotAlreadyPendingCommit = new List( count ); - - for( int i = 0; i < count; i++ ) - { - VirtualizedItemInfo virtualizedItemInfo = this[ i ]; - - if( ( virtualizedItemInfo.IsDirty ) && ( !this.IsAsyncCommitInfoQueuedForItem( virtualizedItemInfo.DataItem ) ) ) - { - Debug.WriteLineIf( VirtualPageManager.DebugDataVirtualization, "QueueCommitData for page " + this.ToString() + " and index " + virtualizedItemInfo.Index ); - - dirtyItemInfoNotAlreadyPendingCommit.Add( virtualizedItemInfo ); - } - } - - if( dirtyItemInfoNotAlreadyPendingCommit.Count > 0 ) - { - AsyncCommitInfo asyncCommitInfo = new AsyncCommitInfo( - dispatcher, - new Action( this.AsyncCommitInfo_BeginCommitItems ), - new Action( this.AsyncCommitInfo_EndCommitItems ), - new Action( this.AsyncCommitInfo_CommitErrorChanged ), - dirtyItemInfoNotAlreadyPendingCommit.ToArray() ); - - m_asyncCommitInfoList.Add( asyncCommitInfo ); - asyncCommitInfo.BeginCommit(); - } - } - - internal bool IsAsyncCommitInfoQueuedForItem( object item ) - { - int pendingAsyncCommitInfoCount = m_asyncCommitInfoList.Count; - - for( int i = 0; i < pendingAsyncCommitInfoCount; i++ ) - { - VirtualizedItemInfo[] pendingCommitVirtualizedItemInfos = m_asyncCommitInfoList[ i ].VirtualizedItemInfos; - - foreach( VirtualizedItemInfo pendingCommitVirtualizedItemInfo in pendingCommitVirtualizedItemInfos ) - { - if( pendingCommitVirtualizedItemInfo.DataItem == item ) - return true; - } - } - - return false; - } - - internal void EndCommitItems( AsyncCommitInfo asyncCommitInfo ) - { - Debug.Assert( !this.IsDisposed ); - Debug.Assert( m_asyncCommitInfoList.Contains( asyncCommitInfo ) ); - - VirtualizedItemInfo[] commitedItemInfos = asyncCommitInfo.VirtualizedItemInfos; - - for( int i = 0; i < commitedItemInfos.Length; i++ ) - { - commitedItemInfos[ i ].OldValues = null; - } - - m_asyncCommitInfoList.Remove( asyncCommitInfo ); - - asyncCommitInfo.Dispose(); - } - - internal void Restart() - { - if( !this.IsRestarting ) - { - Debug.WriteLineIf( VirtualPageManager.DebugDataVirtualization, "Restart VirtualPage requested for " + this.ToString() ); - - this.IsRestarting = true; - this.ParentVirtualList.OnVirtualPageRestarting( this ); - } - - // The page has finished commiting or aborting - if( ( !this.IsCommitPending ) && ( !this.IsAborting ) ) - { - this.EndRestart(); - } - } - - internal void EndRestart() - { - // VirtualPage will be disposed by the VirtualPageManager when it removes the page from is m_pageNodeList - Debug.WriteLineIf( VirtualPageManager.DebugDataVirtualization, "Restart VirtualPage completed for " + this.ToString() ); - - this.IsRestarting = false; - this.ParentVirtualList.OnVirtualPageRestarted( this ); - } - - private void AsyncQueryInfo_BuiltInAbort( AsyncQueryInfo queryInfo ) - { - if( this.IsDisposed ) - return; - - Debug.Assert( ( this.ParentVirtualList != null ) || ( this.ParentVirtualList.PagingManager != null ) ); - - this.ParentVirtualList.PagingManager.OnBuiltInAbort( this, queryInfo ); - this.IsAborting = false; - } - - private void AsyncQueryInfo_BeginQueryItems( AsyncQueryInfo queryInfo ) - { - if( this.IsDisposed ) - return; - - Debug.Assert( ( this.ParentVirtualList != null ) || ( this.ParentVirtualList.PagingManager != null ) ); - - this.ParentVirtualList.PagingManager.OnQueryItems( this, queryInfo ); - } - - private void AsyncQueryInfo_AbortQueryItems( AsyncQueryInfo queryInfo ) - { - if( this.IsDisposed ) - return; - - Debug.Assert( ( this.ParentVirtualList != null ) || ( this.ParentVirtualList.PagingManager != null ) ); - - this.ParentVirtualList.PagingManager.OnAbortQueryItems( this, queryInfo ); - - this.IsAborting = false; - - // If the page was removed, it was also disposed. This case means the page was not restarting - if( !this.RemoveAfterOperation && this.ParentVirtualList.IsRestarting ) - { - this.Restart(); - } - } - - private void AsyncQueryInfo_EndQueryItems( AsyncQueryInfo queryInfo, object[] fetchedItems ) - { - if( this.IsDisposed ) - return; - - Debug.Assert( ( this.ParentVirtualList != null ) || ( this.ParentVirtualList.PagingManager != null ) ); - Debug.Assert( !this.IsAborting ); - - // The page can be removed when the CollectionView raises a CollectionChanged and the selection is consequently updated, so make sure to lock it until the update operation is done. - this.LockPage(); - - this.ParentVirtualList.PagingManager.OnQueryItemsCompleted( this, queryInfo, fetchedItems ); - - this.UnlockPage(); - - if( this.ParentVirtualList.IsRestarting ) - { - this.Restart(); - } - } - - private void AsyncQueryInfo_QueryErrorChanged( AsyncQueryInfo queryInfo ) - { - if( this.IsDisposed ) - return; - - Debug.Assert( ( this.ParentVirtualList != null ) || ( this.ParentVirtualList.PagingManager != null ) ); - - this.ParentVirtualList.PagingManager.OnQueryErrorChanged( this, queryInfo ); - - if( this.ParentVirtualList.IsRestarting ) - { - this.Restart(); - } - } - - private void AsyncCommitInfo_BeginCommitItems( AsyncCommitInfo commitInfo ) - { - if( this.IsDisposed ) - return; - - Debug.Assert( ( this.ParentVirtualList != null ) || ( this.ParentVirtualList.PagingManager != null ) ); - - this.ParentVirtualList.PagingManager.OnCommitItems( this, commitInfo ); - } - - private void AsyncCommitInfo_EndCommitItems( AsyncCommitInfo commitInfo ) - { - if( this.IsDisposed ) - return; - - Debug.Assert( ( this.ParentVirtualList != null ) || ( this.ParentVirtualList.PagingManager != null ) ); - - this.ParentVirtualList.PagingManager.OnCommitItemsCompleted( this, commitInfo ); - - // Make sure the page has not been removed by the previous call before accessing the parent virtual list. - if( !this.IsDisposed && this.ParentVirtualList.IsRestarting ) - { - this.Restart(); - } - } - - private void AsyncCommitInfo_CommitErrorChanged( AsyncCommitInfo commitInfo ) - { - if( this.IsDisposed ) - return; - - Debug.Assert( ( this.ParentVirtualList != null ) || ( this.ParentVirtualList.PagingManager != null ) ); - - this.ParentVirtualList.PagingManager.OnCommitErrorChanged( this, commitInfo ); - - if( this.ParentVirtualList.IsRestarting ) - { - this.Restart(); - } - } - - private int SourceIndexToPageEntryIndex( int sourceIndex ) - { - if( ( this.Count != 0 ) && ( ( sourceIndex >= m_startDataIndex ) && ( sourceIndex <= this.EndDataIndex ) ) ) - return sourceIndex - m_startDataIndex; - - return -1; - } - - private bool ContainsItem( object item ) - { - int count = this.Count; - - for( int i = 0; i < count; i++ ) - { - if( this[ i ].DataItem == item ) - return true; - } - - return false; - } - - #region IDisposable Members - - public void Dispose() - { - Debug.Assert( !this.IsDisposed ); - Debug.Assert( ( m_asyncCommitInfoList != null ) && ( m_asyncCommitInfoList.Count == 0 ), "Some async commit are not completed while disposing VirtualPage" ); - - if( m_asyncQueryInfo != null ) - { - // We must dispose the AsyncQueryInfo to be sure it does not root this VirtualPage instance - m_asyncQueryInfo.Dispose(); - m_asyncQueryInfo = null; - } - - this.Clear(); - m_parentVirtualList = null; - - this.IsDisposed = true; - - } - - #endregion - - private BitVector32 m_flags; - - private int m_startDataIndex; - private int m_lockCount; - - private VirtualList m_parentVirtualList; - - public AsyncQueryInfo m_asyncQueryInfo; - private List m_asyncCommitInfoList; - - [Flags] - private enum VirtualItemPageFlags - { - IsFilled = 1, - IsDisposed = 2, - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(DataVirtualization)/VirtualPageManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(DataVirtualization)/VirtualPageManager.cs deleted file mode 100644 index 2969c085..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(DataVirtualization)/VirtualPageManager.cs +++ /dev/null @@ -1,817 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Collections.Specialized; -using System.Diagnostics; -using System.Windows.Threading; - -namespace Xceed.Wpf.DataGrid -{ - internal abstract class VirtualPageManager : IDisposable - { - internal static bool DebugDataVirtualization = false; - private const DispatcherPriority CommitDataPriority = DispatcherPriority.Input; - private const int EstimatedLockedPageCount = 3; - - public VirtualPageManager( Dispatcher dispatcher, int pageSize, int maxRealizedItemCount, double preemptivePageQueryRatio ) - { - if( dispatcher == null ) - throw new ArgumentNullException( "dispatcher" ); - - if( pageSize < 1 ) - throw new ArgumentOutOfRangeException( "pageSize", pageSize, "pageSize must be greater than zero." ); - - if( maxRealizedItemCount < pageSize ) - throw new ArgumentOutOfRangeException( "maxRealizedItemCount", maxRealizedItemCount, "maxRealizedItemCount must be greater than or equal to pageSize." ); - - m_managedLists = new List(); - m_pageNodes = new LinkedList(); - - this.Dispatcher = dispatcher; - - m_pageSize = pageSize; - m_maxRealizedItemCount = maxRealizedItemCount; - - m_maxRemovablePageCount = ( m_maxRealizedItemCount / m_pageSize ); - - m_preemptivePageQueryRatio = preemptivePageQueryRatio; - - this.IsConnected = true; - } - - #region Dispatcher Property - - public Dispatcher Dispatcher - { - get; - private set; - } - - #endregion - - #region PageSize Property - - public int PageSize - { - get - { - return m_pageSize; - } - } - - #endregion - - #region MaxRealizedItemCount Property - - public int MaxRealizedItemCount - { - get - { - return m_maxRealizedItemCount; - } - } - - #endregion - - #region PreemptivePageQueryRatio Property - - public double PreemptivePageQueryRatio - { - get - { - return m_preemptivePageQueryRatio; - } - set - { - m_preemptivePageQueryRatio = value; - } - } - - #endregion - - #region ManagedLists Property - - public ReadOnlyCollection ManagedLists - { - get - { - if( m_readOnlyManagedLists == null ) - { - m_readOnlyManagedLists = new ReadOnlyCollection( m_managedLists ); - } - - return m_readOnlyManagedLists; - } - } - - #endregion - - #region IsDisposed Property - - protected bool IsDisposed - { - get - { - return m_flags[ ( int )VirtualPageManagerFlags.IsDisposed ]; - } - private set - { - m_flags[ ( int )VirtualPageManagerFlags.IsDisposed ] = value; - } - } - - #endregion - - #region EstimatedTotalPageCount Property - - internal int EstimatedTotalPageCount - { - get - { - return m_maxRemovablePageCount + VirtualPageManager.EstimatedLockedPageCount; - } - } - - #endregion - - #region Version Property - - internal int Version - { - get - { - return m_version; - } - } - - #endregion - - #region IsConnected Property - - internal bool IsConnected - { - get - { - return m_flags[ ( int )VirtualPageManagerFlags.IsConnected ]; - } - private set - { - m_flags[ ( int )VirtualPageManagerFlags.IsConnected ] = value; - } - } - - #endregion - - #region RestartingManager Property - - private bool RestartingManager - { - get - { - return m_flags[ ( int )VirtualPageManagerFlags.RestartingManager ]; - } - set - { - m_flags[ ( int )VirtualPageManagerFlags.RestartingManager ] = value; - } - } - - #endregion - - #region ShouldRefreshAfterRestart Property - - private bool ShouldRefreshAfterRestart - { - get - { - return m_flags[ ( int )VirtualPageManagerFlags.ShouldRefreshAfterRestart ]; - } - set - { - m_flags[ ( int )VirtualPageManagerFlags.ShouldRefreshAfterRestart ] = value; - } - } - - #endregion - - #region LastRemovable Property - - private LinkedListNode LastRemovable - { - get - { - LinkedListNode lastRemovableNode = m_pageNodes.Last; - - while( lastRemovableNode != null ) - { - Debug.Assert( lastRemovableNode.Value != null ); - - VirtualPage page = lastRemovableNode.Value; - - if( page.IsRemovable ) - return lastRemovableNode; - - lastRemovableNode = lastRemovableNode.Previous; - } - - return lastRemovableNode; - } - } - - #endregion - - protected abstract int OnQueryItemCountCore( VirtualList virtualList ); - - protected virtual void OnVirtualPageManagerRestarting() - { - } - - protected virtual void OnVirtualPageManagerRestarted( bool shouldRefresh ) - { - } - - protected virtual void EndRestart() - { - this.RestartingManager = false; - - Debug.WriteLineIf( VirtualPageManager.DebugDataVirtualization, "VirtualPageManager (" + this.GetHashCode() + ")- All virtual Lists restarted." ); - - this.OnVirtualPageManagerRestarted( this.ShouldRefreshAfterRestart ); - this.ShouldRefreshAfterRestart = false; - } - - protected internal abstract void OnBuiltInAbort( VirtualPage virtualPage, AsyncQueryInfo queryInfo ); - - protected internal virtual int OnQueryItemCount( VirtualList virtualList ) - { - return this.OnQueryItemCountCore( virtualList ); - } - - protected internal abstract void OnQueryItems( VirtualPage page, AsyncQueryInfo queryInfo ); - - protected internal virtual void OnAbortQueryItems( VirtualPage page, AsyncQueryInfo queryInfo ) - { - } - - protected internal virtual void OnQueryItemsCompleted( VirtualPage page, AsyncQueryInfo queryInfo, object[] fetchedItems ) - { - this.IncrementVersion(); - - page.ParentVirtualList.FillEmptyPage( queryInfo, fetchedItems ); - } - - protected internal virtual void OnCommitItems( VirtualPage page, AsyncCommitInfo commitInfo ) - { - } - - protected internal virtual void OnCommitItemsCompleted( VirtualPage page, AsyncCommitInfo commitInfo ) - { - page.ParentVirtualList.NotifyCommitComplete( commitInfo ); - } - - protected internal virtual void OnQueryErrorChanged( VirtualPage page, AsyncQueryInfo queryInfo ) - { - } - - protected internal virtual void OnCommitErrorChanged( VirtualPage page, AsyncCommitInfo commitInfo ) - { - } - - internal virtual void OnVirtualListRestarting( VirtualList virtualList ) - { - Debug.Assert( m_managedLists.Contains( virtualList ) ); - Debug.Assert( this.RestartingManager, "Until CollectionViewGroups can be virtualized, we should not be restarting a leaf list on its own." ); - } - - internal virtual void OnVirtualListRestarted( VirtualList virtualList ) - { - Debug.Assert( m_managedLists.Contains( virtualList ) ); - Debug.Assert( this.RestartingManager, "Until CollectionViewGroups can be virtualized, we should not be restarting a leaf list on its own." ); - - if( this.RestartingManager ) - { - m_restartingListsCount--; - } - - // Make sure that no page nodes belonging to this virtual list are left in the linked list. Remove all remaining ones since after the manager is restarted, its content is completely cleared. - LinkedListNode pageNode = m_pageNodes.Last; - while( pageNode != null ) - { - LinkedListNode previousNode = pageNode.Previous; - - if( pageNode.Value.ParentVirtualList == virtualList ) - throw new DataGridInternalException( "A VirtualPage was not remove from its parent VirtualList after it is restarted" ); - - pageNode = previousNode; - } - - this.IncrementVersion(); - - // If the manager is restarting, no page left and no more list restarting - if( this.RestartingManager && ( m_pageNodes.Count == 0 ) && ( m_restartingListsCount == 0 ) ) - { - this.EndRestart(); - } - } - - internal virtual void OnVirtualListPageRestarting( VirtualList virtualList, VirtualPage page ) - { - Debug.Assert( m_managedLists.Contains( virtualList ) ); - - LinkedListNode pageNode = m_pageNodes.Find( page ); - - Debug.Assert( pageNode != null ); - - // RemovePageNode takes care of either raising the AbortQueryData event or aborting the QueryData Dispatcher Operation altogether. - // It also takes care of raising the CommitVirtualData event for loaded pages which contains modified data. - this.QueueCommitDataOrAbortIfRequired( pageNode, false ); - } - - internal virtual void OnVirtualListPageRestarted( VirtualList virtualList, VirtualPage page ) - { - Debug.Assert( m_managedLists.Contains( virtualList ) ); - Debug.Assert( m_pageNodes.Contains( page ) ); - - this.RemovePage( page ); - } - - internal void QueueQueryData( VirtualPage page ) - { - Debug.Assert( m_managedLists.Contains( page.ParentVirtualList ) ); - - page.QueueQueryData( this.Dispatcher ); - } - - internal void QueueCommitData( VirtualPage page ) - { - Debug.WriteLineIf( VirtualPageManager.DebugDataVirtualization, "QueueCommitData for page " + page.ToString() ); - Debug.Assert( m_managedLists.Contains( page.ParentVirtualList ) ); - Debug.Assert( page.IsFilled ); - Debug.Assert( page.IsDirty ); - - if( this.RestartingManager ) - { - this.ShouldRefreshAfterRestart = true; - } - - page.QueueCommitData( this.Dispatcher ); - } - - internal List> GetUnlockedPendingFillNodes() - { - List> unlockedPendingFillNodes = new List>(); - - LinkedListNode lastUnlockedPendingFillNode = m_pageNodes.Last; - - while( lastUnlockedPendingFillNode != null ) - { - VirtualPage page = lastUnlockedPendingFillNode.Value; - - Debug.Assert( page != null ); - - if( ( !page.IsLocked ) && ( !page.IsFilled ) ) - { - unlockedPendingFillNodes.Add( lastUnlockedPendingFillNode ); - } - - lastUnlockedPendingFillNode = lastUnlockedPendingFillNode.Previous; - } - - return unlockedPendingFillNodes; - } - - internal void CleanUpAndDisposeUnused() - { - // Remove the less used unlocked pages. This will also ask to save it. - - // Also remove all pending fill pages which are not locked wether or not we are under the max unlocked page count. - // This is so the abort query event is raised so that the user can abort his fetching of data. - - // Start with the unlocked pending fill pages since it is mandatory to remove them all in order to abort the async data fetching. - // The first node in the list returned by the GetUnlockedPendingFillNodes method is the oldest one, so we can start removing from the beginning of the returned list. - List> unlockedPendingFillNodes = this.GetUnlockedPendingFillNodes(); - - int unlockedPendingFillCount = unlockedPendingFillNodes.Count; - - for( int i = 0; i < unlockedPendingFillCount; i++ ) - { - this.QueueCommitDataOrAbortIfRequired( unlockedPendingFillNodes[ i ], true ); - } - - // Then, move on to removing the other unlocked pages not up for commit, if we are above the max item in memory limit. There should not be any pending fill pages left which are not locked. - int removablePageItemCount = this.GetRemovablePageItemCount(); - - while( removablePageItemCount > m_maxRealizedItemCount ) - { - LinkedListNode lastRemovable = this.LastRemovable; - - Debug.Assert( lastRemovable != null ); - - removablePageItemCount -= lastRemovable.Value.Count; - - this.QueueCommitDataOrAbortIfRequired( lastRemovable, true ); - } - } - - internal void RemovePage( VirtualPage page ) - { - if( page.IsDisposed ) - return; - - Debug.Assert( page != null ); - Debug.Assert( !page.IsDirty ); - - // A filled page is being removed. Change the version. - this.IncrementVersion(); - - // Update the table of content of the page's ParentVirtualList - page.ParentVirtualList.TableOfContent.RemovePage( page ); - - m_pageNodes.Remove( page ); - - Debug.WriteLineIf( VirtualPageManager.DebugDataVirtualization, "Removed Page: " + page.ToString() ); - - // Dispose the page since it will never be reused - page.Dispose(); - } - - internal void MovePageToFront( VirtualPage page ) - { - // The further from the front a page is, the longer it has been since it was requested. - Debug.Assert( page != null ); - - LinkedListNode firstNode = m_pageNodes.First; - - if( firstNode.Value != page ) - { - LinkedListNode node = m_pageNodes.Find( page ); - m_pageNodes.Remove( node ); - m_pageNodes.AddFirst( node ); - - Debug.WriteLineIf( VirtualPageManager.DebugDataVirtualization, "Moved To Front: Page " + page.ToString() ); - } - } - - internal void AddPage( VirtualPage page, PageInsertPosition insertPosition ) - { - if( page == null ) - throw new ArgumentNullException( "page", "TODOOC: An internal error occured while paging data. Page cannot be null." ); - - // We call clean-up before the call to AddFirst since if we do it afterward and the page is pending fill, we will remove it. - this.CleanUpAndDisposeUnused(); - - if( insertPosition == PageInsertPosition.Front ) - { - m_pageNodes.AddFirst( page ); - } - else - { - m_pageNodes.AddLast( page ); - } - - Debug.WriteLineIf( VirtualPageManager.DebugDataVirtualization, "Added To " + ( ( insertPosition == PageInsertPosition.Front ) ? "Front" : "Back" ) + ": Page " + page.ToString() ); - } - - internal void Restart() - { - if( this.RestartingManager ) - return; - - this.RestartingManager = true; - - Debug.WriteLineIf( VirtualPageManager.DebugDataVirtualization, "VirtualPageManager (" + this.GetHashCode() + ") - Restarting all virtual Lists. " ); - - this.OnVirtualPageManagerRestarting(); - - if( m_managedLists.Count == 0 ) - { - // No pages, restart is completed - this.EndRestart(); - } - else - { - m_restartingListsCount = m_managedLists.Count; - int managedListCount = m_managedLists.Count; - - // Restart all VirtualLists - for( int i = managedListCount - 1; i >= 0; i-- ) - { - VirtualList virtualList = m_managedLists[ i ]; - virtualList.Restart(); - } - } - } - - internal void Disconnect() - { - this.IsConnected = false; - } - - internal void ManageList( VirtualList virtualList ) - { - Debug.Assert( !m_managedLists.Contains( virtualList ) ); - Debug.Assert( virtualList.VirtualPagingManager == null ); - - virtualList.VirtualPagingManager = this; - - this.m_managedLists.Add( virtualList ); - } - - internal bool IsAsyncCommitQueuedForItem( object item ) - { - LinkedListNode pageNode = m_pageNodes.First; - - while( pageNode != null ) - { - VirtualList virtualList = pageNode.Value.ParentVirtualList; - - Debug.Assert( m_managedLists.Contains( virtualList ) ); - - if( virtualList.IsAsyncCommitQueuedForItem( item ) ) - { - Debug.Assert( !( item is EmptyDataItem ), "A commit operation should not have been queued for an EmptyDataItem." ); - - return true; - } - - pageNode = pageNode.Next; - } - - return false; - } - - internal bool IsItemDirty( object item ) - { - LinkedListNode pageNode = m_pageNodes.First; - - while( pageNode != null ) - { - VirtualList virtualList = pageNode.Value.ParentVirtualList; - - Debug.Assert( m_managedLists.Contains( virtualList ) ); - - if( virtualList.IsItemDirty( item ) ) - { - Debug.Assert( !( item is EmptyDataItem ), "An EmptyDataItem should not have been flagged as dirty." ); - - return true; - } - - pageNode = pageNode.Next; - } - - return false; - } - - internal void SetCachedValuesForItem( object item, string[] names, object[] values ) - { - LinkedListNode pageNode = m_pageNodes.First; - - while( pageNode != null ) - { - VirtualList virtualList = pageNode.Value.ParentVirtualList; - - Debug.Assert( m_managedLists.Contains( virtualList ) ); - - int localIndex = virtualList.IndexOf( item ); - - if( localIndex != -1 ) - { - virtualList.SetCachedValuesForItemAtIndex( localIndex, names, values ); - return; - } - - pageNode = pageNode.Next; - } - - throw new InvalidOperationException( "An attempt was made to begin the edit process on an unknown item." ); - } - - internal VirtualizedItemValueCollection GetCachedValuesForItem( object item ) - { - LinkedListNode pageNode = m_pageNodes.First; - - while( pageNode != null ) - { - VirtualList virtualList = pageNode.Value.ParentVirtualList; - - Debug.Assert( m_managedLists.Contains( virtualList ) ); - - int localIndex = virtualList.IndexOf( item ); - - if( localIndex != -1 ) - return virtualList.GetCachedValuesForItemAtIndex( localIndex ); - - pageNode = pageNode.Next; - } - - return null; - } - - internal void ClearCachedValuesForItem( object item ) - { - LinkedListNode pageNode = m_pageNodes.First; - - while( pageNode != null ) - { - VirtualList virtualList = pageNode.Value.ParentVirtualList; - - Debug.Assert( m_managedLists.Contains( virtualList ) ); - - int localIndex = virtualList.IndexOf( item ); - - if( localIndex != -1 ) - { - virtualList.ClearCachedValuesForItemAtIndex( localIndex ); - return; - } - - pageNode = pageNode.Next; - } - - throw new InvalidOperationException( "An attempt was made to leave the edit process on an unknown item." ); - } - - internal void CommitAll() - { - List currentVirtualLists = new List( m_pageNodes.Count ); - - LinkedListNode pageNode = m_pageNodes.First; - - // Scan all in memory pages to build a list of unique VirtualLists which currently have items loaded in memory. - while( pageNode != null ) - { - VirtualList virtualList = pageNode.Value.ParentVirtualList; - - Debug.Assert( m_managedLists.Contains( virtualList ) ); - - if( !currentVirtualLists.Contains( virtualList ) ) - { - currentVirtualLists.Add( virtualList ); - } - - pageNode = pageNode.Next; - } - - int currentVirtualListCount = currentVirtualLists.Count; - - for( int i = 0; i < currentVirtualListCount; i++ ) - { - currentVirtualLists[ i ].CommitAll(); - } - } - - private int GetRemovablePageCount() - { - int removablePageCount = 0; - - LinkedListNode pageNode = m_pageNodes.Last; - - while( pageNode != null ) - { - VirtualPage page = pageNode.Value; - - Debug.Assert( page != null ); - - if( ( page != null ) && ( page.IsRemovable ) ) - { - removablePageCount++; - } - - pageNode = pageNode.Previous; - } - - return removablePageCount; - } - - private int GetRemovablePageItemCount() - { - int removablePageItemCount = 0; - - LinkedListNode pageNode = m_pageNodes.Last; - - while( pageNode != null ) - { - VirtualPage page = pageNode.Value; - - Debug.Assert( page != null ); - - if( ( page != null ) && ( page.IsRemovable ) ) - { - removablePageItemCount += page.Count; - } - - pageNode = pageNode.Previous; - } - - return removablePageItemCount; - } - - private void QueueCommitDataOrAbortIfRequired( LinkedListNode pageNode, bool removeAfterOperation ) - { - VirtualPage page = pageNode.Value; - - // Update the flag in case this page must be removed after an abort or commit operation - page.RemoveAfterOperation = removeAfterOperation; - - // The only circumstance when we should remove a page which is not removable is if we are restarting. - Debug.Assert( ( page != null ) && ( !page.IsDisposed ) && ( ( page.IsRemovable ) || ( page.ParentVirtualList.IsRestarting ) ) ); - - if( page.IsDirty ) - { - // Don't remove pages which contains modifications. We'll remove them from the book when they are committed, if they aren't locked. - this.QueueCommitData( page ); - } - else if( !page.IsFilled ) - { - // The page is not filled, we must send abort the QueryData for this page in case it was sent - page.AbortQueryDataOperation(); - } - - // The page must be removed after operation and it has nothing to commit and is not currently aborting an operation. It is safe to remove it - if( removeAfterOperation && !page.IsCommitPending && !page.IsAborting ) - { - this.RemovePage( page ); - } - } - - private void IncrementVersion() - { - unchecked - { - m_version++; - } - } - - #region IDisposable Members - - public void Dispose() - { - - this.DisposeCore(); - - } - - protected virtual void DisposeCore() - { - if( m_managedLists != null ) - { - m_managedLists.Clear(); - } - - if( m_pageNodes != null ) - { - m_pageNodes.Clear(); - } - - this.IsDisposed = true; - } - - #endregion - - private int m_version; - private int m_restartingListsCount; - - private BitVector32 m_flags = new BitVector32(); - - private LinkedList m_pageNodes; - - private List m_managedLists; - private ReadOnlyCollection m_readOnlyManagedLists; - - private int m_pageSize; - private int m_maxRealizedItemCount; - private double m_preemptivePageQueryRatio; - private int m_maxRemovablePageCount; - - internal enum PageInsertPosition - { - Front = 0, - Back = 1 - } - - private enum VirtualPageManagerFlags - { - RestartingManager = 1, - ShouldRefreshAfterRestart = 2, - IsDisposed = 4, - IsConnected = 8, - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(DataVirtualization)/VirtualizedItemInfo.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(DataVirtualization)/VirtualizedItemInfo.cs deleted file mode 100644 index 4e5f8753..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(DataVirtualization)/VirtualizedItemInfo.cs +++ /dev/null @@ -1,100 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - public class VirtualizedItemInfo - { - #region CONSTRUCTORS - - internal VirtualizedItemInfo( int index, object dataItem ) - { - m_dataIndex = index; - m_dataItem = dataItem; - } - - #endregion CONSTRUCTORS - - #region DataItem Property - - public object DataItem - { - get - { - return m_dataItem; - } - internal set - { - m_dataItem = value; - } - } - - #endregion DataItem Property - - #region Index Property - - public int Index - { - get - { - return m_dataIndex; - } - } - - #endregion Index Property - - #region OldValues Property - - public VirtualizedItemValueCollection OldValues - { - get - { - return m_oldValues; - } - internal set - { - m_oldValues = value; - } - } - - #endregion OldValues Property - - #region INTERNAL PROPERTIES - - internal bool IsDirty - { - get - { - return m_oldValues != null; - } - } - - #endregion INTERNAL PROPERTIES - - #region PRIVATE FIELDS - - private object m_dataItem; - private int m_dataIndex; - private VirtualizedItemValueCollection m_oldValues; - - #endregion PRIVATE FIELDS - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(DataVirtualization)/VirtualizedItemValueCollection.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(DataVirtualization)/VirtualizedItemValueCollection.cs deleted file mode 100644 index 66b1a76e..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(DataVirtualization)/VirtualizedItemValueCollection.cs +++ /dev/null @@ -1,153 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Collections; - -namespace Xceed.Wpf.DataGrid -{ - public class VirtualizedItemValueCollection : ICollection - { - internal VirtualizedItemValueCollection( string[] names, object[] values ) - { - if( names.Length != values.Length ) - throw new ArgumentException( "Names and Values must be of the same length." ); - - m_nameValueDictionary = new Dictionary( names.Length ); - m_valueList = new List( values.Length ); - - for( int i = 0; i < names.Length; i++ ) - { - object value = values[ i ]; - m_nameValueDictionary.Add( names[ i ], value ); - m_valueList.Add( value ); - } - - } - - public object this[ int index ] - { - get - { - if( ( index < 0 ) || ( index >= m_valueList.Count ) ) - throw new ArgumentOutOfRangeException( "index", index, "The index must be greater than or equal to zero and less than count." ); - - return m_valueList[ index ]; - } - } - - public object this[ string name ] - { - get - { - if( name == null ) - throw new ArgumentNullException( "name" ); - - if( name == string.Empty ) - throw new ArgumentException( "name" ); - - object val; - - if( !m_nameValueDictionary.TryGetValue( name, out val ) ) - throw new ArgumentException( "No value could be found for the specified property name." ); - - return val; - } - } - - public int Count - { - get - { - return m_valueList.Count; - } - } - - #region PRIVATE FIELDS - - private Dictionary m_nameValueDictionary; - private List m_valueList; - - #endregion PRIVATE FIELDS - - - #region ICollection Members - - public void CopyTo( Array array, int index ) - { - if( array == null ) - throw new ArgumentNullException( "array" ); - - if( array.Rank != 1 ) - throw new NotSupportedException( "Multi-dimensional arrays are not supported." ); - - if( index < 0 ) - throw new ArgumentOutOfRangeException( "index", index, "index must be greater than or equal to zero." ); - - int count = this.Count; - - if( ( array.Length - index ) < count ) - throw new ArgumentException( "Invalid offset position." ); - - if( array is object[] ) - { - object[] objects = ( object[] )array; - - for( int i = 0; i < count; i++ ) - { - objects[ i + index ] = m_valueList[ i ]; - } - } - else - { - for( int i = 0; i < count; i++ ) - { - array.SetValue( m_valueList[ i ], ( i + index ) ); - } - } - } - - public bool IsSynchronized - { - get - { - return false; - } - } - - public object SyncRoot - { - get - { - return this; - } - } - - #endregion - - #region IEnumerable Members - - public IEnumerator GetEnumerator() - { - return m_valueList.GetEnumerator(); - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(ForeignKeys)/DataGridForeignKeyDescription.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(ForeignKeys)/DataGridForeignKeyDescription.cs deleted file mode 100644 index 0abec623..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(ForeignKeys)/DataGridForeignKeyDescription.cs +++ /dev/null @@ -1,226 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Data; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - public class DataGridForeignKeyDescription : DependencyObject - { - public DataGridForeignKeyDescription() - { - this.SetForeignKeyConverter(); - } - - #region ForeignKeyConverter Property - - public static readonly DependencyProperty ForeignKeyConverterProperty = DependencyProperty.Register( - "ForeignKeyConverter", - typeof( ForeignKeyConverter ), - typeof( DataGridForeignKeyDescription ), - new FrameworkPropertyMetadata( null ) ); - - public ForeignKeyConverter ForeignKeyConverter - { - get - { - return ( ForeignKeyConverter )this.GetValue( DataGridForeignKeyDescription.ForeignKeyConverterProperty ); - } - set - { - this.SetValue( DataGridForeignKeyDescription.ForeignKeyConverterProperty, value ); - } - } - - #endregion - - #region ItemsSource Property - - public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register( - "ItemsSource", - typeof( IEnumerable ), - typeof( DataGridForeignKeyDescription ), - new FrameworkPropertyMetadata( null ) ); - - public IEnumerable ItemsSource - { - get - { - return ( IEnumerable )this.GetValue( DataGridForeignKeyDescription.ItemsSourceProperty ); - } - set - { - this.SetValue( DataGridForeignKeyDescription.ItemsSourceProperty, value ); - } - } - - #endregion - - #region IsAutoCreated Internal Property - - internal bool IsAutoCreated - { - get; - set; - } - - #endregion - - #region ValuePath Property - - public static readonly DependencyProperty ValuePathProperty = DependencyProperty.Register( - "ValuePath", - typeof( string ), - typeof( DataGridForeignKeyDescription ), - new FrameworkPropertyMetadata( null ) ); - - public string ValuePath - { - get - { - return ( string )this.GetValue( DataGridForeignKeyDescription.ValuePathProperty ); - } - set - { - this.SetValue( DataGridForeignKeyDescription.ValuePathProperty, value ); - } - } - - #endregion - - #region DisplayMemberPath Property - - public static readonly DependencyProperty DisplayMemberPathProperty = DependencyProperty.Register( - "DisplayMemberPath", - typeof( string ), - typeof( DataGridForeignKeyDescription ), - new FrameworkPropertyMetadata( null ) ); - - public string DisplayMemberPath - { - get - { - return ( string )this.GetValue( DataGridForeignKeyDescription.DisplayMemberPathProperty ); - } - set - { - this.SetValue( DataGridForeignKeyDescription.DisplayMemberPathProperty, value ); - } - } - - #endregion - - protected virtual void SetForeignKeyConverter() - { - this.ForeignKeyConverter = new DataGridForeignKeyConverter(); - } - - internal Type GetDataType() - { - var itemsSource = this.ItemsSource; - if( itemsSource == null ) - return null; - - var displayMemberPath = this.DisplayMemberPath; - var foreignKeyConverter = this.ForeignKeyConverter; - - if( string.IsNullOrWhiteSpace( displayMemberPath ) && ( foreignKeyConverter == null ) ) - return null; - - try - { - //Use the DisplayMemberPath or the ForeignKeyConverter to find the converted value data type, using a DataRowView or reflection. - if( ( itemsSource is DataView ) || ( itemsSource is DataTable ) ) - { - foreach( object item in itemsSource ) - { - var dataRowView = item as DataRowView; - if( dataRowView == null ) - continue; - - if( !string.IsNullOrWhiteSpace( displayMemberPath ) ) - { - var dataColumn = dataRowView.Row.Table.Columns[ displayMemberPath ]; - if( dataColumn != null ) - { - return dataColumn.DataType; - } - } - else - { - var valuePath = this.ValuePath; - if( valuePath != null ) - { - var key = dataRowView[ valuePath ]; - var value = foreignKeyConverter.GetValueFromKey( key, this ); - if( value != null ) - { - return value.GetType(); - } - } - } - } - } - else - { - foreach( object item in itemsSource ) - { - if( item == null ) - continue; - - if( !string.IsNullOrWhiteSpace( displayMemberPath ) ) - return item.GetType().GetProperty( displayMemberPath ).PropertyType; - - if( item is Enum ) - return item.GetType(); - - var valuePath = this.ValuePath; - if( valuePath != null ) - { - var key = item.GetType().GetProperty( valuePath ).GetValue( item, null ); - var value = foreignKeyConverter.GetValueFromKey( key, this ); - if( value != null ) - { - return value.GetType(); - } - } - } - } - } - catch - { - //Swallow the exception, no need to terminate the application, since the original value will be exported. - } - - return null; - } - - internal object GetDisplayValue( object fieldValue ) - { - if( fieldValue == null ) - return null; - - var foreignKeyConverter = this.ForeignKeyConverter; - if( foreignKeyConverter != null ) - return foreignKeyConverter.GetValueFromKey( fieldValue, this ); - - return fieldValue; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(ForeignKeys)/DataTableForeignKeyDescription.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(ForeignKeys)/DataTableForeignKeyDescription.cs deleted file mode 100644 index 816d0cd3..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/(ForeignKeys)/DataTableForeignKeyDescription.cs +++ /dev/null @@ -1,113 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Data; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - public class DataTableForeignKeyDescription : DataGridForeignKeyDescription - { - public DataTableForeignKeyDescription() - { - } - - internal DataTableForeignKeyDescription( ForeignKeyConstraint constraint ) - : this() - { - this.ForeignKeyConstraint = constraint; - } - - #region ForeignKeyConstraint Property - - public static readonly DependencyProperty ForeignKeyConstraintProperty = DependencyProperty.Register( - "ForeignKeyConstraint", - typeof( ForeignKeyConstraint ), - typeof( DataTableForeignKeyDescription ), - new FrameworkPropertyMetadata( - null, - new PropertyChangedCallback( DataTableForeignKeyDescription.OnForeignKeyConstraintChanged ) ) ); - - public ForeignKeyConstraint ForeignKeyConstraint - { - get - { - return ( ForeignKeyConstraint )this.GetValue( DataTableForeignKeyDescription.ForeignKeyConstraintProperty ); - } - set - { - this.SetValue( DataTableForeignKeyDescription.ForeignKeyConstraintProperty, value ); - } - } - - private static void OnForeignKeyConstraintChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var foreignKeyDescription = sender as DataTableForeignKeyDescription; - if( foreignKeyDescription != null ) - { - foreignKeyDescription.UpdateValuePath(); - foreignKeyDescription.UpdateItemsSource(); - } - } - - #endregion - - protected override void SetForeignKeyConverter() - { - this.ForeignKeyConverter = new DataTableForeignKeyConverter(); - } - - private void UpdateValuePath() - { - // Affect the ValuePath if it was not explicitly set or bound - var valuePath = this.ReadLocalValue( ValuePathProperty ); - - if( string.IsNullOrEmpty( this.ValuePath ) - && ( ( valuePath == DependencyProperty.UnsetValue ) - || ( valuePath == null ) ) ) - { - var foreignKeyConstraint = this.ForeignKeyConstraint; - - // Affect the FieldName to the first RelatedColumn's name - // if there is only one DataColumn in the RelatedColumns Collection - if( ( foreignKeyConstraint != null ) - && ( foreignKeyConstraint.RelatedColumns != null ) - && ( foreignKeyConstraint.RelatedColumns.Length == 1 ) ) - { - var foreignFieldName = foreignKeyConstraint.RelatedColumns[ 0 ].ColumnName; - - if( !string.IsNullOrEmpty( foreignFieldName ) ) - { - this.ValuePath = foreignFieldName; - } - } - } - } - - private void UpdateItemsSource() - { - var foreignKeyConstraint = this.ForeignKeyConstraint; - if( foreignKeyConstraint == null ) - return; - - var relatedTable = foreignKeyConstraint.RelatedTable; - if( relatedTable == null ) - return; - - this.ItemsSource = relatedTable.DefaultView; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/AsyncCommitInfo.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/AsyncCommitInfo.cs deleted file mode 100644 index 856743ea..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/AsyncCommitInfo.cs +++ /dev/null @@ -1,187 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows.Threading; -using System.Diagnostics; - -namespace Xceed.Wpf.DataGrid -{ - public class AsyncCommitInfo : IDisposable - { - #region STATIC MEMBERS - - - #endregion STATIC MEMBERS - - #region CONSTRUCTORS - - internal AsyncCommitInfo( - Dispatcher dispatcher, - Action beginCommitDelegate, - Action endCommitDelegate, - Action commitErrorChangedDelegate, - VirtualizedItemInfo[] virtualizedItemInfos ) - { - m_dispatcher = dispatcher; - - m_beginCommitDelegate = beginCommitDelegate; - m_endCommitDelegate = endCommitDelegate; - m_commitErrorChangedDelegate = commitErrorChangedDelegate; - - m_virtualizedItemInfos = virtualizedItemInfos; - } - - #endregion CONSTRUCTORS - - - #region Items Property - - public VirtualizedItemInfo[] VirtualizedItemInfos - { - get - { - return m_virtualizedItemInfos; - } - } - - #endregion Items Property - - #region AsyncState Property - - public object AsyncState - { - get; - set; - } - - #endregion AsyncState Property - - #region Error Property - - public object Error - { - get - { - return m_error; - } - set - { - Debug.Assert( !this.IsDisposed ); - - if( m_error != value ) - { - m_error = value; - - if( m_commitErrorChangedDelegate != null ) - { - m_dispatcher.Invoke( - DispatcherPriority.Send, - m_commitErrorChangedDelegate, - this ); - } - } - } - } - - #endregion Error Property - - #region IsDisposed Internal Property - - internal bool IsDisposed - { - get - { - return m_isDisposed; - } - } - - #endregion - - - #region PUBLIC METHODS - - public void EndCommit() - { - Debug.Assert( !this.IsDisposed ); - - if( m_commitEndedDispatched ) - throw new InvalidOperationException( "An attempt was made to call EndCommit when it has already been called for this AsyncCommitInfo." ); - - m_dispatcher.BeginInvoke( - DispatcherPriority.Send, - m_endCommitDelegate, - this ); - - m_commitEndedDispatched = true; - } - - #endregion PUBLIC METHODS - - #region INTERNAL METHODS - - internal void BeginCommit() - { - Debug.Assert( !this.IsDisposed ); - - m_dispatcher.BeginInvoke( - DispatcherPriority.Background, - m_beginCommitDelegate, - this ); - } - - #endregion INTERNAL METHODS - - #region PRIVATE FIELDS - - private VirtualizedItemInfo[] m_virtualizedItemInfos; - private bool m_commitEndedDispatched; - private bool m_isDisposed; - - private object m_error; - - private Dispatcher m_dispatcher; - private Action m_beginCommitDelegate; - private Action m_endCommitDelegate; - private Action m_commitErrorChangedDelegate; - - #endregion PRIVATE FIELDS - - #region IDisposable Members - - public void Dispose() - { - if( m_isDisposed ) - { - Debug.Assert( false, "The AsyncQueryInfo is disposed" ); - return; - } - - m_dispatcher = null; - - m_beginCommitDelegate = null; - m_endCommitDelegate = null; - m_commitErrorChangedDelegate = null; - - m_isDisposed = true; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/AsyncQueryInfo.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/AsyncQueryInfo.cs deleted file mode 100644 index e06f09cf..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/AsyncQueryInfo.cs +++ /dev/null @@ -1,297 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Specialized; -using System.Diagnostics; -using System.Windows.Threading; - -namespace Xceed.Wpf.DataGrid -{ - public class AsyncQueryInfo : IDisposable - { - internal AsyncQueryInfo( - Dispatcher dispatcher, - Action beginQueryDelegate, - Action abortQueryDelegate, - Action endQueryDelegate, - Action queryErrorChangedDelegate, - Action builtInAbortDelegate, - int startIndex, - int requestedItemCount ) - { - m_dispatcher = dispatcher; - m_builtInAbortDelegate = builtInAbortDelegate; - m_beginQueryDelegate = beginQueryDelegate; - m_abortQueryDelegate = abortQueryDelegate; - m_endQueryDelegate = endQueryDelegate; - - m_queryErrorChangedDelegate = queryErrorChangedDelegate; - - m_startIndex = startIndex; - m_requestedItemCount = requestedItemCount; - } - - #region StartIndex Property - - public int StartIndex - { - get - { - return m_startIndex; - } - } - - #endregion - - #region RequestedItemCount Property - - public int RequestedItemCount - { - get - { - return m_requestedItemCount; - } - } - - #endregion - - #region AsyncState Property - - public object AsyncState - { - get; - set; - } - - #endregion - - #region Error Property - - public object Error - { - get - { - return m_error; - } - set - { - Debug.Assert( !this.IsDisposed ); - - if( m_error != value ) - { - m_error = value; - - if( m_queryErrorChangedDelegate != null ) - { - m_dispatcher.Invoke( DispatcherPriority.Send, m_queryErrorChangedDelegate, this ); - } - } - } - } - - #endregion - - #region ShouldAbort Property - - public bool ShouldAbort - { - get - { - return m_flags[ ( int )AsyncQueryInfoFlags.ShouldAbort ]; - } - private set - { - m_flags[ ( int )AsyncQueryInfoFlags.ShouldAbort ] = value; - } - } - - #endregion - - #region IsDisposed Property - - internal bool IsDisposed - { - get - { - return m_flags[ ( int )AsyncQueryInfoFlags.IsDisposed ]; - } - private set - { - m_flags[ ( int )AsyncQueryInfoFlags.IsDisposed ] = value; - } - } - - #endregion - - #region BeginQueryDelegateInvoked Property - - private bool BeginQueryDelegateInvoked - { - get - { - return m_flags[ ( int )AsyncQueryInfoFlags.BeginQueryDelegateInvoked ]; - } - set - { - m_flags[ ( int )AsyncQueryInfoFlags.BeginQueryDelegateInvoked ] = value; - } - } - - #endregion - - public void EndQuery( object[] items ) - { - // Ignore this query when disposed - if( this.IsDisposed ) - return; - - if( m_endQueryDelegateDispatcherOperation != null ) - throw new InvalidOperationException( "An attempt was made to call EndQuery when it has already been called for this AsyncQueryInfo." ); - - if( this.ShouldAbort ) - return; - - m_endQueryDelegateDispatcherOperation = m_dispatcher.BeginInvoke( DispatcherPriority.Background, m_endQueryDelegate, this, new object[] { items } ); - } - - internal void QueueQuery() - { - Debug.Assert( !this.IsDisposed, "The AsyncQueryInfo is disposed" ); - - this.ShouldAbort = false; - this.BeginQueryDelegateInvoked = false; - - //Make sure to abort the EndQuery operation before queuing a new query. - if( m_endQueryDelegateDispatcherOperation != null ) - { - m_endQueryDelegateDispatcherOperation.Abort(); - m_endQueryDelegateDispatcherOperation = null; - } - -#if SILVERLIGHT - m_dispatcher.BeginInvoke( new Action( this.BeginQuery ) ); -#else - m_beginQueryDispatcherOperation = m_dispatcher.BeginInvoke( DispatcherPriority.Background, new Action( this.BeginQueryDispatcherCallback ) ); -#endif - } - - internal void AbortQuery() - { - Debug.Assert( !this.IsDisposed ); - - // Make sure to abort the EndQuery operation before queuing an abort query. - if( m_endQueryDelegateDispatcherOperation != null ) - { - m_endQueryDelegateDispatcherOperation.Abort(); - m_endQueryDelegateDispatcherOperation = null; - } - - if( this.ShouldAbort ) - { - Debug.Assert( m_beginQueryDispatcherOperation == null ); - - m_builtInAbortDelegate( this ); - return; - } - - this.ShouldAbort = true; - - // If the BeginQuery already had time to execute, then we know the user was notified of the query request. Notify him to cancel the query as soon as possible. - if( this.BeginQueryDelegateInvoked ) - { - Debug.WriteLineIf( VirtualPageManager.DebugDataVirtualization, "CALLING Abort Query! For page at starting index: " + m_startIndex.ToString() ); - - m_dispatcher.BeginInvoke( DispatcherPriority.Send, m_abortQueryDelegate, this ); - } - else - { - // BeginQueryDispatcherCallback was dispatched but not executed yet, abort it and return - if( m_beginQueryDispatcherOperation != null ) - { - m_beginQueryDispatcherOperation.Abort(); - m_beginQueryDispatcherOperation = null; - } - - m_builtInAbortDelegate( this ); - } - } - - private void BeginQueryDispatcherCallback() - { - m_beginQueryDispatcherOperation = null; - - Debug.Assert( !this.IsDisposed ); - - if( this.ShouldAbort ) - { - Debug.WriteLineIf( VirtualPageManager.DebugDataVirtualization, "BUILT-IN BeginQueryDispatcherCallback Aborted! (" + this.GetHashCode() + ") For page at starting index: " + m_startIndex.ToString() ); - - m_builtInAbortDelegate( this ); - return; - } - - m_beginQueryDelegate( this ); - this.BeginQueryDelegateInvoked = true; - } - - #region IDisposable Members - - public void Dispose() - { - m_dispatcher = null; - - Debug.Assert( m_beginQueryDispatcherOperation == null, "A BeginQueryDispatcherCallback is still pending on the Dispatcher" ); - - m_beginQueryDispatcherOperation = null; - m_builtInAbortDelegate = null; - m_abortQueryDelegate = null; - m_beginQueryDelegate = null; - m_endQueryDelegate = null; - m_queryErrorChangedDelegate = null; - - this.IsDisposed = true; - } - - #endregion - - private int m_startIndex; - private int m_requestedItemCount; - - private BitVector32 m_flags = new BitVector32(); - - private object m_error; - - private Dispatcher m_dispatcher; - - private DispatcherOperation m_beginQueryDispatcherOperation; - private DispatcherOperation m_endQueryDelegateDispatcherOperation; - private Action m_builtInAbortDelegate; - private Action m_beginQueryDelegate; - private Action m_abortQueryDelegate; - private Action m_endQueryDelegate; - private Action m_queryErrorChangedDelegate; - - [Flags] - private enum AsyncQueryInfoFlags - { - ShouldAbort = 1, - EndQueryDelegateInvoked = 2, - BeginQueryDelegateInvoked = 4, - IsDisposed = 8, - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/AsyncQueryInfoWeakComparer.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/AsyncQueryInfoWeakComparer.cs deleted file mode 100644 index 1513f240..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/AsyncQueryInfoWeakComparer.cs +++ /dev/null @@ -1,53 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - internal class AsyncQueryInfoWeakComparer : IEqualityComparer - { - #region IEqualityComparer Members - - public bool Equals( AsyncQueryInfo x, AsyncQueryInfo y ) - { - if( ( x == null ) && ( y == null ) ) - return true; - - if( ( x == null ) || ( y == null ) ) - return false; - - - if( ( x.StartIndex == y.StartIndex ) && ( x.RequestedItemCount == y.RequestedItemCount ) ) - return true; - - return false; - } - - public int GetHashCode( AsyncQueryInfo obj ) - { - if( obj == null ) - return 0; - - return obj.StartIndex ^ obj.RequestedItemCount; - } - - #endregion IEqualityComparer Members - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/BindingPathValueExtractor.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/BindingPathValueExtractor.cs deleted file mode 100644 index ace88293..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/BindingPathValueExtractor.cs +++ /dev/null @@ -1,217 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows; -using System.Windows.Data; -using System.Diagnostics; -using System.Globalization; -using System.Collections; - -namespace Xceed.Wpf.DataGrid -{ - internal class BindingPathValueExtractor : FrameworkElement - { - #region CONSTRUCTORS - - public BindingPathValueExtractor( - string xPath, - PropertyPath propertyPath, - bool onlyForWrite, - Type dataType, - IValueConverter converter, - object converterParameter, - CultureInfo converterCulture ) - { - m_onlyForWrite = onlyForWrite; - m_targetType = dataType; - m_contextDataProvider = new ContextDataProvider(); - m_binding = new Binding(); - m_binding.XPath = xPath; - m_binding.Path = propertyPath; - - if( converter == null ) - throw new DataGridInternalException( "A Converter must be used" ); - - if( onlyForWrite ) - { - m_binding.Mode = BindingMode.OneWayToSource; - m_binding.Converter = new ConvertBackInhibitorPassthroughConverter( converter ); - m_binding.ConverterParameter = converterParameter; - m_binding.ConverterCulture = converterCulture; - } - else - { - m_binding.Mode = BindingMode.OneWay; - m_converter = converter; - m_converterParameter = converterParameter; - m_converterCulture = converterCulture; - } - - m_binding.Source = m_contextDataProvider; - - this.SetBinding( - BindingPathValueExtractor.ValueProperty, - m_binding ); - } - - #endregion CONSTRUCTORS - - #region ValueProperty - - private static object UninitializedValueKey = new object(); - - private static readonly DependencyProperty ValueProperty = DependencyProperty.Register( - "Value", typeof( object ), typeof( BindingPathValueExtractor ), new PropertyMetadata( BindingPathValueExtractor.UninitializedValueKey ) ); - - private object Value - { - get - { - if( m_onlyForWrite ) - throw new InvalidOperationException( "An attempt was made to read in a write-only binding." ); - - object value = this.GetValue( BindingPathValueExtractor.ValueProperty ); - - if( value == BindingPathValueExtractor.UninitializedValueKey ) - value = null; - - value = m_converter.Convert( value, m_targetType, m_converterParameter, m_converterCulture ); - - if( ( value == DependencyProperty.UnsetValue ) || ( value == Binding.DoNothing ) ) - return null; - - return value; - } - set - { - if( !m_onlyForWrite ) - throw new InvalidOperationException( "An attempt was made to write in a read-only binding." ); - - this.SetValue( BindingPathValueExtractor.ValueProperty, value ); - } - } - - #endregion ValueProperty - - #region PUBLIC METHODS - - public object GetValueFromItem( object item ) - { - m_contextDataProvider.SetNewDataContext( item ); - return this.Value; - - // To gain some performance we do not reset the context - //m_contextDataProvider.SetNewDataContext( null ); - } - - public void SetValueToItem( object item, object value ) - { - if( m_binding.Mode == BindingMode.OneWay ) - throw new InvalidOperationException( "An attempt was made to set a value for a read-only destination path." ); - - m_contextDataProvider.SetNewDataContext( item ); - this.Value = value; - - // To gain some performance we do not reset the context - //m_contextDataProvider.SetNewDataContext( null ); - } - - #endregion PUBLIC METHODS - - #region PRIVATE FIELDS - - internal static readonly object[] EmptyObjectArray = new object[ 0 ]; - - private ContextDataProvider m_contextDataProvider; - private Binding m_binding; - private IValueConverter m_converter; - private object m_converterParameter; - private CultureInfo m_converterCulture; - private bool m_onlyForWrite; - private Type m_targetType; - - #endregion PRIVATE FIELDS - - #region PRIVATE ConvertBackInhibitorConverter CLASS - - private class ConvertBackInhibitorPassthroughConverter : IValueConverter - { - public ConvertBackInhibitorPassthroughConverter( IValueConverter converter ) - { - m_converter = converter; - } - - #region IValueConverter Members - - public object Convert( object value, Type targetType, object parameter, CultureInfo culture ) - { - if( m_converter != null ) - return m_converter.Convert( value, targetType, parameter, culture ); - - return value; - } - - public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture ) - { - if( value == BindingPathValueExtractor.UninitializedValueKey ) - return Binding.DoNothing; - - if( m_converter != null ) - return m_converter.ConvertBack( value, targetType, parameter, culture ); - - return value; - } - - #endregion - - #region PRIVATE FIELDS - - private IValueConverter m_converter; - - #endregion PRIVATE FIELDS - } - - #endregion PRIVATE ConvertBackInhibitorConverter CLASS - - #region PRIVATE ContextDataProvider CLASS - - private class ContextDataProvider : DataSourceProvider - { - public ContextDataProvider() - { - } - - public void SetNewDataContext( object dataContext ) - { - m_dataContext = dataContext; - this.Refresh(); - } - - protected override void BeginQuery() - { - this.OnQueryFinished( m_dataContext ); - } - - private object m_dataContext; - } - - #endregion PRIVATE ContextDataProvider CLASS - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/CollectionViewGroupExtensions.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/CollectionViewGroupExtensions.cs deleted file mode 100644 index 0b56e991..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/CollectionViewGroupExtensions.cs +++ /dev/null @@ -1,161 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows.Data; -using System.Collections.ObjectModel; -using System.Diagnostics; - - -namespace Xceed.Wpf.DataGrid -{ - public static class CollectionViewGroupExtensions - { - - internal static SelectionRange GetRange( this CollectionViewGroup collectionViewGroup, DataGridContext dataGridContext ) - { - int startIndex = -1; - int endIndex = -1; - - DataGridVirtualizingCollectionViewGroupBase dataGridVirtualizingCollectionViewGroupBase = collectionViewGroup as DataGridVirtualizingCollectionViewGroupBase; - DataGridCollectionViewGroup dataGridCollectionViewGroup = collectionViewGroup as DataGridCollectionViewGroup; - - if( dataGridVirtualizingCollectionViewGroupBase != null ) - { - startIndex = dataGridVirtualizingCollectionViewGroupBase.StartGlobalIndex; - endIndex = startIndex + dataGridVirtualizingCollectionViewGroupBase.VirtualItemCount - 1; - } - else if( dataGridCollectionViewGroup != null ) - { - startIndex = dataGridCollectionViewGroup.GetFirstRawItemGlobalSortedIndex(); - endIndex = startIndex + dataGridCollectionViewGroup.GlobalRawItemCount - 1; - } - else if( collectionViewGroup.ItemCount > 0 ) - { - if( dataGridContext == null ) - throw new DataGridInternalException( "This collectionViewGroup require a DataGridContext instance" ); - - var firstItem = collectionViewGroup.GetFirstLeafItem(); - var lastItem = collectionViewGroup.GetLastLeafItem(); - - if( firstItem != null && lastItem != null ) - { - startIndex = dataGridContext.Items.IndexOf( firstItem ); - endIndex = dataGridContext.Items.IndexOf( lastItem ); - } - } - - return ( startIndex >= 0 ) && ( startIndex <= endIndex ) - ? new SelectionRange( startIndex, endIndex ) - : SelectionRange.Empty; - } - - public static IList GetItems( this CollectionViewGroup collectionViewGroup ) - { - var dataGridVirtualizingCollectionViewGroupBase = collectionViewGroup as DataGridVirtualizingCollectionViewGroupBase; - if( dataGridVirtualizingCollectionViewGroupBase != null ) - return dataGridVirtualizingCollectionViewGroupBase.VirtualItems; - - // The Items property of the DataGridCollectionViewGroup has been optimized to allow faster IndexOf and Contains. Since this property we could not - // override the property, we had to new it thus, we need to cast the CollectionViewGroup in the right type before acecssing the property. - var dataGridCollectionViewGroup = collectionViewGroup as DataGridCollectionViewGroup; - if( dataGridCollectionViewGroup != null ) - return dataGridCollectionViewGroup.Items; - - return collectionViewGroup.Items; - } - - public static int GetItemCount( this CollectionViewGroup collectionViewGroup ) - { - var dataGridVirtualizingCollectionViewGroupBase = collectionViewGroup as DataGridVirtualizingCollectionViewGroupBase; - if( dataGridVirtualizingCollectionViewGroupBase != null ) - return dataGridVirtualizingCollectionViewGroupBase.VirtualItemCount; - - return collectionViewGroup.ItemCount; - } - - internal static IEnumerable GetLeafItems( this CollectionViewGroup collectionViewGroup ) - { - foreach( var item in collectionViewGroup.GetItems() ) - { - if( item is CollectionViewGroup ) - { - foreach( var subItem in ( ( CollectionViewGroup )item ).GetLeafItems() ) - { - yield return subItem; - } - } - else - { - yield return item; - } - } - } - - internal static object GetFirstLeafItem( this CollectionViewGroup collectionViewGroup ) - { - IList items = collectionViewGroup.GetItems(); - - if( items.Count == 0 ) - return null; - - var item = items[ 0 ]; - var subGroup = item as CollectionViewGroup; - - return ( subGroup != null ) - ? subGroup.GetFirstLeafItem() - : item; - } - - internal static object GetLastLeafItem( this CollectionViewGroup collectionViewGroup ) - { - IList items = collectionViewGroup.GetItems(); - - if( items.Count == 0 ) - return null; - - var item = items[ items.Count - 1 ]; - var subGroup = item as CollectionViewGroup; - - return ( subGroup != null ) - ? subGroup.GetLastLeafItem() - : item; - } - - - internal static IEnumerable GetSubGroups( this CollectionViewGroup collectionViewGroup ) - { - foreach( var item in collectionViewGroup.GetItems() ) - { - var subGroup = item as CollectionViewGroup; - - //No need to check every items, they will be all Groups or not. - if( subGroup == null ) - break; - - yield return subGroup; - - foreach( var subSubgroup in subGroup.GetSubGroups() ) - { - yield return subGroup; - } - } - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/CommitItemsEvent.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/CommitItemsEvent.cs deleted file mode 100644 index d2e26886..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/CommitItemsEvent.cs +++ /dev/null @@ -1,55 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - public class CommitItemsEventArgs : EventArgs - { - internal CommitItemsEventArgs( DataGridVirtualizingCollectionViewBase collectionView, AsyncCommitInfo asyncCommitInfo ) - { - m_dataGridVirtualizingCollectionViewBase = collectionView; - m_asyncCommitInfo = asyncCommitInfo; - } - - public DataGridVirtualizingCollectionViewBase CollectionView - { - get - { - return m_dataGridVirtualizingCollectionViewBase; - } - } - - public AsyncCommitInfo AsyncCommitInfo - { - get - { - return m_asyncCommitInfo; - } - } - - #region PRIVATE FIELDS - - private DataGridVirtualizingCollectionViewBase m_dataGridVirtualizingCollectionViewBase; - private AsyncCommitInfo m_asyncCommitInfo; - - #endregion PRIVATE FIELDS - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/ConnectionErrorChangedEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/ConnectionErrorChangedEventManager.cs deleted file mode 100644 index 55233eec..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/ConnectionErrorChangedEventManager.cs +++ /dev/null @@ -1,87 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class ConnectionErrorChangedEventManager : WeakEventManager - { - #region Constructor - - private ConnectionErrorChangedEventManager() - { - } - - #endregion - - #region CurrentManager Private Property - - private static ConnectionErrorChangedEventManager CurrentManager - { - get - { - var managerType = typeof( ConnectionErrorChangedEventManager ); - var currentManager = ( ConnectionErrorChangedEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new ConnectionErrorChangedEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - #endregion - - public static void AddListener( DataGridVirtualizingCollectionViewBase source, IWeakEventListener listener ) - { - if( source == null ) - throw new ArgumentNullException( "source" ); - - if( listener == null ) - throw new ArgumentNullException( "listener" ); - - CurrentManager.ProtectedAddListener( source, listener ); - } - - public static void RemoveListener( DataGridVirtualizingCollectionViewBase source, IWeakEventListener listener ) - { - if( source == null ) - throw new ArgumentNullException( "source" ); - - if( listener == null ) - throw new ArgumentNullException( "listener" ); - - CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - var target = ( DataGridVirtualizingCollectionViewBase )source; - target.ConnectionErrorChanged += new EventHandler( this.DeliverEvent ); - } - - protected override void StopListening( object source ) - { - var target = ( DataGridVirtualizingCollectionViewBase )source; - target.ConnectionErrorChanged -= new EventHandler( this.DeliverEvent ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/ConnectionStateChangedEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/ConnectionStateChangedEventManager.cs deleted file mode 100644 index 5e0eaf03..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/ConnectionStateChangedEventManager.cs +++ /dev/null @@ -1,87 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class ConnectionStateChangedEventManager : WeakEventManager - { - #region Constructor - - private ConnectionStateChangedEventManager() - { - } - - #endregion - - #region CurrentManager Private Property - - private static ConnectionStateChangedEventManager CurrentManager - { - get - { - var managerType = typeof( ConnectionStateChangedEventManager ); - var currentManager = ( ConnectionStateChangedEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new ConnectionStateChangedEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - #endregion - - public static void AddListener( DataGridVirtualizingCollectionViewBase source, IWeakEventListener listener ) - { - if( source == null ) - throw new ArgumentNullException( "source" ); - - if( listener == null ) - throw new ArgumentNullException( "listener" ); - - CurrentManager.ProtectedAddListener( source, listener ); - } - - public static void RemoveListener( DataGridVirtualizingCollectionViewBase source, IWeakEventListener listener ) - { - if( source == null ) - throw new ArgumentNullException( "source" ); - - if( listener == null ) - throw new ArgumentNullException( "listener" ); - - CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - var target = ( DataGridVirtualizingCollectionViewBase )source; - target.ConnectionStateChanged += new EventHandler( this.DeliverEvent ); - } - - protected override void StopListening( object source ) - { - var target = ( DataGridVirtualizingCollectionViewBase )source; - target.ConnectionStateChanged -= new EventHandler( this.DeliverEvent ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/CustomDistinctValueItemConfiguration.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/CustomDistinctValueItemConfiguration.cs deleted file mode 100644 index 97e9ce23..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/CustomDistinctValueItemConfiguration.cs +++ /dev/null @@ -1,37 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Collections; - -namespace Xceed.Wpf.DataGrid -{ - internal class CustomDistinctValueItemConfiguration - { - public CustomDistinctValueItemConfiguration() - { - } - - public object Title - { - get; - set; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/CustomDistinctValueItemConfigurationCollection.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/CustomDistinctValueItemConfigurationCollection.cs deleted file mode 100644 index b1b6c46c..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/CustomDistinctValueItemConfigurationCollection.cs +++ /dev/null @@ -1,47 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Collections.ObjectModel; - -namespace Xceed.Wpf.DataGrid -{ - internal class CustomDistinctValueItemConfigurationCollection : ObservableCollection - { - internal CustomDistinctValueItemConfigurationCollection() - { - } - - public CustomDistinctValueItemConfiguration this[ object configurationTitle ] - { - get - { - foreach( CustomDistinctValueItemConfiguration configuration in this ) - { - if( configuration.Title == configurationTitle ) - { - return configuration; - } - } - - return null; - } - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionView.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionView.cs deleted file mode 100644 index eb81f1e5..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionView.cs +++ /dev/null @@ -1,2456 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Diagnostics; -using System.Globalization; -using System.Linq; -using System.Threading; -using System.Windows.Data; -using Xceed.Utils.Collections; -using Xceed.Utils.Data; - -namespace Xceed.Wpf.DataGrid -{ - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Design", "CA1039:ListsAreStronglyTyped" )] - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Design", "CA1035:ICollectionImplementationsHaveStronglyTypedMembers" )] - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix" )] - public sealed partial class DataGridCollectionView : DataGridCollectionViewBase, ISupportInitializeNotification, ICancelAddNew, IBindingList - { - public DataGridCollectionView( IEnumerable collection ) - : this( collection, null, true, true ) - { - } - - public DataGridCollectionView( IEnumerable collection, Type itemType ) - : this( collection, itemType, true, true ) - { - } - - public DataGridCollectionView( IEnumerable collection, Type itemType, bool autoCreateItemProperties, bool autoCreateDetailDescriptions ) - : this( collection, itemType, autoCreateItemProperties, autoCreateDetailDescriptions, false ) - { - } - - public DataGridCollectionView( IEnumerable collection, Type itemType, bool autoCreateItemProperties, bool autoCreateDetailDescriptions, bool autoCreateForeignKeyDescriptions ) - : base( null, collection, itemType, autoCreateItemProperties, autoCreateDetailDescriptions, autoCreateForeignKeyDescriptions ) - { - if( collection == null ) - throw new ArgumentNullException( "collection" ); - } - - [EditorBrowsable( EditorBrowsableState.Never )] - [Obsolete( "This constructor is obsolete and should no longer be used.", true )] - public DataGridCollectionView( Type itemType ) - : base( null, null, null, false, false, false ) - { - throw new NotSupportedException( "This constructor is obsolete and should no longer be used." ); - } - - private DataGridCollectionView( IEnumerable collection, DataGridDetailDescription parentDetailDescription, DataGridCollectionView parentDataGridCollectionView ) - : base( collection, parentDetailDescription, parentDataGridCollectionView.RootDataGridCollectionViewBase ) - { - if( collection == null ) - throw new ArgumentNullException( "collection" ); - - //If already deferring refreshes while a detail grid is expanded. - if( parentDataGridCollectionView.InDeferRefresh ) - { - //If count is 0, it means this child collection view represents the first detail of its parent item, so create the parent's list of disposable. - if( parentDataGridCollectionView.DetailDeferRefreshes.Count == 0 ) - { - parentDataGridCollectionView.DetailDeferRefreshes.Add( new List() ); - } - - //Need to defer refresh on the detail CollectionView as well, and for as many "defers" there are presently at the master level. - foreach( List detailDisposables in parentDataGridCollectionView.DetailDeferRefreshes ) - { - detailDisposables.Add( this.DeferRefresh() ); - } - - //If Refresh() has been called on the root CollectionView, do it also for the detail one. - if( parentDataGridCollectionView.NeedsRefresh ) - { - this.Refresh(); - } - } - } - - internal override void PreConstruct() - { - base.PreConstruct(); - - m_sourceItemList = new List( 128 ); - m_filteredItemList = new List( 128 ); - - m_sourceItems = new SourceItemCollection( this ); - this.RootGroup = new DataGridCollectionViewGroupRoot( this ); - } - - #region SourceItems Property - - public IList SourceItems - { - get - { - this.EnsureThreadAndCollectionLoaded(); - return m_sourceItems; - } - } - - private SourceItemCollection m_sourceItems; - - #endregion SourceItems Property - - #region View Property - - // The View property was created to continue the support of a binding where the - // Path property was set to View to fix an issue with VS 2008: - // ItemsSource="{Binding Source={StaticResource cvs_orders}, Path=View} - // - // Since binding to a CollectionViewSource is like binding directly to - // the object returned by the CVS (the DataGridCollectionView), which was not - // the case with our older DataGridCollectionViewSource, we decided to expose "View" here - // to support the previously recommended fix. - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - [Obsolete( "The View property is obsolete and should not be used. A Binding's Path property no longer needs to be set to the underlying View.", true )] - public DataGridCollectionView View - { - get - { - return this; - } - } - - #endregion View Property - - #region Count Property - - public override int Count - { - get - { - this.EnsureThreadAndCollectionLoaded(); - return this.RootGroup.GlobalRawItemCount; - } - } - - #endregion Count Property - - #region IsAddingItem Property - - [Obsolete( "The IsAddingItem property is obsolete and has been replaced by the IsAddingNew property.", false )] - [EditorBrowsable( EditorBrowsableState.Never )] - [Browsable( false )] - public bool IsAddingItem - { - get - { - return this.IsAddingNew; - } - } - - #endregion IsAddingItem Property - - #region RawItemIndexComparer Property - - private static RawItemIndexComparer RawItemIndexComparer - { - get - { - if( m_rawItemIndexComparer == null ) - m_rawItemIndexComparer = new RawItemIndexComparer(); - - return m_rawItemIndexComparer; - } - } - - #endregion - - #region RawItemSortComparer Property - - private RawItemSortComparer RawItemSortComparer - { - get - { - if( m_rawItemSortComparer == null ) - m_rawItemSortComparer = new RawItemSortComparer( this ); - - return m_rawItemSortComparer; - } - } - - #endregion - - #region Insertion Property - - public bool AllowNew - { - get - { - return this.CanAddNew; - } - } - - #endregion - - #region RootGroup Property - - internal new DataGridCollectionViewGroupRoot RootGroup - { - get - { - return base.RootGroup as DataGridCollectionViewGroupRoot; - } - set - { - base.RootGroup = value; - } - } - - #endregion - - #region SortedItemVersion Property - - internal int SortedItemVersion - { - get - { - return m_sortedItemVersion; - } - } - - #endregion - - #region SourceItemCount Property - - internal override int SourceItemCount - { - get - { - return m_sourceItemList.Count; - } - } - - #endregion - - #region SyncRoot Property - - internal override object SyncRoot - { - get - { - IEnumerable enumeration = this.Enumeration; - - ICollection collection = enumeration as ICollection; - - if( collection != null ) - return collection.SyncRoot; - - if( enumeration != null ) - return enumeration; - - return base.SyncRoot; - } - } - - #endregion - - public override bool MoveCurrentToPosition( int position ) - { - if( position == this.CurrentPosition ) - return ( this.CurrentItem != null ); - - this.EnsureThreadAndCollectionLoaded(); - return this.SetCurrentItem( position, true ); - } - - public override void RemoveAt( int index ) - { - if( !this.CanRemove ) - throw new InvalidOperationException( "An attempt was made to remove an item from a source that does not support removal." ); - - RawItem rawItem = this.GetRawItemAt( index ); - int sourceIndex; - object dataItem; - - if( rawItem != null ) - { - sourceIndex = rawItem.Index; - dataItem = rawItem.DataItem; - } - else - { - sourceIndex = -1; - dataItem = null; - } - - DataGridRemovingItemEventArgs removingItemEventArgs = new DataGridRemovingItemEventArgs( this, dataItem, index, false ); - this.RootDataGridCollectionViewBase.OnRemovingItem( removingItemEventArgs ); - - if( removingItemEventArgs.Cancel ) - throw new DataGridException( "RemoveAt was canceled." ); - - if( !removingItemEventArgs.Handled ) - this.InternalRemoveAt( sourceIndex ); - - if( ( !this.IsSourceSupportingChangeNotification ) && ( sourceIndex != -1 ) ) - { - DeferredOperation deferredOperation = new DeferredOperation( DeferredOperation.DeferredOperationAction.Remove, sourceIndex, new object[] { dataItem } ); - - this.ExecuteOrQueueSourceItemOperation( deferredOperation ); - } - - DataGridItemRemovedEventArgs itemRemovedEventArgs = new DataGridItemRemovedEventArgs( this, dataItem, index ); - this.RootDataGridCollectionViewBase.OnItemRemoved( itemRemovedEventArgs ); - } - - public override object GetItemAt( int index ) - { - this.EnsureThreadAndCollectionLoaded(); - - return this.RootGroup.GetRawItemAtGlobalSortedIndex( index ).DataItem; - } - - public void ResetItem( object item ) - { - DeferredOperation deferredOperation = new DeferredOperation( DeferredOperation.DeferredOperationAction.ResetItem, item ); - this.ExecuteOrQueueSourceItemOperation( deferredOperation ); - } - - public void ResetItems( IList items ) - { - DeferredOperation deferredOperation = new DeferredOperation( DeferredOperation.DeferredOperationAction.ResetItem, items ); - this.ExecuteOrQueueSourceItemOperation( deferredOperation ); - } - - public void RefreshUnboundItemProperties( object item = null ) - { - DeferredOperation deferredOperation = new DeferredOperation( DeferredOperation.DeferredOperationAction.RefreshUnboundItemProperties, item ); - this.ExecuteOrQueueSourceItemOperation( deferredOperation ); - } - - public void RefreshUnboundItemProperties( IList items ) - { - DeferredOperation deferredOperation = new DeferredOperation( DeferredOperation.DeferredOperationAction.RefreshUnboundItemProperties, items ); - this.ExecuteOrQueueSourceItemOperation( deferredOperation ); - } - - internal override DataGridCollectionViewBase CreateDetailDataGridCollectionViewBase( - IEnumerable detailDataSource, - DataGridDetailDescription parentDetailDescription, - DataGridCollectionViewBase parentDataGridCollectionViewBase ) - { - Debug.Assert( parentDataGridCollectionViewBase is DataGridCollectionView ); - - if( parentDetailDescription != null ) - return new DataGridCollectionView( detailDataSource, parentDetailDescription, parentDataGridCollectionViewBase as DataGridCollectionView ); - - return new DataGridCollectionView( detailDataSource ); - } - - internal override void CreateDefaultCollections( DataGridDetailDescription parentDetailDescription ) - { - base.CreateDefaultCollections( parentDetailDescription ); - } - - internal override bool CanCreateItemProperties() - { - if( base.CanCreateItemProperties() ) - return true; - - return ( m_sourceItems.Count != 0 ); - } - - internal override int IndexOfSourceItem( object item ) - { - if( item != null ) - { - // The source index of raw items may not be up-to-date if some operations were deferred. - if( !this.DeferredOperationManager.HasPendingOperations ) - { - // Use the RawItem/DataItem mapping instead of looping through the list for efficency. - var rawItem = this.GetFirstRawItemFromDataItem( item ); - - if( rawItem != null ) - return rawItem.Index; - } - - IList list = this.Enumeration as IList; - if( list != null ) - return list.IndexOf( item ); - - var index = 0; - foreach( var obj in this.Enumeration ) - { - if( obj == item ) - return index; - - index++; - } - } - - return -1; - } - - internal override void EnsurePosition( int globalSortedIndex ) - { - RawItem rawItem = this.GetRawItemAt( globalSortedIndex ); - - this.EnsurePosition( rawItem, globalSortedIndex ); - } - - internal override void ExecuteSourceItemOperation( DeferredOperation deferredOperation, out bool refreshForced ) - { - switch( deferredOperation.Action ) - { - case DeferredOperation.DeferredOperationAction.Add: - { - refreshForced = !this.AddSourceItem( deferredOperation.NewStartingIndex, deferredOperation.NewItems, deferredOperation.NewSourceItemCount ); - break; - } - - case DeferredOperation.DeferredOperationAction.Move: - { - refreshForced = !this.MoveSourceItem( deferredOperation.OldStartingIndex, deferredOperation.OldItems, deferredOperation.NewStartingIndex ); - break; - } - - case DeferredOperation.DeferredOperationAction.Refresh: - { - refreshForced = false; - this.OnProxyCollectionRefresh(); - this.ForceRefresh( true, false, true ); - break; - } - - case DeferredOperation.DeferredOperationAction.RefreshDistincValues: - { - refreshForced = false; - break; - } - - case DeferredOperation.DeferredOperationAction.Regroup: - { - refreshForced = false; - - // Ensure to defer the CurrentItem change when regrouping is completed to be sure the SaveCurrent has the right values when restoring - using( this.DeferCurrencyEvent() ) - { - var oldCurrentPosition = -1; - var oldCurrentRawItem = default( RawItem ); - - this.SaveCurrentBeforeReset( out oldCurrentRawItem, out oldCurrentPosition ); - - var sortDescriptionInfos = default( IList ); - - this.GroupItems(); - this.PrepareSort( out sortDescriptionInfos ); - this.SortItems( sortDescriptionInfos ); - - // Ensure to send reset notifications - this.AdjustCurrentAndSendResetNotification( oldCurrentRawItem, oldCurrentPosition ); - this.TriggerRootGroupChanged(); - } - break; - } - - case DeferredOperation.DeferredOperationAction.Remove: - { - refreshForced = !this.RemoveSourceItem( deferredOperation.OldStartingIndex, deferredOperation.OldItems.Count ); - break; - } - - case DeferredOperation.DeferredOperationAction.Replace: - { - refreshForced = !this.ReplaceSourceItem( deferredOperation.OldStartingIndex, deferredOperation.OldItems, - deferredOperation.NewStartingIndex, deferredOperation.NewItems ); - break; - } - - case DeferredOperation.DeferredOperationAction.Resort: - { - refreshForced = false; - - // Ensure to defer the CurrentItem change when resort is completed to be sure the SaveCurrent has the right values when restoring - using( this.DeferCurrencyEvent() ) - { - var oldCurrentPosition = -1; - var oldCurrentRawItem = default( RawItem ); - - this.SaveCurrentBeforeReset( out oldCurrentRawItem, out oldCurrentPosition ); - - var sortDescriptionInfos = default( IList ); - - this.PrepareSort( out sortDescriptionInfos ); - this.SortItems( sortDescriptionInfos ); - - // Ensure to send reset notifications - this.AdjustCurrentAndSendResetNotification( oldCurrentRawItem, oldCurrentPosition ); - - //If there is no grouping, there is no group changes, so no GroupChanged to raise. - if( !this.RootGroup.IsBottomLevel ) - { - this.TriggerRootGroupChanged(); - } - } - break; - } - - case DeferredOperation.DeferredOperationAction.ResetItem: - { - refreshForced = false; - if( deferredOperation.DataItem != null ) - { - this.ResetSourceItem( deferredOperation.DataItem ); - } - else - { - this.ResetSourceItems( deferredOperation.NewItems ); - } - m_currentChildCollectionView = null; - break; - } - - case DeferredOperation.DeferredOperationAction.RefreshUnboundItemProperties: - { - refreshForced = false; - if( deferredOperation.NewItems != null ) - { - this.RefreshUnboundItemPropertiesCore( deferredOperation.NewItems ); - } - else - { - this.RefreshUnboundItemPropertiesCore( deferredOperation.DataItem ); - } - m_currentChildCollectionView = null; - break; - } - - default: - { - base.ExecuteSourceItemOperation( deferredOperation, out refreshForced ); - break; - } - } - } - - internal override void ForceRefresh( bool sendResetNotification, bool initialLoad, bool setCurrentToFirstOnInitialLoad ) - { - if( this.Refreshing ) - throw new InvalidOperationException( "An attempt was made to refresh the DataGridCollectionView while it is already in the process of refreshing." ); - - if( this.IsRefreshingDistinctValues ) - throw new InvalidOperationException( "An attempt was made to refresh the DataGridCollectionView while it is already in the process of refreshing distinct values." ); - - this.SetCurrentEditItem( null ); - - var oldCurrentPosition = -1; - var oldCurrentRawItem = default( RawItem ); - - if( !initialLoad ) - { - this.SaveCurrentBeforeReset( out oldCurrentRawItem, out oldCurrentPosition ); - } - - var sortDescriptionInfos = default( IList ); - - using( this.DeferCurrencyEvent() ) - { - this.Refreshing = true; - - try - { - lock( this.SyncRoot ) - { - var deferredOperationManager = this.DeferredOperationManager; - - lock( deferredOperationManager ) - { - deferredOperationManager.ClearDeferredOperations(); - m_lastAddCount = -1; - - var bLoaded = false; - var enumeration = this.Enumeration; - var collectionView = enumeration as CollectionView; - - if( collectionView == null ) - { - var list = enumeration as IList; - - if( list != null ) - { - int count = list.Count; - - m_sourceItemList.Clear(); - m_filteredItemList.Clear(); - m_dataItemToRawItemMap.Clear(); - - for( int i = 0; i < count; i++ ) - { - var item = list[ i ]; - var rawItem = new RawItem( i, item ); - - m_sourceItemList.Add( rawItem ); - this.AddRawItemDataItemMapping( rawItem ); - - if( this.PassesFilter( item ) ) - { - m_filteredItemList.Add( rawItem ); - } - } - - bLoaded = true; - } - } - - if( !bLoaded ) - { - if( enumeration != null ) - { - var count = 128; - - if( collectionView != null ) - { - count = collectionView.Count; - } - else - { - var collection = enumeration as ICollection; - if( collection != null ) - { - count = collection.Count; - } - } - - m_sourceItemList.Clear(); - m_filteredItemList.Clear(); - m_dataItemToRawItemMap.Clear(); - - var index = 0; - var enumerator = enumeration.GetEnumerator(); - - while( enumerator.MoveNext() ) - { - var item = enumerator.Current; - var rawItem = new RawItem( index, item ); - - index++; - m_sourceItemList.Add( rawItem ); - - this.AddRawItemDataItemMapping( rawItem ); - - if( this.PassesFilter( item )) - { - m_filteredItemList.Add( rawItem ); - } - } - } - } - - m_filteredItemList.TrimExcess(); - - // We set the current item to -1 to prevent the developper to get an invalid position. - // We will replace the current item to the correct one later. - this.SetCurrentItem( -1, null, false, false ); - this.GroupItems(); - - // This will cache the data for the sorting - this.PrepareSort( out sortDescriptionInfos ); - } - } - - this.SortItems( sortDescriptionInfos ); - - unchecked - { - m_sortedItemVersion++; - } - } - finally - { - this.Refreshing = false; - } - - if( initialLoad ) - { - this.Loaded = true; - this.AdjustCurrencyAfterInitialLoad( setCurrentToFirstOnInitialLoad ); - } - else - { - this.AdjustCurrencyAfterReset( oldCurrentRawItem, oldCurrentPosition, true ); - } - - if( sendResetNotification ) - { - this.OnCollectionChanged( new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Reset ) ); - } - - this.TriggerRootGroupChanged(); - } - } - - internal override void ClearGroupSortComparers() - { - m_groupSortComparers.Clear(); - m_groupSortComparers.TrimExcess(); - } - - internal RawItem GetRawItemAt( int index ) - { - this.EnsureThreadAndCollectionLoaded(); - return this.RootGroup.GetRawItemAtGlobalSortedIndex( index ); - } - - internal object GetSourceItemAt( int index ) - { - if( index > m_sourceItemList.Count - 1 ) - throw new ArgumentOutOfRangeException( "index", index, "index must be greater than zero and less than SourceItems.Count." ); - - return m_sourceItemList[ index ].DataItem; - } - - internal IEnumerator GetSourceListEnumerator() - { - return m_sourceItemList.GetEnumerator(); - } - - internal bool AddSourceItem( int startIndex, IList items, int newSourceItemCount ) - { - if( items == null ) - throw new ArgumentNullException( "items" ); - - if( ( startIndex < 0 ) || ( startIndex > m_sourceItemList.Count ) ) - { - this.ForceRefresh( true, !this.Loaded, true ); - return false; - } - - if( ( newSourceItemCount != -1 ) && ( newSourceItemCount == m_lastAddCount ) ) - { - // In that case, we are reciving a second add to confirm an insertion of a previous item. - // We will convert this add into a replace. - return this.ReplaceSourceItem( m_lastAddIndex, items, m_lastAddIndex, items ); - } - - m_lastAddCount = newSourceItemCount; - m_lastAddIndex = startIndex; - - for( int i = 0; i < items.Count; i++ ) - { - var index = startIndex + i; - var item = items[ i ]; - var rawItem = new RawItem( index, item ); - - if( this.PassesFilter( item ) ) - { - this.AddRawItemInSourceList( index, rawItem ); - this.AddRawItemInFilteredList( rawItem ); - this.AddRawItemInGroup( rawItem ); - } - else - { - this.AddRawItemInSourceList( index, rawItem ); - } - } - - return true; - } - - internal bool RemoveSourceItem( int startIndex, int count ) - { - m_lastAddCount = -1; - - if( ( startIndex < 0 ) || ( ( startIndex + count ) > m_sourceItemList.Count ) ) - { - this.ForceRefresh( true, !this.Loaded, true ); - return false; - } - - for( int i = 0; i < count; i++ ) - { - var rawItem = m_sourceItemList[ startIndex ]; - - if( this.CurrentEditItem == rawItem.DataItem ) - { - this.SetCurrentEditItem( null ); - } - - if( this.RemoveRawItemInFilteredList( rawItem ) ) - { - this.RemoveRawItemInSourceList( startIndex ); - this.RemoveRawItemInGroup( rawItem ); - } - else - { - this.RemoveRawItemInSourceList( startIndex ); - } - } - - return true; - } - - internal bool ReplaceSourceItem( int oldStartIndex, IList oldItems, int newStartIndex, IList newItems ) - { - m_lastAddCount = -1; - - if( ( oldStartIndex < 0 ) || ( newStartIndex < 0 ) ) - { - this.ForceRefresh( true, !this.Loaded, true ); - return false; - } - - int oldItemCount = oldItems.Count; - int newItemCount = newItems.Count; - int sourceItemListCount = m_sourceItemList.Count; - - if( ( oldStartIndex + oldItemCount ) > sourceItemListCount || ( newStartIndex + newItemCount ) > sourceItemListCount ) - { - this.ForceRefresh( true, !this.Loaded, true ); - return false; - } - - int extraOldItemCount = oldItemCount - newItemCount; - - int count = Math.Min( newItemCount, oldItemCount ); - - using( this.DeferCurrencyEvent() ) - { - for( int i = 0; i < count; i++ ) - { - if( oldStartIndex == newStartIndex ) - { - RawItem rawItem = m_sourceItemList[ oldStartIndex + i ]; - object oldItem = rawItem.DataItem; - int globalSortedIndex = rawItem.GetGlobalSortedIndex(); - object newItem = newItems[ i ]; - - // globalSortedIndex == -1 means item does not pass filter - if( globalSortedIndex != -1 ) - { - bool itemChanged = !object.Equals( oldItem, newItem ); - if( ( this.CurrentEditItem == oldItem ) && ( itemChanged ) ) - { - try - { - this.CancelEdit(); - } - catch - { - } - } - - if( this.CurrentEditItem != oldItem ) - { - if( newItem != oldItem ) - { - this.RemoveRawItemDataItemMapping( rawItem ); - rawItem.SetDataItem( newItem ); - this.AddRawItemDataItemMapping( rawItem ); - - this.AdjustCurrencyBeforeReplace( globalSortedIndex, newItem ); - } - - DataGridCollectionViewGroup oldGroup = rawItem.ParentGroup; - - // Even if the newItem == oldItem, we want to set rawItem.ParentGroup.ProtectedItems[] for the change event to be raised. - if( ( oldGroup != null ) && ( oldGroup != this.RootGroup ) ) - { - oldGroup.ProtectedItems[ rawItem.SortedIndex ] = newItem; - } - - this.OnCollectionChanged( new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Replace, newItem, oldItem, rawItem.GetGlobalSortedIndex() ) ); - - this.EnsurePosition( rawItem, globalSortedIndex ); - - DataGridCollectionViewGroup newGroup = rawItem.ParentGroup; - bool movedToDifferentParentGroup = oldGroup != newGroup; - } - } - else - { - if( newItem != oldItem ) - { - this.RemoveRawItemDataItemMapping( rawItem ); - rawItem.SetDataItem( newItem ); - this.AddRawItemDataItemMapping( rawItem ); - } - - // Since it is a replace, we must re-ensure position and invalidate stats function (no need to invalidate the old group, since the old item is filtered - // out, and thus has no parent group), even if it is an item being replaced by itself, in case a property changed would now let it pass the filter. - this.EnsurePosition( rawItem, globalSortedIndex ); - } - } - else - { - Debug.Fail( "Replace should have an oldStartIndex equal to newStartIndex." ); - this.RemoveSourceItem( oldStartIndex + i, 1 ); - this.AddSourceItem( newStartIndex + i, new object[] { newItems[ i ] }, -1 ); - } - } - - if( extraOldItemCount > 0 ) - { - this.RemoveSourceItem( oldStartIndex + newItemCount, extraOldItemCount ); - } - - int extraNewItemCount = newItemCount - oldItemCount; - - if( extraNewItemCount > 0 ) - { - object[] tempItems = new object[ extraNewItemCount ]; - - for( int i = 0; i < extraNewItemCount; i++ ) - { - tempItems[ i ] = newItems[ oldItemCount + i ]; - } - - this.AddSourceItem( newStartIndex + oldItemCount, tempItems, -1 ); - } - } - - return true; - } - - internal RawItem GetFirstRawItemFromDataItem( object dataItem ) - { - this.EnsureThreadAndCollectionLoaded(); - - return m_dataItemToRawItemMap[ dataItem ]; - } - - internal int GetGlobalSortedIndexFromDataItem( object dataItem ) - { - RawItem rawItem = this.GetFirstRawItemFromDataItem( dataItem ); - int globalSortedIndex = rawItem.GetGlobalSortedIndex(); - if( globalSortedIndex == -1 ) - { - return rawItem.SortedIndex; - } - - return globalSortedIndex; - } - - internal IEnumerable GetSortedFilteredDataItems() - { - foreach( RawItem item in this.RootGroup.RawItems ) - { - yield return item.DataItem; - } - } - - private static DataStore CreateStore( Type dataType, int initialCapacity ) - { - if( dataType == typeof( bool ) ) - { - return new BoolDataStore( initialCapacity ); - } - else if( dataType == typeof( byte ) ) - { - return new ValueTypeDataStore( initialCapacity ); - } - else if( dataType == typeof( char ) ) - { - return new ValueTypeDataStore( initialCapacity ); - } - else if( dataType == typeof( DateTime ) ) - { - return new ValueTypeDataStore( initialCapacity ); - } - else if( dataType == typeof( decimal ) ) - { - return new ValueTypeDataStore( initialCapacity ); - } - else if( dataType == typeof( double ) ) - { - return new ValueTypeDataStore( initialCapacity ); - } - else if( dataType == typeof( Guid ) ) - { - return new ValueTypeDataStore( initialCapacity ); - } - else if( dataType == typeof( short ) ) - { - return new ValueTypeDataStore( initialCapacity ); - } - else if( dataType == typeof( int ) ) - { - return new ValueTypeDataStore( initialCapacity ); - } - else if( dataType == typeof( long ) ) - { - return new ValueTypeDataStore( initialCapacity ); - } - else if( dataType == typeof( sbyte ) ) - { - return new ValueTypeDataStore( initialCapacity ); - } - else if( dataType == typeof( float ) ) - { - return new ValueTypeDataStore( initialCapacity ); - } - else if( dataType == typeof( string ) ) - { - return new StringDataStore( initialCapacity ); - } - else if( dataType == typeof( TimeSpan ) ) - { - return new ValueTypeDataStore( initialCapacity ); - } - else if( dataType == typeof( ushort ) ) - { - return new ValueTypeDataStore( initialCapacity ); - } - else if( dataType == typeof( uint ) ) - { - return new ValueTypeDataStore( initialCapacity ); - } - else if( dataType == typeof( ulong ) ) - { - return new ValueTypeDataStore( initialCapacity ); - } - else - { - return new ObjectDataStore( initialCapacity ); - } - } - - private void EnsurePosition( RawItem rawItem, int globalSortedIndex ) - { - Debug.Assert( rawItem.GetGlobalSortedIndex() == globalSortedIndex ); - - var dataItem = rawItem.DataItem; - - if( this.PassesFilter( dataItem ) ) - { - if( globalSortedIndex == -1 ) - { - this.AddRawItemInFilteredList( rawItem ); - this.AddRawItemInGroup( rawItem ); - return; - } - } - else - { - if( globalSortedIndex != -1 ) - { - this.RemoveRawItemInFilteredList( rawItem ); - this.RemoveRawItemInGroup( rawItem ); - } - - return; - } - - // Verify the row is in the correct group. - var newGroup = this.GetRawItemNewGroup( rawItem ); - var currentGroup = rawItem.ParentGroup; - - if( currentGroup != newGroup ) - { - using( this.DeferCurrencyEvent() ) - { - var newSortIndex = newGroup.BinarySearchRawItem( rawItem, this.RawItemSortComparer ); - if( newSortIndex < 0 ) - { - newSortIndex = ~newSortIndex; - } - - currentGroup.RemoveRawItemAt( rawItem.SortedIndex ); - newGroup.InsertRawItem( newSortIndex, rawItem ); - - var newGlobalSortedIndex = rawItem.GetGlobalSortedIndex(); - this.AdjustCurrencyAfterMove( globalSortedIndex, newGlobalSortedIndex, 1 ); - - this.OnCollectionChanged( new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Move, rawItem.DataItem, newGlobalSortedIndex, globalSortedIndex ) ); - } - } - else - { - // Verify sorting only if we have not changed group, since adding an item in a group will automatically sort it. - // Even if we are not sorted, we must ensure the order matches the natural order of the source. - int newSortIndex = newGroup.BinarySearchRawItem( rawItem, this.RawItemSortComparer ); - - if( newSortIndex < 0 ) - { - newSortIndex = ~newSortIndex; - } - - if( newSortIndex > rawItem.SortedIndex ) - { - newSortIndex--; - } - - if( rawItem.SortedIndex != newSortIndex ) - { - using( this.DeferCurrencyEvent() ) - { - newGroup.MoveRawItem( rawItem.SortedIndex, newSortIndex ); - - var newGlobalSortedIndex = rawItem.GetGlobalSortedIndex(); - this.AdjustCurrencyAfterMove( globalSortedIndex, newGlobalSortedIndex, 1 ); - - this.OnCollectionChanged( new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Move, rawItem.DataItem, newGlobalSortedIndex, globalSortedIndex ) ); - } - } - } - } - - private bool SetCurrentItem( int newCurrentPosition, bool isCancelable ) - { - DataGridCollectionViewGroupRoot rootGroup = this.RootGroup; - int itemCount = rootGroup.GlobalRawItemCount; - - if( ( newCurrentPosition < -1 ) || ( newCurrentPosition > itemCount ) ) - throw new ArgumentOutOfRangeException( "newCurrentPosition", "The current position must be greater than -1 and less than Count." ); - - // When we have no items, the current item/position must not be changed - // We have done that to get a behavior like the microsoft BindingListCollectionView - if( itemCount == 0 ) - return false; - - object newCurrentItem = null; - - if( ( newCurrentPosition >= 0 ) && ( newCurrentPosition < itemCount ) ) - { - RawItem newCurrentRawItem = rootGroup.GetRawItemAtGlobalSortedIndex( newCurrentPosition ); - - if( newCurrentRawItem != null ) - newCurrentItem = newCurrentRawItem.DataItem; - } - - return this.SetCurrentItem( newCurrentPosition, newCurrentItem, isCancelable, false ); - } - - private bool SetCurrentItem( int newCurrentPosition, object newCurrentItem, bool isCancelable, bool beforeDeleteOperation ) - { - object oldCurrentItem = this.CurrentItem; - int oldCurrentPosition = this.CurrentPosition; - bool oldIsCurrentBeforeFirst = this.IsCurrentBeforeFirst; - bool oldIsCurrentAfterLast = this.IsCurrentAfterLast; - - if( ( !object.Equals( oldCurrentItem, newCurrentItem ) ) || ( oldCurrentPosition != newCurrentPosition ) ) - { - // We raise the changing event even if we are in DeferCurrencyEvent - CurrentChangingEventArgs currentChangingEventArgs = new CurrentChangingEventArgs( isCancelable ); - this.OnCurrentChanging( currentChangingEventArgs ); - - if( ( !currentChangingEventArgs.Cancel ) || ( !currentChangingEventArgs.IsCancelable ) ) - { - int globalRawItemCount = this.RootGroup.GlobalRawItemCount; - - if( beforeDeleteOperation ) - { - Debug.Assert( globalRawItemCount > 0 ); - globalRawItemCount--; - } - - bool isCurrentBeforeFirst; - bool isCurrentAfterLast; - - if( globalRawItemCount == 0 ) - { - isCurrentBeforeFirst = true; - isCurrentAfterLast = true; - } - else - { - isCurrentBeforeFirst = newCurrentPosition < 0; - isCurrentAfterLast = newCurrentPosition >= globalRawItemCount; - } - -#if DEBUG - if( newCurrentItem == null ) - Debug.Assert( ( newCurrentPosition == -1 ) || ( newCurrentPosition >= ( globalRawItemCount - 1 ) ) ); -#endif - - this.SetCurrentItemAndPositionCore( newCurrentItem, newCurrentPosition, isCurrentBeforeFirst, isCurrentAfterLast ); - - if( !this.IsCurrencyDeferred ) - { - if( !object.Equals( oldCurrentItem, newCurrentItem ) ) - { - this.OnPropertyChanged( new PropertyChangedEventArgs( "CurrentItem" ) ); - } - - if( oldCurrentPosition != this.CurrentPosition ) - { - this.OnPropertyChanged( new PropertyChangedEventArgs( "CurrentPosition" ) ); - } - - if( oldIsCurrentBeforeFirst != this.IsCurrentBeforeFirst ) - { - this.OnPropertyChanged( new PropertyChangedEventArgs( "IsCurrentBeforeFirst" ) ); - } - - if( oldIsCurrentAfterLast != this.IsCurrentAfterLast ) - { - this.OnPropertyChanged( new PropertyChangedEventArgs( "IsCurrentAfterLast" ) ); - } - - this.OnCurrentChanged(); - } - } - } - - return ( newCurrentItem != null ); - } - - private bool MoveSourceItem( int oldStartIndex, IList items, int newStartIndex ) - { - var count = items.Count; - - if( ( oldStartIndex < 0 ) || ( oldStartIndex + count > m_sourceItemList.Count ) || ( newStartIndex < 0 ) || ( newStartIndex > ( m_sourceItemList.Count - count ) ) ) - { - this.ForceRefresh( true, !this.Loaded, true ); - return false; - } - - m_lastAddCount = -1; - - if( oldStartIndex < newStartIndex ) - { - for( int i = count - 1; i >= 0; i-- ) - { - var oldIndex = oldStartIndex + i; - var newIndex = newStartIndex + i; - - Debug.Assert( ( oldIndex >= 0 ) && ( oldIndex < m_sourceItemList.Count ) ); - Debug.Assert( ( newIndex >= 0 ) && ( newIndex < m_sourceItemList.Count ) ); - - var rawItem = m_sourceItemList[ oldIndex ]; - var wasFiltered = this.RemoveRawItemInFilteredList( rawItem ); - - m_sourceItemList.RemoveAt( oldIndex ); - m_sourceItemList.Insert( newIndex, rawItem ); - - for( int j = oldIndex; j <= newIndex; j++ ) - { - m_sourceItemList[ j ].SetIndex( j ); - } - - if( wasFiltered ) - { - this.AddRawItemInFilteredList( rawItem ); - this.EnsurePosition( rawItem, rawItem.GetGlobalSortedIndex() ); - } - } - } - else if( oldStartIndex > newStartIndex ) - { - for( int i = 0; i < count; i++ ) - { - var oldIndex = oldStartIndex + i; - var newIndex = newStartIndex + i; - - Debug.Assert( ( oldIndex >= 0 ) && ( oldIndex < m_sourceItemList.Count ) ); - Debug.Assert( ( newIndex >= 0 ) && ( newIndex < m_sourceItemList.Count ) ); - - var rawItem = m_sourceItemList[ oldIndex ]; - var wasFiltered = this.RemoveRawItemInFilteredList( rawItem ); - - m_sourceItemList.RemoveAt( oldIndex ); - m_sourceItemList.Insert( newIndex, rawItem ); - - for( int j = newIndex; j <= oldIndex; j++ ) - { - m_sourceItemList[ j ].SetIndex( j ); - } - - if( wasFiltered ) - { - this.AddRawItemInFilteredList( rawItem ); - this.EnsurePosition( rawItem, rawItem.GetGlobalSortedIndex() ); - } - } - } - - return true; - } - - private bool ResetSourceItem( object dataItem ) - { - var rawItem = default( RawItem ); - - //Verify if the item is in the same detail CollectionView as the previous item was found in. - if( m_currentChildCollectionView != null ) - { - rawItem = m_currentChildCollectionView.GetFirstRawItemFromDataItem( dataItem ); - - //If the item was found, refresh it. - if( rawItem != null ) - { - int globalSortedIndex = rawItem.GetGlobalSortedIndex(); - m_currentChildCollectionView.EnsurePosition( rawItem, globalSortedIndex ); - return true; - } - } - - //If the item has not been found, try to find it in the current CollectionView. - rawItem = this.GetFirstRawItemFromDataItem( dataItem ); - m_currentChildCollectionView = null; - - //If the item was found, refresh it. - if( rawItem != null ) - { - this.EnsurePosition( rawItem, rawItem.GetGlobalSortedIndex() ); - return true; - } - - //If the item was not found, look for it in an expended detail. - foreach( var detailContext in this.DataGridContext.GetChildContextsCore() ) - { - var detailCollectionView = detailContext.Items as DataGridCollectionView; - if( detailCollectionView == null ) - continue; - - if( detailCollectionView.ResetSourceItem( dataItem ) ) - { - //keep a reference to the detail CollectionView the item was found in, in case following items belong to the same detail. - m_currentChildCollectionView = detailCollectionView; - return true; - } - } - - return false; - } - - private void ResetSourceItems( IList items ) - { - foreach( object dataItem in items ) - { - this.ResetSourceItem( dataItem ); - } - } - - private void AddRawItemInSourceList( int index, RawItem rawItem ) - { - Debug.Assert( ( index >= 0 ) && ( index <= m_sourceItemList.Count ) ); - Debug.Assert( rawItem != null ); - - m_sourceItemList.Insert( index, rawItem ); - - this.AddRawItemDataItemMapping( rawItem ); - - for( var i = m_sourceItemList.Count - 1; i > index; i-- ) - { - m_sourceItemList[ i ].SetIndex( i ); - } - } - - private void AddRawItemInFilteredList( RawItem rawItem ) - { - Debug.Assert( rawItem != null ); - - // The function take for granted that all RawItem's index are sequential, - // or if there is gap, the index contained in the gap are not already contained in the list. - if( ( m_filteredItemList.Count == 0 ) || ( m_filteredItemList.Last().Index < rawItem.Index ) ) - { - m_filteredItemList.Add( rawItem ); - } - else - { - var index = m_filteredItemList.BinarySearch( rawItem, DataGridCollectionView.RawItemIndexComparer ); - Debug.Assert( index < 0 ); - - if( index < 0 ) - { - index = ~index; - } - - m_filteredItemList.Insert( index, rawItem ); - } - } - - private void AddRawItemInGroup( RawItem rawItem ) - { - Debug.Assert( rawItem != null ); - - using( this.DeferCurrencyEvent() ) - { - var newGroup = this.GetRawItemNewGroup( rawItem ); - var index = newGroup.BinarySearchRawItem( rawItem, this.RawItemSortComparer ); - - if( index < 0 ) - { - index = ~index; - } - - var globalIndex = newGroup.GetFirstRawItemGlobalSortedIndex() + index; - - this.AdjustCurrencyBeforeAdd( globalIndex ); - - newGroup.InsertRawItem( index, rawItem ); - - unchecked - { - m_sortedItemVersion++; - } - - this.OnCollectionChanged( new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Add, rawItem.DataItem, globalIndex ) ); - } - } - - private void RemoveRawItemInSourceList( int index ) - { - Debug.Assert( ( index >= 0 ) && ( index < m_sourceItemList.Count ) ); - - this.RemoveRawItemDataItemMapping( m_sourceItemList[ index ] ); - - m_sourceItemList.RemoveAt( index ); - - for( int i = m_sourceItemList.Count - 1; i >= index; i-- ) - { - m_sourceItemList[ i ].SetIndex( i ); - } - } - - private bool RemoveRawItemInFilteredList( RawItem rawItem ) - { - Debug.Assert( rawItem != null ); - - // The function take for granted that all RawItem's index are sequential, - // There should not be any gap in the index sequence. - var index = m_filteredItemList.BinarySearch( rawItem, DataGridCollectionView.RawItemIndexComparer ); - if( index < 0 ) - return false; - - Debug.Assert( ( index >= 0 ) && ( index < m_filteredItemList.Count ) ); - - m_filteredItemList.RemoveAt( index ); - - return true; - } - - private void RemoveRawItemInGroup( RawItem rawItem ) - { - Debug.Assert( rawItem != null ); - - var parentGroup = rawItem.ParentGroup; - if( parentGroup == null ) - return; - - var globalSortedIndex = rawItem.GetGlobalSortedIndex(); - - using( this.DeferCurrencyEvent() ) - { - this.AdjustCurrencyBeforeRemove( globalSortedIndex ); - parentGroup.RemoveRawItemAt( rawItem.SortedIndex ); - - unchecked - { - m_sortedItemVersion++; - } - } - - // In the case of a remove, the CollectionChanged must be after the CurrentChanged since when the DataGridCollectionView is used with a Selector having the - // IsSynchronizedWithCurrent set, the Selector will set the current position to -1 if the selected item is removed. - this.OnCollectionChanged( new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Remove, rawItem.DataItem, globalSortedIndex ) ); - } - - private bool RefreshUnboundItemPropertiesCore( object dataItem = null ) - { - if( dataItem != null ) - { - //Verify if the item is in the same detail CollectionView as the previous item was found in. - if( m_currentChildCollectionView != null && m_currentChildCollectionView.m_sourceItems.Contains( dataItem ) ) - { - m_currentChildCollectionView.ItemProperties.RefreshUnboundItemProperty( dataItem ); - return true; - } - - //Since the item was not found in the previous detail, it means items are not sequential, thus no need to keep looking into this detail. - m_currentChildCollectionView = null; - - //Try to find it in the current CollectionView. - if( m_sourceItems.Contains( dataItem ) ) - { - this.ItemProperties.RefreshUnboundItemProperty( dataItem ); - return true; - } - - //If not, try to find it in an expended detail - foreach( DataGridContext detailContext in this.DataGridContext.GetChildContextsCore() ) - { - DataGridCollectionView detailCollectionView = detailContext.Items as DataGridCollectionView; - if( detailCollectionView != null ) - { - if( detailCollectionView.RefreshUnboundItemPropertiesCore( dataItem ) ) - { - m_currentChildCollectionView = detailCollectionView; - return true; - } - } - } - - return false; - } - - //If dataItem is null, it means every item must be Refreshed. Let's start with the level we're on. - foreach( RawItem rawItem in m_sourceItemList ) - { - this.ItemProperties.RefreshUnboundItemProperty( rawItem.DataItem ); - } - - //Refresh every expended detail of the parent - foreach( DataGridContext detailContext in this.DataGridContext.GetChildContextsCore() ) - { - DataGridCollectionView detailCollectionView = detailContext.Items as DataGridCollectionView; - if( detailCollectionView != null ) - { - detailCollectionView.RefreshUnboundItemPropertiesCore(); - } - } - - return true; - } - - private void RefreshUnboundItemPropertiesCore( IList items ) - { - foreach( object dataItem in items ) - { - this.RefreshUnboundItemPropertiesCore( dataItem ); - } - } - - private void GroupItems() - { - // We set the current item to -1 to prevent the developper to get an invalid position. - // We will replace the current item to the correct one later. - this.SetCurrentItem( -1, null, false, false ); - - // We use a new DataGridCollectionViewGroupRoot instead of doing a clear to prevent - // some event to be raised. And it should also be faster. - this.RootGroup = new DataGridCollectionViewGroupRoot( this ); - - ObservableCollection groupDescriptions = this.GroupDescriptions; - - int groupDescriptionCount = groupDescriptions.Count; - int itemCount = m_filteredItemList.Count; - - DataGridCollectionViewGroupRoot rootGroup = this.RootGroup; - - if( groupDescriptionCount > 0 ) - { - CultureInfo culture = this.Culture; - - for( int i = 0; i < groupDescriptionCount; i++ ) - { - DataGridGroupDescription groupDescription = groupDescriptions[ i ] as DataGridGroupDescription; - - if( groupDescription != null ) - { - groupDescription.SetContext( this ); - } - } - - try - { - rootGroup.SetSubGroupBy( groupDescriptions[ 0 ] ); - rootGroup.CreateFixedGroupNames( 0, groupDescriptions, null ); - - for( int i = 0; i < itemCount; i++ ) - { - RawItem rawItem = m_filteredItemList[ i ]; - DataGridCollectionViewGroup currentGroup = rootGroup; - - for( int j = 1; j <= groupDescriptionCount; j++ ) - { - // We set SortComparers to null to avoid Sorting since we are in the middle of a "batch operation" - // The sorting will be done after the batch operation which is faster than sorting for each group modification - currentGroup = currentGroup.GetGroup( rawItem, j - 1, culture, groupDescriptions, null ); - } - - currentGroup.InsertRawItem( currentGroup.ItemCount, rawItem ); - } - } - finally - { - for( int i = 0; i < groupDescriptionCount; i++ ) - { - DataGridGroupDescription groupDescription = groupDescriptions[ i ] as DataGridGroupDescription; - - if( groupDescription != null ) - { - groupDescription.SetContext( null ); - } - } - } - } - else - { - for( int i = 0; i < itemCount; i++ ) - { - rootGroup.InsertRawItem( i, m_filteredItemList[ i ] ); - } - } - - unchecked - { - m_sortedItemVersion++; - } - } - - private void SortItems( IList sortDescriptionInfos ) - { - // We set the current item to -1 to prevent the developper to get an invalid position. We will replace the current item to the correct one later. - this.SetCurrentItem( -1, null, false, false ); - - var rootGroup = this.RootGroup; - if( rootGroup.IsBottomLevel ) - { - rootGroup.SortRootRawItems( sortDescriptionInfos, m_sourceItemList ); - } - else - { - // We use a new DataGridCollectionViewGroupRoot to prevent some event to be raised. - var newRootGroup = new DataGridCollectionViewGroupRoot( rootGroup ); - - rootGroup.SortItems( sortDescriptionInfos, this.GetGroupSortComparers(), 0, m_sourceItemList, newRootGroup ); - - this.RootGroup = newRootGroup; - } - - unchecked - { - m_sortedItemVersion++; - } - } - - private void SortGroups() - { - //This method assumes the that the RootGroup is not the bottom level group, i.e. there DataGrid is currently grouped. - this.RootGroup.SortGroups( this.GetGroupSortComparers(), 0 ); - - unchecked - { - m_sortedItemVersion++; - } - } - - private void ResortGroups() - { - using( this.DeferCurrencyEvent() ) - { - object oldCurrentDataItem = this.CurrentItem; - int oldCurrentPosition = this.CurrentPosition; - - this.SortGroups(); - - RawItem currentRawItem = null; - - if( oldCurrentDataItem != null ) - { - currentRawItem = this.GetFirstRawItemFromDataItem( oldCurrentDataItem ); - } - - if( currentRawItem == null ) - { - if( ( oldCurrentPosition > 0 ) && ( oldCurrentPosition < this.RootGroup.GlobalRawItemCount ) ) - { - currentRawItem = this.RootGroup.GetRawItemAtGlobalSortedIndex( oldCurrentPosition ); - } - } - - if( currentRawItem != null ) - { - this.SetCurrentItem( currentRawItem.GetGlobalSortedIndex(), oldCurrentDataItem, false, false ); - } - - this.OnCollectionChanged( new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Reset ) ); - } - } - - private void PrepareSort( out IList sortDescriptionInfos ) - { - sortDescriptionInfos = new List(); - - lock( this.SyncRoot ) - { - lock( this.DeferredOperationManager ) - { - var itemCount = m_sourceItemList.Count; - - foreach( var sortDescription in this.SortDescriptions ) - { - var itemProperty = ItemsSourceHelper.GetItemPropertyFromProperty( this.ItemProperties, sortDescription.PropertyName ); - var sortDescriptionInfo = new SortDescriptionInfo( itemProperty, sortDescription.Direction ); - - sortDescriptionInfos.Add( sortDescriptionInfo ); - - if( itemProperty == null ) - continue; - - // This will cache the data for the sorting - var dataStore = default( DataStore ); - var isSortingOnForeignKeyDescription = false; - - var foreignKeyDescription = itemProperty.ForeignKeyDescription; - if( foreignKeyDescription != null ) - { - var dataType = foreignKeyDescription.GetDataType(); - if( dataType != null ) - { - dataStore = DataGridCollectionView.CreateStore( dataType, itemCount ); - isSortingOnForeignKeyDescription = true; - } - } - - itemProperty.IsSortingOnForeignKeyDescription = isSortingOnForeignKeyDescription; - - //Create the DataStore if it has not been created yet. - if( !isSortingOnForeignKeyDescription ) - { - if( itemProperty.SortComparer != null ) - { - // If we have a sort comparer, keep the element in an object data type to increase the performance. - dataStore = DataGridCollectionView.CreateStore( typeof( object ), itemCount ); - } - else - { - dataStore = DataGridCollectionView.CreateStore( itemProperty.DataType, itemCount ); - } - } - - sortDescriptionInfo.DataStore = dataStore; - - var supportInitialize = itemProperty as ISupportInitialize; - if( supportInitialize != null ) - { - supportInitialize.BeginInit(); - } - - try - { - if( isSortingOnForeignKeyDescription ) - { - for( int i = 0; i < itemCount; i++ ) - { - var value = ItemsSourceHelper.GetValueFromItemProperty( itemProperty, m_sourceItemList[ i ].DataItem ); - - dataStore.SetData( i, foreignKeyDescription.GetDisplayValue( value ) ); - } - } - else - { - for( int i = 0; i < itemCount; i++ ) - { - var value = ItemsSourceHelper.GetValueFromItemProperty( itemProperty, m_sourceItemList[ i ].DataItem ); - - dataStore.SetData( i, value ); - } - } - } - finally - { - if( supportInitialize != null ) - { - supportInitialize.EndInit(); - } - } - } - } - } - } - - private List GetGroupSortComparers() - { - if( m_groupSortComparers.Count > 0 ) - return m_groupSortComparers; - - var sortDescriptions = this.SortDescriptions; - - foreach( var groupDescription in this.GroupDescriptions ) - { - // Find all the SortInfos for the current sub group. - var groupDescriptionName = DataGridCollectionView.GetPropertyNameFromGroupDescription( groupDescription ); - var sortInfos = new List( sortDescriptions.Count + 1 ); - - foreach( var sortDescription in sortDescriptions ) - { - var sortDirection = sortDescription.Direction; - var sortDescriptionName = sortDescription.PropertyName; - var itemProperty = ItemsSourceHelper.GetItemPropertyFromProperty( this.ItemProperties, sortDescriptionName ); - - if( string.Equals( groupDescriptionName, sortDescriptionName ) ) - { - var foreignKeyDescription = ( itemProperty != null ) ? itemProperty.ForeignKeyDescription : null; - if( foreignKeyDescription != null ) - { - if( foreignKeyDescription.ItemsSource != null - && ( !string.IsNullOrWhiteSpace( foreignKeyDescription.DisplayMemberPath ) || ( foreignKeyDescription.ForeignKeyConverter != null ) ) ) - { - sortInfos.Add( new GroupSortComparer.SortInfo( foreignKeyDescription, sortDirection, this.GetSortComparer( groupDescription, itemProperty ) ) ); - } - } - - sortInfos.Add( new GroupSortComparer.SortInfo( sortDirection, this.GetSortComparer( groupDescription, itemProperty ) ) ); - } - } - - m_groupSortComparers.Add( new GroupSortComparer( sortInfos ) ); - } - - return m_groupSortComparers; - } - - private IComparer GetSortComparer( GroupDescription groupDescription, DataGridItemPropertyBase itemProperty ) - { - var dataGridGroupDescription = groupDescription as DataGridGroupDescription; - var sortComparer = default( IComparer ); - - if( dataGridGroupDescription != null ) - { - sortComparer = dataGridGroupDescription.SortComparer; - } - - if( ( sortComparer == null ) && ( itemProperty != null ) ) - { - sortComparer = itemProperty.SortComparer; - } - - if( sortComparer == null ) - { - sortComparer = ObjectComparer.Singleton; - } - - return sortComparer; - } - - private void AdjustCurrentAndSendResetNotification( RawItem oldCurrentRawItem, int oldCurrentPosition ) - { - this.AdjustCurrencyAfterReset( oldCurrentRawItem, oldCurrentPosition, false ); - - this.OnCollectionChanged( new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Reset ) ); - } - - private void TriggerRootGroupChanged() - { - // All the groups will be recreated. No need to trigger the StatFunctions PropertyChanged. - this.DeferredOperationManager.ClearInvalidatedGroups(); - - this.OnPropertyChanged( new PropertyChangedEventArgs( DataGridCollectionViewBase.RootGroupPropertyName ) ); - - // Flag that the Collection of groups itself has changed. - this.OnPropertyChanged( new PropertyChangedEventArgs( DataGridCollectionViewBase.GroupsPropertyName ) ); - } - - private DataGridCollectionViewGroup GetRawItemNewGroup( RawItem rawItem ) - { - ObservableCollection groupDescriptions = this.GroupDescriptions; - int groupDescriptionCount = groupDescriptions.Count; - - if( groupDescriptionCount == 0 ) - return this.RootGroup; - - CultureInfo culture = this.Culture; - List sortComparers = this.GetGroupSortComparers(); - - for( int i = 0; i < groupDescriptionCount; i++ ) - { - DataGridGroupDescription groupDescription = groupDescriptions[ i ] as DataGridGroupDescription; - - if( groupDescription != null ) - { - groupDescription.SetContext( this ); - } - } - - try - { - DataGridCollectionViewGroup currentGroup = this.RootGroup; - - for( int j = 1; j <= groupDescriptionCount; j++ ) - { - currentGroup = currentGroup.GetGroup( rawItem, j - 1, culture, groupDescriptions, sortComparers ); - } - - return currentGroup; - } - finally - { - for( int i = 0; i < groupDescriptionCount; i++ ) - { - DataGridGroupDescription groupDescription = groupDescriptions[ i ] as DataGridGroupDescription; - - if( groupDescription != null ) - { - groupDescription.SetContext( null ); - } - } - } - } - - private void AddRawItemDataItemMapping( RawItem rawItem ) - { - m_dataItemToRawItemMap.Add( rawItem.DataItem, rawItem ); - } - - private void RemoveRawItemDataItemMapping( RawItem rawItem ) - { - m_dataItemToRawItemMap.Remove( rawItem.DataItem, rawItem ); - } - - private void SaveCurrentBeforeReset( out RawItem oldCurrentRawItem, out int oldCurrentPosition ) - { - Debug.Assert( this.Loaded ); - - if( this.IsCurrentAfterLast ) - { - oldCurrentPosition = int.MaxValue; - } - else - { - oldCurrentPosition = this.CurrentPosition; - } - - oldCurrentRawItem = ( oldCurrentPosition < 0 ) || ( oldCurrentPosition == int.MaxValue ) ? null : this.RootGroup.GetRawItemAtGlobalSortedIndex( oldCurrentPosition ); - } - - private void AdjustCurrencyAfterReset( RawItem oldCurrentRawItem, int oldCurrentPosition, bool itemsChanged ) - { - DataGridCollectionViewGroupRoot rootGroup = this.RootGroup; - - if( ( oldCurrentPosition < 0 ) || ( rootGroup.GlobalRawItemCount == 0 ) ) - { - this.SetCurrentItem( -1, null, false, false ); - return; - } - - if( oldCurrentPosition == int.MaxValue ) - { - this.SetCurrentItem( rootGroup.GlobalRawItemCount, null, false, false ); - return; - } - - if( itemsChanged ) - { - object oldCurrentItem = oldCurrentRawItem.DataItem; - int newIndex = this.IndexOf( oldCurrentItem ); - - if( newIndex == -1 ) - { - this.SetCurrentItem( -1, null, false, false ); - } - else - { - this.SetCurrentItem( newIndex, oldCurrentItem, false, false ); - } - } - else - { - this.SetCurrentItem( oldCurrentRawItem.GetGlobalSortedIndex(), oldCurrentRawItem.DataItem, false, false ); - } - } - - private void AdjustCurrencyAfterInitialLoad( bool setCurrentToFirst ) - { - if( this.RootGroup.GlobalRawItemCount == 0 ) - { - this.SetCurrentItem( -1, null, false, false ); - return; - } - - if( setCurrentToFirst ) - { - this.SetCurrentItem( 0, this.RootGroup.GetRawItemAtGlobalSortedIndex( 0 ).DataItem, false, false ); - } - else - { - this.SetCurrentItem( -1, null, false, false ); - } - } - - private void AdjustCurrencyBeforeAdd( int index ) - { - if( this.RootGroup.GlobalRawItemCount == 0 ) - { - this.SetCurrentItem( -1, null, false, false ); - } - else if( index <= this.CurrentPosition ) - { - this.SetCurrentItem( this.CurrentPosition + 1, this.CurrentItem, false, false ); - } - } - - private void AdjustCurrencyAfterMove( int oldIndex, int newIndex, int itemCount ) - { - int oldRangeEnd = oldIndex + itemCount - 1; - - // Current position was in the moved range - if( ( this.CurrentPosition >= oldIndex ) && ( this.CurrentPosition <= oldRangeEnd ) ) - { - int offset = this.CurrentPosition - oldIndex; - this.SetCurrentItem( newIndex + offset, this.CurrentItem, false, false ); - } - else if( ( ( oldIndex >= this.CurrentPosition ) || ( newIndex >= this.CurrentPosition ) ) - && ( ( oldIndex <= this.CurrentPosition ) || ( newIndex <= this.CurrentPosition ) ) ) - { - if( oldIndex < this.CurrentPosition ) - { - this.SetCurrentItem( this.CurrentPosition - itemCount, this.CurrentItem, false, false ); - } - else if( newIndex <= this.CurrentPosition ) - { - this.SetCurrentItem( this.CurrentPosition + itemCount, this.CurrentItem, false, false ); - } - } - } - - private void AdjustCurrencyBeforeRemove( int index ) - { - if( index < this.CurrentPosition ) - { - this.SetCurrentItem( this.CurrentPosition - 1, this.CurrentItem, false, true ); - } - else if( index == this.CurrentPosition ) - { - DataGridCollectionViewGroupRoot rootGroup = this.RootGroup; - - if( this.CurrentPosition == ( rootGroup.GlobalRawItemCount - 1 ) ) - { - index = rootGroup.GlobalRawItemCount - 2; - - if( index >= 0 ) - { - this.SetCurrentItem( index, rootGroup.GetRawItemAtGlobalSortedIndex( index ).DataItem, false, true ); - } - else - { - this.SetCurrentItem( index, null, false, true ); - } - } - else - { - this.SetCurrentItem( index, rootGroup.GetRawItemAtGlobalSortedIndex( index + 1 ).DataItem, false, true ); - } - } - } - - private void AdjustCurrencyBeforeReplace( int index, object newItem ) - { - if( index == this.CurrentPosition ) - { - this.SetCurrentItem( index, newItem, false, false ); - } - } - - #region ICancelAddNew Members - - void ICancelAddNew.CancelNew( int itemIndex ) - { - this.CancelNew(); - } - - void ICancelAddNew.EndNew( int itemIndex ) - { - this.CommitNew(); - } - - #endregion - - #region ISupportInitializeNotification Members - - private event EventHandler Initialized; - - event EventHandler ISupportInitializeNotification.Initialized - { - add - { - this.Initialized = ( EventHandler )Delegate.Combine( this.Initialized, value ); - } - remove - { - this.Initialized = ( EventHandler )Delegate.Remove( this.Initialized, value ); - } - } - - private void OnInitialized( EventArgs e ) - { - if( this.Initialized != null ) - { - this.Initialized( this, e ); - } - } - - bool ISupportInitializeNotification.IsInitialized - { - get - { - return m_batchInitializationCount == 0; - } - } - - #endregion ISupportInitializeNotification Members - - #region ISupportInitialize Members - - void ISupportInitialize.BeginInit() - { - if( m_batchInitializationCount == 0 ) - { - Debug.Assert( m_batchDeferred == null ); - m_batchDeferred = this.DeferRefresh(); - } - - m_batchInitializationCount++; - } - - void ISupportInitialize.EndInit() - { - if( m_batchInitializationCount > 0 ) - { - m_batchInitializationCount--; - } - - if( m_batchInitializationCount == 0 ) - { - m_batchDeferred.Dispose(); - m_batchDeferred = null; - this.OnInitialized( EventArgs.Empty ); - } - } - - #endregion ISupportInitialize Members - - #region ICollectionView Members - - public override IEnumerable SourceCollection - { - get - { - return this.Enumeration; - } - } - - public override bool Contains( object item ) - { - this.EnsureThreadAndCollectionLoaded(); - - if( item != null ) - { - RawItem rawItem = this.GetFirstRawItemFromDataItem( item ); - if( rawItem != null ) - { - // A SortedIndex of -1 means that the RawItem is not in the m_filteredItemList. - if( rawItem.SortedIndex > -1 ) - return true; - } - } - - return false; - } - - public override bool IsEmpty - { - get - { - this.EnsureThreadAndCollectionLoaded(); - return ( this.RootGroup.GlobalRawItemCount == 0 ); - } - } - - public override int IndexOf( object item ) - { - this.EnsureThreadAndCollectionLoaded(); - - if( item != null ) - { - var rawItem = this.GetFirstRawItemFromDataItem( item ); - if( rawItem != null ) - { - // A SortedIndex of -1 means that the RawItem is not in the m_filteredItemList. - if( rawItem.SortedIndex >= 0 ) - return rawItem.GetGlobalSortedIndex(); - } - } - - return -1; - } - - #endregion ICollectionView Members - - #region IBindingList Members - - void IBindingList.AddIndex( PropertyDescriptor property ) - { - throw new NotSupportedException( "The IBindingList.AddIndex method not supported." ); - } - - bool IBindingList.AllowEdit - { - get - { - return false; - } - } - - bool IBindingList.AllowRemove - { - get - { - return false; - } - } - - void IBindingList.ApplySort( PropertyDescriptor property, ListSortDirection direction ) - { - throw new NotSupportedException( "The IBindingList.ApplySort method is not supported." ); - } - - int IBindingList.Find( PropertyDescriptor property, object key ) - { - throw new NotSupportedException( "The IBindingList.Find method is not supported." ); - } - - bool IBindingList.IsSorted - { - get - { - return false; - } - } - - private event ListChangedEventHandler ListChanged; - - event ListChangedEventHandler IBindingList.ListChanged - { - add - { - this.ListChanged = ( ListChangedEventHandler )EventHandler.Combine( this.ListChanged, value ); - } - remove - { - this.ListChanged = ( ListChangedEventHandler )EventHandler.Remove( this.ListChanged, value ); - } - } - - void IBindingList.RemoveIndex( PropertyDescriptor property ) - { - throw new NotSupportedException( "The IBindingList.RemoveIndex method is not supported." ); - } - - void IBindingList.RemoveSort() - { - throw new NotSupportedException( "The IBindingList.RemoveSort method is not supported." ); - } - - ListSortDirection IBindingList.SortDirection - { - get - { - throw new NotSupportedException( "The IBindingList.SortDirection property is not supported." ); - } - } - - PropertyDescriptor IBindingList.SortProperty - { - get - { - throw new NotSupportedException( "The IBindingList.SortProperty property is not supported." ); - } - } - - bool IBindingList.SupportsChangeNotification - { - get - { - return false; - } - } - - bool IBindingList.SupportsSearching - { - get - { - return false; - } - } - - bool IBindingList.SupportsSorting - { - get - { - return false; - } - } - - #endregion IBindingList Members - - #region IList Members - - int IList.Add( object value ) - { - throw new NotSupportedException( "The IList.Add method is not supported." ); - } - - void IList.Clear() - { - throw new NotSupportedException( "The IList.Clear method is not supported." ); - } - - void IList.Insert( int index, object value ) - { - throw new NotSupportedException( "The IList.Insert method is not supported." ); - } - - bool IList.IsFixedSize - { - get - { - return true; - } - } - - bool IList.IsReadOnly - { - get - { - return true; - } - } - - void IList.Remove( object value ) - { - throw new NotSupportedException( "The IList.Remove method is not supported." ); - } - - void IList.RemoveAt( int index ) - { - throw new NotSupportedException( "The IList.RemoveAt method is not supported." ); - } - - object IList.this[ int index ] - { - get - { - return this.GetItemAt( index ); - } - set - { - throw new NotSupportedException( "The IList indexer is not supported." ); - } - } - - #endregion IList Members - - #region ICollection Members - - void ICollection.CopyTo( Array array, int index ) - { - IEnumerator enumerator = this.GetEnumerator(); - - while( enumerator.MoveNext() ) - { - array.SetValue( enumerator.Current, index ); - index++; - } - } - - void CopyTo( object[] array, int index ) - { - IEnumerator enumerator = this.GetEnumerator(); - - while( enumerator.MoveNext() ) - { - array[ index ] = enumerator.Current; - index++; - } - } - - bool ICollection.IsSynchronized - { - get - { - return false; - } - } - - object ICollection.SyncRoot - { - get - { - return this.SyncRoot; - } - } - - #endregion ICollection Members - - #region IEnumerable Members - - protected override IEnumerator GetEnumerator() - { - this.EnsureThreadAndCollectionLoaded(); - return new DataGridCollectionViewEnumerator( this ); - } - - #endregion IEnumerable Members - - private static RawItemIndexComparer m_rawItemIndexComparer; - private RawItemSortComparer m_rawItemSortComparer; - private List m_groupSortComparers = new List(); - - private int m_lastAddCount; - private int m_lastAddIndex; - - private int m_batchInitializationCount; - private IDisposable m_batchDeferred; - - private List m_sourceItemList; - private List m_filteredItemList; - private readonly RawItemMap m_dataItemToRawItemMap = new RawItemMap(); - - private int m_sortedItemVersion; - private DataGridCollectionView m_currentChildCollectionView; - - #region Private Class EqualityComparerWrapper - - private class EqualityComparerWrapper : IEqualityComparer - { - public EqualityComparerWrapper( IEqualityComparer comparer ) - { - if( comparer == null ) - { - m_comparer = EqualityComparer.Default; - } - else - { - m_comparer = comparer; - } - } - - bool IEqualityComparer.Equals( object x, object y ) - { - return m_comparer.Equals( x, y ); - } - - int IEqualityComparer.GetHashCode( object obj ) - { - return m_comparer.GetHashCode( obj ); - } - - private IEqualityComparer m_comparer; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewBase.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewBase.cs deleted file mode 100644 index 38435771..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewBase.cs +++ /dev/null @@ -1,2901 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Data; -using System.Diagnostics; -using System.Globalization; -using System.Linq; -using System.Threading; -using System.Windows; -using System.Windows.Data; -using System.Windows.Threading; -using Xceed.Utils.Collections; -using Xceed.Wpf.DataGrid.Utils; - -namespace Xceed.Wpf.DataGrid -{ - public abstract partial class DataGridCollectionViewBase : CollectionView, IEditableCollectionView, IWeakEventListener, IItemProperties - { - #region Static Fields - - internal static readonly string GroupsPropertyName = PropertyHelper.GetPropertyName( ( DataGridCollectionViewBase c ) => c.Groups ); - internal static readonly string RootGroupPropertyName = PropertyHelper.GetPropertyName( ( DataGridCollectionViewBase c ) => c.RootGroup ); - - #endregion - - #region Static Members - - internal static string GetPropertyNameFromGroupDescription( GroupDescription groupDescription ) - { - var propertyGroupDescription = groupDescription as PropertyGroupDescription; - if( propertyGroupDescription != null ) - return propertyGroupDescription.PropertyName; - - var dataGridGroupDescription = groupDescription as DataGridGroupDescription; - if( dataGridGroupDescription != null ) - return dataGridGroupDescription.PropertyName; - - return null; - } - - #endregion - -// static DataGridCollectionViewBase() -// { -// Licenser.VerifyLicenseSilently(); -// } - - private DataGridCollectionViewBase() - : base( new object[ 0 ] ) - { - - this.PreConstruct(); - - m_distinctValues = new DistinctValuesDictionary( this ); - - m_filteredItemProperties = new List(); - m_readOnlyFilteredItemProperties = new ReadOnlyCollection( m_filteredItemProperties ); - - // The constructor used for detail creation will rectify the m_rootDataGridCollectionViewBase later on. - m_rootDataGridCollectionViewBase = this; - - m_deferredOperationManager = new DeferredOperationManager( this, this.Dispatcher, true ); - } - - internal DataGridCollectionViewBase( - object modelSource, - IEnumerable source, - Type itemType, - bool autoCreateItemProperties, - bool autoCreateDetailDescriptions, - bool autoCreateForeignKeyDescriptions ) - : this() - { - m_desiredItemType = itemType; - - m_itemProperties = new DataGridItemPropertyCollection(); - m_detailDescriptions = new DataGridDetailDescriptionCollection(); - m_defaultPropertyDescriptions = new PropertyDescriptionRouteDictionary(); - - this.AutoCreateItemProperties = autoCreateItemProperties; - this.AutoCreateDetailDescriptions = autoCreateDetailDescriptions; - this.AutoCreateForeignKeyDescriptions = autoCreateForeignKeyDescriptions; - - if( itemType == null ) - { - if( source != null ) - { - itemType = ItemsSourceHelper.GetItemTypeFromEnumeration( source ); - } - else if( modelSource != null ) - { - var queryable = modelSource as IQueryable; - if( queryable != null ) - { - itemType = queryable.ElementType; - } - } - } - else - { - var listItemType = ItemsSourceHelper.GetItemTypeFromEnumeration( source ) ?? typeof( object ); - if( !listItemType.IsAssignableFrom( itemType ) && !itemType.IsAssignableFrom( listItemType ) ) - throw new InvalidOperationException( "The itemType is not assignable to the type of the list." ); - } - - m_modelSource = modelSource; - m_itemType = itemType; - m_enumeration = source; - - this.CreateDefaultCollections( null ); - this.RegisterChangedEvents(); - this.SetupCurrent( true ); - this.SetupDefaultPropertyDescriptions(); - this.SetupDefaultDetailDescriptions(); - this.PrepareItemProperties( m_itemProperties ); - - if( this.AutoCreateItemProperties ) - { - ItemsSourceHelper.CreateAndAddItemPropertiesForPropertyDescriptions( m_itemProperties, m_defaultPropertyDescriptions.Values ); - ItemsSourceHelper.AutoDetectSynonyms( this ); - } - } - - internal DataGridCollectionViewBase( IEnumerable collection, DataGridDetailDescription parentDetailDescription, DataGridCollectionViewBase rootDataGridCollectionViewBase ) - : this() - { - if( parentDetailDescription == null ) - throw new ArgumentNullException( "parentDetailDescription" ); - - m_rootDataGridCollectionViewBase = rootDataGridCollectionViewBase; - m_parentDetailDescription = parentDetailDescription; - m_itemProperties = parentDetailDescription.ItemProperties; - m_detailDescriptions = parentDetailDescription.DetailDescriptions; - m_defaultPropertyDescriptions = parentDetailDescription.DefaultPropertyDescriptions; - - m_distinctValuesConstraint = m_parentDetailDescription.DistinctValuesConstraint; - - this.AutoCreateDetailDescriptions = parentDetailDescription.AutoCreateDetailDescriptions; - this.AutoCreateItemProperties = parentDetailDescription.AutoCreateItemProperties; - this.AutoCreateForeignKeyDescriptions = parentDetailDescription.AutoCreateForeignKeyDescriptions; - - if( parentDetailDescription.ItemType == null ) - { - parentDetailDescription.ItemType = ItemsSourceHelper.GetItemTypeFromEnumeration( collection ) ?? typeof( object ); - } - - m_modelSource = default( object ); - m_itemType = parentDetailDescription.ItemType; - m_enumeration = collection; - - this.CreateDefaultCollections( m_parentDetailDescription ); - this.RegisterChangedEvents(); - this.SetupCurrent( false ); - this.SetupDefaultPropertyDescriptions(); - this.SetupDefaultDetailDescriptions(); - - // Creates the item properties if auto-creation is ON and no one already created them. - if( this.AutoCreateItemProperties && !m_parentDetailDescription.AutoCreateItemPropertiesCompleted ) - { - ItemsSourceHelper.CreateAndAddItemPropertiesForPropertyDescriptions( m_itemProperties, m_defaultPropertyDescriptions.Values ); - ItemsSourceHelper.AutoDetectSynonyms( this ); - - m_parentDetailDescription.AutoCreateItemPropertiesCompleted = true; - } - - m_filteredItemProperties.Clear(); - - this.PrepareItemProperties( m_itemProperties ); - - // This is required in the Master/Detail scheme of things! - this.ForceRefresh( false, true, false ); - } - - internal virtual void PreConstruct() - { - } - - #region ParentCollectionViewSource Internal Property - - internal DataGridCollectionViewSourceBase ParentCollectionViewSourceBase - { - get - { - return m_parentCollectionViewSourceBase; - } - set - { - if( ( m_parentCollectionViewSourceBase != null ) && ( value != null ) && ( m_parentCollectionViewSourceBase != value ) ) - throw new InvalidOperationException( "An attempt was made to use a DataGridCollectionView that is already being used by a DataGridCollectionViewSource." ); - - m_parentCollectionViewSourceBase = value; - } - } - - private DataGridCollectionViewSourceBase m_parentCollectionViewSourceBase; - - #endregion - - #region NeedsRefresh Public Property - - public override bool NeedsRefresh - { - get - { - return m_deferredOperationManager.RefreshPending; - } - } - - #endregion - - #region Culture Public Property - - public override CultureInfo Culture - { - get - { - return base.Culture; - } - set - { - base.Culture = value; - - // This is the only way we found to update the extra properties defined on our CollectionViewSource. - // In the CollectionViewSource.ApplyPropertiesToView method, the first thing that is done - // is setting the Culture; therefore, we have no choice but to use this as the entry point and then - // apply our properties to the DataGridCollectionView. - // - // See CollectionViewSource.ApplyPropertiesToView in reflector for a better understanding. - if( ( this.InDeferRefresh ) && ( m_parentCollectionViewSourceBase != null ) ) - { - m_parentCollectionViewSourceBase.ApplyExtraPropertiesToView( this ); - } - } - } - - #endregion - - #region AutoCreateItemProperties Public Property - - public bool AutoCreateItemProperties - { - get - { - return m_flags[ ( int )DataGridCollectionViewBaseFlags.AutoCreateItemProperties ]; - } - private set - { - m_flags[ ( int )DataGridCollectionViewBaseFlags.AutoCreateItemProperties ] = value; - } - } - - #endregion - - #region AutoCreateDetailDescriptions Public Property - - internal bool AutoCreateDetailDescriptions - { - get - { - return m_flags[ ( int )DataGridCollectionViewBaseFlags.AutoCreateDetailDescriptions ]; - } - private set - { - m_flags[ ( int )DataGridCollectionViewBaseFlags.AutoCreateDetailDescriptions ] = value; - } - } - - #endregion - - #region ParentDetailDescription Public Property - - internal DataGridDetailDescription ParentDetailDescription - { - get - { - return m_parentDetailDescription; - } - } - - - #endregion - - #region AutoCreateForeignKeyDescriptions Public Property - - public bool AutoCreateForeignKeyDescriptions - { - get - { - return m_flags[ ( int )DataGridCollectionViewBaseFlags.AutoCreateForeignKeyDescriptions ]; - } - private set - { - m_flags[ ( int )DataGridCollectionViewBaseFlags.AutoCreateForeignKeyDescriptions ] = value; - } - } - - #endregion - - #region SyncRoot Internal Property - - internal virtual object SyncRoot - { - get - { - if( m_syncRoot == null ) - { - Interlocked.CompareExchange( ref m_syncRoot, new object(), null ); - } - - return m_syncRoot; - } - } - - private object m_syncRoot; //null - - #endregion - - #region DeferredOperationManager Internal Property - - internal DeferredOperationManager DeferredOperationManager - { - get - { - return m_deferredOperationManager; - } - } - - #endregion - - #region InDeferRefresh Internal Property - - internal bool InDeferRefresh - { - get - { - return ( m_deferRefreshCount > 0 ); - } - } - - #endregion - - #region Loaded Internal Property - - internal bool Loaded - { - get - { - return m_flags[ ( int )DataGridCollectionViewBaseFlags.Loaded ]; - } - set - { - m_flags[ ( int )DataGridCollectionViewBaseFlags.Loaded ] = value; - } - } - - #endregion - - #region IsRefreshingDestinctValues Internal Property - - internal bool IsRefreshingDistinctValues - { - get - { - return m_flags[ ( int )DataGridCollectionViewBaseFlags.IsRefreshingDistinctValues ]; - } - set - { - m_flags[ ( int )DataGridCollectionViewBaseFlags.IsRefreshingDistinctValues ] = value; - } - } - - #endregion - - #region Refreshing Internal Property - - internal bool Refreshing - { - get - { - return m_flags[ ( int )DataGridCollectionViewBaseFlags.Refreshing ]; - } - set - { - m_flags[ ( int )DataGridCollectionViewBaseFlags.Refreshing ] = value; - } - } - - #endregion - - #region ModelSource Internal Property - - internal object ModelSource - { - get - { - return m_modelSource; - } - } - - #endregion - - #region ItemEditionIsManuallyHandled Private Property - - private bool ItemEditionIsManuallyHandled - { - get - { - return m_flags[ ( int )DataGridCollectionViewBaseFlags.ItemEditionIsManuallyHandled ]; - } - set - { - m_flags[ ( int )DataGridCollectionViewBaseFlags.ItemEditionIsManuallyHandled ] = value; - } - } - - #endregion - - #region CreatingNewItemIsManuallyHandled Private Property - - private bool CreatingNewItemIsManuallyHandled - { - get - { - return m_flags[ ( int )DataGridCollectionViewBaseFlags.CreatingNewItemIsManuallyHandled ]; - } - set - { - m_flags[ ( int )DataGridCollectionViewBaseFlags.CreatingNewItemIsManuallyHandled ] = value; - } - } - - #endregion - - #region ItemProperties Public Property - - public DataGridItemPropertyCollection ItemProperties - { - get - { - return m_itemProperties; - } - } - - #endregion - - #region DefaultItemPropertiesInitialized Private Property - - private bool DefaultItemPropertiesInitialized - { - get - { - if( m_parentDetailDescription != null ) - return m_parentDetailDescription.DefaultItemPropertiesInitialized; - - return m_flags[ ( int )DataGridCollectionViewBaseFlags.DefaultItemPropertiesInitialized ]; - } - set - { - if( m_parentDetailDescription != null ) - { - m_parentDetailDescription.DefaultItemPropertiesInitialized = value; - } - else - { - m_flags[ ( int )DataGridCollectionViewBaseFlags.DefaultItemPropertiesInitialized ] = value; - } - } - } - - #endregion - - #region DefaultPropertyDescriptionsCreated Private Property - - private bool DefaultPropertyDescriptionsCreated - { - get - { - if( m_parentDetailDescription != null ) - return m_parentDetailDescription.DefaultPropertyDescriptionsCreated; - - return m_flags[ ( int )DataGridCollectionViewBaseFlags.DefaultPropertyDescriptionsCreated ]; - } - set - { - if( m_parentDetailDescription != null ) - { - m_parentDetailDescription.DefaultPropertyDescriptionsCreated = value; - } - else - { - m_flags[ ( int )DataGridCollectionViewBaseFlags.DefaultPropertyDescriptionsCreated ] = value; - } - } - } - - #endregion - - #region CanCreateItemPropertiesFormModelSource Private Property - - private bool CanCreateItemPropertiesFromModelSource - { - get - { - return ( ( m_modelSource != null ) && ( m_modelSource is DataTable || m_modelSource is IQueryable ) ); - } - } - - #endregion - - #region DetailDeferRefreshes Internal Property - - internal List> DetailDeferRefreshes - { - get - { - return m_detailDeferRefreshes; - } - } - - private List> m_detailDeferRefreshes; - - #endregion - - #region DataGridContext Internal Property - - internal DataGridContext DataGridContext - { - get - { - if( m_dataGridContext == null ) - return null; - - return m_dataGridContext.Target as DataGridContext; - } - set - { - if( value == null ) - { - m_dataGridContext = null; - } - else - { - m_dataGridContext = new WeakReference( value ); - } - } - } - - private WeakReference m_dataGridContext; - - #endregion - - #region DataGridCollectionViewBase ABSTRACT MEMBERS - - internal virtual int IndexOfSourceItem( object item ) - { - return this.IndexOf( item ); - } - - internal abstract DataGridCollectionViewBase CreateDetailDataGridCollectionViewBase( - IEnumerable detailDataSource, - DataGridDetailDescription parentDetailDescription, - DataGridCollectionViewBase parentDataGridCollectionViewBase ); - - internal abstract void EnsurePosition( int globalSortedIndex ); - - internal abstract int SourceItemCount - { - get; - } - - internal abstract void ForceRefresh( bool sendResetNotification, bool initialLoad, bool setCurrentToFirstOnInitialLoad ); - - #endregion - - #region SOURCE - - internal IEnumerable Enumeration - { - get - { - return m_enumeration; - } - } - - public Type ItemType - { - get - { - return m_itemType; - } - } - - internal Type DesiredItemType - { - get - { - return m_desiredItemType; - } - } - - internal bool HasSource - { - get - { - return ( m_enumeration != null ); - } - } - - #endregion - - #region SOURCE COLLECTION CHANGED HANDLERS - - private void OnItemsSourceCollectionChanged( object sender, NotifyCollectionChangedEventArgs e ) - { - Debug.Assert( !( this is DataGridVirtualizingCollectionViewBase ), - "The DataGridVirtualizingCollectionView is unbound and therefore should never receive a notification from a source." ); - - lock( m_deferredOperationManager ) - { - if( m_deferredOperationManager.RefreshPending ) - return; - - DeferredOperation deferredOperation = null; - - switch( e.Action ) - { - case NotifyCollectionChangedAction.Add: - { - CollectionView collectionView = m_enumeration as CollectionView; - int count = ( collectionView == null ) ? -1 : collectionView.Count; - - deferredOperation = new DeferredOperation( DeferredOperation.DeferredOperationAction.Add, count, e.NewStartingIndex, e.NewItems ); - break; - } - - case NotifyCollectionChangedAction.Move: - { - deferredOperation = new DeferredOperation( DeferredOperation.DeferredOperationAction.Move, -1, e.NewStartingIndex, e.NewItems, e.OldStartingIndex, e.OldItems ); - break; - } - - case NotifyCollectionChangedAction.Remove: - { - deferredOperation = new DeferredOperation( DeferredOperation.DeferredOperationAction.Remove, e.OldStartingIndex, e.OldItems ); - break; - } - - case NotifyCollectionChangedAction.Replace: - { - deferredOperation = new DeferredOperation( DeferredOperation.DeferredOperationAction.Replace, -1, e.NewStartingIndex, e.NewItems, e.OldStartingIndex, e.OldItems ); - break; - } - - case NotifyCollectionChangedAction.Reset: - { - deferredOperation = new DeferredOperation( DeferredOperation.DeferredOperationAction.Refresh, -1, null ); - break; - } - - default: - throw new NotSupportedException( e.Action.ToString() + " is not a supported action." ); - } - - if( deferredOperation != null ) - { - this.ExecuteOrQueueSourceItemOperation( deferredOperation ); - } - } - } - - private void OnItemsSourceListChanged( object sender, ListChangedEventArgs e ) - { - Debug.Assert( !( this is DataGridVirtualizingCollectionViewBase ), - "The DataGridVirtualizingCollectionView is unbound and therefore should never receive a notification from a source." ); - - Action propertyDescriptorHandler; - ListChangedType listChangedType = e.ListChangedType; - - switch( listChangedType ) - { - case ListChangedType.PropertyDescriptorAdded: - propertyDescriptorHandler = this.HandlePropertyDescriptorAdded; - break; - - case ListChangedType.PropertyDescriptorChanged: - propertyDescriptorHandler = this.HandlePropertyDescriptorChanged; - break; - - case ListChangedType.PropertyDescriptorDeleted: - propertyDescriptorHandler = this.HandlePropertyDescriptorDeleted; - break; - - default: - propertyDescriptorHandler = null; - break; - } - - if( propertyDescriptorHandler != null ) - { - if( this.CheckAccess() ) - { - propertyDescriptorHandler.Invoke( e.PropertyDescriptor ); - } - else - { - this.Dispatcher.Invoke( new Action( propertyDescriptorHandler ), e.PropertyDescriptor ); - } - } - else - { - IBindingList bindingList = ( IBindingList )m_enumeration; - int index = e.NewIndex; - IList items = null; - - if( ( listChangedType != ListChangedType.Reset ) && ( listChangedType != ListChangedType.ItemDeleted ) ) - { - var indexInBound = ( index >= 0 ) && ( index < bindingList.Count ); - - //If we're within bounds - if( indexInBound ) - { - //Let's get the item - items = new object[] { bindingList[ index ] }; - } - else - { - //Let's reset the list because a change to the list has happenned (e.g. a delete) before we had a chance to process the current change. - listChangedType = ListChangedType.Reset; - } - } - - lock( m_deferredOperationManager ) - { - if( m_deferredOperationManager.RefreshPending ) - return; - - DeferredOperation deferredOperation; - - switch( listChangedType ) - { - case ListChangedType.ItemAdded: - { - deferredOperation = new DeferredOperation( DeferredOperation.DeferredOperationAction.Add, bindingList.Count, index, items ); - break; - } - - case ListChangedType.ItemChanged: - { - var collectionView = this as DataGridCollectionView; - deferredOperation = new DeferredOperation( DeferredOperation.DeferredOperationAction.Replace, -1, index, items, index, items ); - break; - } - - case ListChangedType.ItemDeleted: - { - deferredOperation = new DeferredOperation( DeferredOperation.DeferredOperationAction.Remove, index, new object[ 1 ] ); - break; - } - - case ListChangedType.ItemMoved: - { - deferredOperation = new DeferredOperation( DeferredOperation.DeferredOperationAction.Move, -1, index, items, e.OldIndex, items ); - break; - } - - case ListChangedType.Reset: - { - deferredOperation = new DeferredOperation( DeferredOperation.DeferredOperationAction.Refresh, -1, null ); - break; - } - - default: - throw new NotSupportedException( "This ListChangedType (" + listChangedType.ToString() + ") is not supported." ); - } - - Debug.Assert( deferredOperation != null ); - - this.ExecuteOrQueueSourceItemOperation( deferredOperation ); - } - } - } - - private void HandlePropertyDescriptorAdded( PropertyDescriptor property ) - { - this.ClearDefaultPropertyDescriptions(); - this.SetupDefaultPropertyDescriptions(); - - if( !this.AutoCreateItemProperties ) - return; - - if( m_itemProperties[ property.Name ] != null ) - return; - - var propertyRoute = PropertyRouteParser.Parse( property.Name ); - if( propertyRoute == null ) - return; - - ItemsSourceHelper.CreateAndAddItemPropertyForPropertyDescription( m_itemProperties, m_defaultPropertyDescriptions[ propertyRoute ] ); - ItemsSourceHelper.AutoDetectSynonyms( this, DataGridItemPropertyRoute.Create( ItemsSourceHelper.GetItemPropertyFromProperty( m_itemProperties, propertyRoute ) ) ); - } - - private void HandlePropertyDescriptorChanged( PropertyDescriptor property ) - { - this.ClearDefaultPropertyDescriptions(); - this.SetupDefaultPropertyDescriptions(); - - if( !this.AutoCreateItemProperties ) - return; - - if( property == null ) - { - using( m_itemProperties.DeferCollectionChanged() ) - { - for( int i = m_itemProperties.Count - 1; i >= 0; i-- ) - { - var oldItemProperty = m_itemProperties[ i ] as DataGridItemProperty; - if( ( oldItemProperty != null ) && ( oldItemProperty.IsAutoCreated ) ) - { - m_itemProperties.RemoveAt( i ); - } - } - } - - ItemsSourceHelper.CreateAndAddItemPropertiesForPropertyDescriptions( m_itemProperties, m_defaultPropertyDescriptions.Values ); - ItemsSourceHelper.AutoDetectSynonyms( this ); - } - else - { - var oldItemProperty = m_itemProperties[ property.Name ] as DataGridItemProperty; - - if( ( oldItemProperty != null ) && ( oldItemProperty.IsAutoCreated ) ) - { - // It is better to completely remove the item property and add a new one instead of changing is content. - m_itemProperties.Remove( oldItemProperty ); - - if( m_itemProperties[ property.Name ] != null ) - return; - - var propertyRoute = PropertyRouteParser.Parse( property.Name ); - if( propertyRoute == null ) - return; - - ItemsSourceHelper.CreateAndAddItemPropertyForPropertyDescription( m_itemProperties, m_defaultPropertyDescriptions[ propertyRoute ] ); - ItemsSourceHelper.AutoDetectSynonyms( this, DataGridItemPropertyRoute.Create( ItemsSourceHelper.GetItemPropertyFromProperty( m_itemProperties, propertyRoute ) ) ); - } - } - } - - private void HandlePropertyDescriptorDeleted( PropertyDescriptor property ) - { - this.ClearDefaultPropertyDescriptions(); - this.SetupDefaultPropertyDescriptions(); - - if( this.AutoCreateItemProperties ) - { - var oldItemProperty = m_itemProperties[ property.Name ] as DataGridItemProperty; - - if( ( oldItemProperty != null ) && ( oldItemProperty.IsAutoCreated ) ) - { - m_itemProperties.Remove( oldItemProperty ); - } - } - } - - #endregion - - #region CHILD COLLECTION CHANGED HANDLERS - - // This method is also called for sub properties. - private void OnItemPropertiesCollectionChanged( object sender, NotifyCollectionChangedEventArgs e ) - { - var addedItems = default( IEnumerable ); - var removedItems = default( IEnumerable ); - - switch( e.Action ) - { - case NotifyCollectionChangedAction.Add: - addedItems = e.NewItems.Cast(); - break; - - case NotifyCollectionChangedAction.Remove: - removedItems = e.OldItems.Cast(); - break; - - case NotifyCollectionChangedAction.Replace: - addedItems = e.NewItems.Cast(); - removedItems = e.OldItems.Cast(); - break; - - case NotifyCollectionChangedAction.Reset: - throw new NotSupportedException(); - } - - if( ( addedItems == null ) && ( removedItems == null ) ) - return; - - var deferRefresh = ( this.Loaded ) ? this.DeferRefresh() : null; - - try - { - if( removedItems != null ) - { - foreach( var itemProperty in removedItems ) - { - this.ClearItemProperty( itemProperty ); - } - } - - if( addedItems != null ) - { - foreach( var itemProperty in addedItems ) - { - this.PrepareItemProperty( itemProperty ); - } - } - } - finally - { - lock( this.SyncRoot ) - { - lock( this.DeferredOperationManager ) - { - //This is required as the GroupSortStatResultPropertyName property affects this collection, and thus must be updated when there is a change to the ItemsProperties. - this.ClearGroupSortComparers(); - } - } - - if( deferRefresh != null ) - { - deferRefresh.Dispose(); - } - } - } - - private void OnItemPropertyPropertyChanged( DataGridItemPropertyBase itemProperty, PropertyChangedEventArgs e ) - { - if( itemProperty == null ) - return; - - var propertyName = e.PropertyName; - - if( string.IsNullOrEmpty( propertyName ) || ( propertyName == DataGridItemPropertyBase.ItemPropertiesInternalPropertyName ) ) - { - var itemProperties = itemProperty.ItemPropertiesInternal; - if( itemProperties != null ) - { - this.ClearItemProperties( itemProperties ); - this.PrepareItemProperties( itemProperties ); - } - } - } - - private void OnSortDescriptionsChanged( object sender, NotifyCollectionChangedEventArgs e ) - { - lock( this.SyncRoot ) - { - lock( this.DeferredOperationManager ) - { - this.ClearGroupSortComparers(); - - this.OnProxySortDescriptionsChanged( this, e ); - - if( this.DataGridSortDescriptions.IsResortDefered ) - { - this.DataGridSortDescriptions.AddResortNotification( this.DeferRefresh() ); - } - - this.ExecuteOrQueueSourceItemOperation( new DeferredOperation( DeferredOperation.DeferredOperationAction.Resort, -1, null ) ); - } - } - } - - private void OnGroupDescriptionsChanged( object sender, NotifyCollectionChangedEventArgs e ) - { - lock( this.SyncRoot ) - { - lock( this.DeferredOperationManager ) - { - this.ClearGroupSortComparers(); - - this.OnProxyGroupDescriptionsChanged( this, e ); - - this.ExecuteOrQueueSourceItemOperation( new DeferredOperation( DeferredOperation.DeferredOperationAction.Regroup, -1, null ) ); - } - } - } - - #endregion - - #region PROXY EVENTS - - internal DataGridCollectionViewBase RootDataGridCollectionViewBase - { - get - { - return m_rootDataGridCollectionViewBase; - } - } - - internal event EventHandler ProxyCollectionRefresh; - - internal void OnProxyCollectionRefresh() - { - if( m_rootDataGridCollectionViewBase.ProxyCollectionRefresh != null ) - { - m_rootDataGridCollectionViewBase.ProxyCollectionRefresh( this, EventArgs.Empty ); - } - } - - internal event NotifyCollectionChangedEventHandler ProxySortDescriptionsChanged; - - internal void OnProxySortDescriptionsChanged( object sender, NotifyCollectionChangedEventArgs e ) - { - if( m_rootDataGridCollectionViewBase.ProxySortDescriptionsChanged != null ) - { - m_rootDataGridCollectionViewBase.ProxySortDescriptionsChanged( sender, e ); - } - } - - internal event NotifyCollectionChangedEventHandler ProxyGroupDescriptionsChanged; - - internal void OnProxyGroupDescriptionsChanged( object sender, NotifyCollectionChangedEventArgs e ) - { - if( m_rootDataGridCollectionViewBase.ProxyGroupDescriptionsChanged != null ) - { - m_rootDataGridCollectionViewBase.ProxyGroupDescriptionsChanged( sender, e ); - } - } - - #endregion - - #region EDIT PROCESS - - internal void SetCurrentEditItem( object item ) - { - m_currentEditItem = item; - } - - private void EditItemInternal( object item, out bool beginEditCalled ) - { - if( item == null ) - throw new ArgumentNullException( "item" ); - - beginEditCalled = false; - IEditableObject editableObject = ItemsSourceHelper.GetEditableObject( item ); - - if( editableObject != null ) - { - // editableObject can be an Xceed DataRow when the datarow is directly inserted in us. - // In that case we do not call BeginEdit since we already being called from it. - if( !( editableObject is DataRow ) ) - { - editableObject.BeginEdit(); - beginEditCalled = true; - } - } - } - - private void EndEditInternal( object item, out bool endEditCalled ) - { - if( item == null ) - throw new ArgumentNullException( "item" ); - - endEditCalled = false; - var editableObject = ItemsSourceHelper.GetEditableObject( item ); - - // editableObject can be an Xceed datarow when directly inserted as Items in the DataGridControl. - if( ( editableObject != null ) && ( !( editableObject is Xceed.Wpf.DataGrid.DataRow ) ) ) - { - // Keep a copy of the values, because if EndEdit throw ( for a DataView ), we loose the old values. - var itemProperties = this.ItemProperties; - var oldValueBeforeEndEdit = new Dictionary( itemProperties.Count ); - - foreach( var itemProperty in itemProperties ) - { - oldValueBeforeEndEdit[ itemProperty ] = ItemsSourceHelper.GetValueFromItemProperty( itemProperty, item ); - } - - try - { - editableObject.EndEdit(); - endEditCalled = true; - } - finally - { - if( !endEditCalled ) - { - // Since the DataView of MS cancel the edition when EndEdit is throwing, we ensure to restart the editing mode. - editableObject.BeginEdit(); - - itemProperties.SuspendUnboundItemPropertyChanged( item ); - - try - { - // restore the oldvalues - foreach( var itemProperty in itemProperties ) - { - var readOnly = ( ( item == m_currentAddItem ) && itemProperty.OverrideReadOnlyForInsertion.HasValue && itemProperty.OverrideReadOnlyForInsertion.Value ) - ? false - : itemProperty.IsReadOnly; - - if( !readOnly ) - { - ItemsSourceHelper.SetValueForItemProperty( itemProperty, item, oldValueBeforeEndEdit[ itemProperty ] ); - } - } - } - finally - { - itemProperties.ResumeUnboundItemPropertyChanged( item ); - } - } - } - } - } - - private void CancelEditInternal( object item, out bool cancelEditCalled ) - { - if( item == null ) - throw new ArgumentNullException( "item" ); - - cancelEditCalled = false; - IEditableObject editableObject = ItemsSourceHelper.GetEditableObject( item ); - - // editableObject can be an Xceed datarow when directly inserted as Items in the DataGridControl. - if( ( editableObject != null ) && ( !( editableObject is Xceed.Wpf.DataGrid.DataRow ) ) ) - { - editableObject.CancelEdit(); - cancelEditCalled = true; - } - } - - - public event EventHandler BeginningEdit; - - internal virtual void OnBeginningEdit( DataGridItemCancelEventArgs e ) - { - // We throw instead of setting e.Cancel to True because we do not want to give the developer the chance to set it back to False. - if( e.Item is EmptyDataItem ) - throw new DataGridException( "Cannot begin edit on an empty data item." ); - - if( this.BeginningEdit != null ) - this.BeginningEdit( this, e ); - - if( m_parentCollectionViewSourceBase != null ) - m_parentCollectionViewSourceBase.OnBeginningEdit( e ); - } - - public event EventHandler EditBegun; - - internal virtual void OnEditBegun( DataGridItemEventArgs e ) - { - if( this.EditBegun != null ) - this.EditBegun( this, e ); - - if( m_parentCollectionViewSourceBase != null ) - m_parentCollectionViewSourceBase.OnEditBegun( e ); - } - - public event EventHandler CancelingEdit; - - internal void OnCancelingEdit( DataGridItemHandledEventArgs e ) - { - if( this.CancelingEdit != null ) - this.CancelingEdit( this, e ); - - if( m_parentCollectionViewSourceBase != null ) - m_parentCollectionViewSourceBase.OnCancelingEdit( e ); - } - - public event EventHandler EditCanceled; - - internal virtual void OnEditCanceled( DataGridItemEventArgs e ) - { - if( this.EditCanceled != null ) - { - this.EditCanceled( this, e ); - } - - if( m_parentCollectionViewSourceBase != null ) - { - m_parentCollectionViewSourceBase.OnEditCanceled( e ); - } - } - - public event EventHandler CommittingEdit; - - internal void OnCommittingEdit( DataGridItemCancelEventArgs e ) - { - if( this.CommittingEdit != null ) - this.CommittingEdit( this, e ); - - if( m_parentCollectionViewSourceBase != null ) - m_parentCollectionViewSourceBase.OnCommittingEdit( e ); - } - - public event EventHandler EditCommitted; - - internal virtual void OnEditCommitted( DataGridItemEventArgs e ) - { - if( this.EditCommitted != null ) - this.EditCommitted( this, e ); - - if( m_parentCollectionViewSourceBase != null ) - m_parentCollectionViewSourceBase.OnEditCommitted( e ); - } - - #endregion - - #region INSERTION PROCESS - - internal void SetCurrentAddNew( object newItem, int position ) - { - m_currentAddItem = newItem; - m_currentAddItemPosition = position; - } - - public event EventHandler InitializingNewItem; - - internal void OnInitializingNewItem( DataGridItemEventArgs e ) - { - if( this.InitializingNewItem != null ) - this.InitializingNewItem( this, e ); - - if( m_parentCollectionViewSourceBase != null ) - m_parentCollectionViewSourceBase.OnInitializingNewItem( e ); - } - - public event EventHandler CreatingNewItem; - - internal void OnCreatingNewItem( DataGridCreatingNewItemEventArgs e ) - { - if( this.CreatingNewItem != null ) - this.CreatingNewItem( this, e ); - - if( m_parentCollectionViewSourceBase != null ) - m_parentCollectionViewSourceBase.OnCreatingNewItem( e ); - } - - public event EventHandler CommittingNewItem; - - internal void OnCommittingNewItem( DataGridCommittingNewItemEventArgs e ) - { - if( this.CommittingNewItem != null ) - this.CommittingNewItem( this, e ); - - if( m_parentCollectionViewSourceBase != null ) - m_parentCollectionViewSourceBase.OnCommittingNewItem( e ); - } - - public event EventHandler CancelingNewItem; - - internal void OnCancelingNewItem( DataGridItemHandledEventArgs e ) - { - if( this.CancelingNewItem != null ) - this.CancelingNewItem( this, e ); - - if( m_parentCollectionViewSourceBase != null ) - m_parentCollectionViewSourceBase.OnCancelingNewItem( e ); - } - - public event EventHandler NewItemCreated; - - internal void OnNewItemCreated( DataGridItemEventArgs e ) - { - if( this.NewItemCreated != null ) - this.NewItemCreated( this, e ); - - if( m_parentCollectionViewSourceBase != null ) - m_parentCollectionViewSourceBase.OnNewItemCreated( e ); - } - - public event EventHandler NewItemCommitted; - - internal void OnNewItemCommitted( DataGridItemEventArgs e ) - { - if( this.NewItemCommitted != null ) - this.NewItemCommitted( this, e ); - - if( m_parentCollectionViewSourceBase != null ) - m_parentCollectionViewSourceBase.OnNewItemCommitted( e ); - } - - public event EventHandler NewItemCanceled; - - internal void OnNewItemCanceled( DataGridItemEventArgs e ) - { - if( this.NewItemCanceled != null ) - this.NewItemCanceled( this, e ); - - if( m_parentCollectionViewSourceBase != null ) - m_parentCollectionViewSourceBase.OnNewItemCanceled( e ); - } - - #endregion - - #region DELETION PROCESS - - internal void InternalRemoveAt( int sourceIndex ) - { - IList list = m_enumeration as IList; - - if( list != null ) - { - list.RemoveAt( sourceIndex ); - return; - } - - throw new InvalidOperationException( "An attempt was made to remove an item from the source collection." ); - } - - public event EventHandler RemovingItem; - - internal void OnRemovingItem( DataGridRemovingItemEventArgs e ) - { - if( this.RemovingItem != null ) - this.RemovingItem( this, e ); - - if( m_parentCollectionViewSourceBase != null ) - m_parentCollectionViewSourceBase.OnRemovingItem( e ); - } - - public event EventHandler ItemRemoved; - - internal void OnItemRemoved( DataGridItemRemovedEventArgs e ) - { - if( this.ItemRemoved != null ) - this.ItemRemoved( this, e ); - - if( m_parentCollectionViewSourceBase != null ) - m_parentCollectionViewSourceBase.OnItemRemoved( e ); - } - - #endregion - - #region CURRENCY MANAGEMENT - - internal IDisposable DeferCurrencyEvent() - { - return new DataGridCollectionViewBase.DeferCurrencyEventHelper( this ); - } - - internal bool IsCurrencyDeferred - { - get - { - return m_deferCurrencyEventCount > 0; - } - } - - public override object CurrentItem - { - get - { - return m_currentItem; - } - } - - public override int CurrentPosition - { - get - { - return m_currentPosition; - } - } - - public override bool IsCurrentAfterLast - { - get - { - return m_flags[ ( int )DataGridCollectionViewBaseFlags.IsCurrentAfterLast ]; - } - } - - public override bool IsCurrentBeforeFirst - { - get - { - return m_flags[ ( int )DataGridCollectionViewBaseFlags.IsCurrentBeforeFirst ]; - } - } - - public override bool MoveCurrentTo( object item ) - { - // This is done in DataGridCollectionView's IndexOf and MoveCurrentToPosition : - // this.EnsureThreadAndCollectionLoaded(); - - int index = this.IndexOf( item ); - return this.MoveCurrentToPosition( index ); - } - - public override bool MoveCurrentToFirst() - { - // This is done in DataGridCollectionView's MoveCurrentToPosition : - // this.EnsureThreadAndCollectionLoaded(); - - return this.MoveCurrentToPosition( 0 ); - } - - public override bool MoveCurrentToLast() - { - // This is done in DataGridCollectionView's MoveCurrentToPosition : - // this.EnsureThreadAndCollectionLoaded(); - - return this.MoveCurrentToPosition( this.Count - 1 ); - } - - public override bool MoveCurrentToNext() - { - // This is done in DataGridCollectionView's MoveCurrentToPosition : - // this.EnsureThreadAndCollectionLoaded(); - - if( this.CurrentPosition < this.Count ) - return this.MoveCurrentToPosition( this.CurrentPosition + 1 ); - - return false; - } - - public override bool MoveCurrentToPrevious() - { - // This is done in DataGridCollectionView's MoveCurrentToPosition : - // this.EnsureThreadAndCollectionLoaded(); - - if( this.CurrentPosition > -1 ) - return this.MoveCurrentToPosition( this.CurrentPosition - 1 ); - - return false; - } - - internal virtual void SetCurrentItemAndPositionCore( - object currentItem, - int currentPosition, - bool isCurrentBeforeFirst, - bool isCurrentAfterLast ) - { - m_currentItem = currentItem; - m_currentPosition = currentPosition; - - m_flags[ ( int )DataGridCollectionViewBaseFlags.IsCurrentBeforeFirst ] = isCurrentBeforeFirst; - m_flags[ ( int )DataGridCollectionViewBaseFlags.IsCurrentAfterLast ] = isCurrentAfterLast; - } - - #endregion - - #region DEFERRED OPERATIONS HANDLING - - internal event EventHandler PreBatchCollectionChanged; - internal event EventHandler PostBatchCollectionChanged; - - internal void RaisePreBatchCollectionChanged() - { - var handler = this.PreBatchCollectionChanged; - if( handler == null ) - return; - - handler.Invoke( this, EventArgs.Empty ); - } - - internal void RaisePostBatchCollectionChanged() - { - var handler = this.PostBatchCollectionChanged; - if( handler == null ) - return; - - handler.Invoke( this, EventArgs.Empty ); - } - - internal void EnsureThread() - { - if( !this.CheckAccess() ) - throw new InvalidOperationException( "An attempt was made to execute an operation on a thread other than the dispatcher thread." ); - } - - internal void EnsureThreadAndCollectionLoaded() - { - this.EnsureThread(); - - if( !this.Loaded ) - { - this.ForceRefresh( false, true, true ); - Debug.Assert( this.Loaded ); - } - } - - private bool QueueOperationForAddNew - { - get - { - return m_flags[ ( int )DataGridCollectionViewBaseFlags.QueueOperationForAddNew ]; - } - set - { - m_flags[ ( int )DataGridCollectionViewBaseFlags.QueueOperationForAddNew ] = value; - } - } - - internal bool ShouldDeferOperation - { - get - { - if( this.InDeferRefresh || !this.CheckAccess() ) - return true; - - lock( m_deferredOperationManager ) - { - return ( !this.Loaded ) || ( m_deferredOperationManager.HasPendingOperations ); - } - } - } - - private bool MustQueueOperationForPendingAddNew( int index, IList oldItems, IList newItems ) - { - if( this.QueueOperationForAddNew ) - return true; - - if( m_currentAddItem == null ) - return false; - - if( oldItems != null ) - { - if( ( oldItems.Count == 1 ) && ( oldItems[ 0 ] == m_currentAddItem ) ) - return true; - } - - if( newItems != null ) - { - if( ( newItems.Count == 1 ) && ( newItems[ 0 ] == m_currentAddItem ) ) - return true; - } - - if( ( oldItems == null ) && ( newItems == null ) ) - { - if( index == -1 ) - return false; - - if( m_currentAddItemPosition == index ) - return true; - } - - return false; - } - - internal void ExecuteOrQueueSourceItemOperation( DeferredOperation deferredOperation ) - { - bool queueOperationForPendingAddNew = this.MustQueueOperationForPendingAddNew( deferredOperation.OldStartingIndex, deferredOperation.OldItems, deferredOperation.NewItems ); - - if( queueOperationForPendingAddNew ) - { - this.AddDeferredOperationForAddNew( deferredOperation ); - } - else if( this.ShouldDeferOperation ) - { - this.AddDeferredOperation( deferredOperation ); - } - else - { - bool refreshForced; - this.ExecuteSourceItemOperation( deferredOperation, out refreshForced ); - } - } - - internal virtual void ExecuteSourceItemOperation( DeferredOperation deferredOperation, out bool refreshForced ) - { - throw new NotSupportedException( deferredOperation.Action.ToString() + " is not a supported action." ); - } - - internal void AddDeferredOperation( DeferredOperation deferredOperation ) - { - m_deferredOperationManager.Add( deferredOperation ); - } - - private void AddDeferredOperationForAddNew( DeferredOperation deferredOperation ) - { - if( m_deferredAddNewOperationManager == null ) - m_deferredAddNewOperationManager = new DeferredOperationManager( this, null, false ); - - m_deferredAddNewOperationManager.Add( deferredOperation ); - } - - #endregion - - protected override void OnCollectionChanged( NotifyCollectionChangedEventArgs args ) - { - - if( ( args != null ) - && ( ( ( args.NewItems != null ) && ( args.NewItems.Count > 1 ) ) - || ( ( args.OldItems != null ) && ( args.OldItems.Count > 1 ) ) ) ) - { - args = new NotifyRangeCollectionChangedEventArgs( args ); - } - - base.OnCollectionChanged( args ); - } - - internal virtual void ProcessInvalidatedGroupStats( HashSet invalidatedGroups, bool resortGroups ) - { - } - - internal virtual void ClearGroupSortComparers() - { - } - - internal virtual bool CanCreateItemProperties() - { - return ( ( m_enumeration != null ) || ( m_itemType != typeof( object ) ) || this.CanCreateItemPropertiesFromModelSource ); - } - - internal virtual void CreateDefaultCollections( DataGridDetailDescription parentDetailDescription ) - { - Debug.Assert( parentDetailDescription == null ); - - m_sortDescriptions = ( parentDetailDescription == null ) ? new DataGridSortDescriptionCollection() : parentDetailDescription.SortDescriptions as DataGridSortDescriptionCollection; - m_groupDescriptions = ( parentDetailDescription == null ) ? new GroupDescriptionCollection() : parentDetailDescription.GroupDescriptions; - } - - internal bool IsSourceSupportingChangeNotification - { - get - { - return ItemsSourceHelper.IsSourceSupportingChangeNotification( m_enumeration ); - } - } - - internal void PrepareRootContextForDeferRefresh( DataGridContext dataGridContext ) - { - this.DataGridContext = dataGridContext; - m_detailDeferRefreshes = new List>(); - } - - internal void Dispose() - { - if( this.ParentCollectionViewSourceBase != null ) - { - this.ParentCollectionViewSourceBase = null; - - this.ClearDefaultPropertyDescriptions(); - this.ClearItemProperties(); - } - - this.ClearItemProperties( m_itemProperties ); - this.UnregisterChangedEvents(); - } - - private void SetupDefaultDetailDescriptions() - { - if( ( m_parentDetailDescription != null ) && m_parentDetailDescription.AutoCreateDetailDescriptionsCompleted ) - return; - - if( this.AutoCreateDetailDescriptions) - { - var defaultDetailDescriptions = ItemsSourceHelper.CreateDetailDescriptions( m_itemType, m_enumeration ); - if( defaultDetailDescriptions != null ) - { - foreach( var detailDescription in defaultDetailDescriptions ) - { - if( m_detailDescriptions[ detailDescription.RelationName ] != null ) - continue; - - if( detailDescription.IsAutoCreated ) - { - // Propagate the AutoCreateForeignKeyDescriptions values to the auto created DataGridDetailDescription. - detailDescription.AutoCreateForeignKeyDescriptions = this.AutoCreateForeignKeyDescriptions; - } - - m_detailDescriptions.Add( detailDescription ); - } - } - } - - if( m_parentDetailDescription != null ) - { - m_parentDetailDescription.AutoCreateDetailDescriptionsCompleted = true; - } - } - - private void SetupCurrent( bool setToFirstItem ) - { - Debug.Assert( !this.Loaded ); - - var enumerator = ( m_enumeration != null ) ? m_enumeration.GetEnumerator() : null; - - try - { - if( ( enumerator != null ) && enumerator.MoveNext() ) - { - if( setToFirstItem ) - { - this.SetCurrentItemAndPositionCore( enumerator.Current, 0, false, false ); - } - else - { - this.SetCurrentItemAndPositionCore( null, -1, true, false ); - } - } - else - { - this.SetCurrentItemAndPositionCore( null, -1, true, true ); - } - } - finally - { - var disposable = enumerator as IDisposable; - if( disposable != null ) - { - disposable.Dispose(); - } - } - } - - private void RegisterChangedEvents() - { - this.RegisterSourceChanged( m_enumeration ); - - CollectionChangedEventManager.AddListener( m_sortDescriptions, this ); - CollectionChangedEventManager.AddListener( m_groupDescriptions, this ); - - ItemPropertyGroupSortStatNameChangedEventManager.AddListener( m_itemProperties, this ); - - if( m_parentDetailDescription == null ) - { - InitializeItemPropertyEventManager.AddListener( m_itemProperties, this ); - CollectionChangedEventManager.AddListener( m_detailDescriptions, this ); - } - } - - private void UnregisterChangedEvents() - { - this.UnregisterSourceChanged( m_enumeration ); - - CollectionChangedEventManager.RemoveListener( m_sortDescriptions, this ); - CollectionChangedEventManager.RemoveListener( m_groupDescriptions, this ); - - ItemPropertyGroupSortStatNameChangedEventManager.RemoveListener( m_itemProperties, this ); - - if( m_parentDetailDescription == null ) - { - InitializeItemPropertyEventManager.RemoveListener( m_itemProperties, this ); - CollectionChangedEventManager.RemoveListener( m_detailDescriptions, this ); - } - } - - private void RegisterSourceChanged( IEnumerable source ) - { - if( source == null ) - return; - - var collectionChanged = source as INotifyCollectionChanged; - var bindingList = source as IBindingList; - - if( collectionChanged != null ) - { - CollectionChangedEventManager.AddListener( collectionChanged, this ); - } - else if( ( bindingList != null ) && bindingList.SupportsChangeNotification ) - { - ListChangedEventManager.AddListener( bindingList, this ); - } - } - - private void UnregisterSourceChanged( IEnumerable source ) - { - if( source == null ) - return; - - var collectionChanged = source as INotifyCollectionChanged; - if( collectionChanged != null ) - { - CollectionChangedEventManager.RemoveListener( collectionChanged, this ); - } - var bindingList = source as IBindingList; - if( ( bindingList != null ) && bindingList.SupportsChangeNotification ) - { - ListChangedEventManager.RemoveListener( bindingList, this ); - } - } - - private void RegisterItemProperties( DataGridItemPropertyCollection itemProperties ) - { - if( itemProperties == null ) - return; - - CollectionChangedEventManager.AddListener( itemProperties, this ); - } - - private void UnregisterItemProperties( DataGridItemPropertyCollection itemProperties ) - { - if( itemProperties == null ) - return; - - CollectionChangedEventManager.RemoveListener( itemProperties, this ); - } - - private void RegisterItemProperty( DataGridItemPropertyBase itemProperty ) - { - if( itemProperty == null ) - return; - - PropertyChangedEventManager.AddListener( itemProperty, this, DataGridItemPropertyBase.ItemPropertiesInternalPropertyName ); - } - - private void UnregisterItemProperty( DataGridItemPropertyBase itemProperty ) - { - if( itemProperty == null ) - return; - - PropertyChangedEventManager.RemoveListener( itemProperty, this, DataGridItemPropertyBase.ItemPropertiesInternalPropertyName ); - } - - private void PrepareItemProperties( DataGridItemPropertyCollection itemProperties ) - { - if( itemProperties == null ) - return; - - foreach( var itemProperty in itemProperties ) - { - this.PrepareItemProperty( itemProperty ); - } - - this.RegisterItemProperties( itemProperties ); - } - - private void ClearItemProperties( DataGridItemPropertyCollection itemProperties ) - { - if( itemProperties == null ) - return; - - foreach( var itemProperty in itemProperties ) - { - this.ClearItemProperty( itemProperty ); - } - - this.UnregisterItemProperties( itemProperties ); - } - - private void PrepareItemProperty( DataGridItemPropertyBase itemProperty ) - { - if( itemProperty == null ) - return; - - // Set default value for CalculateDistinctValues if not explicitly set. - if( !itemProperty.IsCalculateDistinctValuesInitialized && ( m_parentDetailDescription != null ) ) - { - itemProperty.CalculateDistinctValues = m_parentDetailDescription.DefaultCalculateDistinctValues; - } - - var propertyPath = PropertyRouteParser.Parse( itemProperty ); - - this.RegisterItemProperty( itemProperty ); - this.PrepareItemProperties( itemProperty.ItemPropertiesInternal ); - } - - private void ClearItemProperty( DataGridItemPropertyBase itemProperty ) - { - if( itemProperty == null ) - return; - - this.ClearItemProperties( itemProperty.ItemPropertiesInternal ); - this.UnregisterItemProperty( itemProperty ); - - var propertyPath = PropertyRouteParser.Parse( itemProperty ); - } - - private void SetupDefaultPropertyDescriptions() - { - if( this.DefaultPropertyDescriptionsCreated ) - return; - - var modelDataTable = ( m_enumeration as DataTable ) ?? ( m_modelSource as DataTable ); - - if( this.CanCreateItemProperties() ) - { - this.DefaultItemPropertiesInitialized = false; - this.DefaultPropertyDescriptionsCreated = true; - - ItemsSourceHelper.SetPropertyDescriptions( m_defaultPropertyDescriptions, modelDataTable, m_enumeration, m_itemType, true ); - } - - if( !this.DefaultItemPropertiesInitialized ) - { - this.DefaultItemPropertiesInitialized = true; - - // Initialize the item properties according to the default property descriptions. - foreach( var itemProperty in m_itemProperties ) - { - var itemPropertyRoute = DataGridItemPropertyRoute.Create( itemProperty ); - - ItemsSourceHelper.SetPropertyDescriptionsFromItemProperty( m_defaultPropertyDescriptions, modelDataTable, m_enumeration, m_itemType, itemPropertyRoute ); - ItemsSourceHelper.InitializePropertyDescriptions( m_defaultPropertyDescriptions, itemPropertyRoute, m_itemType, this.DefaultPropertyDescriptionsCreated ); - } - } - } - - private void ClearDefaultPropertyDescriptions() - { - this.DefaultItemPropertiesInitialized = false; - this.DefaultPropertyDescriptionsCreated = false; - - m_defaultPropertyDescriptions.Clear(); - } - - private void ClearItemProperties() - { - m_itemProperties.Clear(); - } - - #region IWeakEventListener Members - - 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( managerType == typeof( CollectionChangedEventManager ) ) - { - var eventArgs = ( NotifyCollectionChangedEventArgs )e; - - if( sender == this.SortDescriptions ) - { - this.OnSortDescriptionsChanged( sender, eventArgs ); - } - else if( sender == this.GroupDescriptions ) - { - this.OnGroupDescriptionsChanged( sender, eventArgs ); - } - else if( sender == this.Enumeration ) - { - this.OnItemsSourceCollectionChanged( sender, eventArgs ); - } - else if( sender is DataGridItemPropertyCollection ) - { - this.OnItemPropertiesCollectionChanged( sender, eventArgs ); - } - } - else if( managerType == typeof( PropertyChangedEventManager ) ) - { - var eventArgs = ( PropertyChangedEventArgs )e; - var itemProperty = sender as DataGridItemPropertyBase; - - if( itemProperty != null ) - { - this.OnItemPropertyPropertyChanged( itemProperty, eventArgs ); - } - } - else if( managerType == typeof( ListChangedEventManager ) ) - { - if( sender == this.Enumeration ) - { - this.OnItemsSourceListChanged( sender, ( ListChangedEventArgs )e ); - } - } - else if( managerType == typeof( ItemPropertyGroupSortStatNameChangedEventManager ) ) - { - if( sender == this.ItemProperties ) - { - this.ClearGroupSortComparers(); - } - } - else if( managerType == typeof( InitializeItemPropertyEventManager ) ) - { - var eventArgs = ( InitializeItemPropertyEventArgs )e; - - if( sender == this.ItemProperties ) - { - var itemProperty = eventArgs.ItemProperty; - var itemPropertyRoute = DataGridItemPropertyRoute.Create( itemProperty ); - var modelDataTable = ( m_enumeration as DataTable ) ?? ( m_modelSource as DataTable ); - - ItemsSourceHelper.SetPropertyDescriptionsFromItemProperty( m_defaultPropertyDescriptions, modelDataTable, m_enumeration, m_itemType, itemPropertyRoute ); - ItemsSourceHelper.InitializePropertyDescriptions( m_defaultPropertyDescriptions, itemPropertyRoute, m_itemType, this.DefaultPropertyDescriptionsCreated ); - ItemsSourceHelper.AutoDetectSynonyms( this, itemPropertyRoute ); - } - } - else - { - return false; - } - - return true; - } - - #endregion - - #region ICollectionView Members - - public override IDisposable DeferRefresh() - { - this.EnsureThread(); - - var dataGridContext = this.DataGridContext; - - if( dataGridContext != null ) - { - //Make sure detail DataGridCollectionView's are also deferred. - List detailDisposables = new List(); - foreach( DataGridContext detailContext in dataGridContext.GetChildContextsCore() ) - { - detailDisposables.Add( detailContext.Items.DeferRefresh() ); - } - - m_detailDeferRefreshes.Add( detailDisposables ); - } - - return new DataGridCollectionView.DeferRefreshHelper( this ); - } - - public override void Refresh() - { - this.EnsureThread(); - - var dataGridContext = this.DataGridContext; - - if( this.InDeferRefresh ) - { - if( dataGridContext != null ) - { - //Make sure to queue a Refresh on all detail DataGridCollectionView's. - foreach( DataGridContext detailContext in dataGridContext.GetChildContextsCore() ) - { - detailContext.Items.Refresh(); - } - } - - this.AddDeferredOperation( new DeferredOperation( DeferredOperation.DeferredOperationAction.Refresh, -1, null ) ); - } - else - { - if( dataGridContext != null ) - { - //Make sure all detail DataGridCollectionView's are refreshed. - foreach( DataGridContext detailContext in dataGridContext.GetChildContextsCore() ) - { - detailContext.Items.Refresh(); - } - } - - this.OnProxyCollectionRefresh(); - this.ForceRefresh( true, !this.Loaded, true ); - } - } - - public override SortDescriptionCollection SortDescriptions - { - get - { - return m_sortDescriptions; - } - } - - internal DataGridSortDescriptionCollection DataGridSortDescriptions - { - get - { - return m_sortDescriptions; - } - } - - public override ObservableCollection GroupDescriptions - { - get - { - return m_groupDescriptions; - } - } - - public override ReadOnlyObservableCollection Groups - { - get - { - if( m_groupDescriptions.Count > 0 ) - { - this.EnsureThreadAndCollectionLoaded(); - - IList rootGroups = m_rootGroup.GetItems(); - - Debug.Assert( rootGroups is ReadOnlyObservableCollection, - "The CollectionViewGroup GetItems extensibility method should always return a ReadOnlyObservableCollection when " + - "dealing with a DataGridVirtualizingCollectionViewGroupRoot which has subgroups." ); - - return ( ReadOnlyObservableCollection )rootGroups; - } - - return null; - } - } - - internal CollectionViewGroup RootGroup - { - get - { - return m_rootGroup; - } - set - { - m_rootGroup = value; - } - } - - public override bool CanSort - { - get - { - return true; - } - } - - public override bool CanGroup - { - get - { - return true; - } - } - - public override bool CanFilter - { - get - { - return true; - } - } - - public override Predicate Filter - { - get - { - return m_filter; - } - set - { - if( !this.CanFilter ) - throw new NotSupportedException(); - - if( ( value == null ) && ( value == m_filter ) ) - return; - - m_filter = value; - this.Refresh(); - } - } - - public override bool PassesFilter( object item ) - { - if( ( this.CanFilter ) && ( m_filter != null ) ) - return m_filter( item ); - - return true; - } - - #endregion - - #region IEditableCollectionView - - public virtual bool CanAddNew - { - get - { - return true; - } - } - - public virtual object AddNew() - { - if( !this.CanAddNew ) - throw new InvalidOperationException( "An attempt was made to add an item to a source that does not support addition." ); - - // If a current AddNew has not been committed, commit it. - this.CommitNew(); - this.CommitEdit(); - - this.QueueOperationForAddNew = true; - - try - { - DataGridCreatingNewItemEventArgs creatingNewItemEventArgs = new DataGridCreatingNewItemEventArgs( this, null, false ); - - this.RootDataGridCollectionViewBase.OnCreatingNewItem( creatingNewItemEventArgs ); - - this.SetCurrentAddNew( creatingNewItemEventArgs.NewItem, -1 ); - - if( creatingNewItemEventArgs.Cancel ) - throw new DataGridException( "AddNew was canceled." ); - - this.CreatingNewItemIsManuallyHandled = creatingNewItemEventArgs.Handled; - - if( this.CreatingNewItemIsManuallyHandled ) - { - if( m_currentAddItem == null ) - throw new InvalidOperationException( "An attempt was made to handle the CreatingNewItem event without providing a new item." ); - } - else - { - if( !this.HasSource ) - throw new InvalidOperationException( "The CreatingNewItem event must be handled when not using an underlying data source." ); - - int newItemIndex; - object newItem = ItemsSourceHelper.AddNewDataItem( this.Enumeration, null, out newItemIndex ); - - this.SetCurrentAddNew( newItem, newItemIndex ); - } - - DataGridItemEventArgs initializingNewItemEventArgs = new DataGridItemEventArgs( this, m_currentAddItem ); - this.RootDataGridCollectionViewBase.OnInitializingNewItem( initializingNewItemEventArgs ); - } - catch - { - // QueueOperationForAddNew must be off when calling CancelNew - this.QueueOperationForAddNew = false; - - if( m_currentAddItem != null ) - { - this.CancelNew(); - } - - throw; - } - finally - { - this.QueueOperationForAddNew = false; - } - - DataGridItemEventArgs itemCreatedEventArgs = new DataGridItemEventArgs( this, m_currentAddItem ); - m_rootDataGridCollectionViewBase.OnNewItemCreated( itemCreatedEventArgs ); - - return m_currentAddItem; - } - - public virtual void CommitNew() - { - if( m_currentAddItem == null ) - return; - - object item = m_currentAddItem; - DeferredOperation addOperationToNotifyIfNotAlreadyQueued = null; - this.QueueOperationForAddNew = true; - - try - { - DataGridCommittingNewItemEventArgs committingNewItemEventArgs = new DataGridCommittingNewItemEventArgs( this, m_currentAddItem, false ); - - this.RootDataGridCollectionViewBase.OnCommittingNewItem( committingNewItemEventArgs ); - - if( committingNewItemEventArgs.Cancel ) - throw new DataGridException( "CommitNew was canceled." ); - - if( this.CreatingNewItemIsManuallyHandled != committingNewItemEventArgs.Handled ) - throw new InvalidOperationException( "When manually handling the item-insertion process the CreatingNewItem, CommittingNewItem, and CancelingNewItem events must all be handled." ); - - if( !committingNewItemEventArgs.Handled ) - { - if( !this.HasSource ) - throw new InvalidOperationException( "The CommittingNewItem event must be handled when not using an underlying data source." ); - - int addItemPosition = m_currentAddItemPosition; - ItemsSourceHelper.EndNewDataItem( this.Enumeration, null, m_currentAddItem, ref addItemPosition ); - - addOperationToNotifyIfNotAlreadyQueued = new DeferredOperation( DeferredOperation.DeferredOperationAction.Add, addItemPosition + 1, - addItemPosition, new object[] { m_currentAddItem } ); - } - else - { - if( committingNewItemEventArgs.Index == -1 ) - throw new InvalidOperationException( "An attempt was made to handle the CommittingNewItem event without providing the index at which the new item was inserted." ); - - if( committingNewItemEventArgs.NewCount == -1 ) - throw new InvalidOperationException( "An attempt was made to handle the CommittingNewItem event without providing the new item count." ); - - if( committingNewItemEventArgs.Index >= committingNewItemEventArgs.NewCount ) - throw new InvalidOperationException( "The index at which the new item was inserted was greater than the new item count." ); - - addOperationToNotifyIfNotAlreadyQueued = new DeferredOperation( DeferredOperation.DeferredOperationAction.Add, committingNewItemEventArgs.NewCount, - committingNewItemEventArgs.Index, new object[] { m_currentAddItem } ); - } - - this.SetCurrentAddNew( null, -1 ); - } - finally - { - this.QueueOperationForAddNew = false; - } - - if( m_deferredAddNewOperationManager != null ) - { - m_deferredAddNewOperationManager.PurgeAddWithRemoveOrReplace(); - - DeferredOperationManager deferredOperationManager = this.DeferredOperationManager; - - lock( deferredOperationManager ) - { - if( this.ShouldDeferOperation ) - { - deferredOperationManager.Combine( m_deferredAddNewOperationManager ); - } - else - { - m_deferredAddNewOperationManager.Process(); - } - } - - m_deferredAddNewOperationManager = null; - } - else - { - Debug.Assert( !this.IsSourceSupportingChangeNotification ); - - // No pending operation was in m_deferredAddNewOperationManager, so the list has not trigger notification for the new item added. - // We will, in that case, raise the notification ourself. - this.ExecuteOrQueueSourceItemOperation( addOperationToNotifyIfNotAlreadyQueued ); - } - - DataGridItemEventArgs itemEventArgs = new DataGridItemEventArgs( this, item ); - m_rootDataGridCollectionViewBase.OnNewItemCommitted( itemEventArgs ); - } - - public virtual void CancelNew() - { - if( m_currentAddItem == null ) - return; - - object currentAddItem = m_currentAddItem; - this.QueueOperationForAddNew = true; - - try - { - DataGridItemHandledEventArgs cancelingNewItemEventArgs = new DataGridItemHandledEventArgs( this, currentAddItem ); - this.RootDataGridCollectionViewBase.OnCancelingNewItem( cancelingNewItemEventArgs ); - - if( this.CreatingNewItemIsManuallyHandled != cancelingNewItemEventArgs.Handled ) - throw new InvalidOperationException( "When manually handling the item-insertion process the CreatingNewItem, CommittingNewItem, and CancelingNewItem events must all be handled." ); - - if( !cancelingNewItemEventArgs.Handled ) - { - if( !this.HasSource ) - throw new InvalidOperationException( "The CancelingNewItem event must be handled when not using an underlying data source." ); - - ItemsSourceHelper.CancelNewDataItem( this.Enumeration, null, m_currentAddItem, m_currentAddItemPosition ); - } - - this.SetCurrentAddNew( null, -1 ); - } - finally - { - this.QueueOperationForAddNew = false; - } - - if( m_deferredAddNewOperationManager != null ) - { - m_deferredAddNewOperationManager.PurgeAddWithRemoveOrReplace(); - - DeferredOperationManager deferredOperationManager = this.DeferredOperationManager; - - lock( deferredOperationManager ) - { - if( this.ShouldDeferOperation ) - { - deferredOperationManager.Combine( m_deferredAddNewOperationManager ); - } - else - { - m_deferredAddNewOperationManager.Process(); - } - } - - m_deferredAddNewOperationManager = null; - } - - DataGridItemEventArgs itemEventArgs = new DataGridItemEventArgs( this, currentAddItem ); - m_rootDataGridCollectionViewBase.OnNewItemCanceled( itemEventArgs ); - } - - public virtual void EditItem( object item ) - { - if( item == null ) - throw new ArgumentNullException( "item" ); - - this.CommitNew(); - - if( m_currentEditItem == item ) - return; - - this.CommitEdit(); - - var itemCancelEventArgs = new DataGridItemCancelEventArgs( this, item, false ); - m_rootDataGridCollectionViewBase.OnBeginningEdit( itemCancelEventArgs ); - - if( itemCancelEventArgs.Cancel ) - throw new DataGridException( "EditItem was canceled." ); - - this.ItemEditionIsManuallyHandled = itemCancelEventArgs.Handled; - - if( !this.ItemEditionIsManuallyHandled ) - { - bool beginEditCalled; - this.EditItemInternal( item, out beginEditCalled ); - - if( !beginEditCalled ) - { - var itemProperties = this.ItemProperties; - m_oldValuesBeforeEdition = new Dictionary( itemProperties.Count ); - - foreach( var itemProperty in itemProperties ) - { - m_oldValuesBeforeEdition[ itemProperty ] = ItemsSourceHelper.GetValueFromItemProperty( itemProperty, item ); - } - } - } - - m_currentEditItem = item; - m_rootDataGridCollectionViewBase.OnEditBegun( new DataGridItemEventArgs( this, item ) ); - } - - public virtual void CommitEdit() - { - if( m_currentEditItem == null ) - return; - - var itemCancelEventArgs = new DataGridItemCancelEventArgs( this, m_currentEditItem, false ); - m_rootDataGridCollectionViewBase.OnCommittingEdit( itemCancelEventArgs ); - - if( itemCancelEventArgs.Cancel ) - throw new DataGridException( "CommitEdit was canceled." ); - - if( itemCancelEventArgs.Handled != this.ItemEditionIsManuallyHandled ) - throw new InvalidOperationException( "When manually handling the item-edition process the BeginningEdit, CommittingEdit, and CancelingEdit events must all be handled." ); - - if( !itemCancelEventArgs.Handled ) - { - bool endEditCalled; - this.EndEditInternal( m_currentEditItem, out endEditCalled ); - m_oldValuesBeforeEdition = null; - } - - var itemEventArgs = new DataGridItemEventArgs( this, m_currentEditItem ); - var index = this.IndexOfSourceItem( m_currentEditItem ); - - var items = new object[] { m_currentEditItem }; - m_currentEditItem = null; - - this.ExecuteOrQueueSourceItemOperation( new DeferredOperation( DeferredOperation.DeferredOperationAction.Replace, -1, index, items, index, items ) ); - - m_rootDataGridCollectionViewBase.OnEditCommitted( itemEventArgs ); - } - - public virtual bool CanCancelEdit - { - get - { - return true; - } - } - - public virtual void CancelEdit() - { - if( !this.CanCancelEdit ) - throw new InvalidOperationException( "An attempt was made to cancel the edit process on a source that does not support cancellation." ); - - if( m_currentEditItem == null ) - return; - - var itemHandleEventArgs = new DataGridItemHandledEventArgs( this, m_currentEditItem ); - m_rootDataGridCollectionViewBase.OnCancelingEdit( itemHandleEventArgs ); - - if( itemHandleEventArgs.Handled != this.ItemEditionIsManuallyHandled ) - throw new InvalidOperationException( "An attempt was made to manually handle the edit prcess without handling the BeginningEdit, CommittingEdit, and CancelingEdit events." ); - - if( !itemHandleEventArgs.Handled ) - { - bool cancelEditCalled; - this.CancelEditInternal( m_currentEditItem, out cancelEditCalled ); - - var itemProperties = this.ItemProperties; - - if( ( !cancelEditCalled ) && ( itemProperties.Count > 0 ) ) - { - itemProperties.SuspendUnboundItemPropertyChanged( m_currentEditItem ); - - try - { - foreach( var itemProperty in itemProperties ) - { - var readOnly = ( ( m_currentEditItem == m_currentAddItem ) && itemProperty.OverrideReadOnlyForInsertion.HasValue && itemProperty.OverrideReadOnlyForInsertion.Value ) - ? false - : itemProperty.IsReadOnly; - - if( readOnly ) - continue; - - try - { - ItemsSourceHelper.SetValueForItemProperty( itemProperty, m_currentEditItem, m_oldValuesBeforeEdition[ itemProperty ] ); - } - catch - { - // Swallow any Exception, setting a property to is old value should not throw. - } - } - } - finally - { - itemProperties.ResumeUnboundItemPropertyChanged( m_currentEditItem ); - } - } - } - - var itemEventArgs = new DataGridItemEventArgs( this, m_currentEditItem ); - m_currentEditItem = null; - m_rootDataGridCollectionViewBase.OnEditCanceled( itemEventArgs ); - } - - public virtual bool CanRemove - { - get - { - return true; - } - } - - public virtual void Remove( object item ) - { - if( !this.CanRemove ) - throw new InvalidOperationException( "An attempt was made to remove an item from a source that does not support removal." ); - - if( this.IsEditingItem || this.IsAddingNew ) - throw new InvalidOperationException( "An attempt was made to remove an item while an item is being edited or added." ); - - int sourceIndex = -2; - - if( ( !this.HasSource ) || ( !this.IsSourceSupportingChangeNotification ) ) - sourceIndex = this.IndexOfSourceItem( item ); - - DataGridRemovingItemEventArgs removingItemEventArgs = new DataGridRemovingItemEventArgs( this, item, -1, false ); - this.RootDataGridCollectionViewBase.OnRemovingItem( removingItemEventArgs ); - - if( removingItemEventArgs.Cancel ) - throw new DataGridException( "Remove was canceled." ); - - if( !removingItemEventArgs.Handled ) - { - if( !this.HasSource ) - throw new InvalidOperationException( "The RemovingItem event must be handled when not using an underlying data source." ); - - if( sourceIndex == -2 ) - sourceIndex = this.IndexOfSourceItem( item ); - - if( sourceIndex != -1 ) - this.InternalRemoveAt( sourceIndex ); - } - - if( ( !this.HasSource ) || ( !this.IsSourceSupportingChangeNotification ) ) - { - DeferredOperation deferredOperation = new DeferredOperation( - DeferredOperation.DeferredOperationAction.Remove, - sourceIndex, - new object[] { item } ); - - this.ExecuteOrQueueSourceItemOperation( deferredOperation ); - } - - DataGridItemRemovedEventArgs itemRemovedEventArgs = new DataGridItemRemovedEventArgs( this, item, -1 ); - this.RootDataGridCollectionViewBase.OnItemRemoved( itemRemovedEventArgs ); - } - - public virtual void RemoveAt( int index ) - { - object item = this.GetItemAt( index ); - this.Remove( item ); - } - - public virtual object CurrentAddItem - { - get - { - return m_currentAddItem; - } - } - - public virtual object CurrentEditItem - { - get - { - return m_currentEditItem; - } - } - - public virtual bool IsAddingNew - { - get - { - return m_currentAddItem != null; - } - } - - public virtual bool IsEditingItem - { - get - { - return m_currentEditItem != null; - } - } - - NewItemPlaceholderPosition IEditableCollectionView.NewItemPlaceholderPosition - { - get - { - return m_newItemPlaceholderPosition; - } - set - { - m_newItemPlaceholderPosition = value; - } - } - - private NewItemPlaceholderPosition m_newItemPlaceholderPosition = NewItemPlaceholderPosition.None; - - #endregion - - #region IItemProperties Members - - ReadOnlyCollection IItemProperties.ItemProperties - { - get - { - List itemPropertyInfos = this.GetItemPropertyInfos(); - - if( itemPropertyInfos == null ) - return null; - - return new ReadOnlyCollection( itemPropertyInfos ); - } - } - - internal virtual List GetItemPropertyInfos() - { - return ( from item in m_itemProperties - select new ItemPropertyInfo( item.Name, item.DataType, item.GetPropertyDescriptorForBinding() ) ).ToList(); - } - - #endregion - - private BitVector32 m_flags = new BitVector32(); - - private DeferredOperationManager m_deferredOperationManager; - private DeferredOperationManager m_deferredAddNewOperationManager; - - private int m_deferRefreshCount; - - private readonly DataGridCollectionViewBase m_rootDataGridCollectionViewBase; - - private Type m_itemType; - private Type m_desiredItemType; - private object m_modelSource; - private IEnumerable m_enumeration; - - private int m_currentPosition; - private object m_currentItem; - private int m_deferCurrencyEventCount; - - private object m_currentEditItem; - private Dictionary m_oldValuesBeforeEdition; - - private object m_currentAddItem; - private int m_currentAddItemPosition = -1; - - private DistinctValuesConstraint m_distinctValuesConstraint = DistinctValuesConstraint.All; - private DistinctValuesUpdateMode m_distinctValueUpdateMode = DistinctValuesUpdateMode.Manual; - - private List m_filteredItemProperties; - private ReadOnlyCollection m_readOnlyFilteredItemProperties; - - private DataGridDetailDescription m_parentDetailDescription; - - private readonly DataGridItemPropertyCollection m_itemProperties; - - private DataGridSortDescriptionCollection m_sortDescriptions; - private ObservableCollection m_groupDescriptions; - private readonly DataGridDetailDescriptionCollection m_detailDescriptions; - private readonly PropertyDescriptionRouteDictionary m_defaultPropertyDescriptions; - - private CollectionViewGroup m_rootGroup; - - private Predicate m_filter; - - // Containing a DataGridItemProperty key, ObservableCollection values map - private DistinctValuesDictionary m_distinctValues; - private DataGridItemPropertyBase m_excludedItemPropertyFromDistinctValueCalculation; - - [Flags] - private enum DataGridCollectionViewBaseFlags - { - Loaded = 1 << 0, - Refreshing = 1 << 1, - QueueOperationForAddNew = 1 << 2, - IsRefreshingDistinctValues = 1 << 3, - IsCurrentAfterLast = 1 << 4, - IsCurrentBeforeFirst = 1 << 5, - CreatingNewItemIsManuallyHandled = 1 << 6, - ItemEditionIsManuallyHandled = 1 << 7, - AutoCreateItemProperties = 1 << 8, - AutoCreateDetailDescriptions = 1 << 9, - AutoCreateForeignKeyDescriptions = 1 << 10, - DefaultItemPropertiesInitialized = 1 << 11, - DefaultPropertyDescriptionsCreated = 1 << 12, - } - - private sealed class DeferRefreshHelper : IDisposable - { - public DeferRefreshHelper( DataGridCollectionViewBase collectionView ) - { - m_collectionView = collectionView; - - Interlocked.Increment( ref collectionView.m_deferRefreshCount ); - } - - void IDisposable.Dispose() - { - this.Dispose( true ); - GC.SuppressFinalize( this ); - } - - private void Dispose( bool disposing ) - { - // Prevent this method from being invoked more than once by the same IDisposable. - var collectionView = Interlocked.Exchange( ref m_collectionView, null ); - if( collectionView == null ) - return; - - if( collectionView.CheckAccess() ) - { - DeferRefreshHelper.ProcessDispose( collectionView ); - } - else - { - //In case Dispose is called from a different thread, make sure the refresh is done on the UI thread. - collectionView.Dispatcher.BeginInvoke( new Action( DeferRefreshHelper.ProcessDispose ), DispatcherPriority.Send, collectionView ); - } - } - - private static void ProcessDispose( DataGridCollectionViewBase collectionView ) - { - //If there are detail DataGridCollectionView's being defered. - if( collectionView.m_detailDeferRefreshes != null && collectionView.m_detailDeferRefreshes.Count > 0 ) - { - //Dispose them. - foreach( IDisposable detailDisposable in collectionView.m_detailDeferRefreshes[ 0 ] ) - { - if( detailDisposable != null ) - { - detailDisposable.Dispose(); - } - } - - //Clear and remove the list that was just disposed of. - collectionView.m_detailDeferRefreshes[ 0 ].Clear(); - collectionView.m_detailDeferRefreshes.RemoveAt( 0 ); - } - - //Only process the DeferRefresh when count is back to 0. - if( Interlocked.Decrement( ref collectionView.m_deferRefreshCount ) > 0 ) - return; - - if( collectionView.Loaded ) - { - collectionView.m_deferredOperationManager.Process(); - } - else - { - // We call ForceRefresh when not yet "Loaded" because we want the Dispose here to triger the CollectionChanged( NotifyCollectionChangedAction.Reset ) - // This is needed because of the way the ItemsControl works (other than our grid). - collectionView.ForceRefresh( true, true, true ); - } - } - - ~DeferRefreshHelper() - { - //Make sure the defering process for the CollectionView stays in a valid state, by disposing of details and properly setting the count. - this.Dispose( false ); - } - - private DataGridCollectionViewBase m_collectionView; - } - - private sealed class DeferCurrencyEventHelper : IDisposable - { - public DeferCurrencyEventHelper( DataGridCollectionViewBase collectionView ) - { - m_collectionView = collectionView; - m_oldCurrentItem = m_collectionView.CurrentItem; - m_oldCurrentPosition = m_collectionView.CurrentPosition; - m_oldIsCurrentBeforeFirst = m_collectionView.IsCurrentBeforeFirst; - m_oldIsCurrentAfterLast = m_collectionView.IsCurrentAfterLast; - - Interlocked.Increment( ref m_collectionView.m_deferCurrencyEventCount ); - } - - void IDisposable.Dispose() - { - this.Dispose( true ); - GC.SuppressFinalize( this ); - } - - private void Dispose( bool disposing ) - { - // Prevent this method from being invoked more than once by the same IDisposable. - var collectionView = Interlocked.Exchange( ref m_collectionView, null ); - if( collectionView == null ) - return; - - if( collectionView.CheckAccess() ) - { - DeferCurrencyEventHelper.ProcessDispose( collectionView, m_oldCurrentItem, m_oldCurrentPosition, m_oldIsCurrentBeforeFirst, m_oldIsCurrentAfterLast ); - } - else - { - // Make sure the calls to the collection view will be done on the collection view's thread. - collectionView.Dispatcher.BeginInvoke( - new Action( DeferCurrencyEventHelper.ProcessDispose ), - DispatcherPriority.Send, - collectionView, - m_oldCurrentItem, - m_oldCurrentPosition, - m_oldIsCurrentBeforeFirst, - m_oldIsCurrentAfterLast ); - } - } - - private static void ProcessDispose( - DataGridCollectionViewBase collectionView, - object oldCurrentItem, - int oldCurrentPosition, - bool oldIsCurrentBeforeFirst, - bool oldIsCurrentAfterLast ) - { - if( Interlocked.Decrement( ref collectionView.m_deferCurrencyEventCount ) > 0 ) - return; - - bool itemChanged = false; - - if( !object.Equals( oldCurrentItem, collectionView.CurrentItem ) ) - { - itemChanged = true; - collectionView.OnPropertyChanged( new PropertyChangedEventArgs( "CurrentItem" ) ); - } - - if( oldCurrentPosition != collectionView.CurrentPosition ) - { - itemChanged = true; - collectionView.OnPropertyChanged( new PropertyChangedEventArgs( "CurrentPosition" ) ); - } - - if( oldIsCurrentBeforeFirst != collectionView.IsCurrentBeforeFirst ) - { - itemChanged = true; - collectionView.OnPropertyChanged( new PropertyChangedEventArgs( "IsCurrentBeforeFirst" ) ); - } - - if( oldIsCurrentAfterLast != collectionView.IsCurrentAfterLast ) - { - itemChanged = true; - collectionView.OnPropertyChanged( new PropertyChangedEventArgs( "IsCurrentAfterLast" ) ); - } - - if( itemChanged ) - { - collectionView.OnCurrentChanged(); - } - } - - ~DeferCurrencyEventHelper() - { - this.Dispose( false ); - } - - private readonly int m_oldCurrentPosition; - private readonly object m_oldCurrentItem; - private readonly bool m_oldIsCurrentAfterLast; - private readonly bool m_oldIsCurrentBeforeFirst; - - private DataGridCollectionViewBase m_collectionView; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewBaseDataProvider.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewBaseDataProvider.cs deleted file mode 100644 index 93604b4e..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewBaseDataProvider.cs +++ /dev/null @@ -1,179 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Diagnostics; -using System.Windows; -using System.Windows.Data; -using System.Windows.Threading; - -namespace Xceed.Wpf.DataGrid -{ - internal abstract class DataGridCollectionViewBaseDataProvider : DataSourceProvider, IWeakEventListener - { - internal DataGridCollectionViewBaseDataProvider( DataGridCollectionViewSourceBase parentSource ) - : base() - { - if( parentSource == null ) - throw new ArgumentNullException( "parentSource" ); - - m_parentSource = parentSource; - } - - #region CurrentView Property - - public DataGridCollectionViewBase CurrentView - { - get - { - return m_currentView; - } - } - - private DataGridCollectionViewBase m_currentView; - - #endregion - - #region ParentSource Internal Property - - internal DataGridCollectionViewSourceBase ParentSource - { - get - { - return m_parentSource; - } - } - - private readonly DataGridCollectionViewSourceBase m_parentSource; - - #endregion - - public void DelayRefresh( Dispatcher dispatcher, DispatcherPriority priority ) - { - // No need to call Refresh again since there is already one that is pending. - if( m_delayedRefreshPending ) - return; - - // Call Refresh on the dispatcher with the specified priority. - var operation = dispatcher.BeginInvoke( - priority, - new Action( delegate - { - this.Refresh(); - } ) ); - - // If we're not already completed, set the internal flag to prevent - // another Refresh from being stacked on register to be notified - // when the operation complete. - if( operation.Status != DispatcherOperationStatus.Completed ) - { - m_delayedRefreshPending = true; - operation.Completed += new EventHandler( this.OnDelayedRefreshCompleted ); - } - } - - protected override void BeginQuery() - { - var queryException = default( Exception ); - - try - { - this.EnsureDataGridCollectionViewBase(); - } - catch( Exception exception ) - { - queryException = exception; - } - - this.OnQueryFinished( m_currentView, queryException, null, null ); - } - - internal abstract DataGridCollectionViewBase EnsureDataGridCollectionViewBaseCore(); - - private void EnsureDataGridCollectionViewBase() - { - var success = false; - - try - { - var newView = this.EnsureDataGridCollectionViewBaseCore(); - if( newView != m_currentView ) - { - this.ClearView(); - - m_currentView = newView; - - if( m_currentView != null ) - { - m_currentView.ParentCollectionViewSourceBase = m_parentSource; - } - } - - Debug.Assert( ( m_currentView == null ) || ( m_currentView.ParentCollectionViewSourceBase == m_parentSource ) ); - - success = true; - } - finally - { - if( !success ) - { - this.ClearView(); - } - } - } - - private void ClearView() - { - if( m_currentView == null ) - return; - - var view = m_currentView; - m_currentView = null; - - view.Dispose(); - } - - private void OnDelayedRefreshCompleted( object sender, EventArgs e ) - { - m_delayedRefreshPending = false; - } - - #region IWeakEventListener Members - - 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( managerType == typeof( DataChangedEventManager ) ) - { - this.Refresh(); - } - else - { - return false; - } - - return true; - } - - #endregion - - private bool m_delayedRefreshPending; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewDataProvider.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewDataProvider.cs deleted file mode 100644 index c0c390af..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewDataProvider.cs +++ /dev/null @@ -1,95 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Windows.Data; -using System.Windows; -using System.ComponentModel; -using System.Collections; -using System.Diagnostics; - -namespace Xceed.Wpf.DataGrid -{ - internal class DataGridCollectionViewDataProvider : DataGridCollectionViewBaseDataProvider - { - #region CONSTRUCTORS - - public DataGridCollectionViewDataProvider( DataGridCollectionViewSource parentSource ) - : base( parentSource ) - { - } - - #endregion CONSTRUCTORS - - internal override DataGridCollectionViewBase EnsureDataGridCollectionViewBaseCore() - { - DataGridCollectionViewSource parentSource = this.ParentSource as DataGridCollectionViewSource; - object source = parentSource.OriginalSource; - Type itemType = parentSource.ItemType; - DataSourceProvider dataSourceProvider = source as DataSourceProvider; - - if( dataSourceProvider != m_dataSourceProvider ) - { - if( m_dataSourceProvider != null ) - DataChangedEventManager.RemoveListener( m_dataSourceProvider, this ); - - m_dataSourceProvider = dataSourceProvider; - - if( m_dataSourceProvider != null ) - { - DataChangedEventManager.AddListener( m_dataSourceProvider, this ); - m_dataSourceProvider.InitialLoad(); - } - } - - if( dataSourceProvider != null ) - source = dataSourceProvider.Data; - - IListSource listSource = source as IListSource; - - if( listSource != null ) - source = listSource.GetList(); - - if( source == null ) - return null; - - IEnumerable enumerableSource = source as IEnumerable; - Debug.Assert( enumerableSource != null ); - - DataGridCollectionViewBase currentView = this.CurrentView; - - if( ( currentView != null ) - && ( currentView.SourceCollection == enumerableSource ) - && ( currentView.DesiredItemType == itemType ) ) - { - // No changes. - return currentView; - } - - return new DataGridCollectionView( - enumerableSource, - itemType, - parentSource.AutoCreateItemProperties, - parentSource.AutoCreateDetailDescriptions, - parentSource.AutoCreateForeignKeyDescriptions ); - } - - - private DataSourceProvider m_dataSourceProvider; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewEnumerator.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewEnumerator.cs deleted file mode 100644 index 500fe8d3..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewEnumerator.cs +++ /dev/null @@ -1,162 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - internal class DataGridCollectionViewEnumerator : IEnumerator - { - public DataGridCollectionViewEnumerator( DataGridCollectionView collectionView ) - { - m_collectionView = collectionView; - m_version = m_collectionView.SortedItemVersion; - - this.Reset(); - } - - #region IEnumerator Members - - public object Current - { - get - { - if( m_beforeStart == true ) - throw new InvalidOperationException( "MoveNext must be called first." ); - - if( m_current == null ) - throw new InvalidOperationException( "The index is past the end of the list." ); - - return m_current.DataItem; - } - } - - public bool MoveNext() - { - bool retval = false; - - if( m_version != m_collectionView.SortedItemVersion ) - throw new InvalidOperationException( "The list of items has changed." ); - - if( m_beforeStart == true ) - { - m_beforeStart = false; - - if( ( m_currentGroup != null ) && ( m_currentGroup.RawItems.Count == 0 ) ) - { - // This should only occur if the first leaf group encountered after the Reset call was empty. - this.MoveToNextNonEmptyLeafGroup(); - } - } - - if( m_afterEnd == true ) - { - m_current = null; - } - else - { - if( ( m_currentGroup == null ) || ( m_currentGroup.RawItems.Count == 0 ) ) - { - m_afterEnd = true; - } - else - { - //check indexes - if( m_currentItemIndex < m_currentGroup.RawItems.Count ) - { - m_current = m_currentGroup.RawItems[ m_currentItemIndex ]; - m_currentItemIndex++; - - if( m_currentItemIndex >= m_currentGroup.RawItems.Count ) - { - m_currentItemIndex = 0; - m_afterEnd = !this.MoveToNextNonEmptyLeafGroup(); - } - - retval = true; - } - } - } - - return retval; - } - - private bool MoveToNextNonEmptyLeafGroup() - { - bool foundNonEmptyLeafGroup = false; - - while( foundNonEmptyLeafGroup == false ) - { - if( m_currentGroupIndex.Count == 0 ) - break; - - m_currentGroup = m_currentGroup.Parent; - int index = m_currentGroupIndex.Pop(); - index++; - - if( index < m_currentGroup.ItemCount ) - { - m_currentGroup = this.MoveToFirstLeafGroup( m_currentGroup, index ); - - foundNonEmptyLeafGroup = ( m_currentGroup.RawItems.Count > 0 ); - } - } - - return foundNonEmptyLeafGroup; - } - - private DataGridCollectionViewGroup MoveToFirstLeafGroup( DataGridCollectionViewGroup referenceGroup, int index ) - { - while( !referenceGroup.IsBottomLevel ) - { - referenceGroup = referenceGroup.Items[ index ] as DataGridCollectionViewGroup; - m_currentGroupIndex.Push( index ); - - if( index != 0 ) - index = 0; - } - - return referenceGroup; - } - - public void Reset() - { - m_beforeStart = true; - m_afterEnd = false; - - m_current = null; - m_currentItemIndex = 0; - m_currentGroupIndex.Clear(); - - m_currentGroup = ( m_collectionView.Count == 0 ) ? null : this.MoveToFirstLeafGroup( m_collectionView.RootGroup, 0 ); - } - - #endregion - - private DataGridCollectionViewGroup m_currentGroup; - - private RawItem m_current; - private Stack m_currentGroupIndex = new Stack( 16 ); - private int m_currentItemIndex; - private bool m_beforeStart; - private bool m_afterEnd; - private int m_version; - private DataGridCollectionView m_collectionView; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewGroup.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewGroup.cs deleted file mode 100644 index aeb74be4..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewGroup.cs +++ /dev/null @@ -1,1055 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Diagnostics; -using System.Globalization; -using System.Reflection; -using System.Reflection.Emit; -using System.Windows.Data; - -namespace Xceed.Wpf.DataGrid -{ - internal class DataGridCollectionViewGroup : CollectionViewGroup, ICustomTypeDescriptor - { - protected DataGridCollectionViewGroup( int capacity ) - : this( null, null, 0, capacity, 4 ) - { - } - - protected DataGridCollectionViewGroup( DataGridCollectionViewGroup template, DataGridCollectionViewGroup parent ) - : this( template.Name, parent, template.m_unsortedIndex, template.m_sortedRawItems.Count, template.m_subGroups.Count ) - { - m_nextSubGroupUnsortedIndex = template.m_nextSubGroupUnsortedIndex; - m_subGroupBy = template.m_subGroupBy; - m_groupByName = template.GroupByName; - } - - private DataGridCollectionViewGroup( object name, DataGridCollectionViewGroup parent, int unsortedIndex ) - : this( name, parent, unsortedIndex, 4, 4 ) - { - } - - private DataGridCollectionViewGroup( object name, DataGridCollectionViewGroup parent, int unsortedIndex, int rawCapacity, int groupCapacity ) - : base( name ) - { - m_parent = parent; - m_unsortedIndex = unsortedIndex; - m_protectedItems = ObservableCollectionHelper.GetItems( base.ProtectedItems ); - m_protectedItemsCollectionChanged = ObservableCollectionHelper.GetCollectionChanged( base.ProtectedItems ); - m_optimizedItems = new OptimizedReadOnlyObservableCollection( this ); - m_subGroups = new Dictionary( groupCapacity ); - m_sortedRawItems = new List( rawCapacity ); - } - - #region IsBottomLevel Property - - public override bool IsBottomLevel - { - get - { - // returns true if .Items contain DataItem - return ( m_subGroupBy == null ); - } - } - - #endregion - - #region Items Property - - internal new ReadOnlyObservableCollection Items - { - get - { - return m_optimizedItems; - } - } - - #endregion - - #region ProtectedItems Property - - internal new ObservableCollection ProtectedItems - { - get - { - return base.ProtectedItems; - } - } - - #endregion - - #region UnsortedIndex Property - - internal int UnsortedIndex - { - get - { - return m_unsortedIndex; - } - } - - #endregion - - #region GroupByName Property - - internal string GroupByName - { - get - { - return m_groupByName; - } - set - { - m_groupByName = value; - } - } - - private string m_groupByName; - - #endregion - - #region SubGroupBy Property - - internal GroupDescription SubGroupBy - { - get - { - return m_subGroupBy; - } - } - - #endregion - - #region Parent Property - - internal DataGridCollectionViewGroup Parent - { - get - { - return m_parent; - } - } - - #endregion - - #region GlobalRawItemCount Property - - internal int GlobalRawItemCount - { - get - { - return m_globalRawItemCount; - } - } - - #endregion - - #region RawItems Property - - internal List RawItems - { - get - { - return m_sortedRawItems; - } - } - - #endregion - - protected virtual DataGridCollectionView GetCollectionView() - { - if( m_parent != null ) - return m_parent.GetCollectionView(); - - return null; - } - - internal bool Contains( object item ) - { - var group = item as DataGridCollectionViewGroup; - if( group != null ) - { - //Must make sure the group the group is ref equals, because there can be groups with a null name at more than one level. - DataGridCollectionViewGroup foundGroup; - if( m_subGroups.TryGetValue( DataGridCollectionViewGroup.GetHashKeyFromName( group.Name ), out foundGroup ) ) - return ( foundGroup == group ); - - return false; - } - - DataGridCollectionView collectionView = this.GetCollectionView(); - if( collectionView != null ) - { - RawItem rawItem = collectionView.GetFirstRawItemFromDataItem( item ); - if( rawItem != null ) - return ( rawItem.ParentGroup == this ); - } - - return false; - } - - internal int IndexOf( object item ) - { - if( item is DataGridCollectionViewGroup ) - return this.ProtectedItems.IndexOf( item ); - - DataGridCollectionView collectionView = this.GetCollectionView(); - - if( collectionView != null ) - { - RawItem rawItem = collectionView.GetFirstRawItemFromDataItem( item ); - - if( ( rawItem != null ) && ( rawItem.ParentGroup == this ) ) - return rawItem.SortedIndex; - } - - return -1; - } - - internal int GetFirstRawItemGlobalSortedIndex() - { - var index = 0; - var group = this; - var parent = this.Parent; - var currentGroup = default( DataGridCollectionViewGroup ); - - while( parent != null ) - { - var items = parent.ProtectedItems; - var count = items.Count; - - for( int i = 0; i < count; i++ ) - { - var value = items[ i ]; - if( value == group ) - break; - - currentGroup = value as DataGridCollectionViewGroup; - index += currentGroup.GlobalRawItemCount; - } - - group = parent; - parent = parent.Parent; - } - - return index; - } - - internal void SetSubGroupBy( GroupDescription groupBy ) - { - bool oldIsBottomLevel = this.IsBottomLevel; - m_subGroupBy = groupBy; - - if( oldIsBottomLevel != this.IsBottomLevel ) - { - this.OnPropertyChanged( new PropertyChangedEventArgs( "IsBottomLevel" ) ); - } - } - - internal DataGridCollectionViewGroup GetGroup( - RawItem rawItem, - int level, - CultureInfo culture, - ObservableCollection groupByList, - List groupSortComparers ) - { - // If sortComparers is null, we are in massive group creation, no order check. - - if( this.IsBottomLevel ) - throw new InvalidOperationException( "An attempt was made to get a group for which a GroupDescription has not been provided." ); - - object groupName = m_subGroupBy.GroupNameFromItem( rawItem.DataItem, level, culture ); - DataGridCollectionViewGroup group; - - if( ( m_subGroupBy is DataGridGroupDescription ) || ( m_subGroupBy is PropertyGroupDescription ) ) - { - m_subGroups.TryGetValue( DataGridCollectionViewGroup.GetHashKeyFromName( groupName ), out group ); - } - else - { - //If dealing with an unknown GroupDescription type, use the standard method to retrieve a group, in case group retrival is handle differently. - group = null; - - foreach( var tempGroup in m_subGroups.Values ) - { - if( m_subGroupBy.NamesMatch( tempGroup.Name, groupName ) ) - { - group = tempGroup; - break; - } - } - } - - if( group == null ) - { - group = this.CreateSubGroup( groupName, level, groupByList, groupSortComparers ); - } - - return group; - } - - internal void SortItems( - IList sortDescriptionInfos, - List groupSortComparers, - int level, - List globalRawItems, - DataGridCollectionViewGroup newSortedGroup ) - { - var itemCount = this.ProtectedItemCount; - if( itemCount == 0 ) - return; - - if( this.IsBottomLevel ) - { - var indexes = new int[ itemCount + 1 ]; - - for( int i = 0; i < itemCount; i++ ) - { - indexes[ i ] = m_sortedRawItems[ i ].Index; - } - - // "Weak heap sort" sort array[0..NUM_ELEMENTS-1] to array[1..NUM_ELEMENTS] - var collectionViewSort = new DataGridCollectionViewSort( indexes, sortDescriptionInfos ); - - collectionViewSort.Sort( itemCount ); - var index = 0; - - for( int i = 1; i <= itemCount; i++ ) - { - newSortedGroup.InsertRawItem( index, globalRawItems[ indexes[ i ] ] ); - index++; - } - } - else - { - var indexes = new int[ itemCount + 1 ]; - - for( int i = 0; i < itemCount; i++ ) - { - indexes[ i ] = i; - } - - var subGroupsArray = new DataGridCollectionViewGroup[ itemCount ]; - m_subGroups.Values.CopyTo( subGroupsArray, 0 ); - - // "Weak heap sort" sort array[0..NUM_ELEMENTS-1] to array[1..NUM_ELEMENTS] - var collectionViewSort = new DataGridCollectionViewGroupSort( indexes, groupSortComparers[ level ], subGroupsArray ); - - collectionViewSort.Sort( itemCount ); - int index = 0; - level++; - - for( int i = 1; i <= itemCount; i++ ) - { - DataGridCollectionViewGroup oldGroup = subGroupsArray[ indexes[ i ] ]; - DataGridCollectionViewGroup newGroup = new DataGridCollectionViewGroup( oldGroup, newSortedGroup ); - - // Sort sub items - oldGroup.SortItems( sortDescriptionInfos, groupSortComparers, level, globalRawItems, newGroup ); - - newSortedGroup.InsertGroup( index, newGroup ); - index++; - } - } - } - - internal void SortGroups( List groupSortComparers, int level ) - { - int itemCount = this.ProtectedItemCount; - - if( itemCount == 0 ) - return; - - int[] indexes; - indexes = new int[ itemCount + 1 ]; - for( int i = 0; i < itemCount; i++ ) - { - indexes[ i ] = i; - } - - DataGridCollectionViewGroup[] subGroupsArray = new DataGridCollectionViewGroup[ itemCount ]; - m_subGroups.Values.CopyTo( subGroupsArray, 0 ); - - // "Weak heap sort" sort array[0..NUM_ELEMENTS-1] to array[1..NUM_ELEMENTS] - DataGridCollectionViewGroupSort collectionViewSort = new DataGridCollectionViewGroupSort( indexes, groupSortComparers[ level ], subGroupsArray ); - - collectionViewSort.Sort( itemCount ); - level++; - m_protectedItems.Clear(); - - for( int i = 1; i <= itemCount; i++ ) - { - DataGridCollectionViewGroup group = subGroupsArray[ indexes[ i ] ]; - - // Sort sub groups - if( !group.IsBottomLevel ) - { - group.SortGroups( groupSortComparers, level ); - } - - m_protectedItems.Add( group ); - } - - this.ProtectedItemCount = m_protectedItems.Count; - m_protectedItemsCollectionChanged.Invoke( new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Reset ) ); - } - - internal void CreateFixedGroupNames( int fixedGroupLevel, ObservableCollection groupByList, List groupSortComparers ) - { - GroupDescription groupDescription = this.SubGroupBy; - - if( groupDescription == null ) - return; - - Debug.Assert( groupByList[ fixedGroupLevel ] == this.SubGroupBy ); - - ObservableCollection groupNames = groupDescription.GroupNames; - int count = groupNames.Count; - - for( int i = 0; i < count; i++ ) - { - this.CreateSubGroup( groupNames[ i ], fixedGroupLevel, groupByList, groupSortComparers ); - } - } - - - internal RawItem GetRawItemAtGlobalSortedIndex( int index ) - { - if( this.IsBottomLevel ) - { - return m_sortedRawItems[ index ]; - } - else - { - foreach( object value in this.ProtectedItems ) - { - DataGridCollectionViewGroup subGroup = value as DataGridCollectionViewGroup; - - int subGroupCount = subGroup.GlobalRawItemCount; - - if( index < subGroupCount ) - return subGroup.GetRawItemAtGlobalSortedIndex( index ); - - index -= subGroupCount; - } - } - - throw new ArgumentOutOfRangeException( "index" ); - } - - internal int RawItemIndexOf( RawItem rawItem ) - { - Debug.Assert( m_sortedRawItems != null ); - - if( m_sortedRawItems == null ) - return -1; - - return m_sortedRawItems.IndexOf( rawItem ); - } - - internal virtual void InsertRawItem( int index, RawItem rawItem ) - { - Debug.Assert( this.IsBottomLevel ); - - m_globalRawItemCount++; - DataGridCollectionViewGroup parent = m_parent; - - while( parent != null ) - { - parent.m_globalRawItemCount++; - parent = parent.m_parent; - } - - int count = m_sortedRawItems.Count; - - for( int i = index; i < count; i++ ) - { - m_sortedRawItems[ i ].SetSortedIndex( i + 1 ); - } - - m_sortedRawItems.Insert( index, rawItem ); - rawItem.SetParentGroup( this ); - rawItem.SetSortedIndex( index ); - - this.ProtectedItemCount++; - this.ProtectedItems.Insert( index, rawItem.DataItem ); - } - - internal virtual void RemoveRawItemAt( int index ) - { - Debug.Assert( this.IsBottomLevel ); - Debug.Assert( m_sortedRawItems.Count > 0 ); - - int count = m_sortedRawItems.Count; - if( count == 0 ) - return; - - if( index != -1 ) - { - m_globalRawItemCount--; - DataGridCollectionViewGroup parent = m_parent; - - while( parent != null ) - { - parent.m_globalRawItemCount--; - parent = parent.Parent; - } - - for( int i = index + 1; i < count; i++ ) - { - m_sortedRawItems[ i ].SetSortedIndex( i - 1 ); - } - - RawItem rawItem = m_sortedRawItems[ index ]; - rawItem.SetParentGroup( null ); - rawItem.SetSortedIndex( -1 ); - m_sortedRawItems.RemoveAt( index ); - - this.ProtectedItemCount--; - this.ProtectedItems.RemoveAt( index ); - - if( ( this.ProtectedItemCount == 0 ) && ( m_parent != null ) ) - { - m_parent.RemoveGroup( this ); - } - } - } - - internal virtual void MoveRawItem( int oldIndex, int newIndex ) - { - Debug.Assert( this.IsBottomLevel ); - Debug.Assert( m_sortedRawItems != null ); - - if( m_sortedRawItems == null ) - return; - - RawItem rawItem = m_sortedRawItems[ oldIndex ]; - - m_sortedRawItems.RemoveAt( oldIndex ); - m_sortedRawItems.Insert( newIndex, rawItem ); - - int startIndex = Math.Min( oldIndex, newIndex ); - int endIndex = Math.Max( oldIndex, newIndex ); - - for( int i = startIndex; i <= endIndex; i++ ) - { - m_sortedRawItems[ i ].SetSortedIndex( i ); - } - - this.ProtectedItems.Move( oldIndex, newIndex ); - } - - internal int BinarySearchRawItem( RawItem value, IComparer comparer ) - { - if( comparer == null ) - throw new ArgumentNullException( "comparer" ); - - if( m_sortedRawItems == null ) - return -1; // ~0 - - Debug.Assert( ( m_sortedRawItems.Count == this.ProtectedItemCount ) || ( this is DataGridCollectionViewGroupRoot ) ); - - int low = 0; - int hi = ( m_sortedRawItems.Count ) - 1; - - while( low <= hi ) - { - int compareResult; - int median = ( low + ( ( hi - low ) >> 1 ) ); - - RawItem medianRawItem = m_sortedRawItems[ median ]; - - // We exclude ourself from the research because we seek for a new valid position - if( medianRawItem == value ) - { - if( low == hi ) - return low; - - median++; - medianRawItem = m_sortedRawItems[ median ]; - } - - try - { - compareResult = comparer.Compare( medianRawItem, value ); - } - catch( Exception exception ) - { - throw new InvalidOperationException( "IComparer has failed to compare the values.", exception ); - } - - if( compareResult == 0 ) - { - return median; - } - if( compareResult < 0 ) - { - low = median + 1; - } - else - { - hi = median - 1; - } - } - - return ~low; - } - - private int BinarySearchGroup( DataGridCollectionViewGroup value, IComparer comparer ) - { - if( comparer == null ) - throw new ArgumentNullException( "comparer" ); - - int low = 0; - int hi = ( this.ProtectedItemCount ) - 1; - int median; - int compareResult; - - while( low <= hi ) - { - median = ( low + ( ( hi - low ) >> 1 ) ); - - DataGridCollectionViewGroup medianGroup = this.ProtectedItems[ median ] as DataGridCollectionViewGroup; - - if( medianGroup == value ) - { - if( low == hi ) - return low; - - return median; - } - - try - { - compareResult = comparer.Compare( medianGroup, value ); - } - catch( Exception exception ) - { - throw new InvalidOperationException( "IComparer has failed to compare the values.", exception ); - } - - if( compareResult == 0 ) - { - return median; - } - if( compareResult < 0 ) - { - low = median + 1; - } - else - { - hi = median - 1; - } - } - - return ~low; - } - - private static object GetHashKeyFromName( object groupName ) - { - if( groupName == null ) - return DBNull.Value; - - return groupName; - } - - private DataGridCollectionViewGroup CreateSubGroup( object groupName, int level, ObservableCollection groupByList, - List groupSortComparers ) - { - // If sortComparers is null, we are in massive group creation, no order check. - var group = new DataGridCollectionViewGroup( groupName, this, m_nextSubGroupUnsortedIndex ); - - var dataGridGroupDescription = groupByList[ level ] as DataGridGroupDescription; - if( dataGridGroupDescription != null ) - { - group.GroupByName = dataGridGroupDescription.PropertyName; - } - - unchecked - { - m_nextSubGroupUnsortedIndex++; - } - - int index; - - if( groupSortComparers == null ) - { - Debug.Assert( this.ProtectedItemCount == this.ProtectedItems.Count ); - index = this.ProtectedItemCount; - } - else - { - index = this.BinarySearchGroup( group, groupSortComparers[ level ] ); - - if( index < 0 ) - { - index = ~index; - } - } - - level++; - - if( level < groupByList.Count ) - { - group.SetSubGroupBy( groupByList[ level ] ); - group.CreateFixedGroupNames( level, groupByList, groupSortComparers ); - } - - this.InsertGroup( index, group ); - return group; - } - - private void InsertGroup( int index, DataGridCollectionViewGroup group ) - { - Debug.Assert( !this.IsBottomLevel ); - - m_subGroups.Add( DataGridCollectionViewGroup.GetHashKeyFromName( group.Name ), group ); - this.ProtectedItemCount++; - this.ProtectedItems.Insert( index, group ); - } - - private void RemoveGroup( DataGridCollectionViewGroup group ) - { - if( group == null ) - throw new ArgumentNullException( "group" ); - - Debug.Assert( this == group.m_parent ); - - // We do not remove group forced in SubGroupBy.GroupNames - if( group.UnsortedIndex < this.SubGroupBy.GroupNames.Count ) - return; - - Debug.Assert( !this.IsBottomLevel ); - Debug.Assert( ( group.m_globalRawItemCount == 0 ) && ( group.ProtectedItemCount == 0 ) ); - - m_subGroups.Remove( DataGridCollectionViewGroup.GetHashKeyFromName( group.Name ) ); - - this.ProtectedItemCount--; - this.ProtectedItems.Remove( group ); - - if( ( m_subGroups.Count == 0 ) && ( m_parent != null ) ) - { - m_parent.RemoveGroup( this ); - } - } - - #region ICustomTypeDescriptor Members - - AttributeCollection ICustomTypeDescriptor.GetAttributes() - { - return AttributeCollection.Empty; - } - - string ICustomTypeDescriptor.GetClassName() - { - return null; - } - - string ICustomTypeDescriptor.GetComponentName() - { - return null; - } - - TypeConverter ICustomTypeDescriptor.GetConverter() - { - return null; - } - - EventDescriptor ICustomTypeDescriptor.GetDefaultEvent() - { - return null; - } - - PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty() - { - return null; - } - - object ICustomTypeDescriptor.GetEditor( Type editorBaseType ) - { - return null; - } - - EventDescriptorCollection ICustomTypeDescriptor.GetEvents( Attribute[] attributes ) - { - return EventDescriptorCollection.Empty; - } - - EventDescriptorCollection ICustomTypeDescriptor.GetEvents() - { - return EventDescriptorCollection.Empty; - } - - // This method returns the StatFunction properties as defined by the "parent" - // DataGridCollectionView as well as the other "standard" properties for this class. - // The StatFunction properties are NOT filtered by the specified attributes. - PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties( Attribute[] attributes ) - { - if( attributes == null ) - { - // We only cache the full property list. - if( m_classProperties == null ) - { - DataGridCollectionView view = this.GetCollectionView(); - - Debug.Assert( view != null, "A group should always have a parent CollectionView for the StatFunctions to work." ); - - if( view == null ) - return TypeDescriptor.GetProperties( typeof( DataGridCollectionViewGroup ) ); - - PropertyDescriptorCollection classProperties = TypeDescriptor.GetProperties( typeof( DataGridCollectionViewGroup ) ); - PropertyDescriptor[] properties = new PropertyDescriptor[ classProperties.Count ]; - classProperties.CopyTo( properties, 0 ); - - m_classProperties = new PropertyDescriptorCollection( properties ); - } - - return m_classProperties; - } - else - { - PropertyDescriptorCollection props = TypeDescriptor.GetProperties( this, attributes ); - DataGridCollectionView view = this.GetCollectionView(); - - return props; - } - } - - PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties() - { - return ( ( ICustomTypeDescriptor )this ).GetProperties( null ); - } - - object ICustomTypeDescriptor.GetPropertyOwner( PropertyDescriptor pd ) - { - return this; - } - - #endregion - - #region INotifyPropertyChanged Members - - protected sealed override event PropertyChangedEventHandler PropertyChanged - { - add - { - this.PropertyChangedImpl += value; - } - remove - { - this.PropertyChangedImpl -= value; - } - } - - protected override void OnPropertyChanged( PropertyChangedEventArgs e ) - { - var handler = this.PropertyChangedImpl; - if( handler == null ) - return; - - handler.Invoke( this, e ); - } - - private bool HasPropertyChangedListeners - { - get - { - return ( this.PropertyChangedImpl != null ); - } - } - - private event PropertyChangedEventHandler PropertyChangedImpl; - - #endregion - - private PropertyDescriptorCollection m_classProperties; - - protected int m_globalRawItemCount; - protected readonly List m_sortedRawItems; - - private readonly OptimizedReadOnlyObservableCollection m_optimizedItems; - private readonly Dictionary m_subGroups; - private readonly IList m_protectedItems; - private readonly Action m_protectedItemsCollectionChanged; - - private GroupDescription m_subGroupBy; - private readonly DataGridCollectionViewGroup m_parent; - private readonly int m_unsortedIndex; - private int m_nextSubGroupUnsortedIndex; - - #region OptimizedReadOnlyObservableCollection Private Class - - // We re-implement IList and IList to override the implementation of the - // IndexOf and Contains methods to use our optimized way. - private sealed class OptimizedReadOnlyObservableCollection : ReadOnlyObservableCollection, IList, IList - { - internal OptimizedReadOnlyObservableCollection( DataGridCollectionViewGroup dataGridCollectionViewGroup ) - : base( dataGridCollectionViewGroup.ProtectedItems ) - { - if( dataGridCollectionViewGroup == null ) - throw new ArgumentNullException( "dataGridCollectionViewGroup" ); - - m_dataGridCollectionViewGroup = dataGridCollectionViewGroup; - } - - public new int IndexOf( object item ) - { - // The DataGridCollectionViewGroup has been optimized to use the information - // stored on the RawItem associated with the data item instead of searching the item in the list. - return m_dataGridCollectionViewGroup.IndexOf( item ); - } - - public new bool Contains( object item ) - { - // The DataGridCollectionViewGroup has been optimized to use the information - // stored on the RawItem associated with the data item instead of searching the item in the list. - return m_dataGridCollectionViewGroup.Contains( item ); - } - - private readonly DataGridCollectionViewGroup m_dataGridCollectionViewGroup; - } - - #endregion - - #region ObservableCollectionHelper Private Class - - private static class ObservableCollectionHelper - { - private const string AssemblyName = "Xceed.Wpf.DataGrid.CollectionViewGroupExtractor"; - private const string GetItemsMethodName = "GetItems"; - private const string GetCollectionChangedMethodName = "GetCollectionChanged"; - - private static readonly Func, IList> s_getItems; - private static readonly Func, Action> s_collectionChanged; - - static ObservableCollectionHelper() - { - var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly( new AssemblyName( ObservableCollectionHelper.AssemblyName ), AssemblyBuilderAccess.RunAndCollect ); - var moduleBuilder = assemblyBuilder.DefineDynamicModule( ObservableCollectionHelper.AssemblyName ); - - var typeBuilder = moduleBuilder.DefineType( "ObservableCollectionExtractor", TypeAttributes.Class | TypeAttributes.NotPublic | TypeAttributes.AutoLayout, typeof( ObservableCollection ) ); - - ObservableCollectionHelper.DefineGetItemsMethod( typeBuilder ); - ObservableCollectionHelper.DefineGetCollectionChangedMethod( typeBuilder ); - - var targetType = typeBuilder.CreateType(); - - s_getItems = ( Func, IList> )Delegate.CreateDelegate( typeof( Func, IList> ), targetType.GetMethod( ObservableCollectionHelper.GetItemsMethodName, BindingFlags.Public | BindingFlags.Static ) ); - s_collectionChanged = ( Func, Action> )Delegate.CreateDelegate( typeof( Func, Action> ), targetType.GetMethod( ObservableCollectionHelper.GetCollectionChangedMethodName, BindingFlags.Public | BindingFlags.Static ) ); - } - - internal static IList GetItems( ObservableCollection source ) - { - if( source == null ) - throw new ArgumentNullException( "source" ); - - var storage = ( s_getItems != null ) ? s_getItems.Invoke( source ) : null; - if( storage == null ) - throw new InvalidOperationException( "Unable to retrieve the ObservableCollection<>'s items storage." ); - - return storage; - } - - internal static Action GetCollectionChanged( ObservableCollection source ) - { - if( source == null ) - throw new ArgumentNullException( "source" ); - - var collectionChanged = ( s_collectionChanged != null ) ? s_collectionChanged.Invoke( source ) : null; - if( collectionChanged == null ) - throw new InvalidOperationException( "Unable to retrieve the ObservableCollection<>'s collection change method." ); - - return collectionChanged; - } - - private static void DefineGetItemsMethod( TypeBuilder typeBuilder ) - { - var propertyInfo = typeof( ObservableCollection ).GetProperty( "Items", BindingFlags.Instance | BindingFlags.NonPublic, null, typeof( IList ), new Type[ 0 ], null ); - if( ( propertyInfo == null ) || !propertyInfo.CanRead ) - throw new InvalidOperationException( "Unable to retrieve the ObservableCollection<>.Items property." ); - - var methodInfo = propertyInfo.GetGetMethod( true ); - if( ( methodInfo == null ) || !ObservableCollectionHelper.HasCallingConvention( methodInfo.CallingConvention, CallingConventions.HasThis ) ) - throw new InvalidOperationException( "Unable to retrieve the ObservableCollection<>.Items property." ); - - var methodBuilder = typeBuilder.DefineMethod( - ObservableCollectionHelper.GetItemsMethodName, - MethodAttributes.Public | MethodAttributes.Static, - CallingConventions.Standard, - typeof( IList ), - new Type[] { typeof( ObservableCollection ) } ); - - var body = methodBuilder.GetILGenerator(); - // Load the reference to the ObservableCollection and put it on top of the stack. - body.Emit( OpCodes.Ldarg_0 ); - // Invoke the property getter of the reference. This operation pops the reference - // from the stack and pushes the result of the property getter. - body.Emit( OpCodes.Callvirt, methodInfo ); - // Since the result of the propery getter will be retrieved by the method's caller, - // we may leave it on the stack and simply return. - body.Emit( OpCodes.Ret ); - } - - private static void DefineGetCollectionChangedMethod( TypeBuilder typeBuilder ) - { - var methodInfo = typeof( ObservableCollection ).GetMethod( "OnCollectionChanged", BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[] { typeof( NotifyCollectionChangedEventArgs ) }, null ); - if( ( methodInfo == null ) || methodInfo.IsPrivate || !ObservableCollectionHelper.HasCallingConvention( methodInfo.CallingConvention, CallingConventions.HasThis ) ) - throw new InvalidOperationException( "Unable to retrieve the ObservableCollection<>.OnCollectionChanged method." ); - - var constructorInfo = typeof( Action ).GetConstructor( new Type[] { typeof( object ), typeof( IntPtr ) } ); - if( ( constructorInfo == null ) || constructorInfo.IsPrivate || !ObservableCollectionHelper.HasCallingConvention( constructorInfo.CallingConvention, CallingConventions.HasThis ) ) - throw new InvalidOperationException( "Unable to retrieve the Action<>'s constructor." ); - - var methodBuilder = typeBuilder.DefineMethod( - ObservableCollectionHelper.GetCollectionChangedMethodName, - MethodAttributes.Public | MethodAttributes.Static, - CallingConventions.Standard, - typeof( Action ), - new Type[] { typeof( ObservableCollection ) } ); - - var body = methodBuilder.GetILGenerator(); - // Load the reference to the ObservableCollection and put it on top of the stack. - body.Emit( OpCodes.Ldarg_0 ); - // The last loaded reference will be consume in the call to "new Action<>". - // We must duplicate the value since it will be consume by the call that retrieve the - // target method's address. - body.Emit( OpCodes.Dup ); - // This operation pops the top ObservableCollection's reference from the stack - // and pushes the ObservableCollection<>.OnCollectionChanged method's address. - body.Emit( OpCodes.Ldvirtftn, methodInfo ); - // Create an Action<> delegate from the first ObservableCollection's reference we - // have put on the stack and the target method's address. - body.Emit( OpCodes.Newobj, constructorInfo ); - // The resulting delegate should be on top of the stack. We simply leave it there - // so it will be retrieved by the method's caller. - body.Emit( OpCodes.Ret ); - } - - private static bool HasCallingConvention( CallingConventions source, CallingConventions value ) - { - return ( ( source & value ) == value ); - } - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewGroupRoot.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewGroupRoot.cs deleted file mode 100644 index 55dde31d..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewGroupRoot.cs +++ /dev/null @@ -1,134 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Diagnostics; - -namespace Xceed.Wpf.DataGrid -{ - internal class DataGridCollectionViewGroupRoot : DataGridCollectionViewGroup - { - internal DataGridCollectionViewGroupRoot( DataGridCollectionView parentCollectionView ) - : base( 128 ) - { - m_parentCollectionView = parentCollectionView; - } - - internal DataGridCollectionViewGroupRoot( DataGridCollectionViewGroupRoot template ) - : base( template, null ) - { - m_parentCollectionView = template.m_parentCollectionView; - } - - protected override DataGridCollectionView GetCollectionView() - { - return m_parentCollectionView; - } - - internal void SortRootRawItems( IList sortDescriptionInfos, List globalRawItems ) - { - Debug.Assert( this.IsBottomLevel ); - - var itemCount = m_sortedRawItems.Count; - if( itemCount == 0 ) - return; - - var indexes = new int[ itemCount + 1 ]; - - for( int i = 0; i < itemCount; i++ ) - { - indexes[ i ] = m_sortedRawItems[ i ].Index; - } - - // "Weak heap sort" sort array[0..NUM_ELEMENTS-1] to array[1..NUM_ELEMENTS] - var collectionViewSort = new DataGridCollectionViewSort( indexes, sortDescriptionInfos ); - - collectionViewSort.Sort( itemCount ); - var index = 0; - - for( int i = 1; i <= itemCount; i++ ) - { - var newRawItem = globalRawItems[ indexes[ i ] ]; - newRawItem.SetSortedIndex( index ); - m_sortedRawItems[ index ] = newRawItem; - index++; - } - } - - internal override void InsertRawItem( int index, RawItem rawItem ) - { - Debug.Assert( this.IsBottomLevel ); - - m_globalRawItemCount++; - int count = m_sortedRawItems.Count; - - for( int i = index; i < count; i++ ) - { - m_sortedRawItems[ i ].SetSortedIndex( i + 1 ); - } - - m_sortedRawItems.Insert( index, rawItem ); - rawItem.SetParentGroup( this ); - rawItem.SetSortedIndex( index ); - } - - internal override void RemoveRawItemAt( int index ) - { - Debug.Assert( this.IsBottomLevel ); - Debug.Assert( m_sortedRawItems.Count > 0 ); - - int count = m_sortedRawItems.Count; - if( count == 0 ) - return; - - if( index != -1 ) - { - m_globalRawItemCount--; - - for( int i = index + 1; i < count; i++ ) - { - m_sortedRawItems[ i ].SetSortedIndex( i - 1 ); - } - - RawItem rawItem = m_sortedRawItems[ index ]; - rawItem.SetParentGroup( null ); - rawItem.SetSortedIndex( -1 ); - m_sortedRawItems.RemoveAt( index ); - } - } - - internal override void MoveRawItem( int oldIndex, int newIndex ) - { - Debug.Assert( this.IsBottomLevel ); - - RawItem rawItem = m_sortedRawItems[ oldIndex ]; - - m_sortedRawItems.RemoveAt( oldIndex ); - m_sortedRawItems.Insert( newIndex, rawItem ); - - int startIndex = Math.Min( oldIndex, newIndex ); - int endIndex = Math.Max( oldIndex, newIndex ); - - for( int i = startIndex; i <= endIndex; i++ ) - { - m_sortedRawItems[ i ].SetSortedIndex( i ); - } - } - - private DataGridCollectionView m_parentCollectionView; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewGroupSort.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewGroupSort.cs deleted file mode 100644 index 40627242..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewGroupSort.cs +++ /dev/null @@ -1,51 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; -using System.Collections.Generic; -using System.Text; - -using Xceed.Utils.Collections; -using System.Collections.ObjectModel; -using Xceed.Utils.Data; - -namespace Xceed.Wpf.DataGrid -{ - internal class DataGridCollectionViewGroupSort : IndexWeakHeapSort - { - public DataGridCollectionViewGroupSort( int[] dataIndexArray, GroupSortComparer groupSortedComparer, DataGridCollectionViewGroup[] protectedItems ) - : base( dataIndexArray ) - { - if( groupSortedComparer == null ) - throw new ArgumentNullException( "groupSortedComparer" ); - - m_groupSortedComparer = groupSortedComparer; - m_groups = protectedItems; - } - - public override int Compare( int xDataIndex, int yDataIndex ) - { - DataGridCollectionViewGroup xGroup = m_groups[ xDataIndex ]; - DataGridCollectionViewGroup yGroup = m_groups[ yDataIndex ]; - - return m_groupSortedComparer.Compare( xGroup, yGroup ); - } - - private GroupSortComparer m_groupSortedComparer; - private DataGridCollectionViewGroup[] m_groups; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewSort.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewSort.cs deleted file mode 100644 index ba3e1704..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewSort.cs +++ /dev/null @@ -1,63 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Collections.Generic; -using System.ComponentModel; -using Xceed.Utils.Collections; - -namespace Xceed.Wpf.DataGrid -{ - internal class DataGridCollectionViewSort : IndexWeakHeapSort - { - public DataGridCollectionViewSort( int[] dataIndexArray, IList sortDescriptionInfos ) - : base( dataIndexArray ) - { - m_sortDescriptionInfos = sortDescriptionInfos; - } - - public override int Compare( int xDataIndex, int yDataIndex ) - { - var lastSortDirection = ListSortDirection.Ascending; - - if( m_sortDescriptionInfos != null ) - { - foreach( var sortDescriptionInfo in m_sortDescriptionInfos ) - { - lastSortDirection = sortDescriptionInfo.SortDirection; - - if( sortDescriptionInfo.Property == null ) - continue; - - var sortComparer = sortDescriptionInfo.SortComparer; - var dataStore = sortDescriptionInfo.DataStore; - var compare = ( sortComparer != null ) - ? sortComparer.Compare( dataStore.GetData( xDataIndex ), dataStore.GetData( yDataIndex ) ) - : dataStore.Compare( xDataIndex, yDataIndex ); - - if( compare != 0 ) - return ( lastSortDirection == ListSortDirection.Descending ) ? -compare : compare; - } - } - - if( lastSortDirection == ListSortDirection.Descending ) - return yDataIndex - xDataIndex; - - return xDataIndex - yDataIndex; - } - - private readonly IList m_sortDescriptionInfos; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewSource.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewSource.cs deleted file mode 100644 index 0c88a205..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewSource.cs +++ /dev/null @@ -1,111 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.ObjectModel; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Windows; -using System.Windows.Data; - -namespace Xceed.Wpf.DataGrid -{ - public sealed class DataGridCollectionViewSource : DataGridCollectionViewSourceBase - { - #region CONSTRUCTORS - - static DataGridCollectionViewSource() - { - CollectionViewSource.CollectionViewTypeProperty.OverrideMetadata( - typeof( DataGridCollectionViewSource ), - new FrameworkPropertyMetadata( typeof( DataGridCollectionView ) ) ); - } - - public DataGridCollectionViewSource() - : base() - { - } - - #endregion CONSTRUCTORS - - #region CollectionViewType Property - - protected override void OnCollectionViewTypeChanged( - Type oldCollectionViewType, - Type newCollectionViewType ) - { - if( newCollectionViewType != typeof( DataGridCollectionView ) ) - throw new InvalidOperationException( "An attempt was made to use a view other than DataGridCollectionView." ); - - base.OnCollectionViewTypeChanged( oldCollectionViewType, newCollectionViewType ); - } - - #endregion CollectionViewType Property - - #region UpdateChangedPropertyStatsOnly Property - - internal bool UpdateChangedPropertyStatsOnly - { - get; - set; - } - - #endregion - - #region SourceItems Property - - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - [Obsolete( "The SourceItems property is obsolete and should no longer be used. Unbound data should be wrapped in a collection and assigned to the Source property instead.", true )] - public ObservableCollection SourceItems - { - get - { - throw new NotSupportedException( "The SourceItems property is obsolete and should no longer be used. Unbound data should be wrapped in a collection and assigned to the Source property instead." ); - } - } - - #endregion SourceItems Property - - #region INTERNAL METHODS - - internal override DataGridCollectionViewBaseDataProvider CreateDataProvider() - { - return new DataGridCollectionViewDataProvider( this ); - } - - internal override void ApplyExtraPropertiesToView( DataGridCollectionViewBase currentView ) - { - base.ApplyExtraPropertiesToView( currentView ); - } - - #endregion INTERNAL METHODS - - #region PRIVATE METHODS - - private static void OnDataGridCollectionViewSourceDependencyPropertyChanged( DependencyObject o, DependencyPropertyChangedEventArgs e ) - { - DataGridCollectionViewSource source = o as DataGridCollectionViewSource; - - if( source == null ) - return; - - source.AdviseForwardedPropertyChanged(); - } - - #endregion PRIVATE METHODS - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewSourceBase.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewSourceBase.cs deleted file mode 100644 index 3e74c516..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCollectionViewSourceBase.cs +++ /dev/null @@ -1,550 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.ObjectModel; -using System.Collections.Specialized; -using System.Globalization; -using System.Windows; -using System.Windows.Data; - -namespace Xceed.Wpf.DataGrid -{ - public abstract class DataGridCollectionViewSourceBase : CollectionViewSource - { - static DataGridCollectionViewSourceBase() - { - CollectionViewSource.SourceProperty.OverrideMetadata( - typeof( DataGridCollectionViewSourceBase ), - new FrameworkPropertyMetadata( - null, - null, - new CoerceValueCallback( DataGridCollectionViewSourceBase.OnSourceCoerceValue ) ) ); - } - - public DataGridCollectionViewSourceBase() - { - - m_itemProperties = new ObservableCollection(); - m_itemProperties.CollectionChanged += new NotifyCollectionChangedEventHandler( this.ForwardedCollection_CollectionChanged ); - m_dataGridDetailDescriptions = new DataGridDetailDescriptionCollection(); - m_dataGridDetailDescriptions.CollectionChanged += new NotifyCollectionChangedEventHandler( this.ForwardedCollection_CollectionChanged ); - - // We force a culture because it is the only way to be - // notified when the Culture changes in order to launch our own - // ApplyExtraPropertiesToView (because the implentation of ApplyPropertiesToView is not virtual!) - // - // See CollectionViewSource.ApplyPropertiesToView in reflector for a better understanding. - this.Culture = CultureInfo.InvariantCulture; - } - - #region ItemProperties Property - - public ObservableCollection ItemProperties - { - get - { - return m_itemProperties; - } - } - - private ObservableCollection m_itemProperties; - - #endregion - - #region DetailDescriptions Property - - internal ObservableCollection DetailDescriptions - { - get - { - return m_dataGridDetailDescriptions; - } - } - - private ObservableCollection m_dataGridDetailDescriptions; - - #endregion - - #region ItemType Property - - public static readonly DependencyProperty ItemTypeProperty = DependencyProperty.Register( - "ItemType", typeof( Type ), typeof( DataGridCollectionViewSourceBase ), - new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.NotDataBindable ) ); - - public Type ItemType - { - get - { - return this.GetValue( ItemTypeProperty ) as Type; - } - set - { - this.SetValue( ItemTypeProperty, value ); - - if( m_dataSourceProvider != null ) - m_dataSourceProvider.DelayRefresh( this.Dispatcher, System.Windows.Threading.DispatcherPriority.DataBind ); - } - } - - #endregion - - #region CollectionViewType Property - - protected override void OnCollectionViewTypeChanged( - Type oldCollectionViewType, - Type newCollectionViewType ) - { - if( !typeof( DataGridCollectionViewBase ).IsAssignableFrom( newCollectionViewType ) ) - throw new InvalidOperationException( "An attempt was made to use a view other than DataGridCollectionViewBase." ); - - base.OnCollectionViewTypeChanged( oldCollectionViewType, newCollectionViewType ); - } - - #endregion - - #region AutoCreateItemProperties Property - - public static readonly DependencyProperty AutoCreateItemPropertiesProperty = DependencyProperty.Register( - "AutoCreateItemProperties", typeof( bool ), typeof( DataGridCollectionViewSourceBase ), - new FrameworkPropertyMetadata( true, - new PropertyChangedCallback( DataGridCollectionViewSourceBase.OnDataGridCollectionViewSourceChanged ) ) ); - - public bool AutoCreateItemProperties - { - get - { - return ( bool )this.GetValue( AutoCreateItemPropertiesProperty ); - } - set - { - this.SetValue( AutoCreateItemPropertiesProperty, value ); - } - } - - #endregion - - #region AutoCreateDetailDescriptions Property - - internal static readonly DependencyProperty AutoCreateDetailDescriptionsProperty = DependencyProperty.Register( - "AutoCreateDetailDescriptions", typeof( bool ), typeof( DataGridCollectionViewSourceBase ), - new FrameworkPropertyMetadata( false, - new PropertyChangedCallback( DataGridCollectionViewSourceBase.OnDataGridCollectionViewSourceChanged ) ) ); - - internal bool AutoCreateDetailDescriptions - { - get - { - return ( bool )this.GetValue( AutoCreateDetailDescriptionsProperty ); - } - set - { - this.SetValue( AutoCreateDetailDescriptionsProperty, value ); - } - } - - #endregion - - #region DistinctValuesConstraints Property - - public static readonly DependencyProperty DistinctValuesConstraintProperty = DependencyProperty.Register( - "DistinctValuesConstraint", typeof( DistinctValuesConstraint ), typeof( DataGridCollectionViewSourceBase ), - new UIPropertyMetadata( DistinctValuesConstraint.All, - new PropertyChangedCallback( DataGridCollectionViewSourceBase.OnDataGridCollectionViewSourceBaseDependencyPropertyChanged ) ) ); - - public DistinctValuesConstraint DistinctValuesConstraint - { - get - { - return ( DistinctValuesConstraint )this.GetValue( DistinctValuesConstraintProperty ); - } - set - { - this.SetValue( DistinctValuesConstraintProperty, value ); - } - } - - #endregion - - #region DistinctValuesUpdateMode Property - - public static readonly DependencyProperty DistinctValuesUpdateModeProperty = DependencyProperty.Register( - "DistinctValuesUpdateMode", typeof( DistinctValuesUpdateMode ), typeof( DataGridCollectionViewSourceBase ), - new UIPropertyMetadata( DistinctValuesUpdateMode.Manual, - new PropertyChangedCallback( DataGridCollectionViewSourceBase.OnDataGridCollectionViewSourceBaseDependencyPropertyChanged ) ) ); - - public DistinctValuesUpdateMode DistinctValuesUpdateMode - { - get - { - return ( DistinctValuesUpdateMode )this.GetValue( DistinctValuesUpdateModeProperty ); - } - set - { - this.SetValue( DistinctValuesUpdateModeProperty, value ); - } - } - - #endregion - - #region DefaultCalculateDistinctValues Property - - public static readonly DependencyProperty DefaultCalculateDistinctValuesProperty = DependencyProperty.Register( - "DefaultCalculateDistinctValues", typeof( bool ), typeof( DataGridCollectionViewSourceBase ), - new UIPropertyMetadata( true, - new PropertyChangedCallback( DataGridCollectionViewSourceBase.OnDataGridCollectionViewSourceBaseDependencyPropertyChanged ) ) ); - - public bool DefaultCalculateDistinctValues - { - get - { - return ( bool )this.GetValue( DefaultCalculateDistinctValuesProperty ); - } - set - { - this.SetValue( DefaultCalculateDistinctValuesProperty, value ); - } - } - - #endregion - - #region Culture Property - - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly" )] - public new CultureInfo Culture - { - get - { - return base.Culture; - } - set - { - // We force a culture because it is the only way to be - // notified when the Culture changes in order to launch our own - // ApplyExtraPropertiesToView (because the implentation of ApplyPropertiesToView is not virtual!) - // - // See CollectionViewSource.ApplyPropertiesToView in reflector for a better understanding. - if( value == null ) - throw new ArgumentNullException( "Culture" ); - - base.Culture = value; - } - } - - #endregion - - #region DistinctValuesRefreshNeeded Event - - public event EventHandler DistinctValuesRefreshNeeded; - - internal void RaiseDistinctValuesRefreshNeeded() - { - //Inform the user DistinctValues need to be refreshed. - if( this.DistinctValuesRefreshNeeded != null ) - { - this.DistinctValuesRefreshNeeded( this, EventArgs.Empty ); - } - } - - #endregion - - #region Source property - - public new object Source - { - get - { - return m_originalSource; - } - set - { - base.Source = value; - } - } - - private static object OnSourceCoerceValue( DependencyObject d, object newValue ) - { - if( newValue is DataGridCollectionViewBaseDataProvider ) - return newValue; - - DataGridCollectionViewSourceBase collectionViewSourceBase = ( DataGridCollectionViewSourceBase )d; - collectionViewSourceBase.m_originalSource = newValue; - - if( collectionViewSourceBase.m_dataSourceProvider == null ) - { - collectionViewSourceBase.m_dataSourceProvider = collectionViewSourceBase.CreateDataProvider(); - } - else - { - collectionViewSourceBase.m_dataSourceProvider.DelayRefresh( collectionViewSourceBase.Dispatcher, System.Windows.Threading.DispatcherPriority.DataBind ); - } - - return collectionViewSourceBase.m_dataSourceProvider; - } - - internal abstract DataGridCollectionViewBaseDataProvider CreateDataProvider(); - - #endregion - - #region OriginalSource Property - - internal object OriginalSource - { - get - { - return m_originalSource; - } - } - - #endregion - - #region AutoCreateForeignKeyDescriptions Property - - public static readonly DependencyProperty AutoCreateForeignKeyDescriptionsProperty = DependencyProperty.Register( - "AutoCreateForeignKeyDescriptions", - typeof( bool ), - typeof( DataGridCollectionViewSourceBase ), - new FrameworkPropertyMetadata( false, - new PropertyChangedCallback( DataGridCollectionViewSourceBase.OnDataGridCollectionViewSourceChanged ) ) ); - - public bool AutoCreateForeignKeyDescriptions - { - get - { - return ( bool )this.GetValue( DataGridCollectionViewSourceBase.AutoCreateForeignKeyDescriptionsProperty ); - } - set - { - this.SetValue( DataGridCollectionViewSourceBase.AutoCreateForeignKeyDescriptionsProperty, value ); - } - } - - #endregion - - #region DataSourceProvider Internal Property - - internal DataGridCollectionViewBaseDataProvider DataSourceProvider - { - get - { - return m_dataSourceProvider; - } - } - - #endregion - - #region EVENTS - - public event EventHandler InitializingNewItem; - - internal void OnInitializingNewItem( DataGridItemEventArgs e ) - { - if( this.InitializingNewItem != null ) - this.InitializingNewItem( this, e ); - } - - public event EventHandler CreatingNewItem; - - internal void OnCreatingNewItem( DataGridCreatingNewItemEventArgs e ) - { - if( this.CreatingNewItem != null ) - this.CreatingNewItem( this, e ); - } - - public event EventHandler CommittingNewItem; - - internal void OnCommittingNewItem( DataGridCommittingNewItemEventArgs e ) - { - if( this.CommittingNewItem != null ) - this.CommittingNewItem( this, e ); - } - - public event EventHandler CancelingNewItem; - - internal void OnCancelingNewItem( DataGridItemHandledEventArgs e ) - { - if( this.CancelingNewItem != null ) - this.CancelingNewItem( this, e ); - } - - public event EventHandler NewItemCreated; - - internal void OnNewItemCreated( DataGridItemEventArgs e ) - { - if( this.NewItemCreated != null ) - this.NewItemCreated( this, e ); - } - - public event EventHandler NewItemCommitted; - - internal void OnNewItemCommitted( DataGridItemEventArgs e ) - { - if( this.NewItemCommitted != null ) - this.NewItemCommitted( this, e ); - } - - public event EventHandler NewItemCanceled; - - internal void OnNewItemCanceled( DataGridItemEventArgs e ) - { - if( this.NewItemCanceled != null ) - this.NewItemCanceled( this, e ); - } - - public event EventHandler BeginningEdit; - - internal void OnBeginningEdit( DataGridItemCancelEventArgs e ) - { - if( this.BeginningEdit != null ) - this.BeginningEdit( this, e ); - } - - public event EventHandler EditBegun; - - internal void OnEditBegun( DataGridItemEventArgs e ) - { - if( this.EditBegun != null ) - this.EditBegun( this, e ); - } - - public event EventHandler CancelingEdit; - - internal void OnCancelingEdit( DataGridItemHandledEventArgs e ) - { - if( this.CancelingEdit != null ) - this.CancelingEdit( this, e ); - } - - public event EventHandler EditCanceled; - - internal void OnEditCanceled( DataGridItemEventArgs e ) - { - if( this.EditCanceled != null ) - { - this.EditCanceled( this, e ); - } - } - - public event EventHandler CommittingEdit; - - internal void OnCommittingEdit( DataGridItemCancelEventArgs e ) - { - if( this.CommittingEdit != null ) - this.CommittingEdit( this, e ); - } - - public event EventHandler EditCommitted; - - internal void OnEditCommitted( DataGridItemEventArgs e ) - { - if( this.EditCommitted != null ) - this.EditCommitted( this, e ); - } - - public event EventHandler RemovingItem; - - internal void OnRemovingItem( DataGridRemovingItemEventArgs e ) - { - if( this.RemovingItem != null ) - this.RemovingItem( this, e ); - } - - public event EventHandler ItemRemoved; - - internal void OnItemRemoved( DataGridItemRemovedEventArgs e ) - { - if( this.ItemRemoved != null ) - this.ItemRemoved( this, e ); - } - - #endregion - - internal virtual void ApplyExtraPropertiesToView( DataGridCollectionViewBase currentView ) - { - var currentViewItemProperties = currentView.ItemProperties; - - foreach( var itemProperty in m_itemProperties ) - { - currentViewItemProperties[ itemProperty.Name ] = itemProperty; - } - - var defaultCalculateDistinctValues = this.DefaultCalculateDistinctValues; - - foreach( var itemProperty in currentViewItemProperties ) - { - // Set default value for CalculateDistinctValues if not explicitly set - if( !itemProperty.IsCalculateDistinctValuesInitialized ) - { - itemProperty.CalculateDistinctValues = defaultCalculateDistinctValues; - } - } - - var autoCreateForeignKeyDescriptions = this.AutoCreateForeignKeyDescriptions; - - for( int i = 0; i < m_dataGridDetailDescriptions.Count; i++ ) - { - DataGridDetailDescription detailDescription = m_dataGridDetailDescriptions[ i ]; - - // We assume we want to auto-create ForeignKeyDescriptions for DetailDescriptions - // if this.AutoCreateForeignKeyDescriptions is true and it was auto-created - if( detailDescription.IsAutoCreated ) - { - detailDescription.AutoCreateForeignKeyDescriptions = autoCreateForeignKeyDescriptions; - } - } - } - - internal static void OnDataGridCollectionViewSourceBaseDependencyPropertyChanged( DependencyObject o, DependencyPropertyChangedEventArgs e ) - { - DataGridCollectionViewSourceBase source = o as DataGridCollectionViewSourceBase; - - if( source == null ) - return; - - source.AdviseForwardedPropertyChanged(); - } - - internal static void OnDataGridCollectionViewSourceChanged( DependencyObject o, DependencyPropertyChangedEventArgs e ) - { - DataGridCollectionViewSourceBase source = o as DataGridCollectionViewSourceBase; - - if( source == null ) - return; - - if( source.m_dataSourceProvider != null ) - source.m_dataSourceProvider.DelayRefresh( source.Dispatcher, System.Windows.Threading.DispatcherPriority.DataBind ); - } - - internal void ForwardedCollection_CollectionChanged( object sender, NotifyCollectionChangedEventArgs e ) - { - this.AdviseForwardedPropertyChanged(); - } - - internal void AdviseForwardedPropertyChanged() - { - // This is the only way to react like we are increasing the version number - // and ending with calling the base.ApplyPropertiesToView - base.Culture = base.Culture; - } - - #region Private Fields - - private DataGridCollectionViewBaseDataProvider m_dataSourceProvider; - private object m_originalSource; - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCommittingNewItemEvent.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCommittingNewItemEvent.cs deleted file mode 100644 index a61cda36..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCommittingNewItemEvent.cs +++ /dev/null @@ -1,57 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - public class DataGridCommittingNewItemEventArgs : DataGridItemCancelEventArgs - { - public DataGridCommittingNewItemEventArgs( DataGridCollectionViewBase collectionView, object item, bool cancel ) - : base( collectionView, item, cancel ) - { - m_index = -1; - m_newCount = -1; - } - - #region Index Property - - public int Index - { - get { return m_index; } - set { m_index = value; } - } - - private int m_index; - - #endregion Index Property - - #region NewCount - - public int NewCount - { - get { return m_newCount; } - set { m_newCount = value; } - } - - private int m_newCount; - - #endregion NewCount - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCreatingNewItemEvent.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCreatingNewItemEvent.cs deleted file mode 100644 index 0ef957f3..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridCreatingNewItemEvent.cs +++ /dev/null @@ -1,84 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.ComponentModel; - -namespace Xceed.Wpf.DataGrid -{ - public class DataGridCreatingNewItemEventArgs : CancelEventArgs - { - public DataGridCreatingNewItemEventArgs( - DataGridCollectionViewBase collectionView, - object newItem, - bool cancel ) - : base( cancel ) - { - m_collectionView = collectionView; - m_newItem = newItem; - } - - #region CollectionView Property - - public DataGridCollectionViewBase CollectionView - { - get { return m_collectionView; } - } - - private DataGridCollectionViewBase m_collectionView; - - #endregion CollectionView Property - - #region NewItem Property - - public object NewItem - { - get - { - return m_newItem; - } - set - { - m_newItem = value; - } - } - - private object m_newItem; - - #endregion NewItem Property - - #region Handled Property - - public bool Handled - { - get - { - return m_handled; - } - set - { - m_handled = value; - } - } - - private bool m_handled; - - #endregion Handled Property - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridDetailDescription.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridDetailDescription.cs deleted file mode 100644 index 7595a6eb..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridDetailDescription.cs +++ /dev/null @@ -1,507 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Diagnostics; -using System.Linq; -using System.Windows; -using Xceed.Utils.Collections; - -namespace Xceed.Wpf.DataGrid -{ - internal abstract class DataGridDetailDescription : DependencyObject, IWeakEventListener - { - protected DataGridDetailDescription() - { - m_itemProperties = new DataGridItemPropertyCollection(); - m_detailDescriptions = new DataGridDetailDescriptionCollection(); - m_defaultPropertyDescriptions = new PropertyDescriptionRouteDictionary(); - - m_groupDescriptions = new GroupDescriptionCollection(); - m_sortDescriptions = new DataGridSortDescriptionCollection(); - - this.AutoCreateDetailDescriptions = true; - this.AutoCreateItemProperties = true; - this.DefaultCalculateDistinctValues = true; - - CollectionChangedEventManager.AddListener( m_itemProperties, this ); - InitializeItemPropertyEventManager.AddListener( m_itemProperties, this ); - CollectionChangedEventManager.AddListener( m_detailDescriptions, this ); - } - - #region RelationName Public Property - - public string RelationName - { - get - { - return m_relationName; - } - set - { - if( this.InternalIsSealed == true ) - throw new InvalidOperationException( "An attempt was made to change the RelationName property after the DataGridDetailDescription has been sealed." ); - - m_relationName = value; - } - } - - private string m_relationName; - - #endregion - - #region Title Public Property - - public object Title - { - get - { - return m_title; - } - set - { - m_title = value; - } - } - - private object m_title; - - #endregion - - #region TitleTemplate Public Property - - public DataTemplate TitleTemplate - { - get - { - return m_titleTemplate; - } - set - { - m_titleTemplate = value; - } - } - - private DataTemplate m_titleTemplate; - - #endregion - - #region AutoCreateItemProperties Public Property - - public bool AutoCreateItemProperties - { - get - { - return m_flags[ ( int )DataGridDetailDescriptionFlags.AutoCreateItemProperties ]; - } - set - { - m_flags[ ( int )DataGridDetailDescriptionFlags.AutoCreateItemProperties ] = value; - } - } - - #endregion - - #region AutoCreateDetailDescriptions Public Property - - public bool AutoCreateDetailDescriptions - { - get - { - return m_flags[ ( int )DataGridDetailDescriptionFlags.AutoCreateDetailDescriptions ]; - } - set - { - m_flags[ ( int )DataGridDetailDescriptionFlags.AutoCreateDetailDescriptions ] = value; - } - } - - #endregion - - #region AutoCreateForeignKeyDescriptions Public Property - - public bool AutoCreateForeignKeyDescriptions - { - get - { - return m_flags[ ( int )DataGridDetailDescriptionFlags.AutoCreateForeignKeyDescriptions ]; - } - set - { - m_flags[ ( int )DataGridDetailDescriptionFlags.AutoCreateForeignKeyDescriptions ] = value; - } - } - - #endregion - - #region DistinctValuesConstraint Public Property - - public DistinctValuesConstraint DistinctValuesConstraint - { - get - { - return m_distinctValuesConstraint; - } - set - { - m_distinctValuesConstraint = value; - } - } - - private DistinctValuesConstraint m_distinctValuesConstraint = DistinctValuesConstraint.All; - - #endregion - - #region ItemProperties Public Property - - public DataGridItemPropertyCollection ItemProperties - { - get - { - return m_itemProperties; - } - } - - private readonly DataGridItemPropertyCollection m_itemProperties; - - #endregion - - #region DefaultCalculateDistinctValues Public Property - - public bool DefaultCalculateDistinctValues - { - get - { - return m_flags[ ( int )DataGridDetailDescriptionFlags.DefaultCalculateDistinctValues ]; - } - set - { - m_flags[ ( int )DataGridDetailDescriptionFlags.DefaultCalculateDistinctValues ] = value; - } - } - - #endregion - - #region DetailDescriptions Public Property - - public DataGridDetailDescriptionCollection DetailDescriptions - { - get - { - return m_detailDescriptions; - } - } - - private readonly DataGridDetailDescriptionCollection m_detailDescriptions; - - #endregion - - #region GroupDescriptions Public Property - - public ObservableCollection GroupDescriptions - { - get - { - return m_groupDescriptions; - } - } - - private readonly GroupDescriptionCollection m_groupDescriptions; - - #endregion - - #region SortDescriptions Public Propertiy - - public SortDescriptionCollection SortDescriptions - { - get - { - return m_sortDescriptions; - } - } - - private readonly DataGridSortDescriptionCollection m_sortDescriptions; - - #endregion - - #region AutoCreateItemPropertiesCompleted Internal Property - - internal bool AutoCreateItemPropertiesCompleted - { - get - { - return m_flags[ ( int )DataGridDetailDescriptionFlags.AutoCreateItemPropertiesCompleted ]; - } - set - { - m_flags[ ( int )DataGridDetailDescriptionFlags.AutoCreateItemPropertiesCompleted ] = value; - } - } - - #endregion - - #region AutoCreateDetailDescriptionsCompleted Internal Property - - internal bool AutoCreateDetailDescriptionsCompleted - { - get - { - return m_flags[ ( int )DataGridDetailDescriptionFlags.AutoCreateDetailDescriptionsCompleted ]; - } - set - { - m_flags[ ( int )DataGridDetailDescriptionFlags.AutoCreateDetailDescriptionsCompleted ] = value; - } - } - - #endregion - - #region DefaultItemPropertiesInitialized Internal Property - - internal bool DefaultItemPropertiesInitialized - { - get - { - return m_flags[ ( int )DataGridDetailDescriptionFlags.DefaultItemPropertiesInitialized ]; - } - set - { - m_flags[ ( int )DataGridDetailDescriptionFlags.DefaultItemPropertiesInitialized ] = value; - } - } - - #endregion - - #region DefaultPropertyDescriptionsCreated Internal Property - - internal bool DefaultPropertyDescriptionsCreated - { - get - { - return m_flags[ ( int )DataGridDetailDescriptionFlags.DefaultPropertyDescriptionsCreated ]; - } - set - { - m_flags[ ( int )DataGridDetailDescriptionFlags.DefaultPropertyDescriptionsCreated ] = value; - } - } - - #endregion - - #region DefaultPropertyDescriptions Internal Property - - internal PropertyDescriptionRouteDictionary DefaultPropertyDescriptions - { - get - { - return m_defaultPropertyDescriptions; - } - } - - private readonly PropertyDescriptionRouteDictionary m_defaultPropertyDescriptions; - - #endregion - - #region IsAutoCreated Internal Property - - internal bool IsAutoCreated - { - get - { - return m_flags[ ( int )DataGridDetailDescriptionFlags.IsAutoCreated ]; - } - set - { - m_flags[ ( int )DataGridDetailDescriptionFlags.IsAutoCreated ] = value; - } - } - - #endregion - - #region InternalIsSealed Internal Property - - internal bool InternalIsSealed - { - get - { - return m_flags[ ( int )DataGridDetailDescriptionFlags.IsSealed ]; - } - private set - { - m_flags[ ( int )DataGridDetailDescriptionFlags.IsSealed ] = value; - } - } - - #endregion - - #region IsInitialized Internal Property - - internal bool IsInitialized - { - get - { - return m_flags[ ( int )DataGridDetailDescriptionFlags.IsInitialized ]; - } - set - { - m_flags[ ( int )DataGridDetailDescriptionFlags.IsInitialized ] = value; - } - } - - #endregion - - #region ItemType Internal Property - - internal Type ItemType - { - get - { - return m_itemType; - } - set - { - if( value == m_itemType ) - return; - - m_itemType = value; - } - } - - private Type m_itemType; //null - - #endregion - - #region DataGridSortDescriptions Internal Property - - internal DataGridSortDescriptionCollection DataGridSortDescriptions - { - get - { - return m_sortDescriptions; - } - } - - #endregion - - protected internal virtual void Initialize( DataGridCollectionViewBase parentCollectionView ) - { - } - - protected internal abstract IEnumerable GetDetailsForParentItem( DataGridCollectionViewBase parentCollectionView, object parentItem ); - - internal void Seal() - { - this.InternalIsSealed = true; - } - - internal void InternalInitialize( DataGridCollectionViewBase parentCollectionView ) - { - if( string.IsNullOrEmpty( this.RelationName ) ) - throw new InvalidOperationException( "An attempt was made to initialize a detail description that does not have a relation name." ); - - this.Initialize( parentCollectionView ); - } - - private void OnItemPropertiesCollectionChanged( object sender, NotifyCollectionChangedEventArgs e ) - { - var removedItems = default( IEnumerable ); - - switch( e.Action ) - { - case NotifyCollectionChangedAction.Replace: - removedItems = e.OldItems.Cast(); - break; - - case NotifyCollectionChangedAction.Remove: - removedItems = e.OldItems.Cast(); - break; - - case NotifyCollectionChangedAction.Reset: - throw new NotSupportedException(); - } - } - - #region IWeakEventListener Members - - 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( ( managerType == null ) || ( sender == null ) || ( e == null ) ) - return false; - - if( managerType == typeof( CollectionChangedEventManager ) ) - { - var eventArgs = ( NotifyCollectionChangedEventArgs )e; - - if( m_itemProperties == sender ) - { - this.OnItemPropertiesCollectionChanged( sender, eventArgs ); - } - else if( m_detailDescriptions == sender ) - { - } - } - else if( managerType == typeof( InitializeItemPropertyEventManager ) ) - { - var eventArgs = ( InitializeItemPropertyEventArgs )e; - - if( m_itemProperties == sender ) - { - var itemProperty = eventArgs.ItemProperty; - var itemPropertyRoute = DataGridItemPropertyRoute.Create( itemProperty ); - - ItemsSourceHelper.SetPropertyDescriptionsFromItemProperty( m_defaultPropertyDescriptions, null, null, m_itemType, itemPropertyRoute ); - ItemsSourceHelper.InitializePropertyDescriptions( m_defaultPropertyDescriptions, itemPropertyRoute, m_itemType, this.DefaultPropertyDescriptionsCreated ); - } - } - else - { - return false; - } - - return true; - } - - #endregion - - private BitVector32 m_flags = new BitVector32(); - - [Flags] - private enum DataGridDetailDescriptionFlags - { - IsSealed = 1 << 0, - DefaultCalculateDistinctValues = 1 << 1, - IsInitialized = 1 << 2, - AutoCreateItemProperties = 1 << 3, - AutoCreateDetailDescriptions = 1 << 4, - AutoCreateForeignKeyDescriptions = 1 << 5, - IsAutoCreated = 1 << 6, - AutoCreateItemPropertiesCompleted = 1 << 7, - AutoCreateDetailDescriptionsCompleted = 1 << 8, - DefaultItemPropertiesInitialized = 1 << 9, - DefaultPropertyDescriptionsCreated = 1 << 10, - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridDetailDescriptionCollection.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridDetailDescriptionCollection.cs deleted file mode 100644 index 218d3575..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridDetailDescriptionCollection.cs +++ /dev/null @@ -1,77 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; - -namespace Xceed.Wpf.DataGrid -{ - internal class DataGridDetailDescriptionCollection : ObservableCollection - { - public DataGridDetailDescriptionCollection() - { - } - - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Design", "CA1002:DoNotExposeGenericLists" )] - public DataGridDetailDescriptionCollection( List detailDescriptions ) - : base( detailDescriptions ) - { - } - - public DataGridDetailDescription this[ string relationName ] - { - get - { - var index = this.IndexOf( relationName ); - if( index < 0 ) - return null; - - return this.Items[ index ]; - } - } - - public int IndexOf( string relationName ) - { - var items = this.Items; - var count = items.Count; - - for( int i = 0; i < count; i++ ) - { - if( string.Equals( items[ i ].RelationName, relationName ) ) - return i; - } - - return -1; - } - - protected override void SetItem( int index, DataGridDetailDescription item ) - { - if( string.IsNullOrEmpty( item.RelationName ) ) - throw new ArgumentException( "The RelationName property of the specified DataGridDetailDescription cannot be null or empty.", "item" ); - - base.SetItem( index, item ); - } - - protected override void InsertItem( int index, DataGridDetailDescription item ) - { - if( string.IsNullOrEmpty( item.RelationName ) ) - throw new ArgumentException( "The RelationName property of the specified DataGridDetailDescription cannot be null or empty.", "item" ); - - base.InsertItem( index, item ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridGroupDescription.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridGroupDescription.cs deleted file mode 100644 index 1bd2b380..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridGroupDescription.cs +++ /dev/null @@ -1,122 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Collections; -using System.ComponentModel; -using System.Globalization; -using System.Windows.Data; - -namespace Xceed.Wpf.DataGrid -{ - public class DataGridGroupDescription : GroupDescription - { - public DataGridGroupDescription() - { - } - - public DataGridGroupDescription( string propertyName ) - { - m_propertyGroupDescription.PropertyName = propertyName; - } - - public string PropertyName - { - get - { - return m_propertyGroupDescription.PropertyName; - } - - set - { - m_propertyGroupDescription.PropertyName = value; - this.OnPropertyChanged( new PropertyChangedEventArgs( "PropertyName" ) ); - } - } - - public IComparer SortComparer - { - get - { - return m_sortComparer; - } - set - { - m_sortComparer = value; - this.OnPropertyChanged( new PropertyChangedEventArgs( "SortComparer" ) ); - } - } - - public GroupConfiguration GroupConfiguration - { - get - { - return m_groupConfiguration; - } - set - { - m_groupConfiguration = value; - } - } - - public override object GroupNameFromItem( object item, int level, CultureInfo culture ) - { - return this.GetPropertyValue( item ); - } - - public override sealed bool NamesMatch( object groupName, object itemName ) - { - // We sealed up the NamesMatch because we will use a HashTable to find existing key - // for performance reason. - // - // We do not throw, because we want our GroupDescription to be usable in other CollectionView - return base.NamesMatch( groupName, itemName ); - } - - protected object GetPropertyValue( object item ) - { - if( m_contextProperty != null ) - return ItemsSourceHelper.GetValueFromItemProperty( m_contextProperty, item ); - - return m_propertyGroupDescription.GroupNameFromItem( item, 0, CultureInfo.InvariantCulture ); - } - - internal void SetContext( DataGridCollectionView collectionView ) - { - if( collectionView == null ) - { - m_contextProperty = null; - } - else - { - var propertyName = m_propertyGroupDescription.PropertyName; - - if( string.IsNullOrEmpty( propertyName ) ) - { - m_contextProperty = null; - } - else - { - m_contextProperty = ItemsSourceHelper.GetItemPropertyFromProperty( collectionView.ItemProperties, propertyName ); - } - } - } - - private IComparer m_sortComparer; - private DataGridItemPropertyBase m_contextProperty; - private PropertyGroupDescription m_propertyGroupDescription = new PropertyGroupDescription(); - private GroupConfiguration m_groupConfiguration; // = null - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridGroupInfo.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridGroupInfo.cs deleted file mode 100644 index ba7ffdcf..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridGroupInfo.cs +++ /dev/null @@ -1,71 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows.Data; -using System.ComponentModel; - -namespace Xceed.Wpf.DataGrid -{ - public class DataGridGroupInfo - { - internal DataGridGroupInfo( GroupDescription groupDescription, CollectionViewGroup collectionViewGroup ) - { - if( groupDescription == null ) - throw new ArgumentNullException( "groupDescription" ); - - if( collectionViewGroup == null ) - throw new ArgumentNullException( "collectionViewGroup" ); - - this.GroupDescription = groupDescription; - this.PropertyName = DataGridCollectionViewBase.GetPropertyNameFromGroupDescription( groupDescription ); - this.Value = collectionViewGroup.Name; - } - - #region GroupDescription PROPERTY - - public GroupDescription GroupDescription - { - get; - private set; - } - - #endregion GroupDescription PROPERTY - - #region Value PROPERTY - - public object Value - { - get; - private set; - } - - #endregion Value PROPERTY - - #region PropertyName PROPERTY - - public string PropertyName - { - get; - private set; - } - - #endregion PropertyName PROPERTY - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemCancelEvent.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemCancelEvent.cs deleted file mode 100644 index 51dfbbaa..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemCancelEvent.cs +++ /dev/null @@ -1,53 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - public class DataGridItemCancelEventArgs : DataGridItemHandledEventArgs - { - public DataGridItemCancelEventArgs( - DataGridCollectionViewBase collectionView, - object item, - bool cancel ) - : base( collectionView, item ) - { - m_cancel = cancel; - } - - #region Cancel Property - - public bool Cancel - { - get - { - return m_cancel; - } - set - { - m_cancel = value; - } - } - - private bool m_cancel; - - #endregion Cancel Property - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemEvent.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemEvent.cs deleted file mode 100644 index aafe44f0..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemEvent.cs +++ /dev/null @@ -1,60 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.ComponentModel; - -namespace Xceed.Wpf.DataGrid -{ - public class DataGridItemEventArgs : EventArgs - { - public DataGridItemEventArgs( - DataGridCollectionViewBase collectionView, - object item ) - { - m_collectionView = collectionView; - m_item = item; - } - - #region CollectionView Property - - public DataGridCollectionViewBase CollectionView - { - get { return m_collectionView; } - } - - private DataGridCollectionViewBase m_collectionView; - - #endregion CollectionView Property - - #region Item Property - - public object Item - { - get - { - return m_item; - } - } - - private object m_item; - - #endregion Item Property - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemHandledEvent.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemHandledEvent.cs deleted file mode 100644 index 03261982..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemHandledEvent.cs +++ /dev/null @@ -1,51 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - public class DataGridItemHandledEventArgs : DataGridItemEventArgs - { - public DataGridItemHandledEventArgs( - DataGridCollectionViewBase collectionView, - object item ) - : base( collectionView, item ) - { - } - - #region Handled Property - - public bool Handled - { - get - { - return m_handled; - } - set - { - m_handled = value; - } - } - - private bool m_handled; - - #endregion Handled Property - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemProperty.PropertyDescriptorFromItemProperty.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemProperty.PropertyDescriptorFromItemProperty.cs deleted file mode 100644 index 4c488cfe..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemProperty.PropertyDescriptorFromItemProperty.cs +++ /dev/null @@ -1,68 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.ComponentModel; - -namespace Xceed.Wpf.DataGrid -{ - public partial class DataGridItemProperty - { - internal class PropertyDescriptorFromItemProperty : DataGridItemPropertyBase.PropertyDescriptorFromItemPropertyBase - { - public PropertyDescriptorFromItemProperty( DataGridItemProperty dataGridItemProperty ) - : base( dataGridItemProperty ) - { - m_propertyDescriptorForValueChanged = dataGridItemProperty.PropertyDescriptor; - } - - public override void AddValueChanged( object component, EventHandler handler ) - { - if( m_propertyDescriptorForValueChanged != null ) - { - if( !( component is EmptyDataItem ) ) - { - m_propertyDescriptorForValueChanged.AddValueChanged( component, handler ); - } - } - else - { - base.AddValueChanged( component, handler ); - } - } - - public override void RemoveValueChanged( object component, EventHandler handler ) - { - if( m_propertyDescriptorForValueChanged != null ) - { - if( !( component is EmptyDataItem ) ) - { - m_propertyDescriptorForValueChanged.RemoveValueChanged( component, handler ); - } - } - else - { - base.RemoveValueChanged( component, handler ); - } - } - - private PropertyDescriptor m_propertyDescriptorForValueChanged; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemProperty.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemProperty.cs deleted file mode 100644 index 7e4ebe1a..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemProperty.cs +++ /dev/null @@ -1,629 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; -using System.Data; -using System.Diagnostics; -using System.Globalization; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - [DebuggerDisplay( "Name = {Name}" )] - public partial class DataGridItemProperty : DataGridItemPropertyBase - { - public DataGridItemProperty() - { - } - - public DataGridItemProperty( string name, string valuePath, Type dataType ) - : this( name, null, valuePath, dataType ) - { - } - - public DataGridItemProperty( string name, string valueXPath, string valuePath, Type dataType ) - { - if( string.IsNullOrEmpty( name ) ) - throw new ArgumentException( "name cannot be null or empty.", "name" ); - - if( ( string.IsNullOrEmpty( valuePath ) ) && ( string.IsNullOrEmpty( valueXPath ) ) ) - throw new ArgumentException( "valuePath or valueXPath cannot be null or empty." ); - - this.Initialize( - name, - null, - null, - valueXPath, - valuePath, - dataType, - false, - null, - null, - null, - null, - null ); - } - - public DataGridItemProperty( string name, string valuePath, Type dataType, bool isReadOnly ) - : this( name, null, valuePath, dataType, isReadOnly ) - { - } - - public DataGridItemProperty( string name, string valueXPath, string valuePath, Type dataType, bool isReadOnly ) - { - if( string.IsNullOrEmpty( name ) ) - throw new ArgumentException( "name cannot be null or empty.", "name" ); - - if( ( string.IsNullOrEmpty( valuePath ) ) && ( string.IsNullOrEmpty( valueXPath ) ) ) - throw new ArgumentException( "valuePath or valueXPath cannot be null or empty." ); - - this.Initialize( - name, - null, - null, - valueXPath, - valuePath, - dataType, - false, - isReadOnly, - null, - null, - null, - null ); - } - - public DataGridItemProperty( PropertyDescriptor propertyDescriptor ) - : this( propertyDescriptor, false ) - { - } - - public DataGridItemProperty( string name, Type dataType ) - { - if( string.IsNullOrEmpty( name ) ) - throw new ArgumentException( "The name must not be null (Nothing in Visual Basic) or empty.", "name" ); - - if( dataType == null ) - throw new ArgumentNullException( "dataType" ); - - this.Initialize( - name, - null, - null, - null, - null, - dataType, - false, - null, - null, - null, - null, - null ); - } - - public DataGridItemProperty( string name, Type dataType, bool isReadOnly ) - : this( name, dataType, isReadOnly, null ) - { - } - - public DataGridItemProperty( string name, Type dataType, bool isReadOnly, Nullable overrideReadOnlyForInsertion ) - { - if( string.IsNullOrEmpty( name ) ) - throw new ArgumentException( "The name must not be null (Nothing in Visual Basic) or empty.", "name" ); - - if( dataType == null ) - throw new ArgumentNullException( "dataType" ); - - this.Initialize( - name, - null, - null, - null, - null, - dataType, - false, - isReadOnly, - overrideReadOnlyForInsertion, - null, - null, - null ); - } - - public DataGridItemProperty( string name, PropertyDescriptor propertyDescriptor ) - { - if( string.IsNullOrEmpty( name ) ) - throw new ArgumentException( "The name must not be null (Nothing in Visual Basic) or empty.", "name" ); - - if( propertyDescriptor == null ) - throw new ArgumentNullException( "propertyDescriptor" ); - - this.Initialize( - name, - propertyDescriptor, - null, - null, - null, - null, - false, - null, - null, - null, - null, - null ); - } - - internal DataGridItemProperty( PropertyDescriptor propertyDescriptor, bool isAutoCreated ) - { - if( propertyDescriptor == null ) - throw new ArgumentNullException( "propertyDescriptor" ); - - this.Initialize( - propertyDescriptor.Name, - propertyDescriptor, - null, - null, - null, - null, - isAutoCreated, - null, - null, - null, - null, - null ); - } - - internal DataGridItemProperty( - string name, - PropertyDescriptor propertyDescriptor, - string title, - string valueXPath, - string valuePath, - Type dataType, - bool isAutoCreated, - Nullable isReadOnly, - Nullable overrideReadOnlyForInsertion, - Nullable isDisplayable, - Nullable isASubRelationship, - DataGridForeignKeyDescription foreignKeyDescription ) - { - if( string.IsNullOrEmpty( name ) ) - throw new ArgumentException( "name cannot be null or empty.", "name" ); - - if( ( string.IsNullOrEmpty( valuePath ) ) && ( string.IsNullOrEmpty( valueXPath ) ) && ( propertyDescriptor == null ) ) - throw new ArgumentException( "The valuePath, valueXPath, or propertyDescriptor must be provided." ); - - this.Initialize( - name, - propertyDescriptor, - title, - valueXPath, - valuePath, - dataType, - isAutoCreated, - isReadOnly, - overrideReadOnlyForInsertion, - isDisplayable, - isASubRelationship, - foreignKeyDescription ); - } - - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - [Obsolete( "This constructor is obsolete and should no longer be used.", true )] - protected DataGridItemProperty( DataGridItemProperty template ) - { - throw new NotSupportedException(); - } - - private void Initialize( - string name, - PropertyDescriptor propertyDescriptor, - string title, - string valueXPath, - string valuePath, - Type dataType, - bool isAutoCreated, - Nullable isReadOnly, - Nullable overrideReadOnlyForInsertion, - Nullable isDisplayable, - Nullable isASubRelationship, - DataGridForeignKeyDescription foreignKeyDescription ) - { - this.IsAutoCreated = isAutoCreated; - m_valueXPath = valueXPath; - m_valuePath = valuePath; - m_propertyDescriptor = propertyDescriptor; - - if( m_propertyDescriptor == null ) - { - if( ( string.IsNullOrEmpty( m_valueXPath ) ) && ( m_valuePath == "." ) ) - m_propertyDescriptor = new SelfPropertyDescriptor( dataType ); - } - - if( m_propertyDescriptor != null ) - { - this.IsBrowsable = m_propertyDescriptor.IsBrowsable; - - if( m_propertyDescriptor.IsReadOnly ) - isReadOnly = m_propertyDescriptor.IsReadOnly; - } - - if( title == null ) - { - if( m_propertyDescriptor != null ) - { - title = m_propertyDescriptor.DisplayName; - } - } - - if( isReadOnly == null ) - { - if( m_propertyDescriptor != null ) - { - isReadOnly = m_propertyDescriptor.IsReadOnly; - } - } - - if( dataType == null ) - { - if( m_propertyDescriptor != null ) - { - dataType = m_propertyDescriptor.PropertyType; - } - } - - this.ForeignKeyDescription = foreignKeyDescription; - - base.Initialize( name, title, dataType, isReadOnly, overrideReadOnlyForInsertion, isDisplayable, isASubRelationship ); - } - - #region ValuePath Property - - public string ValuePath - { - get - { - return m_valuePath; - } - set - { - if( this.IsSealed ) - throw new InvalidOperationException( "An attempt was made to change the ValuePath of a property already added to a containing collection." ); - - this.SetValuePath( value ); - } - } - - internal void SetValuePath( string valuePath ) - { - m_valuePath = valuePath; - m_bindingPathValueExtractorForRead = null; - m_bindingPathValueExtractorForWrite = null; - } - - private string m_valuePath; - - #endregion - - #region ValueXPath Property - - public string ValueXPath - { - get - { - return m_valueXPath; - } - set - { - if( this.IsSealed ) - throw new InvalidOperationException( "An attempt was made to change the ValueXPath of a property already added to a containing collection." ); - - this.SetValueXPath( value ); - } - } - - internal void SetValueXPath( string valueXPath ) - { - m_valueXPath = valueXPath; - m_bindingPathValueExtractorForRead = null; - m_bindingPathValueExtractorForWrite = null; - } - - private string m_valueXPath; - - #endregion - - #region PropertyDescriptor Property - - public PropertyDescriptor PropertyDescriptor - { - get - { - return m_propertyDescriptor; - } - set - { - if( this.IsSealed ) - throw new InvalidOperationException( "An attempt was made to change the PropertyDescriptor of a property already added to a containing collection." ); - - this.SetPropertyDescriptor( value ); - } - } - - internal void SetPropertyDescriptor( PropertyDescriptor propertyDescriptor ) - { - m_propertyDescriptor = propertyDescriptor; - - if( ( m_propertyDescriptor != null ) && ( !this.IsReadOnly ) ) - { - this.SetIsReadOnly( propertyDescriptor.IsReadOnly ); - } - - m_bindingPathValueExtractorForRead = null; - m_bindingPathValueExtractorForWrite = null; - } - - private PropertyDescriptor m_propertyDescriptor; - - #endregion - - #region IsAutoCreated Property - - public bool IsAutoCreated - { - get; - private set; - } - - #endregion - - #region FieldName Internal Property - - internal override string FieldName - { - get - { - var descriptor = this.PropertyDescriptor; - if( descriptor != null ) - return descriptor.Name; - - return base.FieldName; - } - } - - #endregion - - protected override object GetValueCore( object component ) - { - if( m_propertyDescriptor != null ) - { - object value; - - try - { - value = m_propertyDescriptor.GetValue( component ); - } - catch( DataException ) - { - // We have to return null if the datarow is deleted from the DataTable. When the System.Data.DataRow has RowState == detached, - // it can be because it has been deleted or it being inserted, nothing special found to differentiate that 2 state. So doing a try catch. - value = null; - } - - CultureInfo converterCulture = this.ConverterCulture; - - if( converterCulture == null ) - { - converterCulture = CultureInfo.InvariantCulture; - } - - return this.GetBindingConverter( component ).Convert( value, this.DataType, this.ConverterParameter, converterCulture ); - } - - if( m_bindingPathValueExtractorForRead == null ) - { - CultureInfo converterCulture = this.ConverterCulture; - - if( converterCulture == null ) - { - converterCulture = CultureInfo.InvariantCulture; - } - - PropertyPath propertyPath = null; - - if( !string.IsNullOrEmpty( this.ValuePath ) ) - { - propertyPath = new PropertyPath( this.ValuePath, BindingPathValueExtractor.EmptyObjectArray ); - } - - m_bindingPathValueExtractorForRead = new BindingPathValueExtractor( this.ValueXPath, propertyPath, false, this.DataType, - this.GetBindingConverter( component ), this.ConverterParameter, converterCulture ); - } - - return m_bindingPathValueExtractorForRead.GetValueFromItem( component ); - } - - protected override void SetValueCore( object component, object value ) - { - if( m_propertyDescriptor != null ) - { - CultureInfo converterCulture = this.ConverterCulture; - - if( converterCulture == null ) - { - converterCulture = CultureInfo.InvariantCulture; - } - - object convertedValue = this.GetBindingConverter( component ).ConvertBack( value, m_propertyDescriptor.PropertyType, this.ConverterParameter, converterCulture ); - - m_propertyDescriptor.SetValue( component, convertedValue ); - } - else - { - if( m_bindingPathValueExtractorForWrite == null ) - { - CultureInfo converterCulture = this.ConverterCulture; - - if( converterCulture == null ) - { - converterCulture = CultureInfo.InvariantCulture; - } - - PropertyPath propertyPath = null; - - if( !string.IsNullOrEmpty( this.ValuePath ) ) - { - propertyPath = new PropertyPath( this.ValuePath, BindingPathValueExtractor.EmptyObjectArray ); - } - - m_bindingPathValueExtractorForWrite = new BindingPathValueExtractor( this.ValueXPath, propertyPath, true, this.DataType, - this.GetBindingConverter( component ), this.ConverterParameter, converterCulture ); - } - - m_bindingPathValueExtractorForWrite.SetValueToItem( component, value ); - } - - base.SetValueCore( component, value ); - } - - internal override PropertyDescriptorFromItemPropertyBase GetPropertyDescriptorForBindingCore() - { - return new PropertyDescriptorFromItemProperty( this ); - } - - internal override void SetUnspecifiedPropertiesValues( - PropertyDescription description, - Type itemType, - bool defaultItemPropertiesCreated ) - { - var itemIsXceedDataRow = ( itemType != null ) ? typeof( DataRow ).IsAssignableFrom( itemType ) : false; - - if( ( this.PropertyDescriptor == null ) && string.IsNullOrEmpty( this.ValuePath ) && string.IsNullOrEmpty( this.ValueXPath ) ) - { - if( itemIsXceedDataRow ) - { - this.SetPropertyDescriptor( new UnboundDataRowPropertyDescriptor( this.Name, this.DataType ) ); - } - else - { - if( description == null ) - { - if( this.Name == "." ) - { - this.SetPropertyDescriptor( new SelfPropertyDescriptor( this.DataType ) ); - this.SetValuePath( "." ); - this.SetIsReadOnly( true ); - this.SetOverrideReadOnlyForInsertion( false ); - } - } - else - { - this.SetPropertyDescriptor( description.PropertyDescriptor ); - this.SetValuePath( description.Path ); - this.SetValueXPath( description.XPath ); - } - } - - if( defaultItemPropertiesCreated && ( this.PropertyDescriptor == null ) && string.IsNullOrEmpty( this.ValuePath ) && string.IsNullOrEmpty( this.ValueXPath ) ) - { - // I have to add this particular exception case to make sure that when the ItemProperty is "re-normalized" when the first DataGridCollectionView - // is created for it, then the ValuePath is still null or empty (allowing it to be re-normalized) - this.SetValuePath( this.Name ); - } - } - - if( this.DataType == null ) - { - //only try to affect the DataType if the DefaultPropertyDescriptions were set. (will not be the case when XAML parsing DetailDescriptions) - if( defaultItemPropertiesCreated ) - { - if( description == null ) - throw new InvalidOperationException( "An attempt was made to add an item (" + this.Name + ") without specifying its data type." ); - - this.SetDataType( description.DataType ); - } - } - - if( string.IsNullOrEmpty( this.Title ) ) - { - if( !itemIsXceedDataRow && ( description != null ) && !string.IsNullOrEmpty( description.DisplayName ) ) - { - this.Title = description.DisplayName; - } - else - { - this.Title = this.Name; - } - } - - if( !this.IsReadOnly ) - { - if( description != null ) - { - this.SetIsReadOnly( description.IsReadOnly ); - } - } - - if( this.OverrideReadOnlyForInsertion == null ) - { - //only try to affect the DataType if the DefaultItemProperties were set. (will not be the case when XAML parsing DetailDescriptions) - if( defaultItemPropertiesCreated ) - { - this.SetOverrideReadOnlyForInsertion( ( description != null ) ? description.OverrideReadOnlyForInsertion : false ); - } - } - - if( ( !string.IsNullOrEmpty( this.ValueXPath ) ) && ( string.IsNullOrEmpty( this.ValuePath ) ) ) - { - this.SetValuePath( "InnerText" ); - } - - var foreignKeyDescriptionIsNull = ( this.ForeignKeyDescription == null ); - var foreignKeyDescriptionItemsSourceIsNull = false; - - if( !foreignKeyDescriptionIsNull ) - { - foreignKeyDescriptionItemsSourceIsNull = ( this.ForeignKeyDescription.ItemsSource == null ); - } - - // Update the ForeignKeyDescription if not set - if( foreignKeyDescriptionIsNull || foreignKeyDescriptionItemsSourceIsNull ) - { - if( ( description != null ) && ( description.ForeignKeyDescription != null ) ) - { - if( foreignKeyDescriptionIsNull ) - { - this.SetForeignKeyDescription( description.ForeignKeyDescription ); - } - else - { - if( foreignKeyDescriptionItemsSourceIsNull ) - { - this.ForeignKeyDescription.ItemsSource = description.ForeignKeyDescription.ItemsSource; - } - } - } - } - } - - #region Private Fields - - private BindingPathValueExtractor m_bindingPathValueExtractorForRead; - private BindingPathValueExtractor m_bindingPathValueExtractorForWrite; - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemPropertyBase.PropertyDescriptorFromItemPropertyBase.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemPropertyBase.PropertyDescriptorFromItemPropertyBase.cs deleted file mode 100644 index dff6b4ae..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemPropertyBase.PropertyDescriptorFromItemPropertyBase.cs +++ /dev/null @@ -1,113 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid -{ - public abstract partial class DataGridItemPropertyBase - { - internal class PropertyDescriptorFromItemPropertyBase : EmptyDataItemSafePropertyDescriptor - { - public PropertyDescriptorFromItemPropertyBase( DataGridItemPropertyBase dataGridItemProperty ) - : base( dataGridItemProperty.FieldName ) - { - m_dataGridItemProperty = new WeakReference( dataGridItemProperty ); - m_propertyType = dataGridItemProperty.DataType; - } - - public DataGridItemPropertyBase DataGridItemProperty - { - get - { - return m_dataGridItemProperty.Target as DataGridItemPropertyBase; - } - } - - public override string DisplayName - { - get - { - DataGridItemPropertyBase dataGridItemProperty = this.DataGridItemProperty; - - if( dataGridItemProperty != null ) - return dataGridItemProperty.Title; - - return string.Empty; - } - } - - public override bool IsReadOnly - { - get - { - DataGridItemPropertyBase dataGridItemProperty = this.DataGridItemProperty; - - if( dataGridItemProperty == null ) - return true; - - return ( dataGridItemProperty.OverrideReadOnlyForInsertion ?? false ) - ? false : dataGridItemProperty.IsReadOnly; - } - } - - public override Type PropertyType - { - get - { - // This value need to not be changed during the life time of the PropertyDescriptor - return m_propertyType; - } - } - - public override object GetValue( object component ) - { - DataGridItemPropertyBase dataGridItemProperty = this.DataGridItemProperty; - - if( dataGridItemProperty == null ) - return null; - - return dataGridItemProperty.GetValue( base.GetValue( component ) ); - } - - public override void SetValue( object component, object value ) - { - if( component is EmptyDataItem ) - throw new InvalidOperationException( "An attempt was made to set a value on an empty data item." ); - - DataGridItemPropertyBase dataGridItemProperty = this.DataGridItemProperty; - - if( dataGridItemProperty == null ) - return; - - dataGridItemProperty.SetValue( component, value ); - } - - public void RaiseValueChanged( object component ) - { - EventHandler valueChangedHandler = this.GetValueChangedHandler( component ); - - if( valueChangedHandler != null ) - { - valueChangedHandler.Invoke( component, EventArgs.Empty ); - } - } - - private WeakReference m_dataGridItemProperty; - private Type m_propertyType; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemPropertyBase.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemPropertyBase.cs deleted file mode 100644 index a2a3707b..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemPropertyBase.cs +++ /dev/null @@ -1,955 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.ComponentModel; -using System.Diagnostics; -using System.Globalization; -using System.Threading; -using System.Windows.Data; -using Xceed.Wpf.DataGrid.Converters; -using Xceed.Wpf.DataGrid.Utils; - -namespace Xceed.Wpf.DataGrid -{ - [DebuggerDisplay( "Name = {Name}" )] - public abstract partial class DataGridItemPropertyBase : INotifyPropertyChanged, ICloneable - { - #region Static Fields - - internal static readonly string CalculateDistinctValuesPropertyName = PropertyHelper.GetPropertyName( ( DataGridItemPropertyBase i ) => i.CalculateDistinctValues ); - internal static readonly string ContainingCollectionPropertyName = PropertyHelper.GetPropertyName( ( DataGridItemPropertyBase i ) => i.ContainingCollection ); - internal static readonly string ForeignKeyDescriptionPropertyName = PropertyHelper.GetPropertyName( ( DataGridItemPropertyBase i ) => i.ForeignKeyDescription ); - internal static readonly string GroupSortStatResultPropertyNamePropertyName = PropertyHelper.GetPropertyName( ( DataGridItemPropertyBase i ) => i.GroupSortStatResultPropertyName ); - internal static readonly string IsNameSealedPropertyName = PropertyHelper.GetPropertyName( ( DataGridItemPropertyBase i ) => i.IsNameSealed ); - internal static readonly string IsSealedPropertyName = PropertyHelper.GetPropertyName( ( DataGridItemPropertyBase i ) => i.IsSealed ); - internal static readonly string ItemPropertiesInternalPropertyName = PropertyHelper.GetPropertyName( ( DataGridItemPropertyBase i ) => i.ItemPropertiesInternal ); - internal static readonly string MaxDistinctValuesPropertyName = PropertyHelper.GetPropertyName( ( DataGridItemPropertyBase i ) => i.MaxDistinctValues ); - internal static readonly string SynonymPropertyName = PropertyHelper.GetPropertyName( ( DataGridItemPropertyBase i ) => i.Synonym ); - - #endregion - - protected DataGridItemPropertyBase() - { - this.SetIsDisplayable( true ); - this.IsBrowsable = true; - } - - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - [Obsolete( "This constructor is obsolete and should no longer be used.", true )] - protected DataGridItemPropertyBase( DataGridItemPropertyBase template ) - : this() - { - throw new NotSupportedException(); - } - - protected void Initialize( - string name, - string title, - Type dataType, - Nullable isReadOnly, - Nullable overrideReadOnlyForInsertion, - Nullable isDisplayable, - Nullable isASubRelationship ) - { - if( string.IsNullOrEmpty( name ) ) - throw new ArgumentException( "name cannot be null or empty.", "name" ); - - m_name = name; - - if( title == null ) - { - m_title = name; - } - else - { - m_title = title; - } - - if( isReadOnly.HasValue ) - { - this.SetIsReadOnly( isReadOnly.Value ); - } - - this.SetOverrideReadOnlyForInsertion( overrideReadOnlyForInsertion ); - m_dataType = dataType; - - if( isDisplayable.HasValue ) - { - this.SetIsDisplayable( isDisplayable.Value ); - } - - if( isASubRelationship != null ) - { - this.SetIsASubRelationship( isASubRelationship ); - } - } - - #region Name Property - - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly" )] - public string Name - { - get - { - return m_name; - } - set - { - if( string.IsNullOrEmpty( value ) ) - throw new ArgumentException( "Name is null (Nothing in Visual Basic) or empty.", "Name" ); - - if( this.IsNameSealed || this.IsSealed ) - throw new InvalidOperationException( "An attempt was made to change the name of a property already added to a containing collection." ); - - m_name = value; - } - } - - private string m_name; - - #endregion - - #region DataType Property - - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly" )] - public Type DataType - { - get - { - return m_dataType; - } - set - { - if( this.IsSealed ) - throw new InvalidOperationException( "An attempt was made to change the DataType of a property already added to a containing collection." ); - - this.SetDataType( value ); - } - } - - internal void SetDataType( Type dataType ) - { - if( dataType == null ) - throw new ArgumentNullException( "dataType" ); - - m_dataType = dataType; - } - - private Type m_dataType; - - #endregion - - #region IsReadOnly Property - - public bool IsReadOnly - { - get - { - return m_flags[ DataGridItemPropertyBaseFlags.IsReadOnly ]; - } - set - { - if( this.IsSealed ) - throw new InvalidOperationException( "An attempt was made to change the IsReadOnly property of a DataGridItemProperty already added to a containing collection." ); - - this.SetIsReadOnly( value ); - } - } - - internal void SetIsReadOnly( bool isReadOnly ) - { - m_flags[ DataGridItemPropertyBaseFlags.IsReadOnly ] = isReadOnly; - } - - #endregion - - #region OverrideReadOnlyForInsertion Property - - public Nullable OverrideReadOnlyForInsertion - { - get - { - if( !m_flags[ DataGridItemPropertyBaseFlags.IsOverrideReadOnlyForInsertionSet ] ) - return null; - - return m_flags[ DataGridItemPropertyBaseFlags.IsOverrideReadOnlyForInsertion ]; - } - set - { - if( this.IsSealed ) - throw new InvalidOperationException( "An attempt was made to change the OverrideReadOnlyForInsertion property of a DataGridItemProperty already added to a containing collection." ); - - this.SetOverrideReadOnlyForInsertion( value ); - } - } - - internal void SetOverrideReadOnlyForInsertion( Nullable overrideReadOnlyForInsertion ) - { - if( overrideReadOnlyForInsertion.HasValue ) - { - m_flags[ DataGridItemPropertyBaseFlags.IsOverrideReadOnlyForInsertion ] = overrideReadOnlyForInsertion.Value; - m_flags[ DataGridItemPropertyBaseFlags.IsOverrideReadOnlyForInsertionSet ] = true; - } - else - { - m_flags[ DataGridItemPropertyBaseFlags.IsOverrideReadOnlyForInsertionSet - | DataGridItemPropertyBaseFlags.IsOverrideReadOnlyForInsertion ] = false; - } - } - - #endregion - - #region Title Property - - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly" )] - public string Title - { - get - { - return m_title; - } - set - { - if( value == null ) - throw new ArgumentNullException( "Title" ); - - m_title = value; - } - } - - private string m_title; - - #endregion - - #region Synonym Property - - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly" )] - public string Synonym - { - get - { - return m_synonym; - } - set - { - if( this.IsSealed ) - throw new InvalidOperationException( "An attempt was made to change the Synonym of a property already added to a containing collection." ); - - this.SetSynonym( value ); - } - } - - internal void SetSynonym( string value ) - { - if( value == m_synonym ) - return; - - var wasSealed = this.IsSealed; - this.IsSealed = false; - - m_synonym = value; - - this.IsSealed = wasSealed; - this.OnPropertyChanged( DataGridItemPropertyBase.SynonymPropertyName ); - } - - private string m_synonym; - - #endregion - - #region SortComparer Property - - public IComparer SortComparer - { - get - { - return m_sortComparer; - } - set - { - m_sortComparer = value; - } - } - - private IComparer m_sortComparer; - - #endregion - - #region Converter Property - - public IValueConverter Converter - { - get - { - return m_converter; - } - set - { - if( this.IsSealed ) - throw new InvalidOperationException( "An attempt was made to change the Converter property of a DataGridItemProperty already added to a containing collection." ); - - m_converter = value; - } - } - - internal IValueConverter GetBindingConverter( object sourceItem ) - { - if( !this.IsSealed ) - throw new InvalidOperationException( "An attempt was made to apply a binding to a DataGridItemProperty that has not be added to the ItemProperties collection." ); - - if( m_bindingConverter == null ) - { - if( m_converter != null ) - { - m_bindingConverter = m_converter; - } - else - { - m_bindingConverter = new SourceDataConverter( ItemsSourceHelper.IsItemSupportingDBNull( sourceItem ), CultureInfo.InvariantCulture ); - } - } - - return m_bindingConverter; - } - - private IValueConverter m_converter; - private IValueConverter m_bindingConverter; - - #endregion - - #region ConverterCulture Property - - public CultureInfo ConverterCulture - { - get - { - return m_converterCulture; - } - set - { - if( this.IsSealed ) - throw new InvalidOperationException( "An attempt was made to change the ConverterCulture property of a DataGridItemProperty already added to a containing collection." ); - - m_converterCulture = value; - } - } - - private CultureInfo m_converterCulture; - - #endregion - - #region ConverterParameter Property - - public object ConverterParameter - { - get - { - return m_converterParameter; - } - set - { - if( this.IsSealed ) - throw new InvalidOperationException( "An attempt was made to change the ConverterParameter property of a DataGridItemProperty already added to a containing collection." ); - - m_converterParameter = value; - } - } - - private object m_converterParameter; - - #endregion - - #region CalculateDistinctValues Property - - public bool CalculateDistinctValues - { - get - { - // Always activate DistinctValues if not explicitly specified - if( !this.IsCalculateDistinctValuesInitialized ) - return true; - - return m_flags[ DataGridItemPropertyBaseFlags.CalculateDistinctValues ]; - } - set - { - if( value != m_flags[ DataGridItemPropertyBaseFlags.CalculateDistinctValues ] ) - { - m_flags[ DataGridItemPropertyBaseFlags.CalculateDistinctValues ] = value; - this.OnPropertyChanged( DataGridItemPropertyBase.CalculateDistinctValuesPropertyName ); - } - - this.IsCalculateDistinctValuesInitialized = true; - } - } - - internal bool IsCalculateDistinctValuesInitialized - { - get - { - return m_flags[ DataGridItemPropertyBaseFlags.IsCalculateDistinctValuesInitialized ]; - } - set - { - m_flags[ DataGridItemPropertyBaseFlags.IsCalculateDistinctValuesInitialized ] = value; - } - } - - #endregion - - #region MaxDistinctValues Property - - public int MaxDistinctValues - { - get - { - return m_maxDistinctValues; - } - set - { - if( m_maxDistinctValues != value ) - { - m_maxDistinctValues = value; - this.OnPropertyChanged( DataGridItemPropertyBase.MaxDistinctValuesPropertyName ); - } - } - } - - private int m_maxDistinctValues = -1; // -1 ==> no maximum - - #endregion - - #region DistinctValuesSortComparer Property - - public IComparer DistinctValuesSortComparer - { - get; - set; - } - - #endregion - - #region DistinctValuesEqualityComparer Property - - public IEqualityComparer DistinctValuesEqualityComparer - { - get; - set; - } - - #endregion - - #region ForeignKeyDescription Property - - public DataGridForeignKeyDescription ForeignKeyDescription - { - get - { - return m_foreignKeyDescription; - } - set - { - this.SetForeignKeyDescription( value ); - } - } - - internal void SetForeignKeyDescription( DataGridForeignKeyDescription description ) - { - if( m_foreignKeyDescription != description ) - { - m_foreignKeyDescription = description; - this.OnPropertyChanged( DataGridItemPropertyBase.ForeignKeyDescriptionPropertyName ); - } - } - - private DataGridForeignKeyDescription m_foreignKeyDescription; // = null; - - #endregion - - #region GroupSortStatResultPropertyName Property - - public string GroupSortStatResultPropertyName - { - get - { - return m_groupSortStatResultPropertyName; - } - set - { - if( value == m_groupSortStatResultPropertyName ) - return; - - m_groupSortStatResultPropertyName = value; - - this.OnPropertyChanged( DataGridItemPropertyBase.GroupSortStatResultPropertyNamePropertyName ); - } - } - - private string m_groupSortStatResultPropertyName; - - #endregion - - #region GroupSortStatResultComparer Property - - public IComparer GroupSortStatResultComparer - { - get; - set; - } - - #endregion - - #region IsDisplayable Property - - public bool IsDisplayable - { - get - { - return m_flags[ DataGridItemPropertyBaseFlags.IsDisplayable ]; - } - set - { - if( this.IsSealed ) - throw new InvalidOperationException( "An attempt was made to change the IsDisplayable property of a DataGridItemProperty already added to a containing collection." ); - - this.SetIsDisplayable( value ); - } - } - - internal void SetIsDisplayable( bool value ) - { - m_flags[ DataGridItemPropertyBaseFlags.IsDisplayable ] = value; - } - - #endregion - - #region ItemProperties Property - - public DataGridItemPropertyCollection ItemProperties - { - get - { - if( m_itemProperties == null ) - { - Interlocked.CompareExchange( ref m_itemProperties, new DataGridItemPropertyCollection( this ), null ); - Debug.Assert( m_itemProperties != null ); - - this.OnPropertyChanged( DataGridItemPropertyBase.ItemPropertiesInternalPropertyName ); - } - - return m_itemProperties; - } - } - - internal DataGridItemPropertyCollection ItemPropertiesInternal - { - get - { - return m_itemProperties; - } - } - - private DataGridItemPropertyCollection m_itemProperties; - - #endregion - - #region FieldName Internal Property - - internal virtual string FieldName - { - get - { - return this.Name; - } - } - - #endregion - - #region IsNameSealed Internal Property - - internal bool IsNameSealed - { - get - { - return m_flags[ DataGridItemPropertyBaseFlags.IsNameSealed ]; - } - set - { - if( value == this.IsNameSealed ) - return; - - m_flags[ DataGridItemPropertyBaseFlags.IsNameSealed ] = value; - - this.OnPropertyChanged( DataGridItemPropertyBase.IsNameSealedPropertyName ); - } - } - - #endregion - - #region IsSealed Internal Property - - internal bool IsSealed - { - get - { - return m_flags[ DataGridItemPropertyBaseFlags.IsSealed ]; - } - set - { - if( value == this.IsSealed ) - return; - - m_flags[ DataGridItemPropertyBaseFlags.IsSealed ] = value; - - this.OnPropertyChanged( DataGridItemPropertyBase.IsSealedPropertyName ); - } - } - - #endregion - - #region IsBrowsable Internal Property - - // That property only indicates for the DefaultProperties generated if the property should take place in the real property list by default. - internal bool IsBrowsable - { - get - { - return m_flags[ DataGridItemPropertyBaseFlags.IsBrowsable ]; - } - set - { - m_flags[ DataGridItemPropertyBaseFlags.IsBrowsable ] = value; - } - } - - #endregion - - #region IsASubRelationship Internal Property - - internal bool IsASubRelationship - { - get - { - if( m_flags[ DataGridItemPropertyBaseFlags.IsASubRelationshipSet ] ) - return m_flags[ DataGridItemPropertyBaseFlags.IsASubRelationship ]; - - if( m_dataType == null ) - return false; - - bool isASubRelationship = ItemsSourceHelper.IsASubRelationship( m_dataType ); - - if( this.IsSealed ) - { - m_flags[ DataGridItemPropertyBaseFlags.IsASubRelationship ] = isASubRelationship; - m_flags[ DataGridItemPropertyBaseFlags.IsASubRelationshipSet ] = true; - } - - return isASubRelationship; - } - } - - private void SetIsASubRelationship( Nullable isASubRelationship ) - { - if( isASubRelationship.HasValue ) - { - m_flags[ DataGridItemPropertyBaseFlags.IsASubRelationship ] = isASubRelationship.Value; - m_flags[ DataGridItemPropertyBaseFlags.IsASubRelationshipSet ] = true; - } - else - { - m_flags[ DataGridItemPropertyBaseFlags.IsASubRelationshipSet - | DataGridItemPropertyBaseFlags.IsASubRelationship ] = false; - } - } - - #endregion - - #region IsSortingOnForeignKeyDescription Internal Property - - internal bool IsSortingOnForeignKeyDescription - { - get; - set; - } - - #endregion - - #region ContainingCollection Internal Property - - internal DataGridItemPropertyCollection ContainingCollection - { - get - { - return m_containingCollection; - } - private set - { - if( value == m_containingCollection ) - return; - - if( ( value != null ) && ( m_containingCollection != null ) ) - throw new InvalidOperationException( "The property is already assigned to a DataGridItemPropertyCollection." ); - - m_containingCollection = value; - - this.OnPropertyChanged( DataGridItemPropertyBase.ContainingCollectionPropertyName ); - } - } - - private DataGridItemPropertyCollection m_containingCollection; //null - - #endregion - - #region ValueChanged Internal Event - - internal event EventHandler ValueChanged; - - private void OnValueChanged( ValueChangedEventArgs e ) - { - var handler = this.ValueChanged; - if( handler == null ) - return; - - handler.Invoke( this, e ); - } - - #endregion - - #region DistinctValueSelector Event - - public event EventHandler QueryDistinctValue - { - add - { - m_queryDistinctValue = ( EventHandler )Delegate.Combine( m_queryDistinctValue, value ); - } - remove - { - m_queryDistinctValue = ( EventHandler )Delegate.Remove( m_queryDistinctValue, value ); - } - } - - private EventHandler m_queryDistinctValue; - - internal object GetDistinctValueFromItem( object dataSourceValue ) - { - if( m_queryDistinctValue == null ) - return dataSourceValue; - - QueryDistinctValueEventArgs args = new QueryDistinctValueEventArgs( dataSourceValue ); - - m_queryDistinctValue( this, args ); - - return args.DistinctValue; - } - - #endregion - - public object GetValue( object component ) - { - var unboundDataItem = component as UnboundDataItem; - if( unboundDataItem != null ) - { - component = unboundDataItem.DataItem; - } - - // Since EmptyDataItemSafePropertyDescriptor ensures to return null to avoid Binding exceptions when a CollectionView other - // than the DataGridCollectionView is used, we must return null to avoid calling GetValueCore using null as component. - if( ( component == null ) || ( component is EmptyDataItem ) ) - return null; - - return this.GetValueCore( component ); - } - - public void SetValue( object component, object value ) - { - var unboundDataItem = component as UnboundDataItem; - if( unboundDataItem != null ) - { - component = unboundDataItem.DataItem; - } - - if( component == null ) - throw new InvalidOperationException( "An attempt was made to set a value on a null data item." ); - - if( component is EmptyDataItem ) - throw new InvalidOperationException( "An attempt was made to set a value on an empty data item." ); - - if( this.IsReadOnly && !this.OverrideReadOnlyForInsertion.GetValueOrDefault( false ) ) - throw new InvalidOperationException( "An attempt was made to set a read-only property." ); - - this.SetValueCore( component, value ); - } - - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - [Obsolete( "The ICloneable interface is no longer supported.", true )] - public virtual object Clone() - { - throw new NotSupportedException(); - } - - protected abstract object GetValueCore( object component ); - - protected virtual void SetValueCore( object component, object value ) - { - this.OnValueChanged( new ValueChangedEventArgs( component ) ); - } - - internal PropertyDescriptorFromItemPropertyBase GetPropertyDescriptorForBinding() - { - if( m_propertyDescriptorFromItemProperty == null ) - { - m_propertyDescriptorFromItemProperty = this.GetPropertyDescriptorForBindingCore(); - } - - return m_propertyDescriptorFromItemProperty; - } - - internal virtual PropertyDescriptorFromItemPropertyBase GetPropertyDescriptorForBindingCore() - { - return new PropertyDescriptorFromItemPropertyBase( this ); - } - - internal virtual void SetUnspecifiedPropertiesValues( PropertyDescription description, Type itemType, bool defaultItemPropertiesCreated ) - { - } - - internal void AttachToContainingCollection( DataGridItemPropertyCollection collection ) - { - if( collection == null ) - throw new ArgumentNullException( "collection" ); - - this.ContainingCollection = collection; - } - - internal void DetachFromContainingCollection() - { - this.ContainingCollection = null; - } - - #region INotifyPropertyChanged Members - - public event PropertyChangedEventHandler PropertyChanged; - - private void OnPropertyChanged( string propertyName ) - { - var handler = this.PropertyChanged; - if( handler == null ) - return; - - handler.Invoke( this, new PropertyChangedEventArgs( propertyName ) ); - } - - #endregion - - private PropertyDescriptorFromItemPropertyBase m_propertyDescriptorFromItemProperty; - private BitFlags m_flags; - - #region ValueChangedEventArgs Internal Class - - internal class ValueChangedEventArgs : EventArgs - { - public ValueChangedEventArgs( object component ) - { - this.Component = component; - } - - public object Component - { - get; - private set; - } - } - - #endregion - - #region BitFlags Private Struct - - private struct BitFlags - { - internal bool this[ DataGridItemPropertyBaseFlags flag ] - { - get - { - return ( ( m_data & flag ) == flag ); - } - set - { - this.CheckIfIsDefined( flag ); - - if( value ) - { - m_data |= flag; - } - else - { - m_data &= ~flag; - } - } - } - - [Conditional( "DEBUG" )] - private void CheckIfIsDefined( DataGridItemPropertyBaseFlags value ) - { - if( Enum.IsDefined( typeof( DataGridItemPropertyBaseFlags ), value ) ) - return; - - int flags = Convert.ToInt32( value ); - foreach( var flag in Enum.GetValues( typeof( DataGridItemPropertyBaseFlags ) ) ) - { - int flagValue = Convert.ToInt32( flag ); - if( ( flags & flagValue ) == flagValue ) - { - flags &= ~flagValue; - - if( flags == 0 ) - break; - } - } - - Debug.Assert( flags == 0 ); - } - - private DataGridItemPropertyBaseFlags m_data; - } - - #endregion - - #region DataGridItemPropertyBaseFlags Private Enum - - [Flags] - private enum DataGridItemPropertyBaseFlags : ushort - { - IsReadOnly = 0x0001, - IsOverrideReadOnlyForInsertionSet = 0x0002, - IsOverrideReadOnlyForInsertion = 0x0004, - IsASubRelationshipSet = 0x0008, - IsASubRelationship = 0x0010, - CalculateDistinctValues = 0x0020, - IsCalculateDistinctValuesInitialized = 0x0040, - IsNameSealed = 0x0080, - IsSealed = 0x0100, - IsBrowsable = 0x0200, - IsDisplayable = 0x0400, - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemPropertyCollection.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemPropertyCollection.cs deleted file mode 100644 index 16793294..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemPropertyCollection.cs +++ /dev/null @@ -1,978 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Diagnostics; -using System.Linq; -using System.Threading; -using Xceed.Utils.Wpf; -using Xceed.Wpf.DataGrid.Utils; - -namespace Xceed.Wpf.DataGrid -{ - [DebuggerDisplay( "Count = {Count}" )] - public sealed class DataGridItemPropertyCollection : - IList, - IList, - ICollection, - ICollection, - IEnumerable, - IEnumerable, - INotifyCollectionChanged, - INotifyPropertyChanged - { - #region Static Fields - - private static readonly string CountPropertyName = PropertyHelper.GetPropertyName( ( DataGridItemPropertyCollection c ) => c.Count ); - private static readonly string ItemsPropertyName = "Item[]"; - - #endregion - - internal DataGridItemPropertyCollection() - : this( null ) - { - } - - internal DataGridItemPropertyCollection( DataGridItemPropertyBase owner ) - { - m_owner = owner; - } - - #region [] Property - - public DataGridItemPropertyBase this[ string name ] - { - get - { - if( !string.IsNullOrEmpty( name ) ) - { - DataGridItemPropertyBase item; - if( m_nameToItem.TryGetValue( name, out item ) ) - return item; - } - - return null; - } - set - { - if( value == null ) - throw new ArgumentNullException( "value" ); - - if( string.IsNullOrEmpty( value.Name ) ) - throw new ArgumentException( "An attempt was made to add an item that does not have a name.", "value" ); - - if( value.Name != name ) - throw new ArgumentException( "The item's name is not the same as the parameter.", "name" ); - - var oldItem = this[ name ]; - if( oldItem == null ) - { - this.InsertItemAndNotify( m_collection.Count, value ); - } - else - { - if( value == oldItem ) - return; - - var index = this.IndexOf( oldItem ); - Debug.Assert( index >= 0 ); - - this.ReplaceItemAndNotify( index, oldItem, value ); - } - } - } - - #endregion - - #region DataGridItemPropertyBase Internal Owner - - internal DataGridItemPropertyBase Owner - { - get - { - return m_owner; - } - } - - private readonly DataGridItemPropertyBase m_owner; - - #endregion - - #region SyncRoot Private Property - - private object SyncRoot - { - get - { - return ( ( ICollection )this ).SyncRoot; - } - } - - #endregion - - #region ItemPropertyGroupSortStatNameChanged Internal Event - - internal event EventHandler ItemPropertyGroupSortStatNameChanged; - - private void OnItemPropertyGroupSortStatNameChanged() - { - var handler = this.ItemPropertyGroupSortStatNameChanged; - if( handler == null ) - return; - - handler.Invoke( this, EventArgs.Empty ); - } - - #endregion - - #region InitializeItemProperty Internal Event - - internal event EventHandler InitializeItemProperty; - - private void OnInitializeItemProperty( DataGridItemPropertyBase itemProperty ) - { - var handler = this.InitializeItemProperty; - if( handler == null ) - return; - - handler.Invoke( this, new InitializeItemPropertyEventArgs( itemProperty ) ); - } - - private void RelayInitializeItemProperty( InitializeItemPropertyEventArgs e ) - { - var handler = this.InitializeItemProperty; - if( handler == null ) - return; - - Debug.Assert( e != null ); - - handler.Invoke( this, e ); - } - - #endregion - - internal IDisposable DeferCollectionChanged() - { - return new DeferredDisposable( new DeferState( this ) ); - } - - internal bool Contains( string name ) - { - if( string.IsNullOrEmpty( name ) ) - return false; - - return m_nameToItem.ContainsKey( name ); - } - - internal DataGridItemPropertyBase GetForSynonym( string name ) - { - if( string.IsNullOrEmpty( name ) ) - return null; - - DataGridItemPropertyBase[] synonyms; - if( !m_synonymToItem.TryGetValue( name, out synonyms ) ) - return null; - - Debug.Assert( synonyms.Length > 0 ); - if( synonyms.Length <= 0 ) - return null; - - return synonyms[ 0 ]; - } - - internal void RefreshUnboundItemProperty( object component ) - { - if( m_unboundItems.Count <= 0 || ( component == null ) ) - return; - - var unboundDataItem = UnboundDataItem.GetUnboundDataItem( component ); - if( unboundDataItem == null ) - return; - - var dataItem = unboundDataItem.DataItem; - if( ( dataItem == null ) || ( dataItem is EmptyDataItem ) ) - return; - - State state; - if( m_dataItems.TryGetValue( dataItem, out state ) && ( state.Refreshing || state.Suspended ) ) - return; - - m_dataItems.Add( dataItem, new State( true, false ) ); - - try - { - foreach( var item in m_unboundItems ) - { - item.Refresh( unboundDataItem ); - } - } - finally - { - state = m_dataItems[ dataItem ]; - - if( state.Suspended ) - { - m_dataItems[ dataItem ] = new State( false, true ); - } - else - { - m_dataItems.Remove( dataItem ); - } - } - } - - internal void SuspendUnboundItemPropertyChanged( object component ) - { - if( component == null ) - return; - - var unboundDataItem = UnboundDataItem.GetUnboundDataItem( component ); - if( unboundDataItem == null ) - return; - - var dataItem = unboundDataItem.DataItem; - if( ( dataItem == null ) || ( dataItem is EmptyDataItem ) ) - return; - - State state; - bool refreshing = false; - - if( m_dataItems.TryGetValue( dataItem, out state ) ) - { - if( state.Suspended ) - return; - - refreshing = state.Refreshing; - } - - m_dataItems[ dataItem ] = new State( refreshing, true ); - } - - internal void ResumeUnboundItemPropertyChanged( object component ) - { - if( component == null ) - return; - - var unboundDataItem = UnboundDataItem.GetUnboundDataItem( component ); - if( unboundDataItem == null ) - return; - - var dataItem = unboundDataItem.DataItem; - if( ( dataItem == null ) || ( dataItem is EmptyDataItem ) ) - return; - - State state; - if( !m_dataItems.TryGetValue( dataItem, out state ) || !state.Suspended ) - { - Debug.Fail( "The item is not suspended." ); - return; - } - - if( state.Refreshing ) - { - m_dataItems[ dataItem ] = new State( true, false ); - } - else - { - m_dataItems.Remove( dataItem ); - - this.RefreshUnboundItemProperty( dataItem ); - } - } - - private static NotifyCollectionChangedEventArgs Combine( NotifyCollectionChangedEventArgs x, NotifyCollectionChangedEventArgs y ) - { - if( x == null ) - return y; - - if( y == null ) - return x; - - var addedItems = DataGridItemPropertyCollection.GetAddedItems( x ).ToList(); - var removedItems = DataGridItemPropertyCollection.GetRemovedItems( x ).ToList(); - - foreach( var item in DataGridItemPropertyCollection.GetAddedItems( y ) ) - { - if( !removedItems.Remove( item ) ) - { - Debug.Assert( !addedItems.Contains( item ) ); - addedItems.Add( item ); - } - } - - foreach( var item in DataGridItemPropertyCollection.GetRemovedItems( y ) ) - { - if( !addedItems.Remove( item ) ) - { - Debug.Assert( !removedItems.Contains( item ) ); - removedItems.Add( item ); - } - } - - var addedItemsCount = addedItems.Count; - var removedItemsCount = removedItems.Count; - - if( ( addedItemsCount > 0 ) && ( removedItemsCount > 0 ) ) - { - if( ( x.Action != NotifyCollectionChangedAction.Replace ) || ( y.Action != NotifyCollectionChangedAction.Replace ) || ( addedItemsCount != removedItemsCount ) ) - throw new NotSupportedException(); - - return new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Replace, addedItems, removedItems ); - } - - if( addedItemsCount > 0 ) - return new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Add, addedItems ); - - if( removedItemsCount > 0 ) - return new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Remove, removedItems ); - - return null; - } - - private static IEnumerable GetAddedItems( NotifyCollectionChangedEventArgs source ) - { - if( ( source != null ) && ( source.NewItems != null ) ) - return source.NewItems.Cast(); - - return Enumerable.Empty(); - } - - private static IEnumerable GetRemovedItems( NotifyCollectionChangedEventArgs source ) - { - if( ( source != null ) && ( source.OldItems != null ) ) - return source.OldItems.Cast(); - - return Enumerable.Empty(); - } - - private void InsertItemAndNotify( int index, DataGridItemPropertyBase item ) - { - this.InsertItem( index, item ); - - this.OnPropertyChanged( DataGridItemPropertyCollection.CountPropertyName ); - this.OnPropertyChanged( DataGridItemPropertyCollection.ItemsPropertyName ); - this.OnCollectionChanged( new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Add, item, index ) ); - } - - private void ReplaceItemAndNotify( int index, DataGridItemPropertyBase oldItem, DataGridItemPropertyBase newItem ) - { - this.RemoveItem( index, oldItem ); - this.InsertItem( index, newItem ); - - this.OnPropertyChanged( DataGridItemPropertyCollection.ItemsPropertyName ); - this.OnCollectionChanged( new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Replace, newItem, oldItem, index ) ); - } - - private void RemoveItemAndNotify( int index, DataGridItemPropertyBase item ) - { - this.RemoveItem( index, item ); - - this.OnPropertyChanged( DataGridItemPropertyCollection.CountPropertyName ); - this.OnPropertyChanged( DataGridItemPropertyCollection.ItemsPropertyName ); - this.OnCollectionChanged( new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Remove, item, index ) ); - } - - private void InsertItem( int index, DataGridItemPropertyBase item ) - { - Debug.Assert( ( index >= 0 ) && ( index <= m_collection.Count ) ); - Debug.Assert( item != null ); - Debug.Assert( !string.IsNullOrEmpty( item.Name ) ); - - var name = item.Name; - if( m_nameToItem.ContainsKey( name ) ) - throw new InvalidOperationException( "An item with the same name is already in the collection." ); - - if( item.ContainingCollection != null ) - throw new InvalidOperationException( "The item is already contained in a collection." ); - - item.IsNameSealed = true; - - m_collection.Insert( index, item ); - m_nameToItem.Add( name, item ); - - var unboundItem = item as DataGridUnboundItemProperty; - if( unboundItem != null ) - { - m_unboundItems.Add( unboundItem ); - } - - item.AttachToContainingCollection( this ); - - this.OnInitializeItemProperty( item ); - this.RegisterEvents( item ); - - item.IsSealed = true; - } - - private void RemoveItem( int index, DataGridItemPropertyBase item ) - { - Debug.Assert( ( index >= 0 ) && ( index < m_collection.Count ) ); - Debug.Assert( item != null ); - Debug.Assert( object.ReferenceEquals( item, m_collection[ index ] ) ); - - this.UnregisterEvents( item ); - - m_collection.RemoveAt( index ); - m_nameToItem.Remove( item.Name ); - - var unboundItem = item as DataGridUnboundItemProperty; - if( unboundItem != null ) - { - m_unboundItems.Remove( unboundItem ); - } - - this.RemoveSynonym( item ); - this.ClearItem( item ); - } - - private void AddSynonym( DataGridItemPropertyBase item ) - { - Debug.Assert( item != null ); - - var synonym = item.Synonym; - if( string.IsNullOrEmpty( synonym ) ) - return; - - DataGridItemPropertyBase[] synonyms; - if( m_synonymToItem.TryGetValue( synonym, out synonyms ) ) - { - Array.Resize( ref synonyms, synonyms.Length + 1 ); - } - else - { - Array.Resize( ref synonyms, 1 ); - } - - synonyms[ synonyms.Length - 1 ] = item; - m_synonymToItem[ synonym ] = synonyms; - } - - private void RemoveSynonym( DataGridItemPropertyBase item ) - { - Debug.Assert( item != null ); - - var synonym = item.Synonym; - if( string.IsNullOrEmpty( synonym ) ) - return; - - DataGridItemPropertyBase[] synonyms; - if( !m_synonymToItem.TryGetValue( synonym, out synonyms ) ) - return; - - var removeAt = Array.IndexOf( synonyms, item ); - Debug.Assert( removeAt >= 0 ); - - if( removeAt < 0 ) - return; - - if( synonyms.Length > 1 ) - { - for( int i = removeAt + 1; i < synonyms.Length; i++ ) - { - synonyms[ i - 1 ] = synonyms[ i ]; - } - - Array.Resize( ref synonyms, synonyms.Length - 1 ); - - m_synonymToItem[ synonym ] = synonyms; - } - else - { - m_synonymToItem.Remove( synonym ); - } - } - - private void ClearItem( DataGridItemPropertyBase item ) - { - Debug.Assert( item != null ); - - item.IsNameSealed = false; - item.IsSealed = false; - item.DetachFromContainingCollection(); - } - - private void RegisterEvents( DataGridItemPropertyBase item ) - { - Debug.Assert( item != null ); - - item.PropertyChanged += new PropertyChangedEventHandler( this.OnItemPropertyChanged ); - item.ValueChanged += new EventHandler( this.OnItemValueChanged ); - - if( item.ItemPropertiesInternal != null ) - { - item.ItemPropertiesInternal.InitializeItemProperty += new EventHandler( this.OnItemInitializeItemProperty ); - } - } - - private void UnregisterEvents( DataGridItemPropertyBase item ) - { - Debug.Assert( item != null ); - - item.PropertyChanged -= new PropertyChangedEventHandler( this.OnItemPropertyChanged ); - item.ValueChanged -= new EventHandler( this.OnItemValueChanged ); - - if( item.ItemPropertiesInternal != null ) - { - item.ItemPropertiesInternal.InitializeItemProperty -= new EventHandler( this.OnItemInitializeItemProperty ); - } - } - - private void OnItemPropertyChanged( object sender, PropertyChangedEventArgs e ) - { - var item = ( DataGridItemPropertyBase )sender; - var propertyName = e.PropertyName; - - if( string.IsNullOrEmpty( e.PropertyName ) || ( propertyName == DataGridItemPropertyBase.GroupSortStatResultPropertyNamePropertyName ) ) - { - this.OnItemPropertyGroupSortStatNameChanged(); - } - - if( string.IsNullOrEmpty( e.PropertyName ) || ( propertyName == DataGridItemPropertyBase.ItemPropertiesInternalPropertyName ) ) - { - this.OnItemItemPropertiesInternalChanged( ( DataGridItemPropertyBase )sender ); - } - - if( string.IsNullOrEmpty( e.PropertyName ) || ( propertyName == DataGridItemPropertyBase.IsSealedPropertyName ) ) - { - if( item.IsSealed ) - { - this.AddSynonym( item ); - } - else - { - this.RemoveSynonym( item ); - } - } - } - - private void OnItemValueChanged( object sender, DataGridItemPropertyBase.ValueChangedEventArgs e ) - { - this.RefreshUnboundItemProperty( e.Component ); - } - - private void OnItemItemPropertiesInternalChanged( DataGridItemPropertyBase itemProperty ) - { - if( ( itemProperty == null ) || ( itemProperty.ItemPropertiesInternal == null ) ) - return; - - itemProperty.ItemPropertiesInternal.InitializeItemProperty += new EventHandler( this.OnItemInitializeItemProperty ); - } - - private void OnItemInitializeItemProperty( object sender, InitializeItemPropertyEventArgs e ) - { - var itemProperties = sender as DataGridItemPropertyCollection; - if( itemProperties == null ) - return; - - this.RelayInitializeItemProperty( e ); - } - - #region IList<> Members - - public DataGridItemPropertyBase this[ int index ] - { - get - { - if( ( index < 0 ) || ( index >= m_collection.Count ) ) - throw new ArgumentOutOfRangeException( "index" ); - - return m_collection[ index ]; - } - set - { - if( ( index < 0 ) || ( index > m_collection.Count ) ) - throw new ArgumentOutOfRangeException( "index" ); - - if( value == null ) - throw new ArgumentNullException( "value" ); - - if( string.IsNullOrEmpty( value.Name ) ) - throw new ArgumentException( "The item must have a non empty name.", "value" ); - - if( index < m_collection.Count ) - { - var oldItem = m_collection[ index ]; - if( value == oldItem ) - return; - - this.ReplaceItemAndNotify( index, oldItem, value ); - } - else - { - this.InsertItemAndNotify( index, value ); - } - } - } - - public int IndexOf( DataGridItemPropertyBase item ) - { - if( !this.Contains( item ) ) - return -1; - - return m_collection.IndexOf( item ); - } - - public void Insert( int index, DataGridItemPropertyBase item ) - { - if( ( index < 0 ) || ( index > m_collection.Count ) ) - throw new ArgumentOutOfRangeException( "index" ); - - if( item == null ) - throw new ArgumentNullException( "item" ); - - if( string.IsNullOrEmpty( item.Name ) ) - throw new ArgumentException( "The item must have a non empty name.", "item" ); - - this.InsertItemAndNotify( index, item ); - } - - public void RemoveAt( int index ) - { - if( ( index < 0 ) || ( index >= m_collection.Count ) ) - throw new ArgumentOutOfRangeException( "index" ); - - this.RemoveItemAndNotify( index, m_collection[ index ] ); - } - - #endregion - - #region IList Members - - bool IList.IsFixedSize - { - get - { - return false; - } - } - - bool IList.IsReadOnly - { - get - { - return ( ( ICollection )this ).IsReadOnly; - } - } - - object IList.this[ int index ] - { - get - { - return this[ index ]; - } - set - { - this[ index ] = ( DataGridItemPropertyBase )value; - } - } - - int IList.Add( object value ) - { - var item = value as DataGridItemPropertyBase; - if( item == null ) - return -1; - - this.Add( item ); - - return m_collection.Count - 1; - } - - bool IList.Contains( object value ) - { - return this.Contains( value as DataGridItemPropertyBase ); - } - - int IList.IndexOf( object value ) - { - var item = value as DataGridItemPropertyBase; - if( !this.Contains( item ) ) - return -1; - - return m_collection.IndexOf( item ); - } - - void IList.Insert( int index, object value ) - { - this.Insert( index, ( DataGridItemPropertyBase )value ); - } - - void IList.Remove( object value ) - { - this.Remove( value as DataGridItemPropertyBase ); - } - - void IList.RemoveAt( int index ) - { - this.RemoveAt( index ); - } - - #endregion - - #region ICollection<> Members - - bool ICollection.IsReadOnly - { - get - { - return false; - } - } - - public void Add( DataGridItemPropertyBase item ) - { - this.Insert( m_collection.Count, item ); - } - - public void Clear() - { - if( m_collection.Count == 0 ) - return; - - var removedItems = m_collection.ToList(); - - m_collection.Clear(); - m_nameToItem.Clear(); - m_synonymToItem.Clear(); - m_unboundItems.Clear(); - - foreach( var item in removedItems ) - { - this.UnregisterEvents( item ); - this.ClearItem( item ); - } - - this.OnPropertyChanged( DataGridItemPropertyCollection.CountPropertyName ); - this.OnPropertyChanged( DataGridItemPropertyCollection.ItemsPropertyName ); - this.OnCollectionChanged( new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Remove, removedItems ) ); - } - - public bool Contains( DataGridItemPropertyBase item ) - { - if( item == null ) - return false; - - var name = item.Name; - if( string.IsNullOrEmpty( name ) ) - return false; - - DataGridItemPropertyBase stored; - if( !m_nameToItem.TryGetValue( name, out stored ) ) - return false; - - return ( item == stored ); - } - - void ICollection.CopyTo( DataGridItemPropertyBase[] array, int index ) - { - m_collection.CopyTo( array, index ); - } - - public bool Remove( DataGridItemPropertyBase item ) - { - if( !this.Contains( item ) ) - return false; - - var index = m_collection.IndexOf( item ); - Debug.Assert( index >= 0 ); - - this.RemoveItemAndNotify( index, item ); - - return true; - } - - #endregion - - #region ICollection Members - - public int Count - { - get - { - return m_collection.Count; - } - } - - bool ICollection.IsSynchronized - { - get - { - return false; - } - } - - object ICollection.SyncRoot - { - get - { - return ( ( ICollection )m_collection ).SyncRoot; - } - } - - void ICollection.CopyTo( Array array, int index ) - { - ( ( ICollection )m_collection ).CopyTo( array, index ); - } - - #endregion - - #region IEnumerable<> Members - - public IEnumerator GetEnumerator() - { - return m_collection.GetEnumerator(); - } - - #endregion - - #region IEnumerable Members - - IEnumerator IEnumerable.GetEnumerator() - { - return this.GetEnumerator(); - } - - #endregion - - #region INotifyCollectionChanged Members - - public event NotifyCollectionChangedEventHandler CollectionChanged; - - private void OnCollectionChanged( NotifyCollectionChangedEventArgs e ) - { - if( e.Action == NotifyCollectionChangedAction.Reset ) - throw new NotSupportedException(); - - var handler = this.CollectionChanged; - if( handler == null ) - return; - - lock( this.SyncRoot ) - { - if( m_deferCollectionChangedCount != 0 ) - { - m_deferCollectionChangedEventArgs = DataGridItemPropertyCollection.Combine( m_deferCollectionChangedEventArgs, e ); - return; - } - } - - handler.Invoke( this, e ); - } - - #endregion - - #region INotifyPropertyChanged Members - - public event PropertyChangedEventHandler PropertyChanged; - - private void OnPropertyChanged( string propertyName ) - { - var handler = this.PropertyChanged; - if( handler == null ) - return; - - handler.Invoke( this, new PropertyChangedEventArgs( propertyName ) ); - } - - #endregion - - private int m_deferCollectionChangedCount; //0 - private NotifyCollectionChangedEventArgs m_deferCollectionChangedEventArgs; //null - - private readonly List m_collection = new List(); - private readonly Dictionary m_nameToItem = new Dictionary(); - private readonly Dictionary m_synonymToItem = new Dictionary(); - private readonly HashSet m_unboundItems = new HashSet(); - private readonly Dictionary m_dataItems = new Dictionary( 0 ); - - #region DeferState Private Class - - private sealed class DeferState : DeferredDisposableState - { - internal DeferState( DataGridItemPropertyCollection target ) - { - Debug.Assert( target != null ); - m_target = target; - } - - protected override object SyncRoot - { - get - { - return m_target.SyncRoot; - } - } - - protected override bool IsDeferred - { - get - { - return ( m_target.m_deferCollectionChangedCount != 0 ); - } - } - - protected override void Increment() - { - m_target.m_deferCollectionChangedCount++; - } - - protected override void Decrement() - { - m_target.m_deferCollectionChangedCount--; - } - - protected override void OnDeferEnding( bool disposing ) - { - m_eventArgs = m_target.m_deferCollectionChangedEventArgs; - m_target.m_deferCollectionChangedEventArgs = null; - - base.OnDeferEnding( disposing ); - } - - protected override void OnDeferEnded( bool disposing ) - { - if( m_eventArgs == null ) - return; - - m_target.OnCollectionChanged( m_eventArgs ); - } - - private readonly DataGridItemPropertyCollection m_target; - private NotifyCollectionChangedEventArgs m_eventArgs; - } - - #endregion - - #region State Private Struct - - private struct State - { - internal State( bool refreshing, bool suspended ) - { - this.Refreshing = refreshing; - this.Suspended = suspended; - } - - internal readonly bool Refreshing; - internal readonly bool Suspended; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemPropertyCommittingValue.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemPropertyCommittingValue.cs deleted file mode 100644 index 03dfb914..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemPropertyCommittingValue.cs +++ /dev/null @@ -1,35 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - public class DataGridItemPropertyCommittingValueEventArgs : EventArgs - { - public DataGridItemPropertyCommittingValueEventArgs( object item, object value ) - { - this.Item = item; - this.Value = value; - } - - public object Item { get; private set; } - public object Value { get; private set; } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemPropertyDictionary.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemPropertyDictionary.cs deleted file mode 100644 index fe93c0ff..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemPropertyDictionary.cs +++ /dev/null @@ -1,47 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Collections; -using System.Diagnostics; - -namespace Xceed.Wpf.DataGrid -{ - public class DataGridItemPropertyDictionary : Dictionary - { - internal DataGridItemPropertyDictionary() - { - } - - public object this[ string name ] - { - get - { - foreach( object item in this.Keys ) - { - DataGridItemPropertyBase dataGridItemProperty = item as DataGridItemPropertyBase; - Debug.Assert( dataGridItemProperty != null ); - - if( dataGridItemProperty.Name.Equals( name ) ) - return this[ dataGridItemProperty ]; - } - - return null; - } - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemPropertyMap.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemPropertyMap.cs deleted file mode 100644 index c6874223..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemPropertyMap.cs +++ /dev/null @@ -1,625 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Diagnostics; -using System.Linq; -using System.Windows; -using Xceed.Utils.Wpf; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class DataGridItemPropertyMap : IWeakEventListener - { - #region MasterItemProperties Property - - internal DataGridItemPropertyCollection MasterItemProperties - { - get - { - return m_masterItemProperties; - } - set - { - if( value == m_masterItemProperties ) - return; - - using( this.DeferMappingChanged() ) - { - this.UnregisterItemProperties( m_masterItemProperties ); - this.UnmapItemProperties(); - - m_masterItemProperties = value; - - this.MapItemProperties(); - this.RegisterItemProperties( m_masterItemProperties ); - } - } - } - - private DataGridItemPropertyCollection m_masterItemProperties; - - #endregion - - #region DetailItemProperties Property - - internal DataGridItemPropertyCollection DetailItemProperties - { - get - { - return m_detailItemProperties; - } - set - { - if( value == m_detailItemProperties ) - return; - - using( this.DeferMappingChanged() ) - { - this.UnregisterItemProperties( m_detailItemProperties ); - this.UnmapItemProperties(); - - m_detailItemProperties = value; - - this.MapItemProperties(); - this.RegisterItemProperties( m_detailItemProperties ); - } - } - } - - private DataGridItemPropertyCollection m_detailItemProperties; - - #endregion - - #region IsMapping Property - - internal bool IsMapping - { - get - { - return ( m_masterItemProperties != null ) - && ( m_detailItemProperties != null ); - } - } - - #endregion - - #region MappingChanged Event - - internal event EventHandler MappingChanged; - - private void OnMappingChanged() - { - if( m_deferRaiseMappingChangedCount != 0 ) - { - m_raiseMappingChanged = true; - } - else - { - m_raiseMappingChanged = false; - - var handler = this.MappingChanged; - if( handler == null ) - return; - - handler.Invoke( this, EventArgs.Empty ); - } - } - - #endregion - - internal IDisposable DeferMappingChanged() - { - return new DeferredDisposable( new DeferMappingChangedEvent( this ) ); - } - - internal bool TryGetMasterItemProperty( DataGridItemPropertyBase detailItemProperty, out DataGridItemPropertyBase masterItemProperty ) - { - return DataGridItemPropertyMap.TryGetTargetItemProperty( m_detailToMaster, detailItemProperty, out masterItemProperty ); - } - - internal bool TryGetDetailItemProperty( DataGridItemPropertyBase masterItemProperty, out DataGridItemPropertyBase detailItemProperty ) - { - return DataGridItemPropertyMap.TryGetTargetItemProperty( m_masterToDetail, masterItemProperty, out detailItemProperty ); - } - - private static bool TryGetTargetItemProperty( Dictionary collection, DataGridItemPropertyBase sourceItemProperty, out DataGridItemPropertyBase targetItemProperty ) - { - if( ( collection != null ) && ( sourceItemProperty != null ) && collection.TryGetValue( sourceItemProperty, out targetItemProperty ) ) - return true; - - targetItemProperty = default( DataGridItemPropertyBase ); - - return false; - } - - private void RegisterItemProperties( DataGridItemPropertyCollection itemProperties ) - { - if( itemProperties == null ) - return; - - CollectionChangedEventManager.AddListener( itemProperties, this ); - - foreach( var itemProperty in itemProperties ) - { - this.RegisterItemProperty( itemProperty ); - } - } - - private void UnregisterItemProperties( DataGridItemPropertyCollection itemProperties ) - { - if( itemProperties == null ) - return; - - foreach( var itemProperty in itemProperties ) - { - this.UnregisterItemProperty( itemProperty ); - } - - CollectionChangedEventManager.RemoveListener( itemProperties, this ); - } - - private void RegisterItemProperty( DataGridItemPropertyBase itemProperty ) - { - if( itemProperty == null ) - return; - - if( !m_listeningToPropertyChanged.Add( itemProperty ) ) - return; - - PropertyChangedEventManager.AddListener( itemProperty, this, string.Empty ); - this.RegisterItemProperties( itemProperty.ItemPropertiesInternal ); - } - - private void UnregisterItemProperty( DataGridItemPropertyBase itemProperty ) - { - if( itemProperty == null ) - return; - - if( !m_listeningToPropertyChanged.Remove( itemProperty ) ) - return; - - this.UnregisterItemProperties( itemProperty.ItemPropertiesInternal ); - PropertyChangedEventManager.RemoveListener( itemProperty, this, string.Empty ); - } - - private void MapItemProperties() - { - this.MapItemProperties( m_masterItemProperties, m_detailItemProperties ); - } - - private void MapItemProperties( DataGridItemPropertyCollection masterItemProperties, DataGridItemPropertyCollection detailItemProperties ) - { - if( ( masterItemProperties == null ) || ( masterItemProperties.Count <= 0 ) ) - return; - - foreach( var masterItemProperty in masterItemProperties ) - { - this.MapMasterItemProperty( masterItemProperty ); - } - } - - private void MapItemProperties( DataGridItemPropertyBase masterItemProperty, DataGridItemPropertyBase detailItemProperty ) - { - if( ( masterItemProperty == null ) || ( detailItemProperty == null ) ) - return; - - DataGridItemPropertyBase mappedItemProperty; - if( m_masterToDetail.TryGetValue( masterItemProperty, out mappedItemProperty ) ) - { - if( mappedItemProperty == detailItemProperty ) - return; - - this.UnmapMasterItemProperty( masterItemProperty ); - } - - this.UnmapDetailItemProperty( detailItemProperty ); - - m_masterToDetail[ masterItemProperty ] = detailItemProperty; - m_detailToMaster[ detailItemProperty ] = masterItemProperty; - - this.OnMappingChanged(); - this.MapItemProperties( masterItemProperty.ItemPropertiesInternal, detailItemProperty.ItemPropertiesInternal ); - } - - private void MapMasterItemProperty( DataGridItemPropertyBase itemProperty ) - { - if( itemProperty == null ) - return; - - var collection = itemProperty.ContainingCollection; - if( collection == null ) - return; - - DataGridItemPropertyCollection mappedItemProperties; - DataGridItemPropertyBase mappedItemProperty; - - var owner = collection.Owner; - if( owner == null ) - { - Debug.Assert( collection == m_masterItemProperties ); - if( collection != m_masterItemProperties ) - return; - - mappedItemProperties = m_detailItemProperties; - } - else - { - if( !m_masterToDetail.TryGetValue( owner, out mappedItemProperty ) ) - return; - - mappedItemProperties = mappedItemProperty.ItemPropertiesInternal; - } - - if( mappedItemProperties == null ) - return; - - mappedItemProperty = mappedItemProperties.GetForSynonym( itemProperty.Name ); - - if( mappedItemProperty != null ) - { - this.MapItemProperties( itemProperty, mappedItemProperty ); - } - else - { - this.UnmapMasterItemProperty( itemProperty ); - } - } - - private void MapDetailItemProperty( DataGridItemPropertyBase itemProperty ) - { - if( itemProperty == null ) - return; - - var collection = itemProperty.ContainingCollection; - if( collection == null ) - return; - - DataGridItemPropertyCollection mappedItemProperties; - DataGridItemPropertyBase mappedItemProperty; - - var owner = collection.Owner; - if( owner == null ) - { - Debug.Assert( collection == m_detailItemProperties ); - if( collection != m_detailItemProperties ) - return; - - mappedItemProperties = m_masterItemProperties; - } - else - { - if( !m_detailToMaster.TryGetValue( owner, out mappedItemProperty ) ) - return; - - mappedItemProperties = mappedItemProperty.ItemPropertiesInternal; - } - - if( mappedItemProperties == null ) - return; - - mappedItemProperty = ( !string.IsNullOrEmpty( itemProperty.Synonym ) ) ? mappedItemProperties[ itemProperty.Synonym ] : null; - - if( mappedItemProperty != null ) - { - this.MapItemProperties( mappedItemProperty, itemProperty ); - } - else - { - this.UnmapDetailItemProperty( itemProperty ); - } - } - - private void UnmapItemProperties() - { - if( ( m_masterItemProperties == null ) || ( m_detailItemProperties == null ) ) - return; - - while( m_masterToDetail.Count > 0 ) - { - var entry = m_masterToDetail.First(); - - this.UnmapItemProperties( entry.Key, entry.Value, false ); - } - - Debug.Assert( m_masterToDetail.Count == 0 ); - Debug.Assert( m_detailToMaster.Count == 0 ); - - while( m_detailToMaster.Count > 0 ) - { - var entry = m_detailToMaster.First(); - - this.UnmapItemProperties( entry.Value, entry.Key, false ); - } - - m_masterToDetail.Clear(); - m_detailToMaster.Clear(); - } - - private void UnmapItemProperties( DataGridItemPropertyBase masterItemProperty, DataGridItemPropertyBase detailItemProperty, bool recursive ) - { - if( ( masterItemProperty == null ) || ( detailItemProperty == null ) ) - return; - - DataGridItemPropertyBase mappedItemProperty; - if( !m_masterToDetail.TryGetValue( masterItemProperty, out mappedItemProperty ) || ( mappedItemProperty != detailItemProperty ) ) - throw new InvalidOperationException(); - - if( !m_detailToMaster.TryGetValue( detailItemProperty, out mappedItemProperty ) || ( mappedItemProperty != masterItemProperty ) ) - throw new InvalidOperationException(); - - m_masterToDetail.Remove( masterItemProperty ); - m_detailToMaster.Remove( detailItemProperty ); - - this.OnMappingChanged(); - - if( recursive ) - { - this.UnmapMasterItemProperties( masterItemProperty.ItemPropertiesInternal ); - this.UnmapDetailItemProperties( detailItemProperty.ItemPropertiesInternal ); - } - } - - private void UnmapMasterItemProperties( DataGridItemPropertyCollection itemProperties ) - { - if( itemProperties == null ) - return; - - foreach( var itemProperty in itemProperties ) - { - this.UnmapMasterItemProperty( itemProperty ); - } - } - - private void UnmapDetailItemProperties( DataGridItemPropertyCollection itemProperties ) - { - if( itemProperties == null ) - return; - - foreach( var itemProperty in itemProperties ) - { - this.UnmapDetailItemProperty( itemProperty ); - } - } - - private void UnmapMasterItemProperty( DataGridItemPropertyBase itemProperty ) - { - if( itemProperty == null ) - return; - - DataGridItemPropertyBase mappedItemProperty; - if( !m_masterToDetail.TryGetValue( itemProperty, out mappedItemProperty ) ) - return; - - Debug.Assert( mappedItemProperty != null ); - - this.UnmapItemProperties( itemProperty, mappedItemProperty, true ); - } - - private void UnmapDetailItemProperty( DataGridItemPropertyBase itemProperty ) - { - if( itemProperty == null ) - return; - - DataGridItemPropertyBase mappedItemProperty; - if( !m_detailToMaster.TryGetValue( itemProperty, out mappedItemProperty ) ) - return; - - Debug.Assert( mappedItemProperty != null ); - - this.UnmapItemProperties( mappedItemProperty, itemProperty, true ); - } - - private void OnItemPropertyCollectionChanged( DataGridItemPropertyCollection collection, NotifyCollectionChangedEventArgs e ) - { - var rootCollection = ItemsSourceHelper.GetRootCollection( collection ); - if( rootCollection == null ) - return; - - if( rootCollection == m_masterItemProperties ) - { - if( e.Action == NotifyCollectionChangedAction.Reset ) - throw new NotSupportedException(); - - if( e.Action == NotifyCollectionChangedAction.Move ) - return; - - using( this.DeferMappingChanged() ) - { - if( e.OldItems != null ) - { - foreach( DataGridItemPropertyBase itemProperty in e.OldItems ) - { - this.UnregisterItemProperty( itemProperty ); - this.UnmapMasterItemProperty( itemProperty ); - } - } - - if( e.NewItems != null ) - { - foreach( DataGridItemPropertyBase itemProperty in e.NewItems ) - { - this.RegisterItemProperty( itemProperty ); - this.MapMasterItemProperty( itemProperty ); - } - } - } - } - else if( rootCollection == m_detailItemProperties ) - { - if( e.Action == NotifyCollectionChangedAction.Reset ) - throw new NotSupportedException(); - - if( e.Action == NotifyCollectionChangedAction.Move ) - return; - - using( this.DeferMappingChanged() ) - { - if( e.OldItems != null ) - { - foreach( DataGridItemPropertyBase itemProperty in e.OldItems ) - { - this.UnregisterItemProperty( itemProperty ); - this.UnmapDetailItemProperty( itemProperty ); - } - } - - if( e.NewItems != null ) - { - foreach( DataGridItemPropertyBase itemProperty in e.NewItems ) - { - this.RegisterItemProperty( itemProperty ); - this.MapDetailItemProperty( itemProperty ); - } - } - } - } - else - { - Debug.Fail( "The collection should have been either for the master or the detail item properties." ); - CollectionChangedEventManager.RemoveListener( collection, this ); - } - } - - private void OnItemPropertyPropertyChanged( DataGridItemPropertyBase itemProperty, PropertyChangedEventArgs e ) - { - var rootCollection = ItemsSourceHelper.GetRootCollection( itemProperty ); - if( rootCollection == null ) - return; - - using( this.DeferMappingChanged() ) - { - if( string.IsNullOrEmpty( e.PropertyName ) || ( e.PropertyName == DataGridItemPropertyBase.SynonymPropertyName ) ) - { - if( rootCollection == m_detailItemProperties ) - { - this.MapDetailItemProperty( itemProperty ); - } - } - - if( string.IsNullOrEmpty( e.PropertyName ) || ( e.PropertyName == DataGridItemPropertyBase.ItemPropertiesInternalPropertyName ) ) - { - var itemProperties = itemProperty.ItemPropertiesInternal; - if( itemProperties != null ) - { - this.UnregisterItemProperties( itemProperties ); - this.RegisterItemProperties( itemProperties ); - - if( rootCollection == m_masterItemProperties ) - { - foreach( var childItemProperty in itemProperties ) - { - this.MapMasterItemProperty( childItemProperty ); - } - } - else if( rootCollection == m_detailItemProperties ) - { - foreach( var childItemProperty in itemProperties ) - { - this.MapDetailItemProperty( childItemProperty ); - } - } - } - } - } - } - - #region IWeakEventListener Members - - bool IWeakEventListener.ReceiveWeakEvent( Type managerType, object sender, EventArgs e ) - { - if( managerType == typeof( CollectionChangedEventManager ) ) - { - this.OnItemPropertyCollectionChanged( ( DataGridItemPropertyCollection )sender, ( NotifyCollectionChangedEventArgs )e ); - } - else if( managerType == typeof( PropertyChangedEventManager ) ) - { - this.OnItemPropertyPropertyChanged( ( DataGridItemPropertyBase )sender, ( PropertyChangedEventArgs )e ); - } - else - { - return false; - } - - return true; - } - - #endregion - - private readonly Dictionary m_masterToDetail = new Dictionary(); - private readonly Dictionary m_detailToMaster = new Dictionary(); - private readonly HashSet m_listeningToPropertyChanged = new HashSet(); - private int m_deferRaiseMappingChangedCount; - private bool m_raiseMappingChanged; //false - - #region DeferMappingChangedEvent Private Class - - private sealed class DeferMappingChangedEvent : DeferredDisposableState - { - internal DeferMappingChangedEvent( DataGridItemPropertyMap target ) - { - if( target == null ) - throw new ArgumentNullException( "target" ); - - m_target = target; - } - - protected override object SyncRoot - { - get - { - return m_target.m_listeningToPropertyChanged; - } - } - - protected override bool IsDeferred - { - get - { - return ( m_target.m_deferRaiseMappingChangedCount != 0 ); - } - } - - protected override void Increment() - { - m_target.m_deferRaiseMappingChangedCount++; - } - - protected override void Decrement() - { - m_target.m_deferRaiseMappingChangedCount--; - } - - protected override void OnDeferEnded( bool disposing ) - { - if( !disposing ) - return; - - if( m_target.m_raiseMappingChanged ) - { - m_target.OnMappingChanged(); - } - } - - private readonly DataGridItemPropertyMap m_target; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemPropertyMapHelper.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemPropertyMapHelper.cs deleted file mode 100644 index 1a6e4563..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemPropertyMapHelper.cs +++ /dev/null @@ -1,118 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - - -namespace Xceed.Wpf.DataGrid -{ - internal static class DataGridItemPropertyMapHelper - { - internal static bool TryGetMasterColumnName( DataGridItemPropertyMap itemPropertyMap, string detailColumnName, out string masterColumnName ) - { - masterColumnName = default( string ); - - if( itemPropertyMap == null ) - return false; - - var detailItemProperty = ItemsSourceHelper.GetItemPropertyFromProperty( itemPropertyMap.DetailItemProperties, detailColumnName ); - if( detailItemProperty == null ) - return false; - - DataGridItemPropertyBase masterItemProperty; - if( !itemPropertyMap.TryGetMasterItemProperty( detailItemProperty, out masterItemProperty ) ) - return false; - - masterColumnName = PropertyRouteParser.Parse( masterItemProperty ); - - return !string.IsNullOrEmpty( masterColumnName ); - } - - internal static bool TryGetDetailColumnName( DataGridItemPropertyMap itemPropertyMap, string masterColumnName, out string detailColumnName ) - { - detailColumnName = default( string ); - - if( itemPropertyMap == null ) - return false; - - var masterItemProperty = ItemsSourceHelper.GetItemPropertyFromProperty( itemPropertyMap.MasterItemProperties, masterColumnName ); - if( masterItemProperty == null ) - return false; - - DataGridItemPropertyBase detailItemProperty; - if( !itemPropertyMap.TryGetDetailItemProperty( masterItemProperty, out detailItemProperty ) ) - return false; - - detailColumnName = PropertyRouteParser.Parse( detailItemProperty ); - - return !string.IsNullOrEmpty( detailColumnName ); - } - - internal static bool TryGetMasterColumn( DataGridContext detailContext, ColumnBase detailColumn, out ColumnBase masterColumn ) - { - if( detailContext != null ) - { - var masterContext = detailContext.RootDataGridContext; - if( masterContext != null ) - return DataGridItemPropertyMapHelper.TryGetMasterColumn( detailContext.ItemPropertyMap, masterContext.Columns, detailColumn, out masterColumn ); - } - - masterColumn = default( ColumnBase ); - - return false; - } - - internal static bool TryGetDetailColumn( DataGridContext detailContext, ColumnBase masterColumn, out ColumnBase detailColumn ) - { - if( detailContext != null ) - return DataGridItemPropertyMapHelper.TryGetDetailColumn( detailContext.ItemPropertyMap, detailContext.Columns, masterColumn, out detailColumn ); - - detailColumn = default( ColumnBase ); - - return false; - } - - internal static bool TryGetMasterColumn( DataGridItemPropertyMap itemPropertyMap, ColumnCollection masterColumns, ColumnBase detailColumn, out ColumnBase masterColumn ) - { - masterColumn = default( ColumnBase ); - - if( ( masterColumns == null ) || ( detailColumn == null ) ) - return false; - - string masterColumnName; - if( !DataGridItemPropertyMapHelper.TryGetMasterColumnName( itemPropertyMap, detailColumn.FieldName, out masterColumnName ) ) - return false; - - masterColumn = masterColumns[ masterColumnName ]; - - return ( masterColumn != null ); - } - - internal static bool TryGetDetailColumn( DataGridItemPropertyMap itemPropertyMap, ColumnCollection detailColumns, ColumnBase masterColumn, out ColumnBase detailColumn ) - { - detailColumn = default( ColumnBase ); - - if( ( detailColumns == null ) || ( masterColumn == null ) ) - return false; - - string detailColumnName; - if( !DataGridItemPropertyMapHelper.TryGetDetailColumnName( itemPropertyMap, masterColumn.FieldName, out detailColumnName ) ) - return false; - - detailColumn = detailColumns[ detailColumnName ]; - - return ( detailColumn != null ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemPropertyQueryValueEvent.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemPropertyQueryValueEvent.cs deleted file mode 100644 index bdd409c9..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemPropertyQueryValueEvent.cs +++ /dev/null @@ -1,34 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - public class DataGridItemPropertyQueryValueEventArgs : EventArgs - { - public DataGridItemPropertyQueryValueEventArgs( object item ) - { - this.Item = item; - } - - public object Item { get; private set; } - public object Value { get; set; } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemPropertyRoute.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemPropertyRoute.cs deleted file mode 100644 index 1e094a81..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemPropertyRoute.cs +++ /dev/null @@ -1,97 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Diagnostics; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class DataGridItemPropertyRoute - { - private DataGridItemPropertyRoute( DataGridItemPropertyBase itemProperty ) - : this( itemProperty, null ) - { - } - - private DataGridItemPropertyRoute( DataGridItemPropertyBase itemProperty, DataGridItemPropertyRoute parent ) - { - Debug.Assert( itemProperty != null ); - - m_itemProperty = itemProperty; - m_parent = parent; - } - - #region Current Property - - internal DataGridItemPropertyBase Current - { - get - { - return m_itemProperty; - } - } - - private readonly DataGridItemPropertyBase m_itemProperty; - - #endregion - - #region Parent Property - - internal DataGridItemPropertyRoute Parent - { - get - { - return m_parent; - } - } - - private readonly DataGridItemPropertyRoute m_parent; - - #endregion - - internal static DataGridItemPropertyRoute Create( DataGridItemPropertyBase itemProperty ) - { - if( itemProperty == null ) - return null; - - var collection = itemProperty.ContainingCollection; - if( collection == null ) - return new DataGridItemPropertyRoute( itemProperty ); - - return new DataGridItemPropertyRoute( - itemProperty, - DataGridItemPropertyRoute.Create( collection.Owner ) ); - } - - internal static DataGridItemPropertyRoute Combine( DataGridItemPropertyBase itemProperty, DataGridItemPropertyRoute ancestors ) - { - if( itemProperty == null ) - return ancestors; - - if( ancestors == null ) - return DataGridItemPropertyRoute.Create( itemProperty ); - - var collection = itemProperty.ContainingCollection; - if( collection == null ) - throw new InvalidOperationException(); - - if( collection.Owner != ancestors.Current ) - throw new InvalidOperationException(); - - return new DataGridItemPropertyRoute( itemProperty, ancestors ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemRemovedEvent.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemRemovedEvent.cs deleted file mode 100644 index a764a261..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridItemRemovedEvent.cs +++ /dev/null @@ -1,43 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - public class DataGridItemRemovedEventArgs : DataGridItemEventArgs - { - public DataGridItemRemovedEventArgs( DataGridCollectionViewBase collectionView, object item, int index ) - : base( collectionView, item ) - { - m_index = index; - } - - #region Index Property - - public int Index - { - get { return m_index; } - } - - private int m_index; - - #endregion Index Property - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridLINQPageManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridLINQPageManager.cs deleted file mode 100644 index 4505d0ec..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridLINQPageManager.cs +++ /dev/null @@ -1,171 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Diagnostics; - -namespace Xceed.Wpf.DataGrid -{ - internal class DataGridLINQPageManager : DataGridPageManagerBase - { - public DataGridLINQPageManager( DataGridVirtualizingQueryableCollectionView collectionView, object syncRoot, bool supportsPrimaryKeyOptimizations ) - : base( collectionView ) - { - m_supportsPrimaryKeyOptimizations = supportsPrimaryKeyOptimizations; - m_syncRoot = syncRoot; - } - - protected override void DisposeCore() - { - m_syncRoot = null; - base.DisposeCore(); - } - - protected override int OnQueryItemCountCore( VirtualList virtualList ) - { - if( !this.IsConnected ) - return 0; - - DataGridVirtualizingQueryableCollectionViewGroup collectionViewGroup = - this.GetLinkedCollectionViewGroup( virtualList ) as DataGridVirtualizingQueryableCollectionViewGroup; - - Debug.Assert( collectionViewGroup != null ); - - return collectionViewGroup.QueryItemCount(); - } - - protected internal override void OnQueryItems( VirtualPage page, AsyncQueryInfo queryInfo ) - { - base.OnQueryItems( page, queryInfo ); - - DataGridVirtualizingQueryableCollectionViewGroup collectionViewGroup = - this.GetLinkedCollectionViewGroup( page.ParentVirtualList ) as DataGridVirtualizingQueryableCollectionViewGroup; - - IQueryable queryableToUse; - - int virtualItemCount = collectionViewGroup.VirtualItemCount; - - bool queryableIsReversed; - - if( ( !m_supportsPrimaryKeyOptimizations ) || ( queryInfo.StartIndex < ( virtualItemCount / 2 ) ) ) - { - queryableIsReversed = false; - queryableToUse = collectionViewGroup.Queryable.Slice( queryInfo.StartIndex, queryInfo.RequestedItemCount ); - } - else - { - queryableIsReversed = true; - - int reversedStartIndex = virtualItemCount - ( queryInfo.StartIndex + queryInfo.RequestedItemCount ); - - queryableToUse = collectionViewGroup.ReversedQueryable.Slice( reversedStartIndex, queryInfo.RequestedItemCount ); - } - - System.Threading.ThreadPool.QueueUserWorkItem( new System.Threading.WaitCallback( this.AsyncGatherItems ), new object[] { queryInfo, queryableToUse, queryableIsReversed } ); - } - - protected internal override void OnQueryItemsCompleted( VirtualPage page, AsyncQueryInfo queryInfo, object[] fetchedItems ) - { - DataGridVirtualizingQueryableCollectionView collectionView = this.CollectionView as DataGridVirtualizingQueryableCollectionView; - - // The VirtualPageManager was Disposed - if( collectionView == null ) - return; - - using( collectionView.DeferRefresh() ) - { - base.OnQueryItemsCompleted( page, queryInfo, fetchedItems ); - } - } - - private void AsyncGatherItems( object workItem ) - { - object[] parameters = ( object[] )workItem; - - AsyncQueryInfo queryInfo = parameters[ 0 ] as AsyncQueryInfo; - - if( queryInfo.ShouldAbort ) - return; - - IQueryable queryable = ( IQueryable )parameters[ 1 ]; - int requestedItemCount = queryInfo.RequestedItemCount; - object[] items = new object[ requestedItemCount ]; - - System.Collections.IEnumerator enumerator; - - lock( m_syncRoot ) - { - // We reverify here since a reset could have been issued while we were waiting on the lock statement. - if( ( queryInfo.ShouldAbort ) || ( !this.IsConnected ) || ( this.IsDisposed ) ) - return; - - try - { - Debug.WriteLineIf( VirtualPageManager.DebugDataVirtualization, "Beginning Provider Execute for page at start index: " + queryInfo.StartIndex.ToString() ); - - enumerator = queryable.GetEnumerator(); - - Debug.WriteLineIf( VirtualPageManager.DebugDataVirtualization, "Ended Provider Execute for page at start index: " + queryInfo.StartIndex.ToString() ); - - int i = 0; - - while( enumerator.MoveNext() && ( i < requestedItemCount ) ) - { - object current = enumerator.Current; - - if( current != null ) - { - items[ i ] = enumerator.Current; - i++; - } - } - } - catch( Exception exception ) - { - // TimeOut exeception or other. - queryInfo.AbortQuery(); - queryInfo.Error = exception.Message; - return; - } - } - - items = items.Where( item => item != null ).ToArray(); - - try - { - if( items.Count() != requestedItemCount ) - throw new InvalidOperationException( "The number of non-null items returned by the source must be equal to the provided item count." ); - } - catch - { - //go silently here, in case the next sequance give a valid result. At the same time, if it does not, the dev has information when debugging. - } - - bool queryableWasReversed = ( bool )parameters[ 2 ]; - - if( queryableWasReversed ) - Array.Reverse( items ); - - queryInfo.EndQuery( items ); - } - - private object m_syncRoot; - private bool m_supportsPrimaryKeyOptimizations; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridPageManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridPageManager.cs deleted file mode 100644 index d5e1e0ea..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridPageManager.cs +++ /dev/null @@ -1,103 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Diagnostics; - -namespace Xceed.Wpf.DataGrid -{ - internal class DataGridPageManager : DataGridPageManagerBase - { - #region CONSTRUCTORS - - public DataGridPageManager( DataGridVirtualizingCollectionView collectionView ) - : base( collectionView ) - { - } - - #endregion CONSTRUCTORS - - #region DATA VIRTUALIZATION - - protected override int OnQueryItemCountCore( VirtualList virtualList ) - { - if( !this.IsConnected ) - return 0; - - DataGridVirtualizingCollectionView collectionView = this.CollectionView as DataGridVirtualizingCollectionView; - - // The VirtualPageManager was Disposed - if( collectionView == null ) - return 0; - - DataGridVirtualizingCollectionViewGroup collectionViewGroup = this.GetLinkedCollectionViewGroup( virtualList ) as DataGridVirtualizingCollectionViewGroup; - Debug.Assert( ( collectionViewGroup != null ) && ( collectionView != null ) ); - - return collectionView.OnQueryItemCount( collectionViewGroup ); - } - - protected internal override void OnQueryItems( VirtualPage page, AsyncQueryInfo queryInfo ) - { - base.OnQueryItems( page, queryInfo ); - - DataGridVirtualizingCollectionView collectionView = this.CollectionView as DataGridVirtualizingCollectionView; - - // The VirtualPageManager was Disposed - if( collectionView == null ) - return; - - DataGridVirtualizingCollectionViewGroup collectionViewGroup = this.GetLinkedCollectionViewGroup( page.ParentVirtualList ) as DataGridVirtualizingCollectionViewGroup; - - Debug.Assert( ( collectionViewGroup != null ) && ( collectionView != null ) ); - - collectionView.OnQueryItems( queryInfo, collectionViewGroup ); - } - - protected internal override void OnAbortQueryItems( VirtualPage page, AsyncQueryInfo queryInfo ) - { - DataGridVirtualizingCollectionView collectionView = this.CollectionView as DataGridVirtualizingCollectionView; - - // The VirtualPageManager was Disposed - if( collectionView == null ) - return; - - DataGridVirtualizingCollectionViewGroup collectionViewGroup = this.GetLinkedCollectionViewGroup( page.ParentVirtualList ) as DataGridVirtualizingCollectionViewGroup; - - collectionView.OnAbortQueryItems( queryInfo, collectionViewGroup ); - - base.OnAbortQueryItems( page, queryInfo ); - } - - protected internal override void OnQueryItemsCompleted( VirtualPage page, AsyncQueryInfo queryInfo, object[] fetchedItems ) - { - DataGridVirtualizingCollectionView collectionView = this.CollectionView as DataGridVirtualizingCollectionView; - - // The VirtualPageManager was Disposed - if( collectionView == null ) - return; - - using( collectionView.DeferRefresh() ) - { - base.OnQueryItemsCompleted( page, queryInfo, fetchedItems ); - } - } - - #endregion DATA VIRTUALIZATION - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridPageManagerBase.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridPageManagerBase.cs deleted file mode 100644 index c00a84ab..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridPageManagerBase.cs +++ /dev/null @@ -1,584 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Diagnostics; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.Linq.Expressions; -using System.Reflection; -using System.Collections; -using System.Windows.Threading; -using System.Collections.Specialized; - -namespace Xceed.Wpf.DataGrid -{ - internal abstract class DataGridPageManagerBase : VirtualPageManager, IEnumerable, IEnumerable - { - #region STATIC MEMBERS - - private static AsyncQueryInfoWeakComparer QueryInfoWeakComparer = new AsyncQueryInfoWeakComparer(); - - #endregion STATIC MEMBERS - - public DataGridPageManagerBase( DataGridVirtualizingCollectionViewBase collectionView ) - : base( collectionView.Dispatcher, collectionView.PageSize, collectionView.MaxRealizedItemCount, collectionView.PreemptivePageQueryRatio ) - { - m_collectionView = collectionView; - m_virtualListVSCollectionViewGroupDictionary = new Dictionary(); - } - - #region CollectionView Property - - public DataGridVirtualizingCollectionViewBase CollectionView - { - get - { - return m_collectionView; - } - } - - #endregion CollectionView Property - - #region PUBLIC METHODS - - public DataGridVirtualizingCollectionViewGroupBase GetLinkedCollectionViewGroup( VirtualList virtualItemList ) - { - DataGridVirtualizingCollectionViewGroupBase collectionViewGroup; - - m_virtualListVSCollectionViewGroupDictionary.TryGetValue( virtualItemList, out collectionViewGroup ); - - return collectionViewGroup; - } - - public int GetGlobalIndexOf( object item ) - { - ReadOnlyCollection virtualItemLists = this.ManagedLists; - int virtualItemListsCount = virtualItemLists.Count; - - for( int i = 0; i < virtualItemListsCount; i++ ) - { - VirtualList localList = virtualItemLists[ i ]; - int localIndex = localList.IndexOf( item ); - - if( localIndex >= 0 ) - { - Debug.Assert( m_virtualListVSCollectionViewGroupDictionary.ContainsKey( localList ) ); - - DataGridVirtualizingCollectionViewGroupBase dgvcvg = m_virtualListVSCollectionViewGroupDictionary[ localList ]; - - return localIndex + dgvcvg.StartGlobalIndex; - } - } - - return -1; - } - - #endregion PUBLIC METHODS - - #region PROTECTED METHODS - - protected internal override void OnBuiltInAbort( VirtualPage page, AsyncQueryInfo queryInfo ) - { - // When a built-in abort occurs, we ensure to remove - // any AsyncQueryInfo from references since the ConnectionState - // use this array to update its actual state - m_asyncQueryInfosInProgress.Remove( queryInfo ); - - // In case the page query was aborted when - // VirtualPageManager.CleanUpUnused is called - if( page.RemoveAfterOperation ) - this.RemovePage( page ); - - this.UpdateConnectionState(); - } - - protected internal override void OnQueryItems( VirtualPage page, AsyncQueryInfo queryInfo ) - { - // The VirtualPageManager is not connected to the CollectionView anymore, - // do NOT query items since it will be done by the new VirtualPageManager - // assigned to the same CollectionView - if( !this.IsConnected ) - return; - - Debug.Assert( !m_asyncQueryInfosInProgress.Contains( queryInfo ) ); - m_asyncQueryInfosInProgress.Add( queryInfo ); - - if( m_asyncQueryInfosInError != null ) - { - LinkedListNode queryInfoInErrorNode = m_asyncQueryInfosInError.First; - - while( queryInfoInErrorNode != null ) - { - if( DataGridPageManagerBase.QueryInfoWeakComparer.Equals( queryInfo, queryInfoInErrorNode.Value ) ) - { - m_asyncQueryInfosInError.Remove( queryInfoInErrorNode ); - break; - } - - queryInfoInErrorNode = queryInfoInErrorNode.Next; - } - - if( m_asyncQueryInfosInError.Count == 0 ) - m_asyncQueryInfosInError = null; - } - - this.UpdateConnectionState(); - } - - protected internal override void OnQueryItemsCompleted( VirtualPage page, AsyncQueryInfo queryInfo, object[] fetchedItems ) - { - base.OnQueryItemsCompleted( page, queryInfo, fetchedItems ); - - Debug.Assert( m_asyncQueryInfosInProgress.Contains( queryInfo ) ); - m_asyncQueryInfosInProgress.Remove( queryInfo ); - - this.UpdateConnectionState(); - } - - protected internal override void OnAbortQueryItems( VirtualPage page, AsyncQueryInfo queryInfo ) - { - base.OnAbortQueryItems( page, queryInfo ); - - // It is possible that the queryInfo was removed previously - m_asyncQueryInfosInProgress.Remove( queryInfo ); - - // In case the page query was aborted when - // VirtualPageManager.CleanUpUnused is called - if( page.RemoveAfterOperation ) - this.RemovePage( page ); - - this.UpdateConnectionState(); - } - - protected internal override void OnQueryErrorChanged( VirtualPage page, AsyncQueryInfo queryInfo ) - { - base.OnQueryErrorChanged( page, queryInfo ); - - // It is possible that m_asyncQueryInfosInProgress does not contain the queryInfo when - // the query was aborted but the user did not stop the query and later on set the queryInfo error - // event if the queryInfo ShouldAbort is set to True. - Debug.Assert( ( m_asyncQueryInfosInProgress.Contains( queryInfo ) ) || ( queryInfo.ShouldAbort ) ); - - object error = queryInfo.Error; - - if( error == null ) - { - // Even if the queryInfo's ShouldAbort property is set to True, clean-up the error. - Debug.Assert( ( m_asyncQueryInfosInError != null ) && ( m_asyncQueryInfosInError.Contains( queryInfo ) ) ); - - m_asyncQueryInfosInError.Remove( queryInfo ); - - if( m_asyncQueryInfosInError.Count == 0 ) - m_asyncQueryInfosInError = null; - } - else if( !queryInfo.ShouldAbort ) - { - // Only add errors if the queryInfo's ShouldAbort property is set to False. - if( m_asyncQueryInfosInError == null ) - m_asyncQueryInfosInError = new LinkedList(); - - if( m_asyncQueryInfosInError.Contains( queryInfo ) ) - m_asyncQueryInfosInError.Remove( queryInfo ); - - m_asyncQueryInfosInError.AddFirst( queryInfo ); - } - - this.UpdateConnectionState(); - } - - protected override void OnVirtualPageManagerRestarting() - { - base.OnVirtualPageManagerRestarting(); - - // Keep a reference on the old CollectionViewGroupRoot of the - // parent CollectionView to be able to clear all references - // of this group after the VirtualPageManager is disposed - m_managerCollectionViewGroupRoot = m_collectionView.RootGroup; - } - - protected override void OnVirtualPageManagerRestarted( bool shouldRefresh ) - { - base.OnVirtualPageManagerRestarted( shouldRefresh ); - - // No need for a refresh since a new VirtualPageManager will - // be created and force QueryItemsCount and QueryItems using - // the same CollectionView - - this.TryDispose(); - } - - protected internal override void OnCommitItems( VirtualPage page, AsyncCommitInfo commitInfo ) - { - base.OnCommitItems( page, commitInfo ); - - Debug.Assert( !m_asyncCommitInfosInProgress.Contains( commitInfo ) ); - m_asyncCommitInfosInProgress.Add( commitInfo ); - - this.UpdateConnectionState(); - - Debug.WriteLineIf( VirtualPageManager.DebugDataVirtualization, "OnCommitItems for page " + page.ToString() ); - - m_collectionView.Dispatcher.BeginInvoke( - new Action( this.RaiseCollectionViewOnCommitItems ), - DispatcherPriority.Background, - page, - commitInfo ); - } - - protected internal override void OnCommitItemsCompleted( VirtualPage page, AsyncCommitInfo commitInfo ) - { - Debug.Assert( m_asyncCommitInfosInProgress.Contains( commitInfo ) ); - m_asyncCommitInfosInProgress.Remove( commitInfo ); - this.UpdateConnectionState(); - - base.OnCommitItemsCompleted( page, commitInfo ); - - // In case the page query was aborted when - // VirtualPageManager.CleanUpUnused is called - if( page.RemoveAfterOperation ) - this.RemovePage( page ); - - Debug.WriteLineIf( VirtualPageManager.DebugDataVirtualization, "OnCommitItemsCompleted for page " + page.ToString() ); - } - - protected internal override void OnCommitErrorChanged( VirtualPage page, AsyncCommitInfo commitInfo ) - { - base.OnCommitErrorChanged( page, commitInfo ); - - Debug.Assert( m_asyncCommitInfosInProgress.Contains( commitInfo ) ); - - object error = commitInfo.Error; - - if( error == null ) - { - Debug.Assert( ( m_asyncCommitInfosInError != null ) && ( m_asyncCommitInfosInError.Contains( commitInfo ) ) ); - - m_asyncCommitInfosInError.Remove( commitInfo ); - - if( m_asyncCommitInfosInError.Count == 0 ) - m_asyncCommitInfosInError = null; - } - else - { - if( m_asyncCommitInfosInError == null ) - m_asyncCommitInfosInError = new LinkedList(); - - if( m_asyncCommitInfosInError.Contains( commitInfo ) ) - m_asyncCommitInfosInError.Remove( commitInfo ); - - m_asyncCommitInfosInError.AddFirst( commitInfo ); - } - - this.UpdateConnectionState(); - } - - protected void UnlinkVirtualListAndCollectionViewGroup( VirtualList virtualList ) - { - DataGridVirtualizingCollectionViewGroupBase collectionViewGroup = null; - - if( m_virtualListVSCollectionViewGroupDictionary.TryGetValue( virtualList, out collectionViewGroup ) ) - { - CollectionChangedEventManager.RemoveListener( virtualList, collectionViewGroup ); - m_virtualListVSCollectionViewGroupDictionary.Remove( virtualList ); - } - } - - protected override void DisposeCore() - { - // Remove every CollectionChanged WeakEventListener from the - // inner DataGridVirtualizingCollectionViewGroupBase - // and clear the references to them - Debug.Assert( m_virtualListVSCollectionViewGroupDictionary.Count == 0 ); - - // Dispose the RootGroup for which this manager - // was created - if( m_managerCollectionViewGroupRoot != null ) - { - m_managerCollectionViewGroupRoot.Dispose(); - m_managerCollectionViewGroupRoot = null; - } - - // Force a PropertyChanged on the CollectionView - // for properties ConnectionState and Error to force - // bound countrol to update correctly using the values - // affected on the CollectionView by the new - // VirtualPageManager - if( m_collectionView != null ) - { - m_collectionView.RefreshConnectionStateAndError(); - m_collectionView = null; - } - - base.DisposeCore(); - } - - protected internal override int OnQueryItemCount( VirtualList virtualList ) - { - try - { - return base.OnQueryItemCount( virtualList ); - } - finally - { - this.UpdateConnectionState(); - } - } - - #endregion PROTECTED METHODS - - #region PRIVATE METHODS - - private void TryDispose() - { - if( ( m_asyncCommitInfosInProgress.Count == 0 ) - && ( m_asyncCommitInfosInError == null ) - && ( m_asyncQueryInfosInError == null ) - && ( m_asyncQueryInfosInProgress.Count == 0 ) ) - { - // At this point, all data was correctly committed. - - // This manager is no more required, we can dispose - // it. This will force a dispose of all VirtualList, - // their inner VirtualListTableOfContent and Pages. - this.Dispose(); - } - } - - private void UpdateConnectionState() - { - // Never update the ConnectionState when disconnected - // from the CollectionView or Disposed since another - // VirtualPageManager will take care or updating it - if( !this.IsConnected || this.IsDisposed ) - return; - - DataGridConnectionState state = DataGridConnectionState.Idle; - object error = null; - - if( m_asyncCommitInfosInError != null ) - { - state = DataGridConnectionState.Error; - Debug.Assert( m_asyncCommitInfosInError.Count > 0 ); - error = m_asyncCommitInfosInError.First.Value.Error; - } - else if( m_asyncQueryInfosInError != null ) - { - state = DataGridConnectionState.Error; - Debug.Assert( m_asyncQueryInfosInError.Count > 0 ); - error = m_asyncQueryInfosInError.First.Value.Error; - } - else if( m_asyncCommitInfosInProgress.Count > 0 ) - { - state = DataGridConnectionState.Committing; - } - else if( m_asyncQueryInfosInProgress.Count > 0 ) - { - state = DataGridConnectionState.Loading; - } - - m_collectionView.UpdateConnectionState( state, error ); - } - - private void RaiseCollectionViewOnCommitItems( VirtualPage dispatchedPage, AsyncCommitInfo dispatchedCommitInfo ) - { - DataGridVirtualizingCollectionViewBase collectionView = this.CollectionView as DataGridVirtualizingCollectionViewBase; - - DataGridVirtualizingCollectionViewGroupBase collectionViewGroup = - this.GetLinkedCollectionViewGroup( dispatchedPage.ParentVirtualList ) as DataGridVirtualizingCollectionViewGroupBase; - - Debug.Assert( ( collectionViewGroup != null ) && ( collectionView != null ) ); - - collectionView.OnCommitItems( dispatchedCommitInfo ); - } - - #endregion - - #region INTERNAL METHODS - - internal void LinkVirtualListAndCollectionViewGroup( VirtualList virtualItemList, DataGridVirtualizingCollectionViewGroupBase collectionViewGroup ) - { - Debug.Assert( !m_virtualListVSCollectionViewGroupDictionary.ContainsKey( virtualItemList ) ); - Debug.Assert( !m_virtualListVSCollectionViewGroupDictionary.ContainsValue( collectionViewGroup ) ); - - m_virtualListVSCollectionViewGroupDictionary.Add( virtualItemList, collectionViewGroup ); - - CollectionChangedEventManager.AddListener( virtualItemList, collectionViewGroup ); - } - - internal override void OnVirtualListRestarted( VirtualList virtualList ) - { - this.UnlinkVirtualListAndCollectionViewGroup( virtualList ); - base.OnVirtualListRestarted( virtualList ); - } - - #endregion INTERNAL METHODS - - #region PRIVATE FIELDS - - private DataGridVirtualizingCollectionViewGroupBase m_managerCollectionViewGroupRoot; - private DataGridVirtualizingCollectionViewBase m_collectionView; - private Dictionary m_virtualListVSCollectionViewGroupDictionary; - - private HashSet m_asyncQueryInfosInProgress = new HashSet(); - private HashSet m_asyncCommitInfosInProgress = new HashSet(); - - private LinkedList m_asyncQueryInfosInError; - private LinkedList m_asyncCommitInfosInError; - - #endregion PRIVATE FIELDS - - - #region IEnumerable Members - - public IEnumerator GetEnumerator() - { - return new DataGridPageManagerEnumerator( this ); - } - - #endregion - - #region IEnumerable Members - - IEnumerator IEnumerable.GetEnumerator() - { - return null; - } - - #endregion - - - #region PRIVATE NESTED CLASSES - - private class DataGridPageManagerEnumerator : IEnumerator, IEnumerator - { - public DataGridPageManagerEnumerator( DataGridPageManagerBase dataGridPageManagerBase ) - { - if( dataGridPageManagerBase == null ) - throw new ArgumentNullException( "dataGridPageManagerBase" ); - - m_dataGridPageManagerBase = dataGridPageManagerBase; - - VirtualList[] orderedVirtualLists = - m_dataGridPageManagerBase.m_virtualListVSCollectionViewGroupDictionary.Keys.OrderBy( - virtualList => m_dataGridPageManagerBase.m_virtualListVSCollectionViewGroupDictionary[ virtualList ].StartGlobalIndex ).ToArray(); - - m_orderedVirtualListEnumerators = new VirtualListEnumerator[ orderedVirtualLists.Length ]; - - for( int i = 0; i < orderedVirtualLists.Length; i++ ) - { - m_orderedVirtualListEnumerators[ i ] = ( VirtualListEnumerator )( ( IEnumerable )orderedVirtualLists[ i ] ).GetEnumerator(); - } - } - - #region IEnumerator Members - - public object Current - { - get - { - return m_currentItem; - } - } - - #endregion IEnumerator Members - - #region IDisposable Members - - public void Dispose() - { - foreach( VirtualListEnumerator enumerator in m_orderedVirtualListEnumerators ) - { - enumerator.Dispose(); - } - - m_orderedVirtualListEnumerators = null; - m_dataGridPageManagerBase = null; - m_currentItem = null; - } - - #endregion - - #region IEnumerator Members - - public bool MoveNext() - { - // No need to check the VirtualPageManager's version. The sub VirtualLists' Enumerator will take care of it. - while( m_currentEnumeratorIndex < m_orderedVirtualListEnumerators.Length ) - { - VirtualListEnumerator enumerator = m_orderedVirtualListEnumerators[ m_currentEnumeratorIndex ]; - - enumerator.MoveNext(); - - if( !enumerator.AfterEnd ) - { - m_currentItem = enumerator.Current; - return true; - } - else - { - // Reached the end of this enumerator. Let's increment the currentEnumeratorIndex. - m_currentEnumeratorIndex++; - } - } - - m_currentItem = null; - return false; - } - - public void Reset() - { - m_currentEnumeratorIndex = 0; - m_currentItem = null; - } - - object IEnumerator.Current - { - get - { - return this.Current; - } - } - - bool IEnumerator.MoveNext() - { - return this.MoveNext(); - } - - void IEnumerator.Reset() - { - this.Reset(); - } - - #endregion IEnumerator Members - - - #region PRIVATE FIELDS - - private DataGridPageManagerBase m_dataGridPageManagerBase; - private VirtualListEnumerator[] m_orderedVirtualListEnumerators; - private object m_currentItem; - private int m_currentEnumeratorIndex; - - #endregion PRIVATE FIELDS - } - - #endregion PRIVATE NESTED CLASSES - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridRemovingItemEvent.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridRemovingItemEvent.cs deleted file mode 100644 index 484902e5..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridRemovingItemEvent.cs +++ /dev/null @@ -1,43 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - public class DataGridRemovingItemEventArgs : DataGridItemCancelEventArgs - { - public DataGridRemovingItemEventArgs( DataGridCollectionViewBase collectionView, object item, int index, bool cancel) - : base( collectionView, item, cancel ) - { - m_index = index; - } - - #region Index Property - - public int Index - { - get { return m_index; } - } - - private int m_index; - - #endregion Index Property - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridSortDescriptionCollection.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridSortDescriptionCollection.cs deleted file mode 100644 index c9b4ec2f..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridSortDescriptionCollection.cs +++ /dev/null @@ -1,130 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics; - -namespace Xceed.Wpf.DataGrid -{ - internal class DataGridSortDescriptionCollection : SortDescriptionCollection - { - #region CONSTRUCTORS - - public DataGridSortDescriptionCollection() - { - } - - #endregion CONSTRUCTORS - - #region IsResortDefered PROPERTY - - public bool IsResortDefered - { - get - { - return ( m_deferResortCount > 0 ); - } - } - - #endregion IsResortDefered PROPERTY - - #region SyncContext PROPERTY - - public SortDescriptionsSyncContext SyncContext - { - get - { - return m_syncContext; - } - } - - #endregion SyncContext PROPERTY - - #region PUBLIC METHODS - - public IDisposable DeferResort() - { - return new DeferResortDisposable( this ); - } - - public void AddResortNotification( IDisposable notificationObject ) - { - Debug.Assert( m_deferResortCount > 0 ); - - lock( m_notificationList ) - { - m_notificationList.Enqueue( notificationObject ); - } - } - - #endregion PUBLIC METHODS - - #region PRIVATE FIELDS - - private SortDescriptionsSyncContext m_syncContext = new SortDescriptionsSyncContext(); - private int m_deferResortCount; // = 0 - private Queue m_notificationList = new Queue(); - - #endregion PRIVATE FIELDS - - #region NESTED CLASSES - - private sealed class DeferResortDisposable : IDisposable - { - public DeferResortDisposable( DataGridSortDescriptionCollection parentCollection ) - { - if( parentCollection == null ) - throw new ArgumentNullException( "parentCollection" ); - - m_parentCollection = parentCollection; - m_parentCollection.m_deferResortCount++; - } - - #region IDisposable Members - - public void Dispose() - { - Debug.Assert( m_parentCollection.m_deferResortCount > 0 ); - - lock( m_parentCollection.m_notificationList ) - { - m_parentCollection.m_deferResortCount--; - - if( m_parentCollection.m_deferResortCount == 0 ) - { - while( m_parentCollection.m_notificationList.Count > 0 ) - { - IDisposable notificationObject = m_parentCollection.m_notificationList.Dequeue(); - - notificationObject.Dispose(); - notificationObject = null; - } - } - } - - m_parentCollection = null; - } - - #endregion - - private DataGridSortDescriptionCollection m_parentCollection; // = null - } - - #endregion NESTED CLASSES - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridUnboundItemProperty.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridUnboundItemProperty.cs deleted file mode 100644 index abf7aa6a..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridUnboundItemProperty.cs +++ /dev/null @@ -1,126 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; -using System.Diagnostics; - -namespace Xceed.Wpf.DataGrid -{ - [DebuggerDisplay( "Name = {Name}" )] - public class DataGridUnboundItemProperty : DataGridItemPropertyBase - { - public DataGridUnboundItemProperty() - { - } - - public DataGridUnboundItemProperty( string name, Type dataType ) - { - if( string.IsNullOrEmpty( name ) ) - throw new ArgumentException( "The name must not be null (Nothing in Visual Basic) or empty.", "name" ); - - if( dataType == null ) - throw new ArgumentNullException( "dataType" ); - - this.Initialize( name, null, dataType, null, null, null, null ); - } - - public DataGridUnboundItemProperty( string name, Type dataType, bool isReadOnly ) - { - if( string.IsNullOrEmpty( name ) ) - throw new ArgumentException( "The name must not be null (Nothing in Visual Basic) or empty.", "name" ); - - if( dataType == null ) - throw new ArgumentNullException( "dataType" ); - - this.Initialize( name, null, dataType, isReadOnly, null, null, null ); - } - - public DataGridUnboundItemProperty( string name, Type dataType, bool isReadOnly, bool overrideReadOnlyForInsertion ) - { - if( string.IsNullOrEmpty( name ) ) - throw new ArgumentException( "The name must not be null (Nothing in Visual Basic) or empty.", "name" ); - - if( dataType == null ) - throw new ArgumentNullException( "dataType" ); - - this.Initialize( name, null, dataType, isReadOnly, overrideReadOnlyForInsertion, null, null ); - } - - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - [Obsolete( "This constructor is obsolete and should no longer be used.", true )] - protected DataGridUnboundItemProperty( DataGridUnboundItemProperty template ) - { - throw new NotSupportedException(); - } - - public event EventHandler QueryValue; - public event EventHandler CommittingValue; - - protected override object GetValueCore( object component ) - { - var handler = this.QueryValue; - if( handler == null ) - return null; - - var e = new DataGridItemPropertyQueryValueEventArgs( component ); - - handler.Invoke( this, e ); - - return e.Value; - } - - protected override void SetValueCore( object component, object value ) - { - var handler = this.CommittingValue; - if( handler != null ) - { - handler.Invoke( this, new DataGridItemPropertyCommittingValueEventArgs( component, value ) ); - } - - base.SetValueCore( component, value ); - } - - internal void Refresh( object component ) - { - var propertyDescriptor = this.GetPropertyDescriptorForBinding(); - if( propertyDescriptor == null ) - return; - - propertyDescriptor.RaiseValueChanged( component ); - } - - internal override void SetUnspecifiedPropertiesValues( - PropertyDescription description, - Type itemType, - bool defaultItemPropertiesCreated ) - { - if( this.DataType == null ) - throw new InvalidOperationException( "An attempt was made to add an item without specifying its data type." ); - - if( string.IsNullOrEmpty( this.Title ) ) - { - this.Title = this.Name; - } - - if( !this.OverrideReadOnlyForInsertion.HasValue ) - { - this.OverrideReadOnlyForInsertion = false; - } - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingCollectionView.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingCollectionView.cs deleted file mode 100644 index 17d68113..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingCollectionView.cs +++ /dev/null @@ -1,155 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Collections; -using Xceed.Utils.Collections; -using System.Data; -using System.ComponentModel; -using System.Collections.ObjectModel; -using System.Diagnostics; - -namespace Xceed.Wpf.DataGrid -{ - public sealed class DataGridVirtualizingCollectionView : DataGridVirtualizingCollectionViewBase - { - #region CONSTRUCTORS - - public DataGridVirtualizingCollectionView() - : this( null, typeof( object ), true, DataGridVirtualizingCollectionViewBase.DefaultPageSize, DataGridVirtualizingCollectionViewBase.DefaultMaxRealizedItemCount ) - { - } - - public DataGridVirtualizingCollectionView( Type itemType ) - : this( null, itemType, true, DataGridVirtualizingCollectionViewBase.DefaultPageSize, DataGridVirtualizingCollectionViewBase.DefaultMaxRealizedItemCount ) - { - } - - public DataGridVirtualizingCollectionView( Type itemType, bool autoCreateItemProperties, int pageSize, int maxRealizedItemCount ) - : this( null, itemType, autoCreateItemProperties, pageSize, maxRealizedItemCount ) - { - } - - - public DataGridVirtualizingCollectionView( DataTable sourceSchema ) - : this( sourceSchema, typeof( object ), true, DataGridVirtualizingCollectionViewBase.DefaultPageSize, DataGridVirtualizingCollectionViewBase.DefaultMaxRealizedItemCount ) - { - } - - public DataGridVirtualizingCollectionView( DataTable sourceSchema, bool autoCreateItemProperties, int pageSize, int maxRealizedItemCount ) - : this( sourceSchema, typeof( object ), autoCreateItemProperties, pageSize, maxRealizedItemCount ) - { - } - - - private DataGridVirtualizingCollectionView( DataTable sourceSchema, Type itemType, bool autoCreateItemProperties, int pageSize, int maxRealizedItemCount ) - : base( sourceSchema, itemType, autoCreateItemProperties, pageSize, maxRealizedItemCount ) - { - } - - #endregion CONSTRUCTORS - - - #region DATA VIRTUALIZATION - - public event EventHandler QueryItemCount; - - internal int OnQueryItemCount( DataGridVirtualizingCollectionViewGroup collectionViewGroup ) - { - QueryItemCountEventArgs e = new QueryItemCountEventArgs( this, collectionViewGroup ); - - if( this.QueryItemCount != null ) - this.QueryItemCount( this, e ); - - DataGridVirtualizingCollectionViewSource source = this.ParentCollectionViewSourceBase as DataGridVirtualizingCollectionViewSource; - - if( source != null ) - source.OnQueryItemCount( e ); - - return e.Count; - } - - public event EventHandler QueryGroups; - - internal List OnQueryGroups( DataGridVirtualizingCollectionViewGroup parentGroup ) - { - ObservableCollection groupDescriptions = this.GroupDescriptions; - int nextLevel = parentGroup.Level + 1; - - Debug.Assert( ( groupDescriptions != null ) && ( groupDescriptions.Count > nextLevel ) ); - - QueryGroupsEventArgs e = new QueryGroupsEventArgs( this, parentGroup, groupDescriptions[ nextLevel ] ); - - if( this.QueryGroups != null ) - this.QueryGroups( this, e ); - - DataGridVirtualizingCollectionViewSource source = this.ParentCollectionViewSourceBase as DataGridVirtualizingCollectionViewSource; - - if( source != null ) - source.OnQueryGroups( e ); - - return e.ChildGroupNameCountPairs; - } - - - public event EventHandler AbortQueryItems; - - internal void OnAbortQueryItems( AsyncQueryInfo asyncQueryInfo, DataGridVirtualizingCollectionViewGroup collectionViewGroup ) - { - QueryItemsEventArgs e = new QueryItemsEventArgs( this, collectionViewGroup, asyncQueryInfo ); - - if( this.AbortQueryItems != null ) - this.AbortQueryItems( this, e ); - - DataGridVirtualizingCollectionViewSource source = this.ParentCollectionViewSourceBase as DataGridVirtualizingCollectionViewSource; - - if( source != null ) - source.OnAbortQueryItems( e ); - } - - public event EventHandler QueryItems; - - internal void OnQueryItems( AsyncQueryInfo asyncQueryInfo, DataGridVirtualizingCollectionViewGroup collectionViewGroup ) - { - QueryItemsEventArgs e = new QueryItemsEventArgs( this, collectionViewGroup, asyncQueryInfo ); - - if( this.QueryItems != null ) - this.QueryItems( this, e ); - - DataGridVirtualizingCollectionViewSource source = this.ParentCollectionViewSourceBase as DataGridVirtualizingCollectionViewSource; - - if( source != null ) - source.OnQueryItems( e ); - } - - #endregion DATA VIRTUALIZATION - - internal override IEnumerator GetVirtualEnumerator() - { - return ( ( DataGridVirtualizingCollectionViewGroupRoot )this.RootGroup ).GetVirtualPageManager().GetEnumerator(); - } - - internal override DataGridVirtualizingCollectionViewGroupBase CreateNewRootGroup() - { - bool rootIsBottomLevel = ( this.GroupDescriptions == null ) ? true : ( this.GroupDescriptions.Count == 0 ); - - return new DataGridVirtualizingCollectionViewGroupRoot( this, rootIsBottomLevel ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingCollectionViewBase.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingCollectionViewBase.cs deleted file mode 100644 index 81ba31c9..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingCollectionViewBase.cs +++ /dev/null @@ -1,977 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Diagnostics; - -namespace Xceed.Wpf.DataGrid -{ - public abstract class DataGridVirtualizingCollectionViewBase : DataGridCollectionViewBase - { - #region STATIC MEMBERS - - internal const int DefaultMaxRealizedItemCount = 1000; - internal const int DefaultPageSize = 200; - internal const double DefaultPreemptivePageQueryRatio = 0.25; - - #endregion STATIC MEMBERS - - #region CONSTRUCTORS - - internal DataGridVirtualizingCollectionViewBase( object sourceModel, Type itemType, bool autoCreateItemProperties, int pageSize, int maxRealizedItemCount ) - : base( sourceModel, null, itemType, autoCreateItemProperties, false, false ) - { - if( itemType == null ) - { - itemType = typeof( object ); - } - - if( pageSize < 1 ) - throw new ArgumentOutOfRangeException( "pageSize", pageSize, "pageSize must be greater than zero." ); - - if( maxRealizedItemCount < 1 ) - throw new ArgumentOutOfRangeException( "maxRealizedItemCount", maxRealizedItemCount, "maxRealizedItemCount must be greater than zero." ); - - if( maxRealizedItemCount < pageSize ) - { - maxRealizedItemCount = pageSize; - } - - m_pageSize = pageSize; - m_maxRealizedItemCount = maxRealizedItemCount; - m_preemptivePageQueryRatio = DataGridVirtualizingCollectionViewBase.DefaultPreemptivePageQueryRatio; - } - - internal override DataGridCollectionViewBase CreateDetailDataGridCollectionViewBase( - IEnumerable detailDataSource, - DataGridDetailDescription parentDetailDescription, - DataGridCollectionViewBase parentDataGridCollectionViewBase ) - { - throw new NotImplementedException(); - } - - #endregion - - #region CollectionView Members - - public override bool CanGroup - { - get - { - return true; - } - } - - public override bool CanFilter - { - get - { - return false; - } - } - - public override IEnumerable SourceCollection - { - get - { - // VirtualizingDataGridCollectionView does not have a source. - return null; - } - } - - public override bool Contains( object item ) - { - if( item == null ) - return false; - - return ( this.IndexOf( item ) != -1 ); - } - - public override bool IsEmpty - { - get - { - return ( this.Count == 0 ); - } - } - - public override int IndexOf( object item ) - { - this.EnsureThreadAndCollectionLoaded(); - - return this.RootGroup.GetGlobalIndexOf( item ); - } - - public override object GetItemAt( int index ) - { - this.EnsureThreadAndCollectionLoaded(); - - if( index < 0 ) - return null; - - return this.RootGroup.GetItemAtGlobalIndex( index ); - } - - #endregion CollectionView Members - - #region Currency management - - public override object CurrentItem - { - get - { - if( ( !this.Loaded ) || ( this.IsCurrentBeforeFirst ) || ( this.IsCurrentAfterLast ) ) - return null; - - return base.CurrentItem; - } - } - - public override bool MoveCurrentToPosition( int position ) - { - if( position == this.CurrentPosition ) - return ( this.CurrentItem != null ); - - this.EnsureThreadAndCollectionLoaded(); - return this.SetCurrentItem( position, true ); - } - - private bool SetCurrentItem( int newCurrentPosition, bool isCancelable ) - { - int count = this.Count; - - if( ( newCurrentPosition < -1 ) || ( newCurrentPosition > count ) ) - throw new ArgumentOutOfRangeException( "newCurrentPosition", "The current position must be greater than -1 and less than Count." ); - - object newCurrentItem = null; - - if( ( newCurrentPosition >= 0 ) && ( newCurrentPosition < count ) ) - newCurrentItem = this.GetItemAt( newCurrentPosition ); - - return this.SetCurrentItem( newCurrentPosition, newCurrentItem, isCancelable, false ); - } - - private bool SetCurrentItem( int newCurrentPosition, object newCurrentItem, bool isCancelable, bool beforeDeleteOperation ) - { - object oldCurrentItem = this.CurrentItem; - int oldCurrentPosition = this.CurrentPosition; - bool oldIsCurrentBeforeFirst = this.IsCurrentBeforeFirst; - bool oldIsCurrentAfterLast = this.IsCurrentAfterLast; - - if( ( !object.Equals( oldCurrentItem, newCurrentItem ) ) || ( oldCurrentPosition != newCurrentPosition ) ) - { - // We raise the changing event even if we are in DeferCurrencyEvent - CurrentChangingEventArgs currentChangingEventArgs = new CurrentChangingEventArgs( isCancelable ); - this.OnCurrentChanging( currentChangingEventArgs ); - - if( ( !currentChangingEventArgs.Cancel ) || ( !currentChangingEventArgs.IsCancelable ) ) - { - int count = this.Count; - - if( beforeDeleteOperation ) - { - Debug.Assert( count > 0 ); - count--; - } - - bool isCurrentBeforeFirst; - bool isCurrentAfterLast; - - if( count == 0 ) - { - isCurrentBeforeFirst = true; - isCurrentAfterLast = true; - } - else - { - isCurrentBeforeFirst = newCurrentPosition < 0; - isCurrentAfterLast = newCurrentPosition >= count; - } - -#if DEBUG - if( newCurrentItem == null ) - Debug.Assert( ( newCurrentPosition == -1 ) || ( newCurrentPosition >= ( count - 1 ) ) ); -#endif - - this.SetCurrentItemAndPositionCore( - newCurrentItem, newCurrentPosition, isCurrentBeforeFirst, isCurrentAfterLast ); - - if( !this.IsCurrencyDeferred ) - { - if( !object.Equals( oldCurrentItem, newCurrentItem ) ) - this.OnPropertyChanged( new PropertyChangedEventArgs( "CurrentItem" ) ); - - if( oldCurrentPosition != this.CurrentPosition ) - this.OnPropertyChanged( new PropertyChangedEventArgs( "CurrentPosition" ) ); - - if( oldIsCurrentBeforeFirst != this.IsCurrentBeforeFirst ) - this.OnPropertyChanged( new PropertyChangedEventArgs( "IsCurrentBeforeFirst" ) ); - - if( oldIsCurrentAfterLast != this.IsCurrentAfterLast ) - this.OnPropertyChanged( new PropertyChangedEventArgs( "IsCurrentAfterLast" ) ); - - this.OnCurrentChanged(); - } - } - } - - return ( newCurrentItem != null ); - } - - private void SaveCurrentBeforeReset( out int oldCurrentPosition ) - { - Debug.Assert( this.Loaded ); - - if( this.IsCurrentAfterLast ) - { - oldCurrentPosition = int.MaxValue; - } - else - { - oldCurrentPosition = this.CurrentPosition; - } - } - - private void AdjustCurrencyAfterReset( int oldCurrentPosition ) - { - if( oldCurrentPosition < 0 ) - { - this.SetCurrentItem( -1, null, false, false ); - return; - } - - int count = this.Count; - - if( oldCurrentPosition == int.MaxValue ) - { - this.SetCurrentItem( count, null, false, false ); - return; - } - - if( oldCurrentPosition >= count ) - { - this.SetCurrentItem( count - 1, false ); - return; - } - - this.SetCurrentItem( oldCurrentPosition, false ); - } - - #endregion Currency management - - #region IEnumerable Members - - protected override IEnumerator GetEnumerator() - { - this.EnsureThreadAndCollectionLoaded(); - - return this.GetVirtualEnumerator(); - } - - internal abstract IEnumerator GetVirtualEnumerator(); - - #endregion - - #region Count Property - - public override int Count - { - get - { - this.EnsureThreadAndCollectionLoaded(); - - int count = this.RootGroup.VirtualItemCount; - - if( count > 0 ) - return count; - - return 0; - } - } - - #endregion Count Property - - #region DistinctValues Management - - private void ResetDistinctValues() - { - } - - #endregion - - #region PageSize Property - - public int PageSize - { - get - { - return m_pageSize; - } - set - { - if( m_pageSize != value ) - { - m_pageSize = value; - - // Cannot modify this PageManager property. Must Refresh which will recreate the CollectionViewGroupRoot - // and the DataGridVirtualPageManagerBase taking the new pageSize into account. - this.Refresh(); - - this.OnPropertyChanged( new PropertyChangedEventArgs( "PageSize" ) ); - } - } - } - - #endregion PageSize Property - - #region MaxRealizedItemCount Property - - public int MaxRealizedItemCount - { - get - { - return m_maxRealizedItemCount; - } - set - { - if( m_maxRealizedItemCount != value ) - { - m_maxRealizedItemCount = value; - - if( value < this.PageSize ) - { - value = this.PageSize; - } - - // Cannot modify this PageManager property. Must Refresh which will recreate the CollectionViewGroupRoot - // and the DataGridVirtualPageManagerBase taking the new pageSize into account. - this.Refresh(); - - this.OnPropertyChanged( new PropertyChangedEventArgs( "MaxRealizedItemCount" ) ); - } - } - } - - #endregion MaxRealizedItemCount Property - - #region PreemptivePageQueryRatio Property - - public double PreemptivePageQueryRatio - { - get - { - return m_preemptivePageQueryRatio; - } - set - { - if( m_preemptivePageQueryRatio != value ) - { - m_preemptivePageQueryRatio = value; - - // Cannot modify this PageManager property. Must Refresh which will recreate the CollectionViewGroupRoot - // and the DataGridVirtualPageManagerBase taking the new pageSize into account. - this.Refresh(); - - this.OnPropertyChanged( new PropertyChangedEventArgs( "PreemptivePageQueryRatio" ) ); - } - } - } - - #endregion PreemptivePageQueryRatio Property - - #region CommitMode Property - - public CommitMode CommitMode - { - get - { - return m_commitMode; - } - set - { - if( m_commitMode != value ) - { - m_commitMode = value; - this.OnPropertyChanged( new PropertyChangedEventArgs( "CommitMode" ) ); - } - } - } - - #endregion CommitMode Property - - #region DATA VIRTUALIZATION - - public void CommitAll() - { - this.RootGroup.GetVirtualPageManager().CommitAll(); - } - - public event EventHandler CommitItems; - - internal void OnCommitItems( AsyncCommitInfo asyncCommitInfo ) - { - CommitItemsEventArgs e = new CommitItemsEventArgs( this, asyncCommitInfo ); - - if( this.CommitItems != null ) - this.CommitItems( this, e ); - - DataGridVirtualizingCollectionViewSourceBase source = this.ParentCollectionViewSourceBase as DataGridVirtualizingCollectionViewSourceBase; - - if( source != null ) - source.OnCommitItems( e ); - } - - public DataGridConnectionState ConnectionState - { - get - { - return m_connectionState; - } - private set - { - if( m_connectionState != value ) - { - m_connectionState = value; - this.RefreshConnectionState(); - } - } - } - - private void RefreshConnectionState() - { - this.OnPropertyChanged( new PropertyChangedEventArgs( "ConnectionState" ) ); - this.OnConnectionStateChanged(); - } - - public object ConnectionError - { - get - { - return m_connectionError; - } - private set - { - if( m_connectionError != value ) - { - m_connectionError = value; - this.RefreshConnectionError(); - } - } - } - - private void RefreshConnectionError() - { - this.OnPropertyChanged( new PropertyChangedEventArgs( "ConnectionError" ) ); - this.OnConnectionErrorChanged(); - } - - internal void RefreshConnectionStateAndError() - { - this.RefreshConnectionState(); - this.RefreshConnectionError(); - } - - internal void UpdateConnectionState( DataGridConnectionState connectionState, object error ) - { - this.ConnectionState = connectionState; - this.ConnectionError = error; - } - - #endregion DATA VIRTUALIZATION - - - #region PUBLIC METHODS - - public override void CommitNew() - { - // We are not calling base since the intended behavior is quite different with Virtualizing collection views. - object currentAddItem = this.CurrentAddItem; - - if( currentAddItem == null ) - return; - - DataGridCommittingNewItemEventArgs committingNewItemEventArgs = new DataGridCommittingNewItemEventArgs( this, currentAddItem, false ); - - this.RootDataGridCollectionViewBase.OnCommittingNewItem( committingNewItemEventArgs ); - - if( committingNewItemEventArgs.Cancel ) - throw new DataGridException( "CommitNew was canceled." ); - - if( !committingNewItemEventArgs.Handled ) - throw new InvalidOperationException( "When manually handling the item-insertion process the CreatingNewItem, CommittingNewItem, and CancelingNewItem events must all be handled." ); - - // Contrarily to the data bound collection views, we do not care about the new index or new count since we will enqueue a Refresh operation. - - this.SetCurrentAddNew( null, -1 ); - - this.ExecuteOrQueueSourceItemOperation( new DeferredOperation( DeferredOperation.DeferredOperationAction.Refresh, -1, null ) ); - } - - public override bool MoveCurrentTo( object item ) - { - m_canSynchronizeSelectionWithCurrent = true; - bool ret = base.MoveCurrentTo( item ); - m_canSynchronizeSelectionWithCurrent = false; - - return ret; - } - - public override bool MoveCurrentToFirst() - { - m_canSynchronizeSelectionWithCurrent = true; - bool ret = base.MoveCurrentToFirst(); - m_canSynchronizeSelectionWithCurrent = false; - - return ret; - } - - public override bool MoveCurrentToLast() - { - m_canSynchronizeSelectionWithCurrent = true; - bool ret = base.MoveCurrentToLast(); - m_canSynchronizeSelectionWithCurrent = false; - - return ret; - } - - public override bool MoveCurrentToNext() - { - m_canSynchronizeSelectionWithCurrent = true; - bool ret = base.MoveCurrentToNext(); - m_canSynchronizeSelectionWithCurrent = false; - - return ret; - } - - public override bool MoveCurrentToPrevious() - { - m_canSynchronizeSelectionWithCurrent = true; - bool ret = base.MoveCurrentToPrevious(); - m_canSynchronizeSelectionWithCurrent = false; - - return ret; - } - - #endregion PUBLIC METHODS - - internal override void SetCurrentItemAndPositionCore( object currentItem, int currentPosition, bool isCurrentBeforeFirst, bool isCurrentAfterLast ) - { - this.UpdateDataVirtualizationLockForCurrentPosition( false ); - - base.SetCurrentItemAndPositionCore( currentItem, currentPosition, isCurrentBeforeFirst, isCurrentAfterLast ); - - this.UpdateDataVirtualizationLockForCurrentPosition( true ); - } - - private void UpdateDataVirtualizationLockForCurrentPosition( bool applyLock ) - { - if( base.RootGroup == null ) - return; - - if( !this.IsCurrentAfterLast && !this.IsCurrentBeforeFirst ) - { - int currentPosition = this.CurrentPosition; - - Debug.Assert( currentPosition > -1 ); - - if( applyLock ) - { - this.RootGroup.LockGlobalIndex( currentPosition ); - } - else - { - this.RootGroup.UnlockGlobalIndex( currentPosition ); - } - } - } - - - #region DEFERRED OPERATIONS HANDLING - - internal override void ExecuteSourceItemOperation( DeferredOperation deferredOperation, out bool refreshForced ) - { - refreshForced = false; - - switch( deferredOperation.Action ) - { - case DeferredOperation.DeferredOperationAction.Add: - case DeferredOperation.DeferredOperationAction.Move: - case DeferredOperation.DeferredOperationAction.RefreshDistincValues: - { - Debug.Assert( false ); - break; - } - - case DeferredOperation.DeferredOperationAction.Refresh: - case DeferredOperation.DeferredOperationAction.Remove: - case DeferredOperation.DeferredOperationAction.Resort: - case DeferredOperation.DeferredOperationAction.Regroup: - { - this.ForceRefresh( true, false, true ); - break; - } - - case DeferredOperation.DeferredOperationAction.Replace: - { - this.ReplaceSourceItem( deferredOperation.OldStartingIndex, deferredOperation.OldItems, - deferredOperation.NewStartingIndex, deferredOperation.NewItems ); - break; - } - - default: - { - base.ExecuteSourceItemOperation( deferredOperation, out refreshForced ); - break; - } - } - } - - private void ReplaceSourceItem( int oldStartIndex, IList oldItems, int newStartIndex, IList newItems ) - { - Debug.Assert( oldStartIndex == newStartIndex ); - Debug.Assert( oldItems.Count == newItems.Count ); - - if( ( oldStartIndex == -1 ) || ( newStartIndex == -1 ) ) - { - this.ForceRefresh( true, !this.Loaded, true ); - return; - } - - int newItemCount = newItems.Count; - int oldItemCount = oldItems.Count; - int extraOldItemCount = oldItemCount - newItemCount; - - int currentPosition = this.CurrentPosition; - - int count = Math.Min( newItemCount, oldItemCount ); - - for( int i = 0; i < count; i++ ) - { - object oldItem = oldItems[ i ]; - object newItem = newItems[ i ]; - - if( ( oldStartIndex == newStartIndex ) && ( object.Equals( oldItem, newItem ) ) ) - { - if( this.CurrentEditItem != oldItem ) - { - this.OnCollectionChanged( new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Replace, - new object[] { newItem }, - new object[] { oldItem }, - oldStartIndex + i ) ); - } - } - else - { - this.OnCollectionChanged( new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Replace, - new object[] { newItem }, - new object[] { oldItem }, - oldStartIndex + i ) ); - - if( currentPosition == newStartIndex + i ) - this.SetCurrentItem( currentPosition, newItem, false, false ); - } - } - } - - #endregion DEFERRED OPERATIONS HANDLING - - #region INTERNAL PROPERTIES - - internal new DataGridVirtualizingCollectionViewGroupBase RootGroup - { - get - { - if( base.RootGroup == null ) - base.RootGroup = this.CreateNewRootGroup(); - - return base.RootGroup as DataGridVirtualizingCollectionViewGroupBase; - } - set - { - base.RootGroup = value; - } - } - - internal override int SourceItemCount - { - get - { - return this.Count; - } - } - - internal bool CanSynchronizeSelectionWithCurrent - { - get - { - return m_canSynchronizeSelectionWithCurrent; - } - } - - #endregion INTERNAL PROPERTIES - - #region INTERNAL METHODS - - internal abstract DataGridVirtualizingCollectionViewGroupBase CreateNewRootGroup(); - - internal override void OnBeginningEdit( DataGridItemCancelEventArgs e ) - { - object item = e.Item; - - // We throw instead of setting e.Cancel to True because we do not want to give the developer the chance to set it back to False. - if( item is EmptyDataItem ) - throw new DataGridException( "Cannot begin edit on an empty data item or on an item that has a pending commit async operation." ); - - DataGridPageManagerBase pageManager = this.RootGroup.GetVirtualPageManager(); - - if( pageManager.IsAsyncCommitQueuedForItem( item ) ) - throw new DataGridException( "Cannot begin edit on an empty data item or on an item that has a pending commit async operation." ); - - base.OnBeginningEdit( e ); - } - - internal override void OnEditBegun( DataGridItemEventArgs e ) - { - var item = e.Item; - var pageManager = this.RootGroup.GetVirtualPageManager(); - - if( !pageManager.IsItemDirty( item ) ) - { - // First time we enter edit on this item. - var itemProperties = this.ItemProperties; - var count = itemProperties.Count; - - var propertyNames = new string[ count ]; - var cachedValues = new object[ count ]; - - for( int i = 0; i < count; i++ ) - { - var itemProperty = itemProperties[ i ]; - - propertyNames[ i ] = PropertyRouteParser.Parse( itemProperty ); - cachedValues[ i ] = ItemsSourceHelper.GetValueFromItemProperty( itemProperty, item ); - } - - // Cache the values of the never edited before row. This will help the developer find the corresponding row - // in the source when times comes to commit the changes to the data source. - pageManager.SetCachedValuesForItem( item, propertyNames, cachedValues ); - } - - base.OnEditBegun( e ); - } - - internal override void OnEditCommitted( DataGridItemEventArgs e ) - { - var item = e.Item; - var pageManager = this.RootGroup.GetVirtualPageManager(); - - // Compare cached values with current values. If they are the same, we can clear the old values which in turn will - // make the item non dirty. - var clearIsDirty = true; - - var cachedValues = pageManager.GetCachedValuesForItem( item ); - - Debug.Assert( cachedValues != null ); - - var itemProperties = this.ItemProperties; - - foreach( var itemProperty in itemProperties ) - { - var currentValue = ItemsSourceHelper.GetValueFromItemProperty( itemProperty, item ); - - if( !( object.Equals( currentValue, cachedValues[ itemProperty.Name ] ) ) ) - { - clearIsDirty = false; - break; - } - } - - if( clearIsDirty ) - { - // No modification was detected. - pageManager.ClearCachedValuesForItem( item ); - } - else if( m_commitMode == CommitMode.EditCommitted ) - { - pageManager.CommitAll(); - } - - base.OnEditCommitted( e ); - } - - internal override void OnEditCanceled( DataGridItemEventArgs e ) - { - var item = e.Item; - var pageManager = this.RootGroup.GetVirtualPageManager(); - - // Compare cached values with current values. If they are the same, we can clear the old values which in turn will - // make the item non dirty. - var clearIsDirty = true; - - var cachedValues = pageManager.GetCachedValuesForItem( item ); - - Debug.Assert( cachedValues != null ); - - var itemProperties = this.ItemProperties; - - foreach( var itemProperty in itemProperties ) - { - var currentValue = ItemsSourceHelper.GetValueFromItemProperty( itemProperty, item ); - - if( !( object.Equals( currentValue, cachedValues[ PropertyRouteParser.Parse( itemProperty ) ] ) ) ) - { - clearIsDirty = false; - break; - } - } - - if( clearIsDirty ) - { - pageManager.ClearCachedValuesForItem( item ); - } - - base.OnEditCanceled( e ); - } - - #endregion INTERNAL METHODS - - #region INTERNAL EVENTS - - internal event EventHandler ConnectionStateChanged; - - internal void OnConnectionStateChanged() - { - if( this.ConnectionStateChanged != null ) - this.ConnectionStateChanged( this, EventArgs.Empty ); - } - - internal event EventHandler ConnectionErrorChanged; - - internal void OnConnectionErrorChanged() - { - if( this.ConnectionErrorChanged != null ) - this.ConnectionErrorChanged( this, EventArgs.Empty ); - } - - #endregion INTERNAL EVENTS - - - #region PRIVATE FIELDS - - private CommitMode m_commitMode; - - private int m_pageSize; - private double m_preemptivePageQueryRatio; - private int m_maxRealizedItemCount; - - private object m_connectionError; - private DataGridConnectionState m_connectionState; - - private bool m_canSynchronizeSelectionWithCurrent; - - #endregion PRIVATE FIELDS - - - #region DataGridCollectionViewBase Implementation - - internal override void EnsurePosition( int globalSortedIndex ) - { - } - - internal override void ForceRefresh( bool sendResetNotification, bool initialLoad, bool setCurrentToFirstOnInitialLoad ) - { - if( this.Refreshing ) - throw new InvalidOperationException( "An attempt was made to refresh the DataGridVirtualizingCollectionView while it is already in the process of refreshing." ); - - if( this.IsRefreshingDistinctValues ) - throw new InvalidOperationException( "An attempt was made to refresh the DataGridVirtualizingCollectionView while it is already in the process of refreshing distinct values." ); - - this.SetCurrentEditItem( null ); - int oldCurrentPosition = -1; - - if( !initialLoad ) - this.SaveCurrentBeforeReset( out oldCurrentPosition ); - - using( this.DeferCurrencyEvent() ) - { - this.Refreshing = true; - try - { - lock( this.SyncRoot ) - { - lock( this.DeferredOperationManager ) - { - this.DeferredOperationManager.ClearDeferredOperations(); - - // We explicitly go through base so we do not end-up creating a RootGroup if there is none existing at the moment. - DataGridVirtualizingCollectionViewGroupBase rootGroup = base.RootGroup as DataGridVirtualizingCollectionViewGroupBase; - if( rootGroup != null ) - { - DataGridPageManagerBase pageManager = rootGroup.GetVirtualPageManager(); - - // The pageManager can be null when no queryable source was set yet. - if( pageManager != null ) - { - // Disconnect the PageManager so that subsequent Items/Count interrogations are not processed. - pageManager.Disconnect(); - - // Restart all virtual lists. The DataGridPageManagerBase will make a call to ForceRefresh once everything has been restarted if - // commit operations had to be made. - pageManager.Restart(); - } - } - - // Ensure to clear the DistinctValues cache when refreshing - // since the source could have changed - this.ResetDistinctValues(); - - base.RootGroup = this.CreateNewRootGroup(); - - // We set the current item to -1 to prevent the developper to get an invalid position. - // We will replace the current item to the correct one later. - this.SetCurrentItem( -1, null, false, false ); - } - } - } - finally - { - this.Refreshing = false; - } - - if( initialLoad ) - { - this.Loaded = true; - } - else - { - this.AdjustCurrencyAfterReset( oldCurrentPosition ); - } - - if( sendResetNotification ) - { - this.OnCollectionChanged( new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Reset ) ); - } - - this.OnPropertyChanged( new PropertyChangedEventArgs( "Groups" ) ); - } - } - - #endregion DataGridCollectionViewBase Implementation - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingCollectionViewDataProvider.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingCollectionViewDataProvider.cs deleted file mode 100644 index b2bc3288..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingCollectionViewDataProvider.cs +++ /dev/null @@ -1,53 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - internal class DataGridVirtualizingCollectionViewDataProvider : DataGridCollectionViewBaseDataProvider - { - #region CONSTRUCTORS - - public DataGridVirtualizingCollectionViewDataProvider( DataGridVirtualizingCollectionViewSource parentSource ) - : base( parentSource ) - { - } - - #endregion CONSTRUCTORS - - #region INTERNAL METHODS - - internal override DataGridCollectionViewBase EnsureDataGridCollectionViewBaseCore() - { - DataGridVirtualizingCollectionViewSource parentSource = this.ParentSource as DataGridVirtualizingCollectionViewSource; - - if( !parentSource.IsInitialized ) - return null; - - return new DataGridVirtualizingCollectionView( - parentSource.ItemType, - parentSource.AutoCreateItemProperties, - parentSource.PageSize, - parentSource.MaxRealizedItemCount ); - } - - #endregion INTERNAL METHODS - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingCollectionViewGroup.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingCollectionViewGroup.cs deleted file mode 100644 index 95c64d4f..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingCollectionViewGroup.cs +++ /dev/null @@ -1,112 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.Diagnostics; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal class DataGridVirtualizingCollectionViewGroup : DataGridVirtualizingCollectionViewGroupBase, IWeakEventListener - { - private static List EmptyDataGridInfoList = new List( 0 ); - - internal DataGridVirtualizingCollectionViewGroup( object name, int initialItemsCount, int startGlobalIndex, DataGridVirtualizingCollectionViewGroup parent, int level, bool isBottomLevel ) - : base( name, initialItemsCount, startGlobalIndex, parent, level, isBottomLevel ) - { - } - - #region GroupPath Property - - internal List GroupPath - { - get - { - if( m_groupPath == null ) - { - m_groupPath = this.BuildGroupPath(); - } - - return m_groupPath; - } - } - - #endregion - - internal override int QueryItemCount() - { - DataGridVirtualizingCollectionView collectionView = this.GetCollectionView() as DataGridVirtualizingCollectionView; - return collectionView.OnQueryItemCount( this ); - } - - internal override ObservableCollection QuerySubCollectionViewGroupList( GroupDescription subGroupBy, int nextLevel, bool nextLevelIsBottom ) - { - DataGridVirtualizingCollectionView collectionView = this.GetCollectionView() as DataGridVirtualizingCollectionView; - - Debug.Assert( collectionView != null ); - - List subGroupInfos = collectionView.OnQueryGroups( this ); - int subGroupCount = subGroupInfos.Count; - - // Create the collection of sub CollectionViewGroups - ObservableCollection subCollectionViewGroupList = new ObservableCollection(); - - int runningCount = this.StartGlobalIndex; - for( int i = 0; i < subGroupCount; i++ ) - { - object subGroupName = subGroupInfos[ i ].Name; - int subGroupItemCount = subGroupInfos[ i ].ItemCount; - - subCollectionViewGroupList.Add( new DataGridVirtualizingCollectionViewGroup( subGroupName, subGroupItemCount, runningCount, this, nextLevel, nextLevelIsBottom ) ); - - runningCount += subGroupItemCount; - } - - return subCollectionViewGroupList; - } - - private List BuildGroupPath() - { - DataGridVirtualizingCollectionViewGroup parent = this.Parent as DataGridVirtualizingCollectionViewGroup; - - if( parent == null ) - return new List(); - - DataGridVirtualizingCollectionViewBase collectionView = this.GetCollectionView(); - - ObservableCollection groupDescriptions = collectionView.GroupDescriptions; - - int level = this.Level; - - Debug.Assert( this.Level != -1, "A DataGridCollectionViewGroupRoot should have returned a new List since its parent should have been null." ); - - List groupPath = new List( parent.GroupPath ); - - Debug.Assert( groupDescriptions.Count > level ); - - if( groupDescriptions.Count > level ) - { - groupPath.Add( new DataGridGroupInfo( groupDescriptions[ level ], this ) ); - } - - return groupPath; - } - - private List m_groupPath; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingCollectionViewGroupBase.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingCollectionViewGroupBase.cs deleted file mode 100644 index bdad311d..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingCollectionViewGroupBase.cs +++ /dev/null @@ -1,469 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Diagnostics; -using System.Windows; -using System.Windows.Data; - -namespace Xceed.Wpf.DataGrid -{ - internal abstract class DataGridVirtualizingCollectionViewGroupBase : CollectionViewGroup, IWeakEventListener, IDisposable - { - internal DataGridVirtualizingCollectionViewGroupBase( - object name, - int initialItemsCount, - int startGlobalIndex, - DataGridVirtualizingCollectionViewGroupBase parent, - int level, - bool isBottomLevel ) - : base( name ) - { - m_parent = parent; - m_level = level; - m_isBottomLevel = isBottomLevel; - m_virtualItemCount = initialItemsCount; - m_startGlobalIndex = startGlobalIndex; - } - - #region ItemCount (Obselete) Property - - [Obsolete( "The ItemCount property is obsolete and has been replaced by the VirtualItemCount property. When referencing through a CollectionViewGroup, the CollectionViewGroupExtensions.GetItemCount extension method can be used.", true )] - public new int ItemCount - { - get - { - return this.VirtualItemCount; - } - } - - #endregion - - #region Items (Obselete) Property - - [Obsolete( "The Items property is obsolete and has been replaced by the VirtualItems property. When referencing through a CollectionViewGroup, the CollectionViewGroupExtensions.GetItems extension method can be used.", true )] - public new ReadOnlyObservableCollection Items - { - get - { - return base.Items; - } - } - - #endregion - - #region VirtualItemCount Property - - public int VirtualItemCount - { - get - { - if( this.GetVirtualPageManager() == null ) - return 0; - - if( m_virtualItemCount == -1 ) - { - if( m_isBottomLevel ) - { - this.EnsureProtectedVirtualItems(); - m_virtualItemCount = m_protectedVirtualItems.Count; - } - else - { - m_virtualItemCount = this.QueryItemCount(); - } - } - - return m_virtualItemCount; - } - } - - #endregion - - #region VirtualItems Property - - public IList VirtualItems - { - get - { - if( m_virtualItems == null ) - { - this.EnsureProtectedVirtualItems(); - - ObservableCollection observableProtectedItems = m_protectedVirtualItems as ObservableCollection; - - if( observableProtectedItems != null ) - { - Debug.Assert( !m_isBottomLevel ); - m_virtualItems = new ReadOnlyObservableCollection( observableProtectedItems ); - } - else - { - Debug.Assert( m_isBottomLevel ); - m_virtualItems = m_protectedVirtualItems; - } - } - - return m_virtualItems; - } - } - - #endregion - - #region IsBottomLevel Property - - public override bool IsBottomLevel - { - get - { - return m_isBottomLevel; - } - } - - #endregion - - #region Parent Property - - internal DataGridVirtualizingCollectionViewGroupBase Parent - { - get - { - return m_parent; - } - } - - #endregion - - #region Level Property - - internal int Level - { - get - { - return m_level; - } - } - - #endregion - - #region StartGlobalIndex Property - - internal int StartGlobalIndex - { - get - { - return m_startGlobalIndex; - } - } - - #endregion - - protected virtual DataGridVirtualizingCollectionViewBase GetCollectionView() - { - if( m_parent != null ) - return m_parent.GetCollectionView(); - - return null; - } - - internal abstract int QueryItemCount(); - - internal abstract ObservableCollection QuerySubCollectionViewGroupList( GroupDescription subGroupBy, int nextLevel, bool nextLevelIsBottom ); - - internal virtual GroupDescription GetSubGroupBy() - { - CollectionView collectionView = this.GetCollectionView(); - - ObservableCollection groupDescriptions = collectionView.GroupDescriptions; - - int groupDescriptionsCount = ( groupDescriptions == null ) ? 0 : groupDescriptions.Count; - - if( groupDescriptionsCount == 0 ) - return null; - - DataGridVirtualizingCollectionViewGroupBase parentCollectionViewGroup = this.Parent; - - int level = 0; - while( parentCollectionViewGroup != null ) - { - level++; - parentCollectionViewGroup = parentCollectionViewGroup.Parent; - } - - Debug.Assert( groupDescriptionsCount >= level ); - - return groupDescriptions[ level ]; - } - - internal virtual void OnProtectedVirtualItemsCreated( IList protectedVirtualItems ) - { - } - - internal virtual void DisposeCore() - { - m_protectedVirtualItems = new List(); - m_virtualItems = m_protectedVirtualItems; - m_parent = null; - } - - internal virtual int GetGlobalIndexOf( object item ) - { - return m_parent.GetGlobalIndexOf( item ); - } - - internal virtual DataGridPageManagerBase GetVirtualPageManager() - { - return m_parent.GetVirtualPageManager(); - } - - internal object GetItemAtGlobalIndex( int globalIndex ) - { - Func getItemFunction = ( localIndex, cvg ) => - { - return cvg.m_protectedVirtualItems[ localIndex ]; - }; - - return this.OperateOnGlobalIndex( globalIndex, getItemFunction ); - } - - internal void LockGlobalIndex( int globalIndex ) - { - Func lockingAction = ( localIndex, cvg ) => - { - VirtualList virtualItemList = cvg.VirtualItems as VirtualList; - - if( virtualItemList != null ) - { - virtualItemList.LockPageForLocalIndex( localIndex ); - } - - return null; - }; - - this.OperateOnGlobalIndex( globalIndex, lockingAction ); - } - - internal void UnlockGlobalIndex( int globalIndex ) - { - var collectionView = this.GetCollectionView(); - - if( collectionView != null ) - { - var rootGroup = collectionView.RootGroup; - - // This can happen when refreshing a CollectionView and the record count has changed in such a way that the global index to unlock is out of range of the new count. - if( ( rootGroup != null ) && ( ( globalIndex >= rootGroup.m_virtualItemCount ) ) ) - return; - } - - Func unlockingAction = ( localIndex, cvg ) => - { - VirtualList virtualItemList = cvg.VirtualItems as VirtualList; - - if( virtualItemList != null ) - { - virtualItemList.UnlockPageForLocalIndex( localIndex ); - } - - return null; - }; - - this.OperateOnGlobalIndex( globalIndex, unlockingAction ); - } - - private void EnsureProtectedVirtualItems() - { - if( m_protectedVirtualItems != null ) - return; - - DataGridVirtualizingCollectionViewBase collectionView = this.GetCollectionView(); - - Debug.Assert( collectionView != null ); - - if( m_isBottomLevel ) - { - m_protectedVirtualItems = this.CreateNewVirtualList(); - } - else - { - ObservableCollection groupDescriptions = collectionView.GroupDescriptions; - - int groupDescriptionCount = ( groupDescriptions == null ) ? 0 : groupDescriptions.Count; - - int nextLevel = m_level + 1; - - if( nextLevel > ( groupDescriptionCount - 1 ) ) - throw new DataGridInternalException( "At attempt was made to retrieve child groups for a non-existing group description." ); - - GroupDescription subGroupBy = groupDescriptions[ nextLevel ]; - - if( subGroupBy == null ) - throw new InvalidOperationException( "TODDOOC: " ); - - bool nextLevelIsBottom = ( nextLevel == ( groupDescriptionCount - 1 ) ); - - m_protectedVirtualItems = this.QuerySubCollectionViewGroupList( subGroupBy, nextLevel, nextLevelIsBottom ); - } - } - - private VirtualList CreateNewVirtualList() - { - Debug.Assert( m_isBottomLevel ); - - DataGridVirtualizingCollectionViewBase collectionView = this.GetCollectionView(); - - DataGridPageManagerBase virtualPageManagerBase = collectionView.RootGroup.GetVirtualPageManager(); - - VirtualList virtualItemList = new VirtualList( virtualPageManagerBase, m_virtualItemCount ); - virtualPageManagerBase.LinkVirtualListAndCollectionViewGroup( virtualItemList, this ); - - return virtualItemList; - } - - private int GetSubLevelCount() - { - CollectionView collectionView = this.GetCollectionView(); - - ObservableCollection groupDescriptions = collectionView.GroupDescriptions; - - int groupDescriptionsCount = ( groupDescriptions == null ) ? 0 : groupDescriptions.Count; - - DataGridVirtualizingCollectionViewGroupBase parentCollectionViewGroup = this.Parent; - - int level = 0; - while( parentCollectionViewGroup != null ) - { - level++; - parentCollectionViewGroup = parentCollectionViewGroup.Parent; - } - - Debug.Assert( groupDescriptionsCount >= level ); - - return ( groupDescriptionsCount - level ); - } - - private object OperateOnGlobalIndex( int index, Func function ) - { - this.EnsureProtectedVirtualItems(); - - if( this.IsBottomLevel ) - { - return function( index, this ); - } - else - { - // The Count property of the virtualItems collection will return the sub-group count since this is not the bottom level. - int count = m_protectedVirtualItems.Count; - - for( int i = 0; i < count; i++ ) - { - DataGridVirtualizingCollectionViewGroupBase subGroup = m_protectedVirtualItems[ i ] as DataGridVirtualizingCollectionViewGroupBase; - - if( subGroup == null ) - throw new InvalidOperationException( "Sub-group cannot be null (Nothing in Visual Basic)." ); - - // VirtualItemCount will return the sum of data items contained in this group and its possible subgroups. - int subGroupItemCount = subGroup.VirtualItemCount; - - if( index < subGroupItemCount ) - return subGroup.OperateOnGlobalIndex( index, function ); - - index -= subGroupItemCount; - } - } - - throw new ArgumentOutOfRangeException( "index" ); - } - - private void OnVirtualItemListCollectionChanged( object sender, NotifyCollectionChangedEventArgs e ) - { - DataGridVirtualizingCollectionViewBase collectionView = this.GetCollectionView(); - - lock( collectionView.DeferredOperationManager ) - { - DeferredOperation deferredOperation = null; - - switch( e.Action ) - { - case NotifyCollectionChangedAction.Replace: - { - deferredOperation = new DeferredOperation( DeferredOperation.DeferredOperationAction.Replace, -1, e.NewStartingIndex + m_startGlobalIndex, - e.NewItems, e.OldStartingIndex + m_startGlobalIndex, e.OldItems ); - break; - } - - case NotifyCollectionChangedAction.Reset: - { - deferredOperation = new DeferredOperation( DeferredOperation.DeferredOperationAction.Refresh, -1, null ); - break; - } - - default: - throw new NotSupportedException( e.Action.ToString() + " is not a supported action." ); - } - - if( deferredOperation != null ) - { - collectionView.ExecuteOrQueueSourceItemOperation( deferredOperation ); - } - } - } - - #region IWeakEventListener Members - - 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( managerType == typeof( CollectionChangedEventManager ) ) - { - this.OnVirtualItemListCollectionChanged( sender, ( NotifyCollectionChangedEventArgs )e ); - return true; - } - - return false; - } - - #endregion IWeakEventListener Members - - #region IDisposable Members - - public void Dispose() - { - this.DisposeCore(); - } - - #endregion - - private bool m_isBottomLevel; - private int m_level; - - private int m_startGlobalIndex; - private int m_virtualItemCount; - - private IList m_protectedVirtualItems; - private IList m_virtualItems; - - private DataGridVirtualizingCollectionViewGroupBase m_parent; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingCollectionViewGroupRoot.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingCollectionViewGroupRoot.cs deleted file mode 100644 index 23038be3..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingCollectionViewGroupRoot.cs +++ /dev/null @@ -1,54 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -namespace Xceed.Wpf.DataGrid -{ - internal class DataGridVirtualizingCollectionViewGroupRoot : DataGridVirtualizingCollectionViewGroup - { - internal DataGridVirtualizingCollectionViewGroupRoot( DataGridVirtualizingCollectionView collectionView, bool isBottomLevel ) - : base( null, -1, 0, null, -1, isBottomLevel ) - { - m_parentCollectionView = collectionView; - m_virtualPageManager = new DataGridPageManager( collectionView ); - } - - protected override DataGridVirtualizingCollectionViewBase GetCollectionView() - { - return m_parentCollectionView; - } - - internal override int GetGlobalIndexOf( object item ) - { - return m_virtualPageManager.GetGlobalIndexOf( item ); - } - - internal override DataGridPageManagerBase GetVirtualPageManager() - { - return m_virtualPageManager; - } - - internal override void DisposeCore() - { - m_parentCollectionView = null; - m_virtualPageManager = null; - base.DisposeCore(); - } - - private DataGridVirtualizingCollectionView m_parentCollectionView; - private DataGridPageManager m_virtualPageManager; - } - -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingCollectionViewSource.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingCollectionViewSource.cs deleted file mode 100644 index 52a9e952..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingCollectionViewSource.cs +++ /dev/null @@ -1,87 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows.Data; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - public class DataGridVirtualizingCollectionViewSource : DataGridVirtualizingCollectionViewSourceBase - { - #region CONSTRUCTORS - - static DataGridVirtualizingCollectionViewSource() - { - CollectionViewSource.CollectionViewTypeProperty.OverrideMetadata( - typeof( DataGridVirtualizingCollectionViewSource ), - new FrameworkPropertyMetadata( typeof( DataGridVirtualizingCollectionView ) ) ); - } - - public DataGridVirtualizingCollectionViewSource() - : base() - { - } - - #endregion CONSTRUCTORS - - #region DATA VIRTUALIZATION EVENTS - - public event EventHandler QueryItemCount; - - internal void OnQueryItemCount( QueryItemCountEventArgs e ) - { - if( this.QueryItemCount != null ) - this.QueryItemCount( this, e ); - } - - public event EventHandler QueryGroups; - - internal void OnQueryGroups( QueryGroupsEventArgs e ) - { - if( this.QueryGroups != null ) - this.QueryGroups( this, e ); - } - - public event EventHandler AbortQueryItems; - - internal void OnAbortQueryItems( QueryItemsEventArgs e ) - { - if( this.AbortQueryItems != null ) - this.AbortQueryItems( this, e ); - } - - public event EventHandler QueryItems; - - internal void OnQueryItems( QueryItemsEventArgs e ) - { - if( this.QueryItems != null ) - this.QueryItems( this, e ); - } - - #endregion DATA VIRTUALIZATION EVENTS - - - internal override DataGridCollectionViewBaseDataProvider CreateDataProvider() - { - return new DataGridVirtualizingCollectionViewDataProvider( this ); - } - - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingCollectionViewSourceBase.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingCollectionViewSourceBase.cs deleted file mode 100644 index eba1b266..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingCollectionViewSourceBase.cs +++ /dev/null @@ -1,164 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - public abstract class DataGridVirtualizingCollectionViewSourceBase : DataGridCollectionViewSourceBase - { - public DataGridVirtualizingCollectionViewSourceBase() - { - this.Source = null; - - m_isInitialized = true; - this.DataSourceProvider.DelayRefresh( this.Dispatcher, System.Windows.Threading.DispatcherPriority.DataBind ); - } - - #region PageSize Property - - public static readonly DependencyProperty PageSizeProperty = DependencyProperty.Register( - "PageSize", typeof( int ), typeof( DataGridVirtualizingCollectionViewSourceBase ), - new UIPropertyMetadata( DataGridVirtualizingCollectionViewBase.DefaultPageSize ) ); - - public int PageSize - { - get - { - return ( int )this.GetValue( DataGridVirtualizingCollectionViewSourceBase.PageSizeProperty ); - } - set - { - this.SetValue( DataGridVirtualizingCollectionViewSourceBase.PageSizeProperty, value ); - - if( this.DataSourceProvider != null ) - this.DataSourceProvider.DelayRefresh( this.Dispatcher, System.Windows.Threading.DispatcherPriority.DataBind ); - } - } - - #endregion PageSize Property - - #region MaxRealizedItemCount - - public static readonly DependencyProperty MaxRealizedItemCountProperty = DependencyProperty.Register( - "MaxRealizedItemCount", typeof( int ), typeof( DataGridVirtualizingCollectionViewSourceBase ), - new UIPropertyMetadata( DataGridVirtualizingCollectionViewBase.DefaultMaxRealizedItemCount ) ); - - public int MaxRealizedItemCount - { - get - { - return ( int )GetValue( DataGridVirtualizingCollectionViewSourceBase.MaxRealizedItemCountProperty ); - } - set - { - this.SetValue( DataGridVirtualizingCollectionViewSourceBase.MaxRealizedItemCountProperty, value ); - - if( this.DataSourceProvider != null ) - this.DataSourceProvider.DelayRefresh( this.Dispatcher, System.Windows.Threading.DispatcherPriority.DataBind ); - } - } - - #endregion MaxRealizedItemCount - - #region PreemptivePageQueryRatio - - public static readonly DependencyProperty PreemptivePageQueryRatioProperty = DependencyProperty.Register( - "PreemptivePageQueryRatio", typeof( double ), typeof( DataGridVirtualizingCollectionViewSourceBase ), - new UIPropertyMetadata( DataGridVirtualizingCollectionViewBase.DefaultPreemptivePageQueryRatio, - new PropertyChangedCallback( DataGridCollectionViewSourceBase.OnDataGridCollectionViewSourceBaseDependencyPropertyChanged ) ) ); - - public double PreemptivePageQueryRatio - { - get - { - return ( double )GetValue( DataGridVirtualizingCollectionViewSourceBase.PreemptivePageQueryRatioProperty ); - } - set - { - this.SetValue( DataGridVirtualizingCollectionViewSourceBase.PreemptivePageQueryRatioProperty, value ); - } - } - - #endregion PreemptivePageQueryRatio - - #region CommitMode - - public static readonly DependencyProperty CommitModeProperty = DependencyProperty.Register( - "CommitMode", typeof( CommitMode ), typeof( DataGridVirtualizingCollectionViewSourceBase ), - new UIPropertyMetadata( CommitMode.PageReleasedFromMemory, - new PropertyChangedCallback( DataGridCollectionViewSourceBase.OnDataGridCollectionViewSourceBaseDependencyPropertyChanged ) ) ); - - public CommitMode CommitMode - { - get - { - return ( CommitMode )GetValue( DataGridVirtualizingCollectionViewSourceBase.CommitModeProperty ); - } - set - { - this.SetValue( DataGridVirtualizingCollectionViewSourceBase.CommitModeProperty, value ); - } - } - - #endregion CommitMode - - #region DATA VIRTUALIZATION EVENTS - - public event EventHandler CommitItems; - - internal void OnCommitItems( CommitItemsEventArgs e ) - { - if( this.CommitItems != null ) - this.CommitItems( this, e ); - } - - #endregion DATA VIRTUALIZATION EVENTS - - #region INTERNAL PROPERTIES - - internal bool IsInitialized - { - get - { - return m_isInitialized; - } - } - - #endregion INTERNAL PROPERTIES - - #region INTERNAL METHODS - - internal override void ApplyExtraPropertiesToView( DataGridCollectionViewBase currentView ) - { - base.ApplyExtraPropertiesToView( currentView ); - - DataGridVirtualizingCollectionViewBase dataGridVirtualizingCollectionView = currentView as DataGridVirtualizingCollectionViewBase; - - dataGridVirtualizingCollectionView.PreemptivePageQueryRatio = this.PreemptivePageQueryRatio; - dataGridVirtualizingCollectionView.CommitMode = this.CommitMode; - } - - #endregion INTERNAL METHODS - - #region PRIVATE FIELDS - - private bool m_isInitialized; - - #endregion PRIVATE FIELDS - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingQueryableCollectionView.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingQueryableCollectionView.cs deleted file mode 100644 index 9f9f979c..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingQueryableCollectionView.cs +++ /dev/null @@ -1,77 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using Xceed.Utils.Collections; - -namespace Xceed.Wpf.DataGrid -{ - public sealed class DataGridVirtualizingQueryableCollectionView : DataGridVirtualizingCollectionViewBase - { - public DataGridVirtualizingQueryableCollectionView() - : this( null, true, DataGridVirtualizingCollectionViewBase.DefaultPageSize, DataGridVirtualizingCollectionViewBase.DefaultMaxRealizedItemCount ) - { - } - - public DataGridVirtualizingQueryableCollectionView( IQueryable queryableSource ) - : this( queryableSource, true, DataGridVirtualizingCollectionViewBase.DefaultPageSize, DataGridVirtualizingCollectionViewBase.DefaultMaxRealizedItemCount ) - { - } - - public DataGridVirtualizingQueryableCollectionView( IQueryable queryableSource, bool autoCreateItemProperties, int pageSize, int maxRealizedItemCount ) - : base( queryableSource, null, autoCreateItemProperties, pageSize, maxRealizedItemCount ) - { - m_pageManagerSyncRoot = new object(); - } - - #region QueryableSource PROPERTY - - public IQueryable QueryableSource - { - get - { - return this.ModelSource as IQueryable; - } - } - - #endregion QueryableSource PROPERTY - - #region INTERNAL METHODS - - internal override DataGridVirtualizingCollectionViewGroupBase CreateNewRootGroup() - { - bool rootIsBottomLevel = ( this.GroupDescriptions == null ) ? true : ( this.GroupDescriptions.Count == 0 ); - - return new DataGridVirtualizingQueryableCollectionViewGroupRoot( this, m_pageManagerSyncRoot, rootIsBottomLevel ); - } - - internal override System.Collections.IEnumerator GetVirtualEnumerator() - { - return ( ( DataGridVirtualizingQueryableCollectionViewGroupRoot )this.RootGroup ).GetVirtualPageManager().GetEnumerator(); - } - - #endregion - - #region PRIVATE FIELDS - - private object m_pageManagerSyncRoot; - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingQueryableCollectionViewDataProvider.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingQueryableCollectionViewDataProvider.cs deleted file mode 100644 index d1fde7e8..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingQueryableCollectionViewDataProvider.cs +++ /dev/null @@ -1,54 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - internal class DataGridVirtualizingQueryableCollectionViewDataProvider : DataGridCollectionViewBaseDataProvider - { - #region CONSTRUCTORS - - public DataGridVirtualizingQueryableCollectionViewDataProvider( DataGridVirtualizingQueryableCollectionViewSource parentSource ) - : base( parentSource ) - { - } - - #endregion CONSTRUCTORS - - #region INTERNAL METHODS - - internal override DataGridCollectionViewBase EnsureDataGridCollectionViewBaseCore() - { - DataGridVirtualizingQueryableCollectionViewSource parentSource = this.ParentSource as DataGridVirtualizingQueryableCollectionViewSource; - - if( !parentSource.IsInitialized ) - return null; - - return new DataGridVirtualizingQueryableCollectionView( - parentSource.QueryableSource, - parentSource.AutoCreateItemProperties, - parentSource.PageSize, - parentSource.MaxRealizedItemCount ); - } - - #endregion INTERNAL METHODS - } - -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingQueryableCollectionViewGroup.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingQueryableCollectionViewGroup.cs deleted file mode 100644 index 4a575760..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingQueryableCollectionViewGroup.cs +++ /dev/null @@ -1,283 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.Diagnostics; -using System.Linq.Expressions; - -namespace Xceed.Wpf.DataGrid -{ - internal class DataGridVirtualizingQueryableCollectionViewGroup : DataGridVirtualizingCollectionViewGroupBase - { - #region CONSTRUCTORS - - public DataGridVirtualizingQueryableCollectionViewGroup( - object name, - int initialItemsCount, - int startGlobalIndex, - DataGridVirtualizingQueryableCollectionViewGroup parent, - int level, - bool isBottomLevel ) - : base( name, initialItemsCount, startGlobalIndex, parent, level, isBottomLevel ) - { - } - - #endregion CONSTRUCTORS - - #region INTERNAL PROPERTIES - - internal IQueryable UnsortedFilteredQueryable - { - get - { - if( m_unsortedFilteredQueryable == null ) - m_unsortedFilteredQueryable = this.CreateUnsortedFilteredQueryable(); - - return m_unsortedFilteredQueryable; - } - } - - internal IQueryable Queryable - { - get - { - if( m_selectQueryable == null ) - m_selectQueryable = this.CreateSelectQueryable( false ); - - return m_selectQueryable; - } - } - - internal IQueryable ReversedQueryable - { - get - { - if( m_reversedSelectQueryable == null ) - m_reversedSelectQueryable = this.CreateSelectQueryable( true ); - - return m_reversedSelectQueryable; - } - } - - #endregion INTERNAL PROPERTIES - - #region INTERNAL METHODS - - internal override int QueryItemCount() - { - if( this.UnsortedFilteredQueryable != null ) - { - try - { - return this.UnsortedFilteredQueryable.Count(); - } - catch - { - // Timeout or other error occured. - } - } - - return 0; - } - - internal override ObservableCollection QuerySubCollectionViewGroupList( GroupDescription childGroupBy, int nextLevel, bool nextLevelIsBottom ) - { - string childGroupByPropertyName = DataGridCollectionViewBase.GetPropertyNameFromGroupDescription( childGroupBy ); - - if( String.IsNullOrEmpty( childGroupByPropertyName ) ) - throw new NotSupportedException( "Custom groups are not supported when using a DataGridVirtualizingQueryableCollectionView." ); - - DataGridVirtualizingCollectionViewBase collectionView = this.GetCollectionView(); - - bool sortGroupBy = false; - ListSortDirection groupByDirection = ListSortDirection.Ascending; - - foreach( SortDescription sortDescription in collectionView.SortDescriptions ) - { - if( sortDescription.PropertyName == childGroupByPropertyName ) - { - sortGroupBy = true; - groupByDirection = sortDescription.Direction; - break; - } - } - - IQueryable groupsAndCountsQueryable = this.Queryable.GetSubGroupsAndCountsQueryable( childGroupByPropertyName, sortGroupBy, groupByDirection ); - - List distinctValuesAndCounts = new List(); - try - { - System.Collections.IEnumerator enumerator = groupsAndCountsQueryable.GetEnumerator(); - - while( enumerator.MoveNext() ) - { - QueryableExtensions.IQueryableGroupNameCountPair current = enumerator.Current as QueryableExtensions.IQueryableGroupNameCountPair; - - if( current != null ) - distinctValuesAndCounts.Add( current ); - } - } - catch - { - // TimeOut exception on the connection or other. - distinctValuesAndCounts.Clear(); - } - - - // If we are not the bottom level, we should have subgroups. - // However, if the connection timed out and the catch statement set the coundAndDistinctValues to an empty array, - // then we shouldn't add anything. We cannot reset on the spot since we might already be resetting. - - - // Create the collection of sub CollectionViewGroups - ObservableCollection subCollectionViewGroupList = new ObservableCollection(); - - int runningCount = this.StartGlobalIndex; - int distinctValuesCount = distinctValuesAndCounts.Count; - for( int i = 0; i < distinctValuesCount; i++ ) - { - QueryableExtensions.IQueryableGroupNameCountPair queryableGroupNameCountPair = distinctValuesAndCounts[ i ]; - - subCollectionViewGroupList.Add( - new DataGridVirtualizingQueryableCollectionViewGroup( queryableGroupNameCountPair.GroupName, queryableGroupNameCountPair.Count, runningCount, this, nextLevel, nextLevelIsBottom ) ); - - runningCount += queryableGroupNameCountPair.Count; - } - - return subCollectionViewGroupList; - } - - internal virtual IQueryable CreateUnsortedFilteredQueryable() - { - int level = this.Level; - - Debug.Assert( ( level > -1 ), "The DataGridVirtualizingGroupRoot should have overriden this method without calling base." ); - - // Sub group. Only group from parent, which will already be sorted. - DataGridVirtualizingQueryableCollectionViewGroup parentCollectionViewGroup = this.Parent as DataGridVirtualizingQueryableCollectionViewGroup; - - IQueryable parentUnsortedQueryable = parentCollectionViewGroup.UnsortedFilteredQueryable; - - Debug.Assert( parentUnsortedQueryable != null ); - - if( parentUnsortedQueryable == null ) - return null; - - // Narrow the filter to this group's clauses. - return this.FilterQueryable( parentUnsortedQueryable ); - } - - internal IQueryable CreateSelectQueryable( bool reversed ) - { - // Sub group. Only group from parent. The sorting will be appended just before the Slice statement. - IQueryable queryable = this.UnsortedFilteredQueryable; - - return this.SortQueryable( queryable, reversed ); - } - - internal override void DisposeCore() - { - m_unsortedFilteredQueryable = null; - m_reversedSelectQueryable = null; - m_selectQueryable = null; - base.DisposeCore(); - } - - #endregion INTERNAL METHODS - - #region PRIVATE METHODS - - private IQueryable FilterQueryable( IQueryable queryable ) - { - // Filters a queryable to match this Group's clause. - // This method does not apply the AutoFilter clauses or the FilterRow clauses. - // It is the DataGridVirtualizingQueryableCollectionViewGroupRoot's job to do so on the - // base queryable used as a base for all other queryables. - - if( queryable == null ) - throw new ArgumentNullException( "queryable" ); - - int level = this.Level; - - DataGridVirtualizingCollectionViewBase collectionView = this.GetCollectionView(); - - ObservableCollection groupDescriptions = collectionView.GroupDescriptions; - - Debug.Assert( ( groupDescriptions != null ) && ( level < groupDescriptions.Count ) ); - - DataGridGroupDescription groupBy = groupDescriptions[ level ] as DataGridGroupDescription; - - Debug.Assert( groupBy != null ); - - ParameterExpression sharedParameterExpression = queryable.CreateParameterExpression(); - - Expression expression = queryable.CreateEqualExpression( sharedParameterExpression, groupBy.PropertyName, this.Name ); - return queryable.WhereFilter( sharedParameterExpression, expression ); - } - - private IQueryable SortQueryable( IQueryable queryable, bool reverseSort ) - { - DataGridVirtualizingCollectionViewBase parentCollectionView = this.GetCollectionView(); - - Debug.Assert( parentCollectionView != null ); - - SortDescriptionCollection explicitSortDescriptions = parentCollectionView.SortDescriptions; - - ListSortDirection directionToUseForImplicitSortDescriptions = ListSortDirection.Ascending; - - if( explicitSortDescriptions.Count > 0 ) - directionToUseForImplicitSortDescriptions = explicitSortDescriptions[ explicitSortDescriptions.Count - 1 ].Direction; - - SortDescriptionCollection implicitSortDescriptions = new SortDescriptionCollection(); - - DataGridVirtualizingQueryableCollectionViewGroupRoot groupRoot = - parentCollectionView.RootGroup as DataGridVirtualizingQueryableCollectionViewGroupRoot; - - Debug.Assert( groupRoot != null ); - - string[] primaryKeys = groupRoot.PrimaryKeys; - - if( primaryKeys != null ) - { - for( int i = 0; i < primaryKeys.Length; i++ ) - { - string primaryKey = primaryKeys[ i ]; - - Debug.Assert( !string.IsNullOrEmpty( primaryKey ) ); - - implicitSortDescriptions.Add( new SortDescription( primaryKey, directionToUseForImplicitSortDescriptions ) ); - } - } - - return queryable.OrderBy( implicitSortDescriptions, explicitSortDescriptions, reverseSort ); - } - - #endregion PRIVATE METHODS - - #region PRIVATE FIELDS - - private IQueryable m_unsortedFilteredQueryable; - private IQueryable m_selectQueryable; - private IQueryable m_reversedSelectQueryable; - - #endregion PRIVATE FIELDS - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingQueryableCollectionViewGroupRoot.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingQueryableCollectionViewGroupRoot.cs deleted file mode 100644 index 44c4c1f3..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingQueryableCollectionViewGroupRoot.cs +++ /dev/null @@ -1,146 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Diagnostics; -using System.ComponentModel; -using System.Collections; -using System.Linq.Expressions; - -namespace Xceed.Wpf.DataGrid -{ - internal class DataGridVirtualizingQueryableCollectionViewGroupRoot : DataGridVirtualizingQueryableCollectionViewGroup - { - #region CONSTRUCTORS - - internal DataGridVirtualizingQueryableCollectionViewGroupRoot( - DataGridVirtualizingQueryableCollectionView collectionView, - object pageManagerSyncRoot, - bool isBottomLevel ) - : base( null, -1, 0, null, -1, isBottomLevel ) - { - m_parentCollectionView = collectionView; - m_queryableSource = m_parentCollectionView.QueryableSource; - - if( m_queryableSource != null ) - { - m_primaryKeyPropertyNames = m_queryableSource.FindPrimaryKeys(); - // Primary key optimizations are only possible when only one primary key is identified in the source. - // When dealing with sources defining more than one primary key, we would need to know in which order - bool supportsPrimaryKeyOptimizations = ( ( m_primaryKeyPropertyNames != null ) && ( m_primaryKeyPropertyNames.Length == 1 ) ); - - m_virtualPageManager = new DataGridLINQPageManager( collectionView, - pageManagerSyncRoot, - supportsPrimaryKeyOptimizations ); - } - } - - - #endregion CONSTRUCTORS - - #region PROTECTED METHODS - - protected override DataGridVirtualizingCollectionViewBase GetCollectionView() - { - return m_parentCollectionView; - } - - #endregion PROTECTED METHODS - - #region INTERNAL PROPERTIES - - public string[] PrimaryKeys - { - get - { - return m_primaryKeyPropertyNames; - } - } - - #endregion INTERNAL PROPERTIES - - #region INTERNAL METHODS - - internal override IQueryable CreateUnsortedFilteredQueryable() - { - return m_queryableSource; - } - - internal override int GetGlobalIndexOf( object item ) - { - return m_virtualPageManager.GetGlobalIndexOf( item ); - } - - internal override DataGridPageManagerBase GetVirtualPageManager() - { - return m_virtualPageManager; - } - - internal object[] GetItemPropertyDistinctValues( DataGridItemPropertyBase dataGridItemProperty ) - { - if( m_queryableSource == null ) - return new object[ 0 ]; - - IQueryable distinctQueryable = m_queryableSource.GetSubGroupsAndCountsQueryable( dataGridItemProperty.Name, false, ListSortDirection.Ascending ); - - List distinctValuesAndCounts = new List(); - try - { - System.Collections.IEnumerator enumerator = distinctQueryable.GetEnumerator(); - - while( enumerator.MoveNext() ) - { - QueryableExtensions.IQueryableGroupNameCountPair current = enumerator.Current as QueryableExtensions.IQueryableGroupNameCountPair; - - if( current != null ) - distinctValuesAndCounts.Add( current.GroupName ); - } - - return distinctValuesAndCounts.ToArray(); - } - catch - { - // TimeOut exception on the connection or other. - return new object[ 0 ]; - } - } - - internal override void DisposeCore() - { - m_parentCollectionView = null; - m_queryableSource = null; - m_virtualPageManager = null; - base.DisposeCore(); - } - - #endregion INTERNAL METHODS - - #region PRIVATE FIELDS - - private DataGridVirtualizingQueryableCollectionView m_parentCollectionView; - - private IQueryable m_queryableSource; - - private string[] m_primaryKeyPropertyNames; - - private DataGridLINQPageManager m_virtualPageManager; - - #endregion PRIVATE FIELDS - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingQueryableCollectionViewSource.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingQueryableCollectionViewSource.cs deleted file mode 100644 index 42fb6592..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataGridVirtualizingQueryableCollectionViewSource.cs +++ /dev/null @@ -1,77 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Linq; -using System.Windows; -using System.Windows.Data; -using System.Windows.Threading; - -namespace Xceed.Wpf.DataGrid -{ - public class DataGridVirtualizingQueryableCollectionViewSource : DataGridVirtualizingCollectionViewSourceBase - { - static DataGridVirtualizingQueryableCollectionViewSource() - { - CollectionViewSource.CollectionViewTypeProperty.OverrideMetadata( - typeof( DataGridVirtualizingQueryableCollectionViewSource ), - new FrameworkPropertyMetadata( typeof( DataGridVirtualizingQueryableCollectionView ) ) ); - } - - #region QueryableSource Property - - public static readonly DependencyProperty QueryableSourceProperty = DependencyProperty.Register( - "QueryableSource", - typeof( IQueryable ), - typeof( DataGridVirtualizingQueryableCollectionViewSource ), - new FrameworkPropertyMetadata( - null, - new PropertyChangedCallback( DataGridVirtualizingQueryableCollectionViewSource.OnQueryableSourcePropertyChanged ) ) ); - - public IQueryable QueryableSource - { - get - { - return ( IQueryable )GetValue( DataGridVirtualizingQueryableCollectionViewSource.QueryableSourceProperty ); - } - set - { - this.SetValue( DataGridVirtualizingQueryableCollectionViewSource.QueryableSourceProperty, value ); - } - } - - private static void OnQueryableSourcePropertyChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var source = sender as DataGridCollectionViewSourceBase; - if( source == null ) - return; - - source.AdviseForwardedPropertyChanged(); - - var provider = source.DataSourceProvider; - if( provider != null ) - { - provider.DelayRefresh( source.Dispatcher, DispatcherPriority.DataBind ); - } - } - - #endregion - - internal override DataGridCollectionViewBaseDataProvider CreateDataProvider() - { - return new DataGridVirtualizingQueryableCollectionViewDataProvider( this ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataRelationDetailDescription.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataRelationDetailDescription.cs deleted file mode 100644 index 5fc2db7b..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataRelationDetailDescription.cs +++ /dev/null @@ -1,141 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Data; - -namespace Xceed.Wpf.DataGrid -{ - internal class DataRelationDetailDescription : DataGridDetailDescription - { - public DataRelationDetailDescription() - : base() - { - } - - public DataRelationDetailDescription( DataRelation relation ) - : this() - { - if( relation == null ) - throw new ArgumentNullException( "relation" ); - - this.DataRelation = relation; - m_userAssignedDataRelation = true; - } - - #region DataRelation Property - - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly" )] - public DataRelation DataRelation - { - get - { - return m_dataRelation; - } - set - { - if( value == null ) - throw new ArgumentNullException( "DataRelation" ); - - if( this.InternalIsSealed ) - throw new InvalidOperationException( "An attempt was made to set the DataRelation property after the DataRelationDetailDescription has been sealed." ); - - m_dataRelation = value; - this.RelationName = value.RelationName; - this.Seal(); - } - } - - #endregion - - protected internal override void Initialize( DataGridCollectionViewBase parentCollectionView ) - { - base.Initialize( parentCollectionView ); - - if( this.DataRelation != null ) - return; - - string relationName = this.RelationName; - - if( string.IsNullOrEmpty( relationName ) ) - throw new InvalidOperationException( "An attempt was made to initialize a DataRelationDetailDescription whose RelationName property has not been set." ); - - this.DataRelation = this.FindDataRelation( parentCollectionView, relationName ); - } - - protected internal override IEnumerable GetDetailsForParentItem( DataGridCollectionViewBase parentCollectionView, object parentItem ) - { - if( this.DataRelation == null ) - throw new InvalidOperationException( "An attempt was made to obtain the details of a DataRelationDetailDescription object whose DataRelation property has not been set." ); - - this.Seal(); - - System.Data.DataRow dataRow = parentItem as System.Data.DataRow; - DataRowView dataRowView; - - if( dataRow != null ) - { - int rawIndex = parentCollectionView.IndexOfSourceItem( dataRow ); - - DataView dataView = parentCollectionView.SourceCollection as DataView; - - if( dataView == null ) - return null; - - dataRowView = dataView[ rawIndex ]; - } - else - { - dataRowView = parentItem as DataRowView; - } - - if( dataRowView == null ) - return null; - - if( !m_userAssignedDataRelation ) - { - if( m_dataRelation.ParentTable != dataRowView.Row.Table ) - { - m_dataRelation = this.FindDataRelation( parentCollectionView, this.RelationName ); - } - } - - return dataRowView.CreateChildView( m_dataRelation ); - } - - private DataRelation FindDataRelation( DataGridCollectionViewBase parentCollectionView, string relationName ) - { - DataView view = parentCollectionView.SourceCollection as DataView; - - if( view == null ) - throw new InvalidOperationException( "An attempt was made to initialize a DataRelationDetailDescription whose data source is not a DataView." ); - - foreach( DataRelation relation in view.Table.ChildRelations ) - { - if( relation.RelationName == relationName ) - { - return relation; - } - } - - throw new InvalidOperationException( "An attempt was made to initialize a DataRelationDetailDescription whose data source does not contain a DataRelation corresponding to the specified name." ); - } - - private DataRelation m_dataRelation; - private bool m_userAssignedDataRelation; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataRowColumnPropertyDescriptor.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataRowColumnPropertyDescriptor.cs deleted file mode 100644 index 2abf397e..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DataRowColumnPropertyDescriptor.cs +++ /dev/null @@ -1,192 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.ComponentModel; -using System.Data; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class DataRowColumnPropertyDescriptor : PropertyDescriptor - { - internal DataRowColumnPropertyDescriptor( DataColumn column ) - : base( column.ColumnName, null ) - { - if( column == null ) - throw new ArgumentNullException( "column" ); - - m_column = column; - } - - #region DisplayName Property - - public override string DisplayName - { - get - { - return m_column.Caption; - } - } - - #endregion - - #region Attributes Property - - public override AttributeCollection Attributes - { - get - { - if( typeof( IList ).IsAssignableFrom( this.PropertyType ) ) - { - var array = new Attribute[ base.Attributes.Count + 1 ]; - base.Attributes.CopyTo( array, 0 ); - array[ array.Length - 1 ] = new ListBindableAttribute( false ); - return new AttributeCollection( array ); - } - - return base.Attributes; - } - } - - #endregion - - #region ComponentType Property - - public override Type ComponentType - { - get - { - return typeof( System.Data.DataRow ); - } - } - - #endregion - - #region IsBrowsable Property - - public override bool IsBrowsable - { - get - { - return ( m_column.ColumnMapping != MappingType.Hidden ) - && ( base.IsBrowsable ); - } - } - - #endregion - - #region IsReadOnly Property - - public override bool IsReadOnly - { - get - { - return m_column.ReadOnly; - } - } - - #endregion - - #region PropertyType Property - - public override Type PropertyType - { - get - { - return ItemsSourceHelper.GetColumnDataType( m_column ); - } - } - - #endregion - - public override bool CanResetValue( object component ) - { - var value = this.GetValue( component ); - - return ( value != null ) - && ( value != DBNull.Value ); - } - - public override object GetValue( object component ) - { - var dataRow = component as System.Data.DataRow; - if( dataRow == null ) - return null; - - var value = default( object ); - - try - { - value = dataRow[ m_column ]; - } - catch - { - } - - if( value == DBNull.Value ) - return null; - - return value; - } - - public override void ResetValue( object component ) - { - this.SetValue( component, null ); - } - - public override void SetValue( object component, object value ) - { - var dataRow = component as System.Data.DataRow; - if( dataRow == null ) - throw new InvalidOperationException( "An attempt was made to set a value on a DataRow that does not exist." ); - - if( this.IsReadOnly ) - throw new InvalidOperationException( "An attempt was made to set a value on a read-only field." ); - - var oldValue = dataRow[ m_column ]; - - if( ( oldValue == null ) || ( oldValue == DBNull.Value ) ) - { - if( ( ( value == null ) || ( value == DBNull.Value ) ) ) - return; - } - else - { - if( oldValue.Equals( value ) ) - return; - } - - if( value == null ) - { - dataRow[ m_column ] = DBNull.Value; - } - else - { - dataRow[ m_column ] = value; - } - - this.OnValueChanged( component, EventArgs.Empty ); - } - - public override bool ShouldSerializeValue( object component ) - { - return false; - } - - private readonly DataColumn m_column; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DeferredOperation.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DeferredOperation.cs deleted file mode 100644 index f6694682..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DeferredOperation.cs +++ /dev/null @@ -1,229 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - internal class DeferredOperation - { - internal static DeferredOperation RefreshDistinctValuesOperation = new DeferredOperation( DeferredOperationAction.RefreshDistincValues, false ); - - internal static DeferredOperation RefreshDistinctValuesOperationWithFilteredItemsChanged = new DeferredOperation( DeferredOperationAction.RefreshDistincValues, true ); - - public DeferredOperation( DeferredOperationAction action, bool filteredItemsChanged ) - : this( action, -1, -1, null ) - { - m_filteredItemsChanged = filteredItemsChanged; - } - - public DeferredOperation( DeferredOperationAction action, object dataItem ) - { - m_action = action; - m_dataItem = dataItem; - } - - public DeferredOperation( DeferredOperationAction action, IList items ) - { - m_action = action; - m_newItems = items; - } - - public DeferredOperation( DeferredOperationAction action, int startingIndex, IList items ) - : this( action, -1, startingIndex, items ) - { - } - - public DeferredOperation( DeferredOperationAction action, int newSourceItemCount, int startingIndex, IList items ) - { - // newSourceItemCount is for when we are adding item in a IBindingList - // It is use to detect we 2 add are in fact only one, bcause the second one is just for confirming the first one. - m_action = action; - m_newSourceItemCount = newSourceItemCount; - - switch( action ) - { - case DeferredOperationAction.Add: - case DeferredOperationAction.Replace: - { - m_newItems = items; - m_newStartingIndex = startingIndex; - break; - } - - case DeferredOperationAction.Remove: - { - m_oldItems = items; - m_oldStartingIndex = startingIndex; - break; - } - - case DeferredOperationAction.Refresh: - case DeferredOperationAction.Resort: - case DeferredOperationAction.Regroup: - case DeferredOperationAction.RefreshDistincValues: - break; - - default: - { - throw new ArgumentException( "An attempt was made to use the " + action.ToString() + " action, which is not supported by this constructor." ); - } - } - } - - public DeferredOperation( DeferredOperationAction action, int newSourceItemCount, int newStartingIndex, IList newItems, int oldStartingIndex, IList oldItems ) - { - // newSourceItemCount is for when we are adding item in a IBindingList - // It is use to detect that 2 add are in fact only one, because the second one is just for confirming the first one. - m_action = action; - m_newSourceItemCount = newSourceItemCount; - m_newItems = newItems; - m_newStartingIndex = newStartingIndex; - m_oldItems = oldItems; - m_oldStartingIndex = oldStartingIndex; - } - - #region Action Property - - public DeferredOperationAction Action - { - get - { - return m_action; - } - } - - private DeferredOperationAction m_action; - - #endregion Action Property - - #region NewSourceItemCount Property - - public int NewSourceItemCount - { - get - { - return m_newSourceItemCount; - } - } - - private int m_newSourceItemCount; - - #endregion NewSourceItemCount Property - - #region NewStartingIndex Property - - public int NewStartingIndex - { - get - { - return m_newStartingIndex; - } - } - - private int m_newStartingIndex; - - #endregion NewStartingIndex Property - - #region NewItems Property - - public IList NewItems - { - get - { - return m_newItems; - } - } - - private IList m_newItems; - - #endregion NewItems Property - - #region OldStartingIndex Property - - public int OldStartingIndex - { - get - { - return m_oldStartingIndex; - } - } - - private int m_oldStartingIndex; - - #endregion OldStartingIndex Property - - #region OldItems Property - - public IList OldItems - { - get - { - return m_oldItems; - } - } - - private IList m_oldItems; - - #endregion OldItems Property - - #region DataItem Property - - public object DataItem - { - get - { - return m_dataItem; - } - } - - private object m_dataItem; - - #endregion - - #region FilteredItemsChanged Property - - public bool FilteredItemsChanged - { - get - { - return m_filteredItemsChanged; - } - } - - private bool m_filteredItemsChanged; - - #endregion FilteredItemsChanged Property - - internal enum DeferredOperationAction - { - Unknow = 0, - Add = 1, - Move = 2, - Remove = 3, - Replace = 4, - Refresh = 5, - Resort = 6, - Regroup = 7, - RefreshDistincValues = 8, - ResetItem = 9, - RefreshUnboundItemProperties = 10 - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DeferredOperationManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DeferredOperationManager.cs deleted file mode 100644 index 4db22b8b..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DeferredOperationManager.cs +++ /dev/null @@ -1,599 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Diagnostics; -using System.Windows.Threading; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class DeferredOperationManager - { - #region Static Fields - - private static readonly TimeSpan MaxProcessDuration = TimeSpan.FromMilliseconds( 100d ); - private static readonly TimeSpan MaxQueueDuration = TimeSpan.FromMilliseconds( 20d ); - - #endregion - - internal DeferredOperationManager( DataGridCollectionViewBase collectionView, Dispatcher dispatcher, bool postPendingRefreshWithoutDispatching ) - { - m_collectionView = collectionView; - m_deferredOperations = new List( 1000 ); - m_invalidatedGroups = new HashSet(); - - if( postPendingRefreshWithoutDispatching ) - { - this.Add( new DeferredOperation( DeferredOperation.DeferredOperationAction.Refresh, -1, null ) ); - } - - m_dispatcher = dispatcher; - } - - #region HasPendingOperations Property - - public bool HasPendingOperations - { - get - { - lock( this ) - { - return ( m_pendingFlags.Data != 0 ) || ( m_deferredOperations.Count > 0 ); - } - } - } - - #endregion - - #region RefreshPending Property - - public bool RefreshPending - { - get - { - return m_pendingFlags[ ( int )DeferredOperationManagerPendingFlags.RefreshPending ]; - } - private set - { - m_pendingFlags[ ( int )DeferredOperationManagerPendingFlags.RefreshPending ] = value; - } - } - - #endregion - - #region ResortPending Property - - public bool ResortPending - { - get - { - return m_pendingFlags[ ( int )DeferredOperationManagerPendingFlags.ResortPending ]; - } - private set - { - m_pendingFlags[ ( int )DeferredOperationManagerPendingFlags.ResortPending ] = value; - } - } - - #endregion - - #region RegroupPending Property - - public bool RegroupPending - { - get - { - return m_pendingFlags[ ( int )DeferredOperationManagerPendingFlags.RegroupPending ]; - } - private set - { - m_pendingFlags[ ( int )DeferredOperationManagerPendingFlags.RegroupPending ] = value; - } - } - - #endregion - - #region RefreshDistincValuesPending Property - - public bool RefreshDistincValuesPending - { - get - { - return m_pendingFlags[ ( int )DeferredOperationManagerPendingFlags.RefreshDistincValuesPending ]; - } - private set - { - m_pendingFlags[ ( int )DeferredOperationManagerPendingFlags.RefreshDistincValuesPending ] = value; - } - } - - #endregion - - #region RefreshDistincValuesWithFilteredItemChangedPending Property - - public bool RefreshDistincValuesWithFilteredItemChangedPending - { - get - { - return m_pendingFlags[ ( int )DeferredOperationManagerPendingFlags.RefreshDistincValuesWithFilteredItemChangedPending ]; - } - private set - { - m_pendingFlags[ ( int )DeferredOperationManagerPendingFlags.RefreshDistincValuesWithFilteredItemChangedPending ] = value; - } - } - - #endregion - - #region DeferProcessOfInvalidatedGroupStats Property - - internal bool DeferProcessOfInvalidatedGroupStats - { - private get - { - return m_deferProcessOfInvalidatedGroupStats; - } - set - { - lock( this ) - { - //Make sure that stats calculation that have been defer are processed before defering again! - if( value && ( m_deferredOperationsToProcess > 0 ) ) - { - m_forceProcessOfInvalidatedGroupStats = true; - } - m_deferProcessOfInvalidatedGroupStats = value; - } - } - } - - private bool m_deferProcessOfInvalidatedGroupStats; - - #endregion - - public void ClearInvalidatedGroups() - { - lock( this ) - { - if( ( m_dispatcherOperation != null ) && ( !this.HasPendingOperations ) ) - { - m_dispatcherOperation.Abort(); - m_dispatcherOperation = null; - m_dispatcherOperationStartTime = DateTime.MinValue; - m_hasNewOperationsSinceStartTime = false; - } - - m_invalidatedGroups.Clear(); - } - } - - public void ClearDeferredOperations() - { - lock( this ) - { - if( ( m_dispatcherOperation != null ) && ( m_invalidatedGroups.Count == 0 ) ) - { - m_dispatcherOperation.Abort(); - m_dispatcherOperation = null; - m_dispatcherOperationStartTime = DateTime.MinValue; - m_hasNewOperationsSinceStartTime = false; - } - - m_pendingFlags[ -1 ] = false; - m_deferredOperations.Clear(); - } - } - - public void PurgeAddWithRemoveOrReplace() - { - if( m_deferredOperations.Count >= 2 ) - { - var addOperation = m_deferredOperations[ 0 ]; - - if( addOperation.Action != DeferredOperation.DeferredOperationAction.Add ) - return; - - var addIndex = addOperation.NewStartingIndex; - var addCount = addOperation.NewItems.Count; - - var firstIndexToRemove = 1; - var lastIndexToRemove = -1; - - var count = m_deferredOperations.Count; - for( int i = 1; i < count; i++ ) - { - var operation = m_deferredOperations[ i ]; - - var replaced = ( operation.Action == DeferredOperation.DeferredOperationAction.Replace ); - var removed = ( operation.Action == DeferredOperation.DeferredOperationAction.Remove ); - - if( replaced || removed ) - { - if( removed && ( i < count - 1 ) ) - { - Debug.Fail( "How come we have a remove operation before the end?" ); - return; - } - - if( ( addIndex == operation.OldStartingIndex ) && ( addCount == operation.OldItems.Count ) ) - { - lastIndexToRemove = i; - - if( removed ) - { - firstIndexToRemove = 0; - } - } - else - { - Debug.Fail( "Why do we have a replace or remove operation with different indexes?" ); - return; - } - } - else - { - // Can be normal, we can receive 2 adds for the same item and same position when we are bound to an IBindingList ( like a DataView ) - return; - } - } - - if( lastIndexToRemove > -1 ) - { - m_deferredOperations.RemoveRange( firstIndexToRemove, ( lastIndexToRemove - firstIndexToRemove ) + 1 ); - } - } - } - - public void Add( DeferredOperation operation ) - { - lock( this ) - { - if( this.RefreshPending ) - return; - - switch( operation.Action ) - { - case DeferredOperation.DeferredOperationAction.Refresh: - { - this.RefreshPending = true; - m_deferredOperations.Clear(); - break; - } - - case DeferredOperation.DeferredOperationAction.RefreshDistincValues: - { - if( operation.FilteredItemsChanged ) - { - this.RefreshDistincValuesWithFilteredItemChangedPending = true; - } - else - { - this.RefreshDistincValuesPending = true; - } - - break; - } - - case DeferredOperation.DeferredOperationAction.Regroup: - { - this.RegroupPending = true; - break; - } - - case DeferredOperation.DeferredOperationAction.Resort: - { - this.ResortPending = true; - break; - } - - default: - { - m_deferredOperations.Add( operation ); - m_hasNewOperationsSinceStartTime = true; - - if( this.DeferProcessOfInvalidatedGroupStats ) - { - m_deferredOperationsToProcess++; - } - - break; - } - } - - if( ( m_dispatcher != null ) && ( m_dispatcherOperation == null ) ) - { - Debug.Assert( m_collectionView.Loaded ); - - m_dispatcherOperation = m_dispatcher.BeginInvoke( DispatcherPriority.DataBind, new DispatcherOperationCallback( this.Dispatched_Process ), null ); - m_dispatcherOperationStartTime = DateTime.UtcNow; - m_hasNewOperationsSinceStartTime = false; - } - } - } - - public void Combine( DeferredOperationManager sourceDeferredOperationManager ) - { - lock( this ) - { - this.RefreshPending = this.RefreshPending || sourceDeferredOperationManager.RefreshPending; - this.RegroupPending = this.RegroupPending || sourceDeferredOperationManager.RegroupPending; - this.ResortPending = this.ResortPending || sourceDeferredOperationManager.ResortPending; - this.RefreshDistincValuesPending = this.RefreshDistincValuesPending || sourceDeferredOperationManager.RefreshDistincValuesPending; - this.RefreshDistincValuesWithFilteredItemChangedPending = this.RefreshDistincValuesWithFilteredItemChangedPending || sourceDeferredOperationManager.RefreshDistincValuesWithFilteredItemChangedPending; - - if( this.RefreshPending ) - { - m_deferredOperations.Clear(); - return; - } - - List sourceOperations = sourceDeferredOperationManager.m_deferredOperations; - - if( sourceOperations.Count == 0 ) - return; - - m_deferredOperations.InsertRange( 0, sourceOperations ); - } - } - - public void Process() - { - this.Process( true ); - } - - public void InvalidateGroupStats( DataGridCollectionViewGroup group, bool calculateAllStats = false, bool resortGroups = true ) - { - if( group == null ) - return; - - lock( this ) - { - if( this.RefreshPending ) - return; - - // When set to false, this will prevent group resorting when the DataGridCollectionView.ProcessInvalidatedGroupStats() is called through the disptached call below. - // If the current method is called again and this variable is set to true before groups are processed, it will be fine, as the grid is now in a state that will support group resorting. - m_resortGroups = resortGroups; - - var parent = group; - while( parent != null ) - { - if( !m_invalidatedGroups.Contains( parent ) ) - { - m_invalidatedGroups.Add( parent ); - } - - parent = parent.Parent; - } - - if( m_dispatcher != null ) - { - if( m_dispatcherOperation == null ) - { - m_dispatcherOperation = m_dispatcher.BeginInvoke( DispatcherPriority.DataBind, new DispatcherOperationCallback( this.Dispatched_Process ), null ); - m_dispatcherOperationStartTime = DateTime.UtcNow; - } - else - { - m_hasNewOperationsSinceStartTime = true; - } - } - } - } - - private object Dispatched_Process( object e ) - { - this.Process( false ); - return null; - } - - private void Process( bool processAll ) - { - //This method will be called again when Dispose() is called on the DeferRefreshHelper of the CollectionView. - if( m_collectionView.InDeferRefresh ) - return; - - if( !processAll ) - { - lock( this ) - { - if( ( m_hasNewOperationsSinceStartTime ) - && ( m_dispatcherOperation != null ) - && ( DateTime.UtcNow.Subtract( m_dispatcherOperationStartTime ) < DeferredOperationManager.MaxQueueDuration ) ) - { - Debug.Assert( m_dispatcher != null ); - m_dispatcherOperation = m_dispatcher.BeginInvoke( m_dispatcherOperation.Priority, new DispatcherOperationCallback( this.Dispatched_Process ), null ); - m_hasNewOperationsSinceStartTime = false; - - return; - } - } - } - - // We lock here since it is possible that a DataTable Column's value array is being redimensioned - // while we are trying to process the DeferredOperation. - lock( m_collectionView.SyncRoot ) - { - lock( this ) - { - // Abort the current dispatcher operation - if( m_dispatcherOperation != null ) - { - m_dispatcherOperation.Abort(); - m_dispatcherOperation = null; - m_dispatcherOperationStartTime = DateTime.MinValue; - m_hasNewOperationsSinceStartTime = false; - } - - // A deferredOperation can cause a DeferRefresh to be disposed of, hence provoking a re-entry in this method. - // As a result, all variables must be cached to prevent re-executing the same deferredOperation. - - List deferredOperations = m_deferredOperations; - //Set a new list in case new operations are added while processing the current operations. - m_deferredOperations = new List( 10 ); - bool refreshDistincValuesWithFilteredItemChangedPending = this.RefreshDistincValuesWithFilteredItemChangedPending; - this.RefreshDistincValuesWithFilteredItemChangedPending = false; - bool refreshDistincValuesPending = this.RefreshDistincValuesPending; - this.RefreshDistincValuesPending = false; - bool refreshPending = this.RefreshPending; - this.RefreshPending = false; - bool regroupPending = this.RegroupPending; - this.RegroupPending = false; - bool resortPending = this.ResortPending; - this.ResortPending = false; - bool refreshForced = false; - - m_collectionView.RaisePreBatchCollectionChanged(); - - DateTime startTime = DateTime.UtcNow; - - if( refreshPending ) - { - m_collectionView.ExecuteSourceItemOperation( new DeferredOperation( DeferredOperation.DeferredOperationAction.Refresh, -1, null ), out refreshForced ); - } - else if( regroupPending ) - { - m_collectionView.ExecuteSourceItemOperation( new DeferredOperation( DeferredOperation.DeferredOperationAction.Regroup, -1, null ), out refreshForced ); - } - else if( resortPending ) - { - m_collectionView.ExecuteSourceItemOperation( new DeferredOperation( DeferredOperation.DeferredOperationAction.Resort, -1, null ), out refreshForced ); - } - - if( ( deferredOperations.Count > 0 ) && ( !refreshForced ) ) - { - int count = deferredOperations.Count; - int operationIndex = 0; - - while( ( operationIndex < count ) && ( !refreshForced ) && ( processAll || ( DateTime.UtcNow.Subtract( startTime ) < DeferredOperationManager.MaxProcessDuration ) ) ) - { - m_collectionView.ExecuteSourceItemOperation( deferredOperations[ operationIndex ], out refreshForced ); - operationIndex++; - } - - if( ( operationIndex < count ) && ( !refreshForced ) ) - { - deferredOperations.RemoveRange( 0, operationIndex ); - m_deferredOperationsToProcess -= operationIndex; - } - else - { - deferredOperations.Clear(); - m_deferredOperationsToProcess = 0; - } - } - - if( m_deferredOperations.Count == 0 ) - { - m_deferredOperations = deferredOperations; - } - else - { - // When this method is re-entered, the processAll parameter should be true, which means all deferredOperations should have been processed. When assigning it back to m_deferredOperations, - // it's count should be 0. Thus in the previous call on the stack, the "if" condition should always be true, hence this assert. - Debug.Assert( false, "Should never get there." ); - - //To be GC friendly, keep the original list, which at one point is the one created with a capacity of a 1000 items. - deferredOperations.InsertRange( deferredOperations.Count, m_deferredOperations ); - m_deferredOperations = deferredOperations; - } - - // The recalculation of the StatFunctions is performed last. - if( ( m_deferredOperationsToProcess <= 0 || m_forceProcessOfInvalidatedGroupStats ) && ( m_invalidatedGroups.Count != 0 ) ) - { - m_collectionView.ProcessInvalidatedGroupStats( m_invalidatedGroups, m_resortGroups ); - m_invalidatedGroups.Clear(); - m_forceProcessOfInvalidatedGroupStats = false; - } - - // Since a refresh has been forced, we don't want to process anything else. - if( !refreshForced ) - { - if( processAll || ( DateTime.UtcNow.Subtract( startTime ) < DeferredOperationManager.MaxProcessDuration ) ) - { - if( refreshDistincValuesWithFilteredItemChangedPending || refreshDistincValuesPending ) - { - m_collectionView.ExecuteSourceItemOperation( new DeferredOperation( DeferredOperation.DeferredOperationAction.RefreshDistincValues, - refreshDistincValuesWithFilteredItemChangedPending ), out refreshForced ); - } - } - else - { - if( refreshDistincValuesWithFilteredItemChangedPending ) - { - this.RefreshDistincValuesWithFilteredItemChangedPending = true; - } - - if( refreshDistincValuesPending ) - { - this.RefreshDistincValuesPending = true; - } - } - } - - m_collectionView.RaisePostBatchCollectionChanged(); - - if( this.HasPendingOperations || m_invalidatedGroups.Count != 0 ) - { - Debug.Assert( !processAll ); - Debug.Assert( m_dispatcher != null ); - - // Requeue pending operations - if( m_dispatcherOperation == null ) - { - if( m_dispatcher != null ) - { - m_dispatcherOperation = m_dispatcher.BeginInvoke( DispatcherPriority.Input, new DispatcherOperationCallback( this.Dispatched_Process ), null ); - m_dispatcherOperationStartTime = DateTime.UtcNow; - m_hasNewOperationsSinceStartTime = false; - } - } - else - { - m_dispatcherOperation.Priority = DispatcherPriority.Input; - m_dispatcherOperationStartTime = DateTime.UtcNow; - } - } - } - } - } - - private readonly DataGridCollectionViewBase m_collectionView; - private List m_deferredOperations; - private HashSet m_invalidatedGroups; - private int m_deferredOperationsToProcess; - private BitVector32 m_pendingFlags; - private bool m_forceProcessOfInvalidatedGroupStats; - private bool m_resortGroups; - - private readonly Dispatcher m_dispatcher; - private DispatcherOperation m_dispatcherOperation; - private DateTime m_dispatcherOperationStartTime; - private bool m_hasNewOperationsSinceStartTime; - - [Flags] - private enum DeferredOperationManagerPendingFlags - { - RegroupPending = 1, - ResortPending = 2, - RefreshPending = 4, - RefreshDistincValuesPending = 8, - RefreshDistincValuesWithFilteredItemChangedPending = 16 - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DistinctValuesDictionary.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DistinctValuesDictionary.cs deleted file mode 100644 index 000071d4..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DistinctValuesDictionary.cs +++ /dev/null @@ -1,74 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Diagnostics; -using Xceed.Utils.Collections; - -namespace Xceed.Wpf.DataGrid -{ - internal class DistinctValuesDictionary : ReadOnlyDictionary - { - public DistinctValuesDictionary( DataGridCollectionViewBase dataGridCollectionViewBase ) - { - if( dataGridCollectionViewBase == null ) - throw new DataGridInternalException( "dataGridCollectionView is null." ); - - m_dataGridCollectionViewBase = dataGridCollectionViewBase; - } - - public override ReadOnlyObservableHashList this[ string key ] - { - get - { - return this.AssertValueIsCreated( key ); - } - set - { - base[ key ] = value; - } - } - - public override bool TryGetValue( string key, out ReadOnlyObservableHashList value ) - { - // We force the creation of the key in the Dictionary - value = this.AssertValueIsCreated( key ); - - return true; - } - - internal bool InternalTryGetValue( string key, out ReadOnlyObservableHashList value ) - { - return base.TryGetValue( key, out value ); - } - - private ReadOnlyObservableHashList AssertValueIsCreated( string key ) - { - ReadOnlyObservableHashList value = null; - - if( !base.TryGetValue( key, out value ) ) - { - value = new ReadOnlyObservableHashList(); - this.InternalAdd( key, value ); - } - - Debug.Assert( value != null ); - - return value; - } - - private DataGridCollectionViewBase m_dataGridCollectionViewBase; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DistinctValuesRefreshNeededEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DistinctValuesRefreshNeededEventManager.cs deleted file mode 100644 index f9423cce..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/DistinctValuesRefreshNeededEventManager.cs +++ /dev/null @@ -1,83 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class DistinctValuesRefreshNeededEventManager : WeakEventManager - { - #region Constructor - - private DistinctValuesRefreshNeededEventManager() - { - } - - #endregion - - #region CurrentManager Private Property - - private static DistinctValuesRefreshNeededEventManager CurrentManager - { - get - { - var managerType = typeof( DistinctValuesRefreshNeededEventManager ); - var currentManager = ( DistinctValuesRefreshNeededEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new DistinctValuesRefreshNeededEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - #endregion - - public static void AddListener( DataGridCollectionViewBase source, IWeakEventListener listener ) - { - if( source == null ) - throw new ArgumentNullException( "source" ); - - if( listener == null ) - throw new ArgumentNullException( "listener" ); - - CurrentManager.ProtectedAddListener( source, listener ); - } - - public static void RemoveListener( DataGridCollectionViewBase source, IWeakEventListener listener ) - { - if( source == null ) - throw new ArgumentNullException( "source" ); - - if( listener == null ) - throw new ArgumentNullException( "listener" ); - - CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - } - - protected override void StopListening( object source ) - { - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/EmptyDataItemSafePropertyDescriptor.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/EmptyDataItemSafePropertyDescriptor.cs deleted file mode 100644 index ed6cf94f..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/EmptyDataItemSafePropertyDescriptor.cs +++ /dev/null @@ -1,104 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.ComponentModel; - -namespace Xceed.Wpf.DataGrid -{ - internal class EmptyDataItemSafePropertyDescriptor : PropertyDescriptor - { - #region STATIC MEMBERS - - private const string PropertyName = "__EmptyDataItemPropertyDescriptor"; - - private static readonly Attribute[] EmptyAttributeArray = new Attribute[ 0 ]; - - #endregion STATIC MEMBERS - - #region SINGLETON - - internal static EmptyDataItemSafePropertyDescriptor Singleton - { - get - { - if( ms_Singleton == null ) - ms_Singleton = new EmptyDataItemSafePropertyDescriptor( EmptyDataItemSafePropertyDescriptor.PropertyName ); - - return ms_Singleton; - } - } - - private static EmptyDataItemSafePropertyDescriptor ms_Singleton; - - #endregion SINGLETON - - #region CONSTRUCTORS - - public EmptyDataItemSafePropertyDescriptor( string name ) - : base( name, EmptyDataItemSafePropertyDescriptor.EmptyAttributeArray ) - { - } - - #endregion CONSTRUCTORS - - public override bool CanResetValue( object component ) - { - return false; - } - - public override Type ComponentType - { - get { return typeof( object ); } - } - - public override object GetValue( object component ) - { - if( component is EmptyDataItem ) - return null; - - return component; - } - - public override bool IsReadOnly - { - get { return true; } - } - - public override Type PropertyType - { - get { return typeof( object ); } - } - - public override void ResetValue( object component ) - { - throw new NotImplementedException(); - } - - public override void SetValue( object component, object value ) - { - throw new NotImplementedException(); - } - - public override bool ShouldSerializeValue( object component ) - { - return false; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/EntityDetailDescription.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/EntityDetailDescription.cs deleted file mode 100644 index da4dc938..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/EntityDetailDescription.cs +++ /dev/null @@ -1,107 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.ComponentModel; -using System.Data.Objects.DataClasses; -using System.Reflection; - -namespace Xceed.Wpf.DataGrid -{ - internal class EntityDetailDescription : DataGridDetailDescription - { - public EntityDetailDescription() - { - } - - public EntityDetailDescription( string propertyName ) - : this() - { - if( string.IsNullOrEmpty( propertyName ) ) - throw new ArgumentException( "The specified property name is null or empty", "propertyName" ); - - this.RelationName = propertyName; - } - - #region QueryDetails Event - - public event EventHandler QueryDetails; - - protected virtual void OnQueryDetails( QueryEntityDetailsEventArgs e ) - { - var handler = this.QueryDetails; - if( handler == null ) - return; - - handler.Invoke( this, e ); - } - - #endregion - - protected internal override IEnumerable GetDetailsForParentItem( DataGridCollectionViewBase parentCollectionView, object parentItem ) - { - EntityObject entityObject = parentItem as EntityObject; - - if( entityObject == null ) - return null; - - // Even if EntityObject is not in a loadable state, we must still return the IList - // so that the ItemProperties can be extracted based on the elements type. - bool entityObjectLoadable = ItemsSourceHelper.IsEntityObjectLoadable( entityObject ); - - // We let the user take charge of handling the details. - QueryEntityDetailsEventArgs args = new QueryEntityDetailsEventArgs( entityObject ); - - if( entityObjectLoadable ) - this.OnQueryDetails( args ); - - // The parentItem must implement IEntityWithRelationships - Type parentItemType = parentItem.GetType(); - if( typeof( IEntityWithRelationships ).IsAssignableFrom( parentItemType ) ) - { - // Since the relationship was based on the the property - // name, we must find that property using reflection. - PropertyInfo propertyInfo = parentItemType.GetProperty( this.RelationName ); - - if( propertyInfo != null ) - { - RelatedEnd relatedEnd = propertyInfo.GetValue( parentItem, null ) as RelatedEnd; - - if( relatedEnd != null ) - { - // Make sure that the details are loaded - // except if the user already handled it. - if( !relatedEnd.IsLoaded - && !args.Handled - && entityObjectLoadable ) - { - relatedEnd.Load(); - } - - IListSource listSource = relatedEnd as IListSource; - - // Returns an IList to have proper change notification events. - if( listSource != null ) - return listSource.GetList(); - } - } - } - - return null; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/EnumerableDetailDescription.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/EnumerableDetailDescription.cs deleted file mode 100644 index 9bf607fc..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/EnumerableDetailDescription.cs +++ /dev/null @@ -1,44 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Collections; - -namespace Xceed.Wpf.DataGrid -{ - internal class EnumerableDetailDescription : DataGridDetailDescription - { - public EnumerableDetailDescription() - : base() - { - this.RelationName = "Children"; - } - - protected internal override IEnumerable GetDetailsForParentItem( DataGridCollectionViewBase parentCollectionView, object parentItem ) - { - IEnumerable enumerable = parentItem as IEnumerable; - - if (enumerable == null) - return null; - - this.Seal(); - - return enumerable; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/GroupDescriptionCollection.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/GroupDescriptionCollection.cs deleted file mode 100644 index b999a42c..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/GroupDescriptionCollection.cs +++ /dev/null @@ -1,89 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.ComponentModel; -using System.Collections.ObjectModel; -using System.Diagnostics; - -namespace Xceed.Wpf.DataGrid -{ - internal class GroupDescriptionCollection : ObservableCollection - { - #region CONSTRUCTORS - - public GroupDescriptionCollection() - { - } - - #endregion CONSTRUCTORS - - #region PROTECTED METHODS - - protected override void InsertItem( int index, GroupDescription item ) - { - string newGroupName; - - if( this.IsGroupDescriptionAlreadyPresent( item, out newGroupName ) == true ) - throw new DataGridInternalException( "A group with the specified name already exists in the collection: " + ( ( newGroupName != null ) ? newGroupName : "" ) ); - - base.InsertItem( index, item ); - } - - protected override void SetItem( int index, GroupDescription item ) - { - string newGroupName; - - if( this.IsGroupDescriptionAlreadyPresent( item, out newGroupName ) == true ) - throw new DataGridInternalException( "A group with the specified name already exists in the collection: " + ( ( newGroupName != null ) ? newGroupName : "" ) ); - - base.SetItem( index, item ); - } - - #endregion PROTECTED METHODS - - #region PRIVATE METHODS - - private bool IsGroupDescriptionAlreadyPresent( GroupDescription newGroupDescription, out string newGroupName ) - { - newGroupName = DataGridContext.GetColumnNameFromGroupDescription( newGroupDescription ); - - // We accept null or empty group names - if( !string.IsNullOrEmpty( newGroupName ) ) - { - foreach( GroupDescription groupDescription in this.Items ) - { - string groupName = DataGridContext.GetColumnNameFromGroupDescription( groupDescription ); - - if( !string.IsNullOrEmpty( groupName ) ) - { - if( newGroupName == groupName ) - { - return true; - } - } - } - } - - return false; - } - - #endregion PRIVATE METHODS - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/GroupNameCountPair.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/GroupNameCountPair.cs deleted file mode 100644 index 2029d28d..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/GroupNameCountPair.cs +++ /dev/null @@ -1,41 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - public class GroupNameCountPair - { - public GroupNameCountPair( object name, int itemCount ) - { - if( name == null ) - throw new ArgumentNullException( "name" ); - - if( itemCount < 0 ) - throw new ArgumentOutOfRangeException( "itemCount", "The specified item count must be greater than or equal to zero." ); - - this.Name = name; - this.ItemCount = itemCount; - } - - public object Name { get; private set; } - public int ItemCount { get; private set; } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/GroupSortComparer.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/GroupSortComparer.cs deleted file mode 100644 index 4483ee7d..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/GroupSortComparer.cs +++ /dev/null @@ -1,147 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Text; -using System.ComponentModel; - -using Xceed.Utils.Data; - -namespace Xceed.Wpf.DataGrid -{ - internal class GroupSortComparer : IComparer - { - public GroupSortComparer( List sortInfos ) - { - m_sortInfos = sortInfos; - } - - #region IComparer Members - - public int Compare( DataGridCollectionViewGroup xGroup, DataGridCollectionViewGroup yGroup ) - { - if( xGroup == null ) - { - if( yGroup == null ) - { - return 0; - } - else - { - return -1; - } - } - else - { - if( yGroup == null ) - { - return 1; - } - } - - var sortDirection = ListSortDirection.Ascending; - int result; - - foreach( SortInfo sortInfo in m_sortInfos ) - { - var foreignKeyDescription = sortInfo.ForeignKeyDescription; - var sortComparer = sortInfo.SortComparer; - sortDirection = sortInfo.SortDirection; - - if( foreignKeyDescription != null ) - { - result = sortComparer.Compare( foreignKeyDescription.GetDisplayValue( xGroup.Name ), foreignKeyDescription.GetDisplayValue( yGroup.Name ) ); - } - else - { - result = sortComparer.Compare( xGroup.Name, yGroup.Name ); - } - - if( result != 0 ) - { - if( sortDirection == ListSortDirection.Descending ) - return -result; - - return result; - } - } - - if( sortDirection == ListSortDirection.Descending ) - return yGroup.UnsortedIndex - xGroup.UnsortedIndex; - - return xGroup.UnsortedIndex - yGroup.UnsortedIndex; - } - - #endregion - - private List m_sortInfos; - - public class SortInfo - { - public SortInfo( ListSortDirection sortDirection, IComparer sortComparer ) - { - if( sortComparer == null ) - throw new ArgumentNullException( "sortComparer" ); - - this.SortDirection = sortDirection; - this.SortComparer = sortComparer; - } - - public SortInfo( DataGridForeignKeyDescription foreignKeyDescription, ListSortDirection sortDirection, IComparer sortComparer ) - { - if( sortComparer == null ) - throw new ArgumentNullException( "sortComparer" ); - - this.ForeignKeyDescription = foreignKeyDescription; - this.SortDirection = sortDirection; - this.SortComparer = sortComparer; - } - - - #region ForeignKeyDescription Property - - internal DataGridForeignKeyDescription ForeignKeyDescription - { - get; - private set; - } - - #endregion - - #region SortDirection Property - - public ListSortDirection SortDirection - { - get; - private set; - } - - #endregion - - #region SortComparer Property - - public IComparer SortComparer - { - get; - private set; - } - - #endregion - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/ItemPropertyGroupSortStatNameChangedEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/ItemPropertyGroupSortStatNameChangedEventManager.cs deleted file mode 100644 index 8ea99cf1..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/ItemPropertyGroupSortStatNameChangedEventManager.cs +++ /dev/null @@ -1,92 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class ItemPropertyGroupSortStatNameChangedEventManager : WeakEventManager - { - private ItemPropertyGroupSortStatNameChangedEventManager() - { - } - - #region CurrentManager Private Property - - private static ItemPropertyGroupSortStatNameChangedEventManager CurrentManager - { - get - { - var managerType = typeof( ItemPropertyGroupSortStatNameChangedEventManager ); - var currentManager = WeakEventManager.GetCurrentManager( managerType ) as ItemPropertyGroupSortStatNameChangedEventManager; - - if( currentManager == null ) - { - currentManager = new ItemPropertyGroupSortStatNameChangedEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - #endregion - - public static void AddListener( DataGridItemPropertyCollection source, IWeakEventListener listener ) - { - if( source == null ) - throw new ArgumentNullException( "source" ); - - if( listener == null ) - throw new ArgumentNullException( "listener" ); - - CurrentManager.ProtectedAddListener( source, listener ); - } - - public static void RemoveListener( DataGridItemPropertyCollection source, IWeakEventListener listener ) - { - if( source == null ) - throw new ArgumentNullException( "source" ); - - if( listener == null ) - throw new ArgumentNullException( "listener" ); - - CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - var target = source as DataGridItemPropertyCollection; - //target.ItemPropertyGroupSortStatNameChanged += new EventHandler( this.DeliverEvent ); - target.ItemPropertyGroupSortStatNameChanged += target_ItemPropertyGroupSortStatNameChanged; - } - - void target_ItemPropertyGroupSortStatNameChanged( object sender, EventArgs e ) - { - this.DeliverEvent( sender, e ); - } - - protected override void StopListening( object source ) - { - var target = source as DataGridItemPropertyCollection; - target.ItemPropertyGroupSortStatNameChanged -= new EventHandler( this.DeliverEvent ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/JaggedArrayPropertyDescriptor.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/JaggedArrayPropertyDescriptor.cs deleted file mode 100644 index b80a5f59..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/JaggedArrayPropertyDescriptor.cs +++ /dev/null @@ -1,116 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.ComponentModel; -using System.Data; -using System.Collections; -using System.Globalization; - -namespace Xceed.Wpf.DataGrid -{ - internal class JaggedArrayPropertyDescriptor : PropertyDescriptor - { - public JaggedArrayPropertyDescriptor( int columnIndex, Type columnDataType ) - : base( ".[" + columnIndex.ToString( CultureInfo.InvariantCulture ) + "]", null ) - { - m_columnIndex = columnIndex; - m_columnDataType = columnDataType; - } - - public override AttributeCollection Attributes - { - get - { - if( typeof( IList ).IsAssignableFrom( this.PropertyType ) ) - { - Attribute[] array = new Attribute[ base.Attributes.Count + 1 ]; - base.Attributes.CopyTo( array, 0 ); - array[ array.Length - 1 ] = new ListBindableAttribute( false ); - return new AttributeCollection( array ); - } - - return base.Attributes; - } - } - - public override Type ComponentType - { - get - { - return m_columnDataType.MakeArrayType(); - } - } - - public override bool IsReadOnly - { - get - { - return false; - } - } - - public override Type PropertyType - { - get - { - return m_columnDataType; - } - } - - public override bool CanResetValue( object component ) - { - return false; - } - - public override object GetValue( object component ) - { - Array arrayComponent = component as Array; - - if( arrayComponent == null ) - return null; - - return arrayComponent.GetValue( m_columnIndex ); - } - - public override void ResetValue( object component ) - { - } - - public override void SetValue( object component, object value ) - { - Array arrayComponent = component as Array; - - if( arrayComponent == null ) - throw new InvalidOperationException( "An attempt was made to set a value on something other than a one dimension array." ); - - if( this.IsReadOnly ) - throw new InvalidOperationException( "An attempt was made to set a value on a read-only property." ); - - arrayComponent.SetValue( value, m_columnIndex ); - } - - public override bool ShouldSerializeValue( object component ) - { - return false; - } - - private int m_columnIndex; - private Type m_columnDataType; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/ListSourceDetailDescription.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/ListSourceDetailDescription.cs deleted file mode 100644 index fdab96ca..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/ListSourceDetailDescription.cs +++ /dev/null @@ -1,47 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Collections; -using System.ComponentModel; - -namespace Xceed.Wpf.DataGrid -{ - internal class ListSourceDetailDescription : DataGridDetailDescription - { - public ListSourceDetailDescription() - : base() - { - this.RelationName = "Children"; - } - - protected internal override IEnumerable GetDetailsForParentItem( DataGridCollectionViewBase parentCollectionView, object parentItem ) - { - IListSource listSource = parentItem as IListSource; - - if( listSource == null ) - return null; - - this.Seal(); - - return listSource.GetList(); - - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/PostBatchCollectionChangedEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/PostBatchCollectionChangedEventManager.cs deleted file mode 100644 index d3426f16..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/PostBatchCollectionChangedEventManager.cs +++ /dev/null @@ -1,78 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class PostBatchCollectionChangedEventManager : WeakEventManager - { - #region Constructor - - private PostBatchCollectionChangedEventManager() - { - } - - #endregion - - #region CurrentManager Static Property - - private static PostBatchCollectionChangedEventManager CurrentManager - { - get - { - var managerType = typeof( PostBatchCollectionChangedEventManager ); - var currentManager = ( PostBatchCollectionChangedEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new PostBatchCollectionChangedEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - #endregion - - public static void AddListener( DataGridCollectionViewBase source, IWeakEventListener listener ) - { - PostBatchCollectionChangedEventManager.CurrentManager.ProtectedAddListener( source, listener ); - } - - public static void RemoveListener( DataGridCollectionViewBase source, IWeakEventListener listener ) - { - PostBatchCollectionChangedEventManager.CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - ( ( DataGridCollectionViewBase )source ).PostBatchCollectionChanged += new EventHandler( this.OnEventRaised ); - } - - protected override void StopListening( object source ) - { - ( ( DataGridCollectionViewBase )source ).PostBatchCollectionChanged -= new EventHandler( this.OnEventRaised ); - } - - private void OnEventRaised( object sender, EventArgs e ) - { - this.DeliverEvent( sender, e ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/PreBatchCollectionChangedEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/PreBatchCollectionChangedEventManager.cs deleted file mode 100644 index 573a752d..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/PreBatchCollectionChangedEventManager.cs +++ /dev/null @@ -1,78 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class PreBatchCollectionChangedEventManager : WeakEventManager - { - #region Constructor - - private PreBatchCollectionChangedEventManager() - { - } - - #endregion - - #region CurrentManager Static Property - - private static PreBatchCollectionChangedEventManager CurrentManager - { - get - { - var managerType = typeof( PreBatchCollectionChangedEventManager ); - var currentManager = ( PreBatchCollectionChangedEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new PreBatchCollectionChangedEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - #endregion - - public static void AddListener( DataGridCollectionViewBase source, IWeakEventListener listener ) - { - PreBatchCollectionChangedEventManager.CurrentManager.ProtectedAddListener( source, listener ); - } - - public static void RemoveListener( DataGridCollectionViewBase source, IWeakEventListener listener ) - { - PreBatchCollectionChangedEventManager.CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - ( ( DataGridCollectionViewBase )source ).PreBatchCollectionChanged += new EventHandler( this.OnEventRaised ); - } - - protected override void StopListening( object source ) - { - ( ( DataGridCollectionViewBase )source ).PreBatchCollectionChanged -= new EventHandler( this.OnEventRaised ); - } - - private void OnEventRaised( object sender, EventArgs e ) - { - this.DeliverEvent( sender, e ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/PropertyDetailDescription.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/PropertyDetailDescription.cs deleted file mode 100644 index 3f6fd826..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/PropertyDetailDescription.cs +++ /dev/null @@ -1,182 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.ComponentModel; - -namespace Xceed.Wpf.DataGrid -{ - internal class PropertyDetailDescription : DataGridDetailDescription - { - public PropertyDetailDescription() - : base() - { - } - - public PropertyDetailDescription( PropertyDescriptor relation ) - : this() - { - if( relation == null ) - throw new ArgumentNullException( "relation" ); - - this.PropertyDescriptor = relation; - } - - #region PropertyDescriptor Property - - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly" )] - public PropertyDescriptor PropertyDescriptor - { - get - { - return m_propertyDescriptor; - } - set - { - if( value == null ) - throw new ArgumentNullException( "PropertyDescriptor" ); - - if( this.InternalIsSealed == true ) - throw new InvalidOperationException( "An attempt was made to set the PropertyDescriptor property after the PropertyDetailDescription has been sealed." ); - - m_propertyDescriptor = value; - this.RelationName = value.Name; - - this.Seal(); - } - } - - private PropertyDescriptor m_propertyDescriptor; - - #endregion - - protected internal override void Initialize( DataGridCollectionViewBase parentCollectionView ) - { - base.Initialize( parentCollectionView ); - - if( this.PropertyDescriptor != null ) - return; - - string relationName = this.RelationName; - - if( String.IsNullOrEmpty( relationName ) == true ) - throw new InvalidOperationException( "An attempt was made to initialize a PropertyDetailDescription whose Name property has not been set." ); - - var enumeration = parentCollectionView as IEnumerable; - if( enumeration != null ) - { - // Try to get it from the first item in the DataGridCollectionView - var firstItem = ItemsSourceHelper.GetFirstItemByEnumerable( enumeration ); - if( firstItem != null ) - { - var propertyDescriptor = this.GetPropertyDescriptorFromFirstItem( firstItem ); - if( propertyDescriptor != null ) - { - this.PropertyDescriptor = propertyDescriptor; - return; - } - } - } - - // If the list is empty, check if the SourceCollection is ITypedList - var typedList = parentCollectionView.SourceCollection as ITypedList; - if( typedList != null ) - { - var propertyDescriptor = this.GetPropertyDescriptorFromITypedList( typedList ); - if( propertyDescriptor != null ) - { - this.PropertyDescriptor = propertyDescriptor; - return; - } - } - - throw new InvalidOperationException( "An attempt was made to initialize a PropertyDetailDescription whose data source does not contain a property that corresponds to the specified relation name." ); - } - - private PropertyDescriptor GetPropertyDescriptorFromITypedList( ITypedList typedList ) - { - if( string.IsNullOrEmpty( this.RelationName ) || ( typedList == null ) ) - return null; - - var properties = typedList.GetItemProperties( null ); - if( ( properties != null ) && ( properties.Count > 0 ) ) - return properties[ this.RelationName ]; - - var listName = typedList.GetListName( null ); - if( string.IsNullOrEmpty( listName ) ) - return null; - - var itemType = Type.GetType( listName, false, false ); - if( itemType == null ) - return null; - - var descriptionProvider = TypeDescriptor.GetProvider( itemType ); - if( descriptionProvider == null ) - return null; - - var descriptor = descriptionProvider.GetTypeDescriptor( itemType ); - if( descriptor == null ) - return null; - - properties = descriptor.GetProperties(); - if( ( properties != null ) && ( properties.Count > 0 ) ) - return properties[ this.RelationName ]; - - return null; - } - - private PropertyDescriptor GetPropertyDescriptorFromFirstItem( object firstItem ) - { - if( string.IsNullOrEmpty( this.RelationName ) || ( firstItem == null ) ) - return null; - - var descriptor = ItemsSourceHelper.GetCustomTypeDescriptorFromItem( firstItem, firstItem.GetType() ); - if( descriptor == null ) - return null; - - var properties = descriptor.GetProperties(); - if( ( properties != null ) && ( properties.Count > 0 ) ) - return properties[ this.RelationName ]; - - return null; - } - - protected internal override IEnumerable GetDetailsForParentItem( DataGridCollectionViewBase parentCollectionView, object parentItem ) - { - if( this.PropertyDescriptor == null ) - throw new InvalidOperationException( "An attempt was made to obtain details of a PropertyDetailDescription object whose PropertyDescriptor property has not been set." ); - - this.Seal(); - - var value = this.PropertyDescriptor.GetValue( parentItem ); - if( value == null ) - return null; - - var enumeration = value as IEnumerable; - if( enumeration == null ) - { - var listSource = value as IListSource; - if( listSource != null ) - { - enumeration = listSource.GetList(); - } - } - - return enumeration; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/PropertyRelationAttribute.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/PropertyRelationAttribute.cs deleted file mode 100644 index b878a623..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/PropertyRelationAttribute.cs +++ /dev/null @@ -1,28 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - [Obsolete( "The PropertyRelationAttribute is obsolete. All IEnumerable properties will automatically be detected as detail relations. ", false )] - [AttributeUsage( AttributeTargets.Property )] - public sealed class PropertyRelationAttribute: Attribute - { - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/ProxyCollectionRefreshEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/ProxyCollectionRefreshEventManager.cs deleted file mode 100644 index 6610e084..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/ProxyCollectionRefreshEventManager.cs +++ /dev/null @@ -1,87 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class ProxyCollectionRefreshEventManager : WeakEventManager - { - #region Constructor - - private ProxyCollectionRefreshEventManager() - { - } - - #endregion - - #region CurrentManager Private Property - - private static ProxyCollectionRefreshEventManager CurrentManager - { - get - { - var managerType = typeof( ProxyCollectionRefreshEventManager ); - var currentManager = ( ProxyCollectionRefreshEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new ProxyCollectionRefreshEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - #endregion - - public static void AddListener( DataGridCollectionViewBase source, IWeakEventListener listener ) - { - if( source == null ) - throw new ArgumentNullException( "source" ); - - if( listener == null ) - throw new ArgumentNullException( "listener" ); - - CurrentManager.ProtectedAddListener( source, listener ); - } - - public static void RemoveListener( DataGridCollectionViewBase source, IWeakEventListener listener ) - { - if( source == null ) - throw new ArgumentNullException( "source" ); - - if( listener == null ) - throw new ArgumentNullException( "listener" ); - - CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - var target = ( DataGridCollectionViewBase )source; - target.ProxyCollectionRefresh += new EventHandler( this.DeliverEvent ); - } - - protected override void StopListening( object source ) - { - var target = ( DataGridCollectionViewBase )source; - target.ProxyCollectionRefresh -= new EventHandler( this.DeliverEvent ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/ProxyGroupDescriptionsChangedEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/ProxyGroupDescriptionsChangedEventManager.cs deleted file mode 100644 index 95c6aa3d..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/ProxyGroupDescriptionsChangedEventManager.cs +++ /dev/null @@ -1,93 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Specialized; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class ProxyGroupDescriptionsChangedEventManager : WeakEventManager - { - #region Constructor - - private ProxyGroupDescriptionsChangedEventManager() - { - } - - #endregion - - #region CurrentManager Private Property - - private static ProxyGroupDescriptionsChangedEventManager CurrentManager - { - get - { - var managerType = typeof( ProxyGroupDescriptionsChangedEventManager ); - var currentManager = ( ProxyGroupDescriptionsChangedEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new ProxyGroupDescriptionsChangedEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - #endregion - - public static void AddListener( DataGridCollectionViewBase source, IWeakEventListener listener ) - { - if( source == null ) - throw new ArgumentNullException( "source" ); - - if( listener == null ) - throw new ArgumentNullException( "listener" ); - - CurrentManager.ProtectedAddListener( source, listener ); - } - - public static void RemoveListener( DataGridCollectionViewBase source, IWeakEventListener listener ) - { - if( source == null ) - throw new ArgumentNullException( "source" ); - - if( listener == null ) - throw new ArgumentNullException( "listener" ); - - CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - var target = ( DataGridCollectionViewBase )source; - target.ProxyGroupDescriptionsChanged += new NotifyCollectionChangedEventHandler( this.OnEventRaised ); - } - - protected override void StopListening( object source ) - { - var target = ( DataGridCollectionViewBase )source; - target.ProxyGroupDescriptionsChanged -= new NotifyCollectionChangedEventHandler( this.OnEventRaised ); - } - - private void OnEventRaised( object sender, NotifyCollectionChangedEventArgs e ) - { - this.DeliverEvent( sender, e ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/ProxySortDescriptionsChangedEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/ProxySortDescriptionsChangedEventManager.cs deleted file mode 100644 index 7c62a0cd..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/ProxySortDescriptionsChangedEventManager.cs +++ /dev/null @@ -1,93 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Specialized; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class ProxySortDescriptionsChangedEventManager : WeakEventManager - { - #region Constructor - - private ProxySortDescriptionsChangedEventManager() - { - } - - #endregion - - #region CurrentManager Private Property - - private static ProxySortDescriptionsChangedEventManager CurrentManager - { - get - { - var managerType = typeof( ProxySortDescriptionsChangedEventManager ); - var currentManager = ( ProxySortDescriptionsChangedEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new ProxySortDescriptionsChangedEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - #endregion - - public static void AddListener( DataGridCollectionViewBase source, IWeakEventListener listener ) - { - if( source == null ) - throw new ArgumentNullException( "source" ); - - if( listener == null ) - throw new ArgumentNullException( "listener" ); - - CurrentManager.ProtectedAddListener( source, listener ); - } - - public static void RemoveListener( DataGridCollectionViewBase source, IWeakEventListener listener ) - { - if( source == null ) - throw new ArgumentNullException( "source" ); - - if( listener == null ) - throw new ArgumentNullException( "listener" ); - - CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - var target = ( DataGridCollectionViewBase )source; - target.ProxySortDescriptionsChanged += new NotifyCollectionChangedEventHandler( this.OnEventRaised ); - } - - protected override void StopListening( object source ) - { - var target = ( DataGridCollectionViewBase )source; - target.ProxySortDescriptionsChanged -= new NotifyCollectionChangedEventHandler( this.OnEventRaised ); - } - - private void OnEventRaised( object sender, NotifyCollectionChangedEventArgs e ) - { - this.DeliverEvent( sender, e ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/QueryDistinctValueEventArgs.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/QueryDistinctValueEventArgs.cs deleted file mode 100644 index 3d69259f..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/QueryDistinctValueEventArgs.cs +++ /dev/null @@ -1,47 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - public class QueryDistinctValueEventArgs : EventArgs - { - internal QueryDistinctValueEventArgs( object dataSourceValue ) - { - this.DataSourceValue = dataSourceValue; - - // Initialize the DistinctValue as the original DataSourceValue - // in case it is not modified during the QueryDistinctValue event - this.DistinctValue = dataSourceValue; - } - - public object DataSourceValue - { - get; - private set; - } - - public object DistinctValue - { - get; - set; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/QueryEntityDetailsEventArgs.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/QueryEntityDetailsEventArgs.cs deleted file mode 100644 index 1ecf2f1b..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/QueryEntityDetailsEventArgs.cs +++ /dev/null @@ -1,61 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows; -using System.Data.Objects.DataClasses; - -namespace Xceed.Wpf.DataGrid -{ - public class QueryEntityDetailsEventArgs : EventArgs - { - #region CONSTRUCTORS - - internal QueryEntityDetailsEventArgs( EntityObject parentItem ) - : base() - { - if( parentItem == null ) - throw new ArgumentNullException( "parentItem" ); - - this.ParentItem = parentItem; - } - - #endregion CONSTRUCTORS - - #region ParentItem Property - - public EntityObject ParentItem - { - get; - private set; - } - - #endregion ParentItem Property - - #region Handled Property - - public bool Handled - { - get; - set; - } - - #endregion Handled Property - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/QueryGroupsEventArgs.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/QueryGroupsEventArgs.cs deleted file mode 100644 index b76ad776..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/QueryGroupsEventArgs.cs +++ /dev/null @@ -1,148 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows.Data; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.Diagnostics; - -namespace Xceed.Wpf.DataGrid -{ - public class QueryGroupsEventArgs : EventArgs - { - #region CONSTRUCTORS - - internal QueryGroupsEventArgs( - DataGridVirtualizingCollectionView collectionView, - DataGridVirtualizingCollectionViewGroup parentGroup, - GroupDescription childGroupDescription ) - { - m_dataGridVirtualizingCollectionView = collectionView; - m_readonlyGroupPath = parentGroup.GroupPath.AsReadOnly(); - m_childGroupDescription = childGroupDescription; - this.ChildGroupPropertyName = DataGridCollectionViewBase.GetPropertyNameFromGroupDescription( childGroupDescription ); - - m_sortDirection = SortDirection.None; - - SortDescriptionCollection sortDescriptions = m_dataGridVirtualizingCollectionView.SortDescriptions; - - int sortDescriptionCount = ( sortDescriptions == null ) ? 0 : sortDescriptions.Count; - - for( int i = 0; i < sortDescriptions.Count ; i++ ) - { - SortDescription sortDescription = sortDescriptions[ i ]; - - if( string.Equals( sortDescription.PropertyName, this.ChildGroupPropertyName ) ) - { - m_sortDirection = ( sortDescription.Direction == ListSortDirection.Ascending ) ? SortDirection.Ascending : SortDirection.Descending; - break; - } - } - - m_childGroupNameCountPairs = new List(); - } - - #endregion CONSTRUCTORS - - #region CollectionView PROPERTY - - public DataGridVirtualizingCollectionView CollectionView - { - get - { - return m_dataGridVirtualizingCollectionView; - } - } - - #endregion CollectionView PROPERTY - - #region ChildGroupDescription PROPERTY - - public GroupDescription ChildGroupDescription - { - get - { - return m_childGroupDescription; - } - } - - #endregion ChildGroupDescription PROPERTY - - #region ChildGroupPropertyName PROPERTY - - public string ChildGroupPropertyName - { - get; - private set; - } - - #endregion ChildGroupPropertyName PROPERTY - - #region ChildSortDirection PROPERTY - - public SortDirection ChildSortDirection - { - get - { - return m_sortDirection; - } - } - - #endregion ChildSortDirection PROPERTY - - #region ChildGroupNameCountPairs PROPERTY - - public List ChildGroupNameCountPairs - { - get - { - return m_childGroupNameCountPairs; - } - } - - #endregion ChildGroupNameCountPairs PROPERTY - - - #region GroupPath PROPERTY - - public ReadOnlyCollection GroupPath - { - get - { - return m_readonlyGroupPath; - } - } - - #endregion GroupPath PROPERTY - - - #region PRIVATE FIELDS - - private DataGridVirtualizingCollectionView m_dataGridVirtualizingCollectionView; - private GroupDescription m_childGroupDescription; - private SortDirection m_sortDirection; - private ReadOnlyCollection m_readonlyGroupPath; - - private List m_childGroupNameCountPairs; - - #endregion PRIVATE FIELDS - } - -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/QueryItemCountEvent.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/QueryItemCountEvent.cs deleted file mode 100644 index 822ecc55..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/QueryItemCountEvent.cs +++ /dev/null @@ -1,90 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows.Data; -using System.Collections.ObjectModel; - -namespace Xceed.Wpf.DataGrid -{ - public class QueryItemCountEventArgs : EventArgs - { - #region CONSTRUCTORS - - internal QueryItemCountEventArgs( DataGridVirtualizingCollectionView collectionView, - DataGridVirtualizingCollectionViewGroup collectionViewGroup ) - { - m_dataGridVirtualizingCollectionView = collectionView; - m_readonlyGroupPath = collectionViewGroup.GroupPath.AsReadOnly(); - - m_count = -1; - } - - #endregion CONSTRUCTORS - - #region CollectionView PROPERTY - - public DataGridVirtualizingCollectionView CollectionView - { - get - { - return m_dataGridVirtualizingCollectionView; - } - } - - #endregion CollectionView PROPERTY - - #region GroupPath PROPERTY - - public ReadOnlyCollection GroupPath - { - get - { - return m_readonlyGroupPath; - } - } - - #endregion GroupPath PROPERTY - - #region Count PROPERTY - - public int Count - { - get - { - return m_count; - } - set - { - m_count = value; - } - } - - #endregion Count PROPERTY - - #region PRIVATE FIELDS - - private DataGridVirtualizingCollectionView m_dataGridVirtualizingCollectionView; - private ReadOnlyCollection m_readonlyGroupPath; - - private int m_count; - - #endregion PRIVATE FIELDS - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/QueryItemsEvent.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/QueryItemsEvent.cs deleted file mode 100644 index dbf338d0..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/QueryItemsEvent.cs +++ /dev/null @@ -1,95 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows.Data; -using System.ComponentModel; -using System.Collections.ObjectModel; - -namespace Xceed.Wpf.DataGrid -{ - public class QueryItemsEventArgs : EventArgs - { - internal QueryItemsEventArgs( - DataGridVirtualizingCollectionView collectionView, - DataGridVirtualizingCollectionViewGroup collectionViewGroup, - AsyncQueryInfo asyncQueryInfo ) - { - m_dataGridVirtualizingCollectionView = collectionView; - - // The collectionViewGroup can be null when we abort - // a QueryItems for the old RootGroup when - // DataGridVirtualizingCollectionViewBase.ForceRefresh - // is called - m_readonlyGroupPath = ( collectionViewGroup != null ) - ? collectionViewGroup.GroupPath.AsReadOnly() - : new ReadOnlyCollection( new List() ); - - m_asyncQueryInfo = asyncQueryInfo; - } - - - #region CollectionView PROPERTY - - public DataGridVirtualizingCollectionView CollectionView - { - get - { - return m_dataGridVirtualizingCollectionView; - } - } - - #endregion CollectionView PROPERTY - - #region GroupPath PROPERTY - - public ReadOnlyCollection GroupPath - { - get - { - return m_readonlyGroupPath; - } - } - - #endregion GroupPath PROPERTY - - - #region AsyncQueryInfo PROPERTY - - public AsyncQueryInfo AsyncQueryInfo - { - get - { - return m_asyncQueryInfo; - } - } - - #endregion AsyncQueryInfo PROPERTY - - - #region PRIVATE FIELDS - - private DataGridVirtualizingCollectionView m_dataGridVirtualizingCollectionView; - private AsyncQueryInfo m_asyncQueryInfo; - - private ReadOnlyCollection m_readonlyGroupPath; - - #endregion PRIVATE FIELDS - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/QueryableExtensions.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/QueryableExtensions.cs deleted file mode 100644 index ee7d4f72..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/QueryableExtensions.cs +++ /dev/null @@ -1,798 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics; -using System.Linq; -using System.Linq.Expressions; -using System.Reflection; - -namespace Xceed.Wpf.DataGrid -{ - internal static class QueryableExtensions - { - #region REFLECTION METHODS - - private static MemberInfo GetMemberInfo( Type type, string memberName ) - { - MemberInfo[] members = type.FindMembers( MemberTypes.Property | MemberTypes.Field, - BindingFlags.Public | BindingFlags.Instance, - Type.FilterNameIgnoreCase, memberName ); - - if( members.Length != 0 ) - return members[ 0 ]; - - return null; - } - - internal static string[] FindPrimaryKeys( this IQueryable queryable ) - { - if( queryable == null ) - throw new ArgumentNullException( "queryable" ); - - Type elementType = queryable.ElementType; - - List primaryKeyNames = new List(); - - try - { - PropertyInfo[] properties = elementType.GetProperties(); - - for( int i = 0; i < properties.Length; i++ ) - { - PropertyInfo propertyInfo = properties[ i ]; - - object[] attributes = propertyInfo.GetCustomAttributes( true ); - - for( int j = 0; j < attributes.Length; j++ ) - { - Attribute attribute = attributes[ j ] as Attribute; - - if( attribute == null ) - continue; - - Type attributeType = attribute.GetType(); - - if( attributeType.FullName == "System.Data.Linq.Mapping.ColumnAttribute" ) - { - // LINQ to SQL support. - PropertyInfo isPrimaryKeyPropertyInfo = attributeType.GetProperty( "IsPrimaryKey" ); - - if( isPrimaryKeyPropertyInfo != null ) - { - bool isPrimaryKey = ( bool )isPrimaryKeyPropertyInfo.GetValue( attribute, null ); - - if( isPrimaryKey ) - primaryKeyNames.Add( propertyInfo.Name ); - } - } - else if( attributeType.FullName == "System.Data.Objects.DataClasses.EdmScalarPropertyAttribute" ) - { - // LINQ to Entity support. - PropertyInfo entityKeyPropertyInfo = attributeType.GetProperty( "EntityKeyProperty" ); - - if( entityKeyPropertyInfo != null ) - { - bool isPrimaryKey = ( bool )entityKeyPropertyInfo.GetValue( attribute, null ); - - if( isPrimaryKey ) - primaryKeyNames.Add( propertyInfo.Name ); - } - } - } - } - } - catch - { - } - - return primaryKeyNames.ToArray(); - } - - - #endregion REFLECTION METHODS - - #region ORDERING - - internal static IQueryable OrderBy( - this IQueryable queryable, - SortDescriptionCollection implicitSortDescriptions, - SortDescriptionCollection explicitSortDescriptions, - bool reverse ) - { - if( queryable == null ) - throw new ArgumentNullException( "queryable" ); - - if( ( implicitSortDescriptions == null ) && ( explicitSortDescriptions == null ) ) - return queryable; - - Expression orderedExpression = queryable.Expression; - - Type queryableElementType = queryable.ElementType; - - ParameterExpression[] parameters = new ParameterExpression[] { Expression.Parameter( queryableElementType, "" ) }; - - string ascendingOrderByMethodName = "OrderBy"; - string descendingOrderByMethodName = "OrderByDescending"; - - if( explicitSortDescriptions != null ) - { - foreach( SortDescription sortDescription in explicitSortDescriptions ) - { - MemberExpression sortMemberExpression = QueryableExtensions.GenerateMemberExpression( parameters[ 0 ], sortDescription.PropertyName ); - - string methodNameToUse; - - if( ( sortDescription.Direction == ListSortDirection.Ascending && !reverse ) || ( sortDescription.Direction == ListSortDirection.Descending && reverse ) ) - { - methodNameToUse = ascendingOrderByMethodName; - } - else - { - methodNameToUse = descendingOrderByMethodName; - } - - orderedExpression = Expression.Call( typeof( Queryable ), - methodNameToUse, - new Type[] { queryableElementType, sortMemberExpression.Type }, - orderedExpression, Expression.Quote( Expression.Lambda( sortMemberExpression, parameters ) ) ); - - - ascendingOrderByMethodName = "ThenBy"; - descendingOrderByMethodName = "ThenByDescending"; - } - } - - if( implicitSortDescriptions != null ) - { - foreach( SortDescription sortDescription in implicitSortDescriptions ) - { - MemberExpression sortMemberExpression = QueryableExtensions.GenerateMemberExpression( parameters[ 0 ], sortDescription.PropertyName ); - - string methodNameToUse; - - if( ( sortDescription.Direction == ListSortDirection.Ascending && !reverse ) || ( sortDescription.Direction == ListSortDirection.Descending && reverse ) ) - { - methodNameToUse = ascendingOrderByMethodName; - } - else - { - methodNameToUse = descendingOrderByMethodName; - } - - orderedExpression = Expression.Call( typeof( Queryable ), - methodNameToUse, - new Type[] { queryableElementType, sortMemberExpression.Type }, - orderedExpression, Expression.Quote( Expression.Lambda( sortMemberExpression, parameters ) ) ); - - - ascendingOrderByMethodName = "ThenBy"; - descendingOrderByMethodName = "ThenByDescending"; - } - } - - return queryable.Provider.CreateQuery( orderedExpression ); - } - - #endregion ORDERING - - #region FILTERING - - internal static Expression CreateStartsWithExpression( - this IQueryable queryable, - ParameterExpression sharedParameterExpression, - string propertyName, - params string[] values ) - { - return QueryableExtensions.FilterString( queryable, sharedParameterExpression, propertyName, values, StringFilterMode.StartsWith ); - } - - internal static Expression CreateEndsWithExpression( - this IQueryable queryable, - ParameterExpression sharedParameterExpression, - string propertyName, - params string[] values ) - { - return QueryableExtensions.FilterString( queryable, sharedParameterExpression, propertyName, values, StringFilterMode.EndsWith ); - } - - internal static Expression CreateContainsExpression( - this IQueryable queryable, - ParameterExpression sharedParameterExpression, - string propertyName, - params string[] values ) - { - return QueryableExtensions.FilterString( queryable, sharedParameterExpression, propertyName, values, StringFilterMode.Contains ); - } - - - internal static Expression CreateGreaterThanExpression( - this IQueryable queryable, - ParameterExpression sharedParameterExpression, - string propertyName, - params object[] values ) - { - return QueryableExtensions.CreateBinaryComparison( - queryable, - sharedParameterExpression, - propertyName, - values, - BinaryExpression.GreaterThan ); - } - - internal static Expression CreateGreaterThanOrEqualExpression( - this IQueryable queryable, - ParameterExpression sharedParameterExpression, - string propertyName, - params object[] values ) - { - return QueryableExtensions.CreateBinaryComparison( - queryable, - sharedParameterExpression, - propertyName, - values, - BinaryExpression.GreaterThanOrEqual ); - } - - - internal static Expression CreateLesserThanExpression( - this IQueryable queryable, - ParameterExpression sharedParameterExpression, - string propertyName, - params object[] values ) - { - return QueryableExtensions.CreateBinaryComparison( - queryable, - sharedParameterExpression, - propertyName, - values, - BinaryExpression.LessThan ); - } - - internal static Expression CreateLesserThanOrEqualExpression( - this IQueryable queryable, - ParameterExpression sharedParameterExpression, - string propertyName, - params object[] values ) - { - return QueryableExtensions.CreateBinaryComparison( - queryable, - sharedParameterExpression, - propertyName, - values, - BinaryExpression.LessThanOrEqual ); - } - - internal static Expression CreateEqualExpression( - this IQueryable queryable, - ParameterExpression sharedParameterExpression, - string propertyName, - params object[] values ) - { - return QueryableExtensions.CreateBinaryComparison( - queryable, - sharedParameterExpression, - propertyName, - values, - BinaryExpression.Equal ); - } - - internal static Expression CreateDifferentThanExpression( - this IQueryable queryable, - ParameterExpression sharedParameterExpression, - string propertyName, - params object[] values ) - { - return QueryableExtensions.CreateBinaryComparison( - queryable, - sharedParameterExpression, - propertyName, - values, - BinaryExpression.NotEqual ); - } - - - internal static ParameterExpression CreateParameterExpression( this IQueryable queryable ) - { - if( queryable == null ) - throw new ArgumentNullException( "queryable" ); - - return Expression.Parameter( queryable.ElementType, "" ); - } - - private static Expression CreateBinaryComparison( - this IQueryable queryable, - ParameterExpression sharedParameterExpression, - string propertyName, - object[] values, - BinaryComparisonDelegate binaryComparisonDelegate ) - { - if( queryable == null ) - throw new ArgumentNullException( "queryable" ); - - if( ( values == null ) || ( values.Length == 0 ) ) - throw new ArgumentNullException( "values" ); - - if( binaryComparisonDelegate == null ) - throw new ArgumentNullException( "binaryComparisonDelegate" ); - - MemberExpression memberExpression = QueryableExtensions.GenerateMemberExpression( sharedParameterExpression, propertyName ); - - Expression mergedFilterExpression = null; - - for( int i = 0; i < values.Length; i++ ) - { - ConstantExpression valueExpression = Expression.Constant( values[ i ] ); - - Expression newFilterExpression = binaryComparisonDelegate( memberExpression, - Expression.Convert( valueExpression, memberExpression.Type ) ); - - if( mergedFilterExpression == null ) - { - mergedFilterExpression = newFilterExpression; - } - else - { - mergedFilterExpression = Expression.Or( mergedFilterExpression, newFilterExpression ); - } - } - - return mergedFilterExpression; - } - - - internal static IQueryable WhereFilter( this IQueryable queryable, ParameterExpression sharedParameterExpression, Expression expression ) - { - if( queryable == null ) - throw new ArgumentNullException( "queryable" ); - - Type queryableElementType = queryable.ElementType; - - LambdaExpression whereLambda = Expression.Lambda( expression, sharedParameterExpression ); - - MethodCallExpression whereCall = - Expression.Call( - typeof( Queryable ), "Where", - new Type[] { queryableElementType }, - queryable.Expression, - Expression.Quote( whereLambda ) ); - - return queryable.Provider.CreateQuery( whereCall ); - } - - - - #endregion FILTERING - - #region SELECTING - - internal static IQueryable Select( this IQueryable queryable, string propertyName ) - { - if( queryable == null ) - throw new ArgumentNullException( "queryable" ); - - if( string.IsNullOrEmpty( propertyName ) ) - { - if( propertyName == null ) - throw new ArgumentNullException( "propertyName" ); - - throw new ArgumentException( "A property name must be provided.", "propertyName" ); - } - - Type queryableElementType = queryable.ElementType; - ParameterExpression[] parameters = new ParameterExpression[] { Expression.Parameter( queryableElementType, "" ) }; - - MemberExpression selectMemberExpression = QueryableExtensions.GenerateMemberExpression( parameters[ 0 ], propertyName ); - - LambdaExpression selectLambdaExpression = Expression.Lambda( selectMemberExpression, parameters ); - - return queryable.Provider.CreateQuery( - Expression.Call( typeof( Queryable ), "Select", - new Type[] { queryableElementType, selectLambdaExpression.Body.Type }, - queryable.Expression, Expression.Quote( selectLambdaExpression ) ) ); - } - - internal static IQueryable GetSubGroupsAndCountsQueryable( this IQueryable queryable, string subGroupBy, bool sortGroupBy, ListSortDirection direction ) - { - // Create GroupBy - Type queryableElementType = queryable.ElementType; - - ParameterExpression[] parameters = new ParameterExpression[] { Expression.Parameter( queryableElementType, "" ) }; - MemberExpression memberExpression = QueryableExtensions.GenerateMemberExpression( parameters[ 0 ], subGroupBy ); - LambdaExpression groupByLambdaExpression = Expression.Lambda( memberExpression, parameters ); - - MethodCallExpression groupByMethodExpression = - Expression.Call( - typeof( Queryable ), "GroupBy", - new Type[] { queryableElementType, groupByLambdaExpression.Body.Type }, - new Expression[] { queryable.Expression, Expression.Quote( groupByLambdaExpression ) } ); - - IQueryable groupedResult = queryable.Provider.CreateQuery( groupByMethodExpression ); - - if( sortGroupBy ) - groupedResult = groupedResult.OrderByKey( direction == ListSortDirection.Ascending ); - - ParameterExpression[] groupedParameters = new ParameterExpression[] { System.Linq.Expressions.Expression.Parameter( groupedResult.ElementType, "" ) }; - - MemberExpression keyMemberExpression = MemberExpression.Property( groupedParameters[ 0 ], "Key" ); - MethodCallExpression countCallExpression = MethodCallExpression.Call( typeof( Enumerable ), "Count", new Type[] { queryableElementType }, groupedParameters ); - - QueryableGroupNameCountPairInfo queryableGroupNameCountPairInfo = - QueryableExtensions.QueryableGroupNameCountPairInfos.GetInfosForType( memberExpression.Type ); - - Expression[] newExpressionArguments = new Expression[ 2 ] { keyMemberExpression, countCallExpression }; - - NewExpression newExpression = - NewExpression.New( - queryableGroupNameCountPairInfo.ConstructorInfo, - newExpressionArguments, - new MemberInfo[] { queryableGroupNameCountPairInfo.KeyPropertyInfo, queryableGroupNameCountPairInfo.CountPropertyInfo } ); - - LambdaExpression finalLambdaExpression = System.Linq.Expressions.Expression.Lambda( newExpression, groupedParameters ); - - MethodCallExpression finalSelectExpression = - System.Linq.Expressions.Expression.Call( - typeof( Queryable ), "Select", - new Type[] { groupedResult.ElementType, finalLambdaExpression.Body.Type }, - new System.Linq.Expressions.Expression[] { groupedResult.Expression, System.Linq.Expressions.Expression.Quote( finalLambdaExpression ) } ); - - return groupedResult.Provider.CreateQuery( finalSelectExpression ); - } - - internal static IQueryable Slice( this IQueryable queryable, int skip, int take ) - { - if( queryable == null ) - throw new ArgumentNullException( "queryable" ); - - Expression skipAndTakeExpression = queryable.Expression; - - Type queryableElementType = queryable.ElementType; - - skipAndTakeExpression = QueryableExtensions.Skip( queryableElementType, skipAndTakeExpression, skip ); - skipAndTakeExpression = QueryableExtensions.Take( queryableElementType, skipAndTakeExpression, take ); - - return queryable.Provider.CreateQuery( skipAndTakeExpression ); - } - - internal static int Count( this IQueryable queryable ) - { - if( queryable == null ) - throw new ArgumentNullException( "queryable" ); - - Type queryableElementType = queryable.ElementType; - Expression expressionToCount = queryable.Expression; - - MethodCallExpression countExpression = Expression.Call( - typeof( Queryable ), "Count", - new Type[] { queryableElementType }, expressionToCount ); - - Debug.WriteLineIf( VirtualPageManager.DebugDataVirtualization, "Beginning Provider Execute for total count." ); - int count = ( int )queryable.Provider.Execute( countExpression ); - Debug.WriteLineIf( VirtualPageManager.DebugDataVirtualization, "Ended Provider Execute for total count." ); - return count; - } - - #endregion SELECTING - - #region PRIVATE METHODS - - private static IQueryable OrderByKey( this IQueryable queryable, bool ascending ) - { - if( queryable == null ) - throw new ArgumentNullException( "queryable" ); - - Expression orderedExpression = queryable.Expression; - - Type queryableElementType = queryable.ElementType; - - ParameterExpression parameter = queryable.CreateParameterExpression(); - - MemberExpression sortMemberExpression = QueryableExtensions.GenerateMemberExpression( parameter, "Key" ); - - string methodName = ( ascending ) ? "OrderBy" : "OrderByDescending"; - - orderedExpression = Expression.Call( typeof( Queryable ), - methodName, - new Type[] { queryableElementType, sortMemberExpression.Type }, - orderedExpression, Expression.Quote( Expression.Lambda( sortMemberExpression, parameter ) ) ); - - return queryable.Provider.CreateQuery( orderedExpression ); - } - - - internal static MemberExpression GenerateMemberExpression( ParameterExpression typeExpression, string name ) - { - if( string.IsNullOrEmpty( name ) ) - { - if( name == null ) - throw new ArgumentNullException( "name" ); - - throw new ArgumentException( "A name must be provided.", "name" ); - } - - MemberExpression memberExpression = null; - - MemberInfo member = QueryableExtensions.GetMemberInfo( typeExpression.Type, name ); - - if( member == null ) - throw new DataGridInternalException( "MemberInfo is null." ); - - if( member is PropertyInfo ) - { - // Member is a property. - memberExpression = Expression.Property( typeExpression, ( PropertyInfo )member ); - } - else - { - // Member is a field. - memberExpression = Expression.Field( typeExpression, ( FieldInfo )member ); - } - - return memberExpression; - } - - private static MethodCallExpression Take( Type queryableElementType, Expression expression, int count ) - { - if( queryableElementType == null ) - throw new ArgumentNullException( "queryableElementType" ); - - if( expression == null ) - throw new ArgumentNullException( "expression" ); - - return Expression.Call( typeof( Queryable ), "Take", new Type[] { queryableElementType }, expression, Expression.Constant( count ) ); - } - - private static MethodCallExpression Skip( Type queryableElementType, Expression expression, int count ) - { - if( queryableElementType == null ) - throw new ArgumentNullException( "queryableElementType" ); - - if( expression == null ) - throw new ArgumentNullException( "expression" ); - - return Expression.Call( typeof( Queryable ), "Skip", new Type[] { queryableElementType }, expression, Expression.Constant( count ) ); - } - - private static string GetMethodNameFromStringFilterMode( StringFilterMode stringFilterMode ) - { - switch( stringFilterMode ) - { - case StringFilterMode.StartsWith: - { - return "StartsWith"; - } - - case StringFilterMode.Contains: - { - return "Contains"; - } - - case StringFilterMode.EndsWith: - { - return "EndsWith"; - } - } - - Debug.Fail( "Should have handled the new StringFilterMode." ); - return string.Empty; - } - - private static Expression FilterString( - this IQueryable queryable, - ParameterExpression sharedParameterExpression, - string propertyName, - string[] values, - StringFilterMode stringFilterMode ) - { - if( queryable == null ) - throw new ArgumentNullException( "queryable" ); - - if( ( values == null ) || ( values.Length == 0 ) ) - throw new ArgumentNullException( "values" ); - - string methodName = QueryableExtensions.GetMethodNameFromStringFilterMode( stringFilterMode ); - - Debug.Assert( !String.IsNullOrEmpty( methodName ) ); - - MemberExpression memberExpression = QueryableExtensions.GenerateMemberExpression( sharedParameterExpression, propertyName ); - - Expression mergedFilterCall = null; - - for( int i = 0; i < values.Length; i++ ) - { - ConstantExpression valueExpression = Expression.Constant( values[ i ] ); - - MethodCallExpression newFilterCall = Expression.Call( - memberExpression, - typeof( string ).GetMethod( methodName, new Type[] { typeof( string ) } ), - Expression.Convert( valueExpression, memberExpression.Type ) ); - - if( mergedFilterCall == null ) - { - mergedFilterCall = newFilterCall; - } - else - { - mergedFilterCall = MethodCallExpression.Or( mergedFilterCall, newFilterCall ); - } - } - - return mergedFilterCall; - } - - #endregion PRIVATE METHODS - - #region PRIVATE FIELDS - - private delegate Expression BinaryComparisonDelegate( Expression left, Expression right ); - - - - - #endregion PRIVATE FIELDS - - #region INTERNAL NESTED CLASSES - - internal interface IQueryableGroupNameCountPair - { - object GroupName - { - get; - } - - Type GroupNameType - { - get; - } - - int Count - { - get; - } - } - - #endregion INTERNAL NESTED CLASSES - - #region PRIVATE NESTED CLASSES - - private class QueryableGroupNameCountPair : IQueryableGroupNameCountPair - { - public QueryableGroupNameCountPair( T groupName, int count ) - { - this.GroupName = groupName; - this.Count = count; - } - - public T GroupName - { - get; - set; - } - - public int Count - { - get; - set; - } - - #region QueryableGroupNameCountPair Members - - object IQueryableGroupNameCountPair.GroupName - { - get - { - return this.GroupName; - } - } - - public Type GroupNameType - { - get - { - return typeof( T ); - } - } - - int IQueryableGroupNameCountPair.Count - { - get - { - return this.Count; - } - } - - #endregion - } - - private static class QueryableGroupNameCountPairInfos - { - public static QueryableGroupNameCountPairInfo GetInfosForType( Type sourceType ) - { - if( QueryableGroupNameCountPairInfos.ReflectionInfoDictionary == null ) - QueryableGroupNameCountPairInfos.ReflectionInfoDictionary = new Dictionary(); - - QueryableGroupNameCountPairInfo queryableGroupNameCountPairInfo; - - if( !QueryableGroupNameCountPairInfos.ReflectionInfoDictionary.TryGetValue( sourceType, out queryableGroupNameCountPairInfo ) ) - { - Type queryableGroupNameCountPairType = typeof( QueryableGroupNameCountPair<> ).MakeGenericType( sourceType ); - - ConstructorInfo constructorInfo = - queryableGroupNameCountPairType.GetConstructor( new Type[] { sourceType, typeof( int ) } ); - - PropertyInfo keyPropertyInfo = queryableGroupNameCountPairType.GetProperty( "GroupName" ); - PropertyInfo countPropertyInfo = queryableGroupNameCountPairType.GetProperty( "Count" ); - - queryableGroupNameCountPairInfo = new QueryableGroupNameCountPairInfo() - { - Type = queryableGroupNameCountPairType, - ConstructorInfo = constructorInfo, - KeyPropertyInfo = keyPropertyInfo, - CountPropertyInfo = countPropertyInfo - }; - - QueryableGroupNameCountPairInfos.ReflectionInfoDictionary.Add( sourceType, queryableGroupNameCountPairInfo ); - } - - return queryableGroupNameCountPairInfo; - } - - private static Dictionary ReflectionInfoDictionary; - } - - private struct QueryableGroupNameCountPairInfo - { - public Type Type - { - get; - set; - } - - public ConstructorInfo ConstructorInfo - { - get; - set; - } - - public PropertyInfo KeyPropertyInfo - { - get; - set; - } - - public PropertyInfo CountPropertyInfo - { - get; - set; - } - } - - #endregion PRIVATE NESTED CLASSES - - #region PRIVATE NESTED ENUMS - - private enum StringFilterMode - { - StartsWith = 0, - Contains = 1, - EndsWith = 2 - } - - #endregion PRIVATE NESTED ENUMS - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/RawItem.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/RawItem.cs deleted file mode 100644 index d422c4dc..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/RawItem.cs +++ /dev/null @@ -1,104 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - // We use an intermediate liste to always acces the source with the index - // and never directly by keeping a variable that contains the source item directly. - // ( We do that to be able to work correctly with a DataView has source ) - // - // RawItem is always pointing at the same item. - // The dataIndex may be changing to always represent the same item if the item is moving in the source. - internal class RawItem - { - public RawItem( int dataIndex, object dataItem ) - { - m_dataIndex = dataIndex; - m_dataItem = dataItem; - m_sortedIndex = -1; - } - - public int Index - { - get - { - return m_dataIndex; - } - } - - public int SortedIndex - { - get - { - return m_sortedIndex; - } - } - - public object DataItem - { - get - { - return m_dataItem; - } - } - - public DataGridCollectionViewGroup ParentGroup - { - get - { - return m_parentGroup; - } - } - - public int GetGlobalSortedIndex() - { - if( m_parentGroup == null ) - return -1; - - return m_sortedIndex + m_parentGroup.GetFirstRawItemGlobalSortedIndex(); - } - - internal void SetIndex( int newIndex ) - { - m_dataIndex = newIndex; - } - - internal void SetParentGroup( DataGridCollectionViewGroup parentGroup ) - { - m_parentGroup = parentGroup; - } - - internal void SetSortedIndex( int newIndex ) - { - m_sortedIndex = newIndex; - } - - internal void SetDataItem( object dataItem ) - { - m_dataItem = dataItem; - } - - private object m_dataItem; - private int m_dataIndex; - private int m_sortedIndex; - private DataGridCollectionViewGroup m_parentGroup; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/RawItemIndexComparer.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/RawItemIndexComparer.cs deleted file mode 100644 index fff0886d..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/RawItemIndexComparer.cs +++ /dev/null @@ -1,58 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - internal class RawItemIndexComparer : IComparer - { - public RawItemIndexComparer() - { - } - - #region IComparer Members - - public int Compare( RawItem x, RawItem y ) - { - if( x == null ) - { - if( y == null ) - { - return 0; - } - else - { - return -1; - } - } - else - { - if( y == null ) - { - return 1; - } - } - - return x.Index - y.Index; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/RawItemMap.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/RawItemMap.cs deleted file mode 100644 index 01bef4eb..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/RawItemMap.cs +++ /dev/null @@ -1,145 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class RawItemMap - { - #region [] Property - - internal RawItem this[ object dataItem ] - { - get - { - Debug.Assert( dataItem != null ); - - RawItem value; - if( m_singleMap.TryGetValue( dataItem, out value ) ) - return value; - - RawItem[] values; - if( m_multiMap.TryGetValue( dataItem, out values ) ) - return values[ 0 ]; - - return null; - } - } - - #endregion - - internal void Add( object dataItem, RawItem rawItem ) - { - Debug.Assert( dataItem != null ); - Debug.Assert( rawItem != null ); - Debug.Assert( dataItem == rawItem.DataItem ); - - RawItem single; - RawItem[] multiple; - - if( m_singleMap.TryGetValue( dataItem, out single ) ) - { - Debug.Assert( rawItem != single, "It's not normal to be called twice for the same RawItem." ); - - m_multiMap.Add( dataItem, new RawItem[] { single, rawItem } ); - m_singleMap.Remove( dataItem ); - } - else if( m_multiMap.TryGetValue( dataItem, out multiple ) ) - { - Debug.Assert( !multiple.Contains( rawItem ), "It's not normal to be called twice for the same RawItem." ); - - var length = multiple.Length; - - Array.Resize( ref multiple, length + 1 ); - multiple[ length ] = rawItem; - - m_multiMap[ dataItem ] = multiple; - } - else - { - m_singleMap.Add( dataItem, rawItem ); - } - } - - internal void Remove( object dataItem, RawItem rawItem ) - { - Debug.Assert( dataItem != null ); - Debug.Assert( rawItem != null ); - Debug.Assert( dataItem == rawItem.DataItem ); - - if( m_singleMap.Remove( dataItem ) ) - return; - - RawItem[] multiple; - if( !m_multiMap.TryGetValue( dataItem, out multiple ) ) - return; - - var length = multiple.Length; - if( length == 2 ) - { - if( multiple[ 0 ] == rawItem ) - { - m_singleMap.Add( dataItem, multiple[ 1 ] ); - m_multiMap.Remove( dataItem ); - } - else if( multiple[ 1 ] == rawItem ) - { - m_singleMap.Add( dataItem, multiple[ 0 ] ); - m_multiMap.Remove( dataItem ); - } - } - else - { - Debug.Assert( length > 2 ); - - var index = Array.IndexOf( multiple, rawItem ); - if( index < 0 ) - return; - - RawItem[] copy = new RawItem[ length - 1 ]; - - if( index > 0 ) - { - Array.Copy( multiple, 0, copy, 0, index ); - } - - if( index < length - 1 ) - { - Array.Copy( multiple, index + 1, copy, index, length - index - 1 ); - } - - m_multiMap[ dataItem ] = copy; - } - } - - internal void Clear() - { - m_singleMap.Clear(); - m_multiMap.Clear(); - } - - #region Private Fields - - private readonly Dictionary m_singleMap = new Dictionary( 128 ); - private readonly Dictionary m_multiMap = new Dictionary( 0 ); - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/RawItemSortComparer.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/RawItemSortComparer.cs deleted file mode 100644 index a3decd05..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/RawItemSortComparer.cs +++ /dev/null @@ -1,120 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Collections.Generic; -using System.ComponentModel; - -using Xceed.Utils.Data; - -namespace Xceed.Wpf.DataGrid -{ - internal class RawItemSortComparer : IComparer - { - public RawItemSortComparer( DataGridCollectionView collectionView ) - { - m_collectionView = collectionView; - } - - #region IComparer Members - - public int Compare( RawItem xRawItem, RawItem yRawItem ) - { - if( xRawItem == null ) - return ( yRawItem == null ) ? 0 : -1; - - if( yRawItem == null ) - return 1; - - var lastSortDirection = ListSortDirection.Ascending; - var sortDescriptions = m_collectionView.SortDescriptions; - var sortDescriptionCount = sortDescriptions.Count; - - if( sortDescriptionCount > 0 ) - { - var result = default( int ); - var itemProperties = m_collectionView.ItemProperties; - - for( int i = 0; i < sortDescriptionCount; i++ ) - { - var sortDescription = sortDescriptions[ i ]; - lastSortDirection = sortDescription.Direction; - - var itemProperty = ItemsSourceHelper.GetItemPropertyFromProperty( itemProperties, sortDescription.PropertyName ); - if( itemProperty == null ) - continue; - - var supportInitialize = itemProperty as ISupportInitialize; - var xData = default( object ); - var yData = default( object ); - - if( supportInitialize != null ) - { - supportInitialize.BeginInit(); - } - - try - { - xData = ItemsSourceHelper.GetValueFromItemProperty( itemProperty, xRawItem.DataItem ); - yData = ItemsSourceHelper.GetValueFromItemProperty( itemProperty, yRawItem.DataItem ); - - if( itemProperty.IsSortingOnForeignKeyDescription ) - { - var foreignKeyDescription = itemProperty.ForeignKeyDescription; - - xData = foreignKeyDescription.GetDisplayValue( xData ); - yData = foreignKeyDescription.GetDisplayValue( yData ); - } - } - finally - { - if( supportInitialize != null ) - { - supportInitialize.EndInit(); - } - } - - var sortComparer = itemProperty.SortComparer; - - if( sortComparer != null ) - { - result = sortComparer.Compare( xData, yData ); - } - else - { - result = ObjectDataStore.CompareData( xData, yData ); - } - - if( result != 0 ) - { - if( lastSortDirection == ListSortDirection.Descending ) - return -result; - - return result; - } - } - } - - if( lastSortDirection == ListSortDirection.Descending ) - return yRawItem.Index - xRawItem.Index; - - return xRawItem.Index - yRawItem.Index; - } - - #endregion - - private DataGridCollectionView m_collectionView; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/SelfPropertyDescriptor.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/SelfPropertyDescriptor.cs deleted file mode 100644 index 7a73eacd..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/SelfPropertyDescriptor.cs +++ /dev/null @@ -1,102 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.ComponentModel; -using System.Data; -using System.Collections; -using System.Globalization; - -namespace Xceed.Wpf.DataGrid -{ - internal class SelfPropertyDescriptor : PropertyDescriptor - { - public SelfPropertyDescriptor( Type columnDataType ) - : base( ".", null ) - { - m_columnDataType = columnDataType; - } - - public override AttributeCollection Attributes - { - get - { - if( typeof( IList ).IsAssignableFrom( this.PropertyType ) ) - { - Attribute[] array = new Attribute[ base.Attributes.Count + 1 ]; - base.Attributes.CopyTo( array, 0 ); - array[ array.Length - 1 ] = new ListBindableAttribute( false ); - return new AttributeCollection( array ); - } - - return base.Attributes; - } - } - - public override Type ComponentType - { - get - { - return m_columnDataType; - } - } - - public override bool IsReadOnly - { - get - { - return true; - } - } - - public override Type PropertyType - { - get - { - return m_columnDataType; - } - } - - public override bool CanResetValue( object component ) - { - return false; - } - - public override object GetValue( object component ) - { - return component; - } - - public override void ResetValue( object component ) - { - throw new InvalidOperationException( "An attempt was made to set a value on a read-only property." ); - } - - public override void SetValue( object component, object value ) - { - throw new InvalidOperationException( "An attempt was made to set a value on a read-only property." ); - } - - public override bool ShouldSerializeValue( object component ) - { - return false; - } - - private Type m_columnDataType; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/SortDescriptionsSyncContext.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/SortDescriptionsSyncContext.cs deleted file mode 100644 index 6976c602..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/SortDescriptionsSyncContext.cs +++ /dev/null @@ -1,66 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - internal class SortDescriptionsSyncContext - { - //public bool IsInitializing - //{ - // get - // { - // return m_isInitializing; - // } - // set - // { - // m_isInitializing = value; - // } - //} - - public bool ProcessingSortSynchronization - { - get - { - return m_processingSortSynchronization; - } - set - { - m_processingSortSynchronization = value; - } - } - - //public bool SynchronizeSortDelayed - //{ - // get - // { - // return m_synchronizeSortDelayed; - // } - // set - // { - // m_synchronizeSortDelayed = value; - // } - //} - - private bool m_processingSortSynchronization; - //private bool m_synchronizeSortDelayed; - //private bool m_isInitializing; - - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/SortedDescriptionInfo.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/SortedDescriptionInfo.cs deleted file mode 100644 index 46a87291..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/SortedDescriptionInfo.cs +++ /dev/null @@ -1,131 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; -using System.Collections; - -using Xceed.Utils.Data; -using System.Windows.Data; - -namespace Xceed.Wpf.DataGrid -{ - internal class SortDescriptionInfo - { - public SortDescriptionInfo( DataGridItemPropertyBase property, ListSortDirection direction ) - { - m_property = property; - m_direction = direction; - } - - #region SortDirection Property - - public ListSortDirection SortDirection - { - get - { - return m_direction; - } - } - - #endregion - - #region Property Property - - public DataGridItemPropertyBase Property - { - get - { - return m_property; - } - } - - #endregion - - #region DataStore Property - - public DataStore DataStore - { - get - { - return m_dataStore; - } - set - { - m_dataStore = value; - } - } - - #endregion - - #region SortComparer Property - - public IComparer SortComparer - { - get - { - if( m_property == null ) - return null; - - return m_property.SortComparer; - } - } - - #endregion - - public bool IsReverseOf( SortDescriptionInfo sortDescriptionInfo ) - { - if( sortDescriptionInfo.m_property == m_property ) - { - switch( sortDescriptionInfo.m_direction ) - { - case ListSortDirection.Ascending: - return m_direction == ListSortDirection.Descending; - - case ListSortDirection.Descending: - return m_direction == ListSortDirection.Ascending; - } - } - - return false; - } - - public override bool Equals( object obj ) - { - SortDescriptionInfo sortDescriptionInfo = obj as SortDescriptionInfo; - - if( sortDescriptionInfo == null ) - return false; - - if( ( sortDescriptionInfo.m_direction == m_direction ) && - ( sortDescriptionInfo.m_property == m_property ) ) - { - return true; - } - - return false; - } - - public override int GetHashCode() - { - return ( m_property.GetHashCode() ) ^ ( ( int )m_direction << 14 ); - } - - private ListSortDirection m_direction; // Initialize in constructor - private DataGridItemPropertyBase m_property; // Initialize in constructor - private DataStore m_dataStore; // = null - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/SourceItemCollection.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/SourceItemCollection.cs deleted file mode 100644 index d9f6d467..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/SourceItemCollection.cs +++ /dev/null @@ -1,239 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Text; -using System.Windows.Markup; - -namespace Xceed.Wpf.DataGrid -{ - internal class SourceItemCollection : IList, IAddChild - { - internal SourceItemCollection( DataGridCollectionView parentCollectionView ) - { - if( parentCollectionView == null ) - throw new ArgumentNullException( "parentCollectionView" ); - - m_parentCollectionView = parentCollectionView; - } - - #region IList Members - - public int Add( object value ) - { - int index = this.Count; - this.Insert( index, value ); - return index; - } - - public void Clear() - { - this.CheckParentCollectionViewSourceNotUsed(); - m_parentCollectionView.RemoveSourceItem( 0, this.Count ); - } - - public bool Contains( object value ) - { - return m_parentCollectionView.IndexOfSourceItem( value ) != -1; - } - - public int IndexOf( object value ) - { - return m_parentCollectionView.IndexOfSourceItem( value ); - } - - public void Insert( int index, object value ) - { - this.CheckParentCollectionViewSourceNotUsed(); - - if( ( index < 0 ) || ( index > this.Count ) ) - throw new ArgumentOutOfRangeException( "index", index, "index must be greater than or equal to zero and less than or equal to Count." ); - - m_parentCollectionView.AddSourceItem( index, new object[] { value }, this.Count + 1 ); - } - - public bool IsFixedSize - { - get - { - return !this.ParentCollectionViewSourceNotUsed(); - } - } - - public bool IsReadOnly - { - get - { - return !this.ParentCollectionViewSourceNotUsed(); - } - } - - public void Remove( object value ) - { - this.CheckParentCollectionViewSourceNotUsed(); - int index = this.IndexOf( value ); - - if( index != -1 ) - m_parentCollectionView.RemoveSourceItem( index, 1 ); - } - - public void RemoveAt( int index ) - { - this.CheckParentCollectionViewSourceNotUsed(); - - if( ( index < 0 ) || ( index >= this.Count ) ) - throw new ArgumentOutOfRangeException( "index", index, "index must be greater than or equal to zero and less than Count." ); - - m_parentCollectionView.RemoveSourceItem( index, 1 ); - } - - public object this[ int index ] - { - get - { - if( ( index < 0 ) || ( index >= this.Count ) ) - throw new ArgumentOutOfRangeException( "index", index, "index must be greater than or equal to zero and less than Count." ); - - return m_parentCollectionView.GetSourceItemAt( index ); - } - set - { - if( ( index < 0 ) || ( index >= this.Count ) ) - throw new ArgumentOutOfRangeException( "index", index, "index must be greater than or equal to zero and less than Count." ); - - m_parentCollectionView.ReplaceSourceItem( - index, new object[] { this[ index ] }, - index, new object[] { value } ); - } - } - - #endregion - - #region ICollection Members - - public void CopyTo( Array array, int index ) - { - int count = this.Count; - - for( int i = 0; i < count; i++ ) - { - array.SetValue( this[ i ], index ); - index++; - } - } - - public int Count - { - get - { - return m_parentCollectionView.SourceItemCount; - } - } - - public bool IsSynchronized - { - get - { - return false; - } - } - - public object SyncRoot - { - get - { - return this; - } - } - - #endregion - - #region IEnumerable Members - - public IEnumerator GetEnumerator() - { - return new SourceItemCollectionEnumerator( m_parentCollectionView.GetSourceListEnumerator() ); - } - - #endregion - - #region IAddChild Members - - void IAddChild.AddChild( object value ) - { - this.Add( value ); - } - - void IAddChild.AddText( string text ) - { - this.Add( text ); - } - - #endregion - - private void CheckParentCollectionViewSourceNotUsed() - { - if( this.ParentCollectionViewSourceNotUsed() ) - throw new InvalidOperationException( "An attempt was made to modify the list of items while a source is being used." ); - } - - private bool ParentCollectionViewSourceNotUsed() - { - return ( m_parentCollectionView.SourceCollection != null ); - } - - private DataGridCollectionView m_parentCollectionView; - - private class SourceItemCollectionEnumerator : IEnumerator - { - public SourceItemCollectionEnumerator( IEnumerator rawItemEnumerator ) - { - m_rawItemEnumerator = rawItemEnumerator; - } - - #region IEnumerator Members - - public object Current - { - get - { - RawItem currentItem = m_rawItemEnumerator.Current; - - if( currentItem == null ) - return null; - - return currentItem.DataItem; - } - } - - public bool MoveNext() - { - return m_rawItemEnumerator.MoveNext(); - } - - public void Reset() - { - m_rawItemEnumerator.Reset(); - } - - #endregion - - private IEnumerator m_rawItemEnumerator; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/StatResultComparer.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/StatResultComparer.cs deleted file mode 100644 index fdec585f..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/StatResultComparer.cs +++ /dev/null @@ -1,78 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Collections; - -namespace Xceed.Wpf.DataGrid -{ - internal class StatResultComparer : IComparer - { - private StatResultComparer() - { - } - - #region Singleton Property - - public static StatResultComparer Singleton - { - get - { - if( _singleton == null ) - _singleton = new StatResultComparer(); - - return _singleton; - } - } - - private static StatResultComparer _singleton; - - #endregion Singleton Property - - public int Compare( object x, object y ) - { - bool xIsExceptionOrNull = ( x == null ) || ( x == DBNull.Value ) || ( x is Exception ); - bool yIsExceptionOrNull = ( y == null ) || ( y == DBNull.Value ) || ( y is Exception ); - - if( xIsExceptionOrNull ) - { - if( yIsExceptionOrNull ) - { - return 0; - } - else - { - return -1; - } - } - else - { - if( yIsExceptionOrNull ) - return 1; - - IComparable xComparer = x as IComparable; - - if( xComparer != null ) - return xComparer.CompareTo( y ); - - return 0; - } - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/UnboundDataItem.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/UnboundDataItem.cs deleted file mode 100644 index aff4b0a8..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/UnboundDataItem.cs +++ /dev/null @@ -1,92 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Collections; -using System.Collections.Generic; -using Xceed.Utils.Collections; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class UnboundDataItem - { - #region Static Fields - - private static readonly WeakDictionary s_collection = new WeakDictionary( 0, new Comparer() ); - private static readonly UnboundDataItem s_empty = new UnboundDataItem( null ); - - #endregion - - private UnboundDataItem( object dataItem ) - { - m_dataItem = dataItem; - } - - #region DataItem Property - - internal object DataItem - { - get - { - return m_dataItem; - } - } - - private readonly object m_dataItem; - - #endregion - - internal static UnboundDataItem GetUnboundDataItem( object dataItem ) - { - if( dataItem == null ) - return s_empty; - - var value = dataItem as UnboundDataItem; - if( value != null ) - return value; - - lock( ( ( ICollection )s_collection ).SyncRoot ) - { - if( !s_collection.TryGetValue( dataItem, out value ) ) - { - value = new UnboundDataItem( dataItem ); - s_collection.Add( dataItem, value ); - } - - return value; - } - } - - #region Comparer Private Class - - private sealed class Comparer : IEqualityComparer - { - int IEqualityComparer.GetHashCode( object obj ) - { - if( obj == null ) - return 0; - - return obj.GetHashCode(); - } - - bool IEqualityComparer.Equals( object x, object y ) - { - return object.Equals( x, y ); - } - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/UnboundDataRowPropertyDescriptor.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/UnboundDataRowPropertyDescriptor.cs deleted file mode 100644 index d9f5e154..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(CollectionView)/UnboundDataRowPropertyDescriptor.cs +++ /dev/null @@ -1,141 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.ComponentModel; -using System.Data; -using System.Collections; - -namespace Xceed.Wpf.DataGrid -{ - internal class UnboundDataRowPropertyDescriptor : PropertyDescriptor - { - public UnboundDataRowPropertyDescriptor( string fieldName, Type dataType ) - : base( fieldName, null ) - { - if( string.IsNullOrEmpty( fieldName ) ) - throw new ArgumentException( "fieldName must not be null or empty.", "fieldName" ); - - if( dataType == null ) - throw new ArgumentNullException( "dataType" ); - - m_fieldName = fieldName; - m_dataType = dataType; - } - - public override string DisplayName - { - get - { - return m_fieldName; - } - } - - public override AttributeCollection Attributes - { - get - { - if( typeof( IList ).IsAssignableFrom( this.PropertyType ) ) - { - Attribute[] array = new Attribute[ base.Attributes.Count + 1 ]; - base.Attributes.CopyTo( array, 0 ); - array[ array.Length - 1 ] = new ListBindableAttribute( false ); - return new AttributeCollection( array ); - } - - return base.Attributes; - } - } - - public override Type ComponentType - { - get - { - return typeof( DataRow ); - } - } - - public override bool IsReadOnly - { - get - { - return false; - } - } - - public override Type PropertyType - { - get - { - return m_dataType; - } - } - - public override bool CanResetValue( object component ) - { - object value = this.GetValue( component ); - return ( value != null ) && ( value != DBNull.Value ); - } - - public override object GetValue( object component ) - { - DataRow dataRow = component as DataRow; - - if( dataRow == null ) - return null; - - Cell cell = dataRow.Cells[ m_fieldName ]; - - if( cell == null ) - return null; - - return cell.Content; - } - - public override void ResetValue( object component ) - { - this.SetValue( component, null ); - } - - public override void SetValue( object component, object value ) - { - if( this.IsReadOnly ) - throw new InvalidOperationException( "An attempt was made to set a value on a read-only field." ); - - DataRow dataRow = component as DataRow; - - if( dataRow == null ) - throw new InvalidOperationException( "An attempt was made to set a value on a DataRow that does not exist." ); - - Cell cell = dataRow.Cells[ m_fieldName ]; - - if( cell == null ) - throw new InvalidOperationException( "An attempt was made to set a value on a Cell that does not exist." ); - - cell.Content = value; - } - - public override bool ShouldSerializeValue( object component ) - { - return false; - } - - private string m_fieldName; - private Type m_dataType; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/AddingNewDataItemEventArgs.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/AddingNewDataItemEventArgs.cs deleted file mode 100644 index 54ee691c..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/AddingNewDataItemEventArgs.cs +++ /dev/null @@ -1,45 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; - -namespace Xceed.Wpf.DataGrid -{ - [Obsolete( "The AddingNewDataItem event is obsolete and has been replaced by the DataGridCollectionView.InsertingNewItem and InitializingNewItem events.", false )] - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - public class AddingNewDataItemEventArgs : EventArgs - { - public AddingNewDataItemEventArgs() - { - } - - public object DataItem - { - get - { - return m_dataItem; - } - set - { - m_dataItem = value; - } - } - - private object m_dataItem; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/AllowDetailToggleChangedEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/AllowDetailToggleChangedEventManager.cs deleted file mode 100644 index 97ee3092..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/AllowDetailToggleChangedEventManager.cs +++ /dev/null @@ -1,94 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal class AllowDetailToggleChangedEventManager : WeakEventManager - { - internal static void AddListener( object source, IWeakEventListener listener ) - { - CurrentManager.ProtectedAddListener( source, listener ); - } - - internal static void RemoveListener( object source, IWeakEventListener listener ) - { - CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - DataGridControl dataGridControl = source as DataGridControl; - if( dataGridControl != null ) - { - dataGridControl.AllowDetailToggleChanged += new EventHandler( this.OnAllowDetailToggleChanged ); - return; - } - - DetailConfiguration detailConfiguration = source as DetailConfiguration; - if( detailConfiguration != null ) - { - detailConfiguration.AllowDetailToggleChanged += new EventHandler( this.OnAllowDetailToggleChanged ); - return; - } - - throw new ArgumentException( "The specified source must be a DataGridControl or a DetailConfiguration.", "source" ); - } - - protected override void StopListening( object source ) - { - DataGridControl dataGridControl = source as DataGridControl; - if( dataGridControl != null ) - { - dataGridControl.AllowDetailToggleChanged -= new EventHandler( this.OnAllowDetailToggleChanged ); - return; - } - - DetailConfiguration detailConfiguration = source as DetailConfiguration; - if( detailConfiguration != null ) - { - detailConfiguration.AllowDetailToggleChanged -= new EventHandler( this.OnAllowDetailToggleChanged ); - return; - } - - throw new ArgumentException( "The specified source must be a DataGridControl or a DetailConfiguration.", "source" ); - } - - private static AllowDetailToggleChangedEventManager CurrentManager - { - get - { - Type managerType = typeof( AllowDetailToggleChangedEventManager ); - AllowDetailToggleChangedEventManager currentManager = ( AllowDetailToggleChangedEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new AllowDetailToggleChangedEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - private void OnAllowDetailToggleChanged( object sender, EventArgs args ) - { - this.DeliverEvent( sender, args ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/CancelRoutedEvent.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/CancelRoutedEvent.cs deleted file mode 100644 index 972f097d..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/CancelRoutedEvent.cs +++ /dev/null @@ -1,59 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - public delegate void CancelRoutedEventHandler( object sender, CancelRoutedEventArgs e ); - - public class CancelRoutedEventArgs : RoutedEventArgs - { - public CancelRoutedEventArgs() - : base() - { - } - - public CancelRoutedEventArgs( RoutedEvent routedEvent ) - : base( routedEvent ) - { - } - - public CancelRoutedEventArgs( RoutedEvent routedEvent, object source ) - : base( routedEvent, source ) - { - } - - #region Cancel PROPERTY - - public bool Cancel - { - get - { - return m_cancel; - } - - set - { - m_cancel = value; - } - } - - private bool m_cancel; - - #endregion Cancel PROPERTY - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/CellValidatingEventArgs.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/CellValidatingEventArgs.cs deleted file mode 100644 index 0ce4b2d7..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/CellValidatingEventArgs.cs +++ /dev/null @@ -1,81 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Globalization; -using System.Windows.Controls; - -namespace Xceed.Wpf.DataGrid -{ - public class CellValidatingEventArgs : EventArgs - { - public CellValidatingEventArgs( - object value, - CultureInfo culture, - CellValidationContext context ) - { - m_value = value; - m_culture = culture; - m_context = context; - } - - public object Value - { - get - { - return m_value; - } - } - - public CultureInfo Culture - { - get - { - return m_culture; - } - } - - public CellValidationContext Context - { - get - { - return m_context; - } - } - - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly" )] - public ValidationResult Result - { - get - { - return m_validationResult; - } - - set - { - if( value == null ) - throw new ArgumentNullException( "Result" ); - - m_validationResult = value; - } - } - - object m_value; - CultureInfo m_culture; - CellValidationContext m_context; - ValidationResult m_validationResult = ValidationResult.ValidResult; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/CellValidationErrorRoutedEvent.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/CellValidationErrorRoutedEvent.cs deleted file mode 100644 index 51376a50..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/CellValidationErrorRoutedEvent.cs +++ /dev/null @@ -1,67 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - public delegate void CellValidationErrorRoutedEventHandler( object sender, CellValidationErrorRoutedEventArgs e ); - - public class CellValidationErrorRoutedEventArgs : RoutedEventArgs - { - public CellValidationErrorRoutedEventArgs( CellValidationError cellValidationError ) - : base() - { - if( cellValidationError == null ) - throw new ArgumentNullException( "cellValidationError" ); - - m_cellValidationError = cellValidationError; - } - - public CellValidationErrorRoutedEventArgs( RoutedEvent routedEvent, CellValidationError cellValidationError ) - : base( routedEvent ) - { - if( cellValidationError == null ) - throw new ArgumentNullException( "cellValidationError" ); - - m_cellValidationError = cellValidationError; - } - - public CellValidationErrorRoutedEventArgs( RoutedEvent routedEvent, object source, CellValidationError cellValidationError ) - : base( routedEvent, source ) - { - if( cellValidationError == null ) - throw new ArgumentNullException( "cellValidationError" ); - - m_cellValidationError = cellValidationError; - } - - #region CellValidationError PROPERTY - - public CellValidationError CellValidationError - { - get - { - return m_cellValidationError; - } - } - - private CellValidationError m_cellValidationError; - - #endregion CellValidationError PROPERTY - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/ColumnActualWidthChangedEvent.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/ColumnActualWidthChangedEvent.cs deleted file mode 100644 index 4df0ddf5..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/ColumnActualWidthChangedEvent.cs +++ /dev/null @@ -1,60 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid -{ - internal class ColumnActualWidthChangedEventArgs : EventArgs - { - internal ColumnActualWidthChangedEventArgs( ColumnBase column, double oldValue, double newValue ) - { - m_column = column; - m_oldValue = oldValue; - m_newValue = newValue; - } - - internal ColumnBase Column - { - get - { - return m_column; - } - } - - internal double NewValue - { - get - { - return m_newValue; - } - } - - internal double OldValue - { - get - { - return m_oldValue; - } - } - - private ColumnBase m_column; - private double m_oldValue; - private double m_newValue; - } - - internal delegate void ColumnActualWidthChangedEventHandler( object sender, ColumnActualWidthChangedEventArgs e ); -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/ColumnActualWidthEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/ColumnActualWidthEventManager.cs deleted file mode 100644 index b06c6463..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/ColumnActualWidthEventManager.cs +++ /dev/null @@ -1,68 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal class ColumnActualWidthEventManager : WeakEventManager - { - internal static void AddListener( ColumnCollection source, IWeakEventListener listener ) - { - CurrentManager.ProtectedAddListener( source, listener ); - } - - internal static void RemoveListener( ColumnCollection source, IWeakEventListener listener ) - { - CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - ColumnCollection columns = ( ColumnCollection )source; - columns.ActualWidthChanged += new ColumnActualWidthChangedEventHandler( this.OnActualWidthChanged ); - } - - protected override void StopListening( object source ) - { - ColumnCollection columns = ( ColumnCollection )source; - columns.ActualWidthChanged -= new ColumnActualWidthChangedEventHandler( this.OnActualWidthChanged ); - } - - private static ColumnActualWidthEventManager CurrentManager - { - get - { - Type managerType = typeof( ColumnActualWidthEventManager ); - ColumnActualWidthEventManager currentManager = ( ColumnActualWidthEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new ColumnActualWidthEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - private void OnActualWidthChanged( object sender, ColumnActualWidthChangedEventArgs args ) - { - this.DeliverEvent( sender, args ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/ColumnSortDirectionChangingEvent.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/ColumnSortDirectionChangingEvent.cs deleted file mode 100644 index f89fe7ba..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/ColumnSortDirectionChangingEvent.cs +++ /dev/null @@ -1,98 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - public delegate void ColumnSortDirectionChangingEventHandler( object sender, ColumnSortDirectionChangingEventArgs e ); - - public class ColumnSortDirectionChangingEventArgs : RoutedEventArgs - { - public ColumnSortDirectionChangingEventArgs( RoutedEvent routedEvent, ColumnBase column, DataGridContext dataGridContext, SortDirection currentSortDirection, SortDirection nextSortDirection ) - : base( routedEvent, column ) - { - if( column == null ) - throw new ArgumentNullException( "column" ); - - if( dataGridContext == null ) - throw new ArgumentNullException( "dataGridContext" ); - - m_dataGridContext = dataGridContext; - m_current = currentSortDirection; - m_next = nextSortDirection; - } - - #region Column Property - - public ColumnBase Column - { - get - { - return ( ColumnBase )this.OriginalSource; - } - } - - #endregion - - #region DataGridContext Property - - public DataGridContext DataGridContext - { - get - { - return m_dataGridContext; - } - } - - private DataGridContext m_dataGridContext; - - #endregion - - #region CurrentSortDirection Property - - public SortDirection CurrentSortDirection - { - get - { - return m_current; - } - } - - private SortDirection m_current; - - #endregion - - #region NextSortDirection Property - - public SortDirection NextSortDirection - { - get - { - return m_next; - } - set - { - m_next = value; - } - } - - private SortDirection m_next; - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/ColumnVisibilePositionChangedEventArgs.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/ColumnVisibilePositionChangedEventArgs.cs deleted file mode 100644 index bc121bd9..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/ColumnVisibilePositionChangedEventArgs.cs +++ /dev/null @@ -1,50 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid -{ - internal class ColumnVisiblePositionChangedEventArgs : EventArgs - { - internal ColumnVisiblePositionChangedEventArgs( ColumnBase triggeringColumn, int oldPosition, int newPosition ) - { - m_triggeringColumn = triggeringColumn; - m_newPosition = newPosition; - m_oldPosition = oldPosition; - } - - internal ColumnBase TriggeringColumn - { - get - { - return m_triggeringColumn; - } - } - - internal int PositionDelta - { - get - { - return m_newPosition - m_oldPosition; - } - } - - private ColumnBase m_triggeringColumn; - private int m_newPosition; - private int m_oldPosition; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/ColumnsLayoutChangedEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/ColumnsLayoutChangedEventManager.cs deleted file mode 100644 index 7245ae74..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/ColumnsLayoutChangedEventManager.cs +++ /dev/null @@ -1,66 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class ColumnsLayoutChangedEventManager : WeakEventManager - { - internal static void AddListener( ColumnHierarchyManager source, IWeakEventListener listener ) - { - ColumnsLayoutChangedEventManager.CurrentManager.ProtectedAddListener( source, listener ); - } - - internal static void RemoveListener( ColumnHierarchyManager source, IWeakEventListener listener ) - { - ColumnsLayoutChangedEventManager.CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - ( ( ColumnHierarchyManager )source ).LayoutChanged += new EventHandler( this.OnEventRaised ); - } - - protected override void StopListening( object source ) - { - ( ( ColumnHierarchyManager )source ).LayoutChanged -= new EventHandler( this.OnEventRaised ); - } - - private static ColumnsLayoutChangedEventManager CurrentManager - { - get - { - var managerType = typeof( ColumnsLayoutChangedEventManager ); - var currentManager = ( ColumnsLayoutChangedEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new ColumnsLayoutChangedEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - private void OnEventRaised( object sender, EventArgs e ) - { - this.DeliverEvent( sender, e ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/ColumnsLayoutChangingEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/ColumnsLayoutChangingEventManager.cs deleted file mode 100644 index 1446319b..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/ColumnsLayoutChangingEventManager.cs +++ /dev/null @@ -1,66 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class ColumnsLayoutChangingEventManager : WeakEventManager - { - internal static void AddListener( ColumnHierarchyManager source, IWeakEventListener listener ) - { - ColumnsLayoutChangingEventManager.CurrentManager.ProtectedAddListener( source, listener ); - } - - internal static void RemoveListener( ColumnHierarchyManager source, IWeakEventListener listener ) - { - ColumnsLayoutChangingEventManager.CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - ( ( ColumnHierarchyManager )source ).LayoutChanging += new EventHandler( this.OnEventRaised ); - } - - protected override void StopListening( object source ) - { - ( ( ColumnHierarchyManager )source ).LayoutChanging -= new EventHandler( this.OnEventRaised ); - } - - private static ColumnsLayoutChangingEventManager CurrentManager - { - get - { - var managerType = typeof( ColumnsLayoutChangingEventManager ); - var currentManager = ( ColumnsLayoutChangingEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new ColumnsLayoutChangingEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - private void OnEventRaised( object sender, EventArgs e ) - { - this.DeliverEvent( sender, e ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/CurrentColumnChangedEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/CurrentColumnChangedEventManager.cs deleted file mode 100644 index 3f7fe457..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/CurrentColumnChangedEventManager.cs +++ /dev/null @@ -1,68 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal class CurrentColumnChangedEventManager : WeakEventManager - { - internal static void AddListener( DetailConfiguration source, IWeakEventListener listener ) - { - CurrentManager.ProtectedAddListener( source, listener ); - } - - internal static void RemoveListener( DetailConfiguration source, IWeakEventListener listener ) - { - CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - DetailConfiguration detailConfig = ( DetailConfiguration )source; - detailConfig.CurrentColumnChanged += new EventHandler( this.OnCurrentColumnChanged ); - } - - protected override void StopListening( object source ) - { - DetailConfiguration detailConfig = ( DetailConfiguration )source; - detailConfig.CurrentColumnChanged -= new EventHandler( this.OnCurrentColumnChanged ); - } - - private static CurrentColumnChangedEventManager CurrentManager - { - get - { - Type managerType = typeof( CurrentColumnChangedEventManager ); - CurrentColumnChangedEventManager currentManager = ( CurrentColumnChangedEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new CurrentColumnChangedEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - private void OnCurrentColumnChanged( object sender, EventArgs args ) - { - this.DeliverEvent( sender, args ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/CurrentItemChangedEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/CurrentItemChangedEventManager.cs deleted file mode 100644 index c9fc90c9..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/CurrentItemChangedEventManager.cs +++ /dev/null @@ -1,66 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class CurrentItemChangedEventManager : WeakEventManager - { - internal static void AddListener( DataGridContext source, IWeakEventListener listener ) - { - CurrentItemChangedEventManager.CurrentManager.ProtectedAddListener( source, listener ); - } - - internal static void RemoveListener( DataGridContext source, IWeakEventListener listener ) - { - CurrentItemChangedEventManager.CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - ( ( DataGridContext )source ).CurrentItemChanged += new EventHandler( this.OnEventRaised ); - } - - protected override void StopListening( object source ) - { - ( ( DataGridContext )source ).CurrentItemChanged -= new EventHandler( this.OnEventRaised ); - } - - private static CurrentItemChangedEventManager CurrentManager - { - get - { - var managerType = typeof( CurrentItemChangedEventManager ); - var currentManager = ( CurrentItemChangedEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new CurrentItemChangedEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - private void OnEventRaised( object sender, EventArgs e ) - { - this.DeliverEvent( sender, e ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DataGridControlSelectionChangedEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DataGridControlSelectionChangedEventManager.cs deleted file mode 100644 index 783432d8..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DataGridControlSelectionChangedEventManager.cs +++ /dev/null @@ -1,73 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal class DataGridControlSelectionChangedEventManager : WeakEventManager - { - internal static void AddListener( DataGridControl source, IWeakEventListener listener ) - { - CurrentManager.ProtectedAddListener( source, listener ); - } - - internal static void RemoveListener( DataGridControl source, IWeakEventListener listener ) - { - CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - DataGridControl dataGridControl = source as DataGridControl; - - if( dataGridControl != null ) - dataGridControl.SelectionChanged += this.DataGridControl_SelectionChanged; - } - - protected override void StopListening( object source ) - { - DataGridControl dataGridControl = source as DataGridControl; - - if( dataGridControl != null ) - dataGridControl.SelectionChanged -= this.DataGridControl_SelectionChanged; - } - - private static DataGridControlSelectionChangedEventManager CurrentManager - { - get - { - Type managerType = typeof( DataGridControlSelectionChangedEventManager ); - DataGridControlSelectionChangedEventManager currentManager = - ( DataGridControlSelectionChangedEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new DataGridControlSelectionChangedEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - private void DataGridControl_SelectionChanged( object sender, DataGridSelectionChangedEventArgs e ) - { - this.DeliverEvent( sender, e ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DataGridControlTemplateChangedEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DataGridControlTemplateChangedEventManager.cs deleted file mode 100644 index 7c26c53f..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DataGridControlTemplateChangedEventManager.cs +++ /dev/null @@ -1,80 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal class DataGridControlTemplateChangedEventManager : WeakEventManager - { - internal static void AddListener( object source, IWeakEventListener listener ) - { - CurrentManager.ProtectedAddListener( source, listener ); - } - - internal static void RemoveListener( object source, IWeakEventListener listener ) - { - CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - DataGridControl dataGridControl = source as DataGridControl; - if( dataGridControl != null ) - { - dataGridControl.TemplateApplied += new EventHandler( this.OnTemplateApplied ); - return; - } - - throw new ArgumentException( "The specified source must be a DataGridControl.", "source" ); - } - - protected override void StopListening( object source ) - { - DataGridControl dataGridControl = source as DataGridControl; - if( dataGridControl != null ) - { - dataGridControl.TemplateApplied -= new EventHandler( this.OnTemplateApplied ); - return; - } - - throw new ArgumentException( "The specified source must be a DataGridControl.", "source" ); - } - - private static DataGridControlTemplateChangedEventManager CurrentManager - { - get - { - Type managerType = typeof( DataGridControlTemplateChangedEventManager ); - DataGridControlTemplateChangedEventManager currentManager = ( DataGridControlTemplateChangedEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new DataGridControlTemplateChangedEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - private void OnTemplateApplied( object sender, EventArgs args ) - { - this.DeliverEvent( sender, args ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DataGridCurrentChangedEvent.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DataGridCurrentChangedEvent.cs deleted file mode 100644 index 1d9de1ae..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DataGridCurrentChangedEvent.cs +++ /dev/null @@ -1,58 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - public delegate void DataGridCurrentChangedEventHandler( object sender, DataGridCurrentChangedEventArgs e ); - - public class DataGridCurrentChangedEventArgs : RoutedEventArgs - { - internal DataGridCurrentChangedEventArgs( DataGridContext oldDataGridContext, object oldCurrent, DataGridContext newDataGridContext, object newCurrent ) - : base( DataGridControl.CurrentChangedEvent ) - { - this.OldDataGridContext = oldDataGridContext; - this.OldCurrent = oldCurrent; - this.NewDataGridContext = newDataGridContext; - this.NewCurrent = newCurrent; - } - - public DataGridContext OldDataGridContext - { - get; - private set; - } - - public object OldCurrent - { - get; - private set; - } - - public DataGridContext NewDataGridContext - { - get; - private set; - } - - public object NewCurrent - { - get; - private set; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DataGridCurrentChangingEvent.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DataGridCurrentChangingEvent.cs deleted file mode 100644 index 2c828e7a..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DataGridCurrentChangingEvent.cs +++ /dev/null @@ -1,63 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -namespace Xceed.Wpf.DataGrid -{ - public delegate void DataGridCurrentChangingEventHandler( object sender, DataGridCurrentChangingEventArgs e ); - - public class DataGridCurrentChangingEventArgs : CancelRoutedEventArgs - { - internal DataGridCurrentChangingEventArgs( DataGridContext oldDataGridContext, object oldCurrent, DataGridContext newDataGridContext, object newCurrent, bool isCancelable ) - : base( DataGridControl.CurrentChangingEvent ) - { - this.IsCancelable = isCancelable; - this.OldDataGridContext = oldDataGridContext; - this.OldCurrent = oldCurrent; - this.NewDataGridContext = newDataGridContext; - this.NewCurrent = newCurrent; - } - - public bool IsCancelable - { - get; - private set; - } - - public DataGridContext OldDataGridContext - { - get; - private set; - } - - public object OldCurrent - { - get; - private set; - } - - public DataGridContext NewDataGridContext - { - get; - private set; - } - - public object NewCurrent - { - get; - private set; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DataGridSelectionChangedEvent.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DataGridSelectionChangedEvent.cs deleted file mode 100644 index 13f6576e..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DataGridSelectionChangedEvent.cs +++ /dev/null @@ -1,38 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Collections.Generic; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - public delegate void DataGridSelectionChangedEventHandler( object sender, DataGridSelectionChangedEventArgs e ); - - public class DataGridSelectionChangedEventArgs : RoutedEventArgs - { - internal DataGridSelectionChangedEventArgs( IList selectionInfos ) - : base( DataGridControl.SelectionChangedEvent ) - { - this.SelectionInfos = selectionInfos; - } - - public IList SelectionInfos - { - get; - private set; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DataGridSelectionChangingEvent.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DataGridSelectionChangingEvent.cs deleted file mode 100644 index c2cd8b0f..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DataGridSelectionChangingEvent.cs +++ /dev/null @@ -1,44 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Collections.Generic; - -namespace Xceed.Wpf.DataGrid -{ - public delegate void DataGridSelectionChangingEventHandler( object sender, DataGridSelectionChangingEventArgs e ); - - public class DataGridSelectionChangingEventArgs : CancelRoutedEventArgs - { - internal DataGridSelectionChangingEventArgs( IList selectionInfos, bool isCancelable ) - : base( DataGridControl.SelectionChangingEvent ) - { - this.SelectionInfos = selectionInfos; - this.IsCancelable = isCancelable; - } - - public bool IsCancelable - { - get; - private set; - } - - public IList SelectionInfos - { - get; - private set; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DeletingSelectedItemErrorRoutedEvent.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DeletingSelectedItemErrorRoutedEvent.cs deleted file mode 100644 index ce6f8975..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DeletingSelectedItemErrorRoutedEvent.cs +++ /dev/null @@ -1,99 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - public delegate void DeletingSelectedItemErrorRoutedEventHandler( object sender, DeletingSelectedItemErrorRoutedEventArgs e ); - - public class DeletingSelectedItemErrorRoutedEventArgs : RoutedEventArgs - { - #region CONSTRUCTORS - - public DeletingSelectedItemErrorRoutedEventArgs( object item, Exception exception ) - : base() - { - m_item = item; - m_exception = exception; - } - - public DeletingSelectedItemErrorRoutedEventArgs( object item, Exception exception, RoutedEvent routedEvent ) - : base( routedEvent ) - { - m_item = item; - m_exception = exception; - } - - public DeletingSelectedItemErrorRoutedEventArgs( object item, Exception exception, RoutedEvent routedEvent, object source ) - : base( routedEvent, source ) - { - m_item = item; - m_exception = exception; - } - - #endregion CONSTRUCTORS - - #region Item Property - - public object Item - { - get - { - return m_item; - } - } - - #endregion Item Property - - #region Exception Property - - public Exception Exception - { - get - { - return m_exception; - } - } - - #endregion Exception Property - - #region Action Property - - public DeletingSelectedItemErrorAction Action - { - get - { - return m_action; - } - set - { - m_action = value; - } - } - - #endregion Action Property - - #region PRIVATE FIELDS - - private object m_item; - private Exception m_exception; - private DeletingSelectedItemErrorAction m_action = DeletingSelectedItemErrorAction.Skip; - - #endregion PRIVATE FIELDS - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DetailVisibilityChangedEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DetailVisibilityChangedEventManager.cs deleted file mode 100644 index 336162ef..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DetailVisibilityChangedEventManager.cs +++ /dev/null @@ -1,89 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal class DetailVisibilityChangedEventManager : WeakEventManager - { - internal static void AddListener( object source, IWeakEventListener listener ) - { - CurrentManager.ProtectedAddListener( source, listener ); - } - - internal static void RemoveListener( object source, IWeakEventListener listener ) - { - CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - DetailConfiguration detailConfig = source as DetailConfiguration; - if( detailConfig != null ) - { - detailConfig.VisibilityChanged += new EventHandler( this.OnVisibilityChanged ); - return; - } - - DetailConfigurationCollection detailConfigCollection = source as DetailConfigurationCollection; - if( detailConfigCollection != null ) - { - detailConfigCollection.DetailVisibilityChanged += new EventHandler( this.OnVisibilityChanged ); - } - - } - - protected override void StopListening( object source ) - { - DetailConfiguration detailConfig = source as DetailConfiguration; - if( detailConfig != null ) - { - detailConfig.VisibilityChanged -= new EventHandler( this.OnVisibilityChanged ); - return; - } - - DetailConfigurationCollection detailConfigCollection = source as DetailConfigurationCollection; - if( detailConfigCollection != null ) - { - detailConfigCollection.DetailVisibilityChanged -= new EventHandler( this.OnVisibilityChanged ); - } - } - - private static DetailVisibilityChangedEventManager CurrentManager - { - get - { - Type managerType = typeof( DetailVisibilityChangedEventManager ); - DetailVisibilityChangedEventManager currentManager = ( DetailVisibilityChangedEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new DetailVisibilityChangedEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - private void OnVisibilityChanged( object sender, EventArgs e ) - { - this.DeliverEvent( sender, e ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DetailsChangedEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DetailsChangedEventManager.cs deleted file mode 100644 index aa10bd11..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DetailsChangedEventManager.cs +++ /dev/null @@ -1,98 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal class DetailsChangedEventManager : WeakEventManager - { - internal static void AddListener( object source, IWeakEventListener listener ) - { - CurrentManager.ProtectedAddListener( source, listener ); - } - - internal static void RemoveListener( object source, IWeakEventListener listener ) - { - CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - DataGridControl dataGridControl = source as DataGridControl; - if( dataGridControl != null ) - { - dataGridControl.DetailsChanged += this.OnDetailsChanged; - return; - } - else - { - CustomItemContainerGenerator generator = source as CustomItemContainerGenerator; - if( generator != null ) - { - generator.DetailsChanged += this.OnDetailsChanged; - return; - } - } - - throw new InvalidOperationException( "An attempt was made to use a source other than a DataGridControl or CustomItemContainerGenerator." ); - } - - protected override void StopListening( object source ) - { - DataGridControl dataGridControl = source as DataGridControl; - if( dataGridControl != null ) - { - dataGridControl.DetailsChanged -= this.OnDetailsChanged; - return; - } - else - { - CustomItemContainerGenerator generator = source as CustomItemContainerGenerator; - if( generator != null ) - { - generator.DetailsChanged -= this.OnDetailsChanged; - return; - } - } - - throw new InvalidOperationException( "An attempt was made to use a source other than a DataGridControl or CustomItemContainerGenerator." ); - } - - private static DetailsChangedEventManager CurrentManager - { - get - { - Type managerType = typeof( DetailsChangedEventManager ); - DetailsChangedEventManager currentManager = ( DetailsChangedEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new DetailsChangedEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - private void OnDetailsChanged( object sender, EventArgs args ) - { - this.DeliverEvent( sender, args ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DetailsExpansionChangedEventArgs.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DetailsExpansionChangedEventArgs.cs deleted file mode 100644 index 3a5a9618..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DetailsExpansionChangedEventArgs.cs +++ /dev/null @@ -1,63 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - public delegate void DetailsExpansionChangedEventHandler( object sender, DetailsExpansionChangedEventArgs e ); - - public class DetailsExpansionChangedEventArgs : RoutedEventArgs - { - public DetailsExpansionChangedEventArgs( RoutedEvent routedEvent, object dataItem, DataGridContext dataGridContext, bool isExpanded ) - : base( routedEvent ) - { - this.DataGridContext = dataGridContext; - this.IsExpanded = isExpanded; - this.MasterItem = dataItem; - } - - #region DataGridContext Property - - public DataGridContext DataGridContext - { - get; - private set; - } - - #endregion - - #region IsExpanded Property - - public bool IsExpanded - { - get; - private set; - } - - #endregion - - #region MasterItem Property - - public object MasterItem - { - get; - private set; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DetailsExpansionChangingEventArgs.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DetailsExpansionChangingEventArgs.cs deleted file mode 100644 index b79426a0..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DetailsExpansionChangingEventArgs.cs +++ /dev/null @@ -1,73 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - public delegate void DetailsExpansionChangingEventHandler( object sender, DetailsExpansionChangingEventArgs e ); - - public class DetailsExpansionChangingEventArgs : RoutedEventArgs - { - public DetailsExpansionChangingEventArgs( RoutedEvent routedEvent, object dataItem, DataGridContext dataGridContext, bool isExpanding ) - : base( routedEvent ) - { - this.DataGridContext = dataGridContext; - this.IsExpanding = isExpanding; - this.MasterItem = dataItem; - } - - #region Cancel Property - - public bool Cancel - { - get; - set; - } - - #endregion - - #region DataGridContext Property - - public DataGridContext DataGridContext - { - get; - private set; - } - - #endregion - - #region IsExpanding Property - - public bool IsExpanding - { - get; - private set; - } - - #endregion - - #region MasterItem Property - - public object MasterItem - { - get; - private set; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DistinctValuesRequestedEvent.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DistinctValuesRequestedEvent.cs deleted file mode 100644 index d0609a22..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DistinctValuesRequestedEvent.cs +++ /dev/null @@ -1,50 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; - -namespace Xceed.Wpf.DataGrid -{ - internal class DistinctValuesRequestedEventArgs : EventArgs - { - internal DistinctValuesRequestedEventArgs( string autoFilterColumnFieldName ) - { - m_autoFilterColumnFieldName = autoFilterColumnFieldName; - } - - internal string AutoFilterColumnFieldName - { - get - { - return m_autoFilterColumnFieldName; - } - } - - internal HashSet DistinctValues - { - get - { - return m_distinctValues; - } - } - - private string m_autoFilterColumnFieldName; - private HashSet m_distinctValues = new HashSet(); - } - - internal delegate void DistinctValuesRequestedEventHandler( object sender, DistinctValuesRequestedEventArgs e ); -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DistinctValuesRequestedEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DistinctValuesRequestedEventManager.cs deleted file mode 100644 index 2f0e026b..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/DistinctValuesRequestedEventManager.cs +++ /dev/null @@ -1,68 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal class DistinctValuesRequestedEventManager: WeakEventManager - { - internal static void AddListener( ColumnCollection source, IWeakEventListener listener ) - { - CurrentManager.ProtectedAddListener( source, listener ); - } - - internal static void RemoveListener( ColumnCollection source, IWeakEventListener listener ) - { - CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - ColumnCollection columns = ( ColumnCollection )source; - columns.DistinctValuesRequested += this.OnDistinctValuesRequested; - } - - protected override void StopListening( object source ) - { - ColumnCollection columns = ( ColumnCollection )source; - columns.DistinctValuesRequested -= this.OnDistinctValuesRequested; - } - - private static DistinctValuesRequestedEventManager CurrentManager - { - get - { - Type managerType = typeof( DistinctValuesRequestedEventManager ); - DistinctValuesRequestedEventManager currentManager = ( DistinctValuesRequestedEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new DistinctValuesRequestedEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - private void OnDistinctValuesRequested( object sender, DistinctValuesRequestedEventArgs args ) - { - this.DeliverEvent( sender, args ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/FittedWidthRequestedEvent.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/FittedWidthRequestedEvent.cs deleted file mode 100644 index 359e8dd6..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/FittedWidthRequestedEvent.cs +++ /dev/null @@ -1,51 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class FittedWidthRequestedEventArgs : EventArgs - { - #region Value Internal Read-Only Property - - internal Nullable Value - { - get - { - return m_value; - } - } - - internal void SetValue( double value ) - { - if( m_value.HasValue ) - { - // We keep the highest of the two values. - if( m_value.Value >= value ) - return; - } - - m_value = value; - } - - private Nullable m_value; - - #endregion - } - - internal delegate void FittedWidthRequestedEventHandler( object sender, FittedWidthRequestedEventArgs e ); -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/FrameworkElementUnloadedEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/FrameworkElementUnloadedEventManager.cs deleted file mode 100644 index 664a7244..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/FrameworkElementUnloadedEventManager.cs +++ /dev/null @@ -1,88 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; -using System.Windows.Threading; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class FrameworkElementUnloadedEventManager : WeakEventManager - { - internal static void AddListener( FrameworkElement source, IWeakEventListener listener ) - { - FrameworkElementUnloadedEventManager.CurrentManager.ProtectedAddListener( source, listener ); - } - - internal static void RemoveListener( FrameworkElement source, IWeakEventListener listener ) - { - FrameworkElementUnloadedEventManager.CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - var fe = source as FrameworkElement; - if( fe == null ) - return; - - fe.Unloaded += new RoutedEventHandler( this.OnEventRaised ); - } - - protected override void StopListening( object source ) - { - var fe = source as FrameworkElement; - if( fe == null ) - return; - - var dispatcher = fe.Dispatcher; - if( dispatcher.CheckAccess() ) - { - this.StopListening( fe ); - } - else - { - dispatcher.BeginInvoke( new Action( this.StopListening ), DispatcherPriority.Send, fe ); - } - } - - private static FrameworkElementUnloadedEventManager CurrentManager - { - get - { - var managerType = typeof( FrameworkElementUnloadedEventManager ); - var currentManager = ( FrameworkElementUnloadedEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new FrameworkElementUnloadedEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - private void StopListening( FrameworkElement fe ) - { - fe.Unloaded -= new RoutedEventHandler( this.OnEventRaised ); - } - - private void OnEventRaised( object sender, RoutedEventArgs e ) - { - this.DeliverEvent( sender, e ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/GroupConfigurationSelectorChangedEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/GroupConfigurationSelectorChangedEventManager.cs deleted file mode 100644 index 4e7de696..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/GroupConfigurationSelectorChangedEventManager.cs +++ /dev/null @@ -1,110 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal class GroupConfigurationSelectorChangedEventManager : WeakEventManager - { - internal static void AddListener( object source, IWeakEventListener listener ) - { - CurrentManager.ProtectedAddListener( source, listener ); - } - - internal static void RemoveListener( object source, IWeakEventListener listener ) - { - CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - DataGridContext context = source as DataGridContext; - - if (context != null) - { - context.GroupConfigurationSelectorChanged += new EventHandler(this.OnGroupConfigurationSelectorChanged); - return; - } - - DataGridControl dataGridControl = source as DataGridControl; - if (dataGridControl != null) - { - dataGridControl.GroupConfigurationSelectorChanged += new EventHandler(this.OnGroupConfigurationSelectorChanged); - return; - } - - DetailConfiguration detailConfig = source as DetailConfiguration; - if (detailConfig != null) - { - detailConfig.GroupConfigurationSelectorChanged += new EventHandler(this.OnGroupConfigurationSelectorChanged); - return; - } - - throw new InvalidOperationException("An attempt was made to register an item other than a DataGridContext, DataGridControl, or DetailConfiguration to the GroupConfigurationSelectorChangedEventManager."); - } - - protected override void StopListening(object source) - { - DataGridContext context = source as DataGridContext; - - if (context != null) - { - context.GroupConfigurationSelectorChanged -= new EventHandler(this.OnGroupConfigurationSelectorChanged); - return; - } - - DataGridControl dataGridControl = source as DataGridControl; - if (dataGridControl != null) - { - dataGridControl.GroupConfigurationSelectorChanged -= new EventHandler(this.OnGroupConfigurationSelectorChanged); - return; - } - - DetailConfiguration detailConfig = source as DetailConfiguration; - if (detailConfig != null) - { - detailConfig.GroupConfigurationSelectorChanged -= new EventHandler(this.OnGroupConfigurationSelectorChanged); - return; - } - - throw new InvalidOperationException( "An attempt was made to unregister an item other than a DataGridContext, DataGridControl, or DetailConfiguration from the GroupConfigurationSelectorChangedEventManager." ); - } - - private static GroupConfigurationSelectorChangedEventManager CurrentManager - { - get - { - Type managerType = typeof( GroupConfigurationSelectorChangedEventManager ); - GroupConfigurationSelectorChangedEventManager currentManager = ( GroupConfigurationSelectorChangedEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new GroupConfigurationSelectorChangedEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - private void OnGroupConfigurationSelectorChanged( object sender, EventArgs args ) - { - this.DeliverEvent( sender, args ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/GroupExpansionChangedEventArgs.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/GroupExpansionChangedEventArgs.cs deleted file mode 100644 index 9cac5769..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/GroupExpansionChangedEventArgs.cs +++ /dev/null @@ -1,75 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Windows; -using System.Windows.Data; - -namespace Xceed.Wpf.DataGrid -{ - public delegate void GroupExpansionChangedEventHandler( object sender, GroupExpansionChangedEventArgs e ); - - public class GroupExpansionChangedEventArgs : RoutedEventArgs - { - public GroupExpansionChangedEventArgs( RoutedEvent routedEvent, Group group, CollectionViewGroup collectionViewGroup, DataGridContext dataGridContext, bool isExpanded ) - : base( routedEvent ) - { - this.CollectionViewGroup = collectionViewGroup; - this.DataGridContext = dataGridContext; - this.Group = group; - this.IsExpanded = isExpanded; - } - - #region CollectionViewGroup Property - - public CollectionViewGroup CollectionViewGroup - { - get; - private set; - } - - #endregion - - #region DataGridContext Property - - public DataGridContext DataGridContext - { - get; - private set; - } - - #endregion - - #region Group Property - - public Group Group - { - get; - private set; - } - - #endregion - - #region IsExpanded Property - - public bool IsExpanded - { - get; - private set; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/GroupExpansionChangingEventArgs.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/GroupExpansionChangingEventArgs.cs deleted file mode 100644 index bae3a76b..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/GroupExpansionChangingEventArgs.cs +++ /dev/null @@ -1,85 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Windows; -using System.Windows.Data; - -namespace Xceed.Wpf.DataGrid -{ - public delegate void GroupExpansionChangingEventHandler( object sender, GroupExpansionChangingEventArgs e ); - - public class GroupExpansionChangingEventArgs : RoutedEventArgs - { - public GroupExpansionChangingEventArgs( RoutedEvent routedEvent, Group group, CollectionViewGroup collectionViewGroup, DataGridContext dataGridContext, bool isExpanding ) - : base( routedEvent ) - { - this.CollectionViewGroup = collectionViewGroup; - this.DataGridContext = dataGridContext; - this.Group = group; - this.IsExpanding = isExpanding; - } - - #region Cancel Property - - public bool Cancel - { - get; - set; - } - - #endregion - - #region CollectionViewGroup Property - - public CollectionViewGroup CollectionViewGroup - { - get; - private set; - } - - #endregion - - #region DataGridContext Property - - public DataGridContext DataGridContext - { - get; - private set; - } - - #endregion - - #region Group Property - - public Group Group - { - get; - private set; - } - - #endregion - - #region IsExpanding Property - - public bool IsExpanding - { - get; - private set; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/InitializeItemPropertyEventArgs.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/InitializeItemPropertyEventArgs.cs deleted file mode 100644 index b9317115..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/InitializeItemPropertyEventArgs.cs +++ /dev/null @@ -1,41 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid -{ - internal class InitializeItemPropertyEventArgs : EventArgs - { - internal InitializeItemPropertyEventArgs( DataGridItemPropertyBase itemProperty ) - { - if( itemProperty == null ) - throw new ArgumentNullException( "itemProperty" ); - - m_itemProperty = itemProperty; - } - - internal DataGridItemPropertyBase ItemProperty - { - get - { - return m_itemProperty; - } - } - - private readonly DataGridItemPropertyBase m_itemProperty; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/InitializeItemPropertyEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/InitializeItemPropertyEventManager.cs deleted file mode 100644 index 14145220..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/InitializeItemPropertyEventManager.cs +++ /dev/null @@ -1,68 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class InitializeItemPropertyEventManager : WeakEventManager - { - internal static void AddListener( DataGridItemPropertyCollection source, IWeakEventListener listener ) - { - CurrentManager.ProtectedAddListener( source, listener ); - } - - internal static void RemoveListener( DataGridItemPropertyCollection source, IWeakEventListener listener ) - { - CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - var target = ( DataGridItemPropertyCollection )source; - target.InitializeItemProperty += new EventHandler( this.OnEventRaised ); - } - - protected override void StopListening( object source ) - { - var target = ( DataGridItemPropertyCollection )source; - target.InitializeItemProperty -= new EventHandler( this.OnEventRaised ); - } - - private static InitializeItemPropertyEventManager CurrentManager - { - get - { - var managerType = typeof( InitializeItemPropertyEventManager ); - var currentManager = ( InitializeItemPropertyEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new InitializeItemPropertyEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - private void OnEventRaised( object sender, InitializeItemPropertyEventArgs e ) - { - this.DeliverEvent( sender, e ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/ItemsSourceChangedEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/ItemsSourceChangedEventManager.cs deleted file mode 100644 index a75070b8..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/ItemsSourceChangedEventManager.cs +++ /dev/null @@ -1,68 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal class ItemsSourceChangeCompletedEventManager : WeakEventManager - { - internal static void AddListener( DataGridControl source, IWeakEventListener listener ) - { - CurrentManager.ProtectedAddListener( source, listener ); - } - - internal static void RemoveListener( DataGridControl source, IWeakEventListener listener ) - { - CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - DataGridControl dataGridControl = ( DataGridControl )source; - dataGridControl.ItemsSourceChangeCompleted += new EventHandler( this.OnItemsSourceChanged ); - } - - protected override void StopListening( object source ) - { - DataGridControl dataGridControl = ( DataGridControl )source; - dataGridControl.ItemsSourceChangeCompleted -= new EventHandler( this.OnItemsSourceChanged ); - } - - private static ItemsSourceChangeCompletedEventManager CurrentManager - { - get - { - Type managerType = typeof( ItemsSourceChangeCompletedEventManager ); - ItemsSourceChangeCompletedEventManager currentManager = ( ItemsSourceChangeCompletedEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new ItemsSourceChangeCompletedEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - private void OnItemsSourceChanged( object sender, EventArgs args ) - { - this.DeliverEvent( sender, args ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/ListChangedEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/ListChangedEventManager.cs deleted file mode 100644 index 77528b36..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/ListChangedEventManager.cs +++ /dev/null @@ -1,69 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal class ListChangedEventManager : WeakEventManager - { - internal static void AddListener( IBindingList source, IWeakEventListener listener ) - { - CurrentManager.ProtectedAddListener( source, listener ); - } - - internal static void RemoveListener( IBindingList source, IWeakEventListener listener ) - { - CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - IBindingList list = ( IBindingList )source; - list.ListChanged += new ListChangedEventHandler( this.OnListChanged ); - } - - protected override void StopListening( object source ) - { - IBindingList list = ( IBindingList )source; - list.ListChanged -= new ListChangedEventHandler( this.OnListChanged ); - } - - private static ListChangedEventManager CurrentManager - { - get - { - Type managerType = typeof( ListChangedEventManager ); - ListChangedEventManager currentManager = ( ListChangedEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new ListChangedEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - private void OnListChanged( object sender, ListChangedEventArgs args ) - { - this.DeliverEvent( sender, args ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/MappingChangedEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/MappingChangedEventManager.cs deleted file mode 100644 index 9abbaea8..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/MappingChangedEventManager.cs +++ /dev/null @@ -1,66 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class MappingChangedEventManager : WeakEventManager - { - internal static void AddListener( DataGridItemPropertyMap source, IWeakEventListener listener ) - { - MappingChangedEventManager.CurrentManager.ProtectedAddListener( source, listener ); - } - - internal static void RemoveListener( DataGridItemPropertyMap source, IWeakEventListener listener ) - { - MappingChangedEventManager.CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - ( ( DataGridItemPropertyMap )source ).MappingChanged += new EventHandler( this.OnEventRaised ); - } - - protected override void StopListening( object source ) - { - ( ( DataGridItemPropertyMap )source ).MappingChanged -= new EventHandler( this.OnEventRaised ); - } - - private static MappingChangedEventManager CurrentManager - { - get - { - var managerType = typeof( MappingChangedEventManager ); - var currentManager = ( MappingChangedEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new MappingChangedEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - private void OnEventRaised( object sender, EventArgs e ) - { - this.DeliverEvent( sender, e ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/MaxGroupLevelsChangedEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/MaxGroupLevelsChangedEventManager.cs deleted file mode 100644 index 4274cbe0..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/MaxGroupLevelsChangedEventManager.cs +++ /dev/null @@ -1,94 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal class MaxGroupLevelsChangedEventManager : WeakEventManager - { - internal static void AddListener( object source, IWeakEventListener listener ) - { - CurrentManager.ProtectedAddListener( source, listener ); - } - - internal static void RemoveListener( object source, IWeakEventListener listener ) - { - CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - DataGridControl dataGridControl = source as DataGridControl; - if( dataGridControl != null ) - { - dataGridControl.MaxGroupLevelsChanged += new EventHandler( this.OnMaxGroupLevelsChanged ); - return; - } - - DetailConfiguration detailConfiguration = source as DetailConfiguration; - if( detailConfiguration != null ) - { - detailConfiguration.MaxGroupLevelsChanged += new EventHandler( this.OnMaxGroupLevelsChanged ); - return; - } - - throw new ArgumentException( "The specified source must be a DataGridControl or a DetailConfiguration.", "source" ); - } - - protected override void StopListening( object source ) - { - DataGridControl dataGridControl = source as DataGridControl; - if( dataGridControl != null ) - { - dataGridControl.MaxGroupLevelsChanged -= new EventHandler( this.OnMaxGroupLevelsChanged ); - return; - } - - DetailConfiguration detailConfiguration = source as DetailConfiguration; - if( detailConfiguration != null ) - { - detailConfiguration.MaxGroupLevelsChanged -= new EventHandler( this.OnMaxGroupLevelsChanged ); - return; - } - - throw new ArgumentException( "The specified source must be a DataGridControl or a DetailConfiguration.", "source" ); - } - - private static MaxGroupLevelsChangedEventManager CurrentManager - { - get - { - Type managerType = typeof( MaxGroupLevelsChangedEventManager ); - MaxGroupLevelsChangedEventManager currentManager = ( MaxGroupLevelsChangedEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new MaxGroupLevelsChangedEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - private void OnMaxGroupLevelsChanged( object sender, EventArgs args ) - { - this.DeliverEvent( sender, args ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/MaxSortLevelsChangedEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/MaxSortLevelsChangedEventManager.cs deleted file mode 100644 index d6bf7273..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/MaxSortLevelsChangedEventManager.cs +++ /dev/null @@ -1,94 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal class MaxSortLevelsChangedEventManager : WeakEventManager - { - internal static void AddListener( object source, IWeakEventListener listener ) - { - CurrentManager.ProtectedAddListener( source, listener ); - } - - internal static void RemoveListener( object source, IWeakEventListener listener ) - { - CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - DataGridControl dataGridControl = source as DataGridControl; - if( dataGridControl != null ) - { - dataGridControl.MaxSortLevelsChanged += new EventHandler( this.OnMaxSortLevelsChanged ); - return; - } - - DetailConfiguration detailConfiguration = source as DetailConfiguration; - if( detailConfiguration != null ) - { - detailConfiguration.MaxSortLevelsChanged += new EventHandler( this.OnMaxSortLevelsChanged ); - return; - } - - throw new ArgumentException( "The specified source must be a DataGridControl or a DetailConfiguration.", "source" ); - } - - protected override void StopListening( object source ) - { - DataGridControl dataGridControl = source as DataGridControl; - if( dataGridControl != null ) - { - dataGridControl.MaxSortLevelsChanged -= new EventHandler( this.OnMaxSortLevelsChanged ); - return; - } - - DetailConfiguration detailConfiguration = source as DetailConfiguration; - if( detailConfiguration != null ) - { - detailConfiguration.MaxSortLevelsChanged -= new EventHandler( this.OnMaxSortLevelsChanged ); - return; - } - - throw new ArgumentException( "The specified source must be a DataGridControl or a DetailConfiguration.", "source" ); - } - - private static MaxSortLevelsChangedEventManager CurrentManager - { - get - { - Type managerType = typeof( MaxSortLevelsChangedEventManager ); - MaxSortLevelsChangedEventManager currentManager = ( MaxSortLevelsChangedEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new MaxSortLevelsChangedEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - private void OnMaxSortLevelsChanged( object sender, EventArgs args ) - { - this.DeliverEvent( sender, args ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/NotifyBatchCollectionChangedEventArgs.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/NotifyBatchCollectionChangedEventArgs.cs deleted file mode 100644 index 43066596..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/NotifyBatchCollectionChangedEventArgs.cs +++ /dev/null @@ -1,349 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Diagnostics; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class NotifyBatchCollectionChangedEventArgs : NotifyCollectionChangedEventArgs - { - private NotifyBatchCollectionChangedEventArgs( NotifyCollectionChangedAction action ) - : base( action ) - { - } - - private NotifyBatchCollectionChangedEventArgs( NotifyCollectionChangedAction action, IList changedItems ) - : base( action, changedItems ) - { - } - - private NotifyBatchCollectionChangedEventArgs( NotifyCollectionChangedAction action, IList changedItems, int startingIndex ) - : base( action, changedItems, startingIndex ) - { - } - - private NotifyBatchCollectionChangedEventArgs( NotifyCollectionChangedAction action, IList changedItems, int index, int oldIndex ) - : base( action, changedItems, index, oldIndex ) - { - } - - private NotifyBatchCollectionChangedEventArgs( NotifyCollectionChangedAction action, IList newItems, IList oldItems ) - : base( action, newItems, oldItems ) - { - } - - private NotifyBatchCollectionChangedEventArgs( NotifyCollectionChangedAction action, IList newItems, IList oldItems, int startingIndex ) - : base( action, newItems, oldItems, startingIndex ) - { - } - - #region Replacements Property - - internal IDictionary Replacements - { - get - { - if( m_fromTo == null ) - { - m_fromTo = new Dictionary( 0 ); - m_toFrom = new Dictionary( 0 ); - } - - return m_fromTo; - } - } - - #endregion - - internal static NotifyBatchCollectionChangedEventArgs Combine( NotifyCollectionChangedEventArgs x, NotifyCollectionChangedEventArgs y ) - { - return NotifyBatchCollectionChangedEventArgs.Combine( - NotifyBatchCollectionChangedEventArgs.Create( x ), - NotifyBatchCollectionChangedEventArgs.Create( y ) ); - } - - private static NotifyBatchCollectionChangedEventArgs Combine( NotifyBatchCollectionChangedEventArgs x, NotifyBatchCollectionChangedEventArgs y ) - { - if( x == null ) - return y; - - if( y == null ) - return x; - - var replacements = default( BiMap ); - var result = default( NotifyBatchCollectionChangedEventArgs ); - - if( x.Action == y.Action ) - { - switch( x.Action ) - { - case NotifyCollectionChangedAction.Replace: - { - replacements = NotifyBatchCollectionChangedEventArgs.Merge( - NotifyBatchCollectionChangedEventArgs.Map( x.OldItems, x.NewItems ), - NotifyBatchCollectionChangedEventArgs.Map( y.OldItems, y.NewItems ) ); - if( replacements == null ) - return null; - - result = new NotifyBatchCollectionChangedEventArgs( NotifyCollectionChangedAction.Reset ); - } - break; - - case NotifyCollectionChangedAction.Add: - case NotifyCollectionChangedAction.Remove: - case NotifyCollectionChangedAction.Move: - result = new NotifyBatchCollectionChangedEventArgs( NotifyCollectionChangedAction.Reset ); - break; - - case NotifyCollectionChangedAction.Reset: - result = new NotifyBatchCollectionChangedEventArgs( NotifyCollectionChangedAction.Reset ); - replacements = NotifyBatchCollectionChangedEventArgs.Merge( x.m_fromTo, y.m_fromTo ); - break; - - default: - throw new NotSupportedException(); - } - } - else - { - if( x.Action == NotifyCollectionChangedAction.Replace ) - { - replacements = NotifyBatchCollectionChangedEventArgs.Merge( NotifyBatchCollectionChangedEventArgs.Map( x.OldItems, x.NewItems ), null ); - } - else if( ( x.Action == NotifyCollectionChangedAction.Reset ) && ( x.m_fromTo != null ) ) - { - replacements = new BiMap( x.m_fromTo, x.m_toFrom ); - } - - switch( y.Action ) - { - case NotifyCollectionChangedAction.Add: - { - if( replacements != null ) - { - var fromTo = replacements.FromTo; - var toFrom = replacements.ToFrom; - - foreach( var item in y.NewItems ) - { - object to; - - if( fromTo.TryGetValue( item, out to ) ) - { - fromTo.Remove( item ); - toFrom.Remove( to ); - } - } - } - } - break; - - case NotifyCollectionChangedAction.Remove: - { - if( replacements != null ) - { - var fromTo = replacements.FromTo; - var toFrom = replacements.ToFrom; - - foreach( var item in y.OldItems ) - { - object from; - - if( toFrom.TryGetValue( item, out from ) ) - { - fromTo.Remove( from ); - toFrom.Remove( item ); - } - } - } - } - break; - - case NotifyCollectionChangedAction.Replace: - { - var mapping = NotifyBatchCollectionChangedEventArgs.Map( y.OldItems, y.NewItems ); - - if( replacements != null ) - { - replacements = NotifyBatchCollectionChangedEventArgs.Merge( replacements.FromTo, mapping ); - } - else - { - replacements = NotifyBatchCollectionChangedEventArgs.Merge( mapping, null ); - } - } - break; - - case NotifyCollectionChangedAction.Move: - break; - - case NotifyCollectionChangedAction.Reset: - { - if( replacements != null ) - { - replacements = NotifyBatchCollectionChangedEventArgs.Merge( replacements.FromTo, y.m_fromTo ); - } - else - { - replacements = NotifyBatchCollectionChangedEventArgs.Merge( y.m_fromTo, null ); - } - } - break; - - default: - throw new NotSupportedException(); - } - - result = new NotifyBatchCollectionChangedEventArgs( NotifyCollectionChangedAction.Reset ); - } - - if( ( result != null ) && ( replacements != null ) ) - { - result.m_fromTo = replacements.FromTo; - result.m_toFrom = replacements.ToFrom; - } - - return result; - } - - private static NotifyBatchCollectionChangedEventArgs Create( NotifyCollectionChangedEventArgs e ) - { - if( e == null ) - return null; - - var batch = e as NotifyBatchCollectionChangedEventArgs; - if( batch != null ) - return batch; - - switch( e.Action ) - { - case NotifyCollectionChangedAction.Add: - return new NotifyBatchCollectionChangedEventArgs( e.Action, e.NewItems, e.NewStartingIndex ); - - case NotifyCollectionChangedAction.Remove: - return new NotifyBatchCollectionChangedEventArgs( e.Action, e.OldItems, e.OldStartingIndex ); - - case NotifyCollectionChangedAction.Move: - return new NotifyBatchCollectionChangedEventArgs( e.Action, e.OldItems, e.NewStartingIndex, e.OldStartingIndex ); - - case NotifyCollectionChangedAction.Replace: - return new NotifyBatchCollectionChangedEventArgs( e.Action, e.NewItems, e.OldItems, e.OldStartingIndex ); - - case NotifyCollectionChangedAction.Reset: - return new NotifyBatchCollectionChangedEventArgs( e.Action ); - - default: - throw new NotSupportedException(); - } - } - - private static BiMap Merge( IDictionary x, IDictionary y ) - { - var fromTo = new Dictionary(); - var toFrom = new Dictionary(); - - if( x != null ) - { - foreach( var entry in x ) - { - if( object.ReferenceEquals( entry.Key, entry.Value ) ) - continue; - - fromTo.Add( entry.Key, entry.Value ); - toFrom.Add( entry.Value, entry.Key ); - } - } - - if( y != null ) - { - foreach( var entry in y ) - { - if( object.ReferenceEquals( entry.Key, entry.Value ) ) - continue; - - // Keep only the initial and final value. For example, (A -> B -> C) becomes (A -> C). - var from = default( object ); - if( toFrom.TryGetValue( entry.Key, out from ) ) - { - toFrom.Remove( entry.Key ); - - if( object.ReferenceEquals( from, entry.Value ) ) - { - fromTo.Remove( from ); - } - else - { - fromTo[ from ] = entry.Value; - toFrom[ entry.Value ] = from; - } - } - else - { - // There is no need to check if the entry exists, since it should not or the same instance - // is use multiple time in the data source, which is not supported by the grid. - fromTo.Add( entry.Key, entry.Value ); - toFrom.Add( entry.Value, entry.Key ); - } - } - } - - if( fromTo.Count <= 0 ) - return null; - - return new BiMap( fromTo, toFrom ); - } - - private static IDictionary Map( IList oldItems, IList newItems ) - { - Debug.Assert( oldItems != null ); - Debug.Assert( newItems != null ); - Debug.Assert( oldItems.Count == newItems.Count ); - - var items = new Dictionary(); - var count = oldItems.Count; - - for( int i = 0; i < count; i++ ) - { - items.Add( oldItems[ i ], newItems[ i ] ); - } - - return items; - } - - private IDictionary m_fromTo; - private IDictionary m_toFrom; - - #region BiMap Private Class - - private sealed class BiMap - { - internal BiMap( IDictionary fromTo, IDictionary toFrom ) - { - this.FromTo = fromTo; - this.ToFrom = toFrom; - } - - internal readonly IDictionary FromTo; - internal readonly IDictionary ToFrom; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/NotifyCollectionChangedEventArgsExtensions.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/NotifyCollectionChangedEventArgsExtensions.cs deleted file mode 100644 index 8ac11222..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/NotifyCollectionChangedEventArgsExtensions.cs +++ /dev/null @@ -1,72 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Specialized; - -namespace Xceed.Wpf.DataGrid -{ - internal static class NotifyCollectionChangedEventArgsExtensions - { - internal static NotifyCollectionChangedEventArgs GetRangeActionOrSelf( this NotifyCollectionChangedEventArgs source ) - { - if( source == null ) - throw new ArgumentNullException( "source" ); - - var rangeEventArgs = source as NotifyRangeCollectionChangedEventArgs; - if( rangeEventArgs != null ) - return rangeEventArgs.OriginalEventArgs; - - return source; - } - - internal static object GetReplacement( this NotifyCollectionChangedEventArgs source, object item ) - { - if( source == null ) - throw new ArgumentNullException( "source" ); - - var result = default( object ); - - if( item != null ) - { - var batch = source as NotifyBatchCollectionChangedEventArgs; - if( batch != null ) - { - if( !batch.Replacements.TryGetValue( item, out result ) ) - { - result = null; - } - } - else if( source.Action == NotifyCollectionChangedAction.Replace ) - { - var oldItems = source.OldItems; - var newItems = source.NewItems; - - if( ( oldItems != null ) && ( newItems != null ) ) - { - var index = oldItems.IndexOf( item ); - if( index >= 0 ) - { - result = newItems[ index ]; - } - } - } - } - - return result; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/NotifyRangeCollectionChangedEventArgs.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/NotifyRangeCollectionChangedEventArgs.cs deleted file mode 100644 index 5482024d..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/NotifyRangeCollectionChangedEventArgs.cs +++ /dev/null @@ -1,51 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Specialized; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class NotifyRangeCollectionChangedEventArgs : NotifyCollectionChangedEventArgs - { - #region Constructor - - internal NotifyRangeCollectionChangedEventArgs( NotifyCollectionChangedEventArgs args ) - : base( NotifyCollectionChangedAction.Reset ) - { - if( args == null ) - throw new ArgumentNullException( "args" ); - - m_originalEventArgs = args; - } - - #endregion - - #region OriginalEventArgs Property - - internal NotifyCollectionChangedEventArgs OriginalEventArgs - { - get - { - return m_originalEventArgs; - } - } - - private readonly NotifyCollectionChangedEventArgs m_originalEventArgs; - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/RealizedContainersRequestedEvent.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/RealizedContainersRequestedEvent.cs deleted file mode 100644 index ccef5ae2..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/RealizedContainersRequestedEvent.cs +++ /dev/null @@ -1,37 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - internal class RealizedContainersRequestedEventArgs: EventArgs - { - public List RealizedContainers - { - get - { - return m_realizedContainers; - } - } - - private List m_realizedContainers = new List(); - } - - internal delegate void RealizedContainersRequestedEventHandler( object sender, RealizedContainersRequestedEventArgs e ); -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/RealizedContainersRequestedEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/RealizedContainersRequestedEventManager.cs deleted file mode 100644 index d3783e53..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/RealizedContainersRequestedEventManager.cs +++ /dev/null @@ -1,74 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal class RealizedContainersRequestedEventManager: WeakEventManager - { - private RealizedContainersRequestedEventManager() - { - } - - public static void AddListener( ColumnCollection source, IWeakEventListener listener ) - { - CurrentManager.ProtectedAddListener( source, listener ); - } - - public static void RemoveListener( ColumnCollection source, IWeakEventListener listener ) - { - CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - ColumnCollection columns = ( ColumnCollection )source; - columns.RealizedContainersRequested += this.OnRealizedContainersRequested; - } - - protected override void StopListening( object source ) - { - ColumnCollection columns = ( ColumnCollection )source; - columns.RealizedContainersRequested -= this.OnRealizedContainersRequested; - } - - private static RealizedContainersRequestedEventManager CurrentManager - { - get - { - Type managerType = typeof( RealizedContainersRequestedEventManager ); - RealizedContainersRequestedEventManager currentManager = ( RealizedContainersRequestedEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new RealizedContainersRequestedEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - private void OnRealizedContainersRequested( object sender, RealizedContainersRequestedEventArgs args ) - { - this.DeliverEvent( sender, args ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/RequestBringIntoViewWeakEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/RequestBringIntoViewWeakEventManager.cs deleted file mode 100644 index 858670ef..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/RequestBringIntoViewWeakEventManager.cs +++ /dev/null @@ -1,73 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal class RequestBringIntoViewWeakEventManager : WeakEventManager - { - #region CurrentManager Static Property - - private static RequestBringIntoViewWeakEventManager CurrentManager - { - get - { - var managerType = typeof( RequestBringIntoViewWeakEventManager ); - var currentManager = ( RequestBringIntoViewWeakEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new RequestBringIntoViewWeakEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - #endregion - - internal static void AddListener( FrameworkElement source, IWeakEventListener listener ) - { - RequestBringIntoViewWeakEventManager.CurrentManager.ProtectedAddListener( source, listener ); - } - - internal static void RemoveListener( FrameworkElement source, IWeakEventListener listener ) - { - RequestBringIntoViewWeakEventManager.CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - var fe = ( FrameworkElement )source; - - fe.RequestBringIntoView += new RequestBringIntoViewEventHandler( this.OnEventRaised ); - } - - protected override void StopListening( object source ) - { - var fe = ( FrameworkElement )source; - - fe.RequestBringIntoView -= new RequestBringIntoViewEventHandler( this.OnEventRaised ); - } - - private void OnEventRaised( object sender, RequestBringIntoViewEventArgs e ) - { - this.DeliverEvent( sender, e ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/RequestingDelayBringIntoViewAndFocusCurrentEventArgs.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/RequestingDelayBringIntoViewAndFocusCurrentEventArgs.cs deleted file mode 100644 index 6ee4f79a..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/RequestingDelayBringIntoViewAndFocusCurrentEventArgs.cs +++ /dev/null @@ -1,42 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid -{ - internal class RequestingDelayBringIntoViewAndFocusCurrentEventArgs : EventArgs - { - internal RequestingDelayBringIntoViewAndFocusCurrentEventArgs( AutoScrollCurrentItemSourceTriggers trigger ) - { - m_trigger = trigger; - } - - #region Trigger Property - - internal AutoScrollCurrentItemSourceTriggers Trigger - { - get - { - return m_trigger; - } - } - - private readonly AutoScrollCurrentItemSourceTriggers m_trigger; - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/RowValidationErrorRoutedEvent.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/RowValidationErrorRoutedEvent.cs deleted file mode 100644 index 4385a741..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/RowValidationErrorRoutedEvent.cs +++ /dev/null @@ -1,67 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - public delegate void RowValidationErrorRoutedEventHandler( object sender, RowValidationErrorRoutedEventArgs e ); - - public class RowValidationErrorRoutedEventArgs : RoutedEventArgs - { - public RowValidationErrorRoutedEventArgs( RowValidationError rowValidationError ) - : base() - { - if( rowValidationError == null ) - throw new ArgumentNullException( "rowValidationError" ); - - m_rowValidationError = rowValidationError; - } - - public RowValidationErrorRoutedEventArgs( RoutedEvent routedEvent, RowValidationError rowValidationError ) - : base( routedEvent ) - { - if( rowValidationError == null ) - throw new ArgumentNullException( "rowValidationError" ); - - m_rowValidationError = rowValidationError; - } - - public RowValidationErrorRoutedEventArgs( RoutedEvent routedEvent, object source, RowValidationError rowValidationError ) - : base( routedEvent, source ) - { - if( rowValidationError == null ) - throw new ArgumentNullException( "rowValidationError" ); - - m_rowValidationError = rowValidationError; - } - - #region ValidationError PROPERTY - - public RowValidationError RowValidationError - { - get - { - return m_rowValidationError; - } - } - - private RowValidationError m_rowValidationError; - - #endregion ValidationError PROPERTY - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/ScrollChangedWeakEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/ScrollChangedWeakEventManager.cs deleted file mode 100644 index 3d713888..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/ScrollChangedWeakEventManager.cs +++ /dev/null @@ -1,74 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; -using System.Windows.Controls; - -namespace Xceed.Wpf.DataGrid -{ - internal class ScrollChangedWeakEventManager : WeakEventManager - { - internal static void AddListener( ScrollViewer source, IWeakEventListener listener ) - { - CurrentManager.ProtectedAddListener( source, listener ); - } - - internal static void RemoveListener( ScrollViewer source, IWeakEventListener listener ) - { - CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - ScrollViewer scrollViewer = source as ScrollViewer; - - if( scrollViewer != null ) - scrollViewer.ScrollChanged += this.ScrollViewer_ScrollChanged; - } - - protected override void StopListening( object source ) - { - ScrollViewer scrollViewer = source as ScrollViewer; - - if( scrollViewer != null ) - scrollViewer.ScrollChanged -= this.ScrollViewer_ScrollChanged; - } - - private static ScrollChangedWeakEventManager CurrentManager - { - get - { - Type managerType = typeof( ScrollChangedWeakEventManager ); - ScrollChangedWeakEventManager currentManager = - ( ScrollChangedWeakEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new ScrollChangedWeakEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - private void ScrollViewer_ScrollChanged( object sender, ScrollChangedEventArgs e ) - { - this.DeliverEvent( sender, e ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/SelectionChangedEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/SelectionChangedEventManager.cs deleted file mode 100644 index 5c5ab821..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/SelectionChangedEventManager.cs +++ /dev/null @@ -1,74 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Controls.Primitives; - -namespace Xceed.Wpf.DataGrid -{ - internal class SelectionChangedEventManager : WeakEventManager - { - internal static void AddListener( Selector source, IWeakEventListener listener ) - { - CurrentManager.ProtectedAddListener( source, listener ); - } - - internal static void RemoveListener( Selector source, IWeakEventListener listener ) - { - CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - Selector selector = ( Selector )source; - - if( selector != null ) - selector.SelectionChanged += new SelectionChangedEventHandler( this.Selector_SelectionChanged ); - } - - protected override void StopListening( object source ) - { - Selector selector = ( Selector )source; - - if( selector != null ) - selector.SelectionChanged -= new SelectionChangedEventHandler( this.Selector_SelectionChanged ); - } - - private static SelectionChangedEventManager CurrentManager - { - get - { - Type managerType = typeof( SelectionChangedEventManager ); - SelectionChangedEventManager currentManager = ( SelectionChangedEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new SelectionChangedEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - private void Selector_SelectionChanged( object sender, SelectionChangedEventArgs e ) - { - this.DeliverEvent( sender, e ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/SelectionChangedInternalEventArgs.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/SelectionChangedInternalEventArgs.cs deleted file mode 100644 index 247f799f..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/SelectionChangedInternalEventArgs.cs +++ /dev/null @@ -1,35 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid -{ - internal class SelectionChangedInternalEventArgs : EventArgs - { - - internal SelectionChangedInternalEventArgs( SelectionInfo selectionInfo ) - { - this.SelectionInfo = selectionInfo; - } - - internal SelectionInfo SelectionInfo - { - get; - private set; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/SelectionChangedInternalEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/SelectionChangedInternalEventManager.cs deleted file mode 100644 index fbd32012..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/SelectionChangedInternalEventManager.cs +++ /dev/null @@ -1,67 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; -using System.Windows.Threading; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class SelectionChangedInternalEventManager : WeakEventManager - { - internal static void AddListener( DataGridContext source, IWeakEventListener listener ) - { - SelectionChangedInternalEventManager.CurrentManager.ProtectedAddListener( source, listener ); - } - - internal static void RemoveListener( DataGridContext source, IWeakEventListener listener ) - { - SelectionChangedInternalEventManager.CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - ( ( DataGridContext )source ).SelectionChangedInternal += new EventHandler( this.OnEventRaised ); - } - - protected override void StopListening( object source ) - { - ( ( DataGridContext )source ).SelectionChangedInternal -= new EventHandler( this.OnEventRaised ); - } - - private static SelectionChangedInternalEventManager CurrentManager - { - get - { - var managerType = typeof( SelectionChangedInternalEventManager ); - var currentManager = ( SelectionChangedInternalEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new SelectionChangedInternalEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - private void OnEventRaised( object sender, SelectionChangedInternalEventArgs e ) - { - this.DeliverEvent( sender, e ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/ThemeChangedEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/ThemeChangedEventManager.cs deleted file mode 100644 index cdf6af77..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/ThemeChangedEventManager.cs +++ /dev/null @@ -1,68 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal class ThemeChangedEventManager : WeakEventManager - { - internal static void AddListener( DataGridControl source, IWeakEventListener listener ) - { - CurrentManager.ProtectedAddListener( source, listener ); - } - - internal static void RemoveListener( DataGridControl source, IWeakEventListener listener ) - { - CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - DataGridControl dataGridControl = ( DataGridControl )source; - dataGridControl.ThemeChanged += new EventHandler( this.OnThemeChanged ); - } - - protected override void StopListening( object source ) - { - DataGridControl dataGridControl = ( DataGridControl )source; - dataGridControl.ThemeChanged -= new EventHandler( this.OnThemeChanged ); - } - - private static ThemeChangedEventManager CurrentManager - { - get - { - Type managerType = typeof( ThemeChangedEventManager ); - ThemeChangedEventManager currentManager = ( ThemeChangedEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new ThemeChangedEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - private void OnThemeChanged( object sender, EventArgs args ) - { - this.DeliverEvent( sender, args ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/ViewChangedEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/ViewChangedEventManager.cs deleted file mode 100644 index 18730990..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/ViewChangedEventManager.cs +++ /dev/null @@ -1,68 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal class ViewChangedEventManager : WeakEventManager - { - internal static void AddListener( DataGridControl source, IWeakEventListener listener ) - { - CurrentManager.ProtectedAddListener( source, listener ); - } - - internal static void RemoveListener( DataGridControl source, IWeakEventListener listener ) - { - CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - DataGridControl dataGridControl = ( DataGridControl )source; - dataGridControl.ViewChanged += new EventHandler( this.OnViewChanged ); - } - - protected override void StopListening( object source ) - { - DataGridControl dataGridControl = ( DataGridControl )source; - dataGridControl.ViewChanged -= new EventHandler( this.OnViewChanged ); - } - - private static ViewChangedEventManager CurrentManager - { - get - { - Type managerType = typeof( ViewChangedEventManager ); - ViewChangedEventManager currentManager = ( ViewChangedEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new ViewChangedEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - private void OnViewChanged( object sender, EventArgs args ) - { - this.DeliverEvent( sender, args ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/VirtualizingCellCollectionChangedEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/VirtualizingCellCollectionChangedEventManager.cs deleted file mode 100644 index f82d3ef9..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Events)/VirtualizingCellCollectionChangedEventManager.cs +++ /dev/null @@ -1,78 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal class VirtualizingCellCollectionChangedEventManager : WeakEventManager - { - internal static void AddListener( VirtualizingCellCollection source, IWeakEventListener listener ) - { - VirtualizingCellCollectionChangedEventManager.CurrentManager.ProtectedAddListener( source, listener ); - } - - internal static void RemoveListener( VirtualizingCellCollection source, IWeakEventListener listener ) - { - VirtualizingCellCollectionChangedEventManager.CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - VirtualizingCellCollection virtualizingCellCollection = source as VirtualizingCellCollection; - if( source == null ) - { - throw new InvalidOperationException( "An attempt was made to use a source other than a VirtualizingCellCollection" ); - } - - virtualizingCellCollection.CollectionChanged += this.OnVirtualizingCellCollectionChanged; - } - - protected override void StopListening( object source ) - { - VirtualizingCellCollection virtualizingCellCollection = source as VirtualizingCellCollection; - if( source == null ) - { - throw new InvalidOperationException( "An attempt was made to use a source other than a VirtualizingCellCollection" ); - } - - virtualizingCellCollection.CollectionChanged -= this.OnVirtualizingCellCollectionChanged; - } - - private static VirtualizingCellCollectionChangedEventManager CurrentManager - { - get - { - Type managerType = typeof( VirtualizingCellCollectionChangedEventManager ); - VirtualizingCellCollectionChangedEventManager currentManager = WeakEventManager.GetCurrentManager( managerType ) as VirtualizingCellCollectionChangedEventManager; - - if( currentManager == null ) - { - currentManager = new VirtualizingCellCollectionChangedEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - private void OnVirtualizingCellCollectionChanged( object sender, EventArgs args ) - { - this.DeliverEvent( sender, args ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(ForeignKeys)/DataGridForeignKeyConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(ForeignKeys)/DataGridForeignKeyConverter.cs deleted file mode 100644 index da972812..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(ForeignKeys)/DataGridForeignKeyConverter.cs +++ /dev/null @@ -1,141 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - public class DataGridForeignKeyConverter : ForeignKeyConverter - { - public DataGridForeignKeyConverter() - { - } - - public override object GetValueFromKey( object key, ForeignKeyConfiguration configuration ) - { - var itemsSource = configuration.ItemsSource; - if( itemsSource == null ) - return key; - - if( ( itemsSource is DataView ) || ( itemsSource is DataTable ) ) - return new DataTableForeignKeyConverter().GetValueFromKey( key, configuration ); - - return this.GetValueFromKeyCore( key, itemsSource, configuration.ValuePath, configuration.DisplayMemberPath ); - } - - public override object GetKeyFromValue( object value, ForeignKeyConfiguration configuration ) - { - if( value == null ) - return null; - - var displayMemberPath = configuration.DisplayMemberPath; - if( string.IsNullOrWhiteSpace( displayMemberPath ) ) - return value; - - var valuePath = configuration.ValuePath; - if( string.IsNullOrWhiteSpace( valuePath ) ) - return value; - - var itemsSource = configuration.ItemsSource; - if( itemsSource == null ) - return value; - - if( ( itemsSource is DataView ) || ( itemsSource is DataTable ) ) - return new DataTableForeignKeyConverter().GetKeyFromValue( value, configuration ); - - try - { - var enumerator = itemsSource.GetEnumerator(); - enumerator.MoveNext(); - var firstItem = enumerator.Current; - var itemType = firstItem.GetType(); - var propertyInfo = itemType.GetProperty( displayMemberPath ); - - foreach( object item in itemsSource ) - { - if( item == null ) - continue; - - var displayValue = propertyInfo.GetValue( item, null ); - - if( value.Equals( displayValue ) ) - return itemType.GetProperty( valuePath ).GetValue( item, null ); - } - } - catch - { - //Swallow the exception, no need to terminate the application, just return the original value. - } - - return value; - } - - public override object GetValueFromKey( object key, DataGridForeignKeyDescription description ) - { - var itemsSource = description.ItemsSource; - if( itemsSource == null ) - return key; - - if( ( itemsSource is DataView ) || ( itemsSource is DataTable ) ) - return new DataTableForeignKeyConverter().GetValueFromKey( key, description ); - - return this.GetValueFromKeyCore( key, itemsSource, description.ValuePath, description.DisplayMemberPath ); - } - - private object GetValueFromKeyCore( object key, IEnumerable itemsSource, string valuePath, string displayMemberPath ) - { - if( key == null ) - return null; - - if( string.IsNullOrWhiteSpace( displayMemberPath ) ) - return key; - - if( string.IsNullOrWhiteSpace( valuePath ) ) - return key; - - try - { - var enumerator = itemsSource.GetEnumerator(); - enumerator.MoveNext(); - var firstItem = enumerator.Current; - var itemType = firstItem.GetType(); - var propertyInfo = itemType.GetProperty( valuePath ); - - foreach( object item in itemsSource ) - { - if( item == null ) - continue; - - var value = propertyInfo.GetValue( item, null ); - - if( key.Equals( value ) ) - return itemType.GetProperty( displayMemberPath ).GetValue( item, null ); - } - } - catch - { - //Swallow the exception, no need to terminate the application, just return the original value. - } - - return key; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(ForeignKeys)/DataTableForeignKeyConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(ForeignKeys)/DataTableForeignKeyConverter.cs deleted file mode 100644 index 0ed005c4..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(ForeignKeys)/DataTableForeignKeyConverter.cs +++ /dev/null @@ -1,134 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Data; -using System.Collections; - -namespace Xceed.Wpf.DataGrid -{ - public class DataTableForeignKeyConverter : ForeignKeyConverter - { - public DataTableForeignKeyConverter() - { - } - - public override object GetValueFromKey( object key, ForeignKeyConfiguration configuration ) - { - return this.GetValueFromKeyCore( key, configuration.ItemsSource, configuration.ValuePath, configuration.DisplayMemberPath, true ); - } - - public override object GetKeyFromValue( object value, ForeignKeyConfiguration configuration ) - { - var dataView = configuration.ItemsSource as DataView; - if( dataView == null ) - { - var dataTable = configuration.ItemsSource as DataTable; - if( dataTable != null ) - { - dataView = dataTable.DefaultView; - } - } - - if( dataView == null ) - { - return value; - } - - var dataRow = value as DataRowView; - - if( dataRow == null ) - { - return null; - } - else - { - return dataRow[ dataView.Sort ]; - } - } - - public override object GetValueFromKey( object key, DataGridForeignKeyDescription description ) - { - return this.GetValueFromKeyCore( key, description.ItemsSource, description.ValuePath, description.DisplayMemberPath, false ); - } - - private object GetValueFromKeyCore( object key, IEnumerable itemsSource, string valuePath, string displayMemberPath, bool isConfiguration ) - { - var dataView = itemsSource as DataView; - if( dataView == null ) - { - var dataTable = itemsSource as DataTable; - if( dataTable != null ) - { - dataView = dataTable.DefaultView; - } - } - - if( dataView == null ) - { - return key; - } - - if( string.IsNullOrEmpty( valuePath ) ) - { - return key; - } - - dataView.Sort = valuePath; - - DataRowView dataRow; - - int index = -1; - - if( ( key != null ) && ( !object.Equals( string.Empty, key ) ) ) - { - try - { - index = dataView.Find( key ); - } - catch( Exception ) - { - } - } - - if( index == -1 ) - { - dataRow = null; - } - else - { - dataRow = dataView[ index ]; - } - - // Use the DisplayMemberPath if defined - if( dataRow != null ) - { - if( !string.IsNullOrEmpty( displayMemberPath ) ) - { - return dataRow[ displayMemberPath ]; - } - } - - if( isConfiguration ) - return dataRow; - - return key; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(ForeignKeys)/ForeignKeyConfigNotifyCollectionChangedEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(ForeignKeys)/ForeignKeyConfigNotifyCollectionChangedEventManager.cs deleted file mode 100644 index 0adf06c4..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(ForeignKeys)/ForeignKeyConfigNotifyCollectionChangedEventManager.cs +++ /dev/null @@ -1,68 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal class ForeignKeyConfigNotifyCollectionChangedEventManager : WeakEventManager - { - public static void AddListener( ForeignKeyConfiguration source, IWeakEventListener listener ) - { - CurrentManager.ProtectedAddListener( source, listener ); - } - - public static void RemoveListener( ForeignKeyConfiguration source, IWeakEventListener listener ) - { - CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - var configuration = ( ForeignKeyConfiguration )source; - configuration.NotifiyCollectionChanged += new EventHandler( this.OnNotifiyCollectionChanged ); - } - - protected override void StopListening( object source ) - { - var configuration = ( ForeignKeyConfiguration )source; - configuration.NotifiyCollectionChanged -= new EventHandler( this.OnNotifiyCollectionChanged ); - } - - private static ForeignKeyConfigNotifyCollectionChangedEventManager CurrentManager - { - get - { - Type managerType = typeof( ForeignKeyConfigNotifyCollectionChangedEventManager ); - var currentManager = ( ForeignKeyConfigNotifyCollectionChangedEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new ForeignKeyConfigNotifyCollectionChangedEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - private void OnNotifiyCollectionChanged( object sender, EventArgs args ) - { - this.DeliverEvent( sender, args ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(ForeignKeys)/ForeignKeyConfiguration.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(ForeignKeys)/ForeignKeyConfiguration.cs deleted file mode 100644 index 1e3327aa..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(ForeignKeys)/ForeignKeyConfiguration.cs +++ /dev/null @@ -1,719 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Data; -using System.Globalization; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; - -namespace Xceed.Wpf.DataGrid -{ - public class ForeignKeyConfiguration : DependencyObject, IWeakEventListener - { - static ForeignKeyConfiguration() - { - ForeignKeyConfiguration.DefaultDistinctValueItemContentTemplateProperty = ForeignKeyConfiguration.DefaultDistinctValueItemContentTemplatePropertyKey.DependencyProperty; - ForeignKeyConfiguration.DefaultCellContentTemplateProperty = ForeignKeyConfiguration.DefaultCellContentTemplatePropertyKey.DependencyProperty; - ForeignKeyConfiguration.DefaultGroupValueTemplateProperty = ForeignKeyConfiguration.DefaultGroupValueTemplatePropertyKey.DependencyProperty; - ForeignKeyConfiguration.DefaultScrollTipContentTemplateProperty = ForeignKeyConfiguration.DefaultScrollTipContentTemplatePropertyKey.DependencyProperty; - ForeignKeyConfiguration.DefaultCellEditorProperty = ForeignKeyConfiguration.DefaultCellEditorPropertyKey.DependencyProperty; - } - - public ForeignKeyConfiguration() - { - this.SetDefaultCellContentTemplate( GenericContentTemplateSelector.ForeignKeyCellContentTemplate ); - this.SetDefaultGroupValueTemplate( GenericContentTemplateSelector.ForeignKeyGroupValueTemplate ); - this.SetDefaultScrollTipContentTemplate( GenericContentTemplateSelector.ForeignKeyScrollTipContentTemplate ); - this.SetDefaultCellEditor( DefaultCellEditorSelector.ForeignKeyCellEditor ); - } - - #region ValuePath Property - - public static readonly DependencyProperty ValuePathProperty = DependencyProperty.Register( - "ValuePath", - typeof( string ), - typeof( ForeignKeyConfiguration ), - new FrameworkPropertyMetadata( null ) ); - - public string ValuePath - { - get - { - return ( string )this.GetValue( ForeignKeyConfiguration.ValuePathProperty ); - } - set - { - this.SetValue( ForeignKeyConfiguration.ValuePathProperty, value ); - } - } - - #endregion - - #region DisplayMemberPath Property - - public static readonly DependencyProperty DisplayMemberPathProperty = DependencyProperty.Register( - "DisplayMemberPath", - typeof( string ), - typeof( ForeignKeyConfiguration ), - new FrameworkPropertyMetadata( null ) ); - - public string DisplayMemberPath - { - get - { - return ( string )this.GetValue( ForeignKeyConfiguration.DisplayMemberPathProperty ); - } - set - { - this.SetValue( ForeignKeyConfiguration.DisplayMemberPathProperty, value ); - } - } - - #endregion - - #region ItemContainerStyle Property - - public static readonly DependencyProperty ItemContainerStyleProperty = DependencyProperty.Register( - "ItemContainerStyle", - typeof( Style ), - typeof( ForeignKeyConfiguration ), - new FrameworkPropertyMetadata( null ) ); - - public Style ItemContainerStyle - { - get - { - return ( Style )this.GetValue( ForeignKeyConfiguration.ItemContainerStyleProperty ); - } - set - { - this.SetValue( ForeignKeyConfiguration.ItemContainerStyleProperty, value ); - } - } - - #endregion - - #region ItemContainerStyleSelector Property - - public static readonly DependencyProperty ItemContainerStyleSelectorProperty = DependencyProperty.Register( - "ItemContainerStyleSelector", - typeof( StyleSelector ), - typeof( ForeignKeyConfiguration ), - new FrameworkPropertyMetadata( null ) ); - - public StyleSelector ItemContainerStyleSelector - { - get - { - return ( StyleSelector )this.GetValue( ForeignKeyConfiguration.ItemContainerStyleSelectorProperty ); - } - set - { - this.SetValue( ForeignKeyConfiguration.ItemContainerStyleSelectorProperty, value ); - } - } - - #endregion - - #region IsAutoCreated Property - - internal bool IsAutoCreated - { - get; - set; - } - - #endregion - - #region ItemsSource Property - - public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register( - "ItemsSource", - typeof( IEnumerable ), - typeof( ForeignKeyConfiguration ), - new FrameworkPropertyMetadata( - null, - new PropertyChangedCallback( ForeignKeyConfiguration.OnItemsSourceChanged ) ) ); - - public IEnumerable ItemsSource - { - get - { - return ( IEnumerable )this.GetValue( ForeignKeyConfiguration.ItemsSourceProperty ); - } - set - { - this.SetValue( ForeignKeyConfiguration.ItemsSourceProperty, value ); - } - } - - private static void OnItemsSourceChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var foreignConfiguration = sender as ForeignKeyConfiguration; - if( foreignConfiguration != null ) - { - foreignConfiguration.OnItemsSourceChanged( ( IEnumerable )e.OldValue, ( IEnumerable )e.NewValue ); - } - } - - private void OnItemsSourceChanged( IEnumerable oldItemsSource, IEnumerable newItemsSource ) - { - //Unsubscribe from the old list changed event, if any. - if( oldItemsSource != null ) - { - var oldNotifyCollectionChanged = oldItemsSource as INotifyCollectionChanged; - if( oldNotifyCollectionChanged != null ) - { - CollectionChangedEventManager.RemoveListener( oldNotifyCollectionChanged, this ); - } - else - { - var oldBindingList = oldItemsSource as IBindingList; - if( oldBindingList != null && oldBindingList.SupportsChangeNotification ) - { - ListChangedEventManager.RemoveListener( oldBindingList, this ); - } - } - } - - //Subscribe from to the new list changed event, if any. - if( newItemsSource != null ) - { - var newNotifyCollectionChanged = newItemsSource as INotifyCollectionChanged; - if( newNotifyCollectionChanged != null ) - { - CollectionChangedEventManager.AddListener( newNotifyCollectionChanged, this ); - } - else - { - var newBindingList = newItemsSource as IBindingList; - if( newBindingList != null && newBindingList.SupportsChangeNotification ) - { - ListChangedEventManager.AddListener( newBindingList, this ); - } - } - } - } - - private void OnNotifiyCollectionChanged() - { - var handler = this.NotifiyCollectionChanged; - if( handler == null ) - return; - - handler.Invoke( this, EventArgs.Empty ); - } - - internal event EventHandler NotifiyCollectionChanged; - - #endregion - - #region ForeignKeyConverter Property - - public static readonly DependencyProperty ForeignKeyConverterProperty = DependencyProperty.Register( - "ForeignKeyConverter", - typeof( ForeignKeyConverter ), - typeof( ForeignKeyConfiguration ), - new FrameworkPropertyMetadata( null ) ); - - public ForeignKeyConverter ForeignKeyConverter - { - get - { - return ( ForeignKeyConverter )this.GetValue( ForeignKeyConfiguration.ForeignKeyConverterProperty ); - } - set - { - this.SetValue( ForeignKeyConfiguration.ForeignKeyConverterProperty, value ); - } - } - - #endregion - - #region ForeignKeyValueConverter Property - - public static readonly DependencyProperty ForeignKeyValueConverterProperty = DependencyProperty.Register( - "ForeignKeyValueConverter", - typeof( IValueConverter ), - typeof( ForeignKeyConfiguration ), - new FrameworkPropertyMetadata( null ) ); - - public IValueConverter ForeignKeyValueConverter - { - get - { - return ( IValueConverter )this.GetValue( ForeignKeyConfiguration.ForeignKeyValueConverterProperty ); - } - set - { - this.SetValue( ForeignKeyConfiguration.ForeignKeyValueConverterProperty, value ); - } - } - - #endregion - - #region ForeignKeyValueConverterParameter Property - - public static readonly DependencyProperty ForeignKeyValueConverterParameterProperty = DependencyProperty.Register( - "ForeignKeyValueConverterParameter", - typeof( object ), - typeof( ForeignKeyConfiguration ), - new FrameworkPropertyMetadata( null ) ); - - public object ForeignKeyValueConverterParameter - { - get - { - return ( object )this.GetValue( ForeignKeyConfiguration.ForeignKeyValueConverterParameterProperty ); - } - set - { - this.SetValue( ForeignKeyConfiguration.ForeignKeyValueConverterParameterProperty, value ); - } - } - - #endregion - - #region ForeignKeyValueConverterCulture Property - - public static readonly DependencyProperty ForeignKeyValueConverterCultureProperty = DependencyProperty.Register( - "ForeignKeyValueConverterCulture", - typeof( CultureInfo ), - typeof( ForeignKeyConfiguration ), - new FrameworkPropertyMetadata( null ) ); - - public CultureInfo ForeignKeyValueConverterCulture - { - get - { - return ( CultureInfo )this.GetValue( ForeignKeyConfiguration.ForeignKeyValueConverterCultureProperty ); - } - set - { - this.SetValue( ForeignKeyConfiguration.ForeignKeyValueConverterCultureProperty, value ); - } - } - - #endregion - - #region UseDefaultFilterCriterion Property - - public static readonly DependencyProperty UseDefaultFilterCriterionProperty = DependencyProperty.Register( - "UseDefaultFilterCriterion", - typeof( bool ), - typeof( ForeignKeyConfiguration ), - new FrameworkPropertyMetadata( true ) ); - - public bool UseDefaultFilterCriterion - { - get - { - return ( bool )this.GetValue( ForeignKeyConfiguration.UseDefaultFilterCriterionProperty ); - } - set - { - this.SetValue( ForeignKeyConfiguration.UseDefaultFilterCriterionProperty, value ); - } - } - - #endregion - - #region UseDisplayedValueWhenExporting Property - - public static readonly DependencyProperty UseDisplayedValueWhenExportingProperty = DependencyProperty.Register( - "UseDisplayedValueWhenExporting", - typeof( bool ), - typeof( ForeignKeyConfiguration ), - new FrameworkPropertyMetadata( true ) ); - - public bool UseDisplayedValueWhenExporting - { - get - { - return ( bool )this.GetValue( ForeignKeyConfiguration.UseDisplayedValueWhenExportingProperty ); - } - set - { - this.SetValue( ForeignKeyConfiguration.UseDisplayedValueWhenExportingProperty, value ); - } - } - - #endregion - - #region ValuePathDataType Property - - internal Type ValuePathDataType - { - get; - set; - } - - #endregion - - #region DefaultDistinctValueItemContentTemplate Property - - private static readonly DependencyPropertyKey DefaultDistinctValueItemContentTemplatePropertyKey = DependencyProperty.RegisterReadOnly( - "DefaultDistinctValueItemContentTemplate", - typeof( DataTemplate ), - typeof( ForeignKeyConfiguration ), - new FrameworkPropertyMetadata( null ) ); - - internal static readonly DependencyProperty DefaultDistinctValueItemContentTemplateProperty; - - internal DataTemplate DefaultDistinctValueItemContentTemplate - { - get - { - return ( DataTemplate )this.GetValue( ForeignKeyConfiguration.DefaultDistinctValueItemContentTemplateProperty ); - } - } - - private void SetDefaultDistinctValueItemContentTemplate( DataTemplate value ) - { - this.SetValue( ForeignKeyConfiguration.DefaultDistinctValueItemContentTemplatePropertyKey, value ); - } - - private void ClearDefaultDistinctValueItemContentTemplate() - { - this.ClearValue( ForeignKeyConfiguration.DefaultDistinctValueItemContentTemplatePropertyKey ); - } - - #endregion - - #region DefaultCellContentTemplate Internal Property - - private static readonly DependencyPropertyKey DefaultCellContentTemplatePropertyKey = DependencyProperty.RegisterReadOnly( - "DefaultCellContentTemplate", - typeof( DataTemplate ), - typeof( ForeignKeyConfiguration ), - new FrameworkPropertyMetadata( null ) ); - - internal static readonly DependencyProperty DefaultCellContentTemplateProperty; - - internal DataTemplate DefaultCellContentTemplate - { - get - { - return ( DataTemplate )this.GetValue( ForeignKeyConfiguration.DefaultCellContentTemplateProperty ); - } - } - - private void SetDefaultCellContentTemplate( DataTemplate value ) - { - this.SetValue( ForeignKeyConfiguration.DefaultCellContentTemplatePropertyKey, value ); - } - - private void ClearDefaultCellContentTemplate() - { - this.ClearValue( ForeignKeyConfiguration.DefaultCellContentTemplatePropertyKey ); - } - - #endregion - - #region DefaultGroupValueTemplate Internal Property - - private static readonly DependencyPropertyKey DefaultGroupValueTemplatePropertyKey = DependencyProperty.RegisterReadOnly( - "DefaultGroupValueTemplate", - typeof( DataTemplate ), - typeof( ForeignKeyConfiguration ), - new FrameworkPropertyMetadata( null ) ); - - internal static readonly DependencyProperty DefaultGroupValueTemplateProperty; - - - internal DataTemplate DefaultGroupValueTemplate - { - get - { - return ( DataTemplate )this.GetValue( ForeignKeyConfiguration.DefaultGroupValueTemplateProperty ); - } - } - - private void SetDefaultGroupValueTemplate( DataTemplate value ) - { - this.SetValue( ForeignKeyConfiguration.DefaultGroupValueTemplatePropertyKey, value ); - } - - private void ClearDefaultGroupValueTemplate() - { - this.ClearValue( ForeignKeyConfiguration.DefaultGroupValueTemplatePropertyKey ); - } - - #endregion - - #region DefaultScrollTipContentTemplate Property - - private static readonly DependencyPropertyKey DefaultScrollTipContentTemplatePropertyKey = DependencyProperty.RegisterReadOnly( - "DefaultScrollTipContentTemplate", - typeof( DataTemplate ), - typeof( ForeignKeyConfiguration ), - new FrameworkPropertyMetadata( null ) ); - - internal static readonly DependencyProperty DefaultScrollTipContentTemplateProperty; - - internal DataTemplate DefaultScrollTipContentTemplate - { - get - { - return ( DataTemplate )this.GetValue( ForeignKeyConfiguration.DefaultScrollTipContentTemplateProperty ); - } - } - - private void SetDefaultScrollTipContentTemplate( DataTemplate value ) - { - this.SetValue( ForeignKeyConfiguration.DefaultScrollTipContentTemplatePropertyKey, value ); - } - - private void ClearDefaultScrollTipContentTemplate() - { - this.ClearValue( ForeignKeyConfiguration.DefaultScrollTipContentTemplatePropertyKey ); - } - - #endregion - - #region DefaultCellEditor Internal Property - - private static readonly DependencyPropertyKey DefaultCellEditorPropertyKey = DependencyProperty.RegisterReadOnly( - "DefaultCellEditor", - typeof( CellEditor ), - typeof( ForeignKeyConfiguration ), - new FrameworkPropertyMetadata( null ) ); - - internal static readonly DependencyProperty DefaultCellEditorProperty; - - internal CellEditor DefaultCellEditor - { - get - { - return ( CellEditor )this.GetValue( ForeignKeyConfiguration.DefaultCellEditorProperty ); - } - } - - private void SetDefaultCellEditor( CellEditor value ) - { - this.SetValue( ForeignKeyConfiguration.DefaultCellEditorPropertyKey, value ); - } - - private void ClearDefaultCellEditor() - { - this.ClearValue( ForeignKeyConfiguration.DefaultCellEditorPropertyKey ); - } - - #endregion - - internal object GetDisplayMemberValue( object fieldValue ) - { - try - { - var valuePath = this.ValuePath; - var displayMemberPath = this.DisplayMemberPath; - - if( ( valuePath == null ) || ( displayMemberPath == null ) ) - return fieldValue; - - var itemsSource = this.ItemsSource; - - //Convert the value from the ValuePath value to the DisplayMemberPath value, using a DataRowView or reflection. - if( ( itemsSource is DataView ) || ( itemsSource is DataTable ) ) - { - foreach( object item in itemsSource ) - { - var dataRowView = item as DataRowView; - if( dataRowView != null ) - { - var value = dataRowView[ valuePath ]; - - if( fieldValue.Equals( value ) ) - return dataRowView[ displayMemberPath ]; - } - } - } - else - { - foreach( object item in itemsSource ) - { - var value = item.GetType().GetProperty( valuePath ).GetValue( item, null ); - - if( fieldValue.Equals( value ) ) - return item.GetType().GetProperty( displayMemberPath ).GetValue( item, null ); - } - } - } - catch - { - //Swallow the exception, no need to terminate the application, since the original value will be exported. - } - - return fieldValue; - } - - internal static void UpdateColumnsForeignKeyConfigurations( - ObservableColumnCollection columns, - IEnumerable itemsSourceCollection, - PropertyDescriptionRouteDictionary propertyDescriptions, - bool autoCreateForeignKeyConfigurations ) - { - var collectionViewBase = itemsSourceCollection as DataGridCollectionViewBase; - if( collectionViewBase != null ) - { - ForeignKeyConfiguration.UpdateColumnsForeignKeyConfigurationsFromDataGridCollectionView( columns, collectionViewBase.ItemProperties, autoCreateForeignKeyConfigurations ); - } - else - { - ForeignKeyConfiguration.UpdateColumnsForeignKeyConfigurationsFromPropertyDescriptions( columns, propertyDescriptions, autoCreateForeignKeyConfigurations ); - } - } - - // If a DataGridCollectionViewBase is used, get the ItemProperties it defines to be able to retreive DataGridForeignKeyDescription for each of them - // to get the auto-detected ForeignKey ItemsSource (if any). - // If a DataGridCollectionViewBase is not used, the ItemsSource must be manually specified on each Column in order to correctly display/edit the Data - internal static void UpdateColumnsForeignKeyConfigurationsFromDataGridCollectionView( - ObservableColumnCollection columns, - DataGridItemPropertyCollection itemProperties, - bool autoCreateForeignKeyConfigurations ) - { - if( itemProperties == null ) - return; - - foreach( var itemProperty in itemProperties ) - { - var description = itemProperty.ForeignKeyDescription; - if( description != null ) - { - var columnName = PropertyRouteParser.Parse( itemProperty ); - var column = ( columnName != null ) ? columns[ columnName ] as Column : null; - - if( column != null ) - { - ForeignKeyConfiguration.SynchronizeForeignKeyConfigurationFromForeignKeyDescription( column, description, autoCreateForeignKeyConfigurations ); - } - } - - if( itemProperty.ItemPropertiesInternal != null ) - { - ForeignKeyConfiguration.UpdateColumnsForeignKeyConfigurationsFromDataGridCollectionView( - columns, - itemProperty.ItemPropertiesInternal, - autoCreateForeignKeyConfigurations ); - } - } - } - - private static void UpdateColumnsForeignKeyConfigurationsFromPropertyDescriptions( - ObservableColumnCollection columns, - PropertyDescriptionRouteDictionary propertyDescriptions, - bool autoCreateForeignKeyConfigurations ) - { - if( ( columns == null ) || ( propertyDescriptions == null ) ) - return; - - foreach( var column in columns ) - { - var targetColumn = column as Column; - if( targetColumn == null ) - continue; - - var key = PropertyRouteParser.Parse( targetColumn.FieldName ); - if( key == null ) - continue; - - var propertyDescription = propertyDescriptions[ key ]; - if( propertyDescription == null ) - continue; - - var foreignKeyDescription = propertyDescription.Current.ForeignKeyDescription; - if( foreignKeyDescription == null ) - continue; - - ForeignKeyConfiguration.SynchronizeForeignKeyConfigurationFromForeignKeyDescription( targetColumn, foreignKeyDescription, autoCreateForeignKeyConfigurations ); - } - } - - internal static void SynchronizeForeignKeyConfigurationFromForeignKeyDescription( - Column column, - DataGridForeignKeyDescription description, - bool autoCreateForeignKeyConfigurations ) - { - if( ( description == null ) || ( column == null ) ) - return; - - var configuration = column.ForeignKeyConfiguration; - if( configuration == null ) - { - if( !autoCreateForeignKeyConfigurations ) - return; - - configuration = new ForeignKeyConfiguration(); - configuration.IsAutoCreated = true; - column.ForeignKeyConfiguration = configuration; - } - - // ValuePath will be affected to the FieldName when the configuration is auto-created to be able to modify local source using foreign key value - if( configuration.IsAutoCreated ) - { - if( string.IsNullOrEmpty( configuration.ValuePath ) ) - { - configuration.ValuePath = description.ValuePath; - } - - if( string.IsNullOrEmpty( configuration.DisplayMemberPath ) ) - { - configuration.DisplayMemberPath = description.DisplayMemberPath; - } - } - - // Affect the ItemsSource on the configuration if it is not already set - if( ( configuration.ItemsSource == null ) && ( description.ItemsSource != null ) ) - { - configuration.ItemsSource = description.ItemsSource; - } - - // Set the Converter if it was not locally set - if( configuration.ForeignKeyConverter == null ) - { - configuration.ForeignKeyConverter = description.ForeignKeyConverter; - } - } - - #region IWeakEventListener Members - - 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( ( managerType == typeof( CollectionChangedEventManager ) ) || ( managerType == typeof( ListChangedEventManager ) ) ) - { - this.OnNotifiyCollectionChanged(); - } - else - { - return false; - } - - return true; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(ForeignKeys)/ForeignKeyConfigurationChangedEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(ForeignKeys)/ForeignKeyConfigurationChangedEventManager.cs deleted file mode 100644 index 10db6557..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(ForeignKeys)/ForeignKeyConfigurationChangedEventManager.cs +++ /dev/null @@ -1,72 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal class ForeignKeyConfigurationChangedEventManager : WeakEventManager - { - private ForeignKeyConfigurationChangedEventManager() - { - } - - public static void AddListener( Column source, IWeakEventListener listener ) - { - CurrentManager.ProtectedAddListener( source, listener ); - } - - public static void RemoveListener( Column source, IWeakEventListener listener ) - { - CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - Column column = ( Column )source; - column.ForeignKeyConfigurationChanged += new EventHandler( this.OnForeignKeyConfigurationChangedChanged ); - } - - protected override void StopListening( object source ) - { - Column column = ( Column )source; - column.ForeignKeyConfigurationChanged -= new EventHandler( this.OnForeignKeyConfigurationChangedChanged ); - } - - private static ForeignKeyConfigurationChangedEventManager CurrentManager - { - get - { - Type managerType = typeof( ForeignKeyConfigurationChangedEventManager ); - ForeignKeyConfigurationChangedEventManager currentManager = ( ForeignKeyConfigurationChangedEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new ForeignKeyConfigurationChangedEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - private void OnForeignKeyConfigurationChangedChanged( object sender, EventArgs args ) - { - this.DeliverEvent( sender, args ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(ForeignKeys)/ForeignKeyContentControl.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(ForeignKeys)/ForeignKeyContentControl.cs deleted file mode 100644 index 54bfb21b..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(ForeignKeys)/ForeignKeyContentControl.cs +++ /dev/null @@ -1,219 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows; -using System.Collections; -using System.Windows.Controls; -using System.Windows.Data; -using System.ComponentModel; - -namespace Xceed.Wpf.DataGrid -{ - internal class ForeignKeyContentControl : ContentControl - { - private static readonly Binding BindingToValue; - - static ForeignKeyContentControl() - { - ForeignKeyContentControl.BindingToValue = new Binding(); - ForeignKeyContentControl.BindingToValue.Mode = BindingMode.OneWay; - ForeignKeyContentControl.BindingToValue.Path = new PropertyPath( ForeignKeyContentControl.ValueProperty ); - ForeignKeyContentControl.BindingToValue.RelativeSource = new RelativeSource( RelativeSourceMode.Self ); - - ForeignKeyContentControl.FocusableProperty.OverrideMetadata( typeof( ForeignKeyContentControl ), new FrameworkPropertyMetadata( false ) ); - } - - public ForeignKeyContentControl() - { - // Bind ContentProperty to the Value property. - this.SetBinding( ForeignKeyContentControl.ContentProperty, ForeignKeyContentControl.BindingToValue ); - - // Ensure this control is not Focusable, it only displays converted value between - // ID and ForeignKey - this.Focusable = false; - } - - #region ForeignKeyConfiguration Property - - public static readonly DependencyProperty ForeignKeyConfigurationProperty = DependencyProperty.Register( - "ForeignKeyConfiguration", - typeof( ForeignKeyConfiguration ), - typeof( ForeignKeyContentControl ), - new FrameworkPropertyMetadata( - null, - new PropertyChangedCallback( ForeignKeyContentControl.OnForeignKeyConfigurationChanged ) ) ); - - public ForeignKeyConfiguration ForeignKeyConfiguration - { - get - { - return ( ForeignKeyConfiguration )this.GetValue( ForeignKeyContentControl.ForeignKeyConfigurationProperty ); - } - set - { - this.SetValue( ForeignKeyContentControl.ForeignKeyConfigurationProperty, value ); - } - } - - private static void OnForeignKeyConfigurationChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - ForeignKeyContentControl contentControl = sender as ForeignKeyContentControl; - - if( contentControl != null ) - { - contentControl.NotifyKeyChanged(); - } - } - - #endregion - - #region Key Property - - public static readonly DependencyProperty KeyProperty = DependencyProperty.Register( - "Key", - typeof( object ), - typeof( ForeignKeyContentControl ), - new FrameworkPropertyMetadata( - null, - new PropertyChangedCallback( ForeignKeyContentControl.OnKeyChanged ) ) ); - - public object Key - { - get - { - return ( object )this.GetValue( ForeignKeyContentControl.KeyProperty ); - } - set - { - this.SetValue( ForeignKeyContentControl.KeyProperty, value ); - } - } - - private static void OnKeyChanged( DependencyObject o, DependencyPropertyChangedEventArgs e ) - { - ForeignKeyContentControl contentControl = o as ForeignKeyContentControl; - - if( contentControl != null ) - { - contentControl.NotifyKeyChanged(); - } - } - - #endregion - - #region Value Property - - public static readonly DependencyProperty ValueProperty = DependencyProperty.Register( - "Value", - typeof( object ), - typeof( ForeignKeyContentControl ), - new FrameworkPropertyMetadata( - null, - new PropertyChangedCallback( OnValueChanged ) ) ); - - public object Value - { - get - { - return ( object )this.GetValue( ForeignKeyContentControl.ValueProperty ); - } - set - { - this.SetValue( ForeignKeyContentControl.ValueProperty, value ); - } - } - - private static void OnValueChanged( DependencyObject o, DependencyPropertyChangedEventArgs e ) - { - ForeignKeyContentControl contentControl = o as ForeignKeyContentControl; - - if( contentControl != null ) - { - contentControl.NotifyValueChanged(); - } - } - - #endregion - - protected void NotifyKeyChanged() - { - if( m_isBeingModified ) - return; - - try - { - m_isBeingModified = true; - - this.OnKeyChanged(); - } - finally - { - m_isBeingModified = false; - } - } - - protected void NotifyValueChanged() - { - if( m_isBeingModified ) - return; - - try - { - m_isBeingModified = true; - - this.OnValueChanged(); - } - finally - { - m_isBeingModified = false; - } - } - - private void OnKeyChanged() - { - ForeignKeyConfiguration configuration = this.ForeignKeyConfiguration; - - if( ( configuration != null ) && ( configuration.ForeignKeyConverter != null ) ) - { - this.Value = configuration.ForeignKeyConverter.GetValueFromKey( this.Key, configuration ); - } - else - { - this.Value = this.Key; - } - } - - private void OnValueChanged() - { - ForeignKeyConfiguration configuration = this.ForeignKeyConfiguration; - - if( ( configuration != null ) && ( configuration.ForeignKeyConverter != null ) ) - { - this.Key = configuration.ForeignKeyConverter.GetKeyFromValue( this.Value, configuration ); - } - else - { - this.Key = this.Value; - } - } - - private bool m_isBeingModified; // = false; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(ForeignKeys)/ForeignKeyConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(ForeignKeys)/ForeignKeyConverter.cs deleted file mode 100644 index aea26416..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(ForeignKeys)/ForeignKeyConverter.cs +++ /dev/null @@ -1,46 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Collections; - -namespace Xceed.Wpf.DataGrid -{ - public abstract class ForeignKeyConverter - { - public ForeignKeyConverter() - { - } - - public virtual object GetValueFromKey( object key, ForeignKeyConfiguration configuration ) - { - return key; - } - - public virtual object GetKeyFromValue( object value, ForeignKeyConfiguration configuration ) - { - return value; - } - - public virtual object GetValueFromKey( object key, DataGridForeignKeyDescription description ) - { - return key; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(ForeignKeys)/ForeignKeyDistinctValueItemContentControl.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(ForeignKeys)/ForeignKeyDistinctValueItemContentControl.cs deleted file mode 100644 index a0e5eca2..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(ForeignKeys)/ForeignKeyDistinctValueItemContentControl.cs +++ /dev/null @@ -1,154 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows; -using System.Windows.Data; - -namespace Xceed.Wpf.DataGrid -{ - internal class ForeignKeyDistinctValueItemContentControl : ForeignKeyContentControl - { - #region Static Fields - - private static Binding ParentAutoFilterControlBinding; - - #endregion - - #region Constructors - - static ForeignKeyDistinctValueItemContentControl() - { - ForeignKeyDistinctValueItemContentControl.ParentAutoFilterControlBinding = new Binding(); - ForeignKeyDistinctValueItemContentControl.ParentAutoFilterControlBinding.Mode = BindingMode.OneWay; - } - - public ForeignKeyDistinctValueItemContentControl() - { - } - - #endregion - - #region Private Methods - - #endregion - - #region DefaultCellContentTemplateBinding Private Static Property - - private static Binding DefaultCellContentTemplateBinding - { - get - { - if( ForeignKeyDistinctValueItemContentControl.DefaultCellContentTemplateBindingCache == null ) - { - ForeignKeyDistinctValueItemContentControl.DefaultCellContentTemplateBindingCache = new Binding(); - ForeignKeyDistinctValueItemContentControl.DefaultCellContentTemplateBindingCache.Mode = BindingMode.OneWay; - ForeignKeyDistinctValueItemContentControl.DefaultCellContentTemplateBindingCache.RelativeSource = new RelativeSource( RelativeSourceMode.Self ); - - ForeignKeyDistinctValueItemContentControl.DefaultCellContentTemplateBindingCache.Path = - new PropertyPath( "(0).(1).(2)", - Cell.ParentCellProperty, - Cell.ParentColumnProperty, - ColumnBase.CellContentTemplateProperty ); - } - - return ForeignKeyDistinctValueItemContentControl.DefaultCellContentTemplateBindingCache; - } - } - - private static Binding DefaultCellContentTemplateBindingCache; // = null; - - #endregion - - #region DefaultCellContentTemplateSelectorBinding Private Static Property - - private static Binding DefaultCellContentTemplateSelectorBinding - { - get - { - if( ForeignKeyDistinctValueItemContentControl.DefaultCellContentTemplateSelectorBindingCache == null ) - { - ForeignKeyDistinctValueItemContentControl.DefaultCellContentTemplateSelectorBindingCache = new Binding(); - ForeignKeyDistinctValueItemContentControl.DefaultCellContentTemplateSelectorBindingCache.Mode = BindingMode.OneWay; - ForeignKeyDistinctValueItemContentControl.DefaultCellContentTemplateSelectorBindingCache.RelativeSource = new RelativeSource( RelativeSourceMode.Self ); - - ForeignKeyDistinctValueItemContentControl.DefaultCellContentTemplateSelectorBindingCache.Path = - new PropertyPath( "(0).(1).(2)", - Cell.ParentCellProperty, - Cell.ParentColumnProperty, - ColumnBase.CellContentTemplateSelectorProperty ); - } - - return ForeignKeyDistinctValueItemContentControl.DefaultCellContentTemplateSelectorBindingCache; - } - } - - private static Binding DefaultCellContentTemplateSelectorBindingCache; - - #endregion - - #region DistinctValueItemTemplateBinding Private Static Property - - private static Binding DistinctValueItemTemplateBinding - { - get - { - if( ForeignKeyDistinctValueItemContentControl.DistinctValueItemTemplateBindingCache == null ) - { - ForeignKeyDistinctValueItemContentControl.DistinctValueItemTemplateBindingCache = new Binding(); - ForeignKeyDistinctValueItemContentControl.DistinctValueItemTemplateBindingCache.Mode = BindingMode.OneWay; - - - ForeignKeyDistinctValueItemContentControl.DistinctValueItemTemplateBindingCache.Path = - new PropertyPath( "DistinctValueItemTemplate" ); - } - - return ForeignKeyDistinctValueItemContentControl.DistinctValueItemTemplateBindingCache; - } - } - - private static Binding DistinctValueItemTemplateBindingCache; // = null; - - #endregion - - #region DefaultCellContentTemplateSelectorBinding Private Static Property - - private static Binding DistinctValueItemTemplateSelectorBinding - { - get - { - if( ForeignKeyDistinctValueItemContentControl.DistinctValueItemTemplateSelectorBindingCache == null ) - { - ForeignKeyDistinctValueItemContentControl.DistinctValueItemTemplateSelectorBindingCache = new Binding(); - ForeignKeyDistinctValueItemContentControl.DistinctValueItemTemplateSelectorBindingCache.Mode = BindingMode.OneWay; - - - ForeignKeyDistinctValueItemContentControl.DistinctValueItemTemplateSelectorBindingCache.Path = - new PropertyPath( "DistinctValueItemTemplateSelector" ); - } - - return ForeignKeyDistinctValueItemContentControl.DistinctValueItemTemplateSelectorBindingCache; - } - } - - private static Binding DistinctValueItemTemplateSelectorBindingCache; - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(ForeignKeys)/ForeignKeyGroupContentControl.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(ForeignKeys)/ForeignKeyGroupContentControl.cs deleted file mode 100644 index 6daa204f..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(ForeignKeys)/ForeignKeyGroupContentControl.cs +++ /dev/null @@ -1,207 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows.Controls; -using System.Windows; -using System.Diagnostics; -using System.Windows.Data; -using Xceed.Wpf.DataGrid.Views; - -namespace Xceed.Wpf.DataGrid -{ - internal class ForeignKeyGroupContentControl : ContentControl - { - #region Contructors - - static ForeignKeyGroupContentControl() - { - ForeignKeyGroupContentControl.GroupProperty = GroupHeaderControl.GroupProperty.AddOwner( typeof( ForeignKeyGroupContentControl ), new FrameworkPropertyMetadata( - null, - new PropertyChangedCallback( ForeignKeyGroupContentControl.OnGroupChanged ), - new CoerceValueCallback( ForeignKeyGroupContentControl.OnCoerceGroupChanged ) ) ); - } - - public ForeignKeyGroupContentControl() - { - // Ensure this control is not Focusable, it only displays converted value between - // ID and ForeignKey - this.Focusable = false; - } - - #endregion - - #region Group Internal Property - - internal static readonly DependencyProperty GroupProperty; - - internal Group Group - { - get - { - return GroupHeaderControl.GetGroup( this ); - } - } - - private static object OnCoerceGroupChanged( DependencyObject o, object newValue ) - { - ForeignKeyGroupContentControl contentControl = o as ForeignKeyGroupContentControl; - - if( contentControl != null ) - { - Group currentGroup = contentControl.Group; - Group newGroup = newValue as Group; - bool clearContentTemplate = false; - - if( ( currentGroup != null ) && ( newGroup != null ) ) - { - if( ( currentGroup.Level == -1 ) || ( newGroup.Level == -1 ) ) - { - clearContentTemplate = true; - } - // The Group is different, must clear the templates - else if( currentGroup.GroupBy != newGroup.GroupBy ) - { - clearContentTemplate = true; - } - } - else - { - // The Group is null or different, must clear the templates - clearContentTemplate = true; - } - - if( clearContentTemplate ) - { - contentControl.ClearValue( ContentControl.ContentTemplateProperty ); - contentControl.ClearValue( ContentControl.ContentTemplateSelectorProperty ); - } - } - - return newValue; - } - - private static void OnGroupChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - ForeignKeyGroupContentControl contentControl = sender as ForeignKeyGroupContentControl; - - if( contentControl != null ) - { - contentControl.UpdateContent( e.NewValue as Group ); - } - } - - #endregion - - #region Private Methods - - private void UpdateContent( Group group ) - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - if( dataGridContext == null ) - return; - - if( group == null ) - return; - - string groupBy = group.GroupBy; - - if( string.IsNullOrEmpty( groupBy ) ) - throw new DataGridInternalException( "Group.GroupBy is null." ); - - Column column = dataGridContext.Columns[ groupBy ] as Column; - - object newContent = group.Value; - - if( column != null ) - { - ForeignKeyConfiguration foreignKeyConfiguration = column.ForeignKeyConfiguration; - - if( foreignKeyConfiguration != null ) - { - // Ensure to set the Content converted according to the DataContext - // when a converter is present. Else, the DataContext will be displayed - if( foreignKeyConfiguration.ForeignKeyConverter != null ) - { - newContent = foreignKeyConfiguration.ForeignKeyConverter.GetValueFromKey( - group.Value, - foreignKeyConfiguration ); - } - } - } - - // We must update the template according - // to values present on Column - this.UpdateContentTemplate( column, group ); - - this.Content = newContent; - } - - private void UpdateContentTemplate( Column column, Group group ) - { - if( column == null ) - return; - - bool contentTemplateAffected = false; - bool contentTemplateSelectorAffected = false; - - if( column.GroupValueTemplate != null ) - { - this.ContentTemplate = column.GroupValueTemplate; - contentTemplateAffected = true; - } - else if( column.GroupValueTemplateSelector != null ) - { - this.ContentTemplateSelector = column.GroupValueTemplateSelector; - contentTemplateSelectorAffected = true; - } - - if( !contentTemplateAffected && !contentTemplateSelectorAffected ) - { - ForeignKeyConfiguration foreignKeyConfiguration = column.ForeignKeyConfiguration; - if( foreignKeyConfiguration != null ) - { - if( column.CellContentTemplate != null ) - { - this.ContentTemplate = column.CellContentTemplate; - contentTemplateAffected = true; - } - else if( column.CellContentTemplateSelector != null ) - { - this.ContentTemplateSelector = column.CellContentTemplateSelector; - contentTemplateSelectorAffected = true; - } - } - } - - if( !contentTemplateAffected ) - { - this.ClearValue( ContentPresenter.ContentTemplateProperty ); - } - - if( !contentTemplateSelectorAffected ) - { - this.ClearValue( ContentPresenter.ContentTemplateSelectorProperty ); - } - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(ForeignKeys)/ForeignKeyScrollTipContentControl.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(ForeignKeys)/ForeignKeyScrollTipContentControl.cs deleted file mode 100644 index 0e9589eb..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(ForeignKeys)/ForeignKeyScrollTipContentControl.cs +++ /dev/null @@ -1,164 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Windows; -using System.Windows.Data; -using Xceed.Wpf.DataGrid.Views; - -namespace Xceed.Wpf.DataGrid -{ - internal class ForeignKeyScrollTipContentControl : ForeignKeyContentControl - { - #region Static Fields - - private static Binding MainColumnBinding; // = null; - - #endregion - - #region Constructors - - static ForeignKeyScrollTipContentControl() - { - ForeignKeyScrollTipContentControl.MainColumnBinding = new Binding(); - ForeignKeyScrollTipContentControl.MainColumnBinding.Mode = BindingMode.OneWay; - ForeignKeyScrollTipContentControl.MainColumnBinding.RelativeSource = new RelativeSource( RelativeSourceMode.FindAncestor, typeof( ScrollTip ), 1 ); - ForeignKeyScrollTipContentControl.MainColumnBinding.Path = new PropertyPath( "(0).Columns.MainColumn", DataGridControl.DataGridContextProperty ); - } - - public ForeignKeyScrollTipContentControl() - { - BindingOperations.SetBinding( - this, - ForeignKeyScrollTipContentControl.MainColumnProperty, - ForeignKeyScrollTipContentControl.MainColumnBinding ); - - // Ensure this control is not Focusable, it only displays converted value between - // ID and ForeignKey - this.Focusable = false; - } - - #endregion - - #region MainColumn Property - - public static readonly DependencyProperty MainColumnProperty = DependencyProperty.Register( - "MainColumn", - typeof( ColumnBase ), - typeof( ForeignKeyScrollTipContentControl ), - new FrameworkPropertyMetadata( - null, - new PropertyChangedCallback( ForeignKeyScrollTipContentControl.OnMainColumnChanged ) ) ); - - public ColumnBase MainColumn - { - get - { - return ( ColumnBase )this.GetValue( ForeignKeyScrollTipContentControl.MainColumnProperty ); - } - set - { - this.SetValue( ForeignKeyScrollTipContentControl.MainColumnProperty, value ); - } - } - - private static void OnMainColumnChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - ForeignKeyScrollTipContentControl contentControl = sender as ForeignKeyScrollTipContentControl; - - if( contentControl != null ) - { - // Reset ContentTemplate/Selector when the MainColum changes - // since it is set locally - contentControl.ContentTemplate = null; - contentControl.ContentTemplateSelector = null; - - contentControl.UpdateKeyBinding(); - contentControl.UpdateContentTemplate(); - } - } - - #endregion - - #region Private Methods - - private void UpdateContentTemplate() - { - Column mainColumn = this.MainColumn as Column; - - if( mainColumn == null ) - return; - - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - UIViewBase uiViewBase = null; - - if( dataGridContext != null ) - { - DataGridControl dataGridControl = dataGridContext.DataGridControl; - - if( dataGridControl != null ) - { - uiViewBase = dataGridControl.GetView() as UIViewBase; - } - } - - if( uiViewBase != null ) - { - if( uiViewBase.ScrollTipContentTemplate != null ) - { - this.ContentTemplate = uiViewBase.ScrollTipContentTemplate; - } - else - { - this.ContentTemplateSelector = uiViewBase.ScrollTipContentTemplateSelector; - } - } - - if( ( this.ContentTemplate == null ) && ( this.ContentTemplateSelector == null ) ) - { - if( mainColumn.CellContentTemplate != null ) - { - this.ContentTemplate = mainColumn.CellContentTemplate; - } - else - { - this.ContentTemplateSelector = mainColumn.CellContentTemplateSelector; - } - } - } - - private void UpdateKeyBinding() - { - Column mainColumn = this.MainColumn as Column; - - if( mainColumn == null ) - return; - - // Disable warning for DisplayMemberBinding when internaly used -#pragma warning disable 618 - BindingBase displayMemberBinding = mainColumn.DisplayMemberBinding; - - if( displayMemberBinding != null ) - { - // Set the DisplayMemberBinding to the KeyProperty - this.SetBinding( ForeignKeyScrollTipContentControl.KeyProperty, displayMemberBinding ); - } -#pragma warning restore 618 - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/CollectionGeneratorNode.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/CollectionGeneratorNode.cs deleted file mode 100644 index c71f366b..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/CollectionGeneratorNode.cs +++ /dev/null @@ -1,52 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Collections; -using System.Diagnostics; - -namespace Xceed.Wpf.DataGrid -{ - internal class CollectionGeneratorNode : NotifyCollectionChangedGeneratorNode - { - protected CollectionGeneratorNode( IList list, GeneratorNode parent ) - : base( parent ) - { - Debug.Assert( list != null, "list cannot be null for CollectionGeneratorNode" ); - - m_items = list; - } - - public IList Items - { - get - { - return m_items; - } - } - - public virtual int IndexOf( object item ) - { - return m_items.IndexOf( item ); - } - - public virtual object GetAt( int index ) - { - return m_items[ index ]; - } - - private readonly IList m_items; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/ContainersRemovedEvent.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/ContainersRemovedEvent.cs deleted file mode 100644 index bdf27017..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/ContainersRemovedEvent.cs +++ /dev/null @@ -1,48 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows; -using System.Collections.Specialized; - -namespace Xceed.Wpf.DataGrid -{ - internal delegate void ContainersRemovedEventHandler( object sender, ContainersRemovedEventArgs e ); - - internal class ContainersRemovedEventArgs : EventArgs - { - public ContainersRemovedEventArgs( IList removedContainers ) - { - if( removedContainers == null ) - throw new ArgumentNullException( "removedContainers" ); - - m_removedContainers = removedContainers; - } - - public IList RemovedContainers - { - get - { - return m_removedContainers; - } - } - - private IList m_removedContainers; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/CustomGeneratorChangedEvent.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/CustomGeneratorChangedEvent.cs deleted file mode 100644 index 9016ccfc..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/CustomGeneratorChangedEvent.cs +++ /dev/null @@ -1,78 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal delegate void CustomGeneratorChangedEventHandler( object sender, CustomGeneratorChangedEventArgs e ); - - internal sealed class CustomGeneratorChangedEventArgs : EventArgs - { - private CustomGeneratorChangedEventArgs( NotifyCollectionChangedAction action, int count, IList containers ) - { - m_action = action; - m_count = count; - m_containers = containers; - } - - internal NotifyCollectionChangedAction Action - { - get - { - return m_action; - } - } - - internal int Count - { - get - { - return m_count; - } - } - - internal IList Containers - { - get - { - return m_containers; - } - } - - internal static CustomGeneratorChangedEventArgs Add( int count ) - { - return new CustomGeneratorChangedEventArgs( NotifyCollectionChangedAction.Add, count, null ); - } - - internal static CustomGeneratorChangedEventArgs Remove( int count, IList containers ) - { - return new CustomGeneratorChangedEventArgs( NotifyCollectionChangedAction.Remove, count, containers ); - } - - internal static CustomGeneratorChangedEventArgs Reset() - { - return new CustomGeneratorChangedEventArgs( NotifyCollectionChangedAction.Reset, 0, null ); - } - - private readonly NotifyCollectionChangedAction m_action; - private readonly int m_count; - private readonly IList m_containers; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/CustomItemContainerGenerator.Trace.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/CustomItemContainerGenerator.Trace.cs deleted file mode 100644 index 81cbe351..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/CustomItemContainerGenerator.Trace.cs +++ /dev/null @@ -1,82 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using Xceed.Wpf.DataGrid.Diagnostics; - -namespace Xceed.Wpf.DataGrid -{ - partial class CustomItemContainerGenerator - { - private IDisposable TraceBlock( DataGridTraceEventId eventId ) - { - return this.TraceBlock( eventId, ( string )null, null ); - } - - private IDisposable TraceBlock( DataGridTraceEventId eventId, params DataGridTraceArg[] args ) - { - return this.TraceBlock( eventId, null, args ); - } - - private IDisposable TraceBlock( DataGridTraceEventId eventId, string message, params DataGridTraceArg[] args ) - { - var traceSource = DataGridControlTraceSources.ItemContainerGeneratorSource; - if( !traceSource.ShouldTraceBlock() ) - return traceSource.NoTrace; - - return traceSource.TraceBlock( eventId, message, this.GetTraceArgs( args ).ToList() ); - } - - [Conditional( "TRACE" )] - private void TraceEvent( TraceEventType eventType, DataGridTraceEventId eventId ) - { - this.TraceEvent( eventType, eventId, ( string )null, null ); - } - - [Conditional( "TRACE" )] - private void TraceEvent( TraceEventType eventType, DataGridTraceEventId eventId, params DataGridTraceArg[] args ) - { - this.TraceEvent( eventType, eventId, null, args ); - } - - [Conditional( "TRACE" )] - private void TraceEvent( TraceEventType eventType, DataGridTraceEventId eventId, string message, params DataGridTraceArg[] args ) - { - var traceSource = DataGridControlTraceSources.ItemContainerGeneratorSource; - if( !traceSource.ShouldTrace( eventType ) ) - return; - - traceSource.TraceEvent( eventType, eventId, message, this.GetTraceArgs( args ).ToList() ); - } - - private IEnumerable GetTraceArgs( DataGridTraceArg[] args ) - { - if( ( args != null ) && ( args.Length > 0 ) ) - { - foreach( var arg in args ) - { - yield return arg; - } - } - - yield return DataGridTraceArgs.Generator( this ); - yield return DataGridTraceArgs.DataGridControl( m_dataGridControl ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/CustomItemContainerGenerator.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/CustomItemContainerGenerator.cs deleted file mode 100644 index eccc13cb..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/CustomItemContainerGenerator.cs +++ /dev/null @@ -1,7589 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Diagnostics; -using System.Linq; -using System.Threading; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Controls.Primitives; -using System.Windows.Data; -using Xceed.Utils.Collections; -using Xceed.Wpf.DataGrid.Diagnostics; -using Xceed.Wpf.DataGrid.Views; - -namespace Xceed.Wpf.DataGrid -{ - internal partial class CustomItemContainerGenerator - : IInhibitGenPosToIndexUpdating, - ICustomItemContainerGenerator, - IWeakEventListener, - INotifyPropertyChanged, - IDataGridContextVisitable - { - internal static CustomItemContainerGenerator CreateGenerator( DataGridControl dataGridControl, CollectionView collectionView, DataGridContext dataGridContext ) - { - if( dataGridControl == null ) - throw new ArgumentNullException( "dataGridControl" ); - - if( collectionView == null ) - throw DataGridException.Create( "collectionView", dataGridControl ); - - if( dataGridContext == null ) - throw DataGridException.Create( "dataGridContext", dataGridControl ); - - var recyclingPools = new CustomItemContainerGeneratorRecyclingPools(); - var ensureNodeTreeCreatedRequiredFlag = new BubbleDirtyFlag( true ); - var handleGlobalItemsResetFlag = new InheritAutoResetFlag(); - var deferDetailsRemapFlag = new LeveledAutoResetFlag(); - var generator = new CustomItemContainerGenerator( dataGridControl, collectionView, dataGridContext, recyclingPools, ensureNodeTreeCreatedRequiredFlag, handleGlobalItemsResetFlag, deferDetailsRemapFlag ); - - dataGridContext.SetGenerator( generator ); - - return generator; - } - - private static CustomItemContainerGenerator CreateGenerator( DataGridControl dataGridControl, CollectionView collectionView, DataGridContext dataGridContext, CustomItemContainerGenerator masterGenerator ) - { - if( dataGridControl == null ) - throw new ArgumentNullException( "dataGridControl" ); - - if( collectionView == null ) - throw DataGridException.Create( "collectionView", dataGridControl ); - - if( dataGridContext == null ) - throw DataGridException.Create( "dataGridContext", dataGridControl ); - - if( masterGenerator == null ) - throw DataGridException.Create( "masterGenerator", dataGridControl ); - - var recyclingPools = masterGenerator.m_recyclingPools; - var ensureNodeTreeCreatedRequiredFlag = new BubbleDirtyFlag( masterGenerator.m_ensureNodeTreeCreatedRequired, true ); - var handleGlobalItemsResetFlag = new InheritAutoResetFlag( masterGenerator.m_handleGlobalItemsReset ); - var deferDetailsRemapFlag = masterGenerator.m_deferDetailsRemap.GetChild(); - var generator = new CustomItemContainerGenerator( dataGridControl, collectionView, dataGridContext, recyclingPools, ensureNodeTreeCreatedRequiredFlag, handleGlobalItemsResetFlag, deferDetailsRemapFlag ); - - dataGridContext.SetGenerator( generator ); - - return generator; - } - - private CustomItemContainerGenerator( - DataGridControl dataGridControl, - CollectionView collectionView, - DataGridContext dataGridContext, - CustomItemContainerGeneratorRecyclingPools recyclingPools, - BubbleDirtyFlag ensureNodeTreeCreatedRequiredFlag, - InheritAutoResetFlag handleGlobalItemResetFlag, - LeveledAutoResetFlag deferDetailsRemapFlag ) - { - Debug.Assert( dataGridControl != null ); - Debug.Assert( collectionView != null ); - Debug.Assert( dataGridContext != null ); - Debug.Assert( recyclingPools != null ); - Debug.Assert( ensureNodeTreeCreatedRequiredFlag != null ); - Debug.Assert( handleGlobalItemResetFlag != null ); - Debug.Assert( deferDetailsRemapFlag != null ); - - m_dataGridControl = dataGridControl; - m_dataGridContext = dataGridContext; - m_collectionView = collectionView; - m_recyclingPools = recyclingPools; - m_ensureNodeTreeCreatedRequired = ensureNodeTreeCreatedRequiredFlag; - m_handleGlobalItemsReset = handleGlobalItemResetFlag; - m_deferDetailsRemap = deferDetailsRemapFlag; - - //initialize explicitly (set a local value) to the DataItem attached property (for nested DataGridControls) - CustomItemContainerGenerator.SetDataItemProperty( m_dataGridControl, EmptyDataItemDataProvider.Instance ); - - this.RegisterEvents(); - - m_nodeFactory = new GeneratorNodeFactory( this.OnGeneratorNodeItemsCollectionChanged, - this.OnGeneratorNodeGroupsCollectionChanged, - this.OnGeneratorNodeHeadersFootersCollectionChanged, - this.OnGeneratorNodeExpansionStateChanged, - this.OnGroupGeneratorNodeIsExpandedChanging, - this.OnGroupGeneratorNodeIsExpandedChanged, - dataGridControl ); - - m_headerFooterDataContextBinding = new Binding(); - m_headerFooterDataContextBinding.Source = m_dataGridControl; - m_headerFooterDataContextBinding.Path = new PropertyPath( DataGridControl.DataContextProperty ); - - this.ResetNodeList(); - - this.IncrementCurrentGenerationCount(); - } - - #region CurrentGeneratorContentGeneration Internal Property - - internal int CurrentGeneratorContentGeneration - { - get - { - return m_currentGeneratorContentGeneration; - } - } - - private int m_currentGeneratorContentGeneration; //0 - - #endregion - - #region DataItemProperty Attached Internal Property - - internal static readonly DependencyProperty DataItemPropertyProperty = DependencyProperty.RegisterAttached( - "DataItemProperty", - typeof( DataItemDataProviderBase ), - typeof( CustomItemContainerGenerator ), - new FrameworkPropertyMetadata( EmptyDataItemDataProvider.Instance, FrameworkPropertyMetadataOptions.Inherits ) ); - - internal static DataItemDataProviderBase GetDataItemProperty( DependencyObject obj ) - { - return ( DataItemDataProviderBase )obj.GetValue( CustomItemContainerGenerator.DataItemPropertyProperty ); - } - - private static void SetDataItemProperty( DependencyObject obj, DataItemDataProviderBase value ) - { - obj.SetValue( CustomItemContainerGenerator.DataItemPropertyProperty, value ); - } - - #endregion - - #region IsInUse Internal Property - - internal bool IsInUse - { - get - { - return m_flags[ ( int )CustomItemContainerGeneratorFlags.InUse ]; - } - private set - { - m_flags[ ( int )CustomItemContainerGeneratorFlags.InUse ] = value; - } - } - - internal void InvalidateIsInUse() - { - this.IsInUse = false; - } - - internal void SetIsInUse() - { - this.IsInUse = true; - } - - #endregion - - #region ForceReset Internal Property - - internal bool ForceReset - { - get - { - return m_flags[ ( int )CustomItemContainerGeneratorFlags.ForceReset ]; - } - set - { - m_flags[ ( int )CustomItemContainerGeneratorFlags.ForceReset ] = value; - } - } - - #endregion - - #region Header Property - - public HeadersFootersGeneratorNode Header - { - get - { - return m_firstHeader; - } - } - - private HeadersFootersGeneratorNode m_firstHeader; - - #endregion - - #region Footer Property - - public HeadersFootersGeneratorNode Footer - { - get - { - return m_firstFooter; - } - } - - private HeadersFootersGeneratorNode m_firstFooter; - - #endregion - - #region RealizedContainers Property - - public ReadOnlyCollection RealizedContainers - { - get - { - return new ReadOnlyCollection( m_genPosToContainer ); - } - } - - #endregion - - #region RealizedItems Property - - public ReadOnlyCollection RealizedItems - { - get - { - return new ReadOnlyCollection( m_genPosToItem ); - } - } - - #endregion - - #region Status Property - - public GeneratorStatus Status - { - get - { - return m_generatorStatus; - } - } - - private GeneratorStatus m_generatorStatus = GeneratorStatus.NotStarted; - - #endregion - - #region NodeFactory Private Property - - private GeneratorNodeFactory NodeFactory - { - get - { - return m_nodeFactory; - } - } - - private readonly GeneratorNodeFactory m_nodeFactory; - - #endregion - - #region IsDetailsRemapDeferred Private Property - - private bool IsDetailsRemapDeferred - { - get - { - return m_deferDetailsRemap.IsSet; - } - } - - private IDisposable DeferDetailsRemap() - { - return m_deferDetailsRemap.Set(); - } - - private readonly LeveledAutoResetFlag m_deferDetailsRemap; - - #endregion - - #region IsEnsuringNodeTreeCreated Private Property - - private bool IsEnsuringNodeTreeCreated - { - get - { - return m_ensureNodeTreeCreated.IsSet; - } - } - - private IDisposable SetIsEnsuringNodeTreeCreated() - { - m_ensureNodeTreeCreatedRequired.IsSet = false; - - return m_ensureNodeTreeCreated.Set(); - } - - private readonly AutoResetFlag m_ensureNodeTreeCreated = AutoResetFlagFactory.Create(); - - #endregion - - #region IsNodeTreeValid Private Property - - private bool IsNodeTreeValid - { - get - { - return !m_ensureNodeTreeCreatedRequired.IsSet; - } - } - - private void InvalidateNodeTree() - { - if( this.IsEnsuringNodeTreeCreated ) - return; - - m_ensureNodeTreeCreatedRequired.IsSet = true; - } - - private readonly BubbleDirtyFlag m_ensureNodeTreeCreatedRequired; - - #endregion - - #region IsHandlingGlobalItemsReset Private Property - - private bool IsHandlingGlobalItemsReset - { - get - { - return m_handleGlobalItemsReset.IsSet; - } - } - - private bool IsHandlingGlobalItemsResetLocally - { - get - { - return m_handleGlobalItemsReset.IsSetLocal; - } - } - - private IDisposable SetIsHandlingGlobalItemsResetLocally() - { - return m_handleGlobalItemsReset.SetLocal(); - } - - private readonly InheritAutoResetFlag m_handleGlobalItemsReset; - - #endregion - - #region IsItemsChangedInhibited Private Property - - private bool IsItemsChangedInhibited - { - get - { - return m_isItemsChangedInhibited.IsSet; - } - } - - private IDisposable InhibitItemsChanged() - { - return m_isItemsChangedInhibited.Set(); - } - - private readonly AutoResetFlag m_isItemsChangedInhibited = AutoResetFlagFactory.Create(); - - #endregion - - #region DetailsChanged Event - - public event EventHandler DetailsChanged; - - #endregion - - #region ItemsChanged Internal Event - - internal event CustomGeneratorChangedEventHandler ItemsChanged; - - private void SendRemoveEvent( int count, IList containers ) - { - var handler = this.ItemsChanged; - if( ( handler == null ) || ( count <= 0 ) || this.IsItemsChangedInhibited ) - return; - - using( this.DeferDetailsRemap() ) - { - handler.Invoke( this, CustomGeneratorChangedEventArgs.Remove( count, containers ) ); - } - } - - private void SendAddEvent( int count ) - { - var handler = this.ItemsChanged; - if( ( handler == null ) || ( count <= 0 ) || this.IsItemsChangedInhibited ) - return; - - using( this.DeferDetailsRemap() ) - { - handler.Invoke( this, CustomGeneratorChangedEventArgs.Add( count ) ); - } - } - - private void SendResetEvent() - { - var handler = this.ItemsChanged; - if( ( handler == null ) || this.IsItemsChangedInhibited ) - return; - - using( this.DeferDetailsRemap() ) - { - handler.Invoke( this, CustomGeneratorChangedEventArgs.Reset() ); - } - } - - #endregion - - #region ContainersRemoved Internal Event - - internal event ContainersRemovedEventHandler ContainersRemoved; - - private void OnContainersRemoved( IList containers ) - { - var handler = this.ContainersRemoved; - if( ( handler == null ) || ( containers == null ) || ( containers.Count <= 0 ) ) - return; - - handler.Invoke( this, new ContainersRemovedEventArgs( containers ) ); - } - - #endregion - - #region RecyclingCandidatesCleaned Internal Event - - internal event RecyclingCandidatesCleanedEventHandler RecyclingCandidatesCleaned; - - private void OnRecyclingCandidatesCleaned( object sender, RecyclingCandidatesCleanedEventArgs e ) - { - if( !this.IsRecyclingEnabled ) - return; - - foreach( DependencyObject container in e.RecyclingCandidates ) - { - this.ClearStatContext( container ); - } - - var handler = this.RecyclingCandidatesCleaned; - if( handler == null ) - return; - - handler.Invoke( this, e ); - } - - #endregion - - public void ResetGeneratorContent() - { - this.CleanupGenerator(); - this.EnsureNodeTreeCreated(); - } - - public DependencyObject ContainerFromIndex( int itemIndex ) - { - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_ContainerFromIndex, DataGridTraceArgs.Index( itemIndex ) ) ) - { - if( this.IsHandlingGlobalItemsReset ) - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_ContainerFromIndex, DataGridTraceMessages.CannotProcessOnReset, DataGridTraceArgs.Index( itemIndex ) ); - return null; - } - - this.EnsureNodeTreeCreated(); - - var index = m_genPosToIndex.IndexOf( itemIndex ); - if( index >= 0 ) - { - var container = m_genPosToContainer[ index ]; - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_ContainerFromIndex, DataGridTraceMessages.ContainerFound, DataGridTraceArgs.Container( container ), DataGridTraceArgs.GeneratorIndex( index ), DataGridTraceArgs.Index( itemIndex ) ); - - var detailNode = m_genPosToNode[ index ] as DetailGeneratorNode; - if( detailNode == null ) - return container; - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_ContainerFromIndex, DataGridTraceMessages.ContainerIsInDetail, DataGridTraceArgs.Container( container ), DataGridTraceArgs.GeneratorIndex( index ), DataGridTraceArgs.Index( itemIndex ), DataGridTraceArgs.Node( detailNode ) ); - } - else - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_ContainerFromIndex, DataGridTraceMessages.ContainerNotFound, DataGridTraceArgs.Index( itemIndex ) ); - } - - return null; - } - } - - internal DependencyObject ContainerFromItem( object item ) - { - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_ContainerFromItem, DataGridTraceArgs.Item( item ) ) ) - { - if( this.IsHandlingGlobalItemsReset ) - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_ContainerFromItem, DataGridTraceMessages.CannotProcessOnReset, DataGridTraceArgs.Item( item ) ); - return null; - } - - this.EnsureNodeTreeCreated(); - - var index = this.FindFirstGeneratedIndexForLocalItem( item ); - if( index >= 0 ) - { - var container = m_genPosToContainer[ index ]; - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_ContainerFromItem, DataGridTraceMessages.ContainerFound, DataGridTraceArgs.Container( container ), DataGridTraceArgs.GeneratorIndex( index ), DataGridTraceArgs.Item( item ) ); - return container; - } - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_ContainerFromItem, DataGridTraceMessages.ContainerNotFound, DataGridTraceArgs.Item( item ) ); - return null; - } - } - - internal List GetRealizedDataItemsForGroup( GroupGeneratorNode group ) - { - var count = m_genPosToNode.Count; - var items = new List( count ); - - for( int i = 0; i < count; i++ ) - { - var node = m_genPosToNode[ i ] as ItemsGeneratorNode; - if( ( node != null ) && ( node.Parent == group ) ) - { - items.Add( m_genPosToItem[ i ] ); - } - } - - return items; - } - - internal List GetRealizedDataItems() - { - var count = m_genPosToNode.Count; - var items = new List( count ); - - for( int i = 0; i < count; i++ ) - { - var node = m_genPosToNode[ i ] as ItemsGeneratorNode; - if( node != null ) - { - items.Add( m_genPosToItem[ i ] ); - } - } - - return items; - } - - internal object ItemFromContainer( DependencyObject container ) - { - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_ItemFromContainer, DataGridTraceArgs.Container( container ) ) ) - { - if( this.IsHandlingGlobalItemsReset ) - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_ItemFromContainer, DataGridTraceMessages.CannotProcessOnReset, DataGridTraceArgs.Container( container ) ); - return null; - } - - var dataItemStore = CustomItemContainerGenerator.GetDataItemProperty( container ); - if( ( dataItemStore == null ) || dataItemStore.IsEmpty ) - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_ItemFromContainer, DataGridTraceMessages.ItemNotFound, DataGridTraceArgs.Container( container ) ); - return null; - } - - var dataItem = dataItemStore.Data; - var index = m_genPosToContainer.IndexOf( container ); - - if( index >= 0 ) - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_ItemFromContainer, DataGridTraceMessages.ContainerFound, DataGridTraceArgs.Container( container ), DataGridTraceArgs.GeneratorIndex( index ) ); - - var detailNode = m_genPosToNode[ index ] as DetailGeneratorNode; - if( detailNode != null ) - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_ItemFromContainer, DataGridTraceMessages.ContainerIsInDetail, DataGridTraceArgs.Container( container ), DataGridTraceArgs.GeneratorIndex( index ), DataGridTraceArgs.Node( detailNode ) ); - return null; - } - } - else - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_ItemFromContainer, DataGridTraceMessages.ContainerNotFound, DataGridTraceArgs.Container( container ), DataGridTraceArgs.Item( dataItem ) ); - } - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_ItemFromContainer, DataGridTraceMessages.ItemFound, DataGridTraceArgs.Item( dataItem ), DataGridTraceArgs.Container( container ) ); - return dataItem; - } - } - - public int IndexFromItem( object item ) - { - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_IndexFromItem, DataGridTraceArgs.Item( item ) ) ) - { - if( item == null ) - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_IndexFromItem, DataGridTraceMessages.ItemNotFound, DataGridTraceArgs.Item( item ) ); - return -1; - } - - this.EnsureNodeTreeCreated(); - - if( m_startNode == null ) - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_IndexFromItem, DataGridTraceMessages.EmptyTree, DataGridTraceArgs.Item( item ) ); - return -1; - } - - var index = this.FindFirstGeneratedIndexForLocalItem( item ); - if( index >= 0 ) - { - var itemIndex = m_genPosToIndex[ index ]; - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_IndexFromItem, DataGridTraceMessages.IndexFound, DataGridTraceArgs.Index( itemIndex ), DataGridTraceArgs.GeneratorIndex( index ), DataGridTraceArgs.Item( item ) ); - return itemIndex; - } - else - { - //Note: Under that specific case, I do not want to search through collapsed group nodes... Effectivelly, an item "below" a collapsed group node - // Have no index as per the "item to index" interface of the generator. - var nodeHelper = new GeneratorNodeHelper( m_startNode, 0, 0 ); - var itemIndex = nodeHelper.FindItem( item ); - - if( itemIndex >= 0 ) - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_IndexFromItem, DataGridTraceMessages.IndexFound, DataGridTraceArgs.Index( itemIndex ), DataGridTraceArgs.Node( nodeHelper.CurrentNode ), DataGridTraceArgs.Item( item ) ); - return itemIndex; - } - } - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_IndexFromItem, DataGridTraceMessages.ItemNotFoundOrCollapsed, DataGridTraceArgs.Item( item ) ); - return -1; - } - } - - public object ItemFromIndex( int index ) - { - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_ItemFromIndex, DataGridTraceArgs.Index( index ) ) ) - { - this.EnsureNodeTreeCreated(); - - if( m_startNode == null ) - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_ItemFromIndex, DataGridTraceMessages.EmptyTree, DataGridTraceArgs.Index( index ) ); - return null; - } - - var nodeHelper = new GeneratorNodeHelper( m_startNode, 0, 0 ); - var item = nodeHelper.FindIndex( index ); - - if( item != null ) - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_ItemFromIndex, DataGridTraceMessages.ItemFound, DataGridTraceArgs.Item( item ), DataGridTraceArgs.Node( nodeHelper.CurrentNode ), DataGridTraceArgs.Index( index ) ); - } - else - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_ItemFromIndex, DataGridTraceMessages.ItemNotFound, DataGridTraceArgs.Index( index ) ); - } - - return item; - } - } - - internal bool IsGroupRealized( Group group ) - { - var groupNode = ( group != null ) ? group.GeneratorNode : null; - if( groupNode == null ) - return false; - - foreach( var node in m_genPosToNode ) - { - var parentNode = node; - - // Find the first GroupGeneratorNode among its ancestors. - while( parentNode != null ) - { - if( parentNode is GroupGeneratorNode ) - break; - - parentNode = parentNode.Parent; - } - - // Find out if the GroupGeneratorNode found is the group or a - // child of the target group. - while( parentNode != null ) - { - if( parentNode == groupNode ) - return true; - - // The current node cannot be a child of the target group if - // the parent node is not a group. - parentNode = parentNode.Parent as GroupGeneratorNode; - } - } - - return false; - } - - public int GetGroupIndex( Group group ) - { - if( group == null ) - throw DataGridException.Create( "group", m_dataGridControl ); - - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_GetGroupIndex, DataGridTraceArgs.Group( group ) ) ) - { - this.EnsureNodeTreeCreated(); - - if( m_startNode == null ) - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_GetGroupIndex, DataGridTraceMessages.EmptyTree, DataGridTraceArgs.Group( group ) ); - return -1; - } - - var nodeHelper = new GeneratorNodeHelper( m_startNode, 0, 0 ); - if( nodeHelper.FindGroup( group.CollectionViewGroup ) ) - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_GetGroupIndex, DataGridTraceMessages.GroupFound, DataGridTraceArgs.Index( nodeHelper.Index ), DataGridTraceArgs.Node( nodeHelper.CurrentNode ), DataGridTraceArgs.Group( group ) ); - return nodeHelper.Index; - } - - foreach( var detailNode in this.GetDetailGeneratorNodes() ) - { - var index = detailNode.DetailGenerator.GetGroupIndex( group ); - if( index >= 0 ) - { - var detailIndex = this.FindGlobalIndexForDetailNode( detailNode ); - if( detailIndex >= 0 ) - { - var groupIndex = index + detailIndex; - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_GetGroupIndex, DataGridTraceMessages.GroupFound, DataGridTraceArgs.Index( groupIndex ), DataGridTraceArgs.Group( group ) ); - return groupIndex; - } - - this.TraceEvent( TraceEventType.Error, DataGridTraceEventId.CustomItemContainerGenerator_GetGroupIndex, DataGridTraceMessages.DetailNodeNotFound, DataGridTraceArgs.Group( group ) ); - return -1; - } - } - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_GetGroupIndex, DataGridTraceMessages.GroupNotFound, DataGridTraceArgs.Group( group ) ); - return -1; - } - } - - public Group GetGroupFromItem( object item ) - { - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_GetGroupFromItem, DataGridTraceArgs.Item( item ) ) ) - { - this.EnsureNodeTreeCreated(); - - if( m_startNode == null ) - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_GetGroupFromItem, DataGridTraceMessages.EmptyTree, DataGridTraceArgs.Item( item ) ); - return null; - } - - GeneratorNode node; - - var index = this.FindFirstGeneratedIndexForLocalItem( item ); - if( index >= 0 ) - { - node = m_genPosToNode[ index ]; - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_GetGroupFromItem, DataGridTraceMessages.NodeFound, DataGridTraceArgs.Node( node ), DataGridTraceArgs.GeneratorIndex( index ), DataGridTraceArgs.Item( item ) ); - } - else - { - var nodeHelper = new GeneratorNodeHelper( m_startNode, 0, 0 ); - if( !nodeHelper.Contains( item ) ) //NOTE: this will only return items directly contained in this generator (not from details ) - throw DataGridException.Create( "An attempt was made to retrieve the group of an item that does not belong to the generator.", m_dataGridControl ); - - //if the nodeHelper was able to locate the content, use the nodeHelper's CurrentNode as the node for the item. - node = nodeHelper.CurrentNode; - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_GetGroupFromItem, DataGridTraceMessages.NodeFound, DataGridTraceArgs.Node( node ), DataGridTraceArgs.Item( item ) ); - } - - if( node != null ) - { - var parentGroup = node.Parent as GroupGeneratorNode; - if( parentGroup != null ) - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_GetGroupFromItem, DataGridTraceMessages.GroupFound, DataGridTraceArgs.Group( parentGroup.UIGroup ), DataGridTraceArgs.Node( parentGroup ), DataGridTraceArgs.Item( item ) ); - return parentGroup.UIGroup; - } - } - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_GetGroupFromItem, DataGridTraceMessages.GroupNotFound, DataGridTraceArgs.Item( item ) ); - return null; - } - } - - public Group GetGroupFromCollectionViewGroup( CollectionViewGroup collectionViewGroup ) - { - this.EnsureNodeTreeCreated(); - - return this.GetGroupFromCollectionViewGroupCore( collectionViewGroup ); - } - - private Group GetGroupFromCollectionViewGroupCore( CollectionViewGroup collectionViewGroup ) - { - GroupGeneratorNode node; - if( m_groupNodeMappingCache.TryGetValue( collectionViewGroup, out node ) ) - return node.UIGroup; - - return null; - } - - public CollectionViewGroup GetParentGroupFromItem( object item, bool recurseDetails ) - { - if( item == null ) - throw DataGridException.Create( "item", m_dataGridControl ); - - CollectionViewGroup collectionViewGroup; - if( !this.TryGetParentGroupFromItem( item, recurseDetails, out collectionViewGroup ) ) - throw DataGridException.Create( "An attempt was made to retrieve the parent group of an item that does not belong to the generator.", m_dataGridControl ); - - return collectionViewGroup; - } - - public bool TryGetParentGroupFromItem( object item, bool recurseDetails, out CollectionViewGroup collectionViewGroup ) - { - collectionViewGroup = null; - - if( item == null ) - return false; - - this.EnsureNodeTreeCreated(); - - if( m_startNode == null ) - throw DataGridException.Create( "Start node is null for the CollectionViewGroup.", m_dataGridControl ); - - if( this.TryGetParentGroupFromItemHelper( item, out collectionViewGroup ) ) - return true; - - if( recurseDetails ) - { - //the item was not found in this generator's content... check all the detail generators - foreach( var generator in this.GetDetailGenerators() ) - { - if( generator.TryGetParentGroupFromItem( item, recurseDetails, out collectionViewGroup ) ) - return true; - } - } - - return false; - } - - private bool TryGetParentGroupFromItemHelper( object item, out CollectionViewGroup collectionViewGroup ) - { - //This helper method is used to simplify previous code flow of the TryGetParentGroupFromItem method. - collectionViewGroup = null; - - //----------------------------------------------- - //1 - First check is to see of the item is a CVG. - //----------------------------------------------- - var groupItem = item as CollectionViewGroup; - if( groupItem != null ) - { - var group = this.GetGroupFromCollectionViewGroup( groupItem ); - if( group != null ) - { - var groupGeneratorNode = group.GeneratorNode; - if( groupGeneratorNode.Parent == null ) - return true; - - //if the nodeHelper was able to locate the content, use the nodeHelper's CurrentNode as the node for the item. - collectionViewGroup = ( ( GroupGeneratorNode )groupGeneratorNode.Parent ).CollectionViewGroup; - return true; - } - - //item is a CVG, but is not present in the generator! - return false; - } - - //----------------------------------------------- - //2 - Second check is to see if the item is already in the generated list - //----------------------------------------------- - - //item might be in the "generated" list... much quicker to find-out if it is! - //note: if the item belongs to a detail, then it will be excluded from the "fast" algo. - var itemGenPosIndex = this.FindFirstGeneratedIndexForLocalItem( item ); - if( itemGenPosIndex != -1 ) - { - //item was generated and was not from a DetailGeneratorNode - if( m_genPosToNode[ itemGenPosIndex ].Parent == null ) - return true; - - collectionViewGroup = ( ( GroupGeneratorNode )m_genPosToNode[ itemGenPosIndex ].Parent ).CollectionViewGroup; - return true; - } - - //----------------------------------------------- - //3 - Third check is to check of the item is a GroupHeaderFooterItem - //----------------------------------------------- - if( item.GetType() == typeof( GroupHeaderFooterItem ) ) - { - var groupHeaderFooterItem = ( GroupHeaderFooterItem )item; - var parentGroup = groupHeaderFooterItem.Group; - - if( this.GetGroupFromCollectionViewGroup( parentGroup ) != null ) - { - //since the goal is the find the parentGroup from the item passed (which is a GroupHeader or GroupFooter), then the Group - //is what I am looking for. - collectionViewGroup = parentGroup; - - return true; - } - - //Item was a GroupHeaderFooterItem but was not part of the genreator! - return false; - } - - //----------------------------------------------- - //4 - Final Check - //----------------------------------------------- - - //if the item was not generated, then try to find the item as is within the generator's content - var finalNodeHelper = new GeneratorNodeHelper( m_startNode, 0, 0 ); - if( finalNodeHelper.AbsoluteFindItem( item ) ) - { - //item was not generated but was part of this generator - if( finalNodeHelper.CurrentNode.Parent == null ) - return true; - - collectionViewGroup = ( ( GroupGeneratorNode )finalNodeHelper.CurrentNode.Parent ).CollectionViewGroup; - return true; - } - - return false; - } - - internal bool ExpandGroup( CollectionViewGroup group ) - { - return this.ExpandGroup( group, false ); - } - - internal bool ExpandGroup( CollectionViewGroup group, bool recurseDetails ) - { - if( this.Status == GeneratorStatus.GeneratingContainers ) - throw DataGridException.Create( "An attempt was made to expand a group while the generator is busy generating items.", m_dataGridControl ); - - if( group == null ) - throw DataGridException.Create( "group", m_dataGridControl ); - - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_ExpandGroup, DataGridTraceArgs.Group( group ) ) ) - { - this.EnsureNodeTreeCreated(); - - if( m_firstItem == null ) - throw DataGridException.Create( "No GeneratorNode found for the group.", m_dataGridControl ); - - var uiGroup = this.GetGroupFromCollectionViewGroup( group ); - if( uiGroup != null ) - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_ExpandGroup, DataGridTraceMessages.GroupFound, DataGridTraceArgs.Group( uiGroup ), DataGridTraceArgs.Node( uiGroup.GeneratorNode ), DataGridTraceArgs.Value( uiGroup.GeneratorNode.IsExpanded ) ); - - uiGroup.GeneratorNode.IsExpanded = true; - return true; - } - - if( recurseDetails ) - { - foreach( var generator in this.GetDetailGenerators() ) - { - // If the item is not found in the detail generator, it will return false; - if( generator.ExpandGroup( group, recurseDetails ) ) - return true; - } - } - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_ExpandGroup, DataGridTraceMessages.GroupNotFound, DataGridTraceArgs.Group( group ) ); - return false; - } - } - - internal bool CollapseGroup( CollectionViewGroup group ) - { - return this.CollapseGroup( group, false ); - } - - internal bool CollapseGroup( CollectionViewGroup group, bool recurseDetails ) - { - if( this.Status == GeneratorStatus.GeneratingContainers ) - throw DataGridException.Create( "An attempt was made to collapse a group while the generator is busy generating items.", m_dataGridControl ); - - if( group == null ) - throw DataGridException.Create( "group", m_dataGridControl ); - - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_CollapseGroup, DataGridTraceArgs.Group( group ) ) ) - { - this.EnsureNodeTreeCreated(); - - if( m_firstItem == null ) - throw DataGridException.Create( "No GeneratorNode found for the group.", m_dataGridControl ); - - var uiGroup = this.GetGroupFromCollectionViewGroup( group ); - if( uiGroup != null ) - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_CollapseGroup, DataGridTraceMessages.GroupFound, DataGridTraceArgs.Group( uiGroup ), DataGridTraceArgs.Node( uiGroup.GeneratorNode ), DataGridTraceArgs.Value( uiGroup.GeneratorNode.IsExpanded ) ); - - uiGroup.GeneratorNode.IsExpanded = false; - return true; - } - - if( recurseDetails ) - { - foreach( var generator in this.GetDetailGenerators() ) - { - // If the item is not found in the detail generator, it will return false; - if( generator.CollapseGroup( group, recurseDetails ) ) - return true; - } - } - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_CollapseGroup, DataGridTraceMessages.GroupNotFound, DataGridTraceArgs.Group( group ) ); - return false; - } - } - - internal bool ToggleGroupExpansion( CollectionViewGroup group ) - { - return this.ToggleGroupExpansion( group, false ); - } - - internal bool ToggleGroupExpansion( CollectionViewGroup group, bool recurseDetails ) - { - if( this.Status == GeneratorStatus.GeneratingContainers ) - throw DataGridException.Create( "An attempt was made to toggle a group's expansion while the generator is busy generating items.", m_dataGridControl ); - - if( group == null ) - throw DataGridException.Create( "group", m_dataGridControl ); - - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_ToggleGroupExpansion, DataGridTraceArgs.Group( group ) ) ) - { - this.EnsureNodeTreeCreated(); - - if( m_firstItem == null ) - throw DataGridException.Create( "No GeneratorNode found for the group.", m_dataGridControl ); - - var uiGroup = this.GetGroupFromCollectionViewGroup( group ); - if( uiGroup != null ) - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_ToggleGroupExpansion, DataGridTraceMessages.GroupFound, DataGridTraceArgs.Group( uiGroup ), DataGridTraceArgs.Node( uiGroup.GeneratorNode ), DataGridTraceArgs.Value( uiGroup.GeneratorNode.IsExpanded ) ); - - var groupNode = uiGroup.GeneratorNode; - groupNode.IsExpanded = !groupNode.IsExpanded; - return true; - } - - if( recurseDetails ) - { - foreach( var generator in this.GetDetailGenerators() ) - { - // If the item is not found in the detail generator, it will return false; - if( generator.ToggleGroupExpansion( group, recurseDetails ) ) - return true; - } - } - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_ToggleGroupExpansion, DataGridTraceMessages.GroupNotFound, DataGridTraceArgs.Group( group ) ); - return false; - } - } - - internal bool? IsGroupExpanded( CollectionViewGroup group ) - { - return this.IsGroupExpanded( group, false ); - } - - internal bool? IsGroupExpanded( CollectionViewGroup group, bool recurseDetails ) - { - if( group == null ) - throw DataGridException.Create( "group", m_dataGridControl ); - - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_IsGroupExpanded, DataGridTraceArgs.Group( group ) ) ) - { - this.EnsureNodeTreeCreated(); - - if( m_firstItem == null ) - throw DataGridException.Create( "No GeneratorNode found for the group.", m_dataGridControl ); - - var uiGroup = this.GetGroupFromCollectionViewGroup( group ); - if( uiGroup != null ) - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_IsGroupExpanded, DataGridTraceMessages.GroupFound, DataGridTraceArgs.Group( uiGroup ), DataGridTraceArgs.Node( uiGroup.GeneratorNode ), DataGridTraceArgs.Value( uiGroup.GeneratorNode.IsExpanded ) ); - return uiGroup.GeneratorNode.IsExpanded; - } - - if( recurseDetails ) - { - //the group was not found in this generator, check in all the child generators for the group. - foreach( var generator in this.GetDetailGenerators() ) - { - var result = generator.IsGroupExpanded( group, recurseDetails ); - if( result.HasValue ) - return result.Value; - } - } - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_IsGroupExpanded, DataGridTraceMessages.GroupNotFound, DataGridTraceArgs.Group( group ) ); - return null; - } - } - - internal void ExpandDetails( object dataItem ) - { - - } - - internal void CollapseDetails( object dataItem ) - { - - } - - internal void ToggleDetails( object dataItem ) - { - } - - internal bool AreDetailsExpanded( object dataItem ) - { - return false; - } - - public void RemoveAllAndNotify() - { - if( m_startNode == null ) - return; - - this.RemoveGeneratedItems( int.MinValue, int.MaxValue, null ); - this.SendResetEvent(); - this.ClearRecyclingPools(); - } - - internal int FindIndexForItem( object item, DataGridContext dataGridContext ) - { - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_FindIndexForItem, DataGridTraceArgs.Item( item ) ) ) - { - this.EnsureNodeTreeCreated(); - - // If the seeked DataGridContext is this generator's context, the item should be here. - // When the seeked DataGridContext is null, search for the first item match no matter the generator's context. - if( ( m_dataGridContext == dataGridContext ) || ( dataGridContext == null ) ) - { - var itemIndex = this.IndexFromItem( item ); - if( itemIndex >= 0 ) - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_FindIndexForItem, DataGridTraceMessages.ItemFound, DataGridTraceArgs.Item( item ), DataGridTraceArgs.Index( itemIndex ) ); - return itemIndex; - } - - if( dataGridContext != null ) - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_FindIndexForItem, DataGridTraceMessages.ItemNotFound, DataGridTraceArgs.Item( item ) ); - return -1; - } - } - - foreach( var masterToDetails in m_masterToDetails ) - { - var detailsTotalCount = 0; - - foreach( var detailNode in masterToDetails.Value ) - { - var itemIndex = detailNode.DetailGenerator.FindIndexForItem( item, dataGridContext ); - if( itemIndex >= 0 ) - { - var masterIndex = this.IndexFromItem( masterToDetails.Key ); - if( masterIndex >= 0 ) - { - var result = masterIndex + 1 + detailsTotalCount + itemIndex; - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_FindIndexForItem, DataGridTraceMessages.ItemFound, DataGridTraceArgs.Item( item ), DataGridTraceArgs.Index( result ) ); - return result; - } - - this.TraceEvent( TraceEventType.Error, DataGridTraceEventId.CustomItemContainerGenerator_FindIndexForItem, DataGridTraceMessages.ItemNotFound, DataGridTraceArgs.Item( item ) ); - return -1; - } - - detailsTotalCount += detailNode.ItemCount; - } - } - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_FindIndexForItem, DataGridTraceMessages.ItemNotFound, DataGridTraceArgs.Item( item ) ); - return -1; - } - } - - public DependencyObject GetRealizedContainerForIndex( int index ) - { - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_GetRealizedContainerForIndex, DataGridTraceArgs.Index( index ) ) ) - { - this.EnsureNodeTreeCreated(); - - if( m_startNode == null ) - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_GetRealizedContainerForIndex, DataGridTraceMessages.EmptyTree, DataGridTraceArgs.Index( index ) ); - return null; - } - - var nodeHelper = new GeneratorNodeHelper( m_startNode, 0, 0 ); - if( !nodeHelper.FindNodeForIndex( index ) ) - throw DataGridException.Create( "The specified index does not correspond to an item in the generator.", m_dataGridControl, "index" ); - - var indexIndex = m_genPosToIndex.IndexOf( index ); - if( indexIndex >= 0 ) - { - var container = m_genPosToContainer[ indexIndex ]; - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_GetRealizedContainerForIndex, DataGridTraceMessages.ContainerFound, DataGridTraceArgs.Container( container ), DataGridTraceArgs.GeneratorIndex( indexIndex ), DataGridTraceArgs.Index( index ) ); - return container; - } - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_GetRealizedContainerForIndex, DataGridTraceMessages.ContainerNotFound, DataGridTraceArgs.Index( index ) ); - return null; - } - } - - public int GetRealizedIndexForContainer( DependencyObject container ) - { - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_GetRealizedIndexForContainer, DataGridTraceArgs.Container( container ) ) ) - { - this.EnsureNodeTreeCreated(); - - var index = m_genPosToContainer.IndexOf( container ); - if( index >= 0 ) - { - var itemIndex = m_genPosToIndex[ index ]; - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_GetRealizedIndexForContainer, DataGridTraceMessages.ContainerFound, DataGridTraceArgs.Index( itemIndex ), DataGridTraceArgs.GeneratorIndex( index ) ); - return itemIndex; - } - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_GetRealizedIndexForContainer, DataGridTraceMessages.ContainerNotFound, DataGridTraceArgs.Container( container ) ); - return -1; - } - } - - internal List GetMasterIndexesWithExpandedDetails() - { - var masterIndexes = new List(); - - foreach( var dataItem in m_masterToDetails.Keys ) - { - var itemIndex = m_collectionView.IndexOf( dataItem ); - Debug.Assert( itemIndex >= 0 ); - - masterIndexes.Add( itemIndex ); - } - - masterIndexes.Sort(); - - return masterIndexes; - } - - internal IEnumerable GetChildContextsForMasterItem( object item ) - { - if( item == null ) - yield break; - - List detailNodes; - if( m_masterToDetails.TryGetValue( item, out detailNodes ) ) - { - foreach( var detailNode in detailNodes ) - { - yield return detailNode.DetailContext; - } - } - } - - public DataGridContext GetChildContext( object parentItem, string relationName ) - { - if( parentItem == null ) - throw DataGridException.Create( "parentItem", m_dataGridControl ); - - this.EnsureNodeTreeCreated(); - - //Note: This function does not validate if the parentItem is part of the generator or not, effectivelly, there is - // no need to validate of the parentItem is part of the Generator or not, the only calling function is already doing the - // validation (DataGridContext.GetChildContext() ). - List details; - if( m_masterToDetails.TryGetValue( parentItem, out details ) ) - { - foreach( DetailGeneratorNode detailNode in details ) - { - //Note: DetailContext.SourceDetailConfiguration will always be non-null, since we are looking for child contexts ( only the root master context can have a null - //SourceDetailConfiguration. - if( detailNode.DetailContext.SourceDetailConfiguration.RelationName == relationName ) - return detailNode.DetailContext; - } - } - - return null; - } - - public IEnumerable GetChildContexts() - { - this.EnsureNodeTreeCreated(); - - return this.GetChildContextsCore(); - } - - internal IEnumerable GetChildContextsCore() - { - return this.GetDetailContexts(); - } - - public bool Contains( object item ) - { - this.EnsureNodeTreeCreated(); - - var nodeHelper = new GeneratorNodeHelper( m_startNode, 0, 0 ); - return nodeHelper.Contains( item ); - } - - #region Sticky Headers Methods - - public List GenerateStickyHeaders( - DependencyObject container, - bool areHeadersSticky, - bool areGroupHeadersSticky, - bool areParentRowsSticky ) - { - var generatedStickyContainers = new List(); - - GeneratorNode containerNode; - int containerRealizedIndex; - object containerDataItem; - - if( this.FindGeneratorListMappingInformationForContainer( container, - out containerNode, - out containerRealizedIndex, - out containerDataItem ) ) - { - var nodeHelper = default( GeneratorNodeHelper ); - var detailNode = containerNode as DetailGeneratorNode; - - if( detailNode != null ) - { - // Get the parent item of the detail node to be able - // to readjust the containerRealizedIndex to the one - // of the master item container since the detail node - // will be processed by the DetailGenerator. - containerDataItem = detailNode.DetailContext.ParentItem; - - // OPTIMIZATION: We will look in the m_genPos* first to avoid using - // FindItem for performance reason. - var index = m_genPosToItem.IndexOf( containerDataItem ); - if( index >= 0 ) - { - var sourceDataIndex = ( int )m_genPosToContainer[ index ].GetValue( DataGridVirtualizingPanel.ItemIndexProperty ); - containerNode = m_genPosToNode[ index ]; - containerRealizedIndex = m_genPosToIndex[ index ]; - - var collectionNode = containerNode as CollectionGeneratorNode; - if( collectionNode != null ) - { - nodeHelper = new GeneratorNodeHelper( containerNode, containerRealizedIndex - collectionNode.IndexOf( containerDataItem ), sourceDataIndex ); - } - } - - if( nodeHelper == null ) - { - // We want to find the ItemsGeneratorNode for the DetailNode. - nodeHelper = new GeneratorNodeHelper( m_startNode, 0, 0 ); - containerRealizedIndex = nodeHelper.FindItem( containerDataItem ); - containerNode = nodeHelper.CurrentNode; - } - - if( containerRealizedIndex == -1 ) - throw DataGridException.Create( "The index of a sticky header container is out of bound.", m_dataGridControl ); - - generatedStickyContainers.AddRange( - this.GenerateStickyHeadersForDetail( container, - detailNode, - areHeadersSticky, - areGroupHeadersSticky, - areParentRowsSticky ) ); - } - else - { - var collectionNode = containerNode as CollectionGeneratorNode; - if( collectionNode != null ) - { - // We don't need to have an up to date sourceDataIndex so we pass 0 - nodeHelper = new GeneratorNodeHelper( containerNode, containerRealizedIndex - collectionNode.IndexOf( containerDataItem ), 0 ); - } - - if( nodeHelper == null ) - { - nodeHelper = new GeneratorNodeHelper( containerNode, 0, 0 ); - nodeHelper.ReverseCalculateIndex(); - } - } - - if( ( areParentRowsSticky ) - && ( containerDataItem != null ) - && ( this.AreDetailsExpanded( containerDataItem ) ) ) - { - generatedStickyContainers.Add( this.GenerateStickyParentRow( containerRealizedIndex ) ); - } - - // We want to find the HeaderFooterGeneratorNode for the container - // node. This is to find the headers for the container. - nodeHelper.MoveToFirst(); - var headersNode = nodeHelper.CurrentNode as HeadersFootersGeneratorNode; - - // There is no headers to generate if the item count of the node is 0. - if( headersNode.ItemCount > 0 ) - { - if( ( ( areHeadersSticky ) && ( headersNode.Parent == null ) ) - || ( ( areGroupHeadersSticky ) && ( headersNode.Parent is GroupGeneratorNode ) ) ) - { - generatedStickyContainers.AddRange( - this.GenerateStickyHeadersForNode( headersNode, - nodeHelper.Index, - containerRealizedIndex, - ( headersNode == containerNode ) ) ); - } - } - - // We must also find the top most headers for our level of detail and, if they need to be sticky, - // we will generate the containers and add them the to list. - var topMostHeaderNode = this.GetTopMostHeaderNode( nodeHelper ); - if( ( areHeadersSticky ) - && ( topMostHeaderNode != null ) - && ( topMostHeaderNode != headersNode ) - && ( topMostHeaderNode.ItemCount > 0 ) ) - { - generatedStickyContainers.AddRange( - this.GenerateStickyHeadersForNode( topMostHeaderNode, nodeHelper.Index ) ); - } - } - - return generatedStickyContainers; - } - - private HeadersFootersGeneratorNode GetTopMostHeaderNode( GeneratorNodeHelper nodeHelper ) - { - var parentNode = default( HeadersFootersGeneratorNode ); - - if( nodeHelper.MoveToParent() - && nodeHelper.MoveToFirst() ) - { - if( ( nodeHelper.CurrentNode is HeadersFootersGeneratorNode ) - && ( nodeHelper.CurrentNode.Parent == null ) ) - { - parentNode = nodeHelper.CurrentNode as HeadersFootersGeneratorNode; - } - else - { - parentNode = this.GetTopMostHeaderNode( nodeHelper ); - } - } - - return parentNode; - } - - private List GenerateStickyHeadersForDetail( - DependencyObject container, - DetailGeneratorNode detailNode, - bool areHeadersSticky, - bool areGroupHeadersSticky, - bool areParentRowsSticky ) - { - var generatedStickyContainers = detailNode.DetailGenerator.GenerateStickyHeaders( container, areHeadersSticky, areGroupHeadersSticky, areParentRowsSticky ); - var detailIndex = this.FindGlobalIndexForDetailNode( detailNode ); - var count = generatedStickyContainers.Count; - - for( int i = 0; i < count; i++ ) - { - var stickyContainer = generatedStickyContainers[ i ]; - var detailItemIndex = stickyContainer.Index + detailIndex; - - //if the container was just realized, ensure to add it to the lists maintaining the generated items. - if( stickyContainer.IsNewlyRealized ) - { - var insertionIndex = this.FindInsertionPoint( detailItemIndex ); - var item = CustomItemContainerGenerator.GetDataItemProperty( stickyContainer.StickyContainer ).Data; - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_GenerateStickyHeadersForDetail, DataGridTraceMessages.ContainerAdded, DataGridTraceArgs.Container( stickyContainer.StickyContainer ), DataGridTraceArgs.Node( detailNode ), DataGridTraceArgs.Item( item ), DataGridTraceArgs.GeneratorIndex( insertionIndex ), DataGridTraceArgs.Index( detailItemIndex ) ); - - m_genPosToIndex.Insert( insertionIndex, detailItemIndex ); - m_genPosToItem.Insert( insertionIndex, item ); - m_genPosToContainer.Insert( insertionIndex, stickyContainer.StickyContainer ); - m_genPosToNode.Insert( insertionIndex, detailNode ); - } - - generatedStickyContainers[ i ] = new StickyContainerGenerated( stickyContainer.StickyContainer, detailItemIndex, stickyContainer.IsNewlyRealized ); - } - - return generatedStickyContainers; - } - - private StickyContainerGenerated GenerateStickyParentRow( int itemNodeIndex ) - { - var generator = ( ICustomItemContainerGenerator )this; - var position = generator.GeneratorPositionFromIndex( itemNodeIndex ); - - using( generator.StartAt( position, GeneratorDirection.Forward, true ) ) - { - bool isNewlyRealized; - var container = generator.GenerateNext( out isNewlyRealized ); - - return new StickyContainerGenerated( container, itemNodeIndex, isNewlyRealized ); - } - } - - private List GenerateStickyHeadersForNode( - HeadersFootersGeneratorNode headerNode, - int headerNodeIndex ) - { - return this.GenerateStickyHeadersForNode( headerNode, headerNodeIndex, -1, false ); - } - - private List GenerateStickyHeadersForNode( - HeadersFootersGeneratorNode headerNode, - int headerNodeIndex, - int realizedIndex, - bool isRealizedIndexPartOfHeaderNode ) - { - var generatedStickyContainers = new List(); - - // The container is already part of the header. - var generator = ( ICustomItemContainerGenerator )this; - var position = generator.GeneratorPositionFromIndex( headerNodeIndex ); - - // In that case, the potential sticky containers are the requested one and up. - using( generator.StartAt( position, GeneratorDirection.Forward, true ) ) - { - for( int i = 0; i < headerNode.ItemCount; i++ ) - { - // If the realized index represent the index of one of the HeaderNode - // item, do not process - if( ( isRealizedIndexPartOfHeaderNode ) - && ( headerNodeIndex + i > realizedIndex ) ) - break; - - var item = headerNode.GetAt( i ); - var groupHeaderFooterItem = default( GroupHeaderFooterItem? ); - - if( item is GroupHeaderFooterItem ) - { - groupHeaderFooterItem = ( GroupHeaderFooterItem )item; - } - - if( ( groupHeaderFooterItem != null ) - && ( !groupHeaderFooterItem.Value.Group.IsBottomLevel || ( this.IsGroupExpanded( groupHeaderFooterItem.Value.Group ) != true ) ) ) - { - this.Skip(); - continue; - } - - bool isNewlyRealized; - var stickyContainer = generator.GenerateNext( out isNewlyRealized ); - - generatedStickyContainers.Add( new StickyContainerGenerated( stickyContainer, headerNodeIndex + i, isNewlyRealized ) ); - } - } - - return generatedStickyContainers; - } - - private bool FindGeneratorListMappingInformationForContainer( - DependencyObject container, - out GeneratorNode containerNode, - out int containerRealizedIndex, - out object containerDataItem ) - { - var index = m_genPosToContainer.IndexOf( container ); - if( index < 0 ) - { - containerNode = null; - containerRealizedIndex = -1; - containerDataItem = null; - - return false; - } - else - { - containerNode = m_genPosToNode[ index ]; - containerRealizedIndex = m_genPosToIndex[ index ]; - containerDataItem = m_genPosToItem[ index ]; - - return true; - } - } - - public int GetLastHoldingContainerIndexForStickyHeader( DependencyObject stickyHeader ) - { - return this.GetLastHoldingContainerIndexForStickyHeaderRecurse( stickyHeader, this.ItemCount ); - } - - private int GetLastHoldingContainerIndexForStickyHeaderRecurse( DependencyObject stickyHeader, int parentCount ) - { - var lastContainerIndex = 0; - - int containerRealizedIndex; - GeneratorNode containerNode; - object containerDataItem; - - if( this.FindGeneratorListMappingInformationForContainer( stickyHeader, out containerNode, out containerRealizedIndex, out containerDataItem ) ) - { - var detailNode = containerNode as DetailGeneratorNode; - if( detailNode != null ) - { - lastContainerIndex = - detailNode.DetailGenerator.GetLastHoldingContainerIndexForStickyHeaderRecurse( stickyHeader, detailNode.ItemCount ) + - this.FindGlobalIndexForDetailNode( detailNode ); - } - else - { - var itemsNode = containerNode as ItemsGeneratorNode; - if( itemsNode != null ) - { - // This means that the sticky container is a MasterRow for a detail. - if( this.AreDetailsExpanded( containerDataItem ) ) - { - var detailNodesForDataItem = m_masterToDetails[ containerDataItem ]; - - foreach( DetailGeneratorNode detailNodeForDataItem in detailNodesForDataItem ) - { - lastContainerIndex += - detailNodeForDataItem.ItemCount + - this.FindGlobalIndexForDetailNode( detailNodeForDataItem ) - - 1; - } - } - } - else - { - var nodeHelper = default( GeneratorNodeHelper ); - - // This means that the sticky container is a Header. - var collectionNode = containerNode as CollectionGeneratorNode; - if( collectionNode != null ) - { - // We don't need to have an up to date sourceDataIndex so we pass 0 - nodeHelper = new GeneratorNodeHelper( containerNode, containerRealizedIndex - collectionNode.IndexOf( containerDataItem ), 0 ); - } - - if( nodeHelper == null ) - { - nodeHelper = new GeneratorNodeHelper( containerNode, 0, 0 ); - nodeHelper.ReverseCalculateIndex(); - } - - lastContainerIndex = nodeHelper.Index; - - if( containerNode.Parent != null ) - { - // This means that it is a GroupHeader - lastContainerIndex += containerNode.Parent.ItemCount - 1; - } - else - { - lastContainerIndex += Math.Max( 0, parentCount - 1 ); - } - } - } - } - - return lastContainerIndex; - } - - public int GetFirstHoldingContainerIndexForStickyFooter( DependencyObject stickyFooter ) - { - var firstContainerIndex = 0; - - int containerRealizedIndex; - GeneratorNode containerNode; - object containerDataItem; - - if( this.FindGeneratorListMappingInformationForContainer( stickyFooter, out containerNode, out containerRealizedIndex, out containerDataItem ) ) - { - var detailNode = containerNode as DetailGeneratorNode; - - if( detailNode != null ) - { - int detailIndex = this.FindGlobalIndexForDetailNode( detailNode ); - firstContainerIndex = detailNode.DetailGenerator.GetFirstHoldingContainerIndexForStickyFooter( stickyFooter ) + detailIndex; - } - else - { - var nodeHelper = default( GeneratorNodeHelper ); - var collectionNode = containerNode as CollectionGeneratorNode; - - if( collectionNode != null ) - { - // We don't need to have an up to date sourceDataIndex so we pass 0 - nodeHelper = new GeneratorNodeHelper( containerNode, containerRealizedIndex - collectionNode.IndexOf( containerDataItem ), 0 ); - } - - if( nodeHelper == null ) - { - nodeHelper = new GeneratorNodeHelper( containerNode, 0, 0 ); - nodeHelper.ReverseCalculateIndex(); - } - - nodeHelper.MoveToFirst(); - nodeHelper.MoveToNext(); // We exclude headers from this calculation. - firstContainerIndex = nodeHelper.Index; - } - } - - return firstContainerIndex; - } - - #endregion Sticky Headers Methods - - #region Sticky Footers Methods - - public List GenerateStickyFooters( - DependencyObject container, - bool areFootersSticky, - bool areGroupFootersSticky ) - { - var generatedStickyContainers = new List(); - - GeneratorNode containerNode; - int containerRealizedIndex; - object containerDataItem; - - - if( this.FindGeneratorListMappingInformationForContainer( container, - out containerNode, - out containerRealizedIndex, - out containerDataItem ) ) - { - var nodeHelper = default( GeneratorNodeHelper ); - var detailNode = containerNode as DetailGeneratorNode; - - if( detailNode != null ) - { - // Get the parent item of the detail node to be able - // to readjust the containerRealizedIndex to the one - // of the master item container since the detail node - // will be processed by the DetailGenerator. - containerDataItem = detailNode.DetailContext.ParentItem; - - // OPTIMIZATION: We will look in the m_genPos* first to avoid using - // FindItem for performance reason. - int index = m_genPosToItem.IndexOf( containerDataItem ); - if( index >= 0 ) - { - var sourceDataIndex = ( int )m_genPosToContainer[ index ].GetValue( DataGridVirtualizingPanel.ItemIndexProperty ); - containerNode = m_genPosToNode[ index ]; - containerRealizedIndex = m_genPosToIndex[ index ]; - - var collectionNode = containerNode as CollectionGeneratorNode; - if( collectionNode != null ) - { - nodeHelper = new GeneratorNodeHelper( containerNode, containerRealizedIndex - collectionNode.IndexOf( containerDataItem ), sourceDataIndex ); - } - } - - if( nodeHelper == null ) - { - // We want to find the ItemsGeneratorNode for the DetailNode. - nodeHelper = new GeneratorNodeHelper( m_startNode, 0, 0 ); - containerRealizedIndex = nodeHelper.FindItem( containerDataItem ); - containerNode = nodeHelper.CurrentNode; - } - - if( containerRealizedIndex == -1 ) - throw DataGridException.Create( "The index of a sticky footer container is out of bound.", m_dataGridControl ); - - generatedStickyContainers.AddRange( - this.GenerateStickyFootersForDetail( container, detailNode, areFootersSticky, areGroupFootersSticky ) ); - } - else - { - var collectionNode = containerNode as CollectionGeneratorNode; - if( collectionNode != null ) - { - // We don't need to have an up to date sourceDataIndex so we pass 0 - nodeHelper = new GeneratorNodeHelper( containerNode, containerRealizedIndex - collectionNode.IndexOf( containerDataItem ), 0 ); - } - - if( nodeHelper == null ) - { - nodeHelper = new GeneratorNodeHelper( containerNode, 0, 0 ); - nodeHelper.ReverseCalculateIndex(); - } - } - - bool isHeaderNode = - ( ( nodeHelper.CurrentNode is HeadersFootersGeneratorNode ) && - ( nodeHelper.CurrentNode.Previous == null ) ); - - // We want to find the HeaderFooterGeneratorNode for the container - // node. This is to find the footers for the container. - nodeHelper.MoveToEnd(); - var footersNode = nodeHelper.CurrentNode as HeadersFootersGeneratorNode; - - if( !isHeaderNode ) - { - // There is no footers to generate if the item count of the node is 0. - if( footersNode.ItemCount > 0 ) - { - if( ( ( areFootersSticky ) && ( footersNode.Parent == null ) ) - || ( ( areGroupFootersSticky ) && ( footersNode.Parent is GroupGeneratorNode ) ) ) - { - generatedStickyContainers.AddRange( - this.GenerateStickyFootersForNode( footersNode, - nodeHelper.Index, - containerRealizedIndex, - ( footersNode == containerNode ) ) ); - } - } - } - - // We must also find the bottom most footers for our level of detail and, if they need to be sticky, - // we will generate the containers and add them the to list. - var bottomFootersNode = this.GetDetailFootersNode( nodeHelper ); - - if( ( areFootersSticky ) - && ( bottomFootersNode != null ) - && ( bottomFootersNode != footersNode ) - && ( bottomFootersNode.ItemCount > 0 ) ) - { - generatedStickyContainers.AddRange( - this.GenerateStickyFootersForNode( bottomFootersNode, nodeHelper.Index ) ); - } - } - - return generatedStickyContainers; - } - - private List GenerateStickyFootersForDetail( - DependencyObject container, - DetailGeneratorNode detailNode, - bool areFootersSticky, - bool areGroupFootersSticky ) - { - var generatedStickyContainers = detailNode.DetailGenerator.GenerateStickyFooters( container, areFootersSticky, areGroupFootersSticky ); - var detailIndex = this.FindGlobalIndexForDetailNode( detailNode ); - var count = generatedStickyContainers.Count; - - for( int i = 0; i < count; i++ ) - { - var stickyContainer = generatedStickyContainers[ i ]; - var detailItemIndex = stickyContainer.Index + detailIndex; - - //if the container was just realized, ensure to add it to the lists maintaining the generated items. - if( stickyContainer.IsNewlyRealized ) - { - var insertionIndex = this.FindInsertionPoint( detailItemIndex ); - var item = CustomItemContainerGenerator.GetDataItemProperty( stickyContainer.StickyContainer ).Data; - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_GenerateStickyFootersForDetail, DataGridTraceMessages.ContainerAdded, DataGridTraceArgs.Container( stickyContainer.StickyContainer ), DataGridTraceArgs.Node( detailNode ), DataGridTraceArgs.Item( item ), DataGridTraceArgs.GeneratorIndex( insertionIndex ), DataGridTraceArgs.Index( detailItemIndex ) ); - - m_genPosToIndex.Insert( insertionIndex, detailItemIndex ); - m_genPosToItem.Insert( insertionIndex, item ); - m_genPosToContainer.Insert( insertionIndex, stickyContainer.StickyContainer ); - m_genPosToNode.Insert( insertionIndex, detailNode ); - } - - generatedStickyContainers[ i ] = new StickyContainerGenerated( stickyContainer.StickyContainer, detailItemIndex, stickyContainer.IsNewlyRealized ); - } - - return generatedStickyContainers; - } - - private List GenerateStickyFootersForNode( - HeadersFootersGeneratorNode footerNode, - int footerNodeIndex ) - { - return this.GenerateStickyFootersForNode( footerNode, footerNodeIndex, -1, false ); - } - - private List GenerateStickyFootersForNode( - HeadersFootersGeneratorNode footerNode, - int footerNodeIndex, - int realizedIndex, - bool isRealizedIndexPartOfFooterNode ) - { - var generatedStickyContainers = new List(); - - int footersNodeItemCount = footerNode.ItemCount; - - // The container is already part of the footer. - var generator = ( ICustomItemContainerGenerator )this; - var position = generator.GeneratorPositionFromIndex( footerNodeIndex + footersNodeItemCount - 1 ); - - // In that case, the potential sticky containers are the requested one and bottom. - using( generator.StartAt( position, GeneratorDirection.Backward, true ) ) - { - for( int i = footersNodeItemCount - 1; i >= 0; i-- ) - { - if( ( isRealizedIndexPartOfFooterNode ) - && ( footerNodeIndex + i < realizedIndex ) ) - { - continue; - } - - var item = footerNode.GetAt( i ); - var groupHeaderFooterItem = default( GroupHeaderFooterItem? ); - - if( item is GroupHeaderFooterItem ) - { - groupHeaderFooterItem = ( GroupHeaderFooterItem )item; - } - - if( ( groupHeaderFooterItem != null ) - && ( !groupHeaderFooterItem.Value.Group.IsBottomLevel || ( this.IsGroupExpanded( groupHeaderFooterItem.Value.Group ) != true ) ) ) - { - this.Skip(); - continue; - } - - bool isNewlyRealized; - var stickyContainer = generator.GenerateNext( out isNewlyRealized ); - - generatedStickyContainers.Add( new StickyContainerGenerated( stickyContainer, footerNodeIndex + i, isNewlyRealized ) ); - } - } - - return generatedStickyContainers; - } - - private HeadersFootersGeneratorNode GetDetailFootersNode( GeneratorNodeHelper nodeHelper ) - { - var parentNode = default( HeadersFootersGeneratorNode ); - - if( nodeHelper.MoveToParent() - && nodeHelper.MoveToEnd() ) - { - if( ( nodeHelper.CurrentNode is HeadersFootersGeneratorNode ) - && ( nodeHelper.CurrentNode.Parent == null ) ) - { - parentNode = nodeHelper.CurrentNode as HeadersFootersGeneratorNode; - } - else - { - parentNode = this.GetDetailFootersNode( nodeHelper ); - } - } - - return parentNode; - } - - #endregion Sticky Footers Methods - - #region Sticky Header Count Methods - - internal int GetStickyHeaderCountForIndex( - int index, - bool areHeadersSticky, - bool areGroupHeadersSticky, - bool areParentRowsSticky ) - { - var stickyHeadersCount = 0; - var nodeHelper = new GeneratorNodeHelper( m_startNode, 0, 0 ); - - // Unable to find the node, no sticky header for this node - if( !nodeHelper.FindNodeForIndex( index ) ) - return 0; - - var indexNode = nodeHelper.CurrentNode; - var itemsGeneratorNode = indexNode as ItemsGeneratorNode; - - // We found an ItemsGeneratorNode - if( itemsGeneratorNode != null ) - { - var detailNode = itemsGeneratorNode.GetDetailNodeForIndex( index - nodeHelper.Index ); - - // Only do a special case if the index represent - // a DetailNode - if( detailNode != null ) - { - if( ( areParentRowsSticky ) - && ( this.AreDetailsExpanded( detailNode.DetailContext.ParentItem ) ) ) - { - stickyHeadersCount++; - } - - var detailFirstRealizedIndex = this.FindGlobalIndexForDetailNode( detailNode ); - var correctedIndex = index - detailFirstRealizedIndex; - - Debug.Assert( correctedIndex >= 0, "correctedIndex >= 0 .. 1" ); - - stickyHeadersCount += - detailNode.DetailGenerator.GetStickyHeaderCountForIndex( correctedIndex, - areHeadersSticky, - areGroupHeadersSticky, - areParentRowsSticky ); - } - } - - // We want to find the HeaderFooterGeneratorNode for the container - // node. This is to find the headers for the container. - nodeHelper.MoveToFirst(); - var headersNode = nodeHelper.CurrentNode as HeadersFootersGeneratorNode; - - // There is no headers to generate if the item count of the node is 0. - if( headersNode.ItemCount > 0 ) - { - if( ( ( headersNode.Parent == null ) && ( areHeadersSticky ) ) - || ( ( headersNode.Parent is GroupGeneratorNode ) && ( areGroupHeadersSticky ) ) ) - { - // We are generating sticky headers for a container that is already - // part of the headers, we need to handle it differently. - stickyHeadersCount += this.GetStickyHeaderCountForNode( headersNode, - nodeHelper.Index, - index, - ( headersNode == indexNode ) ); - } - } - - // We must also find the top most headers for our level of detail and, if they need to be sticky, - // we will generate the containers and add them the to list. - var topMostHeaderNode = this.GetTopMostHeaderNode( nodeHelper ); - if( ( topMostHeaderNode != null ) - && ( topMostHeaderNode != headersNode ) - && ( topMostHeaderNode.ItemCount > 0 ) - && ( areHeadersSticky ) ) - { - stickyHeadersCount += this.GetStickyHeaderCountForNode( topMostHeaderNode, nodeHelper.Index ); - } - - return stickyHeadersCount; - } - - private int GetStickyHeaderCountForNode( HeadersFootersGeneratorNode headerNode, int headerNodeIndex ) - { - return this.GetStickyHeaderCountForNode( headerNode, headerNodeIndex, -1, false ); - } - - private int GetStickyHeaderCountForNode( - HeadersFootersGeneratorNode headerNode, - int headerNodeIndex, - int realizedIndex, - bool isRealizedIndexPartOfHeaderNode ) - { - var stickyHeaderCount = 0; - - for( int i = 0; i < headerNode.ItemCount; i++ ) - { - if( ( isRealizedIndexPartOfHeaderNode ) - && ( headerNodeIndex + i >= realizedIndex ) ) - break; - - var item = headerNode.GetAt( i ); - var groupHeaderFooterItem = default( GroupHeaderFooterItem? ); - - if( item is GroupHeaderFooterItem ) - { - groupHeaderFooterItem = ( GroupHeaderFooterItem )item; - } - - if( ( groupHeaderFooterItem != null ) - && ( !groupHeaderFooterItem.Value.Group.IsBottomLevel || ( this.IsGroupExpanded( groupHeaderFooterItem.Value.Group ) != true ) ) ) - continue; - - stickyHeaderCount++; - } - - return stickyHeaderCount; - } - - #endregion - - #region Sticky Footers Count Methods - - internal int GetStickyFooterCountForIndex( - int index, - bool areFootersSticky, - bool areGroupFootersSticky ) - { - var stickyFooterCount = 0; - var nodeHelper = new GeneratorNodeHelper( m_startNode, 0, 0 ); - - // Unable to find the node, no sticky header for this node - if( !nodeHelper.FindNodeForIndex( index ) ) - return 0; - - var indexNode = nodeHelper.CurrentNode; - var itemsGeneratorNode = indexNode as ItemsGeneratorNode; - - // We found an ItemsGeneratorNode - if( itemsGeneratorNode != null ) - { - var detailNode = itemsGeneratorNode.GetDetailNodeForIndex( index - nodeHelper.Index ); - if( detailNode != null ) - { - var detailFirstRealizedIndex = this.FindGlobalIndexForDetailNode( detailNode ); - var correctedIndex = index - detailFirstRealizedIndex; - - Debug.Assert( correctedIndex >= 0, "correctedIndex >= 0 .. 2" ); - - stickyFooterCount += - detailNode.DetailGenerator.GetStickyFooterCountForIndex( correctedIndex, - areFootersSticky, - areGroupFootersSticky ); - } - } - - // We want to find the HeaderFooterGeneratorNode for the container - // node. This is to find the footers for the container. - nodeHelper.MoveToEnd(); - var footersNode = nodeHelper.CurrentNode as HeadersFootersGeneratorNode; - - // There is no footers to generate if the item count of the node is 0. - if( footersNode.ItemCount > 0 ) - { - if( ( ( footersNode.Parent == null ) && ( areFootersSticky ) ) - || ( ( footersNode.Parent is GroupGeneratorNode ) && ( areGroupFootersSticky ) ) ) - { - // We are generating sticky footers for a container that is already - // part of the footers, we need to handle it differently. - stickyFooterCount += this.GetStickyFooterCountForNode( footersNode, - nodeHelper.Index, - index, - ( footersNode != indexNode ) ); - } - } - - // We must also find the bottom most footers for our level of detail and, if they need to be sticky, - // we will generate the containers and add them the to list. - var bottomFootersNode = this.GetDetailFootersNode( nodeHelper ); - - if( ( bottomFootersNode != null ) - && ( bottomFootersNode != footersNode ) - && ( bottomFootersNode.ItemCount > 0 ) - && ( areFootersSticky ) ) - { - stickyFooterCount += this.GetStickyFooterCountForNode( bottomFootersNode, nodeHelper.Index ); - } - - return stickyFooterCount; - } - - private int GetStickyFooterCountForNode( - HeadersFootersGeneratorNode footerNode, - int footerNodeIndex ) - { - return this.GetStickyFooterCountForNode( footerNode, footerNodeIndex, -1, false ); - } - - private int GetStickyFooterCountForNode( - HeadersFootersGeneratorNode footerNode, - int footerNodeIndex, - int realizedIndex, - bool isRealizedIndexPartOfHeaderNode ) - { - var stickyFooterCount = 0; - var footersNodeItemCount = footerNode.ItemCount; - - for( int i = footersNodeItemCount - 1; i >= 0; i-- ) - { - if( ( isRealizedIndexPartOfHeaderNode ) - && ( footerNodeIndex + i < realizedIndex ) ) - continue; - - var item = footerNode.GetAt( i ); - var groupHeaderFooterItem = default( GroupHeaderFooterItem? ); - - if( item is GroupHeaderFooterItem ) - { - groupHeaderFooterItem = ( GroupHeaderFooterItem )item; - } - - if( ( groupHeaderFooterItem != null ) - && ( !groupHeaderFooterItem.Value.Group.IsBottomLevel || ( this.IsGroupExpanded( groupHeaderFooterItem.Value.Group ) != true ) ) ) - continue; - - stickyFooterCount++; - } - - return stickyFooterCount; - } - - #endregion - - #region IItemContainerGenerator Members - - DependencyObject IItemContainerGenerator.GenerateNext( out bool isNewlyRealized ) - { - if( this.Status != GeneratorStatus.GeneratingContainers ) - throw DataGridException.Create( "The Generator is not active: StartAt() was not called prior calling GenerateNext() or the returned IDisposable was already disposed of.", m_dataGridControl ); - - isNewlyRealized = false; - - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_IItemContainerGenerator_GenerateNext ) ) - { - if( m_generatorNodeHelper == null ) //the m_generatorNodeHelper will be turned to null when we reach the end of the list ot items. - return null; - - var node = m_generatorNodeHelper.CurrentNode; - if( node == null ) - throw DataGridException.Create( "CurrentNode is null.", m_dataGridControl ); - - if( !( node is CollectionGeneratorNode ) ) - throw DataGridException.Create( "CurrentNode is not a CollectionGeneratorNode.", m_dataGridControl ); - - if( node is GroupGeneratorNode ) - { - this.TraceEvent( TraceEventType.Error, DataGridTraceEventId.CustomItemContainerGenerator_IItemContainerGenerator_GenerateNext, DataGridTraceMessages.UnexpectedNode, DataGridTraceArgs.Node( node ) ); - } - - var container = default( DependencyObject ); - - //if a detail generator is currently "started", then rely on it for the generation of items - if( m_generatorCurrentDetail != null ) - { - //if the detail generator was not yet started - if( m_generatorCurrentDetailDisposable == null ) - { - //start it - m_generatorCurrentDetailDisposable = ( ( IItemContainerGenerator )m_generatorCurrentDetail.DetailGenerator ).StartAt( m_generatorCurrentDetail.DetailGenerator.GeneratorPositionFromIndex( m_generatorCurrentDetailIndex ), m_generatorDirection, true ); - } - - container = ( ( IItemContainerGenerator )m_generatorCurrentDetail.DetailGenerator ).GenerateNext( out isNewlyRealized ); - node = m_generatorCurrentDetail; - //Detail Generator will have taken care of the "nasty" stuff ( ItemIndex, ... ) - } - else - { - //otherwise, it means the item to be generated is within this generator. - container = this.GenerateNextLocalContainer( out isNewlyRealized ); - - //special case for table view grid lines - Xceed.Wpf.DataGrid.Views.ViewBase.SetIsLastItem( container, this.ShouldDrawBottomLine() ); - DataGridControl.SetHasExpandedDetails( container, this.ItemHasExpandedDetails() ); - } - - //if the container was just realized, ensure to add it to the lists maintaining the generated items. - if( isNewlyRealized ) - { - var insertionIndex = this.FindInsertionPoint( m_generatorCurrentGlobalIndex ); - var item = CustomItemContainerGenerator.GetDataItemProperty( container ).Data; - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_IItemContainerGenerator_GenerateNext, DataGridTraceMessages.ContainerAdded, DataGridTraceArgs.Container( container ), DataGridTraceArgs.Node( node ), DataGridTraceArgs.Item( item ), DataGridTraceArgs.GeneratorIndex( insertionIndex ), DataGridTraceArgs.Index( m_generatorCurrentGlobalIndex ) ); - - if( insertionIndex > 0 ) - { - if( m_generatorCurrentGlobalIndex <= m_genPosToIndex[ insertionIndex - 1 ] ) - throw DataGridException.Create( "Realized item inserted at wrong location.", m_dataGridControl ); - } - else if( m_genPosToIndex.Count > 0 ) - { - if( m_generatorCurrentGlobalIndex >= m_genPosToIndex[ insertionIndex ] ) - throw DataGridException.Create( "Realized item inserted at wrong location.", m_dataGridControl ); - } - - m_genPosToIndex.Insert( insertionIndex, m_generatorCurrentGlobalIndex ); - m_genPosToItem.Insert( insertionIndex, item ); - m_genPosToContainer.Insert( insertionIndex, container ); - m_genPosToNode.Insert( insertionIndex, node ); - } - - if( m_generatorDirection == GeneratorDirection.Forward ) - { - this.MoveGeneratorForward(); - } - else - { - this.MoveGeneratorBackward(); - } - - return container; - } - } - - DependencyObject IItemContainerGenerator.GenerateNext() - { - bool flag; - - return ( ( IItemContainerGenerator )this ).GenerateNext( out flag ); - } - - public GeneratorPosition GeneratorPositionFromIndex( int itemIndex ) - { - this.EnsureNodeTreeCreated(); - - var genPosIndex = m_genPosToIndex.IndexOf( itemIndex ); - if( genPosIndex >= 0 ) - return new GeneratorPosition( genPosIndex, 0 ); - - var storedIndex = -1; - var offset = itemIndex + 1; - - //Find the closest (lower) realized index - for( int i = 0; i < m_genPosToIndex.Count; i++ ) - { - storedIndex = i; - if( m_genPosToIndex[ i ] > itemIndex ) - { - storedIndex = i - 1; - break; - } - } - - //and from there, compute the offset. - if( storedIndex >= 0 ) - { - offset = itemIndex - m_genPosToIndex[ storedIndex ]; - } - - return new GeneratorPosition( storedIndex, offset ); - } - - ItemContainerGenerator IItemContainerGenerator.GetItemContainerGeneratorForPanel( Panel panel ) - { - return ( ( IItemContainerGenerator )( ( ItemsControl )m_dataGridControl ).ItemContainerGenerator ).GetItemContainerGeneratorForPanel( panel ); - } - - public int IndexFromGeneratorPosition( GeneratorPosition position ) - { - this.EnsureNodeTreeCreated(); - - int retval = -1; - - if( ( position.Index >= 0 ) && ( position.Index < m_genPosToIndex.Count ) ) - { - //calculate based on the generator position passed. - retval = m_genPosToIndex[ position.Index ] + position.Offset; - } - else if( position.Index == -1 ) - { - // if the Index is -1, then we ask for a non realized item, at the beginning of the range, so - // first step, ensure the GeneratorPosition asked is valid (offset non-Zero) - if( position.Offset > 0 ) - { - //then return index based on the GenPos. - retval = position.Offset - 1; - } - } - //if not above 0, and not -1, then return an error (-1)... - - return retval; - } - - void IItemContainerGenerator.PrepareItemContainer( DependencyObject container ) - { - if( this.Status != GeneratorStatus.GeneratingContainers ) - throw DataGridException.Create( "The Generator is not active: StartAt() was not called prior calling PrepareItemContainer() or the returned IDisposable was already disposed of.", m_dataGridControl ); - - var dataItemStore = CustomItemContainerGenerator.GetDataItemProperty( container ); - if( ( dataItemStore == null ) || dataItemStore.IsEmpty ) - return; - - var dataItem = dataItemStore.Data; - if( dataItem == null ) - return; - - m_dataGridControl.PrepareItemContainer( container, dataItem ); - } - - void IItemContainerGenerator.Remove( GeneratorPosition position, int count ) - { - if( this.Status == GeneratorStatus.GeneratingContainers ) - throw DataGridException.Create( "Cannot perform this operation while the generator is busy generating items", m_dataGridControl ); - - if( position.Offset != 0 ) - throw DataGridException.Create( "The GeneratorPosition to remove cannot map to a non-realized item.", m_dataGridControl, "position" ); - - if( position.Index == -1 ) - throw DataGridException.Create( "The GeneratorPosition to remove cannot map to a non-realized item.", m_dataGridControl, "position" ); - - if( count <= 0 ) - throw DataGridException.Create( "The number of item to remove must be greater than or equal to one.", m_dataGridControl, "count" ); - - if( position.Index >= m_genPosToIndex.Count ) - throw DataGridException.Create( "Trying to remove an item at an out-of-bound GeneratorPosition index", m_dataGridControl ); - - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_IItemContainerGenerator_Remove, DataGridTraceArgs.Index( position.Index ), DataGridTraceArgs.Count( count ) ) ) - { - for( int i = 0; i < count; i++ ) - { - if( this.RemoveGeneratedItem( position.Index, null ) == 0 ) - //This case deserves a more solid approach... We do not want to allow removal from the user panel of an item that somehow is not present. - throw DataGridException.Create( "Trying to remove an item at an out-of-bound GeneratorPosition index.", m_dataGridControl ); - } - } - } - - void IItemContainerGenerator.RemoveAll() - { - if( this.Status == GeneratorStatus.GeneratingContainers ) - throw DataGridException.Create( "Cannot perform this operation while the generator is busy generating items", m_dataGridControl ); - - using( this.SetIsHandlingGlobalItemsResetLocally() ) - { - //Call to remove all shall not request container recycling panels to remove their containers. Therefore, I am not collecting the remove containers. - this.RemoveAllGeneratedItems(); - } - } - - IDisposable IItemContainerGenerator.StartAt( GeneratorPosition position, GeneratorDirection direction, bool allowStartAtRealizedItem ) - { - this.SetIsInUse(); - - if( this.Status == GeneratorStatus.GeneratingContainers ) - throw DataGridException.Create( "Cannot perform this operation while the generator is busy generating items", m_dataGridControl ); - - this.EnsureNodeTreeCreated(); - - if( ( !allowStartAtRealizedItem ) && ( position.Offset == 0 ) ) - { - if( direction == GeneratorDirection.Forward ) - { - position = this.FindNextUnrealizedGeneratorPosition( position ); - } - else - { - position = this.FindPreviousUnrealizedGeneratorPosition( position ); - } - } - - return new CustomItemContainerGeneratorDisposableDisposer( this, position, direction ); - } - - IDisposable IItemContainerGenerator.StartAt( GeneratorPosition position, GeneratorDirection direction ) - { - return ( ( IItemContainerGenerator )this ).StartAt( position, direction, false ); - } - - #endregion - - #region ICustomItemContainerGenerator Members - - public int ItemCount - { - get - { - this.EnsureNodeTreeCreated(); - - //if the value that was last cached is invalid - if( m_lastValidItemCountGeneration != m_currentGeneratorContentGeneration ) - { - //then re-evaluate the number of items. - if( m_startNode != null ) - { - // If it does that correctly, then this function is OK. - int chainLength; - GeneratorNodeHelper.EvaluateChain( m_startNode, out m_cachedItemCount, out chainLength ); - } - else - { - m_cachedItemCount = 0; - } - - m_lastValidItemCountGeneration = m_currentGeneratorContentGeneration; - } - - //return the cached value. - return m_cachedItemCount; - } - } - - public bool IsRecyclingEnabled - { - get - { - return m_flags[ ( int )CustomItemContainerGeneratorFlags.RecyclingEnabled ]; - } - set - { - //if the container recycling is turned OFF from ON - if( value == ( bool )m_flags[ ( int )CustomItemContainerGeneratorFlags.RecyclingEnabled ] ) - return; - - if( !value ) - { - this.ClearRecyclingPools(); - } - - m_flags[ ( int )CustomItemContainerGeneratorFlags.RecyclingEnabled ] = value; - - foreach( var generator in this.GetDetailGenerators() ) - { - generator.IsRecyclingEnabled = value; - } - } - } - - private bool GenPosToIndexNeedsUpdate - { - get - { - return m_flags[ ( int )CustomItemContainerGeneratorFlags.GenPosToIndexNeedsUpdate ]; - } - set - { - m_flags[ ( int )CustomItemContainerGeneratorFlags.GenPosToIndexNeedsUpdate ] = value; - } - } - - void ICustomItemContainerGenerator.SetCurrentIndex( int newCurrentIndex ) - { - // This method enables the possibility for the "ItemsHost" panels to set the current item of the - // DataGridControl. This is required for scenarios such as the CardflowItemsHost. - this.EnsureNodeTreeCreated(); - - var nodeHelper = new GeneratorNodeHelper( m_startNode, 0, 0 ); - - //First, locate the item within the Generator. - object newCurrentItem = nodeHelper.FindIndex( newCurrentIndex ); - - if( newCurrentItem == null ) - throw DataGridException.Create( "An attempt was made to access an item at an index that does not correspond to an item.", m_dataGridControl ); - - //Then, if the item is within an ItemsNode, check if it belongs to a detail - var itemsNode = nodeHelper.CurrentNode as ItemsGeneratorNode; - if( itemsNode != null ) - { - int masterIndex; - int detailIndex; - int detailNodeIndex; - - var detailNode = itemsNode.GetDetailNodeForIndex( newCurrentIndex - nodeHelper.Index, out masterIndex, out detailIndex, out detailNodeIndex ); - if( detailNode != null ) - { - //call recursively the SetCurrentIndex method on the detail generator to ensure that if the item - //belongs to a sub-generator of the detail generator, then the appropriate DataGridContext will get invoked. - ICustomItemContainerGenerator detailGenerator = detailNode.DetailGenerator; - detailGenerator.SetCurrentIndex( detailIndex ); - return; - } - } - - //If the item is not within an ItemsNode or not within a detail - //then set it current within its context. - m_dataGridContext.SetCurrentItemCore( newCurrentItem, false, false, AutoScrollCurrentItemSourceTriggers.Navigation ); - } - - int ICustomItemContainerGenerator.GetCurrentIndex() - { - if( m_dataGridControl.CurrentContext != null ) - return this.FindIndexForItem( m_dataGridControl.CurrentContext.InternalCurrentItem, m_dataGridContext ); - - return -1; - } - - void ICustomItemContainerGenerator.RestoreFocus( DependencyObject container ) - { - if( !m_genPosToContainer.Contains( container ) ) - throw DataGridException.Create( "The specified container is not part of the generator's content.", m_dataGridControl, "container" ); - - var dataGridContext = DataGridControl.GetDataGridContext( container ); - var column = ( dataGridContext == null ) ? null : dataGridContext.CurrentColumn; - - m_dataGridControl.SetFocusHelper( container as UIElement, column, false, true ); - } - - #endregion - - private DependencyObject GenerateNextLocalContainer( out bool isNewlyRealized ) - { - var container = default( DependencyObject ); - var node = m_generatorNodeHelper.CurrentNode as CollectionGeneratorNode; - - //if the index exists in the list, then the item is already realized. - var genPosIndex = m_genPosToIndex.IndexOf( m_generatorCurrentGlobalIndex ); - var itemsNode = node as ItemsGeneratorNode; - - if( node == null ) - { - this.TraceEvent( TraceEventType.Error, DataGridTraceEventId.CustomItemContainerGenerator_GenerateNextLocalContainer, DataGridTraceMessages.UnexpectedNode, DataGridTraceArgs.Node( node ), DataGridTraceArgs.GeneratorIndex( genPosIndex ) ); - } - - object dataItem; - - if( genPosIndex >= 0 ) - { - //retrieve the container for the item that is already stored in the data structure - container = m_genPosToContainer[ genPosIndex ]; - dataItem = m_genPosToItem[ genPosIndex ]; - - var tempNode = m_genPosToNode[ genPosIndex ]; - node = tempNode as CollectionGeneratorNode; - - if( tempNode == null ) - { - this.TraceEvent( TraceEventType.Critical, DataGridTraceEventId.CustomItemContainerGenerator_GenerateNextLocalContainer, DataGridTraceMessages.UnexpectedNode, DataGridTraceArgs.Node( node ), DataGridTraceArgs.GeneratorIndex( genPosIndex ), DataGridTraceArgs.Container( container ), DataGridTraceArgs.Item( dataItem ) ); - throw DataGridException.Create( "CustomItemContainerGenerator.GenerateNextLocalContainer: cached Node is null", m_dataGridControl ); - } - else if( node != m_generatorNodeHelper.CurrentNode ) - { - this.TraceEvent( TraceEventType.Critical, DataGridTraceEventId.CustomItemContainerGenerator_GenerateNextLocalContainer, DataGridTraceMessages.NodeIsNotTheCurrentNode, DataGridTraceArgs.Node( tempNode ), DataGridTraceArgs.Node( m_generatorNodeHelper.CurrentNode ), DataGridTraceArgs.GeneratorIndex( genPosIndex ), DataGridTraceArgs.Container( container ), DataGridTraceArgs.Item( dataItem ) ); - throw DataGridException.Create( "CustomItemContainerGenerator.GenerateNextLocalContainer: Node is not the current one.", m_dataGridControl ); - } - - isNewlyRealized = false; - } - else - { - //This means that the container is not already generated for the item... - - //First need to fetch the dataItem - if( itemsNode != null ) - { - dataItem = itemsNode.Items[ m_generatorCurrentOffset ]; //here I use this particular exception to prevent over-complicating the algo - //I know it's rather dirty but!!! (i.e. calling GetAt() would return something with details computed in ). - - this.UpdateDataVirtualizationLockForItemsNode( itemsNode, dataItem, true ); - } - else - { - dataItem = node.GetAt( m_generatorCurrentOffset ); - //Here I Need to call the GetAt() to make sure the collapsed GroupHeaders/Footers are correctly generated... - } - - //create the container for the item specified according to the item's type - container = this.CreateContainerForItem( dataItem, node ); - - //flag the container as newly generated. - isNewlyRealized = true; - } - - if( itemsNode != null ) - { - int itemIndex = m_generatorNodeHelper.SourceDataIndex + m_generatorCurrentOffset; - - DataGridVirtualizingPanel.SetItemIndex( container, itemIndex ); - - //In order to make sure the container is properly selected, a new selection range must be initialized with the updated item index. - var currentSelection = new SelectionRange( itemIndex ); - var rowToSelect = container as DataRow; - - if( rowToSelect != null ) - { - if( m_dataGridContext.SelectedItemsStore.Contains( currentSelection ) ) - { - rowToSelect.SetIsSelected( true ); - } - else - { - rowToSelect.SetIsSelected( false ); - } - } - } - else - { - DataGridVirtualizingPanel.SetItemIndex( container, -1 ); - } - - if( node != null ) - { - //determine the appropriate GroupConfiguration ( based on parent node ) and set it on the container. - var groupConfig = default( GroupConfiguration ); - var parentNode = node.Parent as GroupGeneratorNode; //implicit rule: a parent node is always a GroupGeneratorNode - - if( parentNode != null ) - { - groupConfig = parentNode.GroupConfiguration; - } - - if( groupConfig != null ) - { - DataGridControl.SetContainerGroupConfiguration( container, groupConfig ); - } - } - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_GenerateNextLocalContainer, DataGridTraceMessages.ContainerGenerated, DataGridTraceArgs.Container( container ), DataGridTraceArgs.Node( node ), DataGridTraceArgs.GeneratorIndex( genPosIndex ), DataGridTraceArgs.Value( isNewlyRealized ) ); - - return container; - } - - private bool IsDataVirtualized( ItemsGeneratorNode node ) - { - DataGridVirtualizingCollectionViewBase collectionView; - VirtualList items; - - return this.TryGetVirtualizedCollection( node, out collectionView, out items ); - } - - private bool TryGetVirtualizedCollection( ItemsGeneratorNode node, out DataGridVirtualizingCollectionViewBase collectionView, out VirtualList items ) - { - if( node == null ) - { - collectionView = default( DataGridVirtualizingCollectionViewBase ); - items = default( VirtualList ); - } - else - { - var itemCollection = node.Items as ItemCollection; - if( itemCollection != null ) - { - collectionView = itemCollection.SourceCollection as DataGridVirtualizingCollectionViewBase; - items = default( VirtualList ); - } - else - { - collectionView = default( DataGridVirtualizingCollectionViewBase ); - items = node.Items as VirtualList; - } - } - - return ( collectionView != null ) - || ( items != null ); - } - - private void UpdateDataVirtualizationLockForItemsNode( ItemsGeneratorNode node, object dataItem, bool applyLock ) - { - DataGridVirtualizingCollectionViewBase collectionView; - VirtualList items; - - if( !this.TryGetVirtualizedCollection( node, out collectionView, out items ) ) - return; - - if( collectionView != null ) - { - var index = node.Items.IndexOf( dataItem ); - if( applyLock ) - { - collectionView.RootGroup.LockGlobalIndex( index ); - } - else - { - collectionView.RootGroup.UnlockGlobalIndex( index ); - } - } - else if( items != null ) - { - var index = node.Items.IndexOf( dataItem ); - if( applyLock ) - { - items.LockPageForLocalIndex( index ); - } - else - { - items.UnlockPageForLocalIndex( index ); - } - } - } - - private void MoveGeneratorForward() - { - var currentMasterNode = m_generatorNodeHelper.CurrentNode as ItemsGeneratorNode; - - //if I was generating from a detail generator - if( m_generatorCurrentDetail != null ) - { - if( ( currentMasterNode == null ) || ( currentMasterNode.Details == null ) ) - { - this.TraceEvent( TraceEventType.Critical, DataGridTraceEventId.CustomItemContainerGenerator_MoveGeneratorForward, DataGridTraceMessages.UnexpectedNode, DataGridTraceArgs.Node( currentMasterNode ) ); - } - - //incremment the running counter for the item index generated in the detail generator - m_generatorCurrentDetailIndex++; - - //if that was the last item from the detail generator - if( m_generatorCurrentDetailIndex >= m_generatorCurrentDetail.ItemCount ) - { - //stop the detail generator - m_generatorCurrentDetailDisposable.Dispose(); - m_generatorCurrentDetailDisposable = null; - m_generatorCurrentDetailIndex = -1; - - //increment detail node index - m_generatorCurrentDetailNodeIndex++; - - List detailsforMasterNode; - currentMasterNode.Details.TryGetValue( m_generatorCurrentOffset, out detailsforMasterNode ); - - if( detailsforMasterNode == null ) - { - this.TraceEvent( TraceEventType.Critical, DataGridTraceEventId.CustomItemContainerGenerator_MoveGeneratorForward, DataGridTraceMessages.DetailExpected, DataGridTraceArgs.Node( currentMasterNode ) ); - } - - while( ( m_generatorCurrentDetailNodeIndex < detailsforMasterNode.Count ) && ( m_generatorCurrentDetailIndex == -1 ) ) - { - //try to use it - m_generatorCurrentDetail = detailsforMasterNode[ m_generatorCurrentDetailNodeIndex ]; - - if( m_generatorCurrentDetail.ItemCount > 0 ) - { - m_generatorCurrentDetailIndex = 0; - } - else - { - //increment detail node index - m_generatorCurrentDetailNodeIndex++; - } - } - - if( m_generatorCurrentDetailIndex == -1 ) - { - //if there are no other details for this master item, then move the master item counter forward - m_generatorCurrentDetail = null; - m_generatorCurrentOffset++; - } - } - } - else - { - //If I was not generating from a detail generator - - //Check if there is availlable details for the current item - List detailsForNode; - - if( ( currentMasterNode != null ) && ( currentMasterNode.Details != null ) - && ( currentMasterNode.Details.TryGetValue( m_generatorCurrentOffset, out detailsForNode ) ) ) - { - var foundDetail = false; - - for( int i = 0; i < detailsForNode.Count; i++ ) - { - var detailNode = detailsForNode[ i ]; - - if( detailNode.ItemCount > 0 ) - { - //There are details for the master item - m_generatorCurrentDetailIndex = 0; - m_generatorCurrentDetailNodeIndex = i; - m_generatorCurrentDetail = detailNode; - foundDetail = true; - break; - } - } - - if( !foundDetail ) - { - //there are no items in the details - m_generatorCurrentOffset++; //move to the next index in the local generator... - } - } - else - { - //there are no details OR the node is not an ItemsGeneratorNode (cannot have details) - m_generatorCurrentOffset++; //move to the next index... - } - } - - //if the current offset is after the last "item" of the node (can be more than 1 item, for multi item nodes) - if( m_generatorCurrentOffset >= ( ( currentMasterNode != null ) ? currentMasterNode.Items.Count : m_generatorNodeHelper.CurrentNode.ItemCount ) ) - { - //if we are at the last (and possible only) item in the node, move to the next node. - if( !m_generatorNodeHelper.MoveForward() ) - { - //if we failed to move the the next node, then we want to make sure the generator will not be able to generate - //any more containers. - m_generatorNodeHelper = null; - } - - //reset the offset, since we moved the the node helper. - m_generatorCurrentOffset = 0; - } - - m_generatorCurrentGlobalIndex++; - } - - private void MoveGeneratorBackward() - { - var currentMasterNode = m_generatorNodeHelper.CurrentNode as ItemsGeneratorNode; - - //if I was generating from a detail generator - if( m_generatorCurrentDetail != null ) - { - if( ( currentMasterNode == null ) || ( currentMasterNode.Details == null ) ) - { - this.TraceEvent( TraceEventType.Critical, DataGridTraceEventId.CustomItemContainerGenerator_MoveGeneratorBackward, DataGridTraceMessages.UnexpectedNode, DataGridTraceArgs.Node( currentMasterNode ) ); - } - - //decrement the running counter for the item index generated in the detail generator - m_generatorCurrentDetailIndex--; - - //if that was the first item from the detail generator - if( m_generatorCurrentDetailIndex < 0 ) - { - //stop the detail generator - m_generatorCurrentDetailDisposable.Dispose(); - m_generatorCurrentDetailDisposable = null; - m_generatorCurrentDetailIndex = -1; - - //decrement detail node index - m_generatorCurrentDetailNodeIndex--; - - if( m_generatorCurrentDetailNodeIndex >= 0 ) - { - List detailsforMasterNode; - currentMasterNode.Details.TryGetValue( m_generatorCurrentOffset, out detailsforMasterNode ); - - if( detailsforMasterNode == null ) - { - this.TraceEvent( TraceEventType.Critical, DataGridTraceEventId.CustomItemContainerGenerator_MoveGeneratorBackward, DataGridTraceMessages.DetailExpected, DataGridTraceArgs.Node( currentMasterNode ) ); - } - - while( ( m_generatorCurrentDetailNodeIndex >= 0 ) && ( m_generatorCurrentDetailIndex == -1 ) ) - { - //try to use it - m_generatorCurrentDetail = detailsforMasterNode[ m_generatorCurrentDetailNodeIndex ]; - - if( m_generatorCurrentDetail.ItemCount > 0 ) - { - m_generatorCurrentDetailIndex = m_generatorCurrentDetail.ItemCount - 1; - } - else - { - //decrement detail node index - m_generatorCurrentDetailNodeIndex--; - } - } - } - - if( m_generatorCurrentDetailIndex == -1 ) - { - //if there are no other details for this master item, then - //don't do anything, the current m_generatorCurrentOffset will - //be generated - m_generatorCurrentDetail = null; - } - } - } - else - { - //If I was not generating from a detail generator - - //move the current offset to the previous element - m_generatorCurrentOffset--; - - //do not try open details if the offset falls below 0 - if( m_generatorCurrentOffset >= 0 ) - { - //Check if there is availlable details for the current item - this.SetupLastDetailForNode( currentMasterNode ); - } - } - - //if the current offset is below the last "item" of the node (can be more than 1 item, for multi item nodes) - if( m_generatorCurrentOffset < 0 ) - { - //if we are at the last (and possible only) item in the node, move to the next node. - if( !m_generatorNodeHelper.MoveBackward() ) - { - //if we failed to move the the next node, then we want to make sure the generator will not be able to generate - //any more containers. - m_generatorNodeHelper = null; - } - else - { - currentMasterNode = m_generatorNodeHelper.CurrentNode as ItemsGeneratorNode; - - //reset the offset, since we moved the the node helper. - m_generatorCurrentOffset = ( ( currentMasterNode != null ) ? currentMasterNode.Items.Count : m_generatorNodeHelper.CurrentNode.ItemCount ) - 1; - - this.SetupLastDetailForNode( currentMasterNode ); - } - } - - m_generatorCurrentGlobalIndex--; - } - - private void SetupLastDetailForNode( ItemsGeneratorNode node ) - { - List detailsForNode; - - if( ( node != null ) && ( node.Details != null ) && ( node.Details.TryGetValue( m_generatorCurrentOffset, out detailsForNode ) ) ) - { - for( int i = detailsForNode.Count - 1; i >= 0; i-- ) - { - var detailNode = detailsForNode[ i ]; - if( detailNode.ItemCount > 0 ) - { - //There are details for the master item - m_generatorCurrentDetailNodeIndex = i; - m_generatorCurrentDetail = detailNode; - m_generatorCurrentDetailIndex = detailNode.ItemCount - 1; - break; - } - } - } - } - - private bool ShouldDrawBottomLine() - { - if( m_generatorStatus != GeneratorStatus.GeneratingContainers ) - throw DataGridException.Create( "An attempt was made to call the CustomItemContainerGenerator.ShouldDrawBottomLine method while containers are not being generated.", m_dataGridControl ); - - return ( m_generatorCurrentGlobalIndex == ( this.ItemCount - 1 ) ); - } - - private bool ItemHasExpandedDetails() - { - if( m_generatorStatus != GeneratorStatus.GeneratingContainers ) - throw DataGridException.Create( "An attempt was made to call the CustomItemContainerGenerator.ItemHasExpandedDetails method while containers are not being generated.", m_dataGridControl ); - - var itemsNode = m_generatorNodeHelper.CurrentNode as ItemsGeneratorNode; - if( ( itemsNode == null ) || ( itemsNode.Details == null ) ) - return false; - - return itemsNode.Details.ContainsKey( m_generatorCurrentOffset ); - } - - internal void CleanupGenerator() - { - this.CleanupGenerator( false ); - } - - internal void CleanupGenerator( bool isNestedCall ) - { - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_CleanupGenerator ) ) - { - this.ForceReset = false; - - if( this.IsHandlingGlobalItemsResetLocally ) - { - this.TraceEvent( TraceEventType.Warning, DataGridTraceEventId.CustomItemContainerGenerator_CleanupGenerator, DataGridTraceMessages.CannotProcessOnReset ); - return; - } - - using( this.SetIsHandlingGlobalItemsResetLocally() ) - { - this.RemoveAllGeneratedItems(); - - if( !isNestedCall ) - { - this.SendResetEvent(); - this.ClearRecyclingPools(); - } - - this.ClearLateGroupLevelDescriptions(); - - if( m_startNode != null ) - { - //Note: this does not disconnects the "general" master/detail relationship established between an Item and its details, - //within the Generator itself, however, it does break the link between the GeneratorNode where the details are mapped. - this.NodeFactory.CleanGeneratorNodeTree( m_startNode ); - } - - m_groupNodeMappingCache.Clear(); - m_firstHeader = null; - m_firstFooter = null; - m_firstItem = null; - m_startNode = null; - - //This absolutelly needs to be done after the node list is Cleaned! - this.CleanupDetailRelations(); - this.InvalidateNodeTree(); - } - } - } - - private void CleanupDetailRelations() - { - var detailNodes = this.GetDetailGeneratorNodes().ToList(); - - m_masterToDetails.Clear(); - - foreach( var detailNode in detailNodes ) - { - this.ClearDetailGeneratorNode( detailNode ); - } - - m_floatingDetails.Clear(); - } - - private void IncrementCurrentGenerationCount( bool updateGenPosList ) - { - unchecked - { - m_currentGeneratorContentGeneration++; - } - - if( updateGenPosList ) - { - if( m_genPosToIndexUpdateInhibitCount == 0 ) - { - this.UpdateGenPosToIndexList(); - this.GenPosToIndexNeedsUpdate = false; - } - else - { - this.GenPosToIndexNeedsUpdate = true; - } - } - } - - private void IncrementCurrentGenerationCount() - { - this.IncrementCurrentGenerationCount( true ); - } - - private void OnItemsSourceChanged( object sender, EventArgs e ) - { - // Avoid re-entrance when processing a global reset - if( this.IsHandlingGlobalItemsReset ) - return; - - this.CleanupGenerator(); - } - - private void OnDetailConfigurationsChanged( object sender, NotifyCollectionChangedEventArgs e ) - { - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_OnDetailConfigurationsChanged ) ) - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_OnDetailConfigurationsChanged, DataGridTraceArgs.Action( e.Action ) ); - - switch( e.Action ) - { - case NotifyCollectionChangedAction.Remove: - { - using( m_recyclingPools.DeferContainersRemoved() ) - { - foreach( DetailConfiguration detailConfiguration in e.OldItems ) - { - this.CloseDetails( detailConfiguration ); - - m_recyclingPools.Clear( detailConfiguration ); - } - } - break; - } - - case NotifyCollectionChangedAction.Move: - case NotifyCollectionChangedAction.Add: - case NotifyCollectionChangedAction.Replace: - case NotifyCollectionChangedAction.Reset: - default: - { - // That ensure the RemapFloatingDetails() got called and the loop on m_masterToDetails.Keys will not contain invalid item. - this.EnsureNodeTreeCreated(); - - foreach( object item in m_masterToDetails.Keys.ToList() ) - { - this.CloseDetailsForItem( item, null ); - } - break; - } - } - } - } - - private void OnCollectionViewPropertyChanged( PropertyChangedEventArgs e ) - { - var propertyName = e.PropertyName; - - if( string.IsNullOrEmpty( propertyName ) || ( propertyName == DataGridCollectionViewBase.GroupsPropertyName ) ) - { - this.OnCollectionViewGroupsPropertyChanged(); - } - - if( string.IsNullOrEmpty( propertyName ) || ( propertyName == DataGridCollectionViewBase.RootGroupPropertyName ) ) - { - this.OnCollectionViewRootGroupChanged(); - } - } - - private void OnCollectionViewGroupsPropertyChanged() - { - if( m_groupsCollection == m_collectionView.Groups ) - return; - - this.HandleGlobalItemsReset(); - } - - private void OnCollectionViewRootGroupChanged() - { - for( int i = 0; i < m_genPosToNode.Count; i++ ) - { - if( !( m_genPosToNode[ i ] is HeadersFootersGeneratorNode ) ) - continue; - - this.SetStatContext( m_genPosToContainer[ i ], m_genPosToNode[ i ] ); - } - } - - private void OnItemsChanged( object sender, NotifyCollectionChangedEventArgs e ) - { - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_OnItemsChanged ) ) - { - if( this.IsHandlingGlobalItemsResetLocally ) - { - this.TraceEvent( TraceEventType.Warning, DataGridTraceEventId.CustomItemContainerGenerator_OnItemsChanged, DataGridTraceMessages.CannotProcessOnReset, DataGridTraceArgs.Action( e.Action ) ); - return; - } - - if( this.Status == GeneratorStatus.GeneratingContainers ) - throw DataGridException.Create( "Cannot perform this operation while the generator is busy generating items.", m_dataGridControl ); - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_OnItemsChanged, DataGridTraceArgs.Action( e.Action ) ); - - if( this.ForceReset ) - { - this.HandleGlobalItemsReset(); - } - else - { - if( e.Action == NotifyCollectionChangedAction.Reset ) - { - if( ( m_groupsCollection == null ) != ( m_collectionView.GroupDescriptions.Count == 0 ) ) - { - this.HandleGlobalItemsReset(); - } - } - } - } - } - - private void OnGroupsChanged( object sender, NotifyCollectionChangedEventArgs e ) - { - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_OnGroupsChanged, DataGridTraceArgs.Group( sender ) ) ) - { - if( this.IsHandlingGlobalItemsResetLocally ) - { - this.TraceEvent( TraceEventType.Warning, DataGridTraceEventId.CustomItemContainerGenerator_OnGroupsChanged, DataGridTraceMessages.CannotProcessOnReset, DataGridTraceArgs.Group( sender ), DataGridTraceArgs.Action( e.Action ) ); - return; - } - - if( this.Status == GeneratorStatus.GeneratingContainers ) - throw DataGridException.Create( "Cannot perform this operation while the generator is busy generating items.", m_dataGridControl ); - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_OnGroupsChanged, DataGridTraceArgs.Group( sender ), DataGridTraceArgs.Action( e.Action ) ); - - switch( e.Action ) - { - case NotifyCollectionChangedAction.Add: - { - var count = e.NewItems.Count; - - //if the first item is empty, do not do anything, the structure will be generated when the generator is started! - if( m_firstItem != null ) - { - //The only moment where the m_firstItem is null is typically when a reset occured... - //other moments is when there are 0 items. - this.HandleSameLevelGroupAddition( m_firstItem, out count, e ); - this.IncrementCurrentGenerationCount(); - } - - this.SendAddEvent( count ); - } - break; - - case NotifyCollectionChangedAction.Move: - { - if( m_firstItem != null ) - { - if( !( m_firstItem is GroupGeneratorNode ) ) - throw DataGridException.Create( "Trying to move a GeneratorNode that is not a GroupGeneratorNode.", m_dataGridControl ); - - Debug.Assert( e.OldStartingIndex != e.NewStartingIndex, "An attempt was made to move a group to the same location." ); - - this.HandleSameLevelGroupMove( m_firstItem, e ); - } - } - break; - - case NotifyCollectionChangedAction.Remove: - { - if( m_firstItem != null ) - { - if( !( m_firstItem is GroupGeneratorNode ) ) - throw DataGridException.Create( "Trying to remove a GeneratorNode that is not a GroupGeneratorNode.", m_dataGridControl ); - - var count = default( int ); - var containers = new List(); - - this.HandleSameLevelGroupRemove( m_firstItem, out count, e, containers ); - this.IncrementCurrentGenerationCount(); - this.SendRemoveEvent( count, containers ); - } - } - break; - - case NotifyCollectionChangedAction.Replace: - throw DataGridException.Create( "Replace not supported at the moment on groups.", m_dataGridControl ); - - case NotifyCollectionChangedAction.Reset: - { - if( m_firstItem != null ) - { - if( !( m_firstItem is GroupGeneratorNode ) ) - throw DataGridException.Create( "Trying to reset a GeneratorNode that is not a GroupGeneratorNode.", m_dataGridControl ); - - this.HandleSameLevelGroupReset( m_firstItem ); - } - else - { - this.HandleGlobalItemsReset(); - } - } - break; - } - } - } - - private void OnGeneratorNodeItemsCollectionChanged( object sender, NotifyCollectionChangedEventArgs e ) - { - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_OnGeneratorNodeItemsCollectionChanged, DataGridTraceArgs.Node( sender ), DataGridTraceArgs.Action( e.Action ) ) ) - { - if( this.IsHandlingGlobalItemsResetLocally ) - { - this.TraceEvent( TraceEventType.Warning, DataGridTraceEventId.CustomItemContainerGenerator_OnGeneratorNodeItemsCollectionChanged, DataGridTraceMessages.CannotProcessOnReset, DataGridTraceArgs.Node( sender ), DataGridTraceArgs.Action( e.Action ) ); - return; - } - - if( this.Status == GeneratorStatus.GeneratingContainers ) - throw DataGridException.Create( "Cannot perform this operation while the generator is busy generating items.", m_dataGridControl ); - - var node = ( ItemsGeneratorNode )sender; - var updateContainersIndex = !node.IsComputedExpanded; - - e = e.GetRangeActionOrSelf(); - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_OnGeneratorNodeItemsCollectionChanged, DataGridTraceArgs.Node( sender ), DataGridTraceArgs.Action( e.Action ) ); - - switch( e.Action ) - { - case NotifyCollectionChangedAction.Add: - { - this.HandleItemAddition( node, e ); - } - break; - - case NotifyCollectionChangedAction.Remove: - { - this.HandleItemRemoveMoveReplace( node, e ); - } - break; - - case NotifyCollectionChangedAction.Move: - case NotifyCollectionChangedAction.Replace: - { - //detect the case where the replace is targeted at a single item, replaced with himself. - //This particular case is there to handle the particularities of the DGCV with regards to - //IBindingList.ListChanged.ChangeType == ItemChanged. - if( ( e.Action == NotifyCollectionChangedAction.Replace ) && - ( e.OldItems.Count == 1 ) && ( e.NewItems.Count == 1 ) && - ( e.NewItems[ 0 ] == e.OldItems[ 0 ] ) ) - { - // Getting a replace with the same instance should just do nothing. - // - // Note : We know that will prevent a row from refreshing correctly if the item - // are not implementing a mechanic of notification ( like INotifyPropertyChanged ). - - updateContainersIndex = false; - } - else - { - //any other case, normal handling - this.HandleItemRemoveMoveReplace( node, e ); - } - } - break; - - case NotifyCollectionChangedAction.Reset: - { - this.HandleItemReset( node ); - } - break; - } - - if( updateContainersIndex ) - { - this.UpdateContainersIndex(); - } - } - } - - private void OnGeneratorNodeExpansionStateChanged( object sender, ExpansionStateChangedEventArgs e ) - { - if( this.Status == GeneratorStatus.GeneratingContainers ) - throw DataGridException.Create( "Cannot perform this operation while the generator is busy generating items.", m_dataGridControl ); - - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_OnGeneratorNodeExpansionStateChanged, DataGridTraceArgs.Node( sender ) ) ) - { - - var node = sender as GeneratorNode; - Debug.Assert( node != null ); - - var changedNode = node.Parent as GroupGeneratorNode; - if( changedNode == null ) - { - this.TraceEvent( TraceEventType.Error, DataGridTraceEventId.CustomItemContainerGenerator_OnGeneratorNodeExpansionStateChanged, DataGridTraceMessages.UnexpectedNode, DataGridTraceArgs.Node( node.Parent ) ); - } - - //Determine if the changedNode is "below" a collapsed group (because if so, I don't need any sort of notification or removal ). - var parentGroupNode = changedNode.Parent as GroupGeneratorNode; - if( ( parentGroupNode != null ) && ( !parentGroupNode.IsComputedExpanded ) ) - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_OnGeneratorNodeExpansionStateChanged, DataGridTraceMessages.NodeIsCollapsed, DataGridTraceArgs.Node( node ) ); - return; - } - - var nodeHelper = new GeneratorNodeHelper( node, 0, 0 ); - nodeHelper.ReverseCalculateIndex(); - - //if the node was "Collapsed" - if( !e.NewExpansionState ) - { - var startIndex = nodeHelper.Index + e.IndexOffset; - var containers = new List(); - - this.RemoveGeneratedItems( startIndex, startIndex + e.Count - 1, containers ); - this.SendRemoveEvent( e.Count, containers ); - } - //if the node was "Expanded" - else - { - this.SendAddEvent( e.Count ); - } - } - } - - private void OnGroupGeneratorNodeIsExpandedChanging( object sender, EventArgs e ) - { - if( this.Status == GeneratorStatus.GeneratingContainers ) - throw DataGridException.Create( "Cannot perform this operation while the generator is busy generating items.", m_dataGridControl ); - - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_OnGroupGeneratorNodeIsExpandedChanging, DataGridTraceArgs.Node( sender ) ) ) - { - if( m_currentGenPosToIndexInhibiterDisposable != null ) - { - this.TraceEvent( TraceEventType.Error, DataGridTraceEventId.CustomItemContainerGenerator_OnGroupGeneratorNodeIsExpandedChanging, DataGridTraceMessages.InhibiterAlreadySet ); - } - - m_currentGenPosToIndexInhibiterDisposable = this.InhibitParentGenPosToIndexUpdate(); - - var groupGeneratorNode = sender as GroupGeneratorNode; - - if( ( m_dataGridContext != null ) - && ( !m_dataGridContext.IsDeferRestoringState ) - && ( !m_dataGridContext.IsRestoringState ) - && ( m_dataGridControl != null ) - && ( groupGeneratorNode != null ) - && ( groupGeneratorNode.IsExpanded ) ) - { - var tableflowItemsHost = m_dataGridControl.ItemsHost as TableflowViewItemsHost; - if( tableflowItemsHost != null ) - { - tableflowItemsHost.OnGroupCollapsing( groupGeneratorNode.UIGroup ); - } - } - } - } - - private void OnGroupGeneratorNodeIsExpandedChanged( object sender, EventArgs e ) - { - if( this.Status == GeneratorStatus.GeneratingContainers ) - throw DataGridException.Create( "Cannot perform this operation while the generator is busy generating items.", m_dataGridControl ); - - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_OnGroupGeneratorNodeIsExpandedChanged, DataGridTraceArgs.Node( sender ) ) ) - { - var node = sender as GroupGeneratorNode; - if( node != null ) - { - this.IncrementCurrentGenerationCount(); - } - else - { - this.TraceEvent( TraceEventType.Error, DataGridTraceEventId.CustomItemContainerGenerator_OnGroupGeneratorNodeIsExpandedChanged, DataGridTraceMessages.UnexpectedNode, DataGridTraceArgs.Node( sender ) ); - } - - if( m_currentGenPosToIndexInhibiterDisposable != null ) - { - m_currentGenPosToIndexInhibiterDisposable.Dispose(); - m_currentGenPosToIndexInhibiterDisposable = null; - } - } - } - - private void OnGeneratorNodeGroupsCollectionChanged( object sender, NotifyCollectionChangedEventArgs e ) - { - if( this.Status == GeneratorStatus.GeneratingContainers ) - throw DataGridException.Create( "Cannot perform this operation while the generator is busy generating items.", m_dataGridControl ); - - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_OnGeneratorNodeGroupsCollectionChanged, DataGridTraceArgs.Node( sender ), DataGridTraceArgs.Action( e.Action ) ) ) - { - var node = sender as GroupGeneratorNode; - if( node == null ) - { - this.TraceEvent( TraceEventType.Error, DataGridTraceEventId.CustomItemContainerGenerator_OnGeneratorNodeGroupsCollectionChanged, DataGridTraceMessages.UnexpectedNode, DataGridTraceArgs.Node( sender ), DataGridTraceArgs.Action( e.Action ) ); - return; - } - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_OnGeneratorNodeGroupsCollectionChanged, DataGridTraceArgs.Node( sender ), DataGridTraceArgs.Action( e.Action ) ); - - switch( e.Action ) - { - case NotifyCollectionChangedAction.Add: - { - var count = default( int ); - this.HandleParentGroupAddition( node, out count, e ); - - if( node.IsComputedExpanded ) - { - this.IncrementCurrentGenerationCount(); - this.SendAddEvent( count ); - } - else - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_OnGeneratorNodeGroupsCollectionChanged, DataGridTraceMessages.NodeIsCollapsed, DataGridTraceArgs.Node( node ) ); - } - } - break; - - case NotifyCollectionChangedAction.Move: - { - if( node.Child == null ) - throw DataGridException.Create( "An attempt was made to move a group with a null child GeneratorNode.", m_dataGridControl ); - - Debug.Assert( e.OldStartingIndex != e.NewStartingIndex, "An attempt was made to move a group to the same location." ); - - this.HandleSameLevelGroupMove( node.Child, e ); - } - break; - - case NotifyCollectionChangedAction.Remove: - { - if( node.Child == null ) - throw DataGridException.Create( "An attempt was made to remove a group with a null child GeneratorNode.", m_dataGridControl ); - - var count = default( int ); - var containers = new List(); - - this.HandleParentGroupRemove( node, out count, e, containers ); - - if( node.IsComputedExpanded ) - { - this.IncrementCurrentGenerationCount(); - this.SendRemoveEvent( count, containers ); - } - else - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_OnGeneratorNodeGroupsCollectionChanged, DataGridTraceMessages.NodeIsCollapsed, DataGridTraceArgs.Node( node ) ); - } - } - break; - - case NotifyCollectionChangedAction.Replace: - throw DataGridException.Create( "Replace not supported at the moment on groups.", m_dataGridControl ); - - case NotifyCollectionChangedAction.Reset: - { - if( node.Child == null ) - throw DataGridException.Create( "An attempt was made to reset a group with a null child GeneratorNode.", m_dataGridControl ); - - this.HandleSameLevelGroupReset( node.Child ); - } - break; - } - } - } - - private void OnGeneratorNodeHeadersFootersCollectionChanged( object sender, NotifyCollectionChangedEventArgs e ) - { - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_OnGeneratorNodeHeadersFootersCollectionChanged ) ) - { - if( this.IsHandlingGlobalItemsResetLocally ) - { - this.TraceEvent( TraceEventType.Warning, DataGridTraceEventId.CustomItemContainerGenerator_OnGeneratorNodeHeadersFootersCollectionChanged, DataGridTraceMessages.CannotProcessOnReset ); - return; - } - - if( this.Status == GeneratorStatus.GeneratingContainers ) - throw DataGridException.Create( "Cannot perform this operation while the generator is busy generating items.", m_dataGridControl ); - - var nodes = ( IEnumerable )sender; - Debug.Assert( nodes != null ); - Debug.Assert( nodes.Any() ); - - e = e.GetRangeActionOrSelf(); - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_OnGeneratorNodeHeadersFootersCollectionChanged, DataGridTraceArgs.Action( e.Action ) ); - - switch( e.Action ) - { - case NotifyCollectionChangedAction.Add: - this.HandleHeadersFootersAddition( nodes, e ); - break; - - case NotifyCollectionChangedAction.Remove: - case NotifyCollectionChangedAction.Move: - case NotifyCollectionChangedAction.Replace: - this.HandleHeadersFootersRemoveMoveReplace( nodes, e ); - break; - - case NotifyCollectionChangedAction.Reset: - this.HandleGlobalItemsReset(); - break; - } - } - } - - private void OnViewThemeChanged( object sender, EventArgs e ) - { - if( this.Status == GeneratorStatus.GeneratingContainers ) - throw DataGridException.Create( "Cannot perform this operation while the generator is busy generating items.", m_dataGridControl ); - - if( m_startNode != null ) - { - this.CleanupGenerator(); - } - - this.IncrementCurrentGenerationCount(); - } - - private void OnGroupConfigurationSelectorChanged() - { - this.CleanupGenerator(); - } - - private void OnRecyclingPoolsContainersRemoved( object sender, ContainersRemovedEventArgs e ) - { - this.OnContainersRemoved( e.RemovedContainers ); - } - - private void ResetNodeList() - { - this.UpdateHeaders( m_dataGridContext.Headers ); - - int addCount; - this.SetupInitialItemsNodes( out addCount ); - - this.UpdateFooters( m_dataGridContext.Footers ); - } - - private int ClearItems() - { - //if the first item is not null, that means that we have items within the grid. - if( m_firstItem == null ) - return 0; - - var previous = m_firstItem.Previous; - - //there are footers items - if( m_firstFooter != null ) - { - //there is a previous item (headers present) - if( previous != null ) - { - m_firstFooter.Previous.Next = null; //clear the next pointer from the last item - m_firstFooter.Previous = previous; //set the last header as the previous from the first footer - previous.Next = m_firstFooter; //set the first footer as the next from the last header - } - else - { - //there is no header present - m_firstFooter.Previous.Next = null; //set the last item next to null (protect again recursive clearing) - m_firstFooter.Previous = null; //make the first footer have not previous - - m_startNode = m_firstFooter; - } - } - else - { - //There is no footers after the items. - if( previous != null ) - { - //this means we have some headers before the items. - previous.Next = null; - } - else - { - //this means we have no headers before the items and no footers after. - m_startNode = null; - } - } - - int removeCount; - int chainLength; - GeneratorNodeHelper.EvaluateChain( m_firstItem, out removeCount, out chainLength ); - - this.ClearLateGroupLevelDescriptions(); - m_groupNodeMappingCache.Clear(); - - this.NodeFactory.CleanGeneratorNodeTree( m_firstItem ); - m_firstItem = null; - - this.InvalidateNodeTree(); - - return removeCount; - } - - private void ClearRecyclingPools() - { - // Only the top most generator may clear the recycling pools. - if( m_dataGridContext.SourceDetailConfiguration != null ) - return; - - m_recyclingPools.Clear(); - } - - private int RemoveGeneratedItem( int index, IList removedContainers ) - { - if( ( index < 0 ) || ( index >= m_genPosToIndex.Count ) ) - return 0; - - Debug.Assert( ( m_genPosToContainer.Count == m_genPosToIndex.Count ) - && ( m_genPosToIndex.Count == m_genPosToItem.Count ) - && ( m_genPosToItem.Count == m_genPosToNode.Count ) ); - - var item = m_genPosToItem[ index ]; - var container = m_genPosToContainer[ index ]; - var node = m_genPosToNode[ index ]; - - //remove the item from the 4 lists... (same as doing a "remove") - this.GenPosArraysRemoveAt( index ); - - if( removedContainers != null ) - { - removedContainers.Insert( 0, container ); - } - - //to ensure this is only done once, check if the node associated with the container is a Detail or not - var detailNode = node as DetailGeneratorNode; - if( detailNode == null ) - { - //Node for item is NOT a detail, can safelly remove the container locally (int this generator instance). - this.RemoveContainer( container, item ); - - return 1; - } - else - { - //node is from a detail relationship, calling a more appropriate detail generator for removal - return detailNode.DetailGenerator.RemoveGeneratedItem( container ); - } - } - - private int RemoveGeneratedItem( DependencyObject container ) - { - var index = m_genPosToContainer.IndexOf( container ); - if( index < 0 ) - return 0; - - return this.RemoveGeneratedItem( index, null ); - } - - private void RemoveGeneratedItems( int startIndex, int endIndex, IList removedContainers ) - { - if( startIndex > endIndex ) - return; - - var count = m_genPosToIndex.Count; - if( ( count <= 0 ) || ( m_genPosToIndex[ 0 ] > endIndex ) || ( m_genPosToIndex[ count - 1 ] < startIndex ) ) - return; - - Debug.Assert( ( m_genPosToContainer.Count == m_genPosToIndex.Count ) - && ( m_genPosToIndex.Count == m_genPosToItem.Count ) - && ( m_genPosToItem.Count == m_genPosToNode.Count ) ); - - //cycle through the list of generated items, and see if any items are generated between the indexes in the removed range. - //start from the end so that removing an item will not cause the indexes to shift. - for( var i = count - 1; i >= 0; i-- ) - { - var index = m_genPosToIndex[ i ]; - - //if the item is within the range removed - if( ( index >= startIndex ) && ( index <= endIndex ) ) - { - //this will ensure to recurse the call to the appropriate Detail Generator for clearing of the container. - //otherwise, it will only remove it from the list of container generated in the current generator instance. - this.RemoveGeneratedItem( i, removedContainers ); - } - } - } - - private void RemoveGeneratedItems( GeneratorNode referenceNode, IList removedContainers ) - { - var toRemove = new List(); - - toRemove.Add( referenceNode ); - - var itemsNode = referenceNode as ItemsGeneratorNode; - if( itemsNode != null ) - { - if( itemsNode.Details != null ) - { - //cycle through all the details currently mapped to the reference node - foreach( var detailsForNode in itemsNode.Details ) - { - foreach( var detailNode in detailsForNode.Value ) - { - toRemove.Add( detailNode ); - } - } - } - } - - //cycle through the list of generated items, and see if any items are from the reference node passed. - //start from the end so that removing an item will not cause the indexes to shift - for( int i = m_genPosToNode.Count - 1; i >= 0; i-- ) - { - var node = m_genPosToNode[ i ]; - - //if the item is within the range removed - if( toRemove.Contains( node ) ) - { - //this will ensure to recurse the call to the appropriate Detail Generator for clearing of the container. - //otherwise, it will only remove it from the list of container generated in the current generator instance. - this.RemoveGeneratedItem( i, removedContainers ); - } - } - } - - private void RemoveAllGeneratedItems() - { - Debug.Assert( this.IsHandlingGlobalItemsReset, "A flag is not set." ); - - //Call RemoveAllGeneratedItems() on all the detail generators - foreach( var generator in this.GetDetailGenerators() ) - { - generator.RemoveAllGeneratedItems(); - } - - //then we can clean the list of items of items generated held by this generator - var genCountRemoved = m_genPosToNode.Count; - - //start from the end so that removing an item will not cause the indexes to shift - for( int i = genCountRemoved - 1; i >= 0; i-- ) - { - var node = m_genPosToNode[ i ]; - var container = m_genPosToContainer[ i ]; - - //if item is NOT a detail - if( !( node is DetailGeneratorNode ) ) - { - // Clear it. - this.RemoveContainer( container, m_genPosToItem[ i ] ); - } - - //Note: there is no need to call "RemoveContainer" on the "detail" items... since RemoveAllGeneratedItems() was called - // on all detail generators already. - this.GenPosArraysRemoveAt( i ); - } - } - - private bool RemoveGeneratedItems( HeadersFootersGeneratorNode referenceNode, object referenceItem, IList removedContainers ) - { - - //cycle through the list of generated items, and see if any items are generated between the indexes in the removed range. - //start from the end so that removing an item will not cause the indexes to shift - for( int i = m_genPosToNode.Count - 1; i >= 0; i-- ) - { - var node = m_genPosToNode[ i ]; - - //if the item is within the range removed - if( node == referenceNode ) - { - var item = m_genPosToItem[ i ]; - - if( item.Equals( referenceItem ) ) - { - var container = m_genPosToContainer[ i ]; - - if( removedContainers != null ) - { - removedContainers.Add( container ); - } - - this.RemoveContainer( container, referenceItem ); - this.GenPosArraysRemoveAt( i ); - - return true; - } - } - } - - return false; - } - - private void RemoveContainer( DependencyObject container, object dataItem ) - { - m_dataGridControl.ClearItemContainer( container, dataItem ); - - var isContainerRecycled = false; - - if( this.IsRecyclingEnabled ) - { - isContainerRecycled = this.EnqueueContainer( container, dataItem ); - - var dataItemStore = container.ReadLocalValue( CustomItemContainerGenerator.DataItemPropertyProperty ) as DataItemDataProviderBase; - if( dataItemStore != null ) - { - dataItemStore.ClearDataItem(); - } - } - - //If recycling is not enabled, or if the container could not be enqueued, make sure it is removed from the DataGridItemsHost's child collection. - if( !isContainerRecycled ) - { - Debug.Assert( container != null ); - this.OnContainersRemoved( new DependencyObject[] { container } ); - } - } - - private void RemoveDetailContainers( IEnumerable containers ) - { - if( containers == null ) - return; - - var toRemove = new HashSet( containers ); - if( toRemove.Count <= 0 ) - return; - - for( int i = m_genPosToContainer.Count - 1; i >= 0; i-- ) - { - if( !toRemove.Contains( m_genPosToContainer[ i ] ) ) - continue; - - this.GenPosArraysRemoveAt( i ); - } - } - - private void GenPosArraysRemoveAt( int index ) - { - //remove the item from the 4 lists... (same as doing a "remove") - var itemsNode = m_genPosToNode[ index ] as ItemsGeneratorNode; - - // Unlock DataVirtualization hold on item's page. - if( itemsNode != null ) - { - this.UpdateDataVirtualizationLockForItemsNode( itemsNode, m_genPosToItem[ index ], false ); - } - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_GenPosArraysRemoveAt, DataGridTraceMessages.ContainerRemoved, DataGridTraceArgs.Container( m_genPosToContainer[ index ] ), DataGridTraceArgs.Node( m_genPosToNode[ index ] ), DataGridTraceArgs.Item( m_genPosToItem[ index ] ), DataGridTraceArgs.GeneratorIndex( index ), DataGridTraceArgs.Index( m_genPosToIndex[ index ] ) ); - - m_genPosToContainer.RemoveAt( index ); - m_genPosToIndex.RemoveAt( index ); - m_genPosToItem.RemoveAt( index ); - m_genPosToNode.RemoveAt( index ); - } - - private void UpdateHeaders( IList headers ) - { - //If the m_firstHeader is not NULL, then there is nothing to do, since the Header node contains an observable collection - //which we monitor otherwise. - if( m_firstHeader != null ) - return; - - //create the node(s) that would contain the headers - m_firstHeader = this.CreateHeaders( headers ); - - int count; - int chainLength; - GeneratorNodeHelper.EvaluateChain( m_firstHeader, out count, out chainLength ); - - //if there was items present in the linked list. - if( m_startNode != null ) - { - //headers are automatically inserted at the beginning - var nodeHelper = new GeneratorNodeHelper( m_startNode, 0, 0 ); - nodeHelper.InsertBefore( m_firstHeader ); - } - else - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_UpdateHeaders, DataGridTraceMessages.NewTreeCreated, DataGridTraceArgs.Node( m_firstHeader ) ); - } - - //set the start node as the first header node. - m_startNode = m_firstHeader; - - this.InvalidateNodeTree(); - } - - private void UpdateFooters( IList footers ) - { - //If the m_firstHeader is not NULL, then there is nothing to do, since the Header node contains an observable collection - //which we monitor otherwise. - if( m_firstFooter != null ) - return; - - //create the node(s) that would contain the footers - m_firstFooter = this.CreateFooters( footers ); - - //if there are no footers, then the m_firstFooter will remain null - if( m_firstFooter != null ) - { - int count; - int chainLength; - GeneratorNodeHelper.EvaluateChain( m_firstFooter, out count, out chainLength ); - - //if there was items present in the linked list. - if( m_startNode != null ) - { - //since we called ClearFooters earlier, I can just go at the end of the list of items - GeneratorNodeHelper nodeHelper = new GeneratorNodeHelper( m_startNode, 0, 0 ); - - nodeHelper.MoveToEnd(); - nodeHelper.InsertAfter( m_firstFooter ); - } - else - { - m_startNode = m_firstFooter; - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_UpdateFooters, DataGridTraceMessages.NewStartNode, DataGridTraceArgs.Node( m_startNode ) ); - } - } - - this.InvalidateNodeTree(); - } - - private HeadersFootersGeneratorNode CreateHeaders( IList headers ) - { - return this.NodeFactory.CreateHeadersFootersGeneratorNode( headers, null, null, null ); - } - - private HeadersFootersGeneratorNode CreateFooters( IList footers ) - { - return this.NodeFactory.CreateHeadersFootersGeneratorNode( footers, null, null, null ); - } - - private GeneratorNode SetupInitialItemsNodes( out int addCount ) - { - addCount = 0; - - var newItemNode = default( GeneratorNode ); - - this.RefreshGroupsCollection(); - - //this function should only be called when the m_firstItem is null. - if( m_groupsCollection != null ) - { - newItemNode = this.CreateGroupListFromCollection( m_groupsCollection, null ); - } - else - { - newItemNode = this.CreateStandaloneItemsNode(); - } - - //if the node is non-null, then that's because there was items in the collection - if( newItemNode != null ) - { - m_firstItem = newItemNode; - - int chainLength; - GeneratorNodeHelper.EvaluateChain( m_firstItem, out addCount, out chainLength ); - - //find the appropriate point to inject the Items nodes... - if( m_startNode != null ) - { - //if there is a footer node, then the insertion point is just before the footer node (if there is anything before!) - if( m_firstFooter != null ) - { - var originalPrevious = m_firstFooter.Previous; - var nodeHelper = new GeneratorNodeHelper( m_firstFooter, 0, 0 ); //do not care about index! - - nodeHelper.InsertBefore( m_firstItem ); - - if( originalPrevious == null ) //that means that the first footer is the first item - { - m_startNode = newItemNode; - } - } - else if( m_firstHeader != null ) //if there is no footer but some headers, add it at the end. - { - var nodeHelper = new GeneratorNodeHelper( m_firstHeader, 0, 0 ); //do not care about index! - - nodeHelper.MoveToEnd(); - nodeHelper.InsertAfter( m_firstItem ); - } - else - { - //this case should not be possible: no header, no footers but there is a startNode - throw DataGridException.Create( "No start node found for the current GeneratorNode.", m_dataGridControl ); - } - } - else - { - m_startNode = m_firstItem; - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_SetupInitialItemsNodes, DataGridTraceMessages.NewStartNode, DataGridTraceArgs.Node( m_startNode ) ); - } - - this.InvalidateNodeTree(); - } - - return newItemNode; - } - - private void RefreshGroupsCollection() - { - var groupsCollection = m_collectionView.Groups; - if( m_groupsCollection == groupsCollection ) - return; - - if( m_groupsCollection != null ) - { - CollectionChangedEventManager.RemoveListener( m_groupsCollection, this ); - } - - m_groupsCollection = groupsCollection; - - if( m_groupsCollection != null ) - { - CollectionChangedEventManager.AddListener( m_groupsCollection, this ); - } - } - - private GeneratorNode CreateStandaloneItemsNode() - { - var list = CustomItemContainerGenerator.GetList( m_collectionView ); - - return this.NodeFactory.CreateItemsGeneratorNode( list, null, null, null ); - } - - private GeneratorNode CreateGroupListFromCollection( IList collection, GeneratorNode parentNode ) - { - if( collection.Count == 0 ) - return null; - - var rootNode = default( GeneratorNode ); - var previousNode = default( GeneratorNode ); - var actualNode = default( GroupGeneratorNode ); - var childNode = default( GeneratorNode ); - var level = ( parentNode == null ) ? 0 : parentNode.Level + 1; - - GroupConfiguration groupConfig; - bool initiallyExpanded; - - var groupDescriptions = DataGridContext.GetGroupDescriptionsHelper( m_collectionView ); - var groupConfigurationSelector = m_dataGridContext.GroupConfigurationSelector; - var lateGroupLevelDescription = this.CreateOrGetLateGroupLevelDescription( level, groupDescriptions ); - - foreach( CollectionViewGroup group in collection ) - { - groupConfig = GroupConfiguration.GetGroupConfiguration( m_dataGridContext, groupDescriptions, groupConfigurationSelector, level, group ); - Debug.Assert( groupConfig != null ); - - if( groupConfig.UseDefaultHeadersFooters ) - { - groupConfig.AddDefaultHeadersFooters(); - } - - initiallyExpanded = groupConfig.InitiallyExpanded; - - actualNode = ( GroupGeneratorNode )this.NodeFactory.CreateGroupGeneratorNode( group, parentNode, previousNode, null, groupConfig ); - actualNode.UIGroup = new Group( actualNode, group, lateGroupLevelDescription, m_dataGridContext ); - - m_groupNodeMappingCache.Add( group, actualNode ); - - if( rootNode == null ) - { - rootNode = actualNode; - } - - previousNode = actualNode; - - //Independently if the Group is the bottom level or not, we need to setup GroupHeaders - childNode = this.SetupGroupHeaders( groupConfig, actualNode ); - actualNode.Child = childNode; - - var childNodeHelper = new GeneratorNodeHelper( childNode, 0, 0 ); //do not care about index. - childNodeHelper.MoveToEnd(); //extensibility, just in case SetupGroupHeaders() ever return a node list. - - var subItems = group.GetItems(); - - //if the node newly created is not the bottom level - if( !group.IsBottomLevel ) - { - if( ( subItems != null ) && ( subItems.Count > 0 ) ) - { - var subGroupsNode = this.CreateGroupListFromCollection( subItems as IList, actualNode ); - if( subGroupsNode != null ) - { - childNodeHelper.InsertAfter( subGroupsNode ); - } - } - } - else - { - //this is the bottom level, create an Items node - var itemsNode = this.NodeFactory.CreateItemsGeneratorNode( subItems as IList, actualNode, null, null ); - if( itemsNode != null ) - { - childNodeHelper.InsertAfter( itemsNode ); - } - } - - childNodeHelper.InsertAfter( this.SetupGroupFooters( groupConfig, actualNode ) ); - } - - return rootNode; - } - - private LateGroupLevelDescription CreateOrGetLateGroupLevelDescription( int level, IList groupDescriptions ) - { - Debug.Assert( groupDescriptions != null ); - - if( ( m_groupLevelDescriptionCache == null ) || ( level >= m_groupLevelDescriptionCache.Length ) ) - { - var newSize = Math.Max( level + 1, groupDescriptions.Count ); - Array.Resize( ref m_groupLevelDescriptionCache, newSize ); - } - - var item = m_groupLevelDescriptionCache[ level ]; - if( item == null ) - { - var groupDescription = groupDescriptions[ level ]; - Debug.Assert( groupDescription != null ); - - item = new LateGroupLevelDescription( groupDescription, m_dataGridContext.GroupLevelDescriptions ); - m_groupLevelDescriptionCache[ level ] = item; - } - - return item; - } - - private void ClearLateGroupLevelDescriptions() - { - if( m_groupLevelDescriptionCache == null ) - return; - - for( int i = 0; i < m_groupLevelDescriptionCache.Length; i++ ) - { - var item = m_groupLevelDescriptionCache[ i ]; - if( item == null ) - continue; - - item.Clear(); - } - - m_groupLevelDescriptionCache = null; - } - - private GeneratorNode SetupGroupFooters( GroupConfiguration groupConfig, GeneratorNode actualNode ) - { - if( groupConfig == null ) - return new GeneratorNode( actualNode ); - - return this.NodeFactory.CreateHeadersFootersGeneratorNode( groupConfig.Footers, actualNode, null, null ); - } - - private GeneratorNode SetupGroupHeaders( GroupConfiguration groupConfig, GeneratorNode actualNode ) - { - if( groupConfig == null ) - return new GeneratorNode( actualNode ); - - return this.NodeFactory.CreateHeadersFootersGeneratorNode( groupConfig.Headers, actualNode, null, null ); - } - - private void HandleParentGroupRemove( GeneratorNode parent, out int countRemoved, NotifyCollectionChangedEventArgs e, IList removedContainers ) - { - var nodeHelper = new GeneratorNodeHelper( parent, 0, 0 ); //do not care about index (for now). - - // start by moving to the first child... of the node (GroupHeaders node, most probably). - // false parameter is to prevent skipping over a collapsed node (item count 0 ) - if( !nodeHelper.MoveToChild( false ) ) - //could not advance to the child item so there is no items to be removed... - throw DataGridException.Create( "No child item in the group to remove.", m_dataGridControl ); - - this.HandleSameLevelGroupRemove( nodeHelper.CurrentNode, out countRemoved, e, removedContainers ); - } - - private void HandleSameLevelGroupRemove( GeneratorNode firstChild, out int countRemoved, NotifyCollectionChangedEventArgs e, IList removedContainers ) - { - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_HandleSameLevelGroupRemove ) ) - { - countRemoved = 0; - - var nodeHelper = new GeneratorNodeHelper( firstChild, 0, 0 ); - nodeHelper.ReverseCalculateIndex(); - - //Advance to the first "Group" node (skip the GroupHeaders) - while( !( nodeHelper.CurrentNode is GroupGeneratorNode ) ) - { - if( !nodeHelper.MoveToNext() ) - throw DataGridException.Create( "Unable to move to next GeneratorNode.", m_dataGridControl ); - } - - //then move up to the removal start point. - if( !nodeHelper.MoveToNextBy( e.OldStartingIndex ) ) - throw DataGridException.Create( "Unable to move to the requested generator index.", m_dataGridControl ); - - var startNode = nodeHelper.CurrentNode as GroupGeneratorNode; - var removeIndex = -1; - - //Only fetch the index if the group itself is not "collapsed" or under a collapsed group already - if( ( startNode.IsExpanded == startNode.IsComputedExpanded ) && ( startNode.ItemCount > 0 ) ) - { - removeIndex = nodeHelper.Index; - } - - //retrieve the generator position for the first item to remove. - this.ProcessGroupRemoval( startNode, e.OldItems.Count, true, out countRemoved ); - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_HandleSameLevelGroupRemove, DataGridTraceMessages.GroupNodeRemoved, DataGridTraceArgs.Node( startNode ), DataGridTraceArgs.ItemCount( countRemoved ) ); - - //Clean the chain "isolated" previously - this.NodeFactory.CleanGeneratorNodeTree( startNode ); - - if( removeIndex >= 0 ) - { - this.RemoveGeneratedItems( removeIndex, removeIndex + countRemoved - 1, removedContainers ); - } - } - } - - private GroupGeneratorNode ProcessGroupRemoval( GeneratorNode startNode, int removeCount, bool updateGroupNodeMappingCache, out int countRemoved ) - { - countRemoved = 0; - - var nodeHelper = new GeneratorNodeHelper( startNode, 0, 0 ); //index not important. - var parentGroup = startNode.Parent as GroupGeneratorNode; - var i = 0; - - do - { - var group = nodeHelper.CurrentNode as GroupGeneratorNode; - if( group == null ) - { - this.TraceEvent( TraceEventType.Warning, DataGridTraceEventId.CustomItemContainerGenerator_ProcessGroupRemoval, DataGridTraceMessages.UnexpectedNode, DataGridTraceArgs.Node( nodeHelper.CurrentNode ) ); - } - else - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_ProcessGroupRemoval, DataGridTraceMessages.GroupNodeRemoved, DataGridTraceArgs.Node( group ), DataGridTraceArgs.ItemCount( group.ItemCount ) ); - } - - if( updateGroupNodeMappingCache ) - { - m_groupNodeMappingCache.Remove( group.CollectionViewGroup ); - } - - //add the total number of child to the count of items removed. - countRemoved += group.ItemCount; - - i++; - - if( i < removeCount ) - { - if( !nodeHelper.MoveToNext() ) - throw DataGridException.Create( "Could not move to the last node to be removed.", m_dataGridControl ); - } - } - while( i < removeCount ); - - //disconnect the node chain to be removed from the linked list. - var previous = startNode.Previous; - var next = nodeHelper.CurrentNode.Next; - - if( next != null ) - { - next.Previous = previous; - } - - if( previous != null ) - { - previous.Next = next; - } - - //if the first node removed was the first child of its parent - if( ( parentGroup != null ) && ( parentGroup.Child == startNode ) ) - { - //set the next in line after the chain to be removed as the first child - parentGroup.Child = next; - } - - //break the link between the chain and its same-level siblings. - nodeHelper.CurrentNode.Next = null; - startNode.Previous = null; - - //Here, I need a special handling case... If I remove the first group node, I need to set a new firstItem - if( startNode == m_firstItem ) - { - if( next != m_firstFooter ) - { - m_firstItem = next; - } - else - { - m_firstItem = null; - } - - if( m_startNode == startNode ) - { - m_startNode = next; - } - - this.InvalidateNodeTree(); - } - - if( !( nodeHelper.CurrentNode is GroupGeneratorNode ) ) - { - this.TraceEvent( TraceEventType.Warning, DataGridTraceEventId.CustomItemContainerGenerator_ProcessGroupRemoval, DataGridTraceMessages.UnexpectedNode, DataGridTraceArgs.LastNode( nodeHelper.CurrentNode ) ); - } - - return ( GroupGeneratorNode )nodeHelper.CurrentNode; - } - - private void HandleSameLevelGroupReset( GeneratorNode node ) - { - Debug.Assert( node != null ); - - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_HandleSameLevelGroupReset ) ) - { - var parentNode = node.Parent as GroupGeneratorNode; - var oldGroups = new List(); - var nodeHelper = new GeneratorNodeHelper( node, 0, 0 ); - - do - { - var groupNode = nodeHelper.CurrentNode as GroupGeneratorNode; - if( groupNode != null ) - { - Debug.Assert( groupNode.CollectionViewGroup != null ); - oldGroups.Add( groupNode.CollectionViewGroup ); - } - } - while( nodeHelper.MoveToNext() ); - - var newGroups = ( parentNode != null ) - ? parentNode.CollectionViewGroup.GetItems().Cast().ToList() - : m_groupsCollection.Cast().ToList(); - - // If nothing has changed, avoid the heavy process of finding out which groups have been added, - // removed and moved. - if( newGroups.Count == oldGroups.Count ) - { - if( newGroups.SequenceEqual( oldGroups ) ) - return; - } - - var groupsAdded = new HashSet(); - var groupsRemoved = new HashSet(); - var groupsMoved = new HashSet(); - - CustomItemContainerGenerator.FindChanges( oldGroups, newGroups, groupsAdded, groupsRemoved, groupsMoved ); - this.ApplyGroupChanges( node, oldGroups, newGroups, groupsAdded, groupsRemoved, groupsMoved ); - } - } - - private void ApplyGroupChanges( - GeneratorNode node, - IList oldGroups, - IList newGroups, - ICollection groupsAdded, - ICollection groupsRemoved, - ICollection groupsMoved ) - { - Debug.Assert( node != null ); - - var parentNode = node.Parent as GroupGeneratorNode; - var insertAfter = !( node is GroupGeneratorNode ); - - if( ( groupsRemoved.Count > 0 ) || ( groupsMoved.Count > 0 ) ) - { - var removeNodeHelper = new GeneratorNodeHelper( m_groupNodeMappingCache[ oldGroups.Last() ], 0, 0 ); - removeNodeHelper.ReverseCalculateIndex(); - - for( int i = oldGroups.Count - 1; i >= 0; i-- ) - { - var group = oldGroups[ i ]; - var removed = groupsRemoved.Contains( group ); - var moved = ( !removed && groupsMoved.Contains( group ) ); - - if( removed || moved ) - { - var groupNode = removeNodeHelper.CurrentNode; - Debug.Assert( ( groupNode != null ) && ( groupNode == m_groupNodeMappingCache[ group ] ) ); - - if( groupNode == node ) - { - Debug.Assert( !( groupNode.Previous is GroupGeneratorNode ), "How come the node was not the first GroupGeneratorNode." ); - - node = groupNode.Next; - insertAfter = false; - } - - var startIndex = removeNodeHelper.Index; - int count; - - removeNodeHelper.MoveToPrevious(); - - if( removed ) - { - this.ProcessGroupRemoval( groupNode, 1, true, out count ); - this.NodeFactory.CleanGeneratorNodeTree( groupNode ); - } - else - { - this.ProcessGroupRemoval( groupNode, 1, false, out count ); - } - - if( count > 0 ) - { - this.RemoveGeneratedItems( startIndex, startIndex + count - 1, null ); - } - } - else - { - removeNodeHelper.MoveToPrevious(); - } - } - } - - if( ( groupsAdded.Count > 0 ) || ( groupsMoved.Count > 0 ) ) - { - var firstGroup = newGroups[ 0 ]; - var added = groupsAdded.Contains( firstGroup ); - var moved = ( !added && groupsMoved.Contains( firstGroup ) ); - - if( added || moved ) - { - var groupNode = default( GeneratorNode ); - - if( added ) - { - groupNode = this.CreateGroupListFromCollection( new object[] { firstGroup }, parentNode ); - } - else - { - groupNode = m_groupNodeMappingCache[ firstGroup ]; - } - - Debug.Assert( groupNode != null ); - - if( node != null ) - { - var addNodeHelper = new GeneratorNodeHelper( node, 0, 0 ); - - if( insertAfter ) - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_ApplyGroupChanges, DataGridTraceMessages.GroupNodeAdded, DataGridTraceArgs.Node( groupNode ), DataGridTraceArgs.PreviousNode( addNodeHelper.CurrentNode ) ); - addNodeHelper.InsertAfter( groupNode ); - } - else - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_ApplyGroupChanges, DataGridTraceMessages.GroupNodeAdded, DataGridTraceArgs.Node( groupNode ), DataGridTraceArgs.NextNode( addNodeHelper.CurrentNode ) ); - addNodeHelper.InsertBefore( groupNode ); - insertAfter = true; - } - - if( parentNode == null ) - { - if( m_startNode == m_firstItem ) - { - m_startNode = groupNode; - } - - m_firstItem = groupNode; - - this.InvalidateNodeTree(); - } - } - else - { - if( parentNode == null ) - { - m_firstItem = groupNode; - - if( m_startNode != null ) - { - if( m_firstFooter != null ) - { - var addNodeHelper = new GeneratorNodeHelper( m_firstFooter, 0, 0 ); - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_ApplyGroupChanges, DataGridTraceMessages.GroupNodeAdded, DataGridTraceArgs.Node( groupNode ), DataGridTraceArgs.NextNode( addNodeHelper.CurrentNode ) ); - addNodeHelper.InsertBefore( groupNode ); - } - else if( m_firstHeader != null ) - { - var addNodeHelper = new GeneratorNodeHelper( m_firstHeader, 0, 0 ); - addNodeHelper.MoveToEnd(); - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_ApplyGroupChanges, DataGridTraceMessages.GroupNodeAdded, DataGridTraceArgs.Node( groupNode ), DataGridTraceArgs.PreviousNode( addNodeHelper.CurrentNode ) ); - addNodeHelper.InsertAfter( groupNode ); - } - else - { - throw DataGridException.Create( "No start node found for the current GeneratorNode.", m_dataGridControl ); - } - } - else - { - m_startNode = groupNode; - } - - this.InvalidateNodeTree(); - } - else - { - Debug.Assert( parentNode.Child != null ); - - var addNodeHelper = new GeneratorNodeHelper( parentNode.Child, 0, 0 ); - addNodeHelper.MoveToEnd(); - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_ApplyGroupChanges, DataGridTraceMessages.GroupNodeAdded, DataGridTraceArgs.Node( groupNode ), DataGridTraceArgs.PreviousNode( addNodeHelper.CurrentNode ) ); - addNodeHelper.InsertAfter( groupNode ); - } - } - - node = groupNode; - } - - for( var i = 1; i < newGroups.Count; i++ ) - { - var group = newGroups[ i ]; - - added = groupsAdded.Contains( group ); - moved = ( !added && groupsMoved.Contains( group ) ); - - if( !added && !moved ) - continue; - - var groupNode = default( GeneratorNode ); - - if( added ) - { - groupNode = this.CreateGroupListFromCollection( new object[] { group }, parentNode ); - } - else - { - groupNode = m_groupNodeMappingCache[ group ]; - } - - Debug.Assert( groupNode != null ); - - var addNodeHelper = new GeneratorNodeHelper( m_groupNodeMappingCache[ newGroups[ i - 1 ] ], 0, 0 ); - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_ApplyGroupChanges, DataGridTraceMessages.GroupNodeAdded, DataGridTraceArgs.Node( groupNode ), DataGridTraceArgs.PreviousNode( addNodeHelper.CurrentNode ) ); - addNodeHelper.InsertAfter( groupNode ); - } - } - - this.IncrementCurrentGenerationCount(); - this.SendResetEvent(); - } - - private void HandleSameLevelGroupMove( GeneratorNode node, NotifyCollectionChangedEventArgs e ) - { - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_HandleSameLevelGroupMove ) ) - { - var parentGroup = node.Parent as GroupGeneratorNode; - - //Start a NodeHelper on the first child of the node where the move occured. - var nodeHelper = new GeneratorNodeHelper( node, 0, 0 ); - nodeHelper.ReverseCalculateIndex(); //determine index of the node. - - //Advance to the first "Group" node (skip the GroupHEaders) - while( !( nodeHelper.CurrentNode is GroupGeneratorNode ) ) - { - if( !nodeHelper.MoveToNext() ) - throw DataGridException.Create( "Unable to move to next GeneratorNode.", m_dataGridControl ); - } - - //then move up to the removal start point. - if( !nodeHelper.MoveToNextBy( e.OldStartingIndex ) ) - throw DataGridException.Create( "Unable to move to the requested generator index.", m_dataGridControl ); - - //remember the current node as the start point of the move (will be used when "extracting the chain") - var startNode = nodeHelper.CurrentNode; - //also remember the index of the node, to calculate range of elements to remove (containers ) - var startIndex = nodeHelper.Index; - - //then, cumulate the total number of items in the groups concerned - var totalCountRemoved = 0; - - node = this.ProcessGroupRemoval( startNode, e.OldItems.Count, false, out totalCountRemoved ); - - //send a message to the panel to remove the visual elements concerned - var containers = new List(); - - this.RemoveGeneratedItems( startIndex, startIndex + totalCountRemoved - 1, containers ); - this.SendRemoveEvent( totalCountRemoved, containers ); - - //reset the node parameter for the "re-addition" - node = ( parentGroup != null ) ? parentGroup.Child : m_firstItem; - - if( node == null ) - throw DataGridException.Create( "No node found to move.", m_dataGridControl ); - - //Once the chain was pulled out, re-insert it at the appropriate location. - nodeHelper = new GeneratorNodeHelper( node, 0, 0 ); //do not care about the index for what I need - - //Advance to the first "Group" node (skip the GroupHEaders) - while( !( nodeHelper.CurrentNode is GroupGeneratorNode ) ) - { - if( !nodeHelper.MoveToNext() ) - throw DataGridException.Create( "Unable to move to next GeneratorNode.", m_dataGridControl ); - } - - bool insertBefore = nodeHelper.MoveToNextBy( e.NewStartingIndex ); - - if( insertBefore ) - { - if( nodeHelper.CurrentNode == m_firstItem ) - { - if( m_startNode == m_firstItem ) - { - m_startNode = startNode; - } - - m_firstItem = startNode; - - this.InvalidateNodeTree(); - } - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_HandleSameLevelGroupMove, DataGridTraceMessages.GroupNodeAdded, DataGridTraceArgs.Node( startNode ), DataGridTraceArgs.NextNode( nodeHelper.CurrentNode ), DataGridTraceArgs.ItemCount( totalCountRemoved ) ); - nodeHelper.InsertBefore( startNode ); - } - else - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_HandleSameLevelGroupMove, DataGridTraceMessages.GroupNodeAdded, DataGridTraceArgs.Node( startNode ), DataGridTraceArgs.PreviousNode( nodeHelper.CurrentNode ), DataGridTraceArgs.ItemCount( totalCountRemoved ) ); - nodeHelper.InsertAfter( startNode ); - } - - //and finally, call to increment the generation count for the generator content - this.IncrementCurrentGenerationCount(); - } - } - - private void HandleSameLevelGroupAddition( GeneratorNode firstChild, out int countAdded, NotifyCollectionChangedEventArgs e ) - { - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_HandleSameLevelGroupAddition ) ) - { - if( ( firstChild.Parent != null ) && !( firstChild.Parent is GroupGeneratorNode ) ) - { - this.TraceEvent( TraceEventType.Error, DataGridTraceEventId.CustomItemContainerGenerator_HandleSameLevelGroupAddition, DataGridTraceMessages.UnexpectedNode, DataGridTraceArgs.Node( firstChild.Parent ) ); - } - - var newNodeChain = this.CreateGroupListFromCollection( e.NewItems, firstChild.Parent ); - - countAdded = 0; - if( newNodeChain != null ) - { - int chainLength; - GeneratorNodeHelper.EvaluateChain( newNodeChain, out countAdded, out chainLength ); - - var nodeHelper = default( GeneratorNodeHelper ); - var insertAfter = false; - - // Instead of counting groups to insert the group chain, we may locate right away the GroupGeneratorNode that - // preceed the insertion point. This will give us a performance boost when there are lots of groups. - if( e.NewStartingIndex > 0 ) - { - IList groups; - - if( firstChild.Parent != null ) - { - var parentGroup = ( ( GroupGeneratorNode )firstChild.Parent ).CollectionViewGroup; - - groups = ( parentGroup != null ) ? parentGroup.Items : null; - } - else - { - groups = m_groupsCollection; - } - - if( ( groups != null ) && ( groups.Count > 0 ) ) - { - Debug.Assert( e.NewStartingIndex <= groups.Count ); - - var previousGroup = ( CollectionViewGroup )groups[ e.NewStartingIndex - 1 ]; - var previousGroupNode = default( GroupGeneratorNode ); - - if( m_groupNodeMappingCache.TryGetValue( previousGroup, out previousGroupNode ) ) - { - nodeHelper = new GeneratorNodeHelper( previousGroupNode, 0, 0 ); //do not care about index. - insertAfter = true; - } - } - } - - // We could not find the insertion point efficiently, use a fallback strategy. - if( nodeHelper == null ) - { - nodeHelper = new GeneratorNodeHelper( firstChild, 0, 0 ); //do not care about index. - - while( !( nodeHelper.CurrentNode is GroupGeneratorNode ) ) - { - if( !nodeHelper.MoveToNext() ) - { - //if there are no items and no groups in the Group Node, then we will never find a GroupGeneratorNode... - //However, the structure of the group/headers/footers/group headers/groups footers makes it so - //that inserting before the last item (footer/group footer) will place the group at the appropriate location. - break; - } - } - - //If there is 0 group in the parent group, then this loop will exit without executing the control block once... - for( int i = 0; i < e.NewStartingIndex; i++ ) - { - if( !nodeHelper.MoveToNext() ) - { - insertAfter = true; - } - } - } - - Debug.Assert( nodeHelper != null ); - - //if we are inserting past the end of the linked list level. - if( insertAfter ) - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_HandleSameLevelGroupAddition, DataGridTraceMessages.GroupNodeAdded, DataGridTraceArgs.Node( newNodeChain ), DataGridTraceArgs.PreviousNode( nodeHelper.CurrentNode ), DataGridTraceArgs.ItemCount( countAdded ) ); - nodeHelper.InsertAfter( newNodeChain ); - } - else - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_HandleSameLevelGroupAddition, DataGridTraceMessages.GroupNodeAdded, DataGridTraceArgs.Node( newNodeChain ), DataGridTraceArgs.NextNode( nodeHelper.CurrentNode ), DataGridTraceArgs.ItemCount( countAdded ) ); - nodeHelper.InsertBefore( newNodeChain ); - } - - - //If the insertion point is the beginning, check that the node pointers are updated properly - if( ( e.NewStartingIndex == 0 ) && ( ( firstChild.Parent == null ) ) ) - { - if( m_startNode == m_firstItem ) - { - m_startNode = newNodeChain; - } - - m_firstItem = newNodeChain; - - this.InvalidateNodeTree(); - } - } - } - } - - private void HandleParentGroupAddition( GeneratorNode parent, out int countAdded, NotifyCollectionChangedEventArgs e ) - { - var nodeHelper = new GeneratorNodeHelper( parent, 0, 0 ); //do not care about index (for now). - - //start by moving to the first child... of the node (GroupHeaders node, most probably). - if( !nodeHelper.MoveToChild( false ) ) - throw DataGridException.Create( "Could not move to the child node to be removed.", m_dataGridControl ); - - this.HandleSameLevelGroupAddition( nodeHelper.CurrentNode, out countAdded, e ); - } - - private void HandleItemAddition( ItemsGeneratorNode node, NotifyCollectionChangedEventArgs e ) - { - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_HandleItemAddition, DataGridTraceArgs.Node( node ) ) ) - { - var nodeHelper = new GeneratorNodeHelper( node, 0, 0 ); //index not important for now. - var itemCount = e.NewItems.Count; - - node.AdjustItemCount( itemCount ); - node.AdjustLeafCount( itemCount ); - this.OffsetDetails( node, e.NewStartingIndex, itemCount ); - - if( node.IsComputedExpanded ) - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_HandleItemAddition, DataGridTraceMessages.ItemAdded, DataGridTraceArgs.ItemCount( itemCount ) ); - - this.IncrementCurrentGenerationCount(); - this.SendAddEvent( itemCount ); - } - else - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_HandleItemAddition, DataGridTraceMessages.CollapsedItemAdded, DataGridTraceArgs.ItemCount( itemCount ) ); - } - } - } - - private void HandleItemRemoveMoveReplace( ItemsGeneratorNode node, NotifyCollectionChangedEventArgs e ) - { - if( e.Action == NotifyCollectionChangedAction.Remove ) - { - node.AdjustItemCount( -e.OldItems.Count ); - node.AdjustLeafCount( -e.OldItems.Count ); - } - - var nodeStartIndex = e.OldStartingIndex; - var nodeEndIndex = nodeStartIndex + e.OldItems.Count - 1; - var detailCountToRemove = CustomItemContainerGenerator.ComputeDetailsCount( node, nodeStartIndex, nodeEndIndex ); - var detailCountBeforeRemovedItems = 0; - - if( nodeStartIndex > 0 ) - { - detailCountBeforeRemovedItems = CustomItemContainerGenerator.ComputeDetailsCount( node, 0, nodeStartIndex - 1 ); - } - - var removeCount = e.OldItems.Count + detailCountToRemove; - var replaceCount = ( e.Action == NotifyCollectionChangedAction.Replace ) ? e.NewItems.Count : 0; - var startIndex = -1; - var endIndex = -1; - - // We must memorize the range of items that we are going to remove before starting any action. - if( node.IsComputedExpanded ) - { - var nodeHelper = new GeneratorNodeHelper( node, 0, 0 ); //index not important for now. - nodeHelper.ReverseCalculateIndex(); - - startIndex = nodeHelper.Index + e.OldStartingIndex + detailCountBeforeRemovedItems; - endIndex = startIndex + detailCountToRemove + e.OldItems.Count - 1; - } - - //Remove the details from the ItemsGeneratorNode and re-index the other details appropriatly. - this.RemoveDetails( node, nodeStartIndex, nodeEndIndex, replaceCount ); - - //Try to remap the old item for detail remapping (will do nothing if item has no details ) - foreach( var oldItem in e.OldItems ) - { - this.QueueDetailItemForRemapping( oldItem ); - } - - var raiseEvent = false; - var removedContainers = default( List ); - - // Remove the matching realized containers. - if( node.IsComputedExpanded ) - { - raiseEvent = true; - removedContainers = new List(); - - Debug.Assert( ( startIndex >= 0 ) && ( endIndex >= 0 ) ); - - this.RemoveGeneratedItems( startIndex, endIndex, removedContainers ); - } - - if( e.Action == NotifyCollectionChangedAction.Move ) - { - this.OffsetDetails( node, e.NewStartingIndex, e.NewItems.Count ); - } - - if( raiseEvent ) - { - Debug.Assert( removedContainers != null ); - - this.IncrementCurrentGenerationCount(); - this.SendRemoveEvent( removeCount, removedContainers ); - - switch( e.Action ) - { - case NotifyCollectionChangedAction.Move: - case NotifyCollectionChangedAction.Replace: - { - this.SendAddEvent( e.NewItems.Count ); - } - break; - - case NotifyCollectionChangedAction.Remove: - // There is nothing to do. - break; - - case NotifyCollectionChangedAction.Add: - case NotifyCollectionChangedAction.Reset: - throw DataGridException.Create( "Add or Reset not supported at the moment on groups.", m_dataGridControl ); - } - } - } - - private void HandleHeadersFootersAddition( IEnumerable nodes, NotifyCollectionChangedEventArgs e ) - { - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_HandleHeadersFootersAddition ) ) - { - var itemCount = e.NewItems.Count; - var notify = false; - - foreach( var node in nodes ) - { - node.AdjustItemCount( itemCount ); - notify = notify || node.IsComputedExpanded; - } - - if( notify ) - { - this.IncrementCurrentGenerationCount(); - - this.SendResetEvent(); - } - else - { - //There is no need to regenerate the containers. However, we still need to update the realized containers source index. - this.UpdateContainersIndex(); - } - } - } - - private void HandleHeadersFootersRemoveMoveReplace( IEnumerable nodes, NotifyCollectionChangedEventArgs e ) - { - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_HandleHeadersFootersRemoveMoveReplace ) ) - { - Debug.Assert( e.OldItems != null ); - - var itemCount = ( ( e.NewItems != null ) ? e.NewItems.Count : 0 ) - e.OldItems.Count; - var notify = false; - - foreach( var node in nodes ) - { - node.AdjustItemCount( itemCount ); - - if( node.IsComputedExpanded ) - { - notify = true; - - var parentGroup = node.Parent as GroupGeneratorNode; - - foreach( var item in e.OldItems ) - { - var targetItem = ( parentGroup != null ) ? new GroupHeaderFooterItem( parentGroup.CollectionViewGroup, item ) : item; - - this.RemoveGeneratedItems( node, targetItem, null ); - } - } - } - - if( notify ) - { - this.IncrementCurrentGenerationCount(); - - this.SendResetEvent(); - } - else - { - //There is no need to regenerate the containers. However, we still need to update the realized containers source index. - this.UpdateContainersIndex(); - } - } - } - - private void UpdateContainersIndex() - { - if( ( m_startNode == null ) || ( m_genPosToItem.Count <= 0 ) ) - return; - - var collectionView = m_collectionView.SourceCollection as DataGridCollectionView; - if( collectionView != null ) - { - for( int i = 0; i < m_genPosToItem.Count; i++ ) - { - // If we're not on an ItemsGeneratorNode, it means we are not on a DataRow, so no need to process it (all ItemIndex == -1 in this case). - if( !( m_genPosToNode[ i ] is ItemsGeneratorNode ) ) - continue; - - // There is no need to find the node or the item within the node since it should match the CollectionView. - var sourceIndex = collectionView.GetGlobalSortedIndexFromDataItem( m_genPosToItem[ i ] ); - - DataGridVirtualizingPanel.SetItemIndex( m_genPosToContainer[ i ], sourceIndex ); - } - } - else - { - var nodeHelper = new GeneratorNodeHelper( m_startNode, 0, 0 ); - - for( int i = 0; i < m_genPosToItem.Count; i++ ) - { - // If we're not on an ItemsGeneratorNode, it means we are not on a DataRow, so no need to process it (all ItemIndex == -1 in this case). - var node = m_genPosToNode[ i ] as ItemsGeneratorNode; - if( node == null ) - continue; - - int offset = -1; - - if( nodeHelper.FindNode( node ) && ( nodeHelper.FindItem( m_genPosToItem[ i ] ) >= 0 ) ) - { - offset = node.IndexOf( m_genPosToItem[ i ] ); - } - - // If not a DGCV, it means there are no details, so this will work fine. - var sourceIndex = ( offset >= 0 ) - ? nodeHelper.SourceDataIndex + offset - : -1; - - DataGridVirtualizingPanel.SetItemIndex( m_genPosToContainer[ i ], sourceIndex ); - } - } - } - - private void OffsetDetails( ItemsGeneratorNode node, int startIndex, int addOffset ) - { - if( ( node.Details == null ) || ( node.Details.Count == 0 ) ) - return; - - var detailsCount = node.Details.Count; - var keys = new int[ detailsCount ]; - node.Details.Keys.CopyTo( keys, 0 ); - - Array.Sort( keys ); - - for( int i = detailsCount - 1; i >= 0; i-- ) - { - var key = keys[ i ]; - if( key >= startIndex ) - { - List details; - if( !node.Details.TryGetValue( key, out details ) ) - throw DataGridException.Create( "Key not found in Details dictionary.", m_dataGridControl ); - - node.Details.Remove( key ); - node.Details.Add( key + addOffset, details ); - } - } - } - - private void RemoveDetails( ItemsGeneratorNode node, int nodeStartIndex, int nodeEndIndex, int replaceCount ) - { - if( ( node.Details == null ) || ( node.Details.Count == 0 ) ) - return; - - var removeCount = nodeEndIndex - nodeStartIndex + 1 - replaceCount; - //Note: If a replace was invoked, replace count will be greater than 0, and will be used to properly re-offset the - //details beyond the initial remove range. - - //Note2: for the case of a move or remove, the replace count must remain 0, so that the other details are correctly offseted. - - var keys = new int[ node.Details.Count ]; - node.Details.Keys.CopyTo( keys, 0 ); - - Array.Sort( keys ); - - var countDetailsRemoved = 0; - - foreach( int key in keys ) - { - //if the key is below the remove range, do not do anything with the dictionary entry - - //If the key match the remove range, remove the dictionary entry ( clear and queue remap ) - if( ( key >= nodeStartIndex ) && ( key <= nodeEndIndex ) ) - { - List details; - if( node.Details.TryGetValue( key, out details ) ) - { - //sum them - foreach( var detailNode in details ) - { - countDetailsRemoved += detailNode.ItemCount; - } - details.Clear(); //note: detail generators will be "closed" by another section of code (Remap floating details). - - node.Details.Remove( key ); - - if( node.Details.Count == 0 ) - { - node.Details = null; - } - } - else - { - //Key not found in the dictionary, something wrong is going on. - throw DataGridException.Create( "Key not found in Details dictionary within the remove range.", m_dataGridControl ); - } - } - //If the key is above the remove range, re-key it appropriatly. - else if( key > nodeEndIndex ) - { - List details; - if( node.Details.TryGetValue( key, out details ) ) - { - node.Details.Remove( key ); - node.Details.Add( key - removeCount, details ); - } - else - { - //Key not found in the dictionary, something wrong is going on. - throw DataGridException.Create( "Key not found in Details dictionary above the remove range.", m_dataGridControl ); - } - } - } - - //if some details have been "disconnected" - if( countDetailsRemoved > 0 ) - { - node.AdjustItemCount( -countDetailsRemoved ); - } - } - - private static int ComputeDetailsCount( ItemsGeneratorNode node, int startIndex, int endIndex ) - { - int detailCount = 0; - - if( node.Details != null ) - { - //add the detail grids for the items into the calculation of what to remove. - for( int i = startIndex; i <= endIndex; i++ ) - { - List details; - if( node.Details.TryGetValue( i, out details ) ) - { - foreach( var detailNode in details ) - { - detailCount += detailNode.ItemCount; - } - } - } - } - - return detailCount; - } - - private void HandleItemReset( ItemsGeneratorNode node ) - { - Debug.Assert( node != null ); - - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_HandleItemReset ) ) - { - var oldItems = new List(); - var newItems = new IListWrapper( node.Items ); - var oldItemsFound = new HashSet(); - - for( int i = 0; i < m_genPosToNode.Count; i++ ) - { - var currentNode = m_genPosToNode[ i ]; - var currentItem = default( object ); - - if( currentNode == node ) - { - currentItem = m_genPosToItem[ i ]; - } - // Since some details of an unrealized item may be realized, we need to consider the unrealized - // item as if it was realized or the details containers may not be properly ordered in the - // internal data structure. - else if( currentNode is DetailGeneratorNode ) - { - currentItem = ( ( DetailGeneratorNode )currentNode ).DetailContext.ParentItem; - } - else - { - continue; - } - - Debug.Assert( currentItem != null ); - if( !oldItemsFound.Add( currentItem ) ) - continue; - - oldItems.Add( currentItem ); - } - - ICollection itemsRemoved; - ICollection itemsMoved; - - if( this.IsDataVirtualized( node ) ) - { - // Since the items collection is doning data virtualization, we do not want to enumerate items. - // Instead, we will simply remove the containers that were linked to old items to requery the items - // on demand. - itemsRemoved = new HashSet( oldItems ); - itemsMoved = new HashSet(); - } - else - { - itemsRemoved = new HashSet(); - itemsMoved = new HashSet(); - - // Since the old items collection contains only items that are realized, we must be aware - // that the collections for the items moved or removed are for realized items only. Other - // items may have moved or were removed and we are not aware of it. - CustomItemContainerGenerator.FindChanges( oldItems, newItems, null, itemsRemoved, itemsMoved ); - } - - this.ApplyItemChanges( node, newItems, itemsRemoved, itemsMoved ); - } - } - - private void HandleGlobalItemsReset() - { - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_HandleGlobalItemsReset ) ) - { - this.ForceReset = false; - - if( this.IsHandlingGlobalItemsResetLocally ) - { - this.TraceEvent( TraceEventType.Warning, DataGridTraceEventId.CustomItemContainerGenerator_HandleGlobalItemsReset, DataGridTraceMessages.CannotProcessOnReset ); - return; - } - - if( m_startNode == null ) - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_HandleGlobalItemsReset, DataGridTraceMessages.EmptyTree ); - return; - } - - using( this.SetIsHandlingGlobalItemsResetLocally() ) - { - this.RemoveAllGeneratedItems(); - - //No need to clean any more Master/Detail stuff, effectivelly, the call to ClearItems() below will clean the nodes themselves... - //generator will then be able to remap. - - //if there are items to start with!!! - if( m_firstItem != null ) - { - m_dataGridControl.SaveDataGridContextState( m_dataGridContext, true, int.MaxValue ); - - //requeue all opened details for remapping! - foreach( object item in m_masterToDetails.Keys ) - { - this.QueueDetailItemForRemapping( item ); - } - - //then clear the items nodes - this.ClearItems(); - this.RefreshGroupsCollection(); - - //increment the generation count... to ensure that further calls to the index based functions are not messed up. - this.IncrementCurrentGenerationCount(); - - //Note: There is no need to Clear the recyclingManager since this only represents a reset of the Items (not the headers and footers nodes) - //and that the list of containers to be recycled is not "invalidated" - - } - - this.SendResetEvent(); - } - } - } - - private void ApplyItemChanges( - ItemsGeneratorNode node, - IList newItems, - ICollection itemsRemoved, - ICollection itemsMoved ) - { - Debug.Assert( node != null ); - Debug.Assert( newItems != null ); - Debug.Assert( itemsRemoved != null ); - Debug.Assert( itemsMoved != null ); - - // IMPORTANT: The items removed and moved collection contains realized items that have moved - // or have been removed. It is possible that some of the items that were not - // realized have moved or have been removed and we are unaware of it. We must - // consider this possibility in the following algorithm. - - var detailEntries = node.Details; - var detailNodes = new HashSet(); - var detailNodesByItem = new Dictionary>(); - var isDataVirtualized = this.IsDataVirtualized( node ); - - // The first thing to do is to remove all details that are linked to items that are not in the final result set. - if( detailEntries != null ) - { - var itemCount = 0; - - foreach( var detailEntry in detailEntries.ToList() ) - { - var i = 0; - var detailList = detailEntry.Value; - - while( i < detailList.Count ) - { - var detailNode = detailList[ i ]; - var masterItem = detailNode.DetailContext.ParentItem; - - // Since the items removed collection is for realized item only, we must take a look - // at the final result set in case the item was unrealized and removed. - if( isDataVirtualized || itemsRemoved.Contains( masterItem ) || !newItems.Contains( masterItem ) ) - { - itemCount += detailNode.ItemCount; - detailList.RemoveAt( i ); - - // Put the detail aside and close it properly later. - this.RemoveGeneratedItems( detailNode, null ); - this.QueueDetailItemForRemapping( masterItem ); - } - else - { - // Keep a list of active detail nodes and their order. We will need those later in the algorithm. - detailNodes.Add( detailNode ); - - var detailNodesList = default( List ); - if( !detailNodesByItem.TryGetValue( masterItem, out detailNodesList ) ) - { - detailNodesList = new List( 1 ); - detailNodesByItem.Add( masterItem, detailNodesList ); - } - - Debug.Assert( detailNodesList != null ); - detailNodesList.Add( detailNode ); - - i++; - } - } - - if( detailList.Count <= 0 ) - { - detailEntries.Remove( detailEntry.Key ); - } - } - - if( detailEntries.Count <= 0 ) - { - node.Details = null; - } - - node.AdjustItemCount( -itemCount ); - } - - // The next thing to do is to remove the containers for the realized items that were removed. - if( itemsRemoved.Count > 0 ) - { - for( int i = m_genPosToItem.Count - 1; i >= 0; i-- ) - { - if( !itemsRemoved.Contains( m_genPosToItem[ i ] ) ) - continue; - - this.RemoveGeneratedItem( i, null ); - } - } - - // Now that everything that needed to be removed was removed, we will repair the collection - // that is used as a link between items and detail nodes. - if( detailNodes.Count > 0 ) - { - Debug.Assert( detailEntries != null ); - Debug.Assert( detailEntries == node.Details ); - Debug.Assert( !isDataVirtualized ); - - detailEntries.Clear(); - - for( int i = 0; i < newItems.Count; i++ ) - { - var masterItem = newItems[ i ]; - var detailNodesList = default( List ); - - if( detailNodesByItem.TryGetValue( masterItem, out detailNodesList ) ) - { - detailNodesByItem.Remove( masterItem ); - detailEntries.Add( i, detailNodesList ); - } - } - - Debug.Assert( ( detailNodesByItem.Count == 0 ), "The detail nodes should have been reinserted properly." ); - } - else - { - Debug.Assert( ( detailEntries == null ) || ( detailEntries.Count == 0 ) ); - Debug.Assert( node.Details == null ); - } - - // The next thing to do is to reorder the containers within the internal data structure so it match - // the ordering of the realized items that have moved. - if( itemsMoved.Count > 0 ) - { - Debug.Assert( !isDataVirtualized ); - - var insertionIndex = default( int? ); - var itemGenPosEntries = new Dictionary(); - var detailGenPosEntries = new Dictionary>>(); - - // Remove the entries within the data structure that are linked to the current node or one of its detail. - { - var i = 0; - - while( i < m_genPosToNode.Count ) - { - var currentNode = m_genPosToNode[ i ]; - - // We have found a container that is linked to one of the data item. - if( currentNode == node ) - { - itemGenPosEntries.Add( m_genPosToItem[ i ], m_genPosToContainer[ i ] ); - } - // We have found a container that is part of a detail that is linked to one of the data item. - else if( detailNodes.Contains( currentNode ) ) - { - var detailInfos = default( IList> ); - - if( !detailGenPosEntries.TryGetValue( currentNode, out detailInfos ) ) - { - detailInfos = new List>(); - detailGenPosEntries.Add( currentNode, detailInfos ); - } - - Debug.Assert( detailInfos != null ); - detailInfos.Add( new Tuple( m_genPosToItem[ i ], m_genPosToContainer[ i ] ) ); - } - // The container as nothing to do with the node we are looking for or one of its detail. - else - { - i++; - continue; - } - - // Remove the entries from the internal data structure. - this.GenPosArraysRemoveAt( i ); - - // Keep a reference on the first location a removal occurred. - if( !insertionIndex.HasValue ) - { - insertionIndex = i; - } - } - } - - // We must reinsert all entries that have been removed in the last step in appropriate order. - if( insertionIndex.HasValue ) - { - var index = insertionIndex.Value; - - for( int i = 0; i < newItems.Count; i++ ) - { - var currentItem = newItems[ i ]; - var currentContainer = default( DependencyObject ); - - if( itemGenPosEntries.TryGetValue( currentItem, out currentContainer ) ) - { - itemGenPosEntries.Remove( currentItem ); - - // The value inserted as the index is not important and will be updated at the last step of the algorithmn. - m_genPosToContainer.Insert( index, currentContainer ); - m_genPosToIndex.Insert( index, int.MinValue ); - m_genPosToItem.Insert( index, currentItem ); - m_genPosToNode.Insert( index, node ); - - index++; - } - - if( ( detailEntries != null ) && ( detailEntries.Count > 0 ) ) - { - var detailNodesList = default( List ); - - if( detailEntries.TryGetValue( i, out detailNodesList ) && ( detailNodesList != null ) ) - { - foreach( var detailNode in detailNodesList ) - { - var detailInfos = default( IList> ); - if( !detailGenPosEntries.TryGetValue( detailNode, out detailInfos ) ) - continue; - - detailGenPosEntries.Remove( detailNode ); - - foreach( var detailInfo in detailInfos ) - { - // The value inserted as the index is not important and will be updated at the last step of the algorithmn. - m_genPosToContainer.Insert( index, detailInfo.Item2 ); - m_genPosToIndex.Insert( index, int.MinValue ); - m_genPosToItem.Insert( index, detailInfo.Item1 ); - m_genPosToNode.Insert( index, detailNode ); - - index++; - } - } - } - } - } - } - - Debug.Assert( ( itemGenPosEntries.Count == 0 ), "The containers should have been reinserted properly." ); - Debug.Assert( ( detailGenPosEntries.Count == 0 ), "The detail containers should have been reinserted properly." ); - } - - // The last thing to do is to update the indexes and raise a notification. - this.IncrementCurrentGenerationCount(); - this.SendResetEvent(); - } - - private void ApplyDetailChanges( - DetailGeneratorNode node, - IList newContainers, - ICollection containersRemoved, - ICollection containersMoved ) - { - Debug.Assert( node != null ); - Debug.Assert( newContainers != null ); - Debug.Assert( containersRemoved != null ); - Debug.Assert( containersMoved != null ); - - // The first thing to do is to remove the containers for the realized items that were removed. - if( containersRemoved.Count > 0 ) - { - for( int i = m_genPosToContainer.Count - 1; i >= 0; i-- ) - { - if( !containersRemoved.Contains( m_genPosToContainer[ i ] ) ) - continue; - - this.RemoveGeneratedItem( i, null ); - } - } - - // The next thing to do is to reorder the containers within the internal data structure so it match - // the ordering of the realized containers that have moved. - if( containersMoved.Count > 0 ) - { - var insertionIndex = default( int? ); - var entries = new Dictionary(); - - // Remove the entries within the data structure that are linked to the detail node. - { - var i = 0; - - while( i < m_genPosToNode.Count ) - { - var currentNode = m_genPosToNode[ i ]; - - // We have found a container that is linked to the desired node. - if( currentNode == node ) - { - entries.Add( m_genPosToContainer[ i ], m_genPosToItem[ i ] ); - - // Remove the entries from the internal data structure. - this.GenPosArraysRemoveAt( i ); - - // Keep a reference on the first location a removal occurred. - if( !insertionIndex.HasValue ) - { - insertionIndex = i; - } - } - // The container as nothing to do with the node we are looking. - else - { - i++; - } - } - } - - // We must reinsert all entries that have been removed in the last step in appropriate order. - if( insertionIndex.HasValue ) - { - var index = insertionIndex.Value; - - for( int i = 0; i < newContainers.Count; i++ ) - { - var currentContainer = newContainers[ i ]; - var currentItem = default( object ); - - if( entries.TryGetValue( currentContainer, out currentItem ) ) - { - entries.Remove( currentContainer ); - - // The value inserted as the index is not important and will be updated at the last step of the algorithmn. - m_genPosToContainer.Insert( index, currentContainer ); - m_genPosToIndex.Insert( index, int.MinValue ); - m_genPosToItem.Insert( index, currentItem ); - m_genPosToNode.Insert( index, node ); - - index++; - } - } - } - - Debug.Assert( ( entries.Count == 0 ), "The containers should have been reinserted properly." ); - } - - // The last thing to do is to update the indexes and raise a notification. - this.IncrementCurrentGenerationCount(); - this.SendResetEvent(); - } - - internal void EnsureNodeTreeCreated() - { - //This is done to ensure that any public interface function called get an "up to date" generator content when being accessed. - - // No reentrency is allowed for this method - // to avoid any problem. - if( this.IsNodeTreeValid || this.IsEnsuringNodeTreeCreated ) - return; - - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_EnsureNodeTreeCreated ) ) - using( this.SetIsEnsuringNodeTreeCreated() ) - { - if( m_startNode == null ) - { - int addCount; - - this.UpdateHeaders( m_dataGridContext.Headers ); - this.SetupInitialItemsNodes( out addCount ); - this.UpdateFooters( m_dataGridContext.Footers ); - - this.IncrementCurrentGenerationCount(); - } - else if( m_firstItem == null ) - { - this.HandleItemsRecreation(); - } - - this.EnsureDetailsNodeTreeCreated(); - this.RemapFloatingDetails(); - - m_dataGridControl.RestoreDataGridContextState( m_dataGridContext ); - } - - // The current method will need to be called again. The data source is most probably not set yet. - if( ( m_startNode == null ) || ( m_firstItem == null ) || ( m_floatingDetails.Count != 0 ) ) - { - this.InvalidateNodeTree(); - } - } - - private void EnsureDetailsNodeTreeCreated() - { - if( m_masterToDetails.Count == 0 ) - return; - - Debug.Assert( this.IsEnsuringNodeTreeCreated, "The method EnsureDetailsNodeTreeCreated should have been called from EnsureNodeTreeCreated." ); - - foreach( var generator in this.GetDetailGenerators().ToList() ) - { - generator.EnsureNodeTreeCreated(); - } - } - - private void HandleItemsRecreation() - { - //Then, since its a Reset, recreates the Items nodes. - int resetAddCount; - - var addNode = this.SetupInitialItemsNodes( out resetAddCount ); - if( addNode != null ) - { - this.IncrementCurrentGenerationCount(); - } - } - - private void UpdateGenPosToIndexList() - { - if( m_startNode == null ) - return; - - //after the modification to have the item count stored "locally" in the DetailGeneratorNodes, - //it becomes important to have the nodes updated when the layout of the items changes. - foreach( var detailNode in this.GetDetailGeneratorNodes() ) - { - detailNode.UpdateItemCount(); - } - - var nodeHelper = new GeneratorNodeHelper( m_startNode, 0, 0 ); - var cachedDetailNode = default( DetailGeneratorNode ); - var cachedDetailNodeIndex = -1; - var previousDetailIndex = -1; - - //loop through the realized items. By design they are present sequentially in the linked list, so I do not need to reset the GeneratorNodeHelper - for( int i = 0; i < m_genPosToItem.Count; i++ ) - { - var item = m_genPosToItem[ i ]; - var node = m_genPosToNode[ i ]; - var detailNode = node as DetailGeneratorNode; - - int index; - - if( detailNode == null ) - { - if( !nodeHelper.FindNode( node ) ) - throw DataGridException.Create( "Realized item not found.", m_dataGridControl ); - - index = nodeHelper.FindItem( item ); - if( index < 0 ) - throw DataGridException.Create( "Realized item not found.", m_dataGridControl ); - - var itemsNode = nodeHelper.CurrentNode as ItemsGeneratorNode; - if( itemsNode != null ) - { - index = nodeHelper.Index + itemsNode.IndexOf( item ); - } - } - else - { - if( cachedDetailNode != detailNode ) - { - cachedDetailNodeIndex = this.FindGlobalIndexForDetailNode( detailNode ); - cachedDetailNode = detailNode; - previousDetailIndex = -1; - } - - var detailIndex = detailNode.DetailGenerator.IndexFromRealizedItem( item, previousDetailIndex + 1, out previousDetailIndex ); - if( detailIndex < 0 ) - throw DataGridException.Create( "Realized item not found at detail level.", m_dataGridControl ); - - index = cachedDetailNodeIndex + detailIndex; - } - - if( ( i > 0 ) && ( index <= m_genPosToIndex[ i - 1 ] ) ) - throw DataGridException.Create( "Realized item re-indexed at wrong location.", m_dataGridControl ); - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_UpdateGenPosToIndexList, DataGridTraceMessages.IndexUpdated, DataGridTraceArgs.Container( m_genPosToContainer[ i ] ), DataGridTraceArgs.Node( m_genPosToNode[ i ] ), DataGridTraceArgs.Item( m_genPosToItem[ i ] ), DataGridTraceArgs.GeneratorIndex( i ), DataGridTraceArgs.From( m_genPosToIndex[ i ] ), DataGridTraceArgs.To( index ) ); - - m_genPosToIndex[ i ] = index; - } - } - - private int IndexFromRealizedItem( object referenceItem, int startIndex, out int foundIndex ) - { - int retval = -1; - foundIndex = startIndex; - - for( int i = startIndex; i < m_genPosToIndex.Count; i++ ) - { - object item = m_genPosToItem[ i ]; - - if( item == referenceItem ) - { - foundIndex = i; - retval = m_genPosToIndex[ i ]; - break; - } - } - - return retval; - } - - private int FindGlobalIndexForDetailNode( DetailGeneratorNode detailNode ) - { - foreach( var masterItemToDetails in m_masterToDetails ) - { - var detailsNodes = masterItemToDetails.Value; - var detailIndex = detailsNodes.IndexOf( detailNode ); - if( detailIndex < 0 ) - continue; - - var parentItem = masterItemToDetails.Key; - var offset = detailsNodes.Take( detailIndex ).Sum( item => item.ItemCount - 1 ); - - var index = m_genPosToItem.IndexOf( parentItem ); - - if( index >= 0 ) - { - if( m_genPosToNode[ index ] is ItemsGeneratorNode ) - return offset + detailIndex + m_genPosToIndex[ index ] + 1; - } - - // Look for parent item index the old way. - var nodeHelper = new GeneratorNodeHelper( m_startNode, 0, 0 ); - - var parentItemIndex = nodeHelper.FindItem( parentItem ); - if( parentItemIndex < 0 ) - throw DataGridException.Create( "Master item index is out of bound.", m_dataGridControl ); - - return offset + detailIndex + parentItemIndex + 1; - } - - return -1; - } - - private void StartGenerator( GeneratorPosition startPos, GeneratorDirection direction ) - { - if( this.Status == GeneratorStatus.GeneratingContainers ) - throw DataGridException.Create( "Cannot perform this operation while the generator is busy generating items.", m_dataGridControl ); - - m_generatorStatus = GeneratorStatus.GeneratingContainers; - m_generatorDirection = direction; - m_generatorCurrentGlobalIndex = this.IndexFromGeneratorPosition( startPos ); - - var itemCount = this.ItemCount; - if( ( m_generatorCurrentGlobalIndex < 0 ) || ( m_generatorCurrentGlobalIndex >= itemCount ) ) - return; - - //and create a node helper that will assist us during the Generation process... - m_generatorNodeHelper = new GeneratorNodeHelper( m_startNode, 0, 0 ); // start index is always 0 - - //position the GeneratorNodeHelper to the appropriate node - if( !m_generatorNodeHelper.FindNodeForIndex( m_generatorCurrentGlobalIndex ) ) //find index?!?! - //there was a problem moving the Node helper... - throw DataGridException.Create( "Unable to move to the required generator node by using the current index.", m_dataGridControl ); - - //Calculate the offset - m_generatorCurrentOffset = m_generatorCurrentGlobalIndex - m_generatorNodeHelper.Index; - - var itemsNode = m_generatorNodeHelper.CurrentNode as ItemsGeneratorNode; - if( itemsNode != null ) - { - m_generatorCurrentDetail = itemsNode.GetDetailNodeForIndex( m_generatorCurrentOffset, out m_generatorCurrentOffset, out m_generatorCurrentDetailIndex, out m_generatorCurrentDetailNodeIndex ); - } - - if( m_generatorCurrentDetail != null ) - { - // No detail generator should be started already. - if( m_generatorCurrentDetailDisposable != null ) - throw DataGridException.Create( "The detail generator is already started.", m_dataGridControl ); - - m_generatorCurrentDetailDisposable = ( ( IItemContainerGenerator )m_generatorCurrentDetail.DetailGenerator ).StartAt( m_generatorCurrentDetail.DetailGenerator.GeneratorPositionFromIndex( m_generatorCurrentDetailIndex ), direction, true ); - } - } - - private void StopGenerator() - { - if( this.Status != GeneratorStatus.GeneratingContainers ) - throw DataGridException.Create( "Cannot perform this operation while the generator is busy generating items.", m_dataGridControl ); - - m_generatorNodeHelper = null; - m_generatorCurrentOffset = -1; - m_generatorCurrentGlobalIndex = -1; - - m_generatorCurrentDetailIndex = -1; - m_generatorCurrentDetailNodeIndex = -1; - - m_generatorCurrentDetail = null; - - if( m_generatorCurrentDetailDisposable != null ) - { - try - { - m_generatorCurrentDetailDisposable.Dispose(); - m_generatorCurrentDetailDisposable = null; - } - catch( Exception e ) - { - m_generatorStatus = GeneratorStatus.Error; - - throw new DataGridInternalException( "The generator failed to stop.", e, m_dataGridControl ); - } - } - - m_generatorStatus = GeneratorStatus.ContainersGenerated; - } - - private GeneratorPosition FindNextUnrealizedGeneratorPosition( GeneratorPosition position ) - { - var retval = position; - var index = this.IndexFromGeneratorPosition( position ) + 1; - - while( index < this.ItemCount ) - { - if( m_genPosToIndex.Contains( index ) ) - { - retval.Index++; - } - else - { - retval.Offset++; - break; - } - - index++; - } - - return retval; - } - - private GeneratorPosition FindPreviousUnrealizedGeneratorPosition( GeneratorPosition position ) - { - var index = this.IndexFromGeneratorPosition( position ) - 1; - while( index >= 0 ) - { - if( !m_genPosToIndex.Contains( index ) ) - break; - - index--; - } - - return this.GeneratorPositionFromIndex( index ); - } - - private DependencyObject CreateContainerForItem( object dataItem, GeneratorNode node ) - { - var container = default( DependencyObject ); - - if( node is HeadersFootersGeneratorNode ) - { - container = this.CreateHeaderFooterContainer( dataItem ); - - if( node.Parent == null ) - { - GroupLevelIndicatorPane.SetGroupLevel( container, -1 ); - } - else - { - GroupLevelIndicatorPane.SetGroupLevel( container, node.Level ); - } - - this.SetStatContext( container, node ); - } - else if( node is ItemsGeneratorNode ) - { - //ensure that item is not its own container... - if( !this.IsItemItsOwnContainer( dataItem ) ) - { - container = this.CreateNextItemContainer( dataItem ); - } - else - { - container = dataItem as DependencyObject; - } - - GroupLevelIndicatorPane.SetGroupLevel( container, node.Level ); - } - else - { - throw DataGridException.Create( "Cannot create container for the GeneratorNode, as it is not of a valid type.", m_dataGridControl ); - } - - if( container == null ) - throw DataGridException.Create( "A container could not be created or recycled for the GeneratorNode.", m_dataGridControl ); - - var dataItemStore = container.ReadLocalValue( CustomItemContainerGenerator.DataItemPropertyProperty ) as DataItemDataProviderBase; - if( dataItemStore != null ) - { - dataItemStore.SetDataItem( dataItem ); - } - else - { - dataItemStore = new DataItemDataProvider(); - dataItemStore.SetDataItem( dataItem ); - - CustomItemContainerGenerator.SetDataItemProperty( container, dataItemStore ); - } - - DataGridControl.SetDataGridContext( container, m_dataGridContext ); - - return container; - } - - private void SetStatContext( DependencyObject container, GeneratorNode node ) - { - var parentGroup = node.Parent as GroupGeneratorNode; - var collectionViewGroup = default( DataGridCollectionViewGroup ); - - if( parentGroup != null ) - { - collectionViewGroup = parentGroup.CollectionViewGroup as DataGridCollectionViewGroup; - } - else if( m_dataGridContext != null ) - { - var collectionView = m_dataGridContext.ItemsSourceCollection as DataGridCollectionViewBase; - if( collectionView != null ) - { - collectionViewGroup = collectionView.RootGroup as DataGridCollectionViewGroup; - } - } - - if( collectionViewGroup != null ) - { - container.SetValue( DataGridControl.StatContextPropertyKey, collectionViewGroup ); - } - } - - private void ClearStatContext( DependencyObject container ) - { - if( GroupLevelIndicatorPane.GetGroupLevel( container ) == -1 ) - { - container.ClearValue( GroupLevelIndicatorPane.GroupLevelProperty ); - } - - if( container is HeaderFooterItem ) - { - container.ClearValue( DataGridControl.StatContextPropertyKey ); - } - } - - private bool IsItemItsOwnContainer( object dataItem ) - { - return m_dataGridControl.IsItemItsOwnContainer( dataItem ); - } - - private DependencyObject CreateHeaderFooterContainer( object dataItem ) - { - if( this.IsRecyclingEnabled ) - { - var recycledContainer = this.DequeueHeaderFooterContainer( dataItem ); - if( recycledContainer != null ) - return recycledContainer; - } - - //If the container cannot be recycled, then create a new one. - var realDataItem = dataItem; - if( dataItem.GetType() == typeof( GroupHeaderFooterItem ) ) - { - realDataItem = ( ( GroupHeaderFooterItem )dataItem ).Template; - } - - var template = realDataItem as DataTemplate; - if( template == null ) - { - var vwc = realDataItem as GroupHeaderFooterItemTemplate; - if( vwc != null ) - { - vwc.Seal(); - template = vwc.Template; - } - - if( template == null ) - throw DataGridException.Create( "No template found for the creation of a header or footer container.", m_dataGridControl ); - } - - var newItem = new HeaderFooterItem(); - - BindingOperations.SetBinding( newItem, HeaderFooterItem.ContentProperty, m_headerFooterDataContextBinding ); - newItem.ContentTemplate = template; - - return newItem; - } - - private int FindInsertionPoint( int itemIndex ) - { - var count = m_genPosToIndex.Count; - - for( var i = 0; i < count; i++ ) - { - //if the item is larger in index, then I want to insert before it! - if( m_genPosToIndex[ i ] > itemIndex ) - return i; - } - - return count; - } - - private void RemapFloatingDetails() - { - if( m_floatingDetails.Count == 0 ) - return; - - if( this.IsDetailsRemapDeferred ) - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_RemapFloatingDetails, DataGridTraceMessages.CannotRemapDetails ); - return; - } - - Debug.Assert( m_startNode != null, "Generator structure should already be created." ); - - while( m_floatingDetails.Count > 0 ) - { - var closeDetail = true; //using this approach to have a default behavior or closing the details, if something inconsistent occur (see Debug Asserts). - var itemToCheck = m_floatingDetails[ 0 ]; - m_floatingDetails.RemoveAt( 0 ); - - var nodeHelper = new GeneratorNodeHelper( m_startNode, 0, 0 ); - if( nodeHelper.AbsoluteFindItem( itemToCheck ) ) - { - var itemsNode = nodeHelper.CurrentNode as ItemsGeneratorNode; - if( itemsNode != null ) - { - var insertionIndex = itemsNode.Items.IndexOf( itemToCheck ); - if( insertionIndex < 0 ) - { - this.TraceEvent( TraceEventType.Critical, DataGridTraceEventId.CustomItemContainerGenerator_RemapFloatingDetails, DataGridTraceMessages.ItemNotBelongingToNode, DataGridTraceArgs.Item( itemToCheck ), DataGridTraceArgs.Node( itemsNode ) ); - } - - if( itemsNode.Details == null ) - { - itemsNode.Details = new SortedDictionary>(); - } - - try - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_RemapFloatingDetails, DataGridTraceMessages.RemapDetailNodes, DataGridTraceArgs.Item( itemToCheck ) ); - - var oldItemCount = this.ItemCount; - - itemsNode.Details.Add( insertionIndex, new List( m_masterToDetails[ itemToCheck ] ) ); - - var addCount = 0; - foreach( var detailNode in m_masterToDetails[ itemToCheck ] ) - { - // Refresh the item count in case it changed while the detail was floating. - detailNode.UpdateItemCount(); - - addCount += detailNode.ItemCount; - } - itemsNode.AdjustItemCount( addCount ); - - this.IncrementCurrentGenerationCount(); - - // The ItemsChanged event should not be raised if the new items are hidden under a collapsed group, or else the master node's ItemCount will become unbalanced. - var newItemCount = this.ItemCount; - if( oldItemCount != newItemCount ) - { - //ensure that no add event is sent when the generator is currently processing a Reset. - if( !this.IsHandlingGlobalItemsReset ) - { - this.SendAddEvent( addCount ); - } - } - - closeDetail = false; - } - catch( Exception e ) - { - //both the "Add" and the " [] " could throw if the key is already present or if its not... - throw new DataGridInternalException( e.Message, e, m_dataGridControl ); - } - } - else - { - this.TraceEvent( TraceEventType.Warning, DataGridTraceEventId.CustomItemContainerGenerator_RemapFloatingDetails, DataGridTraceMessages.UnexpectedNode, DataGridTraceArgs.Node( nodeHelper.CurrentNode ) ); - } - } - - if( closeDetail ) - { - //The item was not located in the generator, then it's time to "close" the detail node/generator - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_RemapFloatingDetails, DataGridTraceMessages.CollapsingDetail, DataGridTraceArgs.Item( itemToCheck ) ); - this.CloseDetailsForItem( itemToCheck, null ); - } - } - } - - private void QueueDetailItemForRemapping( object item ) - { - if( item == null ) - return; - - if( !m_masterToDetails.ContainsKey( item ) || m_floatingDetails.Contains( item ) ) - return; - - m_floatingDetails.Add( item ); - - this.InvalidateNodeTree(); - } - - private void CloseDetails( DetailConfiguration detailConfiguration ) - { - var details = new KeyValuePair>[ m_masterToDetails.Count ]; - ( ( ICollection>> )m_masterToDetails ).CopyTo( details, 0 ); - - foreach( var detail in details ) - { - this.CloseDetailsForItem( detail.Key, detailConfiguration ); - } - } - - private int CloseDetailsForItem( object dataItem, DetailConfiguration detailConfiguration ) - { - if( m_generatorStatus == GeneratorStatus.GeneratingContainers ) - throw DataGridException.Create( "Cannot perform this operation while the generator is busy generating items", m_dataGridControl ); - - if( dataItem is EmptyDataItem ) - { - this.TraceEvent( TraceEventType.Error, DataGridTraceEventId.CustomItemContainerGenerator_CloseDetailsForItem, DataGridTraceMessages.CannotCollapseDetail, DataGridTraceArgs.Item( dataItem ) ); - return -1; - } - - if( ( dataItem == null ) || ( !m_masterToDetails.ContainsKey( dataItem ) ) ) - return -1; //the item is no longer present in the opened details list... or item is invalid (null) - - var nodeHelper = new GeneratorNodeHelper( m_startNode, 0, 0 ); - var globalItemIndex = nodeHelper.FindItem( dataItem ); - var dataItemFound = ( globalItemIndex >= 0 ); - //Note: this function will only return index for items directly contained in this generator ( no details ). - - ItemsGeneratorNode masterNode; - - if( dataItemFound ) - { - masterNode = nodeHelper.CurrentNode as ItemsGeneratorNode; - } - else - { - nodeHelper = new GeneratorNodeHelper( m_startNode, 0, 0 ); - masterNode = ( nodeHelper.Contains( dataItem ) ) ? nodeHelper.CurrentNode as ItemsGeneratorNode : null; - } - - List oldDetails; - if( !m_masterToDetails.TryGetValue( dataItem, out oldDetails ) ) - { - this.TraceEvent( TraceEventType.Critical, DataGridTraceEventId.CustomItemContainerGenerator_CloseDetailsForItem, DataGridTraceMessages.DetailNotFound, DataGridTraceArgs.Item( dataItem ) ); - throw DataGridException.Create( "Detail not found", m_dataGridControl ); - } - - var count = 0; - var containers = new List(); - - for( int i = oldDetails.Count - 1; i >= 0; i-- ) - { - var detailNode = oldDetails[ i ]; - - if( ( detailConfiguration == null ) || ( detailConfiguration == detailNode.DetailContext.SourceDetailConfiguration ) ) - { - count += detailNode.ItemCount; - - this.RemoveGeneratedItems( detailNode, containers ); - this.ClearDetailGeneratorNode( detailNode ); - - oldDetails.RemoveAt( i ); - } - } - - if( oldDetails.Count == 0 ) - { - m_masterToDetails.Remove( dataItem ); - m_floatingDetails.Remove( dataItem ); - } - - if( ( masterNode != null ) && ( masterNode.Details != null ) ) - { - var indexOfItem = masterNode.Items.IndexOf( dataItem ); - - if( !masterNode.Details.TryGetValue( indexOfItem, out oldDetails ) ) - { - this.TraceEvent( TraceEventType.Critical, DataGridTraceEventId.CustomItemContainerGenerator_CloseDetailsForItem, DataGridTraceMessages.DetailNotFound, DataGridTraceArgs.Item( dataItem ) ); - throw DataGridException.Create( "Detail not found .. 2", m_dataGridControl ); - } - - for( int i = oldDetails.Count - 1; i >= 0; i-- ) - { - var detailNode = oldDetails[ i ]; - - if( ( detailConfiguration == null ) || ( detailConfiguration == detailNode.DetailContext.SourceDetailConfiguration ) ) - { - oldDetails.RemoveAt( i ); - } - } - - if( oldDetails.Count == 0 ) - { - masterNode.Details.Remove( indexOfItem ); - } - - masterNode.AdjustItemCount( -count ); - - if( masterNode.Details.Count == 0 ) - { - masterNode.Details = null; - } - } - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_CloseDetailsForItem, DataGridTraceMessages.DetailCollapsed, DataGridTraceArgs.Item( dataItem ) ); - - if( dataItemFound ) - { - this.IncrementCurrentGenerationCount(); - this.SendRemoveEvent( count, containers ); - } - - return globalItemIndex; - } - - private DetailGeneratorNode CreateDetailGeneratorNode( object dataItem, DataGridCollectionViewBase collectionView, DetailConfiguration detailConfiguration ) - { - var detailDataGridContext = new DataGridContext( m_dataGridContext, m_dataGridControl, dataItem, collectionView, detailConfiguration ); - var detailGenerator = CustomItemContainerGenerator.CreateGenerator( m_dataGridControl, collectionView, detailDataGridContext, this ); - detailGenerator.SetGenPosToIndexUpdateInhibiter( this ); - detailGenerator.IsRecyclingEnabled = this.IsRecyclingEnabled; - - if( m_dataGridControl.AreDetailsFlatten ) - { - var updateColumnSortCommand = detailDataGridContext.UpdateColumnSortCommand; - if( updateColumnSortCommand.CanExecute() ) - { - updateColumnSortCommand.Execute(); - } - } - - DetailsChangedEventManager.AddListener( detailGenerator, this ); - - var detailNode = new DetailGeneratorNode( detailDataGridContext, detailGenerator ); - - //register to the ItemsChanged only after the columns were updated (to avoid a reset being received without having completed the initialization ). - //Also wait after the creation of the DetailGeneratorNode, since messages could be issued before initialization completes. - detailGenerator.ItemsChanged += new CustomGeneratorChangedEventHandler( this.HandleDetailGeneratorContentChanged ); - detailGenerator.ContainersRemoved += new ContainersRemovedEventHandler( this.OnDetailContainersRemoved ); - - return detailNode; - } - - private void ClearDetailGeneratorNode( DetailGeneratorNode detailNode ) - { - m_dataGridControl.SelectionChangerManager.Begin(); - - try - { - m_dataGridControl.SelectionChangerManager.UnselectAllItems( detailNode.DetailContext ); - m_dataGridControl.SelectionChangerManager.UnselectAllCells( detailNode.DetailContext ); - } - finally - { - m_dataGridControl.SelectionChangerManager.End( false, false ); - } - - m_dataGridControl.SaveDataGridContextState( detailNode.DetailContext, true, int.MaxValue ); - - var detailGenerator = detailNode.DetailGenerator; - - detailNode.CleanGeneratorNode(); - - DetailsChangedEventManager.RemoveListener( detailGenerator, this ); - detailGenerator.ItemsChanged -= new CustomGeneratorChangedEventHandler( this.HandleDetailGeneratorContentChanged ); - detailGenerator.ContainersRemoved -= new ContainersRemovedEventHandler( this.OnDetailContainersRemoved ); - detailGenerator.SetGenPosToIndexUpdateInhibiter( null ); - detailGenerator.UnregisterEvents(); - detailGenerator.ClearEvents(); - } - - private void RegisterEvents() - { - Debug.Assert( m_dataGridControl != null ); - Debug.Assert( m_collectionView != null ); - Debug.Assert( m_dataGridContext != null ); - - CollectionChangedEventManager.AddListener( m_collectionView, this ); - GroupConfigurationSelectorChangedEventManager.AddListener( m_dataGridContext, this ); - PropertyChangedEventManager.AddListener( m_collectionView, this, string.Empty ); - - // The top most generator must register to additional events. - if( m_dataGridContext.SourceDetailConfiguration == null ) - { - ItemsSourceChangeCompletedEventManager.AddListener( m_dataGridControl, this ); - ViewChangedEventManager.AddListener( m_dataGridControl, this ); - ThemeChangedEventManager.AddListener( m_dataGridControl, this ); - - m_recyclingPools.ContainersRemoved += new ContainersRemovedEventHandler( this.OnRecyclingPoolsContainersRemoved ); - m_recyclingPools.RecyclingCandidatesCleaned += new RecyclingCandidatesCleanedEventHandler( this.OnRecyclingCandidatesCleaned ); - } - } - - private void UnregisterEvents() - { - Debug.Assert( m_dataGridControl != null ); - Debug.Assert( m_collectionView != null ); - Debug.Assert( ( m_dataGridContext != null ) && ( m_dataGridContext.DetailConfigurations != null ) ); - - CollectionChangedEventManager.RemoveListener( m_collectionView, this ); - GroupConfigurationSelectorChangedEventManager.RemoveListener( m_dataGridContext, this ); - CollectionChangedEventManager.RemoveListener( m_dataGridContext.DetailConfigurations, this ); - PropertyChangedEventManager.RemoveListener( m_collectionView, this, string.Empty ); - - // The top most generator must unregister from additional events. - if( m_dataGridContext.SourceDetailConfiguration == null ) - { - ItemsSourceChangeCompletedEventManager.RemoveListener( m_dataGridControl, this ); - ViewChangedEventManager.RemoveListener( m_dataGridControl, this ); - ThemeChangedEventManager.RemoveListener( m_dataGridControl, this ); - - m_recyclingPools.ContainersRemoved -= new ContainersRemovedEventHandler( this.OnRecyclingPoolsContainersRemoved ); - m_recyclingPools.RecyclingCandidatesCleaned -= new RecyclingCandidatesCleanedEventHandler( this.OnRecyclingCandidatesCleaned ); - } - } - - private void ClearEvents() - { - this.ContainersRemoved = null; - this.DetailsChanged = null; - this.ItemsChanged = null; - this.PropertyChanged = null; - } - - internal int CreateDetailsHelper( ItemsGeneratorNode masterNode, object dataItem ) - { - var dataGridCollectionViewBase = ( m_dataGridContext != null ) ? m_dataGridContext.ItemsSourceCollection as DataGridCollectionViewBase - : default( DataGridCollectionViewBase ); - - if( dataGridCollectionViewBase == null ) - { - this.TraceEvent( TraceEventType.Critical, DataGridTraceEventId.CustomItemContainerGenerator_CreateDetailsHelper, DataGridTraceMessages.DetailNotSupported, - DataGridTraceArgs.DataSource( dataGridCollectionViewBase ) ); - } - - var totalAddCount = 0; - var newDetails = default( List ); - var detailsAlreadyExist = m_floatingDetails.Contains( dataItem ); - - if( detailsAlreadyExist ) - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_CreateDetailsHelper, DataGridTraceMessages.RemapDetailNodes, - DataGridTraceArgs.Item( dataItem ) ); - - newDetails = new List( m_masterToDetails[ dataItem ] ); - m_floatingDetails.Remove( dataItem ); - } - - var detailConfigurations = m_dataGridContext.DetailConfigurations; - - //If the master item was not found in the list of details pending requeuing, then create a new set of detail nodes - if( newDetails == null ) - { - newDetails = new List( detailConfigurations.Count ); - - foreach( DetailConfiguration detailConfig in detailConfigurations ) - { - if( detailConfig.IsAutoCreated ) - { - var defaultDetailConfig = m_dataGridContext.DefaultDetailConfiguration; - if( defaultDetailConfig == null ) - { - defaultDetailConfig = m_dataGridContext.GetDefaultDetailConfigurationForContext(); - } - - if( defaultDetailConfig != null ) - { - //if the default headers footers shall be used, add then to the detail config ( internally, it ensures that it is added only once ). - if( defaultDetailConfig.UseDefaultHeadersFooters ) - { - defaultDetailConfig.AddDefaultHeadersFooters(); - detailConfig.AddDefaultHeadersFooters(); - } - } - else - { - //if the default headers footers shall be used, add then to the detail config ( internally, it ensures that it is added only once ). - if( detailConfig.UseDefaultHeadersFooters ) - { - detailConfig.AddDefaultHeadersFooters(); - } - } - } - else - { - //if the default headers footers shall be used, add then to the detail config ( internally, it ensures that it is added only once ). - if( detailConfig.UseDefaultHeadersFooters ) - { - detailConfig.AddDefaultHeadersFooters(); - } - } - - // If the DetailConfiguration is not meant to be visible, then skip next section (creation of detail) and continue looping on other detail configurations - if( !detailConfig.Visible ) - continue; - - var newDetailCollectionViewBase = default( DataGridCollectionViewBase ); - var detailDataSource = default( IEnumerable ); - - // If the data source returned by the detailDescription is null ( or if there was no detail description ), then create an empty data source for the detail data. - if( detailDataSource == null ) - { - detailDataSource = new object[] { }; - } - - newDetailCollectionViewBase = dataGridCollectionViewBase.CreateDetailDataGridCollectionViewBase( detailDataSource, null, dataGridCollectionViewBase ); - - Debug.Assert( newDetailCollectionViewBase != null ); - - using( detailConfig.ColumnManager.DeferUpdate( new ColumnHierarchyManager.UpdateOptions( TableView.GetFixedColumnCount( detailConfig ), true ) ) ) - { - if( detailConfig.AutoCreateForeignKeyConfigurations && !detailConfig.ForeignKeysUpdatedOnAutoCreate ) - { - // Ensure to update the foreign key related properties before expanding detail - ForeignKeyConfiguration.UpdateColumnsForeignKeyConfigurationsFromDataGridCollectionView( detailConfig.Columns, - newDetailCollectionViewBase.ItemProperties, - detailConfig.AutoCreateForeignKeyConfigurations ); - detailConfig.ForeignKeysUpdatedOnAutoCreate = true; - } - } - - var newDetailNode = this.CreateDetailGeneratorNode( dataItem, newDetailCollectionViewBase, detailConfig ); - newDetails.Add( newDetailNode ); - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_CreateDetailsHelper, DataGridTraceMessages.DetailNodeAdded, - DataGridTraceArgs.Node( newDetailNode ), DataGridTraceArgs.Item( dataItem ) ); - - totalAddCount += newDetailNode.ItemCount; - } - } - else // there was details for the master item in the list to be requeued - { - // count the items from the details. - foreach( var detailNode in newDetails ) - { - totalAddCount += detailNode.ItemCount; - } - } - - // Plug details in the master items node. - var indexOfItem = masterNode.Items.IndexOf( dataItem ); - var details = masterNode.Details; - - if( details == null ) - { - details = new SortedDictionary>(); - masterNode.Details = details; - } - - details.Add( indexOfItem, newDetails ); - - masterNode.AdjustItemCount( totalAddCount ); - - if( !detailsAlreadyExist ) - { - m_masterToDetails.Add( dataItem, new List( newDetails ) ); - - for( int i = 0; i < newDetails.Count; i++ ) - { - m_dataGridControl.RestoreDataGridContextState( newDetails[ i ].DetailContext ); - } - } - else - { - var detailsMapped = m_masterToDetails.ContainsKey( dataItem ); - Debug.Assert( detailsMapped, "Item not found on master level." ); - - if( !detailsMapped ) - { - this.TraceEvent( TraceEventType.Warning, DataGridTraceEventId.CustomItemContainerGenerator_CreateDetailsHelper, DataGridTraceMessages.RemapZombieDetail, - DataGridTraceArgs.Item( dataItem ) ); - } - } - - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_CreateDetailsHelper, DataGridTraceMessages.DetailExpanded, - DataGridTraceArgs.Item( dataItem ) ); - - return totalAddCount; - } - - private void CreateDetailsForItem( object dataItem ) - { - if( m_generatorStatus == GeneratorStatus.GeneratingContainers ) - throw DataGridException.Create( "Cannot perform this operation while the generator is busy generating items", m_dataGridControl ); - - if( ( dataItem == null ) || ( dataItem is EmptyDataItem ) ) - { - this.TraceEvent( TraceEventType.Error, DataGridTraceEventId.CustomItemContainerGenerator_CreateDetailsForItem, DataGridTraceMessages.CannotExpandDetail, DataGridTraceArgs.Item( dataItem ) ); - return; - } - - if( m_masterToDetails.ContainsKey( dataItem ) ) - { - //before throwing, verify if the item is not currently pending requeue - if( !m_floatingDetails.Contains( dataItem ) ) - throw DataGridException.Create( "An attempt was made to create details for an item whose details are already mapped.", m_dataGridControl ); - } - - var nodeHelper = new GeneratorNodeHelper( m_startNode, 0, 0 ); - var dataItemFound = ( nodeHelper.FindItem( dataItem ) >= 0 ); - - //means either that the item is not present in the Generator or that a parent group of the item is collapsed... - if( !dataItemFound ) - { - //make sure it is the later, else throw an exception. - nodeHelper = new GeneratorNodeHelper( m_startNode, 0, 0 ); - if( !nodeHelper.Contains( dataItem ) ) - throw DataGridException.Create( "An attempt was made to create details for an item that does not belong to the generator.", m_dataGridControl ); - } - - var masterNode = nodeHelper.CurrentNode as ItemsGeneratorNode; - if( masterNode == null ) - throw DataGridException.Create( "An attempt was made to create details for an item that does not map to an item node.", m_dataGridControl ); - - try - { - var count = this.CreateDetailsHelper( masterNode, dataItem ); - - this.IncrementCurrentGenerationCount(); - - if( dataItemFound ) - { - this.SendAddEvent( count ); - } - } - catch( Exception e ) - { - throw new DataGridException( e.Message, e, m_dataGridControl ); - } - } - - private void HandleDetailGeneratorContentChanged( object sender, CustomGeneratorChangedEventArgs e ) - { - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_OnDetailGeneratorContentChanged, DataGridTraceArgs.Node( sender ) ) ) - { - if( this.IsHandlingGlobalItemsResetLocally ) - { - this.TraceEvent( TraceEventType.Warning, DataGridTraceEventId.CustomItemContainerGenerator_OnDetailGeneratorContentChanged, DataGridTraceMessages.CannotProcessOnReset ); - return; - } - - var detailGenerator = sender as CustomItemContainerGenerator; - - Debug.Assert( detailGenerator != null ); - Debug.Assert( m_startNode != null ); - - object masterItem; - var detailNode = this.FindDetailGeneratorNodeForGenerator( detailGenerator, out masterItem ); - - Debug.Assert( masterItem != null ); - Debug.Assert( detailNode != null ); - - if( ( detailNode != null ) && ( masterItem != null ) ) - { - this.TraceEvent( TraceEventType.Verbose, DataGridTraceEventId.CustomItemContainerGenerator_OnDetailGeneratorContentChanged, DataGridTraceArgs.Action( e.Action ), DataGridTraceArgs.Node( detailNode ), DataGridTraceArgs.Item( masterItem ) ); - - switch( e.Action ) - { - case NotifyCollectionChangedAction.Add: - this.HandleDetailAddition( masterItem, detailNode, e ); - break; - - case NotifyCollectionChangedAction.Move: - case NotifyCollectionChangedAction.Remove: - this.HandleDetailMoveRemove( masterItem, detailNode, e ); - break; - - case NotifyCollectionChangedAction.Replace: //CustomItemContainerGenreator never issues a Replace! - throw DataGridException.Create( "CustomItemContainerGenerator never notifies a Replace action.", m_dataGridControl ); - - case NotifyCollectionChangedAction.Reset: - this.HandleDetailReset( masterItem, detailNode ); - break; - - default: - break; - } - } - } - } - - private void HandleDetailAddition( object masterItem, DetailGeneratorNode detailNode, CustomGeneratorChangedEventArgs e ) - { - if( m_floatingDetails.Contains( masterItem ) ) - return; - - var nodeHelper = new GeneratorNodeHelper( m_startNode, 0, 0 ); - - // The master item has been found. - if( nodeHelper.FindItem( masterItem ) >= 0 ) - { - var masterNode = ( ItemsGeneratorNode )nodeHelper.CurrentNode; - - masterNode.AdjustItemCount( e.Count ); - detailNode.UpdateItemCount(); - - this.IncrementCurrentGenerationCount(); - this.SendAddEvent( e.Count ); - } - // The master item could be located inside a collapsed group. - else - { - //in that case, I need to determine the appropriate masterNode another way - nodeHelper = new GeneratorNodeHelper( m_startNode, 0, 0 ); - if( !nodeHelper.Contains( masterItem ) ) - throw DataGridException.Create( "An attempt was made to add a detail for an item that does not belong to the generator.", m_dataGridControl ); - - var masterNode = ( ItemsGeneratorNode )nodeHelper.CurrentNode; - - masterNode.AdjustItemCount( e.Count ); - detailNode.UpdateItemCount(); - - this.IncrementCurrentGenerationCount(); - } - } - - private void HandleDetailMoveRemove( object masterItem, DetailGeneratorNode detailNode, CustomGeneratorChangedEventArgs e ) - { - if( m_floatingDetails.Contains( masterItem ) ) - return; - - var nodeHelper = new GeneratorNodeHelper( m_startNode, 0, 0 ); - - // The master item has been found. - if( nodeHelper.FindItem( masterItem ) >= 0 ) - { - this.RemoveDetailContainers( e.Containers ); - - if( e.Action == NotifyCollectionChangedAction.Remove ) - { - var masterNode = ( ItemsGeneratorNode )nodeHelper.CurrentNode; - - masterNode.AdjustItemCount( -e.Count ); - detailNode.UpdateItemCount(); - } - - this.IncrementCurrentGenerationCount(); - this.SendRemoveEvent( e.Count, e.Containers ); - } - // The master item could be located inside a collapsed group. - else - { - //in that case, I need to determine the appropriate masterNode another way - nodeHelper = new GeneratorNodeHelper( m_startNode, 0, 0 ); - if( !nodeHelper.Contains( masterItem ) ) - throw DataGridException.Create( "An attempt was made to move or remove a detail for an item that does not belong to the generator.", m_dataGridControl ); - - if( e.Action == NotifyCollectionChangedAction.Remove ) - { - var masterNode = ( ItemsGeneratorNode )nodeHelper.CurrentNode; - - masterNode.AdjustItemCount( -e.Count ); - detailNode.UpdateItemCount(); - } - - this.IncrementCurrentGenerationCount(); - } - } - - private void HandleDetailReset( object masterItem, DetailGeneratorNode detailNode ) - { - using( this.TraceBlock( DataGridTraceEventId.CustomItemContainerGenerator_HandleDetailReset ) ) - { - if( m_floatingDetails.Contains( masterItem ) ) - { - this.TraceEvent( TraceEventType.Information, DataGridTraceEventId.CustomItemContainerGenerator_HandleDetailReset, DataGridTraceMessages.DetailIsFloating ); - return; - } - - var nodeHelper = new GeneratorNodeHelper( m_startNode, 0, 0 ); - var masterItemFound = ( nodeHelper.FindItem( masterItem ) >= 0 ); - - // The master item could be located inside a collapsed group. - if( !masterItemFound ) - { - nodeHelper = new GeneratorNodeHelper( m_startNode, 0, 0 ); - if( !nodeHelper.Contains( masterItem ) ) - { - this.TraceEvent( TraceEventType.Critical, DataGridTraceEventId.CustomItemContainerGenerator_HandleDetailReset, DataGridTraceMessages.ItemNotBelongingToGenerator ); - throw DataGridException.Create( "An attempt was made to reset a detail for an item that does not belong to the generator.", m_dataGridControl ); - } - - this.TraceEvent( TraceEventType.Information, DataGridTraceEventId.CustomItemContainerGenerator_HandleDetailReset, DataGridTraceMessages.ItemNotFoundOrCollapsed ); - } - - var masterNode = ( ItemsGeneratorNode )nodeHelper.CurrentNode; - var oldDetailCount = detailNode.ItemCount; - var oldContainers = m_genPosToContainer.Where( ( c, i ) => m_genPosToNode[ i ] == detailNode ).ToList(); - - using( detailNode.DetailGenerator.InhibitItemsChanged() ) - { - detailNode.UpdateItemCount(); - } - - var newDetailCount = detailNode.ItemCount; - var newContainers = detailNode.DetailGenerator.m_genPosToContainer; - - masterNode.AdjustItemCount( newDetailCount - oldDetailCount ); - - var containersRemoved = new HashSet(); - var containersMoved = new HashSet(); - - CustomItemContainerGenerator.FindChanges( oldContainers, newContainers, null, containersRemoved, containersMoved ); - this.ApplyDetailChanges( detailNode, newContainers, containersRemoved, containersMoved ); - } - } - - private DetailGeneratorNode FindDetailGeneratorNodeForGenerator( CustomItemContainerGenerator detailGenerator, out object masterItem ) - { - foreach( var detailsForItem in m_masterToDetails ) - { - foreach( var detailNode in detailsForItem.Value ) - { - if( detailNode.DetailGenerator == detailGenerator ) - { - masterItem = detailsForItem.Key; - return detailNode; - } - } - } - - masterItem = null; - return null; - } - - internal void SetGenPosToIndexUpdateInhibiter( IInhibitGenPosToIndexUpdating inhibiter ) - { - m_genPosToIndexInhibiter = inhibiter; - } - - private IDisposable InhibitParentGenPosToIndexUpdate() - { - if( m_genPosToIndexInhibiter != null ) - return m_genPosToIndexInhibiter.InhibitGenPosToIndexUpdates(); - - return null; - } - - private int FindFirstGeneratedIndexForLocalItem( object item ) - { - //this function will find an item in the m_genPosToItem, but will filter out those that belongs to details. - //This is to avoid the problem caused by Detail items that belongs also to a master. - var retval = -1; - var runningIndex = 0; - var itemCount = m_genPosToItem.Count; - - while( runningIndex < itemCount ) - { - retval = m_genPosToItem.IndexOf( item, runningIndex ); - - //No item found past the current runningIndex - if( retval == -1 ) - break; - - //check if the item belongs to a Detail or not. - var detailNode = m_genPosToNode[ retval ] as DetailGeneratorNode; - if( detailNode == null ) - break; //the item is not a detail and therefore qualifies as a return value. - - //Item is from a detail - runningIndex = retval + 1; - } - - return retval; - } - - private bool EnqueueContainer( DependencyObject container, object item ) - { - if( container is HeaderFooterItem ) - { - if( item is GroupHeaderFooterItem ) - { - //If the group does not exist anymore (i.e. all its rows have been deleted), do not recycle it. - var groupHeaderFooterItem = ( GroupHeaderFooterItem )item; - var collectionViewGroup = groupHeaderFooterItem.Group; - if( collectionViewGroup == null ) - return false; - - string groupBy = null; - if( collectionViewGroup is DataGridCollectionViewGroup ) - { - groupBy = ( ( DataGridCollectionViewGroup )collectionViewGroup ).GroupByName; - } - - if( string.IsNullOrEmpty( groupBy ) ) - { - var group = this.GetGroupFromCollectionViewGroupCore( collectionViewGroup ); - if( group == null ) - return false; - - groupBy = group.GroupBy; - if( string.IsNullOrEmpty( groupBy ) ) - return false; - } - - m_recyclingPools.GetGroupHeaderFooterItemContainerPool( m_dataGridContext.SourceDetailConfiguration, true ).Enqueue( groupBy, groupHeaderFooterItem.Template, container ); - } - else - { - m_recyclingPools.GetHeaderFooterItemContainerPool( m_dataGridContext.SourceDetailConfiguration, true ).Enqueue( item, container ); - } - } - else - { - m_recyclingPools.GetItemContainerPool( m_dataGridContext.SourceDetailConfiguration, true ).Enqueue( item, container ); - } - - return true; - } - - private DependencyObject DequeueItemContainer( object item ) - { - var pool = m_recyclingPools.GetItemContainerPool( m_dataGridContext.SourceDetailConfiguration ); - if( pool == null ) - return null; - - return pool.Dequeue( item ); - } - - private DependencyObject DequeueHeaderFooterContainer( object item ) - { - if( !( item is GroupHeaderFooterItem ) ) - { - var pool = m_recyclingPools.GetHeaderFooterItemContainerPool( m_dataGridContext.SourceDetailConfiguration ); - if( pool == null ) - return null; - - return pool.Dequeue( item ); - } - else - { - var pool = m_recyclingPools.GetGroupHeaderFooterItemContainerPool( m_dataGridContext.SourceDetailConfiguration ); - if( pool == null ) - return null; - - var groupHeaderFooterItem = ( GroupHeaderFooterItem )item; - var collectionViewGroup = groupHeaderFooterItem.Group; - if( collectionViewGroup == null ) - return null; - - string groupBy = null; - if( collectionViewGroup is DataGridCollectionViewGroup ) - { - groupBy = ( ( DataGridCollectionViewGroup )collectionViewGroup ).GroupByName; - } - - if( string.IsNullOrEmpty( groupBy ) ) - { - var group = this.GetGroupFromCollectionViewGroupCore( collectionViewGroup ); - if( group == null ) - return null; - - groupBy = group.GroupBy; - if( string.IsNullOrEmpty( groupBy ) ) - return null; - } - - return pool.Dequeue( groupBy, groupHeaderFooterItem.Template ); - } - } - - internal void CleanRecyclingCandidates() - { - m_recyclingPools.CleanRecyclingCandidates(); - } - - private void OnDetailContainersRemoved( object sender, ContainersRemovedEventArgs e ) - { - Debug.Assert( !this.IsRecyclingEnabled ); - - this.OnContainersRemoved( e.RemovedContainers ); - } - - private DependencyObject CreateNextItemContainer( object item ) - { - DependencyObject container = null; - - if( this.IsRecyclingEnabled ) - { - container = this.DequeueItemContainer( item ); - } - - if( container == null ) - { - container = m_dataGridControl.CreateContainerForItem(); - } - - return container; - } - - private IEnumerable GetDetailContexts() - { - return ( from node in this.GetDetailGeneratorNodes() - select node.DetailContext ); - } - - private IEnumerable GetDetailGenerators() - { - return ( from node in this.GetDetailGeneratorNodes() - select node.DetailGenerator ); - } - - private IEnumerable GetDetailGeneratorNodes() - { - foreach( List details in m_masterToDetails.Values ) - { - foreach( DetailGeneratorNode detailNode in details ) - { - yield return detailNode; - } - } - } - - private static IList GetList( CollectionView collectionView ) - { - if( collectionView == null ) - return null; - - var list = collectionView as IList; - if( list != null ) - return list; - - return collectionView.SourceCollection as IList; - } - - private static void FindChanges( - IList source, - IList destination, - ICollection itemsAdded, - ICollection itemsRemoved, - ICollection itemsMoved ) - { - if( source == null ) - throw new ArgumentNullException( "source" ); - - if( destination == null ) - throw new ArgumentNullException( "destination" ); - - // There is nothing to do since the caller is not interested by the result. - if( ( itemsAdded == null ) && ( itemsRemoved == null ) && ( itemsMoved == null ) ) - return; - - var sourceCount = source.Count; - var sourcePositions = new Dictionary( sourceCount ); - var sequence = new List( Math.Min( sourceCount, destination.Count ) ); - var isAlive = new BitArray( sourceCount, false ); - var hasNotMoved = default( BitArray ); - - for( var i = 0; i < sourceCount; i++ ) - { - sourcePositions.Add( source[ i ], i ); - } - - foreach( var item in destination ) - { - int index; - - if( sourcePositions.TryGetValue( item, out index ) ) - { - isAlive[ index ] = true; - sequence.Add( index ); - } - else if( itemsAdded != null ) - { - itemsAdded.Add( item ); - } - } - - // We may omit this part of the algorithm if the caller is not interested by the items that have moved. - if( itemsMoved != null ) - { - hasNotMoved = new BitArray( sourceCount, false ); - - // The subsequence contains the position of the item that are in the destination collection and that have not moved. - foreach( var index in LongestIncreasingSubsequence.Find( sequence ) ) - { - hasNotMoved[ index ] = true; - } - } - - // We may omit this part of the algorithm if the caller is not interested by the items that have moved or were removed. - if( ( itemsRemoved != null ) || ( itemsMoved != null ) ) - { - for( var i = 0; i < sourceCount; i++ ) - { - if( isAlive[ i ] ) - { - // We check if the move collection is not null first because the bit array is null when the move collection is null. - if( ( itemsMoved != null ) && !hasNotMoved[ i ] ) - { - itemsMoved.Add( source[ i ] ); - } - } - else if( itemsRemoved != null ) - { - itemsRemoved.Add( source[ i ] ); - } - } - } - } - - public void Skip() - { - if( m_generatorDirection == GeneratorDirection.Forward ) - { - this.MoveGeneratorForward(); - } - else - { - this.MoveGeneratorBackward(); - } - } - - #region Private Fields - - private BitVector32 m_flags = new BitVector32(); - - //This list is used to map from a Realized Item generator position to an actual index. Index in list is the GenPos Index. - private readonly List m_genPosToIndex = new List(); - private readonly List m_genPosToItem = new List(); - private readonly List m_genPosToContainer = new List(); - private readonly List m_genPosToNode = new List(); - - private readonly Dictionary> m_masterToDetails = new Dictionary>(); - private readonly List m_floatingDetails = new List(); - - private GeneratorNode m_startNode; - private GeneratorNode m_firstItem; - - private ReadOnlyObservableCollection m_groupsCollection; - - private readonly DataGridControl m_dataGridControl; - private readonly DataGridContext m_dataGridContext; - private readonly CollectionView m_collectionView; - - private readonly CustomItemContainerGeneratorRecyclingPools m_recyclingPools; - - private int m_lastValidItemCountGeneration = 0; - - private int m_cachedItemCount = 0; - - private GeneratorDirection m_generatorDirection; - private int m_generatorCurrentOffset; - private int m_generatorCurrentGlobalIndex = -1; - private GeneratorNodeHelper m_generatorNodeHelper; // = null - - private readonly Dictionary m_groupNodeMappingCache = new Dictionary(); - private LateGroupLevelDescription[] m_groupLevelDescriptionCache; // = null - - private IDisposable m_generatorCurrentDetailDisposable; // = null - private DetailGeneratorNode m_generatorCurrentDetail; // = null - private int m_generatorCurrentDetailIndex = -1; - private int m_generatorCurrentDetailNodeIndex = -1; - - private int m_genPosToIndexUpdateInhibitCount = 0; - - private IInhibitGenPosToIndexUpdating m_genPosToIndexInhibiter; // = null - private IDisposable m_currentGenPosToIndexInhibiterDisposable; // = null - - private Binding m_headerFooterDataContextBinding; - - #endregion - - #region IWeakEventListener Members - - 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( managerType == typeof( CollectionChangedEventManager ) ) - { - var eventArgs = ( ( NotifyCollectionChangedEventArgs )e ).GetRangeActionOrSelf(); - - if( sender == m_collectionView ) - { - this.OnItemsChanged( sender, eventArgs ); - } - else if( sender == m_groupsCollection ) - { - this.OnGroupsChanged( sender, eventArgs ); - } - else if( sender == m_dataGridContext.DetailConfigurations ) - { - this.OnDetailConfigurationsChanged( sender, eventArgs ); - } - } - else if( managerType == typeof( PropertyChangedEventManager ) ) - { - var eventArgs = ( PropertyChangedEventArgs )e; - - if( sender == m_collectionView ) - { - this.OnCollectionViewPropertyChanged( eventArgs ); - } - else - { - //this is only registered on the DataGridContext, this has the effect of forwarding property changes for all properties of the DataGridContext - this.OnNotifyPropertyChanged( eventArgs ); - } - } - else if( ( managerType == typeof( ViewChangedEventManager ) ) || ( managerType == typeof( ThemeChangedEventManager ) ) ) - { - this.OnViewThemeChanged( sender, e ); - } - else if( managerType == typeof( DetailsChangedEventManager ) ) - { - if( this.DetailsChanged != null ) - { - this.DetailsChanged( sender, e ); - } - } - else if( managerType == typeof( ItemsSourceChangeCompletedEventManager ) ) - { - this.OnItemsSourceChanged( sender, e ); - } - else if( managerType == typeof( GroupConfigurationSelectorChangedEventManager ) ) - { - this.OnGroupConfigurationSelectorChanged(); - } - else - { - return false; - } - - return true; - } - - #endregion - - #region INotifyPropertyChanged Members - - public event PropertyChangedEventHandler PropertyChanged; - - private void OnNotifyPropertyChanged( PropertyChangedEventArgs e ) - { - var handler = this.PropertyChanged; - if( handler == null ) - return; - - handler.Invoke( this, e ); - } - - #endregion - - #region IInhibitGenPosToIndexUpdating Members - - IDisposable IInhibitGenPosToIndexUpdating.InhibitGenPosToIndexUpdates() - { - return new GenPosToIndexInhibitionDisposable( this ); - } - - #endregion - - #region IDataGridContextVisitable Members - - void IDataGridContextVisitable.AcceptVisitor( IDataGridContextVisitor visitor, out bool visitWasStopped ) - { - IDataGridContextVisitable visitable = this as IDataGridContextVisitable; - - visitable.AcceptVisitor( 0, int.MaxValue, visitor, DataGridContextVisitorType.All, true, out visitWasStopped ); - } - - void IDataGridContextVisitable.AcceptVisitor( int minIndex, int maxIndex, IDataGridContextVisitor visitor, out bool visitWasStopped ) - { - IDataGridContextVisitable visitable = this as IDataGridContextVisitable; - - visitable.AcceptVisitor( minIndex, maxIndex, visitor, DataGridContextVisitorType.All, true, out visitWasStopped ); - } - - void IDataGridContextVisitable.AcceptVisitor( int minIndex, int maxIndex, IDataGridContextVisitor visitor, DataGridContextVisitorType visitorType, out bool visitWasStopped ) - { - IDataGridContextVisitable visitable = this as IDataGridContextVisitable; - - visitable.AcceptVisitor( minIndex, maxIndex, visitor, visitorType, true, out visitWasStopped ); - } - - void IDataGridContextVisitable.AcceptVisitor( int minIndex, int maxIndex, IDataGridContextVisitor visitor, DataGridContextVisitorType visitorType, bool visitDetails, out bool visitWasStopped ) - { - visitWasStopped = false; - - if( m_startNode == null ) - return; - - GeneratorNodeHelper nodeHelper = new GeneratorNodeHelper( m_startNode, 0, 0 ); - nodeHelper.ProcessVisit( m_dataGridContext, minIndex, maxIndex, visitor, visitorType, visitDetails, out visitWasStopped ); - } - - #endregion - - #region InheritAutoResetFlag Private Class - - private sealed class InheritAutoResetFlag : AutoResetFlag - { - internal InheritAutoResetFlag() - : this( null ) - { - } - - internal InheritAutoResetFlag( AutoResetFlag parent ) - { - m_parent = parent; - m_current = AutoResetFlagFactory.Create(); - } - - public override bool IsSet - { - get - { - return ( this.IsSetLocal ) - || ( ( m_parent != null ) && m_parent.IsSet ); - } - } - - public bool IsSetLocal - { - get - { - return m_current.IsSet; - } - } - - public override IDisposable Set() - { - return m_current.Set(); - } - - public IDisposable SetLocal() - { - return this.Set(); - } - - private readonly AutoResetFlag m_parent; - private readonly AutoResetFlag m_current; - } - - #endregion - - #region LeveledAutoResetFlag Private Class - - private sealed class LeveledAutoResetFlag : AutoResetFlag - { - internal LeveledAutoResetFlag() - : this( new List( 3 ), 0 ) - { - } - - private LeveledAutoResetFlag( IList levels, int index ) - { - Debug.Assert( levels != null ); - Debug.Assert( ( index >= 0 ) && ( index <= levels.Count ) ); - - m_levels = levels; - m_flag = AutoResetFlagFactory.Create(); - m_index = index; - - var self = new WeakReference( this ); - if( m_index == m_levels.Count ) - { - m_levels.Add( self ); - } - else - { - m_levels[ m_index ] = self; - } - } - - public override bool IsSet - { - get - { - if( m_flag.IsSet ) - return true; - - var parent = this.GetFlag( m_index - 1 ); - if( parent != null ) - return parent.IsSet; - - return false; - } - } - - public override IDisposable Set() - { - return m_flag.Set(); - } - - internal LeveledAutoResetFlag GetChild() - { - var index = m_index + 1; - var flag = this.GetFlag( index ); - - if( flag != null ) - return flag; - - return new LeveledAutoResetFlag( m_levels, index ); - } - - private LeveledAutoResetFlag GetFlag( int index ) - { - if( ( index < 0 ) || ( index >= m_levels.Count ) ) - return null; - - return ( LeveledAutoResetFlag )m_levels[ index ].Target; - } - - private readonly IList m_levels; - private readonly AutoResetFlag m_flag; - private readonly int m_index; - } - - #endregion - - #region BubbleDirtyFlag Private Class - - private sealed class BubbleDirtyFlag - { - internal BubbleDirtyFlag( bool isSet ) - : this( null, isSet ) - { - } - - internal BubbleDirtyFlag( BubbleDirtyFlag parent, bool isSet ) - { - m_parent = parent; - - this.IsSet = isSet; - } - - internal bool IsSet - { - get - { - return m_isSet; - } - set - { - if( value == m_isSet ) - return; - - m_isSet = value; - - if( value && ( m_parent != null ) ) - { - m_parent.IsSet = true; - } - } - } - - private readonly BubbleDirtyFlag m_parent; - private bool m_isSet; - } - - #endregion - - #region CustomItemContainerGeneratorDisposableDisposer Private Class - - private sealed class CustomItemContainerGeneratorDisposableDisposer : IDisposable - { - public CustomItemContainerGeneratorDisposableDisposer( CustomItemContainerGenerator generator, GeneratorPosition startGenPos, GeneratorDirection direction ) - { - if( generator == null ) - throw new ArgumentNullException( "generator" ); - - try - { - generator.StartGenerator( startGenPos, direction ); - } - catch( Exception e ) - { - try - { - generator.StopGenerator(); - } - catch - { - // We swallow all exceptions thrown here because the actual exception we want to raise to the user - // is the one that has been thrown in the call to StartGenerator. - } - - throw new DataGridInternalException( "The generator failed to start.", e, generator.m_dataGridControl ); - } - - m_generator = generator; - } - - void IDisposable.Dispose() - { - this.Dispose( true ); - GC.SuppressFinalize( this ); - } - - private void Dispose( bool disposing ) - { - // Prevent this method from being called more than once. - var generator = Interlocked.Exchange( ref m_generator, null ); - if( generator == null ) - return; - - generator.StopGenerator(); - } - - ~CustomItemContainerGeneratorDisposableDisposer() - { - this.Dispose( false ); - } - - private CustomItemContainerGenerator m_generator; //null - } - - #endregion - - #region GenPosToIndexInhibitionDisposable Private Class - - private sealed class GenPosToIndexInhibitionDisposable : IDisposable - { - internal GenPosToIndexInhibitionDisposable( CustomItemContainerGenerator generator ) - { - if( generator == null ) - throw new ArgumentNullException( "generator" ); - - m_generator = generator; - - Interlocked.Increment( ref m_generator.m_genPosToIndexUpdateInhibitCount ); - - if( m_generator.m_genPosToIndexInhibiter != null ) - { - m_nestedDisposable = m_generator.m_genPosToIndexInhibiter.InhibitGenPosToIndexUpdates(); - } - } - - private void Dispose( bool disposing ) - { - var generator = Interlocked.Exchange( ref m_generator, null ); - if( generator == null ) - return; - - if( Interlocked.Decrement( ref generator.m_genPosToIndexUpdateInhibitCount ) == 0 ) - { - if( generator.GenPosToIndexNeedsUpdate ) - { - generator.IncrementCurrentGenerationCount(); - } - } - - if( m_nestedDisposable != null ) - { - m_nestedDisposable.Dispose(); - m_nestedDisposable = null; - } - } - - void IDisposable.Dispose() - { - this.Dispose( true ); - GC.SuppressFinalize( this ); - } - - ~GenPosToIndexInhibitionDisposable() - { - this.Dispose( false ); - } - - private CustomItemContainerGenerator m_generator; // = null - private IDisposable m_nestedDisposable; // = null - } - - #endregion - - #region CustomItemContainerGeneratorFlags Private Enum - - [Flags] - private enum CustomItemContainerGeneratorFlags - { - RecyclingEnabled = 1 << 0, - InUse = 1 << 1, - GenPosToIndexNeedsUpdate = 1 << 2, - ForceReset = 1 << 3, - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/CustomItemContainerGeneratorRecyclingPools.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/CustomItemContainerGeneratorRecyclingPools.cs deleted file mode 100644 index 79678e3d..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/CustomItemContainerGeneratorRecyclingPools.cs +++ /dev/null @@ -1,306 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Windows; -using Xceed.Utils.Wpf; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class CustomItemContainerGeneratorRecyclingPools - { - #region ContainersRemoved Event - - internal event ContainersRemovedEventHandler ContainersRemoved; - - private void OnContainersRemoved() - { - if( ( m_containersRemoved == null ) || ( m_deferCount != 0 ) ) - return; - - var containers = m_containersRemoved; - m_containersRemoved = null; - - if( containers.Count <= 0 ) - return; - - var handler = this.ContainersRemoved; - if( handler == null ) - return; - - handler.Invoke( this, new ContainersRemovedEventArgs( containers ) ); - } - - #endregion - - #region RecyclingCandidateCleaned Event - - internal event RecyclingCandidatesCleanedEventHandler RecyclingCandidatesCleaned; - - private void OnRecyclingCandidatesCleaned( List recyclingCandidates ) - { - if( recyclingCandidates.Count == 0 ) - return; - - var handler = this.RecyclingCandidatesCleaned; - if( handler == null ) - return; - - handler.Invoke( this, new RecyclingCandidatesCleanedEventArgs( recyclingCandidates ) ); - } - - #endregion - - internal IDisposable DeferContainersRemoved() - { - return new DeferredDisposable( new DeferContainersRemovedState( this ) ); - } - - internal void Clear() - { - m_containersRemoved = m_containersRemoved ?? new List(); - - this.ClearPools( m_itemContainerPools, m_containersRemoved, pool => pool.Clear() ); - this.ClearPools( m_headerFooterItemContainerPools, m_containersRemoved, pool => pool.Clear() ); - this.ClearPools( m_groupHeaderFooterItemContainerPools, m_containersRemoved, pool => pool.Clear() ); - - this.OnContainersRemoved(); - } - - internal void Clear( DetailConfiguration detailConfiguration ) - { - m_containersRemoved = m_containersRemoved ?? new List(); - - var key = CustomItemContainerGeneratorRecyclingPools.GetKey( detailConfiguration ); - - var itemContainerPool = default( ItemContainerRecyclingPool ); - if( m_itemContainerPools.TryGetValue( key, out itemContainerPool ) ) - { - m_itemContainerPools.Remove( key ); - - this.ClearPool( itemContainerPool, m_containersRemoved, pool => pool.Clear() ); - } - - var headerFooterItemContainerPool = default( HeaderFooterItemContainerRecyclingPool ); - if( m_headerFooterItemContainerPools.TryGetValue( key, out headerFooterItemContainerPool ) ) - { - m_headerFooterItemContainerPools.Remove( key ); - - this.ClearPool( headerFooterItemContainerPool, m_containersRemoved, pool => pool.Clear() ); - } - - var groupHeaderFooterItemContainerPool = default( GroupHeaderFooterItemContainerRecyclingPool ); - if( m_groupHeaderFooterItemContainerPools.TryGetValue( key, out groupHeaderFooterItemContainerPool ) ) - { - m_groupHeaderFooterItemContainerPools.Remove( key ); - - this.ClearPool( groupHeaderFooterItemContainerPool, m_containersRemoved, pool => pool.Clear() ); - } - - this.OnContainersRemoved(); - } - - internal void CleanRecyclingCandidates() - { - var recyclingCandidates = new List( 4 ); - - foreach( var pool in m_itemContainerPools.Values ) - { - foreach( var container in pool ) - { - var dataGridItemContainer = container as IDataGridItemContainer; - if( dataGridItemContainer != null && dataGridItemContainer.IsRecyclingCandidate ) - { - dataGridItemContainer.IsRecyclingCandidate = false; - dataGridItemContainer.CleanRecyclingCandidate(); - recyclingCandidates.Add( container ); - } - } - } - - foreach( var pool in m_headerFooterItemContainerPools.Values ) - { - foreach( var container in pool ) - { - var dataGridItemContainer = container as IDataGridItemContainer; - if( dataGridItemContainer != null && dataGridItemContainer.IsRecyclingCandidate ) - { - dataGridItemContainer.IsRecyclingCandidate = false; - dataGridItemContainer.CleanRecyclingCandidate(); - recyclingCandidates.Add( container ); - } - } - } - - foreach( var pool in m_groupHeaderFooterItemContainerPools.Values ) - { - foreach( var container in pool ) - { - var dataGridItemContainer = container as IDataGridItemContainer; - if( dataGridItemContainer != null && dataGridItemContainer.IsRecyclingCandidate ) - { - dataGridItemContainer.IsRecyclingCandidate = false; - dataGridItemContainer.CleanRecyclingCandidate(); - recyclingCandidates.Add( container ); - } - } - } - - this.OnRecyclingCandidatesCleaned( recyclingCandidates ); - } - - internal ItemContainerRecyclingPool GetItemContainerPool( DetailConfiguration detailConfiguration ) - { - return this.GetPool( m_itemContainerPools, detailConfiguration, false ); - } - - internal ItemContainerRecyclingPool GetItemContainerPool( DetailConfiguration detailConfiguration, bool create ) - { - return this.GetPool( m_itemContainerPools, detailConfiguration, create ); - } - - internal HeaderFooterItemContainerRecyclingPool GetHeaderFooterItemContainerPool( DetailConfiguration detailConfiguration ) - { - return this.GetPool( m_headerFooterItemContainerPools, detailConfiguration, false ); - } - - internal HeaderFooterItemContainerRecyclingPool GetHeaderFooterItemContainerPool( DetailConfiguration detailConfiguration, bool create ) - { - return this.GetPool( m_headerFooterItemContainerPools, detailConfiguration, create ); - } - - internal GroupHeaderFooterItemContainerRecyclingPool GetGroupHeaderFooterItemContainerPool( DetailConfiguration detailConfiguration ) - { - return this.GetPool( m_groupHeaderFooterItemContainerPools, detailConfiguration, false ); - } - - internal GroupHeaderFooterItemContainerRecyclingPool GetGroupHeaderFooterItemContainerPool( DetailConfiguration detailConfiguration, bool create ) - { - return this.GetPool( m_groupHeaderFooterItemContainerPools, detailConfiguration, create ); - } - - private T GetPool( Dictionary pools, DetailConfiguration detailConfiguration, bool create ) where T : class, new() - { - if( pools == null ) - throw new ArgumentNullException( "pools" ); - - var key = CustomItemContainerGeneratorRecyclingPools.GetKey( detailConfiguration ); - var pool = default( T ); - - if( !pools.TryGetValue( key, out pool ) ) - { - if( create ) - { - pool = new T(); - pools.Add( key, pool ); - } - else - { - pool = null; - } - } - - return pool; - } - - private void ClearPools( - Dictionary pools, - ICollection containers, - Action clearPool ) where T : IEnumerable - { - Debug.Assert( pools != null ); - - foreach( var pool in pools.Values ) - { - this.ClearPool( pool, containers, clearPool ); - } - - pools.Clear(); - } - - private void ClearPool( - T pool, - ICollection containers, - Action clearPool ) where T : IEnumerable - { - Debug.Assert( pool != null ); - Debug.Assert( clearPool != null ); - - foreach( var container in pool ) - { - containers.Add( container ); - } - - clearPool.Invoke( pool ); - } - - private static object GetKey( DetailConfiguration detailConfiguration ) - { - return detailConfiguration ?? CustomItemContainerGeneratorRecyclingPools.MasterConfiguration; - } - - private static readonly object MasterConfiguration = new object(); - - private int m_deferCount; //0 - private List m_containersRemoved; //null - - private readonly Dictionary m_itemContainerPools = new Dictionary(); - private readonly Dictionary m_headerFooterItemContainerPools = new Dictionary(); - private readonly Dictionary m_groupHeaderFooterItemContainerPools = new Dictionary(); - - #region DeferContainersRemovedState Private Class - - private sealed class DeferContainersRemovedState : DeferredDisposableState - { - internal DeferContainersRemovedState( CustomItemContainerGeneratorRecyclingPools target ) - { - if( target == null ) - throw new ArgumentNullException( "target" ); - - m_target = target; - } - - protected override bool IsDeferred - { - get - { - return ( m_target.m_deferCount != 0 ); - } - } - - protected override void Increment() - { - m_target.m_deferCount++; - } - - protected override void Decrement() - { - m_target.m_deferCount--; - } - - protected override void OnDeferEnded( bool disposing ) - { - m_target.OnContainersRemoved(); - } - - private readonly CustomItemContainerGeneratorRecyclingPools m_target; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/DataItemDataProvider.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/DataItemDataProvider.cs deleted file mode 100644 index 5e24629e..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/DataItemDataProvider.cs +++ /dev/null @@ -1,109 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.ComponentModel; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class DataItemDataProvider : DataItemDataProviderBase - { - #region Static Fields - - private static readonly object EmptyDataItem = new object(); - - #endregion - - #region IsEmpty Property - - public override bool IsEmpty - { - get - { - return m_isEmpty; - } - } - - private void SetIsEmpty( bool value ) - { - if( m_isEmpty == value ) - return; - - m_isEmpty = value; - - this.OnPropertyChanged( new PropertyChangedEventArgs( "IsEmpty" ) ); - } - - private bool m_isEmpty = true; - - #endregion - - public override void SetDataItem( object dataItem ) - { - if( m_dataItem == dataItem ) - return; - - m_dataItem = dataItem; - - if( this.IsRefreshDeferred ) - return; - - this.Refresh(); - } - - public override void ClearDataItem() - { - if( m_dataItem == DataItemDataProvider.EmptyDataItem ) - return; - - m_dataItem = DataItemDataProvider.EmptyDataItem; - - if( this.IsRefreshDeferred ) - return; - - this.Refresh(); - } - - protected override void BeginQuery() - { - if( this.IsRefreshDeferred ) - return; - - base.BeginQuery(); - - if( m_dataItem == DataItemDataProvider.EmptyDataItem ) - { - this.OnQueryFinished( null, null, this.OnDataChanged, true ); - } - else - { - this.OnQueryFinished( m_dataItem, null, this.OnDataChanged, false ); - } - } - - private object OnDataChanged( object arg ) - { - this.SetIsEmpty( ( bool )arg ); - - return null; - } - - #region Private Fields - - private object m_dataItem = DataItemDataProvider.EmptyDataItem; - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/DataItemDataProviderBase.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/DataItemDataProviderBase.cs deleted file mode 100644 index 83187b67..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/DataItemDataProviderBase.cs +++ /dev/null @@ -1,38 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Windows.Data; -using Xceed.Wpf.DataGrid.Utils; - -namespace Xceed.Wpf.DataGrid -{ - internal abstract class DataItemDataProviderBase : DataSourceProvider - { - internal static readonly string DataPropertyName = PropertyHelper.GetPropertyName( ( DataItemDataProviderBase s ) => s.Data ); - - #region IsEmpty Property - - public abstract bool IsEmpty - { - get; - } - - #endregion - - public abstract void SetDataItem( object dataItem ); - public abstract void ClearDataItem(); - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/DetailGeneratorNode.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/DetailGeneratorNode.cs deleted file mode 100644 index e2e791fa..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/DetailGeneratorNode.cs +++ /dev/null @@ -1,80 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid -{ - internal partial class DetailGeneratorNode : GeneratorNode - { - internal DetailGeneratorNode( DataGridContext dataGridContext, CustomItemContainerGenerator generator ) - : base( null ) - { - if( dataGridContext == null ) - throw new ArgumentNullException( "dataGridContext" ); - - if( generator == null ) - throw new ArgumentNullException( "generator" ); - - m_dataGridContext = dataGridContext; - m_generator = generator; - m_itemCount = generator.ItemCount; - } - - public CustomItemContainerGenerator DetailGenerator - { - get - { - return m_generator; - } - } - - public DataGridContext DetailContext - { - get - { - return m_dataGridContext; - } - } - - internal override int ItemCount - { - get - { - return m_itemCount; - } - } - - internal override void CleanGeneratorNode() - { - base.CleanGeneratorNode(); - - m_generator.CleanupGenerator( true ); - m_dataGridContext.CleanDataGridContext(); - - m_generator = null; - } - - public void UpdateItemCount() - { - m_itemCount = m_generator.ItemCount; - } - - private readonly DataGridContext m_dataGridContext; - private CustomItemContainerGenerator m_generator; - private int m_itemCount; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/EmptyDataItemDataProvider.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/EmptyDataItemDataProvider.cs deleted file mode 100644 index 0b9c4af9..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/EmptyDataItemDataProvider.cs +++ /dev/null @@ -1,70 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Threading; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class EmptyDataItemDataProvider : DataItemDataProviderBase - { - #region Constructor - - private EmptyDataItemDataProvider() - { - } - - #endregion - - #region Instance Static Property - - internal static EmptyDataItemDataProvider Instance - { - get - { - if( m_instance == null ) - { - Interlocked.CompareExchange( ref EmptyDataItemDataProvider.m_instance, new EmptyDataItemDataProvider(), null ); - } - - return m_instance; - } - } - - private static EmptyDataItemDataProvider m_instance; - - #endregion - - #region IsEmpty Property - - public override bool IsEmpty - { - get - { - return true; - } - } - - #endregion - - public override void SetDataItem( object dataItem ) - { - } - - public override void ClearDataItem() - { - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/ExpansionStateEventArgs.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/ExpansionStateEventArgs.cs deleted file mode 100644 index dcad5454..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/ExpansionStateEventArgs.cs +++ /dev/null @@ -1,58 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid -{ - internal class ExpansionStateChangedEventArgs : EventArgs - { - public ExpansionStateChangedEventArgs( bool newExpansionState, int nodeIndexOffset, int itemCount ) - { - m_expansionState = newExpansionState; - m_offset = nodeIndexOffset; - m_count = itemCount; - } - - public bool NewExpansionState - { - get - { - return m_expansionState; - } - } - - public int IndexOffset - { - get - { - return m_offset; - } - } - - public int Count - { - get - { - return m_count; - } - } - - private readonly bool m_expansionState; - private readonly int m_offset; - private readonly int m_count; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/GeneratorNode.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/GeneratorNode.cs deleted file mode 100644 index 193cde13..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/GeneratorNode.cs +++ /dev/null @@ -1,153 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; - -namespace Xceed.Wpf.DataGrid -{ - internal partial class GeneratorNode - { - internal GeneratorNode( GeneratorNode parent ) - { - this.Parent = parent; - } - - //------------- - // Events - internal event EventHandler ExpansionStateChanged; - - //------------- - // Properties - - internal GeneratorNode Previous; - - internal GeneratorNode Next; - - internal GeneratorNode Parent; - - internal int Level - { - get - { - int count = 0; - - GeneratorNode runningPtr = this; - - while( runningPtr.Parent != null ) - { - runningPtr = runningPtr.Parent; - count++; - } - - return count; - } - } - - internal virtual int ItemCount - { - get - { - return 0; - } - } - - internal bool IsComputedExpanded - { - get - { - bool expanded = true; - - GeneratorNode runningPtr = this; - - while( runningPtr != null ) - { - expanded = runningPtr.IsComputedExpandedOverride; - if( expanded == false ) - { - break; - } - - runningPtr = runningPtr.Parent; - } - - return expanded; - } - } - - protected virtual bool IsComputedExpandedOverride - { - get - { - //default implementation... - return true; - } - } - - //------------- - // Methods - - internal virtual void CleanGeneratorNode() - { - this.Previous = null; - this.Parent = null; - this.Next = null; - } - - internal void AdjustItemCount( int delta ) - { - delta = this.AdjustItemCountOverride( delta ); - - if( ( this.Parent != null ) && ( delta != 0 ) ) - { - this.Parent.AdjustItemCount( delta ); - } - } - - internal void AdjustLeafCount( int delta ) - { - delta = this.AdjustLeafCountOverride( delta ); - - if( ( this.Parent != null ) && ( delta != 0 ) ) - { - this.Parent.AdjustLeafCount( delta ); - } - } - - protected virtual int AdjustItemCountOverride( int delta ) - { - return delta; - } - - protected virtual int AdjustLeafCountOverride( int delta ) - { - return delta; - } - - internal virtual void NotifyExpansionStateChanged( bool isParentExpanded ) - { - } - - protected void OnExpansionStateChanged( bool newExpansionState, int itemOffset, int count ) - { - var handler = this.ExpansionStateChanged; - if( handler == null ) - return; - - handler.Invoke( this, new ExpansionStateChangedEventArgs( newExpansionState, itemOffset, count ) ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/GeneratorNodeFactory.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/GeneratorNodeFactory.cs deleted file mode 100644 index be0703fc..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/GeneratorNodeFactory.cs +++ /dev/null @@ -1,404 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Diagnostics; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; - -namespace Xceed.Wpf.DataGrid -{ - internal class GeneratorNodeFactory : IWeakEventListener - { - public GeneratorNodeFactory( NotifyCollectionChangedEventHandler itemsChangedHandler, - NotifyCollectionChangedEventHandler groupsChangedHandler, - NotifyCollectionChangedEventHandler headersFootersChangedHandler, - EventHandler expansionStateChangedHandler, - EventHandler isExpandedChangingHandler, - EventHandler isExpandedChangedHandler, - DataGridControl dataGridControl ) - { - if( itemsChangedHandler == null ) - throw new ArgumentNullException( "itemsChangedHandler" ); - - if( groupsChangedHandler == null ) - throw new ArgumentNullException( "groupsChangedHandler" ); - - if( headersFootersChangedHandler == null ) - throw new ArgumentNullException( "headersFootersChangedHandler" ); - - if( expansionStateChangedHandler == null ) - throw new ArgumentNullException( "expansionStateChangedHandler" ); - - if( isExpandedChangingHandler == null ) - throw new ArgumentNullException( "isExpandedChangingHandler" ); - - if( isExpandedChangedHandler == null ) - throw new ArgumentNullException( "isExpandedChangedHandler" ); - - m_itemsChangedHandler = itemsChangedHandler; - m_groupsChangedHandler = groupsChangedHandler; - m_headersFootersChangedHandler = headersFootersChangedHandler; - m_expansionStateChangedHandler = expansionStateChangedHandler; - m_isExpandedChangingHandler = isExpandedChangingHandler; - m_isExpandedChangedHandler = isExpandedChangedHandler; - - if( dataGridControl != null ) - { - m_dataGridControl = new WeakReference( dataGridControl ); - } - } - - #region DataGridControl Private Property - - private DataGridControl DataGridControl - { - get - { - if( m_dataGridControl == null ) - return null; - - return m_dataGridControl.Target as DataGridControl; - } - } - - //For exception purposes only. - private readonly WeakReference m_dataGridControl; //null - - #endregion - - public GeneratorNode CreateGroupGeneratorNode( - CollectionViewGroup collectionViewGroup, - GeneratorNode parent, - GeneratorNode previous, - GeneratorNode next, - GroupConfiguration groupConfig ) - { - Debug.Assert( collectionViewGroup != null, "collectionViewGroup cannot be null for CreateGroupGeneratorNode()" ); - - GroupGeneratorNode node = new GroupGeneratorNode( collectionViewGroup, parent, groupConfig ); - - if( previous != null ) - { - previous.Next = node; - } - node.Previous = previous; - - if( next != null ) - { - next.Previous = node; - } - node.Next = next; - - node.SetIsExpandedAtInitialization( groupConfig.InitiallyExpanded ); - - if( !collectionViewGroup.IsBottomLevel ) - { - this.RegisterNodeCollectionChanged( - ( INotifyCollectionChanged )collectionViewGroup.GetItems(), - new NotifyCollectionChangedEventHandler( node.OnCollectionChanged ) ); - - node.CollectionChanged += m_groupsChangedHandler; - } - - node.ExpansionStateChanged += m_expansionStateChangedHandler; - node.IsExpandedChanging += m_isExpandedChangingHandler; - node.IsExpandedChanged += m_isExpandedChangedHandler; - - node.AdjustItemCount( node.ItemCount ); - - node.BuildNamesTree(); - - return node; - } - - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "generator" )] - public GeneratorNode CreateItemsGeneratorNode( - IList collection, - GeneratorNode parent, - GeneratorNode previous, - GeneratorNode next ) - { - Debug.Assert( collection != null, "collection cannot be null for CreateItemsGeneratorNode()" ); - - INotifyCollectionChanged notifyCollection = collection as INotifyCollectionChanged; - - Debug.Assert( notifyCollection != null, "collection must be a INotifyCollectionChanged for CreateItemsGeneratorNode()" ); - - ItemCollection itemCollection = collection as ItemCollection; - if( itemCollection != null ) - { - DataGridCollectionView dgcv = itemCollection.SourceCollection as DataGridCollectionView; - if( dgcv != null ) - { - collection = dgcv; - } - } - - ItemsGeneratorNode node = new ItemsGeneratorNode( collection, parent ); - - this.SetupCollectionGeneratorNode( node, parent, previous, next ); - - node.AdjustLeafCount( node.Items.Count ); - - return node; - } - - public HeadersFootersGeneratorNode CreateHeadersFootersGeneratorNode( - IList collection, - GeneratorNode parent, - GeneratorNode previous, - GeneratorNode next ) - { - Debug.Assert( collection != null, "collection cannot be null for CreateHeadersFootersGeneratorNode()" ); - - INotifyCollectionChanged notifyCollection = collection as INotifyCollectionChanged; - - Debug.Assert( notifyCollection != null, "collection must be a INotifyCollectionChanged for CreateHeadersFootersGeneratorNode()" ); - - HeadersFootersGeneratorNode node = new HeadersFootersGeneratorNode( collection, parent ); - - if( previous != null ) - { - previous.Next = node; - } - node.Previous = previous; - - if( next != null ) - { - next.Previous = node; - } - node.Next = next; - - node.ExpansionStateChanged += m_expansionStateChangedHandler; - - this.ConfigureHeadersFootersNotification( notifyCollection, node ); - - if( parent != null ) - { - node.AdjustItemCount( node.ItemCount ); - } - - return node; - } - - public void CleanGeneratorNodeTree( GeneratorNode node ) - { - if( node.Parent != null ) - { - node.Parent.AdjustItemCount( -node.ItemCount ); - - GroupGeneratorNode parentGroupNode = node.Parent as GroupGeneratorNode; - if( ( parentGroupNode != null ) && ( parentGroupNode.Child == node ) ) - { - parentGroupNode.Child = null; - } - } - - GeneratorNode child; - GeneratorNode next; - - do - { - GroupGeneratorNode groupNode = node as GroupGeneratorNode; - - next = node.Next; - child = ( groupNode != null ) ? groupNode.Child : null; - - this.CleanGeneratorNode( node ); - - //this recursive function cleans up the tree of nodes - if( child != null ) - { - this.CleanGeneratorNodeTree( child ); - } - - node = next; - } - while( node != null ); - } - - public void CleanGeneratorNode( GeneratorNode node ) - { - HeadersFootersGeneratorNode headersFootersNode = node as HeadersFootersGeneratorNode; - if( headersFootersNode != null ) - { - this.CleanHeadersFootersNotification( headersFootersNode ); - } - else - { - ItemsGeneratorNode itemsNode = node as ItemsGeneratorNode; - if( itemsNode != null ) - { - this.UnregisterNodeCollectionChanged( ( INotifyCollectionChanged )itemsNode.Items ); - itemsNode.CollectionChanged -= m_itemsChangedHandler; - } - else - { - GroupGeneratorNode groupNode = node as GroupGeneratorNode; - if( groupNode != null ) - { - IList subItems = groupNode.CollectionViewGroup.GetItems(); - - this.UnregisterNodeCollectionChanged( ( INotifyCollectionChanged )subItems ); - - groupNode.CollectionChanged -= m_groupsChangedHandler; - groupNode.IsExpandedChanging -= m_isExpandedChangingHandler; - groupNode.IsExpandedChanged -= m_isExpandedChangedHandler; - } - } - } - - node.ExpansionStateChanged -= m_expansionStateChangedHandler; - - node.CleanGeneratorNode(); - } - - private void SetupCollectionGeneratorNode( CollectionGeneratorNode newNode, GeneratorNode parent, GeneratorNode previous, GeneratorNode next ) - { - if( previous != null ) - { - previous.Next = newNode; - } - newNode.Previous = previous; - - if( next != null ) - { - next.Previous = newNode; - } - newNode.Next = next; - - this.RegisterNodeCollectionChanged( ( INotifyCollectionChanged )newNode.Items, new NotifyCollectionChangedEventHandler( newNode.OnCollectionChanged ) ); - - newNode.CollectionChanged += m_itemsChangedHandler; - newNode.ExpansionStateChanged += m_expansionStateChangedHandler; - - if( parent != null ) - { - newNode.AdjustItemCount( newNode.ItemCount ); - } - } - - private void ConfigureHeadersFootersNotification( INotifyCollectionChanged collection, HeadersFootersGeneratorNode node ) - { - ICollection nodeList; - if( !m_headersFootersMapping.TryGetValue( collection, out nodeList ) ) - { - nodeList = new HashSet(); - - m_headersFootersMapping.Add( collection, nodeList ); - CollectionChangedEventManager.AddListener( collection, this ); - } - - nodeList.Add( node ); - } - - private void CleanHeadersFootersNotification( HeadersFootersGeneratorNode node ) - { - var collection = node.Items as INotifyCollectionChanged; - if( collection == null ) - return; - - try - { - var nodeList = m_headersFootersMapping[ collection ]; - nodeList.Remove( node ); - - if( nodeList.Count == 0 ) - { - CollectionChangedEventManager.RemoveListener( collection, this ); - m_headersFootersMapping.Remove( collection ); - } - } - catch( Exception e ) - { - throw new DataGridInternalException( e.Message, e, this.DataGridControl ); - } - } - - private void RegisterNodeCollectionChanged( INotifyCollectionChanged source, NotifyCollectionChangedEventHandler handler ) - { - m_nodesCollectionChangedEventHandlers.Add( source, handler ); - CollectionChangedEventManager.AddListener( source, this ); - } - - private void UnregisterNodeCollectionChanged( INotifyCollectionChanged source ) - { - if( m_nodesCollectionChangedEventHandlers.Remove( source ) ) - { - CollectionChangedEventManager.RemoveListener( source, this ); - } - } - - #region IWeakEventListener Members - - 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( managerType == typeof( CollectionChangedEventManager ) ) - { - this.OnCollectionChanged( ( INotifyCollectionChanged )sender, ( NotifyCollectionChangedEventArgs )e ); - } - else - { - return false; - } - - return true; - } - - private void OnCollectionChanged( INotifyCollectionChanged source, NotifyCollectionChangedEventArgs e ) - { - NotifyCollectionChangedEventHandler handler; - ICollection nodeList; - - if( m_nodesCollectionChangedEventHandlers.TryGetValue( source, out handler ) ) - { - handler.Invoke( source, e ); - } - else if( m_headersFootersMapping.TryGetValue( source, out nodeList ) ) - { - Debug.Assert( nodeList.Count > 0 ); - - m_headersFootersChangedHandler.Invoke( nodeList, e ); - } - } - - #endregion - - #region Private Fields - - private readonly NotifyCollectionChangedEventHandler m_itemsChangedHandler; - private readonly NotifyCollectionChangedEventHandler m_groupsChangedHandler; - private readonly NotifyCollectionChangedEventHandler m_headersFootersChangedHandler; - private readonly EventHandler m_expansionStateChangedHandler; - private readonly EventHandler m_isExpandedChangedHandler; - private readonly EventHandler m_isExpandedChangingHandler; - - private readonly Dictionary> m_headersFootersMapping = new Dictionary>( 32 ); - private readonly Dictionary m_nodesCollectionChangedEventHandlers = new Dictionary( 32 ); - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/GeneratorNodeHelper.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/GeneratorNodeHelper.cs deleted file mode 100644 index 1a448bf4..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/GeneratorNodeHelper.cs +++ /dev/null @@ -1,1152 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Diagnostics; -using System.Windows; -using System.Windows.Data; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class GeneratorNodeHelper - { - internal GeneratorNodeHelper( GeneratorNode startNode, int index, int sourceDataIndex ) - { - if( startNode == null ) - throw new ArgumentNullException( "startNode" ); - - m_state = new State( startNode, index, sourceDataIndex ); - } - - internal GeneratorNode CurrentNode - { - get - { - return m_state.Node; - } - } - - internal int Index - { - get - { - return m_state.Index; - } - } - - internal int SourceDataIndex - { - get - { - return m_state.DataIndex; - } - } - - internal bool MoveToNext() - { - var success = GeneratorNodeHelper.MoveToNext( ref m_state ); - - this.EnsureState(); - - return success; - } - - internal bool MoveToNextBy( int count ) - { - var success = GeneratorNodeHelper.MoveToNext( ref m_state, count ); - - this.EnsureState(); - - return success; - } - - internal bool MoveToPrevious() - { - var success = GeneratorNodeHelper.MoveToPrevious( ref m_state ); - - this.EnsureState(); - - return success; - } - - internal bool MoveToFirst() - { - GeneratorNodeHelper.MoveToFirst( ref m_state ); - - this.EnsureState(); - - return true; - } - - internal bool MoveToEnd() - { - // We call MoveToNext instead of MoveToEnd because MoveToEnd includes the indexes of the last node. - while( GeneratorNodeHelper.MoveToNext( ref m_state ) ) - { - } - - this.EnsureState(); - - return true; - } - - internal bool MoveToChild( bool skipItemLessGroupNodes ) - { - var success = GeneratorNodeHelper.MoveToChild( ref m_state, skipItemLessGroupNodes ); - - this.EnsureState(); - - return success; - } - - internal bool MoveToParent() - { - var success = GeneratorNodeHelper.MoveToParent( ref m_state ); - - this.EnsureState(); - - return success; - } - - internal bool InsertAfter( GeneratorNode insert ) - { - if( insert == null ) - throw new DataGridInternalException( "GeneratorNode is null." ); - - var insertionCount = default( int ); - var chainLength = default( int ); - var insertLast = GeneratorNodeHelper.EvaluateChain( insert, out insertionCount, out chainLength ); - - var nextNode = m_state.Node.Next; - if( nextNode != null ) - { - nextNode.Previous = insertLast; - } - - insertLast.Next = nextNode; - insert.Previous = m_state.Node; - m_state.Node.Next = insert; - - // Move the current node to the last node inserted - if( !this.MoveToNextBy( chainLength ) ) - throw new DataGridInternalException( "Unable to move to the requested generator index." ); - - return true; - } - - internal bool InsertBefore( GeneratorNode insert ) - { - if( insert == null ) - throw new DataGridInternalException( "GeneratorNode is null" ); - - var insertionCount = default( int ); - var chainLength = default( int ); - var insertLast = GeneratorNodeHelper.EvaluateChain( insert, out insertionCount, out chainLength ); - - var previousNode = m_state.Node.Previous; - if( previousNode != null ) - { - previousNode.Next = insert; - } - - insert.Previous = previousNode; - m_state.Node.Previous = insertLast; - insertLast.Next = m_state.Node; - - var parentGroup = insert.Parent as GroupGeneratorNode; - if( parentGroup != null ) - { - if( parentGroup.Child == m_state.Node ) - { - parentGroup.Child = insert; - } - } - - // Move the current to the first item inserted. - // No need to update the indexes since they will still be with the correct value. - m_state.Node = insert; - - this.EnsureState(); - - return true; - } - - internal int FindItem( object item ) - { - var current = m_state; - - while( true ) - { - var itemsNode = current.Node as ItemsGeneratorNode; - if( itemsNode != null ) - { - var index = itemsNode.Items.IndexOf( item ); - if( index >= 0 ) - { - index += itemsNode.CountDetailsBeforeDataIndex( index ); - - // Item is directly from this items node... then return the appropriate index! - m_state = current; - - this.EnsureState(); - - return index + current.Index; - } - - // If the item is from a detail, then I don't want to "use" it!!! - // but continue looping.... to find occurances of this item somewhere else in the tree. - } - else - { - var collectionNode = current.Node as CollectionGeneratorNode; - if( collectionNode != null ) - { - var index = collectionNode.IndexOf( item ); - if( index >= 0 ) - { - m_state = current; - - this.EnsureState(); - - return index + current.Index; - } - } - } - - // If we reach this point, it's because the item we are looking - // for is not in this node... Try to access the child - if( !GeneratorNodeHelper.MoveToChild( ref current ) ) - { - // Try "advancing" to the next item. - if( !GeneratorNodeHelper.MoveToFollowing( ref current ) ) - break; - } - } - - return -1; - } - - internal object FindIndex( int index ) - { - var current = m_state; - - while( true ) - { - if( index < current.Index + current.Node.ItemCount ) - { - var itemsNode = current.Node as CollectionGeneratorNode; - if( itemsNode != null ) - { - m_state = current; - - this.EnsureState(); - - return itemsNode.GetAt( index - current.Index ); - } - - if( !GeneratorNodeHelper.MoveToChild( ref current ) ) - break; - } - else - { - // If we reach this point, it's because the item we are looking for is not in this node... Try to access the child. - // No need to check for childs, since the condition above would catch it (childs part of ItemCount). - if( !GeneratorNodeHelper.MoveToFollowing( ref current ) ) - break; - } - } - - return null; - } - - internal bool FindNode( GeneratorNode node ) - { - if( node == null ) - throw new ArgumentNullException( "node" ); - - var success = GeneratorNodeHelper.FindNode( ref m_state, node ); - - this.EnsureState(); - - return success; - } - - internal bool FindNodeForIndex( int index ) - { - var success = GeneratorNodeHelper.FindNodeForIndex( ref m_state, index ); - - this.EnsureState(); - - return success; - } - - //Note: this function will not check for the presence of the item in the details for Items nodes. - internal bool AbsoluteFindItem( object item ) - { - // This method will search through nodes, even those collapsed for the item. - var current = m_state; - - while( true ) - { - var itemsNode = current.Node as CollectionGeneratorNode; - if( ( itemsNode != null ) && itemsNode.Items.Contains( item ) ) - break; - - // If we reach this point, it's because the item we are looking - // for is not in this node... Try to access the child - if( !GeneratorNodeHelper.MoveToChild( ref current, false ) ) - { - // Try "advancing" to the next item. - if( !GeneratorNodeHelper.MoveToFollowing( ref current ) ) - return false; - } - } - - m_state = current; - - this.EnsureState(); - - return true; - } - - //Note: this function will not check for the presence of the group in the details for Items nodes. - internal bool FindGroup( CollectionViewGroup group ) - { - if( group == null ) - return false; - - var current = m_state; - - while( true ) - { - var groupNode = current.Node as GroupGeneratorNode; - if( groupNode != null ) - { - if( groupNode.CollectionViewGroup == group ) - break; - - if( !groupNode.CollectionViewGroup.IsBottomLevel ) - { - if( !GeneratorNodeHelper.MoveToChild( ref current, false ) ) - return false; - } - else - { - if( !GeneratorNodeHelper.MoveToFollowing( ref current ) ) - return false; - } - } - else - { - // There is nothing under a non GroupGeneratorNode, try to move Next node in the list. - if( !GeneratorNodeHelper.MoveToFollowing( ref current ) ) - return false; - } - } - - m_state = current; - - this.EnsureState(); - - return true; - } - - internal void ReverseCalculateIndex() - { - m_state = GeneratorNodeHelper.FindNodeLocation( m_state.Node ); - - this.EnsureState(); - } - - internal bool MoveForward() - { - var startNode = m_state.Node; - - while( true ) - { - if( !( m_state.Node is GroupGeneratorNode ) && ( m_state.Node != startNode ) && ( m_state.Node.ItemCount != 0 ) ) - break; - - if( !GeneratorNodeHelper.MoveToChild( ref m_state ) ) - { - if( !GeneratorNodeHelper.MoveToFollowing( ref m_state ) ) - return false; - } - } - - this.EnsureState(); - - return true; - } - - internal bool MoveBackward() - { - var startNode = m_state.Node; - - while( true ) - { - if( !( m_state.Node is GroupGeneratorNode ) && ( m_state.Node != startNode ) && ( m_state.Node.ItemCount != 0 ) ) - break; - - if( !GeneratorNodeHelper.MoveToChild( ref m_state ) ) - { - if( !GeneratorNodeHelper.MoveToPreceding( ref m_state ) ) - return false; - } - else - { - GeneratorNodeHelper.MoveToEnd( ref m_state ); - } - } - - this.EnsureState(); - - return true; - } - - // This method cannot be used for groups. - // This method will search for items independently of the Expanded/Collapsed status of GroupGeneratorNodes. - internal bool Contains( object item ) - { - var current = m_state; - var found = false; - var skipCollectionGeneratorNodeCheck = false; - - while( true ) - { - skipCollectionGeneratorNodeCheck = false; - - var headersFootersNode = current.Node as HeadersFootersGeneratorNode; - if( ( headersFootersNode != null ) && ( item is GroupHeaderFooterItem ) ) - { - var groupHeaderFooterItem = ( GroupHeaderFooterItem )item; - var parentGroup = headersFootersNode.Parent as GroupGeneratorNode; - - if( ( parentGroup != null ) && ( parentGroup.CollectionViewGroup == groupHeaderFooterItem.Group ) && headersFootersNode.Items.Contains( groupHeaderFooterItem.Template ) ) - { - found = true; - break; - } - - // If there is no parent node, then its because the current HeadersFootersGeneratorNode is not a GroupHeaders/Footers node (FixedHeaders/Footers or Headers/Footers). - skipCollectionGeneratorNodeCheck = true; // force skip CollectionGeneratorNode verification, this is to limit amount of job done by loop body. - } - - if( !skipCollectionGeneratorNodeCheck ) - { - var collectionNode = current.Node as CollectionGeneratorNode; - if( collectionNode != null ) - { - // When dealing with a DataView, the DataView's IList's Contains implementation will return false - // for a dataRowView which is in edition and was modified even though it is really part of the collection. - // Therefore, we must use a for loop of Object.Equals method calls. - var dataRowViewItem = item as System.Data.DataRowView; - if( dataRowViewItem != null ) - { - var items = collectionNode.Items; - var itemsCount = items.Count; - var itemDataRow = dataRowViewItem.Row; - - for( int i = 0; i < itemsCount; i++ ) - { - var currentDataRowView = items[ i ] as System.Data.DataRowView; - if( ( currentDataRowView != null ) && ( itemDataRow == currentDataRowView.Row ) ) - { - found = true; - break; - } - } - - if( found ) - break; - } - else - { - // Since the GetAt() methods can be overriden to compensate for the Expand/Collapse status of Groups - // AND the details features, accessing the collection directly prevent pre-processing of the content of the collection node. - if( collectionNode.Items.Contains( item ) ) - { - found = true; - break; - } - } - } - } - - if( GeneratorNodeHelper.MoveToChild( ref current, false ) ) - continue; - - if( GeneratorNodeHelper.MoveToFollowing( ref current ) ) - continue; - - break; - } - - m_state = current; - - this.EnsureState(); - - return found; - } - - internal void ProcessVisit( - DataGridContext sourceContext, - int minIndex, - int maxIndex, - IDataGridContextVisitor visitor, - DataGridContextVisitorType visitorType, - bool visitDetails, - out bool visitWasStopped ) - { - visitWasStopped = false; - - // This is used only for DataGridContextVisitorType.ItemsBlock - var startSourceDataItemIndex = -1; - var endSourceDataItemIndex = -1; - - if( minIndex < 0 ) - throw DataGridException.Create( "The minimum index must be greater than or equal to zero.", sourceContext.DataGridControl, "minIndex" ); - - if( ( visitorType & DataGridContextVisitorType.DataGridContext ) == DataGridContextVisitorType.DataGridContext ) - { - visitor.Visit( sourceContext, ref visitWasStopped ); - - if( visitWasStopped ) - return; - } - - //Take a shortcut, if the visit is made only for contexts, and there is no child contexts - //return right away. - var containsDetails = false; - - foreach( var childContext in sourceContext.GetChildContextsCore() ) - { - containsDetails = true; - break; - } - - var processed = false; - var current = m_state; - - while( true ) - { - processed = false; - - var itemCount = current.Node.ItemCount; - - //If the whole current node is below the minIndex, jump over it. - if( ( current.Index + ( itemCount - 1 ) ) < minIndex ) - { - processed = true; - } - - //when the index to visit exceeds the range defined, exit the loop. - if( current.Index > maxIndex ) - break; - - var minForNode = Math.Max( 0, minIndex - current.Index ); // this will give the base offset within the node where to start the visitating! - var maxForNode = Math.Min( itemCount - 1, maxIndex - current.Index ); //this will five the max offset within this node to visit (protected against overlfow ) - - if( !processed ) - { - var headersNode = current.Node as HeadersFootersGeneratorNode; - if( headersNode != null ) - { - var isHeaderFooter = ( headersNode.Parent == null ); - - //If the node is a Headers or Footers node AND the visitorType does not contain HeadersFooters - if( ( isHeaderFooter ) && ( ( visitorType & DataGridContextVisitorType.HeadersFooters ) == DataGridContextVisitorType.HeadersFooters ) ) - { - GeneratorNodeHelper.ProcessHeadersNodeVisit( headersNode, sourceContext, minForNode, maxForNode, visitor, ref visitWasStopped ); - } - else if( ( !isHeaderFooter ) && ( ( visitorType & DataGridContextVisitorType.GroupHeadersFooters ) == DataGridContextVisitorType.GroupHeadersFooters ) ) - { - GeneratorNodeHelper.ProcessHeadersNodeVisit( headersNode, sourceContext, minForNode, maxForNode, visitor, ref visitWasStopped ); - } - - processed = true; - } - } - - if( !processed ) - { - var itemsNode = current.Node as ItemsGeneratorNode; - if( itemsNode != null ) - { - if( ( visitorType & DataGridContextVisitorType.ItemsBlock ) == DataGridContextVisitorType.ItemsBlock ) - { - GeneratorNodeHelper.ProcessItemsNodeBlockVisit( - itemsNode, sourceContext, - minForNode, maxForNode, - visitor, visitorType, visitDetails, containsDetails, current.DataIndex, - ref startSourceDataItemIndex, ref endSourceDataItemIndex, ref visitWasStopped ); - } - else if( ( ( visitDetails ) && ( containsDetails ) ) - || ( ( visitorType & DataGridContextVisitorType.Items ) == DataGridContextVisitorType.Items ) ) - { - GeneratorNodeHelper.ProcessItemsNodeVisit( - itemsNode, sourceContext, - minForNode, maxForNode, - visitor, visitorType, visitDetails, current.DataIndex, ref visitWasStopped ); - } - - processed = true; - } - } - - if( !processed ) - { - var groupNode = current.Node as GroupGeneratorNode; - if( groupNode != null ) - { - if( ( visitorType & DataGridContextVisitorType.Groups ) == DataGridContextVisitorType.Groups ) - { - visitor.Visit( - sourceContext, - groupNode.CollectionViewGroup, - groupNode.NamesTree, - groupNode.Level, - groupNode.IsExpanded, - groupNode.IsComputedExpanded, - ref visitWasStopped ); - } - - processed = true; - } - } - - if( !processed ) - throw DataGridException.Create( "Unable to process the visit.", sourceContext.DataGridControl ); - - if( visitWasStopped ) - break; - - if( GeneratorNodeHelper.MoveToChild( ref current ) ) - continue; - - if( GeneratorNodeHelper.MoveToFollowing( ref current ) ) - continue; - - break; - } - - if( ( visitorType & DataGridContextVisitorType.ItemsBlock ) == DataGridContextVisitorType.ItemsBlock ) - { - if( startSourceDataItemIndex != -1 ) - { - var stopVisit = false; - visitor.Visit( sourceContext, startSourceDataItemIndex, endSourceDataItemIndex, ref stopVisit ); - visitWasStopped = visitWasStopped || stopVisit; - } - } - - m_state = current; - - this.EnsureState(); - } - - internal static GeneratorNode EvaluateChain( GeneratorNode startNode, out int totalChildCount, out int chainLength ) - { - if( startNode == null ) - throw new ArgumentNullException( "startNode" ); - - var current = new State( startNode, 0, 0 ); - - totalChildCount = startNode.ItemCount; - chainLength = 1; - - while( true ) - { - if( !GeneratorNodeHelper.MoveToNext( ref current ) ) - break; - - totalChildCount += current.Node.ItemCount; - chainLength++; - } - - return current.Node; - } - - private void EnsureState() - { - if( m_state.Node == null ) - throw new DataGridInternalException(); - } - - private static void ProcessItemsNodeBlockVisit( - ItemsGeneratorNode itemsNode, - DataGridContext sourceContext, - int minIndex, - int maxIndex, - IDataGridContextVisitor visitor, - DataGridContextVisitorType visitorType, - bool visitDetails, - bool containsDetails, - int sourceDataItemIndex, - ref int startSourceDataItemIndex, - ref int endSourceDataItemIndex, - ref bool stopVisit ) - { - if( maxIndex < minIndex ) - return; - - int runningIndex = minIndex; - sourceDataItemIndex += minIndex - itemsNode.CountDetailsBeforeGlobalIndex( minIndex ); - - if( !containsDetails ) - { - // If we contains no detail, we take a quick way out of it. - if( startSourceDataItemIndex == -1 ) - { - startSourceDataItemIndex = sourceDataItemIndex; - } - else - { - if( ( endSourceDataItemIndex + 1 ) != sourceDataItemIndex ) - { - visitor.Visit( sourceContext, startSourceDataItemIndex, endSourceDataItemIndex, ref stopVisit ); - - if( stopVisit ) - return; - - startSourceDataItemIndex = sourceDataItemIndex; - } - } - - endSourceDataItemIndex = sourceDataItemIndex + Math.Min( maxIndex - minIndex, itemsNode.Items.Count - 1 ); - return; - } - - int masterIndex; - int detailStartIndex; - int detailNodeIndex; - - while( runningIndex <= maxIndex ) - { - DetailGeneratorNode detailNode = itemsNode.GetDetailNodeForIndex( runningIndex, out masterIndex, out detailStartIndex, out detailNodeIndex ); - - if( detailNode != null ) - { - int detailEndIndex = Math.Min( detailNode.ItemCount - 1, detailStartIndex + ( maxIndex - runningIndex ) ); - sourceDataItemIndex -= detailStartIndex; - bool visitWasStopped; - - ( ( IDataGridContextVisitable )detailNode.DetailGenerator ).AcceptVisitor( - detailStartIndex, detailEndIndex, visitor, visitorType, visitDetails, out visitWasStopped ); - - stopVisit = stopVisit || visitWasStopped; - - if( stopVisit ) - break; - - runningIndex += detailNode.ItemCount - detailStartIndex - 1; - } - else - { - // set the first data index that will be visited for that items block - if( startSourceDataItemIndex == -1 ) - { - startSourceDataItemIndex = sourceDataItemIndex; - endSourceDataItemIndex = sourceDataItemIndex; - } - else - { - if( ( endSourceDataItemIndex + 1 ) != sourceDataItemIndex ) - { - visitor.Visit( sourceContext, startSourceDataItemIndex, endSourceDataItemIndex, ref stopVisit ); - - if( stopVisit ) - break; - - startSourceDataItemIndex = sourceDataItemIndex; - } - - endSourceDataItemIndex = sourceDataItemIndex; - } - - sourceDataItemIndex++; - } - - runningIndex++; - } - } - - private static void ProcessItemsNodeVisit( - ItemsGeneratorNode itemsNode, - DataGridContext sourceContext, - int minIndex, - int maxIndex, - IDataGridContextVisitor visitor, - DataGridContextVisitorType visitorType, - bool visitDetails, - int sourceDataItemIndex, - ref bool stopVisit ) - { - var runningIndex = minIndex; - sourceDataItemIndex += minIndex; - - int masterIndex; - int detailStartIndex; - int detailNodeIndex; - - while( runningIndex <= maxIndex ) - { - var detailNode = itemsNode.GetDetailNodeForIndex( runningIndex, out masterIndex, out detailStartIndex, out detailNodeIndex ); - - if( detailNode != null ) - { - var detailEndIndex = Math.Min( detailNode.ItemCount - 1, detailStartIndex + ( maxIndex - runningIndex ) ); - sourceDataItemIndex -= detailStartIndex; - - if( visitDetails ) - { - bool visitWasStopped; - - ( ( IDataGridContextVisitable )detailNode.DetailGenerator ).AcceptVisitor( detailStartIndex, detailEndIndex, visitor, visitorType, visitDetails, out visitWasStopped ); - - stopVisit = stopVisit || visitWasStopped; - - if( stopVisit ) - break; - - runningIndex += detailNode.ItemCount - detailStartIndex - 1; - } - } - else - { - if( ( visitorType & DataGridContextVisitorType.Items ) == DataGridContextVisitorType.Items ) - { - object dataItem = itemsNode.GetAt( runningIndex ); - visitor.Visit( sourceContext, sourceDataItemIndex, dataItem, ref stopVisit ); - - if( stopVisit ) - break; - } - - sourceDataItemIndex++; - } - - runningIndex++; - } - } - - private static void ProcessHeadersNodeVisit( HeadersFootersGeneratorNode headersNode, DataGridContext sourceContext, int minIndex, int maxIndex, IDataGridContextVisitor visitor, ref bool stopVisit ) - { - for( int i = minIndex; i <= maxIndex; i++ ) - { - var template = headersNode.GetAt( i ); - - var groupNode = headersNode.Parent as GroupGeneratorNode; - if( groupNode != null ) - { - visitor.Visit( sourceContext, ( GroupHeaderFooterItem )template, ref stopVisit ); - } - else - { - visitor.Visit( sourceContext, ( DataTemplate )template, ref stopVisit ); - } - - if( stopVisit ) - break; - } - } - - private static bool MoveToNext( ref State state ) - { - return GeneratorNodeHelper.MoveToNext( ref state, 1 ); - } - - private static bool MoveToNext( ref State state, int count ) - { - if( count <= 0 ) - return true; - - var node = state.Node; - var index = state.Index; - var dataIndex = state.DataIndex; - - for( int i = 0; i < count; i++ ) - { - var nextNode = node.Next; - if( nextNode == null ) - return false; - - var groupNode = node as GroupGeneratorNode; - if( groupNode != null ) - { - dataIndex += groupNode.TotalLeafCount; - } - - index += node.ItemCount; - node = nextNode; - } - - state.Node = node; - state.Index = index; - state.DataIndex = dataIndex; - - return true; - } - - private static bool MoveToPrevious( ref State state ) - { - var node = state.Node.Previous; - if( node == null ) - return false; - - state.Node = node; - state.Index -= node.ItemCount; - - var groupNode = node as GroupGeneratorNode; - if( groupNode != null ) - { - state.DataIndex -= groupNode.TotalLeafCount; - } - - return true; - } - - private static void MoveToFirst( ref State state ) - { - var node = state.Node.Previous; - if( node == null ) - return; - - var index = state.Index; - var dataIndex = state.DataIndex; - - while( true ) - { - var groupNode = node as GroupGeneratorNode; - if( groupNode != null ) - { - dataIndex -= groupNode.TotalLeafCount; - } - - index -= node.ItemCount; - - var target = node.Previous; - if( target == null ) - break; - - node = target; - } - - state.Node = node; - state.Index = index; - state.DataIndex = dataIndex; - } - - private static void MoveToEnd( ref State state ) - { - var node = state.Node; - if( node.Next == null ) - return; - - var index = state.Index; - var dataIndex = state.DataIndex; - - while( true ) - { - var groupNode = node as GroupGeneratorNode; - if( groupNode != null ) - { - dataIndex += groupNode.TotalLeafCount; - } - - index += node.ItemCount; - - var target = node.Next; - if( target == null ) - break; - - node = target; - } - - state.Node = node; - state.Index = index; - state.DataIndex = dataIndex; - } - - private static bool MoveToChild( ref State state ) - { - return GeneratorNodeHelper.MoveToChild( ref state, true ); - } - - private static bool MoveToChild( ref State state, bool skipItemLessGroupNodes ) - { - var groupNode = state.Node as GroupGeneratorNode; - if( ( groupNode == null ) || ( groupNode.Child == null ) ) - return false; - - if( ( skipItemLessGroupNodes ) && ( groupNode.ItemCount <= 0 ) ) - return false; - - state.Node = groupNode.Child; - - return true; - } - - private static bool MoveToParent( ref State state ) - { - if( state.Node.Level == 0 ) - return false; - - GeneratorNodeHelper.MoveToFirst( ref state ); - - state.Node = state.Node.Parent; - Debug.Assert( state.Node != null ); - - return true; - } - - private static bool MoveToFollowing( ref State state ) - { - while( !GeneratorNodeHelper.MoveToNext( ref state ) ) - { - if( !GeneratorNodeHelper.MoveToParent( ref state ) ) - return false; - } - - return true; - } - - private static bool MoveToPreceding( ref State state ) - { - while( !GeneratorNodeHelper.MoveToPrevious( ref state ) ) - { - if( !GeneratorNodeHelper.MoveToParent( ref state ) ) - return false; - } - - return true; - } - - private static State FindNodeLocation( GeneratorNode node ) - { - var state = new State( node, 0, 0 ); - - while( true ) - { - GeneratorNodeHelper.MoveToFirst( ref state ); - - if( !GeneratorNodeHelper.MoveToParent( ref state ) ) - break; - } - - Debug.Assert( state.Index <= 0 ); - Debug.Assert( state.DataIndex <= 0 ); - - return new State( node, -state.Index, -state.DataIndex ); - } - - private static bool FindNode( ref State state, GeneratorNode node ) - { - if( state.Node == node ) - return true; - - var from = state; - var fromLevel = state.Node.Level; - var to = new State( node, 0, 0 ); - var toLevel = node.Level; - - while( from.Node != to.Node ) - { - if( fromLevel > toLevel ) - { - if( !GeneratorNodeHelper.MoveToParent( ref from ) ) - return false; - - fromLevel = from.Node.Level; - } - else - { - if( !GeneratorNodeHelper.MoveToPrevious( ref to ) ) - { - if( !GeneratorNodeHelper.MoveToParent( ref to ) ) - return false; - - toLevel = to.Node.Level; - } - } - } - - state.Node = node; - state.Index = from.Index - to.Index; - state.DataIndex = from.DataIndex - to.DataIndex; - - return true; - } - - private static bool FindNodeForIndex( ref State state, int index ) - { - var current = state; - - // The algo is a single drill-down... for optimized performance.. - // It first tries to go horizontally in the tree and then drills-down if it can. - while( true ) - { - var itemCount = current.Node.ItemCount; - - // Verify if the current node contains ( directly or its children ) the required index - if( index < current.Index + itemCount ) - { - // A Group node is the only node that can have children is by definition empty... let's dig deeper. - // If we cannot travel deeper, then this node is the closest we get. - if( !GeneratorNodeHelper.MoveToChild( ref current ) ) - break; - } - else if( ( index == current.Index ) && ( itemCount != 0 ) ) - { - break; - } - else - { - if( !GeneratorNodeHelper.MoveToNext( ref current ) ) - return false; - } - } - - state.Node = current.Node; - state.Index = current.Index; - state.DataIndex = current.DataIndex; - - return true; - } - - private State m_state; - - #region State Private Struct - - private struct State - { - internal State( GeneratorNode node, int index, int dataIndex ) - { - Debug.Assert( node != null ); - - this.Node = node; - this.Index = index; - this.DataIndex = dataIndex; - } - - internal GeneratorNode Node; - internal int Index; - internal int DataIndex; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/GroupGeneratorNode.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/GroupGeneratorNode.cs deleted file mode 100644 index a0b3ce6a..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/GroupGeneratorNode.cs +++ /dev/null @@ -1,328 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Diagnostics; -using System.Windows.Data; - -namespace Xceed.Wpf.DataGrid -{ - internal partial class GroupGeneratorNode : NotifyCollectionChangedGeneratorNode - { - public GroupGeneratorNode( CollectionViewGroup group, GeneratorNode parent, GroupConfiguration groupConfig ) - : base( parent ) - { - Debug.Assert( group != null, "group cannot be null for GroupGeneratorNode" ); - Debug.Assert( groupConfig != null ); - - m_group = group; - m_groupConfig = groupConfig; - } - - public event EventHandler TotalLeafCountChanged; - public event EventHandler IsExpandedChanged; - public event EventHandler IsExpandedChanging; - - #region CollectionViewGroup Property - - public CollectionViewGroup CollectionViewGroup - { - get - { - return m_group; - } - } - - #endregion - - #region UIGroup Property - - public Group UIGroup - { - get - { - return m_uiGroup; - } - set - { - m_uiGroup = value; - } - } - - #endregion - - #region GroupConfiguration Property - - public GroupConfiguration GroupConfiguration - { - get - { - return m_groupConfig; - } - } - - #endregion - - #region TotalLeafCount Property - - public int TotalLeafCount - { - get - { - return m_leafCount; - } - } - - #endregion - - #region ItemCount Property - - internal override int ItemCount - { - get - { - GroupGeneratorNode parentGroup = this.Parent as GroupGeneratorNode; - if( parentGroup != null ) - { - return ( parentGroup.IsExpanded == true ) ? m_itemCount : 0; - } - return m_itemCount; - } - } - - #endregion - - #region IsExpanded Property - - public bool IsExpanded - { - get - { - return m_isExpanded; - } - set - { - //if the expanded status changed - if( m_isExpanded != value ) - { - var dataGridContext = m_uiGroup.DataGridContext; - var groupExpansionChangingEventArgs = default( GroupExpansionChangingEventArgs ); - if( value ) - { - groupExpansionChangingEventArgs = new GroupExpansionChangingEventArgs( DataGridControl.GroupExpandingEvent, m_uiGroup, m_group, dataGridContext, true ); - dataGridContext.DataGridControl.RaiseGroupExpanding( groupExpansionChangingEventArgs ); - } - else - { - groupExpansionChangingEventArgs = new GroupExpansionChangingEventArgs( DataGridControl.GroupCollapsingEvent, m_uiGroup, m_group, dataGridContext, false ); - dataGridContext.DataGridControl.RaiseGroupCollapsing( groupExpansionChangingEventArgs ); - } - - if( groupExpansionChangingEventArgs.Cancel ) - return; - - var handler = this.IsExpandedChanging; - if( handler != null ) - { - handler.Invoke( this, EventArgs.Empty ); - } - - this.NotifyImmediateChildren( value ); - - m_isExpanded = value; - - handler = this.IsExpandedChanged; - if( handler != null ) - { - handler.Invoke( this, EventArgs.Empty ); - } - - if( m_isExpanded ) - { - dataGridContext.DataGridControl.RaiseGroupExpanded( new GroupExpansionChangedEventArgs( DataGridControl.GroupExpandedEvent, m_uiGroup, m_group, dataGridContext, true ) ); - } - else - { - dataGridContext.DataGridControl.RaiseGroupCollapsed( new GroupExpansionChangedEventArgs( DataGridControl.GroupCollapsedEvent, m_uiGroup, m_group, dataGridContext, false ) ); - } - } - } - } - - internal void SetIsExpandedAtInitialization( bool isExpanded ) - { - m_isExpanded = isExpanded; - } - - #endregion - - #region NamesTree Property - - public object[] NamesTree - { - get - { - return m_namesTree; - } - } - - #endregion - - #region Child Property - - public GeneratorNode Child - { - get; - set; - } - - #endregion - - #region IsComputedExpandedOverride Property - - protected override bool IsComputedExpandedOverride - { - get - { - return this.IsExpanded; - } - } - - #endregion - - public HeadersFootersGeneratorNode GetHeaderNode() - { - return this.Child as HeadersFootersGeneratorNode; - } - - public HeadersFootersGeneratorNode GetFooterNode() - { - GeneratorNode generatorNode = this.Child; - HeadersFootersGeneratorNode footerGeneratorNode = null; - - if( generatorNode == null ) - return null; - - do - { - generatorNode = generatorNode.Next; - footerGeneratorNode = generatorNode as HeadersFootersGeneratorNode; - } while( ( footerGeneratorNode == null ) && ( generatorNode != null ) ); - - return footerGeneratorNode; - } - - protected override int AdjustItemCountOverride( int delta ) - { - delta = base.AdjustItemCountOverride( delta ); - - m_itemCount += delta; - - GroupGeneratorNode parentGroup = this.Parent as GroupGeneratorNode; - if( ( parentGroup != null ) && ( parentGroup.IsExpanded == false ) ) - { - return 0; - } - - return delta; - } - - protected override int AdjustLeafCountOverride( int delta ) - { - delta = base.AdjustLeafCountOverride( delta ); - - if( delta != 0 ) - { - m_leafCount += delta; - - if( this.TotalLeafCountChanged != null ) - { - this.TotalLeafCountChanged( this, EventArgs.Empty ); - } - } - - return delta; - } - - internal override void NotifyExpansionStateChanged( bool isParentExpanded ) - { - base.NotifyExpansionStateChanged( isParentExpanded ); - - if( this.Parent != null ) - { - this.OnExpansionStateChanged( isParentExpanded, 0, m_itemCount ); - - if( isParentExpanded == true ) - { - this.Parent.AdjustItemCount( m_itemCount ); - } - else - { - this.Parent.AdjustItemCount( -m_itemCount ); - } - } - } - - internal override void CleanGeneratorNode() - { - base.CleanGeneratorNode(); - - this.Child = null; - this.UIGroup.ClearGroup(); - this.UIGroup = null; - - m_group = null; - } - - internal void BuildNamesTree() - { - int level = this.Level; - - m_namesTree = new object[ level + 1 ]; - - m_namesTree[ level ] = this.CollectionViewGroup.Name; - - GroupGeneratorNode parentNode = this.Parent as GroupGeneratorNode; - for( int i = level - 1; i >= 0; i-- ) - { - m_namesTree[ i ] = parentNode.CollectionViewGroup.Name; - parentNode = parentNode.Parent as GroupGeneratorNode; - } - } - - private void NotifyImmediateChildren( bool value ) - { - if( this.Child != null ) - { - GeneratorNodeHelper nodeHelper = new GeneratorNodeHelper( this.Child, 0, 0 ); //index not important - nodeHelper.MoveToEnd(); - do - { - nodeHelper.CurrentNode.NotifyExpansionStateChanged( value ); - } - while( nodeHelper.MoveToPrevious() == true ); - } - } - - private GroupConfiguration m_groupConfig; - private bool m_isExpanded = true; - private int m_leafCount; //this is the storage for the total number of "leaf" items that are child of this group. (no counting the groups, headers and footers) - private int m_itemCount; //this is the storage for the total number of items that are "child" of this group node. - private CollectionViewGroup m_group; - private Group m_uiGroup; - private object[] m_namesTree; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/GroupHeaderFooterItem.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/GroupHeaderFooterItem.cs deleted file mode 100644 index 55f73cfb..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/GroupHeaderFooterItem.cs +++ /dev/null @@ -1,117 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Diagnostics; -using System.Windows; -using System.Windows.Data; - -namespace Xceed.Wpf.DataGrid -{ - public struct GroupHeaderFooterItem - { - #region Static Fields - - public static readonly GroupHeaderFooterItem Empty = new GroupHeaderFooterItem(); - - #endregion - - public GroupHeaderFooterItem( CollectionViewGroup collectionViewGroup, object template ) - { - if( !( template is DataTemplate ) && !( template is GroupHeaderFooterItemTemplate ) ) - throw new ArgumentException( "A GroupHeaderFooterItem can only be created with a DataTemplate or VisibleWhenCollapsed objects.", "template" ); - - Debug.Assert( template != null ); - - m_template = template; - m_group = new WeakReference( collectionViewGroup ); - - m_hashCode = template.GetHashCode(); - if( collectionViewGroup != null ) - { - m_hashCode ^= collectionViewGroup.GetHashCode(); - } - } - - #region Template Property - - public object Template - { - get - { - return m_template; - } - } - - private readonly object m_template; - - #endregion - - #region Group Property - - public CollectionViewGroup Group - { - get - { - if( m_group != null ) - return m_group.Target as CollectionViewGroup; - - return null; - } - } - - private readonly WeakReference m_group; - - #endregion - - public static bool Equals( GroupHeaderFooterItem item1, GroupHeaderFooterItem item2 ) - { - return ( item1.m_hashCode == item2.m_hashCode ) - && ( item1.m_template == item2.m_template ) - && ( item1.Group == item2.Group ); - } - - public static bool operator ==( GroupHeaderFooterItem item1, GroupHeaderFooterItem item2 ) - { - return GroupHeaderFooterItem.Equals( item1, item2 ); - } - - public static bool operator !=( GroupHeaderFooterItem item1, GroupHeaderFooterItem item2 ) - { - return !GroupHeaderFooterItem.Equals( item1, item2 ); - } - - public override bool Equals( object obj ) - { - if( ( obj == null ) || !( obj is GroupHeaderFooterItem ) ) - return false; - - return this.Equals( ( GroupHeaderFooterItem )obj ); - } - - public bool Equals( GroupHeaderFooterItem item ) - { - return GroupHeaderFooterItem.Equals( this, item ); - } - - public override int GetHashCode() - { - return m_hashCode; - } - - private readonly int m_hashCode; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/GroupHeaderFooterItemContainerRecyclingPool.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/GroupHeaderFooterItemContainerRecyclingPool.cs deleted file mode 100644 index 18defb54..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/GroupHeaderFooterItemContainerRecyclingPool.cs +++ /dev/null @@ -1,117 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class GroupHeaderFooterItemContainerRecyclingPool : IEnumerable - { - internal int Count - { - get - { - return m_count; - } - } - - internal void Clear() - { - m_collection.Clear(); - m_count = 0; - } - - internal void Enqueue( string groupBy, object template, DependencyObject container ) - { - if( groupBy == null ) - throw new ArgumentNullException( "groupBy" ); - - if( template == null ) - throw new ArgumentNullException( "template" ); - - var pool = default( HeaderFooterItemContainerRecyclingPool ); - if( m_collection.TryGetValue( groupBy, out pool ) ) - { - pool.Enqueue( template, container ); - } - else - { - pool = new HeaderFooterItemContainerRecyclingPool(); - pool.Enqueue( template, container ); - - m_collection.Add( groupBy, pool ); - } - - m_count++; - } - - internal DependencyObject Dequeue( string groupBy, object template ) - { - if( groupBy == null ) - throw new ArgumentNullException( "groupBy" ); - - if( template == null ) - throw new ArgumentNullException( "template" ); - - var pool = default( HeaderFooterItemContainerRecyclingPool ); - if( !m_collection.TryGetValue( groupBy, out pool ) ) - return null; - - var container = pool.Dequeue( template ); - if( container != null ) - { - if( pool.Count == 0 ) - { - m_collection.Remove( groupBy ); - } - - m_count--; - } - - return container; - } - - #region IEnumerable<> Members - - public IEnumerator GetEnumerator() - { - foreach( var pool in m_collection.Values ) - { - foreach( var entry in pool ) - { - yield return entry; - } - } - } - - #endregion - - #region IEnumerable Members - - IEnumerator IEnumerable.GetEnumerator() - { - return this.GetEnumerator(); - } - - #endregion - - private int m_count; //0 - private readonly Dictionary m_collection = new Dictionary(); - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/GroupHeaderFooterItemTemplate.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/GroupHeaderFooterItemTemplate.cs deleted file mode 100644 index fac91861..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/GroupHeaderFooterItemTemplate.cs +++ /dev/null @@ -1,66 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Windows; -using System.Windows.Markup; -using System; - -namespace Xceed.Wpf.DataGrid -{ - [ContentProperty("Template")] - public class GroupHeaderFooterItemTemplate - { - public DataTemplate Template - { - get - { - return m_template; - } - set - { - if( m_isSealed == true ) - throw new InvalidOperationException( "An attempt was made to modify a GroupHeaderFooterItemTemplate that is currently in use." ); - - m_template = value; - } - } - - public bool VisibleWhenCollapsed - { - get - { - return m_visible; - } - set - { - if( m_isSealed == true ) - throw new InvalidOperationException( "An attempt was made to modify a GroupHeaderFooterItemTemplate that is currently in use." ); - - m_visible = value; - } - } - - internal void Seal() - { - m_isSealed = true; - } - - private DataTemplate m_template; - private bool m_visible; - private bool m_isSealed; - - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/GroupNamesTreeKey.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/GroupNamesTreeKey.cs deleted file mode 100644 index 7712bf36..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/GroupNamesTreeKey.cs +++ /dev/null @@ -1,94 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - internal class GroupNamesTreeKey - { - public GroupNamesTreeKey( object[] namesTree ) - { - m_namesTree = namesTree; - - this.Initialize(); - } - - private void Initialize() - { - m_cachedHash = 0; - - // We use this hashing algorithm in order to get a different hashCode - // when the same values are in a different order in the object array. - int namesTreeLength = m_namesTree.Length; - for( int i = 0; i < namesTreeLength; i++ ) - { - object groupName = m_namesTree[ i ]; - - if( groupName == null ) - { - m_cachedHash ^= DBNull.Value.GetHashCode(); - } - else - { - m_cachedHash ^= groupName.GetHashCode(); - } - - m_cachedHash += ( m_cachedHash << 10 ); - m_cachedHash ^= ( m_cachedHash >> 6 ); - } - } - - public override int GetHashCode() - { - return m_cachedHash; - } - - public override bool Equals( object obj ) - { - GroupNamesTreeKey groupStatusKey = obj as GroupNamesTreeKey; - - if( groupStatusKey == null ) - return false; - - if( m_cachedHash != groupStatusKey.m_cachedHash ) - return false; - - int groupStatusKeyNamesTreeLength = groupStatusKey.m_namesTree.Length; - - if( m_namesTree.Length != groupStatusKeyNamesTreeLength ) - return false; - - for( int i = 0; i < groupStatusKeyNamesTreeLength; i++ ) - { - if( !Object.Equals( m_namesTree[ i ], groupStatusKey.m_namesTree[ i ] ) ) - return false; - } - - return true; - } - - #region PRIVATE FIELDS - - private object[] m_namesTree; - private int m_cachedHash; - - #endregion PRIVATE FIELDS - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/HeaderFooterItemContainerRecyclingPool.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/HeaderFooterItemContainerRecyclingPool.cs deleted file mode 100644 index 0968de47..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/HeaderFooterItemContainerRecyclingPool.cs +++ /dev/null @@ -1,190 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class HeaderFooterItemContainerRecyclingPool : IEnumerable - { - internal int Count - { - get - { - return m_count; - } - } - - internal void Clear() - { - if( m_count <= 0 ) - return; - - m_collection.Clear(); - m_count = 0; - m_version++; - } - - internal void Enqueue( object item, DependencyObject container ) - { - if( item == null ) - throw new ArgumentNullException( "item" ); - - if( container == null ) - throw new ArgumentNullException( "container" ); - - var entry = default( Entry ); - - if( !m_collection.TryGetValue( item, out entry ) ) - { - entry = new Entry(); - } - - entry.Push( container ); - - m_collection[ item ] = entry; - m_count++; - m_version++; - } - - internal DependencyObject Dequeue( object item ) - { - if( item == null ) - throw new ArgumentNullException( "item" ); - - if( m_collection.Count <= 0 ) - return null; - - var entry = default( Entry ); - - if( !m_collection.TryGetValue( item, out entry ) ) - return null; - - Debug.Assert( entry.Count > 0 ); - var container = entry.Pop(); - Debug.Assert( container != null ); - - if( entry.Count == 0 ) - { - m_collection.Remove( item ); - } - else - { - m_collection[ item ] = entry; - } - - m_count--; - m_version++; - - return container; - } - - #region IEnumerable<> Members - - public IEnumerator GetEnumerator() - { - var version = m_version; - - foreach( var entry in m_collection.Values ) - { - for( int i = entry.Count - 1; i >= 0; i-- ) - { - if( version != m_version ) - throw new InvalidOperationException(); - - yield return entry[ i ]; - } - } - } - - #endregion - - #region IEnumerable Members - - IEnumerator IEnumerable.GetEnumerator() - { - return this.GetEnumerator(); - } - - #endregion - - private int m_count; //0 - private int m_version; //0 - private readonly Dictionary m_collection = new Dictionary(); - - #region Entry Private Struct - - private struct Entry - { - internal int Count - { - get - { - return m_count; - } - } - - internal DependencyObject this[ int index ] - { - get - { - Debug.Assert( ( index >= 0 ) && ( index < m_count ) ); - return m_containers[ index ]; - } - } - - internal void Push( DependencyObject container ) - { - Debug.Assert( container != null ); - - if( m_containers == null ) - { - Array.Resize( ref m_containers, 1 ); - } - else if( m_count == m_containers.Length ) - { - Debug.Assert( m_containers.Length > 0 ); - Array.Resize( ref m_containers, m_containers.Length * 2 ); - } - - m_containers[ m_count ] = container; - m_count++; - } - - internal DependencyObject Pop() - { - Debug.Assert( m_count > 0 ); - Debug.Assert( m_containers != null ); - - m_count--; - - var container = m_containers[ m_count ]; - m_containers[ m_count ] = default( DependencyObject ); - - return container; - } - - private int m_count; //0 - private DependencyObject[] m_containers; //null - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/HeadersFootersGeneratorNode.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/HeadersFootersGeneratorNode.cs deleted file mode 100644 index 91849d2c..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/HeadersFootersGeneratorNode.cs +++ /dev/null @@ -1,354 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Collections; -using System.Windows; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Diagnostics; - -namespace Xceed.Wpf.DataGrid -{ - internal partial class HeadersFootersGeneratorNode : CollectionGeneratorNode - { - #region STATIC MEMBERS - - internal static HeadersFootersGeneratorNode GetSameLevelFirstHeaderNode( GroupGeneratorNode generatorNode ) - { - HeadersFootersGeneratorNode headerGeneratorNode = null; - - GroupGeneratorNode parentGroupGeneratorNode = generatorNode.Parent as GroupGeneratorNode; - - if( parentGroupGeneratorNode == null ) - { - GeneratorNodeHelper nodeHelper = new GeneratorNodeHelper( generatorNode, 0, 0 ); //index is not important - - if( nodeHelper.MoveToFirst() ) - headerGeneratorNode = nodeHelper.CurrentNode as HeadersFootersGeneratorNode; - } - else - { - headerGeneratorNode = parentGroupGeneratorNode.Child as HeadersFootersGeneratorNode; - } - - return headerGeneratorNode; - } - - #endregion STATIC MEMBERS - - public HeadersFootersGeneratorNode( IList list, GeneratorNode parent ) - : base( list, parent ) - { - } - - internal override int ItemCount - { - get - { - GroupGeneratorNode parentGroup = this.Parent as GroupGeneratorNode; - if( parentGroup == null || parentGroup.IsExpanded == true ) - { - return this.Items.Count; - } - else - { - return this.ComputeCollapsedItemCount(); - } - } - } - - internal override void NotifyExpansionStateChanged( bool isParentExpanded ) - { - base.NotifyExpansionStateChanged( isParentExpanded ); - - bool sequenceStarted = false; - - int startIndex = 0; - int sequenceCount = 0; - int totalCount = 0; - - GroupHeaderFooterItemTemplate groupHeaderTemplate; - - //cycle through all of the items of the node - for( int i = 0; i < this.Items.Count; i++ ) - { - //determine if the DataTemplate for the node is a GroupHeaderFooterTemplate - groupHeaderTemplate = this.Items[ i ] as GroupHeaderFooterItemTemplate; - - //if the Node represent a GroupHeader of GroupFooter and the template is a GroupHeaderFooterTemplate which - //is VisibleWhenCollapsed - if( ( groupHeaderTemplate != null ) && ( groupHeaderTemplate.VisibleWhenCollapsed == true ) ) - { - groupHeaderTemplate.Seal(); - //send any pending message to the Generator - if( sequenceStarted == true ) - { - this.OnExpansionStateChanged( isParentExpanded, startIndex, sequenceCount ); - - //cumulate the total number of items collapsed/expanded - totalCount += sequenceCount; - - //reset the sequence variables. - startIndex = 0; - sequenceCount = 0; - sequenceStarted = false; - } - } - //the node is to be collapsed/expanded - else - { - //if no sequence were started yet - if( sequenceStarted == false ) - { - //start it. - sequenceCount = 0; - startIndex = i; - sequenceStarted = true; - } - - //cumulate the sequence count - sequenceCount++; - - } - - } - - //if a sequence was started but not completed (event sent), then terminate it - if( sequenceStarted == true ) - { - this.OnExpansionStateChanged( isParentExpanded, startIndex, sequenceCount ); - - //cumulate the total number of items collapsed/expanded - totalCount += sequenceCount; - } - - //finally, adjust the ItemCount - this.Parent.AdjustItemCount( ( isParentExpanded == true ) ? totalCount : -totalCount ); - } - - public override int IndexOf( object item ) - { - int retval = -1; - - if( item != null ) - { - GroupGeneratorNode parentGroup = this.Parent as GroupGeneratorNode; - - //if the node is the child of a GroupGeneratorNode (then its a GroupHeader or GroupFooter). - if( parentGroup != null ) - { - //Debug.Assert( ( item.GetType() == typeof( GroupHeaderFooterItem ) ), "item must be a GroupHeaderFooterItem for HeadersFootersGeneratorNode whose parent is a GroupGeneratorNode" ); - - if( item.GetType() == typeof( GroupHeaderFooterItem ) ) - { - //only process further is the ParentGroup match the requested group. - GroupHeaderFooterItem ghf = ( GroupHeaderFooterItem )item; - if( ghf.Group == parentGroup.CollectionViewGroup ) - { - retval = this.IndexOfHelper( parentGroup, ghf.Template ); - } - } - else - { - retval = this.IndexOfHelper( parentGroup, item ); - } - - } - else - { - //if there is no parent group (or no parent at all), then process the item directly! - retval = this.IndexOfHelper( parentGroup, item ); - } - } - - return retval; - - } - - public override object GetAt( int index ) - { - var parentGroup = this.Parent as GroupGeneratorNode; - object item; - - if( ( parentGroup != null ) && !parentGroup.IsExpanded ) - { - item = this.ComputeCollapsedGetAt( index ); - } - else - { - item = base.GetAt( index ); - } - - if( ( parentGroup != null ) && ( item != null ) ) - return new GroupHeaderFooterItem( parentGroup.CollectionViewGroup, item ); - - return item; - } - - #region ImmediateUIGroups - - internal ReadOnlyCollection GetImmediateUIGroups( int generatorCurrentGeneration ) - { - if( ( m_cachedGeneratorCurrentGeneration != generatorCurrentGeneration ) - || ( m_readOnlyImmediateUIGroups == null ) ) - { - Debug.WriteLineIf( ( ( m_cachedGeneratorCurrentGeneration != generatorCurrentGeneration ) && ( m_readOnlyImmediateUIGroups == null ) ), - "Creating Groups collection since generator version differs AND ReadOnlyCollection is null." ); - - Debug.WriteLineIf( ( ( m_cachedGeneratorCurrentGeneration != generatorCurrentGeneration ) && ( m_readOnlyImmediateUIGroups != null ) ), - "Creating Groups collection since generator version differs." ); - - Debug.WriteLineIf( ( ( m_cachedGeneratorCurrentGeneration == generatorCurrentGeneration ) && ( m_readOnlyImmediateUIGroups == null ) ), - "Creating Groups collection even if generator version is the same, since ReadOnlyCollection is null." ); - - m_cachedGeneratorCurrentGeneration = generatorCurrentGeneration; - - // Ensure collections. - if( m_immediateUIGroups == null ) - { - Debug.Assert( m_readOnlyImmediateUIGroups == null ); - m_immediateUIGroups = new Collection(); - m_readOnlyImmediateUIGroups = new ReadOnlyCollection( m_immediateUIGroups ); - } - else - { - Debug.Assert( m_readOnlyImmediateUIGroups != null ); - m_immediateUIGroups.Clear(); - } - - // Recalculate. - GeneratorNodeHelper nodeHelper = new GeneratorNodeHelper( this, 0, 0 ); //index is not important - - while( nodeHelper.MoveToNext() ) - { - GroupGeneratorNode groupGeneratorNode = nodeHelper.CurrentNode as GroupGeneratorNode; - - if( groupGeneratorNode == null ) - continue; - - m_immediateUIGroups.Add( groupGeneratorNode.UIGroup ); - } - } - - return m_readOnlyImmediateUIGroups; - } - - private int m_cachedGeneratorCurrentGeneration; - private Collection m_immediateUIGroups; - private ReadOnlyCollection m_readOnlyImmediateUIGroups; - - #endregion ImmediateUIGroups - - private int ComputeCollapsedItemCount() - { - int retval = 0; - - GroupHeaderFooterItemTemplate groupHeaderTemplate; - - for( int i = 0; i < this.Items.Count; i++ ) - { - //determine if the DataTemplate for the node is a GroupHeaderFooterTemplate - groupHeaderTemplate = this.Items[ i ] as GroupHeaderFooterItemTemplate; - - //if the Node represent a GroupHeader of GroupFooter and the template is a GroupHeaderFooterTemplate which - //is VisibleWhenCollapsed - if( ( groupHeaderTemplate != null ) && ( groupHeaderTemplate.VisibleWhenCollapsed == true ) ) - { - groupHeaderTemplate.Seal(); - retval++; - } - } - - return retval; - } - - private int ComputeCollapsedIndexOf( object item ) - { - int retval = -1; - int count = -1; - - GroupHeaderFooterItemTemplate groupHeaderTemplate; - - for( int i = 0; i < this.Items.Count; i++ ) - { - //determine if the DataTemplate for the node is a GroupHeaderFooterTemplate - groupHeaderTemplate = this.Items[ i ] as GroupHeaderFooterItemTemplate; - - //if the Node represent a GroupHeader of GroupFooter and the template is a GroupHeaderFooterTemplate which - //is VisibleWhenCollapsed - if( ( groupHeaderTemplate != null ) && ( groupHeaderTemplate.VisibleWhenCollapsed == true ) ) - { - groupHeaderTemplate.Seal(); - count++; - } - - if( this.Items[ i ] == item ) - { - retval = count; - break; - } - } - - return retval; - } - - private object ComputeCollapsedGetAt( int index ) - { - object retval = null; - - GroupHeaderFooterItemTemplate groupHeaderTemplate; - int count = -1; - - for( int i = 0; i < this.Items.Count; i++ ) - { - //determine if the DataTemplate for the node is a GroupHeaderFooterTemplate - groupHeaderTemplate = this.Items[ i ] as GroupHeaderFooterItemTemplate; - - //if the Node represent a GroupHeader of GroupFooter and the template is a GroupHeaderFooterTemplate which - //is VisibleWhenCollapsed - if( ( groupHeaderTemplate != null ) && ( groupHeaderTemplate.VisibleWhenCollapsed == true ) ) - { - groupHeaderTemplate.Seal(); - count++; - } - - if( count == index ) - { - retval = this.Items[ i ]; - break; - } - } - - return retval; - } - - private int IndexOfHelper( GroupGeneratorNode parentGroup, object template ) - { - int retval = -1; - - if( parentGroup != null && parentGroup.IsExpanded == false ) - { - retval = this.ComputeCollapsedIndexOf( template ); - } - else - { - retval = base.IndexOf( template ); - } - - return retval; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/ICustomItemContainerGenerator.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/ICustomItemContainerGenerator.cs deleted file mode 100644 index 60a172bd..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/ICustomItemContainerGenerator.cs +++ /dev/null @@ -1,44 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Windows; -using System.Windows.Controls.Primitives; - -namespace Xceed.Wpf.DataGrid -{ - public interface ICustomItemContainerGenerator : IItemContainerGenerator - { - int ItemCount - { - get; - } - - bool IsRecyclingEnabled - { - get; - set; - } - - DependencyObject ContainerFromIndex( int index ); - DependencyObject GetRealizedContainerForIndex( int index ); - int GetRealizedIndexForContainer( DependencyObject container ); - - void SetCurrentIndex( int newCurrentIndex ); - int GetCurrentIndex(); - - void RestoreFocus( DependencyObject container ); - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/IInhibitGenPosToIndexUpdating.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/IInhibitGenPosToIndexUpdating.cs deleted file mode 100644 index 41bf41d2..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/IInhibitGenPosToIndexUpdating.cs +++ /dev/null @@ -1,28 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - internal interface IInhibitGenPosToIndexUpdating - { - IDisposable InhibitGenPosToIndexUpdates(); - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/ItemContainerRecyclingPool.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/ItemContainerRecyclingPool.cs deleted file mode 100644 index 0d40ba07..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/ItemContainerRecyclingPool.cs +++ /dev/null @@ -1,192 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class ItemContainerRecyclingPool : IEnumerable - { - internal int Count - { - get - { - return m_count; - } - } - - internal void Clear() - { - if( m_count <= 0 ) - return; - - m_collection.Clear(); - m_count = 0; - m_version++; - } - - internal void Enqueue( object hint, DependencyObject container ) - { - if( container == null ) - throw new ArgumentNullException( "container" ); - - var key = ( hint != null ) ? hint.GetHashCode() : 0; - var entry = default( Entry ); - - if( !m_collection.TryGetValue( key, out entry ) ) - { - entry = new Entry(); - } - - entry.Push( container ); - - m_collection[ key ] = entry; - m_count++; - m_version++; - } - - internal DependencyObject Dequeue( object hint ) - { - if( m_collection.Count <= 0 ) - return null; - - var key = ( hint != null ) ? hint.GetHashCode() : 0; - var entry = default( Entry ); - - if( !m_collection.TryGetValue( key, out entry ) ) - { - var pair = m_collection.First(); - - key = pair.Key; - entry = pair.Value; - } - - Debug.Assert( entry.Count > 0 ); - var container = entry.Pop(); - Debug.Assert( container != null ); - - if( entry.Count == 0 ) - { - m_collection.Remove( key ); - } - else - { - m_collection[ key ] = entry; - } - - m_count--; - m_version++; - - return container; - } - - #region IEnumerable<> Members - - public IEnumerator GetEnumerator() - { - var version = m_version; - - foreach( var entry in m_collection.Values ) - { - for( int i = entry.Count - 1; i >= 0; i-- ) - { - if( version != m_version ) - throw new InvalidOperationException(); - - yield return entry[ i ]; - } - } - } - - #endregion - - #region IEnumerable Members - - IEnumerator IEnumerable.GetEnumerator() - { - return this.GetEnumerator(); - } - - #endregion - - private int m_count; //0 - private int m_version; //0 - private readonly Dictionary m_collection = new Dictionary(); - - #region Entry Private Struct - - private struct Entry - { - internal int Count - { - get - { - return m_count; - } - } - - internal DependencyObject this[ int index ] - { - get - { - Debug.Assert( ( index >= 0 ) && ( index < m_count ) ); - return m_containers[ index ]; - } - } - - internal void Push( DependencyObject container ) - { - Debug.Assert( container != null ); - - if( m_containers == null ) - { - Array.Resize( ref m_containers, 1 ); - } - else if( m_count == m_containers.Length ) - { - Debug.Assert( m_containers.Length > 0 ); - Array.Resize( ref m_containers, m_containers.Length * 2 ); - } - - m_containers[ m_count ] = container; - m_count++; - } - - internal DependencyObject Pop() - { - Debug.Assert( m_count > 0 ); - Debug.Assert( m_containers != null ); - - m_count--; - - var container = m_containers[ m_count ]; - m_containers[ m_count ] = default( DependencyObject ); - - return container; - } - - private int m_count; //0 - private DependencyObject[] m_containers; //null - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/ItemContextVisitor.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/ItemContextVisitor.cs deleted file mode 100644 index ebd0e1c8..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/ItemContextVisitor.cs +++ /dev/null @@ -1,144 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; -using System.Windows.Data; -using Xceed.Wpf.DataGrid.Views; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class ItemContextVisitor : IDataGridContextVisitor - { - internal ItemContextVisitor( TableflowViewItemsHost itemsHost, double firstItemHiddenRatio ) - { - m_itemsHost = itemsHost; - m_firstItemHiddenRatio = firstItemHiddenRatio; - } - - #region ParentDataGridContext - - public DataGridContext ParentDataGridContext - { - get - { - return m_parentDataGridContext; - } - } - - private DataGridContext m_parentDataGridContext; - - #endregion - - #region Item Property - - public object Item - { - get - { - return m_item; - } - } - - private object m_item; - - #endregion - - #region VisitSuccessful Property - - public bool VisitSuccessful - { - get - { - return m_success; - } - } - - private bool m_success; //false; - - #endregion - - #region IDataGridContextVisitor Members - - public void Visit( DataGridContext sourceContext, ref bool stopVisit ) - { - throw new NotSupportedException( "The ItemAndDataGridContextVisitor is only capable of handling data items." ); - } - - public void Visit( DataGridContext sourceContext, int startSourceDataItemIndex, int endSourceDataItemIndex, ref bool stopVisit ) - { - throw new NotSupportedException( "The ItemAndDataGridContextVisitor is only capable of handling data items." ); - } - - public void Visit( DataGridContext sourceContext, int sourceDataItemIndex, object item, ref bool stopVisit ) - { - // In TableflowView, we must consider that sticky headers may hide the item. - if( m_itemsHost != null ) - { - if( m_isFirstItem ) - { - m_isFirstItem = false; - - // At least half the item is hidden. - if( m_firstItemHiddenRatio > 0.5d ) - return; - } - - var areHeadersSticky = TableflowView.GetAreHeadersSticky( sourceContext ); - var areGroupHeadersSticky = TableflowView.GetAreGroupHeadersSticky( sourceContext ); - var areParentRowsSticky = TableflowView.GetAreParentRowsSticky( sourceContext ); - - if( areHeadersSticky || areGroupHeadersSticky || areParentRowsSticky ) - { - var stickyHeadersCount = sourceContext.CustomItemContainerGenerator.GetStickyHeaderCountForIndex( sourceDataItemIndex, areHeadersSticky, areGroupHeadersSticky, areParentRowsSticky ); - - if( stickyHeadersCount > m_stickyHeadersSkipped ) - { - m_stickyHeadersSkipped++; - return; - } - } - } - - m_item = item; - m_parentDataGridContext = sourceContext; - m_success = true; - stopVisit = true; - } - - public void Visit( DataGridContext sourceContext, CollectionViewGroup group, object[] namesTree, int groupLevel, bool isExpanded, bool isComputedExpanded, ref bool stopVisit ) - { - throw new NotSupportedException( "The ItemAndDataGridContextVisitor is only capable of handling data items." ); - } - - public void Visit( DataGridContext sourceContext, DataTemplate headerFooter, ref bool stopVisit ) - { - throw new NotSupportedException( "The ItemAndDataGridContextVisitor is only capable of handling data items." ); - } - - public void Visit( DataGridContext sourceContext, GroupHeaderFooterItem groupHeaderFooter, ref bool stopVisit ) - { - throw new NotSupportedException( "The ItemAndDataGridContextVisitor is only capable of handling data items." ); - } - - #endregion - - private readonly TableflowViewItemsHost m_itemsHost; - private readonly double m_firstItemHiddenRatio; - private bool m_isFirstItem = true; - private int m_stickyHeadersSkipped; //0 - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/ItemsGeneratorNode.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/ItemsGeneratorNode.cs deleted file mode 100644 index 5a107b4f..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/ItemsGeneratorNode.cs +++ /dev/null @@ -1,305 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Collections; -using System.Collections.Generic; - -namespace Xceed.Wpf.DataGrid -{ - internal partial class ItemsGeneratorNode : CollectionGeneratorNode - { - internal ItemsGeneratorNode( IList list, GeneratorNode parent ) - : base( list, parent ) - { - } - - internal override int ItemCount - { - get - { - var parentGroup = this.Parent as GroupGeneratorNode; - if( ( parentGroup == null ) || parentGroup.IsExpanded ) - return this.Items.Count + this.ComputeDetailsCount(); - - return 0; - } - } - - internal override void NotifyExpansionStateChanged( bool isParentExpanded ) - { - base.NotifyExpansionStateChanged( isParentExpanded ); - - if( this.Parent != null ) - { - this.OnExpansionStateChanged( isParentExpanded, 0, this.Items.Count + this.ComputeDetailsCount() ); - - if( isParentExpanded ) - { - this.Parent.AdjustItemCount( this.Items.Count + this.ComputeDetailsCount() ); - } - else - { - this.Parent.AdjustItemCount( -( this.Items.Count + this.ComputeDetailsCount() ) ); - } - } - } - - protected override int AdjustItemCountOverride( int delta ) - { - base.AdjustItemCountOverride( delta ); - - var parentGroup = this.Parent as GroupGeneratorNode; - if( ( parentGroup == null ) || parentGroup.IsExpanded ) - return delta; - - return 0; - } - - public override object GetAt( int index ) - { - if( index < 0 ) - return null; - - //If there are no details, call base (quicker) - if( ( m_detailsMapping == null ) || ( m_detailsMapping.Count == 0 ) ) - return base.GetAt( index ); - - int masterIndex; - int detailIndex; - int detailNodeIndex; - - var detailNode = this.GetDetailNodeForIndex( index, out masterIndex, out detailIndex, out detailNodeIndex ); - if( detailNode == null ) - return this.Items[ masterIndex ]; - - return detailNode.DetailGenerator.ItemFromIndex( detailIndex ); - } - - public override int IndexOf( object item ) - { - if( ( m_detailsMapping == null ) || ( m_detailsMapping.Count == 0 ) ) - return base.IndexOf( item ); - - var tmpIndex = this.Items.IndexOf( item ); - if( tmpIndex >= 0 ) - return tmpIndex + this.CountDetailsBeforeDataIndex( tmpIndex ); - - int runningDetailCount = 0; - - foreach( KeyValuePair> pair in m_detailsMapping ) - { - var detailNodeList = pair.Value; - var currentIndex = pair.Key; - var runningIndex = ( currentIndex + runningDetailCount ); - - var count = detailNodeList.Count; - for( int i = 0; i < count; i++ ) - { - var detailNode = detailNodeList[ i ]; - var detailIndex = detailNode.DetailGenerator.IndexFromItem( item ); - - if( detailIndex >= 0 ) - return runningIndex + detailIndex + 1; - - var detailItemCount = detailNode.ItemCount; - - runningDetailCount += detailItemCount; - runningIndex += detailItemCount; - } - } - - return -1; - } - - internal override void CleanGeneratorNode() - { - base.CleanGeneratorNode(); - - if( m_detailsMapping != null ) - { - foreach( var detail in m_detailsMapping.Values ) - { - detail.Clear(); - } - - m_detailsMapping.Clear(); - m_detailsMapping = null; - } - } - - #region Master/Detail Specific Stuff - - public SortedDictionary> Details - { - get - { - return m_detailsMapping; - } - set - { - m_detailsMapping = value; - } - } - - private int ComputeDetailsCount() - { - if( m_detailsMapping == null ) - return 0; - - var count = 0; - - foreach( var detailsList in m_detailsMapping.Values ) - { - foreach( var detail in detailsList ) - { - count += detail.ItemCount; - } - } - - return count; - } - - internal int CountDetailsBeforeDataIndex( int dataIndex ) - { - if( m_detailsMapping == null ) - return 0; - - var count = 0; - - foreach( KeyValuePair> indexToDetails in m_detailsMapping ) - { - if( indexToDetails.Key < dataIndex ) - { - foreach( var node in indexToDetails.Value ) - { - count += node.ItemCount; - } - - continue; - } - - // Since the details list is now a SortedDictionary, we can assume - // that if the key is greater or equal than the reference index, - // there will be no more entry after this. - break; - } - - return count; - } - - internal int CountDetailsBeforeGlobalIndex( int globalIndex ) - { - if( ( m_detailsMapping == null ) || ( globalIndex == 0 ) ) - return 0; - - var retval = 0; - - foreach( KeyValuePair> indexToDetails in m_detailsMapping ) - { - var key = indexToDetails.Key; - - // Since the details list is now a SortedDictionary, we can assume - // that if the key is greater or equal than the reference index, - // there will be no more entry after this. - if( key >= globalIndex ) - break; - - foreach( var node in indexToDetails.Value ) - { - var itemCount = node.ItemCount; - globalIndex -= itemCount; - - if( key >= globalIndex ) - break; - - retval += itemCount; - } - } - - return retval; - } - - public DetailGeneratorNode GetDetailNodeForIndex( int targetIndex ) - { - int masterIndex; - int detailIndex; - int detailNodeIndex; - - return this.GetDetailNodeForIndex( targetIndex, out masterIndex, out detailIndex, out detailNodeIndex ); - } - - public DetailGeneratorNode GetDetailNodeForIndex( int targetIndex, out int masterIndex, out int detailIndex, out int detailNodeIndex ) - { - masterIndex = -1; - detailIndex = -1; - detailNodeIndex = -1; - - if( ( m_detailsMapping == null ) || ( m_detailsMapping.Count == 0 ) ) - { - masterIndex = targetIndex; - return null; - } - - var runningDetailCount = 0; - - foreach( KeyValuePair> pair in m_detailsMapping ) - { - var detailNodeList = pair.Value; - var currentIndex = pair.Key; - var runningIndex = ( currentIndex + runningDetailCount ); - - if( targetIndex < runningIndex ) - { - masterIndex = targetIndex - runningDetailCount; - return null; - } - - if( runningIndex == targetIndex ) - { - masterIndex = currentIndex; - return null; - } - - var count = detailNodeList.Count; - for( int i = 0; i < count; i++ ) - { - var detailNode = detailNodeList[ i ]; - var detailItemCount = detailNode.ItemCount; - - if( targetIndex <= ( runningIndex + detailItemCount ) ) - { - masterIndex = currentIndex; - detailIndex = targetIndex - runningIndex - 1; - detailNodeIndex = i; - return detailNode; - } - else - { - runningDetailCount += detailItemCount; - runningIndex += detailItemCount; - } - } - } - - masterIndex = targetIndex - runningDetailCount; - return null; - } - - private SortedDictionary> m_detailsMapping; // null - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/NotifyCollectionChangedGeneratorNode.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/NotifyCollectionChangedGeneratorNode.cs deleted file mode 100644 index c6e09415..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/NotifyCollectionChangedGeneratorNode.cs +++ /dev/null @@ -1,39 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Collections.Specialized; - -namespace Xceed.Wpf.DataGrid -{ - internal class NotifyCollectionChangedGeneratorNode : GeneratorNode, INotifyCollectionChanged - { - internal NotifyCollectionChangedGeneratorNode( GeneratorNode parent ) - : base( parent ) - { - } - - public event NotifyCollectionChangedEventHandler CollectionChanged; - - public void OnCollectionChanged( object sender, NotifyCollectionChangedEventArgs e ) - { - var handler = this.CollectionChanged; - if( handler == null ) - return; - - handler.Invoke( this, e ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/RangeSelectionVisitor.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/RangeSelectionVisitor.cs deleted file mode 100644 index aab7e77d..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/RangeSelectionVisitor.cs +++ /dev/null @@ -1,113 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Diagnostics; - -namespace Xceed.Wpf.DataGrid -{ - internal class RangeSelectionVisitor : IDataGridContextVisitor - { - public RangeSelectionVisitor( SelectionRange[] selectedColumns, bool unselect ) - { - m_selectedColumns = selectedColumns; - m_unselect = unselect; - } - - #region IDataGridContextVisitor Members - - public void Visit( DataGridContext sourceContext, ref bool stopVisit ) - { - throw new NotSupportedException( "The RangeSelectionVisitor is only capable of handling data items block." ); - } - - public void Visit( DataGridContext sourceContext, int startSourceDataItemIndex, int endSourceDataItemIndex, ref bool stopVisit ) - { - SelectionManager selectionChangerManager = sourceContext.DataGridControl.SelectionChangerManager; - - if( m_selectedColumns != null ) - { - int columnCount = sourceContext.Columns.Count; - - if( columnCount == 0 ) - return; - - SelectionRange contextColumnMaxRange = new SelectionRange( 0, columnCount - 1 ); - - for( int i = 0; i < m_selectedColumns.Length; i++ ) - { - SelectionRange selectionRange = m_selectedColumns[ i ]; - SelectionRange intersectionSelectionRange = selectionRange.Intersect( contextColumnMaxRange ); - - if( intersectionSelectionRange.IsEmpty ) - continue; - - - var cellRange = new SelectionCellRangeWithItems( new SelectionRange( startSourceDataItemIndex, endSourceDataItemIndex ), null, intersectionSelectionRange ); - - if( m_unselect ) - { - selectionChangerManager.UnselectCells( sourceContext, cellRange ); - } - else - { - selectionChangerManager.SelectCells( sourceContext, cellRange ); - } - } - } - else - { - var itemRange = new SelectionRangeWithItems( new SelectionRange( startSourceDataItemIndex, endSourceDataItemIndex ), null ); - - if( m_unselect ) - { - selectionChangerManager.UnselectItems( sourceContext, itemRange ); - } - else - { - selectionChangerManager.SelectItems( sourceContext, itemRange ); - } - } - } - - public void Visit( DataGridContext sourceContext, int sourceDataItemIndex, object item, ref bool stopVisit ) - { - throw new NotSupportedException( "The RangeSelectionVisitor is only capable of handling data items block." ); - } - - public void Visit( DataGridContext sourceContext, System.Windows.Data.CollectionViewGroup group, object[] namesTree, int groupLevel, bool isExpanded, bool isComputedExpanded, ref bool stopVisit ) - { - throw new NotSupportedException( "The RangeSelectionVisitor is only capable of handling data items block." ); - } - - public void Visit( DataGridContext sourceContext, System.Windows.DataTemplate headerFooter, ref bool stopVisit ) - { - throw new NotSupportedException( "The RangeSelectionVisitor is only capable of handling data items block." ); - } - - public void Visit( DataGridContext sourceContext, GroupHeaderFooterItem groupHeaderFooter, ref bool stopVisit ) - { - throw new NotSupportedException( "The RangeSelectionVisitor is only capable of handling data items block." ); - } - - #endregion - - private SelectionRange[] m_selectedColumns; - private bool m_unselect; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/RecyclingCandidateCleanedEvent.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/RecyclingCandidateCleanedEvent.cs deleted file mode 100644 index 6c4beb1d..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/RecyclingCandidateCleanedEvent.cs +++ /dev/null @@ -1,46 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal delegate void RecyclingCandidatesCleanedEventHandler( object sender, RecyclingCandidatesCleanedEventArgs e ); - - internal class RecyclingCandidatesCleanedEventArgs : EventArgs - { - public RecyclingCandidatesCleanedEventArgs( IList recyclingCandidates ) - { - if( recyclingCandidates == null ) - throw new ArgumentNullException( "recyclingCandidates" ); - - m_recyclingCandidates = recyclingCandidates; - } - - public IList RecyclingCandidates - { - get - { - return m_recyclingCandidates; - } - } - - private IList m_recyclingCandidates; - } - -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/SaveRestoreDataGridContextStateVisitor.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/SaveRestoreDataGridContextStateVisitor.cs deleted file mode 100644 index 7c385052..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/SaveRestoreDataGridContextStateVisitor.cs +++ /dev/null @@ -1,232 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Windows.Data; - -namespace Xceed.Wpf.DataGrid -{ - /// - /// This visitor saves and restores a DataGridContext's Expanded Groups and Expanded Items. - /// - /// It will not handle the dataGridContext's details, beside expanding this dataGridContext's items - /// which were expanded. - /// - /// It will handle has many group levels as needed, or as specified. - /// - internal class SaveRestoreDataGridContextStateVisitor : SaveRestoreStateVisitor - { - #region CONSTRUCTORS - - public SaveRestoreDataGridContextStateVisitor() - : this( true, int.MaxValue, false ) - { - } - - public SaveRestoreDataGridContextStateVisitor( bool saveExpandedItems, int maxGroupLevel, bool stopAtFirstCollapsedGroup ) - { - if( maxGroupLevel < 0 ) - throw new ArgumentOutOfRangeException( "maxGroupLevel" ); - - m_saveExpandedItems = saveExpandedItems; - m_maxGroupLevel = maxGroupLevel; - m_stopAtFirstCollapsedGroup = stopAtFirstCollapsedGroup; - } - - #endregion CONSTRUCTORS - - #region MaxGroupLevel Property - - private int m_maxGroupLevel; - - public int MaxGroupLevel - { - get - { - return m_maxGroupLevel; - } - } - - #endregion MaxGroupLevel Property - - #region SaveExpandedItems Property - - private bool m_saveExpandedItems; - - public bool SaveExpandedItems - { - get - { - return m_saveExpandedItems; - } - } - - #endregion SaveExpandedItems Property - - #region StopAtFirstCollapsedGroup Property - - private bool m_stopAtFirstCollapsedGroup; - - public bool StopAtFirstCollapsedGroup - { - get - { - return m_stopAtFirstCollapsedGroup; - } - } - - #endregion StopAtFirstCollapsedGroup Property - - #region PROTECTED METHODS - - protected override void InitializeCore() - { - m_rootDataGridContext = null; - m_itemsToExpand = new List(); - m_groupsStateDictionary = new Dictionary(); - } - - protected override void SaveStateCore( IDataGridContextVisitable dataGridContextVisitable ) - { - try - { - bool visitWasStopped; - m_rootDataGridContext = SaveRestoreStateVisitor.GetDataGridContextFromVisitable( dataGridContextVisitable ); - - if( m_saveExpandedItems ) - dataGridContextVisitable.AcceptVisitor( 0, int.MaxValue, this, DataGridContextVisitorType.DataGridContext, true, out visitWasStopped ); - - dataGridContextVisitable.AcceptVisitor( 0, int.MaxValue, this, DataGridContextVisitorType.Groups, false, out visitWasStopped ); - } - finally - { - m_rootDataGridContext = null; - } - } - - protected override void RestoreStateCore( IDataGridContextVisitable dataGridContextVisitable ) - { - try - { - m_rootDataGridContext = SaveRestoreDataGridContextStateVisitor.GetDataGridContextFromVisitable( dataGridContextVisitable ); - - if( m_saveExpandedItems ) - { - for( int i = 0; i < m_itemsToExpand.Count; i++ ) - { - var dataItemToExpand = m_itemsToExpand[ i ].Target; - if( dataItemToExpand == null ) - continue; - - // Verify if we have a System.Data.DataView as ItemsSource to - // ensure to restore the System.Data.DataRowView that represents - // the System.Data.DataRow saved previously - System.Data.DataView dataView = ItemsSourceHelper.TryGetDataViewFromDataGridContext( m_rootDataGridContext ); - - if( ( dataView != null ) && ( dataItemToExpand is System.Data.DataRow ) ) - { - foreach( System.Data.DataRowView dataRowView in dataView ) - { - if( dataRowView.Row == dataItemToExpand ) - { - dataItemToExpand = dataRowView; - break; - } - } - } - } - } - - bool visitWasStopped; - dataGridContextVisitable.AcceptVisitor( 0, int.MaxValue, this, DataGridContextVisitorType.Groups, false, out visitWasStopped ); - } - finally - { - m_itemsToExpand = null; - m_rootDataGridContext = null; - } - } - - protected override void SavingVisit( DataGridContext sourceContext ) - { - if( sourceContext.ParentDataGridContext == m_rootDataGridContext ) - { - // Ensure to get a reference to the System.Data.DataRow when doing a - // save/restore of a System.Data.DataRowView since the view is recreated - // for every detail views - object parentItem = ItemsSourceHelper.TryGetDataRowFromDataItem( sourceContext.ParentItem ); - - m_itemsToExpand.Add( new WeakReference( parentItem ) ); - } - } - - protected override void SavingVisit( DataGridContext sourceContext, CollectionViewGroup group, object[] namesTree, int groupLevel, bool isExpanded, bool isComputedExpanded ) - { - if( sourceContext != m_rootDataGridContext ) - throw new InvalidOperationException( "Group does not belong to the root DataGridContext." ); - - if( groupLevel > m_maxGroupLevel ) - return; - - if( ( m_stopAtFirstCollapsedGroup ) && ( !isComputedExpanded ) ) - return; - - GroupNamesTreeKey groupNamesTreeKey = new GroupNamesTreeKey( namesTree ); - - m_groupsStateDictionary.Add( groupNamesTreeKey, isExpanded ); - } - - protected override void RestoringVisit( DataGridContext sourceContext, CollectionViewGroup group, object[] namesTree, int groupLevel, bool isExpanded, bool isComputedExpanded ) - { - if( sourceContext != m_rootDataGridContext ) - throw new InvalidOperationException( "Group does not belong to the root DataGridContext." ); - - if( groupLevel > m_maxGroupLevel ) - return; - - GroupNamesTreeKey groupNamesTreeKey = new GroupNamesTreeKey( namesTree ); - - bool wasExpanded; - if( m_groupsStateDictionary.TryGetValue( groupNamesTreeKey, out wasExpanded ) ) - { - if( wasExpanded ) - { - sourceContext.ExpandGroup( group, true ); - } - else - { - sourceContext.CollapseGroup( group, true ); - } - } - else if( m_stopAtFirstCollapsedGroup ) - { - sourceContext.CollapseGroup( group, true ); - } - } - - #endregion PROTECTED METHODS - - #region PRIVATE FIELDS - - private DataGridContext m_rootDataGridContext; - private List m_itemsToExpand; - private Dictionary m_groupsStateDictionary; - - #endregion PRIVATE FIELDS - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/SaveRestoreGlobalStateVisitor.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/SaveRestoreGlobalStateVisitor.cs deleted file mode 100644 index edb805a2..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/SaveRestoreGlobalStateVisitor.cs +++ /dev/null @@ -1,104 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Collections.Generic; - -namespace Xceed.Wpf.DataGrid -{ - internal class SaveRestoreGlobalStateVisitor : SaveRestoreStateVisitor - { - internal SaveRestoreGlobalStateVisitor( bool stopAtFirstCollapsedGroup ) - { - m_stopAtFirstCollapsedGroup = stopAtFirstCollapsedGroup; - } - - #region StopAtFirstCollapsedGroup Property - - internal bool StopAtFirstCollapsedGroup - { - get - { - return m_stopAtFirstCollapsedGroup; - } - set - { - m_stopAtFirstCollapsedGroup = value; - } - } - - private bool m_stopAtFirstCollapsedGroup; - - #endregion - - protected override void InitializeCore() - { - m_dataGridContextsStateDictionary = new Dictionary(); - } - - protected override void SaveStateCore( IDataGridContextVisitable dataGridContextVisitable ) - { - var dataGridContext = SaveRestoreStateVisitor.GetDataGridContextFromVisitable( dataGridContextVisitable ); - - this.RecursiveSaveDataGridContextsState( dataGridContext ); - } - - protected override void RestoreStateCore( IDataGridContextVisitable dataGridContextVisitable ) - { - var dataGridContext = SaveRestoreStateVisitor.GetDataGridContextFromVisitable( dataGridContextVisitable ); - - this.RecursiveRestoreDataGridContextsState( dataGridContext ); - } - - private void RecursiveSaveDataGridContextsState( DataGridContext dataGridContext ) - { - var saveRestoreDataGridContextStateVisitor = new SaveRestoreDataGridContextStateVisitor( true, int.MaxValue, m_stopAtFirstCollapsedGroup ); - - saveRestoreDataGridContextStateVisitor.SaveState( dataGridContext as IDataGridContextVisitable ); - - m_dataGridContextsStateDictionary.Add( new WeakDataGridContextKey( dataGridContext ), saveRestoreDataGridContextStateVisitor ); - - foreach( var subDataGridContext in dataGridContext.GetChildContextsCore() ) - { - this.RecursiveSaveDataGridContextsState( subDataGridContext ); - } - } - - private void RecursiveRestoreDataGridContextsState( DataGridContext dataGridContext ) - { - var weakDataGridContextKey = new WeakDataGridContextKey( dataGridContext ); - var saveRestoreDataGridContextStateVisitor = default( SaveRestoreDataGridContextStateVisitor ); - - if( m_dataGridContextsStateDictionary.TryGetValue( weakDataGridContextKey, out saveRestoreDataGridContextStateVisitor ) ) - { - try - { - saveRestoreDataGridContextStateVisitor.RestoreState( dataGridContext as IDataGridContextVisitable ); - } - finally - { - m_dataGridContextsStateDictionary.Remove( weakDataGridContextKey ); - } - } - - foreach( var subDataGridContext in dataGridContext.GetChildContextsCore() ) - { - this.RecursiveRestoreDataGridContextsState( subDataGridContext ); - } - } - - private Dictionary m_dataGridContextsStateDictionary; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/SaveRestoreStateVisitor.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/SaveRestoreStateVisitor.cs deleted file mode 100644 index 34abfd3a..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/SaveRestoreStateVisitor.cs +++ /dev/null @@ -1,319 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Windows.Data; - -namespace Xceed.Wpf.DataGrid -{ - abstract internal class SaveRestoreStateVisitor : IDataGridContextVisitor - { - #region STATIC MEMBERS - - public static DataGridContext GetDataGridContextFromVisitable( IDataGridContextVisitable dataGridContextVisitable ) - { - DataGridContext dataGridContext = dataGridContextVisitable as DataGridContext; - - if( dataGridContext == null ) - { - DataGridControl dataGridControl = dataGridContextVisitable as DataGridControl; - - if( dataGridControl != null ) - dataGridContext = dataGridControl.DataGridContext; - } - - if( dataGridContext == null ) - throw new InvalidOperationException( "A dataGridContext could not be extracted from the IDataGridContextVisitable object." ); - - return dataGridContext; - } - - #endregion STATIC MEMBERS - - #region CONSTRUCTORS - - public SaveRestoreStateVisitor() - { - this.Initialize(); - } - - #endregion CONSTRUCTORS - - #region SaveRestoreStateVisitorStatus - - private SaveRestoreStateVisitorStatus m_status; - - public SaveRestoreStateVisitorStatus SaveRestoreStateVisitorStatus - { - get { return m_status; } - } - - #endregion SaveRestoreStateVisitorStatus - - #region PUBLIC METHODS - - public void Initialize() - { - this.InitializeCore(); - m_status = SaveRestoreStateVisitorStatus.Ready; - } - - public void SaveState( IDataGridContextVisitable dataGridContextVisitable ) - { - if( m_status != SaveRestoreStateVisitorStatus.Ready ) - throw new InvalidOperationException( "An attempt was made to save the state of a visitor that is not ready." ); - - m_status = SaveRestoreStateVisitorStatus.Saving; - try - { - this.SaveStateCore( dataGridContextVisitable ); - m_status = SaveRestoreStateVisitorStatus.RestorePending; - } - catch - { - m_status = SaveRestoreStateVisitorStatus.Error; - throw; - } - } - - public void RestoreState( IDataGridContextVisitable dataGridContextVisitable ) - { - if( m_status != SaveRestoreStateVisitorStatus.RestorePending ) - throw new InvalidOperationException( "An attempt was made to restore the state of a visitor that does not have a pending restorable state." ); - - m_status = SaveRestoreStateVisitorStatus.Restoring; - try - { - this.RestoreStateCore( dataGridContextVisitable ); - m_status = SaveRestoreStateVisitorStatus.Restored; - } - catch - { - m_status = SaveRestoreStateVisitorStatus.Error; - throw; - } - } - - #endregion PUBLIC METHODS - - #region PROTECTED METHODS - - protected abstract void SaveStateCore( IDataGridContextVisitable dataGridContextVisitable ); - - protected abstract void RestoreStateCore( IDataGridContextVisitable dataGridContextVisitable ); - - protected abstract void InitializeCore(); - - protected virtual void SavingVisit( DataGridContext sourceContext ) - { - throw new NotImplementedException(); - } - - protected virtual void RestoringVisit( DataGridContext sourceContext ) - { - throw new NotImplementedException(); - } - - protected virtual void SavingVisit( DataGridContext sourceContext, object item ) - { - throw new NotImplementedException(); - } - - protected virtual void RestoringVisit( DataGridContext sourceContext, object item ) - { - throw new NotImplementedException(); - } - - protected virtual void SavingVisit( DataGridContext sourceContext, - CollectionViewGroup group, - object[] namesTree, - int groupLevel, - bool isExpanded, - bool isComputedExpanded ) - { - throw new NotImplementedException(); - } - - protected virtual void RestoringVisit( DataGridContext sourceContext, - CollectionViewGroup group, - object[] namesTree, - int groupLevel, - bool isExpanded, - bool isComputedExpanded ) - { - throw new NotImplementedException(); - } - - protected virtual void SavingVisit( DataGridContext sourceContext, System.Windows.DataTemplate headerFooter ) - { - throw new NotImplementedException(); - } - - protected virtual void RestoringVisit( DataGridContext sourceContext, System.Windows.DataTemplate headerFooter ) - { - throw new NotImplementedException(); - } - - protected virtual void SavingVisit( DataGridContext sourceContext, GroupHeaderFooterItem groupHeaderFooter ) - { - throw new NotImplementedException(); - } - - protected virtual void RestoringVisit( DataGridContext sourceContext, GroupHeaderFooterItem groupHeaderFooter ) - { - throw new NotImplementedException(); - } - - #endregion PROTECTED METHODS - - #region IDataGridContextVisitor Members - - void IDataGridContextVisitor.Visit( DataGridContext sourceContext, ref bool stopVisit ) - { - switch( m_status ) - { - case SaveRestoreStateVisitorStatus.Saving: - { - this.SavingVisit( sourceContext ); - break; - } - - case SaveRestoreStateVisitorStatus.Restoring: - { - this.RestoringVisit( sourceContext ); - break; - } - - default: - { - throw new InvalidOperationException( "An attempt was made to visit using a method other than the SaveRestoreStateVisitor's Save and Restore methods." ); - } - } - } - - void IDataGridContextVisitor.Visit( DataGridContext sourceContext, int startSourceDataItemIndex, int endSourceDataItemIndex, ref bool stopVisit ) - { - throw new NotSupportedException( "The SaveRestoreStateVisitor is not handling of data items block." ); - } - - void IDataGridContextVisitor.Visit( DataGridContext sourceContext, int sourceDataItemIndex, object item, ref bool stopVisit ) - { - switch( m_status ) - { - case SaveRestoreStateVisitorStatus.Saving: - { - this.SavingVisit( sourceContext, item ); - break; - } - - case SaveRestoreStateVisitorStatus.Restoring: - { - this.RestoringVisit( sourceContext, item ); - break; - } - - default: - { - throw new InvalidOperationException( "An attempt was made to visit using a method other than the SaveRestoreStateVisitor's Save and Restore methods." ); - } - } - } - - void IDataGridContextVisitor.Visit( DataGridContext sourceContext, System.Windows.Data.CollectionViewGroup group, object[] namesTree, int groupLevel, bool isExpanded, bool isComputedExpanded, ref bool stopVisit ) - { - switch( m_status ) - { - case SaveRestoreStateVisitorStatus.Saving: - { - this.SavingVisit( sourceContext, group, namesTree, groupLevel, isExpanded, isComputedExpanded ); - break; - } - - case SaveRestoreStateVisitorStatus.Restoring: - { - this.RestoringVisit( sourceContext, group, namesTree, groupLevel, isExpanded, isComputedExpanded ); - break; - } - - default: - { - throw new InvalidOperationException( "An attempt was made to visit using a method other than the SaveRestoreStateVisitor's Save and Restore methods." ); - } - } - } - - void IDataGridContextVisitor.Visit( DataGridContext sourceContext, System.Windows.DataTemplate headerFooter, ref bool stopVisit ) - { - switch( m_status ) - { - case SaveRestoreStateVisitorStatus.Saving: - { - this.SavingVisit( sourceContext, headerFooter ); - break; - } - - case SaveRestoreStateVisitorStatus.Restoring: - { - this.RestoringVisit( sourceContext, headerFooter ); - break; - } - - default: - { - throw new InvalidOperationException( "An attempt was made to visit using a method other than the SaveRestoreStateVisitor's Save and Restore methods." ); - } - } - } - - void IDataGridContextVisitor.Visit( DataGridContext sourceContext, GroupHeaderFooterItem groupHeaderFooter, ref bool stopVisit ) - { - switch( m_status ) - { - case SaveRestoreStateVisitorStatus.Saving: - { - this.SavingVisit( sourceContext, groupHeaderFooter ); - break; - } - - case SaveRestoreStateVisitorStatus.Restoring: - { - this.RestoringVisit( sourceContext, groupHeaderFooter ); - break; - } - - default: - { - throw new InvalidOperationException( "An attempt was made to visit using a method other than the SaveRestoreStateVisitor's Save and Restore methods." ); - } - } - } - - #endregion - } - - internal enum SaveRestoreStateVisitorStatus - { - Ready = 0, - Saving = 1, - RestorePending = 2, - Restoring = 3, - Restored = 4, - Error = 5 - } - -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/SelectAllVisitor.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/SelectAllVisitor.cs deleted file mode 100644 index 48a52128..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/SelectAllVisitor.cs +++ /dev/null @@ -1,123 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Windows.Data; - -namespace Xceed.Wpf.DataGrid -{ - internal class SelectAllVisitor : IDataGridContextVisitor - { - #region CONSTRUCTORS - - public SelectAllVisitor() - { - } - - #endregion CONSTRUCTORS - - #region IDataGridContextVisitor Members - - public void Visit( DataGridContext sourceContext, ref bool stopVisit ) - { - object[] items; - CollectionView itemsCollection = sourceContext.Items; - int count = itemsCollection.Count; - - if( count == 0 ) - return; - - if( sourceContext.ItemsSourceCollection is DataGridVirtualizingCollectionViewBase ) - { - items = null; - } - else - { - items = new object[ count ]; - - for( int i = 0; i < count; i++ ) - { - items[ i ] = itemsCollection.GetItemAt( i ); - } - } - - SelectionRange itemRange = new SelectionRange( 0, count - 1 ); - - if( sourceContext.DataGridControl.SelectionUnit == SelectionUnit.Row ) - { - sourceContext.DataGridControl.SelectionChangerManager.SelectItems( - sourceContext, - new SelectionRangeWithItems( itemRange, items ) ); - } - else - { - HashedLinkedList columnsByVisiblePosition = sourceContext.ColumnsByVisiblePosition; - SelectedItemsStorage selectedColumnStore = new SelectedItemsStorage( null ); - SelectionRange fullColumnRange = new SelectionRange( 0, columnsByVisiblePosition.Count - 1 ); - selectedColumnStore.Add( new SelectionRangeWithItems( fullColumnRange, null ) ); - int index = 0; - - foreach( ColumnBase column in columnsByVisiblePosition ) - { - if( !column.Visible ) - { - selectedColumnStore.Remove( new SelectionRangeWithItems( new SelectionRange( index ), null ) ); - } - - index++; - } - - int columnRangeCount = selectedColumnStore.Count; - - for( int i = 0; i < columnRangeCount; i++ ) - { - sourceContext.DataGridControl.SelectionChangerManager.SelectCells( - sourceContext, - new SelectionCellRangeWithItems( itemRange, items, selectedColumnStore[ i ].Range ) ); - } - } - } - - public void Visit( DataGridContext sourceContext, int startSourceDataItemIndex, int endSourceDataItemIndex, ref bool stopVisit ) - { - throw new NotSupportedException( "Only DataGridContexts can be visited by this visitor." ); - } - - public void Visit( DataGridContext sourceContext, int sourceDataItemIndex, object item, ref bool stopVisit ) - { - throw new NotSupportedException( "Only DataGridContexts can be visited by this visitor." ); - } - - public void Visit( DataGridContext sourceContext, System.Windows.Data.CollectionViewGroup group, object[] namesTree, int groupLevel, bool isExpanded, bool isComputedExpanded, ref bool stopVisit ) - { - throw new NotSupportedException( "Only DataGridContexts can be visited by this visitor." ); - } - - public void Visit( DataGridContext sourceContext, System.Windows.DataTemplate headerFooter, ref bool stopVisit ) - { - throw new NotSupportedException( "Only DataGridContexts can be visited by this visitor." ); - } - - public void Visit( DataGridContext sourceContext, GroupHeaderFooterItem groupHeaderFooter, ref bool stopVisit ) - { - throw new NotSupportedException( "Only DataGridContexts can be visited by this visitor." ); - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/StickyContainerGeneratedComparer.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/StickyContainerGeneratedComparer.cs deleted file mode 100644 index 54c16ac2..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/StickyContainerGeneratedComparer.cs +++ /dev/null @@ -1,52 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - internal class StickyContainerGeneratedComparer : IComparer - { - #region Singleton Property - - public static StickyContainerGeneratedComparer Singleton - { - get - { - if( _singleton == null ) - _singleton = new StickyContainerGeneratedComparer(); - - return _singleton; - } - } - - private static StickyContainerGeneratedComparer _singleton; - - #endregion Singleton Property - - #region IComparer Members - - public int Compare( StickyContainerGenerated x, StickyContainerGenerated y ) - { - return x.Index.CompareTo( y.Index ); - } - - #endregion IComparer Members - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/StickyContainerGeneratedReverseComparer.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/StickyContainerGeneratedReverseComparer.cs deleted file mode 100644 index bf9e4af7..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/StickyContainerGeneratedReverseComparer.cs +++ /dev/null @@ -1,52 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - internal class StickyContainerGeneratedReverseComparer : IComparer - { - #region Singleton Property - - public static StickyContainerGeneratedReverseComparer Singleton - { - get - { - if( _singleton == null ) - _singleton = new StickyContainerGeneratedReverseComparer(); - - return _singleton; - } - } - - private static StickyContainerGeneratedReverseComparer _singleton; - - #endregion Singleton Property - - #region IComparer Members - - public int Compare( StickyContainerGenerated x, StickyContainerGenerated y ) - { - return y.Index.CompareTo( x.Index ); - } - - #endregion IComparer Members - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/StickyContainerGeneratedStruct.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/StickyContainerGeneratedStruct.cs deleted file mode 100644 index 141b848d..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/StickyContainerGeneratedStruct.cs +++ /dev/null @@ -1,83 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal struct StickyContainerGenerated - { - #region CONSTRUCTORS - - public StickyContainerGenerated( DependencyObject container, int index, bool isNewlyRealized ) - : this() - { - this.StickyContainer = container; - this.Index = index; - this.IsNewlyRealized = isNewlyRealized; - } - - #endregion CONSTRUCTORS - - #region StickyContainer Property - - public DependencyObject StickyContainer - { - get; - private set; - } - - #endregion StickyContainer Property - - #region IsNewlyRealized Property - - public bool IsNewlyRealized - { - get; - private set; - } - - #endregion IsNewlyRealized Property - - #region Index Property - - public int Index - { - get; - set; - } - - #endregion Index Property - - #region Overrides - - public override bool Equals( object obj ) - { - return object.Equals( obj, this.StickyContainer ); - } - - public override int GetHashCode() - { - return this.StickyContainer.GetHashCode(); - } - - #endregion Overrides - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/WeakDataGridContextKey.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/WeakDataGridContextKey.cs deleted file mode 100644 index 7467129b..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(Generator)/WeakDataGridContextKey.cs +++ /dev/null @@ -1,124 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Diagnostics; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class WeakDataGridContextKey - { - internal WeakDataGridContextKey( DataGridContext dataGridContext ) - { - var parentDataGridContext = dataGridContext.ParentDataGridContext; - var level = 0; - - while( parentDataGridContext != null ) - { - level++; - parentDataGridContext = parentDataGridContext.ParentDataGridContext; - } - - Debug.Assert( ( ( level == 0 ) || ( dataGridContext.SourceDetailConfiguration != null ) ), "A child dataGridContext must have a SourceDetailConfiguration." ); - - m_sourceDetailConfigurationRelationName = ( dataGridContext.SourceDetailConfiguration != null ) ? dataGridContext.SourceDetailConfiguration.RelationName : string.Empty; - - if( level > 0 ) - { - // We are NOT dealing with the root DataGridContext. - - // Build the tree of master items. - m_weakItemsTree = new WeakReference[ level ]; - - var tempDataGridContext = dataGridContext; - for( int i = level - 1; i >= 0; i-- ) - { - // Ensure to get a reference to the System.Data.DataRow when doing a - // save/restore of a System.Data.DataRowView since the view is recreated - // for every detail views - var parentItem = ItemsSourceHelper.TryGetDataRowFromDataItem( tempDataGridContext.ParentItem ); - - m_weakItemsTree[ i ] = new WeakReference( parentItem ); - - tempDataGridContext = tempDataGridContext.ParentDataGridContext; - } - } - - m_hashCode = WeakDataGridContextKey.CalculateHashCode( m_sourceDetailConfigurationRelationName, m_weakItemsTree ); - } - - public override int GetHashCode() - { - return m_hashCode; - } - - public override bool Equals( object obj ) - { - var target = obj as WeakDataGridContextKey; - if( ( target == null ) || ( m_hashCode != target.m_hashCode ) ) - return false; - - if( m_sourceDetailConfigurationRelationName != target.m_sourceDetailConfigurationRelationName ) - return false; - - var dataGridContextStatusKeyLength = ( target.m_weakItemsTree == null ) ? 0 : target.m_weakItemsTree.Length; - var myLength = ( m_weakItemsTree == null ) ? 0 : m_weakItemsTree.Length; - - if( myLength != dataGridContextStatusKeyLength ) - return false; - - for( var i = 0; i < dataGridContextStatusKeyLength; i++ ) - { - var sourceItem = m_weakItemsTree[ i ].Target; - var targetItem = target.m_weakItemsTree[ i ].Target; - - if( !object.Equals( sourceItem, targetItem ) ) - return false; - } - - return true; - } - - private static int CalculateHashCode( string relationName, WeakReference[] items ) - { - var hashCode = ( !string.IsNullOrEmpty( relationName ) ) ? relationName.GetHashCode() : 0; - - if( items != null ) - { - // We use this hashing algorithm in order to get a different hashCode - // when the same values are in a different order in the object array. - for( var i = 0; i < items.Length; i++ ) - { - var item = items[ i ].Target; - Debug.Assert( item != null, "Item should still be referenced by the Child DataGridContext at this point!." ); - - if( item == null ) - continue; - - hashCode ^= item.GetHashCode(); - hashCode += ( hashCode << 10 ); - hashCode ^= ( hashCode >> 6 ); - } - } - - return hashCode; - } - - private readonly WeakReference[] m_weakItemsTree; - private readonly string m_sourceDetailConfigurationRelationName; - private readonly int m_hashCode; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/AutoScrollCurrentItemSourceTriggersEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/AutoScrollCurrentItemSourceTriggersEnum.cs deleted file mode 100644 index 423ac4c1..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/AutoScrollCurrentItemSourceTriggersEnum.cs +++ /dev/null @@ -1,39 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid -{ - [Flags] - internal enum AutoScrollCurrentItemSourceTriggers - { - None = 0x0000, - Navigation = 0x0001, - Editing = 0x0002, - FocusChanged = 0x0004, - SelectionChanged = 0x0008, - SortChanged = 0x0010, - GroupChanged = 0x0020, - CurrentItemChanged = 0x0040, - CurrentColumnChanged = 0x0080, - CollectionViewCurrentItemChanged = 0x0100, - ColumnsCollectionChanged = 0x0200, - ItemsSourceChanged = 0x0400, - ViewChanged = 0x0800, - ThemeChanged = 0x1000, - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/AutoScrollCurrentItemTriggersEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/AutoScrollCurrentItemTriggersEnum.cs deleted file mode 100644 index 535c7a13..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/AutoScrollCurrentItemTriggersEnum.cs +++ /dev/null @@ -1,37 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid -{ - // Defines the events that trigger the bring into view for the current item. - [Flags] - public enum AutoScrollCurrentItemTriggers - { - None = 0x00, - - CurrentChanged = 0x01, - ItemsSourceChanged = 0x02, - FocusChanged = 0x04, - SortChanged = 0x08, - GroupChanged = 0x10, - ViewChanged = 0x20, - ThemeChanged = 0x40, - - All = ~0x00 - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/CellEditorDisplayConditionsEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/CellEditorDisplayConditionsEnum.cs deleted file mode 100644 index c5942354..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/CellEditorDisplayConditionsEnum.cs +++ /dev/null @@ -1,33 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; - -namespace Xceed.Wpf.DataGrid -{ - [Flags] - public enum CellEditorDisplayConditions - { - None = 0x00, - RowIsBeingEdited = 0x01, - MouseOverCell = 0x02, - MouseOverRow = 0x04, - RowIsCurrent = 0x08, - CellIsCurrent = 0x10, - Always = 0x20 - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/ColumnDraggableStatusEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/ColumnDraggableStatusEnum.cs deleted file mode 100644 index 96f85cfe..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/ColumnDraggableStatusEnum.cs +++ /dev/null @@ -1,25 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -namespace Xceed.Wpf.DataGrid -{ - public enum ColumnDraggableStatus - { - Draggable = 0, - FirstUndraggable, - LastUndraggable, - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/ColumnWidthUnitTypeEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/ColumnWidthUnitTypeEnum.cs deleted file mode 100644 index 19b926a7..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/ColumnWidthUnitTypeEnum.cs +++ /dev/null @@ -1,26 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid -{ - public enum ColumnWidthUnitType - { - Pixel, - Star - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/CommitModeEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/CommitModeEnum.cs deleted file mode 100644 index 5b7711f4..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/CommitModeEnum.cs +++ /dev/null @@ -1,28 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - public enum CommitMode - { - PageReleasedFromMemory = 0, - EditCommitted = 1 - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/CompareResultEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/CompareResultEnum.cs deleted file mode 100644 index 1f941bb7..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/CompareResultEnum.cs +++ /dev/null @@ -1,28 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid -{ - internal enum CompareResult - { - DifferentThan, - EqualsTo, - LessThan, - GreaterThan - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/ConnectionLineAlignmentEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/ConnectionLineAlignmentEnum.cs deleted file mode 100644 index 9402538a..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/ConnectionLineAlignmentEnum.cs +++ /dev/null @@ -1,31 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - public enum ConnectionLineAlignment - { - RightToBottom = 0, - LeftToBottom = 1, - RightToTop = 2, - LeftToTop = 3, - CenterToCenter = 4, - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/DataGridConnectionStateEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/DataGridConnectionStateEnum.cs deleted file mode 100644 index 05c4a35a..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/DataGridConnectionStateEnum.cs +++ /dev/null @@ -1,30 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - public enum DataGridConnectionState - { - Idle, - Loading, - Committing, - Error - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/DataGridContextVisitorTypeEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/DataGridContextVisitorTypeEnum.cs deleted file mode 100644 index 37a7bd31..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/DataGridContextVisitorTypeEnum.cs +++ /dev/null @@ -1,34 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - [Flags] - internal enum DataGridContextVisitorType - { - Groups = 1, - HeadersFooters = 2, - GroupHeadersFooters = 4, - Items = 8, - DataGridContext = 16, - ItemsBlock = 32, - All = 63, //combine all the values together - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/DataGridDragBehaviorEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/DataGridDragBehaviorEnum.cs deleted file mode 100644 index f0783ca8..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/DataGridDragBehaviorEnum.cs +++ /dev/null @@ -1,29 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - public enum DataGridDragBehavior - { - DragDrop = 0, - Select - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/DataGridUpdateSourceTriggerEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/DataGridUpdateSourceTriggerEnum.cs deleted file mode 100644 index a5096c01..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/DataGridUpdateSourceTriggerEnum.cs +++ /dev/null @@ -1,30 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - public enum DataGridUpdateSourceTrigger - { - RowEndingEdit = 0, - CellEndingEdit = 1, - CellContentChanged = 2 - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/DeletingSelectedItemErrorActionEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/DeletingSelectedItemErrorActionEnum.cs deleted file mode 100644 index 70379485..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/DeletingSelectedItemErrorActionEnum.cs +++ /dev/null @@ -1,30 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - public enum DeletingSelectedItemErrorAction - { - Abort, - Retry, - Skip, - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/DistinctValuesConstraintEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/DistinctValuesConstraintEnum.cs deleted file mode 100644 index 17d43d29..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/DistinctValuesConstraintEnum.cs +++ /dev/null @@ -1,29 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - public enum DistinctValuesConstraint - { - All, - Filtered, - FilteredWithAllFilters - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/DistinctValuesUpdateModeEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/DistinctValuesUpdateModeEnum.cs deleted file mode 100644 index 9cf96663..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/DistinctValuesUpdateModeEnum.cs +++ /dev/null @@ -1,29 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - public enum DistinctValuesUpdateMode - { - Manual, - Auto - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/DropMarkAlignmentEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/DropMarkAlignmentEnum.cs deleted file mode 100644 index 094d8898..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/DropMarkAlignmentEnum.cs +++ /dev/null @@ -1,27 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid -{ - internal enum DropMarkAlignment - { - Near, - Far, - ExplicitPosition - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/EditTriggersEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/EditTriggersEnum.cs deleted file mode 100644 index 0e0560b6..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/EditTriggersEnum.cs +++ /dev/null @@ -1,34 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - [Flags] - public enum EditTriggers - { - None = 0x00, - BeginEditCommand = 0x01, - ClickOnCurrentCell = 0x02, - SingleClick = 0x04, - CellIsCurrent = 0x08, - ActivationGesture = 0x10, - RowIsCurrent = 0x20, - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/GeneratorNodeTypeEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/GeneratorNodeTypeEnum.cs deleted file mode 100644 index b71c66b9..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/GeneratorNodeTypeEnum.cs +++ /dev/null @@ -1,29 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - internal enum GeneratorNodeType - { - HeadersOrFooters, - Group, - Items, - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/ItemScrollingBehaviorEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/ItemScrollingBehaviorEnum.cs deleted file mode 100644 index 35ebd279..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/ItemScrollingBehaviorEnum.cs +++ /dev/null @@ -1,26 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid -{ - public enum ItemScrollingBehavior - { - Deferred, - Immediate - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/LocationTypeEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/LocationTypeEnum.cs deleted file mode 100644 index 93651a88..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/LocationTypeEnum.cs +++ /dev/null @@ -1,28 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - - -namespace Xceed.Wpf.DataGrid -{ - internal enum LocationType - { - Column, - Start, - End, - Splitter, - Orphan, - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/NavigationBehaviorEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/NavigationBehaviorEnum.cs deleted file mode 100644 index f6e03068..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/NavigationBehaviorEnum.cs +++ /dev/null @@ -1,30 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - public enum NavigationBehavior - { - None, - RowOnly, - CellOnly, - RowOrCell - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/PagingBehaviorEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/PagingBehaviorEnum.cs deleted file mode 100644 index 6c2f5a81..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/PagingBehaviorEnum.cs +++ /dev/null @@ -1,26 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid -{ - public enum PagingBehavior - { - TopToBottom, - LeftToRight - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/PrimaryAxisEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/PrimaryAxisEnum.cs deleted file mode 100644 index 84c37689..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/PrimaryAxisEnum.cs +++ /dev/null @@ -1,28 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid -{ - public enum PrimaryAxis - { - Vertical, - Horizontal, - Both, - None - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/PropertyRouteSegmentTypeEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/PropertyRouteSegmentTypeEnum.cs deleted file mode 100644 index 506316aa..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/PropertyRouteSegmentTypeEnum.cs +++ /dev/null @@ -1,27 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - - -namespace Xceed.Wpf.DataGrid -{ - internal enum PropertyRouteSegmentType : byte - { - Self, - Property, - Indexer, - Other, - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/ScrollDirectionEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/ScrollDirectionEnum.cs deleted file mode 100644 index 082fdf90..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/ScrollDirectionEnum.cs +++ /dev/null @@ -1,30 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - internal enum ScrollDirection - { - None, - Backward, - Forward - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/ScrollOrientationEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/ScrollOrientationEnum.cs deleted file mode 100644 index cddd4165..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/ScrollOrientationEnum.cs +++ /dev/null @@ -1,28 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid -{ - [Flags] - public enum ScrollOrientation - { - None = 0, - Horizontal = 1, - Vertical = 2, - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/SelectionBehaviorEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/SelectionBehaviorEnum.cs deleted file mode 100644 index 5cec2603..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/SelectionBehaviorEnum.cs +++ /dev/null @@ -1,25 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -namespace Xceed.Wpf.DataGrid -{ - public enum SelectionBehavior - { - Default, - None, - All - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/SelectionUnitEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/SelectionUnitEnum.cs deleted file mode 100644 index de69a0bd..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/SelectionUnitEnum.cs +++ /dev/null @@ -1,29 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - public enum SelectionUnit - { - Row = 0, - Cell = 1 - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/SortDirectionEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/SortDirectionEnum.cs deleted file mode 100644 index f1d536cd..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/SortDirectionEnum.cs +++ /dev/null @@ -1,27 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid -{ - public enum SortDirection - { - None, - Ascending, - Descending, - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/ValidationModeEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/ValidationModeEnum.cs deleted file mode 100644 index 83d94ce6..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/(enums)/ValidationModeEnum.cs +++ /dev/null @@ -1,26 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid -{ - public enum ValidationMode - { - CellEndingEdit, - RowEndingEdit - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ActivationGesture.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ActivationGesture.cs deleted file mode 100644 index 999bbed8..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ActivationGesture.cs +++ /dev/null @@ -1,30 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - public abstract class ActivationGesture : Freezable - { - internal ActivationGesture() - { - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ActivationGestureCollection.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ActivationGestureCollection.cs deleted file mode 100644 index 13062af9..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ActivationGestureCollection.cs +++ /dev/null @@ -1,28 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Collections.ObjectModel; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - public class ActivationGestureCollection: FreezableCollection - { - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/AssemblyVersionInfo.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/AssemblyVersionInfo.cs deleted file mode 100644 index cc626fb5..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/AssemblyVersionInfo.cs +++ /dev/null @@ -1,41 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -[assembly: System.Reflection.AssemblyVersion( _XceedVersionInfo.Version )] - -internal static class _XceedVersionInfo -{ - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] - public const string BaseVersion = "3.5"; - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] - public const string Version = BaseVersion + ".0.0"; - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] - public const string PublicKeyToken = "ba83ff368b7563c6"; - - public const string FrameworkVersion = "4.0.0.0"; - - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] - public const string DesignFullName = - "Xceed.Wpf.DataGrid,Version=" + - Version + - ",Culture=neutral,PublicKeyToken=" + PublicKeyToken; - - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] - public const string CurrentAssemblyPackUri = - "pack://application:,,,/Xceed.Wpf.DataGrid,Version=" + Version; - - -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/AssemblyVersionInfoCommon.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/AssemblyVersionInfoCommon.cs deleted file mode 100644 index 3316fb13..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/AssemblyVersionInfoCommon.cs +++ /dev/null @@ -1,22 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -internal static class _XceedVersionInfoCommon -{ -[System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] - public const string Build = ".*"; - -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/AutoResetFlag.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/AutoResetFlag.cs deleted file mode 100644 index 412e166e..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/AutoResetFlag.cs +++ /dev/null @@ -1,34 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid -{ - internal abstract class AutoResetFlag - { - #region IsSet Property - - public abstract bool IsSet - { - get; - } - - #endregion - - public abstract IDisposable Set(); - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/AutoResetFlagFactory.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/AutoResetFlagFactory.cs deleted file mode 100644 index 29221f10..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/AutoResetFlagFactory.cs +++ /dev/null @@ -1,155 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Diagnostics; -using System.Threading; - -namespace Xceed.Wpf.DataGrid -{ - internal static class AutoResetFlagFactory - { - public static AutoResetFlag Create() - { - return AutoResetFlagFactory.Create( true ); - } - - public static AutoResetFlag Create( bool singleSet ) - { - if( singleSet ) - return new SingleAutoResetFlag(); - - return new MultiAutoResetFlag(); - } - - #region IAutoResetFlag Private Interface - - private interface IAutoResetFlag - { - void Set(); - void Unset(); - } - - #endregion - - #region ResetFlagDisposable Private Class - - private sealed class ResetFlagDisposable : IDisposable - { - internal ResetFlagDisposable( IAutoResetFlag target ) - { - Debug.Assert( target != null ); - - m_target = target; - m_target.Set(); - } - - private void Dispose( bool disposing ) - { - // The disposed method has already been called at least once. - var target = Interlocked.Exchange( ref m_target, null ); - if( target == null ) - return; - - Debug.Assert( m_target == null ); - Debug.Assert( target != null ); - - // We can only get here if this is the first call to Dispose. - target.Unset(); - } - - void IDisposable.Dispose() - { - this.Dispose( true ); - GC.SuppressFinalize( this ); - } - - ~ResetFlagDisposable() - { - this.Dispose( false ); - } - - private IAutoResetFlag m_target; - } - - #endregion - - #region SingleAutoResetFlag Private Class - - private sealed class SingleAutoResetFlag : AutoResetFlag, IAutoResetFlag - { - public override bool IsSet - { - get - { - return ( Interlocked.CompareExchange( ref m_isSet, null, null ) == this ); - } - } - - public override IDisposable Set() - { - return new ResetFlagDisposable( this ); - } - - void IAutoResetFlag.Set() - { - if( Interlocked.CompareExchange( ref m_isSet, this, null ) != null ) - throw new InvalidOperationException( "The flag is already set." ); - } - - void IAutoResetFlag.Unset() - { - Interlocked.CompareExchange( ref m_isSet, null, this ); - } - - private object m_isSet; //null - } - - #endregion - - #region MultiAutoResetFlag Private Class - - private sealed class MultiAutoResetFlag : AutoResetFlag, IAutoResetFlag - { - public override bool IsSet - { - get - { - return ( m_count > 0 ); - } - } - - public override IDisposable Set() - { - return new ResetFlagDisposable( this ); - } - - void IAutoResetFlag.Set() - { - Interlocked.Increment( ref m_count ); - } - - void IAutoResetFlag.Unset() - { - Interlocked.Decrement( ref m_count ); - } - - private int m_count; //0 - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/AutoScrollCurrentItemSourceTriggersRestrictions.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/AutoScrollCurrentItemSourceTriggersRestrictions.cs deleted file mode 100644 index 0b95cf24..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/AutoScrollCurrentItemSourceTriggersRestrictions.cs +++ /dev/null @@ -1,105 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class AutoScrollCurrentItemSourceTriggersRestrictions - { - #region Restrictions Property - - internal AutoScrollCurrentItemSourceTriggers Restrictions - { - get - { - var result = AutoScrollCurrentItemSourceTriggers.None; - - for( int i = m_restrictions.Count - 1; i >= 0; i-- ) - { - var item = m_restrictions[ i ].Target as SingleRestriction; - - if( item != null ) - { - result |= item.Value; - } - else - { - m_restrictions.RemoveAt( i ); - } - } - - return result; - } - } - - #endregion - - internal IDisposable SetRestriction( AutoScrollCurrentItemSourceTriggers value ) - { - var disposable = new SingleRestriction( value ); - - m_restrictions.Add( new WeakReference( disposable ) ); - - return disposable; - } - - #region Private Fields - - private readonly List m_restrictions = new List(); - - #endregion - - #region SingleRestriction Private Class - - private sealed class SingleRestriction : IDisposable - { - internal SingleRestriction( AutoScrollCurrentItemSourceTriggers value ) - { - m_value = value; - } - - internal AutoScrollCurrentItemSourceTriggers Value - { - get - { - return m_value; - } - } - - void IDisposable.Dispose() - { - this.Dispose( true ); - GC.SuppressFinalize( this ); - } - - private void Dispose( bool disposing ) - { - m_value = AutoScrollCurrentItemSourceTriggers.None; - } - - ~SingleRestriction() - { - this.Dispose( false ); - } - - private AutoScrollCurrentItemSourceTriggers m_value; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/BindingProxy.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/BindingProxy.cs deleted file mode 100644 index d8d3dd82..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/BindingProxy.cs +++ /dev/null @@ -1,60 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.ComponentModel; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - public class BindingProxy : Freezable - { - #region Value Property - - public static readonly DependencyProperty ValueProperty = DependencyProperty.Register( - "Value", - typeof( object ), - typeof( BindingProxy ), - new UIPropertyMetadata( null ) ); - - public object Value - { - get - { - return this.GetValue( BindingProxy.ValueProperty ); - } - set - { - this.SetValue( BindingProxy.ValueProperty, value ); - } - } - - #endregion - - protected override Freezable CreateInstanceCore() - { - return new BindingProxy(); - } - - protected sealed override bool FreezeCore( bool isChecking ) - { - // Only derived from Freezable to have DataContext and ElementName binding. - // So we don't want to be freezable. - return false; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Cell.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Cell.cs deleted file mode 100644 index 64490444..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Cell.cs +++ /dev/null @@ -1,4568 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Diagnostics; -using System.Globalization; -using System.Reflection; -using System.Security; -using System.Windows; -using System.Windows.Automation.Peers; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Threading; -using Xceed.Utils.Wpf; -using Xceed.Wpf.DataGrid.Utils; -using Xceed.Wpf.DataGrid.ValidationRules; -using Xceed.Wpf.DataGrid.Views; -using Xceed.Wpf.Toolkit.Core; - -namespace Xceed.Wpf.DataGrid -{ - [TemplatePart( Name = "PART_CellContentPresenter", Type = typeof( ContentPresenter ) )] - public class Cell : ContentControl, INotifyPropertyChanged, IWeakEventListener - { - internal static readonly string FieldNamePropertyName = PropertyHelper.GetPropertyName( ( Cell c ) => c.FieldName ); - - // This validation rule is meant to be used as the rule in error set in a Cell's ValidationError when the CellEditor's HasError attached property returns true. - private static readonly CellEditorErrorValidationRule CellEditorErrorValidationRule = new CellEditorErrorValidationRule(); - - // This validation rule is meant to be used as the rule in error set in a Cell's ValidationError when - // we want to flag a validation error even though no binding's ValidationRules or CellValidationRules are invalid. - // ie: Cell EditEnding event throws or returns with e.Cancel set to True. - private static readonly PassthroughCellValidationRule CustomCellValidationExceptionValidationRule = new PassthroughCellValidationRule( new ExceptionValidationRule() ); - - static Cell() - { - Cell.ContentProperty.OverrideMetadata( typeof( Cell ), - new FrameworkPropertyMetadata( new PropertyChangedCallback( OnContentChanged ), new CoerceValueCallback( OnCoerceContent ) ) ); - - //This configures the TAB key to go trough the controls of the cell once... then continue with other controls - KeyboardNavigation.TabNavigationProperty.OverrideMetadata( typeof( Cell ), new FrameworkPropertyMetadata( KeyboardNavigationMode.None ) ); - - //This configures the directional keys to go trough the controls of the cell once... then continue with other controls - KeyboardNavigation.DirectionalNavigationProperty.OverrideMetadata( typeof( Cell ), new FrameworkPropertyMetadata( KeyboardNavigationMode.None ) ); - - ContentControl.HorizontalContentAlignmentProperty.OverrideMetadata( typeof( Cell ), new FrameworkPropertyMetadata( HorizontalAlignment.Stretch ) ); - - ContentControl.VerticalContentAlignmentProperty.OverrideMetadata( typeof( Cell ), new FrameworkPropertyMetadata( VerticalAlignment.Stretch ) ); - - Cell.ContentTemplateProperty.OverrideMetadata( typeof( Cell ), new FrameworkPropertyMetadata( new PropertyChangedCallback( OnContentTemplateChanged ) ) ); - - Cell.ContentTemplateSelectorProperty.OverrideMetadata( typeof( Cell ), new FrameworkPropertyMetadata( new PropertyChangedCallback( OnContentTemplateSelectorChanged ) ) ); - - Cell.IsCurrentProperty = Cell.IsCurrentPropertyKey.DependencyProperty; - Cell.IsSelectedProperty = Cell.IsSelectedPropertyKey.DependencyProperty; - Cell.ParentCellProperty = Cell.ParentCellPropertyKey.DependencyProperty; - Cell.ParentColumnProperty = Cell.ParentColumnPropertyKey.DependencyProperty; - Cell.ParentRowProperty = Cell.ParentRowPropertyKey.DependencyProperty; - Cell.CoercedContentTemplateProperty = Cell.CoercedContentTemplatePropertyKey.DependencyProperty; - - //Editing stuff - DataGridControl.CellEditorDisplayConditionsProperty.OverrideMetadata( typeof( Cell ), - new FrameworkPropertyMetadata( new PropertyChangedCallback( OnCellEditorDisplayConditionsChanged ) ) ); - - Cell.IsBeingEditedProperty = Cell.IsBeingEditedPropertyKey.DependencyProperty; - Cell.IsDirtyProperty = Cell.IsDirtyPropertyKey.DependencyProperty; - - // We do this last to ensure all the Static content of the cell is done before using - // any static read-only field of the row. - Cell.RowDisplayEditorMatchingConditionsProperty = - Row.RowDisplayEditorMatchingConditionsProperty.AddOwner( typeof( Cell ), - new FrameworkPropertyMetadata( new PropertyChangedCallback( OnMatchingDisplayEditorChanged ) ) ); - - Cell.CellEditorContextProperty = Cell.CellEditorContextPropertyKey.DependencyProperty; - - // Animated Column reordering Binding - Cell.ParentColumnTranslationBinding = new Binding(); - Cell.ParentColumnTranslationBinding.Path = new PropertyPath( "ParentColumn.(0)", ColumnReorderingDragSourceManager.AnimatedColumnReorderingTranslationProperty ); - Cell.ParentColumnTranslationBinding.Mode = BindingMode.OneWay; - Cell.ParentColumnTranslationBinding.RelativeSource = new RelativeSource( RelativeSourceMode.Self ); - - Cell.ParentColumnIsBeingDraggedBinding = new Binding(); - Cell.ParentColumnIsBeingDraggedBinding.Path = new PropertyPath( "ParentColumn.(0)", TableflowView.IsBeingDraggedAnimatedProperty ); - Cell.ParentColumnIsBeingDraggedBinding.Mode = BindingMode.OneWay; - Cell.ParentColumnIsBeingDraggedBinding.RelativeSource = new RelativeSource( RelativeSourceMode.Self ); - - Cell.ParentColumnReorderingDragSourceManagerBinding = new Binding(); - Cell.ParentColumnReorderingDragSourceManagerBinding.Path = new PropertyPath( "ParentColumn.(0)", TableflowView.ColumnReorderingDragSourceManagerProperty ); - Cell.ParentColumnReorderingDragSourceManagerBinding.Mode = BindingMode.OneWay; - Cell.ParentColumnReorderingDragSourceManagerBinding.RelativeSource = new RelativeSource( RelativeSourceMode.Self ); - - Cell.ParentRowCellContentOpacityBinding = new Binding(); - Cell.ParentRowCellContentOpacityBinding.Path = new PropertyPath( "(0).(1)", Cell.ParentRowProperty, Row.CellContentOpacityProperty ); - Cell.ParentRowCellContentOpacityBinding.Mode = BindingMode.OneWay; - Cell.ParentRowCellContentOpacityBinding.RelativeSource = new RelativeSource( RelativeSourceMode.TemplatedParent ); - - Row.IsTemplateCellProperty.OverrideMetadata( typeof( Cell ), new FrameworkPropertyMetadata( new PropertyChangedCallback( Cell.OnIsTemplateCellChanged ) ) ); - - EventManager.RegisterClassHandler( typeof( Cell ), FrameworkElement.RequestBringIntoViewEvent, new RequestBringIntoViewEventHandler( Cell.Cell_RequestBringIntoView ) ); - } - - public Cell() - { - this.SetParentCell(); - - this.CommandBindings.Add( new CommandBinding( DataGridCommands.BeginEdit, - new ExecutedRoutedEventHandler( OnBeginEditExecuted ), - new CanExecuteRoutedEventHandler( OnBeginEditCanExecute ) ) ); - - this.CommandBindings.Add( new CommandBinding( DataGridCommands.CancelEdit, - new ExecutedRoutedEventHandler( OnCancelEditExecuted ), - new CanExecuteRoutedEventHandler( OnCancelEditCanExecute ) ) ); - - // Remove the error template by default. - this.SetValue( Validation.ErrorTemplateProperty, null ); - - Validation.AddErrorHandler( this, Cell.OnContentBindingNotifyValidationError ); - this.TargetUpdated += new EventHandler( this.OnContentBindingTargetUpdated ); - this.LayoutUpdated += new EventHandler( this.Cell_LayoutUpdated ); - } - - #region IsCellFocusScope Attached Property - - - public static readonly DependencyProperty IsCellFocusScopeProperty = - DependencyProperty.RegisterAttached( "IsCellFocusScope", typeof( bool ), typeof( Cell ), new UIPropertyMetadata( false ) ); - - - public static bool GetIsCellFocusScope( DependencyObject obj ) - { - return ( bool )obj.GetValue( Cell.IsCellFocusScopeProperty ); - } - - - public static void SetIsCellFocusScope( DependencyObject obj, bool value ) - { - obj.SetValue( Cell.IsCellFocusScopeProperty, value ); - } - - #endregion IsCellFocusScope Attached Property - - #region ReadOnly Property - - public static readonly DependencyProperty ReadOnlyProperty = DataGridControl.ReadOnlyProperty.AddOwner( typeof( Cell ) ); - - public bool ReadOnly - { - get - { - return ( bool )this.GetValue( Cell.ReadOnlyProperty ); - } - set - { - this.SetValue( Cell.ReadOnlyProperty, value ); - } - } - - #endregion ReadOnly Property - - #region IsCurrent Read-Only Property - - private static readonly DependencyPropertyKey IsCurrentPropertyKey = - DependencyProperty.RegisterReadOnly( "IsCurrent", typeof( bool ), typeof( Cell ), new UIPropertyMetadata( false ) ); - - public static readonly DependencyProperty IsCurrentProperty; - - public bool IsCurrent - { - get - { - return ( bool )this.GetValue( Cell.IsCurrentProperty ); - } - } - - internal void SetIsCurrent( bool value ) - { - if( value ) - { - this.SetValue( Cell.IsCurrentPropertyKey, true ); - } - else - { - this.SetValue( Cell.IsCurrentPropertyKey, DependencyProperty.UnsetValue ); - } - } - - #endregion IsCurrent Read-Only Property - - #region IsSelected Read-Only Property - - private static readonly DependencyPropertyKey IsSelectedPropertyKey = - DependencyProperty.RegisterReadOnly( "IsSelected", typeof( bool ), typeof( Cell ), new UIPropertyMetadata( false ) ); - - public static readonly DependencyProperty IsSelectedProperty; - - public bool IsSelected - { - get - { - return ( bool )this.GetValue( Cell.IsSelectedProperty ); - } - } - - internal void SetIsSelected( bool value ) - { - if( this.IsSelected != value ) - { - if( value ) - { - this.SetValue( Cell.IsSelectedPropertyKey, value ); - } - else - { - this.ClearValue( Cell.IsSelectedPropertyKey ); - } - } - } - - #endregion IsSelected Read-Only Property - - #region IsBeingEdited Read-Only Property - - private static readonly DependencyPropertyKey IsBeingEditedPropertyKey = DependencyProperty.RegisterReadOnly( - "IsBeingEdited", - typeof( bool ), - typeof( Cell ), - new PropertyMetadata( false ) ); - - public static readonly DependencyProperty IsBeingEditedProperty; - - internal static readonly RoutedEvent IsBeingEditedEvent = EventManager.RegisterRoutedEvent( "IsBeingEdited", RoutingStrategy.Bubble, typeof( RoutedEventHandler ), typeof( Cell ) ); - - public bool IsBeingEdited - { - get - { - return this.IsBeingEditedCache; - } - } - - private void SetIsBeingEdited( bool value ) - { - if( value != this.IsBeingEdited ) - { - this.FocusEditor = false; - this.IsBeingEditedCache = value; - - if( value ) - { - this.SetValue( Cell.IsBeingEditedPropertyKey, true ); - } - else - { - this.SetValue( Cell.IsBeingEditedPropertyKey, DependencyProperty.UnsetValue ); - } - - CellState cellState = this.GetEditCachedState(); - - if( cellState != null ) - { - cellState.SetIsBeingEdited( value ); - } - - if( this.ParentRow.IsClearingContainer ) - return; - - //If cell is being edited - if( value ) - { - //Raise the RoutedEvent that notifies any Row that the cell is being edited. - RoutedEventArgs eventArgs = new RoutedEventArgs( Cell.IsBeingEditedEvent ); - this.RaiseEvent( eventArgs ); - this.FocusEditor = true; - } - - this.RefreshDisplayedTemplate(); - } - } - - #endregion IsBeingEdited Read-Only Property - - #region IsDirty Read-Only Property - - private static readonly DependencyPropertyKey IsDirtyPropertyKey = DependencyProperty.RegisterReadOnly( - "IsDirty", - typeof( bool ), - typeof( Cell ), - new PropertyMetadata( false, new PropertyChangedCallback( Cell.OnIsDirtyChanged ) ) ); - - public static readonly DependencyProperty IsDirtyProperty; - - internal static readonly RoutedEvent IsDirtyEvent = EventManager.RegisterRoutedEvent( "IsDirty", RoutingStrategy.Bubble, typeof( RoutedEventHandler ), typeof( Cell ) ); - - public bool IsDirty - { - get - { - return ( bool )this.GetValue( Cell.IsDirtyProperty ); - } - } - - internal void SetIsDirty( bool value ) - { - if( value != this.IsDirty ) - { - if( value ) - { - this.SetValue( Cell.IsDirtyPropertyKey, value ); - } - else - { - this.SetValue( Cell.IsDirtyPropertyKey, DependencyProperty.UnsetValue ); - } - - CellState cellState = this.GetEditCachedState(); - - if( cellState != null ) - { - cellState.SetIsDirty( value ); - } - } - } - - #endregion IsDirty Read-Only Property - - #region IsCellEditorDisplayed Read-Only Property - - public bool IsCellEditorDisplayed - { - get - { - return m_flags[ ( int )CellFlags.IsCellEditorDisplayed ]; - } - } - - private void SetIsCellEditorDisplayed( bool value ) - { - if( value != this.IsCellEditorDisplayed ) - { - m_flags[ ( int )CellFlags.IsCellEditorDisplayed ] = value; - this.OnPropertyChanged( "IsCellEditorDisplayed" ); - } - } - - #endregion IsCellEditorDisplayed Read-Only Property - - #region CurrentBackground Property - - public static readonly DependencyProperty CurrentBackgroundProperty = DependencyProperty.Register( - "CurrentBackground", - typeof( Brush ), - typeof( Cell ), - new FrameworkPropertyMetadata( null ) ); - - public Brush CurrentBackground - { - get - { - return ( Brush )this.GetValue( Cell.CurrentBackgroundProperty ); - } - set - { - this.SetValue( Cell.CurrentBackgroundProperty, value ); - } - } - - #endregion CurrentBackground Property - - #region CurrentForeground Property - - public static readonly DependencyProperty CurrentForegroundProperty = - DependencyProperty.Register( "CurrentForeground", - typeof( Brush ), - typeof( Cell ), - new FrameworkPropertyMetadata( null ) ); - - public Brush CurrentForeground - { - get - { - return ( Brush )this.GetValue( Cell.CurrentForegroundProperty ); - } - set - { - this.SetValue( Cell.CurrentForegroundProperty, value ); - } - } - - #endregion CurrentForeground Property - - #region CellValidationRules Property - - public Collection CellValidationRules - { - get - { - if( m_cellValidationRules == null ) - m_cellValidationRules = new Collection(); - - return m_cellValidationRules; - } - } - - private Collection m_cellValidationRules; // = null - - #endregion CellValidationRules Property - - #region CellErrorStyle Property - - public static readonly DependencyProperty CellErrorStyleProperty = DataGridControl.CellErrorStyleProperty.AddOwner( typeof( Cell ) ); - - public Style CellErrorStyle - { - get - { - return ( Style )this.GetValue( Cell.CellErrorStyleProperty ); - } - - set - { - this.SetValue( Cell.CellErrorStyleProperty, value ); - } - } - - #endregion CellErrorStyle Property - - #region HasValidationError Read-Only Property - - private static readonly DependencyPropertyKey HasValidationErrorPropertyKey = DependencyProperty.RegisterReadOnly( - "HasValidationError", - typeof( bool ), - typeof( Cell ), - new UIPropertyMetadata( false, new PropertyChangedCallback( Cell.OnHasValidationErrorChanged ) ) ); - - public static readonly DependencyProperty HasValidationErrorProperty = HasValidationErrorPropertyKey.DependencyProperty; - - public bool HasValidationError - { - get - { - return ( bool )this.GetValue( Cell.HasValidationErrorProperty ); - } - } - - private void SetHasValidationError( bool value ) - { - if( value != this.HasValidationError ) - { - if( value ) - { - this.SetValue( Cell.HasValidationErrorPropertyKey, value ); - } - else - { - this.SetValue( Cell.HasValidationErrorPropertyKey, DependencyProperty.UnsetValue ); - } - } - } - - private static void OnHasValidationErrorChanged( object sender, DependencyPropertyChangedEventArgs e ) - { - Cell cell = ( Cell )sender; - - // If we are in the process of clearing the cell, don't refresh the error style. - // It is imperative to take care of resetting all the flags used by the DelayedRefreshErrorStyle architecture in the Cell's ClearContainer method though. - var parentRow = cell.ParentRow; - if( ( parentRow != null ) && parentRow.IsClearingContainer ) - return; - - // This flag is used to optimize the synchronization of error flags on the parent row/column so that it is done only once at the end of the UpdateHasErrorFlags method. - cell.HasPendingSyncParentErrorFlags = true; - - if( cell.HasPendingErrorStyleRefresh ) - return; - - cell.HasPendingErrorStyleRefresh = true; - - if( !cell.IsLoaded ) - { - // If the cell isn't loaded, wait for the loaded event to dispatch the change of style. - System.Diagnostics.Debug.Assert( cell.m_loadedRoutedEventHandler == null ); - - cell.m_loadedRoutedEventHandler = new RoutedEventHandler( cell.Cell_Loaded ); - cell.Loaded += cell.m_loadedRoutedEventHandler; - return; - } - - cell.DelayRefreshErrorStyle(); - } - - private void DelayRefreshErrorStyle() - { - if( m_delayedRefreshErrorStyleDispatcherOperation != null ) - return; - - // Push on the dispatcher so that we prevent multiple affectation of Style when the binding is re-evaluated. - // Re-evaluating a binding causes it to clear all errors, then validate and finally sets the errors. - // By using the following strategy, we make sure of not affecting Style when it will change right afterward. - m_delayedRefreshErrorStyleDispatcherOperation = this.Dispatcher.BeginInvoke( DispatcherPriority.Render, new Action( this.DelayedRefreshErrorStyle ) ); - } - - private void AbortRefreshErrorStyle() - { - if( m_delayedRefreshErrorStyleDispatcherOperation == null ) - return; - - Debug.Assert( m_delayedRefreshErrorStyleDispatcherOperation.Status == DispatcherOperationStatus.Pending ); - m_delayedRefreshErrorStyleDispatcherOperation.Abort(); - m_delayedRefreshErrorStyleDispatcherOperation = null; - } - - private void DelayedRefreshErrorStyle() - { - m_delayedRefreshErrorStyleDispatcherOperation = null; - System.Diagnostics.Debug.Assert( this.HasPendingErrorStyleRefresh, "The operation should have been aborted." ); - System.Diagnostics.Debug.Assert( ( ( this.ParentRow != null ) && !this.ParentRow.IsClearingContainer ), "The operation should have been aborted." ); - - if( !this.IsLoaded ) - { - // Such a sitation can occur when the cell is Loaded when OnHasErrorChanged is raised but unloaded without a ClearContainer afterward. - // Therefore, we need to push back the refreshing of the style to the cell's Loaded event. - System.Diagnostics.Debug.Assert( m_loadedRoutedEventHandler == null ); - - m_loadedRoutedEventHandler = new RoutedEventHandler( this.Cell_Loaded ); - this.Loaded += m_loadedRoutedEventHandler; - return; - } - - try - { - bool hasValidationError = this.HasValidationError; - bool shouldChangeStyle = ( this.IsErrorStyleApplied != hasValidationError ); - - if( shouldChangeStyle ) - { - if( hasValidationError ) - { - // Cache the normal style. - m_styleBeforeError = this.ReadLocalValue( Cell.StyleProperty ); - - //Apply the style. - Style errorStyle = this.GetInheritedErrorStyle(); - - if( errorStyle != null ) - { - this.Style = errorStyle; - this.IsErrorStyleApplied = true; - } - } - else - { - // Revert to the normal style. - if( m_styleBeforeError == DependencyProperty.UnsetValue ) - { - this.ClearValue( Cell.StyleProperty ); - } - else - { - this.Style = m_styleBeforeError as Style; - } - - this.IsErrorStyleApplied = false; - } - } - } - finally - { - this.HasPendingErrorStyleRefresh = false; - } - } - - #endregion HasValidationError Read-Only Property - - #region IsValidationErrorRestrictive Read-Only Property - - private static readonly DependencyPropertyKey IsValidationErrorRestrictivePropertyKey = DependencyProperty.RegisterReadOnly( - "IsValidationErrorRestrictive", - typeof( bool ), - typeof( Cell ), - new PropertyMetadata( false ) ); - - public static readonly DependencyProperty IsValidationErrorRestrictiveProperty = Cell.IsValidationErrorRestrictivePropertyKey.DependencyProperty; - - public bool IsValidationErrorRestrictive - { - get - { - return ( bool )this.GetValue( Cell.IsValidationErrorRestrictiveProperty ); - } - } - - private void SetIsValidationErrorRestrictive( bool value ) - { - if( value != this.IsValidationErrorRestrictive ) - { - if( value ) - { - this.SetValue( Cell.IsValidationErrorRestrictivePropertyKey, value ); - } - else - { - this.SetValue( Cell.IsValidationErrorRestrictivePropertyKey, DependencyProperty.UnsetValue ); - } - } - } - - private static void OnIsValidationErrorRestrictiveChanged( object sender, DependencyPropertyChangedEventArgs e ) - { - Cell cell = ( Cell )sender; - cell.HasPendingSyncParentErrorFlags = true; - } - - #endregion IsValidationErrorRestrictive Read-Only Property - - #region ValidationError Read-Only Property - - public static readonly RoutedEvent ValidationErrorChangingEvent = - EventManager.RegisterRoutedEvent( "ValidationErrorChanging", RoutingStrategy.Bubble, typeof( CellValidationErrorRoutedEventHandler ), typeof( Cell ) ); - - public event CellValidationErrorRoutedEventHandler ValidationErrorChanging - { - add - { - base.AddHandler( Cell.ValidationErrorChangingEvent, value ); - } - remove - { - base.RemoveHandler( Cell.ValidationErrorChangingEvent, value ); - } - } - - protected virtual void OnValidationErrorChanging( CellValidationErrorRoutedEventArgs e ) - { - this.RaiseEvent( e ); - } - - private static readonly DependencyPropertyKey ValidationErrorPropertyKey = DependencyProperty.RegisterReadOnly( - "ValidationError", - typeof( CellValidationError ), - typeof( Cell ), - new FrameworkPropertyMetadata( null, new PropertyChangedCallback( Cell.OnValidationErrorChanged ), new CoerceValueCallback( Cell.OnCoerceValidationError ) ) ); - - public static readonly DependencyProperty ValidationErrorProperty = ValidationErrorPropertyKey.DependencyProperty; - - public CellValidationError ValidationError - { - get - { - return ( CellValidationError )this.GetValue( Cell.ValidationErrorProperty ); - } - } - - private static object OnCoerceValidationError( DependencyObject sender, object value ) - { - if( value == null ) - return value; - - Cell cell = ( Cell )sender; - - CellValidationErrorRoutedEventArgs cellValidationErrorRoutedEventArgs = - new CellValidationErrorRoutedEventArgs( Cell.ValidationErrorChangingEvent, cell, ( CellValidationError )value ); - - cell.OnValidationErrorChanging( cellValidationErrorRoutedEventArgs ); - - return cellValidationErrorRoutedEventArgs.CellValidationError; - } - - private static void OnValidationErrorChanged( object sender, DependencyPropertyChangedEventArgs e ) - { - Cell cell = ( Cell )sender; - - CellValidationError newCellValidationError = e.NewValue as CellValidationError; - - // Update the flags telling us wether or not the current validation error is CellEditor error, or a UI error and update the HasValidationError dependency property. - cell.UpdateHasErrorFlags( newCellValidationError ); - - // Refresh which content template is displayed (editTemplate or not) in case there was a CellEditor validation error on the cell and now there isn't one anymore. - cell.RefreshDisplayedTemplate(); - } - - private void UpdateHasErrorFlags( CellValidationError cellValidationError ) - { - bool hasValidationError = ( cellValidationError != null ); - - try - { - if( hasValidationError ) - { - this.HasCellEditorError = Cell.GetIsCellEditorError( cellValidationError ); - this.HasUIValidationError = Cell.GetIsUIValidationError( cellValidationError ); - this.HasContentBindingValidationError = Cell.GetIsContentBindingValidationError( cellValidationError ); - - this.SetIsValidationErrorRestrictive( Cell.GetIsValidationErrorRestrictive( cellValidationError ) ); - - this.SetHasValidationError( true ); - } - else - { - this.HasCellEditorError = false; - this.HasUIValidationError = false; - this.HasContentBindingValidationError = false; - - this.SetIsValidationErrorRestrictive( false ); - - this.SetHasValidationError( false ); - } - - // This flag is raised in the PropertyChanged callbacks of the Has_X_Error properties in order to - // minimize the calls to the cell's parent row's UpdateHasErrorFlags method. - if( this.HasPendingSyncParentErrorFlags ) - { - ColumnBase column = this.ParentColumn; - - if( column != null ) - { - column.SetHasValidationError( hasValidationError ); - } - - Row row = this.ParentRow; - - if( row != null ) - { - row.UpdateHasErrorFlags( this ); - } - } - } - finally - { - this.HasPendingSyncParentErrorFlags = false; - } - } - - internal void SetValidationError( CellValidationError value ) - { - if( value != this.ValidationError ) - { - if( value != null ) - { - this.SetValue( Cell.ValidationErrorPropertyKey, value ); - } - else - { - this.SetValue( Cell.ValidationErrorPropertyKey, DependencyProperty.UnsetValue ); - } - - CellState cellState = this.GetEditCachedState(); - - if( cellState != null ) - { - cellState.SetCellValidationError( value ); - } - } - } - - #endregion ValidationError Read-Only Property - - #region RowDisplayEditorMatchingConditions Property - - private static readonly DependencyProperty RowDisplayEditorMatchingConditionsProperty; - - #endregion RowDisplayEditorMatchingConditions Property - - #region CellDisplayEditorMatchingConditions Property - - private static readonly DependencyProperty CellDisplayEditorMatchingConditionsProperty = DependencyProperty.Register( - "CellDisplayEditorMatchingConditions", - typeof( CellEditorDisplayConditions ), - typeof( Cell ), - new UIPropertyMetadata( CellEditorDisplayConditions.None, new PropertyChangedCallback( OnMatchingDisplayEditorChanged ) ) ); - - internal void SetDisplayEditorMatchingCondition( CellEditorDisplayConditions condition ) - { - CellEditorDisplayConditions previousValue = ( CellEditorDisplayConditions )this.GetValue( Cell.CellDisplayEditorMatchingConditionsProperty ); - - previousValue = previousValue | condition; - - this.SetValue( Cell.CellDisplayEditorMatchingConditionsProperty, previousValue ); - } - - internal void RemoveDisplayEditorMatchingCondition( CellEditorDisplayConditions condition ) - { - CellEditorDisplayConditions previousValue = ( CellEditorDisplayConditions )this.GetValue( Cell.CellDisplayEditorMatchingConditionsProperty ); - - previousValue = previousValue & ~condition; - - this.SetValue( Cell.CellDisplayEditorMatchingConditionsProperty, previousValue ); - } - - #endregion CellDisplayEditorMatchingConditions Property - - #region ShouldDisplayEditor Property - - private bool ShouldDisplayEditor - { - get - { - if( this.GetRealDataContext() is EmptyDataItem ) - return false; - - // If the cell is considered read-only, the EditTemplate should never be displayed. - if( this.GetInheritedReadOnly() ) - return false; - - // If the cell currently has a restrictive error, the EditTemplate should always be displayed. - if( Cell.GetIsValidationErrorRestrictive( this.ValidationError ) ) - return true; - - CellEditor cellEditor = this.GetCellEditor(); - - // If no cell editor is retrieved, we don't even have an edit template to display. - if( cellEditor == null ) - return false; - - //Retrieve the matching display conditions from both the Row and the Cell - CellEditorDisplayConditions rowValue = ( CellEditorDisplayConditions )this.GetValue( Cell.RowDisplayEditorMatchingConditionsProperty ); - CellEditorDisplayConditions cellValue = ( CellEditorDisplayConditions )this.GetValue( Cell.CellDisplayEditorMatchingConditionsProperty ); - - //If there is at least one "matching conditions" - if( ( rowValue | cellValue ) != CellEditorDisplayConditions.None ) - return true; - - CellEditorDisplayConditions cellEditorDisplayConditions = this.CellEditorDisplayConditions; - - // We always want to display the editor if it is set on the ParentColumn.CellEditorDisplayConditions are Always - if( ( cellEditorDisplayConditions & CellEditorDisplayConditions.Always ) == CellEditorDisplayConditions.Always ) - return true; - - Row parentRow = this.ParentRow; - - if( parentRow == null ) - return false; - - // this.CellEditorDisplayConditions will get the value set on ParentColumn if any in case it was explicitly set - if( parentRow.IsMouseOver && ( ( cellEditorDisplayConditions & CellEditorDisplayConditions.MouseOverRow ) == CellEditorDisplayConditions.MouseOverRow ) ) - return true; - - if( parentRow.IsBeingEdited && ( ( cellEditorDisplayConditions & CellEditorDisplayConditions.RowIsBeingEdited ) == CellEditorDisplayConditions.RowIsBeingEdited ) ) - return true; - - if( parentRow.IsCurrent && ( ( cellEditorDisplayConditions & CellEditorDisplayConditions.RowIsCurrent ) == CellEditorDisplayConditions.RowIsCurrent ) ) - return true; - - // If the cell is being edited, the edit template should be displayed. - return this.IsBeingEdited; - } - } - - #endregion - - #region CellEditorDisplayConditions Property - - internal CellEditorDisplayConditions CellEditorDisplayConditions - { - get - { - - //Read the Value of the Parent column - object propertyValue = DependencyProperty.UnsetValue; - ColumnBase parentColumn = this.ParentColumn; - - if( parentColumn != null ) - { - propertyValue = parentColumn.ReadLocalValue( DataGridControl.CellEditorDisplayConditionsProperty ); - - // In case we have a BindingExpression, we need to get the resulting value. - if( propertyValue is BindingExpressionBase ) - propertyValue = parentColumn.CellEditorDisplayConditions; - } - - //If the ParentColumn has no value defined for the CellEditorDisplayConditions DP, - if( propertyValue == DependencyProperty.UnsetValue ) - { - //Then interrogate the ParentRow - propertyValue = this.GetValue( DataGridControl.CellEditorDisplayConditionsProperty ); - } - - return ( CellEditorDisplayConditions )propertyValue; - } - } - - #endregion - - #region ParentCell Property - - private static readonly DependencyPropertyKey ParentCellPropertyKey = DependencyProperty.RegisterAttachedReadOnly( - "ParentCell", - typeof( Cell ), - typeof( Cell ), - new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.Inherits ) ); - - public static readonly DependencyProperty ParentCellProperty; - - private void SetParentCell() - { - this.SetValue( Cell.ParentCellPropertyKey, this ); - } - - #endregion ParentCell Property - - #region ParentColumn Read-Only Property - - private static readonly DependencyPropertyKey ParentColumnPropertyKey = DependencyProperty.RegisterReadOnly( - "ParentColumn", - typeof( ColumnBase ), - typeof( Cell ), - new PropertyMetadata( null, new PropertyChangedCallback( Cell.OnParentColumnChanged ) ) ); - - public static readonly DependencyProperty ParentColumnProperty; - - public ColumnBase ParentColumn - { - get - { - return ( ColumnBase )this.GetValue( Cell.ParentColumnProperty ); - } - private set - { - this.SetValue( Cell.ParentColumnPropertyKey, value ); - } - } - - internal virtual void OnParentColumnChanged( ColumnBase oldColumn, ColumnBase newColumn ) - { - if( oldColumn != null ) - { - PropertyChangedEventManager.RemoveListener( oldColumn, this, string.Empty ); - } - - if( newColumn != null ) - { - PropertyChangedEventManager.AddListener( newColumn, this, string.Empty ); - } - - this.UpdateFocusable(); - } - - private static void OnParentColumnChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var self = sender as Cell; - if( self == null ) - return; - - self.OnParentColumnChanged( ( ColumnBase )e.OldValue, ( ColumnBase )e.NewValue ); - - // Since Cell.FieldName in fact returns Cell.ParentColumn.FieldName, a PropertyChanged corresponding to FieldName must be raised when the ParentColumn has changed. - self.OnPropertyChanged( Cell.FieldNamePropertyName ); - } - - #endregion - - #region ParentRow Read-Only Property - - private static readonly DependencyPropertyKey ParentRowPropertyKey = DependencyProperty.RegisterReadOnly( - "ParentRow", - typeof( Row ), - typeof( Cell ), - new PropertyMetadata( null ) ); - - public static readonly DependencyProperty ParentRowProperty; - - public Row ParentRow - { - get - { - return ( Row )this.GetValue( Cell.ParentRowProperty ); - } - private set - { - this.SetValue( Cell.ParentRowPropertyKey, value ); - } - } - - #endregion - - #region FieldName Property - - public string FieldName - { - get - { - ColumnBase parentColumn = this.ParentColumn; - - if( parentColumn != null ) - return parentColumn.FieldName; - - return m_fieldName; - } - set - { - ColumnBase parentColumn = this.ParentColumn; - - if( parentColumn != null ) - throw new InvalidOperationException( "An attempt was made to change the FieldName of a cell already associated with a column." ); - - m_fieldName = value; - this.OnPropertyChanged( Cell.FieldNamePropertyName ); - } - } - - private void SetFieldName( string fieldName ) - { - m_fieldName = fieldName; - } - - #endregion FieldName Property - - #region CoercedContentTemplate Property - - private static readonly DependencyPropertyKey CoercedContentTemplatePropertyKey = DependencyProperty.RegisterReadOnly( - "CoercedContentTemplate", - typeof( DataTemplate ), - typeof( Cell ), - new FrameworkPropertyMetadata( null ) ); - - public static readonly DependencyProperty CoercedContentTemplateProperty; - - public DataTemplate CoercedContentTemplate - { - get - { - return ( DataTemplate )this.GetValue( Cell.CoercedContentTemplateProperty ); - } - } - - private void SetCoercedContentTemplate( DataTemplate viewerTemplate, DataTemplate editorTemplate ) - { - var contentTemplate = this.CoercedContentTemplate; - var editorDataTemplate = contentTemplate as EditorDataTemplate; - - if( editorDataTemplate != null ) - { - if( ( editorDataTemplate.Viewer == viewerTemplate ) && ( editorDataTemplate.Editor == editorTemplate ) ) - return; - } - else if( editorTemplate == null ) - { - if( contentTemplate == viewerTemplate ) - return; - } - - var newContentTemplate = ( editorTemplate != null ) - ? EditorDataTemplate.Create( viewerTemplate, editorTemplate ) - : viewerTemplate; - - this.SetValue( Cell.CoercedContentTemplatePropertyKey, newContentTemplate ); - } - - private void UpdateCoercedContentTemplate( bool force ) - { - if( force || this.IsContainerPrepared ) - { - this.SetCoercedContentTemplate( this.GetCoercedCellContentTemplate(), null ); - } - } - - #endregion - - #region ContentTemplateInternal Property (private) - - private DataTemplate ContentTemplateInternal - { - get - { - if( m_contentTemplateCache == Cell.NotInitializedDataTemplate ) - { - m_contentTemplateCache = this.GetValue( Cell.ContentTemplateProperty ) as DataTemplate; - } - return m_contentTemplateCache; - } - } - - private static readonly DataTemplate NotInitializedDataTemplate = new DataTemplate(); - - private DataTemplate m_contentTemplateCache = Cell.NotInitializedDataTemplate; - - #endregion - - #region ContentTemplateSelectorInternal Property (private) - - private DataTemplateSelector ContentTemplateSelectorInternal - { - get - { - if( m_contentTemplateSelectorCache == NotInitializedSelector ) - { - m_contentTemplateSelectorCache = this.GetValue( Cell.ContentTemplateSelectorProperty ) as DataTemplateSelector; - } - return m_contentTemplateSelectorCache; - } - } - - private static readonly DataTemplateSelector NotInitializedSelector = new DataTemplateSelector(); - - private DataTemplateSelector m_contentTemplateSelectorCache = Cell.NotInitializedSelector; - - #endregion - - #region OverrideColumnCellContentTemplate Property (protected virtual) - - protected virtual bool OverrideColumnCellContentTemplate - { - get - { - return true; - } - } - - #endregion - - #region CellEditorContext Attached Property - - private static readonly DependencyPropertyKey CellEditorContextPropertyKey = DependencyProperty.RegisterAttachedReadOnly( - "CellEditorContext", typeof( CellEditorContext ), typeof( Cell ), - new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.Inherits ) ); - - public static readonly DependencyProperty CellEditorContextProperty; - - public static CellEditorContext GetCellEditorContext( DependencyObject obj ) - { - return ( CellEditorContext )obj.GetValue( Cell.CellEditorContextProperty ); - } - - private static void SetCellEditorContext( DependencyObject obj, CellEditorContext value ) - { - obj.SetValue( Cell.CellEditorContextPropertyKey, value ); - } - - internal static void ClearCellEditorContext( DependencyObject obj ) - { - obj.ClearValue( Cell.CellEditorContextPropertyKey ); - } - - #endregion - - #region ParentColumnIsBeingDragged Private Property - - private static readonly DependencyProperty ParentColumnIsBeingDraggedProperty = DependencyProperty.Register( - "ParentColumnIsBeingDragged", - typeof( bool ), - typeof( Cell ), - new FrameworkPropertyMetadata( - ( bool )false, - new PropertyChangedCallback( Cell.OnParentColumnIsBeingDraggedChanged ), - new CoerceValueCallback( Cell.OnCoerceParentColumnIsBeingDragged ) ) ); - - private bool ParentColumnIsBeingDragged - { - get - { - return ( bool )this.GetValue( Cell.ParentColumnIsBeingDraggedProperty ); - } - set - { - this.SetValue( Cell.ParentColumnIsBeingDraggedProperty, value ); - } - } - - private static void OnParentColumnIsBeingDraggedChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var self = ( Cell )sender; - Debug.Assert( self != null ); - - var row = self.ParentRow; - if( row == null ) - return; - - var fixedCellPanel = row.CellsHostPanel as FixedCellPanel; - if( fixedCellPanel == null ) - return; - - if( ( bool )e.NewValue ) - { - fixedCellPanel.ChangeCellZOrder( self, fixedCellPanel.Children.Count ); - } - else - { - fixedCellPanel.ClearCellZOrder( self ); - } - } - - private static object OnCoerceParentColumnIsBeingDragged( DependencyObject sender, object newValue ) - { - var self = ( Cell )sender; - Debug.Assert( self != null ); - - var parentColumn = self.ParentColumn; - if( parentColumn == null ) - return newValue; - - var manager = TableflowView.GetColumnReorderingDragSourceManager( parentColumn ); - if( manager == null ) - return newValue; - - if( ( bool )newValue ) - { - self.AddDraggedColumnGhost( manager, true ); - } - else - { - self.RemoveDraggedColumnGhost( manager ); - } - - return newValue; - } - - #endregion - - #region ParentColumnReorderingDragSourceManager Property - - internal static readonly DependencyProperty ParentColumnReorderingDragSourceManagerProperty = DependencyProperty.Register( - "ParentColumnReorderingDragSourceManager", - typeof( ColumnReorderingDragSourceManager ), - typeof( Cell ), - new FrameworkPropertyMetadata( null, new PropertyChangedCallback( Cell.OnParentColumnReorderingDragSourceManagerChanged ) ) ); - - internal ColumnReorderingDragSourceManager ParentColumnReorderingDragSourceManager - { - get - { - return ( ColumnReorderingDragSourceManager )this.GetValue( Cell.ParentColumnReorderingDragSourceManagerProperty ); - } - set - { - this.SetValue( Cell.ParentColumnReorderingDragSourceManagerProperty, value ); - } - } - - private static void OnParentColumnReorderingDragSourceManagerChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var self = sender as Cell; - Debug.Assert( self != null ); - - var oldManager = ( ColumnReorderingDragSourceManager )e.OldValue; - var newManager = ( ColumnReorderingDragSourceManager )e.NewValue; - - if( ( oldManager != null ) && ( newManager != null ) ) - { - self.RemoveDraggedColumnGhost( oldManager ); - self.AddDraggedColumnGhost( newManager, self.ParentColumnIsBeingDragged ); - } - } - - #endregion - - #region SelectionBackground Property - - public static readonly DependencyProperty SelectionBackgroundProperty = DependencyProperty.Register( - "SelectionBackground", - typeof( Brush ), - typeof( Cell ), - new FrameworkPropertyMetadata( null ) ); - - public Brush SelectionBackground - { - get - { - return ( Brush )this.GetValue( Cell.SelectionBackgroundProperty ); - } - set - { - this.SetValue( Cell.SelectionBackgroundProperty, value ); - } - } - - #endregion SelectionBackground Property - - #region SelectionForeground Property - - public static readonly DependencyProperty SelectionForegroundProperty = DependencyProperty.Register( - "SelectionForeground", - typeof( Brush ), - typeof( Cell ), - new FrameworkPropertyMetadata( null ) ); - - public Brush SelectionForeground - { - get - { - return ( Brush )this.GetValue( Cell.SelectionForegroundProperty ); - } - set - { - this.SetValue( Cell.SelectionForegroundProperty, value ); - } - } - - #endregion SelectionForeground Property - - #region InactiveSelectionBackground Property - - public static readonly DependencyProperty InactiveSelectionBackgroundProperty = DependencyProperty.Register( - "InactiveSelectionBackground", - typeof( Brush ), - typeof( Cell ), - new FrameworkPropertyMetadata( null ) ); - - public Brush InactiveSelectionBackground - { - get - { - return ( Brush )this.GetValue( Cell.InactiveSelectionBackgroundProperty ); - } - set - { - this.SetValue( Cell.InactiveSelectionBackgroundProperty, value ); - } - } - - #endregion InactiveSelectionBackground Property - - #region InactiveSelectionForeground Property - - public static readonly DependencyProperty InactiveSelectionForegroundProperty = DependencyProperty.Register( - "InactiveSelectionForeground", - typeof( Brush ), - typeof( Cell ), - new FrameworkPropertyMetadata( null ) ); - - public Brush InactiveSelectionForeground - { - get - { - return ( Brush )this.GetValue( Cell.InactiveSelectionForegroundProperty ); - } - set - { - this.SetValue( Cell.InactiveSelectionForegroundProperty, value ); - } - } - - #endregion InactiveSelectionForeground Property - - #region ParentForeground Property - - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - public static readonly DependencyProperty ParentForegroundProperty = DependencyProperty.Register( - "ParentForeground", - typeof( Brush ), - typeof( Cell ), - new FrameworkPropertyMetadata( TextElement.ForegroundProperty.DefaultMetadata.DefaultValue ) ); - - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - public Brush ParentForeground - { - get - { - return ( Brush )this.GetValue( Cell.ParentForegroundProperty ); - } - set - { - this.SetValue( Cell.ParentForegroundProperty, value ); - } - } - - private void UpdateParentForeground() - { - // Use the visual parent when there is no logical parent. - var parent = LogicalTreeHelper.GetParent( this ) ?? VisualTreeHelper.GetParent( this ); - - if( parent != null ) - { - var binding = new Binding(); - binding.Path = new PropertyPath( TextElement.ForegroundProperty ); - binding.Source = parent; - - this.SetBinding( Cell.ParentForegroundProperty, binding ); - } - else - { - this.ClearValue( Cell.ParentForegroundProperty ); - } - } - - #endregion ParentForeground Property - - #region IsInternalyInitialized Property - - internal bool IsInternalyInitialized - { - get - { - return m_flags[ ( int )CellFlags.IsInternalyInitialized ]; - } - private set - { - m_flags[ ( int )CellFlags.IsInternalyInitialized ] = value; - } - } - - #endregion - - #region IsContainerPrepared Property - - internal bool IsContainerPrepared - { - get - { - return m_flags[ ( int )CellFlags.IsContainerPrepared ]; - } - private set - { - m_flags[ ( int )CellFlags.IsContainerPrepared ] = value; - } - } - - #endregion - - #region IsContainerVirtualized Property - - internal bool IsContainerVirtualized - { - get - { - return m_flags[ ( int )CellFlags.IsContainerVirtualized ]; - } - private set - { - m_flags[ ( int )CellFlags.IsContainerVirtualized ] = value; - } - } - - #endregion - - #region IsContainerRecycled Property - - internal bool IsContainerRecycled - { - get - { - return m_flags[ ( int )CellFlags.IsContainerRecycled ]; - } - private set - { - m_flags[ ( int )CellFlags.IsContainerRecycled ] = value; - } - } - - #endregion - - #region IsContainerPartiallyCleared Property - - internal bool IsContainerPartiallyCleared - { - get - { - return m_flags[ ( int )CellFlags.IsContainerPartiallyCleared ]; - } - private set - { - m_flags[ ( int )CellFlags.IsContainerPartiallyCleared ] = value; - } - } - - #endregion - - #region CanBeRecycled Property - - protected internal virtual bool CanBeRecycled - { - get - { - if( !this.IsErrorStyleApplied ) - { - // We should not recycle the cell if the user has set a style or template explicitly. - if( Cell.IsValueSourceHazardingCellRecycling( DependencyPropertyHelper.GetValueSource( this, Cell.StyleProperty ) ) - || Cell.IsValueSourceHazardingCellRecycling( DependencyPropertyHelper.GetValueSource( this, Cell.TemplateProperty ) ) ) - return false; - } - else if( m_styleBeforeError != DependencyProperty.UnsetValue ) - { - // The regular style has been set by the user. - return false; - } - - return true; - } - } - - #endregion - - #region CanBeCollapsed Property - - internal virtual bool CanBeCollapsed - { - get - { - if( this.IsCurrent || this.IsDirty || this.HasValidationError || this.IsBeingEdited || this.IsKeyboardFocused || this.IsKeyboardFocusWithin ) - return false; - - var parentColumn = this.ParentColumn; - if( parentColumn == null ) - return true; - - return !TableflowView.GetIsBeingDraggedAnimated( parentColumn ); - } - } - - #endregion - - #region FocusEditor Property - - private bool FocusEditor - { - get - { - return m_flags[ ( int )CellFlags.FocusEditor ]; - } - set - { - m_flags[ ( int )CellFlags.FocusEditor ] = value; - } - } - - #endregion - - #region PreventValidateAndSetAllErrors Property - - private bool PreventValidateAndSetAllErrors - { - get - { - return m_flags[ ( int )CellFlags.PreventValidateAndSetAllErrors ]; - } - set - { - m_flags[ ( int )CellFlags.PreventValidateAndSetAllErrors ] = value; - } - } - - #endregion - - #region IsBeingEditedCache Property - - private bool IsBeingEditedCache - { - get - { - return m_flags[ ( int )CellFlags.IsBeingEdited ]; - } - set - { - m_flags[ ( int )CellFlags.IsBeingEdited ] = value; - } - } - - #endregion - - #region HasCellEditorError Property - - internal bool HasCellEditorError - { - get - { - return m_flags[ ( int )CellFlags.HasCellEditorError ]; - } - set - { - m_flags[ ( int )CellFlags.HasCellEditorError ] = value; - } - } - - #endregion - - #region HasUIValidationError Property - - private bool HasUIValidationError - { - get - { - return m_flags[ ( int )CellFlags.HasUIValidationError ]; - } - set - { - m_flags[ ( int )CellFlags.HasUIValidationError ] = value; - } - } - - #endregion - - #region HasContentBindingValidationError Property - - private bool HasContentBindingValidationError - { - get - { - return m_flags[ ( int )CellFlags.HasContentBindingValidationError ]; - } - set - { - m_flags[ ( int )CellFlags.HasContentBindingValidationError ] = value; - } - } - - #endregion - - #region HasPendingErrorStyleRefresh Property - - private bool HasPendingErrorStyleRefresh - { - get - { - return m_flags[ ( int )CellFlags.HasPendingErrorStyleRefresh ]; - } - set - { - m_flags[ ( int )CellFlags.HasPendingErrorStyleRefresh ] = value; - } - } - - #endregion - - #region IsErrorStyleApplied Property - - private bool IsErrorStyleApplied - { - get - { - return m_flags[ ( int )CellFlags.IsErrorStyleApplied ]; - } - set - { - m_flags[ ( int )CellFlags.IsErrorStyleApplied ] = value; - } - } - - #endregion - - #region IsUpdatingContentBindingSource Property - - private bool IsUpdatingContentBindingSource - { - get - { - return m_flags[ ( int )CellFlags.IsUpdatingContentBindingSource ]; - } - set - { - m_flags[ ( int )CellFlags.IsUpdatingContentBindingSource ] = value; - } - } - - #endregion - - #region IsInCascadingValidation Property - - private bool IsInCascadingValidation - { - get - { - return m_flags[ ( int )CellFlags.IsInCascadingValidation ]; - } - set - { - m_flags[ ( int )CellFlags.IsInCascadingValidation ] = value; - } - } - - #endregion - - #region HasPendingSyncParentErrorFlags Property - - private bool HasPendingSyncParentErrorFlags - { - get - { - return m_flags[ ( int )CellFlags.HasPendingSyncParentErrorFlags ]; - } - set - { - m_flags[ ( int )CellFlags.HasPendingSyncParentErrorFlags ] = value; - } - } - - #endregion - - #region IsRestoringEditionState Property - - private bool IsRestoringEditionState - { - get - { - return m_flags[ ( int )CellFlags.IsRestoringEditionState ]; - } - set - { - m_flags[ ( int )CellFlags.IsRestoringEditionState ] = value; - } - } - - #endregion - - #region AnimatedColumnReorderingBindingApplied Property - - private bool AnimatedColumnReorderingBindingApplied - { - get - { - return m_flags[ ( int )CellFlags.AnimatedColumnReorderingBindingApplied ]; - } - set - { - m_flags[ ( int )CellFlags.AnimatedColumnReorderingBindingApplied ] = value; - } - } - - #endregion - - #region PreventMakeVisible Property - - private bool PreventMakeVisible - { - get - { - return m_flags[ ( int )CellFlags.PreventMakeVisible ]; - } - set - { - m_flags[ ( int )CellFlags.PreventMakeVisible ] = value; - } - } - - #endregion - - #region ResetNonTransientFlags Property - - private void ResetNonTransientFlags() - { - m_flags = new BitVector32( m_flags.Data & ( int )( CellFlags.IsInternalyInitialized ) ); - - if( !this.HasPendingErrorStyleRefresh ) - { - this.AbortRefreshErrorStyle(); - } - } - - #endregion - - #region HasAliveContentBinding - - protected internal virtual bool HasAliveContentBinding - { - get - { - return true; - } - } - - #endregion - - public static Cell FindFromChild( DependencyObject child ) - { - return Cell.FindFromChild( ( DataGridContext )null, child ); - } - - public static Cell FindFromChild( DataGridContext dataGridContext, DependencyObject child ) - { - // In this situation, the dataGridContext is the DataGridContext of the Cell to find. - // Useful when a grid is used as a Cell editor and want the Cell for a specific DataGridContext. - if( child == null ) - return null; - - Cell cell = null; - - while( ( cell == null ) && ( child != null ) ) - { - child = TreeHelper.GetParent( child ); - cell = child as Cell; - - if( ( cell != null ) - && ( dataGridContext != null ) - && ( dataGridContext != DataGridControl.GetDataGridContext( cell ) ) ) - { - cell = null; - } - } - - return cell; - } - - public static Cell FindFromChild( DataGridControl dataGridControl, DependencyObject child ) - { - // In this situation, the dataGridControl is the DataGridControl of the Cell to find. - // Useful when a grid is used as a Cell editor and want the Cell for a specific DataGridControl. - if( child == null ) - return null; - - Cell cell = null; - - while( ( cell == null ) && ( child != null ) ) - { - child = TreeHelper.GetParent( child ); - cell = child as Cell; - - if( ( cell != null ) && ( dataGridControl != null ) ) - { - DataGridContext tempDataGridContext = DataGridControl.GetDataGridContext( cell ); - - if( ( tempDataGridContext == null ) || ( tempDataGridContext.DataGridControl != dataGridControl ) ) - { - cell = null; - } - } - } - - return cell; - } - - public override void OnApplyTemplate() - { - base.OnApplyTemplate(); - - if( m_cellContentPresenter != null ) - { - BindingOperations.ClearBinding( m_cellContentPresenter, UIElement.OpacityProperty ); - } - - m_cellContentPresenter = this.GetTemplateChild( "PART_CellContentPresenter" ) as ContentPresenter; - - if( m_cellContentPresenter != null ) - { - BindingOperations.SetBinding( m_cellContentPresenter, UIElement.OpacityProperty, Cell.ParentRowCellContentOpacityBinding ); - } - } - - public override string ToString() - { - string fieldName = this.FieldName; - object content = this.Content; - string cellType = string.Empty; - - Type type = this.GetType(); - - if( type != null ) - cellType = type.ToString(); - - try - { - return String.Format( "{0} : FieldName = {1}, Content = {2}", cellType, ( fieldName != null ) ? fieldName : "", ( content != null ) ? content.ToString() : "null" ); - } - catch( Exception ) - { - return base.ToString(); - } - } - - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate" )] - public double GetFittedWidth() - { - if( !this.IsContainerPrepared || this.IsContainerVirtualized ) - return -1d; - - this.ApplyTemplate(); - - var child = ( this.VisualChildrenCount > 0 ) ? this.GetVisualChild( 0 ) as UIElement : null; - if( child == null ) - return -1d; - - child.Measure( new Size( double.PositiveInfinity, this.ActualHeight ) ); - - return child.DesiredSize.Width; - } - - protected override void OnMouseLeftButtonDown( MouseButtonEventArgs e ) - { - base.OnMouseLeftButtonDown( e ); - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - if( dataGridContext == null ) - return; - - dataGridContext.DataGridControl.ResetDragDataObject(); - - if( e.Handled ) - return; - - Row parentRow = this.ParentRow; - ColumnBase parentColumn = this.ParentColumn; - - if( ( parentRow != null ) && ( parentColumn != null ) - && ( parentRow.NavigationBehavior != NavigationBehavior.None ) - && ( parentRow.NavigationBehavior != NavigationBehavior.RowOnly ) ) - { - bool wasAlreadyCurrent = this.IsCurrent; - - if( !this.GetCalculatedCanBeCurrent() ) - { - if( ( this.ParentRow == dataGridContext.CurrentRow ) && ( this.ParentRow.NavigationBehavior == NavigationBehavior.RowOrCell ) ) - { - try - { - dataGridContext.SetCurrentColumnCore( null, true, false, AutoScrollCurrentItemSourceTriggers.Navigation ); - } - catch( DataGridException ) - { - // We swallow the exception if it occurs because of a validation error or Cell was read-only or - // any other GridException. - } - } - - return; - } - - bool focused = this.Focus(); - e.Handled = true; - - if( !focused ) - return; - - // Keep a reference to the mouse position so we can calculate when a drag operation is actually started. - dataGridContext.DataGridControl.InitializeDragPostion( e ); - - //only process the SingleClick and ClickOnCurrentCell edit triggers if the CTRL or the SHIFT key is not pressed. - if( ( ( Keyboard.Modifiers & ModifierKeys.Control ) != ModifierKeys.Control ) - && ( ( Keyboard.Modifiers & ModifierKeys.Shift ) != ModifierKeys.Shift ) ) - { - bool readOnly = this.GetInheritedReadOnly(); - - if( readOnly ) - return; - - //If grid is configured for SingleClickEdit, set edition status - if( ( parentRow.IsEditTriggerSet( EditTriggers.SingleClick ) ) - || ( ( wasAlreadyCurrent ) && ( parentRow.IsEditTriggerSet( EditTriggers.ClickOnCurrentCell ) ) ) ) - { - try - { - this.BeginEdit(); - } - catch( DataGridException ) - { - // We swallow the exception if it occurs because of a validation error or Cell was read-only or - // any other GridException. - } - } - } - } - } - - protected override void OnPreviewTextInput( TextCompositionEventArgs e ) - { - base.OnPreviewTextInput( e ); - - if( e.Handled ) - return; - - var parentRow = this.ParentRow; - if( parentRow == null ) - return; - - //Do not try to process the Activation Gesture if the Cell is readonly! - var readOnly = this.GetInheritedReadOnly(); - if( readOnly ) - return; - - //This condition ensures that we process the TextInput against the editor only if the Grid is configured to answer to activation gestures. - if( !( parentRow.IsEditTriggerSet( EditTriggers.ActivationGesture ) ) ) - return; - - var editor = this.GetCellEditor(); - - //This condition is more complex and is used to filter cases were a TextInput is done and there is no need to process for activation keys... - //Condition is: Editor is not null, editor is not displaued and editor is not pending showing. - if( ( editor != null ) && ( this.IsBeingEdited == false ) && ( this.CurrentEditorPendingDisplayState != EditorDisplayState.PendingShow ) ) - { - - //If the Activation gestures for the editor includes TextInput - //Note that this condition also filters out TextInput which are other than Regular (non system or control) TextInput - if( ( !string.IsNullOrEmpty( e.Text ) ) && ( string.IsNullOrEmpty( e.SystemText ) ) && ( string.IsNullOrEmpty( e.ControlText ) ) - && ( editor.IsTextInputActivation() ) ) - { - m_textInputArgs = e; - e.Handled = true; - - try - { - //enter edit mode for cell - this.BeginEdit(); - } - catch( DataGridException ) - { - // We swallow the exception if it occurs because of a validation error or Cell was read-only or - // any other GridException. - } - } - } - } - - protected override void OnPreviewKeyDown( KeyEventArgs e ) - { - base.OnPreviewKeyDown( e ); - - if( e.Handled ) - return; - - Row parentRow = this.ParentRow; - - if( parentRow == null ) - return; - - //This condition ensures that we process the KeyDown against the editor only if the Grid is configured to answer to activation gestures. - if( !( parentRow.IsEditTriggerSet( EditTriggers.ActivationGesture ) ) ) - return; - - CellEditor editor = this.GetCellEditor(); - - //This condition is more complex and is used to filter cases were a KeyDown is done and there is no need to process for activation keys... - //Condition is: Editor is not null, editor is not displaued and editor is not pending showing. - - if( ( editor != null ) && ( !this.IsBeingEdited ) && ( this.CurrentEditorPendingDisplayState != EditorDisplayState.PendingShow ) ) - { - KeyActivationGesture gesture = editor.GetMatchingKeyActivationGesture( e.Key, e.SystemKey, Keyboard.Modifiers ); - - //Check if the key stroke received corresponds to one matching one of the KeyActivationGesture of the editor - if( gesture == null ) - return; - - //preserve the keystroke so it can be "resent" to the editor once layout is updated. - m_keyGesture = gesture; - - e.Handled = true; - - try - { - //If the key match, then enter edit mode. - this.BeginEdit(); - } - catch( DataGridException ) - { - // We swallow the exception if it occurs because of a validation error or Cell was read-only or - // any other GridException. - } - } - } - - protected override void OnVisualParentChanged( DependencyObject oldParent ) - { - base.OnVisualParentChanged( oldParent ); - - // Since the parent property isn't a DP, we must update the binding ourself. - this.UpdateParentForeground(); - } - - - protected override void OnPropertyChanged( DependencyPropertyChangedEventArgs e ) - { - base.OnPropertyChanged( e ); - this.OnPropertyChanged( e.Property.Name ); - } - - protected virtual void InitializeCore( DataGridContext dataGridContext, Row parentRow, ColumnBase parentColumn ) - { - this.ParentRow = parentRow; - this.ParentColumn = parentColumn; - - this.UpdateAnimatedColumnReorderingBindings( dataGridContext, Row.GetIsTemplateCell( this ) ); - - if( !this.IsInternalyInitialized ) - { - Binding rowMatchingConditionsBinding = new Binding(); - rowMatchingConditionsBinding.Path = new PropertyPath( "(0).(1)", Cell.ParentRowProperty, Row.RowDisplayEditorMatchingConditionsProperty ); - rowMatchingConditionsBinding.Source = this; - rowMatchingConditionsBinding.Mode = BindingMode.OneWay; - - //Initialize the RowDisplayEditorMatchingConditions binding to the ParentRow - BindingOperations.SetBinding( this, Cell.RowDisplayEditorMatchingConditionsProperty, rowMatchingConditionsBinding ); - - // Clear the FieldName since it will be taken from the column instead of directly from the Cell. - this.SetFieldName( string.Empty ); - } - } - - protected virtual CellEditor GetCellEditor() - { - if( !this.IsInternalyInitialized ) - return null; - - var parentColumnBase = this.ParentColumn; - - if( parentColumnBase == null ) - return null; - - //Since the CellEditor property is set by default, first verify if the CelLEditorSelector property has been explicitly set. - if( parentColumnBase.CellEditorSelector != null ) - return parentColumnBase.CellEditorSelector.SelectCellEditor( parentColumnBase, this.DataContext ); - - if( parentColumnBase.CellEditor != null ) - return parentColumnBase.CellEditor; - - var parentColumn = parentColumnBase as Column; - - if( parentColumn != null ) - { - // Try to get a CellEditor from the ParentColumn.ForeignKeyConfiguration - var foreignKeyConfiguration = parentColumn.ForeignKeyConfiguration; - - if( foreignKeyConfiguration != null ) - { - return foreignKeyConfiguration.DefaultCellEditor; - } - } - - var content = this.Content; - - if( content == null ) - return null; - - var contentType = content.GetType(); - - var cellEditor = DefaultCellEditorSelector.SelectCellEditor( contentType ); - - if( cellEditor != null ) - return cellEditor; - - var typeConverter = TypeDescriptor.GetConverter( contentType ); - - if( typeConverter == null ) - return null; - - if( typeConverter.CanConvertFrom( typeof( string ) ) && typeConverter.CanConvertTo( typeof( string ) ) ) - { - return DefaultCellEditorSelector.TextBoxEditor; - } - - return null; - } - - protected internal void Initialize( DataGridContext dataGridContext, Row parentRow, ColumnBase parentColumn ) - { - //Check that both parameters are valid. - if( parentRow == null ) - throw new ArgumentNullException( "parentRow" ); - - if( parentColumn == null ) - throw new ArgumentNullException( "parentColumn" ); - - if( ( this.IsInternalyInitialized ) - && ( this.IsContainerPrepared ) - && ( parentColumn == this.ParentColumn ) - && ( parentRow == this.ParentRow ) ) - return; - - //Mark the cell has being recycled to prevent some check to occur. - this.IsContainerRecycled = this.IsInternalyInitialized; - - try - { - //A cell that hasn't been prepare once or that has a new parent column - //due to recycling needs to be prepared again. - this.IsContainerPrepared = false; - - this.InitializeCore( dataGridContext, parentRow, parentColumn ); - - this.IsInternalyInitialized = true; - - this.PostInitialize(); - } - finally - { - //From here, there is no difference between a fresh new cell and - //a recycled cell. - this.IsContainerRecycled = false; - } - } - - protected internal virtual void PostInitialize() - { - if( this.ParentRow.IsBeingEdited ) - { - // Cell was added to the row's CreatedCells. Update the parentColumn's cell in edition state. - var parentColumn = this.ParentColumn; - - if( ( parentColumn != null ) && ( parentColumn.CurrentRowInEditionCellState == null ) ) - { - CellState cellState = new CellState(); - cellState.SetContentBeforeRowEdition( this.Content ); - parentColumn.CurrentRowInEditionCellState = cellState; - } - } - } - - protected internal virtual void PrepareContainer( DataGridContext dataGridContext, object item ) - { - this.IsContainerPartiallyCleared = false; - - // If the container is already prepared and not virtualized and the DataContext is the same, just ignore this call. - // For example, a cell generated through the xaml parser can already be prepared (went through this method once) but - // still have its DataContext set only after it has been prepared, thus the need to excute this method once more. - var dataContext = this.DataContext; - if( this.IsContainerPrepared && !this.IsContainerVirtualized && - ( ( dataContext == item ) || ( ( dataContext is UnboundDataItem ) && this.IsSameUnboundItem( dataContext, item ) ) ) ) - return; - - //Make sure that the DataGridContext is set appropriatly on the cells that are already created. - //This is to ensure that the value is appropriate when the container is recycled within another DataGridContext ( another detail on the same level ). - DataGridControl.SetDataGridContext( this, dataGridContext ); - - var parentColumn = this.ParentColumn; - var isSameDataContext = Cell.AssignDataContext( this, item, null, parentColumn ); - - // In some scenarios, there may be validation errors on the content binding that is not reflected on the cell or the row, so make sure it is. - if( isSameDataContext && ( item is IDataErrorInfo ) && ( Validation.GetErrors( this ).Count > 0 ) && !this.HasValidationError - && !this.IsDirty) - { - this.NotifyContentBindingValidationError(); - } - - // If there is a current column on the DataGridContext, try to restore the currency of the cell - var parentRow = this.ParentRow; - var currentColumn = dataGridContext.CurrentColumn; - if( ( parentRow != null ) && ( parentRow.IsCurrent ) && ( currentColumn != null ) && ( currentColumn == parentColumn ) ) - { - this.SetIsCurrent( true ); - } - - // This will force invalidation of the CoercedContentTemplate, only if the content is null after the prepare - // and if the content template is set to something else than default. However, when binded to an EmptyDataItem, - // our content will always be null but a CellContentTemplate will be applied. In this case, we do NOT want to reapplied the template every time. - if( ( this.Content == null ) && ( !( this.GetRealDataContext() is EmptyDataItem ) ) ) - { - this.ClearValue( Cell.CoercedContentTemplatePropertyKey ); - } - - this.UpdateCoercedContentTemplate( true ); - this.UpdateMatchingDisplayConditions(); - - // Ensure to reset both container recycling flags - this.IsContainerPrepared = true; - this.IsContainerVirtualized = false; - - // Force a refresh of the displayed template in case the display conditions where initially matched (e.g. Always). - this.RefreshDisplayedTemplate(); - } - - protected internal virtual void ClearContainer() - { - // If the container is not prepared just ignore this call. - if( !this.IsContainerPrepared ) - return; - - this.IsContainerPrepared = false; - this.IsContainerPartiallyCleared = false; - - this.AbortRefreshErrorStyle(); - this.AbortHideEditTemplate(); - - if( m_loadedRoutedEventHandler != null ) - { - this.Loaded -= m_loadedRoutedEventHandler; - m_loadedRoutedEventHandler = null; - } - - // In DP's PropertyChanged Callbacks, for the sake of performance, you could return immediatly if the cell is in process of being cleared. - - this.ClearValue( Cell.StyleProperty ); - this.ClearValue( Cell.IsCurrentPropertyKey ); - this.ClearValue( Cell.IsSelectedPropertyKey ); - this.ClearValue( Cell.IsBeingEditedPropertyKey ); - this.ClearValue( Cell.ValidationErrorPropertyKey ); - this.ClearValue( Cell.HasValidationErrorPropertyKey ); - this.ClearValue( Cell.IsValidationErrorRestrictivePropertyKey ); - - // We must not clear the IsDirty flag of the Cell here since its Content could have been edited and this flag is checked - // to determine if the new value is commited or not in the source - - // No need to clear the Cell.CellDisplayEditorMatchingConditionsProperty neither DataGridControl.CellEditorDisplayConditionsProperty since - // both will be updated when Cell.PrepareContainer is called again - - m_cellValidationRules = null; - m_styleBeforeError = DependencyProperty.UnsetValue; - this.CurrentEditorPendingDisplayState = EditorDisplayState.None; - this.IsContainerVirtualized = true; - - this.SetIsCellEditorDisplayed( false ); - - // This will reset every flags maintained in m_flags - this.ResetNonTransientFlags(); - } - - protected internal virtual void PartialClearContainer() - { - // If the container is not prepared just ignore this call. - if( !this.IsContainerPrepared ) - return; - - this.IsContainerPartiallyCleared = true; - - this.AbortRefreshErrorStyle(); - this.AbortHideEditTemplate(); - - this.ClearValue( Cell.StyleProperty ); - this.ClearValue( Cell.IsCurrentPropertyKey ); - this.ClearValue( Cell.IsSelectedPropertyKey ); - this.ClearValue( Cell.IsBeingEditedPropertyKey ); - this.ClearValue( Cell.ValidationErrorPropertyKey ); - this.ClearValue( Cell.HasValidationErrorPropertyKey ); - this.ClearValue( Cell.IsValidationErrorRestrictivePropertyKey ); - - m_styleBeforeError = DependencyProperty.UnsetValue; - this.CurrentEditorPendingDisplayState = EditorDisplayState.None; - - this.SetIsCellEditorDisplayed( false ); - - // This will reset every flags maintained in m_flags - this.ResetNonTransientFlags(); - } - - protected internal virtual void PrepareDefaultStyleKey( Xceed.Wpf.DataGrid.Views.ViewBase view ) - { - var newThemeKey = view.GetDefaultStyleKey( typeof( Cell ) ); - if( object.Equals( this.DefaultStyleKey, newThemeKey ) ) - return; - - this.DefaultStyleKey = newThemeKey; - } - - protected internal virtual void AddContentBinding( DataGridContext dataGridContext, Row parentRow, ColumnBase parentColumn ) - { - } - - protected internal virtual void RemoveContentBinding() - { - } - - protected internal virtual void CleanUpOnRemove() - { - this.AbortRefreshErrorStyle(); - this.AbortHideEditTemplate(); - - if( m_loadedRoutedEventHandler != null ) - { - this.Loaded -= m_loadedRoutedEventHandler; - m_loadedRoutedEventHandler = null; - } - - //This is done so the WeakEventListener on ParentColumn is removed. - this.ParentColumn = null; - } - - internal static Cell FindFromChildOrSelf( DataGridControl dataGridControl, DependencyObject child ) - { - var cell = child as Cell; - if( cell != null ) - { - if( dataGridControl == null ) - return cell; - - var dataGridContext = DataGridControl.GetDataGridContext( cell ); - if( ( dataGridContext != null ) && ( dataGridContext.DataGridControl == dataGridControl ) ) - return cell; - } - - return Cell.FindFromChild( dataGridControl, child ); - } - - internal static bool GetIsUIValidationError( CellValidationError validationError ) - { - if( validationError == null ) - return false; - - return ( !Cell.GetIsContentBindingValidationError( validationError ) ) && ( !Cell.GetIsCellEditorError( validationError ) ); - } - - internal static bool GetIsCellEditorError( CellValidationError validationError ) - { - if( validationError == null ) - return false; - - return validationError.RuleInError is CellEditorValidationRule; - } - - internal static bool GetIsContentBindingValidationError( CellValidationError validationError ) - { - if( validationError == null ) - return false; - - return validationError.RuleInError is CellContentBindingValidationRule; - } - - internal static bool GetIsValidationErrorRestrictive( CellValidationError cellValidationError ) - { - if( cellValidationError == null ) - return false; - - return Cell.GetIsRuleInErrorRestrictive( cellValidationError.RuleInError ); - } - - internal static bool GetIsValidationErrorRestrictive( ValidationError validationError ) - { - if( validationError == null ) - return false; - - return Cell.GetIsRuleInErrorRestrictive( validationError.RuleInError ); - } - - internal static bool GetIsRuleInErrorRestrictive( CellValidationRule ruleInError ) - { - if( ruleInError == null ) - return false; - - CellContentBindingValidationRule cellContentBindingValidationRule = ruleInError as CellContentBindingValidationRule; - - if( cellContentBindingValidationRule != null ) - return Cell.GetIsRuleInErrorRestrictive( cellContentBindingValidationRule.ValidationRule ); - - return true; - } - - internal static bool GetIsRuleInErrorRestrictive( ValidationRule ruleInError ) - { - if( ruleInError == null ) - return false; - - return !( ruleInError is DataErrorValidationRule ); - } - - internal static bool IsCellEditorDisplayConditionsSet( Cell cell, CellEditorDisplayConditions condition ) - { - if( ( cell.CellEditorDisplayConditions & condition ) == condition ) - return true; - - return false; - } - - internal static UIElement GetCellFocusScope( UIElement reference ) - { - if( reference == null ) - return null; - - if( Cell.GetIsCellFocusScope( reference ) ) - { - return reference; - } - - UIElement cellFocusScope = null; - - for( int i = 0; i < VisualTreeHelper.GetChildrenCount( reference ); i++ ) - { - cellFocusScope = Cell.GetCellFocusScope( VisualTreeHelper.GetChild( reference, i ) as UIElement ); - - if( cellFocusScope != null ) - { - return cellFocusScope; - } - } - - return null; - } - - internal static bool IsValueSourceHazardingCellRecycling( ValueSource valueSource ) - { - switch( valueSource.BaseValueSource ) - { - case BaseValueSource.Local: - case BaseValueSource.ParentTemplate: - case BaseValueSource.ParentTemplateTrigger: - case BaseValueSource.Unknown: - return true; - - default: - return false; - } - } - - internal static bool AssignDataContext( Cell cell, object dataContext, UnboundDataItem unboundDataItemContext, ColumnBase parentColumn ) - { - var column = parentColumn as Column; - if( ( column != null ) && ( column.IsBoundToDataGridUnboundItemProperty ) ) - { - dataContext = unboundDataItemContext ?? UnboundDataItem.GetUnboundDataItem( dataContext ); - } - - // Read the LocalValue of the DataContext to avoid getting the one inherited from the ParentRow. - // This prevent the DataContext to become null when the Cell is virtualized. - object localDataContext = cell.ReadLocalValue( Cell.DataContextProperty ); - - if( localDataContext != dataContext ) - { - // The system will call Equals instead of RefEquals on the DataContext change. If Equals has been overriden and returns true, the DataContext will not be updated. - // Hence setting it to null will make sure the right DataContext is used by the cell, and thus the cell content will be correctly updated. - // This would not have to be done if a reference to the old DataItem was not keeped, which DataItem may not be part of the source anymore. - if( object.Equals( localDataContext, dataContext ) ) - { - cell.DataContext = null; - } - cell.DataContext = dataContext; - - return false; - } - - return true; - } - - //This ensures the CellEditorContext is set on the Cell to avoid problems with RelativeSource causing undesired behaviors when ComboBox is used as default CellEditor - internal void EnsureCellEditorContext() - { - ForeignKeyConfiguration configuration = null; - - var parentColumn = this.ParentColumn as Column; - - if( parentColumn != null ) - { - configuration = parentColumn.ForeignKeyConfiguration; - CellEditorContext context = new CellEditorContext( parentColumn, configuration ); - Cell.SetCellEditorContext( this, context ); - } - } - - internal void RefreshDisplayedTemplate() - { - // Never refresh any templates when the Cell is not prepared or virtualized - if( !this.IsContainerPrepared || this.IsContainerVirtualized ) - return; - - Row parentRow = this.ParentRow; - - // Never refresh template while clearing container - if( ( parentRow == null ) || parentRow.IsClearingContainer ) - return; - - if( this.ShouldDisplayEditor ) - { - this.EnsureCellEditorContext(); - this.ShowEditTemplate(); - } - else - { - this.DelayHideEditTemplate(); - } - } - - internal void RevertEditedValue() - { - CellState cellState = this.GetEditCachedState(); - - if( cellState != null ) - { - Debug.Assert( ( cellState.ContentBeforeRowEdition != DependencyProperty.UnsetValue ), "It seems the column was recreated or the cellstate overwritten while the row/cell was in edition." ); - - if( cellState.ContentBeforeRowEdition != DependencyProperty.UnsetValue ) - { - this.PreventValidateAndSetAllErrors = true; - try - { - if( ( this.GetInheritedReadOnly() ) || ( !this.GetIsContentBindingSupportingSourceUpdate() ) ) - { - this.UpdateContentBindingTarget(); - } - else - { - this.Content = cellState.ContentBeforeRowEdition; - } - } - finally - { - this.PreventValidateAndSetAllErrors = false; - } - - // Since it is impossible to leave edition on a row containing restrictive errors, there's no need to re-validate the UI Rules. - // The Validation.Error handler on the Content Binding will take care of updating the ValidationError property if it need to, - // which will in turn synch the HasValidationError property and refresh the Cell's style either to its normal style or - // to its error style. - Exception exception; - CellValidationRule ruleInErrorWrapper; - - // We always want to update the content binding source. - this.ClearAllErrors(); - this.ValidateAndSetAllErrors( false, false, true, true, out exception, out ruleInErrorWrapper ); - } - } - - this.SetIsDirty( false ); - } - - internal void UpdateContentBindingTarget() - { - // Never update the target of a binding to a an item if the Cell is dirty - if( ( !this.IsDirty ) ) - { - // We need to refresh the Cell.Content target binding in case the dataObject value was coerced to something else. - BindingExpressionBase bindingExpression = this.GetContentBindingExpression(); - - if( bindingExpression != null ) - { - bindingExpression.UpdateTarget(); - } - } - } - - internal void RestoreEditionState( ColumnBase currentColumn ) - { - Debug.Assert( ( this.ParentRow != null ) && ( this.ParentRow.IsBeingEdited ) && ( this.ParentColumn != null ) ); - - ColumnBase parentColumn = this.ParentColumn; - - if( parentColumn == null ) - return; - - CellState savedState = parentColumn.CurrentRowInEditionCellState; - - Debug.Assert( savedState != null ); - - if( savedState == null ) - return; - - bool wasDirty = savedState.IsDirty; - this.SetIsDirty( wasDirty ); - - if( wasDirty ) - { - if( ( savedState.Content != DependencyProperty.UnsetValue ) - && ( !object.Equals( this.Content, savedState.Content ) ) - && ( this.GetIsContentBindingSupportingSourceUpdate() ) ) - { - this.IsRestoringEditionState = true; - - try - { - this.Content = savedState.Content; - } - finally - { - this.IsRestoringEditionState = false; - } - } - } - - if( ( savedState.IsBeingEdited ) && ( parentColumn == currentColumn ) ) - this.BeginEdit(); - - - this.SetValidationError( savedState.CellValidationError ); - } - - internal void OnIsTemplateCellChanged( bool newValue ) - { - this.UpdateAnimatedColumnReorderingBindings( DataGridControl.GetDataGridContext( this ), newValue ); - } - - internal ValidationResult UpdateContentBindingSource( out Exception exception, out CellValidationRule ruleInErrorWrapper ) - { - Debug.Assert( ( ( this.IsDirty ) || ( this.IsInCascadingValidation ) ), - "UpdateContentBindingSource should not be called when the cell isn't dirty beside when cascading validation. Call ValidateContentBindingRules instead." ); - - exception = null; - ruleInErrorWrapper = null; - - var validationResult = ValidationResult.ValidResult; - var contentBindingExpression = this.GetContentBindingExpression(); - - if( contentBindingExpression != null ) - { - // The caller of UpdateContentBindingSource will take care of setting the errors. - this.PreventValidateAndSetAllErrors = true; - this.IsUpdatingContentBindingSource = true; - try - { - contentBindingExpression.UpdateSource(); - } - finally - { - this.PreventValidateAndSetAllErrors = false; - this.IsUpdatingContentBindingSource = false; - } - - validationResult = this.ValidateContentBindingRules( out exception, out ruleInErrorWrapper ); - } - - // Only consider the content committed if the source was correctly updated. - if( ( validationResult.IsValid ) || ( !( Cell.GetIsRuleInErrorRestrictive( ruleInErrorWrapper ) ) ) ) - { - this.ContentCommitted(); - } - - // The dirty flag will only be lowered when the row ends or cancels edition, or if the cell cancels edition and it wasn't dirty when begining edition. - return validationResult; - } - - internal CellState GetEditCachedState() - { - var cellState = default( CellState ); - var parentRow = this.ParentRow; - - if( ( parentRow != null ) && ( ( parentRow.IsBeingEdited ) || ( parentRow.IsBeginningEdition ) ) ) - { - var dataGridContext = DataGridControl.GetDataGridContext( this ); - - if( dataGridContext != null ) - { - var dataGridControl = dataGridContext.DataGridControl; - - if( ( dataGridControl != null ) && ( dataGridControl.CurrentRowInEditionState != null ) ) - { - var parentColumn = this.ParentColumn; - - if( parentColumn != null ) - { - cellState = parentColumn.CurrentRowInEditionCellState; - } - } - } - } - - return cellState; - } - - internal Nullable GetContentBindingUpdateSourceTrigger() - { - BindingExpressionBase contentBindingExpression = this.GetContentBindingExpression(); - - if( contentBindingExpression != null ) - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - if( dataGridContext != null ) - { - DataGridControl parentDataGridControl = dataGridContext.DataGridControl; - - if( parentDataGridControl != null ) - return parentDataGridControl.UpdateSourceTrigger; - } - } - - return null; - } - - internal IDisposable InhibitMakeVisible() - { - return new PreventMakeVisibleDisposable( this ); - } - - internal virtual bool GetCalculatedCanBeCurrent() - { - var column = this.ParentColumn; - if( ( column == null ) || ( this.ParentRow == null ) ) - return false; - - if( column.CanBeCurrentWhenReadOnly ) - return true; - - return !this.GetInheritedReadOnly(); - } - - internal virtual void ContentCommitted() - { - } - - internal void EnsureInVisualTree() - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - if( dataGridContext == null ) - return; - - TableView view = dataGridContext.DataGridControl.GetView() as TableView; - if( view == null ) - return; - - Row parentRow = this.ParentRow; - if( parentRow == null ) - return; - - FixedCellPanel fixedCellPanel = parentRow.CellsHostPanel as FixedCellPanel; - if( fixedCellPanel == null ) - return; - - var columnVirtualizationManager = ColumnVirtualizationManager.GetColumnVirtualizationManager( dataGridContext ) as TableViewColumnVirtualizationManagerBase; - if( columnVirtualizationManager == null ) - return; - - if( columnVirtualizationManager.GetFixedFieldNames( this.ParentRow.LevelCache ).Contains( this.FieldName ) ) - return; - - if( !fixedCellPanel.ForceScrollingCellToLayout( this ) ) - return; - - UIElement container = dataGridContext.GetContainerFromItem( this.GetRealDataContext() ) as UIElement; - if( container == null ) - return; - - // We must Call UpdateLayout on the container when a cell is - // added to VisualTree to ensure the offset relative to this - // container are correctly returned - container.UpdateLayout(); - } - - internal virtual DataTemplate GetForeignKeyDataTemplate() - { - return null; - } - - internal virtual DataTemplate GetCellStringFormatDataTemplate( DataTemplate contentTemplate ) - { - return null; - } - - private static object OnCoerceContent( DependencyObject sender, object value ) - { - var cell = sender as Cell; - - // If we are updating the Content binding source and content is refreshed as a result, hold-on. - // We will manually update Content from the source by calling UpdateTarget on the binding later. - if( ( cell != null ) && cell.IsUpdatingContentBindingSource ) - return DependencyProperty.UnsetValue; - - return value; - } - - private static void OnContentChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var cell = sender as Cell; - if( cell == null ) - return; - - var parentRow = cell.ParentRow; - if( parentRow == null ) - return; - - var doCellValidation = false; - var parentColumn = cell.ParentColumn; - - var changeDuringRowIsInEdit = ( cell.IsInternalyInitialized ) - && ( !cell.IsContainerRecycled ) - && ( !parentRow.IsBeginningEdition ) - && ( !cell.IsUpdatingContentBindingSource ) - && ( !cell.IsRestoringEditionState ) - && ( parentRow.IsBeingEdited ); - - if( changeDuringRowIsInEdit ) - { - if( parentColumn != null ) - { - if( parentColumn.CurrentRowInEditionCellState == null ) - { -#pragma warning disable 618 - Debug.Assert( false, "Should only happen with MultiSurfaceView. Unless there is a new template assigned to the Row in a trigger?" ); -#pragma warning restore 618 - parentColumn.CurrentRowInEditionCellState = new CellState(); - } - - parentColumn.CurrentRowInEditionCellState.SetContent( cell.Content ); - } - } - - if( changeDuringRowIsInEdit ) - { - if( !object.Equals( e.OldValue, e.NewValue ) ) - { - cell.SetIsDirty( true ); - } - - if( !cell.PreventValidateAndSetAllErrors ) - { - if( cell.GetContentBindingUpdateSourceTrigger() == DataGridUpdateSourceTrigger.CellContentChanged ) - { - doCellValidation = true; - } - } - } - - if( doCellValidation ) - { - // This method is called to make sure we are not calling ValidateAndSetAllErrors at all nor triggering a cascade validation - // as a side-effect of updating a cell's content binding source while another cell is bound to the very same source. - // We would be surprised of such a usage, but this fail-safe will take care of this possibility. - if( !cell.GetIsSiblingUpdatingContentBindingSource() ) - { - // The CellEditorRules must not be ckecked when UpdateSourceTrigger is set to CellContentChanged because the editor's HasValidationError property - // changes only AFTER the new cell value is commited. It would thus result in nothing being processed here if it were to be checked. - - Exception exception; - CellValidationRule ruleInError; - var validationResult = cell.ValidateCellRules( out exception, out ruleInError ); - if( validationResult.IsValid ) - { - cell.ValidateAndSetAllErrors( false, false, true, true, out exception, out ruleInError ); - } - } - } - - //When the content changes, check if the CellContentTemplateSelector needs to be updated. - //This depdends on several factor, including if a Selector is present and if the editor is not displayed - if( cell.ShouldInvalidateCellContentTemplateSelector( parentColumn ) ) - { - cell.UpdateCoercedContentTemplate( false ); - } - } - - private static void OnIsDirtyChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var cell = sender as Cell; - if( cell == null ) - return; - - if( ( bool )e.NewValue ) - { - //Raise the RoutedEvent that notifies any Row that the cell is becoming dirty. - RoutedEventArgs eventArgs = new RoutedEventArgs( Cell.IsDirtyEvent ); - cell.RaiseEvent( eventArgs ); - } - } - - private static void OnMatchingDisplayEditorChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var cell = sender as Cell; - if( cell == null ) - return; - - //performing this check because at the end of the Initializing function, I will call this explicitelly, to ensure - //proper display of the Editor if the appropriate conditions are met. - if( cell.IsInternalyInitialized ) - { - cell.RefreshDisplayedTemplate(); - } - } - - private static void OnCellEditorDisplayConditionsChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var cell = sender as Cell; - if( cell == null ) - return; - - // The cell.ParentRow can be null if this Cell is a TemplateCell - var parentRow = cell.ParentRow; - if( ( parentRow != null ) && parentRow.IsClearingContainer ) - return; - - cell.UpdateMatchingDisplayConditions(); - } - - private static void OnContentTemplateChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var cell = sender as Cell; - if( cell == null ) - return; - - cell.m_contentTemplateCache = e.NewValue as DataTemplate; - - if( ( cell.CurrentEditorPendingDisplayState != EditorDisplayState.PendingShow ) && ( !cell.IsCellEditorDisplayed ) ) - { - cell.UpdateCoercedContentTemplate( false ); - } - } - - private static void OnContentTemplateSelectorChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var cell = sender as Cell; - if( cell == null ) - return; - - cell.m_contentTemplateSelectorCache = e.NewValue as DataTemplateSelector; - - if( ( cell.CurrentEditorPendingDisplayState != EditorDisplayState.PendingShow ) && ( !cell.IsCellEditorDisplayed ) ) - { - cell.UpdateCoercedContentTemplate( false ); - } - } - - private static void OnIsTemplateCellChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var cell = sender as Cell; - if( cell == null ) - return; - - cell.OnIsTemplateCellChanged( ( bool )e.NewValue ); - } - - private bool GetInheritedReadOnly() - { - var isReadOnly = false; - var parentRow = this.ParentRow; - var parentColumn = this.ParentColumn; - - if( m_readOnlyIsInternalySet ) - { - this.ClearValue( Cell.ReadOnlyProperty ); - m_readOnlyIsInternalySet = false; - } - - var readOnlyPropertyValueSource = DependencyPropertyHelper.GetValueSource( this, Cell.ReadOnlyProperty ); - var isDataBound = readOnlyPropertyValueSource.BaseValueSource > BaseValueSource.Inherited; - - //If a value is set in any way (explicitly or implicitly) by the user on the cell, use that value. - if( isDataBound ) - { - isReadOnly = this.ReadOnly; - } - - //If a value is set in any way (explicitly or implicitly) by the user on the row, use that value. - if( !isDataBound && ( parentRow != null ) ) - { - readOnlyPropertyValueSource = DependencyPropertyHelper.GetValueSource( parentRow, Row.ReadOnlyProperty ); - isDataBound = readOnlyPropertyValueSource.BaseValueSource > BaseValueSource.Inherited; - - if( isDataBound ) - { - isReadOnly = parentRow.ReadOnly; - this.ReadOnly = isReadOnly; - m_readOnlyIsInternalySet = true; - } - } - - //If a value is set in any way (explicitly or implicitly) by the user on the column, use that value. - if( !isDataBound && ( parentColumn != null ) ) - { - readOnlyPropertyValueSource = DependencyPropertyHelper.GetValueSource( parentColumn, ColumnBase.ReadOnlyProperty ); - isDataBound = readOnlyPropertyValueSource.BaseValueSource > BaseValueSource.Inherited; - - if( isDataBound ) - { - isReadOnly = parentColumn.ReadOnly; - this.ReadOnly = isReadOnly; - m_readOnlyIsInternalySet = true; - } - } - - //If no value set by the user at any level, use the one set by the framework on the cell. - if( !isDataBound ) - { - isReadOnly = this.ReadOnly; - } - - if( isReadOnly ) - return true; - - var contentBindingExpression = this.GetContentBindingExpression(); - if( contentBindingExpression == null ) - return false; - - Nullable contentBindingMode = null; - if( contentBindingExpression is BindingExpression ) - { - contentBindingMode = ( ( Binding )contentBindingExpression.ParentBindingBase ).Mode; - } - else if( contentBindingExpression is MultiBindingExpression ) - { - contentBindingMode = ( ( MultiBinding )contentBindingExpression.ParentBindingBase ).Mode; - } - - return ( contentBindingMode.HasValue ) && ( contentBindingMode.Value != BindingMode.TwoWay ); - } - - private bool ShouldInvalidateCellContentTemplateSelector( ColumnBase parentColumn ) - { - if( parentColumn == null ) - return false; - - var onlyInternalContentTemplateSelectorAvailable = ( ( this.ContentTemplateInternal == null ) && ( this.ContentTemplateSelectorInternal != null ) ); - var onlyColumnContentTemplateSelectorAvailable = ( ( parentColumn.CellContentTemplate == null ) && ( parentColumn.CellContentTemplateSelector != null ) ); - var onlyTemplateSelectorAvailable = onlyColumnContentTemplateSelectorAvailable || onlyInternalContentTemplateSelectorAvailable; - var editorHiddenAndNotPendingShow = !this.IsCellEditorDisplayed && ( this.CurrentEditorPendingDisplayState != EditorDisplayState.PendingShow ); - - // Only TemplateSelectors are available and editor is not hidden and pending showing - return ( onlyTemplateSelectorAvailable && editorHiddenAndNotPendingShow ); - } - - private bool GetIsContentBindingSupportingSourceUpdate() - { - var binding = this.GetContentBindingExpression(); - if( binding == null ) - return false; - - BindingMode mode; - var singleBinding = binding.ParentBindingBase as Binding; - - if( singleBinding == null ) - { - var multiBinding = binding.ParentBindingBase as MultiBinding; - if( multiBinding == null ) - return false; - - mode = multiBinding.Mode; - } - else - { - mode = singleBinding.Mode; - } - - return ( mode == BindingMode.OneWayToSource ) || ( mode == BindingMode.TwoWay ); - } - - private bool GetIsSiblingUpdatingContentBindingSource() - { - // This method is called to make sure we are not calling ValidateAndSetAllErrors at all nor triggering a cascade validation - // as a side-effect of updating a cell's content binding source while another cell is bound to the very same source. - // We would be surprised of such a usage, but this fail-safe will take care of this possibility. - var parentRow = this.ParentRow; - if( parentRow != null ) - { - foreach( Cell siblingCell in parentRow.CreatedCells ) - { - if( ( siblingCell != this ) && ( siblingCell.IsUpdatingContentBindingSource ) ) - { - // Such a situation should only occur when one of the two (or more) cells sharing the exact same source as their content binding. - return true; - } - } - } - - return false; - } - - private DataTemplate GetCoercedCellContentTemplate() - { - var dataGridContext = DataGridControl.GetDataGridContext( this ); - if( dataGridContext == null ) - return null; - - var contentTemplate = this.ContentTemplateInternal; - var content = this.Content; - - if( contentTemplate == null ) - { - //If none, check if there is a ContentTemplateSelector directly assigned on cell. - var contentTemplateSelector = this.ContentTemplateSelectorInternal; - if( contentTemplateSelector != null ) - { - //If there is one, the query it for a ContentTemplate. - contentTemplate = contentTemplateSelector.SelectTemplate( content, this ); - } - } - - var parentColumn = this.ParentColumn; - - //If there was no ContentTemplateSelector on Cell or if the output of the selector was Null. - if( ( !this.OverrideColumnCellContentTemplate ) && ( contentTemplate == null ) && ( parentColumn != null ) ) - { - contentTemplate = this.GetForeignKeyDataTemplate(); - if( contentTemplate != null ) - return contentTemplate; - - if( contentTemplate == null ) - { - //If the parent Column defines a CellContentTemplate, then use it - contentTemplate = parentColumn.CellContentTemplate; - - //if it doesn't, then check for a selector on Column - if( contentTemplate == null ) - { - var contentTemplateSelector = parentColumn.CellContentTemplateSelector; - if( contentTemplateSelector != null ) - { - //If a selector exists on Column, then use it. - contentTemplate = contentTemplateSelector.SelectTemplate( content, this ); - } - } - } - } - - //After all of this, if there is still no ContentTemplate found, then use the default basic one. - if( contentTemplate == null ) - { - contentTemplate = GenericContentTemplateSelector.Instance.SelectTemplate( content, this ); - } - - if( ( contentTemplate != null ) && ( parentColumn != null ) && !string.IsNullOrEmpty( parentColumn.CellContentStringFormat ) ) - { - var newContentTemplate = this.GetCellStringFormatDataTemplate( contentTemplate ); - if( newContentTemplate != null ) - { - contentTemplate = newContentTemplate; - } - } - - return contentTemplate; - } - - private Style GetInheritedErrorStyle() - { - object style = this.ReadLocalValue( Cell.CellErrorStyleProperty ); - - // In case we have a BindingExpression, we need to get the resulting value. - if( style is BindingExpressionBase ) - style = this.CellErrorStyle; - - if( style == DependencyProperty.UnsetValue ) - { - ColumnBase column = this.ParentColumn; - - if( column != null ) - { - style = column.ReadLocalValue( Column.CellErrorStyleProperty ); - - // In case we have a BindingExpression, we need to get the resulting value. - if( style is BindingExpressionBase ) - style = column.CellErrorStyle; - } - } - - if( style == DependencyProperty.UnsetValue ) - style = this.CellErrorStyle; - - return style as Style; - } - - private BindingExpressionBase GetContentBindingExpression() - { - return BindingOperations.GetBindingExpressionBase( this, Cell.ContentProperty ); - } - - private EditorDisplayState CurrentEditorPendingDisplayState - { - get; - set; - } - - private object GetRealDataContext() - { - object dataContext = this.DataContext; - UnboundDataItem unboundDataItem = dataContext as UnboundDataItem; - - if( unboundDataItem == null ) - return dataContext; - - return unboundDataItem.DataItem; - } - - private bool IsSameUnboundItem( object dataContext, object item ) - { - UnboundDataItem unboundDataItem = dataContext as UnboundDataItem; - - return unboundDataItem.DataItem == item; - } - - private void UpdateAnimatedColumnReorderingBindings( DataGridContext dataGridContext, bool isTemplateCell ) - { - // Only set the Binding if the view is a TableflowView. - var setBindings = ( !isTemplateCell ) - && ( dataGridContext != null ) - && ( dataGridContext.DataGridControl.GetView() is TableflowView ); - - if( setBindings == this.AnimatedColumnReorderingBindingApplied ) - return; - - if( setBindings ) - { - BindingOperations.SetBinding( this, Cell.RenderTransformProperty, Cell.ParentColumnTranslationBinding ); - BindingOperations.SetBinding( this, Cell.ParentColumnIsBeingDraggedProperty, Cell.ParentColumnIsBeingDraggedBinding ); - BindingOperations.SetBinding( this, Cell.ParentColumnReorderingDragSourceManagerProperty, Cell.ParentColumnReorderingDragSourceManagerBinding ); - } - else - { - BindingOperations.ClearBinding( this, Cell.RenderTransformProperty ); - BindingOperations.ClearBinding( this, Cell.ParentColumnIsBeingDraggedProperty ); - BindingOperations.ClearBinding( this, Cell.ParentColumnReorderingDragSourceManagerProperty ); - } - - this.AnimatedColumnReorderingBindingApplied = setBindings; - } - - private void ShowEditTemplate() - { - this.AbortHideEditTemplate(); - - // The editor is not pending showing - if( this.CurrentEditorPendingDisplayState != EditorDisplayState.PendingShow ) - { - // If it is not displayed or pending hiding - if( !this.IsCellEditorDisplayed || ( this.CurrentEditorPendingDisplayState == EditorDisplayState.PendingHide ) || m_forceEditorRefresh ) - { - var cellEditor = this.GetCellEditor(); - if( cellEditor != null ) - { - this.SetCoercedContentTemplate( this.GetCoercedCellContentTemplate(), cellEditor.EditTemplate ); - - // Force the editor to update its editor state on next layout pass - this.CurrentEditorPendingDisplayState = EditorDisplayState.PendingShow; - } - } - else - { - // This will force re-layout of the control, raising the LayoutUpdated event - // and correctly update the display state for this editor - this.InvalidateArrange(); - } - } - } - - private void DelayHideEditTemplate() - { - if( m_delayedHideEditTemplateDispatcherOperation != null ) - return; - - if( ( !this.IsCellEditorDisplayed ) && ( this.CurrentEditorPendingDisplayState != EditorDisplayState.PendingShow ) ) - return; - - m_delayedHideEditTemplateDispatcherOperation = this.Dispatcher.BeginInvoke( new Action( this.HideEditTemplate ), DispatcherPriority.DataBind ); - } - - private void AbortHideEditTemplate() - { - if( m_delayedHideEditTemplateDispatcherOperation == null ) - return; - - Debug.Assert( m_delayedHideEditTemplateDispatcherOperation.Status == DispatcherOperationStatus.Pending ); - m_delayedHideEditTemplateDispatcherOperation.Abort(); - m_delayedHideEditTemplateDispatcherOperation = null; - } - - private void HideEditTemplate() - { - m_delayedHideEditTemplateDispatcherOperation = null; - - // The Cell is not prepared or virtualized, no need to - // hide the edit template since it will be refreshed - // the the Cell is prepared again. - if( !this.IsContainerPrepared || this.IsContainerVirtualized ) - return; - - if( !this.IsCellEditorDisplayed && ( this.CurrentEditorPendingDisplayState != EditorDisplayState.PendingShow ) ) - return; - - this.SetCoercedContentTemplate( this.GetCoercedCellContentTemplate(), null ); - this.CurrentEditorPendingDisplayState = EditorDisplayState.PendingHide; - - // We must clear the CellEditorContext when the Template is hidden - // to avoid side effects of the CellEditorBinding affecting null - // in the source. The reason is that the CellEditorContext is the - // binding source of the default foreign key CellEditor Template - Cell.ClearCellEditorContext( this ); - } - - private void AddDraggedColumnGhost( ColumnReorderingDragSourceManager manager, bool isBeingDraggedAnimated ) - { - if( !isBeingDraggedAnimated || !this.IsContainerPrepared || manager.ContainsDraggedColumnGhost( this ) ) - return; - - this.ClearValue( Cell.OpacityProperty ); - - manager.AddDraggedColumnGhost( this ); - } - - private void RemoveDraggedColumnGhost( ColumnReorderingDragSourceManager manager ) - { - if( !manager.ContainsDraggedColumnGhost( this ) ) - return; - - manager.RemoveDraggedColumnGhost( this ); - - this.ClearValue( Cell.OpacityProperty ); - } - - private void UpdateMatchingDisplayConditions() - { - CellEditorDisplayConditions newEffectiveValue = CellEditorDisplayConditions.None; - - if( ( Cell.IsCellEditorDisplayConditionsSet( this, CellEditorDisplayConditions.MouseOverCell ) ) && - ( this.IsMouseOver ) ) - { - newEffectiveValue |= CellEditorDisplayConditions.MouseOverCell; - } - - if( ( Cell.IsCellEditorDisplayConditionsSet( this, CellEditorDisplayConditions.CellIsCurrent ) ) && - ( this.IsCurrent ) ) - { - newEffectiveValue |= CellEditorDisplayConditions.CellIsCurrent; - } - - if( Cell.IsCellEditorDisplayConditionsSet( this, CellEditorDisplayConditions.Always ) ) - { - newEffectiveValue |= CellEditorDisplayConditions.Always; - } - - // No need to call RefreshDisplayedTemplate since - // this method is called when the CellDisplayEditorMatchingConditions - // property changes on Cell or ParentColumn - // OR - // when PrepareContainer is called on Cell - this.SetValue( Cell.CellDisplayEditorMatchingConditionsProperty, newEffectiveValue ); - } - - private void UpdateFocusable() - { - var isFocusable = false; - var dataGridContext = DataGridControl.GetDataGridContext( this ); - - if( dataGridContext != null ) - { - var column = this.ParentColumn; - var dataGridControl = dataGridContext.DataGridControl; - - Debug.Assert( dataGridControl != null ); - - if( ( !this.GetCalculatedCanBeCurrent() ) && ( column != null ) && ( column == dataGridContext.CurrentColumn ) ) - { - try - { - dataGridContext.SetCurrentColumnCore( null, false, dataGridControl.SynchronizeSelectionWithCurrent, AutoScrollCurrentItemSourceTriggers.CurrentColumnChanged ); - } - catch( DataGridException ) - { - // We swallow the exception if it occurs because of a validation error or Cell was read-only or - // any other GridException. - } - } - - isFocusable = true; - - if( !this.IsBeingEdited ) - { - var row = this.ParentRow; - if( row != null ) - { - switch( row.NavigationBehavior ) - { - case NavigationBehavior.None: - case NavigationBehavior.RowOnly: - isFocusable = false; - break; - } - } - } - } - - //force an update of the NavigationBehavior characteristics - this.Focusable = isFocusable && this.GetCalculatedCanBeCurrent(); - } - - private void OnBeginEditExecuted( object sender, ExecutedRoutedEventArgs e ) - { - try - { - this.BeginEdit(); - } - catch( DataGridException ) - { - // We swallow the exception if it occurs because of a validation error or Cell was read-only or - // any other GridException. - } - } - - private void OnBeginEditCanExecute( object sender, CanExecuteRoutedEventArgs e ) - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - if( dataGridContext != null ) - { - DataGridControl parentGrid = dataGridContext.DataGridControl; - - if( parentGrid == null || this.ParentRow == null ) - { - e.CanExecute = false; - } - else - { - e.CanExecute = ( !this.IsBeingEdited ) - && ( !this.GetInheritedReadOnly() ) - && ( this.ParentRow.IsEditTriggerSet( EditTriggers.BeginEditCommand ) ); - } - } - } - - private void OnCancelEditExecuted( object sender, ExecutedRoutedEventArgs e ) - { - this.CancelEdit(); - } - - private void OnCancelEditCanExecute( object sender, CanExecuteRoutedEventArgs e ) - { - e.CanExecute = this.IsBeingEdited; - } - - private void Cell_Loaded( object sender, RoutedEventArgs e ) - { - System.Diagnostics.Debug.Assert( this.HasPendingErrorStyleRefresh, "The cell should have unsubcribed from the event." ); - System.Diagnostics.Debug.Assert( m_loadedRoutedEventHandler != null ); - - this.Loaded -= m_loadedRoutedEventHandler; - m_loadedRoutedEventHandler = null; - - this.DelayRefreshErrorStyle(); - } - - private void Cell_LayoutUpdated( object sender, EventArgs e ) - { - if( !this.IsContainerPrepared || this.IsContainerVirtualized ) - return; - - if( this.CurrentEditorPendingDisplayState == EditorDisplayState.PendingShow ) - { - //If the Cell is marked to be pending the display of the editor, then - //this LayoutUpdated means that Editor has been effectively displayed - - - - //Change the IsCellEditorDisplayed flag accordingly - this.SetIsCellEditorDisplayed( true ); - } - else if( this.CurrentEditorPendingDisplayState == EditorDisplayState.PendingHide ) - { - //If the Cell is marked to be pending the Display of the viewer, then - //this LayoutUpdated means that Editor has been effectively hidden - - - - //Change the IsCellEditorDisplayed flag accordingly - this.SetIsCellEditorDisplayed( false ); - } - - // Reset the Editor/Viewer displaying flag. - this.CurrentEditorPendingDisplayState = EditorDisplayState.None; - - // This condition allows detecting if the focus needs to be changed - // after having displayed the editor. - if( !this.IsCellEditorDisplayed || !this.FocusEditor ) - return; - - // Reset the flag that indicates if the focus needs to be set in the template - this.FocusEditor = false; - bool editorFocused = false; - - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - DataGridControl dataGridControl = dataGridContext.DataGridControl; - - if( dataGridControl != null ) - { - //Focus need to be changed. - editorFocused = dataGridControl.SetFocusHelper( this.ParentRow, this.ParentColumn, false, true ); - } - - if( !editorFocused ) - { - m_keyGesture = null; - m_textInputArgs = null; - } - else - { - //If a keystroke was recorded for "resend" upon layout update - if( m_keyGesture != null ) - { - //Generate an EventArgs for the PreviewKeyDown for the KeyStroke - Key realKey; - if( ( m_keyGesture.Key == Key.None ) && ( m_keyGesture.SystemKey != Key.None ) ) - { - realKey = m_keyGesture.SystemKey; - } - else - { - realKey = m_keyGesture.Key; - } - - try - { - KeyEventArgs kea = new KeyEventArgs( Keyboard.PrimaryDevice, Keyboard.PrimaryDevice.ActiveSource, 0, realKey ); - kea.RoutedEvent = Keyboard.PreviewKeyDownEvent; - - //send the event - Keyboard.PrimaryDevice.FocusedElement.RaiseEvent( kea ); - - if( kea.Handled == false ) - { - //Generate an EventArgs for the KeyDown event Args for the preserved KeyStroke - kea = new KeyEventArgs( Keyboard.PrimaryDevice, Keyboard.PrimaryDevice.ActiveSource, 0, realKey ); - kea.RoutedEvent = Keyboard.KeyDownEvent; - - //Send the Event to the Input Manager - Keyboard.PrimaryDevice.FocusedElement.RaiseEvent( kea ); - } - } - catch( SecurityException ex ) - { - //if the exception is for the UIPermission, then we want to suppress it - if( !( ex.PermissionType.FullName == "System.Security.Permissions.UIPermission" ) ) - { - //not correct type, then rethrow the exception - throw; - } - } - - //clear the KeyStroke preserved. - m_keyGesture = null; - } - - //If TextInput was preserved for resend - if( m_textInputArgs != null ) - { - //Generate new TextInput Event Args - TextCompositionEventArgs new_event = new TextCompositionEventArgs( m_textInputArgs.Device, m_textInputArgs.TextComposition ); - new_event.RoutedEvent = UIElement.PreviewTextInputEvent; - - //Send the event to the InputManager. - Keyboard.PrimaryDevice.FocusedElement.RaiseEvent( new_event ); - - if( !new_event.Handled ) - { - new_event = new TextCompositionEventArgs( m_textInputArgs.Device, m_textInputArgs.TextComposition ); - new_event.RoutedEvent = UIElement.TextInputEvent; - - //Send the event to the InputManager. - Keyboard.PrimaryDevice.FocusedElement.RaiseEvent( new_event ); - } - } - - //Clear the TextInput preserved. - m_textInputArgs = null; - } - } - - #region EDITION - - public static readonly RoutedEvent EditBeginningEvent = EventManager.RegisterRoutedEvent( "EditBeginning", RoutingStrategy.Bubble, typeof( CancelRoutedEventHandler ), typeof( Cell ) ); - public static readonly RoutedEvent EditBegunEvent = EventManager.RegisterRoutedEvent( "EditBegun", RoutingStrategy.Bubble, typeof( RoutedEventHandler ), typeof( Cell ) ); - public static readonly RoutedEvent EditEndingEvent = EventManager.RegisterRoutedEvent( "EditEnding", RoutingStrategy.Bubble, typeof( CancelRoutedEventHandler ), typeof( Cell ) ); - public static readonly RoutedEvent EditEndedEvent = EventManager.RegisterRoutedEvent( "EditEnded", RoutingStrategy.Bubble, typeof( RoutedEventHandler ), typeof( Cell ) ); - public static readonly RoutedEvent EditCancelingEvent = EventManager.RegisterRoutedEvent( "EditCanceling", RoutingStrategy.Bubble, typeof( RoutedEventHandler ), typeof( Cell ) ); - public static readonly RoutedEvent EditCanceledEvent = EventManager.RegisterRoutedEvent( "EditCanceled", RoutingStrategy.Bubble, typeof( RoutedEventHandler ), typeof( Cell ) ); - - public event CancelRoutedEventHandler EditBeginning - { - add - { - base.AddHandler( Cell.EditBeginningEvent, value ); - } - remove - { - base.RemoveHandler( Cell.EditBeginningEvent, value ); - } - } - - public event RoutedEventHandler EditBegun - { - add - { - base.AddHandler( Cell.EditBegunEvent, value ); - } - remove - { - base.RemoveHandler( Cell.EditBegunEvent, value ); - } - } - - public event CancelRoutedEventHandler EditEnding - { - add - { - base.AddHandler( Cell.EditEndingEvent, value ); - } - remove - { - base.RemoveHandler( Cell.EditEndingEvent, value ); - } - } - - public event RoutedEventHandler EditEnded - { - add - { - base.AddHandler( Cell.EditEndedEvent, value ); - } - remove - { - base.RemoveHandler( Cell.EditEndedEvent, value ); - } - } - - public event RoutedEventHandler EditCanceling - { - add - { - base.AddHandler( Cell.EditCancelingEvent, value ); - } - remove - { - base.RemoveHandler( Cell.EditCancelingEvent, value ); - } - } - - public event RoutedEventHandler EditCanceled - { - add - { - base.AddHandler( Cell.EditCanceledEvent, value ); - } - remove - { - base.RemoveHandler( Cell.EditCanceledEvent, value ); - } - } - - public void BeginEdit() - { - if( this.IsBeingEdited ) - return; - - var readOnly = this.GetInheritedReadOnly(); - if( readOnly ) - throw new DataGridException( "An attempt was made to edit a read-only cell or the cell content is not bound using two way binding." ); - - // If there is no dataItem mapped to this container, we don't want to - // enter in edition - var dataGridContext = DataGridControl.GetDataGridContext( this ); - if( dataGridContext != null ) - { - var dataItem = dataGridContext.GetItemFromContainer( this ); - if( dataItem == null ) - return; - } - - Debug.Assert( this.IsContainerPrepared, "Can't edit a cell that has not been prepared." ); - - var parentRow = this.ParentRow; - - try - { - if( !parentRow.IsBeingEdited ) - { - // Prevent the Row Beginning and Begun events from being raised. The cell will handle them in order - // to maintain the same logical order as in other scenarios. - parentRow.IsBeginningEditFromCell = true; - - CancelRoutedEventArgs rowCancelEventArgs = new CancelRoutedEventArgs( Row.EditBeginningEvent, parentRow ); - parentRow.OnEditBeginning( rowCancelEventArgs ); - - if( rowCancelEventArgs.Cancel ) - throw new DataGridException( "BeginEdit was canceled." ); - } - - CancelRoutedEventArgs e = new CancelRoutedEventArgs( Cell.EditBeginningEvent, this ); - this.OnEditBeginning( e ); - - if( e.Cancel ) - throw new DataGridException( "BeginEdit was canceled." ); - - if( !this.IsCurrent ) - { - dataGridContext.SetCurrent( - dataGridContext.GetItemFromContainer( parentRow ), - parentRow, - DataGridVirtualizingPanel.GetItemIndex( parentRow ), - this.ParentColumn, - false, - true, - dataGridContext.DataGridControl.SynchronizeSelectionWithCurrent, - AutoScrollCurrentItemSourceTriggers.Editing ); - } - - if( ( !parentRow.IsBeingEdited ) && ( !parentRow.IsBeginningEdition ) ) - { - parentRow.BeginEdit(); - } - - this.SetIsBeingEdited( true ); - var cellState = this.GetEditCachedState(); - - if( cellState != null ) - { - if( cellState.ContentBeforeCellEdition == DependencyProperty.UnsetValue ) - { - cellState.SetContentBeforeCellEdition( this.Content ); - } - - cellState.SetIsDirtyBeforeEdition( this.IsDirty ); - } - - this.OnEditBegun(); - - if( parentRow.IsBeginningEditFromCell ) - { - parentRow.OnEditBegun(); - } - } - finally - { - parentRow.IsBeginningEditFromCell = false; - } - } - - public void EndEdit() - { - if( !this.IsBeingEdited ) - return; - - var dataGridUpdateSourceTrigger = this.GetContentBindingUpdateSourceTrigger(); - var updateContentBindingSource = ( dataGridUpdateSourceTrigger == DataGridUpdateSourceTrigger.CellEndingEdit ) - || ( dataGridUpdateSourceTrigger == DataGridUpdateSourceTrigger.CellContentChanged ); - - this.EndEdit( true, true, updateContentBindingSource ); - } - - public void CancelEdit() - { - if( !this.IsBeingEdited ) - return; - - this.OnEditCanceling(); - - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - //There is an identified weakness with the IsKeyboardFocusWithin property where it cannot tell if the focus is within a Popup which is within the element - //This has been identified, and only the places where it caused problems were fixed... This comment is only here to remind developpers of the flaw - if( ( !this.IsKeyboardFocused ) && ( this.IsKeyboardFocusWithin ) ) - { - // We delay the set focus on the cell to prevent the lost focus from being raised for the editor. - // This is to prevent execution of some validation code that may be in the LostFocus of the editor. - if( dataGridContext != null ) - { - dataGridContext.DelayBringIntoViewAndFocusCurrent( AutoScrollCurrentItemSourceTriggers.Editing ); - } - } - - CellState cellState = this.GetEditCachedState(); - - Debug.Assert( cellState != null ); - - if( cellState != null ) - { - Debug.Assert( ( cellState.ContentBeforeCellEdition != DependencyProperty.UnsetValue ) && ( cellState.IsDirtyBeforeEdition.HasValue ), "It seems the column was recreated or the cellstate overwritten while the row/cell was in edition." ); - - if( cellState.ContentBeforeCellEdition != DependencyProperty.UnsetValue ) - { - - // Prevent ValidateAndSetAllErrors since we will call it later. - this.PreventValidateAndSetAllErrors = true; - - try - { - Debug.Assert( !this.GetInheritedReadOnly() ); - this.Content = cellState.ContentBeforeCellEdition; - } - finally - { - this.PreventValidateAndSetAllErrors = false; - } - - var dataGridUpdateSourceTrigger = this.GetContentBindingUpdateSourceTrigger(); - var updateContentBindingSource = ( dataGridUpdateSourceTrigger == DataGridUpdateSourceTrigger.CellEndingEdit ) - || ( dataGridUpdateSourceTrigger == DataGridUpdateSourceTrigger.CellContentChanged ); - - Exception exception; - CellValidationRule ruleInError; - this.ValidateAndSetAllErrors( true, true, updateContentBindingSource, true, out exception, out ruleInError ); - - cellState.SetContentBeforeCellEdition( DependencyProperty.UnsetValue ); - } - - if( cellState.IsDirtyBeforeEdition.HasValue ) - { - this.SetIsDirty( cellState.IsDirtyBeforeEdition.Value ); - cellState.SetIsDirtyBeforeEdition( null ); - } - } - - this.SetIsBeingEdited( false ); - this.OnEditCanceled(); - } - - protected virtual void OnEditBeginning( CancelRoutedEventArgs e ) - { - this.RaiseEvent( e ); - } - - protected virtual void OnEditBegun() - { - RoutedEventArgs e = new RoutedEventArgs( Cell.EditBegunEvent, this ); - this.RaiseEvent( e ); - } - - protected virtual void OnEditEnding( CancelRoutedEventArgs e ) - { - this.RaiseEvent( e ); - } - - protected virtual void OnEditEnded() - { - RoutedEventArgs e = new RoutedEventArgs( Cell.EditEndedEvent, this ); - this.RaiseEvent( e ); - } - - protected virtual void OnEditCanceling() - { - RoutedEventArgs e = new RoutedEventArgs( Cell.EditCancelingEvent, this ); - this.RaiseEvent( e ); - } - - protected virtual void OnEditCanceled() - { - RoutedEventArgs e = new RoutedEventArgs( Cell.EditCanceledEvent, this ); - this.RaiseEvent( e ); - } - - internal void EndEdit( bool validateCellEditorRules, bool validateUIRules, bool updateContentBindingSource ) - { - if( !this.IsBeingEdited ) - return; - - try - { - var e = new CancelRoutedEventArgs( Cell.EditEndingEvent, this ); - - this.OnEditEnding( e ); - - // Throwing a DataGridValidationException will be caught by the grid and will make the cell stay in edition. - if( e.Cancel ) - throw new DataGridValidationException( "EndEdit was canceled." ); - - //There is an identified weakness with the IsKeyboardFocusWithin property where it cannot tell if the focus is within a Popup which is within the element - //This has been identified, and only the places where it caused problems were fixed... This comment is only here to remind developpers of the flaw - if( ( !this.IsKeyboardFocused ) && ( this.IsKeyboardFocusWithin ) ) - { - var dataGridContext = DataGridControl.GetDataGridContext( this ); - - if( ( dataGridContext != null ) && ( !dataGridContext.DataGridControl.IsSetFocusInhibited ) ) - { - // Prevent the focus to make a RequestBringIntoView - using( this.InhibitMakeVisible() ) - { - // We want to try to focus the Cell before we continue the EndEdit to ensure any validation or process in the lost focus is done - if( !dataGridContext.DataGridControl.SetFocusHelper( this.ParentRow, this.ParentColumn, false, false ) ) - throw new DataGridFocusException( "Unable to set focus on the Cell." ); - } - } - } - } - catch( Exception exception ) - { - if( exception is TargetInvocationException ) - { - exception = exception.InnerException; - } - - // In the case it's the focus that failed, we don't want to make that a ValidationError since it - // must be retained by the editor itself with his own error mechanic. - // - // Also, for example, clicking on another cell will trigger the lost focus first and editor - // will retain focus without any EndEdit being called and without any error displayed by the grid. - // So with that focus exception we make sure the behaviour is uniform. - if( exception is DataGridFocusException ) - throw; - - this.SetValidationError( new CellValidationError( Cell.CustomCellValidationExceptionValidationRule, this, exception.Message, exception ) ); - - // Throwing a DataGridValidationException will be caught by the grid and will make the cell stay in edition. - throw new DataGridValidationException( "An error occurred while attempting to end the edit process.", exception ); - } - - Exception notUsed; - CellValidationRule ruleInError; - var result = this.ValidateAndSetAllErrors( validateCellEditorRules, validateUIRules, updateContentBindingSource, true, out notUsed, out ruleInError ); - - var cellState = this.GetEditCachedState(); - if( cellState != null ) - { - if( result.IsValid ) - { - cellState.SetContentBeforeCellEdition( DependencyProperty.UnsetValue ); - } - - cellState.SetIsDirtyBeforeEdition( null ); - } - - this.SetIsBeingEdited( false ); - this.OnEditEnded(); - } - - internal FrameworkElement CellEditorBoundControl - { - get - { - return this.GetCellEditorBoundControl( this ); - } - } - - private static void Cell_RequestBringIntoView( object sender, RequestBringIntoViewEventArgs e ) - { - Cell cell = sender as Cell; - - if( cell.PreventMakeVisible ) - { - e.Handled = true; - } - } - - private FrameworkElement GetCellEditorBoundControl( FrameworkElement frameworkElement ) - { - int childrenCount = System.Windows.Media.VisualTreeHelper.GetChildrenCount( frameworkElement ); - - for( int i = 0; i < childrenCount; i++ ) - { - FrameworkElement child = System.Windows.Media.VisualTreeHelper.GetChild( frameworkElement, i ) as FrameworkElement; - - if( child != null ) - { - if( child.Name == "PART_CellEditorBoundControl" ) - return child; - - FrameworkElement matchingPart = this.GetCellEditorBoundControl( child ); - - if( matchingPart != null ) - return matchingPart; - } - } - - return null; - } - - #endregion EDITION - - #region VALIDATION - - internal ValidationResult ValidateAndSetAllErrors( - bool validateCellEditorRules, - bool validateUIRules, - bool updateContentBindingSource, - bool cascadeValidate, - out Exception exception, - out CellValidationRule ruleInError ) - { - System.Diagnostics.Debug.Assert( !this.PreventValidateAndSetAllErrors, - "We should not have called this method while in this state." ); - - System.Diagnostics.Debug.Assert( !( cascadeValidate && this.IsInCascadingValidation ), - "We should never be calling ValidateAndSetAllErrors with a request to start cascade validation if we are currently cascading validation." ); - - if( this.IsInCascadingValidation && cascadeValidate ) - { - throw new DataGridInternalException( - "We should never be calling ValidateAndSetAllErrors with a request to start cascade validation if we are currently cascading validation.", - DataGridControl.GetDataGridContext( this ).DataGridControl ); - } - - var result = ValidationResult.ValidResult; - exception = null; - ruleInError = null; - - // Validate that the CellEditor isn't in error. - if( validateCellEditorRules ) - { - result = this.ValidateCellEditorRules( out exception, out ruleInError ); - - // If the CellEditor is in error, it must be shown, no matter what. - if( !result.IsValid ) - { - this.SetAllError( result, exception, ruleInError ); - return result; - } - } - - // Validate CellValidationRules against the cell's Content property. - if( validateUIRules ) - { - result = this.ValidateCellRules( out exception, out ruleInError ); - } - - if( result.IsValid ) - { - // Only need to update the Content binding source if the cell is dirty or if we are cascading the validation. - if( ( updateContentBindingSource ) - && ( ( this.IsDirty ) || ( this.IsInCascadingValidation ) ) ) - { - // Update the Content binding's source and check for errors. - result = this.UpdateContentBindingSource( out exception, out ruleInError ); - } - else - { - // Just check for errors. We must validate even if the cell isn't dirty since its value might have been in error even before entering edit on the row. - // ie: DataErrorInfo or any other non-restrictive validation error. - result = this.ValidateContentBindingRules( out exception, out ruleInError ); - } - } - - // Only refresh ValidationError property, HasValidationError property, and the cell's style - // if if we are in a validating the UI Rules or if there wasn't any UI error before this validation pass. - if( ( validateUIRules ) || ( !this.HasUIValidationError ) ) - { - this.SetAllError( result, exception, ruleInError ); - - if( cascadeValidate ) - { - this.CascadeValidation(); - } - } - - return result; - } - - internal ValidationResult ValidateCellEditorRules( out Exception validationException, out CellValidationRule ruleInError ) - { - validationException = null; - ruleInError = null; - - FrameworkElement cellEditorBoundControl = this.CellEditorBoundControl; - - ValidationResult validationResult = - Cell.CellEditorErrorValidationRule.Validate( this.Content, - CultureInfo.CurrentCulture, - new CellValidationContext( this.GetRealDataContext(), this ), - cellEditorBoundControl ); - - if( !validationResult.IsValid ) - { - ruleInError = Cell.CellEditorErrorValidationRule; - validationException = new DataGridException( "An invalid or incomplete value was provided." ); - } - - return validationResult; - } - - internal void ClearAllErrors() - { - this.SetAllError( ValidationResult.ValidResult, null, null ); - } - - private static void OnContentBindingNotifyValidationError( object sender, ValidationErrorEventArgs e ) - { - Cell cell = ( Cell )sender; - - cell.NotifyContentBindingValidationError(); - } - - internal void NotifyContentBindingValidationError() - { - if( this.PreventValidateAndSetAllErrors ) - return; - - // Proceed only if the isn't any UI ValidationRules error flagged since last UI validation pass. - if( this.HasUIValidationError ) - return; - - var validationError = this.GetContentBindingValidationError(); - - // In order to minimize switching of styles when we need to update the Content Binding's source, the SetAllError method will not do anything while it is being prevented. - // e.g. : When we need to update the ContentBinding's source manually through EndEdit. - if( validationError != null ) - { - this.SetAllError( new ValidationResult( false, validationError.ErrorContent ), validationError.Exception, - new CellContentBindingValidationRule( validationError.RuleInError ) ); - } - else - { - this.SetAllError( ValidationResult.ValidResult, null, null ); - } - } - - private void OnContentBindingTargetUpdated( object sender, DataTransferEventArgs e ) - { - if( e.Property != Cell.ContentProperty ) - return; - - var cell = e.TargetObject as Cell; - - // Under certain circumstances which have not yet been clearly identified, the TargetObject is the ContentPresenter of the ScrollTip. - // This would raise a NullReferenceException when trying to access cell's members, as the previous cast would return null. - if( cell == null ) - return; - - var parentRow = cell.ParentRow; - - if( ( cell.IsUpdatingContentBindingSource ) || ( cell.PreventValidateAndSetAllErrors ) - || ( parentRow == null ) || ( !parentRow.IsBeingEdited ) || ( !parentRow.IsDirty ) ) - { - return; - } - - // This method is called to make sure we are not calling ValidateAndSetAllErrors at all nor triggering a cascade validation - // as a side-effect of updating a cell's content binding source while another cell is bound to the very same source. - // We would be surprised of such a usage, but this fail-safe will take care of this possibility. - if( cell.GetIsSiblingUpdatingContentBindingSource() ) - return; - - Exception exception; - CellValidationRule ruleInError; - cell.ValidateAndSetAllErrors( false, true, false, true, out exception, out ruleInError ); - } - - private void CascadeValidation() - { - var parentRow = this.ParentRow; - - if( parentRow == null ) - return; - - var dataGridUpdateSourceTrigger = this.GetContentBindingUpdateSourceTrigger(); - var updateContentBindingSource = ( parentRow.IsEndingEdition || parentRow.IsCancelingEdition ) - || ( dataGridUpdateSourceTrigger == DataGridUpdateSourceTrigger.CellEndingEdit ) - || ( dataGridUpdateSourceTrigger == DataGridUpdateSourceTrigger.CellContentChanged ); - - // Create a clone of the list to avoid concurrent access when iterating and a Cell is added to CreatedCells because of ColumnVirtualization - var createdCells = new List( parentRow.CreatedCells ); - - foreach( Cell siblingCell in createdCells ) - { - if( ( siblingCell == this ) || ( siblingCell.ReadOnly ) || ( siblingCell.IsBeingEdited ) ) - continue; - - CellValidationError siblingValidationError = siblingCell.ValidationError; - - if( ( siblingValidationError == null ) || ( Cell.GetIsCellEditorError( siblingValidationError ) ) ) - continue; - - siblingCell.IsInCascadingValidation = true; - try - { - Exception exception; - CellValidationRule ruleInError; - siblingCell.ValidateAndSetAllErrors( false, true, updateContentBindingSource, false, out exception, out ruleInError ); - } - finally - { - siblingCell.IsInCascadingValidation = false; - } - } - } - - private void SetAllError( ValidationResult result, Exception validationException, CellValidationRule ruleInError ) - { - bool invalid = ( !result.IsValid ); - - if( invalid ) - { - CellValidationError validationError = new CellValidationError( ruleInError, this, result.ErrorContent, validationException ); - - this.SetValidationError( validationError ); - } - else - { - this.SetValidationError( null ); - } - } - - private ValidationResult ValidateCellRules( out Exception validationException, out CellValidationRule ruleInError ) - { - ValidationResult result = ValidationResult.ValidResult; - ruleInError = null; - validationException = null; - - CellValidationContext cellValidationContext = new CellValidationContext( this.GetRealDataContext(), this ); - - CultureInfo culture = this.Language.GetSpecificCulture(); - - foreach( CellValidationRule cellValidationRule in this.CellValidationRules ) - { - try - { - result = cellValidationRule.Validate( this.Content, culture, cellValidationContext ); - } - catch( Exception exception ) - { - validationException = exception; - result = new ValidationResult( false, exception.Message ); - } - - if( !result.IsValid ) - { - ruleInError = cellValidationRule; - break; - } - } - - ColumnBase parentColumn = this.ParentColumn; - - if( ( parentColumn != null ) && ( result.IsValid ) ) - { - foreach( CellValidationRule cellValidationRule in parentColumn.CellValidationRules ) - { - try - { - result = cellValidationRule.Validate( this.Content, culture, cellValidationContext ); - } - catch( Exception exception ) - { - validationException = exception; - result = new ValidationResult( false, exception.Message ); - } - - if( !result.IsValid ) - { - ruleInError = cellValidationRule; - break; - } - } - } - - return result; - } - - private ValidationResult ValidateContentBindingRules( out Exception validationException, out CellValidationRule ruleInErrorWrapper ) - { - validationException = null; - ruleInErrorWrapper = null; - - ValidationError cellContentBindingValidationError = this.GetContentBindingValidationError(); - - if( cellContentBindingValidationError == null ) - return ValidationResult.ValidResult; - - ruleInErrorWrapper = new CellContentBindingValidationRule( cellContentBindingValidationError.RuleInError ); - validationException = cellContentBindingValidationError.Exception; - - return new ValidationResult( false, cellContentBindingValidationError.ErrorContent ); - } - - private ValidationError GetContentBindingValidationError() - { - BindingExpressionBase contentBindingExpression = this.GetContentBindingExpression(); - - return ( contentBindingExpression != null ) ? contentBindingExpression.ValidationError : null; - } - - private delegate void ClearAllErrorsDelegate(); - - #endregion VALIDATION - - #region INotifyPropertyChanged Members - - public event PropertyChangedEventHandler PropertyChanged; - - private void OnPropertyChanged( string propertyName ) - { - var handler = this.PropertyChanged; - if( handler == null ) - return; - - handler.Invoke( this, new PropertyChangedEventArgs( propertyName ) ); - } - - #endregion - - #region IWeakEventListener Members - - 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( managerType == typeof( PropertyChangedEventManager ) ) - { - var column = sender as ColumnBase; - if( ( column != null ) && ( column == this.ParentColumn ) ) - { - this.OnParentColumnPropertyChanged( ( PropertyChangedEventArgs )e ); - } - } - else - { - return false; - } - - return true; - } - - internal virtual void OnParentColumnPropertyChanged( PropertyChangedEventArgs e ) - { - if( !this.IsContainerPrepared || this.IsContainerVirtualized ) - return; - - var propertyName = e.PropertyName; - - if( string.IsNullOrEmpty( propertyName ) ) - { - if( !this.IsCellEditorDisplayed && ( this.CurrentEditorPendingDisplayState != EditorDisplayState.PendingShow ) ) - { - this.UpdateCoercedContentTemplate( false ); - } - - this.UpdateFocusable(); - this.UpdateMatchingDisplayConditions(); - } - else if( propertyName == ColumnBase.CanBeCurrentWhenReadOnlyProperty.Name ) - { - this.UpdateFocusable(); - } - else if( propertyName == ColumnBase.CellEditorDisplayConditionsProperty.Name ) - { - this.UpdateMatchingDisplayConditions(); - } - else if( ( propertyName == ColumnBase.CellContentTemplateProperty.Name ) - || ( propertyName == ColumnBase.CellContentTemplateSelectorProperty.Name ) ) - { - if( !this.IsCellEditorDisplayed && ( this.CurrentEditorPendingDisplayState != EditorDisplayState.PendingShow ) ) - { - if( ( this.ContentTemplateInternal == null ) && ( this.ContentTemplateSelectorInternal == null ) ) - { - this.UpdateCoercedContentTemplate( false ); - } - } - } - else if( ( propertyName == ColumnBase.CellContentStringFormatProperty.Name ) - || ( propertyName == ColumnBase.DefaultCultureProperty.Name ) - || ( propertyName == Column.ForeignKeyConfigurationProperty.Name ) ) - { - if( !this.IsCellEditorDisplayed && ( this.CurrentEditorPendingDisplayState != EditorDisplayState.PendingShow ) ) - { - this.UpdateCoercedContentTemplate( false ); - } - } - else if( propertyName == ColumnBase.CellEditorSelectorProperty.Name ) - { - //Make sure the editor is refreshed even if it is currently displayed. - m_forceEditorRefresh = true; - this.RefreshDisplayedTemplate(); - m_forceEditorRefresh = false; - } - } - - #endregion - - private KeyActivationGesture m_keyGesture; // = null - private TextCompositionEventArgs m_textInputArgs; // = null - private string m_fieldName; // = string.Empty - private object m_styleBeforeError = DependencyProperty.UnsetValue; - - private RoutedEventHandler m_loadedRoutedEventHandler; // = null; - private DispatcherOperation m_delayedRefreshErrorStyleDispatcherOperation; // = null - private DispatcherOperation m_delayedHideEditTemplateDispatcherOperation; - - private BitVector32 m_flags = new BitVector32(); - private bool m_forceEditorRefresh; - - // Binding used by the animated Column reordering feature - private static Binding ParentColumnTranslationBinding; - private static Binding ParentColumnIsBeingDraggedBinding; - private static Binding ParentColumnReorderingDragSourceManagerBinding; - - private static Binding ParentRowCellContentOpacityBinding; - private ContentPresenter m_cellContentPresenter; - - private int m_preventMakeVisibleCount; // = 0; - private bool m_readOnlyIsInternalySet; - - #region CellFlags Private Type - - [Flags] - private enum CellFlags - { - IsInternalyInitialized = 1, - IsContainerPrepared = 2, - FocusEditor = 4, - IsBeingEdited = 8, - IsCellEditorDisplayed = 16, - PreventValidateAndSetAllErrors = 32, - HasCellEditorError = 64, - HasUIValidationError = 128, - HasContentBindingValidationError = 256, - HasPendingErrorStyleRefresh = 512, - IsErrorStyleApplied = 1024, - HasPendingSyncParentErrorFlags = 2048, - IsUpdatingContentBindingSource = 4096, - IsInCascadingValidation = 8192, - IsRestoringEditionState = 16384, - IsContainerVirtualized = 32768, - AnimatedColumnReorderingBindingApplied = 65536, - PreventMakeVisible = 131072, - IsContainerRecycled = 262144, - IsContainerPartiallyCleared = 524288 - } - - #endregion - - #region EditorDisplayState Private Type - - private enum EditorDisplayState - { - None = 0, - PendingShow, - PendingHide - } - - #endregion - - #region PreventMakeVisibleDisposable Private Class - - private class PreventMakeVisibleDisposable : IDisposable - { - public PreventMakeVisibleDisposable( Cell cell ) - { - if( cell == null ) - throw new ArgumentNullException( "cell" ); - - m_cell = cell; - m_cell.PreventMakeVisible = true; - m_cell.m_preventMakeVisibleCount++; - } - - public void Dispose() - { - if( m_cell == null ) - return; - - m_cell.m_preventMakeVisibleCount--; - - if( m_cell.m_preventMakeVisibleCount == 0 ) - m_cell.PreventMakeVisible = false; - - m_cell = null; - } - - private Cell m_cell; - } - - #endregion - - #region EditorDataTemplate Private Class - - private sealed class EditorDataTemplate : DataTemplate - { - private EditorDataTemplate( DataTemplate viewer, DataTemplate editor ) - { - Debug.Assert( editor != null ); - - m_viewer = viewer; - m_editor = editor; - } - - internal DataTemplate Viewer - { - get - { - return m_viewer; - } - } - - internal DataTemplate Editor - { - get - { - return m_editor; - } - } - - internal static EditorDataTemplate Create( DataTemplate viewer, DataTemplate editor ) - { - var viewerContent = new FrameworkElementFactory( typeof( InnerCellContentPresenter ) ); - viewerContent.SetValue( InnerCellContentPresenter.VisibilityProperty, Visibility.Hidden ); - viewerContent.SetValue( InnerCellContentPresenter.ContentTemplateProperty, viewer ); - - var editorContent = new FrameworkElementFactory( typeof( InnerCellContentPresenter ) ); - editorContent.SetValue( InnerCellContentPresenter.ContentTemplateProperty, editor ); - - var grid = new FrameworkElementFactory( typeof( Grid ) ); - grid.AppendChild( viewerContent ); - grid.AppendChild( editorContent ); - - var template = new EditorDataTemplate( viewer, editor ); - template.VisualTree = grid; - template.Seal(); - - return template; - } - - private readonly DataTemplate m_viewer; - private readonly DataTemplate m_editor; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CellCollection.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CellCollection.cs deleted file mode 100644 index d8a519d0..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CellCollection.cs +++ /dev/null @@ -1,127 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Controls.Primitives; -using System.Windows.Data; -using System.Text; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; - -namespace Xceed.Wpf.DataGrid -{ - public class CellCollection : Collection - { - public CellCollection() - { - } - - internal CellCollection( IList cells ) - : base( cells ) - { - } - - public virtual Cell this[ ColumnBase column ] - { - get - { - int count = this.Count; - - for( int i = 0; i < count; i++ ) - { - Cell cell = this[ i ]; - - if( cell.ParentColumn == column ) - return cell; - } - - return null; - } - } - - public virtual Cell this[ string fieldName ] - { - get - { - int count = this.Count; - - for( int i = 0; i < count; i++ ) - { - Cell cell = this[ i ]; - - if( string.Equals( cell.FieldName, fieldName ) ) - return cell; - } - - return null; - } - } - - protected override void InsertItem( int index, Cell item ) - { - base.InsertItem( index, item ); - } - - protected override void RemoveItem( int index ) - { - base.RemoveItem( index ); - } - - protected override void SetItem( int index, Cell item ) - { - base.SetItem( index, item ); - } - - - protected override void ClearItems() - { - base.ClearItems(); - } - - internal virtual void InternalAdd( Cell cell ) - { - this.Items.Add( cell ); - } - - internal virtual void InternalClear() - { - this.Items.Clear(); - } - - internal virtual void InternalInsert( int index, Cell cell ) - { - this.Items.Insert( index, cell ); - } - - internal virtual void InternalRemove( Cell cell ) - { - this.Items.Remove( cell ); - } - - internal virtual void InternalRemoveAt( int index ) - { - this.Items.RemoveAt( index ); - } - - internal virtual void InternalSetCell( int index, Cell cell ) - { - this.Items[ index ] = cell; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CellContentPresenter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CellContentPresenter.cs deleted file mode 100644 index e0bd4aff..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CellContentPresenter.cs +++ /dev/null @@ -1,105 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; - -namespace Xceed.Wpf.DataGrid -{ - public class CellContentPresenter : ContentPresenter - { - static CellContentPresenter() - { - CellContentPresenter.MinHeightProperty.OverrideMetadata( typeof( CellContentPresenter ), new FrameworkPropertyMetadata( null, new CoerceValueCallback( CellContentPresenter.CoerceMinHeight ) ) ); - TextElement.FontFamilyProperty.OverrideMetadata( typeof( CellContentPresenter ), new FrameworkPropertyMetadata( new PropertyChangedCallback( CellContentPresenter.InvalidateMinHeight ) ) ); - TextElement.FontSizeProperty.OverrideMetadata( typeof( CellContentPresenter ), new FrameworkPropertyMetadata( new PropertyChangedCallback( CellContentPresenter.InvalidateMinHeight ) ) ); - TextElement.FontStretchProperty.OverrideMetadata( typeof( CellContentPresenter ), new FrameworkPropertyMetadata( new PropertyChangedCallback( CellContentPresenter.InvalidateMinHeight ) ) ); - TextElement.FontStyleProperty.OverrideMetadata( typeof( CellContentPresenter ), new FrameworkPropertyMetadata( new PropertyChangedCallback( CellContentPresenter.InvalidateMinHeight ) ) ); - TextElement.FontWeightProperty.OverrideMetadata( typeof( CellContentPresenter ), new FrameworkPropertyMetadata( new PropertyChangedCallback( CellContentPresenter.InvalidateMinHeight ) ) ); - - m_sContentBinding = new Binding(); - m_sContentBinding.RelativeSource = RelativeSource.TemplatedParent; - m_sContentBinding.Mode = BindingMode.OneWay; - m_sContentBinding.Path = new PropertyPath( Cell.ContentProperty ); - - m_sContentTemplateBinding = new Binding(); - m_sContentTemplateBinding.RelativeSource = RelativeSource.TemplatedParent; - m_sContentTemplateBinding.Mode = BindingMode.OneWay; - m_sContentTemplateBinding.Path = new PropertyPath( Cell.CoercedContentTemplateProperty ); - - Binding trimmingBinding = new Binding(); - trimmingBinding.Path = new PropertyPath( "(0).(1).(2)", - Cell.ParentCellProperty, - Cell.ParentColumnProperty, - ColumnBase.TextTrimmingProperty ); - trimmingBinding.Mode = BindingMode.OneWay; - trimmingBinding.RelativeSource = new RelativeSource( RelativeSourceMode.Self ); - - Binding wrappingBinding = new Binding(); - wrappingBinding.Path = new PropertyPath( "(0).(1).(2)", - Cell.ParentCellProperty, - Cell.ParentColumnProperty, - ColumnBase.TextWrappingProperty ); - wrappingBinding.Mode = BindingMode.OneWay; - wrappingBinding.RelativeSource = new RelativeSource( RelativeSourceMode.Self ); - - m_sTextBlockStyle = new Style( typeof( TextBlock ) ); - m_sTextBlockStyle.Setters.Add( new Setter( TextBlock.TextTrimmingProperty, trimmingBinding ) ); - m_sTextBlockStyle.Setters.Add( new Setter( TextBlock.TextWrappingProperty, wrappingBinding ) ); - m_sTextBlockStyle.Seal(); - } - - public CellContentPresenter() - { - this.Resources.Add( typeof( TextBlock ), m_sTextBlockStyle ); - this.DataContext = null; - - this.SetCurrentValue( CellContentPresenter.MinHeightProperty, 0d ); - } - - public override void EndInit() - { - base.EndInit(); - - BindingOperations.SetBinding( this, CellContentPresenter.ContentProperty, m_sContentBinding ); - BindingOperations.SetBinding( this, CellContentPresenter.ContentTemplateProperty, m_sContentTemplateBinding ); - } - - private static object CoerceMinHeight( DependencyObject sender, object value ) - { - var self = sender as CellContentPresenter; - if( self == null ) - return value; - - return self.CoerceMinHeight( new Thickness(), value ); - } - - private static void InvalidateMinHeight( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var self = sender as CellContentPresenter; - if( self == null ) - return; - - self.CoerceValue( CellContentPresenter.MinHeightProperty ); - } - - private static Binding m_sContentTemplateBinding; - private static Binding m_sContentBinding; - private static Style m_sTextBlockStyle; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CellEditor.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CellEditor.cs deleted file mode 100644 index 6be35cc3..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CellEditor.cs +++ /dev/null @@ -1,161 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Windows; -using System.Windows.Input; - -namespace Xceed.Wpf.DataGrid -{ - public class CellEditor: Freezable - { - static CellEditor() - { - CellEditor.ActivationGesturesProperty = CellEditor.ActivationGesturesPropertyKey.DependencyProperty; - } - - public CellEditor() - { - this.SetActivationGestures( new ActivationGestureCollection() ); - } - - public static CellEditor TextBoxEditor - { - get - { - return DefaultCellEditorSelector.TextBoxEditor; - } - } - - public static CellEditor CheckBoxEditor - { - get - { - return DefaultCellEditorSelector.CheckBoxEditor; - } - } - - public static CellEditor DatePickerEditor - { - get - { - return DefaultCellEditorSelector.DateTimeEditor; - } - } - - #region EditTemplate Property - - public static readonly DependencyProperty EditTemplateProperty = - DependencyProperty.Register( "EditTemplate", typeof( DataTemplate ), typeof( CellEditor ), new UIPropertyMetadata( null ) ); - - public DataTemplate EditTemplate - { - get - { - return ( DataTemplate )this.GetValue( CellEditor.EditTemplateProperty ); - } - set - { - this.SetValue( CellEditor.EditTemplateProperty, value ); - } - } - - #endregion EditTemplate Property - - #region ActivationGestures Property - - private static readonly DependencyPropertyKey ActivationGesturesPropertyKey = DependencyProperty.RegisterReadOnly( - "ActivationGestures", - typeof( ActivationGestureCollection ), - typeof( CellEditor ), - new FrameworkPropertyMetadata( ( ActivationGestureCollection )null ) ); - - public static readonly DependencyProperty ActivationGesturesProperty; - - public ActivationGestureCollection ActivationGestures - { - get - { - return (ActivationGestureCollection)this.GetValue( CellEditor.ActivationGesturesProperty ); - } - } - - private void SetActivationGestures( ActivationGestureCollection value ) - { - this.SetValue( CellEditor.ActivationGesturesPropertyKey, value ); - } - - #endregion - - #region HasError Attached Property - - public static readonly DependencyProperty HasErrorProperty = - DependencyProperty.RegisterAttached( "HasError", typeof( bool ), typeof( CellEditor ), new UIPropertyMetadata( false ) ); - - public static bool GetHasError( DependencyObject obj ) - { - return ( bool )obj.GetValue( HasErrorProperty ); - } - - public static void SetHasError( DependencyObject obj, bool value ) - { - obj.SetValue( HasErrorProperty, value ); - } - - #endregion HasError Attached Property - - protected override Freezable CreateInstanceCore() - { - CellEditor editorClone = new CellEditor(); - - foreach( ActivationGesture gesture in this.ActivationGestures ) - { - editorClone.ActivationGestures.Add( gesture.Clone() as ActivationGesture ); - } - - return editorClone; - } - - internal KeyActivationGesture GetMatchingKeyActivationGesture( Key key, Key systemKey, ModifierKeys modifier) - { - foreach( ActivationGesture gesture in this.ActivationGestures ) - { - KeyActivationGesture keyGesture = gesture as KeyActivationGesture; - - if( keyGesture != null ) - { - if( keyGesture.IsActivationKey( key, systemKey, modifier ) == true ) - { - return keyGesture; - } - } - } - - return null; - } - - internal virtual bool IsTextInputActivation() - { - foreach( ActivationGesture gesture in this.ActivationGestures ) - { - if( gesture is TextInputActivationGesture ) - { - return true; - } - } - return false; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CellEditorContext.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CellEditorContext.cs deleted file mode 100644 index b24a929c..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CellEditorContext.cs +++ /dev/null @@ -1,103 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - public class CellEditorContext : DependencyObject - { - #region Constructors - - static CellEditorContext() - { - CellEditorContext.ForeignKeyConfigurationProperty = CellEditorContext.ForeignKeyConfigurationPropertyKey.DependencyProperty; - CellEditorContext.ParentColumnProperty = CellEditorContext.ParentColumnPropertyKey.DependencyProperty; - } - - internal CellEditorContext( ColumnBase parentColumn, ForeignKeyConfiguration configuration ) - { - this.SetParentColumn( parentColumn ); - this.SetForeignKeyConfiguration( configuration ); - } - - #endregion - - #region ForeignKeyConfiguration Property - - private static readonly DependencyPropertyKey ForeignKeyConfigurationPropertyKey = DependencyProperty.RegisterReadOnly( - "ForeignKeyConfiguration", - typeof( ForeignKeyConfiguration ), - typeof( CellEditorContext ), - new PropertyMetadata( null ) ); - - public static readonly DependencyProperty ForeignKeyConfigurationProperty; - - public ForeignKeyConfiguration ForeignKeyConfiguration - { - get - { - return ( ForeignKeyConfiguration )this.GetValue( CellEditorContext.ForeignKeyConfigurationProperty ); - } - } - - private void SetForeignKeyConfiguration( ForeignKeyConfiguration value ) - { - this.SetValue( CellEditorContext.ForeignKeyConfigurationPropertyKey, value ); - } - - private void ClearForeignKeyConfiguration() - { - this.ClearValue( CellEditorContext.ForeignKeyConfigurationPropertyKey ); - } - - #endregion - - #region ParentColumn Property - - private static readonly DependencyPropertyKey ParentColumnPropertyKey = DependencyProperty.RegisterReadOnly( - "ParentColumn", - typeof( ColumnBase ), - typeof( CellEditorContext ), - new PropertyMetadata( null ) ); - - public static readonly DependencyProperty ParentColumnProperty; - - public ColumnBase ParentColumn - { - get - { - return ( ColumnBase )this.GetValue( CellEditorContext.ParentColumnProperty ); - } - } - - private void SetParentColumn( ColumnBase value ) - { - this.SetValue( CellEditorContext.ParentColumnPropertyKey, value ); - } - - private void ClearParentColumn() - { - this.ClearValue( CellEditorContext.ParentColumnPropertyKey ); - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CellEditorSelector.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CellEditorSelector.cs deleted file mode 100644 index 39d6984a..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CellEditorSelector.cs +++ /dev/null @@ -1,26 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -namespace Xceed.Wpf.DataGrid -{ - public abstract class CellEditorSelector - { - public virtual CellEditor SelectCellEditor( ColumnBase column, object item ) - { - return null; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CellState.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CellState.cs deleted file mode 100644 index d91a2e9e..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CellState.cs +++ /dev/null @@ -1,159 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Windows.Controls; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal class CellState - { - public CellState() - { - m_contentBeforeRowEdition = DependencyProperty.UnsetValue; - m_contentBeforeCellEdition = DependencyProperty.UnsetValue; - } - - public CellValidationError CellValidationError - { - get - { - return m_cellValidationError; - } - } - - public bool IsBeingEdited - { - get - { - return m_isBeingEdited; - } - } - - public bool IsDirty - { - get - { - return m_isDirty; - } - } - - #region ContentBeforeRowEdition Read-Only Property - - public object ContentBeforeRowEdition - { - get { return m_contentBeforeRowEdition; } - } - - internal void SetContentBeforeRowEdition( object value ) - { - m_contentBeforeRowEdition = value; - } - - private object m_contentBeforeRowEdition = DependencyProperty.UnsetValue; - - #endregion ContentBeforeRowEdition Read-Only Property - - #region ContentBeforeCellEdition Read-Only Property - - public object ContentBeforeCellEdition - { - get { return m_contentBeforeCellEdition; } - } - - internal void SetContentBeforeCellEdition( object value ) - { - m_contentBeforeCellEdition = value; - } - - private object m_contentBeforeCellEdition = DependencyProperty.UnsetValue; - - #endregion ContentBeforeCellEdition Read-Only Property - - #region Content - - public object Content - { - get { return m_content; } - } - - internal void SetContent( object value ) - { - m_content = value; - } - - private object m_content = DependencyProperty.UnsetValue; - - #endregion Content - - #region IsDirtyBeforeEdition Property - - public Nullable IsDirtyBeforeEdition - { - get - { - return m_isDirtyBeforeEdition; - } - } - - internal void SetIsDirtyBeforeEdition( Nullable value ) - { - m_isDirtyBeforeEdition = value; - } - - private Nullable m_isDirtyBeforeEdition; - - #endregion IsDirtyBeforeEdition Property - - public CellState Clone() - { - CellState cellState = new CellState(); - - cellState.m_content = m_content; - cellState.m_contentBeforeRowEdition = m_contentBeforeRowEdition; - cellState.m_contentBeforeCellEdition = m_contentBeforeCellEdition; - cellState.m_isDirtyBeforeEdition = m_isDirtyBeforeEdition; - - cellState.m_cellValidationError = m_cellValidationError; - cellState.m_isBeingEdited = m_isBeingEdited; - cellState.m_isDirty = m_isDirty; - - return cellState; - } - - internal void SetCellValidationError( CellValidationError value ) - { - m_cellValidationError = value; - } - - internal void SetIsBeingEdited( bool value ) - { - m_isBeingEdited = value; - } - - internal void SetIsDirty( bool value ) - { - m_isDirty = value; - } - - private CellValidationError m_cellValidationError; // = null - private bool m_isBeingEdited; // = false - private bool m_isDirty; // = false - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CellValidationContext.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CellValidationContext.cs deleted file mode 100644 index f4f32c91..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CellValidationContext.cs +++ /dev/null @@ -1,50 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - public class CellValidationContext - { - public CellValidationContext( object dataItem, Cell cell ) - { - m_cell = cell; - m_dataItem = dataItem; - } - - public object DataItem - { - get - { - return m_dataItem; - } - } - - public Cell Cell - { - get - { - return m_cell; - } - } - - private object m_dataItem; - private Cell m_cell; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CellValidationError.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CellValidationError.cs deleted file mode 100644 index 2f215386..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CellValidationError.cs +++ /dev/null @@ -1,78 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using Xceed.Wpf.DataGrid.ValidationRules; -using System.Windows.Controls; - -namespace Xceed.Wpf.DataGrid -{ - public class CellValidationError - { - public CellValidationError( - CellValidationRule ruleInError, - Cell cellInError, - object errorContent, - Exception exception ) - { - m_ruleInError = ruleInError; - m_cellInError = cellInError; - m_errorContent = errorContent; - m_exception = exception; - } - - public CellValidationRule RuleInError - { - get - { - return m_ruleInError; - } - } - - public Cell CellInError - { - get - { - return m_cellInError; - } - } - - public object ErrorContent - { - get - { - return m_errorContent; - } - set - { - m_errorContent = value; - } - } - - public Exception Exception - { - get - { - return m_exception; - } - } - - private CellValidationRule m_ruleInError; - private Cell m_cellInError; - private object m_errorContent; - private Exception m_exception; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CheckBox.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CheckBox.cs deleted file mode 100644 index bf6b17ca..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CheckBox.cs +++ /dev/null @@ -1,303 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; -using System.Security; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Input; -using System.Windows.Automation; - -namespace Xceed.Wpf.DataGrid -{ - [TemplatePart( Name = "PART_ChildCheckBox", Type = typeof( System.Windows.Controls.CheckBox ) )] - public class DataGridCheckBox : ContentControl - { - static DataGridCheckBox() - { - DefaultStyleKeyProperty.OverrideMetadata( typeof( DataGridCheckBox ), new FrameworkPropertyMetadata( typeof( DataGridCheckBox ) ) ); - - AutomationProperties.AutomationIdProperty.OverrideMetadata( typeof( DataGridCheckBox ), new UIPropertyMetadata( "CheckBox" ) ); - - CheckedEvent = System.Windows.Controls.CheckBox.CheckedEvent.AddOwner( typeof( DataGridCheckBox ) ); - UncheckedEvent = System.Windows.Controls.CheckBox.UncheckedEvent.AddOwner( typeof( DataGridCheckBox ) ); - IndeterminateEvent = System.Windows.Controls.CheckBox.IndeterminateEvent.AddOwner( typeof( DataGridCheckBox ) ); - - EventManager.RegisterClassHandler( typeof( DataGridCheckBox ), CheckedEvent, new RoutedEventHandler( CheckBoxEventHandler ) ); - EventManager.RegisterClassHandler( typeof( DataGridCheckBox ), UncheckedEvent, new RoutedEventHandler( CheckBoxEventHandler ) ); - EventManager.RegisterClassHandler( typeof( DataGridCheckBox ), IndeterminateEvent, new RoutedEventHandler( CheckBoxEventHandler ) ); - } - - #region IsChecked Property - - public static readonly DependencyProperty IsCheckedProperty = - System.Windows.Controls.CheckBox.IsCheckedProperty.AddOwner( typeof( DataGridCheckBox ), new FrameworkPropertyMetadata( new PropertyChangedCallback( OnIsCheckedChanged ) ) ); - - [TypeConverter( typeof( NullableBoolConverter ) )] - public Nullable IsChecked - { - get - { - return ( Nullable )this.GetValue( DataGridCheckBox.IsCheckedProperty ); - } - set - { - this.SetValue( DataGridCheckBox.IsCheckedProperty, value ); - } - } - - #endregion IsChecked Property - - #region IsThreeState Property - - public static readonly DependencyProperty IsThreeStateProperty = System.Windows.Controls.CheckBox.IsThreeStateProperty.AddOwner( typeof( DataGridCheckBox ) ); - - public bool IsThreeState - { - get - { - return ( bool )this.GetValue( DataGridCheckBox.IsThreeStateProperty ); - } - set - { - this.SetValue( DataGridCheckBox.IsThreeStateProperty, value ); - } - } - - #endregion IsThreeState Property - - public static readonly RoutedEvent CheckedEvent; - public static readonly RoutedEvent UncheckedEvent; - public static readonly RoutedEvent IndeterminateEvent; - - public event RoutedEventHandler Checked - { - add - { - base.AddHandler( DataGridCheckBox.CheckedEvent, value ); - } - remove - { - base.RemoveHandler( DataGridCheckBox.CheckedEvent, value ); - } - } - - public event RoutedEventHandler Unchecked - { - add - { - base.AddHandler( DataGridCheckBox.UncheckedEvent, value ); - } - remove - { - base.RemoveHandler( DataGridCheckBox.UncheckedEvent, value ); - } - } - - public event RoutedEventHandler Indeterminate - { - add - { - base.AddHandler( DataGridCheckBox.IndeterminateEvent, value ); - } - remove - { - base.RemoveHandler( DataGridCheckBox.IndeterminateEvent, value ); - } - } - - protected override void OnPreviewKeyDown( KeyEventArgs e ) - { - base.OnPreviewKeyDown( e ); - - if( e.Handled == false ) - { - //if this item is the source of the PreviewKeyDown event - if( e.OriginalSource == this && e.IsRepeat == false ) - { - e.Handled = this.ProcessKeyEventArgs( e, this.ChildCheckBox ); - } - } - } - - protected override void OnKeyDown( KeyEventArgs e ) - { - base.OnKeyDown( e ); - - if( e.Handled == false ) - { - if( e.OriginalSource == this && e.IsRepeat == false ) - { - e.Handled = this.ProcessKeyEventArgs( e, this.ChildCheckBox ); - } - } - } - - protected override void OnPreviewKeyUp( KeyEventArgs e ) - { - base.OnPreviewKeyUp( e ); - - if( e.Handled == false ) - { - if( e.OriginalSource == this && e.IsRepeat == false ) - { - e.Handled = this.ProcessKeyEventArgs( e, this.ChildCheckBox ); - } - } - } - - protected override void OnKeyUp( KeyEventArgs e ) - { - base.OnKeyUp( e ); - - if( e.Handled == false ) - { - if( e.OriginalSource == this && e.IsRepeat == false ) - { - e.Handled = this.ProcessKeyEventArgs( e, this.ChildCheckBox ); - } - } - } - - protected override void OnPreviewMouseLeftButtonDown( MouseButtonEventArgs e ) - { - base.OnPreviewMouseLeftButtonDown( e ); - - if( e.Handled == false ) - { - this.Focus(); - - //do not set the e.Handled to true, we want the mouse down event to go as far as possible (true checkbox) - } - } - - private System.Windows.Controls.CheckBox ChildCheckBox - { - get - { - return this.GetTemplateChild( "PART_ChildCheckBox" ) as System.Windows.Controls.CheckBox; - } - } - - private bool ProcessKeyEventArgs( KeyEventArgs e, IInputElement target ) - { - bool retval = false; - - if( target != null ) - { - //foward the event to the child check box - Key realKey; - if( ( e.Key == Key.None ) && ( e.SystemKey != Key.None ) ) - { - realKey = e.SystemKey; - } - else - { - realKey = e.Key; - } - - //in XBAP the Keyboard.PrimaryDevice.ActiveSource will throw ,therefore, protect against the throw and suppress the exception - //if its the one we expect. - try - { - KeyEventArgs kea = new KeyEventArgs( Keyboard.PrimaryDevice, Keyboard.PrimaryDevice.ActiveSource, 0, realKey ); - kea.RoutedEvent = e.RoutedEvent; - - //send the event - target.RaiseEvent( kea ); - - retval = kea.Handled; - } - catch( SecurityException ex ) - { - //if the exception is for the UIPermission, then we want to suppress it - if( ( ex.PermissionType.FullName == "System.Security.Permissions.UIPermission" ) == false ) - { - //not correct type, then rethrow the exception - throw; - } - else //this means that we are in XBAP - { - //we want to handle speciallly the case where the space was pressed (so that checkbox works in XBAP) - //condition taken from the System ChecckBox - if( ( e.RoutedEvent == Keyboard.KeyDownEvent ) - && ( e.Key == Key.Space ) - && ( ( Keyboard.Modifiers & ( ModifierKeys.Control | ModifierKeys.Alt ) ) != ModifierKeys.Alt ) - && ( this.IsMouseCaptured == false ) ) - { - if( this.IsChecked.HasValue == true ) - { - if( this.IsChecked.Value == false ) - { - this.IsChecked = true; - } - else if( this.IsThreeState == false ) - { - this.IsChecked = false; - } - else - { - this.IsChecked = null; - } - } - else - { - this.IsChecked = false; - } - - retval = true; - } - } - } - } - - return retval; - } - - private static void CheckBoxEventHandler( object sender, RoutedEventArgs e ) - { - //this condition detects that the event does not originates from himself and suppress the event if it does... - if( sender != e.OriginalSource ) - { - e.Handled = true; - } - } - - private static void OnIsCheckedChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - DataGridCheckBox obj = ( DataGridCheckBox )sender; - Nullable newValue = ( Nullable )e.NewValue; - - if( newValue.HasValue == true ) - { - if( newValue.GetValueOrDefault() == true ) - { - obj.RaiseEvent( new RoutedEventArgs( DataGridCheckBox.CheckedEvent ) ); - } - else - { - obj.RaiseEvent( new RoutedEventArgs( DataGridCheckBox.UncheckedEvent ) ); - } - } - else - { - obj.RaiseEvent( new RoutedEventArgs( DataGridCheckBox.IndeterminateEvent ) ); - } - } - - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Column.GenericContentTemplateSelectorResources.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Column.GenericContentTemplateSelectorResources.cs deleted file mode 100644 index 448cb17a..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Column.GenericContentTemplateSelectorResources.cs +++ /dev/null @@ -1,28 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal partial class GenericContentTemplateSelectorResources : ResourceDictionary - { - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Column.GenericContentTemplateSelectorResources.xaml b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Column.GenericContentTemplateSelectorResources.xaml deleted file mode 100644 index 7ced3878..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Column.GenericContentTemplateSelectorResources.xaml +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Column.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Column.cs deleted file mode 100644 index 48b7010d..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Column.cs +++ /dev/null @@ -1,363 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.ComponentModel; -using System.Diagnostics; -using System.Windows; -using System.Windows.Data; -using Xceed.Wpf.DataGrid.Utils; - -namespace Xceed.Wpf.DataGrid -{ - [DebuggerDisplay( "FieldName = {FieldName}" )] - public class Column : ColumnBase - { - #region Static Fields - - internal static readonly string AllowSortPropertyName = PropertyHelper.GetPropertyName( ( Column c ) => c.AllowSort ); - internal static readonly string AllowGroupPropertyName = PropertyHelper.GetPropertyName( ( Column c ) => c.AllowGroup ); -#pragma warning disable 618 - internal static readonly string DisplayMemberBindingPropertyName = PropertyHelper.GetPropertyName( ( Column c ) => c.DisplayMemberBinding ); -#pragma warning restore 618 - internal static readonly string DisplayMemberBindingInfoPropertyName = PropertyHelper.GetPropertyName( ( Column c ) => c.DisplayMemberBindingInfo ); - - #endregion - - public Column() - { - } - - [Obsolete( "The DisplayMemberBinding property is obsolete and has been replaced by the DisplayMemberBindingInfo property.", false )] - public Column( string fieldName, object title, BindingBase displayMemberBinding ) - : base( fieldName, title ) - { - this.SetDisplayMemberBinding( displayMemberBinding ); - } - - internal static Column Create( string fieldName, object title, BindingBase displayMemberBinding ) - { - // Disable warning for DisplayMemberBinding when internaly used -#pragma warning disable 618 - var column = new Column( fieldName, title, displayMemberBinding ); -#pragma warning restore 618 - - return column; - } - - #region DisplayMemberBinding Property - - private BindingBase m_displayMemberBinding; // = null - - [Obsolete( "The DisplayMemberBinding property is obsolete and has been replaced by the DisplayMemberBindingInfo property.", false )] - [EditorBrowsable( EditorBrowsableState.Never )] - [Browsable( false )] - public BindingBase DisplayMemberBinding - { - get - { - return m_displayMemberBinding; - } - - set - { - if( value == m_displayMemberBinding ) - return; - - m_displayMemberBinding = value; - - this.OnPropertyChanged( new PropertyChangedEventArgs( Column.DisplayMemberBindingPropertyName ) ); - } - } - - internal BindingBase GetDisplayMemberBinding() - { - // Disable warning for DisplayMemberBinding when internaly used -#pragma warning disable 618 - var value = this.DisplayMemberBinding; -#pragma warning restore 618 - - return value; - } - - internal void SetDisplayMemberBinding( BindingBase value ) - { - // Disable warning for DisplayMemberBinding when internaly used -#pragma warning disable 618 - this.DisplayMemberBinding = value; -#pragma warning restore 618 - } - - #endregion DisplayMemberBinding Property - - #region DisplayMemberBindingInfo Property - - private DataGridBindingInfo m_displayMemberBindingInfo; - - public DataGridBindingInfo DisplayMemberBindingInfo - { - get - { - return m_displayMemberBindingInfo; - } - - set - { - if( value != m_displayMemberBindingInfo ) - { - m_displayMemberBindingInfo = value; - m_displayMemberBinding = m_displayMemberBindingInfo.GetBinding(); - - this.OnPropertyChanged( new PropertyChangedEventArgs( Column.DisplayMemberBindingInfoPropertyName ) ); - } - } - } - - #endregion DisplayMemberBindingInfo Property - - #region AllowSort Property - - public override bool AllowSort - { - get - { - return m_allowSort; - } - set - { - if( m_allowSort == value ) - return; - - m_allowSort = value; - this.OnPropertyChanged( new PropertyChangedEventArgs( Column.AllowSortPropertyName ) ); - } - } - - private bool m_allowSort = true; - - #endregion AllowSort Property - - #region AllowGroup Property - - public override bool AllowGroup - { - get - { - return m_allowGroup; - } - set - { - if( m_allowGroup == value ) - return; - - m_allowGroup = value; - this.OnPropertyChanged( new PropertyChangedEventArgs( Column.AllowGroupPropertyName ) ); - } - } - - private bool m_allowGroup = true; - - #endregion AllowGroup Property - - #region IsAutoCreated Property - - public bool IsAutoCreated - { - get; - internal set; - } - - #endregion IsAutoCreated Property - - #region DistinctValues Property - - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - [Obsolete( "The DistinctValues property is obsolete and has been replaced by the DataGridCollectionView.DistinctValues and DataGridContext.DistinctValues properties.", true )] - public ICollection DistinctValues - { - get - { - return null; - } - } - - #endregion DistinctValues Property - - #region ParentGrid Property - - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - [Obsolete( "The ParentDataGridControl property is obsolete.", true )] - protected DataGridControl ParentDataGridControl - { - get - { - return null; - } - } - - #endregion ParentGrid Property - - #region ForeignKeyConfiguration Property - - internal event EventHandler ForeignKeyConfigurationChanged; - - public static readonly DependencyProperty ForeignKeyConfigurationProperty = DependencyProperty.Register( - "ForeignKeyConfiguration", - typeof( ForeignKeyConfiguration ), - typeof( Column ), - new FrameworkPropertyMetadata( - null, - new PropertyChangedCallback( Column.OnForeignKeyConfigurationChanged ) ) ); - - public ForeignKeyConfiguration ForeignKeyConfiguration - { - get - { - return ( ForeignKeyConfiguration )this.GetValue( Column.ForeignKeyConfigurationProperty ); - } - set - { - this.SetValue( Column.ForeignKeyConfigurationProperty, value ); - } - } - - private static void OnForeignKeyConfigurationChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var column = ( Column )sender; - - column.RaiseForeignKeyConfigurationChanged(); - - if( column.ParentDetailConfiguration != null ) - { - column.ParentDetailConfiguration.SynchronizeForeignKeyConfigurations(); - } - else if( column.DataGridControl != null ) - { - column.DataGridControl.SynchronizeForeignKeyConfigurations(); - } - } - - private void RaiseForeignKeyConfigurationChanged() - { - var handler = this.ForeignKeyConfigurationChanged; - if( handler == null ) - return; - - handler.Invoke( this, EventArgs.Empty ); - } - - #endregion - - #region IsBindingAutoCreated Property - - internal bool IsBindingAutoCreated - { - get - { - return m_isBindingAutoCreated; - } - set - { - m_isBindingAutoCreated = value; - } - } - - private bool m_isBindingAutoCreated; //false - - #endregion - - #region IsBoundToDataGridUnboundItemProperty Property - - internal bool IsBoundToDataGridUnboundItemProperty - { - get - { - return m_isBoundToDataGridUnboundItemProperty; - } - set - { - if( value == m_isBoundToDataGridUnboundItemProperty ) - return; - - m_isBoundToDataGridUnboundItemProperty = value; - this.ResetDefaultCellRecyclingGroup(); - } - } - - private bool m_isBoundToDataGridUnboundItemProperty; //false - - #endregion - -#if DEBUG - public override string ToString() - { - string toString = base.ToString(); - - if( string.IsNullOrEmpty( this.FieldName ) == false ) - toString += " " + this.FieldName; - - return toString; - } -#endif - - internal override object CreateDefaultCellRecyclingGroup() - { - var key = base.CreateDefaultCellRecyclingGroup(); - - if( !this.IsBoundToDataGridUnboundItemProperty ) - return key; - - return new UnboundColumnCellRecyclingGroupKey( key ); - } - - #region UnboundColumnCellRecyclingGroupKey Private Nested Type - - private sealed class UnboundColumnCellRecyclingGroupKey - { - internal UnboundColumnCellRecyclingGroupKey( object key ) - { - m_key = key; - } - - public override int GetHashCode() - { - if( m_key != null ) - return m_key.GetHashCode(); - - return 0; - } - - public override bool Equals( object obj ) - { - UnboundColumnCellRecyclingGroupKey key = obj as UnboundColumnCellRecyclingGroupKey; - if( key == null ) - return false; - - if( key == this ) - return true; - - return object.Equals( key.m_key, m_key ); - } - - private readonly object m_key; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnAddGroupCommand.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnAddGroupCommand.cs deleted file mode 100644 index 9b4660e5..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnAddGroupCommand.cs +++ /dev/null @@ -1,116 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Collections.ObjectModel; -using System.ComponentModel; - -namespace Xceed.Wpf.DataGrid -{ - internal abstract class ColumnAddGroupCommand : ColumnGroupCommand - { - #region GroupDescriptions Protected Property - - protected abstract ObservableCollection GroupDescriptions - { - get; - } - - #endregion - - public bool CanExecute( ColumnBase column ) - { - return this.CanExecute( column, -1 ); - } - - public bool CanExecute( ColumnBase column, int index ) - { - return ( column != null ) - && ( this.CanExecuteCore( column, index ) ); - } - - public void Execute( ColumnBase column ) - { - this.Execute( column, -1 ); - } - - public void Execute( ColumnBase column, int index ) - { - if( !this.CanExecute( column, index ) ) - return; - - this.ExecuteCore( column, index ); - } - - protected virtual string GetColumnName( ColumnBase column ) - { - return column.FieldName; - } - - protected virtual GroupDescription GetGroupDescription( ColumnBase column ) - { - return column.GroupDescription; - } - - protected virtual GroupConfiguration GetGroupConfiguration( ColumnBase column ) - { - return column.GroupConfiguration; - } - - protected virtual bool CanExecuteCore( ColumnBase column, int index ) - { - return ( this.GroupDescriptions != null ) - && ( !string.IsNullOrEmpty( this.GetColumnName( column ) ) ); - } - - protected virtual void ExecuteCore( ColumnBase column, int index ) - { - var groupDescriptions = this.GroupDescriptions; - if( groupDescriptions == null ) - return; - - GroupDescription groupDescription = this.GetGroupDescription( column ); - if( groupDescription == null ) - { - groupDescription = new DataGridGroupDescription( this.GetColumnName( column ) ); - } - - var dataGridGroupDescription = groupDescription as DataGridGroupDescription; - if( ( dataGridGroupDescription != null ) && ( dataGridGroupDescription.GroupConfiguration == null ) ) - { - dataGridGroupDescription.GroupConfiguration = this.GetGroupConfiguration( column ); - } - - if( index < 0 ) - { - groupDescriptions.Add( groupDescription ); - } - else - { - groupDescriptions.Insert( index, groupDescription ); - } - } - - protected sealed override bool CanExecuteImpl( object parameter ) - { - return this.CanExecute( parameter as ColumnBase ); - } - - protected sealed override void ExecuteImpl( object parameter ) - { - this.Execute( parameter as ColumnBase ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnBase.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnBase.cs deleted file mode 100644 index a9968741..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnBase.cs +++ /dev/null @@ -1,1873 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Diagnostics; -using System.Globalization; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using Xceed.Wpf.DataGrid.Utils; -using Xceed.Wpf.DataGrid.ValidationRules; -using Xceed.Wpf.DataGrid.Views; - -namespace Xceed.Wpf.DataGrid -{ - [DebuggerDisplay( "FieldName = {FieldName}" )] - public abstract class ColumnBase : Freezable, INotifyPropertyChanged, IWeakEventListener - { - static ColumnBase() - { - ColumnBase.IsFirstVisibleProperty = ColumnBase.IsFirstVisiblePropertyKey.DependencyProperty; - ColumnBase.IsLastVisibleProperty = ColumnBase.IsLastVisiblePropertyKey.DependencyProperty; - } - - protected ColumnBase() - { - // Set the ActualWidth "default" value. - this.UpdateActualWidth(); - } - - protected ColumnBase( string fieldName, object title ) - : this() - { - this.FieldName = fieldName; - this.Title = title; - } - - #region Description Property - - public static readonly DependencyProperty DescriptionProperty = DependencyProperty.Register( - "Description", - typeof( string ), - typeof( ColumnBase ), - new UIPropertyMetadata( null ) ); - - public string Description - { - get - { - return ( string )this.GetValue( ColumnBase.DescriptionProperty ); - } - set - { - this.SetValue( ColumnBase.DescriptionProperty, value ); - } - } - - #endregion - - #region CellContentTemplate Property - - public static readonly DependencyProperty CellContentTemplateProperty = DependencyProperty.Register( - "CellContentTemplate", - typeof( DataTemplate ), - typeof( ColumnBase ), - new FrameworkPropertyMetadata( null, new PropertyChangedCallback( ColumnBase.OnCellContentTemplateChanged ) ) ); - - public DataTemplate CellContentTemplate - { - get - { - return ( DataTemplate )this.GetValue( ColumnBase.CellContentTemplateProperty ); - } - set - { - this.SetValue( ColumnBase.CellContentTemplateProperty, value ); - } - } - - private static void OnCellContentTemplateChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var self = sender as ColumnBase; - if( self == null ) - return; - - //Make sure cells pertaining to this group are assigned to the correct recycle bin. - //The recycle bin based on the previous key value will be clean up later by the FixedCellPanel, if no other column uses it. - self.ResetDefaultCellRecyclingGroup(); - } - - #endregion - - #region CellContentTemplateSelector Property - - public static readonly DependencyProperty CellContentTemplateSelectorProperty = DependencyProperty.Register( - "CellContentTemplateSelector", - typeof( DataTemplateSelector ), - typeof( ColumnBase ), - new FrameworkPropertyMetadata( GenericContentTemplateSelector.Instance, new PropertyChangedCallback( ColumnBase.OnCellContentTemplateSelectorChanged ) ) ); - - public DataTemplateSelector CellContentTemplateSelector - { - get - { - return ( DataTemplateSelector )this.GetValue( ColumnBase.CellContentTemplateSelectorProperty ); - } - set - { - this.SetValue( ColumnBase.CellContentTemplateSelectorProperty, value ); - } - } - - private static void OnCellContentTemplateSelectorChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var self = sender as ColumnBase; - if( self == null ) - return; - - //Make sure cells pertaining to this group are assigned to the correct recycle bin. - //The recycle bin based on the previous key value will be clean up later by the FixedCellPanel, if no other column uses it. - self.ResetDefaultCellRecyclingGroup(); - } - - #endregion - - #region CellHorizontalContentAlignment Property - - public static readonly DependencyProperty CellHorizontalContentAlignmentProperty = DependencyProperty.Register( - "CellHorizontalContentAlignment", - typeof( HorizontalAlignment ), - typeof( ColumnBase ), - new FrameworkPropertyMetadata( HorizontalAlignment.Stretch ) ); - - public HorizontalAlignment CellHorizontalContentAlignment - { - get - { - return ( HorizontalAlignment )this.GetValue( ColumnBase.CellHorizontalContentAlignmentProperty ); - } - set - { - this.SetValue( ColumnBase.CellHorizontalContentAlignmentProperty, value ); - } - } - - #endregion - - #region CellVerticalContentAlignment Property - - public static readonly DependencyProperty CellVerticalContentAlignmentProperty = DependencyProperty.Register( - "CellVerticalContentAlignment", - typeof( VerticalAlignment ), - typeof( ColumnBase ), - new FrameworkPropertyMetadata( VerticalAlignment.Stretch ) ); - - public VerticalAlignment CellVerticalContentAlignment - { - get - { - return ( VerticalAlignment )this.GetValue( ColumnBase.CellVerticalContentAlignmentProperty ); - } - set - { - this.SetValue( ColumnBase.CellVerticalContentAlignmentProperty, value ); - } - } - - #endregion - - #region CellContentStringFormat Property - - public static readonly DependencyProperty CellContentStringFormatProperty = DependencyProperty.Register( - "CellContentStringFormat", - typeof( string ), - typeof( ColumnBase ), - new FrameworkPropertyMetadata( null ) ); - - public string CellContentStringFormat - { - get - { - return ( string )this.GetValue( ColumnBase.CellContentStringFormatProperty ); - } - set - { - this.SetValue( ColumnBase.CellContentStringFormatProperty, value ); - } - } - - #endregion - - #region Title Property - - public static readonly DependencyProperty TitleProperty = DependencyProperty.Register( - "Title", - typeof( object ), - typeof( ColumnBase ), - new UIPropertyMetadata( null ) ); - - public object Title - { - get - { - return this.GetValue( ColumnBase.TitleProperty ); - } - set - { - this.SetValue( ColumnBase.TitleProperty, value ); - } - } - - #endregion - - #region TitleTemplate Property - - public static readonly DependencyProperty TitleTemplateProperty = DependencyProperty.Register( - "TitleTemplate", - typeof( DataTemplate ), - typeof( ColumnBase ), - new UIPropertyMetadata( null ) ); - - public DataTemplate TitleTemplate - { - get - { - return ( DataTemplate )this.GetValue( ColumnBase.TitleTemplateProperty ); - } - set - { - this.SetValue( ColumnBase.TitleTemplateProperty, value ); - } - } - - #endregion - - #region TitleTemplateSelector Property - - public static readonly DependencyProperty TitleTemplateSelectorProperty = DependencyProperty.Register( - "TitleTemplateSelector", - typeof( DataTemplateSelector ), - typeof( ColumnBase ), - new UIPropertyMetadata( null ) ); - - public DataTemplateSelector TitleTemplateSelector - { - get - { - return ( DataTemplateSelector )this.GetValue( ColumnBase.TitleTemplateSelectorProperty ); - } - set - { - this.SetValue( ColumnBase.TitleTemplateSelectorProperty, value ); - } - } - - #endregion - - #region ActualWidth Property - - private static readonly DependencyPropertyKey ActualWidthPropertyKey = DependencyProperty.RegisterReadOnly( - "ActualWidth", - typeof( double ), - typeof( ColumnBase ), - new PropertyMetadata( ColumnBase.OnActualWidthChanged ) ); - - public static readonly DependencyProperty ActualWidthProperty = ColumnBase.ActualWidthPropertyKey.DependencyProperty; - - public double ActualWidth - { - get - { - return ( double )this.GetValue( ColumnBase.ActualWidthProperty ); - } - } - - private static void OnActualWidthChanged( DependencyObject o, DependencyPropertyChangedEventArgs e ) - { - var column = o as ColumnBase; - if( column == null ) - return; - - var handler = column.ActualWidthChanged; - if( handler != null ) - { - handler.Invoke( column, new ColumnActualWidthChangedEventArgs( column, ( double )e.OldValue, ( double )e.NewValue ) ); - } - } - - private void UpdateActualWidth() - { - var width = this.Width; - var actualWidth = ( ( width.UnitType == ColumnWidthUnitType.Pixel ) ? width.Value : ( ( ColumnWidth )ColumnBase.WidthProperty.DefaultMetadata.DefaultValue ).Value ); - var maxWidth = this.MaxWidth; - var minWidth = this.MinWidth; - var useDesiredWidth = false; - - if( this.DesiredWidth >= 0d ) - { - actualWidth = this.DesiredWidth; - useDesiredWidth = true; - } - - if( actualWidth > maxWidth ) - { - actualWidth = maxWidth; - } - - // If Width is set to a value lesser than MinWidth or, if MaxWidth is inferior to - // MinWidth, ActualWidth will become equal to MinWidth. - if( actualWidth < minWidth ) - { - actualWidth = minWidth; - } - - this.SetValue( ColumnBase.ActualWidthPropertyKey, actualWidth ); - - if( ( minWidth >= maxWidth ) || ( useDesiredWidth ) ) - { - this.HasFixedWidth = true; - } - else - { - this.ClearValue( ColumnBase.HasFixedWidthPropertyKey ); - } - } - - #endregion - - #region Width Property - - public static readonly DependencyProperty WidthProperty = DependencyProperty.Register( - "Width", - typeof( ColumnWidth ), - typeof( ColumnBase ), - new PropertyMetadata( new ColumnWidth( 125d ), new PropertyChangedCallback( ColumnBase.WidthChanged ) ) ); - - public ColumnWidth Width - { - get - { - return ( ColumnWidth )this.GetValue( ColumnBase.WidthProperty ); - } - set - { - this.SetValue( ColumnBase.WidthProperty, value ); - } - } - - private static void WidthChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var column = ( ColumnBase )sender; - - if( e.Property == ColumnBase.WidthProperty ) - { - var oldValue = ( ColumnWidth )e.OldValue; - var newValue = ( ColumnWidth )e.NewValue; - - if( ( oldValue.UnitType == ColumnWidthUnitType.Star ) && - ( newValue.UnitType == ColumnWidthUnitType.Pixel ) ) - { - // If the old width was a star, reset the desired width before updating the - // ActualWidth. Otherwise, ActualWidth would still return the old desired width. - column.ClearValue( ColumnBase.DesiredWidthProperty ); - } - else if( newValue.UnitType == ColumnWidthUnitType.Star ) - { - // Assign a temporary value to DesiredWidth (different from ActualWidth) - // to force a new Measure pass. Mandatory, for instance, when the old star - // value was limited by a MaxValue and the new star value would give a - // smaller value to DesiredWidth. - var oldActualWidth = column.ActualWidth; - - if( column.ActualWidth > column.MinWidth ) - { - column.DesiredWidth = column.MinWidth; - } - else - { - column.DesiredWidth = column.ActualWidth + 1d; - } - } - } - - column.UpdateActualWidth(); - } - - #endregion - - #region MinWidth Property - - public static readonly DependencyProperty MinWidthProperty = FrameworkElement.MinWidthProperty.AddOwner( typeof( ColumnBase ), new PropertyMetadata( new PropertyChangedCallback( ColumnBase.WidthChanged ) ) ); - - public double MinWidth - { - get - { - return ( double )this.GetValue( ColumnBase.MinWidthProperty ); - } - set - { - this.SetValue( ColumnBase.MinWidthProperty, value ); - } - } - - #endregion - - #region MaxWidth Property - - public static readonly DependencyProperty MaxWidthProperty = FrameworkElement.MaxWidthProperty.AddOwner( typeof( ColumnBase ), new PropertyMetadata( new PropertyChangedCallback( ColumnBase.WidthChanged ) ) ); - - public double MaxWidth - { - get - { - return ( double )this.GetValue( ColumnBase.MaxWidthProperty ); - } - set - { - this.SetValue( ColumnBase.MaxWidthProperty, value ); - } - } - - #endregion - - #region DesiredWidth Property - - internal static readonly DependencyProperty DesiredWidthProperty = DependencyProperty.Register( "DesiredWidth", typeof( double ), typeof( ColumnBase ), new PropertyMetadata( -1d, new PropertyChangedCallback( ColumnBase.WidthChanged ) ) ); - - internal double DesiredWidth - { - get - { - return ( double )this.GetValue( ColumnBase.DesiredWidthProperty ); - } - set - { - this.SetValue( ColumnBase.DesiredWidthProperty, value ); - } - } - - #endregion - - #region TextTrimming Property - - public static readonly DependencyProperty TextTrimmingProperty = DependencyProperty.Register( - "TextTrimming", - typeof( TextTrimming ), - typeof( ColumnBase ), - new UIPropertyMetadata( TextTrimming.CharacterEllipsis ) ); - - public TextTrimming TextTrimming - { - get - { - return ( TextTrimming )this.GetValue( ColumnBase.TextTrimmingProperty ); - } - set - { - this.SetValue( ColumnBase.TextTrimmingProperty, value ); - } - } - - #endregion - - #region TextWrapping Property - - public static readonly DependencyProperty TextWrappingProperty = DependencyProperty.Register( - "TextWrapping", - typeof( TextWrapping ), - typeof( ColumnBase ), - new UIPropertyMetadata( TextWrapping.NoWrap ) ); - - public TextWrapping TextWrapping - { - get - { - return ( TextWrapping )this.GetValue( ColumnBase.TextWrappingProperty ); - } - set - { - this.SetValue( ColumnBase.TextWrappingProperty, value ); - } - } - - #endregion - - #region HasFixedWidth Read-Only Property - - private static readonly DependencyPropertyKey HasFixedWidthPropertyKey = DependencyProperty.RegisterReadOnly( - "HasFixedWidth", - typeof( bool ), - typeof( ColumnBase ), - new PropertyMetadata( false ) ); - - public static readonly DependencyProperty HasFixedWidthProperty = ColumnBase.HasFixedWidthPropertyKey.DependencyProperty; - - public bool HasFixedWidth - { - get - { - return ( bool )this.GetValue( ColumnBase.HasFixedWidthProperty ); - } - private set - { - this.SetValue( ColumnBase.HasFixedWidthPropertyKey, value ); - } - } - - #endregion - - #region VisiblePosition Property - - public static readonly DependencyProperty VisiblePositionProperty = DependencyProperty.Register( - "VisiblePosition", - typeof( int ), - typeof( ColumnBase ), - new UIPropertyMetadata( int.MaxValue, new PropertyChangedCallback( ColumnBase.OnVisiblePositionChanged ), new CoerceValueCallback( ColumnBase.OnCoerceVisiblePosition ) ) ); - - public int VisiblePosition - { - get - { - return ( int )this.GetValue( ColumnBase.VisiblePositionProperty ); - } - set - { - this.SetValue( ColumnBase.VisiblePositionProperty, value ); - } - } - - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly" )] - private static object OnCoerceVisiblePosition( DependencyObject sender, object value ) - { - var newValue = ( int )value; - if( newValue < 0 ) - throw new ArgumentOutOfRangeException( "VisiblePosition", "VisiblePosition must be greater than or equal to zero." ); - - var column = ( ColumnBase )sender; - - if( !column.m_inhibitVisiblePositionChanging.IsSet ) - { - var oldValue = column.VisiblePosition; - - if( newValue != oldValue ) - { - var handler = column.VisiblePositionChanging; - if( handler != null ) - { - handler.Invoke( sender, EventArgs.Empty ); - } - } - } - - return value; - } - - private static void OnVisiblePositionChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var column = ( ColumnBase )sender; - var oldValue = ( int )e.OldValue; - var newValue = ( int )e.NewValue; - - var handler = column.VisiblePositionChanged; - if( handler != null ) - { - handler.Invoke( column, new ColumnVisiblePositionChangedEventArgs( column, oldValue, newValue ) ); - } - - // Invalidate own PreviousVisibleColumnProperty - column.InvalidatePreviousVisibleColumnProperty(); - - // Also invalidate next visible column's PreviousVisibleColumnProperty - var nextVisibleColumn = column.NextVisibleColumn; - - if( nextVisibleColumn != null ) - { - nextVisibleColumn.InvalidatePreviousVisibleColumnProperty(); - } - } - - internal IDisposable InhibitVisiblePositionChanging() - { - return m_inhibitVisiblePositionChanging.Set(); - } - - internal event EventHandler VisiblePositionChanging; - internal event EventHandler VisiblePositionChanged; - - private readonly AutoResetFlag m_inhibitVisiblePositionChanging = AutoResetFlagFactory.Create( false ); - - #endregion - - #region IsFirstVisible Read-Only Property - - private static readonly DependencyPropertyKey IsFirstVisiblePropertyKey = DependencyProperty.RegisterReadOnly( - "IsFirstVisible", - typeof( bool ), - typeof( ColumnBase ), - new PropertyMetadata( false ) ); - - public static readonly DependencyProperty IsFirstVisibleProperty; - - public bool IsFirstVisible - { - get - { - return ( bool )this.GetValue( ColumnBase.IsFirstVisibleProperty ); - } - } - - internal void SetIsFirstVisible( bool value ) - { - this.SetValue( ColumnBase.IsFirstVisiblePropertyKey, value ); - } - - internal void ClearIsFirstVisible() - { - this.ClearValue( ColumnBase.IsFirstVisiblePropertyKey ); - } - - #endregion - - #region IsLastVisible Read-Only Property - - private static readonly DependencyPropertyKey IsLastVisiblePropertyKey = DependencyProperty.RegisterReadOnly( - "IsLastVisible", - typeof( bool ), - typeof( ColumnBase ), - new PropertyMetadata( false ) ); - - public static readonly DependencyProperty IsLastVisibleProperty; - - public bool IsLastVisible - { - get - { - return ( bool )this.GetValue( ColumnBase.IsLastVisibleProperty ); - } - } - - internal void SetIsLastVisible( bool value ) - { - this.SetValue( ColumnBase.IsLastVisiblePropertyKey, value ); - } - - internal void ClearIsLastVisible() - { - this.ClearValue( ColumnBase.IsLastVisiblePropertyKey ); - } - - #endregion - - #region FieldName Property - - public static readonly DependencyProperty FieldNameProperty = DependencyProperty.Register( - "FieldName", - typeof( string ), - typeof( ColumnBase ), - new UIPropertyMetadata( - null, - null, - new CoerceValueCallback( ColumnBase.OnCoerceFieldName ) ) ); - - public string FieldName - { - get - { - return ( string )this.GetValue( ColumnBase.FieldNameProperty ); - } - set - { - this.SetValue( ColumnBase.FieldNameProperty, value ); - } - } - - private static object OnCoerceFieldName( DependencyObject sender, object requestedValue ) - { - var column = sender as ColumnBase; - if( ( column.m_containingCollection != null ) && ( !DesignerProperties.GetIsInDesignMode( column ) ) ) - throw new InvalidOperationException( "An attempt was made to change the FieldName of a column that is contained in a grid." ); - - return requestedValue; - } - - #endregion - - #region Visible Property - - public static readonly DependencyProperty VisibleProperty = DependencyProperty.Register( - "Visible", - typeof( bool ), - typeof( ColumnBase ), - new UIPropertyMetadata( true ) ); - - public bool Visible - { - get - { - return ( bool )this.GetValue( ColumnBase.VisibleProperty ); - } - set - { - this.SetValue( ColumnBase.VisibleProperty, value ); - } - } - - #endregion - - #region Index Property - - public int Index - { - get - { - if( m_containingCollection == null ) - return -1; - - return m_containingCollection.IndexOf( this ); - } - } - - #endregion - - #region DataGridControl Property - - public DataGridControl DataGridControl - { - get - { - if( m_containingCollection == null ) - return null; - - return m_containingCollection.DataGridControl; - } - } - - internal void NotifyDataGridControlChanged() - { - this.OnPropertyChanged( new PropertyChangedEventArgs( ColumnBase.DataGridControlPropertyName ) ); - } - - internal static readonly string DataGridControlPropertyName = PropertyHelper.GetPropertyName( ( ColumnBase c ) => c.DataGridControl ); - - #endregion - - #region ParentDetailConfiguration Property - - internal DetailConfiguration ParentDetailConfiguration - { - get - { - if( m_containingCollection == null ) - return null; - - return m_containingCollection.ParentDetailConfiguration; - } - } - - #endregion - - #region ContainingCollection Property - - internal ColumnCollection ContainingCollection - { - get - { - return m_containingCollection; - } - } - - private ColumnCollection m_containingCollection; //null - - #endregion - - #region AllowSort Property - - public virtual bool AllowSort - { - get - { - return false; - } - set - { - throw new NotSupportedException( "An attempt was made to set the AllowSort property of a column that does not support sorting." ); - } - } - - #endregion - - #region AllowGroup Property - - public virtual bool AllowGroup - { - get - { - return false; - } - set - { - throw new NotSupportedException( "An attempt was made to set the AllowGroup property of a column that does not support grouping." ); - } - } - - #endregion - - #region GroupValueTemplate Property - - public static readonly DependencyProperty GroupValueTemplateProperty = DependencyProperty.Register( - "GroupValueTemplate", - typeof( DataTemplate ), - typeof( ColumnBase ), - new FrameworkPropertyMetadata( null ) ); - - public DataTemplate GroupValueTemplate - { - get - { - return ( DataTemplate )this.GetValue( ColumnBase.GroupValueTemplateProperty ); - } - set - { - this.SetValue( ColumnBase.GroupValueTemplateProperty, value ); - } - } - - #endregion - - #region GroupValueTemplateSelector Property - - public static readonly DependencyProperty GroupValueTemplateSelectorProperty = DependencyProperty.Register( - "GroupValueTemplateSelector", - typeof( DataTemplateSelector ), - typeof( ColumnBase ), - new FrameworkPropertyMetadata( null ) ); - - public DataTemplateSelector GroupValueTemplateSelector - { - get - { - return ( DataTemplateSelector )this.GetValue( ColumnBase.GroupValueTemplateSelectorProperty ); - } - set - { - this.SetValue( ColumnBase.GroupValueTemplateSelectorProperty, value ); - } - } - - #endregion - - #region GroupValueStringFormat Property - - public static readonly DependencyProperty GroupValueStringFormatProperty = DependencyProperty.Register( - "GroupValueStringFormat", - typeof( string ), - typeof( ColumnBase ), - new FrameworkPropertyMetadata( null ) ); - - public string GroupValueStringFormat - { - get - { - return ( string )this.GetValue( ColumnBase.GroupValueStringFormatProperty ); - } - set - { - this.SetValue( ColumnBase.GroupValueStringFormatProperty, value ); - } - } - - #endregion - - #region CellEditor Property - - public static readonly DependencyProperty CellEditorProperty = DependencyProperty.Register( - "CellEditor", - typeof( CellEditor ), - typeof( ColumnBase ), - new UIPropertyMetadata( null ) ); - - public CellEditor CellEditor - { - get - { - return ( CellEditor )this.GetValue( ColumnBase.CellEditorProperty ); - } - set - { - this.SetValue( ColumnBase.CellEditorProperty, value ); - } - } - - #endregion - - #region CellEditorSelector Property - - public static readonly DependencyProperty CellEditorSelectorProperty = DependencyProperty.Register( - "CellEditorSelector", - typeof( CellEditorSelector ), - typeof( ColumnBase ), - new FrameworkPropertyMetadata( null ) ); - - public CellEditorSelector CellEditorSelector - { - get - { - return ( CellEditorSelector )this.GetValue( ColumnBase.CellEditorSelectorProperty ); - } - set - { - this.SetValue( ColumnBase.CellEditorSelectorProperty, value ); - } - } - - #endregion - - #region CellEditorDisplayConditions Property - - public static readonly DependencyProperty CellEditorDisplayConditionsProperty = DataGridControl.CellEditorDisplayConditionsProperty.AddOwner( typeof( ColumnBase ) ); - - public CellEditorDisplayConditions CellEditorDisplayConditions - { - get - { - return ( CellEditorDisplayConditions )this.GetValue( ColumnBase.CellEditorDisplayConditionsProperty ); - } - set - { - this.SetValue( ColumnBase.CellEditorDisplayConditionsProperty, value ); - } - } - - #endregion - - #region CellValidationRules Property - - public Collection CellValidationRules - { - get - { - if( m_cellValidationRules == null ) - { - m_cellValidationRules = new Collection(); - } - - return m_cellValidationRules; - } - } - - private Collection m_cellValidationRules; // = null - - #endregion - - #region CellErrorStyle Property - - public static readonly DependencyProperty CellErrorStyleProperty = DataGridControl.CellErrorStyleProperty.AddOwner( typeof( ColumnBase ) ); - - public Style CellErrorStyle - { - get - { - return ( Style )this.GetValue( ColumnBase.CellErrorStyleProperty ); - } - - set - { - this.SetValue( ColumnBase.CellErrorStyleProperty, value ); - } - } - - #endregion - - #region CanBeCurrentWhenReadOnly Property - - public static readonly DependencyProperty CanBeCurrentWhenReadOnlyProperty = DependencyProperty.Register( - "CanBeCurrentWhenReadOnly", - typeof( bool ), - typeof( ColumnBase ), - new FrameworkPropertyMetadata( true ) ); - - public bool CanBeCurrentWhenReadOnly - { - get - { - return ( bool )this.GetValue( ColumnBase.CanBeCurrentWhenReadOnlyProperty ); - } - set - { - this.SetValue( ColumnBase.CanBeCurrentWhenReadOnlyProperty, value ); - } - } - - #endregion - - #region HasValidationError Property - - private static readonly DependencyPropertyKey HasValidationErrorPropertyKey = DependencyProperty.RegisterReadOnly( - "HasValidationError", - typeof( bool ), - typeof( ColumnBase ), - new UIPropertyMetadata( false ) ); - - public static readonly DependencyProperty HasValidationErrorProperty = ColumnBase.HasValidationErrorPropertyKey.DependencyProperty; - - public bool HasValidationError - { - get - { - return ( bool )this.GetValue( ColumnBase.HasValidationErrorProperty ); - } - } - - internal void SetHasValidationError( bool value ) - { - if( value != this.HasValidationError ) - { - if( value ) - { - this.SetValue( ColumnBase.HasValidationErrorPropertyKey, value ); - } - else - { - this.ClearValue( ColumnBase.HasValidationErrorPropertyKey ); - } - } - } - - #endregion - - #region SortDirection Property - - private static readonly DependencyPropertyKey SortDirectionPropertyKey = DependencyProperty.RegisterReadOnly( - "SortDirection", - typeof( SortDirection ), - typeof( ColumnBase ), - new PropertyMetadata( SortDirection.None ) ); - - public static readonly DependencyProperty SortDirectionProperty = ColumnBase.SortDirectionPropertyKey.DependencyProperty; - - public SortDirection SortDirection - { - get - { - return ( SortDirection )this.GetValue( ColumnBase.SortDirectionProperty ); - } - } - - internal void SetSortDirection( SortDirection value ) - { - if( value == SortDirection.None ) - { - this.ClearValue( ColumnBase.SortDirectionPropertyKey ); - } - else - { - this.SetValue( ColumnBase.SortDirectionPropertyKey, value ); - } - } - - #endregion - - #region SortDirectionCycle Property - - private static readonly SortDirectionCycleCollection DefaultSortDirectionCycle = new SortDirectionCycleCollection( - new ReadOnlyCollection( - new List() - { - SortDirection.Ascending, - SortDirection.Descending, - SortDirection.None, - } ) ); - - public static readonly DependencyProperty SortDirectionCycleProperty = DependencyProperty.Register( - "SortDirectionCycle", - typeof( SortDirectionCycleCollection ), - typeof( ColumnBase ), - new PropertyMetadata( ColumnBase.DefaultSortDirectionCycle ) ); - - public SortDirectionCycleCollection SortDirectionCycle - { - get - { - return ( SortDirectionCycleCollection )this.GetValue( ColumnBase.SortDirectionCycleProperty ); - } - set - { - this.SetValue( ColumnBase.SortDirectionCycleProperty, value ); - } - } - - #endregion - - #region SortIndex Read-Only Property - - private static readonly DependencyPropertyKey SortIndexPropertyKey = DependencyProperty.RegisterReadOnly( - "SortIndex", - typeof( int ), - typeof( ColumnBase ), - new PropertyMetadata( -1 ) ); - - public static readonly DependencyProperty SortIndexProperty = ColumnBase.SortIndexPropertyKey.DependencyProperty; - - public int SortIndex - { - get - { - return ( int )this.GetValue( ColumnBase.SortIndexProperty ); - } - } - - internal void SetSortIndex( int value ) - { - if( value == -1 ) - { - this.ClearValue( ColumnBase.SortIndexPropertyKey ); - } - else - { - this.SetValue( ColumnBase.SortIndexPropertyKey, value ); - } - } - - #endregion - - #region GroupDescription Property - - public static readonly DependencyProperty GroupDescriptionProperty = DependencyProperty.Register( - "GroupDescription", - typeof( GroupDescription ), - typeof( ColumnBase ), - new UIPropertyMetadata( null ) ); - - public GroupDescription GroupDescription - { - get - { - return ( GroupDescription )GetValue( ColumnBase.GroupDescriptionProperty ); - } - set - { - SetValue( ColumnBase.GroupDescriptionProperty, value ); - } - } - - #endregion - - #region GroupConfiguration Property - - public static readonly DependencyProperty GroupConfigurationProperty = DependencyProperty.Register( - "GroupConfiguration", - typeof( GroupConfiguration ), - typeof( ColumnBase ), - new UIPropertyMetadata( null ) ); - - public GroupConfiguration GroupConfiguration - { - get - { - return ( GroupConfiguration )this.GetValue( ColumnBase.GroupConfigurationProperty ); - } - set - { - this.SetValue( ColumnBase.GroupConfigurationProperty, value ); - } - } - - #endregion - - #region IsMainColumn Property - - public virtual bool IsMainColumn - { - get - { - var containingCollection = this.ContainingCollection; - if( containingCollection == null ) - return ( m_isMainColumn.HasValue ? m_isMainColumn.Value : false ); - - return ( containingCollection.MainColumn == this ); - } - set - { - var containingCollection = this.ContainingCollection; - if( containingCollection == null ) - { - if( m_isMainColumn == value ) - return; - - m_isMainColumn = value; - - this.RaiseIsMainColumnChanged(); - } - else if( value ) - { - containingCollection.MainColumn = this; - } - else - { - if( containingCollection.MainColumn != this ) - return; - - containingCollection.MainColumn = null; - } - } - } - - internal void RaiseIsMainColumnChanged() - { - this.RefreshDraggableStatus(); - this.OnPropertyChanged( new PropertyChangedEventArgs( ColumnBase.IsMainColumnPropertyName ) ); - } - - internal static readonly string IsMainColumnPropertyName = PropertyHelper.GetPropertyName( ( ColumnBase c ) => c.IsMainColumn ); - - private Nullable m_isMainColumn = null; - - #endregion - - #region ReadOnly Property - - public static readonly DependencyProperty ReadOnlyProperty = DependencyProperty.Register( - "ReadOnly", - typeof( bool ), - typeof( ColumnBase ), - new FrameworkPropertyMetadata( false ) ); - - public virtual bool ReadOnly - { - get - { - return ( bool )this.GetValue( ColumnBase.ReadOnlyProperty ); - } - set - { - this.SetValue( ColumnBase.ReadOnlyProperty, value ); - } - } - - #endregion - - #region OverrideReadOnlyForInsertion Property - - public static readonly DependencyProperty OverrideReadOnlyForInsertionProperty = DependencyProperty.Register( - "OverrideReadOnlyForInsertion", - typeof( bool ), - typeof( ColumnBase ), - new UIPropertyMetadata( false ) ); - - public bool OverrideReadOnlyForInsertion - { - get - { - return ( bool )this.GetValue( ColumnBase.OverrideReadOnlyForInsertionProperty ); - } - set - { - this.SetValue( ColumnBase.OverrideReadOnlyForInsertionProperty, value ); - } - } - - #endregion - - #region PreviousVisibleColumn Property - - [EditorBrowsable( EditorBrowsableState.Never )] - public virtual ColumnBase PreviousVisibleColumn - { - get - { - // Column is being initialized. - if( this.DataGridControl == null ) - return null; - - var columnsByVisiblePosition = ( this.ParentDetailConfiguration != null ) - ? this.ParentDetailConfiguration.ColumnsByVisiblePosition - : this.DataGridControl.ColumnsByVisiblePosition; - var previousColumnNode = columnsByVisiblePosition.Find( this ).Previous; - - while( previousColumnNode != null ) - { - var previousColumn = previousColumnNode.Value; - - if( previousColumn.Visible ) - return previousColumn; - - previousColumnNode = previousColumnNode.Previous; - } - - return null; - } - } - - internal void InvalidatePreviousVisibleColumnProperty() - { - this.OnPropertyChanged( new PropertyChangedEventArgs( ColumnBase.PreviousVisibleColumnPropertyName ) ); - } - - internal static readonly string PreviousVisibleColumnPropertyName = PropertyHelper.GetPropertyName( ( ColumnBase c ) => c.PreviousVisibleColumn ); - - #endregion - - #region NextVisibleColumn Property - - internal virtual ColumnBase NextVisibleColumn - { - get - { - // Column is being initialized. - if( this.DataGridControl == null ) - return null; - - var columnsByVisiblePosition = ( this.ParentDetailConfiguration != null ) - ? this.ParentDetailConfiguration.ColumnsByVisiblePosition - : this.DataGridControl.ColumnsByVisiblePosition; - - var nextColumnNode = columnsByVisiblePosition.Find( this ); - - if( nextColumnNode != null ) - { - nextColumnNode = nextColumnNode.Next; - } - - while( nextColumnNode != null ) - { - var previousColumn = nextColumnNode.Value; - - if( previousColumn.Visible ) - return previousColumn; - - nextColumnNode = nextColumnNode.Next; - } - - return null; - } - } - - #endregion - - #region CellRecyclingGroup Property - - public static readonly DependencyProperty CellRecyclingGroupProperty = DependencyProperty.Register( - "CellRecyclingGroup", - typeof( object ), - typeof( ColumnBase ), - new FrameworkPropertyMetadata( null ) ); - - public object CellRecyclingGroup - { - get - { - return this.GetValue( ColumnBase.CellRecyclingGroupProperty ); - } - set - { - this.SetValue( ColumnBase.CellRecyclingGroupProperty, value ); - } - } - - internal object GetCellRecyclingGroupOrDefault() - { - //Always return the one assigned by the client application - var recyclingGroup = this.CellRecyclingGroup; - if( recyclingGroup != null ) - return recyclingGroup; - - var defaultCellRecyclingGroup = this.DefaultCellRecyclingGroup; - Debug.Assert( defaultCellRecyclingGroup != null ); - - return defaultCellRecyclingGroup; - } - - #endregion - - #region DefaultCellRecyclingGroupDataType Internal Property - - internal Type DefaultCellRecyclingGroupDataType - { - get - { - return m_defaultCellRecyclingGroupDataType; - } - set - { - if( value == m_defaultCellRecyclingGroupDataType ) - return; - - Debug.Assert( value != null ); - - m_defaultCellRecyclingGroupDataType = value; - - this.ResetDefaultCellRecyclingGroup(); - } - } - - private Type m_defaultCellRecyclingGroupDataType = typeof( object ); - - #endregion - - #region DefaultCellRecyclingGroup Private Property - - private object DefaultCellRecyclingGroup - { - get - { - if( m_defaultCellRecyclingGroup == null ) - { - m_defaultCellRecyclingGroup = this.CreateDefaultCellRecyclingGroup(); - if( m_defaultCellRecyclingGroup == null ) - throw new InvalidOperationException( "CreateDefaultCellRecyclingGroup must return a non-null value." ); - } - - return m_defaultCellRecyclingGroup; - } - } - - internal virtual object CreateDefaultCellRecyclingGroup() - { - return new CellRecyclingGroupKey( this.CellContentTemplate, this.DefaultCellRecyclingGroupDataType ); - } - - internal void ResetDefaultCellRecyclingGroup() - { - m_defaultCellRecyclingGroup = null; - } - - private object m_defaultCellRecyclingGroup; - - #endregion - - #region CurrentRowInEditionCellState Property - - internal CellState CurrentRowInEditionCellState - { - get; - set; - } - - #endregion - - #region DisplayedValueConverter Property - - public IValueConverter DisplayedValueConverter - { - get; - set; - } - - #endregion - - #region DisplayedValueConverterParameter Property - - public object DisplayedValueConverterParameter - { - get; - set; - } - - #endregion - - #region DisplayedValueConverterCulture Property - - public CultureInfo DisplayedValueConverterCulture - { - get; - set; - } - - #endregion - - #region DefaultCulture Property - - public static readonly DependencyProperty DefaultCultureProperty = DependencyProperty.Register( - "DefaultCulture", - typeof( CultureInfo ), - typeof( ColumnBase ), - new FrameworkPropertyMetadata( CultureInfo.CurrentCulture ) ); - - public CultureInfo DefaultCulture - { - get - { - return ( CultureInfo )this.GetValue( ColumnBase.DefaultCultureProperty ); - } - set - { - this.SetValue( ColumnBase.DefaultCultureProperty, value ); - } - } - - #endregion - - #region DraggableStatus Property - - public static readonly DependencyProperty DraggableStatusProperty = DependencyProperty.Register( - "DraggableStatus", - typeof( ColumnDraggableStatus ), - typeof( ColumnBase ), - new UIPropertyMetadata( ColumnDraggableStatus.Draggable, null, new CoerceValueCallback( ColumnBase.CoerceDraggableStatus ) ) ); - - public ColumnDraggableStatus DraggableStatus - { - get - { - return ( ColumnDraggableStatus )this.GetValue( ColumnBase.DraggableStatusProperty ); - } - set - { - this.SetValue( ColumnBase.DraggableStatusProperty, value ); - } - } - - internal void RefreshDraggableStatus() - { - this.CoerceValue( ColumnBase.DraggableStatusProperty ); - } - - private static object CoerceDraggableStatus( DependencyObject sender, object value ) - { - var self = sender as ColumnBase; - var collection = ( self != null ) ? self.ContainingCollection : null; - if( collection == null ) - return value; - - var dataGridControl = collection.DataGridControl; - if( ( dataGridControl == null ) || !dataGridControl.AreDetailsFlatten || !self.IsMainColumn ) - return value; - - // The main column is always locked in first position when details are flatten. - return ColumnDraggableStatus.FirstUndraggable; - } - - #endregion - - #region RealizedContainersRequested Event - - internal event RealizedContainersRequestedEventHandler RealizedContainersRequested; - - #endregion - - #region ActualWidthChanged Event - - internal event ColumnActualWidthChangedEventHandler ActualWidthChanged; - - #endregion - - #region DistinctValuesRequested Event - - internal event DistinctValuesRequestedEventHandler DistinctValuesRequested; - - #endregion - - #region FittedWidthRequested Event - - internal event FittedWidthRequestedEventHandler FittedWidthRequested; - - private Nullable RequestFittedWidth() - { - var handler = this.FittedWidthRequested; - if( handler == null ) - return null; - - var e = new FittedWidthRequestedEventArgs(); - handler.Invoke( this, e ); - - return e.Value; - } - - #endregion - -#if DEBUG - public override string ToString() - { - string toString = base.ToString(); - - if( !string.IsNullOrEmpty( this.FieldName ) ) - { - toString += " " + this.FieldName; - } - - return toString; - } -#endif - - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate" )] - public virtual double GetFittedWidth() - { - var fittedWidth = this.RequestFittedWidth().GetValueOrDefault( -1d ); - var e = new RealizedContainersRequestedEventArgs(); - - var handler = this.RealizedContainersRequested; - if( handler != null ) - { - handler.Invoke( this, e ); - } - - var realizedContainers = e.RealizedContainers; - if( realizedContainers.Count > 0 ) - { - fittedWidth = Math.Max( fittedWidth, this.GetElementCollectionFittedWidth( realizedContainers ) ); - } - - return fittedWidth; - } - - protected override void OnPropertyChanged( DependencyPropertyChangedEventArgs e ) - { - base.OnPropertyChanged( e ); - this.OnPropertyChanged( new PropertyChangedEventArgs( e.Property.Name ) ); - } - - protected override Freezable CreateInstanceCore() - { - // Only derived from Freezable to have DataContext and ElementName binding. - // So we have not implemented the Clone. - throw new NotImplementedException(); - } - - protected override bool FreezeCore( bool isChecking ) - { - // Only derived from Freezable to have DataContext and ElementName binding. - // So we don't want to be freezable. - return false; - } - - internal virtual void SetIsBeingDraggedAnimated( bool value ) - { - TableflowView.SetIsBeingDraggedAnimated( this, value ); - } - - internal virtual void SetColumnReorderingDragSourceManager( ColumnReorderingDragSourceManager value ) - { - TableflowView.SetColumnReorderingDragSourceManager( this, value ); - } - - internal virtual void ClearColumnReorderingDragSourceManager() - { - TableflowView.ClearColumnReorderingDragSourceManager( this ); - } - - internal void AttachToContainingCollection( ColumnCollection columnCollection ) - { - if( columnCollection == null ) - throw new ArgumentNullException( "columnCollection" ); - - if( m_containingCollection != null ) - throw new InvalidOperationException( "An attempt was made to add a column to a grid while it already exists in another grid." ); - - if( m_containingCollection == columnCollection ) - return; - - this.AttachToContainingCollectionCore( columnCollection ); - } - - internal void DetachFromContainingCollection() - { - if( m_containingCollection == null ) - return; - - this.DetachFromContainingCollectionCore(); - } - - internal void OnDistinctValuesRequested( object sender, DistinctValuesRequestedEventArgs e ) - { - var handler = this.DistinctValuesRequested; - if( handler == null ) - return; - - handler.Invoke( this, e ); - } - - internal CultureInfo GetCulture( CultureInfo value ) - { - if( value != null ) - return value; - - return this.GetCulture(); - } - - internal CultureInfo GetCulture() - { - var culture = this.DefaultCulture; - if( culture != null ) - return culture; - - return CultureInfo.CurrentCulture; - } - - private void AttachToContainingCollectionCore( ColumnCollection columnCollection ) - { - m_containingCollection = columnCollection; - m_isMainColumn = null; - - this.NotifyDataGridControlChanged(); - } - - private void DetachFromContainingCollectionCore() - { - m_containingCollection = null; - - this.NotifyDataGridControlChanged(); - } - - private double GetElementCollectionFittedWidth( IEnumerable collection ) - { - if( collection == null ) - throw new ArgumentNullException( "collection" ); - - // Ensure to use the FieldName of the Cell instead of the visible position since a lookup dictionary is used underneath - // and if the Indexer is used, the Cells are returned in the order they were added, not visible position. - double fittedWidth = -1; - - foreach( object item in collection ) - { - var row = item as Row; - if( row == null ) - { - var headerFooter = item as HeaderFooterItem; - if( headerFooter != null ) - { - row = headerFooter.AsVisual() as Row; - } - } - - double cellFittedWidth; - if( !this.TryGetCellFittedWidth( row, out cellFittedWidth ) ) - continue; - - fittedWidth = Math.Max( fittedWidth, cellFittedWidth ); - } - - return fittedWidth; - } - - private bool TryGetCellFittedWidth( Row row, out double fittedWidth ) - { - fittedWidth = -1d; - - if( row == null ) - return false; - - Cell cell; - var cells = row.Cells; - var virtualCells = cells as VirtualizingCellCollection; - bool releaseCell = false; - - if( virtualCells != null ) - { - if( !virtualCells.TryGetBindedCell( this, out cell ) ) - { - releaseCell = true; - cell = virtualCells[ this ]; - - if( cell == null ) - return false; - - // A created cell doesn't have a template applied yet. - // The call to Cell.GetFittedWidth will fail unless we force the creation of the child element by measuring the cell. - if( !cell.IsMeasureValid ) - { - cell.Measure( Size.Empty ); - } - } - } - else - { - cell = cells[ this ]; - } - - Debug.Assert( cell != null ); - fittedWidth = cell.GetFittedWidth(); - - // A cell that was created or recycled to calculate the fitted width must be released in order to minimize the number of cells created overall. - if( releaseCell ) - { - Debug.Assert( virtualCells != null ); - virtualCells.Release( cell ); - } - - return true; - } - - #region INotifyPropertyChanged Members - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void OnPropertyChanged( PropertyChangedEventArgs e ) - { - var handler = this.PropertyChanged; - if( handler == null ) - return; - - Debug.Assert( e != null ); - handler.Invoke( this, e ); - } - - #endregion - - #region IWeakEventListener Members - - 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 ) - { - return false; - } - - #endregion - - #region CellRecyclingGroupKey Private Class - - private sealed class CellRecyclingGroupKey - { - internal CellRecyclingGroupKey( DataTemplate contentTemplate, Type dataType ) - { - //This is a value that is cached at the cell level and that is costly to update, thus basing the recycling on it optimizes performance. - m_contentTemplate = contentTemplate; - m_dataType = dataType; - } - - public override int GetHashCode() - { - if( m_contentTemplate != null ) - return m_contentTemplate.GetHashCode(); - - if( m_dataType != null ) - return m_dataType.GetHashCode(); - - return 0; - } - - public override bool Equals( object obj ) - { - var key = obj as CellRecyclingGroupKey; - if( key == null ) - return false; - - if( key == this ) - return true; - - if( ( key.m_contentTemplate == null ) && ( m_contentTemplate == null ) ) - return ( key.m_dataType == m_dataType ); - - return ( key.m_contentTemplate == m_contentTemplate ); - } - - private readonly DataTemplate m_contentTemplate; - private readonly Type m_dataType; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnCollection.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnCollection.cs deleted file mode 100644 index e599683f..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnCollection.cs +++ /dev/null @@ -1,289 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; -using System.Diagnostics; -using Xceed.Wpf.DataGrid.Utils; - -namespace Xceed.Wpf.DataGrid -{ - public class ColumnCollection : ObservableColumnCollection - { - #region Static Fields - - internal static readonly string MainColumnPropertyName = PropertyHelper.GetPropertyName( ( ColumnCollection c ) => c.MainColumn ); - - #endregion - - - internal ColumnCollection( DataGridControl dataGridControl, DetailConfiguration parentDetailConfiguration ) - { - m_dataGridControl = dataGridControl; - m_parentDetailConfiguration = parentDetailConfiguration; - } - - #region MainColumn Property - - public virtual ColumnBase MainColumn - { - get - { - return m_mainColumn; - } - set - { - if( value == m_mainColumn ) - return; - - if( ( value != null ) && !this.Contains( value ) ) - throw new ArgumentException( "The column was not found in the collection." ); - - using( this.DeferColumnsUpdate() ) - { - var oldMainColumn = m_mainColumn; - m_mainColumn = value; - - if( m_mainColumn != null ) - { - m_mainColumn.RaiseIsMainColumnChanged(); - } - - if( oldMainColumn != null ) - { - oldMainColumn.RaiseIsMainColumnChanged(); - } - } - - this.OnPropertyChanged( new PropertyChangedEventArgs( ColumnCollection.MainColumnPropertyName ) ); - } - } - - private ColumnBase m_mainColumn; - - #endregion - - #region DataGridControl Internal Property - - internal DataGridControl DataGridControl - { - get - { - return m_dataGridControl; - } - set - { - if( value == m_dataGridControl ) - return; - - m_dataGridControl = value; - - foreach( var column in this ) - { - column.NotifyDataGridControlChanged(); - } - } - } - - private DataGridControl m_dataGridControl; - - #endregion - - #region ParentDetailConfiguration Internal Property - - internal DetailConfiguration ParentDetailConfiguration - { - get - { - return m_parentDetailConfiguration; - } - set - { - m_parentDetailConfiguration = value; - } - } - - private DetailConfiguration m_parentDetailConfiguration; - - #endregion - - #region RealizedContainersRequested Internal Event - - internal event RealizedContainersRequestedEventHandler RealizedContainersRequested; - - private void OnRealizedContainersRequested( RealizedContainersRequestedEventArgs e ) - { - var handler = this.RealizedContainersRequested; - if( handler == null ) - return; - - handler.Invoke( this, e ); - } - - #endregion - - #region DistinctValuesRequested Internal Event - - internal event DistinctValuesRequestedEventHandler DistinctValuesRequested; - - private void OnDistinctValuesRequested( DistinctValuesRequestedEventArgs e ) - { - var handler = this.DistinctValuesRequested; - if( handler == null ) - return; - - handler.Invoke( this, e ); - } - - #endregion - - #region ActualWidthChanged Internal Event - - internal event ColumnActualWidthChangedEventHandler ActualWidthChanged; - - private void OnActualWidthChanged( ColumnActualWidthChangedEventArgs e ) - { - var handler = this.ActualWidthChanged; - if( handler == null ) - return; - - handler.Invoke( this, e ); - } - - #endregion - - protected override void OnItemAdding( ColumnBase item ) - { - base.OnItemAdding( item ); - - Debug.Assert( item != null ); - - if( item.IsMainColumn ) - { - m_nextMainColumn = item; - } - - item.AttachToContainingCollection( this ); - - item.PropertyChanged += new PropertyChangedEventHandler( this.OnColumnPropertyChanged ); - item.RealizedContainersRequested += new RealizedContainersRequestedEventHandler( this.OnColumnRealizedContainersRequested ); - item.ActualWidthChanged += new ColumnActualWidthChangedEventHandler( this.OnColumnActualWidthChanged ); - item.DistinctValuesRequested += new DistinctValuesRequestedEventHandler( this.OnColumnDistinctValuesRequested ); - } - - protected override void OnItemAdded( ColumnBase item ) - { - base.OnItemAdded( item ); - - this.UpdateMainColumn(); - } - - protected override void OnItemRemoving( ColumnBase item ) - { - Debug.Assert( item != null ); - - item.PropertyChanged -= new PropertyChangedEventHandler( this.OnColumnPropertyChanged ); - item.RealizedContainersRequested -= new RealizedContainersRequestedEventHandler( this.OnColumnRealizedContainersRequested ); - item.ActualWidthChanged -= new ColumnActualWidthChangedEventHandler( this.OnColumnActualWidthChanged ); - item.DistinctValuesRequested -= new DistinctValuesRequestedEventHandler( this.OnColumnDistinctValuesRequested ); - - item.DetachFromContainingCollection(); - - base.OnItemRemoving( item ); - } - - protected override void OnItemRemoved( ColumnBase item ) - { - base.OnItemRemoved( item ); - - this.UpdateMainColumn(); - } - - private void UpdateMainColumn() - { - switch( this.Count ) - { - case 0: - this.MainColumn = null; - break; - - case 1: - this.MainColumn = this[ 0 ]; - break; - - default: - { - var column = m_nextMainColumn ?? m_mainColumn; - - m_nextMainColumn = null; - - if( ( column != null ) && this.Contains( column ) ) - { - this.MainColumn = column; - } - else - { - this.MainColumn = null; - } - } - break; - } - } - - private IDisposable DeferColumnsUpdate() - { - if( m_parentDetailConfiguration != null ) - return m_parentDetailConfiguration.DeferColumnsUpdate(); - - if( m_dataGridControl != null ) - return m_dataGridControl.DeferColumnsUpdate(); - - return new EmptyDisposable(); - } - - private void OnColumnPropertyChanged( object sender, PropertyChangedEventArgs e ) - { - } - - private void OnColumnRealizedContainersRequested( object sender, RealizedContainersRequestedEventArgs e ) - { - this.OnRealizedContainersRequested( e ); - } - - private void OnColumnDistinctValuesRequested( object sender, DistinctValuesRequestedEventArgs e ) - { - this.OnDistinctValuesRequested( e ); - } - - private void OnColumnActualWidthChanged( object sender, ColumnActualWidthChangedEventArgs e ) - { - this.OnActualWidthChanged( e ); - } - - private ColumnBase m_nextMainColumn; //null - - #region EmptyDisposable Private Class - - private sealed class EmptyDisposable : IDisposable - { - void IDisposable.Dispose() - { - } - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnCommand.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnCommand.cs deleted file mode 100644 index a8ce1c39..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnCommand.cs +++ /dev/null @@ -1,62 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Diagnostics; -using System.Windows.Input; - -namespace Xceed.Wpf.DataGrid -{ - internal abstract class ColumnCommand : ICommand - { - #region Validation Methods - - protected static void ThrowIfNull( object value, string paramName ) - { - if( value == null ) - throw new ArgumentNullException( paramName ); - } - - #endregion - - protected abstract bool CanExecuteImpl( object parameter ); - protected abstract void ExecuteImpl( object parameter ); - - #region ICommand Members - - event EventHandler ICommand.CanExecuteChanged - { - add - { - } - remove - { - } - } - - bool ICommand.CanExecute( object parameter ) - { - return this.CanExecuteImpl( parameter ); - } - - void ICommand.Execute( object parameter ) - { - this.ExecuteImpl( parameter ); - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnGroupCommand.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnGroupCommand.cs deleted file mode 100644 index 676448be..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnGroupCommand.cs +++ /dev/null @@ -1,26 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Diagnostics; -using System.Windows.Input; - -namespace Xceed.Wpf.DataGrid -{ - internal abstract class ColumnGroupCommand : ColumnCommand - { - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnHierarchyManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnHierarchyManager.cs deleted file mode 100644 index 0406cdc6..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnHierarchyManager.cs +++ /dev/null @@ -1,2916 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Diagnostics; -using System.Linq; -using System.Windows; -using Xceed.Utils.Wpf; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class ColumnHierarchyManager : IWeakEventListener - { - internal ColumnHierarchyManager( ColumnCollection columns) - { - if( columns == null ) - throw new ArgumentNullException( "columns" ); - - m_columns = columns; - m_visibleColumns = new ReadOnlyColumnCollection( new ObservableColumnCollection() ); - m_columnsByVisiblePosition = new HashedLinkedList(); - - m_model.LayoutChanging += new EventHandler( this.OnViewLayoutChanging ); - m_model.LayoutChanged += new EventHandler( this.OnViewLayoutChanged ); - m_model.StatusChanged += new EventHandler( this.OnViewStatusChanged ); - } - - #region Columns Property - - internal ColumnCollection Columns - { - get - { - return m_columns; - } - } - - private readonly ColumnCollection m_columns; - - #endregion - - #region VisibleColumns Property - - internal ReadOnlyColumnCollection VisibleColumns - { - get - { - return m_visibleColumns; - } - } - - private readonly ReadOnlyColumnCollection m_visibleColumns; - - #endregion - - #region ColumnsByVisiblePosition Property - - internal HashedLinkedList ColumnsByVisiblePosition - { - get - { - return m_columnsByVisiblePosition; - } - } - - private readonly HashedLinkedList m_columnsByVisiblePosition; - - #endregion - - #region IsUpdateDeferred Property - - internal bool IsUpdateDeferred - { - get - { - lock( this.SyncRoot ) - { - return ( m_deferUpdateCount != 0 ); - } - } - } - - #endregion - - #region SyncRoot Private Property - - private object SyncRoot - { - get - { - return m_model; - } - } - - #endregion - - #region LayoutChanging Event - - internal event EventHandler LayoutChanging; - - private void OnLayoutChanging() - { - var handler = this.LayoutChanging; - if( handler == null ) - return; - - handler.Invoke( this, EventArgs.Empty ); - } - - #endregion - - #region LayoutChanged Event - - internal event EventHandler LayoutChanged; - - private void OnLayoutChanged() - { - var handler = this.LayoutChanged; - if( handler == null ) - return; - - handler.Invoke( this, EventArgs.Empty ); - } - - #endregion - - internal void Initialize( DataGridControl dataGridControl ) - { - if( dataGridControl == null ) - throw new ArgumentNullException( "dataGridControl" ); - - if( m_dataGridControl == dataGridControl ) - return; - - if( m_dataGridControl != null ) - throw new InvalidOperationException( "The current object is already initialized." ); - - m_dataGridControl = dataGridControl; - m_columns.DataGridControl = dataGridControl; - - this.PrepareInitialLayout(); - } - - internal void Clear() - { - if( m_dataGridControl == null ) - return; - - this.ClearLayout(); - - m_columns.DataGridControl = null; - - m_dataGridControl = null; - m_desiredFixedColumnCount = null; - m_synchronizeChildColumnNamesWithChildColumns = false; - } - - internal IDisposable DeferUpdate() - { - return this.DeferUpdate( new UpdateOptions() ); - } - - internal IDisposable DeferUpdate( UpdateOptions options ) - { - return new DeferredDisposable( new DeferUpdateState( this, options ) ); - } - - internal ILevelMarkers GetLevelMarkersFor( ColumnCollection collection ) - { - if( collection == null ) - return null; - - var level = int.MinValue; - - if( collection == m_columns ) - { - level = 0; - } - - if( ( level < 0 ) || ( level >= m_model.LevelCount ) ) - return null; - - return this.WrapLevelMarkers( m_model.GetLevelMarkers( level ) ); - } - - internal IColumnLocation GetColumnLocationFor( ColumnBase column ) - { - return ( IColumnLocation )this.WrapLocation( m_model[ column ] ); - } - - internal int GetFixedColumnCount() - { - var levelCount = m_model.LevelCount; - if( levelCount == 0 ) - return 0; - - // Get the top-most level. - var markers = m_model.GetLevelMarkers( levelCount - 1 ); - - var splitterLocation = markers.Splitter; - if( splitterLocation == null ) - return 0; - - var count = 0; - var location = splitterLocation.GetPreviousSiblingOrCousin(); - - // Count the number of visibile columns that are located before the splitter. - while( location != null ) - { - if( location.Type == LocationType.Column ) - { - var columnLocation = ( ColumnHierarchyModel.IColumnLocation )location; - if( columnLocation.Column.Visible ) - { - count++; - } - } - - location = location.GetPreviousSiblingOrCousin(); - } - - return count; - } - - internal void SetFixedColumnCount( int count ) - { - this.Update( new UpdateOptions( count ) ); - } - - private static int ConvertLevelToMergedHeaderIndex( int level, int mergedHeaderCount ) - { - if( level <= 0 ) - throw new ArgumentException( "The level must be greater than or equal to 1.", "level" ); - - if( mergedHeaderCount <= 0 ) - throw new ArgumentException( "The number of merged headers is expected to be greater than or equal to 1.", "mergedHeaderCount" ); - - if( level > mergedHeaderCount ) - throw new ArgumentException( "The level must be less than or equal to the number of merged headers.", "level" ); - - return ( mergedHeaderCount - level ); - } - - private static int ConvertMergedHeaderIndexToLevel( int index, int mergedHeaderCount ) - { - if( index < 0 ) - throw new ArgumentException( "The index must be greater than or equal to zero.", "index" ); - - if( mergedHeaderCount <= 0 ) - throw new ArgumentException( "The number of merged headers is expected to be greater than or equal to 1.", "mergedHeaderCount" ); - - if( index >= mergedHeaderCount ) - throw new ArgumentException( "The index must be less than the number of merged headers.", "index" ); - - return ( mergedHeaderCount - index ); - } - - private void PrepareInitialLayout() - { - Debug.Assert( m_model.LevelCount == 0 ); - - this.RegisterEvents( m_columns ); - - m_model.AddLevel( 0 ); - - this.SetColumnsInView( 0 ); - - this.UpdateLevelsInView(); - this.Update(); - } - - private void ClearLayout() - { - for( int i = m_model.LevelCount - 1; i > 0; i-- ) - { - this.RemoveLevelInView( i ); - } - - Debug.Assert( m_model.LevelCount == 1 ); - - foreach( var column in this.GetColumns( 0 ) ) - { - this.UnregisterEvents( column ); - } - - m_model.RemoveLevel( 0 ); - - Debug.Assert( m_model.LevelCount == 0 ); - - this.UnregisterEvents( m_columns ); - } - - private void Update() - { - this.Update( new UpdateOptions() ); - } - - private void Update( UpdateOptions options ) - { - lock( this.SyncRoot ) - { - try - { - // The current object has not been initialized yet. - if( m_dataGridControl == null ) - return; - - // The update is deferred and must not be applied yet. - if( m_deferUpdateCount != 0 ) - return; - } - finally - { - if( options.DesiredFixedColumnCount.HasValue ) - { - m_desiredFixedColumnCount = Math.Max( 0, options.DesiredFixedColumnCount.Value ); - } - - if( !m_synchronizeChildColumnNamesWithChildColumns && ( options.SynchronizeChildColumnNamesWithChildColumns == true ) ) - { - m_synchronizeChildColumnNamesWithChildColumns = true; - - for( int i = m_model.LevelCount - 1; i > 0; i-- ) - { - foreach( var columnLocation in this.GetColumnsLocation( this.GetLocationsOnLevelFromFirstToLast( i ) ) ) - { - this.SetPosition( columnLocation, columnLocation.Status.Position.SetChildrenTimestamp( this.GetTimestamp() ) ); - } - } - - this.InvalidateLayout(); - } - } - } - - // Prevent reentrancy. - if( m_isApplyingChanges.IsSet ) - return; - - this.UpdateLayout(); - } - - private void UpdateLayout() - { - Debug.Assert( !m_isApplyingChanges.IsSet ); - - if( ( m_positionVersion == m_modelPositionVersion ) && ( m_visibilityVersion == m_modelVisibilityVersion ) && ( m_layoutVersion == m_modelLayoutVersion ) ) - { - // Nothing has changed, so nothing to do. - if( ( !m_desiredFixedColumnCount.HasValue ) || ( m_desiredFixedColumnCount == this.GetFixedColumnCount() ) ) - { - m_desiredFixedColumnCount = null; - - this.ResetTimestamp(); - return; - } - } - - this.OnLayoutChanging(); - - this.ResetMainColumn(); - - while( true ) - { - if( m_positionVersion != m_modelPositionVersion ) - { - m_positionVersion = m_modelPositionVersion; - this.ApplyPosition(); - } - else if( m_visibilityVersion != m_modelVisibilityVersion ) - { - m_visibilityVersion = m_modelVisibilityVersion; - this.ApplyVisibility(); - } - else if( m_desiredFixedColumnCount.HasValue ) - { - var fixedColumnCount = m_desiredFixedColumnCount.Value; - m_desiredFixedColumnCount = null; - - this.ApplyFixedColumnCount( fixedColumnCount ); - } - else if( m_layoutVersion != m_modelLayoutVersion ) - { - m_layoutVersion = m_modelLayoutVersion; - this.ApplyLayout(); - } - else - { - this.ResetTimestamp(); - break; - } - } - - Debug.Assert( m_timestamp == 0u ); - Debug.Assert( !m_desiredFixedColumnCount.HasValue ); - Debug.Assert( m_positionVersion == m_modelPositionVersion ); - Debug.Assert( m_visibilityVersion == m_modelVisibilityVersion ); - Debug.Assert( m_layoutVersion == m_modelLayoutVersion ); - - this.OnLayoutChanged(); - } - - private void ApplyLayout() - { - if( m_isApplyingChanges.IsSet ) - throw new InvalidOperationException( "The columns' layout is already being applied." ); - - using( m_isApplyingChanges.Set() ) - { - for( int i = m_model.LevelCount - 1; i >= 0; i-- ) - { - this.ApplyColumnsLayoutFromView( i ); - - if( i == 0 ) - { - this.SetVisibleColumnsFromView( i, m_visibleColumns, m_columnsByVisiblePosition ); - } - } - } - } - - private void ApplyPosition() - { - if( m_isApplyingChanges.IsSet ) - throw new InvalidOperationException( "The columns' relations are already being applied." ); - - var levelCount = m_model.LevelCount; - if( levelCount <= 0 ) - return; - - using( m_isApplyingChanges.Set() ) - { - this.UpdateLevelsInView(); - } - } - - private void ApplyVisibility() - { - if( m_isApplyingChanges.IsSet ) - throw new InvalidOperationException( "The columns' visibility is already being applied." ); - - var levelCount = m_model.LevelCount; - if( levelCount <= 0 ) - return; - - using( m_isApplyingChanges.Set() ) - { - foreach( var location in this.GetLocationsOnLevel( levelCount - 1 ) ) - { - // We must redo a visibility pass if the layout has changed while applying the visiblity. - if( !this.ApplyColumnsVisibilityFromView( location ) ) - return; - } - } - } - - private void ApplyFixedColumnCount( int count ) - { - Debug.Assert( count >= 0 ); - - // There is no level or the splitter is already at the proper location. - var levelCount = m_model.LevelCount; - if( ( levelCount == 0 ) || ( count == this.GetFixedColumnCount() ) ) - return; - - // Get the top-most level. - var markers = m_model.GetLevelMarkers( levelCount - 1 ); - - var startLocation = markers.Start; - Debug.Assert( startLocation != null ); - Debug.Assert( startLocation.Type == LocationType.Start ); - - var splitterLocation = markers.Splitter; - Debug.Assert( splitterLocation != null ); - Debug.Assert( splitterLocation.Type == LocationType.Splitter ); - - var targetLocation = default( ColumnHierarchyModel.ILocation ); - var moveBefore = false; - - if( count <= 0 ) - { - targetLocation = startLocation; - } - else - { - var remaining = count; - var currentLocation = startLocation; - var found = false; - - while( !found ) - { - currentLocation = currentLocation.GetNextSiblingOrCousin(); - if( currentLocation == null ) - throw new InvalidOperationException( "Unexpected location." ); - - switch( currentLocation.Type ) - { - case LocationType.Column: - { - var column = ( ( ColumnHierarchyModel.IColumnLocation )currentLocation ).Column; - Debug.Assert( column != null ); - - if( column.Visible ) - { - remaining--; - - if( remaining == 0 ) - { - targetLocation = currentLocation; - found = true; - break; - } - } - } - break; - - // The splitter cannot be set past the orphan section. - case LocationType.Orphan: - { - targetLocation = currentLocation; - moveBefore = true; - found = true; - } - break; - } - } - } - - Debug.Assert( targetLocation != null ); - - if( moveBefore ) - { - if( !splitterLocation.CanMoveBefore( targetLocation ) ) - throw new InvalidOperationException( "The fixed-column splitter cannot be moved." ); - - splitterLocation.MoveBefore( targetLocation ); - } - else - { - if( !splitterLocation.CanMoveAfter( targetLocation ) ) - throw new InvalidOperationException( "The fixed-column splitter cannot be moved." ); - - splitterLocation.MoveAfter( targetLocation ); - } - } - - private void ResetStatus() - { - if( ( m_timestamp == 0u ) || ( m_model.LevelCount <= 0 ) ) - return; - - foreach( var location in this.GetLocationsOnLevel( m_model.LevelCount - 1 ) ) - { - this.ResetStatusOnLocation( location ); - } - } - - private void ResetStatusOnLocation( ColumnHierarchyModel.ILocation location ) - { - if( location == null ) - return; - - var columnLocation = location as ColumnHierarchyModel.IColumnLocation; - if( columnLocation != null ) - { - this.SetStatus( columnLocation, new ColumnStatus( ColumnPositionStatus.Default, ColumnVisibilityStatus.Create( columnLocation.Column.Visible ) ) ); - } - - foreach( var childLocation in this.GetChildLocations( location ) ) - { - this.ResetStatusOnLocation( childLocation ); - } - } - - private void InsertLevelInView( int level ) - { - Debug.Assert( ( level > 0 ) && ( level <= m_model.LevelCount ) ); - - m_model.AddLevel( level ); - - this.SetColumnsInView( level ); - } - - private void RemoveLevelInView( int level ) - { - Debug.Assert( ( level > 0 ) && ( level < m_model.LevelCount ) ); - - foreach( var location in this.GetLocationsOnLevel( level ) ) - { - var parentColumnLocation = location.GetParent() as ColumnHierarchyModel.IColumnLocation; - if( parentColumnLocation != null ) - { - this.UpdateVisibility( parentColumnLocation ); - } - - var columnLocation = location as ColumnHierarchyModel.IColumnLocation; - if( columnLocation != null ) - { - this.UnregisterEvents( columnLocation.Column ); - } - } - - m_model.RemoveLevel( level ); - } - - private void UpdateLevelsInView() - { - var levelCount = m_model.LevelCount; - if( levelCount == 0 ) - return; - - if( levelCount > 1 ) - { - var movedLocations = new HashSet(); - var childLocationsToMove = new Queue(); - var parentLocationsToInspect = new Queue(); - var relationsHistory = new List[ levelCount ]; - var relationsHistoryComparer = new ParentChildRelationshipSnapshotComparer(); - - for( int i = 0; i < levelCount; i++ ) - { - relationsHistory[ i ] = new List(); - - foreach( var columnLocation in this.GetColumnsLocation( this.GetLocationsOnLevel( i ) ) ) - { - var positionStatus = columnLocation.Status.Position; - - if( ( positionStatus.ParentTimestamp != 0u ) && ( i < levelCount - 1 ) ) - { - childLocationsToMove.Enqueue( columnLocation ); - } - - if( ( positionStatus.ChildrenTimestamp != 0u ) && ( i > 0 ) ) - { - parentLocationsToInspect.Enqueue( columnLocation ); - - foreach( var childColumnLocation in this.GetColumnsLocation( this.GetChildLocations( columnLocation ) ) ) - { - childLocationsToMove.Enqueue( childColumnLocation ); - } - - var entry = new ParentChildRelationshipSnapshot( columnLocation, positionStatus.ChildrenTimestamp ); - var history = relationsHistory[ i ]; - - // Insert the entries in a specific order to meet the GetChildColumnLocationDestination method needs. - var index = history.BinarySearch( entry, relationsHistoryComparer ); - - if( index < 0 ) - { - index = ~index; - } - - if( index >= history.Count ) - { - history.Add( entry ); - } - else - { - history.Insert( index, entry ); - } - } - } - } - } - - var isAFlattenDetail = ( m_columns.ParentDetailConfiguration != null ) - && ( m_dataGridControl != null ) - && ( m_dataGridControl.AreDetailsFlatten ); - - // Reorder the columns on each level. - for( int i = 0; i < levelCount; i++ ) - { - // Reorder one of the child level. - if( i < levelCount - 1 ) - { - foreach( var parentLocation in this.GetLocationsOnLevel( i + 1 ) ) - { - ColumnLocationOrderer.Reorder( this.GetColumnsLocation( this.GetChildLocationsFromFirstToLast( parentLocation ) ).ToList(), !isAFlattenDetail ); - } - } - // Reorder the top level. - else - { - ColumnLocationOrderer.Reorder( this.GetColumnsLocation( this.GetLocationsOnLevelFromFirstToLast( i ) ).ToList(), !isAFlattenDetail ); - } - } - } - - private Tuple SetColumnsInView( int level ) - { - var columns = m_columns; - var addAny = false; - - Debug.Assert( columns != null ); - - var columnsToRemove = new HashSet( this.GetColumns( level ) ); - - // Add the missing columns into the view. - foreach( var column in columns ) - { - if( !columnsToRemove.Remove( column ) ) - { - var propagation = PropagationMode.None; - - if( level > 0 ) - { - var visibilitySource = DependencyPropertyHelper.GetValueSource( column, ColumnBase.VisibleProperty ); - - propagation = ( visibilitySource.BaseValueSource == BaseValueSource.Default ) ? PropagationMode.BottomUp : PropagationMode.TopDown; - } - - this.AddColumnInView( column, propagation, level ); - addAny = true; - } - } - - var removedAny = false; - - // Remove the columns that should no longer be in the view. - foreach( var column in columnsToRemove ) - { - this.RemoveColumnInView( column ); - removedAny = true; - } - - return new Tuple( addAny, removedAny ); - } - - private void ResetMainColumn() - { - // The main column must only be reset when details are flatten because it impact column positioning. - if( ( m_dataGridControl == null ) || !m_dataGridControl.AreDetailsFlatten ) - return; - - if( m_isApplyingChanges.IsSet ) - throw new InvalidOperationException( "The columns' relations are already being applied." ); - - var levelCount = m_model.LevelCount; - if( levelCount <= 0 ) - return; - - using( m_isApplyingChanges.Set() ) - { - var mainColumn = m_columns.MainColumn; - if( mainColumn != null ) - { - // We must not reset the main column if it was set explicitly. - var mainColumnLocation = m_model[ mainColumn ]; - if( ( mainColumnLocation == null ) || ( mainColumnLocation.Status.Position.MainColumnTimestamp != 0u ) ) - return; - - m_columns.MainColumn = null; - } - } - } - - private ColumnHierarchyModel.IColumnLocation AddColumnInView( ColumnBase column, PropagationMode mode, int level ) - { - Debug.Assert( column != null ); - Debug.Assert( ( level >= 0 ) && ( level < m_model.LevelCount ) ); - - var location = m_model[ column ]; - if( location == null ) - { - var timestamp = this.GetTimestamp(); - var visibilityStatus = ColumnVisibilityStatus.Create( column.Visible, mode, timestamp ); - var positionStatus = ColumnPositionStatus.Default; - - if( level > 0 ) - { - positionStatus = positionStatus.SetChildrenTimestamp( timestamp ); - } - - switch( DependencyPropertyHelper.GetValueSource( column, ColumnBase.VisiblePositionProperty ).BaseValueSource ) - { - case BaseValueSource.Default: - case BaseValueSource.Inherited: - case BaseValueSource.Unknown: - break; - - default: - positionStatus = positionStatus.SetVisiblePositionTimestamp( timestamp ); - break; - } - - var columnStatus = new ColumnStatus( positionStatus, visibilityStatus ); - - location = m_model.Add( column, columnStatus, level ); - Debug.Assert( location != null ); - - this.RegisterEvents( column ); - } - - return location; - } - - private void RemoveColumnInView( ColumnBase column ) - { - Debug.Assert( column != null ); - - var location = m_model[ column ]; - if( location == null ) - return; - - var parentColumnLocation = location.GetParent() as ColumnHierarchyModel.IColumnLocation; - if( parentColumnLocation != null ) - { - this.UpdateVisibility( parentColumnLocation ); - } - - m_model.Remove( column ); - - this.UnregisterEvents( column ); - } - - private ColumnHierarchyModel.IColumnLocation ReplaceColumnInView( ColumnBase oldColumn, ColumnBase newColumn ) - { - Debug.Assert( ( oldColumn != null ) && ( newColumn != null ) ); - - var oldColumnLocation = m_model[ oldColumn ]; - if( ( oldColumn == newColumn ) || ( oldColumnLocation == null ) ) - return oldColumnLocation; - - var newColumnLocation = m_model[ newColumn ]; - if( newColumnLocation == null ) - { - newColumnLocation = this.AddColumnInView( newColumn, PropagationMode.BottomUp, oldColumnLocation.Level ); - Debug.Assert( newColumnLocation != null ); - } - else if( newColumnLocation.Level != oldColumnLocation.Level ) - { - throw new InvalidOperationException( "The replaced column is not on the same level." ); - } - - Debug.Assert( newColumnLocation.CanMoveAfter( oldColumnLocation ) ); - newColumnLocation.MoveAfter( oldColumnLocation ); - - // Update the location timestamp to keep the column under the parent column. - this.SetPosition( newColumnLocation, newColumnLocation.Status.Position.SetLocationTimestamp( this.GetTimestamp() ) ); - this.SetPosition( newColumnLocation, newColumnLocation.Status.Position.SetDraggableStatusTimestamp( this.GetTimestamp() ) ); - - var lastChildColumnLocation = this.GetColumnsLocation( this.GetChildLocationsFromFirstToLast( newColumnLocation ) ).FirstOrDefault(); - var childColumnLocations = this.GetColumnsLocation( this.GetChildLocationsFromFirstToLast( oldColumnLocation ) ).ToList(); - - // Move the columns under the new column and keep them in the same order. - foreach( var childColumnLocation in childColumnLocations ) - { - if( lastChildColumnLocation != null ) - { - Debug.Assert( childColumnLocation.CanMoveAfter( lastChildColumnLocation ) ); - childColumnLocation.MoveAfter( lastChildColumnLocation ); - } - else - { - Debug.Assert( childColumnLocation.CanMoveUnder( newColumnLocation ) ); - childColumnLocation.MoveUnder( newColumnLocation ); - } - - lastChildColumnLocation = childColumnLocation; - } - - // Reserve a timestamp that is going to be used to keep child columns under their new parent column. - // We want that timestamp to be of "lower priority" than any visible position timestamp update - // on the child columns so a reordering may be done. - var locationTimestamp = this.GetTimestamp(); - - // Update the timestamps on the transfered child columns to keep them under their new parent column. - foreach( var entry in ( from childColumnLocation in childColumnLocations - let positionStatus = childColumnLocation.Status.Position - orderby positionStatus.VisiblePositionTimestamp - select new - { - Location = childColumnLocation, - Status = positionStatus - } ) ) - { - var positionStatus = entry.Status.SetLocationTimestamp( locationTimestamp ); - - if( positionStatus.VisiblePositionTimestamp != 0u ) - { - // Since a visible position reordering was scheduled before the parent column was replaced, - // we must update the visible position timestamp to apply the reordering in the same order - // under the new parent column. - positionStatus = positionStatus.SetVisiblePositionTimestamp( this.GetTimestamp() ); - } - - this.SetPosition( entry.Location, positionStatus ); - } - - this.RemoveColumnInView( oldColumn ); - - return newColumnLocation; - } - - private bool MoveChildColumnUnderLocationInView( ColumnHierarchyModel.IColumnLocation location, ColumnHierarchyModel.ILocation pivot ) - { - if( ( location == null ) || ( pivot == null ) ) - return false; - - // The column is already at the proper location. - if( object.Equals( location.GetParent(), pivot ) ) - return false; - - Debug.Assert( location.CanMoveUnder( pivot ) ); - location.MoveUnder( pivot ); - - var positionStatus = location.Status.Position; - if( positionStatus.VisiblePositionTimestamp == 0u ) - { - // Update the child column status to move it at the right place under its new parent location. - this.SetPosition( location, positionStatus.SetVisiblePositionTimestamp( this.GetTimestamp() ) ); - } - - return true; - } - - private ColumnHierarchyModel.ILocation GetChildColumnLocationDestination( ColumnHierarchyModel.IColumnLocation location, IList relationsHistory ) - { - Debug.Assert( location != null ); - Debug.Assert( ( location.Level >= 0 ) && ( location.Level < m_model.LevelCount - 1 ) ); - - - var column = location.Column; - var positionStatus = location.Status.Position; - var orphanLocation = m_model.GetLevelMarkers( location.Level + 1 ).Orphan; - Debug.Assert( orphanLocation != null ); - - var fallbackParentLocation = location.GetParent(); - var fallbackTimestamp = 0u; - - // Since the target column wants to be under a specific column (or orphan), we must consider the new parent location - // as a possible candidate if it is not one already. - if( ( positionStatus.ParentTimestamp != 0u ) || ( positionStatus.LocationTimestamp != 0u ) ) - { - if( positionStatus.ParentTimestamp > positionStatus.LocationTimestamp ) - { - fallbackParentLocation = orphanLocation; - fallbackTimestamp = positionStatus.ParentTimestamp; - } - else - { - - fallbackParentLocation = location.GetParent(); - fallbackTimestamp = positionStatus.LocationTimestamp; - - Debug.Assert( object.Equals( fallbackParentLocation, location.GetParent() ) ); - } - } - - // Figure out if one of the candidates wants the column. - foreach( var relationHistory in relationsHistory ) - { - // Since the fallback parent location wants the column and it has an higher priority than any remaining - // candidates, there is no need to look for a candidate. - if( relationHistory.Timestamp < fallbackTimestamp ) - break; - - // Since the fallback location is the candidate and it does not want the child column anymore, - // the column should become orphan. - if( object.Equals( fallbackParentLocation, relationHistory.Location ) ) - return orphanLocation; - } - - Debug.Assert( fallbackParentLocation != null ); - return fallbackParentLocation; - } - - private void ApplyColumnsLayoutFromView( int level ) - { - var location = this.GetLocationsOnLevelFromFirstToLast( level ).FirstOrDefault(); - var position = 0; - - while( location != null ) - { - var columnLocation = location as ColumnHierarchyModel.IColumnLocation; - if( columnLocation == null ) - { - location = location.GetNextSiblingOrCousin(); - continue; - } - - var parentColumnLocation = columnLocation.GetParent() as ColumnHierarchyModel.IColumnLocation; - var column = columnLocation.Column; - - column.VisiblePosition = position; - - if( position == 0 ) - { - var columns = column.ContainingCollection; - if( columns != null ) - { - if( ( columns.MainColumn == null ) || ( ( m_dataGridControl != null ) && m_dataGridControl.AreDetailsFlatten ) ) - { - columns.MainColumn = column; - } - } - } - - location = location.GetNextSiblingOrCousin(); - position++; - } - } - - private bool ApplyColumnsVisibilityFromView( ColumnHierarchyModel.ILocation location ) - { - Debug.Assert( location != null ); - - var columnLocation = location as ColumnHierarchyModel.IColumnLocation; - var childrenLocation = this.GetChildLocations( location ).ToList(); - var visibilityStatus = this.GetStatus( location ).Visibility; - - // Apply visibility changes top-down. - if( childrenLocation.Count > 0 ) - { - if( visibilityStatus.Mode == PropagationMode.TopDown ) - { - var childVisibilityStatus = visibilityStatus.SetMode( PropagationMode.TopDown ); - - foreach( var childLocation in ( from l in childrenLocation - let cl = l as ColumnHierarchyModel.IColumnLocation - where ( cl != null ) - && ( cl.Status.Visibility.Timestamp <= childVisibilityStatus.Timestamp ) - select cl ) ) - { - this.SetVisibility( childLocation, childVisibilityStatus ); - } - - // The current column will need to query its child column visibility to determine its visibility. - if( columnLocation != null ) - { - this.SetVisibility( columnLocation, visibilityStatus.SetMode( PropagationMode.BottomUp ) ); - } - } - - // Apply the child columns visibility. - foreach( var childLocation in childrenLocation ) - { - // The layout has been modified while we were updating a child column's visibility. - // A new visibility pass must be done. - if( !this.ApplyColumnsVisibilityFromView( childLocation ) ) - return false; - } - - // Refresh the status in case it changed while applying the child columns visibility. - visibilityStatus = this.GetStatus( location ).Visibility; - } - - // Update the current column's visibility based on its children. - if( columnLocation != null ) - { - if( childrenLocation.Count > 0 ) - { - // Make sure the child columns visible state is not dirty because a user did some changes while we were updating - // the child columns visibility. - if( visibilityStatus.Mode == PropagationMode.BottomUp ) - { - // One of the children is not up-to-date. We need redo the visibility pass. - // We return true because the layout is still the same. - if( !childrenLocation.All( l => this.GetStatus( l ).Visibility.Mode == PropagationMode.None ) ) - return true; - - visibilityStatus = ColumnVisibilityStatus.Create( childrenLocation.Any( l => this.GetStatus( l ).Visibility.Visible ) ); - this.SetVisibility( columnLocation, visibilityStatus ); - } - } - else - { - // A merged column must be hidden when it contains no child column. - visibilityStatus = ColumnVisibilityStatus.Create( visibilityStatus.Visible && ( location.Level == 0 ) ); - this.SetVisibility( columnLocation, visibilityStatus ); - } - } - - // A new visibility pass is required when the visibility needs to be progagated. - if( ( visibilityStatus.Mode != PropagationMode.None ) || ( columnLocation == null ) ) - return true; - - var column = columnLocation.Column; - Debug.Assert( column != null ); - - // Nothing to do. - if( column.Visible == visibilityStatus.Visible ) - return true; - - // The layout is no longer the same since the columns is now hidden or displayed. - this.InvalidateLayout(); - - var layoutVersion = m_modelLayoutVersion; - - column.Visible = visibilityStatus.Visible; - - // The versions will be different if the user altered the layout while we were updating the column's visibility. - return ( layoutVersion == m_modelLayoutVersion ); - } - - private void SetVisibleColumnsFromView( int level, ReadOnlyColumnCollection visibleColumns, HashedLinkedList columnsByVisiblePosition ) - { - Debug.Assert( visibleColumns != null ); - Debug.Assert( columnsByVisiblePosition != null ); - - using( visibleColumns.DeferNotifications() ) - { - // Prevent a Reset event for nothing. - if( visibleColumns.Count != 0 ) - { - visibleColumns.InternalClear(); - } - - columnsByVisiblePosition.Clear(); - - foreach( var column in this.GetColumns( this.GetColumnsLocation( this.GetLocationsOnLevelFromFirstToLast( level ) ) ) ) - { - columnsByVisiblePosition.AddLast( column ); - - using( column.InhibitVisiblePositionChanging() ) - { - if( column.Visible ) - { - visibleColumns.InternalAdd( column ); - } - } - } - } - - var firstVisibleColumn = default( ColumnBase ); - var lastVisibleColumn = default( ColumnBase ); - - foreach( var column in columnsByVisiblePosition ) - { - if( column.Visible ) - { - if( firstVisibleColumn == null ) - { - firstVisibleColumn = column; - } - else - { - column.ClearIsFirstVisible(); - } - - if( lastVisibleColumn != null ) - { - lastVisibleColumn.ClearIsLastVisible(); - } - - lastVisibleColumn = column; - } - else - { - column.ClearIsFirstVisible(); - column.ClearIsLastVisible(); - } - } - - if( firstVisibleColumn != null ) - { - firstVisibleColumn.SetIsFirstVisible( true ); - } - - if( lastVisibleColumn != null ) - { - lastVisibleColumn.SetIsLastVisible( true ); - } - } - - private IEnumerable GetLocationsOnLevelFromFirstToLast( int level ) - { - var location = ( ColumnHierarchyModel.ILocation )m_model.GetLevelMarkers( level ).Start; - Debug.Assert( location.GetPreviousSiblingOrCousin() == null ); - - while( location != null ) - { - yield return location; - - location = location.GetNextSiblingOrCousin(); - } - } - - private IEnumerable GetLocationsOnLevelFromLastToFirst( int level ) - { - var location = ( ColumnHierarchyModel.ILocation )m_model.GetLevelMarkers( level ).End; - Debug.Assert( location.GetNextSiblingOrCousin() == null ); - - while( location != null ) - { - yield return location; - - location = location.GetPreviousSiblingOrCousin(); - } - } - - private IEnumerable GetLocationsOnLevel( int level ) - { - return this.GetLocationsOnLevelFromFirstToLast( level ); - } - - private IEnumerable GetChildLocationsFromFirstToLast( ColumnHierarchyModel.ILocation parentLocation ) - { - if( parentLocation != null ) - { - var location = parentLocation.GetFirstChild(); - - while( location != null ) - { - yield return location; - - location = location.GetNextSibling(); - } - } - } - - private IEnumerable GetChildLocationsFromLastToFirst( ColumnHierarchyModel.ILocation parentLocation ) - { - return this.GetChildLocationsFromFirstToLast( parentLocation ).Reverse(); - } - - private IEnumerable GetChildLocations( ColumnHierarchyModel.ILocation parentLocation ) - { - return this.GetChildLocationsFromFirstToLast( parentLocation ); - } - - private IEnumerable GetColumnsLocation( IEnumerable locations ) - { - return ( from location in locations - let columnLocation = location as ColumnHierarchyModel.IColumnLocation - where ( columnLocation != null ) - select columnLocation ); - } - - private IEnumerable GetColumns( IEnumerable locations ) - { - return ( from location in locations - select location.Column ); - } - - private IEnumerable GetColumns( int level ) - { - return this.GetColumns( this.GetColumnsLocation( this.GetLocationsOnLevel( level ) ) ); - } - - private ColumnStatus GetStatus( ColumnHierarchyModel.ILocation location ) - { - var columnLocation = location as ColumnHierarchyModel.IColumnLocation; - if( columnLocation != null ) - return columnLocation.Status; - - return new ColumnStatus( ColumnVisibilityStatus.Create( false ) ); - } - - private void InvalidateLayout() - { - unchecked - { - m_modelLayoutVersion++; - } - } - - private void InvalidatePosition() - { - unchecked - { - m_modelPositionVersion++; - } - } - - private void InvalidateVisibility() - { - unchecked - { - m_modelVisibilityVersion++; - } - } - - private uint GetTimestamp() - { - checked - { - m_timestamp++; - } - - return m_timestamp; - } - - private void ResetTimestamp() - { - if( m_timestamp == 0u ) - return; - - this.ResetStatus(); - - // The position and visibility counter are reset here since a call to ResetStatus may update them. These updates may be safely ignored. - m_positionVersion = m_modelPositionVersion; - m_visibilityVersion = m_modelVisibilityVersion; - - // The counter is reset to lower the chance of an overflow. - m_timestamp = 0u; - } - - private void UpdateVisibility( ColumnHierarchyModel.IColumnLocation location ) - { - if( location == null ) - return; - - // An update is already scheduled. - var visibilityStatus = location.Status.Visibility; - if( visibilityStatus.Mode != PropagationMode.None ) - return; - - this.SetVisibility( location, visibilityStatus.SetMode( PropagationMode.BottomUp ) ); - } - - private void SetVisibility( ColumnHierarchyModel.IColumnLocation location, ColumnVisibilityStatus visibilityStatus ) - { - if( location == null ) - return; - - var status = location.Status; - - this.SetStatus( location, status.SetVisibilityStatus( visibilityStatus ) ); - } - - private void SetPosition( ColumnHierarchyModel.IColumnLocation location, ColumnPositionStatus positionStatus ) - { - if( location == null ) - return; - - var status = location.Status; - - this.SetStatus( location, status.SetPositionStatus( positionStatus ) ); - } - - private void SetStatus( ColumnHierarchyModel.IColumnLocation location, ColumnStatus status ) - { - if( ( location == null ) || object.Equals( location.Status, status ) ) - return; - - location.Status = status; - } - - private ILevelMarkers WrapLevelMarkers( ColumnHierarchyModel.IMarkers markers ) - { - if( markers == null ) - return null; - - return new Markers( this, markers ); - } - - private ILocation WrapLocation( ColumnHierarchyModel.ILocation location ) - { - if( location == null ) - return null; - - if( location.Type == LocationType.Column ) - { - Debug.Assert( location is ColumnHierarchyModel.IColumnLocation ); - return new ColumnLocation( this, ( ColumnHierarchyModel.IColumnLocation )location ); - } - - return new Location( this, location ); - } - - private void RegisterEvents( ColumnCollection collection ) - { - Debug.Assert( collection != null ); - - CollectionChangedEventManager.AddListener( collection, this ); - PropertyChangedEventManager.AddListener( collection, this, string.Empty ); - } - - private void UnregisterEvents( ColumnCollection collection ) - { - Debug.Assert( collection != null ); - - CollectionChangedEventManager.RemoveListener( collection, this ); - PropertyChangedEventManager.RemoveListener( collection, this, string.Empty ); - } - - private void RegisterEvents( ColumnBase column ) - { - Debug.Assert( column != null ); - PropertyChangedEventManager.AddListener( column, this, string.Empty ); - } - - private void UnregisterEvents( ColumnBase column ) - { - Debug.Assert( column != null ); - - PropertyChangedEventManager.RemoveListener( column, this, string.Empty ); - } - - private void OnColumnsChanged( NotifyCollectionChangedEventArgs e ) - { - Debug.Assert( m_model.LevelCount > 0 ); - - var resetFixedRegions = false; - var resetItemContainerGenerator = false; - - switch( e.Action ) - { - case NotifyCollectionChangedAction.Add: - { - var items = e.NewItems; - if( ( items == null ) || ( items.Count <= 0 ) ) - return; - - Debug.Assert( m_model.LevelCount > 0 ); - - // Only reset the fixed headers/footers if columns are at the master level. - resetFixedRegions = ( m_columns.ParentDetailConfiguration == null ); - - foreach( ColumnBase column in items ) - { - this.AddColumnInView( column, PropagationMode.None, 0 ); - } - } - break; - - case NotifyCollectionChangedAction.Remove: - { - var items = e.OldItems; - if( ( items == null ) || ( items.Count <= 0 ) ) - return; - - resetItemContainerGenerator = true; - - foreach( ColumnBase column in items ) - { - this.RemoveColumnInView( column ); - } - } - break; - - case NotifyCollectionChangedAction.Move: - // Nothing to do. - return; - - case NotifyCollectionChangedAction.Replace: - { - var oldItems = e.OldItems; - if( ( oldItems == null ) || ( oldItems.Count <= 0 ) ) - return; - - var newItems = e.NewItems; - if( ( newItems == null ) || ( newItems.Count <= 0 ) ) - return; - - if( newItems.Count != oldItems.Count ) - throw new NotSupportedException(); - - resetItemContainerGenerator = true; - - for( int i = 0; i < oldItems.Count; i++ ) - { - this.ReplaceColumnInView( ( ColumnBase )oldItems[ i ], ( ColumnBase )newItems[ i ] ); - } - } - break; - - case NotifyCollectionChangedAction.Reset: - { - var result = this.SetColumnsInView( 0 ); - resetFixedRegions = result.Item1; - resetItemContainerGenerator = result.Item2; - } - break; - - default: - throw new NotSupportedException(); - } - - this.Update(); - - if( resetFixedRegions ) - { - m_dataGridControl.ResetFixedRegions(); - } - // When a column is removed, we need to clear the generator from every container to avoid problem - // when a new instance of a column with the same field name is reinserted. - else if( resetItemContainerGenerator ) - { - var itemContainerGenerator = m_dataGridControl.CustomItemContainerGenerator; - if( itemContainerGenerator != null ) - { - itemContainerGenerator.RemoveAllAndNotify(); - } - - // Only reset the fixed headers/footers if columns are at the master level. - if( m_columns.ParentDetailConfiguration == null ) - { - m_dataGridControl.ResetFixedRegions(); - } - } - } - - private void OnColumnCollectionPropertyChanged( PropertyChangedEventArgs e ) - { - var mayHaveChanged = string.IsNullOrEmpty( e.PropertyName ); - - if( mayHaveChanged || ( e.PropertyName == ColumnCollection.MainColumnPropertyName ) ) - { - // We don't want to alter the layout while it is being applied. Furthermore, it is most likely the - // new layout that triggered the change notification. - if( !m_isApplyingChanges.IsSet ) - { - // The ColumnCollection.MainColumn (ColumnBase.IsMainColumn) property impacts the columns layout when details are flatten. - if( ( m_dataGridControl != null ) && m_dataGridControl.AreDetailsFlatten ) - { - var mainColumn = m_columns.MainColumn; - var mainColumnLocation = ( mainColumn != null ) ? m_model[ mainColumn ] : null; - - if( mainColumnLocation != null ) - { - Debug.Assert( mainColumnLocation.Level == 0 ); - - var columnsToMove = new Stack(); - columnsToMove.Push( mainColumnLocation.Column ); - - var parentLocation = mainColumnLocation.GetParent(); - while( parentLocation != null ) - { - var parentColumnLocation = parentLocation as ColumnHierarchyModel.IColumnLocation; - if( parentColumnLocation == null ) - { - // The desired main column is under one of the orphan section. - // It is impossible to move the column and its parent to the first location. - columnsToMove.Clear(); - break; - } - - columnsToMove.Push( parentColumnLocation.Column ); - parentLocation = parentLocation.GetParent(); - } - - while( columnsToMove.Count > 0 ) - { - var column = columnsToMove.Pop(); - var columnLocation = m_model[ column ]; - Debug.Assert( columnLocation != null ); - - var pivotLocation = columnLocation; - var previousLocation = ( ColumnHierarchyModel.ILocation )pivotLocation; - - while( previousLocation != null ) - { - if( previousLocation.Type == LocationType.Column ) - { - pivotLocation = ( ColumnHierarchyModel.IColumnLocation )previousLocation; - } - - previousLocation = previousLocation.GetPreviousSibling(); - } - - if( !object.Equals( columnLocation, pivotLocation ) ) - { - Debug.Assert( columnLocation.CanMoveBefore( pivotLocation ) ); - columnLocation.MoveBefore( pivotLocation ); - - this.SetPosition( columnLocation, columnLocation.Status.Position.SetLocationTimestamp( this.GetTimestamp() ) ); - } - } - } - } - } - - this.InvalidateLayout(); - this.Update(); - } - } - - private void OnColumnPropertyChanged( ColumnBase column, PropertyChangedEventArgs e ) - { - var mayHaveChanged = string.IsNullOrEmpty( e.PropertyName ); - var columnLocation = m_model[ column ]; - var needUpdate = false; - - Debug.Assert( columnLocation != null ); - - if( mayHaveChanged || ( e.PropertyName == ColumnBase.VisibleProperty.Name ) ) - { - if( column.Visible != columnLocation.Status.Visibility.Visible ) - { - this.SetVisibility( columnLocation, ColumnVisibilityStatus.Create( column.Visible, PropagationMode.TopDown, this.GetTimestamp() ) ); - } - - needUpdate = true; - } - - if( mayHaveChanged || ( e.PropertyName == ColumnBase.VisiblePositionProperty.Name ) ) - { - this.SetPosition( columnLocation, columnLocation.Status.Position.SetVisiblePositionTimestamp( this.GetTimestamp() ) ); - - // We must invalidate the layout no matter what to make sure the column's visible position is recalculated and reapplied. - this.InvalidateLayout(); - - needUpdate = true; - } - - if( mayHaveChanged || ( e.PropertyName == ColumnBase.DraggableStatusProperty.Name ) ) - { - this.SetPosition( columnLocation, columnLocation.Status.Position.SetDraggableStatusTimestamp( this.GetTimestamp() ) ); - - needUpdate = true; - } - - if( mayHaveChanged || ( e.PropertyName == ColumnBase.IsMainColumnPropertyName ) ) - { - this.SetPosition( columnLocation, columnLocation.Status.Position.SetMainColumnTimestamp( this.GetTimestamp() ) ); - - needUpdate = true; - } - - if( mayHaveChanged) - { - ColumnHierarchyModel parentColumnLocation = null; - - if( !object.Equals( columnLocation.GetParent(), parentColumnLocation ) ) - { - this.SetPosition( columnLocation, columnLocation.Status.Position.SetParentTimestamp( this.GetTimestamp() ) ); - } - - needUpdate = true; - } - - if( needUpdate ) - { - this.Update(); - } - } - - private void OnViewLayoutChanging( object sender, ColumnHierarchyModel.LayoutChangingEventArgs e ) - { - switch( e.Action ) - { - case ColumnHierarchyModel.LayoutChangingAction.ChangingParent: - case ColumnHierarchyModel.LayoutChangingAction.ChangingFirstChild: - case ColumnHierarchyModel.LayoutChangingAction.Removing: - { - var location = e.Location.GetParent() as ColumnHierarchyModel.IColumnLocation; - if( location != null ) - { - this.UpdateVisibility( location ); - } - } - break; - } - - this.InvalidateLayout(); - } - - private void OnViewLayoutChanged( object sender, ColumnHierarchyModel.LayoutChangedEventArgs e ) - { - switch( e.Action ) - { - case ColumnHierarchyModel.LayoutChangedAction.ParentChanged: - case ColumnHierarchyModel.LayoutChangedAction.FirstChildChanged: - { - var location = e.Location.GetParent() as ColumnHierarchyModel.IColumnLocation; - if( location != null ) - { - this.UpdateVisibility( location ); - } - } - break; - } - - this.InvalidateLayout(); - } - - private void OnViewStatusChanged( object sender, ColumnHierarchyModel.StatusChangedEventArgs e ) - { - var oldStatus = e.OldValue; - var oldVisibilityStatus = oldStatus.Visibility; - var oldPositionStatus = oldStatus.Position; - var newStatus = e.NewValue; - var newVisibilityStatus = newStatus.Visibility; - var newPositionStatus = newStatus.Position; - - if( oldVisibilityStatus.Visible != newVisibilityStatus.Visible ) - { - var parentColumnLocation = e.Location.GetParent() as ColumnHierarchyModel.IColumnLocation; - if( parentColumnLocation != null ) - { - this.UpdateVisibility( parentColumnLocation ); - } - - // The layout is no longer the same since a columns is now hidden or displayed. - this.InvalidateLayout(); - } - - if( !object.Equals( oldPositionStatus, newPositionStatus ) ) - { - this.InvalidatePosition(); - } - - this.InvalidateVisibility(); - } - - #region IWeakEventListener Members - - bool IWeakEventListener.ReceiveWeakEvent( Type managerType, object sender, EventArgs e ) - { - return this.OnReceiveWeakEvent( managerType, sender, e ); - } - - private bool OnReceiveWeakEvent( Type managerType, object sender, EventArgs e ) - { - if( managerType == typeof( CollectionChangedEventManager ) ) - { - Debug.Assert( m_dataGridControl != null, "The current object should be initialized." ); - - var eventArgs = ( NotifyCollectionChangedEventArgs )e; - - if( sender == m_columns ) - { - this.OnColumnsChanged( eventArgs ); - } - } - else if( managerType == typeof( PropertyChangedEventManager ) ) - { - Debug.Assert( m_dataGridControl != null, "The current object should be initialized." ); - - var eventArgs = ( PropertyChangedEventArgs )e; - - if( sender is ColumnBase ) - { - this.OnColumnPropertyChanged( ( ColumnBase )sender, eventArgs ); - } - else if( sender == m_columns ) - { - this.OnColumnCollectionPropertyChanged( eventArgs ); - } - } - else - { - return false; - } - - return true; - } - - #endregion - - private readonly ColumnHierarchyModel m_model = new ColumnHierarchyModel(); - private readonly AutoResetFlag m_isApplyingChanges = AutoResetFlagFactory.Create( true ); - private DataGridControl m_dataGridControl; - private int m_deferUpdateCount; //0 - private int? m_desiredFixedColumnCount; //null - private bool m_synchronizeChildColumnNamesWithChildColumns; //false - private uint m_timestamp; //0 - private int m_modelLayoutVersion; //0 - private int m_modelPositionVersion; //0 - private int m_modelVisibilityVersion; //0 - private int m_layoutVersion; //0 - private int m_positionVersion; //0 - private int m_visibilityVersion; //0 - - #region ILevelMarkers Internal Interface - - internal interface ILevelMarkers - { - ILocation Start - { - get; - } - - ILocation End - { - get; - } - - ILocation Splitter - { - get; - } - - ILocation Orphan - { - get; - } - } - - #endregion - - #region ILocation Internal Interface - - internal interface ILocation - { - LocationType Type - { - get; - } - - ILocation GetParent(); - ILocation GetFirstChild(); - ILocation GetLastChild(); - - ILocation GetPreviousSibling(); - ILocation GetNextSibling(); - - ILocation GetPreviousSiblingOrCousin(); - ILocation GetNextSiblingOrCousin(); - - bool CanMoveBefore( ILocation location ); - bool CanMoveAfter( ILocation location ); - bool CanMoveUnder( ILocation location ); - - void MoveBefore( ILocation location ); - void MoveAfter( ILocation location ); - void MoveUnder( ILocation location ); - } - - #endregion - - #region IColumnLocation Internal Interface - - internal interface IColumnLocation : ILocation - { - ColumnBase Column - { - get; - } - } - - #endregion - - #region UpdateOptions Internal Struct - - internal struct UpdateOptions - { - internal UpdateOptions( int desiredFixedColumnCount ) - { - m_desiredFixedColumnCount = desiredFixedColumnCount; - m_synchronizeChildColumnNamesWithChildColumns = default( bool? ); - } - - internal UpdateOptions( int desiredFixedColumnCount, bool synchronizeChildColumnNamesWithChildColumns ) - { - m_desiredFixedColumnCount = desiredFixedColumnCount; - m_synchronizeChildColumnNamesWithChildColumns = synchronizeChildColumnNamesWithChildColumns; - } - - internal int? DesiredFixedColumnCount - { - get - { - return m_desiredFixedColumnCount; - } - set - { - m_desiredFixedColumnCount = value; - } - } - - internal bool? SynchronizeChildColumnNamesWithChildColumns - { - get - { - return m_synchronizeChildColumnNamesWithChildColumns; - } - set - { - m_synchronizeChildColumnNamesWithChildColumns = value; - } - } - - private int? m_desiredFixedColumnCount; - private bool? m_synchronizeChildColumnNamesWithChildColumns; - } - - #endregion - - #region Markers Private Class - - private sealed class Markers : ILevelMarkers - { - internal Markers( ColumnHierarchyManager owner, ColumnHierarchyModel.IMarkers markers ) - { - Debug.Assert( owner != null ); - Debug.Assert( markers != null ); - - m_owner = owner; - m_markers = markers; - } - - public ILocation Start - { - get - { - return m_owner.WrapLocation( m_markers.Start ); - } - } - - public ILocation End - { - get - { - return m_owner.WrapLocation( m_markers.End ); - } - } - - public ILocation Splitter - { - get - { - return m_owner.WrapLocation( m_markers.Splitter ); - } - } - - public ILocation Orphan - { - get - { - return m_owner.WrapLocation( m_markers.Orphan ); - } - } - - public override int GetHashCode() - { - return m_markers.GetHashCode(); - } - - public override bool Equals( object obj ) - { - var target = obj as Markers; - if( target == null ) - return false; - - return ( m_owner == target.m_owner ) - && ( object.Equals( m_markers, target.m_markers ) ); - } - - private readonly ColumnHierarchyManager m_owner; - private readonly ColumnHierarchyModel.IMarkers m_markers; - } - - #endregion - - #region Location Private Class - - private class Location : ILocation - { - internal Location( ColumnHierarchyManager owner, ColumnHierarchyModel.ILocation location ) - { - Debug.Assert( owner != null ); - Debug.Assert( location != null ); - - m_owner = owner; - m_location = location; - } - - protected ColumnHierarchyManager Owner - { - get - { - return m_owner; - } - } - - protected ColumnHierarchyModel.ILocation LocationCache - { - get - { - return m_location; - } - } - - LocationType ILocation.Type - { - get - { - return m_location.Type; - } - } - - public override int GetHashCode() - { - return m_location.GetHashCode(); - } - - public override bool Equals( object obj ) - { - var target = obj as Location; - if( target == null ) - return false; - - return ( m_owner == target.m_owner ) - && ( object.Equals( m_location, target.m_location ) ); - } - - protected virtual void OnMovedBefore( Location location ) - { - } - - protected virtual void OnMovedAfter( Location location ) - { - } - - protected virtual void OnMovedUnder( Location location ) - { - } - - ILocation ILocation.GetParent() - { - return m_owner.WrapLocation( m_location.GetParent() ); - } - - ILocation ILocation.GetFirstChild() - { - return m_owner.WrapLocation( m_location.GetFirstChild() ); - } - - ILocation ILocation.GetLastChild() - { - var location = m_location.GetFirstChild(); - if( location == null ) - return m_owner.WrapLocation( null ); - - var next = location.GetNextSibling(); - while( next != null ) - { - location = next; - next = next.GetNextSibling(); - } - - return m_owner.WrapLocation( location ); - } - - ILocation ILocation.GetPreviousSibling() - { - return m_owner.WrapLocation( m_location.GetPreviousSibling() ); - } - - ILocation ILocation.GetNextSibling() - { - return m_owner.WrapLocation( m_location.GetNextSibling() ); - } - - ILocation ILocation.GetPreviousSiblingOrCousin() - { - return m_owner.WrapLocation( m_location.GetPreviousSiblingOrCousin() ); - } - - ILocation ILocation.GetNextSiblingOrCousin() - { - return m_owner.WrapLocation( m_location.GetNextSiblingOrCousin() ); - } - - bool ILocation.CanMoveBefore( ILocation location ) - { - var target = location as Location; - if( target == null ) - return false; - - return m_location.CanMoveBefore( target.m_location ); - } - - bool ILocation.CanMoveAfter( ILocation location ) - { - var target = location as Location; - if( target == null ) - return false; - - return m_location.CanMoveAfter( target.m_location ); - } - - bool ILocation.CanMoveUnder( ILocation location ) - { - var target = location as Location; - if( target == null ) - return false; - - return m_location.CanMoveUnder( target.m_location ); - } - - void ILocation.MoveBefore( ILocation location ) - { - Debug.Assert( ( ( ILocation )this ).CanMoveBefore( location ) ); - - var pivot = ( Location )location; - Debug.Assert( pivot != null ); - - m_location.MoveBefore( pivot.m_location ); - this.OnMovedBefore( pivot ); - - m_owner.Update(); - } - - void ILocation.MoveAfter( ILocation location ) - { - Debug.Assert( ( ( ILocation )this ).CanMoveAfter( location ) ); - - var pivot = ( Location )location; - Debug.Assert( pivot != null ); - - m_location.MoveAfter( pivot.m_location ); - this.OnMovedAfter( pivot ); - - m_owner.Update(); - } - - void ILocation.MoveUnder( ILocation location ) - { - Debug.Assert( ( ( ILocation )this ).CanMoveUnder( location ) ); - - var pivot = ( Location )location; - Debug.Assert( pivot != null ); - - m_location.MoveUnder( pivot.m_location ); - this.OnMovedUnder( pivot ); - - m_owner.Update(); - } - - private readonly ColumnHierarchyManager m_owner; - private readonly ColumnHierarchyModel.ILocation m_location; - } - - #endregion - - #region ColumnLocation Private Class - - private sealed class ColumnLocation : Location, IColumnLocation - { - internal ColumnLocation( ColumnHierarchyManager owner, ColumnHierarchyModel.IColumnLocation location ) - : base( owner, location ) - { - } - - private ColumnHierarchyModel.IColumnLocation TargetLocation - { - get - { - return ( ColumnHierarchyModel.IColumnLocation )this.LocationCache; - } - } - - ColumnBase IColumnLocation.Column - { - get - { - return this.TargetLocation.Column; - } - } - - protected override void OnMovedBefore( Location location ) - { - base.OnMovedBefore( location ); - - this.InvalidatePosition(); - } - - protected override void OnMovedAfter( Location location ) - { - base.OnMovedAfter( location ); - - this.InvalidatePosition(); - } - - protected override void OnMovedUnder( Location location ) - { - base.OnMovedUnder( location ); - - this.InvalidatePosition(); - } - - private void InvalidatePosition() - { - var owner = this.Owner; - var columnLocation = this.TargetLocation; - var positionStatus = columnLocation.Status.Position.SetLocationTimestamp( owner.GetTimestamp() ); - - owner.SetPosition( columnLocation, positionStatus ); - } - } - - #endregion - - #region ColumnHierarchyModel Private Class - - private sealed class ColumnHierarchyModel : ColumnHierarchyModel - { - } - - #endregion - - #region ColumnLocationOrderer Private Class - - private static class ColumnLocationOrderer - { - internal static void Reorder( IList locations, bool useDraggableStatus ) - { - if( ColumnLocationOrderer.IsUnchanged( locations ) ) - return; - - var lockedFirst = new List(); - var lockedLast = new List(); - var unlocked = new List(); - - ColumnLocationOrderer.Split( locations, useDraggableStatus, lockedFirst, lockedLast, unlocked ); - - var lockedFirstStartIndex = 0; - var unlockedStartIndex = lockedFirstStartIndex + lockedFirst.Count; - var lockedLastStartIndex = unlockedStartIndex + unlocked.Count; - - ColumnLocationOrderer.Reorder( locations, lockedFirst, lockedFirstStartIndex ); - ColumnLocationOrderer.Reorder( locations, unlocked, unlockedStartIndex ); - ColumnLocationOrderer.Reorder( locations, lockedLast, lockedLastStartIndex ); - - var newOrder = new int[ locations.Count ]; - - lockedFirst.CopyTo( newOrder, lockedFirstStartIndex ); - unlocked.CopyTo( newOrder, unlockedStartIndex ); - lockedLast.CopyTo( newOrder, lockedLastStartIndex ); - - // Move the locations to get them in the desired order. - ColumnLocationOrderer.Apply( locations, newOrder ); - } - - private static void Reorder( IList locations, IList indexes, int startingPosition ) - { - Debug.Assert( locations != null ); - Debug.Assert( indexes != null ); - - var count = indexes.Count; - if( count <= 1 ) - return; - - var positionsStatus = new ColumnPositionStatus[ count ]; - var newOrder = new int[ count ]; - var movableCount = 0; - var reorderCount = 0; - - // Do a pass to check if a reordering is required. - for( int i = 0; i < positionsStatus.Length; i++ ) - { - var index = indexes[ i ]; - var positionStatus = locations[ index ].Status.Position; - - positionsStatus[ i ] = positionStatus; - - if( positionStatus.LocationTimestamp > positionStatus.VisiblePositionTimestamp ) - { - // This location is considered fixed and will not be sorted. - newOrder[ i ] = index; - } - else - { - // This location is considered movable and may be sorted. - newOrder[ i ] = -1; - movableCount++; - - // This location visible position has changed, so we will need to apply - // an algorithm to figure out where to put it. - if( positionStatus.VisiblePositionTimestamp != 0u ) - { - reorderCount++; - } - } - } - - // Nothing to do if all columns stay where they are. - if( ( reorderCount <= 0 ) || ( movableCount <= 1 ) ) - return; - - var visiblePositions = new List( count ); - var slots = new List( movableCount ); - var movables = new List( movableCount ); - var reorder = new List>( reorderCount ); - - // Separate the movable locations that were updated from the ones that were not. - for( int i = 0; i < newOrder.Length; i++ ) - { - visiblePositions.Add( locations[ indexes[ i ] ].Column.VisiblePosition ); - - // This location is fixed. - if( newOrder[ i ] >= 0 ) - continue; - - slots.Add( new Slot( i, startingPosition + i ) ); - - var timestamp = positionsStatus[ i ].VisiblePositionTimestamp; - if( timestamp == 0u ) - { - movables.Add( i ); - } - else - { - reorder.Add( new Tuple( i, timestamp ) ); - } - } - - var comparer = new MovableComparer( slots, visiblePositions ); - - // Reinsert the updated movable locations in a time fashion order into the not updated movable locations. - foreach( var i in ( from item in reorder - orderby item.Item2, item.Item1 - select item.Item1 ) ) - { - // This property is set to help the comparer identify the element the binary search is looking for. - // The algorithm is complex and need more information than the ones provided by the IComparer<>.Compare method. - comparer.LookFor = i; - - var index = movables.BinarySearch( i, comparer ); - if( index < 0 ) - { - index = ~index; - } - - if( index >= movables.Count ) - { - movables.Add( i ); - } - else - { - movables.Insert( index, i ); - } - } - - Debug.Assert( movables.Count == movableCount ); - - // Reinsert the movable locations into the fixed locations. - for( int i = 0; i < movables.Count; i++ ) - { - newOrder[ slots[ i ].Index ] = indexes[ movables[ i ] ]; - } - - // Set the results. - for( int i = 0; i < newOrder.Length; i++ ) - { - indexes[ i ] = newOrder[ i ]; - } - } - - private static void Apply( IList locations, IList indexes ) - { - Debug.Assert( locations != null ); - Debug.Assert( indexes != null ); - Debug.Assert( locations.Count == indexes.Count ); - - for( int i = 0; i < indexes.Count - 1; i++ ) - { - var pivot = locations[ indexes[ i ] ]; - var target = locations[ indexes[ i + 1 ] ]; - var next = pivot.GetNextSibling(); - - while( !object.Equals( next, target ) ) - { - if( ( next == null ) || ( next.Type == LocationType.Column ) ) - { - Debug.Assert( target.CanMoveAfter( pivot ) ); - target.MoveAfter( pivot ); - break; - } - // A splitter may be located between the columns. Make sure not to move the column if it - // is the case or the splitter will go back next to the starting location. - else - { - next = next.GetNextSibling(); - } - } - } - } - - private static bool IsUnchanged( IList locations ) - { - if( ( locations == null ) || ( locations.Count <= 1 ) ) - return true; - - // Do a pass to check if a reordering is required. - foreach( var location in locations ) - { - var positionStatus = location.Status.Position; - - // This location's lock type may have changed, so does its position. - if( ( positionStatus.DraggableStatusTimestamp != 0u ) || ( positionStatus.MainColumnTimestamp != 0u ) ) - return false; - - if( location.Column.DraggableStatus != ColumnDraggableStatus.Draggable ) - { - // This location may have change position, so we will need to apply an algorithm to figure out where to put it. - if( ( positionStatus.LocationTimestamp != 0u ) || ( positionStatus.VisiblePositionTimestamp != 0u ) ) - return false; - } - else - { - // This location is considered fixed and will not be sorted. - if( positionStatus.LocationTimestamp > positionStatus.VisiblePositionTimestamp ) - continue; - - // This location visible position has changed, so we will need to apply - // an algorithm to figure out where to put it. - if( positionStatus.VisiblePositionTimestamp != 0u ) - return false; - } - } - - return true; - } - - private static void Split( IList locations, bool useDraggableStatus, IList lockedFirst, IList lockedLast, IList unlocked ) - { - Debug.Assert( locations != null ); - Debug.Assert( lockedFirst != null ); - Debug.Assert( lockedLast != null ); - Debug.Assert( unlocked != null ); - - for( int i = 0; i < locations.Count; i++ ) - { - var column = locations[ i ].Column; - var draggableStatus = column.DraggableStatus; - - if( useDraggableStatus ) - { - switch( draggableStatus ) - { - case ColumnDraggableStatus.FirstUndraggable: - { - lockedFirst.Add( i ); - } - break; - - case ColumnDraggableStatus.LastUndraggable: - { - lockedLast.Add( i ); - } - break; - - case ColumnDraggableStatus.Draggable: - { - unlocked.Add( i ); - } - break; - - default: - throw new NotImplementedException(); - } - } - else - { - unlocked.Add( i ); - } - } - } - - private sealed class MovableComparer : IComparer - { - private static readonly IComparer SlotComparer = new VisiblePositionComparer(); - - internal MovableComparer( List slots, IList positions ) - { - m_slots = slots; - m_positions = positions; - } - - internal int LookFor - { - set - { - m_lookFor = value; - } - } - - public int Compare( int x, int y ) - { - if( x == m_lookFor ) - { - var xPosition = m_positions[ x ]; - var yPosition = m_positions[ y ]; - - // Since we are using this comparer to reinsert updated locations in time order, - // a visible position that is lesser than any other location should always be inserted before. - if( ( xPosition < yPosition ) ) - return -1; - - // For a visible position that is greater or equal, we must look at the available movables - // slots to insert the column in the slot that is the nearest to the desired target position. - var xSlot = this.FindSlot( xPosition ); - var ySlot = this.FindSlot( yPosition ); - - var compare = xSlot.CompareTo( ySlot ); - if( compare != 0 ) - return compare; - - var position = this.FindPosition( xSlot ); - - // The location is moving toward the end. - if( x < position ) - { - if( y <= position ) - return 1; - - return -1; - } - // The location is moving toward the start. - else if( x > position ) - { - if( y >= position ) - return -1; - - return 1; - } - } - else if( y == m_lookFor ) - { - var xPosition = m_positions[ x ]; - var yPosition = m_positions[ y ]; - - // Since we are using this comparer to reinsert updated locations in time order, - // a visible position that is lesser than any other location should always be inserted before. - if( ( yPosition < xPosition ) ) - return 1; - - // For a visible position that is greater or equal, we must look at the available movables - // slots to insert the column in the slot that is the nearest to the desired target position. - var xSlot = this.FindSlot( xPosition ); - var ySlot = this.FindSlot( yPosition ); - - var compare = xSlot.CompareTo( ySlot ); - if( compare != 0 ) - return compare; - - var position = this.FindPosition( ySlot ); - - // The location is moving toward the end. - if( y < position ) - { - if( x <= position ) - return -1; - - return 1; - } - // The location is moving toward the start. - else if( y > position ) - { - if( x >= position ) - return 1; - - return -1; - } - } - - return x.CompareTo( y ); - } - - private int FindSlot( int position ) - { - var index = m_slots.BinarySearch( new Slot( 0, position ), MovableComparer.SlotComparer ); - if( index < 0 ) - return ~index; - - return index; - } - - private int FindPosition( int slot ) - { - Debug.Assert( ( slot >= 0 ) && ( slot <= m_slots.Count ) ); - - if( slot >= m_slots.Count ) - return m_slots.Last().Index + 1; - - return m_slots[ slot ].Index; - } - - private readonly List m_slots; - private readonly IList m_positions; - private int m_lookFor; - - private sealed class VisiblePositionComparer : IComparer - { - public int Compare( Slot x, Slot y ) - { - return x.VisiblePosition.CompareTo( y.VisiblePosition ); - } - } - } - - private struct Slot - { - internal Slot( int index, int visiblePosition ) - { - Debug.Assert( index >= 0 ); - Debug.Assert( visiblePosition >= 0 ); - - this.Index = index; - this.VisiblePosition = visiblePosition; - } - - internal readonly int Index; - internal readonly int VisiblePosition; - } - } - - #endregion - - #region DeferUpdateState Private Class - - private sealed class DeferUpdateState : DeferredDisposableState - { - internal DeferUpdateState( ColumnHierarchyManager target, UpdateOptions options ) - { - if( target == null ) - throw new ArgumentNullException( "target" ); - - m_target = target; - m_options = options; - } - - protected override object SyncRoot - { - get - { - return m_target.SyncRoot; - } - } - - protected override bool IsDeferred - { - get - { - return ( m_target.m_deferUpdateCount != 0 ); - } - } - - protected override void Increment() - { - m_target.m_deferUpdateCount++; - } - - protected override void Decrement() - { - m_target.m_deferUpdateCount--; - } - - protected override void OnDeferEnded( bool disposing ) - { - if( !disposing ) - return; - - m_target.Update( m_options ); - } - - private readonly ColumnHierarchyManager m_target; - private readonly UpdateOptions m_options; - } - - #endregion - - #region ColumnStatus Private Struct - - private struct ColumnStatus - { - internal ColumnStatus( ColumnVisibilityStatus visibility ) - : this( default( ColumnPositionStatus ), visibility ) - { - } - - internal ColumnStatus( ColumnPositionStatus position, ColumnVisibilityStatus visibility ) - { - this.Position = position; - this.Visibility = visibility; - } - - internal ColumnStatus SetPositionStatus( ColumnPositionStatus status ) - { - return new ColumnStatus( status, this.Visibility ); - } - - internal ColumnStatus SetVisibilityStatus( ColumnVisibilityStatus status ) - { - return new ColumnStatus( this.Position, status ); - } - - internal readonly ColumnPositionStatus Position; - internal readonly ColumnVisibilityStatus Visibility; - } - - #endregion - - #region ColumnVisibilityStatus Private Struct - - [DebuggerDisplay( "Visible = {Visible}, Mode = {Mode}" )] - private struct ColumnVisibilityStatus - { - private ColumnVisibilityStatus( bool visible, PropagationMode mode, uint timestamp ) - { - m_visible = visible; - m_mode = mode; - m_timestamp = timestamp; - } - - internal ColumnVisibilityStatus SetMode( PropagationMode mode ) - { - return ColumnVisibilityStatus.Create( m_visible, mode, m_timestamp ); - } - - internal bool Visible - { - get - { - return m_visible; - } - } - - internal PropagationMode Mode - { - get - { - return m_mode; - } - } - - internal uint Timestamp - { - get - { - return m_timestamp; - } - } - - internal static ColumnVisibilityStatus Create( bool visible ) - { - return ColumnVisibilityStatus.Create( visible, PropagationMode.None, 0u ); - } - - internal static ColumnVisibilityStatus Create( bool visible, PropagationMode mode, uint timestamp ) - { - return new ColumnVisibilityStatus( visible, mode, timestamp ); - } - - private readonly bool m_visible; - private readonly PropagationMode m_mode; - private readonly uint m_timestamp; - } - - #endregion - - #region ColumnPositionStatus Private Struct - - private struct ColumnPositionStatus - { - internal static readonly ColumnPositionStatus Default = new ColumnPositionStatus(); - - private ColumnPositionStatus( uint parent, uint children, uint visiblePosition, uint location, uint draggableStatus, uint mainColumn ) - { - m_parentTimestamp = parent; - m_childrenTimestamp = children; - m_visiblePositionTimestamp = visiblePosition; - m_locationTimestamp = location; - m_draggableStatusTimestamp = draggableStatus; - m_mainColumnTimestamp = mainColumn; - } - - internal uint ParentTimestamp - { - get - { - return m_parentTimestamp; - } - } - - internal uint ChildrenTimestamp - { - get - { - return m_childrenTimestamp; - } - } - - internal uint VisiblePositionTimestamp - { - get - { - return m_visiblePositionTimestamp; - } - } - - internal uint LocationTimestamp - { - get - { - return m_locationTimestamp; - } - } - - internal uint DraggableStatusTimestamp - { - get - { - return m_draggableStatusTimestamp; - } - } - - internal uint MainColumnTimestamp - { - get - { - return m_mainColumnTimestamp; - } - } - - internal ColumnPositionStatus SetParentTimestamp( uint timestamp ) - { - return new ColumnPositionStatus( timestamp, m_childrenTimestamp, m_visiblePositionTimestamp, m_locationTimestamp, m_draggableStatusTimestamp, m_mainColumnTimestamp ); - } - - internal ColumnPositionStatus SetChildrenTimestamp( uint timestamp ) - { - return new ColumnPositionStatus( m_parentTimestamp, timestamp, m_visiblePositionTimestamp, m_locationTimestamp, m_draggableStatusTimestamp, m_mainColumnTimestamp ); - } - - internal ColumnPositionStatus SetVisiblePositionTimestamp( uint timestamp ) - { - return new ColumnPositionStatus( m_parentTimestamp, m_childrenTimestamp, timestamp, m_locationTimestamp, m_draggableStatusTimestamp, m_mainColumnTimestamp ); - } - - internal ColumnPositionStatus SetLocationTimestamp( uint timestamp ) - { - return new ColumnPositionStatus( m_parentTimestamp, m_childrenTimestamp, m_visiblePositionTimestamp, timestamp, m_draggableStatusTimestamp, m_mainColumnTimestamp ); - } - - internal ColumnPositionStatus SetDraggableStatusTimestamp( uint timestamp ) - { - return new ColumnPositionStatus( m_parentTimestamp, m_childrenTimestamp, m_visiblePositionTimestamp, m_locationTimestamp, timestamp, m_mainColumnTimestamp ); - } - - internal ColumnPositionStatus SetMainColumnTimestamp( uint timestamp ) - { - return new ColumnPositionStatus( m_parentTimestamp, m_childrenTimestamp, m_visiblePositionTimestamp, m_locationTimestamp, m_draggableStatusTimestamp, timestamp ); - } - - private readonly uint m_parentTimestamp; - private readonly uint m_childrenTimestamp; - private readonly uint m_visiblePositionTimestamp; - private readonly uint m_locationTimestamp; - private readonly uint m_draggableStatusTimestamp; - private readonly uint m_mainColumnTimestamp; - } - - #endregion - - #region ParentChildRelationshipSnapshot Private Struct - - private struct ParentChildRelationshipSnapshot - { - internal ParentChildRelationshipSnapshot( ColumnHierarchyModel.IColumnLocation location, uint timestamp ) - { - m_location = location; - m_timestamp = timestamp; - } - - internal ColumnHierarchyModel.IColumnLocation Location - { - get - { - return m_location; - } - } - - internal uint Timestamp - { - get - { - return m_timestamp; - } - } - - private readonly ColumnHierarchyModel.IColumnLocation m_location; - private readonly uint m_timestamp; - } - - #endregion - - #region ParentChildRelationshipSnapshotComparer Private Class - - private sealed class ParentChildRelationshipSnapshotComparer : IComparer - { - public int Compare( ParentChildRelationshipSnapshot x, ParentChildRelationshipSnapshot y ) - { - var compare = x.Timestamp.CompareTo( y.Timestamp ); - if( compare != 0 ) - return -compare; - - return -string.CompareOrdinal( x.Location.Column.FieldName, y.Location.Column.FieldName ); - } - } - - #endregion - - #region PropagationMode Private Enum - - private enum PropagationMode : byte - { - None = 0, - BottomUp, - TopDown, - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnHierarchyManagerHelper.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnHierarchyManagerHelper.cs deleted file mode 100644 index 4d538c14..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnHierarchyManagerHelper.cs +++ /dev/null @@ -1,167 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Diagnostics; -using System.Linq; - -namespace Xceed.Wpf.DataGrid -{ - internal static class ColumnHierarchyManagerHelper - { - internal static IDisposable DeferColumnsUpdate( DataGridContext dataGridContext ) - { - Debug.Assert( dataGridContext != null ); - - return dataGridContext.ColumnManager.DeferUpdate(); - } - - internal static IDisposable DeferColumnsUpdate( DetailConfiguration detailConfiguration ) - { - Debug.Assert( detailConfiguration != null ); - - return detailConfiguration.ColumnManager.DeferUpdate(); - } - - internal static bool MoveColumnBefore( DataGridContext dataGridContext, ColumnBase current, ColumnBase next ) - { - Debug.Assert( dataGridContext != null ); - - return ColumnHierarchyManagerHelper.MoveColumnBefore( dataGridContext.ColumnManager, current, next ); - } - - internal static bool MoveColumnBefore( DetailConfiguration detailConfiguration, ColumnBase current, ColumnBase next ) - { - Debug.Assert( detailConfiguration != null ); - - return ColumnHierarchyManagerHelper.MoveColumnBefore( detailConfiguration.ColumnManager, current, next ); - } - - internal static bool MoveColumnAfter( DataGridContext dataGridContext, ColumnBase current, ColumnBase previous ) - { - Debug.Assert( dataGridContext != null ); - - return ColumnHierarchyManagerHelper.MoveColumnAfter( dataGridContext.ColumnManager, current, previous ); - } - - internal static bool MoveColumnAfter( DetailConfiguration detailConfiguration, ColumnBase current, ColumnBase previous ) - { - Debug.Assert( detailConfiguration != null ); - - return ColumnHierarchyManagerHelper.MoveColumnAfter( detailConfiguration.ColumnManager, current, previous ); - } - - internal static bool MoveColumnUnder( DataGridContext dataGridContext, ColumnBase current, ColumnBase parent ) - { - Debug.Assert( dataGridContext != null ); - - return ColumnHierarchyManagerHelper.MoveColumnUnder( dataGridContext.ColumnManager, dataGridContext.Columns, current, parent ); - } - - internal static bool MoveColumnUnder( DetailConfiguration detailConfiguration, ColumnBase current, ColumnBase parent ) - { - Debug.Assert( detailConfiguration != null ); - - return ColumnHierarchyManagerHelper.MoveColumnUnder( detailConfiguration.ColumnManager, detailConfiguration.Columns, current, parent ); - } - - private static bool MoveColumnBefore( ColumnHierarchyManager columnsLayout, ColumnBase current, ColumnBase next ) - { - Debug.Assert( columnsLayout != null ); - - var currentLocation = columnsLayout.GetColumnLocationFor( current ); - if( currentLocation == null ) - return false; - - var pivotLocation = columnsLayout.GetColumnLocationFor( next ); - if( pivotLocation == null ) - return false; - - if( !currentLocation.CanMoveBefore( pivotLocation ) ) - return false; - - currentLocation.MoveBefore( pivotLocation ); - return true; - } - - private static bool MoveColumnAfter( ColumnHierarchyManager columnsLayout, ColumnBase current, ColumnBase previous ) - { - Debug.Assert( columnsLayout != null ); - - var currentLocation = columnsLayout.GetColumnLocationFor( current ); - if( currentLocation == null ) - return false; - - var pivotLocation = columnsLayout.GetColumnLocationFor( previous ); - if( pivotLocation == null ) - return false; - - if( !currentLocation.CanMoveAfter( pivotLocation ) ) - return false; - - currentLocation.MoveAfter( pivotLocation ); - return true; - } - - private static bool MoveColumnUnder( ColumnHierarchyManager columnsLayout, ColumnCollection columns, ColumnBase current, ColumnBase parent ) - { - Debug.Assert( columnsLayout != null ); - - var currentLocation = columnsLayout.GetColumnLocationFor( current ); - if( currentLocation == null ) - return false; - - var pivotLocation = default( ColumnHierarchyManager.ILocation ); - - // Move the column under the orphan section. - if( parent == null ) - { - var columnCollection = current.ContainingCollection; - if( columnCollection == null ) - return false; - - var mergedColumnCollection = default( ColumnCollection ); - - if( columnCollection == columns ) - { - mergedColumnCollection = null; - } - - if( mergedColumnCollection == null ) - return false; - - var levelMarkers = columnsLayout.GetLevelMarkersFor( mergedColumnCollection ); - if( levelMarkers == null ) - return false; - - pivotLocation = levelMarkers.Orphan; - } - else - { - pivotLocation = columnsLayout.GetColumnLocationFor( parent ); - } - - if( pivotLocation == null ) - return false; - - if( !currentLocation.CanMoveUnder( pivotLocation ) ) - return false; - - currentLocation.MoveUnder( pivotLocation ); - return true; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnHierarchyModel.Generic.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnHierarchyModel.Generic.cs deleted file mode 100644 index 2179ed22..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnHierarchyModel.Generic.cs +++ /dev/null @@ -1,3122 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Diagnostics; -using System.Linq; -using Xceed.Utils.Collections; - -namespace Xceed.Wpf.DataGrid -{ - internal class ColumnHierarchyModel where TColumn : class - { - #region Static Fields - - private const int None = -1; - - #endregion - - #region LevelCount Property - - internal int LevelCount - { - get - { - return m_level; - } - } - - #endregion - - #region [] Property - - internal IColumnLocation this[ TColumn column ] - { - get - { - if( object.ReferenceEquals( column, null ) ) - throw new ArgumentNullException( "column" ); - - if( m_capacity <= 0 ) - return null; - - var hashCode = column.GetHashCode(); - var index = this.FindColumn( column, hashCode ); - if( index == ColumnHierarchyModel.None ) - return null; - - var entry = m_columns[ index ]; - return new ColumnLocation( this, entry.Column, entry.HashCode, index ); - } - } - - #endregion - - #region LayoutChanging Event - - internal event EventHandler LayoutChanging; - - private void OnLayoutChanging( LayoutChangingEventArgs e ) - { - var handler = this.LayoutChanging; - if( handler == null ) - return; - - try - { - m_preventLayoutChanged = true; - handler.Invoke( this, e ); - } - finally - { - m_preventLayoutChanged = false; - } - } - - #endregion - - #region LayoutChanged Event - - internal event EventHandler LayoutChanged; - - private void OnLayoutChanged( LayoutChangedEventArgs e ) - { - var handler = this.LayoutChanged; - if( handler == null ) - return; - - try - { - m_preventLayoutChanged = true; - handler.Invoke( this, e ); - } - finally - { - m_preventLayoutChanged = false; - } - } - - #endregion - - #region StatusChanged Event - - internal event EventHandler StatusChanged; - - private void OnStatusChanged( StatusChangedEventArgs e ) - { - var handler = this.StatusChanged; - if( handler == null ) - return; - - try - { - m_preventLayoutChanged = true; - handler.Invoke( this, e ); - } - finally - { - m_preventLayoutChanged = false; - } - } - - #endregion - - internal IMarkers AddLevel( int level ) - { - if( level < 0 ) - throw new ArgumentException( "The level must be greater than or equal to zero.", "level" ); - - if( level > m_level ) - throw new ArgumentException( "Only one level can be inserted at a time.", "level" ); - - if( m_preventLayoutChanged ) - throw new InvalidOperationException( "The layout cannot be updated." ); - - // Resize the array to make space for a new level. - if( ( m_marks == null ) || ( m_marks.Length < m_level + 1 ) ) - { - var currentSize = ( m_marks != null ) ? m_marks.Length : 0; - var desizedSize = ( int )Math.Min( Math.Max( m_level + 1, currentSize * 2L ), int.MaxValue ); - - Array.Resize( ref m_marks, desizedSize ); - Debug.Assert( m_marks != null ); - - for( int i = currentSize; i < m_marks.Length; i++ ) - { - m_marks[ i ] = MarkEntry.Default; - } - - // This should only happen when the array is of size int.MaxValue. Technically, this should never happen. - if( !object.Equals( m_marks.Last(), MarkEntry.Default ) ) - throw new InvalidOperationException( "No more levels could be created." ); - } - - return this.AddLevelCore( level ); - } - - internal void RemoveLevel( int level ) - { - if( level < 0 ) - throw new ArgumentException( "The level must be greater than or equal to zero.", "level" ); - - if( level >= m_level ) - throw new ArgumentException( "The level does not exist.", "level" ); - - if( m_preventLayoutChanged ) - throw new InvalidOperationException( "The layout cannot be updated." ); - - this.RemoveLevelCore( level ); - } - - internal IColumnLocation Add( TColumn column, int level ) - { - return this.Add( column, default( TStatus ), level ); - } - - internal IColumnLocation Add( TColumn column, TStatus status, int level ) - { - if( object.ReferenceEquals( column, null ) ) - throw new ArgumentNullException( "column" ); - - if( level < 0 ) - throw new ArgumentException( "The level must be greater than or equal to zero.", "level" ); - - if( level >= m_level ) - throw new ArgumentException( "The level is not available.", "level" ); - - if( m_preventLayoutChanged ) - throw new InvalidOperationException( "The layout cannot be updated." ); - - var hashCode = column.GetHashCode(); - - if( m_size > 0 ) - { - if( this.FindColumn( column, hashCode ) != ColumnHierarchyModel.None ) - throw new ArgumentException( "The column is already in the collection.", "column" ); - } - - var orphan = this.FindMark( level ).Orphan; - Debug.Assert( orphan != ColumnHierarchyModel.None ); - - var index = this.AddCore( column, status, hashCode ); - var location = new ColumnLocation( this, column, hashCode, index ); - - this.OnLayoutChanged( new LayoutChangedEventArgs( location, LayoutChangedAction.Added ) ); - - if( !object.Equals( status, default( TStatus ) ) ) - { - this.OnStatusChanged( new StatusChangedEventArgs( location, default( TStatus ), status ) ); - } - - this.ConnectBefore( index, orphan ); - - return location; - } - - internal bool Remove( TColumn column ) - { - if( object.ReferenceEquals( column, null ) ) - throw new ArgumentNullException( "column" ); - - if( m_preventLayoutChanged ) - throw new InvalidOperationException( "The layout cannot be updated." ); - - if( m_size <= 0 ) - return false; - - var index = this.FindColumn( column ); - if( index == ColumnHierarchyModel.None ) - return false; - - var level = this.GetLevel( index ); - var relations = m_relations[ index ]; - - // Move all children under the level's orphan entry. - if( relations.FirstChild != ColumnHierarchyModel.None ) - { - var orphan = this.FindMark( level ).Orphan; - Debug.Assert( orphan != ColumnHierarchyModel.None ); - - var current = relations.FirstChild; - var next = this.GetNextSibling( current ); - - Debug.Assert( this.IsColumn( current ) ); - this.Disconnect( current ); - this.ConnectUnder( current, orphan ); - - var previous = current; - current = next; - - while( current != ColumnHierarchyModel.None ) - { - next = this.GetNextSibling( current ); - - Debug.Assert( this.IsColumn( current ) ); - this.Disconnect( current ); - this.ConnectAfter( current, previous ); - - previous = current; - current = next; - } - } - - Debug.Assert( this.GetFirstChild( index ) == ColumnHierarchyModel.None ); - - this.OnLayoutChanging( new LayoutChangingEventArgs( this.GetTargetLocation( index ), LayoutChangingAction.Removing ) ); - this.Disconnect( index ); - this.RemoveCore( index ); - - return true; - } - - internal bool Contains( TColumn column ) - { - if( ( m_size <= 0 ) || object.ReferenceEquals( column, null ) ) - return false; - - return ( this.FindColumn( column ) != ColumnHierarchyModel.None ); - } - - internal void Clear() - { - if( m_preventLayoutChanged ) - throw new InvalidOperationException( "The layout cannot be updated." ); - - if( m_size <= 0 ) - return; - - this.OnLayoutChanging( new LayoutChangingEventArgs( null, LayoutChangingAction.Clearing ) ); - - Debug.Assert( m_buckets != null ); - Debug.Assert( m_columns != null ); - Debug.Assert( m_status != null ); - Debug.Assert( m_relations != null ); - Debug.Assert( m_marks != null ); - - for( int i = 0; i < m_level; i++ ) - { - m_marks[ i ] = MarkEntry.Default; - } - - for( int i = 0; i < m_capacity; i++ ) - { - m_buckets[ i ] = ColumnHierarchyModel.None; - m_columns[ i ] = new ColumnEntry( ( i < m_capacity - 1 ) ? i + 1 : ColumnHierarchyModel.None ); - m_status[ i ] = default( TStatus ); - m_relations[ i ] = RelationEntry.Default; - } - - m_level = 0; - m_free = 0; - m_size = 0; - - this.OnLayoutChanged( new LayoutChangedEventArgs( null, LayoutChangedAction.Cleared ) ); - } - - internal IMarkers GetLevelMarkers( int level ) - { - if( level < 0 ) - throw new ArgumentException( "The level must be greater than or equal to zero.", "level" ); - - if( level >= m_level ) - throw new ArgumentException( "The level must be less than LevelCount.", "level" ); - - var entry = this.FindMark( level ); - - return new Markers( this, level, entry ); - } - - private Markers AddLevelCore( int level ) - { - Debug.Assert( ( level >= 0 ) && ( level <= m_level ) ); - Debug.Assert( m_marks != null ); - Debug.Assert( level < m_marks.Length ); - Debug.Assert( object.Equals( m_marks.Last(), MarkEntry.Default ) ); - - // Offset the marks to insert a entry that will deal with the new level. - for( int i = m_marks.Length - 1; i > level; i-- ) - { - m_marks[ i ] = m_marks[ i - 1 ]; - } - - var start = this.AddCore( default( TStatus ) ); - var end = this.AddCore( default( TStatus ) ); - var splitter = this.AddCore( default( TStatus ) ); - var orphan = this.AddCore( default( TStatus ) ); - var markEntry = new MarkEntry( start, end, splitter, orphan ); - var markers = new Markers( this, level, markEntry ); - - m_marks[ level ] = markEntry; - m_level++; - - this.OnLayoutChanged( new LayoutChangedEventArgs( markers.Start, LayoutChangedAction.Added ) ); - this.OnLayoutChanged( new LayoutChangedEventArgs( markers.End, LayoutChangedAction.Added ) ); - this.OnLayoutChanged( new LayoutChangedEventArgs( markers.Splitter, LayoutChangedAction.Added ) ); - this.OnLayoutChanged( new LayoutChangedEventArgs( markers.Orphan, LayoutChangedAction.Added ) ); - - var parentStart = ColumnHierarchyModel.None; - var parentEnd = ColumnHierarchyModel.None; - var parentSplitter = ColumnHierarchyModel.None; - var parentOrphan = ColumnHierarchyModel.None; - var childStart = ColumnHierarchyModel.None; - var childEnd = ColumnHierarchyModel.None; - var childSplitter = ColumnHierarchyModel.None; - var childOrphan = ColumnHierarchyModel.None; - - if( level + 1 < m_marks.Length ) - { - var entry = m_marks[ level + 1 ]; - - parentStart = entry.Start; - parentEnd = entry.End; - parentSplitter = entry.Splitter; - parentOrphan = entry.Orphan; - } - - if( level > 0 ) - { - var entry = m_marks[ level - 1 ]; - - childStart = entry.Start; - childEnd = entry.End; - childSplitter = entry.Splitter; - childOrphan = entry.Orphan; - } - - // Move the entries on the child level under the new level entries. - if( childStart != ColumnHierarchyModel.None ) - { - Debug.Assert( childStart != ColumnHierarchyModel.None ); - Debug.Assert( childEnd != ColumnHierarchyModel.None ); - Debug.Assert( childSplitter != ColumnHierarchyModel.None ); - Debug.Assert( childOrphan != ColumnHierarchyModel.None ); - Debug.Assert( childOrphan == this.GetPreviousSiblingOrCousin( childEnd ) ); - Debug.Assert( this.GetNextSiblingOrCousin( childEnd ) == ColumnHierarchyModel.None ); - - var next = childOrphan; - var current = this.GetPreviousSiblingOrCousin( next ); - - // Move the child orphan entry under the new level's orphan entry. - this.Disconnect( childOrphan ); - this.ConnectUnder( childOrphan, orphan ); - - // Move the columns under the new level's orphan entry. - while( current != ColumnHierarchyModel.None ) - { - var previous = this.GetPreviousSiblingOrCousin( current ); - - if( this.IsColumn( current ) ) - { - this.Disconnect( current ); - this.ConnectBefore( current, next ); - - next = current; - } - - current = previous; - } - - // Move the remaining marker entries under the new level's related marker entries. - this.Disconnect( childStart ); - this.Disconnect( childEnd ); - this.Disconnect( childSplitter ); - - this.ConnectUnder( childStart, start ); - this.ConnectUnder( childEnd, end ); - this.ConnectUnder( childSplitter, splitter ); - - Debug.Assert( this.GetFirstChild( start ) != ColumnHierarchyModel.None ); - Debug.Assert( this.GetFirstChild( end ) != ColumnHierarchyModel.None ); - Debug.Assert( this.GetFirstChild( splitter ) != ColumnHierarchyModel.None ); - Debug.Assert( this.GetFirstChild( orphan ) != ColumnHierarchyModel.None ); - } - - // Move the new level's marker entries under the parent level's related marker entries. - if( parentStart != ColumnHierarchyModel.None ) - { - Debug.Assert( parentStart != ColumnHierarchyModel.None ); - Debug.Assert( parentEnd != ColumnHierarchyModel.None ); - Debug.Assert( parentSplitter != ColumnHierarchyModel.None ); - Debug.Assert( parentOrphan != ColumnHierarchyModel.None ); - Debug.Assert( parentOrphan == this.GetPreviousSiblingOrCousin( parentEnd ) ); - Debug.Assert( this.GetNextSiblingOrCousin( parentEnd ) == ColumnHierarchyModel.None ); - - Debug.Assert( this.GetFirstChild( parentStart ) == ColumnHierarchyModel.None ); - Debug.Assert( this.GetFirstChild( parentEnd ) == ColumnHierarchyModel.None ); - Debug.Assert( this.GetFirstChild( parentSplitter ) == ColumnHierarchyModel.None ); - Debug.Assert( this.GetFirstChild( parentOrphan ) == ColumnHierarchyModel.None ); - - this.ConnectUnder( start, parentStart ); - this.ConnectUnder( end, parentEnd ); - this.ConnectUnder( splitter, parentSplitter ); - this.ConnectUnder( orphan, parentOrphan ); - } - // Order the new level's marker entries. - else - { - this.ConnectAfter( splitter, start ); - this.ConnectAfter( orphan, splitter ); - this.ConnectAfter( end, orphan ); - } - - return markers; - } - - private void RemoveLevelCore( int level ) - { - var markers = this.FindMark( level ); - var start = markers.Start; - var end = markers.End; - var splitter = markers.Splitter; - var orphan = markers.Orphan; - Debug.Assert( start != ColumnHierarchyModel.None ); - Debug.Assert( end != ColumnHierarchyModel.None ); - Debug.Assert( splitter != ColumnHierarchyModel.None ); - Debug.Assert( orphan != ColumnHierarchyModel.None ); - - var parentStart = ColumnHierarchyModel.None; - var parentEnd = ColumnHierarchyModel.None; - var parentSplitter = ColumnHierarchyModel.None; - var parentOrphan = ColumnHierarchyModel.None; - var childStart = ColumnHierarchyModel.None; - var childEnd = ColumnHierarchyModel.None; - var childSplitter = ColumnHierarchyModel.None; - var childOrphan = ColumnHierarchyModel.None; - - if( level + 1 < m_marks.Length ) - { - var entry = m_marks[ level + 1 ]; - - parentStart = entry.Start; - parentEnd = entry.End; - parentSplitter = entry.Splitter; - parentOrphan = entry.Orphan; - } - - if( level > 0 ) - { - var entry = m_marks[ level - 1 ]; - - childStart = entry.Start; - childEnd = entry.End; - childSplitter = entry.Splitter; - childOrphan = entry.Orphan; - } - - if( childStart != ColumnHierarchyModel.None ) - { - Debug.Assert( childStart != ColumnHierarchyModel.None ); - Debug.Assert( childEnd != ColumnHierarchyModel.None ); - Debug.Assert( childSplitter != ColumnHierarchyModel.None ); - Debug.Assert( childOrphan != ColumnHierarchyModel.None ); - Debug.Assert( childOrphan == this.GetPreviousSiblingOrCousin( childEnd ) ); - Debug.Assert( this.GetNextSiblingOrCousin( childEnd ) == ColumnHierarchyModel.None ); - - // Link all entries on the child level together. They will be rearrange later if necessary. - var next = ColumnHierarchyModel.None; - var current = childEnd; - - while( current != ColumnHierarchyModel.None ) - { - var previous = this.GetPreviousSiblingOrCousin( current ); - - this.Disconnect( current ); - - if( next != ColumnHierarchyModel.None ) - { - this.ConnectBefore( current, next ); - } - else - { - this.SetRelations( current, new RelationEntry( ColumnHierarchyModel.None, this.GetFirstChild( current ), ColumnHierarchyModel.None, ColumnHierarchyModel.None ) ); - } - - next = current; - current = previous; - } - } - - // Remove any relation to entries of the removed level. - { - var current = end; - while( current != ColumnHierarchyModel.None ) - { - var previous = this.GetPreviousSiblingOrCousin( current ); - - this.OnLayoutChanging( new LayoutChangingEventArgs( this.GetTargetLocation( current ), LayoutChangingAction.Removing ) ); - this.Disconnect( current ); - this.RemoveCore( current ); - - current = previous; - } - } - - // Offset the marks to remove the level that was removed. - for( int i = level; i < m_level - 1; i++ ) - { - m_marks[ i ] = m_marks[ i + 1 ]; - } - - m_level--; - m_marks[ m_level ] = MarkEntry.Default; - - // Reconnect the entries on the child level under the parent level's related entries. - if( ( childStart != ColumnHierarchyModel.None ) && ( parentStart != ColumnHierarchyModel.None ) ) - { - Debug.Assert( parentStart != ColumnHierarchyModel.None ); - Debug.Assert( parentEnd != ColumnHierarchyModel.None ); - Debug.Assert( parentSplitter != ColumnHierarchyModel.None ); - Debug.Assert( parentOrphan != ColumnHierarchyModel.None ); - Debug.Assert( parentOrphan == this.GetPreviousSibling( parentEnd ) ); - Debug.Assert( this.GetFirstChild( parentStart ) == ColumnHierarchyModel.None ); - Debug.Assert( this.GetFirstChild( parentEnd ) == ColumnHierarchyModel.None ); - Debug.Assert( this.GetFirstChild( parentSplitter ) == ColumnHierarchyModel.None ); - Debug.Assert( this.GetFirstChild( parentOrphan ) == ColumnHierarchyModel.None ); - Debug.Assert( this.GetNextSiblingOrCousin( parentEnd ) == ColumnHierarchyModel.None ); - - var next = childOrphan; - var current = this.GetPreviousSibling( next ); - - // Move the child orphan entry under the parent level's orphan entry. - this.Disconnect( childOrphan ); - this.ConnectUnder( childOrphan, parentOrphan ); - - // Move the columns under the parent level's orphan entry. - while( current != ColumnHierarchyModel.None ) - { - var previous = this.GetPreviousSibling( current ); - - if( this.IsColumn( current ) ) - { - this.Disconnect( current ); - this.ConnectBefore( current, next ); - - next = current; - } - - current = previous; - } - - // Move the remaining marker entries under the parent level's related marker entries. - this.Disconnect( childStart ); - this.Disconnect( childEnd ); - this.Disconnect( childSplitter ); - - this.ConnectUnder( childStart, parentStart ); - this.ConnectUnder( childEnd, parentEnd ); - this.ConnectUnder( childSplitter, parentSplitter ); - - Debug.Assert( this.GetFirstChild( parentStart ) == childStart ); - Debug.Assert( this.GetFirstChild( parentEnd ) == childEnd ); - Debug.Assert( this.GetFirstChild( parentSplitter ) == childSplitter ); - Debug.Assert( this.GetFirstChild( parentOrphan ) != ColumnHierarchyModel.None ); - } - } - - private int AddCore( TStatus status ) - { - this.EnsureCapacity(); - - Debug.Assert( m_columns != null ); - Debug.Assert( m_status != null ); - Debug.Assert( m_relations != null ); - - var free = m_free; - - m_free = m_columns[ m_free ].Next; - m_columns[ free ] = new ColumnEntry( ColumnHierarchyModel.None ); - m_status[ free ] = status; - m_relations[ free ] = RelationEntry.Default; - - m_size++; - - return free; - } - - private int AddCore( TColumn column, TStatus status, int hashCode ) - { - var index = this.AddCore( status ); - - Debug.Assert( ( index >= 0 ) && ( index < m_capacity ) ); - Debug.Assert( m_buckets != null ); - Debug.Assert( m_columns != null ); - Debug.Assert( m_status != null ); - - var bucket = this.GetBucket( hashCode ); - Debug.Assert( ( bucket >= 0 ) && ( bucket < m_buckets.Length ) ); - - var collision = m_buckets[ bucket ]; - - m_buckets[ bucket ] = index; - m_columns[ index ] = new ColumnEntry( column, hashCode, collision ); - - return index; - } - - private void RemoveCore( int index ) - { - Debug.Assert( m_buckets != null ); - Debug.Assert( m_columns != null ); - Debug.Assert( m_status != null ); - Debug.Assert( m_relations != null ); - Debug.Assert( ( index >= 0 ) && ( index < m_capacity ) ); - - m_status[ index ] = default( TStatus ); - m_relations[ index ] = RelationEntry.Default; - - var entry = m_columns[ index ]; - - // Only column entry needs to adjust the buckets. - if( this.IsColumn( entry ) ) - { - var bucket = this.GetBucket( entry.HashCode ); - Debug.Assert( ( bucket >= 0 ) && ( bucket < m_buckets.Length ) ); - Debug.Assert( m_buckets[ bucket ] != ColumnHierarchyModel.None ); - - if( m_buckets[ bucket ] == index ) - { - m_buckets[ bucket ] = entry.Next; - } - else - { - // Repair the linked list. - var previous = m_buckets[ bucket ]; - var next = m_columns[ previous ].Next; - - while( next != index ) - { - Debug.Assert( next != ColumnHierarchyModel.None ); - previous = next; - next = m_columns[ next ].Next; - } - - Debug.Assert( next == index ); - - m_columns[ previous ] = m_columns[ previous ].SetNext( entry.Next ); - } - } - - m_columns[ index ] = new ColumnEntry( m_free ); - m_free = index; - - m_size--; - } - - private void Disconnect( int index ) - { - var relations = m_relations[ index ]; - - if( relations.Previous != ColumnHierarchyModel.None ) - { - this.SetRelations( relations.Previous, m_relations[ relations.Previous ].SetNext( relations.Next ) ); - } - else if( relations.Parent != ColumnHierarchyModel.None ) - { - Debug.Assert( m_relations[ relations.Parent ].FirstChild == index ); - - this.SetRelations( relations.Parent, m_relations[ relations.Parent ].SetFirstChild( relations.Next ) ); - } - - if( relations.Next != ColumnHierarchyModel.None ) - { - this.SetRelations( relations.Next, m_relations[ relations.Next ].SetPrevious( relations.Previous ) ); - } - } - - private void ConnectBefore( int index, int pivot ) - { - var sourceRelations = m_relations[ index ]; - var pivotRelations = m_relations[ pivot ]; - - if( pivotRelations.Previous != ColumnHierarchyModel.None ) - { - Debug.Assert( pivotRelations.Previous != index ); - - this.SetRelations( pivotRelations.Previous, m_relations[ pivotRelations.Previous ].SetNext( index ) ); - } - else if( pivotRelations.Parent != ColumnHierarchyModel.None ) - { - Debug.Assert( m_relations[ pivotRelations.Parent ].FirstChild == pivot ); - - this.SetRelations( pivotRelations.Parent, m_relations[ pivotRelations.Parent ].SetFirstChild( index ) ); - } - - this.SetRelations( index, new RelationEntry( pivotRelations.Parent, sourceRelations.FirstChild, pivotRelations.Previous, pivot ) ); - this.SetRelations( pivot, pivotRelations.SetPrevious( index ) ); - } - - private void ConnectAfter( int index, int pivot ) - { - var sourceRelations = m_relations[ index ]; - var pivotRelations = m_relations[ pivot ]; - - if( pivotRelations.Next != ColumnHierarchyModel.None ) - { - Debug.Assert( pivotRelations.Next != index ); - - this.SetRelations( pivotRelations.Next, m_relations[ pivotRelations.Next ].SetPrevious( index ) ); - } - - this.SetRelations( index, new RelationEntry( pivotRelations.Parent, sourceRelations.FirstChild, pivot, pivotRelations.Next ) ); - this.SetRelations( pivot, pivotRelations.SetNext( index ) ); - } - - private void ConnectUnder( int index, int pivot ) - { - var sourceRelations = m_relations[ index ]; - var pivotRelations = m_relations[ pivot ]; - - if( pivotRelations.FirstChild != ColumnHierarchyModel.None ) - { - Debug.Assert( pivotRelations.FirstChild != index ); - Debug.Assert( m_relations[ pivotRelations.FirstChild ].Previous == ColumnHierarchyModel.None ); - - this.SetRelations( pivotRelations.FirstChild, m_relations[ pivotRelations.FirstChild ].SetPrevious( index ) ); - } - - this.SetRelations( index, new RelationEntry( pivot, sourceRelations.FirstChild, ColumnHierarchyModel.None, pivotRelations.FirstChild ) ); - this.SetRelations( pivot, pivotRelations.SetFirstChild( index ) ); - } - - private void MoveBefore( int source, int pivot ) - { - if( m_preventLayoutChanged ) - throw new InvalidOperationException( "The layout cannot be updated." ); - - Debug.Assert( ( source >= 0 ) && ( source < m_capacity ) ); - Debug.Assert( ( pivot >= 0 ) && ( pivot < m_capacity ) ); - - // The entry is already at the proper location. - if( m_relations[ pivot ].Previous == source ) - return; - - if( source == pivot ) - throw new ArgumentException( "Cannot move the entry before itself.", "source" ); - - Debug.Assert( this.GetAncestorCount( source ) == this.GetAncestorCount( pivot ), "Cannot move entries on different level." ); - Debug.Assert( !this.IsStart( pivot ), "No entry can be moved before the start." ); - Debug.Assert( !this.IsStart( source ) && !this.IsEnd( source ) && !this.IsOrphan( source ), "The entry cannot be moved." ); - Debug.Assert( !this.IsSplitter( source ) || ( this.GetLevel( source ) == m_level - 1 ), "Only the topmost splitter can be moved." ); - Debug.Assert( !this.IsSplitter( pivot ) || ( this.GetLevel( pivot ) == m_level - 1 ), "An entry cannot be moved before the splitter on this level." ); - - this.Disconnect( source ); - this.ConnectBefore( source, pivot ); - } - - private void MoveAfter( int source, int pivot ) - { - if( m_preventLayoutChanged ) - throw new InvalidOperationException( "The layout cannot be updated." ); - - Debug.Assert( ( source >= 0 ) && ( source < m_capacity ) ); - Debug.Assert( ( pivot >= 0 ) && ( pivot < m_capacity ) ); - - // The entry is already at the proper location. - if( m_relations[ pivot ].Next == source ) - return; - - if( source == pivot ) - throw new ArgumentException( "Cannot move the entry after itself.", "source" ); - - Debug.Assert( this.GetAncestorCount( source ) == this.GetAncestorCount( pivot ), "Cannot move entries on different level." ); - Debug.Assert( !this.IsEnd( pivot ), "No entry can be moved after the end." ); - Debug.Assert( !this.IsOrphan( pivot ), "No entry can be moved after an orphan entry." ); - Debug.Assert( !this.IsStart( source ) && !this.IsEnd( source ) && !this.IsOrphan( source ), "The entry cannot be moved." ); - Debug.Assert( !this.IsSplitter( source ) || ( this.GetLevel( source ) == m_level - 1 ), "Only the topmost splitter can be move." ); - Debug.Assert( !this.IsSplitter( pivot ) || ( this.GetLevel( pivot ) == m_level - 1 ), "An entry cannot be moved after the splitter on this level." ); - - this.Disconnect( source ); - this.ConnectAfter( source, pivot ); - } - - private void MoveUnder( int source, int pivot ) - { - if( m_preventLayoutChanged ) - throw new InvalidOperationException( "The layout cannot be updated." ); - - Debug.Assert( ( source >= 0 ) && ( source < m_capacity ) ); - Debug.Assert( ( pivot >= 0 ) && ( pivot < m_capacity ) ); - - // The entry is already at the proper location. - if( m_relations[ source ].Parent == pivot ) - return; - - if( source == pivot ) - throw new ArgumentException( "Cannot move the entry under itself.", "source" ); - - Debug.Assert( this.GetAncestorCount( source ) == ( this.GetAncestorCount( pivot ) + 1 ), "The entry must be a location on the previous level." ); - Debug.Assert( !this.IsStart( source ) && !this.IsEnd( source ) && !this.IsOrphan( source ), "The entry cannot be moved." ); - Debug.Assert( !this.IsSplitter( source ), "A splitter cannot be moved under another entry." ); - Debug.Assert( !this.IsSplitter( pivot ), "An entry cannot be moved under a splitter." ); - - this.Disconnect( source ); - this.ConnectUnder( source, pivot ); - } - - private void SetRelations( int index, RelationEntry relations ) - { - Debug.Assert( ( index >= 0 ) && ( index < m_capacity ) ); - - var current = m_relations[ index ]; - var location = this.GetTargetLocation( index ); - Debug.Assert( location != null ); - - if( current.Parent != relations.Parent ) - { - this.OnLayoutChanging( new LayoutChangingEventArgs( location, LayoutChangingAction.ChangingParent ) ); - } - - if( current.FirstChild != relations.FirstChild ) - { - this.OnLayoutChanging( new LayoutChangingEventArgs( location, LayoutChangingAction.ChangingFirstChild ) ); - } - - if( current.Previous != relations.Previous ) - { - this.OnLayoutChanging( new LayoutChangingEventArgs( location, LayoutChangingAction.ChangingPrevious ) ); - } - - if( current.Next != relations.Next ) - { - this.OnLayoutChanging( new LayoutChangingEventArgs( location, LayoutChangingAction.ChangingNext ) ); - } - - m_relations[ index ] = relations; - - if( current.Parent != relations.Parent ) - { - this.OnLayoutChanged( new LayoutChangedEventArgs( location, LayoutChangedAction.ParentChanged ) ); - } - - if( current.FirstChild != relations.FirstChild ) - { - this.OnLayoutChanged( new LayoutChangedEventArgs( location, LayoutChangedAction.FirstChildChanged ) ); - } - - if( current.Previous != relations.Previous ) - { - this.OnLayoutChanged( new LayoutChangedEventArgs( location, LayoutChangedAction.PreviousChanged ) ); - } - - if( current.Next != relations.Next ) - { - this.OnLayoutChanged( new LayoutChangedEventArgs( location, LayoutChangedAction.NextChanged ) ); - } - } - - private TStatus GetStatus( int index ) - { - Debug.Assert( ( index >= 0 ) && ( index < m_capacity ) ); - - return m_status[ index ]; - } - - private void SetStatus( int index, TStatus value ) - { - Debug.Assert( ( index >= 0 ) && ( index < m_capacity ) ); - - var oldValue = m_status[ index ]; - if( object.Equals( oldValue, value ) ) - return; - - var columnLocation = this.GetTargetLocation( index ) as IColumnLocation; - Debug.Assert( columnLocation != null ); - - m_status[ index ] = value; - - this.OnStatusChanged( new StatusChangedEventArgs( columnLocation, oldValue, value ) ); - } - - private bool IsStart( int index ) - { - if( ( index < 0 ) || ( index >= m_capacity ) || this.IsColumn( index ) ) - return false; - - for( int level = m_level - 1; level >= 0; level-- ) - { - if( index == this.FindMark( level ).Start ) - return true; - } - - return false; - } - - private bool IsEnd( int index ) - { - if( ( index < 0 ) || ( index >= m_capacity ) || this.IsColumn( index ) ) - return false; - - for( int level = m_level - 1; level >= 0; level-- ) - { - if( index == this.FindMark( level ).End ) - return true; - } - - return false; - } - - private bool IsSplitter( int index ) - { - if( ( index < 0 ) || ( index >= m_capacity ) || this.IsColumn( index ) ) - return false; - - for( int level = m_level - 1; level >= 0; level-- ) - { - if( index == this.FindMark( level ).Splitter ) - return true; - } - - return false; - } - - private bool IsOrphan( int index ) - { - if( ( index < 0 ) || ( index >= m_capacity ) || this.IsColumn( index ) ) - return false; - - for( int level = m_level - 1; level >= 0; level-- ) - { - if( index == this.FindMark( level ).Orphan ) - return true; - } - - return false; - } - - private bool IsColumn( int index ) - { - if( ( index < 0 ) || ( index >= m_capacity ) ) - return false; - - return this.IsColumn( m_columns[ index ] ); - } - - private bool IsColumn( ColumnEntry entry ) - { - return !object.ReferenceEquals( entry.Column, null ); - } - - private MarkEntry FindMark( int level ) - { - Debug.Assert( ( level >= 0 ) && ( level < m_level ) ); - Debug.Assert( m_marks != null ); - Debug.Assert( level < m_marks.Length ); - - return m_marks[ level ]; - } - - private int FindColumn( TColumn column ) - { - Debug.Assert( !object.ReferenceEquals( column, null ) ); - - return this.FindColumn( column, column.GetHashCode() ); - } - - private int FindColumn( TColumn column, int hashCode ) - { - Debug.Assert( !object.ReferenceEquals( column, null ) ); - Debug.Assert( m_buckets != null ); - Debug.Assert( m_columns != null ); - - var bucket = this.GetBucket( hashCode ); - Debug.Assert( ( bucket >= 0 ) && ( bucket < m_buckets.Length ) ); - - var index = m_buckets[ bucket ]; - - while( index != ColumnHierarchyModel.None ) - { - var entry = m_columns[ index ]; - if( ( entry.HashCode == hashCode ) && object.Equals( entry.Column, column ) ) - return index; - - index = entry.Next; - } - - return ColumnHierarchyModel.None; - } - - private StartLocation CreateStartLocation( int level, int index ) - { - Debug.Assert( this.IsStart( index ) ); - - return new StartLocation( this, level, index ); - } - - private EndLocation CreateEndLocation( int level, int index ) - { - Debug.Assert( this.IsEnd( index ) ); - - return new EndLocation( this, level, index ); - } - - private SplitterLocation CreateSplitterLocation( int level, int index ) - { - Debug.Assert( this.IsSplitter( index ) ); - - return new SplitterLocation( this, level, index ); - } - - private OrphanLocation CreateOrphanLocation( int level, int index ) - { - Debug.Assert( this.IsOrphan( index ) ); - - return new OrphanLocation( this, level, index ); - } - - private ColumnLocation CreateColumnLocation( int index ) - { - Debug.Assert( this.IsColumn( index ) ); - - var entry = m_columns[ index ]; - - return new ColumnLocation( this, entry.Column, entry.HashCode, index ); - } - - private int GetParent( int index ) - { - Debug.Assert( ( index >= 0 ) && ( index < m_capacity ) ); - Debug.Assert( m_relations != null ); - - return m_relations[ index ].Parent; - } - - private int GetFirstChild( int index ) - { - Debug.Assert( ( index >= 0 ) && ( index < m_capacity ) ); - Debug.Assert( m_relations != null ); - - return m_relations[ index ].FirstChild; - } - - private int GetPreviousSibling( int index ) - { - Debug.Assert( ( index >= 0 ) && ( index < m_capacity ) ); - Debug.Assert( m_relations != null ); - - return m_relations[ index ].Previous; - } - - private int GetNextSibling( int index ) - { - Debug.Assert( ( index >= 0 ) && ( index < m_capacity ) ); - Debug.Assert( m_relations != null ); - - return m_relations[ index ].Next; - } - - private int GetPreviousSiblingOrCousin( int index ) - { - Debug.Assert( ( index >= 0 ) && ( index < m_capacity ) ); - - var relations = m_relations[ index ]; - var target = relations.Previous; - - if( target != ColumnHierarchyModel.None ) - return target; - - var parent = relations.Parent; - if( parent != ColumnHierarchyModel.None ) - { - var oncle = parent; - - while( true ) - { - oncle = this.GetPreviousSiblingOrCousin( oncle ); - if( oncle == ColumnHierarchyModel.None ) - break; - - target = this.GetFirstChild( oncle ); - if( target != ColumnHierarchyModel.None ) - { - while( this.GetNextSibling( target ) != ColumnHierarchyModel.None ) - { - target = this.GetNextSibling( target ); - } - - return target; - } - } - } - - // No more sibling. - return ColumnHierarchyModel.None; - } - - private int GetNextSiblingOrCousin( int index ) - { - Debug.Assert( ( index >= 0 ) && ( index < m_capacity ) ); - - var relations = m_relations[ index ]; - var target = relations.Next; - - if( target != ColumnHierarchyModel.None ) - return target; - - var parent = relations.Parent; - if( parent != ColumnHierarchyModel.None ) - { - var oncle = parent; - - while( true ) - { - oncle = this.GetNextSiblingOrCousin( oncle ); - if( oncle == ColumnHierarchyModel.None ) - break; - - target = this.GetFirstChild( oncle ); - if( target != ColumnHierarchyModel.None ) - return target; - } - } - - // No more sibling. - return ColumnHierarchyModel.None; - } - - private ILocation GetTargetLocation( int index ) - { - if( index == ColumnHierarchyModel.None ) - return null; - - if( this.IsColumn( index ) ) - return this.CreateColumnLocation( index ); - - for( int level = m_level - 1; level >= 0; level-- ) - { - var entry = this.FindMark( level ); - if( entry.Start == index ) - return this.CreateStartLocation( level, index ); - - if( entry.End == index ) - return this.CreateEndLocation( level, index ); - - if( entry.Splitter == index ) - return this.CreateSplitterLocation( level, index ); - - if( entry.Orphan == index ) - return this.CreateOrphanLocation( level, index ); - } - - throw new InvalidOperationException(); - } - - private int GetLevel( int index ) - { - Debug.Assert( m_level > 0 ); - - var ancestors = this.GetAncestorCount( index ); - Debug.Assert( ancestors < m_level ); - - return m_level - ancestors - 1; - } - - private int GetAncestorCount( int index ) - { - Debug.Assert( ( index >= 0 ) && ( index < m_capacity ) ); - - var count = -1; - - while( index != ColumnHierarchyModel.None ) - { - index = this.GetParent( index ); - count++; - } - - Debug.Assert( count >= 0 ); - - return count; - } - - private int GetBucket( int hashCode ) - { - return ColumnHierarchyModel.GetBucket( hashCode, m_capacity ); - } - - private void EnsureMarks( int level, MarkEntry entry ) - { - if( ( m_marks == null ) || ( level < 0 ) || ( level >= m_marks.Length ) || !object.Equals( entry, m_marks[ level ] ) ) - throw new InvalidOperationException( "The markers are no longer valid." ); - } - - private int EnsureStart( int level, int index ) - { - if( ( m_marks == null ) || ( level < 0 ) || ( level >= m_marks.Length ) || ( index != m_marks[ level ].Start ) ) - throw new InvalidOperationException( "The location is no longer valid." ); - - return level; - } - - private int EnsureEnd( int level, int index ) - { - if( ( m_marks == null ) || ( level < 0 ) || ( level >= m_marks.Length ) || ( index != m_marks[ level ].End ) ) - throw new InvalidOperationException( "The location is no longer valid." ); - - return level; - } - - private int EnsureSplitter( int level, int index ) - { - if( ( m_marks == null ) || ( level < 0 ) || ( level >= m_marks.Length ) || ( index != m_marks[ level ].Splitter ) ) - throw new InvalidOperationException( "The location is no longer valid." ); - - return level; - } - - private int EnsureOrphan( int level, int index ) - { - if( ( m_marks == null ) || ( level < 0 ) || ( level >= m_marks.Length ) || ( index != m_marks[ level ].Orphan ) ) - throw new InvalidOperationException( "The location is no longer valid." ); - - return level; - } - - private int EnsureColumn( TColumn column, int hashCode, int index ) - { - if( ( index < 0 ) || ( index >= m_capacity ) ) - throw new InvalidOperationException( "The column location is no longer valid." ); - - var entry = m_columns[ index ]; - if( ( hashCode != entry.HashCode ) || !object.Equals( column, entry.Column ) ) - throw new InvalidOperationException( "The column location is no longer valid." ); - - return this.GetLevel( index ); - } - - private void EnsureCapacity() - { - // Make sure the collection is not full. - if( m_size != m_capacity ) - return; - - Debug.Assert( m_free == ColumnHierarchyModel.None ); - this.EnsureCapacity( m_capacity * 2L ); - Debug.Assert( m_free != ColumnHierarchyModel.None ); - Debug.Assert( m_size != m_capacity ); - } - - private void EnsureCapacity( long min ) - { - if( ( m_capacity >= min ) && ( m_capacity > 0 ) ) - return; - - var capacity = ColumnHierarchyModel.FindNextSize( min ); - Debug.Assert( capacity > 0 ); - - m_buckets = new int[ capacity ]; - - Array.Resize( ref m_columns, capacity ); - Array.Resize( ref m_status, capacity ); - Array.Resize( ref m_relations, capacity ); - - for( int i = 0; i < m_buckets.Length; i++ ) - { - m_buckets[ i ] = ColumnHierarchyModel.None; - } - - for( int i = m_capacity; i < capacity; i++ ) - { - m_columns[ i ] = new ColumnEntry( ( i < capacity - 1 ) ? i + 1 : ColumnHierarchyModel.None ); - m_status[ i ] = default( TStatus ); - m_relations[ i ] = RelationEntry.Default; - } - - // Rehash the elements to initialize the buckets. - for( int i = 0; i < m_capacity; i++ ) - { - var entry = m_columns[ i ]; - - // Only column entry needs to adjust the buckets. - if( this.IsColumn( entry ) ) - { - var bucket = ColumnHierarchyModel.GetBucket( entry.HashCode, capacity ); - Debug.Assert( ( bucket >= 0 ) && ( bucket < capacity ) ); - - var index = m_buckets[ bucket ]; - - m_buckets[ bucket ] = i; - m_columns[ i ] = entry.SetNext( index ); - } - } - - m_free = m_capacity; - m_capacity = capacity; - } - - private static int FindNextSize( long min ) - { - var sizes = ArrayHelper.Sizes; - - for( int i = 0; i < sizes.Length; i++ ) - { - var size = sizes[ i ]; - - if( size >= min ) - return size; - } - - throw new InvalidOperationException( "Cannot find a larger size." ); - } - - private static int GetBucket( int hashCode, int capacity ) - { - Debug.Assert( capacity > 0 ); - - // Remove the negative sign without using Math.Abs to handle the case of int.MinValue. - return ( hashCode & 0x7fffffff ) % capacity; - } - - private int[] m_buckets; - private ColumnEntry[] m_columns; - private TStatus[] m_status; - private RelationEntry[] m_relations; - private MarkEntry[] m_marks; - private int m_level; //0 - private int m_capacity; //0 - private int m_size; //0 - private bool m_preventLayoutChanged; //false - private int m_free = ColumnHierarchyModel.None; - - #region IMarkers Internal Interface - - internal interface IMarkers - { - ILocation Start - { - get; - } - - ILocation End - { - get; - } - - ILocation Splitter - { - get; - } - - ILocation Orphan - { - get; - } - } - - #endregion - - #region ILocation Internal Interface - - internal interface ILocation - { - LocationType Type - { - get; - } - - int Level - { - get; - } - - ILocation GetParent(); - ILocation GetFirstChild(); - - ILocation GetPreviousSibling(); - ILocation GetNextSibling(); - - ILocation GetPreviousSiblingOrCousin(); - ILocation GetNextSiblingOrCousin(); - - bool CanMoveBefore( ILocation location ); - bool CanMoveAfter( ILocation location ); - bool CanMoveUnder( ILocation location ); - - void MoveBefore( ILocation location ); - void MoveAfter( ILocation location ); - void MoveUnder( ILocation location ); - } - - #endregion - - #region IColumnLocation Internal Interface - - internal interface IColumnLocation : ILocation - { - TColumn Column - { - get; - } - - TStatus Status - { - get; - set; - } - } - - #endregion - - #region LayoutChangingEventArgs Internal Class - - internal sealed class LayoutChangingEventArgs : EventArgs - { - internal LayoutChangingEventArgs( ILocation location, LayoutChangingAction action ) - { - m_location = location; - m_action = action; - } - - internal ILocation Location - { - get - { - return m_location; - } - } - - internal LayoutChangingAction Action - { - get - { - return m_action; - } - } - - private readonly ILocation m_location; - private readonly LayoutChangingAction m_action; - } - - #endregion - - #region LayoutChangedEventArgs Internal Class - - internal sealed class LayoutChangedEventArgs : EventArgs - { - internal LayoutChangedEventArgs( ILocation location, LayoutChangedAction action ) - { - m_location = location; - m_action = action; - } - - internal ILocation Location - { - get - { - return m_location; - } - } - - internal LayoutChangedAction Action - { - get - { - return m_action; - } - } - - private readonly ILocation m_location; - private readonly LayoutChangedAction m_action; - } - - #endregion - - #region StatusChangedEventArgs Internal Class - - internal sealed class StatusChangedEventArgs : EventArgs - { - internal StatusChangedEventArgs( IColumnLocation location, TStatus oldValue, TStatus newValue ) - { - m_location = location; - m_oldValue = oldValue; - m_newValue = newValue; - } - - internal IColumnLocation Location - { - get - { - return m_location; - } - } - - internal TStatus OldValue - { - get - { - return m_oldValue; - } - } - - internal TStatus NewValue - { - get - { - return m_newValue; - } - } - - private readonly IColumnLocation m_location; - private readonly TStatus m_oldValue; - private readonly TStatus m_newValue; - } - - #endregion - - #region LayoutChangingAction Internal Enum - - internal enum LayoutChangingAction - { - Clearing, - Removing, - ChangingParent, - ChangingFirstChild, - ChangingPrevious, - ChangingNext, - } - - #endregion - - #region LayoutChangedAction Internal Enum - - internal enum LayoutChangedAction - { - Cleared, - Added, - ParentChanged, - FirstChildChanged, - PreviousChanged, - NextChanged, - } - - #endregion - - #region IPivotLocation Private Interface - - private interface IPivotLocation - { - bool CanBeNextSiblingOf( IMovableLocation location ); - bool CanBePreviousSiblingOf( IMovableLocation location ); - bool CanBeParentOf( IMovableLocation location ); - - void SetHasNextSiblingOf( IMovableLocation location ); - void SetHasPreviousSiblingOf( IMovableLocation location ); - void SetHasParentOf( IMovableLocation location ); - } - - #endregion - - #region IMovableLocation Private Interface - - private interface IMovableLocation - { - bool CanMoveBefore( StartLocation location ); - bool CanMoveBefore( EndLocation location ); - bool CanMoveBefore( SplitterLocation location ); - bool CanMoveBefore( OrphanLocation location ); - bool CanMoveBefore( ColumnLocation location ); - - bool CanMoveAfter( StartLocation location ); - bool CanMoveAfter( EndLocation location ); - bool CanMoveAfter( SplitterLocation location ); - bool CanMoveAfter( OrphanLocation location ); - bool CanMoveAfter( ColumnLocation location ); - - bool CanMoveUnder( StartLocation location ); - bool CanMoveUnder( EndLocation location ); - bool CanMoveUnder( SplitterLocation location ); - bool CanMoveUnder( OrphanLocation location ); - bool CanMoveUnder( ColumnLocation location ); - - void MoveBefore( StartLocation location ); - void MoveBefore( EndLocation location ); - void MoveBefore( SplitterLocation location ); - void MoveBefore( OrphanLocation location ); - void MoveBefore( ColumnLocation location ); - - void MoveAfter( StartLocation location ); - void MoveAfter( EndLocation location ); - void MoveAfter( SplitterLocation location ); - void MoveAfter( OrphanLocation location ); - void MoveAfter( ColumnLocation location ); - - void MoveUnder( StartLocation location ); - void MoveUnder( EndLocation location ); - void MoveUnder( SplitterLocation location ); - void MoveUnder( OrphanLocation location ); - void MoveUnder( ColumnLocation location ); - } - - #endregion - - #region Markers Private Class - - private sealed class Markers : IMarkers - { - internal Markers( ColumnHierarchyModel owner, int level, MarkEntry entry ) - { - Debug.Assert( owner != null ); - - m_owner = owner; - m_level = level; - m_entry = entry; - } - - public ILocation Start - { - get - { - this.EnsureMarks(); - - return m_owner.CreateStartLocation( m_level, m_entry.Start ); - } - } - - public ILocation End - { - get - { - this.EnsureMarks(); - - return m_owner.CreateEndLocation( m_level, m_entry.End ); - } - } - - public ILocation Splitter - { - get - { - this.EnsureMarks(); - - return m_owner.CreateSplitterLocation( m_level, m_entry.Splitter ); - } - } - - public ILocation Orphan - { - get - { - this.EnsureMarks(); - - return m_owner.CreateOrphanLocation( m_level, m_entry.Orphan ); - } - } - - public override int GetHashCode() - { - return m_level; - } - - public override bool Equals( object obj ) - { - var target = obj as Markers; - if( target == null ) - return false; - - return ( m_level == target.m_level ) - && ( object.Equals( m_entry, target.m_entry ) ) - && ( m_owner == target.m_owner ); - } - - private void EnsureMarks() - { - m_owner.EnsureMarks( m_level, m_entry ); - } - - private readonly ColumnHierarchyModel m_owner; - private readonly int m_level; - private readonly MarkEntry m_entry; - } - - #endregion - - #region Location Private Class - - private abstract class Location : ILocation, IMovableLocation, IPivotLocation - { - protected Location( ColumnHierarchyModel owner, int index ) - { - Debug.Assert( owner != null ); - - m_owner = owner; - m_index = index; - } - - protected abstract LocationType Type - { - get; - } - - protected int Level - { - get - { - return this.EnsureLocation(); - } - } - - internal int Index - { - get - { - return m_index; - } - } - - internal ColumnHierarchyModel Owner - { - get - { - return m_owner; - } - } - - LocationType ILocation.Type - { - get - { - return this.Type; - } - } - - int ILocation.Level - { - get - { - return this.Level; - } - } - - public override int GetHashCode() - { - return m_index; - } - - public override bool Equals( object obj ) - { - var target = obj as Location; - if( target == null ) - return false; - - return ( m_index == target.m_index ) - && ( m_owner == target.m_owner ); - } - - protected TStatus GetStatus() - { - this.EnsureLocation(); - - return m_owner.GetStatus( m_index ); - } - - protected void SetStatus( TStatus status ) - { - this.EnsureLocation(); - - m_owner.SetStatus( m_index, status ); - } - - protected void MoveBeforeCore( Location location ) - { - m_owner.MoveBefore( m_index, location.m_index ); - } - - protected void MoveAfterCore( Location location ) - { - m_owner.MoveAfter( m_index, location.m_index ); - } - - protected void MoveUnderCore( Location location ) - { - m_owner.MoveUnder( m_index, location.m_index ); - } - - protected virtual bool CanMoveBefore( StartLocation location ) - { - return false; - } - - protected virtual bool CanMoveBefore( EndLocation location ) - { - return false; - } - - protected virtual bool CanMoveBefore( SplitterLocation location ) - { - return false; - } - - protected virtual bool CanMoveBefore( OrphanLocation location ) - { - return false; - } - - protected virtual bool CanMoveBefore( ColumnLocation location ) - { - return false; - } - - protected virtual bool CanMoveAfter( StartLocation location ) - { - return false; - } - - protected virtual bool CanMoveAfter( EndLocation location ) - { - return false; - } - - protected virtual bool CanMoveAfter( SplitterLocation location ) - { - return false; - } - - protected virtual bool CanMoveAfter( OrphanLocation location ) - { - return false; - } - - protected virtual bool CanMoveAfter( ColumnLocation location ) - { - return false; - } - - protected virtual bool CanMoveUnder( StartLocation location ) - { - return false; - } - - protected virtual bool CanMoveUnder( EndLocation location ) - { - return false; - } - - protected virtual bool CanMoveUnder( SplitterLocation location ) - { - return false; - } - - protected virtual bool CanMoveUnder( OrphanLocation location ) - { - return false; - } - - protected virtual bool CanMoveUnder( ColumnLocation location ) - { - return false; - } - - protected virtual void MoveBefore( StartLocation location ) - { - throw new NotSupportedException(); - } - - protected virtual void MoveBefore( EndLocation location ) - { - throw new NotSupportedException(); - } - - protected virtual void MoveBefore( SplitterLocation location ) - { - throw new NotSupportedException(); - } - - protected virtual void MoveBefore( OrphanLocation location ) - { - throw new NotSupportedException(); - } - - protected virtual void MoveBefore( ColumnLocation location ) - { - throw new NotSupportedException(); - } - - protected virtual void MoveAfter( StartLocation location ) - { - throw new NotSupportedException(); - } - - protected virtual void MoveAfter( EndLocation location ) - { - throw new NotSupportedException(); - } - - protected virtual void MoveAfter( SplitterLocation location ) - { - throw new NotSupportedException(); - } - - protected virtual void MoveAfter( OrphanLocation location ) - { - throw new NotSupportedException(); - } - - protected virtual void MoveAfter( ColumnLocation location ) - { - throw new NotSupportedException(); - } - - protected virtual void MoveUnder( StartLocation location ) - { - throw new NotSupportedException(); - } - - protected virtual void MoveUnder( EndLocation location ) - { - throw new NotSupportedException(); - } - - protected virtual void MoveUnder( SplitterLocation location ) - { - throw new NotSupportedException(); - } - - protected virtual void MoveUnder( OrphanLocation location ) - { - throw new NotSupportedException(); - } - - protected virtual void MoveUnder( ColumnLocation location ) - { - throw new NotSupportedException(); - } - - protected abstract bool CanBeNextSiblingOf( IMovableLocation location ); - protected abstract bool CanBePreviousSiblingOf( IMovableLocation location ); - protected abstract bool CanBeParentOf( IMovableLocation location ); - protected abstract void SetHasNextSiblingOf( IMovableLocation location ); - protected abstract void SetHasPreviousSiblingOf( IMovableLocation location ); - protected abstract void SetHasParentOf( IMovableLocation location ); - - internal abstract int EnsureLocation(); - - private int EnsureLocation( ILocation location ) - { - if( location == null ) - throw new ArgumentNullException( "location" ); - - var target = location as Location; - if( target == null ) - throw new ArgumentException( "The location must derive from Location.", "location" ); - - if( target.Owner != m_owner ) - throw new ArgumentException( "The location must share the same owner.", "location" ); - - return target.EnsureLocation(); - } - - private void EnsureSiblingLocation( ILocation location ) - { - var sourceLevel = this.EnsureLocation(); - var targetLevel = this.EnsureLocation( location ); - - if( sourceLevel != targetLevel ) - throw new ArgumentException( "The location must be on the same level.", "location" ); - } - - private void EnsureParentLocation( ILocation location ) - { - var sourceLevel = this.EnsureLocation(); - var targetLevel = this.EnsureLocation( location ); - - if( sourceLevel != targetLevel - 1 ) - throw new ArgumentException( "The location must be on the parent level.", "location" ); - } - - ILocation ILocation.GetParent() - { - this.EnsureLocation(); - return m_owner.GetTargetLocation( m_owner.GetParent( m_index ) ); - } - - ILocation ILocation.GetFirstChild() - { - this.EnsureLocation(); - return m_owner.GetTargetLocation( m_owner.GetFirstChild( m_index ) ); - } - - ILocation ILocation.GetPreviousSibling() - { - this.EnsureLocation(); - return m_owner.GetTargetLocation( m_owner.GetPreviousSibling( m_index ) ); - } - - ILocation ILocation.GetNextSibling() - { - this.EnsureLocation(); - return m_owner.GetTargetLocation( m_owner.GetNextSibling( m_index ) ); - } - - ILocation ILocation.GetPreviousSiblingOrCousin() - { - this.EnsureLocation(); - return m_owner.GetTargetLocation( m_owner.GetPreviousSiblingOrCousin( m_index ) ); - } - - ILocation ILocation.GetNextSiblingOrCousin() - { - this.EnsureLocation(); - return m_owner.GetTargetLocation( m_owner.GetNextSiblingOrCousin( m_index ) ); - } - - bool ILocation.CanMoveBefore( ILocation location ) - { - if( location == null ) - return false; - - if( object.Equals( location, this ) ) - return false; - - var currentLevel = this.EnsureLocation(); - var targetLevel = this.EnsureLocation( location ); - - if( currentLevel != targetLevel ) - return false; - - Debug.Assert( location is IPivotLocation ); - - return ( ( IPivotLocation )location ).CanBeNextSiblingOf( this ); - } - - bool ILocation.CanMoveAfter( ILocation location ) - { - if( location == null ) - return false; - - if( object.Equals( location, this ) ) - return false; - - var currentLevel = this.EnsureLocation(); - var targetLevel = this.EnsureLocation( location ); - - if( currentLevel != targetLevel ) - return false; - - Debug.Assert( location is IPivotLocation ); - - return ( ( IPivotLocation )location ).CanBePreviousSiblingOf( this ); - } - - bool ILocation.CanMoveUnder( ILocation location ) - { - if( location == null ) - return false; - - if( object.Equals( location, this ) ) - return false; - - var currentLevel = this.EnsureLocation(); - var targetLevel = this.EnsureLocation( location ); - - if( currentLevel != targetLevel - 1 ) - return false; - - Debug.Assert( location is IPivotLocation ); - - return ( ( IPivotLocation )location ).CanBeParentOf( this ); - } - - void ILocation.MoveBefore( ILocation location ) - { - this.EnsureSiblingLocation( location ); - - Debug.Assert( ( ( ILocation )this ).CanMoveBefore( location ) ); - Debug.Assert( location is IPivotLocation ); - - ( ( IPivotLocation )location ).SetHasNextSiblingOf( this ); - } - - void ILocation.MoveAfter( ILocation location ) - { - this.EnsureSiblingLocation( location ); - - Debug.Assert( ( ( ILocation )this ).CanMoveAfter( location ) ); - Debug.Assert( location is IPivotLocation ); - - ( ( IPivotLocation )location ).SetHasPreviousSiblingOf( this ); - } - - void ILocation.MoveUnder( ILocation location ) - { - this.EnsureParentLocation( location ); - - Debug.Assert( ( ( ILocation )this ).CanMoveUnder( location ) ); - Debug.Assert( location is IPivotLocation ); - - ( ( IPivotLocation )location ).SetHasParentOf( this ); - } - - bool IMovableLocation.CanMoveBefore( StartLocation location ) - { - return this.CanMoveBefore( location ); - } - - bool IMovableLocation.CanMoveBefore( EndLocation location ) - { - return this.CanMoveBefore( location ); - } - - bool IMovableLocation.CanMoveBefore( SplitterLocation location ) - { - return this.CanMoveBefore( location ); - } - - bool IMovableLocation.CanMoveBefore( OrphanLocation location ) - { - return this.CanMoveBefore( location ); - } - - bool IMovableLocation.CanMoveBefore( ColumnLocation location ) - { - return this.CanMoveBefore( location ); - } - - bool IMovableLocation.CanMoveAfter( StartLocation location ) - { - return this.CanMoveAfter( location ); - } - - bool IMovableLocation.CanMoveAfter( EndLocation location ) - { - return this.CanMoveAfter( location ); - } - - bool IMovableLocation.CanMoveAfter( SplitterLocation location ) - { - return this.CanMoveAfter( location ); - } - - bool IMovableLocation.CanMoveAfter( OrphanLocation location ) - { - return this.CanMoveAfter( location ); - } - - bool IMovableLocation.CanMoveAfter( ColumnLocation location ) - { - return this.CanMoveAfter( location ); - } - - bool IMovableLocation.CanMoveUnder( StartLocation location ) - { - return this.CanMoveUnder( location ); - } - - bool IMovableLocation.CanMoveUnder( EndLocation location ) - { - return this.CanMoveUnder( location ); - } - - bool IMovableLocation.CanMoveUnder( SplitterLocation location ) - { - return this.CanMoveUnder( location ); - } - - bool IMovableLocation.CanMoveUnder( OrphanLocation location ) - { - return this.CanMoveUnder( location ); - } - - bool IMovableLocation.CanMoveUnder( ColumnLocation location ) - { - return this.CanMoveUnder( location ); - } - - void IMovableLocation.MoveBefore( StartLocation location ) - { - this.MoveBefore( location ); - } - - void IMovableLocation.MoveBefore( EndLocation location ) - { - this.MoveBefore( location ); - } - - void IMovableLocation.MoveBefore( SplitterLocation location ) - { - this.MoveBefore( location ); - } - - void IMovableLocation.MoveBefore( OrphanLocation location ) - { - this.MoveBefore( location ); - } - - void IMovableLocation.MoveBefore( ColumnLocation location ) - { - this.MoveBefore( location ); - } - - void IMovableLocation.MoveAfter( StartLocation location ) - { - this.MoveAfter( location ); - } - - void IMovableLocation.MoveAfter( EndLocation location ) - { - this.MoveAfter( location ); - } - - void IMovableLocation.MoveAfter( SplitterLocation location ) - { - this.MoveAfter( location ); - } - - void IMovableLocation.MoveAfter( OrphanLocation location ) - { - this.MoveAfter( location ); - } - - void IMovableLocation.MoveAfter( ColumnLocation location ) - { - this.MoveAfter( location ); - } - - void IMovableLocation.MoveUnder( StartLocation location ) - { - this.MoveUnder( location ); - } - - void IMovableLocation.MoveUnder( EndLocation location ) - { - this.MoveUnder( location ); - } - - void IMovableLocation.MoveUnder( SplitterLocation location ) - { - this.MoveUnder( location ); - } - - void IMovableLocation.MoveUnder( OrphanLocation location ) - { - this.MoveUnder( location ); - } - - void IMovableLocation.MoveUnder( ColumnLocation location ) - { - this.MoveUnder( location ); - } - - bool IPivotLocation.CanBeNextSiblingOf( IMovableLocation location ) - { - return this.CanBeNextSiblingOf( location ); - } - - bool IPivotLocation.CanBePreviousSiblingOf( IMovableLocation location ) - { - return this.CanBePreviousSiblingOf( location ); - } - - bool IPivotLocation.CanBeParentOf( IMovableLocation location ) - { - return this.CanBeParentOf( location ); - } - - void IPivotLocation.SetHasNextSiblingOf( IMovableLocation location ) - { - this.SetHasNextSiblingOf( location ); - } - - void IPivotLocation.SetHasPreviousSiblingOf( IMovableLocation location ) - { - this.SetHasPreviousSiblingOf( location ); - } - - void IPivotLocation.SetHasParentOf( IMovableLocation location ) - { - this.SetHasParentOf( location ); - } - - private readonly ColumnHierarchyModel m_owner; - private readonly int m_index; - } - - #endregion - - #region StartLocation Private Class - - private sealed class StartLocation : Location - { - internal StartLocation( ColumnHierarchyModel owner, int level, int index ) - : base( owner, index ) - { - m_level = level; - } - - protected override LocationType Type - { - get - { - return LocationType.Start; - } - } - - public override int GetHashCode() - { - return base.GetHashCode(); - } - - public override bool Equals( object obj ) - { - var target = obj as StartLocation; - if( target == null ) - return false; - - return ( m_level == target.m_level ) - && ( base.Equals( target ) ); - } - - protected override bool CanBeNextSiblingOf( IMovableLocation location ) - { - return location.CanMoveBefore( this ); - } - - protected override bool CanBePreviousSiblingOf( IMovableLocation location ) - { - return location.CanMoveAfter( this ); - } - - protected override bool CanBeParentOf( IMovableLocation location ) - { - return location.CanMoveUnder( this ); - } - - protected override void SetHasNextSiblingOf( IMovableLocation location ) - { - location.MoveBefore( this ); - } - - protected override void SetHasPreviousSiblingOf( IMovableLocation location ) - { - location.MoveAfter( this ); - } - - protected override void SetHasParentOf( IMovableLocation location ) - { - location.MoveUnder( this ); - } - - internal override int EnsureLocation() - { - return this.Owner.EnsureStart( m_level, this.Index ); - } - - private readonly int m_level; - } - - #endregion - - #region EndLocation Private Class - - private sealed class EndLocation : Location - { - internal EndLocation( ColumnHierarchyModel owner, int level, int index ) - : base( owner, index ) - { - m_level = level; - } - - protected override LocationType Type - { - get - { - return LocationType.End; - } - } - - public override int GetHashCode() - { - return base.GetHashCode(); - } - - public override bool Equals( object obj ) - { - var target = obj as EndLocation; - if( target == null ) - return false; - - return ( m_level == target.m_level ) - && ( base.Equals( target ) ); - } - - protected override bool CanBeNextSiblingOf( IMovableLocation location ) - { - return location.CanMoveBefore( this ); - } - - protected override bool CanBePreviousSiblingOf( IMovableLocation location ) - { - return location.CanMoveAfter( this ); - } - - protected override bool CanBeParentOf( IMovableLocation location ) - { - return location.CanMoveUnder( this ); - } - - protected override void SetHasNextSiblingOf( IMovableLocation location ) - { - location.MoveBefore( this ); - } - - protected override void SetHasPreviousSiblingOf( IMovableLocation location ) - { - location.MoveAfter( this ); - } - - protected override void SetHasParentOf( IMovableLocation location ) - { - location.MoveUnder( this ); - } - - internal override int EnsureLocation() - { - return this.Owner.EnsureEnd( m_level, this.Index ); - } - - private readonly int m_level; - } - - #endregion - - #region SplitterLocation Private Class - - private sealed class SplitterLocation : Location - { - internal SplitterLocation( ColumnHierarchyModel owner, int level, int index ) - : base( owner, index ) - { - m_level = level; - } - - protected override LocationType Type - { - get - { - return LocationType.Splitter; - } - } - - internal bool IsMovable - { - get - { - return ( m_level == this.Owner.LevelCount - 1 ); - } - } - - public override int GetHashCode() - { - return base.GetHashCode(); - } - - public override bool Equals( object obj ) - { - var target = obj as SplitterLocation; - if( target == null ) - return false; - - return ( m_level == target.m_level ) - && ( base.Equals( target ) ); - } - - protected override bool CanMoveBefore( ColumnLocation location ) - { - return this.CanMoveSplitterBefore( location ); - } - - protected override bool CanMoveBefore( OrphanLocation location ) - { - return this.CanMoveSplitterBefore( location ); - } - - protected override bool CanMoveAfter( ColumnLocation location ) - { - return this.CanMoveSplitterAfter( location ); - } - - protected override bool CanMoveAfter( StartLocation location ) - { - return this.CanMoveSplitterAfter( location ); - } - - protected override void MoveBefore( ColumnLocation location ) - { - this.MoveSplitterBefore( location ); - } - - protected override void MoveBefore( OrphanLocation location ) - { - this.MoveSplitterBefore( location ); - } - - protected override void MoveAfter( ColumnLocation location ) - { - this.MoveSplitterAfter( location ); - } - - protected override void MoveAfter( StartLocation location ) - { - this.MoveSplitterAfter( location ); - } - - protected override bool CanBeNextSiblingOf( IMovableLocation location ) - { - return location.CanMoveBefore( this ); - } - - protected override bool CanBePreviousSiblingOf( IMovableLocation location ) - { - return location.CanMoveAfter( this ); - } - - protected override bool CanBeParentOf( IMovableLocation location ) - { - return location.CanMoveUnder( this ); - } - - protected override void SetHasNextSiblingOf( IMovableLocation location ) - { - location.MoveBefore( this ); - } - - protected override void SetHasPreviousSiblingOf( IMovableLocation location ) - { - location.MoveAfter( this ); - } - - protected override void SetHasParentOf( IMovableLocation location ) - { - location.MoveUnder( this ); - } - - internal override int EnsureLocation() - { - return this.Owner.EnsureSplitter( m_level, this.Index ); - } - - private bool CanMoveSplitterBefore( ILocation location ) - { - if( this.IsMovable ) - return true; - - // The current and target locations should not be on the top-most level. - Debug.Assert( m_level < this.Owner.LevelCount - 1 ); - - // The splitter may not move or a merged column is going to be splitted. - if( location.GetPreviousSibling() != null ) - return false; - - var parentLocation = ( ( ILocation )this ).GetParent(); - Debug.Assert( parentLocation != null ); - - return parentLocation.CanMoveBefore( location.GetParent() ); - } - - private bool CanMoveSplitterAfter( ILocation location ) - { - if( this.IsMovable ) - return true; - - // The current and target locations should not be on the top-most level. - Debug.Assert( m_level < this.Owner.LevelCount - 1 ); - - // The splitter may not move or a merged column is going to be splitted. - if( location.GetNextSibling() != null ) - return false; - - var parentLocation = ( ( ILocation )this ).GetParent(); - Debug.Assert( parentLocation != null ); - - return parentLocation.CanMoveAfter( location.GetParent() ); - } - - private void MoveSplitterBefore( Location location ) - { - if( this.IsMovable ) - { - this.MoveBeforeCore( location ); - } - else - { - var parentLocation = ( ( ILocation )this ).GetParent(); - Debug.Assert( parentLocation != null ); - - parentLocation.MoveBefore( ( ( ILocation )location ).GetParent() ); - } - } - - private void MoveSplitterAfter( Location location ) - { - if( this.IsMovable ) - { - this.MoveAfterCore( location ); - } - else - { - var parentLocation = ( ( ILocation )this ).GetParent(); - Debug.Assert( parentLocation != null ); - - parentLocation.MoveAfter( ( ( ILocation )location ).GetParent() ); - } - } - - private readonly int m_level; - } - - #endregion - - #region OrphanLocation Private Class - - private sealed class OrphanLocation : Location - { - internal OrphanLocation( ColumnHierarchyModel owner, int level, int index ) - : base( owner, index ) - { - m_level = level; - } - - protected override LocationType Type - { - get - { - return LocationType.Orphan; - } - } - - public override int GetHashCode() - { - return base.GetHashCode(); - } - - public override bool Equals( object obj ) - { - var target = obj as OrphanLocation; - if( target == null ) - return false; - - return ( m_level == target.m_level ) - && ( base.Equals( target ) ); - } - - protected override bool CanBeNextSiblingOf( IMovableLocation location ) - { - return location.CanMoveBefore( this ); - } - - protected override bool CanBePreviousSiblingOf( IMovableLocation location ) - { - return location.CanMoveAfter( this ); - } - - protected override bool CanBeParentOf( IMovableLocation location ) - { - return location.CanMoveUnder( this ); - } - - protected override void SetHasNextSiblingOf( IMovableLocation location ) - { - location.MoveBefore( this ); - } - - protected override void SetHasPreviousSiblingOf( IMovableLocation location ) - { - location.MoveAfter( this ); - } - - protected override void SetHasParentOf( IMovableLocation location ) - { - location.MoveUnder( this ); - } - - internal override int EnsureLocation() - { - return this.Owner.EnsureOrphan( m_level, this.Index ); - } - - private readonly int m_level; - } - - #endregion - - #region ColumnLocation Private Class - - private sealed class ColumnLocation : Location, IColumnLocation - { - internal ColumnLocation( ColumnHierarchyModel owner, TColumn column, int hashCode, int index ) - : base( owner, index ) - { - m_column = column; - m_hashCode = hashCode; - } - - protected override LocationType Type - { - get - { - return LocationType.Column; - } - } - - TColumn IColumnLocation.Column - { - get - { - return m_column; - } - } - - TStatus IColumnLocation.Status - { - get - { - return this.GetStatus(); - } - set - { - this.SetStatus( value ); - } - } - - public override int GetHashCode() - { - return base.GetHashCode(); - } - - public override bool Equals( object obj ) - { - var target = obj as ColumnLocation; - if( target == null ) - return false; - - return ( object.Equals( m_column, target.m_column ) ) - && ( base.Equals( target ) ); - } - - protected override bool CanMoveBefore( ColumnLocation location ) - { - return true; - } - - protected override bool CanMoveBefore( SplitterLocation location ) - { - // The column may move only next to the the top-most splitter. - return location.IsMovable; - } - - protected override bool CanMoveBefore( OrphanLocation location ) - { - return true; - } - - protected override bool CanMoveAfter( ColumnLocation location ) - { - return true; - } - - protected override bool CanMoveAfter( SplitterLocation location ) - { - // The column may move only next to the the top-most splitter. - return location.IsMovable; - } - - protected override bool CanMoveAfter( StartLocation location ) - { - return true; - } - - protected override bool CanMoveUnder( ColumnLocation location ) - { - return true; - } - - protected override bool CanMoveUnder( OrphanLocation location ) - { - return true; - } - - protected override void MoveBefore( ColumnLocation location ) - { - this.MoveBeforeCore( location ); - } - - protected override void MoveBefore( SplitterLocation location ) - { - this.MoveBeforeCore( location ); - } - - protected override void MoveBefore( OrphanLocation location ) - { - this.MoveBeforeCore( location ); - } - - protected override void MoveAfter( ColumnLocation location ) - { - this.MoveAfterCore( location ); - } - - protected override void MoveAfter( SplitterLocation location ) - { - this.MoveAfterCore( location ); - } - - protected override void MoveAfter( StartLocation location ) - { - this.MoveAfterCore( location ); - } - - protected override void MoveUnder( ColumnLocation location ) - { - this.MoveUnderCore( location ); - } - - protected override void MoveUnder( OrphanLocation location ) - { - this.MoveUnderCore( location ); - } - - protected override bool CanBeNextSiblingOf( IMovableLocation location ) - { - return location.CanMoveBefore( this ); - } - - protected override bool CanBePreviousSiblingOf( IMovableLocation location ) - { - return location.CanMoveAfter( this ); - } - - protected override bool CanBeParentOf( IMovableLocation location ) - { - return location.CanMoveUnder( this ); - } - - protected override void SetHasNextSiblingOf( IMovableLocation location ) - { - location.MoveBefore( this ); - } - - protected override void SetHasPreviousSiblingOf( IMovableLocation location ) - { - location.MoveAfter( this ); - } - - protected override void SetHasParentOf( IMovableLocation location ) - { - location.MoveUnder( this ); - } - - internal override int EnsureLocation() - { - return this.Owner.EnsureColumn( m_column, m_hashCode, this.Index ); - } - - private readonly TColumn m_column; - private readonly int m_hashCode; - } - - #endregion - - #region ColumnEntry Private Struct - - [DebuggerDisplay( "Column = {Column}, Next = {Next}" )] - private struct ColumnEntry - { - internal ColumnEntry( TColumn column, int hashCode, int next ) - { - m_column = column; - m_hashCode = hashCode; - m_next = next; - } - - internal ColumnEntry( int next ) - : this( default( TColumn ), 0, next ) - { - } - - internal TColumn Column - { - get - { - return m_column; - } - } - - internal int HashCode - { - get - { - return m_hashCode; - } - } - - internal int Next - { - get - { - return m_next; - } - } - - internal ColumnEntry SetNext( int next ) - { - return new ColumnEntry( m_column, m_hashCode, next ); - } - - private readonly TColumn m_column; - private readonly int m_hashCode; - private readonly int m_next; - } - - #endregion - - #region MarkEntry Private Struct - - [DebuggerDisplay( "Start = {Start}, End = {End}, Splitter = {Splitter}, Orphan = {Orphan}" )] - private struct MarkEntry - { - internal static readonly MarkEntry Default = new MarkEntry( ColumnHierarchyModel.None, ColumnHierarchyModel.None, ColumnHierarchyModel.None, ColumnHierarchyModel.None ); - - internal MarkEntry( int start, int end, int splitter, int orphan ) - { - m_start = start; - m_end = end; - m_splitter = splitter; - m_orphan = orphan; - } - - internal int Start - { - get - { - return m_start; - } - } - - internal int End - { - get - { - return m_end; - } - } - - internal int Splitter - { - get - { - return m_splitter; - } - } - - internal int Orphan - { - get - { - return m_orphan; - } - } - - private readonly int m_start; - private readonly int m_end; - private readonly int m_splitter; - private readonly int m_orphan; - } - - #endregion - - #region RelationEntry Private Struct - - [DebuggerDisplay( "Parent = {Parent}, FirstChild = {FirstChild}, Previous = {Previous}, Next = {Next}" )] - private struct RelationEntry - { - internal static readonly RelationEntry Default = new RelationEntry( ColumnHierarchyModel.None, ColumnHierarchyModel.None ); - - internal RelationEntry( int parent, int child, int previous, int next ) - { - m_previous = previous; - m_next = next; - m_parent = parent; - m_child = child; - } - - internal RelationEntry( int child, int previous, int next ) - : this( ColumnHierarchyModel.None, child, previous, next ) - { - } - - internal RelationEntry( int previous, int next ) - : this( ColumnHierarchyModel.None, previous, next ) - { - } - - internal int Parent - { - get - { - return m_parent; - } - } - - internal int FirstChild - { - get - { - return m_child; - } - } - - internal int Previous - { - get - { - return m_previous; - } - } - - internal int Next - { - get - { - return m_next; - } - } - - internal RelationEntry SetParent( int parent ) - { - return new RelationEntry( parent, m_child, m_previous, m_next ); - } - - internal RelationEntry SetFirstChild( int child ) - { - return new RelationEntry( m_parent, child, m_previous, m_next ); - } - - internal RelationEntry SetPrevious( int previous ) - { - return new RelationEntry( m_parent, m_child, previous, m_next ); - } - - internal RelationEntry SetNext( int next ) - { - return new RelationEntry( m_parent, m_child, m_previous, next ); - } - - private readonly int m_previous; - private readonly int m_next; - private readonly int m_parent; - private readonly int m_child; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnManagerCell.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnManagerCell.cs deleted file mode 100644 index 3704d7fb..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnManagerCell.cs +++ /dev/null @@ -1,1026 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; -using System.Diagnostics; -using System.Globalization; -using System.Windows; -using System.Windows.Automation.Peers; -using System.Windows.Controls.Primitives; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using Xceed.Utils.Wpf.DragDrop; -using Xceed.Wpf.DataGrid.Views; - -namespace Xceed.Wpf.DataGrid -{ - [TemplatePart( Name = "PART_ColumnResizerThumb", Type = typeof( Thumb ) )] - [TemplatePart( Name = "PART_ColumnResizerThumbLeft", Type = typeof( Thumb ) )] - public class ColumnManagerCell : Cell, IDropTarget - { - static ColumnManagerCell() - { - UIElement.FocusableProperty.OverrideMetadata( typeof( ColumnManagerCell ), new FrameworkPropertyMetadata( false ) ); - Cell.ReadOnlyProperty.OverrideMetadata( typeof( ColumnManagerCell ), new FrameworkPropertyMetadata( true ) ); - - ColumnManagerCell.IsPressedProperty = ColumnManagerCell.IsPressedPropertyKey.DependencyProperty; - - ColumnManagerCell.IsBeingDraggedProperty = ColumnManagerCell.IsBeingDraggedPropertyKey.DependencyProperty; - } - - public ColumnManagerCell() - { - this.ReadOnly = true; - } - - #region IsPressed Read-Only Property - - private static readonly DependencyPropertyKey IsPressedPropertyKey = - DependencyProperty.RegisterReadOnly( "IsPressed", typeof( bool ), typeof( ColumnManagerCell ), new PropertyMetadata( false ) ); - - public static readonly DependencyProperty IsPressedProperty; - - public bool IsPressed - { - get - { - return ( bool )this.GetValue( ColumnManagerCell.IsPressedProperty ); - } - } - - private void SetIsPressed( bool value ) - { - this.SetValue( ColumnManagerCell.IsPressedPropertyKey, value ); - } - - #endregion IsPressed Read-Only Property - - #region IsBeingDragged Read-Only Property - - private static readonly DependencyPropertyKey IsBeingDraggedPropertyKey = - DependencyProperty.RegisterReadOnly( "IsBeingDragged", typeof( bool ), typeof( ColumnManagerCell ), new PropertyMetadata( false ) ); - - public static readonly DependencyProperty IsBeingDraggedProperty; - - public bool IsBeingDragged - { - get - { - return ( bool )this.GetValue( ColumnManagerCell.IsBeingDraggedProperty ); - } - } - - private void SetIsBeingDragged( bool value ) - { - this.SetValue( ColumnManagerCell.IsBeingDraggedPropertyKey, value ); - } - - #endregion IsBeingDragged Read-Only Property - - #region DataGridContext Internal Read-Only Property - - internal DataGridContext DataGridContext - { - get - { - return m_dataGridContext; - } - } - - #endregion - - #region DragSourceManager Property - - // This property is required by the ColumnManagerRow when performing AnimatedColumnReordering since it must - // handle the Commit when the DraggedCell is dropped over the space already reserved for it in the ColumnManagerRow - internal DragSourceManager DragSourceManager - { - get - { - return m_dragSourceManager; - } - } - - #endregion - - #region ShowResizeCursor Property - - internal bool ShowResizeCursor - { - get; - set; - } - - #endregion - - #region AllowResize Internal Read-Only Property - - internal virtual bool AllowResize - { - get - { - if( this.ParentColumn == null ) - return false; - - var dataGridContext = this.DataGridContext; - if( dataGridContext == null ) - return false; - - // When details are flatten, only the column at the master level may be resized. - if( dataGridContext.IsAFlattenDetail ) - return false; - - return true; - } - } - - #endregion - - #region CanBeCollapsed Property - - internal override bool CanBeCollapsed - { - get - { - // A ColumnManagerCell is always collapsible (except when it, or it's parent column, is being dragged), since it can't be edited. - if( ( bool )this.GetValue( ColumnManagerCell.IsBeingDraggedProperty ) ) - { - return false; - } - - var parentColumn = this.ParentColumn; - if( parentColumn == null ) - return true; - - return !TableflowView.GetIsBeingDraggedAnimated( parentColumn ); - - } - } - - #endregion - - public override void OnApplyTemplate() - { - base.OnApplyTemplate(); - - this.SetupColumnResizerThumb(); - } - - protected override void InitializeCore( DataGridContext dataGridContext, Row parentRow, ColumnBase parentColumn ) - { - base.InitializeCore( dataGridContext, parentRow, parentColumn ); - - this.SetColumnBinding( ColumnManagerCell.ContentProperty, "ParentColumn.Title" ); - this.SetColumnBinding( ColumnManagerCell.ContentTemplateProperty, "ParentColumn.TitleTemplate" ); - this.SetColumnBinding( ColumnManagerCell.ContentTemplateSelectorProperty, "ParentColumn.TitleTemplateSelector" ); - } - - - protected internal override void PrepareDefaultStyleKey( ViewBase view ) - { - var newThemeKey = view.GetDefaultStyleKey( typeof( ColumnManagerCell ) ); - if( object.Equals( this.DefaultStyleKey, newThemeKey ) ) - return; - - this.DefaultStyleKey = newThemeKey; - } - - protected internal override void PrepareContainer( DataGridContext dataGridContext, object item ) - { - base.PrepareContainer( dataGridContext, item ); - m_dataGridContext = dataGridContext; - } - - protected internal override void ClearContainer() - { - m_dataGridContext = null; - base.ClearContainer(); - } - - protected override void OnMouseLeftButtonDown( MouseButtonEventArgs e ) - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - if( this.CaptureMouse() ) - { - this.SetIsPressed( true ); - - // Ensure the DragSourceManager is created - if( m_dragSourceManager == null ) - { - this.SetupDragManager(); - Debug.Assert( m_dragSourceManager != null ); - } - - if( m_dragSourceManager != null ) - { - if( dataGridContext != null ) - { - // Update the DropOutsideCursor since it is defined on the View - UIViewBase uiViewBase = dataGridContext.DataGridControl.GetView() as UIViewBase; - - m_dragSourceManager.DropOutsideCursor = ( uiViewBase != null ) ? uiViewBase.CannotDropDraggedElementCursor : UIViewBase.DefaultCannotDropDraggedElementCursor; - m_dragSourceManager.DragStart( e ); - } - } - - e.Handled = true; - } - - base.OnMouseLeftButtonDown( e ); - } - - protected override void OnMouseMove( MouseEventArgs e ) - { - if( ( this.IsMouseCaptured ) && ( e.LeftButton == MouseButtonState.Pressed ) ) - { - if( m_dragSourceManager != null ) - { - m_dragSourceManager.DragMove( e ); - } - - if( !this.IsBeingDragged ) - { - Rect bounds = new Rect( 0d, 0d, this.ActualWidth, this.ActualHeight ); - this.SetIsPressed( bounds.Contains( e.GetPosition( this ) ) ); - } - else - { - this.SetIsPressed( false ); - } - - e.Handled = true; - } - - base.OnMouseMove( e ); - } - - protected override void OnMouseLeftButtonUp( MouseButtonEventArgs e ) - { - // m_dragSourceManager.ProcessMouseLeftButtonUp() will release the capture, so we need to check the IsMouseCaptured and IsPressed states before calling it. - bool isMouseCaptured = this.IsMouseCaptured; - bool isPressed = this.IsPressed; - - if( m_dragSourceManager != null ) - { - m_dragSourceManager.Drop( e ); - } - - if( isMouseCaptured ) - { - bool click = isPressed; - - this.ReleaseMouseCapture(); - this.SetIsPressed( false ); - - if( click ) - { - this.DoSort( ( ( Keyboard.Modifiers & ModifierKeys.Shift ) != ModifierKeys.Shift ) ); - } - - e.Handled = true; - } - - // Focus must be done only on mouse up ( after the sort is done ... etc ) - // we have to focus the grid. - - // We don't need to set PreserveEditorFocus to true since clicking on another element will automatically - // set the Cell/Row IsBeingEdited to false and try to make it leave edition. - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - if( dataGridContext != null ) - { - DataGridControl dataGridControl = dataGridContext.DataGridControl; - - if( ( dataGridControl != null ) && ( !dataGridControl.IsKeyboardFocusWithin ) ) - { - dataGridControl.Focus(); - } - } - - base.OnMouseLeftButtonUp( e ); - } - - protected override void OnLostMouseCapture( MouseEventArgs e ) - { - if( m_dragSourceManager != null ) - { - m_dragSourceManager.DragCancel( e ); - } - - if( this.IsPressed ) - { - this.SetIsPressed( false ); - } - - base.OnLostMouseCapture( e ); - } - - internal bool CanDoSort() - { - ColumnManagerRow parentRow = this.ParentRow as ColumnManagerRow; - if( parentRow != null ) - { - if( !parentRow.AllowSort ) - return false; - } - - DataGridContext dataGridContext = this.DataGridContext; - if( dataGridContext == null ) - return false; - - // When details are flatten, only the ColumnManagerCell at the master level may do the sort. - if( dataGridContext.IsAFlattenDetail ) - return false; - - if( dataGridContext.SourceDetailConfiguration == null ) - { - if( !dataGridContext.Items.CanSort ) - return false; - } - - if( !this.IsEnabled ) - return false; - - ColumnBase parentColumn = this.ParentColumn; - if( ( parentColumn == null ) || ( !parentColumn.AllowSort ) ) - return false; - - return true; - } - - internal void DoSort( bool shiftUnpressed ) - { - if( !this.CanDoSort() ) - return; - - DataGridContext dataGridContext = this.DataGridContext; - ColumnBase column = this.ParentColumn; - - Debug.Assert( dataGridContext != null ); - - var toggleColumnSortCommand = dataGridContext.ToggleColumnSortCommand; - - toggleColumnSortCommand.Execute( column, shiftUnpressed ); - } - - internal void DoResize( double newWidth, ColumnBase parentColumn ) - { - if( !this.IsEnabled ) - return; - - if( !parentColumn.HasFixedWidth ) - { - if( newWidth < MIN_WIDTH ) - { - newWidth = MIN_WIDTH; - } - - if( newWidth < parentColumn.MinWidth ) - { - newWidth = parentColumn.MinWidth; - } - - if( newWidth > parentColumn.MaxWidth ) - { - newWidth = parentColumn.MaxWidth; - } - - parentColumn.Width = newWidth; - } - } - - internal virtual void OnColumnResizerThumbDragStarted( DragStartedEventArgs e ) - { - var parentColumn = this.ParentColumn; - Debug.Assert( parentColumn != null ); - - var dataGridContext = this.DataGridContext; - Debug.Assert( dataGridContext != null ); - - m_originalWidth = parentColumn.ActualWidth; - - if( TableView.GetRemoveColumnStretchingOnResize( dataGridContext ) ) - { - dataGridContext.ColumnStretchingManager.DisableColumnStretching(); - } - } - - internal virtual void OnColumnResizerThumbDragDelta( DragDeltaEventArgs e ) - { - var parentColumn = this.ParentColumn; - Debug.Assert( parentColumn != null ); - - this.DoResize( parentColumn.ActualWidth + e.HorizontalChange, parentColumn ); - } - - internal virtual void OnColumnResizerThumbDragCompleted( DragCompletedEventArgs e ) - { - if( e.Canceled ) - { - this.ParentColumn.Width = m_originalWidth; - } - - m_originalWidth = -1d; - } - - internal void ShowDropMark( RelativePoint mousePosition ) - { - if( m_dropMarkAdorner == null ) - { - var dataGridContext = this.DataGridContext; - var grid = ( dataGridContext != null ) ? dataGridContext.DataGridControl : null; - - Pen pen = UIViewBase.GetDropMarkPen( this ); - - if( ( pen == null ) && ( grid != null ) ) - { - UIViewBase uiViewBase = grid.GetView() as UIViewBase; - pen = uiViewBase.DefaultDropMarkPen; - } - - DropMarkOrientation orientation = UIViewBase.GetDropMarkOrientation( this ); - - if( ( orientation == DropMarkOrientation.Default ) && ( grid != null ) ) - { - UIViewBase uiViewBase = grid.GetView() as UIViewBase; - orientation = uiViewBase.DefaultDropMarkOrientation; - } - - m_dropMarkAdorner = new DropMarkAdorner( this, pen, orientation ); - - AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer( this ); - - if( adornerLayer != null ) - { - adornerLayer.Add( m_dropMarkAdorner ); - } - } - - m_dropMarkAdorner.UpdateAlignment( mousePosition ); - } - - internal void HideDropMark() - { - if( m_dropMarkAdorner != null ) - { - AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer( this ); - - if( adornerLayer != null ) - { - adornerLayer.Remove( m_dropMarkAdorner ); - } - - m_dropMarkAdorner = null; - } - } - - private void SetupColumnResizerThumb() - { - if( m_columnResizerThumb != null ) - { - m_columnResizerThumb.DragStarted -= new DragStartedEventHandler( this.ColumnResizerThumb_DragStarted ); - m_columnResizerThumb.DragDelta -= new DragDeltaEventHandler( this.ColumnResizerThumb_DragDelta ); - m_columnResizerThumb.DragCompleted -= new DragCompletedEventHandler( this.ColumnResizerThumb_DragCompleted ); - m_columnResizerThumb.QueryCursor -= new QueryCursorEventHandler( this.ColumnResizerThumb_QueryCursor ); - m_columnResizerThumb.MouseDoubleClick -= new MouseButtonEventHandler( this.ColumnResizerThumb_MouseDoubleClick ); - - m_columnResizerThumb = null; - } - - if( m_columnResizerThumbLeft != null ) - { - m_columnResizerThumbLeft.DragStarted -= new DragStartedEventHandler( this.ColumnResizerThumbLeft_DragStarted ); - m_columnResizerThumbLeft.DragDelta -= new DragDeltaEventHandler( this.ColumnResizerThumbLeft_DragDelta ); - m_columnResizerThumbLeft.DragCompleted -= new DragCompletedEventHandler( this.ColumnResizerThumbLeft_DragCompleted ); - m_columnResizerThumbLeft.QueryCursor -= new QueryCursorEventHandler( this.ColumnResizerThumbLeft_QueryCursor ); - m_columnResizerThumbLeft.MouseDoubleClick -= new MouseButtonEventHandler( this.ColumnResizerThumbLeft_MouseDoubleClick ); - - m_columnResizerThumbLeft = null; - } - - m_columnResizerThumb = this.GetTemplateChild( "PART_ColumnResizerThumb" ) as Thumb; - m_columnResizerThumbLeft = this.GetTemplateChild( "PART_ColumnResizerThumbLeft" ) as Thumb; - - if( m_columnResizerThumb != null ) - { - m_columnResizerThumb.DragStarted += new DragStartedEventHandler( this.ColumnResizerThumb_DragStarted ); - m_columnResizerThumb.DragDelta += new DragDeltaEventHandler( this.ColumnResizerThumb_DragDelta ); - m_columnResizerThumb.DragCompleted += new DragCompletedEventHandler( this.ColumnResizerThumb_DragCompleted ); - m_columnResizerThumb.QueryCursor += new QueryCursorEventHandler( this.ColumnResizerThumb_QueryCursor ); - m_columnResizerThumb.MouseDoubleClick += new MouseButtonEventHandler( this.ColumnResizerThumb_MouseDoubleClick ); - } - - if( m_columnResizerThumbLeft != null ) - { - m_columnResizerThumbLeft.DragStarted += new DragStartedEventHandler( this.ColumnResizerThumbLeft_DragStarted ); - m_columnResizerThumbLeft.DragDelta += new DragDeltaEventHandler( this.ColumnResizerThumbLeft_DragDelta ); - m_columnResizerThumbLeft.DragCompleted += new DragCompletedEventHandler( this.ColumnResizerThumbLeft_DragCompleted ); - m_columnResizerThumbLeft.QueryCursor += new QueryCursorEventHandler( this.ColumnResizerThumbLeft_QueryCursor ); - m_columnResizerThumbLeft.MouseDoubleClick += new MouseButtonEventHandler( this.ColumnResizerThumbLeft_MouseDoubleClick ); - } - } - - private void SetupDragManager() - { - // Prevent any drag operation if columns layout is changing. - var dataGridContext = this.DataGridContext; - if( ( dataGridContext == null ) || ( dataGridContext.ColumnManager.IsUpdateDeferred ) ) - return; - - // We do not support DragDrop when there are no AdornerLayer because there wouldn't be any visual feedback for the operation. - AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer( this ); - if( adornerLayer == null ) - { - // When virtualizing, the Cell is not yet in the VisualTree because it is the ParentRow's CellsHost which - // is reponsible of putting them in the VisualTree. We try to get the adorner from the ParentRow instead - if( this.ParentRow != null ) - { - adornerLayer = AdornerLayer.GetAdornerLayer( this.ParentRow ); - } - - if( adornerLayer == null ) - return; - } - - var dataGridControl = dataGridContext.DataGridControl; - Debug.Assert( dataGridControl != null ); - - if( m_dragSourceManager != null ) - { - m_dragSourceManager.PropertyChanged -= this.DragSourceManager_PropertyChanged; - } - - // The DataGridControl's AdornerDecoratorForDragAndDrop must be used for dragging in order to include the RenderTransform - // the DataGridControl may performs. This AdornerDecorator is defined in the ControlTemplate as PART_DragDropAdornerDecorator - if( ( dataGridControl.DragDropAdornerDecorator != null ) && ( dataGridControl.DragDropAdornerDecorator.AdornerLayer != null ) ) - { - m_dragSourceManager = new ColumnReorderingDragSourceManager( this, dataGridControl.DragDropAdornerDecorator.AdornerLayer, dataGridControl, this.ParentRow.LevelCache ); - } - else - { - m_dragSourceManager = new ColumnReorderingDragSourceManager( this, null, dataGridControl, this.ParentRow.LevelCache ); - } - - m_dragSourceManager.PropertyChanged += this.DragSourceManager_PropertyChanged; - - // Create bindings to ViewProperties for AutoScroll Properties - Binding binding = new Binding(); - binding.Path = new PropertyPath( "(0).(1)", DataGridControl.DataGridContextProperty, TableView.AutoScrollIntervalProperty ); - binding.Mode = BindingMode.OneWay; - binding.Source = this; - binding.Converter = new MillisecondsConverter(); - BindingOperations.SetBinding( m_dragSourceManager, DragSourceManager.AutoScrollIntervalProperty, binding ); - - binding = new Binding(); - binding.Path = new PropertyPath( "(0).(1)", DataGridControl.DataGridContextProperty, TableView.AutoScrollThresholdProperty ); - binding.Mode = BindingMode.OneWay; - binding.Source = this; - BindingOperations.SetBinding( m_dragSourceManager, DragSourceManager.AutoScrollThresholdProperty, binding ); - } - - private void DragSourceManager_PropertyChanged( object sender, PropertyChangedEventArgs e ) - { - if( e.PropertyName == "IsDragging" ) - { - this.SetIsBeingDragged( m_dragSourceManager.IsDragging ); - } - } - - private void ColumnResizerThumb_DragStarted( object sender, DragStartedEventArgs e ) - { - if( !this.ShowResizeCursor || !this.AllowResize ) - return; - - this.OnColumnResizerThumbDragStarted( e ); - } - - private void ColumnResizerThumb_DragDelta( object sender, DragDeltaEventArgs e ) - { - if( !this.ShowResizeCursor || !this.AllowResize ) - return; - - this.OnColumnResizerThumbDragDelta( e ); - } - - private void ColumnResizerThumb_DragCompleted( object sender, DragCompletedEventArgs e ) - { - if( !this.ShowResizeCursor || !this.AllowResize ) - return; - - this.OnColumnResizerThumbDragCompleted( e ); - } - - private void ColumnResizerThumb_MouseDoubleClick( object sender, MouseButtonEventArgs e ) - { - var parentColumn = this.ParentColumn; - if( ( parentColumn == null ) || !this.ShowResizeCursor || !this.AllowResize ) - return; - - e.Handled = true; - - double fittedWidth = parentColumn.GetFittedWidth(); - if( fittedWidth != -1 ) - { - parentColumn.Width = fittedWidth; - } - } - - private void ColumnResizerThumb_QueryCursor( object sender, QueryCursorEventArgs e ) - { - var parentColumn = this.ParentColumn; - if( parentColumn == null ) - return; - - var dataGridContext = this.DataGridContext; - - bool showResizeCursor = false; - if( this.AllowResize ) - { - // Don't disable resizing if ColumnStretching can be disabled by an end-user resize. - showResizeCursor = ( !parentColumn.HasFixedWidth ) - || ( ( dataGridContext != null ) && TableView.GetRemoveColumnStretchingOnResize( dataGridContext ) ); - } - - this.ShowResizeCursor = showResizeCursor; - if( this.ShowResizeCursor ) - { - UIViewBase viewBase = ( dataGridContext != null ) ? dataGridContext.DataGridControl.GetView() as UIViewBase : null; - - e.Cursor = ( viewBase != null ) ? viewBase.ColumnResizeWestEastCursor : UIViewBase.DefaultColumnResizeWestEastCursor; - e.Handled = true; - } - } - - private ColumnManagerCell GetPreviousVisibleColumnManagerCell() - { - var parentColumn = this.ParentColumn; - if( parentColumn == null ) - return null; - - var previousVisibleColumn = parentColumn.PreviousVisibleColumn; - if( previousVisibleColumn == null ) - return null; - - return ( ColumnManagerCell )this.ParentRow.Cells[ previousVisibleColumn ]; - } - - private void ColumnResizerThumbLeft_QueryCursor( object sender, QueryCursorEventArgs e ) - { - var previousColumnManagerCell = this.GetPreviousVisibleColumnManagerCell(); - if( previousColumnManagerCell == null ) - return; - - previousColumnManagerCell.ColumnResizerThumb_QueryCursor( previousColumnManagerCell, e ); - } - - private void ColumnResizerThumbLeft_DragStarted( object sender, DragStartedEventArgs e ) - { - var previousColumnManagerCell = this.GetPreviousVisibleColumnManagerCell(); - if( previousColumnManagerCell == null ) - return; - - previousColumnManagerCell.ColumnResizerThumb_DragStarted( previousColumnManagerCell, e ); - } - - private void ColumnResizerThumbLeft_MouseDoubleClick( object sender, MouseButtonEventArgs e ) - { - var previousColumnManagerCell = this.GetPreviousVisibleColumnManagerCell(); - if( previousColumnManagerCell == null ) - return; - - previousColumnManagerCell.ColumnResizerThumb_MouseDoubleClick( previousColumnManagerCell, e ); - } - - private void ColumnResizerThumbLeft_DragDelta( object sender, DragDeltaEventArgs e ) - { - var previousColumnManagerCell = this.GetPreviousVisibleColumnManagerCell(); - if( previousColumnManagerCell == null ) - return; - - previousColumnManagerCell.ColumnResizerThumb_DragDelta( previousColumnManagerCell, e ); - } - - private void ColumnResizerThumbLeft_DragCompleted( object sender, DragCompletedEventArgs e ) - { - var previousColumnManagerCell = this.GetPreviousVisibleColumnManagerCell(); - if( previousColumnManagerCell == null ) - return; - - previousColumnManagerCell.ColumnResizerThumb_DragCompleted( previousColumnManagerCell, e ); - } - - private void SetColumnBinding( DependencyProperty targetProperty, string sourceProperty ) - { - if( BindingOperations.GetBinding( this, targetProperty ) != null ) - return; - - var binding = ColumnManagerCell.CreateColumnBinding( sourceProperty ); - if( binding != null ) - { - BindingOperations.SetBinding( this, targetProperty, binding ); - } - else - { - BindingOperations.ClearBinding( this, targetProperty ); - } - } - - private static Binding CreateColumnBinding( string sourceProperty ) - { - var binding = new Binding(); - binding.Path = new PropertyPath( sourceProperty ); - binding.Mode = BindingMode.OneWay; - binding.RelativeSource = new RelativeSource( RelativeSourceMode.Self ); - binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged; - - return binding; - } - - #region IDropTarget Members - - bool IDropTarget.CanDropElement( UIElement draggedElement, RelativePoint mousePosition ) - { - var draggedCell = draggedElement as ColumnManagerCell; - if( ( draggedCell == null ) || ( this == draggedCell ) ) - return false; - - var parentRow = this.ParentRow as ColumnManagerRow; - if( ( parentRow == null ) || !parentRow.AllowColumnReorder ) - return false; - - var draggedDetailContext = draggedCell.DataGridContext; - var sourceDetailContext = this.DataGridContext; - Debug.Assert( ( draggedDetailContext != null ) && ( sourceDetailContext != null ) ); - - if( ( sourceDetailContext.SourceDetailConfiguration != draggedDetailContext.SourceDetailConfiguration ) || - ( sourceDetailContext.GroupLevelDescriptions != draggedDetailContext.GroupLevelDescriptions ) ) - return false; - - if( !ColumnManagerCell.CanMove( draggedCell ) ) - return false; - - var manager = draggedCell.DragSourceManager as ColumnReorderingDragSourceManager; - if( ( manager != null ) && ( manager.IsAnimatedColumnReorderingEnabled ) ) - { - if( !manager.CanReorder( draggedCell, this, mousePosition ) ) - return false; - } - else - { - var relativePosition = mousePosition.GetPoint( this ); - var moveBefore = ( relativePosition.X <= this.ActualWidth / 2d ); - - if( moveBefore ) - { - if( !draggedCell.CanMoveBefore( this.ParentColumn ) ) - return false; - } - else - { - if( !draggedCell.CanMoveAfter( this.ParentColumn ) ) - return false; - } - } - - return true; - } - - void IDropTarget.DragEnter( UIElement draggedElement ) - { - } - - void IDropTarget.DragOver( UIElement draggedElement, RelativePoint mousePosition ) - { - var draggedCell = draggedElement as ColumnManagerCell; - if( draggedCell != null ) - { - var manager = draggedCell.DragSourceManager as ColumnReorderingDragSourceManager; - - // No need for drop mark when performing animated Column reordering - if( ( manager != null ) && ( manager.IsAnimatedColumnReorderingEnabled ) ) - return; - } - - this.ShowDropMark( mousePosition ); - } - - void IDropTarget.DragLeave( UIElement draggedElement ) - { - var draggedCell = draggedElement as ColumnManagerCell; - if( draggedCell != null ) - { - var manager = draggedCell.DragSourceManager as ColumnReorderingDragSourceManager; - - // No need for drop mark when performing animated Column reordering - if( ( manager != null ) && ( manager.IsAnimatedColumnReorderingEnabled ) ) - return; - } - - this.HideDropMark(); - } - - void IDropTarget.Drop( UIElement draggedElement, RelativePoint mousePosition ) - { - var draggedCell = draggedElement as ColumnManagerCell; - if( draggedCell == null ) - return; - - this.ProcessDrop( draggedCell, mousePosition ); - } - - internal void ProcessDrop( ColumnManagerCell draggedCell, RelativePoint mousePosition ) - { - var manager = default( ColumnReorderingDragSourceManager ); - - if( draggedCell != null ) - { - manager = draggedCell.DragSourceManager as ColumnReorderingDragSourceManager; - } - - if( ( manager != null ) && ( manager.IsAnimatedColumnReorderingEnabled ) ) - { - manager.CommitReordering(); - } - else - { - this.HideDropMark(); - - var dataGridContext = this.DataGridContext; - Debug.Assert( dataGridContext != null ); - - if( dataGridContext != null ) - { - var targetColumn = draggedCell.ParentColumn; - var pivotColumn = this.ParentColumn; - - Debug.Assert( targetColumn != null ); - Debug.Assert( pivotColumn != null ); - - var relativePosition = mousePosition.GetPoint( this ); - var offset = Point.Subtract( mousePosition.GetPoint( draggedCell ), relativePosition ); - var moveBefore = true; - - // We assumme the cells are layouted horizontally. - if( Math.Abs( offset.X ) >= Math.Abs( offset.Y ) ) - { - // Consider the case where the columns are layouted from left to right in reverse order. - var reverse = ( ( offset.X > 0d ) == ( targetColumn.VisiblePosition >= pivotColumn.VisiblePosition ) ); - - moveBefore = ( ( relativePosition.X < this.ActualWidth / 2d ) != reverse ); - } - // We assume the cells are layouted vertically. - else - { - // Consider the case where the columns are layouted from top to bottom in reverse order. - var reverse = ( ( offset.Y > 0d ) == ( targetColumn.VisiblePosition >= pivotColumn.VisiblePosition ) ); - - moveBefore = ( ( relativePosition.Y < this.ActualHeight / 2d ) != reverse ); - } - - var success = ( moveBefore ) - ? dataGridContext.MoveColumnBefore( targetColumn, pivotColumn ) - : dataGridContext.MoveColumnAfter( targetColumn, pivotColumn ); - - Debug.Assert( success ); - } - } - } - - internal bool CanMoveBefore( ColumnBase column ) - { - // A column that is locked cannot move. - var parentColumn = this.ParentColumn; - if( ( parentColumn == null ) || ( parentColumn.DraggableStatus != ColumnDraggableStatus.Draggable ) ) - return false; - - // The cell cannot move before a column that is locked in the first position. - if( ( column == null ) || ( column.DraggableStatus == ColumnDraggableStatus.FirstUndraggable ) ) - return false; - - var dataGridContext = this.DataGridContext; - if( dataGridContext == null ) - return false; - - if( dataGridContext.AreDetailsFlatten ) - { - // Column reordering is not allowed for a ColumnManagerCell that is located at a detail level - // when details are flatten. - if( dataGridContext.SourceDetailConfiguration != null ) - return false; - - // The main column is always the first column when details are flatten. - if( column.IsMainColumn ) - return false; - } - - return true; - } - - internal bool CanMoveAfter( ColumnBase column ) - { - // A column that is locked cannot move. - var parentColumn = this.ParentColumn; - if( ( parentColumn == null ) || ( parentColumn.DraggableStatus != ColumnDraggableStatus.Draggable ) ) - return false; - - // The cell cannot move after a column that is locked in the last position. - if( ( column == null ) || ( column.DraggableStatus == ColumnDraggableStatus.LastUndraggable ) ) - return false; - - var dataGridContext = this.DataGridContext; - if( dataGridContext == null ) - return false; - - if( dataGridContext.AreDetailsFlatten ) - { - // Column reordering is not allowed for a ColumnManagerCell that is located at a detail level - // when details are flatten. - if( dataGridContext.SourceDetailConfiguration != null ) - return false; - - // The main column is not allowed to be reordered when details are flatten. - if( column.IsMainColumn ) - return false; - } - - return true; - } - - internal static bool CanMove( ColumnManagerCell cell ) - { - if( cell == null ) - return false; - - var dataGridContext = cell.DataGridContext; - if( dataGridContext == null ) - return false; - - // A column that is locked cannot move. - var parentColumn = cell.ParentColumn; - if( ( parentColumn == null ) || ( parentColumn.DraggableStatus != ColumnDraggableStatus.Draggable ) ) - return false; - - if( dataGridContext.AreDetailsFlatten ) - { - // Column reordering is not allowed for a ColumnManagerCell that is located at a detail level - // when details are flatten. - if( dataGridContext.SourceDetailConfiguration != null ) - return false; - - // The main column is not allowed to be reordered when details are flatten. - if( parentColumn.IsMainColumn ) - return false; - } - - return true; - } - - #endregion - - // Will remain null when no AdornerLayer is found. - private ColumnReorderingDragSourceManager m_dragSourceManager; - - private DropMarkAdorner m_dropMarkAdorner; - - private DataGridContext m_dataGridContext; // = null; - - private const double MIN_WIDTH = 8d; - private double m_originalWidth = -1d; - private Thumb m_columnResizerThumb; // = null - private Thumb m_columnResizerThumbLeft; // null - - #region MillisecondsConverter Private Class - - private sealed class MillisecondsConverter : IValueConverter - { - public object Convert( object value, Type targetType, object parameter, CultureInfo culture ) - { - return TimeSpan.FromMilliseconds( System.Convert.ToDouble( value ) ); - } - - public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture ) - { - throw new NotSupportedException(); - } - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnManagerRow.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnManagerRow.cs deleted file mode 100644 index 9f19429b..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnManagerRow.cs +++ /dev/null @@ -1,346 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.ComponentModel; -using System.Linq; -using System.Windows; -using System.Windows.Automation.Peers; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Input; -using Xceed.Utils.Wpf; -using Xceed.Utils.Wpf.DragDrop; -using Xceed.Wpf.DataGrid.Views; - -namespace Xceed.Wpf.DataGrid -{ - public class ColumnManagerRow : Row, IDropTarget - { - static ColumnManagerRow() - { - Row.NavigationBehaviorProperty.OverrideMetadata( typeof( ColumnManagerRow ), new FrameworkPropertyMetadata( NavigationBehavior.None ) ); - FrameworkElement.ContextMenuProperty.OverrideMetadata( typeof( ColumnManagerRow ), new FrameworkPropertyMetadata( null, new CoerceValueCallback( ColumnManagerRow.CoerceContextMenu ) ) ); - } - - public ColumnManagerRow() - { - //ensure that all ColumnManagerRows are ReadOnly - this.ReadOnly = true; //This is safe to perform since there is nowhere a callback installed on the DP... - - //ensure that all ColumnManagerRows are not navigable - this.NavigationBehavior = NavigationBehavior.None; //This is safe to perform since there is nowhere a callback installed on the DP... - } - - #region AllowColumnReorder Property - - public static readonly DependencyProperty AllowColumnReorderProperty = DependencyProperty.Register( - "AllowColumnReorder", - typeof( bool ), - typeof( ColumnManagerRow ), - new FrameworkPropertyMetadata( true, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback( ColumnManagerRow.OnAllowColumnReorderChanged ) ) ); - - public bool AllowColumnReorder - { - get - { - return ( bool )this.GetValue( ColumnManagerRow.AllowColumnReorderProperty ); - } - set - { - this.SetValue( ColumnManagerRow.AllowColumnReorderProperty, value ); - } - } - - private static void OnAllowColumnReorderChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var self = sender as ColumnManagerRow; - if( self == null ) - return; - - var configuration = self.Configuration; - if( configuration == null ) - return; - - configuration.AllowColumnReorder = ( bool )e.NewValue; - } - - #endregion - - #region AllowColumnResize Property - - public static readonly DependencyProperty AllowColumnResizeProperty = DependencyProperty.Register( - "AllowColumnResize", - typeof( bool ), - typeof( ColumnManagerRow ), - new UIPropertyMetadata( true ) ); - - public bool AllowColumnResize - { - get - { - return ( bool )this.GetValue( ColumnManagerRow.AllowColumnResizeProperty ); - } - set - { - this.SetValue( ColumnManagerRow.AllowColumnResizeProperty, value ); - } - } - - #endregion - - #region AllowSort Property - - public static readonly DependencyProperty AllowSortProperty = DependencyProperty.Register( - "AllowSort", - typeof( bool ), - typeof( ColumnManagerRow ), - new UIPropertyMetadata( true ) ); - - public bool AllowSort - { - get - { - return ( bool )this.GetValue( ColumnManagerRow.AllowSortProperty ); - } - set - { - this.SetValue( ColumnManagerRow.AllowSortProperty, value ); - } - } - - #endregion - - #region IsUnfocusable Property - - internal override bool IsUnfocusable - { - get - { - return true; - } - } - - #endregion - - #region Configuration Internal Property - - internal ColumnManagerRowConfiguration Configuration - { - get - { - return m_configuration; - } - set - { - if( value == m_configuration ) - return; - - if( m_configuration != null ) - { - PropertyChangedEventManager.RemoveListener( m_configuration, this, string.Empty ); - } - - m_configuration = value; - - this.PushAllowColumnReorder(); - - if( m_configuration != null ) - { - PropertyChangedEventManager.AddListener( m_configuration, this, string.Empty ); - } - - this.UpdateAllowColumnReorder(); - } - } - - private ColumnManagerRowConfiguration m_configuration; - - #endregion - - - protected override Cell CreateCell( ColumnBase column ) - { - return new ColumnManagerCell(); - } - - protected override bool IsValidCellType( Cell cell ) - { - return ( cell is ColumnManagerCell ); - } - - protected internal override void PrepareDefaultStyleKey( Xceed.Wpf.DataGrid.Views.ViewBase view ) - { - var currentThemeKey = view.GetDefaultStyleKey( typeof( ColumnManagerRow ) ); - if( currentThemeKey.Equals( this.DefaultStyleKey ) ) - return; - - this.DefaultStyleKey = currentThemeKey; - } - - protected override void PrepareContainer( DataGridContext dataGridContext, object item ) - { - base.PrepareContainer( dataGridContext, item ); - - this.Configuration = dataGridContext.ColumnManagerRowConfiguration; - } - - protected override void ClearContainer() - { - this.Configuration = null; - - base.ClearContainer(); - } - - protected override void OnPreviewMouseLeftButtonDown( System.Windows.Input.MouseButtonEventArgs e ) - { - //Do not call the base class implementation to prevent SetCurrent from being called... - //This is because we do not want the ColumnManager Row to be selectable through the Mouse - } - - protected override void OnMouseRightButtonUp( MouseButtonEventArgs e ) - { - if( e.Handled ) - return; - - base.OnMouseRightButtonUp( e ); - } - - private static object CoerceContextMenu( DependencyObject sender, object value ) - { - if( value == null ) - return value; - - var self = sender as ColumnManagerRow; - if( ( self == null ) ) - return value; - - return null; - } - - private void PushAllowColumnReorder() - { - var configuration = this.Configuration; - if( configuration == null ) - return; - - if( DependencyPropertyHelper.GetValueSource( this, ColumnManagerRow.AllowColumnReorderProperty ).BaseValueSource == BaseValueSource.Default ) - return; - - configuration.AllowColumnReorder = this.AllowColumnReorder; - } - - private void UpdateAllowColumnReorder() - { - var configuration = this.Configuration; - if( configuration == null ) - return; - - this.AllowColumnReorder = configuration.AllowColumnReorder; - } - - private void OnConfigurationPropertyChanged( PropertyChangedEventArgs e ) - { - var propertyName = e.PropertyName; - - if( string.IsNullOrEmpty( propertyName ) || propertyName == ColumnManagerRow.AllowColumnReorderProperty.Name ) - { - this.UpdateAllowColumnReorder(); - } - } - - #region IDropTarget Members - - bool IDropTarget.CanDropElement( UIElement draggedElement, RelativePoint mousePosition ) - { - var draggedCell = draggedElement as ColumnManagerCell; - if( draggedCell == null ) - return false; - - var manager = draggedCell.DragSourceManager as ColumnReorderingDragSourceManager; - if( ( manager != null ) && manager.IsAnimatedColumnReorderingEnabled && draggedCell.IsBeingDragged ) - { - var dataGridContext = DataGridControl.GetDataGridContext( this ); - if( ( dataGridContext == null ) || !dataGridContext.Columns.Contains( draggedCell.ParentColumn ) ) - return false; - - // We are not interested by the y-axis. - var relativePoint = mousePosition.GetPoint( this ); - var xPosition = new RelativePoint( this, new Point( relativePoint.X, this.ActualHeight / 2d ) ); - - var targetCell = ( from dropTarget in manager.GetDropTargetsAtPoint( xPosition ) - let dropCell = dropTarget as ColumnManagerCell - where ( dropCell != null ) - select dropCell ).FirstOrDefault(); - if( ( targetCell == null ) || ( targetCell == draggedCell ) || ( ( IDropTarget )targetCell ).CanDropElement( draggedElement, xPosition ) ) - return true; - } - - return false; - } - - void IDropTarget.DragEnter( UIElement draggedElement ) - { - } - - void IDropTarget.DragOver( UIElement draggedElement, RelativePoint mousePosition ) - { - } - - void IDropTarget.DragLeave( UIElement draggedElement ) - { - } - - void IDropTarget.Drop( UIElement draggedElement, RelativePoint mousePosition ) - { - var draggedCell = draggedElement as ColumnManagerCell; - if( draggedCell == null ) - return; - - var manager = draggedCell.DragSourceManager as ColumnReorderingDragSourceManager; - if( ( manager != null ) && ( manager.IsAnimatedColumnReorderingEnabled ) ) - { - manager.CommitReordering(); - } - } - - #endregion - - #region IWeakEventListener Members - - protected override bool OnReceiveWeakEvent( Type managerType, object sender, EventArgs e ) - { - var result = base.OnReceiveWeakEvent( managerType, sender, e ); - - if( typeof( PropertyChangedEventManager ) == managerType ) - { - if( sender == m_configuration ) - { - this.OnConfigurationPropertyChanged( ( PropertyChangedEventArgs )e ); - } - } - else - { - return result; - } - - return true; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnManagerRowConfiguration.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnManagerRowConfiguration.cs deleted file mode 100644 index 81fbab68..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnManagerRowConfiguration.cs +++ /dev/null @@ -1,67 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.ComponentModel; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal class ColumnManagerRowConfiguration : DependencyObject, INotifyPropertyChanged - { - #region AllowColumnReorder Property - - public static readonly DependencyProperty AllowColumnReorderProperty = DependencyProperty.Register( - "AllowColumnReorder", - typeof( bool ), - typeof( ColumnManagerRowConfiguration ), - new UIPropertyMetadata( true ) ); - - public bool AllowColumnReorder - { - get - { - return ( bool )this.GetValue( ColumnManagerRowConfiguration.AllowColumnReorderProperty ); - } - set - { - this.SetValue( ColumnManagerRowConfiguration.AllowColumnReorderProperty, value ); - } - } - - #endregion - - protected override void OnPropertyChanged( DependencyPropertyChangedEventArgs e ) - { - base.OnPropertyChanged( e ); - this.OnPropertyChanged( e.Property.Name ); - } - - #region INotifyPropertyChanged Members - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void OnPropertyChanged( string propertyName ) - { - var handler = this.PropertyChanged; - if( handler == null ) - return; - - handler.Invoke( this, new PropertyChangedEventArgs( propertyName ) ); - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnSortCommand.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnSortCommand.cs deleted file mode 100644 index 10ebae03..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnSortCommand.cs +++ /dev/null @@ -1,261 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics; -using System.Windows.Data; - -namespace Xceed.Wpf.DataGrid -{ - internal abstract class ColumnSortCommand : ColumnCommand - { - protected SynchronizationContext StartSynchronizing( SortDescriptionsSyncContext context ) - { - return new SynchronizationContext( context ); - } - - protected bool TryDeferResort( DetailConfiguration detailConfiguration, out IDisposable defer ) - { - defer = null; - - return ( detailConfiguration != null ) - && ( this.TryDeferResort( detailConfiguration.SortDescriptions, out defer ) ); - } - - protected bool TryDeferResort( SortDescriptionCollection sortDescriptions, out IDisposable defer ) - { - var dataGridSortDescriptions = sortDescriptions as DataGridSortDescriptionCollection; - if( dataGridSortDescriptions != null ) - { - defer = dataGridSortDescriptions.DeferResort(); - } - else - { - defer = null; - } - - return ( defer != null ); - } - - protected IDisposable DeferResortHelper( - IEnumerable itemsSourceCollection, - CollectionView collectionView ) - { - var dataGridCollectionView = itemsSourceCollection as DataGridCollectionViewBase; - if( dataGridCollectionView != null ) - return dataGridCollectionView.DataGridSortDescriptions.DeferResort(); - - ColumnSortCommand.ThrowIfNull( collectionView, "collectionView" ); - - return collectionView.DeferRefresh(); - } - - #region SynchronizationContext Protected Class - - protected sealed class SynchronizationContext : IDisposable - { - #region Constructor - - internal SynchronizationContext( SortDescriptionsSyncContext context ) - { - if( context == null ) - throw new ArgumentNullException( "context" ); - - m_context = context; - m_isOwner = !context.ProcessingSortSynchronization; - - context.ProcessingSortSynchronization = true; - } - - #endregion - - #region Own Property - - public bool Own - { - get - { - var context = m_context; - - return ( m_isOwner ) - && ( context != null ) - && ( context.ProcessingSortSynchronization ); - } - } - - #endregion - - #region IDisposable Members - - public void Dispose() - { - this.Dispose( true ); - GC.SuppressFinalize( this ); - } - - private void Dispose( bool disposing ) - { - var context = m_context; - if( context == null ) - return; - - m_context = null; - - if( m_isOwner ) - { - context.ProcessingSortSynchronization = false; - } - } - - ~SynchronizationContext() - { - this.Dispose( false ); - } - - #endregion - - #region Private Fields - - private SortDescriptionsSyncContext m_context; - private bool m_isOwner; - - #endregion - } - - #endregion - - #region Disposer Protected Class - - protected sealed class Disposer : IDisposable - { - #region Constants - - private static readonly int DisposableTypeCount = Enum.GetValues( typeof( DisposableType ) ).Length; - - #endregion - - public Disposer() - { - m_disposable = new Stack[ Disposer.DisposableTypeCount ]; - } - - public void Add( IDisposable disposable, DisposableType disposableType ) - { - if( m_disposed ) - throw new ObjectDisposedException( "Disposer" ); - - if( !Enum.IsDefined( typeof( DisposableType ), disposableType ) ) - throw new ArgumentException( "disposableType" ); - - if( disposable == null ) - return; - - int index = Disposer.GetIndex( disposableType ); - var collection = m_disposable[ index ]; - - if( collection == null ) - { - collection = new Stack(); - m_disposable[ index ] = collection; - } - - collection.Push( disposable ); - } - - private static int GetIndex( DisposableType value ) - { - int index = System.Convert.ToInt32( value ); - Debug.Assert( ( index >= 0 ) && ( index < Disposer.DisposableTypeCount ) ); - - return index; - } - - #region IDisposable Members - - public void Dispose() - { - this.Dispose( true ); - GC.SuppressFinalize( this ); - } - - private void Dispose( bool disposing ) - { - if( m_disposed ) - return; - - m_disposed = true; - - Exception exception = null; - - for( int i = m_disposable.Length - 1; i >= 0; i-- ) - { - var disposable = m_disposable[ i ]; - if( disposable == null ) - continue; - - while( disposable.Count > 0 ) - { - try - { - disposable.Pop().Dispose(); - } - catch( Exception e ) - { - if( exception == null ) - { - exception = e; - } - } - } - - m_disposable[ i ] = null; - } - - if( exception != null ) - throw new DataGridInternalException( exception ); - } - - ~Disposer() - { - this.Dispose( false ); - } - - #endregion - - #region Private Fields - - private readonly Stack[] m_disposable; - private bool m_disposed; - - #endregion - } - - #endregion - - #region DisposableType Protected Nested Type - - protected enum DisposableType - { - DeferRestoreState = 0, - DeferResort = 1, - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnSynchronizationManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnSynchronizationManager.cs deleted file mode 100644 index 8e8ded1f..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnSynchronizationManager.cs +++ /dev/null @@ -1,1126 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Diagnostics; -using System.Linq; -using System.Windows; -using System.Windows.Data; -using Xceed.Utils.Wpf; -using Xceed.Wpf.DataGrid.Views; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class ColumnSynchronizationManager : IWeakEventListener - { - #region Constructor - - internal ColumnSynchronizationManager( DetailConfiguration configuration ) - { - if( configuration == null ) - throw new ArgumentNullException( "configuration" ); - - m_detailConfiguration = configuration; - m_itemPropertyMap = configuration.ItemPropertyMap; - - PropertyChangedEventManager.AddListener( configuration, this, string.Empty ); - MappingChangedEventManager.AddListener( m_itemPropertyMap, this ); - - using( this.DeferSynchronization() ) - { - this.DataGridControl = configuration.DataGridControl; - this.DetailColumnManager = configuration.ColumnManager; - - Debug.Assert( m_detailColumnManager != null ); - } - } - - #endregion - - #region DataGridControl Private Property - - private DataGridControl DataGridControl - { - get - { - return m_dataGridControl; - } - set - { - if( value == m_dataGridControl ) - return; - - using( this.DeferSynchronization() ) - { - if( m_dataGridControl != null ) - { - ViewChangedEventManager.RemoveListener( m_dataGridControl, this ); - } - - m_dataGridControl = value; - - if( m_dataGridControl != null ) - { - ViewChangedEventManager.AddListener( m_dataGridControl, this ); - - this.MasterColumnManager = m_dataGridControl.DataGridContext.ColumnManager; - } - else - { - this.MasterColumnManager = null; - } - - m_isSynchronizationValid = false; - } - } - } - - private DataGridControl m_dataGridControl; - - #endregion - - #region MasterColumnManager Private Property - - private ColumnHierarchyManager MasterColumnManager - { - get - { - return m_masterColumnManager; - } - set - { - if( value == m_masterColumnManager ) - return; - - if( m_masterColumnManager != null ) - { - ColumnsLayoutChangedEventManager.RemoveListener( m_masterColumnManager, this ); - CollectionChangedEventManager.RemoveListener( m_masterColumnManager.Columns, this ); - PropertyChangedEventManager.RemoveListener( m_masterColumnManager.Columns, this, ColumnCollection.MainColumnPropertyName ); - } - - m_masterColumnManager = value; - - if( m_masterColumnManager != null ) - { - ColumnsLayoutChangedEventManager.AddListener( m_masterColumnManager, this ); - CollectionChangedEventManager.AddListener( m_masterColumnManager.Columns, this ); - PropertyChangedEventManager.AddListener( m_masterColumnManager.Columns, this, ColumnCollection.MainColumnPropertyName ); - } - } - } - - private ColumnHierarchyManager m_masterColumnManager; - - #endregion - - #region DetailColumnManager Private Property - - private ColumnHierarchyManager DetailColumnManager - { - get - { - return m_detailColumnManager; - } - set - { - if( value == m_detailColumnManager ) - return; - - if( m_detailColumnManager != null ) - { - ColumnsLayoutChangedEventManager.RemoveListener( m_detailColumnManager, this ); - CollectionChangedEventManager.RemoveListener( m_detailColumnManager.Columns, this ); - } - - m_detailColumnManager = value; - - if( m_detailColumnManager != null ) - { - ColumnsLayoutChangedEventManager.AddListener( m_detailColumnManager, this ); - CollectionChangedEventManager.AddListener( m_detailColumnManager.Columns, this ); - } - } - } - - private ColumnHierarchyManager m_detailColumnManager; - - #endregion - - #region IsSynchronizationReady Private Property - - private bool IsSynchronizationReady - { - get - { - return ( m_masterColumnManager != null ) - && ( m_detailConfiguration.DetailDescription != null ); - } - } - - #endregion - - #region AreDetailsFlatten Private Property - - private bool AreDetailsFlatten - { - get - { - return ( m_dataGridControl != null ) - && ( m_dataGridControl.AreDetailsFlatten ); - } - } - - #endregion - - #region DeferSynchronization Methods - - private IDisposable DeferSynchronization() - { - return new DeferredDisposable( new DeferState( this ) ); - } - - private bool IsSynchronizationDeferred - { - get - { - return ( m_deferSynchronizationCount != 0 ); - } - } - - private int m_deferSynchronizationCount; //0 - private bool m_isSynchronizationValid = true; - - #endregion - - internal void Refresh() - { - if( m_isUpdatingColumns ) - return; - - m_isSynchronizationValid = false; - - this.UpdateColumns(); - } - - private void UpdateColumns() - { - if( this.IsSynchronizationDeferred || m_isSynchronizationValid || m_isUpdatingColumns ) - return; - - try - { - m_isUpdatingColumns = true; - m_isSynchronizationValid = true; - - if( this.IsSynchronizationReady && this.AreDetailsFlatten ) - { - Debug.Assert( m_detailColumnManager != null ); - - using( m_detailColumnManager.DeferUpdate() ) - { - var keys = new HashSet( this.GetNewKeys() ); - - foreach( var key in m_pairedColumns.Keys.Except( keys ).ToArray() ) - { - this.Desynchronize( key ); - } - - foreach( var key in keys.OrderBy( item => item.OrderKey ) ) - { - this.Synchronize( key ); - } - - this.SetMainColumn(); - } - } - else - { - this.Desynchronize(); - } - } - finally - { - m_isUpdatingColumns = false; - } - } - - private void Synchronize( SynchronizationKey key ) - { - if( key == null ) - return; - - var collection = m_pairedColumns; - - SynchronizationEntry pair; - if( !collection.TryGetValue( key, out pair ) ) - { - if( key.MasterColumn != null ) - { - pair = new BoundColumn( this, key ); - } - else - { - pair = new UnboundColumn( this, key ); - } - - collection.Add( key, pair ); - } - - pair.Synchronize(); - } - - private void Desynchronize( SynchronizationKey key ) - { - if( key == null ) - return; - - var collection = m_pairedColumns; - - SynchronizationEntry pair; - if( !collection.TryGetValue( key, out pair ) ) - return; - - collection.Remove( key ); - pair.Desynchronize(); - } - - private void Desynchronize() - { - var collection = m_pairedColumns; - while( collection.Count > 0 ) - { - this.Desynchronize( collection.First().Key ); - } - } - - private void SetMainColumn() - { - if( !this.IsSynchronizationReady || !this.AreDetailsFlatten ) - return; - - Debug.Assert( m_detailColumnManager != null ); - - var detailColumns = m_detailColumnManager.Columns; - var detailColumn = default( ColumnBase ); - - var mainColumn = m_masterColumnManager.Columns.MainColumn; - if( mainColumn != null ) - { - if( !DataGridItemPropertyMapHelper.TryGetDetailColumn( m_itemPropertyMap, detailColumns, mainColumn, out detailColumn ) ) - { - detailColumn = null; - } - } - - detailColumns.MainColumn = detailColumn; - } - - private IEnumerable GetNewKeys() - { - foreach( var detailColumn in m_detailColumnManager.Columns ) - { - var masterColumn = default( ColumnBase ); - - if( !DataGridItemPropertyMapHelper.TryGetMasterColumn( m_itemPropertyMap, m_masterColumnManager.Columns, detailColumn, out masterColumn ) ) - { - masterColumn = null; - } - - yield return new SynchronizationKey( masterColumn, detailColumn, m_detailConfiguration ); - } - } - - private void OnViewChanged() - { - this.Refresh(); - } - - private void OnMasterColumnsPropertyChanged( PropertyChangedEventArgs e ) - { - var propertyName = e.PropertyName; - bool mayHaveChanged = string.IsNullOrEmpty( propertyName ); - - if( mayHaveChanged || ( propertyName == ColumnCollection.MainColumnPropertyName ) ) - { - this.SetMainColumn(); - } - } - - private void OnDetailConfigurationPropertyChanged( PropertyChangedEventArgs e ) - { - var propertyName = e.PropertyName; - bool mayHaveChanged = string.IsNullOrEmpty( propertyName ); - - if( mayHaveChanged || ( propertyName == DetailConfiguration.DataGridControlPropertyName ) ) - { - this.DataGridControl = m_detailConfiguration.DataGridControl; - } - } - - private void OnItemPropertyMapMappingChanged( EventArgs e ) - { - this.Refresh(); - } - - private void OnMasterColumnsCollectionChanged( NotifyCollectionChangedEventArgs e ) - { - if( e.Action == NotifyCollectionChangedAction.Move ) - return; - - this.Refresh(); - } - - private void OnDetailColumnsCollectionChanged( NotifyCollectionChangedEventArgs e ) - { - if( e.Action == NotifyCollectionChangedAction.Move ) - return; - - this.Refresh(); - } - - private void OnMasterVisibleColumnsUpdated( EventArgs e ) - { - this.Refresh(); - } - - private void OnDetailVisibleColumnsUpdated( EventArgs e ) - { - this.Refresh(); - } - - #region IWeakEventListener Members - - bool IWeakEventListener.ReceiveWeakEvent( Type managerType, object sender, EventArgs e ) - { - Debug.Assert( sender != null ); - - if( managerType == typeof( CollectionChangedEventManager ) ) - { - if( ( m_masterColumnManager != null ) && ( sender == m_masterColumnManager.Columns ) ) - { - this.OnMasterColumnsCollectionChanged( ( NotifyCollectionChangedEventArgs )e ); - } - else if( ( m_detailColumnManager != null ) && ( sender == m_detailColumnManager.Columns ) ) - { - this.OnDetailColumnsCollectionChanged( ( NotifyCollectionChangedEventArgs )e ); - } - } - else if( managerType == typeof( PropertyChangedEventManager ) ) - { - if( ( m_masterColumnManager != null ) && ( sender == m_masterColumnManager.Columns ) ) - { - this.OnMasterColumnsPropertyChanged( ( PropertyChangedEventArgs )e ); - } - else if( sender == m_detailConfiguration ) - { - this.OnDetailConfigurationPropertyChanged( ( PropertyChangedEventArgs )e ); - } - } - else if( managerType == typeof( ColumnsLayoutChangedEventManager ) ) - { - if( sender == m_masterColumnManager ) - { - this.OnMasterVisibleColumnsUpdated( e ); - } - else if( sender == m_detailColumnManager ) - { - this.OnDetailVisibleColumnsUpdated( e ); - } - } - else if( managerType == typeof( MappingChangedEventManager ) ) - { - if( sender == m_itemPropertyMap ) - { - this.OnItemPropertyMapMappingChanged( e ); - } - } - else if( managerType == typeof( ViewChangedEventManager ) ) - { - if( sender == m_dataGridControl ) - { - this.OnViewChanged(); - } - } - else - { - return false; - } - - return true; - } - - #endregion - - private readonly DetailConfiguration m_detailConfiguration; - private readonly DataGridItemPropertyMap m_itemPropertyMap; - private readonly Dictionary m_pairedColumns = new Dictionary( 0 ); - - private bool m_isUpdatingColumns; - - #region DeferState Private Class - - private sealed class DeferState : DeferredDisposableState - { - internal DeferState( ColumnSynchronizationManager target ) - { - Debug.Assert( target != null ); - m_target = target; - } - - protected override bool IsDeferred - { - get - { - return m_target.IsSynchronizationDeferred; - } - } - - protected override void Increment() - { - m_target.m_deferSynchronizationCount++; - } - - protected override void Decrement() - { - m_target.m_deferSynchronizationCount--; - } - - protected override void OnDeferEnded( bool disposing ) - { - m_target.UpdateColumns(); - } - - private readonly ColumnSynchronizationManager m_target; - } - - #endregion - - #region SynchronizationKey Private Class - - private sealed class SynchronizationKey - { - internal SynchronizationKey( - ColumnBase masterColumn, - ColumnBase detailColumn, - DetailConfiguration detailConfig ) - { - if( detailColumn == null ) - throw new ArgumentNullException( "detailColumn" ); - - if( detailConfig == null ) - throw new ArgumentNullException( "detailConfig" ); - - m_masterColumn = masterColumn; - m_detailColumn = detailColumn; - m_detailConfiguration = detailConfig; - } - - #region MasterColumn Property - - internal ColumnBase MasterColumn - { - get - { - return m_masterColumn; - } - } - - private readonly ColumnBase m_masterColumn; - - #endregion - - #region DetailColumn Property - - internal ColumnBase DetailColumn - { - get - { - return m_detailColumn; - } - } - - private readonly ColumnBase m_detailColumn; - - #endregion - - #region DetailConfiguration Property - - internal DetailConfiguration DetailConfiguration - { - get - { - return m_detailConfiguration; - } - } - - private readonly DetailConfiguration m_detailConfiguration; - - #endregion - - #region OrderKey Property - - internal int OrderKey - { - get - { - var column = this.MasterColumn; - if( column != null ) - return column.VisiblePosition; - - return int.MaxValue; - } - } - - #endregion - - public override int GetHashCode() - { - if( m_masterColumn == null ) - return m_detailColumn.GetHashCode(); - - return ( m_masterColumn.GetHashCode() ) - ^ ( m_detailColumn.GetHashCode() ); - } - - public override bool Equals( object obj ) - { - var key = obj as SynchronizationKey; - if( key == null ) - return false; - - if( key == this ) - return true; - - return ( key.m_masterColumn == m_masterColumn ) - && ( key.m_detailColumn == m_detailColumn ) - && ( key.m_detailConfiguration == m_detailConfiguration ); - } - } - - #endregion - - #region SynchronizationEntry Private Class - - private abstract class SynchronizationEntry - { - protected SynchronizationEntry( ColumnSynchronizationManager owner, SynchronizationKey key ) - { - if( owner == null ) - throw new ArgumentNullException( "owner" ); - - if( key == null ) - throw new ArgumentNullException( "key" ); - - m_owner = owner; - m_key = key; - } - - #region Owner Protected Property - - protected ColumnSynchronizationManager Owner - { - get - { - return m_owner; - } - } - - private readonly ColumnSynchronizationManager m_owner; - - #endregion - - #region MasterColumn Protected Property - - protected ColumnBase MasterColumn - { - get - { - return m_key.MasterColumn; - } - } - - #endregion - - #region DetailColumn Protected Property - - protected ColumnBase DetailColumn - { - get - { - return m_key.DetailColumn; - } - } - - #endregion - - #region DetailConfiguration Protected Property - - protected DetailConfiguration DetailConfiguration - { - get - { - return m_key.DetailConfiguration; - } - } - - #endregion - - #region Key Private Property - - private SynchronizationKey Key - { - get - { - return m_key; - } - } - - private readonly SynchronizationKey m_key; - - #endregion - - public abstract void Synchronize(); - public abstract void Desynchronize(); - } - - #endregion - - #region BoundColumn Private Class - - private sealed class BoundColumn : SynchronizationEntry - { - internal BoundColumn( ColumnSynchronizationManager owner, SynchronizationKey key ) - : base( owner, key ) - { - if( key.MasterColumn == null ) - throw new ArgumentException( "The master column is not set.", "key" ); - } - - public override void Synchronize() - { - var masterColumn = this.MasterColumn; - var detailColumn = this.DetailColumn; - - if( m_localValues == null ) - { - m_localValues = new Dictionary( 8 ); - - masterColumn.PropertyChanged += new PropertyChangedEventHandler( this.OnMasterColumnPropertyChanged ); - masterColumn.FittedWidthRequested += new FittedWidthRequestedEventHandler( this.OnMasterColumnFittedWidthRequested ); - - BoundColumn.StoreLocalValue( m_localValues, detailColumn, ColumnBase.WidthProperty ); - BoundColumn.StoreLocalValue( m_localValues, detailColumn, ColumnBase.MinWidthProperty ); - BoundColumn.StoreLocalValue( m_localValues, detailColumn, ColumnBase.MaxWidthProperty ); - BoundColumn.StoreLocalValue( m_localValues, detailColumn, ColumnBase.DesiredWidthProperty ); - BoundColumn.StoreLocalValue( m_localValues, detailColumn, ColumnBase.VisibleProperty ); - BoundColumn.StoreLocalValue( m_localValues, detailColumn, ColumnReorderingDragSourceManager.AnimatedColumnReorderingTranslationProperty ); - BoundColumn.StoreLocalValue( m_localValues, detailColumn, TableflowView.IsBeingDraggedAnimatedProperty ); - BoundColumn.StoreLocalValue( m_localValues, detailColumn, TableflowView.ColumnReorderingDragSourceManagerProperty ); - } - - BoundColumn.SetValue( masterColumn, detailColumn, ColumnBase.WidthProperty ); - BoundColumn.SetValue( masterColumn, detailColumn, ColumnBase.MinWidthProperty ); - BoundColumn.SetValue( masterColumn, detailColumn, ColumnBase.MaxWidthProperty ); - BoundColumn.SetValue( masterColumn, detailColumn, ColumnBase.DesiredWidthProperty ); - BoundColumn.SetValue( masterColumn, detailColumn, ColumnBase.VisibleProperty ); - BoundColumn.SetValue( masterColumn, detailColumn, ColumnReorderingDragSourceManager.AnimatedColumnReorderingTranslationProperty ); - BoundColumn.SetValue( masterColumn, detailColumn, TableflowView.IsBeingDraggedAnimatedProperty ); - BoundColumn.SetValue( masterColumn, detailColumn, TableflowView.ColumnReorderingDragSourceManagerProperty ); - - this.UpdateTargetPosition(); - } - - public override void Desynchronize() - { - if( m_localValues == null ) - return; - - var localValues = m_localValues; - m_localValues = null; - - var masterColumn = this.MasterColumn; - masterColumn.PropertyChanged -= new PropertyChangedEventHandler( this.OnMasterColumnPropertyChanged ); - masterColumn.FittedWidthRequested -= new FittedWidthRequestedEventHandler( this.OnMasterColumnFittedWidthRequested ); - - var detailColumn = this.DetailColumn; - BoundColumn.RestoreLocalValue( localValues, detailColumn, ColumnBase.WidthProperty ); - BoundColumn.RestoreLocalValue( localValues, detailColumn, ColumnBase.MinWidthProperty ); - BoundColumn.RestoreLocalValue( localValues, detailColumn, ColumnBase.MaxWidthProperty ); - BoundColumn.RestoreLocalValue( localValues, detailColumn, ColumnBase.DesiredWidthProperty ); - BoundColumn.RestoreLocalValue( localValues, detailColumn, ColumnBase.VisibleProperty ); - BoundColumn.RestoreLocalValue( localValues, detailColumn, ColumnReorderingDragSourceManager.AnimatedColumnReorderingTranslationProperty ); - BoundColumn.RestoreLocalValue( localValues, detailColumn, TableflowView.IsBeingDraggedAnimatedProperty ); - BoundColumn.RestoreLocalValue( localValues, detailColumn, TableflowView.ColumnReorderingDragSourceManagerProperty ); - - detailColumn.ClearValue( ColumnBase.VisiblePositionProperty ); - } - - private static void StoreLocalValue( Dictionary store, ColumnBase column, DependencyProperty property ) - { - Debug.Assert( store != null ); - Debug.Assert( column != null ); - Debug.Assert( property != null ); - - var binding = BindingOperations.GetBindingBase( column, property ); - if( binding != null ) - { - store[ property ] = binding; - } - else - { - var value = column.ReadLocalValue( property ); - if( value != DependencyProperty.UnsetValue ) - { - store[ property ] = value; - } - else - { - store.Remove( property ); - } - } - } - - private static void RestoreLocalValue( Dictionary store, ColumnBase column, DependencyProperty property ) - { - Debug.Assert( store != null ); - Debug.Assert( column != null ); - Debug.Assert( property != null ); - - object value; - if( !store.TryGetValue( property, out value ) || ( value == DependencyProperty.UnsetValue ) ) - { - column.ClearValue( property ); - } - else if( value is BindingBase ) - { - BindingOperations.SetBinding( column, property, ( BindingBase )value ); - } - else - { - column.SetValue( property, value ); - } - } - - private static void SetValue( ColumnBase source, ColumnBase destination, DependencyProperty property, string propertyName ) - { - Debug.Assert( property != null ); - - if( string.IsNullOrEmpty( propertyName ) || ( propertyName == property.Name ) ) - { - BoundColumn.SetValue( source, destination, property ); - } - } - - private static void SetValue( ColumnBase source, ColumnBase destination, DependencyProperty property ) - { - Debug.Assert( source != null ); - Debug.Assert( destination != null ); - Debug.Assert( property != null ); - - destination.SetValue( property, source.GetValue( property ) ); - } - - private void UpdateTargetPosition() - { - var detailConfig = this.DetailConfiguration; - var dataGridControl = detailConfig.DataGridControl; - - if( dataGridControl == null ) - return; - - var masterColumn = this.MasterColumn; - var masterColumnManager = DataGridControl.GetDataGridContext( dataGridControl ).ColumnManager; - var masterColumnLocation = masterColumnManager.GetColumnLocationFor( masterColumn ); - - if( masterColumnLocation == null ) - return; - - var detailColumn = this.DetailColumn; - var detailColumnManager = detailConfig.ColumnManager; - var detailColumnLocation = detailColumnManager.GetColumnLocationFor( detailColumn ); - - if( detailColumnLocation == null ) - return; - - var map = detailConfig.ItemPropertyMap; - var previousMasterLocation = masterColumnLocation.GetPreviousSiblingOrCousin(); - Debug.Assert( previousMasterLocation != null ); - - switch( previousMasterLocation.Type ) - { - case LocationType.Start: - case LocationType.Splitter: - { - for( var previousDetailLocation = detailColumnLocation.GetPreviousSiblingOrCousin(); previousDetailLocation != null; previousDetailLocation = previousDetailLocation.GetPreviousSiblingOrCousin() ) - { - // The detail column is at the appropriate location. - if( previousDetailLocation.Type == previousMasterLocation.Type ) - return; - - if( previousDetailLocation.Type != LocationType.Column ) - break; - - ColumnBase unused; - if( DataGridItemPropertyMapHelper.TryGetMasterColumn( map, masterColumnManager.Columns, ( ( ColumnHierarchyManager.IColumnLocation )previousDetailLocation ).Column, out unused ) ) - break; - } - } - break; - - case LocationType.Column: - { - var previousMasterColumn = ( ( ColumnHierarchyManager.IColumnLocation )previousMasterLocation ).Column; - - for( var previousDetailLocation = detailColumnLocation.GetPreviousSiblingOrCousin(); previousDetailLocation != null; previousDetailLocation = previousDetailLocation.GetPreviousSiblingOrCousin() ) - { - if( previousDetailLocation.Type != LocationType.Column ) - break; - - ColumnBase targetMasterColumn; - if( DataGridItemPropertyMapHelper.TryGetMasterColumn( map, masterColumnManager.Columns, ( ( ColumnHierarchyManager.IColumnLocation )previousDetailLocation ).Column, out targetMasterColumn ) ) - { - // The detail column is at the appropriate location. - if( previousMasterColumn == targetMasterColumn ) - return; - } - } - } - break; - - default: - // Unexpected location. - throw new NotSupportedException(); - } - - var nextMasterLocation = masterColumnLocation.GetNextSiblingOrCousin(); - Debug.Assert( nextMasterLocation != null ); - - switch( nextMasterLocation.Type ) - { - case LocationType.Splitter: - case LocationType.Orphan: - { - for( var nextDetailLocation = detailColumnLocation.GetNextSiblingOrCousin(); nextDetailLocation != null; nextDetailLocation = nextDetailLocation.GetNextSiblingOrCousin() ) - { - // The detail column is at the appropriate location. - if( nextDetailLocation.Type == nextMasterLocation.Type ) - return; - - if( nextDetailLocation.Type != LocationType.Column ) - break; - - ColumnBase unused; - if( DataGridItemPropertyMapHelper.TryGetMasterColumn( map, masterColumnManager.Columns, ( ( ColumnHierarchyManager.IColumnLocation )nextDetailLocation ).Column, out unused ) ) - break; - } - } - break; - - case LocationType.Column: - { - var nextMasterColumn = ( ( ColumnHierarchyManager.IColumnLocation )nextMasterLocation ).Column; - - for( var nextDetailLocation = detailColumnLocation.GetNextSiblingOrCousin(); nextDetailLocation != null; nextDetailLocation = nextDetailLocation.GetNextSiblingOrCousin() ) - { - if( nextDetailLocation.Type != LocationType.Column ) - break; - - ColumnBase targetMasterColumn; - if( DataGridItemPropertyMapHelper.TryGetMasterColumn( map, masterColumnManager.Columns, ( ( ColumnHierarchyManager.IColumnLocation )nextDetailLocation ).Column, out targetMasterColumn ) ) - { - // The detail column is at the appropriate location. - if( nextMasterColumn == targetMasterColumn ) - return; - } - } - } - break; - - default: - // Unexpected location. - throw new NotSupportedException(); - } - - // If we get here, it means that the column is really not at the appropriate location. - for( var pivotMasterLocation = previousMasterLocation; pivotMasterLocation != null; pivotMasterLocation = pivotMasterLocation.GetPreviousSiblingOrCousin() ) - { - if( pivotMasterLocation.Type == LocationType.Column ) - { - ColumnBase pivotDetailColumn; - if( !DataGridItemPropertyMapHelper.TryGetDetailColumn( map, detailColumnManager.Columns, ( ( ColumnHierarchyManager.IColumnLocation )pivotMasterLocation ).Column, out pivotDetailColumn ) ) - continue; - - var pivotDetailLocation = ( pivotDetailColumn != null ) ? detailColumnManager.GetColumnLocationFor( pivotDetailColumn ) : null; - if( pivotDetailLocation == null ) - continue; - - Debug.Assert( detailColumnLocation.CanMoveAfter( pivotDetailLocation ) ); - detailColumnLocation.MoveAfter( pivotDetailLocation ); - } - else - { - switch( pivotMasterLocation.Type ) - { - case LocationType.Start: - { - var pivotDetailLocation = detailColumnManager.GetLevelMarkersFor( detailColumnManager.Columns ).Start; - - if( !detailColumnLocation.CanMoveAfter( pivotDetailLocation ) ) - throw new NotSupportedException(); - - detailColumnLocation.MoveAfter( pivotDetailLocation ); - } - break; - - case LocationType.Splitter: - { - var pivotDetailLocation = detailColumnManager.GetLevelMarkersFor( detailColumnManager.Columns ).Splitter; - - if( !detailColumnLocation.CanMoveAfter( pivotDetailLocation ) ) - throw new NotSupportedException(); - - detailColumnLocation.MoveAfter( pivotDetailLocation ); - } - break; - - default: - // Unexpected location. - throw new NotSupportedException(); - } - } - - // The detail column is now at the appropriate location. - return; - } - } - - private void OnMasterColumnPropertyChanged( object sender, PropertyChangedEventArgs e ) - { - var masterColumn = sender as ColumnBase; - if( masterColumn == null ) - return; - - Debug.Assert( masterColumn == this.MasterColumn ); - - var masterColumnManager = this.Owner.MasterColumnManager; - if( ( masterColumnManager == null ) || masterColumnManager.IsUpdateDeferred ) - return; - - var detailColumn = this.DetailColumn; - var propertyName = e.PropertyName; - - BoundColumn.SetValue( masterColumn, detailColumn, ColumnBase.WidthProperty, propertyName ); - BoundColumn.SetValue( masterColumn, detailColumn, ColumnBase.MinWidthProperty, propertyName ); - BoundColumn.SetValue( masterColumn, detailColumn, ColumnBase.MaxWidthProperty, propertyName ); - BoundColumn.SetValue( masterColumn, detailColumn, ColumnBase.DesiredWidthProperty, propertyName ); - BoundColumn.SetValue( masterColumn, detailColumn, ColumnBase.VisibleProperty, propertyName ); - BoundColumn.SetValue( masterColumn, detailColumn, ColumnReorderingDragSourceManager.AnimatedColumnReorderingTranslationProperty, propertyName ); - BoundColumn.SetValue( masterColumn, detailColumn, TableflowView.IsBeingDraggedAnimatedProperty, propertyName ); - BoundColumn.SetValue( masterColumn, detailColumn, TableflowView.ColumnReorderingDragSourceManagerProperty, propertyName ); - } - - private void OnMasterColumnFittedWidthRequested( object sender, FittedWidthRequestedEventArgs e ) - { - Debug.Assert( ( ColumnBase )sender == this.MasterColumn ); - - var fittedWidth = this.DetailColumn.GetFittedWidth(); - if( fittedWidth < 0d ) - return; - - e.SetValue( fittedWidth ); - } - - private Dictionary m_localValues; - } - - #endregion - - #region UnboundColumn Private Class - - private sealed class UnboundColumn : SynchronizationEntry - { - internal UnboundColumn( ColumnSynchronizationManager owner, SynchronizationKey key ) - : base( owner, key ) - { - if( key.MasterColumn != null ) - throw new ArgumentException( "The master column should not be set.", "key" ); - } - - public override void Synchronize() - { - var targetColumn = this.DetailColumn; - var dp = ColumnBase.VisibleProperty; - - var currentBinding = BindingOperations.GetBindingBase( targetColumn, dp ); - if( currentBinding != null ) - { - m_localValue = currentBinding; - BindingOperations.ClearBinding( targetColumn, dp ); - } - else - { - var localValue = targetColumn.ReadLocalValue( dp ); - - // The appropriate value is still in place. - if( object.Equals( localValue, false ) ) - return; - - m_localValue = localValue; - } - - // Hide the column. - targetColumn.SetValue( dp, false ); - } - - public override void Desynchronize() - { - var targetColumn = this.DetailColumn; - var dp = ColumnBase.VisibleProperty; - var oldLocalValue = m_localValue; - - m_localValue = DependencyProperty.UnsetValue; - - if( BindingOperations.GetBindingBase( targetColumn, dp ) != null ) - return; - - if( !object.Equals( targetColumn.ReadLocalValue( dp ), false ) ) - return; - - var oldBinding = oldLocalValue as BindingBase; - if( oldBinding != null ) - { - BindingOperations.SetBinding( targetColumn, dp, oldBinding ); - } - else if( oldLocalValue != DependencyProperty.UnsetValue ) - { - targetColumn.SetValue( dp, oldLocalValue ); - } - else - { - targetColumn.ClearValue( dp ); - } - } - - private object m_localValue = DependencyProperty.UnsetValue; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnWidth.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnWidth.cs deleted file mode 100644 index 07f853e4..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ColumnWidth.cs +++ /dev/null @@ -1,122 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; -using System.Globalization; -using System.Windows; - -using Xceed.Wpf.DataGrid.Converters; - -namespace Xceed.Wpf.DataGrid -{ - [TypeConverter( typeof( ColumnWidthConverter ) )] - public struct ColumnWidth - { - public ColumnWidth( double pixels ) - : this( pixels, ColumnWidthUnitType.Pixel ) - { - } - - public ColumnWidth( double value, ColumnWidthUnitType type ) - { - if( double.IsNaN( value ) ) - throw new ArgumentException( "NaN is not a valid value.", "value" ); - - if( double.IsInfinity( value ) ) - throw new ArgumentException( "Infinity is not a valid value.", "value" ); - - if( ( type != ColumnWidthUnitType.Pixel ) && ( type != ColumnWidthUnitType.Star ) ) - throw new InvalidEnumArgumentException( "type", ( int )type, typeof( ColumnWidthUnitType ) ); - - if( value < 0d ) - throw new ArgumentException( "Negative values are not valid.", "value" ); - - if( ( Xceed.Utils.Math.DoubleUtil.AreClose( value, 0d ) ) && ( type == ColumnWidthUnitType.Star ) ) - throw new ArgumentException( "Zero star (0*) is not a valid value.", "value" ); - - m_unitValue = value; - m_unitType = type; - } - - public double Value - { - get - { - return m_unitValue; - } - } - - public ColumnWidthUnitType UnitType - { - get - { - return m_unitType; - } - } - - public static implicit operator double( ColumnWidth columnWidth ) - { - return ( ( columnWidth.UnitType == ColumnWidthUnitType.Pixel ) ? columnWidth.Value : double.NaN ); - } - - public static implicit operator ColumnWidth( double columnWidth ) - { - return new ColumnWidth( columnWidth, ColumnWidthUnitType.Pixel ); - } - - public static bool operator ==( ColumnWidth columnWidth1, ColumnWidth columnWidth2 ) - { - return - ( ( columnWidth1.UnitType == columnWidth2.UnitType ) && - ( Xceed.Utils.Math.DoubleUtil.AreClose( columnWidth1.Value, columnWidth2.Value ) ) ); - } - - public static bool operator !=( ColumnWidth columnWidth1, ColumnWidth columnWidth2 ) - { - if( columnWidth1.UnitType == columnWidth2.UnitType ) - return !Xceed.Utils.Math.DoubleUtil.AreClose( columnWidth1.Value, columnWidth2.Value ); - - return true; - } - - public override bool Equals( object obj ) - { - if( obj is ColumnWidth ) - return ( this == ( ColumnWidth )obj ); - - return false; - } - - public bool Equals( ColumnWidth columnWidth ) - { - return ( this == columnWidth ); - } - - public override int GetHashCode() - { - return ( Convert.ToInt32( m_unitValue ) + ( int )m_unitType ); - } - - public override string ToString() - { - return ColumnWidthConverter.ToString( this, CultureInfo.InvariantCulture ); - } - - private double m_unitValue; - private ColumnWidthUnitType m_unitType; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ContainerSizeState.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ContainerSizeState.cs deleted file mode 100644 index c5fa02fe..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ContainerSizeState.cs +++ /dev/null @@ -1,102 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal struct ContainerSizeState - { - public ContainerSizeState( FrameworkElement container ) - { - m_width = container.ReadLocalValue( FrameworkElement.WidthProperty ); - m_minWidth = container.ReadLocalValue( FrameworkElement.MinWidthProperty ); - m_maxWidth = container.ReadLocalValue( FrameworkElement.MaxWidthProperty ); - m_height = container.ReadLocalValue( FrameworkElement.HeightProperty ); - m_minHeight = container.ReadLocalValue( FrameworkElement.MinHeightProperty ); - m_maxHeight = container.ReadLocalValue( FrameworkElement.MaxHeightProperty ); - } - - public bool IsEmpty() - { - return ( ( this.Height == DependencyProperty.UnsetValue ) && - ( this.Width == DependencyProperty.UnsetValue ) && - ( this.MinHeight == DependencyProperty.UnsetValue ) && - ( this.MinWidth == DependencyProperty.UnsetValue ) && - ( this.MaxHeight == DependencyProperty.UnsetValue ) && - ( this.MaxWidth == DependencyProperty.UnsetValue ) ); - } - - public object Width - { - get - { - return m_width; - } - } - - public object MinWidth - { - get - { - return m_minWidth; - } - } - - public object MaxWidth - { - get - { - return m_maxWidth; - } - } - - public object Height - { - get - { - return m_height; - } - } - - public object MinHeight - { - get - { - return m_minHeight; - } - } - - public object MaxHeight - { - get - { - return m_maxHeight; - } - } - - private object m_width; - private object m_minWidth; - private object m_maxWidth; - private object m_height; - private object m_minHeight; - private object m_maxHeight; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/ColumnWidthConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/ColumnWidthConverter.cs deleted file mode 100644 index 4cbf812c..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/ColumnWidthConverter.cs +++ /dev/null @@ -1,164 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; -using System.ComponentModel.Design.Serialization; -using System.Globalization; -using System.Windows; - -namespace Xceed.Wpf.DataGrid.Converters -{ - public class ColumnWidthConverter : TypeConverter - { - public override bool CanConvertFrom( ITypeDescriptorContext context, Type sourceType ) - { - switch( Type.GetTypeCode( sourceType ) ) - { - case TypeCode.Int16: - case TypeCode.UInt16: - case TypeCode.Int32: - case TypeCode.UInt32: - case TypeCode.Int64: - case TypeCode.UInt64: - case TypeCode.Single: - case TypeCode.Double: - case TypeCode.Decimal: - case TypeCode.String: - return true; - } - - if( typeof( ColumnWidth ).IsAssignableFrom( sourceType ) ) - return true; - - return false; - } - - public override bool CanConvertTo( ITypeDescriptorContext context, Type destinationType ) - { - return ( destinationType == typeof( string ) ); - } - - public override object ConvertFrom( ITypeDescriptorContext context, CultureInfo culture, object value ) - { - ColumnWidthUnitType unitType; - - if( value == null ) - throw new ArgumentNullException( "value" ); - - if( value is ColumnWidth ) - return value; - - if( value is string ) - return ColumnWidthConverter.FromString( ( string )value, culture ); - - double doubleValue = Convert.ToDouble( value, culture ); - - unitType = ColumnWidthUnitType.Pixel; - - return new ColumnWidth( doubleValue, unitType ); - } - - public override object ConvertTo( ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType ) - { - if( destinationType == null ) - throw new ArgumentNullException( "destinationType" ); - - if( ( value != null ) && ( value is ColumnWidth ) ) - { - ColumnWidth columnWidth = ( ColumnWidth )value; - - if( destinationType == typeof( string ) ) - { - return ColumnWidthConverter.ToString( columnWidth, culture ); - } - - // If we ever want to add InstanceDescriptor in the list of supported destination - // type, we will have to implement it in another method and surround the call - // with a try/catch. Otherwise, the call to Type.GetConstructor() will fail if - // the application does not have reflection permission (typically XBAP). - } - - throw new ArgumentException( "Cannot convert to type " + destinationType.FullName + ".", "value" ); - } - - internal static ColumnWidth FromString( string stringValue, CultureInfo cultureInfo ) - { - stringValue = stringValue.Trim().ToLowerInvariant(); - double value = 0.0; - ColumnWidthUnitType unit = ColumnWidthUnitType.Pixel; - int stringValueLength = stringValue.Length; - int unitStringLength = 0; - double factorValue = 1.0; - int index = 0; - - for( index = 0; index < ColumnWidthConverter.UnitStrings.Length; index++ ) - { - if( stringValue.EndsWith( ColumnWidthConverter.UnitStrings[ index ], StringComparison.Ordinal ) ) - { - unitStringLength = ColumnWidthConverter.UnitStrings[ index ].Length; - unit = ( ColumnWidthUnitType )index; - break; - } - } - - if( index >= ColumnWidthConverter.UnitStrings.Length ) - { - // The unit type was not recognized so far. Search for pixel unit types. - for( index = 0; index < ColumnWidthConverter.PixelUnitStrings.Length; index++ ) - { - if( stringValue.EndsWith( ColumnWidthConverter.PixelUnitStrings[ index ], StringComparison.Ordinal ) ) - { - unitStringLength = ColumnWidthConverter.PixelUnitStrings[ index ].Length; - factorValue = ColumnWidthConverter.PixelUnitFactors[ index ]; - break; - } - } - } - - if( ( stringValueLength == unitStringLength ) && ( unit == ColumnWidthUnitType.Star ) ) - { - // * was specified alone. Use the default value of 1. - value = 1.0; - } - else - { - // Extract the numeric part of the string. - string valuePartString = stringValue.Substring( 0, stringValueLength - unitStringLength ); - value = Convert.ToDouble( valuePartString, cultureInfo ) * factorValue; - } - - return new ColumnWidth( value, unit ); - } - - internal static string ToString( ColumnWidth columnWidth, CultureInfo cultureInfo ) - { - if( columnWidth.UnitType == ColumnWidthUnitType.Star ) - { - if( columnWidth.Value != 1d ) - return ( Convert.ToString( columnWidth.Value, cultureInfo ) + "*" ); - - return "*"; - } - - return Convert.ToString( columnWidth.Value, cultureInfo ); - } - - private static string[] UnitStrings = new string[] { "px", "*" }; - private static string[] PixelUnitStrings = new string[] { "in", "cm", "pt" }; - private static double[] PixelUnitFactors = new double[] { 96.0, 37.795275590551178, 1.3333333333333333 }; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/CurrencyConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/CurrencyConverter.cs deleted file mode 100644 index 15d5cce1..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/CurrencyConverter.cs +++ /dev/null @@ -1,66 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Windows.Data; -using System.Globalization; -using System.Windows; - -namespace Xceed.Wpf.DataGrid.Converters -{ - [ValueConversion( typeof( double ), typeof( string ) )] - public class CurrencyConverter : IValueConverter - { - public object Convert( object value, Type targetType, object parameter, CultureInfo culture ) - { - if( ( value != null ) && ( !object.Equals( string.Empty, value ) ) ) - { - Type valueType = value.GetType(); - - // Only Decimal or Double values can be converted - if( ( valueType.IsAssignableFrom( typeof( decimal ) ) == false ) && ( valueType.IsAssignableFrom( typeof( double ) ) == false ) ) - { - return Binding.DoNothing; - } - - try - { - // Convert the string value provided by an editor to a double before formatting. - double tempDouble = System.Convert.ToDouble( value, CultureInfo.CurrentCulture ); - return string.Format( CultureInfo.CurrentCulture, "{0:C}", tempDouble ); - } - catch - { - return Binding.DoNothing; - } - } - - return string.Format( CultureInfo.CurrentCulture, "{0}", value ); - } - - public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture ) - { - double result; - - if( double.TryParse( value as string, NumberStyles.Currency, CultureInfo.CurrentCulture, out result ) ) - return result; - - return Binding.DoNothing; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/DefaultDataConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/DefaultDataConverter.cs deleted file mode 100644 index c3198de9..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/DefaultDataConverter.cs +++ /dev/null @@ -1,197 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Windows.Data; -using System.Windows; -using System.Globalization; -using System.ComponentModel; -using System.Windows.Controls; -using System.Diagnostics; -using System.Collections; - -namespace Xceed.Wpf.DataGrid.Converters -{ - internal class DefaultDataConverter : IValueConverter - { - public DefaultDataConverter() - { - } - - public object Convert( object sourceValue, Type targetType, object parameter, CultureInfo targetCulture ) - { - Exception exception; - return DefaultDataConverter.TryConvert( sourceValue, targetType, CultureInfo.InvariantCulture, targetCulture, out exception ); - } - - public object ConvertBack( - object targetValue, - Type sourceType, - object parameter, - CultureInfo targetCulture ) - { - Exception exception; - return DefaultDataConverter.TryConvert( targetValue, sourceType, targetCulture, CultureInfo.InvariantCulture, out exception ); - } - - internal static object TryConvert( - object sourceValue, - Type targetType, - CultureInfo sourceCulture, - CultureInfo targetCulture, - out Exception exception ) - { - if( targetCulture == null ) - targetCulture = CultureInfo.CurrentCulture; - - if( sourceCulture == null ) - sourceCulture = CultureInfo.InvariantCulture; - - exception = null; - Type valueType = null; - - try - { - if( sourceValue != null ) - { - valueType = sourceValue.GetType(); - - if( targetType.IsAssignableFrom( valueType ) ) - return sourceValue; - } - else - { - if( !targetType.IsValueType ) - return sourceValue; - } - - if( targetType == typeof( string ) ) - return string.Format( targetCulture, "{0}", sourceValue ); - - if( sourceValue != null ) - { - bool targetTypeIsNullable = false; - Type targetConversionType = targetType; - object resultValue; - - if( ( targetType.IsGenericType ) && ( targetType.GetGenericTypeDefinition() == typeof( Nullable<> ) ) ) - { - targetTypeIsNullable = true; - targetConversionType = targetType.GetGenericArguments()[ 0 ]; - } - - if( DefaultDataConverter.IsConvertibleToAndFrom( valueType, targetConversionType ) ) - { - resultValue = System.Convert.ChangeType( sourceValue, targetConversionType, sourceCulture ); - - if( !targetTypeIsNullable ) - return resultValue; - - sourceValue = resultValue; - } - } - - TypeConverter cachedTypeConverter; - - lock( mg_cachedTypeConverter ) - { - cachedTypeConverter = mg_cachedTypeConverter[ targetType ] as TypeConverter; - - if( cachedTypeConverter == null ) - { - cachedTypeConverter = TypeDescriptor.GetConverter( targetType ); - mg_cachedTypeConverter[ targetType ] = cachedTypeConverter; - } - } - - return cachedTypeConverter.ConvertFrom( null, sourceCulture, sourceValue ); - } - catch( Exception localException ) - { - exception = localException; - return DependencyProperty.UnsetValue; - } - } - - private static bool IsConvertibleToAndFrom( Type sourceType, Type targetType ) - { - if( sourceType == typeof( DateTime ) ) - return ( targetType == typeof( string ) ); - - if( targetType == typeof( DateTime ) ) - return ( sourceType == typeof( string ) ); - - if( sourceType == typeof( char ) ) - return DefaultDataConverter.IsConvertibleFromAndToChar( targetType ); - - if( targetType == typeof( char ) ) - return DefaultDataConverter.IsConvertibleFromAndToChar( sourceType ); - - bool sourceTypeFound = false; - bool targetTypeFound = false; - - for( int i = 0; i < ConvertibleTypes.Length; i++ ) - { - if( ( !sourceTypeFound ) && ( sourceType == ConvertibleTypes[ i ] ) ) - { - if( targetTypeFound ) - return true; - - sourceTypeFound = true; - } - else if( ( !targetTypeFound ) && ( targetType == ConvertibleTypes[ i ] ) ) - { - if( sourceTypeFound ) - return true; - - targetTypeFound = true; - } - } - - return false; - } - - private static bool IsConvertibleFromAndToChar( Type type ) - { - for( int i = 0; i < CharConvertibleTypes.Length; i++ ) - { - if( type == CharConvertibleTypes[ i ] ) - return true; - } - - return false; - } - - private static readonly Type[] ConvertibleTypes = new Type[] - { - typeof(string), typeof(int), typeof(long), - typeof(float), typeof(double), typeof(decimal), - typeof(bool), typeof(byte), typeof(short), - typeof(uint), typeof(ulong), typeof(ushort), typeof(sbyte) - }; - - private static readonly Type[] CharConvertibleTypes = new Type[] - { - typeof(string), typeof(int), typeof(long), - typeof(byte), typeof(short), typeof(uint), - typeof(ulong), typeof(ushort), typeof(sbyte) - }; - - private static Hashtable mg_cachedTypeConverter = new Hashtable(); - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/EmptyStringToBooleanConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/EmptyStringToBooleanConverter.cs deleted file mode 100644 index 65111d45..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/EmptyStringToBooleanConverter.cs +++ /dev/null @@ -1,36 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Globalization; -using System.Windows.Data; - -namespace Xceed.Wpf.DataGrid.Converters -{ - [ValueConversion( typeof( string ), typeof( bool ) )] - public class EmptyStringToBooleanConverter : IValueConverter - { - public object Convert( object value, Type targetType, object parameter, CultureInfo culture ) - { - return string.IsNullOrWhiteSpace( value as string ); - } - - public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture ) - { - return Binding.DoNothing; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/GreaterThanZeroConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/GreaterThanZeroConverter.cs deleted file mode 100644 index 7a4ead6f..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/GreaterThanZeroConverter.cs +++ /dev/null @@ -1,59 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Text; -using System.Windows.Data; -using System.Globalization; -using System.Windows; - -namespace Xceed.Wpf.DataGrid.Converters -{ - [ValueConversion( typeof( object ), typeof( bool ) )] - public class GreaterThanZeroConverter : IValueConverter - { - #region IValueConverter Members - - public object Convert( object value, Type targetType, object parameter, CultureInfo culture ) - { - if( !targetType.IsAssignableFrom( typeof( bool ) ) ) - return DependencyProperty.UnsetValue; - - if( value == null ) - return false; - - double number = 0d; - - try - { - number = System.Convert.ToDouble( value ); - } - catch - { - return false; - } - - return number > 0d; - } - - public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture ) - { - return Binding.DoNothing; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/ImageConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/ImageConverter.cs deleted file mode 100644 index b0e12d71..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/ImageConverter.cs +++ /dev/null @@ -1,110 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Windows.Data; -using System.Windows.Controls; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows; -using System.ComponentModel; - -namespace Xceed.Wpf.DataGrid.Converters -{ - [EditorBrowsable( EditorBrowsableState.Never )] - [ValueConversion( typeof( object ), typeof( ImageSource ) )] - public class ImageConverter : IValueConverter - { - #region IValueConverter Members - - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1800:DoNotCastUnnecessarily" )] - public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) - { - if( !targetType.IsAssignableFrom( typeof( ImageSource ) ) ) - return DependencyProperty.UnsetValue; - - if( ( value == null ) || ( value is ImageSource ) ) - return value; - - ImageSource imageSource = null; - - System.Drawing.Image image = value as System.Drawing.Image; - - if( image != null ) - { - imageSource = ImageConverter.ConvertFromWinFormsImage( image ); - } - else - { - byte[] byteArray = value as byte[]; - - if( byteArray != null ) - { - imageSource = ImageConverter.ConvertFromByteArray( byteArray ); - } - } - - return imageSource; - } - - public object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) - { - return Binding.DoNothing; - } - - #endregion - - #region PRIVATE METHODS - - private static ImageSource ConvertFromWinFormsImage( System.Drawing.Image image ) - { - ImageSource imageSource = null; - - try - { - System.Drawing.ImageConverter imageConverter = new System.Drawing.ImageConverter(); - - byte[] imageBytes = ( byte[] )imageConverter.ConvertTo( image, typeof( byte[] ) ); - - if( imageBytes != null ) - imageSource = ImageConverter.ConvertFromByteArray( imageBytes ); - } - catch {} - - return imageSource; - } - - private static ImageSource ConvertFromByteArray( byte[] imageBytes ) - { - ImageSource imageSource = null; - - try - { - ImageSourceConverter imageSourceConverter = new ImageSourceConverter(); - imageSource = imageSourceConverter.ConvertFrom( imageBytes ) as ImageSource; - } - catch - { - } - - return imageSource; - } - - #endregion PRIVATE METHODS - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/IndexToOddConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/IndexToOddConverter.cs deleted file mode 100644 index 60c0425d..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/IndexToOddConverter.cs +++ /dev/null @@ -1,67 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Globalization; -using System.Windows.Data; -using System.Windows; - -namespace Xceed.Wpf.DataGrid.Converters -{ - [ValueConversion( typeof( int ), typeof( bool ) )] - public class IndexToOddConverter : IValueConverter - { - #region Singleton Property - - public static IndexToOddConverter Singleton - { - get - { - if( mg_singleton == null ) - mg_singleton = new IndexToOddConverter(); - - return mg_singleton; - } - } - - private static IndexToOddConverter mg_singleton; - - #endregion Singleton Property - - #region IValueConverter Members - - public object Convert( object value, Type targetType, object parameter, CultureInfo culture ) - { - if( ( !targetType.IsAssignableFrom( typeof( bool ) ) ) - || ( value == null ) - || ( value.GetType() != typeof( int ) ) ) - { - return DependencyProperty.UnsetValue; - } - - int index = ( int )value; - - return ( ( index % 2 ) == 1 ); - } - - public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture ) - { - return Binding.DoNothing; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/IntAdditionConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/IntAdditionConverter.cs deleted file mode 100644 index c87ab350..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/IntAdditionConverter.cs +++ /dev/null @@ -1,121 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Globalization; -using System.Windows.Data; -using System.Windows; - -namespace Xceed.Wpf.DataGrid.Converters -{ - [ValueConversion( typeof( int ), typeof( int ) )] - public class IntAdditionConverter : IValueConverter - { - #region IValueConverter Members - - public object Convert( - object value, - Type targetType, - object parameter, - CultureInfo culture ) - { - if( ( !targetType.IsAssignableFrom( typeof( int ) ) ) - || ( value == null ) - || ( value.GetType() != typeof( int ) ) - || ( parameter == null ) ) - { - return DependencyProperty.UnsetValue; - } - - int myParameter; - - Type parameterType = parameter.GetType(); - if( parameterType == typeof( int ) ) - { - myParameter = ( int )parameter; - } - else if( parameterType == typeof( string ) ) - { - string stringParameter = ( string )parameter; - try - { - myParameter = int.Parse( stringParameter, CultureInfo.InvariantCulture ); - } - catch - { - return DependencyProperty.UnsetValue; - } - } - else - { - return DependencyProperty.UnsetValue; - } - - int myValue = ( int )value; - - myValue = myValue + myParameter; - - return myValue; - } - - public object ConvertBack( - object value, - Type targetType, - object parameter, - CultureInfo culture ) - { - if( ( targetType != typeof( int ) ) - || ( value == null ) - || ( value.GetType() != typeof( int ) ) - || ( parameter == null ) ) - { - return DependencyProperty.UnsetValue; - } - - int myParameter; - - Type parameterType = parameter.GetType(); - if( parameterType == typeof( int ) ) - { - myParameter = ( int )parameter; - } - else if( parameterType == typeof( string ) ) - { - string stringParameter = ( string )parameter; - try - { - myParameter = int.Parse( stringParameter, CultureInfo.InvariantCulture ); - } - catch - { - return DependencyProperty.UnsetValue; - } - } - else - { - return DependencyProperty.UnsetValue; - } - - int myValue = ( int )value; - - myValue = myValue - myParameter; - - return myValue; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/InverseBooleanConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/InverseBooleanConverter.cs deleted file mode 100644 index 19ecb5e4..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/InverseBooleanConverter.cs +++ /dev/null @@ -1,45 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows.Data; - -namespace Xceed.Wpf.DataGrid.Converters -{ - [ValueConversion( typeof( bool ), typeof( bool ) )] - public class InverseBooleanConverter : IValueConverter - { - #region IValueConverter Members - - public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) - { - if( value is bool ) - return !( bool )value; - - return value; - } - - public object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) - { - if( value is bool ) - return !( bool )value; - - return value; - } - - #endregion IValueConverter Members - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/LevelToOpacityConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/LevelToOpacityConverter.cs deleted file mode 100644 index 7a50af56..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/LevelToOpacityConverter.cs +++ /dev/null @@ -1,136 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Globalization; -using System.Windows.Data; -using System.Windows; - -namespace Xceed.Wpf.DataGrid.Converters -{ - [ValueConversion(typeof(int), typeof(double))] - public class LevelToOpacityConverter : IValueConverter - { - #region IValueConverter Members - - public object Convert( - object value, - Type targetType, - object parameter, - CultureInfo culture ) - { - if( ( value == null ) - || ( value.GetType() != typeof( int ) ) - || ( !targetType.IsAssignableFrom( typeof( double ) ) ) - || ( parameter == null ) ) - { - return DependencyProperty.UnsetValue; - } - - double step; - - Type parameterType = parameter.GetType(); - if( parameterType == typeof( double ) ) - { - step = ( double )parameter; - } - else if( parameterType == typeof( string ) ) - { - string strParam = (string)parameter; - try - { - step = Double.Parse( strParam, CultureInfo.InvariantCulture ); - } - catch - { - return DependencyProperty.UnsetValue; - } - } - else - { - return DependencyProperty.UnsetValue; - } - - int level = ( int )value - 1; - double opacity = 1.0d; - - //subtract 'step' opacity for each level - opacity -= level * step; - - if( opacity < MinOpacity ) - { - opacity = MinOpacity; - } - - if( opacity > 1.0d ) - { - opacity = 1.0d; - } - - return opacity; - - } - - public object ConvertBack( - object value, - Type targetType, - object parameter, - CultureInfo culture ) - { - if( ( value.GetType() != typeof( double ) ) - || ( targetType != typeof( int ) ) - || ( parameter == null ) ) - { - return DependencyProperty.UnsetValue; - } - - double step; - - Type parameterType = parameter.GetType(); - if( parameterType == typeof( double ) ) - { - step = ( double )parameter; - } - else if( parameterType == typeof( string ) ) - { - string strParam = ( string )parameter; - try - { - step = Double.Parse( strParam, CultureInfo.InvariantCulture ); - } - catch - { - return DependencyProperty.UnsetValue; - } - } - else - { - return DependencyProperty.UnsetValue; - } - - double opacity = ( double )value; - int level = 1; - - level += ( int )Math.Ceiling( ( 1.0d - opacity ) / step ); - - return level; - } - - #endregion - - private const double MinOpacity = 0.2d; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/MultimodalResultConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/MultimodalResultConverter.cs deleted file mode 100644 index 4efb2ec7..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/MultimodalResultConverter.cs +++ /dev/null @@ -1,70 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Globalization; -using System.Text; -using System.Windows.Data; -using System.Windows; - -namespace Xceed.Wpf.DataGrid.Converters -{ - [ValueConversion( typeof( object[] ), typeof( string ) )] - public class MultimodalResultConverter : IValueConverter - { - private string m_separator = ", "; - - public string Separator - { - get - { - return m_separator; - } - set - { - m_separator = value; - } - } - - public object Convert( object value, Type targetType, object parameter, CultureInfo culture ) - { - object[] values = value as object[]; - - if( values == null ) - return DependencyProperty.UnsetValue; - - StringBuilder result = new StringBuilder(); - - if( values.Length > 0 ) - { - for( int i = 0; i < values.Length - 1; i++ ) - { - result.Append( values[ i ].ToString() + m_separator ); - } - - result.Append( values[ values.Length - 1 ].ToString() ); - } - - return result.ToString(); - } - - public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture ) - { - // Stat values come from read-only properties. - return Binding.DoNothing; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/NegativeDoubleConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/NegativeDoubleConverter.cs deleted file mode 100644 index dbc8eb5d..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/NegativeDoubleConverter.cs +++ /dev/null @@ -1,57 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Globalization; -using System.Windows.Data; -using System.Windows; - -namespace Xceed.Wpf.DataGrid.Converters -{ - [ValueConversion( typeof( double ), typeof( double ) )] - public class NegativeDoubleConverter : IValueConverter - { - #region IValueConverter Members - - public object Convert( - object value, - Type targetType, - object parameter, - CultureInfo culture ) - { - if( ( value == null ) - || ( value.GetType() != typeof( double ) ) - || ( !targetType.IsAssignableFrom( typeof( double ) ) ) ) - { - return DependencyProperty.UnsetValue; - } - - double doubleValue = ( double )value; - return ( doubleValue * -1d ); - } - - public object ConvertBack( - object value, - Type targetType, - object parameter, - CultureInfo culture ) - { - return this.Convert( value, targetType, parameter, culture ); - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/NullToBooleanConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/NullToBooleanConverter.cs deleted file mode 100644 index ddf9cc58..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/NullToBooleanConverter.cs +++ /dev/null @@ -1,61 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Globalization; -using System.Windows.Data; -using System.Windows; - -namespace Xceed.Wpf.DataGrid.Converters -{ - [ValueConversion( typeof( object ), typeof( bool ) )] - public class NullToBooleanConverter : IValueConverter - { - #region IValueConverter Members - - public object Convert( object value, Type targetType, object parameter, CultureInfo culture ) - { - // If value is null and no parameter is passed to converter, return true by default - bool defaultNullReturnValue = true; - - if( parameter != null ) - { - // Define the bool value to return if a null value is passed to the converter - // this allows a NullToTrue or NullToFalse converter - Boolean.TryParse( parameter.ToString(), out defaultNullReturnValue ); - } - - if( !targetType.IsAssignableFrom( typeof( bool ) ) ) - return DependencyProperty.UnsetValue; - - if( value == null ) - { - return defaultNullReturnValue; - } - else - { - return !defaultNullReturnValue; - } - } - - public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture ) - { - return Binding.DoNothing; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/SortingDirectionToBooleanConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/SortingDirectionToBooleanConverter.cs deleted file mode 100644 index 0d00a3c5..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/SortingDirectionToBooleanConverter.cs +++ /dev/null @@ -1,44 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows.Data; -using System.ComponentModel; - -namespace Xceed.Wpf.DataGrid.Converters -{ - [ EditorBrowsable( EditorBrowsableState.Never ) ] - public class SortingDirectionToBooleanConverter : IValueConverter - { - #region IValueConverter Members - - public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) - { - SortDirection direction = ( SortDirection )value; - return direction != SortDirection.None; - } - - public object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) - { - return Binding.DoNothing; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/SourceDataConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/SourceDataConverter.cs deleted file mode 100644 index 22044920..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/SourceDataConverter.cs +++ /dev/null @@ -1,110 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Windows.Data; -using System.Windows; -using System.Globalization; -using System.ComponentModel; -using System.Windows.Controls; -using System.Diagnostics; - -namespace Xceed.Wpf.DataGrid.Converters -{ - public class SourceDataConverter : IValueConverter - { - public SourceDataConverter() - : this( false, null ) - { - } - - public SourceDataConverter( bool sourceSupportsDBNull ) - : this( sourceSupportsDBNull, null ) - { - } - - internal SourceDataConverter( bool sourceSupportsDBNull, CultureInfo sourceCulture ) - { - m_sourceSupportsDBNull = sourceSupportsDBNull; - m_sourceCulture = sourceCulture; - - if( m_sourceCulture == null ) - m_sourceCulture = CultureInfo.InvariantCulture; - } - - public object Convert( object sourceValue, Type targetType, object parameter, CultureInfo targetCulture ) - { - if( ( sourceValue == DBNull.Value ) || ( sourceValue == null ) ) - return null; - - Exception exception; - return DefaultDataConverter.TryConvert( sourceValue, targetType, CultureInfo.InvariantCulture, targetCulture, out exception ); - } - - public object ConvertBack( - object targetValue, - Type sourceType, - object parameter, - CultureInfo targetCulture ) - { - Exception exception; - return this.TryConvertBack( targetValue, sourceType, m_sourceCulture, targetCulture, out exception ); - } - - internal object TryConvertBack( - object targetValue, - Type sourceType, - CultureInfo sourceCulture, - CultureInfo targetCulture, - out Exception exception ) - { - exception = null; - - if( ( targetValue == null ) || ( targetValue == DBNull.Value ) - || ( ( sourceType != typeof( string ) ) && ( string.Empty.Equals( targetValue ) ) ) ) - { - if( m_sourceSupportsDBNull ) - { - return DBNull.Value; - } - else - { - return null; - } - } - - return DefaultDataConverter.TryConvert( targetValue, sourceType, targetCulture, sourceCulture, out exception ); - } - - public bool SourceSupportsDBNull - { - get - { - return m_sourceSupportsDBNull; - } - - set - { - m_sourceSupportsDBNull = value; - } - } - - bool m_sourceSupportsDBNull; // = false - CultureInfo m_sourceCulture; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/StringFormatConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/StringFormatConverter.cs deleted file mode 100644 index fdfa4f0d..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/StringFormatConverter.cs +++ /dev/null @@ -1,141 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Windows.Data; -using System.Globalization; - -namespace Xceed.Wpf.DataGrid.Converters -{ - [ValueConversion( typeof( object ), typeof( string ) )] - public class StringFormatConverter : IValueConverter - { - #region FormatProvider Property - - private IFormatProvider m_formatProvider; - - public IFormatProvider FormatProvider - { - get - { - return m_formatProvider; - } - set - { - m_formatProvider = value; - } - } - - #endregion FormatProvider Property - - #region IValueConverter Members - - public virtual object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) - { - if( ( value == null ) || ( value is DBNull ) ) - return string.Empty; - - string format = StringFormatConverter.GetFormat( parameter as string ); - - if( format == null ) - { - return value; - } - else - { - if( m_formatProvider == null ) - { - return string.Format( culture, format, value ); - } - else - { - return string.Format( m_formatProvider, format, value ); - } - } - } - - public virtual object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture ) - { - return Binding.DoNothing; - } - - #endregion - - private static string GetFormat( string format ) - { - if( format == null ) - return null; - - int formatLength = format.Length; - StringBuilder workingFormat = new StringBuilder( formatLength ); - char character; - bool previousIsOpenBracket = false; - - for( int i = 0; i < formatLength; i++ ) - { - character = format[ i ]; - - if( character == '[' ) - { - if( previousIsOpenBracket ) - { - workingFormat.Append( '[' ); - previousIsOpenBracket = false; - } - else - { - previousIsOpenBracket = true; - } - } - else if( character == ']' ) - { - if( previousIsOpenBracket ) - { - workingFormat.Append( ']' ); - previousIsOpenBracket = false; - } - else - { - workingFormat.Append( '}' ); - } - } - else - { - if( previousIsOpenBracket ) - { - workingFormat.Append( "{0:" ); - previousIsOpenBracket = false; - } - - workingFormat.Append( character ); - } - } - - string resultingFormat = workingFormat.ToString(); - - if( ( !resultingFormat.Contains( "{0:" ) ) && ( !resultingFormat.Contains( "{0}" ) ) ) - { - workingFormat.Insert( 0, "{0:" ); - workingFormat.Append( '}' ); - resultingFormat = workingFormat.ToString(); - } - - return resultingFormat; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/StringFormatMultiConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/StringFormatMultiConverter.cs deleted file mode 100644 index 288849a7..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/StringFormatMultiConverter.cs +++ /dev/null @@ -1,50 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Globalization; -using System.Windows.Data; - -namespace Xceed.Wpf.DataGrid.Converters -{ - public class StringFormatMultiConverter : IMultiValueConverter - { - public object Convert( object[] values, Type targetType, object parameter, CultureInfo culture ) - { - if( ( values == null ) || ( values.Length <= 0 ) ) - return null; - - var data = values[ 0 ]; - - var format = ( values.Length > 1 ) ? values[ 1 ] as string : null; - if( string.IsNullOrEmpty( format ) ) - return data; - - var currentCulture = ( values.Length > 2 ) ? values[ 2 ] as CultureInfo : null; - if( currentCulture == null ) - { - currentCulture = culture ?? CultureInfo.CurrentCulture; - } - - return string.Format( currentCulture, format, data ); - } - - public object[] ConvertBack( object value, Type[] targetTypes, object parameter, CultureInfo culture ) - { - throw new NotImplementedException(); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/SynchronizedScrollViewerMultiConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/SynchronizedScrollViewerMultiConverter.cs deleted file mode 100644 index ee65aba9..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/SynchronizedScrollViewerMultiConverter.cs +++ /dev/null @@ -1,51 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows.Data; - -namespace Xceed.Wpf.DataGrid.Converters -{ - internal class SynchronizedScrollViewerMultiConverter : IMultiValueConverter - { - #region IMultiValueConverter Members - - public object Convert( object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture ) - { - double largestValue = 0d; - - foreach( double value in values ) - { - if( value > largestValue ) - { - largestValue = value; - } - } - - return largestValue; - } - - public object[] ConvertBack( object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture ) - { - return null; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/ThicknessConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/ThicknessConverter.cs deleted file mode 100644 index b2ad2c19..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/ThicknessConverter.cs +++ /dev/null @@ -1,136 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Globalization; -using System.Windows; -using System.Windows.Data; - -namespace Xceed.Wpf.DataGrid.Converters -{ - [ValueConversion( typeof( double ), typeof( Thickness ) )] - public class ThicknessConverter : IValueConverter - { - private bool m_inverseValue; - - public bool InverseValue - { - get - { - return m_inverseValue; - } - set - { - m_inverseValue = value; - } - } - - - #region IValueConverter Members - - public object Convert( - object value, - Type targetType, - object parameter, - CultureInfo culture ) - { - if( ( !targetType.IsAssignableFrom( typeof( Thickness ) ) ) - || ( value == null ) - || ( value.GetType() != typeof( double ) ) ) - { - return DependencyProperty.UnsetValue; - } - - ThicknessSides sides = ThicknessSides.All; // Defaults to All when no parameter is present; - if(parameter != null) - { - Type parameterType = parameter.GetType(); - if( parameterType == typeof(ThicknessSides) ) - { - sides = ( ThicknessSides )parameter; - } - else if( parameterType == typeof( string ) ) - { - string stringParameter = (string)parameter; - if( !string.IsNullOrEmpty( stringParameter ) ) - { - try - { - sides = ( ThicknessSides )Enum.Parse( typeof( ThicknessSides ), stringParameter ); - } - catch - { - return DependencyProperty.UnsetValue; - } - } - } - else - { - return DependencyProperty.UnsetValue; - } - } - - double doubleValue = ( double )value; - - if( this.InverseValue == true ) - { - doubleValue *= -1; - } - - Thickness thickness = new Thickness(); - - if( IsSideSet( sides, ThicknessSides.Left ) ) - thickness.Left = doubleValue; - - if( IsSideSet( sides, ThicknessSides.Top ) ) - thickness.Top = doubleValue; - - if( IsSideSet( sides, ThicknessSides.Right ) ) - thickness.Right = doubleValue; - - if( IsSideSet( sides, ThicknessSides.Bottom ) ) - thickness.Bottom = doubleValue; - - return thickness; - } - - public object ConvertBack( - object value, - Type targetType, - object parameter, - CultureInfo culture ) - { - return Binding.DoNothing; - } - - #endregion - - private static bool IsSideSet( ThicknessSides sides, ThicknessSides sideToTest ) - { - return ( ( sides & sideToTest ) == sideToTest ); - } - - [Flags] - public enum ThicknessSides - { - Left = 0x01, - Top = 0x02, - Right = 0x04, - Bottom = 0x08, - All = 0x0F - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/TreeViewLineConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/TreeViewLineConverter.cs deleted file mode 100644 index d5db71b8..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/TreeViewLineConverter.cs +++ /dev/null @@ -1,44 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Windows.Data; -using System.Windows.Controls; -using System.ComponentModel; - -namespace Xceed.Wpf.DataGrid.Converters -{ - [EditorBrowsable( EditorBrowsableState.Never )] - public class TreeViewLineConverter : IValueConverter - { - public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) - { - TreeViewItem item = ( TreeViewItem )value; - ItemsControl ic = ItemsControl.ItemsControlFromItemContainer( item ); - - return ic.ItemContainerGenerator.IndexFromContainer( item ) == ic.Items.Count - 1; - } - - public object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) - { - return Binding.DoNothing; - } - } - - -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/TypeToBooleanConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/TypeToBooleanConverter.cs deleted file mode 100644 index f47fd34f..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/TypeToBooleanConverter.cs +++ /dev/null @@ -1,75 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Globalization; -using System.Windows.Data; - - -namespace Xceed.Wpf.DataGrid.Converters -{ - public class TypeToBooleanConverter : IValueConverter - { - #region Singleton Property - - public static TypeToBooleanConverter Singleton - { - get - { - if( mg_singleton == null ) - mg_singleton = new TypeToBooleanConverter(); - - return mg_singleton; - } - } - - private static TypeToBooleanConverter mg_singleton; - - #endregion Singleton Property - - #region IValueConverter Implementation - - public object Convert( object value, Type targetType, object parameter, CultureInfo culture ) - { - if( ( value == null ) || ( parameter == null ) ) - return false; - - Type typeToVerify = (Type)parameter; - - Type valueType = value.GetType(); - - if( typeof(Type).IsAssignableFrom( valueType ) == true ) - { - valueType = (Type) value; - } - - bool retval = typeToVerify.IsAssignableFrom( valueType ); - - return retval; - } - - public object ConvertBack( - object value, - Type targetType, - object parameter, - CultureInfo culture ) - { - return Binding.DoNothing; - } - - #endregion IValueConverter Implementation - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/TypeToVisibilityConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/TypeToVisibilityConverter.cs deleted file mode 100644 index 4ae5b69d..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/TypeToVisibilityConverter.cs +++ /dev/null @@ -1,89 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows.Data; -using System.Windows; - -namespace Xceed.Wpf.DataGrid.Converters -{ - public class TypeToVisibilityConverter : IValueConverter - { - #region Visibility Property - - public Visibility Visibility - { - get - { - return m_visibility; - } - set - { - m_visibility = value; - } - } - - private Visibility m_visibility = Visibility.Visible; - - #endregion - - #region SetVisibilityWhenTrue Property - - public bool SetVisibilityWhenTrue - { - get - { - return m_setVisibilityWhenTrue; - } - set - { - m_setVisibilityWhenTrue = value; - } - } - - private bool m_setVisibilityWhenTrue = false; - - #endregion - - #region IValueConverter Members - - public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) - { - Type toCompareWith = parameter as Type; - - if( ( toCompareWith == null ) - || ( value == null ) ) - { - return DependencyProperty.UnsetValue; - } - - if( toCompareWith.IsAssignableFrom( value.GetType() ) == m_setVisibilityWhenTrue ) - return m_visibility; - - return DependencyProperty.UnsetValue; - } - - public object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) - { - return Binding.DoNothing; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/ValueToMaskedTextConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/ValueToMaskedTextConverter.cs deleted file mode 100644 index 675ac832..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Converters/ValueToMaskedTextConverter.cs +++ /dev/null @@ -1,112 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Globalization; -using System.Windows; -using System.Windows.Data; -using System.ComponentModel; -using System.Reflection; -using Xceed.Wpf.Toolkit; - -namespace Xceed.Wpf.DataGrid.Converters -{ - public class ValueToMaskedTextConverter : IValueConverter - { - #region IValueConverter Members - - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1800:DoNotCastUnnecessarily" )] - public object Convert( object value, Type targetType, object parameter, CultureInfo culture ) - { - if( !targetType.IsAssignableFrom( typeof( string ) ) ) - return DependencyProperty.UnsetValue; - - string workingText = ( value == null ) ? string.Empty : value.ToString(); - - string mask = null; // Defaults to no mask when no parameter is specified. - - if( parameter != null ) - { - Type parameterType = parameter.GetType(); - if( parameterType == typeof( string ) ) - { - string stringParameter = ( string )parameter; - - if( !string.IsNullOrEmpty( stringParameter ) ) - mask = stringParameter; - } - else - { - return DependencyProperty.UnsetValue; - } - } - - if( !string.IsNullOrEmpty( mask ) ) - { - try - { - string rawText = string.Empty; - - CultureInfo currentCulture = CultureInfo.CurrentCulture; - - if( value != null ) - { - try - { - Type valueDataType = value.GetType(); - - MethodInfo valueToStringMethodInfo = - valueDataType.GetMethod( "ToString", new Type[] { typeof( string ), typeof( IFormatProvider ) } ); - - string formatSpecifier = MaskedTextBox.GetFormatSpecifierFromMask( mask, currentCulture ); - - if( valueToStringMethodInfo != null ) - { - rawText = ( string )valueToStringMethodInfo.Invoke( value, new object[] { formatSpecifier, currentCulture } ); - } - else - { - rawText = value.ToString(); - } - } - catch - { - rawText = value.ToString(); - } - } - - MaskedTextProvider maskedTextProvider = new MaskedTextProvider( mask, currentCulture ); - - maskedTextProvider.Set( rawText ); - - return maskedTextProvider.ToString( false, true ); - } - catch - { - } - } - - return value.ToString(); - } - - public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture ) - { - return Binding.DoNothing; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CurrencyManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CurrencyManager.cs deleted file mode 100644 index ea7925d2..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/CurrencyManager.cs +++ /dev/null @@ -1,298 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics; -using System.Linq; -using System.Windows; -using System.Windows.Data; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class CurrencyManager : IWeakEventListener - { - internal CurrencyManager( DataGridContext dataGridContext, CollectionView collectionView ) - { - if( dataGridContext == null ) - throw new ArgumentNullException( "dataGridContext" ); - - if( collectionView == null ) - throw new ArgumentNullException( "collectionView" ); - - m_dataGridContext = dataGridContext; - m_collectionView = collectionView; - - Debug.Assert( m_dataGridContext.CurrentItem == m_collectionView.CurrentItem ); - - this.RegisterListeners(); - } - - #region IsSetCurrentInProgress Private Property - - private bool IsSetCurrentInProgress - { - get - { - return m_dataGridContext.DataGridControl.IsSetCurrentInProgress; - } - } - - #endregion - - #region ShouldSynchronizeCurrentItem Private Property - - private bool ShouldSynchronizeCurrentItem - { - get - { - return m_dataGridContext.DataGridControl.ShouldSynchronizeCurrentItem; - } - } - - #endregion - - #region ShouldSynchronizeSelectionWithCurrent Private Property - - private bool ShouldSynchronizeSelectionWithCurrent - { - get - { - // #case 158670 - // When using DataGridVirtualizingCollectionViewBase, the synchronization between - // currentItem and Selection will only be done if currentItem is modified in code-behind. - var dgvcvb = m_collectionView.SourceCollection as DataGridVirtualizingCollectionViewBase; - if( ( dgvcvb != null ) && !dgvcvb.CanSynchronizeSelectionWithCurrent ) - return false; - - return m_dataGridContext.DataGridControl.SynchronizeSelectionWithCurrent; - } - } - - #endregion - - internal void CleanManager() - { - this.UnregisterListeners(); - } - - private void ChangeCollectionViewCurrentItem() - { - if( m_isCurrentChanging || !this.ShouldSynchronizeCurrentItem ) - return; - - m_isCurrentChanging = true; - - try - { - // Synchronize the CurrentItem of the CollecitonView with the one of the DataGridContext. - m_collectionView.MoveCurrentToPosition( m_dataGridContext.CurrentItemIndex ); - } - finally - { - m_isCurrentChanging = false; - } - } - - private void ChangeDataGridContextCurrentItem() - { - // Prevent when a SetCurrent is in progress - if( this.IsSetCurrentInProgress ) - return; - - if( m_isCurrentChanging || !this.ShouldSynchronizeCurrentItem ) - return; - - m_isCurrentChanging = true; - - try - { - // Synchronize the CurrentItem of the DataGridContext - // with the one of the CollecitonView. - m_dataGridContext.SetCurrent( - m_collectionView.CurrentItem, - null, - m_collectionView.CurrentPosition, - m_dataGridContext.CurrentColumn, - false, - false, - this.ShouldSynchronizeSelectionWithCurrent, - AutoScrollCurrentItemSourceTriggers.CollectionViewCurrentItemChanged ); - - if( m_collectionView.CurrentItem == null ) - { - this.ChangeCurrentDataGridContext(); - } - } - catch( DataGridException ) - { - // When we deleted an item in edit that contain invalid data, we don't want a throw to go all the way up to the end user. - // We try to abort the edit in that case. - - if( ( m_dataGridContext.IsCurrent ) && ( m_dataGridContext.DataGridControl.IsBeingEdited ) && ( !m_dataGridContext.Items.Contains( m_dataGridContext.CurrentItem ) ) ) - { - m_dataGridContext.CancelEdit(); - - m_dataGridContext.SetCurrent( - m_collectionView.CurrentItem, - null, - m_collectionView.CurrentPosition, - m_dataGridContext.CurrentColumn, - false, - false, - this.ShouldSynchronizeSelectionWithCurrent, - AutoScrollCurrentItemSourceTriggers.CollectionViewCurrentItemChanged ); - - if( m_collectionView.CurrentItem == null ) - { - this.ChangeCurrentDataGridContext(); - } - } - } - finally - { - m_isCurrentChanging = false; - } - } - - private void ChangeCurrentDataGridContext() - { - var parentDataGridContext = m_dataGridContext.ParentDataGridContext; - var parentItem = m_dataGridContext.ParentItem; - - if( ( parentDataGridContext == null ) || ( parentItem == null ) ) - return; - - var childContexts = CurrencyManager.GetChildContexts( parentDataGridContext, parentItem ).ToList(); - - if( childContexts.Count > 1 ) - { - var currentContextIndex = childContexts.IndexOf( m_dataGridContext ); - int lookForwardFrom; - int lookBackwardFrom; - - if( currentContextIndex < 0 ) - { - lookForwardFrom = 0; - lookBackwardFrom = -1; - } - else - { - lookForwardFrom = currentContextIndex + 1; - lookBackwardFrom = currentContextIndex - 1; - } - - for( int i = lookForwardFrom; i < childContexts.Count; i++ ) - { - var childContext = childContexts[ i ]; - if( childContext.Items.Count <= 0 ) - continue; - - childContext.SetCurrentItemCore( childContext.Items.GetItemAt( 0 ), false, this.ShouldSynchronizeSelectionWithCurrent, AutoScrollCurrentItemSourceTriggers.CollectionViewCurrentItemChanged ); - return; - } - - for( int i = lookBackwardFrom; i >= 0; i-- ) - { - var childContext = childContexts[ i ]; - - var itemsCount = childContext.Items.Count; - if( itemsCount <= 0 ) - continue; - - childContext.SetCurrentItemCore( childContext.Items.GetItemAt( itemsCount - 1 ), false, this.ShouldSynchronizeSelectionWithCurrent, AutoScrollCurrentItemSourceTriggers.CollectionViewCurrentItemChanged ); - return; - } - } - - // No context after or before us have been found, we will set the CurrentItem to our ParentItem. - parentDataGridContext.SetCurrentItemCore( parentItem, false, this.ShouldSynchronizeSelectionWithCurrent, AutoScrollCurrentItemSourceTriggers.CollectionViewCurrentItemChanged ); - } - - private void RegisterListeners() - { - // We are not checking this.ShouldSynchronizeCurrentItem since it might return the wrong value if the grid - // is still in the process of being instantiated. - CurrentItemChangedEventManager.AddListener( m_dataGridContext, this ); - CurrentChangedEventManager.AddListener( m_collectionView, this ); - } - - private void UnregisterListeners() - { - // We are not checking this.ShouldSynchronizeCurrentItem since it might have returned the wrong value - // when RegisterListeners was called if the grid was still in the process of being instantiated. - CurrentItemChangedEventManager.RemoveListener( m_dataGridContext, this ); - CurrentChangedEventManager.RemoveListener( m_collectionView, this ); - } - - private static IEnumerable GetChildContexts( DataGridContext dataGridContext, object item ) - { - Debug.Assert( dataGridContext != null ); - Debug.Assert( item != null ); - - return ( from detailConfig in dataGridContext.DetailConfigurations - let childContext = dataGridContext.GetChildContext( item, detailConfig ) - where ( childContext != null ) - select childContext ); - } - - private void OnDataGridContextCurrentItemChanged( object sender, EventArgs e ) - { - Debug.Assert( sender == m_dataGridContext ); - - this.ChangeCollectionViewCurrentItem(); - } - - private void OnCollectionViewCurrentChanged( object sender, EventArgs e ) - { - Debug.Assert( sender == m_collectionView ); - - this.ChangeDataGridContextCurrentItem(); - } - - #region IWeakEventListener Members - - bool IWeakEventListener.ReceiveWeakEvent( Type managerType, object sender, EventArgs e ) - { - return this.OnReceiveWeakEvent( managerType, sender, e ); - } - - private bool OnReceiveWeakEvent( Type managerType, object sender, EventArgs e ) - { - if( managerType == typeof( CurrentItemChangedEventManager ) ) - { - this.OnDataGridContextCurrentItemChanged( sender, e ); - } - else if( managerType == typeof( CurrentChangedEventManager ) ) - { - this.OnCollectionViewCurrentChanged( sender, e ); - } - else - { - return false; - } - - return true; - } - - #endregion - - private readonly DataGridContext m_dataGridContext; - private readonly CollectionView m_collectionView; - private bool m_isCurrentChanging; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataCell.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataCell.cs deleted file mode 100644 index 6d83fceb..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataCell.cs +++ /dev/null @@ -1,282 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; -using System.Diagnostics; -using System.Windows; -using System.Windows.Automation.Peers; -using System.Windows.Data; -using System.Windows.Input; -using System.Xml; - -namespace Xceed.Wpf.DataGrid -{ - public class DataCell : Cell - { - static DataCell() - { - } - - public DataCell() - { - } - - public DataCell( string fieldName, object content ) - { - this.FieldName = fieldName; - this.Content = content; - } - - #region CanBeRecycled Property - - protected internal override bool CanBeRecycled - { - get - { - return ( m_canBeRecycled ) - && ( base.CanBeRecycled ); - } - } - - private bool m_canBeRecycled; //= false - - #endregion - - #region OverrideColumnCellContentTemplate Property - - protected override bool OverrideColumnCellContentTemplate - { - get - { - return false; - } - } - - #endregion - - - protected override void OnMouseEnter( MouseEventArgs e ) - { - //If the current CellEditorDisplayConditions requires display when mouse is over the Cell - if( Cell.IsCellEditorDisplayConditionsSet( this, CellEditorDisplayConditions.MouseOverCell ) ) - { - //Display the editors for the Row - this.SetDisplayEditorMatchingCondition( CellEditorDisplayConditions.MouseOverCell ); - } - - base.OnMouseEnter( e ); - } - - protected override void OnMouseLeave( MouseEventArgs e ) - { - //If the current CellEditorDisplayConditions requires display when mouse is over the Cell - if( Cell.IsCellEditorDisplayConditionsSet( this, CellEditorDisplayConditions.MouseOverCell ) ) - { - //Display the editors for the Row - this.RemoveDisplayEditorMatchingCondition( CellEditorDisplayConditions.MouseOverCell ); - } - - base.OnMouseLeave( e ); - } - - protected override void InitializeCore( DataGridContext dataGridContext, Row parentRow, ColumnBase parentColumn ) - { - ColumnBase oldParentColumn = this.ParentColumn; - - base.InitializeCore( dataGridContext, parentRow, parentColumn ); - - // - // For an unknown reason, when a recycled DataCell was added back to the VisualTree (added - // to the CellsHostPanel in its ParentRow), the binding would fail to update when the XPath - // expression contained a namespace prefix, even if the XmlNamespaceManager property is inherited - // and querying for the value of this property after adding the DataCell to the VTree would return - // a valid, non-null XmlNamespaceManager. - // - // Forcing a local value for the XmlNamespaceManager property solves this problem, but it is - // not the best thing to do as we are effectively bypassing the inheritance behavior for this - // property... - this.SetValue( Binding.XmlNamespaceManagerProperty, dataGridContext.DataGridControl.GetValue( Binding.XmlNamespaceManagerProperty ) ); - - //prevent the setup of the display member binding more than once on the same column! - if( ( !this.IsInternalyInitialized ) || ( oldParentColumn != parentColumn ) ) - { - //call the helper function to setup the Cell's binding. - this.SetupDisplayMemberBinding( dataGridContext ); - } - } - - protected internal override void PrepareContainer( DataGridContext dataGridContext, object item ) - { - base.PrepareContainer( dataGridContext, item ); - - if( dataGridContext.SelectedCellsStore.Contains( DataGridVirtualizingPanel.GetItemIndex( this.ParentRow ), this.ParentColumn.VisiblePosition ) ) - { - this.SetIsSelected( true ); - } - } - - protected internal override void PrepareDefaultStyleKey( Xceed.Wpf.DataGrid.Views.ViewBase view ) - { - var newThemeKey = view.GetDefaultStyleKey( typeof( DataCell ) ); - if( object.Equals( this.DefaultStyleKey, newThemeKey ) ) - return; - - this.DefaultStyleKey = newThemeKey; - } - - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters" )] - [EditorBrowsable( EditorBrowsableState.Never )] - protected internal virtual void SetupDisplayMemberBinding( DataGridContext dataGridContext ) - { - // Bind the cell content. - var column = this.ParentColumn as Column; - - if( column != null ) - { - var displayMemberBinding = default( BindingBase ); - var dataItem = this.ParentRow.DataContext; - - // If the dataContext is our ParentRow, we do not create any binding - if( dataItem != this.ParentRow ) - { - displayMemberBinding = column.GetDisplayMemberBinding(); - - if( displayMemberBinding == null ) - { - if( dataGridContext == null ) - throw new InvalidOperationException( "An attempt was made to create a DisplayMemberBinding before the DataGridContext has been initialized." ); - - if( !DesignerProperties.GetIsInDesignMode( this ) ) - { - var propertyDescription = ItemsSourceHelper.CreateOrGetPropertyDescriptionFromColumn( dataGridContext, column, ( dataItem != null ) ? dataItem.GetType() : null ); - ItemsSourceHelper.UpdateColumnFromPropertyDescription( column, dataGridContext.DataGridControl.DefaultCellEditors, dataGridContext.AutoCreateForeignKeyConfigurations, propertyDescription ); - - displayMemberBinding = column.GetDisplayMemberBinding(); - } - - column.IsBindingAutoCreated = true; - } - } - - if( displayMemberBinding != null ) - { - m_canBeRecycled = DataCell.VerifyDisplayMemberBinding( displayMemberBinding ); - - BindingOperations.SetBinding( this, Cell.ContentProperty, displayMemberBinding ); - - var xmlElement = this.GetValue( Cell.ContentProperty ) as XmlElement; - if( xmlElement != null ) - { - - - // Convert binding to an InnerXML binding in the case we are bound on a XmlElement - // to be able to refresh the data in the XML. - - //under any circumstances, a cell that is bound to XML cannot be recycled - m_canBeRecycled = false; - - this.ClearDisplayMemberBinding(); - - var xmlElementBinding = new Binding( "InnerXml" ); - xmlElementBinding.Source = xmlElement; - xmlElementBinding.Mode = BindingMode.TwoWay; - xmlElementBinding.UpdateSourceTrigger = UpdateSourceTrigger.Explicit; - - BindingOperations.SetBinding( this, Cell.ContentProperty, xmlElementBinding ); - } - } - else - { - this.ClearDisplayMemberBinding(); - } - } - else - { - this.ClearDisplayMemberBinding(); - } - } - - internal virtual void ClearDisplayMemberBinding() - { - if( BindingOperations.IsDataBound( this, Cell.ContentProperty ) ) - { - BindingOperations.ClearBinding( this, Cell.ContentProperty ); - } - else - { - this.ClearValue( Cell.ContentProperty ); - } - } - - internal override void ContentCommitted() - { - base.ContentCommitted(); - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - DataRow parentRow = this.ParentRow as DataRow; - - if( ( dataGridContext != null ) && ( parentRow != null ) ) - parentRow.EnsurePosition( dataGridContext, this ); - } - - internal override DataTemplate GetForeignKeyDataTemplate() - { - var column = this.ParentColumn as Column; - if( column == null ) - return null; - - // If a foreignKey CellContentTemplate was found by the configuration, it must be used even if a CellContentTemplate is defined - // because the CellContentTemplate will be used by this template - var configuration = column.ForeignKeyConfiguration; - if( configuration == null ) - return null; - - return configuration.DefaultCellContentTemplate; - } - - internal override DataTemplate GetCellStringFormatDataTemplate( DataTemplate contentTemplate ) - { - // parentColumn is verified to be not null in the calling method - var parentColumn = this.ParentColumn; - - var format = parentColumn.CellContentStringFormat; - Debug.Assert( !string.IsNullOrEmpty( format ) ); - - return StringFormatDataTemplate.Get( contentTemplate, format, parentColumn.GetCulture() ); - } - - private static bool VerifyDisplayMemberBinding( BindingBase binding ) - { - bool retval = false; - //a DataCell can only be recycled if the DisplayMemberBinding is of type Binding - //and have no source, relativesource, elementname - - Binding displayMemberBinding = binding as Binding; - - if( displayMemberBinding != null ) - { - if( ( ( displayMemberBinding.Source == null ) || ( displayMemberBinding.Source == DependencyProperty.UnsetValue ) ) - && ( ( displayMemberBinding.RelativeSource == null ) || ( displayMemberBinding.Source == DependencyProperty.UnsetValue ) ) - && ( string.IsNullOrEmpty( displayMemberBinding.ElementName ) == true ) ) - { - retval = true; - } - } - - return retval; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridBindingInfo.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridBindingInfo.cs deleted file mode 100644 index becf2ff1..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridBindingInfo.cs +++ /dev/null @@ -1,279 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows.Data; -using System.Globalization; -using System.Windows; -using System.Windows.Controls; -using System.Collections.ObjectModel; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Diagnostics; - -namespace Xceed.Wpf.DataGrid -{ - public class DataGridBindingInfo - { - public DataGridBindingInfo() - { - m_binding = new Binding(); - - m_binding.Mode = BindingMode.TwoWay; - m_binding.UpdateSourceTrigger = UpdateSourceTrigger.Explicit; - m_binding.ConverterCulture = CultureInfo.CurrentCulture; - - m_binding.ValidatesOnDataErrors = true; - m_binding.ValidatesOnExceptions = true; - - m_binding.NotifyOnTargetUpdated = true; - m_binding.NotifyOnValidationError = true; - } - - #region BindsDirectlyToSource Property - - public bool BindsDirectlyToSource - { - get - { - return m_binding.BindsDirectlyToSource; - } - - set - { - m_binding.BindsDirectlyToSource = value; - } - } - - #endregion BindsDirectlyToSource Property - - #region Converter Property - - public IValueConverter Converter - { - get - { - return m_binding.Converter; - } - - set - { - m_binding.Converter = value; - } - } - - #endregion Converter Property - - #region ConverterCulture Property - - public CultureInfo ConverterCulture - { - get - { - return m_binding.ConverterCulture; - } - - set - { - m_binding.ConverterCulture = value; - } - } - - #endregion ConverterCulture Property - - #region ConverterParameter Property - - public object ConverterParameter - { - get - { - return m_binding.ConverterParameter; - } - - set - { - m_binding.ConverterParameter = value; - } - } - - #endregion ConverterParameter Property - - #region ElementName Property - - public string ElementName - { - get - { - return m_binding.ElementName; - } - - set - { - m_binding.ElementName = value; - } - } - - #endregion ElementName Property - - #region FallbackValue Property - - public object FallbackValue - { - get - { - return m_binding.FallbackValue; - } - - set - { - m_binding.FallbackValue = value; - } - } - - #endregion FallbackValue Property - - #region IsAsync Property - - public bool IsAsync - { - get - { - return m_binding.IsAsync; - } - - set - { - m_binding.IsAsync = value; - } - } - - #endregion IsAsync Property - - #region NotifyOnSourceUpdated Property - - public bool NotifyOnSourceUpdated - { - get - { - return m_binding.NotifyOnSourceUpdated; - } - - set - { - m_binding.NotifyOnSourceUpdated = value; - } - } - - #endregion NotifyOnSourceUpdated Property - - #region Path Property - - public PropertyPath Path - { - get - { - return m_binding.Path; - } - - set - { - m_binding.Path = value; - } - } - - #endregion Path Property - - #region ReadOnly Property - - public bool ReadOnly - { - get - { - return ( m_binding.Mode == BindingMode.OneWay ); - } - - set - { - if( value ) - { - m_binding.Mode = BindingMode.OneWay; - } - else - { - m_binding.Mode = BindingMode.TwoWay; - } - } - } - - #endregion ReadOnly Property - - #region UpdateSourceExceptionFilter Property - - public UpdateSourceExceptionFilterCallback UpdateSourceExceptionFilter - { - get - { - return m_binding.UpdateSourceExceptionFilter; - } - - set - { - m_binding.UpdateSourceExceptionFilter = value; - } - } - - #endregion UpdateSourceExceptionFilter Property - - #region ValidationRules Property - - public Collection ValidationRules - { - get - { - return m_binding.ValidationRules; - } - } - - #endregion ValidationRules Property - - #region XPath Property - - public string XPath - { - get - { - return m_binding.XPath; - } - - set - { - m_binding.XPath = value; - } - } - - #endregion Path Property - - internal Binding GetBinding() - { - return m_binding; - } - - private Binding m_binding; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridCommands.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridCommands.cs deleted file mode 100644 index 59b1d6b0..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridCommands.cs +++ /dev/null @@ -1,75 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows.Input; - -namespace Xceed.Wpf.DataGrid -{ - public static class DataGridCommands - { - static DataGridCommands() - { - DataGridCommands.BeginEdit.InputGestures.Add( new KeyGesture( Key.F2, ModifierKeys.None ) ); - DataGridCommands.EndEdit.InputGestures.Add( new KeyGesture( Key.Enter, ModifierKeys.None ) ); - DataGridCommands.CancelEdit.InputGestures.Add( new KeyGesture( Key.Escape, ModifierKeys.None ) ); - - DataGridCommands.Refresh.InputGestures.Add( new KeyGesture( Key.F5, ModifierKeys.None ) ); - - DataGridCommands.ApplyFilter.InputGestures.Add( new KeyGesture( Key.Enter, ModifierKeys.None ) ); - } - - public static readonly RoutedCommand ExpandGroup = - new RoutedCommand( "ExpandGroup", typeof( DataGridCommands ) ); - - public static readonly RoutedCommand CollapseGroup = - new RoutedCommand( "CollapseGroup", typeof( DataGridCommands ) ); - - public static readonly RoutedCommand ToggleGroupExpansion = - new RoutedCommand( "ToggleGroupExpansion", typeof( DataGridCommands ) ); - - public static readonly RoutedCommand ExpandDetails = - new RoutedCommand( "ExpandDetails", typeof( DataGridCommands ) ); - - public static readonly RoutedCommand CollapseDetails = - new RoutedCommand( "CollapseDetails", typeof( DataGridCommands ) ); - - public static readonly RoutedCommand ToggleDetailExpansion = - new RoutedCommand( "ToggleDetailExpansion", typeof( DataGridCommands ) ); - - public static readonly RoutedCommand BeginEdit = - new RoutedCommand( "BeginEdit", typeof( DataGridCommands ) ); - - public static readonly RoutedCommand EndEdit = - new RoutedCommand( "EndEdit", typeof( DataGridCommands ) ); - - public static readonly RoutedCommand CancelEdit = - new RoutedCommand( "CancelEdit", typeof( DataGridCommands ) ); - - [ Obsolete( "This command is obsolete and should no longer be used." ) ] - public static readonly RoutedCommand SelectRow = - new RoutedCommand( "SelectRow", typeof( DataGridCommands ) ); - - public static readonly RoutedCommand Refresh = - new RoutedCommand( "Refresh", typeof( DataGridCommands ) ); - - public static readonly RoutedCommand ApplyFilter = - new RoutedCommand( "ApplyFilter", typeof( DataGridCommands ) ); - - public static readonly RoutedCommand ClearFilter = - new RoutedCommand( "ClearFilter", typeof( DataGridCommands ) ); - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridContext.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridContext.cs deleted file mode 100644 index ab48b471..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridContext.cs +++ /dev/null @@ -1,4319 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Diagnostics; -using System.Globalization; -using System.Linq; -using System.Threading; -using System.Windows; -using System.Windows.Automation.Peers; -using System.Windows.Controls; -using System.Windows.Controls.Primitives; -using System.Windows.Data; -using System.Windows.Media; -using Xceed.Utils.Collections; -using Xceed.Wpf.DataGrid.Views; - -namespace Xceed.Wpf.DataGrid -{ - public sealed class DataGridContext : DependencyObject, INotifyPropertyChanged, IWeakEventListener, IDataGridContextVisitable, ICustomTypeDescriptor - { - internal DataGridContext( - DataGridContext parentDataGridContext, - DataGridControl dataGridControl, - object parentItem, - CollectionView collectionView, - DetailConfiguration detailConfiguration ) - { - if( dataGridControl == null ) - throw new ArgumentNullException( "dataGridControl" ); - - if( collectionView == null ) - throw new ArgumentNullException( "collectionView" ); - - // ParentItem cannot be null except when dealing with the root DataGridContext. - if( ( parentDataGridContext != null ) && ( parentItem == null ) ) - throw new ArgumentNullException( "parentItem" ); - - m_parentDataGridContext = parentDataGridContext; //voluntarily not validating if not null... this will be null for master level. - m_dataGridControl = dataGridControl; - m_dataGridControlItemsSource = m_dataGridControl.ItemsSource; - m_parentItem = parentItem; - m_items = collectionView; - m_detailConfig = detailConfiguration; //voluntarily not validating if not null... this will be null for master level. - - m_currencyManager = new CurrencyManager( this, m_items ); - - m_selectedItemsStore = new SelectedItemsStorage( this ); - m_selectedCellsStore = new SelectedCellsStorage( this ); - m_selectedItemsRanges = new SelectionItemRangeCollection( m_selectedItemsStore ); - m_selectedCellRanges = new SelectionCellRangeCollection( m_selectedCellsStore ); - m_selectedItems = new SelectionItemCollection( m_selectedItemsStore ); - - CollectionChangedEventManager.AddListener( m_items, this ); - - var dataGridCollectionViewBase = m_items as DataGridCollectionViewBase; - if( dataGridCollectionViewBase != null ) - { - PreBatchCollectionChangedEventManager.AddListener( dataGridCollectionViewBase, this ); - PostBatchCollectionChangedEventManager.AddListener( dataGridCollectionViewBase, this ); - } - - //if this is a DataGridCollectionView - var dataGridCollectionView = m_items as DataGridCollectionView; - if( dataGridCollectionView != null ) - { - //Set its dataGridContext so it can propagate a DeferRefresh to details' DataGridCollectionView's - dataGridCollectionView.PrepareRootContextForDeferRefresh( this ); - } - - //If the detailConfiguration is null then we are in the master... - if( m_detailConfig == null ) - { - var columns = new ColumnCollection( dataGridControl, null ); - - m_columnManager = new ColumnHierarchyManager( columns ); - m_itemsSourcePropertyDescriptions = dataGridControl.ItemsSourcePropertyDescriptions; - m_itemPropertyMap = dataGridControl.ItemPropertyMap; - m_groupLevelDescriptions = new GroupLevelDescriptionCollection(); - - //in this particular case, I need to create a SortDescriptionsSyncContext to ensure I will be able to synchronize access to the sort descriptions collection. - m_sortDescriptionsSyncContext = new SortDescriptionsSyncContext(); - - //Register to the Columns Collection's CollectionChanged event to manage the Removal of the CurrentColumn. - CollectionChangedEventManager.AddListener( m_columnManager.Columns, this ); - - // Register to the VisibleColumnsChanged to update, if need be, the columns desired width when column stretching is active and there's a column reordering. - CollectionChangedEventManager.AddListener( m_columnManager.VisibleColumns, this ); - - CollectionChangedEventManager.AddListener( m_items.SortDescriptions, this ); - CollectionChangedEventManager.AddListener( m_items.GroupDescriptions, this ); - - GroupConfigurationSelectorChangedEventManager.AddListener( m_dataGridControl, this ); - AllowDetailToggleChangedEventManager.AddListener( m_dataGridControl, this ); - MaxGroupLevelsChangedEventManager.AddListener( m_dataGridControl, this ); - MaxSortLevelsChangedEventManager.AddListener( m_dataGridControl, this ); - ItemsSourceChangeCompletedEventManager.AddListener( m_dataGridControl, this ); - - this.HookToItemPropertiesChanged(); - } - //Detail DataGridContext - else - { - m_detailConfig.AddDataGridContext( this ); - - m_columnManager = m_detailConfig.ColumnManager; - m_itemsSourcePropertyDescriptions = m_detailConfig.ItemsSourcePropertyDescriptions; - m_itemPropertyMap = m_detailConfig.ItemPropertyMap; - - //only listen to the detail grid config current column changed if the detail grid config is synchronized. - CurrentColumnChangedEventManager.AddListener( m_detailConfig, this ); - - GroupConfigurationSelectorChangedEventManager.AddListener( m_detailConfig, this ); - AllowDetailToggleChangedEventManager.AddListener( m_detailConfig, this ); - - // Register to the VisibleColumnsChanged to update, if need be, the columns desired width - // when column stretching is active and there's a column reordering. - CollectionChangedEventManager.AddListener( m_detailConfig.VisibleColumns, this ); - - MaxGroupLevelsChangedEventManager.AddListener( m_detailConfig, this ); - MaxSortLevelsChangedEventManager.AddListener( m_detailConfig, this ); - - m_detailConfig.DetailConfigurations.DataGridControl = dataGridControl; - } - - Debug.Assert( m_columnManager != null ); - Debug.Assert( m_itemsSourcePropertyDescriptions != null ); - Debug.Assert( m_itemPropertyMap != null ); - - ColumnsLayoutChangingEventManager.AddListener( m_columnManager, this ); - ColumnsLayoutChangedEventManager.AddListener( m_columnManager, this ); - DetailVisibilityChangedEventManager.AddListener( this.DetailConfigurations, this ); - RealizedContainersRequestedEventManager.AddListener( this.Columns, this ); - DistinctValuesRequestedEventManager.AddListener( this.Columns, this ); - - this.SetupViewProperties(); - this.InitializeViewProperties(); - - ViewChangedEventManager.AddListener( m_dataGridControl, this ); - - GroupLevelDescriptionCollection groupLevelDescriptions = this.GroupLevelDescriptions; - ObservableCollection groupDescriptions = m_items.GroupDescriptions; - if( groupLevelDescriptions.Count != groupDescriptions.Count ) - { - DataGridContext.UpdateGroupLevelDescriptions( groupLevelDescriptions, new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Reset ), groupDescriptions, this.Columns ); - } - - // Set the value of DetailLevel property - DataGridContext tempDataGridContext = this.ParentDataGridContext; - while( tempDataGridContext != null ) - { - this.DetailLevel++; - tempDataGridContext = tempDataGridContext.ParentDataGridContext; - } - } - - private void Items_CollectionChanged( object sender, NotifyCollectionChangedEventArgs e ) - { - if( m_deferSelectionChangedOnItemsCollectionChanged != null ) - { - m_deferSelectionChangedOnItemsCollectionChanged.Queue( e ); - } - else - { - this.UpdateSelectionAfterSourceCollectionChanged( e ); - } - } - - private void UpdateSelectionAfterSourceCollectionChanged( NotifyCollectionChangedEventArgs e ) - { - if( m_dataGridControl.SelectedIndexPropertyNeedCoerce ) - { - m_dataGridControl.CoerceValue( DataGridControl.SelectedIndexProperty ); - } - - if( m_dataGridControl.SelectedItemPropertyNeedCoerce ) - { - m_dataGridControl.CoerceValue( DataGridControl.SelectedItemProperty ); - } - - m_dataGridControl.SelectionChangerManager.UpdateSelectionAfterSourceCollectionChanged( this, e ); - - } - - internal void CleanDataGridContext() - { - m_currencyManager.CleanManager(); - - if( m_items != null ) - { - CollectionChangedEventManager.RemoveListener( m_items, this ); - - var dataGridCollectionViewBase = this.ItemsSourceCollection as DataGridCollectionViewBase; - if( dataGridCollectionViewBase != null ) - { - dataGridCollectionViewBase.Dispose(); - } - } - - if( m_detailConfig == null ) - { - GroupConfigurationSelectorChangedEventManager.RemoveListener( m_dataGridControl, this ); - AllowDetailToggleChangedEventManager.RemoveListener( m_dataGridControl, this ); - MaxGroupLevelsChangedEventManager.RemoveListener( m_dataGridControl, this ); - MaxSortLevelsChangedEventManager.RemoveListener( m_dataGridControl, this ); - ItemsSourceChangeCompletedEventManager.RemoveListener( m_dataGridControl, this ); - - CollectionChangedEventManager.RemoveListener( m_items.SortDescriptions, this ); - CollectionChangedEventManager.RemoveListener( m_items.GroupDescriptions, this ); - - this.UnhookToItemPropertiesChanged( m_dataGridControlItemsSource as DataGridCollectionViewBase ); - } - else - { - CurrentColumnChangedEventManager.RemoveListener( m_detailConfig, this ); - GroupConfigurationSelectorChangedEventManager.RemoveListener( m_detailConfig, this ); - AllowDetailToggleChangedEventManager.RemoveListener( m_detailConfig, this ); - CollectionChangedEventManager.RemoveListener( m_detailConfig.VisibleColumns, this ); - MaxGroupLevelsChangedEventManager.RemoveListener( m_detailConfig, this ); - MaxSortLevelsChangedEventManager.RemoveListener( m_detailConfig, this ); - - m_detailConfig.RemoveDataGridContext( this ); - } - - this.ClearSizeStates(); - - ColumnsLayoutChangingEventManager.RemoveListener( m_columnManager, this ); - ColumnsLayoutChangedEventManager.RemoveListener( m_columnManager, this ); - CollectionChangedEventManager.RemoveListener( this.DetailConfigurations, this ); - DetailVisibilityChangedEventManager.RemoveListener( this.DetailConfigurations, this ); - RealizedContainersRequestedEventManager.RemoveListener( this.Columns, this ); - DistinctValuesRequestedEventManager.RemoveListener( this.Columns, this ); - - ViewChangedEventManager.RemoveListener( m_dataGridControl, this ); - - var columnVirtualizationManager = this.ColumnVirtualizationManager; - if( columnVirtualizationManager != null ) - { - columnVirtualizationManager.CleanManager(); - ColumnVirtualizationManager.ClearColumnVirtualizationManager( this ); - } - - this.ClearViewPropertyBindings(); - - if( m_defaultDetailConfiguration != null ) - { - GroupConfigurationSelectorChangedEventManager.RemoveListener( m_defaultDetailConfiguration, this ); - m_defaultDetailConfiguration = null; - } - } - - //---------- PUBLIC PROPERTIES ---------- - - #region ParentDataGridContext Read-Only Property - - public DataGridContext ParentDataGridContext - { - get - { - return m_parentDataGridContext; - } - } - - private readonly DataGridContext m_parentDataGridContext; // = null - - #endregion - - #region ParentItem Read-Only Property - - public object ParentItem - { - get - { - return m_parentItem; - } - } - - private readonly object m_parentItem; - - #endregion - - #region AllowDetailToggle Property - - public bool AllowDetailToggle - { - get - { - if( m_detailConfig != null ) - { - var defaultDetailConfig = this.GetDefaultDetailConfigurationForContext(); - if( defaultDetailConfig != null ) - return defaultDetailConfig.AllowDetailToggle; - - return m_detailConfig.AllowDetailToggle; - } - - return m_dataGridControl.AllowDetailToggle; - } - } - - #endregion - - #region DistinctValues Property - - public IDictionary DistinctValues - { - get - { - var dataGridCollectionViewBase = this.ItemsSourceCollection as DataGridCollectionViewBase; - if( dataGridCollectionViewBase == null ) - return null; - - return null; - } - } - - #endregion - - #region Columns Read-Only Property - - public ColumnCollection Columns - { - get - { - return m_columnManager.Columns; - } - } - - #endregion - - #region Items Property - - public CollectionView Items - { - get - { - return m_items; - } - } - - private readonly CollectionView m_items; - - #endregion - - #region OriginalItems Property - - internal IEnumerable ItemsSourceCollection - { - get - { - if( m_parentDataGridContext != null ) - return m_items; - - return m_dataGridControl.ItemsSource; - } - } - - #endregion - - #region CurrentColumn Property - - public ColumnBase CurrentColumn - { - get - { - if( m_detailConfig != null ) - return m_detailConfig.CurrentColumn; - - return m_currentColumn; - } - set - { - if( m_currentColumn == value ) - return; - - this.SetCurrentColumnCore( value, true, m_dataGridControl.SynchronizeSelectionWithCurrent, AutoScrollCurrentItemSourceTriggers.CurrentColumnChanged ); - } - } - - internal void SetCurrentColumnCore( ColumnBase column, bool isCancelable, bool synchronizeSelectionWithCurrent, AutoScrollCurrentItemSourceTriggers trigger ) - { - this.SetCurrent( this.InternalCurrentItem, null, null, column, false, isCancelable, synchronizeSelectionWithCurrent, trigger ); - } - - private ColumnBase m_currentColumn; // = null - - private void SetCurrentColumnHelper( ColumnBase value ) - { - if( m_detailConfig != null ) - { - m_detailConfig.CurrentColumn = value; - } - else - { - m_currentColumn = value; - } - } - - #endregion - - #region CurrentItem Properties - - public object CurrentItem - { - get - { - return m_currentItem; - } - set - { - if( value == m_currentItem ) - return; - - this.SetCurrentItemCore( value, true, m_dataGridControl.SynchronizeSelectionWithCurrent, AutoScrollCurrentItemSourceTriggers.CurrentItemChanged ); - } - } - - internal void SetCurrentItemCore( object item, bool isCancelable, bool synchronizeSelectionWithCurrent, AutoScrollCurrentItemSourceTriggers trigger ) - { - this.SetCurrent( item, null, null, this.CurrentColumn, false, isCancelable, synchronizeSelectionWithCurrent, trigger ); - } - - public int CurrentItemIndex - { - get - { - return m_currentItemIndex; - } - set - { - if( value == m_currentItemIndex ) - return; - - this.SetCurrentItemIndexCore( value, true, m_dataGridControl.SynchronizeSelectionWithCurrent, AutoScrollCurrentItemSourceTriggers.CurrentItemChanged ); - } - } - - internal void SetCurrentItemIndexCore( int index, bool isCancelable, bool synchronizeSelectionWithCurrent, AutoScrollCurrentItemSourceTriggers trigger ) - { - this.SetCurrent( this.Items.GetItemAt( index ), null, index, this.CurrentColumn, false, isCancelable, synchronizeSelectionWithCurrent, trigger ); - } - - private void SetCurrentItem( object dataItem, int sourceDataItemIndex ) - { - // This is called only for DataItem - if( ( m_currentItem == dataItem ) && ( m_currentItemIndex == sourceDataItemIndex ) ) - return; - - m_currentItem = dataItem; - m_currentItemIndex = sourceDataItemIndex; - this.OnCurrentItemChanged(); - } - - internal event EventHandler CurrentItemChanged; - - private void OnCurrentItemChanged() - { - var handler = this.CurrentItemChanged; - if( handler == null ) - return; - - handler.Invoke( this, EventArgs.Empty ); - } - - private object m_currentItem; // = null - private int m_currentItemIndex = -1; - - #endregion - - #region DefaultGroupConfiguration Read-Only Property - - public GroupConfiguration DefaultGroupConfiguration - { - get - { - if( m_detailConfig != null ) - { - var defaultDetailConfig = this.GetDefaultDetailConfigurationForContext(); - if( defaultDetailConfig != null ) - return defaultDetailConfig.DefaultGroupConfiguration; - - return m_detailConfig.DefaultGroupConfiguration; - } - - return m_dataGridControl.DefaultGroupConfiguration; - } - } - - #endregion - - #region DetailConfigurations Read-Only Property - - internal DetailConfigurationCollection DetailConfigurations - { - get - { - if( m_detailConfig != null ) - return m_detailConfig.DetailConfigurations; - - return null; - } - } - - #endregion - - #region Footers Read-Only Property - - public ObservableCollection Footers - { - get - { - if( m_detailConfig != null ) - { - var defaultDetailConfig = this.GetDefaultDetailConfigurationForContext(); - if( defaultDetailConfig != null ) - return defaultDetailConfig.Footers; - - return m_detailConfig.Footers; - } - - var view = m_dataGridControl.GetView(); - if( view == null ) - return new ObservableCollection(); - - return view.Footers; - } - } - - #endregion - - #region GroupLevelDescriptions Read-Only Property - - public GroupLevelDescriptionCollection GroupLevelDescriptions - { - get - { - if( m_detailConfig != null ) - return m_detailConfig.GroupLevelDescriptions; - - return m_groupLevelDescriptions; - } - } - - private readonly GroupLevelDescriptionCollection m_groupLevelDescriptions; //null - - #endregion - - #region GroupConfigurationSelector Property - - public GroupConfigurationSelector GroupConfigurationSelector - { - get - { - if( m_detailConfig != null ) - { - var defaultDetailConfig = this.GetDefaultDetailConfigurationForContext(); - if( defaultDetailConfig != null ) - return defaultDetailConfig.GroupConfigurationSelector; - - return m_detailConfig.GroupConfigurationSelector; - } - - return m_dataGridControl.GroupConfigurationSelector; - } - } - - private void OnGroupConfigurationSelectorChanged() - { - var handler = this.GroupConfigurationSelectorChanged; - if( handler == null ) - return; - - handler.Invoke( this, EventArgs.Empty ); - } - - internal event EventHandler GroupConfigurationSelectorChanged; - - #endregion - - #region HasDetails Read-Only Property - - public bool HasDetails - { - get - { - return false; - } - } - - #endregion - - #region Headers Read-Only property - - public ObservableCollection Headers - { - get - { - if( m_detailConfig != null ) - { - var defaultDetailConfig = this.GetDefaultDetailConfigurationForContext(); - if( defaultDetailConfig != null ) - return defaultDetailConfig.Headers; - - return m_detailConfig.Headers; - } - - var view = m_dataGridControl.GetView(); - if( view == null ) - return new ObservableCollection(); - - return view.Headers; - } - } - - #endregion - - #region IsCurrent Read-Only Property - - public bool IsCurrent - { - get - { - return m_flags[ ( int )DataGridContextFlags.IsCurrent ]; - } - } - - internal void SetIsCurrent( bool value ) - { - m_flags[ ( int )DataGridContextFlags.IsCurrent ] = value; - } - - #endregion - - #region ItemContainerStyle - - public Style ItemContainerStyle - { - get - { - if( m_detailConfig != null ) - { - var defaultDetailConfig = this.GetDefaultDetailConfigurationForContext(); - if( defaultDetailConfig != null ) - return defaultDetailConfig.ItemContainerStyle; - - return m_detailConfig.ItemContainerStyle; - } - - return m_dataGridControl.ItemContainerStyle; - } - } - - #endregion - - #region ItemContainerStyleSelector - - public StyleSelector ItemContainerStyleSelector - { - get - { - if( m_detailConfig != null ) - { - var defaultDetailConfig = this.GetDefaultDetailConfigurationForContext(); - if( defaultDetailConfig != null ) - return defaultDetailConfig.ItemContainerStyleSelector; - - return m_detailConfig.ItemContainerStyleSelector; - } - - return m_dataGridControl.ItemContainerStyleSelector; - } - } - - #endregion - - #region DataGridControl Read-Only Property - - public DataGridControl DataGridControl - { - get - { - return m_dataGridControl; - } - } - - private readonly DataGridControl m_dataGridControl; - - #endregion - - #region SelectedItems Read-Only Property - - public IList SelectedItems - { - get - { - return m_selectedItems; - } - } - - private readonly SelectionItemCollection m_selectedItems; - - #endregion - - #region SelectedItemRanges Read-Only Property - - public IList SelectedItemRanges - { - get - { - return m_selectedItemsRanges; - } - } - - private readonly SelectionItemRangeCollection m_selectedItemsRanges; - - #endregion - - #region SelectedCellRanges Read-Only Property - - public IList SelectedCellRanges - { - get - { - return m_selectedCellRanges; - } - } - - private readonly SelectionCellRangeCollection m_selectedCellRanges; - - #endregion - - #region SourceDetailConfiguration Read-Only Property - - internal DetailConfiguration SourceDetailConfiguration - { - get - { - return m_detailConfig; - } - } - - private readonly DetailConfiguration m_detailConfig; - - #endregion - - #region VisibleColumns Read-Only Property - - public ReadOnlyObservableCollection VisibleColumns - { - get - { - return m_columnManager.VisibleColumns; - } - } - - #endregion - - #region AutoCreateForeignKeyConfigurations Internal Property - - internal bool AutoCreateForeignKeyConfigurations - { - get - { - if( m_detailConfig != null ) - return m_detailConfig.AutoCreateForeignKeyConfigurations; - - return m_dataGridControl.AutoCreateForeignKeyConfigurations; - } - } - - #endregion - - #region MaxSortLevels Property - - public int MaxSortLevels - { - get - { - if( m_detailConfig != null ) - { - var defaultDetailConfig = this.GetDefaultDetailConfigurationForContext(); - if( defaultDetailConfig != null ) - return defaultDetailConfig.MaxSortLevels; - - return m_detailConfig.MaxSortLevels; - } - - return m_dataGridControl.MaxSortLevels; - } - } - - #endregion - - #region MaxGroupLevels Property - - public int MaxGroupLevels - { - get - { - if( m_detailConfig != null ) - { - var defaultDetailConfig = this.GetDefaultDetailConfigurationForContext(); - if( defaultDetailConfig != null ) - return defaultDetailConfig.MaxGroupLevels; - - return m_detailConfig.MaxGroupLevels; - } - - return m_dataGridControl.MaxGroupLevels; - } - } - - #endregion - - //--------- INTERNAL PROPERTIES --------- - - #region RootDataGridContext Read-Only Property - - internal DataGridContext RootDataGridContext - { - get - { - return this.DataGridControl.DataGridContext; - } - } - - #endregion - - #region SelectedItemsStore Read-Only Property - - internal SelectedItemsStorage SelectedItemsStore - { - get - { - return m_selectedItemsStore; - } - } - - private readonly SelectedItemsStorage m_selectedItemsStore; - - #endregion - - #region SelectedItemsStore Read-Only Property - - internal SelectedCellsStorage SelectedCellsStore - { - get - { - return m_selectedCellsStore; - } - } - - private readonly SelectedCellsStorage m_selectedCellsStore; - - #endregion - - #region ColumnsByVisiblePosition Read-Only Property - - internal HashedLinkedList ColumnsByVisiblePosition - { - get - { - return m_columnManager.ColumnsByVisiblePosition; - } - } - - #endregion - - #region ColumnStretchingManager Property - - internal ColumnStretchingManager ColumnStretchingManager - { - get - { - if( m_columnStretchingManager == null ) - { - m_columnStretchingManager = new ColumnStretchingManager( this ); - } - - return m_columnStretchingManager; - } - } - - private ColumnStretchingManager m_columnStretchingManager; - - #endregion - - #region CurrentCell Read-Only Property - - internal Cell CurrentCell - { - get - { - var currentRow = this.CurrentRow; - if( currentRow == null ) - return null; - - return currentRow.Cells[ this.CurrentColumn ]; - } - } - - #endregion - - #region CurrentRow Read-Only Property - - internal Row CurrentRow - { - get - { - if( this.InternalCurrentItem == null ) - return null; - - return Row.FromContainer( this.GetContainerFromItem( this.InternalCurrentItem ) ); - } - } - - #endregion - - #region CustomItemContainerGenerator Read-Only Property - - internal CustomItemContainerGenerator CustomItemContainerGenerator - { - get - { - return m_generator; - } - } - - internal void SetGenerator( CustomItemContainerGenerator generator ) - { - if( m_generator != null ) - throw new InvalidOperationException( "An attempt was made to reset the generator after it has already been set." ); - - if( generator == null ) - throw new ArgumentNullException( "generator" ); - - m_generator = generator; - } - - private CustomItemContainerGenerator m_generator; - - #endregion - - #region InternalCurrentItem Read-Only Property - - internal object InternalCurrentItem - { - get - { - return m_internalCurrentItem; - } - } - - private void SetInternalCurrentItem( object value ) - { - m_internalCurrentItem = value; - } - - private object m_internalCurrentItem; //null - - #endregion - - #region ItemsSourcePropertyDescriptions Property - - internal PropertyDescriptionRouteDictionary ItemsSourcePropertyDescriptions - { - get - { - return m_itemsSourcePropertyDescriptions; - } - } - - private readonly PropertyDescriptionRouteDictionary m_itemsSourcePropertyDescriptions; - - #endregion - - #region ItemPropertyMap Internal Property - - internal DataGridItemPropertyMap ItemPropertyMap - { - get - { - return m_itemPropertyMap; - } - } - - private readonly DataGridItemPropertyMap m_itemPropertyMap; - - #endregion - - #region ToggleColumnSortCommand Internal Property - - internal ToggleColumnSortCommand ToggleColumnSortCommand - { - get - { - if( m_toggleColumnSortCommand == null ) - { - m_toggleColumnSortCommand = new DataGridContextToggleColumnSortCommand( this ); - } - - Debug.Assert( m_toggleColumnSortCommand != null ); - - return m_toggleColumnSortCommand; - } - } - - private ToggleColumnSortCommand m_toggleColumnSortCommand; - - #endregion - - #region UpdateColumnSortCommand Internal Property - - internal UpdateColumnSortCommand UpdateColumnSortCommand - { - get - { - if( m_updateColumnSortCommand == null ) - { - m_updateColumnSortCommand = new DataGridContextUpdateColumnSortCommand( this ); - } - - Debug.Assert( m_updateColumnSortCommand != null ); - - return m_updateColumnSortCommand; - } - } - - private UpdateColumnSortCommand m_updateColumnSortCommand; - - #endregion - - #region AddGroupCommand Internal Property - - internal ColumnAddGroupCommand AddGroupCommand - { - get - { - if( m_addGroupCommand == null ) - { - m_addGroupCommand = new DataGridContextAddGroupCommand( this ); - } - - Debug.Assert( m_addGroupCommand != null ); - - return m_addGroupCommand; - } - } - - private ColumnAddGroupCommand m_addGroupCommand; - - #endregion - - #region SortDescriptionsSyncContext Read-Only Property - - internal SortDescriptionsSyncContext SortDescriptionsSyncContext - { - get - { - var dataGridCollectionViewBase = this.ItemsSourceCollection as DataGridCollectionViewBase; - if( dataGridCollectionViewBase != null ) - return dataGridCollectionViewBase.DataGridSortDescriptions.SyncContext; - - Debug.Assert( m_sortDescriptionsSyncContext != null ); - return m_sortDescriptionsSyncContext; - } - } - - private readonly SortDescriptionsSyncContext m_sortDescriptionsSyncContext; //null - - #endregion - - #region DefaultDetailConfiguration Property - - internal DefaultDetailConfiguration DefaultDetailConfiguration - { - get - { - if( m_detailConfig != null ) - return m_detailConfig.DefaultDetailConfiguration; - - return m_dataGridControl.DefaultDetailConfiguration; - } - } - - #endregion - - #region ColumnVirtualizationManager Property - - internal ColumnVirtualizationManager ColumnVirtualizationManager - { - get - { - var columnVirtualizationManager = this.GetColumnVirtualizationManagerOrNull(); - if( columnVirtualizationManager == null ) - { - columnVirtualizationManager = this.DataGridControl.GetView().CreateColumnVirtualizationManager( this ); - } - - // We must ensure the manager is up to date before using it - columnVirtualizationManager.Update(); - - return columnVirtualizationManager; - } - } - - internal ColumnVirtualizationManager GetColumnVirtualizationManagerOrNull() - { - return ColumnVirtualizationManager.GetColumnVirtualizationManager( this ); - } - - #endregion - - #region ColumnManagerRowConfiguration Read-Only Internal Property - - internal ColumnManagerRowConfiguration ColumnManagerRowConfiguration - { - get - { - if( m_detailConfig != null ) - return m_detailConfig.ColumnManagerRowConfiguration; - - return this.DataGridControl.ColumnManagerRowConfiguration; - } - } - - #endregion - - #region FixedHeaderFooterViewPortSize Property - - internal Size FixedHeaderFooterViewPortSize - { - get - { - return m_fixedHeaderFooterViewPortSize; - } - set - { - if( Size.Equals( value, m_fixedHeaderFooterViewPortSize ) ) - return; - - m_fixedHeaderFooterViewPortSize = value; - - this.OnPropertyChanged( "FixedHeaderFooterViewPortSize" ); - } - } - - private Size m_fixedHeaderFooterViewPortSize = new Size(); - - #endregion - - #region IsDeleteCommandEnabled Property - - internal bool IsDeleteCommandEnabled - { - get - { - return this.FindIsDeletedCommandEnabledAmbient( this ); - } - } - - private bool FindIsDeletedCommandEnabledAmbient( DataGridContext dataGridContext ) - { - if( dataGridContext == null ) - return false; - - if( dataGridContext.SourceDetailConfiguration == null ) - { - if( dataGridContext.DataGridControl == null ) - return false; - - return dataGridContext.DataGridControl.IsDeleteCommandEnabled; - } - - var defaultDetailConfig = dataGridContext.GetDefaultDetailConfigurationForContext(); - if( defaultDetailConfig != null ) - { - if( defaultDetailConfig.ReadLocalValue( DefaultDetailConfiguration.IsDeleteCommandEnabledProperty ) != DependencyProperty.UnsetValue ) - return defaultDetailConfig.IsDeleteCommandEnabled; - } - else - { - if( dataGridContext.SourceDetailConfiguration.ReadLocalValue( DetailConfiguration.IsDeleteCommandEnabledProperty ) != DependencyProperty.UnsetValue ) - return dataGridContext.SourceDetailConfiguration.IsDeleteCommandEnabled; - } - - return this.FindIsDeletedCommandEnabledAmbient( dataGridContext.ParentDataGridContext ); - } - - #endregion - - #region SelectionChanged Event - - internal event EventHandler SelectionChangedInternal; - - internal void InvokeSelectionChanged( SelectionInfo selectionInfo ) - { - - if( this.SelectionChangedInternal != null ) - { - this.SelectionChangedInternal( this, new SelectionChangedInternalEventArgs( selectionInfo ) ); - } - - Debug.Assert( selectionInfo.DataGridContext == this ); - - if( ( selectionInfo.RemovedItems.Count == 0 ) && ( selectionInfo.AddedItems.Count == 0 ) ) - return; - - } - - #endregion - - #region DetailLevel Property - - // Represents the detail level from the master item - internal int DetailLevel - { - get; - private set; - } - - #endregion - - #region IsSavingState Property - - internal bool IsSavingState - { - get - { - return m_flags[ ( int )DataGridContextFlags.IsSavingState ]; - } - set - { - m_flags[ ( int )DataGridContextFlags.IsSavingState ] = value; - } - } - - #endregion - - #region IsRestoringState Property - - internal bool IsRestoringState - { - get - { - return m_flags[ ( int )DataGridContextFlags.IsRestoringState ]; - } - set - { - m_flags[ ( int )DataGridContextFlags.IsRestoringState ] = value; - } - } - - #endregion - - #region IsDeferRestoringState Internal Property - - internal bool IsDeferRestoringState - { - get - { - return ( m_deferRestoreStateCount > 0 ); - } - } - - #endregion - - #region IsAFlattenDetail Internal Property - - internal bool IsAFlattenDetail - { - get - { - return ( m_detailConfig != null ) - && ( this.AreDetailsFlatten ); - } - } - - #endregion - - #region AreDetailsFlatten Internal Property - - internal bool AreDetailsFlatten - { - get - { - return this.DataGridControl.AreDetailsFlatten; - } - } - - #endregion - - #region AlreadySearchedForDefaultDetailConfig Private Property - - private bool AlreadySearchedForDefaultDetailConfig - { - get - { - return m_flags[ ( int )DataGridContextFlags.AlreadySearchedForDetailConfig ]; - } - set - { - m_flags[ ( int )DataGridContextFlags.AlreadySearchedForDetailConfig ] = value; - } - } - - #endregion - - #region DefaultImageColumnDetermined Private Property - - private bool DefaultImageColumnDetermined - { - get - { - return m_flags[ ( int )DataGridContextFlags.DefaultImageColumnDetermined ]; - } - set - { - m_flags[ ( int )DataGridContextFlags.DefaultImageColumnDetermined ] = value; - } - } - - #endregion - - #region ColumnManager Internal Property - - internal ColumnHierarchyManager ColumnManager - { - get - { - return m_columnManager; - } - } - - private readonly ColumnHierarchyManager m_columnManager; - - #endregion - - #region CanIncreaseColumnWidth Property - - internal bool CanIncreaseColumnWidth - { - get - { - return m_canIncreaseColumnWidth; - } - set - { - m_canIncreaseColumnWidth = value; - } - } - - private bool m_canIncreaseColumnWidth = true; - - #endregion - - internal void SetCurrentColumnAndChangeSelection( ColumnBase newCurrentColumn ) - { - // Since SetCurrentColumnCore can be aborted, we do it before changing the selection. - this.SetCurrentColumnCore( newCurrentColumn, true, false, AutoScrollCurrentItemSourceTriggers.Navigation ); - - if( m_dataGridControl != null ) - { - Row row = this.CurrentRow; - object item = this.InternalCurrentItem; - - int dataRowIndex; - bool rowIsBeingEdited; - - if( row == null ) - { - dataRowIndex = -1; - rowIsBeingEdited = false; - } - else - { - dataRowIndex = DataGridVirtualizingPanel.GetItemIndex( row ); - rowIsBeingEdited = row.IsBeingEdited; - } - - var oldPosition = SelectionRangePoint.TryCreateFromCurrent( this ); - var newPosition = SelectionRangePoint.TryCreateRangePoint( this, item, dataRowIndex, newCurrentColumn.VisiblePosition ); - - m_dataGridControl.SelectionChangerManager.UpdateSelection( oldPosition, newPosition, true, rowIsBeingEdited, SelectionManager.UpdateSelectionSource.Navigation ); - } - } - - //---------- PUBLIC METHODS ---------- - - public void BeginEdit() - { - this.BeginEdit( this.InternalCurrentItem ); - } - - public void BeginEdit( object item ) - { - DataGridControl.BeginEditHelper( this, item ); - } - - public void EndEdit() - { - DataGridControl.EndEditHelper( this ); - } - - public void CancelEdit() - { - DataGridControl.CancelEditHelper( this ); - } - - internal bool IsContainingItem( object item ) - { - DataTemplate itemTemplate = item as DataTemplate; - - if( ( this.ParentItem == null ) && ( itemTemplate != null ) ) - { - if( m_dataGridControl.View.FixedHeaders.Contains( itemTemplate ) - || m_dataGridControl.View.FixedFooters.Contains( itemTemplate ) ) - { - return true; - } - } - - return m_generator.Contains( item ); - } - - public bool IsGroupExpanded( CollectionViewGroup group ) - { - return ( this.CustomItemContainerGenerator.IsGroupExpanded( group ) == true ); - } - - internal bool? IsGroupExpanded( CollectionViewGroup group, bool recurseDetails ) - { - return this.CustomItemContainerGenerator.IsGroupExpanded( group, recurseDetails ); - } - - public bool ToggleGroupExpansion( CollectionViewGroup group ) - { - return this.CustomItemContainerGenerator.ToggleGroupExpansion( group ); - } - - public bool ExpandGroup( CollectionViewGroup group ) - { - return this.CustomItemContainerGenerator.ExpandGroup( group ); - } - - internal bool ExpandGroup( CollectionViewGroup group, bool recurseDetails ) - { - return this.CustomItemContainerGenerator.ExpandGroup( group, recurseDetails ); - } - - public bool CollapseGroup( CollectionViewGroup group ) - { - return this.CustomItemContainerGenerator.CollapseGroup( group ); - } - - internal bool CollapseGroup( CollectionViewGroup group, bool recurseDetails ) - { - return this.CustomItemContainerGenerator.CollapseGroup( group, recurseDetails ); - } - - public bool AreDetailsExpanded( object dataItem ) - { - return this.CustomItemContainerGenerator.AreDetailsExpanded( dataItem ); - } - - public Group GetGroupFromCollectionViewGroup( CollectionViewGroup collectionViewGroup ) - { - if( collectionViewGroup == null ) - return null; - - Group group = this.CustomItemContainerGenerator.GetGroupFromCollectionViewGroup( collectionViewGroup ); - - return group; - } - - public DependencyObject GetContainerFromItem( object item ) - { - if( item == null ) - return null; - - var container = default( DependencyObject ); - - if( ( m_detailConfig == null ) && ( item is DataTemplate ) ) - { - //If the container was not found in the DataGridContext's Generator and the DataGridContext does not have a source DetailConfig ( master context ) - //then check in the DataGridControl's Fixed Items - container = m_dataGridControl.GetContainerForFixedItem( item ); - } - - if( container == null ) - { - container = this.CustomItemContainerGenerator.ContainerFromItem( item ); - } - - return container; - } - - public object GetItemFromContainer( DependencyObject container ) - { - object item = null; - - if( m_detailConfig == null ) - { - //If the item was not found in the DataGridContext's Generator and the DataGridContext does not have a source DetailConfig ( master context ) - //then check in the DataGridControl's Fixed Items - item = DataGridControl.GetFixedItemFromContainer( container ); - } - - if( item == null ) - { - item = this.CustomItemContainerGenerator.ItemFromContainer( container ); - } - - return item; - } - - [EditorBrowsable( EditorBrowsableState.Never )] - public DependencyObject GetContainerFromIndex( int index ) - { - return this.CustomItemContainerGenerator.GetRealizedContainerForIndex( index ); - } - - [EditorBrowsable( EditorBrowsableState.Never )] - public int GetIndexFromContainer( DependencyObject container ) - { - return this.CustomItemContainerGenerator.GetRealizedIndexForContainer( container ); - } - - public CollectionViewGroup GetParentGroupFromItem( object item ) - { - return this.GetParentGroupFromItemCore( item, false ); - } - - internal CollectionViewGroup GetParentGroupFromItemCore( object item, bool recurseDetails ) - { - CollectionViewGroup retval = null; - - DataTemplate dataTemplate = item as DataTemplate; - - //For the master level, before interrogating the Generator, I need to check for the items presence in the Fixed regions. - if( ( m_detailConfig == null ) && ( dataTemplate != null ) ) - { - Views.ViewBase view = m_dataGridControl.GetView(); - - //Fixed header cannot have a Parent Group. - if( view.FixedHeaders.Contains( dataTemplate ) == true ) - return null; - - //Fixed header cannot have a Parent Group. - if( view.FixedFooters.Contains( dataTemplate ) == true ) - return null; - } - - if( this.CustomItemContainerGenerator.IsInUse == true ) - { - retval = this.CustomItemContainerGenerator.GetParentGroupFromItem( item, recurseDetails ); - } - - return retval; - } - - internal DataGridContext GetChildContext( object parentItem, DetailConfiguration detailConfiguration ) - { - if( detailConfiguration == null ) - throw new ArgumentNullException( "detailConfiguration" ); - - return this.GetChildContext( parentItem, detailConfiguration.RelationName ); - } - - public DataGridContext GetChildContext( object parentItem, string relationName ) - { - return this.CustomItemContainerGenerator.GetChildContext( parentItem, relationName ); - } - - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate" )] - public IEnumerable GetChildContexts() - { - return this.CustomItemContainerGenerator.GetChildContexts(); - } - - internal IEnumerable GetChildContextsCore() - { - return this.CustomItemContainerGenerator.GetChildContextsCore(); - } - - internal BindingPathValueExtractor GetBindingPathExtractorForColumn( Column column, object dataItem ) - { - if( column == null ) - throw new ArgumentNullException( "column" ); - - if( dataItem == null ) - return null; - - if( column == null ) - throw new ArgumentNullException( "column" ); - - var xPath = default( string ); - var propertyPath = default( PropertyPath ); - - // Disable warning for DisplayMemberBinding when internaly used -#pragma warning disable 618 - var displayMemberBinding = column.DisplayMemberBinding as Binding; -#pragma warning restore 618 - - if( displayMemberBinding == null ) - { - displayMemberBinding = ItemsSourceHelper.CreateDefaultBinding( - ItemsSourceHelper.CreateOrGetPropertyDescriptionFromColumn( this, column, dataItem.GetType() ) ); - } - - if( displayMemberBinding == null ) - throw new DataGridInternalException( "DisplayMemberBinding is null.", m_dataGridControl ); - - xPath = displayMemberBinding.XPath; - propertyPath = displayMemberBinding.Path; - - var converter = new Xceed.Wpf.DataGrid.Converters.SourceDataConverter( ItemsSourceHelper.IsItemSupportingDBNull( dataItem ), CultureInfo.InvariantCulture ); - - return new BindingPathValueExtractor( xPath, propertyPath, false, typeof( object ), converter, null, CultureInfo.InvariantCulture ); - } - - public IDisposable DeferColumnsUpdate() - { - return ColumnHierarchyManagerHelper.DeferColumnsUpdate( this ); - } - - public bool MoveColumnBefore( ColumnBase current, ColumnBase next ) - { - return ColumnHierarchyManagerHelper.MoveColumnBefore( this, current, next ); - } - - public bool MoveColumnAfter( ColumnBase current, ColumnBase previous ) - { - return ColumnHierarchyManagerHelper.MoveColumnAfter( this, current, previous ); - } - - public bool MoveColumnUnder( ColumnBase current, ColumnBase parent ) - { - return ColumnHierarchyManagerHelper.MoveColumnUnder( this, current, parent ); - } - - //---------- INTERNAL METHODS ----------- - - internal IDisposable DeferRestoreState() - { - return new DeferRestoreStateDisposable( this ); - } - - internal void UpdatePublicSelectionProperties() - { - if( ( m_selectedItemsStore.Count > 0 ) || ( m_selectedCellsStore.Count > 0 ) ) - { - m_dataGridControl.AddToSelectedContexts( this ); - } - else - { - m_dataGridControl.RemoveFromSelectedContexts( this ); - } - - - if( m_parentItem == null ) - { - // We are the root context ( GridControl ) - int newSelectedItemIndex; - object newSelectedItem; - int newSelectedColumnIndex; - this.GetFirstSelectedItemFromStore( false, out newSelectedItemIndex, out newSelectedItem, out newSelectedColumnIndex ); - - if( m_dataGridControl.SelectedIndex != newSelectedItemIndex ) - { - m_dataGridControl.SelectedIndex = newSelectedItemIndex; - } - - // Calculate the new SelectedItem - if( !object.Equals( m_dataGridControl.SelectedItem, newSelectedItem ) ) - { - m_dataGridControl.SetSkipCoerceSelectedItemCheck( true ); - - try - { - m_dataGridControl.SelectedItem = newSelectedItem; - } - finally - { - m_dataGridControl.SetSkipCoerceSelectedItemCheck( false ); - } - } - } - } - - internal void GetFirstSelectedItemFromStore( bool checkCellsStore, out int selectedItemIndex, out object selectedItem, out int selectedColumnIndex ) - { - var newSelectedRangeWithItems = ( m_selectedItemsStore.Count == 0 ) ? SelectionRangeWithItems.Empty : m_selectedItemsStore[ 0 ]; - - try - { - if( newSelectedRangeWithItems.IsEmpty ) - { - if( checkCellsStore ) - { - var newSelectionCellRangeWithItems = ( m_selectedCellsStore.Count == 0 ) ? SelectionCellRangeWithItems.Empty : m_selectedCellsStore[ 0 ]; - - if( newSelectionCellRangeWithItems.ItemRange.IsEmpty ) - { - selectedColumnIndex = -1; - selectedItemIndex = -1; - selectedItem = null; - } - else - { - selectedColumnIndex = newSelectionCellRangeWithItems.ColumnRange.StartIndex; - selectedItemIndex = newSelectionCellRangeWithItems.ItemRange.StartIndex; - selectedItem = newSelectionCellRangeWithItems.ItemRangeWithItems.GetItem( this, 0 ); - } - } - else - { - selectedColumnIndex = -1; - selectedItemIndex = -1; - selectedItem = null; - } - } - else - { - selectedColumnIndex = -1; - selectedItemIndex = newSelectedRangeWithItems.Range.StartIndex; - selectedItem = newSelectedRangeWithItems.GetItem( this, 0 ); - } - } - catch( ArgumentOutOfRangeException ) - { - selectedColumnIndex = -1; - selectedItemIndex = -1; - selectedItem = null; - } - } - - internal ColumnBase GetMatchingColumn( DataGridContext sourceContext, ColumnBase sourceColumn ) - { - if( ( sourceContext == null ) || ( sourceColumn == null ) ) - return null; - - if( sourceContext == this ) - return sourceColumn; - - var collectionView = sourceContext.ItemsSourceCollection as DataGridCollectionViewBase; - if( collectionView == null ) - return null; - - var sourceItemProperty = ItemsSourceHelper.GetItemPropertyFromProperty( collectionView.ItemProperties, sourceColumn.FieldName ); - if( sourceItemProperty == null ) - return null; - - var masterContext = sourceContext.RootDataGridContext; - var masterItemProperty = sourceItemProperty; - - if( masterContext != sourceContext ) - { - if( !sourceContext.ItemPropertyMap.TryGetMasterItemProperty( sourceItemProperty, out masterItemProperty ) ) - return null; - } - - Debug.Assert( masterItemProperty != null ); - if( masterItemProperty == null ) - return null; - - var currentItemProperty = masterItemProperty; - if( masterContext != this ) - { - if( !this.ItemPropertyMap.TryGetDetailItemProperty( masterItemProperty, out currentItemProperty ) ) - return null; - } - - Debug.Assert( currentItemProperty != null ); - if( currentItemProperty == null ) - return null; - - var columnName = PropertyRouteParser.Parse( currentItemProperty ); - if( string.IsNullOrEmpty( columnName ) ) - return null; - - return this.Columns[ columnName ]; - } - - internal ColumnBase GetDefaultImageColumn() - { - if( !this.DefaultImageColumnDetermined ) - { - if( this.Items.Count > 0 ) - { - this.DefaultImageColumnDetermined = true; - - var dataItem = this.Items.GetItemAt( 0 ); - - foreach( var column in this.VisibleColumns ) - { - var key = PropertyRouteParser.Parse( column.FieldName ); - if( key == null ) - continue; - - var propertyDescriptionRoute = default( PropertyDescriptionRoute ); - if( !m_itemsSourcePropertyDescriptions.TryGetValue( key, out propertyDescriptionRoute ) ) - continue; - - var propertyDescription = propertyDescriptionRoute.Current; - var dataType = propertyDescription.DataType; - - if( typeof( ImageSource ).IsAssignableFrom( dataType ) ) - { - m_defaultImageColumn = column; - break; - } - else if( ( typeof( byte[] ).IsAssignableFrom( dataType ) ) || - ( typeof( System.Drawing.Image ).IsAssignableFrom( dataType ) ) ) - { - var converter = new Xceed.Wpf.DataGrid.Converters.ImageConverter(); - var convertedValue = default( object ); - var rawValue = default( object ); - - try - { - if( propertyDescription.PropertyDescriptor == null ) - { - var dataRow = dataItem as System.Data.DataRow; - if( dataRow == null ) - { - var dataRowView = dataItem as System.Data.DataRowView; - if( dataRowView != null ) - { - rawValue = dataRowView[ propertyDescription.Name ]; - } - } - else - { - rawValue = dataRow[ propertyDescription.Name ]; - } - } - else - { - rawValue = propertyDescription.PropertyDescriptor.GetValue( dataItem ); - } - - if( rawValue != null ) - { - convertedValue = converter.Convert( rawValue, typeof( ImageSource ), null, CultureInfo.CurrentCulture ); - } - } - catch( NotSupportedException ) - { - //suppress the exception, the byte[] is not an image. convertedValue will remain null - } - - if( convertedValue != null ) - { - m_defaultImageColumn = column; - break; - } - } - } - } - } - - return m_defaultImageColumn; - } - - internal void EnsureResort() - { - if( ( !ItemsSourceHelper.IsDataView( this.Items ) ) && ( this.Items.SortDescriptions.Count > 0 ) ) - { - SortDescriptionCollection sortDescriptions = this.Items.SortDescriptions; - SortDescription[] sortDescriptionsCopy = new SortDescription[ sortDescriptions.Count ]; - - sortDescriptions.CopyTo( sortDescriptionsCopy, 0 ); - sortDescriptions.Clear(); - - foreach( SortDescription sortDescription in sortDescriptionsCopy ) - { - sortDescriptions.Add( sortDescription ); - } - } - } - - internal void EnsureRegroup() - { - - if( this.Items.GroupDescriptions.Count > 0 ) - { - ObservableCollection groupDescriptions = this.Items.GroupDescriptions; - GroupDescription[] groupDescriptionsCopy = new GroupDescription[ groupDescriptions.Count ]; - - groupDescriptions.CopyTo( groupDescriptionsCopy, 0 ); - groupDescriptions.Clear(); - - foreach( GroupDescription groupDescription in groupDescriptionsCopy ) - { - groupDescriptions.Add( groupDescription ); - } - } - } - - internal static string GetColumnNameFromGroupDescription( GroupDescription groupDescription ) - { - PropertyGroupDescription propertyGroupDescription = - groupDescription as PropertyGroupDescription; - - if( propertyGroupDescription != null ) - return propertyGroupDescription.PropertyName; - - DataGridGroupDescription dataGridGroupDescription = - groupDescription as DataGridGroupDescription; - - if( dataGridGroupDescription != null ) - return dataGridGroupDescription.PropertyName; - - throw new NotSupportedException( "Group descriptions other than PropertyGroupDescription or DataGridGroupDescription are not supported." ); - } - - internal static ObservableCollection GetGroupDescriptionsHelper( CollectionView collectionView ) - { - ObservableCollection retval = collectionView.GroupDescriptions; - - ItemCollection itemCollection = collectionView as ItemCollection; - - if( itemCollection != null ) - { - CollectionView sourceCollectionView = itemCollection.SourceCollection as CollectionView; - - if( sourceCollectionView != null ) - { - if( sourceCollectionView.GroupDescriptions != null ) - retval = sourceCollectionView.GroupDescriptions; - } - else - { - sourceCollectionView = CollectionViewSource.GetDefaultView( itemCollection.SourceCollection ) as CollectionView; - - if( ( sourceCollectionView != null ) && ( sourceCollectionView.GroupDescriptions != null ) ) - retval = sourceCollectionView.GroupDescriptions; - } - } - - return retval; - } - - internal Group GetGroupFromItem( object dataItem ) - { - return this.CustomItemContainerGenerator.GetGroupFromItem( dataItem ); - } - - internal IDisposable SetQueueBringIntoViewRestrictions( AutoScrollCurrentItemSourceTriggers trigger ) - { - return m_dataGridControl.SetQueueBringIntoViewRestrictions( trigger ); - } - - internal IDisposable InhibitQueueBringIntoView() - { - return m_dataGridControl.InhibitQueueBringIntoView(); - } - - internal IDisposable InhibitSetFocus() - { - return m_dataGridControl.InhibitSetFocus(); - } - - internal void NotifyItemsSourceChanged() - { - this.OnPropertyChanged( "HasDetails" ); - } - - internal void DelayBringIntoViewAndFocusCurrent( AutoScrollCurrentItemSourceTriggers trigger ) - { - m_dataGridControl.DelayBringIntoViewAndFocusCurrent( trigger ); - } - - internal void ResetViewProperties() - { - //Used only for the Print DataGridControl - this.SetupViewProperties(); - this.InitializeViewProperties(); - } - - internal void SetCurrent( - object item, - Row containerRow, - Nullable sourceDataItemIndex, - ColumnBase column, - bool forceFocus, - bool isCancelable, - bool synchronizeSelectionWithCurrent, - AutoScrollCurrentItemSourceTriggers trigger ) - { - // sourceDataItemIndex - // null = item have to be checked if it is a dataItem - // -1 = the item it's not a dataItem - // ? = then index of the item in the source collection. - - //verify that SetCurrent is not called successively caused by actions performed within, this is to prevent - //exceptions caused by the accessing of resources that could be "locked" (e.g., ItemsControl.Items.DeferRefresh) - if( m_dataGridControl.IsSetCurrentInProgress ) - throw new DataGridException( "SetCurrent cannot be invoked while another SetCurrent is in progress.", m_dataGridControl ); - - try - { - //set the flag that indicates that we are already processing a SetCurrent - m_dataGridControl.IsSetCurrentInProgress = true; - - var oldCurrentContext = m_dataGridControl.CurrentContext; - var newCurrentContext = this; - - //store the previous public current item, so I can detect a change and lift the PropertyChanged for this properties - var oldCurrentItem = oldCurrentContext.InternalCurrentItem; - var oldPublicCurrentItem = oldCurrentContext.CurrentItem; - var oldCurrentColumn = oldCurrentContext.CurrentColumn; - var oldCurrentRow = oldCurrentContext.CurrentRow; - - //if item is not realized or if the item passed is not a Data Item (header, footer or group), then the old current cell will be null - var oldCurrentCell = ( oldCurrentRow == null ) ? null : oldCurrentRow.Cells[ oldCurrentColumn ]; - - var newCurrentRow = ( containerRow != null ) ? containerRow : Row.FromContainer( this.GetContainerFromItem( item ) ); - var newCurrentCell = default( Cell ); - - //verify that set Current is not called on a column that cannot be current - if( newCurrentRow != null ) - { - newCurrentCell = newCurrentRow.Cells[ column ]; - if( ( column != null ) && column.ReadOnly && ( newCurrentCell != null ) && !newCurrentCell.GetCalculatedCanBeCurrent() ) - throw new DataGridException( "SetCurrent cannot be invoked if the column cannot be current.", m_dataGridControl ); - } - - var currentCellChanged = ( newCurrentCell != oldCurrentCell ); - - if( ( ( item != oldCurrentItem ) || ( oldCurrentContext != newCurrentContext ) ) && ( oldCurrentRow != null ) ) - { - if( Row.IsCellEditorDisplayConditionsSet( oldCurrentRow, CellEditorDisplayConditions.RowIsCurrent ) ) - { - oldCurrentRow.RemoveDisplayEditorMatchingCondition( CellEditorDisplayConditions.RowIsCurrent ); - } - - oldCurrentRow.SetIsCurrent( false ); - - try - { - oldCurrentRow.EndEdit(); - } - //an error occurred in the end edit - catch( DataGridException ) - { - //restore the Cell and the Row's IsCurrent Flag - if( oldCurrentCell != null ) - { - oldCurrentCell.SetIsCurrent( true ); - } - - oldCurrentRow.SetIsCurrent( true ); - throw; - } - } - - //For this if, the assumption is that current item hasn't changed, but current column has... (previous if will have caught the case where current item changed). - - //if the currentCell has changed and the old current cell still exists. - if( ( currentCellChanged ) && ( oldCurrentCell != null ) ) - { - //clear the CellIsCurrent editor display conditions - if( Cell.IsCellEditorDisplayConditionsSet( oldCurrentCell, CellEditorDisplayConditions.CellIsCurrent ) ) - { - oldCurrentCell.RemoveDisplayEditorMatchingCondition( CellEditorDisplayConditions.CellIsCurrent ); - } - - oldCurrentCell.SetIsCurrent( false ); - - try - { - //cancel any ongoing editing on the cell. (this has no effect if row or cell is not being edited. This line can throw but no action is to be done. - oldCurrentCell.EndEdit(); - } - catch( DataGridException ) - { - oldCurrentCell.SetIsCurrent( true ); - throw; - } - } - - if( ( item != oldCurrentItem ) || ( oldCurrentContext != newCurrentContext ) ) - { - var currentChangingEventArgs = new DataGridCurrentChangingEventArgs( oldCurrentContext, oldCurrentItem, newCurrentContext, item, isCancelable ); - m_dataGridControl.RaiseCurrentChanging( currentChangingEventArgs ); - - if( isCancelable && currentChangingEventArgs.Cancel ) - { - // We restore the currentness on the previous row and cell. - if( oldCurrentRow != null ) - { - if( oldCurrentCell != null ) - { - oldCurrentCell.SetIsCurrent( true ); - } - - oldCurrentRow.SetIsCurrent( true ); - } - - throw new DataGridException( "The operation has been canceled.", m_dataGridControl ); - } - } - - //If they are different, clean the previously current DataGridContext - if( oldCurrentContext != newCurrentContext ) - { - oldCurrentContext.SetCurrentItem( null, -1 ); - oldCurrentContext.SetInternalCurrentItem( null ); - //preserve current column on the old DataGridContext - - oldCurrentContext.SetIsCurrent( false ); - } - - if( !sourceDataItemIndex.HasValue ) - { - sourceDataItemIndex = this.Items.IndexOf( item ); - } - - // All the stuff that can throw is done - newCurrentContext.SetInternalCurrentItem( item ); - newCurrentContext.SetIsCurrent( true ); - - // change the CurrentRow and CurentColumn - if( ( item != null ) && ( sourceDataItemIndex.Value != -1 ) ) - { - newCurrentContext.SetCurrentItem( item, sourceDataItemIndex.Value ); - } - else - { - newCurrentContext.SetCurrentItem( null, -1 ); - } - - newCurrentContext.SetCurrentColumnHelper( column ); - m_dataGridControl.SetCurrentDataGridContextHelper( this ); - - // We must refetch the container for the current item in case EndEdit triggers a reset on the - // CustomItemContainerGenerator and remap this item to a container other than the one previously fetched - newCurrentRow = Row.FromContainer( newCurrentContext.GetContainerFromItem( item ) ); - newCurrentCell = ( newCurrentRow == null ) ? null : newCurrentRow.Cells[ column ]; - - bool currentRowChanged = ( newCurrentRow != oldCurrentRow ); - - //If there is a container for the new Row. - if( newCurrentRow != null ) - { - Debug.Assert( newCurrentRow.IsContainerPrepared, "The container must be prepared to be set as current and call BeginEdit." ); - - //update the RowIsCurrent display condition - if( Row.IsCellEditorDisplayConditionsSet( newCurrentRow, CellEditorDisplayConditions.RowIsCurrent ) ) - { - newCurrentRow.SetDisplayEditorMatchingCondition( CellEditorDisplayConditions.RowIsCurrent ); - } - - //Update the IsCurrent flag - newCurrentRow.SetIsCurrent( true ); - - //if the current row changed, make sure to check the appropriate edition triggers. - if( currentRowChanged == true ) - { - //if EditTriggers tells to enter editing mode AND no current cell is set on the new current row - if( ( newCurrentRow.IsEditTriggerSet( EditTriggers.RowIsCurrent ) ) && ( newCurrentCell == null ) ) - { - //To prevent re-entrancy of the SetCurrent fonction (since Row.BeginEdit will call Cell.BeginEdit which will call SetCurrent if not current already) - if( this.VisibleColumns.Count > 0 ) - { - var firstFocusableColumn = NavigationHelper.GetFirstVisibleFocusableColumnIndex( this, newCurrentRow ); - if( firstFocusableColumn < 0 ) - throw new DataGridException( "Trying to edit while no cell is focusable. ", m_dataGridControl ); - - this.SetCurrentColumnHelper( this.VisibleColumns[ firstFocusableColumn ] ); - newCurrentCell = newCurrentRow.Cells[ m_currentColumn ]; - currentCellChanged = true; - } - } - } - } - - //If current cell exists. - if( newCurrentCell != null ) - { - //update the CellIsCurrent display condition - if( Cell.IsCellEditorDisplayConditionsSet( newCurrentCell, CellEditorDisplayConditions.CellIsCurrent ) ) - { - newCurrentCell.SetDisplayEditorMatchingCondition( CellEditorDisplayConditions.CellIsCurrent ); - } - - newCurrentCell.SetIsCurrent( true ); - - //Then, if the Current Cell has changed or not currently in edition, process the edition conditions. - if( currentCellChanged || !newCurrentCell.IsBeingEdited ) - { - //if the EditTriggers dictate that we should enter edition, do it. - if( ( newCurrentRow.IsEditTriggerSet( EditTriggers.CellIsCurrent ) ) - || ( ( newCurrentRow.IsEditTriggerSet( EditTriggers.RowIsCurrent ) ) && ( currentRowChanged ) ) ) - { - try - { - newCurrentCell.BeginEdit(); - } - catch( DataGridException ) - { - // We swallow the exception if it occurs because the Cell was read-only. - - // Try to begin edit only on the row - try - { - newCurrentRow.BeginEdit(); - } - catch( DataGridException ) - { - // We swallow the exception if it occurs because the Row was read-only. - } - } - } - } - } - - //if there is a new CurrentItem - if( item != null ) - { - //if the container from the new Current item is realized - if( newCurrentRow != null ) - { - if( m_dataGridControl.IsBringIntoViewAllowed( trigger ) ) - { - if( !m_dataGridControl.IsBringIntoViewDelayed ) - { - if( newCurrentCell != null ) - { - newCurrentCell.BringIntoView(); - } - else - { - // Ensure the item is visible visible - newCurrentRow.BringIntoView(); - } - } - else - { - m_dataGridControl.DelayBringIntoViewAndFocusCurrent( trigger ); - } - } - - using( m_dataGridControl.SelectionChangerManager.PushUpdateSelectionSource( SelectionManager.UpdateSelectionSource.None ) ) - { - // Call this to update the Focus to the correct location - m_dataGridControl.SetFocusHelper( newCurrentRow, column, forceFocus, true ); - } - } - else - { - m_dataGridControl.DelayBringIntoViewAndFocusCurrent( trigger ); - } - } - - //Send notification at the end (as much as possible) to ensure that no code bound on the property changed handler will interrupt this sequence - - if( ( synchronizeSelectionWithCurrent ) && ( !m_dataGridControl.SelectionChangerManager.IsActive ) ) - { - m_dataGridControl.SelectionChangerManager.Begin(); - - try - { - if( m_dataGridControl.SelectionUnit == SelectionUnit.Row ) - { - if( newCurrentContext.CurrentItemIndex == -1 ) - { - m_dataGridControl.SelectionChangerManager.UnselectAll(); - } - else - { - m_dataGridControl.SelectionChangerManager.SelectJustThisItem( this, newCurrentContext.CurrentItemIndex, newCurrentContext.CurrentItem ); - } - } - else - { - int currentColumnVisibleIndex = ( newCurrentContext.CurrentColumn == null ) ? -1 : newCurrentContext.CurrentColumn.VisiblePosition; - - if( ( currentColumnVisibleIndex == -1 ) || ( newCurrentContext.CurrentItemIndex == -1 ) ) - { - m_dataGridControl.SelectionChangerManager.UnselectAll(); - } - else - { - m_dataGridControl.SelectionChangerManager.SelectJustThisCell( this, newCurrentContext.CurrentItemIndex, newCurrentContext.CurrentItem, currentColumnVisibleIndex ); - } - } - } - finally - { - m_dataGridControl.SelectionChangerManager.End( false, false ); - } - } - - if( this.CurrentItem != oldPublicCurrentItem ) - { - this.OnPropertyChanged( "CurrentItem" ); - } - - if( column != oldCurrentColumn ) - { - this.OnPropertyChanged( "CurrentColumn" ); - } - - if( ( item != oldCurrentItem ) || ( oldCurrentContext != newCurrentContext ) ) - { - var currentChangedEventArgs = new DataGridCurrentChangedEventArgs( oldCurrentContext, oldCurrentItem, newCurrentContext, item ); - m_dataGridControl.RaiseCurrentChanged( currentChangedEventArgs ); - } - } - finally - { - m_dataGridControl.IsSetCurrentInProgress = false; - } - } - - internal void SetupTitleBindingForGroupLevelDescriptions() - { - foreach( GroupLevelDescription gld in this.GroupLevelDescriptions ) - { - Binding titleBinding = BindingOperations.GetBinding( gld, GroupLevelDescription.TitleProperty ); - - if( titleBinding == null ) - { - ColumnBase column = this.Columns[ gld.FieldName ]; - - if( column != null ) - { - DataGridContext.SetupGroupLevelDescriptionBindings( gld, column ); - } - } - } - } - - internal static void UpdateGroupLevelDescriptions( GroupLevelDescriptionCollection groupLevelDescriptions, - NotifyCollectionChangedEventArgs e, ObservableCollection groupDescriptions, ColumnCollection columns ) - { - switch( e.Action ) - { - case NotifyCollectionChangedAction.Add: - //add all the items added into the GroupLevelDescriptions collection - for( int i = 0; i < e.NewItems.Count; i++ ) - { - GroupLevelDescription newInfo = DataGridContext.CreateGroupLevelDescription( columns, ( GroupDescription )e.NewItems[ i ] ); - - groupLevelDescriptions.Insert( i + e.NewStartingIndex, newInfo ); - } - break; - - case NotifyCollectionChangedAction.Remove: - foreach( GroupDescription desc in e.OldItems ) - { - GroupLevelDescription oldInfo = DataGridContext.GetGroupLevelDescription( groupLevelDescriptions, desc ); - - if( oldInfo != null ) - { - groupLevelDescriptions.Remove( oldInfo ); - } - } - break; - - case NotifyCollectionChangedAction.Reset: - - groupLevelDescriptions.Clear(); - - foreach( GroupDescription desc in groupDescriptions ) - { - GroupLevelDescription newInfo = DataGridContext.CreateGroupLevelDescription( columns, desc ); - - groupLevelDescriptions.Add( newInfo ); - } - - break; - - case NotifyCollectionChangedAction.Move: - - GroupLevelDescription movedGroupLevelDescription = groupLevelDescriptions[ e.OldStartingIndex ]; - groupLevelDescriptions.RemoveAt( e.OldStartingIndex ); - groupLevelDescriptions.Insert( e.NewStartingIndex, movedGroupLevelDescription ); - - break; - - case NotifyCollectionChangedAction.Replace: - - groupLevelDescriptions.RemoveAt( e.OldStartingIndex ); - GroupLevelDescription replaceInfo = DataGridContext.CreateGroupLevelDescription( columns, ( GroupDescription )e.NewItems[ 0 ] ); - - groupLevelDescriptions.Insert( e.NewStartingIndex, replaceInfo ); - - break; - } - } - - internal static DataGridContext SafeGetDataGridContextForDataGridCollectionView( - DataGridContext rootDataGridContext, - DataGridCollectionViewBase targetDataGridCollectionViewBase ) - { - DataGridContext matchingDataGridContext = null; - - DataGridCollectionViewBase rootDataGridCollectionViewBase = rootDataGridContext.ItemsSourceCollection as DataGridCollectionViewBase; - - if( rootDataGridCollectionViewBase != null ) - { - if( rootDataGridCollectionViewBase == targetDataGridCollectionViewBase ) - { - matchingDataGridContext = rootDataGridContext; - } - else - { - matchingDataGridContext = DataGridContext.SafeRecursiveGetDataGridContextForDataGridCollectionViewBase( - rootDataGridContext.GetChildContexts(), - targetDataGridCollectionViewBase ); - } - } - - return matchingDataGridContext; - } - - private static DataGridContext SafeRecursiveGetDataGridContextForDataGridCollectionViewBase( - IEnumerable childDataGridContexts, - DataGridCollectionViewBase targetDataGridCollectionViewBase ) - { - foreach( DataGridContext childDataGridContext in childDataGridContexts ) - { - // Child DataGridContext's Items cannot be anything else than a DataGridCollectionView. - DataGridCollectionViewBase dataGridCollectionViewBase = ( DataGridCollectionViewBase )childDataGridContext.Items; - - if( dataGridCollectionViewBase == targetDataGridCollectionViewBase ) - return childDataGridContext; - - // Deep down. - DataGridContext matchingDataGridContext = DataGridContext.SafeRecursiveGetDataGridContextForDataGridCollectionViewBase( - childDataGridContext.GetChildContexts(), - targetDataGridCollectionViewBase ); - - if( matchingDataGridContext != null ) - return matchingDataGridContext; - } - - return null; - } - - private static void UnselectAllCells( DataGridContext dataGridContext ) - { - if( dataGridContext == null ) - return; - - var selectionManager = dataGridContext.DataGridControl.SelectionChangerManager; - selectionManager.Begin(); - - try - { - selectionManager.UnselectAllCells( dataGridContext ); - } - finally - { - selectionManager.End( false, false ); - } - } - - internal void SaveContainerSizeState( object item, FrameworkElement container ) - { - if( item == null ) - return; - - ContainerSizeState containerSizeState = new ContainerSizeState( container ); - - if( containerSizeState.IsEmpty() == false ) - { - m_sizeStateDictionary[ item ] = containerSizeState; - - DataGridContext.CleanContainerSizeState( container, containerSizeState ); - } - else - { - m_sizeStateDictionary.Remove( item ); - } - } - - internal void RestoreContainerSizeState( object item, FrameworkElement container ) - { - if( item == null ) - return; - - ContainerSizeState containerSizeState; - if( m_sizeStateDictionary.TryGetValue( item, out containerSizeState ) == true ) - { - DataGridContext.RestoreContainerSizeWorker( container, containerSizeState ); - } - } - - internal void ClearSizeStates() - { - m_sizeStateDictionary.Clear(); - } - - /// - /// Gets the current View property value for this DataGridContext. It can either come - /// from a local (attached) value or the value on the view (if the property is "routed"). - /// - /// The return value type of the requested property. - /// The property name on the View. - /// The value of the property if found. Will be ignored if the property is not found. - /// Returns true if the returnValue has been set. False otherwise. - internal bool GetViewPropertyValue( string propertyName, ref T returnValue ) - { - object value = null; - - if( m_viewPropertiesDescriptors != null ) - { - PropertyDescriptor descriptor = m_viewPropertiesDescriptors[ propertyName ]; - - if( descriptor != null ) - value = descriptor.GetValue( this ); - } - - if( value != null ) - { - returnValue = ( T )value; - return true; - } - - return false; - } - - - - //---------- PRIVATE METHODS ---------- - - private void ClearViewPropertyBindings() - { - foreach( Views.ViewBase.ViewPropertyStruct viewProperty in m_viewProperties ) - { - BindingOperations.ClearBinding( this, viewProperty.DependencyProperty ); - this.ClearValue( viewProperty.DependencyProperty ); - } - - m_viewProperties.Clear(); - - //Empty the list of ViewBindingPropertyDescriptor as well. - if( m_viewPropertiesDescriptors != null ) - { - m_viewPropertiesDescriptors.Clear(); - m_viewPropertiesDescriptors = null; - } - } - - private static GroupLevelDescription CreateGroupLevelDescription( ColumnCollection columns, GroupDescription group ) - { - GroupLevelDescription retval = null; - string columnName = DataGridContext.GetColumnNameFromGroupDescription( group ); - - if( !string.IsNullOrEmpty( columnName ) ) - { - retval = new GroupLevelDescription( group, columnName ); - - //find the column for that property name - ColumnBase column = columns[ columnName ]; - - if( column != null ) - { - DataGridContext.SetupGroupLevelDescriptionBindings( retval, column ); - } - else - { - //if no column exists for that name, then use the name as the Title for the GroupLevelDescription - retval.SetTitle( columnName ); - } - } - - return retval; - } - - private Binding CreateViewPropertyBinding( Views.ViewBase view, Views.ViewBase.ViewPropertyStruct viewProperty ) - { - var dependencyProperty = viewProperty.DependencyProperty; - - if( this.IsAFlattenDetail ) - { - switch( viewProperty.FlattenDetailBindingMode ) - { - case FlattenDetailBindingMode.None: - return null; - - case FlattenDetailBindingMode.MasterOneWay: - { - var rootDataGridContext = this.RootDataGridContext; - Debug.Assert( ( rootDataGridContext != null ) && ( this != rootDataGridContext ) ); - return DataGridContext.CreateViewPropertyBindingForSource( rootDataGridContext, dependencyProperty, BindingMode.OneWay ); - } - - default: - break; - } - } - - if( viewProperty.ViewPropertyMode == ViewPropertyMode.ViewOnly ) - return DataGridContext.CreateViewPropertyBindingForSource( view, dependencyProperty ); - - var detailConfiguration = this.SourceDetailConfiguration; - if( detailConfiguration != null ) - { - var defaultDetailConfiguration = this.GetDefaultDetailConfigurationForContext(); - if( defaultDetailConfiguration != null ) - return DataGridContext.CreateViewPropertyBindingForSource( defaultDetailConfiguration, dependencyProperty ); - - return DataGridContext.CreateViewPropertyBindingForSource( detailConfiguration, dependencyProperty ); - } - - return DataGridContext.CreateViewPropertyBindingForSource( view, dependencyProperty ); - } - - private static Binding CreateViewPropertyBindingForSource( object source, DependencyProperty property ) - { - return DataGridContext.CreateViewPropertyBindingForSource( source, property, BindingMode.TwoWay ); - } - - private static Binding CreateViewPropertyBindingForSource( object source, DependencyProperty property, BindingMode bindingMode ) - { - Binding binding = new Binding(); - binding.Source = source; - binding.Path = new PropertyPath( property ); - binding.Mode = bindingMode; - - return binding; - } - - private static GroupLevelDescription GetGroupLevelDescription( GroupLevelDescriptionCollection groupLevelDescriptions, GroupDescription group ) - { - GroupLevelDescription retval = null; - string columnName = DataGridContext.GetColumnNameFromGroupDescription( group ); - - if( string.IsNullOrEmpty( columnName ) == false ) - { - foreach( GroupLevelDescription info in groupLevelDescriptions ) - { - if( info.FieldName == columnName ) - { - retval = info; - break; - } - } - } - - return retval; - } - - internal DefaultDetailConfiguration GetDefaultDetailConfigurationForContext() - { - if( this.AlreadySearchedForDefaultDetailConfig ) - return m_defaultDetailConfiguration; - - m_defaultDetailConfiguration = null; - //start the loop with the current instance. - if( ( this.SourceDetailConfiguration != null ) && ( this.SourceDetailConfiguration.IsAutoCreated == true ) ) - { - DataGridContext currentContext = this; - - do - { - DefaultDetailConfiguration defaultDetailConfig = currentContext.DefaultDetailConfiguration; - if( defaultDetailConfig != null ) - { - m_defaultDetailConfiguration = defaultDetailConfig; - break; - } - - currentContext = currentContext.ParentDataGridContext; - } - while( currentContext != null ); - } - - this.AlreadySearchedForDefaultDetailConfig = true; - return m_defaultDetailConfiguration; - } - - internal void GetRealizedItems( List containers ) - { - lock( containers ) - { - //obtain the IItemContainerGenerator interface of the ItemContainerGenerator (since called many places and it's bothering to always cast). - IItemContainerGenerator generator = this.CustomItemContainerGenerator; - //exception case, I wan to ask for the Generator Interface - - //obtain the GeneratorPosition from the last item in the items collection of the Itemscontrol, this will give me the number of items that are realized. - int itemCount = this.CustomItemContainerGenerator.ItemCount; - - GeneratorPosition lastItemGenPos = generator.GeneratorPositionFromIndex( itemCount - 1 ); - - //the index of the generator position of the last item will indicate the number of realized items. - for( int i = 0; i <= lastItemGenPos.Index; i++ ) - { - //To obtain the Container from the Generator, I need and Index, I can obtain an index from a GeneratorPosition - GeneratorPosition itemGenPos = new GeneratorPosition( i, 0 ); //items with offset == 0 are "realized items" - int itemIndex = generator.IndexFromGeneratorPosition( itemGenPos ); - - object item = this.CustomItemContainerGenerator.ContainerFromIndex( itemIndex ); - - //add the container the the enumerable collection - containers.Add( item ); - } - - //exception case for the master DataGridContext, take the Fixed regions as well - if( m_detailConfig == null ) - { - Panel fixedPanel = m_dataGridControl.FixedHeadersHostPanel; - if( fixedPanel != null ) - { - foreach( object container in fixedPanel.Children ) - { - containers.Add( container ); - } - } - - fixedPanel = m_dataGridControl.FixedFootersHostPanel; - if( fixedPanel != null ) - { - foreach( object container in fixedPanel.Children ) - { - containers.Add( container ); - } - } - } //end if Master DataGridContext - - } - } - - internal static void InsertColumnByVisiblePosition( HashedLinkedList linkedList, ColumnBase columnToInsert ) - { - int requestedPosition = columnToInsert.VisiblePosition; - LinkedListNode columnNode = linkedList.First; - - LinkedListNode insertBeforeNode = null; - ColumnBase column = null; - - // Append columns which VisiblePosition haven't explicitly set - if( columnToInsert.VisiblePosition == int.MaxValue ) - { - linkedList.AddLast( columnToInsert ); - return; - } - - if( linkedList.Count == 0 ) - { - linkedList.AddFirst( columnToInsert ); - } - else - { - while( columnNode != null ) - { - column = columnNode.Value; - - if( column != null ) - { - if( column.VisiblePosition > requestedPosition ) - { - // Insertion point found - insertBeforeNode = columnNode; - break; - } - - columnNode = columnNode.Next; - } - } - - if( insertBeforeNode != null ) - { - linkedList.AddBefore( insertBeforeNode, columnToInsert ); - insertBeforeNode = null; - } - else - { - linkedList.AddLast( columnToInsert ); - } - } - } - - private void MergeDistinctValues( DistinctValuesRequestedEventArgs args ) - { - Debug.Assert( this.Columns[ args.AutoFilterColumnFieldName ] != null ); - - var distinctValues = this.DistinctValues; - if( distinctValues == null ) - return; - - var readOnlyObservableHashList = default( ReadOnlyObservableHashList ); - - // We force the creation of DistinctValues for this field in every DataGridCollectionView - if( distinctValues.TryGetValue( args.AutoFilterColumnFieldName, out readOnlyObservableHashList ) ) - { - foreach( var item in readOnlyObservableHashList ) - { - args.DistinctValues.Add( item ); - } - } - } - - private void OnGroupDescriptionsChanged( object sender, NotifyCollectionChangedEventArgs e ) - { - this.DelayBringIntoViewAndFocusCurrent( AutoScrollCurrentItemSourceTriggers.GroupChanged ); - - DataGridContext.UpdateGroupLevelDescriptions( this.GroupLevelDescriptions, e, this.Items.GroupDescriptions, this.Columns ); - } - - private void OnSortDescriptionsChanged( object sender, NotifyCollectionChangedEventArgs e ) - { - this.DelayBringIntoViewAndFocusCurrent( AutoScrollCurrentItemSourceTriggers.SortChanged ); - - var updateColumnSortCommand = this.UpdateColumnSortCommand; - if( updateColumnSortCommand.CanExecute() ) - { - updateColumnSortCommand.Execute(); - } - } - - private static void SetupGroupLevelDescriptionBindings( GroupLevelDescription groupLevelDescription, ColumnBase column ) - { - //Bind the column title to the GroupLevelDescription title - Binding titleBinding = new Binding(); - titleBinding.Path = new PropertyPath( ColumnBase.TitleProperty ); - titleBinding.Source = column; - titleBinding.Mode = BindingMode.OneWay; - - //Bind the column title template to the GroupLevelDescription title template - Binding titleTemplateBinding = new Binding(); - titleTemplateBinding.Path = - new PropertyPath( ColumnBase.TitleTemplateProperty ); - titleTemplateBinding.Source = column; - titleTemplateBinding.Mode = BindingMode.OneWay; - - //Bind the column title template selector to the GroupLevelDescription title template selector - Binding titleTemplateSelectorBinding = new Binding(); - titleTemplateSelectorBinding.Path = - new PropertyPath( ColumnBase.TitleTemplateSelectorProperty ); - titleTemplateSelectorBinding.Source = column; - titleTemplateSelectorBinding.Mode = BindingMode.OneWay; - - Binding valueTemplateBinding = null; - Binding valueTemplateSelectorBinding = null; - Binding valueStringFormatBinding = null; - Binding valueStringFormatCultureBinding = null; - - Column dataColumn = column as Column; - - // If we have a Column and a ForeignKey is defined - if( ( dataColumn != null ) && ( dataColumn.ForeignKeyConfiguration != null ) ) - { - //Bind the column GroupValueTemplate to the GroupLevelDescription value template - valueTemplateBinding = new Binding(); - valueTemplateBinding.Source = dataColumn; - valueTemplateBinding.Path = new PropertyPath( "(0).(1)", - Column.ForeignKeyConfigurationProperty, - ForeignKeyConfiguration.DefaultGroupValueTemplateProperty ); - valueTemplateBinding.Mode = BindingMode.OneWay; - } - else - { - //Bind the column GroupValueTemplate to the GroupLevelDescription value template - valueTemplateBinding = new Binding(); - valueTemplateBinding.Path = new PropertyPath( ColumnBase.GroupValueTemplateProperty ); - valueTemplateBinding.Source = column; - valueTemplateBinding.Mode = BindingMode.OneWay; - - //Bind the column GroupValueTemplateSelector to the GroupLevelDescription value template selector - valueTemplateSelectorBinding = new Binding(); - valueTemplateSelectorBinding.Path = new PropertyPath( ColumnBase.GroupValueTemplateSelectorProperty ); - valueTemplateSelectorBinding.Source = column; - valueTemplateSelectorBinding.Mode = BindingMode.OneWay; - - //Bind the column GroupValueStringFormat to the GroupLevelDescription string format - valueStringFormatBinding = new Binding(); - valueStringFormatBinding.Path = new PropertyPath( ColumnBase.GroupValueStringFormatProperty ); - valueStringFormatBinding.Source = column; - valueStringFormatBinding.Mode = BindingMode.OneWay; - - //Bind the column DefaultCulture to the GroupLevelDescription string format culture - valueStringFormatCultureBinding = new Binding(); - valueStringFormatCultureBinding.Path = new PropertyPath( ColumnBase.DefaultCultureProperty ); - valueStringFormatCultureBinding.Source = column; - valueStringFormatCultureBinding.Mode = BindingMode.OneWay; - valueStringFormatCultureBinding.TargetNullValue = CultureInfo.CurrentCulture; - } - - BindingOperations.SetBinding( groupLevelDescription, GroupLevelDescription.TitleProperty, titleBinding ); - BindingOperations.SetBinding( groupLevelDescription, GroupLevelDescription.TitleTemplateProperty, titleTemplateBinding ); - BindingOperations.SetBinding( groupLevelDescription, GroupLevelDescription.TitleTemplateSelectorProperty, titleTemplateSelectorBinding ); - BindingOperations.SetBinding( groupLevelDescription, GroupLevelDescription.ValueTemplateProperty, valueTemplateBinding ); - - if( valueStringFormatBinding != null ) - { - BindingOperations.SetBinding( groupLevelDescription, GroupLevelDescription.ValueStringFormatProperty, valueStringFormatBinding ); - } - - if( valueStringFormatCultureBinding != null ) - { - BindingOperations.SetBinding( groupLevelDescription, GroupLevelDescription.ValueStringFormatCultureProperty, valueStringFormatCultureBinding ); - } - - if( valueTemplateSelectorBinding != null ) - { - BindingOperations.SetBinding( groupLevelDescription, GroupLevelDescription.ValueTemplateSelectorProperty, valueTemplateSelectorBinding ); - } - } - - private void HandleMasterColumnsCollectionChanged( NotifyCollectionChangedEventArgs e ) - { - var removeCurrentColumn = false; - var needGeneratorHardReset = false; - var currentColumn = this.CurrentColumn; - - //If( e.Action == Add ), there is nothing to do. - - if( e.Action == NotifyCollectionChangedAction.Reset ) - { - var columns = this.Columns; - - removeCurrentColumn = ( columns == null ) || ( !columns.Contains( currentColumn ) ); - needGeneratorHardReset = true; - } - else if( e.Action == NotifyCollectionChangedAction.Remove ) - { - //Remove of at least the current column - if( e.OldItems.Contains( currentColumn ) ) - { - removeCurrentColumn = true; - needGeneratorHardReset = true; - } - } - else if( e.Action == NotifyCollectionChangedAction.Replace ) - { - //Replace in which at least the current column was "replaced" by another (current column not present in new items ) - if( ( e.OldItems.Contains( currentColumn ) ) && ( !e.NewItems.Contains( currentColumn ) ) ) - { - removeCurrentColumn = true; - needGeneratorHardReset = true; - } - } - //Nothing to do because the way to change the visible position of a column is through its VisiblePosition property. - else if( e.Action == NotifyCollectionChangedAction.Move ) - { - return; - } - - var closestColumn = default( ColumnBase ); - - //Select the current column's closest visible column while its possible - if( removeCurrentColumn ) - { - closestColumn = DataGridContext.GetClosestColumn( currentColumn, this.ColumnsByVisiblePosition ); - } - - // When a column is removed, we need to clear the Generator from every container to avoid problems - // if the column is added again, but using a different instance (i.e. a new column with the same fieldname). - if( needGeneratorHardReset ) - { - // We only reset the fixed region if the column is part of the master context - if( this.SourceDetailConfiguration == null ) - { - this.DataGridControl.ResetFixedRegions(); - } - - this.DataGridControl.CustomItemContainerGenerator.RemoveAllAndNotify(); - } - - this.DefaultImageColumnDetermined = false; - - var updateColumnSortCommand = this.UpdateColumnSortCommand; - if( updateColumnSortCommand.CanExecute() ) - { - this.UpdateColumnSortCommand.Execute(); - } - - if( removeCurrentColumn ) - { - // Now that the columns collections have been updated, it is time to set the new current column if necessary. - // The new current column that was identified earlier may have been removed from the visible columns after the collections update. - if( ( closestColumn != null ) && !this.Columns.Contains( closestColumn ) ) - { - closestColumn = null; - } - - this.SetCurrentColumnCore( closestColumn, false, m_dataGridControl.SynchronizeSelectionWithCurrent, AutoScrollCurrentItemSourceTriggers.ColumnsCollectionChanged ); - } - - ForeignKeyConfiguration.UpdateColumnsForeignKeyConfigurations( this.Columns, - this.ItemsSourceCollection, - m_itemsSourcePropertyDescriptions, - this.AutoCreateForeignKeyConfigurations ); - } - - internal static ColumnBase GetClosestColumn( ColumnBase reference, HashedLinkedList columnsByVisiblePosition ) - { - LinkedListNode oldColumnNode = columnsByVisiblePosition.Find( reference ); - - ColumnBase newColumn = null; - - if( oldColumnNode != null ) - { - LinkedListNode newColumnNode = oldColumnNode.Previous; - - if( newColumnNode == null ) - { - newColumnNode = oldColumnNode.Next; - } - - if( newColumnNode != null ) - { - newColumn = newColumnNode.Value; - } - } - - return newColumn; - } - - private void SetupViewProperties() - { - this.ClearViewPropertyBindings(); - - Views.ViewBase view = m_dataGridControl.GetView(); - if( view == null ) - return; - - var viewProperties = view.GetViewProperties() - .Concat( view.GetSharedProperties() ) - .Concat( view.GetSharedNoFallbackProperties() ); - - foreach( var viewProperty in viewProperties ) - { - var dependencyProperty = viewProperty.DependencyProperty; - Debug.Assert( !dependencyProperty.ReadOnly ); - - Binding binding = this.CreateViewPropertyBinding( view, viewProperty ); - if( binding != null ) - { - BindingOperations.SetBinding( this, dependencyProperty, binding ); - } - - //Note: we place the shared and non-shared properties in the same pool (makes no differences beyond this point ). - m_viewProperties.Add( viewProperty ); - - this.OnPropertyChanged( dependencyProperty.Name ); - } - } - - private void InitializeViewProperties() - { - if( !this.IsAFlattenDetail ) - { - TableflowView.SetFixedColumnSplitterTranslation( this, new TranslateTransform() ); - } - } - - private void HookToItemPropertiesChanged() - { - var collectionView = this.ItemsSourceCollection as DataGridCollectionViewBase; - if( collectionView == null ) - return; - - this.RegisterItemProperties( collectionView.ItemProperties ); - } - - private void UnhookToItemPropertiesChanged( DataGridCollectionViewBase collectionView ) - { - if( collectionView == null ) - return; - - this.UnregisterItemProperties( collectionView.ItemProperties ); - } - - private void UpdateColumns() - { - Debug.Assert( m_detailConfig == null ); - - ItemsSourceHelper.ResetPropertyDescriptions( m_itemsSourcePropertyDescriptions, m_itemPropertyMap, m_dataGridControl, m_dataGridControlItemsSource ); - - if( m_dataGridControl.AutoCreateColumns ) - { - ItemsSourceHelper.UpdateColumnsFromPropertyDescriptions( m_columnManager, m_dataGridControl.DefaultCellEditors, m_itemsSourcePropertyDescriptions, this.AutoCreateForeignKeyConfigurations ); - } - } - - private void RegisterItemProperties( DataGridItemPropertyCollection itemProperties ) - { - if( itemProperties == null ) - return; - - CollectionChangedEventManager.AddListener( itemProperties, this ); - - foreach( var itemProperty in itemProperties ) - { - this.RegisterItemProperty( itemProperty ); - } - } - - private void UnregisterItemProperties( DataGridItemPropertyCollection itemProperties ) - { - if( itemProperties == null ) - return; - - foreach( var itemProperty in itemProperties ) - { - this.UnregisterItemProperty( itemProperty ); - } - - CollectionChangedEventManager.RemoveListener( itemProperties, this ); - } - - private void RegisterItemProperty( DataGridItemPropertyBase itemProperty ) - { - if( itemProperty == null ) - return; - - PropertyChangedEventManager.AddListener( itemProperty, this, DataGridItemPropertyBase.ItemPropertiesInternalPropertyName ); - this.RegisterItemProperties( itemProperty.ItemPropertiesInternal ); - } - - private void UnregisterItemProperty( DataGridItemPropertyBase itemProperty ) - { - if( itemProperty == null ) - return; - - this.UnregisterItemProperties( itemProperty.ItemPropertiesInternal ); - PropertyChangedEventManager.RemoveListener( itemProperty, this, DataGridItemPropertyBase.ItemPropertiesInternalPropertyName ); - } - - private void OnItemPropertiesCollectionChanged( DataGridItemPropertyCollection collection, NotifyCollectionChangedEventArgs e ) - { - Debug.Assert( m_detailConfig == null ); - - var rootCollection = ItemsSourceHelper.GetRootCollection( collection ); - if( rootCollection == null ) - return; - - if( rootCollection == ( ( DataGridCollectionViewBase )m_dataGridControlItemsSource ).ItemProperties ) - { - if( e.Action == NotifyCollectionChangedAction.Reset ) - throw new NotSupportedException(); - - if( e.Action == NotifyCollectionChangedAction.Move ) - return; - - if( e.OldItems != null ) - { - foreach( DataGridItemPropertyBase itemProperty in e.OldItems ) - { - this.UnregisterItemProperty( itemProperty ); - } - } - - if( e.NewItems != null ) - { - foreach( DataGridItemPropertyBase itemProperty in e.NewItems ) - { - this.RegisterItemProperty( itemProperty ); - } - } - - this.UpdateColumns(); - } - else - { - Debug.Fail( "The collection is not linked to the collection view's item properties." ); - this.UnregisterItemProperties( collection ); - } - } - - private void OnItemPropertyPropertyChanged( DataGridItemPropertyBase itemProperty, PropertyChangedEventArgs e ) - { - Debug.Assert( m_detailConfig == null ); - - var rootCollection = ItemsSourceHelper.GetRootCollection( itemProperty ); - if( rootCollection == null ) - return; - - if( rootCollection != ( ( DataGridCollectionViewBase )m_dataGridControlItemsSource ).ItemProperties ) - { - Debug.Fail( "The collection is not linked to the detail configuration's item properties." ); - this.UnregisterItemProperty( itemProperty ); - return; - } - - if( string.IsNullOrEmpty( e.PropertyName ) || ( e.PropertyName == DataGridItemPropertyBase.ItemPropertiesInternalPropertyName ) ) - { - var itemProperties = itemProperty.ItemPropertiesInternal; - if( itemProperties != null ) - { - this.UnregisterItemProperties( itemProperties ); - this.RegisterItemProperties( itemProperties ); - this.UpdateColumns(); - } - } - } - - private void OnDetailConfigRequestingDelayBringIntoViewAndFocusCurrent( object sender, RequestingDelayBringIntoViewAndFocusCurrentEventArgs e ) - { - if( !this.IsCurrent ) - return; - - this.DelayBringIntoViewAndFocusCurrent( e.Trigger ); - } - - private static void CleanContainerSizeState( FrameworkElement container, ContainerSizeState containerSizeState ) - { - if( containerSizeState.Height != DependencyProperty.UnsetValue ) - container.ClearValue( FrameworkElement.HeightProperty ); - - if( containerSizeState.Width != DependencyProperty.UnsetValue ) - container.ClearValue( FrameworkElement.WidthProperty ); - - if( containerSizeState.MinHeight != DependencyProperty.UnsetValue ) - container.ClearValue( FrameworkElement.MinHeightProperty ); - - if( containerSizeState.MinWidth != DependencyProperty.UnsetValue ) - container.ClearValue( FrameworkElement.MinWidthProperty ); - - if( containerSizeState.MaxHeight != DependencyProperty.UnsetValue ) - container.ClearValue( FrameworkElement.MaxHeightProperty ); - - if( containerSizeState.MaxWidth != DependencyProperty.UnsetValue ) - container.ClearValue( FrameworkElement.MaxWidthProperty ); - } - - private static void RestoreContainerSizeWorker( FrameworkElement container, ContainerSizeState sizeState ) - { - if( sizeState.Height != DependencyProperty.UnsetValue ) - container.SetValue( FrameworkElement.HeightProperty, sizeState.Height ); - - if( sizeState.Width != DependencyProperty.UnsetValue ) - container.SetValue( FrameworkElement.WidthProperty, sizeState.Width ); - - if( sizeState.MinHeight != DependencyProperty.UnsetValue ) - container.SetValue( FrameworkElement.MinHeightProperty, sizeState.MinHeight ); - - if( sizeState.MinWidth != DependencyProperty.UnsetValue ) - container.SetValue( FrameworkElement.MinWidthProperty, sizeState.MinWidth ); - - if( sizeState.MaxHeight != DependencyProperty.UnsetValue ) - container.SetValue( FrameworkElement.MaxHeightProperty, sizeState.MaxHeight ); - - if( sizeState.MaxWidth != DependencyProperty.UnsetValue ) - container.SetValue( FrameworkElement.MaxWidthProperty, sizeState.MaxWidth ); - } - - //---------- OVERRIDES ---------- - - protected override void OnPropertyChanged( DependencyPropertyChangedEventArgs e ) - { - base.OnPropertyChanged( e ); - this.OnPropertyChanged( e.Property.Name ); - } - - //---------- INTERFACES ---------- - - #region INotifyPropertyChanged Members - - public event PropertyChangedEventHandler PropertyChanged; - - private void OnPropertyChanged( string propertyName ) - { - var handler = this.PropertyChanged; - if( handler == null ) - return; - - handler.Invoke( this, new PropertyChangedEventArgs( propertyName ) ); - } - - #endregion - - #region IWeakEventListener Members - - bool IWeakEventListener.ReceiveWeakEvent( Type managerType, object sender, EventArgs e ) - { - return this.OnReceiveWeakEvent( managerType, sender, e ); - } - - private bool OnReceiveWeakEvent( Type managerType, object sender, EventArgs e ) - { - if( managerType == typeof( CollectionChangedEventManager ) ) - { - var eventArgs = ( NotifyCollectionChangedEventArgs )e; - - if( sender == m_items ) - { - var args = eventArgs.GetRangeActionOrSelf(); - - this.Items_CollectionChanged( sender, args ); - } - if( sender == this.DetailConfigurations ) - { - this.OnPropertyChanged( "HasDetails" ); - } - else if( sender == m_columnManager.Columns ) - { - //Master Level columns collection changed - this.HandleMasterColumnsCollectionChanged( eventArgs ); - } - else if( sender == this.VisibleColumns ) - { - var mode = ColumnStretchMode.None; - - if( this.GetViewPropertyValue( "ColumnStretchMode", ref mode ) ) - { - if( ( mode == ColumnStretchMode.First ) || ( mode == ColumnStretchMode.Last ) ) - { - if( eventArgs.NewItems != null ) - { - foreach( ColumnBase column in eventArgs.NewItems ) - { - column.ClearValue( ColumnBase.DesiredWidthProperty ); - } - } - } - } - } - else if( sender == m_items.SortDescriptions ) - { - this.OnSortDescriptionsChanged( sender, eventArgs ); - } - else if( sender == m_items.GroupDescriptions ) - { - this.OnGroupDescriptionsChanged( sender, eventArgs ); - } - else if( sender is DataGridItemPropertyCollection ) - { - this.OnItemPropertiesCollectionChanged( ( DataGridItemPropertyCollection )sender, eventArgs ); - } - } - else if( managerType == typeof( PropertyChangedEventManager ) ) - { - var eventArgs = ( PropertyChangedEventArgs )e; - - if( sender is DataGridItemPropertyBase ) - { - this.OnItemPropertyPropertyChanged( ( DataGridItemPropertyBase )sender, eventArgs ); - } - } - else if( managerType == typeof( ColumnsLayoutChangingEventManager ) ) - { - DataGridContext.UnselectAllCells( this ); - } - else if( managerType == typeof( ColumnsLayoutChangedEventManager ) ) - { - // Only force a reset if at least one Row has not used an IVirtualizingCellsHost as PART_CellsHost - if( m_dataGridControl.ForceGeneratorReset ) - { - //forces the collection view to refresh (therefore, regenerates all the items ). - this.CustomItemContainerGenerator.RemoveAllAndNotify(); - - if( this.SourceDetailConfiguration == null ) // not linked to a DetailConfiguration (master level) - { - //also notify the DataGridControl so it can clear the fixed regions - m_dataGridControl.ResetFixedRegions(); - } - } - - this.DefaultImageColumnDetermined = false; - } - else if( managerType == typeof( PreBatchCollectionChangedEventManager ) ) - { - Debug.Assert( m_deferSelectionChangedOnItemsCollectionChanged == null ); - - // When using DataGridVirtualizingCollectionViewBase, we should keep the "Replace" action - // in order to call UpdateSelectionAfterSourceCollectionChanged with a Replace instead of a Reset. - if( m_deferSelectionChangedOnItemsCollectionChanged == null && !( sender is DataGridVirtualizingCollectionViewBase ) ) - { - m_deferSelectionChangedOnItemsCollectionChanged = new DeferSelectionChangedOnItemsCollectionChangedDisposable( this ); - } - } - else if( managerType == typeof( PostBatchCollectionChangedEventManager ) ) - { - var disposable = m_deferSelectionChangedOnItemsCollectionChanged; - if( disposable != null ) - { - m_deferSelectionChangedOnItemsCollectionChanged = null; - disposable.Dispose(); - } - } - else if( managerType == typeof( RealizedContainersRequestedEventManager ) ) - { - var eventArgs = ( RealizedContainersRequestedEventArgs )e; - this.GetRealizedItems( eventArgs.RealizedContainers ); - } - else if( managerType == typeof( DistinctValuesRequestedEventManager ) ) - { - var eventArgs = ( DistinctValuesRequestedEventArgs )e; - this.MergeDistinctValues( eventArgs ); - } - else if( managerType == typeof( AllowDetailToggleChangedEventManager ) ) - { - this.OnPropertyChanged( "AllowDetailToggle" ); - } - else if( managerType == typeof( ViewChangedEventManager ) ) - { - this.SetupViewProperties(); - this.InitializeViewProperties(); - } - else if( managerType == typeof( CurrentColumnChangedEventManager ) ) - { - this.OnPropertyChanged( "CurrentColumn" ); - } - else if( managerType == typeof( GroupConfigurationSelectorChangedEventManager ) ) - { - this.OnGroupConfigurationSelectorChanged(); - } - else if( managerType == typeof( DetailVisibilityChangedEventManager ) ) - { - this.OnPropertyChanged( "HasDetails" ); - } - else if( managerType == typeof( MaxGroupLevelsChangedEventManager ) ) - { - this.OnPropertyChanged( "MaxGroupLevels" ); - } - else if( managerType == typeof( MaxSortLevelsChangedEventManager ) ) - { - this.OnPropertyChanged( "MaxSortLevels" ); - } - else if( managerType == typeof( ItemsSourceChangeCompletedEventManager ) ) - { - var dataGridCollectionViewBase = m_dataGridControlItemsSource as DataGridCollectionViewBase; - - // GenerateColumnsFromItemsSourceFields is already done in DataGridControl.ProcessDelayedItemsSourceChanged no need to do it here. - this.UnhookToItemPropertiesChanged( dataGridCollectionViewBase ); - - if( dataGridCollectionViewBase != null ) - { - PreBatchCollectionChangedEventManager.RemoveListener( dataGridCollectionViewBase, this ); - PostBatchCollectionChangedEventManager.RemoveListener( dataGridCollectionViewBase, this ); - } - - m_dataGridControlItemsSource = m_dataGridControl.ItemsSource; - - dataGridCollectionViewBase = m_dataGridControlItemsSource as DataGridCollectionViewBase; - if( dataGridCollectionViewBase != null ) - { - PreBatchCollectionChangedEventManager.AddListener( dataGridCollectionViewBase, this ); - PostBatchCollectionChangedEventManager.AddListener( dataGridCollectionViewBase, this ); - } - - this.HookToItemPropertiesChanged(); - - //If this is the master level DataGridContext - if( m_parentDataGridContext == null ) - { - //And if this is a DataGridCollectionView - DataGridCollectionView collectionView = m_dataGridControlItemsSource as DataGridCollectionView; - if( collectionView != null ) - { - //Set its dataGridContext so it can propagate a DeferRefresh to details' DataGridCollectionViews - collectionView.PrepareRootContextForDeferRefresh( this ); - } - } - } - else - { - return false; - } - - return true; - } - - #endregion - - #region Private Fields - - private BitVector32 m_flags = new BitVector32(); - private readonly CurrencyManager m_currencyManager; - private readonly ICollection m_viewProperties = new List(); - private PropertyDescriptorCollection m_viewPropertiesDescriptors; // = null - private DefaultDetailConfiguration m_defaultDetailConfiguration; // = null - private ColumnBase m_defaultImageColumn; // = null - private int m_deferRestoreStateCount; // = 0; - private readonly Dictionary m_sizeStateDictionary = new Dictionary(); - private IEnumerable m_dataGridControlItemsSource; - private DeferSelectionChangedOnItemsCollectionChangedDisposable m_deferSelectionChangedOnItemsCollectionChanged; // = null - - #endregion - - #region IDataGridContextVisitable Members - - void IDataGridContextVisitable.AcceptVisitor( IDataGridContextVisitor visitor, out bool visitWasStopped ) - { - ( ( IDataGridContextVisitable )this.CustomItemContainerGenerator ).AcceptVisitor( visitor, out visitWasStopped ); - } - - void IDataGridContextVisitable.AcceptVisitor( int minIndex, int maxIndex, IDataGridContextVisitor visitor, out bool visitWasStopped ) - { - ( ( IDataGridContextVisitable )this.CustomItemContainerGenerator ).AcceptVisitor( minIndex, maxIndex, visitor, out visitWasStopped ); - } - - void IDataGridContextVisitable.AcceptVisitor( int minIndex, int maxIndex, IDataGridContextVisitor visitor, DataGridContextVisitorType visitorType, out bool visitWasStopped ) - { - ( ( IDataGridContextVisitable )this.CustomItemContainerGenerator ).AcceptVisitor( minIndex, maxIndex, visitor, visitorType, out visitWasStopped ); - } - - void IDataGridContextVisitable.AcceptVisitor( int minIndex, int maxIndex, IDataGridContextVisitor visitor, DataGridContextVisitorType visitorType, bool visitDetails, out bool visitWasStopped ) - { - ( ( IDataGridContextVisitable )this.CustomItemContainerGenerator ).AcceptVisitor( minIndex, maxIndex, visitor, visitorType, visitDetails, out visitWasStopped ); - } - - #endregion - - #region ICustomTypeDescriptor Members - - AttributeCollection ICustomTypeDescriptor.GetAttributes() - { - return AttributeCollection.Empty; - } - - string ICustomTypeDescriptor.GetClassName() - { - return null; - } - - string ICustomTypeDescriptor.GetComponentName() - { - return null; - } - - TypeConverter ICustomTypeDescriptor.GetConverter() - { - return null; - } - - EventDescriptor ICustomTypeDescriptor.GetDefaultEvent() - { - return null; - } - - PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty() - { - return null; - } - - object ICustomTypeDescriptor.GetEditor( Type editorBaseType ) - { - return null; - } - - EventDescriptorCollection ICustomTypeDescriptor.GetEvents( Attribute[] attributes ) - { - return EventDescriptorCollection.Empty; - } - - EventDescriptorCollection ICustomTypeDescriptor.GetEvents() - { - return EventDescriptorCollection.Empty; - } - - PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties( Attribute[] attributes ) - { - if( attributes == null ) - { - // We only cache the full property list. - if( m_viewPropertiesDescriptors == null ) - { - var view = m_dataGridControl.GetView(); - Debug.Assert( view != null ); - - if( view == null ) - return PropertyDescriptorCollection.Empty; - - var properties = new ViewBindingPropertyDescriptor[ m_viewProperties.Count ]; - var defaultDetailConfiguration = this.GetDefaultDetailConfigurationForContext(); - var index = 0; - - foreach( var property in m_viewProperties ) - { - properties[ index ] = new ViewBindingPropertyDescriptor( m_detailConfig, defaultDetailConfiguration, view, property.DependencyProperty, property.ViewPropertyMode ); - index++; - } - - m_viewPropertiesDescriptors = new PropertyDescriptorCollection( properties ); - } - - return m_viewPropertiesDescriptors; - } - - return PropertyDescriptorCollection.Empty; - } - - PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties() - { - return ( ( ICustomTypeDescriptor )this ).GetProperties( null ); - } - - object ICustomTypeDescriptor.GetPropertyOwner( PropertyDescriptor pd ) - { - return this; - } - - #endregion - - //---------- SUB CLASSES ---------- - - #region DeferRestoreStateDisposable Private Class - - private sealed class DeferRestoreStateDisposable : IDisposable - { - internal DeferRestoreStateDisposable( DataGridContext dataGridContext ) - { - if( dataGridContext == null ) - throw new ArgumentNullException( "dataGridContext" ); - - m_dataGridContext = new WeakReference( dataGridContext ); - - Interlocked.Increment( ref dataGridContext.m_deferRestoreStateCount ); - } - - void IDisposable.Dispose() - { - this.Dispose( true ); - GC.SuppressFinalize( this ); - } - - private void Dispose( bool disposing ) - { - var wr = Interlocked.Exchange( ref m_dataGridContext, null ); - if( wr == null ) - return; - - var dataGridContext = ( DataGridContext )wr.Target; - if( dataGridContext == null ) - return; - - if( Interlocked.Decrement( ref dataGridContext.m_deferRestoreStateCount ) != 0 ) - return; - - Debug.Assert( disposing ); - - var dataGridControl = dataGridContext.DataGridControl; - dataGridControl.RestoreDataGridContextState( dataGridContext ); - } - - ~DeferRestoreStateDisposable() - { - this.Dispose( false ); - } - - private WeakReference m_dataGridContext; - } - - #endregion - - #region DeferSelectionChangedOnItemsCollectionChangedDisposable Private Class - - private sealed class DeferSelectionChangedOnItemsCollectionChangedDisposable : IDisposable - { - internal DeferSelectionChangedOnItemsCollectionChangedDisposable( DataGridContext dataGridContext ) - { - if( dataGridContext == null ) - throw new ArgumentNullException( "dataGridContext" ); - - m_dataGridContext = new WeakReference( dataGridContext ); - } - - internal void Queue( NotifyCollectionChangedEventArgs e ) - { - if( e == null ) - return; - - if( m_eventArgs != null ) - { - m_eventArgs = NotifyBatchCollectionChangedEventArgs.Combine( m_eventArgs, e ); - } - else - { - m_eventArgs = e; - } - } - - public void Dispose() - { - this.Dispose( true ); - GC.SuppressFinalize( this ); - } - - private void Dispose( bool disposing ) - { - if( !disposing ) - return; - - var wr = Interlocked.Exchange( ref m_dataGridContext, null ); - if( wr == null ) - return; - - var eventArgs = m_eventArgs; - if( eventArgs == null ) - return; - - var dataGridContext = ( DataGridContext )wr.Target; - if( dataGridContext == null ) - return; - - dataGridContext.UpdateSelectionAfterSourceCollectionChanged( eventArgs ); - } - - private WeakReference m_dataGridContext; - private NotifyCollectionChangedEventArgs m_eventArgs; //null - } - - #endregion - - #region ViewBindingPropertyDescriptor Private Class - - private class ViewBindingPropertyDescriptor : PropertyDescriptor - { - public ViewBindingPropertyDescriptor( DetailConfiguration detailConfig, DefaultDetailConfiguration defaultDetailConfig, Views.ViewBase view, DependencyProperty dp, ViewPropertyMode viewPropertyMode ) - : base( dp.Name, null ) - { - if( dp == null ) - throw new ArgumentNullException( "dp" ); - - if( view == null ) - throw new ArgumentNullException( "view" ); - - if( viewPropertyMode == ViewPropertyMode.None ) - throw new ArgumentException( "viewPropertyMode cannot be ViewPropertyMode.None", "mode" ); - - m_dp = dp; - m_detailConfig = detailConfig; - m_defaultDetailConfig = defaultDetailConfig; - m_view = view; - m_viewPropertyMode = viewPropertyMode; - } - - #region DependencyProperty Read-Only Property - - public DependencyProperty DependencyProperty - { - get - { - return m_dp; - } - } - - private DependencyProperty m_dp; // = null - - #endregion - - #region DetailConfig Read-Only Property - - public DetailConfiguration DetailConfig - { - get - { - return m_detailConfig; - } - } - - private DetailConfiguration m_detailConfig; - - #endregion - - #region DefaultDetailConfig Read-Only Property - - public DefaultDetailConfiguration DefaultDetailConfig - { - get - { - return m_defaultDetailConfig; - } - } - - private DefaultDetailConfiguration m_defaultDetailConfig; - - #endregion - - #region View Read-Only Property - - public Views.ViewBase View - { - get - { - return m_view; - } - } - - private Views.ViewBase m_view; - - #endregion - - #region ViewPropertyMode Read-Only Property - - public ViewPropertyMode ViewPropertyMode - { - get - { - return m_viewPropertyMode; - } - } - - private ViewPropertyMode m_viewPropertyMode; - - #endregion - - public override bool CanResetValue( object component ) - { - return false; //stubbing this so that value cannot be reset through the PropertyDescriptor - } - - public override Type ComponentType - { - get - { - return typeof( DataGridContext ); - } - } - - public override object GetValue( object component ) - { - if( m_viewPropertyMode == ViewPropertyMode.Routed ) - { - var source = ( DependencyObject )m_defaultDetailConfig ?? m_detailConfig; - - //If there is a DefaultDetailConfig, process it in precedence to the DetailConfig. - if( source != null ) - { - var valueSource = DependencyPropertyHelper.GetValueSource( source, m_dp ); - - switch( valueSource.BaseValueSource ) - { - // Pick the value on the view. - case BaseValueSource.Default: - case BaseValueSource.Inherited: - case BaseValueSource.Unknown: - return m_view.GetValue( m_dp ); - - // Pick the value on the source component itself. - default: - break; - } - } - } - - var dependencyObject = component as DependencyObject; - if( dependencyObject != null ) - return dependencyObject.GetValue( m_dp ); - - return null; - } - - public override bool IsReadOnly - { - get - { - return m_dp.ReadOnly; - } - } - - public override Type PropertyType - { - get - { - return m_dp.PropertyType; - } - } - - public override void ResetValue( object component ) - { - throw new InvalidOperationException(); - } - - public override void SetValue( object component, object value ) - { - var dependencyObject = component as DependencyObject; - if( dependencyObject == null ) - throw new ArgumentException( "SetValue was called for an object which is not a DependencyObject.", component.ToString() ); - - dependencyObject.SetValue( m_dp, value ); - } - - public override bool ShouldSerializeValue( object component ) - { - return false; - } - } - - #endregion - - #region DataGridContextToggleColumnSortCommand Private Class - - private sealed class DataGridContextToggleColumnSortCommand : ToggleColumnSortCommand - { - #region Constructor - - internal DataGridContextToggleColumnSortCommand( DataGridContext dataGridContext ) - : base() - { - ToggleColumnSortCommand.ThrowIfNull( dataGridContext, "dataGridContext" ); - - m_dataGridContext = new WeakReference( dataGridContext ); - } - - #endregion - - #region Properties - - #region CanSort Protected Property - - protected override bool CanSort - { - get - { - var dataGridContext = this.DataGridContext; - if( this.DataGridContext == null ) - return false; - - return this.DataGridContext.Items.CanSort; - } - } - - #endregion - - #region Columns Protected Property - - protected override ColumnCollection Columns - { - get - { - return this.DataGridContext.Columns; - } - } - - #endregion - - #region DataGridContext Protected Property - - protected override DataGridContext DataGridContext - { - get - { - return ( m_dataGridContext != null ) ? m_dataGridContext.Target as DataGridContext : null; - } - } - - private readonly WeakReference m_dataGridContext; - - #endregion - - #region MaxSortLevels Protected Property - - protected override int MaxSortLevels - { - get - { - return this.DataGridContext.MaxSortLevels; - } - } - - #endregion - - #region SortDescriptions Protected Property - - protected override SortDescriptionCollection SortDescriptions - { - get - { - return this.DataGridContext.Items.SortDescriptions; - } - } - - #endregion - - #endregion - - #region Methods Override - - protected override bool CanExecuteCore( ColumnBase column, bool resetSort ) - { - var dataGridContext = this.DataGridContext; - if( dataGridContext == null ) - return false; - - return base.CanExecuteCore( column, resetSort ); - } - - protected override void ValidateToggleColumnSort() - { - var dataGridContext = this.DataGridContext; - if( dataGridContext == null ) - return; - - Debug.Assert( !dataGridContext.IsAFlattenDetail, "A flatten detail should not be able to toggle the column sort direction." ); - } - - protected override SortDescriptionsSyncContext GetSortDescriptionsSyncContext() - { - var dataGridContext = this.DataGridContext; - - ToggleColumnSortCommand.ThrowIfNull( dataGridContext, "dataGridContext" ); - return dataGridContext.SortDescriptionsSyncContext; - } - - protected override void ValidateSynchronizationContext( SynchronizationContext synchronizationContext ) - { - var dataGridContext = this.DataGridContext; - ToggleColumnSortCommand.ThrowIfNull( dataGridContext, "dataGridContext" ); - - if( !synchronizationContext.Own ) - throw new DataGridInternalException( "The column is already being processed.", dataGridContext.DataGridControl ); - } - - protected override void DeferRestoreStateOnLevel( Disposer disposer ) - { - var dataGridContext = this.DataGridContext; - ToggleColumnSortCommand.ThrowIfNull( dataGridContext, "dataGridContext" ); - - ToggleColumnSortCommand.DeferRestoreStateOnLevel( disposer, dataGridContext ); - } - - protected override IDisposable SetQueueBringIntoViewRestrictions( AutoScrollCurrentItemSourceTriggers triggers ) - { - var dataGridContext = this.DataGridContext; - if( dataGridContext == null ) - return null; - - return this.DataGridContext.SetQueueBringIntoViewRestrictions( triggers ); - } - - protected override bool TryDeferResortSourceDetailConfiguration( out IDisposable defer ) - { - var dataGridContext = this.DataGridContext; - ToggleColumnSortCommand.ThrowIfNull( dataGridContext, "dataGridContext" ); - - return this.TryDeferResort( dataGridContext.SourceDetailConfiguration, out defer ); - } - - protected override IDisposable DeferResortHelperItemsSourceCollection() - { - var dataGridContext = this.DataGridContext; - ToggleColumnSortCommand.ThrowIfNull( dataGridContext, "dataGridContext" ); - - return this.DeferResortHelper( dataGridContext.ItemsSourceCollection, dataGridContext.Items ); - } - - protected override void UpdateColumnSort() - { - var dataGridContext = this.DataGridContext; - Debug.Assert( dataGridContext != null ); - - base.UpdateColumnSort(); - } - - #endregion - } - - #endregion - - #region DataGridContextUpdateColumnSortCommand Private Class - - private sealed class DataGridContextUpdateColumnSortCommand : UpdateColumnSortCommand - { - #region Validation Methods - - private static void ThrowIfDetailDataGridContext( DataGridContext dataGridContext, string paramName ) - { - Debug.Assert( dataGridContext != null ); - - if( dataGridContext.ParentDataGridContext != null ) - throw new ArgumentException( "The DataGridContext is not the topmost DataGridContext.", paramName ); - } - - #endregion - - #region Constructor - - internal DataGridContextUpdateColumnSortCommand( DataGridContext dataGridContext ) - { - DataGridContextUpdateColumnSortCommand.ThrowIfNull( dataGridContext, "dataGridContext" ); - - m_dataGridContext = new WeakReference( dataGridContext ); - } - - #endregion - - #region SortDescriptionsSyncContext Protected Property - - protected override SortDescriptionsSyncContext SortDescriptionsSyncContext - { - get - { - var dataGridContext = this.DataGridContext; - if( dataGridContext == null ) - return null; - - return dataGridContext.SortDescriptionsSyncContext; - } - } - - #endregion - - #region DataGridContext Private Property - - private DataGridContext DataGridContext - { - get - { - return m_dataGridContext.Target as DataGridContext; - } - } - - private readonly WeakReference m_dataGridContext; - - #endregion - - protected override bool CanExecuteCore() - { - return ( this.DataGridContext != null ); - } - - protected override void ExecuteCore() - { - var dataGridContext = this.DataGridContext; - if( dataGridContext == null ) - return; - - var detailConfiguration = dataGridContext.SourceDetailConfiguration; - if( detailConfiguration != null ) - { - this.Update( detailConfiguration ); - } - // The current DataGridContext is the top most DataGridContext; - else - { - this.Update( dataGridContext ); - } - } - - private void Update( DataGridContext dataGridContext ) - { - ColumnSortCommand.ThrowIfNull( dataGridContext, "dataGridContext" ); - DataGridContextUpdateColumnSortCommand.ThrowIfDetailDataGridContext( dataGridContext, "dataGridContext" ); - - // The sort order of the flatten details is driven by the master. A sort order change - // on the master must be reflected in the details. - if( dataGridContext.AreDetailsFlatten ) - { - foreach( var detailConfiguration in dataGridContext.DetailConfigurations ) - { - this.Update( detailConfiguration, true ); - } - } - - using( var synchronizationContext = this.StartSynchronizing( dataGridContext.SortDescriptionsSyncContext ) ) - { - this.SynchronizeColumnSort( - synchronizationContext, - dataGridContext.Items.SortDescriptions, - dataGridContext.Columns ); - } - } - - private void Update( DetailConfiguration detailConfiguration ) - { - this.Update( detailConfiguration, false ); - } - - private void Update( DetailConfiguration detailConfiguration, bool recursive ) - { - ColumnSortCommand.ThrowIfNull( detailConfiguration, "detailConfiguration" ); - - if( recursive ) - { - foreach( var children in detailConfiguration.DetailConfigurations ) - { - this.Update( children, true ); - } - } - - var command = detailConfiguration.UpdateColumnSortCommand; - if( command.CanExecute() ) - { - command.Execute(); - } - } - } - - #endregion - - #region DataGridContextAddGroupCommand Private Class - - private sealed class DataGridContextAddGroupCommand : ColumnAddGroupCommand - { - #region Constructor - - internal DataGridContextAddGroupCommand( DataGridContext dataGridContext ) - { - DataGridContextAddGroupCommand.ThrowIfNull( dataGridContext, "dataGridContext" ); - - m_dataGridContext = new WeakReference( dataGridContext ); - } - - #endregion - - #region GroupDescriptions Protected Property - - protected override ObservableCollection GroupDescriptions - { - get - { - var dataGridContext = this.DataGridContext; - if( dataGridContext == null ) - return null; - - return dataGridContext.Items.GroupDescriptions; - } - } - - #endregion - - #region DataGridContext Private Property - - private DataGridContext DataGridContext - { - get - { - return m_dataGridContext.Target as DataGridContext; - } - } - - private readonly WeakReference m_dataGridContext; - - #endregion - - protected override string GetColumnName( ColumnBase column ) - { - var dataGridContext = this.DataGridContext; - if( ( dataGridContext == null ) || ( column == null ) ) - return null; - - var itemPropertyMap = dataGridContext.ItemPropertyMap; - if( ( itemPropertyMap != null ) && itemPropertyMap.IsMapping ) - { - string fieldName; - if( DataGridItemPropertyMapHelper.TryGetDetailColumnName( itemPropertyMap, column.FieldName, out fieldName ) ) - return fieldName; - } - else - { - return column.FieldName; - } - - return null; - } - - protected override GroupDescription GetGroupDescription( ColumnBase column ) - { - if( this.DataGridContext == null ) - return null; - - return base.GetGroupDescription( column ); - } - - protected override GroupConfiguration GetGroupConfiguration( ColumnBase column ) - { - if( this.DataGridContext == null ) - return null; - - return base.GetGroupConfiguration( column ); - } - - protected override bool CanExecuteCore( ColumnBase column, int index ) - { - if( this.DataGridContext == null ) - return false; - - return base.CanExecuteCore( column, index ); - } - - protected override void ExecuteCore( ColumnBase column, int index ) - { - var dataGridContext = this.DataGridContext; - if( dataGridContext == null ) - return; - - using( dataGridContext.SetQueueBringIntoViewRestrictions( AutoScrollCurrentItemSourceTriggers.CollectionViewCurrentItemChanged ) ) - { - base.ExecuteCore( column, index ); - } - } - } - - #endregion - - #region DataGridContextFlags Private Enum - - [Flags] - private enum DataGridContextFlags - { - AlreadySearchedForDetailConfig = 1, - DefaultImageColumnDetermined = 2, - IsCurrent = 4, - IsRestoringState = 8, - IsSavingState = 16, - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridControl.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridControl.cs deleted file mode 100644 index 50d4c3dd..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridControl.cs +++ /dev/null @@ -1,6850 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Data; -using System.Diagnostics; -using System.Linq; -using System.Printing; -using System.Security; -using System.Security.Permissions; -using System.Windows; -using System.Windows.Automation.Peers; -using System.Windows.Controls; -using System.Windows.Controls.Primitives; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Threading; -using Xceed.Utils.Wpf; -using Xceed.Utils.Wpf.DragDrop; -using Xceed.Wpf.DataGrid.Export; -using Xceed.Wpf.DataGrid.Utils; -using Xceed.Wpf.DataGrid.Views; - -namespace Xceed.Wpf.DataGrid -{ - [TemplatePart( Name = "PART_ScrollViewer", Type = typeof( ScrollViewer ) )] - [StyleTypedProperty( Property = "ItemContainerStyle", StyleTargetType = typeof( DataRow ) )] // Blend has to be able to create an instance of this for the style edition so it can't be typeof( Row ) - [StyleTypedProperty( Property = "CellErrorStyle", StyleTargetType = typeof( Cell ) )] - public partial class DataGridControl : ItemsControl, INotifyPropertyChanged, IDocumentPaginatorSource, IWeakEventListener - { - #region Static Fields - - internal static readonly string SelectionModeToUsePropertyName = PropertyHelper.GetPropertyName( ( DataGridControl d ) => d.SelectionModeToUse ); - - #endregion - - static DataGridControl() - { - FrameworkElement.DefaultStyleKeyProperty.OverrideMetadata( typeof( DataGridControl ), new FrameworkPropertyMetadata( TableflowView.GetDefaultStyleKey( typeof( TableflowView ), typeof( DataGridControl ) ) ) ); - - ItemsControl.ItemsSourceProperty.OverrideMetadata( typeof( DataGridControl ), new FrameworkPropertyMetadata( null, new CoerceValueCallback( DataGridControl.ItemsSourceCoerceCallback ) ) ); - ItemsControl.GroupStyleSelectorProperty.OverrideMetadata( typeof( DataGridControl ), new FrameworkPropertyMetadata( new PropertyChangedCallback( OnGroupStyleSelectorChanged ) ) ); - - KeyboardNavigation.DirectionalNavigationProperty.OverrideMetadata( typeof( DataGridControl ), new FrameworkPropertyMetadata( KeyboardNavigationMode.Contained ) ); - KeyboardNavigation.TabNavigationProperty.OverrideMetadata( typeof( DataGridControl ), new FrameworkPropertyMetadata( KeyboardNavigationMode.None ) ); - - FrameworkElement.FlowDirectionProperty.OverrideMetadata( typeof( DataGridControl ), new FrameworkPropertyMetadata( new PropertyChangedCallback( DataGridControl.OnFlowDirectionPropertyChanged ) ) ); - - DataGridControl.ColumnsProperty = DataGridControl.ColumnsPropertyKey.DependencyProperty; - DataGridControl.VisibleColumnsProperty = DataGridControl.VisibleColumnsPropertyKey.DependencyProperty; - DataGridControl.SelectedItemsProperty = DataGridControl.SelectedItemsPropertyKey.DependencyProperty; - DataGridControl.SelectedItemRangesProperty = DataGridControl.SelectedItemRangesPropertyKey.DependencyProperty; - DataGridControl.SelectedCellRangesProperty = DataGridControl.SelectedCellRangesPropertyKey.DependencyProperty; - DataGridControl.ParentDataGridControlProperty = DataGridControl.ParentDataGridControlPropertyKey.DependencyProperty; - DataGridControl.DataGridContextProperty = DataGridControl.DataGridContextPropertyKey.DependencyProperty; - DataGridControl.StatContextProperty = DataGridControl.StatContextPropertyKey.DependencyProperty; - DataGridControl.GroupLevelDescriptionsProperty = DataGridControl.GroupLevelDescriptionsPropertyKey.DependencyProperty; - DataGridControl.HasExpandedDetailsProperty = DataGridControl.HasExpandedDetailsPropertyKey.DependencyProperty; - } - - public DataGridControl() - { - m_selectionChangerManager = new SelectionManager( this ); - m_columnManagerRowConfiguration = new ColumnManagerRowConfiguration(); - - this.SetValue( DataGridControl.ParentDataGridControlPropertyKey, this ); - - //set the FixedItem for the gridControl to NotSet, this is to prevent problems with nested DataGridControls - DataGridControl.SetFixedItem( this, DataGridControl.NotSet ); - - this.CommandBindings.Add( new CommandBinding( DataGridCommands.ExpandGroup, this.OnExpandGroupExecuted, this.OnExpandGroupCanExecute ) ); - this.CommandBindings.Add( new CommandBinding( DataGridCommands.CollapseGroup, this.OnCollapseGroupExecuted, this.OnCollapseGroupCanExecute ) ); - this.CommandBindings.Add( new CommandBinding( DataGridCommands.ToggleGroupExpansion, this.OnToggleGroupExecuted, this.OnToggleGroupCanExecute ) ); - this.CommandBindings.Add( new CommandBinding( ApplicationCommands.SelectAll, this.OnSelectAllExecuted, this.OnSelectAllCanExecute ) ); - - // We keep a references to be able to remove the CommandBindings when they are not required (feature disabled) - m_refreshCommandBinding = new CommandBinding( DataGridCommands.Refresh, this.OnRefreshExecuted, this.OnRefreshCanExecute ); - this.CommandBindings.Add( m_refreshCommandBinding ); - - // We keep a references to be able to remove the CommandBindings when they are not required (feature disabled) - m_copyCommandBinding = new CommandBinding( ApplicationCommands.Copy, this.OnCopyExecuted, this.OnCopyCanExecute ); - this.CommandBindings.Add( m_copyCommandBinding ); - - // The delete command is not enabled by default, so don't add it to CommandBindings - m_deleteCommandBinding = new CommandBinding( ApplicationCommands.Delete, this.OnDeleteExecuted, this.OnDeleteCanExecute ); - - DataGridContext dataGridContext = new DataGridContext( null, this, null, this.Items, null ); - m_customItemContainerGenerator = CustomItemContainerGenerator.CreateGenerator( this, this.Items, dataGridContext ); - m_customItemContainerGenerator.DetailsChanged += OnDetailsChanged; - - DataGridControl.SetDataGridContext( this, dataGridContext ); - m_localDataGridContext = dataGridContext; - - //so that at least one DataGridContext is always current - dataGridContext.SetIsCurrent( true ); - this.SetCurrentDataGridContextHelper( dataGridContext ); - - this.SetValue( DataGridControl.ColumnsPropertyKey, dataGridContext.Columns ); - this.SetValue( DataGridControl.VisibleColumnsPropertyKey, dataGridContext.VisibleColumns ); - this.SetValue( DataGridControl.GroupLevelDescriptionsPropertyKey, dataGridContext.GroupLevelDescriptions ); - this.SetValue( DataGridControl.SelectedItemsPropertyKey, dataGridContext.SelectedItems ); - this.SetValue( DataGridControl.SelectedItemRangesPropertyKey, new SelectionItemRangeCollection( dataGridContext.SelectedItemsStore ) ); - this.SetValue( DataGridControl.SelectedCellRangesPropertyKey, new SelectionCellRangeCollection( dataGridContext.SelectedCellsStore ) ); - - // Apparently, we don't need to unsubscribe from these event handlers. These event - // subscriptions do not "root" the grid and we observed no leak cause be these. - // We did not investigate why that is and we should keep an eye on it. - this.GroupStyle.CollectionChanged += new NotifyCollectionChangedEventHandler( GroupStyle_CollectionChanged ); - - - if( DesignerProperties.GetIsInDesignMode( this ) ) - { - // Workaround for VS2008's know issue (the DataGrid's Template is not active). - this.ClipToBounds = true; - } - - this.Loaded += new RoutedEventHandler( DataGridControl_Loaded ); - } - - #region INITIALIZATION - - public override void BeginInit() - { - m_initCount++; - if( m_initCount != 1 ) - return; - - Debug.Assert( m_deferColumnsUpdate == null ); - m_deferColumnsUpdate = this.DataGridContext.DeferColumnsUpdate(); - Debug.Assert( m_deferColumnsUpdate != null ); - - m_deferColumnsNotifications = this.Columns.DeferNotifications(); - - var dataGridCollectionViewBase = this.DataGridContext.Items as DataGridCollectionViewBase; - if( dataGridCollectionViewBase != null ) - { - m_deferItemPropertiesUpdate = dataGridCollectionViewBase.ItemProperties.DeferCollectionChanged(); - } - - base.BeginInit(); - } - - public override void EndInit() - { - m_initCount--; - if( m_initCount != 0 ) - return; - - // Set a view if none is set at this point. This will also make sure that eventual implicit style declarations for the default View in user applications will work. - if( this.View == null ) - { - this.View = this.GetDefaultView() as UIViewBase; - } - - if( this.ItemsSourceChangedDelayed ) - { - this.ItemsSourceChangedDelayed = false; - this.ProcessDelayedItemsSourceChanged(); - } - - var dataGridContext = this.DataGridContext; - var columnManager = dataGridContext.ColumnManager; - - columnManager.Initialize( this ); - columnManager.SetFixedColumnCount( TableView.GetFixedColumnCount( dataGridContext ) ); - - //see if any of the GroupLevelDescriptions are matched to a column but aren't bound ( case 102437 ) and update then (bind them) if necessary - dataGridContext.SetupTitleBindingForGroupLevelDescriptions(); - - if( m_deferItemPropertiesUpdate != null ) - { - var collectionViewDisposable = m_deferItemPropertiesUpdate; - m_deferItemPropertiesUpdate = null; - collectionViewDisposable.Dispose(); - } - - var columnsNotificationsDisposable = m_deferColumnsNotifications; - m_deferColumnsNotifications = null; - columnsNotificationsDisposable.Dispose(); - - Debug.Assert( m_deferColumnsUpdate != null ); - var columnsUpdateDisposable = m_deferColumnsUpdate; - m_deferColumnsUpdate = null; - columnsUpdateDisposable.Dispose(); - - m_customItemContainerGenerator.ForceReset = true; - - base.EndInit(); - } - - private void DataGridControl_Loaded( object sender, RoutedEventArgs e ) - { - this.InvalidateViewStyle(); - - // Always set this as ParentDataGridControl to stop inheritance - // when a grid is inside a another grid - this.SetValue( ParentDataGridControlPropertyKey, this ); - this.HookToUnloaded(); - - // The layout pass was inhibited while the DataGridControl was unloaded - // to make the parent control load faster. A new layout pass - // must be forced to render the datagrid content correctly. The layout - // pass isn't inhibited when the grid is use for printing purpose. - if( ( this.DeferInitialLayoutPass ) && ( m_isFirstTimeLoaded ) ) - { - m_isFirstTimeLoaded = false; - - this.Dispatcher.BeginInvoke( new Action( this.InvalidateMeasure ) ); - } - } - - private void HookToUnloaded() - { - this.UnhookToUnloaded(); - - m_parentWindow = null; - FrameworkElement parentWindow; - DependencyObject parent = this; - - do - { - parent = TreeHelper.GetParent( parent ); - parentWindow = parent as Window; - - if( parentWindow == null ) - { - parentWindow = parent as Page; - } - } while( ( parent != null ) && ( parentWindow == null ) ); - - if( parentWindow == null ) - { - parentWindow = this; - } - else - { - m_parentWindow = new WeakReference( parentWindow ); - } - - FrameworkElementUnloadedEventManager.AddListener( parentWindow, this ); - } - - private void UnhookToUnloaded() - { - var parentWindow = ( m_parentWindow != null ) ? m_parentWindow.Target as FrameworkElement : this; - if( parentWindow == null ) - return; - - FrameworkElementUnloadedEventManager.RemoveListener( parentWindow, this ); - } - - private int m_initCount; //0 - private IDisposable m_deferColumnsUpdate; //null - private IDisposable m_deferColumnsNotifications; //null - private IDisposable m_deferItemPropertiesUpdate; //null - - #endregion - - #region ParentDataGridControl Attached Property - - internal static readonly DependencyPropertyKey ParentDataGridControlPropertyKey = DependencyProperty.RegisterAttachedReadOnly( - "ParentDataGridControl", - typeof( DataGridControl ), - typeof( DataGridControl ), - new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.Inherits ) ); - - public static readonly DependencyProperty ParentDataGridControlProperty; - - [Obsolete( "GetParentDataGridControl is obsolete. Use DataGridContext.DataGridControl instead" )] - public static DataGridControl GetParentDataGridControl( DependencyObject obj ) - { - return ( DataGridControl )obj.GetValue( DataGridControl.ParentDataGridControlProperty ); - } - - #endregion - - #region DataGridContext Attached Property - - internal static readonly DependencyPropertyKey DataGridContextPropertyKey = DependencyProperty.RegisterAttachedReadOnly( - "DataGridContext", - typeof( DataGridContext ), - typeof( DataGridControl ), - new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.Inherits ) ); - - public static readonly DependencyProperty DataGridContextProperty; - - public static DataGridContext GetDataGridContext( DependencyObject obj ) - { - return ( DataGridContext )obj.GetValue( DataGridControl.DataGridContextProperty ); - } - - internal static void SetDataGridContext( DependencyObject obj, DataGridContext value ) - { - obj.SetValue( DataGridControl.DataGridContextPropertyKey, value ); - } - - private readonly DataGridContext m_localDataGridContext; // = null - - #endregion - - #region Container Attached Property - - private static readonly DependencyPropertyKey ContainerPropertyKey = DependencyProperty.RegisterAttachedReadOnly( - "Container", - typeof( FrameworkElement ), - typeof( DataGridControl ), - new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.Inherits ) ); - - public static readonly DependencyProperty ContainerProperty = DataGridControl.ContainerPropertyKey.DependencyProperty; - - public static FrameworkElement GetContainer( DependencyObject obj ) - { - return ( FrameworkElement )obj.GetValue( DataGridControl.ContainerProperty ); - } - - internal static void SetContainer( DependencyObject obj, object value ) - { - obj.SetValue( DataGridControl.ContainerPropertyKey, value ); - } - - internal static void ClearContainer( DependencyObject obj ) - { - obj.ClearValue( DataGridControl.ContainerPropertyKey ); - } - - #endregion - - #region IsContainerPrepared Attached Property - - private static readonly DependencyPropertyKey IsContainerPreparedPropertyKey = DependencyProperty.RegisterAttachedReadOnly( - "IsContainerPrepared", - typeof( bool ), - typeof( DataGridControl ), - new FrameworkPropertyMetadata( false ) ); - - private static readonly DependencyProperty IsContainerPreparedProperty = DataGridControl.IsContainerPreparedPropertyKey.DependencyProperty; - - internal static bool GetIsContainerPrepared( DependencyObject obj ) - { - return ( bool )obj.GetValue( DataGridControl.IsContainerPreparedProperty ); - } - - private static void SetIsContainerPrepared( DependencyObject obj, bool value ) - { - obj.SetValue( DataGridControl.IsContainerPreparedPropertyKey, value ); - } - - private static void ClearIsContainerPrepared( DependencyObject obj ) - { - obj.ClearValue( DataGridControl.IsContainerPreparedPropertyKey ); - } - - #endregion - - #region StatContext Attached Property - - internal static readonly DependencyPropertyKey StatContextPropertyKey = DependencyProperty.RegisterAttachedReadOnly( - "StatContext", - typeof( object ), - typeof( DataGridControl ), - new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.Inherits ) ); - - public static readonly DependencyProperty StatContextProperty; - - public static object GetStatContext( DependencyObject obj ) - { - return obj.GetValue( DataGridControl.StatContextProperty ); - } - - internal static void SetStatContext( DependencyObject obj, object statContext ) - { - obj.SetValue( DataGridControl.StatContextPropertyKey, statContext ); - } - - #endregion - - #region HasExpandedDetails Attached Property - - internal static readonly DependencyPropertyKey HasExpandedDetailsPropertyKey = DependencyProperty.RegisterAttachedReadOnly( - "HasExpandedDetails", - typeof( bool ), - typeof( DataGridControl ), - new FrameworkPropertyMetadata( false, FrameworkPropertyMetadataOptions.Inherits ) ); - - public static readonly DependencyProperty HasExpandedDetailsProperty; - - public static bool GetHasExpandedDetails( DependencyObject obj ) - { - return ( bool )obj.GetValue( DataGridControl.HasExpandedDetailsProperty ); - } - - internal static void SetHasExpandedDetails( DependencyObject obj, bool value ) - { - obj.SetValue( DataGridControl.HasExpandedDetailsPropertyKey, value ); - } - - #endregion - - #region Columns Read-Only Property - - private static readonly DependencyPropertyKey ColumnsPropertyKey = DependencyProperty.RegisterReadOnly( - "Columns", - typeof( ColumnCollection ), - typeof( DataGridControl ), - new PropertyMetadata( null ) ); - - public static readonly DependencyProperty ColumnsProperty; - - public ColumnCollection Columns - { - get - { - return ( ColumnCollection )this.GetValue( DataGridControl.ColumnsProperty ); - } - } - - #endregion - - #region VisibleColumns Read-Only Property - - private static readonly DependencyPropertyKey VisibleColumnsPropertyKey = DependencyProperty.RegisterAttachedReadOnly( - "VisibleColumns", - typeof( ReadOnlyObservableCollection ), - typeof( DataGridControl ), - new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.Inherits ) ); - - public static readonly DependencyProperty VisibleColumnsProperty; - - // VisibleColumns is a ReadOnlyObservableCollection because it would be too confusing to - // have a ColumnCollection. For instance, if somebody would have set the VisiblePosition - // of some columns and then used VisibleColumns.Insert to add them in the collection - // at the right place, what should hold the real visible index value? The VisiblePosition - // property or the index in the VisibleColumns collection? - public ReadOnlyObservableCollection VisibleColumns - { - get - { - return ( ReadOnlyObservableCollection )this.GetValue( DataGridControl.VisibleColumnsProperty ); - } - } - - #endregion - - #region ColumnsByVisiblePosition Read-Only Property - - internal HashedLinkedList ColumnsByVisiblePosition - { - get - { - return this.DataGridContext.ColumnsByVisiblePosition; - } - } - - #endregion - - #region CellEditorDisplayConditions Property - - public static readonly DependencyProperty CellEditorDisplayConditionsProperty = DependencyProperty.RegisterAttached( - "CellEditorDisplayConditions", - typeof( CellEditorDisplayConditions ), - typeof( DataGridControl ), - new FrameworkPropertyMetadata( CellEditorDisplayConditions.None, FrameworkPropertyMetadataOptions.Inherits ) ); - - public CellEditorDisplayConditions CellEditorDisplayConditions - { - get - { - return ( CellEditorDisplayConditions )this.GetValue( DataGridControl.CellEditorDisplayConditionsProperty ); - } - set - { - this.SetValue( DataGridControl.CellEditorDisplayConditionsProperty, value ); - } - } - - #endregion - - #region DefaultCellEditors Property - - public Dictionary DefaultCellEditors - { - get - { - return m_defaultCellEditors; - } - } - - private readonly Dictionary m_defaultCellEditors = new Dictionary(); - - #endregion - - #region CellErrorStyle Property - - public static readonly DependencyProperty CellErrorStyleProperty = DependencyProperty.RegisterAttached( - "CellErrorStyle", - typeof( Style ), - typeof( DataGridControl ), - new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.Inherits ) ); - - public Style CellErrorStyle - { - get - { - return ( Style )this.GetValue( DataGridControl.CellErrorStyleProperty ); - } - - set - { - this.SetValue( DataGridControl.CellErrorStyleProperty, value ); - } - } - - #endregion - - #region HasValidationError Property - - private static readonly DependencyPropertyKey HasValidationErrorPropertyKey = DependencyProperty.RegisterReadOnly( - "HasValidationError", - typeof( bool ), - typeof( DataGridControl ), - new UIPropertyMetadata( false ) ); - - public static readonly DependencyProperty HasValidationErrorProperty = DataGridControl.HasValidationErrorPropertyKey.DependencyProperty; - - public bool HasValidationError - { - get - { - return ( bool )this.GetValue( DataGridControl.HasValidationErrorProperty ); - } - } - - internal void SetHasValidationError( bool value ) - { - if( value != this.HasValidationError ) - { - if( value ) - { - this.SetValue( DataGridControl.HasValidationErrorPropertyKey, value ); - } - else - { - this.SetValue( DataGridControl.HasValidationErrorPropertyKey, DependencyProperty.UnsetValue ); - } - } - } - - #endregion - - #region ValidationMode Property - - [Obsolete( "The ValidationMode is obsolete. Refer to the Editing and Validating Data topic in the documentation.", true )] - public static readonly DependencyProperty ValidationModeProperty = DependencyProperty.Register( - "ValidationMode", - typeof( ValidationMode ), - typeof( DataGridControl ), - new UIPropertyMetadata( ValidationMode.RowEndingEdit ) ); - - [Obsolete( "The ValidationMode is obsolete. Refer to the Editing and Validating Data topic in the documentation.", true )] - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - public ValidationMode ValidationMode - { - get - { - return ValidationMode.RowEndingEdit; - } - set - { - } - } - - #endregion - - #region SelectedItems Read-Only Property - - private static readonly DependencyPropertyKey SelectedItemsPropertyKey = DependencyProperty.RegisterReadOnly( - "SelectedItems", - typeof( IList ), - typeof( DataGridControl ), - new PropertyMetadata( null ) ); - - public static readonly DependencyProperty SelectedItemsProperty; - - public IList SelectedItems - { - get - { - return ( IList )this.GetValue( DataGridControl.SelectedItemsProperty ); - } - } - - #endregion - - #region SelectedRanges Read-Only Property - - private static readonly DependencyPropertyKey SelectedItemRangesPropertyKey = DependencyProperty.RegisterReadOnly( - "SelectedItemRanges", - typeof( IList ), - typeof( DataGridControl ), - new PropertyMetadata( null ) ); - - public static readonly DependencyProperty SelectedItemRangesProperty; - - public IList SelectedItemRanges - { - get - { - return ( IList )this.GetValue( DataGridControl.SelectedItemRangesProperty ); - } - } - - #endregion - - #region SelectedCellRanges Read-Only Property - - private static readonly DependencyPropertyKey SelectedCellRangesPropertyKey = DependencyProperty.RegisterReadOnly( - "SelectedCellRanges", - typeof( IList ), - typeof( DataGridControl ), - new PropertyMetadata( null ) ); - - public static readonly DependencyProperty SelectedCellRangesProperty; - - public IList SelectedCellRanges - { - get - { - return ( IList )this.GetValue( DataGridControl.SelectedCellRangesProperty ); - } - } - - #endregion - - #region SelectedItem Property - - public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register( - "SelectedItem", - typeof( object ), - typeof( DataGridControl ), - new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback( DataGridControl.OnSelectedItemChanged ), new CoerceValueCallback( DataGridControl.OnCoerceSelectedItem ) ) ); - - public object SelectedItem - { - get - { - return this.GetValue( DataGridControl.SelectedItemProperty ); - } - set - { - this.SetValue( DataGridControl.SelectedItemProperty, value ); - } - } - - internal void SetSkipCoerceSelectedItemCheck( bool value ) - { - m_skipCoerceSelectedItemCheck = value; - } - - private static object OnCoerceSelectedItem( DependencyObject sender, object value ) - { - var self = sender as DataGridControl; - if( self == null ) - return value; - - if( ( value != null ) && ( !self.m_skipCoerceSelectedItemCheck ) ) - { - if( !self.Items.Contains( value ) ) - { - self.SelectedItemPropertyNeedCoerce = true; - return DependencyProperty.UnsetValue; - } - } - - self.SelectedItemPropertyNeedCoerce = false; - return value; - } - - private static void OnSelectedItemChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var self = sender as DataGridControl; - if( ( self == null ) || self.m_selectionChangerManager.IsActive ) - return; - - self.m_selectionChangerManager.Begin(); - - try - { - if( e.NewValue == null ) - { - self.m_selectionChangerManager.UnselectAll(); - } - else - { - self.m_selectionChangerManager.SelectJustThisItem( self.DataGridContext, self.Items.IndexOf( e.NewValue ), e.NewValue ); - } - } - finally - { - self.m_selectionChangerManager.End( false, true ); - } - } - - private bool m_skipCoerceSelectedItemCheck; - - #endregion - - #region SelectedIndex Property - - public static readonly DependencyProperty SelectedIndexProperty = DependencyProperty.Register( - "SelectedIndex", - typeof( int ), - typeof( DataGridControl ), - new FrameworkPropertyMetadata( -1, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback( DataGridControl.OnSelectedIndexChanged ), new CoerceValueCallback( DataGridControl.OnCoerceSelectedIndex ) ) ); - - public int SelectedIndex - { - get - { - return ( int )this.GetValue( DataGridControl.SelectedIndexProperty ); - } - set - { - this.SetValue( DataGridControl.SelectedIndexProperty, value ); - } - } - - private static object OnCoerceSelectedIndex( DependencyObject sender, object value ) - { - var self = sender as DataGridControl; - if( self == null ) - return value; - - var newValue = ( int )value; - - if( ( newValue < -1 ) || ( newValue >= self.Items.Count ) ) - { - self.SelectedIndexPropertyNeedCoerce = true; - return DependencyProperty.UnsetValue; - } - - self.SelectedIndexPropertyNeedCoerce = false; - return value; - } - - private static void OnSelectedIndexChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var self = sender as DataGridControl; - if( ( self == null ) || self.m_selectionChangerManager.IsActive ) - return; - - var newValue = ( int )e.NewValue; - - self.m_selectionChangerManager.Begin(); - - try - { - if( ( newValue >= 0 ) && ( newValue < self.Items.Count ) ) - { - //affect the item as the new selection - self.m_selectionChangerManager.SelectJustThisItem( self.DataGridContext, newValue, self.Items[ newValue ] ); - } - else - { - //clear the selection. - self.m_selectionChangerManager.UnselectAll(); - } - } - finally - { - self.m_selectionChangerManager.End( false, true ); - } - } - - #endregion - - #region GlobalSelectedItems Read-Only Property - - public IEnumerable GlobalSelectedItems - { - get - { - foreach( var context in this.SelectedContexts ) - { - foreach( var selectedItem in context.SelectedItems ) - { - yield return selectedItem; - } - } - } - } - - internal void NotifyGlobalSelectedItemsChanged() - { - this.OnPropertyChanged( "GlobalSelectedItems" ); - } - - #endregion - - #region SelectedContexts Read-Only Property - - public ReadOnlyCollection SelectedContexts - { - get - { - if( m_readOnlySelectedContexts == null ) - { - m_readOnlySelectedContexts = new ReadOnlyCollection( m_selectedContexts ); - } - - return m_readOnlySelectedContexts; - } - } - - private readonly List m_selectedContexts = new List(); - private ReadOnlyCollection m_readOnlySelectedContexts; - - #endregion - - #region SelectionMode Property - - public static readonly DependencyProperty SelectionModeProperty = DependencyProperty.Register( - "SelectionMode", - typeof( SelectionMode ), - typeof( DataGridControl ), - new UIPropertyMetadata( SelectionMode.Extended, new PropertyChangedCallback( DataGridControl.OnSelectionModeChanged ) ) ); - - public SelectionMode SelectionMode - { - get - { - return ( SelectionMode )this.GetValue( DataGridControl.SelectionModeProperty ); - } - set - { - this.SetValue( DataGridControl.SelectionModeProperty, value ); - } - } - - internal SelectionMode SelectionModeToUse - { - get - { - return this.SelectionMode; - } - } - - private static void OnSelectionModeChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var self = sender as DataGridControl; - if( self == null ) - return; - } - - #endregion - - #region SelectionUnit Property - - public static readonly DependencyProperty SelectionUnitProperty = DependencyProperty.Register( - "SelectionUnit", - typeof( SelectionUnit ), - typeof( DataGridControl ), - new UIPropertyMetadata( SelectionUnit.Row, new PropertyChangedCallback( DataGridControl.OnSelectionUnitChanged ) ) ); - - public SelectionUnit SelectionUnit - { - get - { - return ( SelectionUnit )this.GetValue( DataGridControl.SelectionUnitProperty ); - } - set - { - this.SetValue( DataGridControl.SelectionUnitProperty, value ); - } - } - - private static void OnSelectionUnitChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var self = sender as DataGridControl; - if( self == null ) - return; - - var selectionUnit = ( SelectionUnit )e.NewValue; - - self.m_selectionChangerManager.Begin(); - - try - { - switch( selectionUnit ) - { - case SelectionUnit.Row: - { - self.m_selectionChangerManager.UnselectAllCells(); - break; - } - case SelectionUnit.Cell: - { - self.m_selectionChangerManager.UnselectAllItems(); - break; - } - } - } - finally - { - self.m_selectionChangerManager.End( false, true ); - } - } - - #endregion - - #region CurrentItem Property - - public object CurrentItem - { - get - { - return this.DataGridContext.CurrentItem; - } - set - { - if( value == this.DataGridContext.CurrentItem ) - return; - - this.DataGridContext.SetCurrent( value, null, null, this.DataGridContext.CurrentColumn, false, true, this.SynchronizeSelectionWithCurrent, AutoScrollCurrentItemSourceTriggers.CurrentItemChanged ); - } - } - - internal bool ShouldSynchronizeCurrentItem - { - get - { - return ( this.SynchronizeCurrent ); - } - } - - #endregion - - #region CurrentColumn Property - - public ColumnBase CurrentColumn - { - get - { - return this.DataGridContext.CurrentColumn; - } - set - { - if( value == this.DataGridContext.CurrentColumn ) - return; - - this.DataGridContext.SetCurrent( this.DataGridContext.InternalCurrentItem, null, null, value, false, true, this.SynchronizeSelectionWithCurrent, AutoScrollCurrentItemSourceTriggers.CurrentColumnChanged ); - } - } - - #endregion - - #region CurrentContext Property - - public DataGridContext CurrentContext - { - get - { - Debug.Assert( m_currentDataGridContext != null ); - - return m_currentDataGridContext; - } - } - - internal void SetCurrentDataGridContextHelper( DataGridContext value ) - { - m_currentDataGridContext = value; - - this.OnPropertyChanged( "CurrentContext" ); - this.OnPropertyChanged( "CurrentColumn" ); - this.OnPropertyChanged( "CurrentItem" ); - this.OnPropertyChanged( "GlobalCurrentItem" ); - this.OnPropertyChanged( "GlobalCurrentColumn" ); - } - - private DataGridContext m_currentDataGridContext; // = null - - #endregion - - #region GlobalCurrentItem Read-Only Property - - public object GlobalCurrentItem - { - get - { - return this.CurrentContext.CurrentItem; - } - } - - #endregion - - #region GlobalCurrentColumn Read-Only Property - - public ColumnBase GlobalCurrentColumn - { - get - { - return this.CurrentContext.CurrentColumn; - } - } - - #endregion - - #region DragDropAdornerDecorator Property - - internal AdornerDecorator DragDropAdornerDecorator - { - get - { - return m_dragDropAdornerDecorator; - } - } - - private AdornerDecorator m_dragDropAdornerDecorator; - - #endregion - - #region AutoCreateColumns Property - - public static readonly DependencyProperty AutoCreateColumnsProperty = DependencyProperty.Register( - "AutoCreateColumns", - typeof( bool ), - typeof( DataGridControl ), - new UIPropertyMetadata( true ) ); - - public bool AutoCreateColumns - { - get - { - return ( bool )this.GetValue( DataGridControl.AutoCreateColumnsProperty ); - } - set - { - this.SetValue( DataGridControl.AutoCreateColumnsProperty, value ); - } - } - - #endregion - - #region AutoCreateForeignKeyConfigurations Property - - public static readonly DependencyProperty AutoCreateForeignKeyConfigurationsProperty = DependencyProperty.Register( - "AutoCreateForeignKeyConfigurations", - typeof( bool ), - typeof( DataGridControl ), - new FrameworkPropertyMetadata( - ( bool )false, - new PropertyChangedCallback( DataGridControl.OnAutoCreateForeignKeyConfigurationsChanged ) ) ); - - public bool AutoCreateForeignKeyConfigurations - { - get - { - return ( bool )this.GetValue( DataGridControl.AutoCreateForeignKeyConfigurationsProperty ); - } - set - { - this.SetValue( DataGridControl.AutoCreateForeignKeyConfigurationsProperty, value ); - } - } - - private static void OnAutoCreateForeignKeyConfigurationsChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var self = sender as DataGridControl; - if( ( self == null ) || !self.AutoCreateForeignKeyConfigurations ) - return; - - self.SynchronizeForeignKeyConfigurations(); - } - - #endregion - - #region HideSelection Property - - public static readonly DependencyProperty HideSelectionProperty = DependencyProperty.Register( - "HideSelection", - typeof( bool ), - typeof( DataGridControl ), - new UIPropertyMetadata( false ) ); - - public bool HideSelection - { - get - { - return ( bool )this.GetValue( DataGridControl.HideSelectionProperty ); - } - set - { - this.SetValue( DataGridControl.HideSelectionProperty, value ); - } - } - - #endregion - - #region ReadOnly Property - - public static readonly DependencyProperty ReadOnlyProperty = DependencyProperty.RegisterAttached( - "ReadOnly", - typeof( bool ), - typeof( DataGridControl ), - new FrameworkPropertyMetadata( false, FrameworkPropertyMetadataOptions.Inherits ) ); - - public bool ReadOnly - { - get - { - return ( bool )this.GetValue( DataGridControl.ReadOnlyProperty ); - } - set - { - this.SetValue( DataGridControl.ReadOnlyProperty, value ); - } - } - - #endregion - - #region AutoScrollCurrentItem Property - - public static readonly DependencyProperty AutoScrollCurrentItemProperty = DependencyProperty.Register( - "AutoScrollCurrentItem", - typeof( AutoScrollCurrentItemTriggers ), - typeof( DataGridControl ), - new PropertyMetadata( AutoScrollCurrentItemTriggers.All ) ); - - public AutoScrollCurrentItemTriggers AutoScrollCurrentItem - { - get - { - return ( AutoScrollCurrentItemTriggers )this.GetValue( DataGridControl.AutoScrollCurrentItemProperty ); - } - set - { - this.SetValue( DataGridControl.AutoScrollCurrentItemProperty, value ); - } - } - - #endregion - - #region EditTriggers Property - - public static readonly DependencyProperty EditTriggersProperty = DependencyProperty.RegisterAttached( - "EditTriggers", - typeof( EditTriggers ), - typeof( DataGridControl ), - new FrameworkPropertyMetadata( EditTriggers.BeginEditCommand | EditTriggers.ClickOnCurrentCell | EditTriggers.ActivationGesture, FrameworkPropertyMetadataOptions.Inherits ) ); - - public EditTriggers EditTriggers - { - get - { - return ( EditTriggers )this.GetValue( DataGridControl.EditTriggersProperty ); - } - set - { - this.SetValue( DataGridControl.EditTriggersProperty, value ); - } - } - - #endregion - - #region ScrollViewer Property - - internal ScrollViewer ScrollViewer - { - get - { - return m_scrollViewer; - } - } - - private ScrollViewer m_scrollViewer; - - #endregion - - #region ItemsHost Property - - internal FrameworkElement ItemsHost - { - get - { - if( m_itemsHost == null ) - { - var scrollViewer = this.ScrollViewer; - if( scrollViewer == null ) - return null; - - //this can be either a ItemsPresenter (which implements IScrollInfo and reforwards it to the ItemsPanel instantiated from the - //ItemsPanelTemplate or the DataGridItemsHost used for the Container Recycling. - var scrollViewerContent = default( FrameworkElement ); - - var itemsPresenter = scrollViewer.Content as ItemsPresenter; - if( itemsPresenter != null ) - { - if( VisualTreeHelper.GetChildrenCount( itemsPresenter ) > 0 ) - { - scrollViewerContent = VisualTreeHelper.GetChild( itemsPresenter, 0 ) as FrameworkElement; - } - } - else - { - scrollViewerContent = scrollViewer.Content as DataGridItemsHost; - - if( scrollViewerContent == null ) - { - scrollViewerContent = scrollViewer.Content as Panel; - } - } - - if( scrollViewerContent == null ) - throw new InvalidOperationException( "An attempt was made to use a ScrollViewer that does not have an ItemsPresenter, Panel, or DataGridItemsHost as its content." ); - - m_itemsHost = scrollViewerContent; - } - - return m_itemsHost; - } - } - - #endregion - - #region ItemsPanel override - - [Obsolete( "The ItemsPanel property is obsolete and has been replaced by the DataGridItemsHost (and derived) classes.", false )] - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - public new ItemsPanelTemplate ItemsPanel - { - get - { - return base.ItemsPanel; - } - set - { - base.ItemsPanel = value; - } - } - - #endregion - - #region FixedHeadersHostPanel Property - - internal Panel FixedHeadersHostPanel - { - get - { - return m_fixedHeadersHostPanel; - } - } - - private void SetFixedHeadersHostPanel( Panel panel ) - { - if( m_fixedHeadersHostPanel == panel ) - return; - - m_fixedHeadersHostPanel = panel; - - if( m_fixedHeadersHostPanel != null ) - { - DataGridControl.RefreshFixedHeaderFooter( this, m_fixedHeadersHostPanel, this.GetView().FixedHeaders ); - } - } - - private Panel m_fixedHeadersHostPanel; - - #endregion - - #region FixedFootersHostPanel Property - - internal Panel FixedFootersHostPanel - { - get - { - return m_fixedFootersHostPanel; - } - } - - private void SetFixedFootersHostPanel( Panel panel ) - { - if( m_fixedFootersHostPanel == panel ) - return; - - m_fixedFootersHostPanel = panel; - - if( m_fixedFootersHostPanel != null ) - { - DataGridControl.RefreshFixedHeaderFooter( this, m_fixedFootersHostPanel, this.GetView().FixedFooters ); - } - } - - private Panel m_fixedFootersHostPanel; - - #endregion - - #region IsFixedHeadersHost Attached Property - - public static readonly DependencyProperty IsFixedHeadersHostProperty = DependencyProperty.RegisterAttached( - "IsFixedHeadersHost", - typeof( bool ), - typeof( DataGridControl ), - new UIPropertyMetadata( false, new PropertyChangedCallback( DataGridControl.OnIsFixedHeadersHost_Changed ) ) ); - - public static bool GetIsFixedHeadersHost( DependencyObject obj ) - { - return ( bool )obj.GetValue( DataGridControl.IsFixedHeadersHostProperty ); - } - - public static void SetIsFixedHeadersHost( DependencyObject obj, bool value ) - { - obj.SetValue( DataGridControl.IsFixedHeadersHostProperty, value ); - } - - private static void OnIsFixedHeadersHost_Changed( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - if( !( bool )e.NewValue ) - return; - - var panel = sender as Panel; - if( panel == null ) - return; - - var dataGridContext = DataGridControl.GetDataGridContext( sender ); - var dataGridControl = ( dataGridContext != null ) ? dataGridContext.DataGridControl : null; - - if( dataGridControl != null ) - { - dataGridControl.SetFixedHeadersHostPanel( panel ); - } - } - - #endregion - - #region IsFixedFootersHost Attached Property - - public static readonly DependencyProperty IsFixedFootersHostProperty = DependencyProperty.RegisterAttached( - "IsFixedFootersHost", - typeof( bool ), - typeof( DataGridControl ), - new UIPropertyMetadata( false, new PropertyChangedCallback( DataGridControl.OnIsFixedFootersHost_Changed ) ) ); - - public static bool GetIsFixedFootersHost( DependencyObject obj ) - { - return ( bool )obj.GetValue( DataGridControl.IsFixedFootersHostProperty ); - } - - public static void SetIsFixedFootersHost( DependencyObject obj, bool value ) - { - obj.SetValue( DataGridControl.IsFixedFootersHostProperty, value ); - } - - private static void OnIsFixedFootersHost_Changed( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - if( !( bool )e.NewValue ) - return; - - var panel = sender as Panel; - if( panel == null ) - return; - - var dataGridContext = DataGridControl.GetDataGridContext( sender ); - var dataGridControl = ( dataGridContext != null ) ? dataGridContext.DataGridControl : null; - - if( dataGridControl != null ) - { - dataGridControl.SetFixedFootersHostPanel( panel ); - } - } - - #endregion - - #region ItemsPrimaryAxis Property - - public static readonly DependencyProperty ItemsPrimaryAxisProperty = DependencyProperty.Register( - "ItemsPrimaryAxis", - typeof( PrimaryAxis ), - typeof( DataGridControl ), - new UIPropertyMetadata( PrimaryAxis.Vertical ) ); - - public PrimaryAxis ItemsPrimaryAxis - { - get - { - return ( PrimaryAxis )this.GetValue( DataGridControl.ItemsPrimaryAxisProperty ); - } - set - { - this.SetValue( DataGridControl.ItemsPrimaryAxisProperty, value ); - } - } - - #endregion - - #region View Property - - public static readonly DependencyProperty ViewProperty = DependencyProperty.Register( - "View", - typeof( UIViewBase ), - typeof( DataGridControl ), - new UIPropertyMetadata( null, new PropertyChangedCallback( DataGridControl.OnViewChanged ), new CoerceValueCallback( DataGridControl.ViewCoerceValueCallback ) ) ); - - [TypeConverter( typeof( Markup.ViewConverter ) )] - public UIViewBase View - { - get - { - return ( UIViewBase )this.GetValue( DataGridControl.ViewProperty ); - } - set - { - this.SetValue( DataGridControl.ViewProperty, value ); - } - } - - internal event EventHandler ViewChanged; - internal event EventHandler ThemeChanged; - - private static object ViewCoerceValueCallback( DependencyObject sender, object value ) - { - var view = value as UIViewBase; - var dataGridControl = sender as DataGridControl; - - if( ( view == null ) && ( dataGridControl != null ) ) - return dataGridControl.GetDefaultView(); - - if( view != null ) - { - if( ( view.Parent != null ) && ( view.Parent != sender ) ) - throw new InvalidOperationException( "An attempt was made to associate a view with more than one grid." ); - } - - return value; - } - - private static void OnViewChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var self = sender as DataGridControl; - if( self == null ) - return; - - // Cannot stay in editing mode when the view is changed - self.CancelEdit(); - - var oldView = e.OldValue as Views.ViewBase; - var newView = e.NewValue as Views.ViewBase; - - self.OnViewChanged( oldView, newView ); - } - - private void OnViewChanged( Views.ViewBase oldView, Views.ViewBase newView ) - { - if( oldView != null ) - { - oldView.ThemeChanged -= new DependencyPropertyChangedEventHandler( this.View_ThemeChanged ); - oldView.FixedHeaders.CollectionChanged -= new NotifyCollectionChangedEventHandler( this.View_FixedHeadersCollectionChanged ); - oldView.FixedFooters.CollectionChanged -= new NotifyCollectionChangedEventHandler( this.View_FixedFootersCollectionChanged ); - } - - object newDefaultStyleKey = null; - - if( newView != null ) - { - newView.ThemeChanged += new DependencyPropertyChangedEventHandler( this.View_ThemeChanged ); - newView.FixedHeaders.CollectionChanged += new NotifyCollectionChangedEventHandler( this.View_FixedHeadersCollectionChanged ); - newView.FixedFooters.CollectionChanged += new NotifyCollectionChangedEventHandler( this.View_FixedFootersCollectionChanged ); - - newDefaultStyleKey = newView.GetDefaultStyleKey( typeof( DataGridControl ) ); - } - - // Cache if the view requires to preserve container size - this.ViewPreservesContainerSize = ( newView != null ) ? newView.PreserveContainerSize : true; - - if( !object.Equals( newDefaultStyleKey, this.DefaultStyleKey ) ) - { - this.ClearValue( FrameworkElement.DefaultStyleKeyProperty ); - - if( !object.Equals( newDefaultStyleKey, this.DefaultStyleKey ) ) - { - this.DefaultStyleKey = newDefaultStyleKey; - } - } - - this.InvalidateViewStyle(); - - // We cannot be sure that the grid elements default style key are different with this new View/Theme (for instance, if the new View/Theme are of the same type - // as the old ones). So, we have to force the new templates. This is mainly to setup the new ViewBindings. - this.ReapplyTemplate(); - - if( this.ViewChanged != null ) - { - this.ViewChanged( this, EventArgs.Empty ); - } - - // Reset the size states since we do not want to apply old size states to a new view/new container style. - this.DataGridContext.ClearSizeStates(); - - // Reset the flag - this.ForceGeneratorReset = false; - - // Make sure the current item is into view. - this.DelayBringIntoViewAndFocusCurrent( DispatcherPriority.Render, AutoScrollCurrentItemSourceTriggers.ViewChanged ); - } - - private UIViewBase m_defaultView; - - #endregion - - #region GroupLevelDescriptions Read-Only Property - - private static readonly DependencyPropertyKey GroupLevelDescriptionsPropertyKey = DependencyProperty.RegisterReadOnly( - "GroupLevelDescriptions", - typeof( GroupLevelDescriptionCollection ), - typeof( DataGridControl ), - new PropertyMetadata( null ) ); - - public static readonly DependencyProperty GroupLevelDescriptionsProperty; - - public GroupLevelDescriptionCollection GroupLevelDescriptions - { - get - { - return ( GroupLevelDescriptionCollection )this.GetValue( DataGridControl.GroupLevelDescriptionsProperty ); - } - } - - #endregion - - #region NavigationBehavior Property - - public static readonly DependencyProperty NavigationBehaviorProperty = DependencyProperty.RegisterAttached( - "NavigationBehavior", - typeof( NavigationBehavior ), - typeof( DataGridControl ), - new FrameworkPropertyMetadata( NavigationBehavior.CellOnly, FrameworkPropertyMetadataOptions.Inherits ) ); - - public NavigationBehavior NavigationBehavior - { - get - { - return ( NavigationBehavior )this.GetValue( DataGridControl.NavigationBehaviorProperty ); - } - set - { - this.SetValue( DataGridControl.NavigationBehaviorProperty, value ); - } - } - - #endregion - - #region PagingBehavior Property - - public static readonly DependencyProperty PagingBehaviorProperty = DependencyProperty.Register( - "PagingBehavior", - typeof( PagingBehavior ), - typeof( DataGridControl ), - new UIPropertyMetadata( PagingBehavior.TopToBottom ) ); - - public PagingBehavior PagingBehavior - { - get - { - return ( PagingBehavior )this.GetValue( DataGridControl.PagingBehaviorProperty ); - } - set - { - this.SetValue( DataGridControl.PagingBehaviorProperty, value ); - } - } - - #endregion - - #region ItemScrollingBehavior Property - - public static readonly DependencyProperty ItemScrollingBehaviorProperty = DependencyProperty.Register( - "ItemScrollingBehavior", - typeof( ItemScrollingBehavior ), - typeof( DataGridControl ), - new FrameworkPropertyMetadata( ItemScrollingBehavior.Deferred ) ); - - public ItemScrollingBehavior ItemScrollingBehavior - { - get - { - return ( ItemScrollingBehavior )this.GetValue( DataGridControl.ItemScrollingBehaviorProperty ); - } - set - { - this.SetValue( DataGridControl.ItemScrollingBehaviorProperty, value ); - } - } - - #endregion - - #region CurrentRowInEditionState Read-Only Property - - internal RowState CurrentRowInEditionState - { - get - { - return m_currentRowInEditionState; - } - } - - #endregion - - #region CurrentItemInEdition Read-Only Property - - internal object CurrentItemInEdition - { - get - { - return m_currentItemInEdition; - } - } - - #endregion - - #region FixedItem Attached Property - - private static readonly object NotSet = new object(); - - // The ownerType is set to FrameworkElement to make the inheritance works for all grid elements. - private static readonly DependencyProperty FixedItemProperty = DependencyProperty.RegisterAttached( - "FixedItem", - typeof( object ), - typeof( DataGridControl ), - new FrameworkPropertyMetadata( DataGridControl.NotSet, FrameworkPropertyMetadataOptions.Inherits ) ); - - private static object GetFixedItem( DependencyObject obj ) - { - return obj.GetValue( DataGridControl.FixedItemProperty ); - } - - private static void SetFixedItem( DependencyObject obj, object value ) - { - obj.SetValue( DataGridControl.FixedItemProperty, value ); - } - - #endregion - - #region Hidden Properties - - // We want to hide these inherited properties because they have no impact on the DataGridControl behavior. - - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - public new DataTemplate ItemTemplate - { - get - { - return base.ItemTemplate; - } - set - { - base.ItemTemplate = value; - } - } - - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - public new DataTemplateSelector ItemTemplateSelector - { - get - { - return base.ItemTemplateSelector; - } - set - { - base.ItemTemplateSelector = value; - } - } - - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - public new ObservableCollection GroupStyle - { - get - { - return base.GroupStyle; - } - } - - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - public new GroupStyleSelector GroupStyleSelector - { - get - { - return base.GroupStyleSelector; - } - - set - { - base.GroupStyleSelector = value; - } - } - - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - public new bool IsGrouping - { - get - { - return base.IsGrouping; - } - } - - #endregion - - #region ItemContainerGenerator Property - - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - [Obsolete( "The ItemContainerGenerator is obsolete and has been replaced by the GetContainerFromItem and GetItemFromContainer methods.", true )] - public new ItemContainerGenerator ItemContainerGenerator - { - get - { - return base.ItemContainerGenerator; - } - } - - #endregion - - #region CustomItemContainerGenerator Property - - internal CustomItemContainerGenerator CustomItemContainerGenerator - { - get - { - return m_customItemContainerGenerator; - } - } - - #endregion - - #region IsBeingEdited Property - - private static readonly DependencyPropertyKey IsBeingEditedPropertyKey = DependencyProperty.RegisterReadOnly( - "IsBeingEdited", - typeof( bool ), - typeof( DataGridControl ), - new UIPropertyMetadata( false ) ); - - public static readonly DependencyProperty IsBeingEditedProperty = IsBeingEditedPropertyKey.DependencyProperty; - - public bool IsBeingEdited - { - get - { - return ( bool )this.GetValue( DataGridControl.IsBeingEditedProperty ); - } - } - - private void UpdateIsBeingEdited() - { - var isBeingEdited = ( m_currentItemInEdition != null ); - if( isBeingEdited == this.IsBeingEdited ) - return; - - if( isBeingEdited ) - { - this.SetValue( DataGridControl.IsBeingEditedPropertyKey, isBeingEdited ); - } - else - { - this.ClearValue( DataGridControl.IsBeingEditedPropertyKey ); - } - } - - #endregion - - #region DataGridContext Read-Only Property - - internal DataGridContext DataGridContext - { - get - { - return m_localDataGridContext; - } - } - - #endregion - - #region GroupConfigurationSelector Property - - public static readonly DependencyProperty GroupConfigurationSelectorProperty = DependencyProperty.Register( - "GroupConfigurationSelector", - typeof( GroupConfigurationSelector ), - typeof( DataGridControl ), - new FrameworkPropertyMetadata( null, new PropertyChangedCallback( OnGroupConfigurationSelectorChanged ) ) ); - - public GroupConfigurationSelector GroupConfigurationSelector - { - get - { - return ( GroupConfigurationSelector )this.GetValue( DataGridControl.GroupConfigurationSelectorProperty ); - } - set - { - this.SetValue( DataGridControl.GroupConfigurationSelectorProperty, value ); - } - } - - internal event EventHandler GroupConfigurationSelectorChanged; - - private static void OnGroupConfigurationSelectorChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var self = sender as DataGridControl; - if( self == null ) - return; - - var handler = self.GroupConfigurationSelectorChanged; - if( handler == null ) - return; - - handler.Invoke( self, EventArgs.Empty ); - } - - #endregion - - #region AllowDetailToggle Property - - public static readonly DependencyProperty AllowDetailToggleProperty = DependencyProperty.Register( - "AllowDetailToggle", - typeof( bool ), - typeof( DataGridControl ), - new FrameworkPropertyMetadata( true, new PropertyChangedCallback( DataGridControl.OnAllowDetailToggleChanged ) ) ); - - public bool AllowDetailToggle - { - get - { - return ( bool )this.GetValue( DataGridControl.AllowDetailToggleProperty ); - } - set - { - this.SetValue( DataGridControl.AllowDetailToggleProperty, value ); - } - } - - internal event EventHandler AllowDetailToggleChanged; - - private static void OnAllowDetailToggleChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var self = sender as DataGridControl; - if( self == null ) - return; - - var handler = self.AllowDetailToggleChanged; - if( handler == null ) - return; - - handler.Invoke( self, EventArgs.Empty ); - } - - #endregion - - #region DefaultDetailConfiguration Property - - public static readonly DependencyProperty DefaultDetailConfigurationProperty = DependencyProperty.Register( - "DefaultDetailConfiguration", - typeof( DefaultDetailConfiguration ), - typeof( DataGridControl ), - new FrameworkPropertyMetadata( null ) ); - - public DefaultDetailConfiguration DefaultDetailConfiguration - { - get - { - return ( DefaultDetailConfiguration )this.GetValue( DataGridControl.DefaultDetailConfigurationProperty ); - } - set - { - this.SetValue( DataGridControl.DefaultDetailConfigurationProperty, value ); - } - } - - #endregion - - #region DefaultGroupConfiguration Property - - public static readonly DependencyProperty DefaultGroupConfigurationProperty = DependencyProperty.Register( - "DefaultGroupConfiguration", - typeof( GroupConfiguration ), - typeof( DataGridControl ), - new FrameworkPropertyMetadata( null ) ); - - public GroupConfiguration DefaultGroupConfiguration - { - get - { - return ( GroupConfiguration )this.GetValue( DataGridControl.DefaultGroupConfigurationProperty ); - } - set - { - this.SetValue( DataGridControl.DefaultGroupConfigurationProperty, value ); - } - } - - #endregion - - #region ContainerGroupConfiguration Attached Property - - internal static readonly DependencyProperty ContainerGroupConfigurationProperty = DependencyProperty.RegisterAttached( - "ContainerGroupConfiguration", - typeof( GroupConfiguration ), - typeof( DataGridControl ), - new UIPropertyMetadata( null ) ); - - internal static GroupConfiguration GetContainerGroupConfiguration( DependencyObject obj ) - { - return ( GroupConfiguration )obj.GetValue( DataGridControl.ContainerGroupConfigurationProperty ); - } - - internal static void SetContainerGroupConfiguration( DependencyObject obj, GroupConfiguration value ) - { - obj.SetValue( DataGridControl.ContainerGroupConfigurationProperty, value ); - } - - #endregion - - #region ItemsSourceName Property - - public object ItemsSourceName - { - get - { - if( m_itemsSourceName == null ) - return m_detectedName; - - return m_itemsSourceName; - } - set - { - if( value == m_itemsSourceName ) - return; - - m_itemsSourceName = value; - - this.OnPropertyChanged( "ItemsSourceName" ); - } - } - - private object m_itemsSourceName; - private object m_detectedName; - - #endregion - - #region ItemsSourceNameTemplate Property - - public static readonly DependencyProperty ItemsSourceNameTemplateProperty = DependencyProperty.Register( - "ItemsSourceNameTemplate", - typeof( DataTemplate ), - typeof( DataGridControl ), - new UIPropertyMetadata( null ) ); - - public DataTemplate ItemsSourceNameTemplate - { - get - { - return ( DataTemplate )this.GetValue( DataGridControl.ItemsSourceNameTemplateProperty ); - } - set - { - this.SetValue( DataGridControl.ItemsSourceNameTemplateProperty, value ); - } - } - - #endregion - - #region UpdateSourceTrigger Property - - public static readonly DependencyProperty UpdateSourceTriggerProperty = DependencyProperty.Register( - "UpdateSourceTrigger", - typeof( DataGridUpdateSourceTrigger ), - typeof( DataGridControl ), - new UIPropertyMetadata( DataGridUpdateSourceTrigger.RowEndingEdit ) ); - - public DataGridUpdateSourceTrigger UpdateSourceTrigger - { - get - { - return ( DataGridUpdateSourceTrigger )this.GetValue( DataGridControl.UpdateSourceTriggerProperty ); - } - set - { - this.SetValue( DataGridControl.UpdateSourceTriggerProperty, value ); - } - } - - #endregion - - #region ForceGeneratorReset Property - - // This property is used to avoid a reset when Column Virtualization is on and all Row instances are using FixedCellPanel as PART_CellsHost - internal bool ForceGeneratorReset - { - get - { - return m_forceGeneratorReset; - } - set - { - m_forceGeneratorReset = value; - } - } - - private bool m_forceGeneratorReset; // = false; - - #endregion - - #region ClipboardExporters Property - - public Dictionary ClipboardExporters - { - get - { - if( m_clipboardExporters == null ) - { - m_clipboardExporters = new Dictionary(); - - if( !DesignerProperties.GetIsInDesignMode( this ) ) - { - // Configure CSV ClipboardExporter - CsvClipboardExporter csvClipboardExporter = new CsvClipboardExporter(); - csvClipboardExporter.FormatSettings.Separator = ','; - csvClipboardExporter.FormatSettings.TextQualifier = '"'; - m_clipboardExporters.Add( DataFormats.CommaSeparatedValue, csvClipboardExporter ); - - // Configure tab separated value ClipboardExporter - csvClipboardExporter = new CsvClipboardExporter(); - csvClipboardExporter.FormatSettings.Separator = '\t'; - csvClipboardExporter.FormatSettings.TextQualifier = '"'; - m_clipboardExporters.Add( DataFormats.Text, csvClipboardExporter ); - - // Configure HTML exporter - m_clipboardExporters.Add( DataFormats.Html, new HtmlClipboardExporter() ); - - // Configure Unicode ClipboardExporter - m_clipboardExporters.Add( DataFormats.UnicodeText, new UnicodeCsvClipboardExporter() ); - } - } - - return m_clipboardExporters; - } - } - - private Dictionary m_clipboardExporters; // = null; - - #endregion - - #region IsDeleteCommandEnabled Property - - public static readonly DependencyProperty IsDeleteCommandEnabledProperty = DependencyProperty.Register( - "IsDeleteCommandEnabled", - typeof( bool ), - typeof( DataGridControl ), - new FrameworkPropertyMetadata( false, new PropertyChangedCallback( DataGridControl.OnIsDeleteCommandEnabledChanged ) ) ); - - public bool IsDeleteCommandEnabled - { - get - { - return ( bool )this.GetValue( DataGridControl.IsDeleteCommandEnabledProperty ); - } - set - { - this.SetValue( DataGridControl.IsDeleteCommandEnabledProperty, value ); - } - } - - private static void OnIsDeleteCommandEnabledChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var self = sender as DataGridControl; - if( self == null ) - return; - - // On keep the command binding active if it is required - if( ( bool )e.NewValue ) - { - if( !self.CommandBindings.Contains( self.m_deleteCommandBinding ) ) - { - self.CommandBindings.Add( self.m_deleteCommandBinding ); - } - } - else - { - self.CommandBindings.Remove( self.m_deleteCommandBinding ); - } - - CommandManager.InvalidateRequerySuggested(); - } - - #endregion - - #region IsCopyCommandEnabled Property - - public static readonly DependencyProperty IsCopyCommandEnabledProperty = DependencyProperty.Register( - "IsCopyCommandEnabled", - typeof( bool ), - typeof( DataGridControl ), - new FrameworkPropertyMetadata( true, new PropertyChangedCallback( OnIsCopyCommandEnabledChanged ) ) ); - - public bool IsCopyCommandEnabled - { - get - { - return ( bool )this.GetValue( DataGridControl.IsCopyCommandEnabledProperty ); - } - set - { - this.SetValue( DataGridControl.IsCopyCommandEnabledProperty, value ); - } - } - - private static void OnIsCopyCommandEnabledChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var self = sender as DataGridControl; - if( self == null ) - return; - - // On keep the command binding active if it is required - if( ( bool )e.NewValue ) - { - if( !self.CommandBindings.Contains( self.m_copyCommandBinding ) ) - { - self.CommandBindings.Add( self.m_copyCommandBinding ); - } - } - else - { - self.CommandBindings.Remove( self.m_copyCommandBinding ); - } - - CommandManager.InvalidateRequerySuggested(); - } - - #endregion - - #region IsRefreshCommandEnabled Property - - public static readonly DependencyProperty IsRefreshCommandEnabledProperty = DependencyProperty.Register( - "IsRefreshCommandEnabled", - typeof( bool ), - typeof( DataGridControl ), - new FrameworkPropertyMetadata( true, new PropertyChangedCallback( DataGridControl.OnIsRefreshCommandEnabledChanged ) ) ); - - public bool IsRefreshCommandEnabled - { - get - { - return ( bool )this.GetValue( DataGridControl.IsRefreshCommandEnabledProperty ); - } - set - { - this.SetValue( DataGridControl.IsRefreshCommandEnabledProperty, value ); - } - } - - private static void OnIsRefreshCommandEnabledChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var self = sender as DataGridControl; - if( self == null ) - return; - - // On keep the command binding active if it is required - if( ( bool )e.NewValue ) - { - if( !self.CommandBindings.Contains( self.m_refreshCommandBinding ) ) - { - self.CommandBindings.Add( self.m_refreshCommandBinding ); - } - } - else - { - self.CommandBindings.Remove( self.m_refreshCommandBinding ); - } - - CommandManager.InvalidateRequerySuggested(); - } - - #endregion - - #region MaxSortLevels Property - - public static readonly DependencyProperty MaxSortLevelsProperty = DependencyProperty.Register( - "MaxSortLevels", - typeof( int ), - typeof( DataGridControl ), - new FrameworkPropertyMetadata( -1, new PropertyChangedCallback( DataGridControl.OnMaxSortLevelsChanged ) ) ); - - public int MaxSortLevels - { - get - { - return ( int )this.GetValue( DataGridControl.MaxSortLevelsProperty ); - } - set - { - this.SetValue( DataGridControl.MaxSortLevelsProperty, value ); - } - } - - internal event EventHandler MaxSortLevelsChanged; - - private static void OnMaxSortLevelsChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var self = sender as DataGridControl; - if( self == null ) - return; - - var handler = self.MaxSortLevelsChanged; - if( handler == null ) - return; - - handler.Invoke( self, EventArgs.Empty ); - } - - #endregion - - #region MaxGroupLevels Property - - public static readonly DependencyProperty MaxGroupLevelsProperty = DependencyProperty.Register( - "MaxGroupLevels", - typeof( int ), - typeof( DataGridControl ), - new FrameworkPropertyMetadata( -1, new PropertyChangedCallback( DataGridControl.OnMaxGroupLevelsChanged ) ) ); - - public int MaxGroupLevels - { - get - { - return ( int )this.GetValue( DataGridControl.MaxGroupLevelsProperty ); - } - set - { - this.SetValue( DataGridControl.MaxGroupLevelsProperty, value ); - } - } - - internal event EventHandler MaxGroupLevelsChanged; - - private static void OnMaxGroupLevelsChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var self = sender as DataGridControl; - if( self == null ) - return; - - var handler = self.MaxGroupLevelsChanged; - if( handler == null ) - return; - - handler.Invoke( self, EventArgs.Empty ); - } - - #endregion - - #region SynchronizeSelectionWithCurrent Property - - public static readonly DependencyProperty SynchronizeSelectionWithCurrentProperty = DependencyProperty.Register( - "SynchronizeSelectionWithCurrent", - typeof( bool ), - typeof( DataGridControl ), - new UIPropertyMetadata( false ) ); - - public bool SynchronizeSelectionWithCurrent - { - get - { - return ( bool )this.GetValue( DataGridControl.SynchronizeSelectionWithCurrentProperty ); - } - set - { - this.SetValue( DataGridControl.SynchronizeSelectionWithCurrentProperty, value ); - } - } - - #endregion - - #region SynchronizeCurrent Property - - public static readonly DependencyProperty SynchronizeCurrentProperty = DependencyProperty.Register( - "SynchronizeCurrent", - typeof( bool ), - typeof( DataGridControl ), - new UIPropertyMetadata( true ) ); - - public bool SynchronizeCurrent - { - get - { - return ( bool )this.GetValue( DataGridControl.SynchronizeCurrentProperty ); - } - set - { - this.SetValue( DataGridControl.SynchronizeCurrentProperty, value ); - } - } - - #endregion - - #region PreserveExtendedSelection Property - - [Obsolete( "The PreserveExtendedSelection dependency property is obsolete.", false )] - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - public static readonly DependencyProperty PreserveExtendedSelectionProperty = DependencyProperty.Register( - "PreserveExtendedSelection", - typeof( bool ), - typeof( DataGridControl ), - new UIPropertyMetadata( false ) ); - - [Obsolete( "The PreserveExtendedSelection property is obsolete.", false )] - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - public bool PreserveExtendedSelection - { - get - { -#pragma warning disable 618 - return ( bool )this.GetValue( DataGridControl.PreserveExtendedSelectionProperty ); -#pragma warning restore 618 - } - set - { -#pragma warning disable 618 - this.SetValue( DataGridControl.PreserveExtendedSelectionProperty, value ); -#pragma warning restore 618 - } - } - - #endregion - - #region PreserveSelectionWhenEnteringEdit Property - - [Obsolete( "The PreserveSelectionWhenEnteringEdit dependency property is obsolete.", false )] - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - public static readonly DependencyProperty PreserveSelectionWhenEnteringEditProperty = DependencyProperty.Register( - "PreserveSelectionWhenEnteringEdit", - typeof( bool ), - typeof( DataGridControl ), - new UIPropertyMetadata( false ) ); - - [Obsolete( "The PreserveSelectionWhenEnteringEdit property is obsolete.", false )] - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - public bool PreserveSelectionWhenEnteringEdit - { - get - { -#pragma warning disable 618 - return ( bool )this.GetValue( DataGridControl.PreserveSelectionWhenEnteringEditProperty ); -#pragma warning restore 618 - } - set - { -#pragma warning disable 618 - this.SetValue( DataGridControl.PreserveSelectionWhenEnteringEditProperty, value ); -#pragma warning restore 618 - } - } - - #endregion - - #region ItemsSourceChangedDelayed Private Property - - private bool ItemsSourceChangedDelayed - { - get - { - return m_flags[ ( int )DataGridControlFlags.ItemsSourceChangedDelayed ]; - } - set - { - m_flags[ ( int )DataGridControlFlags.ItemsSourceChangedDelayed ] = value; - } - } - - #endregion - - #region SelectedIndexPropertyNeedCoerce Internal Property - - internal bool SelectedIndexPropertyNeedCoerce - { - get - { - return m_flags[ ( int )DataGridControlFlags.SelectedIndexPropertyNeedCoerce ]; - } - set - { - m_flags[ ( int )DataGridControlFlags.SelectedIndexPropertyNeedCoerce ] = value; - } - } - - #endregion - - #region SelectedItemPropertyNeedCoerce Internal Property - - internal bool SelectedItemPropertyNeedCoerce - { - get - { - return m_flags[ ( int )DataGridControlFlags.SelectedItemPropertyNeedCoerce ]; - } - set - { - m_flags[ ( int )DataGridControlFlags.SelectedItemPropertyNeedCoerce ] = value; - } - } - - #endregion - - #region ColumnManagerRowConfiguration Internal Property - - internal ColumnManagerRowConfiguration ColumnManagerRowConfiguration - { - get - { - return m_columnManagerRowConfiguration; - } - } - - private readonly ColumnManagerRowConfiguration m_columnManagerRowConfiguration; - - #endregion - - #region IsBoundToDataGridVirtualizingCollectionViewBase Private Property - - private bool IsBoundToDataGridVirtualizingCollectionViewBase - { - get - { - return m_flags[ ( int )DataGridControlFlags.IsBoundToDataGridVirtualizingCollectionViewBase ]; - } - set - { - m_flags[ ( int )DataGridControlFlags.IsBoundToDataGridVirtualizingCollectionViewBase ] = value; - } - } - - #endregion - - #region ViewPreservesContainerSize Private Property - - private bool ViewPreservesContainerSize - { - get - { - return m_flags[ ( int )DataGridControlFlags.ViewPreservesContainerSize ]; - } - set - { - m_flags[ ( int )DataGridControlFlags.ViewPreservesContainerSize ] = value; - } - } - - #endregion - - #region DebugSaveRestore Private Property - - private bool DebugSaveRestore - { - get - { - return m_flags[ ( int )DataGridControlFlags.DebugSaveRestore ]; - } - set - { - m_flags[ ( int )DataGridControlFlags.DebugSaveRestore ] = value; - } - } - - #endregion - - #region SelectionChangerManager Property - - internal SelectionManager SelectionChangerManager - { - get - { - return m_selectionChangerManager; - } - } - - #endregion - - #region MouseDownSelectionRangePoint Property - - internal SelectionRangePoint MouseDownSelectionRangePoint - { - get - { - return m_mouseDownSelectionRangePoint; - } - } - - #endregion - - #region HandlesScrolling Property - - protected override bool HandlesScrolling - { - get - { - return true; - } - } - - #endregion - - #region ConnectionState ReadOnly Dependency Property - - private static readonly DependencyPropertyKey ConnectionStatePropertyKey = DependencyProperty.RegisterReadOnly( - "ConnectionState", - typeof( DataGridConnectionState ), - typeof( DataGridControl ), - new UIPropertyMetadata( DataGridConnectionState.Idle ) ); - - public static readonly DependencyProperty ConnectionStateProperty = DataGridControl.ConnectionStatePropertyKey.DependencyProperty; - - public DataGridConnectionState ConnectionState - { - get - { - return ( DataGridConnectionState )this.GetValue( DataGridControl.ConnectionStateProperty ); - } - } - - private void SetConnectionState( DataGridConnectionState value ) - { - if( value == DataGridConnectionState.Idle ) - { - this.ClearValue( DataGridControl.ConnectionStatePropertyKey ); - } - else - { - this.SetValue( DataGridControl.ConnectionStatePropertyKey, value ); - } - } - - #endregion - - #region ConnectionError ReadOnly Dependency Property - - private static readonly DependencyPropertyKey ConnectionErrorPropertyKey = DependencyProperty.RegisterReadOnly( - "ConnectionError", - typeof( object ), - typeof( DataGridControl ), - new UIPropertyMetadata( null ) ); - - public static readonly DependencyProperty ConnectionErrorProperty = DataGridControl.ConnectionErrorPropertyKey.DependencyProperty; - - public object ConnectionError - { - get - { - return this.GetValue( DataGridControl.ConnectionErrorProperty ); - } - } - - private void SetConnectionError( object value ) - { - if( value == null ) - { - this.ClearValue( DataGridControl.ConnectionErrorPropertyKey ); - } - else - { - this.SetValue( DataGridControl.ConnectionErrorPropertyKey, value ); - } - } - - #endregion - - #region DeferInitialLayoutPass Property - - public static readonly DependencyProperty DeferInitialLayoutPassProperty = DependencyProperty.Register( - "DeferInitialLayoutPass", - typeof( bool ), - typeof( DataGridControl ), - new FrameworkPropertyMetadata( ( bool )false ) ); - - public bool DeferInitialLayoutPass - { - get - { - return ( bool )this.GetValue( DataGridControl.DeferInitialLayoutPassProperty ); - } - set - { - this.SetValue( DataGridControl.DeferInitialLayoutPassProperty, value ); - } - } - - #endregion - - #region ItemsSourcePropertyDescriptions Internal Property - - internal PropertyDescriptionRouteDictionary ItemsSourcePropertyDescriptions - { - get - { - return m_itemsSourcePropertyDescriptions; - } - } - - private readonly PropertyDescriptionRouteDictionary m_itemsSourcePropertyDescriptions = new PropertyDescriptionRouteDictionary(); - - #endregion - - #region ItemPropertyMap Internal Property - - internal DataGridItemPropertyMap ItemPropertyMap - { - get - { - return m_itemPropertyMap; - } - } - - private readonly DataGridItemPropertyMap m_itemPropertyMap = new DataGridItemPropertyMap(); - - #endregion - - #region AreDetailsFlatten Internal Property - - internal bool AreDetailsFlatten - { - get - { - var view = this.GetView(); - if( view == null ) - return false; - - var viewType = view.GetType(); - if( viewType != m_areDetailsFlattenCache.Key ) - { - var attributes = viewType.GetCustomAttributes( typeof( MasterDetailLayoutAttribute ), true ); - var flatten = ( attributes != null ) - && ( attributes.Length > 0 ) - && ( ( ( MasterDetailLayoutAttribute )attributes[ 0 ] ).MasterDetailLayoutMode == MasterDetailLayoutMode.Flatten ); - - m_areDetailsFlattenCache = new KeyValuePair( viewType, flatten ); - } - - return m_areDetailsFlattenCache.Value; - } - } - - private KeyValuePair m_areDetailsFlattenCache; - - #endregion - - #region GridUniqueName Property - - internal string GridUniqueName - { - get; - set; - } - - #endregion - - #region TemplateApplied Event - - internal event EventHandler TemplateApplied; - - #endregion - - #region DetailsChanged Event - - internal event EventHandler DetailsChanged; - - private void OnDetailsChanged( object sender, EventArgs e ) - { - var handler = this.DetailsChanged; - if( handler == null ) - return; - - handler.Invoke( sender, e ); - } - - #endregion - - #region DeletingSelectedItems Event - - public static readonly RoutedEvent DeletingSelectedItemsEvent = EventManager.RegisterRoutedEvent( - "DeletingSelectedItems", - RoutingStrategy.Bubble, - typeof( CancelRoutedEventHandler ), - typeof( DataGridControl ) ); - - public event CancelRoutedEventHandler DeletingSelectedItems - { - add - { - base.AddHandler( DataGridControl.DeletingSelectedItemsEvent, value ); - } - remove - { - base.RemoveHandler( DataGridControl.DeletingSelectedItemsEvent, value ); - } - } - - protected virtual void OnDeletingSelectedItems( CancelRoutedEventArgs e ) - { - this.RaiseEvent( e ); - } - - #endregion - - #region SelectedItemsDeleted Event - - public static readonly RoutedEvent SelectedItemsDeletedEvent = EventManager.RegisterRoutedEvent( - "SelectedItemsDeleted", - RoutingStrategy.Bubble, - typeof( RoutedEventHandler ), - typeof( DataGridControl ) ); - - public event RoutedEventHandler SelectedItemsDeleted - { - add - { - base.AddHandler( DataGridControl.SelectedItemsDeletedEvent, value ); - } - remove - { - base.RemoveHandler( DataGridControl.SelectedItemsDeletedEvent, value ); - } - } - - protected virtual void OnSelectedItemsDeleted() - { - this.RaiseEvent( new RoutedEventArgs( DataGridControl.SelectedItemsDeletedEvent, this ) ); - } - - #endregion - - #region SelectionChanged Event - - public static readonly RoutedEvent SelectionChangedEvent = EventManager.RegisterRoutedEvent( - "SelectionChanged", - RoutingStrategy.Bubble, - typeof( DataGridSelectionChangedEventHandler ), - typeof( DataGridControl ) ); - - public event DataGridSelectionChangedEventHandler SelectionChanged - { - add - { - base.AddHandler( DataGridControl.SelectionChangedEvent, value ); - } - remove - { - base.RemoveHandler( DataGridControl.SelectionChangedEvent, value ); - } - } - - protected virtual void OnSelectionChanged( DataGridSelectionChangedEventArgs e ) - { - this.RaiseEvent( e ); - } - - internal void RaiseSelectionChanged( DataGridSelectionChangedEventArgs e ) - { - this.OnSelectionChanged( e ); - } - - #endregion - - #region SelectionChanging Event - - public static readonly RoutedEvent SelectionChangingEvent = EventManager.RegisterRoutedEvent( - "SelectionChanging", - RoutingStrategy.Bubble, - typeof( DataGridSelectionChangingEventHandler ), - typeof( DataGridControl ) ); - - public event DataGridSelectionChangingEventHandler SelectionChanging - { - add - { - base.AddHandler( DataGridControl.SelectionChangingEvent, value ); - } - remove - { - base.RemoveHandler( DataGridControl.SelectionChangingEvent, value ); - } - } - - protected virtual void OnSelectionChanging( DataGridSelectionChangingEventArgs e ) - { - this.RaiseEvent( e ); - } - - internal void RaiseSelectionChanging( DataGridSelectionChangingEventArgs e ) - { - using( m_inhibitPreviewGotKeyboardFocus.Set() ) - { - this.OnSelectionChanging( e ); - } - } - - #endregion - - #region DeletingSelectedItemError Event - - public static readonly RoutedEvent DeletingSelectedItemErrorEvent = EventManager.RegisterRoutedEvent( - "DeletingSelectedItemError", - RoutingStrategy.Bubble, - typeof( DeletingSelectedItemErrorRoutedEventHandler ), - typeof( DataGridControl ) ); - - public event DeletingSelectedItemErrorRoutedEventHandler DeletingSelectedItemError - { - add - { - base.AddHandler( DataGridControl.DeletingSelectedItemErrorEvent, value ); - } - remove - { - base.RemoveHandler( DataGridControl.DeletingSelectedItemErrorEvent, value ); - } - } - - protected virtual void OnDeletingSelectedItemError( DeletingSelectedItemErrorRoutedEventArgs e ) - { - this.RaiseEvent( e ); - } - - #endregion - - #region CurrentChanging Event - - public static readonly RoutedEvent CurrentChangingEvent = EventManager.RegisterRoutedEvent( - "CurrentChanging", - RoutingStrategy.Bubble, - typeof( DataGridCurrentChangingEventHandler ), - typeof( DataGridControl ) ); - - public event DataGridCurrentChangingEventHandler CurrentChanging - { - add - { - base.AddHandler( DataGridControl.CurrentChangingEvent, value ); - } - remove - { - base.RemoveHandler( DataGridControl.CurrentChangingEvent, value ); - } - } - - protected virtual void OnCurrentChanging( DataGridCurrentChangingEventArgs e ) - { - this.RaiseEvent( e ); - } - - internal void RaiseCurrentChanging( DataGridCurrentChangingEventArgs e ) - { - this.OnCurrentChanging( e ); - } - - #endregion - - #region CurrentChanged Event - - public static readonly RoutedEvent CurrentChangedEvent = EventManager.RegisterRoutedEvent( - "CurrentChanged", - RoutingStrategy.Bubble, - typeof( DataGridCurrentChangedEventHandler ), - typeof( DataGridControl ) ); - - public event DataGridCurrentChangedEventHandler CurrentChanged - { - add - { - base.AddHandler( DataGridControl.CurrentChangedEvent, value ); - } - remove - { - base.RemoveHandler( DataGridControl.CurrentChangedEvent, value ); - } - } - - protected virtual void OnCurrentChanged( DataGridCurrentChangedEventArgs e ) - { - this.RaiseEvent( e ); - } - - internal void RaiseCurrentChanged( DataGridCurrentChangedEventArgs e ) - { - this.OnCurrentChanged( e ); - } - - #endregion - - #region SortDirectionChanging Event - - public static readonly RoutedEvent SortDirectionChangingEvent = EventManager.RegisterRoutedEvent( - "SortDirectionChanging", - RoutingStrategy.Bubble, - typeof( ColumnSortDirectionChangingEventHandler ), - typeof( DataGridControl ) ); - - public event ColumnSortDirectionChangingEventHandler SortDirectionChanging - { - add - { - base.AddHandler( DataGridControl.SortDirectionChangingEvent, value ); - } - remove - { - base.RemoveHandler( DataGridControl.SortDirectionChangingEvent, value ); - } - } - - protected virtual void OnSortDirectionChanging( ColumnSortDirectionChangingEventArgs e ) - { - this.RaiseEvent( e ); - } - - internal void RaiseSortDirectionChanging( ColumnSortDirectionChangingEventArgs e ) - { - this.OnSortDirectionChanging( e ); - } - - #endregion - - #region GroupCollapsing Event - - public static readonly RoutedEvent GroupCollapsingEvent = EventManager.RegisterRoutedEvent( - "GroupCollapsing", - RoutingStrategy.Bubble, - typeof( GroupExpansionChangingEventHandler ), - typeof( DataGridControl ) ); - - public event GroupExpansionChangingEventHandler GroupCollapsing - { - add - { - base.AddHandler( DataGridControl.GroupCollapsingEvent, value ); - } - remove - { - base.RemoveHandler( DataGridControl.GroupCollapsingEvent, value ); - } - } - - protected virtual void OnGroupCollapsing( GroupExpansionChangingEventArgs e ) - { - this.RaiseEvent( e ); - } - - internal void RaiseGroupCollapsing( GroupExpansionChangingEventArgs e ) - { - this.OnGroupCollapsing( e ); - } - - #endregion - - #region GroupCollapsed Event - - public static readonly RoutedEvent GroupCollapsedEvent = EventManager.RegisterRoutedEvent( - "GroupCollapsed", - RoutingStrategy.Bubble, - typeof( GroupExpansionChangedEventHandler ), - typeof( DataGridControl ) ); - - public event GroupExpansionChangedEventHandler GroupCollapsed - { - add - { - base.AddHandler( DataGridControl.GroupCollapsedEvent, value ); - } - remove - { - base.RemoveHandler( DataGridControl.GroupCollapsedEvent, value ); - } - } - - protected virtual void OnGroupCollapsed( GroupExpansionChangedEventArgs e ) - { - this.RaiseEvent( e ); - } - - internal void RaiseGroupCollapsed( GroupExpansionChangedEventArgs e ) - { - this.OnGroupCollapsed( e ); - } - - #endregion - - #region GroupExpanding Event - - public static readonly RoutedEvent GroupExpandingEvent = EventManager.RegisterRoutedEvent( - "GroupExpanding", - RoutingStrategy.Bubble, - typeof( GroupExpansionChangingEventHandler ), - typeof( DataGridControl ) ); - - public event GroupExpansionChangingEventHandler GroupExpanding - { - add - { - base.AddHandler( DataGridControl.GroupExpandingEvent, value ); - } - remove - { - base.RemoveHandler( DataGridControl.GroupExpandingEvent, value ); - } - } - - protected virtual void OnGroupExpanding( GroupExpansionChangingEventArgs e ) - { - this.RaiseEvent( e ); - } - - internal void RaiseGroupExpanding( GroupExpansionChangingEventArgs e ) - { - this.OnGroupExpanding( e ); - } - - #endregion - - #region GroupExpanded Event - - public static readonly RoutedEvent GroupExpandedEvent = EventManager.RegisterRoutedEvent( - "GroupExpanded", - RoutingStrategy.Bubble, - typeof( GroupExpansionChangedEventHandler ), - typeof( DataGridControl ) ); - - public event GroupExpansionChangedEventHandler GroupExpanded - { - add - { - base.AddHandler( DataGridControl.GroupExpandedEvent, value ); - } - remove - { - base.RemoveHandler( DataGridControl.GroupExpandedEvent, value ); - } - } - - protected virtual void OnGroupExpanded( GroupExpansionChangedEventArgs e ) - { - this.RaiseEvent( e ); - } - - internal void RaiseGroupExpanded( GroupExpansionChangedEventArgs e ) - { - this.OnGroupExpanded( e ); - } - - #endregion - - #region Event Handlers - - private static void OnFlowDirectionPropertyChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var self = sender as DataGridControl; - if( self == null ) - return; - - self.CustomItemContainerGenerator.ResetGeneratorContent(); - } - - private void OnDataGridCollectionView_PropertyChanged( DataGridCollectionViewBase sender, PropertyChangedEventArgs e ) - { - Debug.Assert( sender != null ); - Debug.Assert( e != null ); - - var propertyName = e.PropertyName; - - if( string.IsNullOrEmpty( propertyName ) || ( propertyName == DataGridCollectionViewBase.RootGroupPropertyName ) ) - { - this.SetValue( DataGridControl.StatContextPropertyKey, sender.RootGroup ); - } - } - - private void OnDataGridDetailDescriptionsChanged( DataGridDetailDescriptionCollection sender, NotifyCollectionChangedEventArgs e ) - { - if( sender == null ) - return; - - switch( e.Action ) - { - case NotifyCollectionChangedAction.Reset: - case NotifyCollectionChangedAction.Replace: - case NotifyCollectionChangedAction.Remove: - case NotifyCollectionChangedAction.Add: - break; - - case NotifyCollectionChangedAction.Move: - //Don't care about the move. - break; - - default: - break; - } - } - - private static void OnGroupStyleSelectorChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - throw new NotSupportedException( "GroupStyles are not supported by the DataGridControl." ); - } - - private static void GroupStyle_CollectionChanged( object sender, NotifyCollectionChangedEventArgs e ) - { - if( e.Action == NotifyCollectionChangedAction.Add ) - { - throw new NotSupportedException( "GroupStyles are not supported by the DataGridControl." ); - } - } - - #endregion - - #region Drag Management - - public static readonly DependencyProperty AllowDragProperty = DependencyProperty.Register( - "AllowDrag", - typeof( bool ), - typeof( DataGridControl ), - new UIPropertyMetadata( false, new PropertyChangedCallback( DataGridControl.OnAllowDragPropertyChanged ) ) ); - - public bool AllowDrag - { - get - { - return ( bool )GetValue( DataGridControl.AllowDragProperty ); - } - set - { - this.SetValue( DataGridControl.AllowDragProperty, value ); - } - } - - private static void OnAllowDragPropertyChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var self = sender as DataGridControl; - if( ( self == null ) || ( ( bool )e.NewValue ) ) - return; - } - - internal bool UseDragBehavior - { - get - { - return false; - } - } - - internal void InitializeDragPostion( MouseEventArgs e ) - { - if( !this.UseDragBehavior ) - return; - - m_initialDragPosition = e.GetPosition( this ); - } - - internal void DoDrag( MouseEventArgs e ) - { - return; - } - - internal void ResetDragDataObject() - { - m_dragDataObject = null; - m_initialDragPosition = null; - } - - internal IDisposable InhibitDrag() - { - return m_inhibitDrag.Set(); - } - - private void PrepareDragDataObject( MouseEventArgs e ) - { - if( !this.UseDragBehavior ) - return; - - try - { - new UIPermission( UIPermissionClipboard.AllClipboard ).Demand(); - - m_dragDataObject = ClipboardExporterBase.CreateDataObject( this ); - } - catch( SecurityException ) - { - throw; - } - } - - private IDataObject m_dragDataObject; // = null; - private Nullable m_initialDragPosition; // = null; - private readonly AutoResetFlag m_inhibitDrag = AutoResetFlagFactory.Create( false ); - - #endregion - - #region VIEWBASE METHODS - - private void View_FixedHeadersCollectionChanged( object sender, NotifyCollectionChangedEventArgs e ) - { - ObservableCollection collection = ( ObservableCollection )sender; - Panel panel = this.FixedHeadersHostPanel; - - if( panel != null ) - { - DataGridControl.RefreshFixedHeaderFooter( this, panel, collection ); - } - } - private void View_FixedFootersCollectionChanged( object sender, NotifyCollectionChangedEventArgs e ) - { - ObservableCollection collection = ( ObservableCollection )sender; - Panel panel = this.FixedFootersHostPanel; - - if( panel != null ) - { - DataGridControl.RefreshFixedHeaderFooter( this, panel, collection ); - } - } - - private void View_ThemeChanged( object sender, DependencyPropertyChangedEventArgs e ) - { - - // We need to reevaluate the CurrentContext when it is a detail context since the details are cleared and recreated when the theme changes and no update is - // made to the current item itself. We dispatch it with a high priority in order to be sure it is executed before a potential BringIntoView of the current item. - if( this.CurrentContext != this.DataGridContext ) - { - this.Dispatcher.BeginInvoke( new Action( delegate () - { - this.UpdateCurrentContextOnThemeChanged( this.CurrentContext ); - } ), DispatcherPriority.Normal ); - } - - var view = this.GetView(); - - this.SaveDataGridContextState( this.DataGridContext, true, int.MaxValue ); - - this.ClearFixedHostPanels(); - - if( this.ThemeChanged != null ) - { - this.ThemeChanged( this, EventArgs.Empty ); - } - - // Reset the size states since we do not want to apply old size states to a new view/new container style. - this.DataGridContext.ClearSizeStates(); - - // Reset the flag - this.ForceGeneratorReset = false; - - var oldTemplate = this.Template; - - this.DefaultStyleKey = view.GetDefaultStyleKey( typeof( DataGridControl ) ); - - var newTemplate = this.Template; - - this.ClearValue( DataGridControl.ParentDataGridControlPropertyKey ); - this.SetValue( DataGridControl.ParentDataGridControlPropertyKey, this ); - - // When a null Theme is set or the new Theme is the already the applied System Theme, we detect if the - // template changed after setting the DefaultStyleKey to refresh the FixedHeaders and FixedFooters - if( oldTemplate == newTemplate ) - { - this.ResetFixedRegions(); - } - - // Make sure the current item is into view. - this.DelayBringIntoViewAndFocusCurrent( DispatcherPriority.Render, AutoScrollCurrentItemSourceTriggers.ThemeChanged ); - } - - /// - /// Calling this method will enable the grid's current view to be styled. - /// If any implicit Style exits, it will be immediately applied. - /// - private void InvalidateViewStyle() - { - this.AddLogicalChild( this.View ); - } - - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - [Obsolete( "The ViewBindingContext property is obsolete and has been replaced by the DataGridControl.DataGridContext attached property.", false )] - public object ViewBindingContext - { - get - { - return this.GetView(); - } - } - - internal Views.ViewBase GetView() - { - return this.View; - } - - private Views.ViewBase GetDefaultView() - { - if( m_defaultView == null ) - { - m_defaultView = new TableflowView(); - } - - return m_defaultView; - } - - #endregion - - #region FOCUS - - internal bool IsSetFocusInhibited - { - get - { - return m_inhibitSetFocus.IsSet; - } - } - - internal bool SettingFocusOnCell - { - get - { - return m_flags[ ( int )DataGridControlFlags.SettingFocusOnCell ]; - } - private set - { - m_flags[ ( int )DataGridControlFlags.SettingFocusOnCell ] = value; - } - } - - internal static bool SetFocusUIElementHelper( UIElement toFocus ) - { - if( toFocus == null ) - return false; - - try - { - if( toFocus.Focus() ) - return true; - } - catch - { - } - - if( toFocus.IsKeyboardFocusWithin ) - return true; - - UIElement childToFocus = DataGridControl.FindFirstFocusableChild( toFocus ); - - if( childToFocus == null ) - return false; - - try - { - return childToFocus.Focus(); - } - catch - { - return false; - } - } - - internal static UIElement FindFirstFocusableChild( UIElement reference ) - { - UIElement retval = null; - - int childCount = VisualTreeHelper.GetChildrenCount( reference ); - - for( int i = 0; i < childCount; i++ ) - { - UIElement element = VisualTreeHelper.GetChild( reference, i ) as UIElement; - - if( ( element != null ) && ( element.Visibility == Visibility.Visible ) ) - { - if( ( element.Focusable == true ) && ( KeyboardNavigation.GetIsTabStop( element ) == true ) ) - { - retval = element; - } - - if( retval == null ) - { - retval = FindFirstFocusableChild( element ); - } - } - - if( retval != null ) - { - break; - } - } - - return retval; - } - - internal void QueueSetFocusHelper( bool forceFocus ) - { - if( m_queueSetFocus != null ) - return; - - m_queueSetFocus = this.Dispatcher.BeginInvoke( DispatcherPriority.Loaded, - new DelayedSetFocusHelperHandler( this.DelayedSetFocusHelper ), forceFocus, new object[] { true } ); - } - - internal bool SetFocusHelper( UIElement itemContainer, ColumnBase column, bool forceFocus, bool preserveEditorFocus ) - { - return this.SetFocusHelper( itemContainer, column, forceFocus, preserveEditorFocus, false ); - } - - internal bool SetFocusHelper( UIElement itemContainer, ColumnBase column, bool forceFocus, bool preserveEditorFocus, bool preventMakeVisibleIfCellFocused ) - { - if( ( itemContainer == null ) || m_inhibitSetFocus.IsSet ) - return false; - - //There is an identified weakness with the IsKeyboardFocusWithin property where it cannot tell if the focus is within a Popup which is within the element - //This has been identified, and only the places where it caused problems were fixed... This comment is only here to remind developpers of the flaw - if( ( !this.IsKeyboardFocusWithin ) && ( !this.IsKeyboardFocused ) && ( !forceFocus ) ) - return false; - -#if DEBUG - DataGridContext itemContainerDataGridContext = DataGridControl.GetDataGridContext( itemContainer ); - Debug.Assert( itemContainerDataGridContext != null ); - Debug.Assert( ( column == null ) || ( itemContainerDataGridContext.Columns.Contains( column ) ) ); -#endif - - var toFocus = default( UIElement ); - - var row = Row.FromContainer( itemContainer ); - var preventMakeVisibleDisposable = default( IDisposable ); - - try - { - if( row != null ) - { - //ColumnManagerRow and derived classes should not be focused - if( row.IsUnfocusable ) - return false; - - var cell = default( Cell ); - if( column != null ) - { - cell = row.Cells[ column ]; - - // The cell must be in VisualTree to be able to get the focus, else, .Focus() will always return false - if( cell != null ) - { - cell.EnsureInVisualTree(); - - if( preventMakeVisibleIfCellFocused ) - { - preventMakeVisibleDisposable = cell.InhibitMakeVisible(); - } - } - } - - if( ( row.IsBeingEdited ) && ( cell != null ) ) - { - if( ( cell.IsBeingEdited ) && ( preserveEditorFocus ) ) - { - //Obtain the CellEditor's Focus Scope - toFocus = Cell.GetCellFocusScope( cell ); - - //If there was none defined - if( toFocus == null ) - { - //obtain the first focusable child into the template - toFocus = DataGridControl.FindFirstFocusableChild( cell ); - } - } - - if( toFocus == null ) - { - toFocus = cell; - } - - var currentFocusIsInsideCell = ( cell != Keyboard.FocusedElement ) && ( TreeHelper.IsDescendantOf( Keyboard.FocusedElement as DependencyObject, cell ) ); - - // If the focus is already within the Cell to focus, there is noting to do. The item to focus should be the Keyboard focused element - hence, already focused. - // Verify cell.IsBeingEdited to prevent the focus to stay on the editor when in fact the editing process is being canceled (pressing ESC). - if( ( currentFocusIsInsideCell ) && ( preserveEditorFocus ) && ( cell.IsBeingEdited ) ) - return true; - } - else if( ( row.NavigationBehavior == NavigationBehavior.RowOnly ) || ( cell == null ) ) - { - toFocus = row.RowFocusRoot; - - if( toFocus == null ) - { - toFocus = row; - } - - if( ( row.NavigationBehavior == NavigationBehavior.RowOrCell ) && ( row.IsSelected ) ) - { - toFocus.Focusable = true; - } - } - else - { - toFocus = cell; - - var currentFocusIsInsideCell = ( cell != Keyboard.FocusedElement ) && ( TreeHelper.IsDescendantOf( Keyboard.FocusedElement as DependencyObject, cell ) ); - - //If the focus is already within the Cell to focus, then don't touch a thing. It means the item to focus should be the Keyboard focused element - Already focused - if( ( currentFocusIsInsideCell ) && ( preserveEditorFocus ) ) - return true; - } - } - else - { - toFocus = itemContainer; - - if( TreeHelper.IsDescendantOf( Keyboard.FocusedElement as DependencyObject, toFocus ) ) - return true; - } - - // If setting the focus on a row fails, we must try to focus the item container in case the target row is not the topmost container, - // i.e. a StatRow that is contained in a a GroupHeaderControl. - if( ( toFocus != itemContainer ) && DataGridControl.SetFocusUIElementHelper( toFocus ) ) - return true; - - return DataGridControl.SetFocusUIElementHelper( itemContainer ); - } - finally - { - if( preventMakeVisibleDisposable != null ) - { - preventMakeVisibleDisposable.Dispose(); - preventMakeVisibleDisposable = null; - } - } - } - - private void DelayedSetFocusHelper( bool forceFocus, bool preserveEditorFocus ) - { - DataGridContext currentContext = this.CurrentContext; - - if( currentContext == null ) - return; - - this.SettingFocusOnCell = ( currentContext.CurrentCell != null ); - - try - { - UIElement element = currentContext.GetContainerFromItem( currentContext.InternalCurrentItem ) as UIElement; - - using( m_selectionChangerManager.PushUpdateSelectionSource( SelectionManager.UpdateSelectionSource.None ) ) - { - this.SetFocusHelper( element, currentContext.CurrentColumn, forceFocus, preserveEditorFocus ); - } - } - finally - { - this.SettingFocusOnCell = false; - m_queueSetFocus = null; - } - } - - #endregion - - #region BRING INTO VIEW - - internal bool IsBringIntoViewDelayed - { - get - { - var itemsHost = this.ItemsHost as DataGridItemsHost; - - return ( itemsHost != null ) - && ( itemsHost.DelayBringIntoView ); - } - } - - internal IDisposable SetQueueBringIntoViewRestrictions( AutoScrollCurrentItemSourceTriggers trigger ) - { - return m_inhibitAutoScroll.SetRestriction( trigger ); - } - - internal IDisposable InhibitQueueBringIntoView() - { - return m_inhibitBringIntoView.Set(); - } - - internal IDisposable InhibitSetFocus() - { - return m_inhibitSetFocus.Set(); - } - - internal void DelayBringIntoViewAndFocusCurrent( AutoScrollCurrentItemSourceTriggers trigger ) - { - this.DelayBringIntoViewAndFocusCurrent( DispatcherPriority.DataBind, trigger ); - } - - private void DelayBringIntoViewAndFocusCurrent( DispatcherPriority priority, AutoScrollCurrentItemSourceTriggers trigger ) - { - if( ( m_queueBringIntoView != null ) || m_inhibitBringIntoView.IsSet || m_inhibitSetFocus.IsSet || !this.IsBringIntoViewAllowed( trigger ) ) - return; - - m_queueBringIntoView = this.QueueBringIntoView( priority ); - - //if the operation is not inhibited - if( m_queueBringIntoView != null ) - { - //register to the DispatcherOperation completed event - m_queueBringIntoView.Completed += new EventHandler( BringIntoView_Completed ); - } - } - - private DispatcherOperation QueueBringIntoView( DispatcherPriority priority ) - { - Debug.Assert( !m_inhibitBringIntoView.IsSet ); - - return this.Dispatcher.BeginInvoke( priority, new GenericHandler( this.QueueBringIntoViewHelper ) ); - } - - private bool QueueBringIntoViewHelper() - { - var dataGridContext = this.CurrentContext; - if( dataGridContext == null ) - return false; - - var currentItem = dataGridContext.InternalCurrentItem; - if( currentItem == null ) - return false; - - return this.BringItemIntoViewHelper( dataGridContext, currentItem ); - } - - public bool BringItemIntoView( object item ) - { - return this.BringItemIntoViewHelper( this.DataGridContext, item ); - } - - internal bool BringItemIntoViewHelper( DataGridContext dataGridContext, object item ) - { - //this is a protection in case the Template is incomplete or not realized yet. - var itemsHost = this.ItemsHost; - if( itemsHost == null ) - return false; - - // It is possible that a BringIntoView was queued before an operation that will - // detach the ItemsHost of the DataGridControl and we want to avoid to call - // ICustomVirtualizingPanel.BringIntoView in this situation. - var itemsHostDataGridContext = DataGridControl.GetDataGridContext( itemsHost ); - if( itemsHostDataGridContext == null ) - return false; - - // We don't want to call BringIntoView directly on the container if a layout pass - // is scheduled. - if( !this.IsBringIntoViewDelayed ) - { - // If a container exists, call bring into view on it! - var container = dataGridContext.GetContainerFromItem( item ) as FrameworkElement; - if( container != null ) - { - container.BringIntoView(); - - //flag the function as being successful - return true; - } - } - - // The container does not exist, it is not yet realized or the action is delayed. - - // If we are not virtualizing any items, return. - // The call to SetFocusHelper when the BringIntoView completes will call a FrameworkElement BringIntoView - // which will cause the ScrollViewer to bring the item into view approprietly. - if( ( this.ScrollViewer != null ) && ( !this.ScrollViewer.CanContentScroll ) ) - return false; - - var customPanel = itemsHost as ICustomVirtualizingPanel; - if( customPanel == null ) - return false; - - - int index = this.GetGlobalGeneratorIndexFromItem( null, item ); - - if( index != -1 ) - { - //call the special function to bring an index into view. - customPanel.BringIntoView( index ); - return true; - } - - return false; - } - - internal bool IsBringIntoViewAllowed( AutoScrollCurrentItemSourceTriggers trigger ) - { - if( trigger == AutoScrollCurrentItemSourceTriggers.None ) - return false; - - var source = ( ~m_inhibitAutoScroll.Restrictions & trigger ); - if( source == AutoScrollCurrentItemSourceTriggers.None ) - return false; - - var options = this.AutoScrollCurrentItem; - - switch( source ) - { - case AutoScrollCurrentItemSourceTriggers.Editing: - case AutoScrollCurrentItemSourceTriggers.Navigation: - return true; - - case AutoScrollCurrentItemSourceTriggers.CurrentItemChanged: - case AutoScrollCurrentItemSourceTriggers.CurrentColumnChanged: - case AutoScrollCurrentItemSourceTriggers.CollectionViewCurrentItemChanged: - case AutoScrollCurrentItemSourceTriggers.SelectionChanged: - case AutoScrollCurrentItemSourceTriggers.ColumnsCollectionChanged: - return DataGridControl.IsSet( options, AutoScrollCurrentItemTriggers.CurrentChanged ); - - case AutoScrollCurrentItemSourceTriggers.SortChanged: - return DataGridControl.IsSet( options, AutoScrollCurrentItemTriggers.SortChanged ); - - case AutoScrollCurrentItemSourceTriggers.GroupChanged: - return DataGridControl.IsSet( options, AutoScrollCurrentItemTriggers.GroupChanged ); - - case AutoScrollCurrentItemSourceTriggers.FocusChanged: - return DataGridControl.IsSet( options, AutoScrollCurrentItemTriggers.FocusChanged ); - - case AutoScrollCurrentItemSourceTriggers.ItemsSourceChanged: - return DataGridControl.IsSet( options, AutoScrollCurrentItemTriggers.ItemsSourceChanged ); - - case AutoScrollCurrentItemSourceTriggers.ViewChanged: - return DataGridControl.IsSet( options, AutoScrollCurrentItemTriggers.ViewChanged ); - - case AutoScrollCurrentItemSourceTriggers.ThemeChanged: - return DataGridControl.IsSet( options, AutoScrollCurrentItemTriggers.ThemeChanged ); - } - - return false; - } - - private void BringIntoView_Completed( object sender, EventArgs e ) - { - m_queueBringIntoView.Completed -= new EventHandler( BringIntoView_Completed ); - bool successful = ( bool )m_queueBringIntoView.Result; - m_queueBringIntoView = null; - - if( successful ) - { - this.QueueSetFocusHelper( false ); - } - else if( this.IsKeyboardFocusWithin ) - { - //The restore current and the bringintoview failed, give the focus back to the DataGridControl (safe handling of focus). - this.ForceFocus( this.ScrollViewer ); - } - } - - private static bool IsSet( AutoScrollCurrentItemTriggers source, AutoScrollCurrentItemTriggers comparand ) - { - return ( ( source & comparand ) == comparand ); - } - - #endregion - - #region COMMANDS - - private void OnExpandGroupCanExecute( object sender, CanExecuteRoutedEventArgs e ) - { - e.CanExecute = false; - - var group = e.Parameter as CollectionViewGroup; - if( group == null ) - return; - - if( this.DataGridContext.IsGroupExpanded( group, false ) == false ) - { - e.CanExecute = true; - } - } - - protected virtual void OnExpandGroupExecuted( object sender, ExecutedRoutedEventArgs e ) - { - var group = e.Parameter as CollectionViewGroup; - if( group == null ) - return; - - this.DataGridContext.ExpandGroup( group ); - } - - private void OnCollapseGroupCanExecute( object sender, CanExecuteRoutedEventArgs e ) - { - e.CanExecute = false; - - var group = e.Parameter as CollectionViewGroup; - if( group == null ) - return; - - if( this.DataGridContext.IsGroupExpanded( group, false ) == true ) - { - e.CanExecute = true; - } - } - - protected virtual void OnCollapseGroupExecuted( object sender, ExecutedRoutedEventArgs e ) - { - var group = e.Parameter as CollectionViewGroup; - if( group == null ) - return; - - this.DataGridContext.CollapseGroup( group ); - } - - private void OnToggleGroupCanExecute( object sender, CanExecuteRoutedEventArgs e ) - { - e.CanExecute = false; - - var group = e.Parameter as CollectionViewGroup; - if( group == null ) - return; - - e.CanExecute = this.DataGridContext.IsGroupExpanded( group, false ).HasValue; - } - - protected virtual void OnToggleGroupExecuted( object sender, ExecutedRoutedEventArgs e ) - { - var group = e.Parameter as CollectionViewGroup; - if( group == null ) - return; - - this.DataGridContext.ToggleGroupExpansion( group ); - } - - private void OnSelectAllCanExecute( object sender, CanExecuteRoutedEventArgs e ) - { - e.CanExecute = ( this.SelectionModeToUse != SelectionMode.Single ); - } - - private void OnSelectAllExecuted( object sender, ExecutedRoutedEventArgs e ) - { - if( this.SelectionModeToUse == SelectionMode.Single ) - return; - - this.UpdateLayout(); - - SelectAllVisitor selectAllVisitor = new SelectAllVisitor(); - DataGridContext originContext = e.Parameter as DataGridContext; - - if( originContext == null ) - { - originContext = this.DataGridContext; - } - - this.SelectionChangerManager.Begin(); - - try - { - bool visitWasStopped; - - ( ( IDataGridContextVisitable )originContext ).AcceptVisitor( - 0, int.MaxValue, selectAllVisitor, DataGridContextVisitorType.DataGridContext, out visitWasStopped ); - } - finally - { - this.SelectionChangerManager.End( true, false ); - } - } - - private bool CopyCanExecute() - { - try - { - new UIPermission( UIPermissionClipboard.AllClipboard ).Demand(); - return ( this.ClipboardExporters.Count > 0 ) && ( this.SelectedContexts.Count > 0 ); - } - catch( SecurityException ) - { - return false; - } - } - - private void OnCopyCanExecute( object sender, CanExecuteRoutedEventArgs e ) - { - e.CanExecute = this.CopyCanExecute(); - } - - protected virtual void OnCopyExecuted( object sender, ExecutedRoutedEventArgs e ) - { - if( !this.CopyCanExecute() ) - return; - - try - { - IDataObject copyDataObject = ClipboardExporterBase.CreateDataObject( this ); - - if( copyDataObject != null ) - Clipboard.SetDataObject( copyDataObject, true ); - } - catch( SecurityException ) - { - } - } - - private void OnDeleteCanExecute( object sender, CanExecuteRoutedEventArgs e ) - { - foreach( DataGridContext dataGridContext in this.SelectedContexts ) - { - if( ( !dataGridContext.IsDeleteCommandEnabled ) || ( dataGridContext.SelectedItems.Count == 0 ) ) - continue; - - DataGridCollectionViewBase dataGridCollectionViewBase = dataGridContext.ItemsSourceCollection as DataGridCollectionViewBase; - - // If we already have a DataGridCollectionView, no need to look for an IList source. - IList list = ( dataGridCollectionViewBase == null ) ? ItemsSourceHelper.TryGetIList( dataGridContext.ItemsSourceCollection ) : null; - - if( ( dataGridCollectionViewBase != null ) || ( ( list != null ) && DataGridControl.IsRemoveAllowedForDeleteCommand( list ) ) ) - { - // Ensure that at least on item can be deleted. - foreach( object item in dataGridContext.SelectedItems ) - { - if( dataGridCollectionViewBase != null ) - { - if( dataGridCollectionViewBase.Contains( item ) ) - { - e.CanExecute = true; - return; - } - } - else if( list != null ) - { - if( list.Contains( item ) ) - { - e.CanExecute = true; - return; - } - } - } - } - } - - e.CanExecute = false; - } - - protected virtual void OnDeleteExecuted( object sender, ExecutedRoutedEventArgs e ) - { - CancelRoutedEventArgs args = new CancelRoutedEventArgs( DataGridControl.DeletingSelectedItemsEvent, this ); - this.OnDeletingSelectedItems( args ); - - if( args.Cancel ) - return; - - // Copy the selected item in a temp hashtable. - List> selectedItemList = new List>(); - - for( int i = m_selectedContexts.Count - 1; i >= 0; i-- ) - { - DataGridContext selectedContext = m_selectedContexts[ i ]; - IList sourceSelectedItems = selectedContext.SelectedItems; - object[] clonedSelectedItems = new object[ sourceSelectedItems.Count ]; - sourceSelectedItems.CopyTo( clonedSelectedItems, 0 ); - selectedItemList.Add( new KeyValuePair( selectedContext, clonedSelectedItems ) ); - } - - bool raiseItemDeleted = false; - - // Delete the selected item - foreach( KeyValuePair keyValuePair in selectedItemList ) - { - DataGridContext dataGridContext = keyValuePair.Key; - object[] selectedItems = keyValuePair.Value; - - if( ( !dataGridContext.IsDeleteCommandEnabled ) || ( selectedItems.Length == 0 ) ) - continue; - - DataGridCollectionViewBase dataGridCollectionViewBase = dataGridContext.ItemsSourceCollection as DataGridCollectionViewBase; - - // If we already have a DataGridCollectionView, no need to look for an IList source. - IList list = ( dataGridCollectionViewBase == null ) ? ItemsSourceHelper.TryGetIList( dataGridContext.ItemsSourceCollection ) : null; - - if( ( dataGridCollectionViewBase != null ) || ( ( list != null ) && DataGridControl.IsRemoveAllowedForDeleteCommand( list ) ) ) - { - foreach( object item in selectedItems ) - { - bool retry = false; - - do - { - try - { - int itemIndex; - - if( dataGridCollectionViewBase != null ) - { - itemIndex = dataGridCollectionViewBase.IndexOf( item ); - - if( itemIndex != -1 ) - { - dataGridCollectionViewBase.RemoveAt( itemIndex ); - } - } - else if( list != null ) - { - itemIndex = list.IndexOf( item ); - - if( itemIndex != -1 ) - { - list.RemoveAt( itemIndex ); - } - } - - retry = false; - raiseItemDeleted = true; - } - catch( Exception ex ) - { - DeletingSelectedItemErrorRoutedEventArgs deletingItemErrorArgs = - new DeletingSelectedItemErrorRoutedEventArgs( item, ex, DataGridControl.DeletingSelectedItemErrorEvent, this ); - - this.OnDeletingSelectedItemError( deletingItemErrorArgs ); - - switch( deletingItemErrorArgs.Action ) - { - case DeletingSelectedItemErrorAction.Abort: - return; - - default: - retry = ( deletingItemErrorArgs.Action == DeletingSelectedItemErrorAction.Retry ); - break; - } - } - } - while( retry ); - } - } - } - - if( raiseItemDeleted ) - { - this.OnSelectedItemsDeleted(); - } - } - - private void OnRefreshCanExecute( object sender, CanExecuteRoutedEventArgs e ) - { - e.CanExecute = ( this.IsRefreshCommandEnabled ) && ( this.Items != null ) && ( this.Items.SourceCollection is ICollectionView ); - } - - protected virtual void OnRefreshExecuted( object sender, ExecutedRoutedEventArgs e ) - { - Debug.Assert( this.IsRefreshCommandEnabled ); - - if( this.Items != null ) - { - ICollectionView collectionView = this.Items.SourceCollection as ICollectionView; - - if( collectionView != null ) - { - collectionView.Refresh(); - } - } - } - - #endregion - - #region SOURCE HANDLING - - private void ProcessDelayedItemsSourceChanged() - { - var dataGridContext = this.DataGridContext; - - if( this.ShouldSynchronizeCurrentItem ) - { - var currentItem = this.Items.CurrentItem; - var currentItemIndex = this.Items.CurrentPosition; - - if( ( this.Items.IsCurrentAfterLast ) || ( this.Items.IsCurrentBeforeFirst ) ) - { - currentItemIndex = -1; - } - - dataGridContext.SetCurrent( currentItem, null, currentItemIndex, null, false, false, this.SynchronizeSelectionWithCurrent, AutoScrollCurrentItemSourceTriggers.ItemsSourceChanged ); - - if( !this.SynchronizeSelectionWithCurrent ) - { - m_selectionChangerManager.Begin(); - - try - { - if( ( this.SelectionUnit == SelectionUnit.Row ) && ( !this.Items.IsCurrentAfterLast ) && ( !this.Items.IsCurrentBeforeFirst ) && ( currentItemIndex != -1 ) ) - { - m_selectionChangerManager.SelectJustThisItem( dataGridContext, currentItemIndex, currentItem ); - } - else - { - m_selectionChangerManager.UnselectAll(); - } - } - finally - { - m_selectionChangerManager.End( false, false ); - } - } - } - - var columnManager = dataGridContext.ColumnManager; - - using( columnManager.DeferUpdate( new ColumnHierarchyManager.UpdateOptions( TableView.GetFixedColumnCount( dataGridContext ), true ) ) ) - { - ItemsSourceHelper.ResetPropertyDescriptions( m_itemsSourcePropertyDescriptions, m_itemPropertyMap, this, this.ItemsSource ); - ItemsSourceHelper.CleanUpColumns( this.Columns, false ); - - if( this.AutoCreateColumns ) - { - ItemsSourceHelper.CreateColumnsFromPropertyDescriptions( this.DataGridContext.ColumnManager, - this.DefaultCellEditors, - m_itemsSourcePropertyDescriptions, - this.AutoCreateForeignKeyConfigurations ); - } - - var dataGridCollectionView = this.ItemsSource as DataGridCollectionView; - if( dataGridCollectionView != null ) - { - PropertyChangedEventManager.AddListener( dataGridCollectionView, this, string.Empty ); - this.SetValue( DataGridControl.StatContextPropertyKey, dataGridCollectionView.RootGroup ); - - ProxyCollectionRefreshEventManager.AddListener( dataGridCollectionView, this ); - ProxyGroupDescriptionsChangedEventManager.AddListener( dataGridCollectionView, this ); - ProxySortDescriptionsChangedEventManager.AddListener( dataGridCollectionView, this ); - } - else - { - this.ClearValue( DataGridControl.StatContextPropertyKey ); - } - - var virtualizingCollectionView = this.ItemsSource as DataGridVirtualizingCollectionViewBase; - - // Keep if the source is bound to DataGridVirtualizingCollectionView to avoid preserving ContainerSizeState to avoid memory leaks - this.IsBoundToDataGridVirtualizingCollectionViewBase = ( virtualizingCollectionView != null ); - - if( this.IsBoundToDataGridVirtualizingCollectionViewBase ) - { - ConnectionStateChangedEventManager.AddListener( virtualizingCollectionView, this ); - ConnectionErrorChangedEventManager.AddListener( virtualizingCollectionView, this ); - } - - columnManager.Initialize( this ); - } - - dataGridContext.NotifyItemsSourceChanged(); - this.OnItemsSourceChangeCompleted(); - } - - [Obsolete( "The AddingNewDataItem event is obsolete and has been replaced by the DataGridCollectionView.CreatingNewItem and InitializingNewItem events.", false )] - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - public event EventHandler AddingNewDataItem; - - [Obsolete( "The AddingNewDataItem event is obsolete and has been replaced by the DataGridCollectionView.CreatingNewItem and InitializingNewItem events.", false )] - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - protected internal virtual void OnAddingNewDataItem( AddingNewDataItemEventArgs e ) - { - if( this.AddingNewDataItem != null ) - { - this.AddingNewDataItem( this, e ); - } - } - - public event EventHandler ItemsSourceChangeCompleted; - - private void OnItemsSourceChangeCompleted() - { - var handler = this.ItemsSourceChangeCompleted; - if( handler == null ) - return; - - handler.Invoke( this, EventArgs.Empty ); - } - - protected override void OnItemsSourceChanged( IEnumerable oldValue, IEnumerable newValue ) - { - base.OnItemsSourceChanged( oldValue, newValue ); - - if( m_inhibitItemsCollectionChanged != null ) - { - m_inhibitItemsCollectionChanged.Dispose(); - m_inhibitItemsCollectionChanged = null; - } - - ScrollViewer scrollViewer = this.ScrollViewer; - if( scrollViewer != null ) - { - ScrollViewerHelper.ResetScrollPositions( scrollViewer ); - } - - //This section is to detect automatically the ItemsSourceName - DataView dataView = newValue as DataView; - if( dataView == null ) - { - CollectionView colView = newValue as CollectionView; - if( colView != null ) - { - dataView = colView.SourceCollection as DataView; - } - } - - //Refresh the detectedName - //If the DataSource is directly or indirectly a DataView, then use the TableName. - object oldItemsSourceName = this.ItemsSourceName; - m_detectedName = ( dataView != null ) ? dataView.Table.TableName : null; - - if( !object.Equals( this.ItemsSourceName, oldItemsSourceName ) ) - { - this.OnPropertyChanged( "ItemsSourceName" ); - } - - DataGridContext localContext = this.DataGridContext; - this.UpdateCurrentRowInEditionCellStates( null, null ); - localContext.ClearSizeStates(); - - if( m_initCount != 0 ) - { - this.ItemsSourceChangedDelayed = true; - } - else - { - this.ProcessDelayedItemsSourceChanged(); - } - - DataGridCollectionView dataGridCollectionView = oldValue as DataGridCollectionView; - - if( dataGridCollectionView != null ) - { - PropertyChangedEventManager.RemoveListener( dataGridCollectionView, this, string.Empty ); - - ProxyCollectionRefreshEventManager.RemoveListener( dataGridCollectionView, this ); - ProxyGroupDescriptionsChangedEventManager.RemoveListener( dataGridCollectionView, this ); - ProxySortDescriptionsChangedEventManager.RemoveListener( dataGridCollectionView, this ); - - m_dataGridContextsStateDictionary = null; - } - - DataGridVirtualizingCollectionViewBase virtualizingCollectionView = oldValue as DataGridVirtualizingCollectionViewBase; - - if( virtualizingCollectionView != null ) - { - ConnectionStateChangedEventManager.RemoveListener( virtualizingCollectionView, this ); - ConnectionErrorChangedEventManager.RemoveListener( virtualizingCollectionView, this ); - } - - // We must refresh the FixedRegions to call Clear/Prepare Container for IDataGridItemContainer elements - this.ResetFixedRegions(); - - // Reset the flag - this.ForceGeneratorReset = false; - } - - private object OnCoerceItemsSource( object value ) - { - // Ensure to EndEdit the currently edited container - var currentContext = this.CurrentContext; - var currentItem = currentContext.InternalCurrentItem; - if( currentItem != null ) - { - // Use Row.FromContainer to ensure Rows in Header/Footers are returned correctly - var row = Row.FromContainer( currentContext.GetContainerFromItem( currentItem ) ); - if( ( row != null ) && ( row.IsBeingEdited ) ) - { - row.CancelEdit(); - } - } - - if( this.ItemsSource != value ) - { - if( m_inhibitItemsCollectionChanged == null ) - { - m_inhibitItemsCollectionChanged = this.Items.DeferRefresh(); - } - } - else if( m_inhibitItemsCollectionChanged != null ) - { - m_inhibitItemsCollectionChanged.Dispose(); - m_inhibitItemsCollectionChanged = null; - } - - return value; - } - - private static object ItemsSourceCoerceCallback( DependencyObject sender, object value ) - { - return ( ( DataGridControl )sender ).OnCoerceItemsSource( value ); - } - - #endregion - - #region SAVE/RESTORE STATE - - internal void SaveDataGridContextState( DataGridContext dataGridContext, bool handleExpandedItems, int maxGroupLevel ) - { - if( dataGridContext == null ) - throw new ArgumentNullException( "dataGridContext" ); - - Debug.Assert( !dataGridContext.IsRestoringState ); - - if( dataGridContext.IsSavingState ) - return; - - dataGridContext.IsSavingState = true; - - try - { - WeakDataGridContextKey weakDataGridContextKey = new WeakDataGridContextKey( dataGridContext ); - - if( m_dataGridContextsStateDictionary == null ) - { - m_dataGridContextsStateDictionary = new Dictionary(); - } - else if( m_dataGridContextsStateDictionary.ContainsKey( weakDataGridContextKey ) ) - { - // Already a state saved for this context. Don't overwrite it. - Debug.WriteLineIf( this.DebugSaveRestore, "Already a state saved for WeakDataGridContextKey: " + weakDataGridContextKey.GetHashCode().ToString() ); - return; - } - - SaveRestoreDataGridContextStateVisitor saveRestoreDataGridContextStateVisitor = new SaveRestoreDataGridContextStateVisitor( handleExpandedItems, maxGroupLevel, false ); - - try - { - saveRestoreDataGridContextStateVisitor.SaveState( ( IDataGridContextVisitable )dataGridContext ); - - m_dataGridContextsStateDictionary.Add( weakDataGridContextKey, saveRestoreDataGridContextStateVisitor ); - - Debug.WriteLineIf( this.DebugSaveRestore, "SAVING DataGridContext state for WeakDataGridContextKey: " + weakDataGridContextKey.GetHashCode().ToString() + " SAVED!" ); - } - catch - { - Debug.WriteLineIf( this.DebugSaveRestore, "SAVING DataGridContext state for WeakDataGridContextKey: " + weakDataGridContextKey.GetHashCode().ToString() + " FAILED!" ); - } - } - finally - { - dataGridContext.IsSavingState = false; - } - } - - internal void RestoreDataGridContextState( DataGridContext dataGridContext ) - { - if( ( m_dataGridContextsStateDictionary == null ) || ( m_dataGridContextsStateDictionary.Count == 0 ) ) - return; - - if( dataGridContext == null ) - throw new ArgumentNullException( "dataGridContext" ); - - // A call to RestoreDataGridContextState can be made while processing a save or a restore - // of a DataGridContext because the Generator forces the call in EnsureNodeTreeCreated - // when public methods are accessed. If we are saving, already restoring or pending restoring - // we ignore this call - if( dataGridContext.IsSavingState - || dataGridContext.IsDeferRestoringState - || dataGridContext.IsRestoringState ) - return; - - WeakDataGridContextKey weakDataGridContextKey = new WeakDataGridContextKey( dataGridContext ); - SaveRestoreDataGridContextStateVisitor saveRestoreDataGridContextStateVisitor; - - if( m_dataGridContextsStateDictionary.TryGetValue( weakDataGridContextKey, out saveRestoreDataGridContextStateVisitor ) ) - { - try - { - dataGridContext.IsRestoringState = true; - - // Restoring this dataGridContext state's will expand sub items that should be expanded. - // Their expansion will make the customItemGenerator generate sub detailNodes, which in turn will try - // to be restored to their previous state. - saveRestoreDataGridContextStateVisitor.RestoreState( ( IDataGridContextVisitable )dataGridContext ); - Debug.WriteLineIf( this.DebugSaveRestore, "RESTORING DataGridContext state for WeakDataGridContextKey: " + weakDataGridContextKey.GetHashCode().ToString() + " RESTORED!" ); - } - catch - { - Debug.WriteLineIf( this.DebugSaveRestore, "RESTORING DataGridContext state for WeakDataGridContextKey: " + weakDataGridContextKey.GetHashCode().ToString() + " FAILED!" ); - } - finally - { - m_dataGridContextsStateDictionary.Remove( weakDataGridContextKey ); - dataGridContext.IsRestoringState = false; - } - } - else - { - Debug.WriteLineIf( this.DebugSaveRestore, "Cannot Restore. No state saved for WeakDataGridContextKey: " + weakDataGridContextKey.GetHashCode().ToString() ); - } - } - - private void OnDataGridCollectionView_ProxyCollectionRefresh( DataGridCollectionView sender, EventArgs e ) - { - if( ( sender == null ) || ( sender.GroupDescriptions.Count <= 0 ) ) - return; - - var targetDataGridContext = DataGridContext.SafeGetDataGridContextForDataGridCollectionView( this.DataGridContext, sender ); - if( targetDataGridContext != null ) - { - this.SaveDataGridContextState( targetDataGridContext, false, int.MaxValue ); - } - } - - private void OnDataGridCollectionView_ProxyGroupDescriptionsChanged( DataGridCollectionView sender, NotifyCollectionChangedEventArgs e ) - { - if( sender == null ) - return; - - var maxGroupLevelToSave = -1; - - switch( e.Action ) - { - case NotifyCollectionChangedAction.Add: - { - // Only save/restore group states when there was already at least one GroupDescription. - maxGroupLevelToSave = e.NewStartingIndex - 1; - break; - } - - case NotifyCollectionChangedAction.Move: - { - // Only save/restore the state if there's other groups located before the moved group old/new index. - // Else, do not save, since we already know that we won't be able to find any match when restoring. - maxGroupLevelToSave = Math.Min( e.OldStartingIndex, e.NewStartingIndex ) - 1; - break; - } - - case NotifyCollectionChangedAction.Remove: - { - // No need to save/restore groups states if there won't be any group left. - maxGroupLevelToSave = e.OldStartingIndex - 1; - break; - } - - case NotifyCollectionChangedAction.Replace: - { - maxGroupLevelToSave = e.NewStartingIndex - 1; - break; - } - - case NotifyCollectionChangedAction.Reset: - { - // Don't save. - break; - } - } - - if( maxGroupLevelToSave > -1 ) - { - var targetDataGridContext = DataGridContext.SafeGetDataGridContextForDataGridCollectionView( this.DataGridContext, sender ); - if( targetDataGridContext != null ) - { - this.SaveDataGridContextState( targetDataGridContext, false, maxGroupLevelToSave ); - } - } - } - - private void OnDataGridCollectionView_ProxySortDescriptionsChanged( DataGridCollectionView sender, NotifyCollectionChangedEventArgs e ) - { - if( ( sender == null ) || ( sender.GroupDescriptions.Count <= 0 ) ) - return; - - var targetDataGridContext = DataGridContext.SafeGetDataGridContextForDataGridCollectionView( this.DataGridContext, sender ); - if( targetDataGridContext != null ) - { - this.SaveDataGridContextState( targetDataGridContext, false, int.MaxValue ); - } - } - - private void OnDataGridCollectionView_ProxyAutoFilterValuesChanged( DataGridCollectionView sender, NotifyCollectionChangedEventArgs e ) - { - if( ( sender == null ) || ( sender.GroupDescriptions.Count <= 0 ) ) - return; - - var targetDataGridContext = DataGridContext.SafeGetDataGridContextForDataGridCollectionView( this.DataGridContext, sender ); - if( targetDataGridContext != null ) - { - this.SaveDataGridContextState( targetDataGridContext, false, int.MaxValue ); - } - } - - private void OnDataGridCollectionView_ProxyApplyingFilterCriterias( DataGridCollectionView sender, EventArgs e ) - { - if( ( sender == null ) || ( sender.GroupDescriptions.Count <= 0 ) ) - return; - - var targetDataGridContext = DataGridContext.SafeGetDataGridContextForDataGridCollectionView( this.DataGridContext, sender ); - if( targetDataGridContext != null ) - { - this.SaveDataGridContextState( targetDataGridContext, false, int.MaxValue ); - } - } - - #endregion - - #region VIRTUALIZING COLLECTION VIEW SUPPORT - - private void OnDataGridVirtualizingCollectionViewBase_ConnectionStateChanged( DataGridVirtualizingCollectionViewBase sender, EventArgs e ) - { - if( sender == null ) - return; - - this.SetConnectionState( sender.ConnectionState ); - } - - private void OnDataGridVirtualizingCollectionViewBase_ConnectionErrorChanged( DataGridVirtualizingCollectionViewBase sender, EventArgs e ) - { - if( sender == null ) - return; - - this.SetConnectionError( sender.ConnectionError ); - } - - #endregion - - #region EDITING - - public void BeginEdit() - { - this.BeginEdit( this.CurrentContext.InternalCurrentItem ); - } - - public void BeginEdit( object item ) - { - DataGridControl.BeginEditHelper( this.DataGridContext, item ); - } - - internal static void BeginEditHelper( DataGridContext dataGridContext, object item ) - { - if( item == null ) - return; - - var dataGridControl = dataGridContext.DataGridControl; - if( dataGridControl.IsBeingEdited ) - return; - - if( !dataGridContext.IsContainingItem( item ) ) - throw new InvalidOperationException( "An attempt was made to call the BeginEdit method of an item that is not part of the specified context." ); - - var container = dataGridContext.GetContainerFromItem( item ); - - //if the item is realized, then I could call the BeginEdit() directly on the container. - if( container != null ) - { - var row = Row.FromContainer( container ); - if( row != null ) - { - row.BeginEdit(); - } - - //not a row, then not editable. - } - //if the container is not realized, then I need to set things up so that when the container is realized, it's gonna resume edition. - else - { - dataGridContext.DataGridControl.UpdateCurrentRowInEditionCellStates( null, item ); - dataGridContext.DataGridControl.BringItemIntoView( item ); - } - } - - public void EndEdit() - { - DataGridControl.EndEditHelper( this.DataGridContext ); - } - - internal static void EndEditHelper( DataGridContext dataGridContext ) - { - var dataGridControl = dataGridContext.DataGridControl; - if( !dataGridControl.IsBeingEdited ) - return; - - if( !dataGridContext.IsContainingItem( dataGridContext.DataGridControl.CurrentItemInEdition ) ) - throw new InvalidOperationException( "An attempt was made to call the EndEdit method of an item that is not part of the specified context." ); - - var container = dataGridContext.GetContainerFromItem( dataGridControl.m_currentItemInEdition ); - - //if the item is realized, then I could call the EndEdit() directly on the container. - if( container != null ) - { - var row = Row.FromContainer( container ); - if( row != null ) - { - row.EndEdit(); - } - - //not a row, then not editable. - } - //if the container is not realized, then set things up so that when the container is realized, editing will resume. - else - { - DataGridControl.ProcessUnrealizedEndEdit( dataGridContext ); - } - } - - public void CancelEdit() - { - DataGridControl.CancelEditHelper( this.DataGridContext ); - } - - internal static void CancelEditHelper( DataGridContext dataGridContext ) - { - var dataGridControl = dataGridContext.DataGridControl; - if( !dataGridControl.IsBeingEdited ) - return; - - if( !dataGridContext.IsCurrent ) - throw new InvalidOperationException( "An attempt was made to call the CancelEdit method on a DataGridContext that is not current." ); - - var container = dataGridContext.GetContainerFromItem( dataGridControl.m_currentItemInEdition ); - - //if the item is realized, then I could call the CancelEdit() directly on the container. - if( container != null ) - { - var row = Row.FromContainer( container ); - if( row != null ) - { - row.CancelEdit(); - } - - //not a row, then not editable. - } - //if the container is not realized, then I need to clear the parameters that indicate that the row is being edited. - else - { - dataGridControl.UpdateCurrentRowInEditionCellStates( null, null ); - } - } - - private static void ProcessUnrealizedEndEdit( DataGridContext dataGridContext ) - { - Row row; - - object currentItemInEdition = dataGridContext.DataGridControl.m_currentItemInEdition; - - //first, determine if the item currently in edition is an Item or a [Group]Header/Footer - if( dataGridContext.Items.Contains( currentItemInEdition ) ) - { - //the item currently in edition is a data item. - DependencyObject container = dataGridContext.DataGridControl.CreateContainerForItem(); - Debug.Assert( container != null, "CreateContainerForItem() returned null" ); - - row = container as Row; - } - else - { - DataTemplate template = DataGridControl.GetTemplateForItem( currentItemInEdition ); - Debug.Assert( template != null, "DataTemplate for [Group]Header/Footer is null" ); - - HeaderFooterItem headerFooterItem = new HeaderFooterItem(); - headerFooterItem.ContentTemplate = template; - headerFooterItem.Measure( new Size( double.PositiveInfinity, double.PositiveInfinity ) ); - - row = headerFooterItem.AsVisual() as Row; - } - - if( row != null ) - { - // Ensure to set the DataGridContext on the Container for the - // PrepareItemContainer to correctly fetch the DataGridContext - DataGridControl.SetDataGridContext( row, dataGridContext ); - dataGridContext.DataGridControl.PrepareItemContainer( row, currentItemInEdition ); - - try - { - row.EndEdit(); - } - finally - { - dataGridContext.DataGridControl.ClearItemContainer( row, currentItemInEdition ); - } - } - } - - // Used to initialize/clear Column.CurrentRowInEditionCellState for each cell in the row passed as parameter - internal void UpdateCurrentRowInEditionCellStates( Row newCurrentItemContainer, object newCurrentItemInEdition ) - { - if( newCurrentItemInEdition != m_currentItemInEdition ) - { - var currentRowInEdition = default( Row ); - - if( m_currentItemInEdition != null ) - { - // Get the container for m_currentItemInEdition - currentRowInEdition = Row.FromContainer( this.CurrentContext.GetContainerFromItem( m_currentItemInEdition ) ); - - if( newCurrentItemInEdition != null ) - { - if( ( currentRowInEdition != null ) && ( currentRowInEdition.IsBeingEdited ) ) - throw new InvalidOperationException( "An attempt was made to place a row in edit mode while another row is being edited." ); - } - } - - // The newCurrentItemContainer is null - if( newCurrentItemContainer == null ) - { - if( currentRowInEdition != null ) - { - // We must clear the edition state of the old Row in edition - foreach( Cell cell in currentRowInEdition.CreatedCells ) - { - var parentColumn = cell.ParentColumn; - if( parentColumn == null ) - continue; - - parentColumn.CurrentRowInEditionCellState = null; - } - } - } - - m_currentItemInEdition = newCurrentItemInEdition; - m_currentRowInEditionState = new RowState(); - - this.UpdateIsBeingEdited(); - } - - // It may occur that the newCurrentItemInEdition was set for a - // Container that is currently out of view, so the newCurrentItemContainer - // was null at this time. We must then ensure the CellStates are - // create for the newCurrentItemContainer when not null even if - // newCurrentItemInEdition == m_currentItemInEdition - if( newCurrentItemContainer != null ) - { - foreach( Cell cell in newCurrentItemContainer.CreatedCells ) - { - var parentColumn = cell.ParentColumn; - if( parentColumn == null ) - continue; - - var cellState = new CellState(); - cellState.SetContentBeforeRowEdition( cell.Content ); - - parentColumn.CurrentRowInEditionCellState = cellState; - } - } - } - - #endregion - - #region SELECTION/CURRENT - - internal bool UseDragToSelectBehavior - { - get - { - return false; - } - } - - internal bool IsSetCurrentInProgress - { - get - { - return m_flags[ ( int )DataGridControlFlags.IsSetCurrentInProgress ]; - } - set - { - m_flags[ ( int )DataGridControlFlags.IsSetCurrentInProgress ] = value; - } - } - - internal void QueueClearCurrentColumn( object currentItem ) - { - if( m_queueClearCurrentColumn != null ) - { - m_queueClearCurrentColumn.Abort(); - m_queueClearCurrentColumn = null; - } - - m_queueClearCurrentColumn = this.Dispatcher.BeginInvoke( System.Windows.Threading.DispatcherPriority.DataBind, - new ParametrizedGenericHandler( ClearCurrentColumnHandler ), currentItem ); - } - - internal void AddToSelectedContexts( DataGridContext context ) - { - if( !m_selectedContexts.Contains( context ) ) - m_selectedContexts.Add( context ); - } - - internal void RemoveFromSelectedContexts( DataGridContext context ) - { - m_selectedContexts.Remove( context ); - } - - private void ClearCurrentColumnHandler( object oldCurrentItem ) - { - try - { - DataGridContext currentDataGridContext = this.CurrentContext; - - //the old data item was nescessarily the current item since only the current item can be in edit mode. - if( currentDataGridContext.InternalCurrentItem == oldCurrentItem ) - { - try - { - currentDataGridContext.SetCurrent( oldCurrentItem, null, null, null, false, false, - this.SynchronizeSelectionWithCurrent, AutoScrollCurrentItemSourceTriggers.Editing ); - } - catch( DataGridException ) - { - // We swallow the exception if it occurs because of a validation error or Cell was read-only or any other GridException. - } - } - } - finally - { - m_queueClearCurrentColumn = null; - } - } - - private void UpdateCurrentContextOnThemeChanged( DataGridContext currentContext ) - { - CustomItemContainerGenerator generator = this.CustomItemContainerGenerator; - - // the CurrentContext is the master DataGridContext, and this one will never change - if( currentContext == this.DataGridContext ) - return; - - object newCurrentItem = currentContext.CurrentItem; - - // Try to get the new DataGridContext mathing the old one (containing the old CurrentItem). - DataGridContext newCurrentContext = this.UpdateCurrentContextRecursive( this.DataGridContext, currentContext, out newCurrentItem ); - - // If it none was found, affect the master DataGridContext - if( newCurrentContext == null ) - { - Debug.WriteLine( "Unable to find a matching DataGridContext" ); - this.SetCurrentDataGridContextHelper( this.DataGridContext ); - } - else - { - // Affect the newly found DataGridContext - this.SetCurrentDataGridContextHelper( newCurrentContext ); - - // Set it as current using the old context CurrentItem, CurrentColumn - newCurrentContext.SetCurrent( newCurrentItem, null, null, currentContext.CurrentColumn, false, false, - this.SynchronizeSelectionWithCurrent, AutoScrollCurrentItemSourceTriggers.ThemeChanged ); - } - } - - private DataGridContext UpdateCurrentContextRecursive( DataGridContext parentDataGridContext, DataGridContext oldCurrentDataGridContext, out object newCurrentItem ) - { - if( parentDataGridContext == null ) - { - newCurrentItem = null; - return null; - } - - foreach( DataGridContext childContext in parentDataGridContext.GetChildContexts() ) - { - if( childContext.SourceDetailConfiguration == oldCurrentDataGridContext.SourceDetailConfiguration ) - { - object oldCurrentItem = oldCurrentDataGridContext.CurrentItem; - - System.Data.DataView dataView = ItemsSourceHelper.TryGetDataViewFromDataGridContext( childContext ); - - System.Data.DataRowView oldCurrentDataRowView = oldCurrentItem as System.Data.DataRowView; - - if( ( dataView != null ) && ( oldCurrentDataRowView != null ) ) - { - System.Data.DataRow oldDataRow = oldCurrentDataRowView.Row; - - foreach( System.Data.DataRowView dataRowView in dataView ) - { - if( dataRowView.Row == oldDataRow ) - { - newCurrentItem = dataRowView; - return childContext; - } - } - } - else - { - if( childContext.Items.Contains( oldCurrentItem ) ) - { - newCurrentItem = oldCurrentItem; - return childContext; - } - } - } - - DataGridContext foundContext = this.UpdateCurrentContextRecursive( childContext, oldCurrentDataGridContext, out newCurrentItem ); - - if( foundContext != null ) - return foundContext; - } - - newCurrentItem = null; - return null; - } - - #endregion - - #region DRAG TO SELECT - - private AutoScrollManager AutoScrollManager - { - get - { - return m_autoScrollManager; - } - set - { - if( m_autoScrollManager != null ) - { - m_autoScrollManager.AutoScrolled -= this.OnAutoScrollManagerAutoScrolled; - } - - m_autoScrollManager = value; - - if( m_autoScrollManager != null ) - { - m_autoScrollManager.AutoScrolled += this.OnAutoScrollManagerAutoScrolled; - } - } - } - - private void OnPreviewMouseDown_DragToSelect( MouseButtonEventArgs e ) - { - if( !this.UseDragToSelectBehavior ) - return; - - if( e.LeftButton != MouseButtonState.Pressed ) - return; - - var source = e.OriginalSource as DependencyObject; - if( source == null ) - return; - - var container = DataGridControl.GetContainer( source ); - var itemContainer = container as IDataGridItemContainer; - if( itemContainer == null ) - return; - - var dataGridContext = DataGridControl.GetDataGridContext( container ); - if( ( dataGridContext == null ) || ( dataGridContext.DataGridControl != this ) ) - return; - - m_startDragSelection = false; - - if( container is Row ) - { - m_startDragSelection = ( DataGridVirtualizingPanel.GetItemIndex( container ) >= 0 ); - } - } - - private void OnMouseLeftButtonUp_DragToSelect( MouseButtonEventArgs e ) - { - this.AbortDragSelection(); - } - - private void OnLostMouseCapture_DragToSelect( MouseEventArgs e ) - { - this.AbortDragSelection(); - } - - private void OnMouseMove_DragToSelect( MouseEventArgs e ) - { - // Verify if the "Excel like drag selection" should be handled. - if( !this.UseDragToSelectBehavior ) - return; - - if( e.LeftButton != MouseButtonState.Pressed ) - return; - - if( !this.IsKeyboardFocusWithin ) - return; - - var autoScrollManager = this.AutoScrollManager; - if( autoScrollManager != null ) - { - m_startDragSelection = false; - - // This should happen only on the second mouse move after the mouse down. - // The mouse is capture so "MouseMove" and "ButtonUp" events can be handled outside the DataGridControl. - if( !this.IsMouseCaptured ) - { - this.CaptureMouse(); - } - - autoScrollManager.HandleMouseMove( e ); - e.Handled = this.SelectMouseOverElement(); - } - // This should happen only on the first mouse move after the mouse down, if it was detected that DragSelection should be processed. - else if( m_startDragSelection ) - { - m_startDragSelection = false; - - // Before starting the AutoScrollManager, make sure all the conditions that apply in OnPreviewMouseDown_DragToSelect are still valid here. - var source = e.OriginalSource as DependencyObject; - if( source == null ) - return; - - var container = DataGridControl.GetContainer( source ); - var itemContainer = container as IDataGridItemContainer; - if( itemContainer == null ) - return; - - var dataGridContext = DataGridControl.GetDataGridContext( container ); - if( ( dataGridContext == null ) || ( dataGridContext.DataGridControl != this ) ) - return; - - autoScrollManager = new AutoScrollManager( this.ScrollViewer ); - autoScrollManager.Start(); - this.AutoScrollManager = autoScrollManager; - } - } - - private void OnAutoScrollManagerAutoScrolled( object sender, EventArgs e ) - { - Debug.Assert( this.UseDragToSelectBehavior ); - this.SelectMouseOverElement(); - } - - private void AbortDragSelection() - { - var autoScrollManager = this.AutoScrollManager; - if( autoScrollManager != null ) - { - autoScrollManager.Stop(); - this.AutoScrollManager = null; - this.ReleaseMouseCapture(); - } - } - - private bool SelectMouseOverElement() - { - var itemsHost = this.ItemsHost; - var mousePosition = Mouse.GetPosition( itemsHost ); - var hitPosition = new Point(); - - var width = itemsHost.ActualWidth; - var height = itemsHost.ActualHeight; - - //Here, Since we are auto scrolling, the mouse position may be - // out of the bounds of the datagrid. Get the mouse's nearest row or cell. - hitPosition.Y = Math.Min( Math.Max( 0d, mousePosition.Y ), height - 1 ); - hitPosition.X = Math.Min( Math.Max( 0d, mousePosition.X ), width - 1 ); - - var targetItem = itemsHost.InputHitTest( hitPosition ) as DependencyObject; - if( targetItem == null ) - return false; - - var container = DataGridControl.GetContainer( targetItem ); - if( container == null ) - return false; - - var dataGridContext = DataGridControl.GetDataGridContext( container ); - if( ( dataGridContext == null ) || ( DataGridContext.DataGridControl != this ) ) - return false; - - var newPosition = default( SelectionRangePoint ); - - var row = container as Row; - if( row != null ) - { - var sourceDataItemIndex = DataGridVirtualizingPanel.GetItemIndex( row ); - if( sourceDataItemIndex < 0 ) - return false; - - var columnIndex = -1; - - // Dont border finding the cell if we are not in cell selection mode. - if( this.SelectionUnit == DataGrid.SelectionUnit.Cell ) - { - var cell = targetItem as Cell; - if( ( cell == null ) || ( cell.ParentColumn.DataGridControl != this ) ) - { - cell = Cell.FindFromChild( this, targetItem ); - } - - if( cell == null ) - { - // If the cell is still null, It may be because the X mouse position was out of bounds - // an thus, we should take the first or last visible cell in screen - if( mousePosition.X >= 0d && mousePosition.X < itemsHost.Width ) - return false; - - var columnManager = dataGridContext.ColumnVirtualizationManager as TableViewColumnVirtualizationManagerBase; - if( columnManager == null ) - return false; - - var columns = columnManager.GetVisibleFieldNames(); - if( columns.Count <= 0 ) - return false; - - var index = ( mousePosition.X < 0 ) ? 0 : columns.Count - 1; - - columnIndex = dataGridContext.Columns[ columns[ index ] ].VisiblePosition; - } - else - { - columnIndex = cell.ParentColumn.VisiblePosition; - } - } - - var item = dataGridContext.GetItemFromContainer( row ); - - newPosition = SelectionRangePoint.TryCreateRangePoint( dataGridContext, item, sourceDataItemIndex, columnIndex ); - } - else - { - return false; - } - - if( newPosition == null ) - return false; - - m_selectionChangerManager.UpdateSelection( null, newPosition, true, false, SelectionManager.UpdateSelectionSource.MouseMove ); - return true; - } - - #endregion - - public override void OnApplyTemplate() - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - DataGridControl parentGrid = ( dataGridContext != null ) - ? dataGridContext.DataGridControl - : null; - - if( parentGrid == null ) - { - this.SetValue( ParentDataGridControlPropertyKey, this ); - } - - base.OnApplyTemplate(); - - m_scrollViewer = this.Template.FindName( "PART_ScrollViewer", this ) as ScrollViewer; - m_dragDropAdornerDecorator = this.Template.FindName( "PART_DragDropAdornerDecorator", this ) as AdornerDecorator; - - this.CustomItemContainerGenerator.InvalidateIsInUse(); - - m_itemsHost = null; - - Views.ViewBase view = this.GetView(); - - if( view.UseDefaultHeadersFooters ) - { - view.InvokeAddDefaultHeadersFooters(); - } - - // Cache if the view requires to preserve container size - this.ViewPreservesContainerSize = view.PreserveContainerSize; - - // Notify the template was reapplied - if( this.TemplateApplied != null ) - { - this.TemplateApplied( this, EventArgs.Empty ); - } - } - - public bool ExpandGroup( CollectionViewGroup group ) - { - if( group == null ) - throw new ArgumentNullException( "group" ); - - return this.DataGridContext.ExpandGroup( group ); - } - - public bool CollapseGroup( CollectionViewGroup group ) - { - if( group == null ) - throw new ArgumentNullException( "group" ); - - return this.DataGridContext.CollapseGroup( group ); - } - - public bool ToggleGroupExpansion( CollectionViewGroup group ) - { - if( group == null ) - throw new ArgumentNullException( "group" ); - - return this.DataGridContext.ToggleGroupExpansion( group ); - } - - public bool IsGroupExpanded( CollectionViewGroup group ) - { - if( group == null ) - throw new ArgumentNullException( "group" ); - - return this.DataGridContext.IsGroupExpanded( group ); - } - - public bool AreDetailsExpanded( object dataItem ) - { - //This function will work only for master items. - //In the cases where a Detail item is passed to the function, the function will return false. - return this.DataGridContext.AreDetailsExpanded( dataItem ); - } - - public DataGridContext GetChildContext( object parentItem, string relationName ) - { - return this.DataGridContext.GetChildContext( parentItem, relationName ); - } - - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate" )] - public IEnumerable GetChildContexts() - { - return this.DataGridContext.GetChildContexts(); - } - - public DependencyObject GetContainerFromItem( object item ) - { - return this.DataGridContext.GetContainerFromItem( item ); - } - - public Group GetGroupFromCollectionViewGroup( CollectionViewGroup collectionViewGroup ) - { - return this.DataGridContext.GetGroupFromCollectionViewGroup( collectionViewGroup ); - } - - [EditorBrowsable( EditorBrowsableState.Never )] - public DependencyObject GetContainerFromIndex( int index ) - { - return this.DataGridContext.GetContainerFromIndex( index ); - } - - [EditorBrowsable( EditorBrowsableState.Never )] - public int GetIndexFromContainer( DependencyObject container ) - { - return this.DataGridContext.GetIndexFromContainer( container ); - } - - public object GetItemFromContainer( DependencyObject container ) - { - return this.DataGridContext.GetItemFromContainer( container ); - } - - public CollectionViewGroup GetParentGroupFromItem( object item ) - { - return this.DataGridContext.GetParentGroupFromItem( item ); - } - - public IDisposable DeferColumnsUpdate() - { - return this.DataGridContext.DeferColumnsUpdate(); - } - - public bool MoveColumnBefore( ColumnBase current, ColumnBase next ) - { - return this.DataGridContext.MoveColumnBefore( current, next ); - } - - public bool MoveColumnAfter( ColumnBase current, ColumnBase previous ) - { - return this.DataGridContext.MoveColumnAfter( current, previous ); - } - - public bool MoveColumnUnder( ColumnBase current, ColumnBase parent ) - { - return this.DataGridContext.MoveColumnUnder( current, parent ); - } - - [Obsolete( "MoveMergedColumn is obsolete. Use MoveColumnUnder instead." )] - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - public void MoveMergedColumn( ColumnBase columnToMove, ColumnBase parentMergedColumn ) - { - if( !this.MoveColumnUnder( columnToMove, parentMergedColumn ) ) - throw new InvalidOperationException( "Failed to move the column." ); - } - - [Obsolete( "MoveMergedColumn is obsolete. Use MoveColumnUnder instead." )] - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - public void MoveMergedColumn( string columnToMove, string parentMergedColumn ) - { - var level = -1; - var parentColumn = default( ColumnBase ); - - if( level == -1 ) - throw new ArgumentException( "An attempt was made to use a column that is not part of a MergedHeader.", "parentMergedColumn" ); - - ColumnBase childColumn = null; - childColumn = this.Columns[ columnToMove ]; - if( childColumn == null ) - throw new ArgumentException( "An attempt was made to move an invalid child column to a parent merged column.", "childColumn" ); - - if( !this.MoveColumnUnder( childColumn, parentColumn ) ) - throw new InvalidOperationException( "Failed to move the column." ); - } - - protected override Size MeasureOverride( Size constraint ) - { - //By default the measure pass must not be delayed, or if the grid is already loaded or if we are printing. - if( ( !this.DeferInitialLayoutPass ) || ( this.IsLoaded )|| ( !m_isFirstTimeLoaded ) ) - return base.MeasureOverride( constraint ); - - return this.GetStartUpSize( constraint ); - } - - protected override Size ArrangeOverride( Size arrangeBounds ) - { - //By default the measure pass must not be delayed, or if the grid is already loaded or if we are printing. - if( ( !this.DeferInitialLayoutPass ) || ( this.IsLoaded ) || ( !m_isFirstTimeLoaded ) ) - return base.ArrangeOverride( arrangeBounds ); - - return arrangeBounds; - } - - protected override DependencyObject GetContainerForItemOverride() - { - return new DataRow(); - } - - protected override bool IsItemItsOwnContainerOverride( object item ) - { - return ( item is DataRow ); - } - - protected override void ClearContainerForItemOverride( DependencyObject element, object item ) - { - base.ClearContainerForItemOverride( element, item ); - FrameworkElement feContainer = element as FrameworkElement; - - if( ( ( feContainer.IsKeyboardFocused ) || ( feContainer.IsKeyboardFocusWithin ) ) - && ( !this.IsSetFocusInhibited ) ) - { - // If the cleared element contain focus, move the focus on the scrollViewer - this.ForceFocus( this.ScrollViewer ); - } - - var dataGridItemContainer = element as IDataGridItemContainer; - var row = element as Row; - - // Only preserve ContainerSizeState if necessary - if( !this.IsBoundToDataGridVirtualizingCollectionViewBase - && this.ViewPreservesContainerSize ) - { - var dataGridContext = DataGridControl.GetDataGridContext( element ); - - //Save the size state of the container (this will do nothing if no size has been set on the item ). - dataGridContext.SaveContainerSizeState( item, feContainer ); - } - - // Try to get the element as a HeaderFooterItem to avoid - // calling ClearContainer on a Row inside a HeaderFooterItem. - // HeaderFooterItem implements IDataGridItemContainer and we call - // ClearContainer on it if not null. - var hfi = element as HeaderFooterItem; - - // If element is a HeaderFooterItem, then it cannot be a Row - if( hfi != null ) - { - row = Row.FromContainer( hfi ); - } - - // Special handling case for the Row class when it is not in a HeaderFooterItem - if( row != null ) - { - //cancel edit if applicable and preserve state of the row. - if( row.IsBeingEdited ) - { - var oldRowEditionState = m_currentRowInEditionState.Clone(); - var oldColumnsStates = new Dictionary(); - - //Debug.Assert( item == m_currentItemInEdition, "The current item being edited on the DataGridControl differs from the one of the currently edited container." ); - - // We can use row because there is only one row in edition in the DataGridControl - foreach( Cell cell in row.CreatedCells ) - { - var parentColumn = cell.ParentColumn; - if( parentColumn == null ) - continue; - - oldColumnsStates.Add( parentColumn, parentColumn.CurrentRowInEditionCellState.Clone() ); - } - - try - { - row.CancelEdit(); - } - catch( InvalidOperationException ) - { - // CancelEdit can throw if we call it when we are in the state of ending the edit process. - } - - // We do not clear any thing when the item is its own container. - if( !this.IsItemItsOwnContainerOverride( item ) ) - { - // Call the ClearContainer on the correct HeaderFooterItem if not null - // to correctly unregister the HeaderFooterItem from the Loaded event - // else directly on the Row - if( hfi != null ) - { - ( ( IDataGridItemContainer )hfi ).ClearContainer(); - } - else - { - ( ( IDataGridItemContainer )row ).ClearContainer(); - } - } - - m_currentRowInEditionState = oldRowEditionState; - - foreach( ColumnBase column in oldColumnsStates.Keys ) - { - column.CurrentRowInEditionCellState = oldColumnsStates[ column ]; - } - - // Though the row state is preserved, the DataGridControl is not in editing anymore. - m_currentItemInEdition = null; - this.UpdateIsBeingEdited(); - } - else - { - // We do not clear any thing when the item is its own container. - if( !this.IsItemItsOwnContainerOverride( item ) ) - { - // Call the ClearContainer on the correct HeaderFooterItem if not null - // to correctly unregister the HeaderFooterItem from the Loaded event - // else directly on the Row - if( hfi != null ) - { - ( ( IDataGridItemContainer )hfi ).ClearContainer(); - } - else - { - ( ( IDataGridItemContainer )row ).ClearContainer(); - } - } - } - } - else if( dataGridItemContainer != null ) - { - //If the Container is not directly a Row (data item) or if the first visual child of HFI is not a Row ( row header or footer). - //then call the ClearContainer on the interface (will catch cases such as GroupHeaderControl ). - dataGridItemContainer.ClearContainer(); - } - - var uiElement = element as UIElement; - if( ( uiElement != null ) && ( ( uiElement.IsKeyboardFocusWithin ) || ( uiElement.IsKeyboardFocused ) ) ) - { - // If the element we are cleaning up contains the focus, we ensure to refocus the ScrollViewer to have - // the focus on a valid element of the grid. - this.DelayBringIntoViewAndFocusCurrent( AutoScrollCurrentItemSourceTriggers.FocusChanged ); - } - } - - protected override void PrepareContainerForItemOverride( DependencyObject element, object item ) - { - base.PrepareContainerForItemOverride( element, item ); - - //this is specific to the DataRows from the Original items list... do not want to do that in the Row.PrepareContainer() - - IDataGridItemContainer dataGridItemContainer = element as IDataGridItemContainer; - Row row = element as Row; - - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( element ); - Debug.Assert( dataGridContext != null ); - - if( dataGridItemContainer != null ) - { - dataGridItemContainer.PrepareContainer( dataGridContext, item ); - } - - //Note: the ItemContainerStyle and ItemContainerStyleSelector will only be applied if the container is a Row or Row-derived object. - // Headers, Footers, Group Headers and Group Footers, even if they contains row types will not be affected since its only the "root" container - // that matters ( headers and the such are enclosed within a HeaderFooterItem container ). - - if( row != null ) - { - //First, Check if the GroupConfiguration for the container has an ItemContainerStyle defined. - GroupConfiguration groupConfig = DataGridControl.GetContainerGroupConfiguration( row ); - Style itemContainerStyle = null; - - //If there is a GroupConfiguration present, try to use its ItemContainerStyle - if( groupConfig != null ) - { - //If an ItemContainerStyle is applied on the GroupConfiguration, I want to force it onto the Container. - if( groupConfig.ItemContainerStyle != null ) - { - itemContainerStyle = groupConfig.ItemContainerStyle; - } - //if no Style but a Selector is present, the same is done. - else if( groupConfig.ItemContainerStyleSelector != null ) - { - itemContainerStyle = groupConfig.ItemContainerStyleSelector.SelectStyle( item, row ); - } - } - - //If there is no GroupConfiguration or if there is no ItemContainerStyle defined on it, go look in the DataGridContext - if( itemContainerStyle == null ) - { - //If not, Use the DataGridContext to determine the appropriate ItemContainerStyle to be applied to the container - DataGridContext containerContext = DataGridControl.GetDataGridContext( row ); - if( containerContext == null ) - { - //container did not pass by the CustomItemContainerGenerator - containerContext = this.DataGridContext; - } - - if( containerContext != null ) - { - //If an ItemContainerStyle is applied on the DataGridContext, I want to force it onto the Container. - if( containerContext.ItemContainerStyle != null ) - { - itemContainerStyle = containerContext.ItemContainerStyle; - } - //if no Style but a Selector is present, the same is done. - else if( containerContext.ItemContainerStyleSelector != null ) - { - itemContainerStyle = containerContext.ItemContainerStyleSelector.SelectStyle( item, row ); - } - } - } - - //If an ItemContainerStyle was found anywhere (GroupConfig or Context), assign it to the container. - if( itemContainerStyle != null ) - { - row.Style = itemContainerStyle; - } - else - { - //this condition is for Rows that are recycled from an environment where they had and item container style to one that doesn't... - if( row.ReadLocalValue( Row.StyleProperty ) != DependencyProperty.UnsetValue ) - { - row.ClearValue( Row.StyleProperty ); - } - } - - } // end if row != null ( data items only) - - //The goal of the next section is to ensure that focus is moved to the appropriate element of the visual tree when the container is being prepared. - //This is to ensure that focus will not be left on a control that has been recycled ( and which is no longer the one we want ). - - //This next section I want to perform independently of wether the container is for a [Fixed]Header/Footer, DataItem, Group Header/Footer - //as such, I will re-determine if the item is a Row ( this time digging beyond HeaderFooterItem - - // Only restore ContainerSizeState if necessary - if( !this.IsBoundToDataGridVirtualizingCollectionViewBase && this.ViewPreservesContainerSize ) - { - //Restore the Size of the item (if there was some special size assigned to the item container previously - dataGridContext.RestoreContainerSizeState( item, element as FrameworkElement ); - } - - // We restore the edit state during the OnApplyTemplate of the Row since the cells are not created before that. - } - - protected override void OnKeyDown( KeyEventArgs e ) - { - base.OnKeyDown( e ); - - if( e.Handled ) - return; - - //Only perform the BringItemIntoView if the item focused is within the host panel! - if( ScrollViewerHelper.IsFocusInElement( this.ItemsHost as FrameworkElement ) ) - { - var currentDataGridContext = this.CurrentContext; - - //ensure that the key pressed is a Keyboard Navigation key - switch( e.Key ) - { - //if any of the directional key - case Key.Up: - case Key.Down: - case Key.Left: - case Key.Right: - case Key.Tab: - // Those keys will be handled by Children of the DataGridControl - // if required - break; - - - case Key.Space: - { - var originalSource = e.OriginalSource as DependencyObject; - if( originalSource == null ) - break; - - var container = DataGridControl.GetContainer( originalSource ); - if( container == null ) - break; - - var dataGridContext = DataGridControl.GetDataGridContext( container ); - if( ( dataGridContext == null ) || ( dataGridContext.DataGridControl != this ) ) - break; - - var row = container as Row; - var newPosition = default( SelectionRangePoint ); - - if( row != null ) - { - if( row.IsBeingEdited ) - break; - - var cell = Cell.FindFromChildOrSelf( this, originalSource ); - var item = dataGridContext.GetItemFromContainer( row ); - var itemIndex = DataGridVirtualizingPanel.GetItemIndex( row ); - var column = ( cell != null ) ? cell.ParentColumn : null; - var columnIndex = ( column != null ) ? column.VisiblePosition : -1; - - newPosition = SelectionRangePoint.TryCreateRangePoint( dataGridContext, item, itemIndex, columnIndex ); - } - else - { - break; - } - - if( newPosition != null ) - { - var oldPosition = SelectionRangePoint.TryCreateFromCurrent( DataGridControl.GetDataGridContext( container ) ); - - m_selectionChangerManager.UpdateSelection( oldPosition, newPosition, true, false, SelectionManager.UpdateSelectionSource.SpaceDown ); - - e.Handled = true; - } - } - - break; - - case Key.LWin: - case Key.RWin: - case Key.MediaNextTrack: - case Key.MediaPlayPause: - case Key.MediaPreviousTrack: - case Key.MediaStop: - case Key.System: - case Key.F1: - case Key.F2: // Should be processed as DataGridCommands.BeginEdit - case Key.F3: - case Key.F4: - case Key.F5: - case Key.F6: - case Key.F7: - case Key.F8: - case Key.F9: - case Key.F10: - case Key.F11: - case Key.F12: - case Key.F13: - case Key.F14: - case Key.F15: - case Key.F16: - case Key.F17: - case Key.F18: - case Key.F19: - case Key.F20: - case Key.F21: - case Key.F22: - case Key.F23: - case Key.F24: - case Key.BrowserBack: - case Key.BrowserFavorites: - case Key.BrowserForward: - case Key.BrowserHome: - case Key.BrowserRefresh: - case Key.BrowserSearch: - case Key.BrowserStop: - case Key.CapsLock: - case Key.NumLock: - case Key.Scroll: - case Key.SelectMedia: - case Key.PrintScreen: - case Key.Pause: - case Key.Play: - case Key.Apps: - case Key.Sleep: - case Key.VolumeDown: - case Key.VolumeMute: - case Key.VolumeUp: - case Key.Zoom: - case Key.LaunchApplication1: - case Key.LaunchApplication2: - case Key.LaunchMail: - case Key.LeftAlt: - case Key.RightAlt: - case Key.RightCtrl: - case Key.LeftCtrl: - case Key.RightShift: - case Key.LeftShift: - case Key.Delete: // Should be processed by the ApplicationCommands.Delete - //do not bring into view in those conditions - break; - - //by default, if not a special key, then bring into view the item. - default: - DataGridItemsHost.BringIntoViewKeyboardFocusedElement(); - break; - } - } - } - - protected override void OnPreviewMouseDown( MouseButtonEventArgs e ) - { - if( m_mouseDownUpdateSelectionSource == null ) - { - m_mouseDownUpdateSelectionSource = this.SelectionChangerManager.PushUpdateSelectionSource( SelectionManager.UpdateSelectionSource.MouseDown ); - } - - var currentColumn = this.CurrentColumn; - - m_mouseDownSelectionRangePoint = SelectionRangePoint.TryCreateFromCurrent( this.CurrentContext ); - - base.OnPreviewMouseDown( e ); - - if( e.Handled ) - return; - - var oldDataGridContext = this.CurrentContext; - var oldRow = ( oldDataGridContext == null ) ? null : oldDataGridContext.CurrentRow; - - var source = e.OriginalSource as DependencyObject; - if( source == null ) - return; - - var container = DataGridControl.GetContainer( source ); - if( container == null ) - return; - - var newDataGridContext = DataGridControl.GetDataGridContext( container ); - if( ( newDataGridContext == null ) || ( newDataGridContext.DataGridControl != this ) ) - return; - - var newRow = Row.FromContainer( container ); - - this.OnPreviewMouseDown_DragToSelect( e ); - - if( ( oldRow == null ) || ( !oldRow.IsBeingEdited ) || ( newRow == oldRow ) ) - return; - - var oldCurrentColumn = oldDataGridContext.CurrentColumn; - - bool mouseDownHandled; - Row newFocusedRow; - ColumnBase newFocusedColumn; - - try - { - // If the source is reset during the EndEdit, we move the focus temporarely on the ScrollViewer to prevent some issue - // when the EndEdit cause a Reset (The ScrollViewer was trying to bring into view the old editing Cell). - var focused = this.ForceFocus( this.ScrollViewer ); - if( !focused ) - return; - - using( this.InhibitSetFocus() ) - { - oldRow.EndEdit(); - - // If the source was reset during the EndEdit, Ensure to relayout right away. - // So the mouse down will continue on the new layouted element. - this.UpdateLayout(); - - IInputElement visualHit = this.InputHitTest( e.GetPosition( this ) ); - mouseDownHandled = ( visualHit == null ) || ( !object.ReferenceEquals( visualHit, e.OriginalSource ) ); - newFocusedRow = newRow; - newFocusedColumn = currentColumn; - } - } - catch( DataGridException ) - { - // We swallow exception if it occurs because of a validation error or Cell was read-only or any other GridException. - mouseDownHandled = true; - newFocusedRow = oldRow; - newFocusedColumn = oldCurrentColumn; - } - - if( mouseDownHandled ) - { - if( m_mouseDownUpdateSelectionSource != null ) - { - m_mouseDownUpdateSelectionSource.Dispose(); - m_mouseDownUpdateSelectionSource = null; - } - - this.SetFocusHelper( newFocusedRow, newFocusedColumn, false, true ); - e.Handled = true; - } - } - - protected override void OnPreviewMouseUp( MouseButtonEventArgs e ) - { - if( m_mouseDownUpdateSelectionSource != null ) - { - m_mouseDownUpdateSelectionSource.Dispose(); - m_mouseDownUpdateSelectionSource = null; - } - - base.OnPreviewMouseUp( e ); - - if( e.ChangedButton != MouseButton.Left ) - return; - - var source = e.OriginalSource as DependencyObject; - if( source == null ) - return; - - var container = DataGridControl.GetContainer( source ); - if( ( container == null ) || ( !container.IsKeyboardFocused && !container.IsKeyboardFocusWithin ) ) - return; - - var dataGridContext = DataGridControl.GetDataGridContext( container ); - if( ( dataGridContext == null ) || ( dataGridContext.DataGridControl != this ) ) - return; - - var row = container as Row; - var newPosition = default( SelectionRangePoint ); - var rowIsBeingEdited = false; - - if( row != null ) - { - var cell = Cell.FindFromChildOrSelf( this, source ); - if( ( cell != null ) && ( this.SelectionUnit == SelectionUnit.Cell ) && ( !cell.IsKeyboardFocused ) && ( !cell.IsKeyboardFocusWithin ) ) - return; - - var item = dataGridContext.GetItemFromContainer( row ); - var itemIndex = DataGridVirtualizingPanel.GetItemIndex( row ); - var column = ( cell != null ) ? cell.ParentColumn : null; - var columnIndex = ( column != null ) ? column.VisiblePosition : -1; - - // If we have an error during the EndEdit that prevent the PreviewMouseDown from occuring (since we put e.Handled = true if an exception occurs), - // the PreviewMouseUp will not occur, so it is safe to call UpdateSelection(). - newPosition = SelectionRangePoint.TryCreateRangePoint( dataGridContext, item, itemIndex, columnIndex ); - rowIsBeingEdited = row.IsBeingEdited; - } - else - { - return; - } - - if( newPosition != null ) - { - m_selectionChangerManager.UpdateSelection( m_mouseDownSelectionRangePoint, newPosition, true, rowIsBeingEdited, SelectionManager.UpdateSelectionSource.MouseUp ); - } - } - - protected override void OnMouseLeave( MouseEventArgs e ) - { - if( m_mouseDownUpdateSelectionSource != null ) - { - m_mouseDownUpdateSelectionSource.Dispose(); - m_mouseDownUpdateSelectionSource = null; - } - - base.OnMouseLeave( e ); - } - - protected override void OnIsKeyboardFocusWithinChanged( DependencyPropertyChangedEventArgs e ) - { - base.OnIsKeyboardFocusWithinChanged( e ); - - KeyboardNavigation.SetIsTabStop( this, !( bool )e.NewValue ); - } - - protected override void OnPreviewGotKeyboardFocus( KeyboardFocusChangedEventArgs e ) - { - base.OnPreviewGotKeyboardFocus( e ); - - if( e.Handled || m_inhibitPreviewGotKeyboardFocus.IsSet ) - return; - - var newFocus = e.NewFocus as DependencyObject; - - if( this.NavigationBehavior == NavigationBehavior.None ) - { - if( newFocus != this.ScrollViewer ) - { - e.Handled = true; - this.ForceFocus( this.ScrollViewer ); - } - return; - } - - if( ( newFocus == this ) || ( newFocus == this.ScrollViewer ) ) - { - var currentDataGridContext = this.CurrentContext; - var internalCurrentItem = currentDataGridContext.InternalCurrentItem; - var itemUIElement = default( UIElement ); - - if( ( internalCurrentItem == null ) && ( currentDataGridContext.Items.Count > 0 ) ) - { - //if InternalCurrentItem is null, then soft-select the first item. - internalCurrentItem = currentDataGridContext.Items.GetItemAt( 0 ); - - if( internalCurrentItem != null ) - { - using( this.InhibitSetFocus() ) - { - currentDataGridContext.SetCurrent( internalCurrentItem, null, 0, currentDataGridContext.CurrentColumn, false, false, this.SynchronizeSelectionWithCurrent, - AutoScrollCurrentItemSourceTriggers.FocusChanged ); - } - } - } - - if( internalCurrentItem != null ) - { - //try to fetch the Container for the Internal current item - itemUIElement = currentDataGridContext.GetContainerFromItem( internalCurrentItem ) as UIElement; - - // Special case when the previous element with the focus is now collapsed, the focus must be moved to the ScrollViewer, so the grid is kept focusable. - var focusScrollViewer = ( itemUIElement == null ); - if( !focusScrollViewer ) - { - var headerFooterItem = itemUIElement as HeaderFooterItem; - if( headerFooterItem != null ) - { - focusScrollViewer = headerFooterItem.Visibility == Visibility.Collapsed; - if( !focusScrollViewer ) - { - var container = headerFooterItem.Container as UIElement; - if( container != null ) - { - focusScrollViewer = container.Visibility == Visibility.Collapsed; - } - } - } - } - - //if container exists, then it's visible (or close to it), try to focus it - if( focusScrollViewer ) - { - currentDataGridContext.DelayBringIntoViewAndFocusCurrent( AutoScrollCurrentItemSourceTriggers.FocusChanged ); - - if( newFocus != this.ScrollViewer ) - { - e.Handled = true; - this.ForceFocus( this.ScrollViewer ); - } - } - else - { - e.Handled = true; - this.SetFocusHelper( itemUIElement, currentDataGridContext.CurrentColumn, true, true ); - } - } - else if( newFocus != this.ScrollViewer ) - { - e.Handled = true; - this.ForceFocus( this.ScrollViewer ); - } - - return; - } - - // If the focus was in a popup menu, we don't want to change the selection, so we consider the focus to be outside the grid in that situation. - var oldFocusWasInTheGrid = ( e.OldFocus != null ) && ( TreeHelper.IsDescendantOf( e.OldFocus as DependencyObject, this, false ) ); - var oldCurrentDataGridContext = this.CurrentContext; - var oldRow = default( Row ); - var oldPosition = default( SelectionRangePoint ); - - if( oldCurrentDataGridContext != null ) - { - oldRow = oldCurrentDataGridContext.CurrentRow; - oldPosition = SelectionRangePoint.TryCreateFromCurrent( oldCurrentDataGridContext ); - m_oldColumn = oldCurrentDataGridContext.CurrentCell != null ? new WeakReference( oldCurrentDataGridContext.CurrentCell.ParentColumn ) : m_oldColumn; - } - - var newContainer = this.GetLocalContainer( newFocus ); - var newDataGridContext = ( newContainer == null ) ? null : DataGridControl.GetDataGridContext( newContainer ); - var newRow = Row.FromContainer( newContainer ); - var newCell = newFocus as Cell; - - if( ( newCell == null ) || ( newCell.ParentColumn.DataGridControl != this ) ) - { - newCell = Cell.FindFromChild( this, newFocus ); - } - - var newColumn = ( newCell == null ) ? null : newCell.ParentColumn; - var item = ( newContainer == null ) ? null : newDataGridContext.GetItemFromContainer( newContainer ); - var containerChangedDuringEndEdit = false; - - // Prevent the focus to be moved during the EndEdit since we are changing focus at the moment - using( this.InhibitSetFocus() ) - { - if( ( oldRow != null ) && ( oldRow.IsBeingEdited ) ) - { - var oldCell = ( oldCurrentDataGridContext == null ) ? null : oldCurrentDataGridContext.CurrentCell; - - if( oldRow != newRow ) - { - try - { - var previousNewContainer = newContainer; - oldRow.EndEdit(); - - // We must refetch the container for the current item in case EndEdit triggers a reset on the CustomItemContainerGenerator - // and remap this item to a container other than the one previously fetched - this.UpdateLayout(); - - newContainer = ( item == null ) ? null : newDataGridContext.GetContainerFromItem( item ) as FrameworkElement; - newRow = Row.FromContainer( newContainer ); - newCell = ( newRow == null ) ? null : newRow.Cells[ newColumn ]; - - if( previousNewContainer != newContainer ) - { - e.Handled = true; - containerChangedDuringEndEdit = true; - } - else - { - // If the newFocus is not in the grid anymore, stop the focus. - if( DataGridControl.GetDataGridContext( newFocus ) == null ) - { - e.Handled = true; - newFocus = null; - } - } - } - catch( DataGridException ) - { - e.Handled = true; - return; - } - } - else if( ( oldCell != null ) && ( oldCell != newCell ) ) - { - try - { - oldCell.EndEdit(); - } - catch( DataGridException ) - { - e.Handled = true; - return; - } - } - } - } - - if( item == null ) - return; - - if( newCell != null && newRow != null ) - { - IDisposable inhibitSetFocus = null; - - if( !containerChangedDuringEndEdit ) - { - // Prevent the focus to be moved during the EndEdit since we are changing focus at the moment - inhibitSetFocus = this.InhibitSetFocus(); - } - - try - { - var oldFocusedCell = e.OldFocus as Cell; - var newFocusedElement = e.NewFocus as UIElement; - - // here we check if the oldFocus is the parent of the new focused element because the OnPreviewGotKeyboardFocus - // is called twice if it's the case which give twice the focus and then endsup unselecting the element during the mouseUp - // because during the second updateSelection, the element is already contained then m_updateSelectionOnNextMouseUp set to true - var isNewFocusParentTheOldFocusedCell = ( ( oldFocusedCell != null ) && ( newFocusedElement != null ) ) ? - ( oldFocusedCell != Cell.FindFromChild( this, newFocusedElement ) ) : true; - var sourceDataItemIndex = DataGridVirtualizingPanel.GetItemIndex( newRow ); - - // newCell != newFocus is in fact a way to test if newFocus is a child of the cell. - if( ( newFocus != null ) && ( newCell != newFocus ) && ( !newCell.IsBeingEdited ) && ( newCell.IsCellEditorDisplayed ) ) - { - newCell.BeginEdit(); - } - else if( !newCell.IsCurrent ) - { - //set the current row/column as this cell's - newDataGridContext.SetCurrent( item, newRow, sourceDataItemIndex, newColumn, false, true, false, AutoScrollCurrentItemSourceTriggers.FocusChanged ); - } - - if( isNewFocusParentTheOldFocusedCell ) - { - var rowIsBeingEditedAndCurrentRowNotChanged = this.IsRowBeingEditedAndCurrentRowNotChanged( newRow, oldRow ); - - var newPosition = SelectionRangePoint.TryCreateRangePoint( newDataGridContext, item, sourceDataItemIndex, newCell.ParentColumn.VisiblePosition ); - m_selectionChangerManager.UpdateSelection( oldPosition, newPosition, oldFocusWasInTheGrid, rowIsBeingEditedAndCurrentRowNotChanged, null ); - } - } - catch( DataGridException ) - { - e.Handled = true; - } - finally - { - if( inhibitSetFocus != null ) - { - inhibitSetFocus.Dispose(); - } - } - - return; - } - - if( newRow != null ) - { - if( newRow.IsCurrent ) - return; - - try - { - var currentColumn = default( ColumnBase ); - - // The current column may need to be propagated, unless the focus is being moved to a GroupHeaderControl - // Special case for a row that is always set to NavigationBehavior.CellOnly (like FilterRow), as it needs a current column for the navigation to work propertly. - if( ( ( this.NavigationBehavior == NavigationBehavior.CellOnly ) || ( newRow.NavigationBehavior == NavigationBehavior.CellOnly ) ) - && !( item is GroupHeaderFooterItem ) ) - { - if( ( newDataGridContext != oldCurrentDataGridContext ) && this.AreDetailsFlatten ) - { - currentColumn = newDataGridContext.GetMatchingColumn( oldCurrentDataGridContext, m_oldColumn.Target as ColumnBase ); - } - - if( currentColumn == null ) - { - currentColumn = newDataGridContext.CurrentColumn; - } - - //if there is no current column, - if( currentColumn == null ) - { - //Check what was the last currentColumn before navigating in Row mode, in the case it's navigating again towards a cell (as for the FilterRow for instance). - var oldColumn = m_oldColumn.Target as ColumnBase; - if( ( oldColumn != null ) && ( newDataGridContext == oldCurrentDataGridContext ) ) - { - var fixedCellPanel = newRow.CellsHostPanel as FixedCellPanel; - if( fixedCellPanel != null ) - { - var cell = default( Cell ); - var virtualizingCellCollection = fixedCellPanel.ParentRowCells; - if( virtualizingCellCollection.TryGetBindedCell( oldColumn, out cell ) ) - { - currentColumn = oldColumn; - } - } - } - } - - //If there is no last currentColumn, or it is not available for navigation. - if( currentColumn == null ) - { - //Then use the first visible column - var columns = newDataGridContext.VisibleColumns; - if( columns.Count > 0 ) - { - //First try to find the first navigable column that is visible in the viewport. - var firstFocusableColumn = NavigationHelper.GetFirstVisibleFocusableInViewportColumnIndex( newDataGridContext, newRow ); - if( firstFocusableColumn == -1 ) - { - //If none is found, find the first navigable one. This will make the grid scroll if one is found, since it's currently out-of-view. - firstFocusableColumn = NavigationHelper.GetFirstVisibleFocusableColumnIndex( newDataGridContext, newRow ); - } - if( firstFocusableColumn < 0 ) - throw new DataGridException( "Trying to edit while no cell is focusable. ", this ); - - currentColumn = columns[ firstFocusableColumn ]; - } - } - } - - int sourceDataItemIndex = DataGridVirtualizingPanel.GetItemIndex( newRow ); - - if( currentColumn == null ) - { - IDisposable inhibitSetFocus = null; - - if( !containerChangedDuringEndEdit ) - { - inhibitSetFocus = this.InhibitSetFocus(); - } - - try - { - newDataGridContext.SetCurrent( item, newRow, sourceDataItemIndex, null, true, true, false, AutoScrollCurrentItemSourceTriggers.FocusChanged ); - } - finally - { - if( inhibitSetFocus != null ) - { - inhibitSetFocus.Dispose(); - } - } - } - else - { - e.Handled = true; // We prevent the focus to go on the row since we will move it on a cell - newDataGridContext.SetCurrent( item, newRow, sourceDataItemIndex, currentColumn, true, true, false, AutoScrollCurrentItemSourceTriggers.FocusChanged ); - } - - var columnIndex = ( currentColumn == null ) ? -1 : currentColumn.VisiblePosition; - var rowIsBeingEditedAndCurrentRowNotChanged = this.IsRowBeingEditedAndCurrentRowNotChanged( newRow, oldRow ); - - var newPosition = SelectionRangePoint.TryCreateRangePoint( newDataGridContext, item, sourceDataItemIndex, columnIndex ); - m_selectionChangerManager.UpdateSelection( oldPosition, newPosition, oldFocusWasInTheGrid, rowIsBeingEditedAndCurrentRowNotChanged, null ); - } - catch( DataGridException ) - { - e.Handled = true; - } - - return; - } - - if( newContainer is HeaderFooterItem ) - { - var headerFooterItem = ( HeaderFooterItem )newContainer; - - var inhibitSetFocus = default( IDisposable ); - - if( !containerChangedDuringEndEdit ) - { - inhibitSetFocus = this.InhibitSetFocus(); - } - - try - { - SelectionRangePoint newPosition; - - var currentColumn = newDataGridContext.CurrentColumn; - newDataGridContext.SetCurrent( item, null, -1, currentColumn, true, true, false, AutoScrollCurrentItemSourceTriggers.FocusChanged ); - - var columnIndex = ( currentColumn == null ) ? -1 : currentColumn.VisiblePosition; - - newPosition = SelectionRangePoint.TryCreateRangePoint( newDataGridContext, item, -1, columnIndex ); - - m_selectionChangerManager.UpdateSelection( oldPosition, newPosition, oldFocusWasInTheGrid, false, null ); - } - catch( DataGridException ) - { - e.Handled = true; - return; - } - finally - { - if( inhibitSetFocus != null ) - { - inhibitSetFocus.Dispose(); - } - } - } - } - - protected override void OnMouseLeftButtonDown( MouseButtonEventArgs e ) - { - base.OnMouseLeftButtonDown( e ); - - if( !e.Handled ) - { - e.Handled = true; - this.Focus(); - } - } - - protected override void OnMouseLeftButtonUp( MouseButtonEventArgs e ) - { - base.OnMouseLeftButtonUp( e ); - - if( e.Handled ) - return; - - this.OnMouseLeftButtonUp_DragToSelect( e ); - } - - protected override void OnLostMouseCapture( MouseEventArgs e ) - { - base.OnLostMouseCapture( e ); - - this.OnLostMouseCapture_DragToSelect( e ); - } - - protected override void OnMouseMove( MouseEventArgs e ) - { - base.OnMouseMove( e ); - - if( e.Handled ) - return; - - this.OnMouseMove_DragToSelect( e ); - } - - - protected override void OnPropertyChanged( DependencyPropertyChangedEventArgs e ) - { - base.OnPropertyChanged( e ); - this.OnPropertyChanged( e.Property.Name ); - } - - internal static object GetFixedItemFromContainer( DependencyObject container ) - { - object fixedItem = DataGridControl.GetFixedItem( container ); - if( fixedItem != DataGridControl.NotSet ) - { - return fixedItem; - } - return null; - } - - internal bool ForceFocus( UIElement element ) - { - if( element == null ) - return false; - - using( m_inhibitPreviewGotKeyboardFocus.Set() ) - { - return element.Focus(); - } - } - - internal DependencyObject GetContainerForFixedItem( object item ) - { - Panel fixedHeaderPanel = this.FixedHeadersHostPanel; - if( fixedHeaderPanel != null ) - { - foreach( DependencyObject headerContainer in fixedHeaderPanel.Children ) - { - object containerItem = DataGridControl.GetFixedItem( headerContainer ); - if( containerItem == item ) - { - return headerContainer; - } - } - } - - Panel fixedFooterPanel = this.FixedFootersHostPanel; - if( fixedFooterPanel != null ) - { - foreach( DependencyObject footerContainer in fixedFooterPanel.Children ) - { - object containerItem = DataGridControl.GetFixedItem( footerContainer ); - if( containerItem == item ) - { - return footerContainer; - } - } - } - - return null; - } - - internal void PrepareItemContainer( DependencyObject container, object item ) - { - //this function is called by the CustomItemContainerGenerator to prepare both the ActualDataItems and the custom items (e.g., Headers and Footers) - DataGridControl.SetContainer( container, container ); - DataGridControl.SetIsContainerPrepared( container, true ); - this.PrepareContainerForItemOverride( container, item ); - } - - internal void ClearItemContainer( DependencyObject container, object item ) - { - // For performance reason, it is useless to clear the ContainerProperty. The value is set in DataGridControl.PrepareItemContainer and it contains the - // container itself. Clearing it here to set it back later is pointless. Furthermore, setting and clearing the property cost more than usual since the - // DependencyProperty is inherited. To determine if the container is in use, the DataGridControl.IsContainerPrepared attached property should be use instead. - //DataGridControl.ClearContainer( container ); - DataGridControl.ClearIsContainerPrepared( container ); - this.ClearContainerForItemOverride( container, item ); - } - - internal DependencyObject CreateContainerForItem() - { - DependencyObject container = this.GetContainerForItemOverride(); - - if( container != null ) - { - - // Set a local value for containers to ensure the DefaultStyleKey is correctly applied on this container - container.SetValue( DataGridControl.ParentDataGridControlPropertyKey, this ); - } - - return container; - } - - internal bool IsItemItsOwnContainer( object dataItem ) - { - return this.IsItemItsOwnContainerOverride( dataItem ); - } - - internal void ClearFixedHostPanels() - { - Panel fixedHeaderHostPanel = this.FixedHeadersHostPanel; - if( fixedHeaderHostPanel != null ) - { - DataGridControl.ClearFixedHostPanelHelper( this, fixedHeaderHostPanel.Children ); - } - - Panel fixedFooterHostPanel = this.FixedFootersHostPanel; - if( fixedFooterHostPanel != null ) - { - DataGridControl.ClearFixedHostPanelHelper( this, fixedFooterHostPanel.Children ); - } - } - - internal void ResetFixedRegions() - { - if( m_fixedHeadersHostPanel != null ) - { - DataGridControl.RefreshFixedHeaderFooter( this, m_fixedHeadersHostPanel, this.GetView().FixedHeaders ); - } - - if( m_fixedFootersHostPanel != null ) - { - DataGridControl.RefreshFixedHeaderFooter( this, m_fixedFootersHostPanel, this.GetView().FixedFooters ); - } - } - - internal int GetGlobalGeneratorIndexFromItem( DataGridContext dataGridContext, object item ) - { - return this.CustomItemContainerGenerator.FindIndexForItem( item, dataGridContext ); - } - - internal void ShowWaitCursor() - { - if( m_waitCursorCount == 0 ) - { - Cursor oldCursor = this.ReadLocalValue( FrameworkElement.CursorProperty ) as Cursor; - object oldForceCursor = this.ReadLocalValue( FrameworkElement.ForceCursorProperty ); - - if( oldCursor != DependencyProperty.UnsetValue ) - m_oldCursor = oldCursor; - - if( oldForceCursor != DependencyProperty.UnsetValue ) - m_oldForceCursor = ( bool )oldForceCursor; - } - - UIViewBase uiViewBase = this.GetView() as UIViewBase; - - this.ForceCursor = true; - - this.Cursor = ( uiViewBase != null ) - ? uiViewBase.BusyCursor - : Cursors.Wait; - - m_waitCursorCount++; - } - - internal void HideWaitCursor() - { - m_waitCursorCount--; - Debug.Assert( m_waitCursorCount >= 0 ); - - if( m_waitCursorCount == 0 ) - { - if( m_oldCursor != null ) - { - this.Cursor = m_oldCursor; - m_oldCursor = null; - } - else - { - this.ClearValue( FrameworkElement.CursorProperty ); - } - - if( m_oldForceCursor != null ) - { - this.ForceCursor = m_oldForceCursor.Value; - m_oldForceCursor = null; - } - else - { - this.ClearValue( FrameworkElement.ForceCursorProperty ); - } - } - } - - internal void CleanUpAfterUnload() - { - m_customItemContainerGenerator.CleanupGenerator(); - this.SetValue( ParentDataGridControlPropertyKey, null ); - } - - internal void SynchronizeForeignKeyConfigurations() - { - ForeignKeyConfiguration.UpdateColumnsForeignKeyConfigurations( this.Columns, - this.ItemsSource, - m_itemsSourcePropertyDescriptions, - this.AutoCreateForeignKeyConfigurations ); - } - - - private static bool IsRemoveAllowedForDeleteCommand( IList list ) - { - // If the list has a fixed sized or if it's read only, we won't allow remove. - bool allowRemove = ( !list.IsFixedSize && !list.IsReadOnly ); - - IBindingList bindingList = list as IBindingList; - - // Even if the list does not have a fixed size and is not read only, - // we don't want to allow remove if the list implements IBindingList - // and does not allow remove. - if( ( allowRemove ) - && ( bindingList != null ) ) - { - allowRemove = bindingList.AllowRemove; - } - - // Finally, we won't support remove if the list does support change notifications - // because we need the grid to be notified of the changes to reflect and adjust - // the displayed items. - if( allowRemove ) - { - allowRemove = ItemsSourceHelper.IsSourceSupportingChangeNotification( list ); - } - - return allowRemove; - } - - private static DataTemplate GetTemplateForItem( object item ) - { - DataTemplate retval = item as DataTemplate; - if( retval == null ) - { - if( item.GetType() == typeof( GroupHeaderFooterItem ) ) - { - GroupHeaderFooterItem groupHeaderFooterItem = ( GroupHeaderFooterItem )item; - - retval = groupHeaderFooterItem.Template as DataTemplate; - if( retval == null ) - { - GroupHeaderFooterItemTemplate headerFooterItemTemplate = groupHeaderFooterItem.Template as GroupHeaderFooterItemTemplate; - if( headerFooterItemTemplate != null ) - { - headerFooterItemTemplate.Seal(); - retval = headerFooterItemTemplate.Template; - } - } - } - } - return retval; - } - - private static void ClearFixedHostPanelHelper( DataGridControl dataGrid, UIElementCollection collection ) - { - TableViewScrollViewer tableViewScrollViewer = dataGrid.ScrollViewer as TableViewScrollViewer; - RowSelectorPane rowSelectorPane = ( tableViewScrollViewer != null ) ? tableViewScrollViewer.RowSelectorPane : null; - - foreach( DependencyObject headerFooterItem in collection ) - { - if( rowSelectorPane != null ) - { - rowSelectorPane.FreeRowSelector( headerFooterItem ); - } - - dataGrid.ClearItemContainer( headerFooterItem, GetFixedItem( headerFooterItem ) ); - DataGridControl.SetDataGridContext( headerFooterItem, null ); - } - - collection.Clear(); - - } - - private static void RefreshFixedHeaderFooter( DataGridControl dataGrid, Panel targetPanel, ObservableCollection collection ) - { - TableViewScrollViewer tableViewScrollViewer = dataGrid.ScrollViewer as TableViewScrollViewer; - RowSelectorPane rowSelectorPane = ( tableViewScrollViewer != null ) ? tableViewScrollViewer.RowSelectorPane : null; - - foreach( HeaderFooterItem element in targetPanel.Children ) - { - if( rowSelectorPane != null ) - { - rowSelectorPane.FreeRowSelector( element ); - } - - dataGrid.ClearItemContainer( element, DataGridControl.GetFixedItem( element ) ); - DataGridControl.SetDataGridContext( element, null ); - } - - targetPanel.Children.Clear(); - - var view = dataGrid.GetView(); - DataGridContext dataGridContext = dataGrid.DataGridContext; - - foreach( DataTemplate template in collection ) - { - HeaderFooterItem control = new HeaderFooterItem(); - - control.Content = dataGrid.DataContext; - control.ContentTemplate = template; - - DataGridControl.SetDataGridContext( control, dataGridContext ); - dataGrid.PrepareItemContainer( control, template ); - - DataGridControl.SetFixedItem( control, template ); - GroupLevelIndicatorPane.SetGroupLevel( control, -1 ); - - targetPanel.Children.Add( control ); - } - - } - - private void ReapplyTemplate() - { - ControlTemplate template = this.Template; - - if( template != null ) - { - this.ClearFixedHostPanels(); - - bool localTemplate = ( this.ReadLocalValue( TemplateProperty ) != DependencyProperty.UnsetValue ); - this.Template = new ControlTemplate(); - - if( localTemplate ) - { - this.Template = template; - } - else - { - this.ClearValue( TemplateProperty ); - } - - m_scrollViewer = null; - } - } - - private bool IsRowBeingEditedAndCurrentRowNotChanged( Row newRow, Row oldRow ) - { - bool rowIsBeingEditedAndCurrentRowNotChanged = newRow.IsBeingEdited; - - if( rowIsBeingEditedAndCurrentRowNotChanged ) - { - rowIsBeingEditedAndCurrentRowNotChanged &= ( newRow == oldRow ); - } - - return rowIsBeingEditedAndCurrentRowNotChanged; - } - - private FrameworkElement GetLocalContainer( DependencyObject container ) - { - if( container == null ) - return null; - - var candidate = DataGridControl.GetContainer( container ); - while( candidate != null ) - { - if( ( candidate is IDataGridItemContainer ) && ( candidate is FrameworkElement ) ) - { - var dataGridContext = DataGridControl.GetDataGridContext( candidate ); - if( dataGridContext == null ) - break; - - var dataGridControl = dataGridContext.DataGridControl; - if( dataGridControl == this ) - return ( FrameworkElement )candidate; - - candidate = dataGridControl; - } - - var parent = TreeHelper.GetParent( candidate ); - if( parent == null ) - break; - - candidate = DataGridControl.GetContainer( parent ); - } - - return null; - } - - private Size GetStartUpSize( Size constraint ) - { - double width = this.Width; - double minWidth = this.MinWidth; - double maxWidth = this.MaxWidth; - - double height = this.Height; - double minHeight = this.MinHeight; - double maxHeight = this.MaxHeight; - - if( double.IsNaN( width ) ) - { - width = constraint.Width; - } - - if( double.IsNaN( height ) ) - { - height = constraint.Height; - } - - if( !double.IsPositiveInfinity( maxWidth ) ) - { - width = Math.Min( maxWidth, width ); - } - - if( !double.IsPositiveInfinity( maxHeight ) ) - { - height = Math.Min( maxHeight, height ); - } - - if( ( width < minWidth ) || ( double.IsPositiveInfinity( width ) ) ) - { - width = minWidth; - } - - if( ( height < minHeight ) || ( double.IsPositiveInfinity( height ) ) ) - { - height = minHeight; - } - - return new Size( width, height ); - } - - private delegate void ParametrizedGenericHandler( object param ); - private delegate void DelayedSetFocusHelperHandler( bool forceFocus, bool preserveEditorFocus ); - private delegate bool GenericHandler(); - - #region INotifyPropertyChanged Members - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void OnNotifyPropertyChanged( PropertyChangedEventArgs e ) - { - var handler = this.PropertyChanged; - if( handler == null ) - return; - - handler.Invoke( this, e ); - } - - private void OnPropertyChanged( string propertyName ) - { - this.OnNotifyPropertyChanged( new PropertyChangedEventArgs( propertyName ) ); - } - - #endregion - - #region IWeakEventListener Members - - 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( managerType == typeof( PropertyChangedEventManager ) ) - { - var dataGridCollectionView = this.ItemsSource as DataGridCollectionViewBase; - var eventArgs = e as PropertyChangedEventArgs; - - if( sender == dataGridCollectionView ) - { - this.OnDataGridCollectionView_PropertyChanged( dataGridCollectionView, eventArgs ); - } - } - else if( managerType == typeof( CollectionChangedEventManager ) ) - { - this.OnDataGridDetailDescriptionsChanged( sender as DataGridDetailDescriptionCollection, ( NotifyCollectionChangedEventArgs )e ); - } - else if( managerType == typeof( ProxyCollectionRefreshEventManager ) ) - { - this.OnDataGridCollectionView_ProxyCollectionRefresh( sender as DataGridCollectionView, e ); - } - else if( managerType == typeof( ProxyGroupDescriptionsChangedEventManager ) ) - { - this.OnDataGridCollectionView_ProxyGroupDescriptionsChanged( sender as DataGridCollectionView, ( NotifyCollectionChangedEventArgs )e ); - } - else if( managerType == typeof( ProxySortDescriptionsChangedEventManager ) ) - { - this.OnDataGridCollectionView_ProxySortDescriptionsChanged( sender as DataGridCollectionView, ( NotifyCollectionChangedEventArgs )e ); - } - else if( managerType == typeof( ConnectionStateChangedEventManager ) ) - { - this.OnDataGridVirtualizingCollectionViewBase_ConnectionStateChanged( sender as DataGridVirtualizingCollectionViewBase, e ); - } - else if( managerType == typeof( ConnectionErrorChangedEventManager ) ) - { - this.OnDataGridVirtualizingCollectionViewBase_ConnectionErrorChanged( sender as DataGridVirtualizingCollectionViewBase, e ); - } - else if( managerType == typeof( FrameworkElementUnloadedEventManager ) ) - { - this.UnhookToUnloaded(); - this.SaveDataGridContextState( this.DataGridContext, true, int.MaxValue ); - this.CleanUpAfterUnload(); - } - else - { - return false; - } - - return true; - } - - #endregion - - #region IDocumentPaginatorSource Members - - DocumentPaginator IDocumentPaginatorSource.DocumentPaginator - { - get - { - return null; - } - } - - #endregion - - private IDisposable m_inhibitItemsCollectionChanged; // = null - - private Cursor m_oldCursor; // = null; - private bool? m_oldForceCursor; // = null; - private int m_waitCursorCount; // = 0; - - private FrameworkElement m_itemsHost; // = null - private readonly CustomItemContainerGenerator m_customItemContainerGenerator; // = null - - private AutoScrollManager m_autoScrollManager; - private bool m_startDragSelection; - - private object m_currentItemInEdition; // = null - private RowState m_currentRowInEditionState; // = null - - private readonly AutoResetFlag m_inhibitBringIntoView = AutoResetFlagFactory.Create( false ); - private readonly AutoResetFlag m_inhibitSetFocus = AutoResetFlagFactory.Create( false ); - private readonly AutoResetFlag m_inhibitPreviewGotKeyboardFocus = AutoResetFlagFactory.Create( false ); - private readonly AutoScrollCurrentItemSourceTriggersRestrictions m_inhibitAutoScroll = new AutoScrollCurrentItemSourceTriggersRestrictions(); - private DispatcherOperation m_queueBringIntoView; // = null - private DispatcherOperation m_queueSetFocus; // = null - private DispatcherOperation m_queueClearCurrentColumn; // = null - - private Dictionary m_dataGridContextsStateDictionary; - private SelectionManager m_selectionChangerManager; - - private CommandBinding m_copyCommandBinding; // = null; - private CommandBinding m_deleteCommandBinding; // = null; - private CommandBinding m_refreshCommandBinding; // = null; - private IDisposable m_mouseDownUpdateSelectionSource; - - private SelectionRangePoint m_mouseDownSelectionRangePoint; - - private bool m_isFirstTimeLoaded = true; - - private WeakReference m_parentWindow; - private WeakReference m_oldColumn = new WeakReference( null ); - - private BitVector32 m_flags = new BitVector32(); - - [Flags] - private enum DataGridControlFlags - { - SettingFocusOnCell = 1, - IsSetCurrentInProgress = 2, - IsBoundToDataGridVirtualizingCollectionViewBase = 8, - ViewPreservesContainerSize = 16, - DebugSaveRestore = 32, - ItemsSourceChangedDelayed = 64, - SelectedIndexPropertyNeedCoerce = 128, - SelectedItemPropertyNeedCoerce = 256 - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridControl.icon.16x16.bmp b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridControl.icon.16x16.bmp deleted file mode 100644 index 1e169e75..00000000 Binary files a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridControl.icon.16x16.bmp and /dev/null differ diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridDatePicker.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridDatePicker.cs deleted file mode 100644 index b96dfc5c..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridDatePicker.cs +++ /dev/null @@ -1,114 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows.Controls; -using System.Windows; -using System.Windows.Input; -using System.Windows.Controls.Primitives; -using System.Globalization; -using System.Windows.Media; -using Xceed.Wpf.Toolkit.Core; -using Xceed.Wpf.Toolkit.Core.Input; -using System.Diagnostics; - -namespace Xceed.Wpf.DataGrid -{ - [TemplatePart( Name = PART_TextBox, Type = typeof( DatePickerTextBox ) )] - public class DataGridDatePicker : DatePicker, IValidateInput - { - private const string PART_TextBox = "PART_TextBox"; - private Exception _commitException; - - #region Method Overrides - - public override void OnApplyTemplate() - { - base.OnApplyTemplate(); - - DatePickerTextBox textBox = GetTemplateChild( PART_TextBox ) as DatePickerTextBox; - if( textBox != null ) - { - textBox.Background = new SolidColorBrush( Colors.Transparent ); - } - } - - protected override void OnDateValidationError( DatePickerDateValidationErrorEventArgs e ) - { - base.OnDateValidationError( e ); - - // This validation error may have been raised by the "CommitInput()" call. - // If this is the case, use the _commitException member. - if( InputValidationError != null ) - { - InputValidationErrorEventArgs args = ( _commitException != null ) - ? new InputValidationErrorEventArgs( _commitException ) - : new InputValidationErrorEventArgs( e.Exception ); - - InputValidationError( this, args ); - if( args.ThrowException ) - { - throw args.Exception; - } - } - } - - #endregion - - #region Method - - public bool CommitInput() - { - bool returnValue = true; - try - { - // Null or empty string is a null date; - DateTime? dateTime = ( !string.IsNullOrEmpty( Text ) ) - ? DateTime.Parse( Text, DateTimeFormatInfo.GetInstance( CultureInfo.CurrentCulture ) ) - : ( DateTime? )null; - - // This may throw an exception if the typed date is - // part of the blackout dates. - this.SelectedDate = dateTime; - } - catch( Exception e ) - { - _commitException = e; - // Return the TextField to the appropritate value for the current SelectedDate. - // Setting the "Text" property to invalid content for a date was the - // observed behavior for the DatePicker. - // "Invalid" is expected to be an invalid content. - // This will raise the "DateValidationError" event from the datepicker - Text = "Invalid"; - _commitException = null; - returnValue = false; - } - - return returnValue; - } - - #endregion - - #region Events - - public event InputValidationErrorEventHandler InputValidationError; - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridException.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridException.cs deleted file mode 100644 index 592fa340..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridException.cs +++ /dev/null @@ -1,130 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Diagnostics; -using System.Runtime.Serialization; - -namespace Xceed.Wpf.DataGrid -{ - [Serializable] - public class DataGridException : Exception - { - public DataGridException() - : base() - { - } - - public DataGridException( string message ) - : base( message ) - { - } - - public DataGridException( string message, DataGridControl dataGridControl ) - : base( message ) - { - this.DataGridControl = dataGridControl; - } - - public DataGridException( string message, Exception innerException ) - : base( message, innerException ) - { - } - - public DataGridException( string message, Exception innerException, DataGridControl dataGridControl ) - : base( message, innerException ) - { - this.DataGridControl = dataGridControl; - } - - protected DataGridException( SerializationInfo info, StreamingContext context ) - : base( info, context ) - { - } - - #region DataGridControl Property - - public DataGridControl DataGridControl - { - get; - private set; - } - - #endregion - - internal static Exception Create( string message, DataGridControl dataGridControl, string argument = "" ) - { - Exception exception; - - var exceptionType = typeof( T ); - - if( typeof( ArgumentException ) == exceptionType ) - { - exception = new ArgumentException( message, argument ); - } - else if( typeof( ArgumentNullException ) == exceptionType ) - { - exception = new ArgumentNullException( message ); - } - else if( typeof( ArgumentOutOfRangeException ) == exceptionType ) - { - exception = new ArgumentOutOfRangeException( argument, message ); - } - else if( typeof( IndexOutOfRangeException ) == exceptionType ) - { - exception = new IndexOutOfRangeException( message ); - } - else if( typeof( InvalidOperationException ) == exceptionType ) - { - exception = new InvalidOperationException( message ); - } - else if( typeof( NotSupportedException ) == exceptionType ) - { - exception = new NotSupportedException( message ); - } - else if( typeof( DataGridException ) == exceptionType ) - { - return new DataGridException( message, dataGridControl ); - } - else if( typeof( DataGridInternalException ) == exceptionType ) - { - return new DataGridInternalException( message, dataGridControl ); - } - else - { - exception = new Exception( message ); - } - - if( dataGridControl != null ) - { - var name = dataGridControl.GridUniqueName; - if( string.IsNullOrEmpty( name ) ) - { - name = dataGridControl.Name; - } - - if( !string.IsNullOrEmpty( name ) ) - { - exception.Source = name; - } - } - - Debug.Assert( exception != null ); - - return exception; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridFocusException.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridFocusException.cs deleted file mode 100644 index cc448300..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridFocusException.cs +++ /dev/null @@ -1,48 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Runtime.Serialization; - -namespace Xceed.Wpf.DataGrid -{ - [Serializable] - public class DataGridFocusException : DataGridException - { - public DataGridFocusException() - : base() - { - } - - public DataGridFocusException( string message ) - : base( message ) - { - } - - public DataGridFocusException( string message, Exception innerException ) - : base( message, innerException ) - { - } - - protected DataGridFocusException( SerializationInfo info, StreamingContext context ) - : base( info, context ) - { - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridInternalException.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridInternalException.cs deleted file mode 100644 index ecdef1f6..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridInternalException.cs +++ /dev/null @@ -1,63 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Runtime.Serialization; -using Xceed.Wpf.DataGrid; - -namespace Xceed.Wpf.DataGrid -{ - [Serializable] - public class DataGridInternalException : DataGridException - { - public DataGridInternalException() - : this( DefaultMessage ) - { - } - - public DataGridInternalException( string message ) - : base( message ) - { - } - - public DataGridInternalException( string message, DataGridControl dataGridControl ) - : base( message, dataGridControl ) - { - } - - public DataGridInternalException( Exception innerException ) - : this( DefaultMessage, innerException ) - { - } - - public DataGridInternalException( string message, Exception innerException ) - : base( message, innerException ) - { - } - - public DataGridInternalException( string message, Exception innerException, DataGridControl dataGridControl ) - : base( message, innerException, dataGridControl ) - { - } - - protected DataGridInternalException( SerializationInfo info, StreamingContext context ) - : base( info, context ) - { - } - - private const string DefaultMessage = "An unexpected internal failure occurred in the Xceed WPF DataGrid control."; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridItemContainerManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridItemContainerManager.cs deleted file mode 100644 index a583c7ef..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridItemContainerManager.cs +++ /dev/null @@ -1,180 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class DataGridItemContainerManager - { - internal DataGridItemContainerManager( IDataGridItemContainer owner ) - { - if( owner == null ) - throw new ArgumentNullException( "owner" ); - - if( !( owner is FrameworkElement ) ) - throw new ArgumentException( "The owner must derive from FrameworkElement.", "owner" ); - - m_owner = owner; - } - - #region CanBeRecycled Property - - internal bool CanBeRecycled - { - get - { - if( m_preparedContainers.Any( item => !item.CanBeRecycled ) ) - return false; - - if( m_unpreparedContainers.Any( item => !item.CanBeRecycled ) ) - return false; - - return true; - } - } - - #endregion - - internal void Prepare( DataGridContext dataGridContext, object dataItem ) - { - m_containersPrepared = true; - m_dataGridContext = dataGridContext; - m_dataItem = dataItem; - - this.Update(); - } - - internal void Clear( bool isRecyclingCandidate ) - { - m_containersPrepared = false; - m_dataGridContext = null; - m_dataItem = null; - - try - { - this.ClearContainers( isRecyclingCandidate ); - } - finally - { - m_unpreparedContainers.Clear(); - m_preparedContainers.Clear(); - } - } - - internal void CleanRecyclingCandidates() - { - var newContainers = m_owner.GetTemplatedChildDataGridItemContainers().ToList(); - - foreach( var container in newContainers ) - { - container.IsRecyclingCandidate = false; - container.CleanRecyclingCandidate(); - } - } - - internal void Update() - { - var newContainers = m_owner.GetTemplatedChildDataGridItemContainers().ToList(); - - try - { - this.ClearContainers( newContainers, false ); - } - finally - { - foreach( var container in newContainers ) - { - if( m_preparedContainers.Contains( container ) || m_unpreparedContainers.Contains( container ) ) - continue; - - m_unpreparedContainers.Add( container ); - } - } - - this.PrepareContainers(); - } - - private void PrepareContainers() - { - if( !m_containersPrepared ) - return; - - foreach( var container in m_unpreparedContainers.ToList() ) - { - m_unpreparedContainers.Remove( container ); - m_preparedContainers.Add( container ); - - // Row based objects apply their template through their implementation of PrepareContainer. - // No need to call ApplyTemplate beforehand. - var row = container as Row; - if( row == null ) - { - var fe = container as FrameworkElement; - if( fe != null ) - { - fe.ApplyTemplate(); - } - } - - container.PrepareContainer( m_dataGridContext, m_dataItem ); - } - } - - private void ClearContainers( bool isRecyclingCandidate ) - { - this.ClearContainers( new List( 0 ), isRecyclingCandidate ); - } - - private void ClearContainers( ICollection keep, bool isRecyclingCandidate ) - { - foreach( var container in m_unpreparedContainers.Except( keep ).ToList() ) - { - m_unpreparedContainers.Remove( container ); - - container.IsRecyclingCandidate = isRecyclingCandidate; - - if( isRecyclingCandidate ) - continue; - - var row = container as Row; - if( row != null ) - { - row.ClearCellsHost(); - } - } - - foreach( var container in m_preparedContainers.Except( keep ).ToList() ) - { - m_preparedContainers.Remove( container ); - - container.IsRecyclingCandidate = isRecyclingCandidate; - container.ClearContainer(); - } - } - - private readonly IDataGridItemContainer m_owner; - private readonly ICollection m_unpreparedContainers = new HashSet(); - private readonly ICollection m_preparedContainers = new HashSet(); - - private DataGridContext m_dataGridContext; - private object m_dataItem; - private bool m_containersPrepared; //false - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridItemsHost.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridItemsHost.cs deleted file mode 100644 index 40cd5805..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridItemsHost.cs +++ /dev/null @@ -1,733 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Diagnostics; -using System.Windows; -using System.Windows.Controls.Primitives; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Threading; -using Xceed.Utils.Wpf; - -namespace Xceed.Wpf.DataGrid -{ - public abstract class DataGridItemsHost : FrameworkElement, ICustomVirtualizingPanel - { - static DataGridItemsHost() - { - DataGridControl.ParentDataGridControlPropertyKey.OverrideMetadata( - typeof( DataGridItemsHost ), - new FrameworkPropertyMetadata( new PropertyChangedCallback( OnParentDataGridControlChanged ) ) ); - } - - #region ParentDataGridControl property - - protected DataGridControl ParentDataGridControl - { - get - { - return ( this.CachedRootDataGridContext != null ) ? this.CachedRootDataGridContext.DataGridControl : null; - } - } - - #endregion - - #region CustomItemContainerGenerator property - - private CustomItemContainerGenerator m_generator; - private bool m_generatorInitialized; // = false - protected ICustomItemContainerGenerator CustomItemContainerGenerator - { - get - { - if( !m_generatorInitialized ) - { - this.InitializeGenerator(); - } - - return m_generator; - } - } - - private void InitializeGenerator() - { - DataGridControl dataGridControl = this.ParentDataGridControl; - - if( dataGridControl == null ) - throw new DataGridInternalException( "No DataGridContext set on the DataGridItemsHost while trying to initalize the ItemContainerGenerator" ); - - if( m_generator == null ) - { - m_generator = dataGridControl.CustomItemContainerGenerator; - } - - Debug.Assert( m_generator != null ); - - m_generator.ItemsChanged += this.HandleGeneratorItemsChanged; - m_generator.ContainersRemoved += this.HandleGeneratorContainersRemoved; - m_generator.RecyclingCandidatesCleaned += this.HandleGeneratorRecyclingCandidatesCleaned; - - m_generatorInitialized = true; - } - - #endregion - - #region CachedRootDataGridContext Internal property - - internal DataGridContext CachedRootDataGridContext - { - get - { - // Ensure to get the DataGridContext of the ItemsHost - // if non was explicitly set - if( m_cachedRootDataGridContext == null ) - { - m_cachedRootDataGridContext = DataGridControl.GetDataGridContext( this ); - } - - return m_cachedRootDataGridContext; - } - } - - private DataGridContext m_cachedRootDataGridContext; - - #endregion - - #region DelayBringIntoView Internal Property - - internal bool DelayBringIntoView - { - get; - private set; - } - - #endregion - - #region Children property - - protected internal IList Children - { - get - { - if( m_children == null ) - { - m_children = this.CreateChildCollection(); - } - - return m_children; - } - } - - private IList m_children; - - #endregion - - #region Visual Tree Override - - protected override IEnumerator LogicalChildren - { - get - { - if( m_children != null ) - return m_children.GetEnumerator(); - - return null; - } - } - - protected override int VisualChildrenCount - { - get - { - if( m_children == null ) - return 0; - - return m_children.Count; - } - } - - protected override Visual GetVisualChild( int index ) - { - if( m_children == null ) - throw new InvalidOperationException( "An attempt was made to retrieve a visual child when none exists for this element." ); - - - if( ( index < 0 ) || ( index >= m_children.Count ) ) - throw new ArgumentOutOfRangeException( "index", index, "index must be greater than or equal to zero and less than or equal to the number of contained UI elements." ); - - return m_children[ index ]; - - } - - #endregion - - #region PreviewKeyDown and KeyDown handling overrides - - protected override void OnPreviewKeyDown( KeyEventArgs e ) - { - if( e.Handled ) - return; - - switch( e.Key ) - { - // Handle the System key definition (basically with ALT key pressed) - case Key.System: - this.HandlePreviewSystemKey( e ); - break; - - case Key.Tab: - this.HandlePreviewTabKey( e ); - break; - - case Key.PageUp: - this.HandlePreviewPageUpKey( e ); - break; - - case Key.PageDown: - this.HandlePreviewPageDownKey( e ); - break; - - case Key.Home: - this.HandlePreviewHomeKey( e ); - break; - - case Key.End: - this.HandlePreviewEndKey( e ); - break; - - case Key.Up: - this.HandlePreviewUpKey( e ); - break; - - case Key.Down: - this.HandlePreviewDownKey( e ); - break; - - case Key.Left: - this.HandlePreviewLeftKey( e ); - break; - - case Key.Right: - this.HandlePreviewRightKey( e ); - break; - - default: - base.OnPreviewKeyDown( e ); - break; - } - } - - protected virtual void HandlePreviewSystemKey( KeyEventArgs e ) - { - } - - protected virtual void HandlePreviewTabKey( KeyEventArgs e ) - { - if( e.Handled ) - return; - - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - if( dataGridContext == null ) - return; - - DataGridContext currentDataGridContext = dataGridContext.DataGridControl.CurrentContext; - - if( currentDataGridContext == null ) - return; - - DependencyObject container = currentDataGridContext.GetContainerFromItem( currentDataGridContext.InternalCurrentItem ); - - if( container != null ) - { - KeyboardNavigationMode tabbingMode = KeyboardNavigation.GetTabNavigation( container ); - - if( tabbingMode != KeyboardNavigationMode.None ) - { - if( ( Keyboard.Modifiers == ModifierKeys.None ) || ( Keyboard.Modifiers == ModifierKeys.Shift ) ) - { - DataGridItemsHost.BringIntoViewKeyboardFocusedElement(); - - //Force the "inline" relayout of the panel - //This has no effect if the panel do not have to be updated. - this.UpdateLayout(); - } - } - } - } - - protected virtual void HandlePreviewLeftKey( KeyEventArgs e ) - { - DataGridItemsHost.BringIntoViewKeyboardFocusedElement(); - this.UpdateLayout(); - } - - protected virtual void HandlePreviewRightKey( KeyEventArgs e ) - { - DataGridItemsHost.BringIntoViewKeyboardFocusedElement(); - this.UpdateLayout(); - } - - protected virtual void HandlePreviewUpKey( KeyEventArgs e ) - { - DataGridItemsHost.BringIntoViewKeyboardFocusedElement(); - this.UpdateLayout(); - } - - protected virtual void HandlePreviewDownKey( KeyEventArgs e ) - { - DataGridItemsHost.BringIntoViewKeyboardFocusedElement(); - this.UpdateLayout(); - } - - protected virtual void HandlePreviewPageUpKey( KeyEventArgs e ) - { - } - - protected virtual void HandlePreviewPageDownKey( KeyEventArgs e ) - { - } - - protected virtual void HandlePreviewHomeKey( KeyEventArgs e ) - { - } - - protected virtual void HandlePreviewEndKey( KeyEventArgs e ) - { - } - - protected override void OnKeyDown( KeyEventArgs e ) - { - if( e.Handled ) - return; - - switch( e.Key ) - { - // Handle the System key definition (basically with ALT key pressed) - case Key.System: - this.HandleSystemKey( e ); - break; - - case Key.Tab: - this.HandleTabKey( e ); - break; - - case Key.PageUp: - this.HandlePageUpKey( e ); - break; - - case Key.PageDown: - this.HandlePageDownKey( e ); - break; - - case Key.Home: - this.HandleHomeKey( e ); - break; - - case Key.End: - this.HandleEndKey( e ); - break; - - case Key.Up: - this.HandleUpKey( e ); - break; - - case Key.Down: - this.HandleDownKey( e ); - break; - - case Key.Left: - this.HandleLeftKey( e ); - break; - - case Key.Right: - this.HandleRightKey( e ); - break; - - default: - base.OnKeyDown( e ); - break; - } - } - - protected virtual void HandleSystemKey( KeyEventArgs e ) - { - } - - protected virtual void HandleTabKey( KeyEventArgs e ) - { - } - - protected virtual void HandlePageUpKey( KeyEventArgs e ) - { - } - - protected virtual void HandlePageDownKey( KeyEventArgs e ) - { - } - - protected virtual void HandleHomeKey( KeyEventArgs e ) - { - } - - protected virtual void HandleEndKey( KeyEventArgs e ) - { - } - - protected virtual void HandleUpKey( KeyEventArgs e ) - { - e.Handled = DataGridItemsHost.ProcessMoveFocus( e.Key ); - } - - protected virtual void HandleDownKey( KeyEventArgs e ) - { - e.Handled = DataGridItemsHost.ProcessMoveFocus( e.Key ); - } - - protected virtual void HandleLeftKey( KeyEventArgs e ) - { - e.Handled = DataGridItemsHost.ProcessMoveFocus( e.Key ); - } - - protected virtual void HandleRightKey( KeyEventArgs e ) - { - e.Handled = DataGridItemsHost.ProcessMoveFocus( e.Key ); - } - - #endregion - - protected virtual IList CreateChildCollection() - { - return new ItemsHostUIElementCollection( this ); - } - - [Obsolete( "This OnItemsAdded method is obsolete and is no longer called." )] - protected virtual void OnItemsAdded( GeneratorPosition position, int index, int itemCount ) - { - } - - [Obsolete( "This OnItemsRemoved method is obsolete and is no longer called." )] - protected virtual void OnItemsRemoved( GeneratorPosition position, int index, GeneratorPosition oldPosition, int oldIndex, int itemCount, int itemUICount, IList affectedContainers ) - { - } - - [Obsolete( "The OnItemsMoved method is obsolete and is no longer called." )] - protected virtual void OnItemsMoved( GeneratorPosition position, int index, GeneratorPosition oldPosition, int oldIndex, int itemCount, int itemUICount, IList affectedContainers ) - { - } - - [Obsolete( "The OnItemsReplaced method is obsolete and is no longer called." )] - protected virtual void OnItemsReplaced( GeneratorPosition position, int index, GeneratorPosition oldPosition, int oldIndex, int itemCount, int itemUICount, IList affectedContainers ) - { - } - - protected abstract void OnItemsAdded(); - - protected abstract void OnItemsRemoved( IList affectedContainers ); - - protected abstract void OnItemsReset(); - - protected abstract void OnContainersRemoved( IList removedContainers ); - - protected virtual void OnRecyclingCandidatesCleaned( IList recyclingCandidates ) - { - } - - protected virtual void OnParentDataGridControlChanged( DataGridControl oldValue, DataGridControl newValue ) - { - if( ( m_generator != null ) && ( newValue != null ) ) - { - if( newValue.CustomItemContainerGenerator != m_generator ) - throw new DataGridInternalException( "The custom generator is different on the parent DataGridControl.", newValue ); - } - - // We must ensure that the old ItemsHost clears the Content of the - // ItemContainerGenerator to avoid a container in the tree of the - // old panel is used into the new one. - // - // This also ensures to remove every link between the RowSelectorPane - // and the containers of the old ItemsHost. - // - // This only occurs when not specifying a Theme on the View of the - // DataGridControl and when the System color scheme is changed. - if( ( oldValue != null ) && ( newValue == null ) ) - { - oldValue.CustomItemContainerGenerator.CleanupGenerator(); - } - - if( newValue != null ) - { - //In order to ensure that the ItemsHost has the latest geneartor content ( since we just [re]subscribed to the geneartor events ), - //we invalidate the ItemsHost layout. If the grid was just loaded, then the measure pass that is triggered is bound to be of almost - //no significance (performance wise) since there will be no generation and no preparation of new containers (content does not change). - this.InvalidateMeasure(); - } - else - { - this.ClearCachedRootDataGridContextAndGenerator(); - } - } - - - - internal static bool ProcessMoveFocus( Key key ) - { - bool moveFocusSucceeded = false; - - //1. Determine the direction in which the focus would navigate - FocusNavigationDirection navDirection; - switch( key ) - { - case Key.Down: - navDirection = FocusNavigationDirection.Down; - break; - case Key.Left: - navDirection = FocusNavigationDirection.Left; - break; - case Key.Right: - navDirection = FocusNavigationDirection.Right; - break; - case Key.Up: - navDirection = FocusNavigationDirection.Up; - break; - default: - throw new DataGridInternalException( "An invalid key was processed to move the focus." ); - } - - //2. Call MoveFocus() on the currently focused keyboard element, - // since this is call within the OnKeyDown of the DataGridControl, it would normally mean - // that the focused element is within the DataGridControl - DependencyObject element = Keyboard.FocusedElement as DependencyObject; - UIElement uiElement = element as UIElement; - - // If the focused element is not a UIElement (e.g. : Hyperlink), we go up until we find one. - while( uiElement == null && element != null ) - { - element = TreeHelper.GetParent( element ); - uiElement = element as UIElement; - } - - if( uiElement != null ) - { - uiElement.MoveFocus( new TraversalRequest( navDirection ) ); - - moveFocusSucceeded = !( uiElement == Keyboard.FocusedElement ); - } - - return moveFocusSucceeded; - } - - internal static void BringIntoViewKeyboardFocusedElement() - { - FrameworkElement frameworkElement = Keyboard.FocusedElement as FrameworkElement; - - if( frameworkElement != null ) - frameworkElement.BringIntoView(); - } - - internal static UIElement GetItemsHostContainerFromElement( DataGridItemsHost itemsHost, DependencyObject element ) - { - UIElement uiElement = element as UIElement; - - // If the focused element is not a UIElement (e.g. : Hyperlink), we go up until we find one. - while( ( uiElement == null ) && ( element != null ) ) - { - element = TreeHelper.GetParent( element ); - uiElement = element as UIElement; - } - - if( uiElement == null ) - return null; - - // Try to do a Contains before enumerating - // to avoid manually enumerating if we - // already have a container - if( itemsHost.Children.Contains( uiElement ) ) - { - return uiElement; - } - else - { - foreach( UIElement container in itemsHost.Children ) - { - if( container.IsAncestorOf( uiElement ) ) - { - return container; - } - } - } - - return null; - } - - internal bool ValidateTabKeyHandleIsWithin( FrameworkElement originalSource, KeyboardDevice keyboardDevice ) - { - DependencyObject predictedNextVisual = null; - - //If the original source is not a control (e.g. the cells panel instead of a cell), columns will be used to move focus. - //In the case of a ListBox set with Cycle or Contained navigation mode, we must move in the other direction if on the first or last item, - //since PedictFocus will throw is we use FocusNavigationDirection.First/Last. - if( originalSource != null ) - { - if( ( keyboardDevice.Modifiers & ModifierKeys.Shift ) == ModifierKeys.Shift ) - { - predictedNextVisual = originalSource.PredictFocus( FocusNavigationDirection.Left ); - if( predictedNextVisual == null ) - { - predictedNextVisual = originalSource.PredictFocus( FocusNavigationDirection.Up ); - if( predictedNextVisual == null ) - { - KeyboardNavigationMode navigationMode = ( KeyboardNavigationMode )originalSource.GetValue( KeyboardNavigation.TabNavigationProperty ); - if( navigationMode == KeyboardNavigationMode.Cycle || navigationMode == KeyboardNavigationMode.Contained ) - { - predictedNextVisual = originalSource.PredictFocus( FocusNavigationDirection.Right ); - if( predictedNextVisual == null ) - { - predictedNextVisual = originalSource.PredictFocus( FocusNavigationDirection.Down ); - } - } - } - } - } - else - { - predictedNextVisual = originalSource.PredictFocus( FocusNavigationDirection.Right ); - if( predictedNextVisual == null ) - { - predictedNextVisual = originalSource.PredictFocus( FocusNavigationDirection.Down ); - if( predictedNextVisual == null ) - { - KeyboardNavigationMode navigationMode = ( KeyboardNavigationMode )originalSource.GetValue( KeyboardNavigation.TabNavigationProperty ); - if( navigationMode == KeyboardNavigationMode.Cycle || navigationMode == KeyboardNavigationMode.Contained ) - { - predictedNextVisual = originalSource.PredictFocus( FocusNavigationDirection.Left ); - if( predictedNextVisual == null ) - { - predictedNextVisual = originalSource.PredictFocus( FocusNavigationDirection.Up ); - } - } - } - } - } - } - - if( predictedNextVisual != null ) - { - Cell ownerCell = Cell.FindFromChild( predictedNextVisual ); - - if( ( ownerCell != null ) && ( ownerCell.ParentColumn == this.ParentDataGridControl.CurrentColumn ) ) - { - if( object.Equals( ownerCell.ParentRow.GetEditingDataContext(), this.ParentDataGridControl.CurrentItemInEdition ) ) - return true; - } - } - - return false; - } - - internal bool CanRecycleContainer( DependencyObject container ) - { - if( container == null ) - return false; - - var target = container as IDataGridItemContainer; - if( target != null ) - return target.CanBeRecycled; - - var element = container as UIElement; - if( ( element != null ) && ( element.IsKeyboardFocused || element.IsKeyboardFocusWithin ) ) - return false; - - return true; - } - - private static void OnParentDataGridControlChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - DataGridItemsHost itemsHost = sender as DataGridItemsHost; - - if( itemsHost != null ) - { - DataGridControl newDataGridControl = e.NewValue as DataGridControl; - DataGridControl oldDataGridControl = e.OldValue as DataGridControl; - itemsHost.OnParentDataGridControlChanged( oldDataGridControl, newDataGridControl ); - } - } - - private void ClearCachedRootDataGridContextAndGenerator() - { - if( m_generator != null ) - { - // Clean up the previous generator that was used by the ItemsHost - m_generator.ItemsChanged -= this.HandleGeneratorItemsChanged; - m_generator.ContainersRemoved -= this.HandleGeneratorContainersRemoved; - m_generator.RecyclingCandidatesCleaned -= this.HandleGeneratorRecyclingCandidatesCleaned; - } - m_generatorInitialized = false; - m_cachedRootDataGridContext = null; - } - - private void HandleGeneratorRecyclingCandidatesCleaned( object sender, RecyclingCandidatesCleanedEventArgs e ) - { - this.OnRecyclingCandidatesCleaned( e.RecyclingCandidates ); - } - - private void HandleGeneratorContainersRemoved( object sender, ContainersRemovedEventArgs e ) - { - this.OnContainersRemoved( e.RemovedContainers ); - } - - private void HandleGeneratorItemsChanged( object sender, CustomGeneratorChangedEventArgs e ) - { - // We set this flag to delay any bring into view until a layout pass occured if there is one. - // We don't want the bring into view to occur on a container that may move around during the layout pass. - this.DelayBringIntoView = true; - - switch( e.Action ) - { - case NotifyCollectionChangedAction.Add: - this.OnItemsAdded(); - break; - - case NotifyCollectionChangedAction.Remove: - this.OnItemsRemoved( e.Containers ); - break; - - default: - this.OnItemsReset(); - break; - } - - this.Dispatcher.BeginInvoke( new Action( () => this.DelayBringIntoView = false ), DispatcherPriority.Loaded ); - } - - #region ICustomVirtualizingPanel Members - - void ICustomVirtualizingPanel.BringIntoView( int index ) - { - this.BringIntoViewCore( index ); - } - - protected virtual void BringIntoViewCore( int index ) - { - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridValidationException.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridValidationException.cs deleted file mode 100644 index b1b3917a..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridValidationException.cs +++ /dev/null @@ -1,48 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Runtime.Serialization; - -namespace Xceed.Wpf.DataGrid -{ - [Serializable] - internal class DataGridValidationException : DataGridException - { - public DataGridValidationException() - : base() - { - } - - public DataGridValidationException( string message ) - : base( message ) - { - } - - public DataGridValidationException( string message, Exception innerException ) - : base( message, innerException ) - { - } - - protected DataGridValidationException( SerializationInfo info, StreamingContext context ) - : base( info, context ) - { - } - - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridVirtualizingPanel.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridVirtualizingPanel.cs deleted file mode 100644 index b579a8fb..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataGridVirtualizingPanel.cs +++ /dev/null @@ -1,326 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Diagnostics; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Controls.Primitives; - -namespace Xceed.Wpf.DataGrid -{ - public abstract class DataGridVirtualizingPanel : VirtualizingPanel - { - static DataGridVirtualizingPanel() - { - DataGridControl.ParentDataGridControlPropertyKey.OverrideMetadata( - typeof( DataGridVirtualizingPanel ), new FrameworkPropertyMetadata( new PropertyChangedCallback( OnParentDataGridControlChanged ) ) ); - } - - public IItemContainerGenerator CustomItemContainerGenerator - { - get - { - //when generator is "requested", initialize the VPanel. - if( m_initializedCustomGenerator == false ) - { - this.InitializeDataGridVirtualizingPanel(); - } - - IItemContainerGenerator retval = null; - - ItemsControl control1 = ItemsControl.GetItemsOwner( this ); - if( ( control1 != null ) && ( m_customGenerator != null ) ) - { - if( control1.IsGrouping == true ) - throw new NotSupportedException( "GroupStyles are not supported by the DataGridVirtualizingPanel." ); - - retval = m_customGenerator; - } - else - { - retval = this.ItemContainerGenerator; - } - - return retval; - } - } - - #region ItemCount Property - - public int ItemCount - { - get - { - CustomItemContainerGenerator generator = this.InternalCustomItemContainerGenerator; - - if( generator != null ) - { - return generator.ItemCount; - } - else - { - // See how many items there are - ItemsControl itemsControl = ItemsControl.GetItemsOwner( this ); - - int itemCount; - - if( itemsControl != null ) - { - itemCount = itemsControl.HasItems ? itemsControl.Items.Count : 0; - } - else - { - itemCount = this.Children.Count; - } - - return itemCount; - } - } - } - - #endregion - - #region InternalCustomItemContainerGenerator Property - - private CustomItemContainerGenerator InternalCustomItemContainerGenerator - { - get - { - if( m_initializedCustomGenerator == false ) - { - this.InitializeDataGridVirtualizingPanel(); - - } - - CustomItemContainerGenerator retval = null; - ItemsControl control1 = ItemsControl.GetItemsOwner( this ); - if( ( control1 != null ) && ( control1.IsGrouping == false ) ) - { - retval = m_customGenerator; - } - - return retval; - } - } - - #endregion - - #region ItemIndex Attached Property - - public static readonly DependencyProperty ItemIndexProperty = - DependencyProperty.RegisterAttached( "ItemIndex", typeof( int ), typeof( DataGridVirtualizingPanel ), new UIPropertyMetadata( -1 ) ); - - public static int GetItemIndex( DependencyObject obj ) - { - return ( int )obj.GetValue( DataGridVirtualizingPanel.ItemIndexProperty ); - } - - public static void SetItemIndex( DependencyObject obj, int value ) - { - obj.SetValue( DataGridVirtualizingPanel.ItemIndexProperty, value ); - } - - #endregion ItemIndex Attached Property - - protected sealed override void OnItemsChanged( object sender, ItemsChangedEventArgs args ) - { - //I don't want anybody to override this since we might be hooked to the CustomItemContainerGenerator - base.OnItemsChanged( sender, args ); - - //Ok, I only want to process this if i'm NOT hooked to the CustomItemContainerGenerator - if( this.InternalCustomItemContainerGenerator == null ) - { - switch( args.Action ) - { - //In case of a Reset, nothing to do since the Panel base class has cleared the internal children already! - case NotifyCollectionChangedAction.Reset: - break; - - //If there was a removal (collapsing) - //or if there was a Move (edition of a Sorted field) - case NotifyCollectionChangedAction.Move: - case NotifyCollectionChangedAction.Remove: - //remove the concerned range - int index = args.OldPosition.Index; - - Debug.Assert( index != -1 ); - - this.RemoveInternalChildRange( index, args.ItemCount ); - break; - - //if some items were added (expansion) - case NotifyCollectionChangedAction.Add: - //invalidate layout so that the items will be inserted in place! - this.InvalidateMeasure(); - break; - - case NotifyCollectionChangedAction.Replace: - Debug.Fail( "NotifyCollectionChangedAction.Replace" ); - break; - - default: - break; - } - } - } - - protected override void OnClearChildren() - { - //Stop listening to the events of the System Generator if this one is not being used. - if( ( this.InternalCustomItemContainerGenerator == null ) && ( this.ItemContainerGenerator != null ) ) - { - this.ItemContainerGenerator.RemoveAll(); - } - - base.OnClearChildren(); - } - - private void InitializeDataGridVirtualizingPanel() - { - DataGridControl dataGridControl = ItemsControl.GetItemsOwner( this ) as DataGridControl; - - if( dataGridControl != null ) - { - //Retrieve the Grouping Custom Generator - m_customGenerator = dataGridControl.CustomItemContainerGenerator; - - //Remove all items from the generator, this is to ensure that the panel starts "fresh" with items. - if( this.InternalChildren.Count > 0 ) - { - this.RemoveInternalChildRange( 0, this.InternalChildren.Count ); - } - ( ( IItemContainerGenerator )m_customGenerator ).RemoveAll(); - - m_customGenerator.ItemsChanged += OnCustomGeneratorItemsChanged; - - m_initializedCustomGenerator = true; - } - } - - private void OnCustomGeneratorItemsChanged( object sender, CustomGeneratorChangedEventArgs e ) - { - - switch( e.Action ) - { - //In case of a Reset, nothing to do since the Panel base class has cleared the internal children already! - case NotifyCollectionChangedAction.Reset: - { - if( this.InternalChildren.Count > 0 ) - { - this.RemoveInternalChildRange( 0, this.InternalChildren.Count ); - } - else - { - this.InvalidateMeasure(); - } - } - break; - - //If there was a removal (collapsing) - //or if there was a Move (edition of a Sorted field) - case NotifyCollectionChangedAction.Move: - case NotifyCollectionChangedAction.Remove: - { - var containers = new HashSet( e.Containers ?? new DependencyObject[ 0 ] ); - - if( containers.Count > 0 ) - { - var children = this.InternalChildren; - var from = -1; - var removeCount = 0; - var i = 0; - - while( i < children.Count ) - { - var container = children[ i ]; - - if( containers.Contains( container ) ) - { - containers.Remove( container ); - - if( from < 0 ) - { - from = i; - } - - removeCount++; - i++; - } - else if( removeCount > 0 ) - { - Debug.Assert( from >= 0 ); - this.RemoveInternalChildRange( from, removeCount ); - - from = -1; - removeCount = 0; - } - else - { - i++; - } - } - - if( removeCount > 0 ) - { - Debug.Assert( from >= 0 ); - this.RemoveInternalChildRange( from, removeCount ); - } - } - else - { - this.InvalidateMeasure(); - } - } - break; - - //if some items were added (expansion) - case NotifyCollectionChangedAction.Add: - { - //invalidate layout so that the items will be inserted in place! - this.InvalidateMeasure(); - } - break; - - case NotifyCollectionChangedAction.Replace: - { - Debug.Fail( "NotifyCollectionChangedAction.Replace" ); - } - break; - - default: - break; - } - } - - private static void OnParentDataGridControlChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - DataGridVirtualizingPanel panel = ( DataGridVirtualizingPanel )sender; - - if( ( panel != null ) && ( e.NewValue == null ) && ( panel.m_customGenerator != null ) ) - { - panel.m_customGenerator.ItemsChanged -= panel.OnCustomGeneratorItemsChanged; - panel.m_customGenerator = null; - panel.m_initializedCustomGenerator = false; - } - } - - private bool m_initializedCustomGenerator = false; - private CustomItemContainerGenerator m_customGenerator = null; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataItemEventDescriptor.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataItemEventDescriptor.cs deleted file mode 100644 index e7bdfb8c..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataItemEventDescriptor.cs +++ /dev/null @@ -1,117 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class DataItemEventDescriptor : DataItemEventDescriptorBase - { - #region Constructor - - internal DataItemEventDescriptor( - DataItemTypeDescriptor owner, - EventDescriptor parent, - Type componentType, - Type eventType, - Action addHandler, - Action removeHandler ) - : base( owner, parent ) - { - if( componentType == null ) - throw new ArgumentNullException( "componentType" ); - - if( eventType == null ) - throw new ArgumentNullException( "eventType" ); - - if( addHandler == null ) - throw new ArgumentNullException( "addHandler" ); - - if( removeHandler == null ) - throw new ArgumentNullException( "removeHandler" ); - - m_componentType = componentType; - m_eventType = eventType; - m_addHandler = addHandler; - m_removeHandler = removeHandler; - } - - #endregion - - #region ComponentType Property - - public override Type ComponentType - { - get - { - return m_componentType; - } - } - - private readonly Type m_componentType; - - #endregion - - #region EventType Property - - public override Type EventType - { - get - { - return m_eventType; - } - } - - private readonly Type m_eventType; - - #endregion - - public override void AddEventHandler( object component, Delegate value ) - { - if( component == null ) - return; - - m_addHandler.Invoke( component, value ); - } - - public override void RemoveEventHandler( object component, Delegate value ) - { - if( component == null ) - return; - - m_removeHandler.Invoke( component, value ); - } - - public override int GetHashCode() - { - return base.GetHashCode(); - } - - public override bool Equals( object obj ) - { - return ( obj is DataItemEventDescriptor ) - && ( base.Equals( obj ) ); - } - - #region Private Fields - - private readonly Action m_addHandler; - private readonly Action m_removeHandler; - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataItemEventDescriptorBase.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataItemEventDescriptorBase.cs deleted file mode 100644 index 00179c25..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataItemEventDescriptorBase.cs +++ /dev/null @@ -1,76 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; - -namespace Xceed.Wpf.DataGrid -{ - internal abstract class DataItemEventDescriptorBase : EventDescriptor - { - protected DataItemEventDescriptorBase( DataItemTypeDescriptor owner, EventDescriptor parent ) - : base( parent ) - { - if( owner == null ) - throw new ArgumentNullException( "owner" ); - - m_owner = owner; - } - - #region IsMulticast Property - - public override bool IsMulticast - { - get - { - return typeof( MulticastDelegate ).IsAssignableFrom( this.EventType ); - } - } - - #endregion - - #region Owner Protected Property - - protected DataItemTypeDescriptor Owner - { - get - { - return m_owner; - } - } - - private readonly DataItemTypeDescriptor m_owner; - - #endregion - - public override int GetHashCode() - { - return base.GetHashCode(); - } - - public override bool Equals( object obj ) - { - var descriptor = obj as DataItemEventDescriptorBase; - if( object.ReferenceEquals( descriptor, null ) ) - return false; - - return ( base.Equals( obj ) ) - && ( descriptor.ComponentType == this.ComponentType ) - && ( descriptor.EventType == this.EventType ) - && ( descriptor.IsMulticast == this.IsMulticast ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataItemEventDescriptorFactory.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataItemEventDescriptorFactory.cs deleted file mode 100644 index e5afde0b..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataItemEventDescriptorFactory.cs +++ /dev/null @@ -1,174 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; -using System.Diagnostics; -using System.Globalization; -using System.Reflection; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class DataItemEventDescriptorFactory - { - #region Static Fields - - private static readonly Type s_reflectEventDescriptorType; - - #endregion - - static DataItemEventDescriptorFactory() - { - s_reflectEventDescriptorType = Assembly.GetAssembly( typeof( EventDescriptor ) ).GetType( "System.ComponentModel.ReflectEventDescriptor" ); - } - - internal DataItemEventDescriptorFactory( DataItemTypeDescriptor typeDescriptor ) - { - if( typeDescriptor == null ) - throw new ArgumentNullException( "typeDescriptor" ); - - m_typeDescriptor = typeDescriptor; - } - - internal DataItemEventDescriptor CreateEventDescriptor( EventDescriptor source ) - { - if( !DataItemEventDescriptorFactory.IsReflected( source ) ) - return null; - - var componentType = source.ComponentType; - - EventInfo eventInfo; - try - { - eventInfo = componentType.GetEvent( source.Name, BindingFlags.Public | BindingFlags.Instance ); - if( eventInfo == null ) - return null; - } - catch( AmbiguousMatchException ) - { - return null; - } - - var handlerType = eventInfo.EventHandlerType; - Debug.Assert( handlerType == source.EventType ); - - var creatorHelper = DelegateCreatorHelperFactory.CreateHelper( componentType, handlerType ); - - var addHandler = DataItemEventDescriptorFactory.CreateAddHandler( eventInfo, creatorHelper ); - if( addHandler == null ) - return null; - - var removeHandler = DataItemEventDescriptorFactory.CreateRemoveHandler( eventInfo, creatorHelper ); - if( removeHandler == null ) - return null; - - return new DataItemEventDescriptor( m_typeDescriptor, source, componentType, handlerType, addHandler, removeHandler ); - } - - private static bool IsReflected( EventDescriptor descriptor ) - { - return ( descriptor != null ) - && ( descriptor.GetType() == s_reflectEventDescriptorType ); - } - - private static Action CreateAddHandler( EventInfo eventInfo, IDelegateCreatorHelper helper ) - { - var methodInfo = eventInfo.GetAddMethod(); - if( methodInfo == null ) - return null; - - Debug.Assert( methodInfo.IsPublic ); - - - return helper.CreateAddOrRemoveHandler( methodInfo ); - } - - private static Action CreateRemoveHandler( EventInfo eventInfo, IDelegateCreatorHelper helper ) - { - var methodInfo = eventInfo.GetRemoveMethod(); - if( methodInfo == null ) - return null; - - Debug.Assert( methodInfo.IsPublic ); - - - return helper.CreateAddOrRemoveHandler( methodInfo ); - } - - #region Private Fields - - private readonly DataItemTypeDescriptor m_typeDescriptor; - - #endregion - - #region IDelegateCreatorHelper Private Interface - - private interface IDelegateCreatorHelper - { - Action CreateAddOrRemoveHandler( MethodInfo methodInfo ); - } - - #endregion - - #region DelegateCreatorHelperFactory Private Class - - private static class DelegateCreatorHelperFactory - { - internal static IDelegateCreatorHelper CreateHelper( Type componentType, Type handleType ) - { - return ( IDelegateCreatorHelper )typeof( DelegateCreatorHelper<,> ).MakeGenericType( componentType, handleType ).GetConstructor( Type.EmptyTypes ).Invoke( null ); - } - } - - #endregion - - #region DelegateCreatorHelper<> Private Class - - private sealed class DelegateCreatorHelper : IDelegateCreatorHelper - { - public Action CreateAddOrRemoveHandler( MethodInfo methodInfo ) - { - Debug.Assert( methodInfo != null ); - Debug.Assert( methodInfo.IsPublic ); - Debug.Assert( methodInfo.GetParameters().Length == 1 ); - Debug.Assert( methodInfo.GetParameters()[ 0 ].ParameterType == typeof( THandler ) ); - - if( !typeof( TSource ).IsValueType ) - { - var d = ( Action )Delegate.CreateDelegate( typeof( Action ), methodInfo, false ); - if( d != null ) - return ( source, handler ) => - { - if( !( source is TSource ) ) - return; - - d.Invoke( ( TSource )source, ( THandler )handler ); - }; - } - - return ( source, handler ) => - { - if( !( source is TSource ) ) - return; - - methodInfo.Invoke( source, new object[] { handler } ); - }; - } - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataItemIndexerDescriptor.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataItemIndexerDescriptor.cs deleted file mode 100644 index 430fab8d..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataItemIndexerDescriptor.cs +++ /dev/null @@ -1,108 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid -{ - internal class DataItemIndexerDescriptor : DataItemPropertyDescriptorBase - { - internal DataItemIndexerDescriptor( DataItemTypeDescriptor owner, IndexerDescriptor parent ) - : base( owner, parent, parent.GetValue, ( !parent.IsReadOnly ) ? parent.SetValue : default( Action ), null ) - { - m_descriptor = parent; - } - - #region ComponentType Property - - public sealed override Type ComponentType - { - get - { - return m_descriptor.ComponentType; - } - } - - #endregion - - #region PropertyType Property - - public sealed override Type PropertyType - { - get - { - return m_descriptor.PropertyType; - } - } - - #endregion - - #region DisplayName Property - - public override string DisplayName - { - get - { - return m_descriptor.DisplayName; - } - } - - #endregion - - #region IndexerParameters Internal Property - - internal string IndexerParameters - { - get - { - return m_descriptor.IndexerParameters; - } - } - - #endregion - - public override int GetHashCode() - { - return base.GetHashCode(); - } - - public override bool Equals( object obj ) - { - return ( obj is DataItemIndexerDescriptor ) - && ( base.Equals( obj ) ); - } - - protected override bool MustInhibitValueChanged( object component ) - { - return false; - } - - protected override bool IsValueChangedInhibited( object component ) - { - return false; - } - - protected override void InhibitValueChanged( object component ) - { - } - - protected override void ResetInhibitValueChanged( object component ) - { - } - - private readonly IndexerDescriptor m_descriptor; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataItemPropertyDescriptor.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataItemPropertyDescriptor.cs deleted file mode 100644 index 3630874e..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataItemPropertyDescriptor.cs +++ /dev/null @@ -1,105 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; - -namespace Xceed.Wpf.DataGrid -{ - internal class DataItemPropertyDescriptor : DataItemPropertyDescriptorBase - { - #region Constructor - - internal DataItemPropertyDescriptor( - DataItemTypeDescriptor owner, - PropertyDescriptor parent, - Type componentType, - Type propertyType, - Func getter, - Action setter, - Action resetter ) - : base( owner, parent, getter, setter, resetter ) - { - if( componentType == null ) - throw new ArgumentNullException( "componentType" ); - - if( propertyType == null ) - throw new ArgumentNullException( "propertyType" ); - - m_componentType = componentType; - m_propertyType = propertyType; - } - - #endregion - - #region ComponentType Property - - public sealed override Type ComponentType - { - get - { - return m_componentType; - } - } - - private readonly Type m_componentType; - - #endregion - - #region PropertyType Property - - public sealed override Type PropertyType - { - get - { - return m_propertyType; - } - } - - private readonly Type m_propertyType; - - #endregion - - public override int GetHashCode() - { - return base.GetHashCode(); - } - - public override bool Equals( object obj ) - { - return ( obj is DataItemPropertyDescriptor ) - && ( base.Equals( obj ) ); - } - - protected override bool MustInhibitValueChanged( object component ) - { - return false; - } - - protected override bool IsValueChangedInhibited( object component ) - { - return false; - } - - protected override void InhibitValueChanged( object component ) - { - } - - protected override void ResetInhibitValueChanged( object component ) - { - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataItemPropertyDescriptorBase.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataItemPropertyDescriptorBase.cs deleted file mode 100644 index 0c3c9dfb..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataItemPropertyDescriptorBase.cs +++ /dev/null @@ -1,340 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Diagnostics; - -namespace Xceed.Wpf.DataGrid -{ - internal abstract class DataItemPropertyDescriptorBase : PropertyDescriptor - { - #region Static Fields - - private static readonly object NotInitialized = new object(); - private static readonly object NotSet = new object(); - - #endregion - - protected DataItemPropertyDescriptorBase( - DataItemTypeDescriptor owner, - PropertyDescriptor parent, - Func getter, - Action setter, - Action resetter ) - : base( parent ) - { - if( owner == null ) - throw new ArgumentNullException( "owner" ); - - if( getter == null ) - throw new ArgumentNullException( "getter" ); - - m_owner = owner; - m_getter = getter; - m_setter = setter; - m_resetter = resetter; - } - - #region IsReadOnly Property - - public sealed override bool IsReadOnly - { - get - { - if( m_setter == null ) - return true; - - var attribute = ( ReadOnlyAttribute )this.Attributes[ typeof( ReadOnlyAttribute ) ]; - - return ( attribute != null ) - && ( attribute.IsReadOnly ); - } - } - - #endregion - - #region Owner Protected Property - - protected DataItemTypeDescriptor Owner - { - get - { - return m_owner; - } - } - - private readonly DataItemTypeDescriptor m_owner; - - #endregion - - #region IsValueChangeEventEnabled Private Property - - private bool IsValueChangeEventEnabled - { - get - { - return ( this.SupportsChangeEvents ) - || ( !this.IsReadOnly ); - } - } - - #endregion - - #region DefaultValue Private Property - - private object DefaultValue - { - get - { - if( m_defaultValue == DataItemPropertyDescriptorBase.NotInitialized ) - { - var attribute = ( DefaultValueAttribute )this.Attributes[ typeof( DefaultValueAttribute ) ]; - if( attribute != null ) - { - var propertyType = this.PropertyType; - var value = attribute.Value; - - if( ( value != null ) && ( propertyType.IsEnum ) && ( Enum.GetUnderlyingType( propertyType ) == value.GetType() ) ) - { - value = Enum.ToObject( propertyType, value ); - } - - m_defaultValue = value; - } - else - { - m_defaultValue = DataItemPropertyDescriptorBase.NotSet; - } - } - - return m_defaultValue; - } - } - - private object m_defaultValue = DataItemPropertyDescriptorBase.NotInitialized; - - #endregion - - #region AmbientValue Private Property - - private object AmbientValue - { - get - { - if( m_ambientValue == DataItemPropertyDescriptorBase.NotInitialized ) - { - var attribute = ( AmbientValueAttribute )this.Attributes[ typeof( AmbientValueAttribute ) ]; - if( attribute != null ) - { - m_ambientValue = attribute.Value; - } - else - { - m_ambientValue = DataItemPropertyDescriptorBase.NotSet; - } - } - - return m_ambientValue; - } - } - - private object m_ambientValue = DataItemPropertyDescriptorBase.NotInitialized; - - #endregion - - public override bool ShouldSerializeValue( object component ) - { - if( this.IsReadOnly ) - return this.Attributes.Contains( DesignerSerializationVisibilityAttribute.Content ); - - if( this.DefaultValue != DataItemPropertyDescriptorBase.NotSet ) - return !object.Equals( this.GetValue( component ), this.DefaultValue ); - - return true; - } - - public sealed override object GetValue( object component ) - { - if( component == null ) - return null; - - return m_getter.Invoke( component ); - } - - public sealed override void SetValue( object component, object value ) - { - if( ( component == null ) || this.IsReadOnly ) - return; - - Debug.Assert( m_setter != null ); - - bool inhibit; - - lock( m_syncRoot ) - { - inhibit = this.MustInhibitValueChanged( component ); - - if( inhibit ) - { - this.InhibitValueChanged( component ); - } - } - - try - { - m_setter.Invoke( component, value ); - } - finally - { - if( inhibit ) - { - lock( m_syncRoot ) - { - this.ResetInhibitValueChanged( component ); - } - } - } - - this.OnValueChanged( component, EventArgs.Empty ); - } - - public sealed override bool CanResetValue( object component ) - { - if( this.IsReadOnly ) - return false; - - if( this.DefaultValue != DataItemPropertyDescriptorBase.NotSet ) - return !object.Equals( this.GetValue( component ), this.DefaultValue ); - - if( m_resetter != null ) - return true; - - return ( this.AmbientValue != DataItemPropertyDescriptorBase.NotSet ) - && ( this.ShouldSerializeValue( component ) ); - } - - public sealed override void ResetValue( object component ) - { - if( ( component == null ) || this.IsReadOnly ) - return; - - if( this.DefaultValue != DataItemPropertyDescriptorBase.NotSet ) - { - this.SetValue( component, this.DefaultValue ); - } - else if( this.AmbientValue != DataItemPropertyDescriptorBase.NotSet ) - { - this.SetValue( component, this.AmbientValue ); - } - else if( m_resetter != null ) - { - Debug.Assert( this.CanResetValue( component ) ); - m_resetter.Invoke( component ); - } - } - - public sealed override void AddValueChanged( object component, EventHandler handler ) - { - // There is no need to set the handler if the ValueChanged event will never be triggered. - if( !this.IsValueChangeEventEnabled ) - return; - - lock( m_syncRoot ) - { - // We register only once on the target component. - if( this.SupportsChangeEvents && ( this.GetValueChangedHandler( component ) == null ) ) - { - this.AddValueChangedCore( component ); - } - - base.AddValueChanged( component, handler ); - } - } - - public sealed override void RemoveValueChanged( object component, EventHandler handler ) - { - // There is no need to remove the handler if it was never set in the first place. - if( !this.IsValueChangeEventEnabled ) - return; - - lock( m_syncRoot ) - { - base.RemoveValueChanged( component, handler ); - - // We unregister only when there is no handler left for the target component. - if( this.SupportsChangeEvents && ( this.GetValueChangedHandler( component ) == null ) ) - { - this.RemoveValueChangedCore( component ); - } - } - } - - public override int GetHashCode() - { - return base.GetHashCode(); - } - - public override bool Equals( object obj ) - { - var descriptor = obj as DataItemPropertyDescriptorBase; - if( object.ReferenceEquals( descriptor, null ) ) - return false; - - return ( base.Equals( descriptor ) ) - && ( descriptor.ComponentType == this.ComponentType ) - && ( descriptor.IsReadOnly == this.IsReadOnly ) - && ( descriptor.SupportsChangeEvents == this.SupportsChangeEvents ); - } - - protected sealed override void OnValueChanged( object component, EventArgs e ) - { - if( component == null ) - return; - - lock( m_syncRoot ) - { - if( this.IsValueChangedInhibited( component ) ) - return; - } - - base.OnValueChanged( component, e ); - } - - protected abstract bool MustInhibitValueChanged( object component ); - protected abstract bool IsValueChangedInhibited( object component ); - protected abstract void InhibitValueChanged( object component ); - protected abstract void ResetInhibitValueChanged( object component ); - - protected virtual void AddValueChangedCore( object component ) - { - } - - protected virtual void RemoveValueChangedCore( object component ) - { - } - - #region Private Fields - - private readonly object m_syncRoot = new object(); - private readonly Func m_getter; - private readonly Action m_setter; - private readonly Action m_resetter; - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataItemPropertyDescriptorFactory.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataItemPropertyDescriptorFactory.cs deleted file mode 100644 index db7b91b5..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataItemPropertyDescriptorFactory.cs +++ /dev/null @@ -1,348 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; -using System.Diagnostics; -using System.Globalization; -using System.Linq; -using System.Reflection; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class DataItemPropertyDescriptorFactory - { - #region Static Fields - - private static readonly Type s_reflectPropertyDescriptorType; - - #endregion - - #region Constructor - - static DataItemPropertyDescriptorFactory() - { - s_reflectPropertyDescriptorType = Assembly.GetAssembly( typeof( PropertyDescriptor ) ).GetType( "System.ComponentModel.ReflectPropertyDescriptor" ); - } - - internal DataItemPropertyDescriptorFactory( DataItemTypeDescriptor typeDescriptor ) - { - if( typeDescriptor == null ) - throw new ArgumentNullException( "typeDescriptor" ); - - m_typeDescriptor = typeDescriptor; - } - - #endregion - - internal DataItemPropertyDescriptor CreatePropertyDescriptor( PropertyDescriptor source ) - { - if( !DataItemPropertyDescriptorFactory.IsReflected( source ) ) - return null; - - var componentType = source.ComponentType; - - PropertyInfo propertyInfo; - try - { - propertyInfo = componentType.GetProperty( source.Name, BindingFlags.Public | BindingFlags.Instance ); - if( ( propertyInfo == null ) || DataItemPropertyDescriptorFactory.IsIndexed( propertyInfo ) ) - return null; - } - catch( AmbiguousMatchException ) - { - return null; - } - - var propertyType = propertyInfo.PropertyType; - Debug.Assert( propertyType == source.PropertyType ); - - var creatorHelper = DelegateCreatorHelperFactory.CreateHelper( componentType, propertyType ); - - var getter = DataItemPropertyDescriptorFactory.CreateGetter( propertyInfo, creatorHelper ); - if( getter == null ) - return null; - - var setter = DataItemPropertyDescriptorFactory.CreateSetter( propertyInfo, creatorHelper ); - var resetter = DataItemPropertyDescriptorFactory.CreateResetter( componentType, propertyInfo, creatorHelper ); - - var propertyChangedEvent = this.GetPropertyChangedEvent( propertyInfo.Name ); - if( propertyChangedEvent != null ) - return new ValueChangeDataItemPropertyDescriptor( m_typeDescriptor, source, componentType, propertyType, getter, setter, resetter, propertyChangedEvent ); - - return new DataItemPropertyDescriptor( m_typeDescriptor, source, componentType, propertyType, getter, setter, resetter ); - } - - internal DataItemIndexerDescriptor CreateIndexerDescriptor( IndexerDescriptor source ) - { - var propertyChangedEvent = this.GetPropertyChangedEvent( null ); - if( propertyChangedEvent != null ) - return new ValueChangeDataItemIndexerDescriptor( m_typeDescriptor, source, propertyChangedEvent ); - - return new DataItemIndexerDescriptor( m_typeDescriptor, source ); - } - - private void InitializeEvents() - { - if( m_eventDescriptors != null ) - return; - - m_eventDescriptors = m_typeDescriptor.GetEvents(); - m_notifyPropertyChangedEventDescriptor = ( from ed in m_eventDescriptors.Cast() - where ( ed != null ) - && ( ed.Name == "PropertyChanged" ) - && ( typeof( INotifyPropertyChanged ).IsAssignableFrom( ed.ComponentType ) ) - && ( typeof( PropertyChangedEventHandler ).IsAssignableFrom( ed.EventType ) ) - select ed ).FirstOrDefault(); - } - - private EventDescriptor GetNotifyPropertyChangedEvent() - { - this.InitializeEvents(); - - return m_notifyPropertyChangedEventDescriptor; - } - - private EventDescriptor GetSinglePropertyChangedEvent( string propertyName ) - { - this.InitializeEvents(); - - if( string.IsNullOrEmpty( propertyName ) ) - return null; - - var eventName = string.Format( CultureInfo.InvariantCulture, "{0}Changed", propertyName ); - - return ( from ed in m_eventDescriptors.Cast() - where ( ed != null ) - && ( ed.Name == eventName ) - && ( typeof( EventHandler ).IsAssignableFrom( ed.EventType ) ) - select ed ).FirstOrDefault(); - } - - private EventDescriptor GetPropertyChangedEvent( string propertyName ) - { - var descriptor = this.GetSinglePropertyChangedEvent( propertyName ); - if( descriptor != null ) - return descriptor; - - return this.GetNotifyPropertyChangedEvent(); - } - - private static bool IsReflected( PropertyDescriptor descriptor ) - { - return ( descriptor != null ) - && ( descriptor.GetType() == s_reflectPropertyDescriptorType ); - } - - private static bool IsIndexed( PropertyInfo propertyInfo ) - { - var parameters = propertyInfo.GetIndexParameters(); - - return ( parameters != null ) - && ( parameters.Length > 0 ); - } - - private static Func CreateGetter( PropertyInfo propertyInfo, IDelegateCreatorHelper helper ) - { - if( !propertyInfo.CanRead ) - return null; - - var methodInfo = propertyInfo.GetGetMethod(); - if( methodInfo == null ) - return null; - - Debug.Assert( methodInfo.IsPublic ); - - - return helper.CreateGetter( methodInfo ); - } - - private static Action CreateSetter( PropertyInfo propertyInfo, IDelegateCreatorHelper helper ) - { - if( !propertyInfo.CanWrite ) - return null; - - var methodInfo = propertyInfo.GetSetMethod(); - if( methodInfo == null ) - return null; - - Debug.Assert( methodInfo.IsPublic ); - - - return helper.CreateSetter( methodInfo ); - } - - private static Action CreateResetter( Type componentType, PropertyInfo propertyInfo, IDelegateCreatorHelper helper ) - { - MethodInfo methodInfo; - try - { - methodInfo = componentType.GetMethod( string.Format( CultureInfo.InvariantCulture, "Reset{0}", propertyInfo.Name ), BindingFlags.Public | BindingFlags.Instance, null, Type.EmptyTypes, null ); - if( ( methodInfo == null ) || methodInfo.IsGenericMethod ) - return null; - } - catch( AmbiguousMatchException ) - { - return null; - } - - Debug.Assert( methodInfo.IsPublic ); - - - return helper.CreateResetter( methodInfo ); - } - - #region Private Fields - - private readonly DataItemTypeDescriptor m_typeDescriptor; - private EventDescriptorCollection m_eventDescriptors; //null - private EventDescriptor m_notifyPropertyChangedEventDescriptor; //null - - #endregion - - #region IDelegateCreatorHelper Private Interface - - private interface IDelegateCreatorHelper - { - Func CreateGetter( MethodInfo methodInfo ); - Action CreateSetter( MethodInfo methodInfo ); - Action CreateResetter( MethodInfo methodInfo ); - } - - #endregion - - #region DelegateCreatorHelperFactory Private Class - - private static class DelegateCreatorHelperFactory - { - internal static IDelegateCreatorHelper CreateHelper( Type componentType, Type propertyType ) - { - return ( IDelegateCreatorHelper )typeof( DelegateCreatorHelper<,> ).MakeGenericType( componentType, propertyType ).GetConstructor( Type.EmptyTypes ).Invoke( null ); - } - } - - #endregion - - #region DelegateCreatorHelper<> Private Class - - private sealed class DelegateCreatorHelper : IDelegateCreatorHelper - { - public Func CreateGetter( MethodInfo methodInfo ) - { - Debug.Assert( methodInfo != null ); - Debug.Assert( methodInfo.IsPublic ); - Debug.Assert( methodInfo.GetParameters().Length == 0 ); - Debug.Assert( methodInfo.ReturnType == typeof( TProperty ) ); - - if( typeof( TSource ).IsValueType ) - { - var d = ( ValueTypeGetter )Delegate.CreateDelegate( typeof( ValueTypeGetter ), methodInfo, false ); - if( d != null ) - return ( source ) => - { - if( !( source is TSource ) ) - return default( TProperty ); - - var s = ( TSource )source; - - return d.Invoke( ref s ); - }; - } - else - { - var d = ( Func )Delegate.CreateDelegate( typeof( Func ), methodInfo, false ); - if( d != null ) - return ( source ) => - { - if( !( source is TSource ) ) - return default( TProperty ); - - return d.Invoke( ( TSource )source ); - }; - } - - return ( source ) => - { - if( !( source is TSource ) ) - return default( TProperty ); - - return methodInfo.Invoke( source, null ); - }; - } - - public Action CreateSetter( MethodInfo methodInfo ) - { - Debug.Assert( methodInfo != null ); - Debug.Assert( methodInfo.IsPublic ); - Debug.Assert( methodInfo.GetParameters().Length == 1 ); - Debug.Assert( methodInfo.GetParameters()[ 0 ].ParameterType == typeof( TProperty ) ); - - if( !typeof( TSource ).IsValueType ) - { - var d = ( Action )Delegate.CreateDelegate( typeof( Action ), methodInfo ); - if( d != null ) - return ( source, value ) => - { - if( !( source is TSource ) ) - return; - - d.Invoke( ( TSource )source, ( TProperty )value ); - }; - } - - return ( source, value ) => - { - if( !( source is TSource ) ) - return; - - methodInfo.Invoke( source, new object[] { value } ); - }; - } - - public Action CreateResetter( MethodInfo methodInfo ) - { - Debug.Assert( methodInfo != null ); - Debug.Assert( methodInfo.IsPublic ); - Debug.Assert( methodInfo.GetParameters().Length == 0 ); - - if( !typeof( TSource ).IsValueType ) - { - var d = ( Action )Delegate.CreateDelegate( typeof( Action ), methodInfo ); - if( d != null ) - return ( source ) => - { - if( !( source is TSource ) ) - return; - - d.Invoke( ( TSource )source ); - }; - } - - return ( source ) => - { - if( !( source is TSource ) ) - return; - - methodInfo.Invoke( source, null ); - }; - } - - private delegate TProperty ValueTypeGetter( ref TSource source ); - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataItemTypeDescriptionProvider.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataItemTypeDescriptionProvider.cs deleted file mode 100644 index 745a6f92..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataItemTypeDescriptionProvider.cs +++ /dev/null @@ -1,48 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class DataItemTypeDescriptionProvider : TypeDescriptionProvider - { - #region Constructor - - internal DataItemTypeDescriptionProvider( TypeDescriptionProvider parent ) - : base( parent ) - { - } - - #endregion - - public override ICustomTypeDescriptor GetTypeDescriptor( Type objectType, object instance ) - { - var descriptor = base.GetTypeDescriptor( objectType, instance ); - - return DataItemTypeDescriptionProvider.GetTypeDescriptor( objectType, descriptor ); - } - - internal static ICustomTypeDescriptor GetTypeDescriptor( Type objectType, ICustomTypeDescriptor descriptor ) - { - if( descriptor == null ) - return null; - - return new DataItemTypeDescriptor( descriptor, objectType ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataItemTypeDescriptor.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataItemTypeDescriptor.cs deleted file mode 100644 index 3937ae65..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataItemTypeDescriptor.cs +++ /dev/null @@ -1,512 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics; -using System.Globalization; -using System.Linq; -using System.Reflection; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class DataItemTypeDescriptor : CustomTypeDescriptor - { - #region Static Fields - - private static readonly List s_entries = new List(); - - #endregion - - #region Constructors - - internal DataItemTypeDescriptor( ICustomTypeDescriptor parent, Type objectType ) - : base( parent ) - { - if( parent == null ) - throw new ArgumentNullException( "parent" ); - - m_targetType = objectType; - m_descriptorType = parent.GetType(); - } - - #endregion - - public override EventDescriptorCollection GetEvents() - { - return this.GetEvents( null ); - } - - public override EventDescriptorCollection GetEvents( Attribute[] attributes ) - { - var sourceEvents = base.GetEvents( attributes ); - if( ( sourceEvents == null ) || ( sourceEvents.Count == 0 ) ) - return sourceEvents; - - var entry = this.GetEntry(); - var replaceEvents = default( Dictionary ); - - lock( entry ) - { - replaceEvents = entry.Events; - - if( replaceEvents == null ) - { - replaceEvents = new Dictionary(); - entry.Events = replaceEvents; - - var factory = new DataItemEventDescriptorFactory( this ); - - foreach( var sourceEvent in sourceEvents.Cast() ) - { - var descriptor = factory.CreateEventDescriptor( sourceEvent ); - if( descriptor != null ) - { - replaceEvents.Add( sourceEvent, descriptor ); - } - } - } - - if( replaceEvents.Count == 0 ) - return sourceEvents; - } - - var destinationEvents = new EventDescriptor[ sourceEvents.Count ]; - - for( int i = 0; i < sourceEvents.Count; i++ ) - { - var sourceEvent = sourceEvents[ i ]; - - DataItemEventDescriptor destinationEvent; - if( replaceEvents.TryGetValue( sourceEvent, out destinationEvent ) ) - { - destinationEvents[ i ] = destinationEvent; - } - else - { - destinationEvents[ i ] = sourceEvent; - } - } - - return new EventDescriptorCollection( destinationEvents ); - } - - public override PropertyDescriptorCollection GetProperties() - { - return this.GetProperties( null ); - } - - public override PropertyDescriptorCollection GetProperties( Attribute[] attributes ) - { - var sourceProperties = base.GetProperties( attributes ); - if( ( sourceProperties == null ) || ( sourceProperties.Count == 0 ) ) - return sourceProperties; - - var entry = this.GetEntry(); - var replaceProperties = default( Dictionary ); - - lock( entry ) - { - replaceProperties = entry.Properties; - - if( replaceProperties == null ) - { - replaceProperties = new Dictionary(); - entry.Properties = replaceProperties; - - var factory = new DataItemPropertyDescriptorFactory( this ); - - foreach( var sourceProperty in sourceProperties.Cast() ) - { - var descriptor = factory.CreatePropertyDescriptor( sourceProperty ); - if( descriptor != null ) - { - replaceProperties.Add( sourceProperty, descriptor ); - } - } - } - - if( replaceProperties.Count == 0 ) - return sourceProperties; - } - - var destinationProperties = new PropertyDescriptor[ sourceProperties.Count ]; - - for( int i = 0; i < sourceProperties.Count; i++ ) - { - var sourceProperty = sourceProperties[ i ]; - - DataItemPropertyDescriptor destinationProperty; - if( replaceProperties.TryGetValue( sourceProperty, out destinationProperty ) ) - { - destinationProperties[ i ] = destinationProperty; - } - else - { - destinationProperties[ i ] = sourceProperty; - } - } - - return new PropertyDescriptorCollection( destinationProperties ); - } - - internal DataItemIndexerDescriptor GetIndexer( object[] indexValues ) - { - if( ( indexValues == null ) || ( indexValues.Length <= 0 ) || ( m_targetType == null ) ) - return null; - - var entry = this.GetEntry(); - - lock( entry ) - { - var indexers = entry.Indexers; - var descriptor = default( DataItemIndexerDescriptor ); - var key = new IndexerKey( indexValues ); - - if( ( indexers != null ) && ( indexers.TryGetValue( key, out descriptor ) ) ) - return descriptor; - - var indexer = this.CreateIndexerDescriptor( indexValues ); - if( indexer == null ) - return null; - - var factory = new DataItemPropertyDescriptorFactory( this ); - - descriptor = factory.CreateIndexerDescriptor( indexer ); - if( descriptor == null ) - return null; - - if( indexers == null ) - { - indexers = new Dictionary(); - entry.Indexers = indexers; - } - - indexers.Add( key, descriptor ); - - return descriptor; - } - } - - private IndexerDescriptor CreateIndexerDescriptor( object[] indexValues ) - { - if( ( indexValues == null ) || ( indexValues.Length <= 0 ) || ( m_targetType == null ) ) - return null; - - var best = default( IndexerChoice ); - - foreach( var propertyInfo in m_targetType.GetProperties() ) - { - var candidate = IndexerChoice.GetMatch( propertyInfo, indexValues ); - if( candidate == null ) - continue; - - if( ( best == null ) || ( candidate.CompareTo( best ) > 0 ) ) - { - best = candidate; - } - } - - // No matching indexer was found. - if( best == null ) - return null; - - return IndexerDescriptor.Create( best.Property, indexValues, best.Values ); - } - - private Entry GetEntry() - { - if( m_entry == null ) - { - m_entry = DataItemTypeDescriptor.GetEntry( m_targetType, m_descriptorType ); - } - - return m_entry; - } - - private static Entry GetEntry( Type targetType, Type descriptorType ) - { - Debug.Assert( targetType != null ); - Debug.Assert( descriptorType != null ); - - lock( ( ( ICollection )s_entries ).SyncRoot ) - { - for( int i = s_entries.Count - 1; i >= 0; i-- ) - { - var entry = ( Entry )s_entries[ i ].Target; - - if( entry != null ) - { - if( object.Equals( targetType, entry.TargetType ) && object.Equals( descriptorType, entry.DescriptorType ) ) - return entry; - } - else - { - s_entries.RemoveAt( i ); - } - } - - var result = new Entry( targetType, descriptorType ); - - s_entries.Add( new WeakReference( result ) ); - - return result; - } - } - - private static bool IsNullableType( Type type ) - { - return ( !type.IsValueType ) - || ( type.IsGenericType && ( type.GetGenericTypeDefinition() == typeof( Nullable<> ) ) ); - } - - #region Private Fields - - private readonly Type m_targetType; - private readonly Type m_descriptorType; - private Entry m_entry; //null - - #endregion - - #region Entry Private Class - - private sealed class Entry - { - internal Entry( Type targetType, Type descriptorType ) - { - Debug.Assert( targetType != null ); - Debug.Assert( descriptorType != null ); - - this.TargetType = targetType; - this.DescriptorType = descriptorType; - } - - internal Type TargetType - { - get; - private set; - } - - internal Type DescriptorType - { - get; - private set; - } - - internal Dictionary Events - { - get; - set; - } - - internal Dictionary Properties - { - get; - set; - } - - internal Dictionary Indexers - { - get; - set; - } - } - - #endregion - - #region IndexerKey Private Class - - private sealed class IndexerKey - { - internal IndexerKey( object[] parameters ) - { - Debug.Assert( ( parameters != null ) && ( parameters.Length > 0 ) ); - - m_parameters = parameters; - } - - public override int GetHashCode() - { - var count = Math.Min( m_parameters.Length, 3 ); - var hashCode = 0; - - for( int i = 0; i < count; i++ ) - { - unchecked - { - hashCode *= 13; - hashCode += m_parameters[ i ].GetHashCode(); - } - } - - return hashCode; - } - - public override bool Equals( object obj ) - { - var target = obj as IndexerKey; - if( target == null ) - return false; - - var targetParameters = target.m_parameters; - if( targetParameters.Length != m_parameters.Length ) - return false; - - for( int i = 0; i < m_parameters.Length; i++ ) - { - if( !object.Equals( targetParameters[ i ], m_parameters[ i ] ) ) - return false; - } - - return true; - } - - private readonly object[] m_parameters; - } - - #endregion - - #region IndexerChoice Private Class - - private sealed class IndexerChoice - { - private IndexerChoice( PropertyInfo propertyInfo, object[] values, FitType[] fitTypes ) - { - m_propertyInfo = propertyInfo; - m_values = values; - m_fitTypes = fitTypes; - } - - internal PropertyInfo Property - { - get - { - return m_propertyInfo; - } - } - - internal object[] Values - { - get - { - return m_values; - } - } - - internal static IndexerChoice GetMatch( PropertyInfo propertyInfo, object[] parameterValues ) - { - if( ( propertyInfo == null ) || ( parameterValues == null ) ) - return null; - - var parameters = propertyInfo.GetIndexParameters(); - if( ( parameters == null ) || ( parameters.Length != parameterValues.Length ) ) - return null; - - var values = new object[ parameters.Length ]; - var fitTypes = new FitType[ parameters.Length ]; - - for( int i = 0; i < parameters.Length; i++ ) - { - var parameterType = parameters[ i ].ParameterType; - var parameterValue = parameterValues[ i ]; - var parameterValueType = ( parameterValue != null ) ? parameterValue.GetType() : typeof( object ); - - if( parameterValue == null ) - { - if( !DataItemTypeDescriptor.IsNullableType( parameterType ) ) - return null; - - fitTypes[ i ] = FitType.KeepAsType; - } - else if( !parameterType.IsAssignableFrom( parameterValueType ) ) - { - var converter = TypeDescriptor.GetConverter( parameterType ); - if( ( converter == null ) || !converter.CanConvertFrom( parameterValueType ) ) - return null; - - try - { - parameterValue = converter.ConvertFrom( null, CultureInfo.InvariantCulture, parameterValue ); - } - catch - { - return null; - } - - // An indexer that takes a parameter of any other type than string is considered a better candidate than - // an indexer that takes a parameter of type string. - fitTypes[ i ] = ( typeof( string ).IsAssignableFrom( parameterType ) ) ? FitType.ConvertToString : FitType.ConvertToType; - } - else - { - if( typeof( string ) == parameterType ) - { - fitTypes[ i ] = FitType.KeepAsString; - } - else if( typeof( object ) == parameterType ) - { - fitTypes[ i ] = FitType.KeepAsObject; - } - else - { - fitTypes[ i ] = FitType.KeepAsType; - } - } - - values[ i ] = parameterValue; - } - - return new IndexerChoice( propertyInfo, values, fitTypes ); - } - - internal int CompareTo( IndexerChoice comparand ) - { - if( comparand == null ) - throw new ArgumentNullException( "comparand" ); - - if( comparand.m_fitTypes.Length != m_fitTypes.Length ) - throw new ArgumentException( "The indexer does not have the same number of parameters.", "comparand" ); - - for( int i = 0; i < m_fitTypes.Length; i++ ) - { - var compare = m_fitTypes[ i ].CompareTo( comparand.m_fitTypes[ i ] ); - if( compare != 0 ) - return compare; - } - - return 0; - } - - private readonly PropertyInfo m_propertyInfo; - private readonly object[] m_values; - private readonly FitType[] m_fitTypes; - - private enum FitType - { - None = 0, - ConvertToString, - KeepAsObject, - KeepAsString, - ConvertToType, - KeepAsType, - } - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataRow.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataRow.cs deleted file mode 100644 index 122eb7ad..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataRow.cs +++ /dev/null @@ -1,713 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Diagnostics; -using System.Windows; -using System.Windows.Automation.Peers; -using System.Windows.Input; -using System.Windows.Media.Animation; -using System.Windows.Threading; -using Xceed.Wpf.DataGrid.Views; - -namespace Xceed.Wpf.DataGrid -{ - public class DataRow : Row, IEditableObject - { - public DataRow() - { - this.CommandBindings.Add( new CommandBinding( DataGridCommands.ExpandDetails, - new ExecutedRoutedEventHandler( OnExpandDetailsExecuted ), - new CanExecuteRoutedEventHandler( OnExpandDetailsCanExecute ) ) ); - - this.CommandBindings.Add( new CommandBinding( DataGridCommands.CollapseDetails, - new ExecutedRoutedEventHandler( OnCollapseDetailsExecuted ), - new CanExecuteRoutedEventHandler( OnCollapseDetailsCanExecute ) ) ); - - this.CommandBindings.Add( new CommandBinding( DataGridCommands.ToggleDetailExpansion, - new ExecutedRoutedEventHandler( OnToggleDetailsExecuted ), - new CanExecuteRoutedEventHandler( OnToggleDetailsCanExecute ) ) ); - } - - private void OnExpandDetailsExecuted( object sender, ExecutedRoutedEventArgs e ) - { - } - - private void OnExpandDetailsCanExecute( object sender, CanExecuteRoutedEventArgs e ) - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - if( ( dataGridContext != null ) && ( this.DataContext != null ) ) - { - if( ( dataGridContext.AllowDetailToggle == true ) && ( dataGridContext.HasDetails == true ) && ( DataGridControl.GetHasExpandedDetails( this ) == false ) ) - { - e.CanExecute = true; - return; - } - } - e.CanExecute = false; - } - - private void OnCollapseDetailsExecuted( object sender, ExecutedRoutedEventArgs e ) - { - } - - private void OnCollapseDetailsCanExecute( object sender, CanExecuteRoutedEventArgs e ) - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - if( ( dataGridContext != null ) && ( this.DataContext != null ) ) - { - if( ( dataGridContext.AllowDetailToggle == true ) && ( dataGridContext.HasDetails == true ) && ( DataGridControl.GetHasExpandedDetails( this ) == true ) ) - { - e.CanExecute = true; - return; - } - } - e.CanExecute = false; - } - - private void OnToggleDetailsExecuted( object sender, ExecutedRoutedEventArgs e ) - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - if( ( dataGridContext != null ) && ( this.DataContext != null ) ) - { - } - } - - private void OnToggleDetailsCanExecute( object sender, CanExecuteRoutedEventArgs e ) - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - if( ( dataGridContext != null ) && ( this.DataContext != null ) ) - { - if( ( dataGridContext.AllowDetailToggle == true ) && ( dataGridContext.HasDetails == true ) ) - { - e.CanExecute = true; - return; - } - } - e.CanExecute = false; - } - - #region ItemIndex property - - internal int ItemIndex - { - get - { - return DataGridVirtualizingPanel.GetItemIndex( this ); - } - } - - #endregion ItemIndex property - - #region EditableObject property - - private IEditableObject EditableObject - { - get - { - return ItemsSourceHelper.GetEditableObject( this.DataContext ); - } - } - - #endregion EditableObject property - - #region TitleBarContent Private Property - - internal static readonly DependencyProperty TitleBarContentProperty = DependencyProperty.Register( - "TitleBarContent", - typeof( object ), - typeof( DataRow ) ); - - #endregion TitleBarContent Private Property - - #region ResortPending property - - private bool ResortPending - { - get - { - return m_flags[ ( int )DataRowFlags.ResortPending ]; - } - set - { - m_flags[ ( int )DataRowFlags.ResortPending ] = value; - } - } - - #endregion - - #region RegroupPending property - - private bool RegroupPending - { - get - { - return m_flags[ ( int )DataRowFlags.RegroupPending ]; - } - set - { - m_flags[ ( int )DataRowFlags.RegroupPending ] = value; - } - } - - #endregion - - #region RepositionPending property - - private bool RepositionPending - { - get - { - return m_flags[ ( int )DataRowFlags.RepositionPending ]; - } - set - { - m_flags[ ( int )DataRowFlags.RepositionPending ] = value; - } - } - - #endregion - - - protected override void OnMouseEnter( MouseEventArgs e ) - { - base.OnMouseEnter( e ); - - //If the current CellEditorDisplayConditions requires display when mouse is over the Row - if( Row.IsCellEditorDisplayConditionsSet( this, CellEditorDisplayConditions.MouseOverRow ) ) - { - //Display the editors for the Row - this.SetDisplayEditorMatchingCondition( CellEditorDisplayConditions.MouseOverRow ); - } - - // In case a value was explicitly specified on the Cell's ParentColumn - this.RefreshCellsDisplayedTemplate(); - } - - protected override void OnMouseLeave( MouseEventArgs e ) - { - base.OnMouseLeave( e ); - - //If the current CellEditorDisplayConditions requires display when mouse is over the Row - if( Row.IsCellEditorDisplayConditionsSet( this, CellEditorDisplayConditions.MouseOverRow ) ) - { - //Display the editors for the Row - this.RemoveDisplayEditorMatchingCondition( CellEditorDisplayConditions.MouseOverRow ); - } - - // In case a value was explicitly specified on the Cell's ParentColumn - this.RefreshCellsDisplayedTemplate(); - } - - protected override void SetDataContext( object item ) - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - // When TableflowViewItemsHost is used and an EmptyDataItem is detected. We also want to avoid getting an animation when the container is sticky - if( !( item is EmptyDataItem ) - && ( dataGridContext != null ) - && ( dataGridContext.DataGridControl.GetView() is TableflowView ) - && !( TableflowViewItemsHost.GetIsSticky( this ) ) - && TableflowViewItemsHost.GetShouldDelayDataContext( this ) ) - { - this.ApplyAnimationClock( Row.CellContentOpacityProperty, null ); - this.SetValue( Row.CellContentOpacityProperty, 0d ); - - // We set the DataContext to an EmptyDataItem to have the real data item set later on with an opacity animation. - this.DataContext = this.EmptyDataItem; - this.UpdateUnboundDataItemContext(); - - // Dispatch a call to SetDataContextDispatched that will update the DataContext of the Row and every CreatedCells to the - // DataItem the Row must display. We use a low priority to limit the impact on scrolling. - if( m_affectDataContextOperation == null ) - { - m_affectDataContextOperation = this.Dispatcher.BeginInvoke( new Action( this.SetDataContextDispatched ), DispatcherPriority.Background, item ); - } - } - else - { - this.DataContext = item; - this.UpdateUnboundDataItemContext(); - - this.ApplyAnimationClock( Row.CellContentOpacityProperty, null ); - this.ClearValue( Row.CellContentOpacityProperty ); - } - } - - protected override void BeginEditCore() - { - var dataGridContext = DataGridControl.GetDataGridContext( this ); - - var dataGridCollectionViewBase = dataGridContext == null ? null : dataGridContext.ItemsSourceCollection as DataGridCollectionViewBase; - - if( dataGridCollectionViewBase != null ) - { - // We do not want to call EditItem when the item is the one in the insertionrow - if( dataGridCollectionViewBase.CurrentAddItem != this.DataContext ) - { - dataGridCollectionViewBase.EditItem( this.DataContext ); - } - } - else - { - IEditableObject editableObject = this.EditableObject; - - // editableObject can be equal to this when the datarow is directly inserted as Item in the DataGridControl. - if( ( editableObject != null ) && ( editableObject != this ) ) - { - editableObject.BeginEdit(); - } - } - - base.BeginEditCore(); - } - - protected override void EndEditCore() - { - var dataGridContext = DataGridControl.GetDataGridContext( this ); - - base.EndEditCore(); - - var dataGridCollectionViewBase = dataGridContext == null ? null : dataGridContext.ItemsSourceCollection as DataGridCollectionViewBase; - - try - { - if( dataGridCollectionViewBase != null ) - { - if( dataGridCollectionViewBase.CurrentEditItem == this.DataContext ) - { - dataGridCollectionViewBase.CommitEdit(); - } - } - else - { - IEditableObject editableObject = this.EditableObject; - - // editableObject can be equal to this when the datarow is directly inserted as Items in the DataGridControl. - if( ( editableObject != null ) && ( editableObject != this ) ) - { - editableObject.EndEdit(); - } - } - } - catch( Exception exception ) - { - // Note that we do not update the created cell's Content from the source in case the IEditableObject EndEdit implementation - // throwed an exception. This is mainly due because we want to make sure that we do not lose all of the edited cells values. - // This way, the end user will have the chance to correct the mistakes without loosing everything he typed. - - // If EndEdit throwed, call BeginEdit on the IEditableObject to make sure that it stays in edit mode. - // We don't have to do this when bound to a DataGridCollectionView since it will take care of it. - if( dataGridCollectionViewBase == null ) - { - IEditableObject editableObject = this.EditableObject; - - // editableObject can be equal to this when the datarow is directly inserted as Items in the DataGridControl. - if( ( editableObject != null ) && ( editableObject != this ) ) - { - editableObject.BeginEdit(); - } - } - - // This method will set a validation error on the row and throw back a DataGridValidationException so that the row stays in edition. - Row.SetRowValidationErrorOnException( this, exception ); - } - - // Update the created cell's Content from the source in case the IEditableObject EndEdit implementation rectified some values. - this.UpdateCellsContentBindingTarget(); - } - - internal override void PreEditEnded() - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - if( dataGridContext != null ) - { - if( !this.RepositionPending ) - { - using( dataGridContext.InhibitQueueBringIntoView() ) - { - if( this.ResortPending ) - this.EnsureResort( dataGridContext ); - - if( this.RegroupPending ) - this.EnsureRegroup( dataGridContext ); - } - } - else - { - this.EnsurePosition( dataGridContext ); - } - } - - base.PreEditEnded(); - } - - protected override void CancelEditCore() - { - var dataGridContext = DataGridControl.GetDataGridContext( this ); - - var dataGridCollectionViewBase = dataGridContext == null ? null : dataGridContext.ItemsSourceCollection as DataGridCollectionViewBase; - - if( dataGridCollectionViewBase != null ) - { - // We do not want to call EditItem when the item is the one in the insertionrow - if( dataGridCollectionViewBase.CurrentEditItem == this.DataContext ) - { - dataGridCollectionViewBase.CancelEdit(); - } - } - else - { - IEditableObject editableObject = this.EditableObject; - - // editableObject can be equal to this when the datarow is directly inserted as Items in the DataGridControl. - if( ( editableObject != null ) && ( editableObject != this ) ) - { - editableObject.CancelEdit(); - } - } - - base.CancelEditCore(); - } - - internal override void PreEditCanceled() - { - this.ResortPending = false; - this.RegroupPending = false; - - base.PreEditCanceled(); - } - - protected override void PrepareContainer( DataGridContext dataGridContext, object item ) - { - base.PrepareContainer( dataGridContext, item ); - - if( dataGridContext != null ) - { - ( ( INotifyPropertyChanged )dataGridContext.Columns ).PropertyChanged += new PropertyChangedEventHandler( this.Columns_PropertyChanged ); - this.SetTitleBarContentBinding( dataGridContext ); - m_storedDataGridContext = dataGridContext; - } - } - - protected override void ClearContainer() - { - if( m_affectDataContextOperation != null ) - { - m_affectDataContextOperation.Abort(); - m_affectDataContextOperation = null; - } - - // Ensure to stop the opacity animation if it is currently active - if( ( m_opacityAnimationClock != null ) && ( m_opacityAnimationClock.CurrentState != ClockState.Stopped ) ) - { - m_opacityAnimationClock.Completed -= this.OpacityAnimationClock_Completed; - m_opacityAnimationClock.Controller.Stop(); - m_opacityAnimationClock = null; - } - - base.ClearContainer(); - - if( m_storedDataGridContext != null ) - { - ( ( INotifyPropertyChanged )m_storedDataGridContext.Columns ).PropertyChanged -= new PropertyChangedEventHandler( Columns_PropertyChanged ); - m_storedDataGridContext = null; - } - } - - protected override void PartialClearContainer() - { - if( m_affectDataContextOperation != null ) - { - m_affectDataContextOperation.Abort(); - m_affectDataContextOperation = null; - } - - // Ensure to stop the opacity animation if it is currently active - if( ( m_opacityAnimationClock != null ) && ( m_opacityAnimationClock.CurrentState != ClockState.Stopped ) ) - { - m_opacityAnimationClock.Completed -= this.OpacityAnimationClock_Completed; - m_opacityAnimationClock.Controller.Stop(); - m_opacityAnimationClock = null; - } - - if( m_storedDataGridContext != null ) - { - ( ( INotifyPropertyChanged )m_storedDataGridContext.Columns ).PropertyChanged -= new PropertyChangedEventHandler( Columns_PropertyChanged ); - m_storedDataGridContext = null; - } - - base.PartialClearContainer(); - } - - protected override Cell CreateCell( ColumnBase column ) - { - if( column == null ) - throw new DataGridInternalException( "Column is null.", DataGridControl.GetDataGridContext( this ).DataGridControl ); - - return new DataCell(); - } - - protected override bool IsValidCellType( Cell cell ) - { - return ( cell is DataCell ); - } - - private void EnsureResort( DataGridContext dataGridContext ) - { - if( dataGridContext == null ) - throw new ArgumentNullException( "dataGridContext" ); - - if( this.IsBeingEdited ) - { - this.ResortPending = true; - return; - } - - this.ResortPending = false; - dataGridContext.EnsureResort(); - } - - private void EnsureRegroup( DataGridContext dataGridContext ) - { - if( dataGridContext == null ) - throw new ArgumentNullException( "dataGridContext" ); - - if( this.IsBeingEdited ) - { - this.RegroupPending = true; - return; - } - - this.RegroupPending = false; - dataGridContext.EnsureRegroup(); - } - - private void EnsurePosition( DataGridContext dataGridContext ) - { - // In the case the ItemsSource is a DataGridCollectionView - // we notify the item that correspond to the DataRow for the possible modification - // of his data, and should then check if is position is still the same. - if( dataGridContext == null ) - throw new ArgumentNullException( "dataGridContext" ); - - if( this.IsBeingEdited ) - { - this.RepositionPending = true; - return; - } - - this.RepositionPending = false; - - DataGridCollectionViewBase dataGridCollectionViewBase = - dataGridContext.ItemsSourceCollection as DataGridCollectionViewBase; - - if( dataGridCollectionViewBase != null ) - { - int globalSortedIndex = dataGridCollectionViewBase.IndexOf( this.DataContext ); - - if( globalSortedIndex == -1 ) - return; - - dataGridCollectionViewBase.EnsurePosition( globalSortedIndex ); - } - } - - internal void EnsurePosition( DataGridContext dataGridContext, Cell changedCell ) - { - if( dataGridContext == null ) - throw new ArgumentNullException( "dataGridContext" ); - - DataGridCollectionViewBase dataGridCollectionViewBase = - dataGridContext.ItemsSourceCollection as DataGridCollectionViewBase; - - if( dataGridCollectionViewBase != null ) - { - this.EnsurePosition( dataGridContext ); - } - else - { - string fieldName = changedCell.FieldName; - - foreach( GroupLevelDescription groupInfo in dataGridContext.GroupLevelDescriptions ) - { - if( groupInfo.FieldName == fieldName ) - { - this.EnsureRegroup( dataGridContext ); - break; - } - } - - SortDescriptionCollection sortDescriptions = dataGridContext.Items.SortDescriptions; - - foreach( SortDescription sortDescription in sortDescriptions ) - { - if( sortDescription.PropertyName == fieldName ) - { - this.EnsureResort( dataGridContext ); - break; - } - } - } - } - - private void Columns_PropertyChanged( object sender, PropertyChangedEventArgs e ) - { - if( e.PropertyName == "MainColumn" ) - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - this.SetTitleBarContentBinding( dataGridContext ); - } - } - - [EditorBrowsable( EditorBrowsableState.Never )] - protected virtual void SetTitleBarContentBinding( DataGridContext dataGridContext ) - { - if( dataGridContext == null ) - return; - - var view = dataGridContext.DataGridControl.GetView(); - if( ( view is TableView ) || ( view is TableflowView ) ) - return; - - var headerColumn = dataGridContext.Columns.MainColumn as Column; - if( headerColumn == null ) - return; - - var displayMemberBinding = headerColumn.GetDisplayMemberBinding(); - if( displayMemberBinding == null ) - { - var dataItem = this.DataContext; - var itemType = ( dataItem != null ) ? dataItem.GetType() : null; - - displayMemberBinding = ItemsSourceHelper.CreateDefaultBinding( - ItemsSourceHelper.CreateOrGetPropertyDescriptionFromColumn( dataGridContext, headerColumn, itemType ) ); - } - - if( displayMemberBinding == null ) - { - Debug.Assert( false, "displayMemberBinding is null." ); - this.ClearValue( DataRow.TitleBarContentProperty ); - } - else - { - this.SetBinding( DataRow.TitleBarContentProperty, displayMemberBinding ); - } - } - - protected internal override void PrepareDefaultStyleKey( Views.ViewBase view ) - { - object currentThemeKey = view.GetDefaultStyleKey( typeof( DataRow ) ); - - if( currentThemeKey.Equals( this.DefaultStyleKey ) == false ) - { - this.DefaultStyleKey = currentThemeKey; - } - } - - #region Delayed DataContext affectation - - private DoubleAnimation m_fadeInAnimation = new DoubleAnimation(); - - private void SetDataContextDispatched( object dataItem ) - { - try - { - if( this.DataContext is EmptyDataItem ) - { - this.DataContext = dataItem; - this.UpdateUnboundDataItemContext(); - - this.SetCellDataContextAnimated( false ); - } - } - finally - { - m_affectDataContextOperation = null; - } - } - - private void OpacityAnimationClock_Completed( object sender, EventArgs e ) - { - m_opacityAnimationClock.Completed -= this.OpacityAnimationClock_Completed; - m_opacityAnimationClock = null; - } - - private void SetCellDataContextAnimated( bool hideContent ) - { - object dataContext = this.DataContext; - UnboundDataItem unboundDataItemContext = this.UnboundDataItemContext; - - foreach( Cell cell in this.CreatedCells ) - { - Cell.AssignDataContext( cell, dataContext, unboundDataItemContext, cell.ParentColumn ); - - // We must refresh the Displayed template since ShouldDisplayEditor always return false when an EmptyDataItem is detected - cell.RefreshDisplayedTemplate(); - } - - if( hideContent ) - { - this.ApplyAnimationClock( Row.CellContentOpacityProperty, null ); - this.SetValue( Row.CellContentOpacityProperty, 0d ); - } - else - { - m_fadeInAnimation.From = 0d; - m_fadeInAnimation.To = 1d; - m_fadeInAnimation.Duration = TimeSpan.FromMilliseconds( TableflowView.GetRowFadeInAnimationDuration( DataGridControl.GetDataGridContext( this ) ) ); - - if( m_opacityAnimationClock != null ) - { - m_opacityAnimationClock.Controller.Pause(); - m_opacityAnimationClock.Completed -= this.OpacityAnimationClock_Completed; - m_opacityAnimationClock = null; - } - - m_opacityAnimationClock = ( AnimationClock )m_fadeInAnimation.CreateClock( true ); - m_opacityAnimationClock.Completed += this.OpacityAnimationClock_Completed; - - this.ApplyAnimationClock( Row.CellContentOpacityProperty, m_opacityAnimationClock ); - m_opacityAnimationClock.Controller.Begin(); - } - } - - private AnimationClock m_opacityAnimationClock; // = null; - - #endregion - - private BitVector32 m_flags = new BitVector32(); - - private DataGridContext m_storedDataGridContext; // = null - private DispatcherOperation m_affectDataContextOperation; // = null; - - #region Flags Enum - - [Flags] - private enum DataRowFlags - { - ResortPending = 1, - RegroupPending = 2, - RepositionPending = 4, - } - - #endregion Flags Enum - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataRowEditableWrapper.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataRowEditableWrapper.cs deleted file mode 100644 index 55dadda3..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DataRowEditableWrapper.cs +++ /dev/null @@ -1,52 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.ComponentModel; - -namespace Xceed.Wpf.DataGrid -{ - internal class DataRowEditableWrapper : IEditableObject - { - public DataRowEditableWrapper( System.Data.DataRow dataRow ) - { - m_dataRow = dataRow; - } - - #region IEditableObject Members - - public void BeginEdit() - { - m_dataRow.BeginEdit(); - } - - public void CancelEdit() - { - m_dataRow.CancelEdit(); - } - - public void EndEdit() - { - m_dataRow.EndEdit(); - } - - #endregion - - private System.Data.DataRow m_dataRow; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DefaultCellEditorSelector.xaml b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DefaultCellEditorSelector.xaml deleted file mode 100644 index 4fe53870..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DefaultCellEditorSelector.xaml +++ /dev/null @@ -1,302 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DefaultCellEditorSelector.xaml.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DefaultCellEditorSelector.xaml.cs deleted file mode 100644 index dfe27fa9..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DefaultCellEditorSelector.xaml.cs +++ /dev/null @@ -1,229 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; -using System.Windows; -using System.Windows.Threading; - -namespace Xceed.Wpf.DataGrid -{ - internal partial class DefaultCellEditorSelector : FrameworkElement - { - #region Static Fields - - private static DefaultCellEditorSelector s_instance = default( DefaultCellEditorSelector ); - private static readonly List s_instances = new List( 1 ); - - #endregion - - private DefaultCellEditorSelector() - { - this.InitializeComponent(); - } - - #region ForeignKeyCellEditor Public Static Property - - public static CellEditor ForeignKeyCellEditor - { - get - { - return DefaultCellEditorSelector.GetCellEditor( "foreignKeyCellEditor" ); - } - } - - #endregion - - #region TextBoxEditor Public Static Property - - public static CellEditor TextBoxEditor - { - get - { - return DefaultCellEditorSelector.SelectCellEditor( typeof( string ) ); - } - } - - #endregion - - #region CheckBoxEditor Public Static Property - - public static CellEditor CheckBoxEditor - { - get - { - return DefaultCellEditorSelector.SelectCellEditor( typeof( bool ) ); - } - } - - #endregion - - #region DateTimeEditor Public Static Editor - - public static CellEditor DateTimeEditor - { - get - { - return DefaultCellEditorSelector.SelectCellEditor( typeof( DateTime ) ); - } - } - - #endregion - - public static CellEditor SelectCellEditor( Type dataType ) - { - if( dataType == null ) - return null; - - if( dataType.IsGenericType && ( dataType.GetGenericTypeDefinition() == typeof( Nullable<> ) ) ) - { - dataType = Nullable.GetUnderlyingType( dataType ); - } - - var editor = default( CellEditor ); - if( DefaultCellEditorSelector.TryGetCellEditor( dataType.FullName, out editor ) ) - return editor; - - return null; - } - - private static DataTemplate GetDataTemplate( object key ) - { - var resource = default( DataTemplate ); - if( !DefaultCellEditorSelector.TryGetDataTemplate( key, out resource ) ) - throw new KeyNotFoundException( "Resource not found" ); - - return resource; - } - - private static bool TryGetDataTemplate( object key, out DataTemplate value ) - { - var resource = default( object ); - if( !DefaultCellEditorSelector.TryGetResource( key, out resource ) ) - { - value = default( DataTemplate ); - return false; - } - else - { - value = DefaultCellEditorSelector.TrySeal( resource as DataTemplate ); - return ( value != null ); - } - } - - private static CellEditor GetCellEditor( object key ) - { - var resource = default( CellEditor ); - if( !DefaultCellEditorSelector.TryGetCellEditor( key, out resource ) ) - throw new KeyNotFoundException( "Resource not found" ); - - return resource; - } - - private static bool TryGetCellEditor( object key, out CellEditor value ) - { - var resource = default( object ); - if( !DefaultCellEditorSelector.TryGetResource( key, out resource ) ) - { - value = default( CellEditor ); - return false; - } - else - { - value = DefaultCellEditorSelector.TryFreeze( resource as CellEditor ); - return ( value != null ); - } - } - - private static bool TryGetResource( object key, out object value ) - { - value = null; - - var dispatcher = Dispatcher.CurrentDispatcher; - if( dispatcher == null ) - return false; - - var target = default( DefaultCellEditorSelector ); - - lock( ( ( ICollection )s_instances ).SyncRoot ) - { - for( int i = s_instances.Count - 1; i >= 0; i-- ) - { - var instance = s_instances[ i ].Target as DefaultCellEditorSelector; - - if( instance == null ) - { - s_instances.RemoveAt( i ); - } - else if( instance.Dispatcher == dispatcher ) - { - target = instance; - - // We could exit the loop but we don't because we want to clean up the list - // and keep it small. We don't want it to become large with lots of empty - // WeakReference. - //break; - } - } - - if( target == null ) - { - target = new DefaultCellEditorSelector(); - s_instances.Add( new WeakReference( target ) ); - } - - // We keep a strong reference on the target instance to prevent that instance - // from being garbage collected. We assume that we will need that instance - // again for other calls. We don't want to have to create a new instance to - // query for a single resource. - s_instance = target; - } - - Debug.Assert( target != null ); - - value = target.TryFindResource( key ); - - return ( value != null ); - } - - private static DataTemplate TrySeal( DataTemplate template ) - { - if( ( template != null ) && !template.IsSealed ) - { - template.Seal(); - } - - return template; - } - - private static CellEditor TryFreeze( CellEditor editor ) - { - if( ( editor != null ) && !editor.IsFrozen ) - { - DefaultCellEditorSelector.TrySeal( editor.EditTemplate ); - - if( editor.CanFreeze ) - { - editor.Freeze(); - } - } - - return editor; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DefaultDetailConfiguration.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DefaultDetailConfiguration.cs deleted file mode 100644 index 7701f8f0..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DefaultDetailConfiguration.cs +++ /dev/null @@ -1,282 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Windows; -using System.Windows.Controls; -using System.Collections.ObjectModel; -using System.Windows.Input; - -namespace Xceed.Wpf.DataGrid -{ - public class DefaultDetailConfiguration : DependencyObject - { - static DefaultDetailConfiguration() - { - HeadersProperty = HeadersPropertyKey.DependencyProperty; - FootersProperty = FootersPropertyKey.DependencyProperty; - } - - public DefaultDetailConfiguration() - { - this.SetHeaders( new ObservableCollection() ); - this.SetFooters( new ObservableCollection() ); - } - - #region AllowDetailToggle Property - - public static readonly DependencyProperty AllowDetailToggleProperty = DataGridControl.AllowDetailToggleProperty.AddOwner( typeof( DefaultDetailConfiguration ) ); - - public bool AllowDetailToggle - { - get - { - return ( bool )this.GetValue( DefaultDetailConfiguration.AllowDetailToggleProperty ); - } - set - { - this.SetValue( DefaultDetailConfiguration.AllowDetailToggleProperty, value ); - } - } - - #endregion AllowDetailToggle Property - - #region DefaultGroupConfiguration Property - - public static readonly DependencyProperty DefaultGroupConfigurationProperty = DataGridControl.DefaultGroupConfigurationProperty.AddOwner( typeof( DefaultDetailConfiguration ) ); - - public GroupConfiguration DefaultGroupConfiguration - { - get - { - return ( GroupConfiguration )this.GetValue( DefaultDetailConfiguration.DefaultGroupConfigurationProperty ); - } - set - { - this.SetValue( DefaultDetailConfiguration.DefaultGroupConfigurationProperty, value ); - } - } - - #endregion DefaultGroupConfiguration Property - - #region GroupConfigurationSelector Property - - public static readonly DependencyProperty GroupConfigurationSelectorProperty = DataGridControl.GroupConfigurationSelectorProperty.AddOwner( typeof( DefaultDetailConfiguration ) ); - - public GroupConfigurationSelector GroupConfigurationSelector - { - get - { - return ( GroupConfigurationSelector )this.GetValue( DefaultDetailConfiguration.GroupConfigurationSelectorProperty ); - } - set - { - this.SetValue( DefaultDetailConfiguration.GroupConfigurationSelectorProperty, value ); - } - } - - #endregion GroupConfigurationSelector Property - - #region ItemContainerStyle Property - - public static readonly DependencyProperty ItemContainerStyleProperty = DataGridControl.ItemContainerStyleProperty.AddOwner( typeof( DefaultDetailConfiguration ) ); - - public Style ItemContainerStyle - { - get - { - return ( Style )this.GetValue( DefaultDetailConfiguration.ItemContainerStyleProperty ); - } - set - { - this.SetValue( DefaultDetailConfiguration.ItemContainerStyleProperty, value ); - } - } - - #endregion ItemContainerStyle Property - - #region ItemContainerStyleSelector Property - - public static readonly DependencyProperty ItemContainerStyleSelectorProperty = DataGridControl.ItemContainerStyleSelectorProperty.AddOwner( typeof( DefaultDetailConfiguration ) ); - - public StyleSelector ItemContainerStyleSelector - { - get - { - return ( StyleSelector )this.GetValue( DefaultDetailConfiguration.ItemContainerStyleSelectorProperty ); - } - set - { - this.SetValue( DefaultDetailConfiguration.ItemContainerStyleSelectorProperty, value ); - } - } - - #endregion ItemContainerStyleSelector Property - - #region DetailIndicatorStyle Property - - public static readonly DependencyProperty DetailIndicatorStyleProperty = DetailConfiguration.DetailIndicatorStyleProperty.AddOwner( typeof( DefaultDetailConfiguration ) ); - - public Style DetailIndicatorStyle - { - get - { - return ( Style )this.GetValue( DefaultDetailConfiguration.DetailIndicatorStyleProperty ); - } - set - { - this.SetValue( DefaultDetailConfiguration.DetailIndicatorStyleProperty, value ); - } - } - - #endregion DetailIndicatorStyle Property - - #region Headers Property - - private static readonly DependencyPropertyKey HeadersPropertyKey = - DependencyProperty.RegisterReadOnly( "Headers", typeof( ObservableCollection ), typeof( DefaultDetailConfiguration ), new FrameworkPropertyMetadata( null ) ); - - public static readonly DependencyProperty HeadersProperty; - - public ObservableCollection Headers - { - get - { - return ( ObservableCollection )this.GetValue( DefaultDetailConfiguration.HeadersProperty ); - } - } - - private void SetHeaders( ObservableCollection headers ) - { - this.SetValue( DefaultDetailConfiguration.HeadersPropertyKey, headers ); - } - - #endregion Headers Property - - #region Footers Property - - private static readonly DependencyPropertyKey FootersPropertyKey = - DependencyProperty.RegisterReadOnly( "Footers", typeof( ObservableCollection ), typeof( DefaultDetailConfiguration ), new FrameworkPropertyMetadata( null ) ); - - public static readonly DependencyProperty FootersProperty; - - public ObservableCollection Footers - { - get - { - return ( ObservableCollection )this.GetValue( DefaultDetailConfiguration.FootersProperty ); - } - } - - private void SetFooters( ObservableCollection footers ) - { - this.SetValue( DefaultDetailConfiguration.FootersPropertyKey, footers ); - } - - #endregion Footers Property - - #region MaxSortLevels Property - - public static readonly DependencyProperty MaxSortLevelsProperty = DataGridControl.MaxSortLevelsProperty.AddOwner( typeof( DefaultDetailConfiguration ) ); - - public int MaxSortLevels - { - get - { - return ( int )this.GetValue( DefaultDetailConfiguration.MaxSortLevelsProperty ); - } - set - { - this.SetValue( DefaultDetailConfiguration.MaxSortLevelsProperty, value ); - } - } - - #endregion MaxSortLevels Property - - #region MaxGroupLevels Property - - public static readonly DependencyProperty MaxGroupLevelsProperty = DataGridControl.MaxGroupLevelsProperty.AddOwner( typeof( DefaultDetailConfiguration ) ); - - public int MaxGroupLevels - { - get - { - return ( int )this.GetValue( DefaultDetailConfiguration.MaxGroupLevelsProperty ); - } - set - { - this.SetValue( DefaultDetailConfiguration.MaxGroupLevelsProperty, value ); - } - } - - #endregion MaxGroupLevels Property - - #region UseDefaultHeadersFooters Property - - public static readonly DependencyProperty UseDefaultHeadersFootersProperty = DetailConfiguration.UseDefaultHeadersFootersProperty.AddOwner( typeof( DefaultDetailConfiguration ) ); - - public bool UseDefaultHeadersFooters - { - get - { - return ( bool )this.GetValue( DefaultDetailConfiguration.UseDefaultHeadersFootersProperty ); - } - set - { - this.SetValue( DefaultDetailConfiguration.UseDefaultHeadersFootersProperty, value ); - } - } - - #endregion UseDefaultHeadersFooters Property - - #region IsDeleteCommandEnabled Property - - public static readonly DependencyProperty IsDeleteCommandEnabledProperty = DetailConfiguration.IsDeleteCommandEnabledProperty.AddOwner( - typeof( DefaultDetailConfiguration ), - new FrameworkPropertyMetadata( false, new PropertyChangedCallback( DefaultDetailConfiguration.OnIsDeleteCommandEnabledChanged ) ) ); - - public bool IsDeleteCommandEnabled - { - get - { - return ( bool )this.GetValue( DefaultDetailConfiguration.IsDeleteCommandEnabledProperty ); - } - set - { - this.SetValue( DefaultDetailConfiguration.IsDeleteCommandEnabledProperty, value ); - } - } - - private static void OnIsDeleteCommandEnabledChanged( DependencyObject obj, DependencyPropertyChangedEventArgs e ) - { - CommandManager.InvalidateRequerySuggested(); - } - - #endregion IsDeleteCommandEnabled Property - - internal void AddDefaultHeadersFooters() - { - if( m_defaultHeadersFootersAdded ) - return; - - m_defaultHeadersFootersAdded = true; - } - - private bool m_defaultHeadersFootersAdded = false; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DetailConfiguration.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DetailConfiguration.cs deleted file mode 100644 index 86423d25..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DetailConfiguration.cs +++ /dev/null @@ -1,2070 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Diagnostics; -using System.Linq; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Input; -using Xceed.Wpf.DataGrid.Markup; -using Xceed.Wpf.DataGrid.Utils; -using Xceed.Wpf.DataGrid.Views; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class DetailConfiguration : DependencyObject, IWeakEventListener, ISupportInitialize, INotifyPropertyChanged - { - #region Static Fields - - internal static readonly string DataGridControlPropertyName = PropertyHelper.GetPropertyName( ( DetailConfiguration d ) => d.DataGridControl ); - internal static readonly string DetailDescriptionPropertyName = PropertyHelper.GetPropertyName( ( DetailConfiguration d ) => d.DetailDescription ); - - #endregion - - static DetailConfiguration() - { - DetailConfiguration.DetailConfigurationsProperty = DetailConfiguration.DetailConfigurationsPropertyKey.DependencyProperty; - DetailConfiguration.ColumnsProperty = DetailConfiguration.ColumnsPropertyKey.DependencyProperty; - DetailConfiguration.GroupLevelDescriptionsProperty = DetailConfiguration.GroupLevelDescriptionsPropertyKey.DependencyProperty; - DetailConfiguration.VisibleColumnsProperty = DetailConfiguration.VisibleColumnsPropertyKey.DependencyProperty; - DetailConfiguration.HeadersProperty = DetailConfiguration.HeadersPropertyKey.DependencyProperty; - DetailConfiguration.FootersProperty = DetailConfiguration.FootersPropertyKey.DependencyProperty; - - DetailConfiguration.BuildDefaultTemplates(); - } - - public DetailConfiguration() - { - var columns = new ColumnCollection( null, this ); - - m_columnManager = new ColumnHierarchyManager( columns ); - - this.SetColumns( columns ); - this.SetVisibleColumns( m_columnManager.VisibleColumns ); - - m_columnSynchronizationManager = new ColumnSynchronizationManager( this ); - m_columnManagerRowConfiguration = new ColumnManagerRowConfiguration(); - - this.SetHeaders( new ObservableCollection() ); - this.SetFooters( new ObservableCollection() ); - - this.SetGroupLevelDescriptions( new GroupLevelDescriptionCollection() ); - this.SetDetailConfigurations( new DetailConfigurationCollection( null, this ) ); - - columns.CollectionChanged += new NotifyCollectionChangedEventHandler( this.OnColumnsCollectionChanged ); - CollectionChangedEventManager.AddListener( this.DetailConfigurations, this ); - - this.BeginInit(); - } - - private static void BuildDefaultTemplates() - { - //Defining the FrameworkElementFactory variables I will use below. - FrameworkElementFactory hglip; - FrameworkElementFactory glip; - FrameworkElementFactory border; - FrameworkElementFactory contentPresenter; - - //Defining the Converters, Bindings and ViewBindings I will use to build the templates below. - Converters.ThicknessConverter thicknessConverter = new Xceed.Wpf.DataGrid.Converters.ThicknessConverter(); - - ViewBindingExtension borderThicknessBinding = new ViewBindingExtension( "HorizontalGridLineThickness" ); - borderThicknessBinding.Converter = thicknessConverter; - borderThicknessBinding.ConverterParameter = Converters.ThicknessConverter.ThicknessSides.Top; - - //ViewBindingExtension borderBrushBinding = new ViewBindingExtension( "HorizontalGridLineBrush" ); - - Binding detailTitleBinding = new Binding(); - detailTitleBinding.Path = new PropertyPath( "(0).SourceDetailConfiguration.Title", DataGridControl.DataGridContextProperty ); - detailTitleBinding.RelativeSource = new RelativeSource( RelativeSourceMode.Self ); - - Binding detailTitleTemplateBinding = new Binding(); - detailTitleTemplateBinding.Path = new PropertyPath( "(0).SourceDetailConfiguration.TitleTemplate", DataGridControl.DataGridContextProperty ); - detailTitleTemplateBinding.RelativeSource = new RelativeSource( RelativeSourceMode.Self ); - - //Defining the Header Spacer template. - DefaultHeaderSpacerTemplate = new DataTemplate(); - DefaultHeaderSpacerTemplate.VisualTree = new FrameworkElementFactory( typeof( DockPanel ) ); - DefaultHeaderSpacerTemplate.VisualTree.SetValue( RowSelector.VisibleProperty, false ); - - hglip = new FrameworkElementFactory( typeof( HierarchicalGroupLevelIndicatorPane ) ); - hglip.SetValue( DockPanel.DockProperty, Dock.Left ); - hglip.SetValue( TableView.CanScrollHorizontallyProperty, false ); - DefaultHeaderSpacerTemplate.VisualTree.AppendChild( hglip ); - - glip = new FrameworkElementFactory( typeof( GroupLevelIndicatorPane ) ); - glip.SetValue( GroupLevelIndicatorPane.IndentedProperty, false ); - glip.SetValue( DockPanel.DockProperty, Dock.Left ); - glip.SetValue( GroupLevelIndicatorPane.ShowIndicatorsProperty, false ); - glip.SetValue( GroupLevelIndicatorPane.ShowVerticalBorderProperty, false ); - glip.SetValue( GroupLevelIndicatorPane.GroupLevelProperty, 0 ); - glip.SetValue( TableView.CanScrollHorizontallyProperty, false ); - DefaultHeaderSpacerTemplate.VisualTree.AppendChild( glip ); - - border = new FrameworkElementFactory( typeof( Border ) ); - border.SetBinding( Border.BorderThicknessProperty, ( BindingBase )borderThicknessBinding.ProvideValue( null ) ); - //border.SetBinding( Border.BorderBrushProperty, ( BindingBase )borderBrushBinding.ProvideValue( null ) ); - border.SetValue( Border.MinHeightProperty, 5d ); - border.SetValue( TableView.CanScrollHorizontallyProperty, false ); - - contentPresenter = new FrameworkElementFactory( typeof( ContentPresenter ) ); - contentPresenter.SetBinding( ContentPresenter.ContentProperty, detailTitleBinding ); - contentPresenter.SetBinding( ContentPresenter.ContentTemplateProperty, detailTitleTemplateBinding ); - contentPresenter.SetValue( Control.FontSizeProperty, 14d ); - - border.AppendChild( contentPresenter ); - - DefaultHeaderSpacerTemplate.VisualTree.AppendChild( border ); - DefaultHeaderSpacerTemplate.Seal(); - - //Defining the ColumnManagerRow template - DefaultColumnManagerRowTemplate = new DataTemplate(); - DefaultColumnManagerRowTemplate.VisualTree = new FrameworkElementFactory( typeof( ColumnManagerRow ) ); - //DefaultColumnManagerRowTemplate.VisualTree.SetValue( ColumnManagerRow.BackgroundProperty, null ); - DefaultColumnManagerRowTemplate.Seal(); - - DefaultGroupByControlTemplate = new DataTemplate(); - DefaultGroupByControlTemplate.VisualTree = new FrameworkElementFactory( typeof( HierarchicalGroupByControl ) ); - DefaultGroupByControlTemplate.Seal(); - } - - private static DataTemplate DefaultHeaderSpacerTemplate; - private static DataTemplate DefaultColumnManagerRowTemplate; - private static DataTemplate DefaultGroupByControlTemplate; - - internal static void AddDefaultHeadersFooters( ObservableCollection headersCollection, int mergedHeadersCount, bool areDetailsFlatten ) - { - if( !areDetailsFlatten ) - { - headersCollection.Insert( 0, DetailConfiguration.DefaultColumnManagerRowTemplate ); - headersCollection.Insert( 0, DetailConfiguration.DefaultHeaderSpacerTemplate ); - } - } - - internal static void SynchronizeAddedConfigurations( IList addedDetailConfigs, DataGridDetailDescriptionCollection detailDescriptions ) - { - foreach( DetailConfiguration detailConfig in addedDetailConfigs ) - { - DataGridDetailDescription detailDesc = null; - - if( detailDescriptions != null ) - { - detailDesc = detailDescriptions[ detailConfig.RelationName ]; - } - - detailConfig.SynchronizeWithDetailDescription( detailDesc ); - } - } - - internal static void CleanupDetailConfigurations( DetailConfigurationCollection detailConfigurationCollection, bool autoRemoveUnassociated ) - { - for( int i = detailConfigurationCollection.Count - 1; i >= 0; i-- ) - { - DetailConfiguration detailConfiguration = detailConfigurationCollection[ i ]; - detailConfiguration.DetachFromDetailDescription(); - DetailConfiguration.CleanupDetailConfigurations( detailConfiguration.DetailConfigurations, autoRemoveUnassociated ); - - if( ( detailConfiguration.IsAutoCreated ) && ( autoRemoveUnassociated ) ) - { - detailConfigurationCollection.RemoveAt( i ); - } - } - } - - #region RelationName Property - - public static readonly DependencyProperty RelationNameProperty = - DependencyProperty.Register( "RelationName", typeof( string ), typeof( DetailConfiguration ), new FrameworkPropertyMetadata( string.Empty ) ); - - public string RelationName - { - get - { - return ( string )this.GetValue( DetailConfiguration.RelationNameProperty ); - } - set - { - this.SetValue( DetailConfiguration.RelationNameProperty, value ); - } - } - - #endregion RelationName Property - - #region AllowDetailToggle Property - - public static readonly DependencyProperty AllowDetailToggleProperty = DataGridControl.AllowDetailToggleProperty.AddOwner( typeof( DetailConfiguration ), new FrameworkPropertyMetadata( true, new PropertyChangedCallback( OnAllowDetailToggleChanged ) ) ); - - public bool AllowDetailToggle - { - get - { - return ( bool )this.GetValue( DetailConfiguration.AllowDetailToggleProperty ); - } - set - { - this.SetValue( DetailConfiguration.AllowDetailToggleProperty, value ); - } - } - - internal event EventHandler AllowDetailToggleChanged; - - private static void OnAllowDetailToggleChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - DetailConfiguration detailConfig = sender as DetailConfiguration; - if( detailConfig != null ) - { - if( detailConfig.AllowDetailToggleChanged != null ) - { - detailConfig.AllowDetailToggleChanged( detailConfig, EventArgs.Empty ); - } - } - } - - #endregion AllowDetailToggle Property - - #region AutoCreateColumns Property - - public static readonly DependencyProperty AutoCreateColumnsProperty = DataGridControl.AutoCreateColumnsProperty.AddOwner( typeof( DetailConfiguration ) ); - - public bool AutoCreateColumns - { - get - { - return ( bool )this.GetValue( DetailConfiguration.AutoCreateColumnsProperty ); - } - set - { - this.SetValue( DetailConfiguration.AutoCreateColumnsProperty, value ); - } - } - - #endregion AutoCreateColumns Property - - #region Columns Read-Only Property - - internal static readonly DependencyPropertyKey ColumnsPropertyKey = - DependencyProperty.RegisterReadOnly( "Columns", typeof( ColumnCollection ), typeof( DetailConfiguration ), new PropertyMetadata( null ) ); - - public static readonly DependencyProperty ColumnsProperty; - - public ColumnCollection Columns - { - get - { - return ( ColumnCollection )this.GetValue( DetailConfiguration.ColumnsProperty ); - } - } - - internal void SetColumns( ColumnCollection value ) - { - this.SetValue( DetailConfiguration.ColumnsPropertyKey, value ); - } - - #endregion - - #region DefaultDetailConfiguration Property - - public static readonly DependencyProperty DefaultDetailConfigurationProperty = DataGridControl.DefaultDetailConfigurationProperty.AddOwner( typeof( DetailConfiguration ) ); - - public DefaultDetailConfiguration DefaultDetailConfiguration - { - get - { - return ( DefaultDetailConfiguration )this.GetValue( DetailConfiguration.DefaultDetailConfigurationProperty ); - } - set - { - this.SetValue( DetailConfiguration.DefaultDetailConfigurationProperty, value ); - } - } - - #endregion DefaultDetailConfiguration Property - - #region DefaultGroupConfiguration Property - - public static readonly DependencyProperty DefaultGroupConfigurationProperty = DataGridControl.DefaultGroupConfigurationProperty.AddOwner( typeof( DetailConfiguration ) ); - - public GroupConfiguration DefaultGroupConfiguration - { - get - { - return ( GroupConfiguration )this.GetValue( DetailConfiguration.DefaultGroupConfigurationProperty ); - } - set - { - this.SetValue( DetailConfiguration.DefaultGroupConfigurationProperty, value ); - } - } - - #endregion DefaultGroupConfiguration Property - - #region VisibleColumns Read-Only Property - - internal static readonly DependencyPropertyKey VisibleColumnsPropertyKey = - DependencyProperty.RegisterReadOnly( "VisibleColumns", typeof( ReadOnlyObservableCollection ), typeof( DetailConfiguration ), new PropertyMetadata( null ) ); - - public static readonly DependencyProperty VisibleColumnsProperty; - - public ReadOnlyObservableCollection VisibleColumns - { - get - { - return ( ReadOnlyObservableCollection )this.GetValue( DetailConfiguration.VisibleColumnsProperty ); - } - } - - private void SetVisibleColumns( ReadOnlyObservableCollection value ) - { - this.SetValue( DetailConfiguration.VisibleColumnsPropertyKey, value ); - } - - #endregion VisibleColumns Read-Only Property - - #region GroupLevelDescriptions Read-Only Property - - internal static readonly DependencyPropertyKey GroupLevelDescriptionsPropertyKey = - DependencyProperty.RegisterReadOnly( "GroupLevelDescriptions", typeof( GroupLevelDescriptionCollection ), typeof( DetailConfiguration ), new PropertyMetadata( null ) ); - - public static readonly DependencyProperty GroupLevelDescriptionsProperty; - - public GroupLevelDescriptionCollection GroupLevelDescriptions - { - get - { - return ( GroupLevelDescriptionCollection )this.GetValue( DetailConfiguration.GroupLevelDescriptionsProperty ); - } - } - - internal void SetGroupLevelDescriptions( GroupLevelDescriptionCollection value ) - { - this.SetValue( DetailConfiguration.GroupLevelDescriptionsPropertyKey, value ); - } - - #endregion GroupLevelDescriptions Read-Only Property - - #region GroupConfigurationSelector Property - - public static readonly DependencyProperty GroupConfigurationSelectorProperty = DataGridControl.GroupConfigurationSelectorProperty.AddOwner( typeof( DetailConfiguration ) ); - - public GroupConfigurationSelector GroupConfigurationSelector - { - get - { - return ( GroupConfigurationSelector )this.GetValue( GroupConfigurationSelectorProperty ); - } - set - { - this.SetValue( GroupConfigurationSelectorProperty, value ); - } - } - - - - internal event EventHandler GroupConfigurationSelectorChanged; - - #endregion - - #region ItemContainerStyle Property - - public static readonly DependencyProperty ItemContainerStyleProperty = - DependencyProperty.Register( "ItemContainerStyle", typeof( Style ), typeof( DetailConfiguration ), new UIPropertyMetadata( null ) ); - - public Style ItemContainerStyle - { - get - { - return ( Style )this.GetValue( DetailConfiguration.ItemContainerStyleProperty ); - } - set - { - this.SetValue( DetailConfiguration.ItemContainerStyleProperty, value ); - } - } - - #endregion ItemContainerStyle Property - - #region ItemContainerStyleSelector Property - - public static readonly DependencyProperty ItemContainerStyleSelectorProperty = - DependencyProperty.Register( "ItemContainerStyleSelector", typeof( StyleSelector ), typeof( DetailConfiguration ), new UIPropertyMetadata( null ) ); - - public StyleSelector ItemContainerStyleSelector - { - get - { - return ( StyleSelector )this.GetValue( DetailConfiguration.ItemContainerStyleSelectorProperty ); - } - set - { - this.SetValue( DetailConfiguration.ItemContainerStyleSelectorProperty, value ); - } - } - - #endregion ItemContainerStyleSelector Property - - #region UseDefaultHeadersFooters Property - - public static readonly DependencyProperty UseDefaultHeadersFootersProperty = - DependencyProperty.Register( "UseDefaultHeadersFooters", typeof( bool ), typeof( DetailConfiguration ), new PropertyMetadata( true ) ); - - public bool UseDefaultHeadersFooters - { - get - { - return ( bool )this.GetValue( DetailConfiguration.UseDefaultHeadersFootersProperty ); - } - set - { - this.SetValue( DetailConfiguration.UseDefaultHeadersFootersProperty, value ); - } - } - - #endregion UseDefaultHeadersFooters Property - - #region DetailConfigurations Read-Only Property - - private static readonly DependencyPropertyKey DetailConfigurationsPropertyKey = - DependencyProperty.RegisterReadOnly( "DetailConfigurations", typeof( DetailConfigurationCollection ), typeof( DetailConfiguration ), new FrameworkPropertyMetadata( null ) ); - - public static readonly DependencyProperty DetailConfigurationsProperty; - - public DetailConfigurationCollection DetailConfigurations - { - get - { - return ( DetailConfigurationCollection )this.GetValue( DetailConfiguration.DetailConfigurationsProperty ); - } - } - - private void SetDetailConfigurations( DetailConfigurationCollection value ) - { - this.SetValue( DetailConfiguration.DetailConfigurationsPropertyKey, value ); - } - - #endregion DetailConfigurations Read-Only Property - - #region Headers Read-Only Property - - private static readonly DependencyPropertyKey HeadersPropertyKey = - DependencyProperty.RegisterReadOnly( "Headers", typeof( ObservableCollection ), typeof( DetailConfiguration ), new PropertyMetadata( null ) ); - - public static readonly DependencyProperty HeadersProperty; - - public ObservableCollection Headers - { - get - { - return ( ObservableCollection )this.GetValue( DetailConfiguration.HeadersProperty ); - } - } - - private void SetHeaders( ObservableCollection value ) - { - this.SetValue( DetailConfiguration.HeadersPropertyKey, value ); - } - - #endregion Headers Read-Only Property - - #region Footers Read-Only Property - - private static readonly DependencyPropertyKey FootersPropertyKey = - DependencyProperty.RegisterReadOnly( "Footers", typeof( ObservableCollection ), typeof( DetailConfiguration ), new PropertyMetadata( null ) ); - - public static readonly DependencyProperty FootersProperty; - - public ObservableCollection Footers - { - get - { - return ( ObservableCollection )this.GetValue( DetailConfiguration.FootersProperty ); - } - } - - private void SetFooters( ObservableCollection value ) - { - this.SetValue( DetailConfiguration.FootersPropertyKey, value ); - } - - #endregion Footers Read-Only Property - - #region DetailIndicatorStyle Property - - public static readonly DependencyProperty DetailIndicatorStyleProperty = - DependencyProperty.Register( "DetailIndicatorStyle", typeof( Style ), typeof( DetailConfiguration ), new FrameworkPropertyMetadata( null ) ); - - public Style DetailIndicatorStyle - { - get - { - return ( Style )this.GetValue( DetailConfiguration.DetailIndicatorStyleProperty ); - } - set - { - this.SetValue( DetailConfiguration.DetailIndicatorStyleProperty, value ); - } - } - - #endregion DetailIndicatorStyle Property - - #region MaxSortLevels Property - - public static readonly DependencyProperty MaxSortLevelsProperty = DataGridControl.MaxSortLevelsProperty.AddOwner( typeof( DetailConfiguration ), - new FrameworkPropertyMetadata( -1, new PropertyChangedCallback( DetailConfiguration.OnMaxSortLevelsChanged ) ) ); - - public int MaxSortLevels - { - get - { - return ( int )this.GetValue( DetailConfiguration.MaxSortLevelsProperty ); - } - set - { - this.SetValue( DetailConfiguration.MaxSortLevelsProperty, value ); - } - } - - internal event EventHandler MaxSortLevelsChanged; - - private static void OnMaxSortLevelsChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - DetailConfiguration detailConfig = sender as DetailConfiguration; - if( detailConfig != null ) - { - if( detailConfig.MaxSortLevelsChanged != null ) - { - detailConfig.MaxSortLevelsChanged( detailConfig, EventArgs.Empty ); - } - } - } - - #endregion MaxSortLevels Property - - #region MaxGroupLevels Property - - public static readonly DependencyProperty MaxGroupLevelsProperty = DataGridControl.MaxGroupLevelsProperty.AddOwner( typeof( DetailConfiguration ), - new FrameworkPropertyMetadata( -1, new PropertyChangedCallback( DetailConfiguration.OnMaxGroupLevelsChanged ) ) ); - - public int MaxGroupLevels - { - get - { - return ( int )this.GetValue( DetailConfiguration.MaxGroupLevelsProperty ); - } - set - { - this.SetValue( DetailConfiguration.MaxGroupLevelsProperty, value ); - } - } - - internal event EventHandler MaxGroupLevelsChanged; - - private static void OnMaxGroupLevelsChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - DetailConfiguration detailConfig = sender as DetailConfiguration; - if( detailConfig != null ) - { - if( detailConfig.MaxGroupLevelsChanged != null ) - { - detailConfig.MaxGroupLevelsChanged( detailConfig, EventArgs.Empty ); - } - } - } - - #endregion MaxGroupLevels Property - - #region Title Property - - public static readonly DependencyProperty TitleProperty = - DependencyProperty.Register( "Title", typeof( object ), typeof( DetailConfiguration ), new UIPropertyMetadata( null ) ); - - public object Title - { - get - { - return this.GetValue( DetailConfiguration.TitleProperty ); - } - set - { - this.SetValue( DetailConfiguration.TitleProperty, value ); - } - } - - #endregion - - #region TitleTemplate Property - - public static readonly DependencyProperty TitleTemplateProperty = - DependencyProperty.Register( "TitleTemplate", typeof( DataTemplate ), typeof( DetailConfiguration ), new UIPropertyMetadata( null ) ); - - public DataTemplate TitleTemplate - { - get - { - return ( DataTemplate )this.GetValue( DetailConfiguration.TitleTemplateProperty ); - } - set - { - this.SetValue( DetailConfiguration.TitleTemplateProperty, value ); - } - } - - #endregion TitleTemplate Property - - #region Visible Property - - public static readonly DependencyProperty VisibleProperty = - DependencyProperty.Register( "Visible", typeof( bool ), typeof( DetailConfiguration ), - new FrameworkPropertyMetadata( ( bool )true, new PropertyChangedCallback( OnVisibilityChanged ) ) ); - - public bool Visible - { - get - { - return ( bool )this.GetValue( VisibleProperty ); - } - set - { - this.SetValue( VisibleProperty, value ); - } - } - - private static void OnVisibilityChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - DetailConfiguration detailConfig = sender as DetailConfiguration; - if( detailConfig != null ) - { - if( detailConfig.VisibilityChanged != null ) - { - detailConfig.VisibilityChanged( detailConfig, EventArgs.Empty ); - } - } - } - - internal event EventHandler VisibilityChanged; - - #endregion - - #region AutoCreateForeignKeyConfigurations Property - - public static readonly DependencyProperty AutoCreateForeignKeyConfigurationsProperty = DependencyProperty.Register( - "AutoCreateForeignKeyConfigurations", - typeof( bool ), - typeof( DetailConfiguration ), - new FrameworkPropertyMetadata( - ( bool )false, - new PropertyChangedCallback( DetailConfiguration.OnAutoCreateForeignKeyConfigurationsChanged ) ) ); - - public bool AutoCreateForeignKeyConfigurations - { - get - { - return ( bool )this.GetValue( DetailConfiguration.AutoCreateForeignKeyConfigurationsProperty ); - } - set - { - this.SetValue( DetailConfiguration.AutoCreateForeignKeyConfigurationsProperty, value ); - } - } - - private static void OnAutoCreateForeignKeyConfigurationsChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - DetailConfiguration configuration = sender as DetailConfiguration; - - if( ( configuration == null ) || ( !configuration.AutoCreateForeignKeyConfigurations ) ) - return; - - configuration.SynchronizeForeignKeyConfigurations(); - } - - #endregion - - #region ForeignKeysUpdatedOnAutoCreate Property - - internal bool ForeignKeysUpdatedOnAutoCreate - { - get; - set; - } - - #endregion - - #region CurrentColumn Property - - internal ColumnBase CurrentColumn - { - get - { - return m_currentColumn; - } - set - { - if( m_currentColumn != value ) - { - m_currentColumn = value; - - if( this.CurrentColumnChanged != null ) - this.CurrentColumnChanged( this, EventArgs.Empty ); - } - } - } - - internal event EventHandler CurrentColumnChanged; - - private ColumnBase m_currentColumn; // = null - - #endregion - - #region ColumnsByVisiblePosition Read-Only Property - - internal HashedLinkedList ColumnsByVisiblePosition - { - get - { - return m_columnManager.ColumnsByVisiblePosition; - } - } - - #endregion - - #region ItemsSourcePropertyDescriptions Internal Property - - internal PropertyDescriptionRouteDictionary ItemsSourcePropertyDescriptions - { - get - { - return m_itemsSourcePropertyDescriptions; - } - } - - private readonly PropertyDescriptionRouteDictionary m_itemsSourcePropertyDescriptions = new PropertyDescriptionRouteDictionary(); - - #endregion - - #region ShouldCreateColumns Property - - internal bool ShouldCreateColumns - { - get - { - return m_shouldCreateColumns; - } - set - { - m_shouldCreateColumns = value; - } - } - - #endregion - - #region SortDescriptionsSyncContext Read-Only Property - - internal SortDescriptionsSyncContext SortDescriptionsSyncContext - { - get - { - DataGridSortDescriptionCollection dataGridSortDescriptions = m_sortDescriptions as DataGridSortDescriptionCollection; - if( dataGridSortDescriptions != null ) - return dataGridSortDescriptions.SyncContext; - - if( m_sortDescriptionsSyncContext == null ) - { - m_sortDescriptionsSyncContext = new SortDescriptionsSyncContext(); - } - - return m_sortDescriptionsSyncContext; - } - } - - private SortDescriptionsSyncContext m_sortDescriptionsSyncContext; // = null - - #endregion - - #region SortDescriptions Read-Only Property - - internal SortDescriptionCollection SortDescriptions - { - get - { - return m_sortDescriptions; - } - } - - private SortDescriptionCollection m_sortDescriptions; // = null - - #endregion - - #region GroupDescriptions Read-Only Property - - internal ObservableCollection GroupDescriptions - { - get - { - return m_groupDescriptions; - } - } - - private ObservableCollection m_groupDescriptions; // = null - - #endregion - - #region DataGridControl Internal Property - - internal DataGridControl DataGridControl - { - get - { - return m_dataGridControl; - } - private set - { - if( value == m_dataGridControl ) - return; - - var oldDataGridControl = m_dataGridControl; - - if( m_dataGridControl != null ) - { - ViewChangedEventManager.RemoveListener( m_dataGridControl, this ); - } - - m_dataGridControl = value; - - if( m_dataGridControl != null ) - { - ViewChangedEventManager.AddListener( m_dataGridControl, this ); - } - - if( value != null ) - { - m_columnManager.Initialize( value ); - m_columnManager.SetFixedColumnCount( TableView.GetFixedColumnCount( this ) ); - } - else - { - m_columnManager.Clear(); - } - - var detailConfigurations = this.DetailConfigurations; - if( detailConfigurations != null ) - { - detailConfigurations.DataGridControl = value; - } - - this.InitializeItemPropertyMap( this.DataGridControl, this.DetailDescription ); - this.OnPropertyChanged( DetailConfiguration.DataGridControlPropertyName ); - - if( m_dataGridControl == null ) - { - this.BeginInit(); - } - else if( oldDataGridControl == null ) - { - this.EndInit(); - } - } - } - - private DataGridControl m_dataGridControl; - - #endregion - - #region DataGridContext Property - - internal DataGridContext DataGridContext - { - get - { - return m_dataGridContexts.FirstOrDefault(); - } - } - - internal void AddDataGridContext( DataGridContext dataGridContext ) - { - Debug.Assert( dataGridContext != null ); - - m_dataGridContexts.Add( dataGridContext ); - } - - internal void RemoveDataGridContext( DataGridContext dataGridContext ) - { - var oldCount = m_dataGridContexts.Count; - m_dataGridContexts.Remove( dataGridContext ); - var newCount = m_dataGridContexts.Count; - } - - private readonly ICollection m_dataGridContexts = new HashSet(); - - #endregion - - #region ParentDetailConfiguration Internal Property - - internal DetailConfiguration ParentDetailConfiguration - { - get - { - if( m_containingCollection == null ) - return null; - - return m_containingCollection.ParentDetailConfiguration; - } - } - - #endregion - - #region ColumnManagerRowConfiguration Internal Property - - internal ColumnManagerRowConfiguration ColumnManagerRowConfiguration - { - get - { - return m_columnManagerRowConfiguration; - } - } - - private readonly ColumnManagerRowConfiguration m_columnManagerRowConfiguration; - - #endregion - - #region IsAutoCreated Internal Property - - internal bool IsAutoCreated - { - get - { - return m_isAutoCreated; - } - private set - { - m_isAutoCreated = value; - } - } - - private bool m_isAutoCreated = false; - - #endregion - - #region IsCreatedFromSelector Property - - private bool IsCreatedFromSelector - { - get; - set; - } - - #endregion - - #region ItemPropertyMap Internal Property - - internal DataGridItemPropertyMap ItemPropertyMap - { - get - { - return m_itemPropertyMap; - } - } - - private readonly DataGridItemPropertyMap m_itemPropertyMap = new DataGridItemPropertyMap(); - - #endregion - - #region UpdateColumnSortCommand Internal Property - - internal UpdateColumnSortCommand UpdateColumnSortCommand - { - get - { - if( m_updateColumnSortCommand == null ) - { - m_updateColumnSortCommand = new DetailConfigurationUpdateColumnSortCommand( this ); - } - - Debug.Assert( m_updateColumnSortCommand != null ); - - return m_updateColumnSortCommand; - } - } - - private UpdateColumnSortCommand m_updateColumnSortCommand; - - #endregion - - #region AddGroupCommand Internal Property - - internal ColumnAddGroupCommand AddGroupCommand - { - get - { - if( m_addGroupCommand == null ) - { - m_addGroupCommand = new DetailConfigurationAddGroupCommand( this ); - } - - Debug.Assert( m_addGroupCommand != null ); - - return m_addGroupCommand; - } - } - - private ColumnAddGroupCommand m_addGroupCommand; - - #endregion - - #region IsDeleteCommandEnabled Property - - public static readonly DependencyProperty IsDeleteCommandEnabledProperty = DependencyProperty.Register( - "IsDeleteCommandEnabled", - typeof( bool ), - typeof( DetailConfiguration ), - new FrameworkPropertyMetadata( false, new PropertyChangedCallback( DetailConfiguration.OnIsDeleteCommandEnabledChanged ) ) ); - - public bool IsDeleteCommandEnabled - { - get - { - return ( bool )this.GetValue( DetailConfiguration.IsDeleteCommandEnabledProperty ); - } - set - { - this.SetValue( DetailConfiguration.IsDeleteCommandEnabledProperty, value ); - } - } - - private static void OnIsDeleteCommandEnabledChanged( DependencyObject obj, DependencyPropertyChangedEventArgs e ) - { - CommandManager.InvalidateRequerySuggested(); - } - - #endregion IsDeleteCommandEnabled Property - - #region DetailDescription Internal Property - - internal DataGridDetailDescription DetailDescription - { - get - { - return m_detailDescription; - } - private set - { - if( value == m_detailDescription ) - return; - - m_detailDescription = value; - this.OnPropertyChanged( DetailConfiguration.DetailDescriptionPropertyName ); - } - } - - private DataGridDetailDescription m_detailDescription; // = null - - #endregion - - #region ContainingCollection Private Property - - private DetailConfigurationCollection ContainingCollection - { - get - { - return m_containingCollection; - } - set - { - if( value == m_containingCollection ) - return; - - if( ( m_containingCollection != null ) && ( value != null ) ) - throw new InvalidOperationException( "The DetailConfiguration is already contained in another DetailConfigurationCollection." ); - - if( m_containingCollection != null ) - { - ( ( INotifyPropertyChanged )m_containingCollection ).PropertyChanged -= new PropertyChangedEventHandler( this.OnContainingCollectionPropertyChanged ); - } - - m_containingCollection = value; - - if( m_containingCollection != null ) - { - ( ( INotifyPropertyChanged )m_containingCollection ).PropertyChanged += new PropertyChangedEventHandler( this.OnContainingCollectionPropertyChanged ); - - this.DataGridControl = m_containingCollection.DataGridControl; - } - else - { - this.DataGridControl = null; - } - } - } - - private void OnContainingCollectionPropertyChanged( object sender, PropertyChangedEventArgs e ) - { - var containingCollection = ( DetailConfigurationCollection )sender; - Debug.Assert( containingCollection == this.ContainingCollection ); - - var propertyName = e.PropertyName; - bool mayHaveChanged = string.IsNullOrEmpty( propertyName ); - - if( mayHaveChanged || ( propertyName == "DataGridControl" ) ) - { - this.DataGridControl = containingCollection.DataGridControl; - } - } - - private DetailConfigurationCollection m_containingCollection; // = null - - #endregion - - #region ColumnSynchronizationManager Private Read-Only Property - - private ColumnSynchronizationManager ColumnSynchronizationManager - { - get - { - return m_columnSynchronizationManager; - } - } - - private readonly ColumnSynchronizationManager m_columnSynchronizationManager; - - #endregion - - #region ColumnManager Internal Property - - internal ColumnHierarchyManager ColumnManager - { - get - { - return m_columnManager; - } - } - - private readonly ColumnHierarchyManager m_columnManager; - - #endregion - - public IDisposable DeferColumnsUpdate() - { - return ColumnHierarchyManagerHelper.DeferColumnsUpdate( this ); - } - - public bool MoveColumnBefore( ColumnBase current, ColumnBase next ) - { - return ColumnHierarchyManagerHelper.MoveColumnBefore( this, current, next ); - } - - public bool MoveColumnAfter( ColumnBase current, ColumnBase previous ) - { - return ColumnHierarchyManagerHelper.MoveColumnAfter( this, current, previous ); - } - - public bool MoveColumnUnder( ColumnBase current, ColumnBase parent ) - { - return ColumnHierarchyManagerHelper.MoveColumnUnder( this, current, parent ); - } - - protected override void OnPropertyChanged( DependencyPropertyChangedEventArgs e ) - { - base.OnPropertyChanged( e ); - - if( e.Property == DetailConfiguration.GroupConfigurationSelectorProperty ) - { - var handler = this.GroupConfigurationSelectorChanged; - if( handler != null ) - { - handler.Invoke( this, EventArgs.Empty ); - } - } - - this.OnPropertyChanged( e.Property.Name ); - } - - internal void AddDefaultHeadersFooters() - { - if( m_defaultHeadersFootersAdded ) - return; - - m_defaultHeadersFootersAdded = true; - - DetailConfiguration.AddDefaultHeadersFooters( this.Headers, 0, this.DataGridControl.AreDetailsFlatten ); - } - - internal void SynchronizeForeignKeyConfigurations() - { - var detailDescription = this.DetailDescription; - if( detailDescription == null ) - return; - - ForeignKeyConfiguration.UpdateColumnsForeignKeyConfigurationsFromDataGridCollectionView( - this.Columns, - detailDescription.ItemProperties, - this.AutoCreateForeignKeyConfigurations ); - } - - internal void AttachToContainingCollection( DetailConfigurationCollection detailConfigurationCollection ) - { - if( detailConfigurationCollection == null ) - throw new ArgumentNullException( "detailConfigurationCollection" ); - - this.ContainingCollection = detailConfigurationCollection; - } - - internal void DetachFromContainingCollection() - { - this.ContainingCollection = null; - } - - private void SynchronizeWithDetailDescription( DataGridDetailDescription detailDescription ) - { - if( detailDescription == this.DetailDescription ) - return; - - this.DetachFromDetailDescription( false ); - - m_shouldCreateColumns = true; - this.DetailDescription = detailDescription; - - DataGridSortDescriptionCollection dataGridSortDescriptionCollection; - ObservableCollection groupDescriptionCollection; - - if( detailDescription != null ) - { - groupDescriptionCollection = detailDescription.GroupDescriptions; - - //register to the collectionchanged of the DataGridDetailDescription collection of the detailDescription matching this one. - dataGridSortDescriptionCollection = detailDescription.DataGridSortDescriptions; - - this.RegisterItemProperties( detailDescription.ItemProperties ); - - CollectionChangedEventManager.AddListener( detailDescription.DetailDescriptions, this ); - } - else - { - groupDescriptionCollection = new GroupDescriptionCollection(); - dataGridSortDescriptionCollection = new DataGridSortDescriptionCollection(); - } - - m_groupDescriptions = groupDescriptionCollection; - m_sortDescriptions = dataGridSortDescriptionCollection; - m_sortDescriptionsSyncContext = null; //clear it, if it was ever set! - - this.InitializeItemPropertyMap( this.DataGridControl, detailDescription ); - - //This update is required since there might be some columns in the columns collection after the XAML parsing of the DetailConfiguration - this.UpdateColumnSortOrder(); - - //This update is required since we want the GroupLevelDescriptions to be created if DetailConfiguration in XAML - //contains GroupDescriptions - DataGridContext.UpdateGroupLevelDescriptions( this.GroupLevelDescriptions, - new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Reset ), - this.GroupDescriptions, - this.Columns ); - - CollectionChangedEventManager.AddListener( m_sortDescriptions, this ); - CollectionChangedEventManager.AddListener( m_groupDescriptions, this ); - - if( detailDescription != null ) - { - if( this.ReadLocalValue( DetailConfiguration.TitleProperty ) == DependencyProperty.UnsetValue ) - { - if( detailDescription.Title == null ) - { - this.Title = detailDescription.RelationName; - } - else - { - this.Title = detailDescription.Title; - } - } - - if( ( this.ReadLocalValue( DetailConfiguration.TitleTemplateProperty ) == DependencyProperty.UnsetValue ) - && ( detailDescription.TitleTemplate != null ) ) - { - this.TitleTemplate = detailDescription.TitleTemplate; - } - } - - this.UpdateColumns(); - } - - private void DetachFromDetailDescription() - { - this.DetachFromDetailDescription( true ); - } - - private void DetachFromDetailDescription( bool synchronizeColumns ) - { - var detailDescription = this.DetailDescription; - if( detailDescription != null ) - { - this.UnregisterItemProperties( detailDescription.ItemProperties ); - - CollectionChangedEventManager.RemoveListener( detailDescription.DetailDescriptions, this ); - } - - if( m_sortDescriptions != null ) - { - CollectionChangedEventManager.RemoveListener( m_sortDescriptions, this ); - } - - if( m_groupDescriptions != null ) - { - CollectionChangedEventManager.RemoveListener( m_groupDescriptions, this ); - } - - m_sortDescriptions = null; - m_groupDescriptions = null; - m_itemsSourcePropertyDescriptions.Clear(); - - this.InitializeItemPropertyMap( this.DataGridControl, null ); - this.DetailDescription = null; - - if( synchronizeColumns ) - { - m_columnSynchronizationManager.Refresh(); - } - } - - private void InitializeItemPropertyMap( DataGridControl dataGridControl, DataGridDetailDescription detailDescription ) - { - using( m_itemPropertyMap.DeferMappingChanged() ) - { - if( ( dataGridControl == null ) || ( detailDescription == null ) || !dataGridControl.AreDetailsFlatten ) - { - m_itemPropertyMap.MasterItemProperties = null; - m_itemPropertyMap.DetailItemProperties = null; - } - else - { - var collectionView = dataGridControl.Items.SourceCollection as DataGridCollectionViewBase; - if( collectionView != null ) - { - m_itemPropertyMap.MasterItemProperties = collectionView.ItemProperties; - m_itemPropertyMap.DetailItemProperties = detailDescription.ItemProperties; - } - else - { - m_itemPropertyMap.MasterItemProperties = null; - m_itemPropertyMap.DetailItemProperties = null; - } - } - } - } - - private void UpdateColumns() - { - var detailDescription = this.DetailDescription; - var dataGridControl = this.DataGridControl; - var dataGridContext = this.DataGridContext; - - if( ( detailDescription != null ) && ( dataGridControl != null ) && ( dataGridContext != null ) ) - { - ItemsSourceHelper.ResetPropertyDescriptions( m_itemsSourcePropertyDescriptions, m_itemPropertyMap, dataGridControl, dataGridContext.Items ); - - if( this.AutoCreateColumns ) - { - ItemsSourceHelper.UpdateColumnsFromPropertyDescriptions( m_columnManager, dataGridControl.DefaultCellEditors, m_itemsSourcePropertyDescriptions, this.AutoCreateForeignKeyConfigurations ); - } - } - else - { - m_itemsSourcePropertyDescriptions.Clear(); - } - - if( detailDescription != null ) - { - // Ensure to update ForeignKeyDescriptions and ForeignKeyConfigurations when ItemProperties change on DetailDescription. - ForeignKeyConfiguration.UpdateColumnsForeignKeyConfigurationsFromDataGridCollectionView( - this.Columns, - detailDescription.ItemProperties, - this.AutoCreateForeignKeyConfigurations ); - } - } - - private void RegisterItemProperties( DataGridItemPropertyCollection itemProperties ) - { - if( itemProperties == null ) - return; - - CollectionChangedEventManager.AddListener( itemProperties, this ); - - foreach( var itemProperty in itemProperties ) - { - this.RegisterItemProperty( itemProperty ); - } - } - - private void UnregisterItemProperties( DataGridItemPropertyCollection itemProperties ) - { - if( itemProperties == null ) - return; - - foreach( var itemProperty in itemProperties ) - { - this.UnregisterItemProperty( itemProperty ); - } - - CollectionChangedEventManager.RemoveListener( itemProperties, this ); - } - - private void RegisterItemProperty( DataGridItemPropertyBase itemProperty ) - { - if( itemProperty == null ) - return; - - PropertyChangedEventManager.AddListener( itemProperty, this, DataGridItemPropertyBase.ItemPropertiesInternalPropertyName ); - this.RegisterItemProperties( itemProperty.ItemPropertiesInternal ); - } - - private void UnregisterItemProperty( DataGridItemPropertyBase itemProperty ) - { - if( itemProperty == null ) - return; - - this.UnregisterItemProperties( itemProperty.ItemPropertiesInternal ); - PropertyChangedEventManager.RemoveListener( itemProperty, this, DataGridItemPropertyBase.ItemPropertiesInternalPropertyName ); - } - - private void UpdateColumnSortOrder() - { - var updateColumnSortCommand = this.UpdateColumnSortCommand; - if( updateColumnSortCommand.CanExecute() ) - { - this.UpdateColumnSortCommand.Execute(); - } - } - - private void SortDescriptions_CollectionChanged( object sender, NotifyCollectionChangedEventArgs e ) - { - this.RequestDelayBringIntoViewAndFocusCurrent( AutoScrollCurrentItemSourceTriggers.SortChanged ); - this.UpdateColumnSortOrder(); - } - - private void GroupDescriptions_CollectionChanged( object sender, NotifyCollectionChangedEventArgs e ) - { - this.RequestDelayBringIntoViewAndFocusCurrent( AutoScrollCurrentItemSourceTriggers.GroupChanged ); - DataGridContext.UpdateGroupLevelDescriptions( this.GroupLevelDescriptions, e, m_groupDescriptions, this.Columns ); - } - - private void OnColumnsCollectionChanged( object sender, NotifyCollectionChangedEventArgs e ) - { - //call the method that will detect if the CurrentColumn should be removed based on the changes in the Columns collection. - this.HandleCurrentColumnRemove( e ); - - this.RequestDelayBringIntoViewAndFocusCurrent( AutoScrollCurrentItemSourceTriggers.ColumnsCollectionChanged ); - this.UpdateColumnSortOrder(); - - var detailDescription = this.DetailDescription; - if( detailDescription != null ) - { - switch( e.Action ) - { - case NotifyCollectionChangedAction.Add: - case NotifyCollectionChangedAction.Replace: - case NotifyCollectionChangedAction.Reset: - { - ForeignKeyConfiguration.UpdateColumnsForeignKeyConfigurationsFromDataGridCollectionView( - this.Columns, - detailDescription.ItemProperties, - this.AutoCreateForeignKeyConfigurations ); - } - break; - - default: - break; - } - } - } - - private void OnItemPropertiesCollectionChanged( DataGridItemPropertyCollection collection, NotifyCollectionChangedEventArgs e ) - { - var detailDescription = this.DetailDescription; - if( detailDescription == null ) - return; - - var rootCollection = ItemsSourceHelper.GetRootCollection( collection ); - if( rootCollection == null ) - return; - - if( rootCollection == detailDescription.ItemProperties ) - { - if( e.Action == NotifyCollectionChangedAction.Reset ) - throw new NotSupportedException(); - - if( e.Action == NotifyCollectionChangedAction.Move ) - return; - - if( e.OldItems != null ) - { - foreach( DataGridItemPropertyBase itemProperty in e.OldItems ) - { - this.UnregisterItemProperty( itemProperty ); - } - } - - if( e.NewItems != null ) - { - foreach( DataGridItemPropertyBase itemProperty in e.NewItems ) - { - this.RegisterItemProperty( itemProperty ); - } - } - - this.UpdateColumns(); - } - else - { - Debug.Fail( "The collection is not linked to the detail configuration's item properties." ); - this.UnregisterItemProperties( collection ); - } - } - - private void OnItemPropertyPropertyChanged( DataGridItemPropertyBase itemProperty, PropertyChangedEventArgs e ) - { - var detailDescription = this.DetailDescription; - if( detailDescription == null ) - return; - - var rootCollection = ItemsSourceHelper.GetRootCollection( itemProperty ); - if( rootCollection == null ) - return; - - if( rootCollection != detailDescription.ItemProperties ) - { - Debug.Fail( "The collection is not linked to the detail configuration's item properties." ); - this.UnregisterItemProperty( itemProperty ); - return; - } - - if( string.IsNullOrEmpty( e.PropertyName ) || ( e.PropertyName == DataGridItemPropertyBase.ItemPropertiesInternalPropertyName ) ) - { - var itemProperties = itemProperty.ItemPropertiesInternal; - if( itemProperties != null ) - { - this.UnregisterItemProperties( itemProperties ); - this.RegisterItemProperties( itemProperties ); - this.UpdateColumns(); - } - } - } - - private void HandleCurrentColumnRemove( NotifyCollectionChangedEventArgs e ) - { - var currentColumn = this.CurrentColumn; - if( currentColumn == null ) - return; - - var removeCurrentColumn = false; - - if( e.Action == NotifyCollectionChangedAction.Reset ) - { - removeCurrentColumn = !this.Columns.Contains( currentColumn ); - } - else if( ( e.Action == NotifyCollectionChangedAction.Remove ) && ( e.OldItems.Contains( currentColumn ) ) ) - { - //Remove of at least the current column - removeCurrentColumn = true; - } - else if( ( e.Action == NotifyCollectionChangedAction.Replace ) && ( e.OldItems.Contains( currentColumn ) ) && ( !e.NewItems.Contains( currentColumn ) ) ) - { - //Replace in which at least the current column was "replaced" by another (current column not present in new items ) - removeCurrentColumn = true; - } - - //If we computed that current columns should be cleared - if( removeCurrentColumn ) - { - //reset current column. - this.CurrentColumn = DataGridContext.GetClosestColumn( currentColumn, this.ColumnsByVisiblePosition ); - } - } - - private void OnDetailConfigurationsChanged( object sender, NotifyCollectionChangedEventArgs e ) - { - var detailDescription = this.DetailDescription; - var detailDescriptions = ( detailDescription != null ) ? detailDescription.DetailDescriptions : null; - - switch( e.Action ) - { - case NotifyCollectionChangedAction.Replace: - case NotifyCollectionChangedAction.Add: - DetailConfiguration.SynchronizeAddedConfigurations( e.NewItems, detailDescriptions ); - break; - case NotifyCollectionChangedAction.Reset: - case NotifyCollectionChangedAction.Remove: - case NotifyCollectionChangedAction.Move: - default: - break; - } - } - - private void RequestDelayBringIntoViewAndFocusCurrent( AutoScrollCurrentItemSourceTriggers trigger ) - { - } - - #region IWeakEventListener Members - - bool IWeakEventListener.ReceiveWeakEvent( Type managerType, object sender, EventArgs e ) - { - return this.OnReceiveWeakEvent( managerType, sender, e ); - } - - private bool OnReceiveWeakEvent( Type managerType, object sender, EventArgs e ) - { - //check if the event comes from a INotifyCollectionChanged collection - if( managerType == typeof( CollectionChangedEventManager ) ) - { - var eventArgs = ( NotifyCollectionChangedEventArgs )e; - - if( sender is DetailConfigurationCollection ) - { - this.OnDetailConfigurationsChanged( sender, eventArgs ); - } - else if( sender is SortDescriptionCollection ) - { - this.SortDescriptions_CollectionChanged( sender, eventArgs ); - } - else if( sender is ObservableCollection ) - { - this.GroupDescriptions_CollectionChanged( sender, eventArgs ); - } - else if( sender is DataGridDetailDescriptionCollection ) - { - } - else if( sender is DataGridItemPropertyCollection ) - { - this.OnItemPropertiesCollectionChanged( ( DataGridItemPropertyCollection )sender, eventArgs ); - } - } - else if( managerType == typeof( PropertyChangedEventManager ) ) - { - var eventArgs = ( PropertyChangedEventArgs )e; - - if( sender is DataGridItemPropertyBase ) - { - this.OnItemPropertyPropertyChanged( ( DataGridItemPropertyBase )sender, eventArgs ); - } - } - else if( managerType == typeof( ViewChangedEventManager ) ) - { - this.InitializeItemPropertyMap( this.DataGridControl, this.DetailDescription ); - } - else - { - return false; - } - - return true; - } - - #endregion - - #region ISupportInitialize Members - - public void BeginInit() - { - m_initCount++; - if( m_initCount != 1 ) - return; - - Debug.Assert( m_deferColumnsLayoutUpdate == null ); - m_deferColumnsLayoutUpdate = m_columnManager.DeferUpdate(); - - m_deferColumnsNotifications = this.Columns.DeferNotifications(); - } - - public void EndInit() - { - m_initCount--; - if( m_initCount != 0 ) - return; - - var columnsNotificationsDisposable = m_deferColumnsNotifications; - m_deferColumnsNotifications = null; - columnsNotificationsDisposable.Dispose(); - - Debug.Assert( m_deferColumnsLayoutUpdate != null ); - var columnsUpdateDisposable = m_deferColumnsLayoutUpdate; - m_deferColumnsLayoutUpdate = null; - columnsUpdateDisposable.Dispose(); - } - - private int m_initCount = 0; - private IDisposable m_deferColumnsLayoutUpdate; //null - private IDisposable m_deferColumnsNotifications; //null - - #endregion - - #region INotifyPropertyChanged Members - - public event PropertyChangedEventHandler PropertyChanged; - - private void OnPropertyChanged( string propertyName ) - { - var handler = this.PropertyChanged; - if( handler == null ) - return; - - handler.Invoke( this, new PropertyChangedEventArgs( propertyName ) ); - } - - #endregion - - private bool m_shouldCreateColumns = true; - private bool m_defaultHeadersFootersAdded; // = false - - private sealed class DetailConfigurationUpdateColumnSortCommand : UpdateColumnSortCommand - { - private static void ThrowIfDetailsNotFlatten( DetailConfiguration detailConfiguration ) - { - Debug.Assert( detailConfiguration != null ); - - var dataGridControl = detailConfiguration.DataGridControl; - if( ( dataGridControl != null ) && ( !dataGridControl.AreDetailsFlatten ) ) - throw new InvalidOperationException( "This method cannot be invoked when details are not flattened." ); - } - - internal DetailConfigurationUpdateColumnSortCommand( DetailConfiguration detailConfiguration ) - { - DetailConfigurationUpdateColumnSortCommand.ThrowIfNull( detailConfiguration, "detailConfiguration" ); - - m_detailConfiguration = new WeakReference( detailConfiguration ); - } - - #region SortDescriptionsSyncContext Protected Property - - protected override SortDescriptionsSyncContext SortDescriptionsSyncContext - { - get - { - var detailConfiguration = this.DetailConfiguration; - if( detailConfiguration == null ) - return null; - - return detailConfiguration.SortDescriptionsSyncContext; - } - } - - #endregion - - #region DetailConfiguration Private Property - - private DetailConfiguration DetailConfiguration - { - get - { - return m_detailConfiguration.Target as DetailConfiguration; - } - } - - private readonly WeakReference m_detailConfiguration; - - #endregion - - protected override bool CanExecuteCore() - { - var detailConfiguration = this.DetailConfiguration; - if( detailConfiguration == null ) - return false; - - var dataGridControl = detailConfiguration.DataGridControl; - if( dataGridControl == null ) - return false; - - var detailDescription = detailConfiguration.DetailDescription; - if( detailDescription == null ) - return false; - - return true; - } - - protected override void ExecuteCore() - { - DetailConfiguration detailConfiguration = this.DetailConfiguration; - if( detailConfiguration == null ) - return; - - var dataGridControl = detailConfiguration.DataGridControl; - if( dataGridControl == null ) - return; - - using( var synchronizationContext = this.StartSynchronizing( detailConfiguration.SortDescriptionsSyncContext ) ) - { - // The SortDescription collection is already being updated. - if( !synchronizationContext.Own ) - return; - - // The sort order of the flatten details is driven by the master. Flatten details are not - // allowed to modify the sort order at their level. - if( dataGridControl.AreDetailsFlatten ) - { - this.SynchronizeDetailSortDescriptions( synchronizationContext, detailConfiguration ); - } - - this.SynchronizeColumnSort( - synchronizationContext, - detailConfiguration.SortDescriptions, - detailConfiguration.Columns ); - } - } - - private static IEnumerable GetDataGridContexts( DetailConfiguration detailConfiguration ) - { - Debug.Assert( detailConfiguration != null ); - - var dataGridControl = detailConfiguration.DataGridControl; - Debug.Assert( dataGridControl != null ); - - var queue = new Queue(); - queue.Enqueue( dataGridControl.DataGridContext ); - - while( queue.Count > 0 ) - { - DataGridContext dataGridContext = queue.Dequeue(); - - if( dataGridContext.SourceDetailConfiguration == detailConfiguration ) - { - yield return dataGridContext; - } - else - { - foreach( var childContext in dataGridContext.GetChildContexts() ) - { - queue.Enqueue( childContext ); - } - } - } - } - - private IDisposable DeferResortHelper( DetailConfiguration detailConfiguration ) - { - ColumnSortCommand.ThrowIfNull( detailConfiguration, "detailConfiguration" ); - - IDisposable defer; - if( this.TryDeferResort( detailConfiguration, out defer ) ) - return defer; - - var disposer = new Disposer(); - - foreach( var dataGridContext in DetailConfigurationUpdateColumnSortCommand.GetDataGridContexts( detailConfiguration ) ) - { - disposer.Add( this.DeferResortHelper( dataGridContext.ItemsSourceCollection, dataGridContext.Items ), DisposableType.DeferResort ); - } - - return disposer; - } - - private void SynchronizeDetailSortDescriptions( SynchronizationContext synchronizationContext, DetailConfiguration detailConfiguration ) - { - ColumnSortCommand.ThrowIfNull( synchronizationContext, "synchronizationContext" ); - ColumnSortCommand.ThrowIfNull( detailConfiguration, "detailConfiguration" ); - DetailConfigurationUpdateColumnSortCommand.ThrowIfDetailsNotFlatten( detailConfiguration ); - - if( !synchronizationContext.Own ) - return; - - if( detailConfiguration.DetailDescription == null ) - return; - - var dataGridControl = detailConfiguration.DataGridControl; - if( dataGridControl == null ) - return; - - var rootDataGridContext = dataGridControl.DataGridContext; - var masterSortDescriptions = rootDataGridContext.Items.SortDescriptions; - var detailSortDescriptions = detailConfiguration.SortDescriptions; - - // There is nothing to synchronize. - if( ( masterSortDescriptions.Count == 0 ) && ( detailSortDescriptions.Count == 0 ) ) - return; - - using( this.DeferResortHelper( detailConfiguration ) ) - { - this.SynchronizeDetailSortDescriptions( masterSortDescriptions, detailSortDescriptions, detailConfiguration ); - } - } - - private void SynchronizeDetailSortDescriptions( SortDescriptionCollection masterSortDescriptions, SortDescriptionCollection detailSortDescriptions, DetailConfiguration detailConfiguration ) - { - ColumnSortCommand.ThrowIfNull( masterSortDescriptions, "masterSortDescriptions" ); - ColumnSortCommand.ThrowIfNull( detailSortDescriptions, "detailSortDescriptions" ); - - var itemPropertyMap = detailConfiguration.ItemPropertyMap; - ColumnSortCommand.ThrowIfNull( itemPropertyMap, "itemPropertyMap" ); - - var masterSortDescriptionsCount = masterSortDescriptions.Count; - if( masterSortDescriptionsCount > 0 ) - { - var insertionIndex = 0; - - for( int i = 0; i < masterSortDescriptionsCount; i++ ) - { - var sortDescription = masterSortDescriptions[ i ]; - var detailPropertyName = default( string ); - - if( !DataGridItemPropertyMapHelper.TryGetDetailColumnName( itemPropertyMap, sortDescription.PropertyName, out detailPropertyName ) ) - continue; - - var detailDirection = sortDescription.Direction; - - if( insertionIndex < detailSortDescriptions.Count ) - { - var detailSortDescription = detailSortDescriptions[ insertionIndex ]; - - if( ( detailSortDescription.PropertyName != detailPropertyName ) || ( detailSortDescription.Direction != detailDirection ) ) - { - detailSortDescriptions[ insertionIndex ] = new SortDescription( detailPropertyName, detailDirection ); - } - } - else - { - detailSortDescriptions.Add( new SortDescription( detailPropertyName, detailDirection ) ); - } - - insertionIndex++; - } - - while( insertionIndex < detailSortDescriptions.Count ) - { - detailSortDescriptions.RemoveAt( insertionIndex ); - } - } - else if( detailSortDescriptions.Count > 0 ) - { - detailSortDescriptions.Clear(); - } - } - } - - private sealed class DetailConfigurationAddGroupCommand : ColumnAddGroupCommand - { - internal DetailConfigurationAddGroupCommand( DetailConfiguration detailConfiguration ) - { - DetailConfigurationAddGroupCommand.ThrowIfNull( detailConfiguration, "detailConfiguration" ); - - m_detailConfiguration = new WeakReference( detailConfiguration ); - } - - #region GroupDescriptions Protected Property - - protected override ObservableCollection GroupDescriptions - { - get - { - var detailConfiguration = this.DetailConfiguration; - if( detailConfiguration == null ) - return null; - - return detailConfiguration.GroupDescriptions; - } - } - - #endregion - - #region DetailConfiguration Private Property - - private DetailConfiguration DetailConfiguration - { - get - { - return m_detailConfiguration.Target as DetailConfiguration; - } - } - - private readonly WeakReference m_detailConfiguration; - - #endregion - - protected override string GetColumnName( ColumnBase column ) - { - var detailConfiguration = this.DetailConfiguration; - if( ( detailConfiguration == null ) || ( column == null ) ) - return null; - - var itemPropertyMap = detailConfiguration.ItemPropertyMap; - if( ( itemPropertyMap != null ) && itemPropertyMap.IsMapping ) - { - string fieldName; - if( DataGridItemPropertyMapHelper.TryGetDetailColumnName( itemPropertyMap, column.FieldName, out fieldName ) ) - return fieldName; - } - else - { - return column.FieldName; - } - - return null; - } - - protected override GroupDescription GetGroupDescription( ColumnBase column ) - { - var detailConfiguration = this.DetailConfiguration; - if( detailConfiguration == null ) - return null; - - return base.GetGroupDescription( column ); - } - - protected override GroupConfiguration GetGroupConfiguration( ColumnBase column ) - { - var detailConfiguration = this.DetailConfiguration; - if( detailConfiguration == null ) - return null; - - return base.GetGroupConfiguration( column ); - } - - protected override bool CanExecuteCore( ColumnBase column, int index ) - { - if( this.DetailConfiguration == null ) - return false; - - return base.CanExecuteCore( column, index ); - } - - protected override void ExecuteCore( ColumnBase column, int index ) - { - var detailConfig = this.DetailConfiguration; - if( detailConfig == null ) - return; - - var dataGridControl = detailConfig.DataGridControl; - IDisposable disposable = null; - - try - { - if( dataGridControl != null ) - { - disposable = dataGridControl.SetQueueBringIntoViewRestrictions( AutoScrollCurrentItemSourceTriggers.CollectionViewCurrentItemChanged ); - } - - base.ExecuteCore( column, index ); - } - finally - { - if( disposable != null ) - { - disposable.Dispose(); - } - } - } - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DetailConfigurationCollection.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DetailConfigurationCollection.cs deleted file mode 100644 index 22632842..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DetailConfigurationCollection.cs +++ /dev/null @@ -1,159 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal class DetailConfigurationCollection : ObservableCollection, IWeakEventListener - { - internal DetailConfigurationCollection( DataGridControl dataGridControl, DetailConfiguration parentDetailConfiguration ) - : base() - { - this.DataGridControl = dataGridControl; - this.ParentDetailConfiguration = parentDetailConfiguration; - } - - #region DataGridControl Property - - internal DataGridControl DataGridControl - { - get - { - return m_dataGridControl; - } - set - { - if( m_dataGridControl == value ) - return; - - m_dataGridControl = value; - - this.OnPropertyChanged( new PropertyChangedEventArgs( "DataGridControl" ) ); - } - } - - private DataGridControl m_dataGridControl; - - #endregion - - #region ParentDetailConfiguration Property - - internal DetailConfiguration ParentDetailConfiguration - { - get; - set; - } - - #endregion - - public DetailConfiguration this[ string relationName ] - { - get - { - foreach( DetailConfiguration config in this ) - { - if( string.Equals( config.RelationName, relationName ) == true ) - { - return config; - } - } - - return null; - } - } - - protected override void InsertItem( int index, DetailConfiguration item ) - { - if( item != null ) - { - item.AttachToContainingCollection( this ); - - DetailVisibilityChangedEventManager.AddListener( item, this ); - } - - base.InsertItem( index, item ); - } - - protected override void RemoveItem( int index ) - { - DetailConfiguration detailConfig = this[ index ]; - - detailConfig.DetachFromContainingCollection(); - - DetailVisibilityChangedEventManager.RemoveListener( detailConfig, this ); - - base.RemoveItem( index ); - } - - protected override void ClearItems() - { - foreach( DetailConfiguration detailConfig in this ) - { - detailConfig.DetachFromContainingCollection(); - - DetailVisibilityChangedEventManager.RemoveListener( detailConfig, this ); - } - - base.ClearItems(); - } - - protected override void SetItem( int index, DetailConfiguration item ) - { - DetailConfiguration detailConfig = this[ index ]; - - if( ( detailConfig != null ) && ( detailConfig != item ) ) - { - detailConfig.DetachFromContainingCollection(); - } - - if( ( item != null ) && ( item != detailConfig ) ) - { - item.AttachToContainingCollection( this ); - } - - base.SetItem( index, item ); - } - - #region IWeakEventListener Members - - internal event EventHandler DetailVisibilityChanged; - - 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( managerType == typeof( DetailVisibilityChangedEventManager ) ) - { - if( this.DetailVisibilityChanged != null ) - { - this.DetailVisibilityChanged( this, EventArgs.Empty ); - } - - return true; - } - return false; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DetailConfigurationSelector.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DetailConfigurationSelector.cs deleted file mode 100644 index fca7f661..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DetailConfigurationSelector.cs +++ /dev/null @@ -1,26 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -namespace Xceed.Wpf.DataGrid -{ - public abstract class DetailConfigurationSelector - { - internal virtual DetailConfiguration SelectDetailConfiguration( string relationName, DataGridDetailDescription dataGridDetailDescription ) - { - return null; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DetailIndicator.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DetailIndicator.cs deleted file mode 100644 index e4e7a52e..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DetailIndicator.cs +++ /dev/null @@ -1,46 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - public class DetailIndicator : GroupLevelIndicator - { - static DetailIndicator() - { - DataGridControl.ParentDataGridControlPropertyKey.OverrideMetadata( typeof( DetailIndicator ), new FrameworkPropertyMetadata( new PropertyChangedCallback( DetailIndicator.OnParentGridControlChanged ) ) ); - - FocusableProperty.OverrideMetadata(typeof(DetailIndicator), new FrameworkPropertyMetadata(false)); - } - - protected internal override void PrepareDefaultStyleKey( Xceed.Wpf.DataGrid.Views.ViewBase view ) - { - this.DefaultStyleKey = view.GetDefaultStyleKey( typeof( DetailIndicator ) ); - } - - private static void OnParentGridControlChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - DataGridControl grid = e.NewValue as DataGridControl; - - if( grid != null ) - ( ( DetailIndicator )sender ).PrepareDefaultStyleKey( grid.GetView() ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Diagnostics/DataGridControlTraceSources.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Diagnostics/DataGridControlTraceSources.cs deleted file mode 100644 index 1e48c1d8..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Diagnostics/DataGridControlTraceSources.cs +++ /dev/null @@ -1,68 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Diagnostics; -using System.Threading; - -namespace Xceed.Wpf.DataGrid.Diagnostics -{ - internal static class DataGridControlTraceSources - { - #region CollectionViewSource Property - - internal static DataGridTraceSource CollectionViewSource - { - get - { - return DataGridControlTraceSources.DataGridTraceSource; - } - } - - #endregion - - #region ItemContainerGeneratorSource Property - - internal static DataGridTraceSource ItemContainerGeneratorSource - { - get - { - return DataGridControlTraceSources.DataGridTraceSource; - } - } - - #endregion - - #region DataSource Private Property - - private static DataGridTraceSource DataGridTraceSource - { - get - { - if( s_traceSource == null ) - { - var source = new DataGridTraceSource( new TraceSource( "Xceed.Wpf.DataGrid" ) ); - Interlocked.CompareExchange( ref s_traceSource, source, null ); - } - - return s_traceSource; - } - } - - private static DataGridTraceSource s_traceSource; //null - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Diagnostics/DataGridTraceArg.Generic.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Diagnostics/DataGridTraceArg.Generic.cs deleted file mode 100644 index ffff83e2..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Diagnostics/DataGridTraceArg.Generic.cs +++ /dev/null @@ -1,86 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Globalization; -using System.Windows; - -namespace Xceed.Wpf.DataGrid.Diagnostics -{ - internal class DataGridTraceArg : DataGridTraceArg - { - internal DataGridTraceArg( T value ) - { - m_value = value; - } - - protected override string FormatOutput( CultureInfo culture ) - { - if( object.ReferenceEquals( m_value, null ) ) - return ""; - - var formattable = m_value as IFormattable; - if( formattable != null ) - return formattable.ToString( null, culture ); - - var valueType = m_value.GetType(); - if( valueType.IsGenericType && ( valueType.GetGenericTypeDefinition() == typeof( Nullable<> ) ) ) - { - valueType = Nullable.GetUnderlyingType( valueType ); - } - - if( valueType.IsEnum ) - return m_value.ToString(); - - if( valueType.IsPrimitive || ( typeof( string ) == valueType ) ) - return string.Format( culture, "{0}", m_value ); - - var hashCode = m_value.GetHashCode(); - var name = default( string ); - - if( m_value is DataGridControl ) - { - var dataGridControl = m_value as DataGridControl; - - name = dataGridControl.GridUniqueName; - - if( string.IsNullOrEmpty( name ) ) - { - name = dataGridControl.Name; - } - } - else if( m_value is FrameworkElement ) - { - var fe = m_value as FrameworkElement; - - name = fe.Name; - } - else if( m_value is FrameworkContentElement ) - { - var fce = m_value as FrameworkContentElement; - - name = fce.Name; - } - - if( !string.IsNullOrEmpty( name ) ) - return string.Format( culture, "('{2}' -> {0}, <{1}>)", hashCode, valueType, name ); - - return string.Format( culture, "({0}, <{1}>)", hashCode, valueType ); - } - - private readonly T m_value; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Diagnostics/DataGridTraceArg.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Diagnostics/DataGridTraceArg.cs deleted file mode 100644 index 328b0853..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Diagnostics/DataGridTraceArg.cs +++ /dev/null @@ -1,34 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Globalization; - -namespace Xceed.Wpf.DataGrid.Diagnostics -{ - internal abstract class DataGridTraceArg - { - protected abstract string FormatOutput( CultureInfo culture ); - - public sealed override string ToString() - { - var output = this.FormatOutput( CultureInfo.InvariantCulture ); - if( string.IsNullOrEmpty( output ) ) - return string.Empty; - - return output; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Diagnostics/DataGridTraceArgs.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Diagnostics/DataGridTraceArgs.cs deleted file mode 100644 index 0297d39f..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Diagnostics/DataGridTraceArgs.cs +++ /dev/null @@ -1,145 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Globalization; - -namespace Xceed.Wpf.DataGrid.Diagnostics -{ - internal static class DataGridTraceArgs - { - internal static DataGridTraceArg Action( T value ) - { - return new TraceArg( "Action", value ); - } - - internal static DataGridTraceArg DataSource( T value ) - { - return new TraceArg( "DataSource", value ); - } - - internal static DataGridTraceArg DataGridControl( T value ) - { - return new TraceArg( "DataGridControl", value ); - } - - internal static DataGridTraceArg Generator( T value ) - { - return new TraceArg( "ItemContainerGenerator", value ); - } - - internal static DataGridTraceArg Count( T value ) - { - return new TraceArg( "Count", value ); - } - - internal static DataGridTraceArg ItemCount( T value ) - { - return new TraceArg( "ItemCount", value ); - } - - internal static DataGridTraceArg Container( T value ) - { - return new TraceArg( "Container", value ); - } - - internal static DataGridTraceArg Group( T value ) - { - return new TraceArg( "Group", value ); - } - - internal static DataGridTraceArg Index( T value ) - { - return new TraceArg( "Index", value ); - } - - internal static DataGridTraceArg GeneratorIndex( T value ) - { - return new TraceArg( "GIndex", value ); - } - - internal static DataGridTraceArg From( T value ) - { - return new TraceArg( "From", value ); - } - - internal static DataGridTraceArg To( T value ) - { - return new TraceArg( "To", value ); - } - - internal static DataGridTraceArg Item( T value ) - { - return new TraceArg( "Item", value ); - } - - internal static DataGridTraceArg Node( T value ) - { - return new TraceArg( "Node", value ); - } - - internal static DataGridTraceArg NextNode( T value ) - { - return new TraceArg( "NNode", value ); - } - - internal static DataGridTraceArg PreviousNode( T value ) - { - return new TraceArg( "PNode", value ); - } - - internal static DataGridTraceArg LastNode( T value ) - { - return new TraceArg( "LNode", value ); - } - - internal static DataGridTraceArg Value( T value ) - { - return new TraceArg( "Value", value ); - } - - #region TraceArg Private Class - - private sealed class TraceArg : DataGridTraceArg - { - internal TraceArg( string label, T value ) - : base( value ) - { - m_label = label; - } - - protected sealed override string FormatOutput( CultureInfo culture ) - { - var label = m_label; - var value = base.FormatOutput( culture ); - - if( string.IsNullOrEmpty( label ) ) - return value; - - if( value == null ) - return string.Format( "{0}: ", label ); - - if( value.Length == 0 ) - return string.Format( "{0}: ''", label ); - - return string.Format( "{0}: {1}", label, value ); - } - - private readonly string m_label; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Diagnostics/DataGridTraceEventIdEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Diagnostics/DataGridTraceEventIdEnum.cs deleted file mode 100644 index 3fd28a1e..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Diagnostics/DataGridTraceEventIdEnum.cs +++ /dev/null @@ -1,80 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - - -namespace Xceed.Wpf.DataGrid.Diagnostics -{ - internal enum DataGridTraceEventId - { - CustomItemContainerGenerator_ApplyGroupChanges = 0, - CustomItemContainerGenerator_CleanupGenerator, - CustomItemContainerGenerator_CloseDetailsForItem, - CustomItemContainerGenerator_CollapseDetails, - CustomItemContainerGenerator_CollapseGroup, - CustomItemContainerGenerator_ContainerFromIndex, - CustomItemContainerGenerator_ContainerFromItem, - CustomItemContainerGenerator_CreateDetailsForItem, - CustomItemContainerGenerator_CreateDetailsHelper, - CustomItemContainerGenerator_EnsureNodeTreeCreated, - CustomItemContainerGenerator_ExpandDetails, - CustomItemContainerGenerator_ExpandGroup, - CustomItemContainerGenerator_FindIndexForItem, - CustomItemContainerGenerator_GenerateNextLocalContainer, - CustomItemContainerGenerator_GenerateStickyFootersForDetail, - CustomItemContainerGenerator_GenerateStickyHeadersForDetail, - CustomItemContainerGenerator_GenPosArraysRemoveAt, - CustomItemContainerGenerator_GetGroupFromItem, - CustomItemContainerGenerator_GetGroupIndex, - CustomItemContainerGenerator_GetRealizedContainerForIndex, - CustomItemContainerGenerator_GetRealizedIndexForContainer, - CustomItemContainerGenerator_HandleDetailReset, - CustomItemContainerGenerator_HandleGlobalItemsReset, - CustomItemContainerGenerator_HandleHeadersFootersAddition, - CustomItemContainerGenerator_HandleHeadersFootersRemoveMoveReplace, - CustomItemContainerGenerator_HandleItemAddition, - CustomItemContainerGenerator_HandleItemReset, - CustomItemContainerGenerator_HandleSameLevelGroupAddition, - CustomItemContainerGenerator_HandleSameLevelGroupMove, - CustomItemContainerGenerator_HandleSameLevelGroupRemove, - CustomItemContainerGenerator_HandleSameLevelGroupReset, - CustomItemContainerGenerator_IItemContainerGenerator_GenerateNext, - CustomItemContainerGenerator_IItemContainerGenerator_Remove, - CustomItemContainerGenerator_IndexFromItem, - CustomItemContainerGenerator_IsGroupExpanded, - CustomItemContainerGenerator_ItemFromContainer, - CustomItemContainerGenerator_ItemFromIndex, - CustomItemContainerGenerator_MoveGeneratorBackward, - CustomItemContainerGenerator_MoveGeneratorForward, - CustomItemContainerGenerator_OnDetailConfigurationsChanged, - CustomItemContainerGenerator_OnDetailGeneratorContentChanged, - CustomItemContainerGenerator_OnGeneratorNodeExpansionStateChanged, - CustomItemContainerGenerator_OnGeneratorNodeGroupsCollectionChanged, - CustomItemContainerGenerator_OnGeneratorNodeHeadersFootersCollectionChanged, - CustomItemContainerGenerator_OnGeneratorNodeItemsCollectionChanged, - CustomItemContainerGenerator_OnGroupGeneratorNodeIsExpandedChanged, - CustomItemContainerGenerator_OnGroupGeneratorNodeIsExpandedChanging, - CustomItemContainerGenerator_OnGroupsChanged, - CustomItemContainerGenerator_OnItemsChanged, - CustomItemContainerGenerator_ProcessGroupRemoval, - CustomItemContainerGenerator_RemapFloatingDetails, - CustomItemContainerGenerator_SetupInitialItemsNodes, - CustomItemContainerGenerator_ToggleDetails, - CustomItemContainerGenerator_ToggleGroupExpansion, - CustomItemContainerGenerator_UpdateFooters, - CustomItemContainerGenerator_UpdateGenPosToIndexList, - CustomItemContainerGenerator_UpdateHeaders, - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Diagnostics/DataGridTraceMessages.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Diagnostics/DataGridTraceMessages.cs deleted file mode 100644 index a1d04d9b..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Diagnostics/DataGridTraceMessages.cs +++ /dev/null @@ -1,71 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Xceed.Wpf.DataGrid.Diagnostics -{ - internal static class DataGridTraceMessages - { - internal const string CannotCollapseDetail = "Cannot collapse the detail."; - internal const string CannotExpandDetail = "Cannot expand the detail."; - internal const string CannotProcessOnReset = "Cannot process while resetting."; - internal const string CannotRemapDetails = "Cannot remap details when deferred."; - internal const string CollapsedItemAdded = "Item(s) added under a collapsed node."; - internal const string CollapsingDetail = "Collapsing a detail."; - internal const string ContainerAdded = "The container was added."; - internal const string ContainerFound = "The container was found."; - internal const string ContainerGenerated = "A container was generated."; - internal const string ContainerIsInDetail = "The container is located in a detail."; - internal const string ContainerNotFound = "The container was not found."; - internal const string ContainerRemoved = "The container was removed."; - internal const string DetailAlreadyCollapsed = "The detail is already collapsed."; - internal const string DetailAlreadyExpanded = "The detail is already expanded."; - internal const string DetailExpanded = "The detail was expanded."; - internal const string DetailCollapsed = "The detail was collapsed."; - internal const string DetailExpected = "Detail expected."; - internal const string DetailIsFloating = "The detail is floating."; - internal const string DetailNodeAdded = "Detail node(s) added."; - internal const string DetailNodeNotFound = "The detail node was not found."; - internal const string DetailNotFound = "The detail was not found."; - internal const string DetailNotSupported = "Details are not supported."; - internal const string EmptyTree = "There is no node."; - internal const string GroupFound = "The group was found."; - internal const string GroupNodeAdded = "Group node(s) added."; - internal const string GroupNodeRemoved = "Group node(s) removed."; - internal const string GroupNotFound = "The group was not found."; - internal const string InhibiterAlreadySet = "An inhibiter is already set."; - internal const string IndexFound = "The index was found."; - internal const string IndexUpdated = "The index was updated."; - internal const string ItemAdded = "Item(s) added."; - internal const string ItemFound = "The item was found."; - internal const string ItemNotBelongingToGenerator = "The item does not belong to the generator."; - internal const string ItemNotBelongingToNode = "The item does not belong to the node."; - internal const string ItemNotFound = "The item was not found."; - internal const string ItemNotFoundOrCollapsed = "The item was not found or is under a collapsed node."; - internal const string NewStartNode = "New start node."; - internal const string NewTreeCreated = "New tree node created."; - internal const string NodeFound = "The node was found."; - internal const string NodeIsCollapsed = "The node is collapsed."; - internal const string NodeIsNotTheCurrentNode = "Node is not the current one."; - internal const string RemapDetailNodes = "Remap details nodes."; - internal const string RemapZombieDetail = "Master item not found for detail."; - internal const string UnexpectedNode = "Unexpected node."; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Diagnostics/DataGridTraceSource.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Diagnostics/DataGridTraceSource.cs deleted file mode 100644 index 647f3c32..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Diagnostics/DataGridTraceSource.cs +++ /dev/null @@ -1,201 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading; - -namespace Xceed.Wpf.DataGrid.Diagnostics -{ - internal class DataGridTraceSource - { - #region Static Fields - - internal readonly IDisposable NoTrace = new EmptyDisposable(); - - #endregion - - internal DataGridTraceSource( TraceSource traceSource ) - { - if( traceSource == null ) - throw new ArgumentNullException( "traceSource" ); - - m_traceSource = traceSource; - } - - internal bool ShouldTrace( TraceEventType eventType ) - { -#if TRACE - var listeners = m_traceSource.Listeners; - if( ( listeners == null ) || ( listeners.Count <= 0 ) ) - return false; - - var sourceSwitch = m_traceSource.Switch; - - return ( sourceSwitch != null ) - && ( sourceSwitch.ShouldTrace( eventType ) ); -#else - return false; -#endif - } - - internal bool ShouldTraceBlock() - { - return ( this.ShouldTrace( TraceEventType.Start ) ) - || ( this.ShouldTrace( TraceEventType.Stop ) ); - } - - internal IDisposable TraceBlock( DataGridTraceEventId eventId, string message, IEnumerable args ) - { - if( this.ShouldTrace( TraceEventType.Start ) ) - { - this.TraceEventCore( TraceEventType.Start, eventId, message, args ); - } - - if( this.ShouldTrace( TraceEventType.Stop ) ) - return new TraceBlockEndDisposable( this, eventId, message, args ); - - return this.NoTrace; - } - - [Conditional( "TRACE" )] - internal void TraceEvent( TraceEventType eventType, DataGridTraceEventId eventId, string message, IEnumerable args ) - { - if( !this.ShouldTrace( eventType ) ) - return; - - this.TraceEventCore( eventType, eventId, message, args ); - } - - private void TraceEventCore( TraceEventType eventType, DataGridTraceEventId eventId, string message, IEnumerable args ) - { - var format = DataGridTraceSource.Format( args ); - - if( string.IsNullOrEmpty( message ) ) - { - if( string.IsNullOrEmpty( format ) ) - { - DataGridTraceSource.TraceEvent( m_traceSource, eventType, ( int )eventId, null ); - } - else - { - DataGridTraceSource.TraceEvent( m_traceSource, eventType, ( int )eventId, format ); - } - } - else - { - if( string.IsNullOrEmpty( format ) ) - { - DataGridTraceSource.TraceEvent( m_traceSource, eventType, ( int )eventId, message ); - } - else - { - DataGridTraceSource.TraceEvent( m_traceSource, eventType, ( int )eventId, message + " | " + format ); - } - } - } - - private static void TraceEvent( TraceSource source, TraceEventType eventType, int eventId, string message ) - { - if( string.IsNullOrEmpty( message ) ) - { - source.TraceEvent( eventType, eventId ); - } - else - { - source.TraceEvent( eventType, eventId, message ); - } - - if( Debugger.IsAttached ) - { - source.Flush(); - } - } - - private static string Format( IEnumerable args ) - { - if( ( args == null ) || !args.Any() ) - return null; - - var sb = new StringBuilder( 128 ); - - foreach( var arg in args ) - { - var value = arg.ToString(); - - if( string.IsNullOrEmpty( value ) ) - continue; - - if( sb.Length > 0 ) - { - sb.Append( "; " ); - } - - sb.Append( value ); - } - - return sb.ToString(); - } - - private readonly TraceSource m_traceSource; - - #region TraceBlockEndDisposable Private Class - - private sealed class TraceBlockEndDisposable : IDisposable - { - internal TraceBlockEndDisposable( DataGridTraceSource owner, DataGridTraceEventId eventId, string message, IEnumerable args ) - { - if( owner == null ) - throw new ArgumentNullException( "owner" ); - - m_owner = owner; - m_eventId = eventId; - m_message = message; - m_args = args; - } - - void IDisposable.Dispose() - { - var owner = Interlocked.Exchange( ref m_owner, null ); - if( owner == null ) - return; - - owner.TraceEventCore( TraceEventType.Stop, m_eventId, m_message, m_args ); - } - - private DataGridTraceSource m_owner; - private readonly DataGridTraceEventId m_eventId; - private readonly string m_message; - private readonly IEnumerable m_args; - } - - #endregion - - #region EmptyDisposable Private Class - - private sealed class EmptyDisposable : IDisposable - { - void IDisposable.Dispose() - { - } - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DropMarkAdorner.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DropMarkAdorner.cs deleted file mode 100644 index a4707270..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/DropMarkAdorner.cs +++ /dev/null @@ -1,198 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Diagnostics; -using System.Windows; -using System.Windows.Documents; -using System.Windows.Media; -using Xceed.Wpf.DataGrid.Views; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class DropMarkAdorner : Adorner - { - // A null value for the pen parameter means that the adorner will not show any visual cue. - internal DropMarkAdorner( UIElement adornedElement, Pen pen, DropMarkOrientation orientation ) - : base( adornedElement ) - { - Debug.Assert( orientation != DropMarkOrientation.Default, "A DropMarkAdorner without a specific orientation should virtually never happen. The only known way to do this would be to have a grid element not hosted in a DataGridControl. The DropMarkAdorner should react well to this nonetheless." ); - m_pen = pen; - m_orientation = orientation; - m_render = ( pen != null ); - - this.IsHitTestVisible = false; - } - - #region HorizontalPosition Property - - public static readonly DependencyProperty HorizontalPositionProperty = DependencyProperty.Register( - "HorizontalPosition", - typeof( double ), - typeof( DropMarkAdorner ), - new FrameworkPropertyMetadata( 0d, new PropertyChangedCallback( DropMarkAdorner.OnHorizontalPositionChanged ) ) ); - - public double HorizontalPosition - { - get - { - return ( double )this.GetValue( DropMarkAdorner.HorizontalPositionProperty ); - } - set - { - this.SetValue( DropMarkAdorner.HorizontalPositionProperty, value ); - } - } - - private static void OnHorizontalPositionChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var self = sender as DropMarkAdorner; - if( self == null ) - return; - - self.Update(); - } - - #endregion - - #region Alignment Property - - internal DropMarkAlignment Alignment - { - get - { - return m_alignment; - } - set - { - if( value == m_alignment ) - return; - - m_alignment = value; - - this.Update(); - } - } - - private DropMarkAlignment m_alignment = DropMarkAlignment.ExplicitPosition; - - #endregion - - #region AdornerLayout Private Property - - private AdornerLayer AdornerLayer - { - get - { - return ( this.Parent as AdornerLayer ); - } - } - - #endregion - - protected override void OnRender( DrawingContext drawingContext ) - { - base.OnRender( drawingContext ); - - if( !m_render || ( m_pen == null ) ) - return; - - var renderSize = this.AdornedElement.RenderSize; - - Point startPoint = new Point( this.HorizontalPosition, 0d ); - Point endPoint; - - switch( m_orientation ) - { - case DropMarkOrientation.Default: - case DropMarkOrientation.Vertical: - { - if( m_alignment == DropMarkAlignment.Far ) - { - startPoint.X += renderSize.Width; - } - - endPoint = new Point( startPoint.X, renderSize.Height ); - } - break; - case DropMarkOrientation.Horizontal: - { - if( m_alignment == DropMarkAlignment.Far ) - { - startPoint.Y += renderSize.Height; - } - - endPoint = new Point( renderSize.Width, startPoint.Y ); - } - break; - default: - return; - } - - drawingContext.DrawLine( m_pen, startPoint, endPoint ); - } - - internal void UpdateAlignment( RelativePoint mousePosition ) - { - var relativePosition = mousePosition.GetPoint( this.AdornedElement ); - var elementSize = this.AdornedElement.RenderSize; - - if( m_orientation == DropMarkOrientation.Horizontal ) - { - this.Alignment = ( relativePosition.Y < elementSize.Height / 2d ) ? DropMarkAlignment.Near : DropMarkAlignment.Far; - } - else - { - this.Alignment = ( relativePosition.X < elementSize.Width / 2d ) ? DropMarkAlignment.Near : DropMarkAlignment.Far; - } - } - - private void Update() - { - if( !m_render ) - return; - - if( !this.InvalidateAdornerLayer() ) - return; - - m_render = false; - this.LayoutUpdated += new EventHandler( this.OnLayoutUpdated ); - } - - private bool InvalidateAdornerLayer() - { - var adornerLayer = this.AdornerLayer; - if( adornerLayer == null ) - return false; - - adornerLayer.Update( this.AdornedElement ); - return true; - } - - private void OnLayoutUpdated( object sender, EventArgs e ) - { - m_render = true; - - this.LayoutUpdated -= new EventHandler( this.OnLayoutUpdated ); - this.InvalidateVisual(); - this.InvalidateAdornerLayer(); - } - - private readonly DropMarkOrientation m_orientation; - private readonly Pen m_pen; - private bool m_render; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Export/(Clipboard)/CF_HtmlStream.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Export/(Clipboard)/CF_HtmlStream.cs deleted file mode 100644 index 13a6e738..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Export/(Clipboard)/CF_HtmlStream.cs +++ /dev/null @@ -1,201 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.IO; -using System.Diagnostics; -using System.Globalization; - -namespace Xceed.Wpf.DataGrid.Export -{ - // Class used to format data into the CF_HTML Clipbard Format - // http://msdn.microsoft.com/en-us/library/aa767917(VS.85).aspx - internal sealed class CF_HtmlStream : Stream - { - public CF_HtmlStream( Stream innerStream ) - { - if( innerStream == null ) - throw new ArgumentNullException( "innerStream" ); - - if( innerStream.CanWrite == false ) - throw new InvalidOperationException( "An attempt was made to use a non-writable stream." ); - - if( innerStream.CanSeek == false ) - throw new InvalidOperationException( "An attempt was made to use a non-seekable stream." ); - - m_innerStream = innerStream; - - StringBuilder headerStringBuilder = new StringBuilder(); - headerStringBuilder.Append( "Version:1.0" ); - headerStringBuilder.Append( Environment.NewLine ); - headerStringBuilder.Append( "StartHTML:-1" ); // This is optional according to MSDN documentation - headerStringBuilder.Append( Environment.NewLine ); - headerStringBuilder.Append( "EndHTML:-1" ); // This is optional according to MSDN documentation - headerStringBuilder.Append( Environment.NewLine ); - headerStringBuilder.Append( "StartFragment:0000000109" ); // Always 109 bytes from start of Version to the end of tag - headerStringBuilder.Append( Environment.NewLine ); - - // Get the offset of the EndFragment: tag to be able to modify the 10 digits - m_endFragmentOffset = headerStringBuilder.ToString().Length; - - Debug.Assert( m_endFragmentOffset == 65 ); - - headerStringBuilder.Append( "EndFragment:0000000000" ); // We write 0000000000 and we will update this field when the Stream is closed - headerStringBuilder.Append( Environment.NewLine ); - headerStringBuilder.Append( "" ); - - string headerString = headerStringBuilder.ToString(); - - byte[] tempBuffer = Encoding.UTF8.GetBytes( headerString ); - - m_headerBytesLength = headerStringBuilder.Length; - - Debug.Assert( m_headerBytesLength == tempBuffer.Length ); - Debug.Assert( tempBuffer.Length == 109 ); - - m_innerStream.Write( tempBuffer, 0, m_headerBytesLength ); - m_HtmlContentByteCount = 0; - } - - public override bool CanRead - { - get - { - return false; - } - } - - public override bool CanSeek - { - get - { - return false; - } - } - - public override bool CanWrite - { - get - { - return true; - } - } - - public override long Length - { - get - { - return m_headerBytesLength + m_HtmlContentByteCount + s_footerBytes.Length; - } - } - - public override long Position - { - get - { - throw new NotSupportedException(); - } - set - { - throw new NotSupportedException(); - } - } - - public override void Close() - { - // Already closed, nothing to do - if( m_closed ) - return; - - // Update the value of EndFragment field in the header - string endFragmentOffset = ( m_HtmlContentByteCount + m_headerBytesLength ).ToString( "0000000000", CultureInfo.InvariantCulture ); - - m_innerStream.Seek( m_endFragmentOffset, SeekOrigin.Begin ); - - byte[] tempBuffer = Encoding.UTF8.GetBytes( "EndFragment:" + endFragmentOffset ); - Debug.Assert( tempBuffer.Length == 22 ); - m_innerStream.Write( tempBuffer, 0, tempBuffer.Length ); - - // Append the final end line and EndFragment tag - m_innerStream.Seek( 0, SeekOrigin.End ); - m_innerStream.Write( s_footerBytes, 0, s_footerBytes.Length ); - m_innerStream.Flush(); - - m_closed = true; - } - - protected override void Dispose( bool disposing ) - { - this.Close(); - } - - public override void Flush() - { - m_innerStream.Flush(); - } - - public override int Read( byte[] buffer, int offset, int count ) - { - throw new NotSupportedException(); - } - - public override int ReadByte() - { - throw new NotSupportedException(); - } - - public override long Seek( long offset, SeekOrigin origin ) - { - throw new NotSupportedException(); - } - - public override void SetLength( long value ) - { - throw new NotSupportedException(); - } - - public override void WriteByte( byte value ) - { - this.CheckIfClosed(); - m_HtmlContentByteCount++; - m_innerStream.WriteByte( value ); - } - - public override void Write( byte[] buffer, int offset, int count ) - { - this.CheckIfClosed(); - m_HtmlContentByteCount += count; - m_innerStream.Write( buffer, offset, count ); - } - - private void CheckIfClosed() - { - if( m_closed ) - throw new InvalidOperationException( "An attempt was made to access a closed stream." ); - } - - private bool m_closed; // = false; - private int m_endFragmentOffset; // = 0; - private int m_headerBytesLength; // = 0; - private long m_HtmlContentByteCount; // = 0; - private Stream m_innerStream; // = null; - - private static byte[] s_footerBytes = Encoding.UTF8.GetBytes( Environment.NewLine + "" ); - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Export/(Clipboard)/ClipboardExporterBase.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Export/(Clipboard)/ClipboardExporterBase.cs deleted file mode 100644 index 0603d1b0..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Export/(Clipboard)/ClipboardExporterBase.cs +++ /dev/null @@ -1,751 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Diagnostics; -using System.Windows; - -namespace Xceed.Wpf.DataGrid.Export -{ - public abstract class ClipboardExporterBase - { - protected ClipboardExporterBase() - { - this.UseFieldNamesInHeader = false; - } - - #region IncludeColumnHeaders Property - - public bool IncludeColumnHeaders - { - get; - set; - } - - #endregion - - #region UseFieldNamesInHeader Property - - public bool UseFieldNamesInHeader - { - get; - set; - } - - #endregion - - #region ClipboardData Property - - protected abstract object ClipboardData - { - get; - } - - #endregion - - protected virtual void Indent() - { - } - - protected virtual void Unindent() - { - } - - protected virtual void StartExporter( string dataFormat ) - { - } - - protected virtual void EndExporter( string dataFormat ) - { - } - - protected virtual void ResetExporter() - { - } - - protected virtual void StartHeader( DataGridContext dataGridContext ) - { - } - - protected virtual void StartHeaderField( DataGridContext dataGridContext, Column column ) - { - } - - protected virtual void EndHeaderField( DataGridContext dataGridContext, Column column ) - { - } - - protected virtual void EndHeader( DataGridContext dataGridContext ) - { - } - - protected virtual void StartDataItem( DataGridContext dataGridContext, object dataItem ) - { - } - - protected virtual void StartDataItemField( DataGridContext dataGridContext, Column column, object fieldValue ) - { - } - - protected virtual void EndDataItemField( DataGridContext dataGridContext, Column column, object fieldValue ) - { - } - - protected virtual void EndDataItem( DataGridContext dataGridContext, object dataItem ) - { - } - - internal static IDataObject CreateDataObject( DataGridControl dataGridControl ) - { - if( dataGridControl == null ) - throw new ArgumentNullException( "dataGridControl" ); - - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( dataGridControl ); - - if( dataGridContext == null ) - return null; - - XceedDataObject dataObject = null; - bool containsData = false; - - try - { - dataGridControl.ShowWaitCursor(); - - Dictionary exporters = dataGridControl.ClipboardExporters; - - foreach( KeyValuePair keyPair in exporters ) - { - if( keyPair.Value == null ) - throw new DataGridException( "ClipboardExporterBase cannot be null." ); - - keyPair.Value.StartExporter( keyPair.Key ); - } - - using( ManualExporter exporter = new ManualExporter( exporters.Values as IEnumerable ) ) - { - exporter.Export( dataGridContext ); - } - - foreach( KeyValuePair keyPair in exporters ) - { - keyPair.Value.EndExporter( keyPair.Key ); - - if( dataObject == null ) - { - dataObject = new XceedDataObject(); - } - - object clipboardExporterValue = keyPair.Value.ClipboardData; - - // For other formats, we directly copy the content to the IDataObject - if( clipboardExporterValue != null ) - { - ( ( IDataObject )dataObject ).SetData( keyPair.Key, clipboardExporterValue ); - containsData = true; - } - - keyPair.Value.ResetExporter(); - } - } - finally - { - dataGridControl.HideWaitCursor(); - } - - // Only return dataObject some data was copied - if( containsData ) - return dataObject as IDataObject; - - return null; - } - - private class ManualExporter : IDisposable - { - public ManualExporter( IEnumerable clipboardExporters ) - { - m_columnToBindingPathExtractor = new Dictionary(); - m_clipboardExporters = new List( clipboardExporters ); - m_visitedDetailExportedVisiblePositions = new Dictionary(); - m_visitedDetailVisibleColumnsCache = new Dictionary(); - } - - #region HasItems Property - - public bool HasItems - { - get; - set; - } - - #endregion - - internal void Export( DataGridContext dataGridContext ) - { - if( dataGridContext == null ) - return; - - // Get the detail level for the current DataGridContext - int detailLevel = dataGridContext.DetailLevel; - - // Update indentation of ClipboardExporters for this detail level - this.UpdateExporterIndentation( detailLevel ); - - // Get master indexes that have mapped expanded details - List indexesToMasterItemList = dataGridContext.CustomItemContainerGenerator.GetMasterIndexesWithExpandedDetails(); - - // Get the index of the next detail to export in case - // it is expanded before the first selected index of the - // current dataGridContext - int nextDetailIndex = ( indexesToMasterItemList.Count > 0 ) ? indexesToMasterItemList[ 0 ] : -1; - - // Get informations on columns, visible positions and selected item indexes - // for this dataGridContext - int[] exportedVisiblePositions = this.GetVisiblePositionsForContext( dataGridContext ); - ColumnBase[] columnsByVisiblePosition = this.GetVisibleColumnsArrayForContext( dataGridContext ); - SelectionRange[] selectedItemsRanges = this.GetSelectedItemsStoreForDataGridContext( dataGridContext ); - - Debug.Assert( exportedVisiblePositions != null ); - Debug.Assert( columnsByVisiblePosition != null ); - Debug.Assert( selectedItemsRanges != null ); - - int selectedItemsRangesCount = selectedItemsRanges.Length; - - // Ensure to flag the exporter has items - this.HasItems = this.HasItems || ( selectedItemsRangesCount > 0 ); - - for( int i = 0; i < selectedItemsRangesCount; i++ ) - { - // For the first level, ensure to export the headers - // before anything else - if( detailLevel == 0 ) - { - this.ExportHeaders( dataGridContext, detailLevel, exportedVisiblePositions, columnsByVisiblePosition ); - } - - SelectionRange range = selectedItemsRanges[ i ]; - - int startIndex = range.StartIndex; - int endIndex = range.EndIndex; - - // If range is inverted - if( startIndex > endIndex ) - { - startIndex = range.EndIndex; - endIndex = range.StartIndex; - } - - // For each index in the range - for( int itemIndex = startIndex; itemIndex <= endIndex; itemIndex++ ) - { - // Export details that are before the itemIndex - while( ( nextDetailIndex != -1 ) && ( itemIndex > nextDetailIndex ) ) - { - this.ExportDetailForMasterIndex( dataGridContext, detailLevel, nextDetailIndex ); - - // Remove it since the detail is processed - indexesToMasterItemList.Remove( nextDetailIndex ); - - nextDetailIndex = ( indexesToMasterItemList.Count > 0 ) ? indexesToMasterItemList[ 0 ] : -1; - } - - // Ensure to re-export the headers if a detail was previously exported - this.ExportHeaders( dataGridContext, detailLevel, exportedVisiblePositions, columnsByVisiblePosition ); - - object exportedItem = dataGridContext.Items.GetItemAt( itemIndex ); - - this.ExportDataItem( dataGridContext, itemIndex, exportedItem, detailLevel, exportedVisiblePositions, columnsByVisiblePosition ); - } - } - - nextDetailIndex = ( indexesToMasterItemList.Count > 0 ) ? indexesToMasterItemList[ 0 ] : -1; - - // Export all remaining details since none are before the context's - // selected index ranges - while( nextDetailIndex != -1 ) - { - this.ExportDetailForMasterIndex( dataGridContext, detailLevel, nextDetailIndex ); - - // Remove it since the detail is processed - indexesToMasterItemList.Remove( nextDetailIndex ); - - nextDetailIndex = ( indexesToMasterItemList.Count > 0 ) ? indexesToMasterItemList[ 0 ] : -1; - } - } - - private void ExportDataItemCore( DataGridContext dataGridContext, ClipboardExporterBase clipboardExporter, int itemIndex, object item, - int[] exportedVisiblePositions, ColumnBase[] columnsByVisiblePosition ) - { - var dataGridCollectionViewBase = dataGridContext.ItemsSourceCollection as DataGridCollectionViewBase; - - clipboardExporter.StartDataItem( dataGridContext, item ); - - // Ensure the count does not exceeds the columns count - var exportedVisiblePositionsCount = exportedVisiblePositions.Length; - exportedVisiblePositionsCount = Math.Min( exportedVisiblePositionsCount, columnsByVisiblePosition.Length ); - - var intersectedIndexes = this.GetIntersectedRangesForIndex( dataGridContext, itemIndex, exportedVisiblePositions, exportedVisiblePositionsCount ); - - for( int i = 0; i < exportedVisiblePositionsCount; i++ ) - { - var fieldValue = default( object ); - var column = default( Column ); - var visiblePosition = exportedVisiblePositions[ i ]; - - // Export null if not intersected by a SelectionRange - if( intersectedIndexes.Contains( visiblePosition ) ) - { - // Only export visible data column - column = columnsByVisiblePosition[ visiblePosition ] as Column; - - if( column == null ) - continue; - - // Use DataGridCollectionView directly since the DataGridItemProperty uses PropertyDescriptor which increase the read of the field value - var dataGridItemProperty = default( DataGridItemPropertyBase ); - - // Try to get a DataGridItemProperty matching the column FieldName and get the value from it - if( dataGridCollectionViewBase != null ) - { - dataGridItemProperty = ItemsSourceHelper.GetItemPropertyFromProperty( dataGridCollectionViewBase.ItemProperties, column.FieldName ); - - if( dataGridItemProperty != null ) - { - fieldValue = ItemsSourceHelper.GetValueFromItemProperty( dataGridItemProperty, item ); - } - } - - // If none was found, create a BindingPathValueExtractor from this column - if( ( dataGridCollectionViewBase == null ) || ( dataGridItemProperty == null ) ) - { - // We don't have a DataGridCollectionView, use a BindingPathValueExtractor to create a binding to help us get the value for the Column in the data item - var extractorForRead = default( BindingPathValueExtractor ); - - if( m_columnToBindingPathExtractor.TryGetValue( column, out extractorForRead ) == false ) - { - extractorForRead = dataGridContext.GetBindingPathExtractorForColumn( column, item ); - m_columnToBindingPathExtractor.Add( column, extractorForRead ); - } - - fieldValue = extractorForRead.GetValueFromItem( item ); - } - } - - if( fieldValue != null ) - { - //Verify if the value should be converted to the displayed value for exporting. - var foreignKeyConfiguration = column.ForeignKeyConfiguration; - if( foreignKeyConfiguration != null && foreignKeyConfiguration.UseDisplayedValueWhenExporting ) - { - fieldValue = foreignKeyConfiguration.GetDisplayMemberValue( fieldValue ); - } - else - { - var valueConverter = column.DisplayedValueConverter; - if( valueConverter != null ) - { - fieldValue = valueConverter.Convert( fieldValue, typeof( object ), column.DisplayedValueConverterParameter, - column.GetCulture( column.DisplayedValueConverterCulture ) ); - } - else - { - var valueFormat = column.CellContentStringFormat; - if( !string.IsNullOrEmpty( valueFormat ) ) - { - fieldValue = string.Format( column.GetCulture(), valueFormat, fieldValue ); - } - } - } - } - - clipboardExporter.StartDataItemField( dataGridContext, column, fieldValue ); - clipboardExporter.EndDataItemField( dataGridContext, column, fieldValue ); - } - - clipboardExporter.EndDataItem( dataGridContext, item ); - } - - private void ExportHeadersCore( DataGridContext dataGridContext, ClipboardExporterBase clipboardExporter, int[] exportedVisiblePositions, - ColumnBase[] columnsByVisiblePosition ) - { - clipboardExporter.StartHeader( dataGridContext ); - - // Ensure the count does not exceeds the columns count - int exportedVisiblePositionsCount = exportedVisiblePositions.Length; - exportedVisiblePositionsCount = Math.Min( exportedVisiblePositionsCount, columnsByVisiblePosition.Length ); - - for( int i = 0; i < exportedVisiblePositionsCount; i++ ) - { - int visiblePosition = exportedVisiblePositions[ i ]; - - // Only export visible data column - Column column = columnsByVisiblePosition[ visiblePosition ] as Column; - - if( column == null ) - continue; - - clipboardExporter.StartHeaderField( dataGridContext, column ); - clipboardExporter.EndHeaderField( dataGridContext, column ); - } - - clipboardExporter.EndHeader( dataGridContext ); - } - - private HashSet GetIntersectedRangesForIndex( DataGridContext dataGridContext, int itemIndex, int[] exportedVisiblePositions, int correctedExportedVisiblePositionsCount ) - { - HashSet intersectedIndexes = null; - - if( correctedExportedVisiblePositionsCount == 0 ) - return intersectedIndexes; - - SelectionItemRangeCollection selectedRanges = dataGridContext.SelectedItemRanges as SelectionItemRangeCollection; - - if( selectedRanges.Contains( itemIndex ) ) - { - intersectedIndexes = new HashSet( exportedVisiblePositions ); - } - else - { - intersectedIndexes = new HashSet(); - - SelectionCellRange columnsRange = new SelectionCellRange( itemIndex, exportedVisiblePositions[ 0 ], itemIndex, - exportedVisiblePositions[ correctedExportedVisiblePositionsCount - 1 ] ); - - IEnumerable intersectedRanges = dataGridContext.SelectedCellsStore.GetIntersectedColumnRanges( columnsRange ); - - foreach( SelectionRange range in intersectedRanges ) - { - int startIndex = range.StartIndex; - int endIndex = range.EndIndex; - - if( startIndex > endIndex ) - { - startIndex = range.EndIndex; - endIndex = range.StartIndex; - } - - for( int i = startIndex; i <= endIndex; i++ ) - { - if( !intersectedIndexes.Contains( i ) ) - { - intersectedIndexes.Add( i ); - } - } - } - } - - return intersectedIndexes; - } - - private void GetAllVisibleColumnsVisiblePosition( DataGridContext dataGridContext, ref HashSet exportedColumnPositions ) - { - if( exportedColumnPositions == null ) - { - exportedColumnPositions = new HashSet(); - } - - if( dataGridContext == null ) - return; - - ReadOnlyObservableCollection visibleColumns = dataGridContext.VisibleColumns; - - int visibleColumnsCount = visibleColumns.Count; - - for( int i = 0; i < visibleColumnsCount; i++ ) - { - ColumnBase column = dataGridContext.VisibleColumns[ i ]; - - if( column == null ) - continue; - - exportedColumnPositions.Add( column.VisiblePosition ); - } - } - - private void ExportDataItem( DataGridContext dataGridContext, int itemIndex, object item, int detailLevel, int[] exportedVisiblePositions, - ColumnBase[] columnsByVisiblePosition ) - { - - foreach( ClipboardExporterBase clipboardExporter in m_clipboardExporters ) - { - this.ExportDataItemCore( dataGridContext, clipboardExporter, itemIndex, item, exportedVisiblePositions, columnsByVisiblePosition ); - } - } - - private void ExportHeaders( DataGridContext dataGridContext, int detailLevel, int[] exportedVisiblePositions, ColumnBase[] columnsByVisiblePosition ) - { - // Master level was already exported, only update the lastExportedHeaderDetailLevel - if( ( m_lastExportedHeaderDetailLevel != -1 ) && ( detailLevel == 0 ) ) - { - m_lastExportedHeaderDetailLevel = 0; - return; - } - - // Headers are already exported for this detail level - if( m_lastExportedHeaderDetailLevel == detailLevel ) - return; - - - foreach( ClipboardExporterBase clipboardExporter in m_clipboardExporters ) - { - // We always add the headers for detail levels every time - if( clipboardExporter.IncludeColumnHeaders ) - { - this.ExportHeadersCore( dataGridContext, clipboardExporter, exportedVisiblePositions, columnsByVisiblePosition ); - } - } - - m_lastExportedHeaderDetailLevel = detailLevel; - } - - private void ExportDetailForMasterIndex( DataGridContext dataGridContext, int detailLevel, int masterIndexForDetail ) - { - object item = dataGridContext.Items.GetItemAt( masterIndexForDetail ); - - IEnumerable dataGridContexts = dataGridContext.CustomItemContainerGenerator.GetChildContextsForMasterItem( item ); - - foreach( DataGridContext childContext in dataGridContexts ) - { - this.Export( childContext ); - } - - this.UpdateExporterIndentation( detailLevel ); - } - - private ColumnBase[] GetVisibleColumnsArrayForContext( DataGridContext dataGridContext ) - { - if( dataGridContext == null ) - throw new ArgumentNullException( "sourceContext" ); - - int detailLevel = dataGridContext.DetailLevel; - - if( m_visitedDetailVisibleColumnsCache.ContainsKey( detailLevel ) ) - return m_visitedDetailVisibleColumnsCache[ detailLevel ]; - - int columnsByVisiblePositionCount = dataGridContext.ColumnsByVisiblePosition.Count; - ColumnBase[] columnsByVisiblePosition = new ColumnBase[ columnsByVisiblePositionCount ]; - dataGridContext.ColumnsByVisiblePosition.CopyTo( columnsByVisiblePosition, 0 ); - - m_visitedDetailVisibleColumnsCache.Add( dataGridContext.DetailLevel, columnsByVisiblePosition ); - - return columnsByVisiblePosition; - } - - private int[] GetVisiblePositionsForContext( DataGridContext dataGridContext ) - { - if( dataGridContext == null ) - throw new ArgumentNullException( "dataGridContext" ); - - int detailLevel = dataGridContext.DetailLevel; - - if( m_visitedDetailExportedVisiblePositions.ContainsKey( detailLevel ) ) - return m_visitedDetailExportedVisiblePositions[ detailLevel ]; - - // We must keep a list of VisiblePositions to export - HashSet exportedColumnPositions = new HashSet(); - - DataGridContext rootDataGridContext = dataGridContext.DataGridControl.DataGridContext; - - this.GetVisiblePositionsForContextDetailLevel( rootDataGridContext, detailLevel, exportedColumnPositions ); - - int exportedColumnPositionsCount = exportedColumnPositions.Count; - int[] exportedVisiblePositionsArray = null; - - exportedVisiblePositionsArray = new int[ exportedColumnPositionsCount ]; - exportedColumnPositions.CopyTo( exportedVisiblePositionsArray ); - Array.Sort( exportedVisiblePositionsArray ); - - m_visitedDetailExportedVisiblePositions.Add( detailLevel, exportedVisiblePositionsArray ); - - return exportedVisiblePositionsArray; - } - - // Parse all the expanded details recursively - private void GetVisiblePositionsForContextDetailLevel( DataGridContext dataGridContext, int desiredDetailLevel, HashSet exportedColumnPositions ) - { - int dataGridContextDetailLevel = dataGridContext.DetailLevel; - - // The detail level is too deep, return immediately - if( dataGridContextDetailLevel > desiredDetailLevel ) - return; - - // The desired detail level is reached get the exportedColumnPositions - if( dataGridContextDetailLevel == desiredDetailLevel ) - { - DataGridContext parentDataGridContext = dataGridContext.ParentDataGridContext; - - if( parentDataGridContext == null ) - { - this.GetVisibleColumnsVisiblePositionForDataGridContext( dataGridContext, exportedColumnPositions ); - } - else - { - foreach( DataGridContext childContext in parentDataGridContext.GetChildContexts() ) - { - if( this.GetVisibleColumnsVisiblePositionForDataGridContext( childContext, exportedColumnPositions ) ) - { - // All columns need to be exported, stop parsing child DataGridContexts - break; - } - } - } - } - else - { - // The detail level differs, parse the child contexts recursively - foreach( DataGridContext childContext in dataGridContext.GetChildContexts() ) - { - this.GetVisiblePositionsForContextDetailLevel( childContext, desiredDetailLevel, exportedColumnPositions ); - } - } - } - - private SelectionRange[] GetSelectedItemsStoreForDataGridContext( DataGridContext dataGridContext ) - { - if( dataGridContext == null ) - return null; - - SelectedItemsStorage itemStorage = new SelectedItemsStorage( null ); - - foreach( SelectionRange range in dataGridContext.SelectedItemRanges ) - { - itemStorage.Add( new SelectionRangeWithItems( range, null ) ); - } - - foreach( SelectionCellRange range in dataGridContext.SelectedCellRanges ) - { - SelectionRangeWithItems itemRange = new SelectionRangeWithItems( range.ItemRange, null ); - - if( !itemStorage.Contains( itemRange ) ) - { - itemStorage.Add( itemRange ); - } - } - - SelectionRange[] itemStorageArray = itemStorage.ToSelectionRangeArray(); - Array.Sort( itemStorageArray ); - - return itemStorageArray; - } - - private bool GetVisibleColumnsVisiblePositionForDataGridContext( DataGridContext dataGridContext, HashSet exportedColumnPositions ) - { - if( dataGridContext == null ) - return false; - - if( exportedColumnPositions == null ) - { - exportedColumnPositions = new HashSet(); - } - - // At least 1 row was completely selected, add - // all VisibleColumns' VisiblePosition - if( dataGridContext.SelectedItemRanges.Count > 0 ) - { - this.GetAllVisibleColumnsVisiblePosition( dataGridContext, ref exportedColumnPositions ); - - // Ensure to set the allColumnExported - return true; - } - - foreach( SelectionCellRange range in dataGridContext.SelectedCellRanges ) - { - // If all columns were already exported, no need to - // ensure visible positions in the exportedColumnPositions - SelectionRange columnRange = range.ColumnRange; - - int startIndex = columnRange.StartIndex; - int endIndex = columnRange.EndIndex; - - if( startIndex > endIndex ) - { - startIndex = columnRange.EndIndex; - endIndex = columnRange.StartIndex; - } - - for( int i = startIndex; i <= endIndex; i++ ) - { - if( !exportedColumnPositions.Contains( i ) ) - { - exportedColumnPositions.Add( i ); - } - } - } - - return false; - } - - // Returns if the indentation changed - private bool UpdateExporterIndentation( int detailLevel ) - { - // Indent / Unindent up to the desired detail level - if( m_currentIndentationLevel < detailLevel ) - { - while( m_currentIndentationLevel < detailLevel ) - { - foreach( ClipboardExporterBase clipboardExporter in m_clipboardExporters ) - { - clipboardExporter.Indent(); - } - - Debug.Indent(); - m_currentIndentationLevel++; - } - - return true; - } - else if( m_currentIndentationLevel > detailLevel ) - { - while( m_currentIndentationLevel > detailLevel ) - { - foreach( ClipboardExporterBase clipboardExporter in m_clipboardExporters ) - { - clipboardExporter.Unindent(); - } - - Debug.Unindent(); - m_currentIndentationLevel--; - } - - return true; - } - - return false; - } - - #region IDisposable Members - - public void Dispose() - { - m_clipboardExporters.Clear(); - m_columnToBindingPathExtractor.Clear(); - m_visitedDetailExportedVisiblePositions.Clear(); - m_visitedDetailVisibleColumnsCache.Clear(); - } - - #endregion IDisposable Members - - private Dictionary m_columnToBindingPathExtractor; // = null; - private Dictionary m_visitedDetailExportedVisiblePositions; // = null; - private Dictionary m_visitedDetailVisibleColumnsCache; // = null; - private List m_clipboardExporters; // = null; - private int m_currentIndentationLevel; // = 0; - private int m_lastExportedHeaderDetailLevel = -1; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Export/(Clipboard)/CsvClipboardExporter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Export/(Clipboard)/CsvClipboardExporter.cs deleted file mode 100644 index 608f271e..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Export/(Clipboard)/CsvClipboardExporter.cs +++ /dev/null @@ -1,222 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.IO; -using System.Diagnostics; - -namespace Xceed.Wpf.DataGrid.Export -{ - public class CsvClipboardExporter : ClipboardExporterBase - { - #region PUBLIC CONSTRUCTORS - - public CsvClipboardExporter() - : base() - { - this.IncludeColumnHeaders = true; - this.FormatSettings = new CsvFormatSettings(); - m_indentationString = string.Empty; - m_baseStream = new ToStringMemoryStream(); - } - - #endregion - - #region PUBLIC PROPERTIES - - public CsvFormatSettings FormatSettings - { - get; - private set; - } - - #endregion - - #region PROTECTED OVERRIDES - - protected override object ClipboardData - { - get - { - return m_baseStream; - } - } - - protected override void Indent() - { - char separator = this.FormatSettings.Separator; - m_indentationString += separator; - } - - protected override void Unindent() - { - char separator = this.FormatSettings.Separator; - - if( m_indentationString == null ) - { - Debug.Fail( "Indentation must at least be string.empty when unindenting." ); - m_indentationString = string.Empty; - } - else - { - int separatorLength = 1; - int indentationLength = m_indentationString.Length; - - // If there are less characters in indentationString than in the empty field, just set indentation - // as string.empty - if( indentationLength < separatorLength ) - { - m_indentationString = string.Empty; - } - else - { - m_indentationString = m_indentationString.Substring( 0, indentationLength - separatorLength ); - } - } - } - - protected override void ResetExporter() - { - m_baseStream = new ToStringMemoryStream(); - m_indentationString = string.Empty; - } - - protected override void StartHeader( DataGridContext dataGridContext ) - { - if( string.IsNullOrEmpty( m_indentationString ) == false ) - this.WriteToBaseStream( m_indentationString ); - - // The next StartDataItemField will be considered as first column - m_isFirstColumn = true; - } - - protected override void StartHeaderField( DataGridContext dataGridContext, Column column ) - { - // We always insert the separator before the value except for the first item - if( !m_isFirstColumn ) - { - this.WriteToBaseStream( this.FormatSettings.Separator ); - } - else - { - m_isFirstColumn = false; - } - - object columnHeader = ( ( this.UseFieldNamesInHeader ) || ( column.Title == null ) ) ? column.FieldName : column.Title; - - string fieldValueString = FormatHelper.FormatCsvData( null, columnHeader, this.FormatSettings ); - - this.WriteToBaseStream( fieldValueString ); - } - - protected override void EndHeader( DataGridContext dataGridContext ) - { - this.WriteToBaseStream( this.FormatSettings.NewLine ); - } - - protected override void StartDataItem( DataGridContext dataGridContext, object dataItem ) - { - if( string.IsNullOrEmpty( m_indentationString ) == false ) - this.WriteToBaseStream( m_indentationString ); - - // The next StartDataItemField will be considered as first column - m_isFirstColumn = true; - } - - protected override void StartDataItemField( DataGridContext dataGridContext, Column column, object fieldValue ) - { - // We always insert the separator before the value except for the first item - if( !m_isFirstColumn ) - { - this.WriteToBaseStream( this.FormatSettings.Separator ); - } - else - { - m_isFirstColumn = false; - } - - string fieldValueString = FormatHelper.FormatCsvData( null, fieldValue, this.FormatSettings ); - - this.WriteToBaseStream( fieldValueString ); - } - - protected override void EndDataItem( DataGridContext dataGridContext, object dataItem ) - { - this.WriteToBaseStream( this.FormatSettings.NewLine ); - } - - #endregion - - #region PRIVATE METHODS - - private void WriteToBaseStream( char value ) - { - byte[] tempBuffer = Encoding.Default.GetBytes( new char[] { value } ); - m_baseStream.Write( tempBuffer, 0, tempBuffer.Length ); - } - - private void WriteToBaseStream( string value ) - { - if( string.IsNullOrEmpty( value ) ) - return; - - byte[] tempBuffer = Encoding.Default.GetBytes( value ); - m_baseStream.Write( tempBuffer, 0, tempBuffer.Length ); - } - - #endregion - - #region PRIVATE FIELDS - - private string m_indentationString; // = null; - private MemoryStream m_baseStream; // = null; - private bool m_isFirstColumn; // = false; - - #endregion - - #region ToStringMemoryStream Private Class - - // This class is used to force the ToString of the - // MemoryStream to return the content of the Stream - // instead of the name of the Type. - private class ToStringMemoryStream : MemoryStream - { - public override string ToString() - { - if( this.Length == 0 ) - { - return string.Empty; - } - else - { - try - { - return Encoding.Default.GetString( this.ToArray() ); - } - catch( Exception ) - { - return base.ToString(); - } - } - } - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Export/(Clipboard)/HtmlClipboardExporter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Export/(Clipboard)/HtmlClipboardExporter.cs deleted file mode 100644 index f8529bf1..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Export/(Clipboard)/HtmlClipboardExporter.cs +++ /dev/null @@ -1,217 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.ComponentModel; -using System.IO; -using System.Diagnostics; - -namespace Xceed.Wpf.DataGrid.Export -{ - public class HtmlClipboardExporter : ClipboardExporterBase - { - #region PUBLIC CONSTRUCTORS - - public HtmlClipboardExporter() - : base() - { - this.IncludeColumnHeaders = true; - this.FormatSettings = new HtmlFormatSettings(); - m_indentationString = string.Empty; - - // We keep a reference to the innerStream to return it when clipboard export is finished - m_memoryStream = new MemoryStream(); - m_baseStream = new CF_HtmlStream( m_memoryStream ); - } - - #endregion - - #region PUBLIC PROPERTIES - - public HtmlFormatSettings FormatSettings - { - get; - private set; - } - - #endregion - - #region PROTECTED OVERRIDES - - protected override object ClipboardData - { - get - { - // Return the innerStream of the CF_HtmlStream which contains the CF_HTML formatted data - return m_memoryStream; - } - } - - protected override void Indent() - { - string startDelimiter = this.FormatSettings.FieldStartDelimiter; - string endDelimiter = this.FormatSettings.FieldEndDelimiter; - - if( startDelimiter == null ) - startDelimiter = string.Empty; - - if( endDelimiter == null ) - endDelimiter = string.Empty; - - // By default, we suppose indentation as an empty field - m_indentationString += startDelimiter + endDelimiter; - } - - protected override void Unindent() - { - string startDelimiter = this.FormatSettings.FieldStartDelimiter; - string endDelimiter = this.FormatSettings.FieldEndDelimiter; - - if( startDelimiter == null ) - startDelimiter = string.Empty; - - if( endDelimiter == null ) - endDelimiter = string.Empty; - - if( m_indentationString == null ) - { - Debug.Fail( "Indentation must at least be string.empty when unindenting." ); - - // We initalize the indentation string and return - m_indentationString = string.Empty; - } - else - { - int emptyFieldLength = startDelimiter.Length + endDelimiter.Length; - int indentationLength = m_indentationString.Length; - - // If there are less characters in indentationString than in the empty field, just set indentation - // as string.empty - if( indentationLength < emptyFieldLength ) - { - m_indentationString = string.Empty; - } - else - { - m_indentationString = m_indentationString.Substring( 0, indentationLength - emptyFieldLength ); - } - } - } - - protected override void ResetExporter() - { - m_tempBuffer = null; - m_indentationString = string.Empty; - - // We must NOT close or dispose the previous MemoryStream since we pass this - // instance to the Clipboard directly and it becomes responsible of - // closing/disposing it - m_memoryStream = new MemoryStream(); - m_baseStream = new CF_HtmlStream( m_memoryStream ); - } - - protected override void StartExporter( string dataFormat ) - { - this.WriteToBaseStream( this.FormatSettings.ExporterStartDelimiter ); - } - - protected override void EndExporter( string dataFormat ) - { - this.WriteToBaseStream( this.FormatSettings.ExporterEndDelimiter ); - - // Force the header to be updated with length of HTML data and add the footer - m_baseStream.Close(); - } - - protected override void StartHeader( DataGridContext dataGridContext ) - { - this.WriteToBaseStream( this.FormatSettings.HeaderDataStartDelimiter ); - - if( string.IsNullOrEmpty( m_indentationString ) == false ) - { - this.WriteToBaseStream( m_indentationString ); - } - } - - protected override void StartHeaderField( DataGridContext dataGridContext, Column column ) - { - this.WriteToBaseStream( this.FormatSettings.HeaderFieldStartDelimiter ); - - object columnHeader = ( ( this.UseFieldNamesInHeader ) || ( column.Title == null ) ) ? column.FieldName : column.Title; - - string fieldValueString = FormatHelper.FormatHtmlFieldData( null, columnHeader, this.FormatSettings ); - - this.WriteToBaseStream( fieldValueString ); - this.WriteToBaseStream( this.FormatSettings.HeaderFieldEndDelimiter ); - } - - protected override void EndHeader( DataGridContext dataGridContext ) - { - this.WriteToBaseStream( this.FormatSettings.HeaderDataEndDelimiter ); - } - - protected override void StartDataItem( DataGridContext dataGridContext, object dataItem ) - { - this.WriteToBaseStream( this.FormatSettings.DataStartDelimiter ); - - if( string.IsNullOrEmpty( m_indentationString ) == false ) - { - this.WriteToBaseStream( m_indentationString ); - } - } - - protected override void StartDataItemField( DataGridContext dataGridContext, Column column, object fieldValue ) - { - this.WriteToBaseStream( this.FormatSettings.FieldStartDelimiter ); - string fieldValueString = FormatHelper.FormatHtmlFieldData( null, fieldValue, this.FormatSettings ); - this.WriteToBaseStream( fieldValueString ); - this.WriteToBaseStream( this.FormatSettings.FieldEndDelimiter ); - } - - protected override void EndDataItem( DataGridContext dataGridContext, object dataItem ) - { - this.WriteToBaseStream( this.FormatSettings.DataEndDelimiter ); - } - - #endregion - - #region PRIVATE METHODS - - private void WriteToBaseStream( string value ) - { - if( string.IsNullOrEmpty( value ) ) - return; - - m_tempBuffer = Encoding.UTF8.GetBytes( value ); - - m_baseStream.Write( m_tempBuffer, 0, m_tempBuffer.Length ); - } - - #endregion - - #region PRIVATE FIELDS - - private string m_indentationString; // = null; - private MemoryStream m_memoryStream; // = null; - private CF_HtmlStream m_baseStream; // = null; - private byte[] m_tempBuffer; // = null; - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Export/(Clipboard)/HtmlFormatSettings.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Export/(Clipboard)/HtmlFormatSettings.cs deleted file mode 100644 index 59bb495f..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Export/(Clipboard)/HtmlFormatSettings.cs +++ /dev/null @@ -1,106 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Xceed.Wpf.DataGrid.Export -{ - public class HtmlFormatSettings : FormatSettingsBase - { - public HtmlFormatSettings() - { - this.ExporterStartDelimiter = ""; - this.ExporterEndDelimiter = "
"; - - this.HeaderFieldStartDelimiter = ""; - this.HeaderFieldEndDelimiter = ""; - this.HeaderDataStartDelimiter = ""; - this.HeaderDataEndDelimiter = ""; - - this.FieldStartDelimiter = ""; - this.FieldEndDelimiter = ""; - this.DataStartDelimiter = ""; - this.DataEndDelimiter = ""; - } - - #region PUBLIC PROPERTIES - - public string ExporterStartDelimiter - { - get; - set; - } - - public string ExporterEndDelimiter - { - get; - set; - } - - public string HeaderFieldStartDelimiter - { - get; - set; - } - - public string HeaderFieldEndDelimiter - { - get; - set; - } - - public string HeaderDataStartDelimiter - { - get; - set; - } - - public string HeaderDataEndDelimiter - { - get; - set; - } - - public string FieldStartDelimiter - { - get; - set; - } - - public string FieldEndDelimiter - { - get; - set; - } - - public string DataStartDelimiter - { - get; - set; - } - - public string DataEndDelimiter - { - get; - set; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Export/(Clipboard)/UnicodeCsvClipboardExporter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Export/(Clipboard)/UnicodeCsvClipboardExporter.cs deleted file mode 100644 index 534d6db8..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Export/(Clipboard)/UnicodeCsvClipboardExporter.cs +++ /dev/null @@ -1,338 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Diagnostics; -using System.Globalization; -using System.IO; -using System.Text; - -namespace Xceed.Wpf.DataGrid.Export -{ - public class UnicodeCsvClipboardExporter : ClipboardExporterBase - { - public UnicodeCsvClipboardExporter() - { - this.IncludeColumnHeaders = true; - this.FormatSettings = new CsvFormatSettings(); - m_indentationString = string.Empty; - m_baseStream = new ToStringMemoryStream(); - } - - #region PUBLIC PROPERTIES - - public CsvFormatSettings FormatSettings - { - get; - private set; - } - - #endregion - - #region PROTECTED OVERRIDES - - protected override object ClipboardData - { - get - { - return m_baseStream; - } - } - - protected override void Indent() - { - char separator = this.FormatSettings.Separator; - m_indentationString += separator; - } - - protected override void Unindent() - { - char separator = this.FormatSettings.Separator; - - if( m_indentationString == null ) - { - Debug.Fail( "Indentation must at least be string.empty when unindenting." ); - m_indentationString = string.Empty; - } - else - { - int separatorLength = 1; - int indentationLength = m_indentationString.Length; - - // If there are less characters in indentationString than in the empty field, just set indentation - // as string.empty - if( indentationLength < separatorLength ) - { - m_indentationString = string.Empty; - } - else - { - m_indentationString = m_indentationString.Substring( 0, indentationLength - separatorLength ); - } - } - } - - protected override void ResetExporter() - { - m_baseStream = new ToStringMemoryStream(); - m_indentationString = string.Empty; - } - - protected override void StartHeader( DataGridContext dataGridContext ) - { - if( string.IsNullOrEmpty( m_indentationString ) == false ) - this.WriteToBaseStream( m_indentationString ); - - // The next StartDataItemField will be considered as first column - m_isFirstColumn = true; - } - - protected override void StartHeaderField( DataGridContext dataGridContext, Column column ) - { - // We always insert the separator before the value except for the first item - if( !m_isFirstColumn ) - { - this.WriteToBaseStream( this.FormatSettings.Separator ); - } - else - { - m_isFirstColumn = false; - } - - object columnHeader = ( ( this.UseFieldNamesInHeader ) || ( column.Title == null ) ) ? column.FieldName : column.Title; - string fieldValueString = UnicodeCsvClipboardExporter.FormatCsvData( null, columnHeader, this.FormatSettings ); - - this.WriteToBaseStream( fieldValueString ); - } - - protected override void EndHeader( DataGridContext dataGridContext ) - { - this.WriteToBaseStream( this.FormatSettings.NewLine ); - } - - protected override void StartDataItem( DataGridContext dataGridContext, object dataItem ) - { - if( string.IsNullOrEmpty( m_indentationString ) == false ) - this.WriteToBaseStream( m_indentationString ); - - // The next StartDataItemField will be considered as first column - m_isFirstColumn = true; - } - - protected override void StartDataItemField( DataGridContext dataGridContext, Column column, object fieldValue ) - { - // We always insert the separator before the value except for the first item - if( !m_isFirstColumn ) - { - this.WriteToBaseStream( this.FormatSettings.Separator ); - } - else - { - m_isFirstColumn = false; - } - - string fieldValueString = UnicodeCsvClipboardExporter.FormatCsvData( null, fieldValue, this.FormatSettings ); - - this.WriteToBaseStream( fieldValueString ); - } - - protected override void EndDataItem( DataGridContext dataGridContext, object dataItem ) - { - this.WriteToBaseStream( this.FormatSettings.NewLine ); - } - - #endregion - - #region PRIVATE METHODS - - private void WriteToBaseStream( char value ) - { - byte[] tempBuffer = Encoding.Unicode.GetBytes( new char[] { value } ); - m_baseStream.Write( tempBuffer, 0, tempBuffer.Length ); - } - - private void WriteToBaseStream( string value ) - { - if( string.IsNullOrEmpty( value ) ) - return; - - byte[] tempBuffer = Encoding.Unicode.GetBytes( value ); - m_baseStream.Write( tempBuffer, 0, tempBuffer.Length ); - } - - #endregion - - #region Private Static Methods - - private static string FormatCsvData( Type dataType, object dataValue, CsvFormatSettings formatSettings ) - { - string outputString = null; - bool checkWhitespace = true; - - if( ( dataValue != null ) && ( !Convert.IsDBNull( dataValue ) ) && ( !( dataValue is Array ) ) ) - { - if( dataType == null ) - dataType = dataValue.GetType(); - - if( dataType == typeof( string ) ) - { - if( formatSettings.TextQualifier == '\0' ) - { - outputString = ( string )dataValue; - } - else - { - outputString = formatSettings.TextQualifier + ( string )dataValue + formatSettings.TextQualifier; - } - - checkWhitespace = false; - } - else if( dataType == typeof( DateTime ) ) - { - if( !string.IsNullOrEmpty( formatSettings.DateTimeFormat ) ) - { - if( formatSettings.Culture == null ) - { - outputString = ( ( DateTime )dataValue ).ToString( formatSettings.DateTimeFormat, CultureInfo.InvariantCulture ); - } - else - { - outputString = ( ( DateTime )dataValue ).ToString( formatSettings.DateTimeFormat, formatSettings.Culture ); - } - } - } - else if( ( dataType == typeof( double ) ) || - ( dataType == typeof( decimal ) ) || - ( dataType == typeof( float ) ) || - ( dataType == typeof( int ) ) || - ( dataType == typeof( double ) ) || - ( dataType == typeof( decimal ) ) || - ( dataType == typeof( float ) ) || - ( dataType == typeof( short ) ) || - ( dataType == typeof( Single ) ) || - ( dataType == typeof( UInt16 ) ) || - ( dataType == typeof( UInt32 ) ) || - ( dataType == typeof( UInt64 ) ) || - ( dataType == typeof( Int16 ) ) || - ( dataType == typeof( Int64 ) ) ) - { - string format = formatSettings.NumericFormat; - - if( ( ( dataType == typeof( double ) ) || - ( dataType == typeof( decimal ) ) || - ( dataType == typeof( float ) ) ) && - ( !string.IsNullOrEmpty( formatSettings.FloatingPointFormat ) ) ) - format = formatSettings.FloatingPointFormat; - - if( !string.IsNullOrEmpty( format ) ) - { - if( formatSettings.Culture == null ) - { - outputString = string.Format( CultureInfo.InvariantCulture, "{0:" + format + "}", dataValue ); - } - else - { - outputString = string.Format( formatSettings.Culture, "{0:" + format + "}", dataValue ); - } - } - } - - if( outputString == null ) - { - if( formatSettings.Culture == null ) - { - outputString = string.Format( CultureInfo.InvariantCulture, "{0}", dataValue ); - } - else - { - outputString = string.Format( formatSettings.Culture, "{0}", dataValue ); - } - } - - // For dates and numbers, as a rule, we never use the TextQualifier. However, the - // specified format can introduce whitespaces. To better support this case, we add - // the TextQualifier if needed. - if( ( checkWhitespace ) && ( formatSettings.TextQualifier != '\0' ) ) - { - bool useTextQualifier = false; - - // If the output string contains the character used to separate the fields, we - // don't bother checking for whitespace. TextQualifier will be used. - if( outputString.IndexOf( formatSettings.Separator ) < 0 ) - { - for( int i = 0; i < outputString.Length; i++ ) - { - if( char.IsWhiteSpace( outputString, i ) ) - { - useTextQualifier = true; - break; - } - } - } - else - { - useTextQualifier = true; - } - - if( useTextQualifier ) - outputString = formatSettings.TextQualifier + outputString + formatSettings.TextQualifier; - } - } - - return outputString; - } - - #endregion - - #region PRIVATE FIELDS - - private string m_indentationString; // = null; - private MemoryStream m_baseStream; // = null; - private bool m_isFirstColumn; // = false; - - #endregion - - #region ToStringMemoryStream Private Class - - // This class is used to force the ToString of the - // MemoryStream to return the content of the Stream - // instead of the name of the Type. - private class ToStringMemoryStream : MemoryStream - { - public override string ToString() - { - if( this.Length == 0 ) - { - return string.Empty; - } - else - { - try - { - return Encoding.Unicode.GetString( this.ToArray() ); - } - catch( Exception ) - { - return base.ToString(); - } - } - } - } - - #endregion - } -} - diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Export/(Clipboard)/XceedDataObject.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Export/(Clipboard)/XceedDataObject.cs deleted file mode 100644 index 3400f3dd..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Export/(Clipboard)/XceedDataObject.cs +++ /dev/null @@ -1,116 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows; -using System.Security; - -namespace Xceed.Wpf.DataGrid.Export -{ - [SecurityCritical] - [Serializable] - internal class XceedDataObject : IDataObject - { - public XceedDataObject() - { - m_formatToValue = new Dictionary(); - } - - #region PRIVATE FIELDS - - private Dictionary m_formatToValue; // = null; - - #endregion - - #region IDataObject Members - - object IDataObject.GetData( string format, bool autoConvert ) - { - return ( ( IDataObject )this ).GetData( format ); - } - - object IDataObject.GetData( Type format ) - { - throw new NotSupportedException(); - } - - object IDataObject.GetData( string format ) - { - object value = null; - - m_formatToValue.TryGetValue( format, out value ); - - return value; - } - - bool IDataObject.GetDataPresent( string format, bool autoConvert ) - { - return ( ( IDataObject )this ).GetDataPresent( format ); - } - - bool IDataObject.GetDataPresent( Type format ) - { - throw new NotSupportedException(); - } - - bool IDataObject.GetDataPresent( string format ) - { - return m_formatToValue.ContainsKey( format ); - } - - string[] IDataObject.GetFormats( bool autoConvert ) - { - return ( ( IDataObject )this ).GetFormats(); - } - - string[] IDataObject.GetFormats() - { - return m_formatToValue.Keys.ToArray(); - } - - void IDataObject.SetData( string format, object data, bool autoConvert ) - { - ( ( IDataObject )this ).SetData( format, data ); - } - - void IDataObject.SetData( Type format, object data ) - { - throw new NotSupportedException(); - } - - void IDataObject.SetData( string format, object data ) - { - if( m_formatToValue.ContainsKey( format ) ) - { - m_formatToValue[ format ] = data; - } - else - { - m_formatToValue.Add( format, data ); - } - } - - void IDataObject.SetData( object data ) - { - throw new NotSupportedException(); - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Export/CsvFormatSettings.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Export/CsvFormatSettings.cs deleted file mode 100644 index 8fa37464..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Export/CsvFormatSettings.cs +++ /dev/null @@ -1,52 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Globalization; - -namespace Xceed.Wpf.DataGrid.Export -{ - public class CsvFormatSettings : FormatSettingsBase - { - public CsvFormatSettings() - { - this.Separator = ','; - this.TextQualifier = '"'; - this.NewLine = Environment.NewLine; - } - - public char Separator - { - get; - set; - } - - public char TextQualifier - { - get; - set; - } - - public string NewLine - { - get; - set; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Export/FormatHelper.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Export/FormatHelper.cs deleted file mode 100644 index a8cfe398..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Export/FormatHelper.cs +++ /dev/null @@ -1,328 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Globalization; -using System.Diagnostics; - -namespace Xceed.Wpf.DataGrid.Export -{ - internal class FormatHelper - { - - public static string FormatCsvData( Type dataType, object dataValue, CsvFormatSettings formatSettings ) - { - string outputString = null; - bool checkWhitespace = true; - - if( ( dataValue != null ) && ( !Convert.IsDBNull( dataValue ) ) && ( !( dataValue is Array ) ) ) - { - if( dataType == null ) - dataType = dataValue.GetType(); - - if( dataType == typeof( string ) ) - { - string textQualifier = formatSettings.TextQualifier.ToString(); - - if( textQualifier == "\0" ) - { - outputString = ( string )dataValue; - } - else - { - outputString = formatSettings.TextQualifier + ( ( string )dataValue ).Replace( textQualifier, textQualifier + textQualifier ) + formatSettings.TextQualifier; - } - - checkWhitespace = false; - } - else if( dataType == typeof( DateTime ) ) - { - if( !string.IsNullOrEmpty( formatSettings.DateTimeFormat ) ) - { - if( formatSettings.Culture == null ) - { - outputString = ( ( DateTime )dataValue ).ToString( formatSettings.DateTimeFormat, CultureInfo.InvariantCulture ); - } - else - { - outputString = ( ( DateTime )dataValue ).ToString( formatSettings.DateTimeFormat, formatSettings.Culture ); - } - } - } - else if( ( dataType == typeof( double ) ) || - ( dataType == typeof( decimal ) ) || - ( dataType == typeof( float ) ) || - ( dataType == typeof( int ) ) || - ( dataType == typeof( double ) ) || - ( dataType == typeof( decimal ) ) || - ( dataType == typeof( float ) ) || - ( dataType == typeof( short ) ) || - ( dataType == typeof( Single ) ) || - ( dataType == typeof( UInt16 ) ) || - ( dataType == typeof( UInt32 ) ) || - ( dataType == typeof( UInt64 ) ) || - ( dataType == typeof( Int16 ) ) || - ( dataType == typeof( Int64 ) ) ) - { - string format = formatSettings.NumericFormat; - - if( ( ( dataType == typeof( double ) ) || - ( dataType == typeof( decimal ) ) || - ( dataType == typeof( float ) ) ) && - ( !string.IsNullOrEmpty( formatSettings.FloatingPointFormat ) ) ) - format = formatSettings.FloatingPointFormat; - - if( !string.IsNullOrEmpty( format ) ) - { - if( formatSettings.Culture == null ) - { - outputString = string.Format( CultureInfo.InvariantCulture, "{0:" + format + "}", dataValue ); - } - else - { - outputString = string.Format( formatSettings.Culture, "{0:" + format + "}", dataValue ); - } - } - } - - if( outputString == null ) - { - if( formatSettings.Culture == null ) - { - outputString = string.Format( CultureInfo.InvariantCulture, "{0}", dataValue ); - } - else - { - outputString = string.Format( formatSettings.Culture, "{0}", dataValue ); - } - } - - // For dates and numbers, as a rule, we never use the TextQualifier. However, the - // specified format can introduce whitespaces. To better support this case, we add - // the TextQualifier if needed. - if( ( checkWhitespace ) && ( formatSettings.TextQualifier != '\0' ) ) - { - bool useTextQualifier = false; - - // If the output string contains the character used to separate the fields, we - // don't bother checking for whitespace. TextQualifier will be used. - if( outputString.IndexOf( formatSettings.Separator ) < 0 ) - { - for( int i = 0; i < outputString.Length; i++ ) - { - if( char.IsWhiteSpace( outputString, i ) ) - { - useTextQualifier = true; - break; - } - } - } - else - { - useTextQualifier = true; - } - - if( useTextQualifier ) - outputString = formatSettings.TextQualifier + outputString + formatSettings.TextQualifier; - } - - } - - return outputString; - } - - public static string FormatHtmlFieldData( Type dataType, object dataValue, HtmlFormatSettings formatSettings ) - { - string outputString = null; - - if( ( dataValue != null ) && ( !Convert.IsDBNull( dataValue ) ) && ( !( dataValue is Array ) ) ) - { - if( dataType == null ) - dataType = dataValue.GetType(); - - if( dataType == typeof( string ) ) - { - outputString = ( string )dataValue; - } - else if( dataType == typeof( DateTime ) ) - { - if( !string.IsNullOrEmpty( formatSettings.DateTimeFormat ) ) - { - if( formatSettings.Culture == null ) - { - outputString = ( ( DateTime )dataValue ).ToString( formatSettings.DateTimeFormat, CultureInfo.InvariantCulture ); - } - else - { - outputString = ( ( DateTime )dataValue ).ToString( formatSettings.DateTimeFormat, formatSettings.Culture ); - } - } - } - else if( ( dataType == typeof( double ) ) || - ( dataType == typeof( decimal ) ) || - ( dataType == typeof( float ) ) || - ( dataType == typeof( int ) ) || - ( dataType == typeof( double ) ) || - ( dataType == typeof( decimal ) ) || - ( dataType == typeof( float ) ) || - ( dataType == typeof( short ) ) || - ( dataType == typeof( Single ) ) || - ( dataType == typeof( UInt16 ) ) || - ( dataType == typeof( UInt32 ) ) || - ( dataType == typeof( UInt64 ) ) || - ( dataType == typeof( Int16 ) ) || - ( dataType == typeof( Int64 ) ) ) - { - string format = formatSettings.NumericFormat; - - if( ( ( dataType == typeof( double ) ) || - ( dataType == typeof( decimal ) ) || - ( dataType == typeof( float ) ) ) && - ( !string.IsNullOrEmpty( formatSettings.FloatingPointFormat ) ) ) - format = formatSettings.FloatingPointFormat; - - if( !string.IsNullOrEmpty( format ) ) - { - if( formatSettings.Culture == null ) - { - outputString = string.Format( CultureInfo.InvariantCulture, "{0:" + format + "}", dataValue ); - } - else - { - outputString = string.Format( formatSettings.Culture, "{0:" + format + "}", dataValue ); - } - } - } - - if( outputString == null ) - { - if( formatSettings.Culture == null ) - { - outputString = string.Format( CultureInfo.InvariantCulture, "{0}", dataValue ); - } - else - { - outputString = string.Format( formatSettings.Culture, "{0}", dataValue ); - } - } - } - - return FormatHelper.FormatPlainTextAsHtml( outputString ); - } - - public static void FormatHtmlData( StringBuilder htmlDataStringBuilder ) - { - string htmlDataString = htmlDataStringBuilder.ToString(); - - StringBuilder headerStringBuilder = new StringBuilder(); - headerStringBuilder.Append( "Version:1.0" ); - headerStringBuilder.Append( Environment.NewLine ); - headerStringBuilder.Append( "StartHTML:-1" ); // This is optional according to MSDN documentation - headerStringBuilder.Append( Environment.NewLine ); - headerStringBuilder.Append( "EndHTML:-1" ); // This is optional according to MSDN documentation - headerStringBuilder.Append( Environment.NewLine ); - headerStringBuilder.Append( "StartFragment:0000000109" ); // Always 109 bytes from start of Version to the end of tag - headerStringBuilder.Append( Environment.NewLine ); - headerStringBuilder.Append( "EndFragment:{0}" ); // need + 7 to "emulate" the 10 digits ( "{x}" is already 3 of the 10 chars ) - headerStringBuilder.Append( Environment.NewLine ); - headerStringBuilder.Append( "" ); - - // We assure the StartFramgment offset is correct - string headerString = headerStringBuilder.ToString(); - int startFragmentByteCounts = headerString.Length + 7; // +7 chars as mentionned above - Debug.Assert( startFragmentByteCounts == 109 ); - - // Compute the EndFragment offset => header size + html data size + final end line (after data) length (\r\n) - int endFragmentByteCounts = startFragmentByteCounts + htmlDataString.Length + Environment.NewLine.Length; - string endFragmentOffset = endFragmentByteCounts.ToString( "0000000000", CultureInfo.InvariantCulture ); - headerString = string.Format( CultureInfo.InvariantCulture, headerString, endFragmentOffset ); - - // Insert header at the beginning of the htmlDataStringBuilder - htmlDataStringBuilder.Insert( 0, headerString ); - - // Append the final end line and EndFragment tag - htmlDataStringBuilder.Append( Environment.NewLine ); - htmlDataStringBuilder.Append( "" ); - } - - public static string FormatPlainTextAsHtml( string plainText ) - { - StringBuilder htmlStringBuilder = new StringBuilder(); - if( string.IsNullOrEmpty( plainText ) == false ) - { - int length = plainText.Length; - - for( int i = 0; i < length; i++ ) - { - char currentChar = plainText[ i ]; - switch( currentChar ) - { - case '\n': - htmlStringBuilder.Append( "
" ); - break; - - case '\r': - break; - - case '\u00A0': - htmlStringBuilder.Append( " " ); - break; - - case '"': - htmlStringBuilder.Append( """ ); - break; - - case '&': - htmlStringBuilder.Append( "&" ); - break; - - case '<': - htmlStringBuilder.Append( "<" ); - break; - - case '>': - htmlStringBuilder.Append( ">" ); - break; - - default: - // For extended ascii table - if( ( currentChar >= 160 ) && ( currentChar < 256 ) ) - { - htmlStringBuilder.Append( "&#" ); - htmlStringBuilder.Append( ( ( int )currentChar ).ToString( NumberFormatInfo.InvariantInfo ) ); - htmlStringBuilder.Append( ';' ); - } - else - { - htmlStringBuilder.Append( currentChar ); - } - break; - } - } - } - else - { - // Add blank space into field when null or empty - htmlStringBuilder.Append( " " ); - } - - return htmlStringBuilder.ToString(); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Export/FormatSettingsBase.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Export/FormatSettingsBase.cs deleted file mode 100644 index e3dad557..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Export/FormatSettingsBase.cs +++ /dev/null @@ -1,51 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Globalization; - -namespace Xceed.Wpf.DataGrid.Export -{ - public abstract class FormatSettingsBase - { - public string DateTimeFormat - { - get; - set; - } - - public string NumericFormat - { - get; - set; - } - - public string FloatingPointFormat - { - get; - set; - } - - public CultureInfo Culture - { - get; - set; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/FieldNameGroupConfigurationSelector.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/FieldNameGroupConfigurationSelector.cs deleted file mode 100644 index e03ae7ae..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/FieldNameGroupConfigurationSelector.cs +++ /dev/null @@ -1,72 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Collections.ObjectModel; -using System.Windows.Data; -using System.Windows.Markup; - -namespace Xceed.Wpf.DataGrid -{ - [ContentProperty( "SelectorItems" )] - public class FieldNameGroupConfigurationSelector : GroupConfigurationSelector - { - private FieldNameGroupConfigurationSelectorItemCollection m_groupConfigurationSelectorItems = new FieldNameGroupConfigurationSelectorItemCollection(); - - public ObservableCollection SelectorItems - { - get - { - return m_groupConfigurationSelectorItems; - } - } - - public override GroupConfiguration SelectGroupConfiguration( int groupLevel, CollectionViewGroup collectionViewGroup, System.ComponentModel.GroupDescription groupDescription ) - { - if( m_groupConfigurationSelectorItems.Count == 0 ) - return base.SelectGroupConfiguration( groupLevel, collectionViewGroup, groupDescription ); - - string fieldName = string.Empty; - - DataGridGroupDescription dataGridGroupDescription = groupDescription as DataGridGroupDescription; - if( dataGridGroupDescription != null ) - { - fieldName = dataGridGroupDescription.PropertyName; - } - else - { - PropertyGroupDescription propertyGroupDescription = groupDescription as PropertyGroupDescription; - if( propertyGroupDescription != null ) - { - fieldName = propertyGroupDescription.PropertyName; - } - } - - if( String.IsNullOrEmpty( fieldName ) == true ) - return base.SelectGroupConfiguration( groupLevel, collectionViewGroup, groupDescription ); - - FieldNameGroupConfigurationSelectorItem groupConfig = m_groupConfigurationSelectorItems.GetGroupConfigurationSelectorItem( fieldName ); - if( groupConfig != null ) - { - return groupConfig.GroupConfiguration; - } - - return base.SelectGroupConfiguration( groupLevel, collectionViewGroup, groupDescription ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/FieldNameGroupConfigurationSelectorItem.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/FieldNameGroupConfigurationSelectorItem.cs deleted file mode 100644 index 97ef71bb..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/FieldNameGroupConfigurationSelectorItem.cs +++ /dev/null @@ -1,85 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Windows.Markup; - -namespace Xceed.Wpf.DataGrid -{ - [ContentProperty( "GroupConfiguration" )] - public class FieldNameGroupConfigurationSelectorItem - { - #region FieldName Property - - public string FieldName - { - get - { - return m_fieldName; - } - set - { - if( m_isSealed == true ) - throw new InvalidOperationException( "An attempt was made to modify the FieldName property after the FieldNameGroupConfigurationSelectorItem has been added to a FieldNameGroupConfigurationSelector." ); - - m_fieldName = value; - } - } - - private string m_fieldName; - - #endregion - - #region GroupConfiguration Property - - public GroupConfiguration GroupConfiguration - { - get - { - return m_groupConfig; - } - set - { - m_groupConfig = value; - } - } - - private GroupConfiguration m_groupConfig; - - #endregion - - #region IsSealed Property - - private bool m_isSealed = false; - - public bool IsSealed - { - get - { - return m_isSealed; - } - } - - internal void Seal() - { - m_isSealed = true; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/FieldNameGroupConfigurationSelectorItemCollection.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/FieldNameGroupConfigurationSelectorItemCollection.cs deleted file mode 100644 index 733b1b36..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/FieldNameGroupConfigurationSelectorItemCollection.cs +++ /dev/null @@ -1,70 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Collections.ObjectModel; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class FieldNameGroupConfigurationSelectorItemCollection : ObservableCollection - { - internal FieldNameGroupConfigurationSelectorItemCollection() - :base() - { - } - - public FieldNameGroupConfigurationSelectorItem GetGroupConfigurationSelectorItem( string fieldName ) - { - FieldNameGroupConfigurationSelectorItem retval = null; - - foreach( FieldNameGroupConfigurationSelectorItem fieldNameGroupConfig in this ) - { - if( fieldNameGroupConfig.FieldName == fieldName ) - { - retval = fieldNameGroupConfig; - break; - } - } - - return retval; - } - - protected override void InsertItem( int index, FieldNameGroupConfigurationSelectorItem item ) - { - if( this.GetGroupConfigurationSelectorItem( item.FieldName ) != null ) - throw new InvalidOperationException( "An attempt was made to insert a FieldNameGroupConfigurationSelectorItem that has the same field name as an existing FieldNameGroupConfigurationSelectorItem." ); - - base.InsertItem( index, item ); - - item.Seal(); - } - - protected override void SetItem( int index, FieldNameGroupConfigurationSelectorItem item ) - { - FieldNameGroupConfigurationSelectorItem oldGroupConfig = this[ index ]; - FieldNameGroupConfigurationSelectorItem failingGroupConfig = this.GetGroupConfigurationSelectorItem( item.FieldName ); - - if( ( failingGroupConfig != null ) && ( oldGroupConfig != failingGroupConfig ) ) - throw new InvalidOperationException( "An attempt was made to set a FieldNameGroupConfigurationSelectorItem that has the same field name as an existing FieldNameGroupConfigurationSelectorItem." ); - - base.SetItem( index, item ); - - item.Seal(); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/FrameworkElementExtensions.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/FrameworkElementExtensions.cs deleted file mode 100644 index a2138730..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/FrameworkElementExtensions.cs +++ /dev/null @@ -1,329 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Globalization; -using System.Windows; -using System.Windows.Documents; -using System.Windows.Media; -using System.Windows.Media.TextFormatting; -using Xceed.Utils.Collections; - -namespace Xceed.Wpf.DataGrid -{ - internal static class FrameworkElementExtensions - { - #region Static Fields - - private static readonly WeakDictionary s_fontHeight = new WeakDictionary(); - - #endregion - - internal static object CoerceMinHeight( this FrameworkElement source, Thickness padding, object value ) - { - if( source == null ) - throw new ArgumentNullException( "source" ); - - var newValue = ( double )value; - var minHeight = FrameworkElementExtensions.GetFontHeight( source ) + padding.Top + padding.Bottom; - - if( newValue >= minHeight ) - return value; - - if( minHeight != source.MinHeight ) - return minHeight; - - return DependencyProperty.UnsetValue; - } - - internal static double GetFontHeight( this FrameworkElement source ) - { - if( source == null ) - throw new ArgumentNullException( "source" ); - - var textProperties = new TextProperties( - TextOptions.GetTextFormattingMode( source ), - TextElement.GetFontFamily( source ), - TextElement.GetFontStyle( source ), - TextElement.GetFontWeight( source ), - TextElement.GetFontStretch( source ), - TextElement.GetFontSize( source ) ); - - lock( ( ( ICollection )s_fontHeight ).SyncRoot ) - { - double fontHeight; - - if( !s_fontHeight.TryGetValue( textProperties, out fontHeight ) ) - { - var formatter = TextFormatter.Create( textProperties.FormattingMode ); - var typeface = new Typeface( textProperties.FontFamily, textProperties.FontStyle, textProperties.FontWeight, textProperties.FontStretch ); - var textSource = new EmptyTextSource(); - var textRunProperties = new EmptyTextRunProperties( typeface, textProperties.FontSize ); - var textParagraphProperties = new EmptyTextParagraphProperties( textRunProperties ); - var textLine = formatter.FormatLine( textSource, 0, 0d, textParagraphProperties, null ); - - fontHeight = textLine.Height; - s_fontHeight.Add( textProperties, fontHeight ); - } - - return fontHeight; - } - } - - #region EmptyTextSource Private Class - - private sealed class EmptyTextSource : TextSource - { - public override TextSpan GetPrecedingText( int textSourceCharacterIndexLimit ) - { - return new TextSpan( 0, null ); - } - - public override int GetTextEffectCharacterIndexFromTextSourceCharacterIndex( int textSourceCharacterIndex ) - { - return -1; - } - - public override TextRun GetTextRun( int textSourceCharacterIndex ) - { - return new TextEndOfParagraph( 1 ); - } - } - - #endregion - - #region EmptyTextParagraphProperties Private Class - - private sealed class EmptyTextParagraphProperties : TextParagraphProperties - { - internal EmptyTextParagraphProperties( TextRunProperties defaultTextRunProperties ) - { - m_defaultTextRunProperties = defaultTextRunProperties; - } - - public override TextRunProperties DefaultTextRunProperties - { - get - { - return m_defaultTextRunProperties; - } - } - - public override bool FirstLineInParagraph - { - get - { - return true; - } - } - - public override FlowDirection FlowDirection - { - get - { - return FlowDirection.LeftToRight; - } - } - - public override double Indent - { - get - { - return 0d; - } - } - - public override double LineHeight - { - get - { - return 0d; - } - } - - public override TextAlignment TextAlignment - { - get - { - return TextAlignment.Left; - } - } - - public override TextMarkerProperties TextMarkerProperties - { - get - { - return null; - } - } - - public override TextWrapping TextWrapping - { - get - { - return TextWrapping.NoWrap; - } - } - - private readonly TextRunProperties m_defaultTextRunProperties; - } - - #endregion - - #region EmptyTextRunProperties Private Class - - private sealed class EmptyTextRunProperties : TextRunProperties - { - internal EmptyTextRunProperties( Typeface typeface, double fontSize ) - { - m_typeface = typeface; - m_fontSize = fontSize; - } - - public override Brush BackgroundBrush - { - get - { - return Brushes.Transparent; - } - } - - public override CultureInfo CultureInfo - { - get - { - return CultureInfo.InvariantCulture; - } - } - - public override double FontHintingEmSize - { - get - { - return m_fontSize; - } - } - - public override double FontRenderingEmSize - { - get - { - return m_fontSize; - } - } - - public override Brush ForegroundBrush - { - get - { - return Brushes.Transparent; - } - } - - public override TextDecorationCollection TextDecorations - { - get - { - return null; - } - } - - public override TextEffectCollection TextEffects - { - get - { - return null; - } - } - - public override Typeface Typeface - { - get - { - return m_typeface; - } - } - - private readonly Typeface m_typeface; - private readonly double m_fontSize; - } - - #endregion - - #region TextProperties Private Class - - private sealed class TextProperties : IEquatable - { - internal TextProperties( TextFormattingMode formattingMode, FontFamily fontFamily, FontStyle fontStyle, FontWeight fontWeight, FontStretch fontStretch, double fontSize ) - { - this.FormattingMode = formattingMode; - this.FontFamily = fontFamily; - this.FontStyle = fontStyle; - this.FontWeight = fontWeight; - this.FontStretch = fontStretch; - this.FontSize = fontSize; - } - - public override int GetHashCode() - { - unchecked - { - var hashCode = this.FontSize.GetHashCode(); - - if( this.FontFamily != null ) - { - hashCode = hashCode * 13 + this.FontFamily.GetHashCode(); - } - - hashCode = hashCode * 13 + this.FontStyle.GetHashCode(); - hashCode = hashCode * 13 + this.FontWeight.GetHashCode(); - hashCode = hashCode * 13 + this.FontStretch.GetHashCode(); - hashCode = hashCode * 13 + this.FormattingMode.GetHashCode(); - - return hashCode; - } - } - - public override bool Equals( object obj ) - { - return this.Equals( obj as TextProperties ); - } - - public bool Equals( TextProperties obj ) - { - if( object.ReferenceEquals( obj, null ) ) - return false; - - return object.Equals( obj.FontSize, this.FontSize ) - && object.Equals( obj.FontFamily, this.FontFamily ) - && object.Equals( obj.FontStyle, this.FontStyle ) - && object.Equals( obj.FontWeight, this.FontWeight ) - && object.Equals( obj.FontStretch, this.FontStretch ) - && object.Equals( obj.FormattingMode, this.FormattingMode ); - } - - internal readonly TextFormattingMode FormattingMode; - internal readonly FontFamily FontFamily; - internal readonly FontStyle FontStyle; - internal readonly FontWeight FontWeight; - internal readonly FontStretch FontStretch; - internal readonly double FontSize; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GenericContentTemplateSelector.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GenericContentTemplateSelector.cs deleted file mode 100644 index a63c558f..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GenericContentTemplateSelector.cs +++ /dev/null @@ -1,400 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics; -using System.Globalization; -using System.Reflection; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Media; -using System.Xml; -using Xceed.Wpf.DataGrid.Converters; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class GenericContentTemplateSelector : DataTemplateSelector - { - #region Static Fields - - internal static readonly DataTemplate ForeignKeyCellContentTemplate; - internal static readonly DataTemplate ForeignKeyGroupValueTemplate; - internal static readonly DataTemplate ForeignKeyScrollTipContentTemplate; - - private static readonly DataTemplate BoolTemplate; - private static readonly DataTemplate CommonTemplate; - private static readonly DataTemplate ImageTemplate; - - private static readonly List> DefaultTemplates = new List>( 0 ); - - private static readonly GenericContentTemplateSelectorResources GenericContentTemplateResources = new GenericContentTemplateSelectorResources(); - - private static Func FindTemplateResource; //null - - #endregion - - #region Constructors - - static GenericContentTemplateSelector() - { - // We need to initalize the ResourceDictionary before accessing since we access - // it in a static constructor and will be called before the Layout was performed - GenericContentTemplateSelector.GenericContentTemplateResources.InitializeComponent(); - - GenericContentTemplateSelector.BoolTemplate = GenericContentTemplateSelector.GenericContentTemplateResources[ "booleanDefaultContentTemplate" ] as DataTemplate; - Debug.Assert( GenericContentTemplateSelector.BoolTemplate != null ); - GenericContentTemplateSelector.BoolTemplate.Seal(); - - GenericContentTemplateSelector.CommonTemplate = GenericContentTemplateSelector.GenericContentTemplateResources[ "commonDefaultContentTemplate" ] as DataTemplate; - Debug.Assert( GenericContentTemplateSelector.CommonTemplate != null ); - GenericContentTemplateSelector.CommonTemplate.Seal(); - - GenericContentTemplateSelector.ImageTemplate = GenericContentTemplateSelector.GenericContentTemplateResources[ "imageDefaultContentTemplate" ] as DataTemplate; - Debug.Assert( GenericContentTemplateSelector.ImageTemplate != null ); - GenericContentTemplateSelector.ImageTemplate.Seal(); - - GenericContentTemplateSelector.ForeignKeyCellContentTemplate = GenericContentTemplateSelector.GenericContentTemplateResources[ "foreignKeyDefaultContentTemplate" ] as DataTemplate; - Debug.Assert( GenericContentTemplateSelector.ForeignKeyCellContentTemplate != null ); - GenericContentTemplateSelector.ForeignKeyCellContentTemplate.Seal(); - - GenericContentTemplateSelector.ForeignKeyGroupValueTemplate = GenericContentTemplateSelector.GenericContentTemplateResources[ "foreignKeyGroupValueDefaultContentTemplate" ] as DataTemplate; - Debug.Assert( GenericContentTemplateSelector.ForeignKeyGroupValueTemplate != null ); - GenericContentTemplateSelector.ForeignKeyGroupValueTemplate.Seal(); - - GenericContentTemplateSelector.ForeignKeyScrollTipContentTemplate = GenericContentTemplateSelector.GenericContentTemplateResources[ "foreignKeyScrollTipDefaultContentTemplate" ] as DataTemplate; - Debug.Assert( GenericContentTemplateSelector.ForeignKeyScrollTipContentTemplate != null ); - GenericContentTemplateSelector.ForeignKeyScrollTipContentTemplate.Seal(); - } - - private GenericContentTemplateSelector() - { - } - - #endregion - - #region Instance Static Property - - public static GenericContentTemplateSelector Instance - { - get - { - return m_instance; - } - } - - private static GenericContentTemplateSelector m_instance = new GenericContentTemplateSelector(); - - #endregion - - public override DataTemplate SelectTemplate( object item, DependencyObject container ) - { - if( item == null ) - return base.SelectTemplate( item, container ); - - DataTemplate template = null; - - if( ( item is byte[] ) || ( item is System.Drawing.Image ) ) - { - bool useImageTemplate = false; - - try - { - var converter = new ImageConverter(); - useImageTemplate = ( converter.Convert( item, typeof( ImageSource ), null, CultureInfo.CurrentCulture ) != null ); - } - catch( NotSupportedException ) - { - //suppress the exception, the byte[] is not an image. convertedValue will remain null - } - - if( useImageTemplate ) - { - template = GenericContentTemplateSelector.GetImageTemplate( container ); - } - } - else if( item is ImageSource ) - { - template = GenericContentTemplateSelector.GetImageTemplate( container ); - } - else if( item is bool ) - { - template = GenericContentTemplateSelector.BoolTemplate; - } - - if( template == null ) - { - template = GenericContentTemplateSelector.GetCommonTemplate( item, container ); - } - - if( template != null ) - return template; - - return base.SelectTemplate( item, container ); - } - - private static DataTemplate GetImageTemplate( DependencyObject container ) - { - return GenericContentTemplateSelector.ImageTemplate; - } - - private static DataTemplate GetCommonTemplate( object item, DependencyObject container ) - { - Debug.Assert( item != null ); - - var itemType = item.GetType(); - - // Do not provide a template for data types that are already optimized by the framework or - // for data types that have a default template. - if( GenericContentTemplateSelector.IsTypeOptimized( itemType ) - || GenericContentTemplateSelector.HasImplicitTemplate( item, itemType, container ) ) - return null; - - return GenericContentTemplateSelector.GetDefaultTemplate( itemType ); - } - - private static DataTemplate GetDefaultTemplate( Type type ) - { - Debug.Assert( type != null ); - - var converter = TypeDescriptor.GetConverter( type ); - if( ( converter == null ) || ( !converter.CanConvertTo( typeof( string ) ) ) ) - return GenericContentTemplateSelector.CommonTemplate; - - var templates = GenericContentTemplateSelector.DefaultTemplates; - lock( ( ( ICollection )templates ).SyncRoot ) - { - for( int i = templates.Count - 1; i >= 0; i-- ) - { - var target = templates[ i ]; - var targetTemplate = target.Value.Target as DataTemplate; - - // We have found the desired template. - if( target.Key == type ) - { - if( targetTemplate != null ) - return targetTemplate; - - // Unfortunately, the template has been garbage collected. - templates.RemoveAt( i ); - break; - } - } - - templates.TrimExcess(); - - var template = GenericContentTemplateSelector.CreateDefaultTemplate( type, converter ); - - templates.Add( new KeyValuePair( type, new WeakReference( template ) ) ); - - return template; - } - } - - private static DataTemplate CreateDefaultTemplate( Type type, TypeConverter converter ) - { - Debug.Assert( type != null ); - Debug.Assert( converter != null ); - - var template = new DataTemplate(); - var factory = new FrameworkElementFactory( typeof( TextBlock ) ); - - var binding = new Binding(); - binding.Mode = BindingMode.OneWay; - binding.Converter = new DefaultConverter( converter ); - binding.ConverterCulture = CultureInfo.CurrentCulture; - - factory.SetBinding( TextBlock.TextProperty, binding ); - - template.VisualTree = factory; - template.Seal(); - - return template; - } - - private static bool IsTypeOptimized( Type type ) - { - Debug.Assert( type != null ); - - if( typeof( string ).IsAssignableFrom( type ) - || typeof( UIElement ).IsAssignableFrom( type ) - || typeof( XmlNode ).IsAssignableFrom( type ) ) - return true; - - if( !typeof( Inline ).IsAssignableFrom( type ) ) - { - var converter = TypeDescriptor.GetConverter( type ); - if( ( converter != null ) && ( converter.CanConvertTo( typeof( UIElement ) ) ) ) - return true; - } - - return false; - } - - private static bool HasImplicitTemplate( object item, Type type, DependencyObject container ) - { - Debug.Assert( type != null ); - - var finder = GenericContentTemplateSelector.FindTemplateResource; - - if( finder == null ) - { - finder = GenericContentTemplateSelector.GetFindTemplateResourceInternal(); - - if( finder == null ) - { - finder = GenericContentTemplateSelector.FindTemplateResourceFallback; - } - - GenericContentTemplateSelector.FindTemplateResource = finder; - } - - Debug.Assert( finder != null ); - - return ( finder.Invoke( container, item, type ) != null ); - } - - private static Func GetFindTemplateResourceInternal() - { - try - { - var methodInfo = typeof( FrameworkElement ).GetMethod( - "FindTemplateResourceInternal", - BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static, - null, - CallingConventions.Any, - new Type[] { typeof( DependencyObject ), typeof( object ), typeof( Type ) }, - null ); - - if( methodInfo != null ) - { - var finder = ( Func )Delegate.CreateDelegate( typeof( Func ), methodInfo ); - - return ( container, item, type ) => finder.Invoke( container, item, typeof( DataTemplate ) ); - } - } - catch( AmbiguousMatchException ) - { - // We swallow the exception and use a fallback method instead. - } - catch( MethodAccessException ) - { - // We swallow the exception and use a fallback method instead. - } - - return null; - } - - private static object FindTemplateResourceFallback( DependencyObject container, object item, Type type ) - { - var fe = container as FrameworkElement; - if( fe == null ) - return null; - - return fe.TryFindResource( new DataTemplateKey( type ) ); - } - - #region DefaultConverter Private Class - - private sealed class DefaultConverter : IValueConverter - { - internal DefaultConverter( TypeConverter converter ) - { - if( converter == null ) - throw new ArgumentNullException( "converter" ); - - m_converter = converter; - } - - public object Convert( object value, Type targetType, object parameter, CultureInfo culture ) - { - object result; - - if( DefaultConverter.TryConvertTo( value, targetType, culture, m_converter, out result ) ) - return result; - - if( value != null ) - { - var valueType = value.GetType(); - - if( DefaultConverter.TryConvertTo( value, targetType, culture, TypeDescriptor.GetConverter( valueType ), out result ) ) - return result; - - if( targetType.IsAssignableFrom( valueType ) ) - return value; - } - else if( DefaultConverter.IsNullableType( targetType ) ) - { - return value; - } - - throw new ArgumentException( "Cannot convert to type " + targetType.FullName + ".", "value" ); - } - - public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture ) - { - throw new NotSupportedException(); - } - - private static bool TryConvertTo( object value, Type targetType, CultureInfo culture, TypeConverter converter, out object result ) - { - if( converter != null ) - { - try - { - result = converter.ConvertTo( null, culture, value, targetType ); - return true; - } - catch - { - // We'll try to convert the value another way. - } - - if( ( value != null ) && ( converter.CanConvertFrom( value.GetType() ) ) ) - { - try - { - var newValue = converter.ConvertFrom( null, culture, value ); - result = converter.ConvertTo( null, culture, newValue, targetType ); - - return true; - } - catch - { - } - } - } - - result = null; - return false; - } - - private static bool IsNullableType( Type type ) - { - return ( !type.IsValueType ) - || ( type.IsGenericType && ( type.GetGenericTypeDefinition() == typeof( Nullable<> ) ) ); - } - - private readonly TypeConverter m_converter; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GlobalSuppressions.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GlobalSuppressions.cs deleted file mode 100644 index caef2c8a..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GlobalSuppressions.cs +++ /dev/null @@ -1,248 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Diagnostics.CodeAnalysis; - -[assembly: SuppressMessage( - "Microsoft.Performance", - "CA1823:AvoidUnusedPrivateFields", - Scope = "member", - Target = "_XceedVersionInfoCommon.Build" )] - -[assembly: SuppressMessage( - "Microsoft.Performance", - "CA1823:AvoidUnusedPrivateFields", - Scope = "member", - Target = "_XceedVersionInfo.CurrentAssemblyPackUri" )] - -[assembly: SuppressMessage( - "Microsoft.Design", - "CA1020:AvoidNamespacesWithFewTypes", - Scope = "namespace", - Target = "XamlGeneratedNamespace" )] - -[assembly: SuppressMessage( - "Microsoft.Usage", - "CA2209:AssembliesShouldDeclareMinimumSecurity" )] - -[assembly: SuppressMessage( - "Microsoft.Design", - "CA1020:AvoidNamespacesWithFewTypes", - Scope = "namespace", - Target = "Xceed.Wpf.DataGrid.ValidationRules" )] - -[assembly: SuppressMessage( - "Microsoft.Usage", - "CA2233:OperationsShouldNotOverflow", - Scope = "member", - Target = "Xceed.Wpf.DataGrid.DataGridCollectionView.System.Collections.ICollection.CopyTo(System.Array,System.Int32):System.Void", - MessageId = "index+1" )] - -[assembly: SuppressMessage( - "Microsoft.Design", - "CA1020:AvoidNamespacesWithFewTypes", - Scope = "namespace", - Target = "Xceed.Utils.Wpf.Markup" )] - -[assembly: SuppressMessage( - "Microsoft.Design", - "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", - Scope = "member", - Target = "Xceed.Wpf.DataGrid.DataGridControl.System.Windows.Documents.IDocumentPaginatorSource.DocumentPaginator" )] - -[assembly: SuppressMessage( - "Microsoft.Design", - "CA1043:UseIntegralOrStringArgumentForIndexers", - Scope = "member", - Target = "Xceed.Wpf.DataGrid.CellCollection.Item[Xceed.Wpf.DataGrid.Column]" )] - -[assembly: SuppressMessage( - "Microsoft.Usage", - "CA1801:ReviewUnusedParameters", - Scope = "member", - Target = "Xceed.Wpf.DataGrid.DataGridCollectionView..ctor(System.Type)", MessageId = "itemType" )] - -[assembly: SuppressMessage( - "Microsoft.Performance", - "CA1805:DoNotInitializeUnnecessarily", - Scope = "member", - Target = "Xceed.Wpf.DataGrid.DetailConfiguration..ctor(Xceed.Wpf.DataGrid.DataGridContext)" )] - -[assembly: SuppressMessage( - "Microsoft.Performance", - "CA1800:DoNotCastUnnecessarily", - Scope = "member", - Target = "Xceed.Wpf.DataGrid.GroupByControl.Xceed.Utils.Wpf.DragDrop.IDropTarget.CanDropElement(System.Windows.UIElement):System.Boolean" )] - -[assembly: SuppressMessage( - "Microsoft.Performance", - "CA1800:DoNotCastUnnecessarily", - Scope = "member", - Target = "Xceed.Wpf.DataGrid.GroupByItem.Xceed.Utils.Wpf.DragDrop.IDropTarget.CanDropElement(System.Windows.UIElement):System.Boolean" )] - -[assembly: SuppressMessage( - "Microsoft.Design", - "CA1011:ConsiderPassingBaseTypesAsParameters", - Scope = "member", - Target = "Xceed.Wpf.DataGrid.Views.Theme.IsViewSupported(System.Type,System.Type):System.Boolean" )] - -[assembly: SuppressMessage( - "Microsoft.Design", - "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", - Scope = "member", - Target = "Xceed.Wpf.DataGrid.GroupLevelIndicatorPane.System.Windows.IWeakEventListener.ReceiveWeakEvent(System.Type,System.Object,System.EventArgs):System.Boolean" )] - -[assembly: SuppressMessage( - "Microsoft.Design", - "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", - Scope = "member", - Target = "Xceed.Wpf.DataGrid.HierarchicalGroupLevelIndicatorPane.System.Windows.IWeakEventListener.ReceiveWeakEvent(System.Type,System.Object,System.EventArgs):System.Boolean" )] - -[assembly: SuppressMessage( - "Microsoft.Usage", - "CA1801:ReviewUnusedParameters", - Scope = "member", - Target = "Xceed.Wpf.DataGrid.DetailConfiguration.AddDefaultHeadersFooters(System.Collections.ObjectModel.ObservableCollection`1,System.Collections.ObjectModel.ObservableCollection`1):System.Void", MessageId = "footersCollection" )] - -#region CA2214:DoNotCallOverridableMethodsInConstructors - -[assembly: SuppressMessage( - "Microsoft.Usage", - "CA2214:DoNotCallOverridableMethodsInConstructors", - Scope = "member", - Target = "Xceed.Wpf.DataGrid.Cell..ctor()" )] - -[assembly: SuppressMessage( - "Microsoft.Usage", - "CA2214:DoNotCallOverridableMethodsInConstructors", - Scope = "member", - Target = "Xceed.Wpf.DataGrid.CellEditor..ctor()" )] - -[assembly: SuppressMessage( - "Microsoft.Usage", - "CA2214:DoNotCallOverridableMethodsInConstructors", - Scope = "member", - Target = "Xceed.Wpf.DataGrid.Column..ctor()" )] - -[assembly: SuppressMessage( - "Microsoft.Usage", - "CA2214:DoNotCallOverridableMethodsInConstructors", - Scope = "member", - Target = "Xceed.Wpf.DataGrid.Column..ctor(System.String,System.Object,System.Windows.Data.BindingBase)" )] - -[assembly: SuppressMessage( - "Microsoft.Usage", - "CA2214:DoNotCallOverridableMethodsInConstructors", - Scope = "member", - Target = "Xceed.Wpf.DataGrid.ColumnManagerCell..ctor()" )] - -[assembly: SuppressMessage( - "Microsoft.Usage", - "CA2214:DoNotCallOverridableMethodsInConstructors", - Scope = "member", - Target = "Xceed.Wpf.DataGrid.ColumnManagerRow..ctor()" )] - -[assembly: SuppressMessage( - "Microsoft.Usage", - "CA2214:DoNotCallOverridableMethodsInConstructors", - Scope = "member", - Target = "Xceed.Wpf.DataGrid.DataCell..ctor(System.String,System.Object)" )] - -[assembly: SuppressMessage( - "Microsoft.Usage", - "CA2214:DoNotCallOverridableMethodsInConstructors", - Scope = "member", - Target = "Xceed.Wpf.DataGrid.DataGridControl..ctor()" )] - -[assembly: SuppressMessage( - "Microsoft.Usage", - "CA2214:DoNotCallOverridableMethodsInConstructors", - Scope = "member", - Target = "Xceed.Wpf.DataGrid.DropMarkAdorner..ctor(System.Windows.UIElement,System.Windows.Media.Pen,Xceed.Wpf.DataGrid.DropMarkOrientation)" )] - -[assembly: SuppressMessage( - "Microsoft.Usage", - "CA2214:DoNotCallOverridableMethodsInConstructors", - Scope = "member", - Target = "Xceed.Wpf.DataGrid.Views.SynchronizedScrollViewer..ctor()" )] - -[assembly: SuppressMessage( - "Microsoft.Usage", - "CA2214:DoNotCallOverridableMethodsInConstructors", - Scope = "member", - Target = "Xceed.Wpf.DataGrid.Views.ViewBase..ctor()" )] - -[assembly: SuppressMessage( - "Microsoft.Usage", - "CA2214:DoNotCallOverridableMethodsInConstructors", - Scope = "member", - Target = "Xceed.Wpf.DataGrid.GroupHeaderControl..ctor(Xceed.Wpf.DataGrid.Group)" )] - -[assembly: SuppressMessage( - "Microsoft.Usage", - "CA2214:DoNotCallOverridableMethodsInConstructors", - Scope = "member", - Target = "Xceed.Wpf.DataGrid.Views.FixedCellPanel..ctor()" )] - -[assembly: SuppressMessage( - "Microsoft.Usage", - "CA2214:DoNotCallOverridableMethodsInConstructors", - Scope = "member", - Target = "Xceed.Wpf.DataGrid.Views.ScrollingCellsDecorator..ctor(Xceed.Wpf.DataGrid.Views.FixedCellPanel)" )] - -[assembly: SuppressMessage( - "Microsoft.Usage", - "CA2214:DoNotCallOverridableMethodsInConstructors", - Scope = "member", - Target = "Xceed.Wpf.DataGrid.Views.DataGridScrollViewer..ctor()" )] - -[assembly: SuppressMessage( - "Microsoft.Usage", - "CA2214:DoNotCallOverridableMethodsInConstructors", - Scope = "member", - Target = "Xceed.Wpf.DataGrid.GroupConfiguration..ctor()" )] - -[assembly: SuppressMessage( - "Microsoft.Usage", - "CA2214:DoNotCallOverridableMethodsInConstructors", - Scope = "member", - Target = "Xceed.Wpf.DataGrid.DataGridContext..ctor(Xceed.Wpf.DataGrid.DataGridContext,Xceed.Wpf.DataGrid.DataGridControl,System.Object,System.Windows.Data.CollectionView,Xceed.Wpf.DataGrid.DetailConfiguration)" )] - -[assembly: SuppressMessage( - "Microsoft.Usage", - "CA2214:DoNotCallOverridableMethodsInConstructors", - Scope = "member", - Target = "Xceed.Wpf.DataGrid.DetailConfiguration..ctor(System.Boolean)" )] - -[assembly: SuppressMessage( - "Microsoft.Usage", - "CA2214:DoNotCallOverridableMethodsInConstructors", - Scope = "member", - Target = "Xceed.Wpf.DataGrid.DetailConfiguration..ctor(Xceed.Wpf.DataGrid.DataGridContext)" )] - -[assembly: SuppressMessage( - "Microsoft.Usage", - "CA2214:DoNotCallOverridableMethodsInConstructors", - Scope = "member", - Target = "Xceed.Wpf.DataGrid.SaveRestoreStateVisitor..ctor()" )] - -[assembly: SuppressMessage( - "Microsoft.Usage", - "CA2214:DoNotCallOverridableMethodsInConstructors", - Scope = "member", - Target = "Xceed.Wpf.DataGrid.DefaultDetailConfiguration..ctor()" )] - -#endregion CA2214:DoNotCallOverridableMethodsInConstructors diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Group.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Group.cs deleted file mode 100644 index 520278e3..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Group.cs +++ /dev/null @@ -1,717 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.Diagnostics; -using System.Globalization; -using System.Linq; -using System.Threading; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using Xceed.Wpf.DataGrid.Utils; - -namespace Xceed.Wpf.DataGrid -{ - public sealed class Group : IGroupLevelDescription, INotifyPropertyChanged, IWeakEventListener - { - #region Static Fields - - internal static readonly string IsExpandedPropertyName = PropertyHelper.GetPropertyName( ( Group g ) => g.IsExpanded ); - internal static readonly string ItemCountPropertyName = PropertyHelper.GetPropertyName( ( Group g ) => g.ItemCount ); - internal static readonly string GroupByPropertyName = PropertyHelper.GetPropertyName( ( Group g ) => g.GroupBy ); - internal static readonly string TitlePropertyName = PropertyHelper.GetPropertyName( ( Group g ) => g.Title ); - internal static readonly string TitleTemplatePropertyName = PropertyHelper.GetPropertyName( ( Group g ) => g.TitleTemplate ); - internal static readonly string TitleTemplateSelectorPropertyName = PropertyHelper.GetPropertyName( ( Group g ) => g.TitleTemplateSelector ); - internal static readonly string ValueTemplatePropertyName = PropertyHelper.GetPropertyName( ( Group g ) => g.ValueTemplate ); - internal static readonly string ValueTemplateSelectorPropertyName = PropertyHelper.GetPropertyName( ( Group g ) => g.ValueTemplateSelector ); - internal static readonly string ValueStringFormatPropertyName = PropertyHelper.GetPropertyName( ( Group g ) => g.ValueStringFormat ); - internal static readonly string ValueStringFormatCulturePropertyName = PropertyHelper.GetPropertyName( ( Group g ) => g.ValueStringFormatCulture ); - - #endregion - - internal Group( - GroupGeneratorNode node, - CollectionViewGroup group, - LateGroupLevelDescription groupLevelDescription, - DataGridContext dataGridContext ) - { - if( node == null ) - throw new ArgumentNullException( "node" ); - - if( group == null ) - throw new ArgumentNullException( "group" ); - - if( groupLevelDescription == null ) - throw new ArgumentNullException( "groupLevelDescription" ); - - if( dataGridContext == null ) - throw new ArgumentNullException( "dataGridContext" ); - - m_collectionViewGroup = group; - - // Initialization is done through setters to register for events. - this.DataGridContext = dataGridContext; - this.GeneratorNode = node; - this.GroupLevelDescription = groupLevelDescription; - } - - #region IsExpanded Property - - public bool IsExpanded - { - get - { - if( m_generatorNode != null ) - return m_generatorNode.IsExpanded; - - return false; - } - set - { - if( m_generatorNode == null ) - return; - - m_generatorNode.IsExpanded = value; - } - } - - internal bool IsComputedExpanded - { - get - { - if( m_generatorNode != null ) - return m_generatorNode.IsComputedExpanded; - - return false; - } - } - - #endregion - - #region Level Property - - public int Level - { - get - { - if( m_generatorNode != null ) - return m_generatorNode.Level; - - return -1; - } - } - - #endregion - - #region ItemCount Property - - public int ItemCount - { - get - { - if( m_generatorNode != null ) - return m_generatorNode.TotalLeafCount; - - return 0; - } - } - - #endregion - - #region ParentGroups Property - - public ReadOnlyCollection ParentGroups - { - get - { - if( m_generatorNode == null ) - return ( new List( 0 ) ).AsReadOnly(); - - var list = new List(); - var nodeHelper = new GeneratorNodeHelper( m_generatorNode, 0, 0 ); //index is not important - - while( nodeHelper.MoveToParent() ) - { - GroupGeneratorNode parentGroup = nodeHelper.CurrentNode as GroupGeneratorNode; - if( parentGroup == null ) - break; - - list.Insert( 0, parentGroup.UIGroup ); - } - - return list.AsReadOnly(); - } - } - - #endregion - - #region SiblingGroups Property - - public ReadOnlyCollection SiblingGroups - { - get - { - if( m_generatorNode == null ) - return null; - - var headersFootersGeneratorNode = HeadersFootersGeneratorNode.GetSameLevelFirstHeaderNode( m_generatorNode ); - if( headersFootersGeneratorNode == null ) - return null; - - var currentGeneratorContentGeneration = this.DataGridContext.CustomItemContainerGenerator.CurrentGeneratorContentGeneration; - return headersFootersGeneratorNode.GetImmediateUIGroups( currentGeneratorContentGeneration ); - } - } - - #endregion - - #region Value Property - - public object Value - { - get - { - if( m_collectionViewGroup != null ) - return m_collectionViewGroup.Name; - - return null; - } - } - - #endregion - - #region ValueStringFormat Property - - public string ValueStringFormat - { - get - { - var description = this.GroupLevelDescription; - if( description != null ) - return description.ValueStringFormat; - - return null; - } - } - - #endregion - - #region ValueStringFormatCulture Property - - public CultureInfo ValueStringFormatCulture - { - get - { - var description = this.GroupLevelDescription; - if( description != null ) - return description.ValueStringFormatCulture; - - return null; - } - } - - #endregion - - #region ValueTemplate Property - - public DataTemplate ValueTemplate - { - get - { - var description = this.GroupLevelDescription; - if( description != null ) - return description.ValueTemplate; - - return null; - } - } - - #endregion - - #region ValueTemplateSelector Property - - public DataTemplateSelector ValueTemplateSelector - { - get - { - var description = this.GroupLevelDescription; - if( description != null ) - return description.ValueTemplateSelector; - - return null; - } - } - - #endregion - - #region IsBottomLevel Property - - public bool IsBottomLevel - { - get - { - if( m_collectionViewGroup != null ) - return m_collectionViewGroup.IsBottomLevel; - - return true; - } - } - - #endregion - - #region Items Property [Obsoleted] - - [Obsolete( "The Items property is obsolete and has been replaced by the GroupExtensions.GetItems extensibility method.", false )] - public ReadOnlyObservableCollection Items - { - get - { - IList items = this.GetItems(); - - if( items is ReadOnlyObservableCollection ) - return ( ReadOnlyObservableCollection )items; - - return null; - } - } - - #endregion - - #region Title Property - - public object Title - { - get - { - var description = this.GroupLevelDescription; - if( description != null ) - return description.Title; - - return null; - } - } - - #endregion - - #region TitleTemplate Property - - public DataTemplate TitleTemplate - { - get - { - var description = this.GroupLevelDescription; - if( description != null ) - return description.TitleTemplate; - - return null; - } - } - - #endregion - - #region TitleTemplateSelector Property - - public DataTemplateSelector TitleTemplateSelector - { - get - { - var description = this.GroupLevelDescription; - if( description != null ) - return description.TitleTemplateSelector; - - return null; - } - } - - #endregion - - #region StatContext Property - - public object StatContext - { - get - { - return m_collectionViewGroup as DataGridCollectionViewGroup; - } - } - - #endregion - - #region GroupConfiguration Property - - public GroupConfiguration GroupConfiguration - { - get - { - if( m_generatorNode != null ) - return m_generatorNode.GroupConfiguration; - - return null; - } - } - - #endregion - - #region GeneratorNode Internal Property - - internal GroupGeneratorNode GeneratorNode - { - get - { - return m_generatorNode; - } - private set - { - if( value == m_generatorNode ) - return; - - if( m_generatorNode != null ) - { - this.UnregisterItemCountEvent( m_generatorNode ); - this.UnregisterIsExpandedEvent( m_generatorNode ); - } - - m_generatorNode = value; - - if( m_generatorNode != null ) - { - this.RegisterItemCountEvent( m_generatorNode, false ); - this.RegisterIsExpandedEvent( m_generatorNode, false ); - } - } - } - - private GroupGeneratorNode m_generatorNode; // = null - - #endregion - - #region GroupBy Internal Property - - internal string GroupBy - { - get - { - var description = this.GroupLevelDescription; - if( description != null ) - return description.FieldName; - - return string.Empty; - } - } - - #endregion - - #region DataGridContext Internal Property - - internal DataGridContext DataGridContext - { - get - { - return m_dataGridContext; - } - private set - { - m_dataGridContext = value; - } - } - - private DataGridContext m_dataGridContext; - - #endregion - - #region CollectionViewGroup Internal Property - - internal CollectionViewGroup CollectionViewGroup - { - get - { - return m_collectionViewGroup; - } - } - - private CollectionViewGroup m_collectionViewGroup; - - #endregion - - #region GroupDescription Private Property - - private GroupDescription GroupDescription - { - get - { - return m_groupDescription; - } - } - - private GroupDescription m_groupDescription; - - #endregion - - #region GroupLevelDescription Private Property - - private LateGroupLevelDescription GroupLevelDescription - { - get - { - return m_groupLevelDescription; - } - set - { - if( value == m_groupLevelDescription ) - return; - - if( m_groupLevelDescription != null ) - { - this.UnregisterGroupLevelDescriptionEvent( m_groupLevelDescription ); - } - - m_groupLevelDescription = value; - - if( m_groupLevelDescription != null ) - { - this.RegisterGroupLevelDescriptionEvent( m_groupLevelDescription, false ); - } - - this.OnGroupLevelDescriptionPropertyChanged(); - } - } - - private LateGroupLevelDescription m_groupLevelDescription; - - #endregion - - #region SyncRoot Private Property - - private object SyncRoot - { - get - { - if( m_syncRoot == null ) - { - Interlocked.CompareExchange( ref m_syncRoot, new object(), null ); - } - - return m_syncRoot; - } - } - - private object m_syncRoot; - - #endregion - - #region ItemCount Event Handling - - private void RegisterItemCountEvent( GroupGeneratorNode item, bool force ) - { - if( item == null ) - return; - - lock( this.SyncRoot ) - { - if( !force && ( m_propertyChanged == null ) ) - return; - - item.TotalLeafCountChanged += new EventHandler( this.OnItemCountChanged ); - } - } - - private void UnregisterItemCountEvent( GroupGeneratorNode item ) - { - if( item == null ) - return; - - item.TotalLeafCountChanged -= new EventHandler( this.OnItemCountChanged ); - } - - private void OnItemCountChanged( object sender, EventArgs e ) - { - this.OnPropertyChanged( Group.ItemCountPropertyName ); - } - - #endregion - - #region IsExpanded Event Handling - - private void RegisterIsExpandedEvent( GroupGeneratorNode item, bool force ) - { - if( item == null ) - return; - - lock( this.SyncRoot ) - { - if( !force && ( m_propertyChanged == null ) ) - return; - - item.IsExpandedChanged += new EventHandler( this.OnIsExpandedChanged ); - } - } - - private void UnregisterIsExpandedEvent( GroupGeneratorNode item ) - { - if( item == null ) - return; - - item.IsExpandedChanged -= new EventHandler( this.OnIsExpandedChanged ); - } - - private void OnIsExpandedChanged( object sender, EventArgs e ) - { - this.OnPropertyChanged( Group.IsExpandedPropertyName ); - } - - #endregion - - #region GroupLevelDescription Event Handling - - private void RegisterGroupLevelDescriptionEvent( LateGroupLevelDescription item, bool force ) - { - if( item == null ) - return; - - lock( this.SyncRoot ) - { - if( !force && ( m_propertyChanged == null ) ) - return; - - item.PropertyChanged += new PropertyChangedEventHandler( this.OnGroupLevelDescriptionChanged ); - } - } - - private void UnregisterGroupLevelDescriptionEvent( LateGroupLevelDescription item ) - { - if( item == null ) - return; - - item.PropertyChanged -= new PropertyChangedEventHandler( this.OnGroupLevelDescriptionChanged ); - } - - private void OnGroupLevelDescriptionChanged( object sender, PropertyChangedEventArgs e ) - { - if( string.IsNullOrEmpty( e.PropertyName ) ) - { - this.OnGroupLevelDescriptionPropertyChanged(); - } - else - { - // Simply relay this property changed to this Group instance. - this.OnPropertyChanged( e.PropertyName ); - } - } - - private void OnGroupLevelDescriptionPropertyChanged() - { - this.OnPropertyChanged( Group.GroupByPropertyName ); - this.OnPropertyChanged( Group.TitlePropertyName ); - this.OnPropertyChanged( Group.TitleTemplatePropertyName ); - this.OnPropertyChanged( Group.TitleTemplateSelectorPropertyName ); - this.OnPropertyChanged( Group.ValueTemplatePropertyName ); - this.OnPropertyChanged( Group.ValueTemplateSelectorPropertyName ); - this.OnPropertyChanged( Group.ValueStringFormatPropertyName ); - this.OnPropertyChanged( Group.ValueStringFormatCulturePropertyName ); - } - - #endregion - - internal void ClearGroup() - { - m_groupDescription = null; - m_collectionViewGroup = null; - m_propertyChanged = null; - - this.DataGridContext = null; - this.GeneratorNode = null; - this.GroupLevelDescription = null; - } - - #region IGroupLevelDescription Members - - string IGroupLevelDescription.FieldName - { - get - { - return this.GroupBy; - } - } - - #endregion - - #region INotifyPropertyChanged Members - - public event PropertyChangedEventHandler PropertyChanged - { - add - { - lock( this.SyncRoot ) - { - if( m_propertyChanged == null ) - { - this.RegisterItemCountEvent( this.GeneratorNode, true ); - this.RegisterIsExpandedEvent( this.GeneratorNode, true ); - this.RegisterGroupLevelDescriptionEvent( this.GroupLevelDescription, true ); - } - - m_propertyChanged += value; - } - } - remove - { - lock( this.SyncRoot ) - { - m_propertyChanged -= value; - - if( m_propertyChanged == null ) - { - this.UnregisterItemCountEvent( this.GeneratorNode ); - this.UnregisterIsExpandedEvent( this.GeneratorNode ); - this.UnregisterGroupLevelDescriptionEvent( this.GroupLevelDescription ); - } - } - } - } - - private PropertyChangedEventHandler m_propertyChanged; - - private void OnPropertyChanged( string propertyName ) - { - var handler = m_propertyChanged; - if( handler == null ) - return; - - handler.Invoke( this, new PropertyChangedEventArgs( propertyName ) ); - } - - #endregion - - #region IWeakEventListener Members - - bool IWeakEventListener.ReceiveWeakEvent( Type managerType, object sender, EventArgs e ) - { - return this.OnReceiveWeakEvent( managerType, sender, e ); - } - - private bool OnReceiveWeakEvent( Type managerType, object sender, EventArgs e ) - { - return false; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupByControl.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupByControl.cs deleted file mode 100644 index b6f28807..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupByControl.cs +++ /dev/null @@ -1,428 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Diagnostics; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Media; -using Xceed.Utils.Wpf.DragDrop; -using Xceed.Wpf.DataGrid.Views; - -namespace Xceed.Wpf.DataGrid -{ - public class GroupByControl : ItemsControl, IDropTarget - { - static GroupByControl() - { - // This DefaultStyleKey will only be used in design-time. - DefaultStyleKeyProperty.OverrideMetadata( typeof( GroupByControl ), new FrameworkPropertyMetadata( new Markup.ThemeKey( typeof( Views.TableView ), typeof( GroupByControl ) ) ) ); - - FrameworkElementFactory staircaseFactory = new FrameworkElementFactory( typeof( StaircasePanel ) ); - ItemsPanelTemplate itemsPanelTemplate = new ItemsPanelTemplate( staircaseFactory ); - RelativeSource ancestorSource = new RelativeSource( RelativeSourceMode.FindAncestor, typeof( GroupByControl ), 1 ); - - Binding binding = new Binding(); - binding.Path = new PropertyPath( GroupByControl.ConnectionLineAlignmentProperty ); - binding.Mode = BindingMode.OneWay; - binding.RelativeSource = ancestorSource; - staircaseFactory.SetBinding( StaircasePanel.ConnectionLineAlignmentProperty, binding ); - - binding = new Binding(); - binding.Path = new PropertyPath( GroupByControl.ConnectionLineOffsetProperty ); - binding.Mode = BindingMode.OneWay; - binding.RelativeSource = ancestorSource; - staircaseFactory.SetBinding( StaircasePanel.ConnectionLineOffsetProperty, binding ); - - binding = new Binding(); - binding.Path = new PropertyPath( GroupByControl.ConnectionLinePenProperty ); - binding.Mode = BindingMode.OneWay; - binding.RelativeSource = ancestorSource; - staircaseFactory.SetBinding( StaircasePanel.ConnectionLinePenProperty, binding ); - - binding = new Binding(); - binding.Path = new PropertyPath( GroupByControl.StairHeightProperty ); - binding.Mode = BindingMode.OneWay; - binding.RelativeSource = ancestorSource; - staircaseFactory.SetBinding( StaircasePanel.StairHeightProperty, binding ); - - binding = new Binding(); - binding.Path = new PropertyPath( GroupByControl.StairSpacingProperty ); - binding.Mode = BindingMode.OneWay; - binding.RelativeSource = ancestorSource; - staircaseFactory.SetBinding( StaircasePanel.StairSpacingProperty, binding ); - - itemsPanelTemplate.Seal(); - - ItemsControl.ItemsPanelProperty.OverrideMetadata( typeof( GroupByControl ), new FrameworkPropertyMetadata( itemsPanelTemplate ) ); - - DataGridControl.ParentDataGridControlPropertyKey.OverrideMetadata( typeof( GroupByControl ), new FrameworkPropertyMetadata( new PropertyChangedCallback( GroupByControl.ParentGridControlChangedCallback ) ) ); - DataGridControl.DataGridContextPropertyKey.OverrideMetadata( typeof( GroupByControl ), new FrameworkPropertyMetadata( new PropertyChangedCallback( GroupByControl.DataGridContextChangedCallback ) ) ); - - FocusableProperty.OverrideMetadata( typeof( GroupByControl ), new FrameworkPropertyMetadata( false ) ); - } - - #region AllowGroupingModification Property - - public static readonly DependencyProperty AllowGroupingModificationProperty = - DependencyProperty.Register( "AllowGroupingModification", typeof( bool ), typeof( GroupByControl ), new UIPropertyMetadata( true ) ); - - public bool AllowGroupingModification - { - get - { - return ( bool )this.GetValue( GroupByControl.AllowGroupingModificationProperty ); - } - set - { - this.SetValue( GroupByControl.AllowGroupingModificationProperty, value ); - } - } - - #endregion AllowGroupingModification Property - - #region AllowSort Property - - public static readonly DependencyProperty AllowSortProperty = - ColumnManagerRow.AllowSortProperty.AddOwner( typeof( GroupByControl ), new UIPropertyMetadata( true ) ); - - public bool AllowSort - { - get - { - return ( bool )this.GetValue( GroupByControl.AllowSortProperty ); - } - set - { - this.SetValue( GroupByControl.AllowSortProperty, value ); - } - } - - #endregion AllowSort Property - - #region ConnectionLineAlignment Property - - public static readonly DependencyProperty ConnectionLineAlignmentProperty = - StaircasePanel.ConnectionLineAlignmentProperty.AddOwner( typeof( GroupByControl ) ); - - public ConnectionLineAlignment ConnectionLineAlignment - { - get - { - return ( ConnectionLineAlignment )this.GetValue( GroupByControl.ConnectionLineAlignmentProperty ); - } - set - { - this.SetValue( GroupByControl.ConnectionLineAlignmentProperty, value ); - } - } - - #endregion ConnectionLineAlignment Property - - #region ConnectionLineOffset Property - - public static readonly DependencyProperty ConnectionLineOffsetProperty = - StaircasePanel.ConnectionLineOffsetProperty.AddOwner( typeof( GroupByControl ) ); - - public double ConnectionLineOffset - { - get - { - return ( double )this.GetValue( GroupByControl.ConnectionLineOffsetProperty ); - } - set - { - this.SetValue( GroupByControl.ConnectionLineOffsetProperty, value ); - } - } - - #endregion ConnectionLineOffset Property - - #region ConnectionLinePen Property - - public static readonly DependencyProperty ConnectionLinePenProperty = - StaircasePanel.ConnectionLinePenProperty.AddOwner( typeof( GroupByControl ) ); - - public Pen ConnectionLinePen - { - get - { - return ( Pen )this.GetValue( GroupByControl.ConnectionLinePenProperty ); - } - set - { - this.SetValue( GroupByControl.ConnectionLinePenProperty, value ); - } - } - - #endregion ConnectionLinePen Property - - #region StairHeight Property - - public static readonly DependencyProperty StairHeightProperty = - StaircasePanel.StairHeightProperty.AddOwner( typeof( GroupByControl ) ); - - public double StairHeight - { - get - { - return ( double )this.GetValue( GroupByControl.StairHeightProperty ); - } - set - { - this.SetValue( GroupByControl.StairHeightProperty, value ); - } - } - - #endregion StairHeight Property - - #region StairSpacing Property - - public static readonly DependencyProperty StairSpacingProperty = - StaircasePanel.StairSpacingProperty.AddOwner( typeof( GroupByControl ) ); - - public double StairSpacing - { - get - { - return ( double )this.GetValue( GroupByControl.StairSpacingProperty ); - } - set - { - this.SetValue( GroupByControl.StairSpacingProperty, value ); - } - } - - #endregion StairSpacing Property - - #region NoGroupContent Property - - public static readonly DependencyProperty NoGroupContentProperty = - DependencyProperty.Register( - "NoGroupContent", - typeof( object ), - typeof( GroupByControl ), - new PropertyMetadata( "Drag a column header here to group by that column." ) ); - - public object NoGroupContent - { - get - { - return this.GetValue( GroupByControl.NoGroupContentProperty ); - } - set - { - this.SetValue( GroupByControl.NoGroupContentProperty, value ); - } - } - - #endregion NoGroupContent Property - - protected override DependencyObject GetContainerForItemOverride() - { - return new GroupByItem(); - } - - protected override bool IsItemItsOwnContainerOverride( object item ) - { - return ( item is GroupByItem ); - } - - protected override void PrepareContainerForItemOverride( DependencyObject element, object item ) - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - DataGridControl grid = ( dataGridContext != null ) - ? dataGridContext.DataGridControl - : null; - - base.PrepareContainerForItemOverride( element, item ); - - if( grid != null ) - { - GroupByItem groupByItem = ( GroupByItem )element; - groupByItem.PrepareDefaultStyleKey( grid.GetView() ); - } - } - - protected internal virtual void PrepareDefaultStyleKey( Xceed.Wpf.DataGrid.Views.ViewBase view ) - { - this.DefaultStyleKey = view.GetDefaultStyleKey( typeof( GroupByControl ) ); - } - - internal bool IsGroupingModificationAllowed - { - get - { - bool allowGroupingModification = this.AllowGroupingModification; - - if( allowGroupingModification ) - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - if( dataGridContext == null ) - { - allowGroupingModification = false; - } - else - { - allowGroupingModification = dataGridContext.Items.CanGroup; - } - } - - return allowGroupingModification; - } - } - - private void RegisterParentDataGridContext( DataGridContext dataGridContext ) - { - if( dataGridContext == null ) - { - this.ItemsSource = null; - } - else - { - this.ItemsSource = dataGridContext.GroupLevelDescriptions; - } - } - - private static void ParentGridControlChangedCallback( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - DataGridControl grid = e.NewValue as DataGridControl; - GroupByControl panel = ( GroupByControl )sender; - - if( grid != null ) - panel.PrepareDefaultStyleKey( grid.GetView() ); - } - - private static void DataGridContextChangedCallback( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - DataGridContext dataGridContext = e.NewValue as DataGridContext; - GroupByControl panel = ( GroupByControl )sender; - - if( dataGridContext != null ) - panel.RegisterParentDataGridContext( dataGridContext ); - } - - #region IDropTarget Members - - bool IDropTarget.CanDropElement( UIElement draggedElement, RelativePoint mousePosition ) - { - var isAlreadyGroupedBy = false; - var cell = draggedElement as ColumnManagerCell; - - if( cell != null ) - { - isAlreadyGroupedBy = GroupingHelper.IsAlreadyGroupedBy( cell ); - - var parentColumn = cell.ParentColumn; - if( ( parentColumn == null ) || ( !parentColumn.AllowGroup ) ) - return false; - } - - var sourceDetailContext = DataGridControl.GetDataGridContext( this ); - Debug.Assert( sourceDetailContext != null ); - var sourceDetailConfig = ( sourceDetailContext != null ) ? sourceDetailContext.SourceDetailConfiguration : null; - - var draggedElementContext = DataGridControl.GetDataGridContext( draggedElement ); - Debug.Assert( draggedElementContext != null ); - var draggedDetailConfig = ( draggedElementContext != null ) ? draggedElementContext.SourceDetailConfiguration : null; - - - var canDrop = ( sourceDetailConfig == draggedDetailConfig ) && - ( sourceDetailContext != null ) && - ( draggedElementContext != null ) && - ( sourceDetailContext.GroupLevelDescriptions == draggedElementContext.GroupLevelDescriptions ) && - ( this.IsGroupingModificationAllowed ) && - ( ( draggedElement is ColumnManagerCell ) || ( draggedElement is GroupByItem ) ) && - ( !isAlreadyGroupedBy ); - - if( canDrop && ( cell != null ) ) - { - canDrop = GroupingHelper.ValidateMaxGroupDescriptions( draggedElementContext ); - } - - return canDrop; - } - - void IDropTarget.DragEnter( UIElement draggedElement ) - { - } - - void IDropTarget.DragOver( UIElement draggedElement, RelativePoint mousePosition ) - { - var cell = draggedElement as ColumnManagerCell; - if( cell == null ) - return; - - var draggedElementContext = DataGridControl.GetDataGridContext( draggedElement ); - var lastIndex = draggedElementContext.GroupLevelDescriptions.Count - 1; - if( lastIndex < 0 ) - return; - - var groupByItem = this.ItemContainerGenerator.ContainerFromIndex( lastIndex ) as GroupByItem; - if( groupByItem == null ) - throw new DataGridInternalException( "groupByItem is null." ); - - groupByItem.ShowDropMark( mousePosition ); - } - - void IDropTarget.DragLeave( UIElement draggedElement ) - { - var cell = draggedElement as ColumnManagerCell; - if( cell == null ) - return; - - var draggedElementContext = DataGridControl.GetDataGridContext( draggedElement ); - var lastIndex = draggedElementContext.GroupLevelDescriptions.Count - 1; - if( lastIndex < 0 ) - return; - - var groupByItem = this.ItemContainerGenerator.ContainerFromIndex( lastIndex ) as GroupByItem; - if( groupByItem == null ) - throw new DataGridInternalException( "groupByItem is null." ); - - groupByItem.HideDropMark(); - } - - void IDropTarget.Drop( UIElement draggedElement, RelativePoint mousePosition ) - { - var cell = draggedElement as ColumnManagerCell; - if( cell == null ) - return; - - var draggedElementContext = DataGridControl.GetDataGridContext( draggedElement ); - var lastIndex = draggedElementContext.GroupLevelDescriptions.Count - 1; - - if( lastIndex >= 0 ) - { - var groupByItem = this.ItemContainerGenerator.ContainerFromIndex( lastIndex ) as GroupByItem; - if( groupByItem == null ) - throw new DataGridInternalException( "groupByItem is null." ); - - groupByItem.HideDropMark(); - } - - var dataGridContext = DataGridControl.GetDataGridContext( this ); - var dataGridControl = ( dataGridContext != null ) ? dataGridContext.DataGridControl : null; - - GroupingHelper.AppendNewGroupFromColumnManagerCell( cell, dataGridControl ); - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupByItem.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupByItem.cs deleted file mode 100644 index 6bb2ba89..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupByItem.cs +++ /dev/null @@ -1,547 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Text; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Documents; -using System.Windows.Media; -using System.ComponentModel; -using System.Windows.Input; -using System.Windows.Data; -using System.Collections.ObjectModel; -using System.Windows.Controls.Primitives; -using System.Windows.Resources; -using System.Security; -using Xceed.Wpf.DataGrid.Views; - -using Xceed.Utils.Wpf.DragDrop; -using Xceed.Utils.Wpf; - -namespace Xceed.Wpf.DataGrid -{ - public class GroupByItem : ButtonBase, IDropTarget, INotifyPropertyChanged - { - #region PUBLIC CONSTRUCTORS - - static GroupByItem() - { - // This DefaultStyleKey will only be used in design-time. - DefaultStyleKeyProperty.OverrideMetadata( typeof( GroupByItem ), new FrameworkPropertyMetadata( new Markup.ThemeKey( typeof( Views.TableView ), typeof( GroupByItem ) ) ) ); - - GroupByItem.IsBeingDraggedProperty = GroupByItem.IsBeingDraggedPropertyKey.DependencyProperty; - - FocusableProperty.OverrideMetadata( typeof( GroupByItem ), new FrameworkPropertyMetadata( false ) ); - } - - #endregion - - #region SortDirection Property - - // Only used to bind between Column and us, but we don't want to expose it publicly - private static readonly DependencyProperty SortDirectionInternalProperty = - DependencyProperty.Register( "SortDirectionInternal", typeof( SortDirection ), typeof( GroupByItem ), new PropertyMetadata( SortDirection.None, new PropertyChangedCallback( GroupByItem.OnSortDirectionInternalChanged ) ) ); - - public SortDirection SortDirection - { - get - { - return ( SortDirection )this.GetValue( GroupByItem.SortDirectionInternalProperty ); - } - } - - private static void OnSortDirectionInternalChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - GroupByItem groupByItem = ( GroupByItem )sender; - groupByItem.OnPropertyChanged( new PropertyChangedEventArgs( "SortDirection" ) ); - } - - #endregion SortDirection Property - - #region IsBeingDragged Read-Only Property - - private static readonly DependencyPropertyKey IsBeingDraggedPropertyKey = - DependencyProperty.RegisterReadOnly( "IsBeingDragged", typeof( bool ), typeof( GroupByItem ), new PropertyMetadata( false ) ); - - public static readonly DependencyProperty IsBeingDraggedProperty; - - public bool IsBeingDragged - { - get - { - return ( bool )this.GetValue( GroupByItem.IsBeingDraggedProperty ); - } - } - - private void SetIsBeingDragged( bool value ) - { - this.SetValue( GroupByItem.IsBeingDraggedPropertyKey, value ); - } - - #endregion IsBeingDragged Read-Only Property - - #region PUBLIC METHODS - - public override void OnApplyTemplate() - { - base.OnApplyTemplate(); - this.InitSortDirection(); - this.SetupDragManager(); - } - - #endregion - - #region PROTECTED METHODS - - protected internal virtual void PrepareDefaultStyleKey( Xceed.Wpf.DataGrid.Views.ViewBase view ) - { - this.DefaultStyleKey = view.GetDefaultStyleKey( typeof( GroupByItem ) ); - } - - #endregion - - #region PRIVATE METHODS - - private void InitSortDirection() - { - var dataGridContext = DataGridControl.GetDataGridContext( this ); - if( dataGridContext == null ) - return; - - var groupInfo = this.Content as GroupLevelDescription; - if( groupInfo == null ) - return; - - var column = dataGridContext.Columns[ groupInfo.FieldName ]; - if( column == null ) - return; - - var sortBinding = new Binding(); - sortBinding.Path = new PropertyPath( ColumnBase.SortDirectionProperty ); - sortBinding.Mode = BindingMode.OneWay; - sortBinding.NotifyOnSourceUpdated = true; - sortBinding.Source = column; - sortBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged; - - BindingOperations.SetBinding( this, GroupByItem.SortDirectionInternalProperty, sortBinding ); - } - - private GroupByControl GetParentGroupByControl() - { - DependencyObject parent = TreeHelper.GetParent( this ); - - while( parent != null ) - { - if( parent is GroupByControl ) - break; - - parent = TreeHelper.GetParent( parent ); - } - - return parent as GroupByControl; - } - - #endregion - - #region Drag & Drop Manager - - private void SetupDragManager() - { - // We do not support DragDrop when there are no AdornerLayer because there wouldn't - // be any visual feedback for the operation. - if( AdornerLayer.GetAdornerLayer( this ) == null ) - return; - - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - DataGridControl dataGridControl = ( dataGridContext != null ) - ? dataGridContext.DataGridControl - : null; - - // Can be null in design-time (edition of a style TargetType GroupByItem). - if( dataGridControl == null ) - return; - - Debug.Assert( m_dragSourceManager == null, "There might be problems when there is already a m_dragSourceManager." ); - - if( m_dragSourceManager != null ) - { - m_dragSourceManager.PropertyChanged -= new PropertyChangedEventHandler( m_dragSourceManager_PropertyChanged ); - m_dragSourceManager.DragOutsideQueryCursor -= new QueryCursorEventHandler( m_dragSourceManager_DragOutsideQueryCursor ); - m_dragSourceManager.DroppedOutside -= new EventHandler( m_dragSourceManager_DroppedOutside ); - } - - // The DataGridControl's AdornerDecoratorForDragAndDrop must be used for dragging in order to include the - // RenderTransform the DataGridControl may performs. This AdornerDecorator is defined in the ControlTemplate - // as PART_DragDropAdornerDecorator - if( ( dataGridControl.DragDropAdornerDecorator != null ) - && ( dataGridControl.DragDropAdornerDecorator.AdornerLayer != null ) ) - { - m_dragSourceManager = new DragSourceManager( this, dataGridControl.DragDropAdornerDecorator.AdornerLayer, dataGridControl ); - } - else - { - System.Diagnostics.Debug.Assert( false, "The drag and drop functionnality won't be fully working properly: PART_DragDropAdornerDecorator was not found" ); - m_dragSourceManager = new DragSourceManager( this, null, dataGridControl ); - } - - m_dragSourceManager.PropertyChanged += new PropertyChangedEventHandler( m_dragSourceManager_PropertyChanged ); - m_dragSourceManager.DragOutsideQueryCursor += new QueryCursorEventHandler( m_dragSourceManager_DragOutsideQueryCursor ); - m_dragSourceManager.DroppedOutside += new EventHandler( m_dragSourceManager_DroppedOutside ); - } - - void m_dragSourceManager_DroppedOutside( object sender, EventArgs e ) - { - bool allowGroupingModification = true; - GroupByControl parentGBC = this.GetParentGroupByControl(); - - if( parentGBC != null ) - allowGroupingModification = parentGBC.IsGroupingModificationAllowed; - - if( allowGroupingModification ) - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - Debug.Assert( dataGridContext != null ); - - if( dataGridContext != null ) - { - GroupingHelper.RemoveGroupDescription( - dataGridContext.Items.GroupDescriptions, - this.Content as GroupLevelDescription, - dataGridContext.DataGridControl ); - } - } - } - - void m_dragSourceManager_PropertyChanged( object sender, PropertyChangedEventArgs e ) - { - if( e.PropertyName == "IsDragging" ) - { - this.SetIsBeingDragged( m_dragSourceManager.IsDragging ); - } - } - - private void m_dragSourceManager_DragOutsideQueryCursor( object sender, QueryCursorEventArgs e ) - { - GroupByControl parentGBC = this.GetParentGroupByControl(); - - if( ( parentGBC == null ) || !parentGBC.IsGroupingModificationAllowed ) - return; - - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - if( ( dataGridContext != null ) && ( dataGridContext.DataGridControl != null ) ) - { - UIViewBase uiViewBase = dataGridContext.DataGridControl.GetView() as UIViewBase; - - e.Cursor = ( uiViewBase != null ) - ? uiViewBase.RemovingGroupCursor - : UIViewBase.DefaultGroupDraggedOutsideCursor; - } - else - { - e.Cursor = UIViewBase.DefaultGroupDraggedOutsideCursor; - } - } - - protected override void OnMouseLeftButtonDown( MouseButtonEventArgs e ) - { - if( this.CaptureMouse() ) - { - if( m_dragSourceManager != null ) - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - if( dataGridContext != null ) - { - // Update the DropOutsideCursor since it is defined on the View - UIViewBase uiViewBase = dataGridContext.DataGridControl.GetView() as UIViewBase; - - m_dragSourceManager.DropOutsideCursor = ( uiViewBase != null ) - ? uiViewBase.RemovingGroupCursor - : UIViewBase.DefaultGroupDraggedOutsideCursor; - } - - m_dragSourceManager.DragStart( e ); - } - - e.Handled = true; - } - - base.OnMouseLeftButtonDown( e ); - } - - protected override void OnMouseMove( MouseEventArgs e ) - { - if( ( this.IsMouseCaptured ) && ( e.LeftButton == MouseButtonState.Pressed ) ) - { - if( m_dragSourceManager != null ) - { - m_dragSourceManager.DragMove( e ); - } - } - - base.OnMouseMove( e ); - } - - protected override void OnMouseLeftButtonUp( MouseButtonEventArgs e ) - { - bool isMouseCaptured = this.IsMouseCaptured; - bool isPressed = this.IsPressed; - - if( m_dragSourceManager != null ) - { - m_dragSourceManager.Drop( e ); - } - - if( isMouseCaptured ) - { - this.ReleaseMouseCapture(); - - bool click = isPressed; - - if( click ) - { - bool allowSort = true; - GroupByControl parentGBC = this.GetParentGroupByControl(); - - if( parentGBC != null ) - allowSort = parentGBC.AllowSort; - - if( allowSort ) - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - GroupLevelDescription groupInfo = this.Content as GroupLevelDescription; - Debug.Assert( ( dataGridContext != null ) && ( groupInfo != null ) ); - - if( ( dataGridContext != null ) && ( groupInfo != null ) ) - { - ColumnBase column = dataGridContext.Columns[ groupInfo.FieldName ]; - - if( ( column != null ) && ( column.AllowSort ) ) - { - bool shiftUnpressed = ( ( Keyboard.Modifiers & ModifierKeys.Shift ) != ModifierKeys.Shift ); - - var toggleColumnSort = dataGridContext.ToggleColumnSortCommand; - if( toggleColumnSort.CanExecute( column, shiftUnpressed ) ) - { - toggleColumnSort.Execute( column, shiftUnpressed ); - } - - e.Handled = true; - } - } - } - } - } - - base.OnMouseLeftButtonUp( e ); - } - - protected override void OnLostMouseCapture( MouseEventArgs e ) - { - if( m_dragSourceManager != null ) - { - m_dragSourceManager.DragCancel( e ); - } - - base.OnLostMouseCapture( e ); - } - - internal void ShowDropMark( RelativePoint mousePosition ) - { - if( m_dropMarkAdorner == null ) - { - var dataGridContext = DataGridControl.GetDataGridContext( this ); - var dataGridControl = ( dataGridContext != null ) ? dataGridContext.DataGridControl : null; - var pen = UIViewBase.GetDropMarkPen( this ); - - if( ( pen == null ) && ( dataGridControl != null ) ) - { - var uiViewBase = dataGridControl.GetView() as UIViewBase; - if( uiViewBase != null ) - { - pen = uiViewBase.DefaultDropMarkPen; - } - } - - var orientation = UIViewBase.GetDropMarkOrientation( this ); - - if( ( orientation == DropMarkOrientation.Default ) && ( dataGridControl != null ) ) - { - var uiViewBase = dataGridControl.GetView() as UIViewBase; - if( uiViewBase != null ) - { - orientation = uiViewBase.DefaultDropMarkOrientation; - } - } - - m_dropMarkAdorner = new DropMarkAdorner( this, pen, orientation ); - - var adornerLayer = AdornerLayer.GetAdornerLayer( this ); - if( adornerLayer != null ) - { - adornerLayer.Add( m_dropMarkAdorner ); - } - } - - m_dropMarkAdorner.UpdateAlignment( mousePosition ); - } - - internal void HideDropMark() - { - if( m_dropMarkAdorner == null ) - return; - - var adornerLayer = AdornerLayer.GetAdornerLayer( this ); - if( adornerLayer != null ) - { - adornerLayer.Remove( m_dropMarkAdorner ); - } - - m_dropMarkAdorner = null; - } - - #endregion Drag & Drop Manager - - #region IDropTarget Members - - bool IDropTarget.CanDropElement( UIElement draggedElement, RelativePoint mousePosition ) - { - var allowGroupingModification = true; - var parentGBC = this.GetParentGroupByControl(); - - if( parentGBC != null ) - { - allowGroupingModification = parentGBC.IsGroupingModificationAllowed; - } - - // We don't accept any ColumnManagerCell from Details - var context = DataGridControl.GetDataGridContext( draggedElement ); - var cell = draggedElement as ColumnManagerCell; - var isAlreadyGroupedBy = false; - - if( cell != null ) - { - isAlreadyGroupedBy = GroupingHelper.IsAlreadyGroupedBy( cell ); - - var parentColumn = cell.ParentColumn; - if( ( parentColumn == null ) || ( !parentColumn.AllowGroup ) ) - return false; - } - - var sourceDetailContext = DataGridControl.GetDataGridContext( this ); - Debug.Assert( sourceDetailContext != null ); - var sourceDetailConfig = ( sourceDetailContext != null ) ? sourceDetailContext.SourceDetailConfiguration : null; - - var draggedDetailContext = DataGridControl.GetDataGridContext( draggedElement ); - Debug.Assert( draggedDetailContext != null ); - var draggedDetailConfig = ( draggedDetailContext != null ) ? draggedDetailContext.SourceDetailConfiguration : null; - - - var canDrop = ( sourceDetailConfig == draggedDetailConfig ) && - ( allowGroupingModification ) && - ( ( draggedElement is ColumnManagerCell ) || ( draggedElement is GroupByItem ) ) && - ( draggedElement != this ) && - ( isAlreadyGroupedBy == false ); - - if( canDrop && ( cell != null ) ) - { - canDrop = GroupingHelper.ValidateMaxGroupDescriptions( draggedDetailContext ); - } - - return canDrop; - } - - void IDropTarget.DragEnter( UIElement draggedElement ) - { - } - - void IDropTarget.DragOver( UIElement draggedElement, RelativePoint mousePosition ) - { - this.ShowDropMark( mousePosition ); - } - - void IDropTarget.DragLeave( UIElement draggedElement ) - { - this.HideDropMark(); - } - - void IDropTarget.Drop( UIElement draggedElement, RelativePoint mousePosition ) - { - if( m_dropMarkAdorner == null ) - return; - - var dataGridContext = DataGridControl.GetDataGridContext( this ); - if( dataGridContext == null ) - return; - - var draggedOverGroupLevelDescription = this.Content as GroupLevelDescription; - if( draggedOverGroupLevelDescription == null ) - return; - - var alignment = m_dropMarkAdorner.Alignment; - - this.HideDropMark(); - - var draggedCell = draggedElement as ColumnManagerCell; - if( draggedCell != null ) - { - GroupingHelper.AddNewGroupFromColumnManagerCell( draggedCell, draggedOverGroupLevelDescription, alignment, dataGridContext.DataGridControl ); - } - else - { - var draggedGroupBy = draggedElement as GroupByItem; - - Debug.Assert( draggedGroupBy != null ); - - if( draggedGroupBy != null ) - { - var draggedGroupLevelDescription = draggedGroupBy.Content as GroupLevelDescription; - - GroupingHelper.MoveGroupDescription( dataGridContext.Columns, dataGridContext.Items.GroupDescriptions, draggedOverGroupLevelDescription, alignment, draggedGroupLevelDescription, dataGridContext.DataGridControl ); - } - } - } - - #endregion - - #region INotifyPropertyChanged Members - - protected virtual void OnPropertyChanged( PropertyChangedEventArgs e ) - { - if( this.PropertyChanged != null ) - this.PropertyChanged( this, e ); - } - - public event PropertyChangedEventHandler PropertyChanged; - - #endregion - - #region PRIVATE FIELDS - - /// - /// Will remain null when no AdornerLayer is found. - /// - private DragSourceManager m_dragSourceManager; - private DropMarkAdorner m_dropMarkAdorner; - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupConfiguration.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupConfiguration.cs deleted file mode 100644 index db2f7812..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupConfiguration.cs +++ /dev/null @@ -1,247 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Collections.ObjectModel; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media; -using System.ComponentModel; -using System; -using System.Windows.Data; - -namespace Xceed.Wpf.DataGrid -{ - public class GroupConfiguration : Freezable - { - static GroupConfiguration() - { - GroupConfiguration.HeadersProperty = GroupConfiguration.HeadersPropertyKey.DependencyProperty; - GroupConfiguration.FootersProperty = GroupConfiguration.FootersPropertyKey.DependencyProperty; - - DefaultHeaderTemplate = new GroupHeaderFooterItemTemplate(); - DefaultHeaderTemplate.VisibleWhenCollapsed = true; - DefaultHeaderTemplate.Template = new DataTemplate(); - DefaultHeaderTemplate.Template.VisualTree = new FrameworkElementFactory( typeof( GroupHeaderControl ) ); - DefaultHeaderTemplate.Template.Seal(); - DefaultHeaderTemplate.Seal(); - - DefaultGroupConfiguration = new GroupConfiguration(); - DefaultGroupConfiguration.AddDefaultHeadersFooters(); - DefaultGroupConfiguration.Freeze(); - } - - internal static readonly GroupConfiguration DefaultGroupConfiguration; - - public GroupConfiguration() - { - this.SetHeaders( new GroupHeaderFooterCollection() ); - this.SetFooters( new GroupHeaderFooterCollection() ); - } - - #region Headers Read-Only Property - - private static readonly DependencyPropertyKey HeadersPropertyKey = - DependencyProperty.RegisterReadOnly( "Headers", typeof( ObservableCollection ), typeof( GroupConfiguration ), new PropertyMetadata( null ) ); - - public static readonly DependencyProperty HeadersProperty; - - public ObservableCollection Headers - { - get - { - return ( ObservableCollection )this.GetValue( GroupConfiguration.HeadersProperty ); - } - } - - private void SetHeaders( ObservableCollection value ) - { - this.SetValue( GroupConfiguration.HeadersPropertyKey, value ); - } - - #endregion Headers Read-Only Property - - #region Footers Read-Only Property - - private static readonly DependencyPropertyKey FootersPropertyKey = - DependencyProperty.RegisterReadOnly( "Footers", typeof( ObservableCollection ), typeof( GroupConfiguration ), new PropertyMetadata( null ) ); - - public static readonly DependencyProperty FootersProperty; - - public ObservableCollection Footers - { - get - { - return ( ObservableCollection )this.GetValue( GroupConfiguration.FootersProperty ); - } - } - - private void SetFooters( ObservableCollection value ) - { - this.SetValue( GroupConfiguration.FootersPropertyKey, value ); - } - - #endregion Footers Read-Only Property - - #region InitiallyExpanded Property - - public static readonly DependencyProperty InitiallyExpandedProperty = - DependencyProperty.Register( "InitiallyExpanded", typeof( bool ), typeof( GroupConfiguration ), new UIPropertyMetadata( true ) ); - - public bool InitiallyExpanded - { - get - { - return ( bool )this.GetValue( GroupConfiguration.InitiallyExpandedProperty ); - } - set - { - this.SetValue( GroupConfiguration.InitiallyExpandedProperty, value ); - } - } - - #endregion InitiallyExpanded Property - - #region ItemContainerStyle Property - - public static readonly DependencyProperty ItemContainerStyleProperty = DataGridControl.ItemContainerStyleProperty.AddOwner( typeof( GroupConfiguration ) ); - - public Style ItemContainerStyle - { - get - { - return ( Style )this.GetValue( GroupConfiguration.ItemContainerStyleProperty ); - } - set - { - this.SetValue( GroupConfiguration.ItemContainerStyleProperty, value ); - } - } - - #endregion ItemContainerStyle Property - - #region ItemContainerStyleSelector Property - - public static readonly DependencyProperty ItemContainerStyleSelectorProperty = DataGridControl.ItemContainerStyleSelectorProperty.AddOwner( typeof( GroupConfiguration ) ); - - public StyleSelector ItemContainerStyleSelector - { - get - { - return ( StyleSelector )this.GetValue( GroupConfiguration.ItemContainerStyleSelectorProperty ); - } - set - { - this.SetValue( GroupConfiguration.ItemContainerStyleSelectorProperty, value ); - } - } - - #endregion ItemContainerStyleSelector Property - - #region GroupLevelIndicatorStyle Property - - public static readonly DependencyProperty GroupLevelIndicatorStyleProperty = - DependencyProperty.Register( "GroupLevelIndicatorStyle", typeof( Style ), typeof( GroupConfiguration ), new UIPropertyMetadata( null ) ); - - public Style GroupLevelIndicatorStyle - { - get - { - return ( Style )this.GetValue( GroupConfiguration.GroupLevelIndicatorStyleProperty ); - } - set - { - this.SetValue( GroupConfiguration.GroupLevelIndicatorStyleProperty, value ); - } - } - - #endregion GroupLevelIndicatorStyle Property - - #region UseDefaultHeadersFooters Property - - public static readonly DependencyProperty UseDefaultHeadersFootersProperty = - DependencyProperty.Register( "UseDefaultHeadersFooters", typeof( bool ), typeof( GroupConfiguration ), new PropertyMetadata( true ) ); - - public bool UseDefaultHeadersFooters - { - get - { - return ( bool )this.GetValue( GroupConfiguration.UseDefaultHeadersFootersProperty ); - } - set - { - this.SetValue( GroupConfiguration.UseDefaultHeadersFootersProperty, value ); - } - } - - #endregion UseDefaultHeadersFooters Property - - internal void AddDefaultHeadersFooters() - { - if( m_defaultHeadersFootersAdded ) - return; - - m_defaultHeadersFootersAdded = true; - this.Headers.Insert( 0, GroupConfiguration.DefaultHeaderTemplate ); - } - - internal static GroupConfiguration GetGroupConfiguration( DataGridContext dataGridContext, ObservableCollection groupDescriptions, GroupConfigurationSelector groupConfigSelector, int groupLevel, CollectionViewGroup collectionViewGroup ) - { - if( dataGridContext == null ) - throw new ArgumentNullException( "dataGridContext" ); - - if( groupDescriptions == null ) - throw new ArgumentNullException( "groupDescriptions" ); - - if( groupLevel >= groupDescriptions.Count ) - throw new ArgumentException( "The specified group level is greater than the number of GroupDescriptions in the DataGridContext.", "groupLevel" ); - - GroupDescription groupDescription = groupDescriptions[ groupLevel ]; - - GroupConfiguration retval = null; - DataGridGroupDescription dataGridGroupDescription = groupDescription as DataGridGroupDescription; - - if( ( dataGridGroupDescription != null ) && ( dataGridGroupDescription.GroupConfiguration != null ) ) - { - retval = dataGridGroupDescription.GroupConfiguration; - } - else if( groupConfigSelector != null ) - { - retval = groupConfigSelector.SelectGroupConfiguration( groupLevel, collectionViewGroup, groupDescription ); - } - - if( retval == null ) - { - retval = dataGridContext.DefaultGroupConfiguration; - } - - if( retval == null ) - { - retval = GroupConfiguration.DefaultGroupConfiguration; - } - - return retval; - } - - protected override Freezable CreateInstanceCore() - { - return new GroupConfiguration(); - } - - - private bool m_defaultHeadersFootersAdded; // = false - private static readonly GroupHeaderFooterItemTemplate DefaultHeaderTemplate; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupConfigurationSelector.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupConfigurationSelector.cs deleted file mode 100644 index 775b5718..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupConfigurationSelector.cs +++ /dev/null @@ -1,29 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.ComponentModel; -using System.Windows.Data; - -namespace Xceed.Wpf.DataGrid -{ - public abstract class GroupConfigurationSelector - { - public virtual GroupConfiguration SelectGroupConfiguration( int groupLevel, CollectionViewGroup collectionViewGroup, GroupDescription groupDescription ) - { - return null; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupExtensions.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupExtensions.cs deleted file mode 100644 index 62900b12..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupExtensions.cs +++ /dev/null @@ -1,57 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows.Data; - -namespace Xceed.Wpf.DataGrid -{ - public static class GroupExtensions - { - public static IList GetItems( this Group group ) - { - CollectionViewGroup collectionViewGroup = group.CollectionViewGroup; - - if( collectionViewGroup == null ) - return null; - - return collectionViewGroup.GetItems(); - } - - public static IEnumerable GetLeafItems( this Group group ) - { - CollectionViewGroup collectionViewGroup = group.CollectionViewGroup; - - if( collectionViewGroup == null ) - return new object[0]; - - return collectionViewGroup.GetLeafItems(); - } - - public static SelectionRange GetRange( this Group group ) - { - CollectionViewGroup collectionViewGroup = group.CollectionViewGroup; - - if( collectionViewGroup == null ) - return SelectionRange.Empty; - - return collectionViewGroup.GetRange( group.DataGridContext ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupHeaderControl.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupHeaderControl.cs deleted file mode 100644 index a432d768..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupHeaderControl.cs +++ /dev/null @@ -1,441 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.ComponentModel; -using System.Diagnostics; -using System.Drawing; -using System.Windows; -using System.Windows.Automation.Peers; -using System.Windows.Controls; -using System.Windows.Controls.Primitives; -using System.Windows.Input; -using Xceed.Utils.Wpf; -using Xceed.Wpf.DataGrid.Utils; - -namespace Xceed.Wpf.DataGrid -{ - public class GroupHeaderControl : ContentControl, INotifyPropertyChanged, IDataGridItemContainer - { - #region Static Fields - - internal static readonly string GroupPropertyName = PropertyHelper.GetPropertyName( ( GroupHeaderControl g ) => g.Group ); - - #endregion - - static GroupHeaderControl() - { - // This DefaultStyleKey will only be used in design-time. - DefaultStyleKeyProperty.OverrideMetadata( typeof( GroupHeaderControl ), new FrameworkPropertyMetadata( new Markup.ThemeKey( typeof( Views.TableView ), typeof( GroupHeaderControl ) ) ) ); - - DataGridControl.ParentDataGridControlPropertyKey.OverrideMetadata( typeof( GroupHeaderControl ), new FrameworkPropertyMetadata( new PropertyChangedCallback( OnParentGridControlChanged ) ) ); - - KeyboardNavigation.TabNavigationProperty.OverrideMetadata( - typeof( GroupHeaderControl ), new FrameworkPropertyMetadata( KeyboardNavigationMode.None ) ); - } - - public GroupHeaderControl() - { - this.CommandBindings.Add( new CommandBinding( DataGridCommands.ExpandGroup, - this.OnExpandExecuted, - this.OnExpandCanExecute ) ); - - this.CommandBindings.Add( new CommandBinding( DataGridCommands.CollapseGroup, - this.OnCollapseExecuted, - this.OnCollapseCanExecute ) ); - - this.CommandBindings.Add( new CommandBinding( DataGridCommands.ToggleGroupExpansion, - this.OnToggleExecuted, - this.OnToggleCanExecute ) ); - - m_itemContainerManager = new DataGridItemContainerManager( this ); - } - - #region Group Internal Attached Property - - internal static readonly DependencyProperty GroupProperty = DependencyProperty.RegisterAttached( - "Group", typeof( Group ), typeof( GroupHeaderControl ), - new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.Inherits ) ); - - internal static Group GetGroup( DependencyObject obj ) - { - return ( Group )obj.GetValue( GroupHeaderControl.GroupProperty ); - } - - internal static void SetGroup( DependencyObject obj, Group value ) - { - obj.SetValue( GroupHeaderControl.GroupProperty, value ); - } - - #endregion - - #region Group Property - - public Group Group - { - get - { - return m_group; - } - } - - internal void SetGroup( Group group ) - { - m_group = group; - this.Content = m_group; - GroupHeaderControl.SetGroup( this, group ); - - this.RaisePropertyChanged( GroupHeaderControl.GroupPropertyName ); - } - - private Group m_group; - - #endregion - - #region SelectionBackground Property - - public static readonly DependencyProperty SelectionBackgroundProperty = Cell.SelectionBackgroundProperty.AddOwner( typeof( GroupHeaderControl ) ); - - public Brush SelectionBackground - { - get - { - return ( Brush )this.GetValue( GroupHeaderControl.SelectionBackgroundProperty ); - } - set - { - this.SetValue( GroupHeaderControl.SelectionBackgroundProperty, value ); - } - } - - #endregion SelectionBackground Property - - #region SelectionForeground Property - - public static readonly DependencyProperty SelectionForegroundProperty = Cell.SelectionForegroundProperty.AddOwner( typeof( GroupHeaderControl ) ); - - public Brush SelectionForeground - { - get - { - return ( Brush )this.GetValue( GroupHeaderControl.SelectionForegroundProperty ); - } - set - { - this.SetValue( GroupHeaderControl.SelectionForegroundProperty, value ); - } - } - - #endregion SelectionForeground Property - - #region InactiveSelectionBackground Property - - public static readonly DependencyProperty InactiveSelectionBackgroundProperty = Cell.InactiveSelectionBackgroundProperty.AddOwner( typeof( GroupHeaderControl ) ); - - public Brush InactiveSelectionBackground - { - get - { - return ( Brush )this.GetValue( GroupHeaderControl.InactiveSelectionBackgroundProperty ); - } - set - { - this.SetValue( GroupHeaderControl.InactiveSelectionBackgroundProperty, value ); - } - } - - #endregion InactiveSelectionBackground Property - - #region InactiveSelectionForeground Property - - public static readonly DependencyProperty InactiveSelectionForegroundProperty = Cell.InactiveSelectionForegroundProperty.AddOwner( typeof( GroupHeaderControl ) ); - - public Brush InactiveSelectionForeground - { - get - { - return ( Brush )this.GetValue( GroupHeaderControl.InactiveSelectionForegroundProperty ); - } - set - { - this.SetValue( GroupHeaderControl.InactiveSelectionForegroundProperty, value ); - } - } - - #endregion InactiveSelectionForeground Property - - #region CanBeRecycled Protected Property - - protected virtual bool CanBeRecycled - { - get - { - if( this.IsKeyboardFocused || this.IsKeyboardFocusWithin ) - return false; - - return m_itemContainerManager.CanBeRecycled; - } - } - - #endregion - - public override void OnApplyTemplate() - { - base.OnApplyTemplate(); - - m_itemContainerManager.Update(); - } - - - protected override void OnPreviewMouseLeftButtonUp( MouseButtonEventArgs e ) - { - base.OnPreviewMouseLeftButtonUp( e ); - return; - } - - protected override void OnIsKeyboardFocusWithinChanged( DependencyPropertyChangedEventArgs e ) - { - base.OnIsKeyboardFocusWithinChanged( e ); - - bool newValue = ( bool )e.NewValue; - - if( newValue == true ) - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - if( dataGridContext != null ) - { - object item = dataGridContext.GetItemFromContainer( this ); - - if( ( item != null ) && ( dataGridContext.InternalCurrentItem != item ) ) - { - try - { - dataGridContext.SetCurrent( item, null, -1, dataGridContext.CurrentColumn, true, true, false, AutoScrollCurrentItemSourceTriggers.FocusChanged ); - } - catch( DataGridException ) - { - // We swallow the exception if it occurs because of a validation error or Cell was read-only or - // any other GridException. - } - } - } - } - } - - protected virtual void PrepareContainer( DataGridContext dataGridContext, object item ) - { - m_isRecyclingCandidate = false; - - if( m_isContainerPrepared ) - Debug.Fail( "A GroupHeaderControl can't be prepared twice, it must be cleaned before PrepareContainer is called again" ); - - Group group = null; - DataGridContext gridContext = DataGridControl.GetDataGridContext( this ); - - if( gridContext != null ) - { - object dataItem = gridContext.GetItemFromContainer( this ); - if( dataItem != null ) - { - group = gridContext.GetGroupFromItem( dataItem ); - } - } - - this.SetGroup( group ); - - m_itemContainerManager.Prepare( gridContext, item ); - - m_isContainerPrepared = true; - } - - protected virtual void ClearContainer() - { - m_itemContainerManager.Clear( m_isRecyclingCandidate ); - m_isContainerPrepared = false; - } - - protected internal virtual void PrepareDefaultStyleKey( Xceed.Wpf.DataGrid.Views.ViewBase view ) - { - this.DefaultStyleKey = view.GetDefaultStyleKey( typeof( GroupHeaderControl ) ); - } - - protected internal virtual bool ShouldHandleSelectionEvent( InputEventArgs eventArgs ) - { - var targetChild = eventArgs.OriginalSource as DependencyObject; - - // If the event is comming from a specific control inside the header (GroupNavigationControl or Collapsed button), - // ignore the event since it is not for selection purposes that the user targeted this control. - var collapsedButtonParent = TreeHelper.FindParent( targetChild, true, null, this ); - if( collapsedButtonParent != null ) - return false; - - var groupNavigationControlParent = TreeHelper.FindParent( targetChild, true, null, this ); - if( groupNavigationControlParent != null ) - return false; - - return true; - } - - private static void OnParentGridControlChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - DataGridControl grid = e.NewValue as DataGridControl; - GroupHeaderControl groupHeaderControl = sender as GroupHeaderControl; - - if( ( groupHeaderControl != null ) && ( grid != null ) ) - { - groupHeaderControl.PrepareDefaultStyleKey( grid.GetView() ); - } - } - - private void OnExpandCanExecute( object sender, CanExecuteRoutedEventArgs e ) - { - e.CanExecute = false; - - if( e.Parameter == null ) - { - //can execute the Expand command if the group is NOT expanded. - e.CanExecute = !this.FindGroupCommandTarget( e.OriginalSource ).IsExpanded; - } - } - - private void OnExpandExecuted( object sender, ExecutedRoutedEventArgs e ) - { - this.FindGroupCommandTarget( e.OriginalSource ).IsExpanded = true; - } - - private void OnCollapseCanExecute( object sender, CanExecuteRoutedEventArgs e ) - { - e.CanExecute = false; - - if( e.Parameter == null ) - { - //can execute the Collapse command if the group is expanded. - e.CanExecute = this.FindGroupCommandTarget( e.OriginalSource ).IsExpanded; - } - } - - private void OnCollapseExecuted( object sender, ExecutedRoutedEventArgs e ) - { - this.FindGroupCommandTarget( e.OriginalSource ).IsExpanded = false; - } - - private void OnToggleCanExecute( object sender, CanExecuteRoutedEventArgs e ) - { - e.CanExecute = false; - - if( e.Parameter == null ) - { - e.CanExecute = true; //can always toggle - } - } - - private void OnToggleExecuted( object sender, ExecutedRoutedEventArgs e ) - { - Group group = FindGroupCommandTarget( e.OriginalSource ); - - group.IsExpanded = !group.IsExpanded; - } - - // We use an ItemsControl inside the GroupHeaderControl to represent the - // ancestors (ParentGroups) of this.Group, and each item in this ItemsControl - // is a Group templated to look like a single, stand-alone GroupHeaderControl. - // - // In the ItemTemplate for each Group in the ItemsControl, we have a Border that - // declares some InputBindings to the group commands. In this case, we want to - // execute the command on this specific instance of Group, which is the DataContext - // of the Border. - private Group FindGroupCommandTarget( object originalSource ) - { - object dataContext = null; - - FrameworkElement fe = originalSource as FrameworkElement; - if( fe != null ) - { - dataContext = fe.DataContext; - } - else - { - FrameworkContentElement fce = originalSource as FrameworkContentElement; - if( fce != null ) - { - dataContext = fce.DataContext; - } - } - - Group groupCommandTarget = dataContext as Group; - - return ( groupCommandTarget != null ) ? groupCommandTarget : this.Group; - } - - #region INotifyPropertyChanged Members - - public event PropertyChangedEventHandler PropertyChanged; - - private void RaisePropertyChanged( string propertyName ) - { - var handler = this.PropertyChanged; - if( handler == null ) - return; - - handler.Invoke( this, new PropertyChangedEventArgs( propertyName ) ); - } - - #endregion - - #region IDataGridItemContainer Members - - bool IDataGridItemContainer.CanBeRecycled - { - get - { - return this.CanBeRecycled; - } - } - - bool IDataGridItemContainer.IsRecyclingCandidate - { - get - { - return m_isRecyclingCandidate; - } - set - { - m_isRecyclingCandidate = value; - } - } - - void IDataGridItemContainer.PrepareContainer( DataGridContext dataGridContext, object item ) - { - this.PrepareContainer( dataGridContext, item ); - } - - void IDataGridItemContainer.ClearContainer() - { - this.ClearContainer(); - } - - void IDataGridItemContainer.CleanRecyclingCandidate() - { - m_itemContainerManager.CleanRecyclingCandidates(); - } - - #endregion - - private readonly DataGridItemContainerManager m_itemContainerManager; - private bool m_isContainerPrepared; - private bool m_isRecyclingCandidate; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupHeaderFooterCollection.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupHeaderFooterCollection.cs deleted file mode 100644 index 25373dc4..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupHeaderFooterCollection.cs +++ /dev/null @@ -1,53 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.ObjectModel; -using System.Windows; -using Xceed.Wpf.DataGrid.Markup; - -namespace Xceed.Wpf.DataGrid -{ - internal class GroupHeaderFooterCollection : ObservableCollection - { - protected override void InsertItem( int index, object item ) - { - if( item is DataTemplate ) - { - base.InsertItem( index, item ); - } - else - { - GroupHeaderFooterItemTemplate vwc = item as GroupHeaderFooterItemTemplate; - if( vwc != null ) - { - if(vwc.Template == null) - { - throw new ArgumentException( "A VisibleWhenCollapsed object must have its Template property set to an instance of a DataTemplate."); - } - else - { - base.InsertItem( index, item ); - } - } - else - { - throw new ArgumentException( "Group headers and footers can only receive ClearHeadersFooters, DataTemplate, or VisibleWhenCollapsed objects." ); - } - } - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupLevelConfiguration.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupLevelConfiguration.cs deleted file mode 100644 index 9b7742a8..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupLevelConfiguration.cs +++ /dev/null @@ -1,122 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.ObjectModel; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media; -using System.ComponentModel; - -namespace Xceed.Wpf.DataGrid -{ - [EditorBrowsable( EditorBrowsableState.Never )] - [Obsolete( "The GroupLevelConfiguration class is obsolete and has been replaced by the LevelGroupConfigurationSelector class.", true )] - public class GroupLevelConfiguration : DependencyObject - { - [EditorBrowsable( EditorBrowsableState.Never )] - [Obsolete( "The GroupLevelConfiguration class is obsolete and has been replaced by the LevelGroupConfigurationSelector class.", true )] - public GroupLevelConfiguration() - { - } - - #region Headers Read-Only Property - - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - [Obsolete( "The GroupLevelConfiguration class is obsolete and has been replaced by the LevelGroupConfigurationSelector class.", true )] - public static readonly DependencyProperty HeadersProperty; - - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - [Obsolete( "The GroupLevelConfiguration class is obsolete and has been replaced by the LevelGroupConfigurationSelector class.", true )] - public ObservableCollection Headers - { - get - { - return null; - } - } - - #endregion Headers Read-Only Property - - #region Footers Read-Only Property - - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - [Obsolete( "The GroupLevelConfiguration class is obsolete and has been replaced by the LevelGroupConfigurationSelector class.", true )] - public static readonly DependencyProperty FootersProperty; - - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - [Obsolete( "The GroupLevelConfiguration class is obsolete and has been replaced by the LevelGroupConfigurationSelector class.", true )] - public ObservableCollection Footers - { - get - { - return null; - } - } - - #endregion Footers Read-Only Property - - #region InitiallyExpanded Property - - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - [Obsolete( "The GroupLevelConfiguration class is obsolete and has been replaced by the LevelGroupConfigurationSelector class.", true )] - public static readonly DependencyProperty InitiallyExpandedProperty; - - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "value" ), System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1822:MarkMembersAsStatic" ), Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - [Obsolete( "The GroupLevelConfiguration class is obsolete and has been replaced by the LevelGroupConfigurationSelector class.", true )] - public bool InitiallyExpanded - { - get - { - return false; - } - set - { - } - } - - #endregion InitiallyExpanded Property - - #region GroupLevelIndicatorStyle Property - - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - [Obsolete( "The GroupLevelConfiguration class is obsolete and has been replaced by the LevelGroupConfigurationSelector class.", true )] - public static readonly DependencyProperty GroupLevelIndicatorStyleProperty; - - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "value" ), System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1822:MarkMembersAsStatic" ), Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - [Obsolete( "The GroupLevelConfiguration class is obsolete and has been replaced by the LevelGroupConfigurationSelector class.", true )] - public Style GroupLevelIndicatorStyle - { - get - { - return null; - } - set - { - } - } - - #endregion GroupLevelIndicatorStyle Property - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupLevelConfigurationCollection.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupLevelConfigurationCollection.cs deleted file mode 100644 index cf171cd2..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupLevelConfigurationCollection.cs +++ /dev/null @@ -1,30 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.ObjectModel; -using Xceed.Wpf.DataGrid.Views; -using Xceed.Wpf.DataGrid.Markup; -using System.ComponentModel; - -namespace Xceed.Wpf.DataGrid -{ - [EditorBrowsable( EditorBrowsableState.Never )] - [Obsolete( "The GroupLevelConfigurationCollection class is obsolete and has been replaced by the LevelGroupConfigurationSelectorItemCollection class.", true )] - public class GroupLevelConfigurationCollection : ObservableCollection - { - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupLevelDescription.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupLevelDescription.cs deleted file mode 100644 index c055d037..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupLevelDescription.cs +++ /dev/null @@ -1,214 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.ComponentModel; -using System.Globalization; -using System.Windows; -using System.Windows.Controls; - -namespace Xceed.Wpf.DataGrid -{ - public class GroupLevelDescription : DependencyObject, IGroupLevelDescription, INotifyPropertyChanged - { - #region CONSTRUCTORS - - internal GroupLevelDescription( GroupDescription groupDescription, string fieldName ) - { - if( groupDescription == null ) - throw new DataGridInternalException( "GroupDescription cannot be null." ); - - m_groupDescription = groupDescription; - m_fieldName = fieldName; - } - - #endregion - - #region FieldName Property - - public string FieldName - { - get - { - return m_fieldName; - } - } - - private readonly string m_fieldName; - - #endregion - - #region GroupDescription Property - - internal GroupDescription GroupDescription - { - get - { - return m_groupDescription; - } - } - - private readonly GroupDescription m_groupDescription; - - #endregion - - #region Title Property - - internal static readonly DependencyProperty TitleProperty = DependencyProperty.Register( - "Title", - typeof( object ), - typeof( GroupLevelDescription ), - new UIPropertyMetadata( null, new PropertyChangedCallback( GroupLevelDescription.OnPropertyChanged ) ) ); - - public object Title - { - get - { - return ( object )this.GetValue( GroupLevelDescription.TitleProperty ); - } - } - - internal void SetTitle( object title ) - { - this.SetValue( GroupLevelDescription.TitleProperty, title ); - } - - #endregion Title Property - - #region TitleTemplate Property - - internal static readonly DependencyProperty TitleTemplateProperty = DependencyProperty.Register( - "TitleTemplate", - typeof( DataTemplate ), - typeof( GroupLevelDescription ), - new UIPropertyMetadata( null, new PropertyChangedCallback( GroupLevelDescription.OnPropertyChanged ) ) ); - - public DataTemplate TitleTemplate - { - get - { - return ( DataTemplate )this.GetValue( GroupLevelDescription.TitleTemplateProperty ); - } - } - - #endregion TitleTemplate Property - - #region TitleTemplateSelector Property - - internal static readonly DependencyProperty TitleTemplateSelectorProperty = DependencyProperty.Register( - "TitleTemplateSelector", - typeof( DataTemplateSelector ), - typeof( GroupLevelDescription ), - new UIPropertyMetadata( null, new PropertyChangedCallback( GroupLevelDescription.OnPropertyChanged ) ) ); - - public DataTemplateSelector TitleTemplateSelector - { - get - { - return ( DataTemplateSelector )this.GetValue( GroupLevelDescription.TitleTemplateSelectorProperty ); - } - } - - #endregion TitleTemplateSelector Property - - #region ValueStringFormat Property - - internal static readonly DependencyProperty ValueStringFormatProperty = DependencyProperty.Register( - "ValueStringFormat", - typeof( string ), - typeof( GroupLevelDescription ), - new UIPropertyMetadata( null, new PropertyChangedCallback( GroupLevelDescription.OnPropertyChanged ) ) ); - - public string ValueStringFormat - { - get - { - return ( string )this.GetValue( GroupLevelDescription.ValueStringFormatProperty ); - } - } - - #endregion ValueStringFormat Property - - #region ValueStringFormatCulture Property - - internal static readonly DependencyProperty ValueStringFormatCultureProperty = DependencyProperty.Register( - "ValueStringFormatCulture", - typeof( CultureInfo ), - typeof( GroupLevelDescription ), - new UIPropertyMetadata( null, new PropertyChangedCallback( GroupLevelDescription.OnPropertyChanged ) ) ); - - public CultureInfo ValueStringFormatCulture - { - get - { - return ( CultureInfo )this.GetValue( GroupLevelDescription.ValueStringFormatCultureProperty ); - } - } - - #endregion ValueStringFormatCulture Property - - #region ValueTemplate Property - - internal static readonly DependencyProperty ValueTemplateProperty = DependencyProperty.Register( - "ValueTemplate", - typeof( DataTemplate ), - typeof( GroupLevelDescription ), - new UIPropertyMetadata( null, new PropertyChangedCallback( GroupLevelDescription.OnPropertyChanged ) ) ); - - public DataTemplate ValueTemplate - { - get - { - return ( DataTemplate )this.GetValue( GroupLevelDescription.ValueTemplateProperty ); - } - } - - #endregion ValueTemplate Property - - #region ValueTemplateSelector Property - - internal static readonly DependencyProperty ValueTemplateSelectorProperty = DependencyProperty.Register( - "ValueTemplateSelector", - typeof( DataTemplateSelector ), - typeof( GroupLevelDescription ), - new UIPropertyMetadata( null, new PropertyChangedCallback( GroupLevelDescription.OnPropertyChanged ) ) ); - - public DataTemplateSelector ValueTemplateSelector - { - get - { - return ( DataTemplateSelector )this.GetValue( GroupLevelDescription.ValueTemplateSelectorProperty ); - } - } - - #endregion ValueTemplateSelector Property - - #region INotifyPropertyChanged Members - - public event PropertyChangedEventHandler PropertyChanged; - - private static void OnPropertyChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var self = ( GroupLevelDescription )sender; - var handler = self.PropertyChanged; - if( handler == null ) - return; - - handler.Invoke( self, new PropertyChangedEventArgs( e.Property.Name ) ); - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupLevelDescriptionCollection.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupLevelDescriptionCollection.cs deleted file mode 100644 index 3786a8b5..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupLevelDescriptionCollection.cs +++ /dev/null @@ -1,56 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Collections.ObjectModel; - -namespace Xceed.Wpf.DataGrid -{ - public class GroupLevelDescriptionCollection : ReadOnlyObservableCollection - { - public GroupLevelDescriptionCollection() - : base( new ObservableCollection() ) - { - } - - internal void Add( GroupLevelDescription info ) - { - this.Items.Add( info ); - } - - internal void Insert( int index, GroupLevelDescription info ) - { - this.Items.Insert( index, info ); - } - - internal bool Remove( GroupLevelDescription info ) - { - return this.Items.Remove( info ); - } - - internal void RemoveAt( int index ) - { - this.Items.RemoveAt( index ); - } - - internal void Clear() - { - this.Items.Clear(); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupLevelIndicator.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupLevelIndicator.cs deleted file mode 100644 index b83b67f7..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupLevelIndicator.cs +++ /dev/null @@ -1,52 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Windows.Controls; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - public class GroupLevelIndicator : Control - { - static GroupLevelIndicator() - { - // This DefaultStyleKey will only be used in design-time. - DefaultStyleKeyProperty.OverrideMetadata( typeof( GroupLevelIndicator ), new FrameworkPropertyMetadata( new Markup.ThemeKey( typeof( Views.TableView ), typeof( GroupLevelIndicator ) ) ) ); - - DataGridControl.DataGridContextPropertyKey.OverrideMetadata( typeof( GroupLevelIndicator ), new FrameworkPropertyMetadata( new PropertyChangedCallback( GroupLevelIndicator.OnDataGridContextChanged ) ) ); - - FocusableProperty.OverrideMetadata( typeof( GroupLevelIndicator ), new FrameworkPropertyMetadata( false ) ); - } - - protected internal virtual void PrepareDefaultStyleKey( Xceed.Wpf.DataGrid.Views.ViewBase view ) - { - this.DefaultStyleKey = view.GetDefaultStyleKey( typeof( GroupLevelIndicator ) ); - } - - private static void OnDataGridContextChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - DataGridContext dataGridContext = e.NewValue as DataGridContext; - - if( dataGridContext != null ) - { - ( ( GroupLevelIndicator )sender ).PrepareDefaultStyleKey( dataGridContext.DataGridControl.GetView() ); - } - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupLevelIndicatorPane.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupLevelIndicatorPane.cs deleted file mode 100644 index 31629031..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupLevelIndicatorPane.cs +++ /dev/null @@ -1,490 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.ObjectModel; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Diagnostics; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Media; -using Xceed.Wpf.DataGrid.Views; - -namespace Xceed.Wpf.DataGrid -{ - [TemplatePart( Name = "PART_GroupLevelIndicatorHost", Type = typeof( Panel ) )] - public class GroupLevelIndicatorPane : Control, IWeakEventListener - { - static GroupLevelIndicatorPane() - { - GroupLevelIndicatorPane.IsLeafProperty = GroupLevelIndicatorPane.IsLeafPropertyKey.DependencyProperty; - GroupLevelIndicatorPane.CurrentIndicatorCountProperty = GroupLevelIndicatorPane.CurrentIndicatorCountPropertyKey.DependencyProperty; - - FocusableProperty.OverrideMetadata( typeof( GroupLevelIndicatorPane ), new FrameworkPropertyMetadata( false ) ); - - DataGridControl.DataGridContextPropertyKey.OverrideMetadata( typeof( GroupLevelIndicatorPane ), new FrameworkPropertyMetadata( new PropertyChangedCallback( OnDataGridContextChanged ) ) ); - CustomItemContainerGenerator.DataItemPropertyProperty.OverrideMetadata( typeof( GroupLevelIndicatorPane ), new FrameworkPropertyMetadata( new PropertyChangedCallback( OnDataItemChanged ) ) ); - - AreGroupsFlattenedBinding = new Binding(); - AreGroupsFlattenedBinding.Mode = BindingMode.OneWay; - AreGroupsFlattenedBinding.RelativeSource = new RelativeSource( RelativeSourceMode.Self ); - - AreGroupsFlattenedBinding.Path = new PropertyPath( "(0).(1)", - DataGridControl.DataGridContextProperty, - TableflowView.AreGroupsFlattenedProperty ); - } - - public GroupLevelIndicatorPane() - { - this.SetBinding( GroupLevelIndicatorPane.AreGroupsFlattenedProperty, GroupLevelIndicatorPane.AreGroupsFlattenedBinding ); - } - - #region AreGroupsFlattened Internal Property - - internal static readonly DependencyProperty AreGroupsFlattenedProperty = DependencyProperty.Register( - "AreGroupsFlattened", typeof( bool ), typeof( GroupLevelIndicatorPane ), - new FrameworkPropertyMetadata( false, FrameworkPropertyMetadataOptions.AffectsMeasure ) ); - - internal bool AreGroupsFlattened - { - get - { - return ( bool )this.GetValue( GroupLevelIndicatorPane.AreGroupsFlattenedProperty ); - } - set - { - this.SetValue( GroupLevelIndicatorPane.AreGroupsFlattenedProperty, value ); - } - } - - private static Binding AreGroupsFlattenedBinding; - - #endregion AreGroupsFlattened Internal Property - - #region GroupLevelIndicatorPaneHost Read-Only Property - - private Panel GroupLevelIndicatorPaneHost - { - get - { - //if there is no local storage for the host panel, try to retrieve and store the value - if( m_storedGroupLevelIndicatorPaneHost == null ) - { - m_storedGroupLevelIndicatorPaneHost = this.RetrieveGroupLevelIndicatorPaneHostPanel(); - } - - return m_storedGroupLevelIndicatorPaneHost; - } - } - - private Panel m_storedGroupLevelIndicatorPaneHost; //null - - #endregion GroupLevelIndicatorPaneHost Read-Only Property - - #region ShowIndicators Attached Property - - public static readonly DependencyProperty ShowIndicatorsProperty = DependencyProperty.RegisterAttached( - "ShowIndicators", typeof( bool ), typeof( GroupLevelIndicatorPane ), - new FrameworkPropertyMetadata( true, FrameworkPropertyMetadataOptions.Inherits | FrameworkPropertyMetadataOptions.AffectsMeasure ) ); - - public static bool GetShowIndicators( DependencyObject obj ) - { - return ( bool )obj.GetValue( GroupLevelIndicatorPane.ShowIndicatorsProperty ); - } - - public static void SetShowIndicators( DependencyObject obj, bool value ) - { - obj.SetValue( GroupLevelIndicatorPane.ShowIndicatorsProperty, value ); - } - - #endregion ShowIndicators Attached Property - - #region ShowVerticalBorder Attached Property - - public static readonly DependencyProperty ShowVerticalBorderProperty = - DependencyProperty.RegisterAttached( "ShowVerticalBorder", typeof( bool ), typeof( GroupLevelIndicatorPane ), - new FrameworkPropertyMetadata( true, FrameworkPropertyMetadataOptions.AffectsMeasure ) ); - - public static bool GetShowVerticalBorder( DependencyObject obj ) - { - return ( bool )obj.GetValue( ShowVerticalBorderProperty ); - } - - public static void SetShowVerticalBorder( DependencyObject obj, bool value ) - { - obj.SetValue( ShowVerticalBorderProperty, value ); - } - - #endregion - - #region Indented Property - - public static readonly DependencyProperty IndentedProperty = - DependencyProperty.Register( "Indented", typeof( bool ), typeof( GroupLevelIndicatorPane ), - new FrameworkPropertyMetadata( true, FrameworkPropertyMetadataOptions.AffectsMeasure ) ); - - public bool Indented - { - get - { - return ( bool )this.GetValue( GroupLevelIndicatorPane.IndentedProperty ); - } - set - { - this.SetValue( GroupLevelIndicatorPane.IndentedProperty, value ); - } - } - - #endregion Indented Property - - #region GroupLevel Attached Property - - public static readonly DependencyProperty GroupLevelProperty = DependencyProperty.RegisterAttached( - "GroupLevel", typeof( int ), typeof( GroupLevelIndicatorPane ), - new FrameworkPropertyMetadata( 0, FrameworkPropertyMetadataOptions.Inherits | FrameworkPropertyMetadataOptions.AffectsMeasure ) ); - - public static int GetGroupLevel( DependencyObject obj ) - { - return ( int )obj.GetValue( GroupLevelIndicatorPane.GroupLevelProperty ); - } - - public static void SetGroupLevel( DependencyObject obj, int value ) - { - obj.SetValue( GroupLevelIndicatorPane.GroupLevelProperty, value ); - } - - #endregion GroupLevel Attached Property - - #region IsLeaf Read-Only Property - - internal static readonly DependencyPropertyKey IsLeafPropertyKey = - DependencyProperty.RegisterReadOnly( "IsLeaf", typeof( bool ), typeof( GroupLevelIndicatorPane ), - new FrameworkPropertyMetadata( true, FrameworkPropertyMetadataOptions.AffectsMeasure ) ); - - public static readonly DependencyProperty IsLeafProperty; - - public bool IsLeaf - { - get - { - return ( bool )this.GetValue( GroupLevelIndicatorPane.IsLeafProperty ); - } - } - - internal void SetIsLeaf( bool value ) - { - this.SetValue( GroupLevelIndicatorPane.IsLeafPropertyKey, value ); - } - - #endregion IsLeaf Read-Only Property - - #region CurrentIndicatorCount Read-Only Property - - private static readonly DependencyPropertyKey CurrentIndicatorCountPropertyKey = - DependencyProperty.RegisterReadOnly( "CurrentIndicatorCount", typeof( int ), typeof( GroupLevelIndicatorPane ), new PropertyMetadata( 0 ) ); - - public static readonly DependencyProperty CurrentIndicatorCountProperty; - - public int CurrentIndicatorCount - { - get - { - return ( int )this.GetValue( GroupLevelIndicatorPane.CurrentIndicatorCountProperty ); - } - } - - internal void SetCurrentIndicatorCount( int value ) - { - this.SetValue( GroupLevelIndicatorPane.CurrentIndicatorCountPropertyKey, value ); - } - - #endregion CurrentIndicatorCount Read-Only Property - - internal virtual void PrepareDefaultStyleKey( Xceed.Wpf.DataGrid.Views.ViewBase view ) - { - this.DefaultStyleKey = view.GetDefaultStyleKey( typeof( GroupLevelIndicatorPane ) ); - } - - protected override Size MeasureOverride( Size availableSize ) - { - var panel = this.GroupLevelIndicatorPaneHost; - var dataGridContext = DataGridControl.GetDataGridContext( this ); - - if( ( panel == null ) || ( dataGridContext == null ) ) - return base.MeasureOverride( availableSize ); - - var groupDescriptions = DataGridContext.GetGroupDescriptionsHelper( dataGridContext.Items ); - var leafGroupLevel = GroupLevelIndicatorPane.GetGroupLevel( this ); - - // If Indented is true (default), we use the total groupDescriptions.Count for this DataGridContext - var correctedGroupLevel = ( this.Indented == true ) ? groupDescriptions.Count : leafGroupLevel; - - // Ensure that the GroupLevel retrieved does not exceeds the number of group descriptions for the DataGridContext - correctedGroupLevel = Math.Min( correctedGroupLevel, groupDescriptions.Count ); - - // Then finally, if the GroupLevel is -1, then indent at maximum. - if( correctedGroupLevel == -1 ) - { - correctedGroupLevel = groupDescriptions.Count; - } - - if( ( correctedGroupLevel > 0 ) && ( this.AreGroupsFlattened ) ) - { - correctedGroupLevel = ( this.Indented ) ? 1 : 0; - } - - var children = panel.Children; - var childrenCount = children.Count; - - // If we need to add/remove GroupLevelIndicators from the panel - if( correctedGroupLevel != childrenCount ) - { - // When grouping change, we take for granted that the group deepness will change, - // so we initialize DataContext of the margin only in there. - - // Clear all the panel's children! - children.Clear(); - - // Create 1 group margin content presenter for each group level - for( int i = correctedGroupLevel - 1; i >= 0; i-- ) - { - GroupLevelIndicator groupMargin = new GroupLevelIndicator(); - groupMargin.DataContext = dataGridContext.GroupLevelDescriptions[ i ]; - children.Insert( 0, new GroupLevelIndicator() ); - } - - childrenCount = correctedGroupLevel; - this.SetCurrentIndicatorCount( childrenCount ); - - this.InvalidateGroupLevelIndicatorPaneHostPanelMeasure(); - } - - var item = dataGridContext.GetItemFromContainer( this ); - - for( int i = 0; i < childrenCount; i++ ) - { - GroupLevelIndicator groupMargin = children[ i ] as GroupLevelIndicator; - - CollectionViewGroup groupForIndicator = GroupLevelIndicatorPane.GetCollectionViewGroupHelper( - dataGridContext, groupDescriptions, item, i ); - - GroupConfiguration groupLevelConfig = GroupConfiguration.GetGroupConfiguration( - dataGridContext, groupDescriptions, dataGridContext.GroupConfigurationSelector, i, groupForIndicator ); - - if( groupLevelConfig != null ) - { - Binding groupLevelIndicatorStyleBinding = BindingOperations.GetBinding( groupMargin, GroupLevelIndicator.StyleProperty ); - - if( ( groupLevelIndicatorStyleBinding == null ) || ( groupLevelIndicatorStyleBinding.Source != groupLevelConfig ) ) - { - groupLevelIndicatorStyleBinding = new Binding( "GroupLevelIndicatorStyle" ); - groupLevelIndicatorStyleBinding.Source = groupLevelConfig; - - // Use a Converter to manage groupLevelConfig.GroupLevelIndicatorStyle == null - // so that an implicit syle won't be overriden by a null style. - groupLevelIndicatorStyleBinding.Converter = new GroupLevelIndicatorConverter(); - - groupLevelIndicatorStyleBinding.ConverterParameter = groupMargin; - groupMargin.SetBinding( GroupLevelIndicator.StyleProperty, groupLevelIndicatorStyleBinding ); - } - } - else - { - groupMargin.ClearValue( GroupLevelIndicator.StyleProperty ); - } - - // If the ShowIndicators property is False or there is already leafGroupLevel GroupLevelIndicators in the panel, - // the current newGroupMargin must be hidden. - if( ( !GroupLevelIndicatorPane.GetShowIndicators( this ) ) || ( ( i >= leafGroupLevel ) && ( leafGroupLevel != -1 ) ) ) - { - groupMargin.Visibility = Visibility.Hidden; - } - else - { - groupMargin.Visibility = Visibility.Visible; - } - } - - return base.MeasureOverride( availableSize ); - } - - private static CollectionViewGroup GetCollectionViewGroupHelper( DataGridContext dataGridContext, ObservableCollection groupDescriptions, object item, int groupLevel ) - { - if( item == null ) - return null; - - int levelOfRecursion = groupDescriptions.Count - groupLevel - 1; - - CollectionViewGroup retval = dataGridContext.GetParentGroupFromItemCore( item, true ); - - if( retval == null ) - return null; - - for( int i = 0; i < levelOfRecursion; i++ ) - { - retval = dataGridContext.GetParentGroupFromItemCore( retval, true ) as CollectionViewGroup; - - if( retval == null ) - return null; - } - - return retval; - } - - private static void OnDataGridContextChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - GroupLevelIndicatorPane self = sender as GroupLevelIndicatorPane; - - if( self != null ) - { - DataGridContext dataGridContext = e.OldValue as DataGridContext; - - //unregister to the old contexts Collection GroupDescriptions Changed event - if( dataGridContext != null ) - { - CollectionChangedEventManager.RemoveListener( dataGridContext.Items.GroupDescriptions, self ); - } - - dataGridContext = e.NewValue as DataGridContext; - - //register to the new contexts Collection GroupDescriptions Changed event - if( dataGridContext != null ) - { - CollectionChangedEventManager.AddListener( dataGridContext.Items.GroupDescriptions, self ); - self.PrepareDefaultStyleKey( dataGridContext.DataGridControl.GetView() ); - } - - self.InvalidateMeasure(); - } - } - - private static void OnDataItemChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var self = ( GroupLevelIndicatorPane )sender; - Debug.Assert( self != null ); - - var oldDataItemStore = ( DataItemDataProviderBase )e.OldValue; - var newDataItemStore = ( DataItemDataProviderBase )e.NewValue; - - if( oldDataItemStore != null ) - { - PropertyChangedEventManager.RemoveListener( oldDataItemStore, self, "Data" ); - } - - if( newDataItemStore != null ) - { - PropertyChangedEventManager.AddListener( newDataItemStore, self, "Data" ); - } - - if( !newDataItemStore.IsEmpty ) - { - self.InvalidateMeasure(); - } - } - - public override void OnApplyTemplate() - { - base.OnApplyTemplate(); - - //whenever the template gets "applied" I want to invalidate the stored Panel. - m_storedGroupLevelIndicatorPaneHost = null; - } - - protected override void OnPropertyChanged( DependencyPropertyChangedEventArgs e ) - { - base.OnPropertyChanged( e ); - - if( e.Property == GroupLevelIndicatorPane.GroupLevelProperty ) - { - this.InvalidateMeasure(); - } - } - - private Panel RetrieveGroupLevelIndicatorPaneHostPanel() - { - //get the template part - return this.GetTemplateChild( "PART_GroupLevelIndicatorHost" ) as Panel; - } - - private void InvalidateGroupLevelIndicatorPaneHostPanelMeasure() - { - UIElement container = this.GroupLevelIndicatorPaneHost; - - while( ( container != null ) && ( container != this ) ) - { - container.InvalidateMeasure(); - container = VisualTreeHelper.GetParent( container ) as UIElement; - } - } - - #region IWeakEventListener Members - - 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( managerType == typeof( CollectionChangedEventManager ) ) - { - this.InvalidateMeasure(); - } - else if( managerType == typeof( PropertyChangedEventManager ) ) - { - var dataItemStore = sender as DataItemDataProviderBase; - if( ( dataItemStore != null ) && !dataItemStore.IsEmpty ) - { - this.InvalidateMeasure(); - } - } - else - { - return false; - } - - return true; - } - - #endregion - - private class GroupLevelIndicatorConverter : IValueConverter - { - public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) - { - // When groupLevelConfig.GroupLevelIndicatorStyle exists, return it. - if( value != null ) - return value; - - // When groupLevelConfig.GroupLevelIndicatorStyle is null, try to find an implicit style - // for the GroupLevelIndicator in the resources. - var gli = ( GroupLevelIndicator )parameter; - var style = gli.TryFindResource( gli.GetType() ); - if( style != null ) - return style; - - return value; - } - - public object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) - { - throw new NotSupportedException(); - } - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupNavigationButton.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupNavigationButton.cs deleted file mode 100644 index 72b759e6..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupNavigationButton.cs +++ /dev/null @@ -1,84 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows.Controls; -using System.Windows; -using Xceed.Wpf.DataGrid.Views; -using System.Windows.Input; - -namespace Xceed.Wpf.DataGrid -{ - public class GroupNavigationButton : Button - { - #region CONSTRUCTORS - - static GroupNavigationButton() - { - DefaultStyleKeyProperty.OverrideMetadata( - typeof( GroupNavigationButton ), - new FrameworkPropertyMetadata( new Markup.ThemeKey( typeof( TableView ), typeof( GroupNavigationButton ) ) ) ); - - DataGridControl.ParentDataGridControlPropertyKey.OverrideMetadata( - typeof( GroupNavigationButton ), new FrameworkPropertyMetadata( new PropertyChangedCallback( GroupNavigationButton.OnParentGridControlChanged ) ) ); - } - - public GroupNavigationButton() - { - this.Focusable = false; - } - - #endregion CONSTRUCTORS - - #region NavigateToGroup Command - - public static readonly RoutedCommand NavigateToGroup = - new RoutedCommand( "NavigateToGroup", typeof( GroupNavigationButton ) ); - - #endregion NavigateToGroup Command - - #region PROTECTED METHODS - - protected internal virtual void PrepareDefaultStyleKey( Xceed.Wpf.DataGrid.Views.ViewBase view ) - { - this.DefaultStyleKey = view.GetDefaultStyleKey( typeof( GroupNavigationButton ) ); - } - - #endregion PROTECTED METHODS - - #region PRIVATE METHODS - - private static void OnParentGridControlChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - GroupNavigationButton button = sender as GroupNavigationButton; - - if( button == null ) - return; - - DataGridControl parentGridControl = e.NewValue as DataGridControl; - - if( parentGridControl == null ) - return; - - button.PrepareDefaultStyleKey( parentGridControl.GetView() ); - } - - #endregion PRIVATE METHODS - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupNavigationControl.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupNavigationControl.cs deleted file mode 100644 index eabe4c86..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupNavigationControl.cs +++ /dev/null @@ -1,433 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows.Controls; -using System.Windows; -using System.Windows.Input; -using System.ComponentModel; -using System.Windows.Media; -using System.Windows.Controls.Primitives; -using Xceed.Wpf.DataGrid.Views; -using System.Windows.Data; - -namespace Xceed.Wpf.DataGrid -{ - [TemplatePart( Name = "PART_Button", Type = typeof( Button ) )] - [TemplatePart( Name = "PART_ToggleButton", Type = typeof( ToggleButton ) )] - [TemplatePart( Name = "PART_Popup", Type = typeof( Popup ) )] - [StyleTypedProperty( Property = "ItemContainerStyle", StyleTargetType = typeof( GroupNavigationControlItem ) )] - public class GroupNavigationControl : ItemsControl - { - #region CONSTRUCTORS - - static GroupNavigationControl() - { - GroupNavigationControl.GroupProperty = GroupHeaderControl.GroupProperty.AddOwner( typeof( GroupNavigationControl ) ); - - DefaultStyleKeyProperty.OverrideMetadata( - typeof( GroupNavigationControl ), - new FrameworkPropertyMetadata( new Markup.ThemeKey( typeof( TableView ), typeof( GroupNavigationControl ) ) ) ); - - DataGridControl.ParentDataGridControlPropertyKey.OverrideMetadata( - typeof( GroupNavigationControl ), - new FrameworkPropertyMetadata( new PropertyChangedCallback( GroupNavigationControl.OnParentGridControlChanged ) ) ); - - EventManager.RegisterClassHandler( - typeof( GroupNavigationControl ), - Mouse.LostMouseCaptureEvent, - new MouseEventHandler( GroupNavigationControl.OnLostMouseCapture ) ); - - EventManager.RegisterClassHandler( - typeof( GroupNavigationControl ), - Mouse.PreviewMouseDownEvent, - new MouseButtonEventHandler( GroupNavigationControl.OnPreviewMouseButtonDown ) ); - - EventManager.RegisterClassHandler( - typeof( GroupNavigationControl ), - Mouse.MouseDownEvent, - new MouseButtonEventHandler( GroupNavigationControl.OnMouseButtonDown ), true ); - - EventManager.RegisterClassHandler( - typeof( GroupNavigationControl ), - Mouse.MouseWheelEvent, - new MouseWheelEventHandler( GroupNavigationControl.OnMouseWheel ), true ); - } - - public GroupNavigationControl() - { - } - - #endregion CONSTRUCTORS - - #region Group Property - - public static readonly DependencyProperty GroupProperty; - - public Group Group - { - get - { - return GroupHeaderControl.GetGroup( this ); - } - set - { - GroupHeaderControl.SetGroup( this, value ); - } - } - - #endregion Group Property - - #region MainItemTemplate Property - - public static readonly DependencyProperty MainItemTemplateProperty = DependencyProperty.Register( - "MainItemTemplate", - typeof( DataTemplate ), - typeof( GroupNavigationControl ) ); - - public DataTemplate MainItemTemplate - { - get - { - return ( DataTemplate )this.GetValue( GroupNavigationControl.MainItemTemplateProperty ); - } - set - { - this.SetValue( GroupNavigationControl.MainItemTemplateProperty, value ); - } - } - - #endregion MainItemTemplate Property - - #region MainItemTemplateSelector Property - - public static readonly DependencyProperty MainItemTemplateSelectorProperty = DependencyProperty.Register( - "MainItemTemplateSelector", - typeof( DataTemplateSelector ), - typeof( GroupNavigationControl ) ); - - public DataTemplateSelector MainItemTemplateSelector - { - get - { - return ( DataTemplateSelector )this.GetValue( GroupNavigationControl.MainItemTemplateSelectorProperty ); - } - set - { - this.SetValue( GroupNavigationControl.MainItemTemplateSelectorProperty, value ); - } - } - - #endregion MainItemTemplateSelector Property - - #region MaxDropDownHeight Property - - public static readonly DependencyProperty MaxDropDownHeightProperty = DependencyProperty.Register( - "MaxDropDownHeight", - typeof( double ), - typeof( GroupNavigationControl ), - new FrameworkPropertyMetadata( SystemParameters.PrimaryScreenHeight / 3.0 ) ); - - public double MaxDropDownHeight - { - get - { - return ( double )this.GetValue( GroupNavigationControl.MaxDropDownHeightProperty ); - } - set - { - this.SetValue( GroupNavigationControl.MaxDropDownHeightProperty, value ); - } - } - - #endregion MaxDropDownHeight Property - - #region IsDropDownOpen Property - - [Browsable( false )] - public static readonly DependencyProperty IsDropDownOpenProperty = DependencyProperty.Register( - "IsDropDownOpen", - typeof( bool ), - typeof( GroupNavigationControl ), - new FrameworkPropertyMetadata( new PropertyChangedCallback( GroupNavigationControl.OnIsDropDownOpenChanged ) ) ); - - [Browsable( false )] - public bool IsDropDownOpen - { - get - { - return ( bool )this.GetValue( GroupNavigationControl.IsDropDownOpenProperty ); - } - set - { - this.SetValue( GroupNavigationControl.IsDropDownOpenProperty, value ); - } - } - - private static void OnIsDropDownOpenChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - GroupNavigationControl groupNavigationControl = ( GroupNavigationControl )sender; - - if( ( bool )e.NewValue ) - { - // To avoid lag while generating the control, we do - // a late binding of the items. - if( groupNavigationControl.ItemsSource == null ) - { - Group group = groupNavigationControl.DataContext as Group; - if( group != null ) - { - groupNavigationControl.ItemsSource = group.SiblingGroups; - } - } - - Mouse.Capture( groupNavigationControl, CaptureMode.SubTree ); - } - else - { - groupNavigationControl.ItemsSource = null; - - if( groupNavigationControl.IsKeyboardFocusWithin ) - { - groupNavigationControl.Focus(); - } - - if( Mouse.Captured == groupNavigationControl ) - { - Mouse.Capture( null ); - } - } - } - - #endregion IsDropDownOpen Property - - #region PartButton Private Property - - private Button PartButton - { - get; - set; - } - - #endregion PartButton Private Property - - #region PartToggleButton Private Property - - private ToggleButton PartToggleButton - { - get; - set; - } - - #endregion PartToggleButton Private Property - - #region PartPopup Private Property - - private Popup PartPopup - { - get; - set; - } - - #endregion PartPopup Private Property - - #region EVENT HANDLERS - - private static void OnLostMouseCapture( object sender, MouseEventArgs e ) - { - GroupNavigationControl groupNavigationControl = ( GroupNavigationControl )sender; - - DependencyObject originalSource = e.OriginalSource as DependencyObject; - - if( Mouse.Captured != groupNavigationControl ) - { - if( e.OriginalSource == groupNavigationControl ) - { - if( ( Mouse.Captured == null ) - && ( Xceed.Utils.Wpf.TreeHelper.IsDescendantOf( originalSource, groupNavigationControl ) ) ) - { - groupNavigationControl.Close(); - } - } - else if( ( originalSource != null ) && ( Xceed.Utils.Wpf.TreeHelper.IsDescendantOf( originalSource, groupNavigationControl ) ) ) - { - if( ( groupNavigationControl.IsDropDownOpen ) && ( Mouse.Captured == null ) ) - { - Mouse.Capture( groupNavigationControl, CaptureMode.SubTree ); - e.Handled = true; - } - } - else - { - groupNavigationControl.Close(); - } - } - } - - private static void OnPreviewMouseButtonDown( object sender, MouseButtonEventArgs e ) - { - GroupNavigationControl groupNavigationControl = ( GroupNavigationControl )sender; - Visual originalSource = e.OriginalSource as Visual; - - if( ( originalSource != null ) - && ( groupNavigationControl.PartButton != null ) - && ( groupNavigationControl.PartButton.IsAncestorOf( originalSource ) ) ) - { - if( groupNavigationControl.IsDropDownOpen ) - { - groupNavigationControl.Close(); - } - } - } - - private static void OnMouseButtonDown( object sender, MouseButtonEventArgs e ) - { - GroupNavigationControl groupNavigationControl = ( GroupNavigationControl )sender; - - if( !groupNavigationControl.IsKeyboardFocusWithin ) - { - groupNavigationControl.Focus(); - } - - e.Handled = true; - - if( ( Mouse.Captured == groupNavigationControl ) && ( e.OriginalSource == groupNavigationControl ) ) - { - groupNavigationControl.Close(); - } - } - - private static void OnMouseWheel( object sender, MouseWheelEventArgs e ) - { - GroupNavigationControl groupNavigationControl = ( GroupNavigationControl )sender; - - if( groupNavigationControl.IsDropDownOpen ) - { - // This is to avoid scrolling any other list if the drop down is open. - // If not set, the grid could scroll while leaving the drop down in view. - // The dorp down will then be left alone while the GroupNavigationControl - // might not be in view anymore. - e.Handled = true; - } - } - - private static void OnParentGridControlChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - GroupNavigationControl groupNavigationControl = sender as GroupNavigationControl; - - if( groupNavigationControl == null ) - return; - - DataGridControl parentGridControl = e.NewValue as DataGridControl; - - if( parentGridControl == null ) - return; - - groupNavigationControl.PrepareDefaultStyleKey( parentGridControl.GetView() ); - } - - #endregion EVENT HANDLERS - - #region OVERRIDES - - public override void OnApplyTemplate() - { - base.OnApplyTemplate(); - - this.PartButton = this.GetTemplateChild( "PART_Button" ) as Button; - this.PartToggleButton = this.GetTemplateChild( "PART_ToggleButton" ) as ToggleButton; - this.PartPopup = this.GetTemplateChild( "PART_Popup" ) as Popup; - } - - protected override DependencyObject GetContainerForItemOverride() - { - return new GroupNavigationControlItem( this ); - } - - protected override void PrepareContainerForItemOverride( DependencyObject element, object item ) - { - base.PrepareContainerForItemOverride( element, item ); - - element.SetValue( GroupHeaderControl.GroupProperty, item ); - } - - protected override void ClearContainerForItemOverride( DependencyObject element, object item ) - { - element.ClearValue( GroupHeaderControl.GroupProperty ); - - base.ClearContainerForItemOverride( element, item ); - } - - protected override void OnIsKeyboardFocusWithinChanged( DependencyPropertyChangedEventArgs e ) - { - base.OnIsKeyboardFocusWithinChanged( e ); - - if( ( this.IsDropDownOpen ) - && ( !base.IsKeyboardFocusWithin ) ) - { - this.Close(); - } - } - - #endregion OVERRIDES - - #region INTERNAL METHODS - - internal void NotifyGroupNavigationControlItemMouseDown( GroupNavigationControlItem groupNavigationControlItem ) - { - } - - internal void NotifyGroupNavigationControlItemMouseUp( GroupNavigationControlItem groupNavigationControlItem ) - { - Group group = groupNavigationControlItem.DataContext as Group; - if( group != null ) - { - GroupNavigationButton.NavigateToGroup.Execute( group, this ); - } - - this.Close(); - } - - #endregion INTERNAL METHODS - - #region PROTECTED METHODS - - protected internal virtual void PrepareDefaultStyleKey( Xceed.Wpf.DataGrid.Views.ViewBase view ) - { - this.DefaultStyleKey = view.GetDefaultStyleKey( typeof( GroupNavigationControl ) ); - } - - #endregion PROTECTED METHODS - - #region PRIVATE METHODS - - private void Close() - { - if( this.IsDropDownOpen ) - { - base.ClearValue( GroupNavigationControl.IsDropDownOpenProperty ); - - if( this.IsDropDownOpen ) - this.IsDropDownOpen = false; - } - } - - #endregion PRIVATE METHODS - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupNavigationControlItem.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupNavigationControlItem.cs deleted file mode 100644 index 45fc9666..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupNavigationControlItem.cs +++ /dev/null @@ -1,131 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows.Controls; -using System.Windows; -using Xceed.Wpf.DataGrid.Views; - -namespace Xceed.Wpf.DataGrid -{ - public class GroupNavigationControlItem : ContentControl - { - #region CONSTRUCTORS - - static GroupNavigationControlItem() - { - GroupNavigationControlItem.GroupProperty = GroupHeaderControl.GroupProperty.AddOwner( typeof( GroupNavigationControlItem ) ); - - DefaultStyleKeyProperty.OverrideMetadata( - typeof( GroupNavigationControlItem ), - new FrameworkPropertyMetadata( new Markup.ThemeKey( typeof( TableView ), typeof( GroupNavigationControlItem ) ) ) ); - - DataGridControl.ParentDataGridControlPropertyKey.OverrideMetadata( - typeof( GroupNavigationControlItem ), - new FrameworkPropertyMetadata( new PropertyChangedCallback( GroupNavigationControlItem.OnParentGridControlChanged ) ) ); - } - - public GroupNavigationControlItem( GroupNavigationControl parentNavigationControl ) - { - this.ParentNavigationControl = parentNavigationControl; - } - - #endregion CONSTRUCTORS - - #region ParentGroupNavigationControl Internal Property - - internal GroupNavigationControl ParentNavigationControl - { - get; - private set; - } - - #endregion ParentGroupNavigationControl Internal Property - - #region Group Property - - public static readonly DependencyProperty GroupProperty; - - public Group Group - { - get - { - return GroupHeaderControl.GetGroup( this ); - } - } - - #endregion Group Property - - #region OVERRIDES - - protected override void OnMouseLeftButtonDown( System.Windows.Input.MouseButtonEventArgs e ) - { - e.Handled = true; - - if( this.ParentNavigationControl != null ) - { - this.ParentNavigationControl.NotifyGroupNavigationControlItemMouseDown( this ); - } - - base.OnMouseLeftButtonDown( e ); - } - - protected override void OnMouseLeftButtonUp( System.Windows.Input.MouseButtonEventArgs e ) - { - e.Handled = true; - - if( this.ParentNavigationControl != null ) - { - this.ParentNavigationControl.NotifyGroupNavigationControlItemMouseUp( this ); - } - - base.OnMouseLeftButtonUp( e ); - } - - #endregion OVERRIDES - - #region EVENT HANDLERS - - private static void OnParentGridControlChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - GroupNavigationControlItem groupNavigationControlItem = sender as GroupNavigationControlItem; - - if( groupNavigationControlItem == null ) - return; - - DataGridControl parentGridControl = e.NewValue as DataGridControl; - - if( parentGridControl == null ) - return; - - groupNavigationControlItem.PrepareDefaultStyleKey( parentGridControl.GetView() ); - } - - #endregion EVENT HANDLERS - - #region PROTECTED METHODS - - protected internal virtual void PrepareDefaultStyleKey( Xceed.Wpf.DataGrid.Views.ViewBase view ) - { - this.DefaultStyleKey = view.GetDefaultStyleKey( typeof( GroupNavigationControlItem ) ); - } - - #endregion PROTECTED METHODS - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupingHelper.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupingHelper.cs deleted file mode 100644 index efd70150..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/GroupingHelper.cs +++ /dev/null @@ -1,280 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.Diagnostics; -using System.Windows; -using System.Windows.Data; -using Xceed.Utils.Wpf; - -namespace Xceed.Wpf.DataGrid -{ - internal static class GroupingHelper - { - public static bool HasGroup( DataGridContext dataGridContext ) - { - if( dataGridContext.GroupLevelDescriptions.Count > 0 ) - return true; - - return GroupingHelper.HasGroup( dataGridContext.DetailConfigurations ); - } - - private static bool HasGroup( DetailConfigurationCollection configurations ) - { - bool returnValue = false; - - int detailConfigurationCount = configurations.Count; - - for( int i = 0; i < detailConfigurationCount; i++ ) - { - DetailConfiguration detailConfiguration = configurations[ i ]; - - if( detailConfiguration.DetailConfigurations != null ) - returnValue = GroupingHelper.HasGroup( detailConfiguration.DetailConfigurations ); - - if( returnValue ) - break; - - returnValue = ( detailConfiguration.GroupLevelDescriptions.Count > 0 ); - - if( returnValue ) - break; - } - - return returnValue; - } - - public static bool IsAlreadyGroupedBy( ColumnManagerCell cell ) - { - DataGridContext cellDataGridContext = DataGridControl.GetDataGridContext( cell ); - - GroupLevelDescriptionCollection cellGroupLevelDescriptions = cellDataGridContext.GroupLevelDescriptions; - - bool isAlreadyGroupedBy = false; - if( cellDataGridContext != null ) - { - foreach( GroupLevelDescription description in cellGroupLevelDescriptions ) - { - if( description.FieldName == cell.FieldName ) - { - isAlreadyGroupedBy = true; - break; - } - } - } - - return isAlreadyGroupedBy; - } - - public static HierarchicalGroupByControl GetHierarchicalGroupByControl( UIElement element ) - { - DependencyObject parent = TreeHelper.GetParent( element ); - - while( parent != null ) - { - if( parent is HierarchicalGroupByControl ) - break; - - parent = TreeHelper.GetParent( parent ); - } - - return parent as HierarchicalGroupByControl; - } - - public static int GetGroupDescriptionIndex( ObservableCollection groupDescriptions, GroupLevelDescription groupLevelDescription, DropMarkAlignment alignment ) - { - int groupIndex = groupDescriptions.IndexOf( groupLevelDescription.GroupDescription ); - - if( groupIndex > -1 ) - { - if( alignment == DropMarkAlignment.Far ) - groupIndex++; - - return groupIndex; - } - else - { - // return the size of the Collection if not found - return groupDescriptions.Count; - } - } - - public static int GetGroupDescriptionIndexFromFieldName( DataGridContext dataGridContext, string fieldName, DropMarkAlignment alignment ) - { - ObservableCollection groupDescriptions = dataGridContext.Items.GroupDescriptions; - - for( int i = groupDescriptions.Count - 1; i >= 0; i-- ) - { - if( DataGridContext.GetColumnNameFromGroupDescription( groupDescriptions[ i ] ) == fieldName ) - { - if( alignment == DropMarkAlignment.Far ) - i++; - - return i; - } - } - - return dataGridContext.Items.GroupDescriptions.Count; - } - - public static bool IsColumnManagerCellInDataGridContext( DataGridContext dataGridContext, ColumnManagerCell cell ) - { - DataGridContext cellDataGridContext = DataGridControl.GetDataGridContext( cell ); - - Debug.Assert( cellDataGridContext != null ); - - if( ( dataGridContext != null ) && - ( cellDataGridContext != null ) && - ( dataGridContext.GroupLevelDescriptions == cellDataGridContext.GroupLevelDescriptions ) ) - return true; - - return GroupingHelper.IsGroupLevelDescriptionsInDetailConfigurations( dataGridContext.DetailConfigurations, cellDataGridContext.GroupLevelDescriptions ); - } - - private static bool IsGroupLevelDescriptionsInDetailConfigurations( DetailConfigurationCollection configurations, GroupLevelDescriptionCollection groupLevelDescriptions ) - { - bool returnValue = false; - - int detailConfigurationCount = configurations.Count; - - for( int i = 0; i < detailConfigurationCount; i++ ) - { - DetailConfiguration detailConfiguration = configurations[ i ]; - - if( detailConfiguration.DetailConfigurations != null ) - returnValue = GroupingHelper.IsGroupLevelDescriptionsInDetailConfigurations( detailConfiguration.DetailConfigurations, groupLevelDescriptions ); - - if( returnValue ) - break; - - returnValue = ( detailConfiguration.GroupLevelDescriptions == groupLevelDescriptions ); - - if( returnValue ) - break; - } - - return returnValue; - } - - public static void AddNewGroupFromColumnManagerCell( ColumnManagerCell cell, GroupLevelDescription draggedOverDescription, DropMarkAlignment alignment, DataGridControl parentDataGridControl ) - { - if( cell == null ) - return; - - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( cell ); - ColumnBase column = cell.ParentColumn; - - if( ( dataGridContext == null ) || - ( parentDataGridControl == null ) || - ( column == null ) || - ( parentDataGridControl != dataGridContext.DataGridControl ) ) - return; - - var addGroupCommand = dataGridContext.AddGroupCommand; - - if( draggedOverDescription != null ) - { - var position = GroupingHelper.GetGroupDescriptionIndexFromFieldName( dataGridContext, draggedOverDescription.FieldName, alignment ); - - if( addGroupCommand.CanExecute( column, position ) ) - { - addGroupCommand.Execute( column, position ); - } - } - else - { - if( addGroupCommand.CanExecute( column ) ) - { - addGroupCommand.Execute( column ); - } - } - } - - public static void AppendNewGroupFromColumnManagerCell( ColumnManagerCell cell, DataGridControl parentDataGridControl ) - { - GroupingHelper.AddNewGroupFromColumnManagerCell( cell, null, DropMarkAlignment.Far, parentDataGridControl ); - } - - public static void MoveGroupDescription( ColumnCollection targetColumns, ObservableCollection targetGroupDescriptions, GroupLevelDescription targetGroupLevelDescription, DropMarkAlignment targetAlignment, GroupLevelDescription movedGroupLevelDescription, DataGridControl parentDataGridControl ) - { - Debug.Assert( targetColumns != null ); - Debug.Assert( targetGroupDescriptions != null ); - Debug.Assert( targetGroupLevelDescription != null ); - Debug.Assert( movedGroupLevelDescription != null ); - - if( ( parentDataGridControl == null ) || - ( targetColumns == null ) || - ( targetGroupDescriptions == null ) || - ( targetGroupLevelDescription == null ) || - ( movedGroupLevelDescription == null ) ) - return; - - int oldPos = GroupingHelper.GetGroupDescriptionIndex( targetGroupDescriptions, movedGroupLevelDescription, DropMarkAlignment.Near ); - int newPos = GroupingHelper.GetGroupDescriptionIndex( targetGroupDescriptions, targetGroupLevelDescription, targetAlignment ); - - if( newPos > oldPos ) - { - newPos--; - } - - if( newPos != oldPos ) - { - Debug.Assert( oldPos < targetGroupDescriptions.Count ); - - using( parentDataGridControl.SetQueueBringIntoViewRestrictions( AutoScrollCurrentItemSourceTriggers.CollectionViewCurrentItemChanged ) ) - { - targetGroupDescriptions.Move( oldPos, newPos ); - } - } - } - - public static void RemoveGroupDescription( ObservableCollection groupDescriptions, GroupLevelDescription groupLevelDescription, DataGridControl parentDataGridControl ) - { - if( ( groupLevelDescription == null ) || - ( parentDataGridControl == null ) ) - return; - - using( parentDataGridControl.SetQueueBringIntoViewRestrictions( AutoScrollCurrentItemSourceTriggers.CollectionViewCurrentItemChanged ) ) - { - groupDescriptions.Remove( groupLevelDescription.GroupDescription ); - } - } - - public static bool ValidateMaxGroupDescriptions( DataGridContext draggedContext ) - { - Debug.Assert( draggedContext != null ); - - int maxGroupDescriptionCount = -1; - int currentGroupDescriptionCount = -1; - - CollectionView collectionView = draggedContext.Items; - - if( collectionView == null ) - return true; - - ObservableCollection groupDescriptions = collectionView.GroupDescriptions; - - if( groupDescriptions == null ) - return true; - - maxGroupDescriptionCount = draggedContext.MaxGroupLevels; - currentGroupDescriptionCount = groupDescriptions.Count; - - return ( ( maxGroupDescriptionCount == -1 ) || ( currentGroupDescriptionCount < maxGroupDescriptionCount ) ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/HashedLinkedList.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/HashedLinkedList.cs deleted file mode 100644 index 39b93cec..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/HashedLinkedList.cs +++ /dev/null @@ -1,380 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Collections; - -namespace Xceed.Wpf.DataGrid -{ - internal class HashedLinkedList : ICollection, ICollection - { - #region Constructors - - public HashedLinkedList() - : this( null ) - { - } - - public HashedLinkedList( IEnumerable collection ) - { - if( collection == null ) - { - m_innerLinkedList = new LinkedList(); - } - else - { - m_innerLinkedList = new LinkedList( collection ); - } - - m_nodeDictionary = new Dictionary>( m_innerLinkedList.Count ); - - var node = m_innerLinkedList.First; - - while( node != null ) - { - var value = node.Value; - - this.ValidateValue( value ); - - m_nodeDictionary.Add( value, node ); - } - } - - #endregion - - #region Validation - - private void ValidateNewNode( LinkedListNode node ) - { - if( node == null ) - throw new ArgumentNullException( "node" ); - - this.ValidateValue( node.Value ); - } - - private void ValidateExistingNode( LinkedListNode node ) - { - if( node == null ) - throw new ArgumentNullException( "node" ); - - if( node.List != m_innerLinkedList ) - throw new InvalidOperationException( "The specified LinkedListNode does belong to this LinkedList." ); - } - - private void ValidateValue( T value ) - { - if( value == null ) - throw new InvalidOperationException( "Null values are not supported by the HashedLinkedList" ); - - if( m_nodeDictionary.ContainsKey( value ) ) - throw new ArgumentException( "The HashedLinkedList already contains this value.", "value" ); - } - - #endregion - - #region Public Methods - - public LinkedListNode AddAfter( LinkedListNode node, T value ) - { - this.ValidateValue( value ); - - var newNode = m_innerLinkedList.AddAfter( node, value ); - - m_nodeDictionary.Add( value, newNode ); - - return newNode; - } - - public void AddAfter( LinkedListNode node, LinkedListNode newNode ) - { - this.ValidateNewNode( newNode ); - - m_innerLinkedList.AddAfter( node, newNode ); - - m_nodeDictionary.Add( newNode.Value, newNode ); - } - - public LinkedListNode AddBefore( LinkedListNode node, T value ) - { - this.ValidateValue( value ); - - var newNode = m_innerLinkedList.AddBefore( node, value ); - - m_nodeDictionary.Add( value, newNode ); - - return newNode; - } - - public void AddBefore( LinkedListNode node, LinkedListNode newNode ) - { - this.ValidateNewNode( newNode ); - - m_innerLinkedList.AddBefore( node, newNode ); - - m_nodeDictionary.Add( newNode.Value, newNode ); - } - - public LinkedListNode AddFirst( T value ) - { - this.ValidateValue( value ); - - var newNode = m_innerLinkedList.AddFirst( value ); - - m_nodeDictionary.Add( value, newNode ); - - return newNode; - } - - public void AddFirst( LinkedListNode node ) - { - this.ValidateNewNode( node ); - - m_innerLinkedList.AddFirst( node ); - - m_nodeDictionary.Add( node.Value, node ); - } - - - public LinkedListNode AddLast( T value ) - { - this.ValidateValue( value ); - - var newNode = m_innerLinkedList.AddLast( value ); - - m_nodeDictionary.Add( value, newNode ); - - return newNode; - } - - public void AddLast( LinkedListNode node ) - { - this.ValidateNewNode( node ); - - m_innerLinkedList.AddLast( node ); - - m_nodeDictionary.Add( node.Value, node ); - } - - public void Clear() - { - m_innerLinkedList.Clear(); - m_nodeDictionary.Clear(); - } - - public bool Contains( T value ) - { - return m_nodeDictionary.ContainsKey( value ); - } - - public void CopyTo( T[] array, int index ) - { - m_innerLinkedList.CopyTo( array, index ); - } - - public LinkedListNode Find( T value ) - { - if( value == null ) - return null; - - LinkedListNode node = null; - - m_nodeDictionary.TryGetValue( value, out node ); - - return node; - } - - public LinkedList.Enumerator GetEnumerator() - { - return m_innerLinkedList.GetEnumerator(); - } - - - public bool Remove( T value ) - { - LinkedListNode node = this.Find( value ); - - if( node != null ) - { - this.Remove( node ); - return true; - } - - return false; - } - - public void Remove( LinkedListNode node ) - { - m_innerLinkedList.Remove( node ); - m_nodeDictionary.Remove( node.Value ); - } - - public void RemoveFirst() - { - this.Remove( this.First ); - } - - public void RemoveLast() - { - this.Remove( this.Last ); - } - - #endregion - - #region Count Property - - public int Count - { - get - { - return m_innerLinkedList.Count; - } - } - - #endregion - - #region First Property - - public LinkedListNode First - { - get - { - return m_innerLinkedList.First; - } - } - - - #endregion - - #region Last Property - - public LinkedListNode Last - { - get - { - return m_innerLinkedList.Last; - } - } - - #endregion - - #region Private Fields - - private LinkedList m_innerLinkedList; - private Dictionary> m_nodeDictionary; - - #endregion - - - #region ICollection Members - - void ICollection.Add( T value ) - { - this.AddLast( value ); - } - - void ICollection.Clear() - { - this.Clear(); - } - - bool ICollection.Contains( T value ) - { - return this.Contains( value ); - } - - void ICollection.CopyTo( T[] array, int arrayIndex ) - { - this.CopyTo( array, arrayIndex ); - } - - int ICollection.Count - { - get - { - return this.Count; - } - } - - bool ICollection.IsReadOnly - { - get - { - return false; - } - } - - bool ICollection.Remove( T value ) - { - return this.Remove( value ); - } - - #endregion - - #region IEnumerable Members - - IEnumerator IEnumerable.GetEnumerator() - { - return this.GetEnumerator(); - } - - #endregion - - #region IEnumerable Members - - IEnumerator IEnumerable.GetEnumerator() - { - return this.GetEnumerator(); - } - - #endregion - - #region ICollection Members - - void ICollection.CopyTo( Array array, int index ) - { - ( ( ICollection )m_innerLinkedList ).CopyTo( array, index ); - } - - int ICollection.Count - { - get - { - return this.Count; - } - } - - bool ICollection.IsSynchronized - { - get - { - return false; - } - } - - object ICollection.SyncRoot - { - get - { - return ( ( ICollection )m_innerLinkedList ).SyncRoot; - } - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/HeaderFooterItem.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/HeaderFooterItem.cs deleted file mode 100644 index 3fdc5132..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/HeaderFooterItem.cs +++ /dev/null @@ -1,449 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Diagnostics; -using System.Linq; -using System.Windows; -using System.Windows.Automation.Peers; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Input; -using System.Windows.Media; - -namespace Xceed.Wpf.DataGrid -{ - internal class HeaderFooterItem : ContentPresenter, IDataGridItemContainer - { - #region Static Fields - - private static readonly Binding m_sIsCurrentInternalBinding; - private static readonly Binding m_sItemIndexBinding; - private static readonly Binding m_sIsBeingEditedInternalBinding; - private static readonly Binding m_sHasValidationErrorInternalBinding; - private static readonly Binding m_sRowSelectorVisibleBinding; - private static readonly Binding m_sRowSelectorStyleBinding; - - #endregion - - static HeaderFooterItem() - { - KeyboardNavigation.TabNavigationProperty.OverrideMetadata( typeof( HeaderFooterItem ), new FrameworkPropertyMetadata( KeyboardNavigationMode.None ) ); - - HeaderFooterItem.ContainerProperty = ContainerPropertyKey.DependencyProperty; - - m_sItemIndexBinding = new Binding(); - m_sItemIndexBinding.RelativeSource = RelativeSource.Self; - m_sItemIndexBinding.Path = new PropertyPath( "(0).(1)", HeaderFooterItem.ContainerProperty, DataGridVirtualizingPanel.ItemIndexProperty ); - m_sItemIndexBinding.Mode = BindingMode.OneWay; - - m_sIsCurrentInternalBinding = new Binding(); - m_sIsCurrentInternalBinding.RelativeSource = RelativeSource.Self; - m_sIsCurrentInternalBinding.Path = new PropertyPath( "(0).(1)", HeaderFooterItem.ContainerProperty, Row.IsCurrentProperty ); - m_sIsCurrentInternalBinding.Mode = BindingMode.OneWay; - - m_sIsBeingEditedInternalBinding = new Binding(); - m_sIsBeingEditedInternalBinding.RelativeSource = RelativeSource.Self; - m_sIsBeingEditedInternalBinding.Path = new PropertyPath( "(0).(1)", HeaderFooterItem.ContainerProperty, Row.IsBeingEditedProperty ); - m_sIsBeingEditedInternalBinding.Mode = BindingMode.OneWay; - - m_sHasValidationErrorInternalBinding = new Binding(); - m_sHasValidationErrorInternalBinding.RelativeSource = RelativeSource.Self; - m_sHasValidationErrorInternalBinding.Path = new PropertyPath( "(0).(1)", HeaderFooterItem.ContainerProperty, Row.HasValidationErrorProperty ); - m_sHasValidationErrorInternalBinding.Mode = BindingMode.OneWay; - - m_sRowSelectorVisibleBinding = new Binding(); - m_sRowSelectorVisibleBinding.RelativeSource = RelativeSource.Self; - m_sRowSelectorVisibleBinding.Path = new PropertyPath( "(0).(1)", HeaderFooterItem.ContainerProperty, RowSelector.VisibleProperty ); - m_sRowSelectorVisibleBinding.Mode = BindingMode.OneWay; - - m_sRowSelectorStyleBinding = new Binding(); - m_sRowSelectorStyleBinding.RelativeSource = RelativeSource.Self; - m_sRowSelectorStyleBinding.Path = new PropertyPath( "(0).(1)", HeaderFooterItem.ContainerProperty, RowSelector.RowSelectorStyleProperty ); - m_sRowSelectorStyleBinding.Mode = BindingMode.OneWay; - } - - internal HeaderFooterItem() - { - m_itemContainerManager = new DataGridItemContainerManager( this ); - - //to prevent creation of the headerfooteritem by anybody else than us. - BindingOperations.SetBinding( this, HeaderFooterItem.ItemIndexProperty, m_sItemIndexBinding ); - BindingOperations.SetBinding( this, HeaderFooterItem.IsBeingEditedInternalProperty, m_sIsBeingEditedInternalBinding ); - BindingOperations.SetBinding( this, HeaderFooterItem.IsCurrentInternalProperty, m_sIsCurrentInternalBinding ); - BindingOperations.SetBinding( this, HeaderFooterItem.HasValidationErrorInternalProperty, m_sHasValidationErrorInternalBinding ); - - BindingOperations.SetBinding( this, RowSelector.VisibleProperty, m_sRowSelectorVisibleBinding ); - BindingOperations.SetBinding( this, RowSelector.RowSelectorStyleProperty, m_sRowSelectorStyleBinding ); - } - - #region IsCurrentInternal Property - - private static readonly DependencyProperty IsCurrentInternalProperty = DependencyProperty.Register( - "IsCurrentInternal", - typeof( bool ), - typeof( HeaderFooterItem ), - new FrameworkPropertyMetadata( - ( bool )false, - new PropertyChangedCallback( OnIsCurrentInternalChanged ) ) ); - - private static void OnIsCurrentInternalChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) - { - ( ( HeaderFooterItem )d ).OnIsCurrentInternalChanged( e ); - } - - protected virtual void OnIsCurrentInternalChanged( DependencyPropertyChangedEventArgs e ) - { - this.SetValue( Row.IsCurrentPropertyKey, e.NewValue ); - } - - #endregion - - #region IsBeingEditedInternal Property - - private static readonly DependencyProperty IsBeingEditedInternalProperty = DependencyProperty.Register( - "IsBeingEditedInternal", - typeof( bool ), - typeof( HeaderFooterItem ), - new FrameworkPropertyMetadata( - ( bool )false, - new PropertyChangedCallback( OnIsBeingEditedInternalChanged ) ) ); - - private static void OnIsBeingEditedInternalChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) - { - ( ( HeaderFooterItem )d ).OnIsBeingEditedInternalChanged( e ); - } - - protected virtual void OnIsBeingEditedInternalChanged( DependencyPropertyChangedEventArgs e ) - { - this.SetValue( Row.IsBeingEditedPropertyKey, e.NewValue ); - } - - #endregion - - #region HasValidationErrorInternal Property - - private static readonly DependencyProperty HasValidationErrorInternalProperty = DependencyProperty.Register( - "HasValidationErrorInternal", - typeof( bool ), - typeof( HeaderFooterItem ), - new FrameworkPropertyMetadata( - ( bool )false, - new PropertyChangedCallback( OnHasValidationErrorInternalChanged ) ) ); - - private static void OnHasValidationErrorInternalChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) - { - ( ( HeaderFooterItem )d ).OnHasValidationErrorInternalChanged( e ); - } - - protected virtual void OnHasValidationErrorInternalChanged( DependencyPropertyChangedEventArgs e ) - { - this.SetValue( Row.HasValidationErrorPropertyKey, e.NewValue ); - } - - #endregion - - #region IsCurrent Property - - public static readonly DependencyProperty IsCurrentProperty = Row.IsCurrentProperty.AddOwner( typeof( HeaderFooterItem ) ); - - public bool IsCurrent - { - get - { - return ( bool )this.GetValue( IsCurrentProperty ); - } - } - - #endregion - - #region IsBeingEdited Property - - public static readonly DependencyProperty IsBeingEditedProperty = Row.IsBeingEditedProperty.AddOwner( typeof( HeaderFooterItem ) ); - - public bool IsBeingEdited - { - get - { - return ( bool )this.GetValue( IsBeingEditedProperty ); - } - } - - #endregion - - #region HasValidationError Property - - public static readonly DependencyProperty HasValidationErrorProperty = Row.HasValidationErrorProperty.AddOwner( typeof( HeaderFooterItem ) ); - - public bool HasValidationError - { - get - { - return ( bool )this.GetValue( HasValidationErrorProperty ); - } - } - - #endregion - - #region ItemIndex Property - - public static readonly DependencyProperty ItemIndexProperty = DataGridVirtualizingPanel.ItemIndexProperty.AddOwner( typeof( HeaderFooterItem ) ); - - #endregion - - #region Container Property - - private static readonly DependencyPropertyKey ContainerPropertyKey = DependencyProperty.RegisterReadOnly( - "Container", - typeof( DependencyObject ), - typeof( HeaderFooterItem ), - new FrameworkPropertyMetadata( ( DependencyObject )null ) ); - - public static readonly DependencyProperty ContainerProperty; - - public DependencyObject Container - { - get - { - return ( DependencyObject )this.GetValue( ContainerProperty ); - } - } - - private void SetContainer( DependencyObject value ) - { - this.SetValue( ContainerPropertyKey, value ); - } - - #endregion - - #region CanBeRecycled Protected Property - - protected virtual bool CanBeRecycled - { - get - { - if( this.IsKeyboardFocused - || this.IsKeyboardFocusWithin - || this.IsBeingEdited ) - return false; - - return m_itemContainerManager.CanBeRecycled; - } - } - - #endregion - - #region VisualRootElementType Property - - internal Type VisualRootElementType - { - get - { - Type elementType = null; - DataTemplate template = m_initializingDataItem as DataTemplate; - - if( template == null ) - { - template = this.ContentTemplate; - } - - if( ( template != null ) && ( template.VisualTree != null ) ) - { - elementType = template.VisualTree.Type; - } - - if( elementType == null ) - { - Visual visual = this.AsVisual(); - - if( visual == null ) - { - //this will force the control to apply the content template "inline"... - this.ApplyTemplate(); - - visual = this.AsVisual(); - } - - Debug.Assert( visual != null ); - - if( visual != null ) - { - elementType = visual.GetType(); - } - } - - return elementType; - } - } - - #endregion - - public override void OnApplyTemplate() - { - base.OnApplyTemplate(); - - m_itemContainerManager.Update(); - } - - public Visual AsVisual() - { - if( this.VisualChildrenCount == 0 ) - return null; - - return this.GetVisualChild( 0 ); - } - - - protected void PrepareContainer( DataGridContext dataGridContext, object item ) - { - if( dataGridContext == null ) - throw new ArgumentNullException( "dataGridContext" ); - - m_initializingDataGridContext = dataGridContext; - m_initializingDataItem = item; - - if( !this.IsLoaded ) - { - if( dataGridContext.DataGridControl.ItemsHost.IsAncestorOf( this ) ) - { - this.ApplyTemplate(); - this.PrepareContainerWorker(); - } - else - { - // When a HeaderFooterItem is in the FixedHeaders or FixedFooters of the grid, - // we must prepare the container only when the container is loaded so that the - // TableView.CanScrollHorizontallyProperty attached property is taken into consideration. - m_loadedHandler = this.HeaderFooterItem_Loaded; - this.Loaded += m_loadedHandler; - } - } - else - { - this.PrepareContainerWorker(); - } - } - - protected void ClearContainer() - { - if( !m_isRecyclingCandidate ) - { - // Ensure we removed the HeaderFooterItem_Loaded event handler if it was not yet loaded - if( m_loadedHandler != null ) - { - this.Loaded -= m_loadedHandler; - m_loadedHandler = null; - } - } - - m_itemContainerManager.Clear( m_isRecyclingCandidate ); - } - - protected override void OnIsKeyboardFocusWithinChanged( DependencyPropertyChangedEventArgs e ) - { - base.OnIsKeyboardFocusWithinChanged( e ); - - //In this case, since the first visual child is not a row, I want to stub the IsCurrent property with the KeyboardFocus. - Row row = this.AsVisual() as Row; - - if( row == null ) - { - this.SetValue( IsCurrentInternalProperty, e.NewValue ); - } - } - - protected override void OnMouseLeftButtonDown( MouseButtonEventArgs e ) - { - base.OnMouseLeftButtonDown( e ); - - if( !e.Handled ) - { - e.Handled = DataGridControl.SetFocusUIElementHelper( this ); - } - } - - private void HeaderFooterItem_Loaded( object sender, RoutedEventArgs e ) - { - if( m_loadedHandler != null ) - { - this.Loaded -= m_loadedHandler; - m_loadedHandler = null; - } - - this.PrepareContainerWorker(); - //Bind properties that CAN be bound (if the DataTemplate instantiated a Row as first visual child ) - } - - private void PrepareContainerWorker() - { - m_isRecyclingCandidate = false; - - var rootContainer = this.AsVisual(); - - this.SetContainer( rootContainer ); - - m_itemContainerManager.Prepare( m_initializingDataGridContext, m_initializingDataItem ); - - m_initializingDataGridContext = null; - m_initializingDataItem = null; - } - - #region IDataGridItemContainer Members - - bool IDataGridItemContainer.CanBeRecycled - { - get - { - return this.CanBeRecycled; - } - } - - bool IDataGridItemContainer.IsRecyclingCandidate - { - get - { - return m_isRecyclingCandidate; - } - set - { - m_isRecyclingCandidate = value; - } - } - - void IDataGridItemContainer.PrepareContainer( DataGridContext dataGridContext, object item ) - { - this.PrepareContainer( dataGridContext, item ); - } - - void IDataGridItemContainer.ClearContainer() - { - this.ClearContainer(); - } - - void IDataGridItemContainer.CleanRecyclingCandidate() - { - m_itemContainerManager.CleanRecyclingCandidates(); - } - - #endregion - - private readonly DataGridItemContainerManager m_itemContainerManager; - private DataGridContext m_initializingDataGridContext; // = null - private object m_initializingDataItem; // = null - private RoutedEventHandler m_loadedHandler; - private bool m_isRecyclingCandidate; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/HierarchicalGroupByControl.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/HierarchicalGroupByControl.cs deleted file mode 100644 index 2304dcba..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/HierarchicalGroupByControl.cs +++ /dev/null @@ -1,665 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.ComponentModel; -using System.Diagnostics; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Media; -using Xceed.Utils.Wpf.DragDrop; - -namespace Xceed.Wpf.DataGrid -{ - [TemplatePart( Name = "PART_HierarchicalGroupByControlTreeView", Type = typeof( TreeView ) )] - public class HierarchicalGroupByControl : Control, IDropTarget, INotifyPropertyChanged - { - #region CONSTRUCTORS - - static HierarchicalGroupByControl() - { - // This DefaultStyleKey will only be used in design-time. - DefaultStyleKeyProperty.OverrideMetadata( typeof( HierarchicalGroupByControl ), new FrameworkPropertyMetadata( new Markup.ThemeKey( typeof( Views.TableView ), typeof( HierarchicalGroupByControl ) ) ) ); - - // Default binding to HierarchicalGroupByControl value - FrameworkElementFactory staircaseFactory = new FrameworkElementFactory( typeof( StaircasePanel ) ); - ItemsPanelTemplate itemsPanelTemplate = new ItemsPanelTemplate( staircaseFactory ); - - Binding binding = new Binding(); - binding.Path = new PropertyPath( HierarchicalGroupByControl.ConnectionLineAlignmentProperty ); - binding.Mode = BindingMode.OneWay; - binding.RelativeSource = RelativeSource.Self; - staircaseFactory.SetBinding( StaircasePanel.ConnectionLineAlignmentProperty, binding ); - - binding = new Binding(); - binding.Path = new PropertyPath( HierarchicalGroupByControl.ConnectionLineOffsetProperty ); - binding.Mode = BindingMode.OneWay; - binding.RelativeSource = RelativeSource.Self; - staircaseFactory.SetBinding( StaircasePanel.ConnectionLineOffsetProperty, binding ); - - binding = new Binding(); - binding.Path = new PropertyPath( HierarchicalGroupByControl.ConnectionLinePenProperty ); - binding.Mode = BindingMode.OneWay; - binding.RelativeSource = RelativeSource.Self; - staircaseFactory.SetBinding( StaircasePanel.ConnectionLinePenProperty, binding ); - - binding = new Binding(); - binding.Path = new PropertyPath( HierarchicalGroupByControl.StairHeightProperty ); - binding.Mode = BindingMode.OneWay; - binding.RelativeSource = RelativeSource.Self; - staircaseFactory.SetBinding( StaircasePanel.StairHeightProperty, binding ); - - binding = new Binding(); - binding.Path = new PropertyPath( HierarchicalGroupByControl.StairSpacingProperty ); - binding.Mode = BindingMode.OneWay; - binding.RelativeSource = RelativeSource.Self; - staircaseFactory.SetBinding( StaircasePanel.StairSpacingProperty, binding ); - - itemsPanelTemplate.Seal(); - - ItemsControl.ItemsPanelProperty.OverrideMetadata( typeof( HierarchicalGroupByControl ), new FrameworkPropertyMetadata( itemsPanelTemplate ) ); - - DataGridControl.ParentDataGridControlPropertyKey.OverrideMetadata( typeof( HierarchicalGroupByControl ), new FrameworkPropertyMetadata( new PropertyChangedCallback( HierarchicalGroupByControl.ParentGridControlChangedCallback ) ) ); - FocusableProperty.OverrideMetadata( typeof( HierarchicalGroupByControl ), new FrameworkPropertyMetadata( false ) ); - - } - - #endregion - - #region AllowGroupingModification Property - - public static readonly DependencyProperty AllowGroupingModificationProperty = - GroupByControl.AllowGroupingModificationProperty.AddOwner( typeof( HierarchicalGroupByControl ), new UIPropertyMetadata( true ) ); - - public bool AllowGroupingModification - { - get - { - return ( bool )this.GetValue( HierarchicalGroupByControl.AllowGroupingModificationProperty ); - } - set - { - this.SetValue( HierarchicalGroupByControl.AllowGroupingModificationProperty, value ); - } - } - - #endregion AllowGroupingModification Property - - #region AllowSort Property - - public static readonly DependencyProperty AllowSortProperty = - ColumnManagerRow.AllowSortProperty.AddOwner( typeof( HierarchicalGroupByControl ), new UIPropertyMetadata( true ) ); - - public bool AllowSort - { - get - { - return ( bool )this.GetValue( HierarchicalGroupByControl.AllowSortProperty ); - } - set - { - this.SetValue( HierarchicalGroupByControl.AllowSortProperty, value ); - } - } - - #endregion AllowSort Property - - #region ConnectionLineAlignment Property - - public static readonly DependencyProperty ConnectionLineAlignmentProperty = - StaircasePanel.ConnectionLineAlignmentProperty.AddOwner( typeof( HierarchicalGroupByControl ) ); - - public ConnectionLineAlignment ConnectionLineAlignment - { - get - { - return ( ConnectionLineAlignment )this.GetValue( HierarchicalGroupByControl.ConnectionLineAlignmentProperty ); - } - set - { - this.SetValue( HierarchicalGroupByControl.ConnectionLineAlignmentProperty, value ); - } - } - - #endregion ConnectionLineAlignment Property - - #region ConnectionLineOffset Property - - public static readonly DependencyProperty ConnectionLineOffsetProperty = - StaircasePanel.ConnectionLineOffsetProperty.AddOwner( typeof( HierarchicalGroupByControl ) ); - - public double ConnectionLineOffset - { - get - { - return ( double )this.GetValue( HierarchicalGroupByControl.ConnectionLineOffsetProperty ); - } - set - { - this.SetValue( HierarchicalGroupByControl.ConnectionLineOffsetProperty, value ); - } - } - - #endregion ConnectionLineOffset Property - - #region ConnectionLinePen Property - - public static readonly DependencyProperty ConnectionLinePenProperty = - StaircasePanel.ConnectionLinePenProperty.AddOwner( typeof( HierarchicalGroupByControl ) ); - - public Pen ConnectionLinePen - { - get - { - return ( Pen )this.GetValue( HierarchicalGroupByControl.ConnectionLinePenProperty ); - } - set - { - this.SetValue( HierarchicalGroupByControl.ConnectionLinePenProperty, value ); - } - } - - #endregion ConnectionLinePen Property - - #region StairHeight Property - - public static readonly DependencyProperty StairHeightProperty = - StaircasePanel.StairHeightProperty.AddOwner( typeof( HierarchicalGroupByControl ) ); - - public double StairHeight - { - get - { - return ( double )this.GetValue( HierarchicalGroupByControl.StairHeightProperty ); - } - set - { - this.SetValue( HierarchicalGroupByControl.StairHeightProperty, value ); - } - } - - #endregion StairHeight Property - - #region StairSpacing Property - - public static readonly DependencyProperty StairSpacingProperty = - StaircasePanel.StairSpacingProperty.AddOwner( typeof( HierarchicalGroupByControl ) ); - - public double StairSpacing - { - get - { - return ( double )this.GetValue( HierarchicalGroupByControl.StairSpacingProperty ); - } - set - { - this.SetValue( HierarchicalGroupByControl.StairSpacingProperty, value ); - } - } - - #endregion StairSpacing Property - - #region HasGroups - - public bool HasGroups - { - get - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - if( dataGridContext == null ) - return false; - - // We only display the NoGroupContent if the HierarchicalGroupByControl is at the master level - if( dataGridContext.ParentDataGridContext != null ) - return false; - - // We look for GroupLevelDescription in the DataGridContext and all details - return ( GroupingHelper.HasGroup( dataGridContext ) == false ); - } - } - - #endregion - - #region NoGroupContent Property - - public static readonly DependencyProperty NoGroupContentProperty = - GroupByControl.NoGroupContentProperty.AddOwner( - typeof( HierarchicalGroupByControl ), - new PropertyMetadata( "Drag a column header here to group by that column." ) ); - - public object NoGroupContent - { - get - { - return this.GetValue( HierarchicalGroupByControl.NoGroupContentProperty ); - } - set - { - this.SetValue( HierarchicalGroupByControl.NoGroupContentProperty, value ); - } - } - - #endregion NoGroupContent Property - - #region PROTECTED INTERNAL METHODS - - protected internal virtual void PrepareDefaultStyleKey( Xceed.Wpf.DataGrid.Views.ViewBase view ) - { - this.DefaultStyleKey = view.GetDefaultStyleKey( typeof( HierarchicalGroupByControl ) ); - } - - #endregion - - #region PRIVATE STATIC METHODS - - private static HierarchicalGroupByControlNode GetHierarchicalGroupByControlNode( UIElement element ) - { - HierarchicalGroupByControlNode hierarchicalGroupByControlNode = element as HierarchicalGroupByControlNode; - - if( hierarchicalGroupByControlNode != null ) - return hierarchicalGroupByControlNode; - - int childCount = VisualTreeHelper.GetChildrenCount( element ); - - for( int i = 0; i < childCount; i++ ) - { - UIElement child = VisualTreeHelper.GetChild( element, i ) as UIElement; - - if( child != null ) - hierarchicalGroupByControlNode = HierarchicalGroupByControl.GetHierarchicalGroupByControlNode( child ); - - if( hierarchicalGroupByControlNode != null ) - break; - } - - return hierarchicalGroupByControlNode; - } - - private static TreeViewItem GetTreeViewItemFromGroupLevelDescriptionCollection( TreeViewItem rootItem, GroupLevelDescriptionCollection groupLevelDescriptions ) - { - TreeViewItem returned = null; - Debug.Assert( rootItem != null ); - Debug.Assert( groupLevelDescriptions != null ); - - if( rootItem == null ) - throw new DataGridInternalException( "rootItem is null." ); - - foreach( object item in rootItem.Items ) - { - TreeViewItem child = rootItem.ItemContainerGenerator.ContainerFromItem( item ) as TreeViewItem; - - // It may not be visible - if( child == null ) - continue; - - DetailConfiguration detailConfiguration = child.Header as DetailConfiguration; - - if( detailConfiguration == null ) - throw new DataGridInternalException( "The item's DataContext must be a DetailConfiguration except for the top-most HierarchicalGroupByControl, which contains a DataGridContext." ); - - if( groupLevelDescriptions == detailConfiguration.GroupLevelDescriptions ) - { - returned = child; - break; - } - - returned = HierarchicalGroupByControl.GetTreeViewItemFromGroupLevelDescriptionCollection( child, groupLevelDescriptions ); - - if( returned != null ) - break; - } - - return returned; - } - - private static TreeViewItem GetTreeViewItemFromGroupLevelDescription( TreeViewItem rootItem, GroupLevelDescription groupLevelDescription ) - { - TreeViewItem returned = null; - Debug.Assert( rootItem != null ); - Debug.Assert( groupLevelDescription != null ); - - if( rootItem == null ) - throw new DataGridInternalException( "rootItem is null." ); - - foreach( object item in rootItem.Items ) - { - TreeViewItem child = rootItem.ItemContainerGenerator.ContainerFromItem( item ) as TreeViewItem; - - Debug.Assert( child != null ); - if( child == null ) - throw new DataGridInternalException( "An item does not contain a valid item." ); - - DetailConfiguration detailConfiguration = child.Header as DetailConfiguration; - - if( detailConfiguration == null ) - throw new DataGridInternalException( "An item's DataContext must be a DetailConfiguration except for the top-most HierarchicalGroupByControl, which contains a DataGridContext." ); - - if( detailConfiguration.GroupLevelDescriptions.Contains( groupLevelDescription ) ) - { - returned = child; - break; - } - - returned = HierarchicalGroupByControl.GetTreeViewItemFromGroupLevelDescription( child, groupLevelDescription ); - - if( returned != null ) - break; - } - - return returned; - } - - private static void ParentGridControlChangedCallback( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - DataGridControl parentDataGrid = e.NewValue as DataGridControl; - HierarchicalGroupByControl groupByControl = ( HierarchicalGroupByControl )sender; - - if( parentDataGrid != null ) - groupByControl.PrepareDefaultStyleKey( parentDataGrid.GetView() ); - } - - #endregion - - #region INTERNAL METHODS - - internal HierarchicalGroupByControlNode GetHierarchicalGroupByControlNodeFromColumnManagerCell( ColumnManagerCell cell ) - { - Debug.Assert( cell != null ); - if( cell == null ) - return null; - - DataGridContext cellDataGridContext = DataGridControl.GetDataGridContext( cell ); - - if( cellDataGridContext == null ) - throw new DataGridInternalException( "A DataGridContext cannot be null on ColumnManagerCell." ); - - TreeView treeView = this.GetTemplateChild( @"PART_HierarchicalGroupByControlTreeView" ) as TreeView; - - if( treeView == null ) - return null; - - if( treeView.Items.Count == 0 ) - throw new DataGridInternalException( "The HierarchicalGroupByControl should contain at least one grouping level." ); - - // The first item is always the top level HierarchicalGroupByControlNode - TreeViewItem rootItem = treeView.ItemContainerGenerator.ContainerFromItem( treeView.Items[ 0 ] ) as TreeViewItem; - - // It may not be visible - if( rootItem == null ) - return null; - - TreeViewItem dropMarkedTreeViewItem = null; - - DataGridContext rootDataGridContext = rootItem.Header as DataGridContext; - - if( ( rootDataGridContext != null ) && ( rootDataGridContext.GroupLevelDescriptions == cellDataGridContext.GroupLevelDescriptions ) ) - { - dropMarkedTreeViewItem = rootItem; - } - else - { - GroupLevelDescriptionCollection groupLevelDescriptions = cellDataGridContext.GroupLevelDescriptions; - - dropMarkedTreeViewItem = HierarchicalGroupByControl.GetTreeViewItemFromGroupLevelDescriptionCollection( rootItem, groupLevelDescriptions ); - } - - // If null, it means the cell does not belong to this detail - if( dropMarkedTreeViewItem == null ) - return null; - - ContentPresenter treeViewItemHeader = dropMarkedTreeViewItem.Template.FindName( "PART_Header", dropMarkedTreeViewItem ) as ContentPresenter; - - // It may not be visible - if( treeViewItemHeader == null ) - return null; - - HierarchicalGroupByControlNode hierarchicalGroupByControlNode = HierarchicalGroupByControl.GetHierarchicalGroupByControlNode( treeViewItemHeader ); - - return hierarchicalGroupByControlNode; - } - - internal HierarchicalGroupByControlNode GetHierarchicalGroupByControlNodeFromHierarchicalGroupByItem( HierarchicalGroupByItem hierarchicalGroupByItem ) - { - Debug.Assert( hierarchicalGroupByItem != null ); - if( hierarchicalGroupByItem == null ) - return null; - - TreeView treeView = this.GetTemplateChild( @"PART_HierarchicalGroupByControlTreeView" ) as TreeView; - - if( treeView == null ) - return null; - - if( treeView.Items.Count == 0 ) - throw new DataGridInternalException( "The HierarchicalGroupByControl should contain at least one grouping level." ); - - // The first item is always the top level HierarchicalGroupByControlNode - TreeViewItem rootItem = treeView.ItemContainerGenerator.ContainerFromItem( treeView.Items[ 0 ] ) as TreeViewItem; - - if( rootItem == null ) - throw new DataGridInternalException( "The root item is null." ); - - GroupLevelDescription detailGroupLevelDescription = hierarchicalGroupByItem.Content as GroupLevelDescription; - - Debug.Assert( detailGroupLevelDescription != null ); - - TreeViewItem dropMarkedTreeViewItem = null; - - DataGridContext rootDataGridContext = rootItem.Header as DataGridContext; - - Debug.Assert( rootDataGridContext != null ); - - if( rootDataGridContext.GroupLevelDescriptions.Contains( detailGroupLevelDescription ) ) - { - dropMarkedTreeViewItem = rootItem; - } - else - { - dropMarkedTreeViewItem = HierarchicalGroupByControl.GetTreeViewItemFromGroupLevelDescription( rootItem, detailGroupLevelDescription ); - } - - - // If null, it means the cell does not belong to this detail - if( dropMarkedTreeViewItem == null ) - return null; - - ContentPresenter treeViewItemHeader = dropMarkedTreeViewItem.Template.FindName( "PART_Header", dropMarkedTreeViewItem ) as ContentPresenter; - - Debug.Assert( treeViewItemHeader != null ); - if( treeViewItemHeader == null ) - throw new DataGridInternalException( "An error occurred while retrieving the PART_Header template part of an item containing a HierarchicalGroupByControlNode." ); - - HierarchicalGroupByControlNode hierarchicalGroupByControlNode = HierarchicalGroupByControl.GetHierarchicalGroupByControlNode( treeViewItemHeader ); - - return hierarchicalGroupByControlNode; - } - - #endregion - - #region IDropTarget Members - - - bool IDropTarget.CanDropElement( UIElement draggedElement, RelativePoint mousePosition ) - { - bool canDrop = this.AllowGroupingModification; - - ColumnManagerCell cell = null; - HierarchicalGroupByItem hierarchicalGroupByItem = null; - - if( canDrop ) - { - cell = draggedElement as ColumnManagerCell; - - if( cell != null ) - { - ColumnBase parentColumn = cell.ParentColumn; - - if( ( parentColumn == null ) || ( !parentColumn.AllowGroup ) ) - return false; - - // Check if already grouped using the cell's DataGridContext - canDrop = !GroupingHelper.IsAlreadyGroupedBy( cell ); - - if( canDrop ) - { - DataGridContext thisDataGridContext = DataGridControl.GetDataGridContext( this ); - - if( thisDataGridContext.Items != null ) - canDrop = thisDataGridContext.Items.CanGroup; - - if( canDrop ) - { - canDrop = GroupingHelper.IsColumnManagerCellInDataGridContext( thisDataGridContext, cell ); - - if( canDrop == true ) - canDrop = GroupingHelper.ValidateMaxGroupDescriptions( DataGridControl.GetDataGridContext( draggedElement ) ); - } - } - } - else - { - hierarchicalGroupByItem = draggedElement as HierarchicalGroupByItem; - - if( hierarchicalGroupByItem == null ) - canDrop = false; - - if( canDrop ) - { - // Try to get the HierarchicalGroupByControlNode in which this HierarchicalGroupByItem can be added using the parent HierarchicalGroupByControl => null it can't - HierarchicalGroupByControlNode draggedHierarchicalGroupByControlNode = this.GetHierarchicalGroupByControlNodeFromHierarchicalGroupByItem( hierarchicalGroupByItem ); - - if( draggedHierarchicalGroupByControlNode == null ) - canDrop = false; - } - } - } - - bool returnedValue = ( ( cell != null ) || ( hierarchicalGroupByItem != null ) ) && // ColumnManagerCell or HierarchicalGroupByItem - ( canDrop ); - - - return returnedValue; - } - - void IDropTarget.DragEnter( UIElement draggedElement ) - { - } - - void IDropTarget.DragOver( UIElement draggedElement, RelativePoint mousePosition ) - { - ColumnManagerCell cell = draggedElement as ColumnManagerCell; - - if( cell != null ) - { - HierarchicalGroupByControlNode hierarchicalGroupByControlNode = this.GetHierarchicalGroupByControlNodeFromColumnManagerCell( cell ); - - // It may not be visible - if( hierarchicalGroupByControlNode != null ) - hierarchicalGroupByControlNode.ShowFarDropMark( cell, mousePosition ); - } - else - { - HierarchicalGroupByItem hierarchicalGroupByItem = draggedElement as HierarchicalGroupByItem; - if( hierarchicalGroupByItem == null ) - return; - - HierarchicalGroupByControlNode hierarchicalGroupByControlNode = this.GetHierarchicalGroupByControlNodeFromHierarchicalGroupByItem( hierarchicalGroupByItem ); - - Debug.Assert( hierarchicalGroupByControlNode != null, "CanDrop should have returned false" ); - if( hierarchicalGroupByControlNode == null ) - throw new DataGridInternalException( "A HierarchicalGroupByControlNode must exist for every level." ); - - hierarchicalGroupByControlNode.ShowFarDropMark( mousePosition ); - } - } - - void IDropTarget.DragLeave( UIElement draggedElement ) - { - ColumnManagerCell cell = draggedElement as ColumnManagerCell; - - if( cell != null ) - { - HierarchicalGroupByControlNode hierarchicalGroupByControlNode = this.GetHierarchicalGroupByControlNodeFromColumnManagerCell( cell ); - - // It may not be visible - if( hierarchicalGroupByControlNode != null ) - hierarchicalGroupByControlNode.HideFarDropMark(); - } - else - { - HierarchicalGroupByItem hierarchicalGroupByItem = draggedElement as HierarchicalGroupByItem; - if( hierarchicalGroupByItem == null ) - return; - - HierarchicalGroupByControlNode hierarchicalGroupByControlNode = this.GetHierarchicalGroupByControlNodeFromHierarchicalGroupByItem( hierarchicalGroupByItem ); - - Debug.Assert( hierarchicalGroupByControlNode != null, "CanDrop should have returned false" ); - if( hierarchicalGroupByControlNode == null ) - throw new DataGridInternalException( "A HierarchicalGroupByControlNode must exist for every level." ); - - hierarchicalGroupByControlNode.HideFarDropMark(); - } - } - - void IDropTarget.Drop( UIElement draggedElement, RelativePoint mousePosition ) - { - ColumnManagerCell cell = draggedElement as ColumnManagerCell; - - if( cell == null ) - return; - - HierarchicalGroupByControlNode hierarchicalGroupByControlNode = this.GetHierarchicalGroupByControlNodeFromColumnManagerCell( cell ); - - // It may not be visible - if( hierarchicalGroupByControlNode != null ) - hierarchicalGroupByControlNode.HideFarDropMark( cell ); - - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - DataGridControl parentGrid = ( dataGridContext != null ) - ? dataGridContext.DataGridControl - : null; - - GroupingHelper.AppendNewGroupFromColumnManagerCell( cell, parentGrid ); - - // Notify groups have changed for NoGroupContent - this.UpdateHasGroups(); - } - - #endregion - - #region INotifyPropertyChanged Members - - public event PropertyChangedEventHandler PropertyChanged; - - private void OnPropertyChanged( string propertyName ) - { - var handler = this.PropertyChanged; - if( handler == null ) - return; - - handler.Invoke( this, new PropertyChangedEventArgs( propertyName ) ); - } - - internal void UpdateHasGroups() - { - this.OnPropertyChanged( "HasGroups" ); - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/HierarchicalGroupByControlNode.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/HierarchicalGroupByControlNode.cs deleted file mode 100644 index 5963ef4a..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/HierarchicalGroupByControlNode.cs +++ /dev/null @@ -1,911 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.Diagnostics; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Media; -using Xceed.Utils.Wpf.DragDrop; -using Xceed.Wpf.DataGrid.Views; - -namespace Xceed.Wpf.DataGrid -{ - public class HierarchicalGroupByControlNode : ItemsControl, IDropTarget - { - #region CONSTRUCTORS - - static HierarchicalGroupByControlNode() - { - // Default binding to HierarchicalGroupByControlNode value - FrameworkElementFactory staircaseFactory = new FrameworkElementFactory( typeof( StaircasePanel ) ); - ItemsPanelTemplate itemsPanelTemplate = new ItemsPanelTemplate( staircaseFactory ); - RelativeSource ancestorSource = new RelativeSource( RelativeSourceMode.FindAncestor, typeof( HierarchicalGroupByControl ), 1 ); - - Binding binding = new Binding(); - binding.Path = new PropertyPath( HierarchicalGroupByControlNode.ConnectionLineAlignmentProperty ); - binding.Mode = BindingMode.OneWay; - binding.RelativeSource = ancestorSource; - staircaseFactory.SetBinding( StaircasePanel.ConnectionLineAlignmentProperty, binding ); - - binding = new Binding(); - binding.Path = new PropertyPath( HierarchicalGroupByControlNode.ConnectionLineOffsetProperty ); - binding.Mode = BindingMode.OneWay; - binding.RelativeSource = ancestorSource; - staircaseFactory.SetBinding( StaircasePanel.ConnectionLineOffsetProperty, binding ); - - binding = new Binding(); - binding.Path = new PropertyPath( HierarchicalGroupByControlNode.ConnectionLinePenProperty ); - binding.Mode = BindingMode.OneWay; - binding.RelativeSource = ancestorSource; - staircaseFactory.SetBinding( StaircasePanel.ConnectionLinePenProperty, binding ); - - binding = new Binding(); - binding.Path = new PropertyPath( HierarchicalGroupByControlNode.StairHeightProperty ); - binding.Mode = BindingMode.OneWay; - binding.RelativeSource = ancestorSource; - staircaseFactory.SetBinding( StaircasePanel.StairHeightProperty, binding ); - - binding = new Binding(); - binding.Path = new PropertyPath( HierarchicalGroupByControlNode.StairSpacingProperty ); - binding.Mode = BindingMode.OneWay; - binding.RelativeSource = ancestorSource; - staircaseFactory.SetBinding( StaircasePanel.StairSpacingProperty, binding ); - - itemsPanelTemplate.Seal(); - - ItemsControl.ItemsPanelProperty.OverrideMetadata( typeof( HierarchicalGroupByControlNode ), new FrameworkPropertyMetadata( itemsPanelTemplate ) ); - DataGridControl.ParentDataGridControlPropertyKey.OverrideMetadata( typeof( HierarchicalGroupByControlNode ), new FrameworkPropertyMetadata( new PropertyChangedCallback( HierarchicalGroupByControlNode.ParentGridControlChangedCallback ) ) ); - FocusableProperty.OverrideMetadata( typeof( HierarchicalGroupByControlNode ), new FrameworkPropertyMetadata( false ) ); - } - - #endregion - - #region AllowGroupingModification Property - - public static readonly DependencyProperty AllowGroupingModificationProperty = - GroupByControl.AllowGroupingModificationProperty.AddOwner( typeof( HierarchicalGroupByControlNode ), new UIPropertyMetadata( true ) ); - - public bool AllowGroupingModification - { - get - { - return ( bool )this.GetValue( HierarchicalGroupByControlNode.AllowGroupingModificationProperty ); - } - set - { - this.SetValue( HierarchicalGroupByControlNode.AllowGroupingModificationProperty, value ); - } - } - - #endregion AllowGroupingModification Property - - #region AllowSort Property - - public static readonly DependencyProperty AllowSortProperty = - ColumnManagerRow.AllowSortProperty.AddOwner( typeof( HierarchicalGroupByControlNode ), new UIPropertyMetadata( true ) ); - - public bool AllowSort - { - get - { - return ( bool )this.GetValue( HierarchicalGroupByControlNode.AllowSortProperty ); - } - set - { - this.SetValue( HierarchicalGroupByControlNode.AllowSortProperty, value ); - } - } - - #endregion AllowSort Property - - #region ConnectionLineAlignment Property - - public static readonly DependencyProperty ConnectionLineAlignmentProperty = - StaircasePanel.ConnectionLineAlignmentProperty.AddOwner( typeof( HierarchicalGroupByControlNode ) ); - - public ConnectionLineAlignment ConnectionLineAlignment - { - get - { - return ( ConnectionLineAlignment )this.GetValue( HierarchicalGroupByControlNode.ConnectionLineAlignmentProperty ); - } - set - { - this.SetValue( HierarchicalGroupByControlNode.ConnectionLineAlignmentProperty, value ); - } - } - - #endregion ConnectionLineAlignment Property - - #region ConnectionLineOffset Property - - public static readonly DependencyProperty ConnectionLineOffsetProperty = - StaircasePanel.ConnectionLineOffsetProperty.AddOwner( typeof( HierarchicalGroupByControlNode ) ); - - public double ConnectionLineOffset - { - get - { - return ( double )this.GetValue( HierarchicalGroupByControlNode.ConnectionLineOffsetProperty ); - } - set - { - this.SetValue( HierarchicalGroupByControlNode.ConnectionLineOffsetProperty, value ); - } - } - - #endregion ConnectionLineOffset Property - - #region ConnectionLinePen Property - - public static readonly DependencyProperty ConnectionLinePenProperty = - StaircasePanel.ConnectionLinePenProperty.AddOwner( typeof( HierarchicalGroupByControlNode ) ); - - public Pen ConnectionLinePen - { - get - { - return ( Pen )this.GetValue( HierarchicalGroupByControlNode.ConnectionLinePenProperty ); - } - set - { - this.SetValue( HierarchicalGroupByControlNode.ConnectionLinePenProperty, value ); - } - } - - #endregion ConnectionLinePen Property - - #region StairHeight Property - - public static readonly DependencyProperty StairHeightProperty = - StaircasePanel.StairHeightProperty.AddOwner( typeof( HierarchicalGroupByControlNode ) ); - - public double StairHeight - { - get - { - return ( double )this.GetValue( HierarchicalGroupByControlNode.StairHeightProperty ); - } - set - { - this.SetValue( HierarchicalGroupByControlNode.StairHeightProperty, value ); - } - } - - #endregion StairHeight Property - - #region StairSpacing Property - - public static readonly DependencyProperty StairSpacingProperty = - StaircasePanel.StairSpacingProperty.AddOwner( typeof( HierarchicalGroupByControlNode ) ); - - public double StairSpacing - { - get - { - return ( double )this.GetValue( HierarchicalGroupByControlNode.StairSpacingProperty ); - } - set - { - this.SetValue( HierarchicalGroupByControlNode.StairSpacingProperty, value ); - } - } - - #endregion StairSpacing Property - - #region NoGroupContent Property - - public static readonly DependencyProperty NoGroupContentProperty = - GroupByControl.NoGroupContentProperty.AddOwner( - typeof( HierarchicalGroupByControlNode ), - new PropertyMetadata( "Drag a column header here to group by that column." ) ); - - public object NoGroupContent - { - get - { - return this.GetValue( HierarchicalGroupByControlNode.NoGroupContentProperty ); - } - set - { - this.SetValue( HierarchicalGroupByControlNode.NoGroupContentProperty, value ); - } - } - - #endregion NoGroupContent Property - - #region Title - - public object Title - { - get - { - return ( object )GetValue( TitleProperty ); - } - set - { - SetValue( TitleProperty, value ); - } - } - - public static readonly DependencyProperty TitleProperty = - DependencyProperty.Register( "Title", typeof( object ), typeof( HierarchicalGroupByControlNode ) ); - - #endregion - - // INTERNAL PROPERTIES - - #region DataGridContext Property - - internal DataGridContext DataGridContext - { - get - { - DataGridContext dataGridContext = this.DataContext as DataGridContext; - - if( dataGridContext != null ) - return dataGridContext; - - DetailConfiguration configuration = this.DetailConfiguration; - - if( configuration == null ) - return null; - - // Ensure to get a DataGridContext created with the same DetailConfiguration - return HierarchicalGroupByControlNode.GetDataGridContextFromDetailConfiguration( configuration, - DataGridControl.GetDataGridContext( this ) ); - } - } - - #endregion - - #region DetailConfiguration Property - - internal DetailConfiguration DetailConfiguration - { - get - { - return this.DataContext as DetailConfiguration; - } - } - - #endregion - - #region Columns Property - - internal ColumnCollection Columns - { - get - { - ColumnCollection columnsCollection = null; - DetailConfiguration detailConfiguration = this.DetailConfiguration; - - if( detailConfiguration != null ) - { - columnsCollection = detailConfiguration.Columns; - } - else - { - DataGridContext dataGridContext = this.DataGridContext; - - if( dataGridContext != null ) - columnsCollection = dataGridContext.Columns; - } - Debug.Assert( ( columnsCollection != null ) || ( DesignerProperties.GetIsInDesignMode( this ) ) ); - return columnsCollection; - } - } - - #endregion - - #region GroupDescriptions Property - - internal ObservableCollection GroupDescriptions - { - get - { - ObservableCollection groupDescriptions = null; - DetailConfiguration detailConfiguration = this.DetailConfiguration; - - if( detailConfiguration != null ) - { - groupDescriptions = detailConfiguration.GroupDescriptions; - } - else - { - DataGridContext dataGridContext = this.DataGridContext; - - groupDescriptions = dataGridContext.Items.GroupDescriptions; - } - Debug.Assert( groupDescriptions != null ); - return groupDescriptions; - } - } - - #endregion - - #region GroupLevelDescriptions Property - - internal GroupLevelDescriptionCollection GroupLevelDescriptions - { - get - { - GroupLevelDescriptionCollection groupLevelDescriptions = null; - DetailConfiguration detailConfiguration = this.DetailConfiguration; - - if( detailConfiguration != null ) - { - groupLevelDescriptions = detailConfiguration.GroupLevelDescriptions; - } - else - { - DataGridContext dataGridContext = this.DataGridContext; - - groupLevelDescriptions = dataGridContext.GroupLevelDescriptions; - } - - if( groupLevelDescriptions == null ) - throw new DataGridInternalException( "GroupLevelDescriptions cannot be null on " + typeof( HierarchicalGroupByControlNode ).Name + "." ); - - return groupLevelDescriptions; - } - } - - #endregion - - #region SortDescriptions Property - - internal SortDescriptionCollection SortDescriptions - { - get - { - SortDescriptionCollection sortDescriptions = null; - DetailConfiguration detailConfiguration = this.DetailConfiguration; - - if( detailConfiguration != null ) - { - sortDescriptions = detailConfiguration.SortDescriptions; - } - else - { - DataGridContext dataGridContext = this.DataGridContext; - - sortDescriptions = dataGridContext.Items.SortDescriptions; - } - - if( sortDescriptions == null ) - throw new DataGridInternalException( "GroupLevelDescriptions cannot be null on " + typeof( HierarchicalGroupByControlNode ).Name + "." ); - - return sortDescriptions; - } - } - - #endregion - - #region PROTECTED METHODS - - protected internal virtual void PrepareDefaultStyleKey( Xceed.Wpf.DataGrid.Views.ViewBase view ) - { - this.DefaultStyleKey = view.GetDefaultStyleKey( typeof( HierarchicalGroupByControlNode ) ); - } - - protected override DependencyObject GetContainerForItemOverride() - { - return new HierarchicalGroupByItem(); - } - - protected override bool IsItemItsOwnContainerOverride( object item ) - { - return item is HierarchicalGroupByItem; - } - - protected override void PrepareContainerForItemOverride( DependencyObject element, object item ) - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - DataGridControl grid = ( dataGridContext != null ) - ? dataGridContext.DataGridControl - : null; - - base.PrepareContainerForItemOverride( element, item ); - - if( grid != null ) - { - HierarchicalGroupByItem groupByItem = ( HierarchicalGroupByItem )element; - groupByItem.PrepareDefaultStyleKey( grid.GetView() ); - } - } - - #endregion - - #region PRIVATE STATIC METHODS - - private static void ParentGridControlChangedCallback( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - DataGridControl parentDataGrid = e.NewValue as DataGridControl; - HierarchicalGroupByControlNode groupByControl = ( HierarchicalGroupByControlNode )sender; - - if( parentDataGrid != null ) - groupByControl.PrepareDefaultStyleKey( parentDataGrid.GetView() ); - } - - private static DataGridContext GetDataGridContextFromDetailConfiguration( - DetailConfiguration configuration, - DataGridContext parentDataGridContext ) - { - if( ( configuration == null ) || ( parentDataGridContext == null ) ) - return null; - - if( parentDataGridContext.SourceDetailConfiguration == configuration ) - return parentDataGridContext; - - foreach( DataGridContext childContext in parentDataGridContext.GetChildContexts() ) - { - DataGridContext foundContext = - HierarchicalGroupByControlNode.GetDataGridContextFromDetailConfiguration( configuration, - childContext ); - - if( foundContext != null ) - return foundContext; - } - - return null; - } - - #endregion - - #region INTERNAL METHODS - - internal bool IsGroupingModificationAllowed - { - get - { - HierarchicalGroupByControl hierarchicalGroupByControl = GroupingHelper.GetHierarchicalGroupByControl( this ); - - // By default, we can since DataGridCollectionView.CanGroup always return true - // but we rely on the HierarchicalGroupByControl.AllowGroupModification value - bool allowGroupingModification = hierarchicalGroupByControl.AllowGroupingModification; - if( allowGroupingModification == true ) - { - DataGridContext dataGridContext = this.DataGridContext; - - Debug.Assert( dataGridContext != null ); - - if( ( dataGridContext != null ) && ( dataGridContext.SourceDetailConfiguration == null ) ) - { - allowGroupingModification = dataGridContext.Items.CanGroup; - } - } - - return allowGroupingModification; - } - } - - internal void ShowFarDropMark( ColumnManagerCell cell, RelativePoint mousePosition ) - { - Debug.Assert( cell != null ); - if( cell == null ) - return; - - DataGridContext cellDataGridContext = DataGridControl.GetDataGridContext( cell ); - - Debug.Assert( cellDataGridContext != null ); - if( cellDataGridContext == null ) - throw new DataGridInternalException( "DataGridContext cannot be null on ColumnManagerCell." ); - - // We already have GroupLevelDescriptions for this level, we should show DropMark on the last HierarchicalGroupByItem - if( cellDataGridContext.GroupLevelDescriptions.Count > 0 ) - { - Debug.Assert( cellDataGridContext.GroupLevelDescriptions == this.GroupLevelDescriptions ); - - if( cellDataGridContext.GroupLevelDescriptions != this.GroupLevelDescriptions ) - return; - - int lastIndex = this.GroupLevelDescriptions.Count - 1; - - // If there - if( lastIndex > -1 ) - { - HierarchicalGroupByItem hierarchicalGroupByItem = this.ItemContainerGenerator.ContainerFromItem( this.GroupLevelDescriptions[ lastIndex ] ) as HierarchicalGroupByItem; - - Debug.Assert( hierarchicalGroupByItem != null ); - if( hierarchicalGroupByItem == null ) - return; - - hierarchicalGroupByItem.ShowFarDropMark( mousePosition ); - } - else - { - this.ShowFarDropMark( mousePosition ); - } - } - else - { - this.ShowFarDropMark( mousePosition ); - } - } - - internal void ShowFarDropMark( RelativePoint mousePosition ) - { - int itemsCount = this.Items.Count; - if( itemsCount < 1 ) - { - if( m_dropMarkAdorner == null ) - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - DataGridControl grid = ( dataGridContext != null ) - ? dataGridContext.DataGridControl - : null; - - Pen pen = UIViewBase.GetDropMarkPen( this ); - - if( ( pen == null ) && ( grid != null ) ) - { - UIViewBase uiViewBase = grid.GetView() as UIViewBase; - pen = uiViewBase.DefaultDropMarkPen; - } - - DropMarkOrientation orientation = UIViewBase.GetDropMarkOrientation( this ); - - if( ( orientation == DropMarkOrientation.Default ) && ( grid != null ) ) - { - UIViewBase uiViewBase = grid.GetView() as UIViewBase; - - orientation = uiViewBase.DefaultDropMarkOrientation; - } - - m_dropMarkAdorner = new DropMarkAdorner( this, pen, orientation ); - - AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer( this ); - - if( adornerLayer != null ) - { - adornerLayer.Add( m_dropMarkAdorner ); - } - } - - // We Only want the drop mark to be displayed at the end of the HierarchicalGroupByControlNode - m_dropMarkAdorner.Alignment = DropMarkAlignment.Far; - } - else - { - HierarchicalGroupByItem hierarchicalGroupByItem = this.ItemContainerGenerator.ContainerFromIndex( itemsCount - 1 ) as HierarchicalGroupByItem; - - Debug.Assert( hierarchicalGroupByItem != null ); - - GroupLevelDescription groupLevelDescription = hierarchicalGroupByItem.Content as GroupLevelDescription; - - Debug.Assert( groupLevelDescription != null ); - - // Show Far DropMark only if not already grouped - if( !this.Items.Contains( groupLevelDescription ) ) - { - hierarchicalGroupByItem.ShowFarDropMark( mousePosition ); - } - } - } - - internal void HideFarDropMark() - { - int itemsCount = this.Items.Count; - if( itemsCount > 0 ) - { - HierarchicalGroupByItem hierarchicalGroupByItem = null; - if( itemsCount > 1 ) - { - // Hide the before last item's DropMark if any in case - hierarchicalGroupByItem = this.ItemContainerGenerator.ContainerFromIndex( itemsCount - 2 ) as HierarchicalGroupByItem; - - Debug.Assert( hierarchicalGroupByItem != null ); - - if( hierarchicalGroupByItem != null ) - hierarchicalGroupByItem.HideDropMark(); - } - - // Hide last item's DropMark if any - hierarchicalGroupByItem = this.ItemContainerGenerator.ContainerFromIndex( itemsCount - 1 ) as HierarchicalGroupByItem; - - Debug.Assert( hierarchicalGroupByItem != null ); - - if( hierarchicalGroupByItem != null ) - hierarchicalGroupByItem.HideDropMark(); - } - - if( m_dropMarkAdorner != null ) - { - AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer( this ); - - if( adornerLayer != null ) - adornerLayer.Remove( m_dropMarkAdorner ); - - m_dropMarkAdorner = null; - } - } - - internal void HideFarDropMark( ColumnManagerCell cell ) - { - Debug.Assert( cell != null ); - if( cell == null ) - return; - - DataGridContext cellDataGridContext = DataGridControl.GetDataGridContext( cell ); - - Debug.Assert( cellDataGridContext != null ); - if( cellDataGridContext == null ) - throw new DataGridInternalException( "DataGridContext cannot be null on ColumnManagerCell." ); - - this.HideFarDropMark(); - - // We already have GroupLevelDescriptions for this level, we should show DropMark on the last HierarchicalGroupByItem - if( cellDataGridContext.GroupLevelDescriptions.Count > 0 ) - { - Debug.Assert( cellDataGridContext.GroupLevelDescriptions == this.GroupLevelDescriptions ); - - if( cellDataGridContext.GroupLevelDescriptions != this.GroupLevelDescriptions ) - return; - - int lastIndex = this.GroupLevelDescriptions.Count - 1; - - if( lastIndex > -1 ) - { - HierarchicalGroupByItem hierarchicalGroupByItem = this.ItemContainerGenerator.ContainerFromItem( this.GroupLevelDescriptions[ lastIndex ] ) as HierarchicalGroupByItem; - - Debug.Assert( hierarchicalGroupByItem != null ); - if( hierarchicalGroupByItem == null ) - return; - - hierarchicalGroupByItem.HideDropMark(); - } - } - } - - #endregion - - #region IDropTarget Members - - bool IDropTarget.CanDropElement( UIElement draggedElement, RelativePoint mousePosition ) - { - ColumnManagerCell cell = null; - HierarchicalGroupByItem hierarchicalGroupByItem = null; - bool canDrop = this.AllowGroupingModification; - - if( canDrop ) - { - cell = draggedElement as ColumnManagerCell; - - if( cell != null ) - { - ColumnBase parentColumn = cell.ParentColumn; - - if( ( parentColumn == null ) || ( !parentColumn.AllowGroup ) ) - return false; - - // Check if already grouped using the cell's DataGridContext - canDrop = !GroupingHelper.IsAlreadyGroupedBy( cell ); - - if( canDrop ) - { - - // Get the HierarchicalGroupByControl for this HierarchicalGroupByControlNode - HierarchicalGroupByControl parentGBC = GroupingHelper.GetHierarchicalGroupByControl( this ); - - if( parentGBC == null ) - throw new DataGridInternalException( "The hierarchical group-by control node must be rooted by a HierarchicalGroupByControl." ); - - DataGridContext parentGBCDataGridContext = DataGridControl.GetDataGridContext( parentGBC ); - - Debug.Assert( parentGBCDataGridContext != null ); - - if( parentGBCDataGridContext.Items != null ) - canDrop = parentGBCDataGridContext.Items.CanGroup; - - if( canDrop ) - { - canDrop = GroupingHelper.IsColumnManagerCellInDataGridContext( parentGBCDataGridContext, cell ); - - if( canDrop == true ) - { - canDrop = GroupingHelper.ValidateMaxGroupDescriptions( DataGridControl.GetDataGridContext( draggedElement ) ); - } - } - } - } - else - { - hierarchicalGroupByItem = draggedElement as HierarchicalGroupByItem; - - if( hierarchicalGroupByItem == null ) - canDrop = false; - - if( canDrop ) - { - HierarchicalGroupByControl parentGBC = GroupingHelper.GetHierarchicalGroupByControl( this ); - - if( parentGBC == null ) - throw new DataGridInternalException( "The hierarchical group-by control node must be rooted by a HierarchicalGroupByControl." ); - - // Try to get the HierarchicalGroupByControlNode in which this HierarchicalGroupByItem can be added using the parent HierarchicalGroupByControl => null it can't - HierarchicalGroupByControlNode draggedHierarchicalGroupByControlNode = parentGBC.GetHierarchicalGroupByControlNodeFromHierarchicalGroupByItem( hierarchicalGroupByItem ); - - if( draggedHierarchicalGroupByControlNode == null ) - canDrop = false; - } - } - } - - bool returnedValue = ( ( cell != null ) || ( hierarchicalGroupByItem != null ) ) &&// ColumnManagerCell or HierarchicalGroupByItem - ( canDrop ); - - - return returnedValue; - } - - void IDropTarget.DragEnter( UIElement draggedElement ) - { - } - - void IDropTarget.DragOver( UIElement draggedElement, RelativePoint mousePosition ) - { - ColumnManagerCell cell = draggedElement as ColumnManagerCell; - - if( cell != null ) - { - HierarchicalGroupByControl parentGBC = GroupingHelper.GetHierarchicalGroupByControl( this ); - - if( parentGBC == null ) - throw new DataGridInternalException( "The hierarchical group-by control node must be rooted by a HierarchicalGroupByControl." ); - - HierarchicalGroupByControlNode hierarchicalGroupByControlNode = parentGBC.GetHierarchicalGroupByControlNodeFromColumnManagerCell( cell ); - - if( hierarchicalGroupByControlNode == null ) - throw new DataGridInternalException( "A HierarchicalGroupByControlNode must exist for every level." ); - - hierarchicalGroupByControlNode.ShowFarDropMark( cell, mousePosition ); - } - else - { - HierarchicalGroupByItem hierarchicalGroupByItem = draggedElement as HierarchicalGroupByItem; - if( hierarchicalGroupByItem == null ) - return; - - HierarchicalGroupByControlNode draggedHierarchicalGroupByControlNode = HierarchicalGroupByItem.GetParentHierarchicalGroupByControlNode( hierarchicalGroupByItem ); - - if( draggedHierarchicalGroupByControlNode == null ) - throw new DataGridInternalException( "draggedHierarchicalGroupByControlNode is null." ); - - if( draggedHierarchicalGroupByControlNode.GroupLevelDescriptions == this.GroupLevelDescriptions ) - { - this.ShowFarDropMark( mousePosition ); - } - else - { - // This HierarchicalGroupByItem does not belong this parent HierarchicalGroupByControlNode, display the DropMark on the correct one - HierarchicalGroupByControl parentGBC = GroupingHelper.GetHierarchicalGroupByControl( this ); - - if( parentGBC == null ) - throw new DataGridInternalException( "The hierarchical group-by control node must be rooted by a HierarchicalGroupByControl." ); - - HierarchicalGroupByControlNode hierarchicalGroupByControlNode = parentGBC.GetHierarchicalGroupByControlNodeFromHierarchicalGroupByItem( hierarchicalGroupByItem ); - - Debug.Assert( hierarchicalGroupByControlNode != null, "CanDrop should have returned false" ); - if( hierarchicalGroupByControlNode == null ) - throw new DataGridInternalException( "A HierarchicalGroupByControlNode must exist for every level." ); - - hierarchicalGroupByControlNode.ShowFarDropMark( mousePosition ); - } - } - } - - void IDropTarget.DragLeave( UIElement draggedElement ) - { - ColumnManagerCell cell = draggedElement as ColumnManagerCell; - - if( cell != null ) - { - HierarchicalGroupByControl parentGBC = GroupingHelper.GetHierarchicalGroupByControl( this ); - - if( parentGBC == null ) - throw new DataGridInternalException( "The hierarchical group-by control node must be rooted by a HierarchicalGroupByControl." ); - - HierarchicalGroupByControlNode hierarchicalGroupByControlNode = parentGBC.GetHierarchicalGroupByControlNodeFromColumnManagerCell( cell ); - - if( hierarchicalGroupByControlNode == null ) - throw new DataGridInternalException( "A HierarchicalGroupByControlNode must exist for every level." ); - - hierarchicalGroupByControlNode.HideFarDropMark( cell ); - } - else - { - HierarchicalGroupByItem hierarchicalGroupByItem = draggedElement as HierarchicalGroupByItem; - if( hierarchicalGroupByItem == null ) - return; - - HierarchicalGroupByControlNode draggedHierarchicalGroupByControlNode = HierarchicalGroupByItem.GetParentHierarchicalGroupByControlNode( hierarchicalGroupByItem ); - - if( draggedHierarchicalGroupByControlNode == null ) - throw new DataGridInternalException( "draggedHierarchicalGroupByControlNode is null." ); - - if( draggedHierarchicalGroupByControlNode.GroupLevelDescriptions == this.GroupLevelDescriptions ) - { - this.HideFarDropMark(); - } - else - { - // This HierarchicalGroupByItem does not belong this parent HierarchicalGroupByControlNode, display the DropMark on the correct one - HierarchicalGroupByControl parentGBC = GroupingHelper.GetHierarchicalGroupByControl( this ); - - Debug.Assert( parentGBC != null ); - if( parentGBC == null ) - throw new DataGridInternalException( "The hierarchical group-by control node must be rooted by a HierarchicalGroupByControl" ); - - HierarchicalGroupByControlNode hierarchicalGroupByControlNode = parentGBC.GetHierarchicalGroupByControlNodeFromHierarchicalGroupByItem( hierarchicalGroupByItem ); - - Debug.Assert( hierarchicalGroupByControlNode != null, "CanDrop should have returned false" ); - if( hierarchicalGroupByControlNode == null ) - throw new DataGridInternalException( "A HierarchicalGroupByControlNode must exist for every level." ); - - hierarchicalGroupByControlNode.HideFarDropMark(); - } - } - } - - void IDropTarget.Drop( UIElement draggedElement, RelativePoint mousePosition ) - { - ColumnManagerCell cell = draggedElement as ColumnManagerCell; - - if( cell == null ) - return; - - HierarchicalGroupByControl parentGBC = GroupingHelper.GetHierarchicalGroupByControl( this ); - - if( parentGBC == null ) - throw new DataGridInternalException( "The hierarchical group-by control node must be rooted by a HierarchicalGroupByControl." ); - - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - DataGridControl parentGrid = ( dataGridContext != null ) - ? dataGridContext.DataGridControl - : null; - - GroupingHelper.AppendNewGroupFromColumnManagerCell( cell, parentGrid ); - - // Notify groups have changed for NoGroupContent - parentGBC.UpdateHasGroups(); - - HierarchicalGroupByControlNode hierarchicalGroupByControlNode = parentGBC.GetHierarchicalGroupByControlNodeFromColumnManagerCell( cell ); - - if( hierarchicalGroupByControlNode == null ) - return; - - hierarchicalGroupByControlNode.HideFarDropMark( cell ); - - this.HideFarDropMark(); - } - - #endregion - - #region PRIVATE FIELDS - - private DropMarkAdorner m_dropMarkAdorner; - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/HierarchicalGroupByItem.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/HierarchicalGroupByItem.cs deleted file mode 100644 index e28af749..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/HierarchicalGroupByItem.cs +++ /dev/null @@ -1,1148 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.Diagnostics; -using System.Windows; -using System.Windows.Controls.Primitives; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using Xceed.Utils.Wpf; -using Xceed.Utils.Wpf.DragDrop; -using Xceed.Wpf.DataGrid.Views; - -namespace Xceed.Wpf.DataGrid -{ - public class HierarchicalGroupByItem : ButtonBase, INotifyPropertyChanged, IDropTarget - { - #region CONSTRUCTORS - - static HierarchicalGroupByItem() - { - // This DefaultStyleKey will only be used in design-time. - DefaultStyleKeyProperty.OverrideMetadata( typeof( HierarchicalGroupByItem ), new FrameworkPropertyMetadata( new Markup.ThemeKey( typeof( Views.TableView ), typeof( HierarchicalGroupByItem ) ) ) ); - - HierarchicalGroupByItem.IsBeingDraggedProperty = HierarchicalGroupByItem.IsBeingDraggedPropertyKey.DependencyProperty; - - FocusableProperty.OverrideMetadata( typeof( HierarchicalGroupByItem ), new FrameworkPropertyMetadata( false ) ); - } - - #endregion - - #region IsBeingDragged Read-Only Property - - private static readonly DependencyPropertyKey IsBeingDraggedPropertyKey = - DependencyProperty.RegisterReadOnly( "IsBeingDragged", typeof( bool ), typeof( HierarchicalGroupByItem ), new PropertyMetadata( false ) ); - - public static readonly DependencyProperty IsBeingDraggedProperty; - - public bool IsBeingDragged - { - get - { - return ( bool )this.GetValue( HierarchicalGroupByItem.IsBeingDraggedProperty ); - } - } - - private void SetIsBeingDragged( bool value ) - { - this.SetValue( HierarchicalGroupByItem.IsBeingDraggedPropertyKey, value ); - } - - #endregion IsBeingDragged Read-Only Property - - #region ParentColumns Property - - internal ColumnCollection ParentColumns - { - get - { - ColumnCollection columnCollection = null; - - HierarchicalGroupByControlNode hierarchicalGroupByControlNode = HierarchicalGroupByItem.GetParentHierarchicalGroupByControlNode( this ); - - Debug.Assert( ( hierarchicalGroupByControlNode != null ) || ( DesignerProperties.GetIsInDesignMode( this ) ) ); - - if( hierarchicalGroupByControlNode != null ) - { - columnCollection = hierarchicalGroupByControlNode.Columns; - } - - if( ( columnCollection == null ) && ( !DesignerProperties.GetIsInDesignMode( this ) ) ) - throw new DataGridInternalException( "The " + typeof( HierarchicalGroupByItem ).Name + "'s ParentColumns cannot be null." ); - - return columnCollection; - } - } - - #endregion - - #region ParentGroupDescriptions Property - - internal ObservableCollection ParentGroupDescriptions - { - get - { - ObservableCollection groupDescriptions = null; - HierarchicalGroupByControlNode hierarchicalGroupByControlNode = HierarchicalGroupByItem.GetParentHierarchicalGroupByControlNode( this ); - - Debug.Assert( hierarchicalGroupByControlNode != null ); - if( hierarchicalGroupByControlNode != null ) - { - groupDescriptions = hierarchicalGroupByControlNode.GroupDescriptions; - } - - if( groupDescriptions == null ) - throw new DataGridInternalException( "The " + typeof( HierarchicalGroupByItem ).Name + "'s ParentGroupDescriptions cannot be null." ); - - return groupDescriptions; - } - } - - #endregion - - #region ParentGroupLevelDescriptions Property - - private GroupLevelDescriptionCollection ParentGroupLevelDescriptions - { - get - { - GroupLevelDescriptionCollection groupLevelDescriptions = null; - HierarchicalGroupByControlNode hierarchicalGroupByControlNode = HierarchicalGroupByItem.GetParentHierarchicalGroupByControlNode( this ); - - if( hierarchicalGroupByControlNode != null ) - { - groupLevelDescriptions = hierarchicalGroupByControlNode.GroupLevelDescriptions; - } - else - { - DataGridContext dataGridContext = this.ParentDataGridContext; - if( dataGridContext == null ) - throw new DataGridInternalException( "The " + typeof( HierarchicalGroupByItem ).Name + "'s DataGridContext cannot be null." ); - groupLevelDescriptions = dataGridContext.GroupLevelDescriptions; - } - - if( groupLevelDescriptions == null ) - throw new DataGridInternalException( "The " + typeof( HierarchicalGroupByItem ).Name + "'s ParentGroupLevelDescriptions cannot be null." ); - - return groupLevelDescriptions; - } - } - - #endregion - - #region ParentSortDescriptions Property - - private SortDescriptionCollection ParentSortDescriptions - { - get - { - SortDescriptionCollection sortDescriptions = null; - - HierarchicalGroupByControlNode hierarchicalGroupByControlNode = HierarchicalGroupByItem.GetParentHierarchicalGroupByControlNode( this ); - - if( hierarchicalGroupByControlNode != null ) - { - sortDescriptions = hierarchicalGroupByControlNode.SortDescriptions; - } - else - { - DataGridContext dataGridContext = this.ParentDataGridContext; - if( dataGridContext == null ) - throw new DataGridInternalException( "The " + typeof( HierarchicalGroupByItem ).Name + "'s DataGridContext cannot be null." ); - sortDescriptions = dataGridContext.Items.SortDescriptions; - } - - if( sortDescriptions == null ) - throw new DataGridInternalException( "The " + typeof( HierarchicalGroupByItem ).Name + "'s ParentSortDescriptions cannot be null." ); - - return sortDescriptions; - } - } - - #endregion - - #region SortDirection Property - - // Only used to bind between Column and us, but we don't want to expose it publicly - private static readonly DependencyProperty SortDirectionInternalProperty = - DependencyProperty.Register( "SortDirectionInternal", typeof( SortDirection ), typeof( HierarchicalGroupByItem ), new PropertyMetadata( SortDirection.None, new PropertyChangedCallback( HierarchicalGroupByItem.OnSortDirectionInternalChanged ) ) ); - - public SortDirection SortDirection - { - get - { - return ( SortDirection )this.GetValue( HierarchicalGroupByItem.SortDirectionInternalProperty ); - } - } - - private static void OnSortDirectionInternalChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - HierarchicalGroupByItem groupByItem = ( HierarchicalGroupByItem )sender; - groupByItem.OnPropertyChanged( new PropertyChangedEventArgs( "SortDirection" ) ); - } - - #endregion SortDirection Property - - #region Drag & Drop Manager METHODS - - private void SetupDragManager() - { - // We do not support DragDrop when there are no AdornerLayer because there wouldn't - // be any visual feedback for the operation. - if( AdornerLayer.GetAdornerLayer( this ) == null ) - return; - - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - DataGridControl dataGridControl = ( dataGridContext != null ) - ? dataGridContext.DataGridControl - : null; - - // Can be null in design-time (edition of a style TargetType HierarchicalGroupByItem ). - if( dataGridControl == null ) - return; - - Debug.Assert( m_dragSourceManager == null, "There might be problems when there is already a m_dragSourceManager." ); - - if( m_dragSourceManager != null ) - { - m_dragSourceManager.PropertyChanged -= new PropertyChangedEventHandler( DragSourceManager_PropertyChanged ); - m_dragSourceManager.DragOutsideQueryCursor -= new QueryCursorEventHandler( DragSourceManager_DragOutsideQueryCursor ); - m_dragSourceManager.DroppedOutside -= new EventHandler( DragSourceManager_DroppedOutside ); - } - - // The DataGridControl's AdornerDecoratorForDragAndDrop must be used for dragging in order to include the - // RenderTransform the DataGridControl may performs. This AdornerDecorator is defined in the ControlTemplate - // as PART_DragDropAdornerDecorator - if( ( dataGridControl.DragDropAdornerDecorator != null ) - && ( dataGridControl.DragDropAdornerDecorator.AdornerLayer != null ) ) - { - m_dragSourceManager = new DragSourceManager( this, dataGridControl.DragDropAdornerDecorator.AdornerLayer, dataGridControl ); - } - else - { - System.Diagnostics.Debug.Assert( false, "The drag and drop functionnality won't be fully working properly: PART_DragDropAdornerDecorator was not found" ); - m_dragSourceManager = new DragSourceManager( this, null, dataGridControl ); - } - - m_dragSourceManager.PropertyChanged += new PropertyChangedEventHandler( DragSourceManager_PropertyChanged ); - m_dragSourceManager.DragOutsideQueryCursor += new QueryCursorEventHandler( DragSourceManager_DragOutsideQueryCursor ); - m_dragSourceManager.DroppedOutside += new EventHandler( DragSourceManager_DroppedOutside ); - } - - private void DragSourceManager_DroppedOutside( object sender, EventArgs e ) - { - HierarchicalGroupByControlNode hierarchicalGroupByControlNode = HierarchicalGroupByItem.GetParentHierarchicalGroupByControlNode( this ); - - if( hierarchicalGroupByControlNode == null ) - throw new DataGridInternalException( "hierarchicalGroupByControlNode is null." ); - - bool allowGroupingModification = hierarchicalGroupByControlNode.IsGroupingModificationAllowed; - - if( !allowGroupingModification ) - return; - - ObservableCollection groupDescriptions = this.ParentGroupDescriptions; - - if( groupDescriptions != null ) - { - // Get the HierarchicalGroupByControl before removing us from it - HierarchicalGroupByControl parentGBC = GroupingHelper.GetHierarchicalGroupByControl( this ); - - GroupLevelDescription groupLevelDescription = this.Content as GroupLevelDescription; - - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - DataGridControl parentDataGridControl = ( dataGridContext != null ) - ? dataGridContext.DataGridControl - : null; - - GroupingHelper.RemoveGroupDescription( groupDescriptions, groupLevelDescription, parentDataGridControl ); - - // Notify groups have changed for NoGroupContent - parentGBC.UpdateHasGroups(); - - // Update the HasGroups property - Debug.Assert( parentGBC != null ); - if( parentGBC == null ) - throw new DataGridInternalException( "The hierarchical group-by item must be rooted by a HierarchicalGroupByControl." ); - } - } - - private void DragSourceManager_PropertyChanged( object sender, PropertyChangedEventArgs e ) - { - if( e.PropertyName == "IsDragging" ) - { - this.SetIsBeingDragged( m_dragSourceManager.IsDragging ); - } - } - - private void DragSourceManager_DragOutsideQueryCursor( object sender, QueryCursorEventArgs e ) - { - HierarchicalGroupByControlNode hierarchicalGroupByControlNode = HierarchicalGroupByItem.GetParentHierarchicalGroupByControlNode( this ); - - if( ( hierarchicalGroupByControlNode == null ) - || ( !hierarchicalGroupByControlNode.IsGroupingModificationAllowed ) ) - return; - - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - if( ( dataGridContext != null ) && ( dataGridContext.DataGridControl != null ) ) - { - UIViewBase uiViewBase = dataGridContext.DataGridControl.GetView() as UIViewBase; - - e.Cursor = ( uiViewBase != null ) - ? uiViewBase.RemovingGroupCursor - : UIViewBase.DefaultGroupDraggedOutsideCursor; - } - else - { - e.Cursor = UIViewBase.DefaultGroupDraggedOutsideCursor; - } - } - - protected override void OnMouseLeftButtonDown( MouseButtonEventArgs e ) - { - if( this.CaptureMouse() ) - { - if( m_dragSourceManager != null ) - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - if( dataGridContext != null ) - { - // Update the DropOutsideCursor since it is defined on the View - UIViewBase uiViewBase = dataGridContext.DataGridControl.GetView() as UIViewBase; - - m_dragSourceManager.DropOutsideCursor = ( uiViewBase != null ) - ? uiViewBase.RemovingGroupCursor - : UIViewBase.DefaultGroupDraggedOutsideCursor; - } - - m_dragSourceManager.DragStart( e ); - } - - e.Handled = true; - } - - base.OnMouseLeftButtonDown( e ); - } - - protected override void OnMouseMove( MouseEventArgs e ) - { - if( ( this.IsMouseCaptured ) && ( e.LeftButton == MouseButtonState.Pressed ) ) - { - if( m_dragSourceManager != null ) - { - m_dragSourceManager.DragMove( e ); - } - } - - base.OnMouseMove( e ); - } - - protected override void OnMouseLeftButtonUp( MouseButtonEventArgs e ) - { - bool isMouseCaptured = this.IsMouseCaptured; - bool isPressed = this.IsPressed; - - if( m_dragSourceManager != null ) - { - m_dragSourceManager.Drop( e ); - } - - if( isMouseCaptured ) - { - this.ReleaseMouseCapture(); - - bool click = isPressed; - - if( click ) - { - // DataGridCollectionView always return true for CanSort - bool allowSort = true; - - // Use the ParentDataGridContext to be sure to get a - // DataGridContext of the correct detail level since - // all the HierarchicalGroupByItem will share the same DataGridContext - // which is the one of the level where the HierarchicalGroupByControl - // is located - DataGridContext dataGridContext = this.ParentDataGridContext; - - if( ( dataGridContext != null ) && ( dataGridContext.SourceDetailConfiguration == null ) ) - { - allowSort = dataGridContext.Items.CanSort; - } - - if( allowSort ) - { - ColumnCollection columns = this.ParentColumns; - GroupLevelDescription groupInfo = this.Content as GroupLevelDescription; - - Debug.Assert( ( columns != null ) && ( groupInfo != null ) ); - - if( ( columns != null ) && ( groupInfo != null ) ) - { - ColumnBase column = columns[ groupInfo.FieldName ]; - - if( ( column != null ) && ( column.AllowSort ) ) - { - bool shiftUnpressed = ( ( Keyboard.Modifiers & ModifierKeys.Shift ) != ModifierKeys.Shift ); - - var toggleColumnSort = new HierarchicalGroupByItemToggleColumnSortCommand( this ); - - if( toggleColumnSort.CanExecute( column, shiftUnpressed ) ) - { - toggleColumnSort.Execute( column, shiftUnpressed ); - } - - e.Handled = true; - } - } - } - } - } - - base.OnMouseLeftButtonUp( e ); - } - - protected override void OnLostMouseCapture( MouseEventArgs e ) - { - if( m_dragSourceManager != null ) - { - m_dragSourceManager.DragCancel( e ); - } - - base.OnLostMouseCapture( e ); - } - - internal void ShowFarDropMark( RelativePoint mousePosition ) - { - this.ShowDropMark( mousePosition, DropMarkAlignment.Far, true ); - } - - private void ShowDropMark( RelativePoint mousePosition ) - { - this.ShowDropMark( mousePosition, DropMarkAlignment.Far, false ); - } - - private void ShowDropMark( RelativePoint mousePosition, DropMarkAlignment defaultAlignment, bool forceDefaultAlignment ) - { - if( m_dropMarkAdorner == null ) - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - DataGridControl grid = ( dataGridContext != null ) - ? dataGridContext.DataGridControl - : null; - - Pen pen = UIViewBase.GetDropMarkPen( this ); - - if( ( pen == null ) && ( grid != null ) ) - { - UIViewBase uiViewBase = grid.GetView() as UIViewBase; - pen = uiViewBase.DefaultDropMarkPen; - } - - DropMarkOrientation orientation = Xceed.Wpf.DataGrid.Views.UIViewBase.GetDropMarkOrientation( this ); - - if( ( orientation == DropMarkOrientation.Default ) && ( grid != null ) ) - { - UIViewBase uiViewBase = grid.GetView() as UIViewBase; - - orientation = uiViewBase.DefaultDropMarkOrientation; - } - - m_dropMarkAdorner = new DropMarkAdorner( this, pen, orientation ); - - AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer( this ); - - if( adornerLayer != null ) - adornerLayer.Add( m_dropMarkAdorner ); - } - - if( forceDefaultAlignment ) - { - m_dropMarkAdorner.Alignment = defaultAlignment; - } - else - { - m_dropMarkAdorner.UpdateAlignment( mousePosition ); - } - } - - internal void HideDropMark() - { - if( m_dropMarkAdorner != null ) - { - AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer( this ); - - if( adornerLayer != null ) - adornerLayer.Remove( m_dropMarkAdorner ); - - m_dropMarkAdorner = null; - } - } - - #endregion - - #region INotifyPropertyChanged Members - - protected virtual void OnPropertyChanged( PropertyChangedEventArgs e ) - { - if( this.PropertyChanged != null ) - this.PropertyChanged( this, e ); - } - - public event PropertyChangedEventHandler PropertyChanged; - - #endregion - - #region PROTECTED METHDOS - - public override void OnApplyTemplate() - { - base.OnApplyTemplate(); - this.InitSortDirection(); - this.SetupDragManager(); - } - - #endregion - - #region PROTECTED INTERNAL METHODS - - protected internal virtual void PrepareDefaultStyleKey( Xceed.Wpf.DataGrid.Views.ViewBase view ) - { - this.DefaultStyleKey = view.GetDefaultStyleKey( typeof( HierarchicalGroupByItem ) ); - } - - #endregion - - #region PRIVATE METHODS - - private void InitSortDirection() - { - ColumnCollection columns = this.ParentColumns; - GroupLevelDescription groupInfo = this.Content as GroupLevelDescription; - - Debug.Assert( ( columns != null ) && ( groupInfo != null ) || ( DesignerProperties.GetIsInDesignMode( this ) ) ); - if( ( columns != null ) && ( groupInfo != null ) ) - { - ColumnBase column = columns[ groupInfo.FieldName ]; - - if( column != null ) - { - Binding sortBinding = new Binding(); - sortBinding.Path = new PropertyPath( ColumnBase.SortDirectionProperty ); - sortBinding.Mode = BindingMode.OneWay; - sortBinding.NotifyOnSourceUpdated = true; - sortBinding.Source = column; - sortBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged; - - BindingOperations.SetBinding( this, HierarchicalGroupByItem.SortDirectionInternalProperty, sortBinding ); - } - } - } - - #endregion - - #region INTERNAL STATIC METHODS - - internal static HierarchicalGroupByControlNode GetParentHierarchicalGroupByControlNode( UIElement element ) - { - DependencyObject parent = TreeHelper.GetParent( element ); - - while( parent != null ) - { - HierarchicalGroupByControlNode hierarchicalGroupByControlNode = parent as HierarchicalGroupByControlNode; - if( hierarchicalGroupByControlNode != null ) - break; - - parent = TreeHelper.GetParent( parent ); - } - - return parent as HierarchicalGroupByControlNode; - } - - #endregion - - #region ParentDataGridContext Property - - internal DataGridContext ParentDataGridContext - { - get - { - DataGridContext dataGridContext = null; - HierarchicalGroupByControlNode hierarchicalGroupByControlNode = HierarchicalGroupByItem.GetParentHierarchicalGroupByControlNode( this ); - - if( hierarchicalGroupByControlNode != null ) - dataGridContext = hierarchicalGroupByControlNode.DataGridContext; - - return dataGridContext; - } - } - - #endregion - - #region ParentDetailConfiguration Property - - internal DetailConfiguration ParentDetailConfiguration - { - get - { - DetailConfiguration detailConfiguration = null; - HierarchicalGroupByControlNode hierarchicalGroupByControlNode = HierarchicalGroupByItem.GetParentHierarchicalGroupByControlNode( this ); - - if( hierarchicalGroupByControlNode != null ) - detailConfiguration = hierarchicalGroupByControlNode.DetailConfiguration; - - // Can return null if the master level is reached: the DataContext - // will be a DataGridContext instead of a DetailConfiguration and - // the properties must be fetched via the DataGridContext instead - return detailConfiguration; - } - } - - #endregion - - #region IDropTarget Members - - bool IDropTarget.CanDropElement( UIElement draggedElement, RelativePoint mousePosition ) - { - bool canDrop = true; - - // Check if this HierarchicalGroupByItem parent HierarchicalGroupByControlNode allows grouping modifications, default yes - HierarchicalGroupByControlNode parentHierarchicalGroupByControlNode = HierarchicalGroupByItem.GetParentHierarchicalGroupByControlNode( this ); - - if( parentHierarchicalGroupByControlNode != null ) - canDrop = parentHierarchicalGroupByControlNode.IsGroupingModificationAllowed; - - ColumnManagerCell cell = draggedElement as ColumnManagerCell; - - HierarchicalGroupByItem hierarchicalGroupByItem = null; - - if( canDrop ) - { - if( cell != null ) - { - ColumnBase parentColumn = cell.ParentColumn; - - if( ( parentColumn == null ) || ( !parentColumn.AllowGroup ) ) - return false; - - // Check if already grouped using the cell's DataGridContext - canDrop = !GroupingHelper.IsAlreadyGroupedBy( cell ); - - if( canDrop ) - { - // Get the HierarchicalGroupByControl for this HierarchicalGroupByItem - HierarchicalGroupByControl parentGBC = GroupingHelper.GetHierarchicalGroupByControl( parentHierarchicalGroupByControlNode ); - - if( parentGBC == null ) - throw new DataGridInternalException( "The hierarchical group-by item must be rooted by a HierarchicalGroupByControl." ); - - DataGridContext parentGBCDataGridContext = DataGridControl.GetDataGridContext( parentGBC ); - - if( parentGBCDataGridContext.Items != null ) - canDrop = parentGBCDataGridContext.Items.CanGroup; - - if( canDrop ) - { - canDrop = GroupingHelper.IsColumnManagerCellInDataGridContext( parentGBCDataGridContext, cell ); - - if( canDrop == true ) - canDrop = GroupingHelper.ValidateMaxGroupDescriptions( DataGridControl.GetDataGridContext( draggedElement ) ); - } - } - } - else - { - hierarchicalGroupByItem = draggedElement as HierarchicalGroupByItem; - - if( hierarchicalGroupByItem == null ) - canDrop = false; - - if( canDrop ) - { - HierarchicalGroupByControl parentGBC = GroupingHelper.GetHierarchicalGroupByControl( parentHierarchicalGroupByControlNode ); - - if( parentGBC == null ) - throw new DataGridInternalException( "The hierarchical group-by item must be rooted by a HierarchicalGroupByControl." ); - - // Try to get the HierarchicalGroupByControlNode in which this HierarchicalGroupByItem can be added using the parent HierarchicalGroupByControl => null it can't - HierarchicalGroupByControlNode draggedHierarchicalGroupByControlNode = parentGBC.GetHierarchicalGroupByControlNodeFromHierarchicalGroupByItem( hierarchicalGroupByItem ); - - if( draggedHierarchicalGroupByControlNode == null ) - canDrop = false; - } - } - } - - - bool returnedValue = ( ( cell != null ) || ( hierarchicalGroupByItem != null ) ) && // ColumnManagerCell or HierarchicalGroupByItem - ( draggedElement != this ) && - ( canDrop ); - - - return returnedValue; - } - - void IDropTarget.DragEnter( UIElement draggedElement ) - { - } - - void IDropTarget.DragOver( UIElement draggedElement, RelativePoint mousePosition ) - { - ColumnManagerCell cell = draggedElement as ColumnManagerCell; - - if( cell != null ) - { - DataGridContext draggedCellDataGridContext = DataGridControl.GetDataGridContext( cell ); - - HierarchicalGroupByControlNode draggedOverHierarchicalGroupByControlNode = HierarchicalGroupByItem.GetParentHierarchicalGroupByControlNode( this ); - - if( draggedCellDataGridContext == null ) - throw new DataGridInternalException( "A ColumnManagerCell must have a DataGridContext." ); - - if( draggedOverHierarchicalGroupByControlNode == null ) - throw new DataGridInternalException( "draggedOverHierarchicalGroupByControlNode is null." ); - - if( draggedOverHierarchicalGroupByControlNode.GroupLevelDescriptions == draggedCellDataGridContext.GroupLevelDescriptions ) - { - this.ShowDropMark( mousePosition ); - } - else - { - // This ColumnManagerCell does not belong this parent HierarchicalGroupByControlNode, display the DropMark on the correct one - HierarchicalGroupByControl parentGBC = GroupingHelper.GetHierarchicalGroupByControl( draggedOverHierarchicalGroupByControlNode ); - - if( parentGBC == null ) - throw new DataGridInternalException( "The hierarchical group-by item must be rooted by a HierarchicalGroupByControl." ); - - HierarchicalGroupByControlNode hierarchicalGroupByControlNode = parentGBC.GetHierarchicalGroupByControlNodeFromColumnManagerCell( cell ); - - Debug.Assert( hierarchicalGroupByControlNode != null, "CanDrop should have returned false" ); - if( hierarchicalGroupByControlNode == null ) - throw new DataGridInternalException( "A HierarchicalGroupByControlNode must exist for every level." ); - - hierarchicalGroupByControlNode.ShowFarDropMark( cell, mousePosition ); - } - } - else - { - HierarchicalGroupByItem hierarchicalGroupByItem = draggedElement as HierarchicalGroupByItem; - - if( hierarchicalGroupByItem == null ) - return; - - HierarchicalGroupByControlNode draggedHierarchicalGroupByControlNode = HierarchicalGroupByItem.GetParentHierarchicalGroupByControlNode( hierarchicalGroupByItem ); - - HierarchicalGroupByControlNode draggedOverHierarchicalGroupByControlNode = HierarchicalGroupByItem.GetParentHierarchicalGroupByControlNode( this ); - - if( draggedHierarchicalGroupByControlNode == null ) - throw new DataGridInternalException( "draggedHierarchicalGroupByControlNode is null." ); - - if( draggedOverHierarchicalGroupByControlNode == null ) - throw new DataGridInternalException( "draggedOverHierarchicalGroupByControlNode is null." ); - - if( draggedHierarchicalGroupByControlNode.GroupLevelDescriptions == draggedOverHierarchicalGroupByControlNode.GroupLevelDescriptions ) - { - this.ShowDropMark( mousePosition ); - } - else - { - // This HierarchicalGroupByItem does not belong this parent HierarchicalGroupByControlNode, display the DropMark on the correct one - HierarchicalGroupByControl parentGBC = GroupingHelper.GetHierarchicalGroupByControl( draggedOverHierarchicalGroupByControlNode ); - - if( parentGBC == null ) - throw new DataGridInternalException( "A hierarchical group-by item must be rooted by a HierarchicalGroupByControl." ); - - HierarchicalGroupByControlNode hierarchicalGroupByControlNode = parentGBC.GetHierarchicalGroupByControlNodeFromHierarchicalGroupByItem( hierarchicalGroupByItem ); - - Debug.Assert( hierarchicalGroupByControlNode != null, "CanDrop should have returned false" ); - if( hierarchicalGroupByControlNode == null ) - throw new DataGridInternalException( "A HierarchicalGroupByControlNode must exist for every level." ); - - hierarchicalGroupByControlNode.ShowFarDropMark( mousePosition ); - } - } - } - - void IDropTarget.DragLeave( UIElement draggedElement ) - { - ColumnManagerCell cell = draggedElement as ColumnManagerCell; - - if( cell != null ) - { - DataGridContext draggedCellDataGridContext = DataGridControl.GetDataGridContext( cell ); - - HierarchicalGroupByControlNode draggedOverHierarchicalGroupByControlNode = HierarchicalGroupByItem.GetParentHierarchicalGroupByControlNode( this ); - - if( draggedOverHierarchicalGroupByControlNode == null ) - throw new DataGridInternalException( "We should never be dragged over and not contained inside a HierarchicalGroupByControlNode." ); - - if( draggedOverHierarchicalGroupByControlNode.GroupLevelDescriptions == draggedCellDataGridContext.GroupLevelDescriptions ) - { - this.HideDropMark(); - } - else - { - // This ColumnManagerCell does not belong this parent HierarchicalGroupByControlNode, display the DropMark on the correct one - HierarchicalGroupByControl parentGBC = GroupingHelper.GetHierarchicalGroupByControl( draggedOverHierarchicalGroupByControlNode ); - - if( parentGBC == null ) - throw new DataGridInternalException( "A hierarchical group-by item must be rooted by a HierarchicalGroupByControl." ); - - HierarchicalGroupByControlNode hierarchicalGroupByControlNode = parentGBC.GetHierarchicalGroupByControlNodeFromColumnManagerCell( cell ); - - Debug.Assert( hierarchicalGroupByControlNode != null, "CanDrop should have returned false" ); - if( hierarchicalGroupByControlNode == null ) - throw new DataGridInternalException( "A HierarchicalGroupByControlNode must exist for every level." ); - - hierarchicalGroupByControlNode.HideFarDropMark( cell ); - } - } - else - { - HierarchicalGroupByItem hierarchicalGroupByItem = draggedElement as HierarchicalGroupByItem; - - if( hierarchicalGroupByItem == null ) - return; - - HierarchicalGroupByControlNode draggedHierarchicalGroupByControlNode = HierarchicalGroupByItem.GetParentHierarchicalGroupByControlNode( hierarchicalGroupByItem ); - - HierarchicalGroupByControlNode draggedOverHierarchicalGroupByControlNode = HierarchicalGroupByItem.GetParentHierarchicalGroupByControlNode( this ); - - if( draggedHierarchicalGroupByControlNode == null ) - throw new DataGridInternalException( "draggedHierarchicalGroupByControlNode is null." ); - - if( draggedOverHierarchicalGroupByControlNode == null ) - throw new DataGridInternalException( "draggedOverHierarchicalGroupByControlNode is null." ); - - if( draggedHierarchicalGroupByControlNode.GroupLevelDescriptions == draggedOverHierarchicalGroupByControlNode.GroupLevelDescriptions ) - { - this.HideDropMark(); - } - else - { - // This HierarchicalGroupByItem does not belong this parent HierarchicalGroupByControlNode, display the DropMark on the correct one - HierarchicalGroupByControl parentGBC = GroupingHelper.GetHierarchicalGroupByControl( draggedOverHierarchicalGroupByControlNode ); - - Debug.Assert( parentGBC != null ); - if( parentGBC == null ) - throw new DataGridInternalException( "A hierarchical group-by item must be rooted by a HierarchicalGroupByControl." ); - - HierarchicalGroupByControlNode hierarchicalGroupByControlNode = parentGBC.GetHierarchicalGroupByControlNodeFromHierarchicalGroupByItem( hierarchicalGroupByItem ); - - Debug.Assert( hierarchicalGroupByControlNode != null, "CanDrop should have returned false" ); - if( hierarchicalGroupByControlNode == null ) - throw new DataGridInternalException( "A HierarchicalGroupByControlNode must exist for every level." ); - - hierarchicalGroupByControlNode.HideFarDropMark(); - } - } - } - - void IDropTarget.Drop( UIElement draggedElement, RelativePoint mousePosition ) - { - ColumnManagerCell draggedColumnManagerCell = draggedElement as ColumnManagerCell; - - if( m_dropMarkAdorner != null ) - { - GroupLevelDescription draggedOverGroupLevelDescription = this.Content as GroupLevelDescription; - - DropMarkAlignment alignment = m_dropMarkAdorner.Alignment; - this.HideDropMark(); - - if( draggedColumnManagerCell != null ) - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - DataGridControl parentGrid = ( dataGridContext != null ) - ? dataGridContext.DataGridControl - : null; - - GroupingHelper.AddNewGroupFromColumnManagerCell( draggedColumnManagerCell, draggedOverGroupLevelDescription, alignment, parentGrid ); - } - else - { - HierarchicalGroupByItem draggedGroupByItem = draggedElement as HierarchicalGroupByItem; - - if( draggedGroupByItem == null ) - return; - - GroupLevelDescription draggedGroupLevelDescription = draggedGroupByItem.Content as GroupLevelDescription; - - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - DataGridControl parentDataGridControl = ( dataGridContext != null ) - ? dataGridContext.DataGridControl - : null; - - GroupLevelDescription destinationGroupLevelDescription = this.Content as GroupLevelDescription; - - GroupingHelper.MoveGroupDescription( this.ParentColumns, this.ParentGroupDescriptions, - destinationGroupLevelDescription, alignment, - draggedGroupLevelDescription, parentDataGridControl ); - } - } - else - { - // We try to add a new Group which is not in the current GroupLevelDescriptions - if( draggedColumnManagerCell == null ) - return; - - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - DataGridControl parentGrid = ( dataGridContext != null ) - ? dataGridContext.DataGridControl - : null; - - GroupingHelper.AppendNewGroupFromColumnManagerCell( draggedColumnManagerCell, parentGrid ); - } - - HierarchicalGroupByControl parentGBC = GroupingHelper.GetHierarchicalGroupByControl( this ); - - Debug.Assert( parentGBC != null ); - if( parentGBC == null ) - throw new DataGridInternalException( "A hierarchical group-by item must be rooted by a HierarchicalGroupByControl." ); - - // Notify groups have changed for NoGroupContent - parentGBC.UpdateHasGroups(); - } - - #endregion - - #region PRIVATE FIELDS - - // Will remain null when no AdornerLayer is found. - private DragSourceManager m_dragSourceManager; - private DropMarkAdorner m_dropMarkAdorner; - - #endregion - - #region HierarchicalGroupByItemToggleColumnSortCommand Private Class - - private sealed class HierarchicalGroupByItemToggleColumnSortCommand : ToggleColumnSortCommand - { - #region Constructor - - internal HierarchicalGroupByItemToggleColumnSortCommand( HierarchicalGroupByItem target ) - : base() - { - if( target == null ) - throw new ArgumentNullException( "owner" ); - - m_target = new WeakReference( target ); - - if( target.ParentDataGridContext != null ) - { - m_dataGridContext = new WeakReference( target.ParentDataGridContext ); - } - - DataGridContext groupByItemDataGridContext = DataGridControl.GetDataGridContext( target ); - ToggleColumnSortCommand.ThrowIfNull( groupByItemDataGridContext, "groupByItemDataGridContext" ); - - DataGridControl dataGridControl = groupByItemDataGridContext.DataGridControl; - ToggleColumnSortCommand.ThrowIfNull( dataGridControl, "dataGridControl" ); - - m_dataGridControl = new WeakReference( dataGridControl ); - } - - #endregion - - #region Properties - - #region CanSort Protected Property - - protected override bool CanSort - { - get - { - var datagrid = this.DataGridControl; - if( datagrid == null ) - return false; - - // When details are flatten, only the master may toggle a column. - if( this.DataGridControl.AreDetailsFlatten ) - return false; - - if( this.DataGridContext != null ) - { - return this.DataGridContext.Items.CanSort; - } - - return true; - } - } - - #endregion - - #region Columns Protected Property - - protected override ColumnCollection Columns - { - get - { - var target = this.Target; - if( target == null ) - return null; - - return target.ParentColumns; - } - } - - #endregion - - #region DataGridContext Protected Property - - protected override DataGridContext DataGridContext - { - get - { - return ( m_dataGridContext != null ) ? m_dataGridContext.Target as DataGridContext : null; - } - } - - private readonly WeakReference m_dataGridContext; - - #endregion - - #region DataGridControl Private Property - - private DataGridControl DataGridControl - { - get - { - return ( m_dataGridControl != null ) ? m_dataGridControl.Target as DataGridControl : null; - } - } - - private readonly WeakReference m_dataGridControl; - - #endregion - - #region MaxSortLevels Protected Property - - protected override int MaxSortLevels - { - get - { - return -1; - } - } - - #endregion - - #region SortDescriptions Protected Property - - protected override SortDescriptionCollection SortDescriptions - { - get - { - var target = this.Target; - if( target == null ) - return null; - - return target.ParentSortDescriptions; - } - } - - #endregion - - #region Target Private Property - - private HierarchicalGroupByItem Target - { - get - { - return m_target.Target as HierarchicalGroupByItem; - } - } - - private readonly WeakReference m_target; - - #endregion - - #endregion - - #region Methods Override - - protected override void ValidateToggleColumnSort() - { - Debug.Assert( !this.DataGridControl.AreDetailsFlatten, "A flatten detail should not be able to toggle the column sort direction." ); - } - - protected override SortDescriptionsSyncContext GetSortDescriptionsSyncContext() - { - var dataGridContext = this.DataGridContext; - if( dataGridContext != null ) - return dataGridContext.SortDescriptionsSyncContext; - - return this.DataGridControl.DataGridContext.SortDescriptionsSyncContext; - } - - protected override void ValidateSynchronizationContext( SynchronizationContext synchronizationContext ) - { - if( !synchronizationContext.Own ) - throw new DataGridInternalException( "The column is already being processed.", this.DataGridControl ); - } - - protected override void DeferRestoreStateOnLevel( Disposer disposer ) - { - var dataGridContext = this.DataGridContext; - if( dataGridContext != null ) - { - ToggleColumnSortCommand.DeferRestoreStateOnLevel( disposer, dataGridContext ); - } - } - - protected override IDisposable DeferResortHelperItemsSourceCollection() - { - var dataGridContext = this.DataGridContext; - - return ( dataGridContext != null ) - ? this.DeferResortHelper( dataGridContext.ItemsSourceCollection, dataGridContext.Items ) - : this.DeferResortHelper( this.DataGridControl.ItemsSource, this.DataGridControl.DataGridContext.Items ); - } - - protected override bool TryDeferResortSourceDetailConfiguration( out IDisposable defer ) - { - var dataGridContext = this.DataGridContext; - - return ( dataGridContext != null ) - ? this.TryDeferResort( dataGridContext.SourceDetailConfiguration, out defer ) - : this.TryDeferResort( this.DataGridControl.DataGridContext.SourceDetailConfiguration, out defer ); - } - - protected override IDisposable SetQueueBringIntoViewRestrictions( AutoScrollCurrentItemSourceTriggers triggers ) - { - return this.DataGridControl.SetQueueBringIntoViewRestrictions( triggers ); - } - - #endregion - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/HierarchicalGroupLevelIndicatorPane.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/HierarchicalGroupLevelIndicatorPane.cs deleted file mode 100644 index fa5f40a6..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/HierarchicalGroupLevelIndicatorPane.cs +++ /dev/null @@ -1,220 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; - -namespace Xceed.Wpf.DataGrid -{ - public class HierarchicalGroupLevelIndicatorPane : Control, IWeakEventListener - { - static HierarchicalGroupLevelIndicatorPane() - { - // This DefaultStyleKey will only be used in design-time. - FrameworkElement.DefaultStyleKeyProperty.OverrideMetadata( typeof( HierarchicalGroupLevelIndicatorPane ), new FrameworkPropertyMetadata( new Markup.ThemeKey( typeof( Views.TableView ), typeof( HierarchicalGroupLevelIndicatorPane ) ) ) ); - - UIElement.FocusableProperty.OverrideMetadata( typeof( HierarchicalGroupLevelIndicatorPane ), new FrameworkPropertyMetadata( false ) ); - - DataGridControl.ParentDataGridControlPropertyKey.OverrideMetadata( typeof( HierarchicalGroupLevelIndicatorPane ), new FrameworkPropertyMetadata( new PropertyChangedCallback( OnParentDataGridControlChanged ) ) ); - DataGridControl.DataGridContextPropertyKey.OverrideMetadata( typeof( HierarchicalGroupLevelIndicatorPane ), new FrameworkPropertyMetadata( new PropertyChangedCallback( OnDataGridContextChanged ) ) ); - } - - #region GroupLevelIndicatorPaneHost Private Property - - private Panel GroupLevelIndicatorPaneHost - { - get - { - //if there is no local storage for the host panel, try to retrieve and store the value - if( m_storedGroupLevelIndicatorPaneHost == null ) - { - m_storedGroupLevelIndicatorPaneHost = this.GetTemplateChild( "PART_GroupLevelIndicatorHost" ) as Panel; - } - - return m_storedGroupLevelIndicatorPaneHost; - } - } - - private Panel m_storedGroupLevelIndicatorPaneHost = null; - - #endregion - - #region GroupLevelIndicatorPaneNeedsRefresh Private Property - - private bool GroupLevelIndicatorPaneNeedsRefresh - { - get - { - var panel = this.GroupLevelIndicatorPaneHost; - if( panel == null ) - return false; - - var dataGridContext = DataGridControl.GetDataGridContext( this ); - if( dataGridContext == null ) - return false; - - //skip the "current" DataGridContext - dataGridContext = dataGridContext.ParentDataGridContext; - - var expectedIndicatorsCount = 0; - for( ; dataGridContext != null; dataGridContext = dataGridContext.ParentDataGridContext ) - { - //a group indicator and a detail indicator should exist per level - expectedIndicatorsCount += 2; - } - - return ( panel.Children.Count != expectedIndicatorsCount ); - } - } - - #endregion - - public override void OnApplyTemplate() - { - base.OnApplyTemplate(); - - //whenever the template gets "applied" I want to invalidate the stored Panel. - m_storedGroupLevelIndicatorPaneHost = null; - } - - internal virtual void PrepareDefaultStyleKey( Xceed.Wpf.DataGrid.Views.ViewBase view ) - { - var newThemeKey = view.GetDefaultStyleKey( typeof( HierarchicalGroupLevelIndicatorPane ) ); - if( object.Equals( this.DefaultStyleKey, newThemeKey ) ) - return; - - this.DefaultStyleKey = newThemeKey; - } - - protected override Size MeasureOverride( Size availableSize ) - { - var panel = this.GroupLevelIndicatorPaneHost; - if( panel == null ) - return base.MeasureOverride( availableSize ); - - var dataGridContext = DataGridControl.GetDataGridContext( this ); - if( ( dataGridContext == null ) || !this.GroupLevelIndicatorPaneNeedsRefresh ) - return base.MeasureOverride( availableSize ); - - //clear all the panel's children! - panel.Children.Clear(); - - var previousContext = dataGridContext; - var runningDataGridContext = dataGridContext.ParentDataGridContext; - - while( runningDataGridContext != null ) - { - //create a GroupLevelIndicator to create indentation between the GLIPs - FrameworkElement newGroupMargin = new DetailIndicator(); - newGroupMargin.DataContext = dataGridContext; - - object bindingSource = dataGridContext.GetDefaultDetailConfigurationForContext(); - if( bindingSource == null ) - { - bindingSource = dataGridContext.SourceDetailConfiguration; - } - - //Bind the GroupLevelIndicator`s style to the running DataGridContext`s GroupLevelIndicatorStyle. - var groupLevelIndicatorStyleBinding = new Binding(); - groupLevelIndicatorStyleBinding.Path = new PropertyPath( DetailConfiguration.DetailIndicatorStyleProperty ); - groupLevelIndicatorStyleBinding.Source = bindingSource; - newGroupMargin.SetBinding( StyleProperty, groupLevelIndicatorStyleBinding ); - - //insert the Spacer GroupLevelIndicator in the panel - panel.Children.Insert( 0, newGroupMargin ); - - if( !runningDataGridContext.AreDetailsFlatten ) - { - //then create the GLIP for the running DataGridContext - var newSubGLIP = new GroupLevelIndicatorPane(); - DataGridControl.SetDataGridContext( newSubGLIP, runningDataGridContext ); - newSubGLIP.SetIsLeaf( false ); - GroupLevelIndicatorPane.SetGroupLevel( newSubGLIP, -1 ); - - //and insert it in the panel. - panel.Children.Insert( 0, newSubGLIP ); - } - - previousContext = runningDataGridContext; - runningDataGridContext = runningDataGridContext.ParentDataGridContext; - } - - return base.MeasureOverride( availableSize ); - } - - private static void OnParentDataGridControlChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var self = sender as HierarchicalGroupLevelIndicatorPane; - if( self == null ) - return; - - var dataGridControl = e.OldValue as DataGridControl; - if( dataGridControl != null ) - { - DetailsChangedEventManager.RemoveListener( dataGridControl, self ); - } - - dataGridControl = e.NewValue as DataGridControl; - - //register to the parent grid control's Items Collection GroupDescriptions Changed event - if( dataGridControl != null ) - { - self.PrepareDefaultStyleKey( dataGridControl.GetView() ); - - DetailsChangedEventManager.AddListener( dataGridControl, self ); - self.InvalidateMeasure(); - } - } - - private static void OnDataGridContextChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var self = sender as HierarchicalGroupLevelIndicatorPane; - if( self == null ) - return; - - var panel = self.GroupLevelIndicatorPaneHost; - if( panel != null ) - { - panel.Children.Clear(); - } - - self.InvalidateMeasure(); - } - - #region IWeakEventListener Members - - 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( managerType == typeof( DetailsChangedEventManager ) ) - { - this.InvalidateMeasure(); - return true; - } - - return false; - } - - #endregion - } -} - diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ICustomVirtualizingPanel.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ICustomVirtualizingPanel.cs deleted file mode 100644 index 2097ed18..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ICustomVirtualizingPanel.cs +++ /dev/null @@ -1,27 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - public interface ICustomVirtualizingPanel - { - void BringIntoView( int index ); - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/IDataGridContextVisitable.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/IDataGridContextVisitable.cs deleted file mode 100644 index 60d5538e..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/IDataGridContextVisitable.cs +++ /dev/null @@ -1,30 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - internal interface IDataGridContextVisitable - { - void AcceptVisitor( IDataGridContextVisitor visitor, out bool visitWasStopped ); - void AcceptVisitor( int minIndex, int maxIndex, IDataGridContextVisitor visitor, out bool visitWasStopped ); - void AcceptVisitor( int minIndex, int maxIndex, IDataGridContextVisitor visitor, DataGridContextVisitorType visitorType, out bool visitWasStopped ); - void AcceptVisitor( int minIndex, int maxIndex, IDataGridContextVisitor visitor, DataGridContextVisitorType visitorType, bool visitDetails, out bool visitWasStopped ); - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/IDataGridContextVisitor.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/IDataGridContextVisitor.cs deleted file mode 100644 index 128d1a20..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/IDataGridContextVisitor.cs +++ /dev/null @@ -1,34 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Windows.Data; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal interface IDataGridContextVisitor - { - void Visit( DataGridContext sourceContext, ref bool stopVisit ); - void Visit( DataGridContext sourceContext, int sourceDataItemIndex, object item, ref bool stopVisit ); - void Visit( DataGridContext sourceContext, int startSourceDataItemIndex, int endSourceDataItemIndex, ref bool stopVisit ); - void Visit( DataGridContext sourceContext, CollectionViewGroup group, object[] namesTree, int groupLevel, bool isExpanded, bool isComputedExpanded, ref bool stopVisit ); - void Visit( DataGridContext sourceContext, DataTemplate headerFooter, ref bool stopVisit ); - void Visit( DataGridContext sourceContext, GroupHeaderFooterItem groupHeaderFooter, ref bool stopVisit ); - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/IDataGridItemContainer.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/IDataGridItemContainer.cs deleted file mode 100644 index 16607809..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/IDataGridItemContainer.cs +++ /dev/null @@ -1,37 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - - -namespace Xceed.Wpf.DataGrid -{ - internal interface IDataGridItemContainer - { - bool CanBeRecycled - { - get; - } - - bool IsRecyclingCandidate - { - get; - set; - } - - void PrepareContainer( DataGridContext dataGridContext, object item ); - void ClearContainer(); - void CleanRecyclingCandidate(); - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/IDataGridItemContainerExtensions.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/IDataGridItemContainerExtensions.cs deleted file mode 100644 index c1697628..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/IDataGridItemContainerExtensions.cs +++ /dev/null @@ -1,121 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Windows; -using Xceed.Utils.Wpf; - -namespace Xceed.Wpf.DataGrid -{ - internal static class IDataGridItemContainerExtensions - { - internal static IEnumerable GetTemplatedDescendantDataGridItemContainers( this IDataGridItemContainer source ) - { - if( source == null ) - throw new ArgumentNullException( "source" ); - - var predicate = IDataGridItemContainerExtensions.GetTemplatedDescendantExpandPredicate( source ); - - return IDataGridItemContainerExtensions.GetChildDataGridItemContainers( source, predicate ); - } - - internal static IEnumerable GetTemplatedChildDataGridItemContainers( this IDataGridItemContainer source ) - { - if( source == null ) - throw new ArgumentNullException( "source" ); - - var predicate = IDataGridItemContainerExtensions.GetTemplatedChildExpandPredicate( source ); - - return IDataGridItemContainerExtensions.GetChildDataGridItemContainers( source, predicate ); - } - - private static IEnumerable GetChildDataGridItemContainers( IDataGridItemContainer source, Func expand ) - { - Debug.Assert( source != null ); - - var root = source as DependencyObject; - if( root == null ) - throw new ArgumentException( "The source object must be a DependencyObject.", "source" ); - - return IDataGridItemContainerExtensions.GetChildDataGridItemContainers( root, expand ); - } - - private static IEnumerable GetChildDataGridItemContainers( DependencyObject source, Func expand ) - { - Debug.Assert( source != null ); - - if( expand == null ) - throw new ArgumentNullException( "expand" ); - - var strategy = new DepthFirstSearchTreeTraversalStrategy(); - - return TreeHelper.GetDescendants( strategy, source, null, expand ); - } - - private static Func GetTemplatedDescendantExpandPredicate( IDataGridItemContainer source ) - { - var fe = source as FrameworkElement; - if( fe == null ) - throw new ArgumentException( "The source object must be a FrameworkElement.", "source" ); - - return ( DependencyObject item ) => IDataGridItemContainerExtensions.IsPartOfTargetTemplate( item, fe ); - } - - private static Func GetTemplatedChildExpandPredicate( IDataGridItemContainer source ) - { - var fe = source as FrameworkElement; - if( fe == null ) - throw new ArgumentException( "The source object must be a FrameworkElement.", "source" ); - - return ( DependencyObject item ) => IDataGridItemContainerExtensions.ExpandChild( item ) - && IDataGridItemContainerExtensions.IsPartOfTargetTemplate( item, fe ); - } - - private static bool ExpandChild( DependencyObject container ) - { - return ( container != null ) && !( container is IDataGridItemContainer ); - } - - private static bool IsPartOfTargetTemplate( DependencyObject element, FrameworkElement target ) - { - while( element != null ) - { - var templatedParent = IDataGridItemContainerExtensions.GetTemplatedParent( element ); - if( templatedParent == target ) - return true; - - element = templatedParent; - } - - return false; - } - - private static DependencyObject GetTemplatedParent( DependencyObject element ) - { - var fe = element as FrameworkElement; - if( fe != null ) - return fe.TemplatedParent; - - var fce = element as FrameworkContentElement; - if( fce != null ) - return fce.TemplatedParent; - - return null; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/IDeferableScrollInfoRefresh.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/IDeferableScrollInfoRefresh.cs deleted file mode 100644 index 6c111df0..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/IDeferableScrollInfoRefresh.cs +++ /dev/null @@ -1,28 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Windows.Controls; - -namespace Xceed.Wpf.DataGrid -{ - internal interface IDeferableScrollInfoRefresh - { - IDisposable DeferScrollInfoRefresh( Orientation orientation ); - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/IGroupLevelDescription.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/IGroupLevelDescription.cs deleted file mode 100644 index a67a1889..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/IGroupLevelDescription.cs +++ /dev/null @@ -1,65 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Globalization; -using System.Windows; -using System.Windows.Controls; - -namespace Xceed.Wpf.DataGrid -{ - internal interface IGroupLevelDescription - { - string FieldName - { - get; - } - - object Title - { - get; - } - - DataTemplate TitleTemplate - { - get; - } - - DataTemplateSelector TitleTemplateSelector - { - get; - } - - DataTemplate ValueTemplate - { - get; - } - - DataTemplateSelector ValueTemplateSelector - { - get; - } - - string ValueStringFormat - { - get; - } - - CultureInfo ValueStringFormatCulture - { - get; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/IndexerDescriptor.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/IndexerDescriptor.cs deleted file mode 100644 index 2356d331..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/IndexerDescriptor.cs +++ /dev/null @@ -1,299 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; -using System.Linq; -using System.Reflection; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class IndexerDescriptor : PropertyDescriptor - { - #region Static Fields - - private static readonly object NotInitialized = new object(); - private static readonly object NotSet = new object(); - - #endregion - - // The name must be set to Item[] for binding to get notified when the data item implements INotifyPropertyChanged. - private IndexerDescriptor( string indexerName, string parametersList, object[] parameterValues, PropertyInfo propertyInfo, Attribute[] attributes ) - : base( string.Format( "{0}[]", indexerName ), attributes ) - { - m_displayName = string.Format( "{0}[{1}]", indexerName, parametersList ); - m_indexerName = indexerName; - m_indexerParameters = parametersList; - m_indexerParameterValues = parameterValues; - m_propertyInfo = propertyInfo; - } - - #region ComponentType Property - - public override Type ComponentType - { - get - { - return m_propertyInfo.DeclaringType; - } - } - - #endregion - - #region PropertyType Property - - public override Type PropertyType - { - get - { - return m_propertyInfo.PropertyType; - } - } - - #endregion - - #region IsReadOnly Property - - public sealed override bool IsReadOnly - { - get - { - if( !m_propertyInfo.CanWrite ) - return true; - - var attribute = ( ReadOnlyAttribute )this.Attributes[ typeof( ReadOnlyAttribute ) ]; - - return ( attribute != null ) - && ( attribute.IsReadOnly ); - } - } - - #endregion - - #region DisplayName Property - - public override string DisplayName - { - get - { - return m_displayName; - } - } - - private readonly string m_displayName; - - #endregion - - #region IndexerName Internal Property - - internal string IndexerName - { - get - { - return m_indexerName; - } - } - - private readonly string m_indexerName; - - #endregion - - #region IndexerParameters Internal Property - - internal string IndexerParameters - { - get - { - return m_indexerParameters; - } - } - - private readonly string m_indexerParameters; - - #endregion - - #region DefaultValue Private Property - - private object DefaultValue - { - get - { - if( m_defaultValue == IndexerDescriptor.NotInitialized ) - { - var attribute = ( DefaultValueAttribute )this.Attributes[ typeof( DefaultValueAttribute ) ]; - if( attribute != null ) - { - var propertyType = this.PropertyType; - var value = attribute.Value; - - if( ( value != null ) && ( propertyType.IsEnum ) && ( Enum.GetUnderlyingType( propertyType ) == value.GetType() ) ) - { - value = Enum.ToObject( propertyType, value ); - } - - m_defaultValue = value; - } - else - { - m_defaultValue = IndexerDescriptor.NotSet; - } - } - - return m_defaultValue; - } - } - - private object m_defaultValue = IndexerDescriptor.NotInitialized; - - #endregion - - #region AmbientValue Private Property - - private object AmbientValue - { - get - { - if( m_ambientValue == IndexerDescriptor.NotInitialized ) - { - var attribute = ( AmbientValueAttribute )this.Attributes[ typeof( AmbientValueAttribute ) ]; - if( attribute != null ) - { - m_ambientValue = attribute.Value; - } - else - { - m_ambientValue = IndexerDescriptor.NotSet; - } - } - - return m_ambientValue; - } - } - - private object m_ambientValue = IndexerDescriptor.NotInitialized; - - #endregion - - public override bool ShouldSerializeValue( object component ) - { - if( this.IsReadOnly ) - return this.Attributes.Contains( DesignerSerializationVisibilityAttribute.Content ); - - if( this.DefaultValue != IndexerDescriptor.NotSet ) - return !object.Equals( this.GetValue( component ), this.DefaultValue ); - - return true; - } - - public override object GetValue( object component ) - { - if( component == null ) - return null; - - return m_propertyInfo.GetValue( component, m_indexerParameterValues ); - } - - public override void SetValue( object component, object value ) - { - if( ( component == null ) || this.IsReadOnly ) - return; - - m_propertyInfo.SetValue( component, value, m_indexerParameterValues ); - - this.OnValueChanged( component, EventArgs.Empty ); - } - - public override bool CanResetValue( object component ) - { - if( this.IsReadOnly ) - return false; - - if( this.DefaultValue != IndexerDescriptor.NotSet ) - return !object.Equals( this.GetValue( component ), this.DefaultValue ); - - return ( this.AmbientValue != IndexerDescriptor.NotSet ) - && ( this.ShouldSerializeValue( component ) ); - } - - public override void ResetValue( object component ) - { - if( ( component == null ) || this.IsReadOnly ) - return; - - if( this.DefaultValue != IndexerDescriptor.NotSet ) - { - this.SetValue( component, this.DefaultValue ); - } - else if( this.AmbientValue != IndexerDescriptor.NotSet ) - { - this.SetValue( component, this.AmbientValue ); - } - } - - public override int GetHashCode() - { - return base.GetHashCode(); - } - - public override bool Equals( object obj ) - { - var descriptor = obj as IndexerDescriptor; - if( object.ReferenceEquals( descriptor, null ) ) - return false; - - return ( base.Equals( descriptor ) ) - && ( descriptor.ComponentType == this.ComponentType ) - && ( descriptor.IsReadOnly == this.IsReadOnly ) - && ( descriptor.SupportsChangeEvents == this.SupportsChangeEvents ) - && ( descriptor.IndexerName == this.IndexerName ) - && ( descriptor.IndexerParameters == this.IndexerParameters ); - } - - internal static IndexerDescriptor Create( PropertyInfo propertyInfo, object[] parameterNames, object[] parameterValues ) - { - if( propertyInfo == null ) - throw new ArgumentNullException( "propertyInfo" ); - - if( parameterNames == null ) - throw new ArgumentNullException( "parameterNames" ); - - if( parameterNames.Length <= 0 ) - throw new ArgumentException( "The indexer must contain at least one index.", "parameterNames" ); - - if( parameterValues == null ) - throw new ArgumentNullException( "parameterValues" ); - - if( parameterValues.Length <= 0 ) - throw new ArgumentException( "The indexer must contain at least one index.", "parameterValues" ); - - var parameters = propertyInfo.GetIndexParameters(); - if( ( parameters == null ) || ( parameters.Length <= 0 ) ) - throw new ArgumentException( "The target property is not a valid indexer.", "propertyInfo" ); - - var attributes = ( from entry in propertyInfo.GetCustomAttributes( true ) - let attr = ( entry as Attribute ) - where ( attr != null ) - select attr ).ToArray(); - var parametersList = IndexerParametersParser.Parse( parameterNames ); - var indexerName = propertyInfo.Name; - - return new IndexerDescriptor( indexerName, parametersList, parameterValues, propertyInfo, attributes ); - } - - private readonly PropertyInfo m_propertyInfo; - private readonly object[] m_indexerParameterValues; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/IndexerParametersParser.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/IndexerParametersParser.cs deleted file mode 100644 index 37452bfa..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/IndexerParametersParser.cs +++ /dev/null @@ -1,258 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Globalization; -using System.Linq; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - internal static class IndexerParametersParser - { - #region Static Fields - - private const char Separator = ','; - private const char DoubleQuote = '"'; - - #endregion - - internal static string Parse( IEnumerable values ) - { - if( values == null ) - return string.Empty; - - var sb = new StringBuilder(); - var first = true; - - foreach( var value in values ) - { - if( !first ) - { - sb.Append( "," ); - } - else - { - first = false; - } - - if( value == null ) - { - sb.Append( "null" ); - } - else - { - sb.Append( Convert.ToString( value, CultureInfo.InvariantCulture ) ); - } - } - - return sb.ToString(); - } - - internal static IEnumerable Parse( string value ) - { - var parameters = ( value != null ) ? value.Trim() : string.Empty; - var length = parameters.Length; - if( length <= 0 ) - return Enumerable.Empty(); - - var values = new List(); - var state = ParserState.Start; - var index = 0; - - while( index < length ) - { - var c = parameters[ index ]; - - switch( state ) - { - case ParserState.Start: - { - if( char.IsWhiteSpace( c ) ) - { - index++; - } - else - { - state = ParserState.FindValue; - } - } - break; - - case ParserState.FindValue: - { - if( char.IsWhiteSpace( c ) ) - { - index++; - } - else if( c == IndexerParametersParser.Separator ) - { - // A parameter is missing. - return Enumerable.Empty(); - } - else if( c == IndexerParametersParser.DoubleQuote ) - { - state = ParserState.ExtractString; - } - else - { - state = ParserState.ExtractValue; - } - } - break; - - case ParserState.FindSeparator: - { - if( char.IsWhiteSpace( c ) ) - { - index++; - } - else if( c == IndexerParametersParser.Separator ) - { - index++; - state = ParserState.FindValue; - } - else - { - // Unexpected character. - return Enumerable.Empty(); - } - } - break; - - case ParserState.ExtractString: - { - if( !IndexerParametersParser.AddString( parameters, length, ref index, values ) ) - return Enumerable.Empty(); - - state = ParserState.FindSeparator; - } - break; - - case ParserState.ExtractValue: - { - if( !IndexerParametersParser.AddValue( parameters, length, ref index, values ) ) - return Enumerable.Empty(); - - state = ParserState.FindSeparator; - } - break; - - default: - throw new NotImplementedException(); - } - } - - if( state != ParserState.FindSeparator ) - return Enumerable.Empty(); - - return values; - } - - private static bool AddString( string source, int length, ref int index, IList values ) - { - if( ( index >= length ) || ( source[ index ] != IndexerParametersParser.DoubleQuote ) ) - return false; - - var currentIndex = index + 1; - var startIndex = currentIndex; - var containsSeparator = false; - - while( currentIndex < length ) - { - var c = source[ currentIndex ]; - if( c == IndexerParametersParser.DoubleQuote ) - { - Debug.Assert( startIndex < length ); - Debug.Assert( startIndex <= currentIndex ); - - var value = source.Substring( startIndex, currentIndex - startIndex ).Trim(); - if( value.Length <= 0 ) - { - return false; - } - else if( containsSeparator ) - { - values.Add( string.Format( "\"{0}\"", value ) ); - } - else - { - values.Add( value ); - } - - index = currentIndex + 1; - - return true; - } - else - { - containsSeparator = containsSeparator || ( c == IndexerParametersParser.Separator ); - currentIndex++; - } - } - - return false; - } - - private static bool AddValue( string source, int length, ref int index, IList values ) - { - if( index >= length ) - return false; - - var currentIndex = index; - var startIndex = currentIndex; - - while( currentIndex < length ) - { - var c = source[ currentIndex ]; - - if( c == IndexerParametersParser.Separator ) - break; - - // Unexpected character. - if( c == IndexerParametersParser.DoubleQuote ) - return false; - - currentIndex++; - } - - var value = source.Substring( startIndex, currentIndex - startIndex ).Trim(); - if( value.Length <= 0 ) - return false; - - values.Add( value ); - - index = currentIndex; - - return true; - } - - #region ParserState Private Enum - - private enum ParserState - { - Start, - FindValue, - FindSeparator, - ExtractString, - ExtractValue, - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/InnerCellContentPresenter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/InnerCellContentPresenter.cs deleted file mode 100644 index ac971a5c..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/InnerCellContentPresenter.cs +++ /dev/null @@ -1,57 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; - -namespace Xceed.Wpf.DataGrid -{ - public class InnerCellContentPresenter : ContentPresenter - { - static InnerCellContentPresenter() - { - Binding trimmingBinding = new Binding(); - trimmingBinding.Path = new PropertyPath( "(0).(1).(2)", - Cell.ParentCellProperty, - Cell.ParentColumnProperty, - ColumnBase.TextTrimmingProperty ); - trimmingBinding.Mode = BindingMode.OneWay; - trimmingBinding.RelativeSource = new RelativeSource( RelativeSourceMode.Self ); - - Binding wrappingBinding = new Binding(); - wrappingBinding.Path = new PropertyPath( "(0).(1).(2)", - Cell.ParentCellProperty, - Cell.ParentColumnProperty, - ColumnBase.TextWrappingProperty ); - wrappingBinding.Mode = BindingMode.OneWay; - wrappingBinding.RelativeSource = new RelativeSource( RelativeSourceMode.Self ); - - m_sTextBlockStyle = new Style( typeof( TextBlock ) ); - m_sTextBlockStyle.Setters.Add( new Setter( TextBlock.TextTrimmingProperty, trimmingBinding ) ); - m_sTextBlockStyle.Setters.Add( new Setter( TextBlock.TextWrappingProperty, wrappingBinding ) ); - m_sTextBlockStyle.Seal(); - } - - public InnerCellContentPresenter() - { - //ContentPresenter.ContentProperty.OverrideMetadata( typeof( InnerCellContentPresenter ), new PropertyMetadata( defaultContent ) ); - this.Resources.Add( typeof( TextBlock ), m_sTextBlockStyle ); - } - - private static Style m_sTextBlockStyle; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ItemsHostUIElementCollection.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ItemsHostUIElementCollection.cs deleted file mode 100644 index 70e2d2b6..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ItemsHostUIElementCollection.cs +++ /dev/null @@ -1,235 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; -using System.Windows.Media; -using System.Collections; -using System.Collections.Generic; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class ItemsHostUIElementCollection : IList - { - #region Constructors - - public ItemsHostUIElementCollection( UIElement visualParent ) - { - if( visualParent == null ) - throw new ArgumentNullException( "visualParent" ); - - m_visualCollection = new VisualCollection( visualParent ); - m_visualCollectionLookupDictionary = new Dictionary(); - m_visualParent = visualParent; - } - - #endregion - - #region IList Members - - public int IndexOf( UIElement element ) - { - if( !m_visualCollectionLookupDictionary.ContainsKey( element ) ) - return -1; - - return m_visualCollection.IndexOf( element ); - } - - public void Insert( int index, UIElement element ) - { - if( element == null ) - throw new ArgumentNullException( "element" ); - - m_visualCollection.Insert( index, element ); - m_visualCollectionLookupDictionary.Add( element, null ); - m_visualParent.InvalidateMeasure(); - } - - public void RemoveAt( int index ) - { - UIElement element = m_visualCollection[ index ] as UIElement; - - if( element != null ) - { - m_visualCollectionLookupDictionary.Remove( element ); - } - - m_visualCollection.RemoveAt( index ); - m_visualParent.InvalidateMeasure(); - } - - public UIElement this[ int index ] - { - get - { - return ( m_visualCollection[ index ] as UIElement ); - } - set - { - if( value == null ) - throw new ArgumentNullException( "value" ); - - // Ensure to contain the value in the lookup dictionary - if( !m_visualCollectionLookupDictionary.ContainsKey( value ) ) - { - m_visualCollectionLookupDictionary.Add( value, null ); - } - - if( m_visualCollection[ index ] == value ) - return; - - m_visualCollection[ index ] = value; - - m_visualParent.InvalidateMeasure(); - } - } - - #endregion - - #region ICollection Members - - public void Add( UIElement element ) - { - if( element == null ) - throw new ArgumentNullException( "element" ); - - m_visualCollection.Add( element ); - m_visualCollectionLookupDictionary.Add( element, null ); - m_visualParent.InvalidateMeasure(); - } - - public void Clear() - { - if( m_visualCollection.Count == 0 ) - return; - - m_visualCollection.Clear(); - m_visualCollectionLookupDictionary.Clear(); - m_visualParent.InvalidateMeasure(); - } - - public bool Contains( UIElement element ) - { - return m_visualCollectionLookupDictionary.ContainsKey( element ); - } - - public void CopyTo( UIElement[] array, int index ) - { - m_visualCollection.CopyTo( array, index ); - } - - public int Count - { - get - { - return m_visualCollection.Count; - } - } - - public bool IsReadOnly - { - get - { - return false; - } - } - - public bool Remove( UIElement element ) - { - m_visualCollection.Remove( element ); - m_visualCollectionLookupDictionary.Remove( element ); - m_visualParent.InvalidateMeasure(); - - return true; - } - - #endregion - - #region IEnumerable Members - - public IEnumerator GetEnumerator() - { - return new Enumerator( m_visualCollection.GetEnumerator() ); - } - - #endregion - - #region IEnumerable Members - - IEnumerator IEnumerable.GetEnumerator() - { - return m_visualCollection.GetEnumerator(); - } - - #endregion - - #region Enumerator Private Class - - private class Enumerator : IEnumerator - { - public Enumerator( IEnumerator nonGenericEnumerator ) - { - if( nonGenericEnumerator == null ) - throw new ArgumentNullException( "nonGenericEnumerator" ); - - m_enumerator = nonGenericEnumerator; - } - - UIElement IEnumerator.Current - { - get - { - return m_enumerator.Current as UIElement; - } - } - - void IDisposable.Dispose() - { - // Nothing to do - } - - object IEnumerator.Current - { - get - { - return m_enumerator.Current; - } - } - - bool IEnumerator.MoveNext() - { - return m_enumerator.MoveNext(); - } - - void IEnumerator.Reset() - { - m_enumerator.Reset(); - } - - IEnumerator m_enumerator; - } - - #endregion - - #region Private Fields - - private readonly Dictionary m_visualCollectionLookupDictionary; - private readonly VisualCollection m_visualCollection; - private readonly UIElement m_visualParent; - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ItemsSourceHelper.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ItemsSourceHelper.cs deleted file mode 100644 index bd6e7139..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ItemsSourceHelper.cs +++ /dev/null @@ -1,2719 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Data; -using System.Data.Objects.DataClasses; -using System.Diagnostics; -using System.Globalization; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Xml; -using Xceed.Wpf.DataGrid.Converters; -using Xceed.Wpf.DataGrid.ValidationRules; - -namespace Xceed.Wpf.DataGrid -{ - internal static class ItemsSourceHelper - { - #region Static Fields - - private static readonly Type EntityObjectType = Type.GetType( - "System.Data.Objects.DataClasses.EntityObject, System.Data.Entity, Version=" + _XceedVersionInfo.FrameworkVersion + ", Culture=neutral, PublicKeyToken=b77a5c561934e089", - false, false ); - - #endregion - - internal static bool IsSourceSupportingChangeNotification( object source ) - { - if( source is INotifyCollectionChanged ) - return true; - - var collection = source as IBindingList; - - return ( collection != null ) - && ( collection.SupportsChangeNotification ); - } - - private static bool IsSupportingDBNull( IEnumerable source ) - { - // return false because all the DBNull conversion should have been done in the DataGridCollectionView.ItemProperties converter. - if( source is DataGridCollectionView ) - return false; - - if( source is DataView ) - return true; - - var collectionView = source as CollectionView; - if( collectionView != null ) - return ItemsSourceHelper.IsSupportingDBNull( collectionView.SourceCollection ); - - return false; - } - - internal static bool IsItemSupportingDBNull( object source ) - { - return ( source is System.Data.DataRow ) - || ( source is DataRowView ); - } - - internal static bool IsDataView( IEnumerable source ) - { - if( source is DataGridCollectionView ) - return false; - - if( source is DataView ) - return true; - - var collectionView = source as CollectionView; - - return ( collectionView != null ) - && ( collectionView.SourceCollection is DataView ); - } - - internal static IList TryGetIList( IEnumerable itemsSourceCollection ) - { - var collectionView = itemsSourceCollection as ItemCollection; - if( collectionView != null ) - { - var list = collectionView.SourceCollection as IList; - if( list != null ) - return list; - } - - return itemsSourceCollection as IList; - } - - private static bool IsValueType( Type itemType ) - { - if( typeof( string ) == itemType ) - return true; - - if( !itemType.IsValueType ) - return false; - - return ( itemType.IsPrimitive ) - || ( typeof( decimal ) == itemType ) - || ( typeof( DateTime ) == itemType ) - || ( typeof( TimeSpan ) == itemType ) - || ( typeof( Guid ) == itemType ); - } - - internal static bool IsEntityObjectLoadable( EntityObject entityObject ) - { - return ( ( entityObject.EntityState & EntityState.Added ) != EntityState.Added ) - && ( ( entityObject.EntityState & EntityState.Detached ) != EntityState.Detached ); - } - - private static bool IsEntityFramework( Type itemType ) - { - var entityObjectType = ItemsSourceHelper.EntityObjectType; - - // The EntityFramework assembly is not loaded. We are running on the client framework. - return ( entityObjectType != null ) - && ( entityObjectType.IsAssignableFrom( itemType ) ); - } - - internal static bool IsEntityFramework( object source ) - { - return ( source != null ) - && ( ItemsSourceHelper.IsEntityFramework( source.GetType() ) ); - } - - internal static object GetFirstItemByEnumerable( IEnumerable source ) - { - if( source == null ) - return null; - - return source.Cast().FirstOrDefault(); - } - - internal static DataGridItemPropertyCollection GetRootCollection( DataGridItemPropertyCollection collection ) - { - if( collection == null ) - return null; - - var owner = collection.Owner; - if( owner == null ) - return collection; - - return ItemsSourceHelper.GetRootCollection( owner ); - } - - internal static DataGridItemPropertyCollection GetRootCollection( DataGridItemPropertyBase itemProperty ) - { - if( itemProperty == null ) - return null; - - return ItemsSourceHelper.GetRootCollection( itemProperty.ContainingCollection ); - } - - internal static object AddNewDataItem( IEnumerable itemsSourceCollection, DataGridControl dataGridControl, out int itemIndex ) - { - var dataGridCollectionViewBase = itemsSourceCollection as DataGridCollectionViewBase; - if( dataGridCollectionViewBase != null ) - { - if( !dataGridCollectionViewBase.CanAddNew ) - throw new InvalidOperationException( "An attempt was made to add a new data item to a source that does not support insertion." ); - - itemIndex = dataGridCollectionViewBase.Count; - - return dataGridCollectionViewBase.AddNew(); - } - - var newItem = default( object ); - - if( ( dataGridControl != null ) && ( dataGridControl.ItemsSource == null ) ) - { - //unbound -#pragma warning disable 618 - var eventArgs = new AddingNewDataItemEventArgs(); - dataGridControl.OnAddingNewDataItem( eventArgs ); - - newItem = eventArgs.DataItem; -#pragma warning restore 618 - - if( newItem == null ) - throw new InvalidOperationException( "The AddingNewDataItem event did not return a new data item because the grid is not bound to a data source." ); - - itemIndex = dataGridControl.Items.Add( newItem ); - - return newItem; - } - - var dataView = itemsSourceCollection as DataView; - if( dataView == null ) - { - var collectionView = itemsSourceCollection as CollectionView; - - dataView = ( collectionView == null ) ? null : collectionView.SourceCollection as DataView; - } - - if( dataView != null ) - { - itemIndex = dataView.Count; - - return dataView.AddNew(); - } - - var bindingList = itemsSourceCollection as IBindingList; - if( bindingList == null ) - { - var collectionView = itemsSourceCollection as CollectionView; - - bindingList = ( collectionView == null ) ? null : collectionView.SourceCollection as IBindingList; - } - - if( ( bindingList != null ) && ( bindingList.AllowNew ) ) - { - itemIndex = bindingList.Count; - newItem = bindingList.AddNew(); - } - else - { - var itemType = ItemsSourceHelper.GetItemTypeFromEnumeration( itemsSourceCollection ); - if( itemType == null ) - throw new InvalidOperationException( "An attempt was made to use a source whose item type cannot be determined." ); - - try - { - itemIndex = -1; - newItem = Activator.CreateInstance( itemType ); - } - catch( MissingMethodException exception ) - { - throw new InvalidOperationException( "An attempt was made to use a source whose item type does not have a default constructor.", exception ); - } - catch( Exception exception ) - { - throw new InvalidOperationException( "An unsuccessful attempt was made to create an instance of the source's item type using the item's default constructor.", exception ); - } - } - - var initializableObject = ItemsSourceHelper.GetSupportInitializeObject( newItem ); - if( initializableObject != null ) - { - initializableObject.BeginInit(); - } - - var editableObject = ItemsSourceHelper.GetEditableObject( newItem ); - if( editableObject != null ) - { - editableObject.BeginEdit(); - } - - return newItem; - } - - internal static void CancelNewDataItem( IEnumerable itemsSourceCollection, DataGridControl dataGridControl, object newItem, int newItemIndex ) - { - var dataGridCollectionViewBase = itemsSourceCollection as DataGridCollectionViewBase; - if( dataGridCollectionViewBase != null ) - { - if( dataGridCollectionViewBase.CurrentAddItem == newItem ) - { - // The DataGridCollectionViewBase's CancelNew will take care of calling the item's CancelEdit if it must do so. - dataGridCollectionViewBase.CancelNew(); - } - - return; - } - - //if unbound - if( ( dataGridControl != null ) && ( dataGridControl.ItemsSource == null ) ) - return; - - var editableObject = ItemsSourceHelper.GetEditableObject( newItem ); - if( editableObject != null ) - { - editableObject.CancelEdit(); - } - - var initializableObject = ItemsSourceHelper.GetSupportInitializeObject( newItem ); - if( initializableObject != null ) - { - initializableObject.EndInit(); - } - - if( ItemsSourceHelper.IsEditableObjectInsertedOrRemovedFromDataSourceAutomatically( editableObject ) ) - return; - - var cancelAddNew = itemsSourceCollection as ICancelAddNew; - if( cancelAddNew == null ) - { - var collectionView = itemsSourceCollection as CollectionView; - - cancelAddNew = ( collectionView == null ) ? null : collectionView.SourceCollection as ICancelAddNew; - } - - if( cancelAddNew != null ) - { - cancelAddNew.CancelNew( newItemIndex ); - return; - } - - if( newItemIndex >= 0 ) - { - var list = itemsSourceCollection as IList; - if( list == null ) - { - var collectionView = itemsSourceCollection as CollectionView; - - list = ( collectionView == null ) ? null : collectionView.SourceCollection as IList; - } - - if( ( list != null ) && ( !list.IsFixedSize ) ) - { - list.RemoveAt( newItemIndex ); - } - } - } - - internal static void EndNewDataItem( IEnumerable itemsSourceCollection, DataGridControl dataGridControl, object newItem, ref int newItemIndex ) - { - var dataGridCollectionViewBase = itemsSourceCollection as DataGridCollectionViewBase; - if( dataGridCollectionViewBase != null ) - { - if( dataGridCollectionViewBase.CurrentAddItem == newItem ) - { - // The DataGridCollectionViewBase's EndNew will take care of calling the item's EndEdit if it must do so. - dataGridCollectionViewBase.CommitNew(); - } - - return; - } - - //if unbound - if( ( dataGridControl != null ) && ( dataGridControl.ItemsSource == null ) ) - return; - - var editableObject = ItemsSourceHelper.GetEditableObject( newItem ); - if( editableObject != null ) - { - editableObject.EndEdit(); - } - - var initializableObject = ItemsSourceHelper.GetSupportInitializeObject( newItem ); - if( initializableObject != null ) - { - initializableObject.EndInit(); - } - - if( ItemsSourceHelper.IsEditableObjectInsertedOrRemovedFromDataSourceAutomatically( editableObject ) ) - return; - - var cancelAddNew = itemsSourceCollection as ICancelAddNew; - if( cancelAddNew == null ) - { - var collectionView = itemsSourceCollection as CollectionView; - - cancelAddNew = ( collectionView == null ) ? null : collectionView.SourceCollection as ICancelAddNew; - } - - if( cancelAddNew != null ) - { - cancelAddNew.EndNew( newItemIndex ); - return; - } - - var bindingList = itemsSourceCollection as IBindingList; - if( bindingList == null ) - { - var collectionView = itemsSourceCollection as CollectionView; - - bindingList = ( collectionView == null ) ? null : collectionView.SourceCollection as IBindingList; - } - - // If the item is already added into the list by IBindingList.AddNew. - if( ( bindingList != null ) && ( bindingList.AllowNew ) ) - return; - - var list = itemsSourceCollection as IList; - if( list == null ) - { - var collectionView = itemsSourceCollection as CollectionView; - - list = ( collectionView == null ) ? null : collectionView.SourceCollection as IList; - } - - if( ( list == null ) || ( list.IsFixedSize ) ) - throw new InvalidOperationException( "An attempt was made to insert an item into a source that does not implement the IList interface or that has a fixed size." ); - - newItemIndex = list.Count; - list.Add( newItem ); - } - - private static PropertyDescription GetPropertyDescriptionFromItemProperty( PropertyDescriptionRouteDictionary propertyDescriptions, DataGridItemPropertyRoute itemPropertyRoute ) - { - if( ( propertyDescriptions == null ) || ( itemPropertyRoute == null ) ) - return null; - - var propertyRoute = PropertyRouteBuilder.ToPropertyRoute( itemPropertyRoute ); - if( propertyRoute == null ) - return null; - - PropertyDescriptionRoute propertyDescription; - if( !propertyDescriptions.TryGetValue( propertyRoute, out propertyDescription ) ) - return null; - - return propertyDescription.Current; - } - - internal static void CreateAndAddItemPropertiesForPropertyDescriptions( DataGridItemPropertyCollection itemProperties, IEnumerable propertyDescriptions ) - { - if( ( itemProperties == null ) || ( propertyDescriptions == null ) ) - return; - - using( itemProperties.DeferCollectionChanged() ) - { - foreach( var propertyDescription in propertyDescriptions ) - { - ItemsSourceHelper.CreateAndAddItemPropertyForPropertyDescription( itemProperties, propertyDescription ); - } - } - } - - internal static void CreateAndAddItemPropertyForPropertyDescription( DataGridItemPropertyCollection itemProperties, PropertyDescriptionRoute propertyDescription ) - { - if( ( itemProperties == null ) || ( propertyDescription == null ) ) - return; - - if( !propertyDescription.Current.IsBrowsable ) - return; - - var ancestors = new Stack(); - for( var current = propertyDescription; current != null; current = current.Parent ) - { - var description = current.Current; - if( description.IsSubRelationship ) - return; - - ancestors.Push( description ); - } - - var parentItemProperty = default( DataGridItemPropertyBase ); - var isRoot = true; - - while( ancestors.Count > 0 ) - { - var description = ancestors.Pop(); - var itemProperty = ( isRoot ) ? itemProperties[ description.Name ] : parentItemProperty.ItemProperties[ description.Name ]; - - if( itemProperty == null ) - { - itemProperty = ItemsSourceHelper.CreateItemPropertyFromPropertyDescription( description ); - Debug.Assert( itemProperty != null ); - - if( isRoot ) - { - itemProperties.Add( itemProperty ); - } - else - { - Debug.Assert( parentItemProperty != null ); - parentItemProperty.ItemProperties.Add( itemProperty ); - } - } - - parentItemProperty = itemProperty; - isRoot = false; - } - } - - internal static void CreateColumnsFromPropertyDescriptions( - ColumnHierarchyManager columnManager, - IDictionary defaultCellEditors, - PropertyDescriptionRouteDictionary propertyDescriptions, - bool autoCreateForeignKeyConfigurations ) - { - Debug.Assert( columnManager != null ); - - var columns = columnManager.Columns; - - using( columnManager.DeferUpdate() ) - { - using( columns.DeferNotifications() ) - { - foreach( var propertyDescriptionRoute in propertyDescriptions.Values ) - { - var fieldName = PropertyRouteParser.Parse( PropertyRouteBuilder.ToPropertyRoute( propertyDescriptionRoute ) ); - var columnBase = columns[ fieldName ]; - var column = columnBase as Column; - - if( columnBase == null ) - { - column = ItemsSourceHelper.CreateColumnFromPropertyDescription( defaultCellEditors, propertyDescriptionRoute, autoCreateForeignKeyConfigurations ); - - if( column != null ) - { - columns.Add( column ); - } - } - else if( column != null ) - { - ItemsSourceHelper.UpdateColumnFromPropertyDescription( column, defaultCellEditors, autoCreateForeignKeyConfigurations, propertyDescriptionRoute ); - } - } - } - } - } - - internal static void UpdateColumnsFromPropertyDescriptions( - ColumnHierarchyManager columnManager, - IDictionary defaultCellEditors, - PropertyDescriptionRouteDictionary propertyDescriptions, - bool autoCreateForeignKeyConfigurations ) - { - Debug.Assert( columnManager != null ); - - var columns = columnManager.Columns; - - using( columnManager.DeferUpdate() ) - { - using( columns.DeferNotifications() ) - { - var columnsToRemove = new HashSet( ( from columnBase in columns - let column = columnBase as Column - where ( column != null ) && column.IsAutoCreated - select column ) ); - - foreach( var propertyDescriptionRoute in propertyDescriptions.Values ) - { - var fieldName = PropertyRouteParser.Parse( PropertyRouteBuilder.ToPropertyRoute( propertyDescriptionRoute ) ); - var columnBase = columns[ fieldName ]; - var column = columnBase as Column; - - if( columnBase == null ) - { - column = ItemsSourceHelper.CreateColumnFromPropertyDescription( defaultCellEditors, propertyDescriptionRoute, autoCreateForeignKeyConfigurations ); - - if( column != null ) - { - columns.Add( column ); - } - } - else if( column != null ) - { - columnsToRemove.Remove( column ); - - ItemsSourceHelper.UpdateColumnFromPropertyDescription( column, defaultCellEditors, autoCreateForeignKeyConfigurations, propertyDescriptionRoute ); - } - } - - foreach( var column in columnsToRemove ) - { - columns.Remove( column ); - } - } - } - } - - private static Column CreateColumnFromPropertyDescription( IDictionary defaultCellEditors, PropertyDescriptionRoute propertyDescriptionRoute, bool autoCreateForeignKeyConfigurations ) - { - if( propertyDescriptionRoute == null ) - return null; - - var propertyDescription = propertyDescriptionRoute.Current; - var dataType = propertyDescription.DataType; - - if( !propertyDescription.IsBrowsable || !propertyDescription.IsDisplayable ) - return null; - - for( var current = propertyDescriptionRoute; current != null; current = current.Parent ) - { - var description = current.Current; - if( description.IsSubRelationship ) - return null; - } - - var name = PropertyRouteParser.Parse( PropertyRouteBuilder.ToPropertyRoute( propertyDescriptionRoute ) ); - if( string.IsNullOrEmpty( name ) ) - return null; - - var column = new Column(); - column.IsAutoCreated = true; - column.FieldName = name; - column.Title = propertyDescription.DisplayName; - column.OverrideReadOnlyForInsertion = propertyDescription.OverrideReadOnlyForInsertion; - column.SetDisplayMemberBinding( ItemsSourceHelper.CreateDefaultBinding( propertyDescriptionRoute ) ); - column.IsBindingAutoCreated = true; - column.IsBoundToDataGridUnboundItemProperty = propertyDescription.IsDataGridUnboundItemProperty; - - if( propertyDescription.IsReadOnly ) - { - column.ReadOnly = true; - } - - var cellEditor = default( CellEditor ); - - if( ( defaultCellEditors != null ) && !defaultCellEditors.TryGetValue( dataType, out cellEditor ) ) - { - cellEditor = default( CellEditor ); - } - - var foreignKeyDescription = propertyDescription.ForeignKeyDescription; - - if( ( foreignKeyDescription != null ) && ( foreignKeyDescription.ItemsSource != null ) && ( autoCreateForeignKeyConfigurations ) ) - { - // We will only use the default foreign key CellEditor if: - // - a ForeignKey ItemsSource was detected - // - the grid allows the auto-creation of the ForeignKeyConfigurations - // else, use the default CellEditor - if( cellEditor == null ) - { - cellEditor = DefaultCellEditorSelector.ForeignKeyCellEditor; - } - - // Update the ForeignKeyConfiguration from the ForeignKeyDescription found on the FieldDescriptor - ForeignKeyConfiguration.SynchronizeForeignKeyConfigurationFromForeignKeyDescription( column, foreignKeyDescription, autoCreateForeignKeyConfigurations ); - } - - if( cellEditor == null ) - { - cellEditor = DefaultCellEditorSelector.SelectCellEditor( dataType ); - } - - column.CellEditor = cellEditor; - column.DefaultCellRecyclingGroupDataType = dataType; - - return column; - } - - internal static void UpdateColumnFromPropertyDescription( - ColumnBase column, - IDictionary defaultCellEditors, - bool autoCreateForeignKeyConfigurations, - PropertyDescriptionRoute propertyDescription ) - { - if( ( column == null ) || ( propertyDescription == null ) ) - return; - - var targetColumn = column as Column; - var targetPropertyDescription = propertyDescription.Current; - - if( targetPropertyDescription.IsReadOnly ) - { - if( column.ReadLocalValue( Column.ReadOnlyProperty ) == DependencyProperty.UnsetValue ) - { - column.ReadOnly = targetPropertyDescription.IsReadOnly; - } - } - - if( targetPropertyDescription.OverrideReadOnlyForInsertion ) - { - if( column.ReadLocalValue( ColumnBase.OverrideReadOnlyForInsertionProperty ) == DependencyProperty.UnsetValue ) - { - column.OverrideReadOnlyForInsertion = targetPropertyDescription.OverrideReadOnlyForInsertion; - } - } - - if( column.ReadLocalValue( ColumnBase.TitleProperty ) == DependencyProperty.UnsetValue ) - { - column.Title = targetPropertyDescription.DisplayName; - } - - if( column.ReadLocalValue( ColumnBase.CellEditorProperty ) == DependencyProperty.UnsetValue ) - { - var cellEditor = default( CellEditor ); - - if( defaultCellEditors != null ) - { - defaultCellEditors.TryGetValue( targetPropertyDescription.DataType, out cellEditor ); - } - - if( ( cellEditor == null ) && ( targetColumn != null ) ) - { - var descriptionItemsSource = default( object ); - var configurationItemsSource = default( object ); - var configuration = targetColumn.ForeignKeyConfiguration; - - if( targetPropertyDescription.ForeignKeyDescription != null ) - { - descriptionItemsSource = targetPropertyDescription.ForeignKeyDescription.ItemsSource; - } - - if( configuration != null ) - { - configurationItemsSource = configuration.ItemsSource; - - if( configurationItemsSource == null ) - { - configurationItemsSource = targetColumn.ReadLocalValue( Column.ForeignKeyConfigurationProperty ); - } - } - - // A foreign key ItemsSource is set and we can auto-create configuration, OR, - // if the foreign key ItemsSource was found in the ForeignKeyConfiguration, use the Default ForeignKey CellEditor. - if( ( ( descriptionItemsSource != null ) && ( autoCreateForeignKeyConfigurations ) ) || ( configurationItemsSource != null ) ) - { - cellEditor = DefaultCellEditorSelector.ForeignKeyCellEditor; - } - } - - if( cellEditor == null ) - { - cellEditor = DefaultCellEditorSelector.SelectCellEditor( targetPropertyDescription.DataType ); - } - - column.CellEditor = cellEditor; - } - - if( targetColumn != null ) - { - if( ( targetPropertyDescription.ForeignKeyDescription != null ) && ( targetPropertyDescription.ForeignKeyDescription.ItemsSource != null ) && ( autoCreateForeignKeyConfigurations ) ) - { - // Update the ForeignKeyConfiguration from the ForeignKeyDescription found on the FieldDescriptor - ForeignKeyConfiguration.SynchronizeForeignKeyConfigurationFromForeignKeyDescription( targetColumn, targetPropertyDescription.ForeignKeyDescription, autoCreateForeignKeyConfigurations ); - } - - if( targetColumn.GetDisplayMemberBinding() == null ) - { - targetColumn.SetDisplayMemberBinding( ItemsSourceHelper.CreateDefaultBinding( propertyDescription ) ); - targetColumn.IsBindingAutoCreated = true; - targetColumn.IsBoundToDataGridUnboundItemProperty = targetPropertyDescription.IsDataGridUnboundItemProperty; - } - } - - column.DefaultCellRecyclingGroupDataType = targetPropertyDescription.DataType; - } - - internal static DataGridItemPropertyBase GetItemPropertyFromProperty( DataGridItemPropertyCollection itemProperties, string propertyPath ) - { - if( itemProperties == null ) - return null; - - return ItemsSourceHelper.GetItemPropertyFromProperty( itemProperties, PropertyRouteParser.Parse( propertyPath ) ); - } - - internal static DataGridItemPropertyBase GetItemPropertyFromProperty( DataGridItemPropertyCollection itemProperties, PropertyRoute propertyRoute ) - { - if( ( itemProperties == null ) || ( propertyRoute == null ) ) - return null; - - if( propertyRoute.Parent != null ) - { - var parentItemProperty = ItemsSourceHelper.GetItemPropertyFromProperty( itemProperties, propertyRoute.Parent ); - if( parentItemProperty == null ) - return null; - - itemProperties = parentItemProperty.ItemPropertiesInternal; - if( itemProperties == null ) - return null; - } - - return itemProperties[ propertyRoute.Current.Name ]; - } - - internal static object GetValueFromItemProperty( DataGridItemPropertyBase itemProperty, object item ) - { - return ItemsSourceHelper.GetValueFromItemProperty( itemProperty, item, null ); - } - - internal static object GetValueFromItemProperty( DataGridItemPropertyBase itemProperty, object item, object defaultValue ) - { - if( itemProperty == null ) - throw new ArgumentNullException( "itemProperty" ); - - // Make sure the DataGridItemProperty is still in use. - var collection = itemProperty.ContainingCollection; - if( collection == null ) - return defaultValue; - - var parentItemProperty = collection.Owner; - if( parentItemProperty != null ) - { - item = ItemsSourceHelper.GetValueFromItemProperty( parentItemProperty, item ); - } - - if( item == null ) - return defaultValue; - - return itemProperty.GetValue( item ); - } - - internal static void SetValueForItemProperty( DataGridItemPropertyBase itemProperty, object item, object value ) - { - if( itemProperty == null ) - throw new ArgumentNullException( "itemProperty" ); - - // Make sure the DataGridItemProperty is still in use. - var collection = itemProperty.ContainingCollection; - if( collection == null ) - return; - - var parentItemProperty = collection.Owner; - if( parentItemProperty != null ) - { - item = ItemsSourceHelper.GetValueFromItemProperty( parentItemProperty, item ); - } - - if( item == null ) - return; - - itemProperty.SetValue( item, value ); - } - - internal static void AutoDetectSynonyms( DataGridCollectionViewBase collectionView ) - { - if( collectionView == null ) - return; - - // The root CollectionView does not need to have its ItemProperties binded. - var masterCollectionView = collectionView.RootDataGridCollectionViewBase; - if( ( masterCollectionView == null ) || ( masterCollectionView == collectionView ) ) - return; - - ItemsSourceHelper.AutoDetectSynonyms( masterCollectionView.ItemProperties, collectionView.ItemProperties ); - } - - internal static void AutoDetectSynonyms( DataGridCollectionViewBase collectionView, DataGridItemPropertyRoute detailItemPropertyRoute ) - { - if( ( collectionView == null ) || ( detailItemPropertyRoute == null ) ) - return; - - // The root CollectionView does not need to have its ItemProperties binded. - var masterCollectionView = collectionView.RootDataGridCollectionViewBase; - if( ( masterCollectionView == null ) || ( masterCollectionView == collectionView ) ) - return; - - var masterItemProperty = ItemsSourceHelper.AutoDetectSynonyms( masterCollectionView.ItemProperties, detailItemPropertyRoute ); - if( masterItemProperty == null ) - return; - - // Do the auto detection on child properties. - ItemsSourceHelper.AutoDetectSynonyms( masterItemProperty.ItemPropertiesInternal, detailItemPropertyRoute.Current.ItemPropertiesInternal ); - } - - private static void AutoDetectSynonyms( DataGridItemPropertyCollection masterItemProperties, DataGridItemPropertyCollection detailItemProperties ) - { - if( ( masterItemProperties == null ) || ( detailItemProperties == null ) ) - return; - - foreach( var detailItemProperty in detailItemProperties ) - { - ItemsSourceHelper.AutoDetectSynonyms( masterItemProperties, detailItemProperty, true ); - } - } - - private static DataGridItemPropertyBase AutoDetectSynonyms( DataGridItemPropertyCollection masterItemProperties, DataGridItemPropertyRoute detailItemPropertyRoute ) - { - if( ( masterItemProperties == null ) || ( detailItemPropertyRoute == null ) ) - return null; - - if( detailItemPropertyRoute.Parent == null ) - return ItemsSourceHelper.AutoDetectSynonyms( masterItemProperties, detailItemPropertyRoute.Current, false ); - - var masterParentItemProperty = ItemsSourceHelper.AutoDetectSynonyms( masterItemProperties, detailItemPropertyRoute.Parent ); - if( masterParentItemProperty == null ) - return null; - - return ItemsSourceHelper.AutoDetectSynonyms( masterParentItemProperty.ItemPropertiesInternal, detailItemPropertyRoute.Current, false ); - } - - private static DataGridItemPropertyBase AutoDetectSynonyms( DataGridItemPropertyCollection masterItemProperties, DataGridItemPropertyBase detailItemProperty, bool autoDetectSubProperties ) - { - if( ( masterItemProperties == null ) || ( detailItemProperty == null ) ) - return null; - - var masterItemProperty = default( DataGridItemPropertyBase ); - - if( string.IsNullOrEmpty( detailItemProperty.Synonym ) ) - { - masterItemProperty = masterItemProperties[ detailItemProperty.Name ]; - - if( ( masterItemProperty != null ) && ( masterItemProperty.DataType == detailItemProperty.DataType ) ) - { - detailItemProperty.SetSynonym( masterItemProperty.Name ); - } - else - { - masterItemProperty = null; - } - } - else if( ( detailItemProperty.ItemPropertiesInternal != null ) && ( detailItemProperty.Synonym == detailItemProperty.Name ) ) - { - masterItemProperty = masterItemProperties[ detailItemProperty.Name ]; - } - - if( autoDetectSubProperties && ( masterItemProperty != null ) && ( masterItemProperty.ItemPropertiesInternal != null ) && ( detailItemProperty.ItemPropertiesInternal != null ) ) - { - ItemsSourceHelper.AutoDetectSynonyms( masterItemProperty.ItemPropertiesInternal, detailItemProperty.ItemPropertiesInternal ); - } - - return masterItemProperty; - } - - internal static ICustomTypeDescriptor GetCustomTypeDescriptorFromItem( object item, Type itemType ) - { - var descriptionProvider = default( TypeDescriptionProvider ); - if( itemType != null ) - { - descriptionProvider = TypeDescriptor.GetProvider( itemType ); - } - - if( !( descriptionProvider is DataItemTypeDescriptionProvider ) ) - { - descriptionProvider = new DataItemTypeDescriptionProvider( descriptionProvider ); - } - - return descriptionProvider.GetTypeDescriptor( itemType, item ); - } - - private static ICustomTypeDescriptor GetCustomTypeDescriptor( IEnumerable itemsSource, Type itemType ) - { - if( ( itemsSource == null ) && ( itemType == null ) ) - return null; - - var firstItem = ItemsSourceHelper.GetFirstItemByEnumerable( itemsSource ); - - return ItemsSourceHelper.GetCustomTypeDescriptor( firstItem, itemType ); - } - - private static ICustomTypeDescriptor GetCustomTypeDescriptor( object item, Type itemType ) - { - var descriptor = item as ICustomTypeDescriptor; - if( descriptor == null ) - return ItemsSourceHelper.GetCustomTypeDescriptorFromItem( item, itemType ); - - if( !( descriptor is DataItemTypeDescriptor ) ) - return DataItemTypeDescriptionProvider.GetTypeDescriptor( itemType, descriptor ); - - return descriptor; - } - - internal static void ResetPropertyDescriptions( PropertyDescriptionRouteDictionary collection, DataGridItemPropertyMap itemPropertyMap, DataGridControl dataGridControl, IEnumerable itemsSource ) - { - if( collection == null ) - throw new ArgumentNullException( "collection" ); - - if( dataGridControl == null ) - throw new ArgumentNullException( "dataGridControl" ); - - collection.Clear(); - - var masterPropertyDescriptions = dataGridControl.ItemsSourcePropertyDescriptions; - - if( ( collection != masterPropertyDescriptions ) && dataGridControl.AreDetailsFlatten ) - { - var collectionView = itemsSource as DataGridCollectionViewBase; - if( collectionView != null ) - { - ItemsSourceHelper.SetPropertyDescriptions( collection, masterPropertyDescriptions, itemPropertyMap, collectionView ); - } - } - else - { - ItemsSourceHelper.SetPropertyDescriptions( collection, null, itemsSource, null, true ); - } - } - - internal static void SetPropertyDescriptions( PropertyDescriptionRouteDictionary collection, DataTable model, IEnumerable itemsSource, Type itemType, bool displayable ) - { - if( collection == null ) - throw new ArgumentNullException( "collection" ); - - var descriptions = default( IEnumerable ); - var supportsDBNull = ItemsSourceHelper.IsSupportingDBNull( itemsSource ); - - if( model != null ) - { - descriptions = ItemsSourceHelper.CreatePropertyDescriptionsFromDataTable( model, displayable ); - } - else if( itemsSource is DataView ) - { - descriptions = ItemsSourceHelper.CreatePropertyDescriptionsFromDataView( ( DataView )itemsSource, displayable ); - } - else if( itemsSource is DataGridCollectionViewBase ) - { - descriptions = ItemsSourceHelper.CreatePropertyDescriptionsFromDataGridCollectionView( ( DataGridCollectionViewBase )itemsSource ); - } - else if( itemsSource is ITypedList ) - { - descriptions = ItemsSourceHelper.CreatePropertyDescriptionsFromPropertyDescriptors( ( ( ITypedList )itemsSource ).GetItemProperties( null ), supportsDBNull, displayable ); - } - else - { - if( itemType == null ) - { - itemType = ItemsSourceHelper.GetItemTypeFromEnumeration( itemsSource ); - } - - descriptions = ItemsSourceHelper.CreatePropertyDescriptionsFromItemType( itemsSource, itemType, supportsDBNull, displayable ); - } - - if( descriptions != null ) - { - foreach( var description in descriptions ) - { - collection.Add( description, true ); - } - } - } - - private static void SetPropertyDescriptions( PropertyDescriptionRouteDictionary detailCollection, PropertyDescriptionRouteDictionary masterCollection, DataGridItemPropertyMap itemPropertyMap, DataGridCollectionViewBase collectionView ) - { - if( collectionView == null ) - return; - - foreach( var itemProperty in collectionView.ItemProperties ) - { - var masterItemProperty = default( DataGridItemPropertyBase ); - if( !itemPropertyMap.TryGetMasterItemProperty( itemProperty, out masterItemProperty ) ) - { - Debug.WriteLine( string.Format( "No mapping was found for the item property." ) ); - continue; - } - - var masterPropertyRoute = PropertyRouteBuilder.ToPropertyRoute( DataGridItemPropertyRoute.Create( masterItemProperty ) ); - if( masterPropertyRoute == null ) - { - masterPropertyRoute = PropertyRouteBuilder.ToPropertyRoute( new PropertyRouteSegment( PropertyRouteSegmentType.Property, masterItemProperty.Name ) ); - } - - var masterPropertyDescription = masterCollection[ masterPropertyRoute ]; - if( masterPropertyDescription == null ) - { - Debug.WriteLine( string.Format( "An item property is mapped to a non-existent master field." ) ); - continue; - } - - var detailPropertyDescription = ItemsSourceHelper.CreatePropertyDescriptionFromDataGridItemProperty( itemProperty ); - if( detailPropertyDescription.Current.DataType != masterPropertyDescription.Current.DataType ) - { - Debug.WriteLine( string.Format( "The data type of an item property doesn't match the data type of its master field." ) ); - continue; - } - - if( detailCollection.Contains( masterPropertyRoute ) ) - { - Debug.WriteLine( string.Format( "Another detail field is already linked to the master field." ) ); - continue; - } - - detailCollection.Add( masterPropertyRoute, detailPropertyDescription, false ); - } - } - - internal static void SetPropertyDescriptionsFromItemProperty( PropertyDescriptionRouteDictionary propertyDescriptions, DataTable model, IEnumerable itemsSource, Type itemType, DataGridItemPropertyRoute itemPropertyRoute ) - { - if( ( propertyDescriptions == null ) || ( itemPropertyRoute == null ) ) - return; - - var key = PropertyRouteBuilder.ToPropertyRoute( itemPropertyRoute ); - ItemsSourceHelper.SetPropertyDescriptions( propertyDescriptions, model, itemsSource, itemType, key ); - - var propertyDescription = default( PropertyDescriptionRoute ); - if( !propertyDescriptions.TryGetValue( key, out propertyDescription ) ) - return; - - var itemProperty = itemPropertyRoute.Current; - if( itemProperty.ItemPropertiesInternal == null ) - return; - - foreach( var childItemProperty in itemProperty.ItemPropertiesInternal ) - { - ItemsSourceHelper.SetPropertyDescriptionsFromItemProperty( - propertyDescriptions, - null, - null, - itemProperty.DataType, - DataGridItemPropertyRoute.Combine( childItemProperty, itemPropertyRoute ) ); - } - } - - internal static void InitializePropertyDescriptions( PropertyDescriptionRouteDictionary collection, DataGridItemPropertyRoute itemPropertyRoute, Type itemType, bool defaultPropertyDescriptionsCreated ) - { - if( ( collection == null ) || ( itemPropertyRoute == null ) ) - return; - - var propertyDescription = ItemsSourceHelper.GetPropertyDescriptionFromItemProperty( collection, itemPropertyRoute ); - var itemProperty = itemPropertyRoute.Current; - - itemProperty.SetUnspecifiedPropertiesValues( propertyDescription, itemType, defaultPropertyDescriptionsCreated ); - - if( itemProperty.ItemPropertiesInternal != null ) - { - foreach( var childItemProperty in itemProperty.ItemPropertiesInternal ) - { - ItemsSourceHelper.InitializePropertyDescriptions( collection, DataGridItemPropertyRoute.Combine( childItemProperty, itemPropertyRoute ), itemProperty.DataType, defaultPropertyDescriptionsCreated ); - } - } - } - - internal static Type GetItemTypeFromEnumeration( IEnumerable source ) - { - if( source == null ) - return null; - - var enumerationType = source.GetType(); - var itemType = ItemsSourceHelper.GetItemTypeFromEnumerationType( enumerationType ); - - if( itemType != null ) - return itemType; - - var item = ItemsSourceHelper.GetFirstItemByEnumerable( source ); - if( item != null ) - return item.GetType(); - - return typeof( object ); - } - - internal static Type GetItemTypeFromEnumerationType( Type enumerationType ) - { - if( enumerationType == null ) - return null; - - if( typeof( Array ).IsAssignableFrom( enumerationType ) ) - return enumerationType.GetElementType(); - - var itemType = ItemsSourceHelper.GetTypedListIndexerType( enumerationType ); - if( itemType != null ) - return itemType; - - return ItemsSourceHelper.GetTypedEnumerationItemType( enumerationType ); - } - - internal static IEditableObject GetEditableObject( object item ) - { - var dataRow = item as System.Data.DataRow; - if( dataRow != null ) - return new DataRowEditableWrapper( dataRow ); - - return item as IEditableObject; - } - - internal static ISupportInitialize GetSupportInitializeObject( object item ) - { - return item as ISupportInitialize; - } - - internal static bool IsASubRelationship( Type dataType ) - { - if( ( dataType == null ) || ( dataType.IsValueType ) || ( typeof( string ).IsAssignableFrom( dataType ) ) ) - return false; - - if( typeof( IEnumerable ).IsAssignableFrom( dataType ) ) - return !typeof( byte[] ).IsAssignableFrom( dataType ); - - return typeof( IListSource ).IsAssignableFrom( dataType ); - } - - internal static object TryGetDataRowFromDataItem( object dataItem ) - { - var dataRowView = dataItem as DataRowView; - if( dataRowView != null ) - return dataRowView.Row; - - return dataItem; - } - - internal static DataView TryGetDataViewFromDataGridContext( DataGridContext context ) - { - if( context == null ) - return null; - - var dataView = context.ItemsSourceCollection as DataView; - if( dataView != null ) - return dataView; - - var collectionViewBase = context.ItemsSourceCollection as DataGridCollectionViewBase; - if( collectionViewBase != null ) - return collectionViewBase.SourceCollection as DataView; - - return null; - } - - internal static Type GetColumnDataType( DataColumn column ) - { - if( !column.AllowDBNull ) - return column.DataType; - - if( column.DataType == typeof( Boolean ) ) - return typeof( Nullable ); - - if( column.DataType == typeof( Byte ) ) - return typeof( Nullable ); - - if( column.DataType == typeof( Char ) ) - return typeof( Nullable ); - - if( column.DataType == typeof( DateTime ) ) - return typeof( Nullable ); - - if( column.DataType == typeof( Decimal ) ) - return typeof( Nullable ); - - if( column.DataType == typeof( Double ) ) - return typeof( Nullable ); - - if( column.DataType == typeof( Int16 ) ) - return typeof( Nullable ); - - if( column.DataType == typeof( Int32 ) ) - return typeof( Nullable ); - - if( column.DataType == typeof( Int64 ) ) - return typeof( Nullable ); - - if( column.DataType == typeof( SByte ) ) - return typeof( Nullable ); - - if( column.DataType == typeof( Single ) ) - return typeof( Nullable ); - - if( column.DataType == typeof( TimeSpan ) ) - return typeof( Nullable ); - - if( column.DataType == typeof( UInt16 ) ) - return typeof( Nullable ); - - if( column.DataType == typeof( UInt32 ) ) - return typeof( Nullable ); - - if( column.DataType == typeof( UInt64 ) ) - return typeof( Nullable ); - - return column.DataType; - } - - internal static void CleanUpColumns( ColumnCollection columns, bool deleteAutoCreatedColumn ) - { - var tempColumns = new ColumnBase[ columns.Count ]; - columns.CopyTo( tempColumns, 0 ); - - foreach( ColumnBase column in tempColumns ) - { - var dataColumn = column as Column; - if( dataColumn == null ) - continue; - - if( ( deleteAutoCreatedColumn ) && ( dataColumn.IsAutoCreated ) ) - { - columns.Remove( column ); - } - else if( dataColumn.IsBindingAutoCreated ) - { - dataColumn.IsBindingAutoCreated = false; - dataColumn.IsBoundToDataGridUnboundItemProperty = false; - dataColumn.SetDisplayMemberBinding( null ); - } - } - } - - internal static PropertyDescriptionRoute CreateOrGetPropertyDescriptionFromColumn( DataGridContext dataGridContext, ColumnBase column, Type itemType ) - { - if( ( dataGridContext == null ) || ( column == null ) || string.IsNullOrEmpty( column.FieldName ) ) - return null; - - var key = PropertyRouteParser.Parse( column.FieldName ); - if( key == null ) - return null; - - var propertyDescriptions = dataGridContext.ItemsSourcePropertyDescriptions; - if( propertyDescriptions == null ) - return null; - - var propertyDescriptionRoute = default( PropertyDescriptionRoute ); - if( !propertyDescriptions.TryGetValue( key, out propertyDescriptionRoute ) ) - { - if( ( itemType == null ) || typeof( EmptyDataItem ).IsAssignableFrom( itemType ) ) - { - var dataGridCollectionView = dataGridContext.ItemsSourceCollection as DataGridCollectionViewBase; - if( dataGridCollectionView != null ) - { - itemType = dataGridCollectionView.ItemType; - } - else - { - var dataItem = ItemsSourceHelper.GetFirstItemByEnumerable( dataGridContext.Items ); - - itemType = ( ( dataItem != null ) && !( dataItem is EmptyDataItem ) ) ? dataItem.GetType() : null; - } - } - - ItemsSourceHelper.SetPropertyDescriptions( propertyDescriptions, null, dataGridContext.Items, itemType, key ); - - if( !propertyDescriptions.TryGetValue( key, out propertyDescriptionRoute ) ) - return null; - } - - return propertyDescriptionRoute; - } - - internal static System.Windows.Data.Binding CreateDefaultBinding( PropertyDescriptionRoute propertyDescriptionRoute ) - { - if( propertyDescriptionRoute == null ) - return null; - - var propertyDescription = propertyDescriptionRoute.Current; - var bindingXPath = propertyDescription.XPath; - var bindingPath = new StringBuilder(); - var isPropertyDescriptorFirstAccessor = false; - - var propertyDescriptors = new List(); - if( propertyDescription.PropertyDescriptor != null ) - { - bindingPath.Append( "(" ).Append( propertyDescriptors.Count ).Append( ")" ); - propertyDescriptors.Add( propertyDescription.PropertyDescriptor ); - isPropertyDescriptorFirstAccessor = true; - } - else if( !string.IsNullOrEmpty( propertyDescription.Path ) ) - { - bindingPath.Append( propertyDescription.Path ); - } - - var currentPropertyDescriptionRoute = propertyDescriptionRoute.Parent; - - while( currentPropertyDescriptionRoute != null ) - { - var currentPropertyDescription = currentPropertyDescriptionRoute.Current; - - if( currentPropertyDescription.SupportDBNull ) - throw new InvalidOperationException( "Cannot create binding when a parent property supports DBNull." ); - - if( currentPropertyDescription.IsDataGridUnboundItemProperty ) - throw new InvalidOperationException( "Cannot create binding when a parent property is linked to an UnboundDataGridItemProperty." ); - - if( currentPropertyDescription.ForeignKeyDescription != null ) - throw new InvalidOperationException( "Cannot create binding when a parent property is a foreign key." ); - - if( !string.IsNullOrEmpty( bindingXPath ) ) - throw new InvalidOperationException( "Cannot create binding when a child property has an XPath." ); - - bindingXPath = currentPropertyDescription.XPath; - - if( currentPropertyDescription.PropertyDescriptor != null ) - { - isPropertyDescriptorFirstAccessor = true; - - if( bindingPath.Length != 0 ) - { - bindingPath.Insert( 0, "." ); - } - - bindingPath.Insert( 0, ")" ).Insert( 0, propertyDescriptors.Count ).Insert( 0, "(" ); - propertyDescriptors.Add( currentPropertyDescription.PropertyDescriptor ); - } - else if( !string.IsNullOrEmpty( currentPropertyDescription.Path ) ) - { - isPropertyDescriptorFirstAccessor = false; - - if( bindingPath.Length != 0 ) - { - bindingPath.Insert( 0, "." ); - } - - bindingPath.Insert( 0, currentPropertyDescription.Path ); - } - - currentPropertyDescriptionRoute = currentPropertyDescriptionRoute.Parent; - } - - var bindingInfo = new DataGridBindingInfo(); - - if( !string.IsNullOrEmpty( bindingXPath ) ) - { - bindingInfo.XPath = bindingXPath; - } - else - { - // We must insert a PropertyDescriptor to manage EmptyDataItem when the accessor is not from a DataGridItemPropertyBase. - if( isPropertyDescriptorFirstAccessor && !( propertyDescriptors.Last() is DataGridItemPropertyBase.PropertyDescriptorFromItemPropertyBase ) ) - { - if( bindingPath.Length != 0 ) - { - bindingPath.Insert( 0, "." ); - } - - bindingPath.Insert( 0, ")" ).Insert( 0, propertyDescriptors.Count ).Insert( 0, "(" ); - propertyDescriptors.Add( EmptyDataItemSafePropertyDescriptor.Singleton ); - } - } - - bindingInfo.Path = new PropertyPath( bindingPath.ToString(), propertyDescriptors.ToArray() ); - bindingInfo.ReadOnly = ( propertyDescription.IsReadOnly && !propertyDescription.OverrideReadOnlyForInsertion ); - bindingInfo.Converter = new SourceDataConverter( propertyDescription.SupportDBNull ); - - bindingInfo.ValidationRules.Add( new SourceDataConverterValidationRule( propertyDescription.SupportDBNull, propertyDescription.DataType ) ); - - return bindingInfo.GetBinding(); - } - - private static Type GetTypedListIndexerType( Type listType ) - { - if( ( !typeof( IList ).IsAssignableFrom( listType ) && !typeof( ITypedList ).IsAssignableFrom( listType ) ) && !typeof( IListSource ).IsAssignableFrom( listType ) ) - return null; - - var info = default( PropertyInfo ); - var propertyInfos = listType.GetProperties( BindingFlags.Public | BindingFlags.Instance ); - - foreach( var propertyInfo in propertyInfos ) - { - if( ( propertyInfo.GetIndexParameters().Length > 0 ) && ( propertyInfo.PropertyType != typeof( object ) ) ) - { - info = propertyInfo; - - if( info.Name == "Item" ) - return info.PropertyType; - } - } - - if( info != null ) - return info.PropertyType; - - return null; - } - - private static Type GetTypedEnumerationItemType( Type listType ) - { - if( listType == null ) - return null; - - foreach( Type interfaceType in listType.GetInterfaces() ) - { - if( ( interfaceType.IsGenericType ) && ( interfaceType.GetGenericTypeDefinition() == typeof( IEnumerable<> ) ) ) - return interfaceType.GetGenericArguments()[ 0 ]; - } - - return null; - } - - private static void SetPropertyDescriptions( PropertyDescriptionRouteDictionary propertyDescriptions, DataTable model, IEnumerable itemsSource, Type itemType, PropertyRoute propertyRoute ) - { - if( ( propertyDescriptions == null ) || ( propertyRoute == null ) || propertyDescriptions.Contains( propertyRoute ) ) - return; - - var parentKey = propertyRoute.Parent; - if( parentKey != null ) - { - ItemsSourceHelper.SetPropertyDescriptions( propertyDescriptions, model, itemsSource, itemType, parentKey ); - - PropertyDescriptionRoute parentPropertyDescriptionRoute; - if( !propertyDescriptions.TryGetValue( parentKey, out parentPropertyDescriptionRoute ) ) - return; - - var parentItemType = parentPropertyDescriptionRoute.Current.DataType; - var childPropertyDescriptions = new PropertyDescriptionRouteDictionary(); - - ItemsSourceHelper.SetPropertyDescriptions( childPropertyDescriptions, null, null, parentItemType, false ); - - foreach( var childPropertyDescriptionRoute in childPropertyDescriptions.Values ) - { - var newPropertyDescriptionRoute = PropertyDescriptionRoute.Combine( childPropertyDescriptionRoute, parentPropertyDescriptionRoute ); - var newPropertyRoute = PropertyRouteBuilder.ToPropertyRoute( newPropertyDescriptionRoute ); - - if( ( newPropertyRoute == null ) || propertyDescriptions.Contains( newPropertyRoute ) ) - continue; - - propertyDescriptions.Add( newPropertyRoute, newPropertyDescriptionRoute, false ); - } - - var currentSegment = propertyRoute.Current; - if( currentSegment.Type == PropertyRouteSegmentType.Indexer ) - { - var indexerDescriptionRoute = ItemsSourceHelper.CreateIndexerDescription( itemsSource, parentItemType, currentSegment.Name, false ); - if( indexerDescriptionRoute != null ) - { - var newIndexerDescriptionRoute = PropertyDescriptionRoute.Combine( indexerDescriptionRoute, parentPropertyDescriptionRoute ); - if( newIndexerDescriptionRoute != null ) - { - var newIndexerRoute = PropertyRouteBuilder.ToPropertyRoute( newIndexerDescriptionRoute ); - if( ( newIndexerRoute != null ) && !propertyDescriptions.Contains( newIndexerRoute ) ) - { - propertyDescriptions.Add( newIndexerRoute, newIndexerDescriptionRoute, false ); - } - } - } - } - } - else - { - ItemsSourceHelper.SetPropertyDescriptions( propertyDescriptions, model, itemsSource, itemType, false ); - - var currentSegment = propertyRoute.Current; - if( currentSegment.Type == PropertyRouteSegmentType.Indexer ) - { - var newIndexerDescriptionRoute = ItemsSourceHelper.CreateIndexerDescription( itemsSource, itemType, currentSegment.Name, false ); - if( newIndexerDescriptionRoute != null ) - { - var newIndexerRoute = PropertyRouteBuilder.ToPropertyRoute( newIndexerDescriptionRoute ); - if( ( newIndexerRoute != null ) && !propertyDescriptions.Contains( newIndexerRoute ) ) - { - propertyDescriptions.Add( newIndexerRoute, newIndexerDescriptionRoute, false ); - } - } - } - } - } - - private static IEnumerable CreatePropertyDescriptionsFromDataTable( DataTable source, bool displayable ) - { - Debug.Assert( source != null ); - - var foreignKeyConstraints = ItemsSourceHelper.GetForeignKeyConstraints( source.Constraints ); - var columns = source.Columns; - - foreach( DataColumn column in columns ) - { - yield return new PropertyDescriptionRoute( - new DataTablePropertyDescription( - new DataRowColumnPropertyDescriptor( column ), - column, - foreignKeyConstraints, - displayable ) ); - } - } - - private static IEnumerable CreatePropertyDescriptionsFromDataView( DataView source, bool displayable ) - { - Debug.Assert( source != null ); - - var itemProperties = ( ( ITypedList )source ).GetItemProperties( null ); - var dataTable = source.Table; - var foreignKeyConstraints = ItemsSourceHelper.GetForeignKeyConstraints( dataTable.Constraints ); - var columns = dataTable.Columns; - - foreach( PropertyDescriptor propertyDescriptor in itemProperties ) - { - yield return new PropertyDescriptionRoute( new DataTablePropertyDescription( propertyDescriptor, columns[ propertyDescriptor.Name ], foreignKeyConstraints, displayable ) ); - } - } - - private static IEnumerable CreatePropertyDescriptionsFromDataGridCollectionView( DataGridCollectionViewBase source ) - { - if( source == null ) - return Enumerable.Empty(); - - return ItemsSourceHelper.CreatePropertyDescriptionsFromItemProperties( source.ItemProperties ); - } - - private static IEnumerable CreatePropertyDescriptionsFromItemProperties( IEnumerable source ) - { - if( source == null ) - yield break; - - foreach( var itemProperty in source ) - { - yield return ItemsSourceHelper.CreatePropertyDescriptionFromDataGridItemProperty( itemProperty ); - - foreach( var childItemProperty in ItemsSourceHelper.CreatePropertyDescriptionsFromItemProperties( itemProperty.ItemPropertiesInternal ) ) - { - yield return childItemProperty; - } - } - } - - private static IEnumerable CreatePropertyDescriptionsFromPropertyDescriptors( PropertyDescriptorCollection source, bool supportsDBNull, bool displayable ) - { - if( source == null ) - yield break; - - foreach( PropertyDescriptor propertyDescriptor in source ) - { - yield return new PropertyDescriptionRoute( new PropertyDescriptorPropertyDescription( propertyDescriptor, supportsDBNull, displayable ) ); - } - } - - private static IEnumerable CreatePropertyDescriptionsFromItemType( IEnumerable itemsSource, Type itemType, bool supportsDBNull, bool displayable ) - { - if( itemType == null ) - return Enumerable.Empty(); - - if( typeof( XmlNode ).IsAssignableFrom( itemType ) ) - return Enumerable.Empty(); - - if( itemType.IsArray ) - return ItemsSourceHelper.CreatePropertyDescriptionsFromJaggedArray( itemType, itemsSource, displayable ); - - if( itemType.IsInterface ) - return ItemsSourceHelper.CreatePropertyDescriptionsFromInterface( itemType, displayable ); - - if( ItemsSourceHelper.IsEntityFramework( itemType ) ) - return ItemsSourceHelper.CreatePropertyDescriptionsFromEntityFramework( itemType, displayable ); - - if( ItemsSourceHelper.IsValueType( itemType ) ) - { - var customTypeDescriptor = ItemsSourceHelper.GetCustomTypeDescriptor( itemsSource, itemType ); - - return ItemsSourceHelper.CreatePropertyDescriptionsFromValueType( itemType, supportsDBNull, null, displayable ).Concat( - ( customTypeDescriptor != null ) - ? ItemsSourceHelper.CreatePropertyDescriptionsFromCustomTypeDescriptor( customTypeDescriptor, itemType, supportsDBNull, false ) - : ItemsSourceHelper.CreatePropertyDescriptionsFromPropertyDescriptors( TypeDescriptor.GetProperties( itemType ), supportsDBNull, false ) ); - } - else - { - var customTypeDescriptor = ItemsSourceHelper.GetCustomTypeDescriptor( itemsSource, itemType ); - if( customTypeDescriptor != null ) - return ItemsSourceHelper.CreatePropertyDescriptionsFromCustomTypeDescriptor( customTypeDescriptor, itemType, supportsDBNull, displayable ); - - return ItemsSourceHelper.CreatePropertyDescriptionsFromPropertyDescriptors( TypeDescriptor.GetProperties( itemType ), supportsDBNull, displayable ); - } - } - - private static IEnumerable CreatePropertyDescriptionsFromJaggedArray( Type itemType, IEnumerable jaggedArray, bool displayable ) - { - var firstItem = ItemsSourceHelper.GetFirstItemByEnumerable( jaggedArray ) as Array; - if( ( firstItem == null ) || ( itemType == null ) ) - yield break; - - var fieldCount = firstItem.GetLength( 0 ); - var fieldType = itemType.GetElementType(); - - for( int i = 0; i < fieldCount; i++ ) - { - yield return new PropertyDescriptionRoute( new JaggedArrayPropertyDescription( i, fieldType, displayable ) ); - } - } - - private static IEnumerable CreatePropertyDescriptionsFromInterface( Type itemType, bool displayable ) - { - var propertyDescriptions = ItemsSourceHelper.CreatePropertyDescriptionsFromPropertyDescriptors( TypeDescriptor.GetProperties( itemType ), false, displayable ).ToList(); - var names = new HashSet( propertyDescriptions.Select( item => PropertyRouteParser.Parse( PropertyRouteBuilder.ToPropertyRoute( item ) ) ) ); - - foreach( var interfaceType in itemType.GetInterfaces() ) - { - foreach( PropertyDescriptor propertyDescriptor in TypeDescriptor.GetProperties( interfaceType ) ) - { - PropertyDescription propertyDescription; - - if( names.Contains( propertyDescriptor.Name ) ) - { - var newName = string.Format( "{0}.{1}", interfaceType.FullName, propertyDescriptor.Name ); - propertyDescription = new NamedPropertyDescriptorPropertyDescription( newName, propertyDescriptor, false, displayable ); - } - else - { - propertyDescription = new PropertyDescriptorPropertyDescription( propertyDescriptor, false, displayable ); - } - - Debug.Assert( propertyDescription != null ); - - names.Add( propertyDescription.Name ); - propertyDescriptions.Add( new PropertyDescriptionRoute( propertyDescription ) ); - } - } - - return propertyDescriptions; - } - - private static IEnumerable CreatePropertyDescriptionsFromEntityFramework( Type itemType, bool displayable ) - { - foreach( PropertyDescriptor propertyDescriptor in TypeDescriptor.GetProperties( itemType ) ) - { - yield return new PropertyDescriptionRoute( new EntityFrameworkPropertyDescription( propertyDescriptor, displayable ) ); - } - } - - private static IEnumerable CreatePropertyDescriptionsFromValueType( Type itemType, bool supportsDBNull, DataGridForeignKeyDescription foreignKeyDescription, bool displayable ) - { - yield return new PropertyDescriptionRoute( new ValueTypePropertyDescription( itemType, supportsDBNull, foreignKeyDescription, displayable ) ); - } - - private static IEnumerable CreatePropertyDescriptionsFromCustomTypeDescriptor( ICustomTypeDescriptor customTypeDescriptor, Type itemType, bool supportsDBNull, bool displayable ) - { - if( customTypeDescriptor == null ) - return Enumerable.Empty(); - - return ItemsSourceHelper.CreatePropertyDescriptionsFromPropertyDescriptors( customTypeDescriptor.GetProperties(), supportsDBNull, displayable ); - } - - private static PropertyDescriptionRoute CreatePropertyDescriptionFromDataGridItemProperty( DataGridItemPropertyBase source ) - { - if( source == null ) - return null; - - var collection = source.ContainingCollection; - var ancestors = ( collection != null ) ? ItemsSourceHelper.CreatePropertyDescriptionFromDataGridItemProperty( collection.Owner ) : null; - - return PropertyDescriptionRoute.Combine( new ItemPropertyPropertyDescription( source ), ancestors ); - } - - private static PropertyDescriptionRoute CreateIndexerDescription( IEnumerable itemsSource, Type itemType, string index, bool displayable ) - { - if( ( itemType == null ) || string.IsNullOrEmpty( index ) ) - return null; - - var typeDescriptor = ItemsSourceHelper.GetCustomTypeDescriptor( itemsSource, itemType ) as DataItemTypeDescriptor; - if( typeDescriptor == null ) - return null; - - var parameters = IndexerParametersParser.Parse( index ).ToArray(); - if( parameters.Length <= 0 ) - return null; - - var indexerDescriptor = typeDescriptor.GetIndexer( parameters ); - if( indexerDescriptor == null ) - return null; - - var supportsDBNull = ItemsSourceHelper.IsSupportingDBNull( itemsSource ); - - return new PropertyDescriptionRoute( new IndexerDescriptorPropertyDescription( indexerDescriptor, supportsDBNull, displayable ) ); - } - - private static Dictionary GetForeignKeyConstraints( ConstraintCollection constraints ) - { - var foreignKeyConstraints = new Dictionary(); - - // Detect every ForeignKeyConstraints - foreach( Constraint constraint in constraints ) - { - var foreignKeyConstraint = constraint as ForeignKeyConstraint; - if( foreignKeyConstraint == null ) - continue; - - // We only support auto-detection when the ForeignKey is composed of a single column - if( ( foreignKeyConstraint.Columns != null ) && ( foreignKeyConstraint.Columns.Length == 1 ) ) - { - foreignKeyConstraints.Add( foreignKeyConstraint.Columns[ 0 ].ColumnName, foreignKeyConstraint ); - } - } - - return foreignKeyConstraints; - } - - private static DataGridForeignKeyDescription GetDataGridForeignKeyDescriptionForEnum( Type enumType ) - { - if( ( enumType == null ) || !enumType.IsEnum ) - return null; - - var description = new DataGridForeignKeyDescription(); - - // Using "." as default value path will revert to Self when used as SelectedValuePath when bound to a DataGridForeignKeyDictionary or ComboBox (default editor) - description.ValuePath = "."; - description.ItemsSource = Enum.GetValues( enumType ); - description.IsAutoCreated = true; - - return description; - } - - private static DataTableForeignKeyDescription GetDataGridForeignKeyDescriptionForForeignKeyConstraint( ForeignKeyConstraint foreignKeyConstraint ) - { - if( foreignKeyConstraint == null ) - return null; - - var columns = foreignKeyConstraint.Columns; - if( ( columns == null ) || ( columns.Length != 1 ) ) - return null; - - var description = new DataTableForeignKeyDescription(); - description.ForeignKeyConstraint = foreignKeyConstraint; - description.IsAutoCreated = true; - - return description; - } - - private static DataGridItemPropertyBase CreateItemPropertyFromPropertyDescription( PropertyDescription propertyDescription ) - { - if( propertyDescription == null ) - return null; - - return new DataGridItemProperty( - propertyDescription.Name, - propertyDescription.PropertyDescriptor, - propertyDescription.DisplayName, - propertyDescription.XPath, - propertyDescription.Path, - propertyDescription.DataType, - true, - propertyDescription.IsReadOnly, - propertyDescription.OverrideReadOnlyForInsertion, - propertyDescription.IsDisplayable, - propertyDescription.IsSubRelationship, - propertyDescription.ForeignKeyDescription ); - } - - internal static List CreateDetailDescriptions( Type itemType, IEnumerable enumeration ) - { - var dataTable = enumeration as DataTable; - if( dataTable == null ) - { - var dataView = enumeration as DataView; - if( dataView != null ) - { - dataTable = dataView.Table; - } - } - - if( dataTable != null ) - return ItemsSourceHelper.CreateDetailDescriptions( dataTable ); - - if( itemType != null ) - { - //We do not support automatic Master/Detail detection with an Xml source - if( typeof( XmlNode ).IsAssignableFrom( itemType ) ) - return new List( 0 ); - - //Unbound mode, we do not support Master/Detail in this scenario. - if( typeof( DataRow ).IsAssignableFrom( itemType ) ) - return new List( 0 ); - - //we do not support Master/Details when Item is a Value type... - if( ItemsSourceHelper.IsValueType( itemType ) ) - return new List( 0 ); - - //Check if the object is a Entity Framework Entity, before checking for IEnumerable (since Entity Framework does have IEnumerable - //properties, but require special handling )... - if( ItemsSourceHelper.IsEntityFramework( itemType ) ) - return ItemsSourceHelper.CreateDetailDescriptionsForEntityFramework( itemType ); - - //If the first item maps to an object that implements IEnumerable, expand that as a Relation ( and only that )... - if( typeof( IEnumerable ).IsAssignableFrom( itemType ) ) - return ItemsSourceHelper.CreateDetailDescriptionsForEnumerable(); - - if( typeof( IListSource ).IsAssignableFrom( itemType ) ) - return ItemsSourceHelper.CreateDetailDescriptionsForListSource(); - } - - //If the Source collection implements ITypedList - var typedList = enumeration as ITypedList; - if( typedList != null ) - return ItemsSourceHelper.GetDataGridDetailDescriptions( typedList.GetItemProperties( null ) ); - - var customTypeDescriptor = ItemsSourceHelper.GetCustomTypeDescriptor( enumeration, itemType ); - if( customTypeDescriptor != null ) - return ItemsSourceHelper.GetDataGridDetailDescriptions( customTypeDescriptor.GetProperties() ); - - if( itemType != null ) - return ItemsSourceHelper.GetDataGridDetailDescriptions( TypeDescriptor.GetProperties( itemType ) ); - - return new List( 0 ); - } - - internal static List CreateDetailDescriptions( DataTable dataTable ) - { - if( dataTable == null ) - return new List( 0 ); - - return ItemsSourceHelper.CreateDetailDescriptionsForDataTable( dataTable ); - } - - private static List CreateDetailDescriptionsForDataTable( DataTable dataTable ) - { - var detailDescriptions = new List( dataTable.ChildRelations.Count ); - - foreach( DataRelation relation in dataTable.ChildRelations ) - { - var description = new DataRelationDetailDescription( relation ); - description.IsAutoCreated = true; - description.IsInitialized = true; - detailDescriptions.Add( description ); - } - - return detailDescriptions; - } - - private static List CreateDetailDescriptionsForEntityFramework( Type type ) - { - var detailDescriptions = new List(); - - // Gets all the public properties of the type. - var propertyInfos = type.GetProperties( BindingFlags.Instance | BindingFlags.Public ); - - // Loop throught the properties to build up the detail descriptions. - foreach( var propertyInfo in propertyInfos ) - { - // We must use Reflection to check for the EntityFramework types. - var propertyType = propertyInfo.PropertyType; - - // The property must be of type RelatedEnd and IEnumerable to continue. - if( ( propertyType.BaseType != null ) - && ( propertyType.BaseType.FullName == "System.Data.Objects.DataClasses.RelatedEnd" ) - && ( typeof( IEnumerable ).IsAssignableFrom( propertyType ) ) ) - { - detailDescriptions.Add( new EntityDetailDescription( propertyInfo.Name ) ); - } - } - - return detailDescriptions; - } - - private static List CreateDetailDescriptionsForEnumerable() - { - var detailDescriptions = new List( 1 ); - - var description = new EnumerableDetailDescription(); - description.IsAutoCreated = true; - description.IsInitialized = true; - detailDescriptions.Add( description ); - - return detailDescriptions; - } - - private static List CreateDetailDescriptionsForListSource() - { - var detailDescriptions = new List( 1 ); - - var description = new ListSourceDetailDescription(); - description.IsAutoCreated = true; - description.IsInitialized = true; - detailDescriptions.Add( description ); - - return detailDescriptions; - } - - private static List GetDataGridDetailDescriptions( PropertyDescriptorCollection properties ) - { - var detailDescriptions = new List( properties.Count ); - - foreach( PropertyDescriptor property in properties ) - { - // We only create details for properties that are browsable. - if( !property.IsBrowsable ) - continue; - - if( ItemsSourceHelper.IsASubRelationship( property.PropertyType ) ) - { - var description = new PropertyDetailDescription( property ); - description.IsAutoCreated = true; - description.IsInitialized = true; - detailDescriptions.Add( description ); - } - } - - return detailDescriptions; - } - - private static bool IsEditableObjectInsertedOrRemovedFromDataSourceAutomatically( IEditableObject item ) - { - return ( item is DataRowView ) - || ( item is DataRow ); - } - - #region DataTablePropertyDescription Private Class - - private sealed class DataTablePropertyDescription : PropertyDescription - { - internal DataTablePropertyDescription( PropertyDescriptor propertyDescriptor, DataColumn column, IDictionary constraints, bool isDisplayable ) - { - if( propertyDescriptor == null ) - throw new ArgumentNullException( "propertyDescriptor" ); - - m_propertyDescriptor = propertyDescriptor; - m_column = column; - m_isDisplayable = isDisplayable; - - if( constraints != null ) - { - ForeignKeyConstraint constraint; - if( constraints.TryGetValue( propertyDescriptor.Name, out constraint ) ) - { - m_foreignKeyDescription = ItemsSourceHelper.GetDataGridForeignKeyDescriptionForForeignKeyConstraint( constraint ); - } - } - } - - internal override string Name - { - get - { - return m_propertyDescriptor.Name; - } - } - - internal override string DisplayName - { - get - { - if( m_column != null ) - return m_column.Caption; - - return m_propertyDescriptor.DisplayName; - } - } - - internal override Type DataType - { - get - { - return m_propertyDescriptor.PropertyType; - } - } - - internal override PropertyDescriptor PropertyDescriptor - { - get - { - return m_propertyDescriptor; - } - } - - internal override bool IsReadOnly - { - get - { - return m_propertyDescriptor.IsReadOnly; - } - } - - internal override bool SupportDBNull - { - get - { - return ( m_column != null ) - && ( m_column.AllowDBNull ); - } - } - - internal override bool IsBrowsable - { - get - { - return m_propertyDescriptor.IsBrowsable; - } - } - - internal override bool IsDisplayable - { - get - { - return m_isDisplayable; - } - } - - internal override bool IsSubRelationship - { - get - { - return ( m_column == null ) - && ( ItemsSourceHelper.IsASubRelationship( this.DataType ) ); - } - } - - internal override DataGridForeignKeyDescription ForeignKeyDescription - { - get - { - return m_foreignKeyDescription; - } - } - - public override int GetHashCode() - { - return m_propertyDescriptor.GetHashCode(); - } - - public override bool Equals( object obj ) - { - var target = obj as DataTablePropertyDescription; - if( target == null ) - return false; - - return ( object.Equals( target.m_propertyDescriptor, m_propertyDescriptor ) ) - && ( object.Equals( target.m_column, m_column ) ); - } - - private readonly PropertyDescriptor m_propertyDescriptor; - private readonly DataColumn m_column; - private readonly bool m_isDisplayable; - private readonly DataGridForeignKeyDescription m_foreignKeyDescription; - } - - #endregion - - #region ItemPropertyPropertyDescription Private Class - - private sealed class ItemPropertyPropertyDescription : PropertyDescription - { - internal ItemPropertyPropertyDescription( DataGridItemPropertyBase itemProperty ) - { - if( itemProperty == null ) - throw new ArgumentNullException( "itemProperty" ); - - m_itemProperty = itemProperty; - m_propertyDescriptor = itemProperty.GetPropertyDescriptorForBinding(); - Debug.Assert( m_propertyDescriptor != null ); - } - - internal override string Name - { - get - { - return m_itemProperty.Name; - } - } - - internal override string DisplayName - { - get - { - return m_propertyDescriptor.DisplayName; - } - } - - internal override Type DataType - { - get - { - return m_propertyDescriptor.PropertyType; - } - } - - internal override PropertyDescriptor PropertyDescriptor - { - get - { - return m_propertyDescriptor; - } - } - - internal override bool IsReadOnly - { - get - { - return m_propertyDescriptor.IsReadOnly; - } - } - - internal override bool OverrideReadOnlyForInsertion - { - get - { - return m_itemProperty.OverrideReadOnlyForInsertion.GetValueOrDefault( false ); - } - } - - internal override bool IsBrowsable - { - get - { - return m_propertyDescriptor.IsBrowsable; - } - } - - internal override bool IsDisplayable - { - get - { - return m_itemProperty.IsDisplayable; - } - } - - internal override bool IsSubRelationship - { - get - { - return m_itemProperty.IsASubRelationship; - } - } - - internal override DataGridForeignKeyDescription ForeignKeyDescription - { - get - { - return m_itemProperty.ForeignKeyDescription; - } - } - - public override int GetHashCode() - { - return m_itemProperty.GetHashCode(); - } - - public override bool Equals( object obj ) - { - var target = obj as ItemPropertyPropertyDescription; - if( target == null ) - return false; - - return object.Equals( target.m_itemProperty, m_itemProperty ); - } - - private readonly DataGridItemPropertyBase m_itemProperty; - private readonly PropertyDescriptor m_propertyDescriptor; - } - - #endregion - - #region PropertyDescriptorPropertyDescription Private Class - - private class PropertyDescriptorPropertyDescription : PropertyDescription - { - internal PropertyDescriptorPropertyDescription( PropertyDescriptor propertyDescriptor, bool supportDBNull, bool isDisplayable ) - { - if( propertyDescriptor == null ) - throw new ArgumentNullException( "propertyDescriptor" ); - - m_propertyDescriptor = propertyDescriptor; - m_supportDBNull = supportDBNull; - m_isDisplayable = isDisplayable; - m_foreignKeyDescription = ItemsSourceHelper.GetDataGridForeignKeyDescriptionForEnum( propertyDescriptor.PropertyType ); - } - - internal override string Name - { - get - { - return m_propertyDescriptor.Name; - } - } - - internal override string DisplayName - { - get - { - return m_propertyDescriptor.DisplayName; - } - } - - internal override Type DataType - { - get - { - return m_propertyDescriptor.PropertyType; - } - } - - internal override PropertyDescriptor PropertyDescriptor - { - get - { - return m_propertyDescriptor; - } - } - - internal override bool IsReadOnly - { - get - { - return m_propertyDescriptor.IsReadOnly; - } - } - - internal override bool SupportDBNull - { - get - { - return m_supportDBNull; - } - } - - internal override bool IsBrowsable - { - get - { - return m_propertyDescriptor.IsBrowsable; - } - } - - internal override bool IsDisplayable - { - get - { - return m_isDisplayable; - } - } - - internal override bool IsSubRelationship - { - get - { - return ItemsSourceHelper.IsASubRelationship( this.DataType ); - } - } - - internal override DataGridForeignKeyDescription ForeignKeyDescription - { - get - { - return m_foreignKeyDescription; - } - } - - public override int GetHashCode() - { - return m_propertyDescriptor.GetHashCode(); - } - - public override bool Equals( object obj ) - { - var target = obj as PropertyDescriptorPropertyDescription; - if( target == null ) - return false; - - return ( object.Equals( target.m_propertyDescriptor, m_propertyDescriptor ) ) - && ( target.m_supportDBNull == m_supportDBNull ); - } - - private readonly PropertyDescriptor m_propertyDescriptor; - private readonly bool m_supportDBNull; - private readonly bool m_isDisplayable; - private readonly DataGridForeignKeyDescription m_foreignKeyDescription; - } - - #endregion - - #region NamedPropertyDescriptorPropertyDescription Private Class - - private sealed class NamedPropertyDescriptorPropertyDescription : PropertyDescriptorPropertyDescription - { - internal NamedPropertyDescriptorPropertyDescription( string name, PropertyDescriptor propertyDescriptor, bool supportDBNull, bool isDisplayable ) - : base( propertyDescriptor, supportDBNull, isDisplayable ) - { - if( name == null ) - throw new ArgumentNullException( "name" ); - - m_name = name; - } - - internal override string Name - { - get - { - return m_name; - } - } - - public override int GetHashCode() - { - return m_name.GetHashCode(); - } - - public override bool Equals( object obj ) - { - var target = obj as NamedPropertyDescriptorPropertyDescription; - if( target == null ) - return false; - - return ( target.m_name == m_name ) - && ( base.Equals( target ) ); - } - - private readonly string m_name; - } - - #endregion - - #region IndexerDescriptorPropertyDescription Private Class - - private class IndexerDescriptorPropertyDescription : PropertyDescriptorPropertyDescription - { - internal IndexerDescriptorPropertyDescription( DataItemIndexerDescriptor indexerDescriptor, bool supportDBNull, bool isDisplayable ) - : base( indexerDescriptor, supportDBNull, isDisplayable ) - { - } - - public override int GetHashCode() - { - return base.GetHashCode(); - } - - public override bool Equals( object obj ) - { - return ( obj is IndexerDescriptorPropertyDescription ) - && ( base.Equals( obj ) ); - } - - internal override PropertyRouteSegment ToPropertyRouteSegment() - { - var descriptor = ( DataItemIndexerDescriptor )this.PropertyDescriptor; - - return new PropertyRouteSegment( PropertyRouteSegmentType.Indexer, descriptor.IndexerParameters ); - } - } - - #endregion - - #region JaggedArrayPropertyDescription Private Class - - private sealed class JaggedArrayPropertyDescription : PropertyDescription - { - internal JaggedArrayPropertyDescription( int index, Type dataType, bool isDisplayable ) - { - if( index < 0 ) - throw new ArgumentException( "index" ); - - if( dataType == null ) - throw new ArgumentNullException( "dataType" ); - - m_name = ".[" + index.ToString( CultureInfo.InvariantCulture ) + "]"; - m_dataType = dataType; - m_isDisplayable = isDisplayable; - m_propertyDescriptor = new JaggedArrayPropertyDescriptor( index, dataType ); - m_foreignKeyDescription = ItemsSourceHelper.GetDataGridForeignKeyDescriptionForEnum( dataType ); - } - - internal override string Name - { - get - { - return m_name; - } - } - - internal override string DisplayName - { - get - { - return m_name; - } - } - - internal override Type DataType - { - get - { - return m_dataType; - } - } - - internal override PropertyDescriptor PropertyDescriptor - { - get - { - return m_propertyDescriptor; - } - } - - internal override bool IsReadOnly - { - get - { - return false; - } - } - - internal override bool IsDisplayable - { - get - { - return m_isDisplayable; - } - } - - internal override bool IsSubRelationship - { - get - { - return ItemsSourceHelper.IsASubRelationship( this.DataType ); - } - } - - internal override DataGridForeignKeyDescription ForeignKeyDescription - { - get - { - return m_foreignKeyDescription; - } - } - - public override int GetHashCode() - { - return m_name.GetHashCode(); - } - - public override bool Equals( object obj ) - { - var target = obj as JaggedArrayPropertyDescription; - if( target == null ) - return false; - - return ( target.m_name == m_name ) - && ( target.m_dataType == m_dataType ); - } - - private readonly string m_name; - private readonly Type m_dataType; - private readonly bool m_isDisplayable; - private readonly PropertyDescriptor m_propertyDescriptor; - private readonly DataGridForeignKeyDescription m_foreignKeyDescription; - } - - #endregion - - #region EntityFrameworkPropertyDescription Private Class - - private sealed class EntityFrameworkPropertyDescription : PropertyDescription - { - internal EntityFrameworkPropertyDescription( PropertyDescriptor propertyDescriptor, bool isDisplayable ) - { - if( propertyDescriptor == null ) - throw new ArgumentNullException( "propertyDescriptor" ); - - var attribute = propertyDescriptor.Attributes[ typeof( EdmScalarPropertyAttribute ) ] as EdmScalarPropertyAttribute; - if( attribute != null ) - { - m_isEntityKey = attribute.EntityKeyProperty; - m_supportDBNull = attribute.IsNullable; - } - else - { - m_isEntityKey = false; - m_supportDBNull = false; - } - - m_isDisplayable = isDisplayable; - m_propertyDescriptor = propertyDescriptor; - } - - internal override string Name - { - get - { - return m_propertyDescriptor.Name; - } - } - - internal override string DisplayName - { - get - { - return m_propertyDescriptor.DisplayName; - } - } - - internal override Type DataType - { - get - { - return m_propertyDescriptor.PropertyType; - } - } - - internal override PropertyDescriptor PropertyDescriptor - { - get - { - return m_propertyDescriptor; - } - } - - internal override bool IsReadOnly - { - get - { - return ( m_isEntityKey ) - || ( m_propertyDescriptor.IsReadOnly ); - } - } - - internal override bool OverrideReadOnlyForInsertion - { - get - { - return ( m_isEntityKey ) - && ( !m_propertyDescriptor.IsReadOnly ); - } - } - - internal override bool SupportDBNull - { - get - { - return m_supportDBNull; - } - } - - internal override bool IsBrowsable - { - get - { - return m_propertyDescriptor.IsBrowsable; - } - } - - internal override bool IsDisplayable - { - get - { - return m_isDisplayable; - } - } - - internal override bool IsSubRelationship - { - get - { - return ItemsSourceHelper.IsASubRelationship( this.DataType ); - } - } - - public override int GetHashCode() - { - return m_propertyDescriptor.GetHashCode(); - } - - public override bool Equals( object obj ) - { - var target = obj as EntityFrameworkPropertyDescription; - if( target == null ) - return false; - - return object.Equals( target.m_propertyDescriptor, m_propertyDescriptor ); - } - - private readonly PropertyDescriptor m_propertyDescriptor; - private readonly bool m_isEntityKey; - private readonly bool m_supportDBNull; - private readonly bool m_isDisplayable; - } - - #endregion - - #region ValueTypePropertyDescription Private Class - - private sealed class ValueTypePropertyDescription : PropertyDescription - { - internal ValueTypePropertyDescription( Type dataType, bool supportDBNull, DataGridForeignKeyDescription foreignKeyDescription, bool isDisplayable ) - { - if( dataType == null ) - throw new ArgumentNullException( "dataType" ); - - m_dataType = dataType; - m_supportDBNull = supportDBNull; - m_isDisplayable = isDisplayable; - m_foreignKeyDescription = foreignKeyDescription; - } - - internal override string Name - { - get - { - return "."; - } - } - - internal override string DisplayName - { - get - { - return string.Empty; - } - } - - internal override Type DataType - { - get - { - return m_dataType; - } - } - - internal override string Path - { - get - { - return this.Name; - } - } - - internal override bool SupportDBNull - { - get - { - return m_supportDBNull; - } - } - - internal override bool IsDisplayable - { - get - { - return m_isDisplayable; - } - } - - internal override bool IsSubRelationship - { - get - { - return ItemsSourceHelper.IsASubRelationship( this.DataType ); - } - } - - internal override DataGridForeignKeyDescription ForeignKeyDescription - { - get - { - return m_foreignKeyDescription; - } - } - - public override int GetHashCode() - { - return m_dataType.GetHashCode(); - } - - public override bool Equals( object obj ) - { - var target = obj as ValueTypePropertyDescription; - if( target == null ) - return false; - - return ( target.m_dataType == m_dataType ); - } - - internal override PropertyRouteSegment ToPropertyRouteSegment() - { - return PropertyRouteSegment.Self; - } - - private readonly Type m_dataType; - private readonly bool m_supportDBNull; - private readonly bool m_isDisplayable; - private readonly DataGridForeignKeyDescription m_foreignKeyDescription; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/KeyActivationGesture.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/KeyActivationGesture.cs deleted file mode 100644 index b3533f12..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/KeyActivationGesture.cs +++ /dev/null @@ -1,114 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Windows.Input; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - public sealed class KeyActivationGesture : ActivationGesture - { - #region Key Property - - public static readonly DependencyProperty KeyProperty = DependencyProperty.Register( - "Key", - typeof( Key ), - typeof( KeyActivationGesture ), - new FrameworkPropertyMetadata( Key.None ) ); - - public Key Key - { - get - { - return ( Key )this.GetValue( KeyActivationGesture.KeyProperty ); - } - set - { - this.SetValue( KeyActivationGesture.KeyProperty, value ); - } - } - - #endregion - - #region SystemKey Property - - public static readonly DependencyProperty SystemKeyProperty = DependencyProperty.Register( - "SystemKey", - typeof( Key ), - typeof( KeyActivationGesture ), - new FrameworkPropertyMetadata( Key.None ) ); - - public Key SystemKey - { - get - { - return ( Key )this.GetValue( KeyActivationGesture.SystemKeyProperty ); - } - set - { - this.SetValue( KeyActivationGesture.SystemKeyProperty, value ); - } - } - - #endregion - - #region Modifiers Property - - public static readonly DependencyProperty ModifiersProperty = DependencyProperty.Register( - "Modifiers", - typeof( ModifierKeys ), - typeof( KeyActivationGesture ), - new FrameworkPropertyMetadata( ( ModifierKeys )ModifierKeys.None ) ); - - public ModifierKeys Modifiers - { - get - { - return ( ModifierKeys )this.GetValue( KeyActivationGesture.ModifiersProperty ); - } - set - { - this.SetValue( KeyActivationGesture.ModifiersProperty, value ); - } - } - - #endregion - - public bool IsActivationKey( Key key, Key systemKey, ModifierKeys modifiers) - { - if( key == Key.System ) - { - return - ( ( systemKey == this.SystemKey ) && - ( modifiers == this.Modifiers ) ); - } - else - { - return - ( ( key == this.Key ) && - ( modifiers == this.Modifiers ) ); - } - } - - protected override Freezable CreateInstanceCore() - { - return new KeyActivationGesture(); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/LateGroupLevelDescription.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/LateGroupLevelDescription.cs deleted file mode 100644 index 4ffb8f02..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/LateGroupLevelDescription.cs +++ /dev/null @@ -1,430 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Diagnostics; -using System.Globalization; -using System.Windows; -using System.Windows.Controls; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class LateGroupLevelDescription : IGroupLevelDescription, INotifyPropertyChanged, IWeakEventListener - { - internal LateGroupLevelDescription( GroupDescription groupDescription, IEnumerable groupLevelDescriptions ) - { - if( groupDescription == null ) - throw new ArgumentNullException( "groupDescription" ); - - var finder = new GroupLevelDescriptionFinder( groupDescription, groupLevelDescriptions ); - - m_groupDescription = groupDescription; - m_groupLevelDescription = finder.GroupLevelDescription; - - if( m_groupLevelDescription == null ) - { - m_finder = finder; - m_finder.PropertyChanged += new PropertyChangedEventHandler( this.OnGroupLevelDescriptionFound ); - } - else - { - finder.Dispose(); - - PropertyChangedEventManager.AddListener( m_groupLevelDescription, this, string.Empty ); - } - } - - #region GroupDescription Property - - public GroupDescription GroupDescription - { - get - { - return m_groupDescription; - } - } - - private readonly GroupDescription m_groupDescription; - - #endregion - - #region FieldName Property - - public string FieldName - { - get - { - GroupLevelDescription description; - if( !this.TryGetGroupLevelDescription( out description ) ) - return null; - - return description.FieldName; - } - } - - #endregion - - #region Title Property - - public object Title - { - get - { - GroupLevelDescription description; - if( !this.TryGetGroupLevelDescription( out description ) ) - return null; - - return description.Title; - } - } - - #endregion - - #region TitleTemplate Property - - public DataTemplate TitleTemplate - { - get - { - GroupLevelDescription description; - if( !this.TryGetGroupLevelDescription( out description ) ) - return null; - - return description.TitleTemplate; - } - } - - #endregion - - #region TitleTemplateSelector Property - - public DataTemplateSelector TitleTemplateSelector - { - get - { - GroupLevelDescription description; - if( !this.TryGetGroupLevelDescription( out description ) ) - return null; - - return description.TitleTemplateSelector; - } - } - - #endregion - - #region ValueStringFormat Property - - public string ValueStringFormat - { - get - { - GroupLevelDescription description; - if( !this.TryGetGroupLevelDescription( out description ) ) - return null; - - return description.ValueStringFormat; - } - } - - #endregion - - #region ValueStringFormatCulture Property - - public CultureInfo ValueStringFormatCulture - { - get - { - GroupLevelDescription description; - if( !this.TryGetGroupLevelDescription( out description ) ) - return null; - - return description.ValueStringFormatCulture; - } - } - - #endregion - - #region ValueTemplate Property - - public DataTemplate ValueTemplate - { - get - { - GroupLevelDescription description; - if( !this.TryGetGroupLevelDescription( out description ) ) - return null; - - return description.ValueTemplate; - } - } - - #endregion - - #region ValueTemplateSelector Property - - public DataTemplateSelector ValueTemplateSelector - { - get - { - GroupLevelDescription description; - if( !this.TryGetGroupLevelDescription( out description ) ) - return null; - - return description.ValueTemplateSelector; - } - } - - #endregion - - internal void Clear() - { - this.ClearLateBinding(); - - this.PropertyChanged = null; - } - - private void ClearLateBinding() - { - if( m_finder != null ) - { - m_finder.PropertyChanged -= new PropertyChangedEventHandler( this.OnGroupLevelDescriptionFound ); - m_finder.Dispose(); - m_finder = null; - } - - if( m_groupLevelDescription != null ) - { - PropertyChangedEventManager.RemoveListener( m_groupLevelDescription, this, string.Empty ); - } - } - - private bool TryGetGroupLevelDescription( out GroupLevelDescription result ) - { - result = m_groupLevelDescription; - if( result != null ) - return true; - - m_raiseEventOnGroupLevelDescriptionFound = true; - - return false; - } - - private void OnGroupLevelDescriptionFound( object sender, PropertyChangedEventArgs e ) - { - var finder = ( GroupLevelDescriptionFinder )sender; - Debug.Assert( finder == m_finder ); - - var groupLevelDescription = finder.GroupLevelDescription; - Debug.Assert( groupLevelDescription != null ); - - this.ClearLateBinding(); - - m_groupLevelDescription = groupLevelDescription; - PropertyChangedEventManager.AddListener( m_groupLevelDescription, this, string.Empty ); - - if( m_raiseEventOnGroupLevelDescriptionFound ) - { - this.RaisePropertyChanged(); - } - } - - private void OnGroupLevelDescriptionPropertyChanged( object sender, PropertyChangedEventArgs e ) - { - Debug.Assert( sender == m_groupLevelDescription ); - - this.RaisePropertyChanged( e ); - } - - #region INotifyPropertyChanged Members - - public event PropertyChangedEventHandler PropertyChanged; - - private void RaisePropertyChanged() - { - var handler = this.PropertyChanged; - if( handler == null ) - return; - - handler.Invoke( this, new PropertyChangedEventArgs( null ) ); - } - - private void RaisePropertyChanged( PropertyChangedEventArgs e ) - { - var handler = this.PropertyChanged; - if( handler == null ) - return; - - handler.Invoke( this, e ); - } - - #endregion - - #region IWeakEventListener Members - - bool IWeakEventListener.ReceiveWeakEvent( Type managerType, object sender, EventArgs e ) - { - if( typeof( PropertyChangedEventManager ) == managerType ) - { - this.OnGroupLevelDescriptionPropertyChanged( sender, ( PropertyChangedEventArgs )e ); - } - else - { - return false; - } - - return true; - } - - #endregion - - private GroupLevelDescription m_groupLevelDescription; - private GroupLevelDescriptionFinder m_finder; - private bool m_raiseEventOnGroupLevelDescriptionFound; //false - - private sealed class GroupLevelDescriptionFinder : INotifyPropertyChanged, IWeakEventListener, IDisposable - { - internal GroupLevelDescriptionFinder( GroupDescription groupDescription, IEnumerable groupLevelDescriptions ) - { - if( groupDescription == null ) - throw new ArgumentNullException( "groupDescription" ); - - if( groupLevelDescriptions == null ) - throw new ArgumentNullException( "groupLevelDescriptions" ); - - if( !GroupLevelDescriptionFinder.TryFind( groupLevelDescriptions, groupDescription, out m_groupLevelDescription ) ) - { - m_groupDescription = groupDescription; - m_groupLevelDescriptions = groupLevelDescriptions; - - this.RegisterCollectionChanged( ( INotifyCollectionChanged )groupLevelDescriptions ); - } - } - - #region GroupLevelDescription Property - - internal GroupLevelDescription GroupLevelDescription - { - get - { - return m_groupLevelDescription; - } - } - - #endregion - - public event PropertyChangedEventHandler PropertyChanged; - - private void RaisePropertyChanged( string propertyName ) - { - var handler = this.PropertyChanged; - if( handler == null ) - return; - - handler.Invoke( this, new PropertyChangedEventArgs( propertyName ) ); - } - - private void RegisterCollectionChanged( INotifyCollectionChanged collection ) - { - if( collection == null ) - return; - - CollectionChangedEventManager.AddListener( collection, this ); - } - - private void UnregisterCollectionChanged( INotifyCollectionChanged collection ) - { - if( collection == null ) - return; - - CollectionChangedEventManager.RemoveListener( collection, this ); - } - - private static bool TryFind( IEnumerable collection, GroupDescription description, out GroupLevelDescription result ) - { - result = default( GroupLevelDescription ); - - if( ( collection != null ) && ( description != null ) ) - { - foreach( var item in collection ) - { - if( ( item == null ) || ( item.GroupDescription != description ) ) - continue; - - result = item; - break; - } - } - - return ( result != null ); - } - - bool IWeakEventListener.ReceiveWeakEvent( Type managerType, object sender, EventArgs e ) - { - if( typeof( CollectionChangedEventManager ) == managerType ) - { - Debug.Assert( sender == m_groupLevelDescriptions ); - - switch( ( ( NotifyCollectionChangedEventArgs )e ).Action ) - { - case NotifyCollectionChangedAction.Move: - case NotifyCollectionChangedAction.Remove: - break; - - default: - if( GroupLevelDescriptionFinder.TryFind( m_groupLevelDescriptions, m_groupDescription, out m_groupLevelDescription ) ) - { - this.RaisePropertyChanged( "GroupLevelDescription" ); - this.Dispose(); - } - break; - } - - return true; - } - - return false; - } - - public void Dispose() - { - this.Dispose( true ); - GC.SuppressFinalize( this ); - } - - private void Dispose( bool disposing ) - { - this.PropertyChanged = null; - - this.UnregisterCollectionChanged( ( INotifyCollectionChanged )m_groupLevelDescriptions ); - - m_groupLevelDescriptions = null; - m_groupDescription = null; - } - - ~GroupLevelDescriptionFinder() - { - this.Dispose( false ); - } - - private GroupDescription m_groupDescription; //null - private GroupLevelDescription m_groupLevelDescription; //null - private IEnumerable m_groupLevelDescriptions; //null - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/LevelGroupConfigurationSelector.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/LevelGroupConfigurationSelector.cs deleted file mode 100644 index 6668e80c..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/LevelGroupConfigurationSelector.cs +++ /dev/null @@ -1,53 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Windows.Markup; -using System.Collections.ObjectModel; -using System.Windows.Data; - -namespace Xceed.Wpf.DataGrid -{ - [ContentProperty( "SelectorItems" )] - public class LevelGroupConfigurationSelector : GroupConfigurationSelector - { - private LevelGroupConfigurationSelectorItemCollection m_groupConfigurationSelectorItems = new LevelGroupConfigurationSelectorItemCollection(); - - public ObservableCollection SelectorItems - { - get - { - return m_groupConfigurationSelectorItems; - } - } - - public override GroupConfiguration SelectGroupConfiguration(int groupLevel, CollectionViewGroup collectionViewGroup, System.ComponentModel.GroupDescription groupDescription) - { - if (m_groupConfigurationSelectorItems.Count == 0) - return base.SelectGroupConfiguration( groupLevel, collectionViewGroup, groupDescription ); - - LevelGroupConfigurationSelectorItem levelGroupConfig = m_groupConfigurationSelectorItems.GetGroupConfigurationSelectorItem( groupLevel ); - if( levelGroupConfig != null ) - { - return levelGroupConfig.GroupConfiguration; - } - - return base.SelectGroupConfiguration( groupLevel, collectionViewGroup, groupDescription ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/LevelGroupConfigurationSelectorItem.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/LevelGroupConfigurationSelectorItem.cs deleted file mode 100644 index 80a378fc..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/LevelGroupConfigurationSelectorItem.cs +++ /dev/null @@ -1,86 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Windows.Markup; - -namespace Xceed.Wpf.DataGrid -{ - [ContentProperty("GroupConfiguration" )] - public class LevelGroupConfigurationSelectorItem - { - #region Level Property - - public int Level - { - get - { - return m_level; - } - set - { - if( m_isSealed == true ) - throw new InvalidOperationException( "An attempt was made to modify the level of a LevelGroupConfigurationSelectorItem that has already been added to a LevelGroupConfigurationSelector." ); - - m_level = value; - } - } - - private int m_level; - - #endregion - - #region GroupConfiguration Property - - public GroupConfiguration GroupConfiguration - { - get - { - return m_groupConfig; - } - set - { - m_groupConfig = value; - } - } - - private GroupConfiguration m_groupConfig; - - #endregion - - #region IsSealed Property - - private bool m_isSealed = false; - - public bool IsSealed - { - get - { - return m_isSealed; - } - } - - internal void Seal() - { - m_isSealed = true; - } - - #endregion - - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/LevelGroupConfigurationSelectorItemCollection.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/LevelGroupConfigurationSelectorItemCollection.cs deleted file mode 100644 index a50a0ba8..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/LevelGroupConfigurationSelectorItemCollection.cs +++ /dev/null @@ -1,70 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Collections.ObjectModel; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class LevelGroupConfigurationSelectorItemCollection : ObservableCollection - { - internal LevelGroupConfigurationSelectorItemCollection() - : base() - { - } - - public LevelGroupConfigurationSelectorItem GetGroupConfigurationSelectorItem( int level ) - { - LevelGroupConfigurationSelectorItem retval = null; - - foreach( LevelGroupConfigurationSelectorItem levelGroupConfig in this ) - { - if( levelGroupConfig.Level == level ) - { - retval = levelGroupConfig; - break; - } - } - - return retval; - } - - protected override void InsertItem( int index, LevelGroupConfigurationSelectorItem item ) - { - if( this.GetGroupConfigurationSelectorItem( item.Level ) != null ) - throw new InvalidOperationException( "An attempt was made to insert a LevelGroupConfigurationSelectorItem that specifies the same level as an existing LevelGroupConfigurationSelectorItem." ); - - base.InsertItem( index, item ); - - item.Seal(); - } - - protected override void SetItem( int index, LevelGroupConfigurationSelectorItem item ) - { - LevelGroupConfigurationSelectorItem oldLevelGroupConfig = this[ index ]; - LevelGroupConfigurationSelectorItem failingLevelGroupConfig = this.GetGroupConfigurationSelectorItem( item.Level ); - - if( ( failingLevelGroupConfig != null ) && ( oldLevelGroupConfig != failingLevelGroupConfig ) ) - throw new InvalidOperationException( "An attempt was made to set a LevelGroupConfigurationSelectorItem that specifies the same level as an existing LevelGroupConfigurationSelectorItem." ); - - base.SetItem( index, item ); - - item.Seal(); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/CellContentBindingExtension.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/CellContentBindingExtension.cs deleted file mode 100644 index ee6261ed..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/CellContentBindingExtension.cs +++ /dev/null @@ -1,174 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Windows.Markup; -using System.Windows.Data; -using System.Windows; -using System.Windows.Controls; -using System.Globalization; -using System.Collections.Specialized; -using System.ComponentModel; - -namespace Xceed.Wpf.DataGrid.Markup -{ - [MarkupExtensionReturnType( typeof( object ) )] - [Obsolete( "The CellContentBinding markup extension is obsolete and has been replaced by the CellContentPresenter class.", false )] - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - public class CellContentBindingExtension : MarkupExtension - { - public CellContentBindingExtension() - { - m_cellBinding.RelativeSource = new RelativeSource( RelativeSourceMode.TemplatedParent ); - m_cellBinding.Mode = BindingMode.OneWay; - m_cellBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged; - - m_cellBinding.Path = new PropertyPath( Cell.ContentProperty ); - } - - #region Converter Property - - public IValueConverter Converter - { - get - { - return m_cellBinding.Converter; - } - set - { - if( this.ConverterInitialized ) - throw new InvalidOperationException( "An attempt was made to set the Converter property when it has already been initialized." ); - - m_cellBinding.Converter = value; - this.ConverterInitialized = true; - } - } - - #endregion Converter Property - - #region ConverterParameter Property - - public object ConverterParameter - { - get - { - return m_cellBinding.ConverterParameter; - } - set - { - if( this.ConverterParameterInitialized ) - throw new InvalidOperationException( "An attempt was made to set the ConverterParameter property when it has already been initialized." ); - - m_cellBinding.ConverterParameter = value; - this.ConverterParameterInitialized = true; - } - } - - #endregion ConverterParameter Property - - #region ConverterCulture Property - - public CultureInfo ConverterCulture - { - get - { - return m_cellBinding.ConverterCulture; - } - set - { - if( this.ConverterCultureInitialized ) - throw new InvalidOperationException( "An attempt was made to set the ConverterCulture property when it has already been initialized." ); - - m_cellBinding.ConverterCulture = value; - this.ConverterCultureInitialized = true; - } - } - - #endregion ConverterCulture Property - - #region PUBLIC METHODS - - public sealed override object ProvideValue( IServiceProvider serviceProvider ) - { - return m_cellBinding.ProvideValue( serviceProvider ); - } - - #endregion PUBLIC METHODS - - #region PRIVATE PROPERTIES - - private bool ConverterCultureInitialized - { - get - { - return m_flags[ ( int )CellContentBindingExtensionFlags.ConverterCultureInitialized ]; - } - set - { - m_flags[ ( int )CellContentBindingExtensionFlags.ConverterCultureInitialized ] = value; - } - } - - - private bool ConverterInitialized - { - get - { - return m_flags[ ( int )CellContentBindingExtensionFlags.ConverterInitialized ]; - } - set - { - m_flags[ ( int )CellContentBindingExtensionFlags.ConverterInitialized ] = value; - } - } - - private bool ConverterParameterInitialized - { - get - { - return m_flags[ ( int )CellContentBindingExtensionFlags.ConverterParameterInitialized ]; - } - set - { - m_flags[ ( int )CellContentBindingExtensionFlags.ConverterParameterInitialized ] = value; - } - } - - #endregion PRIVATE PROPERTIES - - #region PRIVATE FIELDS - - private Binding m_cellBinding = new Binding(); - private BitVector32 m_flags = new BitVector32(); - - #endregion PRIVATE FIELDS - - #region NESTED CLASSES - - [Flags] - private enum CellContentBindingExtensionFlags - { - ConverterCultureInitialized = 1, - ConverterInitialized = 2, - ConverterParameterInitialized = 4 - } - - #endregion NESTED CLASSES - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/CellEditorBindingExtension.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/CellEditorBindingExtension.cs deleted file mode 100644 index 81e0e612..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/CellEditorBindingExtension.cs +++ /dev/null @@ -1,273 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Text; -using System.Windows.Markup; -using System.Windows.Data; -using System.Windows; -using System.Windows.Controls; - -using Xceed.Wpf.DataGrid.Converters; -using System.Collections.Specialized; - -namespace Xceed.Wpf.DataGrid.Markup -{ - [MarkupExtensionReturnType( typeof( object ) )] - public class CellEditorBindingExtension : MarkupExtension - { - public CellEditorBindingExtension() - { - m_cellBinding.RelativeSource = new RelativeSource( RelativeSourceMode.Self ); - m_cellBinding.Mode = BindingMode.TwoWay; - m_cellBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged; - m_cellBinding.Converter = new DefaultDataConverter(); - - m_cellBinding.Path = new PropertyPath( - "(0).(1)", - Cell.ParentCellProperty, Cell.ContentProperty ); - } - - #region Converter Property - - public IValueConverter Converter - { - get - { - return m_cellBinding.Converter; - } - set - { - if( this.ConverterInitialized ) - throw new InvalidOperationException( "An attempt was made to set the Converter property when it has already been initialized." ); - - m_cellBinding.Converter = value; - this.ConverterInitialized = true; - } - } - - #endregion Converter Property - - #region ConverterParameter Property - - public object ConverterParameter - { - get - { - return m_cellBinding.ConverterParameter; - } - set - { - if( this.ConverterParameterInitialized ) - throw new InvalidOperationException( "An attempt was made to set the ConverterParameter property when it has already been initialized." ); - - m_cellBinding.ConverterParameter = value; - this.ConverterParameterInitialized = true; - } - } - - #endregion ConverterParameter Property - - #region ConverterCulture Property - - public CultureInfo ConverterCulture - { - get - { - return m_cellBinding.ConverterCulture; - } - set - { - if( this.ConverterCultureInitialized ) - throw new InvalidOperationException( "An attempt was made to set the ConverterCulture property when it has already been initialized." ); - - m_cellBinding.ConverterCulture = value; - this.ConverterCultureInitialized = true; - } - } - - #endregion ConverterCulture Property - - #region NotifyOnSourceUpdated Property - - public bool NotifyOnSourceUpdated - { - get - { - return m_cellBinding.NotifyOnSourceUpdated; - } - set - { - if( this.NotifyOnSourceUpdatedInitialized ) - throw new InvalidOperationException( "An attempt was made to set the NotifyOnSourceUpdated property when it has already been initialized." ); - - m_cellBinding.NotifyOnSourceUpdated = value; - this.NotifyOnSourceUpdatedInitialized = true; - } - } - - #endregion NotifyOnSourceUpdated Property - - #region NotifyOnTargetUpdated Property - - public bool NotifyOnTargetUpdated - { - get - { - return m_cellBinding.NotifyOnTargetUpdated; - } - set - { - if( this.NotifyOnTargetUpdatedInitialized ) - throw new InvalidOperationException( "An attempt was made to set the NotifyOnTargetUpdated property when it has already been initialized." ); - - m_cellBinding.NotifyOnTargetUpdated = value; - this.NotifyOnTargetUpdatedInitialized = true; - } - } - - #endregion NotifyOnTargetUpdated Property - - #region NotifyOnValidationError Property - - public bool NotifyOnValidationError - { - get - { - return m_cellBinding.NotifyOnValidationError; - } - set - { - if( this.NotifyOnValidationErrorInitialized ) - throw new InvalidOperationException( "An attempt was made to set the NotifyOnValidationError property when it has already been initialized." ); - - m_cellBinding.NotifyOnValidationError = value; - this.NotifyOnValidationErrorInitialized = true; - } - } - - #endregion NotifyOnValidationError Property - - #region PUBLIC METHODS - - public sealed override object ProvideValue( IServiceProvider serviceProvider ) - { - return m_cellBinding.ProvideValue( serviceProvider ); - } - - #endregion PUBLIC METHODS - - #region PRIVATE PROPERTIES - - private bool ConverterInitialized - { - get - { - return m_flags[ ( int )CellEditorBindingExtensionFlags.ConverterInitialized ]; - } - set - { - m_flags[ ( int )CellEditorBindingExtensionFlags.ConverterInitialized ] = value; - } - } - - private bool ConverterParameterInitialized - { - get - { - return m_flags[ ( int )CellEditorBindingExtensionFlags.ConverterParameterInitialized ]; - } - set - { - m_flags[ ( int )CellEditorBindingExtensionFlags.ConverterParameterInitialized ] = value; - } - } - - private bool ConverterCultureInitialized - { - get - { - return m_flags[ ( int )CellEditorBindingExtensionFlags.ConverterCultureInitialized ]; - } - set - { - m_flags[ ( int )CellEditorBindingExtensionFlags.ConverterCultureInitialized ] = value; - } - } - - private bool NotifyOnSourceUpdatedInitialized - { - get - { - return m_flags[ ( int )CellEditorBindingExtensionFlags.NotifyOnSourceUpdatedInitialized ]; - } - set - { - m_flags[ ( int )CellEditorBindingExtensionFlags.NotifyOnSourceUpdatedInitialized ] = value; - } - } - - private bool NotifyOnTargetUpdatedInitialized - { - get - { - return m_flags[ ( int )CellEditorBindingExtensionFlags.NotifyOnTargetUpdatedInitialized ]; - } - set - { - m_flags[ ( int )CellEditorBindingExtensionFlags.NotifyOnTargetUpdatedInitialized ] = value; - } - } - - private bool NotifyOnValidationErrorInitialized - { - get - { - return m_flags[ ( int )CellEditorBindingExtensionFlags.NotifyOnValidationErrorInitialized ]; - } - set - { - m_flags[ ( int )CellEditorBindingExtensionFlags.NotifyOnValidationErrorInitialized ] = value; - } - } - - #endregion PRIVATE PROPERTIES - - #region PRIVATE FIELDS - - private Binding m_cellBinding = new Binding(); - private BitVector32 m_flags = new BitVector32(); - - #endregion PRIVATE FIELDS - - #region NESTED CLASSES - - [Flags] - private enum CellEditorBindingExtensionFlags - { - ConverterInitialized = 1, - ConverterParameterInitialized = 2, - ConverterCultureInitialized = 4, - NotifyOnSourceUpdatedInitialized = 8, - NotifyOnTargetUpdatedInitialized = 16, - NotifyOnValidationErrorInitialized = 32 - } - - #endregion NESTED CLASSES - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/ClearGroupLevelConfigurations.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/ClearGroupLevelConfigurations.cs deleted file mode 100644 index ab4ca7dc..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/ClearGroupLevelConfigurations.cs +++ /dev/null @@ -1,30 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using Xceed.Wpf.DataGrid.Views; -using System.ComponentModel; - -namespace Xceed.Wpf.DataGrid.Markup -{ - [EditorBrowsable( EditorBrowsableState.Never )] - [Obsolete( "The ClearGroupLevelConfigurations class is obsolete.", true )] - public sealed class ClearGroupLevelConfigurations : GroupLevelConfiguration - { - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/ClearHeadersFooters.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/ClearHeadersFooters.cs deleted file mode 100644 index 5b5d8911..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/ClearHeadersFooters.cs +++ /dev/null @@ -1,28 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; -using System.ComponentModel; - -namespace Xceed.Wpf.DataGrid.Markup -{ - [EditorBrowsable( EditorBrowsableState.Never)] - [Obsolete( "The ClearHeadersFooters class is obsolete and has been replaced by the ViewBase.UseDefaultHeadersFooters, GroupConfiguration.UseDefaultHeadersFooters, and DetailConfiguration.UseDefaultHeadersFooters properties.", true )] - public sealed class ClearHeadersFooters : DataTemplate - { - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/DataGridThemeResourceDictionary.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/DataGridThemeResourceDictionary.cs deleted file mode 100644 index 8afeb94e..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/DataGridThemeResourceDictionary.cs +++ /dev/null @@ -1,45 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; -using System.Threading; - -namespace Xceed.Wpf.DataGrid.Markup -{ - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - public sealed class DataGridThemeResourceDictionary : SharedThemeResourceDictionary - { - #region Static Fields - - private static Uri s_baseUri; //null - - #endregion - - protected override Uri GetBaseUri() - { - if( s_baseUri == null ) - { - var baseUri = this.CreateBaseUri( this.GetType().Assembly ); - - Interlocked.CompareExchange( ref s_baseUri, baseUri, null ); - } - - return s_baseUri; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/FrameworkThemeResourceDictionary.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/FrameworkThemeResourceDictionary.cs deleted file mode 100644 index d9654f82..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/FrameworkThemeResourceDictionary.cs +++ /dev/null @@ -1,31 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; - -namespace Xceed.Wpf.DataGrid.Markup -{ - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - public sealed class FrameworkThemeResourceDictionary : SharedThemeResourceDictionary - { - protected override Uri GetBaseUri() - { - return null; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/SharedResourceDictionary.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/SharedResourceDictionary.cs deleted file mode 100644 index 8dcb102f..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/SharedResourceDictionary.cs +++ /dev/null @@ -1,283 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics; -using System.Threading; -using System.Windows; -using System.Windows.Markup; - -namespace Xceed.Wpf.DataGrid.Markup -{ - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - public abstract class SharedResourceDictionary : ResourceDictionary - { - #region SharedDictionaries Private Static Property - - private static List> SharedDictionaries - { - get - { - if( s_sharedDictionaries == null ) - { - Interlocked.CompareExchange>>( ref s_sharedDictionaries, new List>(), null ); - } - - return s_sharedDictionaries; - } - } - - private static List> s_sharedDictionaries; //null - - #endregion - - #region Source Property - - public new Uri Source - { - get - { - if( m_sourceUri != null ) - return m_sourceUri; - - return base.Source; - } - set - { - Uri sourceUri; - if( !this.TryCreateAbsoluteUri( ( ( IUriContext )this ).BaseUri, value, out sourceUri ) - || ( sourceUri == null ) - || ( !sourceUri.IsAbsoluteUri ) ) - { - base.Source = value; - } - else - { - var dictionaries = SharedResourceDictionary.SharedDictionaries; - lock( ( ( ICollection )dictionaries ).SyncRoot ) - { - bool cleanUp; - ResourceDictionary dictionary; - - var index = SharedResourceDictionary.FindIndex( dictionaries, sourceUri, out cleanUp ); - if( index >= 0 ) - { - var container = dictionaries[ index ].Value; - if( container.Status == ResourceDictionaryStatus.NotSet ) - throw new InvalidOperationException( "A circular reference has been detected in a ResourceDictionary." ); - - dictionary = container.Target; - } - else - { - dictionary = null; - } - - m_sourceUri = value; - - if( dictionary != null ) - { - var mergedDictionaries = this.MergedDictionaries; - lock( ( ( ICollection )this ).SyncRoot ) - { - lock( ( ( ICollection )mergedDictionaries ).SyncRoot ) - { - mergedDictionaries.Add( dictionary ); - } - } - } - else - { - // We must add the entry in the collection before we actually load the ResourceDictionary because - // the ResourceDictionary may load other ResourceDictionary as well. Our insertion index may no longer - // be valid after the ResourceDictionary is loaded. - var container = new WeakResourceDictionary(); - var newEntry = new KeyValuePair( sourceUri, container ); - if( index >= 0 ) - { - dictionaries[ index ] = newEntry; - } - else - { - dictionaries.Insert( ~index, newEntry ); - } - - bool exceptionOccured = true; - - try - { - base.Source = sourceUri; - - exceptionOccured = false; - } - finally - { - if( exceptionOccured ) - { - dictionaries.Remove( newEntry ); - } - else - { - container.Target = this; - } - } - } - - if( cleanUp ) - { - for( int i = dictionaries.Count - 1; i >= 0; i-- ) - { - if( dictionaries[ i ].Value.Status != ResourceDictionaryStatus.GarbageCollected ) - continue; - - dictionaries.RemoveAt( i ); - } - } - } - } - } - } - - private Uri m_sourceUri; //null - - #endregion - - protected virtual bool TryCreateAbsoluteUri( Uri baseUri, Uri sourceUri, out Uri result ) - { - result = null; - - if( ( sourceUri == null ) || !sourceUri.IsAbsoluteUri ) - return false; - - if( string.Compare( sourceUri.Scheme, Uri.UriSchemeFile, StringComparison.OrdinalIgnoreCase ) != 0 ) - { - result = sourceUri; - } - else if( string.Compare( sourceUri.OriginalString, 0, Uri.UriSchemeFile, 0, Uri.UriSchemeFile.Length, StringComparison.OrdinalIgnoreCase ) == 0 ) - { - result = sourceUri; - } - else - { - result = new Uri( sourceUri.AbsoluteUri ); - } - - return true; - } - - private static int FindIndex( IList> collection, Uri sourceUri, out bool cleanUp ) - { - cleanUp = false; - - Debug.Assert( collection != null ); - Debug.Assert( sourceUri != null ); - - var lowerBound = 0; - var upperBound = collection.Count - 1; - - while( lowerBound <= upperBound ) - { - var middle = lowerBound + ( upperBound - lowerBound ) / 2; - var entry = collection[ middle ]; - var compare = Uri.Compare( entry.Key, sourceUri, UriComponents.AbsoluteUri, UriFormat.SafeUnescaped, StringComparison.InvariantCultureIgnoreCase ); - - cleanUp = cleanUp || ( entry.Value.Status == ResourceDictionaryStatus.GarbageCollected ); - - if( compare < 0 ) - { - if( middle == lowerBound ) - return ~middle; - - upperBound = middle - 1; - } - else if( compare > 0 ) - { - if( middle == upperBound ) - return ~( middle + 1 ); - - lowerBound = middle + 1; - } - else - { - return middle; - } - } - - return ~0; - } - - #region WeakResourceDictionary Private Class - - private sealed class WeakResourceDictionary - { - internal ResourceDictionary Target - { - get - { - var resource = m_resource; - if( resource == null ) - return null; - - return ( ResourceDictionary )resource.Target; - } - set - { - if( value == null ) - throw new ArgumentNullException( "value" ); - - if( m_resource != null ) - throw new InvalidOperationException( "The property can only be set once." ); - - m_resource = new WeakReference( value ); - } - } - - internal ResourceDictionaryStatus Status - { - get - { - var resource = m_resource; - if( resource == null ) - return ResourceDictionaryStatus.NotSet; - - if( resource.IsAlive ) - return ResourceDictionaryStatus.Alive; - - return ResourceDictionaryStatus.GarbageCollected; - } - } - - private WeakReference m_resource; //null - } - - #endregion - - #region ResourceDictionaryStatus Private Enum - - private enum ResourceDictionaryStatus - { - NotSet = 0, - Alive, - GarbageCollected - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/SharedThemeResourceDictionary.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/SharedThemeResourceDictionary.cs deleted file mode 100644 index 9892c773..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/SharedThemeResourceDictionary.cs +++ /dev/null @@ -1,416 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; -using System.Diagnostics; -using System.Reflection; -using System.Security; -using System.Text; - -namespace Xceed.Wpf.DataGrid.Markup -{ - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - public abstract class SharedThemeResourceDictionary : SharedResourceDictionary - { - #region Static Fields - - private const string UriSchemePack = "pack"; - private const string UriComponent = ";component"; - private const string UriAssemblyVersionSymbol = "V"; - private const string UriAssemblyInfoSeparator = ";"; - private const string UriPathSeparator = "/"; - - private const string AssemblyFullNameSeparator = ","; - private const string AssemblyFullNameVersionPrefix = "Version="; - private const string AssemblyFullNamePublicKeyTokenPrefix = "PublicKeyToken="; - - private static readonly Uri SchemePackBaseUri = new Uri( "pack://application:,,,/", UriKind.Absolute ); - - #endregion - - protected abstract Uri GetBaseUri(); - - protected sealed override bool TryCreateAbsoluteUri( Uri baseUri, Uri sourceUri, out Uri result ) - { - Uri packUri; - - if( sourceUri != null ) - { - if( SharedThemeResourceDictionary.TryConvertToPackUri( sourceUri, out packUri ) ) - { - sourceUri = packUri; - } - - UriDescription sourceUriDescription; - if( SharedThemeResourceDictionary.TryGetUriDescription( sourceUri, out sourceUriDescription ) ) - { - if( SharedThemeResourceDictionary.IsAssemblyInfoFilled( sourceUriDescription ) ) - { - result = SharedThemeResourceDictionary.CreateUri( sourceUriDescription ); - return true; - } - } - } - - if( SharedThemeResourceDictionary.TryConvertToPackUri( baseUri, out packUri ) ) - { - baseUri = packUri; - } - - var newBaseUri = this.GetBaseUri(); - if( newBaseUri != null ) - { - if( SharedThemeResourceDictionary.TryConvertToPackUri( newBaseUri, out packUri ) ) - { - newBaseUri = packUri; - } - - if( baseUri != null ) - { - Uri combinedUri; - if( SharedThemeResourceDictionary.TryCombineUri( newBaseUri, baseUri, out combinedUri ) ) - { - newBaseUri = combinedUri; - } - } - - if( sourceUri != null ) - return SharedThemeResourceDictionary.TryCombineUri( newBaseUri, sourceUri, out result ); - } - else - { - newBaseUri = baseUri; - } - - return base.TryCreateAbsoluteUri( newBaseUri, sourceUri, out result ); - } - - protected Uri CreateBaseUri( Assembly assembly ) - { - if( assembly == null ) - return null; - - try - { - return SharedThemeResourceDictionary.CreateBaseUriFromAssembly( assembly ); - } - catch( SecurityException ) - { - return SharedThemeResourceDictionary.CreateBaseUriFromAssemblyFullName( assembly ); - } - } - - private static Uri CreateBaseUriFromAssembly( Assembly assembly ) - { - Debug.Assert( assembly != null ); - - var assemblyInfo = assembly.GetName(); - var assemblyName = assemblyInfo.Name; - var assemblyVersion = SharedThemeResourceDictionary.GetAssemblyVersion( assemblyInfo.Version ); - var assemblyPublicKeyToken = SharedThemeResourceDictionary.GetAssemblyPublicKeyToken( assemblyInfo.GetPublicKeyToken() ); - - return SharedThemeResourceDictionary.CreateUri( assemblyName, assemblyVersion, assemblyPublicKeyToken, string.Empty ); - } - - private static Uri CreateBaseUriFromAssemblyFullName( Assembly assembly ) - { - Debug.Assert( assembly != null ); - - var fullName = assembly.FullName; - var assemblyName = SharedThemeResourceDictionary.GetAssemblyName( fullName ); - var assemblyVersion = SharedThemeResourceDictionary.GetAssemblyVersion( fullName ); - var assemblyPublicKeyToken = SharedThemeResourceDictionary.GetAssemblyPublicKeyToken( fullName ); - - return SharedThemeResourceDictionary.CreateUri( assemblyName, assemblyVersion, assemblyPublicKeyToken, string.Empty ); - } - - private static string GetAssemblyName( string fullName ) - { - if( fullName == null ) - return null; - - var length = fullName.IndexOf( SharedThemeResourceDictionary.AssemblyFullNameSeparator, StringComparison.InvariantCultureIgnoreCase ); - if( length <= 0 ) - return null; - - return fullName.Substring( 0, length ); - } - - private static string GetAssemblyVersion( Version version ) - { - if( version == null ) - return null; - - return SharedThemeResourceDictionary.UriAssemblyVersionSymbol + version.ToString(); - } - - private static string GetAssemblyVersion( string fullName ) - { - if( fullName == null ) - return null; - - var start = fullName.IndexOf( SharedThemeResourceDictionary.AssemblyFullNameVersionPrefix, StringComparison.InvariantCultureIgnoreCase ); - if( start < 0 ) - return null; - - start += SharedThemeResourceDictionary.AssemblyFullNameVersionPrefix.Length; - - var end = fullName.IndexOf( SharedThemeResourceDictionary.AssemblyFullNameSeparator, start, StringComparison.InvariantCultureIgnoreCase ); - var value = ( end > 0 ) - ? fullName.Substring( start, end - start ) - : fullName.Substring( start ); - - if( string.IsNullOrEmpty( value ) ) - return null; - - return SharedThemeResourceDictionary.UriAssemblyVersionSymbol + value; - } - - private static string GetAssemblyPublicKeyToken( byte[] publicKeyToken ) - { - if( publicKeyToken == null ) - return null; - - var sb = new StringBuilder(); - for( int i = 0; i < publicKeyToken.Length; i++ ) - { - sb.AppendFormat( "{0:x2}", publicKeyToken[ i ] ); - } - - return sb.ToString(); - } - - private static string GetAssemblyPublicKeyToken( string fullName ) - { - if( fullName == null ) - return null; - - var start = fullName.IndexOf( SharedThemeResourceDictionary.AssemblyFullNamePublicKeyTokenPrefix, StringComparison.InvariantCultureIgnoreCase ); - if( start < 0 ) - return null; - - start += SharedThemeResourceDictionary.AssemblyFullNamePublicKeyTokenPrefix.Length; - - var end = fullName.IndexOf( SharedThemeResourceDictionary.AssemblyFullNameSeparator, start, StringComparison.InvariantCultureIgnoreCase ); - var value = ( end > 0 ) - ? fullName.Substring( start, end - start ) - : fullName.Substring( start ); - - return value; - } - - private static string ParseAssemblyVersion( string version ) - { - var symbol = SharedThemeResourceDictionary.UriAssemblyVersionSymbol; - if( string.IsNullOrEmpty( version ) || !version.StartsWith( symbol, StringComparison.InvariantCultureIgnoreCase ) ) - return version; - - Version ver; - if( !Version.TryParse( version.Substring( symbol.Length ), out ver ) ) - return version; - - return SharedThemeResourceDictionary.GetAssemblyVersion( ver ); - } - - private static Uri CreateUri( UriDescription description ) - { - Debug.Assert( description != null ); - - return SharedThemeResourceDictionary.CreateUri( - description.AssemblyName, - description.AssemblyVersion, - description.AssemblyPublicKeyToken, - description.RelativePath ); - } - - private static Uri CreateUri( string assemblyName, string assemblyVersion, string assemblyPublicKeyToken, string relativePath ) - { - var sb = new StringBuilder( SharedThemeResourceDictionary.UriPathSeparator ); - - sb.Append( assemblyName ?? string.Empty ); - - sb.Append( SharedThemeResourceDictionary.UriAssemblyInfoSeparator ); - sb.Append( assemblyVersion ?? string.Empty ); - sb.Append( SharedThemeResourceDictionary.UriAssemblyInfoSeparator ); - sb.Append( assemblyPublicKeyToken ?? string.Empty ); - - sb.Append( SharedThemeResourceDictionary.UriComponent ); - - if( string.IsNullOrEmpty( relativePath ) || !relativePath.StartsWith( SharedThemeResourceDictionary.UriPathSeparator, StringComparison.InvariantCultureIgnoreCase ) ) - { - sb.Append( SharedThemeResourceDictionary.UriPathSeparator ); - } - - sb.Append( relativePath ?? string.Empty ); - - return new Uri( SharedThemeResourceDictionary.SchemePackBaseUri, sb.ToString() ); - } - - private static bool TryConvertToPackUri( Uri sourceUri, out Uri result ) - { - if( SharedThemeResourceDictionary.IsPackUri( sourceUri ) ) - { - result = new Uri( SharedThemeResourceDictionary.SchemePackBaseUri, sourceUri ); - } - else - { - result = null; - } - - return ( result != null ); - } - - private static bool IsPackUri( Uri sourceUri ) - { - if( sourceUri == null ) - return false; - - var path = sourceUri.ToString(); - - return ( path.IndexOf( SharedThemeResourceDictionary.UriComponent, StringComparison.InvariantCultureIgnoreCase ) >= 0 ); - } - - private static bool IsAssemblyInfoFilled( UriDescription description ) - { - if( string.IsNullOrEmpty( description.AssemblyName ) ) - return false; - - return !string.IsNullOrEmpty( description.AssemblyVersion ) - || !string.IsNullOrEmpty( description.AssemblyPublicKeyToken ); - } - - private static bool TryGetUriDescription( Uri uri, out UriDescription description ) - { - description = null; - if( ( uri == null ) || !uri.IsAbsoluteUri ) - return false; - - if( !string.Equals( uri.Scheme, SharedThemeResourceDictionary.UriSchemePack, StringComparison.InvariantCultureIgnoreCase ) ) - return false; - - var segments = uri.Segments; - if( ( segments == null ) || ( segments.Length < 2 ) ) - return false; - - var componentPart = segments[ 1 ]; - var index = componentPart.IndexOf( SharedThemeResourceDictionary.UriComponent, StringComparison.InvariantCultureIgnoreCase ); - if( index < 0 ) - return false; - - string assemblyName = null; - string assemblyVersion = null; - string assemblyPublicKeyToken = null; - - var assemblyInfo = componentPart.Substring( 0, index ); - if( assemblyInfo.Length > 0 ) - { - var assemblyParts = assemblyInfo.Split( new string[] { SharedThemeResourceDictionary.UriAssemblyInfoSeparator }, StringSplitOptions.None ); - Debug.Assert( assemblyParts.Length <= 3 ); - - assemblyName = ( assemblyParts.Length > 0 ) ? assemblyParts[ 0 ] : null; - assemblyVersion = ( assemblyParts.Length > 1 ) ? SharedThemeResourceDictionary.ParseAssemblyVersion( assemblyParts[ 1 ] ) : null; - assemblyPublicKeyToken = ( assemblyParts.Length > 2 ) ? assemblyParts[ 2 ] : null; - } - - string relativePath = null; - - if( segments.Length > 2 ) - { - var sb = new StringBuilder(); - for( int i = 2; i < segments.Length; i++ ) - { - sb.Append( segments[ i ] ); - } - - relativePath = sb.ToString(); - } - - description = new UriDescription( assemblyName, assemblyVersion, assemblyPublicKeyToken, relativePath ); - - return true; - } - - private static bool TryCombineUri( Uri baseUri, Uri relativeUri, out Uri result ) - { - result = null; - - Debug.Assert( ( baseUri != null ) && ( relativeUri != null ) ); - Debug.Assert( baseUri.IsAbsoluteUri ); - - UriDescription baseUriDescription; - if( !SharedThemeResourceDictionary.TryGetUriDescription( baseUri, out baseUriDescription ) ) - return false; - - UriDescription relativeUriDescription; - if( SharedThemeResourceDictionary.TryGetUriDescription( relativeUri, out relativeUriDescription ) ) - { - if( !string.IsNullOrEmpty( relativeUriDescription.AssemblyName ) && !string.Equals( relativeUriDescription.AssemblyName, baseUriDescription.AssemblyName, StringComparison.InvariantCultureIgnoreCase ) ) - return false; - } - else if( relativeUri.IsAbsoluteUri ) - { - return false; - } - else - { - relativeUriDescription = null; - } - - var baseUriPath = baseUriDescription.RelativePath; - var relativeUriPath = ( relativeUriDescription != null ) ? relativeUriDescription.RelativePath : Uri.EscapeUriString( relativeUri.ToString() ); - - if( relativeUriPath.StartsWith( SharedThemeResourceDictionary.UriPathSeparator, StringComparison.InvariantCultureIgnoreCase ) ) - { - baseUriPath = string.Empty; - relativeUriPath = relativeUriPath.Substring( SharedThemeResourceDictionary.UriPathSeparator.Length ); - } - - var assemblyDescription = ( ( relativeUriDescription != null ) && !SharedThemeResourceDictionary.IsAssemblyInfoFilled( baseUriDescription ) ) - ? relativeUriDescription - : baseUriDescription; - var newBaseUri = SharedThemeResourceDictionary.CreateUri( - assemblyDescription.AssemblyName, - assemblyDescription.AssemblyVersion, - assemblyDescription.AssemblyPublicKeyToken, - baseUriPath ); - var newRelativeUri = new Uri( relativeUriPath, UriKind.Relative ); - - return Uri.TryCreate( newBaseUri, newRelativeUri, out result ); - } - - #region UriDescription Private Class - - private sealed class UriDescription - { - internal UriDescription( string assemblyName, string assemblyVersion, string assemblyPublicKeyToken, string relativePath ) - { - this.AssemblyName = assemblyName ?? string.Empty; - this.AssemblyVersion = assemblyVersion ?? string.Empty; - this.AssemblyPublicKeyToken = assemblyPublicKeyToken ?? string.Empty; - this.RelativePath = relativePath ?? string.Empty; - } - - internal readonly string AssemblyName; - internal readonly string AssemblyVersion; - internal readonly string AssemblyPublicKeyToken; - internal readonly string RelativePath; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/ThemeConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/ThemeConverter.cs deleted file mode 100644 index c6e80087..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/ThemeConverter.cs +++ /dev/null @@ -1,113 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; -using Xceed.Wpf.DataGrid.Views; - -namespace Xceed.Wpf.DataGrid.Markup -{ - public class ThemeConverter : TypeConverter - { - public override bool CanConvertFrom( ITypeDescriptorContext context, Type sourceType ) - { - if( sourceType == typeof( string ) ) - return true; - - return base.CanConvertFrom( context, sourceType ); - } - - public override bool CanConvertTo( ITypeDescriptorContext context, Type destinationType ) - { - // We support conversion from string but we don't want to convert back to string. - // Otherwise, the DataGrid designer would persist in XAML using the attribute - // syntax which would fail for ThemePack themes. - if( destinationType == typeof( string ) ) - return false; - - return base.CanConvertTo( context, destinationType ); - } - - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1807:AvoidUnnecessaryStringCreation", MessageId = "stringValue" ), System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1807:AvoidUnnecessaryStringCreation", MessageId = "value" )] - public override object ConvertFrom( ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value ) - { - string stringValue = value as string; - - if( stringValue != null ) - { - string themeName = stringValue.ToLowerInvariant(); - Theme theme = null; - - switch( themeName ) - { - case "classic.systemcolor": - case "classicsystemcolortheme": - theme = s_classicSystemColorTheme; - break; - case "luna.normalcolor": - case "lunanormalcolortheme": - theme = s_lunaNormalColorTheme; - break; - case "luna.homestead": - case "lunahomesteadtheme": - theme = s_lunaHomesteadTheme; - break; - case "luna.metallic": - case "lunametallictheme": - theme = s_lunaMetallicTheme; - break; - case "aero.normalcolor": - case "aeronormalcolortheme": - theme = s_aeroNormalColorTheme; - break; - case "royale.normalcolor": - case "royalenormalcolortheme": - theme = s_royaleNormalColorTheme; - break; - case "zune.normalcolor": - case "zunenormalcolortheme": - theme = s_zuneNormalColorTheme; - break; - case "windows7": - case "windows7theme": - theme = s_windows7Theme; - break; - case "aero2.normalcolor": - case "aero2normalcolortheme": - theme = s_aero2NormalColorTheme; - break; - } - - if( theme == null ) - throw new ArgumentException( "The specified theme is invalid.", "value" ); - - return theme; - } - - return base.ConvertFrom( context, culture, value ); - } - - private static readonly Theme s_classicSystemColorTheme = new ClassicSystemColorTheme(); - private static readonly Theme s_lunaNormalColorTheme = new LunaNormalColorTheme(); - private static readonly Theme s_lunaHomesteadTheme = new LunaHomesteadTheme(); - private static readonly Theme s_lunaMetallicTheme = new LunaMetallicTheme(); - private static readonly Theme s_aeroNormalColorTheme = new AeroNormalColorTheme(); - private static readonly Theme s_royaleNormalColorTheme = new RoyaleNormalColorTheme(); - private static readonly Theme s_zuneNormalColorTheme = new ZuneNormalColorTheme(); - private static readonly Theme s_windows7Theme = new Windows7Theme(); - private static readonly Theme s_aero2NormalColorTheme = new Windows8Theme(); - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/ThemeKey.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/ThemeKey.cs deleted file mode 100644 index f2614724..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/ThemeKey.cs +++ /dev/null @@ -1,187 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; -using System.Reflection; -using System.Windows; -using System.Windows.Markup; -using System.Windows.Media; -using Xceed.Wpf.DataGrid.Views; - -namespace Xceed.Wpf.DataGrid.Markup -{ - [MarkupExtensionReturnType( typeof( ThemeKey ) )] - public class ThemeKey : ResourceKey - { - - public ThemeKey() - { - } - - public ThemeKey( Type targetViewType, Type themeType, Type targetElementType ) - { - if( targetViewType == null ) - throw new ArgumentNullException( "targetViewType" ); - - if( !typeof( ViewBase ).IsAssignableFrom( targetViewType ) ) - throw new ArgumentException( "The specified view type must derive from ViewBase.", "targetViewType" ); - - m_targetViewType = targetViewType; - m_targetViewTypeInitialized = true; - m_themeType = themeType; - m_themeTypeInitialized = true; - m_targetElementType = targetElementType; - m_targetElementTypeInitialized = true; - } - - public ThemeKey( Type targetViewType, Type targetElementType ) - : this( targetViewType, null, targetElementType ) - { - } - - #region TargetViewType Property - - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly" )] - public Type TargetViewType - { - get - { - return m_targetViewType; - } - set - { - if( value == null ) - throw new ArgumentNullException( "TargetViewType" ); - - if( !typeof( ViewBase ).IsAssignableFrom( value ) ) - throw new ArgumentException( "The specified view type must derive from ViewBase.", "TargetViewType" ); - - if( m_targetViewTypeInitialized ) - throw new InvalidOperationException( "An attempt was made to set the TargetViewType property when it has already been initialized." ); - - m_targetViewType = value; - m_targetViewTypeInitialized = true; - } - } - - private Type m_targetViewType; // = null; - private bool m_targetViewTypeInitialized; // = false; - - #endregion TargetViewType Property - - #region ThemeType Property - - public Type ThemeType - { - get - { - return m_themeType; - } - set - { - if( m_themeTypeInitialized ) - throw new InvalidOperationException( "An attempt was made to set the ThemeType property when it has already been initialized." ); - - m_themeType = value; - m_themeTypeInitialized = true; - } - } - - private Type m_themeType; // = null; - private bool m_themeTypeInitialized; // = false; - - #endregion ThemeType Property - - #region TargetElementType Property - - public Type TargetElementType - { - get - { - return m_targetElementType; - } - set - { - if( m_targetElementTypeInitialized ) - throw new InvalidOperationException( "An attempt was made to set the TargetElementType property when it has already been initialized." ); - - m_targetElementType = value; - m_targetElementTypeInitialized = true; - } - } - - private Type m_targetElementType; // = null; - private bool m_targetElementTypeInitialized; // = false; - - #endregion TargetElementType Property - - public override Assembly Assembly - { - get - { - if( m_themeType != null ) - return m_themeType.Assembly; - - if( m_targetViewType != null ) - return m_targetViewType.Assembly; - - return null; - } - } - - public override bool Equals( object obj ) - { - if( object.ReferenceEquals( obj, this ) ) - return true; - - var key = obj as ThemeKey; - if( object.ReferenceEquals( key, null ) ) - return false; - - return ( object.Equals( key.TargetViewType, this.TargetViewType ) ) - && ( object.Equals( key.ThemeType, this.ThemeType ) ) - && ( object.Equals( key.TargetElementType, this.TargetElementType ) ); - } - - public override int GetHashCode() - { - var hashCode = 0; - - var elementType = this.TargetElementType; - if( elementType != null ) - { - hashCode += elementType.GetHashCode(); - } - - var viewType = this.TargetViewType; - if( viewType != null ) - { - hashCode *= 11; - hashCode += viewType.GetHashCode(); - } - - var themeType = this.ThemeType; - if( themeType != null ) - { - hashCode *= 17; - hashCode += themeType.GetHashCode(); - } - - return hashCode; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/ViewBindingExtension.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/ViewBindingExtension.cs deleted file mode 100644 index c3fc6891..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/ViewBindingExtension.cs +++ /dev/null @@ -1,243 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Windows.Data; -using System.Windows.Markup; -using System.Windows; -using System.Globalization; -using System.Collections.Specialized; - -namespace Xceed.Wpf.DataGrid.Markup -{ - [MarkupExtensionReturnType( typeof( Binding ) )] - public class ViewBindingExtension : MarkupExtension - { - public ViewBindingExtension() : base() - { - } - - public ViewBindingExtension( string path ) : base() - { - if( path == null ) - throw new ArgumentNullException( "path" ); - - m_path = path; - } - - #region Path Property - - private string m_path; // = null; - - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly" )] - public string Path - { - get - { - return m_path; - } - set - { - if( value == null ) - throw new ArgumentNullException( "Path" ); - - if( m_path != null ) - throw new InvalidOperationException( "An attempt was made to set the Path property when it has already been initialized.s" ); - - m_path = value; - } - } - - #endregion Path Property - - #region Mode Property - - private BindingMode m_bindingMode = BindingMode.OneWay; - - public BindingMode Mode - { - get - { - return m_bindingMode; - } - set - { - m_bindingMode = value; - } - } - - #endregion Mode Property - - #region Converter Property - - private IValueConverter m_converter; // = null; - - public IValueConverter Converter - { - get - { - return m_converter; - } - set - { - if( this.ConverterInitialized ) - throw new InvalidOperationException( "An attempt was made to set the Converter property when it has already been initialized." ); - - m_converter = value; - this.ConverterInitialized = true; - } - } - - #endregion Converter Property - - #region ConverterParameter Property - - private object m_converterParameter; // = null; - - public object ConverterParameter - { - get - { - return m_converterParameter; - } - set - { - if( this.ConverterParameterInitialized ) - throw new InvalidOperationException( "An attempt was made to set the ConverterParameter property when it has already been initialized." ); - - m_converterParameter = value; - this.ConverterParameterInitialized = true; - } - } - - #endregion ConverterParameter Property - - #region ConverterCulture Property - - private CultureInfo m_converterCulture; // = null; - - public CultureInfo ConverterCulture - { - get - { - return m_converterCulture; - } - set - { - if( this.ConverterCultureInitialized ) - throw new InvalidOperationException( "An attempt was made to set the ConverterCulture property when it has already been initialized." ); - - m_converterCulture = value; - this.ConverterCultureInitialized = true; - } - } - - #endregion ConverterCulture Property - - #region PUBLIC METHODS - - public override object ProvideValue( IServiceProvider serviceProvider ) - { - return this.CreateBinding(); - } - - #endregion PUBLIC METHODS - - #region PRIVATE METHODS - - private Binding CreateBinding() - { - if( m_path == null ) - throw new InvalidOperationException( "An attempt was made to create a binding without a Path." ); - - Binding binding; - - binding = new Binding(); - binding.Path = new PropertyPath( "(0)." + m_path, DataGridControl.DataGridContextProperty ); - binding.RelativeSource = new RelativeSource( RelativeSourceMode.Self ); - - binding.Mode = m_bindingMode; - binding.Converter = m_converter; - binding.ConverterParameter = m_converterParameter; - binding.ConverterCulture = m_converterCulture; - - return binding; - } - - #endregion PRIVATE METHODS - - #region PRIVATE PROPERTIES - - private bool ConverterCultureInitialized - { - get - { - return m_flags[ ( int )ViewBindingExtensionFlags.ConverterCultureInitialized ]; - } - set - { - m_flags[ ( int )ViewBindingExtensionFlags.ConverterCultureInitialized ] = value; - } - } - - - private bool ConverterInitialized - { - get - { - return m_flags[ ( int )ViewBindingExtensionFlags.ConverterInitialized ]; - } - set - { - m_flags[ ( int )ViewBindingExtensionFlags.ConverterInitialized ] = value; - } - } - - private bool ConverterParameterInitialized - { - get - { - return m_flags[ ( int )ViewBindingExtensionFlags.ConverterParameterInitialized ]; - } - set - { - m_flags[ ( int )ViewBindingExtensionFlags.ConverterParameterInitialized ] = value; - } - } - - #endregion PRIVATE PROPERTIES - - #region PRIVATE FIELDS - - private BitVector32 m_flags = new BitVector32(); - - #endregion PRIVATE FIELDS - - #region NESTED CLASSES - - [Flags] - private enum ViewBindingExtensionFlags - { - ConverterCultureInitialized = 1, - ConverterInitialized = 2, - ConverterParameterInitialized = 4 - } - - #endregion NESTED CLASSES - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/ViewConverter.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/ViewConverter.cs deleted file mode 100644 index 257ea898..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Markup/ViewConverter.cs +++ /dev/null @@ -1,103 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; -using System.Globalization; -using Xceed.Wpf.DataGrid.Views; - -namespace Xceed.Wpf.DataGrid.Markup -{ - public class ViewConverter : TypeConverter - { - public override bool CanConvertFrom( ITypeDescriptorContext context, Type sourceType ) - { - if( sourceType == typeof( string ) ) - return true; - - return base.CanConvertFrom( context, sourceType ); - } - - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1807:AvoidUnnecessaryStringCreation", MessageId = "viewName" )] - public override object ConvertFrom( ITypeDescriptorContext context, CultureInfo culture, object value ) - { - string stringValue = value as string; - - if( stringValue != null ) - { - ViewBase toReturn = null; - - string completeName = stringValue; - int pointIndex = completeName.IndexOf( "." ); - string viewName = string.Empty; - string themeName = string.Empty; - - if(pointIndex != -1) - { - viewName = completeName.Substring( 0, pointIndex ); - themeName = completeName.Substring( pointIndex + 1 ); - } - else - { - viewName = completeName; - } - - viewName = viewName.ToLowerInvariant(); - - switch( viewName ) - { - case "tableview": - toReturn = new TableView(); - break; - case "tableflowview": - toReturn = new TableflowView(); - break; - } - - if( toReturn == null ) - { - throw new ArgumentException( "The specified view is invalid.", "value" ); - } - else - { - if( !string.IsNullOrEmpty( themeName ) ) - { - ThemeConverter themeConverter = new ThemeConverter(); - toReturn.Theme = (Theme)themeConverter.ConvertFromString(themeName); - } - } - - return toReturn; - } - - return base.ConvertFrom( context, culture, value ); - } - - public override object ConvertTo( ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType ) - { - if( ( destinationType != null ) && ( value is ViewBase ) ) - { - if( destinationType == typeof( string ) ) - { - return value.GetType().Name; - } - } - - return base.ConvertTo( context, culture, value, destinationType ); - } - - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/NoDrop.cur b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/NoDrop.cur deleted file mode 100644 index 7df3b590..00000000 Binary files a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/NoDrop.cur and /dev/null differ diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ObjectComparer.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ObjectComparer.cs deleted file mode 100644 index 60a5c8af..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ObjectComparer.cs +++ /dev/null @@ -1,73 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Collections; - -namespace Xceed.Wpf.DataGrid -{ - internal class ObjectComparer : IComparer - { - private ObjectComparer() - { - } - - #region Singleton Property - - public static ObjectComparer Singleton - { - get - { - if( _singleton == null ) - _singleton = new ObjectComparer(); - - return _singleton; - } - } - - private static ObjectComparer _singleton; - - #endregion Singleton Property - - public int Compare( object xData, object yData ) - { - // Code in there should be indentical to ObjectDataStore.CompareData - - if( ( xData == null ) || ( xData == DBNull.Value ) ) - { - if( ( yData != null ) && ( yData != DBNull.Value ) ) - { - return -1; - } - } - else - { - if( ( yData == null ) || ( yData == DBNull.Value ) ) - return 1; - - IComparable xDataComparer = xData as IComparable; - - if( xDataComparer != null ) - return xDataComparer.CompareTo( yData ); - } - - return 0; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ObservableColumnCollection.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ObservableColumnCollection.cs deleted file mode 100644 index 72d9cb18..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ObservableColumnCollection.cs +++ /dev/null @@ -1,311 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Diagnostics; -using Xceed.Utils.Wpf; - -namespace Xceed.Wpf.DataGrid -{ - public class ObservableColumnCollection : ObservableCollection - { - #region [] Property - - public ColumnBase this[ string fieldName ] - { - get - { - if( fieldName != null ) - { - ColumnBase value; - if( m_fieldNameToColumn.TryGetValue( fieldName, out value ) ) - return value; - } - - return null; - } - } - - #endregion - - #region SyncRoot Private Property - - private object SyncRoot - { - get - { - return ( ( ICollection )this ).SyncRoot; - } - } - - #endregion - - // This method has better performance than the one on the base class. - public new bool Contains( ColumnBase item ) - { - if( item == null ) - return false; - - return object.ReferenceEquals( item, this[ item.FieldName ] ); - } - - protected virtual void OnItemAdding( ColumnBase item ) - { - } - - protected virtual void OnItemAdded( ColumnBase item ) - { - } - - protected virtual void OnItemRemoving( ColumnBase item ) - { - } - - protected virtual void OnItemRemoved( ColumnBase item ) - { - } - - protected override void RemoveItem( int index ) - { - var item = this[ index ]; - Debug.Assert( item != null ); - - this.OnItemRemovingCore( item ); - - base.RemoveItem( index ); - - this.OnItemRemovedCore( item ); - } - - protected override void InsertItem( int index, ColumnBase item ) - { - if( item == null ) - throw new ArgumentNullException( "item" ); - - var fieldName = item.FieldName; - if( string.IsNullOrEmpty( fieldName ) ) - throw new ArgumentException( "A column must have a fieldname.", "item" ); - - if( m_fieldNameToColumn.ContainsKey( fieldName ) ) - throw new DataGridException( "A column with same field name already exists in collection." ); - - this.OnItemAddingCore( item ); - - base.InsertItem( index, item ); - - this.OnItemAddedCore( item ); - } - - protected override void ClearItems() - { - var items = new List( this ); - - foreach( var item in items ) - { - this.OnItemRemovingCore( item ); - } - - Debug.Assert( m_fieldNameToColumn.Count == 0 ); - m_fieldNameToColumn.Clear(); - - base.ClearItems(); - - foreach( var item in items ) - { - this.OnItemRemovedCore( item ); - } - } - - protected override void SetItem( int index, ColumnBase item ) - { - if( item == null ) - throw new ArgumentNullException( "item" ); - - var fieldName = item.FieldName; - if( string.IsNullOrEmpty( fieldName ) ) - throw new ArgumentException( "A column must have a fieldname.", "item" ); - - var oldItem = this[ index ]; - Debug.Assert( oldItem != null ); - - if( oldItem.FieldName != fieldName ) - { - if( m_fieldNameToColumn.ContainsKey( fieldName ) ) - throw new DataGridException( "A column with same field name already exists in collection." ); - } - - this.OnItemRemovingCore( oldItem ); - this.OnItemAddingCore( item ); - - base.SetItem( index, item ); - - this.OnItemRemovedCore( oldItem ); - this.OnItemAddedCore( item ); - } - - protected override void OnPropertyChanged( PropertyChangedEventArgs e ) - { - lock( this.SyncRoot ) - { - if( m_deferCount != 0 ) - { - if( m_deferPropertyChangedEventArgs == null ) - { - m_deferPropertyChangedEventArgs = e; - } - else if( !string.IsNullOrEmpty( m_deferPropertyChangedEventArgs.PropertyName ) && !object.Equals( m_deferPropertyChangedEventArgs.PropertyName, e.PropertyName ) ) - { - m_deferPropertyChangedEventArgs = new PropertyChangedEventArgs( string.Empty ); - } - - return; - } - } - - base.OnPropertyChanged( e ); - } - - protected override void OnCollectionChanged( NotifyCollectionChangedEventArgs e ) - { - lock( this.SyncRoot ) - { - if( m_deferCount != 0 ) - { - if( m_deferCollectionChangedEventArgs == null ) - { - m_deferCollectionChangedEventArgs = e; - } - else if( m_deferCollectionChangedEventArgs.Action != NotifyCollectionChangedAction.Reset ) - { - m_deferCollectionChangedEventArgs = new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Reset ); - } - - return; - } - } - - base.OnCollectionChanged( e ); - } - - internal IDisposable DeferNotifications() - { - return new DeferredDisposable( new DeferState( this ) ); - } - - private void OnItemAddingCore( ColumnBase item ) - { - m_fieldNameToColumn.Add( item.FieldName, item ); - - this.OnItemAdding( item ); - } - - private void OnItemAddedCore( ColumnBase item ) - { - this.OnItemAdded( item ); - } - - private void OnItemRemovingCore( ColumnBase item ) - { - var fieldName = item.FieldName; - - this.OnItemRemoving( item ); - - m_fieldNameToColumn.Remove( fieldName ); - } - - private void OnItemRemovedCore( ColumnBase item ) - { - this.OnItemRemoved( item ); - } - - private int m_deferCount; //0 - private PropertyChangedEventArgs m_deferPropertyChangedEventArgs; //null - private NotifyCollectionChangedEventArgs m_deferCollectionChangedEventArgs; //null - - private readonly Dictionary m_fieldNameToColumn = new Dictionary(); - - #region DeferState Private Class - - private sealed class DeferState : DeferredDisposableState - { - internal DeferState( ObservableColumnCollection target ) - { - Debug.Assert( target != null ); - m_target = target; - } - - protected override object SyncRoot - { - get - { - return m_target.SyncRoot; - } - } - - protected override bool IsDeferred - { - get - { - return ( m_target.m_deferCount != 0 ); - } - } - - protected override void Increment() - { - m_target.m_deferCount++; - } - - protected override void Decrement() - { - m_target.m_deferCount--; - } - - protected override void OnDeferEnding( bool disposing ) - { - m_propertyChangedEventArgs = m_target.m_deferPropertyChangedEventArgs; - m_collectionChangedEventArgs = m_target.m_deferCollectionChangedEventArgs; - m_target.m_deferPropertyChangedEventArgs = null; - m_target.m_deferCollectionChangedEventArgs = null; - - base.OnDeferEnding( disposing ); - } - - protected override void OnDeferEnded( bool disposing ) - { - if( m_collectionChangedEventArgs != null ) - { - m_target.OnCollectionChanged( m_collectionChangedEventArgs ); - } - - if( m_propertyChangedEventArgs != null ) - { - m_target.OnPropertyChanged( m_propertyChangedEventArgs ); - } - } - - private readonly ObservableColumnCollection m_target; - private PropertyChangedEventArgs m_propertyChangedEventArgs; - private NotifyCollectionChangedEventArgs m_collectionChangedEventArgs; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Properties/AssemblyInfo.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Properties/AssemblyInfo.cs deleted file mode 100644 index f32c0d00..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,78 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -#region Using directives - -using System; -using System.Globalization; -using System.Reflection; -using System.Resources; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Security; -using System.Windows; -using System.Windows.Markup; - -#endregion - -// 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( "Xceed Toolkit for WPF - DataGrid" )] -[assembly: AssemblyDescription( "This assembly implements the Xceed.Wpf.DataGrid namespace, a data grid control for the Windows Presentation Framework." )] - -[assembly: AssemblyCompany( "Xceed Software Inc." )] -[assembly: AssemblyProduct( "Xceed Toolkit for WPF - DataGrid" )] -[assembly: AssemblyCopyright( "Copyright (C) Xceed Software Inc. 2007-2017" )] - - -[assembly: CLSCompliant( true )] -[assembly: ComVisible( false )] - -[assembly: XmlnsPrefix( "http://schemas.xceed.com/wpf/xaml/datagrid", "xcdg" )] -[assembly: XmlnsDefinition( "http://schemas.xceed.com/wpf/xaml/datagrid", "Xceed.Wpf.DataGrid")] -[assembly: XmlnsDefinition( "http://schemas.xceed.com/wpf/xaml/datagrid", "Xceed.Wpf.DataGrid.Converters")] -[assembly: XmlnsDefinition( "http://schemas.xceed.com/wpf/xaml/datagrid", "Xceed.Wpf.DataGrid.Markup")] -[assembly: XmlnsDefinition( "http://schemas.xceed.com/wpf/xaml/datagrid", "Xceed.Wpf.DataGrid.Views")] -[assembly: XmlnsDefinition( "http://schemas.xceed.com/wpf/xaml/datagrid", "Xceed.Wpf.DataGrid.ValidationRules")] - - -[assembly: SecurityRules( SecurityRuleSet.Level1 )] -[assembly: AllowPartiallyTrustedCallers] - -//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.SourceAssembly, //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) -)] - -#pragma warning disable 1699 -[assembly: AssemblyDelaySign( false )] -[assembly: AssemblyKeyFile( @"..\..\sn.snk" )] -[assembly: AssemblyKeyName( "" )] -#pragma warning restore 1699 diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/PropertyDescription.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/PropertyDescription.cs deleted file mode 100644 index 90fe3db8..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/PropertyDescription.cs +++ /dev/null @@ -1,139 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; - -namespace Xceed.Wpf.DataGrid -{ - internal abstract class PropertyDescription - { - internal abstract string Name - { - get; - } - - internal virtual string DisplayName - { - get - { - return this.Name; - } - } - - internal abstract Type DataType - { - get; - } - - internal virtual string Path - { - get - { - return null; - } - } - - internal virtual string XPath - { - get - { - return null; - } - } - - internal virtual PropertyDescriptor PropertyDescriptor - { - get - { - return null; - } - } - - internal virtual DataGridForeignKeyDescription ForeignKeyDescription - { - get - { - return null; - } - } - - internal virtual bool IsReadOnly - { - get - { - return true; - } - } - - internal virtual bool OverrideReadOnlyForInsertion - { - get - { - return false; - } - } - - internal virtual bool SupportDBNull - { - get - { - return false; - } - } - - internal virtual bool IsBrowsable - { - get - { - return true; - } - } - - internal virtual bool IsDisplayable - { - get - { - return false; - } - } - - internal virtual bool IsSubRelationship - { - get - { - return false; - } - } - - internal virtual bool IsDataGridUnboundItemProperty - { - get - { - return false; - } - } - - internal virtual PropertyRouteSegment ToPropertyRouteSegment() - { - var route = PropertyRouteParser.Parse( this.Name ); - if( ( route == null ) || ( route.Parent != null ) ) - return new PropertyRouteSegment( PropertyRouteSegmentType.Property, this.Name ); - - return route.Current; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/PropertyDescriptionRoute.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/PropertyDescriptionRoute.cs deleted file mode 100644 index 5549d486..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/PropertyDescriptionRoute.cs +++ /dev/null @@ -1,91 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class PropertyDescriptionRoute - { - internal PropertyDescriptionRoute( PropertyDescription description ) - : this( description, null ) - { - } - - private PropertyDescriptionRoute( PropertyDescription description, PropertyDescriptionRoute parent ) - { - if( description == null ) - throw new ArgumentNullException( "description" ); - - m_description = description; - m_parent = parent; - } - - #region Current Property - - internal PropertyDescription Current - { - get - { - return m_description; - } - } - - private readonly PropertyDescription m_description; - - #endregion - - #region Parent Property - - internal PropertyDescriptionRoute Parent - { - get - { - return m_parent; - } - } - - private readonly PropertyDescriptionRoute m_parent; - - #endregion - - internal static PropertyDescriptionRoute Combine( PropertyDescription description, PropertyDescriptionRoute ancestors ) - { - return new PropertyDescriptionRoute( description, ancestors ); - } - - internal static PropertyDescriptionRoute Combine( PropertyDescriptionRoute descendants, PropertyDescription description ) - { - if( description == null ) - return descendants; - - return PropertyDescriptionRoute.Combine( descendants, new PropertyDescriptionRoute( description ) ); - } - - internal static PropertyDescriptionRoute Combine( PropertyDescriptionRoute descendants, PropertyDescriptionRoute ancestors ) - { - if( ancestors == null ) - return descendants; - - if( descendants == null ) - return ancestors; - - return PropertyDescriptionRoute.Combine( - descendants.Current, - PropertyDescriptionRoute.Combine( descendants.Parent, ancestors ) ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/PropertyDescriptionRouteDictionary.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/PropertyDescriptionRouteDictionary.cs deleted file mode 100644 index b305c627..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/PropertyDescriptionRouteDictionary.cs +++ /dev/null @@ -1,109 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class PropertyDescriptionRouteDictionary - { - internal PropertyDescriptionRoute this[ PropertyRoute key ] - { - get - { - PropertyDescriptionRoute value; - - if( this.TryGetValue( key, out value ) ) - return value; - - return null; - } - } - - internal ICollection Values - { - get - { - return m_collection.Values; - } - } - - internal void Clear() - { - m_collection.Clear(); - } - - internal void Add( PropertyDescriptionRoute value, bool overwrite ) - { - PropertyDescriptionRouteDictionary.EnsureValue( value ); - - var key = PropertyRouteBuilder.ToPropertyRoute( value ); - - this.Add( key, value, overwrite ); - } - - internal void Add( PropertyRoute key, PropertyDescriptionRoute value, bool overwrite ) - { - PropertyDescriptionRouteDictionary.EnsureKey( key ); - PropertyDescriptionRouteDictionary.EnsureValue( value ); - - if( overwrite ) - { - m_collection[ key ] = value; - } - else - { - m_collection.Add( key, value ); - } - } - - internal void Remove( PropertyRoute key ) - { - PropertyDescriptionRouteDictionary.EnsureKey( key ); - - m_collection.Remove( key ); - } - - internal bool Contains( PropertyRoute key ) - { - PropertyDescriptionRoute unused; - - return this.TryGetValue( key, out unused ); - } - - internal bool TryGetValue( PropertyRoute key, out PropertyDescriptionRoute value ) - { - PropertyDescriptionRouteDictionary.EnsureKey( key ); - - return m_collection.TryGetValue( key, out value ); - } - - private static void EnsureKey( PropertyRoute key ) - { - if( key == null ) - throw new ArgumentNullException( "key" ); - } - - private static void EnsureValue( PropertyDescriptionRoute value ) - { - if( value == null ) - throw new ArgumentNullException( "value" ); - } - - private readonly Dictionary m_collection = new Dictionary(); - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/PropertyRoute.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/PropertyRoute.cs deleted file mode 100644 index f225c51b..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/PropertyRoute.cs +++ /dev/null @@ -1,125 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Diagnostics; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class PropertyRoute - { - internal PropertyRoute( PropertyRouteSegment segment ) - : this( segment, null ) - { - } - - private PropertyRoute( PropertyRouteSegment segment, PropertyRoute parent ) - { - m_current = segment; - m_parent = parent; - } - - #region Current Property - - internal PropertyRouteSegment Current - { - get - { - return m_current; - } - } - - private readonly PropertyRouteSegment m_current; - - #endregion - - #region Parent Property - - internal PropertyRoute Parent - { - get - { - return m_parent; - } - } - - private readonly PropertyRoute m_parent; - - #endregion - - public static bool operator ==( PropertyRoute x, PropertyRoute y ) - { - if( object.ReferenceEquals( x, y ) ) - return true; - - if( object.ReferenceEquals( x, null ) || object.ReferenceEquals( y, null ) ) - return false; - - return ( PropertyRouteSegment.Equals( x.m_current, y.m_current ) ) - && ( x.m_parent == y.m_parent ); - } - - public static bool operator !=( PropertyRoute x, PropertyRoute y ) - { - return !( x == y ); - } - - public override int GetHashCode() - { - return m_current.GetHashCode(); - } - - public override bool Equals( object obj ) - { - var target = obj as PropertyRoute; - if( object.ReferenceEquals( target, null ) ) - return false; - - return ( target == this ); - } - - internal static PropertyRoute Combine( PropertyRouteSegment segment, PropertyRoute ancestors ) - { - if( ancestors == null ) - return new PropertyRoute( segment ); - - if( ancestors.Current.Type != PropertyRouteSegmentType.Other ) - return new PropertyRoute( segment, ancestors ); - - var path = PropertyRouteParser.Parse( new PropertyRoute( segment, new PropertyRoute( ancestors.Current ) ) ); - Debug.Assert( !string.IsNullOrEmpty( path ) ); - - return new PropertyRoute( new PropertyRouteSegment( PropertyRouteSegmentType.Other, path ), ancestors.Parent ); - } - - internal static PropertyRoute Combine( PropertyRoute descendants, PropertyRouteSegment segment ) - { - return PropertyRoute.Combine( descendants, new PropertyRoute( segment ) ); - } - - internal static PropertyRoute Combine( PropertyRoute descendants, PropertyRoute ancestors ) - { - if( ancestors == null ) - return descendants; - - if( descendants == null ) - return ancestors; - - return PropertyRoute.Combine( - descendants.Current, - PropertyRoute.Combine( descendants.Parent, ancestors ) ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/PropertyRouteBuilder.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/PropertyRouteBuilder.cs deleted file mode 100644 index 6333694e..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/PropertyRouteBuilder.cs +++ /dev/null @@ -1,187 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Diagnostics; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class PropertyRouteBuilder - { - internal PropertyRouteBuilder() - { - } - - internal PropertyRouteBuilder( PropertyRoute route ) - { - if( route == null ) - return; - - for( var c = route; c != null; c = c.Parent ) - { - this.PushAncestor( c.Current ); - } - } - - internal PropertyRouteBuilder( PropertyDescriptionRoute route ) - { - if( route == null ) - return; - - for( var c = route; c != null; c = c.Parent ) - { - this.PushAncestor( c.Current ); - } - } - - internal PropertyRouteBuilder( DataGridItemPropertyRoute route ) - { - if( route == null ) - return; - - for( var c = route; c != null; c = c.Parent ) - { - this.PushAncestor( c.Current ); - } - } - - internal bool IsEmpty - { - get - { - return ( m_segments.Count <= 0 ); - } - } - - internal static PropertyRoute ToPropertyRoute( PropertyRouteSegment segment ) - { - return new PropertyRoute( segment ); - } - - internal static PropertyRoute ToPropertyRoute( PropertyDescriptionRoute description ) - { - if( description == null ) - return null; - - return PropertyRoute.Combine( PropertyRouteBuilder.ToSegment( description.Current ), PropertyRouteBuilder.ToPropertyRoute( description.Parent ) ); - } - - internal static PropertyRoute ToPropertyRoute( DataGridItemPropertyRoute itemProperty ) - { - if( itemProperty == null ) - return null; - - return PropertyRoute.Combine( PropertyRouteBuilder.ToSegment( itemProperty.Current ), PropertyRouteBuilder.ToPropertyRoute( itemProperty.Parent ) ); - } - - internal void PushAncestor( PropertyRouteSegment segment ) - { - m_segments.Insert( 0, segment ); - } - - internal void PushAncestor( PropertyDescription description ) - { - if( description == null ) - throw new ArgumentNullException( "description" ); - - this.PushAncestor( PropertyRouteBuilder.ToSegment( description ) ); - } - - internal void PushAncestor( DataGridItemPropertyBase itemProperty ) - { - if( itemProperty == null ) - throw new ArgumentNullException( "itemProperty" ); - - this.PushAncestor( PropertyRouteBuilder.ToSegment( itemProperty ) ); - } - - internal void PushDescendant( PropertyRouteSegment segment ) - { - m_segments.Add( segment ); - } - - internal void PushDescendant( PropertyDescription description ) - { - if( description == null ) - throw new ArgumentNullException( "description" ); - - this.PushDescendant( PropertyRouteBuilder.ToSegment( description ) ); - } - - internal void PushDescendant( DataGridItemPropertyBase itemProperty ) - { - if( itemProperty == null ) - throw new ArgumentNullException( "itemProperty" ); - - this.PushDescendant( PropertyRouteBuilder.ToSegment( itemProperty ) ); - } - - internal void PopAncestor() - { - if( m_segments.Count <= 0 ) - throw new InvalidOperationException(); - - m_segments.RemoveAt( 0 ); - } - - internal void PopDescendant() - { - if( m_segments.Count <= 0 ) - throw new InvalidOperationException(); - - m_segments.RemoveAt( m_segments.Count - 1 ); - } - - internal PropertyRoute ToPropertyRoute() - { - if( m_segments.Count <= 0 ) - return null; - - var route = new PropertyRoute( m_segments[ 0 ] ); - - for( int i = 1; i < m_segments.Count; i++ ) - { - route = PropertyRoute.Combine( m_segments[ i ], route ); - } - - return route; - } - - private static PropertyRouteSegment ToSegment( PropertyDescription description ) - { - Debug.Assert( description != null ); - - return description.ToPropertyRouteSegment(); - } - - private static PropertyRouteSegment ToSegment( DataGridItemPropertyBase itemProperty ) - { - Debug.Assert( itemProperty != null ); - - var route = PropertyRouteParser.Parse( itemProperty.Name ); - if( route == null ) - throw new ArgumentException( "Unexpected DataGridItemPropertyBase.Name property value.", "itemProperty" ); - - if( route.Parent == null ) - return route.Current; - - return new PropertyRouteSegment( PropertyRouteSegmentType.Other, itemProperty.Name ); - } - - private readonly List m_segments = new List(); - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/PropertyRouteParser.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/PropertyRouteParser.cs deleted file mode 100644 index 379e91b2..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/PropertyRouteParser.cs +++ /dev/null @@ -1,317 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Diagnostics; -using System.Text; - -namespace Xceed.Wpf.DataGrid -{ - internal static class PropertyRouteParser - { - #region Static Fields - - private static readonly string ReservedSymbols = ".[]"; - - #endregion - - internal static PropertyRoute Parse( string path ) - { - path = ( path != null ) ? path.Trim() : string.Empty; - - var length = path.Length; - if( length <= 0 ) - return null; - - var builder = new PropertyRouteBuilder(); - var state = ParserState.Start; - var index = 0; - - while( index < length ) - { - var c = path[ index ]; - - if( char.IsWhiteSpace( c ) ) - { - index++; - } - else - { - switch( state ) - { - case ParserState.Start: - { - switch( c ) - { - case '.': - index++; - break; - - default: - state = ParserState.Property; - break; - } - } - break; - - case ParserState.Separator: - { - switch( c ) - { - case '.': - index++; - break; - - case '[': - break; - - default: - { - PropertyRouteParser.AddOther( path, length, ref index, builder ); - Debug.Assert( index >= length ); - } - break; - } - - state = ParserState.Property; - } - break; - - case ParserState.Property: - { - switch( c ) - { - case '[': - { - if( PropertyRouteParser.AddIndexer( path, length, ref index, builder ) ) - { - state = ParserState.Separator; - } - else - { - PropertyRouteParser.AddOther( path, length, ref index, builder ); - Debug.Assert( index >= length ); - } - } - break; - - default: - { - if( PropertyRouteParser.AddProperty( path, length, ref index, builder ) ) - { - state = ParserState.Separator; - } - else - { - PropertyRouteParser.AddOther( path, length, ref index, builder ); - Debug.Assert( index >= length ); - } - } - break; - } - } - break; - - default: - throw new NotImplementedException(); - } - } - } - - if( builder.IsEmpty ) - { - builder.PushDescendant( PropertyRouteSegment.Self ); - } - - return builder.ToPropertyRoute(); - } - - internal static string Parse( DataGridItemPropertyBase itemProperty ) - { - return PropertyRouteParser.Parse( PropertyRouteBuilder.ToPropertyRoute( DataGridItemPropertyRoute.Create( itemProperty ) ) ); - } - - internal static string Parse( PropertyRoute route ) - { - if( route == null ) - return string.Empty; - - var sb = new StringBuilder(); - var childSegmentType = PropertyRouteSegmentType.Self; - - while( route != null ) - { - var segment = route.Current; - if( segment.Type != PropertyRouteSegmentType.Self ) - { - if( !string.IsNullOrEmpty( segment.Name ) ) - { - if( sb.Length != 0 ) - { - switch( childSegmentType ) - { - // For these type of segment, there is no need to put a separator. - case PropertyRouteSegmentType.Self: - case PropertyRouteSegmentType.Indexer: - break; - - default: - sb.Insert( 0, "." ); - break; - } - } - - if( segment.Type == PropertyRouteSegmentType.Indexer ) - { - sb.Insert( 0, "]" ); - sb.Insert( 0, segment.Name ); - sb.Insert( 0, "[" ); - } - else - { - sb.Insert( 0, segment.Name ); - } - } - } - else - { - if( ( route.Parent == null ) && ( sb.Length == 0 ) ) - { - sb.Append( segment.Name ); - } - } - - childSegmentType = segment.Type; - route = route.Parent; - } - - return sb.ToString(); - } - - private static bool AddIndexer( string path, int length, ref int index, PropertyRouteBuilder builder ) - { - if( ( index >= length ) || ( path[ index ] != '[' ) ) - return false; - - var currentIndex = index + 1; - var startIndex = currentIndex; - - while( currentIndex < length ) - { - var c = path[ currentIndex ]; - - if( c == ']' ) - { - Debug.Assert( startIndex < length ); - Debug.Assert( startIndex <= currentIndex ); - - var value = path.Substring( startIndex, currentIndex - startIndex ).Trim(); - if( value.Length <= 0 ) - return false; - - // The value is parsed twice in order to get a standard name that could be used as a key for further use. - var parametersList = IndexerParametersParser.Parse( value ); - var parameters = IndexerParametersParser.Parse( parametersList ); - if( string.IsNullOrEmpty( parameters ) ) - return false; - - builder.PushDescendant( new PropertyRouteSegment( PropertyRouteSegmentType.Indexer, parameters ) ); - index = currentIndex + 1; - - return true; - } - else if( PropertyRouteParser.ReservedSymbols.IndexOf( c ) >= 0 ) - { - return false; - } - - currentIndex++; - } - - return false; - } - - private static bool AddProperty( string path, int length, ref int index, PropertyRouteBuilder builder ) - { - var currentIndex = index; - - while( ( currentIndex < length ) && ( path[ currentIndex ] == '.' ) ) - { - currentIndex++; - } - - var startIndex = currentIndex; - var parens = 0; - - while( currentIndex < length ) - { - var c = path[ currentIndex ]; - - if( PropertyRouteParser.ReservedSymbols.IndexOf( c ) >= 0 ) - break; - - if( c == '(' ) - { - parens++; - } - else if( c == ')' ) - { - parens--; - - // A closing parenthesis was found before an opening parenthesis. - if( parens < 0 ) - return false; - } - - currentIndex++; - } - - if( ( parens != 0 ) || ( startIndex >= length ) ) - return false; - - var name = path.Substring( startIndex, currentIndex - startIndex ).Trim(); - if( name.Length > 0 ) - { - builder.PushDescendant( new PropertyRouteSegment( PropertyRouteSegmentType.Property, name ) ); - index = currentIndex; - } - - return true; - } - - private static void AddOther( string path, int length, ref int index, PropertyRouteBuilder builder ) - { - if( index >= length ) - return; - - var value = path.Substring( index, length - index ).Trim(); - - builder.PushDescendant( new PropertyRouteSegment( PropertyRouteSegmentType.Other, value ) ); - index = length; - } - - #region ParserState Private Enum - - private enum ParserState - { - Start, - Separator, - Property, - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/PropertyRouteSegment.Struct.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/PropertyRouteSegment.Struct.cs deleted file mode 100644 index 1b4327e2..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/PropertyRouteSegment.Struct.cs +++ /dev/null @@ -1,88 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid -{ - internal struct PropertyRouteSegment : IEquatable - { - #region Static Fields - - internal static readonly PropertyRouteSegment Self = new PropertyRouteSegment( PropertyRouteSegmentType.Self, "." ); - - #endregion - - internal PropertyRouteSegment( PropertyRouteSegmentType type, string name ) - { - if( name == null ) - throw new ArgumentNullException( "name" ); - - m_type = type; - m_name = name; - } - - #region Type Property - - internal PropertyRouteSegmentType Type - { - get - { - return m_type; - } - } - - private readonly PropertyRouteSegmentType m_type; - - #endregion - - #region Name Property - - internal string Name - { - get - { - return m_name; - } - } - - private readonly string m_name; - - #endregion - - public static bool Equals( PropertyRouteSegment x, PropertyRouteSegment y ) - { - return x.Equals( y ); - } - - public override int GetHashCode() - { - return m_name.GetHashCode() ^ m_type.GetHashCode(); - } - - public override bool Equals( object obj ) - { - return ( obj is PropertyRouteSegment ) - && ( this.Equals( ( PropertyRouteSegment )obj ) ); - } - - public bool Equals( PropertyRouteSegment obj ) - { - return ( obj.m_name == m_name ) - && ( obj.m_type == m_type ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ReadOnlyColumnCollection.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ReadOnlyColumnCollection.cs deleted file mode 100644 index c5cb9a49..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ReadOnlyColumnCollection.cs +++ /dev/null @@ -1,80 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.ObjectModel; -using System.Collections.Specialized; -using System.Diagnostics; - -namespace Xceed.Wpf.DataGrid -{ - internal class ReadOnlyColumnCollection : ReadOnlyObservableCollection - { - internal ReadOnlyColumnCollection( ObservableColumnCollection collection ) - : base( collection ) - { - } - - #region [] Property - - internal ColumnBase this[ string fieldName ] - { - get - { - return ( ( ObservableColumnCollection )this.Items )[ fieldName ]; - } - } - - #endregion - - internal void RaiseItemChanged( ColumnBase column ) - { - Debug.Assert( column != null ); - - this.OnCollectionChanged( new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Replace, column, column, this.IndexOf( column ) ) ); - } - - internal void InternalClear() - { - this.Items.Clear(); - } - - internal void InternalAdd( ColumnBase column ) - { - this.Items.Add( column ); - } - - internal void InternalInsert( int index, ColumnBase column ) - { - this.Items.Insert( index, column ); - } - - internal bool InternalRemove( ColumnBase column ) - { - return this.Items.Remove( column ); - } - - internal void InternalRemoveAt( int index ) - { - this.Items.RemoveAt( index ); - } - - internal IDisposable DeferNotifications() - { - return ( ( ObservableColumnCollection )this.Items ).DeferNotifications(); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/RelativePoint.Struct.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/RelativePoint.Struct.cs deleted file mode 100644 index b60732a8..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/RelativePoint.Struct.cs +++ /dev/null @@ -1,84 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - internal struct RelativePoint : IEquatable - { - internal RelativePoint( UIElement element, Point relativePoint ) - { - if( element == null ) - throw new ArgumentNullException( "element" ); - - m_element = element; - m_relativePoint = relativePoint; - } - - public static bool operator ==( RelativePoint x, RelativePoint y ) - { - return x.Equals( y ); - } - - public static bool operator !=( RelativePoint x, RelativePoint y ) - { - return !( x == y ); - } - - public override int GetHashCode() - { - return base.GetHashCode(); - } - - public override bool Equals( object obj ) - { - if( !( obj is RelativePoint ) ) - return false; - - return this.Equals( ( RelativePoint )obj ); - } - - public bool Equals( RelativePoint obj ) - { - return ( object.Equals( obj.m_element, m_element ) ) - && ( object.Equals( obj.m_relativePoint, m_relativePoint ) ); - } - - internal Point GetPoint( UIElement relativeTo ) - { - if( relativeTo == null ) - throw new ArgumentNullException( "element" ); - - if( m_element == null ) - throw new InvalidOperationException(); - - if( relativeTo == m_element ) - return m_relativePoint; - - return m_element.TranslatePoint( m_relativePoint, relativeTo ); - } - - internal RelativePoint TranslateTo( UIElement relativeTo ) - { - return new RelativePoint( relativeTo, this.GetPoint( relativeTo ) ); - } - - private readonly UIElement m_element; - private readonly Point m_relativePoint; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Row.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Row.cs deleted file mode 100644 index d9394dad..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Row.cs +++ /dev/null @@ -1,3067 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Diagnostics; -using System.Linq; -using System.Reflection; -using System.Windows; -using System.Windows.Automation.Peers; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Markup; -using System.Windows.Media; -using Xceed.Utils.Wpf; -using Xceed.Wpf.DataGrid.Utils; -using Xceed.Wpf.DataGrid.ValidationRules; -using Xceed.Wpf.DataGrid.Views; - -namespace Xceed.Wpf.DataGrid -{ - [TemplatePart( Name = "PART_CellsHost", Type = typeof( Panel ) )] - [TemplatePart( Name = "PART_RowFocusRoot", Type = typeof( FrameworkElement ) )] - [ContentProperty( "Cells" )] - public abstract class Row : Control, IDataGridItemContainer, INotifyPropertyChanged, IWeakEventListener - { - // This validation rule is meant to be used as the rule in error set in a Row's ValidationError when - // we want to flag a validation error even though no binding's ValidationRules or CellValidationRules are invalid. - // ie: Row EditEnding event throws or returns with e.Cancel set to True, IEditableObject's EndEdit throws. - private static readonly ValidationRule CustomRowValidationExceptionValidationRule = new ExceptionValidationRule(); - - static Row() - { - // We need to override the default Validation ErrorTemplate, else the default adorner will appear - // around the row when the main column's cell has a Validation error. - // We handle validation errors at the cell level by using error styles, not through Validation.ErrorTemplate. - Validation.ErrorTemplateProperty.OverrideMetadata( typeof( Xceed.Wpf.DataGrid.Row ), - new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.OverridesInheritanceBehavior ) ); - - Row.IsCurrentProperty = Row.IsCurrentPropertyKey.DependencyProperty; - Row.CellsProperty = Row.CellsPropertyKey.DependencyProperty; - Row.IsBeingEditedProperty = Row.IsBeingEditedPropertyKey.DependencyProperty; - Row.IsDirtyProperty = Row.IsDirtyPropertyKey.DependencyProperty; - Row.IsSelectedProperty = Row.IsSelectedPropertyKey.DependencyProperty; - - DataGridControl.ParentDataGridControlPropertyKey.OverrideMetadata( typeof( Row ), - new FrameworkPropertyMetadata( new PropertyChangedCallback( OnParentGridControlChanged ) ) ); - - DataGridControl.CellEditorDisplayConditionsProperty.OverrideMetadata( typeof( Row ), - new FrameworkPropertyMetadata( new PropertyChangedCallback( OnCellEditorDisplayConditionsChanged ) ) ); - - // We do this last to ensure all the Static content of the row is done before using any static readonly field of the cell. - Row.SelectionBackgroundProperty = Cell.SelectionBackgroundProperty.AddOwner( typeof( Row ) ); - Row.SelectionForegroundProperty = Cell.SelectionForegroundProperty.AddOwner( typeof( Row ) ); - Row.InactiveSelectionBackgroundProperty = Cell.InactiveSelectionBackgroundProperty.AddOwner( typeof( Row ) ); - Row.InactiveSelectionForegroundProperty = Cell.InactiveSelectionForegroundProperty.AddOwner( typeof( Row ) ); - Row.ParentForegroundProperty = Cell.ParentForegroundProperty.AddOwner( typeof( Row ) ); - - EventManager.RegisterClassHandler( typeof( Row ), Cell.IsDirtyEvent, new RoutedEventHandler( OnCellIsDirty_ClassHandler ) ); - Row.IsDirtyEvent = Cell.IsDirtyEvent.AddOwner( typeof( Row ) ); - } - - protected Row() - { - this.CommandBindings.Add( new CommandBinding( DataGridCommands.BeginEdit, - new ExecutedRoutedEventHandler( OnBeginEditExecuted ), - new CanExecuteRoutedEventHandler( OnBeginEditCanExecute ) ) ); - - this.CommandBindings.Add( new CommandBinding( DataGridCommands.EndEdit, - new ExecutedRoutedEventHandler( OnEndEditExecuted ), - new CanExecuteRoutedEventHandler( OnEndEditCanExecute ) ) ); - - this.CommandBindings.Add( new CommandBinding( DataGridCommands.CancelEdit, - new ExecutedRoutedEventHandler( OnCancelEditExecuted ), - new CanExecuteRoutedEventHandler( OnCancelEditCanExecute ) ) ); - - // Cache the CellsCollection and always return it in the getter of the DependencyProperty's CLR accessor - m_cellsCache = new VirtualizingCellCollection( this ); - - // Set the Value of the DependencyProperty - this.SetValue( Row.CellsPropertyKey, m_cellsCache ); - } - - #region NavigationBehavior Property - - public static readonly DependencyProperty NavigationBehaviorProperty = DataGridControl.NavigationBehaviorProperty.AddOwner( - typeof( Row ), - new FrameworkPropertyMetadata( NavigationBehavior.CellOnly, FrameworkPropertyMetadataOptions.Inherits, - new PropertyChangedCallback( OnNavigationBehaviorChanged ) ) ); - - public NavigationBehavior NavigationBehavior - { - get - { - return ( NavigationBehavior )this.GetValue( Row.NavigationBehaviorProperty ); - } - set - { - this.SetValue( Row.NavigationBehaviorProperty, value ); - } - } - - #endregion NavigationBehavior Property - - #region Cells Read-Only Property - - private static readonly DependencyPropertyKey CellsPropertyKey = DependencyProperty.RegisterReadOnly( - "Cells", - typeof( CellCollection ), - typeof( Row ), - new PropertyMetadata( null ) ); - - public static readonly DependencyProperty CellsProperty; - - // Define it as Virtualizing to avoid casts - private readonly VirtualizingCellCollection m_cellsCache; // = null; - - public CellCollection Cells - { - get - { - return m_cellsCache; - } - } - - #endregion Cells Read-Only Property - - #region CellEditorDisplayConditions Property - - public CellEditorDisplayConditions CellEditorDisplayConditions - { - get - { - return ( CellEditorDisplayConditions )this.GetValue( DataGridControl.CellEditorDisplayConditionsProperty ); - } - set - { - this.SetValue( DataGridControl.CellEditorDisplayConditionsProperty, value ); - } - } - - #endregion CellEditorDisplayConditions Property - - #region CellErrorStyle Property - - public static readonly DependencyProperty CellErrorStyleProperty = - DataGridControl.CellErrorStyleProperty.AddOwner( typeof( Row ) ); - - public Style CellErrorStyle - { - get - { - return ( Style )this.GetValue( Row.CellErrorStyleProperty ); - } - - set - { - this.SetValue( Row.CellErrorStyleProperty, value ); - } - } - - #endregion CellErrorStyle Property - - #region CellContentOpacity Internal Property - - internal static readonly DependencyProperty CellContentOpacityProperty = DependencyProperty.RegisterAttached( - "CellContentOpacity", - typeof( double ), - typeof( Row ), - new FrameworkPropertyMetadata( 1d ) ); - - internal static double GetCellContentOpacity( DependencyObject obj ) - { - return ( double )obj.GetValue( Row.CellContentOpacityProperty ); - } - internal static void SetCellContentOpacity( DependencyObject obj, double value ) - { - obj.SetValue( Row.CellContentOpacityProperty, value ); - } - - #endregion CellContentOpacity Internal Property - - #region EditTriggers Property - - public static readonly DependencyProperty EditTriggersProperty = DataGridControl.EditTriggersProperty.AddOwner( typeof( Row ) ); - - public EditTriggers EditTriggers - { - get - { - return ( EditTriggers )this.GetValue( Row.EditTriggersProperty ); - } - set - { - this.SetValue( Row.EditTriggersProperty, value ); - } - } - - #endregion EditTriggers Property - - #region HasValidationError Read-Only Property - - internal static readonly DependencyPropertyKey HasValidationErrorPropertyKey = DependencyProperty.RegisterReadOnly( - "HasValidationError", - typeof( bool ), - typeof( Row ), - new UIPropertyMetadata( false ) ); - - public static readonly DependencyProperty HasValidationErrorProperty = HasValidationErrorPropertyKey.DependencyProperty; - - public bool HasValidationError - { - get - { - return ( bool )this.GetValue( Row.HasValidationErrorProperty ); - } - } - - internal void SetHasValidationError( bool value ) - { - if( value != this.HasValidationError ) - { - if( value ) - { - this.SetValue( Row.HasValidationErrorPropertyKey, value ); - } - else - { - this.SetValue( Row.HasValidationErrorPropertyKey, DependencyProperty.UnsetValue ); - } - } - } - - #endregion HasValidationError Read-Only Property - - #region IsValidationErrorRestrictive Read-Only Property - - private static readonly DependencyPropertyKey IsValidationErrorRestrictivePropertyKey = DependencyProperty.RegisterReadOnly( - "IsValidationErrorRestrictive", - typeof( bool ), - typeof( Row ), - new UIPropertyMetadata( false ) ); - - public static readonly DependencyProperty IsValidationErrorRestrictiveProperty = IsValidationErrorRestrictivePropertyKey.DependencyProperty; - - public bool IsValidationErrorRestrictive - { - get - { - return ( bool )this.GetValue( Row.IsValidationErrorRestrictiveProperty ); - } - } - - internal void SetIsValidationErrorRestrictive( bool value ) - { - if( value != this.IsValidationErrorRestrictive ) - { - if( value ) - { - this.SetValue( Row.IsValidationErrorRestrictivePropertyKey, value ); - } - else - { - this.SetValue( Row.IsValidationErrorRestrictivePropertyKey, DependencyProperty.UnsetValue ); - } - } - } - - #endregion IsValidationErrorRestrictive Read-Only Property - - #region IsBeingEdited Read-Only Property - - internal static readonly DependencyPropertyKey IsBeingEditedPropertyKey = DependencyProperty.RegisterReadOnly( - "IsBeingEdited", - typeof( bool ), - typeof( Row ), - new PropertyMetadata( false, new PropertyChangedCallback( OnIsBeingEditedChanged ) ) ); - - public static readonly DependencyProperty IsBeingEditedProperty; - - public bool IsBeingEdited - { - get - { - return this.IsBeingEditedCache; - } - } - - private void SetIsBeingEdited( bool value ) - { - if( value != this.IsBeingEdited ) - { - this.IsBeingEditedCache = value; - - if( value ) - { - this.SetValue( Row.IsBeingEditedPropertyKey, value ); - } - else - { - this.SetValue( Row.IsBeingEditedPropertyKey, DependencyProperty.UnsetValue ); - } - } - } - - #endregion IsBeingEdited Read-Only Property - - #region IsDirty Read-Only Property - - private static readonly DependencyPropertyKey IsDirtyPropertyKey = - DependencyProperty.RegisterReadOnly( "IsDirty", typeof( bool ), typeof( Row ), new PropertyMetadata( false ) ); - - public static readonly DependencyProperty IsDirtyProperty; - - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] - internal static RoutedEvent IsDirtyEvent; // = null; - - public bool IsDirty - { - get - { - return ( bool )this.GetValue( Row.IsDirtyProperty ); - } - } - - private void SetIsDirty( bool value ) - { - if( value != this.IsDirty ) - { - if( value ) - { - this.SetValue( Row.IsDirtyPropertyKey, value ); - } - else - { - this.SetValue( Row.IsDirtyPropertyKey, DependencyProperty.UnsetValue ); - } - - if( this.IsBeingEdited ) - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - DataGridControl gridControl = ( dataGridContext != null ) - ? dataGridContext.DataGridControl - : null; - - if( gridControl != null ) - { - RowState rowState = gridControl.CurrentRowInEditionState; - Debug.Assert( rowState != null ); - - if( rowState != null ) - rowState.SetIsDirty( value ); - } - } - } - } - - #endregion IsDirty Read-Only Property - - #region RowDisplayEditorMatchingConditions Property - - internal static readonly DependencyProperty RowDisplayEditorMatchingConditionsProperty = - DependencyProperty.Register( "RowDisplayEditorMatchingConditions", typeof( CellEditorDisplayConditions ), typeof( Row ), new FrameworkPropertyMetadata( CellEditorDisplayConditions.None ) ); - - internal void SetDisplayEditorMatchingCondition( CellEditorDisplayConditions condition ) - { - CellEditorDisplayConditions previousValue = ( CellEditorDisplayConditions )this.GetValue( Row.RowDisplayEditorMatchingConditionsProperty ); - - previousValue = previousValue | condition; - - this.SetValue( Row.RowDisplayEditorMatchingConditionsProperty, previousValue ); - } - - internal void RemoveDisplayEditorMatchingCondition( CellEditorDisplayConditions condition ) - { - CellEditorDisplayConditions previousValue = ( CellEditorDisplayConditions )this.GetValue( Row.RowDisplayEditorMatchingConditionsProperty ); - - previousValue = previousValue & ~condition; - - this.SetValue( Row.RowDisplayEditorMatchingConditionsProperty, previousValue ); - } - - #endregion RowDisplayEditorMatchingConditions Property - - #region ReadOnly Property - - public static readonly DependencyProperty ReadOnlyProperty = - DataGridControl.ReadOnlyProperty.AddOwner( typeof( Row ) ); - - public bool ReadOnly - { - get - { - return ( bool )this.GetValue( Row.ReadOnlyProperty ); - } - set - { - this.SetValue( Row.ReadOnlyProperty, value ); - } - } - - #endregion ReadOnly Property - - #region IsCurrent Read-Only Property - - internal static readonly DependencyPropertyKey IsCurrentPropertyKey = - DependencyProperty.RegisterReadOnly( "IsCurrent", typeof( bool ), typeof( Row ), new UIPropertyMetadata( false, new PropertyChangedCallback( Row.OnIsCurrentChanged ) ) ); - - public static readonly DependencyProperty IsCurrentProperty; - - public bool IsCurrent - { - get - { - return ( bool )this.GetValue( Row.IsCurrentProperty ); - } - } - - internal void SetIsCurrent( bool value ) - { - if( value ) - { - this.SetValue( Row.IsCurrentPropertyKey, true ); - } - else - { - this.SetValue( Row.IsCurrentPropertyKey, DependencyProperty.UnsetValue ); - } - - this.UpdateNavigationBehavior(); - } - - #endregion IsCurrent Read-Only Property - - #region IsSelected Read-only Property - - private static readonly DependencyPropertyKey IsSelectedPropertyKey = - DependencyProperty.RegisterReadOnly( "IsSelected", typeof( bool ), typeof( Row ), new UIPropertyMetadata( false ) ); - - public static readonly DependencyProperty IsSelectedProperty; - - public bool IsSelected - { - get - { - return ( bool )this.GetValue( Row.IsSelectedProperty ); - } - } - - internal void SetIsSelected( bool value ) - { - if( this.IsSelected != value ) - { - if( value ) - { - this.SetValue( Row.IsSelectedPropertyKey, value ); - } - else - { - this.ClearValue( Row.IsSelectedPropertyKey ); - } - - } - } - - #endregion IsSelected Property - - #region CellsHostPanel Read-Only Property - - internal Panel CellsHostPanel - { - get - { - return m_cellsHostPanel; - } - } - - #endregion CellsHostPanel Read-Only Property - - #region SelectionBackground Property - - public static readonly DependencyProperty SelectionBackgroundProperty; - - public Brush SelectionBackground - { - get - { - return ( Brush )this.GetValue( Row.SelectionBackgroundProperty ); - } - set - { - this.SetValue( Row.SelectionBackgroundProperty, value ); - } - } - - #endregion SelectionBackground Property - - #region SelectionForeground Property - - public static readonly DependencyProperty SelectionForegroundProperty; - - public Brush SelectionForeground - { - get - { - return ( Brush )this.GetValue( Row.SelectionForegroundProperty ); - } - set - { - this.SetValue( Row.SelectionForegroundProperty, value ); - } - } - - #endregion SelectionForeground Property - - #region InactiveSelectionBackground Property - - public static readonly DependencyProperty InactiveSelectionBackgroundProperty; - - public Brush InactiveSelectionBackground - { - get - { - return ( Brush )this.GetValue( Row.InactiveSelectionBackgroundProperty ); - } - set - { - this.SetValue( Row.InactiveSelectionBackgroundProperty, value ); - } - } - - #endregion InactiveSelectionBackground Property - - #region InactiveSelectionForeground Property - - public static readonly DependencyProperty InactiveSelectionForegroundProperty; - - public Brush InactiveSelectionForeground - { - get - { - return ( Brush )this.GetValue( Row.InactiveSelectionForegroundProperty ); - } - set - { - this.SetValue( Row.InactiveSelectionForegroundProperty, value ); - } - } - - #endregion InactiveSelectionForeground Property - - #region ParentForeground Property - - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - public static readonly DependencyProperty ParentForegroundProperty; - - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - public Brush ParentForeground - { - get - { - return ( Brush )this.GetValue( Row.ParentForegroundProperty ); - } - set - { - this.SetValue( Row.ParentForegroundProperty, value ); - } - } - - private void UpdateParentForeground() - { - // Use the visual parent when there is no logical parent. - var parent = LogicalTreeHelper.GetParent( this ) ?? VisualTreeHelper.GetParent( this ); - - if( parent != null ) - { - var binding = new Binding(); - binding.Path = new PropertyPath( TextElement.ForegroundProperty ); - binding.Source = parent; - - this.SetBinding( Row.ParentForegroundProperty, binding ); - } - else - { - this.ClearValue( Row.ParentForegroundProperty ); - } - } - - #endregion ParentForeground Property - - #region RowFocusRoot Property - - private FrameworkElement m_rowFocusRoot; - - internal FrameworkElement RowFocusRoot - { - get - { - return m_rowFocusRoot; - } - } - - #endregion - - #region IsTemplateCell Attached Property - - internal static readonly DependencyProperty IsTemplateCellProperty = - DependencyProperty.RegisterAttached( "IsTemplateCell", typeof( bool ), typeof( Row ), new UIPropertyMetadata( false ) ); - - internal static bool GetIsTemplateCell( DependencyObject obj ) - { - return ( bool )obj.GetValue( Row.IsTemplateCellProperty ); - } - - private static void SetIsTemplateCell( DependencyObject obj, bool value ) - { - obj.SetValue( Row.IsTemplateCellProperty, value ); - } - - #endregion IsTemplateCell Attached Property - - #region ValidationError Read-Only Property - - public static readonly RoutedEvent ValidationErrorChangingEvent = - EventManager.RegisterRoutedEvent( "ValidationErrorChanging", RoutingStrategy.Bubble, typeof( RowValidationErrorRoutedEventHandler ), typeof( Row ) ); - - public event RowValidationErrorRoutedEventHandler ValidationErrorChanging - { - add - { - base.AddHandler( Row.ValidationErrorChangingEvent, value ); - } - remove - { - - base.RemoveHandler( Row.ValidationErrorChangingEvent, value ); - } - } - - protected virtual void OnValidationErrorChanging( RowValidationErrorRoutedEventArgs e ) - { - this.RaiseEvent( e ); - } - - private static readonly DependencyPropertyKey ValidationErrorPropertyKey = DependencyProperty.RegisterReadOnly( - "ValidationError", - typeof( RowValidationError ), - typeof( Row ), - new PropertyMetadata( null, new PropertyChangedCallback( Row.OnValidationErrorChanged ), new CoerceValueCallback( Row.OnCoerceValidationError ) ) ); - - public static readonly DependencyProperty ValidationErrorProperty = Row.ValidationErrorPropertyKey.DependencyProperty; - - public RowValidationError ValidationError - { - get - { - return ( RowValidationError )this.GetValue( Row.ValidationErrorProperty ); - } - } - - internal void SetValidationError( RowValidationError value ) - { - this.SetValue( Row.ValidationErrorPropertyKey, value ); - } - - private static object OnCoerceValidationError( DependencyObject sender, object value ) - { - if( value == null ) - return value; - - Row row = ( Row )sender; - - RowValidationErrorRoutedEventArgs rowValidationErrorRoutedEventArgs = - new RowValidationErrorRoutedEventArgs( Row.ValidationErrorChangingEvent, row, ( RowValidationError )value ); - - row.OnValidationErrorChanging( rowValidationErrorRoutedEventArgs ); - - return rowValidationErrorRoutedEventArgs.RowValidationError; - } - - private static void OnValidationErrorChanged( object sender, DependencyPropertyChangedEventArgs e ) - { - Row row = ( Row )sender; - - if( row.IsBeingEdited ) - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( row ); - - if( dataGridContext != null ) - { - DataGridControl dataGridControl = dataGridContext.DataGridControl; - - if( dataGridControl != null ) - { - RowState rowState = dataGridControl.CurrentRowInEditionState; - Debug.Assert( rowState != null ); - - if( rowState != null ) - { - rowState.SetItemValidationError( e.NewValue as RowValidationError ); - } - } - } - } - - if( e.OldValue == null ) - { - row.m_cachedLocalToolTip = row.ReadLocalValue( Row.ToolTipProperty ); - row.ToolTip = ( ( RowValidationError )e.NewValue ).ErrorContent; - } - else if( e.NewValue == null ) - { - if( row.m_cachedLocalToolTip == DependencyProperty.UnsetValue ) - { - row.ClearValue( Row.ToolTipProperty ); - } - else - { - row.ToolTip = row.m_cachedLocalToolTip; - } - } - else - { - row.ToolTip = ( ( RowValidationError )e.NewValue ).ErrorContent; - } - - - row.UpdateHasErrorFlags( null ); - } - - private object m_cachedLocalToolTip; - - #endregion ValidationError Read-Only Property - - #region CanBeRecycled Protected Property - - protected virtual bool CanBeRecycled - { - get - { - if( this.IsKeyboardFocused - || this.IsKeyboardFocusWithin - || this.IsBeingEdited ) - return false; - - return true; - } - } - - #endregion - - #region UnboundDataItemContext Property - - internal UnboundDataItem UnboundDataItemContext - { - get - { - return m_unboundDataItem; - } - } - - internal void ClearUnboundDataItemContext() - { - m_unboundDataItem = null; - } - - internal void UpdateUnboundDataItemContext() - { - var dataItem = this.DataContext; - if( dataItem == null ) - { - this.ClearUnboundDataItemContext(); - } - else - { - if( m_unboundDataItem != null ) - { - if( object.Equals( m_unboundDataItem.DataItem, dataItem ) ) - return; - } - - m_unboundDataItem = UnboundDataItem.GetUnboundDataItem( dataItem ); - } - } - - private UnboundDataItem m_unboundDataItem; - - #endregion - - #region VirtualizedCells Property - - internal IEnumerable VirtualizedCells - { - get - { - Debug.Assert( m_cellsCache != null ); - return m_cellsCache.VirtualizedCells; - } - } - - #endregion - - #region CreatedCells Property - - internal IEnumerable CreatedCells - { - get - { - Debug.Assert( m_cellsCache != null ); - return m_cellsCache.BindedCells; - } - } - - #endregion - - #region CreatedCellsCount Property - - internal int CreatedCellsCount - { - get - { - Debug.Assert( m_cellsCache != null ); - return m_cellsCache.BindedCells.Count; - } - } - - #endregion - - #region IsClearingContainer Property - - internal bool IsClearingContainer - { - get - { - return m_flags[ ( int )RowFlags.IsClearingContainer ]; - } - set - { - m_flags[ ( int )RowFlags.IsClearingContainer ] = value; - } - } - - #endregion - - #region IsContainerPrepared Property - - internal bool IsContainerPrepared - { - get - { - return m_flags[ ( int )RowFlags.IsContainerPrepared ]; - } - set - { - if( value == this.IsContainerPrepared ) - return; - - m_flags[ ( int )RowFlags.IsContainerPrepared ] = value; - - this.OnPropertyChanged( Row.IsContainerPreparedPropertyName ); - } - } - - internal static readonly string IsContainerPreparedPropertyName = PropertyHelper.GetPropertyName( ( Row r ) => r.IsContainerPrepared ); - - #endregion - - #region EmptyDataItem Property - - internal EmptyDataItem EmptyDataItem - { - get - { - if( m_emptyDataItem == null ) - { - m_emptyDataItem = new EmptyDataItem(); - } - - return m_emptyDataItem; - } - } - - private EmptyDataItem m_emptyDataItem; // = null; - - #endregion - - #region LevelCache Property - - internal static readonly DependencyProperty LevelCacheProperty = DependencyProperty.Register( - "LevelCache", - typeof( int ), - typeof( Row ), - new FrameworkPropertyMetadata( -1 ) ); - - internal int LevelCache - { - get - { - return ( int )this.GetValue( Row.LevelCacheProperty ); - } - set - { - this.SetValue( Row.LevelCacheProperty, value ); - } - } - - #endregion - - #region IsUnfocusable Property - - internal virtual bool IsUnfocusable - { - get - { - return false; - } - } - - #endregion - - public static Row FindFromChild( DependencyObject child ) - { - return Row.FindFromChild( ( DataGridContext )null, child ); - } - - public static Row FindFromChild( DataGridContext dataGridContext, DependencyObject child ) - { - // In this situation, the dataGridContext is the DataGridContext of the Row to find. - // Useful when a grid is used as a Cell editor and want the Row for a specific DataGridContext. - if( child == null ) - return null; - - Row row = null; - - while( ( row == null ) && ( child != null ) ) - { - child = TreeHelper.GetParent( child ); - row = child as Row; - - if( row == null ) - { - RowSelector rowSelector = child as RowSelector; - - if( rowSelector != null ) - { - row = rowSelector.DataContext as Row; - } - } - - if( ( row != null ) - && ( dataGridContext != null ) - && ( dataGridContext != DataGridControl.GetDataGridContext( row ) ) ) - { - row = null; - } - } - - return row; - } - - public static Row FindFromChild( DataGridControl dataGridControl, DependencyObject child ) - { - // In this situation, the dataGridControl is the DataGridControl of the Cell to find. - // Useful when a grid is used as a Cell editor and want the Row for a specific DataGridControl. - if( child == null ) - return null; - - Row row = null; - - while( ( row == null ) && ( child != null ) ) - { - child = TreeHelper.GetParent( child ); - row = child as Row; - - if( ( row != null ) && ( dataGridControl != null ) ) - { - DataGridContext tempDataGridContext = DataGridControl.GetDataGridContext( row ); - - if( ( tempDataGridContext == null ) || ( tempDataGridContext.DataGridControl != dataGridControl ) ) - { - row = null; - } - } - } - - return row; - } - - public override void OnApplyTemplate() - { - base.OnApplyTemplate(); - - var dataGridContext = DataGridControl.GetDataGridContext( this ); - if( dataGridContext == null ) - throw new DataGridInternalException( "DataGridContext is null for Row." ); - - var dataGridControl = dataGridContext.DataGridControl; - if( dataGridControl == null ) - throw new DataGridInternalException( "DataGridControl is null for Row." ); - - m_rowFocusRoot = this.GetTemplateChild( "PART_RowFocusRoot" ) as FrameworkElement; - - if( m_cellsHostPanel != null ) - { - var oldVirtualizingCellsHost = m_cellsHostPanel as IVirtualizingCellsHost; - if( oldVirtualizingCellsHost != null ) - { - oldVirtualizingCellsHost.ClearCellsHost(); - } - - m_cellsHostPanel.Children.Clear(); - } - - m_cellsHostPanel = this.GetTemplateChild( "PART_CellsHost" ) as Panel; - - // The PART_CellsHost children are handled internally, it is not allowed to add child elements directly through the template, so clear it. - if( m_cellsHostPanel != null ) - { - m_cellsHostPanel.Children.Clear(); - } - - if( m_rowFocusRoot == null ) - { - m_rowFocusRoot = m_cellsHostPanel; - } - - //Get templated cells, if any (cells added to the visual tree of the row, but not through .Cells). - m_templateCells.Clear(); - this.GetTemplateCells( this, m_templateCells ); - - //This will, among other things, process cells added to Row.Cells, in xaml for instance. - //This must be done AFTER getting template cells, for cells added to Row.Cells will be part of the VisualTree after this call, thus would became template cells. - var fixedCellPanel = m_cellsHostPanel as FixedCellPanel; - if( fixedCellPanel != null ) - { - fixedCellPanel.PrepareVirtualizationMode( dataGridContext ); - } - else - { - m_cellsCache.MergeFreeCells(); - } - - var virtualizingCellsHost = m_cellsHostPanel as IVirtualizingCellsHost; - var hasVirtualizingCellsHost = virtualizingCellsHost != null; - - // Ensure that old template cells are cleared, and remove cells not mapped to any columns. - this.SynchronizeActualAndTemplateCells( dataGridContext, dataGridContext.Columns, ( hasVirtualizingCellsHost && ( m_templateCells.Count > 0 ) ) ); - - if( hasVirtualizingCellsHost ) - { - this.PrepareVirtualizingCellsHost( dataGridContext, virtualizingCellsHost ); - } - else - { - dataGridControl.ForceGeneratorReset = true; - this.PrepareNonVirtualizingCellsHost(); - } - - - this.UpdateNavigationBehavior(); - this.UpdateCellsFocusableStatus(); - } - - protected override void OnMouseMove( MouseEventArgs e ) - { - base.OnMouseMove( e ); - - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - if( dataGridContext == null ) - return; - - if( e.LeftButton == MouseButtonState.Pressed ) - { - dataGridContext.DataGridControl.DoDrag( e ); - } - else - { - dataGridContext.DataGridControl.ResetDragDataObject(); - } - } - - protected override void OnMouseLeftButtonDown( MouseButtonEventArgs e ) - { - base.OnMouseLeftButtonDown( e ); - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - if( dataGridContext == null ) - return; - - dataGridContext.DataGridControl.ResetDragDataObject(); - - if( e.Handled ) - return; - - if( this.NavigationBehavior != NavigationBehavior.None ) - { - // We accept NavigationBehavior.CellOnly because it will be handled by the OnPreviewGotKeyboardFocus - // of DataGridControl to redirect it to the current column if possible. - DependencyObject sourceElement = e.OriginalSource as DependencyObject; - - // Is not FixedColumnSplitter - if( !Row.IsPartOfFixedColumnSplitter( sourceElement ) ) - { - bool focused = false; - - if( m_rowFocusRoot != null ) - { - focused = m_rowFocusRoot.Focus(); - } - else - { - focused = this.Focus(); - } - - e.Handled = true; - - if( focused ) - { - // Keep a reference to the mouse position so we can calculate when a drag operation is actually started. - dataGridContext.DataGridControl.InitializeDragPostion( e ); - } - } - } - } - - protected override void OnIsKeyboardFocusWithinChanged( DependencyPropertyChangedEventArgs e ) - { - base.OnIsKeyboardFocusWithinChanged( e ); - - //Update the NavigationBehavior related parameter - this.UpdateNavigationBehavior(); - this.UpdateCellsFocusableStatus(); - } - - protected override void OnGotKeyboardFocus( KeyboardFocusChangedEventArgs e ) - { - //this element or a child element of the row is receiving the keyboard focus - //update the cell navigation parameters - this.UpdateNavigationBehavior(); - this.UpdateCellsFocusableStatus(); - - base.OnGotKeyboardFocus( e ); - } - - protected internal virtual void PrepareDefaultStyleKey( Xceed.Wpf.DataGrid.Views.ViewBase view ) - { - object currentThemeKey = view.GetDefaultStyleKey( typeof( Row ) ); - - if( currentThemeKey.Equals( this.DefaultStyleKey ) == false ) - { - this.DefaultStyleKey = currentThemeKey; - } - } - - - protected override void OnPropertyChanged( DependencyPropertyChangedEventArgs e ) - { - base.OnPropertyChanged( e ); - this.OnPropertyChanged( e.Property.Name ); - } - - protected override void OnVisualParentChanged( DependencyObject oldParent ) - { - base.OnVisualParentChanged( oldParent ); - - this.UpdateParentForeground(); - } - - protected virtual void SetDataContext( object item ) - { - this.DataContext = item; - } - - protected virtual void ClearDataContext() - { - this.DataContext = null; - } - - protected virtual void PrepareContainer( DataGridContext dataGridContext, object item ) - { - if( dataGridContext == null ) - throw new ArgumentNullException( "dataGridContext" ); - - DataGridControl gridControl = dataGridContext.DataGridControl; - - this.SetDataContext( item ); - - if( dataGridContext.InternalCurrentItem == item ) - { - this.SetIsCurrent( true ); - // The cell.SetIsCurrent is set later since at that stage we have no cell. - - if( !gridControl.IsSetFocusInhibited ) - { - gridControl.QueueSetFocusHelper( false ); - } - } - - //this Forces the generation of the template and linked to that, of the cells. - this.ApplyTemplate(); - - // We ensure to create the CurrentCell by fetching it from the CellsCollection - // If there is a current column on the DataGridContext, try to restore the currency of the cell - var currentColumn = dataGridContext.CurrentColumn; - if( ( this.IsCurrent ) && ( currentColumn != null ) ) - { - //This will also trigger the creation of the Cell if it is virtualized. - Cell currentCell = m_cellsCache[ currentColumn ]; - } - - IVirtualizingCellsHost virtualizingCellsHost = this.CellsHostPanel as IVirtualizingCellsHost; - - if( virtualizingCellsHost != null ) - { - this.PrepareVirtualizingCellsHost( dataGridContext, virtualizingCellsHost ); - - // Template cells are not part of the VirtualzingCellsHost (thus not part of CreatedCells), so we must ensure they are prepared - if( m_templateCells != null ) - { - foreach( Cell cell in m_templateCells.Values ) - { - cell.PrepareContainer( dataGridContext, item ); - } - } - } - else - { - // When not having a VirtualizingCellHost, both template and "default" cells are contained within the VirtualizingCellCollection, so they will all be in CreatedCells. - foreach( Cell cell in this.CreatedCells ) - { - cell.PrepareContainer( dataGridContext, item ); - } - } - - // We must set isContainerPrepared because a verification is made in BeginEdit to ensure the container is prepared before entering in edition. - // The following RestoreEditionState will possibly trigger BeginEdit. - this.IsContainerPrepared = true; - - // Use the CurrentContext.InternalCurrentItem when restoring current item - object currentItemInEdition = gridControl.CurrentItemInEdition; - - // Restore the edition state on the container - // Voluntarilly using the .Equals() method instead of == operator to allow Struct comparison (in case of GroupHeaderFooterItem struct) - if( ( currentItemInEdition != null ) && ( currentItemInEdition.Equals( item ) ) ) - { - //PL: Should only occur when hitting a CollectionView reset while editing. - this.RestoreEditionState( gridControl.CurrentRowInEditionState, currentColumn ); - } - - this.UpdateMatchingDisplayConditions(); - this.UpdateNavigationBehavior(); - } - - protected abstract Cell CreateCell( ColumnBase column ); - - protected abstract bool IsValidCellType( Cell cell ); - - protected virtual void ClearContainer() - { - this.IsClearingContainer = true; - - try - { - // If there were some validation errors, we want to clear every Cells to be sure they will - // never reflect the error state on another data item if they are not explicitly prepared - this.ClearCellsHost(); - - // Clear every Cells before clearing the Row's values to allow the Cell to check some properties on their - // parent row when processing a Cell.ClearContainer, which ensures every prepared Cells are cleared correctly - foreach( Cell cell in this.CreatedCells ) - { - cell.ClearContainer(); - } - - // Clear all the DP's that are either public or somehow inherited. - this.ClearValue( Row.NavigationBehaviorProperty ); - this.ClearValue( DataGridControl.CellEditorDisplayConditionsProperty ); - - // We need to clear both the ValidationError and the HasValidationError property. - // The clearing of ValidationError will take care of the tooltip/cached local tooltip - // The clearing of HasValidationError will take care of updating the DataGridControl HasValidationError property. - this.ClearValue( Row.ValidationErrorPropertyKey ); - this.ClearValue( Row.HasValidationErrorPropertyKey ); - - this.ClearValue( Row.IsBeingEditedPropertyKey ); - this.ClearValue( Row.IsDirtyPropertyKey ); - this.ClearValue( Row.RowDisplayEditorMatchingConditionsProperty ); - this.ClearValue( Row.IsCurrentPropertyKey ); - this.ClearValue( Row.IsSelectedPropertyKey ); - - this.ClearValue( DataGridControl.ContainerGroupConfigurationProperty ); - - this.ClearDataContext(); - } - finally - { - this.IsClearingContainer = false; - this.IsContainerPrepared = false; - } - } - - protected virtual void PartialClearContainer() - { - this.IsClearingContainer = true; - - try - { - this.ClearCellsHost(); - - // Clear every Cells before clearing the Row's values to allow the Cell to check some properties on their - // parent row when processing a Cell.ClearContainer, which ensures every prepared Cells are cleared correctly - foreach( Cell cell in this.CreatedCells ) - { - cell.PartialClearContainer(); - } - - // We need to clear both the ValidationError and the HasValidationError property. - // The clearing of ValidationError will take care of the tooltip/cached local tooltip - // The clearing of HasValidationError will take care of updating the DataGridControl HasValidationError property. - this.ClearValue( Row.ValidationErrorPropertyKey ); - this.ClearValue( Row.HasValidationErrorPropertyKey ); - - this.ClearValue( Row.IsBeingEditedPropertyKey ); - this.ClearValue( Row.IsDirtyPropertyKey ); - this.ClearValue( Row.IsCurrentPropertyKey ); - - //No need to clear the IsSelected property, it will be properly set by the CustomItemContainerGenerator when recycling the row. - - this.ClearValue( DataGridControl.ContainerGroupConfigurationProperty ); - } - finally - { - this.IsClearingContainer = false; - } - } - - protected virtual void SynchronizeActualAndTemplateCells( DataGridContext dataGridContext, ColumnCollection columns, bool initializeTemplateCells ) - { - var oldTemplateCellsToRemove = new List(); - var unmappedCellsToRemove = new Hashtable(); - - //cycle through all the currently created cells, and place them in the right collection for further processing - foreach( var cell in this.CreatedCells ) - { - // When switching row templates, it is possible for a cell that was a template cell to be replaced by a regular cell, - // but still have a counterpart in the template cells. As a result, both conditions need to be checked. - if( Row.GetIsTemplateCell( cell ) || m_templateCells.ContainsKey( cell.FieldName ) ) - { - oldTemplateCellsToRemove.Add( cell ); - continue; - } - - unmappedCellsToRemove.Add( cell.FieldName, cell ); - } - - //First remove old templated cells, so they eventually get replaced by the newly discovered ones. - foreach( var oldTemplateCell in oldTemplateCellsToRemove ) - { - oldTemplateCell.ClearContainer(); - m_cellsCache.InternalRemove( oldTemplateCell ); - } - - if( initializeTemplateCells || ( unmappedCellsToRemove.Count > 0 ) ) - { - Xceed.Wpf.DataGrid.Views.ViewBase view = dataGridContext.DataGridControl.GetView(); - foreach( ColumnBase column in columns ) - { - var fieldName = column.FieldName; - - //This column is still in use, keep the corresponding cell. - unmappedCellsToRemove.Remove( fieldName ); - - // Case 161385 : the following is because template cells are not part of Row.Cells when dealing with an IVirtualizingCellPanel. - // If dealing with an IVirtualizingCellPanel, need to do further processing if there is a template cell associated to this column. - if( initializeTemplateCells ) - { - Cell cell = null; - m_templateCells.TryGetValue( fieldName, out cell ); - - if( cell != null ) - { - cell.Initialize( dataGridContext, this, column ); - cell.PrepareDefaultStyleKey( view ); - } - } - } - } - - // Lastly, clear cells that are not mapped to any column. - foreach( Cell unmappedcell in unmappedCellsToRemove.Values ) - { - unmappedcell.ClearContainer(); - m_cellsCache.InternalRemove( unmappedcell ); - } - } - - internal static Row FromContainer( DependencyObject container ) - { - if( container == null ) - return null; - - var row = container as Row; - if( row != null ) - return row; - - var itemContainer = container as IDataGridItemContainer; - if( itemContainer != null ) - return ( Row )itemContainer.GetTemplatedDescendantDataGridItemContainers().FirstOrDefault( item => item is Row ); - - return null; - } - - internal static void SetRowValidationErrorOnException( Row row, Exception exception ) - { - Debug.Assert( ( row != null ) && ( exception != null ) ); - - // This method will set a validation error on the row and throw back a DataGridValidationException so that the row stays in edition. - - if( exception is TargetInvocationException ) - { - exception = exception.InnerException; - } - - row.SetValidationError( new RowValidationError( Row.CustomRowValidationExceptionValidationRule, row, exception.Message, exception ) ); - - // Throwing a DataGridValidationException will be caught by the grid and will make the cell stay in edition. - throw new DataGridValidationException( "An error occurred while attempting to end the edit process.", exception ); - } - - internal static bool IsCellEditorDisplayConditionsSet( Row row, CellEditorDisplayConditions condition ) - { - return ( ( row.CellEditorDisplayConditions & condition ) == condition ); - } - - internal virtual object GetEditingDataContext() - { - return this.DataContext; - } - - internal void ClearCellsHost() - { - var cellsHost = m_cellsHostPanel as IVirtualizingCellsHost; - if( cellsHost == null ) - return; - - cellsHost.ClearCellsHost(); - } - - internal void UpdateCellsContentBindingTarget() - { - // We need to refresh the Cell.Content target binding in case the dataObject value was coerced to something else. - foreach( Cell cell in this.CreatedCells ) - { - cell.UpdateContentBindingTarget(); - } - } - - internal void UpdateHasErrorFlags( Cell errorChangedCell ) - { - System.Diagnostics.Debug.Assert( ( errorChangedCell == null ) || ( errorChangedCell.ParentRow == this ) ); - - RowValidationError itemValidationError = this.ValidationError; - - bool rowHasValidationError = ( itemValidationError != null ); - bool rowHasRestrictiveValidationError = ( rowHasValidationError ) ? Row.GetIsValidationErrorRestrictive( itemValidationError ) : false; - - if( ( !rowHasRestrictiveValidationError ) && ( errorChangedCell != null ) ) - { - // We must check the passed cell since it might not yet be part of the row's Cells collection. - // This can occur when initializing a cell and its Content binding already has a ValidationError. - if( errorChangedCell.HasValidationError ) - { - rowHasValidationError = true; - - if( errorChangedCell.IsValidationErrorRestrictive ) - { - rowHasRestrictiveValidationError = true; - } - } - - if( !rowHasRestrictiveValidationError ) - { - // Create a clone of the list to avoid concurrent access when iterating and a Cell is added to CreatedCells because of ColumnVirtualization - List createdCells = new List( this.CreatedCells ); - - foreach( Cell cell in createdCells ) - { - if( cell == errorChangedCell ) - continue; - - if( cell.HasValidationError ) - { - rowHasValidationError = true; - - if( cell.IsValidationErrorRestrictive ) - { - rowHasRestrictiveValidationError = true; - break; - } - } - } - } - } - - this.SetHasValidationError( rowHasValidationError ); - this.SetIsValidationErrorRestrictive( rowHasRestrictiveValidationError ); - - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - DataGridControl gridControl = ( dataGridContext != null ) ? dataGridContext.DataGridControl : null; - - if( gridControl != null ) - { - bool gridHasValidationError = rowHasValidationError; - - if( !gridHasValidationError ) - { - var generator = gridControl.CustomItemContainerGenerator; - foreach( var item in generator.GetRealizedDataItems() ) - { - var row = gridControl.GetContainerFromItem( item ) as Row; - - if( ( row != null ) && ( row.HasValidationError ) ) - { - gridHasValidationError = true; - break; - } - } - } - - gridControl.SetHasValidationError( gridHasValidationError ); - } - } - - internal virtual bool IsEditTriggerSet( EditTriggers triggers ) - { - return ( ( this.EditTriggers & triggers ) == triggers ); - } - - internal Cell PrepareUnbindedCell( ColumnBase column, Cell cell ) - { - if( column == null ) - return cell; - - var dataGridContext = DataGridControl.GetDataGridContext( this ); - - if( dataGridContext == null ) - return null; - - //Generate a cell if it was not provided in xaml - if( cell == null ) - { - cell = this.CreateCell( column ); - - // Make sure to add the cell to the VisualTree right away, so the binding engine works correctly when initializing the cell. - this.AddToVisualTree( cell ); - } - - cell.PrepareDefaultStyleKey( dataGridContext.DataGridControl.GetView() ); - cell.Initialize( dataGridContext, this, column ); - cell.PrepareContainer( dataGridContext, this.DataContext ); - - //This is like doing a Measure/Arrange pass, in the sens that first time scrolling will be faster because the cell is ready to be displayed. - cell.ApplyTemplate(); - - //This is an out of view cell, it needs to be treated as such. However, no need to add the cell's fieldName to the FixedCellPanel.PermanentScrollingFieldNames, - //for FixedCellPanel.UpdateChildren() will take care of it in the next layout pass. - cell.Visibility = Visibility.Collapsed; - cell.RemoveContentBinding(); - - return cell; - } - - internal Cell ProvideCell( ColumnBase column ) - { - var dataGridContext = DataGridControl.GetDataGridContext( this ); - Cell cell = null; - - // First verify if there is a corresponding Cell that has been explicitly positioned in the row template. - var fieldName = column.FieldName; - if( fieldName != null ) - { - m_templateCells.TryGetValue( fieldName, out cell ); - } - - // If no template cell provided, create one and set it up. - if( cell == null ) - { - cell = this.CreateCell( column ); - - // Make sure to add the cell to the VisualTree right away, so the binding engine works correctly when initializing the cell. - this.AddToVisualTree( cell ); - } - - cell.PrepareDefaultStyleKey( dataGridContext.DataGridControl.GetView() ); - - //The rest of the preparation of the cell must be done by the caller. - return cell; - } - - internal void AddToVisualTree( Cell cell ) - { - var virtualizingCellsHost = m_cellsHostPanel as IVirtualizingCellsHost; - if( ( virtualizingCellsHost != null ) && ( virtualizingCellsHost.CanModifyLogicalParent ) ) - { - virtualizingCellsHost.SetLogicalParent( cell ); - } - else if( ( virtualizingCellsHost == null ) && ( m_cellsHostPanel != null ) ) - { - m_cellsHostPanel.Children.Add( cell ); - } - } - - internal void RemoveFromVisualTree( Cell cell ) - { - IVirtualizingCellsHost virtualizingCellsHost = m_cellsHostPanel as IVirtualizingCellsHost; - - if( ( virtualizingCellsHost != null ) && ( virtualizingCellsHost.CanModifyLogicalParent ) ) - { - virtualizingCellsHost.ClearLogicalParent( cell ); - } - else if( ( virtualizingCellsHost == null ) && ( m_cellsHostPanel != null ) ) - { - m_cellsHostPanel.Children.Remove( cell ); - } - } - - internal void RefreshCellsDisplayedTemplate() - { - // We never want to update the cell's template while clearing container - if( this.IsClearingContainer ) - return; - - // In case a value was explicitly specified on the Cell's ParentColumn - foreach( Cell cell in this.CreatedCells ) - { - cell.RefreshDisplayedTemplate(); - } - } - - internal virtual HashedLinkedList GetColumnsByVisiblePosition( DataGridContext dataGridContext ) - { - return dataGridContext.ColumnsByVisiblePosition; - } - - private static bool GetIsValidationErrorRestrictive( RowValidationError validationError ) - { - if( validationError == null ) - return false; - - return !( validationError.RuleInError is DataErrorValidationRule ); - } - - private static bool IsPartOfFixedColumnSplitter( DependencyObject element ) - { - DependencyObject parent = TreeHelper.GetParent( element ); - - while( parent != null ) - { - // It is not necessary to go further than the Row. - if( parent is Row ) - break; - - parent = TreeHelper.GetParent( parent ); - } - - return false; - } - - private static IDisposable DeferCollectionViewRefresh( DataGridContext dataGridContext ) - { - if( dataGridContext == null ) - return null; - - return dataGridContext.Items.DeferRefresh(); - } - - private void PrepareVirtualizingCellsHost( DataGridContext dataGridContext, IVirtualizingCellsHost virtualizingCellsHost ) - { - if( dataGridContext == null ) - return; - - // Ensure to register to the TableViewColumnVirtualizationManager - virtualizingCellsHost.PrepareCellsHost( dataGridContext ); - - // We force an InvalidateMeasure on the CellsHost to be sure the visible Cells are the good ones - virtualizingCellsHost.InvalidateCellsHostMeasure(); - } - - private void UpdateMatchingDisplayConditions() - { - CellEditorDisplayConditions newEffectiveValue = CellEditorDisplayConditions.None; - - if( ( Row.IsCellEditorDisplayConditionsSet( this, CellEditorDisplayConditions.RowIsBeingEdited ) ) && - ( this.IsBeingEdited ) ) - { - newEffectiveValue |= CellEditorDisplayConditions.RowIsBeingEdited; - } - - if( ( Row.IsCellEditorDisplayConditionsSet( this, CellEditorDisplayConditions.MouseOverRow ) ) && - ( this.IsMouseOver ) ) - { - newEffectiveValue |= CellEditorDisplayConditions.MouseOverRow; - } - - if( ( Row.IsCellEditorDisplayConditionsSet( this, CellEditorDisplayConditions.RowIsCurrent ) ) && - ( this.IsCurrent ) ) - { - newEffectiveValue |= CellEditorDisplayConditions.RowIsCurrent; - } - - if( Row.IsCellEditorDisplayConditionsSet( this, CellEditorDisplayConditions.Always ) ) - { - newEffectiveValue |= CellEditorDisplayConditions.Always; - } - - this.SetValue( Row.RowDisplayEditorMatchingConditionsProperty, newEffectiveValue ); - } - - private Cell GetCellForCurrentColumn() - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - if( dataGridContext == null ) - return null; - - return m_cellsCache[ dataGridContext.CurrentColumn ]; - } - - private void UpdateNavigationBehavior() - { - DataGridContext context = DataGridControl.GetDataGridContext( this ); - - // We check if the container has an Item binded to it and if - // it's not the case, we don't need to update the navigation - // mode since it has already been changed to None by the - // PrepareIsTabStop of the TableViewItemsHost class. - if( ( context == null ) - || ( context.GetItemFromContainer( this ) == null ) ) - { - return; - } - - bool rowFocusable = false; - KeyboardNavigationMode tabNavigation = KeyboardNavigationMode.None; - KeyboardNavigationMode keyboardNavigation = KeyboardNavigationMode.None; - - FrameworkElement focusItem = this.RowFocusRoot; - - bool isKeyboardFocused = ( focusItem != null ) ? focusItem.IsKeyboardFocused : this.IsKeyboardFocused; - - //do not want to update the navigation behavior of the row if i'm currently editing - if( !this.IsBeingEdited ) - { - if( !this.IsCurrent ) - { - rowFocusable = ( this.NavigationBehavior != NavigationBehavior.None ); - tabNavigation = KeyboardNavigationMode.None; - keyboardNavigation = KeyboardNavigationMode.None; - } - else - { - switch( this.NavigationBehavior ) - { - case NavigationBehavior.None: - rowFocusable = false; - tabNavigation = KeyboardNavigationMode.None; - keyboardNavigation = KeyboardNavigationMode.None; - break; - - case NavigationBehavior.RowOnly: - rowFocusable = true; - tabNavigation = KeyboardNavigationMode.None; - keyboardNavigation = KeyboardNavigationMode.None; - break; - - case NavigationBehavior.RowOrCell: - //There is an identified weakness with the IsKeyboardFocusWithin property where it cannot tell if the focus is within a Popup which is within the element - //This has been identified, and only the places where it caused problems were fixed... This comment is only here to remind developpers of the flaw - if( ( this.IsKeyboardFocusWithin ) && ( !isKeyboardFocused ) ) - { - rowFocusable = false; - tabNavigation = KeyboardNavigationMode.None; //for case 99719: modified this to disable the Tab navigation between cells. - keyboardNavigation = KeyboardNavigationMode.Continue; - } - else - { - rowFocusable = true; - tabNavigation = KeyboardNavigationMode.None; - keyboardNavigation = KeyboardNavigationMode.None; - } - break; - - case NavigationBehavior.CellOnly: - rowFocusable = false; - tabNavigation = KeyboardNavigationMode.None; - keyboardNavigation = KeyboardNavigationMode.Continue; - break; - } - } - } - else - { - rowFocusable = true; - tabNavigation = KeyboardNavigationMode.Cycle; - keyboardNavigation = KeyboardNavigationMode.Continue; - } - - if( focusItem != null ) - { - this.Focusable = false; - KeyboardNavigation.SetTabNavigation( this, KeyboardNavigationMode.None ); - KeyboardNavigation.SetDirectionalNavigation( this, KeyboardNavigationMode.Continue ); - - if( focusItem.FocusVisualStyle != this.FocusVisualStyle ) - { - if( focusItem.ReadLocalValue( FrameworkElement.FocusVisualStyleProperty ) == DependencyProperty.UnsetValue ) - { - focusItem.FocusVisualStyle = this.FocusVisualStyle; - } - } - - focusItem.Focusable = rowFocusable; - KeyboardNavigation.SetTabNavigation( focusItem, tabNavigation ); - KeyboardNavigation.SetDirectionalNavigation( focusItem, keyboardNavigation ); - } - else - { - this.Focusable = rowFocusable; - KeyboardNavigation.SetTabNavigation( this, tabNavigation ); - KeyboardNavigation.SetDirectionalNavigation( this, keyboardNavigation ); - } - } - - private void UpdateCellsFocusableStatus() - { - //cycle through cells in view or those that are permanent (binded cells). - foreach( Cell cell in this.CreatedCells ) - { - //force an update of the NavigationBehavior characteristics - this.UpdateCellFocusableStatus( cell ); - } - } - - private void UpdateCellFocusableStatus( Cell cell ) - { - if( cell == null ) - return; - - var cellFocusable = true; - - if( !this.IsBeingEdited ) - { - switch( this.NavigationBehavior ) - { - case NavigationBehavior.None: - cellFocusable = false; - break; - case NavigationBehavior.RowOnly: - cellFocusable = false; - break; - case NavigationBehavior.RowOrCell: - cellFocusable = true; - break; - case NavigationBehavior.CellOnly: - cellFocusable = true; - break; - } - } - - //force an update of the NavigationBehavior characteristics - cell.Focusable = ( cellFocusable && cell.GetCalculatedCanBeCurrent() ); - } - - private void RestoreEditionState( RowState savedState, ColumnBase currentColumn ) - { - if( savedState == null ) - return; - - savedState = savedState.Clone(); - - Dictionary cachedCellStates = new Dictionary(); - - foreach( Cell cell in this.CreatedCells ) - { - ColumnBase parentColumn = cell.ParentColumn; - - if( parentColumn == null ) - continue; - - var currentRowInEditionCellState = parentColumn.CurrentRowInEditionCellState; - - if( currentRowInEditionCellState != null ) - { - cachedCellStates.Add( parentColumn, currentRowInEditionCellState.Clone() ); - } - } - - try - { - this.BeginEdit(); - } - catch( DataGridException ) - { - // We swallow exception if it occurs because of a validation error or Cell was read-only or - // any other GridException. - } - - if( this.IsBeingEdited ) - { - this.SetValidationError( savedState.ItemValidationError ); - - this.SetIsDirty( savedState.IsDirty ); - - foreach( Cell cell in this.CreatedCells ) - { - ColumnBase parentColumn = cell.ParentColumn; - - if( parentColumn == null ) - continue; - - CellState cachedCellState; - - if( cachedCellStates.TryGetValue( parentColumn, out cachedCellState ) ) - { - parentColumn.CurrentRowInEditionCellState = cachedCellState; - } - - cell.RestoreEditionState( currentColumn ); - } - } - } - - private void PrepareNonVirtualizingCellsHost() - { - var dataGridContext = DataGridControl.GetDataGridContext( this ); - if( dataGridContext == null ) - return; - - if( m_cellsHostPanel == null ) - return; - - var cellsHostCollection = m_cellsHostPanel.Children; - - // Fill the cellsHostPanel in visible order. - foreach( var column in this.GetColumnsByVisiblePosition( dataGridContext ) ) - { - //Cells will be created (if non-existing, via Row.ProvideCell()), initialized, and prepared through this call, including template cells. - var cell = m_cellsCache[ column ]; - - // An existing cell may not be in the VisualTree anymore, since m_cellsHostPanel.Children was just cleared in calling method. - if( !cellsHostCollection.Contains( cell ) && ( ( cell.FieldName == null ) || !m_templateCells.ContainsKey( cell.FieldName ) ) ) - { - cellsHostCollection.Add( cell ); - } - } - } - - private void GetTemplateCells( Visual root, Dictionary templateCells ) - { - int childrenCount = VisualTreeHelper.GetChildrenCount( root ); - - if( childrenCount > 0 ) - { - Visual child = null; - Cell cell = null; - - for( int i = 0; i < childrenCount; i++ ) - { - child = VisualTreeHelper.GetChild( root, i ) as Visual; - - if( child != null ) - { - cell = child as Cell; - - if( cell == null ) - { - this.GetTemplateCells( child, templateCells ); - } - else - { - //if the cell is of the appropriate type for the Row, then ... - if( this.IsValidCellType( cell ) ) - { - //mark the Cell as a Fixed Tempalte Cell. - Row.SetIsTemplateCell( cell, true ); - - templateCells.Add( cell.FieldName, cell ); - } - - //if the cell is not of the appropriate type, don't do anything, it will remain blank. - } - } - } - } - else - { - Visual child = null; - ContentControl contentControl = root as ContentControl; - - if( contentControl == null ) - { - ContentPresenter contentPresenter = root as ContentPresenter; - - if( contentPresenter != null ) - { - child = contentPresenter.Content as Visual; - } - } - else - { - child = contentControl.Content as Visual; - } - - //avoid recursing into a Row object... that can only mean that the Row object is the data item for the Row (self contained, unbound). - if( ( child != null ) && ( ( child is Row ) == false ) ) - { - Cell cell = child as Cell; - - if( cell == null ) - { - this.GetTemplateCells( child, templateCells ); - } - else - { - //mark the Cell as a Fixed Tempalte Cell. - Row.SetIsTemplateCell( cell, true ); - - templateCells.Add( cell.FieldName, cell ); - } - } - } - } - - private void RemovePreviousTemplateCells() - { - List removeList = new List(); - - //cycle through all the cells, and if any of them have the attached property identifying them as Fixed Template Cells, then clear their FieldName property - foreach( Cell cell in this.CreatedCells ) - { - if( Row.GetIsTemplateCell( cell ) ) - { - removeList.Add( cell ); - } - } - - foreach( Cell removedCell in removeList ) - { - removedCell.ClearContainer(); - m_cellsCache.InternalRemove( removedCell ); - } - } - - private void SynchronizeCellsWithColumns( DataGridControl parentGrid, Dictionary templateCells, bool onlyIfParentGridHasChanged ) - { - if( ( !onlyIfParentGridHasChanged ) || ( parentGrid != m_parentGridUsedForCellsGeneration ) ) - { - var dataGridContext = DataGridControl.GetDataGridContext( this ); - - if( dataGridContext == null ) - return; - - this.GenerateMissingAndRemoveUnusedCells( dataGridContext, dataGridContext.Columns, templateCells ); - m_parentGridUsedForCellsGeneration = parentGrid; - } - } - - private void GenerateMissingAndRemoveUnusedCells( DataGridContext dataGridContext, ColumnCollection columns, Dictionary templateCells ) - { - Hashtable cellsDictionary = new Hashtable(); - - //Take each and every cells already created and place them in a dictionary. - //This dictionary will be used to manage cells that need to be removed at the end of the method's body. - foreach( Cell cell in this.CreatedCells ) - { - cellsDictionary.Add( cell.FieldName, cell ); - } - - ColumnBase currentColumn = dataGridContext.CurrentColumn; - bool rowIsCurrent = this.IsCurrent; - - Xceed.Wpf.DataGrid.Views.ViewBase view = dataGridContext.DataGridControl.GetView(); - - foreach( ColumnBase column in columns ) - { - string fieldName = column.FieldName; - Cell cell = null; - - //Try to get the Template Cell defined for this column - templateCells.TryGetValue( fieldName, out cell ); - - //The cell has been found in the template cells, simply prepare it, no need to add it to the VirtualizingCellCollection - if( cell != null ) - { - cell.Initialize( dataGridContext, this, column ); - - // Ensure to prepare a Cell if it is not prepared or virtualized - if( !cell.IsContainerPrepared || cell.IsContainerVirtualized ) - { - cell.PrepareContainer( dataGridContext, this.DataContext ); - } - - //finally, if the Row is current and the column in question is current, set the Currency state on the template cell. - if( ( rowIsCurrent ) && ( column == currentColumn ) ) - { - cell.SetIsCurrent( true ); - } - } - //The cell is not part of the Template Cells... But it still needs some work to be done. - else - { - if( !m_cellsCache.TryGetBindedCell( column, out cell ) ) - { - cell = null; - } - } - - //the cell is a template cell OR is already present in the Row - if( cell != null ) - { - //To ensure that the DefaultStyleKey is set appropriatly - cell.PrepareDefaultStyleKey( view ); - } - - //Remove the Column's FieldName from the dictionary of Cells to remove. This is to prevent the removal of the cell in the cleanup code below. - cellsDictionary.Remove( fieldName ); - } - - // clean unmatched cells - foreach( Cell cell in cellsDictionary.Values ) - { - cell.ClearContainer(); - m_cellsCache.InternalRemove( cell ); - } - } - - #region EDITION - - public static readonly RoutedEvent EditBeginningEvent = EventManager.RegisterRoutedEvent( "EditBeginning", RoutingStrategy.Bubble, typeof( CancelRoutedEventHandler ), typeof( Row ) ); - public static readonly RoutedEvent EditBegunEvent = EventManager.RegisterRoutedEvent( "EditBegun", RoutingStrategy.Bubble, typeof( RoutedEventHandler ), typeof( Row ) ); - - #region IsBeginningEditFromCell Property - - internal bool IsBeginningEditFromCell - { - get - { - return m_flags[ ( int )RowFlags.IsBeginningEditFromCell ]; - } - set - { - m_flags[ ( int )RowFlags.IsBeginningEditFromCell ] = value; - } - } - - #endregion - - #region IsBeginningEdition Property - - internal bool IsBeginningEdition - { - get - { - return m_flags[ ( int )RowFlags.IsBeginningEdition ]; - } - private set - { - m_flags[ ( int )RowFlags.IsBeginningEdition ] = value; - } - } - - #endregion - - #region IsEndingEdition Property - - internal bool IsEndingEdition - { - get - { - return m_flags[ ( int )RowFlags.IsEndingEdition ]; - } - private set - { - m_flags[ ( int )RowFlags.IsEndingEdition ] = value; - } - } - - #endregion - - #region IsCancelingEdition Property - - internal bool IsCancelingEdition - { - get - { - return m_flags[ ( int )RowFlags.IsCancelingEdition ]; - } - private set - { - m_flags[ ( int )RowFlags.IsCancelingEdition ] = value; - } - } - - #endregion - - #region IsBeingEditedCache Property - - private bool IsBeingEditedCache - { - get - { - return m_flags[ ( int )RowFlags.IsBeingEditedCache ]; - } - set - { - m_flags[ ( int )RowFlags.IsBeingEditedCache ] = value; - } - } - - #endregion - - public event CancelRoutedEventHandler EditBeginning - { - add - { - base.AddHandler( Row.EditBeginningEvent, value ); - } - remove - { - base.RemoveHandler( Row.EditBeginningEvent, value ); - } - } - - public event RoutedEventHandler EditBegun - { - add - { - base.AddHandler( Row.EditBegunEvent, value ); - } - remove - { - base.RemoveHandler( Row.EditBegunEvent, value ); - } - } - - protected internal virtual void OnEditBeginning( CancelRoutedEventArgs e ) - { - this.RaiseEvent( e ); - } - - protected internal virtual void OnEditBegun() - { - RoutedEventArgs e = new RoutedEventArgs( Row.EditBegunEvent, this ); - this.RaiseEvent( e ); - } - - public void BeginEdit() - { - if( this.IsBeingEdited ) - return; - - // If there is no dataItem mapped to this container, we don't want to enter in edition - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - if( dataGridContext != null ) - { - object dataItem = dataGridContext.GetItemFromContainer( this ); - - if( dataItem == null ) - return; - } - - // We must prevent entering in edition of an EmptyDataItem. - if( this.DataContext is EmptyDataItem ) - return; - - Debug.Assert( this.IsContainerPrepared, "Can't edit a container that has not been prepared." ); - - //A cell can be editable will the row of the grid is not. - if( this.ReadOnly && !this.IsBeginningEditFromCell ) - throw new DataGridException( "An attempt was made to edit a read-only row." ); - - if( this.IsBeginningEdition ) - throw new DataGridException( "An attempt was made to edit a row for which the edit process has already begun." ); - - this.IsBeginningEdition = true; - - try - { - if( !this.IsBeginningEditFromCell ) - { - CancelRoutedEventArgs e = new CancelRoutedEventArgs( Row.EditBeginningEvent, this ); - this.OnEditBeginning( e ); - - if( e.Cancel ) - throw new DataGridException( "BeginEdit was canceled." ); - } - - // We must update the CellStates before calling BeginEditCore to ensure we have the values that are currently present in the Cells before entering in edition. - DataGridControl gridControl = ( dataGridContext != null ) ? dataGridContext.DataGridControl : null; - - // This call will also validate that we're not starting a second row edition. It will also save the row state and update the columns' CurrentRowInEditionCellState. - if( gridControl != null ) - { - gridControl.UpdateCurrentRowInEditionCellStates( this, this.GetEditingDataContext() ); - } - - this.SetIsBeingEdited( true ); - - try - { - this.BeginEditCore(); - } - catch - { - this.SetIsBeingEdited( false ); - - // Ensure to clear the CellStates - if( gridControl != null ) - { - gridControl.UpdateCurrentRowInEditionCellStates( null, null ); - } - - throw; - } - } - finally - { - this.IsBeginningEdition = false; - } - - if( !this.IsBeginningEditFromCell ) - { - this.OnEditBegun(); - } - } - - protected virtual void BeginEditCore() - { - if( this.IsBeginningEditFromCell ) - return; - - Cell currentCell = this.GetCellForCurrentColumn(); - - try - { - if( currentCell != null ) - { - if( !currentCell.IsBeingEdited ) - { - currentCell.BeginEdit(); - } - } - else - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - if( dataGridContext != null ) - { - int firstEditableColumn = NavigationHelper.GetFirstVisibleFocusableColumnIndex( dataGridContext ); - if( firstEditableColumn < 0 ) - throw new DataGridException( "Trying to edit while no cell is focusable. " ); - - currentCell = m_cellsCache[ dataGridContext.VisibleColumns[ firstEditableColumn ] ]; - - if( currentCell != null ) - { - currentCell.BeginEdit(); - } - } - } - } - catch( DataGridException ) - { - // We swallow exception if it occurs because of a validation error or Cell was read-only or any other GridException. - } - } - - public static readonly RoutedEvent EditEndingEvent = EventManager.RegisterRoutedEvent( "EditEnding", RoutingStrategy.Bubble, typeof( CancelRoutedEventHandler ), typeof( Row ) ); - public static readonly RoutedEvent EditEndedEvent = EventManager.RegisterRoutedEvent( "EditEnded", RoutingStrategy.Bubble, typeof( RoutedEventHandler ), typeof( Row ) ); - - public event CancelRoutedEventHandler EditEnding - { - add - { - base.AddHandler( Row.EditEndingEvent, value ); - } - remove - { - base.RemoveHandler( Row.EditEndingEvent, value ); - } - } - - public event RoutedEventHandler EditEnded - { - add - { - base.AddHandler( Row.EditEndedEvent, value ); - } - remove - { - base.RemoveHandler( Row.EditEndedEvent, value ); - } - } - - protected virtual void OnEditEnding( CancelRoutedEventArgs e ) - { - this.RaiseEvent( e ); - } - - protected virtual void OnEditEnded() - { - RoutedEventArgs e = new RoutedEventArgs( Row.EditEndedEvent, this ); - this.RaiseEvent( e ); - } - - public void EndEdit() - { - if( !this.IsBeingEdited ) - return; - - if( this.IsEndingEdition ) - throw new InvalidOperationException( "An attempt was made to end the edit process while it is already in the process of being ended." ); - - if( this.IsCancelingEdition ) - throw new InvalidOperationException( "An attempt was made to end the edit process while it is being canceled." ); - - var e = new CancelRoutedEventArgs( Row.EditEndingEvent, this ); - - try - { - this.OnEditEnding( e ); - - if( e.Cancel ) - throw new DataGridValidationException( "EndEdit was canceled." ); - } - catch( Exception exception ) - { - // This method will set a validation error on the row and throw back a DataGridValidationException so that the row stays in edition. - Row.SetRowValidationErrorOnException( this, exception ); - } - - this.IsEndingEdition = true; - - try - { - var dataGridContext = DataGridControl.GetDataGridContext( this ); - if( dataGridContext == null ) - { - Debug.Fail( "DataGridContext cannot be null." ); - return; - } - - var dataGridCollectionViewBase = dataGridContext.ItemsSourceCollection as DataGridCollectionViewBase; - var deferRefresh = ( ( dataGridCollectionViewBase != null ) ) ? Row.DeferCollectionViewRefresh( dataGridContext ) : null; - - try - { - this.EndEditCore(); - this.TerminateEditionFromEndEdit(); - } - finally - { - if( deferRefresh != null ) - { - // If there is a validation error, deferRefresh.Dispose() may clear the current error. Be sure to keep it in order to restore it if needed. - var hasValidationError = this.ReadLocalValue( Row.HasValidationErrorProperty ); - var validationError = this.ReadLocalValue( Row.ValidationErrorProperty ); - - deferRefresh.Dispose(); - - if( hasValidationError != DependencyProperty.UnsetValue ) - { - // This will use the PropertyKey. - this.SetHasValidationError( ( bool )hasValidationError ); - } - - if( validationError != DependencyProperty.UnsetValue ) - { - this.SetValidationError( ( RowValidationError )validationError ); - } - } - } - - this.PreEditEnded(); - - // Item validation has passed if we reached this far. Since it is the Row's HasValidationError which drives the error styles, - // setting the ItemValidationError to null will not get in the way of the row's cells validation. - this.SetValidationError( null ); - - } - finally - { - this.IsEndingEdition = false; - } - - this.OnEditEnded(); - } - - private void TerminateEditionFromEndEdit() - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - DataGridControl gridControl = ( dataGridContext != null ) - ? dataGridContext.DataGridControl - : null; - - // Lower IsDirty flags. - foreach( Cell cell in this.CreatedCells ) - { - cell.SetIsDirty( false ); - } - - this.SetIsDirty( false ); - - // Reset current row in edition. - if( gridControl != null ) - { - gridControl.UpdateCurrentRowInEditionCellStates( null, null ); - } - - this.SetIsBeingEdited( false ); - - this.UpdateCellsContentBindingTarget(); - - if( ( this.NavigationBehavior == NavigationBehavior.RowOnly ) && ( this.IsCurrent ) ) - { - if( gridControl != null ) - { - gridControl.QueueClearCurrentColumn( gridControl.CurrentItem ); - } - } - } - - internal virtual void PreEditEnded() - { - } - - protected virtual void EndEditCore() - { - bool hasRestrictiveError = false; - - // Create a clone of the list to avoid concurrent access when iterating and a Cell is added to CreatedCells because of ColumnVirtualization - var createdCells = new List(); - - Cell editCell = null; - - foreach( var cell in this.CreatedCells ) - { - createdCells.Add( cell ); - - if( cell.IsBeingEdited ) - { - editCell = cell; - } - } - - if( editCell != null ) - { - try - { - editCell.EndEdit( true, true, true ); - hasRestrictiveError = hasRestrictiveError || Cell.GetIsValidationErrorRestrictive( editCell.ValidationError ); - } - catch( DataGridValidationException ) - { - hasRestrictiveError = true; - } - } - - foreach( Cell cell in createdCells ) - { - if( cell == editCell ) - continue; - - var contentBindingUpdateSourceTrigger = cell.GetContentBindingUpdateSourceTrigger(); - var updateContentBindingSource = ( contentBindingUpdateSourceTrigger == DataGridUpdateSourceTrigger.RowEndingEdit ); - var cascadeValidate = updateContentBindingSource; - Exception exception; - CellValidationRule ruleInError; - - var result = cell.ValidateAndSetAllErrors( true, true, updateContentBindingSource, cascadeValidate, out exception, out ruleInError ); - - if( ( !result.IsValid ) && ( Cell.GetIsRuleInErrorRestrictive( ruleInError ) ) ) - { - hasRestrictiveError = true; - } - } - - // Throwing a DataGridValidationException will be caught by the grid and will make the cell stay in edition. - if( hasRestrictiveError ) - throw new DataGridValidationException( "Row.EndEdit cannot complete because the cell content is invalid." ); - } - - public static readonly RoutedEvent EditCancelingEvent = EventManager.RegisterRoutedEvent( "EditCanceling", RoutingStrategy.Bubble, typeof( RoutedEventHandler ), typeof( Row ) ); - public static readonly RoutedEvent EditCanceledEvent = EventManager.RegisterRoutedEvent( "EditCanceled", RoutingStrategy.Bubble, typeof( RoutedEventHandler ), typeof( Row ) ); - - public event RoutedEventHandler EditCanceling - { - add - { - base.AddHandler( Row.EditCancelingEvent, value ); - } - remove - { - base.RemoveHandler( Row.EditCancelingEvent, value ); - } - } - - public event RoutedEventHandler EditCanceled - { - add - { - base.AddHandler( Row.EditCanceledEvent, value ); - } - remove - { - base.RemoveHandler( Row.EditCanceledEvent, value ); - } - } - - protected virtual void OnEditCanceling() - { - RoutedEventArgs e = new RoutedEventArgs( Row.EditCancelingEvent, this ); - this.RaiseEvent( e ); - } - - protected virtual void OnEditCanceled() - { - RoutedEventArgs e = new RoutedEventArgs( Row.EditCanceledEvent, this ); - this.RaiseEvent( e ); - } - - public void CancelEdit() - { - this.CancelEdit( false ); - } - - internal void CancelEdit( bool forceCancelEdit ) - { - if( !this.IsBeingEdited ) - return; - - if( this.IsCancelingEdition ) - throw new InvalidOperationException( "An attempt was made to cancel the edit process while it is already in the process of being canceled." ); - - if( ( !forceCancelEdit ) && ( this.IsEndingEdition ) ) - throw new InvalidOperationException( "An attempt was made to cancel the edit process while it is being ended." ); - - this.OnEditCanceling(); - this.IsCancelingEdition = true; - - try - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - IDisposable deferRefresh = null; - - if( dataGridContext != null ) - { - deferRefresh = ( ( this is DataRow ) || ( dataGridContext.ItemsSourceCollection is DataGridCollectionViewBase ) ) - ? DataRow.DeferCollectionViewRefresh( dataGridContext ) : null; - } - - try - { - this.CancelEditCore(); - this.TerminateEditionFromCancelEdit(); - } - finally - { - if( deferRefresh != null ) - { - deferRefresh.Dispose(); - } - } - - this.PreEditCanceled(); - - // A row cannot have an ItemValidationError when not being edited. Since it is the Row's HasValidationError which drives the error styles, - // setting the ItemValidationError to null will not get in the way of the row's cells validation. - this.SetValidationError( null ); - - } - finally - { - this.IsCancelingEdition = false; - } - - this.OnEditCanceled(); - } - - private void TerminateEditionFromCancelEdit() - { - this.SetIsDirty( false ); - - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - DataGridControl gridControl = ( dataGridContext != null ) - ? dataGridContext.DataGridControl - : null; - - if( gridControl != null ) - { - gridControl.UpdateCurrentRowInEditionCellStates( null, null ); - } - - this.SetIsBeingEdited( false ); - - if( ( this.NavigationBehavior == NavigationBehavior.RowOnly ) - && ( this.IsCurrent ) ) - { - if( gridControl != null ) - { - gridControl.QueueClearCurrentColumn( gridControl.CurrentItem ); - } - } - } - - internal virtual void PreEditCanceled() - { - } - - protected virtual void CancelEditCore() - { - // Restore the Cell.Content - foreach( var cell in this.CreatedCells ) - { - if( cell.IsBeingEdited ) - { - cell.CancelEdit(); - } - - cell.RevertEditedValue(); - } - -#if DEBUG - foreach( var cell in this.CreatedCells ) - { - Debug.Assert( Cell.GetIsValidationErrorRestrictive( cell.ValidationError ) == false ); - } -#endif - } - - #endregion EDITION - - #region DP CHANGED HANDLERS - - private static void OnIsBeingEditedChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - Row row = ( Row )sender; - - row.UpdateNavigationBehavior(); - row.UpdateCellsFocusableStatus(); - - //If the current CellEditorDisplayConditions requires display when Row is Editing - if( Row.IsCellEditorDisplayConditionsSet( row, CellEditorDisplayConditions.RowIsBeingEdited ) ) - { - if( ( bool )e.NewValue ) - { - //Display the editors for the Row - row.SetDisplayEditorMatchingCondition( CellEditorDisplayConditions.RowIsBeingEdited ); - } - else - { - //Hide the editors for the Row - row.RemoveDisplayEditorMatchingCondition( CellEditorDisplayConditions.RowIsBeingEdited ); - } - } - - // In case a value was explicitly specified on the Cell's ParentColumn - row.RefreshCellsDisplayedTemplate(); - } - - private static void OnIsCurrentChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - Row row = ( Row )sender; - - if( row == null ) - return; - - // In case a value was explicitly specified on the Cell's ParentColumn - row.RefreshCellsDisplayedTemplate(); - } - - private static void OnCellEditorDisplayConditionsChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - Row obj = ( Row )sender; - - obj.UpdateMatchingDisplayConditions(); - } - - private static void OnNavigationBehaviorChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - Row obj = ( Row )sender; - - obj.UpdateNavigationBehavior(); - obj.UpdateCellsFocusableStatus(); - } - - private static void OnParentGridControlChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - DataGridControl grid = e.NewValue as DataGridControl; - Row row = sender as Row; - - if( ( row != null ) && ( grid != null ) ) - { - row.PrepareDefaultStyleKey( grid.GetView() ); - } - } - - private static void OnCellIsDirty_ClassHandler( object sender, RoutedEventArgs e ) - { - Row row = ( Row )sender; - - row.SetIsDirty( true ); - - e.Source = row; - } - - #endregion DP CHANGED HANDLERS - - #region COMMANDS - - private void OnBeginEditExecuted( object sender, ExecutedRoutedEventArgs e ) - { - try - { - this.BeginEdit(); - } - catch( DataGridException ) - { - // We swallow exception if it occurs because of a validation error or Cell was readonly or - // any other GridException. - } - } - - private void OnBeginEditCanExecute( object sender, CanExecuteRoutedEventArgs e ) - { - - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - DataGridControl parentGrid = ( dataGridContext != null ) - ? dataGridContext.DataGridControl - : null; - - if( parentGrid == null ) - { - e.CanExecute = false; - } - else - { - e.CanExecute = ( !this.IsBeingEdited ) && ( !this.ReadOnly ) - && ( this.IsEditTriggerSet( EditTriggers.BeginEditCommand ) ); - } - } - - private void OnCancelEditExecuted( object sender, ExecutedRoutedEventArgs e ) - { - this.CancelEdit(); - } - - private void OnCancelEditCanExecute( object sender, CanExecuteRoutedEventArgs e ) - { - e.CanExecute = this.IsBeingEdited; - } - - private void OnEndEditExecuted( object sender, ExecutedRoutedEventArgs e ) - { - this.OnEndEditCommandExecutedCore( e ); - } - - internal virtual void OnEndEditCommandExecutedCore( ExecutedRoutedEventArgs e ) - { - try - { - this.EndEdit(); - } - catch( DataGridException ) - { - // We swallow exception if it occurs because of a validation error or Cell was read-only or - // any other GridException. - } - } - - private void OnEndEditCanExecute( object sender, CanExecuteRoutedEventArgs e ) - { - this.OnEndEditCommandCanExecuteCore( e ); - } - - internal virtual void OnEndEditCommandCanExecuteCore( CanExecuteRoutedEventArgs e ) - { - e.CanExecute = this.IsBeingEdited; - } - - #endregion COMMANDS - - #region IDataGridItemContainer Members - - bool IDataGridItemContainer.CanBeRecycled - { - get - { - return this.CanBeRecycled; - } - } - - bool IDataGridItemContainer.IsRecyclingCandidate - { - get - { - return m_isRecyclingCandidate; - } - set - { - m_isRecyclingCandidate = value; - } - } - - void IDataGridItemContainer.PrepareContainer( DataGridContext dataGridContext, object item ) - { - if( m_isRecyclingCandidate ) - { - this.IsContainerPrepared = false; - m_isRecyclingCandidate = false; - } - - if( this.IsContainerPrepared ) - Debug.Fail( "A Row can't be prepared twice, it must be cleaned before PrepareContainer is called again" ); - - this.PrepareContainer( dataGridContext, item ); - } - - void IDataGridItemContainer.ClearContainer() - { - if( m_isRecyclingCandidate ) - { - this.PartialClearContainer(); - return; - } - - this.ClearContainer(); - } - - void IDataGridItemContainer.CleanRecyclingCandidate() - { - this.ClearContainer(); - } - - #endregion - - #region INotifyPropertyChanged Members - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void OnPropertyChanged( string propertyName ) - { - var handler = this.PropertyChanged; - if( handler == null ) - return; - - handler.Invoke( this, new PropertyChangedEventArgs( propertyName ) ); - } - - #endregion - - #region IWeakEventListener Members - - 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 ) - { - return false; - } - - #endregion - - private DataGridControl m_parentGridUsedForCellsGeneration; // = null - private Panel m_cellsHostPanel; // = null - private Dictionary m_templateCells = new Dictionary(); - private List m_oldRegionPresenterConfigs; // = null - private BitVector32 m_flags = new BitVector32(); - private bool m_isRecyclingCandidate; - - #region RegionPresenterConfig Private Class - - private sealed class RegionPresenterConfig - { - public Nullable ReadOnly - { - get; - set; - } - - public Nullable ShowCellTitles - { - get; - set; - } - - public Nullable ImageStretch - { - get; - set; - } - - public Nullable ImageStretchDirection - { - get; - set; - } - - public List FieldNameList - { - get - { - return m_fieldNameList; - } - } - - private List m_fieldNameList = new List(); - } - - #endregion - - #region RowFlags Nested Type - - [Flags] - private enum RowFlags - { - IsBeginningEdition = 1, - IsEndingEdition = 2, - IsCancelingEdition = 4, - IsBeginningEditFromCell = 8, - IsBeingEditedCache = 16, - IsClearingContainer = 32, - IsContainerPrepared = 64, - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/RowSelector.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/RowSelector.cs deleted file mode 100644 index 4c6ce82e..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/RowSelector.cs +++ /dev/null @@ -1,760 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Controls.Primitives; -using System.Windows.Data; -using System.Windows.Input; -using Xceed.Wpf.DataGrid.Views; - -namespace Xceed.Wpf.DataGrid -{ - [TemplatePart( Name = "PART_RowResizerThumb", Type = typeof( Thumb ) )] - public class RowSelector : ContentControl, INotifyPropertyChanged - { - static RowSelector() - { - RowSelector.IsPressedProperty = RowSelector.IsPressedPropertyKey.DependencyProperty; - RowSelector.RowTypeProperty = RowSelector.RowTypePropertyKey.DependencyProperty; - - UIElement.FocusableProperty.OverrideMetadata( typeof( RowSelector ), new FrameworkPropertyMetadata( false ) ); - - DataGridControl.ParentDataGridControlPropertyKey.OverrideMetadata( typeof( RowSelector ), - new FrameworkPropertyMetadata( new PropertyChangedCallback( RowSelector.OnParentGridControlChanged ) ) ); - - m_sDataContextBinding = new Binding(); - m_sDataContextBinding.RelativeSource = new RelativeSource( RelativeSourceMode.Self ); - m_sDataContextBinding.Path = new PropertyPath( DataGridControl.ContainerProperty ); - m_sDataContextBinding.Mode = BindingMode.OneWay; - - m_sItemIndexBinding = new Binding(); - m_sItemIndexBinding.Path = new PropertyPath( DataGridVirtualizingPanel.ItemIndexProperty ); - m_sItemIndexBinding.Mode = BindingMode.OneWay; - - m_sIsCurrentBinding = new Binding(); - m_sIsCurrentBinding.Path = new PropertyPath( Row.IsCurrentProperty ); - m_sIsCurrentBinding.Mode = BindingMode.OneWay; - - m_sIsBeingEditedBinding = new Binding(); - m_sIsBeingEditedBinding.Path = new PropertyPath( Row.IsBeingEditedProperty ); - m_sIsBeingEditedBinding.Mode = BindingMode.OneWay; - - m_sHasValidationErrorBinding = new Binding(); - m_sHasValidationErrorBinding.Path = new PropertyPath( Row.HasValidationErrorProperty ); - m_sHasValidationErrorBinding.Mode = BindingMode.OneWay; - - m_sRowSelectorVisibleBinding = new Binding(); - m_sRowSelectorVisibleBinding.Path = new PropertyPath( RowSelector.VisibleProperty ); - m_sRowSelectorVisibleBinding.Mode = BindingMode.OneWay; - m_sRowSelectorVisibleBinding.Converter = new BooleanToVisibilityConverter(); - m_sRowSelectorVisibleBinding.ConverterParameter = Visibility.Collapsed; - - m_sRowSelectorStyleBinding = new Binding(); - m_sRowSelectorStyleBinding.Path = new PropertyPath( RowSelector.RowSelectorStyleProperty ); - m_sRowSelectorStyleBinding.Mode = BindingMode.OneWay; - - m_sAllowResizeBinding = new Binding(); - m_sAllowResizeBinding.RelativeSource = new RelativeSource( RelativeSourceMode.Self ); - m_sAllowResizeBinding.Path = new PropertyPath( "(0).(1)", DataGridControl.DataGridContextProperty, TableView.AllowRowResizeProperty ); - - m_sAllowResizeBinding.Mode = BindingMode.OneWay; - } - - internal RowSelector() - { - BindingOperations.SetBinding( this, RowSelector.DataContextProperty, m_sDataContextBinding ); - BindingOperations.SetBinding( this, RowSelector.IsCurrentProperty, m_sIsCurrentBinding ); - BindingOperations.SetBinding( this, RowSelector.IsBeingEditedProperty, m_sIsBeingEditedBinding ); - BindingOperations.SetBinding( this, RowSelector.ItemIndexProperty, m_sItemIndexBinding ); - BindingOperations.SetBinding( this, RowSelector.HasValidationErrorProperty, m_sHasValidationErrorBinding ); - BindingOperations.SetBinding( this, RowSelector.VisibilityProperty, m_sRowSelectorVisibleBinding ); - BindingOperations.SetBinding( this, RowSelector.RowSelectorStyleProperty, m_sRowSelectorStyleBinding ); - BindingOperations.SetBinding( this, RowSelector.AllowResizeProperty, m_sAllowResizeBinding ); - } - - #region AllowResize Property - - internal static readonly DependencyProperty AllowResizeProperty = DependencyProperty.Register( - "AllowResize", - typeof( bool ), - typeof( RowSelector ), - new FrameworkPropertyMetadata( true ) ); - - internal bool AllowResize - { - get - { - return ( bool )this.GetValue( RowSelector.AllowResizeProperty ); - } - set - { - this.SetValue( RowSelector.AllowResizeProperty, value ); - } - } - - private bool CanBeResized( Orientation orientation ) - { - if( this.AllowResize ) - { - FrameworkElement rowItem = this.DataContext as FrameworkElement; - if( rowItem != null ) - { - if( orientation == Orientation.Vertical ) - { - object minHeight = rowItem.ReadLocalValue( FrameworkElement.MinHeightProperty ); - object maxHeight = rowItem.ReadLocalValue( FrameworkElement.MaxHeightProperty ); - - if( ( minHeight == DependencyProperty.UnsetValue ) - || ( maxHeight == DependencyProperty.UnsetValue ) - || ( !object.Equals( minHeight, maxHeight ) ) ) - { - return true; - } - } - else - { - object minWidth = rowItem.ReadLocalValue( FrameworkElement.MinWidthProperty ); - object maxWidth = rowItem.ReadLocalValue( FrameworkElement.MaxWidthProperty ); - - if( ( minWidth == DependencyProperty.UnsetValue ) - || ( maxWidth == DependencyProperty.UnsetValue ) - || ( !object.Equals( minWidth, maxWidth ) ) ) - { - return true; - } - } - } - } - - return false; - } - - #endregion AllowResize Property - - #region INotifyPropertyChanged Members - - public event PropertyChangedEventHandler PropertyChanged; - - private void NotifyPropertyChanged( string propertyName ) - { - if( this.PropertyChanged != null ) - { - this.PropertyChanged( this, new PropertyChangedEventArgs( propertyName ) ); - } - } - - #endregion - - #region Orientation Property - - public Orientation Orientation - { - get - { - return ( Orientation )GetValue( OrientationProperty ); - } - set - { - SetValue( OrientationProperty, value ); - } - } - - // Using a DependencyProperty as the backing store for Orientation. This enables animation, styling, binding, etc... - public static readonly DependencyProperty OrientationProperty = - DependencyProperty.Register( "Orientation", typeof( Orientation ), typeof( RowSelector ), new UIPropertyMetadata( Orientation.Vertical ) ); - - #endregion - - #region IsPressed Read-Only Property - - private static readonly DependencyPropertyKey IsPressedPropertyKey = - DependencyProperty.RegisterReadOnly( "IsPressed", typeof( bool ), typeof( RowSelector ), new PropertyMetadata( false ) ); - - public static readonly DependencyProperty IsPressedProperty; - - public bool IsPressed - { - get - { - return ( bool )this.GetValue( RowSelector.IsPressedProperty ); - } - } - - internal void SetIsPressed( bool value ) - { - this.SetValue( RowSelector.IsPressedPropertyKey, value ); - } - - #endregion IsPressed Read-Only Property - - #region IsCurrent - - public static readonly DependencyProperty IsCurrentProperty = DependencyProperty.Register( - "IsCurrent", - typeof( bool ), - typeof( RowSelector ), - new FrameworkPropertyMetadata( false ) ); - - public bool IsCurrent - { - get - { - return ( bool )this.GetValue( IsCurrentProperty ); - } - } - - #endregion - - #region IsBeingEdited - - public static readonly DependencyProperty IsBeingEditedProperty = DependencyProperty.Register( - "IsBeingEdited", - typeof( bool ), - typeof( RowSelector ), - new FrameworkPropertyMetadata( false ) ); - - public bool IsBeingEdited - { - get - { - return ( bool )this.GetValue( IsBeingEditedProperty ); - } - } - - #endregion - - #region ItemIndex - - public static readonly DependencyProperty ItemIndexProperty = DataGridVirtualizingPanel.ItemIndexProperty.AddOwner( typeof( RowSelector ) ); - - public int ItemIndex - { - get - { - return ( int )this.GetValue( ItemIndexProperty ); - } - } - - #endregion - - #region HasValidationError - - public static readonly DependencyProperty HasValidationErrorProperty = DependencyProperty.Register( - "HasValidationError", - typeof( bool ), - typeof( RowSelector ), - new FrameworkPropertyMetadata( false ) ); - - public bool HasValidationError - { - get - { - return ( bool )this.GetValue( HasValidationErrorProperty ); - } - } - - #endregion - - #region RowType - - private static readonly DependencyPropertyKey RowTypePropertyKey = DependencyProperty.RegisterReadOnly( - "RowType", - typeof( Type ), - typeof( RowSelector ), - new FrameworkPropertyMetadata( null ) ); - - public static readonly DependencyProperty RowTypeProperty; - - public Type RowType - { - get - { - return ( Type )this.GetValue( RowSelector.RowTypeProperty ); - } - } - - private void SetRowType( Type value ) - { - this.SetValue( RowSelector.RowTypePropertyKey, value ); - } - - #endregion - - #region ContainerRect - - public static readonly DependencyProperty ContainerRectProperty = DependencyProperty.Register( - "ContainerRect", - typeof( Rect ), - typeof( RowSelector ), - new FrameworkPropertyMetadata( null ) ); - - public Rect ContainerRect - { - get - { - return ( Rect )this.GetValue( ContainerRectProperty ); - } - internal set - { - this.SetValue( ContainerRectProperty, value ); - } - } - - #endregion - - #region Visible Attached Property - - public static readonly DependencyProperty VisibleProperty = DependencyProperty.RegisterAttached( - "Visible", - typeof( bool ), - typeof( RowSelector ), - new FrameworkPropertyMetadata( true ) ); - - public static bool GetVisible( DependencyObject d ) - { - return ( bool )d.GetValue( RowSelector.VisibleProperty ); - } - - public static void SetVisible( DependencyObject d, bool value ) - { - d.SetValue( RowSelector.VisibleProperty, value ); - } - - #endregion - - #region RowSelectorStyle Attached Property - - public static readonly DependencyProperty RowSelectorStyleProperty = DependencyProperty.RegisterAttached( - "RowSelectorStyle", - typeof( Style ), - typeof( RowSelector ), - new FrameworkPropertyMetadata( null, new PropertyChangedCallback( OnRowSelectorStyleChanged ) ) ); - - public static Style GetRowSelectorStyle( DependencyObject obj ) - { - return ( Style )obj.GetValue( RowSelectorStyleProperty ); - } - - public static void SetRowSelectorStyle( DependencyObject obj, Style value ) - { - obj.SetValue( RowSelectorStyleProperty, value ); - } - - private static void OnRowSelectorStyleChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - RowSelector rowSelector = sender as RowSelector; - - //Here, since the property is an Attached propety, the type of sender can be anything, but in this particular case, I want - //to filter out everything but RowSelector since this is my queue to set a local style on the RowSelector ( or clear the local - //value). - if( rowSelector == null ) - return; - - if( e.NewValue == null ) - { - rowSelector.ClearValue( RowSelector.StyleProperty ); - } - else - { - rowSelector.SetValue( RowSelector.StyleProperty, e.NewValue ); - } - } - - #endregion - - #region ReferenceElement Internal Property - - internal static readonly DependencyProperty ReferenceElementProperty = DependencyProperty.Register( - "ReferenceElement", - typeof( FrameworkElement ), - typeof( RowSelector ), - new FrameworkPropertyMetadata( null ) ); - - internal FrameworkElement ReferenceElement - { - get - { - return ( FrameworkElement )this.GetValue( ReferenceElementProperty ); - } - set - { - this.SetValue( ReferenceElementProperty, value ); - } - } - - #endregion - - public override void OnApplyTemplate() - { - base.OnApplyTemplate(); - - this.SetupColumnResizerThumb(); - } - - protected override void OnPropertyChanged( DependencyPropertyChangedEventArgs e ) - { - base.OnPropertyChanged( e ); - - if( e.Property == RowSelector.DataContextProperty ) - { - Type rowType = null; - - Row row = this.DataContext as Row; - if( row != null ) - { - rowType = row.GetType(); - } - else - { - HeaderFooterItem hfi = this.DataContext as HeaderFooterItem; - if( hfi != null ) - { - row = hfi.AsVisual() as Row; - if( row != null ) - { - rowType = row.GetType(); - } - } - } - - this.SetRowType( rowType ); - - } - } - - private static void OnParentGridControlChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - RowSelector rowSelector = ( RowSelector )sender; - DataGridControl newGrid = e.NewValue as DataGridControl; - - if( newGrid != null ) - { - rowSelector.PrepareDefaultStyleKey( newGrid.GetView() ); - } - } - - internal virtual void PrepareDefaultStyleKey( Xceed.Wpf.DataGrid.Views.ViewBase view ) - { - this.DefaultStyleKey = view.GetDefaultStyleKey( typeof( RowSelector ) ); - } - - #region Row Resizer Code - - private void SetupColumnResizerThumb() - { - if( m_rowResizerThumb != null ) - { - m_rowResizerThumb.DragStarted -= new DragStartedEventHandler( m_rowResizerThumb_DragStarted ); - m_rowResizerThumb.DragDelta -= new DragDeltaEventHandler( m_rowResizerThumb_DragDelta ); - m_rowResizerThumb.DragCompleted -= new DragCompletedEventHandler( m_rowResizerThumb_DragCompleted ); - m_rowResizerThumb.QueryCursor -= new QueryCursorEventHandler( m_rowResizerThumb_QueryCursor ); - m_rowResizerThumb.MouseDoubleClick -= new MouseButtonEventHandler( m_rowResizerThumb_MouseDoubleClick ); - - m_rowResizerThumb = null; - } - - m_rowResizerThumb = this.GetTemplateChild( "PART_RowResizerThumb" ) as Thumb; - - if( m_rowResizerThumb != null ) - { - m_rowResizerThumb.DragStarted += new DragStartedEventHandler( m_rowResizerThumb_DragStarted ); - m_rowResizerThumb.DragDelta += new DragDeltaEventHandler( m_rowResizerThumb_DragDelta ); - m_rowResizerThumb.DragCompleted += new DragCompletedEventHandler( m_rowResizerThumb_DragCompleted ); - m_rowResizerThumb.QueryCursor += new QueryCursorEventHandler( m_rowResizerThumb_QueryCursor ); - m_rowResizerThumb.MouseDoubleClick += new MouseButtonEventHandler( m_rowResizerThumb_MouseDoubleClick ); - } - } - - private void m_rowResizerThumb_MouseDoubleClick( object sender, MouseButtonEventArgs e ) - { - FrameworkElement rowItem = ( FrameworkElement )this.DataContext; - - if( rowItem == null ) - return; - - if( !this.CanBeResized( this.Orientation ) ) - return; - - // Resets the row width or height depending on the orientation. - DependencyProperty property = ( this.Orientation == Orientation.Vertical ) ? FrameworkElement.HeightProperty : FrameworkElement.WidthProperty; - - rowItem.ClearValue( property ); - } - - private void m_rowResizerThumb_QueryCursor( object sender, QueryCursorEventArgs e ) - { - FrameworkElement rowItem = ( FrameworkElement )this.DataContext; - - if( rowItem == null ) - return; - - if( this.CanBeResized( this.Orientation ) ) - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - if( dataGridContext != null ) - { - TableView tableView = dataGridContext.DataGridControl.GetView() as TableView; - - e.Cursor = ( ( tableView != null ) && ( this.Orientation == Orientation.Vertical ) ) - ? tableView.RowSelectorResizeNorthSouthCursor - : tableView.RowSelectorResizeWestEastCursor; - } - - if( e.Cursor == null ) - { - e.Cursor = ( this.Orientation == Orientation.Vertical ) ? TableView.DefaultRowSelectorResizeNorthSouthCursor : TableView.DefaultRowSelectorResizeWestEastCursor; - } - } - - e.Handled = true; - } - - private void m_rowResizerThumb_DragStarted( object sender, DragStartedEventArgs e ) - { - if( !this.CanBeResized( this.Orientation ) ) - return; - - FrameworkElement rowItem = ( FrameworkElement )this.DataContext; - - if( rowItem == null ) - return; - - if( this.Orientation == Orientation.Vertical ) - { - m_originalSize = rowItem.ActualHeight; - } - else - { - m_originalSize = rowItem.ActualWidth; - } - } - - private void m_rowResizerThumb_DragDelta( object sender, DragDeltaEventArgs e ) - { - if( !this.CanBeResized( this.Orientation ) ) - return; - - FrameworkElement rowItem = ( FrameworkElement )this.DataContext; - - if( rowItem == null ) - return; - - double newSize; - - if( this.Orientation == Orientation.Vertical ) - { - newSize = rowItem.ActualHeight + e.VerticalChange; - } - else - { - newSize = rowItem.ActualWidth + e.HorizontalChange; - } - - if( newSize < MIN_SIZE ) - { - newSize = MIN_SIZE; - } - - if( this.Orientation == Orientation.Vertical ) - { - if( newSize < rowItem.MinHeight ) - { - newSize = rowItem.MinHeight; - } - else if( newSize > rowItem.MaxHeight ) - { - newSize = rowItem.MaxHeight; - } - - rowItem.Height = newSize; - } - else - { - if( newSize < rowItem.MinWidth ) - { - newSize = rowItem.MinWidth; - } - else if( newSize > rowItem.MaxWidth ) - { - newSize = rowItem.MaxWidth; - } - - rowItem.Width = newSize; - } - } - - private void m_rowResizerThumb_DragCompleted( object sender, DragCompletedEventArgs e ) - { - if( !this.CanBeResized( this.Orientation ) ) - return; - - FrameworkElement rowItem = ( FrameworkElement )this.DataContext; - - if( rowItem == null ) - return; - - if( e.Canceled ) - { - if( this.Orientation == Orientation.Vertical ) - { - rowItem.Height = m_originalSize; - } - else - { - rowItem.Width = m_originalSize; - } - } - - m_originalSize = -1d; - } - - private const double MIN_SIZE = 4d; - - private double m_originalSize = -1d; - private Thumb m_rowResizerThumb; // = null - - #endregion Column Resizer Code - - #region Button Behavior Code - - protected override void OnMouseLeftButtonDown( MouseButtonEventArgs e ) - { - m_isFromMouseButtonDown = true; - - if( this.CaptureMouse() ) - { - this.SetIsPressed( true ); - e.Handled = true; - - FrameworkElement rowItemContainer = this.DataContext as FrameworkElement; - - if( rowItemContainer != null ) - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( rowItemContainer ); - - if( dataGridContext != null ) - { - DataGridControl dataGridControl = dataGridContext.DataGridControl; - - // Ensure to push the RowSelector source to the SelectionChangeManager to be able to - // detect that a RowSelector was used to perform a selection of Row(s) and/or Cell(s) - using( dataGridControl.SelectionChangerManager.PushUpdateSelectionSource( SelectionManager.UpdateSelectionSource.RowSelector ) ) - { - if( dataGridControl.SetFocusHelper( rowItemContainer, dataGridContext.CurrentColumn, true, true, true ) ) - { - // Keep a reference to the mouse position so we can calculate when a drag operation is actually started. - dataGridControl.InitializeDragPostion( e ); - } - - if( dataGridControl.NavigationBehavior == NavigationBehavior.RowOrCell ) - { - try - { - dataGridContext.SetCurrentColumnCore( null, false, false, AutoScrollCurrentItemSourceTriggers.Navigation ); - } - catch( DataGridException ) - { - // We swallow the exception if it occurs because of a validation error or Cell was read-only or any other GridException. - } - } - } - } - } - } - - base.OnMouseLeftButtonDown( e ); - - m_isFromMouseButtonDown = false; - } - - protected override void OnMouseMove( MouseEventArgs e ) - { - bool doDrag = false; - - if( e.LeftButton == MouseButtonState.Pressed ) - { - if( this.IsMouseCaptured ) - { - Rect bounds = new Rect( 0d, 0d, this.ActualWidth, this.ActualHeight ); - this.SetIsPressed( bounds.Contains( e.GetPosition( this ) ) ); - - e.Handled = true; - } - - doDrag = true; - } - - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - if( dataGridContext != null ) - { - //Do not start the drag operation until we have an actual mouse mouve. - if( doDrag && !m_isFromMouseButtonDown ) - { - dataGridContext.DataGridControl.DoDrag( e ); - } - else - { - dataGridContext.DataGridControl.ResetDragDataObject(); - } - } - - base.OnMouseMove( e ); - } - - protected override void OnMouseLeftButtonUp( MouseButtonEventArgs e ) - { - bool isMouseCaptured = this.IsMouseCaptured; - bool isPressed = this.IsPressed; - - if( isMouseCaptured ) - { - this.ReleaseMouseCapture(); - this.SetIsPressed( false ); - e.Handled = true; - } - - base.OnMouseLeftButtonUp( e ); - } - - protected override void OnLostMouseCapture( MouseEventArgs e ) - { - if( this.IsPressed ) - { - this.SetIsPressed( false ); - } - - base.OnLostMouseCapture( e ); - } - - private bool m_isFromMouseButtonDown = false; - - #endregion Button Behavior Code - - private static readonly Binding m_sDataContextBinding; - private static readonly Binding m_sItemIndexBinding; - private static readonly Binding m_sIsCurrentBinding; - private static readonly Binding m_sIsBeingEditedBinding; - private static readonly Binding m_sHasValidationErrorBinding; - private static readonly Binding m_sRowSelectorVisibleBinding; - private static readonly Binding m_sRowSelectorStyleBinding; - private static readonly Binding m_sAllowResizeBinding; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/RowSelectorPane.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/RowSelectorPane.cs deleted file mode 100644 index e57d9bec..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/RowSelectorPane.cs +++ /dev/null @@ -1,523 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Threading; - -namespace Xceed.Wpf.DataGrid -{ - public class RowSelectorPane : Panel - { - static RowSelectorPane() - { - ClipToBoundsProperty.OverrideMetadata( typeof( RowSelectorPane ), new FrameworkPropertyMetadata( true ) ); - FocusableProperty.OverrideMetadata( typeof( RowSelectorPane ), new FrameworkPropertyMetadata( false ) ); - - DataGridControl.ParentDataGridControlPropertyKey.OverrideMetadata( typeof( RowSelectorPane ), new FrameworkPropertyMetadata( new PropertyChangedCallback( RowSelectorPane.OnParentGridControlChanged ) ) ); - } - - #region Orientation Dependency Property - - // Using a DependencyProperty as the backing store for Orientation. This enables animation, styling, binding, etc... - public static readonly DependencyProperty OrientationProperty = DependencyProperty.Register( - "Orientation", - typeof( Orientation ), - typeof( RowSelectorPane ), - new UIPropertyMetadata( Orientation.Vertical ) ); - - public Orientation Orientation - { - get - { - return ( Orientation )this.GetValue( RowSelectorPane.OrientationProperty ); - } - set - { - this.SetValue( RowSelectorPane.OrientationProperty, value ); - } - } - - #endregion - - protected override Size MeasureOverride( Size availableSize ) - { - foreach( UIElement child in this.InternalChildren ) - { - var decorator = child as RowSelectorDecorator; - if( decorator != null ) - { - if( this.IsRowSelectorVisible( decorator ) ) - { - decorator.Visibility = Visibility.Visible; - decorator.Measure( this.GetAvailableSize( decorator, availableSize ) ); - } - else - { - decorator.Visibility = Visibility.Collapsed; - - if( !decorator.IsMeasureValid ) - { - decorator.Measure( RowSelectorPane.EmptySize ); - } - } - } - else - { - child.Measure( RowSelectorPane.EmptySize ); - } - } - - return RowSelectorPane.EmptySize; - } - - protected override Size ArrangeOverride( Size finalSize ) - { - foreach( UIElement child in this.InternalChildren ) - { - var decorator = child as RowSelectorDecorator; - if( decorator != null ) - { - if( this.IsRowSelectorVisible( decorator ) ) - { - var arrangeRect = this.GetArrangeRect( decorator, finalSize ); - var rowSelector = decorator.RowSelector; - var referenceElement = ( rowSelector != null ) ? rowSelector.ReferenceElement : null; - - decorator.Clip = this.GetClipRegion( decorator, arrangeRect, referenceElement ); - decorator.Arrange( arrangeRect ); - } - else if( !decorator.IsArrangeValid ) - { - decorator.Arrange( RowSelectorPane.OutOfViewRect ); - } - } - else - { - child.Arrange( RowSelectorPane.OutOfViewRect ); - } - } - - // The call to Mouse.Synchronize must not start dragging rows. - // Update the mouse status to make sure no container has invalid mouse over status. - // Only do this when the mouse is over the panel, to prevent unescessary update when scrolling with thumb. - if( this.IsMouseOver ) - { - var dataGridContext = DataGridControl.GetDataGridContext( this ); - var dataGridControl = ( dataGridContext != null ) ? dataGridContext.DataGridControl : null; - - if( dataGridControl != null ) - { - using( dataGridControl.InhibitDrag() ) - { - Mouse.Synchronize(); - } - } - } - - return finalSize; - } - - internal virtual void PrepareDefaultStyleKey( Xceed.Wpf.DataGrid.Views.ViewBase view ) - { - this.DefaultStyleKey = view.GetDefaultStyleKey( typeof( RowSelectorPane ) ); - } - - internal void SetRowSelectorPosition( DependencyObject container, Rect containerRect, FrameworkElement referenceElement ) - { - Debug.Assert( ( Visibility )this.GetValue( RowSelectorPane.VisibilityProperty ) == Visibility.Visible, "We should not be creating RowSelectors if we are not Visible." ); - - // Try to re-use the RowSelector already assigned to the container. - if( this.TryReUseVisibleRowSelector( container, containerRect ) ) - return; - - var decorator = this.RecycleOrCreateRowSelector( container ); - Debug.Assert( decorator != null, "An attempt was made to set the position of a row selector that does not exist." ); - - RowSelectorPane.PrepareRowSelector( decorator, container, containerRect, referenceElement ); - - m_visibleSelectors.Add( container, decorator ); - - this.InvalidateMeasure(); - } - - internal void FreeRowSelector( DependencyObject container ) - { - RowSelectorDecorator decorator; - if( !m_visibleSelectors.TryGetValue( container, out decorator ) ) - return; - - m_visibleSelectors.Remove( container ); - m_pendingCleanup.Add( decorator ); - - this.ScheduleUnusedRowSelectorsCleanUp(); - this.InvalidateMeasure(); - } - - private Rect GetArrangeRect( RowSelectorDecorator decorator, Size finalSize ) - { - var rowSelector = decorator.RowSelector; - if( rowSelector == null ) - return RowSelectorPane.EmptyRect; - - var container = rowSelector.DataContext as FrameworkElement; - Debug.Assert( container != null ); - - var coordinatesTransform = container.TransformToVisual( this ); - var origin = coordinatesTransform.Transform( RowSelectorPane.OriginPoint ); - - if( this.Orientation == Orientation.Vertical ) - return new Rect( 0, origin.Y, finalSize.Width, container.ActualHeight ); - - return new Rect( origin.X, 0, container.ActualWidth, finalSize.Height ); - } - - private Size GetAvailableSize( RowSelectorDecorator decorator, Size availableSize ) - { - var rowSelector = decorator.RowSelector; - if( rowSelector == null ) - return RowSelectorPane.EmptySize; - - var containerRect = rowSelector.ContainerRect; - - if( this.Orientation == Orientation.Vertical ) - return new Size( availableSize.Width, containerRect.Height ); - - return new Size( containerRect.Width, availableSize.Height ); - } - - private Geometry GetClipRegion( RowSelectorDecorator decorator, Rect arrangeRect, FrameworkElement referenceElement ) - { - if( referenceElement == null ) - return null; - - var rowSelector = decorator.RowSelector; - if( rowSelector == null ) - return null; - - GeneralTransform referenceElementToRowSelectorPaneTransform = referenceElement.TransformToVisual( this ); - Rect referenceElementRegion = referenceElementToRowSelectorPaneTransform.TransformBounds( new Rect( 0, 0, referenceElement.ActualWidth, referenceElement.ActualHeight ) ); - RectangleGeometry clipRegion = null; - - if( this.Orientation == Orientation.Vertical ) - { - UIElement container = rowSelector.DataContext as UIElement; - - if( ( container != null ) && ( container.Clip != null ) ) - { - Rect containerClipBounds = container.Clip.Bounds; - - // In this case, we will use the container's clip properties (Top and Bottom). - clipRegion = new RectangleGeometry( new Rect( 0d, containerClipBounds.Y, arrangeRect.Width, containerClipBounds.Height ) ); - } - else if( ( arrangeRect.Top < referenceElementRegion.Top ) || ( arrangeRect.Bottom > referenceElementRegion.Bottom ) ) - { - double x = 0d; - double y = Math.Max( referenceElementRegion.Top - arrangeRect.Top, 0 ); - - double width = arrangeRect.Width; - double height = Math.Max( 0, arrangeRect.Height - y - Math.Max( 0, arrangeRect.Bottom - referenceElementRegion.Bottom ) ); - - clipRegion = new RectangleGeometry( new Rect( x, y, width, height ) ); - } - } - else - { - UIElement container = rowSelector.DataContext as UIElement; - - if( ( container != null ) && ( container.Clip != null ) ) - { - Rect containerClipBounds = container.Clip.Bounds; - - // In this case, we will use the container's clip properties (Left and Right). - clipRegion = new RectangleGeometry( new Rect( containerClipBounds.X, 0d, containerClipBounds.Width, arrangeRect.Height ) ); - } - else if( ( arrangeRect.Left < referenceElementRegion.Left ) || ( arrangeRect.Right > referenceElementRegion.Right ) ) - { - double x = Math.Max( referenceElementRegion.Left - arrangeRect.Left, 0 ); - double y = 0d; - - double width = arrangeRect.Width - x - Math.Max( 0, arrangeRect.Right - referenceElementRegion.Right ); - double height = arrangeRect.Height; - - clipRegion = new RectangleGeometry( new Rect( x, y, width, height ) ); - } - } - - return clipRegion; - } - - private bool IsRowSelectorVisible( RowSelectorDecorator decorator ) - { - Debug.Assert( decorator != null ); - if( decorator.RowSelector == null ) - return false; - - var container = DataGridControl.GetContainer( decorator ); - if( container == null ) - return false; - - return m_visibleSelectors.ContainsKey( container ); - } - - private bool TryReUseVisibleRowSelector( DependencyObject container, Rect containerRect ) - { - RowSelectorDecorator decorator; - if( !m_visibleSelectors.TryGetValue( container, out decorator ) ) - return false; - - var rowSelector = decorator.RowSelector; - if( rowSelector == null ) - { - this.FreeRowSelector( container ); - return false; - } - - // Check if the cached position and size of the target container is up to date. - if( !Rect.Equals( rowSelector.ContainerRect, containerRect ) ) - { - rowSelector.ContainerRect = containerRect; - - this.InvalidateMeasure(); - } - - return true; - } - - private RowSelectorDecorator RecycleOrCreateRowSelector( DependencyObject container ) - { - RowSelectorDecorator decorator; - - // Try to re-use a RowSelector that is schedule to be clean up. - if( m_pendingCleanup.Count > 0 ) - { - int index = m_pendingCleanup.Count - 1; - - for( int i = index; i >= 0; i-- ) - { - decorator = m_pendingCleanup[ i ]; - if( DataGridControl.GetContainer( decorator ) == container ) - { - index = i; - break; - } - } - - decorator = m_pendingCleanup[ index ]; - m_pendingCleanup.RemoveAt( index ); - } - // Try to recycle a RowSelector from the recycling pool. - else if( m_recyclingQueue.Count > 0 ) - { - decorator = m_recyclingQueue.Dequeue(); - } - else - { - decorator = new RowSelectorDecorator(); - - this.InternalChildren.Add( decorator ); - } - - return decorator; - } - - private void ScheduleUnusedRowSelectorsCleanUp() - { - if( m_pendingCleanupOperation != null ) - return; - - m_pendingCleanupOperation = this.Dispatcher.BeginInvoke( DispatcherPriority.ApplicationIdle, new Action( this.CleanUpUnusedRowSelectors ) ); - } - - private void CleanUpUnusedRowSelectors() - { - m_pendingCleanupOperation = null; - - for( int i = m_pendingCleanup.Count - 1; i >= 0; i-- ) - { - var decorator = m_pendingCleanup[ i ]; - - RowSelectorPane.ClearRowSelector( decorator ); - - if( decorator.RowSelector != null ) - { - m_recyclingQueue.Enqueue( decorator ); - } - else - { - // The RowSelector has become useless, so we destroy it. - this.InternalChildren.Remove( decorator ); - } - } - - m_pendingCleanup.Clear(); - } - - private static void PrepareRowSelector( RowSelectorDecorator decorator, DependencyObject container, Rect containerRect, FrameworkElement referenceElement ) - { - Debug.Assert( decorator != null ); - - DataGridControl.SetContainer( decorator, container ); - - var rowSelector = decorator.RowSelector; - if( rowSelector != null ) - { - rowSelector.ReferenceElement = referenceElement; - rowSelector.ContainerRect = containerRect; - } - } - - private static void ClearRowSelector( RowSelectorDecorator decorator ) - { - Debug.Assert( decorator != null ); - - DataGridControl.ClearContainer( decorator ); - - var rowSelector = decorator.RowSelector; - if( rowSelector != null ) - { - rowSelector.ReferenceElement = null; - rowSelector.ContainerRect = RowSelectorPane.EmptyRect; - } - } - - private static void OnParentGridControlChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - RowSelectorPane rowSelectorPane = ( RowSelectorPane )sender; - DataGridControl newGrid = e.NewValue as DataGridControl; - DataGridControl oldGrid = e.OldValue as DataGridControl; - - if( oldGrid != null ) - { - // The RowSelectorPane must clear its internal state when the ParentGridControl changes - rowSelectorPane.m_pendingCleanup.Clear(); - rowSelectorPane.m_recyclingQueue.Clear(); - rowSelectorPane.m_visibleSelectors.Clear(); - rowSelectorPane.InternalChildren.Clear(); - } - - if( newGrid != null ) - { - rowSelectorPane.PrepareDefaultStyleKey( newGrid.GetView() ); - } - - rowSelectorPane.InvalidateMeasure(); - } - - #region Obsolete Members - - [Obsolete( "The ItemsPlacementReference property is obsolete and should no longer be used.", true )] - [EditorBrowsable( EditorBrowsableState.Never )] - public FrameworkElement ItemsPlacementReference - { - get - { - return null; - } - set - { - } - } - - [Obsolete( "The ItemsPlacementReferenceProperty dependency property is obsolete and should no longer be used.", true )] - [EditorBrowsable( EditorBrowsableState.Never )] - public static readonly DependencyProperty ItemsPlacementReferenceProperty; - - - [Obsolete( "The RowSelectorStyle attached property is obsolete and has been replaced by the RowSelector.RowSelectorStyle attached property.", true )] - [EditorBrowsable( EditorBrowsableState.Never )] - public static Style GetRowSelectorStyle( DependencyObject obj ) - { - return null; - } - - [Obsolete( "The RowSelectorStyle attached property is obsolete and has been replaced by the RowSelector.RowSelectorStyle attached property.", true )] - [EditorBrowsable( EditorBrowsableState.Never )] - public static void SetRowSelectorStyle( DependencyObject obj, Style value ) - { - } - - [Obsolete( "The RowSelectorStyleProperty dependency property is obsolete and has been replaced by the RowSelector.RowSelectorStyleProperty dependency property.", true )] - [EditorBrowsable( EditorBrowsableState.Never )] - public static readonly DependencyProperty RowSelectorStyleProperty; - - [Obsolete( "The ScrollViewer property is obsolete and should no longer be used.", true )] - [EditorBrowsable( EditorBrowsableState.Never )] - public ScrollViewer ScrollViewer - { - get - { - return null; - } - set - { - } - } - - [Obsolete( "The ScrollViewerProperty dependency property is obsolete and should no longer be used.", true )] - [EditorBrowsable( EditorBrowsableState.Never )] - public static readonly DependencyProperty ScrollViewerProperty; - - #endregion Obsolete Members - - #region CONSTANTS - - private static readonly Point OriginPoint = new Point( 0d, 0d ); - private static readonly Size EmptySize = new Size( 0d, 0d ); - private static readonly Rect EmptyRect = new Rect( RowSelectorPane.OriginPoint, RowSelectorPane.EmptySize ); - private static readonly Rect OutOfViewRect = new Rect( new Point( -999999d, -999999d ), RowSelectorPane.EmptySize ); - - #endregion - - #region PRIVATE FIELDS - - private readonly Queue m_recyclingQueue = new Queue(); - private readonly List m_pendingCleanup = new List(); - private readonly Dictionary m_visibleSelectors = new Dictionary(); - private DispatcherOperation m_pendingCleanupOperation; //null - - #endregion - - #region RowSelectorDecorator Private Class - - private sealed class RowSelectorDecorator : Decorator - { - internal RowSelectorDecorator() - { - this.Focusable = false; - this.OverridesDefaultStyle = true; - - this.Child = new RowSelector(); - } - - internal RowSelector RowSelector - { - get - { - return this.Child as RowSelector; - } - } - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/RowState.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/RowState.cs deleted file mode 100644 index 225b1c8d..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/RowState.cs +++ /dev/null @@ -1,72 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Collections; -using System.Windows.Controls; - -namespace Xceed.Wpf.DataGrid -{ - internal class RowState - { - public RowState() - { - } - - // Restore it only if the Row is being edited - public RowValidationError ItemValidationError - { - get - { - return m_itemValidationError; - } - } - - // Restore it only if the Row is being edited - public bool IsDirty - { - get - { - return m_isDirty; - } - } - - public RowState Clone() - { - RowState rowState = new RowState(); - - rowState.m_itemValidationError = m_itemValidationError; - rowState.m_isDirty = m_isDirty; - - return rowState; - } - - internal void SetItemValidationError( RowValidationError value ) - { - m_itemValidationError = value; - } - - internal void SetIsDirty( bool value ) - { - m_isDirty = value; - } - - private RowValidationError m_itemValidationError; // = null; - private bool m_isDirty; // = false - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/RowValidationError.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/RowValidationError.cs deleted file mode 100644 index 5f33474e..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/RowValidationError.cs +++ /dev/null @@ -1,77 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows.Controls; - -namespace Xceed.Wpf.DataGrid -{ - public class RowValidationError - { - public RowValidationError( - ValidationRule ruleInError, - Row rowInError, - object errorContent, - Exception exception ) - { - m_ruleInError = ruleInError; - m_rowInError = rowInError; - m_errorContent = errorContent; - m_exception = exception; - } - - public ValidationRule RuleInError - { - get - { - return m_ruleInError; - } - } - - public Row RowInError - { - get - { - return m_rowInError; - } - } - - public object ErrorContent - { - get - { - return m_errorContent; - } - set - { - m_errorContent = value; - } - } - - public Exception Exception - { - get - { - return m_exception; - } - } - - private ValidationRule m_ruleInError; - private Row m_rowInError; - private object m_errorContent; - private Exception m_exception; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ScrollTip.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ScrollTip.cs deleted file mode 100644 index 4f67d28b..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ScrollTip.cs +++ /dev/null @@ -1,672 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Controls.Primitives; -using System.Windows.Data; -using Xceed.Wpf.DataGrid.Views; - -namespace Xceed.Wpf.DataGrid -{ - public class ScrollTip : ContentControl, IWeakEventListener - { - #region CONSTRUCTORS - - static ScrollTip() - { - // This DefaultStyleKey will only be used in design-time. - DefaultStyleKeyProperty.OverrideMetadata( typeof( ScrollTip ), new FrameworkPropertyMetadata( new Markup.ThemeKey( typeof( Views.TableView ), typeof( ScrollTip ) ) ) ); - - DataGridControl.ParentDataGridControlPropertyKey.OverrideMetadata( typeof( ScrollTip ), new FrameworkPropertyMetadata( new PropertyChangedCallback( ScrollTip.ParentGridControlPropertyChangedCallback ) ) ); - DataGridControl.DataGridContextPropertyKey.OverrideMetadata( typeof( ScrollTip ), new FrameworkPropertyMetadata( new PropertyChangedCallback( ScrollTip.OnDataGridContextPropertyChanged ) ) ); - } - - #endregion - - #region PUBLIC METHODS - - public override void OnApplyTemplate() - { - base.OnApplyTemplate(); - - this.ScrollTipContentTemplateNeedsRefresh = true; - this.RefreshDefaultScrollTipContentTemplate(); - } - - #endregion - - #region PROTECTED METHODS - - protected internal virtual void PrepareDefaultStyleKey( Xceed.Wpf.DataGrid.Views.ViewBase view ) - { - this.DefaultStyleKey = view.GetDefaultStyleKey( typeof( ScrollTip ) ); - } - - #endregion - - #region ScrollTipContentTemplateNeedsRefresh Private Property - - private bool ScrollTipContentTemplateNeedsRefresh - { - get - { - return m_flags[ ( int )ScrollTipFlags.ScrollTipContentTemplateNeedsRefresh ]; - } - set - { - m_flags[ ( int )ScrollTipFlags.ScrollTipContentTemplateNeedsRefresh ] = value; - } - } - - #endregion - - #region UsingDefaultScrollTipContentTemplate Private Property - - private bool UsingDefaultScrollTipContentTemplate - { - get - { - return m_flags[ ( int )ScrollTipFlags.UsingDefaultScrollTipContentTemplate ]; - } - set - { - m_flags[ ( int )ScrollTipFlags.UsingDefaultScrollTipContentTemplate ] = value; - } - } - - #endregion - - #region IsInParentGridChanged Private Property - - private bool IsInParentGridChanged - { - get - { - return m_flags[ ( int )ScrollTipFlags.IsInParentGridChanged ]; - } - set - { - m_flags[ ( int )ScrollTipFlags.IsInParentGridChanged ] = value; - } - } - - #endregion - - #region IsPixelScrolling Private Property - - private bool IsPixelScrolling - { - get - { - return m_flags[ ( int )ScrollTipFlags.IsPixelScrolling ]; - } - set - { - m_flags[ ( int )ScrollTipFlags.IsPixelScrolling ] = value; - } - } - - #endregion - - #region ShouldDisplayScrollTip Private Property - - private bool ShouldDisplayScrollTip - { - get - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - if( dataGridContext != null ) - { - if( dataGridContext.DataGridControl != null ) - { - UIViewBase uiViewBase = dataGridContext.DataGridControl.GetView() as UIViewBase; - if( ( uiViewBase != null ) && ( uiViewBase.ShowScrollTip ) ) - return true; - } - } - - return false; - } - } - - #endregion - - #region DefaultScrollTipContentTemplateBinding Private Property - - private Binding DefaultScrollTipContentTemplateBinding - { - get - { - if( m_defaultScrollTipContentTemplateBinding == null ) - { - m_defaultScrollTipContentTemplateBinding = new Binding(); - m_defaultScrollTipContentTemplateBinding.Path = new PropertyPath( "(0).ScrollTipContentTemplate", DataGridControl.DataGridContextProperty ); - m_defaultScrollTipContentTemplateBinding.Source = this; - } - - return m_defaultScrollTipContentTemplateBinding; - } - } - - private Binding m_defaultScrollTipContentTemplateBinding; // = null; - - #endregion - - #region DefaultScrollTipContentTemplateSelectorBinding Private Property - - private Binding DefaultScrollTipContentTemplateSelectorBinding - { - get - { - if( m_defaultScrollTipContentTemplateSelectorBinding == null ) - { - m_defaultScrollTipContentTemplateSelectorBinding = new Binding(); - m_defaultScrollTipContentTemplateSelectorBinding.Path = new PropertyPath( "(0).ScrollTipContentTemplateSelector", DataGridControl.DataGridContextProperty ); - m_defaultScrollTipContentTemplateSelectorBinding.Source = this; - } - - return m_defaultScrollTipContentTemplateSelectorBinding; - } - } - - - private Binding m_defaultScrollTipContentTemplateSelectorBinding; // = null; - - #endregion - - #region DefaultCellContentTemplateBinding Private Property - - private Binding DefaultCellContentTemplateBinding - { - get - { - if( m_defaultCellContentTemplateBinding == null ) - { - m_defaultCellContentTemplateBinding = new Binding(); - m_defaultCellContentTemplateBinding.Path = new PropertyPath( "(0).Columns.MainColumn.CellContentTemplate", DataGridControl.DataGridContextProperty ); - m_defaultCellContentTemplateBinding.Source = this; - } - - return m_defaultCellContentTemplateBinding; - } - } - - private Binding m_defaultCellContentTemplateBinding; - - #endregion - - #region DefaultCellContentTemplateSelectorBinding Private Property - - private Binding DefaultCellContentTemplateSelectorBinding - { - get - { - if( m_defaultCellContentTemplateSelectorBinding == null ) - { - m_defaultCellContentTemplateSelectorBinding = new Binding(); - m_defaultCellContentTemplateSelectorBinding.Path = new PropertyPath( "(0).Columns.MainColumn.CellContentTemplateSelector", DataGridControl.DataGridContextProperty ); - m_defaultCellContentTemplateSelectorBinding.Source = this; - } - - return m_defaultCellContentTemplateSelectorBinding; - } - } - - private Binding m_defaultCellContentTemplateSelectorBinding; - - #endregion - - #region PRIVATE METHODS - - private static void OnDataGridContextPropertyChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - ScrollTip scrollTip = ( ScrollTip )sender; - - DataGridContext oldItemContext = e.OldValue as DataGridContext; - DataGridContext newItemContext = e.NewValue as DataGridContext; - - if( scrollTip.m_mainColumn != null ) - { - PropertyChangedEventManager.RemoveListener( scrollTip.m_mainColumn, scrollTip, Column.DisplayMemberBindingPropertyName ); - } - - scrollTip.m_mainColumn = null; - - if( oldItemContext != null ) - { - PropertyChangedEventManager.RemoveListener( oldItemContext.Columns, scrollTip, ColumnCollection.MainColumnPropertyName ); - } - - scrollTip.ClearValue( ScrollTip.ContentProperty ); - - if( newItemContext != null ) - { - scrollTip.m_mainColumn = newItemContext.Columns.MainColumn; - - if( scrollTip.m_mainColumn != null ) - { - PropertyChangedEventManager.AddListener( scrollTip.m_mainColumn, scrollTip, Column.DisplayMemberBindingPropertyName ); - } - - PropertyChangedEventManager.AddListener( newItemContext.Columns, scrollTip, ColumnCollection.MainColumnPropertyName ); - } - - if( !scrollTip.IsInParentGridChanged ) - { - if( !scrollTip.ApplyTemplate() ) - scrollTip.RefreshDefaultScrollTipContentTemplate(); - } - } - - private static void ParentGridControlPropertyChangedCallback( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - DataGridControl oldParentGridControl = e.OldValue as DataGridControl; - DataGridControl parentGridControl = e.NewValue as DataGridControl; - ScrollTip scrollTip = sender as ScrollTip; - - scrollTip.IsInParentGridChanged = true; - try - { - if( oldParentGridControl != null ) - { - if( scrollTip.UsingDefaultScrollTipContentTemplate ) - { - // Unload DefaultTemplate - Xceed.Wpf.DataGrid.Views.UIViewBase uiViewBase = oldParentGridControl.GetView() as Xceed.Wpf.DataGrid.Views.UIViewBase; - - if( uiViewBase != null ) - { - uiViewBase.ClearValue( UIViewBase.ScrollTipContentTemplateProperty ); - scrollTip.UsingDefaultScrollTipContentTemplate = false; - } - } - - if( scrollTip.m_mainColumn != null ) - { - PropertyChangedEventManager.RemoveListener( scrollTip.m_mainColumn, scrollTip, "DisplayMemberBinding" ); - } - - scrollTip.m_mainColumn = null; - - scrollTip.UnregisterListeners( oldParentGridControl ); - } - - if( parentGridControl == null ) - return; - - scrollTip.PrepareDefaultStyleKey( parentGridControl.GetView() ); - - // Assert Template is applied in order to be notified for ScrollBars events - DataGridControl.SetDataGridContext( scrollTip, parentGridControl.DataGridContext ); - - if( !scrollTip.ApplyTemplate() ) - scrollTip.RefreshDefaultScrollTipContentTemplate(); - - scrollTip.RegisterListeners( parentGridControl ); - } - finally - { - scrollTip.IsInParentGridChanged = false; - } - } - - private void RegisterListeners( DataGridControl parentGridControl ) - { - if( parentGridControl.ScrollViewer != null ) - { - parentGridControl.ScrollViewer.ScrollChanged += new ScrollChangedEventHandler( this.OnScrollViewerScrollChanged ); - m_scrollViewerTemplateHelper = new ScrollViewerTemplateHelper( parentGridControl.ScrollViewer, this.DragScrollBegin, this.DragScrollEnd ); - m_scrollViewerTemplateHelper.RefreshTemplate(); - } - } - - private void UnregisterListeners( DataGridControl parentGridControl ) - { - if( parentGridControl.ScrollViewer != null ) - { - parentGridControl.ScrollViewer.ScrollChanged -= new ScrollChangedEventHandler( this.OnScrollViewerScrollChanged ); - } - - if( m_scrollViewerTemplateHelper != null ) - { - m_scrollViewerTemplateHelper.Dispose(); - m_scrollViewerTemplateHelper = null; - } - } - - private void RefreshDefaultScrollTipContentTemplate() - { - DataGridContext itemContext = DataGridControl.GetDataGridContext( this ); - - if( itemContext == null ) - return; - - DataGridControl parentGridControl = itemContext.DataGridControl; - - if( ( parentGridControl == null ) || ( parentGridControl.ScrollViewer == null ) ) - return; - - ColumnCollection columnCollection = itemContext.Columns; - - if( columnCollection == null ) - return; - - Column mainColumn = columnCollection.MainColumn as Column; - - if( mainColumn == null ) - return; - - Xceed.Wpf.DataGrid.Views.UIViewBase uiViewBase = parentGridControl.GetView() as Xceed.Wpf.DataGrid.Views.UIViewBase; - - if( uiViewBase == null ) - return; - - // The ScrollTip.ContentTemplate will now be set. This is to avoid - // a null ContentTemplate when the ColumnsCollection update its - // MainColumn after the template is applied - this.ScrollTipContentTemplateNeedsRefresh = false; - - ForeignKeyConfiguration configuration = mainColumn.ForeignKeyConfiguration; - - // Do not create default template only when none was created before and a template already exists - if( ( !this.UsingDefaultScrollTipContentTemplate ) && ( uiViewBase.ScrollTipContentTemplate != null ) ) - { - if( configuration != null ) - { - this.ContentTemplate = configuration.DefaultScrollTipContentTemplate; - } - else - { - // Clear the value in case we previously affected it - this.ClearValue( ScrollTip.ContentTemplateProperty ); - - // Set the default Binding values - this.SetBinding( ScrollTip.ContentTemplateProperty, this.DefaultScrollTipContentTemplateBinding ); - this.SetBinding( ScrollTip.ContentTemplateSelectorProperty, this.DefaultScrollTipContentTemplateSelectorBinding ); - } - } - else - { - // A default ContentTemplate template is created using MainColumn as displayed data - this.UsingDefaultScrollTipContentTemplate = true; - - // If a configuration was found, the default ContentTemplate will - // be used to convert Content to Foreign value and - // it will use the ScrollTipContentTemplate defined on UIViewBase - // if any - if( configuration == null ) - { - // Disable warning for DisplayMemberBinding when internaly used -#pragma warning disable 618 - - BindingBase displayMemberBinding = mainColumn.DisplayMemberBinding; - -#pragma warning restore 618 - - FrameworkElementFactory contentPresenter = new FrameworkElementFactory( typeof( ContentPresenter ) ); - contentPresenter.SetValue( ContentPresenter.NameProperty, "defaultScrollTipDataTemplateContentPresenter" ); - contentPresenter.SetBinding( ContentPresenter.ContentProperty, displayMemberBinding ); - - contentPresenter.SetBinding( ContentPresenter.ContentTemplateProperty, this.DefaultCellContentTemplateBinding ); - contentPresenter.SetBinding( ContentPresenter.ContentTemplateSelectorProperty, this.DefaultCellContentTemplateSelectorBinding ); - - DataTemplate template = new DataTemplate(); - template.VisualTree = contentPresenter; - template.Seal(); - - this.ContentTemplate = template; - } - else - { - this.SetBinding( ContentPresenter.ContentTemplateProperty, this.DefaultCellContentTemplateBinding ); - this.SetBinding( ContentPresenter.ContentTemplateSelectorProperty, this.DefaultCellContentTemplateSelectorBinding ); - this.ContentTemplate = configuration.DefaultScrollTipContentTemplate; - } - } - } - - private void DragScrollBegin( Orientation orientation ) - { - if( !this.ShouldDisplayScrollTip ) - return; - - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - if( dataGridContext == null ) - return; - - if( dataGridContext.DataGridControl == null ) - return; - - // Update items scrolling orientation and pixel scrolling - m_itemsScrollingOrientation = ScrollViewerHelper.GetItemScrollingOrientation( dataGridContext.DataGridControl ); - - if( m_itemsScrollingOrientation != orientation ) - return; - - this.Visibility = Visibility.Visible; - - this.IsPixelScrolling = ScrollViewerHelper.IsPixelScrolling( dataGridContext.DataGridControl, dataGridContext.DataGridControl.ItemsHost, dataGridContext.DataGridControl.ScrollViewer ); - - this.RefreshScrollTipContent( m_scrollViewerTemplateHelper.GetScrollBar( orientation ) ); - } - - private void DragScrollEnd( Orientation orientation ) - { - this.Visibility = Visibility.Collapsed; - } - - private void OnScrollViewerScrollChanged( object sender, ScrollChangedEventArgs e ) - { - if( this.Visibility != Visibility.Visible ) - return; - - if( !this.ShouldDisplayScrollTip ) - return; - - // Determine if we are scrolling horizontally or vertically - ScrollBar scrollBar = null; - - if( e.VerticalChange == 0 ) - { - scrollBar = m_scrollViewerTemplateHelper.HorizontalScrollBar; - } - else - { - scrollBar = m_scrollViewerTemplateHelper.VerticalScrollBar; - } - - if( scrollBar == null ) - return; - - this.RefreshScrollTipContent( scrollBar ); - } - - private void RefreshScrollTipContent( ScrollBar scrollBar ) - { - const int MaxItemToVisit = 100; - - var dataGridContext = DataGridControl.GetDataGridContext( this ); - if( dataGridContext == null ) - return; - - var parentGridControl = dataGridContext.DataGridControl; - if( parentGridControl == null ) - return; - - if( scrollBar.Orientation != m_itemsScrollingOrientation ) - return; - - var maxOffset = 0d; - - if( scrollBar.Orientation == Orientation.Vertical ) - { - maxOffset = parentGridControl.ScrollViewer.ExtentHeight; - } - else - { - maxOffset = parentGridControl.ScrollViewer.ExtentWidth; - } - - var offset = scrollBar.Track.Value; - - var itemMaxOffset = 0; - var itemOffset = 0; - var itemHiddenRatio = 0d; - - if( this.IsPixelScrolling ) - { - // Calculate the offset ratio to get the item from the Generator - int itemsCount = parentGridControl.CustomItemContainerGenerator.ItemCount; - itemMaxOffset = itemsCount; - - if( ( maxOffset > 0 ) && ( itemsCount > 0 ) ) - { - var position = offset / ( maxOffset / itemsCount ); - itemOffset = ( int )position; - itemHiddenRatio = position - itemOffset; - } - else - { - itemOffset = 0; - } - } - else - { - itemMaxOffset = ( int )maxOffset; - itemOffset = ( int )offset; - itemHiddenRatio = offset - itemOffset; - } - - object newValue; - DataGridContext itemContext; - - // If data is grouped, we do not want to keep the next data item if a HeaderFooterItem - // is the current item returned. So we increment the scroll up to the next item in order - // to get the real item that will be visible when the user will release the mouse - var visitor = new ItemContextVisitor( parentGridControl.ItemsHost as TableflowViewItemsHost, itemHiddenRatio ); - var endOffset = Math.Min( itemOffset + MaxItemToVisit, itemMaxOffset ); - bool visitWasStopped; - ( ( IDataGridContextVisitable )parentGridControl.DataGridContext ).AcceptVisitor( itemOffset, endOffset, visitor, DataGridContextVisitorType.Items, out visitWasStopped ); - - if( visitor.VisitSuccessful ) - { - itemContext = visitor.ParentDataGridContext; - newValue = visitor.Item; - } - else - { - //Set the ItemContext as the ScrollTip's DataGridContext, this is to ensure the - //ScrollTip will not change the ScrollContentTemplate ( by invalidation of the binding). - itemContext = DataGridControl.GetDataGridContext( this ); - newValue = null; //show nothing in the ScrollTip. - } - - // The TippedItemDataGridContext PropertChanged callback will take care of refreshing the ScrollTip CellContentTemplate. - if( itemContext != DataGridControl.GetDataGridContext( this ) ) - { - DataGridControl.SetDataGridContext( this, itemContext ); - } - - this.Content = newValue; - } - - #endregion - - #region IWeakEventListener Members - - bool IWeakEventListener.ReceiveWeakEvent( Type managerType, object sender, EventArgs e ) - { - return OnReceiveWeakEvent( managerType, sender, e ); - } - - protected virtual bool OnReceiveWeakEvent( Type managerType, object sender, EventArgs e ) - { - var dataGridContext = DataGridControl.GetDataGridContext( this ); - if( dataGridContext == null ) - return true; - - if( managerType == typeof( PropertyChangedEventManager ) ) - { - if( dataGridContext.Columns == sender ) - { - if( m_mainColumn != null ) - { - PropertyChangedEventManager.RemoveListener( m_mainColumn, this, Column.DisplayMemberBindingPropertyName ); - } - - m_mainColumn = dataGridContext.Columns.MainColumn; - - if( m_mainColumn != null ) - { - PropertyChangedEventManager.AddListener( m_mainColumn, this, Column.DisplayMemberBindingPropertyName ); - } - - // If a defaut template was created for the previous MainColumn - // create another one for the new MainColumn - if( this.UsingDefaultScrollTipContentTemplate || this.ScrollTipContentTemplateNeedsRefresh ) - { - this.RefreshDefaultScrollTipContentTemplate(); - } - } - else if( sender == m_mainColumn ) - { - // If a defaut template was created for the previous MainColumn - // create another one - if( this.UsingDefaultScrollTipContentTemplate || this.ScrollTipContentTemplateNeedsRefresh ) - { - this.RefreshDefaultScrollTipContentTemplate(); - } - } - } - else - { - return false; - } - - return true; - } - - #endregion - - #region PRIVATE FIELDS - - private ColumnBase m_mainColumn; // = null; - private Orientation m_itemsScrollingOrientation = Orientation.Vertical; - private ScrollViewerTemplateHelper m_scrollViewerTemplateHelper; - - private BitVector32 m_flags = new BitVector32(); - - #endregion - - #region ScrollTipFlags Private Enum - - [Flags] - private enum ScrollTipFlags - { - UsingDefaultScrollTipContentTemplate = 1, - IsInParentGridChanged = 2, - IsPixelScrolling = 4, - ScrollTipContentTemplateNeedsRefresh = 8, - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ScrollViewerHelper.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ScrollViewerHelper.cs deleted file mode 100644 index ae7448d7..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ScrollViewerHelper.cs +++ /dev/null @@ -1,711 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Windows.Controls; -using System.Windows.Controls.Primitives; -using System.Diagnostics; -using System.Windows; -using System.Windows.Media; -using Xceed.Utils.Math; -using Xceed.Utils.Wpf; -using Xceed.Wpf.DataGrid.Views; - -namespace Xceed.Wpf.DataGrid -{ - internal class ScrollViewerHelper - { - //----------------- PROPERTIES ------------------------- - - private static ScrollViewerHelper Current - { - get - { - if( m_singleInstance == null ) - { - m_singleInstance = new ScrollViewerHelper(); - } - - return m_singleInstance; - } - } - - public static readonly int PixelScrollingCount = 16; - - //----------------- PUBLIC METHODS ------------------------- - - public static bool IsFocusInElement( FrameworkElement element ) - { - if( element != null ) - return element.IsKeyboardFocusWithin; - else - return false; - } - - public static FrameworkElement GetLastVisibleContainer( - DataGridControl gridControl, - FrameworkElement container, - ScrollViewer scrollViewer ) - { - FrameworkElement retval = null; - - if( ScrollViewerHelper.IsPixelScrolling( gridControl, container, scrollViewer ) == false ) - { - //This means that the panel is performing Item Scrolling - - //if the panel is Vertically scrolling the items (means the Horizontal Axis is Pixel scrolling) - if( ScrollViewerHelper.GetItemScrollingOrientation( gridControl, container, scrollViewer ) == Orientation.Vertical ) - { - retval = ScrollViewerHelper.ProcessLastVisibleContainer( gridControl, - scrollViewer.VerticalOffset, - scrollViewer.ViewportHeight, - scrollViewer.HorizontalOffset, - scrollViewer.ViewportWidth, - Orientation.Vertical ); - } - //the panel is Horizontally scrolling the items (means the Vertically Axis is Pixel scrolling) - else - { - retval = ScrollViewerHelper.ProcessLastVisibleContainer( gridControl, - scrollViewer.HorizontalOffset, - scrollViewer.ViewportWidth, - scrollViewer.VerticalOffset, - scrollViewer.ViewportHeight, - Orientation.Horizontal ); - } - } - else - { - Point pt = new Point(); - - if( ( container is VirtualizingPanel ) - || ( container is DataGridItemsHost ) - || ( scrollViewer == null ) ) - { - pt.X = 0; - pt.Y = 0; - } - else - { - pt.X = scrollViewer.HorizontalOffset; - pt.Y = scrollViewer.VerticalOffset; - } - - Size size = new Size( ( scrollViewer != null ) ? scrollViewer.ViewportWidth : container.ActualWidth, - ( scrollViewer != null ) ? scrollViewer.ViewportHeight : container.ActualHeight ); - - Rect visibleRect = new Rect( pt, size ); - - RectangleGeometry geo = new RectangleGeometry( visibleRect ); - - lock( ScrollViewerHelper.Current ) - { - m_sVisibleChildList.Clear(); - m_sGridControl = gridControl; - - VisualTreeHelper.HitTest( container, - new HitTestFilterCallback( ScrollViewerHelper.MyFilterFunct ), - new HitTestResultCallback( ScrollViewerHelper.UselessResultCallback ), - new GeometryHitTestParameters( geo ) ); - - m_sGridControl = null; - - FrameworkElement preservedChild = null; - Nullable preservedOffset = null; - - foreach( FrameworkElement child in m_sVisibleChildList ) - { - Vector itemOffset = VisualTreeHelper.GetOffset( child ); - - Rect itemRect = new Rect( itemOffset.X, itemOffset.Y, child.ActualWidth, child.ActualHeight ); - - itemRect.Intersect( visibleRect ); - - switch( gridControl.ItemsPrimaryAxis ) - { - case PrimaryAxis.Vertical: - if( DoubleUtil.AreClose( itemRect.Width, 0 ) == false ) - { - if( DoubleUtil.AreClose( itemRect.Height, child.ActualHeight ) == true ) - { - if( ScrollViewerHelper.IsABetterLastRow( preservedChild, preservedOffset, itemOffset ) == true ) - { - preservedChild = child; - preservedOffset = itemOffset; - } - } - } - break; - case PrimaryAxis.Horizontal: - if( DoubleUtil.AreClose( itemRect.Width, child.ActualWidth ) == true ) - { - if( DoubleUtil.AreClose( itemRect.Height, 0 ) == false ) - { - if( ScrollViewerHelper.IsABetterLastRow( preservedChild, preservedOffset, itemOffset ) == true ) - { - preservedChild = child; - preservedOffset = itemOffset; - } - } - } - break; - case PrimaryAxis.Both: - if( ( DoubleUtil.AreClose( itemRect.Width, child.ActualWidth ) == true ) - && ( DoubleUtil.AreClose( itemRect.Height, child.ActualHeight ) == true ) ) - { - if( ScrollViewerHelper.IsABetterLastRow( preservedChild, preservedOffset, itemOffset ) == true ) - { - preservedChild = child; - preservedOffset = itemOffset; - } - } - break; - case PrimaryAxis.None: - if( itemRect.IsEmpty == false ) - { - if( ( DoubleUtil.AreClose( itemRect.Height, 0 ) == false ) && ( DoubleUtil.AreClose( itemRect.Width, 0 ) == false ) ) - { - if( ScrollViewerHelper.IsABetterLastRow( preservedChild, preservedOffset, itemOffset ) == true ) - { - preservedChild = child; - preservedOffset = itemOffset; - } - } - } - break; - } - } - - retval = preservedChild; - - }//end lock (protection of shared static members with GetFirstVisibleItem() ) - } - - - return retval; - } - - private static FrameworkElement ProcessLastVisibleContainer( - DataGridControl gridControl, - double offset, - double viewportSize, - double opposedOffset, - double opposedViewportSize, - Orientation panelOrientation ) - { - FrameworkElement retval = null; - - // Only needed if the DataGridControl contains items - if( ( gridControl != null ) && ( gridControl.Items.Count > 0 ) ) - { - bool qualifyingContainerFound = false; - - //retrieve the last object index according to item scrolling axis (this covers both the "Vertical and None" primary axis cases... - //as well as default if no other row matches the PrimaryAxis criteria) - int runningIndex = ( int )( offset + viewportSize - 1 ); - - //cycle for as long as a qualifying container is not found. - while( qualifyingContainerFound == false ) - { - retval = gridControl.GetContainerFromIndex( runningIndex ) as FrameworkElement; - - if( retval != null ) - { - qualifyingContainerFound = ScrollViewerHelper.IsContainerQualifying( retval, - gridControl, - offset, - viewportSize, - opposedOffset, - opposedViewportSize, - panelOrientation ); - } - - //under all circumstances, if I am back at the original offset (first item visible), then have it qualify. - if( runningIndex == offset ) - qualifyingContainerFound = true; - - runningIndex--; - } - } - - return retval; - } - - private static FrameworkElement ProcessFirstVisibleContainer( - DataGridControl gridControl, - double offset, - double viewportSize, - double opposedOffset, - double opposedViewportSize, - Orientation panelOrientation ) - { - FrameworkElement retval = null; - - // Only needed if the DataGridControl contains items - if( ( gridControl != null ) && ( gridControl.Items.Count > 0 ) ) - { - bool qualifyingContainerFound = false; - - //retrieve the last object index according to item scrolling axis (this covers both the "Vertical and None" primary axis cases... - //as well as default if no other row matches the PrimaryAxis criteria) - int runningIndex = ( int )( offset ); - - //cycle for as long as a qualifying container is not found. - while( !qualifyingContainerFound ) - { - retval = gridControl.GetContainerFromIndex( runningIndex ) as FrameworkElement; - - //will be reverted back if the container does not match a particular condition. - if( retval != null ) - { - qualifyingContainerFound = ScrollViewerHelper.IsContainerQualifying( retval, - gridControl, - offset, - viewportSize, - opposedOffset, - opposedViewportSize, - panelOrientation ); - } - - //under all circumstances, if I am back at the end of the viewport ( last item visible), then have it qualify. - if( runningIndex == ( offset + viewportSize - 1 ) ) - qualifyingContainerFound = true; - - runningIndex++; - } - } - - return retval; - } - - private static bool IsContainerQualifying( - FrameworkElement container, - DataGridControl gridControl, - double offset, - double viewportSize, - double opposedOffset, - double opposedViewportSize, - Orientation panelOrientation ) - { - bool retval = true; - - HeaderFooterItem headerFooterItemContainer = container as HeaderFooterItem; - Row rowContainer = container as Row; - - //Determine if the Element is Focusable or Navigable - if( headerFooterItemContainer != null ) - { - rowContainer = headerFooterItemContainer.AsVisual() as Row; - if( rowContainer == null ) - { - //If the HeaderFooter Item is not a Row and is Not focusable, then the item does not qualify. - UIElement uiElementContainer = headerFooterItemContainer.AsVisual() as UIElement; - if( ( uiElementContainer == null ) || ( !uiElementContainer.Focusable ) ) - { - retval = false; - } - } - } - - //If the container is a Row (in the headers footers region or not ) - if( ( retval ) && ( rowContainer != null ) ) - { - //and the Row is not navigable, then it does not qualify. - if( rowContainer.NavigationBehavior == NavigationBehavior.None ) - { - retval = false; - } - } - - - //If the container still qualifies after first verification, check for the scrolling axis. - if( retval ) - { - //if the PrimaryAxis requires the opposed axis to be fully visible. - if( ( ( panelOrientation == Orientation.Vertical ) && ( ( gridControl.ItemsPrimaryAxis == PrimaryAxis.Horizontal ) || ( gridControl.ItemsPrimaryAxis == PrimaryAxis.Both ) ) ) - || ( ( panelOrientation == Orientation.Horizontal ) && ( ( gridControl.ItemsPrimaryAxis == PrimaryAxis.Vertical ) || ( gridControl.ItemsPrimaryAxis == PrimaryAxis.Both ) ) ) ) - { - FrameworkElement frameworkElementContainer = container as FrameworkElement; - //Somehow, I decided that a container that is not a FrameworkElement (extremelly highly unprobable) was automaticaly NOT to qualify if opposed axis was required. - if( frameworkElementContainer != null ) - { - Vector rowOffset = VisualTreeHelper.GetOffset( frameworkElementContainer ); - - double computedOffset = ( panelOrientation == Orientation.Vertical ) ? rowOffset.X : rowOffset.Y; - double computedSize = ( panelOrientation == Orientation.Vertical ) ? frameworkElementContainer.ActualWidth : frameworkElementContainer.ActualHeight; - - //if the coordinates of the Row are NOT inside the Scrolling Axis' viewport... then the item is not qualifyable. - if( ( computedOffset < opposedOffset ) || ( ( computedOffset + computedSize ) > ( opposedViewportSize + opposedOffset ) ) ) - { - retval = false; - } - } - else - { - retval = false; - } - } - } - - return retval; - } - - public static FrameworkElement GetFirstVisibleContainer( - DataGridControl gridControl, - FrameworkElement container, - ScrollViewer scrollViewer ) - { - FrameworkElement retval = null; - - if( !ScrollViewerHelper.IsPixelScrolling( gridControl, container, scrollViewer ) ) - { - //This means that the panel is performing Item Scrolling - - //if the panel is Vertically scrolling the items (means the Horizontal Axis is Pixel scrolling) - if( ScrollViewerHelper.GetItemScrollingOrientation( gridControl, container, scrollViewer ) == Orientation.Vertical ) - { - retval = ScrollViewerHelper.ProcessFirstVisibleContainer( gridControl, - scrollViewer.VerticalOffset, - scrollViewer.ViewportHeight, - scrollViewer.HorizontalOffset, - scrollViewer.ViewportWidth, - Orientation.Vertical ); - } - //the panel is Horizontally scrolling the items (means the Vertically Axis is Pixel scrolling) - else - { - retval = ScrollViewerHelper.ProcessFirstVisibleContainer( gridControl, - scrollViewer.HorizontalOffset, - scrollViewer.ViewportWidth, - scrollViewer.VerticalOffset, - scrollViewer.ViewportHeight, - Orientation.Horizontal ); - } - } - else - { - Point pt = new Point(); - - if( ( container is VirtualizingPanel ) - || ( container is DataGridItemsHost ) - || ( scrollViewer == null ) ) - { - pt.X = 0; - pt.Y = 0; - } - else - { - pt.X = scrollViewer.HorizontalOffset; - pt.Y = scrollViewer.VerticalOffset; - } - - Size size = new Size( ( scrollViewer != null ) ? scrollViewer.ViewportWidth : container.ActualWidth, - ( scrollViewer != null ) ? scrollViewer.ViewportHeight : container.ActualHeight ); - - Rect visibleRect = new Rect( pt, size ); - - RectangleGeometry geo = new RectangleGeometry( visibleRect ); - - lock( ScrollViewerHelper.Current ) - { - m_sVisibleChildList.Clear(); - m_sGridControl = gridControl; - - VisualTreeHelper.HitTest( container, - new HitTestFilterCallback( ScrollViewerHelper.MyFilterFunct ), - new HitTestResultCallback( ScrollViewerHelper.UselessResultCallback ), - new GeometryHitTestParameters( geo ) ); - - m_sGridControl = null; - - FrameworkElement preservedChild = null; - Nullable preservedOffset = null; - - foreach( FrameworkElement child in m_sVisibleChildList ) - { - Vector itemOffset = VisualTreeHelper.GetOffset( child ); - - Rect itemRect = new Rect( itemOffset.X, itemOffset.Y, child.ActualWidth, child.ActualHeight ); - - itemRect.Intersect( visibleRect ); - - switch( gridControl.ItemsPrimaryAxis ) - { - case PrimaryAxis.Vertical: - if( DoubleUtil.AreClose( itemRect.Width, 0 ) == false ) - { - if( DoubleUtil.AreClose( child.ActualHeight, itemRect.Height ) == true ) - { - if( ScrollViewerHelper.IsABetterFirstRow( preservedChild, preservedOffset, itemOffset ) == true ) - { - preservedChild = child; - preservedOffset = itemOffset; - } - } - } - break; - case PrimaryAxis.Horizontal: - if( DoubleUtil.AreClose( itemRect.Height, 0 ) == false ) - { - if( DoubleUtil.AreClose( itemRect.Width, child.ActualWidth ) == true ) - { - if( ScrollViewerHelper.IsABetterFirstRow( preservedChild, preservedOffset, itemOffset ) == true ) - { - preservedChild = child; - preservedOffset = itemOffset; - } - } - } - break; - case PrimaryAxis.Both: - if( ( DoubleUtil.AreClose( itemRect.Width, child.ActualWidth ) == true ) && ( DoubleUtil.AreClose( itemRect.Height, child.ActualHeight ) == true ) ) - { - if( ScrollViewerHelper.IsABetterFirstRow( preservedChild, preservedOffset, itemOffset ) == true ) - { - preservedChild = child; - preservedOffset = itemOffset; - } - } - break; - case PrimaryAxis.None: - if( ( DoubleUtil.AreClose( itemRect.Width, 0 ) == false ) && ( DoubleUtil.AreClose( itemRect.Width, 0 ) == false ) ) - { - if( itemRect.IsEmpty == false ) - { - if( ScrollViewerHelper.IsABetterFirstRow( preservedChild, preservedOffset, itemOffset ) == true ) - { - preservedChild = child; - preservedOffset = itemOffset; - } - } - } - break; - } - } - - retval = preservedChild; - }//end lock - } - - return retval; - } - - //----------------- INTERNAL METHODS ------------------------- - - internal static Thumb FindParentThumb( object reference, ScrollViewer scrollViewer ) - { - Thumb retval = null; - DependencyObject obj = reference as DependencyObject; - - if( obj != null ) - { - do - { - retval = obj as Thumb; - - if( retval == null ) - { - obj = TreeHelper.GetParent( obj ); - - if( ( obj == scrollViewer ) || ( obj == null ) ) - break; - } - } while( retval == null ); - } - - return retval; - } - - internal static Orientation GetItemScrollingOrientation( - DataGridControl dataGridControl, - FrameworkElement container, - ScrollViewer scrollViewer ) - { - int itemsCount = dataGridControl.Items.Count; - - //if the Panel passed supports the CustomItemContainerGenerator, then retrieve the itemcount from the customItemContainerGenerator - if( ( container is DataGridVirtualizingPanel ) || ( container is DataGridItemsHost ) ) - { - itemsCount = dataGridControl.CustomItemContainerGenerator.ItemCount; - } - - if( scrollViewer.ExtentHeight == itemsCount ) - return Orientation.Vertical; - - return Orientation.Horizontal; - } - - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1800:DoNotCastUnnecessarily" )] - internal static Orientation GetItemScrollingOrientation( DataGridControl dataGridControl ) - { - int itemsCount = dataGridControl.Items.Count; - - ScrollViewer scrollViewer = dataGridControl.ScrollViewer; - FrameworkElement container = dataGridControl.ItemsHost; - - //if the Panel passed supports the CustomItemContainerGenerator, then retrieve the itemcount from the customItemContainerGenerator - if( ( container is DataGridVirtualizingPanel ) || ( container is DataGridItemsHost ) ) - { - itemsCount = dataGridControl.CustomItemContainerGenerator.ItemCount; - } - - Orientation foundOrientation = Orientation.Horizontal; - if( scrollViewer.ExtentHeight == itemsCount ) - { - foundOrientation = Orientation.Vertical; - } - else if( container is StackPanel ) - { - foundOrientation = ( ( StackPanel )container ).Orientation; - } - else if( container is WrapPanel ) - { - foundOrientation = ( ( WrapPanel )container ).Orientation; - } - else if( container is IAnimatedScrollInfo ) - { - foundOrientation = Orientation.Vertical; - } - else - { - foundOrientation = Orientation.Horizontal; - } - return foundOrientation; - } - - internal static bool IsPixelScrolling( DataGridControl dataGridControl, FrameworkElement container, ScrollViewer scrollViewer ) - { - int itemsCount = dataGridControl.Items.Count; - - //if the Panel passed supports the CustomItemContainerGenerator, then retrieve the itemcount from the customItemContainerGenerator - if( ( container is DataGridVirtualizingPanel ) || ( container is DataGridItemsHost ) ) - { - itemsCount = dataGridControl.CustomItemContainerGenerator.ItemCount; - } - - //This means that the ScrollViewer performs Items Scrolling - if( ( scrollViewer != null ) - && ( ( scrollViewer.ExtentHeight == itemsCount ) || ( scrollViewer.ExtentWidth == itemsCount ) ) - && ( container is IScrollInfo ) && ( scrollViewer.CanContentScroll == true ) ) - { - return false; - } - - return true; - } - - internal static void ResetScrollPositions( ScrollViewer scrollViewer ) - { - if( scrollViewer == null ) - { - throw new ArgumentNullException( "scrollViewer" ); - } - - DataGridScrollViewer dataGridScrollViewer = scrollViewer as DataGridScrollViewer; - if( dataGridScrollViewer != null ) - { - foreach( SynchronizedScrollViewer ssv in dataGridScrollViewer.SynchronizedScrollViewers ) - { - ssv.ScrollToTop(); - ssv.ScrollToLeftEnd(); - } - } - - scrollViewer.ScrollToTop(); - scrollViewer.ScrollToLeftEnd(); - - } - - //----------------- PRIVATE METHODS ------------------------- - - private static HitTestFilterBehavior MyFilterFunct( DependencyObject obj ) - { - Panel panel = m_sGridControl.ItemsHost as Panel; - - //if the object passed is a direct child of the ItemsHostPanel; keep it - if( ( panel != null ) - && ( panel.Children.Contains( ( UIElement )obj ) == true ) ) - { - m_sVisibleChildList.Add( obj ); - - return HitTestFilterBehavior.ContinueSkipChildren; - } - else //otherwise, discard it. - { - return HitTestFilterBehavior.ContinueSkipSelf; - } - } - - private static HitTestResultBehavior UselessResultCallback( HitTestResult htr ) - { - return HitTestResultBehavior.Continue; - } - - private static bool IsABetterFirstRow( DependencyObject referenceChild, Nullable referenceOffset, Vector newOffset ) - { - bool retval = false; - - if( referenceChild != null ) - { - if( ( DoubleUtil.AreClose( referenceOffset.Value.Y, newOffset.Y ) == true ) && ( newOffset.X < referenceOffset.Value.X ) ) - { - retval = true; - } - else if( referenceOffset.Value.Y > newOffset.Y ) - { - retval = true; - } - } - else - { - retval = true; - } - - return retval; - } - - private static bool IsABetterLastRow( DependencyObject referenceChild, Nullable referenceOffset, Vector newOffset ) - { - bool retval = false; - - if( referenceChild != null ) - { - if( ( DoubleUtil.AreClose( referenceOffset.Value.Y, newOffset.Y ) == true ) && ( newOffset.X > referenceOffset.Value.X ) ) - { - retval = true; - } - else if( referenceOffset.Value.Y < newOffset.Y ) - { - retval = true; - } - } - else - { - retval = true; - } - - return retval; - } - - //----------------- FIELDS ------------------------- - - private static ScrollViewerHelper m_singleInstance; // = null; - private static List m_sVisibleChildList = new List(); - private static DataGridControl m_sGridControl; // = null; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectedCellsStorage.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectedCellsStorage.cs deleted file mode 100644 index aee175fe..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectedCellsStorage.cs +++ /dev/null @@ -1,594 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using Xceed.Utils.Collections; - -namespace Xceed.Wpf.DataGrid -{ - internal class SelectedCellsStorage : ICloneable, IEnumerable, IEnumerable - { - internal SelectedCellsStorage( DataGridContext dataGridContext ) - { - // dataGridContext can be null for store that we don't want to auto-get Items from index - m_dataGridContext = dataGridContext; - } - - #region Count Property - - public int Count - { - get - { - return m_ranges.Count; - } - } - - #endregion - - #region DataGridContext Property - - public DataGridContext DataGridContext - { - get - { - return m_dataGridContext; - } - } - - private readonly DataGridContext m_dataGridContext; - - #endregion - - #region [] Property - - public SelectionCellRangeWithItems this[ int index ] - { - get - { - return m_ranges[ index ].Value; - } - private set - { - this.RemoveAt( index, false ); - this.Insert( index, value, false ); - } - } - - #endregion - - public void Add( SelectionCellRangeWithItems rangeWithItems ) - { - Debug.Assert( m_ranges.All( r => r.Value.CellRange.Intersect( rangeWithItems.CellRange ).IsEmpty ), "Part of this range is already selected" ); - - var itemRangeWithItems = rangeWithItems.ItemRangeWithItems; - - SelectedItemsStorage.UpdateSelectionRangeWithItemsFromAdd( m_dataGridContext, itemRangeWithItems, ref itemRangeWithItems ); - - var newRangeWithItems = new SelectionCellRangeWithItems( itemRangeWithItems.Range, itemRangeWithItems.Items, rangeWithItems.ColumnRange ); - - this.Insert( this.Count, newRangeWithItems, true ); - } - - public void Clear() - { - m_ranges.Clear(); - m_map.Clear(); - } - - public bool Contains( int itemIndex, int columnIndex ) - { - if( ( itemIndex < 0 ) || ( itemIndex >= int.MaxValue ) || ( columnIndex < 0 ) || ( columnIndex >= int.MaxValue ) ) - return false; - - return this.Contains( new SelectionCellRange( itemIndex, columnIndex ) ); - } - - public bool Contains( SelectionCellRange range ) - { - if( ( m_ranges.Count <= 0 ) || ( SelectedCellsStorage.IsEmpty( range ) ) ) - return false; - - return this.Contains( new SelectionCellRangeWithItems( range.ItemRange, null, range.ColumnRange ) ); - } - - public bool Contains( SelectionCellRangeWithItems rangeWithItems ) - { - if( ( m_ranges.Count <= 0 ) || ( SelectedCellsStorage.IsEmpty( rangeWithItems ) ) ) - return false; - - if( rangeWithItems.Length == 1 ) - return this.IndexOfOverlap( rangeWithItems ).Any(); - - var store = new SelectedCellsStorage( null ); - store.Add( rangeWithItems ); - - foreach( var match in this.IndexOfOverlap( rangeWithItems ) ) - { - store.Remove( m_ranges[ match ].Value ); - - if( store.Count == 0 ) - return true; - } - - return false; - } - - public bool Remove( SelectionCellRangeWithItems rangeWithItems ) - { - if( SelectedCellsStorage.IsEmpty( rangeWithItems ) ) - return true; - - // It improves performance to leave early and prevent empty enumerators creation. - if( m_ranges.Count <= 0 ) - return false; - - // The SelectionCellRange.IsEmpty should be mapped to the item range's SelectionRange.IsEmpty property. - Debug.Assert( !rangeWithItems.ItemRange.IsEmpty ); - - var matches = this.IndexOfOverlap( rangeWithItems ).OrderBy( index => index ).ToList(); - var rangeToRemove = rangeWithItems.CellRange; - - for( int i = matches.Count - 1; i >= 0; i-- ) - { - var index = matches[ i ]; - var currentRangeWithItems = m_ranges[ index ].Value; - var currentRange = currentRangeWithItems.CellRange; - var overlap = rangeToRemove.Intersect( currentRange ); - - Debug.Assert( !overlap.IsEmpty ); - - var newRanges = currentRange.Exclude( overlap ); - - if( newRanges.Length == 0 ) - { - this.RemoveAt( index, true ); - } - else - { - var currentRangeItems = currentRangeWithItems.ItemRangeWithItems; - - this[ index ] = new SelectionCellRangeWithItems( newRanges[ 0 ].ItemRange, currentRangeItems.GetItems( newRanges[ 0 ].ItemRange ), newRanges[ 0 ].ColumnRange ); - - if( newRanges.Length > 1 ) - { - for( int j = 1; j < newRanges.Length; j++ ) - { - this.Insert( index + j, new SelectionCellRangeWithItems( newRanges[ j ].ItemRange, currentRangeItems.GetItems( newRanges[ j ].ItemRange ), newRanges[ j ].ColumnRange ), false ); - } - - this.RepairIndex( index + 1 ); - } - } - } - - return ( matches.Count > 0 ); - } - - public void OffsetIndex( int startIndex, int offset ) - { - if( m_map.Count == 0 ) - return; - - // Used to offset index after an add or remove from the data source of the grid. - var offsetRange = new SelectionRange( startIndex, startIndex + Math.Abs( offset ) - 1 ); - - var entries = m_map.GetEntriesWithin( new RSTree2D.Area( startIndex, int.MaxValue - startIndex, 0, int.MaxValue ) ).OrderByDescending( e => e.Item.Index ).ToList(); - - // Adjust the range of all ranges greater or that overlaps the target range. - foreach( var entry in entries ) - { - var currentRangeWithItemsWrapper = entry.Item; - var currentRangeIndex = currentRangeWithItemsWrapper.Index; - var currentRangeWithItems = currentRangeWithItemsWrapper.Value; - var currentRange = currentRangeWithItems.ItemRange; - var currentRangeItems = currentRangeWithItems.ItemRangeWithItems.Items; - - Debug.Assert( !( offsetRange > currentRange ) ); - - var currentRangeIntersection = currentRange.Intersect( offsetRange ); - - // The range overlaps. - if( !currentRangeIntersection.IsEmpty ) - { - // Should only happen when adding since when we remove data from the source, we remove the - // the range from the list. - Debug.Assert( offset > 0 ); - - SelectionRange topRange; - SelectionRange bottomRange; - - if( currentRange.StartIndex > currentRange.EndIndex ) - { - if( currentRangeIntersection.EndIndex == currentRange.EndIndex ) - { - this[ currentRangeIndex ] = new SelectionCellRangeWithItems( - new SelectionRange( currentRange.StartIndex + offset, currentRange.EndIndex + offset ), - currentRangeItems, - currentRangeWithItems.ColumnRange ); - continue; - } - else - { - topRange = new SelectionRange( currentRange.StartIndex + offset, startIndex + offset ); - bottomRange = new SelectionRange( startIndex - 1, currentRange.EndIndex ); - } - } - else - { - if( currentRangeIntersection.StartIndex == currentRange.StartIndex ) - { - this[ currentRangeIndex ] = new SelectionCellRangeWithItems( - new SelectionRange( currentRange.StartIndex + offset, currentRange.EndIndex + offset ), - currentRangeItems, - currentRangeWithItems.ColumnRange ); - continue; - } - else - { - topRange = new SelectionRange( currentRange.StartIndex, startIndex - 1 ); - bottomRange = new SelectionRange( startIndex + offset, currentRange.EndIndex + offset ); - } - } - - object[] topItems = null; - object[] bottomItems = null; - - if( currentRangeItems != null ) - { - topItems = new object[ topRange.Length ]; - Array.Copy( currentRangeItems, 0, topItems, 0, topItems.Length ); - - bottomItems = new object[ bottomRange.Length ]; - Array.Copy( currentRangeItems, topItems.Length, bottomItems, 0, bottomItems.Length ); - } - - this[ currentRangeIndex ] = new SelectionCellRangeWithItems( topRange, topItems, currentRangeWithItems.ColumnRange ); - this.Insert( currentRangeIndex + 1, new SelectionCellRangeWithItems( bottomRange, bottomItems, currentRangeWithItems.ColumnRange ), true ); - } - // The range is greater. - else - { - this[ currentRangeIndex ] = new SelectionCellRangeWithItems( - new SelectionRange( currentRange.StartIndex + offset, currentRange.EndIndex + offset ), - currentRangeItems, - currentRangeWithItems.ColumnRange ); - } - } - } - - public void OffsetIndexBasedOnSourceNewIndex( int maxOffset ) - { - if( m_dataGridContext == null ) - throw new InvalidOperationException( "We must have a DataGridContext to find the new index." ); - - if( maxOffset == 0 ) - return; - - var sourceItems = m_dataGridContext.Items; - - for( int i = this.Count - 1; i >= 0; i-- ) - { - var rangeWithItems = this[ i ]; - var rangeItems = rangeWithItems.ItemRangeWithItems.Items; - - if( rangeItems == null ) - throw new InvalidOperationException( "We should have items to find the new index." ); - - var item = rangeItems[ 0 ]; - var range = rangeWithItems.ItemRange; - var startIndex = range.StartIndex; - - if( maxOffset < 0 ) - { - for( int j = 0; j >= maxOffset; j-- ) - { - if( object.Equals( sourceItems.GetItemAt( startIndex ), item ) ) - { - if( j != 0 ) - { - this[ i ] = new SelectionCellRangeWithItems( new SelectionRange( range.StartIndex + j, range.EndIndex + j ), rangeItems, rangeWithItems.ColumnRange ); - } - - break; - } - - startIndex--; - - if( startIndex < 0 ) - break; - } - } - else - { - var sourceItemCount = sourceItems.Count; - - for( int j = 0; j <= maxOffset; j++ ) - { - if( object.Equals( sourceItems.GetItemAt( startIndex ), item ) ) - { - if( j != 0 ) - { - this[ i ] = new SelectionCellRangeWithItems( new SelectionRange( range.StartIndex + j, range.EndIndex + j ), rangeItems, rangeWithItems.ColumnRange ); - } - - break; - } - - startIndex++; - - if( startIndex >= sourceItemCount ) - break; - } - } - } - } - - public IEnumerable GetIntersectedColumnRanges( SelectionCellRange range ) - { - // It improves performance to leave early and prevent empty enumerators creation. - if( m_ranges.Count <= 0 ) - return Enumerable.Empty(); - - return ( from match in this.IndexOfOverlap( range ) - let current = m_ranges[ match ].Value - let intersection = current.CellRange.Intersect( range ) - select intersection.ColumnRange ).ToList(); - } - - public IEnumerable GetIntersectedCellRangesWithItems( SelectionCellRange range ) - { - // It improves performance to leave early and prevent empty enumerators creation. - if( m_ranges.Count <= 0 ) - return Enumerable.Empty(); - - return ( from match in this.IndexOfOverlap( range ) - let current = m_ranges[ match ].Value - let intersection = current.CellRange.Intersect( range ) - select new SelectionCellRangeWithItems( - intersection.ItemRange, - current.ItemRangeWithItems.GetItems( intersection.ItemRange ), - intersection.ColumnRange ) ).ToList(); - } - - private static RSTree2D.Area GetArea( SelectionCellRange range ) - { - if( range.IsEmpty ) - return RSTree2D.Area.Empty; - - var itemRange = range.ItemRange; - var columnRange = range.ColumnRange; - int rs, re, cs, ce; - - if( itemRange.StartIndex <= itemRange.EndIndex ) - { - rs = itemRange.StartIndex; - re = itemRange.EndIndex; - } - else - { - rs = itemRange.EndIndex; - re = itemRange.StartIndex; - } - - if( columnRange.StartIndex <= columnRange.EndIndex ) - { - cs = columnRange.StartIndex; - ce = columnRange.EndIndex; - } - else - { - cs = columnRange.EndIndex; - ce = columnRange.StartIndex; - } - - return new RSTree2D.Area( rs, re - rs + 1, cs, ce - cs + 1 ); - } - - private static RSTree2D.Area GetArea( SelectionCellRangeWithItems range ) - { - return SelectedCellsStorage.GetArea( range.CellRange ); - } - - private void Insert( int index, SelectionCellRangeWithItems item, bool repairIndex ) - { - var wrapper = new SelectionCellRangeWithItemsWrapper( item, index ); - - m_ranges.Insert( index, wrapper ); - - if( repairIndex ) - { - this.RepairIndex( index + 1 ); - } - - if( !SelectedCellsStorage.IsEmpty( item ) ) - { - m_map.Add( SelectedCellsStorage.GetArea( item ), wrapper ); - } - } - - private void RemoveAt( int index, bool repairIndex ) - { - var wrapper = m_ranges[ index ]; - var rangeWithItems = wrapper.Value; - - Debug.Assert( wrapper.Index == index ); - - if( !SelectedCellsStorage.IsEmpty( rangeWithItems ) ) - { - var removed = m_map.Remove( SelectedCellsStorage.GetArea( rangeWithItems ), wrapper ); - Debug.Assert( removed, "Failed to remove the selection range." ); - - // Since there should be only a single instance of the wrapper within the collection, try an altenate strategy. - if( !removed ) - { - var entry = m_map.FirstOrDefault( e => e.Item == wrapper ); - if( entry.Item == wrapper ) - { - removed = m_map.Remove( entry ); - } - - Debug.Assert( removed, "Failed to find the selection range." ); - } - } - - m_ranges.RemoveAt( index ); - - if( repairIndex ) - { - this.RepairIndex( index ); - } - } - - private void RepairIndex( int index ) - { - Debug.Assert( index >= 0 ); - - for( int i = index; i < m_ranges.Count; i++ ) - { - m_ranges[ i ].Index = i; - } - } - - private IEnumerable IndexOfOverlap( SelectionCellRange range ) - { - // It improves performance to leave early. - if( m_map.Count <= 0 ) - yield break; - - foreach( var entry in m_map.GetEntriesWithin( SelectedCellsStorage.GetArea( range ) ) ) - { - var candidate = entry.Item; - var target = candidate.Value; - var overlap = range.Intersect( target.CellRange ); - - Debug.Assert( !SelectedCellsStorage.IsEmpty( overlap ) ); - - if( !SelectedCellsStorage.IsEmpty( overlap ) ) - yield return candidate.Index; - } - } - - private IEnumerable IndexOfOverlap( SelectionCellRangeWithItems target ) - { - var targetRange = target.CellRange; - var targetRangeWithItems = target.ItemRangeWithItems; - var targetItemRange = targetRange.ItemRange; - - foreach( var match in this.IndexOfOverlap( targetRange ) ) - { - var currentRangeWithItems = m_ranges[ match ].Value; - var overlap = targetItemRange.Intersect( currentRangeWithItems.ItemRange ); - - Debug.Assert( !overlap.IsEmpty ); - - if( targetRangeWithItems.IsItemsEqual( overlap, currentRangeWithItems.ItemRangeWithItems ) ) - yield return match; - } - } - - private static bool IsEmpty( SelectionCellRange range ) - { - return ( range.ItemRange.IsEmpty ) - || ( range.ColumnRange.IsEmpty ); - } - - private static bool IsEmpty( SelectionCellRangeWithItems rangeWithItems ) - { - return ( rangeWithItems.ItemRange.IsEmpty ) - || ( rangeWithItems.ColumnRange.IsEmpty ); - } - - #region ICloneable Members - - public object Clone() - { - var copy = new SelectedCellsStorage( m_dataGridContext ); - - for( int i = 0; i < m_ranges.Count; i++ ) - { - copy.Insert( i, m_ranges[ i ].Value, false ); - } - - return copy; - } - - #endregion - - #region IEnumerable Members - - public IEnumerator GetEnumerator() - { - return m_ranges.Select( item => item.Value ).GetEnumerator(); - } - - #endregion - - #region IEnumerable Members - - IEnumerator IEnumerable.GetEnumerator() - { - return this.GetEnumerator(); - } - - #endregion - - private readonly List m_ranges = new List(); - private readonly RSTree2D m_map = new RSTree2D(); - - #region SelectionCellRangeWithItemsWrapper Private Class - - // We are wrapping the SelectionCellRangeWithItems structure inside a class so our collections - // may target the same object. - private sealed class SelectionCellRangeWithItemsWrapper - { - internal SelectionCellRangeWithItemsWrapper( SelectionCellRangeWithItems value, int index ) - { - m_value = value; - m_index = index; - } - - internal SelectionCellRangeWithItems Value - { - get - { - return m_value; - } - } - - internal int Index - { - get - { - return m_index; - } - set - { - m_index = value; - } - } - - private readonly SelectionCellRangeWithItems m_value; - private int m_index; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectedItemsStorage.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectedItemsStorage.cs deleted file mode 100644 index 85ce3541..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectedItemsStorage.cs +++ /dev/null @@ -1,653 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using Xceed.Utils.Collections; - -namespace Xceed.Wpf.DataGrid -{ - internal class SelectedItemsStorage : ICloneable, IEnumerable, IEnumerable - { - internal SelectedItemsStorage( DataGridContext dataGridContext ) - { - // dataGridContext can be null for store that we don't want to auto-get Items from index - m_dataGridContext = dataGridContext; - } - - #region Count Property - - public int Count - { - get - { - return m_ranges.Count; - } - } - - #endregion - - #region ItemsCount Property - - public int ItemsCount - { - get - { - return m_itemsCount; - } - } - - private int m_itemsCount; - - #endregion - - #region DataGridContext Property - - public DataGridContext DataGridContext - { - get - { - return m_dataGridContext; - } - } - - private readonly DataGridContext m_dataGridContext; - - #endregion - - #region [] Property - - public SelectionRangeWithItems this[ int index ] - { - get - { - return m_ranges[ index ].Value; - } - private set - { - this.RemoveAt( index, false ); - this.Insert( index, value, false ); - } - } - - #endregion - - public static void UpdateSelectionRangeWithItemsFromAdd( - DataGridContext dataGridContext, - SelectionRangeWithItems newRangeWithItems, - ref SelectionRangeWithItems lastRangeWithItems ) - { - // Only work for adding at the end of an existing range. - - object[] newRangeItems = newRangeWithItems.Items; - - if( ( dataGridContext == null ) - || ( ( dataGridContext.ItemsSourceCollection == null ) && ( newRangeItems == null ) ) - || ( dataGridContext.ItemsSourceCollection is DataGridVirtualizingCollectionViewBase ) ) - { - lastRangeWithItems = new SelectionRangeWithItems( new SelectionRange( lastRangeWithItems.Range.StartIndex, newRangeWithItems.Range.EndIndex ), null ); - return; - } - - SharedList newItemsList; - - if( newRangeWithItems == lastRangeWithItems ) - { - if( newRangeItems != null ) - return; - - newItemsList = new SharedList( lastRangeWithItems.Length ); - } - else - { - int minNewCapacity = lastRangeWithItems.Length + newRangeWithItems.Length; - - // Optimization, re-use the ItemsList if available. - if( lastRangeWithItems.SharedList != null ) - { - newItemsList = lastRangeWithItems.SharedList.Value; - newItemsList.EnsureCapacity( minNewCapacity ); - } - else - { - newItemsList = new SharedList( minNewCapacity ); - newItemsList.AddRange( lastRangeWithItems.Items ); - } - } - - var rangeToUpdateStartIndex = lastRangeWithItems.Range.StartIndex; - var newRangeEndIndex = newRangeWithItems.Range.EndIndex; - - // If new range have no items set, found the items and set it. - if( newRangeItems == null ) - { - var items = dataGridContext.Items; - var newRangeStartIndex = newRangeWithItems.Range.StartIndex; - - if( newRangeEndIndex > newRangeStartIndex ) - { - for( int i = newRangeStartIndex; i <= newRangeEndIndex; i++ ) - { - newItemsList.Add( items.GetItemAt( i ) ); - } - } - else - { - for( int i = newRangeStartIndex; i >= newRangeEndIndex; i-- ) - { - newItemsList.Add( items.GetItemAt( i ) ); - } - } - } - else - { - newItemsList.AddRange( newRangeItems ); - } - - lastRangeWithItems = new SelectionRangeWithItems( new SelectionRange( rangeToUpdateStartIndex, newRangeEndIndex ), newItemsList ); - } - - public void Add( SelectionRangeWithItems rangeWithItems ) - { - Debug.Assert( !this.Contains( rangeWithItems.Range ) ); - - m_itemsCount += rangeWithItems.Length; - - if( this.Count > 0 ) - { - var lastIndex = this.Count - 1; - var lastRangeWithItems = this[ lastIndex ]; - var lastRange = lastRangeWithItems.Range; - - if( ( lastRange.EndIndex + 1 ) == rangeWithItems.Range.StartIndex ) - { - Debug.Assert( rangeWithItems.Range.EndIndex > lastRange.EndIndex ); - - SelectedItemsStorage.UpdateSelectionRangeWithItemsFromAdd( m_dataGridContext, rangeWithItems, ref lastRangeWithItems ); - - this[ lastIndex ] = lastRangeWithItems; - return; - } - else if( ( lastRange.EndIndex - 1 ) == rangeWithItems.Range.StartIndex ) - { - Debug.Assert( rangeWithItems.Range.EndIndex < lastRange.EndIndex ); - - SelectedItemsStorage.UpdateSelectionRangeWithItemsFromAdd( m_dataGridContext, rangeWithItems, ref lastRangeWithItems ); - - this[ lastIndex ] = lastRangeWithItems; - return; - } - } - - SelectedItemsStorage.UpdateSelectionRangeWithItemsFromAdd( m_dataGridContext, rangeWithItems, ref rangeWithItems ); - - this.Insert( this.Count, rangeWithItems, true ); - } - - public void Clear() - { - m_itemsCount = 0; - m_ranges.Clear(); - m_map.Clear(); - } - - public SelectionRange[] ToSelectionRangeArray() - { - return ( from item in m_ranges - select item.Value.Range ).ToArray(); - } - - public bool Contains( int itemIndex ) - { - if( ( itemIndex < -1 ) || ( itemIndex >= int.MaxValue ) ) - return false; - - return this.Contains( new SelectionRange( itemIndex ) ); - } - - public bool Contains( SelectionRange range ) - { - return m_map.Overlaps( SelectedItemsStorage.GetArea( range ) ); - } - - public bool Contains( SelectionRangeWithItems rangeWithItems ) - { - return this.IndexOfOverlap( rangeWithItems ).Any(); - } - - public bool Remove( SelectionRangeWithItems rangeWithItems ) - { - if( rangeWithItems.IsEmpty ) - return this.RemoveEmptyRange( rangeWithItems ); - - return this.RemoveRangeWithItems( rangeWithItems ); - } - - public void OffsetIndex( int startIndex, int offset ) - { - if( m_map.Count == 0 ) - return; - - // Used to offset index after an add or remove from the data source of the grid. - var offsetRange = new SelectionRange( startIndex, startIndex + Math.Abs( offset ) - 1 ); - - var entries = m_map.GetEntriesWithin( new RSTree1D.Area( startIndex, int.MaxValue - startIndex ) ).OrderByDescending( e => e.Item.Index ).ToList(); - - // Adjust the range of all ranges greater or that overlaps the target range. - foreach( var entry in entries ) - { - var currentRangeWithItemsWrapper = entry.Item; - var currentRangeIndex = currentRangeWithItemsWrapper.Index; - var currentRangeWithItems = currentRangeWithItemsWrapper.Value; - var currentRange = currentRangeWithItems.Range; - var currentRangeItems = currentRangeWithItems.Items; - - Debug.Assert( !( offsetRange > currentRange ) ); - - var currentRangeIntersection = currentRange.Intersect( offsetRange ); - - // The range overlaps. - if( !currentRangeIntersection.IsEmpty ) - { - // Should only happen when adding since when we remove data from the source, we remove the - // the range from the list. - Debug.Assert( offset > 0 ); - - SelectionRange topRange; - SelectionRange bottomRange; - - if( currentRange.StartIndex > currentRange.EndIndex ) - { - if( currentRangeIntersection.EndIndex == currentRange.EndIndex ) - { - this[ currentRangeIndex ] = new SelectionRangeWithItems( - new SelectionRange( currentRange.StartIndex + offset, currentRange.EndIndex + offset ), - currentRangeItems ); - continue; - } - else - { - topRange = new SelectionRange( currentRange.StartIndex + offset, startIndex + offset ); - bottomRange = new SelectionRange( startIndex - 1, currentRange.EndIndex ); - } - } - else - { - if( currentRangeIntersection.StartIndex == currentRange.StartIndex ) - { - this[ currentRangeIndex ] = new SelectionRangeWithItems( - new SelectionRange( currentRange.StartIndex + offset, currentRange.EndIndex + offset ), - currentRangeItems ); - continue; - } - else - { - topRange = new SelectionRange( currentRange.StartIndex, startIndex - 1 ); - bottomRange = new SelectionRange( startIndex + offset, currentRange.EndIndex + offset ); - } - } - - object[] topItems = null; - object[] bottomItems = null; - - if( currentRangeItems != null ) - { - topItems = new object[ topRange.Length ]; - Array.Copy( currentRangeItems, 0, topItems, 0, topItems.Length ); - - bottomItems = new object[ bottomRange.Length ]; - Array.Copy( currentRangeItems, topItems.Length, bottomItems, 0, bottomItems.Length ); - } - - this[ currentRangeIndex ] = new SelectionRangeWithItems( topRange, topItems ); - this.Insert( currentRangeIndex + 1, new SelectionRangeWithItems( bottomRange, bottomItems ), true ); - } - // The range is greater. - else - { - this[ currentRangeIndex ] = new SelectionRangeWithItems( - new SelectionRange( currentRange.StartIndex + offset, currentRange.EndIndex + offset ), - currentRangeItems ); - } - } - } - - public void OffsetIndexBasedOnSourceNewIndex( int maxOffset ) - { - if( m_dataGridContext == null ) - throw new InvalidOperationException( "We must have a DataGridContext to find the new index." ); - - if( maxOffset == 0 ) - return; - - var sourceItems = m_dataGridContext.Items; - - for( int i = this.Count - 1; i >= 0; i-- ) - { - var rangeWithItems = this[ i ]; - var rangeItems = rangeWithItems.Items; - - if( rangeItems == null ) - throw new InvalidOperationException( "We should have items to find the new index." ); - - var item = rangeItems[ 0 ]; - var range = rangeWithItems.Range; - var startIndex = range.StartIndex; - - if( maxOffset < 0 ) - { - for( int j = 0; j >= maxOffset; j-- ) - { - if( object.Equals( sourceItems.GetItemAt( startIndex ), item ) ) - { - if( j != 0 ) - { - this[ i ] = new SelectionRangeWithItems( new SelectionRange( range.StartIndex + j, range.EndIndex + j ), rangeItems ); - } - - break; - } - - startIndex--; - - if( startIndex < 0 ) - break; - } - } - else - { - var sourceItemCount = sourceItems.Count; - - for( int j = 0; j <= maxOffset; j++ ) - { - if( object.Equals( sourceItems.GetItemAt( startIndex ), item ) ) - { - if( j != 0 ) - { - this[ i ] = new SelectionRangeWithItems( new SelectionRange( range.StartIndex + j, range.EndIndex + j ), rangeItems ); - } - - break; - } - - startIndex++; - - if( startIndex >= sourceItemCount ) - break; - } - } - } - } - - private static RSTree1D.Area GetArea( SelectionRange range ) - { - if( range.IsEmpty ) - return RSTree1D.Area.Empty; - - return new RSTree1D.Area( Math.Min( range.StartIndex, range.EndIndex ), range.Length ); - } - - private static RSTree1D.Area GetArea( SelectionRangeWithItems range ) - { - return SelectedItemsStorage.GetArea( range.Range ); - } - - private void Insert( int index, SelectionRangeWithItems item, bool repairIndex ) - { - var wrapper = new SelectionRangeWithItemsWrapper( item, index ); - - m_ranges.Insert( index, wrapper ); - - if( repairIndex ) - { - this.RepairIndex( index + 1 ); - } - - if( !item.IsEmpty ) - { - m_map.Add( SelectedItemsStorage.GetArea( item ), wrapper ); - } - } - - private void RemoveAt( int index, bool repairIndex ) - { - var wrapper = m_ranges[ index ]; - var rangeWithItems = wrapper.Value; - - Debug.Assert( wrapper.Index == index ); - - if( !rangeWithItems.IsEmpty ) - { - var removed = m_map.Remove( SelectedItemsStorage.GetArea( rangeWithItems ), wrapper ); - Debug.Assert( removed, "Failed to remove the selection range." ); - - // Since there should be only a single instance of the wrapper within the collection, try an altenate strategy. - if( !removed ) - { - var entry = m_map.FirstOrDefault( e => e.Item == wrapper ); - if( entry.Item == wrapper ) - { - removed = m_map.Remove( entry ); - } - - Debug.Assert( removed, "Failed to find the selection range." ); - } - } - - m_ranges.RemoveAt( index ); - - if( repairIndex ) - { - this.RepairIndex( index ); - } - } - - private void RepairIndex( int index ) - { - Debug.Assert( index >= 0 ); - - for( int i = index; i < m_ranges.Count; i++ ) - { - m_ranges[ i ].Index = i; - } - } - - private bool RemoveEmptyRange( SelectionRangeWithItems rangeWithItems ) - { - Debug.Assert( rangeWithItems.IsEmpty ); - - bool removed = false; - - var itemsToRemove = rangeWithItems.Items; - var itemsToRemoveCount = ( itemsToRemove == null ) ? 0 : itemsToRemove.Length; - var itemOffsetToRemove = 0; - - do - { - for( int i = this.Count - 1; i >= 0; i-- ) - { - var currentRangeWithItems = this[ i ]; - var currentRange = currentRangeWithItems.Range; - - var itemOffset = Array.IndexOf( currentRangeWithItems.Items, itemsToRemove[ itemOffsetToRemove ] ); - if( itemOffset == -1 ) - continue; - - var overlap = new SelectionRange( currentRange.GetIndexFromItemOffset( itemOffset ) ); - - removed = true; - m_itemsCount -= overlap.Length; - - var newRanges = currentRange.Exclude( overlap ); - - if( newRanges.Length == 0 ) - { - this.RemoveAt( i, true ); - } - else - { - this[ i ] = new SelectionRangeWithItems( newRanges[ 0 ], currentRangeWithItems.GetItems( newRanges[ 0 ] ) ); - - if( newRanges.Length > 1 ) - { - Debug.Assert( newRanges.Length == 2 ); - this.Insert( i + 1, new SelectionRangeWithItems( newRanges[ 1 ], currentRangeWithItems.GetItems( newRanges[ 1 ] ) ), true ); - } - } - } - - itemOffsetToRemove++; - } - while( itemOffsetToRemove < itemsToRemoveCount ); - - return removed; - } - - private bool RemoveRangeWithItems( SelectionRangeWithItems rangeWithItems ) - { - Debug.Assert( !rangeWithItems.IsEmpty ); - - var rangeToRemove = rangeWithItems.Range; - var matches = this.IndexOfOverlap( rangeWithItems ).OrderBy( item => item ).ToList(); - - for( int i = matches.Count - 1; i >= 0; i-- ) - { - var index = matches[ i ]; - var currentRangeWithItems = this[ index ]; - var currentRange = currentRangeWithItems.Range; - var overlap = rangeToRemove.Intersect( currentRange ); - - Debug.Assert( !overlap.IsEmpty ); - - m_itemsCount -= overlap.Length; - - var newRanges = currentRange.Exclude( overlap ); - - if( newRanges.Length == 0 ) - { - this.RemoveAt( index, true ); - } - else - { - this[ index ] = new SelectionRangeWithItems( newRanges[ 0 ], currentRangeWithItems.GetItems( newRanges[ 0 ] ) ); - - if( newRanges.Length > 1 ) - { - Debug.Assert( newRanges.Length == 2 ); - this.Insert( index + 1, new SelectionRangeWithItems( newRanges[ 1 ], currentRangeWithItems.GetItems( newRanges[ 1 ] ) ), true ); - } - } - } - - return ( matches.Count > 0 ); - } - - private IEnumerable IndexOfOverlap( SelectionRangeWithItems rangeWithItems ) - { - foreach( var entry in m_map.GetEntriesWithin( SelectedItemsStorage.GetArea( rangeWithItems ) ) ) - { - var candidate = entry.Item; - var target = candidate.Value; - var overlap = rangeWithItems.Range.Intersect( target.Range ); - - Debug.Assert( !overlap.IsEmpty ); - - if( !overlap.IsEmpty && ( rangeWithItems.IsItemsEqual( overlap, target ) ) ) - yield return candidate.Index; - } - } - - #region ICloneable Members - - public object Clone() - { - var copy = new SelectedItemsStorage( m_dataGridContext ); - - for( int i = 0; i < m_ranges.Count; i++ ) - { - copy.Insert( i, m_ranges[ i ].Value, false ); - } - - copy.m_itemsCount = m_itemsCount; - - return copy; - } - - #endregion - - #region IEnumerable Members - - public IEnumerator GetEnumerator() - { - return m_ranges.Select( item => item.Value ).GetEnumerator(); - } - - #endregion - - #region IEnumerable Members - - IEnumerator IEnumerable.GetEnumerator() - { - return this.GetEnumerator(); - } - - #endregion - - private readonly List m_ranges = new List(); - private readonly RSTree1D m_map = new RSTree1D(); - - #region SelectionRangeWithItemsWrapper Private Class - - // We are wrapping the SelectionRangeWithItems structure inside a class so our collections - // may target the same object. - private sealed class SelectionRangeWithItemsWrapper - { - internal SelectionRangeWithItemsWrapper( SelectionRangeWithItems value, int index ) - { - m_value = value; - m_index = index; - } - - internal SelectionRangeWithItems Value - { - get - { - return m_value; - } - } - - internal int Index - { - get - { - return m_index; - } - set - { - m_index = value; - } - } - - private readonly SelectionRangeWithItems m_value; - private int m_index; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionCellRange.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionCellRange.cs deleted file mode 100644 index 201f46f4..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionCellRange.cs +++ /dev/null @@ -1,205 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Diagnostics; - -namespace Xceed.Wpf.DataGrid -{ - public struct SelectionCellRange - { - public static readonly SelectionCellRange Empty = new SelectionCellRange( -1, -1 ); - - #region CONSTRUCTORS - - public SelectionCellRange( int itemIndex, int columnIndex ) - { - if( ( itemIndex == -1 || columnIndex == -1 ) && ( itemIndex != -1 || columnIndex != -1 ) ) - throw new ArgumentException( "itemIndex and columnIndex must be equal if the value of one is -1." ); - - if( ( itemIndex < -1 ) || ( itemIndex >= int.MaxValue ) ) - throw new ArgumentOutOfRangeException( "itemIndex", "itemIndex must be equal to or greater than -1 and lower than int.MaxValue." ); - - if( ( columnIndex < -1 ) || ( columnIndex >= int.MaxValue ) ) - throw new ArgumentOutOfRangeException( "columnIndex", "columnIndex must be equal to or greater than -1 and lower than int.MaxValue." ); - - m_itemRange = new SelectionRange( itemIndex ); - m_columnRange = new SelectionRange( columnIndex ); - } - - public SelectionCellRange( int itemStartIndex, int columnStartIndex, int itemEndIndex, int columnEndIndex ) - { - if( ( itemStartIndex < 0 ) || ( itemStartIndex >= int.MaxValue ) ) - throw new ArgumentOutOfRangeException( "itemStartIndex", "itemStartIndex must be equal to or greater than zero and lower than int.MaxValue." ); - - if( ( itemEndIndex < 0 ) || ( itemEndIndex >= int.MaxValue ) ) - throw new ArgumentOutOfRangeException( "itemEndIndex", "itemEndIndex must be equal to or greater than zero and lower than int.MaxValue." ); - - if( ( columnStartIndex < 0 ) || ( columnStartIndex >= int.MaxValue ) ) - throw new ArgumentOutOfRangeException( "columnStartIndex", "columnStartIndex must be equal to or greater than zero and lower than int.MaxValue." ); - - if( ( columnEndIndex < 0 ) || ( columnEndIndex >= int.MaxValue ) ) - throw new ArgumentOutOfRangeException( "columnEndIndex", "columnEndIndex must be equal to or greater than zero and lower than int.MaxValue." ); - - m_itemRange = new SelectionRange( itemStartIndex, itemEndIndex ); - m_columnRange = new SelectionRange( columnStartIndex, columnEndIndex ); - } - - public SelectionCellRange( SelectionRange itemRange, SelectionRange columnRange ) - { - m_itemRange = itemRange; - m_columnRange = columnRange; - } - - #endregion - - #region ItemRange Property - - public SelectionRange ItemRange - { - get - { - return m_itemRange; - } - set - { - m_itemRange = value; - } - } - - private SelectionRange m_itemRange; - - #endregion - - #region ColumnRange Property - - public SelectionRange ColumnRange - { - get - { - return m_columnRange; - } - set - { - m_columnRange = value; - } - } - - private SelectionRange m_columnRange; - - #endregion - - #region Length Property - - public int Length - { - get - { - return m_itemRange.Length * m_columnRange.Length; - } - } - - #endregion - - #region IsEmpty Property - - public bool IsEmpty - { - get - { - return m_itemRange.IsEmpty; - } - } - - #endregion - - public static bool operator ==( SelectionCellRange range1, SelectionCellRange range2 ) - { - return range1.Equals( range2 ); - } - - public static bool operator !=( SelectionCellRange range1, SelectionCellRange range2 ) - { - return !range1.Equals( range2 ); - } - - public SelectionCellRange Intersect( SelectionCellRange range ) - { - SelectionCellRange cellRangeIntersection = SelectionCellRange.Empty; - - SelectionRange itemRange = range.ItemRange; - SelectionRange itemRangeIntersection = m_itemRange.Intersect( itemRange ); - - if( itemRangeIntersection.IsEmpty ) - return SelectionCellRange.Empty; - - SelectionRange columnRange = range.ColumnRange; - SelectionRange columnRangeIntersection = m_columnRange.Intersect( columnRange ); - - if( columnRangeIntersection.IsEmpty ) - return SelectionCellRange.Empty; - - return new SelectionCellRange( itemRangeIntersection, columnRangeIntersection ); - } - - public SelectionCellRange[] Exclude( SelectionCellRange cellRangeToExclude ) - { - if( cellRangeToExclude.IsEmpty ) - return new SelectionCellRange[] { this }; - - SelectionCellRange cellRangeIntersection = this.Intersect( cellRangeToExclude ); - - if( cellRangeIntersection.IsEmpty ) - return new SelectionCellRange[] { this }; - - SelectionRange[] itemRanges = m_itemRange.Exclude( cellRangeToExclude.ItemRange ); - SelectionRange[] columnRanges = m_columnRange.Exclude( cellRangeToExclude.ColumnRange ); - SelectionCellRange[] cellRanges = new SelectionCellRange[ itemRanges.Length + columnRanges.Length ]; - int index = 0; - - foreach( SelectionRange itemRange in itemRanges ) - { - cellRanges[ index ] = new SelectionCellRange( itemRange, m_columnRange ); - index++; - } - - foreach( SelectionRange columnRange in columnRanges ) - { - cellRanges[ index ] = new SelectionCellRange( cellRangeIntersection.ItemRange, columnRange ); - index++; - } - - Debug.Assert( index == cellRanges.Length ); - return cellRanges; - } - - public override bool Equals( object obj ) - { - if( !( obj is SelectionCellRange ) ) - return false; - - SelectionCellRange selectionRange = ( SelectionCellRange )obj; - - return ( selectionRange.m_itemRange == m_itemRange ) - && ( selectionRange.m_columnRange == m_columnRange ); - } - - public override int GetHashCode() - { - return ( m_itemRange.GetHashCode() ^ m_columnRange.GetHashCode() ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionCellRangeCollection.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionCellRangeCollection.cs deleted file mode 100644 index 183b8d8e..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionCellRangeCollection.cs +++ /dev/null @@ -1,325 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class SelectionCellRangeCollection : IList, IList - { - internal SelectionCellRangeCollection( SelectedCellsStorage collection ) - { - Debug.Assert( collection != null ); - - m_storage = collection; - } - - #region IList<> Members - - public SelectionCellRange this[ int index ] - { - get - { - return m_storage[ index ].CellRange; - } - set - { - throw new NotSupportedException(); - } - } - - public int IndexOf( SelectionCellRange item ) - { - var count = m_storage.Count; - - for( int i = 0; i < count; i++ ) - { - if( m_storage[ i ].CellRange == item ) - return i; - } - - return -1; - } - - public void Insert( int index, SelectionCellRange item ) - { - if( ( index < 0 ) || ( index > m_storage.Count ) ) - throw new ArgumentOutOfRangeException( "index", index, "index must be greater than or equal to zero and less than or equal to Count." ); - - var dataGridContext = m_storage.DataGridContext; - var dataGridControl = dataGridContext.DataGridControl; - - if( dataGridControl.SelectionUnit == SelectionUnit.Row ) - throw new InvalidOperationException( "Can't add cell range when SelectionUnit is Row." ); - - if( !( dataGridContext.ItemsSourceCollection is DataGridVirtualizingCollectionViewBase ) ) - { - var minIndex = Math.Min( item.ItemRange.StartIndex, item.ItemRange.EndIndex ); - var maxIndex = Math.Max( item.ItemRange.StartIndex, item.ItemRange.EndIndex ); - - if( ( minIndex < 0 ) || ( maxIndex >= dataGridContext.Items.Count ) ) - throw new ArgumentException( "The selection range targets items outside of the data source.", "item" ); - } - - var selectionManager = dataGridControl.SelectionChangerManager; - selectionManager.Begin(); - - try - { - selectionManager.SelectCells( dataGridContext, new SelectionCellRangeWithItems( item.ItemRange, null, item.ColumnRange ) ); - } - finally - { - selectionManager.End( true, true ); - } - } - - public void RemoveAt( int index ) - { - if( ( index < 0 ) || ( index >= m_storage.Count ) ) - throw new ArgumentOutOfRangeException( "index", index, "index must be greater than or equal to zero and less than Count." ); - - var dataGridContext = m_storage.DataGridContext; - var selectionManager = dataGridContext.DataGridControl.SelectionChangerManager; - selectionManager.Begin(); - - try - { - var cellRange = this[ index ]; - selectionManager.UnselectCells( dataGridContext, new SelectionCellRangeWithItems( cellRange.ItemRange, null, cellRange.ColumnRange ) ); - } - finally - { - selectionManager.End( true, true ); - } - } - - #endregion - - #region IList Members - - object IList.this[ int index ] - { - get - { - return this[ index ]; - } - set - { - this[ index ] = ( SelectionCellRange )value; - } - } - - bool IList.IsReadOnly - { - get - { - return ( ( ICollection )this ).IsReadOnly; - } - } - - bool IList.IsFixedSize - { - get - { - return false; - } - } - - int IList.Add( object item ) - { - this.Add( ( SelectionCellRange )item ); - return this.Count - 1; - } - - void IList.Clear() - { - this.Clear(); - } - - void IList.Insert( int index, object item ) - { - this.Insert( index, ( SelectionCellRange )item ); - } - - void IList.Remove( object item ) - { - this.Remove( ( SelectionCellRange )item ); - } - - void IList.RemoveAt( int index ) - { - this.RemoveAt( index ); - } - - bool IList.Contains( object item ) - { - return this.Contains( ( SelectionCellRange )item ); - } - - int IList.IndexOf( object item ) - { - return this.IndexOf( ( SelectionCellRange )item ); - } - - #endregion - - #region ICollection<> Members - - public int Count - { - get - { - return m_storage.Count; - } - } - - bool ICollection.IsReadOnly - { - get - { - return false; - } - } - - public void Add( SelectionCellRange item ) - { - this.Insert( m_storage.Count, item ); - } - - public void Clear() - { - var dataGridContext = m_storage.DataGridContext; - var selectionManager = dataGridContext.DataGridControl.SelectionChangerManager; - selectionManager.Begin(); - - try - { - selectionManager.UnselectAllCells( dataGridContext ); - } - finally - { - selectionManager.End( true, true ); - } - } - - public bool Contains( SelectionCellRange item ) - { - return ( this.IndexOf( item ) >= 0 ); - } - - public bool Remove( SelectionCellRange item ) - { - var dataGridContext = m_storage.DataGridContext; - var dataGridControl = dataGridContext.DataGridControl; - - if( dataGridControl.SelectionUnit == SelectionUnit.Row ) - throw new InvalidOperationException( "Can't remove cell range when SelectionUnit is Row." ); - - if( !( dataGridContext.ItemsSourceCollection is DataGridVirtualizingCollectionViewBase ) ) - { - var minIndex = Math.Min( item.ItemRange.StartIndex, item.ItemRange.EndIndex ); - var maxIndex = Math.Max( item.ItemRange.StartIndex, item.ItemRange.EndIndex ); - - if( ( minIndex < 0 ) || ( maxIndex >= dataGridContext.Items.Count ) ) - throw new ArgumentException( "The selection range targets items outside of the data source.", "item" ); - } - - var selectionManager = dataGridControl.SelectionChangerManager; - selectionManager.Begin(); - - try - { - return selectionManager.UnselectCells( dataGridContext, new SelectionCellRangeWithItems( item.ItemRange, null, item.ColumnRange ) ); - } - finally - { - selectionManager.End( true, true ); - } - } - - public void CopyTo( SelectionCellRange[] array, int arrayIndex ) - { - ( ( ICollection )this ).CopyTo( array, arrayIndex ); - } - - #endregion - - #region ICollection Members - - int ICollection.Count - { - get - { - return this.Count; - } - } - - object ICollection.SyncRoot - { - get - { - return m_storage; - } - } - - bool ICollection.IsSynchronized - { - get - { - return false; - } - } - - void ICollection.CopyTo( Array array, int arrayIndex ) - { - var count = m_storage.Count; - - for( int i = 0; i < count; i++ ) - { - array.SetValue( m_storage[ i ].CellRange, arrayIndex ); - arrayIndex++; - } - } - - #endregion - - #region IEnumerable Members - - public IEnumerator GetEnumerator() - { - return ( from item in m_storage - select item.CellRange ).GetEnumerator(); - } - - #endregion - - #region IEnumerable Members - - IEnumerator IEnumerable.GetEnumerator() - { - return this.GetEnumerator(); - } - - #endregion - - private readonly SelectedCellsStorage m_storage; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionCellRangeWithItems.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionCellRangeWithItems.cs deleted file mode 100644 index 3a62357a..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionCellRangeWithItems.cs +++ /dev/null @@ -1,128 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid -{ - internal struct SelectionCellRangeWithItems - { - public static readonly SelectionCellRangeWithItems Empty = new SelectionCellRangeWithItems( SelectionRange.Empty, null, SelectionRange.Empty ); - - public SelectionCellRangeWithItems( int itemIndex, object item, int columnIndex ) - : this( new SelectionRange( itemIndex ), new object[] { item }, new SelectionRange( columnIndex ) ) - { - } - - public SelectionCellRangeWithItems( SelectionRange itemRange, object[] items, SelectionRange columnRange ) - { - if( ( items != null ) && ( items.Length != itemRange.Length ) ) - throw new ArgumentException( "itemRange and items must have the same length." ); - - m_itemRangeWithItems = new SelectionRangeWithItems( itemRange, items ); - m_columnRange = columnRange; - } - - #region ItemRangeWithItems Property - - public SelectionRangeWithItems ItemRangeWithItems - { - get - { - return m_itemRangeWithItems; - } - } - - SelectionRangeWithItems m_itemRangeWithItems; - - #endregion - - #region ItemRange Property - - public SelectionRange ItemRange - { - get - { - return m_itemRangeWithItems.Range; - } - } - - #endregion - - #region ColumnRange Property - - public SelectionRange ColumnRange - { - get - { - return m_columnRange; - } - } - - SelectionRange m_columnRange; - - #endregion - - #region CellRange Property - - public SelectionCellRange CellRange - { - get - { - return new SelectionCellRange( m_itemRangeWithItems.Range, m_columnRange ); - } - } - - #endregion - - #region Length Property - - public int Length - { - get - { - return m_itemRangeWithItems.Range.Length * m_columnRange.Length; - } - } - - #endregion - - public static bool operator ==( SelectionCellRangeWithItems rangeWithItems1, SelectionCellRangeWithItems rangeWithItems2 ) - { - return ( rangeWithItems1.m_columnRange == rangeWithItems2.m_columnRange ) - && ( rangeWithItems1.m_itemRangeWithItems == rangeWithItems2.m_itemRangeWithItems ); - } - - public static bool operator !=( SelectionCellRangeWithItems rangeWithItems1, SelectionCellRangeWithItems rangeWithItems2 ) - { - return ( rangeWithItems1.m_columnRange != rangeWithItems2.m_columnRange ) - || ( rangeWithItems1.m_itemRangeWithItems != rangeWithItems2.m_itemRangeWithItems ); - } - - public override int GetHashCode() - { - return ( m_itemRangeWithItems.GetHashCode() ^ m_columnRange.GetHashCode() ); - } - - public override bool Equals( object obj ) - { - if( !( obj is SelectionCellRangeWithItems ) ) - return false; - - return ( ( SelectionCellRangeWithItems )obj ) == this; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionChanger.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionChanger.cs deleted file mode 100644 index f2b08270..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionChanger.cs +++ /dev/null @@ -1,1255 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Diagnostics; -using System.Linq; -using System.Windows.Data; - -namespace Xceed.Wpf.DataGrid -{ - internal class SelectionChanger - { - #region Static Fields - - private static readonly SelectedItemsStorage EmptyItemsStore = new SelectedItemsStorage( null ); - private static readonly SelectedCellsStorage EmptyCellsStore = new SelectedCellsStorage( null ); - - #endregion - - internal SelectionChanger( DataGridContext owner ) - { - m_owner = owner; - m_itemsToSelect = new SelectedItemsStorage( owner ); - m_itemsToUnselect = new SelectedItemsStorage( owner ); - m_cellsToSelect = new SelectedCellsStorage( owner ); - m_cellsToUnselect = new SelectedCellsStorage( owner ); - m_toDeferSelect = new List( 1 ); - m_sourceChanges = new List( 2 ); - } - - #region Owner Property - - internal DataGridContext Owner - { - get - { - return m_owner; - } - } - - private readonly DataGridContext m_owner; - - #endregion - - public bool SelectItems( SelectionRangeWithItems rangeWithItems ) - { - SelectionRange range = rangeWithItems.Range; - - if( !( m_owner.ItemsSourceCollection is DataGridVirtualizingCollectionViewBase ) ) - { - if( range.IsEmpty ) - { - foreach( object item in rangeWithItems.Items ) - { - if( !m_toDeferSelect.Contains( item ) ) - m_toDeferSelect.Add( item ); - } - - return false; - } - } - else - { - if( range.IsEmpty ) - throw new ArgumentException( "rangeWithItems.Range can't be empty when we are using a DataGridVirtualizingCollectionView", "rangeWithItems" ); - } - - if( rangeWithItems.Length == 1 ) - { - if( !m_itemsToUnselect.Remove( rangeWithItems ) ) - { - if( m_owner.SelectedItemsStore.Contains( rangeWithItems ) ) - return false; - - if( m_itemsToSelect.Contains( range ) ) - return false; - - this.m_itemsToSelect.Add( rangeWithItems ); - } - - return true; - } - else - { - bool selectionChanged = m_itemsToUnselect.Remove( rangeWithItems ); - - SelectedItemsStorage tempStorage = new SelectedItemsStorage( m_owner ); - tempStorage.Add( rangeWithItems ); - - // Remove the currently selected item from the new range to select - foreach( SelectionRangeWithItems existingSelectionRangeWithItems in m_owner.SelectedItemsStore ) - { - tempStorage.Remove( existingSelectionRangeWithItems ); - } - - // Remove the pending item to be selected from the new range to select - foreach( SelectionRangeWithItems existingSelectionRangeWithItems in m_itemsToSelect ) - { - tempStorage.Remove( existingSelectionRangeWithItems ); - } - - if( tempStorage.Count > 0 ) - { - selectionChanged = true; - - foreach( SelectionRangeWithItems rangeWithItemsToAdd in tempStorage ) - { - m_itemsToSelect.Add( rangeWithItemsToAdd ); - } - } - - return selectionChanged; - } - } - - public bool SelectCells( SelectionCellRangeWithItems cellRangeWithItems ) - { - SelectionRange itemRange = cellRangeWithItems.ItemRange; - - if( itemRange.IsEmpty ) - throw new ArgumentException( "cellRangeWithItems.ItemRange can't be empty", "cellRangeWithItems" ); - - if( cellRangeWithItems.Length == 1 ) - { - if( !m_cellsToUnselect.Remove( cellRangeWithItems ) ) - { - if( m_owner.SelectedCellsStore.Contains( cellRangeWithItems ) ) - return false; - - if( m_cellsToSelect.Contains( cellRangeWithItems.CellRange ) ) - return false; - - this.m_cellsToSelect.Add( cellRangeWithItems ); - } - - return true; - } - else - { - bool selectionChanged = m_cellsToUnselect.Remove( cellRangeWithItems ); - - SelectedCellsStorage tempStorage = new SelectedCellsStorage( m_owner ); - tempStorage.Add( cellRangeWithItems ); - - // Remove the currently selected item from the new range to select - foreach( SelectionCellRangeWithItems existingSelectionCellRangeWithItems in m_owner.SelectedCellsStore ) - { - tempStorage.Remove( existingSelectionCellRangeWithItems ); - } - - // Remove the pending item to be selected from the new range to select - foreach( SelectionCellRangeWithItems existingSelectionCellRangeWithItems in m_cellsToSelect ) - { - tempStorage.Remove( existingSelectionCellRangeWithItems ); - } - - if( tempStorage.Count > 0 ) - { - selectionChanged = true; - - foreach( SelectionCellRangeWithItems cellRangeWithItemsToAdd in tempStorage ) - { - m_cellsToSelect.Add( cellRangeWithItemsToAdd ); - } - } - - return selectionChanged; - } - } - - public bool UnselectItems( SelectionRangeWithItems rangeWithItems ) - { - if( !( m_owner.ItemsSourceCollection is DataGridVirtualizingCollectionViewBase ) ) - { - if( m_toDeferSelect.Count > 0 ) - { - foreach( object item in rangeWithItems.Items ) - { - m_toDeferSelect.Remove( item ); - } - } - } - - SelectionRange range = rangeWithItems.Range; - - if( range.IsEmpty ) - { - // We have no index we have to remove based on item - bool selectionChanged = false; - - List itemsRangeToRemove = new List(); - List itemsToUnselect = new List( rangeWithItems.Items ); - int count = itemsToUnselect.Count; - - for( int i = count - 1; i >= 0; i-- ) - { - object itemToUnselect = itemsToUnselect[ i ]; - bool selectionAdded = false; - - foreach( SelectionRangeWithItems existingSelectionRangeWithItems in m_itemsToSelect ) - { - int index = Array.IndexOf( existingSelectionRangeWithItems.Items, itemToUnselect ); - - if( index > -1 ) - { - selectionAdded = true; - - itemsRangeToRemove.Add( - new SelectionRangeWithItems( - existingSelectionRangeWithItems.Range.GetIndexFromItemOffset( index ), - itemToUnselect ) ); - } - } - - if( selectionAdded ) - { - itemsToUnselect.RemoveAt( i ); - } - } - - // Remove the currently unselected item from the new range to select - foreach( SelectionRangeWithItems itemRangeToRemove in itemsRangeToRemove ) - { - selectionChanged |= m_itemsToSelect.Remove( itemRangeToRemove ); - } - - count = itemsToUnselect.Count; - - for( int i = 0; i < count; i++ ) - { - object itemToUnselect = itemsToUnselect[ i ]; - - foreach( SelectionRangeWithItems existingSelectionRangeWithItems in m_owner.SelectedItemsStore ) - { - int index = Array.IndexOf( existingSelectionRangeWithItems.Items, itemToUnselect ); - - if( index >= 0 ) - { - index = existingSelectionRangeWithItems.Range.GetIndexFromItemOffset( index ); - - if( !m_itemsToUnselect.Contains( index ) ) - { - selectionChanged = true; - m_itemsToUnselect.Add( new SelectionRangeWithItems( index, itemToUnselect ) ); - } - } - } - } - - return selectionChanged; - } - - if( range.Length == 1 ) - { - if( !m_itemsToSelect.Remove( rangeWithItems ) ) - { - if( !m_owner.SelectedItemsStore.Contains( range ) ) - return false; - - if( m_itemsToUnselect.Contains( range ) ) - return false; - - m_itemsToUnselect.Add( rangeWithItems ); - } - - return true; - } - else - { - SelectedItemsStorage tempStorage = new SelectedItemsStorage( m_owner ); - tempStorage.Add( rangeWithItems ); - - // Remove the currently selected item from the new range to select - foreach( SelectionRangeWithItems existingSelectionRangeWithItems in m_itemsToSelect ) - { - if( !range.Intersect( existingSelectionRangeWithItems.Range ).IsEmpty ) - { - tempStorage.Remove( existingSelectionRangeWithItems ); - } - } - - bool selectionChanged = m_itemsToSelect.Remove( rangeWithItems ); - - if( tempStorage.Count > 0 ) - { - selectionChanged = true; - - foreach( SelectionRangeWithItems rangeWithItemsToAdd in tempStorage ) - { - Debug.Assert( !m_itemsToUnselect.Contains( rangeWithItemsToAdd.Range ) ); - m_itemsToUnselect.Add( rangeWithItemsToAdd ); - } - } - - return selectionChanged; - } - } - - public bool UnselectCells( SelectionCellRangeWithItems cellRangeWithItems ) - { - SelectionRange itemRange = cellRangeWithItems.ItemRange; - SelectionRange columnRange = cellRangeWithItems.ColumnRange; - SelectionCellRange cellRange = cellRangeWithItems.CellRange; - - if( itemRange.IsEmpty ) - { - // We have no index we have to remove based on item - bool selectionChanged = false; - - List cellsRangeToRemove = new List(); - List itemsToUnselect = new List( cellRangeWithItems.ItemRangeWithItems.Items ); - int count = itemsToUnselect.Count; - - for( int i = count - 1; i >= 0; i-- ) - { - object itemToUnselect = itemsToUnselect[ i ]; - - foreach( SelectionCellRangeWithItems existingSelectionCellRangeWithItems in m_cellsToSelect ) - { - SelectionRange columnIntersection = columnRange.Intersect( existingSelectionCellRangeWithItems.ColumnRange ); - - if( columnIntersection.IsEmpty ) - continue; - - int index = Array.IndexOf( existingSelectionCellRangeWithItems.ItemRangeWithItems.Items, itemToUnselect ); - - if( index > -1 ) - { - cellsRangeToRemove.Add( - new SelectionCellRangeWithItems( - new SelectionRange( existingSelectionCellRangeWithItems.ItemRange.GetIndexFromItemOffset( index ) ), - new object[] { itemToUnselect }, - columnIntersection ) ); - } - } - } - - // Remove the currently unselected item from the new range to select - foreach( SelectionCellRangeWithItems cellRangeToRemove in cellsRangeToRemove ) - { - selectionChanged |= m_cellsToSelect.Remove( cellRangeToRemove ); - } - - count = itemsToUnselect.Count; - - for( int i = 0; i < count; i++ ) - { - object itemToUnselect = itemsToUnselect[ i ]; - - foreach( SelectionCellRangeWithItems existingSelectionCellRangeWithItems in m_owner.SelectedCellsStore ) - { - SelectionRange columnIntersection = columnRange.Intersect( existingSelectionCellRangeWithItems.ColumnRange ); - - if( columnIntersection.IsEmpty ) - continue; - - int index = Array.IndexOf( existingSelectionCellRangeWithItems.ItemRangeWithItems.Items, itemToUnselect ); - - if( index > -1 ) - { - index = existingSelectionCellRangeWithItems.ItemRange.GetIndexFromItemOffset( index ); - - SelectionCellRange cellRangeTemp = new SelectionCellRange( - new SelectionRange( existingSelectionCellRangeWithItems.ItemRange.GetIndexFromItemOffset( index ) ), - columnIntersection ); - - if( !m_cellsToUnselect.Contains( cellRangeTemp ) ) - { - selectionChanged = true; - - m_cellsToUnselect.Add( new SelectionCellRangeWithItems( - cellRangeTemp.ItemRange, new object[] { itemToUnselect }, cellRangeTemp.ColumnRange ) ); - } - } - } - } - - return selectionChanged; - } - - if( cellRangeWithItems.Length == 1 ) - { - if( !m_cellsToSelect.Remove( cellRangeWithItems ) ) - { - if( !m_owner.SelectedCellsStore.Contains( cellRange ) ) - return false; - - if( m_cellsToUnselect.Contains( cellRange ) ) - return false; - - m_cellsToUnselect.Add( cellRangeWithItems ); - } - - return true; - } - else - { - SelectedCellsStorage tempStorage = new SelectedCellsStorage( m_owner ); - tempStorage.Add( cellRangeWithItems ); - - // Remove the currently selected item from the new range to select - foreach( SelectionCellRangeWithItems existingSelectionCellRangeWithItems in m_cellsToSelect ) - { - tempStorage.Remove( existingSelectionCellRangeWithItems ); - } - - bool selectionChanged = m_cellsToSelect.Remove( cellRangeWithItems ); - - if( tempStorage.Count > 0 ) - { - selectionChanged = true; - - foreach( SelectionCellRangeWithItems cellRangeWithItemsToAdd in tempStorage ) - { - Debug.Assert( !m_cellsToUnselect.Contains( cellRangeWithItemsToAdd.CellRange ) ); - m_cellsToUnselect.Add( cellRangeWithItemsToAdd ); - } - } - - return selectionChanged; - } - } - - public bool SelectJustThisItem( int itemIndex, object item ) - { - bool selectionDone = true; - m_toDeferSelect.Clear(); - - SelectionRangeWithItems rangeWithItemsToSelect = new SelectionRangeWithItems( itemIndex, item ); - SelectionRange range = rangeWithItemsToSelect.Range; - - if( m_itemsToSelect.Contains( range ) ) - selectionDone = false; - - m_itemsToSelect.Clear(); - SelectedItemsStorage selectedItemsInChange = m_owner.SelectedItemsStore; - - if( selectedItemsInChange.Contains( range ) ) - { - if( !m_itemsToUnselect.Contains( range ) ) - selectionDone = false; - - m_itemsToUnselect.Clear(); - - foreach( SelectionRangeWithItems selectedRangeWithItems in selectedItemsInChange ) - { - m_itemsToUnselect.Add( selectedRangeWithItems ); - } - - m_itemsToUnselect.Remove( rangeWithItemsToSelect ); - } - else - { - m_itemsToSelect.Add( rangeWithItemsToSelect ); - m_itemsToUnselect.Clear(); - - foreach( SelectionRangeWithItems selectedRangeWithItems in selectedItemsInChange ) - { - m_itemsToUnselect.Add( selectedRangeWithItems ); - } - } - - this.UnselectAllCells(); - return selectionDone; - } - - public bool SelectJustThisCell( int itemIndex, object item, int columnIndex ) - { - bool selectionDone = true; - m_toDeferSelect.Clear(); - - SelectionCellRangeWithItems rangeWithItemsToSelect = - new SelectionCellRangeWithItems( itemIndex, item, columnIndex ); - - SelectionCellRange cellRange = rangeWithItemsToSelect.CellRange; - - if( m_cellsToSelect.Contains( cellRange ) ) - selectionDone = false; - - m_cellsToSelect.Clear(); - SelectedCellsStorage selectedCellsInChange = m_owner.SelectedCellsStore; - - if( selectedCellsInChange.Contains( cellRange ) ) - { - if( !m_cellsToUnselect.Contains( cellRange ) ) - selectionDone = false; - - m_cellsToUnselect.Clear(); - - foreach( SelectionCellRangeWithItems selectedCellRangeWithItems in selectedCellsInChange ) - { - m_cellsToUnselect.Add( selectedCellRangeWithItems ); - } - - m_cellsToUnselect.Remove( rangeWithItemsToSelect ); - } - else - { - m_cellsToSelect.Add( rangeWithItemsToSelect ); - m_cellsToUnselect.Clear(); - - foreach( SelectionCellRangeWithItems selectedCellRangeWithItems in selectedCellsInChange ) - { - m_cellsToUnselect.Add( selectedCellRangeWithItems ); - } - } - - this.UnselectAllItems(); - return selectionDone; - } - - public bool SelectItemCells( - int itemIndex, - object item, - HashedLinkedList columnsByVisiblePosition, - bool preserveSelection ) - { - bool selectionDone = true; - int columnsCount = columnsByVisiblePosition.Count; - m_toDeferSelect.Clear(); - - SelectionCellRangeWithItems rangeWithItemsToSelect = - new SelectionCellRangeWithItems( - new SelectionRange( itemIndex ), - new object[] { item }, - new SelectionRange( 0, columnsCount - 1 ) ); - - SelectionCellRange cellRange = rangeWithItemsToSelect.CellRange; - - m_cellsToSelect.Clear(); - SelectedCellsStorage selectedCellsInChange = m_owner.SelectedCellsStore; - - // Remove all currently selected Cells from the new selectionRange - // to avoid duplicate SelectionCellRange - SelectedCellsStorage tempStorage = new SelectedCellsStorage( null ); - tempStorage.Add( rangeWithItemsToSelect ); - - for( int i = 0; i < selectedCellsInChange.Count; i++ ) - { - tempStorage.Remove( selectedCellsInChange[ i ] ); - } - - foreach( ColumnBase column in columnsByVisiblePosition ) - { - if( !column.Visible ) - tempStorage.Remove( new SelectionCellRangeWithItems( itemIndex, item, column.VisiblePosition ) ); - } - - int tempStorageCount = tempStorage.Count; - - // All Cells are already selected - if( tempStorageCount == 0 ) - { - if( !m_cellsToUnselect.Contains( cellRange ) ) - selectionDone = false; - - m_cellsToUnselect.Clear(); - - if( !preserveSelection ) - { - foreach( SelectionCellRangeWithItems selectedCellRangeWithItems in selectedCellsInChange ) - { - m_cellsToUnselect.Add( selectedCellRangeWithItems ); - } - } - - m_cellsToUnselect.Remove( rangeWithItemsToSelect ); - } - else - { - // Add each range to selection - for( int i = 0; i < tempStorageCount; i++ ) - { - m_cellsToSelect.Add( tempStorage[ i ] ); - } - - m_cellsToUnselect.Clear(); - - if( !preserveSelection ) - { - foreach( SelectionCellRangeWithItems selectedCellRangeWithItems in selectedCellsInChange ) - { - tempStorage = new SelectedCellsStorage( null ); - tempStorage.Add( selectedCellRangeWithItems ); - tempStorage.Remove( rangeWithItemsToSelect ); - tempStorageCount = tempStorage.Count; - - for( int i = 0; i < tempStorageCount; i++ ) - { - m_cellsToUnselect.Add( tempStorage[ i ] ); - } - } - } - } - - if( !preserveSelection ) - this.UnselectAllItems(); - - return selectionDone; - } - - public void UnselectAllItems() - { - m_toDeferSelect.Clear(); - m_itemsToSelect.Clear(); - m_itemsToUnselect.Clear(); - - foreach( SelectionRangeWithItems selectedRangeWithItems in m_owner.SelectedItemsStore ) - { - m_itemsToUnselect.Add( selectedRangeWithItems ); - } - } - - public void UnselectAllCells() - { - m_cellsToSelect.Clear(); - m_cellsToUnselect.Clear(); - - foreach( SelectionCellRangeWithItems selectedCellRangeWithItems in m_owner.SelectedCellsStore ) - { - m_cellsToUnselect.Add( selectedCellRangeWithItems ); - } - } - - public void Cleanup() - { - m_itemsToSelect.Clear(); - m_itemsToUnselect.Clear(); - m_cellsToSelect.Clear(); - m_cellsToUnselect.Clear(); - } - - public void CleanupDeferSelection() - { - m_toDeferSelect.Clear(); - } - - public void UpdateSelectedItemsInChangeOfDataGridContext() - { - var removedRangeWithItems = new List(); - var unselectedItemsFromRemove = this.GetUnselectedItemsFromRemove( removedRangeWithItems ); - var ownerSelectedItems = m_owner.SelectedItemsStore; - - for( int i = 0; i < m_sourceChanges.Count; i++ ) - { - var sourceChangeInfo = m_sourceChanges[ i ]; - - switch( sourceChangeInfo.Action ) - { - case NotifyCollectionChangedAction.Add: - { - if( sourceChangeInfo.StartIndex != -1 ) - { - ownerSelectedItems.OffsetIndex( sourceChangeInfo.StartIndex, sourceChangeInfo.Count ); - } - - break; - } - - case NotifyCollectionChangedAction.Remove: - break; - - default: - throw new NotSupportedException( "Only Add and Remove are supported." ); - } - } - - foreach( SelectionRangeWithItems rangeWithItems in removedRangeWithItems ) - { - ownerSelectedItems.Remove( rangeWithItems ); - ownerSelectedItems.OffsetIndex( rangeWithItems.Range.StartIndex, -rangeWithItems.Length ); - } - - for( int i = m_toDeferSelect.Count - 1; i >= 0; i-- ) - { - object item = m_toDeferSelect[ i ]; - int itemIndex = m_owner.Items.IndexOf( item ); - - if( itemIndex >= 0 ) - { - if( !m_itemsToUnselect.Contains( itemIndex ) ) - { - m_itemsToSelect.Add( new SelectionRangeWithItems( itemIndex, item ) ); - } - - m_toDeferSelect.RemoveAt( i ); - } - } - - if( ( m_itemsToUnselect.Count > 0 ) || ( m_itemsToSelect.Count > 0 ) || ( unselectedItemsFromRemove.Any() ) ) - { - var realizedDataRows = new Dictionary(); - - // Only want to update the realizedDataRows if the selection change is from user interaction and not - // from the source being updated. When the source is updated, the generator will recreate needed container, - // so the old one will have the correct selection state. - foreach( var container in m_owner.CustomItemContainerGenerator.RealizedContainers ) - { - var dataRow = container as DataRow; - - if( ( dataRow != null ) && ( DataGridControl.GetDataGridContext( dataRow ) == m_owner ) ) - { - realizedDataRows[ DataGridVirtualizingPanel.GetItemIndex( dataRow ) ] = dataRow; - } - } - - var sourceItemIsDataRow = false; - - foreach( var rangeWithItems in m_itemsToUnselect ) - { - sourceItemIsDataRow |= this.SetIsSelectedOnDataRow( realizedDataRows, rangeWithItems, false ); - ownerSelectedItems.Remove( rangeWithItems ); - } - - foreach( var rangeWithItems in m_itemsToSelect ) - { - sourceItemIsDataRow |= this.SetIsSelectedOnDataRow( realizedDataRows, rangeWithItems, true ); - ownerSelectedItems.Add( rangeWithItems ); - } - - foreach( var rangeWithItems in unselectedItemsFromRemove ) - { - m_itemsToUnselect.Add( rangeWithItems ); - } - - if( !sourceItemIsDataRow ) - { - foreach( var realizedItemPair in realizedDataRows ) - { - if( ownerSelectedItems.Contains( new SelectionRange( realizedItemPair.Key ) ) ) - { - realizedItemPair.Value.SetIsSelected( true ); - } - else - { - realizedItemPair.Value.SetIsSelected( false ); - } - } - } - } - } - - public void UpdateSelectedCellsInChangeOfDataGridContext() - { - var removedCellsRangeWithItems = new List(); - var unselectedCellsFromRemove = this.GetUnselectedCellsFromRemove( removedCellsRangeWithItems ); - var ownerSelectedCells = m_owner.SelectedCellsStore; - - for( int i = 0; i < m_sourceChanges.Count; i++ ) - { - var sourceChangeInfo = m_sourceChanges[ i ]; - - switch( sourceChangeInfo.Action ) - { - case NotifyCollectionChangedAction.Add: - { - if( sourceChangeInfo.StartIndex != -1 ) - { - ownerSelectedCells.OffsetIndex( sourceChangeInfo.StartIndex, sourceChangeInfo.Count ); - } - - break; - } - - case NotifyCollectionChangedAction.Remove: - break; - - default: - throw new NotSupportedException( "Only Add and Remove are supported." ); - } - } - - foreach( var cellRangeWithItems in removedCellsRangeWithItems ) - { - ownerSelectedCells.Remove( cellRangeWithItems ); - ownerSelectedCells.OffsetIndex( cellRangeWithItems.ItemRange.StartIndex, -cellRangeWithItems.ItemRange.Length ); - } - - if( ( m_cellsToUnselect.Count > 0 ) || ( m_cellsToSelect.Count > 0 ) || ( unselectedCellsFromRemove.Any() ) ) - { - var realizedDataRows = new Dictionary(); - - // Only want to update the realizedCells if the selection change is from user interaction and not - // from the source being updated. When the source is updated, the generator will recreate needed container, - // so the old one will have the correct selection state. - foreach( var container in m_owner.CustomItemContainerGenerator.RealizedContainers ) - { - var dataRow = container as DataRow; - - if( ( dataRow != null ) && ( DataGridControl.GetDataGridContext( dataRow ) == m_owner ) ) - { - realizedDataRows[ DataGridVirtualizingPanel.GetItemIndex( dataRow ) ] = dataRow; - } - } - - // We use the ColumnsByVisiblePosition for when column are changing position, we want to have the state before the change. - var columnsByVisiblePositionLikedList = m_owner.ColumnsByVisiblePosition; - var columnIndex = 0; - var columnsVisiblePosition = new Dictionary( columnsByVisiblePositionLikedList.Count ); - var columnNode = columnsByVisiblePositionLikedList.First; - - while( columnNode != null ) - { - columnsVisiblePosition.Add( columnNode.Value, columnIndex ); - columnIndex++; - columnNode = columnNode.Next; - } - - foreach( var cellRangeWithItems in m_cellsToUnselect ) - { - this.SetIsSelectedOnDataCell( columnsVisiblePosition, realizedDataRows, cellRangeWithItems, false ); - ownerSelectedCells.Remove( cellRangeWithItems ); - } - - foreach( var cellRangeWithItems in m_cellsToSelect ) - { - this.SetIsSelectedOnDataCell( columnsVisiblePosition, realizedDataRows, cellRangeWithItems, true ); - ownerSelectedCells.Add( cellRangeWithItems ); - } - - foreach( var cellRangeWithItems in unselectedCellsFromRemove ) - { - m_cellsToUnselect.Add( cellRangeWithItems ); - } - } - } - - public void UpdateSelectionAfterSourceDataItemAdded( NotifyCollectionChangedEventArgs e ) - { - int newStartingIndex = e.NewStartingIndex; - - // if newStartingIndex == -1, we take for granted that the newly added items are at the end of the list. - // In that case, we have nothing to do. - if( newStartingIndex == -1 ) - return; - - IList addedItemsList = e.NewItems; - int addedItemsCount = addedItemsList.Count; - - m_sourceChanges.Add( new SourceChangeInfo( e.Action, newStartingIndex, addedItemsCount, addedItemsList ) ); - - m_itemsToSelect.OffsetIndex( newStartingIndex, addedItemsCount ); - m_itemsToUnselect.OffsetIndex( newStartingIndex, addedItemsCount ); - m_cellsToSelect.OffsetIndex( newStartingIndex, addedItemsCount ); - m_cellsToUnselect.OffsetIndex( newStartingIndex, addedItemsCount ); - } - - public void UpdateSelectionAfterSourceDataItemRemoved( NotifyCollectionChangedEventArgs e ) - { - int oldStartingIndex = e.OldStartingIndex; - IList removedItemsList = e.OldItems; - int removedItemsCount = removedItemsList.Count; - - m_sourceChanges.Add( new SourceChangeInfo( e.Action, oldStartingIndex, removedItemsCount, removedItemsList ) ); - - if( oldStartingIndex == -1 ) - { - foreach( object item in removedItemsList ) - { - SelectionRangeWithItems rangeWithItemsToRemove = new SelectionRangeWithItems( SelectionRange.Empty, new object[] { item } ); - - m_itemsToSelect.Remove( rangeWithItemsToRemove ); - m_itemsToUnselect.Remove( rangeWithItemsToRemove ); - - SelectionCellRangeWithItems cellRangeWithItemsToRemove = new SelectionCellRangeWithItems( - SelectionRange.Empty, new object[] { item }, new SelectionRange( 0, int.MaxValue - 1 ) ); - - m_cellsToSelect.Remove( cellRangeWithItemsToRemove ); - m_cellsToUnselect.Remove( cellRangeWithItemsToRemove ); - } - - // Seek out in a max range of removedItemsCount the new position for actually selected item. - m_itemsToSelect.OffsetIndexBasedOnSourceNewIndex( -removedItemsCount ); - m_itemsToUnselect.OffsetIndexBasedOnSourceNewIndex( -removedItemsCount ); - m_cellsToSelect.OffsetIndexBasedOnSourceNewIndex( -removedItemsCount ); - m_cellsToUnselect.OffsetIndexBasedOnSourceNewIndex( -removedItemsCount ); - } - else - { - SelectionRange itemRange = new SelectionRange( oldStartingIndex, oldStartingIndex + removedItemsCount - 1 ); - SelectionRangeWithItems rangeWithItemsToRemove = new SelectionRangeWithItems( itemRange, null ); - m_itemsToSelect.Remove( rangeWithItemsToRemove ); - m_itemsToUnselect.Remove( rangeWithItemsToRemove ); - m_itemsToSelect.OffsetIndex( oldStartingIndex, -removedItemsCount ); - m_itemsToUnselect.OffsetIndex( oldStartingIndex, -removedItemsCount ); - - SelectionCellRangeWithItems cellRangeWithItemsToRemove = new SelectionCellRangeWithItems( - itemRange, null, new SelectionRange( 0, int.MaxValue - 1 ) ); - - m_cellsToSelect.Remove( cellRangeWithItemsToRemove ); - m_cellsToUnselect.Remove( cellRangeWithItemsToRemove ); - m_cellsToSelect.OffsetIndex( oldStartingIndex, -removedItemsCount ); - m_cellsToUnselect.OffsetIndex( oldStartingIndex, -removedItemsCount ); - } - } - - public void UpdateSelectionAfterSourceDataItemReplaced( NotifyCollectionChangedEventArgs e ) - { - Debug.Assert( e.OldItems.Count == e.NewItems.Count ); - Debug.Assert( e.OldStartingIndex == e.NewStartingIndex ); - - SelectedItemsStorage selectedItemsStorage = m_owner.SelectedItemsStore; - SelectedCellsStorage selectedCellsStorage = m_owner.SelectedCellsStore; - int oldItemIndex = e.OldStartingIndex; - IList oldItems = e.OldItems; - IList newItems = e.NewItems; - int replacedItemCount = oldItems.Count; - int cellRangeCount = selectedCellsStorage.Count; - - if( oldItemIndex >= 0 ) - { - int itemIndex = oldItemIndex; - - for( int i = 0; i < replacedItemCount; i++ ) - { - object newItem = newItems[ i ]; - - if( selectedItemsStorage.Contains( itemIndex ) ) - { - this.UnselectItems( new SelectionRangeWithItems( itemIndex, oldItems[ i ] ) ); - this.SelectItems( new SelectionRangeWithItems( itemIndex, newItem ) ); - } - - SelectionCellRange replacedCellRange = new SelectionCellRange( - new SelectionRange( itemIndex ), new SelectionRange( 0, int.MaxValue - 1 ) ); - - for( int j = 0; j < cellRangeCount; j++ ) - { - SelectionCellRangeWithItems cellRangeWithItems = selectedCellsStorage[ j ]; - SelectionCellRange cellRange = cellRangeWithItems.CellRange; - - if( !cellRange.Intersect( replacedCellRange ).IsEmpty ) - { - object[] items = cellRangeWithItems.ItemRangeWithItems.Items; - - if( items != null ) - { - items[ cellRange.ItemRange.GetOffsetFromItemIndex( itemIndex ) ] = newItem; - } - } - } - - itemIndex++; - } - } - else - { - CollectionView sourceItems = m_owner.Items; - - for( int i = 0; i < replacedItemCount; i++ ) - { - object newItem = newItems[ i ]; - int itemIndex = sourceItems.IndexOf( newItem ); - - if( itemIndex < 0 ) - continue; - - if( selectedItemsStorage.Contains( itemIndex ) ) - { - this.UnselectItems( new SelectionRangeWithItems( itemIndex, oldItems[ i ] ) ); - this.SelectItems( new SelectionRangeWithItems( itemIndex, newItem ) ); - } - - SelectionCellRange replacedCellRange = new SelectionCellRange( - new SelectionRange( itemIndex ), new SelectionRange( 0, int.MaxValue - 1 ) ); - - for( int j = 0; j < cellRangeCount; j++ ) - { - SelectionCellRangeWithItems cellRangeWithItems = selectedCellsStorage[ j ]; - SelectionCellRange cellRange = cellRangeWithItems.CellRange; - - if( !cellRange.Intersect( replacedCellRange ).IsEmpty ) - { - object[] items = cellRangeWithItems.ItemRangeWithItems.Items; - - if( items != null ) - { - items[ cellRange.ItemRange.GetOffsetFromItemIndex( itemIndex ) ] = newItem; - } - } - } - } - } - } - - public SelectionInfo GetSelectionInfo() - { - var unselectedItemsFromRemove = this.GetUnselectedItemsFromRemove(); - var unselectedCellsFromRemove = this.GetUnselectedCellsFromRemove(); - - var itemsToUnselect = ( ( m_itemsToUnselect.Count > 0 ) || unselectedItemsFromRemove.Any() ) ? ( SelectedItemsStorage )m_itemsToUnselect.Clone() : SelectionChanger.EmptyItemsStore; - var itemsToSelect = ( m_itemsToSelect.Count > 0 ) ? ( SelectedItemsStorage )m_itemsToSelect.Clone() : SelectionChanger.EmptyItemsStore; - var cellsToUnselect = ( ( m_cellsToUnselect.Count > 0 ) || unselectedCellsFromRemove.Any() ) ? ( SelectedCellsStorage )m_cellsToUnselect.Clone() : SelectionChanger.EmptyCellsStore; - var cellsToSelect = ( m_cellsToSelect.Count > 0 ) ? ( SelectedCellsStorage )m_cellsToSelect.Clone() : SelectionChanger.EmptyCellsStore; - - foreach( var rangeWithItems in unselectedItemsFromRemove ) - { - itemsToUnselect.Add( rangeWithItems ); - } - - foreach( var cellRangeWithItems in unselectedCellsFromRemove ) - { - cellsToUnselect.Add( cellRangeWithItems ); - } - - return new SelectionInfo( m_owner, itemsToUnselect, itemsToSelect, cellsToUnselect, cellsToSelect ); - } - - private IEnumerable GetUnselectedItemsFromRemove() - { - return this.GetUnselectedItemsFromRemove( null ); - } - - private IEnumerable GetUnselectedItemsFromRemove( ICollection removedRangeWithItems ) - { - var store = m_owner.SelectedItemsStore; - if( ( store.Count <= 0 ) || ( m_sourceChanges.Count <= 0 ) ) - return Enumerable.Empty(); - - var unselectedItemsFromRemove = new List(); - - for( int i = 0; i < m_sourceChanges.Count; i++ ) - { - var sourceChangeInfo = m_sourceChanges[ i ]; - if( ( sourceChangeInfo.Action != NotifyCollectionChangedAction.Remove ) || ( sourceChangeInfo.StartIndex == -1 ) ) - continue; - - var startIndex = sourceChangeInfo.StartIndex; - var removedItemCount = sourceChangeInfo.Count; - var removedItems = new object[ removedItemCount ]; - - sourceChangeInfo.Items.CopyTo( removedItems, 0 ); - - var range = new SelectionRange( startIndex, startIndex + removedItemCount - 1 ); - var rangeWithItemsToRemove = new SelectionRangeWithItems( range, removedItems ); - - if( removedRangeWithItems != null ) - { - removedRangeWithItems.Add( rangeWithItemsToRemove ); - } - - if( store.Contains( rangeWithItemsToRemove ) ) - { - unselectedItemsFromRemove.Add( rangeWithItemsToRemove ); - } - } - - return unselectedItemsFromRemove; - } - - private IEnumerable GetUnselectedCellsFromRemove() - { - return this.GetUnselectedCellsFromRemove( null ); - } - - private IEnumerable GetUnselectedCellsFromRemove( ICollection removedCellsRangeWithItems ) - { - var store = m_owner.SelectedCellsStore; - if( ( store.Count <= 0 ) || ( m_sourceChanges.Count <= 0 ) ) - return Enumerable.Empty(); - - var unselectedCellsFromRemove = new List(); - - for( int i = 0; i < m_sourceChanges.Count; i++ ) - { - var sourceChangeInfo = m_sourceChanges[ i ]; - if( ( sourceChangeInfo.Action != NotifyCollectionChangedAction.Remove ) || ( sourceChangeInfo.StartIndex == -1 ) ) - continue; - - var startIndex = sourceChangeInfo.StartIndex; - var removedItemCount = sourceChangeInfo.Count; - var range = new SelectionCellRange( new SelectionRange( startIndex, startIndex + removedItemCount - 1 ), new SelectionRange( 0, int.MaxValue - 1 ) ); - - if( removedCellsRangeWithItems != null ) - { - var removedItems = new object[ removedItemCount ]; - sourceChangeInfo.Items.CopyTo( removedItems, 0 ); - - removedCellsRangeWithItems.Add( new SelectionCellRangeWithItems( range.ItemRange, removedItems, range.ColumnRange ) ); - } - - foreach( var cellRangeWithItems in store.GetIntersectedCellRangesWithItems( range ) ) - { - unselectedCellsFromRemove.Add( cellRangeWithItems ); - } - } - - return unselectedCellsFromRemove; - } - - private bool SetIsSelectedOnDataRow( Dictionary realizedDataRows, SelectionRangeWithItems rangeWithItems, bool selected ) - { - int rangeLength = rangeWithItems.Length; - object[] rangeItems = rangeWithItems.Items; - bool selectionChanged = false; - - if( rangeItems != null ) - { - for( int i = 0; i < rangeLength; i++ ) - { - DataRow rangeItemAsDataRow = rangeItems[ i ] as DataRow; - - if( rangeItemAsDataRow != null ) - { - selectionChanged = true; - rangeItemAsDataRow.SetIsSelected( selected ); - } - else - { - // We take for granted that no item will be a DataRow - break; - } - } - } - - return selectionChanged; - } - - private void SetIsSelectedOnDataCell( - Dictionary columnsVisiblePosition, - Dictionary realizedDataRows, - SelectionCellRangeWithItems cellRangeWithItems, - bool selected ) - { - var rangeItems = cellRangeWithItems.ItemRangeWithItems.Items; - var selectionChanged = false; - var columnRange = cellRangeWithItems.ColumnRange; - - if( rangeItems != null ) - { - int itemsCount = rangeItems.Length; - - for( int i = 0; i < itemsCount; i++ ) - { - var rangeItemAsDataRow = rangeItems[ i ] as DataRow; - - if( rangeItemAsDataRow != null ) - { - selectionChanged = true; - - foreach( var dataCell in rangeItemAsDataRow.CreatedCells ) - { - if( dataCell.IsContainerVirtualized ) - continue; - - int columnPosition; - - if( !columnsVisiblePosition.TryGetValue( dataCell.ParentColumn, out columnPosition ) ) - continue; - - if( !columnRange.Intersect( new SelectionRange( columnPosition ) ).IsEmpty ) - { - dataCell.SetIsSelected( selected ); - } - } - } - else - { - // We take for granted that no item will be a DataRow - break; - } - } - } - - if( !selectionChanged ) - { - var itemRange = cellRangeWithItems.ItemRange; - - foreach( var realizedItemPair in realizedDataRows ) - { - if( !itemRange.Intersect( new SelectionRange( realizedItemPair.Key ) ).IsEmpty ) - { - foreach( var dataCell in realizedItemPair.Value.CreatedCells ) - { - if( dataCell.IsContainerVirtualized ) - continue; - - int columnPosition; - - if( !columnsVisiblePosition.TryGetValue( dataCell.ParentColumn, out columnPosition ) ) - continue; - - if( !columnRange.Intersect( new SelectionRange( columnPosition ) ).IsEmpty ) - { - dataCell.SetIsSelected( selected ); - } - } - } - } - } - } - - private readonly List m_toDeferSelect; - private readonly SelectedItemsStorage m_itemsToSelect; - private readonly SelectedItemsStorage m_itemsToUnselect; - private readonly SelectedCellsStorage m_cellsToSelect; - private readonly SelectedCellsStorage m_cellsToUnselect; - private readonly List m_sourceChanges; - - #region SourceChangeInfo Private Class - - private sealed class SourceChangeInfo - { - internal SourceChangeInfo( NotifyCollectionChangedAction action, int startIndex, int count, IList items ) - { - this.Action = action; - this.StartIndex = startIndex; - this.Count = count; - this.Items = items; - } - - internal NotifyCollectionChangedAction Action - { - get; - private set; - } - - internal int StartIndex - { - get; - private set; - } - - internal int Count - { - get; - private set; - } - - internal IList Items - { - get; - private set; - } - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionInfo.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionInfo.cs deleted file mode 100644 index dedbbb94..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionInfo.cs +++ /dev/null @@ -1,95 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.ObjectModel; - -namespace Xceed.Wpf.DataGrid -{ - public class SelectionInfo - { - internal SelectionInfo( - DataGridContext dataGridContext, - SelectedItemsStorage removedItems, - SelectedItemsStorage addedItems, - SelectedCellsStorage removedCells, - SelectedCellsStorage addedCells ) - { - this.DataGridContext = dataGridContext; - this.AddedItems = new ReadOnlyCollection( new SelectionItemCollection( addedItems ) ); - this.RemovedItems = new ReadOnlyCollection( new SelectionItemCollection( removedItems ) ); - this.AddedItemRanges = new ReadOnlyCollection( new SelectionItemRangeCollection( addedItems ) ); - this.RemovedItemRanges = new ReadOnlyCollection( new SelectionItemRangeCollection( removedItems ) ); - this.AddedCellRanges = new ReadOnlyCollection( new SelectionCellRangeCollection( addedCells ) ); - this.RemovedCellRanges = new ReadOnlyCollection( new SelectionCellRangeCollection( removedCells ) ); - } - - public DataGridContext DataGridContext - { - get; - private set; - } - - public ReadOnlyCollection AddedItems - { - get; - private set; - } - - public ReadOnlyCollection RemovedItems - { - get; - private set; - } - - public ReadOnlyCollection AddedItemRanges - { - get; - private set; - } - - public ReadOnlyCollection RemovedItemRanges - { - get; - private set; - } - - public ReadOnlyCollection AddedCellRanges - { - get; - private set; - } - - public ReadOnlyCollection RemovedCellRanges - { - get; - private set; - } - - internal bool IsEmpty - { - get - { - return - this.RemovedCellRanges.Count == 0 - && this.AddedCellRanges.Count == 0 - && this.RemovedItemRanges.Count == 0 - && this.AddedItemRanges.Count == 0; - } - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionItemCollection.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionItemCollection.cs deleted file mode 100644 index 69586ef5..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionItemCollection.cs +++ /dev/null @@ -1,473 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class SelectionItemCollection : IList, IList - { - internal SelectionItemCollection( SelectedItemsStorage collection ) - { - m_storage = collection; - } - - private bool FindItem( int index, DataGridContext dataGridContext, int itemsCount, out SelectionRangeWithItems range, out int offset ) - { - var rangesCount = m_storage.Count; - - range = SelectionRangeWithItems.Empty; - offset = index; - - for( int i = 0; i < rangesCount; i++ ) - { - if( offset < 0 ) - break; - - range = m_storage[ i ]; - var length = range.Length; - - if( offset < length ) - { - var startAt = range.Range.StartIndex; - var endAt = range.Range.EndIndex; - - if( startAt > endAt ) - { - if( startAt - offset >= itemsCount ) - break; - } - else - { - if( startAt + offset >= itemsCount ) - break; - } - - Debug.Assert( ( offset >= 0 ) && ( offset < length ) ); - - return true; - } - else - { - offset -= length; - } - } - - return false; - } - - private IEnumerable EnumerateItems( SelectionRangeWithItems range, DataGridContext dataGridContext, int itemsCount ) - { - var startAt = range.Range.StartIndex; - var endAt = range.Range.EndIndex; - var min = Math.Min( startAt, endAt ); - var max = Math.Max( startAt, endAt ); - - if( startAt > endAt ) - { - var upperLimit = Math.Min( startAt, itemsCount - 1 ); - - for( int i = upperLimit; i >= endAt; i-- ) - { - object item; - - try - { - item = range.GetItem( dataGridContext, startAt - i ); - } - catch( ArgumentOutOfRangeException ) - { - continue; - } - - yield return item; - } - } - else - { - var upperLimit = Math.Min( endAt, itemsCount - 1 ); - - for( int i = startAt; i <= upperLimit; i++ ) - { - object item; - - try - { - item = range.GetItem( dataGridContext, i - startAt ); - } - catch( ArgumentOutOfRangeException ) - { - break; - } - - yield return item; - } - } - } - - #region IList<> Members - - public object this[ int index ] - { - get - { - if( ( index < 0 ) || ( index >= m_storage.ItemsCount ) ) - throw new ArgumentOutOfRangeException( "index", "The index must be equal or greater than zero and less than Count." ); - - var dataGridContext = m_storage.DataGridContext; - var itemsCount = dataGridContext.Items.Count; - var range = SelectionRangeWithItems.Empty; - var offset = default( int ); - - if( this.FindItem( index, dataGridContext, itemsCount, out range, out offset ) ) - { - try - { - return range.GetItem( dataGridContext, offset ); - } - catch( ArgumentOutOfRangeException ) - { - // return null - } - } - - return null; - } - set - { - throw new NotSupportedException(); - } - } - - public int IndexOf( object item ) - { - var rangesCount = m_storage.Count; - if( rangesCount <= 0 ) - return -1; - - var dataGridContext = m_storage.DataGridContext; - var itemsCount = default( int? ); - var offset = 0; - - for( int i = 0; i < rangesCount; i++ ) - { - var range = m_storage[ i ]; - if( range.Items != null ) - { - var index = 0; - - if( !itemsCount.HasValue ) - { - itemsCount = dataGridContext.Items.Count; - } - - foreach( var target in this.EnumerateItems( range, dataGridContext, itemsCount.Value ) ) - { - if( object.Equals( target, item ) ) - return offset + index; - - index++; - } - } - - offset += range.Length; - } - - return -1; - } - - public void Insert( int index, object item ) - { - if( ( index < 0 ) || ( index > m_storage.ItemsCount ) ) - throw new ArgumentOutOfRangeException( "index", index, "index must be greater than or equal to zero and less than or equal to Count." ); - - var dataGridContext = m_storage.DataGridContext; - var dataGridControl = dataGridContext.DataGridControl; - - if( dataGridControl.SelectionUnit == SelectionUnit.Cell ) - throw new InvalidOperationException( "Can't add item when SelectionUnit is Cell." ); - - var selectionManager = dataGridControl.SelectionChangerManager; - selectionManager.Begin(); - - try - { - selectionManager.SelectItems( dataGridContext, new SelectionRangeWithItems( dataGridContext.Items.IndexOf( item ), item ) ); - } - finally - { - selectionManager.End( true, true ); - } - } - - public void RemoveAt( int index ) - { - if( ( index < 0 ) || ( index >= m_storage.ItemsCount ) ) - throw new ArgumentOutOfRangeException( "index", index, "index must be greater than or equal to zero and less than Count." ); - - var dataGridContext = m_storage.DataGridContext; - var itemsCount = dataGridContext.Items.Count; - var range = SelectionRangeWithItems.Empty; - var offset = default( int ); - - if( !this.FindItem( index, dataGridContext, itemsCount, out range, out offset ) ) - return; - - object item; - int itemIndex; - - try - { - item = range.GetItem( dataGridContext, offset ); - itemIndex = range.Range.GetIndexFromItemOffset( offset ); - } - catch( ArgumentOutOfRangeException ) - { - return; - } - - var selectionManager = dataGridContext.DataGridControl.SelectionChangerManager; - selectionManager.Begin(); - - try - { - selectionManager.UnselectItems( dataGridContext, new SelectionRangeWithItems( itemIndex, item ) ); - } - finally - { - selectionManager.End( true, true ); - } - } - - #endregion - - #region IList Members - - object IList.this[ int index ] - { - get - { - return this[ index ]; - } - set - { - this[ index ] = value; - } - } - - bool IList.IsReadOnly - { - get - { - return ( ( ICollection )this ).IsReadOnly; - } - } - - bool IList.IsFixedSize - { - get - { - return false; - } - } - - int IList.Add( object item ) - { - this.Add( item ); - return this.Count - 1; - } - - void IList.Clear() - { - this.Clear(); - } - - void IList.Insert( int index, object item ) - { - this.Insert( index, item ); - } - - void IList.Remove( object item ) - { - this.Remove( item ); - } - - void IList.RemoveAt( int index ) - { - this.RemoveAt( index ); - } - - bool IList.Contains( object item ) - { - return this.Contains( item ); - } - - int IList.IndexOf( object item ) - { - return this.IndexOf( item ); - } - - #endregion - - #region ICollection<> Members - - public int Count - { - get - { - return m_storage.ItemsCount; - } - } - - bool ICollection.IsReadOnly - { - get - { - return false; - } - } - - public void Add( object item ) - { - this.Insert( m_storage.ItemsCount, item ); - } - - public void Clear() - { - var dataGridContext = m_storage.DataGridContext; - var selectionManager = dataGridContext.DataGridControl.SelectionChangerManager; - selectionManager.Begin(); - - try - { - selectionManager.UnselectAllItems( dataGridContext ); - } - finally - { - selectionManager.End( true, true ); - } - } - - public bool Contains( object item ) - { - return ( this.IndexOf( item ) >= 0 ); - } - - public bool Remove( object item ) - { - var dataGridContext = m_storage.DataGridContext; - var dataGridControl = dataGridContext.DataGridControl; - - if( dataGridControl.SelectionUnit == SelectionUnit.Cell ) - throw new InvalidOperationException( "Can't remove item when SelectionUnit is Cell." ); - - var selectionManager = dataGridControl.SelectionChangerManager; - selectionManager.Begin(); - - try - { - return selectionManager.UnselectItems( dataGridContext, new SelectionRangeWithItems( SelectionRange.Empty, new object[] { item } ) ); - } - finally - { - selectionManager.End( true, true ); - } - } - - public void CopyTo( object[] array, int arrayIndex ) - { - ( ( ICollection )this ).CopyTo( array, arrayIndex ); - } - - #endregion - - #region ICollection Members - - int ICollection.Count - { - get - { - return this.Count; - } - } - - object ICollection.SyncRoot - { - get - { - return m_storage; - } - } - - bool ICollection.IsSynchronized - { - get - { - return false; - } - } - - void ICollection.CopyTo( Array array, int arrayIndex ) - { - using( var enumerator = this.GetEnumerator() ) - { - while( enumerator.MoveNext() ) - { - array.SetValue( enumerator.Current, arrayIndex ); - arrayIndex++; - } - } - } - - #endregion - - #region IEnumerable<> Members - - public IEnumerator GetEnumerator() - { - if( m_storage.Count <= 0 ) - yield break; - - var dataGridContext = m_storage.DataGridContext; - var itemsCount = dataGridContext.Items.Count; - - // We use a foreach to get the exception when the collection is changed. - foreach( var range in m_storage ) - { - foreach( var item in this.EnumerateItems( range, dataGridContext, itemsCount ) ) - { - yield return item; - } - } - } - - #endregion - - #region IEnumerable Members - - IEnumerator IEnumerable.GetEnumerator() - { - return this.GetEnumerator(); - } - - #endregion - - private readonly SelectedItemsStorage m_storage; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionItemRangeCollection.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionItemRangeCollection.cs deleted file mode 100644 index aa118aee..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionItemRangeCollection.cs +++ /dev/null @@ -1,329 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class SelectionItemRangeCollection : IList, IList - { - internal SelectionItemRangeCollection( SelectedItemsStorage collection ) - { - Debug.Assert( collection != null ); - - m_storage = collection; - } - - #region IList<> Members - - public SelectionRange this[ int index ] - { - get - { - return m_storage[ index ].Range; - } - set - { - throw new NotSupportedException(); - } - } - - public int IndexOf( SelectionRange item ) - { - var count = m_storage.Count; - - for( int i = 0; i < count; i++ ) - { - if( m_storage[ i ].Range == item ) - return i; - } - - return -1; - } - - public void Insert( int index, SelectionRange item ) - { - if( ( index < 0 ) || ( index > m_storage.Count ) ) - throw new ArgumentOutOfRangeException( "index", index, "index must be greater than or equal to zero and less than or equal to Count." ); - - var dataGridContext = m_storage.DataGridContext; - var dataGridControl = dataGridContext.DataGridControl; - - if( dataGridControl.SelectionUnit == SelectionUnit.Cell ) - throw new InvalidOperationException( "Can't add item when SelectionUnit is Cell." ); - - if( !( dataGridContext.ItemsSourceCollection is DataGridVirtualizingCollectionViewBase ) ) - { - var minIndex = Math.Min( item.StartIndex, item.EndIndex ); - var maxIndex = Math.Max( item.StartIndex, item.EndIndex ); - - if( ( minIndex < 0 ) || ( maxIndex >= dataGridContext.Items.Count ) ) - throw new ArgumentException( "The selection range targets items outside of the data source.", "item" ); - } - - var selectionManager = dataGridControl.SelectionChangerManager; - selectionManager.Begin(); - - try - { - selectionManager.SelectItems( dataGridContext, new SelectionRangeWithItems( item, null ) ); - } - finally - { - selectionManager.End( true, true ); - } - } - - public void RemoveAt( int index ) - { - if( ( index < 0 ) || ( index >= m_storage.Count ) ) - throw new ArgumentOutOfRangeException( "index", index, "index must be greater than or equal to zero and less than Count." ); - - var dataGridContext = m_storage.DataGridContext; - var selectionManager = dataGridContext.DataGridControl.SelectionChangerManager; - selectionManager.Begin(); - - try - { - selectionManager.UnselectItems( dataGridContext, new SelectionRangeWithItems( this[ index ], null ) ); - } - finally - { - selectionManager.End( true, true ); - } - } - - #endregion - - #region IList Members - - object IList.this[ int index ] - { - get - { - return this[ index ]; - } - set - { - this[ index ] = ( SelectionRange )value; - } - } - - bool IList.IsReadOnly - { - get - { - return ( ( ICollection )this ).IsReadOnly; - } - } - - bool IList.IsFixedSize - { - get - { - return false; - } - } - - int IList.Add( object item ) - { - this.Add( ( SelectionRange )item ); - return this.Count - 1; - } - - void IList.Clear() - { - this.Clear(); - } - - void IList.Insert( int index, object item ) - { - this.Insert( index, ( SelectionRange )item ); - } - - void IList.Remove( object item ) - { - this.Remove( ( SelectionRange )item ); - } - - void IList.RemoveAt( int index ) - { - this.RemoveAt( index ); - } - - bool IList.Contains( object item ) - { - return this.Contains( ( SelectionRange )item ); - } - - int IList.IndexOf( object item ) - { - return this.IndexOf( ( SelectionRange )item ); - } - - #endregion - - #region ICollection<> Members - - public int Count - { - get - { - return m_storage.Count; - } - } - - bool ICollection.IsReadOnly - { - get - { - return false; - } - } - - public void Add( SelectionRange item ) - { - this.Insert( m_storage.Count, item ); - } - - public void Clear() - { - var dataGridContext = m_storage.DataGridContext; - var selectionManager = dataGridContext.DataGridControl.SelectionChangerManager; - selectionManager.Begin(); - - try - { - selectionManager.UnselectAllItems( dataGridContext ); - } - finally - { - selectionManager.End( true, true ); - } - } - - public bool Contains( SelectionRange item ) - { - return ( this.IndexOf( item ) >= 0 ); - } - - public bool Remove( SelectionRange item ) - { - var dataGridContext = m_storage.DataGridContext; - var dataGridControl = dataGridContext.DataGridControl; - - if( dataGridControl.SelectionUnit == SelectionUnit.Cell ) - throw new InvalidOperationException( "Can't remove item when SelectionUnit is Cell." ); - - if( !( dataGridContext.ItemsSourceCollection is DataGridVirtualizingCollectionViewBase ) ) - { - var minIndex = Math.Min( item.StartIndex, item.EndIndex ); - var maxIndex = Math.Max( item.StartIndex, item.EndIndex ); - - if( ( minIndex < 0 ) || ( maxIndex >= dataGridContext.Items.Count ) ) - throw new ArgumentException( "The selection range targets items outside of the data source.", "item" ); - } - - var selectionManager = dataGridControl.SelectionChangerManager; - selectionManager.Begin(); - - try - { - return selectionManager.UnselectItems( dataGridContext, new SelectionRangeWithItems( item, null ) ); - } - finally - { - selectionManager.End( true, true ); - } - } - - public void CopyTo( SelectionRange[] array, int arrayIndex ) - { - ( ( ICollection )this ).CopyTo( array, arrayIndex ); - } - - internal bool Contains( int itemIndex ) - { - return m_storage.Contains( itemIndex ); - } - - #endregion - - #region ICollection Members - - int ICollection.Count - { - get - { - return this.Count; - } - } - - object ICollection.SyncRoot - { - get - { - return m_storage; - } - } - - bool ICollection.IsSynchronized - { - get - { - return false; - } - } - - void ICollection.CopyTo( Array array, int arrayIndex ) - { - var count = m_storage.Count; - - for( int i = 0; i < count; i++ ) - { - array.SetValue( m_storage[ i ].Range, arrayIndex ); - arrayIndex++; - } - } - - #endregion - - #region IEnumerable<> Members - - public IEnumerator GetEnumerator() - { - return ( from item in m_storage - select item.Range ).GetEnumerator(); - } - - #endregion - - #region IEnumerable Members - - IEnumerator IEnumerable.GetEnumerator() - { - return this.GetEnumerator(); - } - - #endregion - - private readonly SelectedItemsStorage m_storage; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionManager.cs deleted file mode 100644 index 96c14252..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionManager.cs +++ /dev/null @@ -1,1715 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Collections.Specialized; -using System.Diagnostics; -using System.Linq; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Input; - -namespace Xceed.Wpf.DataGrid -{ - internal class SelectionManager - { - public enum UpdateSelectionSource - { - Navigation = 0, - MouseDown = 1, - MouseUp = 2, - SpaceDown = 3, - RowSelector = 4, - MouseMove = 5, - None = 99 - } - - public SelectionManager( DataGridControl owner ) - { - if( owner == null ) - throw new ArgumentNullException( "owner" ); - - m_owner = owner; - } - - #region IsActive Property - - public bool IsActive - { - get - { - return m_isActive; - } - } - - #endregion - - public IDisposable PushUpdateSelectionSource( UpdateSelectionSource updateSelectionSource ) - { - // We raise the fromRowSelector flag here since it's possible - // that the focus is already on the correct Cell for the container - // mapped to the RowSelector, preventing the SelectionManager to - // do any processing. - if( updateSelectionSource == UpdateSelectionSource.RowSelector ) - m_fromRowSelector = true; - - return new UpdateSelectionSourceHelper( this, updateSelectionSource ); - } - - public void EnsureRootSelectedItemAndSelectedIndex() - { - // This is done to force the DataGridControl's Root DataGridContext to be in the activated selection changer so that even if no changes were made - // the CommitSelectionChanger method will be called and the DataGridControl's SelectedItem/SelectedIndex will be rectified (ie: When sorting or grouping). - this.GetSelectionChanger( m_owner.DataGridContext ); - } - - public void Begin() - { - if( m_isActive ) - throw new InvalidOperationException( "An attempt was made to change the selection while a selection-change process is already in progress." ); - - m_isActive = true; - } - - public void Cancel() - { - Debug.Assert( m_isActive ); - m_isActive = false; - - foreach( SelectionChanger selectionChanger in m_activatedSelectionChanger.Values ) - { - selectionChanger.Cleanup(); - } - } - - public void End( bool allowCancelingOfSelection, bool allowSynchronizeSelectionWithCurrent ) - { - Debug.Assert( m_isActive ); - - var activatedSelectionDeltas = new List(); - var selectionInfo = default( SelectionInfo ); - - try - { - foreach( var selectionChanger in m_activatedSelectionChanger.Values ) - { - selectionInfo = selectionChanger.GetSelectionInfo(); - - if( !selectionInfo.IsEmpty ) - { - activatedSelectionDeltas.Add( selectionInfo ); - } - } - - if( activatedSelectionDeltas.Count > 0 ) - { - var eventArgs = new DataGridSelectionChangingEventArgs( new ReadOnlyCollection( activatedSelectionDeltas ), allowCancelingOfSelection ); - - m_owner.RaiseSelectionChanging( eventArgs ); - - if( allowCancelingOfSelection && eventArgs.Cancel ) - { - this.Cancel(); - return; - } - } - - foreach( var selectionChanger in m_activatedSelectionChanger.Values ) - { - this.CommitSelectionChanger( selectionChanger ); - } - - if( ( allowSynchronizeSelectionWithCurrent ) && ( m_owner.SynchronizeSelectionWithCurrent ) ) - { - this.UpdateCurrentToSelection(); - } - } - finally - { - m_isActive = false; - m_activatedSelectionChanger.Clear(); - } - - // Notify that GlobalSelectedItems has changed if at least one selection has changed. - if( activatedSelectionDeltas.Count > 0 ) - { - for( int i = activatedSelectionDeltas.Count - 1; i >= 0; i-- ) - { - selectionInfo = activatedSelectionDeltas[ i ]; - - // Invoke the selection changed on the DataGridContext. - selectionInfo.DataGridContext.InvokeSelectionChanged( selectionInfo ); - } - - m_owner.RaiseSelectionChanged( new DataGridSelectionChangedEventArgs( new ReadOnlyCollection( activatedSelectionDeltas ) ) ); - m_owner.NotifyGlobalSelectedItemsChanged(); - } - } - - public bool ToggleItemSelection( SelectionRangePoint rangePosition ) - { - var group = rangePosition.Group; - if( group != null ) - { - bool unselect = false; - var range = rangePosition.ToSelectionRangeWithItems(); - - // When [un]selecting a group, select all children, and recursively - // the expanded details nodes. - return this.AffectSelectionRecursivelyOnDetails( - rangePosition.DataGridContext, range.Range.StartIndex, range.Range.EndIndex, - unselect ); - } - else - { - return this.ToggleItemSelection( - rangePosition.DataGridContext, - rangePosition.ItemIndex, rangePosition.Item ); - } - } - - public bool ToggleItemSelection( DataGridContext context, int itemIndex, object item ) - { - if( this.IsItemSelected( context, itemIndex ) ) - { - return this.UnselectItems( context, new SelectionRangeWithItems( itemIndex, item ) ); - } - else - { - return this.SelectItems( context, new SelectionRangeWithItems( itemIndex, item ) ); - } - } - - public bool ToggleCellSelection( DataGridContext context, int itemIndex, object item, int columnIndex ) - { - if( this.IsCellSelected( context, itemIndex, columnIndex ) ) - { - return this.UnselectCells( context, new SelectionCellRangeWithItems( itemIndex, item, columnIndex ) ); - } - else - { - return this.SelectCells( context, new SelectionCellRangeWithItems( itemIndex, item, columnIndex ) ); - } - } - - public bool ToggleItemCellsSelection( DataGridContext dataGridContext, int itemIndex, object item ) - { - SelectedCellsStorage tempStorage = this.GetItemCellStorage( dataGridContext, itemIndex, item ); - - bool selectionDone = true; - - if( this.IsItemCellsSelected( dataGridContext, tempStorage ) ) - { - foreach( SelectionCellRangeWithItems allCellSelection in tempStorage ) - { - selectionDone &= this.UnselectCells( dataGridContext, allCellSelection ); - } - } - else - { - foreach( SelectionCellRangeWithItems allCellSelection in tempStorage ) - { - selectionDone &= this.SelectCells( dataGridContext, allCellSelection ); - } - } - - return selectionDone; - } - - public bool SelectCells( DataGridContext dataGridContext, SelectionCellRangeWithItems cellRangeWithItems ) - { - SelectionChanger selectionChanger = this.GetSelectionChanger( dataGridContext ); - return selectionChanger.SelectCells( cellRangeWithItems ); - } - - public bool SelectItems( SelectionRangePoint position ) - { - if( position.Group != null ) - { - // When [un]selecting a group, select all children, and recursively - // the expanded details nodes. - var range = position.ToSelectionRangeWithItems(); - return this.AffectSelectionRecursivelyOnDetails( - position.DataGridContext, range.Range.StartIndex, range.Range.EndIndex, - false ); - } - else - { - return this.SelectItems( position.DataGridContext, position.ToSelectionRangeWithItems() ); - } - } - - public bool SelectItems( DataGridContext dataGridContext, SelectionRangeWithItems rangeWithItems ) - { - SelectionChanger selectionChanger = this.GetSelectionChanger( dataGridContext ); - return selectionChanger.SelectItems( rangeWithItems ); - } - - public bool SelectJustThisCell( DataGridContext dataGridContext, int itemIndex, object item, int columnIndex ) - { - bool selected = false; - SelectionChanger selectionChanger = this.GetSelectionChanger( dataGridContext ); - - // Add all the selected context to the activatedSelectionChanger since - // we will unselect all the selected item from it. - foreach( DataGridContext selectedDataGridContext in m_owner.SelectedContexts ) - { - this.GetSelectionChanger( selectedDataGridContext ); - } - - // select only the wanted item. - foreach( SelectionChanger activatedSelectionChanger in m_activatedSelectionChanger.Values ) - { - if( activatedSelectionChanger == selectionChanger ) - { - selected = activatedSelectionChanger.SelectJustThisCell( itemIndex, item, columnIndex ); - } - else - { - activatedSelectionChanger.UnselectAllItems(); - activatedSelectionChanger.UnselectAllCells(); - } - } - - return selected; - } - - public bool SelectItemCells( DataGridContext dataGridContext, int itemIndex, object item, bool preserveSelection ) - { - bool selected = false; - SelectionChanger selectionChanger = this.GetSelectionChanger( dataGridContext ); - - // Add all the selected context to the activatedSelectionChanger since - // we will unselect all the selected item from it. - foreach( DataGridContext selectedDataGridContext in m_owner.SelectedContexts ) - { - this.GetSelectionChanger( selectedDataGridContext ); - } - - // select only the wanted item. - foreach( SelectionChanger activatedSelectionChanger in m_activatedSelectionChanger.Values ) - { - if( activatedSelectionChanger == selectionChanger ) - { - selected = activatedSelectionChanger.SelectItemCells( itemIndex, - item, - dataGridContext.ColumnsByVisiblePosition, - preserveSelection ); - } - else - { - if( !preserveSelection ) - { - activatedSelectionChanger.UnselectAllItems(); - activatedSelectionChanger.UnselectAllCells(); - } - } - } - - return selected; - } - - public bool SelectJustThisItem( SelectionRangePoint point ) - { - bool selected = false; - var group = point.Group; - - if( group != null ) - { - this.UnselectAll(); - // This will also recursively select all expanded detail childrens. - selected = this.SelectItems( point ); - } - else - { - var item = point.Item; - var itemIndex = point.ItemIndex; - if( itemIndex != -1 ) - { - selected = this.SelectJustThisItem( point.DataGridContext, itemIndex, item ); - } - } - - return selected; - } - - public bool SelectJustThisItem( DataGridContext dataGridContext, int itemIndex, object item ) - { - bool selected = false; - SelectionChanger selectionChanger = this.GetSelectionChanger( dataGridContext ); - - // Add all the selected context to the activatedSelectionChanger since - // we will unselect all the selected item from it. - foreach( DataGridContext selectedDataGridContext in m_owner.SelectedContexts ) - { - this.GetSelectionChanger( selectedDataGridContext ); - } - - // select only the wanted item. - foreach( SelectionChanger activatedSelectionChanger in m_activatedSelectionChanger.Values ) - { - if( activatedSelectionChanger == selectionChanger ) - { - selected = activatedSelectionChanger.SelectJustThisItem( itemIndex, item ); - } - else - { - activatedSelectionChanger.UnselectAllItems(); - activatedSelectionChanger.UnselectAllCells(); - } - } - - return selected; - } - - public bool UnselectCells( DataGridContext dataGridContext, SelectionCellRangeWithItems cellRangeWithItems ) - { - SelectionChanger selectionChanger = this.GetSelectionChanger( dataGridContext ); - return selectionChanger.UnselectCells( cellRangeWithItems ); - } - - public bool UnselectItems( DataGridContext dataGridContext, SelectionRangeWithItems rangeWithItems ) - { - SelectionChanger selectionChanger = this.GetSelectionChanger( dataGridContext ); - return selectionChanger.UnselectItems( rangeWithItems ); - } - - public void CleanupDeferSelection( DataGridContext dataGridContext ) - { - SelectionChanger selectionChanger = this.GetSelectionChanger( dataGridContext ); - selectionChanger.CleanupDeferSelection(); - } - - public void UpdateSelectionAfterSourceCollectionChanged( DataGridContext dataGridContext, NotifyCollectionChangedEventArgs e ) - { - switch( e.Action ) - { - case NotifyCollectionChangedAction.Replace: - { - // When we get a replace with the same instance, we just have nothing to do. - if( ( e.NewItems.Count == e.OldItems.Count ) && e.NewItems.Cast().SequenceEqual( e.OldItems.Cast() ) ) - break; - - this.Begin(); - - try - { - // This is done to force the SelectionChangerManager to call the DataGridControl's - // DataGridContext UpdatePublicSelectionProperties method wheter or not - // there is any changes to the selection. This is usefull when resetting due to a Sort operation for instance. - this.EnsureRootSelectedItemAndSelectedIndex(); - - SelectionChanger selectionChanger = this.GetSelectionChanger( dataGridContext ); - selectionChanger.UpdateSelectionAfterSourceDataItemReplaced( e ); - } - finally - { - this.End( false, true ); - } - - break; - } - - case NotifyCollectionChangedAction.Add: - { - this.Begin(); - - try - { - // This is done to force the SelectionChangerManager to call the DataGridControl's - // DataGridContext UpdatePublicSelectionProperties method wheter or not - // there is any changes to the selection. This is usefull when resetting due to a Sort operation for instance. - this.EnsureRootSelectedItemAndSelectedIndex(); - - m_selectionRangeStartPoint = null; - SelectionChanger selectionChanger = this.GetSelectionChanger( dataGridContext ); - selectionChanger.UpdateSelectionAfterSourceDataItemAdded( e ); - } - finally - { - this.End( false, true ); - } - - break; - } - - case NotifyCollectionChangedAction.Remove: - { - this.Begin(); - - try - { - // This is done to force the SelectionChangerManager to call the DataGridControl's - // DataGridContext UpdatePublicSelectionProperties method wheter or not - // there is any changes to the selection. This is usefull when resetting due to a Sort operation for instance. - this.EnsureRootSelectedItemAndSelectedIndex(); - - m_selectionRangeStartPoint = null; - SelectionChanger selectionChanger = this.GetSelectionChanger( dataGridContext ); - selectionChanger.UpdateSelectionAfterSourceDataItemRemoved( e ); - } - finally - { - this.End( false, true ); - } - - break; - } - - case NotifyCollectionChangedAction.Move: - case NotifyCollectionChangedAction.Reset: - { - this.Begin(); - - try - { - // This is done to force the SelectionChangerManager to call the DataGridControl's - // DataGridContext UpdatePublicSelectionProperties method wheter or not - // there is any changes to the selection. This is usefull when resetting due to a Sort operation for instance. - this.EnsureRootSelectedItemAndSelectedIndex(); - - m_selectionRangeStartPoint = null; - - SelectedItemsStorage selectedItemsStorage = dataGridContext.SelectedItemsStore; - int selectedItemsCount = selectedItemsStorage.Count; - SelectedCellsStorage selectedCellsStorage = dataGridContext.SelectedCellsStore; - int selectedCellsCount = selectedCellsStorage.Count; - SelectionChanger selectionChanger = this.GetSelectionChanger( dataGridContext ); - - int newItemCount = dataGridContext.Items.Count; - SelectionRange maxItemRange; - - if( newItemCount == 0 ) - { - maxItemRange = SelectionRange.Empty; - } - else - { - maxItemRange = new SelectionRange( 0, newItemCount - 1 ); - } - - if( selectedItemsCount > 0 ) - { - selectionChanger.UnselectAllItems(); - - for( int i = 0; i < selectedItemsCount; i++ ) - { - SelectionRangeWithItems rangeWithItems = selectedItemsStorage[ i ]; - object[] items = rangeWithItems.Items; - - if( items == null ) - { - SelectionRange itemRange = rangeWithItems.Range; - SelectionRange rangeIntersection = itemRange.Intersect( maxItemRange ); - - if( rangeIntersection != itemRange ) - { - if( rangeIntersection.IsEmpty ) - continue; - - rangeWithItems = new SelectionRangeWithItems( rangeIntersection, null ); - } - - selectionChanger.SelectItems( rangeWithItems ); - } - else - { - CollectionView sourceItems = dataGridContext.Items; - int itemsCount = items.Length; - SelectionRange range = rangeWithItems.Range; - - for( int j = 0; j < itemsCount; j++ ) - { - object item = items[ j ]; - object replacement = e.GetReplacement( item ) ?? item; - - int index = sourceItems.IndexOf( replacement ); - if( index >= 0 ) - { - selectionChanger.SelectItems( new SelectionRangeWithItems( index, replacement ) ); - } - } - } - } - } - - if( selectedCellsCount > 0 ) - { - selectionChanger.UnselectAllCells(); - - for( int i = 0; i < selectedCellsCount; i++ ) - { - SelectionCellRangeWithItems cellRangeWithItems = selectedCellsStorage[ i ]; - SelectionRangeWithItems itemRangeWithItems = cellRangeWithItems.ItemRangeWithItems; - object[] items = itemRangeWithItems.Items; - - if( items == null ) - { - SelectionRange itemRange = itemRangeWithItems.Range; - SelectionRange itemRangeIntersection = itemRange.Intersect( maxItemRange ); - - if( itemRangeIntersection != itemRange ) - { - if( itemRangeIntersection.IsEmpty ) - continue; - - cellRangeWithItems = new SelectionCellRangeWithItems( itemRangeIntersection, null, cellRangeWithItems.ColumnRange ); - } - - selectionChanger.SelectCells( cellRangeWithItems ); - } - else - { - CollectionView sourceItems = dataGridContext.Items; - int itemsCount = items.Length; - SelectionRange itemRange = cellRangeWithItems.ItemRange; - - for( int j = 0; j < itemsCount; j++ ) - { - object item = items[ j ]; - int index = sourceItems.IndexOf( item ); - - if( index != -1 ) - { - selectionChanger.SelectCells( new SelectionCellRangeWithItems( - new SelectionRange( index ), new object[] { item }, cellRangeWithItems.ColumnRange ) ); - } - } - } - } - } - } - finally - { - this.End( false, true ); - } - - break; - } - } - } - - public void UpdateSelection( - SelectionRangePoint oldPosition, - SelectionRangePoint newPosition, - bool oldFocusWasInTheGrid, - bool rowIsBeingEditedAndCurrentRowNotChanged, - Nullable updateSelectionSourceParam ) - { - if( oldPosition != null && oldPosition.Group != null ) - { - oldPosition = null; - } - - if( newPosition != null && newPosition.Group != null ) - { - newPosition = null; - } - - if( newPosition == null ) - return; - - UpdateSelectionSource updateSelectionSource = ( updateSelectionSourceParam.HasValue ) - ? updateSelectionSourceParam.Value : m_currentUpdateSelectionSource; - - // Force the node tree to be created since detail can be deleted during that node creation and selection uptade will be call - // That way we prevent selection code reentrance. - this.EnsureNodeTreeCreatedOnAllSubContext( m_owner.DataGridContext ); - - if( ( updateSelectionSource != UpdateSelectionSource.RowSelector ) - && ( updateSelectionSource != UpdateSelectionSource.MouseUp ) - && ( updateSelectionSource != UpdateSelectionSource.MouseMove ) ) - { - // Reset the fromRowSelector to ensure nothing special is done - // on next MouseUp - m_fromRowSelector = false; - } - - if( updateSelectionSource == UpdateSelectionSource.None ) - return; - - this.Begin(); - - try - { - switch( m_owner.SelectionModeToUse ) - { - case SelectionMode.Single: - { - this.DoSingleSelection( - newPosition, - oldFocusWasInTheGrid, rowIsBeingEditedAndCurrentRowNotChanged, updateSelectionSource ); - - break; - } - - case SelectionMode.Multiple: - { - this.DoMultipleSelection( - newPosition, rowIsBeingEditedAndCurrentRowNotChanged, updateSelectionSource ); - - break; - } - - case SelectionMode.Extended: - { - this.DoExtendedSelection( - oldPosition, newPosition, - oldFocusWasInTheGrid, rowIsBeingEditedAndCurrentRowNotChanged, updateSelectionSource ); - - break; - } - } - } - finally - { - this.End( true, false ); - } - } - - internal void UnselectAll() - { - // Add all the selected context to the activatedSelectionChanger since - // we will unselect all the selected item from it. - foreach( DataGridContext selectedDataGridContext in m_owner.SelectedContexts ) - { - this.GetSelectionChanger( selectedDataGridContext ); - } - - // Unselect all items and cells. - foreach( SelectionChanger activatedSelectionChanger in m_activatedSelectionChanger.Values ) - { - activatedSelectionChanger.UnselectAllItems(); - activatedSelectionChanger.UnselectAllCells(); - } - } - - internal void UnselectAllItems() - { - // Add all the selected context to the activatedSelectionChanger since - // we will unselect all the selected item from it. - foreach( DataGridContext selectedDataGridContext in m_owner.SelectedContexts ) - { - this.GetSelectionChanger( selectedDataGridContext ); - } - - // Unselect all item. - foreach( SelectionChanger activatedSelectionChanger in m_activatedSelectionChanger.Values ) - { - activatedSelectionChanger.UnselectAllItems(); - } - } - - internal void UnselectAllItems( DataGridContext dataGridContext ) - { - SelectionChanger selectionChanger = this.GetSelectionChanger( dataGridContext ); - selectionChanger.UnselectAllItems(); - } - - internal void UnselectAllCells() - { - // Add all the selected context to the activatedSelectionChanger since - // we will unselect all the selected item from it. - foreach( DataGridContext selectedDataGridContext in m_owner.SelectedContexts ) - { - this.GetSelectionChanger( selectedDataGridContext ); - } - - // Unselect all item. - foreach( SelectionChanger activatedSelectionChanger in m_activatedSelectionChanger.Values ) - { - activatedSelectionChanger.UnselectAllCells(); - } - } - - internal void UnselectAllCells( DataGridContext dataGridContext ) - { - SelectionChanger selectionChanger = this.GetSelectionChanger( dataGridContext ); - selectionChanger.UnselectAllCells(); - } - - private void EnsureNodeTreeCreatedOnAllSubContext( DataGridContext context ) - { - // context.GetChildContexts() do a EnsureNodeTreeCreated(), no need to do one before calling it - - foreach( var subContext in context.GetChildContexts() ) - { - this.EnsureNodeTreeCreatedOnAllSubContext( subContext ); - } - } - - private void DoSingleSelection( - SelectionRangePoint newPosition, - bool oldFocusWasInTheGrid, - bool rowIsBeingEditedAndCurrentRowNotChanged, - UpdateSelectionSource updateSelectionSource ) - { - - //Group selection is not valid in single selection mode. - if( newPosition == null || newPosition.Group != null ) - return; - - bool applySelection = true; - - if( updateSelectionSource == UpdateSelectionSource.Navigation ) - { - bool isPageKeys = Keyboard.IsKeyDown( Key.PageUp ) - || Keyboard.IsKeyDown( Key.PageDown ) - || Keyboard.IsKeyDown( Key.End ) - || Keyboard.IsKeyDown( Key.Home ); - - bool isCtrlPressed = ( Keyboard.Modifiers & ModifierKeys.Control ) == ModifierKeys.Control; - - //Special cases where selection should not be applied: - //1. Focus was not in the datagrid - //2. Ctrl is pressed but not the "page keys". - if( !oldFocusWasInTheGrid || ( isCtrlPressed && !isPageKeys ) ) - { - applySelection = false; - } - } - - // Special case for RowSelector : We do not want the - // MouseUp to clear the Selection when it was just set - // by the RowSelector - m_fromRowSelector |= ( updateSelectionSource == UpdateSelectionSource.RowSelector ); - - if( applySelection ) - { - //Handle the case where the selected item is not a datarow/cell. - bool isValid = ( m_owner.SelectionUnit == SelectionUnit.Row ) - ? ( newPosition.ItemIndex != -1 ) - : ( newPosition.ItemIndex != -1 ) && ( newPosition.ColumnIndex != -1 ); - - // In cell selection, Do not remove selection when it comes from the RowSelector - bool cellSelection = ( m_owner.SelectionUnit == SelectionUnit.Cell ); - - this.ApplySelection( null, newPosition, m_fromRowSelector, isValid, - doRangeSelection: false, - allowRangeUnselection: false, - toggleSelection: false, - keepSelection: m_fromRowSelector && cellSelection ); - } - } - - private void DoMultipleSelection( SelectionRangePoint newPosition, bool rowIsBeingEditedAndCurrentRowNotChanged, UpdateSelectionSource updateSelectionSource ) - { - if( newPosition == null ) - return; - - bool applySelection = true; - bool fromRowSelector = ( updateSelectionSource == UpdateSelectionSource.RowSelector ) || m_fromRowSelector; - bool toggleSelection = true; - - //Handle the case where the selected item is not a datarow/cell. - bool isValid = ( m_owner.SelectionUnit == SelectionUnit.Row ) || fromRowSelector - ? ( newPosition.Group != null ) || ( newPosition.ItemIndex != -1 ) - : ( newPosition.ItemIndex != -1 ) && ( newPosition.ColumnIndex != -1 ); - - switch( updateSelectionSource ) - { - case UpdateSelectionSource.RowSelector: - { - m_fromRowSelector = true; - goto case UpdateSelectionSource.MouseDown; - } - case UpdateSelectionSource.MouseDown: - { - m_updateSelectionOnNextMouseUp = - newPosition.GetIsSelected( m_owner.SelectionUnit ) - && !m_owner.UseDragToSelectBehavior; - - if( m_updateSelectionOnNextMouseUp ) - { - applySelection = false; - } - break; - } - - case UpdateSelectionSource.MouseUp: - { - if( !isValid || !m_updateSelectionOnNextMouseUp || rowIsBeingEditedAndCurrentRowNotChanged ) - { - applySelection = false; - } - - // Reset the fromRowSelector to ensure nothing special is done - // on next MouseUp (failsafe, should be reset by UpdateSelection) - m_fromRowSelector = false; - - // We reset the m_updateSelectionOnNextMouseUp to be sure when no focus is moved - // around that mouse up will toggle selection - m_updateSelectionOnNextMouseUp = true; - break; - } - - case UpdateSelectionSource.SpaceDown: - { - break; - } - case UpdateSelectionSource.MouseMove: - { - //This is no "unselection" or "toggle" when doing drag selection. - toggleSelection = false; - break; - } - - default: - { - //Fallback for "None", "Navigation" or other futur cases: - applySelection = false; - break; - } - } - - if( applySelection ) - { - //Never do range selections, Always keep selection, always toggle. - this.ApplySelection( null, newPosition, - fromRowSelector, isValid, - doRangeSelection: false, - allowRangeUnselection: false, - toggleSelection: toggleSelection, - keepSelection: true ); - } - } - - private void DoExtendedSelection( - SelectionRangePoint oldPosition, - SelectionRangePoint newPosition, - bool oldFocusWasInTheGrid, - bool rowIsBeingEditedAndCurrentRowNotChanged, - UpdateSelectionSource updateSelectionSource ) - { - if( newPosition == null ) - return; - - Group group = newPosition.Group; - DataGridContext dataGridContext = newPosition.DataGridContext; - object item = newPosition.Item; - int sourceDataItemIndex = newPosition.ItemIndex; - int columnIndex = newPosition.ColumnIndex; - - bool shift = ( Keyboard.Modifiers & ModifierKeys.Shift ) == ModifierKeys.Shift; - bool ctrl = ( Keyboard.Modifiers & ModifierKeys.Control ) == ModifierKeys.Control; - - //Default behavior - //Ctrl : Keep the current selection - //Shift : Do a range selection and Do not update the selection anchor. - //Ctrl+!Shift: Toggle current. - - bool keepSelection = ctrl; - bool toggleSelection = ctrl && !shift; - bool doRangeSelection = shift; - bool allowRangeUnselection = ctrl; - bool updateRangeStartPosition = !shift; - bool applySelection = true; - bool fromRowSelector = ( updateSelectionSource == UpdateSelectionSource.RowSelector ) || m_fromRowSelector; - bool cellSelection = ( m_owner.SelectionUnit == SelectionUnit.Cell ); - - //Handle the case where the selected item is not a datarow/cell. - bool isValid = ( m_owner.SelectionUnit == SelectionUnit.Row || fromRowSelector ) - ? ( newPosition.Group != null ) || ( newPosition.ItemIndex != -1 ) - : ( newPosition.ItemIndex != -1 ) && ( newPosition.ColumnIndex != -1 ); - - //Special case management in relation to update selection source - switch( updateSelectionSource ) - { - case UpdateSelectionSource.Navigation: - { - // Focus was not in the grid, do nothing. - if( !oldFocusWasInTheGrid ) - { - updateRangeStartPosition = false; - applySelection = false; - break; - } - - // About every behavior of the selection is different in - // keyboard navigation... - - // Navigation never toggle. "Ctrl+Space" is the way - // to select with the keyboard - toggleSelection = false; - - // Do not make range selection for the "Shift-Tab" case... - // Ignore the "Shift", just as it was not pressed. - if( Keyboard.IsKeyDown( Key.Tab ) ) - { - shift = false; - doRangeSelection = false; - } - - // Anchor also is keeped when Ctrl is pressed - updateRangeStartPosition = !ctrl && !shift; - - // Ctrl + Page[Up/Down] and Ctrl+ [Home/End] are special ways - // to scroll using navigation, and does reset the selection. - if( !shift && ctrl ) - { - if( Keyboard.IsKeyDown( Key.PageUp ) - || Keyboard.IsKeyDown( Key.PageDown ) - || Keyboard.IsKeyDown( Key.End ) - || Keyboard.IsKeyDown( Key.Home ) ) - { - keepSelection = false; - } - else - { - //Do not apply selection when moving with the Ctrl pressed. - applySelection = false; - } - } - - if( !keepSelection && !doRangeSelection ) - { - bool isSelected = ( cellSelection ) - ? dataGridContext.SelectedCellsStore.Contains( sourceDataItemIndex, columnIndex ) - : dataGridContext.SelectedItemsStore.Contains( sourceDataItemIndex ); - if( group == null - && isSelected - && rowIsBeingEditedAndCurrentRowNotChanged ) - { - applySelection = false; - } - } - break; - } - - case UpdateSelectionSource.MouseDown: - { - if( doRangeSelection ) - { - m_updateSelectionOnNextMouseUp = false; - } - else - { - m_updateSelectionOnNextMouseUp = - newPosition.GetIsSelected( m_owner.SelectionUnit ) - && !m_owner.UseDragToSelectBehavior; - // If the target item is already selected, do not update - // the selection on mouse down, differ this to mouse up. - if( m_updateSelectionOnNextMouseUp ) - { - applySelection = false; - - if( isValid ) - { - if( !( ctrl && !shift ) ) - { - m_updateSelectionOnNextMouseUp = !rowIsBeingEditedAndCurrentRowNotChanged; - } - } - } - } - break; - } - case UpdateSelectionSource.RowSelector: - { - if( doRangeSelection ) - { - m_updateSelectionOnNextMouseUp = false; - } - else - { - newPosition.ColumnIndex = 0; - isValid = ( newPosition.ItemIndex != -1 ); - - if( isValid ) - { - // If the target item is already selected, do not update - // the selection on mouse down, differ this to mouse up. - m_updateSelectionOnNextMouseUp = - newPosition.GetIsSelected( SelectionUnit.Row ) - && !m_owner.UseDragToSelectBehavior; - - if( m_updateSelectionOnNextMouseUp ) - { - applySelection = false; - } - } - } - break; - } - - case UpdateSelectionSource.MouseUp: - { - if( !isValid || !m_updateSelectionOnNextMouseUp ) - { - applySelection = false; - updateRangeStartPosition = false; - } - - - // Reset the fromRowSelector to ensure nothing special is done - // on next MouseUp (failsafe, should be reset by UpdateSelection) - m_fromRowSelector = false; - - // We reset the m_updateSelectionOnNextMouseUp to be sure when no focus is moved - // around that mouse up will toggle selection - m_updateSelectionOnNextMouseUp = true; - - break; - } - - case UpdateSelectionSource.SpaceDown: - { - //Space Will add to selection without removing the existing - //selection. (ie. Like Windows Explorer) - if( !ctrl && !shift ) - { - keepSelection = true; - } - break; - } - case UpdateSelectionSource.MouseMove: - { - toggleSelection = false; - doRangeSelection = true; - updateRangeStartPosition = false; - break; - } - default: - { - //Fallback for "None" or other futur cases: - applySelection = false; - updateRangeStartPosition = false; - break; - } - } - - if( updateRangeStartPosition ) - { - m_selectionRangeStartPoint = newPosition; - } - - if( applySelection ) - { - this.ApplySelection( - oldPosition, newPosition, - fromRowSelector, - isValid, - doRangeSelection, - allowRangeUnselection, - toggleSelection, keepSelection ); - } - } - - private void ApplySelection( - SelectionRangePoint oldPosition, - SelectionRangePoint newPosition, - bool fromRowSelector, - bool isValid, - bool doRangeSelection, - bool allowRangeUnselection, - bool toggleSelection, - bool keepSelection ) - { - if( !isValid ) - { - if( !keepSelection ) - { - this.UnselectAll(); - } - return; - } - - if( doRangeSelection ) - { - this.DoRangeSelection( oldPosition, newPosition, keepSelection, fromRowSelector, allowRangeUnselection ); - return; - } - - DataGridContext dataGridContext = newPosition.DataGridContext; - object item = newPosition.Item; - int sourceDataItemIndex = newPosition.ItemIndex; - int columnIndex = newPosition.ColumnIndex; - - Action toggleAction; - Action selectAndClearAction; - Action addToSelectionAction; - - if( m_owner.SelectionUnit == SelectionUnit.Cell ) - { - if( fromRowSelector ) - { - toggleAction = () => this.ToggleItemCellsSelection( dataGridContext, sourceDataItemIndex, item ); - selectAndClearAction = () => this.SelectItemCells( dataGridContext, sourceDataItemIndex, item, false ); - addToSelectionAction = () => this.SelectItemCells( dataGridContext, sourceDataItemIndex, item, true ); - } - else - { - toggleAction = () => this.ToggleCellSelection( dataGridContext, sourceDataItemIndex, item, columnIndex ); - selectAndClearAction = () => this.SelectJustThisCell( dataGridContext, sourceDataItemIndex, item, columnIndex ); - addToSelectionAction = () => this.SelectCells( dataGridContext, new SelectionCellRangeWithItems( sourceDataItemIndex, item, columnIndex ) ); - } - } - else - { - toggleAction = () => this.ToggleItemSelection( newPosition ); - selectAndClearAction = () => this.SelectJustThisItem( newPosition ); - addToSelectionAction = () => this.SelectItems( newPosition ); - } - - if( toggleSelection ) - { - toggleAction(); - } - else if( !keepSelection ) - { - selectAndClearAction(); - } - else - { - addToSelectionAction(); - } - } - - private void DoRangeSelection( - SelectionRangePoint oldPosition, - SelectionRangePoint newPosition, - bool keepPreviousSelection, - bool fromRowSelector, - bool allowRangeUnselection ) - { - // Un-select a range if we keep previous selection, and - // the selection anchor is a unselected item. - - //Group selection not supported. Be sure to have no ranges - //that will be relative to a group position. - if( newPosition != null && newPosition.Group != null ) - return; - - if( oldPosition != null && oldPosition.Group != null ) - { - oldPosition = null; - } - - if( m_selectionRangeStartPoint != null && m_selectionRangeStartPoint.Group != null ) - { - m_selectionRangeStartPoint = null; - } - - if( m_selectionRangeStartPoint == null ) - { - m_selectionRangeStartPoint = oldPosition ?? newPosition; - } - - bool unselect = false; - if( allowRangeUnselection && keepPreviousSelection ) - { - if( m_owner.SelectionUnit == SelectionUnit.Cell ) - { - unselect = ( fromRowSelector ) - ? !this.IsItemCellsSelected( m_selectionRangeStartPoint ) - : !this.IsCellSelected( m_selectionRangeStartPoint ); - } - else - { - unselect = !this.IsItemSelected( m_selectionRangeStartPoint ); - } - } - - this.DoRangeSelectionNoGroupSupport( newPosition, keepPreviousSelection, fromRowSelector, unselect ); - } - - private void DoRangeSelectionNoGroupSupport( SelectionRangePoint newPosition, bool keepPreviousSelection, bool fromRowSelector, bool unselect ) - { - int starting_index = m_selectionRangeStartPoint.ItemGlobalIndex; - int ending_index = newPosition.ItemGlobalIndex; - - if( !keepPreviousSelection ) - { - this.UnselectAll(); - } - - // here I need to normalize the values to ensure that I'm not catching the Fixed Headers or Fixed Footers - if( starting_index != -1 && ending_index != -1 ) - { - - int min = Math.Min( starting_index, ending_index ); - int max = Math.Max( starting_index, ending_index ); - - SelectionRange[] selectedColumns; - - if( m_owner.SelectionUnit == SelectionUnit.Row ) - { - selectedColumns = null; - } - else - { - SelectionRange fullColumnRange; - - // If called from a RowSelector, we do a range - // selection using all the columns no matter - // what was the previous anchor - if( fromRowSelector ) - { - m_selectionRangeStartPoint.ColumnIndex = 0; - fullColumnRange = new SelectionRange( 0, Math.Max( 0, newPosition.DataGridContext.ColumnsByVisiblePosition.Count - 1 ) ); - } - else - { - if( m_selectionRangeStartPoint.ColumnIndex == -1 ) - m_selectionRangeStartPoint.ColumnIndex = 0; - - if( newPosition.ColumnIndex == -1 ) - return; - - fullColumnRange = new SelectionRange( m_selectionRangeStartPoint.ColumnIndex, newPosition.ColumnIndex ); - } - - SelectedItemsStorage selectedColumnStore = new SelectedItemsStorage( null ); - selectedColumnStore.Add( new SelectionRangeWithItems( fullColumnRange, null ) ); - int index = 0; - - foreach( ColumnBase column in newPosition.DataGridContext.ColumnsByVisiblePosition ) - { - if( !column.Visible ) - { - selectedColumnStore.Remove( new SelectionRangeWithItems( new SelectionRange( index ), null ) ); - } - - index++; - } - - selectedColumns = selectedColumnStore.ToSelectionRangeArray(); - } - - IDataGridContextVisitable visitable = ( IDataGridContextVisitable )m_owner.DataGridContext; - bool visitWasStopped; - - visitable.AcceptVisitor( - min, max, - new RangeSelectionVisitor( selectedColumns, unselect ), - DataGridContextVisitorType.ItemsBlock, out visitWasStopped ); - } - } - - private void AffectSelectionRange( List startPath, List endPath, bool unselect ) - { - // For each DataContext depth of each path. - for( int i = Math.Max( startPath.Count, endPath.Count ) - 1; i >= 0; i-- ) - { - DataGridContext startContext = null; - DataGridContext endContext = null; - int startIndex = -1; - int endIndex = -1; - int notUsed; - - if( i < startPath.Count ) - { - startContext = startPath[ i ].DataGridContext; - this.ExtractRangePositionIndexes( startPath[ i ], out startIndex, out notUsed ); - if( i != startPath.Count - 1 ) - { - // Except for the deepest level of the start path, - // We should not include the start index in the selection - // This is because the parent item placeholder (ie. the master row) is - // over/before the displayed children, and is not visually within - // the range of the selection. - startIndex++; - } - } - - if( i < endPath.Count ) - { - endContext = endPath[ i ].DataGridContext; - this.ExtractRangePositionIndexes( endPath[ i ], out notUsed, out endIndex ); - } - - if( startContext != endContext ) - { - if( startContext != null ) - { - // This is a sub context unique to the start selection path. - // Since the selection go beyond this data context, select all items starting - // at the startIndex to the last item of this context. - int lastItemIndex = startContext.Items.Count - 1; - this.AffectSelectionRecursivelyForSelectRange( startContext, startIndex, lastItemIndex, unselect ); - } - - if( endContext != null ) - { - // This is a sub context unique to the end selection path. - // Since the selection is starting before this data context, select all items from - // the first of this data context down to the endIndex. - this.AffectSelectionRecursivelyForSelectRange( endContext, 0, endIndex, unselect ); - } - } - else - { - // The context is the same for start and end path. - // Select only items within the range of the startIndex down to the - // endIndex. - Debug.Assert( startContext != null ); - this.AffectSelectionRecursivelyForSelectRange( startContext, startIndex, endIndex, unselect ); - } - } - } - - private void AffectSelectionRecursivelyForSelectRange( DataGridContext dataGridContext, int startIndex, int endIndex, bool unselect ) - { - if( startIndex > endIndex ) - return; - - // We do not Recursively select the last item since the children - // of theses will go beyond this last item. - if( startIndex < endIndex ) - { - this.AffectSelectionRecursivelyOnDetails( dataGridContext, startIndex, endIndex - 1, unselect ); - } - - //Select, not recursively the last item of the range. - var selectionRange = new SelectionRangeWithItems( new SelectionRange( endIndex, endIndex ), null ); - this.AffectSelection( dataGridContext, selectionRange, unselect ); - } - - private bool AffectSelectionRecursivelyOnDetails( DataGridContext dataGridContext, int startIndex, int endIndex, bool unselect ) - { - if( startIndex < 0 || endIndex < 0 ) - return false; - - //Apply the selection operation at the current level. - var rangeWithItem = new SelectionRangeWithItems( new SelectionRange( startIndex, endIndex ), null ); - bool wasAlreadyDone = this.AffectSelection( dataGridContext, rangeWithItem, unselect ); - - if( dataGridContext.DetailConfigurations.Count > 0 ) - { - int firstIndex = Math.Min( startIndex, endIndex ); - int lastIndex = Math.Max( startIndex, endIndex ); - - for( int i = firstIndex; i <= lastIndex; i++ ) - { - // If the items are not provided, extract them from the DataGridContext. - var item = dataGridContext.Items.GetItemAt( i ); - foreach( var configuration in dataGridContext.DetailConfigurations ) - { - var subContext = dataGridContext.GetChildContext( item, configuration ); - if( subContext != null ) - { - wasAlreadyDone = wasAlreadyDone - && this.AffectSelectionRecursivelyOnDetails( subContext, 0, subContext.Items.Count - 1, unselect ); - } - } - } - } - - return wasAlreadyDone; - } - - private bool AffectSelection( DataGridContext dataGridContext, SelectionRangeWithItems selectionRange, bool unselect ) - { - return ( unselect ) - ? this.UnselectItems( dataGridContext, selectionRange ) - : this.SelectItems( dataGridContext, selectionRange ); - } - - private bool IsItemSelected( SelectionRangePoint rangePosition ) - { - return this.IsItemSelected( rangePosition.DataGridContext, rangePosition.ItemIndex ); - } - - private bool IsItemSelected( DataGridContext context, int itemIndex ) - { - return context.SelectedItemsStore.Contains( itemIndex ); - } - - private bool IsCellSelected( SelectionRangePoint selectionPoint ) - { - return this.IsCellSelected( selectionPoint.DataGridContext, selectionPoint.ItemIndex, selectionPoint.ColumnIndex ); - } - - private bool IsCellSelected( DataGridContext context, int itemIndex, int columnIndex ) - { - return context.SelectedCellsStore.Contains( itemIndex, columnIndex ); - } - - private bool IsItemCellsSelected( SelectionRangePoint selectionPoint ) - { - SelectedCellsStorage itemCells = this.GetItemCellStorage( selectionPoint.DataGridContext, - selectionPoint.ItemIndex, selectionPoint.Item ); - - return this.IsItemCellsSelected( selectionPoint.DataGridContext, itemCells ); - } - - private bool IsItemCellsSelected( DataGridContext dataGridContext, SelectedCellsStorage itemCellsStorage ) - { - bool allCellSelected = true; - - foreach( SelectionCellRangeWithItems allCellSelection in itemCellsStorage ) - { - if( !dataGridContext.SelectedCellsStore.Contains( allCellSelection ) ) - { - allCellSelected = false; - break; - } - } - - return allCellSelected; - } - - private SelectedCellsStorage GetItemCellStorage( DataGridContext dataGridContext, int itemIndex, object item ) - { - SelectedCellsStorage tempStorage = new SelectedCellsStorage( null ); - tempStorage.Add( this.GetItemCellRange( dataGridContext, itemIndex, item ) ); - - foreach( ColumnBase column in dataGridContext.ColumnsByVisiblePosition ) - { - if( !column.Visible ) - tempStorage.Remove( new SelectionCellRangeWithItems( itemIndex, item, column.VisiblePosition ) ); - } - - return tempStorage; - } - - private SelectionCellRangeWithItems GetItemCellRange( DataGridContext dataGridContext, int itemIndex, object item ) - { - SelectionRange itemRange = new SelectionRange( itemIndex ); - - SelectionRange cellRange = new SelectionRange( 0, - Math.Max( 0, dataGridContext.Columns.Count - 1 ) ); - - // Select all visible cells for this itemIndex - return new SelectionCellRangeWithItems( itemRange, new object[] { item }, cellRange ); - } - - private int CompareRangePosition( List range1Indexes, List range2Indexes ) - { - for( int i = 0; i < range1Indexes.Count && i < range2Indexes.Count; i++ ) - { - SelectionRangePoint node1 = range1Indexes[ i ]; - SelectionRangePoint node2 = range2Indexes[ i ]; - - Debug.Assert( node1.DataGridContext == node2.DataGridContext ); - int node1First, node1Last; - int node2First, node2Last; - - this.ExtractRangePositionIndexes( node1, out node1First, out node1Last ); - this.ExtractRangePositionIndexes( node2, out node2First, out node2Last ); - - if( node1First < node2First ) - { - return -1; - } - else if( node1First > node2First ) - { - return 1; - } - else - { - // Both node have the same first index. They may however represent - // different items (Ex. A the first item or subgroup of a group - // in relation to this parent group) - // - // In this case, since the group is visually represented as - // the "header" of it's children, consider - // the parent group to be "before" its children. - // The the parent group of an item/subgroup will have a - // higher last index than its children. - if( node1Last != node2Last ) - { - return ( node1Last > node2Last ) - ? -1 - : 1; - } - } - } - - // Since the visual representation of the master is before the children, - // any Master->Children comparaision will identify the master to be "before" - // the children. - if( range1Indexes.Count != range2Indexes.Count ) - { - return ( range1Indexes.Count < range2Indexes.Count ) ? -1 : 1; - } - - // Paths are perfectly equals - return 0; - } - - private List CreatePathForSelectionPoint( SelectionRangePoint rangePoint ) - { - var indexList = new List(); - - indexList.Insert( 0, rangePoint ); - - var context = rangePoint.DataGridContext; - var parentContext = context.ParentDataGridContext; - - while( parentContext != null ) - { - var parentIndex = parentContext.Items.IndexOf( context.ParentItem ); - - var parentRangePoint = SelectionRangePoint.TryCreateRangePoint( parentContext, context.ParentItem, parentIndex, -1 ); - if( parentRangePoint != null ) - { - indexList.Insert( 0, parentRangePoint ); - } - - context = parentContext; - parentContext = parentContext.ParentDataGridContext; - } - - return indexList; - } - - private void ExtractRangePositionIndexes( SelectionRangePoint rangePosition, out int firstIndex, out int lastIndex ) - { - firstIndex = -1; - lastIndex = -1; - - if( rangePosition.Item != null ) - { - Debug.Assert( rangePosition.ItemIndex != -1 ); - firstIndex = rangePosition.ItemIndex; - lastIndex = firstIndex; - } - else if( rangePosition.Group != null ) - { - var groupRange = rangePosition.Group.GetRange(); - firstIndex = groupRange.StartIndex; - lastIndex = groupRange.EndIndex; - } - - Debug.Assert( firstIndex <= lastIndex ); - } - - private SelectionChanger GetSelectionChanger( DataGridContext dataGridContext ) - { - if( dataGridContext == null ) - return null; - - var selectionChanger = default( SelectionChanger ); - - if( !m_activatedSelectionChanger.TryGetValue( dataGridContext, out selectionChanger ) ) - { - selectionChanger = new SelectionChanger( dataGridContext ); - m_activatedSelectionChanger.Add( dataGridContext, selectionChanger ); - } - - return selectionChanger; - } - - private void CommitSelectionChanger( SelectionChanger selectionChanger ) - { - try - { - selectionChanger.UpdateSelectedItemsInChangeOfDataGridContext(); - selectionChanger.UpdateSelectedCellsInChangeOfDataGridContext(); - } - finally - { - selectionChanger.Cleanup(); - } - - selectionChanger.Owner.UpdatePublicSelectionProperties(); - } - - private void UpdateCurrentToSelection() - { - var currentContext = m_owner.CurrentContext; - var currentItemIndex = default( int ); - var currentColumn = default( ColumnBase ); - - var selectedColumn = default( ColumnBase ); - var selectedColumnIndex = -1; - var selectedItemIndex = -1; - var selectedItem = default( object ); - - if( ( currentContext == null ) || !m_owner.SelectedContexts.Contains( currentContext ) ) - { - currentItemIndex = -1; - currentColumn = null; - - if( m_owner.SelectedContexts.Count > 0 ) - { - currentContext = m_owner.SelectedContexts[ 0 ]; - currentContext.GetFirstSelectedItemFromStore( true, out selectedItemIndex, out selectedItem, out selectedColumnIndex ); - } - } - else - { - currentItemIndex = currentContext.CurrentItemIndex; - currentColumn = currentContext.CurrentColumn; - currentContext.GetFirstSelectedItemFromStore( true, out selectedItemIndex, out selectedItem, out selectedColumnIndex ); - } - - if( currentContext == null ) - return; - - if( m_owner.SelectionUnit == SelectionUnit.Cell ) - { - if( ( currentItemIndex != -1 ) && ( currentColumn != null ) - && currentContext.SelectedCellsStore.GetIntersectedColumnRanges( new SelectionCellRange( currentItemIndex, currentColumn.VisiblePosition ) ).Any() ) - return; - - selectedColumn = currentContext.ColumnsByVisiblePosition.ElementAtOrDefault( selectedColumnIndex ); - } - else - { - if( ( currentItemIndex != -1 ) && currentContext.SelectedItemsStore.Contains( currentItemIndex ) ) - return; - - selectedColumn = currentContext.CurrentColumn; - } - - // No need to change Current when the previous and subsequent current are both null, even if SelectionUnit is set to Cell and columns do not correspond, - // since there is no current anyway. It will be correctly updated next time an item becomes current. - if( selectedItem == currentContext.CurrentItem ) - return; - - currentContext.SetCurrent( selectedItem, null, selectedItemIndex, selectedColumn, false, true, false, AutoScrollCurrentItemSourceTriggers.SelectionChanged ); - } - - private bool m_isActive; - private readonly Dictionary m_activatedSelectionChanger = new Dictionary(); - private readonly DataGridControl m_owner; - private SelectionRangePoint m_selectionRangeStartPoint; - private bool m_updateSelectionOnNextMouseUp = true; - private bool m_fromRowSelector; // = false; - - // = Navigation ? - private UpdateSelectionSource m_currentUpdateSelectionSource; - - private class UpdateSelectionSourceHelper : IDisposable - { - public UpdateSelectionSourceHelper( - SelectionManager selectionManager, - UpdateSelectionSource newUpdateSelectionSource ) - { - m_selectionManager = selectionManager; - m_oldUpdateSelectionSource = selectionManager.m_currentUpdateSelectionSource; - selectionManager.m_currentUpdateSelectionSource = newUpdateSelectionSource; - } - - private UpdateSelectionSource m_oldUpdateSelectionSource; - private SelectionManager m_selectionManager; - - #region IDisposable Members - - public void Dispose() - { - m_selectionManager.m_currentUpdateSelectionSource = m_oldUpdateSelectionSource; - } - - #endregion IDisposable Members - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionRange.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionRange.cs deleted file mode 100644 index 973d85dd..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionRange.cs +++ /dev/null @@ -1,354 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Diagnostics; - -namespace Xceed.Wpf.DataGrid -{ - public struct SelectionRange : IComparable - { - public static readonly SelectionRange Empty = new SelectionRange( -1 ); - - #region CONSTRUCTORS - - public SelectionRange( int startIndex, int endIndex ) - { - if( ( startIndex < 0 ) || ( startIndex >= int.MaxValue ) ) - throw new ArgumentOutOfRangeException( "startIndex", "startIndex must be equal to or greater than zero and lower than int.MaxValue." ); - - if( ( endIndex < 0 ) || ( endIndex >= int.MaxValue ) ) - throw new ArgumentOutOfRangeException( "endIndex", "endIndex must be equal to or greater than zero and lower than int.MaxValue." ); - - m_startIndex = startIndex; - m_endIndex = endIndex; - } - - public SelectionRange( int index ) - { - // Only place where we accept index = -1 - if( ( index < -1 ) || ( index >= int.MaxValue ) ) - throw new ArgumentOutOfRangeException( "index", "index must be equal to or greater than -1 and lower than int.MaxValue." ); - - m_startIndex = index; - m_endIndex = index; - } - - #endregion - - #region StartIndex Property - - public int StartIndex - { - get - { - return m_startIndex; - } - set - { - if( ( value < 0 ) || ( value >= int.MaxValue ) ) - throw new ArgumentOutOfRangeException( "StartIndex", "StartIndex must be equal to or greater than zero and lower than int.MaxValue." ); - - m_startIndex = value; - } - } - - private int m_startIndex; - - #endregion - - #region EndIndex Property - - public int EndIndex - { - get - { - return m_endIndex; - } - set - { - if( ( value < 0 ) || ( value >= int.MaxValue ) ) - throw new ArgumentOutOfRangeException( "EndIndex", "EndIndex must be equal to or greater than zero and lower than int.MaxValue." ); - - m_endIndex = value; - } - } - - private int m_endIndex; - - #endregion - - #region Length Property - - public int Length - { - get - { - if( this.IsEmpty ) - return 0; - - return Math.Abs( m_endIndex - m_startIndex ) + 1; - } - } - - #endregion - - #region IsEmpty Property - - public bool IsEmpty - { - get - { - return ( m_startIndex == -1 ) || ( m_endIndex == -1 ); - } - } - - #endregion - - public static bool operator >( SelectionRange range1, SelectionRange range2 ) - { - if( range1.m_startIndex > range1.m_endIndex ) - { - if( range2.m_startIndex < range2.m_endIndex ) - { - return range1.m_endIndex > range2.m_endIndex; - } - else - { - return range1.m_endIndex > range2.m_startIndex; - } - } - else - { - if( range2.m_startIndex > range2.m_endIndex ) - { - return range1.m_startIndex > range2.m_startIndex; - } - else - { - return range1.m_startIndex > range2.m_endIndex; - } - } - } - - public static bool operator <( SelectionRange range1, SelectionRange range2 ) - { - if( range1.m_startIndex > range1.m_endIndex ) - { - if( range2.m_startIndex < range2.m_endIndex ) - { - return range1.m_startIndex < range2.m_startIndex; - } - else - { - return range1.m_startIndex < range2.m_endIndex; - } - } - else - { - if( range2.m_startIndex > range2.m_endIndex ) - { - return range1.m_endIndex < range2.m_endIndex; - } - else - { - return range1.m_endIndex < range2.m_startIndex; - } - } - } - - public static bool operator ==( SelectionRange range1, SelectionRange range2 ) - { - return range1.Equals( range2 ); - } - - public static bool operator !=( SelectionRange range1, SelectionRange range2 ) - { - return !range1.Equals( range2 ); - } - - public SelectionRange Intersect( SelectionRange range ) - { - int newStart; - int newEnd; - - if( m_startIndex > m_endIndex ) - { - if( range.m_startIndex < range.m_endIndex ) - { - int temp = range.m_startIndex; - range.m_startIndex = range.m_endIndex; - range.m_endIndex = temp; - } - - newStart = Math.Min( range.m_startIndex, m_startIndex ); - newEnd = Math.Max( range.m_endIndex, m_endIndex ); - - if( newEnd > newStart ) - return SelectionRange.Empty; - } - else - { - if( range.m_startIndex > range.m_endIndex ) - { - int temp = range.m_startIndex; - range.m_startIndex = range.m_endIndex; - range.m_endIndex = temp; - } - - newStart = Math.Max( range.m_startIndex, m_startIndex ); - newEnd = Math.Min( range.m_endIndex, m_endIndex ); - - if( newStart > newEnd ) - return SelectionRange.Empty; - } - - return new SelectionRange( newStart, newEnd ); - } - - public SelectionRange[] Exclude( SelectionRange rangeToExclude ) - { - if( rangeToExclude.IsEmpty ) - return new SelectionRange[] { this }; - - var rangeIntersection = this.Intersect( rangeToExclude ); - if( rangeIntersection.IsEmpty ) - return new SelectionRange[] { this }; - - if( m_startIndex > m_endIndex ) - { - Debug.Assert( rangeIntersection.StartIndex >= rangeIntersection.EndIndex ); - - if( rangeIntersection.EndIndex > m_endIndex ) - { - var newRange = this; - newRange.StartIndex = rangeIntersection.EndIndex - 1; - - if( rangeIntersection.StartIndex < m_startIndex ) - { - return new SelectionRange[] - { - new SelectionRange( m_startIndex, rangeIntersection.StartIndex + 1 ), - newRange - }; - } - else - { - return new SelectionRange[] { newRange }; - } - } - else - { - if( rangeIntersection.StartIndex < m_startIndex ) - { - var newRange = this; - newRange.EndIndex = rangeIntersection.StartIndex + 1; - return new SelectionRange[] { newRange }; - } - } - } - else - { - Debug.Assert( rangeIntersection.StartIndex <= rangeIntersection.EndIndex ); - - if( rangeIntersection.StartIndex > m_startIndex ) - { - SelectionRange newRange = this; - newRange.EndIndex = rangeIntersection.StartIndex - 1; - - if( rangeIntersection.EndIndex < m_endIndex ) - { - return new SelectionRange[] - { - newRange, - new SelectionRange( rangeIntersection.EndIndex + 1, m_endIndex ) - }; - } - else - { - return new SelectionRange[] { newRange }; - } - } - else - { - if( rangeIntersection.EndIndex < m_endIndex ) - { - SelectionRange newRange = this; - newRange.StartIndex = rangeIntersection.EndIndex + 1; - return new SelectionRange[] { newRange }; - } - } - } - - return new SelectionRange[ 0 ]; - } - - public override bool Equals( object obj ) - { - if( !( obj is SelectionRange ) ) - return false; - - var selectionRange = ( SelectionRange )obj; - - return ( selectionRange.m_startIndex == m_startIndex ) - && ( selectionRange.m_endIndex == m_endIndex ); - } - - public override int GetHashCode() - { - return ( ( m_startIndex >> 16 ) | ( m_startIndex << 16 ) ) ^ m_endIndex; - } - - public int GetIndexFromItemOffset( int itemOffset ) - { - if( m_startIndex > m_endIndex ) - { - return m_startIndex - itemOffset; - } - else - { - return m_startIndex + itemOffset; - } - } - - public int GetOffsetFromItemIndex( int itemIndex ) - { - if( m_startIndex > m_endIndex ) - { - return m_startIndex - itemIndex; - } - else - { - return itemIndex - m_startIndex; - } - } - - #region IComparable Members - - public int CompareTo( SelectionRange other ) - { - if( this < other ) - return -1; - - if( this > other ) - return 1; - - return 0; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionRangePoint.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionRangePoint.cs deleted file mode 100644 index cc23be8b..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionRangePoint.cs +++ /dev/null @@ -1,188 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Linq; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class SelectionRangePoint - { - private SelectionRangePoint() - { - } - - private SelectionRangePoint( DataGridContext dataGridContext, object item, int itemIndex, int columnPosition ) - { - if( dataGridContext == null ) - throw new ArgumentNullException(); - - if( item == null ) - throw new ArgumentNullException(); - - m_localIndex = itemIndex; - - this.Item = item; - this.ColumnIndex = columnPosition; - this.DataGridContext = dataGridContext; - } - - private SelectionRangePoint( Group group ) - { - if( group == null ) - throw new ArgumentNullException(); - - this.Group = group; - this.DataGridContext = group.DataGridContext; - this.ColumnIndex = -1; - } - - public object Item - { - get; - private set; - } - - public int ColumnIndex - { - get; - set; - } - - public Group Group - { - get; - private set; - } - - public DataGridContext DataGridContext - { - get; - private set; - } - - public int ItemIndex - { - get - { - if( m_localIndex == null ) - { - m_localIndex = this.DataGridContext.Items.IndexOf( this.Item ); - } - - return m_localIndex.Value; - } - - } - - public int ItemGlobalIndex - { - get - { - if( m_globalIndex == null ) - { - m_globalIndex = this.DataGridContext.DataGridControl.GetGlobalGeneratorIndexFromItem( this.DataGridContext, this.Item ); - } - - return m_globalIndex.Value; - } - } - - public bool GetIsSelected( SelectionUnit selectionUnit ) - { - if( selectionUnit == SelectionUnit.Cell ) - { - return this.DataGridContext.SelectedCellsStore.Contains( this.ItemIndex, this.ColumnIndex ); - } - else if( selectionUnit == SelectionUnit.Row ) - { - if( this.ItemIndex >= 0 ) - { - return this.DataGridContext.SelectedItemsStore.Contains( this.ItemIndex ); - } - } - - return false; - } - - public static SelectionRangePoint TryCreateRangePoint( DataGridContext dataGridContext, object item, int itemIndex, int columnIndex ) - { - if( ( dataGridContext == null ) || ( item == null ) ) - return null; - - if( !( item is GroupHeaderFooterItem ) ) - return new SelectionRangePoint( dataGridContext, item, itemIndex, columnIndex ); - - var dataGridControl = dataGridContext.DataGridControl; - if( ( dataGridControl == null ) ) - return null; - - var group = dataGridContext.GetGroupFromCollectionViewGroup( ( ( GroupHeaderFooterItem )item ).Group ); - - return SelectionRangePoint.TryCreateRangePoint( group ); - } - - public static SelectionRangePoint TryCreateRangePoint( Group group ) - { - if( group != null ) - return new SelectionRangePoint( group ); - - return null; - } - - public static SelectionRangePoint TryCreateFromCurrent( DataGridContext dataGridContext ) - { - if( dataGridContext == null ) - return null; - - var dataGridControl = dataGridContext.DataGridControl; - if( dataGridControl == null ) - return null; - - var column = dataGridContext.CurrentColumn; - int columnIndex = ( column != null ) ? column.VisiblePosition : -1; - - var oldPosition = SelectionRangePoint.TryCreateRangePoint( dataGridContext, dataGridContext.CurrentItem, dataGridContext.CurrentItemIndex, columnIndex ); - if( oldPosition == null ) - { - oldPosition = SelectionRangePoint.TryCreateRangePoint( dataGridContext, dataGridContext.InternalCurrentItem, -1, columnIndex ); - } - - return oldPosition; - } - - public SelectionRangeWithItems ToSelectionRangeWithItems() - { - if( this.Item != null ) - { - return new SelectionRangeWithItems( this.ItemIndex, this.Item ); - } - else - { - var group = this.Group; - var dataGridContext = group.DataGridContext; - var groupList = group.GetLeafItems().ToArray(); - int firstIndex = dataGridContext.Items.IndexOf( groupList[ 0 ] ); - int lastIndex = dataGridContext.Items.IndexOf( groupList[ groupList.Length - 1 ] ); - - return new SelectionRangeWithItems( new SelectionRange( firstIndex, lastIndex ), groupList ); - } - } - - private int? m_globalIndex; - private int? m_localIndex; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionRangeWithItems.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionRangeWithItems.cs deleted file mode 100644 index ed281619..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SelectionRangeWithItems.cs +++ /dev/null @@ -1,312 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Diagnostics; - -namespace Xceed.Wpf.DataGrid -{ - internal struct SelectionRangeWithItems - { - public static readonly SelectionRangeWithItems Empty = new SelectionRangeWithItems( new SelectionRange( -1 ), null ); - - public SelectionRangeWithItems( int itemIndex, object item ) - : this( new SelectionRange( itemIndex ), new object[] { item } ) - { - } - - public SelectionRangeWithItems( SelectionRange range, object[] items ) - { - if( ( items != null ) && ( items.Length != range.Length ) && ( !range.IsEmpty ) ) - throw new ArgumentException( "selectionRange and items must have the same length." ); - - m_items = ( items != null ) ? new OptimizedItemsList( items ) : null; - m_range = range; - } - - internal SelectionRangeWithItems( SelectionRange range, SharedList items ) - { - if( ( items.Count != range.Length ) && ( !range.IsEmpty ) ) - throw new ArgumentException( "selectionRange and items must have the same length." ); - - m_items = new OptimizedItemsList( items ); - m_range = range; - } - - #region SelectionRange Property - - public SelectionRange Range - { - get - { - return m_range; - } - } - - private SelectionRange m_range; - - #endregion - - #region Items Property - - public object[] Items - { - get - { - if( m_items == null ) - return null; - - return m_items.ItemsArray; - } - } - - private OptimizedItemsList m_items; - - #endregion - - #region ItemsList Property - - internal SharedList? SharedList - { - get - { - if( m_items == null ) - return null; - - return m_items.SharedList; - } - } - - #endregion - - #region Length Property - - public int Length - { - get - { - return m_range.Length; - } - } - - #endregion - - #region IsEmpty Property - - public bool IsEmpty - { - get - { - return m_range.IsEmpty; - } - } - - #endregion - - public static bool operator ==( SelectionRangeWithItems rangeWithItems1, SelectionRangeWithItems rangeWithItems2 ) - { - if( rangeWithItems1.Range != rangeWithItems2.Range ) - return false; - - return rangeWithItems1.IsItemsEqual( rangeWithItems1.Range, rangeWithItems2 ); - } - - public static bool operator !=( SelectionRangeWithItems rangeWithItems1, SelectionRangeWithItems rangeWithItems2 ) - { - if( rangeWithItems1.Range != rangeWithItems2.Range ) - return true; - - return !rangeWithItems1.IsItemsEqual( rangeWithItems1.Range, rangeWithItems2 ); - } - - public bool IsItemsEqual( SelectionRange rangeIntersection, SelectionRangeWithItems rangeWithItemsToCompare ) - { - OptimizedItemsList itemsToCompare = rangeWithItemsToCompare.m_items; - - if( ( m_items == null ) || ( itemsToCompare == null ) ) - return true; - - SelectionRange rangeToCompare = rangeWithItemsToCompare.Range; - int startIndex = Math.Min( rangeIntersection.StartIndex, rangeIntersection.EndIndex ); - int itemIndex1 = Math.Abs( startIndex - m_range.StartIndex ); - int itemIndex2 = Math.Abs( startIndex - rangeToCompare.StartIndex ); - bool inversedRange1 = m_range.StartIndex > m_range.EndIndex; - bool inversedRange2 = rangeToCompare.StartIndex > rangeToCompare.EndIndex; - int count = rangeIntersection.Length; - - for( int i = 0; i < count; i++ ) - { - if( !object.Equals( m_items[ itemIndex1 ], itemsToCompare[ itemIndex2 ] ) ) - return false; - - itemIndex1 = inversedRange1 ? itemIndex1 - 1 : itemIndex1 + 1; - itemIndex2 = inversedRange2 ? itemIndex2 - 1 : itemIndex2 + 1; - } - - return true; - } - - public object GetItem( DataGridContext dataGridContext, int offset ) - { - if( m_items != null ) - return m_items[ offset ]; - - int rangeStart = m_range.StartIndex; - int rangeEnd = m_range.EndIndex; - - if( rangeStart > rangeEnd ) - { - return dataGridContext.Items.GetItemAt( rangeStart - offset ); - } - else - { - return dataGridContext.Items.GetItemAt( rangeStart + offset ); - } - } - - public object[] GetItems( SelectionRange range ) - { - if( m_items == null ) - return null; - - if( range.IsEmpty ) - return new object[ 0 ]; - - int startOffset; - bool reverseOrder; - - SelectionRange rangeIntersection = m_range.Intersect( range ); - - if( m_range.StartIndex > m_range.EndIndex ) - { - startOffset = m_range.StartIndex - rangeIntersection.StartIndex; - reverseOrder = range.StartIndex < range.EndIndex; - } - else - { - startOffset = rangeIntersection.StartIndex - m_range.StartIndex; - reverseOrder = range.StartIndex > range.EndIndex; - } - - object[] items = new object[ rangeIntersection.Length ]; - m_items.CopyItemsToArray( startOffset, items, 0, items.Length ); - - if( reverseOrder ) - { - Array.Reverse( items ); - } - - return items; - } - - public override int GetHashCode() - { - return m_range.GetHashCode(); - } - - public override bool Equals( object obj ) - { - if( !( obj is SelectionRangeWithItems ) ) - return false; - - return ( ( SelectionRangeWithItems )obj ) == this; - } - - #region OptimizedItemsList Private Class - - // Performance optimization. - // This wrapper class allows to store items as an array (exclusive)OR as a SharedList. - // This allows a uniform API to access the items, whether they are stored as an Array or as a SharedList. - // - // The SharedList allows us to be more efficient when we need to add items to the existing ones. - // The Array allows the return of a value to the SelectionRangeWithItems.Items property more efficiently. - private class OptimizedItemsList - { - public OptimizedItemsList( SharedList list ) - { - m_itemsArray = null; - m_itemsList = list; - } - - public OptimizedItemsList( object[] items ) - { - if( items == null ) - throw new ArgumentNullException( "items" ); - - m_itemsArray = items; - m_itemsList = null; - } - - public object this[ int index ] - { - get - { - if( m_itemsArray != null ) - { - return m_itemsArray[ index ]; - } - else - { - Debug.Assert( m_itemsList != null ); - return m_itemsList.Value[ index ]; - } - } - } - - public SharedList? SharedList - { - get - { - return m_itemsList; - } - } - - public object[] ItemsArray - { - get - { - //Convert the list to an array if needed. - if( m_itemsList != null ) - { - Debug.Assert( m_itemsArray == null ); - m_itemsArray = m_itemsList.Value.ToArray(); - m_itemsList = null; - } - - return m_itemsArray; - } - } - - public void CopyItemsToArray( int index, object[] array, int arrayIndex, int length ) - { - if( m_itemsArray != null ) - { - Array.Copy( m_itemsArray, index, array, arrayIndex, length ); - } - else - { - Debug.Assert( m_itemsList != null ); - m_itemsList.Value.CopyTo( index, array, arrayIndex, length ); - } - } - - private object[] m_itemsArray; - private SharedList? m_itemsList; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SharedListStruct.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SharedListStruct.cs deleted file mode 100644 index 049a8312..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SharedListStruct.cs +++ /dev/null @@ -1,121 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; - -namespace Xceed.Wpf.DataGrid -{ - // The idea behind this struct is to share the same "List" instance - // (eg. m_internalList) across many "SharedList" instances - // (note: SharedList is a value type, so the reference is copied on every - // assignation) without having to create and copy of the list every time. - // As long as each SharedList intances shares the same first items, - // each instances can add new items to the list without affecting other instances. - internal struct SharedList - { - public SharedList( int capacity ) - { - m_internalList = new List( capacity ); - m_localCount = 0; - } - - public object this[ int index ] - { - get - { - if( index >= m_localCount ) - throw new ArgumentException( "Provided index is out of range", "index" ); - - return m_internalList[ index ]; - } - } - - public int Count - { - get - { - return m_localCount; - } - } - - public void EnsureCapacity( int capacity ) - { - if( m_internalList.Capacity < capacity ) - { - // Performance optimization. - // To avoid increasing to frequently, at least double the list capacity - m_internalList.Capacity = Math.Max( m_internalList.Capacity * 2, capacity ); - } - } - - public void Add( object item ) - { - this.TrunkExcessiveContent( 1 ); - m_internalList.Add( item ); - m_localCount++; - } - - public void AddRange( object[] e ) - { - this.TrunkExcessiveContent( e.Length ); - m_internalList.AddRange( e ); - m_localCount += e.Length; - } - - public object[] ToArray() - { - object[] newArray = new object[ m_localCount ]; - m_internalList.CopyTo( 0, newArray, 0, m_localCount ); - return newArray; - } - - public void CopyTo( int startIndex, object[] array, int arrayIndex, int length ) - { - if( ( startIndex < 0 ) - || ( length < 0 ) - || ( startIndex + length > m_localCount ) ) - throw new DataGridInternalException( "Specified range is invalid" ); - - m_internalList.CopyTo( startIndex, array, arrayIndex, length ); - } - - private void TrunkExcessiveContent( int newListExtraCapacity ) - { - if( m_localCount < m_internalList.Count ) - { - // This is the scenario that should not happen very often - // where we loose the "same list copy" advantage. If we need - // to add items to a list that already contains others "added" items, - // we need to "branch" the list instance. - var newList = new List( m_localCount + newListExtraCapacity ); - for( int i = 0; i < m_localCount; i++ ) - { - newList[ i ] = m_internalList[ i ]; - } - m_internalList = newList; - } - } - - #region Fields - - private int m_localCount; //0 - private List m_internalList; - - #endregion - - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SortDirectionCycleCollection.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SortDirectionCycleCollection.cs deleted file mode 100644 index 93a86f29..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/SortDirectionCycleCollection.cs +++ /dev/null @@ -1,123 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Collections.Specialized; -using System.ComponentModel; -using Xceed.Wpf.DataGrid.Utils; - -namespace Xceed.Wpf.DataGrid -{ - public class SortDirectionCycleCollection : Collection, INotifyCollectionChanged, INotifyPropertyChanged - { - #region Static Fields - - internal static readonly string CountPropertyName = PropertyHelper.GetPropertyName( ( SortDirectionCycleCollection s ) => s.Count ); - internal static readonly string IndexerName = "Item[]"; - - #endregion - - public SortDirectionCycleCollection() - : base( new List() ) - { - } - - internal SortDirectionCycleCollection( IList list ) - : base( list ) - { - } - - protected override void ClearItems() - { - if( this.Count == 0 ) - return; - - base.ClearItems(); - this.OnPropertyChanged( SortDirectionCycleCollection.CountPropertyName ); - this.OnPropertyChanged( SortDirectionCycleCollection.IndexerName ); - this.OnCollectionChanged( new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Reset ) ); - } - - protected override void InsertItem( int index, SortDirection item ) - { - this.EnsureUnique( item ); - base.InsertItem( index, item ); - this.OnPropertyChanged( SortDirectionCycleCollection.CountPropertyName ); - this.OnPropertyChanged( SortDirectionCycleCollection.IndexerName ); - this.OnCollectionChanged( new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Add, item, index ) ); - } - - protected override void RemoveItem( int index ) - { - var item = base[ index ]; - - base.RemoveItem( index ); - this.OnPropertyChanged( SortDirectionCycleCollection.CountPropertyName ); - this.OnPropertyChanged( SortDirectionCycleCollection.IndexerName ); - this.OnCollectionChanged( new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Remove, item, index ) ); - } - - protected override void SetItem( int index, SortDirection item ) - { - var oldItem = base[ index ]; - if( oldItem == item ) - return; - - this.EnsureUnique( item ); - base.SetItem( index, item ); - this.OnPropertyChanged( SortDirectionCycleCollection.IndexerName ); - this.OnCollectionChanged( new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Replace, item, oldItem, index ) ); - } - - private void EnsureUnique( SortDirection item ) - { - if( this.Contains( item ) ) - throw new ArgumentException( "The SortDirection is already contained in the collection and cannot be added again.", "item" ); - } - - #region INotifyCollectionChanged Members - - public event NotifyCollectionChangedEventHandler CollectionChanged; - - protected virtual void OnCollectionChanged( NotifyCollectionChangedEventArgs e ) - { - var handler = this.CollectionChanged; - if( handler == null ) - return; - - handler.Invoke( this, e ); - } - - #endregion - - #region INotifyPropertyChanged Members - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void OnPropertyChanged( string propertyName ) - { - var handler = this.PropertyChanged; - if( handler == null ) - return; - - handler.Invoke( this, new PropertyChangedEventArgs( propertyName ) ); - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/StaircasePanel.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/StaircasePanel.cs deleted file mode 100644 index 06aa59b6..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/StaircasePanel.cs +++ /dev/null @@ -1,365 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media; -using System.Diagnostics; - -namespace Xceed.Wpf.DataGrid -{ - public class StaircasePanel : Panel - { - #region ConnectionLineAlignment Property - - public static readonly DependencyProperty ConnectionLineAlignmentProperty = - DependencyProperty.Register( - "ConnectionLineAlignment", - typeof( ConnectionLineAlignment ), - typeof( StaircasePanel ), - new FrameworkPropertyMetadata( ConnectionLineAlignment.RightToBottom, - FrameworkPropertyMetadataOptions.AffectsRender ) ); - - public ConnectionLineAlignment ConnectionLineAlignment - { - get - { - return ( ConnectionLineAlignment )this.GetValue( StaircasePanel.ConnectionLineAlignmentProperty ); - } - set - { - this.SetValue( StaircasePanel.ConnectionLineAlignmentProperty, value ); - } - } - - #endregion ConnectionLineAlignment Property - - #region ConnectionLineOffset Property - - public static readonly DependencyProperty ConnectionLineOffsetProperty = - DependencyProperty.Register( - "ConnectionLineOffset", - typeof( double ), - typeof( StaircasePanel ), - new FrameworkPropertyMetadata( 5.0d, FrameworkPropertyMetadataOptions.AffectsRender ) ); - - public double ConnectionLineOffset - { - get - { - return ( double )this.GetValue( StaircasePanel.ConnectionLineOffsetProperty ); - } - set - { - this.SetValue( StaircasePanel.ConnectionLineOffsetProperty, value ); - } - } - - #endregion ConnectionLineOffset Property - - #region StairHeight Property - - public static readonly DependencyProperty StairHeightProperty = - DependencyProperty.Register( - "StairHeight", - typeof( double ), - typeof( StaircasePanel ), - new FrameworkPropertyMetadata( 10.0d, - FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure ) ); - - public double StairHeight - { - get - { - return ( double )this.GetValue( StaircasePanel.StairHeightProperty ); - } - set - { - this.SetValue( StaircasePanel.StairHeightProperty, value ); - } - } - - #endregion StairHeight Property - - #region StairSpacing Property - - public static readonly DependencyProperty StairSpacingProperty = - DependencyProperty.Register( - "StairSpacing", - typeof( double ), - typeof( StaircasePanel ), - new FrameworkPropertyMetadata( 5.0d, - FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure ) ); - - public double StairSpacing - { - get - { - return ( double )this.GetValue( StaircasePanel.StairSpacingProperty ); - } - set - { - this.SetValue( StaircasePanel.StairSpacingProperty, value ); - } - } - - #endregion StairSpacing Property - - #region ConnectionLinePen Property - - public static readonly DependencyProperty ConnectionLinePenProperty = - DependencyProperty.Register( - "ConnectionLinePen", - typeof( Pen ), - typeof( StaircasePanel ), - new FrameworkPropertyMetadata( - new Pen( SystemColors.ControlTextBrush, 2d ), - FrameworkPropertyMetadataOptions.AffectsRender ) ); - - public Pen ConnectionLinePen - { - get - { - return ( Pen )this.GetValue( StaircasePanel.ConnectionLinePenProperty ); - } - set - { - this.SetValue( StaircasePanel.ConnectionLinePenProperty, value ); - } - } - - #endregion ConnectionLinePen Property - - protected override Size MeasureOverride( Size availableSize ) - { - Size infiniteSize = new Size( double.PositiveInfinity, double.PositiveInfinity ); - Size actualRequestedSize = new Size(); - - //for all children of the panel - for( int i = 0; i < this.InternalChildren.Count; i++ ) - { - UIElement item = this.InternalChildren[ i ]; - - //measure the child with no constraints - item.Measure( infiniteSize ); - - //add the desired width of the item to the panel's requested width - actualRequestedSize.Width += item.DesiredSize.Width; - - //if this pass is not for the last item in the collection - if( i < ( this.InternalChildren.Count - 1 ) ) - { - //add the spacing factor as well - actualRequestedSize.Width += this.StairSpacing; - } - - //calculate the remaining - double itemBottom = ( i * this.StairHeight ) + item.DesiredSize.Height; - if( itemBottom > actualRequestedSize.Height ) - { - actualRequestedSize.Height = itemBottom; - } - } - - return actualRequestedSize; - } - - protected override Size ArrangeOverride( Size finalSize ) - { - Point offset = new Point( 0, 0 ); - - Rect itemRect = new Rect( 0, 0, 0, 0 ); - - //for all children of the panel - for( int i = 0; i < this.InternalChildren.Count; i++ ) - { - UIElement item = this.InternalChildren[ i ]; - - itemRect = new Rect( offset, item.DesiredSize ); - - item.Arrange( itemRect ); - - //if not the last item - if( i < ( this.InternalChildren.Count - 1 ) ) - { - //add to the offset, so next item is positionned properly - offset.X += item.DesiredSize.Width + this.StairSpacing; - offset.Y += this.StairHeight; - } - } - - if( double.IsInfinity( finalSize.Width ) == true ) - { - finalSize.Width = itemRect.Right; - } - - if( double.IsInfinity( finalSize.Height ) == true ) - { - finalSize.Height = itemRect.Bottom; - } - - return finalSize; - } - - protected override void OnRender( DrawingContext drawingContext ) - { - if( this.ConnectionLinePen != null ) - { - bool left = false; - bool top = false; - bool middle = false; - - switch( this.ConnectionLineAlignment ) - { - case ConnectionLineAlignment.LeftToBottom: - left = true; - break; - - case ConnectionLineAlignment.RightToTop: - top = true; - break; - - case ConnectionLineAlignment.LeftToTop: - left = true; - top = true; - break; - - case ConnectionLineAlignment.CenterToCenter: - middle = true; - break; - - case ConnectionLineAlignment.RightToBottom: - default: - break; - } - - //cycling with count -1 because we don't want to draw a ligne after last item - for( int i = 0; i < this.InternalChildren.Count - 1; i++ ) - { - UIElement startItem = this.InternalChildren[ i ]; - UIElement endItem = this.InternalChildren[ i + 1 ]; - - Vector startOffset = VisualTreeHelper.GetOffset( startItem ); - Vector endOffset = VisualTreeHelper.GetOffset( endItem ); - - Size startSize = startItem.RenderSize; - Size endSize = endItem.RenderSize; - - double startPointX = 0.0d; - double startPointY = 0.0d; - double endPointX = 0.0d; - double endPointY = 0.0d; - - List myPathSegments = null; - - GuidelineSet guidelineSet = new GuidelineSet(); - drawingContext.PushGuidelineSet( guidelineSet ); - - if( middle == true ) - { - startPointX = startOffset.X + startSize.Width + this.ConnectionLineOffset; - - startPointY = startOffset.Y + ( startSize.Height / 2 ); - - endPointY = endOffset.Y + ( endSize.Height / 2 ); - - endPointX = endOffset.X - this.ConnectionLineOffset; - - double deltaX = ( endPointX - startPointX ); - - guidelineSet.GuidelinesX.Add( startPointX ); - guidelineSet.GuidelinesX.Add( startPointX + ( deltaX / 2 ) + 0.5d ); - guidelineSet.GuidelinesX.Add( startPointX + deltaX ); - guidelineSet.GuidelinesY.Add( startPointY ); - guidelineSet.GuidelinesY.Add( endPointY ); - - myPathSegments = new List( 4 ); //we know there are going be only 4 segments - myPathSegments.Add( new LineSegment( new Point( startPointX, startPointY ), true ) ); - myPathSegments.Add( new LineSegment( new Point( startPointX + ( deltaX / 2 ), startPointY ), true ) ); - myPathSegments.Add( new LineSegment( new Point( startPointX + ( deltaX / 2 ), endPointY ), true ) ); - myPathSegments.Add( new LineSegment( new Point( startPointX + deltaX, endPointY ), true ) ); - - } - else - { - if( left == true ) - { - startPointX = startOffset.X + this.ConnectionLineOffset; - } - else - { - startPointX = startOffset.X + startSize.Width - this.ConnectionLineOffset; - } - - startPointY = startOffset.Y + startSize.Height; - - if( top == true ) - { - endPointY = endOffset.Y + this.ConnectionLineOffset; - } - else - { - endPointY = endOffset.Y + endSize.Height - this.ConnectionLineOffset; - } - - endPointX = endOffset.X; - - guidelineSet.GuidelinesX.Add( startPointX ); - guidelineSet.GuidelinesX.Add( endPointX ); - guidelineSet.GuidelinesY.Add( startPointY ); - guidelineSet.GuidelinesY.Add( endPointY ); - - myPathSegments = new List( 2 ); //we know there are going be only 2 segments - myPathSegments.Add( new LineSegment( new Point( startPointX, endPointY ), true ) ); - myPathSegments.Add( new LineSegment( new Point( endPointX, endPointY ), true ) ); - } - - PathFigure myPathFigure = new PathFigure( new Point( startPointX, startPointY ), myPathSegments, false ); - - PathGeometry myPathGeometry = new PathGeometry(); - myPathGeometry.Figures.Add( myPathFigure ); - - drawingContext.DrawGeometry( null, this.ConnectionLinePen, myPathGeometry ); - - // pop the context to remove the GuidelineSet - drawingContext.Pop(); - } - } - - base.OnRender( drawingContext ); - } - - protected override void OnChildDesiredSizeChanged( UIElement child ) - { - base.OnChildDesiredSizeChanged( child ); - - // OnRender is not automatically called when a child's size changes. - // We have to do it manually if we want the ConnectionLines to adapt. - this.InvalidateVisual(); - } - - protected override void OnVisualChildrenChanged( DependencyObject visualAdded, DependencyObject visualRemoved ) - { - base.OnVisualChildrenChanged( visualAdded, visualRemoved ); - - // OnRender is not automatically called when a new child is added or removed from - // the Panel. We have to do it manually if we want to redraw the ConnectionLines. - this.InvalidateVisual(); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/StringFormatDataTemplate.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/StringFormatDataTemplate.cs deleted file mode 100644 index 7f93410b..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/StringFormatDataTemplate.cs +++ /dev/null @@ -1,282 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; -using System.Globalization; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class StringFormatDataTemplate : DataTemplate - { - #region Static Fields - - private static readonly List s_templates = new List( 0 ); - private static readonly StringFormatConverter s_converter = new StringFormatConverter(); - private static readonly StringFormatComparer s_comparer = new StringFormatComparer(); - - #endregion - - #region Constructor - - private StringFormatDataTemplate( DataTemplate contentTemplate ) - { - m_contentTemplate = contentTemplate; - } - - #endregion - - internal static StringFormatDataTemplate Get( DataTemplate contentTemplate, string format, CultureInfo culture ) - { - if( string.IsNullOrEmpty( format ) ) - throw new ArgumentException( "The format must be non empty.", "format" ); - - lock( ( ( ICollection )s_templates ).SyncRoot ) - { - int insertionIndex = 0; - bool cleanUp = false; - StringFormatDataTemplate template = null; - - if( s_templates.Count > 0 ) - { - var lookup = new Entry( format, culture ); - insertionIndex = s_templates.BinarySearch( lookup, s_comparer ); - - if( insertionIndex >= 0 ) - { - for( int i = insertionIndex; i < s_templates.Count; i++ ) - { - var item = s_templates[ i ]; - if( s_comparer.Compare( lookup, item ) != 0 ) - break; - - var target = item.Template; - if( target == null ) - { - cleanUp = true; - } - else - { - Debug.Assert( object.Equals( item.Format, format ) && object.Equals( item.Culture, culture ) ); - - if( target.m_contentTemplate == contentTemplate ) - { - template = target; - break; - } - } - } - } - else - { - insertionIndex = ~insertionIndex; - cleanUp = ( insertionIndex < s_templates.Count ) && ( s_templates[ insertionIndex ].Template == null ); - } - } - - if( template == null ) - { - template = StringFormatDataTemplate.Create( contentTemplate, format, culture ); - s_templates.Insert( insertionIndex, new Entry( template, format, culture ) ); - } - - if( cleanUp ) - { - StringFormatDataTemplate.CleanUpCache(); - } - - Debug.Assert( template != null ); - - return template; - } - } - - private static StringFormatDataTemplate Create( DataTemplate contentTemplate, string format, CultureInfo culture ) - { - // We are using a converter to format the target value instead of using the - // ContentPresenter.ContentStringFormat or Binding.StringFormat property because - // it is not applied if a ContentPresenter.ContentTemplate is given or if the binding is - // not targeting a string property. - var template = new StringFormatDataTemplate( contentTemplate ); - var control = new FrameworkElementFactory( typeof( ContentPresenter ) ); - - var binding = new Binding(); - binding.Path = new PropertyPath( FrameworkElement.DataContextProperty ); - binding.RelativeSource = RelativeSource.TemplatedParent; - binding.Converter = s_converter; - binding.ConverterParameter = format; - binding.ConverterCulture = culture; - - control.SetValue( ContentPresenter.ContentTemplateProperty, contentTemplate ); - control.SetValue( ContentPresenter.ContentProperty, binding ); - - template.VisualTree = control; - template.Seal(); - - return template; - } - - private static void CleanUpCache() - { - for( int i = s_templates.Count - 1; i >= 0; i-- ) - { - if( s_templates[ i ].Template == null ) - { - s_templates.RemoveAt( i ); - } - } - - s_templates.TrimExcess(); - } - - #region Private Fields - - private readonly DataTemplate m_contentTemplate; - - #endregion - - #region StringFormatConverter Private Class - - private sealed class StringFormatConverter : IValueConverter - { - public object Convert( object value, Type targetType, object parameter, CultureInfo culture ) - { - var format = parameter as string; - if( string.IsNullOrEmpty( format ) ) - return value; - - return string.Format( culture, format, value ); - } - - public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture ) - { - throw new NotSupportedException(); - } - } - - #endregion - - #region StringFormatComparer Private Class - - private sealed class StringFormatComparer : IComparer - { - public int Compare( Entry x, Entry y ) - { - if( object.ReferenceEquals( x, y ) ) - return 0; - - if( object.ReferenceEquals( x, null ) ) - return -1; - - if( object.ReferenceEquals( y, null ) ) - return 1; - - var xf = x.Format; - var yf = y.Format; - - if( !string.Equals( xf, yf, StringComparison.InvariantCulture ) ) - { - if( xf == null ) - return -1; - - if( yf == null ) - return 1; - - return string.Compare( xf, yf, StringComparison.InvariantCulture ); - } - - var xc = x.Culture; - var yc = y.Culture; - - if( !object.Equals( xc, yc ) ) - { - if( xc == null ) - return -1; - - if( yc == null ) - return 1; - - return xc.LCID.CompareTo( yc.LCID ); - } - - return 0; - } - } - - #endregion - - #region Entry Private Class - - private class Entry - { - internal Entry( string format, CultureInfo culture ) - : this( null, format, culture ) - { - } - - internal Entry( StringFormatDataTemplate template, string format, CultureInfo culture ) - { - Debug.Assert( format != null ); - - if( template != null ) - { - m_template = new WeakReference( template ); - } - - m_format = format; - m_culture = culture; - } - - internal StringFormatDataTemplate Template - { - get - { - if( m_template == null ) - return null; - - return ( StringFormatDataTemplate )m_template.Target; - } - } - - internal string Format - { - get - { - return m_format; - } - } - - internal CultureInfo Culture - { - get - { - return m_culture; - } - } - - private readonly WeakReference m_template; - private readonly string m_format; - private readonly CultureInfo m_culture; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/TextInputActivationGesture.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/TextInputActivationGesture.cs deleted file mode 100644 index 8090dc2b..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/TextInputActivationGesture.cs +++ /dev/null @@ -1,32 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Windows.Input; -using System.Windows; - -namespace Xceed.Wpf.DataGrid -{ - public sealed class TextInputActivationGesture : ActivationGesture - { - protected override Freezable CreateInstanceCore() - { - return new TextInputActivationGesture(); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ToggleColumnSortCommand.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ToggleColumnSortCommand.cs deleted file mode 100644 index ffa6abeb..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ToggleColumnSortCommand.cs +++ /dev/null @@ -1,327 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; -using System.Diagnostics; - -namespace Xceed.Wpf.DataGrid -{ - internal abstract class ToggleColumnSortCommand : ColumnSortCommand - { - #region Constructor - - protected ToggleColumnSortCommand() - { - } - - #endregion - - #region Properties - - #region CanSort Protected Property - - protected abstract bool CanSort - { - get; - } - - #endregion - - #region Columns Protected Property - - protected abstract ColumnCollection Columns - { - get; - } - - #endregion - - #region DataGridContext Protected Property - - protected abstract DataGridContext DataGridContext - { - get; - } - - #endregion - - #region MaxSortLevels Protected Property - - protected abstract int MaxSortLevels - { - get; - } - - #endregion - - #region SortDescriptions Protected Property - - protected abstract SortDescriptionCollection SortDescriptions - { - get; - } - - #endregion - - #endregion - - #region Methods - - public bool CanExecute( ColumnBase column, bool resetSort ) - { - return this.CanExecuteCore( column, resetSort ); - } - - public void Execute( ColumnBase column, bool resetSort ) - { - if( !this.CanExecute( column, resetSort ) ) - return; - - var currentSortDirection = column.SortDirection; - var nextSortDirection = currentSortDirection; - var pattern = column.SortDirectionCycle; - - if( ( pattern != null ) && ( pattern.Count > 0 ) ) - { - var index = pattern.IndexOf( currentSortDirection ); - - nextSortDirection = ( ( index < 0 ) || ( index == pattern.Count - 1 ) ) - ? pattern[ 0 ] - : pattern[ index + 1 ]; - } - - var dataGridContext = this.DataGridContext; - if( dataGridContext == null ) - return; - - var eventArgs = new ColumnSortDirectionChangingEventArgs( DataGridControl.SortDirectionChangingEvent, column, dataGridContext, currentSortDirection, nextSortDirection ); - dataGridContext.DataGridControl.RaiseSortDirectionChanging( eventArgs ); - - nextSortDirection = eventArgs.NextSortDirection; - - if( currentSortDirection == nextSortDirection ) - return; - - if( currentSortDirection == SortDirection.None ) - { - var maxSortCount = this.MaxSortLevels; - - // Cannot insert sort description since it would go beyond the max sort description count, but only if Shift key is pressed - if( !resetSort && ( maxSortCount >= 0 ) && ( this.SortDescriptions.Count >= maxSortCount ) ) - return; - - //When Shift key is not pressed, simply evaluate if one sort description can be added, since all others will be cleared. - if( resetSort && maxSortCount == 0 ) - return; - } - - using( this.SetQueueBringIntoViewRestrictions( AutoScrollCurrentItemSourceTriggers.CollectionViewCurrentItemChanged ) ) - { - this.ExecuteCore( column, nextSortDirection, resetSort ); - } - } - - protected virtual bool CanExecuteCore( ColumnBase column, bool resetSort ) - { - if( ( column == null ) || string.IsNullOrEmpty( column.FieldName ) ) - return false; - - if( !this.CanSort || !this.Columns.Contains( column ) ) - return false; - - return true; - } - - protected virtual void ExecuteCore( ColumnBase column, SortDirection direction, bool resetSort ) - { - if( column == null ) - return; - - if( !this.ToggleColumnSort( column, direction, resetSort ) ) - return; - - this.UpdateColumnSort(); - } - - protected virtual SortDescriptionsSyncContext GetSortDescriptionsSyncContext() - { - return null; - } - - protected virtual void ValidateSynchronizationContext( SynchronizationContext synchronizationContext ) - { - } - - protected virtual IDisposable DeferResortHelperItemsSourceCollection() - { - return null; - } - - protected virtual bool TryDeferResortSourceDetailConfiguration( out IDisposable defer ) - { - defer = null; - return false; - } - - protected virtual IDisposable SetQueueBringIntoViewRestrictions( AutoScrollCurrentItemSourceTriggers triggers ) - { - return null; - } - - protected virtual void ValidateToggleColumnSort() - { - } - - protected virtual void DeferRestoreStateOnLevel( Disposer disposer ) - { - } - - protected virtual void UpdateColumnSort() - { - var dataGridContext = this.DataGridContext; - - if( this.DataGridContext != null ) - { - var command = dataGridContext.UpdateColumnSortCommand; - if( command.CanExecute() ) - { - command.Execute(); - } - } - } - - protected override bool CanExecuteImpl( object parameter ) - { - return this.CanExecute( parameter as ColumnBase, true ); - } - - protected override void ExecuteImpl( object parameter ) - { - this.Execute( parameter as ColumnBase, true ); - } - - protected static void DeferRestoreStateOnLevel( Disposer disposer, DataGridContext dataGridContext ) - { - ToggleColumnSortCommand.ThrowIfNull( disposer, "disposer" ); - ToggleColumnSortCommand.ThrowIfNull( dataGridContext, "dataGridContext" ); - - var parentDataGridContext = dataGridContext.ParentDataGridContext; - - // Defer the RestoreState of each DataGridContext of the same level - // to ensure all the DataGridContext will be correctly restored once - // all of them are completely resorted - if( parentDataGridContext != null ) - { - foreach( var childContext in parentDataGridContext.GetChildContexts() ) - { - disposer.Add( childContext.DeferRestoreState(), DisposableType.DeferRestoreState ); - } - } - } - - #endregion - - #region Private Methods - - private static ListSortDirection Convert( SortDirection value ) - { - if( value == SortDirection.None ) - throw new ArgumentException( "Cannot convert the value to ListSortDirection.", "value" ); - - if( value == SortDirection.Descending ) - return ListSortDirection.Descending; - - return ListSortDirection.Ascending; - } - - private bool ToggleColumnSort( ColumnBase column, SortDirection direction, bool resetSort ) - { - this.ValidateToggleColumnSort(); - - using( var synchronizationContext = this.StartSynchronizing( this.GetSortDescriptionsSyncContext() ) ) - { - this.ValidateSynchronizationContext( synchronizationContext ); - - using( var disposer = new Disposer() ) - { - this.DeferRestoreStateOnLevel( disposer ); - - // This will ensure that all DataGridCollectionViews mapped to the SortDescriptions collection will only refresh their sorting once! - var sortDescriptions = this.SortDescriptions; - disposer.Add( this.DeferResortHelper( sortDescriptions ), DisposableType.DeferResort ); - - var columnName = column.FieldName; - int insertionIndex; - - if( ( resetSort ) && - ( ( column.SortIndex == -1 ) || ( sortDescriptions.Count > 1 ) ) ) - { - insertionIndex = 0; - - if( sortDescriptions.Count > 0 ) - { - sortDescriptions.Clear(); - } - - Debug.Assert( sortDescriptions.Count == 0 ); - } - else - { - for( insertionIndex = 0; insertionIndex < sortDescriptions.Count; insertionIndex++ ) - { - if( sortDescriptions[ insertionIndex ].PropertyName == columnName ) - break; - } - } - - if( insertionIndex < sortDescriptions.Count ) - { - if( direction == SortDirection.None ) - { - sortDescriptions.RemoveAt( insertionIndex ); - } - else - { - sortDescriptions[ insertionIndex ] = new SortDescription( columnName, ToggleColumnSortCommand.Convert( direction ) ); - } - } - else if( direction != SortDirection.None ) - { - sortDescriptions.Add( new SortDescription( columnName, ToggleColumnSortCommand.Convert( direction ) ) ); - } - } - } - - return true; - } - - private IDisposable DeferResortHelper( SortDescriptionCollection sortDescriptions ) - { - IDisposable defer; - - if( this.TryDeferResort( sortDescriptions, out defer ) ) - return defer; - - if( this.TryDeferResortSourceDetailConfiguration( out defer ) ) - return defer; - - return this.DeferResortHelperItemsSourceCollection(); - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/UnboundColumn.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/UnboundColumn.cs deleted file mode 100644 index 5fe08b0e..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/UnboundColumn.cs +++ /dev/null @@ -1,298 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.ComponentModel; -using System.Windows; -using System.Windows.Controls; -using Xceed.Wpf.DataGrid.ValidationRules; -using System.Collections.ObjectModel; - -namespace Xceed.Wpf.DataGrid -{ - public class UnboundColumn : ColumnBase - { - public UnboundColumn() - { - } - - public UnboundColumn( string fieldName, object title ) - : base( fieldName, title ) - { - } - - #region AllowSort Property - - [EditorBrowsable( EditorBrowsableState.Never )] - [Browsable( false )] - public override bool AllowSort - { - get - { - return base.AllowSort; - } - set - { - base.AllowSort = value; - } - } - - #endregion AllowSort Property - - #region AllowGroup Property - - [EditorBrowsable( EditorBrowsableState.Never )] - [Browsable( false )] - public override bool AllowGroup - { - get - { - return base.AllowGroup; - } - set - { - base.AllowGroup = value; - } - } - - #endregion AllowGroup Property - - #region GroupValueStringFormat Property - - [EditorBrowsable( EditorBrowsableState.Never )] - [Browsable( false )] - public new string GroupValueStringFormat - { - get - { - return base.GroupValueStringFormat; - } - set - { - base.GroupValueStringFormat = value; - } - } - - #endregion GroupValueStringFormat Property - - #region GroupValueTemplate Property - - [EditorBrowsable( EditorBrowsableState.Never )] - [Browsable( false )] - public new DataTemplate GroupValueTemplate - { - get - { - return base.GroupValueTemplate; - } - set - { - base.GroupValueTemplate = value; - } - } - - #endregion GroupValueTemplate Property - - #region GroupValueTemplateSelector Property - - [EditorBrowsable( EditorBrowsableState.Never )] - [Browsable( false )] - public new DataTemplateSelector GroupValueTemplateSelector - { - get - { - return base.GroupValueTemplateSelector; - } - set - { - base.GroupValueTemplateSelector = value; - } - } - - #endregion GroupValueTemplateSelector Property - - #region CellEditor Property - - [EditorBrowsable( EditorBrowsableState.Never )] - [Browsable( false )] - public new CellEditor CellEditor - { - get - { - return base.CellEditor; - } - set - { - base.CellEditor = value; - } - } - - #endregion CellEditor Property - - #region CellEditorDisplayConditions Property - - [EditorBrowsable( EditorBrowsableState.Never )] - [Browsable( false )] - public new CellEditorDisplayConditions CellEditorDisplayConditions - { - get - { - return base.CellEditorDisplayConditions; - } - set - { - base.CellEditorDisplayConditions = value; - } - } - - #endregion CellEditorDisplayConditions Property - - #region CellValidationRules Property - - [EditorBrowsable( EditorBrowsableState.Never )] - [Browsable( false )] - public new Collection CellValidationRules - { - get - { - return base.CellValidationRules; - } - } - - #endregion CellValidationRules Property - - #region CellErrorStyle Property - - [EditorBrowsable( EditorBrowsableState.Never )] - [Browsable( false )] - public new Style CellErrorStyle - { - get - { - return base.CellErrorStyle; - } - set - { - base.CellErrorStyle = value; - } - } - - #endregion CellErrorStyle Property - - #region HasValidationError Property - - [EditorBrowsable( EditorBrowsableState.Never )] - [Browsable( false )] - public new bool HasValidationError - { - get - { - return base.HasValidationError; - } - } - - #endregion HasValidationError Property - - #region SortDirection Property - - [EditorBrowsable( EditorBrowsableState.Never )] - [Browsable( false )] - public new SortDirection SortDirection - { - get - { - return base.SortDirection; - } - } - - #endregion SortDirection Property - - #region SortIndex Read-Only Property - - [EditorBrowsable( EditorBrowsableState.Never )] - [Browsable( false )] - public new int SortIndex - { - get - { - return base.SortIndex; - } - } - - #endregion SortIndex Read-Only Property - - #region GroupDescription Property - - [EditorBrowsable( EditorBrowsableState.Never )] - [Browsable( false )] - public new GroupDescription GroupDescription - { - get - { - return base.GroupDescription; - } - set - { - base.GroupDescription = value; - } - } - - #endregion GroupDescription Property - - #region GroupConfiguration Property - - [EditorBrowsable( EditorBrowsableState.Never )] - [Browsable( false )] - public new GroupConfiguration GroupConfiguration - { - get - { - return base.GroupConfiguration; - } - set - { - base.GroupConfiguration = value; - } - } - - #endregion GroupConfiguration Property - - #region ReadOnly Property - - public static new readonly DependencyProperty ReadOnlyProperty = DependencyProperty.Register( - "ReadOnly", typeof( bool ), typeof( UnboundColumn ), new FrameworkPropertyMetadata( true ) ); - - public override bool ReadOnly - { - get - { - return ( bool )this.GetValue( UnboundColumn.ReadOnlyProperty ); - } - set - { - if( value == this.ReadOnly ) - return; - - throw new InvalidOperationException( "An attempt was made to set the ReadOnly property of a UnboundColumn, which cannot be edited, to false." ); - } - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/UpdateColumnSortCommand.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/UpdateColumnSortCommand.cs deleted file mode 100644 index 7e2e5799..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/UpdateColumnSortCommand.cs +++ /dev/null @@ -1,204 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; -using System.Threading; - -namespace Xceed.Wpf.DataGrid -{ - internal abstract class UpdateColumnSortCommand : ColumnSortCommand - { - #region SortDescriptionsSyncContext Protected Property - - protected abstract SortDescriptionsSyncContext SortDescriptionsSyncContext - { - get; - } - - #endregion - - public bool CanExecute() - { - return this.CanExecuteCore(); - } - - public void Execute() - { - if( !this.CanExecute() ) - return; - - this.ExecuteCore(); - } - - protected abstract bool CanExecuteCore(); - protected abstract void ExecuteCore(); - - protected override bool CanExecuteImpl( object parameter ) - { - return this.CanExecuteCore(); - } - - protected override void ExecuteImpl( object parameter ) - { - this.Execute(); - } - - protected void SynchronizeColumnSort( - SynchronizationContext synchronizationContext, - SortDescriptionCollection sortDescriptions, - ColumnCollection columns ) - { - ColumnSortCommand.ThrowIfNull( synchronizationContext, "synchronizationContext" ); - ColumnSortCommand.ThrowIfNull( sortDescriptions, "sortDescriptions" ); - ColumnSortCommand.ThrowIfNull( columns, "columns" ); - - if( !synchronizationContext.Own || !columns.Any() ) - return; - - this.SetResortCallback( sortDescriptions, columns ); - - int count = sortDescriptions.Count; - Dictionary sortOrder = new Dictionary( count ); - - for( int i = 0; i < count; i++ ) - { - var sortDescription = sortDescriptions[ i ]; - string propertyName = sortDescription.PropertyName; - - if( sortOrder.ContainsKey( propertyName ) ) - continue; - - sortOrder.Add( propertyName, new ColumnSortInfo( i, sortDescription.Direction ) ); - } - - foreach( var column in columns ) - { - ColumnSortInfo entry; - - if( sortOrder.TryGetValue( column.FieldName, out entry ) ) - { - column.SetSortIndex( entry.Index ); - column.SetSortDirection( entry.Direction ); - } - else - { - column.SetSortIndex( -1 ); - column.SetSortDirection( SortDirection.None ); - } - } - } - - private void SetResortCallback( SortDescriptionCollection sortDescriptions, ColumnCollection columns ) - { - var collection = sortDescriptions as DataGridSortDescriptionCollection; - if( ( m_resortCallback != null ) || ( collection == null ) || !collection.IsResortDefered ) - return; - - m_resortCallback = new ResortCallback( this, sortDescriptions, columns ); - collection.AddResortNotification( m_resortCallback ); - } - - private void OnResortCallback( SortDescriptionCollection sortDescriptions, ColumnCollection columns ) - { - using( var synchronizationContext = this.StartSynchronizing( this.SortDescriptionsSyncContext ) ) - { - this.SynchronizeColumnSort( synchronizationContext, sortDescriptions, columns ); - } - } - - #region Private Fields - - private IDisposable m_resortCallback; //null - - #endregion - - #region ColumnSortInfo Private Nested Type - - private struct ColumnSortInfo - { - public ColumnSortInfo( int index, ListSortDirection direction ) - { - this.Index = index; - this.Direction = ColumnSortInfo.Convert( direction ); - } - - private static SortDirection Convert( ListSortDirection value ) - { - if( value == ListSortDirection.Descending ) - return SortDirection.Descending; - - return SortDirection.Ascending; - } - - public readonly int Index; - public readonly SortDirection Direction; - } - - #endregion - - #region ResortCallback Private Class - - private sealed class ResortCallback : IDisposable - { - internal ResortCallback( - UpdateColumnSortCommand owner, - SortDescriptionCollection sortDescriptions, - ColumnCollection columns ) - { - if( owner == null ) - throw new ArgumentNullException( "owner" ); - - m_owner = new WeakReference( owner ); - m_sortDescriptions = sortDescriptions; - m_columns = columns; - } - - void IDisposable.Dispose() - { - this.Dispose( true ); - GC.SuppressFinalize( this ); - } - - private void Dispose( bool disposing ) - { - if( !disposing ) - return; - - var ownerRef = Interlocked.Exchange( ref m_owner, null ); - if( ownerRef == null ) - return; - - var owner = ( UpdateColumnSortCommand )ownerRef.Target; - if( owner != null ) - { - owner.OnResortCallback( m_sortDescriptions, m_columns ); - } - - m_sortDescriptions = null; - m_columns = null; - } - - private WeakReference m_owner; - private SortDescriptionCollection m_sortDescriptions; - private ColumnCollection m_columns; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/ArrayHelper.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/ArrayHelper.cs deleted file mode 100644 index 0a05aa88..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/ArrayHelper.cs +++ /dev/null @@ -1,24 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - - -namespace Xceed.Utils.Collections -{ - internal static class ArrayHelper - { - internal static readonly int[] Sizes = new int[] { 11, 17, 37, 67, 131, 257, 521, 1031, 2053, 4099, 8209, 16411, 32771, 65537, 131101, 262147, 524309, 1048583, 2097169, 4194319, 8388617, 16777259, 33554467, 67108879, 134217757, 268435459, 536870923, 1073741827, int.MaxValue }; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/DoubleFenwickTree.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/DoubleFenwickTree.cs deleted file mode 100644 index 91031212..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/DoubleFenwickTree.cs +++ /dev/null @@ -1,41 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - - -namespace Xceed.Utils.Collections -{ - internal sealed class DoubleFenwickTree : FenwickTree - { - #region Constructor - - public DoubleFenwickTree( int capacity ) - : base( capacity ) - { - } - - #endregion - - protected override double Add( double x, double y ) - { - return x + y; - } - - protected override double Substract( double x, double y ) - { - return x - y; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/EnumerableWrapper.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/EnumerableWrapper.cs deleted file mode 100644 index 81e2f2e7..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/EnumerableWrapper.cs +++ /dev/null @@ -1,111 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Collections; - -namespace Xceed.Utils.Collections -{ - internal class EnumerableWrapper : IEnumerable where T : class - { - public EnumerableWrapper( IEnumerable collection ) - { - if( collection == null ) - throw new ArgumentNullException( "collection" ); - - m_collection = collection; - } - - #region IEnumerable Members - - public IEnumerator GetEnumerator() - { - return new EnumeratorWrapper( m_collection.GetEnumerator() ); - } - - #endregion - - #region IEnumerable Members - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return m_collection.GetEnumerator(); - } - - #endregion - - private IEnumerable m_collection; - - private class EnumeratorWrapper : IEnumerator where U : class - { - public EnumeratorWrapper( IEnumerator enumerator ) - { - m_wrappedEnumerator = enumerator; - } - - #region IEnumerator Members - - public U Current - { - get - { - return m_wrappedEnumerator.Current as U; - } - } - - #endregion - - #region IDisposable Members - - public void Dispose() - { - IDisposable disposable = m_wrappedEnumerator as IDisposable; - if(disposable != null) - { - disposable.Dispose(); - } - } - - #endregion - - #region IEnumerator Members - - object System.Collections.IEnumerator.Current - { - get - { - return m_wrappedEnumerator.Current; - } - } - - public bool MoveNext() - { - return m_wrappedEnumerator.MoveNext(); - } - - public void Reset() - { - m_wrappedEnumerator.Reset(); - } - - #endregion - - IEnumerator m_wrappedEnumerator; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/FenwickTree.Generic.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/FenwickTree.Generic.cs deleted file mode 100644 index 6f75e22a..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/FenwickTree.Generic.cs +++ /dev/null @@ -1,134 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Utils.Collections -{ - internal abstract class FenwickTree - { - #region Constructor - - protected FenwickTree( int capacity ) - { - if( capacity < 0 ) - throw new ArgumentException( "The capacity must be greater than or equal to zero.", "capacity" ); - - if( capacity > 0 ) - { - m_collection = new T[ capacity + 1 ]; - } - } - - #endregion - - #region Count Property - - public int Count - { - get - { - if( m_collection != null ) - return m_collection.Length - 1; - - return 0; - } - } - - #endregion - - #region [] Property - - public T this[ int index ] - { - get - { - return this.GetRunningSum( index, index ); - } - set - { - var current = this[ index ]; - if( object.Equals( current, value ) ) - return; - - var diff = this.Substract( value, current ); - var x = FenwickTree.ConvertIndex( index ); - - while( x < m_collection.Length ) - { - m_collection[ x ] = this.Add( m_collection[ x ], diff ); - x += FenwickTree.FindLastDigit( x ); - } - } - } - - #endregion - - public T GetRunningSum( int index ) - { - return this.GetRunningSum( 0, index ); - } - - public T GetRunningSum( int startIndex, int endIndex ) - { - if( ( startIndex < 0 ) || ( startIndex >= this.Count ) ) - throw new ArgumentOutOfRangeException( "startIndex", startIndex, "The index must be greater or equal to zero and lesser than the collection Count." ); - - if( ( endIndex < 0 ) || ( endIndex >= this.Count ) ) - throw new ArgumentOutOfRangeException( "endIndex", endIndex, "The index must be greater or equal to zero and lesser than the collection Count." ); - - if( startIndex > endIndex ) - throw new ArgumentException( "The start index must be lesser than or equal to the end index.", "startIndex" ); - - var x = FenwickTree.ConvertIndex( endIndex ); - var y = FenwickTree.ConvertIndex( startIndex - 1 ); - var sum = default( T ); - - while( x > y ) - { - sum = this.Add( sum, m_collection[ x ] ); - x -= FenwickTree.FindLastDigit( x ); - } - - while( y > x ) - { - sum = this.Substract( sum, m_collection[ y ] ); - y -= FenwickTree.FindLastDigit( y ); - } - - return sum; - } - - protected abstract T Add( T x, T y ); - protected abstract T Substract( T x, T y ); - - private static int ConvertIndex( int value ) - { - return value + 1; - } - - private static int FindLastDigit( int value ) - { - return ( value & -value ); - } - - #region Private Fields - - private T[] m_collection; //null - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/IBinaryTree.Generic.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/IBinaryTree.Generic.cs deleted file mode 100644 index 25c8c027..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/IBinaryTree.Generic.cs +++ /dev/null @@ -1,44 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Collections; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.ComponentModel; - -namespace Xceed.Utils.Collections -{ - internal interface IBinaryTree : INotifyCollectionChanged, INotifyPropertyChanged, IEnumerable, IEnumerable - { - IBinaryTreeNode Root - { - get; - } - - IBinaryTreeNode Find( T value ); - - IBinaryTreeNode Insert( T value ); - IBinaryTreeNode InsertBefore( T value, IBinaryTreeNode node ); - IBinaryTreeNode InsertAfter( T value, IBinaryTreeNode node ); - - void Remove( T value ); - void Remove( IBinaryTreeNode node ); - - void Clear(); - - IEnumerable GetItems( bool reverse ); - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/IBinaryTreeNode.Generic.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/IBinaryTreeNode.Generic.cs deleted file mode 100644 index 3840a304..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/IBinaryTreeNode.Generic.cs +++ /dev/null @@ -1,52 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -namespace Xceed.Utils.Collections -{ - internal interface IBinaryTreeNode - { - T Value - { - get; - } - - IBinaryTree Tree - { - get; - } - - IBinaryTreeNode Parent - { - get; - } - - IBinaryTreeNode Left - { - get; - } - - IBinaryTreeNode Right - { - get; - } - - IBinaryTreeNode GetPrevious(); - IBinaryTreeNode GetNext(); - - IBinaryTreeNode GetLeftmost(); - IBinaryTreeNode GetRightmost(); - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/IListExtensions.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/IListExtensions.cs deleted file mode 100644 index 4c2de480..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/IListExtensions.cs +++ /dev/null @@ -1,121 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Xceed.Utils.Collections -{ - internal static class IListExtensions - { - internal static void Diff( - this IList source, - IList destination, - ICollection itemsAdded, - ICollection itemsRemoved, - ICollection itemsMoved ) - { - if( source == null ) - throw new ArgumentNullException( "source" ); - - if( destination == null ) - throw new ArgumentNullException( "destination" ); - - // There is nothing to do since the caller is not interested by the result. - if( ( itemsAdded == null ) && ( itemsRemoved == null ) && ( itemsMoved == null ) ) - return; - - IListExtensions.Diff( new IListWrapper( source ), new IListWrapper( destination ), itemsAdded, itemsRemoved, itemsMoved ); - } - - internal static void Diff( - this IList source, - IList destination, - ICollection itemsAdded, - ICollection itemsRemoved, - ICollection itemsMoved ) - { - if( source == null ) - throw new ArgumentNullException( "source" ); - - if( destination == null ) - throw new ArgumentNullException( "destination" ); - - // There is nothing to do since the caller is not interested by the result. - if( ( itemsAdded == null ) && ( itemsRemoved == null ) && ( itemsMoved == null ) ) - return; - - var sourceCount = source.Count; - var sourcePositions = new Dictionary( sourceCount ); - var sequence = new List( System.Math.Min( sourceCount, destination.Count ) ); - var isAlive = new BitArray( sourceCount, false ); - var hasNotMoved = default( BitArray ); - - for( var i = 0; i < sourceCount; i++ ) - { - sourcePositions.Add( source[ i ], i ); - } - - foreach( var item in destination ) - { - int index; - - if( sourcePositions.TryGetValue( item, out index ) ) - { - isAlive[ index ] = true; - sequence.Add( index ); - } - else if( itemsAdded != null ) - { - itemsAdded.Add( item ); - } - } - - // We may omit this part of the algorithm if the caller is not interested by the items that have moved. - if( itemsMoved != null ) - { - hasNotMoved = new BitArray( sourceCount, false ); - - // The subsequence contains the position of the item that are in the destination collection and that have not moved. - foreach( var index in LongestIncreasingSubsequence.Find( sequence ) ) - { - hasNotMoved[ index ] = true; - } - } - - // We may omit this part of the algorithm if the caller is not interested by the items that have moved or were removed. - if( ( itemsRemoved != null ) || ( itemsMoved != null ) ) - { - for( var i = 0; i < sourceCount; i++ ) - { - if( isAlive[ i ] ) - { - // We check if the move collection is not null first because the bit array is null when the move collection is null. - if( ( itemsMoved != null ) && !hasNotMoved[ i ] ) - { - itemsMoved.Add( source[ i ] ); - } - } - else if( itemsRemoved != null ) - { - itemsRemoved.Add( source[ i ] ); - } - } - } - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/IListWrapper.Generic.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/IListWrapper.Generic.cs deleted file mode 100644 index 302813d5..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/IListWrapper.Generic.cs +++ /dev/null @@ -1,136 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; - -namespace Xceed.Utils.Collections -{ - internal sealed class IListWrapper : IList - { - internal IListWrapper( IList source ) - { - if( source == null ) - throw new ArgumentNullException( "source" ); - - m_source = source; - } - - #region IList<> Members - - public T this[ int index ] - { - get - { - return ( T )m_source[ index ]; - } - set - { - m_source[ index ] = value; - } - } - - public int IndexOf( T item ) - { - return m_source.IndexOf( item ); - } - - public void Insert( int index, T item ) - { - m_source.Insert( index, item ); - } - - public void RemoveAt( int index ) - { - m_source.RemoveAt( index ); - } - - #endregion - - #region ICollection<> Members - - public int Count - { - get - { - return m_source.Count; - } - } - - bool ICollection.IsReadOnly - { - get - { - return false; - } - } - - public void Add( T item ) - { - m_source.Add( item ); - } - - public void Clear() - { - m_source.Clear(); - } - - public bool Contains( T item ) - { - return m_source.Contains( item ); - } - - public void CopyTo( T[] array, int index ) - { - m_source.CopyTo( array, index ); - } - - public bool Remove( T item ) - { - var index = m_source.IndexOf( item ); - if( index < 0 ) - return false; - - m_source.RemoveAt( index ); - - return true; - } - - #endregion - - #region IEnumerable<> Members - - public IEnumerator GetEnumerator() - { - return m_source.Cast().GetEnumerator(); - } - - #endregion - - #region IEnumerable Members - - IEnumerator IEnumerable.GetEnumerator() - { - return m_source.GetEnumerator(); - } - - #endregion - - private readonly IList m_source; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/IListWrapper.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/IListWrapper.cs deleted file mode 100644 index dac4d8d8..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/IListWrapper.cs +++ /dev/null @@ -1,136 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; - -namespace Xceed.Utils.Collections -{ - internal sealed class IListWrapper : IList - { - internal IListWrapper( IList source ) - { - if( source == null ) - throw new ArgumentNullException( "source" ); - - m_source = source; - } - - #region IList<> Members - - public object this[ int index ] - { - get - { - return m_source[ index ]; - } - set - { - m_source[ index ] = value; - } - } - - public int IndexOf( object item ) - { - return m_source.IndexOf( item ); - } - - public void Insert( int index, object item ) - { - m_source.Insert( index, item ); - } - - public void RemoveAt( int index ) - { - m_source.RemoveAt( index ); - } - - #endregion - - #region ICollection<> Members - - public int Count - { - get - { - return m_source.Count; - } - } - - bool ICollection.IsReadOnly - { - get - { - return false; - } - } - - public void Add( object item ) - { - m_source.Add( item ); - } - - public void Clear() - { - m_source.Clear(); - } - - public bool Contains( object item ) - { - return m_source.Contains( item ); - } - - public void CopyTo( object[] array, int index ) - { - m_source.CopyTo( array, index ); - } - - public bool Remove( object item ) - { - var index = m_source.IndexOf( item ); - if( index < 0 ) - return false; - - m_source.RemoveAt( index ); - - return true; - } - - #endregion - - #region IEnumerable<> Members - - public IEnumerator GetEnumerator() - { - return m_source.Cast().GetEnumerator(); - } - - #endregion - - #region IEnumerable Members - - IEnumerator IEnumerable.GetEnumerator() - { - return m_source.GetEnumerator(); - } - - #endregion - - private readonly IList m_source; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/IndexWeakHeapSort.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/IndexWeakHeapSort.cs deleted file mode 100644 index 673d1dfa..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/IndexWeakHeapSort.cs +++ /dev/null @@ -1,132 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.ComponentModel; - -namespace Xceed.Utils.Collections -{ - // "Weak heap sort" sort m_dataIndexArray[0..length-1] to m_dataIndexArray[1..length] - // - // m_dataIndexArray is an array of int which points to the real value to sort. - // The index in dataIndexArray will be used to pass as parameters to Compare. - // That way, when implementing Compare, we use this index to directly acces the real data. - internal abstract class IndexWeakHeapSort - { - protected IndexWeakHeapSort( int[] dataIndexArray ) - { - m_dataIndexArray = dataIndexArray; - } - - public void Sort( int length ) - { - if( m_dataIndexArray == null ) - throw new InvalidOperationException( "A dataIndexArray must be passed at construction in order to sort." ); - - if( length < 0 ) - throw new ArgumentOutOfRangeException( "length", length, "length must be greater than or equal to zero." ); - - if( length >= m_dataIndexArray.Length ) - throw new ArgumentOutOfRangeException( "length", length, "length must be less than dataIndexArray.Length - 1." ); - - m_reverse = new sbyte[ length + 1 ]; - int i; - - for( i = length - 1; i >= 1; i-- ) - { - int parent = i; - - // Gparent // - while( ( parent & 1 ) == 0 ) - { - parent >>= 1; - } - - parent >>= 1; - // End GParent // - - // Merge // - if( this.Compare( m_dataIndexArray[ parent ], m_dataIndexArray[ i ] ) < 0 ) - { - int temp = m_dataIndexArray[ parent ]; - m_dataIndexArray[ parent ] = m_dataIndexArray[ i ]; - m_dataIndexArray[ i ] = temp; - - if( m_reverse[ i ] == 0 ) - { - m_reverse[ i ] = 1; - } - else - { - m_reverse[ i ] = 0; - } - } - // End merge // - } - - m_dataIndexArray[ length ] = m_dataIndexArray[ 0 ]; - - for( i = length - 1; i >= 2; i-- ) - { - this.MergeForest( i ); - } - - // "Weak heap sort" sort array[0..NUM_ELEMENTS-1] to array[1..NUM_ELEMENTS] - - m_reverse = null; - } - - public abstract int Compare( int xDataIndex, int yDataIndex ); - - private void MergeForest( int m ) - { - int x = 1; - - while( ( ( x << 1 ) + m_reverse[ x ] ) < m ) - { - x = ( x << 1 ) + m_reverse[ x ]; - } - - do - { - // Merge // - if( this.Compare( m_dataIndexArray[ m ], m_dataIndexArray[ x ] ) < 0 ) - { - int temp = m_dataIndexArray[ m ]; - m_dataIndexArray[ m ] = m_dataIndexArray[ x ]; - m_dataIndexArray[ x ] = temp; - - if( m_reverse[ x ] == 0 ) - { - m_reverse[ x ] = 1; - } - else - { - m_reverse[ x ] = 0; - } - } - // End merge // - - x >>= 1; - } - while( x > 0 ); - } - - private int[] m_dataIndexArray; - private sbyte[] m_reverse; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/LLRBTree.Generic.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/LLRBTree.Generic.cs deleted file mode 100644 index d797c3ac..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/LLRBTree.Generic.cs +++ /dev/null @@ -1,944 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Diagnostics; -using System.Linq; -using Xceed.Wpf.DataGrid.Utils; - -namespace Xceed.Utils.Collections -{ - // This class implements a left-leaning red–black that is based on - // the research paper "Left-leaning Red-Black Trees" by Robert Sedgewick. - internal class LLRBTree : IBinaryTree - { - #region Static Fields - - internal static readonly string RootPropertyName = PropertyHelper.GetPropertyName( ( LLRBTree t ) => t.Root ); - - #endregion - - internal LLRBTree() - : this( EqualityComparer.Default ) - { - } - - internal LLRBTree( IEqualityComparer comparer ) - { - if( comparer == null ) - throw new ArgumentNullException( "comparer" ); - - m_comparer = comparer; - } - - #region Root Property - - public IBinaryTreeNode Root - { - get - { - return m_rootNode; - } - } - - #endregion - - public IBinaryTreeNode Find( T value ) - { - this.EnsureValue( value ); - - var node = this.FindNode( value ); - if( ( node != null ) && ( node.Tree != this ) ) - return null; - - return node; - } - - public IBinaryTreeNode Insert( T value ) - { - if( m_rootNode != null ) - throw new InvalidOperationException( "This method cannot be called when the tree has a root node." ); - - this.EnsureNewValue( value ); - - m_rootNode = this.CreateNode( value ); - - if( m_rootNode == null ) - throw new InvalidOperationException( "A node was not created." ); - - this.SetRootNodeColor(); - this.OnPostInsert( m_rootNode, null ); - - return m_rootNode; - } - - public IBinaryTreeNode InsertBefore( T value, IBinaryTreeNode node ) - { - this.EnsureNewValue( value ); - this.EnsureCurrentNode( node ); - - var pivotNode = ( Node )node; - var rightmostNode = ( pivotNode.Left != null ) ? pivotNode.Left.GetRightmost() : null; - var oldRootNode = m_rootNode; - var parentNode = rightmostNode ?? pivotNode; - var newNode = this.CreateNode( value ); - - if( newNode == null ) - throw new InvalidOperationException( "A node was not created." ); - - if( rightmostNode != null ) - { - parentNode.Right = newNode; - } - else - { - parentNode.Left = newNode; - } - - newNode.Parent = parentNode; - - this.BalanceUp( parentNode ); - this.SetRootNodeColor(); - this.OnPostInsert( newNode, oldRootNode ); - - return newNode; - } - - public IBinaryTreeNode InsertAfter( T value, IBinaryTreeNode node ) - { - this.EnsureNewValue( value ); - this.EnsureCurrentNode( node ); - - var pivotNode = ( Node )node; - var leftmostNode = ( pivotNode.Right != null ) ? pivotNode.Right.GetLeftmost() : null; - var oldRootNode = m_rootNode; - var parentNode = leftmostNode ?? pivotNode; - var newNode = this.CreateNode( value ); - - if( newNode == null ) - throw new InvalidOperationException( "A node was not created." ); - - if( leftmostNode != null ) - { - parentNode.Left = newNode; - } - else - { - parentNode.Right = newNode; - } - - newNode.Parent = parentNode; - - this.BalanceUp( parentNode ); - this.SetRootNodeColor(); - this.OnPostInsert( newNode, oldRootNode ); - - return newNode; - } - - public void Remove( T value ) - { - this.EnsureValue( value ); - - this.Remove( this.FindNode( value ) ); - } - - public void Remove( IBinaryTreeNode node ) - { - this.EnsureCurrentNode( node ); - - var targetNode = ( Node )node; - var path = new Stack(); - path.Push( targetNode ); - - this.FindPath( path, m_rootNode ); - - var oldValue = node.Value; - var oldRootNode = m_rootNode; - var oldParentNode = default( Node ); - - m_rootNode = this.Remove( path, true, out oldParentNode ); - - this.SetRootNodeColor(); - this.OnPostRemove( oldValue, oldParentNode, oldRootNode ); - } - - public void Clear() - { - if( m_rootNode == null ) - return; - - this.Clear( m_rootNode ); - - m_rootNode = null; - - this.OnCollectionChanged( new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Reset ) ); - this.OnPropertyChanged( LLRBTree.RootPropertyName ); - } - - public IEnumerable GetItems( bool reverse ) - { - return this.GetNodes( reverse ).Select( node => node.Value ); - } - - protected virtual Node CreateNode( T value ) - { - return new Node( this, value ); - } - - protected virtual void ClearNode( Node node ) - { - if( node == null ) - return; - - node.Parent = null; - node.Left = null; - node.Right = null; - node.IsRed = true; - } - - protected virtual Node FindNode( T value ) - { - foreach( var node in this.GetNodes( false ) ) - { - if( m_comparer.Equals( value, node.Value ) ) - return node; - } - - return null; - } - - protected virtual void EnsureValue( T value ) - { - } - - protected virtual void EnsureNewValue( T value ) - { - this.EnsureValue( value ); - } - - private IEnumerable GetNodes( bool reverse ) - { - if( m_rootNode == null ) - yield break; - - if( reverse ) - { - for( var node = m_rootNode.GetRightmost() ?? m_rootNode; node != null; node = node.GetPrevious() ) - { - yield return node; - } - } - else - { - for( var node = m_rootNode.GetLeftmost() ?? m_rootNode; node != null; node = node.GetNext() ) - { - yield return node; - } - } - } - - private Node Remove( Stack path, bool destroy, out Node oldParentNode ) - { - Debug.Assert( path != null ); - Debug.Assert( path.Count > 0 ); - - var node = path.Pop(); - - if( ( path.Count > 0 ) && ( node.Left == path.Peek() ) ) - { - if( !this.IsRed( node.Left ) && !this.IsRed( node.Left.Left ) ) - { - node = this.MoveRedLeft( node ); - - this.CutPath( path ); - this.FindPath( path, node.Left ); - } - - node.Left = this.Remove( path, destroy, out oldParentNode ); - } - else - { - if( this.IsRed( node.Left ) ) - { - if( path.Count <= 0 ) - { - path.Push( node ); - } - - node = this.RotateRight( node ); - - Debug.Assert( path.Count > 0 ); - - this.CutPath( path ); - this.FindPath( path, node.Right ); - } - - if( ( node.Right == null ) && ( path.Count == 0 ) ) - { - Debug.Assert( node.Left == null ); - - oldParentNode = node.Parent; - - if( destroy ) - { - this.ClearNode( node ); - } - - return null; - } - - if( !this.IsRed( node.Right ) && !this.IsRed( node.Right.Left ) ) - { - if( path.Count <= 0 ) - { - path.Push( node ); - } - - node = this.MoveRedRight( node ); - - Debug.Assert( path.Count > 0 ); - - if( path.Peek() == node ) - { - path.Pop(); - } - else - { - this.CutPath( path ); - this.FindPath( path, node.Right ); - } - } - - if( path.Count == 0 ) - { - Debug.Assert( node.Right != null ); - - var child = default( Node ); - var target = node.Right.GetLeftmost(); - - Debug.Assert( target != null ); - Debug.Assert( target.Left == null ); - - if( target != node.Right ) - { - path.Push( target ); - this.FindPath( path, node.Right ); - - child = this.Remove( path, false, out oldParentNode ); - } - else - { - oldParentNode = target; - } - - target.Parent = node.Parent; - target.Left = node.Left; - target.Right = child; - target.IsRed = node.IsRed; - - if( target.Left != null ) - { - target.Left.Parent = target; - } - - if( target.Right != null ) - { - target.Right.Parent = target; - } - - if( target.Parent != null ) - { - if( target.Parent.Left == node ) - { - target.Parent.Left = target; - } - else - { - target.Parent.Right = target; - } - } - - Debug.Assert( destroy ); - if( destroy ) - { - this.ClearNode( node ); - } - - node = target; - } - else - { - node.Right = this.Remove( path, destroy, out oldParentNode ); - } - } - - return this.Balance( node ); - } - - private void BalanceUp( Node node ) - { - while( node != null ) - { - node = this.Balance( node ).Parent; - } - } - - private Node Balance( Node node ) - { - if( this.IsRed( node.Right ) && !this.IsRed( node.Left ) ) - { - // Avoid right-leaning node - node = this.RotateLeft( node ); - } - - if( this.IsRed( node.Left ) && this.IsRed( node.Left.Left ) ) - { - node = this.RotateRight( node ); - } - - if( this.IsRed( node.Left ) && this.IsRed( node.Right ) ) - { - this.FlipColor( node ); - } - - return node; - } - - private void FlipColor( Node node ) - { - Debug.Assert( node != null ); - Debug.Assert( node.Left != null ); - Debug.Assert( node.Right != null ); - - node.Left.IsRed = !node.Left.IsRed; - node.Right.IsRed = !node.Right.IsRed; - node.IsRed = !node.IsRed; - } - - private void SetRootNodeColor() - { - if( m_rootNode == null ) - return; - - m_rootNode.IsRed = false; - } - - private void Clear( Node node ) - { - if( node == null ) - return; - - this.Clear( node.Left ); - this.Clear( node.Right ); - this.ClearNode( node ); - } - - private Node RotateLeft( Node node ) - { - Debug.Assert( node != null ); - - var right = node.Right; - Debug.Assert( right != null ); - - node.Right = right.Left; - if( node.Right != null ) - { - node.Right.Parent = node; - } - - var parentNode = node.Parent; - - right.Parent = parentNode; - right.Left = node; - right.IsRed = node.IsRed; - - node.Parent = right; - node.IsRed = true; - - if( parentNode != null ) - { - if( parentNode.Left == node ) - { - parentNode.Left = right; - } - else - { - parentNode.Right = right; - } - } - else - { - m_rootNode = right; - } - - return right; - } - - private Node RotateRight( Node node ) - { - Debug.Assert( node != null ); - - var left = node.Left; - Debug.Assert( left != null ); - - node.Left = left.Right; - if( node.Left != null ) - { - node.Left.Parent = node; - } - - var parentNode = node.Parent; - - left.Parent = parentNode; - left.Right = node; - left.IsRed = node.IsRed; - - node.Parent = left; - node.IsRed = true; - - if( parentNode != null ) - { - if( parentNode.Left == node ) - { - parentNode.Left = left; - } - else - { - parentNode.Right = left; - } - } - else - { - m_rootNode = left; - } - - return left; - } - - private Node MoveRedLeft( Node node ) - { - Debug.Assert( node != null ); - Debug.Assert( node.Right != null ); - - this.FlipColor( node ); - - if( this.IsRed( node.Right.Left ) ) - { - node.Right = this.RotateRight( node.Right ); - node = this.RotateLeft( node ); - - this.FlipColor( node ); - } - - return node; - } - - private Node MoveRedRight( Node node ) - { - Debug.Assert( node != null ); - Debug.Assert( node.Left != null ); - - this.FlipColor( node ); - - if( this.IsRed( node.Left.Left ) ) - { - node = this.RotateRight( node ); - - this.FlipColor( node ); - } - - return node; - } - - private void FindPath( Stack path, Node upTo ) - { - Debug.Assert( path != null ); - - if( path.Count <= 0 ) - throw new ArgumentException( "The path must contain at least one element.", "path" ); - - if( path.Peek() != upTo ) - { - for( var parentNode = path.Peek().Parent; parentNode != null; parentNode = parentNode.Parent ) - { - path.Push( parentNode ); - - if( parentNode == upTo ) - break; - } - - if( path.Peek() != upTo ) - throw new InvalidOperationException(); - } - } - - private void CutPath( Stack path ) - { - for( int i = 0; i < 2; i++ ) - { - if( path.Count <= 1 ) - break; - - path.Pop(); - } - } - - private void OnPostInsert( Node newNode, Node oldRootNode ) - { - Debug.Assert( newNode != null ); - - this.OnCollectionChanged( new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Add, newNode.Value ) ); - - if( oldRootNode != m_rootNode ) - { - this.OnPropertyChanged( LLRBTree.RootPropertyName ); - } - } - - private void OnPostRemove( T value, Node parentNode, Node oldRootNode ) - { - this.OnCollectionChanged( new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Remove, value ) ); - - if( oldRootNode != m_rootNode ) - { - this.OnPropertyChanged( LLRBTree.RootPropertyName ); - } - } - - private bool IsRed( Node node ) - { - // A null node is "black". - return ( node != null ) - && ( node.IsRed ); - } - - private void EnsureNode( IBinaryTreeNode node ) - { - if( node == null ) - throw new ArgumentNullException( "node" ); - - if( !( node is Node ) ) - throw new ArgumentException( "Unexpected node type.", "node" ); - } - - private void EnsureCurrentNode( IBinaryTreeNode node ) - { - this.EnsureNode( node ); - - if( node.Tree != this ) - throw new ArgumentException( "The node is not within the tree.", "node" ); - } - - #region INotifyCollectionChanged Members - - public event NotifyCollectionChangedEventHandler CollectionChanged; - - protected virtual void OnCollectionChanged( NotifyCollectionChangedEventArgs e ) - { - var handler = this.CollectionChanged; - if( handler == null ) - return; - - handler.Invoke( this, e ); - } - - #endregion - - #region INotifyPropertyChanged Members - - public event PropertyChangedEventHandler PropertyChanged; - - protected void OnPropertyChanged( string propertyName ) - { - this.OnPropertyChanged( new PropertyChangedEventArgs( propertyName ) ); - } - - protected virtual void OnPropertyChanged( PropertyChangedEventArgs e ) - { - var handler = this.PropertyChanged; - if( handler == null ) - return; - - handler.Invoke( this, e ); - } - - #endregion - - #region IEnumerable<> Members - - IEnumerator IEnumerable.GetEnumerator() - { - return this.GetItems( false ).GetEnumerator(); - } - - #endregion - - #region IEnumerable Members - - IEnumerator IEnumerable.GetEnumerator() - { - return ( ( IEnumerable )this ).GetEnumerator(); - } - - #endregion - - private readonly IEqualityComparer m_comparer; - - private Node m_rootNode; - - #region Node Protected Class - - protected class Node : IBinaryTreeNode - { - public Node( LLRBTree owner, T value ) - { - Debug.Assert( owner != null ); - Debug.Assert( value != null ); - - m_owner = owner; - m_value = value; - m_isRed = true; - } - - public T Value - { - get - { - return m_value; - } - } - - public LLRBTree Tree - { - get - { - return m_owner; - } - } - - public Node Parent - { - get - { - return m_parent; - } - internal set - { - if( value == m_parent ) - return; - - var oldNode = m_parent; - - m_parent = value; - - this.OnParentChanged( oldNode, m_parent ); - } - } - - public Node Left - { - get - { - return m_left; - } - internal set - { - if( value == m_left ) - return; - - var oldNode = m_left; - - m_left = value; - - this.OnLeftChanged( oldNode, m_left ); - } - } - - public Node Right - { - get - { - return m_right; - } - internal set - { - if( value == m_right ) - return; - - var oldNode = m_right; - - m_right = value; - - this.OnRightChanged( oldNode, m_right ); - } - } - - internal bool IsRed - { - get - { - return m_isRed; - } - set - { - m_isRed = value; - } - } - - public Node GetPrevious() - { - if( m_left != null ) - return m_left.GetRightmost(); - - var child = this; - var parent = m_parent; - - while( parent != null ) - { - if( parent.Right == child ) - return parent; - - child = parent; - parent = parent.Parent; - } - - return null; - } - - public Node GetNext() - { - if( m_right != null ) - return m_right.GetLeftmost(); - - var child = this; - var parent = m_parent; - - while( parent != null ) - { - if( parent.Left == child ) - return parent; - - child = parent; - parent = parent.Parent; - } - - return null; - } - - public Node GetLeftmost() - { - var child = default( Node ); - - for( var current = this; current != null; current = current.Left ) - { - child = current; - } - - return child; - } - - public Node GetRightmost() - { - var child = default( Node ); - - for( var current = this; current != null; current = current.Right ) - { - child = current; - } - - return child; - } - - protected virtual void OnParentChanged( Node oldNode, Node newNode ) - { - } - - protected virtual void OnLeftChanged( Node oldNode, Node newNode ) - { - } - - protected virtual void OnRightChanged( Node oldNode, Node newNode ) - { - } - - IBinaryTree IBinaryTreeNode.Tree - { - get - { - return this.Tree; - } - } - - IBinaryTreeNode IBinaryTreeNode.Parent - { - get - { - return this.Parent; - } - } - - IBinaryTreeNode IBinaryTreeNode.Left - { - get - { - return this.Left; - } - } - - IBinaryTreeNode IBinaryTreeNode.Right - { - get - { - return this.Right; - } - } - - IBinaryTreeNode IBinaryTreeNode.GetPrevious() - { - return this.GetPrevious(); - } - - IBinaryTreeNode IBinaryTreeNode.GetNext() - { - return this.GetNext(); - } - - IBinaryTreeNode IBinaryTreeNode.GetLeftmost() - { - return this.GetLeftmost(); - } - - IBinaryTreeNode IBinaryTreeNode.GetRightmost() - { - return this.GetRightmost(); - } - - private readonly T m_value; - private readonly LLRBTree m_owner; - private Node m_parent; // null - private Node m_left; // null - private Node m_right; // null - private bool m_isRed; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/LongestIncreasingSubsequence.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/LongestIncreasingSubsequence.cs deleted file mode 100644 index b5ca6012..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/LongestIncreasingSubsequence.cs +++ /dev/null @@ -1,119 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Diagnostics; - -namespace Xceed.Utils.Collections -{ - internal static class LongestIncreasingSubsequence - { - internal static IList Find( IList values ) - { - if( values == null ) - throw new ArgumentNullException( "values" ); - - if( values.Count <= 0 ) - return new int[ 0 ]; - - var maximum = 1; - var predecessors = new int[ values.Count ]; - var positions = new int[ values.Count ]; - - predecessors[ 0 ] = -1; - positions[ 0 ] = 0; - - for( var i = 1; i < values.Count; i++ ) - { - // We have found an element that extend the longest subsequence found so far. - if( values[ i ] > values[ positions[ maximum - 1 ] ] ) - { - predecessors[ i ] = positions[ maximum - 1 ]; - positions[ maximum ] = i; - maximum++; - } - else - { - var index = LongestIncreasingSubsequence.FindLeastIndex( i, values, positions, maximum ); - - // This is the lowest value found so far. - if( index < 0 ) - { - predecessors[ i ] = -1; - positions[ 0 ] = i; - } - // We have found an element that could help to find new future subsequences. - else - { - Debug.Assert( index + 1 < maximum ); - - predecessors[ i ] = positions[ index ]; - positions[ index + 1 ] = i; - } - } - } - - var result = new int[ maximum ]; - var position = positions[ maximum - 1 ]; - - for( var i = maximum - 1; i >= 0; i-- ) - { - result[ i ] = values[ position ]; - position = predecessors[ position ]; - } - - return result; - } - - private static int FindLeastIndex( int index, IList values, int[] positions, int maximum ) - { - Debug.Assert( ( values != null ) && ( values.Count > 0 ) ); - Debug.Assert( ( positions != null ) && ( maximum <= positions.Length ) ); - Debug.Assert( ( index >= 0 ) && ( index < values.Count ) ); - - var lower = 0; - var upper = maximum - 1; - var value = values[ index ]; - - while( lower <= upper ) - { - var middle = lower + ( upper - lower ) / 2; - var compare = value.CompareTo( values[ positions[ middle ] ] ); - - if( compare <= 0 ) - { - if( middle == 0 ) - break; - - if( lower == middle ) - return middle - 1; - - upper = middle - 1; - } - else - { - if( upper == middle ) - return middle; - - lower = middle + 1; - } - } - - return -1; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/ObservableHashList.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/ObservableHashList.cs deleted file mode 100644 index 08d6a7b4..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/ObservableHashList.cs +++ /dev/null @@ -1,423 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Diagnostics; -using System.Threading; -using Xceed.Wpf.DataGrid; - -namespace Xceed.Utils.Collections -{ - [Serializable] - [DebuggerTypeProxy( typeof( Xceed.Utils.Collections.ObservableHashList.ObservableHashListDebugView ) )] - [DebuggerDisplay( "Count = {Count}" )] - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Design", "CA1039:ListsAreStronglyTyped" )] - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Design", "CA1035:ICollectionImplementationsHaveStronglyTypedMembers" )] - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix" )] - public sealed class ObservableHashList : IList, INotifyCollectionChanged, INotifyPropertyChanged - { - #region CONSTANTS - - private const int UseHashSetThreshold = 10; - private const int UseListThreshold = 8; - - #endregion - - internal ObservableHashList() - { - } - - #region IList Members - - public bool IsFixedSize - { - get - { - return false; - } - } - - public bool IsReadOnly - { - get - { - return false; - } - } - - public object this[ int index ] - { - get - { - return m_items[ index ]; - } - set - { - var count = this.Count; - if( ( index < 0 ) || ( index > count ) ) - throw new ArgumentOutOfRangeException( "index" ); - - if( index == count ) - { - this.InsertCore( index, value ); - } - else - { - this.ReplaceCore( index, value ); - } - } - } - - public int Add( object value ) - { - int index = this.Count; - this.InsertCore( index, value ); - - return index; - } - - public void Clear() - { - if( this.Count == 0 ) - return; - - m_set = null; - m_items.Clear(); - - this.OnCollectionChanged( new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Reset ) ); - } - - public bool Contains( object value ) - { - if( m_set != null ) - return m_set.Contains( value ); - - return m_items.Contains( value ); - } - - public int IndexOf( object value ) - { - if( ( m_set != null ) && !m_set.Contains( value ) ) - return -1; - - return m_items.IndexOf( value ); - } - - public void Insert( int index, object value ) - { - this.InsertCore( index, value ); - } - - public void Remove( object value ) - { - int index = this.IndexOf( value ); - if( index < 0 ) - return; - - this.RemoveAtCore( index ); - } - - public void RemoveAt( int index ) - { - this.RemoveAtCore( index ); - } - - #endregion - - #region ICollection Members - - public int Count - { - get - { - return m_items.Count; - } - } - - public bool IsSynchronized - { - get - { - return false; - } - } - - public object SyncRoot - { - get - { - return ( ( ICollection )m_items ).SyncRoot; - } - } - - public void CopyTo( Array array, int index ) - { - ( ( IList )m_items ).CopyTo( array, index ); - } - - #endregion - - #region IEnumerable Members - - public IEnumerator GetEnumerator() - { - return m_items.GetEnumerator(); - } - - #endregion - - #region INotifyCollectionChanged Members - - public event NotifyCollectionChangedEventHandler CollectionChanged; - - private void OnCollectionChanged( NotifyCollectionChangedEventArgs e ) - { - var handler = this.CollectionChanged; - if( handler == null ) - return; - - if( m_deferCount == 0 ) - { - this.OnPropertyChanged( "Item[]" ); - this.OnPropertyChanged( "Count" ); - - handler.Invoke( this, e ); - } - else - { - m_hasDeferredNotifications = true; - } - } - - #endregion - - #region INotifyPropertyChanged Members - - public event PropertyChangedEventHandler PropertyChanged; - - private void OnPropertyChanged( string propertyName ) - { - var handler = this.PropertyChanged; - if( handler == null ) - return; - - handler.Invoke( this, new PropertyChangedEventArgs( propertyName ) ); - } - - #endregion - - public IDisposable DeferINotifyCollectionChanged() - { - return new DeferDisposable( this ); - } - - public void Sort() - { - this.Sort( null ); - } - - public void Sort( IComparer comparer ) - { - var comparerWrapper = new ComparerWrapper( ( comparer != null ) ? comparer : ObjectComparer.Singleton ); - m_items.Sort( comparerWrapper ); - - this.OnCollectionChanged( new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Reset ) ); - } - - private void InsertCore( int index, object value ) - { - var count = this.Count; - if( ( index < 0 ) || ( index > count ) ) - throw new ArgumentOutOfRangeException( "index" ); - - this.EnsureNotIn( value ); - - if( ( m_set == null ) && ( count >= ObservableHashList.UseHashSetThreshold ) ) - { - m_set = new HashSet( m_items ); - } - - m_items.Insert( index, value ); - - if( m_set != null ) - { - m_set.Add( value ); - } - - this.OnCollectionChanged( new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Add, value, index ) ); - } - - private void RemoveAtCore( int index ) - { - var count = this.Count; - if( ( index < 0 ) || ( index >= count ) ) - throw new ArgumentOutOfRangeException( "index" ); - - var value = m_items[ index ]; - - m_items.RemoveAt( index ); - - if( m_set != null ) - { - if( count > ObservableHashList.UseListThreshold ) - { - m_set.Remove( value ); - } - else - { - m_set = null; - } - } - - this.OnCollectionChanged( new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Remove, value, index ) ); - } - - private void ReplaceCore( int index, object value ) - { - Debug.Assert( ( index >= 0 ) && ( index < this.Count ) ); - - if( m_items[ index ] == value ) - return; - - this.EnsureNotIn( value ); - - var oldValue = m_items[ index ]; - m_items[ index ] = value; - - if( m_set != null ) - { - m_set.Remove( oldValue ); - m_set.Add( value ); - } - - this.OnCollectionChanged( new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Replace, value, oldValue, index ) ); - } - - private void EnsureNotIn( object value ) - { - if( this.Contains( value ) ) - throw new ArgumentException( string.Format( "Item has already been added. (Key being added: '{0}')", "value", ( value == null ) ? "null" : value.ToString() ) ); - } - - #region Private Fields - - private readonly List m_items = new List(); - private HashSet m_set; //null - private int m_deferCount; - private bool m_hasDeferredNotifications; //false - - #endregion - - #region DeferDisposable Private Class - - private sealed class DeferDisposable : IDisposable - { - internal DeferDisposable( ObservableHashList owner ) - { - Debug.Assert( owner != null ); - - m_owner = owner; - m_owner.m_deferCount++; - } - - public void Dispose() - { - this.Dispose( true ); - GC.SuppressFinalize( this ); - } - - private void Dispose( bool disposing ) - { - var target = Interlocked.Exchange( ref m_owner, null ); - if( target == null ) - return; - - target.m_deferCount--; - if( target.m_deferCount != 0 ) - return; - - if( target.m_hasDeferredNotifications ) - { - target.m_hasDeferredNotifications = false; - target.OnCollectionChanged( new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Reset ) ); - } - } - - ~DeferDisposable() - { - this.Dispose( false ); - } - - private ObservableHashList m_owner; // = null; - } - - #endregion - - #region ComparerWrapper Private Class - - private sealed class ComparerWrapper : IComparer - { - internal ComparerWrapper( IComparer comparer ) - { - Debug.Assert( comparer != null ); - - m_comparer = comparer; - } - - public int Compare( object x, object y ) - { - return m_comparer.Compare( x, y ); - } - - private readonly IComparer m_comparer; - } - - #endregion - - #region ObservableHashListDebugView Private Class - - private sealed class ObservableHashListDebugView - { - internal ObservableHashListDebugView( ObservableHashList owner ) - { - if( owner == null ) - throw new ArgumentNullException( "list" ); - - m_owner = owner; - } - - public object[] Values - { - get - { - var items = m_owner.m_items; - if( items == null ) - return new object[ 0 ]; - - return items.ToArray(); - } - } - - private readonly ObservableHashList m_owner; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/ObservableList.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/ObservableList.cs deleted file mode 100644 index c0981fc4..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/ObservableList.cs +++ /dev/null @@ -1,517 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Collections.Specialized; -using System.Collections.ObjectModel; -using System.Collections; - -namespace Xceed.Utils.Collections -{ - internal class ObservableList : IList, IList, ICollection, INotifyCollectionChanged - { - public ObservableList() - { - m_wrappedlist = new List(); - } - - public ObservableList( IEnumerable collection ) - { - m_wrappedlist = new List( collection ); - } - - public ObservableList( int capacity ) - { - m_wrappedlist = new List( capacity ); - } - - public void AddRange( IEnumerable collection ) - { - int startingIndex = m_wrappedlist.Count; - - m_wrappedlist.AddRange( collection ); - - if( this.CollectionChanged != null ) - { - List newItems = new List( collection ); - - this.CollectionChanged( this, new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Add, newItems, startingIndex ) ); - } - } - - public ReadOnlyCollection AsReadOnly() - { - return m_wrappedlist.AsReadOnly(); - } - - public int BinarySearch( T item ) - { - return m_wrappedlist.BinarySearch( item ); - } - - public int BinarySearch( T item, IComparer comparer ) - { - return m_wrappedlist.BinarySearch( item, comparer ); - } - - public int BinarySearch( int index, int count, T item, IComparer comparer ) - { - return m_wrappedlist.BinarySearch( index, count, item, comparer ); - } - - public List ConvertAll( Converter converter ) - { - return m_wrappedlist.ConvertAll( converter ); - } - - public void CopyTo( T[] array ) - { - m_wrappedlist.CopyTo( array ); - } - - public void CopyTo( int index, T[] array, int arrayIndex, int count ) - { - m_wrappedlist.CopyTo( index, array, arrayIndex, count ); - } - - public bool Exists( Predicate match ) - { - return m_wrappedlist.Exists( match ); - } - - public T Find( Predicate match ) - { - return m_wrappedlist.Find( match ); - } - - public List FindAll( Predicate match ) - { - return m_wrappedlist.FindAll( match ); - } - - public int FindIndex( Predicate match ) - { - return m_wrappedlist.FindIndex( match ); - } - - public int FindIndex( int startIndex, Predicate match ) - { - return m_wrappedlist.FindIndex( startIndex, match ); - } - - public int FindIndex( int startIndex, int count, Predicate match ) - { - return m_wrappedlist.FindIndex( startIndex, count, match ); - } - - public T FindLast( Predicate match ) - { - return m_wrappedlist.FindLast( match ); - } - - public int FindLastIndex( Predicate match ) - { - return m_wrappedlist.FindLastIndex( match ); - } - - public int FindLastIndex( int startIndex, Predicate match ) - { - return m_wrappedlist.FindLastIndex( startIndex, match ); - } - - public int FindLastIndex( int startIndex, int count, Predicate match ) - { - return m_wrappedlist.FindLastIndex( startIndex, count, match ); - } - - public void ForEach( Action action ) - { - m_wrappedlist.ForEach( action ); - } - - public List GetRange( int index, int count ) - { - return m_wrappedlist.GetRange( index, count ); - } - - public int IndexOf( T item, int index ) - { - return m_wrappedlist.IndexOf( item, index ); - } - - public int IndexOf( T item, int index, int count ) - { - return m_wrappedlist.IndexOf( item, index, count ); - } - - public void InsertRange( int index, IEnumerable collection ) - { - m_wrappedlist.InsertRange( index, collection ); - - if( this.CollectionChanged != null ) - { - List newItems = new List( ( IEnumerable )collection ); - - NotifyCollectionChangedEventArgs eventArgs = new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Add, newItems, index ); - - this.CollectionChanged( this, eventArgs ); - } - } - - public int LastIndexOf( T item ) - { - return m_wrappedlist.LastIndexOf( item ); - } - - public int LastIndexOf( T item, int index ) - { - return m_wrappedlist.LastIndexOf( item, index ); - } - - public int LastIndexOf( T item, int index, int count ) - { - return m_wrappedlist.LastIndexOf( item, index, count ); - } - - public int RemoveAll( Predicate match ) - { - int retval = m_wrappedlist.RemoveAll( match ); - - if( this.CollectionChanged != null ) - { - // Not choices but to send a reset... since I do not know what items were removed. - NotifyCollectionChangedEventArgs eventArgs = new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Reset ); - - this.CollectionChanged( this, eventArgs ); - } - - return retval; - } - - public void RemoveRange( int index, int count ) - { - List removedItems = this.GetRange( index, count ); - - m_wrappedlist.RemoveRange( index, count ); - - if( this.CollectionChanged != null ) - { - NotifyCollectionChangedEventArgs eventArgs = new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Remove, removedItems, index ); - - this.CollectionChanged( this, eventArgs ); - } - } - - public void Reverse() - { - m_wrappedlist.Reverse(); - } - - public void Reverse( int index, int count ) - { - m_wrappedlist.Reverse( index, count ); - } - - public void Sort() - { - m_wrappedlist.Sort(); - } - - public void Sort( IComparer comparer ) - { - m_wrappedlist.Sort( comparer ); - } - - public void Sort( Comparison comparison ) - { - m_wrappedlist.Sort( comparison ); - } - - public void Sort( int index, int count, IComparer comparer ) - { - m_wrappedlist.Sort( index, count, comparer ); - } - - #region IList Members - - public int IndexOf( T item ) - { - return m_wrappedlist.IndexOf( item ); - } - - public void Insert( int index, T item ) - { - m_wrappedlist.Insert( index, item ); - - if( this.CollectionChanged != null ) - { - NotifyCollectionChangedEventArgs eventArgs = new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Add, item, index ); - - this.CollectionChanged( this, eventArgs ); - } - } - - public void RemoveAt( int index ) - { - T removedItem = this[ index ]; - - m_wrappedlist.RemoveAt( index ); - - if( this.CollectionChanged != null ) - { - NotifyCollectionChangedEventArgs eventArgs = new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Remove, removedItem, index ); - - this.CollectionChanged( this, eventArgs ); - } - } - - public T this[ int index ] - { - get - { - return m_wrappedlist[ index ]; - } - set - { - T oldItem = m_wrappedlist[ index ]; - - m_wrappedlist[ index ] = value; - - if( this.CollectionChanged != null ) - { - NotifyCollectionChangedEventArgs eventArgs = new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Replace, value, oldItem ); - - this.CollectionChanged( this, eventArgs ); - } - } - } - - #endregion - - #region ICollection Members - - public void Add( T item ) - { - m_wrappedlist.Add( item ); - - if( this.CollectionChanged != null ) - { - // -1 since the item is already added to the list - NotifyCollectionChangedEventArgs eventArgs = new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Add, item, this.Count - 1 ); - - this.CollectionChanged( this, eventArgs ); - } - } - - public void Clear() - { - m_wrappedlist.Clear(); - - if( this.CollectionChanged != null ) - { - NotifyCollectionChangedEventArgs eventArgs = new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Reset ); - - this.CollectionChanged( this, eventArgs ); - } - } - - public bool Contains( T item ) - { - return m_wrappedlist.Contains( item ); - } - - public void CopyTo( T[] array, int arrayIndex ) - { - m_wrappedlist.CopyTo( array, arrayIndex ); - } - - public int Count - { - get - { - return m_wrappedlist.Count; - } - } - - bool ICollection.IsReadOnly - { - get - { - return ( ( ICollection )m_wrappedlist ).IsReadOnly; - } - } - - public bool Remove( T item ) - { - bool retval = false; - - int oldIndex = m_wrappedlist.IndexOf( item ); - - retval = m_wrappedlist.Remove( item ); - - if( ( retval == true ) && ( this.CollectionChanged != null ) ) - { - NotifyCollectionChangedEventArgs eventArgs = new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Remove, item, oldIndex ); - - this.CollectionChanged( this, eventArgs ); - } - - return retval; - } - - #endregion - - #region IEnumerable Members - - public IEnumerator GetEnumerator() - { - return ( ( IEnumerable )m_wrappedlist ).GetEnumerator(); - } - - #endregion - - #region IEnumerable Members - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return ( ( System.Collections.IEnumerable )m_wrappedlist ).GetEnumerator(); - } - - #endregion - - #region INotifyCollectionChanged Members - - public event NotifyCollectionChangedEventHandler CollectionChanged; - - #endregion - - #region IList Members - - int IList.Add( object value ) - { - if( IsCompatibleObject( value ) == false ) - throw new ArgumentException( "value must be of type T." ); - - this.Add( ( T )value ); - - return ( this.Count - 1 ); - } - - bool IList.Contains( object value ) - { - if( IsCompatibleObject( value ) == false ) - throw new ArgumentException( "value must be of type T." ); - - return this.Contains( ( T )value ); - } - - int IList.IndexOf( object value ) - { - if( IsCompatibleObject( value ) == false ) - throw new ArgumentException( "value must be of type T." ); - - return this.IndexOf( ( T )value ); - } - - void IList.Insert( int index, object value ) - { - if( IsCompatibleObject( value ) == false ) - throw new ArgumentException( "value must be of type T." ); - - this.Insert( index, ( T )value ); - } - - bool IList.IsFixedSize - { - get - { - return ( ( IList )m_wrappedlist ).IsFixedSize; - } - } - - bool IList.IsReadOnly - { - get - { - return ( ( IList )m_wrappedlist ).IsReadOnly; - } - } - - void IList.Remove( object value ) - { - if( IsCompatibleObject( value ) == false ) - throw new ArgumentException( "value must be of type T." ); - - this.Remove( ( T )value ); - } - - object IList.this[ int index ] - { - get - { - return this[ index ]; - } - set - { - if( IsCompatibleObject( value ) == false ) - throw new ArgumentException( "value must be of type T." ); - - this[ index ] = ( T )value; - } - } - - #endregion - - #region ICollection Members - - void ICollection.CopyTo( Array array, int index ) - { - ( ( ICollection )m_wrappedlist ).CopyTo( array, index ); - } - - bool ICollection.IsSynchronized - { - get - { - return ( ( ICollection )m_wrappedlist ).IsSynchronized; - } - } - - object ICollection.SyncRoot - { - get - { - return ( ( ICollection )m_wrappedlist ).SyncRoot; - } - } - - #endregion - - private static bool IsCompatibleObject( object value ) - { - if( !( value is T ) && ( ( value != null ) || typeof( T ).IsValueType ) ) - { - return false; - } - return true; - } - - private List m_wrappedlist; - - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/RSTree.Generic.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/RSTree.Generic.cs deleted file mode 100644 index 48c2d88a..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/RSTree.Generic.cs +++ /dev/null @@ -1,2087 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Threading; - -namespace Xceed.Utils.Collections -{ - internal class RSTree : ICollection.Entry>, ICollection - { - #region Static Fields - - private const double OverflowReInsertionRatio = 0.3d; - - #endregion - - internal RSTree( RSTreeHelper helper ) - : this( helper, 3, 8 ) - { - } - - internal RSTree( RSTreeHelper helper, int minNodeSize, int maxNodeSize ) - { - if( helper == null ) - throw new ArgumentNullException( "helper" ); - - var dimensions = helper.GetDimensions(); - if( dimensions < 1 ) - throw new ArgumentException( "The number of dimensions must be greater than or equal to one.", "helper" ); - - if( minNodeSize < 2 ) - throw new ArgumentOutOfRangeException( "minNodeSize", minNodeSize, "minNodeSize must be greater than or equal to 2." ); - - if( maxNodeSize < minNodeSize * 2 ) - throw new ArgumentException( "maxNodeSize must be greater than or equal to minNodeSize * 2.", "maxNodeSize" ); - - m_helper = helper; - m_minNodeSize = minNodeSize; - m_maxNodeSize = maxNodeSize; - } - - #region Count Property - - public int Count - { - get - { - return m_count; - } - } - - #endregion - - public void Add( TRegion region, TItem item ) - { - this.Add( new Entry( region, item ) ); - } - - public bool Remove( TRegion region, TItem item ) - { - return this.Remove( new Entry( region, item ) ); - } - - public bool Contains( TRegion region, TItem item ) - { - return this.Contains( new Entry( region, item ) ); - } - - public bool Overlaps( TRegion region ) - { - return this.Overlaps( m_rootNode, region ); - } - - public IEnumerable.Entry> GetEntriesWithin( TRegion region ) - { - if( ( m_rootNode == null ) || m_helper.IsEmptyRegion( region ) ) - return Enumerable.Empty.Entry>(); - - return new EntryEnumerable( this, region ); - } - - private static int FindLevel( Node node ) - { - Debug.Assert( node != null ); - - if( node.Parent == null ) - return 0; - - return RSTree.FindLevel( node.Parent ) + 1; - } - - private void Insert( Entry entry ) - { - Debug.Assert( !m_helper.IsEmptyRegion( entry.Region ) ); - - if( m_rootNode == null ) - { - m_rootNode = new LeafNode( m_helper, m_maxNodeSize ); - } - - var leafNode = ( LeafNode )m_rootNode.FindNearest( entry.Region ); - Debug.Assert( leafNode != null ); - - leafNode.Add( entry ); - - if( leafNode.Count > m_maxNodeSize ) - { - this.ManageOverflow( leafNode ); - } - } - - private bool Overlaps( Node node, TRegion region ) - { - if( ( node == null ) || !m_helper.IsOverlapping( node.Region, region ) ) - return false; - - var leafNode = node as LeafNode; - if( leafNode != null ) - { - var count = leafNode.Count; - for( int i = 0; i < count; i++ ) - { - var entry = leafNode[ i ]; - if( m_helper.IsOverlapping( entry.Region, region ) ) - return true; - } - } - else - { - var internalNode = ( InternalNode )node; - var count = internalNode.Count; - - for( int i = 0; i < count; i++ ) - { - if( this.Overlaps( internalNode[ i ], region ) ) - return true; - } - } - - return false; - } - - private void Insert( Node node, int level ) - { - Debug.Assert( ( node != null ) && ( level > 0 ) ); - Debug.Assert( m_rootNode != null ); - - var internalNode = ( InternalNode )m_rootNode.FindNearest( node.Region, level - 1 ); - Debug.Assert( internalNode != null ); - - internalNode.Add( node ); - - if( internalNode.Count > m_maxNodeSize ) - { - this.ManageOverflow( internalNode ); - } - } - - private IEnumerable FindNodes( TRegion region, int level ) - { - Debug.Assert( !m_helper.IsEmptyRegion( region ) ); - - if( m_rootNode == null ) - yield break; - - var nodeInfos = new Queue(); - nodeInfos.Enqueue( new NodeInfo( m_rootNode, 0 ) ); - - while( nodeInfos.Count > 0 ) - { - var nodeInfo = nodeInfos.Dequeue(); - var node = nodeInfo.Node; - var nodeLevel = nodeInfo.Level; - - if( !m_helper.IsOverlapping( node.Region, region ) ) - continue; - - if( nodeLevel == level ) - { - yield return node; - } - else if( ( level < 0 ) || ( nodeLevel < level ) ) - { - var leafNode = node as LeafNode; - if( leafNode != null ) - { - if( level < 0 ) - yield return leafNode; - } - else - { - foreach( var child in ( InternalNode )node ) - { - nodeInfos.Enqueue( new NodeInfo( child, nodeLevel + 1 ) ); - } - } - } - } - } - - private void ManageOverflow( Node node ) - { - while( node != null ) - { - node = ( node is LeafNode ) - ? this.ManageOverflowCore( ( LeafNode )node ) - : this.ManageOverflowCore( ( InternalNode )node ); - } - } - - private Node ManageOverflowCore( LeafNode node ) - { - Debug.Assert( node.Count > m_maxNodeSize ); - - // It makes no sense to reinsert the entry in the root node. - if( node.Parent != null ) - { - node = this.Reinsert( node ); - if( node == null ) - return null; - } - - // We have no choice but to split the node. - var newNode = node.Split( m_minNodeSize ); - Debug.Assert( newNode != null ); - - // We have splited the root node. A new root is required. - if( node == m_rootNode ) - { - var newRootNode = new InternalNode( m_helper, m_maxNodeSize ); - newRootNode.Add( node ); - newRootNode.Add( newNode ); - - m_rootNode = newRootNode; - } - // Add the new node to the same parent node. - else - { - var parentNode = ( InternalNode )node.Parent; - Debug.Assert( parentNode != null ); - - parentNode.Add( newNode ); - - // Return the parent node if it is overflowing to process it. - if( parentNode.Count > m_maxNodeSize ) - return parentNode; - } - - return null; - } - - private Node ManageOverflowCore( InternalNode node ) - { - Debug.Assert( node.Count > m_maxNodeSize ); - - // It makes no sense to reinsert child nodes in the root node. - if( node.Parent != null ) - { - node = this.Reinsert( node ); - if( node == null ) - return null; - } - - // We have no choice but to split the node. - var newNode = node.Split( m_minNodeSize ); - Debug.Assert( newNode != null ); - - // We have splited the root node. A new root is required. - if( node == m_rootNode ) - { - var newRootNode = new InternalNode( m_helper, m_maxNodeSize ); - newRootNode.Add( node ); - newRootNode.Add( newNode ); - - m_rootNode = newRootNode; - } - // Add the new node to the same parent node. - else - { - var parentNode = ( InternalNode )node.Parent; - Debug.Assert( parentNode != null ); - - parentNode.Add( newNode ); - - // Return the parent node if it is overflowing to process it. - if( parentNode.Count > m_maxNodeSize ) - return parentNode; - } - - return null; - } - - private LeafNode Reinsert( LeafNode node ) - { - Debug.Assert( node != null ); - Debug.Assert( node.Count > m_maxNodeSize ); - - var reinsertCount = System.Math.Min( node.Count - m_minNodeSize, ( int )System.Math.Ceiling( m_maxNodeSize * RSTree.OverflowReInsertionRatio ) ); - if( reinsertCount <= 0 ) - return node; - - Debug.Assert( ( m_minNodeSize <= node.Count - reinsertCount ) && ( reinsertCount <= m_maxNodeSize ) ); - - // Identify the entries that are at the "edge" of current region. - var center = new KPoint( m_helper.CenterOf( node.Region ) ); - var candidates = node.Select( ( entry, entryIndex ) => new - { - Entry = entry, - Index = entryIndex, - Distance = KPoint.Distance( center, new KPoint( m_helper.CenterOf( entry.Region ) ) ) - } ) - .OrderByDescending( item => item.Distance ) - .ThenBy( item => item.Index ) - .Take( reinsertCount ).ToList(); - - // The entries must be removed from last to first to prevent an index shift. - foreach( var item in candidates.OrderByDescending( x => x.Index ) ) - { - node.RemoveAt( item.Index ); - } - - var splitNode = node; - var reinsert = 0; - - while( reinsert < candidates.Count ) - { - var entry = candidates[ reinsert ].Entry; - var newLeafNode = ( LeafNode )m_rootNode.FindNearest( entry.Region ); - Debug.Assert( newLeafNode != null ); - - newLeafNode.Add( entry ); - reinsert++; - - // If a new overflow occur while reinserting entries, stop reinserting in order to split the node. - if( newLeafNode.Count > m_maxNodeSize ) - { - splitNode = newLeafNode; - break; - } - // If the best leaf node for this entry is the original node, so does the remaining entries. - else if( newLeafNode == node ) - { - break; - } - } - - Debug.Assert( ( ( candidates.Count - reinsert ) + node.Count <= m_maxNodeSize ) - || ( ( ( candidates.Count - reinsert ) + node.Count > m_maxNodeSize ) && ( splitNode == node ) ) ); - - // Reinsert the remaining entries in the original node. - for( ; reinsert < candidates.Count; reinsert++ ) - { - node.Add( candidates[ reinsert ].Entry ); - } - - if( splitNode.Count > m_maxNodeSize ) - return splitNode; - - return null; - } - - private InternalNode Reinsert( InternalNode node ) - { - Debug.Assert( node != null ); - Debug.Assert( node.Count > m_maxNodeSize ); - - var reinsertCount = System.Math.Min( node.Count - m_minNodeSize, ( int )System.Math.Ceiling( m_maxNodeSize * RSTree.OverflowReInsertionRatio ) ); - if( reinsertCount <= 0 ) - return node; - - Debug.Assert( ( m_minNodeSize <= node.Count - reinsertCount ) && ( reinsertCount <= m_maxNodeSize ) ); - - // Identify the child nodes that are at the "edge" of current region. - var center = new KPoint( m_helper.CenterOf( node.Region ) ); - var candidates = node.Select( ( childNode, childNodeIndex ) => new - { - Node = childNode, - Index = childNodeIndex, - Distance = KPoint.Distance( center, new KPoint( m_helper.CenterOf( childNode.Region ) ) ) - } ) - .OrderByDescending( item => item.Distance ) - .ThenBy( item => item.Index ) - .Take( reinsertCount ).ToList(); - - // The child nodes must be removed from last to first to prevent an index shift. - foreach( var item in candidates.OrderByDescending( x => x.Index ) ) - { - node.RemoveAt( item.Index ); - } - - var splitNode = node; - var nodeLevel = RSTree.FindLevel( node ); - var reinsert = 0; - - while( reinsert < candidates.Count ) - { - var childNode = candidates[ reinsert ].Node; - var newInternalNode = ( InternalNode )m_rootNode.FindNearest( childNode.Region, nodeLevel ); - Debug.Assert( newInternalNode != null ); - - newInternalNode.Add( childNode ); - reinsert++; - - // If a new overflow occur while reinserting child nodes, stop reinserting in order to split the node. - if( newInternalNode.Count > m_maxNodeSize ) - { - splitNode = newInternalNode; - break; - } - // If the best internal node for this child node is the original node, so does the remaining child nodes. - else if( newInternalNode == node ) - { - break; - } - } - - Debug.Assert( ( ( candidates.Count - reinsert ) + node.Count <= m_maxNodeSize ) - || ( ( ( candidates.Count - reinsert ) + node.Count > m_maxNodeSize ) && ( splitNode == node ) ) ); - - // Reinsert the remaining child nodes in the original node. - for( ; reinsert < candidates.Count; reinsert++ ) - { - node.Add( candidates[ reinsert ].Node ); - } - - if( splitNode.Count > m_maxNodeSize ) - return splitNode; - - return null; - } - - private void ManageUnderflow( Node node ) - { - while( node != null ) - { - node = ( node is LeafNode ) - ? this.ManageUnderflowCore( ( LeafNode )node ) - : this.ManageUnderflowCore( ( InternalNode )node ); - } - } - - private Node ManageUnderflowCore( LeafNode node ) - { - Debug.Assert( node.Count < m_minNodeSize ); - - if( node == m_rootNode ) - { - if( node.Count == 0 ) - { - m_rootNode = null; - } - } - else - { - var parent = ( InternalNode )node.Parent; - Debug.Assert( parent != null ); - - // Remove the current node from the parent node to prevent entries to - // be reinserted within it. - var removed = parent.Remove( node ); - Debug.Assert( removed ); - - // Reinsert the entries in the remaining nodes. - for( int i = node.Count - 1; i >= 0; i-- ) - { - var entry = node[ i ]; - node.RemoveAt( i ); - - this.Insert( entry ); - } - - // Return the parent node if it is underflowing to process it. - if( parent.Count < m_minNodeSize ) - return parent; - } - - return null; - } - - private Node ManageUnderflowCore( InternalNode node ) - { - Debug.Assert( node.Count < m_minNodeSize ); - - if( node == m_rootNode ) - { - Debug.Assert( node.Count > 0 ); - - // Remove an entire level. - if( node.Count == 1 ) - { - var child = node[ 0 ]; - node.RemoveAt( 0 ); - - m_rootNode = child; - } - } - else - { - var level = RSTree.FindLevel( node ); - var parent = ( InternalNode )node.Parent; - Debug.Assert( ( parent != null ) && ( level > 0 ) ); - - // Remove the current node from the parent node to prevent child nodes to - // be reinserted within it. - var removed = parent.Remove( node ); - Debug.Assert( removed ); - - // Reinsert the child nodes in the remaining nodes of the same level. - for( int i = node.Count - 1; i >= 0; i-- ) - { - var child = node[ i ]; - node.RemoveAt( i ); - - this.Insert( child, level + 1 ); - } - - // Return the parent node if it is underflowing to process it. - if( parent.Count < m_minNodeSize ) - return parent; - } - - return null; - } - - private void IncrementVersion() - { - unchecked - { - m_version++; - } - } - - #region ICollection<> Members - - int ICollection.Entry>.Count - { - get - { - return this.Count; - } - } - - bool ICollection.Entry>.IsReadOnly - { - get - { - return false; - } - } - - public void Add( Entry entry ) - { - if( m_helper.IsEmptyRegion( entry.Region ) ) - throw new ArgumentException( "The region must not be empty.", "entry" ); - - this.Insert( entry ); - - m_count++; - this.IncrementVersion(); - } - - public void Clear() - { - m_count = 0; - m_rootNode = null; - - this.IncrementVersion(); - } - - public bool Contains( Entry entry ) - { - if( ( m_rootNode == null ) || m_helper.IsEmptyRegion( entry.Region ) ) - return false; - - return ( from candidate in this.GetEntriesWithin( entry.Region ) - where ( m_helper.AreEquivalent( entry.Region, candidate.Region ) ) - && ( object.Equals( entry.Item, candidate.Item ) ) - select candidate ).Any(); - } - - public bool Remove( Entry entry ) - { - if( ( m_rootNode == null ) || m_helper.IsEmptyRegion( entry.Region ) ) - return false; - - // Get the first LeafNode where the entry was found. - var leafNode = ( from candidate in this.FindNodes( entry.Region, -1 ).Cast() - where candidate.Remove( entry ) - select candidate ).FirstOrDefault(); - if( leafNode == null ) - return false; - - if( leafNode.Count < m_minNodeSize ) - { - this.ManageUnderflow( leafNode ); - } - - m_count--; - this.IncrementVersion(); - - return true; - } - - void ICollection.Entry>.CopyTo( Entry[] array, int index ) - { - ( ( ICollection )this ).CopyTo( array, index ); - } - - #endregion - - #region ICollection Members - - int ICollection.Count - { - get - { - return this.Count; - } - } - - bool ICollection.IsSynchronized - { - get - { - return false; - } - } - - object ICollection.SyncRoot - { - get - { - if( m_syncRoot == null ) - { - Interlocked.CompareExchange( ref m_syncRoot, new object(), null ); - } - - return m_syncRoot; - } - } - - void ICollection.CopyTo( Array array, int index ) - { - if( array == null ) - throw new ArgumentNullException( "array" ); - - if( index < 0 ) - throw new ArgumentOutOfRangeException( "index" ); - - if( array.Rank != 1 ) - throw new ArgumentException( "Multi-dimensional array is not supported.", "array" ); - - if( ( array.Length - index ) < this.Count ) - throw new ArgumentException( "The number of elements is greater than the available space from index to the end of the destination array.", "array" ); - - foreach( var entry in this ) - { - array.SetValue( entry, index++ ); - } - } - - #endregion - - #region IEnumerable<> Members - - public IEnumerator GetEnumerator() - { - return new EntryEnumerator( this ); - } - - #endregion - - #region IEnumerable Members - - IEnumerator IEnumerable.GetEnumerator() - { - return this.GetEnumerator(); - } - - #endregion - - private readonly RSTreeHelper m_helper; - private readonly int m_minNodeSize; - private readonly int m_maxNodeSize; - - private Node m_rootNode; //null - private int m_count; //0 - private int m_version; //0 - private object m_syncRoot; //null - - #region Entry Internal Struct - - internal struct Entry - { - public Entry( TRegion region, TItem item ) - { - m_region = region; - m_item = item; - } - - public TRegion Region - { - get - { - return m_region; - } - } - - public TItem Item - { - get - { - return m_item; - } - } - - public override int GetHashCode() - { - return ( !object.ReferenceEquals( m_item, null ) ) ? m_item.GetHashCode() : 0; - } - - public override bool Equals( object obj ) - { - if( !( obj is Entry ) ) - return false; - - var target = ( Entry )obj; - - return ( object.Equals( target.m_region, m_region ) ) - && ( object.Equals( target.m_item, m_item ) ); - } - - private readonly TRegion m_region; - private readonly TItem m_item; - } - - #endregion - - #region EntryEnumerable Private Class - - private sealed class EntryEnumerable : IEnumerable.Entry> - { - internal EntryEnumerable( RSTree owner, TRegion region ) - { - Debug.Assert( owner != null ); - - m_owner = owner; - m_region = region; - } - - public IEnumerator.Entry> GetEnumerator() - { - return new EntryEnumerator( m_owner, m_region ); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return this.GetEnumerator(); - } - - private readonly RSTree m_owner; - private readonly TRegion m_region; - } - - #endregion - - #region EntryEnumerator Private Class - - private sealed class EntryEnumerator : IEnumerator.Entry> - { - internal EntryEnumerator( RSTree owner, TRegion region ) - : this( owner ) - { - Debug.Assert( !owner.m_helper.IsEmptyRegion( region ) ); - - m_filter = ( TRegion r ) => m_owner.m_helper.IsOverlapping( region, r ); - } - - internal EntryEnumerator( RSTree owner ) - { - Debug.Assert( owner != null ); - - m_owner = owner; - m_version = owner.m_version; - - if( owner.m_rootNode != null ) - { - m_nodes.Enqueue( owner.m_rootNode ); - } - } - - public Entry Current - { - get - { - if( m_entries.Count == 0 ) - throw new InvalidOperationException(); - - return m_entries.Peek(); - } - } - - object IEnumerator.Current - { - get - { - return this.Current; - } - } - - public bool MoveNext() - { - this.CheckVersion(); - - if( m_entries.Count > 0 ) - { - m_entries.Dequeue(); - - if( m_entries.Count > 0 ) - return true; - } - - Debug.Assert( m_entries.Count == 0 ); - - while( m_nodes.Count > 0 ) - { - var node = m_nodes.Dequeue(); - if( ( m_filter != null ) && !m_filter.Invoke( node.Region ) ) - continue; - - var leafNode = node as LeafNode; - if( leafNode != null ) - { - var count = leafNode.Count; - - for( int i = 0; i < count; i++ ) - { - var entry = leafNode[ i ]; - if( ( m_filter != null ) && !m_filter.Invoke( entry.Region ) ) - continue; - - m_entries.Enqueue( entry ); - } - - if( m_entries.Count > 0 ) - return true; - } - else - { - var internalNode = ( InternalNode )node; - var count = internalNode.Count; - - for( int i = 0; i < count; i++ ) - { - m_nodes.Enqueue( internalNode[ i ] ); - } - } - } - - Debug.Assert( m_nodes.Count == 0 ); - Debug.Assert( m_entries.Count == 0 ); - - return false; - } - - public void Reset() - { - this.CheckVersion(); - - m_entries.Clear(); - m_nodes.Clear(); - - if( m_owner.m_rootNode != null ) - { - m_nodes.Enqueue( m_owner.m_rootNode ); - } - } - - void IDisposable.Dispose() - { - } - - private void CheckVersion() - { - if( m_version != m_owner.m_version ) - throw new InvalidOperationException(); - } - - private readonly RSTree m_owner; - private readonly Queue m_nodes = new Queue(); - private readonly Queue m_entries = new Queue(); - private readonly Func m_filter; //null - private int m_version; - } - - #endregion - - #region Node Private Class - - protected abstract class Node : ICollection - { - public abstract int Count - { - get; - } - - internal abstract TRegion Region - { - get; - } - - internal Node Parent - { - get - { - return m_parent; - } - } - - bool ICollection.IsSynchronized - { - get - { - return false; - } - } - - object ICollection.SyncRoot - { - get - { - throw new NotSupportedException(); - } - } - - protected abstract void CopyToCore( Array array, int index ); - protected abstract IEnumerator GetEnumeratorCore(); - - protected void SetParent( Node child, Node parent ) - { - if( ( child == null ) || ( child.m_parent == parent ) ) - return; - - if( child.m_parent != null ) - { - child.m_parent.SliceRegion( child.Region ); - } - - child.m_parent = parent; - - if( parent != null ) - { - parent.MergeRegion( child.Region ); - } - } - - protected internal abstract void MergeRegion( TRegion region ); - protected internal abstract void SliceRegion( TRegion region ); - protected internal abstract void InvalidateRegion(); - - internal abstract Node FindNearest( TRegion region, int level ); - - internal Node FindNearest( TRegion region ) - { - return this.FindNearest( region, -1 ); - } - - internal abstract Node Split( int minNodeSize ); - - void ICollection.CopyTo( Array array, int index ) - { - this.CopyToCore( array, index ); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return this.GetEnumeratorCore(); - } - - private Node m_parent; - } - - #endregion - - #region InternalNode Private Class - - [DebuggerDisplay( "Internal (Count = {Count})" )] - private sealed class InternalNode : Node, IList - { - internal InternalNode( RSTreeHelper helper, int size ) - { - Debug.Assert( helper != null ); - Debug.Assert( size > 0 ); - - m_helper = helper; - m_nodes = new Node[ size + 1 ]; // We reserve one extra space for overflow. - } - - public override int Count - { - get - { - return m_count; - } - } - - internal override TRegion Region - { - get - { - if( !m_regionValid ) - { - m_region = m_helper.GetEmptyRegion(); - - for( int i = 0; i < m_count; i++ ) - { - m_region = m_helper.Union( m_region, m_nodes[ i ].Region ); - } - - m_regionValid = true; - } - - return m_region; - } - } - - public Node this[ int index ] - { - get - { - if( ( index < 0 ) || ( index >= m_count ) ) - throw new ArgumentOutOfRangeException( "index" ); - - return m_nodes[ index ]; - } - set - { - this.SetAt( index, value ); - } - } - - bool ICollection.IsReadOnly - { - get - { - return false; - } - } - - public void Add( Node node ) - { - this.InsertAt( m_count, node ); - } - - public void Insert( int index, Node node ) - { - this.InsertAt( index, node ); - } - - public void RemoveAt( int index ) - { - if( ( index < 0 ) || ( index >= m_count ) ) - throw new ArgumentOutOfRangeException( "index" ); - - var node = m_nodes[ index ]; - - for( int i = index; i < m_count - 1; i++ ) - { - m_nodes[ i ] = m_nodes[ i + 1 ]; - } - - m_nodes[ m_count - 1 ] = null; - m_count--; - - this.SetParent( node, null ); - } - - public bool Remove( Node node ) - { - var index = this.IndexOf( node ); - if( index < 0 ) - return false; - - this.RemoveAt( index ); - return true; - } - - public void Clear() - { - var count = m_count; - var nodes = new Node[ m_nodes.Length ]; - - Array.Copy( m_nodes, 0, nodes, 0, m_count ); - Array.Clear( m_nodes, 0, m_count ); - m_count = 0; - m_regionValid = false; - - for( int i = 0; i < count; i++ ) - { - this.SetParent( nodes[ i ], null ); - } - } - - public int IndexOf( Node node ) - { - if( node == null ) - return -1; - - return Array.IndexOf( m_nodes, node, 0, m_count ); - } - - public bool Contains( Node node ) - { - return ( this.IndexOf( node ) >= 0 ); - } - - public IEnumerator GetEnumerator() - { - for( int i = 0; i < m_count; i++ ) - { - yield return m_nodes[ i ]; - } - } - - protected override void CopyToCore( Array array, int index ) - { - Array.Copy( m_nodes, 0, array, index, m_count ); - } - - protected override IEnumerator GetEnumeratorCore() - { - return this.GetEnumerator(); - } - - protected internal override void MergeRegion( TRegion region ) - { - if( !m_regionValid ) - return; - - var newRegion = m_helper.Union( m_region, region ); - if( m_helper.AreEquivalent( m_region, newRegion ) ) - return; - - m_region = newRegion; - this.InvalidateParentRegion(); - } - - protected internal override void SliceRegion( TRegion region ) - { - if( !m_regionValid || m_helper.IsWithinBounds( m_region, region ) ) - return; - - m_regionValid = false; - this.InvalidateParentRegion(); - } - - protected internal override void InvalidateRegion() - { - if( !m_regionValid ) - return; - - m_regionValid = false; - this.InvalidateParentRegion(); - } - - internal override Node FindNearest( TRegion region, int level ) - { - if( m_count <= 0 ) - throw new InvalidOperationException( "An internal node must have children." ); - - this.CheckChildNodesOfSameType(); - - if( level == 0 ) - return this; - - var childNode = ( m_nodes[ 0 ] is LeafNode ) - ? this.FindLeastOverlapEnlargement( m_nodes, m_count, region ) - : this.FindLeastAreaEnlargement( m_nodes, m_count, region ); - - Debug.Assert( childNode != null ); - - return childNode.FindNearest( region, ( level < 0 ) ? level : level - 1 ); - } - - internal override Node Split( int minNodeSize ) - { - Debug.Assert( m_count == m_nodes.Length ); - - var nodes = ( Node[] )m_nodes.Clone(); - var axis = this.FindSplitAxis( nodes, minNodeSize ); - var index = this.FindSplitIndex( nodes, minNodeSize, axis ); - - this.Clear(); - - for( int i = 0; i < index; i++ ) - { - this.Add( nodes[ i ] ); - } - - var newNode = new InternalNode( m_helper, m_nodes.Length - 1 ); - Debug.Assert( newNode.m_nodes.Length == m_nodes.Length ); - - for( int i = index; i < nodes.Length; i++ ) - { - newNode.Add( nodes[ i ] ); - } - - return newNode; - } - - [Conditional( "DEBUG" )] - private void CheckChildNodesOfSameType() - { - if( m_count <= 0 ) - return; - - var isLeaf = m_nodes[ 0 ] is LeafNode; - - for( int i = 1; i < m_count; i++ ) - { - Debug.Assert( ( m_nodes[ i ] is LeafNode ) == isLeaf ); - } - } - - private void SetAt( int index, Node node ) - { - if( node == null ) - throw new ArgumentNullException( "node" ); - - if( ( index < 0 ) || ( index >= m_count ) ) - throw new ArgumentOutOfRangeException( "index" ); - - if( m_count >= m_nodes.Length ) - throw new InvalidOperationException(); - - var oldNode = m_nodes[ index ]; - m_nodes[ index ] = node; - - this.SetParent( node, this ); - this.SetParent( oldNode, null ); - } - - private void InsertAt( int index, Node node ) - { - if( node == null ) - throw new ArgumentNullException( "node" ); - - if( ( index < 0 ) || ( index > m_count ) ) - throw new ArgumentOutOfRangeException( "index" ); - - if( m_count >= m_nodes.Length ) - throw new InvalidOperationException(); - - for( int i = m_count; i > index; i-- ) - { - m_nodes[ i ] = m_nodes[ i - 1 ]; - } - - m_nodes[ index ] = node; - m_count++; - - this.SetParent( node, this ); - } - - private void InvalidateParentRegion() - { - var parent = this.Parent; - if( parent == null ) - return; - - parent.InvalidateRegion(); - } - - private Node FindLeastOverlapEnlargement( IList nodes, int count, TRegion region ) - { - Debug.Assert( ( nodes != null ) && ( nodes.Count > 0 ) ); - Debug.Assert( nodes.Count >= count ); - - if( count == 1 ) - return nodes[ 0 ]; - - var candidates = new List( 1 ); - var minimum = double.PositiveInfinity; - - for( int i = 0; i < count; i++ ) - { - var candidate = nodes[ i ]; - var newRegion = m_helper.Union( candidate.Region, region ); - var value = 0d; - - for( int j = 0; j < count; j++ ) - { - if( i == j ) - continue; - - value += m_helper.CalculateOverlapEnlargement( newRegion, nodes[ j ].Region ); - } - - if( value < minimum ) - { - candidates.Clear(); - candidates.Add( candidate ); - minimum = value; - } - else if( value == minimum ) - { - candidates.Add( candidate ); - } - } - - if( candidates.Count > 1 ) - return this.FindLeastAreaEnlargement( candidates, candidates.Count, region ); - - return candidates[ 0 ]; - } - - private Node FindLeastAreaEnlargement( IList nodes, int count, TRegion region ) - { - Debug.Assert( ( nodes != null ) && ( nodes.Count > 0 ) ); - Debug.Assert( nodes.Count >= count ); - - if( count == 1 ) - return nodes[ 0 ]; - - var candidates = new List( 1 ); - var minimum = double.PositiveInfinity; - - for( int i = 0; i < count; i++ ) - { - var candidate = nodes[ i ]; - var value = m_helper.CalculateAreaEnlargement( candidate.Region, region ); - - if( value < minimum ) - { - candidates.Clear(); - candidates.Add( candidate ); - minimum = value; - } - else if( value == minimum ) - { - candidates.Add( candidate ); - } - } - - if( candidates.Count > 1 ) - return this.FindSmallestArea( candidates, candidates.Count ); - - return candidates[ 0 ]; - } - - private Node FindSmallestArea( IList nodes, int count ) - { - Debug.Assert( ( nodes != null ) && ( nodes.Count > 0 ) ); - Debug.Assert( nodes.Count >= count ); - - if( count == 1 ) - return nodes[ 0 ]; - - var index = 0; - var minimum = double.PositiveInfinity; - - for( int i = 0; i < count; i++ ) - { - var value = m_helper.CalculateArea( nodes[ i ].Region ); - if( value < minimum ) - { - index = i; - minimum = value; - } - } - - return nodes[ index ]; - } - - private int FindSplitAxis( Node[] nodes, int minNodeSize ) - { - Debug.Assert( ( nodes != null ) && ( nodes.Length == m_count ) ); - - var axis = 0; - var minimum = double.PositiveInfinity; - var dimensions = m_helper.GetDimensions(); - - for( int i = 0; i < dimensions; i++ ) - { - Array.Sort( nodes, new LowerBoundComparer( m_helper, i ) ); - - var value = this.CalculateMargin( nodes, minNodeSize ); - if( value < minimum ) - { - minimum = value; - axis = i; - } - - Array.Sort( nodes, new UpperBoundComparer( m_helper, i ) ); - - value = this.CalculateMargin( nodes, minNodeSize ); - if( value < minimum ) - { - minimum = value; - axis = i; - } - } - - return axis; - } - - private int FindSplitIndex( Node[] nodes, int minNodeSize, int dimension ) - { - Array.Sort( nodes, new LowerBoundComparer( m_helper, dimension ) ); - - var lowerOverlap = double.PositiveInfinity; - var lowerArea = double.PositiveInfinity; - var lowerIndex = this.FindSplitIndex( nodes, minNodeSize, out lowerOverlap, out lowerArea ); - - Array.Sort( nodes, new UpperBoundComparer( m_helper, dimension ) ); - - var upperOverlap = double.PositiveInfinity; - var upperArea = double.PositiveInfinity; - var upperIndex = this.FindSplitIndex( nodes, minNodeSize, out upperOverlap, out upperArea ); - - if( ( upperOverlap < lowerOverlap ) || ( ( upperOverlap == lowerOverlap ) && ( upperArea < lowerArea ) ) ) - return upperIndex; - - Array.Sort( nodes, new LowerBoundComparer( m_helper, dimension ) ); - return lowerIndex; - } - - private int FindSplitIndex( Node[] nodes, int minSize, out double overlap, out double area ) - { - var splitIndex = 0; - - overlap = double.PositiveInfinity; - area = double.PositiveInfinity; - - var maxSize = nodes.Length - minSize; - - for( int i = minSize; i < maxSize; i++ ) - { - var firstRegion = m_helper.GetEmptyRegion(); - for( int j = 0; j < i; j++ ) - { - firstRegion = m_helper.Union( firstRegion, nodes[ j ].Region ); - } - - var secondRegion = m_helper.GetEmptyRegion(); - for( int j = i; j < nodes.Length; j++ ) - { - secondRegion = m_helper.Union( secondRegion, nodes[ j ].Region ); - } - - var currentOverlap = m_helper.CalculateArea( m_helper.Intersect( firstRegion, secondRegion ) ); - var currentArea = m_helper.CalculateArea( firstRegion ) + m_helper.CalculateArea( secondRegion ); - - if( ( currentOverlap < overlap ) || ( ( currentOverlap == overlap ) && ( currentArea < area ) ) ) - { - overlap = currentOverlap; - area = currentArea; - splitIndex = i; - } - } - - return splitIndex; - } - - private double CalculateMargin( IList nodes, int minSize ) - { - var maxSize = nodes.Count - minSize; - var margin = 0d; - - for( int i = minSize; i < maxSize; i++ ) - { - var region = m_helper.GetEmptyRegion(); - for( int j = 0; j < i; j++ ) - { - region = m_helper.Union( region, nodes[ j ].Region ); - } - - margin += m_helper.CalculateMargin( region ); - - region = m_helper.GetEmptyRegion(); - for( int j = i; j < nodes.Count; j++ ) - { - region = m_helper.Union( region, nodes[ j ].Region ); - } - - margin += m_helper.CalculateMargin( region ); - } - - return margin; - } - - void ICollection.CopyTo( Node[] array, int index ) - { - this.CopyToCore( array, index ); - } - - private readonly RSTreeHelper m_helper; - private readonly Node[] m_nodes; - private int m_count; - private TRegion m_region; - private bool m_regionValid; //false - } - - #endregion - - #region LeafNode Private Class - - [DebuggerDisplay( "Leaf (Count = {Count})" )] - private sealed class LeafNode : Node, IList - { - internal LeafNode( RSTreeHelper helper, int size ) - { - Debug.Assert( helper != null ); - Debug.Assert( size > 0 ); - - m_helper = helper; - m_values = new Entry[ size + 1 ]; // We reserve one extra space for overflow. - } - - public override int Count - { - get - { - return m_count; - } - } - - internal override TRegion Region - { - get - { - if( !m_regionValid ) - { - m_region = m_helper.GetEmptyRegion(); - - for( int i = 0; i < m_count; i++ ) - { - m_region = m_helper.Union( m_region, m_values[ i ].Region ); - } - - m_regionValid = true; - } - - return m_region; - } - } - - public Entry this[ int index ] - { - get - { - if( ( index < 0 ) || ( index >= m_count ) ) - throw new ArgumentOutOfRangeException( "index" ); - - return m_values[ index ]; - } - set - { - this.SetAt( index, value ); - } - } - - bool ICollection.IsReadOnly - { - get - { - return false; - } - } - - public void Add( Entry value ) - { - this.InsertAt( m_count, value ); - } - - public void Insert( int index, Entry value ) - { - this.InsertAt( index, value ); - } - - public void RemoveAt( int index ) - { - if( ( index < 0 ) || ( index >= m_count ) ) - throw new ArgumentOutOfRangeException( "index" ); - - var value = m_values[ index ]; - - for( int i = index; i < m_count - 1; i++ ) - { - m_values[ i ] = m_values[ i + 1 ]; - } - - m_values[ m_count - 1 ] = default( Entry ); - m_count--; - - this.PostRemove( value ); - } - - public bool Remove( Entry value ) - { - var index = this.IndexOf( value ); - if( index < 0 ) - return false; - - this.RemoveAt( index ); - return true; - } - - public void Clear() - { - Array.Clear( m_values, 0, m_count ); - m_count = 0; - m_regionValid = false; - } - - public int IndexOf( Entry value ) - { - return Array.IndexOf( m_values, value, 0, m_count ); - } - - public bool Contains( Entry value ) - { - return ( this.IndexOf( value ) >= 0 ); - } - - public IEnumerator GetEnumerator() - { - for( int i = 0; i < m_count; i++ ) - { - yield return m_values[ i ]; - } - } - - protected override void CopyToCore( Array array, int index ) - { - Array.Copy( m_values, 0, array, index, m_count ); - } - - protected override IEnumerator GetEnumeratorCore() - { - return this.GetEnumerator(); - } - - protected internal override void MergeRegion( TRegion region ) - { - if( !m_regionValid ) - return; - - var newRegion = m_helper.Union( m_region, region ); - if( m_helper.AreEquivalent( m_region, newRegion ) ) - return; - - m_region = newRegion; - this.InvalidateParentRegion(); - } - - protected internal override void SliceRegion( TRegion region ) - { - if( !m_regionValid || m_helper.IsWithinBounds( m_region, region ) ) - return; - - m_regionValid = false; - this.InvalidateParentRegion(); - } - - protected internal override void InvalidateRegion() - { - if( !m_regionValid ) - return; - - m_regionValid = false; - this.InvalidateParentRegion(); - } - - internal override Node FindNearest( TRegion region, int level ) - { - return this; - } - - internal override Node Split( int minNodeSize ) - { - Debug.Assert( m_count == m_values.Length ); - - var entries = ( Entry[] )m_values.Clone(); - var axis = this.FindSplitAxis( entries, minNodeSize ); - var index = this.FindSplitIndex( entries, minNodeSize, axis ); - - this.Clear(); - - for( int i = 0; i < index; i++ ) - { - this.Add( entries[ i ] ); - } - - var newNode = new LeafNode( m_helper, m_values.Length - 1 ); - Debug.Assert( newNode.m_values.Length == m_values.Length ); - - for( int i = index; i < entries.Length; i++ ) - { - newNode.Add( entries[ i ] ); - } - - return newNode; - } - - private void SetAt( int index, Entry value ) - { - if( ( index < 0 ) || ( index >= m_count ) ) - throw new ArgumentOutOfRangeException( "index" ); - - if( m_count >= m_values.Length ) - throw new InvalidOperationException(); - - var oldValue = m_values[ index ]; - m_values[ index ] = value; - - this.PostAdd( value ); - this.PostRemove( oldValue ); - } - - private void InsertAt( int index, Entry value ) - { - if( ( index < 0 ) || ( index > m_count ) ) - throw new ArgumentOutOfRangeException( "index" ); - - if( m_count >= m_values.Length ) - throw new InvalidOperationException(); - - for( int i = m_count; i > index; i-- ) - { - m_values[ i ] = m_values[ i - 1 ]; - } - - m_values[ index ] = value; - m_count++; - - this.PostAdd( value ); - } - - private void PostAdd( Entry entry ) - { - this.MergeRegion( entry.Region ); - } - - private void PostRemove( Entry entry ) - { - this.SliceRegion( entry.Region ); - } - - private void InvalidateParentRegion() - { - var parent = this.Parent; - if( parent == null ) - return; - - parent.InvalidateRegion(); - } - - private int FindSplitAxis( Entry[] entries, int minNodeSize ) - { - Debug.Assert( ( entries != null ) && ( entries.Length == m_count ) ); - - var axis = 0; - var minimum = double.PositiveInfinity; - var dimensions = m_helper.GetDimensions(); - - for( int i = 0; i < dimensions; i++ ) - { - Array.Sort( entries, new LowerBoundComparer( m_helper, i ) ); - - var value = this.CalculateMargin( entries, minNodeSize ); - if( value < minimum ) - { - minimum = value; - axis = i; - } - - Array.Sort( entries, new UpperBoundComparer( m_helper, i ) ); - - value = this.CalculateMargin( entries, minNodeSize ); - if( value < minimum ) - { - minimum = value; - axis = i; - } - } - - return axis; - } - - private int FindSplitIndex( Entry[] entries, int minNodeSize, int dimension ) - { - Array.Sort( entries, new LowerBoundComparer( m_helper, dimension ) ); - - var lowerOverlap = double.PositiveInfinity; - var lowerArea = double.PositiveInfinity; - var lowerIndex = this.FindSplitIndex( entries, minNodeSize, out lowerOverlap, out lowerArea ); - - Array.Sort( entries, new UpperBoundComparer( m_helper, dimension ) ); - - var upperOverlap = double.PositiveInfinity; - var upperArea = double.PositiveInfinity; - var upperIndex = this.FindSplitIndex( entries, minNodeSize, out upperOverlap, out upperArea ); - - if( ( upperOverlap < lowerOverlap ) || ( ( upperOverlap == lowerOverlap ) && ( upperArea < lowerArea ) ) ) - return upperIndex; - - Array.Sort( entries, new LowerBoundComparer( m_helper, dimension ) ); - return lowerIndex; - } - - private int FindSplitIndex( Entry[] entries, int minSize, out double overlap, out double area ) - { - var splitIndex = 0; - - overlap = double.PositiveInfinity; - area = double.PositiveInfinity; - - var maxSize = entries.Length - minSize; - - for( int i = minSize; i < maxSize; i++ ) - { - var firstRegion = m_helper.GetEmptyRegion(); - for( int j = 0; j < i; j++ ) - { - firstRegion = m_helper.Union( firstRegion, entries[ j ].Region ); - } - - var secondRegion = m_helper.GetEmptyRegion(); - for( int j = i; j < entries.Length; j++ ) - { - secondRegion = m_helper.Union( secondRegion, entries[ j ].Region ); - } - - var currentOverlap = m_helper.CalculateArea( m_helper.Intersect( firstRegion, secondRegion ) ); - var currentArea = m_helper.CalculateArea( firstRegion ) + m_helper.CalculateArea( secondRegion ); - - if( ( currentOverlap < overlap ) || ( ( currentOverlap == overlap ) && ( currentArea < area ) ) ) - { - overlap = currentOverlap; - area = currentArea; - splitIndex = i; - } - } - - return splitIndex; - } - - private double CalculateMargin( IList entries, int minSize ) - { - var maxSize = entries.Count - minSize; - var margin = 0d; - - for( int i = minSize; i < maxSize; i++ ) - { - var region = m_helper.GetEmptyRegion(); - for( int j = 0; j < i; j++ ) - { - region = m_helper.Union( region, entries[ j ].Region ); - } - - margin += m_helper.CalculateMargin( region ); - - region = m_helper.GetEmptyRegion(); - for( int j = i; j < entries.Count; j++ ) - { - region = m_helper.Union( region, entries[ j ].Region ); - } - - margin += m_helper.CalculateMargin( region ); - } - - return margin; - } - - void ICollection.CopyTo( Entry[] array, int index ) - { - this.CopyToCore( array, index ); - } - - private readonly RSTreeHelper m_helper; - private readonly Entry[] m_values; - private int m_count; - private TRegion m_region; - private bool m_regionValid; //false - } - - #endregion - - #region NodeInfo Private Struct - - private struct NodeInfo - { - internal NodeInfo( Node node, int level ) - { - this.Node = node; - this.Level = level; - } - - internal readonly Node Node; - internal readonly int Level; - } - - #endregion - - #region KPoint Private Struct - - private struct KPoint - { - internal KPoint( params double[] values ) - { - if( values == null ) - throw new ArgumentNullException( "values" ); - - m_values = values; - } - - public int Count - { - get - { - return m_values.Length; - } - } - - public double this[ int index ] - { - get - { - if( ( index < 0 ) || ( index >= m_values.Length ) ) - throw new ArgumentOutOfRangeException( "index" ); - - return m_values[ index ]; - } - } - - public static double Distance( KPoint x, KPoint y ) - { - var xs = x.m_values; - var ys = y.m_values; - - if( xs.Length != ys.Length ) - throw new ArgumentException( "The points must have the same number of values.", "y" ); - - if( ( xs == ys ) || ( xs.Length == 0 ) ) - return 0d; - - if( xs.Length == 1 ) - return System.Math.Abs( xs[ 0 ] - ys[ 0 ] ); - - var squareSum = 0d; - for( int i = 0; i < xs.Length; i++ ) - { - var delta = xs[ i ] - ys[ i ]; - squareSum += delta * delta; - } - - return System.Math.Sqrt( squareSum ); - } - - public override int GetHashCode() - { - var hashCode = 0; - - foreach( var value in m_values ) - { - hashCode *= 13; - hashCode += value.GetHashCode(); - } - - return hashCode; - } - - public override bool Equals( object obj ) - { - if( !( obj is KPoint ) ) - return false; - - var values = ( ( KPoint )obj ).m_values; - if( values == m_values ) - return true; - - if( values.Length != m_values.Length ) - return false; - - for( int i = 0; i < m_values.Length; i++ ) - { - if( values[ i ] != m_values[ i ] ) - return false; - } - - return true; - } - - private readonly double[] m_values; - } - - #endregion - - #region LowerBoundComparer Private Class - - private sealed class LowerBoundComparer : IComparer, IComparer - { - internal LowerBoundComparer( RSTreeHelper helper, int dimension ) - { - Debug.Assert( helper != null ); - - m_helper = helper; - m_dimension = dimension; - } - - int IComparer.Compare( Node x, Node y ) - { - return this.GetValue( x.Region ).CompareTo( this.GetValue( y.Region ) ); - } - - int IComparer.Compare( Entry x, Entry y ) - { - return this.GetValue( x.Region ).CompareTo( this.GetValue( y.Region ) ); - } - - private double GetValue( TRegion region ) - { - Debug.Assert( !m_helper.IsEmptyRegion( region ) ); - - return m_helper.GetValueOf( region, m_dimension ); - } - - private readonly RSTreeHelper m_helper; - private readonly int m_dimension; - } - - #endregion - - #region UpperBoundComparer Private Class - - private sealed class UpperBoundComparer : IComparer, IComparer - { - internal UpperBoundComparer( RSTreeHelper helper, int dimension ) - { - Debug.Assert( helper != null ); - - m_helper = helper; - m_dimension = dimension; - } - - int IComparer.Compare( Node x, Node y ) - { - return this.GetValue( x.Region ).CompareTo( this.GetValue( y.Region ) ); - } - - int IComparer.Compare( Entry x, Entry y ) - { - return this.GetValue( x.Region ).CompareTo( this.GetValue( y.Region ) ); - } - - private double GetValue( TRegion region ) - { - Debug.Assert( !m_helper.IsEmptyRegion( region ) ); - - return m_helper.GetValueOf( region, m_dimension ) + m_helper.GetSizeOf( region, m_dimension ); - } - - private readonly RSTreeHelper m_helper; - private readonly int m_dimension; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/RSTree1D.Generic.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/RSTree1D.Generic.cs deleted file mode 100644 index c6efc0e5..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/RSTree1D.Generic.cs +++ /dev/null @@ -1,171 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Diagnostics; -using System.Globalization; - -namespace Xceed.Utils.Collections -{ - internal sealed class RSTree1D : RSTree.Area, T> - { - internal RSTree1D() - : base( new Helper() ) - { - } - - internal RSTree1D( int minNodeSize, int maxNodeSize ) - : base( new Helper(), minNodeSize, maxNodeSize ) - { - } - - #region Area Internal Struct - - internal struct Area - { - internal static readonly Area Empty = new Area( 0, 0 ); - - internal Area( int index, int length ) - { - Debug.Assert( length >= 0 ); - - this.Index = index; - this.Length = length; - } - - internal bool IsEmpty - { - get - { - return ( this.Length <= 0 ); - } - } - - public override string ToString() - { - if( this.IsEmpty ) - return "Empty"; - - var startIndex = this.Index; - var endIndex = this.Index + this.Length - 1; - - return string.Format( CultureInfo.InvariantCulture, "[{0},{1}]", startIndex, endIndex ); - } - - internal readonly int Index; - internal readonly int Length; - } - - #endregion - - #region Helper Private Class - - private sealed class Helper : RSTreeHelper - { - protected override int Dimensions - { - get - { - return 1; - } - } - - protected override bool AreEqual( Area x, Area y ) - { - return ( x.Index == y.Index ) - && ( x.Length == y.Length ); - } - - protected override bool AreOverlapping( Area x, Area y ) - { - return !this.Intersect( x, y ).IsEmpty; - } - - protected override bool IsWithin( Area source, Area region ) - { - return ( source.Index < region.Index ) - && ( source.Index + source.Length ) > ( region.Index + region.Length ); - } - - protected override bool IsEmpty( Area region ) - { - return region.IsEmpty; - } - - protected override Area CreateEmptyRegion() - { - return Area.Empty; - } - - protected override double GetValue( Area region, int dimension ) - { - return region.Index; - } - - protected override double GetSize( Area region, int dimension ) - { - return region.Length; - } - - protected override double GetArea( Area region ) - { - return region.Length; - } - - protected override double GetMargin( Area region ) - { - return region.Length; - } - - protected override double[] GetCenter( Area region ) - { - return new double[] { region.Index + ( region.Length - 1 ) / 2d }; - } - - protected override Area UnionWith( Area x, Area y ) - { - var index = System.Math.Min( x.Index, y.Index ); - var length = System.Math.Max( x.Index + x.Length, y.Index + y.Length ) - index; - - return new Area( index, length ); - } - - protected override Area IntersectWith( Area x, Area y ) - { - var xs = x.Index; - var xe = xs + x.Length; - var ys = y.Index; - var ye = ys + y.Length; - - if( xs <= ys ) - { - if( xe <= ys ) - return Area.Empty; - - return new Area( ys, System.Math.Min( xe, ye ) - ys ); - } - else - { - if( ye <= xs ) - return Area.Empty; - - return new Area( xs, System.Math.Min( xe, ye ) - xs ); - } - } - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/RSTree2D.Generic.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/RSTree2D.Generic.cs deleted file mode 100644 index 4814d4ba..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/RSTree2D.Generic.cs +++ /dev/null @@ -1,255 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Diagnostics; -using System.Globalization; - -namespace Xceed.Utils.Collections -{ - internal sealed class RSTree2D : RSTree.Area, T> - { - internal RSTree2D() - : base( new Helper() ) - { - } - - internal RSTree2D( int minNodeSize, int maxNodeSize ) - : base( new Helper(), minNodeSize, maxNodeSize ) - { - } - - #region Area Internal Struct - - internal struct Area - { - internal static readonly Area Empty = new Area( 0, 0, 0, 0 ); - - internal Area( int row, int rowLength, int column, int columnLength ) - { - Debug.Assert( ( rowLength >= 0 ) && ( columnLength >= 0 ) ); - - this.Row = row; - this.RowLength = rowLength; - this.Column = column; - this.ColumnLength = columnLength; - } - - internal bool IsEmpty - { - get - { - return ( this.RowLength <= 0 ) - || ( this.ColumnLength <= 0 ); - } - } - - public override string ToString() - { - if( this.IsEmpty ) - return "Empty"; - - var rs = this.Row; - var re = this.Row + this.RowLength - 1; - var cs = this.Column; - var ce = this.Column + this.ColumnLength - 1; - - return string.Format( CultureInfo.InvariantCulture, "[R({0},{1}),C({2},{3})]", rs, re, cs, ce ); - } - - internal readonly int Row; - internal readonly int RowLength; - internal readonly int Column; - internal readonly int ColumnLength; - } - - #endregion - - #region Helper Private Class - - private sealed class Helper : RSTreeHelper - { - protected override int Dimensions - { - get - { - return 2; - } - } - - protected override bool AreEqual( Area x, Area y ) - { - return ( x.Row == y.Row ) - && ( x.RowLength == y.RowLength ) - && ( x.Column == y.Column ) - && ( x.ColumnLength == y.ColumnLength ); - } - - protected override bool AreOverlapping( Area x, Area y ) - { - return !this.Intersect( x, y ).IsEmpty; - } - - protected override bool IsWithin( Area source, Area region ) - { - return ( source.Row < region.Row ) - && ( source.Column < region.Column ) - && ( ( source.Row + source.RowLength ) > ( region.Row + region.RowLength ) ) - && ( ( source.Column + source.ColumnLength ) > ( region.Column + region.ColumnLength ) ); - } - - protected override bool IsEmpty( Area region ) - { - return region.IsEmpty; - } - - protected override Area CreateEmptyRegion() - { - return Area.Empty; - } - - protected override double GetValue( Area region, int dimension ) - { - switch( dimension ) - { - case 0: - return region.Row; - - case 1: - return region.Column; - - default: - throw new InvalidOperationException(); - } - } - - protected override double GetSize( Area region, int dimension ) - { - switch( dimension ) - { - case 0: - return region.RowLength; - - case 1: - return region.ColumnLength; - - default: - throw new InvalidOperationException(); - } - } - - protected override double GetArea( Area region ) - { - return ( region.RowLength * region.ColumnLength ); - } - - protected override double GetMargin( Area region ) - { - return ( region.RowLength + region.ColumnLength ); - } - - protected override double[] GetCenter( Area region ) - { - return new double[] { region.Row + ( region.RowLength - 1 ) / 2d, region.Column + ( region.ColumnLength - 1 ) / 2d }; - } - - protected override Area UnionWith( Area x, Area y ) - { - var xrs = x.Row; - var xrl = x.RowLength; - var xcs = x.Column; - var xcl = x.ColumnLength; - var yrs = y.Row; - var yrl = y.RowLength; - var ycs = y.Column; - var ycl = y.ColumnLength; - - var rs = System.Math.Min( xrs, yrs ); - var cs = System.Math.Min( xcs, ycs ); - var rl = System.Math.Max( xrs + xrl, yrs + yrl ) - rs; - var cl = System.Math.Max( xcs + xcl, ycs + ycl ) - cs; - - return new Area( rs, rl, cs, cl ); - } - - protected override Area IntersectWith( Area x, Area y ) - { - var xrs = x.Row; - var xre = xrs + x.RowLength; - var xcs = x.Column; - var xce = xcs + x.ColumnLength; - var yrs = y.Row; - var yre = yrs + y.RowLength; - var ycs = y.Column; - var yce = ycs + y.ColumnLength; - - int rs, rl, cs, cl; - - if( xrs <= yrs ) - { - if( xre <= yrs ) - return Area.Empty; - - rs = yrs; - - if( xcs <= ycs ) - { - if( xce <= ycs ) - return Area.Empty; - - cs = ycs; - } - else - { - if( yce <= xcs ) - return Area.Empty; - - cs = xcs; - } - } - else - { - if( yre <= xrs ) - return Area.Empty; - - rs = xrs; - - if( xcs <= ycs ) - { - if( xce <= ycs ) - return Area.Empty; - - cs = ycs; - } - else - { - if( yce <= xcs ) - return Area.Empty; - - cs = xcs; - } - } - - rl = System.Math.Min( xre, yre ) - rs; - cl = System.Math.Min( xce, yce ) - cs; - - return new Area( rs, rl, cs, cl ); - } - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/RSTreeHelper.Generic.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/RSTreeHelper.Generic.cs deleted file mode 100644 index b4db49cb..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/RSTreeHelper.Generic.cs +++ /dev/null @@ -1,180 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Diagnostics; - -namespace Xceed.Utils.Collections -{ - internal abstract class RSTreeHelper - { - protected abstract int Dimensions - { - get; - } - - protected abstract double GetArea( T region ); - protected abstract double GetMargin( T region ); - protected abstract double[] GetCenter( T region ); - - protected abstract T UnionWith( T x, T y ); - protected abstract T IntersectWith( T x, T y ); - - protected abstract bool AreEqual( T x, T y ); - protected abstract bool AreOverlapping( T x, T y ); - - protected abstract bool IsWithin( T source, T region ); - protected abstract bool IsEmpty( T region ); - - protected abstract T CreateEmptyRegion(); - - protected abstract double GetValue( T region, int dimension ); - protected abstract double GetSize( T region, int dimension ); - - internal int GetDimensions() - { - return this.Dimensions; - } - - internal bool IsEmptyRegion( T region ) - { - return this.IsEmpty( region ); - } - - internal T GetEmptyRegion() - { - return this.CreateEmptyRegion(); - } - - internal double GetValueOf( T region, int dimension ) - { - Debug.Assert( ( dimension >= 0 ) && ( dimension < this.Dimensions ) ); - return this.GetValue( region, dimension ); - } - - internal double GetSizeOf( T region, int dimension ) - { - Debug.Assert( ( dimension >= 0 ) && ( dimension < this.Dimensions ) ); - return this.GetSize( region, dimension ); - } - - internal bool AreEquivalent( T x, T y ) - { - if( this.IsEmpty( x ) ) - { - return this.IsEmpty( y ); - } - else if( this.IsEmpty( y ) ) - { - return this.IsEmpty( x ); - } - else - { - return this.AreEqual( x, y ); - } - } - - internal bool IsOverlapping( T source, T region ) - { - if( this.IsEmpty( source ) || this.IsEmpty( region ) ) - return false; - - return this.AreOverlapping( source, region ); - } - - internal bool IsWithinBounds( T source, T region ) - { - if( this.IsEmpty( source ) || this.IsEmpty( region ) ) - return false; - - return this.IsWithin( source, region ); - } - - internal double[] CenterOf( T region ) - { - if( this.IsEmpty( region ) ) - throw new InvalidOperationException(); - - var center = this.GetCenter( region ); - Debug.Assert( ( center != null ) && ( center.Length == this.Dimensions ) ); - - return center; - } - - internal T Union( T source, T region ) - { - if( this.IsEmpty( source ) ) - { - return region; - } - else if( this.IsEmpty( region ) ) - { - return source; - } - else - { - return this.UnionWith( source, region ); - } - } - - internal T Intersect( T source, T region ) - { - if( this.IsEmpty( source ) ) - { - return source; - } - else if( this.IsEmpty( region ) ) - { - return region; - } - else - { - return this.IntersectWith( source, region ); - } - } - - internal double CalculateOverlapEnlargement( T source, T region ) - { - return this.CalculateArea( this.Intersect( source, region ) ); - } - - internal double CalculateAreaEnlargement( T source, T region ) - { - var finalArea = this.CalculateArea( this.Union( source, region ) ); - var sourceArea = this.CalculateArea( source ); - - Debug.Assert( finalArea >= sourceArea ); - - return finalArea - sourceArea; - } - - internal double CalculateArea( T region ) - { - if( this.IsEmpty( region ) ) - return 0d; - - return this.GetArea( region ); - } - - internal double CalculateMargin( T region ) - { - if( this.IsEmpty( region ) ) - return 0d; - - return this.GetMargin( region ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/ReadOnlyDictionary.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/ReadOnlyDictionary.cs deleted file mode 100644 index 2cbae59b..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/ReadOnlyDictionary.cs +++ /dev/null @@ -1,172 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Collections; - -namespace Xceed.Utils.Collections -{ - internal class ReadOnlyDictionary : IDictionary - { - #region IDictionary Members - - public virtual void Add( Key key, Value value ) - { - throw new NotSupportedException(); - } - - public virtual bool ContainsKey( Key key ) - { - return m_dictionary.ContainsKey( key ); - } - - public virtual ICollection Keys - { - get - { - return m_dictionary.Keys; - } - } - - public virtual bool Remove( Key key ) - { - throw new NotSupportedException(); - } - - public virtual bool TryGetValue( Key key, out Value value ) - { - return m_dictionary.TryGetValue( key, out value ); - } - - public virtual ICollection Values - { - get - { - return m_dictionary.Values; - } - } - - public virtual Value this[ Key key ] - { - get - { - return m_dictionary[ key ]; - } - set - { - throw new NotSupportedException(); - } - } - - #endregion - - #region ICollection> Members - - public virtual void Add( KeyValuePair item ) - { - throw new NotSupportedException(); - } - - public virtual void Clear() - { - throw new NotSupportedException(); - } - - public virtual bool Contains( KeyValuePair item ) - { - return m_dictionary.Contains( item ); - } - - public void CopyTo( KeyValuePair[] array, int arrayIndex ) - { - throw new NotSupportedException(); - } - - public int Count - { - get - { - return m_dictionary.Count; - } - } - - public bool IsReadOnly - { - get - { - return true; - } - } - - public virtual bool Remove( KeyValuePair item ) - { - throw new NotSupportedException(); - } - - #endregion - - #region IEnumerable> Members - - public virtual IEnumerator> GetEnumerator() - { - throw new NotSupportedException(); - } - - #endregion - - #region IEnumerable Members - - IEnumerator IEnumerable.GetEnumerator() - { - throw new NotSupportedException(); - } - - #endregion - - #region INTERNAL METHODS - - internal virtual void InternalAdd( Key key, Value value ) - { - m_dictionary.Add( key, value ); - } - - internal virtual void InternalClear() - { - m_dictionary.Clear(); - } - - internal virtual bool InternalRemove( Key key ) - { - return m_dictionary.Remove( key ); - } - - internal virtual void InternalSet( Key key, Value value ) - { - m_dictionary[ key ] = value; - } - - #endregion - - #region PRIVATE FIELDS - - Dictionary m_dictionary = new Dictionary(); - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/ReadOnlyObservableHashList.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/ReadOnlyObservableHashList.cs deleted file mode 100644 index a36eb5c1..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/ReadOnlyObservableHashList.cs +++ /dev/null @@ -1,206 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Collections.Specialized; -using System.Collections; -using System.Diagnostics; -using System.ComponentModel; - -namespace Xceed.Utils.Collections -{ - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Design", "CA1039:ListsAreStronglyTyped" )] - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix" )] - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Design", "CA1035:ICollectionImplementationsHaveStronglyTypedMembers" )] - public sealed class ReadOnlyObservableHashList : IList, ICollection, IEnumerable, INotifyCollectionChanged, INotifyPropertyChanged - { - public ReadOnlyObservableHashList() - { - m_hashList = new ObservableHashList(); - - m_hashList.CollectionChanged += new NotifyCollectionChangedEventHandler( this.OnInnerCollectionChanged ); - m_hashList.PropertyChanged += new PropertyChangedEventHandler( this.OnInnerPropertyChanged ); - } - - #region IList Members - - public int Add( object value ) - { - throw new InvalidOperationException( "An attempt was made to add an item to a read-only ObservableHashList." ); - } - - public void Clear() - { - throw new InvalidOperationException( "An attempt was made to clear a read-only ObservableHashList." ); - } - - public bool Contains( object value ) - { - return m_hashList.Contains( value ); - } - - public int IndexOf( object value ) - { - return m_hashList.IndexOf( value ); - } - - public void Insert( int index, object value ) - { - throw new InvalidOperationException( "An attempt was made to insert an item into a read-only ObservableHashList." ); - } - - public bool IsFixedSize - { - get - { - return m_hashList.IsFixedSize; - } - } - - public bool IsReadOnly - { - get - { - return true; - } - } - - public void Remove( object value ) - { - throw new InvalidOperationException( "An attempt was made to remove an item from a read-only ObservableHashList." ); - } - - public void RemoveAt( int index ) - { - throw new InvalidOperationException( "An attempt was made to remove an item from a read-only ObservableHashList." ); - } - - public object this[ int index ] - { - get - { - return m_hashList[ index ]; - } - set - { - throw new InvalidOperationException( "An attempt was made to replace an item in a read-only ObservableHashList." ); - } - } - - #endregion - - #region ICollection Members - - public void CopyTo( Array array, int index ) - { - m_hashList.CopyTo( array, index ); - } - - public int Count - { - get - { - return m_hashList.Count; - } - } - - public bool IsSynchronized - { - get - { - return m_hashList.IsSynchronized; - } - } - - public object SyncRoot - { - get - { - return m_hashList.SyncRoot; - } - } - - #endregion - - #region IEnumerable Members - - public IEnumerator GetEnumerator() - { - return m_hashList.GetEnumerator(); - } - - #endregion - - #region INotifyCollectionChanged Members - - public event NotifyCollectionChangedEventHandler CollectionChanged; - - private void OnCollectionChanged( NotifyCollectionChangedEventArgs args ) - { - if( this.CollectionChanged != null ) - this.CollectionChanged( this, args ); - } - - #endregion - - #region INotifyPropertyChanged Members - - public event PropertyChangedEventHandler PropertyChanged; - - private void OnPropertyChanged( PropertyChangedEventArgs args ) - { - if( this.PropertyChanged != null ) - this.PropertyChanged( this, args ); - } - - #endregion - - #region INTERNAL PROPERTIES - - internal ObservableHashList InnerObservableHashList - { - get - { - return m_hashList; - } - } - - - #endregion - - #region PRIVATE METHODS - - private void OnInnerCollectionChanged( object sender, NotifyCollectionChangedEventArgs e ) - { - this.OnCollectionChanged( e ); - } - - private void OnInnerPropertyChanged( object sender, PropertyChangedEventArgs e ) - { - this.OnPropertyChanged( e ); - } - - #endregion - - #region PRIVATE FIELDS - - private ObservableHashList m_hashList; // = null - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/WeakDictionary.Generic.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/WeakDictionary.Generic.cs deleted file mode 100644 index 0b50b58f..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Collections/WeakDictionary.Generic.cs +++ /dev/null @@ -1,987 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Threading; - -namespace Xceed.Utils.Collections -{ - internal sealed class WeakDictionary : IDictionary, ICollection - { - internal WeakDictionary() - : this( 0, null ) - { - } - - internal WeakDictionary( int capacity ) - : this( capacity, null ) - { - } - - internal WeakDictionary( IEqualityComparer comparer ) - : this( 0, comparer ) - { - } - - internal WeakDictionary( int capacity, IEqualityComparer comparer ) - { - if( capacity < 0 ) - throw new ArgumentOutOfRangeException( "capacity" ); - - if( capacity > 0 ) - { - this.EnsureCapacity( capacity ); - } - - m_comparer = comparer ?? EqualityComparer.Default; - m_creator = WeakDictionary.GetCreator(); - - Debug.Assert( m_comparer != null ); - Debug.Assert( m_creator != null ); - } - - #region Count Property - - public int Count - { - get - { - return m_size; - } - } - - #endregion - - #region Keys Property - - public ICollection Keys - { - get - { - if( m_keys == null ) - { - m_keys = new KeyCollection( this ); - } - - return m_keys; - } - } - - #endregion - - #region Values Property - - public ICollection Values - { - get - { - if( m_values == null ) - { - m_values = new ValueCollection( this ); - } - - return m_values; - } - } - - #endregion - - public void Add( TKey key, TValue value ) - { - if( object.ReferenceEquals( key, null ) ) - throw new ArgumentNullException( "key" ); - - if( this.ContainsKey( key ) ) - throw new ArgumentException(); - - this.AddCore( key, value ); - } - - public bool ContainsKey( TKey key ) - { - TValue unused; - - return this.TryGetValue( key, out unused ); - } - - public bool Remove( TKey key ) - { - if( object.ReferenceEquals( key, null ) ) - throw new ArgumentNullException( "key" ); - - return this.Remove( key, default( TValue ), false ); - } - - public void Clear() - { - if( m_size <= 0 ) - return; - - Debug.Assert( m_buckets != null ); - Debug.Assert( m_entries != null ); - Debug.Assert( m_entriesInfo != null ); - Debug.Assert( m_entries.Length == m_entriesInfo.Length ); - - for( int i = 0; i < m_buckets.Length; i++ ) - { - m_buckets[ i ] = -1; - } - - for( int i = 0; i < m_entries.Length; i++ ) - { - m_entries[ i ] = null; - m_entriesInfo[ i ] = new EntryInfo( ( i < m_entries.Length - 1 ) ? i + 1 : -1 ); - } - - m_size = 0; - m_free = 0; - - unchecked - { - m_version++; - } - } - - public bool TryGetValue( TKey key, out TValue value ) - { - if( object.ReferenceEquals( key, null ) ) - throw new ArgumentNullException( "key" ); - - value = default( TValue ); - - var bucket = default( int ); - var index = default( int ); - var previous = default( int ); - - return this.FindKey( key, out bucket, out index, out previous, out value ); - } - - private bool FindKey( TKey key, out int bucket, out int index, out int previous, out TValue value ) - { - Debug.Assert( !object.ReferenceEquals( key, null ) ); - - bucket = -1; - index = -1; - previous = -1; - value = default( TValue ); - - if( m_size <= 0 ) - return false; - - Debug.Assert( m_buckets != null ); - Debug.Assert( m_entries != null ); - Debug.Assert( m_entriesInfo != null ); - - var hashCode = m_comparer.GetHashCode( key ); - - bucket = this.GetBucket( hashCode ); - Debug.Assert( ( bucket >= 0 ) && ( bucket < m_buckets.Length ) ); - - index = m_buckets[ bucket ]; - previous = -1; - - while( index >= 0 ) - { - var entryInfo = m_entriesInfo[ index ]; - if( entryInfo.HashCode == hashCode ) - { - TKey targetKey; - var entry = m_entries[ index ]; - - Debug.Assert( !WeakDictionary.IsFree( entry ) ); - - if( entry.TryGetKeyValue( out targetKey, out value ) && m_comparer.Equals( targetKey, key ) ) - return true; - } - - previous = index; - index = entryInfo.Next; - } - - bucket = -1; - index = -1; - previous = -1; - - return false; - } - - private bool ContainsValue( TValue value ) - { - if( m_size <= 0 ) - return false; - - Debug.Assert( m_entries != null ); - - var comparer = EqualityComparer.Default; - - for( int i = 0; i < m_entries.Length; i++ ) - { - var entry = m_entries[ i ]; - if( WeakDictionary.IsFree( entry ) ) - continue; - - TKey targetKey; - TValue targetValue; - if( !entry.TryGetKeyValue( out targetKey, out targetValue ) ) - continue; - - if( comparer.Equals( targetValue, value ) ) - return true; - } - - return false; - } - - private bool Remove( TKey key, TValue value, bool compareValue ) - { - Debug.Assert( !object.ReferenceEquals( key, null ) ); - - var bucket = default( int ); - var index = default( int ); - var previous = default( int ); - var targetValue = default( TValue ); - - if( !this.FindKey( key, out bucket, out index, out previous, out targetValue ) ) - return false; - - if( compareValue && !EqualityComparer.Default.Equals( value, targetValue ) ) - return false; - - this.RemoveCore( bucket, index, previous ); - - return true; - } - - private void AddCore( TKey key, TValue value ) - { - Debug.Assert( !object.ReferenceEquals( key, null ) ); - - this.EnsureCapacity(); - Debug.Assert( m_buckets != null ); - Debug.Assert( m_entries != null ); - Debug.Assert( m_entriesInfo != null ); - Debug.Assert( m_free >= 0 ); - - var index = m_free; - var hashCode = m_comparer.GetHashCode( key ); - var bucket = this.GetBucket( hashCode ); - - m_free = m_entriesInfo[ index ].Next; - m_entries[ index ] = m_creator.Invoke( key, value ); - m_entriesInfo[ index ] = new EntryInfo( hashCode, m_buckets[ bucket ] ); - m_buckets[ bucket ] = index; - m_size++; - - unchecked - { - m_version++; - } - } - - private void RemoveCore( int bucket, int index, int previous ) - { - Debug.Assert( ( bucket >= 0 ) && ( bucket < m_buckets.Length ) ); - Debug.Assert( ( index >= 0 ) && ( index < m_entries.Length ) ); - Debug.Assert( previous < m_entries.Length ); - - var next = m_entriesInfo[ index ].Next; - - if( m_buckets[ bucket ] == index ) - { - Debug.Assert( previous < 0 ); - - m_buckets[ bucket ] = next; - } - else - { - Debug.Assert( previous >= 0 ); - Debug.Assert( m_entriesInfo[ previous ].Next == index ); - - m_entriesInfo[ previous ] = m_entriesInfo[ previous ].SetNext( next ); - } - - m_entries[ index ] = null; - m_entriesInfo[ index ] = new EntryInfo( m_free ); - m_free = index; - m_size--; - - unchecked - { - m_version++; - } - } - - private int GetBucket( int hashCode ) - { - return WeakDictionary.GetBucket( hashCode, m_capacity ); - } - - private void EnsureCapacity() - { - // Make sure the collection is not full. - if( m_size != m_capacity ) - return; - - this.EnsureCapacity( m_capacity * 2L ); - Debug.Assert( m_free >= 0 ); - Debug.Assert( m_size != m_capacity ); - } - - private void EnsureCapacity( long min ) - { - if( ( m_capacity >= min ) && ( m_capacity > 0 ) ) - return; - - this.RemoveDeadEntries(); - - if( m_size * 2L < m_capacity ) - return; - - var capacity = WeakDictionary.FindNextSize( min ); - Debug.Assert( capacity > 0 ); - - m_buckets = new int[ capacity ]; - - Array.Resize( ref m_entries, capacity ); - Array.Resize( ref m_entriesInfo, capacity ); - - for( int i = 0; i < m_buckets.Length; i++ ) - { - m_buckets[ i ] = -1; - } - - for( int i = m_capacity; i < capacity; i++ ) - { - m_entries[ i ] = null; - m_entriesInfo[ i ] = new EntryInfo( ( i < capacity - 1 ) ? i + 1 : -1 ); - } - - // Rehash the elements to initialize the buckets. - for( int i = 0; i < m_capacity; i++ ) - { - // Do not rehash free entries. - if( WeakDictionary.IsFree( m_entries[ i ] ) ) - continue; - - var entryInfo = m_entriesInfo[ i ]; - var bucket = WeakDictionary.GetBucket( entryInfo.HashCode, capacity ); - Debug.Assert( ( bucket >= 0 ) && ( bucket < capacity ) ); - - var index = m_buckets[ bucket ]; - - m_buckets[ bucket ] = i; - m_entriesInfo[ i ] = entryInfo.SetNext( index ); - } - - // Link the remaining free entries to the newly created free entries. - if( m_free >= 0 ) - { - var index = m_free; - - while( true ) - { - var next = m_entriesInfo[ index ].Next; - if( next < 0 ) - { - m_entriesInfo[ index ] = new EntryInfo( m_capacity ); - break; - } - - index = next; - } - } - else - { - m_free = m_capacity; - } - - m_capacity = capacity; - - unchecked - { - m_version++; - } - } - - private void RemoveDeadEntries() - { - if( m_capacity <= 0 ) - return; - - Debug.Assert( m_buckets != null ); - Debug.Assert( m_entries != null ); - Debug.Assert( m_entriesInfo != null ); - - for( int bucket = 0; bucket < m_buckets.Length; bucket++ ) - { - var index = m_buckets[ bucket ]; - var previous = -1; - - while( index >= 0 ) - { - var entry = m_entries[ index ]; - var entryInfo = m_entriesInfo[ index ]; - var next = entryInfo.Next; - - Debug.Assert( !WeakDictionary.IsFree( entry ) ); - - TKey targetKey; - TValue targetValue; - - if( !entry.TryGetKeyValue( out targetKey, out targetValue ) ) - { - this.RemoveCore( bucket, index, previous ); - } - else - { - previous = index; - } - - index = next; - } - } - } - - private static int FindNextSize( long min ) - { - var sizes = ArrayHelper.Sizes; - - for( int i = 0; i < sizes.Length; i++ ) - { - var size = sizes[ i ]; - - if( size >= min ) - return size; - } - - throw new InvalidOperationException( "Cannot find a larger size." ); - } - - private static int GetBucket( int hashCode, int capacity ) - { - Debug.Assert( capacity > 0 ); - - // Remove the negative sign without using Math.Abs to handle the case of int.MinValue. - return ( hashCode & 0x7fffffff ) % capacity; - } - - private static bool IsFree( Entry entry ) - { - return ( entry == null ); - } - - private static Func GetCreator() - { - var isKeyRef = !typeof( TKey ).IsValueType; - var isValueRef = !typeof( TValue ).IsValueType; - - if( isKeyRef && isValueRef ) - return ( k, v ) => new WWEntry( k, v ); - - if( isKeyRef ) - return ( k, v ) => new WHEntry( k, v ); - - if( isValueRef ) - return ( k, v ) => new HWEntry( k, v ); - - return ( k, v ) => new HHEntry( k, v ); - } - - #region IDictionary<> Members - - TValue IDictionary.this[ TKey key ] - { - get - { - throw new NotSupportedException(); - } - set - { - throw new NotSupportedException(); - } - } - - #endregion - - #region ICollection<> Members - - bool ICollection>.IsReadOnly - { - get - { - return false; - } - } - - void ICollection>.Add( KeyValuePair item ) - { - var key = item.Key; - if( object.ReferenceEquals( key, null ) ) - throw new ArgumentException( "item" ); - - this.Add( key, item.Value ); - } - - bool ICollection>.Contains( KeyValuePair item ) - { - var key = item.Key; - if( object.ReferenceEquals( key, null ) ) - throw new ArgumentException( "item" ); - - TValue value; - - if( !this.TryGetValue( key, out value ) ) - return false; - - return EqualityComparer.Default.Equals( item.Value, value ); - } - - void ICollection>.CopyTo( KeyValuePair[] array, int index ) - { - throw new NotSupportedException(); - } - - bool ICollection>.Remove( KeyValuePair item ) - { - var key = item.Key; - if( object.ReferenceEquals( key, null ) ) - throw new ArgumentException( "item" ); - - return this.Remove( key, item.Value, true ); - } - - #endregion - - #region ICollection Members - - bool ICollection.IsSynchronized - { - get - { - return false; - } - } - - object ICollection.SyncRoot - { - get - { - if( m_syncRoot == null ) - { - Interlocked.CompareExchange( ref m_syncRoot, new object(), null ); - Debug.Assert( m_syncRoot != null ); - } - - return m_syncRoot; - } - } - - void ICollection.CopyTo( Array array, int index ) - { - throw new NotSupportedException(); - } - - #endregion - - #region IEnumerable<> Members - - public IEnumerator> GetEnumerator() - { - if( m_capacity <= 0 ) - yield break; - - Debug.Assert( m_entries != null ); - - var version = m_version; - - for( int i = 0; i < m_entries.Length; i++ ) - { - var entry = m_entries[ i ]; - - if( !WeakDictionary.IsFree( entry ) ) - { - TKey key; - TValue value; - - if( entry.TryGetKeyValue( out key, out value ) ) - yield return new KeyValuePair( key, value ); - } - - if( version != m_version ) - throw new InvalidOperationException(); - } - } - - #endregion - - #region IEnumerable Members - - IEnumerator IEnumerable.GetEnumerator() - { - return this.GetEnumerator(); - } - - #endregion - - private readonly IEqualityComparer m_comparer; - private readonly Func m_creator; - private ICollection m_keys; //null - private ICollection m_values; //null - private object m_syncRoot; - private int[] m_buckets; - private Entry[] m_entries; - private EntryInfo[] m_entriesInfo; - private int m_capacity; //0 - private int m_size; //0 - private int m_free = -1; - private int m_version; //0 - - #region Entry Private Class - - private abstract class Entry - { - internal abstract bool TryGetKey( out TKey value ); - internal abstract bool TryGetValue( out TValue value ); - - internal bool TryGetKeyValue( out TKey key, out TValue value ) - { - if( this.TryGetKey( out key ) ) - return this.TryGetValue( out value ); - - value = default( TValue ); - - return false; - } - } - - #endregion - - #region WWEntry Private Class - - private sealed class WWEntry : Entry - { - internal WWEntry( TKey key, TValue value ) - { - Debug.Assert( !object.ReferenceEquals( key, null ) ); - - m_key = new WeakReference( key ); - m_value = ( object.ReferenceEquals( value, null ) ) - ? null - : new WeakReference( value ); - } - - internal override bool TryGetKey( out TKey value ) - { - value = ( TKey )m_key.Target; - - return !object.ReferenceEquals( value, null ); - } - - internal override bool TryGetValue( out TValue value ) - { - if( m_value != null ) - { - value = ( TValue )m_value.Target; - - return !object.ReferenceEquals( value, null ); - } - - value = default( TValue ); - return true; - } - - private readonly WeakReference m_key; - private readonly WeakReference m_value; - } - - #endregion - - #region WHEntry Private Class - - private sealed class WHEntry : Entry - { - internal WHEntry( TKey key, TValue value ) - { - Debug.Assert( !object.ReferenceEquals( key, null ) ); - - m_key = new WeakReference( key ); - m_value = value; - } - - internal override bool TryGetKey( out TKey value ) - { - value = ( TKey )m_key.Target; - - return !object.ReferenceEquals( value, null ); - } - - internal override bool TryGetValue( out TValue value ) - { - value = m_value; - return true; - } - - private readonly WeakReference m_key; - private readonly TValue m_value; - } - - #endregion - - #region HWEntry Private Class - - private sealed class HWEntry : Entry - { - internal HWEntry( TKey key, TValue value ) - { - m_key = key; - m_value = ( object.ReferenceEquals( value, null ) ) - ? null - : new WeakReference( value ); - } - - internal override bool TryGetKey( out TKey value ) - { - value = m_key; - return true; - } - - internal override bool TryGetValue( out TValue value ) - { - if( m_value != null ) - { - value = ( TValue )m_value.Target; - - return !object.ReferenceEquals( value, null ); - } - - value = default( TValue ); - return true; - } - - private readonly TKey m_key; - private readonly WeakReference m_value; - } - - #endregion - - #region HHEntry Private Class - - private sealed class HHEntry : Entry - { - internal HHEntry( TKey key, TValue value ) - { - m_key = key; - m_value = value; - } - - internal override bool TryGetKey( out TKey value ) - { - value = m_key; - return true; - } - - internal override bool TryGetValue( out TValue value ) - { - value = m_value; - return true; - } - - private readonly TKey m_key; - private readonly TValue m_value; - } - - #endregion - - #region EntryInfo Private Struct - - [DebuggerDisplay( "HashCode = {HashCode}, Next = {Next}" )] - private struct EntryInfo - { - internal EntryInfo( int hashCode, int next ) - { - m_hashCode = hashCode; - m_next = next; - } - - internal EntryInfo( int next ) - : this( 0, next ) - { - } - - internal int HashCode - { - get - { - return m_hashCode; - } - } - - internal int Next - { - get - { - return m_next; - } - } - - internal EntryInfo SetNext( int next ) - { - return new EntryInfo( m_hashCode, next ); - } - - private readonly int m_hashCode; - private readonly int m_next; - } - - #endregion - - #region KeyCollection Private Class - - private sealed class KeyCollection : ICollection - { - internal KeyCollection( WeakDictionary owner ) - { - Debug.Assert( owner != null ); - m_owner = owner; - } - - public int Count - { - get - { - return m_owner.Count; - } - } - - bool ICollection.IsReadOnly - { - get - { - return true; - } - } - - void ICollection.Add( TKey item ) - { - throw new NotSupportedException(); - } - - void ICollection.Clear() - { - throw new NotSupportedException(); - } - - public bool Contains( TKey item ) - { - return m_owner.ContainsKey( item ); - } - - void ICollection.CopyTo( TKey[] array, int index ) - { - throw new NotSupportedException(); - } - - bool ICollection.Remove( TKey item ) - { - throw new NotSupportedException(); - } - - public IEnumerator GetEnumerator() - { - return m_owner.Select( item => item.Key ).GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return this.GetEnumerator(); - } - - private readonly WeakDictionary m_owner; - } - - #endregion - - #region ValueCollection Private Class - - private sealed class ValueCollection : ICollection - { - internal ValueCollection( WeakDictionary owner ) - { - Debug.Assert( owner != null ); - m_owner = owner; - } - - public int Count - { - get - { - return m_owner.Count; - } - } - - bool ICollection.IsReadOnly - { - get - { - return true; - } - } - - void ICollection.Add( TValue item ) - { - throw new NotSupportedException(); - } - - void ICollection.Clear() - { - throw new NotSupportedException(); - } - - public bool Contains( TValue item ) - { - return m_owner.ContainsValue( item ); - } - - void ICollection.CopyTo( TValue[] array, int arrayIndex ) - { - throw new NotSupportedException(); - } - - bool ICollection.Remove( TValue item ) - { - throw new NotSupportedException(); - } - - public IEnumerator GetEnumerator() - { - return m_owner.Select( item => item.Value ).GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return this.GetEnumerator(); - } - - private readonly WeakDictionary m_owner; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Data/BoolDataStore.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Data/BoolDataStore.cs deleted file mode 100644 index 52b4482b..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Data/BoolDataStore.cs +++ /dev/null @@ -1,83 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Utils.Data -{ - internal sealed class BoolDataStore : DataStore - { - public BoolDataStore( int initialCapacity ) - { - this.SetCapacity( initialCapacity ); - } - - public override object GetData( int recordIndex ) - { - switch( m_values[ recordIndex ] ) - { - case BoolDataStoreValue.False: - return false; - - case BoolDataStoreValue.True: - return true; - } - - return null; - } - - public override void SetData( int recordIndex, object data ) - { - if( ( data == null ) || ( data == DBNull.Value ) ) - { - m_values[ recordIndex ] = BoolDataStoreValue.Null; - return; - } - - if( data is bool ) - { - m_values[ recordIndex ] = ( ( bool )data ) ? BoolDataStoreValue.True : BoolDataStoreValue.False; - return; - } - - throw new ArgumentException( "The data must be of " + typeof( bool ).ToString() + " type or null (Nothing in Visual Basic).", "data" ); - } - - public override int Compare( int xRecordIndex, int yRecordIndex ) - { - return ( m_values[ xRecordIndex ] - m_values[ yRecordIndex ] ); - } - - public override void SetCapacity( int capacity ) - { - BoolDataStoreValue[] newValues = new BoolDataStoreValue[ capacity ]; - - if( m_values != null ) - Array.Copy( m_values, 0, newValues, 0, System.Math.Min( capacity, m_values.Length ) ); - - m_values = newValues; - } - - private BoolDataStoreValue[] m_values; - } - - internal enum BoolDataStoreValue : sbyte - { - Null = 0, - False = 1, - True = 2 - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Data/DataStore.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Data/DataStore.cs deleted file mode 100644 index 420a52aa..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Data/DataStore.cs +++ /dev/null @@ -1,32 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; - -namespace Xceed.Utils.Data -{ - // When deriving from that class, ensure that the initial SetCapacity call is - // setting the value to Null ( DefaultValue ) - internal abstract class DataStore - { - public abstract int Compare( int xRecordIndex, int yRecordIndex ); - - public abstract object GetData( int recordIndex ); - public abstract void SetData( int recordIndex, object data ); - public abstract void SetCapacity( int capacity ); - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Data/ObjectDataStore.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Data/ObjectDataStore.cs deleted file mode 100644 index 1247255e..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Data/ObjectDataStore.cs +++ /dev/null @@ -1,84 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; - -namespace Xceed.Utils.Data -{ - internal sealed class ObjectDataStore : DataStore - { - public ObjectDataStore( int initialCapacity ) - { - this.SetCapacity( initialCapacity ); - } - - public override object GetData( int index ) - { - return m_values[ index ]; - } - - public override void SetData( int index, object data ) - { - m_values[ index ] = data; - } - - public override int Compare( int xRecordIndex, int yRecordIndex ) - { - object xData = m_values[ xRecordIndex ]; - object yData = m_values[ yRecordIndex ]; - - return ObjectDataStore.CompareData( xData, yData ); - } - - public override void SetCapacity( int capacity ) - { - object[] newValues = new object[ capacity ]; - - if( m_values != null ) - Array.Copy( m_values, 0, newValues, 0, System.Math.Min( capacity, m_values.Length ) ); - - m_values = newValues; - } - - public static int CompareData( object xData, object yData ) - { - // Code in there should be indentical to ObjectComparer.Compare - - if( ( xData == null ) || ( xData == DBNull.Value ) ) - { - if( ( yData != null ) && ( yData != DBNull.Value ) ) - { - return -1; - } - } - else - { - if( ( yData == null ) || ( yData == DBNull.Value ) ) - return 1; - - IComparable xDataComparer = xData as IComparable; - - if( xDataComparer != null ) - return xDataComparer.CompareTo( yData ); - } - - return 0; - } - - private object[] m_values; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Data/StringDataStore.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Data/StringDataStore.cs deleted file mode 100644 index a50c7c6f..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Data/StringDataStore.cs +++ /dev/null @@ -1,58 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Globalization; - -namespace Xceed.Utils.Data -{ - internal sealed class StringDataStore : DataStore - { - public StringDataStore( int initialCapacity ) - { - this.SetCapacity( initialCapacity ); - } - - public override object GetData( int index ) - { - return m_values[ index ]; - } - - public override void SetData( int index, object data ) - { - m_values[ index ] = data as string; - } - - public override int Compare( int xRecordIndex, int yRecordIndex ) - { - return CultureInfo.CurrentCulture.CompareInfo.Compare( - m_values[ xRecordIndex ], m_values[ yRecordIndex ], CompareOptions.None ); - } - - public override void SetCapacity( int capacity ) - { - string[] newValues = new string[ capacity ]; - - if( m_values != null ) - Array.Copy( m_values, 0, newValues, 0, System.Math.Min( capacity, m_values.Length ) ); - - m_values = newValues; - } - - private string[] m_values; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Data/ValueTypeDataStore.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Data/ValueTypeDataStore.cs deleted file mode 100644 index c4273c70..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Data/ValueTypeDataStore.cs +++ /dev/null @@ -1,105 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Diagnostics; -using System.Collections.Generic; -using System.Text; - -namespace Xceed.Utils.Data -{ - internal sealed class ValueTypeDataStore : DataStore - where T : struct - { - public ValueTypeDataStore( int initialCapacity ) - { - this.SetCapacity( initialCapacity ); - } - - public override int Compare( int xRecordIndex, int yRecordIndex ) - { - if( m_valuesIsNull[ xRecordIndex ] == ValueNull ) - { - if( m_valuesIsNull[ yRecordIndex ] == ValueNull ) - { - return 0; - } - else - { - return -1; - } - } - else - { - if( m_valuesIsNull[ yRecordIndex ] == ValueNull ) - { - return 1; - } - } - - return Comparer.Default.Compare( m_values[ xRecordIndex ], m_values[ yRecordIndex ] ); - } - - public override object GetData( int recordIndex ) - { - if( m_valuesIsNull[ recordIndex ] == ValueNull ) - return null; - - return m_values[ recordIndex ]; - } - - public override void SetData( int recordIndex, object data ) - { - if( ( data == null ) || ( data == DBNull.Value ) ) - { - m_valuesIsNull[ recordIndex ] = ValueNull; - return; - } - - if( data is T ) - { - m_valuesIsNull[ recordIndex ] = ValueNotNull; - m_values[ recordIndex ] = ( T )data; - return; - } - - throw new ArgumentException( "The data must be of " + typeof( T ).ToString() + " type or null (Nothing in Visual Basic).", "data" ); - } - - public override void SetCapacity( int capacity ) - { - T[] newValues = new T[ capacity ]; - byte[] newValuesIsNull = new byte[ capacity ]; - - if( m_values != null ) - { - int copyCount = System.Math.Min( capacity, m_values.Length ); - Array.Copy( m_values, 0, newValues, 0, copyCount ); - Debug.Assert( ( m_valuesIsNull != null ) && ( m_valuesIsNull.Length == m_values.Length ) ); - Array.Copy( m_valuesIsNull, 0, newValuesIsNull, 0, copyCount ); - } - - m_values = newValues; - m_valuesIsNull = newValuesIsNull; - } - - private const byte ValueNull = 0; - private const byte ValueNotNull = 1; - - private T[] m_values; - private byte[] m_valuesIsNull; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Math/DoubleUtil.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Math/DoubleUtil.cs deleted file mode 100644 index 1afb14d1..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Math/DoubleUtil.cs +++ /dev/null @@ -1,42 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Xceed.Utils.Math -{ - internal static class DoubleUtil - { - public static bool AreClose( double value1, double value2 ) - { - if( value1 == value2 ) - { - return true; - } - - double num1 = value1 - value2; - - if( num1 < 1.53E-06 ) - { - return ( num1 > -1.53E-06 ); - } - - return false; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/PropertyHelper.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/PropertyHelper.cs deleted file mode 100644 index db465ea6..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/PropertyHelper.cs +++ /dev/null @@ -1,36 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Linq.Expressions; - -namespace Xceed.Wpf.DataGrid.Utils -{ - internal static class PropertyHelper - { - internal static string GetPropertyName( Expression> expression ) - { - if( expression == null ) - throw new ArgumentNullException( "expression" ); - - var memberExpression = expression.Body as MemberExpression; - if( memberExpression == null ) - throw new ArgumentException( "The body of the expression must be a MemberExpression.", "expression" ); - - return memberExpression.Member.Name; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/WeakEventHandler.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/WeakEventHandler.cs deleted file mode 100644 index 79c0340f..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/WeakEventHandler.cs +++ /dev/null @@ -1,77 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -/************************************************************** - * - * This code is based on public domain code written by Paul Stovell. - * All copyrights and other rights have been waived. - * - * ************************************************************/ - -using System; -using System.ComponentModel; -using System.Reflection; - -namespace Xceed.Wpf.DataGrid.Utils -{ - [Obsolete( "This class is inefficient. You should derive from System.Windows.WeakEventManager instead." )] - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - public sealed class WeakEventHandler - where TEventArgs : class - { - #region Constructors - - public WeakEventHandler( Action callback ) - { - if( callback == null ) - throw new ArgumentNullException( "callback" ); - - // We keep a WeakReference on the target so that the event - // won't keep the object alive. - m_method = callback.Method; - m_targetReference = new WeakReference( callback.Target ); - } - - #endregion // Constructors - - public void Handler( object sender, TEventArgs e ) - { - // Only invoke the callback if the target is still alive. - if( m_targetReference.IsAlive ) - { - var target = m_targetReference.Target; - if( target != null ) - { - // Recreate the callback based on the MethodInfo and target that we received in the ctor. - var callback = Delegate.CreateDelegate( typeof( Action ), target, m_method, false ) as Action; - if( callback != null ) - { - // This will invoke the callback that the subscriber wants to be called for the event. - callback( sender, e ); - } - } - } - } - - #region Private Fields - - private MethodInfo m_method; - private WeakReference m_targetReference; - - #endregion // Private Fields - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/BreadthFirstSearchTreeTraversal.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/BreadthFirstSearchTreeTraversal.cs deleted file mode 100644 index ded4203d..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/BreadthFirstSearchTreeTraversal.cs +++ /dev/null @@ -1,73 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Windows; - -namespace Xceed.Utils.Wpf -{ - internal sealed class BreadthFirstSearchTreeTraversal : ITreeTraversal - { - #region Current Property - - public DependencyObject Current - { - get - { - if( m_current == null ) - throw new InvalidOperationException(); - - return m_current; - } - } - - private DependencyObject m_current; //null - - #endregion - - public bool MoveNext() - { - if( m_collection.Count > 0 ) - { - m_current = m_collection.Dequeue(); - return true; - } - else - { - m_current = null; - return false; - } - } - - public void VisitNodes( IEnumerable nodes ) - { - if( nodes == null ) - return; - - foreach( var node in nodes ) - { - m_collection.Enqueue( node ); - } - } - - #region Private Fields - - private readonly Queue m_collection = new Queue(); - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/BreadthFirstSearchTreeTraversalStrategy.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/BreadthFirstSearchTreeTraversalStrategy.cs deleted file mode 100644 index 243e2761..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/BreadthFirstSearchTreeTraversalStrategy.cs +++ /dev/null @@ -1,27 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - - -namespace Xceed.Utils.Wpf -{ - internal sealed class BreadthFirstSearchTreeTraversalStrategy : ITreeTraversalStrategy - { - public ITreeTraversal Create() - { - return new BreadthFirstSearchTreeTraversal(); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DeferredDisposable.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DeferredDisposable.cs deleted file mode 100644 index a9f033b1..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DeferredDisposable.cs +++ /dev/null @@ -1,53 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows.Threading; - -namespace Xceed.Utils.Wpf -{ - internal sealed class DeferredDisposable : DispatcherDisposable - { - internal DeferredDisposable( DeferredDisposableState state ) - { - if( state == null ) - throw new ArgumentNullException( "state" ); - - m_state = state; - m_state.Initialize(); - } - - protected override Dispatcher GetDisposeDispatcher() - { - var dispatcher = m_state.GetDispatcher(); - if( dispatcher != null ) - return dispatcher; - - return base.GetDisposeDispatcher(); - } - - protected override Action GetDisposeDelegate() - { - // We store the member in a local variable to create a closure. - // We do not want the returned delegate to target the current object. - var state = m_state; - - return ( disposing ) => state.Dispose( disposing ); - } - - private readonly DeferredDisposableState m_state; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DeferredDisposableState.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DeferredDisposableState.cs deleted file mode 100644 index 01fb8393..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DeferredDisposableState.cs +++ /dev/null @@ -1,108 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Threading; -using System.Windows.Threading; - -namespace Xceed.Utils.Wpf -{ - internal abstract class DeferredDisposableState - { - protected virtual object SyncRoot - { - get - { - return null; - } - } - - protected virtual Dispatcher Dispatcher - { - get - { - return null; - } - } - - protected abstract bool IsDeferred - { - get; - } - - protected abstract void Increment(); - protected abstract void Decrement(); - - protected virtual void OnDeferEnding( bool disposing ) - { - } - - protected abstract void OnDeferEnded( bool disposing ); - - internal Dispatcher GetDispatcher() - { - return this.Dispatcher; - } - - internal void Initialize() - { - var syncRoot = this.SyncRoot; - if( syncRoot != null ) - { - Monitor.Enter( syncRoot ); - } - - try - { - this.Increment(); - } - finally - { - if( syncRoot != null ) - { - Monitor.Exit( syncRoot ); - } - } - } - - internal void Dispose( bool disposing ) - { - var syncRoot = this.SyncRoot; - if( syncRoot != null ) - { - Monitor.Enter( syncRoot ); - } - - try - { - this.Decrement(); - - if( this.IsDeferred ) - return; - - this.OnDeferEnding( disposing ); - } - finally - { - if( syncRoot != null ) - { - Monitor.Exit( syncRoot ); - } - } - - this.OnDeferEnded( disposing ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DepthFirstSearchTreeTraversal.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DepthFirstSearchTreeTraversal.cs deleted file mode 100644 index 275e161e..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DepthFirstSearchTreeTraversal.cs +++ /dev/null @@ -1,73 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Windows; - -namespace Xceed.Utils.Wpf -{ - internal sealed class DepthFirstSearchTreeTraversal : ITreeTraversal - { - #region Current Property - - public DependencyObject Current - { - get - { - if( m_current == null ) - throw new InvalidOperationException(); - - return m_current; - } - } - - private DependencyObject m_current; //null - - #endregion - - public bool MoveNext() - { - var lastIndex = m_collection.Count - 1; - if( lastIndex >= 0 ) - { - m_current = m_collection[ lastIndex ]; - m_collection.RemoveAt( lastIndex ); - return true; - } - else - { - m_current = null; - return false; - } - } - - public void VisitNodes( IEnumerable nodes ) - { - if( nodes == null ) - return; - - m_collection.AddRange( nodes.Reverse() ); - } - - #region Private Fields - - private readonly List m_collection = new List(); - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DepthFirstSearchTreeTraversalStrategy.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DepthFirstSearchTreeTraversalStrategy.cs deleted file mode 100644 index 60e84389..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DepthFirstSearchTreeTraversalStrategy.cs +++ /dev/null @@ -1,27 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - - -namespace Xceed.Utils.Wpf -{ - internal sealed class DepthFirstSearchTreeTraversalStrategy : ITreeTraversalStrategy - { - public ITreeTraversal Create() - { - return new DepthFirstSearchTreeTraversal(); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DispatcherDisposable.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DispatcherDisposable.cs deleted file mode 100644 index af6454f0..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DispatcherDisposable.cs +++ /dev/null @@ -1,90 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Threading; -using System.Windows; -using System.Windows.Threading; - -namespace Xceed.Utils.Wpf -{ - internal abstract class DispatcherDisposable : DependencyObject, IDisposable - { - #region Static Fields - - private static readonly object IsAlive = new object(); - - #endregion - - public void Dispose() - { - this.Dispose( true ); - GC.SuppressFinalize( this ); - } - - protected void Dispose( bool disposing ) - { - // Make sure we are only disposing once. - if( Interlocked.Exchange( ref m_isAlive, null ) == null ) - return; - - // We must not try to use managed objects since we have no clue whatever they have been - // garbage collected before the current object or not. - if( !disposing ) - return; - - // We ask the derived class for a delegate instead of calling a protected method directly - // because the current object could be garbage collected before the dispatcher calls the delegate. - // We want to avoid calling a method on a object that is no longer valid. Instead, we ask - // the derived class to generate a delegate that will do the dispose. For example, the delegate - // could be a lambda that encapsulate the fields in a closure. - var d = this.GetDisposeDelegate(); - if( d == null ) - return; - - if( object.ReferenceEquals( d.Target, this ) ) - throw new InvalidOperationException( "The dispose delegate must not target the disposable object." ); - - var dispatcher = this.GetDisposeDispatcher() ?? this.Dispatcher; - if( ( dispatcher == null ) || dispatcher.HasShutdownStarted || dispatcher.HasShutdownFinished ) - return; - - if( dispatcher.CheckAccess() ) - { - d.Invoke( disposing ); - } - else - { - dispatcher.BeginInvoke( d, DispatcherPriority.Send, disposing ); - } - } - - protected abstract Action GetDisposeDelegate(); - - protected virtual Dispatcher GetDisposeDispatcher() - { - return this.Dispatcher; - } - - // This class does not cleanup unmanaged resource, so it does not need a finalizer. - //~DispatcherDisposable() - //{ - // this.Dispose( false ); - //} - - private object m_isAlive = DispatcherDisposable.IsAlive; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DispatcherHelper.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DispatcherHelper.cs deleted file mode 100644 index fa35b536..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DispatcherHelper.cs +++ /dev/null @@ -1,53 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; -using System.Windows.Threading; - -namespace Xceed.Utils.Wpf -{ - internal static class DispatcherHelper - { - private static object ExitFrame( object state ) - { - DispatcherFrame frame = state as DispatcherFrame; - frame.Continue = false; - return null; - } - - private static DispatcherOperationCallback ExitFrameCallback = new - DispatcherOperationCallback( DispatcherHelper.ExitFrame ); - - public static void DoEvents( Dispatcher dispatcher ) - { - if( dispatcher == null ) - throw new ArgumentNullException( "dispatcher" ); - - DispatcherFrame nestedFrame = new DispatcherFrame(); - - DispatcherOperation exitOperation = dispatcher.BeginInvoke( - DispatcherPriority.Background, - DispatcherHelper.ExitFrameCallback, - nestedFrame ); - - Dispatcher.PushFrame( nestedFrame ); - - if( exitOperation.Status != DispatcherOperationStatus.Completed ) - exitOperation.Abort(); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DragDrop/AutoScrollManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DragDrop/AutoScrollManager.cs deleted file mode 100644 index f086d803..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DragDrop/AutoScrollManager.cs +++ /dev/null @@ -1,294 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Threading; - -namespace Xceed.Utils.Wpf.DragDrop -{ - internal sealed class AutoScrollManager : DependencyObject - { - #region Static Fields - - internal static readonly TimeSpan AutoScrollInterval_DefaultValue = TimeSpan.FromMilliseconds( 50d ); - internal const int AutoScrollThreshold_DefaultValue = 5; - - #endregion - - internal AutoScrollManager( ScrollViewer scrollViewer ) - { - if( scrollViewer == null ) - throw new ArgumentNullException( "scrollViewer" ); - - m_scrollViewer = scrollViewer; - - m_timer = new System.Windows.Threading.DispatcherTimer(); - m_timer.Interval = AutoScrollManager.AutoScrollInterval_DefaultValue; - m_timer.Tick += new EventHandler( this.OnAutoScrollTimer_Tick ); - - this.AutoScrollInterval = AutoScrollManager.AutoScrollInterval_DefaultValue; - this.AutoScrollThreshold = AutoScrollManager.AutoScrollThreshold_DefaultValue; - } - - #region AutoScrollInterval Property - - internal TimeSpan AutoScrollInterval - { - get; - set; - } - - #endregion - - #region AutoScrollThreshold Property - - internal int AutoScrollThreshold - { - get; - set; - } - - #endregion - - #region ScrollViewer Internal Property - - internal ScrollViewer ScrollViewer - { - get - { - return m_scrollViewer; - } - } - - #endregion - - #region AutoScrolled Internal Event - - internal event EventHandler AutoScrolled; - - private void OnAutoScrolled() - { - var handler = this.AutoScrolled; - if( handler == null ) - return; - - handler.Invoke( this, EventArgs.Empty ); - } - - #endregion - - internal void Start() - { - m_isStarted = true; - } - - internal void Stop() - { - m_isStarted = false; - m_timer.Stop(); - } - - internal void HandleMouseMove( MouseEventArgs e ) - { - if( !m_isStarted ) - return; - - this.HandleMove( e.GetPosition ); - } - - internal void HandleMove( Func getCursorPosition ) - { - if( !m_isStarted ) - return; - - var position = getCursorPosition.Invoke( m_scrollViewer ); - var renderSize = m_scrollViewer.RenderSize; - var treshold = this.AutoScrollThreshold; - var horizontalSpeed = 0d; - var verticalSpeed = 0d; - - m_autoScrollDirection = AutoScrollDirection.None; - - if( ( m_scrollViewer.ScrollableWidth > 0d ) && ( m_scrollViewer.ViewportWidth > 0d ) ) - { - var distance = 0d; - - if( ( position.X < treshold ) && ( m_scrollViewer.HorizontalOffset > 0d ) ) - { - m_autoScrollDirection |= AutoScrollDirection.Left; - distance = position.X - treshold; - } - else if( ( position.X > renderSize.Width - treshold ) && ( m_scrollViewer.HorizontalOffset < m_scrollViewer.ScrollableWidth ) ) - { - m_autoScrollDirection |= AutoScrollDirection.Right; - distance = position.X - ( renderSize.Width - treshold ); - } - - horizontalSpeed = distance / m_scrollViewer.ViewportWidth; - } - - if( ( m_scrollViewer.ScrollableHeight > 0d ) && ( m_scrollViewer.ViewportHeight > 0d ) ) - { - var distance = 0d; - - if( ( position.Y < treshold ) && ( m_scrollViewer.VerticalOffset > 0d ) ) - { - m_autoScrollDirection |= AutoScrollDirection.Up; - distance = position.Y - treshold; - } - else if( ( position.Y > renderSize.Height - treshold ) && ( m_scrollViewer.VerticalOffset < m_scrollViewer.ScrollableHeight ) ) - { - m_autoScrollDirection |= AutoScrollDirection.Down; - distance = position.Y - ( renderSize.Height - treshold ); - } - - verticalSpeed = distance / m_scrollViewer.ViewportHeight; - } - - m_scrollSpeed = new Vector( horizontalSpeed, verticalSpeed ); - - if( m_autoScrollDirection == AutoScrollDirection.None ) - { - m_timer.Stop(); - } - else - { - // The DispatcherTimer is not a priority event. The Tick event won't fire while the user moves the mouse pointer. That's why we manually call the - // PerformAutoScroll method (on each MouseMove, i.e. Drag). When the user doesn't move the mouse pointer, the timer will take over to do the AutoScroll. - if( !m_timer.IsEnabled ) - { - m_timer.Start(); - } - - this.PerformAutoScroll(); - } - } - - private void PerformAutoScroll() - { - if( !m_timer.IsEnabled ) - return; - - var elapsedTime = DateTime.UtcNow - m_timestamp; - if( elapsedTime < this.AutoScrollInterval ) - return; - - var scaleFactor = Matrix.Identity; - scaleFactor.Scale( m_scrollViewer.ViewportWidth, m_scrollViewer.ViewportHeight ); - - var scrollUnits = m_scrollSpeed * scaleFactor; - - if( ( m_autoScrollDirection & AutoScrollDirection.Left ) == AutoScrollDirection.Left ) - { - if( m_scrollSpeed.X <= -1d ) - { - m_scrollViewer.PageLeft(); - } - else - { - var unit = System.Math.Min( -1d, scrollUnits.X ); - var offset = System.Math.Max( 0d, m_scrollViewer.HorizontalOffset + unit ); - - m_scrollViewer.ScrollToHorizontalOffset( offset ); - } - } - else if( ( m_autoScrollDirection & AutoScrollDirection.Right ) == AutoScrollDirection.Right ) - { - if( m_scrollSpeed.X >= 1d ) - { - m_scrollViewer.PageRight(); - } - else - { - var unit = System.Math.Max( 1d, scrollUnits.X ); - var offset = System.Math.Min( m_scrollViewer.ScrollableWidth, m_scrollViewer.HorizontalOffset + unit ); - - m_scrollViewer.ScrollToHorizontalOffset( offset ); - } - } - - if( ( m_autoScrollDirection & AutoScrollDirection.Up ) == AutoScrollDirection.Up ) - { - if( m_scrollSpeed.Y <= -1d ) - { - m_scrollViewer.PageUp(); - } - else - { - var unit = System.Math.Min( -1d, scrollUnits.Y ); - var offset = System.Math.Max( 0d, m_scrollViewer.VerticalOffset + unit ); - - m_scrollViewer.ScrollToVerticalOffset( offset ); - } - } - else if( ( m_autoScrollDirection & AutoScrollDirection.Down ) == AutoScrollDirection.Down ) - { - if( m_scrollSpeed.Y >= 1d ) - { - m_scrollViewer.PageDown(); - } - else - { - var unit = System.Math.Max( 1d, scrollUnits.Y ); - var offset = System.Math.Min( m_scrollViewer.ScrollableHeight, m_scrollViewer.VerticalOffset + unit ); - - m_scrollViewer.ScrollToVerticalOffset( offset ); - } - } - - m_timestamp = DateTime.UtcNow; - - this.OnAutoScrolled(); - } - - private void OnAutoScrollTimer_Tick( object sender, EventArgs e ) - { - if( m_isStarted ) - { - this.PerformAutoScroll(); - } - else - { - ( ( DispatcherTimer )sender ).Stop(); - } - } - - private AutoScrollDirection m_autoScrollDirection = AutoScrollDirection.None; - private readonly ScrollViewer m_scrollViewer; - private readonly DispatcherTimer m_timer; - private DateTime m_timestamp; - private Vector m_scrollSpeed = new Vector( 0d, 0d ); - private bool m_isStarted; //false - - #region AutoScrollManager Private Enum - - [Flags()] - private enum AutoScrollDirection - { - None = 0, - Left = 1, - Right = 2, - Up = 4, - Down = 8 - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DragDrop/DragDropHelper.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DragDrop/DragDropHelper.cs deleted file mode 100644 index 28d23454..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DragDrop/DragDropHelper.cs +++ /dev/null @@ -1,80 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Windows; -using System.Windows.Input; -using Xceed.Wpf.DataGrid; - -namespace Xceed.Utils.Wpf.DragDrop -{ - internal static class DragDropHelper - { - internal static bool IsMouseMoveDrag( Point initialPosition, Point currentPosition ) - { - var dragRect = new Rect( - initialPosition.X - SystemParameters.MinimumHorizontalDragDistance, - initialPosition.Y - SystemParameters.MinimumVerticalDragDistance, - SystemParameters.MinimumHorizontalDragDistance * 2, - SystemParameters.MinimumVerticalDragDistance * 2 ); - - return !dragRect.Contains( currentPosition ); - } - - internal static IEnumerable GetDropTargetAtPoint( - UIElement draggedElement, - UIElement container, - MouseEventArgs e ) - { - return DragDropHelper.GetDropTargetAtPoint( draggedElement, container, e.GetPosition ); - } - - internal static IEnumerable GetDropTargetAtPoint( - UIElement draggedElement, - UIElement container, - Func getPosition ) - { - if( container == null ) - yield break; - - var mousePosition = new RelativePoint( container, getPosition.Invoke( container ) ); - var hitTest = container.InputHitTest( mousePosition.GetPoint( container ) ); - if( hitTest == null ) - yield break; - - var parent = hitTest as DependencyObject; - - while( parent != null ) - { - var dropTarget = parent as IDropTarget; - if( dropTarget != null ) - { - var element = parent as UIElement; - if( element != null ) - { - var dropTargetPosition = mousePosition.TranslateTo( element ); - var canDrop = dropTarget.CanDropElement( draggedElement, dropTargetPosition ); - - yield return new DropTargetInfo( dropTarget, dropTargetPosition, canDrop ); - } - } - - parent = Xceed.Utils.Wpf.TreeHelper.GetParent( parent ); - } - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DragDrop/DragSourceManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DragDrop/DragSourceManager.cs deleted file mode 100644 index a99b3e70..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DragDrop/DragSourceManager.cs +++ /dev/null @@ -1,304 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Diagnostics; -using System.Windows; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using Xceed.Wpf.DataGrid; - -namespace Xceed.Utils.Wpf.DragDrop -{ - internal class DragSourceManager : DragSourceManagerBase - { - internal DragSourceManager( UIElement draggedElement, AdornerLayer adornerLayer, UIElement container ) - : base( draggedElement, adornerLayer, container ) - { - } - - #region CurrentDropTarget Protected Property - - protected IDropTarget CurrentDropTarget - { - get - { - return m_currentDropTarget; - } - } - - private void SetCurrentDropTarget( IDropTarget value, RelativePoint mousePosition, bool raiseDragEvents ) - { - if( value == m_currentDropTarget ) - return; - - var element = this.DraggedElement; - - if( m_currentDropTarget != null ) - { - if( raiseDragEvents ) - { - m_currentDropTarget.DragLeave( element ); - } - - m_currentDropTarget = null; - } - - if( ( value != null ) && value.CanDropElement( element, mousePosition ) ) - { - m_currentDropTarget = value; - - if( raiseDragEvents ) - { - m_currentDropTarget.DragEnter( element ); - } - } - - this.OnPropertyChanged( "CurrentDropTarget" ); - } - - private IDropTarget m_currentDropTarget; //null - - #endregion - - #region CurrentDropTargetToContainerPosition Protected Property - - protected RelativePoint? CurrentDropTargetToContainerPosition - { - get - { - return m_currentDropTargetToContainerPosition; - } - private set - { - if( value == m_currentDropTargetToContainerPosition ) - return; - - m_currentDropTargetToContainerPosition = value; - - this.OnPropertyChanged( "CurrentDropTargetToContainerPosition" ); - } - } - - private RelativePoint? m_currentDropTargetToContainerPosition; //null - - #endregion - - #region DropOutsideCursor Internal Property - - internal Cursor DropOutsideCursor - { - get - { - return m_dropOutsideCursor; - } - set - { - if( value == m_dropOutsideCursor ) - return; - - m_dropOutsideCursor = value; - - this.OnPropertyChanged( "DropOutsideCursor" ); - } - } - - private Cursor m_dropOutsideCursor; //null - - #endregion - - #region DragOutsideQueryCursor Internal Event - - internal event QueryCursorEventHandler DragOutsideQueryCursor; - - private void OnDragOutsideQueryCursor( QueryCursorEventArgs e ) - { - if( e.Handled ) - return; - - e.Handled = true; - - e.Cursor = m_dropOutsideCursor ?? Cursors.No; - - var handler = this.DragOutsideQueryCursor; - if( handler != null ) - { - handler.Invoke( this, e ); - } - } - - #endregion - - #region DroppedOutside Internal Event - - internal event EventHandler DroppedOutside; - - protected virtual void OnDroppedOutside() - { - var handler = this.DroppedOutside; - if( handler == null ) - return; - - handler.Invoke( this, EventArgs.Empty ); - } - - #endregion - - protected override void OnDragStart( Func getPosition ) - { - base.OnDragStart( getPosition ); - - var element = this.DraggedElement; - element.QueryCursor += new QueryCursorEventHandler( this.OnDraggedElementQueryCursor ); - - Debug.Assert( element.IsMouseCaptured, "The mouse should have be captured by the dragged element." ); - } - - protected override void OnDragEnd( Func getPosition, bool drop ) - { - var element = this.DraggedElement; - element.QueryCursor -= new QueryCursorEventHandler( this.OnDraggedElementQueryCursor ); - - base.OnDragEnd( getPosition, drop ); - } - - protected override void OnDragMove( Func getPosition ) - { - base.OnDragMove( getPosition ); - - var dropTargetInfo = this.GetDropTarget( getPosition ); - - this.CurrentDropTargetToContainerPosition = dropTargetInfo.Position; - this.SetCurrentDropTarget( dropTargetInfo.Target, dropTargetInfo.Position.GetValueOrDefault(), true ); - - var dropTarget = this.CurrentDropTarget; - if( dropTarget != null ) - { - this.OnDragOver( dropTarget, getPosition ); - } - } - - protected override void OnDragCancel( Func getPosition ) - { - var dropTarget = this.CurrentDropTarget; - if( dropTarget != null ) - { - dropTarget.DragLeave( this.DraggedElement ); - this.SetCurrentDropTarget( null, default( RelativePoint ), false ); - } - else - { - this.OnDroppedOutside(); - } - - base.OnDragCancel( getPosition ); - } - - protected override void OnDrop( Func getPosition ) - { - var dropTarget = this.CurrentDropTarget; - if( dropTarget != null ) - { - var element = dropTarget as UIElement; - if( element != null ) - { - var mousePosition = new RelativePoint( element, getPosition.Invoke( element ) ); - - dropTarget.Drop( this.DraggedElement, mousePosition ); - } - - this.SetCurrentDropTarget( null, default( RelativePoint ), false ); - } - else - { - this.OnDroppedOutside(); - } - - base.OnDrop( getPosition ); - } - - protected virtual void OnDragOver( IDropTarget target, Func getPosition ) - { - if( target == null ) - throw new ArgumentNullException( "target" ); - - if( getPosition == null ) - throw new ArgumentNullException( "getPosition" ); - - var element = target as UIElement; - if( element == null ) - return; - - target.DragOver( this.DraggedElement, new RelativePoint( element, getPosition.Invoke( element ) ) ); - } - - protected override void ValidateMouseEventArgs( MouseEventArgs e ) - { - base.ValidateMouseEventArgs( e ); - - var element = this.DraggedElement; - var source = e.Source as DependencyObject; - - while( source != null ) - { - if( source == element ) - break; - - source = VisualTreeHelper.GetParent( source ); - } - - Debug.Assert( ( source != null ), "The Source of the " + e.RoutedEvent.Name + " event is NOT the UIElement that was passed to the ctor of this DragSourceManager OR one of its children." ); - } - - protected virtual DropTargetInfo GetDropTarget( Func getPosition ) - { - foreach( var info in DragDropHelper.GetDropTargetAtPoint( this.DraggedElement, this.Container, getPosition ) ) - { - if( !info.CanDrop ) - continue; - - // ColumnManagerRow was defined as IDropTarget only because Animated Column Reordering required it, ignore it in base class - if( info.Target is ColumnManagerRow ) - break; - - return info; - } - - return new DropTargetInfo( null, null, false ); - } - - private void OnDraggedElementQueryCursor( object sender, QueryCursorEventArgs e ) - { - if( !this.IsDragging ) - return; - - var dropTarget = this.CurrentDropTarget; - if( dropTarget != null ) - { - var element = dropTarget as UIElement; - if( element != null ) - { - var dropPoint = e.GetPosition( element ); - if( dropTarget.CanDropElement( this.DraggedElement, new RelativePoint( element, dropPoint ) ) ) - return; - } - } - - this.OnDragOutsideQueryCursor( e ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DragDrop/DragSourceManagerBase.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DragDrop/DragSourceManagerBase.cs deleted file mode 100644 index 3ae1951b..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DragDrop/DragSourceManagerBase.cs +++ /dev/null @@ -1,710 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; -using System.Diagnostics; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Controls.Primitives; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Interop; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Shapes; -using Xceed.Wpf.DataGrid; - -namespace Xceed.Utils.Wpf.DragDrop -{ - internal class DragSourceManagerBase : DependencyObject, INotifyPropertyChanged - { - internal DragSourceManagerBase( UIElement draggedElement, AdornerLayer adornerLayer, UIElement container ) - : this( draggedElement, adornerLayer, container, true ) - { - } - - internal DragSourceManagerBase( UIElement draggedElement, AdornerLayer adornerLayer, UIElement container, bool enableAutoScroll ) - : this( draggedElement, adornerLayer, container, enableAutoScroll, true ) - { - } - - internal DragSourceManagerBase( UIElement draggedElement, AdornerLayer adornerLayer, UIElement container, bool enableAutoScroll, bool showGhost ) - { - if( draggedElement == null ) - throw new ArgumentNullException( "draggedElement" ); - - if( container == null ) - throw new ArgumentNullException( "container" ); - - m_draggedElement = draggedElement; - m_container = container; - m_adornerLayer = ( adornerLayer != null ) ? adornerLayer : AdornerLayer.GetAdornerLayer( container ); - m_showGhost = showGhost; - - if( enableAutoScroll ) - { - var scrollViewer = DragSourceManagerBase.GetScrollViewer( draggedElement ); - if( scrollViewer != null ) - { - m_autoScrollManager = new AutoScrollManager( scrollViewer ); - } - } - } - - #region IsDragging Property - - internal bool IsDragging - { - get - { - return m_isDragging; - } - private set - { - if( value == m_isDragging ) - return; - - m_isDragging = value; - - this.OnPropertyChanged( "IsDragging" ); - } - } - - private bool m_isDragging; - - #endregion - - #region IsDragStarted Property - - internal bool IsDragStarted - { - get - { - return m_isDragStarted; - } - private set - { - if( value == m_isDragStarted ) - return; - - m_isDragStarted = value; - - this.OnPropertyChanged( "IsDragStarted" ); - } - } - - private bool m_isDragStarted; - - #endregion - - #region ShowGhost Property - - internal bool ShowGhost - { - get - { - return m_showGhost; - } - set - { - if( value == m_showGhost ) - return; - - m_showGhost = value; - - this.OnPropertyChanged( "ShowGhost" ); - } - } - - private bool m_showGhost; - - #endregion - - #region AutoScrollInterval Property - - internal static readonly DependencyProperty AutoScrollIntervalProperty = DependencyProperty.Register( - "AutoScrollInterval", - typeof( TimeSpan ), - typeof( DragSourceManagerBase ), - new FrameworkPropertyMetadata( AutoScrollManager.AutoScrollInterval_DefaultValue, DragSourceManagerBase.OnAutoScrollIntervalChanged ) ); - - internal TimeSpan AutoScrollInterval - { - get - { - return ( TimeSpan )this.GetValue( DragSourceManagerBase.AutoScrollIntervalProperty ); - } - set - { - this.SetValue( DragSourceManagerBase.AutoScrollIntervalProperty, value ); - } - } - - private void OnAutoScrollIntervalChanged( TimeSpan oldValue, TimeSpan newValue ) - { - if( m_autoScrollManager == null ) - return; - - m_autoScrollManager.AutoScrollInterval = newValue; - } - - private static void OnAutoScrollIntervalChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var self = sender as DragSourceManagerBase; - if( self == null ) - return; - - self.OnAutoScrollIntervalChanged( ( TimeSpan )e.OldValue, ( TimeSpan )e.NewValue ); - } - - #endregion - - #region AutoScrollThreshold Property - - public static readonly DependencyProperty AutoScrollThresholdProperty = DependencyProperty.Register( - "AutoScrollThreshold", - typeof( int ), - typeof( DragSourceManagerBase ), - new FrameworkPropertyMetadata( AutoScrollManager.AutoScrollThreshold_DefaultValue, DragSourceManagerBase.OnAutoScrollThresholdChanged ) ); - - public int AutoScrollThreshold - { - get - { - return ( int )this.GetValue( DragSourceManagerBase.AutoScrollThresholdProperty ); - } - set - { - this.SetValue( DragSourceManagerBase.AutoScrollThresholdProperty, value ); - } - } - - private void OnAutoScrollThresholdChanged( int oldValue, int newValue ) - { - if( m_autoScrollManager == null ) - return; - - m_autoScrollManager.AutoScrollThreshold = newValue; - } - - private static void OnAutoScrollThresholdChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var self = sender as DragSourceManagerBase; - if( self == null ) - return; - - self.OnAutoScrollThresholdChanged( ( int )e.OldValue, ( int )e.NewValue ); - } - - #endregion - - #region AdornerLayer Protected Property - - protected AdornerLayer AdornerLayer - { - get - { - return m_adornerLayer; - } - } - - private readonly AdornerLayer m_adornerLayer; - - #endregion - - #region DraggedElement Protected Property - - protected UIElement DraggedElement - { - get - { - return m_draggedElement; - } - } - - private readonly UIElement m_draggedElement; - - #endregion - - #region Container Protected Property - - protected UIElement Container - { - get - { - return m_container; - } - } - - private readonly UIElement m_container; - - #endregion - - #region IsPopup Protected Property - - protected bool IsPopup - { - get - { - return m_isPopup; - } - } - - private bool m_isPopup; - - #endregion - - #region InitialMousePositionToDraggedElement Protected Property - - protected Point? InitialMousePositionToDraggedElement - { - get - { - return m_initialMousePositionToDraggedElement; - } - } - - private Point? m_initialMousePositionToDraggedElement; - - #endregion - - #region InitialMousePositionToAdorner Protected Property - - protected Point? InitialMousePositionToAdorner - { - get - { - return m_initialMousePositionToAdorner; - } - } - - private Point? m_initialMousePositionToAdorner; - - #endregion - - protected virtual void OnDragStart( Func getPosition ) - { - } - - protected virtual void OnDragEnd( Func getPosition, bool drop ) - { - if( drop ) - { - this.OnDrop( getPosition ); - } - else - { - this.OnDragCancel( getPosition ); - } - } - - protected virtual void OnDragCancel( Func getPosition ) - { - } - - protected virtual void OnDragMove( Func getPosition ) - { - } - - protected virtual void OnDrop( Func getPosition ) - { - } - - protected virtual void UpdateGhost( Func getPosition ) - { - if( m_isPopup || ( m_draggedElementGhost == null ) ) - return; - - if( m_showGhost != m_draggedElementGhost.IsVisible ) - { - if( m_showGhost ) - { - m_draggedElementGhost.Show(); - } - else - { - m_draggedElementGhost.Hide(); - } - } - - //Find the new ghost position based on the current mouse position. - var mousePosition = getPosition.Invoke( m_container ); - var draggedElementPosition = Point.Subtract( mousePosition, m_draggedElementMouseOffset ); - - if( FrameworkElement.GetFlowDirection( m_container ) != FlowDirection.LeftToRight ) - { - draggedElementPosition.X += m_draggedElement.RenderSize.Width; - } - - var draggedElementPositionOnScreen = m_container.PointToScreen( draggedElementPosition ); - - // When Windows fonts are magnified (via the Control Panel), the position returned by PointToScreen doesn't match perfectly to the coordinate used - // to translate a Window object. We need to multiply the result by a zoom factor in order to place the Window at the mouse location. - var ghostPosition = new Point( draggedElementPositionOnScreen.X * m_mouseToScreenPositionFactor.X, - draggedElementPositionOnScreen.Y * m_mouseToScreenPositionFactor.Y ); - - m_draggedElementGhost.Left = ghostPosition.X; - m_draggedElementGhost.Top = ghostPosition.Y; - } - - [Conditional( "DEBUG" )] - protected virtual void ValidateMouseEventArgs( MouseEventArgs e ) - { - } - - internal void DragStart( MouseEventArgs e ) - { - if( e.Handled || m_isDragStarted || m_isReentrant || ( e.LeftButton != MouseButtonState.Pressed ) ) - return; - - m_isReentrant = true; - - try - { - this.ValidateMouseEventArgs( e ); - this.DragStart( e.GetPosition ); - } - finally - { - m_isReentrant = false; - } - } - - internal void DragCancel( MouseEventArgs e ) - { - if( e.Handled || !m_isDragStarted || m_isReentrant ) - return; - - m_isReentrant = true; - - try - { - this.ValidateMouseEventArgs( e ); - this.DragEnd( e.GetPosition, false ); - } - finally - { - m_isReentrant = false; - } - } - - internal void Drop( MouseEventArgs e ) - { - if( e.Handled || !m_isDragStarted || m_isReentrant ) - return; - - m_isReentrant = true; - - try - { - this.ValidateMouseEventArgs( e ); - this.DragEnd( e.GetPosition, true ); - } - finally - { - m_isReentrant = false; - } - } - - internal void DragMove( MouseEventArgs e ) - { - this.DragMove( e, false ); - } - - internal void DragMove( MouseEventArgs e, bool isCreatingCopy ) - { - if( e.Handled || !m_isDragStarted || m_isReentrant || ( e.LeftButton != MouseButtonState.Pressed ) ) - return; - - m_isReentrant = true; - - try - { - this.ValidateMouseEventArgs( e ); - this.DragMove( e.GetPosition, isCreatingCopy ); - - if( m_autoScrollManager != null ) - { - m_autoScrollManager.HandleMouseMove( e ); - } - } - finally - { - m_isReentrant = false; - } - } - - private static ScrollViewer GetScrollViewer( DependencyObject from ) - { - while( from != null ) - { - var scrollViewer = from as ScrollViewer; - if( scrollViewer != null ) - return scrollViewer; - - from = VisualTreeHelper.GetParent( from ); - } - - return null; - } - - private static FrameworkElement GetPopupOrWindow( DependencyObject from ) - { - while( from != null ) - { - var popup = from as Popup; - if( popup != null ) - return popup; - - var window = from as Window; - if( window != null ) - return window; - - from = TreeHelper.GetParent( from ); - } - - return null; - } - - private static DependencyObject GetPopupParent( DependencyObject from ) - { - while( from != null ) - { - var popup = from as Popup; - if( popup != null ) - { - var parent = popup.Parent; - if( parent != null ) - return parent; - - var target = popup.PlacementTarget; - if( target != null ) - return target; - } - - from = VisualTreeHelper.GetParent( from ); - } - - return null; - } - - private static Vector CalculateMouseToScreenPositionFactor( FrameworkElement element ) - { - if( element == null ) - return new Vector( 1d, 1d ); - - var source = PresentationSource.FromVisual( element ); - if( source == null ) - { - var parent = DragSourceManagerBase.GetPopupParent( element ); - while( parent != null ) - { - source = PresentationSource.FromDependencyObject( parent ); - if( source != null ) - break; - - parent = DragSourceManagerBase.GetPopupParent( parent ); - } - } - - double x, y; - - if( source != null ) - { - var deviceUnits = source.CompositionTarget.TransformToDevice; - x = deviceUnits.M11; - y = deviceUnits.M22; - } - else - { - using( var hwnd = new HwndSource( new HwndSourceParameters() ) ) - { - var deviceUnits = hwnd.CompositionTarget.TransformToDevice; - x = deviceUnits.M11; - y = deviceUnits.M22; - } - } - - return new Vector( ( x == 0d ) ? 1d : 1d / x, ( y == 0d ) ? 1d : 1d / y ); - } - - private static Window CreateDraggedElementGhost( UIElement element, bool isCreatingCopy ) - { - if( element == null ) - return null; - - TileBrush brush = null; - - // Draw a copy of the element to make sure it won't be modified. - // Used in MergedColumnEditor when recycling is active while dragging a cell far away. - if( isCreatingCopy ) - { - var drawingVisual = new DrawingVisual(); - using( var drawingContext = drawingVisual.RenderOpen() ) - { - var visualBrush = new VisualBrush( element ); - drawingContext.DrawRectangle( visualBrush, null, new Rect( new Point(), new Size( element.RenderSize.Width, element.RenderSize.Height ) ) ); - } - - float dpiX, dpiY; - using( System.Drawing.Graphics graphics = System.Drawing.Graphics.FromHwnd( IntPtr.Zero ) ) - { - dpiX = graphics.DpiX; - dpiY = graphics.DpiY; - } - var bitmapTarget = new RenderTargetBitmap( (int)element.RenderSize.Width, (int)element.RenderSize.Height, dpiX, dpiY, PixelFormats.Default ); - bitmapTarget.Render( drawingVisual ); - brush = new ImageBrush( bitmapTarget ); - } - else - { - brush = new VisualBrush( element ); - } - - brush.Opacity = 0.75d; - brush.Stretch = Stretch.None; - brush.AlignmentX = AlignmentX.Left; - brush.AlignmentY = AlignmentY.Top; - - var rectangle = new Rectangle(); - rectangle.Width = element.DesiredSize.Width; - rectangle.Height = element.DesiredSize.Height; - rectangle.Fill = brush; - - var window = new Window(); - window.Topmost = true; - window.WindowStyle = WindowStyle.None; - window.AllowsTransparency = true; - window.Background = null; - window.SizeToContent = SizeToContent.WidthAndHeight; - window.ShowInTaskbar = false; - window.IsHitTestVisible = false; - window.ShowActivated = false; - window.Focusable = false; - window.Left = 0; - window.Top = 0; - window.Content = rectangle; - - //This will make sure the window follows what has been set on the parent grid. - var dataGridContext = DataGridControl.GetDataGridContext( element ); - if( dataGridContext != null ) - { - window.FlowDirection = dataGridContext.DataGridControl.FlowDirection; - } - - return window; - } - - private void DragStart( Func getPosition ) - { - var parent = DragSourceManagerBase.GetPopupOrWindow( m_draggedElement ); - var draggedElementPosition = getPosition.Invoke( m_draggedElement ); - - m_isPopup = ( parent is Popup ); - m_initialMousePositionToAdorner = ( m_adornerLayer != null ) ? getPosition.Invoke( m_adornerLayer ) : default( Point? ); - m_initialMousePositionToDraggedElement = draggedElementPosition; - m_mouseToScreenPositionFactor = DragSourceManagerBase.CalculateMouseToScreenPositionFactor( parent ); - m_draggedElementMouseOffset = new Vector( draggedElementPosition.X, draggedElementPosition.Y ); - - if( m_autoScrollManager != null ) - { - m_autoScrollManager.Start(); - } - - this.IsDragStarted = true; - } - - private void DragEnd( Func getPosition, bool drop ) - { - if( m_isDragging ) - { - this.OnDragEnd( getPosition, drop ); - this.IsDragging = false; - } - - if( m_draggedElementGhost != null ) - { - m_draggedElementGhost.Hide(); - m_draggedElementGhost.Content = null; - m_draggedElementGhost.Close(); - m_draggedElementGhost = null; - } - - if( m_autoScrollManager != null ) - { - m_autoScrollManager.Stop(); - } - - m_initialMousePositionToAdorner = default( Point? ); - m_initialMousePositionToDraggedElement = default( Point? ); - - this.IsDragStarted = false; - } - - private void DragMove( Func getPosition, bool isCreatingCopy ) - { - if( !m_initialMousePositionToAdorner.HasValue ) - return; - - if( !m_isDragging ) - { - var position = getPosition.Invoke( m_adornerLayer ); - - if( DragDropHelper.IsMouseMoveDrag( m_initialMousePositionToAdorner.Value, position ) ) - { - m_draggedElementGhost = DragSourceManagerBase.CreateDraggedElementGhost( m_draggedElement, isCreatingCopy ); - - this.OnDragStart( getPosition ); - this.IsDragging = true; - } - } - - if( m_isDragging ) - { - this.OnDragMove( getPosition ); - this.UpdateGhost( getPosition ); - } - } - - #region INotifyPropertyChanged Members - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void OnPropertyChanged( string propertyName ) - { - var handler = this.PropertyChanged; - if( handler == null ) - return; - - handler.Invoke( this, new PropertyChangedEventArgs( propertyName ) ); - } - - protected sealed override void OnPropertyChanged( DependencyPropertyChangedEventArgs e ) - { - base.OnPropertyChanged( e ); - this.OnPropertyChanged( e.Property.Name ); - } - - #endregion - - private readonly AutoScrollManager m_autoScrollManager; - private Window m_draggedElementGhost; //null - private Vector m_mouseToScreenPositionFactor = new Vector( 1d, 1d ); - private Vector m_draggedElementMouseOffset; - private bool m_isReentrant; //false - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DragDrop/DraggedElementAdorner.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DragDrop/DraggedElementAdorner.cs deleted file mode 100644 index e5ed5bb9..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DragDrop/DraggedElementAdorner.cs +++ /dev/null @@ -1,164 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Windows.Documents; -using System.Windows; -using System.Windows.Shapes; -using System.Windows.Media; -using System.Windows.Media.Animation; - -namespace Xceed.Utils.Wpf.DragDrop -{ - internal class DraggedElementAdorner : Adorner - { - public DraggedElementAdorner( UIElement adornedElement, AdornerLayer adornerLayer ) - : base( adornedElement ) - { - FrameworkElement element = this.AdornedElement as FrameworkElement; - FrameworkElement layer = adornerLayer as FrameworkElement; - - if( ( element != null ) && ( layer != null ) && ( element.FlowDirection != layer.FlowDirection ) ) - { - m_invertXAxis = true; - } - } - - #region Offset Property - - public static readonly DependencyProperty OffsetProperty = DependencyProperty.Register( - "Offset", - typeof( Point ), - typeof( DraggedElementAdorner ), - new FrameworkPropertyMetadata( new PropertyChangedCallback( DraggedElementAdorner.OnOffsetChanged ) ) ); - - public Point Offset - { - get - { - return ( Point )this.GetValue( DraggedElementAdorner.OffsetProperty ); - } - set - { - this.SetValue( DraggedElementAdorner.OffsetProperty, value ); - } - } - - private static void OnOffsetChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - DraggedElementAdorner adorner = sender as DraggedElementAdorner; - - if( adorner == null ) - return; - - adorner.UpdatePosition(); - } - - #endregion - - #region AdornedElementImage Property - - public Rectangle AdornedElementImage - { - get - { - if( m_adornedElementImage == null ) - { - m_adornedElementImage = this.InitializeAdornedElementImage(); - } - - return m_adornedElementImage; - } - } - - #endregion - - public void SetOffset( Point offset ) - { - this.Offset = offset; - } - - public override GeneralTransform GetDesiredTransform( GeneralTransform transform ) - { - GeneralTransformGroup transformGroup = new GeneralTransformGroup(); - - transformGroup.Children.Add( base.GetDesiredTransform( transform ) ); - transformGroup.Children.Add( new TranslateTransform( ( m_invertXAxis == false ) ? this.Offset.X : -this.Offset.X, this.Offset.Y ) ); - - return transformGroup; - } - - protected virtual Rectangle InitializeAdornedElementImage() - { - Rectangle rectangle = new Rectangle(); - VisualBrush brush = new VisualBrush( this.AdornedElement ); - brush.Opacity = 0.75; - brush.Stretch = Stretch.None; - brush.AlignmentX = AlignmentX.Left; - brush.AlignmentY = AlignmentY.Top; - rectangle.Fill = brush; - - return rectangle; - } - - protected override Size MeasureOverride( Size constraint ) - { - this.AdornedElement.Measure( constraint ); - - return this.AdornedElement.RenderSize; - } - - protected override Size ArrangeOverride( Size finalSize ) - { - this.AdornedElementImage.Width = finalSize.Width; - this.AdornedElementImage.Height = finalSize.Height; - this.AdornedElementImage.Arrange( new Rect( finalSize ) ); - - return finalSize; - } - - protected override Visual GetVisualChild( int index ) - { - if( index != 0 ) - throw new ArgumentOutOfRangeException( "index", index, "Index must be zero: a DraggedElementAdorner can only have one child." ); - - return this.AdornedElementImage; - } - - protected override int VisualChildrenCount - { - get - { - return 1; - } - } - - private void UpdatePosition() - { - AdornerLayer adornerLayer = this.Parent as AdornerLayer; - - if( adornerLayer != null ) - { - adornerLayer.Update( this.AdornedElement ); - } - } - - private Rectangle m_adornedElementImage; - private bool m_invertXAxis; // = false - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DragDrop/DropTargetInfo.Struct.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DragDrop/DropTargetInfo.Struct.cs deleted file mode 100644 index 4aedcab9..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DragDrop/DropTargetInfo.Struct.cs +++ /dev/null @@ -1,34 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using Xceed.Wpf.DataGrid; - -namespace Xceed.Utils.Wpf.DragDrop -{ - internal struct DropTargetInfo - { - public DropTargetInfo( IDropTarget target, RelativePoint? position, bool canDrop ) - { - this.Target = target; - this.Position = position; - this.CanDrop = canDrop; - } - - internal readonly IDropTarget Target; - internal readonly RelativePoint? Position; - internal readonly bool CanDrop; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DragDrop/IDropTarget.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DragDrop/IDropTarget.cs deleted file mode 100644 index ac3a1b05..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/DragDrop/IDropTarget.cs +++ /dev/null @@ -1,34 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Windows; -using Xceed.Wpf.DataGrid; - -namespace Xceed.Utils.Wpf.DragDrop -{ - internal interface IDropTarget - { - bool CanDropElement( UIElement draggedElement, RelativePoint mousePosition ); - - void DragEnter( UIElement draggedElement ); - - void DragOver( UIElement draggedElement, RelativePoint mousePosition ); - - void DragLeave( UIElement draggedElement ); - - void Drop( UIElement draggedElement, RelativePoint mousePosition ); - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/ITreeTraversal.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/ITreeTraversal.cs deleted file mode 100644 index ab1b021a..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/ITreeTraversal.cs +++ /dev/null @@ -1,32 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Collections.Generic; -using System.Windows; - -namespace Xceed.Utils.Wpf -{ - internal interface ITreeTraversal - { - DependencyObject Current - { - get; - } - - bool MoveNext(); - void VisitNodes( IEnumerable nodes ); - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/ITreeTraversalStrategy.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/ITreeTraversalStrategy.cs deleted file mode 100644 index fc0df99a..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/ITreeTraversalStrategy.cs +++ /dev/null @@ -1,24 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - - -namespace Xceed.Utils.Wpf -{ - internal interface ITreeTraversalStrategy - { - ITreeTraversal Create(); - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/Markup/XceedResourceDictionary.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/Markup/XceedResourceDictionary.cs deleted file mode 100644 index 58174876..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/Markup/XceedResourceDictionary.cs +++ /dev/null @@ -1,60 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; -using System.Windows; - -namespace Xceed.Utils.Wpf.Markup -{ - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - public sealed class XceedResourceDictionary : ResourceDictionary - { - #region XceedSource Property - - [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly" )] - public string XceedSource - { - - get - { - return m_xceedSource; - } - set - { - if( value == null ) - throw new ArgumentNullException( "XceedSource" ); - - m_xceedSource = value; - - string[] parsedArguments = m_xceedSource.Split( new char[] { ';' }, 2, StringSplitOptions.RemoveEmptyEntries ); - - if( parsedArguments.Length != 2 ) - throw new ArgumentException( "Invalid URI format.", "XceedSource" ); - - string uriString = parsedArguments[ 0 ] + - ";;;" + parsedArguments[ 1 ]; - - this.Source = new Uri( uriString, UriKind.RelativeOrAbsolute ); - } - } - - private string m_xceedSource = string.Empty; - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/TreeHelper.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/TreeHelper.cs deleted file mode 100644 index 6f6015a2..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/Wpf/TreeHelper.cs +++ /dev/null @@ -1,288 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Windows; -using System.Windows.Controls.Primitives; -using System.Windows.Media; - -namespace Xceed.Utils.Wpf -{ - 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 ) - { - 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 - { - return TreeHelper.FindParent( startingObject, checkStartingObject, additionalCheck, 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. - /// Should not search behond this parent. Scope value is excluded from the search - /// Returns the found element. Null if nothing is found. - /// Button button = TreeHelper.FindParent<Button>( this, foundChild => foundChild.Focusable ); - internal static T FindParent( DependencyObject startingObject, bool checkStartingObject, Func additionalCheck, DependencyObject scope ) 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 ); - - if( object.ReferenceEquals( parent, scope ) ) - break; - - } - - 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 predicate ) where T : DependencyObject - { - return TreeHelper.GetDescendants( new BreadthFirstSearchTreeTraversalStrategy(), parent, predicate, null ).FirstOrDefault(); - } - - /// - /// 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; - } - - public static IEnumerable GetDescendants( ITreeTraversalStrategy strategy, DependencyObject root ) where T : DependencyObject - { - return TreeHelper.GetDescendants( strategy, root, null, null ); - } - - public static IEnumerable GetDescendants( ITreeTraversalStrategy strategy, DependencyObject root, Func predicate ) where T : class - { - return TreeHelper.GetDescendants( strategy, root, predicate, null ); - } - - public static IEnumerable GetDescendants( - ITreeTraversalStrategy strategy, - DependencyObject root, - Func predicate, - Func expand ) where T : class - { - if( strategy == null ) - throw new ArgumentNullException( "strategy" ); - - if( root == null ) - yield break; - - var traversal = strategy.Create(); - Debug.Assert( traversal != null ); - - traversal.VisitNodes( TreeHelper.GetChildren( root ) ); - - while( traversal.MoveNext() ) - { - var current = traversal.Current; - var descendant = current as T; - - if( ( descendant != null ) && ( ( predicate == null ) || predicate.Invoke( descendant ) ) ) - { - yield return descendant; - } - - if( ( expand == null ) || expand.Invoke( current ) ) - { - traversal.VisitNodes( TreeHelper.GetChildren( current ) ); - } - } - } - - private static IEnumerable GetChildren( DependencyObject parent ) - { - if( parent == null ) - yield break; - - var childrenCount = VisualTreeHelper.GetChildrenCount( parent ); - for( int i = 0; i < childrenCount; i++ ) - { - var child = VisualTreeHelper.GetChild( parent, i ); - if( child != null ) - { - yield return child; - } - } - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/XmlSerialization/XmlSerializableBaseType.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/XmlSerialization/XmlSerializableBaseType.cs deleted file mode 100644 index 89829d07..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Utils/XmlSerialization/XmlSerializableBaseType.cs +++ /dev/null @@ -1,135 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Xml.Serialization; -using System.Xml.Schema; -using System.Xml; -using System.ComponentModel; - -namespace Xceed.Utils.XmlSerialization -{ - /// - /// This class can serialize or desirialize the specified type, - /// or any derived type, using an XmlSerializer. - /// - /// To use this class, simply put an XmlElement attribute on the - /// property to serialize and pass the type of this class to - /// the Type parameter of the XmlElement. This can also be used - /// with the XmlArrayItem attribute. - /// - /// The base type for the object to serialize or deserialize. - public class XmlSerializableBaseType : IXmlSerializable - { - #region Implicit Operators - - public static implicit operator XmlSerializableBaseType( T item ) - { - return ( item == null ) - ? null - : new XmlSerializableBaseType( item ); - } - - public static implicit operator T( XmlSerializableBaseType item ) - { - return ( item.Equals( default( T ) ) ) - ? default( T ) - : item.m_item; - } - - #endregion Implicit Operators - - #region CONSTRUCTORS - - public XmlSerializableBaseType() - { - } - - public XmlSerializableBaseType( T item ) - { - m_item = item; - } - - #endregion CONSTRUCTORS - - #region IXmlSerializable Members - - XmlSchema IXmlSerializable.GetSchema() - { - return null; - } - - void IXmlSerializable.ReadXml( XmlReader reader ) - { - Type type = XmlSerializableBaseType.GetType( reader.GetAttribute( "type" ) ); - - reader.ReadStartElement(); - m_item = ( T )new XmlSerializer( type ).Deserialize( reader ); - reader.ReadEndElement(); - } - - void IXmlSerializable.WriteXml( XmlWriter writer ) - { - Type type = m_item.GetType(); - - writer.WriteAttributeString( - "type", string.Format( "{0}, {1}", type.FullName, type.Assembly.GetName().Name ) ); - - new XmlSerializer( type ).Serialize( writer, m_item ); - } - - #endregion IXmlSerializable Members - - #region PRIVATE METHODS - - private static Type GetType( string typeName ) - { - if( mg_types.ContainsKey( typeName ) ) - return mg_types[ typeName ]; - - Type type = null; - int commaPosition = typeName.IndexOf( ',' ); - - if( commaPosition > 0 ) - { - type = Type.GetType( typeName.Substring( 0, commaPosition ) ); - } - - if( type == null ) - { - type = Type.GetType( typeName ); - } - - if( type != null ) - mg_types.Add( typeName, type ); - - return type; - } - - #endregion PRIVATE METHODS - - #region PRIVATE FIELDS - - private static Dictionary mg_types = new Dictionary(); - private T m_item; - - #endregion PRIVATE FIELDS - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ValidationRules/CellContentBindingValidationRule.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ValidationRules/CellContentBindingValidationRule.cs deleted file mode 100644 index 16d229f5..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ValidationRules/CellContentBindingValidationRule.cs +++ /dev/null @@ -1,29 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows.Controls; - -namespace Xceed.Wpf.DataGrid.ValidationRules -{ - public class CellContentBindingValidationRule : PassthroughCellValidationRule - { - public CellContentBindingValidationRule( ValidationRule validationRule ) - : base( validationRule ) - { - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ValidationRules/CellEditorErrorValidationRule.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ValidationRules/CellEditorErrorValidationRule.cs deleted file mode 100644 index 10f563a7..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ValidationRules/CellEditorErrorValidationRule.cs +++ /dev/null @@ -1,36 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Globalization; -using System.Windows.Controls; -using System.Windows; - -namespace Xceed.Wpf.DataGrid.ValidationRules -{ - public class CellEditorErrorValidationRule : CellEditorValidationRule - { - public override ValidationResult Validate( object value, CultureInfo culture, CellValidationContext context, FrameworkElement cellEditor ) - { - bool cellEditorHasError = ( cellEditor == null ) ? false : ( bool )cellEditor.GetValue( CellEditor.HasErrorProperty ); - - if( !cellEditorHasError ) - return ValidationResult.ValidResult; - - return new ValidationResult( false, "An invalid or incomplete value was provided." ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ValidationRules/CellEditorValidationRule.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ValidationRules/CellEditorValidationRule.cs deleted file mode 100644 index d46bbe10..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ValidationRules/CellEditorValidationRule.cs +++ /dev/null @@ -1,44 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows; -using System.Globalization; -using System.Windows.Controls; - -namespace Xceed.Wpf.DataGrid.ValidationRules -{ - public abstract class CellEditorValidationRule : CellValidationRule - { - protected CellEditorValidationRule() - { - } - - public override sealed ValidationResult Validate( object value, CultureInfo culture, CellValidationContext context ) - { - return this.Validate( value, culture, context, context.Cell.CellEditorBoundControl ); - } - - public abstract ValidationResult Validate( - object value, - CultureInfo culture, - CellValidationContext context, - FrameworkElement cellEditor ); - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ValidationRules/CellValidationRule.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ValidationRules/CellValidationRule.cs deleted file mode 100644 index d7a11ec8..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ValidationRules/CellValidationRule.cs +++ /dev/null @@ -1,33 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Windows.Controls; -using System.Globalization; - -namespace Xceed.Wpf.DataGrid.ValidationRules -{ - public abstract class CellValidationRule - { - protected CellValidationRule() - { - } - - public abstract ValidationResult Validate( - object value, - CultureInfo culture, - CellValidationContext context ); - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ValidationRules/EventCellValidationRule.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ValidationRules/EventCellValidationRule.cs deleted file mode 100644 index 29918006..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ValidationRules/EventCellValidationRule.cs +++ /dev/null @@ -1,48 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Globalization; -using System.Windows.Controls; - -namespace Xceed.Wpf.DataGrid.ValidationRules -{ - public class EventCellValidationRule : CellValidationRule - { - public EventCellValidationRule() - { - } - - public override ValidationResult Validate( - object value, - CultureInfo culture, - CellValidationContext context ) - { - if( this.Validating != null ) - { - CellValidatingEventArgs cellValidatingEventArgs = - new CellValidatingEventArgs( value, culture, context ); - - this.Validating( this, cellValidatingEventArgs ); - return cellValidatingEventArgs.Result; - } - - return ValidationResult.ValidResult; - } - - public event EventHandler Validating; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ValidationRules/PassthroughCellValidationRule.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ValidationRules/PassthroughCellValidationRule.cs deleted file mode 100644 index b0f34c36..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ValidationRules/PassthroughCellValidationRule.cs +++ /dev/null @@ -1,60 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Windows.Controls; -using System.Globalization; -using System; - -namespace Xceed.Wpf.DataGrid.ValidationRules -{ - public class PassthroughCellValidationRule : CellValidationRule - { - public PassthroughCellValidationRule() - { - } - - public PassthroughCellValidationRule( ValidationRule validationRule ) - { - m_validationRule = validationRule; - } - - public override ValidationResult Validate( - object value, - CultureInfo culture, - CellValidationContext context ) - { - if( m_validationRule == null ) - return ValidationResult.ValidResult; - - return m_validationRule.Validate( value, culture ); - } - - public ValidationRule ValidationRule - { - get - { - return m_validationRule; - } - - set - { - m_validationRule = value; - } - } - - ValidationRule m_validationRule; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ValidationRules/SourceDataConverterValidationRule.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ValidationRules/SourceDataConverterValidationRule.cs deleted file mode 100644 index ec166a03..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ValidationRules/SourceDataConverterValidationRule.cs +++ /dev/null @@ -1,54 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Windows.Controls; -using System.Globalization; - -using Xceed.Wpf.DataGrid.Converters; - -namespace Xceed.Wpf.DataGrid.ValidationRules -{ - public class SourceDataConverterValidationRule : ValidationRule - { - public SourceDataConverterValidationRule( bool sourceSupportDBNull, Type targetType ) - { - if( targetType == null ) - throw new ArgumentNullException( "targetType" ); - - m_sourceSupportDBNull = sourceSupportDBNull; - m_targetType = targetType; - } - - public override ValidationResult Validate( object value, CultureInfo culture ) - { - SourceDataConverter converter = new SourceDataConverter( m_sourceSupportDBNull ); - - Exception exception; - converter.TryConvertBack( value, m_targetType, CultureInfo.InvariantCulture, culture, out exception ); - - if( exception != null ) - return new ValidationResult( false, exception.Message ); - - return ValidationResult.ValidResult; - } - - bool m_sourceSupportDBNull; // = false - Type m_targetType; // = null - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ValueChangeDataItemIndexerDescriptor.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ValueChangeDataItemIndexerDescriptor.cs deleted file mode 100644 index c41c0b71..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ValueChangeDataItemIndexerDescriptor.cs +++ /dev/null @@ -1,221 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics; -using System.Linq; -using System.Windows.Data; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class ValueChangeDataItemIndexerDescriptor : DataItemIndexerDescriptor - { - internal ValueChangeDataItemIndexerDescriptor( - DataItemTypeDescriptor owner, - IndexerDescriptor parent, - EventDescriptor eventDescriptor ) - : base( owner, parent ) - { - if( eventDescriptor == null ) - throw new ArgumentNullException( "eventDescriptor" ); - - m_eventDescriptor = eventDescriptor; - m_eventProxy = new EventProxy( this, eventDescriptor ); - - var indexerName = parent.IndexerName; - var indexerParameters = parent.IndexerParameters; - - m_propertyChangedNames = new string[] - { - Binding.IndexerName, - string.Format( "{0}[]", indexerName ), - string.Format( "{0}[{1}]", indexerName, indexerParameters ) - }; - } - - #region SupportsChangeEvents Property - - public override bool SupportsChangeEvents - { - get - { - return true; - } - } - - #endregion - - public override int GetHashCode() - { - return base.GetHashCode(); - } - - public override bool Equals( object obj ) - { - var descriptor = obj as ValueChangeDataItemIndexerDescriptor; - if( object.ReferenceEquals( descriptor, null ) ) - return false; - - return ( object.Equals( descriptor.m_eventDescriptor, m_eventDescriptor ) ) - && ( base.Equals( descriptor ) ); - } - - protected override void AddValueChangedCore( object component ) - { - if( component == null ) - return; - - m_eventProxy.AddValueChanged( component ); - } - - protected override void RemoveValueChangedCore( object component ) - { - if( component == null ) - return; - - m_eventProxy.RemoveValueChanged( component ); - } - - protected override bool MustInhibitValueChanged( object component ) - { - return ( ( m_inhibitValueChanged == null ) || !m_inhibitValueChanged.Contains( component ) ) - && ( this.GetValueChangedHandler( component ) != null ); - } - - protected override bool IsValueChangedInhibited( object component ) - { - return ( m_inhibitValueChanged != null ) - && ( m_inhibitValueChanged.Contains( component ) ); - } - - protected override void InhibitValueChanged( object component ) - { - if( m_inhibitValueChanged == null ) - { - m_inhibitValueChanged = new HashSet(); - } - - m_inhibitValueChanged.Add( component ); - } - - protected override void ResetInhibitValueChanged( object component ) - { - Debug.Assert( m_inhibitValueChanged != null ); - - m_inhibitValueChanged.Remove( component ); - - if( m_inhibitValueChanged.Count == 0 ) - { - m_inhibitValueChanged = null; - } - } - - private void OnPropertyChanged( object sender, PropertyChangedEventArgs e ) - { - var propertyName = e.PropertyName; - - if( string.IsNullOrEmpty( propertyName ) || m_propertyChangedNames.Contains( propertyName ) ) - { - this.OnValueChanged( sender, e ); - } - } - - #region Private Fields - - private readonly string[] m_propertyChangedNames; - private readonly EventProxy m_eventProxy; - private readonly EventDescriptor m_eventDescriptor; - private HashSet m_inhibitValueChanged; - - #endregion - - #region EventProxy Private Class - - private sealed class EventProxy - { - internal EventProxy( ValueChangeDataItemIndexerDescriptor propertyDescriptor, EventDescriptor eventDescriptor ) - { - m_propertyDescriptor = new WeakReference( propertyDescriptor ); - m_eventDescriptor = new WeakReference( eventDescriptor ); - } - - private ValueChangeDataItemIndexerDescriptor PropertyDescriptor - { - get - { - return m_propertyDescriptor.Target as ValueChangeDataItemIndexerDescriptor; - } - } - - private EventDescriptor EventDescriptor - { - get - { - return m_eventDescriptor.Target as EventDescriptor; - } - } - - internal void AddValueChanged( object component ) - { - var descriptor = this.EventDescriptor; - if( descriptor == null ) - return; - - var handlerType = descriptor.EventType; - - if( typeof( PropertyChangedEventHandler ).IsAssignableFrom( handlerType ) ) - { - descriptor.AddEventHandler( component, new PropertyChangedEventHandler( this.OnPropertyChanged ) ); - } - } - - internal void RemoveValueChanged( object component ) - { - var descriptor = this.EventDescriptor; - if( descriptor == null ) - return; - - var handlerType = descriptor.EventType; - - if( typeof( PropertyChangedEventHandler ).IsAssignableFrom( handlerType ) ) - { - descriptor.RemoveEventHandler( component, new PropertyChangedEventHandler( this.OnPropertyChanged ) ); - } - } - - private void OnPropertyChanged( object sender, PropertyChangedEventArgs e ) - { - var propertyDescriptor = this.PropertyDescriptor; - if( propertyDescriptor != null ) - { - propertyDescriptor.OnPropertyChanged( sender, e ); - } - else - { - // Since the real listener is no longer available, try to unregister the handler. - this.RemoveValueChanged( sender ); - } - } - - private readonly WeakReference m_propertyDescriptor; - private readonly WeakReference m_eventDescriptor; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ValueChangeDataItemPropertyDescriptor.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ValueChangeDataItemPropertyDescriptor.cs deleted file mode 100644 index 4fdec3b9..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/ValueChangeDataItemPropertyDescriptor.cs +++ /dev/null @@ -1,237 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics; -using System.Globalization; - -namespace Xceed.Wpf.DataGrid -{ - internal sealed class ValueChangeDataItemPropertyDescriptor : DataItemPropertyDescriptor - { - internal ValueChangeDataItemPropertyDescriptor( - DataItemTypeDescriptor owner, - PropertyDescriptor parent, - Type componentType, - Type propertyType, - Func getter, - Action setter, - Action resetter, - EventDescriptor eventDescriptor ) - : base( owner, parent, componentType, propertyType, getter, setter, resetter ) - { - if( eventDescriptor == null ) - throw new ArgumentNullException( "eventDescriptor" ); - - m_eventDescriptor = eventDescriptor; - m_eventProxy = new EventProxy( this, eventDescriptor ); - } - - #region SupportsChangeEvents Property - - public override bool SupportsChangeEvents - { - get - { - return true; - } - } - - #endregion - - public override int GetHashCode() - { - return base.GetHashCode(); - } - - public override bool Equals( object obj ) - { - var descriptor = obj as ValueChangeDataItemPropertyDescriptor; - if( object.ReferenceEquals( descriptor, null ) ) - return false; - - return ( object.Equals( descriptor.m_eventDescriptor, m_eventDescriptor ) ) - && ( base.Equals( descriptor ) ); - } - - protected override void AddValueChangedCore( object component ) - { - if( component == null ) - return; - - m_eventProxy.AddValueChanged( component ); - } - - protected override void RemoveValueChangedCore( object component ) - { - if( component == null ) - return; - - m_eventProxy.RemoveValueChanged( component ); - } - - protected override bool MustInhibitValueChanged( object component ) - { - return ( ( m_inhibitValueChanged == null ) || !m_inhibitValueChanged.Contains( component ) ) - && ( this.GetValueChangedHandler( component ) != null ); - } - - protected override bool IsValueChangedInhibited( object component ) - { - return ( m_inhibitValueChanged != null ) - && ( m_inhibitValueChanged.Contains( component ) ); - } - - protected override void InhibitValueChanged( object component ) - { - if( m_inhibitValueChanged == null ) - { - m_inhibitValueChanged = new HashSet(); - } - - m_inhibitValueChanged.Add( component ); - } - - protected override void ResetInhibitValueChanged( object component ) - { - Debug.Assert( m_inhibitValueChanged != null ); - - m_inhibitValueChanged.Remove( component ); - - if( m_inhibitValueChanged.Count == 0 ) - { - m_inhibitValueChanged = null; - } - } - - private void OnPropertyChanged( object sender, EventArgs e ) - { - var propertyChangedEventArgs = e as PropertyChangedEventArgs; - if( propertyChangedEventArgs != null ) - { - var propertyName = propertyChangedEventArgs.PropertyName; - - if( !string.IsNullOrEmpty( propertyName ) && ( string.Compare( propertyName, this.Name, false, CultureInfo.InvariantCulture ) != 0 ) ) - return; - } - - this.OnValueChanged( sender, e ); - } - - #region Private Fields - - private readonly EventProxy m_eventProxy; - private readonly EventDescriptor m_eventDescriptor; - private HashSet m_inhibitValueChanged; - - #endregion - - #region EventProxy Private Class - - private sealed class EventProxy - { - internal EventProxy( ValueChangeDataItemPropertyDescriptor propertyDescriptor, EventDescriptor eventDescriptor ) - { - m_propertyDescriptor = new WeakReference( propertyDescriptor ); - m_eventDescriptor = new WeakReference( eventDescriptor ); - } - - private ValueChangeDataItemPropertyDescriptor PropertyDescriptor - { - get - { - return m_propertyDescriptor.Target as ValueChangeDataItemPropertyDescriptor; - } - } - - private EventDescriptor EventDescriptor - { - get - { - return m_eventDescriptor.Target as EventDescriptor; - } - } - - internal void AddValueChanged( object component ) - { - var descriptor = this.EventDescriptor; - if( descriptor == null ) - return; - - var handlerType = descriptor.EventType; - - if( typeof( PropertyChangedEventHandler ).IsAssignableFrom( handlerType ) ) - { - descriptor.AddEventHandler( component, new PropertyChangedEventHandler( this.OnPropertyChanged ) ); - } - else if( typeof( EventHandler ).IsAssignableFrom( handlerType ) ) - { - descriptor.AddEventHandler( component, new EventHandler( this.OnPropertyChanged ) ); - } - } - - internal void RemoveValueChanged( object component ) - { - var descriptor = this.EventDescriptor; - if( descriptor == null ) - return; - - var handlerType = descriptor.EventType; - - if( typeof( PropertyChangedEventHandler ).IsAssignableFrom( handlerType ) ) - { - descriptor.RemoveEventHandler( component, new PropertyChangedEventHandler( this.OnPropertyChanged ) ); - } - else if( typeof( EventHandler ).IsAssignableFrom( handlerType ) ) - { - descriptor.RemoveEventHandler( component, new EventHandler( this.OnPropertyChanged ) ); - } - } - - private void HandlePropertyChanged( object sender, EventArgs e ) - { - var propertyDescriptor = this.PropertyDescriptor; - - if( propertyDescriptor != null ) - { - propertyDescriptor.OnPropertyChanged( sender, e ); - } - else - { - // Since the real listener is no longer available, try to unregister the handler. - this.RemoveValueChanged( sender ); - } - } - - private void OnPropertyChanged( object sender, EventArgs e ) - { - this.HandlePropertyChanged( sender, e ); - } - - private void OnPropertyChanged( object sender, PropertyChangedEventArgs e ) - { - this.HandlePropertyChanged( sender, e ); - } - - private readonly WeakReference m_propertyDescriptor; - private readonly WeakReference m_eventDescriptor; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/ColumnVirtualizationManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/ColumnVirtualizationManager.cs deleted file mode 100644 index a0a47d2b..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/ColumnVirtualizationManager.cs +++ /dev/null @@ -1,300 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; -using System.Diagnostics; -using System.Windows; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal class ColumnVirtualizationManager : DependencyObject, IWeakEventListener - { - static ColumnVirtualizationManager() - { - ColumnVirtualizationManager.ColumnVirtualizationManagerProperty = ColumnVirtualizationManager.ColumnVirtualizationManagerPropertyKey.DependencyProperty; - } - - public ColumnVirtualizationManager( DataGridContext dataGridContext ) - { - Debug.Assert( dataGridContext != null ); - m_dataGridContext = dataGridContext; - - // Assign the ColumnVirtualizationManager to the DataGridContext - ColumnVirtualizationManager.SetColumnVirtualizationManager( m_dataGridContext, this ); - - this.Initialize(); - - unchecked - { - m_version++; - } - } - - #region ColumnVirtualizationManager Property - - private static readonly DependencyPropertyKey ColumnVirtualizationManagerPropertyKey = DependencyProperty.RegisterAttachedReadOnly( - "ColumnVirtualizationManager", - typeof( ColumnVirtualizationManager ), - typeof( ColumnVirtualizationManager ), - new UIPropertyMetadata( null, new PropertyChangedCallback( ColumnVirtualizationManager.OnColumnVirtualizationManagerChanged ) ) ); - - public static readonly DependencyProperty ColumnVirtualizationManagerProperty; - - public static ColumnVirtualizationManager GetColumnVirtualizationManager( DependencyObject obj ) - { - return ( ColumnVirtualizationManager )obj.GetValue( ColumnVirtualizationManager.ColumnVirtualizationManagerProperty ); - } - - internal static void SetColumnVirtualizationManager( DependencyObject obj, ColumnVirtualizationManager value ) - { - obj.SetValue( ColumnVirtualizationManager.ColumnVirtualizationManagerPropertyKey, value ); - } - - internal static void ClearColumnVirtualizationManager( DependencyObject obj ) - { - obj.ClearValue( ColumnVirtualizationManager.ColumnVirtualizationManagerPropertyKey ); - } - - private static void OnColumnVirtualizationManagerChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var self = sender as ColumnVirtualizationManager; - if( self == null ) - return; - - var dataGridContext = self.DataGridContext; - if( dataGridContext == null ) - return; - - var column = dataGridContext.Columns.MainColumn; - if( column == null ) - return; - - column.RefreshDraggableStatus(); - } - - #endregion - - #region NeedsUpdate Property - - public bool NeedsUpdate - { - get - { - return ( m_currentVersion != m_version ); - } - } - - #endregion - - #region DataGridContext Property - - public DataGridContext DataGridContext - { - get - { - return m_dataGridContext; - } - } - - private DataGridContext m_dataGridContext; //null; - - #endregion - - #region Version Proptety - - public int Version - { - get - { - return m_version; - } - } - - private int m_version; //0; - - #endregion - - public void Update() - { - if( !this.NeedsUpdate ) - return; - - this.PreUpdate(); - this.ResetInternalState(); - this.DoUpdate(); - this.PostUpdate(); - } - - public virtual void CleanManager() - { - this.Uninitialize(); - } - - protected virtual void PreUpdate() - { - // To be able to keep the previous state of the manager before updating - } - - protected virtual void DoUpdate() - { - } - - // Called after PreUpdate in Update method - protected virtual void ResetInternalState() - { - } - - protected virtual void PostUpdate() - { - // Update was completed correctly - m_currentVersion = m_version; - } - - // Called after attaching ColumnVirtualizationManager to DataGridContext - protected virtual void Initialize() - { - PropertyChangedEventManager.AddListener( m_dataGridContext, this, string.Empty ); - ItemsSourceChangeCompletedEventManager.AddListener( m_dataGridContext.DataGridControl, this ); - ViewChangedEventManager.AddListener( m_dataGridContext.DataGridControl, this ); - ThemeChangedEventManager.AddListener( m_dataGridContext.DataGridControl, this ); - ColumnsLayoutChangingEventManager.AddListener( m_dataGridContext.ColumnManager, this ); - ColumnsLayoutChangedEventManager.AddListener( m_dataGridContext.ColumnManager, this ); - } - - // Called before detaching ColumnVirtualizationManager from DataGridContext - protected virtual void Uninitialize() - { - this.ResetInternalState(); - - PropertyChangedEventManager.RemoveListener( m_dataGridContext, this, string.Empty ); - ItemsSourceChangeCompletedEventManager.RemoveListener( m_dataGridContext.DataGridControl, this ); - ViewChangedEventManager.RemoveListener( m_dataGridContext.DataGridControl, this ); - ThemeChangedEventManager.RemoveListener( m_dataGridContext.DataGridControl, this ); - ColumnsLayoutChangingEventManager.RemoveListener( m_dataGridContext.ColumnManager, this ); - ColumnsLayoutChangedEventManager.RemoveListener( m_dataGridContext.ColumnManager, this ); - - m_dataGridContext = null; - } - - protected virtual void IncrementVersion( UpdateMeasureRequiredEventArgs e ) - { - unchecked - { - m_version++; - } - } - - protected virtual void OnDataGridContextPropertyChanged( PropertyChangedEventArgs e ) - { - Debug.Assert( !string.IsNullOrEmpty( e.PropertyName ) ); - - if( string.IsNullOrEmpty( e.PropertyName ) ) - return; - - switch( e.PropertyName ) - { - case "CurrentColumn": - this.IncrementVersion( null ); - break; - } - } - - protected virtual void OnColumnsLayoutChanging() - { - } - - protected virtual void OnColumnsLayoutChanged() - { - this.IncrementVersion( new UpdateMeasureRequiredEventArgs( UpdateMeasureTriggeredAction.Unspecified ) ); - } - - protected virtual void OnDataGridControlViewChanged() - { - this.IncrementVersion( new UpdateMeasureRequiredEventArgs( UpdateMeasureTriggeredAction.Unspecified ) ); - } - - protected virtual void OnDataGridControlThemeChanged() - { - this.IncrementVersion( new UpdateMeasureRequiredEventArgs( UpdateMeasureTriggeredAction.Unspecified ) ); - } - - protected virtual void OnDataGridControlItemsSourceChanged() - { - } - - private int m_currentVersion; //0; - - #region IWeakEventListener Members - - 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 ) - { - var detach = false; - - if( managerType == typeof( PropertyChangedEventManager ) ) - { - if( sender == m_dataGridContext ) - { - this.OnDataGridContextPropertyChanged( ( PropertyChangedEventArgs )e ); - } - } - else if( managerType == typeof( ColumnsLayoutChangingEventManager ) ) - { - this.OnColumnsLayoutChanging(); - } - else if( managerType == typeof( ColumnsLayoutChangedEventManager ) ) - { - this.OnColumnsLayoutChanged(); - } - else if( managerType == typeof( ViewChangedEventManager ) ) - { - this.OnDataGridControlViewChanged(); - detach = true; - } - else if( managerType == typeof( ThemeChangedEventManager ) ) - { - this.OnDataGridControlThemeChanged(); - detach = true; - } - else if( managerType == typeof( ItemsSourceChangeCompletedEventManager ) ) - { - this.OnDataGridControlItemsSourceChanged(); - detach = true; - } - else - { - return false; - } - - if( detach && ( m_dataGridContext != null ) ) - { - // Detach the ColumnVirtualizationManager from the DataGridContext and detach from the DataGridContext - ColumnVirtualizationManager.SetColumnVirtualizationManager( m_dataGridContext, null ); - - this.Uninitialize(); - } - - return true; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/IColumnInfoCollection.Generic.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/IColumnInfoCollection.Generic.cs deleted file mode 100644 index 729da54d..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/IColumnInfoCollection.Generic.cs +++ /dev/null @@ -1,45 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - - -namespace Xceed.Wpf.DataGrid.Views -{ - internal interface IColumnInfoCollection - { - void Clear(); - - T this[ string fieldName ] - { - get; - set; - } - - T this[ ColumnBase column ] - { - get; - set; - } - - void Reset( string fieldName ); - void Reset( ColumnBase column ); - - bool Contains( string fieldName ); - bool Contains( ColumnBase column ); - - bool TryGetValue( string fieldName, out T value ); - bool TryGetValue( ColumnBase column, out T value ); - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/IColumnNameCollection.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/IColumnNameCollection.cs deleted file mode 100644 index 62062fa7..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/IColumnNameCollection.cs +++ /dev/null @@ -1,44 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Collections.Generic; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal interface IColumnNameCollection : IEnumerable - { - int Count - { - get; - } - - string this[ int index ] - { - get; - } - - void Clear(); - - void Add( string fieldName ); - void Add( ColumnBase column ); - - void Remove( string fieldName ); - void Remove( ColumnBase column ); - - bool Contains( string fieldName ); - bool Contains( ColumnBase column ); - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/TableViewColumnVirtualizationManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/TableViewColumnVirtualizationManager.cs deleted file mode 100644 index 3255ac45..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/TableViewColumnVirtualizationManager.cs +++ /dev/null @@ -1,225 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Collections.Generic; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal class TableViewColumnVirtualizationManager : TableViewColumnVirtualizationManagerBase - { - public TableViewColumnVirtualizationManager( DataGridContext dataGridContext ) - : base( dataGridContext ) - { - } - - #region FixedColumnsWidth Internal Property - - internal override double FixedColumnsWidth - { - get - { - return m_fixedColumnsWidth; - } - } - - protected override void SetFixedColumnsWidth( double value ) - { - m_fixedColumnsWidth = value; - } - - private double m_fixedColumnsWidth; - - #endregion - - #region ScrollingColumnsWidth Internal Property - - internal override double ScrollingColumnsWidth - { - get - { - return m_scrollingColumnsWidth; - } - } - - protected override void SetScrollingColumnsWidth( double value ) - { - m_scrollingColumnsWidth = value; - } - - private double m_scrollingColumnsWidth; - - #endregion - - #region VisibleColumnsWidth Internal Property - - internal override double VisibleColumnsWidth - { - get - { - return m_visibleColumnsWidth; - } - } - - protected override void SetVisibleColumnsWidth( double value ) - { - m_visibleColumnsWidth = value; - } - - private double m_visibleColumnsWidth; - - #endregion - - #region FieldNameToOffset Internal Property - - internal override IColumnInfoCollection FieldNameToOffset - { - get - { - return m_fieldNameToOffset; - } - } - - private readonly IColumnInfoCollection m_fieldNameToOffset = new TableViewColumnVirtualizationManagerBase.ColumnInfoCollection(); - - #endregion - - #region FieldNameToWidth Internal Property - - internal override IColumnInfoCollection FieldNameToWidth - { - get - { - return m_fieldNameToWidth; - } - } - - private readonly IColumnInfoCollection m_fieldNameToWidth = new TableViewColumnVirtualizationManagerBase.ColumnInfoCollection(); - - #endregion - - #region FieldNameToPosition Internal Property - - internal override IColumnInfoCollection FieldNameToPosition - { - get - { - return m_fieldNameToPosition; - } - } - - private readonly IColumnInfoCollection m_fieldNameToPosition = new TableViewColumnVirtualizationManagerBase.ColumnInfoCollection(); - - #endregion - - #region MergedNameToOffset Property - - internal override IList> MergedNameToOffset - { - get - { - return m_mergedNameToOffset; - } - } - - private readonly IList> m_mergedNameToOffset = new List>(); - - #endregion - - #region MergedNameToWidth Property - - internal override IList> MergedNameToWidth - { - get - { - return m_mergedNameToWidth; - } - } - - private readonly IList> m_mergedNameToWidth = new List>(); - - #endregion - - #region MergedNameToPostion Property - - internal override IList> MergedNameToPostion - { - get - { - return m_mergedNameToPostion; - } - } - - private readonly IList> m_mergedNameToPostion = new List>(); - - #endregion - - #region FixedFieldNames Internal Property - - internal override IColumnNameCollection FixedFieldNames - { - get - { - return m_fixedFieldNames; - } - } - - private readonly IColumnNameCollection m_fixedFieldNames = new TableViewColumnVirtualizationManagerBase.ColumnNameCollection(); - - #endregion - - #region ScrollingFieldNames Internal Property - - internal override IColumnNameCollection ScrollingFieldNames - { - get - { - return m_scrollingFieldNames; - } - } - - private readonly IColumnNameCollection m_scrollingFieldNames = new TableViewColumnVirtualizationManagerBase.ColumnNameCollection(); - - #endregion - - #region FixedMergedNames Internal Property - - internal override IList FixedMergedNames - { - get - { - return m_fixedMergedNames; - } - } - - private readonly List m_fixedMergedNames = new List(); - - #endregion - - #region ScrollingMergedNames Internal Property - - internal override IList ScrollingMergedNames - { - get - { - return m_scrollingMergedNames; - } - } - - private readonly List m_scrollingMergedNames = new List(); - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/TableViewColumnVirtualizationManagerBase.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/TableViewColumnVirtualizationManagerBase.cs deleted file mode 100644 index 682e7176..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/TableViewColumnVirtualizationManagerBase.cs +++ /dev/null @@ -1,1352 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Diagnostics; -using System.Linq; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Controls.Primitives; -using System.Windows.Data; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal abstract class TableViewColumnVirtualizationManagerBase : ColumnVirtualizationManager - { - protected TableViewColumnVirtualizationManagerBase( DataGridContext dataGridContext ) - : base( dataGridContext ) - { - } - - #region VirtualizationMode Property - - protected static readonly DependencyProperty VirtualizationModeProperty = DependencyProperty.Register( - "VirtualizationMode", - typeof( ColumnVirtualizationMode ), - typeof( TableViewColumnVirtualizationManagerBase ), - new UIPropertyMetadata( ColumnVirtualizationMode.Recycling, new PropertyChangedCallback( TableViewColumnVirtualizationManagerBase.OnVirtualizationModeChanged ) ) ); - - public ColumnVirtualizationMode VirtualizationMode - { - get - { - return ( ColumnVirtualizationMode )this.GetValue( TableViewColumnVirtualizationManagerBase.VirtualizationModeProperty ); - } - set - { - this.SetValue( TableViewColumnVirtualizationManagerBase.VirtualizationModeProperty, value ); - } - } - - protected virtual void OnVirtualizationModeChanged( ColumnVirtualizationMode oldValue, ColumnVirtualizationMode newValue ) - { - this.OnVirtualizingCellCollectionUpdateRequired( - new VirtualizingCellCollectionUpdateRequiredEventArgs( VirtualizingCellCollectionUpdateTriggeredAction.VirtualizationModeChanged ) ); - } - - private static void OnVirtualizationModeChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var manager = sender as TableViewColumnVirtualizationManagerBase; - if( manager == null ) - return; - - manager.OnVirtualizationModeChanged( ( ColumnVirtualizationMode )e.OldValue, ( ColumnVirtualizationMode )e.NewValue ); - } - - #endregion - - #region FirstColumnCompensationOffset Property - - // This field is set by the FixedCellPanel in OnCompensationOffsetChanged when the AttachedPropertyChanges - protected static readonly DependencyProperty FirstColumnCompensationOffsetProperty = DependencyProperty.Register( - "FirstColumnCompensationOffset", - typeof( double ), - typeof( TableViewColumnVirtualizationManagerBase ), - new FrameworkPropertyMetadata( - 0d, - new PropertyChangedCallback( TableViewColumnVirtualizationManagerBase.OnFirstColumnCompensationOffsetChanged ) ) ); - - public double FirstColumnCompensationOffset - { - get - { - return ( double )this.GetValue( TableViewColumnVirtualizationManagerBase.FirstColumnCompensationOffsetProperty ); - } - set - { - this.SetValue( TableViewColumnVirtualizationManagerBase.FirstColumnCompensationOffsetProperty, value ); - } - } - - protected virtual void OnFirstColumnCompensationOffsetChanged( double oldValue, double newValue ) - { - this.IncrementVersion( new UpdateMeasureRequiredEventArgs( UpdateMeasureTriggeredAction.Unspecified ) ); - } - - private static void OnFirstColumnCompensationOffsetChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var manager = sender as TableViewColumnVirtualizationManagerBase; - if( manager == null ) - return; - - manager.OnFirstColumnCompensationOffsetChanged( ( double )e.OldValue, ( double )e.NewValue ); - } - - #endregion - - #region FixedColumnCount Protected Property - - protected static readonly DependencyProperty FixedColumnCountProperty = DependencyProperty.Register( - "FixedColumnCount", - typeof( int ), - typeof( TableViewColumnVirtualizationManagerBase ), - new UIPropertyMetadata( 0, new PropertyChangedCallback( TableViewColumnVirtualizationManagerBase.OnFixedColumnCountChanged ), - new CoerceValueCallback( TableViewColumnVirtualizationManagerBase.CoerceFixedColumnCount ) ) ); - - // Only used to back the dp. The dp itself is used as the API for the user to change the fixed column count (through TableView binding), - // and the PropertyChangedCallback redirect the value to the top most manager row. - protected int FixedColumnCount - { - get - { - return ( int )this.GetValue( TableViewColumnVirtualizationManagerBase.FixedColumnCountProperty ); - } - set - { - this.SetValue( TableViewColumnVirtualizationManagerBase.FixedColumnCountProperty, value ); - } - } - - private static void OnFixedColumnCountChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var self = sender as TableViewColumnVirtualizationManagerBase; - if( self == null ) - return; - - self.OnFixedColumnCountChanged( ( int )e.OldValue, ( int )e.NewValue ); - } - - private static object CoerceFixedColumnCount( DependencyObject sender, object value ) - { - var self = sender as TableViewColumnVirtualizationManagerBase; - var count = ( int )value; - - if( ( count == 0 ) || ( self == null ) ) - return value; - - var dataGridContext = self.DataGridContext; - if( dataGridContext == null ) - return value; - - if( count < 0 ) - return 0; - - var columns = dataGridContext.VisibleColumns; - var max = columns.Count; - - if( count > max ) - return max; - - return value; - } - - private void OnFixedColumnCountChanged( int oldValue, int newValue ) - { - var dataGridContext = this.DataGridContext; - if( dataGridContext == null ) - return; - - var columnManager = dataGridContext.ColumnManager; - columnManager.SetFixedColumnCount( newValue ); - } - - #endregion - - #region FixedColumnsWidth Internal Property - - internal abstract double FixedColumnsWidth - { - get; - } - - protected abstract void SetFixedColumnsWidth( double value ); - - #endregion - - #region ScrollingColumnsWidth Internal Property - - // The width of all visible columns in - internal abstract double ScrollingColumnsWidth - { - get; - } - - protected abstract void SetScrollingColumnsWidth( double value ); - - #endregion - - #region VisibleColumnsWidth Internal Property - - // The width of all visible columns (fixed and scrolling ones) - internal abstract double VisibleColumnsWidth - { - get; - } - - protected abstract void SetVisibleColumnsWidth( double value ); - - #endregion - - #region FieldNameToOffset Internal Property - - internal abstract IColumnInfoCollection FieldNameToOffset - { - get; - } - - #endregion - - #region FieldNameToWidth Internal Property - - internal abstract IColumnInfoCollection FieldNameToWidth - { - get; - } - - #endregion - - #region FieldNameToPosition Internal Property - - internal abstract IColumnInfoCollection FieldNameToPosition - { - get; - } - - #endregion - - #region MergedNameToOffset Internal Property - - internal abstract IList> MergedNameToOffset - { - get; - } - - #endregion - - #region MergedNameToWidth Internal Property - - internal abstract IList> MergedNameToWidth - { - get; - } - - #endregion - - #region MergedNameToPostion Internal Property - - internal abstract IList> MergedNameToPostion - { - get; - } - - #endregion - - #region FixedFieldNames Internal Property - - internal abstract IColumnNameCollection FixedFieldNames - { - get; - } - - #endregion - - #region ScrollingFieldNames Internal Property - - internal abstract IColumnNameCollection ScrollingFieldNames - { - get; - } - - #endregion - - #region VisibleFieldNames Internal Property - - internal IColumnNameCollection VisibleFieldNames - { - get - { - return new ColumnNameLookup( new IColumnNameCollection[] { this.FixedFieldNames, this.ScrollingFieldNames } ); - } - } - - #endregion - - #region FixedMergedNames Internal Property - - internal abstract IList FixedMergedNames - { - get; - } - - #endregion - - #region ScrollingMergedNames Internal Property - - internal abstract IList ScrollingMergedNames - { - get; - } - - #endregion - - #region VisibleMergedFieldNames Internal Property - - internal IList VisibleMergedFieldNames - { - get - { - var fixedFieldNames = this.FixedMergedNames; - var scrollingFieldNames = this.ScrollingMergedNames; - - Debug.Assert( fixedFieldNames != null ); - Debug.Assert( scrollingFieldNames != null ); - Debug.Assert( fixedFieldNames.Count == scrollingFieldNames.Count ); - - var count = fixedFieldNames.Count; - var retval = new List( count ); - - for( int i = 0; i < count; i++ ) - { - retval.Add( new ColumnNameLookup( new IColumnNameCollection[] { fixedFieldNames[ i ], scrollingFieldNames[ i ] } ) ); - } - - return retval.AsReadOnly(); - } - } - - #endregion - - #region ScrollViewer Private Property - - private ScrollViewer ScrollViewer - { - get - { - return m_scrollViewer; - } - set - { - if( value == m_scrollViewer ) - return; - - if( m_scrollViewer != null ) - { - m_scrollViewer.ScrollChanged -= new ScrollChangedEventHandler( this.ScrollViewer_ScrollChanged ); - } - - m_scrollViewer = value; - - if( m_scrollViewer != null ) - { - m_scrollViewer.ScrollChanged += new ScrollChangedEventHandler( this.ScrollViewer_ScrollChanged ); - } - } - } - - private void ScrollViewer_ScrollChanged( object sender, ScrollChangedEventArgs e ) - { - //If only scrolling vertically, there is no changes to columns in view, thus no need to update this manager, and therefore no need to make FixedCellPanels update. - if( e.VerticalChange != 0 ) - { - if( ( e.ExtentHeightChange == 0 ) && ( e.ExtentWidthChange == 0 ) && ( e.HorizontalChange == 0 ) && - ( e.ViewportHeightChange == 0 ) && ( e.ViewportWidthChange == 0 ) ) - return; - } - - var dataGridContext = this.DataGridContext; - if( dataGridContext == null ) - return; - - var dataGridControl = dataGridContext.DataGridControl; - if( dataGridControl == null ) - return; - - if( e.OriginalSource != dataGridControl.ScrollViewer ) - return; - - this.IncrementVersion( new UpdateMeasureRequiredEventArgs( UpdateMeasureTriggeredAction.ScrollViewerChanged ) ); - } - - private void UpdateScrollViewer() - { - var dataGridContext = this.DataGridContext; - - this.ScrollViewer = ( dataGridContext != null ) ? dataGridContext.DataGridControl.ScrollViewer : null; - } - - private ScrollViewer m_scrollViewer; //null; - - #endregion - - #region UpdateMeasureRequired Public Event - - // This event will be use to notify every listener that the DataGridControl's layout has changed and they must at least call MeasureOverride - public event EventHandler UpdateMeasureRequired; - - protected void OnUpdateMeasureRequired( UpdateMeasureRequiredEventArgs e ) - { - // If the manager is detached, it means it will be soon collected, thus don't send update notifications to FixedCellPanels that can still be hook to it (but being recycled). - if( this.DataGridContext == null ) - return; - - var handler = this.UpdateMeasureRequired; - if( handler == null ) - return; - - handler.Invoke( this, e ); - } - - #endregion - - #region VirtualizingCellCollectionUpdateRequired Public Event - - // This event is raised so FixedCellPanels can update their cell collections accordingly to changes in columns in the ColumnVirtualizingMode they are currently in. - public event EventHandler VirtualizingCellCollectionUpdateRequired; - - protected void OnVirtualizingCellCollectionUpdateRequired( VirtualizingCellCollectionUpdateRequiredEventArgs e ) - { - // If the manager is detached, it means it will be soon collected, thus don't send update notifications to FixedCellPanels that can still be hook to it (but being recycled). - if( this.DataGridContext == null ) - return; - - var handler = this.VirtualizingCellCollectionUpdateRequired; - if( handler == null ) - return; - - handler.Invoke( this, e ); - } - - #endregion - - protected override void Initialize() - { - base.Initialize(); - - CollectionChangedEventManager.AddListener( this.DataGridContext.Items.SortDescriptions, this ); - CollectionChangedEventManager.AddListener( this.DataGridContext.Items.GroupDescriptions, this ); - ColumnActualWidthEventManager.AddListener( this.DataGridContext.Columns, this ); - DataGridControlTemplateChangedEventManager.AddListener( this.DataGridContext.DataGridControl, this ); - - this.UpdateScrollViewer(); - - var fixedColumnCountBindingBase = new Binding( TableView.FixedColumnCountProperty.Name ); - fixedColumnCountBindingBase.Source = this.DataGridContext; - fixedColumnCountBindingBase.Mode = BindingMode.TwoWay; - BindingOperations.SetBinding( this, TableViewColumnVirtualizationManagerBase.FixedColumnCountProperty, fixedColumnCountBindingBase ); - - var compensationOffsetBinding = new Binding(); - compensationOffsetBinding.Path = new PropertyPath( TableView.CompensationOffsetProperty ); - compensationOffsetBinding.Source = this.DataGridContext; - compensationOffsetBinding.Mode = BindingMode.OneWay; - BindingOperations.SetBinding( this, TableViewColumnVirtualizationManagerBase.FirstColumnCompensationOffsetProperty, compensationOffsetBinding ); - - var columnVirtualizationModeBindingBase = new Binding(); - columnVirtualizationModeBindingBase.Source = this.DataGridContext; - columnVirtualizationModeBindingBase.Path = new PropertyPath( TableView.ColumnVirtualizationModeProperty.Name ); - columnVirtualizationModeBindingBase.Mode = BindingMode.OneWay; - BindingOperations.SetBinding( this, TableViewColumnVirtualizationManagerBase.VirtualizationModeProperty, columnVirtualizationModeBindingBase ); - } - - protected override void Uninitialize() - { - BindingOperations.ClearBinding( this, TableViewColumnVirtualizationManagerBase.VirtualizationModeProperty ); - BindingOperations.ClearBinding( this, TableViewColumnVirtualizationManagerBase.FirstColumnCompensationOffsetProperty ); - BindingOperations.ClearBinding( this, TableViewColumnVirtualizationManagerBase.FixedColumnCountProperty ); - - this.ScrollViewer = null; - - CollectionChangedEventManager.RemoveListener( this.DataGridContext.Items.SortDescriptions, this ); - CollectionChangedEventManager.RemoveListener( this.DataGridContext.Items.GroupDescriptions, this ); - ColumnActualWidthEventManager.RemoveListener( this.DataGridContext.Columns, this ); - DataGridControlTemplateChangedEventManager.RemoveListener( this.DataGridContext.DataGridControl, this ); - - base.Uninitialize(); - } - - protected override void ResetInternalState() - { - this.SetFixedColumnsWidth( 0d ); - this.SetScrollingColumnsWidth( 0d ); - this.SetVisibleColumnsWidth( 0d ); - - this.FieldNameToOffset.Clear(); - this.FieldNameToWidth.Clear(); - this.FieldNameToPosition.Clear(); - this.MergedNameToOffset.Clear(); - this.MergedNameToPostion.Clear(); - this.MergedNameToWidth.Clear(); - - this.FixedFieldNames.Clear(); - this.ScrollingFieldNames.Clear(); - this.FixedMergedNames.Clear(); - this.ScrollingMergedNames.Clear(); - } - - protected override void DoUpdate() - { - var dataGridContext = this.DataGridContext; - Debug.Assert( dataGridContext != null ); - - var columnManager = dataGridContext.ColumnManager; - Debug.Assert( columnManager != null ); - - // Make sure the fixed column count is up-to-date. - this.CoerceValue( TableViewColumnVirtualizationManagerBase.FixedColumnCountProperty ); - - //It can happen that the columnManager has not been initialized yet (e.g. when creating a grid in code behind), so make sure markers are not null. - var levelMarkers = columnManager.GetLevelMarkersFor( dataGridContext.Columns ); - if( levelMarkers == null ) - return; - - var currentLocation = levelMarkers.Start; - Debug.Assert( currentLocation != null ); - Debug.Assert( currentLocation.Type == LocationType.Start ); - - var columnPosition = 0; - var visibleColumnsTotalWidth = 0d; - - // Fill the data structures for the fixed columns. - while( currentLocation.Type != LocationType.Splitter ) - { - var columnLocation = currentLocation as ColumnHierarchyManager.IColumnLocation; - if( columnLocation != null ) - { - var column = columnLocation.Column; - Debug.Assert( column != null ); - - // Ensure we keep the correct visible offset for all columns even if they are collpased - this.FieldNameToOffset[ column ] = visibleColumnsTotalWidth; - - if( column.Visible ) - { - var width = column.ActualWidth; - - this.FixedFieldNames.Add( column ); - this.FieldNameToPosition[ column ] = columnPosition; - this.FieldNameToWidth[ column ] = width; - - visibleColumnsTotalWidth += width; - } - - columnPosition++; - } - else - { - Debug.Assert( currentLocation.Type != LocationType.Column ); - } - - currentLocation = currentLocation.GetNextSiblingOrCousin(); - Debug.Assert( currentLocation != null ); - } - - this.SetFixedColumnsWidth( visibleColumnsTotalWidth ); - - var horizontalOffset = this.GetHorizontalOffset(); - var viewportWidth = this.GetViewportWidth(); - - if( this.VirtualizationMode != ColumnVirtualizationMode.None ) - { - // We increment the horizontalOffset to take the fixed columns width into consideration. - horizontalOffset += visibleColumnsTotalWidth; - viewportWidth = Math.Max( 0d, viewportWidth - visibleColumnsTotalWidth ); - } - - // We must consider the fixed columns width when calculating visible indexes in viewport - var viewportMaximumOffset = horizontalOffset + viewportWidth; - var visibleScrollingColumnsTotalWidth = 0d; - - // Fill the data structures for the scrolling columns. - while( currentLocation.Type != LocationType.Orphan ) - { - var columnLocation = currentLocation as ColumnHierarchyManager.IColumnLocation; - if( columnLocation != null ) - { - var column = columnLocation.Column; - Debug.Assert( column != null ); - - // Ensure we keep the correct visible offset for all columns even if they are collapsed - this.FieldNameToOffset[ column ] = visibleColumnsTotalWidth; - - if( column.Visible ) - { - var width = column.ActualWidth; - var leftEdgeOffset = visibleColumnsTotalWidth; - var rightEdgeOffset = leftEdgeOffset + width; - - this.FieldNameToPosition[ column ] = columnPosition; - this.FieldNameToWidth[ column ] = width; - - visibleColumnsTotalWidth += width; - visibleScrollingColumnsTotalWidth += width; - - if( this.VirtualizationMode != ColumnVirtualizationMode.None ) - { - // The column is in the viewport. - if( ( leftEdgeOffset < viewportMaximumOffset ) && ( rightEdgeOffset > horizontalOffset ) ) - { - this.ScrollingFieldNames.Add( column ); - } - } - else - { - this.ScrollingFieldNames.Add( column ); - } - } - - columnPosition++; - } - else - { - Debug.Assert( currentLocation.Type != LocationType.Column ); - } - - currentLocation = currentLocation.GetNextSiblingOrCousin(); - Debug.Assert( currentLocation != null ); - } - - this.SetScrollingColumnsWidth( visibleScrollingColumnsTotalWidth ); - this.SetVisibleColumnsWidth( visibleColumnsTotalWidth ); - } - - protected override void IncrementVersion( UpdateMeasureRequiredEventArgs e ) - { - base.IncrementVersion( e ); - - this.OnUpdateMeasureRequired( e ); - } - - protected override void OnDataGridContextPropertyChanged( PropertyChangedEventArgs e ) - { - base.OnDataGridContextPropertyChanged( e ); - - Debug.Assert( !string.IsNullOrEmpty( e.PropertyName ) ); - - if( string.IsNullOrEmpty( e.PropertyName ) ) - return; - - switch( e.PropertyName ) - { - case "FixedHeaderFooterViewPortSize": - this.IncrementVersion( new UpdateMeasureRequiredEventArgs( UpdateMeasureTriggeredAction.ViewPortWidthChanged ) ); - break; - - case "CurrentItem": - // No need to increment version, only notify the current item to invalidate measure - this.OnUpdateMeasureRequired( new UpdateMeasureRequiredEventArgs( UpdateMeasureTriggeredAction.CurrentItemChanged ) ); - break; - } - } - - protected override void OnColumnsLayoutChanging() - { - m_columnsVisibilitySnapshot.Clear(); - - var dataGridContext = this.DataGridContext; - if( dataGridContext != null ) - { - // We consult the VisibleColumns collection to figure if a column was visible or not instead - // of the ColumnBase.Visible property because the property may already be tainted by a change - // at this step. - var visibleColumns = ( ReadOnlyColumnCollection )dataGridContext.VisibleColumns; - - foreach( var column in dataGridContext.Columns ) - { - // This line of code is equivalent to - // m_columnsVisibilitySnapshot[ column ] = visibleColumns.Contains( column ); - // However, the result is found in O(1) instead of O(n). - m_columnsVisibilitySnapshot[ column ] = ( visibleColumns[ column.FieldName ] == column ); - } - } - - base.OnColumnsLayoutChanging(); - } - - protected override void OnColumnsLayoutChanged() - { - var columnsVisibilitySnapshot = new Dictionary( m_columnsVisibilitySnapshot ); - m_columnsVisibilitySnapshot.Clear(); - - var dataGridContext = this.DataGridContext; - if( dataGridContext != null ) - { - // When details are flatten, the detail DataGridContext's FixedColumnCount property is bound to the - // DataGridControl's FixedColumnCount property. Allowing the value to be changed here would destroy the binding. - if( !dataGridContext.IsAFlattenDetail ) - { - var columnManager = dataGridContext.ColumnManager; - var fixedColumnCount = columnManager.GetFixedColumnCount(); - - Debug.Assert( fixedColumnCount >= 0 ); - - this.FixedColumnCount = fixedColumnCount; - } - - this.IncrementVersion( new UpdateMeasureRequiredEventArgs( UpdateMeasureTriggeredAction.ColumnReordering ) ); - - var columns = dataGridContext.Columns; - - if( this.VirtualizationMode == ColumnVirtualizationMode.Virtualizing ) - { - // Notify the FixedCellPanel that some cells need to be created for new columns. - if( ( columnsVisibilitySnapshot.Count < columns.Count ) || ( columns.Any( c => !columnsVisibilitySnapshot.ContainsKey( c ) ) ) ) - { - this.OnVirtualizingCellCollectionUpdateRequired( new VirtualizingCellCollectionUpdateRequiredEventArgs( VirtualizingCellCollectionUpdateTriggeredAction.VisibleColumnsAdded ) ); - } - } - - // Figure out the columns that have changed visibility - if( columnsVisibilitySnapshot.Count > 0 ) - { - var columnChanges = new List(); - - foreach( var column in columns ) - { - bool visible; - - if( columnsVisibilitySnapshot.TryGetValue( column, out visible ) && ( column.Visible != visible ) ) - { - columnChanges.Add( column ); - } - } - - if( columnChanges.Count > 0 ) - { - this.OnVirtualizingCellCollectionUpdateRequired( new VirtualizingCellCollectionUpdateRequiredEventArgs( columnChanges ) ); - } - } - } - - base.OnColumnsLayoutChanged(); - } - - protected virtual void OnSortDescriptionsChanged( NotifyCollectionChangedEventArgs e ) - { - this.IncrementVersion( new UpdateMeasureRequiredEventArgs( UpdateMeasureTriggeredAction.SortingChanged ) ); - } - - protected virtual void OnGroupDescriptionsChanged( NotifyCollectionChangedEventArgs e ) - { - this.IncrementVersion( new UpdateMeasureRequiredEventArgs( UpdateMeasureTriggeredAction.GroupingChanged ) ); - } - - protected virtual void OnColumnActualWidthChanged( ColumnActualWidthChangedEventArgs e ) - { - // We pass the delta between the old and new value to tell the Panel to reduce the horizontal offset when a column is auto-resized to a smaller value - if( e != null ) - { - this.IncrementVersion( new UpdateMeasureRequiredEventArgs( UpdateMeasureTriggeredAction.ColumnActualWidthChanged, e.OldValue - e.NewValue ) ); - } - else - { - this.IncrementVersion( new UpdateMeasureRequiredEventArgs( UpdateMeasureTriggeredAction.ColumnActualWidthChanged ) ); - } - } - - protected virtual void OnDataGridControlTemplateChanged() - { - this.UpdateScrollViewer(); - this.IncrementVersion( new UpdateMeasureRequiredEventArgs( UpdateMeasureTriggeredAction.Unspecified ) ); - } - - internal IColumnInfoCollection GetFieldNameToOffset() - { - return this.GetFieldNameToOffset( -1 ); - } - - internal IColumnInfoCollection GetFieldNameToOffset( int level ) - { - if( level < 0 ) - return this.FieldNameToOffset; - - var collection = this.MergedNameToOffset; - if( collection.Count > 0 ) - return collection[ level ]; - - //If the list is empty, it means there is no column in the grid right now, so return an empty collection, as does the FieldNameToOffset property. - return new ColumnInfoCollection(); - } - - internal IColumnInfoCollection GetFieldNameToWidth() - { - return this.GetFieldNameToWidth( -1 ); - } - - internal IColumnInfoCollection GetFieldNameToWidth( int level ) - { - if( level < 0 ) - return this.FieldNameToWidth; - - var collection = this.MergedNameToWidth; - if( collection.Count > 0 ) - return collection[ level ]; - - //If the list is empty, it means there is no column in the grid right now, so return an empty collection, as does the FieldNameToWidth property. - return new ColumnInfoCollection(); - } - - internal IColumnInfoCollection GetFieldNameToPosition() - { - return this.GetFieldNameToPosition( -1 ); - } - - internal IColumnInfoCollection GetFieldNameToPosition( int level ) - { - if( level < 0 ) - return this.FieldNameToPosition; - - var collection = this.MergedNameToPostion; - if( collection.Count > 0 ) - return collection[ level ]; - - //If the list is empty, it means there is no column in the grid right now, so return an empty collection, as does the FieldNameToPosition property. - return new ColumnInfoCollection(); - } - - internal IColumnNameCollection GetFixedFieldNames() - { - return this.GetFixedFieldNames( -1 ); - } - - internal IColumnNameCollection GetFixedFieldNames( int level ) - { - if( level < 0 ) - return this.FixedFieldNames; - - var collection = this.FixedMergedNames; - if( collection.Count > 0 ) - return collection[ level ]; - - //If the list is empty, it means there is no column in the grid right now, so return an empty collection, as does the FixedFieldNames property. - return new ColumnNameCollection(); - } - - internal IColumnNameCollection GetScrollingFieldNames() - { - return this.GetScrollingFieldNames( -1 ); - } - - internal IColumnNameCollection GetScrollingFieldNames( int level ) - { - if( level < 0 ) - return this.ScrollingFieldNames; - - var collection = this.ScrollingMergedNames; - if( collection.Count > 0 ) - return collection[ level ]; - - //If the list is empty, it means there is no column in the grid right now, so return an empty collection, as does the ScrollingFieldNames property. - return new ColumnNameCollection(); - } - - internal IColumnNameCollection GetVisibleFieldNames() - { - return this.GetVisibleFieldNames( -1 ); - } - - internal IColumnNameCollection GetVisibleFieldNames( int level ) - { - if( level < 0 ) - return this.VisibleFieldNames; - - var collection = this.VisibleMergedFieldNames; - if( collection.Count > 0 ) - return collection[ level ]; - - //If the list is empty, it means there is no column in the grid right now, so return an empty collection, as does the VisibleFieldNames property. - return new ColumnNameCollection(); - } - - private string FindFirstVisibleFocusableColumnFieldName( LinkedListNode startNode, Func, LinkedListNode> getNextNodeHandler ) - { - if( getNextNodeHandler == null ) - throw new ArgumentNullException( "getNextNodeHandler" ); - - if( startNode == null ) - return null; - - ColumnBase currentColumn = startNode.Value; - - while( ( currentColumn != null ) - && ( ( currentColumn.ReadOnly ) - && ( !currentColumn.CanBeCurrentWhenReadOnly ) - || ( this.FixedFieldNames.Contains( currentColumn.FieldName ) ) - || ( !currentColumn.Visible ) ) ) - { - startNode = getNextNodeHandler.Invoke( startNode ); - currentColumn = ( startNode != null ) ? startNode.Value : null; - } - - return ( currentColumn != null ) ? currentColumn.FieldName : null; - } - - private string GetFirstVisibleFocusableColumnFieldName() - { - var dataGridContext = this.DataGridContext; - if( dataGridContext == null ) - return null; - - return this.FindFirstVisibleFocusableColumnFieldName( - dataGridContext.ColumnsByVisiblePosition.First, - ( node ) => node.Next ); - } - - private string GetLastVisibleFocusableColumnFieldName() - { - var dataGridContext = this.DataGridContext; - if( dataGridContext == null ) - return null; - - return this.FindFirstVisibleFocusableColumnFieldName( - dataGridContext.ColumnsByVisiblePosition.Last, - ( node ) => node.Previous ); - } - - private double GetHorizontalOffset() - { - var scrollViewer = this.ScrollViewer; - if( scrollViewer == null ) - return 0d; - - return scrollViewer.HorizontalOffset - this.FirstColumnCompensationOffset; - } - - private double GetViewportWidth() - { - // Viewport is only required when UI Virtualization is on. - if( this.VirtualizationMode == ColumnVirtualizationMode.None ) - return 0d; - - IScrollInfo scrollInfo = null; - - try - { - var dataGridContext = this.DataGridContext; - if( dataGridContext != null ) - { - scrollInfo = this.DataGridContext.DataGridControl.ItemsHost as IScrollInfo; - } - } - catch( Exception ) - { - // Ignore exceptions since it may be called before the ItemsHost Template is applied - } - - double width = ( scrollInfo != null ) ? scrollInfo.ViewportWidth : 0d; - - // We use the HeaderFooterItem width when greater than the viewport width. - return Math.Max( width, this.DataGridContext.FixedHeaderFooterViewPortSize.Width ); - } - - private IList GetVisibleColumns( int level ) - { - return this.DataGridContext.VisibleColumns; - } - - private ColumnCollection GetColumnCollectionForLevel( int level ) - { - var dataGridContext = this.DataGridContext; - if( dataGridContext == null ) - return null; - - if( level < 0 ) - return dataGridContext.Columns; - - return null; - } - - private IEnumerable GetChildLocations( ColumnHierarchyManager.ILocation location ) - { - if( location == null ) - yield break; - - location = location.GetFirstChild(); - - while( location != null ) - { - yield return location; - - location = location.GetNextSibling(); - } - } - - private IEnumerable GetColumnLocations( IEnumerable locations ) - { - if( locations == null ) - return Enumerable.Empty(); - - return ( from location in locations - let columnLocation = location as ColumnHierarchyManager.IColumnLocation - where ( columnLocation != null ) - select columnLocation ); - } - - private double GetVisibleChildColumnsWidth( ColumnHierarchyManager.ILocation parentLocation ) - { - var width = 0d; - - foreach( var columnLocation in this.GetColumnLocations( this.GetChildLocations( parentLocation ) ) ) - { - var column = columnLocation.Column; - if( column.Visible ) - { - width += column.ActualWidth; - } - } - - return width; - } - - #region IWeakEventListener Members - - protected override bool OnReceiveWeakEvent( Type managerType, object sender, EventArgs e ) - { - var handled = true; - var dataGridContext = this.DataGridContext; - - if( managerType == typeof( CollectionChangedEventManager ) ) - { - if( sender == dataGridContext.Items.SortDescriptions ) - { - this.OnSortDescriptionsChanged( ( NotifyCollectionChangedEventArgs )e ); - } - else if( sender == dataGridContext.Items.GroupDescriptions ) - { - this.OnGroupDescriptionsChanged( ( NotifyCollectionChangedEventArgs )e ); - } - } - else if( managerType == typeof( ColumnActualWidthEventManager ) ) - { - this.OnColumnActualWidthChanged( e as ColumnActualWidthChangedEventArgs ); - } - else if( managerType == typeof( DataGridControlTemplateChangedEventManager ) ) - { - this.OnDataGridControlTemplateChanged(); - } - else - { - handled = false; - } - - if( !base.OnReceiveWeakEvent( managerType, sender, e ) ) - return handled; - - return true; - } - - #endregion - - private readonly Dictionary m_columnsVisibilitySnapshot = new Dictionary(); - - internal sealed class ColumnNameCollection : IColumnNameCollection - { - public int Count - { - get - { - return m_list.Count; - } - } - - public string this[ int index ] - { - get - { - return m_list[ index ]; - } - } - - public void Clear() - { - m_list.Clear(); - m_list.TrimExcess(); - - m_lookup.Clear(); - m_lookup.TrimExcess(); - } - - public void Add( string fieldName ) - { - if( fieldName == null ) - return; - - if( m_lookup.Contains( fieldName ) ) - return; - - m_lookup.Add( fieldName ); - m_list.Add( fieldName ); - } - - public void Add( ColumnBase column ) - { - if( column == null ) - return; - - this.Add( column.FieldName ); - } - - public void Remove( string fieldName ) - { - if( fieldName == null ) - return; - - if( !m_lookup.Contains( fieldName ) ) - return; - - m_lookup.Remove( fieldName ); - m_list.Remove( fieldName ); - } - - public void Remove( ColumnBase column ) - { - if( column == null ) - return; - - this.Remove( column.FieldName ); - } - - public bool Contains( string fieldName ) - { - if( fieldName == null ) - return false; - - return m_lookup.Contains( fieldName ); - } - - public bool Contains( ColumnBase column ) - { - if( column == null ) - return false; - - return this.Contains( column.FieldName ); - } - - public IEnumerator GetEnumerator() - { - return m_list.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return this.GetEnumerator(); - } - - private readonly List m_list = new List(); - private readonly HashSet m_lookup = new HashSet(); - } - - internal sealed class ColumnInfoCollection : IColumnInfoCollection - { - public void Clear() - { - m_data.Clear(); - } - - public T this[ string fieldName ] - { - get - { - return m_data[ fieldName ]; - } - set - { - if( fieldName == null ) - return; - - m_data[ fieldName ] = value; - } - } - - public T this[ ColumnBase column ] - { - get - { - return this[ column.FieldName ]; - } - set - { - if( column == null ) - return; - - this[ column.FieldName ] = value; - } - } - - public void Reset( string fieldName ) - { - if( fieldName == null ) - return; - - m_data.Remove( fieldName ); - } - - public void Reset( ColumnBase column ) - { - if( column == null ) - return; - - this.Reset( column.FieldName ); - } - - public bool Contains( string fieldName ) - { - if( fieldName == null ) - return false; - - return m_data.ContainsKey( fieldName ); - } - - public bool Contains( ColumnBase column ) - { - if( column == null ) - return false; - - return this.Contains( column.FieldName ); - } - - public bool TryGetValue( string fieldName, out T value ) - { - if( fieldName != null ) - return m_data.TryGetValue( fieldName, out value ); - - value = default( T ); - return false; - } - - public bool TryGetValue( ColumnBase column, out T value ) - { - if( column != null ) - return this.TryGetValue( column.FieldName, out value ); - - value = default( T ); - return false; - } - - private readonly Dictionary m_data = new Dictionary(); - } - - private sealed class ColumnNameLookup : IColumnNameCollection - { - internal ColumnNameLookup( IEnumerable collection ) - { - m_collection = ( collection != null ) ? collection.ToList() : new List( 0 ); - } - - public int Count - { - get - { - return m_collection.Sum( item => item.Count ); - } - } - - public string this[ int index ] - { - get - { - foreach( var collection in m_collection ) - { - int count = collection.Count; - - if( index < count ) - return collection[ index ]; - - index -= count; - } - - throw new ArgumentOutOfRangeException( "index" ); - } - } - - public void Clear() - { - throw new NotSupportedException(); - } - - public void Add( string fieldName ) - { - throw new NotSupportedException(); - } - - public void Add( ColumnBase column ) - { - throw new NotSupportedException(); - } - - public void Remove( string fieldName ) - { - throw new NotSupportedException(); - } - - public void Remove( ColumnBase column ) - { - throw new NotSupportedException(); - } - - public bool Contains( string fieldName ) - { - if( fieldName == null ) - return false; - - return ( from list in m_collection - where list.Contains( fieldName ) - select true ).Any(); - } - - public bool Contains( ColumnBase column ) - { - if( column == null ) - return false; - - return this.Contains( column.FieldName ); - } - - public IEnumerator GetEnumerator() - { - if( m_collection.Count == 0 ) - return Enumerable.Empty().GetEnumerator(); - - IEnumerable result = m_collection[ 0 ]; - foreach( var more in m_collection.Skip( 1 ) ) - { - result = result.Concat( more ); - } - - return result.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return this.GetEnumerator(); - } - - private readonly List m_collection; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/UpdateMeasureRequiredEventArgs.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/UpdateMeasureRequiredEventArgs.cs deleted file mode 100644 index b61610da..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/UpdateMeasureRequiredEventArgs.cs +++ /dev/null @@ -1,58 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal class UpdateMeasureRequiredEventArgs : EventArgs - { - public UpdateMeasureRequiredEventArgs( UpdateMeasureTriggeredAction action ) - { - this.TriggeredAction = action; - } - - public UpdateMeasureRequiredEventArgs( UpdateMeasureTriggeredAction action, object parameters ) - : this( action ) - { - this.Parameters = parameters; - } - - public UpdateMeasureTriggeredAction TriggeredAction - { - get; - private set; - } - - public object Parameters - { - get; - private set; - } - } - - internal enum UpdateMeasureTriggeredAction - { - Unspecified, - ColumnActualWidthChanged, - ColumnReordering, // FixedColumns, Columns drag and drop - CurrentItemChanged, - GroupingChanged, - ScrollViewerChanged, - SortingChanged, - ViewPortWidthChanged // Parent viewport resized - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/UpdateMeasureRequiredEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/UpdateMeasureRequiredEventManager.cs deleted file mode 100644 index bc27eca2..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/UpdateMeasureRequiredEventManager.cs +++ /dev/null @@ -1,78 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal class UpdateMeasureRequiredEventManager : WeakEventManager - { - private UpdateMeasureRequiredEventManager() - { - } - - public static void AddListener( object source, IWeakEventListener listener ) - { - CurrentManager.ProtectedAddListener( source, listener ); - } - - public static void RemoveListener( object source, IWeakEventListener listener ) - { - CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - var columnVirtualizationManager = source as TableViewColumnVirtualizationManagerBase; - if( columnVirtualizationManager == null ) - throw new InvalidOperationException( "An attempt was made to use a source other than a ColumnVirtualizationManager." ); - - columnVirtualizationManager.UpdateMeasureRequired += this.OnUpdateMeasureRequired; - } - - protected override void StopListening( object source ) - { - var columnVirtualizationManager = source as TableViewColumnVirtualizationManagerBase; - if( columnVirtualizationManager == null ) - throw new InvalidOperationException( "An attempt was made to use a source other than a ColumnVirtualizationManager." ); - - columnVirtualizationManager.UpdateMeasureRequired -= this.OnUpdateMeasureRequired; - } - - private static UpdateMeasureRequiredEventManager CurrentManager - { - get - { - Type managerType = typeof( UpdateMeasureRequiredEventManager ); - UpdateMeasureRequiredEventManager currentManager = ( UpdateMeasureRequiredEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new UpdateMeasureRequiredEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - private void OnUpdateMeasureRequired( object sender, EventArgs args ) - { - this.DeliverEvent( sender, args ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/VirtualizingCellCollectionUpdateRequiredEventArgs.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/VirtualizingCellCollectionUpdateRequiredEventArgs.cs deleted file mode 100644 index fb8daa4f..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/VirtualizingCellCollectionUpdateRequiredEventArgs.cs +++ /dev/null @@ -1,63 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal sealed class VirtualizingCellCollectionUpdateRequiredEventArgs : EventArgs - { - internal VirtualizingCellCollectionUpdateRequiredEventArgs( VirtualizingCellCollectionUpdateTriggeredAction action ) - { - if( action == VirtualizingCellCollectionUpdateTriggeredAction.VisibleColumnsChanged ) - throw new ArgumentException( "The action must be anything but VirtualizingCellCollectionUpdateTriggeredAction.VisibleColumnsChanged.", "action" ); - - this.TriggeredAction = action; - } - - internal VirtualizingCellCollectionUpdateRequiredEventArgs( IList columns ) - { - if( columns == null ) - throw new ArgumentNullException( "columns" ); - - if( columns.Count <= 0 ) - throw new ArgumentException( "The column count must be greater than zero.", "columns" ); - - this.TriggeredAction = VirtualizingCellCollectionUpdateTriggeredAction.VisibleColumnsChanged; - this.Columns = columns; - } - - internal VirtualizingCellCollectionUpdateTriggeredAction TriggeredAction - { - get; - private set; - } - - internal IList Columns - { - get; - private set; - } - } - - internal enum VirtualizingCellCollectionUpdateTriggeredAction - { - VirtualizationModeChanged, //Virtualizing and recycling cells. - VisibleColumnsAdded, - VisibleColumnsChanged - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/VirtualizingCellCollectionUpdateRequiredEventManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/VirtualizingCellCollectionUpdateRequiredEventManager.cs deleted file mode 100644 index 7fdcf9e4..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/VirtualizingCellCollectionUpdateRequiredEventManager.cs +++ /dev/null @@ -1,78 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal class VirtualizingCellCollectionUpdateRequiredEventManager : WeakEventManager - { - private VirtualizingCellCollectionUpdateRequiredEventManager() - { - } - - public static void AddListener( object source, IWeakEventListener listener ) - { - CurrentManager.ProtectedAddListener( source, listener ); - } - - public static void RemoveListener( object source, IWeakEventListener listener ) - { - CurrentManager.ProtectedRemoveListener( source, listener ); - } - - protected override void StartListening( object source ) - { - var columnVirtualizationManager = source as TableViewColumnVirtualizationManagerBase; - if( columnVirtualizationManager == null ) - throw new InvalidOperationException( "An attempt was made to use a source other than a ColumnVirtualizationManager." ); - - columnVirtualizationManager.VirtualizingCellCollectionUpdateRequired += this.OnVirtualizingCellCollectionUpdateRequired; - } - - protected override void StopListening( object source ) - { - var columnVirtualizationManager = source as TableViewColumnVirtualizationManagerBase; - if( columnVirtualizationManager == null ) - throw new InvalidOperationException( "An attempt was made to use a source other than a ColumnVirtualizationManager." ); - - columnVirtualizationManager.VirtualizingCellCollectionUpdateRequired -= this.OnVirtualizingCellCollectionUpdateRequired; - } - - private static VirtualizingCellCollectionUpdateRequiredEventManager CurrentManager - { - get - { - Type managerType = typeof( VirtualizingCellCollectionUpdateRequiredEventManager ); - VirtualizingCellCollectionUpdateRequiredEventManager currentManager = ( VirtualizingCellCollectionUpdateRequiredEventManager )WeakEventManager.GetCurrentManager( managerType ); - - if( currentManager == null ) - { - currentManager = new VirtualizingCellCollectionUpdateRequiredEventManager(); - WeakEventManager.SetCurrentManager( managerType, currentManager ); - } - - return currentManager; - } - } - - private void OnVirtualizingCellCollectionUpdateRequired( object sender, EventArgs args ) - { - this.DeliverEvent( sender, args ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/VirtualizingFixedCellSubPanel.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/VirtualizingFixedCellSubPanel.cs deleted file mode 100644 index 2d310342..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/VirtualizingFixedCellSubPanel.cs +++ /dev/null @@ -1,205 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Windows; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal class VirtualizingFixedCellSubPanel : FixedCellSubPanel - { - public VirtualizingFixedCellSubPanel( FixedCellPanel parentPanel ) - : base( parentPanel ) - { - } - - // Measure horizontally. - protected override Size MeasureOverride( Size constraint ) - { - // This can be null when the parent Row is not prepared yet. - var columnVirtualizationManager = this.ColumnVirtualizationManager; - if( columnVirtualizationManager == null ) - return new Size(); - - var parentRow = this.ParentPanel.ParentRow; - if( parentRow == null ) - return new Size(); - - var desiredSize = new Size(); - var columnToVisibleWidth = columnVirtualizationManager.GetFieldNameToWidth( parentRow.LevelCache ); - - //This using prevents a WeakEvent to be raised to execute UpdateChildren() in FixedCellPanel, as it is already up to date at this point. - using( this.ParentPanel.ParentRowCells.SetIsUpdating() ) - { - foreach( var cell in this.GetCellsToLayout() ) - { - double width; - - if( columnToVisibleWidth.TryGetValue( cell.FieldName, out width ) ) - { - cell.Measure( new Size( width, constraint.Height ) ); - } - else - { - // The cell will be hidden. - cell.Measure( new Size() ); - } - - if( cell.DesiredSize.Height > desiredSize.Height ) - { - desiredSize.Height = cell.DesiredSize.Height; - } - } - } - - desiredSize.Width = columnVirtualizationManager.ScrollingColumnsWidth; - - return desiredSize; - } - - // Arrange horizontally. - protected override Size ArrangeOverride( Size arrangeSize ) - { - // This can be null when the parent Row is not prepared yet. - var columnVirtualizationManager = this.ColumnVirtualizationManager; - if( columnVirtualizationManager == null ) - return new Size(); - - var parentRow = this.ParentPanel.ParentRow; - if( parentRow == null ) - return new Size(); - - var dataGridContext = this.DataGridContext; - var scrollViewer = ( dataGridContext != null ) ? dataGridContext.DataGridControl.ScrollViewer : null; - - var columnToVisibleOffset = columnVirtualizationManager.GetFieldNameToOffset( parentRow.LevelCache ); - var horizontalOffset = ( scrollViewer != null ) ? scrollViewer.HorizontalOffset : 0d; - var fixedColumnsWidth = columnVirtualizationManager.FixedColumnsWidth; - var compensationOffset = columnVirtualizationManager.FirstColumnCompensationOffset; - var finalRect = new Rect( arrangeSize ); - - //This using prevents a WeakEvent to be raised to execute UpdateChildren() in FixedCellPanel, as it is already up to date at this point. - using( this.ParentPanel.ParentRowCells.SetIsUpdating() ) - { - foreach( var cell in this.GetCellsToLayout() ) - { - var offset = this.CalculateCellOffset( cell.ParentColumn, columnToVisibleOffset, horizontalOffset, fixedColumnsWidth, compensationOffset ); - - finalRect.X = offset.X; - finalRect.Width = cell.DesiredSize.Width; - finalRect.Height = Math.Max( arrangeSize.Height, cell.DesiredSize.Height ); - - cell.Arrange( finalRect ); - } - } - - return arrangeSize; - } - - protected override IEnumerable GetVisibleFieldsName() - { - var columnVirtualizationManager = this.ColumnVirtualizationManager; - if( columnVirtualizationManager == null ) - return new string[ 0 ]; - - return columnVirtualizationManager.GetScrollingFieldNames( this.ParentPanel.ParentRow.LevelCache ); - } - - internal override Point CalculateCellOffset( ColumnBase column ) - { - Debug.Assert( column != null ); - var row = this.ParentPanel.ParentRow; - - if( ( column != null ) && ( row != null ) ) - { - var dataGridContext = this.DataGridContext; - var columnVirtualizationManager = this.ColumnVirtualizationManager; - - if( ( dataGridContext != null ) && ( columnVirtualizationManager != null ) ) - { - var columnToVisibleOffset = columnVirtualizationManager.GetFieldNameToOffset( row.LevelCache ); - var scrollViewer = dataGridContext.DataGridControl.ScrollViewer; - var horizontalOffset = ( scrollViewer != null ) ? scrollViewer.HorizontalOffset : 0d; - var fixedColumnsWidth = columnVirtualizationManager.FixedColumnsWidth; - var compensationOffset = columnVirtualizationManager.FirstColumnCompensationOffset; - - return this.CalculateCellOffset( column, columnToVisibleOffset, horizontalOffset, fixedColumnsWidth, compensationOffset ); - } - } - - return new Point(); - } - - private Point CalculateCellOffset( ColumnBase column, IColumnInfoCollection columnsOffset, double horizontalOffset, double fixedColumnsWidth, double compensationOffset ) - { - if( column == null ) - return new Point(); - - Debug.Assert( columnsOffset != null ); - Debug.Assert( columnsOffset.Contains( column ) ); - - var columnOffset = columnsOffset[ column ]; - - // Calculate the offset of the cell's parent column: - // The original offset of the Column - // - the horizontal offset of the ScrollViewer to scroll to the right - // - the width of the fixed columns since we are in the Scrolling FixedCellSubPanel - // + the compensation offset used in master detail to avoid scrolling when not required - return new Point( columnOffset - horizontalOffset - fixedColumnsWidth + compensationOffset, 0d ); - } - - private IEnumerable GetCellsToLayout() - { - var visibleCells = this.GetVisibleCells(); - - // Check out if there are any out of view cells that needs to be layouted for different purpose. In case of a BringIntoView, the cell - // must be layouted in order to find out the target location. In case of a non recyclable cell, the cell must be arranged out of view. - var permanentScrollingFieldNames = this.ParentPanel.PermanentScrollingFieldNames; - if( !permanentScrollingFieldNames.Any() ) - return visibleCells; - - // Make sure we have access to the collection containing the additional cells to be layouted. - var parentRowCells = this.ParentPanel.ParentRowCells; - if( parentRowCells == null ) - return visibleCells; - - return this.GetCellsToLayout( visibleCells, permanentScrollingFieldNames, parentRowCells ); - } - - private IEnumerable GetCellsToLayout( IEnumerable visibleCells, IEnumerable permanentScrollingFieldNames, VirtualizingCellCollection cellsCollection ) - { - List unhandledCells = permanentScrollingFieldNames.ToList(); - - foreach( var cell in visibleCells ) - { - unhandledCells.Remove( cell.FieldName ); - - yield return cell; - } - - foreach( var fieldName in unhandledCells ) - { - var cell = cellsCollection.GetCell( fieldName, false ); - Debug.Assert( cell != null ); - - yield return cell; - } - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/VirtualizingUICellCollection.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/VirtualizingUICellCollection.cs deleted file mode 100644 index e40406d3..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(ColumnVirtualization)/VirtualizingUICellCollection.cs +++ /dev/null @@ -1,316 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; -using System.Windows; -using System.Windows.Controls; - -namespace Xceed.Wpf.DataGrid.Views -{ - // This class manages the various panel of a FixedCellPanel and the Logical/Visual - // Parent of the elements added to it. More precisely : - // - The logical parent of all the elements added to this collection will be the - // FixedCellPanel. - // - An element added or inserted will be either added to the "fixed" sub panel or the - // "scrolling" sub panel, according to its index. Thus, the element's Visual Parent - // will either be the fixed or the scrolling sub panel. - // - When removing or inserting elements, some other elements may see their parent - // change. From the fixed sub panel to the scrolling sub panel or vice versa. - // - As long as the elements are added to FixedCellSubPanel objects (like our - // m_fixedPanel and m_scrollingPanel), this Visual vs Logical parent management will - // work. - // - The collapsed elements are not considered when counting the number of fixed - // elements, even though they can be found in the m_fixedPanel. This also means that - // for a FixedCellCount of 0, there can still be some (collapsed) element in m_fixedPanel. - // - The scrolling panel only contains the elements presently in ViewPort - internal class VirtualizingUICellCollection : UIElementCollection - { - // The visualParent is passed to the base constructor because it is mandatory, but - // the element's visual parent will always be either the fixed or the scrolling sub - // panel. This is one of the reason why we don't use the base implementation of this - // class functions. - public VirtualizingUICellCollection( Panel fixedPanel, Panel scrollingPanel, FixedCellPanel parentFixedCellPanel ) - : base( parentFixedCellPanel, parentFixedCellPanel ) - { - if( fixedPanel == null ) - throw new ArgumentNullException( "fixedPanel" ); - - if( scrollingPanel == null ) - throw new ArgumentNullException( "scrollingPanel" ); - - if( parentFixedCellPanel == null ) - throw new ArgumentNullException( "parentFixedCellPanel" ); - - m_fixedPanel = fixedPanel; - m_scrollingPanel = scrollingPanel; - m_parentVirtualizingCellsHost = parentFixedCellPanel as IVirtualizingCellsHost; - } - - public override int Capacity - { - get - { - return 0; - } - set - { - Debug.Fail( "Check to see if the caller does something meaningful with this. We don't want to implement this property." ); - } - } - - public override void Clear() - { - //Empty both sub panels - m_fixedPanel.Children.Clear(); - m_scrollingPanel.Children.Clear(); - } - - public override bool Contains( UIElement element ) - { - //check for presence in both sub panels - return m_fixedPanel.Children.Contains( element ) || m_scrollingPanel.Children.Contains( element ); - } - - public override void CopyTo( Array array, int index ) - { - throw new NotSupportedException(); - } - - public override void CopyTo( UIElement[] array, int index ) - { - throw new NotSupportedException(); - } - - public override int Count - { - get - { - return m_fixedPanel.Children.Count + m_scrollingPanel.Children.Count; - } - } - - public override IEnumerator GetEnumerator() - { - return new CombinedEnumerator( this ); - } - - public override int IndexOf( UIElement element ) - { - //get the index of the element in the fixed sub panel first. - int fixedIndex = m_fixedPanel.Children.IndexOf( element ); - - //if found, return this index as it is valid - if( fixedIndex != -1 ) - return fixedIndex; - - //then determine the index of the element in the scrolling sub panel. - int scrollingIndex = m_scrollingPanel.Children.IndexOf( element ); - - //if item not found in the second sub panel, return -1 right away. - if( scrollingIndex == -1 ) - return -1; - - int fixedCount = m_fixedPanel.Children.Count; - - //finally, item was found in second sub panel, return a combined value - return fixedCount + scrollingIndex; - } - - public override bool IsSynchronized - { - get - { - return m_scrollingPanel.Children.IsSynchronized; - } - } - - public override object SyncRoot - { - get - { - return m_scrollingPanel.Children.SyncRoot; - } - } - - public override int Add( UIElement element ) - { - throw new NotSupportedException( "VirtualizingUICellCollection.Add" ); - } - - public override void Insert( int index, UIElement element ) - { - throw new NotSupportedException( "VirtualizingUICellCollection.Insert" ); - } - - public override void Remove( UIElement element ) - { - throw new NotSupportedException( "VirtualizingUICellCollection.Remove" ); - } - - public override void RemoveAt( int index ) - { - throw new NotSupportedException( "VirtualizingUICellCollection.RemoveAt" ); - } - - public override void RemoveRange( int index, int count ) - { - throw new NotSupportedException( "VirtualizingUICellCollection.RemoveRange" ); - } - - public override UIElement this[ int index ] - { - get - { - //check if the index is out of the valid range - if( ( index < 0 ) || ( index >= this.Count ) ) - throw new ArgumentOutOfRangeException( "index" ); - - int fixedCount = m_fixedPanel.Children.Count; - - if( index < fixedCount ) - { - return m_fixedPanel.Children[ index ]; - } - - return m_scrollingPanel.Children[ index - fixedCount ]; - } - set - { - throw new NotSupportedException( "The VirtualizingUICellCollection does not support direct modification of its children." ); - } - } - - public void ClearCellLogicalParent( UIElement targetElement ) - { - if( ( m_parentVirtualizingCellsHost != null ) && ( m_parentVirtualizingCellsHost.CanModifyLogicalParent == false ) ) - { - this.ClearLogicalParent( targetElement ); - } - } - - public void SetCellLogicalParent( UIElement targetElement ) - { - if( ( m_parentVirtualizingCellsHost != null ) && ( m_parentVirtualizingCellsHost.CanModifyLogicalParent == false ) ) - { - this.SetLogicalParent( targetElement ); - } - } - - private void IncrementVersion() - { - unchecked - { - m_version++; - } - } - - private Panel m_fixedPanel; - private Panel m_scrollingPanel; - private IVirtualizingCellsHost m_parentVirtualizingCellsHost; - private int m_version; - - private class CombinedEnumerator : IEnumerator - { - public CombinedEnumerator( VirtualizingUICellCollection cellCollection ) - { - if( cellCollection == null ) - throw new ArgumentNullException( "cellCollection" ); - - m_cellCollection = cellCollection; - } - - #region IEnumerator Members - - public object Current - { - get - { - //Enumerator not started. - if( m_fixedEnumerator == null ) - throw new InvalidOperationException(); - - //If enumerating through fixed panel - if( m_fixed == true ) - return m_fixedEnumerator.Current; - - //otherwise, use the scrolling enumerator - return m_scrollingEnumerator.Current; - } - } - - public bool MoveNext() - { - //If the Enumerator is not started, - if( m_fixedEnumerator == null ) - { - m_fixedEnumerator = m_cellCollection.m_fixedPanel.Children.GetEnumerator(); - m_scrollingEnumerator = m_cellCollection.m_scrollingPanel.Children.GetEnumerator(); - - //problems creating one of the enumerator - if( ( m_fixedEnumerator == null ) || ( m_scrollingEnumerator == null ) ) - { - m_fixedEnumerator = null; - m_scrollingEnumerator = null; - - //could not move to first item. - return false; - } - - //flag to the CombinedEnumerator to use the Fixed enumerator. - m_fixed = true; - } - - //If Fixed enumerator is in use - if( m_fixed == true ) - { - //try to move the Fixed enumerator - bool fixedRetval = m_fixedEnumerator.MoveNext(); - if( fixedRetval == true ) - { - //success, return true - return true; - } - else - { - //failure, reached the end of enumerator empty - m_fixed = false; - - //continue with execution so that scrolling enumerator gets started - } - } - - //If it returns false, then scrolling panel is empty, or we reaced the end. - return m_scrollingEnumerator.MoveNext(); - } - - public void Reset() - { - m_fixedEnumerator = null; - m_scrollingEnumerator = null; - } - - #endregion - - private VirtualizingUICellCollection m_cellCollection; - private bool m_fixed; - private IEnumerator m_fixedEnumerator; - private IEnumerator m_scrollingEnumerator; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(Enums)/ColumnStretchModeEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(Enums)/ColumnStretchModeEnum.cs deleted file mode 100644 index c09c12f1..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(Enums)/ColumnStretchModeEnum.cs +++ /dev/null @@ -1,28 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid.Views -{ - public enum ColumnStretchMode - { - None, - First, - Last, - All - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(Enums)/ColumnVirtualizationModeEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(Enums)/ColumnVirtualizationModeEnum.cs deleted file mode 100644 index b57795de..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(Enums)/ColumnVirtualizationModeEnum.cs +++ /dev/null @@ -1,25 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -namespace Xceed.Wpf.DataGrid.Views -{ - public enum ColumnVirtualizationMode - { - None, - Recycling, - Virtualizing - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(Enums)/DropMarkOrientationEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(Enums)/DropMarkOrientationEnum.cs deleted file mode 100644 index 945af0ee..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(Enums)/DropMarkOrientationEnum.cs +++ /dev/null @@ -1,29 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Xceed.Wpf.DataGrid.Views -{ - public enum DropMarkOrientation - { - Default, - Vertical, - Horizontal - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(Enums)/FlattenDetailBindingModeEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(Enums)/FlattenDetailBindingModeEnum.cs deleted file mode 100644 index 4aa68000..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(Enums)/FlattenDetailBindingModeEnum.cs +++ /dev/null @@ -1,27 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal enum FlattenDetailBindingMode - { - Default, - None, - MasterOneWay, - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(Enums)/MasterDetailLayoutModeEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(Enums)/MasterDetailLayoutModeEnum.cs deleted file mode 100644 index 1bdd1701..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(Enums)/MasterDetailLayoutModeEnum.cs +++ /dev/null @@ -1,26 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal enum MasterDetailLayoutMode - { - Default, - Flatten, - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(Enums)/PassiveLayoutAxisEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(Enums)/PassiveLayoutAxisEnum.cs deleted file mode 100644 index 830ead10..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(Enums)/PassiveLayoutAxisEnum.cs +++ /dev/null @@ -1,27 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid.Views -{ - public enum PassiveLayoutAxis - { - Vertical, - Horizontal, - Both - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(Enums)/SynchronizedScrollViewerPositionEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(Enums)/SynchronizedScrollViewerPositionEnum.cs deleted file mode 100644 index dd4f82f7..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(Enums)/SynchronizedScrollViewerPositionEnum.cs +++ /dev/null @@ -1,29 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid.Views -{ - public enum SynchronizedScrollViewerPosition - { - Top, - Bottom, - Left, - Right, - None, - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(Enums)/ViewPropertyModeEnum.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(Enums)/ViewPropertyModeEnum.cs deleted file mode 100644 index dcc59272..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(Enums)/ViewPropertyModeEnum.cs +++ /dev/null @@ -1,30 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Xceed.Wpf.DataGrid.Views -{ - public enum ViewPropertyMode - { - None, - ViewOnly, - Routed, - RoutedNoFallback, - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/AnimatedDraggedElementAdorner.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/AnimatedDraggedElementAdorner.cs deleted file mode 100644 index 054c3a40..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/AnimatedDraggedElementAdorner.cs +++ /dev/null @@ -1,151 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Xceed.Utils.Wpf.DragDrop; -using System.Windows.Media; -using System.Windows.Shapes; -using System.Windows; -using System.Windows.Documents; -using System.Windows.Media.Imaging; -using System.Diagnostics; -using System.Windows.Controls; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal class AnimatedDraggedElementAdorner : DraggedElementAdorner - { - #region Constructors - - public AnimatedDraggedElementAdorner( UIElement adornedElement, AdornerLayer adornerLayer ) - : this( adornedElement, adornerLayer, false ) - { - } - - public AnimatedDraggedElementAdorner( UIElement adornedElement, AdornerLayer adornerLayer, bool deepCopy ) - : base( adornedElement, adornerLayer ) - { - this.DeepCopy = deepCopy; - this.IsHitTestVisible = false; - } - - #endregion - - #region DeepCopy Property - - public bool DeepCopy - { - get; - private set; - } - - #endregion - - #region Protected Methods - - protected override Rectangle InitializeAdornedElementImage() - { - Rect adornedBounds = VisualTreeHelper.GetDescendantBounds( this.AdornedElement ); - - // Round the height and width of the bounds to reduce the - // blur effect caused by the RenderTargetBitmap. - // When drawing Text into RenderTargetBitmap, the ClearType - // reverts to grayscale causing a blur effect. If there is - // also an extrapolation, the blur effect will be worst. - int roundedHeight = ( int )Math.Round( adornedBounds.Height, MidpointRounding.ToEven ); - int roundedWidth = ( int )Math.Round( adornedBounds.Width, MidpointRounding.ToEven ); - - VisualBrush brush = new VisualBrush( this.AdornedElement ); - - Rectangle rectangle = new Rectangle(); - - // Only if we have something to adorn - if( this.DeepCopy - && ( ( roundedWidth > 0 ) && ( roundedHeight > 0 ) ) ) - { - try - { - RenderTargetBitmap bitmap = new RenderTargetBitmap( roundedWidth, - roundedHeight, - 96, - 96, - PixelFormats.Pbgra32 ); - - DrawingVisual drawingVisual = new DrawingVisual(); - - using( DrawingContext context = drawingVisual.RenderOpen() ) - { - Rect finalRect = new Rect( 0, - 0, - roundedWidth, - roundedHeight ); - - context.DrawRectangle( brush, null, finalRect ); - } - - bitmap.Render( drawingVisual ); - - // Ensure to set the Height and Width - // values for the Fill does not resize the - // rectangle if it is larger. This also - // reduce the blur effect. - rectangle.Height = roundedHeight; - rectangle.Width = roundedWidth; - rectangle.UpdateLayout(); - - // Adding BitmapScallingMode using any other BitmapScalingMode cause some - // blur in the resulting Bitmap - RenderOptions.SetBitmapScalingMode( rectangle, BitmapScalingMode.NearestNeighbor ); - rectangle.Fill = new ImageBrush( bitmap ); - - // Translate the Top Left corner of the rectangle that - // contains the AdornedElement - if( !adornedBounds.Size.IsEmpty ) - { - rectangle.RenderTransform = new TranslateTransform( adornedBounds.X, adornedBounds.Y ); - } - } - catch( Exception ) - { - // Avoid any exception and use the brush itself - rectangle.Fill = brush; - } - } - else - { - rectangle.Fill = brush; - } - - return rectangle; - } - - protected override Size MeasureOverride( Size constraint ) - { - this.AdornedElement.Measure( constraint ); - - // Ensure to return the DescendantBounds to take Margins and Padding - // into consideration - Rect bounds = VisualTreeHelper.GetDescendantBounds( this.AdornedElement ); - - return bounds.Size; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/ColumnReorderingDragSourceManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/ColumnReorderingDragSourceManager.cs deleted file mode 100644 index 476dac4c..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/ColumnReorderingDragSourceManager.cs +++ /dev/null @@ -1,2664 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Windows; -using System.Windows.Documents; -using System.Windows.Media; -using System.Windows.Media.Animation; -using Xceed.Utils.Wpf.DragDrop; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal sealed class ColumnReorderingDragSourceManager : DragSourceManager - { - #region Private Fields - - private static readonly Duration s_columnAnimationDuration = new Duration( TimeSpan.FromMilliseconds( 500d ) ); - private static readonly Duration s_draggedElementFadeInDuration = new Duration( TimeSpan.FromMilliseconds( 250d ) ); - private static readonly Duration s_returnToOriginalPositionDuration = new Duration( TimeSpan.FromMilliseconds( 250d ) ); - - private static readonly Point s_origin = new Point(); - - #endregion - - internal ColumnReorderingDragSourceManager( UIElement draggedElement, AdornerLayer adornerLayer, UIElement container, int level ) - : base( draggedElement, adornerLayer, container ) - { - m_level = level; - m_dataGridContext = DataGridControl.GetDataGridContext( draggedElement ); - - Debug.Assert( m_dataGridContext != null ); - - m_splitterTranslation = TableflowView.GetFixedColumnSplitterTranslation( m_dataGridContext ); - m_columnVirtualizationManager = m_dataGridContext.ColumnVirtualizationManager as TableViewColumnVirtualizationManagerBase; - m_reorderCancelled = false; - } - - #region IsAnimatedColumnReorderingEnabled Internal Property - - internal bool IsAnimatedColumnReorderingEnabled - { - get - { - return m_isAnimatedColumnReorderingEnabled; - } - private set - { - if( value == m_isAnimatedColumnReorderingEnabled ) - return; - - m_isAnimatedColumnReorderingEnabled = value; - - this.OnPropertyChanged( "IsAnimatedColumnReorderingEnabled" ); - } - } - - private bool m_isAnimatedColumnReorderingEnabled; - - #endregion - - #region AnimatedColumnReorderingTranslation Attached Property - - // This translation will be used by the AnimatedColumnReorderingManager to apply a TranslateTransform - // to Columns that require it in order to give a preview of the reordering in an animated or live way - internal static readonly DependencyProperty AnimatedColumnReorderingTranslationProperty = DependencyProperty.RegisterAttached( - "AnimatedColumnReorderingTranslation", - typeof( TransformGroup ), - typeof( ColumnReorderingDragSourceManager ), - new FrameworkPropertyMetadata( null ) ); - - internal static TransformGroup GetAnimatedColumnReorderingTranslation( DependencyObject obj ) - { - return ( TransformGroup )obj.GetValue( ColumnReorderingDragSourceManager.AnimatedColumnReorderingTranslationProperty ); - } - - private static void SetAnimatedColumnReorderingTranslation( DependencyObject obj, TransformGroup value ) - { - obj.SetValue( ColumnReorderingDragSourceManager.AnimatedColumnReorderingTranslationProperty, value ); - } - - private static void ClearAnimatedColumnReorderingTranslation( DependencyObject obj ) - { - var group = ColumnReorderingDragSourceManager.GetAnimatedColumnReorderingTranslation( obj ); - if( group != null ) - { - ColumnReorderingDragSourceManager.ClearTranslateTransformAnimation( ColumnReorderingDragSourceManager.GetColumnPositionTransform( group ) ); - ColumnReorderingDragSourceManager.ClearScaleTransformAnimation( ColumnReorderingDragSourceManager.GetColumnSizeTransform( group ) ); - } - - obj.ClearValue( ColumnReorderingDragSourceManager.AnimatedColumnReorderingTranslationProperty ); - } - - private static TransformGroup CreateColumnTransformGroup() - { - var group = new TransformGroup(); - group.Children.Add( new TranslateTransform() ); - group.Children.Add( new ScaleTransform() ); - - return group; - } - - private static TransformGroup GetColumnTransformGroup( ColumnBase column ) - { - if( column == null ) - return null; - - var group = ColumnReorderingDragSourceManager.GetAnimatedColumnReorderingTranslation( column ); - if( group == null ) - { - group = ColumnReorderingDragSourceManager.CreateColumnTransformGroup(); - ColumnReorderingDragSourceManager.SetAnimatedColumnReorderingTranslation( column, group ); - } - - Debug.Assert( group != null ); - - return group; - } - - private static TranslateTransform GetColumnPositionTransform( TransformGroup group ) - { - if( ( group == null ) || ( group.Children.Count <= 0 ) ) - return null; - - return group.Children[ 0 ] as TranslateTransform; - } - - private static ScaleTransform GetColumnSizeTransform( TransformGroup group ) - { - if( ( group == null ) || ( group.Children.Count <= 1 ) ) - return null; - - return group.Children[ 1 ] as ScaleTransform; - } - - #endregion - - protected override void OnDragStart( Func getPosition ) - { - if( m_isDragStarted ) - throw new InvalidOperationException(); - - m_isDragStarted = true; - - this.StopAnimationsAndRollback(); - this.UpdateIsAnimatedColumnReorderingEnabled(); - - base.OnDragStart( getPosition ); - - var draggedElement = this.DraggedElement; - - //When the grid is hosted in a popup window, it is not possible to know the position of the popup in certain scenarios (e.g. fullscreen, popup openning upward). - //Thus we must use a regular system adorner instead of the ghost window, so that the dragged adorner will appear correctly under the mouse pointer. - if( this.IsPopup ) - { - this.SetPopupDragAdorner( draggedElement as ColumnManagerCell ); - } - - if( !this.IsAnimatedColumnReorderingEnabled ) - { - this.AutoScrollInterval = TimeSpan.FromMilliseconds( 50d ); - return; - } - - this.AutoScrollInterval = TimeSpan.Zero; - - // Get initial mouse positions - m_lastDraggedElementOffset = draggedElement.TranslatePoint( getPosition.Invoke( draggedElement ), this.Container ).X; - - var draggedCell = draggedElement as ColumnManagerCell; - if( draggedCell != null ) - { - var draggedColumn = draggedCell.ParentColumn; - Debug.Assert( draggedColumn != null ); - - this.TakeColumnsLayoutSnapshot(); - - // Affect the column's IsBeingDraggedAnimated to ensure every prepared container calls AddDraggedColumnGhost of this manager. - draggedColumn.SetColumnReorderingDragSourceManager( this ); - draggedColumn.SetIsBeingDraggedAnimated( true ); - } - - TableflowView.SetAreColumnsBeingReordered( m_dataGridContext, true ); - TableflowView.SetColumnReorderingDragSourceManager( m_dataGridContext, this ); - - this.HideDraggedElements(); - } - - protected override void OnDragEnd( Func getPosition, bool drop ) - { - if( !m_isDragStarted ) - throw new InvalidOperationException(); - - m_isDragStarted = false; - - base.OnDragEnd( getPosition, drop ); - - //If in a popup, we are using a system adorner, and we need to hide it when releasing the mouse button. - if( this.IsPopup ) - { - m_popupDraggedElementAdorner.AdornedElementImage.Opacity = 0d; - m_popupDraggedElementAdorner.SetOffset( s_origin ); - } - - m_columnsLayout.Clear(); - - if( !this.IsAnimatedColumnReorderingEnabled ) - return; - - this.MoveGhostToTargetAndDetach(); - this.ClearColumnAnimations(); - this.ClearSplitterAnimation(); - } - - protected override void OnDragMove( Func getPosition ) - { - if( this.IsAnimatedColumnReorderingEnabled ) - { - this.UpdateMouseMoveDirection( getPosition ); - } - - base.OnDragMove( getPosition ); - } - - protected override void OnDragOver( IDropTarget target, Func getPosition ) - { - base.OnDragOver( target, getPosition ); - - if( !this.IsAnimatedColumnReorderingEnabled ) - return; - - // We are reverting every animation before detaching from the manager - // so do not update the ghost position - if( m_ghostToTargetAndDetachAnimationClock != null ) - return; - - var draggedCell = this.DraggedElement as ColumnManagerCell; - if( draggedCell == null ) - return; - - var dropTarget = this.CurrentDropTarget as ColumnManagerCell; - if( ( dropTarget == null ) || ( dropTarget == draggedCell ) ) - return; - - var draggedOverDataGridContext = DataGridControl.GetDataGridContext( dropTarget ); - if( ( draggedOverDataGridContext == null ) || ( m_dataGridContext != draggedOverDataGridContext ) || !this.CanReorder( draggedCell, dropTarget, this.CurrentDropTargetToContainerPosition ) ) - return; - - this.UpdateColumnsLayout(); - this.ApplyColumnsLayoutAnimations(); - this.ApplySplitterAnimation(); - } - - protected override DropTargetInfo GetDropTarget( Func getPosition ) - { - if( !this.IsAnimatedColumnReorderingEnabled ) - return base.GetDropTarget( getPosition ); - - var cell = this.DraggedElement as ColumnManagerCell; - if( cell == null ) - return base.GetDropTarget( getPosition ); - - var parentRow = cell.ParentRow as ColumnManagerRow; - if( parentRow == null ) - return base.GetDropTarget( getPosition ); - - foreach( var dropTargetInfo in DragDropHelper.GetDropTargetAtPoint( this.DraggedElement, this.Container, getPosition ) ) - { - var target = dropTargetInfo.Target; - if( !( target is ColumnManagerCell ) && !( target is ColumnManagerRow ) ) - return dropTargetInfo; - } - - var dragContainer = this.Container; - var dragContainerRect = new Rect( new Point(), dragContainer.RenderSize ); - - var draggedElementToMouse = getPosition.Invoke( cell ); - var draggedElementTopLeftToMouse = new Point( draggedElementToMouse.X - this.InitialMousePositionToDraggedElement.Value.X, draggedElementToMouse.Y - this.InitialMousePositionToDraggedElement.Value.Y ); - var draggedElementBottomRightToMouse = new Point( draggedElementTopLeftToMouse.X + cell.ActualWidth, draggedElementTopLeftToMouse.Y + cell.ActualHeight ); - - var draggedElementRectInDragContainer = new Rect( cell.TranslatePoint( draggedElementTopLeftToMouse, dragContainer ), - cell.TranslatePoint( draggedElementBottomRightToMouse, dragContainer ) ); - draggedElementRectInDragContainer.Intersect( dragContainerRect ); - - // We are not interested by the y-axis. We set the y-axis value to 0 so the rectangle use to look for overlap on the x-axis - // will work no matter where is located the dragged element on the y-axis. - var cellRectInDragContainer = new Rect( cell.TranslatePoint( new Point( draggedElementTopLeftToMouse.X, 0d ), dragContainer ), - cell.TranslatePoint( new Point( draggedElementBottomRightToMouse.X, cell.ActualHeight ), dragContainer ) ); - var rowRectInDragContainer = parentRow.TransformToVisual( dragContainer ).TransformBounds( VisualTreeHelper.GetDescendantBounds( parentRow ) ); - - var dropTargetRectInDragContainer = rowRectInDragContainer; - dropTargetRectInDragContainer.Intersect( cellRectInDragContainer ); - - var result = default( DropTargetInfo ); - - // Some part of the dragged element overlaps the container. - if( !draggedElementRectInDragContainer.IsEmpty && !dropTargetRectInDragContainer.IsEmpty ) - { - var hitTestPosition = new Point(); - var dropPosition = new Point(); - - // We are not interested by the y-axis, but we will set a value that will return a positive result for hit testing. - hitTestPosition.Y = cellRectInDragContainer.Top + ( cellRectInDragContainer.Height / 2d ); - dropPosition.Y = hitTestPosition.Y; - - switch( m_horizontalMouseDragDirection ) - { - // Use the dragged element left edge to minimize the size of the blank area during animations. - case HorizontalMouseDragDirection.Left: - { - hitTestPosition.X = dropTargetRectInDragContainer.Left; - dropPosition.X = cellRectInDragContainer.Left; - } - break; - - // Use the dragged element right edge to minimize the size of the blank area during animations. - case HorizontalMouseDragDirection.Right: - { - hitTestPosition.X = dropTargetRectInDragContainer.Right; - dropPosition.X = cellRectInDragContainer.Right; - } - break; - - default: - { - var dragContainerToMouse = getPosition.Invoke( dragContainer ); - - if( dragContainerToMouse.X <= dropTargetRectInDragContainer.Left ) - { - hitTestPosition.X = dropTargetRectInDragContainer.Left; - dropPosition.X = cellRectInDragContainer.Left; - } - else if( dragContainerToMouse.X >= dropTargetRectInDragContainer.Right ) - { - hitTestPosition.X = dropTargetRectInDragContainer.Right; - dropPosition.X = cellRectInDragContainer.Right; - } - else - { - hitTestPosition.X = dragContainerToMouse.X; - dropPosition.X = dragContainerToMouse.X; - } - } - break; - } - - // Ensure the DraggedElement is not visible to hit test. - cell.IsHitTestVisible = false; - - try - { - result = this.GetDropTargetAtPoint( cell, new RelativePoint( dragContainer, dropPosition ) ); - } - finally - { - cell.ClearValue( UIElement.IsHitTestVisibleProperty ); - } - } - - if( !( result.Target is ColumnManagerRow ) && !( result.Target is ColumnManagerCell ) ) - { - result = default( DropTargetInfo ); - } - - // Flag used to reduce the number of column animations, to speed up the scrolling on ColumnManagerCell dragging. - if( ( result.Target == null ) && ( this.CurrentDropTarget == null ) ) - { - m_noColumnsReorderingNeeded = true; - if( this.IsPopup ) - { - m_popupDraggedElementAdorner.AdornedElementImage.Opacity = 0d; - } - } - else - { - m_noColumnsReorderingNeeded = false; - } - - return result; - } - - protected override void UpdateGhost( Func getPosition ) - { - //If in TableView and the grid is hosted in a Popup window. - if( !this.IsAnimatedColumnReorderingEnabled && this.IsPopup ) - { - this.ShowGhost = false; - - var draggedElementToMouse = getPosition.Invoke( this.DraggedElement ); - var initialMousePosition = this.InitialMousePositionToDraggedElement.GetValueOrDefault(); - - // Correct it according to initial mouse position over the dragged element - draggedElementToMouse.X -= initialMousePosition.X; - draggedElementToMouse.Y -= initialMousePosition.Y; - - this.ApplyContainerClip( m_popupDraggedElementAdorner ); - m_popupDraggedElementAdorner.AdornedElementImage.Opacity = 1d; - m_popupDraggedElementAdorner.SetOffset( draggedElementToMouse ); - } - //If no animation, or if the dragged object is beyond the edge of the grid, no need to do anything in this override, simply call base. - //This will be sufficient to update the DraggedElementGhost positon. The result is a much faster scrolling of the grid via the CheckForAutoScroll() method. - else if( this.IsAnimatedColumnReorderingEnabled && !m_noColumnsReorderingNeeded ) - { - // We are reverting every animation before detaching from the manager - // so do not update the ghost position - if( m_ghostToTargetAndDetachAnimationClock != null ) - return; - - var dragOverRowOrCell = ( this.CurrentDropTarget is ColumnManagerRow ) || ( this.CurrentDropTarget is ColumnManagerCell ); - - // We are dragging over an object that will handle the drop itself - if( !dragOverRowOrCell && !this.IsPopup ) - { - // Ensure to pause every other animations before - this.PauseGhostToMousePositionAnimation(); - this.PauseDraggedElementFadeInAnimation(); - - this.RollbackReordering(); - this.ShowGhost = true; - - this.MoveGhostToTargetColumn( getPosition.Invoke( this.DraggedElement ) ); - } - //If dragging over an object that will handle the drop itself and the grid is hosted in a Popup window. - else if( !dragOverRowOrCell && this.IsPopup ) - { - // Ensure to pause every other animations before - this.PauseGhostToMousePositionAnimation(); - this.PauseDraggedElementFadeInAnimation(); - - this.RollbackReordering(); - this.ShowGhost = false; - - var draggedElementToMouse = getPosition.Invoke( this.DraggedElement ); - - this.MoveGhostToTargetColumn( draggedElementToMouse ); - - var initialMousePosition = this.InitialMousePositionToDraggedElement.GetValueOrDefault(); - - // Correct it according to initial mouse position over the dragged element - draggedElementToMouse.X -= initialMousePosition.X; - draggedElementToMouse.Y -= initialMousePosition.Y; - - this.ApplyContainerClip( m_popupDraggedElementAdorner ); - m_popupDraggedElementAdorner.AdornedElementImage.Opacity = 1d; - m_popupDraggedElementAdorner.SetOffset( draggedElementToMouse ); - } - //If animations are required. - else - { - //If in a popup, hide the dragged element adorner. - if( this.IsPopup ) - { - m_popupDraggedElementAdorner.AdornedElementImage.Opacity = 0d; - m_popupDraggedElementAdorner.SetOffset( s_origin ); - } - - // Pause animations that are moving ghosts to target Column - this.PauseMoveGhostToTargetColumnAnimation(); - this.PauseDraggedElementFadeInAnimation(); - - this.ShowGhost = false; - this.ShowDraggedColumnGhosts(); - this.HideDraggedElements(); - - var draggedElementToMouse = getPosition.Invoke( this.DraggedElement ); - var initialMousePosition = this.InitialMousePositionToDraggedElement.GetValueOrDefault(); - - // Correct it according to initial mouse position over the dragged element - draggedElementToMouse.X -= initialMousePosition.X; - draggedElementToMouse.Y -= initialMousePosition.Y; - - // Wait for the animation to complete before explicitly setting the X and Y offsets on the ghost adorners OR if reordering was canceled - if( ( m_ghostToMousePositionAnimationClock == null ) && ( m_ghostToTargetColumnAnimationClock == null ) && !m_reorderCancelled ) - { - // Update the position of ghosts for each rows - foreach( var adorner in this.GetElementAdorners() ) - { - adorner.ApplyAnimationClock( DraggedElementAdorner.OffsetProperty, null ); - adorner.SetOffset( draggedElementToMouse ); - } - } - else - { - this.MoveGhostToMousePosition( draggedElementToMouse ); - } - } - } - - base.UpdateGhost( getPosition ); - } - - protected override void OnDroppedOutside() - { - base.OnDroppedOutside(); - - if( !this.IsAnimatedColumnReorderingEnabled ) - return; - - this.RollbackReordering(); - } - - internal void AddDraggedColumnGhost( UIElement element ) - { - if( ( element == null ) || m_elementToDraggedElementAdorner.ContainsKey( element ) ) - return; - - // Get the Rect for the DataGridControl - var dataGridControl = m_dataGridContext.DataGridControl; - var dataGridControlRect = new Rect( 0d, 0d, dataGridControl.ActualWidth, dataGridControl.ActualHeight ); - var elementToDataGridControl = element.TranslatePoint( s_origin, dataGridControl ); - var elementRect = new Rect( elementToDataGridControl, element.RenderSize ); - - // This is a special case with the current element that is always layouted, but can be out of view - if( !elementRect.IntersectsWith( dataGridControlRect ) ) - return; - - var adorner = new AnimatedDraggedElementAdorner( element, this.AdornerLayer, true ); - - this.ApplyContainerClip( adorner ); - this.AdornerLayer.Add( adorner ); - - m_elementToDraggedElementAdorner.Add( element, adorner ); - } - - internal void RemoveDraggedColumnGhost( UIElement element ) - { - if( m_elementToDraggedElementAdorner.Count == 0 ) - return; - - DraggedElementAdorner adorner; - if( !m_elementToDraggedElementAdorner.TryGetValue( element, out adorner ) ) - return; - - Debug.Assert( adorner != null ); - this.AdornerLayer.Remove( adorner ); - m_elementToDraggedElementAdorner.Remove( element ); - } - - internal bool ContainsDraggedColumnGhost( UIElement element ) - { - if( ( element == null ) || ( m_elementToDraggedElementAdorner.Count == 0 ) ) - return false; - - return m_elementToDraggedElementAdorner.ContainsKey( element ); - } - - internal bool CanReorder( ColumnManagerCell draggedCell, ColumnManagerCell dropTarget, RelativePoint? dropPoint ) - { - if( ( draggedCell == null ) - || ( dropTarget == null ) - || ( draggedCell == dropTarget ) - || !dropPoint.HasValue - || ( DataGridControl.GetDataGridContext( draggedCell ) != m_dataGridContext ) - || ( DataGridControl.GetDataGridContext( dropTarget ) != DataGridControl.GetDataGridContext( draggedCell ) ) ) - return false; - - var dropColumn = dropTarget.ParentColumn; - if( dropColumn == null ) - return false; - - var sourceLayout = m_dataGridContext.ColumnManager; - var dropColumnLocation = sourceLayout.GetColumnLocationFor( dropColumn ); - if( dropColumnLocation == null ) - return false; - - if( ColumnReorderingDragSourceManager.IsPointLocatedBeforeTarget( dropTarget, dropPoint ) ) - { - if( !draggedCell.CanMoveBefore( dropColumn ) ) - return false; - - for( var location = dropColumnLocation.GetPreviousSibling(); location != null; location = location.GetPreviousSibling() ) - { - if( location.Type != LocationType.Column ) - continue; - - var previousColumn = ( ( ColumnHierarchyManager.IColumnLocation )location ).Column; - if( !draggedCell.CanMoveAfter( previousColumn ) ) - return false; - - break; - } - } - else if( ColumnReorderingDragSourceManager.IsPointLocatedAfterTarget( dropTarget, dropPoint ) ) - { - if( !draggedCell.CanMoveAfter( dropColumn ) ) - return false; - - for( var location = dropColumnLocation.GetNextSibling(); location != null; location = location.GetNextSibling() ) - { - if( location.Type != LocationType.Column ) - continue; - - var nextColumn = ( ( ColumnHierarchyManager.IColumnLocation )location ).Column; - if( !draggedCell.CanMoveBefore( nextColumn ) ) - return false; - - break; - } - } - else - { - return false; - } - - return true; - } - - internal void CommitReordering() - { - var draggedCell = this.DraggedElement as Cell; - if( draggedCell == null ) - return; - - var draggedColumn = draggedCell.ParentColumn; - if( draggedColumn == null ) - return; - - var draggedColumnReorderLocation = m_columnsLayout[ draggedColumn ]; - if( draggedColumnReorderLocation == null ) - return; - - var sourceLayout = m_dataGridContext.ColumnManager; - - var draggedColumnSourceLocation = sourceLayout.GetColumnLocationFor( draggedColumn ); - Debug.Assert( draggedColumnSourceLocation != null ); - if( draggedColumnSourceLocation == null ) - return; - - var previousLocation = draggedColumnReorderLocation.GetPreviousSibling(); - if( previousLocation != null ) - { - switch( previousLocation.Type ) - { - case LocationType.Column: - { - var pivotColumn = ( ( ColumnHierarchyModel.IColumnLocation )previousLocation ).Column; - var pivotLocation = sourceLayout.GetColumnLocationFor( pivotColumn ); - - if( pivotLocation != null ) - { - Debug.Assert( draggedColumnSourceLocation.CanMoveAfter( pivotLocation ) ); - draggedColumnSourceLocation.MoveAfter( pivotLocation ); - return; - } - } - break; - - case LocationType.Splitter: - { - var levelMarkers = sourceLayout.GetLevelMarkersFor( draggedColumn.ContainingCollection ); - var pivotLocation = ( levelMarkers != null ) ? levelMarkers.Splitter : null; - - if( ( pivotLocation != null ) && draggedColumnSourceLocation.CanMoveAfter( pivotLocation ) ) - { - draggedColumnSourceLocation.MoveAfter( pivotLocation ); - return; - } - } - break; - - case LocationType.Start: - { - var levelMarkers = sourceLayout.GetLevelMarkersFor( draggedColumn.ContainingCollection ); - var pivotLocation = ( levelMarkers != null ) ? levelMarkers.Start : null; - - if( ( pivotLocation != null ) && draggedColumnSourceLocation.CanMoveAfter( pivotLocation ) ) - { - draggedColumnSourceLocation.MoveAfter( pivotLocation ); - return; - } - } - break; - - default: - throw new NotImplementedException( "Unexpected target location." ); - } - } - - var nextLocation = draggedColumnReorderLocation.GetNextSibling(); - if( nextLocation != null ) - { - switch( nextLocation.Type ) - { - case LocationType.Column: - { - var pivotColumn = ( ( ColumnHierarchyModel.IColumnLocation )nextLocation ).Column; - var pivotLocation = sourceLayout.GetColumnLocationFor( pivotColumn ); - - if( pivotLocation != null ) - { - Debug.Assert( draggedColumnSourceLocation.CanMoveBefore( pivotLocation ) ); - draggedColumnSourceLocation.MoveBefore( pivotLocation ); - return; - } - } - break; - - case LocationType.Splitter: - { - var levelMarkers = sourceLayout.GetLevelMarkersFor( draggedColumn.ContainingCollection ); - var pivotLocation = ( levelMarkers != null ) ? levelMarkers.Splitter : null; - - if( ( pivotLocation != null ) && draggedColumnSourceLocation.CanMoveBefore( pivotLocation ) ) - { - draggedColumnSourceLocation.MoveBefore( pivotLocation ); - return; - } - } - break; - - case LocationType.Orphan: - { - var levelMarkers = sourceLayout.GetLevelMarkersFor( draggedColumn.ContainingCollection ); - var pivotLocation = ( levelMarkers != null ) ? levelMarkers.Orphan : null; - - if( ( pivotLocation != null ) && draggedColumnSourceLocation.CanMoveBefore( pivotLocation ) ) - { - draggedColumnSourceLocation.MoveBefore( pivotLocation ); - return; - } - } - break; - - default: - throw new NotImplementedException( "Unexpected target location." ); - } - } - - var parentLocation = draggedColumnReorderLocation.GetParent(); - if( parentLocation != null ) - { - switch( parentLocation.Type ) - { - case LocationType.Column: - { - var pivotColumn = ( ( ColumnHierarchyModel.IColumnLocation )parentLocation ).Column; - var pivotLocation = sourceLayout.GetColumnLocationFor( pivotColumn ); - - if( pivotLocation != null ) - { - Debug.Assert( draggedColumnSourceLocation.CanMoveUnder( pivotLocation ) ); - draggedColumnSourceLocation.MoveUnder( pivotLocation ); - return; - } - } - break; - } - } - - this.ClearColumnAnimations(); - this.ClearSplitterAnimation(); - } - - internal IEnumerable GetDropTargetsAtPoint( RelativePoint point ) - { - var container = this.Container; - if( container == null ) - yield break; - - for( var target = container.InputHitTest( point.GetPoint( container ) ) as DependencyObject; target != null; target = Xceed.Utils.Wpf.TreeHelper.GetParent( target ) ) - { - var dropTarget = target as IDropTarget; - if( dropTarget == null ) - continue; - - yield return dropTarget; - } - } - - private static bool IsPointLocatedBeforeTarget( FrameworkElement target, RelativePoint? point ) - { - if( ( target == null ) || !point.HasValue ) - return false; - - var targetPoint = point.Value.GetPoint( target ); - - return ( targetPoint.X <= target.ActualWidth / 2d ); - } - - private static bool IsPointLocatedAfterTarget( FrameworkElement target, RelativePoint? point ) - { - if( ( target == null ) || !point.HasValue ) - return false; - - var targetPoint = point.Value.GetPoint( target ); - - return ( targetPoint.X > target.ActualWidth / 2d ); - } - - private DropTargetInfo GetDropTargetAtPoint( UIElement draggedElement, RelativePoint point ) - { - foreach( var dropTarget in this.GetDropTargetsAtPoint( point ) ) - { - if( dropTarget.CanDropElement( draggedElement, point ) ) - return new DropTargetInfo( dropTarget, point, true ); - } - - return default( DropTargetInfo ); - } - - private static void ClearTranslateTransformAnimation( TranslateTransform transform ) - { - if( transform == null ) - return; - - // Force a local value before removing the potential animation clock of this transform to avoid leaving the current animated value after animation is removed - transform.X = 0d; - transform.ApplyAnimationClock( TranslateTransform.XProperty, null ); - } - - private static void ClearScaleTransformAnimation( ScaleTransform transform ) - { - if( transform == null ) - return; - - // Force a local value before removing the potential animation clock of this transform to avoid leaving the current animated value after animation is removed - transform.CenterX = 0d; - transform.ScaleX = 1d; - transform.ApplyAnimationClock( ScaleTransform.ScaleXProperty, null ); - } - - private void SetPopupDragAdorner( ColumnManagerCell columnManagerCell ) - { - if( columnManagerCell == null ) - return; - - if( m_popupDraggedElementAdorner != null ) - { - this.AdornerLayer.Remove( m_popupDraggedElementAdorner ); - m_popupDraggedElementAdorner = null; - } - - var dataGridControl = m_dataGridContext.DataGridControl; - var dataGridControlRect = new Rect( 0d, 0d, dataGridControl.ActualWidth, dataGridControl.ActualHeight ); - var elementToDataGridControl = columnManagerCell.TranslatePoint( s_origin, dataGridControl ); - var elementRect = new Rect( elementToDataGridControl, columnManagerCell.RenderSize ); - - // This is a special case with the current Element that is always be layouted, but can be out of view - if( !elementRect.IntersectsWith( dataGridControlRect ) ) - return; - - var adorner = new AnimatedDraggedElementAdorner( columnManagerCell, this.AdornerLayer, true ); - adorner.AdornedElementImage.Opacity = 0d; - - this.ApplyContainerClip( adorner ); - this.AdornerLayer.Add( adorner ); - - m_popupDraggedElementAdorner = adorner; - } - - private void StopAnimationsAndRollback() - { - // Ensure to pause any animation that was applied to ghost adorners. - this.PauseGhostToMousePositionAnimation(); - this.PauseMoveGhostToTargetColumnAnimation(); - this.PauseMoveGhostToTargetAndDetachAnimation(); - - m_reorderCancelled = false; - - this.ShowGhost = true; - - this.ClearColumnAnimations(); - this.ClearSplitterAnimation(); - } - - private void UpdateMouseMoveDirection( Func getPosition ) - { - var draggedElement = this.DraggedElement; - var draggedElementToMouse = getPosition.Invoke( draggedElement ); - var currentDraggedElementOffset = draggedElement.TranslatePoint( draggedElementToMouse, this.Container ).X; - - // Verify if there is an horizontal change according to the lastchange - var dragRect = new Rect( m_lastDraggedElementOffset - SystemParameters.MinimumHorizontalDragDistance, 0d, SystemParameters.MinimumVerticalDragDistance * 2, 0d ); - if( dragRect.Contains( new Point( currentDraggedElementOffset, 0 ) ) ) - return; - - if( currentDraggedElementOffset < m_lastDraggedElementOffset ) - { - m_horizontalMouseDragDirection = HorizontalMouseDragDirection.Left; - } - else if( currentDraggedElementOffset > m_lastDraggedElementOffset ) - { - m_horizontalMouseDragDirection = HorizontalMouseDragDirection.Right; - } - - m_lastDraggedElementOffset = currentDraggedElementOffset; - } - - private void UpdateIsAnimatedColumnReorderingEnabled() - { - var tableflowView = m_dataGridContext.DataGridControl.GetView() as TableflowView; - - // Column reordering is not allowed in a detail when details are flatten. - var isAnimatedColumnReorderingEnabled = ( tableflowView != null ) - && ( tableflowView.IsAnimatedColumnReorderingEnabled ) - && ( !m_dataGridContext.IsAFlattenDetail ); - - // Make sure the dragged cell's parent row allows column reordering. - if( isAnimatedColumnReorderingEnabled ) - { - var draggedCell = this.DraggedElement as Cell; - if( draggedCell != null ) - { - // We don't want any ghost to be displayed when column reordering is not allowed by the parent row. - // Setting the IsAnimatedColumnReorderingEnabled property will prevent this and will display the Cursor.No when dragging. - var parentRow = draggedCell.ParentRow as ColumnManagerRow; - if( parentRow != null ) - { - isAnimatedColumnReorderingEnabled = parentRow.AllowColumnReorder; - } - - // The main column is not allowed to be reorder when details are flatten. - if( isAnimatedColumnReorderingEnabled && m_dataGridContext.AreDetailsFlatten ) - { - var parentColumn = draggedCell.ParentColumn; - if( parentColumn != null ) - { - isAnimatedColumnReorderingEnabled = ( parentColumn != null ) && !parentColumn.IsMainColumn; - } - } - } - } - - this.IsAnimatedColumnReorderingEnabled = isAnimatedColumnReorderingEnabled; - } - - private void MoveGhostToMousePosition( Point mousePosition ) - { - // Ensure the opacity of the ghost is correctly set - this.ShowDraggedColumnGhosts(); - - var currentAdornerPosition = mousePosition; - - if( m_elementToDraggedElementAdorner.Count == 0 ) - return; - - var remainingDuration = s_returnToOriginalPositionDuration; - - if( m_ghostToMousePositionAnimationClock != null ) - { - var pointAnimation = m_ghostToMousePositionAnimationClock.Timeline as PointAnimation; - var currentValue = pointAnimation.To.GetValueOrDefault(); - var deltaX = currentValue.X - mousePosition.X; - var deltaY = currentValue.Y - mousePosition.Y; - - var dragingX = Math.Abs( deltaX ) > SystemParameters.MinimumHorizontalDragDistance; - var dragingY = Math.Abs( deltaY ) > SystemParameters.MinimumVerticalDragDistance; - - // If the target value is already the correct one, no need to stop animation and create another one - if( ( pointAnimation != null ) && ( !dragingX && !dragingY ) ) - return; - - if( m_ghostToMousePositionAnimationClock.CurrentState == ClockState.Active ) - { - // The remaining duration is the Timeline Duration less the elapsed time - remainingDuration = new Duration( pointAnimation.Duration.TimeSpan - m_ghostToMousePositionAnimationClock.CurrentTime.Value ); - } - } - - this.PauseGhostToMousePositionAnimation(); - - var animation = new PointAnimation( currentAdornerPosition, mousePosition, remainingDuration ); - - m_ghostToMousePositionAnimationClock = animation.CreateClock( true ) as AnimationClock; - m_ghostToMousePositionAnimationClock.Completed += new EventHandler( this.GhostToMousePosition_Completed ); - - foreach( var adorner in this.GetElementAdorners() ) - { - adorner.ApplyAnimationClock( DraggedElementAdorner.OffsetProperty, m_ghostToMousePositionAnimationClock, HandoffBehavior.SnapshotAndReplace ); - } - - m_ghostToMousePositionAnimationClock.Controller.Begin(); - } - - private void GhostToMousePosition_Completed( object sender, EventArgs e ) - { - if( m_ghostToMousePositionAnimationClock == sender ) - { - this.PauseGhostToMousePositionAnimation(); - } - - // Ghosts are returned to their original position reordering was successfully cancelled - m_reorderCancelled = false; - } - - private void PauseGhostToMousePositionAnimation() - { - if( m_ghostToMousePositionAnimationClock == null ) - return; - - // Stop the animation, do not simply pause it, so it resets correctly. - m_ghostToMousePositionAnimationClock.Controller.Stop(); - m_ghostToMousePositionAnimationClock.Completed -= new EventHandler( this.GhostToMousePosition_Completed ); - m_ghostToMousePositionAnimationClock = null; - } - - private void MoveGhostToTargetColumn( Point mousePostion ) - { - if( m_elementToDraggedElementAdorner.Count == 0 ) - return; - - var remainingDuration = s_returnToOriginalPositionDuration; - - if( m_ghostToTargetColumnAnimationClock != null ) - { - var pointAnimation = m_ghostToTargetColumnAnimationClock.Timeline as PointAnimation; - - // If the target value is already the correct one, no need to stop animation and create another one - if( ( pointAnimation != null ) && ( pointAnimation.To == s_origin ) ) - return; - - if( m_ghostToTargetColumnAnimationClock.CurrentState == ClockState.Active ) - { - // The remaining duration is the Timeline Duration less the elapsed time - remainingDuration = new Duration( pointAnimation.Duration.TimeSpan - m_ghostToTargetColumnAnimationClock.CurrentTime.Value ); - } - } - - // We must apply the DraggedCell FadeIn animation to let the DraggedCell reappears while the ghosts are moving to their target position - this.ApplyDraggedElementFadeInAnimation(); - this.PauseMoveGhostToTargetColumnAnimation(); - - var animation = new PointAnimation( mousePostion, s_origin, remainingDuration ); - - m_ghostToTargetColumnAnimationClock = animation.CreateClock( true ) as AnimationClock; - m_ghostToTargetColumnAnimationClock.Completed += new EventHandler( this.GhostToTargetAnimation_Completed ); - - foreach( var adorner in this.GetElementAdorners() ) - { - adorner.ApplyAnimationClock( DraggedElementAdorner.OffsetProperty, m_ghostToTargetColumnAnimationClock, HandoffBehavior.SnapshotAndReplace ); - } - } - - private void GhostToTargetAnimation_Completed( object sender, EventArgs e ) - { - if( m_ghostToTargetColumnAnimationClock == sender ) - { - this.PauseMoveGhostToTargetColumnAnimation(); - } - else if( m_draggedElementFadeInAnimationClock == sender ) - { - this.PauseDraggedElementFadeInAnimation(); - } - - if( ( m_ghostToTargetColumnAnimationClock == null ) && ( m_draggedElementFadeInAnimationClock == null ) ) - { - // The ghosts were successfully moved to the target position so we hide the ghosts and display the Cells in order - // for the DraggedElementGhost, which is a VisualBrush of the DraggedElement that is transparent during the drag. - this.HideDraggedColumnGhosts(); - this.ShowDraggedElements(); - m_reorderCancelled = false; - } - } - - private void PauseMoveGhostToTargetColumnAnimation() - { - if( m_ghostToTargetColumnAnimationClock == null ) - return; - - // Stop the animation, do not simply pause it, so it resets correctly. - m_ghostToTargetColumnAnimationClock.Controller.Stop(); - m_ghostToTargetColumnAnimationClock.Completed -= new EventHandler( this.GhostToTargetAnimation_Completed ); - m_ghostToTargetColumnAnimationClock = null; - } - - private void MoveGhostToTargetAndDetach() - { - if( m_elementToDraggedElementAdorner.Count == 0 ) - { - this.DetachManager(); - return; - } - - this.PauseMoveGhostToTargetAndDetachAnimation(); - - var draggedCell = this.DraggedElement as ColumnManagerCell; - if( draggedCell == null ) - return; - - var parentColumn = draggedCell.ParentColumn; - if( parentColumn == null ) - return; - - var parentRow = draggedCell.ParentRow; - if( ( parentRow == null ) || ( parentRow.CellsHostPanel == null ) ) - return; - - var cellsHostPanel = parentRow.CellsHostPanel as FixedCellPanel; - var draggedAdorner = m_elementToDraggedElementAdorner[ draggedCell ]; - var fromPoint = default( Point ); - - if( ( draggedAdorner != null ) && ( cellsHostPanel != null ) ) - { - Debug.Assert( m_columnVirtualizationManager != null ); - - // Update the column layout in order to have the right offset. - m_columnVirtualizationManager.Update(); - - var toPoint = default( Point? ); - var fixedPanel = cellsHostPanel.FixedPanel as FixedCellSubPanel; - var scrollingPanel = cellsHostPanel.ScrollingCellsDecorator.Child as VirtualizingFixedCellSubPanel; - - if( m_columnVirtualizationManager.GetScrollingFieldNames( m_level ).Contains( parentColumn ) ) - { - if( scrollingPanel != null ) - { - var targetPosition = scrollingPanel.CalculateCellOffset( parentColumn ); - - // The position must be adjusted when the dragged cell is moved from the fixed panel to the scrolling panel. - targetPosition.Offset( m_columnVirtualizationManager.FixedColumnsWidth - fixedPanel.ActualWidth, 0d ); - - toPoint = scrollingPanel.TranslatePoint( targetPosition, draggedAdorner ); - } - } - else if( m_columnVirtualizationManager.GetFixedFieldNames( m_level ).Contains( parentColumn ) ) - { - if( fixedPanel != null ) - { - var targetPosition = fixedPanel.CalculateCellOffset( parentColumn ); - toPoint = fixedPanel.TranslatePoint( targetPosition, draggedAdorner ); - } - } - - if( toPoint.HasValue ) - { - fromPoint = new Point( -toPoint.Value.X, -toPoint.Value.Y ); - } - else - { - fromPoint = draggedAdorner.Offset; - } - } - - var animation = new PointAnimation( fromPoint, new Point(), s_columnAnimationDuration ); - - m_ghostToTargetAndDetachAnimationClock = ( AnimationClock )animation.CreateClock( true ); - m_ghostToTargetAndDetachAnimationClock.Completed += new EventHandler( this.MoveGhostToTargetAndDetach_Completed ); - - //Animate all cells of all columns. - foreach( var entry in this.GetElementAdornerEntries() ) - { - var cell = entry.Key as Cell; - if( cell == null ) - { - Debug.Assert( false, "Only Cells should be dragged by this manager" ); - continue; - } - - var adorner = entry.Value; - adorner.ApplyAnimationClock( DraggedElementAdorner.OffsetProperty, m_ghostToTargetAndDetachAnimationClock, HandoffBehavior.SnapshotAndReplace ); - } - - m_ghostToTargetAndDetachAnimationClock.Controller.Begin(); - } - - private void MoveGhostToTargetAndDetach_Completed( object sender, EventArgs e ) - { - // Ensure to stop and unregister any event handlers from animations if not null by completed - this.PauseMoveGhostToTargetAndDetachAnimation(); - this.DetachManager(); - } - - private void PauseMoveGhostToTargetAndDetachAnimation() - { - if( m_ghostToTargetAndDetachAnimationClock == null ) - return; - - // Stop the animation, do not simply pause it, so it resets correctly. - m_ghostToTargetAndDetachAnimationClock.Controller.Stop(); - m_ghostToTargetAndDetachAnimationClock.Completed -= new EventHandler( this.MoveGhostToTargetAndDetach_Completed ); - m_ghostToTargetAndDetachAnimationClock = null; - } - - private void DetachManager() - { - this.ShowDraggedElements(); - - var draggedCell = this.DraggedElement as Cell; - var parentColumn = ( draggedCell != null ) ? draggedCell.ParentColumn : null; - - if( ( parentColumn != null ) && this.OwnElement( draggedCell ) ) - { - parentColumn.SetIsBeingDraggedAnimated( false ); - } - - // Clear properties on the manager if it is the one currently in use on for this Detail level. This avoids problem with the FixedColumnSplitter - // when multiple Cells are moved rapidly: - // The FixedColumnSplitter listens to TableflowView.AreColumnsBeingReordered internal ViewProperty to bind to the TableflowView.FixedColumnSplitterTranslation internal - // ViewProperty. The internal ViewProperty ColumnReorderingDragSourceManager is affected when a new Drag begins. The old DragSourceManager is not stopped to allow - // any pending animations to complete smoothly. If the first manager clears the TableflowView.AreColumnBeingReordered property, the FixedColumnSplitters - // just clears its binding to the FixedColumnSplitterTranslation and is no more animated. - // - // Ensuring that the current manager for this Detail level ensure that no other drag was initialized since this manager started animations. - - if( this.OwnElement( m_dataGridContext ) ) - { - TableflowView.SetAreColumnsBeingReordered( m_dataGridContext, false ); - - if( ( parentColumn != null ) && this.OwnElement( draggedCell ) ) - { - parentColumn.ClearColumnReorderingDragSourceManager(); - } - - TableflowView.ClearColumnReorderingDragSourceManager( m_dataGridContext ); - } - } - - private void UpdateColumnsLayout() - { - var targetCell = this.CurrentDropTarget as ColumnManagerCell; - var targetPoint = this.CurrentDropTargetToContainerPosition; - Debug.Assert( targetCell != null ); - Debug.Assert( DataGridControl.GetDataGridContext( targetCell ) == m_dataGridContext ); - - var targetColumn = targetCell.ParentColumn; - Debug.Assert( targetColumn != null ); - - var targetLocation = m_columnsLayout[ targetColumn ]; - Debug.Assert( targetLocation != null ); - if( targetLocation == null ) - return; - - var draggedCell = this.DraggedElement as Cell; - Debug.Assert( draggedCell != null ); - var draggedLocation = m_columnsLayout[ draggedCell.ParentColumn ]; - Debug.Assert( draggedLocation != null ); - if( draggedLocation == null ) - return; - - // Drop before target cell. - if( ColumnReorderingDragSourceManager.IsPointLocatedBeforeTarget( targetCell, targetPoint ) ) - { - if( !draggedLocation.CanMoveBefore( targetLocation ) || object.Equals( draggedLocation, targetLocation.GetPreviousSibling() ) ) - return; - - draggedLocation.MoveBefore( targetLocation ); - } - // Drop after target cell. - else if( ColumnReorderingDragSourceManager.IsPointLocatedAfterTarget( targetCell, targetPoint ) ) - { - if( !draggedLocation.CanMoveAfter( targetLocation ) || object.Equals( draggedLocation, targetLocation.GetNextSibling() ) ) - return; - - draggedLocation.MoveAfter( targetLocation ); - } - else - { - return; - } - - this.UpdateColumnsLayoutAnimations(); - } - - private void UpdateColumnsLayoutAnimations() - { - this.ResetColumnsLayoutAnimations(); - - var draggedCell = ( Cell )this.DraggedElement; - var draggedColumn = draggedCell.ParentColumn; - - var draggedColumnReorderLocation = m_columnsLayout[ draggedColumn ]; - Debug.Assert( draggedColumnReorderLocation != null ); - if( draggedColumnReorderLocation == null ) - return; - - var draggedColumnSourceLocation = m_dataGridContext.ColumnManager.GetColumnLocationFor( draggedColumn ); - Debug.Assert( draggedColumnSourceLocation != null ); - if( draggedColumnSourceLocation == null ) - return; - - Debug.Assert( m_columnVirtualizationManager != null ); - - var indexOfDraggedColumnInReorderedColumns = this.GetColumnLocations( this.GetPreviousLocationsOf( draggedColumnReorderLocation ) ).Count(); - var indexOfDraggedColumnInSourceColumns = this.GetColumnLocations( this.GetPreviousLocationsOf( draggedColumnSourceLocation ) ).Count(); - var columnsInView = m_columnVirtualizationManager.GetVisibleFieldNames( m_level ); - var isDraggingLeft = ( indexOfDraggedColumnInReorderedColumns < indexOfDraggedColumnInSourceColumns ); - var isDraggingRight = ( indexOfDraggedColumnInReorderedColumns > indexOfDraggedColumnInSourceColumns ); - - if( isDraggingLeft ) - { - var remaining = indexOfDraggedColumnInSourceColumns - indexOfDraggedColumnInReorderedColumns; - - foreach( var columnLocation in this.GetColumnLocations( this.GetNextLocationsOf( draggedColumnReorderLocation ) ) ) - { - if( remaining <= 0 ) - break; - - if( columnsInView.Contains( columnLocation.Column ) ) - { - this.AnimateColumn( columnLocation, AnimationType.MoveRight ); - this.AnimateColumnDescendants( columnLocation, AnimationType.MoveRight ); - this.AnimateColumnAncestors( columnLocation, AnimationType.MoveRight ); - } - - remaining--; - } - } - else if( isDraggingRight ) - { - var remaining = indexOfDraggedColumnInReorderedColumns - indexOfDraggedColumnInSourceColumns; - - foreach( var columnLocation in this.GetColumnLocations( this.GetPreviousLocationsOf( draggedColumnReorderLocation ) ) ) - { - if( remaining <= 0 ) - break; - - if( columnsInView.Contains( columnLocation.Column ) ) - { - this.AnimateColumn( columnLocation, AnimationType.MoveLeft ); - this.AnimateColumnDescendants( columnLocation, AnimationType.MoveLeft ); - this.AnimateColumnAncestors( columnLocation, AnimationType.MoveLeft ); - } - - remaining--; - } - } - - var commonAncestor = this.GetCommonAncestor( draggedColumnSourceLocation, draggedColumnReorderLocation ); - - // Adjust the animation type on the ancestors. - for( var childLocation = draggedColumnSourceLocation; childLocation != null; ) - { - var parentLocation = childLocation.GetParent() as ColumnHierarchyManager.IColumnLocation; - if( ( parentLocation == null ) || ( parentLocation.Column == commonAncestor ) ) - break; - - var columnLocation = m_columnsLayout[ parentLocation.Column ]; - Debug.Assert( columnLocation != null ); - - switch( columnLocation.Status ) - { - case AnimationType.MoveLeft: - this.AnimateColumn( columnLocation, AnimationType.DecreaseWidth ); - break; - - case AnimationType.MoveRight: - this.AnimateColumn( columnLocation, AnimationType.MoveRightAndDecreaseWidth ); - break; - - default: - { - if( isDraggingLeft ) - { - this.AnimateColumn( columnLocation, AnimationType.MoveRightAndDecreaseWidth ); - } - else if( isDraggingRight ) - { - this.AnimateColumn( columnLocation, AnimationType.DecreaseWidth ); - } - else - { - var wasFirstVisibleChildColumn = !this.GetVisibleLocations( this.GetColumnLocations( this.GetPreviousSiblingLocationsOf( childLocation ) ) ).Any(); - var wasLastVisibleChildColumn = !this.GetVisibleLocations( this.GetColumnLocations( this.GetNextSiblingLocationsOf( childLocation ) ) ).Any(); - - // We must check for last first since we want to apply the "last" animation if the column is both - // the first and last child. - if( wasLastVisibleChildColumn ) - { - this.AnimateColumn( columnLocation, AnimationType.DecreaseWidth ); - } - else if( wasFirstVisibleChildColumn ) - { - this.AnimateColumn( columnLocation, AnimationType.MoveRightAndDecreaseWidth ); - } - } - } - break; - } - - childLocation = parentLocation; - } - - for( var childLocation = draggedColumnReorderLocation; childLocation != null; ) - { - var parentLocation = childLocation.GetParent() as ColumnHierarchyModel.IColumnLocation; - if( ( parentLocation == null ) || ( parentLocation.Column == commonAncestor ) ) - break; - - switch( parentLocation.Status ) - { - case AnimationType.MoveLeft: - this.AnimateColumn( parentLocation, AnimationType.MoveLeftAndIncreaseWidth ); - break; - - case AnimationType.MoveRight: - this.AnimateColumn( parentLocation, AnimationType.IncreaseWidth ); - break; - - default: - { - if( isDraggingLeft ) - { - this.AnimateColumn( parentLocation, AnimationType.IncreaseWidth ); - } - else if( isDraggingRight ) - { - this.AnimateColumn( parentLocation, AnimationType.MoveLeftAndIncreaseWidth ); - } - else - { - var isFirstVisibleChildColumn = !this.GetVisibleLocations( this.GetColumnLocations( this.GetPreviousSiblingLocationsOf( childLocation ) ) ).Any(); - var isLastVisibleChildColumn = !this.GetVisibleLocations( this.GetColumnLocations( this.GetNextSiblingLocationsOf( childLocation ) ) ).Any(); - - // We must check for last first since we want to apply the "last" animation if the column is both - // the first and last child. - if( isLastVisibleChildColumn ) - { - this.AnimateColumn( parentLocation, AnimationType.IncreaseWidth ); - } - else if( isFirstVisibleChildColumn ) - { - this.AnimateColumn( parentLocation, AnimationType.MoveLeftAndIncreaseWidth ); - } - } - } - break; - } - - childLocation = parentLocation; - } - - // Since the column is staying under the same ancestor, no animation needs to be done. - if( commonAncestor != null ) - { - var columnLocation = m_columnsLayout[ commonAncestor ]; - Debug.Assert( columnLocation != null ); - - this.AnimateColumn( columnLocation, AnimationType.Rollback ); - this.AnimateColumnAncestors( columnLocation, AnimationType.Rollback ); - } - } - - private void ResetColumnsLayoutAnimations() - { - for( int i = 0; i < m_columnsLayout.LevelCount; i++ ) - { - foreach( var location in this.GetColumnLocations( this.GetNextLocationsOf( m_columnsLayout.GetLevelMarkers( i ).Start ) ) ) - { - location.Status = AnimationType.Rollback; - } - } - } - - private ColumnHierarchyManager.ILevelMarkers GetTopLevelMarkers() - { - return m_dataGridContext.ColumnManager.GetLevelMarkersFor( m_dataGridContext.Columns ); - } - - private ColumnHierarchyManager.ILocation GetTopLevelStartLocation() - { - var levelMarkers = this.GetTopLevelMarkers(); - - Debug.Assert( levelMarkers != null ); - if( levelMarkers == null ) - return null; - - return levelMarkers.Start; - } - - private IEnumerable GetColumnLocations( IEnumerable locations ) - { - if( locations == null ) - return Enumerable.Empty(); - - return ( from location in locations - let columnLocation = location as ColumnHierarchyManager.IColumnLocation - where ( columnLocation != null ) - select columnLocation ); - } - - private IEnumerable GetColumnLocations( IEnumerable locations ) - { - if( locations == null ) - return Enumerable.Empty(); - - return ( from location in locations - let columnLocation = location as ColumnHierarchyModel.IColumnLocation - where ( columnLocation != null ) - select columnLocation ); - } - - private IEnumerable GetVisibleLocations( IEnumerable locations ) - { - if( locations == null ) - return Enumerable.Empty(); - - return ( from location in locations - where location.Column.Visible - select location ); - } - - private IEnumerable GetVisibleLocations( IEnumerable locations ) - { - if( locations == null ) - return Enumerable.Empty(); - - return ( from location in locations - where location.Column.Visible - select location ); - } - - private IEnumerable GetNextLocationsOf( ColumnHierarchyManager.ILocation location ) - { - if( location == null ) - yield break; - - var targetLocation = location.GetNextSiblingOrCousin(); - while( targetLocation != null ) - { - yield return targetLocation; - targetLocation = targetLocation.GetNextSiblingOrCousin(); - } - } - - private IEnumerable GetNextLocationsOf( ColumnHierarchyModel.ILocation location ) - { - if( location == null ) - yield break; - - var targetLocation = location.GetNextSiblingOrCousin(); - while( targetLocation != null ) - { - yield return targetLocation; - targetLocation = targetLocation.GetNextSiblingOrCousin(); - } - } - - private IEnumerable GetNextSiblingLocationsOf( ColumnHierarchyManager.ILocation location ) - { - if( location == null ) - yield break; - - var targetLocation = location.GetNextSibling(); - while( targetLocation != null ) - { - yield return targetLocation; - targetLocation = targetLocation.GetNextSibling(); - } - } - - private IEnumerable GetNextSiblingLocationsOf( ColumnHierarchyModel.ILocation location ) - { - if( location == null ) - yield break; - - var targetLocation = location.GetNextSibling(); - while( targetLocation != null ) - { - yield return targetLocation; - targetLocation = targetLocation.GetNextSibling(); - } - } - - private IEnumerable GetPreviousLocationsOf( ColumnHierarchyManager.ILocation location ) - { - if( location == null ) - yield break; - - var targetLocation = location.GetPreviousSiblingOrCousin(); - while( targetLocation != null ) - { - yield return targetLocation; - targetLocation = targetLocation.GetPreviousSiblingOrCousin(); - } - } - - private IEnumerable GetPreviousLocationsOf( ColumnHierarchyModel.ILocation location ) - { - if( location == null ) - yield break; - - var targetLocation = location.GetPreviousSiblingOrCousin(); - while( targetLocation != null ) - { - yield return targetLocation; - targetLocation = targetLocation.GetPreviousSiblingOrCousin(); - } - } - - private IEnumerable GetPreviousSiblingLocationsOf( ColumnHierarchyManager.ILocation location ) - { - if( location == null ) - yield break; - - var targetLocation = location.GetPreviousSibling(); - while( targetLocation != null ) - { - yield return targetLocation; - targetLocation = targetLocation.GetPreviousSibling(); - } - } - - private IEnumerable GetPreviousSiblingLocationsOf( ColumnHierarchyModel.ILocation location ) - { - if( location == null ) - yield break; - - var targetLocation = location.GetPreviousSibling(); - while( targetLocation != null ) - { - yield return targetLocation; - targetLocation = targetLocation.GetPreviousSibling(); - } - } - - private IEnumerable GetChildLocationsOf( ColumnHierarchyManager.ILocation location ) - { - if( location == null ) - yield break; - - var targetLocation = location.GetFirstChild(); - - while( targetLocation != null ) - { - yield return targetLocation; - targetLocation = targetLocation.GetNextSibling(); - } - } - - private IEnumerable GetChildLocationsOf( ColumnHierarchyModel.ILocation location ) - { - if( location == null ) - yield break; - - var targetLocation = location.GetFirstChild(); - - while( targetLocation != null ) - { - yield return targetLocation; - targetLocation = targetLocation.GetNextSibling(); - } - } - - private void ApplyColumnsLayoutAnimations() - { - var draggedCell = this.DraggedElement as Cell; - Debug.Assert( draggedCell != null ); - - var draggedColumn = draggedCell.ParentColumn; - Debug.Assert( draggedColumn != null ); - - var draggedColumnWidth = draggedColumn.ActualWidth; - - var startLocation = this.GetTopLevelStartLocation(); - Debug.Assert( startLocation != null ); - - foreach( var location in this.GetNextLocationsOf( startLocation ) ) - { - this.ApplyColumnsLayoutAnimations( location, draggedColumnWidth, s_columnAnimationDuration ); - } - } - - private void ApplyColumnsLayoutAnimations( ColumnHierarchyManager.ILocation location, double draggedColumnWidth, Duration animationDuration ) - { - if( location == null ) - return; - - var columnLocation = location as ColumnHierarchyManager.IColumnLocation; - if( columnLocation != null ) - { - var column = columnLocation.Column; - var targetLocation = m_columnsLayout[ column ]; - var animationType = ( targetLocation != null ) ? targetLocation.Status : AnimationType.Rollback; - - switch( animationType ) - { - case AnimationType.MoveLeft: - { - this.StartColumnPositionAnimation( column, -draggedColumnWidth, animationDuration ); - } - break; - - case AnimationType.MoveRight: - { - this.StartColumnPositionAnimation( column, draggedColumnWidth, animationDuration ); - } - break; - - case AnimationType.MoveLeftAndIncreaseWidth: - { - } - break; - - case AnimationType.MoveRightAndDecreaseWidth: - { - } - break; - - case AnimationType.IncreaseWidth: - { - } - break; - - case AnimationType.DecreaseWidth: - { - } - break; - - case AnimationType.Rollback: - { - this.StartColumnPositionAnimation( column, 0d, animationDuration ); - } - break; - - default: - throw new NotImplementedException(); - } - } - - foreach( var childLocation in this.GetChildLocationsOf( location ) ) - { - this.ApplyColumnsLayoutAnimations( childLocation, draggedColumnWidth, animationDuration ); - } - } - - private void RollbackColumnsLayoutAnimations() - { - var startLocation = this.GetTopLevelStartLocation(); - Debug.Assert( startLocation != null ); - - foreach( var location in this.GetNextLocationsOf( startLocation ) ) - { - this.RollbackColumnsLayoutAnimations( location ); - } - } - - private void RollbackColumnsLayoutAnimations( ColumnHierarchyManager.ILocation location ) - { - if( location == null ) - return; - - var columnLocation = location as ColumnHierarchyManager.IColumnLocation; - if( columnLocation != null ) - { - var column = columnLocation.Column; - - this.StartColumnPositionAnimation( column, 0d, s_columnAnimationDuration ); - } - - foreach( var childLocation in this.GetChildLocationsOf( location ) ) - { - this.RollbackColumnsLayoutAnimations( childLocation ); - } - } - - private void ApplySplitterAnimation() - { - var draggedCell = this.DraggedElement as Cell; - var draggedColumn = ( draggedCell != null ) ? draggedCell.ParentColumn : null; - Debug.Assert( draggedColumn != null ); - - var draggedColumnContainingCollection = ( draggedColumn != null ) ? draggedColumn.ContainingCollection : null; - Debug.Assert( draggedColumnContainingCollection != null ); - - var sourceLevelMarkers = ( draggedColumnContainingCollection != null ) ? m_dataGridContext.ColumnManager.GetLevelMarkersFor( draggedColumnContainingCollection ) : null; - var sourceSplitter = ( sourceLevelMarkers != null ) ? sourceLevelMarkers.Splitter : null; - - var draggedColumnLocation = m_columnsLayout[ draggedColumn ]; - var reorderedLevelMarkers = ( draggedColumnLocation != null ) ? m_columnsLayout.GetLevelMarkers( draggedColumnLocation.Level ) : null; - var reorderedSplitter = ( reorderedLevelMarkers != null ) ? reorderedLevelMarkers.Splitter : null; - - int oldFixedColumnCount; - int newFixedColumnCount; - - if( ( sourceSplitter != null ) && ( reorderedSplitter != null ) ) - { - oldFixedColumnCount = this.GetVisibleLocations( this.GetColumnLocations( this.GetPreviousLocationsOf( sourceSplitter ) ) ).Count(); - newFixedColumnCount = this.GetVisibleLocations( this.GetColumnLocations( this.GetPreviousLocationsOf( reorderedSplitter ) ) ).Count(); - } - else - { - oldFixedColumnCount = 0; - newFixedColumnCount = 0; - } - - if( newFixedColumnCount > oldFixedColumnCount ) - { - Debug.Assert( draggedColumn != null ); - - this.StartSplitterPositionAnimation( draggedColumn.ActualWidth ); - } - else if( newFixedColumnCount < oldFixedColumnCount ) - { - Debug.Assert( draggedColumn != null ); - - this.StartSplitterPositionAnimation( -draggedColumn.ActualWidth ); - } - else - { - this.StartSplitterPositionAnimation( 0d ); - } - } - - private void RollbackReordering() - { - m_reorderCancelled = true; - - this.RollbackColumnsLayoutAnimations(); - this.StartSplitterPositionAnimation( 0d ); - } - - private void StartColumnPositionAnimation( ColumnBase column, double offset, Duration duration ) - { - if( column == null ) - return; - - var isMergedColumn = false; - - var transformGroup = ColumnReorderingDragSourceManager.GetColumnTransformGroup( column ); - var positionTransform = ColumnReorderingDragSourceManager.GetColumnPositionTransform( transformGroup ); - var sizeTransform = ColumnReorderingDragSourceManager.GetColumnSizeTransform( transformGroup ); - - var positionClock = default( AnimationClock ); - var sizeClock = default( AnimationClock ); - var clocks = default( ColumnAnimationClocks ); - - // Pause any previously started animation. - if( m_animationClocks.TryGetValue( column, out clocks ) ) - { - positionClock = clocks.Position; - var positionTimeLine = ( positionClock != null ) ? positionClock.Timeline as OffsetAnimation : null; - var resetPosition = ( positionTimeLine == null ) || ( positionTimeLine.To != offset ); - - sizeClock = clocks.Size; - var sizeTimeLine = ( sizeClock != null ) ? sizeClock.Timeline as OffsetAnimation : null; - var resetSize = ( isMergedColumn && ( ( sizeTimeLine == null ) || ( sizeTimeLine.To != 1d ) ) ) - || ( !isMergedColumn && ( sizeClock != null ) ); - - // No animation needs to be done. - if( !resetPosition && !resetSize ) - return; - - if( resetPosition && ( positionClock != null ) ) - { - var controller = positionClock.Controller; - Debug.Assert( controller != null ); - - // Stop the animation, do not simply pause it, so it resets correctly. - controller.Stop(); - controller.Remove(); - - positionClock.Completed -= new EventHandler( this.OnRollbackColumnAnimationCompleted ); - positionClock = null; - } - - if( resetSize && ( sizeClock != null ) ) - { - var controller = sizeClock.Controller; - Debug.Assert( controller != null ); - - // Stop the animation, do not simply pause it, so it resets correctly. - controller.Stop(); - controller.Remove(); - - sizeClock.Completed -= new EventHandler( this.OnRollbackColumnAnimationCompleted ); - sizeClock = null; - } - } - - if( positionClock == null ) - { - var animation = new OffsetAnimation( offset, duration ); - positionClock = animation.CreateClock( true ) as AnimationClock; - positionTransform.ApplyAnimationClock( TranslateTransform.XProperty, positionClock, HandoffBehavior.SnapshotAndReplace ); - - if( offset == 0d ) - { - positionClock.Completed += new EventHandler( this.OnRollbackColumnAnimationCompleted ); - } - - positionClock.Controller.Begin(); - } - - Debug.Assert( positionClock != null ); - - if( isMergedColumn && ( sizeClock == null ) ) - { - var animation = new OffsetAnimation( 1d, duration ); - sizeClock = animation.CreateClock( true ) as AnimationClock; - sizeTransform.ApplyAnimationClock( ScaleTransform.ScaleXProperty, sizeClock, HandoffBehavior.SnapshotAndReplace ); - - if( offset == 0d ) - { - sizeClock.Completed += new EventHandler( this.OnRollbackColumnAnimationCompleted ); - } - - sizeClock.Controller.Begin(); - } - - m_animationClocks[ column ] = new ColumnAnimationClocks( positionClock, sizeClock ); - } - - private void StartColumnSizeAnimation( ColumnBase column, double enlarge, Duration duration ) - { - if( column == null ) - return; - - Debug.Assert( column.Width != 0d ); - - //Calculate the resize ratio that needs to be applied to the ScaleTransform (works in %) - var resizedWith = column.Width + enlarge; - var resizedFactor = resizedWith / column.Width; - - var transformGroup = ColumnReorderingDragSourceManager.GetColumnTransformGroup( column ); - var positionTransform = ColumnReorderingDragSourceManager.GetColumnPositionTransform( transformGroup ); - var sizeTransform = ColumnReorderingDragSourceManager.GetColumnSizeTransform( transformGroup ); - - var positionClock = default( AnimationClock ); - var sizeClock = default( AnimationClock ); - var clocks = default( ColumnAnimationClocks ); - - // Pause any previously started animation. - if( m_animationClocks.TryGetValue( column, out clocks ) ) - { - positionClock = clocks.Position; - var positionTimeLine = ( positionClock != null ) ? positionClock.Timeline as OffsetAnimation : null; - var resetPosition = ( positionTimeLine == null ) || ( positionTimeLine.To != 0d ); - - sizeClock = clocks.Size; - var sizeTimeLine = ( sizeClock != null ) ? sizeClock.Timeline as OffsetAnimation : null; - var resetSize = ( sizeTimeLine == null ) || ( sizeTimeLine.To != resizedFactor ); - - // No animation needs to be done. - if( !resetPosition && !resetSize ) - return; - - if( resetPosition && ( positionClock != null ) ) - { - var controller = positionClock.Controller; - Debug.Assert( controller != null ); - - // Stop the animation, do not simply pause it, so it resets correctly. - controller.Stop(); - controller.Remove(); - - positionClock.Completed -= new EventHandler( this.OnRollbackColumnAnimationCompleted ); - positionClock = null; - } - - if( resetSize && ( sizeClock != null ) ) - { - var controller = sizeClock.Controller; - Debug.Assert( controller != null ); - - // Stop the animation, do not simply pause it, so it resets correctly. - controller.Stop(); - controller.Remove(); - - sizeClock.Completed -= new EventHandler( this.OnRollbackColumnAnimationCompleted ); - sizeClock = null; - } - } - - if( positionClock == null ) - { - var animation = new OffsetAnimation( 0d, duration ); - positionClock = animation.CreateClock( true ) as AnimationClock; - positionTransform.ApplyAnimationClock( TranslateTransform.XProperty, positionClock, HandoffBehavior.SnapshotAndReplace ); - - if( enlarge == 0d ) - { - positionClock.Completed += new EventHandler( this.OnRollbackColumnAnimationCompleted ); - } - - positionClock.Controller.Begin(); - } - - Debug.Assert( positionClock != null ); - - if( sizeClock == null ) - { - var animation = new OffsetAnimation( resizedFactor, duration ); - sizeClock = animation.CreateClock( true ) as AnimationClock; - sizeTransform.ApplyAnimationClock( ScaleTransform.ScaleXProperty, sizeClock, HandoffBehavior.SnapshotAndReplace ); - - if( enlarge == 0d ) - { - sizeClock.Completed += new EventHandler( this.OnRollbackColumnAnimationCompleted ); - } - - sizeClock.Controller.Begin(); - } - - Debug.Assert( sizeClock != null ); - - m_animationClocks[ column ] = new ColumnAnimationClocks( positionClock, sizeClock ); - } - - private void StartColumnPositionAndSizeAnimations( ColumnBase column, double offset, Duration duration ) - { - if( column == null ) - return; - - Debug.Assert( column.Width != 0d ); - - //Calculate the resize ratio that needs to be applied to the ScaleTransform (works in %) - var resizedWidth = column.Width - offset; - var resizedFactor = resizedWidth / column.Width; - - var transformGroup = ColumnReorderingDragSourceManager.GetColumnTransformGroup( column ); - var positionTransform = ColumnReorderingDragSourceManager.GetColumnPositionTransform( transformGroup ); - var sizeTransform = ColumnReorderingDragSourceManager.GetColumnSizeTransform( transformGroup ); - - var positionClock = default( AnimationClock ); - var sizeClock = default( AnimationClock ); - var clocks = default( ColumnAnimationClocks ); - - // Pause any previously started animation. - if( m_animationClocks.TryGetValue( column, out clocks ) ) - { - positionClock = clocks.Position; - var positionTimeLine = ( positionClock != null ) ? positionClock.Timeline as OffsetAnimation : null; - var resetPosition = ( positionTimeLine == null ) || ( positionTimeLine.To != offset ); - - sizeClock = clocks.Size; - var sizeTimeLine = ( sizeClock != null ) ? sizeClock.Timeline as OffsetAnimation : null; - var resetSize = ( sizeTimeLine == null ) || ( sizeTimeLine.To != resizedFactor ); - - // No animation needs to be done. - if( !resetPosition && !resetSize ) - return; - - if( resetPosition && ( positionClock != null ) ) - { - var controller = positionClock.Controller; - Debug.Assert( controller != null ); - - // Stop the animation, do not simply pause it, so it resets correctly. - controller.Stop(); - controller.Remove(); - - positionClock.Completed -= new EventHandler( this.OnRollbackColumnAnimationCompleted ); - positionClock = null; - } - - if( resetSize && ( sizeClock != null ) ) - { - var controller = sizeClock.Controller; - Debug.Assert( controller != null ); - - // Stop the animation, do not simply pause it, so it resets correctly. - controller.Stop(); - controller.Remove(); - - sizeClock.Completed -= new EventHandler( this.OnRollbackColumnAnimationCompleted ); - sizeClock = null; - } - } - - if( positionClock == null ) - { - var animation = new OffsetAnimation( offset, duration ); - positionClock = animation.CreateClock( true ) as AnimationClock; - positionTransform.ApplyAnimationClock( TranslateTransform.XProperty, positionClock, HandoffBehavior.SnapshotAndReplace ); - - if( offset == 0d ) - { - positionClock.Completed += new EventHandler( this.OnRollbackColumnAnimationCompleted ); - } - - positionClock.Controller.Begin(); - } - - Debug.Assert( positionClock != null ); - - if( sizeClock == null ) - { - var animation = new OffsetAnimation( resizedFactor, duration ); - sizeClock = animation.CreateClock( true ) as AnimationClock; - - // When doing both a position and a resize animation, the CenterX value must be set so the resizing is applied from the new position, - // or else the offset at which is starts will be wrong. - sizeTransform.CenterX = offset; - sizeTransform.ApplyAnimationClock( ScaleTransform.ScaleXProperty, sizeClock, HandoffBehavior.SnapshotAndReplace ); - - if( offset == 0d ) - { - sizeClock.Completed += new EventHandler( this.OnRollbackColumnAnimationCompleted ); - } - - sizeClock.Controller.Begin(); - } - - Debug.Assert( sizeClock != null ); - - m_animationClocks[ column ] = new ColumnAnimationClocks( positionClock, sizeClock ); - } - - private void StartSplitterPositionAnimation( double offset ) - { - if( m_splitterAnimationClock != null ) - { - var timeLine = m_splitterAnimationClock.Timeline as OffsetAnimation; - - // No animation needs to be done. - if( ( timeLine != null ) && ( timeLine.To == offset ) ) - return; - - var controller = m_splitterAnimationClock.Controller; - Debug.Assert( controller != null ); - - controller.Stop(); - controller.Remove(); - - m_splitterAnimationClock.Completed -= new EventHandler( this.OnRollbackSplitterPositionCompleted ); - } - - var animation = new OffsetAnimation( offset, s_columnAnimationDuration ); - m_splitterAnimationClock = animation.CreateClock( true ) as AnimationClock; - m_splitterTranslation.ApplyAnimationClock( TranslateTransform.XProperty, m_splitterAnimationClock, HandoffBehavior.SnapshotAndReplace ); - - if( m_splitterAnimationClock != null ) - { - if( offset == 0d ) - { - m_splitterAnimationClock.Completed += new EventHandler( this.OnRollbackSplitterPositionCompleted ); - } - - m_splitterAnimationClock.Controller.Begin(); - } - } - - private void OnRollbackColumnAnimationCompleted( object sender, EventArgs e ) - { - var animationClock = sender as AnimationClock; - if( animationClock == null ) - return; - - animationClock.Completed -= new EventHandler( this.OnRollbackColumnAnimationCompleted ); - - this.ClearAnimationClock( ref animationClock ); - } - - private void OnRollbackSplitterPositionCompleted( object sender, EventArgs e ) - { - var animationClock = sender as AnimationClock; - if( animationClock == null ) - return; - - animationClock.Completed -= new EventHandler( this.OnRollbackSplitterPositionCompleted ); - - if( m_splitterAnimationClock == animationClock ) - { - this.ClearAnimationClock( ref m_splitterAnimationClock ); - - Debug.Assert( ( m_splitterTranslation == null ) || ( m_splitterTranslation.X == 0d ) ); - } - else - { - this.ClearAnimationClock( ref animationClock ); - } - } - - private void ClearAnimationClock( ref AnimationClock animationClock ) - { - if( animationClock == null ) - return; - - var controller = animationClock.Controller; - Debug.Assert( controller != null ); - - controller.Stop(); - controller.Remove(); - - animationClock = null; - } - - private void ClearSplitterAnimationClock() - { - if( m_splitterAnimationClock == null ) - return; - - m_splitterAnimationClock.Completed -= new EventHandler( this.OnRollbackSplitterPositionCompleted ); - - this.ClearAnimationClock( ref m_splitterAnimationClock ); - } - - private void ClearColumnAnimations() - { - foreach( var column in m_dataGridContext.Columns ) - { - ColumnReorderingDragSourceManager.ClearAnimatedColumnReorderingTranslation( column ); - } - - m_animationClocks.Clear(); - } - - private void ClearSplitterAnimation() - { - this.ClearSplitterAnimationClock(); - - ColumnReorderingDragSourceManager.ClearTranslateTransformAnimation( TableflowView.GetFixedColumnSplitterTranslation( m_dataGridContext ) ); - } - - private void ApplyContainerClip( DraggedElementAdorner adorner ) - { - if( adorner == null ) - return; - - var adornedElement = adorner.AdornedElement; - if( adornedElement == null ) - return; - - // We only want to clip Cells other than the dragged Cell - if( adornedElement == this.DraggedElement ) - return; - - var dataGridContext = DataGridControl.GetDataGridContext( adornedElement ); - if( dataGridContext == null ) - return; - - var dataItemStore = CustomItemContainerGenerator.GetDataItemProperty( adornedElement ); - if( ( dataItemStore == null ) || dataItemStore.IsEmpty ) - return; - - var dataItem = dataItemStore.Data; - if( dataItem == null ) - return; - - var container = dataGridContext.GetContainerFromItem( dataItem ) as UIElement; - if( container != null ) - { - var containerClip = container.Clip as RectangleGeometry; - if( containerClip != null ) - { - // Transform the bounds of the clip region of the container to fit the bounds of the adornedElement - var transformedBounds = container.TransformToDescendant( adornedElement ).TransformBounds( containerClip.Bounds ); - - containerClip = new RectangleGeometry( transformedBounds ); - } - - adorner.AdornedElementImage.Clip = containerClip; - } - else - { - //This is an item that is in the FixedHeaders/Footers of the gird, do not clip it. - adorner.AdornedElementImage.Clip = null; - } - } - - private void ShowDraggedColumnGhosts() - { - foreach( var adorner in this.GetElementAdorners() ) - { - this.ApplyContainerClip( adorner ); - adorner.AdornedElementImage.Opacity = 1d; - } - } - - private void HideDraggedColumnGhosts() - { - foreach( var adorner in this.GetElementAdorners() ) - { - adorner.AdornedElementImage.Opacity = 0d; - } - } - - private void ShowDraggedElements() - { - this.PauseDraggedElementFadeInAnimation(); - - foreach( var element in this.GetElements() ) - { - element.Opacity = 1d; - } - } - - private void HideDraggedElements() - { - this.PauseDraggedElementFadeInAnimation(); - - foreach( var element in this.GetElements() ) - { - element.Opacity = 0d; - } - } - - private void ApplyDraggedElementFadeInAnimation() - { - var remainingOpacityDuration = s_draggedElementFadeInDuration; - - if( m_draggedElementFadeInAnimationClock != null ) - { - var fadeInAnimation = m_draggedElementFadeInAnimationClock.Timeline as OffsetAnimation; - - if( ( fadeInAnimation != null ) && ( fadeInAnimation.To == 1d ) ) - return; - - if( m_draggedElementFadeInAnimationClock.CurrentState == ClockState.Active ) - { - // The remaining duration is the Timeline Duration less the elapsed time - remainingOpacityDuration = new Duration( fadeInAnimation.Duration.TimeSpan - m_draggedElementFadeInAnimationClock.CurrentTime.Value ); - } - } - - this.PauseDraggedElementFadeInAnimation(); - - var draggedElement = this.DraggedElement; - - // Apply an animation on the opacity of the Cell to ensure a nice transition between the ColumnReordering and another IDropTarget that is not handled by this manager - if( draggedElement != null ) - { - var opacityAnimation = new OffsetAnimation( 1d, remainingOpacityDuration ); - - m_draggedElementFadeInAnimationClock = opacityAnimation.CreateClock( true ) as AnimationClock; - - // We ust the same completed callback as MoveGhostToTarget animation to be sure that the DraggedElement - // FadeIn is completed and the ghosts are correctly positioned before displaying the original UIElements - m_draggedElementFadeInAnimationClock.Completed += new EventHandler( this.GhostToTargetAnimation_Completed ); - - draggedElement.ApplyAnimationClock( UIElement.OpacityProperty, m_draggedElementFadeInAnimationClock ); - - m_draggedElementFadeInAnimationClock.Controller.Begin(); - } - } - - private void PauseDraggedElementFadeInAnimation() - { - // Ensure to stop dragged element FadeIn in order to correctly display the DraggedElementGhost - var draggedElement = this.DraggedElement; - if( draggedElement != null ) - { - draggedElement.ApplyAnimationClock( UIElement.OpacityProperty, null ); - } - - if( m_draggedElementFadeInAnimationClock == null ) - return; - - // Stop the animation, do not simply pause it, so it resets correctly. - m_draggedElementFadeInAnimationClock.Controller.Stop(); - m_draggedElementFadeInAnimationClock.Completed -= new EventHandler( this.GhostToTargetAnimation_Completed ); - m_draggedElementFadeInAnimationClock = null; - } - - private void TakeColumnsLayoutSnapshot() - { - Debug.Assert( !m_dataGridContext.ColumnManager.IsUpdateDeferred ); - - m_columnsLayout.Clear(); - - var levelCount = 1; - - for( int i = 0; i < levelCount; i++ ) - { - m_columnsLayout.AddLevel( i ); - } - - var sourceLevelMarkers = this.GetTopLevelMarkers(); - Debug.Assert( sourceLevelMarkers != null ); - - var pivotLocation = m_columnsLayout.GetLevelMarkers( levelCount - 1 ).Splitter; - Debug.Assert( pivotLocation != null ); - - // Clone all column locations. - for( var currentLocation = sourceLevelMarkers.Start; currentLocation != null; currentLocation = currentLocation.GetNextSibling() ) - { - var cloneLocation = ColumnReorderingDragSourceManager.CloneLocation( m_columnsLayout, currentLocation, levelCount - 1 ); - if( cloneLocation == null ) - continue; - - Debug.Assert( cloneLocation.CanMoveAfter( pivotLocation ) ); - cloneLocation.MoveAfter( pivotLocation ); - - pivotLocation = cloneLocation; - } - - // Move the splitter to get an exact copy. - var sourcePivotLocation = sourceLevelMarkers.Splitter.GetPreviousSibling(); - Debug.Assert( sourcePivotLocation != null ); - - var levelMarkers = m_columnsLayout.GetLevelMarkers( levelCount - 1 ); - var splitterLocation = levelMarkers.Splitter; - - if( sourcePivotLocation.Type == LocationType.Column ) - { - pivotLocation = m_columnsLayout[ ( ( ColumnHierarchyManager.IColumnLocation )sourcePivotLocation ).Column ]; - } - else - { - Debug.Assert( sourcePivotLocation.Type == LocationType.Start ); - pivotLocation = levelMarkers.Start; - } - - Debug.Assert( splitterLocation != null ); - Debug.Assert( pivotLocation != null ); - - Debug.Assert( splitterLocation.CanMoveAfter( pivotLocation ) ); - splitterLocation.MoveAfter( pivotLocation ); - } - - private static ColumnHierarchyModel.ILocation CloneLocation( ColumnHierarchyModel columnsLayout, ColumnHierarchyManager.ILocation sourceLocation, int level ) - { - Debug.Assert( columnsLayout != null ); - Debug.Assert( sourceLocation != null ); - Debug.Assert( level >= 0 ); - - var parentLocation = default( ColumnHierarchyModel.ILocation ); - - if( sourceLocation.Type == LocationType.Column ) - { - var columnLocation = columnsLayout.Add( ( ( ColumnHierarchyManager.IColumnLocation )sourceLocation ).Column, level ); - if( columnLocation == null ) - throw new InvalidOperationException(); - - columnLocation.Status = AnimationType.Rollback; - - parentLocation = columnLocation; - } - else if( sourceLocation.Type == LocationType.Orphan ) - { - parentLocation = columnsLayout.GetLevelMarkers( level ).Orphan; - if( parentLocation == null ) - throw new InvalidOperationException(); - } - - if( parentLocation != null ) - { - var lastLocation = default( ColumnHierarchyModel.ILocation ); - var childLocation = sourceLocation.GetFirstChild(); - - while( childLocation != null ) - { - var cloneLocation = ColumnReorderingDragSourceManager.CloneLocation( columnsLayout, childLocation, level - 1 ); - if( cloneLocation != null ) - { - if( lastLocation != null ) - { - Debug.Assert( cloneLocation.CanMoveAfter( lastLocation ) ); - cloneLocation.MoveAfter( lastLocation ); - } - else - { - Debug.Assert( cloneLocation.CanMoveUnder( parentLocation ) ); - cloneLocation.MoveUnder( parentLocation ); - } - - lastLocation = cloneLocation; - } - - childLocation = childLocation.GetNextSibling(); - } - - if( parentLocation.Type == LocationType.Column ) - return parentLocation; - } - - return null; - } - - private ColumnBase GetCommonAncestor( ColumnHierarchyManager.IColumnLocation x, ColumnHierarchyModel.IColumnLocation y ) - { - Debug.Assert( x != null ); - Debug.Assert( y != null ); - - var ancestors = new HashSet(); - - for( var parentLocation = x.GetParent(); parentLocation != null; parentLocation = parentLocation.GetParent() ) - { - var columnLocation = parentLocation as ColumnHierarchyManager.IColumnLocation; - if( columnLocation == null ) - break; - - ancestors.Add( columnLocation.Column ); - } - - for( var parentLocation = y.GetParent(); parentLocation != null; parentLocation = parentLocation.GetParent() ) - { - var columnLocation = parentLocation as ColumnHierarchyModel.IColumnLocation; - if( columnLocation == null ) - break; - - var column = columnLocation.Column; - if( ancestors.Contains( column ) ) - return column; - } - - return null; - } - - private void AnimateColumn( ColumnHierarchyModel.IColumnLocation columnLocation, AnimationType animationType ) - { - Debug.Assert( columnLocation != null ); - columnLocation.Status = animationType; - } - - private void AnimateColumnDescendants( ColumnHierarchyModel.IColumnLocation columnLocation, AnimationType animationType ) - { - Debug.Assert( columnLocation != null ); - - foreach( var childLocation in this.GetColumnLocations( this.GetChildLocationsOf( columnLocation ) ) ) - { - this.AnimateColumn( childLocation, animationType ); - this.AnimateColumnDescendants( childLocation, animationType ); - } - } - - private void AnimateColumnAncestors( ColumnHierarchyModel.IColumnLocation columnLocation, AnimationType animationType ) - { - Debug.Assert( columnLocation != null ); - - var parentColumnLocation = columnLocation.GetParent() as ColumnHierarchyModel.IColumnLocation; - while( parentColumnLocation != null ) - { - this.AnimateColumn( parentColumnLocation, animationType ); - - parentColumnLocation = parentColumnLocation.GetParent() as ColumnHierarchyModel.IColumnLocation; - } - } - - private IEnumerable GetElements() - { - return this.GetElementAdornerEntries().Select( item => item.Key ); - } - - private IEnumerable GetElementAdorners() - { - return this.GetElementAdornerEntries().Select( item => item.Value ); - } - - private IEnumerable> GetElementAdornerEntries() - { - var entries = m_elementToDraggedElementAdorner.ToList(); - - foreach( var entry in entries ) - { - var container = entry.Key; - - if( this.OwnElement( container ) ) - { - Debug.Assert( m_elementToDraggedElementAdorner.ContainsKey( container ) ); - - yield return entry; - } - else - { - this.RemoveDraggedColumnGhost( container ); - } - } - } - - private bool OwnElement( DependencyObject target ) - { - if( target == null ) - return false; - - ColumnReorderingDragSourceManager manager; - - var cell = target as Cell; - if( cell != null ) - { - manager = cell.ParentColumnReorderingDragSourceManager; - } - else - { - manager = TableflowView.GetColumnReorderingDragSourceManager( target ); - } - - return ( this == manager ); - } - - private readonly int m_level; - private readonly DataGridContext m_dataGridContext; - private readonly TranslateTransform m_splitterTranslation; - private readonly TableViewColumnVirtualizationManagerBase m_columnVirtualizationManager; - private readonly ColumnHierarchyModel m_columnsLayout = new ColumnHierarchyModel(); - private readonly Dictionary m_animationClocks = new Dictionary(); - private readonly Dictionary m_elementToDraggedElementAdorner = new Dictionary(); - - private bool m_isDragStarted; //false - private bool m_reorderCancelled; //false; - private bool m_noColumnsReorderingNeeded; //false - - private AnimationClock m_draggedElementFadeInAnimationClock; //null - private AnimationClock m_ghostToTargetAndDetachAnimationClock; //null; - private AnimationClock m_ghostToTargetColumnAnimationClock; //null; - private AnimationClock m_ghostToMousePositionAnimationClock; //null; - private AnimationClock m_splitterAnimationClock; //null; - - private DraggedElementAdorner m_popupDraggedElementAdorner; //null - private HorizontalMouseDragDirection m_horizontalMouseDragDirection = HorizontalMouseDragDirection.None; - private double m_lastDraggedElementOffset; // 0d; - - #region HorizontalMouseDragDirection Private Enum - - private enum HorizontalMouseDragDirection - { - None, - Left, - Right - } - - #endregion - - #region AnimationType Private Enum - - private enum AnimationType - { - Rollback = 0, - MoveLeft, - MoveRight, - IncreaseWidth, - DecreaseWidth, - MoveLeftAndIncreaseWidth, - MoveRightAndDecreaseWidth, - } - - #endregion - - #region ColumnAnimationClocks Private Struct - - private struct ColumnAnimationClocks - { - internal ColumnAnimationClocks( AnimationClock position, AnimationClock size ) - { - m_position = position; - m_size = size; - } - - internal AnimationClock Position - { - get - { - return m_position; - } - } - - internal AnimationClock Size - { - get - { - return m_size; - } - } - - private readonly AnimationClock m_position; - private readonly AnimationClock m_size; - } - - #endregion - - #region ColumnHierarchyModel Private Class - - private sealed class ColumnHierarchyModel : ColumnHierarchyModel - { - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/IAnimatedScrollInfo.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/IAnimatedScrollInfo.cs deleted file mode 100644 index 513dd5ec..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/IAnimatedScrollInfo.cs +++ /dev/null @@ -1,70 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows.Controls.Primitives; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal interface IAnimatedScrollInfo : IScrollInfo - { - #region Horizontal Offset Properties - - ScrollDirection HorizontalScrollingDirection - { - get; - set; - } - - double OriginalHorizontalOffset - { - get; - set; - } - - double TargetHorizontalOffset - { - get; - set; - } - - #endregion Horizontal Offset Properties - - #region Vertical Offset Properties - - ScrollDirection VerticalScrollingDirection - { - get; - set; - } - - double OriginalVerticalOffset - { - get; - set; - } - double TargetVerticalOffset - { - get; - set; - } - - #endregion Vertical Offset Properties - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/LayoutedContainerInfo.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/LayoutedContainerInfo.cs deleted file mode 100644 index 3225c616..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/LayoutedContainerInfo.cs +++ /dev/null @@ -1,72 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal class LayoutedContainerInfo : IComparable - { - #region CONSTRUCTORS - - public LayoutedContainerInfo( int realizedIndex, UIElement container ) - { - if( container == null ) - throw new ArgumentNullException( "container" ); - - this.RealizedIndex = realizedIndex; - this.Container = container; - } - - #endregion CONSTRUCTORS - - #region RealizedIndex Property - - public int RealizedIndex - { - get; - private set; - } - - #endregion RealizedIndex Property - - #region Container Property - - public UIElement Container - { - get; - private set; - } - - #endregion Container Property - - #region IComparable Members - - public int CompareTo( LayoutedContainerInfo other ) - { - if( other == null ) - return -1; - - return this.RealizedIndex.CompareTo( other.RealizedIndex ); - } - - #endregion IComparable Members - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/LayoutedContainerInfoList.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/LayoutedContainerInfoList.cs deleted file mode 100644 index adb1be73..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/LayoutedContainerInfoList.cs +++ /dev/null @@ -1,76 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal class LayoutedContainerInfoList : List - { - public bool ContainsContainer( UIElement container ) - { - return ( this.IndexOfContainer( container ) > -1 ); - } - - public int IndexOfContainer( UIElement container ) - { - int count = this.Count; - - for( int i = 0; i < count; i++ ) - { - if( this[ i ].Container == container ) - return i; - } - - return -1; - } - - public bool ContainsRealizedIndex( int realizedIndex ) - { - return ( this.IndexOfRealizedIndex( realizedIndex ) > -1 ); - } - - public int IndexOfRealizedIndex( int realizedIndex ) - { - int count = this.Count; - - for( int i = 0; i < count; i++ ) - { - if( this[ i ].RealizedIndex == realizedIndex ) - return i; - } - - return -1; - } - - public LayoutedContainerInfo this[ UIElement container ] - { - get - { - int index = this.IndexOfContainer( container ); - - if( index == -1 ) - return null; - - return this[ index ]; - } - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/OffsetAnimation.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/OffsetAnimation.cs deleted file mode 100644 index 0ba394ae..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/OffsetAnimation.cs +++ /dev/null @@ -1,155 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows.Media.Animation; -using System.Windows; -using Xceed.Utils.Math; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal class OffsetAnimation : DoubleAnimationBase - { - #region CONSTRUCTORS - - public OffsetAnimation() - : base() - { - } - - public OffsetAnimation( double toValue, Duration duration ) - : this() - { - this.To = toValue; - this.Duration = duration; - } - - public OffsetAnimation( double fromValue, double toValue, Duration duration ) - : this( toValue, duration ) - { - this.From = fromValue; - } - - #endregion CONSTRUCTORS - - #region From Property - - public static readonly DependencyProperty FromProperty = DependencyProperty.Register( - "From", - typeof( Nullable ), - typeof( OffsetAnimation ) ); - - public Nullable From - { - get - { - return ( Nullable )this.GetValue( OffsetAnimation.FromProperty ); - } - set - { - this.SetValue( OffsetAnimation.FromProperty, value ); - } - } - - #endregion From Property - - #region To Property - - public static readonly DependencyProperty ToProperty = DependencyProperty.Register( - "To", - typeof( Nullable ), - typeof( OffsetAnimation ) ); - - public Nullable To - { - get - { - return ( Nullable )this.GetValue( OffsetAnimation.ToProperty ); - } - set - { - this.SetValue( OffsetAnimation.ToProperty, value ); - } - } - - #endregion To Property - - #region IsDestinationDefault Property - - public override bool IsDestinationDefault - { - get - { - return false; - } - } - - #endregion IsDestinationDefault Property - - #region DoubleAnimationBase Overrides - - protected override double GetCurrentValueCore( double defaultOriginValue, double defaultDestinationValue, AnimationClock animationClock ) - { - Nullable to = this.To; - Nullable from = this.From; - - if( !from.HasValue ) - { - from = defaultOriginValue; - } - - if( !to.HasValue ) - { - to = defaultDestinationValue; - } - - double toValue = to.GetValueOrDefault(); - double fromValue = from.GetValueOrDefault(); - - if( ( !animationClock.CurrentProgress.HasValue ) - || ( animationClock.CurrentProgress.Value == 1 ) ) - { - return toValue; - } - - if( animationClock.CurrentProgress.Value == 0 ) - return fromValue; - - double totalTime = animationClock.Timeline.Duration.TimeSpan.TotalMilliseconds; - double elapsedTime = totalTime * animationClock.CurrentProgress.Value; - - if( elapsedTime >= totalTime ) - return toValue; - - double animationStep = TableflowViewAnimationHelper.GetAnimationStep( fromValue, toValue, elapsedTime, totalTime ); - - if( DoubleUtil.AreClose( animationStep, toValue ) ) - return toValue; - - return animationStep; - } - - protected override Freezable CreateInstanceCore() - { - return new OffsetAnimation(); - } - - #endregion DoubleAnimationBase Overrides - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/PointAnimation.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/PointAnimation.cs deleted file mode 100644 index 406399ea..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/PointAnimation.cs +++ /dev/null @@ -1,167 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows.Media.Animation; -using System.Windows; -using Xceed.Utils.Math; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal class PointAnimation : PointAnimationBase - { - #region CONSTRUCTORS - - public PointAnimation() - : base() - { - } - - public PointAnimation( Point toValue, Duration duration ) - : this() - { - this.To = toValue; - this.Duration = duration; - } - - public PointAnimation( Point fromValue, Point toValue, Duration duration ) - : this( toValue, duration ) - { - this.From = fromValue; - } - - #endregion CONSTRUCTORS - - #region From Property - - public static readonly DependencyProperty FromProperty = DependencyProperty.Register( - "From", - typeof( Nullable ), - typeof( PointAnimation ) ); - - public Nullable From - { - get - { - return ( Nullable )this.GetValue( PointAnimation.FromProperty ); - } - set - { - this.SetValue( PointAnimation.FromProperty, value ); - } - } - - #endregion From Property - - #region To Property - - public static readonly DependencyProperty ToProperty = DependencyProperty.Register( - "To", - typeof( Nullable ), - typeof( PointAnimation ) ); - - public Nullable To - { - get - { - return ( Nullable )this.GetValue( PointAnimation.ToProperty ); - } - set - { - this.SetValue( PointAnimation.ToProperty, value ); - } - } - - #endregion To Property - - #region IsDestinationDefault Property - - public override bool IsDestinationDefault - { - get - { - return false; - } - } - - #endregion IsDestinationDefault Property - - #region DoubleAnimationBase Overrides - - protected override Point GetCurrentValueCore( Point defaultOriginValue, Point defaultDestinationValue, AnimationClock animationClock ) - { - Nullable to = this.To; - Nullable from = this.From; - - if( !from.HasValue ) - { - from = defaultOriginValue; - } - - if( !to.HasValue ) - { - to = defaultDestinationValue; - } - - Point toValue = to.GetValueOrDefault(); - Point fromValue = from.GetValueOrDefault(); - - if( ( !animationClock.CurrentProgress.HasValue ) - || ( animationClock.CurrentProgress.Value == 1 ) ) - { - return toValue; - } - - if( animationClock.CurrentProgress.Value == 0 ) - return fromValue; - - double totalTime = animationClock.Timeline.Duration.TimeSpan.TotalMilliseconds; - double elapsedTime = totalTime * animationClock.CurrentProgress.Value; - - if( elapsedTime >= totalTime ) - return toValue; - - Point animationStep = this.GetAnimationStep( fromValue, toValue, elapsedTime, totalTime ); - - if( DoubleUtil.AreClose( animationStep.X, toValue.X ) && DoubleUtil.AreClose( animationStep.Y, toValue.Y ) ) - return toValue; - - return animationStep; - } - - protected override Freezable CreateInstanceCore() - { - return new PointAnimation(); - } - - #endregion DoubleAnimationBase Overrides - - #region PRIVATE METHODS - - private Point GetAnimationStep( Point startPos, Point finalPos, double elapsedTime, double totalTime ) - { - double x = TableflowViewAnimationHelper.GetAnimationStep( startPos.X, finalPos.X, elapsedTime, totalTime ); - double y = TableflowViewAnimationHelper.GetAnimationStep( startPos.Y, finalPos.Y, elapsedTime, totalTime ); - - return new Point( x, y ); - } - - #endregion PRIVATE METHODS - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/StickyContainerInfo.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/StickyContainerInfo.cs deleted file mode 100644 index 9bad2475..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/StickyContainerInfo.cs +++ /dev/null @@ -1,71 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal class StickyContainerInfo - { - #region CONSTRUCTORS - - public StickyContainerInfo( UIElement container, int containerIndex, int holdingContainerIndex ) - { - if( container == null ) - throw new ArgumentNullException( "container" ); - - this.Container = container; - this.ContainerIndex = containerIndex; - this.HoldingContainerIndex = holdingContainerIndex; - } - - #endregion CONSTRUCTORS - - #region Container Property - - public UIElement Container - { - get; - private set; - } - - #endregion Container Property - - #region ContainerIndex Property - - public int ContainerIndex - { - get; - private set; - } - - #endregion ContainerIndex Property - - #region HoldingContainerIndex Property - - public int HoldingContainerIndex - { - get; - private set; - } - - #endregion HoldingContainerIndex Property - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/StickyContainerInfoComparer.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/StickyContainerInfoComparer.cs deleted file mode 100644 index 3e893f3f..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/StickyContainerInfoComparer.cs +++ /dev/null @@ -1,52 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal class StickyContainerInfoComparer : IComparer - { - #region Singleton Property - - public static StickyContainerInfoComparer Singleton - { - get - { - if( _singleton == null ) - _singleton = new StickyContainerInfoComparer(); - - return _singleton; - } - } - - private static StickyContainerInfoComparer _singleton; - - #endregion Singleton Property - - #region IComparer Members - - public int Compare( StickyContainerInfo x, StickyContainerInfo y ) - { - return x.ContainerIndex.CompareTo( y.ContainerIndex ); - } - - #endregion IComparer Members - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/StickyContainerInfoList.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/StickyContainerInfoList.cs deleted file mode 100644 index 666da526..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/StickyContainerInfoList.cs +++ /dev/null @@ -1,63 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal class StickyContainerInfoList : List - { - public bool ContainsContainer( UIElement container ) - { - return ( this.IndexOfContainer( container ) > -1 ); - } - - public int IndexOfContainer( UIElement container ) - { - int count = this.Count; - - for( int i = 0; i < count; i++ ) - { - if( this[ i ].Container == container ) - return i; - } - - return -1; - } - - public bool ContainsRealizedIndex( int realizedIndex ) - { - return ( this.IndexOfRealizedIndex( realizedIndex ) > -1 ); - } - - public int IndexOfRealizedIndex( int realizedIndex ) - { - int count = this.Count; - - for( int i = 0; i < count; i++ ) - { - if( this[ i ].ContainerIndex == realizedIndex ) - return i; - } - - return -1; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/StickyContainerInfoReverseComparer.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/StickyContainerInfoReverseComparer.cs deleted file mode 100644 index 8e08735b..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/StickyContainerInfoReverseComparer.cs +++ /dev/null @@ -1,52 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal class StickyContainerInfoReverseComparer : IComparer - { - #region Singleton Property - - public static StickyContainerInfoReverseComparer Singleton - { - get - { - if( _singleton == null ) - _singleton = new StickyContainerInfoReverseComparer(); - - return _singleton; - } - } - - private static StickyContainerInfoReverseComparer _singleton; - - #endregion Singleton Property - - #region IComparer Members - - public int Compare( StickyContainerInfo x, StickyContainerInfo y ) - { - return y.ContainerIndex.CompareTo( x.ContainerIndex ); - } - - #endregion IComparer Members - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/TableflowView.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/TableflowView.cs deleted file mode 100644 index 56b92276..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/TableflowView.cs +++ /dev/null @@ -1,505 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.ComponentModel; -using System.Windows; -using System.Windows.Media; - -namespace Xceed.Wpf.DataGrid.Views -{ - public class TableflowView : TableView - { - #region Constructors - - static TableflowView() - { - FrameworkContentElement.DefaultStyleKeyProperty.OverrideMetadata( - typeof( TableflowView ), - new FrameworkPropertyMetadata( TableflowView.GetDefaultStyleKey( typeof( TableflowView ), null ) ) ); - - TableView.IsAlternatingRowStyleEnabledProperty.OverrideMetadata( - typeof( TableflowView ), - new FrameworkPropertyMetadata( true ) ); - - TableView.AllowRowResizeProperty.OverrideMetadata( - typeof( TableflowView ), - new FrameworkPropertyMetadata( false ) ); - - TableflowView.AreGroupsFlattenedProperty.OverrideMetadata( - typeof( TableflowView ), - new FrameworkPropertyMetadata( true ) ); - - TableflowView.IsDeferredLoadingEnabledProperty.OverrideMetadata( - typeof( TableflowView ), - new FrameworkPropertyMetadata( true ) ); - } - - public TableflowView() - : base() - { - // No need to preserve container size since it is - // forced via ContainerHeight property - this.PreserveContainerSize = false; - } - - #endregion - - #region RowFadeInAnimationDuration Attached Property - - [ViewProperty( ViewPropertyMode.ViewOnly )] - public static readonly DependencyProperty RowFadeInAnimationDurationProperty = DependencyProperty.RegisterAttached( - "RowFadeInAnimationDuration", - typeof( double ), - typeof( TableflowView ), - new FrameworkPropertyMetadata( 300d ) ); - - public double RowFadeInAnimationDuration - { - get - { - return TableflowView.GetRowFadeInAnimationDuration( this ); - } - set - { - TableflowView.SetRowFadeInAnimationDuration( this, value ); - } - } - - public static double GetRowFadeInAnimationDuration( DependencyObject obj ) - { - return ( double )obj.GetValue( TableflowView.RowFadeInAnimationDurationProperty ); - } - - public static void SetRowFadeInAnimationDuration( DependencyObject obj, double value ) - { - obj.SetValue( TableflowView.RowFadeInAnimationDurationProperty, value ); - } - - #endregion RowFadeInAnimationDuration Property - - #region IsAnimatedColumnReorderingEnabled Property - - public static readonly DependencyProperty IsAnimatedColumnReorderingEnabledProperty = DependencyProperty.Register( - "IsAnimatedColumnReorderingEnabled", - typeof( bool ), - typeof( TableflowView ), - new FrameworkPropertyMetadata( true ) ); - - public bool IsAnimatedColumnReorderingEnabled - { - get - { - return ( bool )this.GetValue( TableflowView.IsAnimatedColumnReorderingEnabledProperty ); - } - set - { - this.SetValue( TableflowView.IsAnimatedColumnReorderingEnabledProperty, value ); - } - } - - #endregion RowFadeInAnimationDuration Attached Property - - #region ColumnReorderingDragSourceManager Attached Property - - [ViewProperty( ViewPropertyMode.RoutedNoFallback )] - internal static readonly DependencyProperty ColumnReorderingDragSourceManagerProperty = DependencyProperty.RegisterAttached( - "ColumnReorderingDragSourceManager", - typeof( ColumnReorderingDragSourceManager ), - typeof( TableflowView ), - new FrameworkPropertyMetadata( null ) ); - - internal static ColumnReorderingDragSourceManager GetColumnReorderingDragSourceManager( DependencyObject obj ) - { - return ( ColumnReorderingDragSourceManager )obj.GetValue( TableflowView.ColumnReorderingDragSourceManagerProperty ); - } - - internal static void SetColumnReorderingDragSourceManager( DependencyObject obj, ColumnReorderingDragSourceManager value ) - { - obj.SetValue( TableflowView.ColumnReorderingDragSourceManagerProperty, value ); - } - - internal static void ClearColumnReorderingDragSourceManager( DependencyObject obj ) - { - obj.ClearValue( TableflowView.ColumnReorderingDragSourceManagerProperty ); - } - - #endregion - - #region AreColumnsBeingReordered Attached Property - - [ViewProperty( ViewPropertyMode.RoutedNoFallback, FlattenDetailBindingMode.MasterOneWay )] - public static readonly DependencyProperty AreColumnsBeingReorderedProperty = DependencyProperty.RegisterAttached( - "AreColumnsBeingReordered", - typeof( bool ), - typeof( TableflowView ), - new FrameworkPropertyMetadata( ( bool )false ) ); - - - public static bool GetAreColumnsBeingReordered( DependencyObject obj ) - { - return ( bool )obj.GetValue( TableflowView.AreColumnsBeingReorderedProperty ); - } - - [EditorBrowsable( EditorBrowsableState.Never )] - public static void SetAreColumnsBeingReordered( DependencyObject obj, bool value ) - { - obj.SetValue( TableflowView.AreColumnsBeingReorderedProperty, value ); - } - - #endregion - - #region IsBeingDraggedAnimated Attached Property - - internal static readonly DependencyProperty IsBeingDraggedAnimatedProperty = DependencyProperty.RegisterAttached( - "IsBeingDraggedAnimated", - typeof( bool ), - typeof( TableflowView ), - new FrameworkPropertyMetadata( ( bool )false ) ); - - internal static bool GetIsBeingDraggedAnimated( DependencyObject obj ) - { - return ( bool )obj.GetValue( TableflowView.IsBeingDraggedAnimatedProperty ); - } - - internal static void SetIsBeingDraggedAnimated( DependencyObject obj, bool value ) - { - obj.SetValue( TableflowView.IsBeingDraggedAnimatedProperty, value ); - } - - internal static void ClearIsBeingDraggedAnimated( DependencyObject obj ) - { - obj.ClearValue( TableflowView.IsBeingDraggedAnimatedProperty ); - } - - #endregion - - #region ContainerHeight Attached Property - - [ViewProperty( ViewPropertyMode.ViewOnly )] - public static readonly DependencyProperty ContainerHeightProperty = DependencyProperty.RegisterAttached( - "ContainerHeight", - typeof( double ), - typeof( TableflowView ), - new FrameworkPropertyMetadata( 26d ) ); - - public double ContainerHeight - { - get - { - return TableflowView.GetContainerHeight( this ); - } - set - { - TableflowView.SetContainerHeight( this, value ); - } - } - - public static double GetContainerHeight( DependencyObject obj ) - { - return ( double )obj.GetValue( TableflowView.ContainerHeightProperty ); - } - - public static void SetContainerHeight( DependencyObject obj, double value ) - { - obj.SetValue( TableflowView.ContainerHeightProperty, value ); - } - - #endregion ContainerHeight Attached Property - - #region FixedColumnSplitterTranslation Attached Property - - [ViewProperty( ViewPropertyMode.RoutedNoFallback, FlattenDetailBindingMode.MasterOneWay )] - internal static readonly DependencyProperty FixedColumnSplitterTranslationProperty = DependencyProperty.RegisterAttached( - "FixedColumnSplitterTranslation", - typeof( TranslateTransform ), - typeof( TableflowView ), - new FrameworkPropertyMetadata( null ) ); - - internal static TranslateTransform GetFixedColumnSplitterTranslation( DependencyObject obj ) - { - return ( TranslateTransform )obj.GetValue( TableflowView.FixedColumnSplitterTranslationProperty ); - } - - internal static void SetFixedColumnSplitterTranslation( DependencyObject obj, TranslateTransform value ) - { - obj.SetValue( TableflowView.FixedColumnSplitterTranslationProperty, value ); - } - - #endregion - - #region ScrollingAnimationDuration Property - - [ViewProperty( ViewPropertyMode.ViewOnly )] - public static readonly DependencyProperty ScrollingAnimationDurationProperty = DependencyProperty.RegisterAttached( - "ScrollingAnimationDuration", - typeof( double ), - typeof( TableflowView ), - new FrameworkPropertyMetadata( 750d ) ); - - public double ScrollingAnimationDuration - { - get - { - return TableflowView.GetScrollingAnimationDuration( this ); - } - set - { - TableflowView.SetScrollingAnimationDuration( this, value ); - } - } - - public static double GetScrollingAnimationDuration( DependencyObject obj ) - { - return ( double )obj.GetValue( TableflowView.ScrollingAnimationDurationProperty ); - } - - public static void SetScrollingAnimationDuration( DependencyObject obj, double value ) - { - obj.SetValue( TableflowView.ScrollingAnimationDurationProperty, value ); - } - - #endregion ScrollingAnimationDuration Property - - #region AreHeadersSticky Attached Property - - [ViewProperty( ViewPropertyMode.ViewOnly )] - public static readonly DependencyProperty AreHeadersStickyProperty = DependencyProperty.RegisterAttached( - "AreHeadersSticky", - typeof( bool ), - typeof( TableflowView ), - new FrameworkPropertyMetadata( true ) ); - - public bool AreHeadersSticky - { - get - { - return TableflowView.GetAreHeadersSticky( this ); - } - set - { - TableflowView.SetAreHeadersSticky( this, value ); - } - } - - public static bool GetAreHeadersSticky( DependencyObject obj ) - { - return ( bool )obj.GetValue( TableflowView.AreHeadersStickyProperty ); - } - - public static void SetAreHeadersSticky( DependencyObject obj, bool value ) - { - obj.SetValue( TableflowView.AreHeadersStickyProperty, value ); - } - - #endregion AreHeadersSticky Attached Property - - #region AreFootersSticky Attached Property - - [ViewProperty( ViewPropertyMode.ViewOnly )] - public static readonly DependencyProperty AreFootersStickyProperty = DependencyProperty.RegisterAttached( - "AreFootersSticky", - typeof( bool ), - typeof( TableflowView ), - new FrameworkPropertyMetadata( true ) ); - - public bool AreFootersSticky - { - get - { - return TableflowView.GetAreFootersSticky( this ); - } - set - { - TableflowView.SetAreFootersSticky( this, value ); - } - } - - public static bool GetAreFootersSticky( DependencyObject obj ) - { - return ( bool )obj.GetValue( TableflowView.AreFootersStickyProperty ); - } - - public static void SetAreFootersSticky( DependencyObject obj, bool value ) - { - obj.SetValue( TableflowView.AreFootersStickyProperty, value ); - } - - #endregion AreFootersSticky Attached Property - - #region AreGroupHeadersSticky Attached Property - - [ViewProperty( ViewPropertyMode.ViewOnly )] - public static readonly DependencyProperty AreGroupHeadersStickyProperty = DependencyProperty.RegisterAttached( - "AreGroupHeadersSticky", - typeof( bool ), - typeof( TableflowView ), - new FrameworkPropertyMetadata( true ) ); - - public bool AreGroupHeadersSticky - { - get - { - return TableflowView.GetAreGroupHeadersSticky( this ); - } - set - { - TableflowView.SetAreGroupHeadersSticky( this, value ); - } - } - - public static bool GetAreGroupHeadersSticky( DependencyObject obj ) - { - return ( bool )obj.GetValue( TableflowView.AreGroupHeadersStickyProperty ); - } - - public static void SetAreGroupHeadersSticky( DependencyObject obj, bool value ) - { - obj.SetValue( TableflowView.AreGroupHeadersStickyProperty, value ); - } - - #endregion AreGroupHeadersSticky Attached Property - - #region AreGroupFootersSticky Attached Property - - [ViewProperty( ViewPropertyMode.ViewOnly )] - public static readonly DependencyProperty AreGroupFootersStickyProperty = DependencyProperty.RegisterAttached( - "AreGroupFootersSticky", - typeof( bool ), - typeof( TableflowView ), - new FrameworkPropertyMetadata( true ) ); - - public bool AreGroupFootersSticky - { - get - { - return TableflowView.GetAreGroupFootersSticky( this ); - } - set - { - TableflowView.SetAreGroupFootersSticky( this, value ); - } - } - - public static bool GetAreGroupFootersSticky( DependencyObject obj ) - { - return ( bool )obj.GetValue( TableflowView.AreGroupFootersStickyProperty ); - } - - public static void SetAreGroupFootersSticky( DependencyObject obj, bool value ) - { - obj.SetValue( TableflowView.AreGroupFootersStickyProperty, value ); - } - - #endregion AreGroupFootersSticky Attached Property - - #region AreParentRowsSticky Attached Property - - [ViewProperty( ViewPropertyMode.ViewOnly )] - public static readonly DependencyProperty AreParentRowsStickyProperty = DependencyProperty.RegisterAttached( - "AreParentRowsSticky", - typeof( bool ), - typeof( TableflowView ), - new FrameworkPropertyMetadata( true ) ); - - public bool AreParentRowsSticky - { - get - { - return TableflowView.GetAreParentRowsSticky( this ); - } - set - { - TableflowView.SetAreParentRowsSticky( this, value ); - } - } - - public static bool GetAreParentRowsSticky( DependencyObject obj ) - { - return ( bool )obj.GetValue( TableflowView.AreParentRowsStickyProperty ); - } - - public static void SetAreParentRowsSticky( DependencyObject obj, bool value ) - { - obj.SetValue( TableflowView.AreParentRowsStickyProperty, value ); - } - - #endregion AreParentRowsSticky Attached Property - - #region AreGroupsFlattened Attached Property - - [ViewProperty( ViewPropertyMode.ViewOnly )] - public static readonly DependencyProperty AreGroupsFlattenedProperty = DependencyProperty.RegisterAttached( - "AreGroupsFlattened", - typeof( bool ), - typeof( TableflowView ) ); - - public bool AreGroupsFlattened - { - get - { - return TableflowView.GetAreGroupsFlattened( this ); - } - set - { - TableflowView.SetAreGroupsFlattened( this, value ); - } - } - - public static bool GetAreGroupsFlattened( DependencyObject obj ) - { - return ( bool )obj.GetValue( TableflowView.AreGroupsFlattenedProperty ); - } - - public static void SetAreGroupsFlattened( DependencyObject obj, bool value ) - { - obj.SetValue( TableflowView.AreGroupsFlattenedProperty, value ); - } - - #endregion AreGroupsFlattened Attached Property - - #region IsDeferredLoadingEnabled Attached Property - - [ViewProperty( ViewPropertyMode.ViewOnly )] - public static readonly DependencyProperty IsDeferredLoadingEnabledProperty = DependencyProperty.RegisterAttached( - "IsDeferredLoadingEnabled", - typeof( bool ), - typeof( TableflowView ) ); - - public bool IsDeferredLoadingEnabled - { - get - { - return TableflowView.GetIsDeferredLoadingEnabled( this ); - } - set - { - TableflowView.SetIsDeferredLoadingEnabled( this, value ); - } - } - - public static bool GetIsDeferredLoadingEnabled( DependencyObject obj ) - { - return ( bool )obj.GetValue( TableflowView.IsDeferredLoadingEnabledProperty ); - } - - public static void SetIsDeferredLoadingEnabled( DependencyObject obj, bool value ) - { - obj.SetValue( TableflowView.IsDeferredLoadingEnabledProperty, value ); - } - - #endregion IsDeferredLoadingEnabled Attached Property - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/TableflowViewAnimationHelper.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/TableflowViewAnimationHelper.cs deleted file mode 100644 index aa68882f..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/TableflowViewAnimationHelper.cs +++ /dev/null @@ -1,39 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal class TableflowViewAnimationHelper - { - #region Public Methods - - public static double GetAnimationStep( double startPos, double finalPos, double elapsedTime, double totalTime ) - { - const double power = 6; - - return startPos + - ( ( 1 - Math.Pow( totalTime - elapsedTime, power ) / Math.Pow( totalTime, power ) ) * - ( finalPos - startPos ) ); - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/TableflowViewItemsHost.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/TableflowViewItemsHost.cs deleted file mode 100644 index ca7f7663..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/TableflowViewItemsHost.cs +++ /dev/null @@ -1,3645 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Diagnostics; -using System.Linq; -using System.Threading; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Controls.Primitives; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Animation; - -namespace Xceed.Wpf.DataGrid.Views -{ - public class TableflowViewItemsHost : DataGridItemsHost, IAnimatedScrollInfo, IDeferableScrollInfoRefresh - { - static TableflowViewItemsHost() - { - KeyboardNavigation.DirectionalNavigationProperty.OverrideMetadata( - typeof( TableflowViewItemsHost ), - new FrameworkPropertyMetadata( KeyboardNavigationMode.Local ) ); - - TableflowView.AreHeadersStickyProperty.OverrideMetadata( - typeof( DataGridContext ), - new FrameworkPropertyMetadata( new PropertyChangedCallback( TableflowViewItemsHost.OnViewPropertiesChanged ) ) ); - - TableflowView.AreFootersStickyProperty.OverrideMetadata( - typeof( DataGridContext ), - new FrameworkPropertyMetadata( new PropertyChangedCallback( TableflowViewItemsHost.OnViewPropertiesChanged ) ) ); - - TableflowView.AreGroupHeadersStickyProperty.OverrideMetadata( - typeof( DataGridContext ), - new FrameworkPropertyMetadata( new PropertyChangedCallback( TableflowViewItemsHost.OnViewPropertiesChanged ) ) ); - - TableflowView.AreGroupFootersStickyProperty.OverrideMetadata( - typeof( DataGridContext ), - new FrameworkPropertyMetadata( new PropertyChangedCallback( TableflowViewItemsHost.OnViewPropertiesChanged ) ) ); - - TableflowView.AreParentRowsStickyProperty.OverrideMetadata( - typeof( DataGridContext ), - new FrameworkPropertyMetadata( new PropertyChangedCallback( TableflowViewItemsHost.OnViewPropertiesChanged ) ) ); - - TableflowView.ContainerHeightProperty.OverrideMetadata( - typeof( DataGridContext ), - new FrameworkPropertyMetadata( new PropertyChangedCallback( TableflowViewItemsHost.OnViewPropertiesChanged ) ) ); - - TableflowView.AreGroupsFlattenedProperty.OverrideMetadata( - typeof( DataGridContext ), - new FrameworkPropertyMetadata( new PropertyChangedCallback( TableflowViewItemsHost.OnAreGroupsFlattenedChanged ) ) ); - - TableflowViewItemsHost.IsStickyProperty = TableflowViewItemsHost.IsStickyPropertyKey.DependencyProperty; - - CommandManager.RegisterClassCommandBinding( typeof( TableflowViewItemsHost ), - new CommandBinding( ComponentCommands.MoveFocusForward, - TableflowViewItemsHost.MoveFocusForwardExecuted, TableflowViewItemsHost.MoveFocusForwardCanExecute ) ); - - CommandManager.RegisterClassCommandBinding( typeof( TableflowViewItemsHost ), - new CommandBinding( ComponentCommands.MoveFocusBack, - TableflowViewItemsHost.MoveFocusBackExecuted, TableflowViewItemsHost.MoveFocusBackCanExecute ) ); - - CommandManager.RegisterClassCommandBinding( typeof( TableflowViewItemsHost ), - new CommandBinding( ComponentCommands.MoveFocusUp, - TableflowViewItemsHost.MoveFocusUpExecuted, TableflowViewItemsHost.MoveFocusUpCanExecute ) ); - - CommandManager.RegisterClassCommandBinding( typeof( TableflowViewItemsHost ), - new CommandBinding( ComponentCommands.MoveFocusDown, - TableflowViewItemsHost.MoveFocusDownExecuted, TableflowViewItemsHost.MoveFocusDownCanExecute ) ); - } - - public TableflowViewItemsHost() - { - this.AddHandler( FrameworkElement.RequestBringIntoViewEvent, new RequestBringIntoViewEventHandler( this.OnRequestBringIntoView ) ); - - this.CommandBindings.Add( new CommandBinding( - GroupNavigationButton.NavigateToGroup, this.OnNavigateToGroupExecuted, this.OnNavigateToGroupCanExecute ) ); - - this.InitializeHorizontalOffsetAnimation(); - this.InitializeVerticalOffsetAnimation(); - - this.Unloaded += new RoutedEventHandler( this.TableflowViewItemsHost_Unloaded ); - } - - private void TableflowViewItemsHost_Unloaded( object sender, RoutedEventArgs e ) - { - this.StopHorizontalOffsetAnimation(); - this.StopVerticalOffsetAnimation(); - } - - private static void OnAreGroupsFlattenedChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - DataGridContext dataGridContext = sender as DataGridContext; - - // This property is not intended to be update live in an application. - // We need to force a Reset on the CustomItemContainerGenerator to clear - // all containers in order to get the right indentation. - // Only reset when the change occurs on a the master DataGridContext - // since the property is a ViewOnly property. - if( ( dataGridContext != null ) && ( dataGridContext.ParentDataGridContext == null ) ) - { - CustomItemContainerGenerator customItemContainerGenerator = dataGridContext.CustomItemContainerGenerator; - - if( customItemContainerGenerator != null ) - { - dataGridContext.CustomItemContainerGenerator.ResetGeneratorContent(); - } - } - } - - private static void OnViewPropertiesChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - DataGridContext dataGridContext = sender as DataGridContext; - - if( ( dataGridContext == null ) - || ( dataGridContext.DataGridControl == null ) - || ( dataGridContext.DataGridControl.ItemsHost == null ) ) - { - return; - } - - // Nothing to do for detail DataGridContext. - if( dataGridContext.ParentDataGridContext == null ) - { - dataGridContext.DataGridControl.ItemsHost.InvalidateMeasure(); - } - } - -#if DEBUG - #region RealizedIndex Property - - public static readonly DependencyProperty RealizedIndexProperty = DependencyProperty.RegisterAttached( - "RealizedIndex", - typeof( int ), - typeof( TableflowViewItemsHost ) ); - - public int RealizedIndex - { - get - { - return TableflowViewItemsHost.GetRealizedIndex( this ); - } - set - { - TableflowViewItemsHost.SetRealizedIndex( this, value ); - } - } - - public static int GetRealizedIndex( DependencyObject obj ) - { - return ( int )obj.GetValue( TableflowViewItemsHost.RealizedIndexProperty ); - } - - public static void SetRealizedIndex( DependencyObject obj, int value ) - { - obj.SetValue( TableflowViewItemsHost.RealizedIndexProperty, value ); - } - - #endregion -#endif //DEBUG - - #region ShouldDelayDataContext Property (Internal Attached) - - internal static readonly DependencyProperty ShouldDelayDataContextProperty = DependencyProperty.RegisterAttached( - "ShouldDelayDataContext", - typeof( bool ), - typeof( TableflowViewItemsHost ) ); - - internal static bool GetShouldDelayDataContext( DependencyObject obj ) - { - return ( bool )obj.GetValue( TableflowViewItemsHost.ShouldDelayDataContextProperty ); - } - - internal static void SetShouldDelayDataContext( DependencyObject obj, bool value ) - { - obj.SetValue( TableflowViewItemsHost.ShouldDelayDataContextProperty, value ); - } - - #endregion - - #region NavigateToGroup Command - - private void OnNavigateToGroupCanExecute( object sender, CanExecuteRoutedEventArgs e ) - { - e.CanExecute = true; - e.Handled = true; - } - - private void OnNavigateToGroupExecuted( object sender, ExecutedRoutedEventArgs e ) - { - Group group = e.Parameter as Group; - - if( group != null ) - { - double offset; - double stickyHeadersRegionHeight; - int groupContainerIndex; - - if( this.GetGroupOffset( group, out offset, out stickyHeadersRegionHeight, out groupContainerIndex ) ) - { - this.ScrollToVerticalOffset( offset - stickyHeadersRegionHeight ); - e.Handled = true; - } - } - } - - private bool GetGroupOffset( Group group, out double offset, out double stickyHeadersRegionHeight, out int groupContainerIndex ) - { - groupContainerIndex = ( ( CustomItemContainerGenerator )this.CustomItemContainerGenerator ).GetGroupIndex( group ); - - if( groupContainerIndex > -1 ) - { - stickyHeadersRegionHeight = this.GetStickyHeaderCountForIndex( groupContainerIndex ) * m_containerHeight; - offset = this.GetContainerOffsetFromIndex( groupContainerIndex ); - - return true; - } - - offset = 0d; - stickyHeadersRegionHeight = 0d; - - return false; - } - - #endregion - - internal void OnGroupCollapsing( Group group ) - { - double groupOffset; - double stickyHeadersRegionHeight; - int groupContainerIndex; - - if( this.GetGroupOffset( group, out groupOffset, out stickyHeadersRegionHeight, out groupContainerIndex ) ) - { - if( m_stickyHeaders.ContainsRealizedIndex( groupContainerIndex ) - || m_stickyFooters.ContainsRealizedIndex( groupContainerIndex ) - || m_layoutedContainers.ContainsRealizedIndex( groupContainerIndex ) ) - { - double offset = groupOffset - stickyHeadersRegionHeight; - - if( ( offset < m_verticalOffset ) || ( offset >= m_verticalOffset + m_viewportHeight ) ) - { - this.PreventOpacityAnimation = true; - this.ScrollToVerticalOffset( offset, false, ScrollDirection.None ); - } - } - } - } - - #region AnimatedHorizontalOffset Property - - private static readonly DependencyProperty AnimatedHorizontalOffsetProperty = DependencyProperty.Register( - "AnimatedHorizontalOffset", - typeof( double ), - typeof( TableflowViewItemsHost ), - new FrameworkPropertyMetadata( new PropertyChangedCallback( TableflowViewItemsHost.OnAnimatedHorizontalOffsetChanged ) ) ); - - private double AnimatedHorizontalOffset - { - get - { - return ( double )this.GetValue( TableflowViewItemsHost.AnimatedHorizontalOffsetProperty ); - } - set - { - this.SetValue( TableflowViewItemsHost.AnimatedHorizontalOffsetProperty, value ); - } - } - - private static void OnAnimatedHorizontalOffsetChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - TableflowViewItemsHost host = ( TableflowViewItemsHost )sender; - - host.SetHorizontalOffsetCore( ( double )e.NewValue ); - host.InvalidateArrange(); - host.InvalidateScrollInfo(); - } - - #endregion - - #region AnimatedVerticalOffset Property - - private static readonly DependencyProperty AnimatedVerticalOffsetProperty = DependencyProperty.Register( - "AnimatedVerticalOffset", - typeof( double ), - typeof( TableflowViewItemsHost ), - new FrameworkPropertyMetadata( new PropertyChangedCallback( TableflowViewItemsHost.OnAnimatedVerticalOffsetChanged ) ) ); - - private double AnimatedVerticalOffset - { - get - { - return ( double )this.GetValue( TableflowViewItemsHost.AnimatedVerticalOffsetProperty ); - } - set - { - this.SetValue( TableflowViewItemsHost.AnimatedVerticalOffsetProperty, value ); - } - } - - private void OnAnimatedVerticalOffsetChanged( double oldValue, double newValue ) - { - this.SetVerticalOffsetCore( newValue ); - this.InvalidateLayoutFromScrollingHelper(); - } - - private static void OnAnimatedVerticalOffsetChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var self = ( TableflowViewItemsHost )sender; - - // Do not generate a page while the changed is due to the unloading - // of the grid. See TableflowViewItemsHost.OnParentDataGridControlChanged. - if( ( self == null ) || ( DataGridControl.GetDataGridContext( self ) == null ) ) - return; - - self.OnAnimatedVerticalOffsetChanged( ( double )e.OldValue, ( double )e.NewValue ); - } - - #endregion - - #region AnimatedScrollInfo Property - - internal IAnimatedScrollInfo AnimatedScrollInfo - { - get - { - return ( IAnimatedScrollInfo )this; - } - } - - #endregion - - #region PreviousTabNavigationMode ( private attached property ) - - private static readonly DependencyProperty PreviousTabNavigationModeProperty = DependencyProperty.RegisterAttached( - "PreviousTabNavigationMode", - typeof( KeyboardNavigationMode ), - typeof( TableflowViewItemsHost ), - new FrameworkPropertyMetadata( ( KeyboardNavigationMode )KeyboardNavigationMode.None ) ); - - private static KeyboardNavigationMode GetPreviousTabNavigationMode( DependencyObject d ) - { - return ( KeyboardNavigationMode )d.GetValue( TableflowViewItemsHost.PreviousTabNavigationModeProperty ); - } - - private static void SetPreviousTabNavigationMode( DependencyObject d, KeyboardNavigationMode value ) - { - d.SetValue( TableflowViewItemsHost.PreviousTabNavigationModeProperty, value ); - } - - #endregion - - #region PreviousDirectionalNavigationMode ( private attached property ) - - private static readonly DependencyProperty PreviousDirectionalNavigationModeProperty = DependencyProperty.RegisterAttached( - "PreviousDirectionalNavigationMode", - typeof( KeyboardNavigationMode ), - typeof( TableflowViewItemsHost ), - new FrameworkPropertyMetadata( ( KeyboardNavigationMode )KeyboardNavigationMode.None ) ); - - private static KeyboardNavigationMode GetPreviousDirectionalNavigationMode( DependencyObject d ) - { - return ( KeyboardNavigationMode )d.GetValue( TableflowViewItemsHost.PreviousDirectionalNavigationModeProperty ); - } - - private static void SetPreviousDirectionalNavigationMode( DependencyObject d, KeyboardNavigationMode value ) - { - d.SetValue( TableflowViewItemsHost.PreviousDirectionalNavigationModeProperty, value ); - } - - #endregion - - #region RowSelectorPane Property - - private RowSelectorPane RowSelectorPane - { - get - { - TableViewScrollViewer tableViewScrollViewer = this.AnimatedScrollInfo.ScrollOwner as TableViewScrollViewer; - - return ( tableViewScrollViewer == null ) - ? null - : tableViewScrollViewer.RowSelectorPane; - } - } - - #endregion - - #region IsSticky Internal Attached Property - - private static readonly DependencyPropertyKey IsStickyPropertyKey = DependencyProperty.RegisterAttachedReadOnly( - "IsSticky", typeof( bool ), typeof( TableflowViewItemsHost ), - new FrameworkPropertyMetadata( false, FrameworkPropertyMetadataOptions.Inherits ) ); - - internal static readonly DependencyProperty IsStickyProperty; - - internal static bool GetIsSticky( DependencyObject obj ) - { - return ( bool )obj.GetValue( TableflowViewItemsHost.IsStickyProperty ); - } - - internal static void SetIsSticky( DependencyObject obj, bool value ) - { - obj.SetValue( TableflowViewItemsHost.IsStickyPropertyKey, value ); - } - - internal static void ClearIsSticky( DependencyObject obj ) - { - obj.ClearValue( TableflowViewItemsHost.IsStickyPropertyKey ); - } - - #endregion - - #region AreHeadersStickyCache Private Property - - private bool AreHeadersStickyCache - { - get - { - return m_flags[ ( int )TableflowItemsHostFlags.AreHeadersSticky ]; - } - set - { - m_flags[ ( int )TableflowItemsHostFlags.AreHeadersSticky ] = value; - } - } - - #endregion - - #region AreFootersStickyCache Private Property - - private bool AreFootersStickyCache - { - get - { - return m_flags[ ( int )TableflowItemsHostFlags.AreFootersSticky ]; - } - set - { - m_flags[ ( int )TableflowItemsHostFlags.AreFootersSticky ] = value; - } - } - - #endregion - - #region AreGroupHeadersStickyCache Private Property - - private bool AreGroupHeadersStickyCache - { - get - { - return m_flags[ ( int )TableflowItemsHostFlags.AreGroupHeadersSticky ]; - } - set - { - m_flags[ ( int )TableflowItemsHostFlags.AreGroupHeadersSticky ] = value; - } - } - - #endregion - - #region AreGroupFootersStickyCache Private Property - - private bool AreGroupFootersStickyCache - { - get - { - return m_flags[ ( int )TableflowItemsHostFlags.AreGroupFootersSticky ]; - } - set - { - m_flags[ ( int )TableflowItemsHostFlags.AreGroupFootersSticky ] = value; - } - } - - #endregion - - #region AreParentRowsStickyCache Private Property - - private bool AreParentRowsStickyCache - { - get - { - return m_flags[ ( int )TableflowItemsHostFlags.AreParentRowSticky ]; - } - set - { - m_flags[ ( int )TableflowItemsHostFlags.AreParentRowSticky ] = value; - } - } - - #endregion - - #region PreventOpacityAnimation Private Property - - private bool PreventOpacityAnimation - { - get - { - return m_flags[ ( int )TableflowItemsHostFlags.PreventOpacityAnimation ]; - } - set - { - m_flags[ ( int )TableflowItemsHostFlags.PreventOpacityAnimation ] = value; - } - } - - #endregion - - #region IsDeferredLoadingEnabledCache Private Property - - private bool IsDeferredLoadingEnabledCache - { - get - { - return m_flags[ ( int )TableflowItemsHostFlags.IsDeferredLoadingEnabled ]; - } - set - { - m_flags[ ( int )TableflowItemsHostFlags.IsDeferredLoadingEnabled ] = value; - } - } - - #endregion - - #region Measure/Arrange Methods - - protected override Size MeasureOverride( Size availableSize ) - { - m_cachedContainerDesiredWidth.Clear(); - m_cachedContainerRealDesiredWidth.Clear(); - m_autoWidthCalculatedDataGridContextList.Clear(); - - m_lastMeasureAvailableSize = availableSize; - - this.CacheViewProperties(); - - // CALCULATE THE VIEWPORT HEIGHT - m_viewportHeight = Double.IsInfinity( availableSize.Height ) - ? this.AnimatedScrollInfo.ExtentHeight - : Math.Min( availableSize.Height, this.AnimatedScrollInfo.ExtentHeight ); - - this.CalculatePageItemCount( m_viewportHeight ); - this.EnsureVerticalOffsetValid( m_viewportHeight ); - this.GeneratePage( true, m_viewportHeight ); - - double synchronizedExtentWidth = 0d; - DataGridScrollViewer scrollViewer = this.AnimatedScrollInfo.ScrollOwner as DataGridScrollViewer; - - if( scrollViewer != null ) - { - synchronizedExtentWidth = scrollViewer.SynchronizedScrollViewersWidth; - } - - // CALCULATE THE EXTENT WIDTH - m_extentWidth = Math.Max( this.GetMaxDesiredWidth(), synchronizedExtentWidth ); - - // CALCULATE THE VIEWPORT WIDTH - m_viewportWidth = Double.IsInfinity( availableSize.Width ) - ? m_extentWidth : Math.Min( availableSize.Width, m_extentWidth ); - - this.InvalidateScrollInfo(); - - if( m_delayedBringIntoViewIndex != -1 ) - { - this.DelayedBringIntoView(); - } - - return new Size( m_viewportWidth, m_viewportHeight ); - } - - private void CacheViewProperties() - { - DataGridContext dataGridContext = this.CachedRootDataGridContext; - - m_containerHeight = TableflowView.GetContainerHeight( dataGridContext ); - - this.AreHeadersStickyCache = TableflowView.GetAreHeadersSticky( dataGridContext ); - this.AreFootersStickyCache = TableflowView.GetAreFootersSticky( dataGridContext ); - this.AreGroupHeadersStickyCache = TableflowView.GetAreGroupHeadersSticky( dataGridContext ); - this.AreGroupFootersStickyCache = TableflowView.GetAreGroupFootersSticky( dataGridContext ); - this.AreParentRowsStickyCache = TableflowView.GetAreParentRowsSticky( dataGridContext ); - this.IsDeferredLoadingEnabledCache = TableflowView.GetIsDeferredLoadingEnabled( dataGridContext ); - } - - private void MeasureContainer( UIElement container ) - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( container ); - - string dataGridContextName = this.GetDataGridContextName( container, dataGridContext ); - bool containerIsRow = this.ContainerIsRow( container ); - - if( !m_autoWidthCalculatedDataGridContextList.Contains( dataGridContextName ) - && containerIsRow ) - { - dataGridContext.ColumnStretchingManager.ColumnStretchingCalculated = false; - - // Calling Measure with the Viewport's width will have the effect of - // distributing the extra space (see FixedCellPanel's MeasureOverride). - // Eventually, the FixedCellPanel will receive an adjusted viewport - // width (where GroupLevelIndicator's width et al will be substracted). - container.Measure( new Size( m_lastMeasureAvailableSize.Width, m_containerHeight ) ); - - if( dataGridContext.ColumnStretchingManager.ColumnStretchingCalculated ) - { - // We only calculate once per detail. - m_autoWidthCalculatedDataGridContextList.Add( dataGridContextName ); - } - } - else - { - // We invalidate the CellsHostPanel of the row and all is parent to ensure the - // size is correctly evaluated when we have some auto stretching column. - container.InvalidateMeasure(); - - Row row = Row.FromContainer( container ); - if( row != null ) - { - UIElement itemToInvalidate = row.CellsHostPanel; - - while( ( itemToInvalidate != null ) && ( itemToInvalidate != container ) ) - { - itemToInvalidate.InvalidateMeasure(); - itemToInvalidate = VisualTreeHelper.GetParent( itemToInvalidate ) as UIElement; - } - } - } - - // We always measure the container with infinity so that we'll arrange each container, - // for a DataGridContext, with the maximum needed for that context. - container.Measure( new Size( double.PositiveInfinity, m_containerHeight ) ); - - double desiredSize = container.DesiredSize.Width; - double cachedSize; - - if( m_cachedContainerDesiredWidth.TryGetValue( dataGridContextName, out cachedSize ) ) - { - // Keep the largest size! - if( cachedSize < desiredSize ) - { - m_cachedContainerDesiredWidth[ dataGridContextName ] = desiredSize; - } - } - else - { - // Cache the size for the context. - m_cachedContainerDesiredWidth.Add( dataGridContextName, desiredSize ); - } - - PassiveLayoutDecorator decorator = this.GetPassiveLayoutDecorator( container as HeaderFooterItem ); - if( decorator != null ) - { - desiredSize = decorator.RealDesiredSize.Width; - - if( m_cachedContainerRealDesiredWidth.TryGetValue( dataGridContextName, out cachedSize ) ) - { - // Keep the largest size! - if( cachedSize < desiredSize ) - { - m_cachedContainerRealDesiredWidth[ dataGridContextName ] = desiredSize; - } - } - else - { - // Cache the size for the context. - m_cachedContainerRealDesiredWidth.Add( dataGridContextName, desiredSize ); - } - } - } - - protected override Size ArrangeOverride( Size finalSize ) - { - // Never call InvalidateScrollInfo() in there, that can cause infinit invalidation loop. - m_lastArrangeFinalSize = finalSize; - - this.CalculatePageItemCount( finalSize.Height ); - this.LayoutContainers(); - - m_delayedBringIntoViewIndex = -1; - - return finalSize; - } - - private PassiveLayoutDecorator GetPassiveLayoutDecorator( HeaderFooterItem item ) - { - if( ( item == null ) || ( VisualTreeHelper.GetChildrenCount( item ) == 0 ) ) - return null; - - var child = VisualTreeHelper.GetChild( item, 0 ); - if( child == null ) - return null; - - var decorator = child as PassiveLayoutDecorator; - if( ( decorator == null ) && ( VisualTreeHelper.GetChildrenCount( child ) > 0 ) ) - { - decorator = VisualTreeHelper.GetChild( child, 0 ) as PassiveLayoutDecorator; - } - - return decorator; - } - - private void ArrangeContainer( UIElement container, Point translationPoint, bool rowSelectorPaneVisible ) - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( container ); - string dataGridContextName = this.GetDataGridContextName( container, dataGridContext ); - - Size containerSize = new Size( - this.GetContainerWidth( dataGridContextName ), - m_containerHeight ); - - container.Arrange( new Rect( translationPoint, containerSize ) ); - this.SetCompensationOffset( dataGridContext, container, containerSize.Width ); - - if( rowSelectorPaneVisible ) - { - this.SetRowSelector( container, translationPoint, containerSize ); - } - } - - private double GetContainerWidth( string dataGridContextName ) - { - double synchronizedWidth = this.GetSynchronizedExtentWidth(); - double desiredWidth = 0; - - bool sizeCached = m_cachedContainerDesiredWidth.TryGetValue( dataGridContextName, out desiredWidth ); - - if( !sizeCached ) - { - desiredWidth = synchronizedWidth; - } - - if( string.IsNullOrEmpty( dataGridContextName ) ) // master level - { - //for the master level, I want to consider the Synchronized Extent size as well. - desiredWidth = Math.Max( synchronizedWidth, desiredWidth ); - } - - if( desiredWidth == 0 ) - { - m_cachedContainerRealDesiredWidth.TryGetValue( dataGridContextName, out desiredWidth ); - } - - return desiredWidth; - } - - private double GetSynchronizedExtentWidth() - { - DataGridScrollViewer dgScrollViewer = this.AnimatedScrollInfo.ScrollOwner as DataGridScrollViewer; - - if( dgScrollViewer != null ) - return dgScrollViewer.SynchronizedScrollViewersWidth; - - return 0; - } - - private void SetCompensationOffset( DataGridContext dataGridContext, UIElement container, double desiredWidth ) - { - double compensationOffset = Math.Max( - 0, - ( ( m_horizontalOffset + Math.Min( m_viewportWidth, desiredWidth ) ) - desiredWidth ) ); - - TableView.SetCompensationOffset( container, compensationOffset ); - - // Affect the CompensationOffset on the DataGridContext for the TableViewColumnVirtualizationManager - // to bind to this value - TableView.SetCompensationOffset( dataGridContext, compensationOffset ); - } - - private void SetRowSelector( UIElement container, Point translationPoint, Size size ) - { - RowSelectorPane rowSelectorPane = this.RowSelectorPane; - - if( rowSelectorPane == null ) - return; - - rowSelectorPane.SetRowSelectorPosition( - container, - new Rect( translationPoint, size ), - this ); - } - - private void FreeRowSelector( UIElement container ) - { - RowSelectorPane rowSelectorPane = this.RowSelectorPane; - - if( rowSelectorPane == null ) - return; - - rowSelectorPane.FreeRowSelector( container ); - } - - private double GetMaxDesiredWidth() - { - double maxDesiredWidth = 0d; - - foreach( var item in m_cachedContainerDesiredWidth ) - { - double desiredWidth = item.Value; - - if( desiredWidth == 0 ) - { - m_cachedContainerRealDesiredWidth.TryGetValue( item.Key, out desiredWidth ); - } - - if( desiredWidth > maxDesiredWidth ) - { - maxDesiredWidth = desiredWidth; - } - } - - return maxDesiredWidth; - } - - #endregion - - #region Containers Methods - - private bool ContainerIsRow( UIElement container ) - { - if( container is Row ) - return true; - - HeaderFooterItem headerFooterItem = container as HeaderFooterItem; - - if( headerFooterItem != null ) - return typeof( Row ).IsAssignableFrom( headerFooterItem.VisualRootElementType ); - - return false; - } - - private string GetDataGridContextName( UIElement container ) - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( container ); - - return this.GetDataGridContextName( container, dataGridContext ); - } - - private string GetDataGridContextName( UIElement container, DataGridContext dataGridContext ) - { - return ( dataGridContext.SourceDetailConfiguration != null ) - ? dataGridContext.SourceDetailConfiguration.RelationName - : string.Empty; - } - - private void CalculatePageItemCount( double height ) - { - m_pageVisibleContainerCount = Double.IsInfinity( height ) - ? this.CustomItemContainerGenerator.ItemCount - : ( int )Math.Ceiling( height / m_containerHeight ); - } - - private int CalculateFlooredPageItemCount( double height ) - { - return Double.IsInfinity( height ) - ? this.CustomItemContainerGenerator.ItemCount - : ( int )Math.Floor( height / m_containerHeight ); - } - - private void CalculateLayoutedIndexes( double verticalOffset, double viewportHeight, out PageIndexes layoutedIndexes ) - { - layoutedIndexes = new PageIndexes(); - - int itemCount = this.CustomItemContainerGenerator.ItemCount; - if( itemCount > 0 ) - { - layoutedIndexes.StartIndex = Math.Min( - this.GetContainerIndexFromOffset( verticalOffset, false ), - itemCount - 1 ); - - layoutedIndexes.EndIndex = Math.Min( - this.GetContainerIndexFromOffset( verticalOffset + viewportHeight - m_containerHeight, true ), - itemCount - 1 ); - - layoutedIndexes.EndIndex = Math.Max( - layoutedIndexes.StartIndex, - layoutedIndexes.EndIndex ); - } - } - - private PageIndexes CalculateVisibleIndexesForDesiredFirstVisibleIndex( int desiredFirstVisibleIndex ) - { - PageIndexes layoutedIndexes = new PageIndexes(); - - // Get the sticky header count for the desiredFirstVisibleIndex - // and set the StartIndex - int stickyHeaderCountForFirstVisibleIndex = this.GetStickyHeaderCountForIndex( desiredFirstVisibleIndex ); - layoutedIndexes.StartIndex = desiredFirstVisibleIndex - stickyHeaderCountForFirstVisibleIndex; - - // Get the index of the maximal visible index according - // to the number of container the viewport can display - // and the number of sticky header the desiredFirstVisibleIndex - // must display - int maxLastVisibleIndex = layoutedIndexes.StartIndex - + this.CalculateFlooredPageItemCount( this.AnimatedScrollInfo.ViewportHeight ); - - layoutedIndexes.EndIndex = maxLastVisibleIndex; - - // Process indexes from top to bottom up to an index for which - // the number of required sticky footers will force a visible index - // larger than the maximal acceptable last visible index - for( int i = desiredFirstVisibleIndex + 1; i <= maxLastVisibleIndex; i++ ) - { - int stickyFooterCountForIndex = this.GetStickyFooterCountForIndex( i ); - - // The index of the container + its sticky footer count - // is greater than the last acceptable visible index, we ensure - // the previous container as the maximal one to set as current - if( maxLastVisibleIndex < ( i + stickyFooterCountForIndex ) ) - { - layoutedIndexes.EndIndex = i - 1; - break; - } - } - - return layoutedIndexes; - } - - private PageIndexes CalculateVisibleIndexesForDesiredLastVisibleIndex( int desiredLastVisibleIndex ) - { - PageIndexes layoutedIndexes = new PageIndexes(); - - int stickyFooterCountForLastVisibleIndex = this.GetStickyFooterCountForIndex( desiredLastVisibleIndex ); - layoutedIndexes.EndIndex = desiredLastVisibleIndex + stickyFooterCountForLastVisibleIndex; - - int minVisibleIndex = layoutedIndexes.EndIndex - - this.CalculateFlooredPageItemCount( this.AnimatedScrollInfo.ViewportHeight ); - - layoutedIndexes.StartIndex = minVisibleIndex; - - // Process indexes from bottom to top up to an index for which - // the number of required sticky headers will force a visible index - // larger than the maximal acceptable last visible index - for( int i = desiredLastVisibleIndex - 1; i >= minVisibleIndex; i-- ) - { - int stickyHeaderCountForIndex = this.GetStickyHeaderCountForIndex( i ); - - // If the index of the container - its sticky header count - // is less than the minimal acceptable visible index, we ensure - // the next container index as the minimal one to set as current - if( minVisibleIndex > ( i - stickyHeaderCountForIndex ) ) - { - layoutedIndexes.StartIndex = i + 1; - break; - } - } - - return layoutedIndexes; - } - - private void GeneratePage( bool measureInvalidated, double viewportHeight ) - { - ICustomItemContainerGenerator generator = this.CustomItemContainerGenerator; - - // The generator can be null if we're in design mode. - if( generator != null ) - { - if( Double.IsInfinity( viewportHeight ) ) - { - viewportHeight = this.AnimatedScrollInfo.ExtentHeight; - } - - // Make sure that container recycling is currently enabled on the generator. - generator.IsRecyclingEnabled = true; - - // Calculate the start and end index of the current page. - PageIndexes visiblePageIndexes; - this.CalculateLayoutedIndexes( m_verticalOffset, viewportHeight, out visiblePageIndexes ); - - bool pageChanged = ( m_lastVisiblePageIndexes != visiblePageIndexes ); - - if( measureInvalidated || pageChanged ) - { - ICollection nonRecyclableContainers; - - if( m_containerHeight > 0d ) - { - // Recycle the containers we know will not be in the current page. GenerateContainers will recycle - // the remaining containers that were uncertain. - nonRecyclableContainers = this.RecycleSafeContainers( generator, visiblePageIndexes.StartIndex, visiblePageIndexes.EndIndex ); - - this.GenerateContainers( generator, visiblePageIndexes.StartIndex, visiblePageIndexes.EndIndex, measureInvalidated, nonRecyclableContainers ); - this.GenerateStickyHeaders( generator, measureInvalidated, nonRecyclableContainers ); - this.GenerateStickyFooters( generator, measureInvalidated, nonRecyclableContainers ); - } - else - { - nonRecyclableContainers = this.RecycleAllContainers( generator ); - Debug.Assert( m_layoutedContainers.Count == 0 ); - } - - // Keep alive containers that cannot be recycled (i.e. focused element). - this.KeepNonRecyclableContainers( generator, measureInvalidated, nonRecyclableContainers ); - } - - m_lastVisiblePageIndexes = visiblePageIndexes; - - this.PreventOpacityAnimation = false; - } - - } - - private ICollection RecycleContainers( ICustomItemContainerGenerator generator, int pageStartIndex, int pageEndIndex, bool clearContainer = false ) - { - var nonRecyclableContainers = new HashSet( m_layoutedContainers.Select( entry => entry.Container ).Where( c => !this.CanRecycleContainer( c ) ) ); - - for( int i = m_layoutedContainers.Count - 1; i >= 0; i-- ) - { - var container = m_layoutedContainers[ i ].Container; - - var index = generator.GetRealizedIndexForContainer( container ); - - // If the container's index is now out of view, recycle that container. - if( ( index < pageStartIndex ) || ( index > pageEndIndex ) ) - { - if( !nonRecyclableContainers.Contains( container ) ) - { - this.RecycleContainer( generator, index, container, clearContainer ); - } - - m_layoutedContainers.RemoveAt( i ); - } - } - - return nonRecyclableContainers; - } - - private ICollection RecycleAllContainers( ICustomItemContainerGenerator generator ) - { - return this.RecycleContainers( generator, -1, -1, true ); - } - - private ICollection RecycleSafeContainers( ICustomItemContainerGenerator generator, int pageStartIndex, int pageEndIndex ) - { - if( m_lastVisiblePageIndexes == PageIndexes.Empty ) - return this.RecycleContainers( generator, pageStartIndex, pageEndIndex ); - - if( m_lastVisiblePageIndexes.StartIndex == pageStartIndex ) - return this.RecycleContainers( generator, - pageStartIndex, - Math.Max( pageEndIndex, m_lastVisiblePageIndexes.EndIndex ) ); - - if( m_lastVisiblePageIndexes.EndIndex == pageEndIndex ) - return this.RecycleContainers( generator, - Math.Min( pageStartIndex, m_lastVisiblePageIndexes.StartIndex ), - pageEndIndex ); - - int itemCount = generator.ItemCount; - int threshold = Math.Max( 0, ( m_lastVisiblePageIndexes.EndIndex - m_lastVisiblePageIndexes.StartIndex ) - ( pageEndIndex - pageStartIndex ) ); - - int endIndex = Math.Min( pageEndIndex + threshold, itemCount - 1 ); - if( endIndex < 0 ) - return this.RecycleAllContainers( generator ); - - int startIndex = Math.Max( endIndex - threshold - ( pageEndIndex - pageStartIndex ), 0 ); - - return this.RecycleContainers( generator, startIndex, endIndex ); - } - - private void RecycleUnusedStickyContainers( - ICustomItemContainerGenerator generator, - StickyContainerInfoList stickyContainers, - StickyContainerInfoList stickyContainersToExclude, - ICollection nonRecyclableContainers ) - { - for( int i = stickyContainers.Count - 1; i >= 0; i-- ) - { - StickyContainerInfo stickyHeaderInfo = stickyContainers[ i ]; - UIElement container = stickyHeaderInfo.Container; - - if( m_layoutedContainers.ContainsContainer( container ) ) - continue; - - if( ( stickyContainersToExclude != null ) && ( stickyContainersToExclude.ContainsContainer( container ) ) ) - continue; - - if( ( nonRecyclableContainers != null ) && nonRecyclableContainers.Contains( container ) ) - continue; - - var index = generator.GetRealizedIndexForContainer( container ); - - this.RecycleContainer( generator, index, container ); - stickyContainers.RemoveAt( i ); - } - } - - private void RecycleContainer( UIElement container ) - { - this.RecycleContainer( null, -1, container ); - } - - private void RecycleContainer( ICustomItemContainerGenerator generator, int containerIndex, UIElement container, bool clearContainer = true ) - { - if( !clearContainer ) - { - var dataGridItemContainer = container as IDataGridItemContainer; - if( dataGridItemContainer != null ) - { - dataGridItemContainer.IsRecyclingCandidate = true; - } - } - else - { - this.ClearContainer( container ); - } - - if( ( generator != null ) && ( containerIndex != -1 ) ) - { - try - { - GeneratorPosition position = generator.GeneratorPositionFromIndex( containerIndex ); - generator.Remove( position, 1 ); - } - catch - { - Debug.Fail( "Unable to remove container for containerIndex " + containerIndex ); - } - } - } - - private void CleanRecyclingCandidates() - { - var generator = this.CustomItemContainerGenerator as CustomItemContainerGenerator; - generator.CleanRecyclingCandidates(); - } - - private void GenerateContainers( ICustomItemContainerGenerator generator, int pageStartIndex, int pageEndIndex, bool measureInvalidated, ICollection nonRecyclableContainers ) - { - HashSet unusedLayoutedContainers = new HashSet( m_layoutedContainers.Select( item => item.Container ) ); - m_layoutedContainers.Clear(); - - ScrollDirection scrollDirection = this.AnimatedScrollInfo.VerticalScrollingDirection; - - GeneratorPosition position; - GeneratorDirection direction; - int currentIndex; - int step; - - if( ( scrollDirection == ScrollDirection.Forward ) - || ( scrollDirection == ScrollDirection.None ) ) - { - position = generator.GeneratorPositionFromIndex( pageStartIndex ); - direction = GeneratorDirection.Forward; - currentIndex = pageStartIndex; - step = 1; - } - else - { - position = generator.GeneratorPositionFromIndex( pageEndIndex ); - direction = GeneratorDirection.Backward; - currentIndex = pageEndIndex; - step = -1; - } - - using( generator.StartAt( position, direction, true ) ) - { - while( ( currentIndex >= pageStartIndex ) && ( currentIndex <= pageEndIndex ) ) - { - var container = this.GenerateContainer( generator, currentIndex, measureInvalidated, true ); - if( container == null ) - break; - - // The container is now part of the page layout. Add it to the list. - m_layoutedContainers.Add( new LayoutedContainerInfo( currentIndex, container ) ); - unusedLayoutedContainers.Remove( container ); - nonRecyclableContainers.Remove( container ); - - currentIndex += step; - } - } - - // A ScrollViewer may measure forever if the containers that are "underneath" the horizontal - // scrollbar are the ones that required the scrollbar in the first place. - if( m_lastVisiblePageIndexes != PageIndexes.Empty ) - { - int remainingItemCount = ( m_lastVisiblePageIndexes.EndIndex - m_lastVisiblePageIndexes.StartIndex ) - - ( pageEndIndex - pageStartIndex ); - - if( ( remainingItemCount > 0 ) && ( this.GetMaxDesiredWidth() < this.AnimatedScrollInfo.ExtentWidth ) ) - { - int itemCount = generator.ItemCount; - - if( ( currentIndex >= 0 ) && ( currentIndex < itemCount ) ) - { - position = generator.GeneratorPositionFromIndex( currentIndex ); - - using( generator.StartAt( position, direction, true ) ) - { - while( ( remainingItemCount > 0 ) && ( currentIndex >= 0 ) && ( currentIndex < itemCount ) ) - { - var container = this.GenerateContainer( generator, currentIndex, measureInvalidated, true ); - if( container == null ) - break; - - // The container is now part of the page layout. Add it to the list. - m_layoutedContainers.Add( new LayoutedContainerInfo( currentIndex, container ) ); - unusedLayoutedContainers.Remove( container ); - nonRecyclableContainers.Remove( container ); - - currentIndex += step; - remainingItemCount--; - } - } - } - } - } - - m_layoutedContainers.Sort(); - - // Recycle the containers that have not been reused in the current page. - foreach( var container in unusedLayoutedContainers ) - { - if( nonRecyclableContainers.Contains( container ) ) - continue; - - var index = generator.GetRealizedIndexForContainer( container ); - - this.RecycleContainer( generator, index, container ); - } - - this.CleanRecyclingCandidates(); - } - - private void KeepNonRecyclableContainers( ICustomItemContainerGenerator generator, bool measureInvalidated, ICollection nonRecyclableContainers ) - { - if( ( nonRecyclableContainers == null ) || ( nonRecyclableContainers.Count == 0 ) ) - return; - - foreach( var container in nonRecyclableContainers ) - { - var index = generator.GetRealizedIndexForContainer( container ); - if( index >= 0 ) - { - if( measureInvalidated ) - { - this.MeasureContainer( container ); - } - - m_layoutedContainers.Add( new LayoutedContainerInfo( index, container ) ); - } - else - { - this.RecycleContainer( container ); - } - } - } - - private int GetStickyHeaderCountForIndex( int desiredIndex ) - { - var dataGridContext = DataGridControl.GetDataGridContext( this ); - if( dataGridContext == null ) - return 0; - - var customGenerator = dataGridContext.CustomItemContainerGenerator; - if( customGenerator == null ) - return 0; - - return customGenerator.GetStickyHeaderCountForIndex( desiredIndex, - this.AreHeadersStickyCache, - this.AreGroupHeadersStickyCache, - this.AreParentRowsStickyCache ); - } - - private int GetStickyFooterCountForIndex( int desiredIndex ) - { - var dataGridContext = DataGridControl.GetDataGridContext( this ); - if( dataGridContext == null ) - return 0; - - var customGenerator = dataGridContext.CustomItemContainerGenerator; - if( customGenerator == null ) - return 0; - - return customGenerator.GetStickyFooterCountForIndex( desiredIndex, - this.AreFootersStickyCache, - this.AreGroupFootersStickyCache ); - } - - private void GenerateStickyHeaders( ICustomItemContainerGenerator generator, bool measureInvalidated, ICollection nonRecyclableContainers ) - { - var customGenerator = ( CustomItemContainerGenerator )generator; - var newStickyHeaders = new StickyContainerInfoList(); - - if( this.AreHeadersStickyCache || this.AreGroupHeadersStickyCache || this.AreParentRowsStickyCache ) - { - var numberOfContainerChecked = 0; - - foreach( var layoutedContainerInfo in m_layoutedContainers ) - { - var container = layoutedContainerInfo.Container; - - // For each visible container, we must find what headers should be sticky for it. - var stickyHeaders = customGenerator.GenerateStickyHeaders( container, this.AreHeadersStickyCache, this.AreGroupHeadersStickyCache, this.AreParentRowsStickyCache ); - - stickyHeaders.Sort( StickyContainerGeneratedComparer.Singleton ); - - // For each sticky headers returned, we must get the index of the last container - // that could need that container to be sticky. - foreach( var stickyHeaderInfo in stickyHeaders ) - { - var stickyContainer = ( UIElement )stickyHeaderInfo.StickyContainer; - if( newStickyHeaders.ContainsContainer( stickyContainer ) ) - continue; - - var lastContainerIndex = customGenerator.GetLastHoldingContainerIndexForStickyHeader( stickyContainer ); - - var stickyContainerInfo = new StickyContainerInfo( stickyContainer, stickyHeaderInfo.Index, lastContainerIndex ); - newStickyHeaders.Add( stickyContainerInfo ); - nonRecyclableContainers.Remove( stickyContainer ); - - this.HandleGeneratedStickyContainerPreparation( stickyHeaderInfo, measureInvalidated ); - } - - // We only need to find the sticky headers for one - // more element than what is already sticky. - var visibleStickyHeadersCount = ( int )Math.Ceiling( this.GetStickyHeadersRegionHeight( newStickyHeaders ) / m_containerHeight ); - - if( ( ++numberOfContainerChecked - visibleStickyHeadersCount ) >= 1 ) - break; - } - - foreach( var stickyHeaderInfo in newStickyHeaders ) - { - var index = m_layoutedContainers.IndexOfContainer( stickyHeaderInfo.Container ); - if( index < 0 ) - continue; - - m_layoutedContainers.RemoveAt( index ); - } - - foreach( var stickyHeaderInfo in m_stickyHeaders ) - { - var container = stickyHeaderInfo.Container; - - if( !newStickyHeaders.ContainsContainer( container ) && !nonRecyclableContainers.Contains( container ) && !this.CanRecycleContainer( container ) ) - { - nonRecyclableContainers.Add( container ); - } - } - } - - this.RecycleUnusedStickyContainers( generator, m_stickyHeaders, newStickyHeaders, nonRecyclableContainers ); - - m_stickyHeaders.Clear(); - - if( newStickyHeaders.Count > 0 ) - { - m_stickyHeaders.AddRange( newStickyHeaders ); - m_stickyHeaders.Sort( StickyContainerInfoComparer.Singleton ); - } - } - - private void GenerateStickyFooters( ICustomItemContainerGenerator generator, bool measureInvalidated, ICollection nonRecyclableContainers ) - { - var newStickyFooters = new StickyContainerInfoList(); - - if( this.AreFootersStickyCache || this.AreGroupFootersStickyCache ) - { - var customGenerator = ( CustomItemContainerGenerator )generator; - var numberOfContainerChecked = 0; - var layoutedContainerCount = m_layoutedContainers.Count; - - if( layoutedContainerCount > 0 ) - { - // We must not generate sticky footers if the last container is not even at the bottom of the view! - var bottomMostContainerInfo = m_layoutedContainers[ layoutedContainerCount - 1 ]; - var bottomMostContainerOffset = this.GetContainerOffsetFromIndex( bottomMostContainerInfo.RealizedIndex ); - - if( ( bottomMostContainerOffset + m_containerHeight ) >= m_viewportHeight ) - { - for( var i = layoutedContainerCount - 1; i >= 0; i-- ) - { - var layoutedContainerInfo = m_layoutedContainers[ i ]; - var layoutedContainer = layoutedContainerInfo.Container; - - // For each visible container, we must find what footers should be sticky for it. - var stickyFooters = customGenerator.GenerateStickyFooters( layoutedContainer, this.AreFootersStickyCache, this.AreGroupFootersStickyCache ); - - stickyFooters.Sort( StickyContainerGeneratedReverseComparer.Singleton ); - - // For each sticky headers returned, we must get the index of the last container - // that could need that container to be sticky. - foreach( var stickyFooterInfo in stickyFooters ) - { - var stickyContainer = ( UIElement )stickyFooterInfo.StickyContainer; - if( newStickyFooters.ContainsContainer( stickyContainer ) ) - continue; - - var firstContainerIndex = customGenerator.GetFirstHoldingContainerIndexForStickyFooter( stickyContainer ); - - var stickyContainerInfo = new StickyContainerInfo( stickyContainer, stickyFooterInfo.Index, firstContainerIndex ); - newStickyFooters.Add( stickyContainerInfo ); - nonRecyclableContainers.Remove( stickyContainer ); - - this.HandleGeneratedStickyContainerPreparation( stickyFooterInfo, measureInvalidated ); - } - - // We only need to find the sticky footers for one - // more element than what is already sticky. - var visibleStickyFootersCount = ( int )Math.Ceiling( ( this.AnimatedScrollInfo.ViewportHeight - this.GetStickyFootersRegionHeight( newStickyFooters ) ) / m_containerHeight ); - - if( ( ++numberOfContainerChecked - visibleStickyFootersCount ) >= 1 ) - break; - } - } - } - - foreach( var stickyFooterInfo in newStickyFooters ) - { - var index = m_layoutedContainers.IndexOfContainer( stickyFooterInfo.Container ); - if( index < 0 ) - continue; - - m_layoutedContainers.RemoveAt( index ); - } - - foreach( var stickyFooterInfo in m_stickyFooters ) - { - var container = stickyFooterInfo.Container; - - if( !newStickyFooters.ContainsContainer( container ) && !nonRecyclableContainers.Contains( container ) && !this.CanRecycleContainer( container ) ) - { - nonRecyclableContainers.Add( container ); - } - } - } - - this.RecycleUnusedStickyContainers( generator, m_stickyFooters, newStickyFooters, nonRecyclableContainers ); - - m_stickyFooters.Clear(); - - if( newStickyFooters.Count > 0 ) - { - m_stickyFooters.AddRange( newStickyFooters ); - m_stickyFooters.Sort( StickyContainerInfoReverseComparer.Singleton ); - } - } - - private void HandleGeneratedStickyContainerPreparation( StickyContainerGenerated stickyContainerInfo, bool measureInvalidated ) - { - UIElement container = ( UIElement )stickyContainerInfo.StickyContainer; - bool isNewlyRealized = stickyContainerInfo.IsNewlyRealized; - - if( isNewlyRealized ) - { - if( !this.Children.Contains( container ) ) - { - this.Children.Add( container ); - } - - this.EnableElementNavigation( container ); - KeyboardNavigation.SetTabIndex( container, stickyContainerInfo.Index ); - } - - TableflowViewItemsHost.SetIsSticky( container, true ); - - // This will prepare, if needed, the container. - this.HandleGeneratedContainerPreparation( container, stickyContainerInfo.Index, isNewlyRealized, true ); - - // Measure, if needed, the container. - if( isNewlyRealized || measureInvalidated ) - { - this.MeasureContainer( container ); - } - } - - private UIElement GenerateContainer( ICustomItemContainerGenerator generator, int index, bool measureInvalidated, bool delayDataContext ) - { - bool isNewlyRealized; - UIElement container = ( UIElement )generator.GenerateNext( out isNewlyRealized ); - - if( container != null ) - { - if( isNewlyRealized ) - { - if( !this.Children.Contains( container ) ) - { - this.Children.Add( container ); - } - - this.EnableElementNavigation( container ); - KeyboardNavigation.SetTabIndex( container, index ); - } - - this.HandleGeneratedContainerPreparation( container, index, isNewlyRealized, delayDataContext ); - - if( ( isNewlyRealized ) || ( measureInvalidated ) ) - { - this.MeasureContainer( container ); - } - } - - return container; - } - - private void HandleGeneratedContainerPreparation( UIElement container, int containerIndex, bool isNewlyRealized, bool delayDataContext ) - { -#if DEBUG - TableflowViewItemsHost.SetRealizedIndex( container, containerIndex ); -#endif //DEBUG - - try - { - TableflowViewItemsHost.SetShouldDelayDataContext( - container, ( !this.PreventOpacityAnimation && this.IsDeferredLoadingEnabledCache && delayDataContext ) ); - - if( isNewlyRealized ) - { - // We must prepare the container if the container preparation - // should not be delayed or if we've been ask to prepare it (from - // a keyboard navigation for example) - this.PrepareContainer( container ); - } - - // We must set those properties AFTER calling PrepareContainer since PrepareContainer - // will set the ItemContainerStyle which could affect the Height properties. In our case, - // we want to override those properties so that our layout is ok. - container.SetValue( FrameworkElement.MinHeightProperty, m_containerHeight ); - container.SetValue( FrameworkElement.MaxHeightProperty, m_containerHeight ); - container.SetValue( FrameworkElement.HeightProperty, m_containerHeight ); - - // In the case of HeaderFooterItems, we also want to set the Height properties of the inner - // container if that container is a Row or a descendant. - HeaderFooterItem headerFooterItem = container as HeaderFooterItem; - - if( ( headerFooterItem != null ) - && ( headerFooterItem.Container != null ) - && ( this.ContainerIsRow( container ) ) ) - { - headerFooterItem.Container.SetValue( FrameworkElement.MinHeightProperty, m_containerHeight ); - headerFooterItem.Container.SetValue( FrameworkElement.MaxHeightProperty, m_containerHeight ); - headerFooterItem.Container.SetValue( FrameworkElement.HeightProperty, m_containerHeight ); - } - } - finally - { - container.ClearValue( TableflowViewItemsHost.ShouldDelayDataContextProperty ); - } - } - - private bool IsRowSelectorPaneVisible() - { - DataGridControl parentDataGridControl = this.ParentDataGridControl; - - if( parentDataGridControl != null ) - { - TableViewScrollViewer scrollViewer = parentDataGridControl.ScrollViewer as TableViewScrollViewer; - RowSelectorPane rowSelectorPane = ( scrollViewer != null ) ? scrollViewer.RowSelectorPane : null; - - if( rowSelectorPane != null ) - return ( rowSelectorPane.Visibility == Visibility.Visible ); - } - - return false; - } - - private void LayoutContainers() - { - var rowSelectorPaneVisible = this.IsRowSelectorPaneVisible(); - - this.LayoutStickyHeaders( rowSelectorPaneVisible ); - this.LayoutStickyFooters( rowSelectorPaneVisible ); - this.LayoutNonStickyContainers( rowSelectorPaneVisible ); - - var layoutedContainers = new HashSet(); - - foreach( var container in m_layoutedContainers.Select( item => item.Container ) ) - { - layoutedContainers.Add( container ); - } - - foreach( var container in m_stickyHeaders.Select( item => item.Container ) ) - { - layoutedContainers.Add( container ); - } - - foreach( var container in m_stickyFooters.Select( item => item.Container ) ) - { - layoutedContainers.Add( container ); - } - - // Layout out of view the recycled container - foreach( var container in this.Children ) - { - if( layoutedContainers.Contains( container ) ) - continue; - - this.ArrangeContainer( container, TableflowViewItemsHost.OutOfViewPoint, false ); - } - - CommandManager.InvalidateRequerySuggested(); - - // The call to Mouse.Synchronize must not start dragging rows. - // Update the mouse status to make sure no container has invalid mouse over status. - // Only do this when the mouse is over the panel, to prevent unescessary update when scrolling with thumb. - if( this.IsMouseOver ) - { - var dataGridControl = this.ParentDataGridControl; - if( dataGridControl != null ) - { - using( dataGridControl.InhibitDrag() ) - { - Mouse.Synchronize(); - } - } - } - } - - private void LayoutNonStickyContainers( bool rowSelectorPaneVisible ) - { - int count = m_layoutedContainers.Count; - double clippedHeaderOffset = this.GetStickyHeadersRegionHeight(); - double clippedFooterOffset = this.GetStickyFootersRegionHeight(); - - for( int i = 0; i < count; i++ ) - { - LayoutedContainerInfo layoutedContainerInfo = m_layoutedContainers[ i ]; - int realizedIndex = layoutedContainerInfo.RealizedIndex; - UIElement container = layoutedContainerInfo.Container; - - double desiredOffset = this.GetContainerOffsetFromIndex( realizedIndex ) - m_verticalOffset; - - if( desiredOffset < clippedHeaderOffset ) - { - double shownRectHeight = Math.Max( m_containerHeight - ( clippedHeaderOffset - desiredOffset ), 0 ); - - Rect shownRect = new Rect( - new Point( 0, m_containerHeight - shownRectHeight ), - new Size( this.AnimatedScrollInfo.ExtentWidth, shownRectHeight ) ); - - container.SetValue( UIElement.ClipProperty, new RectangleGeometry( shownRect ) ); - } - else if( desiredOffset + m_containerHeight > clippedFooterOffset ) - { - double shownRectHeight = Math.Min( clippedFooterOffset - desiredOffset, m_containerHeight ); - shownRectHeight = Math.Max( shownRectHeight, 0 ); - - Rect shownRect = new Rect( - new Point(), - new Size( this.AnimatedScrollInfo.ExtentWidth, shownRectHeight ) ); - - container.SetValue( UIElement.ClipProperty, new RectangleGeometry( shownRect ) ); - } - else - { - container.ClearValue( UIElement.ClipProperty ); - } - - Point translationPoint = new Point( -m_horizontalOffset, desiredOffset ); - - this.ArrangeContainer( container, translationPoint, rowSelectorPaneVisible ); - } - } - - private void LayoutStickyHeaders( bool rowSelectorPaneVisible ) - { - int count = m_stickyHeaders.Count; - double lastStickyHeaderOffset = -m_containerHeight; - double clippedOffset = lastStickyHeaderOffset + m_containerHeight; - - for( int i = 0; i < count; i++ ) - { - StickyContainerInfo stickyContainerInfo = m_stickyHeaders[ i ]; - UIElement container = stickyContainerInfo.Container; - - double desiredOffset = this.ComputeStickyHeaderDesiredOffset( stickyContainerInfo, lastStickyHeaderOffset ); - lastStickyHeaderOffset = Math.Max( desiredOffset, lastStickyHeaderOffset ); - - if( desiredOffset < clippedOffset ) - { - double shownRectHeight = Math.Max( m_containerHeight - ( clippedOffset - desiredOffset ), 0 ); - - Rect shownRect = new Rect( - new Point( 0, m_containerHeight - shownRectHeight ), - new Size( this.AnimatedScrollInfo.ExtentWidth, shownRectHeight ) ); - - container.SetValue( UIElement.ClipProperty, new RectangleGeometry( shownRect ) ); - } - else - { - container.ClearValue( UIElement.ClipProperty ); - } - - clippedOffset = lastStickyHeaderOffset + m_containerHeight; - - Point translationPoint = new Point( - -m_horizontalOffset, - desiredOffset ); - - this.ArrangeContainer( container, translationPoint, rowSelectorPaneVisible ); - } - } - - internal double GetStickyHeadersRegionHeight() - { - return this.GetStickyHeadersRegionHeight( m_stickyHeaders ); - } - - internal double GetStickyHeadersRegionHeight( StickyContainerInfoList stickyHeaders ) - { - int count = stickyHeaders.Count; - double lastStickyHeaderOffset = -m_containerHeight; - - for( int i = 0; i < count; i++ ) - { - double desiredOffset = this.ComputeStickyHeaderDesiredOffset( stickyHeaders[ i ], lastStickyHeaderOffset ); - lastStickyHeaderOffset = Math.Max( desiredOffset, lastStickyHeaderOffset ); - } - - return lastStickyHeaderOffset + m_containerHeight; - } - - private double ComputeStickyHeaderDesiredOffset( StickyContainerInfo stickyHeaderInfo, double lastStickyHeaderOffset ) - { - double lastHoldingContainerOffset = this.GetContainerOffsetFromIndex( stickyHeaderInfo.HoldingContainerIndex ) - m_verticalOffset; - double desiredStickyHeaderOffset = lastStickyHeaderOffset + m_containerHeight; - double realHeaderOffset = this.GetContainerOffsetFromIndex( stickyHeaderInfo.ContainerIndex ) - m_verticalOffset; - - desiredStickyHeaderOffset = Math.Min( lastHoldingContainerOffset, desiredStickyHeaderOffset ); - desiredStickyHeaderOffset = Math.Max( realHeaderOffset, desiredStickyHeaderOffset ); - - return desiredStickyHeaderOffset; - } - - private void LayoutStickyFooters( bool rowSelectorPaneVisible ) - { - int count = m_stickyFooters.Count; - double lastStickyFooterOffset = m_viewportHeight; - double clippedHeaderOffset = this.GetStickyHeadersRegionHeight(); - double clippedOffset = lastStickyFooterOffset; - - // The first one in the list is the last visible one! - for( int i = 0; i < count; i++ ) - { - StickyContainerInfo stickyContainerInfo = m_stickyFooters[ i ]; - UIElement container = stickyContainerInfo.Container; - - double desiredOffset = this.ComputeStickyFooterDesiredOffset( stickyContainerInfo, lastStickyFooterOffset ); - lastStickyFooterOffset = Math.Min( desiredOffset, lastStickyFooterOffset ); - - if( desiredOffset < clippedHeaderOffset ) - { - double shownRectHeight = Math.Max( m_containerHeight - ( clippedHeaderOffset - desiredOffset ), 0 ); - - Rect shownRect = new Rect( - new Point( 0, m_containerHeight - shownRectHeight ), - new Size( this.AnimatedScrollInfo.ExtentWidth, shownRectHeight ) ); - - container.SetValue( UIElement.ClipProperty, new RectangleGeometry( shownRect ) ); - } - else if( desiredOffset + m_containerHeight > clippedOffset ) - { - double shownRectHeight = Math.Min( clippedOffset - desiredOffset, m_containerHeight ); - shownRectHeight = Math.Max( shownRectHeight, 0 ); - - Rect shownRect = new Rect( - new Point(), - new Size( this.AnimatedScrollInfo.ExtentWidth, shownRectHeight ) ); - - container.SetValue( UIElement.ClipProperty, new RectangleGeometry( shownRect ) ); - } - else - { - container.ClearValue( UIElement.ClipProperty ); - } - - clippedOffset = lastStickyFooterOffset; - - Point translationPoint = new Point( -m_horizontalOffset, desiredOffset ); - - this.ArrangeContainer( container, translationPoint, rowSelectorPaneVisible ); - } - } - - internal double GetStickyFootersRegionHeight() - { - return this.GetStickyFootersRegionHeight( m_stickyFooters ); - } - - internal double GetStickyFootersRegionHeight( StickyContainerInfoList stickyFooters ) - { - int count = stickyFooters.Count; - double lastStickyFooterOffset = m_viewportHeight; - - for( int i = 0; i < count; i++ ) - { - double desiredOffset = this.ComputeStickyFooterDesiredOffset( stickyFooters[ i ], lastStickyFooterOffset ); - lastStickyFooterOffset = Math.Min( desiredOffset, lastStickyFooterOffset ); - } - - return lastStickyFooterOffset; - } - - private double ComputeStickyFooterDesiredOffset( StickyContainerInfo stickyFooterInfo, double lastStickyFooterOffset ) - { - double firstHoldingContainerOffset = this.GetContainerOffsetFromIndex( stickyFooterInfo.HoldingContainerIndex ) - m_verticalOffset; - double desiredStickyFooterOffset = lastStickyFooterOffset - m_containerHeight; - double realFooterOffset = this.GetContainerOffsetFromIndex( stickyFooterInfo.ContainerIndex ) - m_verticalOffset; - - desiredStickyFooterOffset = Math.Max( firstHoldingContainerOffset, desiredStickyFooterOffset ); - desiredStickyFooterOffset = Math.Min( realFooterOffset, desiredStickyFooterOffset ); - - return desiredStickyFooterOffset; - } - - private int GetContainerIndexFromOffset( double offset, bool includePartiallyVisibleContainers ) - { - if( includePartiallyVisibleContainers ) - { - return ( int )Math.Ceiling( offset / m_containerHeight ); - } - else - { - return ( int )Math.Floor( offset / m_containerHeight ); - } - } - - private double GetContainerOffsetFromIndex( int index ) - { - return ( index * m_containerHeight ); - } - - private void DisableElementNavigation( UIElement child ) - { - //get previous values and store them on the container (attached) - TableflowViewItemsHost.SetPreviousDirectionalNavigationMode( child, KeyboardNavigation.GetDirectionalNavigation( child ) ); - TableflowViewItemsHost.SetPreviousTabNavigationMode( child, KeyboardNavigation.GetTabNavigation( child ) ); - - KeyboardNavigation.SetDirectionalNavigation( child, KeyboardNavigationMode.None ); - KeyboardNavigation.SetTabNavigation( child, KeyboardNavigationMode.None ); - } - - private void EnableElementNavigation( UIElement child ) - { - //checking only one of the 2 properties... This is because they are set together. - if( child.ReadLocalValue( TableflowViewItemsHost.PreviousDirectionalNavigationModeProperty ) != DependencyProperty.UnsetValue ) - { - KeyboardNavigation.SetDirectionalNavigation( child, TableflowViewItemsHost.GetPreviousDirectionalNavigationMode( child ) ); - KeyboardNavigation.SetTabNavigation( child, TableflowViewItemsHost.GetPreviousTabNavigationMode( child ) ); - } - //If unset, then nothing to do in this method! - } - - private void PrepareContainer( UIElement container ) - { - container.ClearValue( UIElement.VisibilityProperty ); - - var dataItemStore = Xceed.Wpf.DataGrid.CustomItemContainerGenerator.GetDataItemProperty( container ); - if( ( dataItemStore == null ) || dataItemStore.IsEmpty ) - return; - - var dataItem = dataItemStore.Data; - if( dataItem == null ) - return; - - // Prepare the container. - this.ParentDataGridControl.PrepareItemContainer( container, dataItem ); - } - - private void ClearContainer( UIElement container ) - { -#if DEBUG - TableflowViewItemsHost.SetRealizedIndex( container, -1 ); -#endif //DEBUG - TableflowViewItemsHost.ClearIsSticky( container ); - container.ClearValue( UIElement.ClipProperty ); - - this.DisableElementNavigation( container ); - this.FreeRowSelector( container ); - - container.Visibility = Visibility.Collapsed; - - // The call to DataGridControl.ClearItemContainer will be done by the CustomItemContainerGenerator. - } - - #endregion - - #region Animations Management - - private void InitializeHorizontalOffsetAnimation() - { - if( m_horizontalOffsetAnimation != null ) - return; - - m_horizontalOffsetAnimation = new OffsetAnimation(); - } - - private bool StartHorizontalOffsetAnimation() - { - var rootDataGridContext = this.CachedRootDataGridContext; - if( rootDataGridContext == null ) - { - this.StopHorizontalOffsetAnimation(); - return false; - } - - var scrollingAnimationDuration = TableflowView.GetScrollingAnimationDuration( rootDataGridContext ); - if( scrollingAnimationDuration <= 0d ) - return false; - - var animatedScrollInfo = this.AnimatedScrollInfo; - - m_horizontalOffsetAnimation.Duration = TimeSpan.FromMilliseconds( scrollingAnimationDuration ); - m_horizontalOffsetAnimation.From = animatedScrollInfo.OriginalHorizontalOffset; - m_horizontalOffsetAnimation.To = animatedScrollInfo.TargetHorizontalOffset; - - this.StopHorizontalOffsetAnimation(); - - m_horizontalOffsetAnimationClock = ( AnimationClock )m_horizontalOffsetAnimation.CreateClock( true ); - m_horizontalOffsetAnimationClock.Completed += this.OnHorizontalOffsetAnimationCompleted; - - this.ApplyAnimationClock( TableflowViewItemsHost.AnimatedHorizontalOffsetProperty, m_horizontalOffsetAnimationClock, HandoffBehavior.SnapshotAndReplace ); - - return true; - } - - private void StopHorizontalOffsetAnimation() - { - if( ( m_horizontalOffsetAnimationClock != null ) && ( m_horizontalOffsetAnimationClock.Controller != null ) ) - { - // We must call Pause instead on Stop to avoid having our - // offset momentary set to 0. Weird... - m_horizontalOffsetAnimationClock.Controller.Pause(); - m_horizontalOffsetAnimationClock.Completed -= this.OnHorizontalOffsetAnimationCompleted; - m_horizontalOffsetAnimationClock = null; - } - } - - private void OnHorizontalOffsetAnimationCompleted( object sender, EventArgs e ) - { - this.AnimatedScrollInfo.HorizontalScrollingDirection = ScrollDirection.None; - } - - private void InitializeVerticalOffsetAnimation() - { - if( m_verticalOffsetAnimation != null ) - return; - - m_verticalOffsetAnimation = new OffsetAnimation(); - } - - private bool StartVerticalOffsetAnimation() - { - var rootDataGridContext = this.CachedRootDataGridContext; - if( rootDataGridContext == null ) - { - this.StopVerticalOffsetAnimation(); - return false; - } - - var scrollingAnimationDuration = TableflowView.GetScrollingAnimationDuration( rootDataGridContext ); - if( scrollingAnimationDuration <= 0d ) - return false; - - var animatedScrollInfo = this.AnimatedScrollInfo; - - m_verticalOffsetAnimation.Duration = TimeSpan.FromMilliseconds( scrollingAnimationDuration ); - m_verticalOffsetAnimation.From = animatedScrollInfo.OriginalVerticalOffset; - m_verticalOffsetAnimation.To = animatedScrollInfo.TargetVerticalOffset; - - this.StopVerticalOffsetAnimation( false ); - - m_verticalOffsetAnimationClock = ( AnimationClock )m_verticalOffsetAnimation.CreateClock( true ); - m_verticalOffsetAnimationClock.Completed += this.OnVerticalOffsetAnimationCompleted; - - this.ApplyAnimationClock( TableflowViewItemsHost.AnimatedVerticalOffsetProperty, m_verticalOffsetAnimationClock, HandoffBehavior.SnapshotAndReplace ); - - return true; - } - - private void StopVerticalOffsetAnimation( bool resetScrollDirection = true ) - { - if( ( m_verticalOffsetAnimationClock != null ) && ( m_verticalOffsetAnimationClock.Controller != null ) ) - { - if( resetScrollDirection ) - { - this.AnimatedScrollInfo.VerticalScrollingDirection = ScrollDirection.None; - } - - // We must call Pause instead on Stop to avoid having our - // offset momentary set to 0. Weird... - m_verticalOffsetAnimationClock.Controller.Pause(); - m_verticalOffsetAnimationClock.Completed -= this.OnVerticalOffsetAnimationCompleted; - m_verticalOffsetAnimationClock = null; - - } - } - - private void OnVerticalOffsetAnimationCompleted( object sender, EventArgs e ) - { - this.AnimatedScrollInfo.VerticalScrollingDirection = ScrollDirection.None; - } - - #endregion - - #region Scrolling Management - - internal void InvalidateScrollInfo() - { - ScrollViewer scrollOwner = this.AnimatedScrollInfo.ScrollOwner; - - if( scrollOwner != null ) - { - scrollOwner.InvalidateScrollInfo(); - } - } - - private void EnsureVerticalOffsetValid( double height ) - { - IAnimatedScrollInfo animatedScrollInfo = this.AnimatedScrollInfo; - - double maxOffset; - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - if( ( !Double.IsInfinity( height ) ) && ( ( dataGridContext == null ) || ( TableView.GetAutoFillLastPage( dataGridContext ) ) ) ) - { - maxOffset = Math.Max( animatedScrollInfo.ExtentHeight - height, 0 ); - } - else - { - maxOffset = Math.Max( animatedScrollInfo.ExtentHeight - m_containerHeight, 0 ); - } - - double offset = Math.Max( m_verticalOffset, 0 ); - offset = Math.Min( m_verticalOffset, maxOffset ); - - if( offset != m_verticalOffset ) - { - this.SetVerticalOffsetCore( offset ); - this.AnimatedScrollInfo.TargetVerticalOffset = offset; - } - } - - private void ScrollByHorizontalOffset( double offset ) - { - this.ScrollByHorizontalOffset( offset, true ); - } - - private void ScrollByHorizontalOffset( double offset, bool animate ) - { - this.ScrollToHorizontalOffset( this.AnimatedScrollInfo.TargetHorizontalOffset + offset, animate ); - } - - private void ScrollToHorizontalOffset( double offset ) - { - this.ScrollToHorizontalOffset( offset, true ); - } - - private void ScrollToHorizontalOffset( double offset, bool animate ) - { - this.ScrollToHorizontalOffset( offset, animate, null ); - } - - private void ScrollToHorizontalOffset( double offset, bool animate, ScrollDirection? scrollingDirection ) - { - IAnimatedScrollInfo animatedScrollInfo = this.AnimatedScrollInfo; - - double maxOffset = Math.Max( animatedScrollInfo.ExtentWidth - animatedScrollInfo.ViewportWidth, 0 ); - offset = Math.Max( offset, 0 ); - offset = Math.Min( offset, maxOffset ); - - if( animatedScrollInfo.TargetHorizontalOffset == offset ) - return; - - double scrollChange = ( offset - animatedScrollInfo.TargetHorizontalOffset ); - - if( scrollingDirection.HasValue ) - { - animatedScrollInfo.HorizontalScrollingDirection = scrollingDirection.Value; - } - else if( scrollChange > 0 ) - { - animatedScrollInfo.HorizontalScrollingDirection = ScrollDirection.Forward; - } - else if( scrollChange == 0 ) - { - animatedScrollInfo.HorizontalScrollingDirection = ScrollDirection.None; - } - else - { - animatedScrollInfo.HorizontalScrollingDirection = ScrollDirection.Backward; - } - - animatedScrollInfo.OriginalHorizontalOffset = animatedScrollInfo.HorizontalOffset; - animatedScrollInfo.TargetHorizontalOffset = offset; - - bool animationStarted = false; - - if( animate ) - { - // The animated offset will take care of generating the - // page and invalidating the ScrollInfo. - animationStarted = this.StartHorizontalOffsetAnimation(); - } - - if( !animationStarted ) - { - if( this.CachedRootDataGridContext != null ) - { - this.StopHorizontalOffsetAnimation(); - this.SetHorizontalOffsetCore( offset ); - // No need to regenerate the page since only the horizontal offset have changed. - // We must, on the other hand, relayout the containers to reflect the new offsets. - this.LayoutContainers(); - this.InvalidateScrollInfo(); - } - - animatedScrollInfo.HorizontalScrollingDirection = ScrollDirection.None; - } - } - - private void SetHorizontalOffsetCore( double offset ) - { - if( m_horizontalOffset == offset ) - return; - - m_horizontalOffset = offset; - } - - private void ScrollByVerticalOffset( double offset ) - { - this.ScrollByVerticalOffset( offset, true ); - } - - private void ScrollByVerticalOffset( double offset, bool animate ) - { - this.ScrollToVerticalOffset( this.AnimatedScrollInfo.TargetVerticalOffset + offset, animate ); - } - - private void ScrollToVerticalOffset( double offset ) - { - this.ScrollToVerticalOffset( offset, true ); - } - - private void ScrollToVerticalOffset( double offset, bool animate ) - { - this.ScrollToVerticalOffset( offset, animate, null ); - } - - private void ScrollToVerticalOffset( double offset, bool animate, ScrollDirection? scrollingDirection ) - { - IAnimatedScrollInfo animatedScrollInfo = this.AnimatedScrollInfo; - - double maxOffset; - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - if( ( dataGridContext == null ) || ( TableView.GetAutoFillLastPage( dataGridContext ) ) ) - { - maxOffset = Math.Max( animatedScrollInfo.ExtentHeight - animatedScrollInfo.ViewportHeight, 0 ); - } - else - { - maxOffset = Math.Max( animatedScrollInfo.ExtentHeight - m_containerHeight, 0 ); - } - - offset = Math.Max( offset, 0 ); - offset = Math.Min( offset, maxOffset ); - - if( animatedScrollInfo.TargetVerticalOffset == offset ) - return; - - double scrollChange = ( offset - animatedScrollInfo.TargetVerticalOffset ); - - if( scrollingDirection.HasValue ) - { - animatedScrollInfo.VerticalScrollingDirection = scrollingDirection.Value; - } - else if( scrollChange > 0 ) - { - animatedScrollInfo.VerticalScrollingDirection = ScrollDirection.Forward; - } - else if( scrollChange == 0 ) - { - animatedScrollInfo.VerticalScrollingDirection = ScrollDirection.None; - } - else - { - animatedScrollInfo.VerticalScrollingDirection = ScrollDirection.Backward; - } - - animatedScrollInfo.OriginalVerticalOffset = animatedScrollInfo.VerticalOffset; - animatedScrollInfo.TargetVerticalOffset = offset; - - bool animationStarted = false; - - if( animate ) - { - // The animated offset will take care of generating the - // page and invalidating the ScrollInfo. - animationStarted = this.StartVerticalOffsetAnimation(); - } - - if( !animationStarted ) - { - if( this.CachedRootDataGridContext != null ) - { - this.StopVerticalOffsetAnimation( false ); - this.SetVerticalOffsetCore( offset ); - this.InvalidateLayoutFromScrollingHelper(); - } - - animatedScrollInfo.VerticalScrollingDirection = ScrollDirection.None; - animatedScrollInfo.HorizontalScrollingDirection = ScrollDirection.None; - } - } - - private void SetVerticalOffsetCore( double offset ) - { - if( m_verticalOffset == offset ) - return; - - m_verticalOffset = offset; - } - - private bool SetCurrent( int index, bool changeColumn ) - { - bool isDataRow; - return this.SetCurrent( index, changeColumn, out isDataRow ); - } - - private bool SetCurrent( int index, bool changeColumn, out bool isDataRow ) - { - var generator = this.CustomItemContainerGenerator; - var position = generator.GeneratorPositionFromIndex( index ); - var container = default( UIElement ); - - using( generator.StartAt( position, GeneratorDirection.Forward, true ) ) - { - container = this.GenerateContainer( generator, index, false, false ); - } - - isDataRow = false; - - if( container != null ) - { - isDataRow = ( container is DataRow ); - - if( ( m_layoutedContainers.IndexOfContainer( container ) < 0 ) - && ( m_stickyHeaders.IndexOfContainer( container ) < 0 ) - && ( m_stickyFooters.IndexOfContainer( container ) < 0 ) ) - { - // If the container was not already layouted, force - // a layout of the current page so that the new container - // is drawn at the right offset. - m_layoutedContainers.Add( new LayoutedContainerInfo( index, container ) ); - this.LayoutContainers(); - } - - var dataGridContext = DataGridControl.GetDataGridContext( container ); - var currentContext = dataGridContext.DataGridControl.CurrentContext; - var column = default( ColumnBase ); - - if( changeColumn ) - { - column = dataGridContext.CurrentColumn; - - if( isDataRow ) - { - if( ( currentContext != dataGridContext ) && dataGridContext.AreDetailsFlatten ) - { - column = dataGridContext.GetMatchingColumn( currentContext, currentContext.CurrentColumn ) ?? column; - } - - if( ( column == null ) || ( !column.CanBeCurrentWhenReadOnly && column.ReadOnly ) ) - { - var focusableIndex = NavigationHelper.GetFirstVisibleFocusableColumnIndex( dataGridContext ); - if( focusableIndex >= 0 ) - { - column = dataGridContext.VisibleColumns[ focusableIndex ]; - } - } - } - } - - try - { - if( currentContext != null ) - { - currentContext.EndEdit(); - } - } - catch( DataGridException ) - { - return false; - } - - var containerIndex = generator.GetRealizedIndexForContainer( container ); - if( containerIndex >= 0 ) - { - if( dataGridContext.DataGridControl.SetFocusHelper( container, column, true, true ) ) - { - generator.SetCurrentIndex( containerIndex ); - return true; - } - } - } - - return false; - } - - #endregion - - #region BringIntoView Methods - - private void OnRequestBringIntoView( object sender, RequestBringIntoViewEventArgs e ) - { - TableViewItemsHost.ProcessRequestBringIntoView( this, - Orientation.Vertical, - 0.5, // Default StableScrollingProportion - e ); - } - - private bool FocusContainerOrPreviousFocusable( UIElement focusedContainer, bool changeColumn ) - { - PageIndexes layoutedIndexes; - this.CalculateLayoutedIndexes( m_verticalOffset, this.AnimatedScrollInfo.ViewportHeight, out layoutedIndexes ); - - int firstIndex = 0; - int focusedIndex = this.CustomItemContainerGenerator.GetRealizedIndexForContainer( focusedContainer ); - int desiredIndex = focusedIndex - 1; - - System.Diagnostics.Debug.Assert( focusedIndex > -1, "How come the realized index is -1?!?" ); - - bool currentChanged = false; - - if( desiredIndex != focusedIndex ) - { - DataGridControl dataGridControl = this.ParentDataGridControl; - int cannotFocusCount = 0; - - // We want to find the first element that can receive focus upward. - while( ( desiredIndex >= 0 ) && ( !currentChanged ) ) - { - bool isDataRow; - currentChanged = this.SetCurrent( desiredIndex, changeColumn, out isDataRow ); - - if( !currentChanged ) - { - if( dataGridControl.HasValidationError ) - return false; - - if( isDataRow ) - { - cannotFocusCount++; - - if( cannotFocusCount > TableflowViewItemsHost.MaxDataRowFailFocusCount ) - return false; - } - } - - // We succeded in changing the current. - if( currentChanged ) - break; - - // We already are at the first index and still not focused on a new container. - if( desiredIndex == firstIndex ) - { - //Let's keep the focus on the last focused container. - currentChanged = this.SetCurrent( focusedIndex, changeColumn, out isDataRow ); - break; - } - - desiredIndex--; - } - - // We will use MoveFocus if the focused index is currently in view. - if( ( !currentChanged ) && ( focusedIndex >= layoutedIndexes.StartIndex ) && ( focusedIndex <= layoutedIndexes.EndIndex ) ) - { - currentChanged = this.MoveFocus( new TraversalRequest( FocusNavigationDirection.Up ) ); - } - } - - return currentChanged; - } - - private bool FocusIndexOrPreviousFocusable( int desiredIndex, int minimumIndex, bool changeColumn ) - { - bool currentChanged = false; - DataGridControl dataGridControl = this.ParentDataGridControl; - int cannotFocusCount = 0; - - // We want to find the first element that can receive focus upward. - while( ( desiredIndex >= 0 ) && ( !currentChanged ) ) - { - bool isDataRow; - currentChanged = this.SetCurrent( desiredIndex, changeColumn, out isDataRow ); - - if( !currentChanged ) - { - if( dataGridControl.HasValidationError ) - return false; - - if( isDataRow ) - { - cannotFocusCount++; - - if( cannotFocusCount > TableflowViewItemsHost.MaxDataRowFailFocusCount ) - return false; - } - } - - // We succeded in changing the current or we're already at the first index? Then nothing we can do. - if( ( currentChanged ) || ( desiredIndex == minimumIndex ) ) - break; - - desiredIndex--; - } - - return currentChanged; - } - - private bool FocusContainerOrNextFocusable( UIElement focusedContainer, bool changeColumn ) - { - PageIndexes layoutedIndexes; - this.CalculateLayoutedIndexes( m_verticalOffset, this.AnimatedScrollInfo.ViewportHeight, out layoutedIndexes ); - - int lastIndex = this.CustomItemContainerGenerator.ItemCount - 1; - int focusedIndex = this.CustomItemContainerGenerator.GetRealizedIndexForContainer( focusedContainer ); - int desiredIndex = focusedIndex + 1; - - System.Diagnostics.Debug.Assert( focusedIndex > -1, "How come the realized index is -1?!?" ); - - bool currentChanged = false; - - if( desiredIndex != focusedIndex ) - { - DataGridControl dataGridControl = this.ParentDataGridControl; - int cannotFocusCount = 0; - - // We want to find the first element that can receive focus downward. - while( ( desiredIndex <= lastIndex ) && ( !currentChanged ) ) - { - bool isDataRow; - currentChanged = this.SetCurrent( desiredIndex, changeColumn, out isDataRow ); - - if( !currentChanged ) - { - if( dataGridControl.HasValidationError ) - return false; - - if( isDataRow ) - { - cannotFocusCount++; - - if( cannotFocusCount > TableflowViewItemsHost.MaxDataRowFailFocusCount ) - return false; - } - } - - // We succeded in changing the current. - if( currentChanged ) - break; - - // We already are at the last index and still not focused on a new container. - if( desiredIndex == lastIndex ) - { - //Let's keep the focus on the last focused container. - currentChanged = this.SetCurrent( focusedIndex, changeColumn, out isDataRow ); - } - - desiredIndex++; - } - - // We will use MoveFocus if the focused index is currently in view. - if( ( !currentChanged ) && ( focusedIndex >= layoutedIndexes.StartIndex ) && ( focusedIndex <= layoutedIndexes.EndIndex ) ) - { - currentChanged = this.MoveFocus( new TraversalRequest( FocusNavigationDirection.Down ) ); - } - } - - return currentChanged; - } - - private bool FocusIndexOrNextFocusable( int desiredIndex, int maximumIndex, bool changeColumn ) - { - bool currentChanged = false; - DataGridControl dataGridControl = this.ParentDataGridControl; - int cannotFocusCount = 0; - - // We want to find the first element that can receive focus downward. - while( ( desiredIndex <= maximumIndex ) && ( !currentChanged ) ) - { - bool isDataRow; - currentChanged = this.SetCurrent( desiredIndex, changeColumn, out isDataRow ); - - if( !currentChanged ) - { - if( dataGridControl.HasValidationError ) - return false; - - if( isDataRow ) - { - cannotFocusCount++; - - if( cannotFocusCount > TableflowViewItemsHost.MaxDataRowFailFocusCount ) - return false; - } - } - - // We succeded in changing the current or we're already at the first index? Then nothing we can do. - if( ( currentChanged ) || ( desiredIndex == maximumIndex ) ) - break; - - desiredIndex++; - } - - return currentChanged; - } - - #endregion - - #region DataGridItemsHost Overrides - - protected override IList CreateChildCollection() - { - return new TableflowViewUIElementCollection( this ); - } - - protected override void OnItemsAdded() - { - this.PreventOpacityAnimation = true; - - // We are calling InvalidateMeasure to regenerate the current - // page and forcing the recycling of out-of-view containers. - this.InvalidateMeasure(); - } - - protected override void OnItemsRemoved( IList containers ) - { - this.PreventOpacityAnimation = true; - - // We are calling InvalidateMeasure to regenerate the current - // page and forcing the recycling of out-of-view containers. - this.InvalidateMeasure(); - } - - protected override void OnItemsReset() - { - // Everything will be recalculated and redrawn in the measure pass. - this.InvalidateMeasure(); - } - - protected override void OnContainersRemoved( IList removedContainers ) - { - foreach( UIElement element in removedContainers ) - { - this.RecycleContainer( element ); - - // Avoid checking if Children already contains - // the element. No exception will be thrown - // if the item is not found. This ensure to - // at parse all the children only 1 time as - // worst scenario - this.Children.Remove( element ); - - - int index = m_layoutedContainers.IndexOfContainer( element ); - if( index > -1 ) - { - m_layoutedContainers.RemoveAt( index ); - } - - index = m_stickyHeaders.IndexOfContainer( element ); - if( index > -1 ) - { - m_stickyHeaders.RemoveAt( index ); - } - - index = m_stickyFooters.IndexOfContainer( element ); - if( index > -1 ) - { - m_stickyFooters.RemoveAt( index ); - } - } - } - - protected override void OnParentDataGridControlChanged( DataGridControl oldValue, DataGridControl newValue ) - { - // Ensure to stop any animation since this ItemsHost - // is no more hosted in a DataGridControl - if( newValue == null ) - { - // Stop the AnimationClock for each offset property - this.StopVerticalOffsetAnimation(); - this.StopHorizontalOffsetAnimation(); - - // Ensure to clear any animation on offset property directly - this.ApplyAnimationClock( TableflowViewItemsHost.AnimatedVerticalOffsetProperty, null, HandoffBehavior.SnapshotAndReplace ); - this.ApplyAnimationClock( TableflowViewItemsHost.AnimatedHorizontalOffsetProperty, null, HandoffBehavior.SnapshotAndReplace ); - } - - base.OnParentDataGridControlChanged( oldValue, newValue ); - } - - protected override void OnRecyclingCandidatesCleaned( IList recyclingCandidates ) - { - foreach( UIElement candidate in recyclingCandidates ) - { - this.ClearContainer( candidate ); - } - } - - #endregion - - #region PreviewKeyDown and KeyDown Handling - - protected override void HandleTabKey( KeyEventArgs e ) - { - if( e.Handled ) - return; - - var dataGridControl = this.ParentDataGridControl; - if( dataGridControl == null ) - return; - - var dataGridContext = dataGridControl.CurrentContext; - if( dataGridContext == null ) - return; - - e.Handled = NavigationHelper.HandleTabKey( dataGridControl, dataGridContext, e.OriginalSource as FrameworkElement, e.KeyboardDevice ); - } - - protected override void HandleLeftKey( KeyEventArgs e ) - { - if( e.Handled ) - return; - - var dataGridControl = this.ParentDataGridControl; - if( dataGridControl == null ) - return; - - e.Handled = NavigationHelper.MoveFocusLeft( dataGridControl.CurrentContext ); - } - - protected override void HandleRightKey( KeyEventArgs e ) - { - if( e.Handled ) - return; - - var dataGridControl = this.ParentDataGridControl; - if( dataGridControl == null ) - return; - - e.Handled = NavigationHelper.MoveFocusRight( dataGridControl.CurrentContext ); - } - - protected override void HandleUpKey( KeyEventArgs e ) - { - if( e.Handled ) - return; - - e.Handled = this.MoveFocusUp(); - } - - protected override void HandleDownKey( KeyEventArgs e ) - { - if( e.Handled ) - return; - - e.Handled = this.MoveFocusDown(); - } - - protected override void HandlePageUpKey( KeyEventArgs e ) - { - if( e.Handled ) - return; - - e.Handled = true; - - DataGridControl dataGridControl = this.ParentDataGridControl; - NavigationBehavior navigationBehavior = dataGridControl.NavigationBehavior; - bool changeCurrentColumn = ( navigationBehavior == NavigationBehavior.CellOnly ); - - if( ( e.KeyboardDevice.Modifiers & ModifierKeys.Control ) == ModifierKeys.Control ) - { - this.MoveToFirstOverallUIElement( changeCurrentColumn ); - return; - } - - UIElement focusedContainer = DataGridItemsHost.GetItemsHostContainerFromElement( this, Keyboard.FocusedElement as DependencyObject ); - - if( ( focusedContainer == null ) || ( navigationBehavior == NavigationBehavior.None ) ) - { - // We just need to scroll one page up. - this.AnimatedScrollInfo.ScrollOwner.PageUp(); - return; - } - - int focusedContainerRealizedIndex = this.CustomItemContainerGenerator.GetRealizedIndexForContainer( focusedContainer ); - int desiredPageUpIndex = Math.Max( 0, focusedContainerRealizedIndex - m_pageVisibleContainerCount + 1 ); - int initialDesiredIndex = desiredPageUpIndex; - - if( focusedContainerRealizedIndex == 0 ) - { - this.MoveFocus( new TraversalRequest( FocusNavigationDirection.Up ) ); - } - else if( focusedContainerRealizedIndex != initialDesiredIndex ) - { - PageIndexes pageIndexes = this.CalculateVisibleIndexesForDesiredLastVisibleIndex( focusedContainerRealizedIndex ); - desiredPageUpIndex = Math.Max( 0, pageIndexes.StartIndex ); - initialDesiredIndex = desiredPageUpIndex; - bool isDataRow = false; - - // SetCurrent on the desired index or down until BEFORE the focused container. - while( ( !dataGridControl.HasValidationError ) && ( !isDataRow ) && ( desiredPageUpIndex < focusedContainerRealizedIndex ) ) - { - if( this.SetCurrent( desiredPageUpIndex, changeCurrentColumn, out isDataRow ) ) - return; - - desiredPageUpIndex++; - } - - if( ( dataGridControl.HasValidationError ) || ( isDataRow ) ) - return; - - // No container were focused while processing indexes from focused to initialDesiredIndex, try SetCurrent on indexes lower than the initial up to 0 - desiredPageUpIndex = initialDesiredIndex - 1; - isDataRow = false; - - while( ( !dataGridControl.HasValidationError ) && ( !isDataRow ) && ( desiredPageUpIndex > 0 ) ) - { - if( this.SetCurrent( desiredPageUpIndex, changeCurrentColumn, out isDataRow ) ) - return; - - desiredPageUpIndex--; - } - - // If not container was successfuly focused, set focus back to the current UIElement. - this.SetCurrent( focusedContainerRealizedIndex, changeCurrentColumn, out isDataRow ); - } - } - - protected override void HandlePageDownKey( KeyEventArgs e ) - { - if( e.Handled ) - return; - - e.Handled = true; - - DataGridControl dataGridControl = this.ParentDataGridControl; - NavigationBehavior navigationBehavior = dataGridControl.NavigationBehavior; - bool changeCurrentColumn = ( navigationBehavior == NavigationBehavior.CellOnly ); - - if( ( e.KeyboardDevice.Modifiers & ModifierKeys.Control ) == ModifierKeys.Control ) - { - this.MoveToLastOverallUIElement( changeCurrentColumn ); - return; - } - - UIElement focusedContainer = DataGridItemsHost.GetItemsHostContainerFromElement( this, Keyboard.FocusedElement as DependencyObject ); - - // No focused container or no navigation allowed - if( ( focusedContainer == null ) || ( navigationBehavior == NavigationBehavior.None ) ) - { - // We just need to scroll one page down. - this.AnimatedScrollInfo.ScrollOwner.PageDown(); - return; - } - - int generatorItemCount = this.CustomItemContainerGenerator.ItemCount; - int focusedContainerRealizedIndex = this.CustomItemContainerGenerator.GetRealizedIndexForContainer( focusedContainer ); - int maxIndex = generatorItemCount - 1; - int desiredPageDownIndex = Math.Min( generatorItemCount - 1, focusedContainerRealizedIndex + m_pageVisibleContainerCount - 1 ); - int initialDesiredIndex = desiredPageDownIndex; - - if( focusedContainerRealizedIndex == maxIndex ) - { - this.MoveFocus( new TraversalRequest( FocusNavigationDirection.Down ) ); - } - else if( focusedContainerRealizedIndex != initialDesiredIndex ) - { - PageIndexes pageIndexes = this.CalculateVisibleIndexesForDesiredFirstVisibleIndex( focusedContainerRealizedIndex ); - desiredPageDownIndex = Math.Min( maxIndex, pageIndexes.EndIndex ); - - initialDesiredIndex = desiredPageDownIndex; - - bool isDataRow = false; - - // SetCurrent on the desired index or up until BEFORE the focused container. - while( ( !dataGridControl.HasValidationError ) && ( !isDataRow ) && ( desiredPageDownIndex > focusedContainerRealizedIndex ) ) - { - if( this.SetCurrent( desiredPageDownIndex, changeCurrentColumn, out isDataRow ) ) - return; - - desiredPageDownIndex--; - } - - if( ( dataGridControl.HasValidationError ) || ( isDataRow ) ) - return; - - desiredPageDownIndex = initialDesiredIndex + 1; - isDataRow = false; - - // No container were focused while processing indexes from focused to initialDesiredIndex, try SetCurrent on indexes higher than the initial down to maxIndex - while( ( !dataGridControl.HasValidationError ) && ( !isDataRow ) && ( desiredPageDownIndex <= maxIndex ) ) - { - if( this.SetCurrent( desiredPageDownIndex, changeCurrentColumn, out isDataRow ) ) - return; - - desiredPageDownIndex++; - } - - // If not container was successfuly focused, set focus back to the current UIElement. - this.SetCurrent( focusedContainerRealizedIndex, changeCurrentColumn, out isDataRow ); - } - } - - protected override void HandleHomeKey( KeyEventArgs e ) - { - if( e.Handled ) - return; - - if( ( e.KeyboardDevice.Modifiers & ModifierKeys.Control ) == ModifierKeys.Control ) - { - DataGridControl dataGridControl = this.ParentDataGridControl; - IAnimatedScrollInfo scrollInfo = this.AnimatedScrollInfo; - NavigationBehavior navigationBehavior = dataGridControl.NavigationBehavior; - bool changeCurrentColumn = ( navigationBehavior == NavigationBehavior.CellOnly ); - - if( navigationBehavior != NavigationBehavior.None ) - { - this.MoveToFirstOverallUIElement( changeCurrentColumn ); - - if( navigationBehavior == NavigationBehavior.CellOnly ) - { - this.MoveToFirstVisibleColumn(); - } - } - else - { - scrollInfo.ScrollOwner.ScrollToTop(); - } - - // In all cases, we must scroll to the left end of the panel. - scrollInfo.ScrollOwner.ScrollToLeftEnd(); - } - else - { - // This should be handled by a parent. - return; - } - - e.Handled = true; - } - - protected override void HandleEndKey( KeyEventArgs e ) - { - if( e.Handled ) - return; - - if( ( e.KeyboardDevice.Modifiers & ModifierKeys.Control ) == ModifierKeys.Control ) - { - DataGridControl dataGridControl = this.ParentDataGridControl; - IAnimatedScrollInfo scrollInfo = this.AnimatedScrollInfo; - NavigationBehavior navigationBehavior = dataGridControl.NavigationBehavior; - bool changeCurrentColumn = ( navigationBehavior == NavigationBehavior.CellOnly ); - - if( navigationBehavior != NavigationBehavior.None ) - { - this.MoveToLastOverallUIElement( changeCurrentColumn ); - - if( navigationBehavior == NavigationBehavior.CellOnly ) - { - this.MoveToLastVisibleColumn(); - } - } - else - { - scrollInfo.ScrollOwner.ScrollToBottom(); - } - - // In all cases, we must scroll to the right end of the panel. - scrollInfo.ScrollOwner.ScrollToRightEnd(); - } - else - { - // This should be handled by a parent. - return; - } - - e.Handled = true; - } - - private void MoveToFirstOverallUIElement( bool changeCurrentColumn ) - { - // Simply scroll to top. - this.AnimatedScrollInfo.ScrollOwner.ScrollToTop(); - - //Try to focus on first UIElement. - if( !this.SetCurrent( 0, changeCurrentColumn ) ) - { - //If not focusable, find the next one downward. - CustomItemContainerGenerator generator = this.CustomItemContainerGenerator as CustomItemContainerGenerator; - this.FocusIndexOrNextFocusable( 1, generator.RealizedContainers.Count - 1, changeCurrentColumn ); - } - } - - private void MoveToLastOverallUIElement( bool changeCurrentColumn ) - { - // Simply scroll to end - this.AnimatedScrollInfo.ScrollOwner.ScrollToBottom(); - - CustomItemContainerGenerator generator = this.CustomItemContainerGenerator as CustomItemContainerGenerator; - int lastItemIndex = generator.ItemCount - 1; - - //Try to focus on last UIElement. - if( !this.SetCurrent( lastItemIndex, changeCurrentColumn ) ) - { - //If not focusable, find the next one upward. - int minimumIndex = lastItemIndex - generator.RealizedContainers.Count; - this.FocusIndexOrPreviousFocusable( lastItemIndex, minimumIndex, changeCurrentColumn ); - } - } - - private void MoveToFirstVisibleColumn() - { - DataGridControl dataGridControl = this.ParentDataGridControl; - - if( dataGridControl == null ) - return; - - DataGridContext currentDataGridContext = dataGridControl.CurrentContext; - ReadOnlyColumnCollection visibleColumnsCollection = ( ReadOnlyColumnCollection )currentDataGridContext.VisibleColumns; - - int visibleColumnsCollectionCount = visibleColumnsCollection.Count; - - // The previous SetCurrent will only select the first row. The CurrentColumn - // is left unchanged. We must set the current column to the first one. - - if( ( currentDataGridContext != null ) && ( visibleColumnsCollectionCount > 0 ) ) - { - int firstVisibleFocusableColumnIndex; - bool focusableColumnFound = false; - - Row currentRow = currentDataGridContext.CurrentRow; - - if( currentRow != null ) - { - for( firstVisibleFocusableColumnIndex = 0; firstVisibleFocusableColumnIndex < visibleColumnsCollectionCount; firstVisibleFocusableColumnIndex++ ) - { - if( currentRow.Cells[ visibleColumnsCollection[ firstVisibleFocusableColumnIndex ] ].GetCalculatedCanBeCurrent() ) - { - focusableColumnFound = true; - break; - } - } - - if( focusableColumnFound ) - { - try - { - currentDataGridContext.SetCurrentColumnAndChangeSelection( - currentDataGridContext.VisibleColumns[ firstVisibleFocusableColumnIndex ] ); - } - catch( DataGridException ) - { - // We swallow the exception if it occurs because of a validation error or Cell was read-only or - // any other GridException. - } - } - } - } - } - - private void MoveToLastVisibleColumn() - { - DataGridControl dataGridControl = this.ParentDataGridControl; - - if( dataGridControl == null ) - return; - - DataGridContext currentDataGridContext = dataGridControl.CurrentContext; - ReadOnlyColumnCollection visibleColumnsCollection = ( ReadOnlyColumnCollection )currentDataGridContext.VisibleColumns; - - int visibleColumnsCollectionCount = visibleColumnsCollection.Count; - - // The previous SetCurrent will only select the first row. The CurrentColumn - // is left unchanged. We must set the current column to the last one. - - if( ( visibleColumnsCollection != null ) && ( visibleColumnsCollectionCount > 0 ) ) - { - bool focusableColumnFound = false; - int lastVisibleFocusableColumnIndex; - - Row currentRow = currentDataGridContext.CurrentRow; - - if( currentRow != null ) - { - for( lastVisibleFocusableColumnIndex = visibleColumnsCollectionCount - 1; lastVisibleFocusableColumnIndex >= 0; lastVisibleFocusableColumnIndex-- ) - { - if( currentRow.Cells[ visibleColumnsCollection[ lastVisibleFocusableColumnIndex ] ].GetCalculatedCanBeCurrent() ) - { - focusableColumnFound = true; - break; - } - } - - if( focusableColumnFound ) - { - try - { - currentDataGridContext.SetCurrentColumnAndChangeSelection( - currentDataGridContext.VisibleColumns[ lastVisibleFocusableColumnIndex ] ); - } - catch( DataGridException ) - { - // We swallow the exception if it occurs because of a validation error or Cell was read-only or - // any other GridException. - } - } - } - } - } - - private void ResetHorizontalOffset() - { - ScrollViewer parentScrollViewer = this.m_scrollOwner; - - if( parentScrollViewer != null ) - parentScrollViewer.ScrollToHorizontalOffset( 0d ); - } - - #endregion - - #region IAnimatedScrollInfo Members - - ScrollDirection IAnimatedScrollInfo.HorizontalScrollingDirection - { - get; - set; - } - - double IAnimatedScrollInfo.OriginalHorizontalOffset - { - get; - set; - } - - double IAnimatedScrollInfo.TargetHorizontalOffset - { - get; - set; - } - - ScrollDirection IAnimatedScrollInfo.VerticalScrollingDirection - { - get; - set; - } - - double IAnimatedScrollInfo.OriginalVerticalOffset - { - get; - set; - } - - double IAnimatedScrollInfo.TargetVerticalOffset - { - get; - set; - } - - #endregion - - #region ICustomVirtualizingPanel Members - - protected override void BringIntoViewCore( int index ) - { - m_delayedBringIntoViewIndex = index; - this.InvalidateMeasure(); - } - - private void DelayedBringIntoView() - { - if( m_delayedBringIntoViewIndex == -1 ) - return; - - double itemOffset = ( m_delayedBringIntoViewIndex * m_containerHeight ); - - bool areHeadersSticky = this.AreHeadersStickyCache || this.AreParentRowsStickyCache || this.AreGroupHeadersStickyCache; - int stickyHeadersCount = ( areHeadersSticky ) ? this.GetStickyHeaderCountForIndex( m_delayedBringIntoViewIndex ) : 0; - - double stickyHeadersHeight = stickyHeadersCount * m_containerHeight; - double topThreshold = m_verticalOffset + stickyHeadersHeight; - - if( itemOffset < topThreshold ) - { - this.ScrollToVerticalOffset( itemOffset - stickyHeadersHeight ); - return; - } - - bool areFootersSticky = this.AreFootersStickyCache || this.AreGroupFootersStickyCache; - int stickyFootersCount = ( areFootersSticky ) ? this.GetStickyFooterCountForIndex( m_delayedBringIntoViewIndex ) : 0; - - double stickyFootersHeight = stickyFootersCount * m_containerHeight; - double bottomThreshold = ( m_verticalOffset + m_viewportHeight ) - stickyHeadersHeight - stickyFootersHeight; - - if( itemOffset + m_containerHeight > bottomThreshold ) - { - this.ScrollToVerticalOffset( itemOffset - ( m_viewportHeight - stickyFootersHeight - m_containerHeight ) ); - } - - } - - #endregion - - #region IScrollInfo Members - - bool IScrollInfo.CanHorizontallyScroll - { - get; - set; - } - - bool IScrollInfo.CanVerticallyScroll - { - get; - set; - } - - double IScrollInfo.ExtentHeight - { - get - { - return ( this.CachedRootDataGridContext != null ) ? ( this.CustomItemContainerGenerator.ItemCount * m_containerHeight ) : 0; - } - } - - private double m_extentWidth; - double IScrollInfo.ExtentWidth - { - get - { - return m_extentWidth; - } - } - - private double m_horizontalOffset; - double IScrollInfo.HorizontalOffset - { - get - { - return m_horizontalOffset; - } - } - - void IScrollInfo.SetHorizontalOffset( double offset ) - { - if( offset == m_horizontalOffset ) - return; - - DataGridScrollViewer scrollViewer = this.AnimatedScrollInfo.ScrollOwner as DataGridScrollViewer; - - // The ScrollToHorizontalOffset method is called by the scroll viewer when the thumb is dragged and when - // the user right-click and choose "Scroll to here", "Scroll to bottom" or "Scroll to top". - // When this method is called, we only want to animate if the called wasn't made by dragging the thumb. - // We also validate if our parent ScrollViewer is a DataGridScrollViewer because for now, we cannot - // have a reference to the Thumb to see is the mouse is captured. - bool animate = - ( ( scrollViewer != null ) - && ( scrollViewer.HorizontalScrollBar != null ) - && ( scrollViewer.HorizontalScrollBar.Track != null ) - && ( scrollViewer.HorizontalScrollBar.Track.Thumb != null ) - && ( !scrollViewer.HorizontalScrollBar.Track.Thumb.IsMouseCaptureWithin ) ); - - this.ScrollToHorizontalOffset( offset, animate ); - } - - private ScrollViewer m_scrollOwner; - ScrollViewer IScrollInfo.ScrollOwner - { - get - { - return m_scrollOwner; - } - set - { - - - - m_scrollOwner = value; - - - } - } - - private double m_verticalOffset; - double IScrollInfo.VerticalOffset - { - get - { - return m_verticalOffset; - } - } - - void IScrollInfo.SetVerticalOffset( double offset ) - { - if( offset == m_verticalOffset ) - return; - - DataGridScrollViewer scrollViewer = this.AnimatedScrollInfo.ScrollOwner as DataGridScrollViewer; - - // The SetVerticalOffset method is called by the scroll viewer when the thumb is dragged and when - // the user right-click and choose "Scroll to here", "Scroll to bottom" or "Scroll to top". - // When this method is called, we only want to animate if the called wasn't made by dragging the thumb. - // We also validate if our parent ScrollViewer is a DataGridScrollViewer because for now, we cannot - // have a reference to the Thumb to see is the mouse is captured. - bool animate = - ( ( scrollViewer != null ) - && ( scrollViewer.VerticalScrollBar != null ) - && ( scrollViewer.VerticalScrollBar.Track != null ) - && ( scrollViewer.VerticalScrollBar.Track.Thumb != null ) - && ( !scrollViewer.VerticalScrollBar.Track.Thumb.IsMouseCaptureWithin ) ); - - this.ScrollToVerticalOffset( offset, animate ); - } - - private double m_viewportHeight; - double IScrollInfo.ViewportHeight - { - get - { - return m_viewportHeight; - } - } - - private double m_viewportWidth; - double IScrollInfo.ViewportWidth - { - get - { - return m_viewportWidth; - } - } - - void IScrollInfo.LineDown() - { - this.ScrollByVerticalOffset( m_containerHeight ); - } - - void IScrollInfo.LineLeft() - { - this.ScrollByHorizontalOffset( ScrollViewerHelper.PixelScrollingCount * -1 ); - } - - void IScrollInfo.LineRight() - { - this.ScrollByHorizontalOffset( ScrollViewerHelper.PixelScrollingCount ); - } - - void IScrollInfo.LineUp() - { - this.ScrollByVerticalOffset( m_containerHeight * -1 ); - } - - void IScrollInfo.MouseWheelDown() - { - this.ScrollByVerticalOffset( SystemParameters.WheelScrollLines * m_containerHeight ); - } - - void IScrollInfo.MouseWheelLeft() - { - this.ScrollByHorizontalOffset( SystemParameters.WheelScrollLines * ScrollViewerHelper.PixelScrollingCount * -1 ); - } - - void IScrollInfo.MouseWheelRight() - { - this.ScrollByHorizontalOffset( SystemParameters.WheelScrollLines * ScrollViewerHelper.PixelScrollingCount ); - } - - void IScrollInfo.MouseWheelUp() - { - this.ScrollByVerticalOffset( SystemParameters.WheelScrollLines * m_containerHeight * -1 ); - } - - void IScrollInfo.PageDown() - { - this.ScrollByVerticalOffset( this.AnimatedScrollInfo.ViewportHeight ); - } - - void IScrollInfo.PageLeft() - { - this.ScrollByHorizontalOffset( this.AnimatedScrollInfo.ViewportWidth * -1 ); - } - - void IScrollInfo.PageRight() - { - this.ScrollByHorizontalOffset( this.AnimatedScrollInfo.ViewportWidth ); - } - - void IScrollInfo.PageUp() - { - this.ScrollByVerticalOffset( this.AnimatedScrollInfo.ViewportHeight * -1 ); - } - - Rect IScrollInfo.MakeVisible( Visual visual, Rect rectangle ) - { - UIElement container = DataGridItemsHost.GetItemsHostContainerFromElement( this, visual ); - - if( container != null ) - { - rectangle = visual.TransformToAncestor( container ).TransformBounds( rectangle ); - - // Make sure that the item is vertically visible. - ICustomItemContainerGenerator generator = this.CustomItemContainerGenerator; - - if( generator != null ) - { - int itemIndex = generator.GetRealizedIndexForContainer( container ); - - if( itemIndex != -1 ) - { - // If the container is already layouted and no Clip applied, nothing to make visible - if( !m_layoutedContainers.ContainsRealizedIndex( itemIndex ) - || ( container.Clip != null ) ) - { - // This will make sure to scroll to the right offsets. - ICustomVirtualizingPanel virtualizingPanel = ( ICustomVirtualizingPanel )this; - virtualizingPanel.BringIntoView( itemIndex ); - } - } - } - } - - // Make sure that the item is horizontally visible. - IAnimatedScrollInfo animatedScrollInfo = this.AnimatedScrollInfo; - - if( rectangle.Left < animatedScrollInfo.HorizontalOffset ) - { - this.ScrollToHorizontalOffset( rectangle.Left ); - } - else if( rectangle.Right > animatedScrollInfo.HorizontalOffset + animatedScrollInfo.ViewportWidth ) - { - this.ScrollToHorizontalOffset( - Math.Min( rectangle.Left, ( rectangle.Right - animatedScrollInfo.ViewportWidth ) ) ); - } - - return rectangle; - } - - #endregion - - #region IDeferableScrollInfoRefresh Members - - IDisposable IDeferableScrollInfoRefresh.DeferScrollInfoRefresh( Orientation orientation ) - { - if( ( orientation == Orientation.Vertical ) && !this.IsDeferredLoadingEnabledCache ) - return new LayoutSuspendedHelper( this ); - - return null; - } - - #endregion - - private static void MoveFocusForwardExecuted( object sender, ExecutedRoutedEventArgs e ) - { - var itemsHost = ( TableflowViewItemsHost )sender; - var dataGridControl = itemsHost.ParentDataGridControl; - if( dataGridControl == null ) - return; - - e.Handled = NavigationHelper.MoveFocusRight( dataGridControl.CurrentContext ); - } - - private static void MoveFocusForwardCanExecute( object sender, CanExecuteRoutedEventArgs e ) - { - e.CanExecute = true; - e.Handled = true; - } - - private static void MoveFocusBackExecuted( object sender, ExecutedRoutedEventArgs e ) - { - var itemsHost = ( TableflowViewItemsHost )sender; - var dataGridControl = itemsHost.ParentDataGridControl; - if( dataGridControl == null ) - return; - - e.Handled = NavigationHelper.MoveFocusLeft( dataGridControl.CurrentContext ); - } - - private static void MoveFocusBackCanExecute( object sender, CanExecuteRoutedEventArgs e ) - { - e.CanExecute = true; - e.Handled = true; - } - - private static void MoveFocusUpExecuted( object sender, ExecutedRoutedEventArgs e ) - { - e.Handled = ( ( TableflowViewItemsHost )sender ).MoveFocusUp(); - } - - private static void MoveFocusUpCanExecute( object sender, CanExecuteRoutedEventArgs e ) - { - e.CanExecute = true; - e.Handled = true; - } - - private static void MoveFocusDownExecuted( object sender, ExecutedRoutedEventArgs e ) - { - e.Handled = ( ( TableflowViewItemsHost )sender ).MoveFocusDown(); - } - - private static void MoveFocusDownCanExecute( object sender, CanExecuteRoutedEventArgs e ) - { - e.CanExecute = true; - e.Handled = true; - } - - private bool MoveFocusUp() - { - DataGridControl dataGridControl = this.ParentDataGridControl; - UIElement focusedContainer = DataGridItemsHost.GetItemsHostContainerFromElement( this, Keyboard.FocusedElement as DependencyObject ); - - NavigationBehavior navigationBehavior = dataGridControl.NavigationBehavior; - bool changeCurrentColumn = ( navigationBehavior == NavigationBehavior.CellOnly ); - - if( ( focusedContainer == null ) || - ( navigationBehavior == NavigationBehavior.None ) ) - { - // We just need to scroll one line up. - this.AnimatedScrollInfo.ScrollOwner.LineUp(); - } - else - { - this.FocusContainerOrPreviousFocusable( focusedContainer, changeCurrentColumn ); - } - - return true; - } - - private bool MoveFocusDown() - { - DataGridControl dataGridControl = this.ParentDataGridControl; - UIElement focusedContainer = DataGridItemsHost.GetItemsHostContainerFromElement( this, Keyboard.FocusedElement as DependencyObject ); - - NavigationBehavior navigationBehavior = dataGridControl.NavigationBehavior; - bool changeCurrentColumn = ( navigationBehavior == NavigationBehavior.CellOnly ); - - if( ( focusedContainer == null ) || - ( navigationBehavior == NavigationBehavior.None ) ) - { - // We just need to scroll one line down. - this.AnimatedScrollInfo.ScrollOwner.LineDown(); - } - else - { - this.FocusContainerOrNextFocusable( focusedContainer, changeCurrentColumn ); - } - - return true; - } - - private void InvalidateLayoutFromScrollingHelper() - { - if( m_layoutSuspended.IsSet ) - { - m_layoutInvalidatedDuringSuspend = true; - return; - } - - this.GeneratePage( false, this.AnimatedScrollInfo.ViewportHeight ); - this.InvalidateArrange(); - this.InvalidateScrollInfo(); - } - - private const int MaxDataRowFailFocusCount = 50; - private static readonly Point OutOfViewPoint = new Point( -999999, -999999 ); - private static readonly Point EmptyPoint = new Point( 0, 0 ); - - private readonly LayoutedContainerInfoList m_layoutedContainers = new LayoutedContainerInfoList(); - private readonly StickyContainerInfoList m_stickyHeaders = new StickyContainerInfoList(); - private readonly StickyContainerInfoList m_stickyFooters = new StickyContainerInfoList(); - - private int m_pageVisibleContainerCount; - - private OffsetAnimation m_horizontalOffsetAnimation; - private AnimationClock m_horizontalOffsetAnimationClock; - - private OffsetAnimation m_verticalOffsetAnimation; - private AnimationClock m_verticalOffsetAnimationClock; - - private PageIndexes m_lastVisiblePageIndexes = PageIndexes.Empty; - - private readonly Dictionary m_cachedContainerDesiredWidth = new Dictionary(); - private readonly Dictionary m_cachedContainerRealDesiredWidth = new Dictionary(); - - private readonly List m_autoWidthCalculatedDataGridContextList = new List(); - - private int m_delayedBringIntoViewIndex = -1; - - private Size m_lastMeasureAvailableSize = Size.Empty; - private Size m_lastArrangeFinalSize = Size.Empty; - - private double m_containerHeight; - - private BitVector32 m_flags = new BitVector32(); - - private AutoResetFlag m_layoutSuspended = AutoResetFlagFactory.Create( false ); - private bool m_layoutInvalidatedDuringSuspend; - - #region TableflowItemsHostFlags Private Enum - - [Flags] - private enum TableflowItemsHostFlags - { - AreHeadersSticky = 1, - AreFootersSticky = 2, - AreGroupHeadersSticky = 4, - AreGroupFootersSticky = 8, - AreParentRowSticky = 16, - PreventOpacityAnimation = 32, - IsDeferredLoadingEnabled = 64, - } - - #endregion - - #region PageIndexes Private Class - - private class PageIndexes - { - public PageIndexes() - { - } - - public PageIndexes( int startIndex, int endIndex ) - { - this.StartIndex = startIndex; - this.EndIndex = endIndex; - } - - public int StartIndex - { - get; - set; - } - public int EndIndex - { - get; - set; - } - - private static PageIndexes _empty; - public static PageIndexes Empty - { - get - { - if( _empty == null ) - _empty = new PageIndexes( -1, -1 ); - - return _empty; - } - } - - public override bool Equals( object obj ) - { - PageIndexes pageIndexes = obj as PageIndexes; - - if( pageIndexes == null ) - return false; - - return ( pageIndexes.StartIndex == this.StartIndex ) - && ( pageIndexes.EndIndex == this.EndIndex ); - } - - public override int GetHashCode() - { - return ( this.StartIndex ^ this.EndIndex ); - } - - public static bool operator ==( PageIndexes objA, PageIndexes objB ) - { - return object.Equals( objA, objB ); - } - - public static bool operator !=( PageIndexes objA, PageIndexes objB ) - { - return !object.Equals( objA, objB ); - } - } - - #endregion - - #region LayoutSuspendedHelper Private Class - - private sealed class LayoutSuspendedHelper : IDisposable - { - public LayoutSuspendedHelper( TableflowViewItemsHost owner ) - { - if( owner == null ) - throw new ArgumentNullException( "owner" ); - - m_owner = owner; - m_disposable = owner.m_layoutSuspended.Set(); - } - - void IDisposable.Dispose() - { - this.Dispose( true ); - GC.SuppressFinalize( this ); - } - - private void Dispose( bool disposing ) - { - var owner = Interlocked.Exchange( ref m_owner, null ); - if( owner == null ) - return; - - if( m_disposable != null ) - { - m_disposable.Dispose(); - m_disposable = null; - } - - if( !owner.m_layoutSuspended.IsSet && owner.m_layoutInvalidatedDuringSuspend ) - { - owner.InvalidateMeasure(); - } - } - - ~LayoutSuspendedHelper() - { - this.Dispose( false ); - } - - private TableflowViewItemsHost m_owner; - private IDisposable m_disposable; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/TableflowViewUIElementCollection.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/TableflowViewUIElementCollection.cs deleted file mode 100644 index ce4936a1..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/TableflowViewUIElementCollection.cs +++ /dev/null @@ -1,225 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows; -using System.Windows.Media; -using System.Collections; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal class TableflowViewUIElementCollection : IList - { - #region CONSTRUCTORS - - public TableflowViewUIElementCollection( UIElement visualParent ) - { - if( visualParent == null ) - throw new ArgumentNullException( "visualParent" ); - - m_visualCollection = new VisualCollection( visualParent ); - } - - #endregion CONSTRUCTORS - - #region IList Members - - public int IndexOf( UIElement item ) - { - return m_visualCollection.IndexOf( item ); - } - - public void Insert( int index, UIElement item ) - { - if( item == null ) - throw new ArgumentNullException( "item" ); - - m_visualCollection.Insert( index, item ); - } - - public void RemoveAt( int index ) - { - m_visualCollection.RemoveAt( index ); - } - - public UIElement this[ int index ] - { - get - { - return m_visualCollection[ index ] as UIElement; - } - set - { - if( value == null ) - throw new ArgumentNullException( "value" ); - - if( m_visualCollection[ index ] == value ) - return; - - m_visualCollection[ index ] = value; - } - } - - #endregion - - #region ICollection Members - - public void Add( UIElement item ) - { - if( item == null ) - throw new ArgumentNullException( "item" ); - - m_visualCollection.Add( item ); - } - - public void Clear() - { - m_visualCollection.Clear(); - } - - public bool Contains( UIElement item ) - { - if( item == null ) - throw new ArgumentNullException( "item" ); - - return m_visualCollection.Contains( item ); - } - - public void CopyTo( UIElement[] array, int arrayIndex ) - { - m_visualCollection.CopyTo( array, arrayIndex ); - } - - public int Count - { - get - { - return m_visualCollection.Count; - } - } - - public bool IsReadOnly - { - get - { - return m_visualCollection.IsReadOnly; - } - } - - public bool Remove( UIElement item ) - { - if( item == null ) - throw new ArgumentNullException( "item" ); - - if( m_visualCollection.Contains( item ) ) - { - m_visualCollection.Remove( item ); - return true; - } - - return false; - } - - #endregion - - #region IEnumerable Members - - public IEnumerator GetEnumerator() - { - return new Enumerator( m_visualCollection.GetEnumerator() ); - } - - #endregion - - #region IEnumerable Members - - IEnumerator IEnumerable.GetEnumerator() - { - return m_visualCollection.GetEnumerator(); - } - - #endregion - - #region PRIVATE FIELDS - - private VisualCollection m_visualCollection; - - #endregion PRIVATE FIELDS - - #region Enumerator Private Class - - private class Enumerator : IEnumerator - { - public Enumerator( IEnumerator nonGenericEnumerator ) - { - if( nonGenericEnumerator == null ) - throw new ArgumentNullException( "nonGenericEnumerator" ); - - m_enumerator = nonGenericEnumerator; - } - - #region IEnumerator Members - - UIElement IEnumerator.Current - { - get - { - return m_enumerator.Current as UIElement; - } - } - - #endregion - - #region IDisposable Members - - void IDisposable.Dispose() - { - // Nothing to do - } - - #endregion - - #region IEnumerator Members - - object IEnumerator.Current - { - get - { - return m_enumerator.Current; - } - } - - bool IEnumerator.MoveNext() - { - return m_enumerator.MoveNext(); - } - - void IEnumerator.Reset() - { - m_enumerator.Reset(); - } - - #endregion - - IEnumerator m_enumerator; - } - - #endregion Enumerator Private Class - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/ZOrderHelper.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/ZOrderHelper.cs deleted file mode 100644 index 288447e4..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/(TableflowView)/ZOrderHelper.cs +++ /dev/null @@ -1,99 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Collections; -using System.Windows; -using System.Windows.Controls; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal class ZOrderHelper - { - /// The Children of the Panel - /// The int[] of ZOrder mapping - /// True if a mapping was performed, false if nothing changed - public static bool ComputeZOrder( IList children, ref int[] zIndexMapping ) - { - if( children == null ) - { - return false; - } - - int count = children.Count; - List tempList = new List( count ); - - bool needMapping = false; - - if( count > 0 ) - { - UIElement element = children[ 0 ] as UIElement; - - int zIndex = ( element != null ) - ? Panel.GetZIndex( element ) - : 0; - - tempList.Add( ( long )zIndex << 32 ); - - if( count > 1 ) - { - int currentItemIndex = 1; - int lastZIndex = zIndex; - - do - { - element = children[ currentItemIndex ] as UIElement; - - zIndex = ( element != null ) - ? Panel.GetZIndex( element ) - : 0; - - tempList.Add( ( ( long )zIndex << 32 ) + currentItemIndex ); - - needMapping |= ( zIndex < lastZIndex ); - lastZIndex = zIndex; - } - while( ++currentItemIndex < count ); - } - } - - - if( needMapping ) - { - tempList.Sort(); - - if( ( zIndexMapping == null ) || ( zIndexMapping.Length != count ) ) - { - zIndexMapping = new int[ children.Count ]; - } - - for( int i = 0; i < count; i++ ) - { - zIndexMapping[ i ] = ( int )( tempList[ i ] & 0xFFFFFFFFL ); - } - } - else - { - zIndexMapping = null; - } - - return needMapping; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/ColumnStretchingManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/ColumnStretchingManager.cs deleted file mode 100644 index 65423907..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/ColumnStretchingManager.cs +++ /dev/null @@ -1,332 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Diagnostics; -using System.Windows; -using System.Windows.Controls; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal class ColumnStretchingManager - { - public ColumnStretchingManager( DataGridContext dataGridContext ) - { - if( dataGridContext == null ) - throw new ArgumentNullException( "dataGridContext" ); - - m_dataGridContext = dataGridContext; - } - - #region ColumnStretchingCalculated Property - - private bool m_columnStretchingCalculated = false; - - /// - /// This property is useful in the case where the first row(s) are not measured - /// (collapsed, for instance). The code that calls the Measure with a restricted - /// size should set this property to false and check if it is true after having - /// called Measure on the Row. - /// - public bool ColumnStretchingCalculated - { - get - { - return m_columnStretchingCalculated; - } - - set - { - m_columnStretchingCalculated = value; - } - } - - #endregion ColumnStretchingCalculated Property - - public void DisableColumnStretching() - { - m_columnStretchingDisabled = true; - - foreach( ColumnBase column in m_dataGridContext.Columns ) - { - if( column.ReadLocalValue( ColumnBase.DesiredWidthProperty ) != DependencyProperty.UnsetValue ) - { - column.Width = new ColumnWidth( column.DesiredWidth ); - // Necessary to enable column sizing for Stretch First/Last/All. - column.ClearValue( ColumnBase.DesiredWidthProperty ); - } - } - } - - public void CalculateColumnStretchWidths( double widthToDistribute, ColumnStretchMode columnStretchMode, double columnStretchMinWidth, bool canIncreaseColumnWidth ) - { - if( m_columnStretchingDisabled ) - return; - - int currentDataGridScrollViewerMeasureVersion = 0; - DataGridControl dataGridControl = m_dataGridContext.DataGridControl; - - if( dataGridControl != null ) - { - DataGridScrollViewer scrollViewer = dataGridControl.ScrollViewer as DataGridScrollViewer; - - if( scrollViewer != null ) - { - currentDataGridScrollViewerMeasureVersion = scrollViewer.MeasureVersion; - } - } - - this.ColumnStretchingCalculated = true; - - if( m_dataGridScrollViewerMeasureVersion != currentDataGridScrollViewerMeasureVersion ) - { - // Reset the widthToDistribute since we are in a new pass of measure in the DataGridScrollViewer - m_widthToDistribute = widthToDistribute; - m_dataGridScrollViewerMeasureVersion = currentDataGridScrollViewerMeasureVersion; - } - else - { - if( widthToDistribute >= m_widthToDistribute ) - { - widthToDistribute = m_widthToDistribute; - } - else - { - m_widthToDistribute = widthToDistribute; - } - } - - List excludedColumns = null; - ColumnBase stretchedColumn = null; - ReadOnlyObservableCollection visibleColumns = m_dataGridContext.VisibleColumns; - - if( visibleColumns.Count == 0 ) - return; - - switch( columnStretchMode ) - { - case ColumnStretchMode.First: - stretchedColumn = visibleColumns[ 0 ]; - excludedColumns = new List( 1 ); - break; - - case ColumnStretchMode.Last: - stretchedColumn = visibleColumns[ visibleColumns.Count - 1 ]; - excludedColumns = new List( 1 ); - break; - - case ColumnStretchMode.All: - excludedColumns = new List( visibleColumns.Count ); - foreach( ColumnBase column in visibleColumns ) - { - excludedColumns.Add( new WorkingColumnWidth( column, 1d, columnStretchMinWidth ) ); - } - break; - - case ColumnStretchMode.None: - foreach( ColumnBase column in visibleColumns ) - { - if( column.Width.UnitType == ColumnWidthUnitType.Star ) - { - if( excludedColumns == null ) - excludedColumns = new List(); - - excludedColumns.Add( new WorkingColumnWidth( column, column.Width.Value, columnStretchMinWidth ) ); - } - else - { - column.ClearValue( Column.DesiredWidthProperty ); - widthToDistribute -= column.ActualWidth; - } - } - break; - } - - if( excludedColumns != null ) - { - if( stretchedColumn != null ) - { - foreach( ColumnBase column in visibleColumns ) - { - if( column == stretchedColumn ) - { - excludedColumns.Add( new WorkingColumnWidth( column, 1, columnStretchMinWidth ) ); - } - else - { - column.ClearValue( Column.DesiredWidthProperty ); - widthToDistribute -= column.ActualWidth; - } - } - } - - this.CalculateColumnDesiredWidth( widthToDistribute, excludedColumns, canIncreaseColumnWidth ); - } - } - - private void CalculateColumnDesiredWidth( double widthToDistribute, List excludedColumns, bool canIncreaseColumnWidth ) - { - double starToDistribute = 0d; - - Debug.Assert( excludedColumns.Count > 0, "Should have at least one excluded Column." ); - - foreach( WorkingColumnWidth columnWidth in excludedColumns ) - { - starToDistribute += columnWidth.StarValue; - } - - double unitWidth = ColumnStretchingManager.CalculateUnitWidth( widthToDistribute, starToDistribute ); - WorkingColumnWidth primaryColumnWidth; - WorkingColumnWidth previousColumnWidth; - - // This width distribution algorithm will perform at most (n² + n)/2 iterations; - // where n is the number of columns involved in the distribution. - // This worst-case scenario will happen if each column has an active MinWidth - // or MaxWidth. - // But it's better than the Framework's grid algorithm which breaks down when star - // distribution is used with Min/MaxWidth. - for( int i = 0; i < excludedColumns.Count; i++ ) - { - primaryColumnWidth = excludedColumns[ i ]; - primaryColumnWidth.CalculateWidths( unitWidth ); - - if( primaryColumnWidth.OverriddenWidth >= 0d ) - { - widthToDistribute -= primaryColumnWidth.OverriddenWidth; - starToDistribute -= primaryColumnWidth.StarValue; - unitWidth = ColumnStretchingManager.CalculateUnitWidth( widthToDistribute, starToDistribute ); - - for( int j = 0; j < i; j++ ) - { - previousColumnWidth = excludedColumns[ j ]; - - if( previousColumnWidth.OverriddenWidth >= 0d ) - { - widthToDistribute += previousColumnWidth.OverriddenWidth; - starToDistribute += previousColumnWidth.StarValue; - unitWidth = ColumnStretchingManager.CalculateUnitWidth( widthToDistribute, starToDistribute ); - } - - previousColumnWidth.CalculateWidths( unitWidth ); - - if( previousColumnWidth.OverriddenWidth >= 0d ) - { - widthToDistribute -= previousColumnWidth.OverriddenWidth; - starToDistribute -= previousColumnWidth.StarValue; - unitWidth = ColumnStretchingManager.CalculateUnitWidth( widthToDistribute, starToDistribute ); - } - } - } - } - - foreach( WorkingColumnWidth columnWidth in excludedColumns ) - { - if( columnWidth.OverriddenWidth >= 0d ) - { - if( !canIncreaseColumnWidth && ( columnWidth.Column.DesiredWidth < columnWidth.DesiredWidth ) ) - continue; - - // Assign the desired calculated Width. Column.ActualWidth will be in charge of - // applying the MinWidth and MaxWidth. This ultimate responsability has to be - // kept in Column to make MinWidth and MaxWidth modifications having an impact. - // For instance, an inactive MinWidth of 200 would become active if - // DesiredWidth was set to a temporary MaxWidth of 200 (resetting MaxWidth - // would not trigger an immediate recalculation). - columnWidth.Column.DesiredWidth = columnWidth.DesiredWidth; - } - else - { - var desiredWidth = unitWidth * columnWidth.StarValue; - - if( !canIncreaseColumnWidth && ( columnWidth.Column.DesiredWidth < desiredWidth ) ) - continue; - - columnWidth.Column.DesiredWidth = desiredWidth; - } - } - } - - private static double CalculateUnitWidth( double widthToDistribute, double starToDistribute ) - { - if( ( widthToDistribute > 0d ) && ( starToDistribute > 0d ) ) - return widthToDistribute / starToDistribute; - - return 0d; - } - - #region Private WorkingColumnWidth Class - - private class WorkingColumnWidth - { - public WorkingColumnWidth( ColumnBase column, double starValue, double columnStretchMinWidth ) - { - bool unsetMinValue = ( column.ReadLocalValue( ColumnBase.MinWidthProperty ) == DependencyProperty.UnsetValue ); - - this.Column = column; - this.StarValue = starValue; - m_maxWidth = column.MaxWidth; - m_minWidth = column.MinWidth; - m_columnStretchMinWidth = ( ( unsetMinValue ) && ( columnStretchMinWidth < m_maxWidth ) ) ? columnStretchMinWidth : -1d; - } - - public void CalculateWidths( double unitWidth ) - { - double desiredWidth = unitWidth * this.StarValue; - - this.OverriddenWidth = -1d; - - if( desiredWidth < m_columnStretchMinWidth ) - { - desiredWidth = m_columnStretchMinWidth; - this.OverriddenWidth = desiredWidth; - } - - // No matter what the Column's MinWidth and MaxWidth are, this is the real - // desired width. - this.DesiredWidth = desiredWidth; - - if( desiredWidth > m_maxWidth ) - { - desiredWidth = m_maxWidth; - this.OverriddenWidth = desiredWidth; - } - - if( desiredWidth < m_minWidth ) - { - this.OverriddenWidth = m_minWidth; - } - } - - public double StarValue; - public ColumnBase Column; - public double DesiredWidth; - public double OverriddenWidth; - - private double m_columnStretchMinWidth; - private double m_minWidth; - private double m_maxWidth; - } - - #endregion Private WorkingColumnWidth Class - - private DataGridContext m_dataGridContext; - private bool m_columnStretchingDisabled; - private int m_dataGridScrollViewerMeasureVersion; - private double m_widthToDistribute = double.MaxValue; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/DataGridControlBackgroundBrushes.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/DataGridControlBackgroundBrushes.cs deleted file mode 100644 index ecc685ed..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/DataGridControlBackgroundBrushes.cs +++ /dev/null @@ -1,171 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows.Media; - -namespace Xceed.Wpf.DataGrid.Views -{ - public static class DataGridControlBackgroundBrushes - { - static DataGridControlBackgroundBrushes() - { - DataGridControlBackgroundBrushesResources resources = new DataGridControlBackgroundBrushesResources(); - - s_auroraBlue = ( Brush )resources[ "auroraBlueBrush" ]; - s_auroraPink = ( Brush )resources[ "auroraPinkBrush" ]; - s_auroraRed = ( Brush )resources[ "auroraRedBrush" ]; - s_elementalBlack = ( Brush )resources[ "elementalBlackBrush" ]; - s_elementalBlue = ( Brush )resources[ "elementalBlueBrush" ]; - s_elementalSilver = ( Brush )resources[ "elementalSilverBrush" ]; - s_horizonBlue = ( Brush )resources[ "horizonBlueBrush" ]; - s_horizonOrange = ( Brush )resources[ "horizonOrangeBrush" ]; - s_nightFog = ( Brush )resources[ "nightFogBrush" ]; - s_sunrise = ( Brush )resources[ "sunriseBrush" ]; - s_sunriseBlue = ( Brush )resources[ "sunriseBlueBrush" ]; - s_sunBlack = ( Brush )resources[ "sunBlackBrush" ]; - s_sunBlue = ( Brush )resources[ "sunBlueBrush" ]; - s_sunOrange = ( Brush )resources[ "sunOrangeBrush" ]; - } - - public static Brush AuroraBlue - { - get - { - return s_auroraBlue; - } - } - - public static Brush AuroraPink - { - get - { - return s_auroraPink; - } - } - - public static Brush AuroraRed - { - get - { - return s_auroraRed; - } - } - - public static Brush ElementalBlack - { - get - { - return s_elementalBlack; - } - } - - public static Brush ElementalBlue - { - get - { - return s_elementalBlue; - } - } - - public static Brush ElementalSilver - { - get - { - return s_elementalSilver; - } - } - - public static Brush HorizonBlue - { - get - { - return s_horizonBlue; - } - } - - public static Brush HorizonOrange - { - get - { - return s_horizonOrange; - } - } - - public static Brush NightFog - { - get - { - return s_nightFog; - } - } - - public static Brush Sunrise - { - get - { - return s_sunrise; - } - } - - public static Brush SunriseBlue - { - get - { - return s_sunriseBlue; - } - } - - public static Brush SunBlack - { - get - { - return s_sunBlack; - } - } - - public static Brush SunBlue - { - get - { - return s_sunBlue; - } - } - - public static Brush SunOrange - { - get - { - return s_sunOrange; - } - } - - private static Brush s_auroraBlue; - private static Brush s_auroraPink; - private static Brush s_auroraRed; - private static Brush s_elementalBlack; - private static Brush s_elementalBlue; - private static Brush s_elementalSilver; - private static Brush s_horizonBlue; - private static Brush s_horizonOrange; - private static Brush s_nightFog; - private static Brush s_sunrise; - private static Brush s_sunriseBlue; - private static Brush s_sunBlack; - private static Brush s_sunBlue; - private static Brush s_sunOrange; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/DataGridControlBackgroundBrushesResources.xaml b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/DataGridControlBackgroundBrushesResources.xaml deleted file mode 100644 index 44e15e30..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/DataGridControlBackgroundBrushesResources.xaml +++ /dev/null @@ -1,1153 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/DataGridControlBackgroundBrushesResources.xaml.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/DataGridControlBackgroundBrushesResources.xaml.cs deleted file mode 100644 index 2f4b3e2a..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/DataGridControlBackgroundBrushesResources.xaml.cs +++ /dev/null @@ -1,28 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Windows; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal partial class DataGridControlBackgroundBrushesResources : ResourceDictionary - { - public DataGridControlBackgroundBrushesResources() - { - this.InitializeComponent(); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/DataGridScrollViewer.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/DataGridScrollViewer.cs deleted file mode 100644 index 07bf8c9e..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/DataGridScrollViewer.cs +++ /dev/null @@ -1,1179 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Controls.Primitives; -using System.Windows.Data; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Threading; -using Xceed.Wpf.DataGrid.Converters; - -namespace Xceed.Wpf.DataGrid.Views -{ - public class DataGridScrollViewer : ScrollViewer - { - static DataGridScrollViewer() - { - DataGridControl.ParentDataGridControlPropertyKey.OverrideMetadata( typeof( DataGridScrollViewer ), new FrameworkPropertyMetadata( new PropertyChangedCallback( OnParentDataGridChanged ) ) ); - } - - internal DataGridScrollViewer() - { - this.Loaded += new RoutedEventHandler( OnLoaded ); - this.Unloaded += new RoutedEventHandler( OnUnloaded ); - m_templateHelper = new ScrollViewerTemplateHelper( this, this.DragScrollBegin, this.DragScrollEnd ); - } - - #region SynchronizedScrollViewerPosition Attached Property - - public static readonly DependencyProperty SynchronizedScrollViewerPositionProperty = DependencyProperty.RegisterAttached( - "SynchronizedScrollViewerPosition", - typeof( SynchronizedScrollViewerPosition ), - typeof( TableViewScrollViewer ), - new UIPropertyMetadata( SynchronizedScrollViewerPosition.None ) ); - - public static SynchronizedScrollViewerPosition GetSynchronizedScrollViewerPosition( DependencyObject obj ) - { - return ( SynchronizedScrollViewerPosition )obj.GetValue( TableViewScrollViewer.SynchronizedScrollViewerPositionProperty ); - } - - public static void SetSynchronizedScrollViewerPosition( DependencyObject obj, SynchronizedScrollViewerPosition value ) - { - obj.SetValue( TableViewScrollViewer.SynchronizedScrollViewerPositionProperty, value ); - } - - #endregion SynchronizedScrollViewerPosition Attached Property - - #region SynchronizedScrollViewersWidth Property - - internal double SynchronizedScrollViewersWidth - { - get - { - double maxValue = 0d; - - foreach( SynchronizedScrollViewer ssv in m_childScrollViewers ) - { - if( ssv.ScrollOrientation == ScrollOrientation.Horizontal ) - { - if( ssv.ExtentWidth > maxValue ) - { - maxValue = ssv.ExtentWidth; - } - } - } - - return maxValue; - } - } - - #endregion - - #region SynchronizedScrollViewersHeight Property - - internal double SynchronizedScrollViewersHeight - { - get - { - double maxValue = 0d; - - foreach( SynchronizedScrollViewer ssv in m_childScrollViewers ) - { - if( ssv.ScrollOrientation == ScrollOrientation.Vertical ) - { - if( ssv.ExtentHeight > maxValue ) - { - maxValue = ssv.ExtentHeight; - } - } - } - - return maxValue; - } - } - - #endregion - - #region SynchronizedScrollViewers Property - - internal IEnumerable SynchronizedScrollViewers - { - get - { - return m_childScrollViewers; - } - } - - private static readonly DependencyProperty SynchronizedScrollViewerExtentProperty = DependencyProperty.Register( - "SynchronizedScrollViewerExtent", - typeof( double ), - typeof( DataGridScrollViewer ), - new FrameworkPropertyMetadata( new PropertyChangedCallback( DataGridScrollViewer.OnSynchronizedScrollViewerExtentPropertyChanged ) ) ); - - private static void OnSynchronizedScrollViewerExtentPropertyChanged( DependencyObject o, DependencyPropertyChangedEventArgs e ) - { - DataGridScrollViewer dataGridScrollViewer = o as DataGridScrollViewer; - - if( dataGridScrollViewer != null ) - { - FrameworkElement panel = dataGridScrollViewer.ScrollInfo as FrameworkElement; - - if( panel != null ) - { - panel.InvalidateMeasure(); - } - } - } - - internal int MeasureVersion - { - get - { - return m_measureVersion; - } - } - - #endregion - - #region HorizontalScrollBar Property - - protected internal ScrollBar HorizontalScrollBar - { - get - { - return m_templateHelper.HorizontalScrollBar; - } - } - - #endregion - - #region VerticalScrollBar Property - - protected internal ScrollBar VerticalScrollBar - { - get - { - return m_templateHelper.VerticalScrollBar; - } - } - - #endregion - - public override void OnApplyTemplate() - { - base.OnApplyTemplate(); - - this.ClearScrollViewerList(); - m_deferableChilds.Clear(); - - this.PopulateScrollViewerList( this, m_childScrollViewers ); - this.FindAllDeferableChildren( this, m_deferableChilds ); - - m_templateHelper.RefreshTemplate(); - - this.UpdateChildScrollViewers(); - } - - internal void HandlePageUpNavigation() - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - if( dataGridContext == null ) - return; - - DataGridControl dataGridControl = dataGridContext.DataGridControl; - FrameworkElement hostPanel = dataGridControl.ItemsHost; - - if( hostPanel != null ) - { - // First thing to do here is the force the relayout of the ItemsHostPanel so that the target element gets "visible" - hostPanel.UpdateLayout(); - - FrameworkElement firstVisibleItem = ScrollViewerHelper.GetFirstVisibleContainer( - dataGridControl, hostPanel, this ); - - if( firstVisibleItem != null ) - { - DataGridContext firstVisibleItemDataGridContext = DataGridControl.GetDataGridContext( firstVisibleItem ); - - object oldItem = dataGridContext.InternalCurrentItem; - - bool focused; - - // Make the first visible item the current and focused. - // in order to cancel the current column in mixed mode when paged-Up - if( dataGridControl.NavigationBehavior == NavigationBehavior.RowOrCell ) - focused = dataGridControl.SetFocusHelper( - firstVisibleItem, null, true, true ); - else - { - focused = dataGridControl.SetFocusHelper( - firstVisibleItem, firstVisibleItemDataGridContext.CurrentColumn, true, true ); - } - - if( ( ( !focused ) || ( oldItem == firstVisibleItemDataGridContext.InternalCurrentItem ) ) - && ( !dataGridControl.HasValidationError ) ) - { - // The current item was already the first item, move focus up. - DataGridItemsHost.ProcessMoveFocus( Key.Up ); - } - } - } - } - - internal void HandlePageDownNavigation() - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - if( dataGridContext == null ) - return; - - DataGridControl dataGridControl = dataGridContext.DataGridControl; - FrameworkElement hostPanel = dataGridControl.ItemsHost; - - if( hostPanel != null ) - { - // First thing to do here is the force the relayout of the ItemsHostPanel so that the target element gets "visible" - hostPanel.UpdateLayout(); - - // Then retrieve the last visible item in this panel - FrameworkElement lastVisibleItem = ScrollViewerHelper.GetLastVisibleContainer( - dataGridControl, hostPanel, this ) as FrameworkElement; - - if( lastVisibleItem != null ) - { - DataGridContext lastVisibleItemDataGridContext = DataGridControl.GetDataGridContext( lastVisibleItem ); - - object oldItem = dataGridContext.InternalCurrentItem; - - bool focused; - - // Make the last visible item the current and focused. - // in order to cancel the current column in mixed mode when paged-Down - if( dataGridControl.NavigationBehavior == NavigationBehavior.RowOrCell ) - focused = dataGridControl.SetFocusHelper( - lastVisibleItem, null, true, true ); - else - { - focused = dataGridControl.SetFocusHelper( - lastVisibleItem, lastVisibleItemDataGridContext.CurrentColumn, true, true ); - } - - if( ( ( !focused ) || ( oldItem == lastVisibleItemDataGridContext.InternalCurrentItem ) ) - && ( !dataGridControl.HasValidationError ) ) - { - // The current item was already the first item, move focus down. - DataGridItemsHost.ProcessMoveFocus( Key.Down ); - } - } - } - } - - protected override void OnKeyDown( KeyEventArgs e ) - { - base.OnKeyDown( e ); - - if( e.Handled ) - return; - - switch( e.Key ) - { - // Handle the System key definition (basically with ALT key pressed) - case Key.System: - this.HandleSystemKey( e ); - break; - - case Key.PageUp: - this.HandlePageUpKey( e ); - break; - - case Key.PageDown: - this.HandlePageDownKey( e ); - break; - - case Key.Home: - this.HandlePageHomeKey( e ); - break; - - case Key.End: - this.HandlePageEndKey( e ); - break; - - case Key.Up: - this.HandleUpKey( e ); - break; - - case Key.Down: - this.HandleDownKey( e ); - break; - - case Key.Left: - this.HandleLeftKey( e ); - break; - - case Key.Right: - this.HandleRightKey( e ); - break; - - default: - base.OnKeyDown( e ); - break; - } - } - - protected virtual void HandleSystemKey( KeyEventArgs e ) - { - if( e.Handled ) - return; - - DataGridContext dataGridContext = null; - - if( e.OriginalSource != null ) - { - dataGridContext = DataGridControl.GetDataGridContext( e.OriginalSource as DependencyObject ); - } - else - { - dataGridContext = DataGridControl.GetDataGridContext( this ); - } - - if( dataGridContext == null ) - return; - - PagingBehavior pagingBehavior = dataGridContext.DataGridControl.PagingBehavior; - - // If Alt-PageDown was pressed - if( e.SystemKey == Key.PageDown ) - { - // Process Paging in opposed axis - if( pagingBehavior == PagingBehavior.TopToBottom ) - { - this.PageRight(); - } - else - { - this.PageDown(); - } - - e.Handled = true; - } - // If Alt-PageUp was pressed - else if( e.SystemKey == Key.PageUp ) - { - // Process scrolling in opposed axis - if( pagingBehavior == PagingBehavior.TopToBottom ) - { - this.PageLeft(); - } - else - { - this.PageUp(); - } - - e.Handled = true; - } - else - { - // If neither Alt-PageUp or alt-PageDown, flag the input as non-processed. - e.Handled = false; - } - } - - protected virtual void HandlePageUpKey( KeyEventArgs e ) - { - if( e.Handled ) - return; - - DataGridContext dataGridContext = null; - - if( e.OriginalSource != null ) - { - dataGridContext = DataGridControl.GetDataGridContext( e.OriginalSource as DependencyObject ); - } - else - { - dataGridContext = DataGridControl.GetDataGridContext( this ); - } - - if( dataGridContext == null ) - return; - - DataGridControl dataGridControl = dataGridContext.DataGridControl; - PagingBehavior pagingBehavior = dataGridControl.PagingBehavior; - NavigationBehavior navigationBehavior = dataGridControl.NavigationBehavior; - - //If the Ctrl Modifier was held at the same time - if( ( e.KeyboardDevice.Modifiers & ModifierKeys.Control ) == ModifierKeys.Control ) - { - //scroll to absolute end of the scroll viewer - if( pagingBehavior == PagingBehavior.TopToBottom ) - { - this.ScrollToTop(); - } - else - { - this.ScrollToLeftEnd(); - } - - // Then handle new selection! - if( navigationBehavior != NavigationBehavior.None ) - this.HandlePageUpNavigation(); - } - // No special modifiers were held - else - { - // Retrieve first visible item - FrameworkElement firstVisibleItem = ScrollViewerHelper.GetFirstVisibleContainer( - dataGridControl, dataGridControl.ItemsHost, this ); - - if( firstVisibleItem != null ) - { - // There is an identified weakness with the IsKeyboardFocusWithin property where - // it cannot tell if the focus is within a Popup which is within the element - // This has been identified, and only the places where it caused problems - // were fixed... This comment is only here to remind developpers of the flaw - - // If the item has keyboard focus - if( ( firstVisibleItem.IsKeyboardFocusWithin ) || ( firstVisibleItem.IsKeyboardFocused ) - || ( navigationBehavior == NavigationBehavior.None ) ) - { - // Then scroll - if( pagingBehavior == PagingBehavior.TopToBottom ) - { - this.PageUp(); - } - else - { - this.PageLeft(); - } - } - - // And process new selection - if( navigationBehavior != NavigationBehavior.None ) - this.HandlePageUpNavigation(); - } - else - { - // Normaly for when we are in dataGridControl.NavigationBehavior == NavigationBehavior.None - if( pagingBehavior == PagingBehavior.TopToBottom ) - { - this.PageUp(); - } - else - { - this.PageLeft(); - } - } - } - - e.Handled = true; - } - - protected virtual void HandlePageDownKey( KeyEventArgs e ) - { - if( e.Handled ) - return; - - DataGridContext dataGridContext = null; - - if( e.OriginalSource != null ) - { - dataGridContext = DataGridControl.GetDataGridContext( e.OriginalSource as DependencyObject ); - } - else - { - dataGridContext = DataGridControl.GetDataGridContext( this ); - } - - if( dataGridContext == null ) - return; - - DataGridControl dataGridControl = dataGridContext.DataGridControl; - PagingBehavior pagingBehavior = dataGridControl.PagingBehavior; - NavigationBehavior navigationBehavior = dataGridControl.NavigationBehavior; - - // If the Ctrl Modifier was held at the same time - if( ( e.KeyboardDevice.Modifiers & ModifierKeys.Control ) == ModifierKeys.Control ) - { - // Scroll to absolute end of the scroll viewer - if( pagingBehavior == PagingBehavior.TopToBottom ) - { - this.ScrollToBottom(); - } - else - { - this.ScrollToRightEnd(); - } - - // Then handle new selection! - if( navigationBehavior != NavigationBehavior.None ) - this.HandlePageDownNavigation(); - } - //No special modifiers were held - else - { - FrameworkElement lastVisibleContainer = ScrollViewerHelper.GetLastVisibleContainer( - dataGridControl, dataGridControl.ItemsHost, this ); - - if( lastVisibleContainer != null ) - { - // There is an identified weakness with the IsKeyboardFocusWithin property where - // it cannot tell if the focus is within a Popup which is within the element - // This has been identified, and only the places where it caused problems - // were fixed... This comment is only here to remind developpers of the flaw - - // If the item has keyboard focus - if( ( lastVisibleContainer.IsKeyboardFocusWithin ) || ( lastVisibleContainer.IsKeyboardFocused ) - || ( navigationBehavior == NavigationBehavior.None ) ) - { - // Then scroll - if( pagingBehavior == PagingBehavior.TopToBottom ) - { - this.PageDown(); - } - else - { - this.PageRight(); - } - } - - //and process new selection - if( navigationBehavior != NavigationBehavior.None ) - this.HandlePageDownNavigation(); - } - else - { - // Normaly for when we are in dataGridControl.NavigationBehavior == NavigationBehavior.None - if( pagingBehavior == PagingBehavior.TopToBottom ) - { - this.PageDown(); - } - else - { - this.PageRight(); - } - } - } - - e.Handled = true; - } - - protected virtual void HandlePageHomeKey( KeyEventArgs e ) - { - if( e.Handled ) - return; - - DataGridContext dataGridContext = null; - - if( e.OriginalSource != null ) - { - dataGridContext = DataGridControl.GetDataGridContext( e.OriginalSource as DependencyObject ); - } - else - { - dataGridContext = DataGridControl.GetDataGridContext( this ); - } - - if( dataGridContext == null ) - return; - - PagingBehavior pagingBehavior = dataGridContext.DataGridControl.PagingBehavior; - NavigationBehavior navigationBehavior = dataGridContext.DataGridControl.NavigationBehavior; - - ColumnBase currentColumn = dataGridContext.CurrentColumn; - - if( ( ( navigationBehavior == NavigationBehavior.CellOnly ) || ( navigationBehavior == NavigationBehavior.RowOrCell ) ) && ( currentColumn != null ) ) - { - int oldCurrentIndex = currentColumn.Index; - - NavigationHelper.MoveFocusToFirstVisibleColumn( dataGridContext ); - - var columnVirtualizationManager = dataGridContext.ColumnVirtualizationManager as TableViewColumnVirtualizationManagerBase; - - //if the first focusable column is is within the viewport, scroll so 0d offset, otherwise, bringIntoView - bool isFixedColumn = ( columnVirtualizationManager == null ) ? false : columnVirtualizationManager.GetFixedFieldNames().Contains( currentColumn.FieldName ); - - if( ( ( this.IsCellsOffsetNeedReset( dataGridContext ) ) && ( oldCurrentIndex == currentColumn.Index ) ) || ( isFixedColumn ) ) - { - this.Dispatcher.BeginInvoke( DispatcherPriority.Normal, new Action( this.ScrollToLeftEnd ) ); - } - - if( ( e.KeyboardDevice.Modifiers & ModifierKeys.Control ) == ModifierKeys.Control ) - { - if( pagingBehavior == PagingBehavior.TopToBottom ) - { - this.ScrollToTop(); - } - else - { - this.ScrollToLeftEnd(); - } - - this.HandlePageUpNavigation(); - } - } - else - { - if( ( e.KeyboardDevice.Modifiers & ModifierKeys.Control ) == ModifierKeys.Control ) - { - this.ScrollToTop(); - this.ScrollToLeftEnd(); - - //than handle new selection! - if( navigationBehavior != NavigationBehavior.None ) - { - this.HandlePageUpNavigation(); - } - } - else - { - if( pagingBehavior == PagingBehavior.TopToBottom ) - { - this.ScrollToLeftEnd(); - } - else - { - this.ScrollToTop(); - } - } - } - - e.Handled = true; - } - - protected virtual void HandlePageEndKey( KeyEventArgs e ) - { - if( e.Handled ) - return; - - DataGridContext dataGridContext = null; - - if( e.OriginalSource != null ) - { - dataGridContext = DataGridControl.GetDataGridContext( e.OriginalSource as DependencyObject ); - } - else - { - dataGridContext = DataGridControl.GetDataGridContext( this ); - } - - if( dataGridContext == null ) - return; - - PagingBehavior pagingBehavior = dataGridContext.DataGridControl.PagingBehavior; - NavigationBehavior navigationBehavior = dataGridContext.DataGridControl.NavigationBehavior; - - ColumnBase CurrentColumn = dataGridContext.CurrentColumn; - - if( ( ( navigationBehavior == NavigationBehavior.CellOnly ) || ( navigationBehavior == NavigationBehavior.RowOrCell ) ) && ( CurrentColumn != null ) ) - { - int oldCurrentIndex = CurrentColumn.Index; - - NavigationHelper.MoveFocusToLastVisibleColumn( dataGridContext ); - - //if the last focusable column is is within the viewport, scroll to Extended offset, otherwise, bringIntoView - if( ( this.IsCellsOffsetNeedReset( dataGridContext ) ) && ( oldCurrentIndex == CurrentColumn.Index ) ) - { - this.Dispatcher.BeginInvoke( DispatcherPriority.Normal, new Action( this.ScrollToRightEnd ) ); - } - - if( ( e.KeyboardDevice.Modifiers & ModifierKeys.Control ) == ModifierKeys.Control ) - { - if( pagingBehavior == PagingBehavior.TopToBottom ) - { - this.ScrollToBottom(); - } - else - { - this.ScrollToRightEnd(); - } - - this.HandlePageDownNavigation(); - } - } - else - { - if( ( e.KeyboardDevice.Modifiers & ModifierKeys.Control ) == ModifierKeys.Control ) - { - this.ScrollToBottom(); - this.ScrollToRightEnd(); - - // Than handle new selection! - if( navigationBehavior != NavigationBehavior.None ) - { - this.HandlePageDownNavigation(); - } - } - else - { - if( pagingBehavior == PagingBehavior.TopToBottom ) - { - this.ScrollToRightEnd(); - } - else - { - this.ScrollToBottom(); - } - } - } - - e.Handled = true; - } - - private bool IsCellsOffsetNeedReset( DataGridContext dataGridContext ) - { - var columnVirtualizationManager = dataGridContext.ColumnVirtualizationManager as TableViewColumnVirtualizationManagerBase; - if( columnVirtualizationManager == null ) - return false; - - Cell targetCell = dataGridContext.CurrentCell; - - // if the targetCell is null, it means we are on a header or a non focusable item; thus we want to scroll as the "no navigation" behavior - if( targetCell == null ) - return true; - - FixedCellPanel fixedCellPanel = targetCell.ParentRow.CellsHostPanel as FixedCellPanel; - DataGridItemsHost itemsHost = dataGridContext.DataGridControl.ItemsHost as DataGridItemsHost; - - double viewportWidth = this.ViewportWidth; - double fixedColumnWidth = columnVirtualizationManager.FixedColumnsWidth; - double fixedColumnSplitterWidth = 0; - double cellsWidth = targetCell.ParentColumn.Width; - - Point cellToScrollingCellsDecorator = targetCell.TranslatePoint( new Point(), fixedCellPanel.ScrollingCellsDecorator ); - - bool leftEdgeOutOfViewPort; - - // verify if the cell's left edge is visible in the viewPort - leftEdgeOutOfViewPort = ( cellToScrollingCellsDecorator.X < 0 ) ? true : false; - - // Verify if the Cell's right edge is visible in the ViewPort - Point cellToItemsHost = targetCell.TranslatePoint( new Point( cellsWidth, 0 ), itemsHost ); - - // If the right edge is out of Viewport, ensure not to call the resetHorizontalOffset - bool rightEdgeOutOfViewPort = ( ( cellToItemsHost.X - viewportWidth ) > 0 ) ? true : false; - - bool resetHorizontalOffset = false; - - // if the cell is inside the viewPort or if one of the edges of the cell are outside the portView but the the viewPort is not wide enough to contain the cell - if( ( ( !rightEdgeOutOfViewPort ) && ( !leftEdgeOutOfViewPort ) ) - || ( ( ( rightEdgeOutOfViewPort ) || ( leftEdgeOutOfViewPort ) ) - && ( ( cellsWidth - Math.Abs( cellToScrollingCellsDecorator.X ) ) >= ( viewportWidth - fixedColumnWidth - fixedColumnSplitterWidth ) ) ) ) - { - resetHorizontalOffset = true; - } - - return resetHorizontalOffset; - } - - protected virtual void HandleUpKey( KeyEventArgs e ) - { - if( e.Handled ) - return; - - DataGridContext dataGridContext = null; - - if( e.OriginalSource != null ) - { - dataGridContext = DataGridControl.GetDataGridContext( e.OriginalSource as DependencyObject ); - } - else - { - dataGridContext = DataGridControl.GetDataGridContext( this ); - } - - if( dataGridContext == null ) - return; - - bool hasValidationError = dataGridContext.DataGridControl.HasValidationError; - - if( !hasValidationError ) - { - this.LineUp(); - } - - e.Handled = true; - } - - protected virtual void HandleDownKey( KeyEventArgs e ) - { - if( e.Handled ) - return; - - DataGridContext dataGridContext = null; - - if( e.OriginalSource != null ) - { - dataGridContext = DataGridControl.GetDataGridContext( e.OriginalSource as DependencyObject ); - } - else - { - dataGridContext = DataGridControl.GetDataGridContext( this ); - } - - if( dataGridContext == null ) - return; - - bool hasValidationError = dataGridContext.DataGridControl.HasValidationError; - - if( !hasValidationError ) - { - this.LineDown(); - } - - e.Handled = true; - } - - protected virtual void HandleLeftKey( KeyEventArgs e ) - { - if( e.Handled ) - return; - - DataGridContext dataGridContext = null; - - if( e.OriginalSource != null ) - { - dataGridContext = DataGridControl.GetDataGridContext( e.OriginalSource as DependencyObject ); - } - else - { - dataGridContext = DataGridControl.GetDataGridContext( this ); - } - - if( dataGridContext == null ) - return; - - FlowDirection flowDirection = dataGridContext.DataGridControl.FlowDirection; - bool hasValidationError = dataGridContext.DataGridControl.HasValidationError; - - if( !hasValidationError ) - { - if( flowDirection == FlowDirection.LeftToRight ) - { - this.LineLeft(); - } - else - { - this.LineRight(); - } - } - - e.Handled = true; - } - - protected virtual void HandleRightKey( KeyEventArgs e ) - { - if( e.Handled ) - return; - - DataGridContext dataGridContext = null; - - if( e.OriginalSource != null ) - { - dataGridContext = DataGridControl.GetDataGridContext( e.OriginalSource as DependencyObject ); - } - else - { - dataGridContext = DataGridControl.GetDataGridContext( this ); - } - - if( dataGridContext == null ) - return; - - FlowDirection flowDirection = dataGridContext.DataGridControl.FlowDirection; - bool hasValidationError = dataGridContext.DataGridControl.HasValidationError; - - if( !hasValidationError ) - { - if( flowDirection == FlowDirection.LeftToRight ) - { - this.LineRight(); - } - else - { - this.LineLeft(); - } - } - - e.Handled = true; - } - - protected override void OnScrollChanged( ScrollChangedEventArgs e ) - { - base.OnScrollChanged( e ); - - this.UpdateChildScrollViewers(); - } - - protected override Size MeasureOverride( Size constraint ) - { - unchecked - { - m_measureVersion++; - } - - return base.MeasureOverride( constraint ); - } - - private static void OnParentDataGridChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - DataGridScrollViewer scrollViewer = sender as DataGridScrollViewer; - if( scrollViewer != null ) - { - if( e.NewValue == null ) - { - scrollViewer.ClearScrollViewerList(); - } - } - } - - private void OnLoaded( object sender, RoutedEventArgs e ) - { - //Placing the "Populate" call here is redundant from the OnApplyTemplate() call, but still required to prevent any possible case - //where the DataGridScrollViewer is removed/added from/to its visual parent without having its template re-applied. - //the if statement is there to ensure that we are not doing the job 2 times - //(if the list if not empty in the loaded event, its because OnApplyTemplate was called) - if( m_childScrollViewers.Count == 0 ) - { - this.PopulateScrollViewerList( this, m_childScrollViewers ); - } - } - - private void OnUnloaded( object sender, RoutedEventArgs e ) - { - //when the ScrollViewer gets unloaded, clear the events (we don't have other hooks that indicate the ScrollViewer - //is deconnected from the DAtaGridControl's Template) - this.ClearScrollViewerList(); - } - - private void DragScrollBegin( Orientation orientation ) - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - if( dataGridContext == null ) - return; - - DataGridControl parentGridControl = dataGridContext.DataGridControl; - - if( parentGridControl == null || dataGridContext.DataGridControl.ScrollViewer == null ) - return; - - if( parentGridControl.ItemScrollingBehavior == ItemScrollingBehavior.Deferred ) - { - IDeferableScrollInfoRefresh panel = this.ScrollInfo as IDeferableScrollInfoRefresh; - - if( panel != null ) - { - if( m_deferScrollInfoRefresh != null ) - { - foreach( IDeferableScrollChanged deferable in m_deferableChilds ) - { - deferable.DeferScrollChanged = false; - } - - m_deferScrollInfoRefresh.Dispose(); - m_deferScrollInfoRefresh = null; - } - - m_deferScrollInfoRefresh = panel.DeferScrollInfoRefresh( orientation ); - - if( m_deferScrollInfoRefresh != null ) - { - foreach( IDeferableScrollChanged deferable in m_deferableChilds ) - { - deferable.DeferScrollChanged = true; - } - } - } - } - } - - private void DragScrollEnd( Orientation orientation ) - { - if( m_deferScrollInfoRefresh != null ) - { - foreach( IDeferableScrollChanged deferable in m_deferableChilds ) - { - deferable.DeferScrollChanged = false; - } - - m_deferScrollInfoRefresh.Dispose(); - m_deferScrollInfoRefresh = null; - } - } - - private void ClearScrollViewerList() - { - BindingOperations.ClearBinding( this, DataGridScrollViewer.SynchronizedScrollViewerExtentProperty ); - m_childScrollViewers.Clear(); - } - - private void PopulateScrollViewerList( DependencyObject reference, List list ) - { - MultiBinding multiBinding = new MultiBinding(); - multiBinding.Converter = new SynchronizedScrollViewerMultiConverter(); - - this.PopulateScrollViewerListHelper( reference, list, multiBinding ); - - BindingOperations.SetBinding( this, DataGridScrollViewer.SynchronizedScrollViewerExtentProperty, multiBinding ); - } - - private void PopulateScrollViewerListHelper( DependencyObject reference, List list, MultiBinding multiBinding ) - { - if( reference == null ) - return; - - var childCount = VisualTreeHelper.GetChildrenCount( reference ); - - for( int i = 0; i < childCount; i++ ) - { - var child = VisualTreeHelper.GetChild( reference, i ); - var synchronizedScrollViewer = child as SynchronizedScrollViewer; - - if( synchronizedScrollViewer != null ) - { - var propertyName = String.Empty; - - if( synchronizedScrollViewer.ScrollOrientation == ScrollOrientation.Horizontal ) - { - propertyName = "ExtentWidth"; - } - else - { - propertyName = "ExtentHeight"; - } - - var binding = new Binding(); - binding.Path = new PropertyPath( propertyName ); - binding.Mode = BindingMode.OneWay; - binding.Source = synchronizedScrollViewer; - - multiBinding.Bindings.Add( binding ); - - list.Add( synchronizedScrollViewer ); - } - else - { - this.PopulateScrollViewerListHelper( child, list, multiBinding ); - } - } - } - - private void FindAllDeferableChildren( DependencyObject reference, List list ) - { - if( reference == null ) - return; - - var childCount = VisualTreeHelper.GetChildrenCount( reference ); - - for( int i = 0; i < childCount; i++ ) - { - var child = VisualTreeHelper.GetChild( reference, i ); - var deferable = child as IDeferableScrollChanged; - - if( deferable != null ) - { - list.Add( deferable ); - } - else - { - this.FindAllDeferableChildren( child, list ); - } - } - } - - private void UpdateChildScrollViewers() - { - bool isAtTop = ( this.VerticalOffset == 0 ); - bool isAtLeft = ( this.HorizontalOffset == 0 ); - bool isAtBottom = ( ( this.VerticalOffset + this.ViewportHeight ) == this.ExtentHeight ); - bool isAtRight = ( ( this.HorizontalOffset + this.ViewportWidth ) == this.ExtentWidth ); - - foreach( SynchronizedScrollViewer scrollViewer in m_childScrollViewers ) - { - SynchronizedScrollViewerPosition position = TableViewScrollViewer.GetSynchronizedScrollViewerPosition( scrollViewer ); - - bool handled = false; - - switch( position ) - { - case SynchronizedScrollViewerPosition.Top: - if( isAtTop == true ) - { - KeyboardNavigation.SetDirectionalNavigation( scrollViewer, KeyboardNavigationMode.Continue ); - KeyboardNavigation.SetTabNavigation( scrollViewer, KeyboardNavigationMode.Continue ); - handled = true; - } - break; - case SynchronizedScrollViewerPosition.Bottom: - if( isAtBottom == true ) - { - KeyboardNavigation.SetDirectionalNavigation( scrollViewer, KeyboardNavigationMode.Continue ); - KeyboardNavigation.SetTabNavigation( scrollViewer, KeyboardNavigationMode.Continue ); - handled = true; - } - break; - case SynchronizedScrollViewerPosition.Left: - if( isAtLeft == true ) - { - KeyboardNavigation.SetDirectionalNavigation( scrollViewer, KeyboardNavigationMode.Continue ); - KeyboardNavigation.SetTabNavigation( scrollViewer, KeyboardNavigationMode.Continue ); - handled = true; - } - break; - case SynchronizedScrollViewerPosition.Right: - if( isAtRight == true ) - { - KeyboardNavigation.SetDirectionalNavigation( scrollViewer, KeyboardNavigationMode.Continue ); - KeyboardNavigation.SetTabNavigation( scrollViewer, KeyboardNavigationMode.Continue ); - handled = true; - } - break; - - case SynchronizedScrollViewerPosition.None: - default: - break; - } - - if( handled == false ) - { - KeyboardNavigation.SetDirectionalNavigation( scrollViewer, KeyboardNavigationMode.None ); - KeyboardNavigation.SetTabNavigation( scrollViewer, KeyboardNavigationMode.None ); - } - } - } - - private List m_childScrollViewers = new List(); - private List m_deferableChilds = new List(); - - ScrollViewerTemplateHelper m_templateHelper; - IDisposable m_deferScrollInfoRefresh; // = null - int m_measureVersion; - - internal interface IDeferableScrollChanged - { - bool DeferScrollChanged - { - get; - set; - } - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/DictionaryTheme.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/DictionaryTheme.cs deleted file mode 100644 index 29b100b7..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/DictionaryTheme.cs +++ /dev/null @@ -1,56 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; - -namespace Xceed.Wpf.DataGrid.Views -{ - public abstract class DictionaryTheme : Theme - { - public DictionaryTheme() - { - } - - public DictionaryTheme( ResourceDictionary themeResourceDictionary ) - { - m_themeResourceDictionary = themeResourceDictionary; - m_themeResourceDictionaryInitialized = true; - } - - #region ThemeResourceDictionary Property - - public ResourceDictionary ThemeResourceDictionary - { - get - { - return m_themeResourceDictionary; - } - set - { - if( m_themeResourceDictionaryInitialized ) - throw new InvalidOperationException( "An attempt was made to set the ThemeResourceDictionary property when it has already been initialized." ); - - m_themeResourceDictionary = value; - } - } - - private ResourceDictionary m_themeResourceDictionary; - private bool m_themeResourceDictionaryInitialized; //false - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/FixedCellPanel.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/FixedCellPanel.cs deleted file mode 100644 index 8efd9a9b..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/FixedCellPanel.cs +++ /dev/null @@ -1,2007 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Diagnostics; -using System.Linq; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Controls.Primitives; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Threading; - -namespace Xceed.Wpf.DataGrid.Views -{ - public class FixedCellPanel : Panel, IVirtualizingCellsHost, IWeakEventListener - { - private static readonly TimeSpan MaxProcessDurationTime = TimeSpan.FromMilliseconds( 25d ); - - static FixedCellPanel() - { - FixedCellPanel.MinHeightProperty.OverrideMetadata( typeof( FixedCellPanel ), new FrameworkPropertyMetadata( null, new CoerceValueCallback( FixedCellPanel.CoerceMinHeight ) ) ); - TextElement.FontFamilyProperty.OverrideMetadata( typeof( FixedCellPanel ), new FrameworkPropertyMetadata( new PropertyChangedCallback( FixedCellPanel.InvalidateMinHeight ) ) ); - TextElement.FontSizeProperty.OverrideMetadata( typeof( FixedCellPanel ), new FrameworkPropertyMetadata( new PropertyChangedCallback( FixedCellPanel.InvalidateMinHeight ) ) ); - TextElement.FontStretchProperty.OverrideMetadata( typeof( FixedCellPanel ), new FrameworkPropertyMetadata( new PropertyChangedCallback( FixedCellPanel.InvalidateMinHeight ) ) ); - TextElement.FontStyleProperty.OverrideMetadata( typeof( FixedCellPanel ), new FrameworkPropertyMetadata( new PropertyChangedCallback( FixedCellPanel.InvalidateMinHeight ) ) ); - TextElement.FontWeightProperty.OverrideMetadata( typeof( FixedCellPanel ), new FrameworkPropertyMetadata( new PropertyChangedCallback( FixedCellPanel.InvalidateMinHeight ) ) ); - } - - public FixedCellPanel() - { - // None of the Visual children of the FixedCellPanel will scroll. The needed scrolling as demanded by the parent ScrollViewer - // will be manually transferred to the content (m_scrollingPanel) of the ScrollingCellsDecorator below. - - m_fixedPanel = new FixedCellSubPanel( this ); - - m_scrollingPanel = new VirtualizingFixedCellSubPanel( this ); - - m_scrollingCellsDecorator = new ScrollingCellsDecorator(); - m_scrollingCellsDecorator.Child = m_scrollingPanel; - - this.AddVisualChild( m_fixedPanel ); - this.AddVisualChild( null ); - this.AddVisualChild( m_scrollingCellsDecorator ); - - // Used to get the correct item depending of the ZIndex - m_visualChildren.Add( m_fixedPanel ); - m_visualChildren.Add( null ); - m_visualChildren.Add( m_scrollingCellsDecorator ); - - this.SetCurrentValue( FixedCellPanel.MinHeightProperty, 0d ); - - this.LayoutUpdated += new EventHandler( FixedCellPanelLayoutUpdated ); - } - - #region ColumnStretchMinWidth Property - - public static readonly DependencyProperty ColumnStretchMinWidthProperty = DependencyProperty.Register( - "ColumnStretchMinWidth", - typeof( double ), - typeof( FixedCellPanel ), - new UIPropertyMetadata( 50d, - new PropertyChangedCallback( FixedCellPanel.ColumnStretchMinWidthChanged ) ), - new ValidateValueCallback( TableView.ValidateColumnStretchMinWidthCallback ) ); - - public double ColumnStretchMinWidth - { - get - { - return ( double )this.GetValue( FixedCellPanel.ColumnStretchMinWidthProperty ); - } - set - { - this.SetValue( FixedCellPanel.ColumnStretchMinWidthProperty, value ); - } - } - - private static void ColumnStretchMinWidthChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var panel = sender as FixedCellPanel; - if( panel == null ) - return; - - //Do not process merged headers. Their width is determined by their child columns. - if( panel.ParentRow.LevelCache != -1 ) - return; - - var dataGridContext = DataGridControl.GetDataGridContext( panel ); - if( dataGridContext == null ) - return; - - if( ( dataGridContext.VisibleColumns.Count > 0 ) && !dataGridContext.IsAFlattenDetail ) - { - // When ColumnStretchMinWidth changes trigger an update by clearing all DesiredWidth values. - foreach( ColumnBase column in dataGridContext.VisibleColumns ) - { - column.ClearValue( Column.DesiredWidthProperty ); - } - } - } - - #endregion - - #region ColumnStretchMode Property - - public static readonly DependencyProperty ColumnStretchModeProperty = DependencyProperty.Register( - "ColumnStretchMode", - typeof( ColumnStretchMode ), - typeof( FixedCellPanel ), - new UIPropertyMetadata( ColumnStretchMode.None ) ); - - public ColumnStretchMode ColumnStretchMode - { - get - { - return ( ColumnStretchMode )this.GetValue( FixedCellPanel.ColumnStretchModeProperty ); - } - set - { - this.SetValue( FixedCellPanel.ColumnStretchModeProperty, value ); - } - } - - #endregion - - #region DataGridContext Property - - // DataGridContext is set when IVirtualizingCellsHost.PrepareCellsHost is called and cleared when IVirtualizingCellsHost.ClearContainer is called. - // We always use the DataGridContext passed and assert the old one is never referenced - internal DataGridContext DataGridContext - { - get - { - return m_dataGridContext; - } - } - - #endregion - - #region Columns Internal Property - - internal ColumnCollection Columns - { - get - { - return m_dataGridContext.Columns; - } - } - - #endregion - - #region ColumnsByVisiblePosition Property - - internal HashedLinkedList ColumnsByVisiblePosition - { - get - { - return m_dataGridContext.ColumnsByVisiblePosition; - } - } - - #endregion - - #region VisibleColumns Property - - private ReadOnlyObservableCollection VisibleColumns - { - get - { - return m_dataGridContext.VisibleColumns; - } - } - - #endregion - - #region FixedCellCount Property - - public static readonly DependencyProperty FixedCellCountProperty = DependencyProperty.Register( - "FixedCellCount", - typeof( int ), - typeof( FixedCellPanel ), - new UIPropertyMetadata( - 0, - new PropertyChangedCallback( FixedCellPanel.FixedCellCountChanged ) ), - new ValidateValueCallback( FixedCellPanel.ValidateFixedCellCountCallback ) ); - - public int FixedCellCount - { - get - { - return ( int )this.GetValue( FixedCellPanel.FixedCellCountProperty ); - } - set - { - this.SetValue( FixedCellPanel.FixedCellCountProperty, value ); - } - } - - private static void FixedCellCountChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - FixedCellPanel panel = sender as FixedCellPanel; - if( panel == null ) - return; - - // Invalidate the measure to force a layout pass - panel.InvalidateMeasure(); - } - - private static bool ValidateFixedCellCountCallback( object value ) - { - return ( ( int )value >= 0 ); - } - - #endregion - - #region FixedPanel Property - - internal Panel FixedPanel - { - get - { - return m_fixedPanel; - } - } - - #endregion - - #region FixedColumnDropMarkPen Property - - public static readonly DependencyProperty FixedColumnDropMarkPenProperty = DependencyProperty.Register( - "FixedColumnDropMarkPen", - typeof( Pen ), - typeof( FixedCellPanel ), - new PropertyMetadata( null ) ); - - public Pen FixedColumnDropMarkPen - { - get - { - return ( Pen )this.GetValue( FixedCellPanel.FixedColumnDropMarkPenProperty ); - } - set - { - this.SetValue( FixedCellPanel.FixedColumnDropMarkPenProperty, value ); - } - } - - #endregion - - #region ParentRow Property - - internal Row ParentRow - { - get - { - if( m_parentRow == null ) - { - m_parentRow = Row.FindFromChild( m_dataGridContext, this ); - } - - return m_parentRow; - } - } - - #endregion - - #region ParentRowCells Property - - internal VirtualizingCellCollection ParentRowCells - { - get - { - if( m_parentRowCells == null ) - { - Row parentRow = this.ParentRow; - - if( parentRow == null ) - return null; - - m_parentRowCells = ( VirtualizingCellCollection )parentRow.Cells; - - Debug.Assert( m_parentRowCells != null ); - } - - return m_parentRowCells; - } - } - - #endregion - - #region ParentScrollViewer Property - - internal ScrollViewer ParentScrollViewer - { - get - { - if( m_parentScrollViewer == null ) - { - m_parentScrollViewer = TableViewScrollViewer.GetParentScrollViewer( this ); - Debug.Assert( m_parentScrollViewer != null ); - } - - return m_parentScrollViewer; - } - } - - #endregion - - #region ScrollingCellsDecorator Property - - internal Decorator ScrollingCellsDecorator - { - get - { - return m_scrollingCellsDecorator; - } - } - - #endregion - - #region ColumnVirtualizationManager Internal Property - - internal TableViewColumnVirtualizationManagerBase ColumnVirtualizationManager - { - get - { - if( m_dataGridContext == null ) - return null; - - var columnVirtualizationManager = m_dataGridContext.ColumnVirtualizationManager as TableViewColumnVirtualizationManagerBase; - if( columnVirtualizationManager == null ) - throw new DataGridInternalException( "Invalid ColumnVirtualizationManager for FixedCellPanel", m_dataGridContext.DataGridControl ); - - return columnVirtualizationManager; - } - } - - #endregion - - #region VisualChildrenCount Property - - protected override int VisualChildrenCount - { - get - { - return c_visualChildrenCount; - } - } - - #endregion - - #region LogicalChildren Property - - protected override IEnumerator LogicalChildren - { - get - { - return this.Children.GetEnumerator(); - } - } - - #endregion - - #region CellsInView Private Property - - private IEnumerable CellsInView - { - get - { - var parentRowCells = this.ParentRowCells; - if( parentRowCells == null ) - return new Cell[ 0 ]; - - TableViewColumnVirtualizationManagerBase columnVirtualizationManager = this.ColumnVirtualizationManager; - if( columnVirtualizationManager == null ) - return new Cell[ 0 ]; - - List cells = new List(); - Cell cell; - - var fieldNames = columnVirtualizationManager.GetFixedFieldNames( m_parentRow.LevelCache ) - .Concat( columnVirtualizationManager.GetScrollingFieldNames( m_parentRow.LevelCache ) ); - - foreach( string fieldName in fieldNames ) - { - if( parentRowCells.TryGetCreatedCell( fieldName, out cell ) ) - { - cells.Add( cell ); - } - } - - return cells; - } - } - - #endregion - - #region PermanentScrollingFieldNames Internal Property - - internal IEnumerable PermanentScrollingFieldNames - { - get - { - return m_permanentScrollingFieldNames; - } - } - - private void AddPermanentScrollingFieldNames( string fieldName ) - { - if( string.IsNullOrEmpty( fieldName ) || m_permanentScrollingFieldNames.Contains( fieldName ) ) - return; - - m_permanentScrollingFieldNames.Add( fieldName ); - } - - private bool AddPermanentScrollingFieldNamesIfOutOfViewColumn( string fieldName ) - { - if( string.IsNullOrEmpty( fieldName ) || m_permanentScrollingFieldNames.Contains( fieldName ) ) - return false; - - var columnVirtualizationManager = this.ColumnVirtualizationManager; - if( columnVirtualizationManager != null ) - { - if( columnVirtualizationManager.GetFixedFieldNames( m_parentRow.LevelCache ).Contains( fieldName ) - || columnVirtualizationManager.GetScrollingFieldNames( m_parentRow.LevelCache ).Contains( fieldName ) ) - return false; - } - - m_permanentScrollingFieldNames.Add( fieldName ); - - return true; - } - - private void ClearPermanentScrollingFieldNames() - { - m_permanentScrollingFieldNames.Clear(); - m_permanentScrollingFieldNames.TrimExcess(); - } - - private readonly List m_permanentScrollingFieldNames = new List( 0 ); - - #endregion - - protected override Visual GetVisualChild( int index ) - { - if( m_zOrderDirty ) - { - this.RecomputeZOrder(); - } - - var correctedIndex = ( m_zIndexMapping == null ) ? index : m_zIndexMapping[ index ]; - - switch( correctedIndex ) - { - case 0: - return m_fixedPanel; - case 1: - return null; - case 2: - return m_scrollingCellsDecorator; - default: - throw DataGridException.Create( "Invalid visual child index.", ( m_dataGridContext != null ? m_dataGridContext.DataGridControl : null ) ); - } - } - - protected override UIElementCollection CreateUIElementCollection( FrameworkElement logicalParent ) - { - return new VirtualizingUICellCollection( m_fixedPanel, m_scrollingPanel, this ); - } - - protected override Size MeasureOverride( Size availableSize ) - { - // DataGridContext can be null when the parent Row is not prepared - if( m_dataGridContext == null ) - return this.DesiredSize; - - this.ApplyFixedTranform(); - - // If a change occured and did not triggered an UpdateMeasureRequiredEvent by the columnVirtualizationManager, we ensure the Row contains the necessary Cells - var columnVirtualizationManager = this.ColumnVirtualizationManager; - if( m_lastColumnVirtualizationManagerVersion != columnVirtualizationManager.Version ) - { - this.UpdateChildren(); - } - - double tempDesiredHeight = 0; - m_desiredSize.Width = 0; - - // Measure the Panels (visual children) around the cells (logical children). Logical children will not be measured again during this process. - m_fixedPanel.Measure( availableSize ); - - if( m_fixedPanel.DesiredSize.Height > tempDesiredHeight ) - { - tempDesiredHeight = m_fixedPanel.DesiredSize.Height; - } - - // Set the desired size for m_scrollingPanel which will be passed to the Decorated that will allow the first cell to be clipped - m_desiredSize.Width += columnVirtualizationManager.VisibleColumnsWidth; - - m_scrollingCellsDecorator.Measure( availableSize ); - - if( m_scrollingCellsDecorator.DesiredSize.Height > tempDesiredHeight ) - { - tempDesiredHeight = m_scrollingCellsDecorator.DesiredSize.Height; - } - - m_desiredSize.Height = tempDesiredHeight; - - if( !double.IsPositiveInfinity( availableSize.Width ) && !m_dataGridContext.IsAFlattenDetail ) - { - m_dataGridContext.ColumnStretchingManager.CalculateColumnStretchWidths( availableSize.Width, this.ColumnStretchMode, - this.ColumnStretchMinWidth, m_dataGridContext.CanIncreaseColumnWidth ); - - // Since a panel can make a column change its width, and since this will invalidate every panel that has already been measured, only a decreasing value - // is allowd to be set from one panel to another, so the layout pass does not fall into an infinite loop of increasing and decreasing values. - m_dataGridContext.CanIncreaseColumnWidth = false; - } - - // Adjust TabIndex of fixed cell and scrolling cell for the tab navigation to be ok - this.AdjustCellTabIndex( columnVirtualizationManager ); - - return m_desiredSize; - } - - protected override Size ArrangeOverride( Size finalSize ) - { - // DataGridContext can be null when the parent Row is not prepared - if( m_dataGridContext == null ) - return this.DesiredSize; - - // Very simple horizontally Arrange implementation. We use m_visualChildren instead of GetVisualChild(index) - // to ensure the sub panels are always arranged in the correct visible order - int childrenCount = m_visualChildren.Count; - Rect finalRect = new Rect( finalSize ); - double offset = 0d; - - UIElement element; - - for( int i = 0; i < childrenCount; i++ ) - { - element = m_visualChildren[ i ]; - if( element != null ) - { - finalRect.X = offset; - finalRect.Width = element.DesiredSize.Width; - finalRect.Height = Math.Max( finalSize.Height, element.DesiredSize.Height ); - element.Arrange( finalRect ); - - offset += finalRect.Width; - } - } - - return finalSize; - } - - // Returns the visible index of a column by its visible position - internal static int CalculateVisibleIndex( int visiblePosition, HashedLinkedList columnsByVisiblePosition ) - { - if( columnsByVisiblePosition == null ) - return -1; - - int visibleIndex = 0; - LinkedListNode tempNode = columnsByVisiblePosition.First; - - for( int i = 0; i < visiblePosition; i++ ) - { - if( tempNode == null ) - break; - - if( tempNode.Value.Visible ) - { - visibleIndex++; - } - - tempNode = tempNode.Next; - } - - return visibleIndex; - } - - internal double GetFixedWidth() - { - var offset = VisualTreeHelper.GetOffset( m_scrollingCellsDecorator ).X; - var parent = VisualTreeHelper.GetParent( this ); - - while( parent != null ) - { - if( parent is Row ) - { - offset = this.TransformToAncestor( parent as Visual ).Transform( new Point( offset, 0 ) ).X; - break; - } - - parent = VisualTreeHelper.GetParent( parent ); - } - - return offset; - } - - internal ScrollViewer GetParentScrollViewer() - { - if( m_parentScrollViewer == null ) - { - m_parentScrollViewer = TableViewScrollViewer.GetParentScrollViewer( this ); - } - - return m_parentScrollViewer; - } - - internal bool ForceScrollingCellToLayout( Cell cell ) - { - bool retVal = false; - - if( cell == null ) - return retVal; - - // We do not want any template cells to be added to/removed from visual tree - Debug.Assert( !Row.GetIsTemplateCell( cell ), "We should never insert template cells" ); - - ColumnBase parentColumn = cell.ParentColumn; - Debug.Assert( parentColumn != null, "The cell doesn't have a parent column" ); - - CellCollection parentRowCells = this.ParentRowCells; - Debug.Assert( parentRowCells != null ); - - Cell targetCell = parentRowCells[ parentColumn ]; - Debug.Assert( targetCell == cell, "The forced cell is inappropriate" ); - - retVal = this.MoveCellToScrollingPanel( cell ); - - // Keep the field name in order to inform the scrolling sub-panel to measure and arrange the target cell. - retVal = this.AddPermanentScrollingFieldNamesIfOutOfViewColumn( parentColumn.FieldName ) || retVal; - - return retVal; - } - - internal void PrepareVirtualizationMode( DataGridContext dataGridContext ) - { - var columnVirtualizationManager = dataGridContext.ColumnVirtualizationManager as TableViewColumnVirtualizationManagerBase; - if( columnVirtualizationManager == null ) - return; - - var parentRowCells = this.ParentRowCells; - m_virtualizationMode = columnVirtualizationManager.VirtualizationMode; - parentRowCells.VirtualizationMode = m_virtualizationMode; - - //Cells provided through Row.Cells (in xaml for instance) must be merged now. - parentRowCells.MergeFreeCells(); - - //Check if the mode is virutalizing without cell recycling - if( m_virtualizationMode != ColumnVirtualizationMode.Virtualizing ) - return; - - //In this mode, cells for all visible columns are automatically generated (speeds up first time horizontal scrolling). - m_generateMissingCellsDispatcherOperation = this.Dispatcher.BeginInvoke( new Action( this.GenerateMissingCells ), DispatcherPriority.Input, 0 ); - } - - private void FixedCellPanelLayoutUpdated( object sender, EventArgs e ) - { - if( m_dataGridContext == null ) - return; - - // Once the layout pass is done, the flag must be reset so the width of columns can be resized. - m_dataGridContext.CanIncreaseColumnWidth = true; - } - - private void MoveCellToFixedPanel( Cell movingCell ) - { - if( movingCell == null ) - return; - - UIElementCollection origin = m_scrollingPanel.Children; - UIElementCollection destination = m_fixedPanel.Children; - - //The VisualTree is altered only if the cells isn't in the appropriate location. - if( !destination.Contains( movingCell ) ) - { - //Transfer the cell from one panel to the other. - origin.Remove( movingCell ); - destination.Add( movingCell ); - } - } - - private bool MoveCellToScrollingPanel( Cell movingCell ) - { - bool retVal = false; - - if( movingCell == null ) - return retVal; - - UIElementCollection origin = m_fixedPanel.Children; - UIElementCollection destination = m_scrollingPanel.Children; - - //The VisualTree is altered only if the cells isn't in the appropriate location. - if( !destination.Contains( movingCell ) ) - { - //Transfer the cell from one panel to the other. - origin.Remove( movingCell ); - destination.Add( movingCell ); - retVal = true; - } - - return retVal; - } - - private void RemoveCellFromFixedOrScrollingPanel( Cell cell ) - { - if( cell == null ) - return; - - m_fixedPanel.Children.Remove( cell ); - m_scrollingPanel.Children.Remove( cell ); - } - - private IEnumerable GetPreviousLocationsOf( ColumnHierarchyManager.ILocation location ) - { - if( location == null ) - yield break; - - var previousLocation = location.GetPreviousSiblingOrCousin(); - while( previousLocation != null ) - { - yield return previousLocation; - previousLocation = previousLocation.GetPreviousSiblingOrCousin(); - } - } - - private IEnumerable GetNextLocationsOf( ColumnHierarchyManager.ILocation location ) - { - if( location == null ) - yield break; - - var nextLocation = location.GetNextSiblingOrCousin(); - while( nextLocation != null ) - { - yield return nextLocation; - nextLocation = nextLocation.GetNextSiblingOrCousin(); - } - } - - private IEnumerable GetColumnLocations( IEnumerable locations ) - { - if( locations == null ) - return Enumerable.Empty(); - - return ( from location in locations - let columnLocation = location as ColumnHierarchyManager.IColumnLocation - where ( columnLocation != null ) - select columnLocation ); - } - - private bool IsDropMarkAtDropTarget( DropTarget dropTarget ) - { - if( ( dropTarget == null ) || ( m_dataGridContext == null ) ) - return false; - - var columnManager = m_dataGridContext.ColumnManager; - var levelMarkers = columnManager.GetLevelMarkersFor( dropTarget.Columns ); - if( levelMarkers == null ) - return false; - - var splitterLocation = levelMarkers.Splitter; - Debug.Assert( splitterLocation != null ); - if( splitterLocation == null ) - return false; - - // The drop mark location should not be adjusted when the only thing that is between the splitter and - // the target location are hidden columns. - if( dropTarget.Type != DropTargetType.Column ) - { - var locations = ( dropTarget.Before ) ? this.GetNextLocationsOf( splitterLocation ) : this.GetPreviousLocationsOf( splitterLocation ); - - return this.GetColumnLocations( locations ).All( columnLocation => !columnLocation.Column.Visible ); - } - else - { - Debug.Assert( dropTarget.Column != null ); - - foreach( var columnLocation in this.GetColumnLocations( this.GetPreviousLocationsOf( splitterLocation ) ) ) - { - var column = columnLocation.Column; - if( column == dropTarget.Column ) - { - if( dropTarget.Before ) - return !column.Visible; - - return true; - } - - if( column.Visible ) - break; - } - - foreach( var columnLocation in this.GetColumnLocations( this.GetNextLocationsOf( splitterLocation ) ) ) - { - var column = columnLocation.Column; - if( column == dropTarget.Column ) - { - if( !dropTarget.Before ) - return !column.Visible; - - return true; - } - - if( column.Visible ) - break; - } - } - - return false; - } - - private bool ShowDropMark() - { - if( ( m_dragDropState == null ) || ( m_dataGridContext == null ) ) - return false; - - var scrollViewer = TableViewScrollViewer.GetParentTableViewScrollViewer( this ); - if( scrollViewer == null ) - return false; - - var parentRowCells = this.ParentRowCells; - if( parentRowCells == null ) - return false; - - var dropTarget = m_dragDropState.DropTarget; - var targetCell = default( Cell ); - var showDropMarkBeforeTargetCell = ( dropTarget != null ) ? dropTarget.Before : false; - - if( ( dropTarget != null ) && !this.IsDropMarkAtDropTarget( dropTarget ) ) - { - var dropTargetLocation = default( ColumnHierarchyManager.ILocation ); - - if( dropTarget.Type == DropTargetType.Column ) - { - Debug.Assert( dropTarget.Column != null ); - dropTargetLocation = m_dataGridContext.ColumnManager.GetColumnLocationFor( dropTarget.Column ); - } - else - { - var levelMarkers = m_dataGridContext.ColumnManager.GetLevelMarkersFor( dropTarget.Columns ); - if( levelMarkers == null ) - return false; - - switch( dropTarget.Type ) - { - case DropTargetType.Start: - dropTargetLocation = levelMarkers.Start; - break; - - case DropTargetType.Orphan: - dropTargetLocation = levelMarkers.Orphan; - break; - - default: - throw new NotImplementedException(); - } - } - - if( dropTargetLocation == null ) - return false; - - // Since the drop target may be a hidden column, we must look for the first visible column - // next to it since the calculation requires a cell. - { - var columnLocation = dropTargetLocation as ColumnHierarchyManager.IColumnLocation; - if( ( columnLocation != null ) && columnLocation.Column.Visible ) - { - if( !parentRowCells.TryGetBindedCell( columnLocation.Column, false, out targetCell ) ) - return false; - } - } - - if( targetCell == null ) - { - foreach( var columnLocation in this.GetColumnLocations( this.GetPreviousLocationsOf( dropTargetLocation ) ) ) - { - if( !columnLocation.Column.Visible ) - continue; - - if( !parentRowCells.TryGetBindedCell( columnLocation.Column, false, out targetCell ) ) - continue; - - showDropMarkBeforeTargetCell = false; - break; - } - } - - if( targetCell == null ) - { - foreach( var columnLocation in this.GetColumnLocations( this.GetNextLocationsOf( dropTargetLocation ) ) ) - { - if( !columnLocation.Column.Visible ) - continue; - - if( !parentRowCells.TryGetBindedCell( columnLocation.Column, false, out targetCell ) ) - continue; - - showDropMarkBeforeTargetCell = true; - break; - } - } - } - - double dropMarkOffset = 0; - - if( targetCell != null ) - { - if( showDropMarkBeforeTargetCell ) - { - dropMarkOffset = targetCell.TranslatePoint( new Point(), scrollViewer ).X; - } - else - { - dropMarkOffset = targetCell.TranslatePoint( new Point( targetCell.ActualWidth, 0d ), scrollViewer ).X; - } - } - else - { - return false; - } - - var adorner = m_dragDropState.DropMarkAdorner; - if( adorner == null ) - { - // FixedCellPanel can only be used in a Horizontal manner. We can afford to plug this vertical handling of drop mark. - var pen = this.FixedColumnDropMarkPen; - if( pen == null ) - { - var dropMarkWidth = 1d; - - pen = new Pen( Brushes.Gray, dropMarkWidth ); - } - - adorner = new DropMarkAdorner( scrollViewer, pen, DropMarkOrientation.Vertical ); - adorner.HorizontalPosition = dropMarkOffset; - - var adornerLayer = AdornerLayer.GetAdornerLayer( scrollViewer ); - if( adornerLayer != null ) - { - adornerLayer.Add( adorner ); - } - - m_dragDropState.DropMarkAdorner = adorner; - } - else - { - adorner.HorizontalPosition = dropMarkOffset; - } - - return true; - } - - private void HideDropMark() - { - if( m_dragDropState == null ) - return; - - var adorner = m_dragDropState.DropMarkAdorner; - if( adorner == null ) - return; - - var adornerLayer = AdornerLayer.GetAdornerLayer( adorner.AdornedElement ); - if( adornerLayer != null ) - { - adornerLayer.Remove( adorner ); - } - - m_dragDropState.DropMarkAdorner = null; - } - - private void UpdateChildren() - { - // If the parent Row is not prepared, do not update children. - // And contrary to this.UpdateChildren( UpdateMeasureTriggeredAction action ), m_dataGridContext can be null here, since it is from a dispatched call. - if( m_dataGridContext == null ) - return; - - this.UpdateChildren( UpdateMeasureTriggeredAction.Unspecified ); - } - - private void UpdateChildren( UpdateMeasureTriggeredAction action ) - { - Debug.Assert( m_dataGridContext != null, "Should not be called when a container is not prepared" ); - - // If the parent Row is not prepared, do not update children - if( m_dataGridContext == null ) - return; - - Row parentRow = this.ParentRow; - - // A CurrentItemChanged was received for a non current Row - if( ( action == UpdateMeasureTriggeredAction.CurrentItemChanged ) && ( parentRow != null ) && ( !parentRow.IsCurrent ) ) - return; - - bool currentItemChangedOnCurrentRow = ( action == UpdateMeasureTriggeredAction.CurrentItemChanged ) && ( parentRow != null ) && ( parentRow.IsCurrent ); - var columnVirtualizationManager = this.ColumnVirtualizationManager; - - if( ( m_lastColumnVirtualizationManagerVersion != columnVirtualizationManager.Version ) || ( currentItemChangedOnCurrentRow ) - || ( m_virtualizingCellCollectionChangedDispatcherOperation != null ) ) - { - this.UpdateChildren( columnVirtualizationManager ); - - m_lastColumnVirtualizationManagerVersion = columnVirtualizationManager.Version; - - this.InvalidateMeasure(); - - m_virtualizingCellCollectionChangedDispatcherOperation = null; - } - } - - private void UpdateChildren( TableViewColumnVirtualizationManagerBase columnVirtualizationManager ) - { - var parentRowCells = this.ParentRowCells; - - //Prevent reentrance - if( ( parentRowCells == null ) || parentRowCells.IsUpdating ) - return; - - using( parentRowCells.SetIsUpdating() ) - { - //If in virtualizing mode but not recycling cells. - if( m_virtualizationMode == ColumnVirtualizationMode.Virtualizing ) - { - //Retrieve the cells that aren't needed anymore. - var cellsToCollapse = this.GetCellsToCollapse( columnVirtualizationManager, parentRowCells ); - - //Simply hide these cells for now. - foreach( var cell in cellsToCollapse ) - { - if( cell.CanBeCollapsed ) - { - cell.Visibility = Visibility.Collapsed; - } - else - { - this.AddPermanentScrollingFieldNames( cell.FieldName ); - } - } - - //And do the actual processing after scrolling has stopped. - if( m_processUnusedCellsDispatcherOperation == null ) - { - m_processUnusedCellsDispatcherOperation = this.Dispatcher.BeginInvoke( new Action( this.ProcessCollapsedCells ), - DispatcherPriority.Background, columnVirtualizationManager ); - } - } - else - { - //If recycling cells, we need to process them now, in order to minimize cells' creation. - this.ProcessCollapsedCells( columnVirtualizationManager ); - } - - var fixedFieldNames = columnVirtualizationManager.GetFixedFieldNames( m_parentRow.LevelCache ).ToList(); - var scrollingFieldNames = columnVirtualizationManager.GetScrollingFieldNames( m_parentRow.LevelCache ).ToList(); - - //Add the missing cells to the fixed region. - foreach( string fieldName in fixedFieldNames ) - { - var cell = this.GetCell( fieldName, parentRowCells ); - - //Make sure the cell is in the appropriate panel. - this.MoveCellToFixedPanel( cell ); - - } - - //Add the missing cells to the scrolling region. - foreach( string fieldName in scrollingFieldNames ) - { - var cell = this.GetCell( fieldName, parentRowCells ); - - //Make sure the cell is in the appropriate panel. - this.MoveCellToScrollingPanel( cell ); - } - - m_fixedPanel.InvalidateMeasure(); - m_scrollingCellsDecorator.InvalidateMeasure(); - m_scrollingPanel.InvalidateMeasure(); - } - } - - private void ProcessCollapsedCells( TableViewColumnVirtualizationManagerBase columnVirtualizationManager ) - { - m_processUnusedCellsDispatcherOperation = null; - - if( m_dataGridContext == null ) - return; - - this.ClearPermanentScrollingFieldNames(); - - //Retrieve the cells that aren't needed anymore. - var collapsedCells = this.GetCellsToCollapse( columnVirtualizationManager, m_parentRowCells ); - - foreach( Cell cell in collapsedCells ) - { - var isCollapsible = cell.CanBeCollapsed; - - if( isCollapsible && cell.CanBeRecycled ) - { - // Ensure to close the ContextMenu if it is open and the Cell is virtualized to avoid problems with ContextMenus defined as static resources - // that won't be able to reopen again if the Close private method is called after the PlacementTarget is removed from the VisualTree - var contextMenu = cell.ContextMenu; - if( ( contextMenu != null ) && ( contextMenu.IsOpen ) ) - { - contextMenu.IsOpen = false; - } - - cell.ClearContainer(); - m_parentRowCells.Release( cell ); - } - else - { - //Certain non recyclable cells like StatCells needs their content binding to be removed when they become out of view. - cell.RemoveContentBinding(); - - //If in virtualizing mode but not recycling cells, release the cell so it will be collapsed, so no need to measure and arrange it. - if( isCollapsible && m_virtualizationMode == ColumnVirtualizationMode.Virtualizing ) - { - m_parentRowCells.Release( cell ); - } - else - { - //Since the cell cannot be released, it will not be collapsed. We must keep its fieldname - //in order to let the scrolling sub-panel measure and arrange the cell out of view. - this.AddPermanentScrollingFieldNames( cell.FieldName ); - } - } - } - } - - private List GetCellsToCollapse( TableViewColumnVirtualizationManagerBase columnVirtualizationManager, VirtualizingCellCollection parentRowCells ) - { - return ( from cell in parentRowCells.BindedCells - where !columnVirtualizationManager.GetScrollingFieldNames( m_parentRow.LevelCache ).Contains( cell.FieldName ) - && !columnVirtualizationManager.GetFixedFieldNames( m_parentRow.LevelCache ).Contains( cell.FieldName ) - select cell ).ToList(); - } - - private Cell GetCell( string fieldName, VirtualizingCellCollection parentRowCells ) - { - //The cell is created if it is missing. - var cell = parentRowCells[ fieldName ]; - - //Certain non recyclable cells like StatCells need their content binding to be updated when they become (or stay) in view. - cell.AddContentBinding( m_dataGridContext, m_parentRow, this.Columns[ fieldName ] ); - - //Only when in Virtualizing mode can the cell still be collapsed at this point, since parentRowCells[ fieldName ] will have uncollapsed it in other modes. - if( m_virtualizationMode == ColumnVirtualizationMode.Virtualizing ) - { - //The current local value must be cleared instead of setting a new local value to give a chance for a style to set a value. - cell.ClearValue( Cell.VisibilityProperty ); - } - - return cell; - } - - private void ApplyFixedTranform() - { - ScrollViewer parentScrollViewer = this.GetParentScrollViewer(); - - if( parentScrollViewer == null ) - return; - - Transform fixedTranslation = TableViewScrollViewer.GetStoredFixedTransform( parentScrollViewer ); - - if( m_fixedPanel.RenderTransform != fixedTranslation ) - { - m_fixedPanel.RenderTransform = fixedTranslation; - } - - if( m_scrollingCellsDecorator.RenderTransform != fixedTranslation ) - { - m_scrollingCellsDecorator.RenderTransform = fixedTranslation; - } - } - - private void AdjustCellTabIndex( TableViewColumnVirtualizationManagerBase columnVirtualizationManager ) - { - // The order of the children in the panel is not guaranteed to be good. We do not reorder children because we will have to remove - // and add them at a different location. Doing that will cause more calculations to occur, so we only change the TabIndex. - var parentRowCells = this.ParentRowCells; - if( parentRowCells == null ) - return; - - var fieldNameToPositionMapping = columnVirtualizationManager.GetFieldNameToPosition( m_parentRow.LevelCache ); - var fieldNames = columnVirtualizationManager.GetFixedFieldNames( m_parentRow.LevelCache ) - .Concat( columnVirtualizationManager.GetScrollingFieldNames( m_parentRow.LevelCache ) ) - .Concat( m_permanentScrollingFieldNames ); - - foreach( var fieldName in fieldNames ) - { - Cell cell = parentRowCells.GetCell( fieldName, false ); - Debug.Assert( cell != null ); - - int tabIndex; - if( fieldNameToPositionMapping.TryGetValue( fieldName, out tabIndex ) ) - { - KeyboardNavigation.SetTabIndex( cell, tabIndex ); - } - else - { - cell.ClearValue( Cell.TabIndexProperty ); - } - } - } - - private void GenerateMissingCells( int index ) - { - m_generateMissingCellsDispatcherOperation = null; - - if( m_dataGridContext == null ) - { - // The row is being recycled without having been prepared properly. By setting these properties, - // it will be correctly prepare when used again (through IVirtualizingCellsHost.PrepareCellsHost()). - m_virtualizationModeChanged = true; - m_virtualizingCellCollectionUpdateRequired = true; - return; - } - - DateTime startTime = DateTime.UtcNow; - - //Generate cells only for visible columns - var columns = this.VisibleColumns; - var parentRowCells = this.ParentRowCells; - var count = columns.Count; - var actualIndex = count; - - for( int i = index; i < count; i++ ) - { - var column = columns[ i ]; - - if( parentRowCells.HasVirtualizedCell( column.FieldName ) ) - continue; - - var cell = parentRowCells.AddVirtualizedCell( column ); - - //Though the cell has been newly prepared to provide better first time scrolling, it needs to be cleared like any other out of view cell. - //For non releasable cells (like StatCell), it's been properly processed in Row.PrepareUnbindedCell(), in the previous call. - if( cell.CanBeRecycled ) - { - cell.ClearContainer(); - } - - if( DateTime.UtcNow.Subtract( startTime ) > FixedCellPanel.MaxProcessDurationTime ) - { - actualIndex = i + 1; - break; - } - } - - if( actualIndex == count ) - return; - - //If there is still cells to generate, dispatch again. - m_generateMissingCellsDispatcherOperation = this.Dispatcher.BeginInvoke( new Action( this.GenerateMissingCells ), DispatcherPriority.Input, actualIndex ); - } - - private void GenerateOrRemoveCell( ColumnBase column ) - { - Debug.Assert( column != null ); - - var parentRowCells = this.ParentRowCells; - - switch( m_virtualizationMode ) - { - case ColumnVirtualizationMode.None: - { - if( !column.Visible ) - { - Cell cell; - if( parentRowCells.TryGetBindedCell( column, false, out cell ) ) - { - //Only remove cells that can be generated without any unique configuration (e.g. no custom template, no ResultPropertyName, etc..) - if( cell.CanBeRecycled ) - { - parentRowCells.InternalRemove( cell ); - } - } - } - break; - } - - case ColumnVirtualizationMode.Recycling: - { - if( !column.Visible && ( m_synchronizeRecyclingBinsDispatcherOperation == null ) ) - { - m_synchronizeRecyclingBinsDispatcherOperation = this.Dispatcher.BeginInvoke( DispatcherPriority.Background, - new Action( this.SynchronizeRecyclingBinsWithRecyclingGroups ) ); - } - break; - } - - case ColumnVirtualizationMode.Virtualizing: - { - if( column.Visible ) - { - if( !parentRowCells.HasVirtualizedCell( column.FieldName ) ) - { - parentRowCells.AddVirtualizedCell( column ); - } - break; - } - - parentRowCells.RemoveVirtualizedCell( column ); - break; - } - } - } - - private void UpdateVirtualizationMode() - { - var columnVirtualizationManager = this.ColumnVirtualizationManager; - if( columnVirtualizationManager == null ) - return; - - var parentRowCells = this.ParentRowCells; - m_virtualizationMode = columnVirtualizationManager.VirtualizationMode; - parentRowCells.VirtualizationMode = m_virtualizationMode; - - switch( m_virtualizationMode ) - { - case ColumnVirtualizationMode.None: - { - //Not virtualizing - parentRowCells.BindRecycledCells( this.Columns ); - parentRowCells.BindVirtualizedCells(); - break; - } - - case ColumnVirtualizationMode.Recycling: - { - //Virtualizing and recycling - parentRowCells.ClearOutOfViewBindedCells( this.GetCellsToCollapse( columnVirtualizationManager, parentRowCells ) ); - parentRowCells.ClearVirtualizedCells(); - break; - } - - case ColumnVirtualizationMode.Virtualizing: - { - //Virtualizing with no recycling - this.ProcessCollapsedCells( columnVirtualizationManager ); - parentRowCells.VirtualizeRecycledCells(); - if( m_generateMissingCellsDispatcherOperation == null ) - { - this.GenerateMissingCells( 0 ); - } - break; - } - } - } - - private void SynchronizeRecyclingBinsWithRecyclingGroups() - { - m_synchronizeRecyclingBinsDispatcherOperation = null; - - if( m_dataGridContext == null ) - return; - - m_parentRowCells.SynchronizeRecyclingBinsWithRecyclingGroups( this.VisibleColumns ); - } - - private FrameworkElement GetPreparedContainer( Cell cell ) - { - if( cell == null ) - return null; - - var parentRow = cell.ParentRow; - if( parentRow == null ) - return null; - - // Use the DataGridControl.Container attached property to assert a container is always returned even if the container is in FixedHeaders or FixedFooters. - var container = DataGridControl.GetContainer( parentRow ); - if( container == null ) - return null; - - if( !DataGridControl.GetIsContainerPrepared( container ) ) - return null; - - return container; - } - - private static object CoerceMinHeight( DependencyObject sender, object value ) - { - var self = sender as FixedCellPanel; - if( self == null ) - return value; - - return self.CoerceMinHeight( new Thickness(), value ); - } - - private static void InvalidateMinHeight( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - var self = sender as FixedCellPanel; - if( self == null ) - return; - - self.CoerceValue( FixedCellPanel.MinHeightProperty ); - } - - #region ZOrder Management - - private void RecomputeZOrder() - { - ZOrderHelper.ComputeZOrder( m_visualChildren, ref m_zIndexMapping ); - m_zOrderDirty = false; - } - - private void InvalidateZOrder() - { - m_zOrderDirty = true; - } - - internal bool ChangeCellZOrder( Cell cell, int zIndex ) - { - bool zOrderChanged = false; - - UIElement panelToChangeZOrder = null; - - // Ensure the ZOrder is also considered by the panel containing the Cell - if( m_fixedPanel.Children.Contains( cell ) ) - { - panelToChangeZOrder = m_fixedPanel; - } - else - { - panelToChangeZOrder = m_scrollingCellsDecorator; - } - - if( object.Equals( zIndex, DependencyProperty.UnsetValue ) ) - { - if( panelToChangeZOrder.ReadLocalValue( Panel.ZIndexProperty ) != DependencyProperty.UnsetValue ) - { - panelToChangeZOrder.ClearValue( Panel.ZIndexProperty ); - this.InvalidateZOrder(); - - zOrderChanged = true; - } - } - else - { - if( !object.Equals( panelToChangeZOrder.GetValue( Panel.ZIndexProperty ), zIndex ) ) - { - panelToChangeZOrder.SetValue( Panel.ZIndexProperty, zIndex ); - this.InvalidateZOrder(); - - zOrderChanged = true; - } - } - - Panel.SetZIndex( cell, zIndex ); - - return zOrderChanged; - } - - internal void ClearCellZOrder( Cell cell ) - { - m_fixedPanel.ClearValue( Panel.ZIndexProperty ); - m_scrollingCellsDecorator.ClearValue( Panel.ZIndexProperty ); - cell.ClearValue( Panel.ZIndexProperty ); - this.InvalidateZOrder(); - } - - #endregion - - #region IVirtualizingCellsHost Members - - bool IVirtualizingCellsHost.CanModifyLogicalParent - { - get - { - return true; - } - } - - void IVirtualizingCellsHost.ClearLogicalParent( Cell cell ) - { - Debug.Assert( cell != null ); - - VirtualizingUICellCollection cellCollection = this.Children as VirtualizingUICellCollection; - - Debug.Assert( cellCollection != null ); - - cellCollection.ClearCellLogicalParent( cell ); - - this.RemoveCellFromFixedOrScrollingPanel( cell ); - } - - void IVirtualizingCellsHost.SetLogicalParent( Cell cell ) - { - Debug.Assert( cell != null ); - - VirtualizingUICellCollection cellCollection = this.Children as VirtualizingUICellCollection; - - Debug.Assert( cellCollection != null ); - - cellCollection.SetCellLogicalParent( cell ); - - this.MoveCellToScrollingPanel( cell ); - } - - void IVirtualizingCellsHost.PrepareCellsHost( DataGridContext dataGridContext ) - { - // This method is called in Row.PrepareContainer and Row.OnApplyTemplate, which is also called in Row.PrepareContainer but only if the template - // was not previously applied, so it is possible that this panel is already prepared. In that case, we only ignore this preparation. - if( m_cellsHostPrepared ) - return; - - if( dataGridContext != null ) - { - m_dataGridContext = dataGridContext; - - object dataItem = this.ParentRow.DataContext; - - foreach( Cell cell in this.CellsInView ) - { - cell.PrepareContainer( dataGridContext, dataItem ); - } - - var columnVirtualizationManager = this.ColumnVirtualizationManager; - - //If the manager has changed, make sure to stop listening to it. - if( columnVirtualizationManager != m_previousColumnVirtualizationManager ) - { - VirtualizingCellCollectionUpdateRequiredEventManager.RemoveListener( m_previousColumnVirtualizationManager, this ); - VirtualizingCellCollectionUpdateRequiredEventManager.AddListener( columnVirtualizationManager, this ); - } - - UpdateMeasureRequiredEventManager.AddListener( columnVirtualizationManager, this ); - m_previousColumnVirtualizationManager = columnVirtualizationManager; - - var parentRowCells = this.ParentRowCells; - if( parentRowCells != null ) - { - VirtualizingCellCollectionChangedEventManager.AddListener( parentRowCells, this ); - } - - //When pulling a row from the recycling pool, need to make sure it is in the correct virtualization mode and its VirtualzingCellCollection is update to date. - if( m_virtualizingCellCollectionUpdateRequired ) - { - m_virtualizingCellCollectionUpdateRequired = false; - - if( m_virtualizationModeChanged ) - { - m_virtualizationModeChanged = false; - this.UpdateVirtualizationMode(); - } - - if( m_visibleColumnsChanged ) - { - m_visibleColumnsChanged = false; - var columns = this.Columns; - foreach( WeakReference weakRef in m_changedVisibleColumns ) - { - var column = weakRef.Target as ColumnBase; - - if( ( column == null ) || !columns.Contains( column ) ) - continue; - - this.GenerateOrRemoveCell( column ); - } - m_changedVisibleColumns.Clear(); - m_changedVisibleColumns.TrimExcess(); - } - - if( m_visibleColumnsAdded ) - { - m_visibleColumnsAdded = false; - this.GenerateMissingCells( 0 ); - } - } - - m_cellsHostPrepared = true; - } - } - - void IVirtualizingCellsHost.ClearCellsHost() - { - if( !m_cellsHostPrepared ) - return; - - var parentRowCells = this.ParentRowCells; - if( parentRowCells != null ) - { - VirtualizingCellCollectionChangedEventManager.RemoveListener( parentRowCells, this ); - } - - //Make sure to stop listening from the same manager it started to listen from. - UpdateMeasureRequiredEventManager.RemoveListener( m_previousColumnVirtualizationManager, this ); - - m_dataGridContext = null; - m_cellsHostPrepared = false; - } - - void IVirtualizingCellsHost.InvalidateCellsHostMeasure() - { - if( m_dataGridContext == null ) - return; - - this.InvalidateMeasure(); - m_fixedPanel.InvalidateMeasure(); - m_scrollingCellsDecorator.InvalidateMeasure(); - m_scrollingPanel.InvalidateMeasure(); - } - - bool IVirtualizingCellsHost.BringIntoView( Cell cell, RequestBringIntoViewEventArgs e ) - { - // This cell doesn't seem to be in the grid. We return true to handle the event that triggered the BringIntoView. - var dataGridContext = DataGridControl.GetDataGridContext( this ); - if( dataGridContext == null ) - return true; - - // If the container is not in use, we return true to handle the event that triggered the BringIntoView. - var container = this.GetPreparedContainer( cell ); - if( container == null ) - return true; - - // The ScrollViewer can handle the bring into view if the grid isn't virtualized. - var scrollViewer = this.ParentScrollViewer; - if( ( scrollViewer == null ) || !scrollViewer.CanContentScroll ) - return false; - - // This cell seems to be dead. We return true to handle the event that triggered the BringIntoView. - var row = cell.ParentRow; - var column = cell.ParentColumn; - if( ( row == null ) || ( column == null ) ) - return true; - - var columnVirtualizationManager = this.ColumnVirtualizationManager; - - // Fixed cells are always visible. - if( columnVirtualizationManager.GetFixedFieldNames( row.LevelCache ).Contains( column ) ) - return this.BringIntoViewFixedCell( container ); - - return this.BringIntoViewScrollingCell( cell, container, e ); - } - - private bool BringIntoViewFixedCell( FrameworkElement container ) - { - Debug.Assert( container != null ); - - // We always want the horizontal offset to change if Tab, Home, Left or Right is pressed. - if( Keyboard.IsKeyDown( Key.Tab ) || Keyboard.IsKeyDown( Key.Home ) || Keyboard.IsKeyDown( Key.Left ) || Keyboard.IsKeyDown( Key.Right ) ) - { - container.BringIntoView( new Rect( 0d, 0d, 0d, 0d ) ); - } - else - { - // Ensure to bring the container into view vertically. - container.BringIntoView(); - } - - return true; - } - - private bool BringIntoViewScrollingCell( Cell cell, FrameworkElement container, RequestBringIntoViewEventArgs e ) - { - Debug.Assert( cell != null ); - Debug.Assert( container != null ); - - // The cell must be measured/arranged for the BringIntoView to correctly reacts - if( this.ForceScrollingCellToLayout( cell ) ) - { - container.UpdateLayout(); - } - - var fixedWidth = this.GetFixedWidth(); - var viewportWidth = this.ParentScrollViewer.ViewportWidth; - - //If fixed cells fill the entire viewport, then there is no scrolling cell that can be brought in to view, simply return. - if( fixedWidth >= viewportWidth ) - return true; - - var scrollingPanel = this.ScrollingCellsDecorator; - var scrollingArea = new Rect( scrollingPanel.TranslatePoint( new Point(), this ), new Size( viewportWidth - fixedWidth, scrollingPanel.ActualHeight ) ); - var cellArea = new Rect( cell.TranslatePoint( new Point(), this ), new Size( cell.ParentColumn.ActualWidth, cell.ActualHeight ) ); - - // The cell is larger than the scrolling area. - if( cellArea.Width > scrollingArea.Width ) - { - var targetObject = e.TargetObject as UIElement; - var targetRect = e.TargetRect; - - // Try to narrow the area within the cell that we clearly want to bring into view. - if( ( targetObject != null ) && ( targetObject != cell || !targetRect.IsEmpty ) ) - { - Debug.Assert( targetObject.IsDescendantOf( cell ) ); - - if( targetRect.IsEmpty ) - { - targetRect = new Rect( new Point( 0d, 0d ), targetObject.RenderSize ); - } - - if( targetRect.Width <= scrollingArea.Width ) - { - var offset = targetObject.TranslatePoint( new Point(), cell ); - var location = cellArea.Location; - location.Offset( offset.X, offset.Y ); - - cellArea.Location = location; - cellArea.Size = targetRect.Size; - } - } - } - - if( ( cellArea.Left <= scrollingArea.Left ) && ( cellArea.Right >= scrollingArea.Right ) ) - { - // Ensure to bring the container into view vertically. - container.BringIntoView(); - } - else if( cellArea.Left < scrollingArea.Left ) - { - // The ScrollViewer's extent width includes the fixed section. We must offset the target area or the cell - // will come into view under the fixed panel. - cellArea.X -= fixedWidth; - - this.BringIntoView( cellArea ); - } - else if( cellArea.Right > scrollingArea.Right ) - { - this.BringIntoView( cellArea ); - } - // The cell is fully visible. - else - { - // Ensure to bring the container into view vertically. - container.BringIntoView(); - } - - return true; - } - - #endregion - - #region IWeakEventListener Members - - 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( managerType == typeof( UpdateMeasureRequiredEventManager ) ) - { - var action = UpdateMeasureTriggeredAction.Unspecified; - var eventArgs = e as UpdateMeasureRequiredEventArgs; - - if( eventArgs != null ) - { - action = eventArgs.TriggeredAction; - } - - this.UpdateChildren( action ); - } - else if( managerType == typeof( VirtualizingCellCollectionUpdateRequiredEventManager ) ) - { - var eventArgs = e as VirtualizingCellCollectionUpdateRequiredEventArgs; - - switch( eventArgs.TriggeredAction ) - { - case VirtualizingCellCollectionUpdateTriggeredAction.VirtualizationModeChanged: - { - if( !m_cellsHostPrepared ) - { - m_virtualizationModeChanged = true; - m_virtualizingCellCollectionUpdateRequired = true; - break; - } - - this.UpdateVirtualizationMode(); - break; - } - - case VirtualizingCellCollectionUpdateTriggeredAction.VisibleColumnsChanged: - { - var columns = eventArgs.Columns; - if( ( columns == null ) || ( columns.Count <= 0 ) ) - break; - - if( !m_cellsHostPrepared ) - { - foreach( var column in columns ) - { - m_changedVisibleColumns.Add( new WeakReference( column ) ); - } - - m_visibleColumnsChanged = true; - m_virtualizingCellCollectionUpdateRequired = true; - break; - } - - //A column was added or removed from VisibleColumns. - foreach( var column in columns ) - { - this.GenerateOrRemoveCell( column ); - } - break; - } - - //This action will be triggered only when in Virtualizing mode, so no need to check it. - //No need to handle Remove, Replace, Reset, since every row will be flushed and recreated, and rows present in recycle bins will simply be flushed. - case VirtualizingCellCollectionUpdateTriggeredAction.VisibleColumnsAdded: - { - if( !m_cellsHostPrepared ) - { - m_visibleColumnsAdded = true; - m_virtualizingCellCollectionUpdateRequired = true; - break; - } - - if( m_generateMissingCellsDispatcherOperation == null ) - { - this.GenerateMissingCells( 0 ); - } - break; - } - } - } - else if( managerType == typeof( VirtualizingCellCollectionChangedEventManager ) ) - { - //Changes to the Cells collection (i.e. VirtualizingCellCollection) can come directly from the Row.Cells property, without the FixedCellPanel knowing about it. - //So it needs to be informed if this is the case, since it is the FixedCellPanel responsablility to correctly manage and recycle cells. - //However, if changes to Cells come from the FixedCellPanel itself, of course there is nothing to do. - if( !m_parentRowCells.IsUpdating ) - { - //Update cells as rarely as possible, so performance is not affected by this (for instance when Row.Cells is updated in a loop, do it once at the end). - if( m_virtualizingCellCollectionChangedDispatcherOperation == null ) - { - m_virtualizingCellCollectionChangedDispatcherOperation = this.Dispatcher.BeginInvoke( DispatcherPriority.Render, new Action( this.UpdateChildren ) ); - } - } - } - else - { - return false; - } - - return true; - } - - #endregion - - private int m_lastColumnVirtualizationManagerVersion = -1; - private Row m_parentRow; // = null; - private ScrollViewer m_parentScrollViewer; // = null; - private bool m_cellsHostPrepared; //false - private bool m_zOrderDirty; //false - - private Size m_desiredSize = new Size(); - private VirtualizingCellCollection m_parentRowCells; // = null; - - private DragDropState m_dragDropState = null; - - // The immediate visual children of this panel. - private FixedCellSubPanel m_fixedPanel; - private ScrollingCellsDecorator m_scrollingCellsDecorator; - private VirtualizingFixedCellSubPanel m_scrollingPanel; - - private int[] m_zIndexMapping; // = null; - - private const int c_visualChildrenCount = 3; - private readonly IList m_visualChildren = new List(); - - private DataGridContext m_dataGridContext; // = null; - private TableViewColumnVirtualizationManagerBase m_previousColumnVirtualizationManager; // = null; - - private DispatcherOperation m_processUnusedCellsDispatcherOperation; // = null; - private DispatcherOperation m_virtualizingCellCollectionChangedDispatcherOperation; - private DispatcherOperation m_generateMissingCellsDispatcherOperation; - private DispatcherOperation m_synchronizeRecyclingBinsDispatcherOperation; - private ColumnVirtualizationMode m_virtualizationMode; - private List m_changedVisibleColumns = new List(); - private bool m_virtualizingCellCollectionUpdateRequired; - private bool m_virtualizationModeChanged; - private bool m_visibleColumnsChanged; - private bool m_visibleColumnsAdded; - - #region DragDropState Private Class - - private sealed class DragDropState - { - internal DragDropState( double splitterOffset ) - { - m_initialSplitterOffset = splitterOffset; - } - - internal double InitialSplitterOffset - { - get - { - return m_initialSplitterOffset; - } - } - - internal DropMarkAdorner DropMarkAdorner - { - get; - set; - } - - internal DropTarget DropTarget - { - get; - set; - } - - private readonly double m_initialSplitterOffset; - } - - #endregion - - #region DropTarget Private Class - - private sealed class DropTarget - { - internal DropTarget( DropTargetType type, ColumnCollection columns ) - { - if( ( type != DropTargetType.Start ) && ( type != DropTargetType.Orphan ) ) - throw new ArgumentException( "The drop target must be a Start or Orphan target type.", "type" ); - - m_type = type; - m_column = default( ColumnBase ); - m_before = ( type == DropTargetType.Orphan ); - m_columns = columns; - } - - internal DropTarget( ColumnBase column, bool before, ColumnCollection columns ) - { - if( column == null ) - throw new ArgumentNullException( "column" ); - - m_type = DropTargetType.Column; - m_column = column; - m_before = before; - m_columns = columns; - } - - internal DropTargetType Type - { - get - { - return m_type; - } - } - - internal ColumnBase Column - { - get - { - return m_column; - } - } - - internal bool Before - { - get - { - return m_before; - } - } - - internal ColumnCollection Columns - { - get - { - return m_columns; - } - } - - private readonly DropTargetType m_type; - private readonly ColumnBase m_column; - private readonly ColumnCollection m_columns; - private readonly bool m_before; - } - - #endregion - - #region DropTargetType Private Enum - - private enum DropTargetType - { - Column = 0, - Start, - Orphan - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/FixedCellSubPanel.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/FixedCellSubPanel.cs deleted file mode 100644 index 5946c317..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/FixedCellSubPanel.cs +++ /dev/null @@ -1,211 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Windows; -using System.Windows.Controls; - -namespace Xceed.Wpf.DataGrid.Views -{ - // Panel used as children of the FixedCellPanel that only layout horizontally. - internal class FixedCellSubPanel : Panel - { - public FixedCellSubPanel( FixedCellPanel parentPanel ) - { - if( parentPanel == null ) - throw new ArgumentNullException( "parentPanel" ); - - m_parentPanel = parentPanel; - } - - #region DataGridContext Internal Property - - internal DataGridContext DataGridContext - { - get - { - return m_parentPanel.DataGridContext; - } - } - - #endregion - - #region ParentFixedCellPanel Internal Property - - internal FixedCellPanel ParentPanel - { - get - { - return m_parentPanel; - } - } - - private readonly FixedCellPanel m_parentPanel; - - #endregion - - #region ColumnVirtualizationManager Internal Property - - internal TableViewColumnVirtualizationManagerBase ColumnVirtualizationManager - { - get - { - var dataGridContext = this.DataGridContext; - if( dataGridContext == null ) - return null; - - return ( TableViewColumnVirtualizationManagerBase )dataGridContext.ColumnVirtualizationManager; - } - } - - #endregion - - protected override UIElementCollection CreateUIElementCollection( FrameworkElement logicalParent ) - { - // We make sure that the element added to this panel won't have this panel as logical parent. - // We want the logical parent of these element to be the FixedCellPanel itself. This is handled in the UICellCollection class. - return new UIElementCollection( this, null ); - } - - // Measure horizontally. - protected override Size MeasureOverride( Size constraint ) - { - // This can be null when the parent Row is not prepared yet. - var columnVirtualizationManager = this.ColumnVirtualizationManager; - if( columnVirtualizationManager == null ) - return new Size(); - - var parentRow = this.ParentPanel.ParentRow; - if( parentRow == null ) - return new Size(); - - var desiredSize = new Size(); - var fieldNameToWidth = columnVirtualizationManager.GetFieldNameToWidth( parentRow.LevelCache ); - - //This using prevents a WeakEvent to be raised to execute UpdateChildren() in FixedCellPanel, as it is already up to date at this point. - using( this.ParentPanel.ParentRowCells.SetIsUpdating() ) - { - foreach( var cell in this.GetVisibleCells() ) - { - Debug.Assert( !Row.GetIsTemplateCell( cell ), "No template Cells should be added to FixedCellPanel" ); - - cell.Measure( new Size( fieldNameToWidth[ cell.FieldName ], constraint.Height ) ); - - if( cell.DesiredSize.Height > desiredSize.Height ) - { - desiredSize.Height = cell.DesiredSize.Height; - } - } - } - - desiredSize.Width = columnVirtualizationManager.FixedColumnsWidth; - - return desiredSize; - } - - // Arrange horizontally. - protected override Size ArrangeOverride( Size arrangeSize ) - { - // This can be null when the parent Row is not prepared yet. - var columnVirtualizationManager = this.ColumnVirtualizationManager; - if( columnVirtualizationManager == null ) - return new Size(); - - var parentRow = this.ParentPanel.ParentRow; - if( parentRow == null ) - return new Size(); - - var columnToVisibleOffset = columnVirtualizationManager.GetFieldNameToOffset( parentRow.LevelCache ); - var finalRect = new Rect( arrangeSize ); - - //This using prevents a WeakEvent to be raised to execute UpdateChildren() in FixedCellPanel, as it is already up to date at this point. - using( this.ParentPanel.ParentRowCells.SetIsUpdating() ) - { - foreach( var cell in this.GetVisibleCells() ) - { - Debug.Assert( !Row.GetIsTemplateCell( cell ), "No template Cells should be added to FixedCellPanel" ); - - var offset = this.CalculateCellOffset( cell.ParentColumn, columnToVisibleOffset ); - - finalRect.X = offset.X; - finalRect.Width = cell.DesiredSize.Width; - finalRect.Height = Math.Max( arrangeSize.Height, cell.DesiredSize.Height ); - - cell.Arrange( finalRect ); - } - } - - return arrangeSize; - } - - protected virtual IEnumerable GetVisibleFieldsName() - { - var columnVirtualizationManager = this.ColumnVirtualizationManager; - if( columnVirtualizationManager == null ) - return new string[ 0 ]; - - return columnVirtualizationManager.GetFixedFieldNames( m_parentPanel.ParentRow.LevelCache ); - } - - protected IEnumerable GetVisibleCells() - { - var parentRowCells = this.ParentPanel.ParentRowCells; - - if( parentRowCells == null ) - yield break; - - foreach( string fieldName in this.GetVisibleFieldsName() ) - { - yield return parentRowCells.GetCell( fieldName, false ); - } - } - - internal virtual Point CalculateCellOffset( ColumnBase column ) - { - Debug.Assert( column != null ); - var row = this.ParentPanel.ParentRow; - - if( ( column != null ) && ( row != null ) ) - { - var columnVirtualizationManager = this.ColumnVirtualizationManager; - if( columnVirtualizationManager != null ) - { - var columnToVisibleOffset = columnVirtualizationManager.GetFieldNameToOffset( row.LevelCache ); - - return this.CalculateCellOffset( column, columnToVisibleOffset ); - } - } - - return new Point(); - } - - private Point CalculateCellOffset( ColumnBase column, IColumnInfoCollection columnsOffset ) - { - if( column == null ) - return new Point(); - - Debug.Assert( columnsOffset != null ); - Debug.Assert( columnsOffset.Contains( column ) ); - - var columnOffset = columnsOffset[ column ]; - - return new Point( columnOffset, 0d ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/IVirtualizingCellsHost.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/IVirtualizingCellsHost.cs deleted file mode 100644 index bd54791e..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/IVirtualizingCellsHost.cs +++ /dev/null @@ -1,42 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System.Windows; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal interface IVirtualizingCellsHost - { - // Determines if it is possible for this CellsHost to internaly set/clear the LogicalParent - // to avoid the UIElementCollection to do it in background for each Collection modification - bool CanModifyLogicalParent - { - get; - } - - void ClearLogicalParent( Cell cell ); - - void SetLogicalParent( Cell cell ); - - void PrepareCellsHost( DataGridContext dataGridContext ); - - void ClearCellsHost(); - - void InvalidateCellsHostMeasure(); - - bool BringIntoView( Cell cell, RequestBringIntoViewEventArgs e ); - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/MasterDetailLayoutAttribute.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/MasterDetailLayoutAttribute.cs deleted file mode 100644 index 9e3d4f2e..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/MasterDetailLayoutAttribute.cs +++ /dev/null @@ -1,42 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid.Views -{ - [AttributeUsage( AttributeTargets.Class, AllowMultiple = false )] // Applies only to the class of a view - internal sealed class MasterDetailLayoutAttribute : Attribute - { - public MasterDetailLayoutAttribute( MasterDetailLayoutMode masterDetailLayoutMode ) - { - if( !Enum.IsDefined( typeof( MasterDetailLayoutMode ), masterDetailLayoutMode ) ) - throw new ArgumentException( "The value is not a valid enum value.", "masterDetailLayoutMode" ); - - m_masterDetailLayoutMode = masterDetailLayoutMode; - } - - public MasterDetailLayoutMode MasterDetailLayoutMode - { - get - { - return m_masterDetailLayoutMode; - } - } - - private MasterDetailLayoutMode m_masterDetailLayoutMode = MasterDetailLayoutMode.Default; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/NavigationHelper.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/NavigationHelper.cs deleted file mode 100644 index a73e47fb..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/NavigationHelper.cs +++ /dev/null @@ -1,616 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Windows; -using System.Windows.Input; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal static class NavigationHelper - { - internal static int GetFirstVisibleFocusableColumnIndex( DataGridContext dataGridContext ) - { - if( dataGridContext == null ) - return -1; - - return NavigationHelper.GetFirstVisibleFocusableColumnIndex( dataGridContext, dataGridContext.CurrentRow ); - } - - internal static int GetFirstVisibleFocusableColumnIndex( DataGridContext dataGridContext, Row targetRow ) - { - if( dataGridContext == null ) - return -1; - - if( dataGridContext.IsAFlattenDetail ) - return NavigationHelper.GetNextVisibleFocusableDetailColumnIndexFromMasterColumnIndex( dataGridContext, targetRow, int.MinValue ); - - return NavigationHelper.GetNextVisibleFocusableColumnIndex( dataGridContext, targetRow, int.MinValue ); - } - - internal static int GetLastVisibleFocusableColumnIndex( DataGridContext dataGridContext ) - { - if( dataGridContext == null ) - return -1; - - return NavigationHelper.GetLastVisibleFocusableColumnIndex( dataGridContext, dataGridContext.CurrentRow ); - } - - internal static int GetLastVisibleFocusableColumnIndex( DataGridContext dataGridContext, Row targetRow ) - { - if( dataGridContext == null ) - return -1; - - if( dataGridContext.IsAFlattenDetail ) - return NavigationHelper.GetPreviousVisibleFocusableDetailColumnIndexFromMasterColumnIndex( dataGridContext, targetRow, int.MaxValue ); - - return NavigationHelper.GetPreviousVisibleFocusableColumnIndex( dataGridContext, targetRow, int.MaxValue ); - } - - internal static int GetNextVisibleFocusableColumnIndex( DataGridContext dataGridContext, Row targetRow, ColumnBase targetColumn ) - { - if( ( dataGridContext == null ) || ( targetRow == null ) || ( targetColumn == null ) ) - return -1; - - var columns = dataGridContext.VisibleColumns; - if( ( columns == null ) || ( columns.Count <= 0 ) ) - return -1; - - var columnIndex = columns.IndexOf( targetColumn ); - if( columnIndex < 0 ) - return -1; - - if( !dataGridContext.IsAFlattenDetail ) - return NavigationHelper.GetNextVisibleFocusableColumnIndex( dataGridContext, targetRow, columnIndex + 1 ); - - var masterColumn = default( ColumnBase ); - if( !DataGridItemPropertyMapHelper.TryGetMasterColumn( dataGridContext, targetColumn, out masterColumn ) ) - return -1; - - var masterDataGridContext = dataGridContext.RootDataGridContext; - var masterColumnIndex = masterDataGridContext.VisibleColumns.IndexOf( masterColumn ); - if( masterColumnIndex < 0 ) - return -1; - - return NavigationHelper.GetNextVisibleFocusableDetailColumnIndexFromMasterColumnIndex( dataGridContext, targetRow, masterColumnIndex + 1 ); - } - - internal static int GetPreviousVisibleFocusableColumnIndex( DataGridContext dataGridContext, Row targetRow, ColumnBase targetColumn ) - { - if( ( dataGridContext == null ) || ( targetRow == null ) || ( targetColumn == null ) ) - return -1; - - var columns = dataGridContext.VisibleColumns; - if( ( columns == null ) || ( columns.Count <= 0 ) ) - return -1; - - var columnIndex = columns.IndexOf( targetColumn ); - if( columnIndex < 0 ) - return -1; - - if( !dataGridContext.IsAFlattenDetail ) - return NavigationHelper.GetPreviousVisibleFocusableColumnIndex( dataGridContext, targetRow, columnIndex - 1 ); - - var masterColumn = default( ColumnBase ); - if( !DataGridItemPropertyMapHelper.TryGetMasterColumn( dataGridContext, targetColumn, out masterColumn ) ) - return -1; - - var masterDataGridContext = dataGridContext.RootDataGridContext; - var masterColumnIndex = masterDataGridContext.VisibleColumns.IndexOf( masterColumn ); - if( masterColumnIndex < 0 ) - return -1; - - return NavigationHelper.GetPreviousVisibleFocusableDetailColumnIndexFromMasterColumnIndex( dataGridContext, targetRow, masterColumnIndex - 1 ); - } - - internal static int GetFirstVisibleFocusableInViewportColumnIndex( DataGridContext dataGridContext, Row targetRow ) - { - if( dataGridContext == null ) - return -1; - - if( dataGridContext.IsAFlattenDetail ) - return NavigationHelper.GetNextVisibleFocusableInViewportDetailColumnIndexFromMasterColumnIndex( dataGridContext, targetRow ); - - return NavigationHelper.GetNextVisibleFocusableInViewportColumnIndex( dataGridContext, targetRow ); - } - - internal static bool MoveFocusLeft( DataGridContext dataGridContext ) - { - var dataGridControl = NavigationHelper.GetDataGridControl( dataGridContext ); - if( dataGridControl == null ) - return false; - - var leftToRight = ( dataGridControl.FlowDirection == FlowDirection.LeftToRight ); - - return NavigationHelper.MoveFocus( dataGridControl, dataGridContext, leftToRight, false ); - } - - internal static bool MoveFocusRight( DataGridContext dataGridContext ) - { - var dataGridControl = NavigationHelper.GetDataGridControl( dataGridContext ); - if( dataGridControl == null ) - return false; - - var leftToRight = ( dataGridControl.FlowDirection == FlowDirection.LeftToRight ); - - return NavigationHelper.MoveFocus( dataGridControl, dataGridContext, !leftToRight, false ); - } - - internal static bool MoveFocusToNextVisibleColumn( DataGridContext dataGridContext, bool cycle ) - { - var dataGridControl = NavigationHelper.GetDataGridControl( dataGridContext ); - if( dataGridControl == null ) - return false; - - Debug.Assert( dataGridControl.CurrentContext == dataGridContext ); - - return NavigationHelper.MoveFocusToNextVisibleColumn( dataGridContext, dataGridContext.CurrentRow, dataGridContext.CurrentColumn, cycle ); - } - - internal static bool MoveFocusToPreviousVisibleColumn( DataGridContext dataGridContext, bool cycle ) - { - var dataGridControl = NavigationHelper.GetDataGridControl( dataGridContext ); - if( dataGridControl == null ) - return false; - - Debug.Assert( dataGridControl.CurrentContext == dataGridContext ); - - return NavigationHelper.MoveFocusToPreviousVisibleColumn( dataGridContext, dataGridContext.CurrentRow, dataGridContext.CurrentColumn, cycle ); - } - - internal static bool MoveFocusToFirstVisibleColumn( DataGridContext dataGridContext ) - { - var dataGridControl = NavigationHelper.GetDataGridControl( dataGridContext ); - if( dataGridControl == null ) - return false; - - Debug.Assert( dataGridControl.CurrentContext == dataGridContext ); - - return NavigationHelper.MoveFocusToFirstVisibleColumn( dataGridContext, dataGridContext.CurrentRow ); - } - - internal static bool MoveFocusToLastVisibleColumn( DataGridContext dataGridContext ) - { - var dataGridControl = NavigationHelper.GetDataGridControl( dataGridContext ); - if( dataGridControl == null ) - return false; - - Debug.Assert( dataGridControl.CurrentContext == dataGridContext ); - - return NavigationHelper.MoveFocusToLastVisibleColumn( dataGridContext, dataGridContext.CurrentRow ); - } - - internal static bool HandleTabKey( - DataGridControl dataGridControl, - DataGridContext dataGridContext, - FrameworkElement source, - KeyboardDevice device ) - { - if( ( dataGridControl == null ) || !dataGridControl.IsKeyboardFocusWithin ) - return false; - - Debug.Assert( dataGridControl.CurrentContext == dataGridContext ); - - if( !dataGridControl.IsBeingEdited ) - { - Debug.Assert( dataGridContext != null ); - return false; - } - - if( NavigationHelper.ValidateTabKeyHandleIsWithin( dataGridControl, source, device ) ) - return false; - - var columns = dataGridContext.VisibleColumns; - if( columns.Count <= 0 ) - return false; - - bool handled; - - if( dataGridContext.CurrentColumn == null ) - { - handled = NavigationHelper.MoveFocusToFirstVisibleColumn( dataGridContext ); - } - else - { - if( ( device.Modifiers & ModifierKeys.Shift ) == ModifierKeys.Shift ) - { - handled = NavigationHelper.MoveFocusToPreviousVisibleColumn( dataGridContext, true ); - } - else - { - handled = NavigationHelper.MoveFocusToNextVisibleColumn( dataGridContext, true ); - } - } - - if( !handled ) - throw new DataGridException( "Trying to edit while no cell is focusable.", dataGridControl ); - - return true; - } - - private static int GetNextVisibleFocusableColumnIndex( DataGridContext dataGridContext, Row targetRow, int startIndex ) - { - if( ( dataGridContext == null ) || ( targetRow == null ) ) - return -1; - - var columns = dataGridContext.VisibleColumns; - if( ( columns == null ) || ( columns.Count <= 0 ) ) - return -1; - - var cells = targetRow.Cells; - - for( int i = Math.Max( 0, startIndex ); i < columns.Count; i++ ) - { - var targetColumn = columns[ i ]; - - if( cells[ targetColumn ].GetCalculatedCanBeCurrent() ) - return i; - } - - return -1; - } - - private static int GetPreviousVisibleFocusableColumnIndex( DataGridContext dataGridContext, Row targetRow, int startIndex ) - { - if( ( dataGridContext == null ) || ( targetRow == null ) ) - return -1; - - var columns = dataGridContext.VisibleColumns; - if( ( columns == null ) || ( columns.Count <= 0 ) ) - return -1; - - var cells = targetRow.Cells; - - for( int i = Math.Min( columns.Count - 1, startIndex ); i >= 0; i-- ) - { - var targetColumn = columns[ i ]; - - if( cells[ targetColumn ].GetCalculatedCanBeCurrent() ) - return i; - } - - return -1; - } - - private static int GetNextVisibleFocusableDetailColumnIndexFromMasterColumnIndex( DataGridContext dataGridContext, Row targetRow, int startIndex ) - { - if( ( dataGridContext == null ) || ( targetRow == null ) ) - return -1; - - Debug.Assert( dataGridContext.IsAFlattenDetail ); - - var detailVisibleColumns = dataGridContext.VisibleColumns; - if( ( detailVisibleColumns == null ) || ( detailVisibleColumns.Count <= 0 ) ) - return -1; - - var masterDataGridContext = dataGridContext.RootDataGridContext; - var masterVisibleColumns = masterDataGridContext.VisibleColumns; - var cells = targetRow.Cells; - - for( int i = Math.Max( 0, startIndex ); i < masterVisibleColumns.Count; i++ ) - { - var masterColumn = masterVisibleColumns[ i ]; - Debug.Assert( masterColumn != null ); - - var detailColumn = default( ColumnBase ); - if( !DataGridItemPropertyMapHelper.TryGetDetailColumn( dataGridContext, masterColumn, out detailColumn ) ) - continue; - - var detailColumnIndex = detailVisibleColumns.IndexOf( detailColumn ); - if( ( detailColumnIndex >= 0 ) && ( cells[ detailColumn ].GetCalculatedCanBeCurrent() ) ) - return detailColumnIndex; - } - - return -1; - } - - private static int GetPreviousVisibleFocusableDetailColumnIndexFromMasterColumnIndex( DataGridContext dataGridContext, Row targetRow, int startIndex ) - { - if( ( dataGridContext == null ) || ( targetRow == null ) ) - return -1; - - Debug.Assert( dataGridContext.IsAFlattenDetail ); - - var detailVisibleColumns = dataGridContext.VisibleColumns; - if( ( detailVisibleColumns == null ) || ( detailVisibleColumns.Count <= 0 ) ) - return -1; - - var masterDataGridContext = dataGridContext.RootDataGridContext; - var masterVisibleColumns = masterDataGridContext.VisibleColumns; - var cells = targetRow.Cells; - - for( int i = Math.Min( masterVisibleColumns.Count - 1, startIndex ); i >= 0; i-- ) - { - var masterColumn = masterVisibleColumns[ i ]; - Debug.Assert( masterColumn != null ); - - var detailColumn = default( ColumnBase ); - if( !DataGridItemPropertyMapHelper.TryGetDetailColumn( dataGridContext, masterColumn, out detailColumn ) ) - continue; - - var detailColumnIndex = detailVisibleColumns.IndexOf( detailColumn ); - if( ( detailColumnIndex >= 0 ) && ( cells[ detailColumn ].GetCalculatedCanBeCurrent() ) ) - return detailColumnIndex; - } - - return -1; - } - - private static int GetNextVisibleFocusableInViewportColumnIndex( DataGridContext dataGridContext, Row targetRow ) - { - if( ( dataGridContext == null ) || ( targetRow == null ) ) - return -1; - - var columns = dataGridContext.VisibleColumns; - if( ( columns == null ) || ( columns.Count <= 0 ) ) - return -1; - - var fixedCellPanel = targetRow.CellsHostPanel as FixedCellPanel; - if( fixedCellPanel == null ) - return -1; - - var cell = default( Cell ); - var virtualizingCellCollection = fixedCellPanel.ParentRowCells; - - foreach( var targetColumn in columns ) - { - if( !virtualizingCellCollection.TryGetBindedCell( targetColumn, out cell ) ) - continue; - - if( cell.GetCalculatedCanBeCurrent() ) - return columns.IndexOf( targetColumn ); - } - - return -1; - } - - private static int GetNextVisibleFocusableInViewportDetailColumnIndexFromMasterColumnIndex( DataGridContext dataGridContext, Row targetRow ) - { - if( ( dataGridContext == null ) || ( targetRow == null ) ) - return -1; - - Debug.Assert( dataGridContext.IsAFlattenDetail ); - - var detailVisibleColumns = dataGridContext.VisibleColumns; - if( ( detailVisibleColumns == null ) || ( detailVisibleColumns.Count <= 0 ) ) - return -1; - - var masterDataGridContext = dataGridContext.RootDataGridContext; - var masterVisibleColumns = masterDataGridContext.VisibleColumns; - - var fixedCellPanel = targetRow.CellsHostPanel as FixedCellPanel; - if( fixedCellPanel == null ) - return -1; - - var cell = default( Cell ); - var virtualizingCellCollection = fixedCellPanel.ParentRowCells; - - foreach( var masterColumn in masterVisibleColumns ) - { - Debug.Assert( masterColumn != null ); - - var detailColumn = default( ColumnBase ); - if( !DataGridItemPropertyMapHelper.TryGetDetailColumn( dataGridContext, masterColumn, out detailColumn ) ) - continue; - - if( !virtualizingCellCollection.TryGetBindedCell( detailColumn, out cell ) ) - continue; - - if( cell.GetCalculatedCanBeCurrent() ) - return detailVisibleColumns.IndexOf( detailColumn ); - } - - return -1; - } - - private static bool ValidateTabKeyHandleIsWithin( - DataGridControl dataGridControl, - FrameworkElement source, - KeyboardDevice device ) - { - if( ( dataGridControl == null ) || ( source == null ) ) - return false; - - var nextControl = NavigationHelper.PredictNextElement( source, device ); - if( nextControl == null ) - return false; - - //If the original source is not a control (e.g. the cells panel instead of a cell), columns will be used to move focus. - var cell = Cell.FindFromChild( nextControl ); - if( ( cell == null ) || ( cell.ParentColumn != dataGridControl.CurrentColumn ) ) - return false; - - return object.Equals( cell.ParentRow.GetEditingDataContext(), dataGridControl.CurrentItemInEdition ); - } - - private static bool MoveFocus( DataGridControl dataGridControl, DataGridContext dataGridContext, bool moveLeft, bool cycle ) - { - Debug.Assert( dataGridControl != null ); - Debug.Assert( dataGridControl.CurrentContext == dataGridContext ); - - bool isFocusWithin = dataGridControl.IsKeyboardFocusWithin; - bool isBeingEdited = ( isFocusWithin && dataGridControl.IsBeingEdited ); - - var navigationBehavior = dataGridControl.NavigationBehavior; - - // Process key even if NavigationBehavior is RowOnly when the grid is being edited. - if( ( navigationBehavior == NavigationBehavior.CellOnly ) - || ( ( navigationBehavior == NavigationBehavior.RowOnly ) && isBeingEdited ) - || ( ( navigationBehavior == NavigationBehavior.RowOrCell ) && isFocusWithin && ( dataGridContext.CurrentColumn != null ) ) ) - { - if( moveLeft ) - return NavigationHelper.MoveFocusToPreviousVisibleColumn( dataGridContext, dataGridContext.CurrentRow, dataGridContext.CurrentColumn, cycle ); - - return NavigationHelper.MoveFocusToNextVisibleColumn( dataGridContext, dataGridContext.CurrentRow, dataGridContext.CurrentColumn, cycle ); - } - - return false; - } - - private static bool MoveFocusToNextVisibleColumn( DataGridContext dataGridContext, Row targetRow, ColumnBase targetColumn, bool cycle ) - { - if( ( dataGridContext == null ) || ( targetRow == null ) ) - return false; - - var columnIndex = NavigationHelper.GetNextVisibleFocusableColumnIndex( dataGridContext, targetRow, targetColumn ); - if( columnIndex < 0 ) - { - if( cycle ) - return NavigationHelper.MoveFocusToFirstVisibleColumn( dataGridContext, targetRow ); - - return false; - } - else - { - var columns = dataGridContext.VisibleColumns; - Debug.Assert( columns != null ); - - NavigationHelper.SetCurrentColumnAndChangeSelection( dataGridContext, columns[ columnIndex ] ); - - return true; - } - } - - private static bool MoveFocusToPreviousVisibleColumn( DataGridContext dataGridContext, Row targetRow, ColumnBase targetColumn, bool cycle ) - { - if( ( dataGridContext == null ) || ( targetRow == null ) ) - return false; - - var columnIndex = NavigationHelper.GetPreviousVisibleFocusableColumnIndex( dataGridContext, targetRow, targetColumn ); - if( columnIndex < 0 ) - { - if( cycle ) - return NavigationHelper.MoveFocusToLastVisibleColumn( dataGridContext, targetRow ); - - return false; - } - else - { - var columns = dataGridContext.VisibleColumns; - Debug.Assert( columns != null ); - - NavigationHelper.SetCurrentColumnAndChangeSelection( dataGridContext, columns[ columnIndex ] ); - - return true; - } - } - - private static bool MoveFocusToFirstVisibleColumn( DataGridContext dataGridContext, Row targetRow ) - { - if( ( dataGridContext == null ) || ( targetRow == null ) ) - return false; - - var columnIndex = NavigationHelper.GetFirstVisibleFocusableColumnIndex( dataGridContext, targetRow ); - if( columnIndex < 0 ) - return false; - - var columns = dataGridContext.VisibleColumns; - Debug.Assert( columns != null ); - - NavigationHelper.SetCurrentColumnAndChangeSelection( dataGridContext, columns[ columnIndex ] ); - - return true; - } - - private static bool MoveFocusToLastVisibleColumn( DataGridContext dataGridContext, Row targetRow ) - { - if( ( dataGridContext == null ) || ( targetRow == null ) ) - return false; - - var columnIndex = NavigationHelper.GetLastVisibleFocusableColumnIndex( dataGridContext, targetRow ); - if( columnIndex < 0 ) - return false; - - var columns = dataGridContext.VisibleColumns; - Debug.Assert( columns != null ); - - NavigationHelper.SetCurrentColumnAndChangeSelection( dataGridContext, columns[ columnIndex ] ); - - return true; - } - - private static DataGridControl GetDataGridControl( DataGridContext dataGridContext ) - { - if( dataGridContext != null ) - return dataGridContext.DataGridControl; - - return null; - } - - private static DependencyObject PredictNextElement( FrameworkElement source, KeyboardDevice device ) - { - foreach( var direction in NavigationHelper.GetFocusNavigationDirections( source, device ) ) - { - var target = source.PredictFocus( direction ); - if( target != null ) - return target; - } - - return null; - } - - private static IEnumerable GetFocusNavigationDirections( FrameworkElement source, KeyboardDevice device ) - { - if( source == null ) - yield break; - - //In the case of a ListBox set with Cycle or Contained navigation mode, we must move in the other direction if on the first or last item, - //since PredictFocus will throw is we use FocusNavigationDirection.First/Last. - if( ( device.Modifiers & ModifierKeys.Shift ) == ModifierKeys.Shift ) - { - yield return FocusNavigationDirection.Left; - yield return FocusNavigationDirection.Up; - - var navigationMode = ( KeyboardNavigationMode )source.GetValue( KeyboardNavigation.TabNavigationProperty ); - if( navigationMode == KeyboardNavigationMode.Cycle || navigationMode == KeyboardNavigationMode.Contained ) - { - yield return FocusNavigationDirection.Right; - yield return FocusNavigationDirection.Down; - } - } - else - { - yield return FocusNavigationDirection.Right; - yield return FocusNavigationDirection.Down; - - var navigationMode = ( KeyboardNavigationMode )source.GetValue( KeyboardNavigation.TabNavigationProperty ); - if( navigationMode == KeyboardNavigationMode.Cycle || navigationMode == KeyboardNavigationMode.Contained ) - { - yield return FocusNavigationDirection.Left; - yield return FocusNavigationDirection.Up; - } - } - } - - private static void SetCurrentColumnAndChangeSelection( DataGridContext dataGridContext, ColumnBase column ) - { - Debug.Assert( dataGridContext != null ); - Debug.Assert( column != null ); - - try - { - dataGridContext.SetCurrentColumnAndChangeSelection( column ); - } - catch( DataGridException ) - { - // We swallow the exception if it occurs because of a validation error or Cell was read-only or - // any other GridException. - } - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/PassiveLayoutDecorator.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/PassiveLayoutDecorator.cs deleted file mode 100644 index f502755d..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/PassiveLayoutDecorator.cs +++ /dev/null @@ -1,80 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows.Controls; -using System.Windows; - -namespace Xceed.Wpf.DataGrid.Views -{ - public class PassiveLayoutDecorator : Decorator - { - #region Axis Property - - public static readonly DependencyProperty AxisProperty = - DependencyProperty.Register( "Axis", typeof( PassiveLayoutAxis ), typeof( PassiveLayoutDecorator ), new UIPropertyMetadata( PassiveLayoutAxis.Vertical ) ); - - public PassiveLayoutAxis Axis - { - get - { - return ( PassiveLayoutAxis )this.GetValue( PassiveLayoutDecorator.AxisProperty ); - } - set - { - this.SetValue( PassiveLayoutDecorator.AxisProperty, value ); - } - } - - #endregion Axis Property - - #region RealDesiredSize Internal Property - - internal Size RealDesiredSize - { - get - { - return m_realDesiredSize; - } - } - - private Size m_realDesiredSize; - - #endregion RealDesiredSize Property - - protected override Size MeasureOverride( Size availableSize ) - { - Size size = base.MeasureOverride( availableSize ); - m_realDesiredSize = size; - - switch( this.Axis ) - { - case PassiveLayoutAxis.Vertical: - return new Size( size.Width, 0d ); - - case PassiveLayoutAxis.Horizontal: - return new Size( 0d, size.Height ); - - case PassiveLayoutAxis.Both: - return new Size( 0d, 0d ); - - default: - System.Diagnostics.Debug.Assert( false, "Unknown PassiveLayoutAxis." ); - return size; - } - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/ScrollViewerTemplateHelper.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/ScrollViewerTemplateHelper.cs deleted file mode 100644 index 8db9777e..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/ScrollViewerTemplateHelper.cs +++ /dev/null @@ -1,186 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Diagnostics; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Controls.Primitives; -using System.Windows.Input; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal class ScrollViewerTemplateHelper : IDisposable - { - - public ScrollViewerTemplateHelper( - ScrollViewer scrollViewer, - Action dragScrollBeginCallback, - Action dragScrollEndCallback ) - { - if( scrollViewer == null ) - throw new ArgumentNullException( "scrollViewer" ); - - m_scrollViewer = scrollViewer; - m_dragScrollBeginCallback = dragScrollBeginCallback; - m_dragScrollEndCallback = dragScrollEndCallback; - } - - #region VerticalScrollBar Property - - public ScrollBar VerticalScrollBar - { - get; - private set; - } - - #endregion - - #region HorizontalScrollBar Property - - public ScrollBar HorizontalScrollBar - { - get; - private set; - } - - #endregion - - public ScrollBar GetScrollBar( Orientation orientation ) - { - return ( orientation == Orientation.Vertical ) - ? this.VerticalScrollBar - : this.HorizontalScrollBar; - } - - public void RefreshTemplate() - { - this.UnregisterEvents(); - - var template = m_scrollViewer.Template; - if( template != null ) - { - this.HorizontalScrollBar = template.FindName( "PART_HorizontalScrollBar", m_scrollViewer ) as ScrollBar; - this.VerticalScrollBar = template.FindName( "PART_VerticalScrollBar", m_scrollViewer ) as ScrollBar; - } - - if( m_dragScrollBeginCallback != null || m_dragScrollEndCallback != null ) - { - this.RegisterEvents(); - } - } - - public void Dispose() - { - this.UnregisterEvents(); - - m_dragScrollBeginCallback = null; - m_dragScrollEndCallback = null; - } - - private void RegisterEvents() - { - if( this.VerticalScrollBar != null ) - { - this.VerticalScrollBar.IsMouseCaptureWithinChanged += ScrollBar_IsMouseCaptureWithinChanged; - } - - if( this.HorizontalScrollBar != null ) - { - this.HorizontalScrollBar.IsMouseCaptureWithinChanged += ScrollBar_IsMouseCaptureWithinChanged; - } - } - - private void UnregisterEvents() - { - if( this.VerticalScrollBar != null ) - { - this.VerticalScrollBar.IsMouseCaptureWithinChanged -= ScrollBar_IsMouseCaptureWithinChanged; - } - - if( this.HorizontalScrollBar != null ) - { - this.HorizontalScrollBar.IsMouseCaptureWithinChanged -= ScrollBar_IsMouseCaptureWithinChanged; - } - } - - private void ScrollBar_IsMouseCaptureWithinChanged( object sender, DependencyPropertyChangedEventArgs e ) - { - var scrollBar = sender as ScrollBar; - - if( scrollBar == null ) - return; - - if( scrollBar != this.HorizontalScrollBar - && scrollBar != this.VerticalScrollBar ) - { - Debug.Fail( "Unknown scrollbar" ); - return; - } - - var scrollThumb = Mouse.Captured as Thumb; - - if( scrollThumb == null ) - return; - - if( scrollBar.Track == null ) - return; - - if( scrollBar.Track.Thumb != scrollThumb ) - return; - - m_currentScrollOrientation = ( scrollBar == this.VerticalScrollBar ) ? Orientation.Vertical : Orientation.Horizontal; - - if( m_dragScrollEndCallback != null ) - { - // Register to LostMouseCapture to be sure to hide the ScrollTip when the ScrollThumb lost the focus - scrollThumb.LostMouseCapture += new MouseEventHandler( this.ScrollThumb_LostMouseCapture ); - } - - if( m_dragScrollBeginCallback != null ) - { - - m_dragScrollBeginCallback( m_currentScrollOrientation ); - } - - } - - - private void ScrollThumb_LostMouseCapture( object sender, MouseEventArgs e ) - { - Thumb scrollBarThumb = sender as Thumb; - - Debug.Assert( scrollBarThumb != null ); - - if( scrollBarThumb != null ) - scrollBarThumb.LostMouseCapture -= new MouseEventHandler( this.ScrollThumb_LostMouseCapture ); - - if( m_dragScrollEndCallback != null ) - { - m_dragScrollEndCallback( m_currentScrollOrientation ); - } - } - - #region Fields - - private ScrollViewer m_scrollViewer; - private Action m_dragScrollBeginCallback; - private Action m_dragScrollEndCallback; - private Orientation m_currentScrollOrientation; - #endregion - - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/ScrollingCellsDecorator.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/ScrollingCellsDecorator.cs deleted file mode 100644 index d4e616cc..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/ScrollingCellsDecorator.cs +++ /dev/null @@ -1,208 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Input; -using System.Windows.Media; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal class ScrollingCellsDecorator : Decorator - { - #region Constructors - - static ScrollingCellsDecorator() - { - KeyboardNavigation.DirectionalNavigationProperty.OverrideMetadata( - typeof( ScrollingCellsDecorator ), - new FrameworkPropertyMetadata( KeyboardNavigationMode.Local ) ); - - // Binding used to affect the AnimatedSplitterTranslationBinding only - // when performing an animated Column reordering - AreColumnsBeingReorderedBinding = new Binding(); - AreColumnsBeingReorderedBinding.RelativeSource = new RelativeSource( RelativeSourceMode.Self ); - AreColumnsBeingReorderedBinding.Path = new PropertyPath( "(0).(1)", - DataGridControl.DataGridContextProperty, - TableflowView.AreColumnsBeingReorderedProperty ); - - AreColumnsBeingReorderedBinding.Mode = BindingMode.OneWay; - } - - public ScrollingCellsDecorator() - { - this.Focusable = false; - - BindingOperations.SetBinding( - this, - ScrollingCellsDecorator.AreColumnsBeingReorderedProperty, - ScrollingCellsDecorator.AreColumnsBeingReorderedBinding ); - } - - #endregion - - #region SplitterOffset Public Property - - public static readonly DependencyProperty SplitterOffsetProperty = DependencyProperty.Register( - "SplitterOffset", - typeof( double ), - typeof( ScrollingCellsDecorator ), - new FrameworkPropertyMetadata( 0d, FrameworkPropertyMetadataOptions.AffectsArrange ) ); - - public double SplitterOffset - { - get - { - return ( double )this.GetValue( ScrollingCellsDecorator.SplitterOffsetProperty ); - } - set - { - this.SetValue( ScrollingCellsDecorator.SplitterOffsetProperty, value ); - } - } - - #endregion - - #region ParentScrollViewer Private Property - - private ScrollViewer ParentScrollViewer - { - get - { - if( m_scrollViewer == null ) - { - m_scrollViewer = TableViewScrollViewer.GetParentScrollViewer( this ); - } - - return m_scrollViewer; - } - } - - #endregion - - #region AreColumnsBeingReordered Property - - internal static readonly DependencyProperty AreColumnsBeingReorderedProperty = DependencyProperty.Register( - "AreColumnsBeingReordered", - typeof( bool ), - typeof( ScrollingCellsDecorator ), - new FrameworkPropertyMetadata( - ( bool )false, - new PropertyChangedCallback( ScrollingCellsDecorator.OnAreColumnsBeingReorderedChanged ) ) ); - - internal bool AreColumnsBeingReordered - { - get - { - return ( bool )this.GetValue( ScrollingCellsDecorator.AreColumnsBeingReorderedProperty ); - } - set - { - this.SetValue( ScrollingCellsDecorator.AreColumnsBeingReorderedProperty, value ); - } - } - - private static void OnAreColumnsBeingReorderedChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - ScrollingCellsDecorator decorator = sender as ScrollingCellsDecorator; - - if( decorator == null ) - return; - - - if( ( bool )e.NewValue ) - { - decorator.SetSplitterOffsetBinding(); - } - else - { - decorator.ClearSplitterOffsetBinding(); - } - } - - #endregion - - #region Protected Methods - - protected override Size ArrangeOverride( Size arrangeSize ) - { - // We need to take ScrollingCellsDecoratorClipOffset into consideration - // in case an animated column reordering is in progress - double clipOffset = this.SplitterOffset; - - //Width of Rect cannot be less then 0. - double widthOffset = Math.Max( 0, arrangeSize.Width - clipOffset ); - - // Try to get the RectangleGeometry from the Clip - // to avoid recreating one per call - RectangleGeometry clip = this.Clip as RectangleGeometry; - - if( clip == null ) - { - clip = new RectangleGeometry(); - this.Clip = clip; - } - - clip.Rect = new Rect( clipOffset, -0.5d, widthOffset, arrangeSize.Height + 1d ); - - return base.ArrangeOverride( arrangeSize ); - } - - #endregion - - #region Private Methods - - private void SetSplitterOffsetBinding() - { - if( m_splitterOffsetBinding == null ) - { - // Binding used to know if there was a splitter translation to enlarge - // or reduce the Clip region of the Decorator - m_splitterOffsetBinding = new Binding(); - m_splitterOffsetBinding.Source = this; - m_splitterOffsetBinding.Path = new PropertyPath( "(0).(1).X", - DataGridControl.DataGridContextProperty, - TableflowView.FixedColumnSplitterTranslationProperty ); - - m_splitterOffsetBinding.Mode = BindingMode.OneWay; - } - - BindingOperations.SetBinding( - this, - ScrollingCellsDecorator.SplitterOffsetProperty, - m_splitterOffsetBinding ); - } - - private void ClearSplitterOffsetBinding() - { - BindingOperations.ClearBinding( this, - ScrollingCellsDecorator.SplitterOffsetProperty ); - } - - - #endregion - - #region Private Fields - - private ScrollViewer m_scrollViewer; // = null; - private Binding m_splitterOffsetBinding; // = null; - private static Binding AreColumnsBeingReorderedBinding; // = null; - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/SynchronizedScrollViewer.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/SynchronizedScrollViewer.cs deleted file mode 100644 index 977d8fbf..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/SynchronizedScrollViewer.cs +++ /dev/null @@ -1,520 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Input; -using System.Windows.Threading; -using Xceed.Utils.Math; - -namespace Xceed.Wpf.DataGrid.Views -{ - public class SynchronizedScrollViewer : ScrollViewer, DataGridScrollViewer.IDeferableScrollChanged - { - #region Constructors - - static SynchronizedScrollViewer() - { - ScrollViewer.HorizontalScrollBarVisibilityProperty.OverrideMetadata( typeof( SynchronizedScrollViewer ), new FrameworkPropertyMetadata( ScrollBarVisibility.Hidden ) ); - ScrollViewer.VerticalScrollBarVisibilityProperty.OverrideMetadata( typeof( SynchronizedScrollViewer ), new FrameworkPropertyMetadata( ScrollBarVisibility.Hidden ) ); - - // By default, we never want item scrolling. - ScrollViewer.CanContentScrollProperty.OverrideMetadata( typeof( SynchronizedScrollViewer ), new FrameworkPropertyMetadata( false ) ); - } - - public SynchronizedScrollViewer() - { - // ScrollViewer binds these three properties to the TemplatedParent properties. - // Changing their default value using only OverrideMetadata would not work. - this.HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden; - this.VerticalScrollBarVisibility = ScrollBarVisibility.Hidden; - } - - #endregion - - #region DataGridScrollViewer.IDeferableScrollChanged Implementation - - bool DataGridScrollViewer.IDeferableScrollChanged.DeferScrollChanged - { - get - { - return m_deferScrollChange; - } - set - { - - var valueChanged = ( m_deferScrollChange != value ); - - m_deferScrollChange = value; - - if( m_mainScrollViewer == null ) - return; - - if( !m_deferScrollChange && valueChanged ) - { - var scrollOrientation = this.ScrollOrientation; - - if( ( scrollOrientation & ScrollOrientation.Horizontal ) == ScrollOrientation.Horizontal ) - { - this.ScrollToHorizontalOffset( m_mainScrollViewer.HorizontalOffset ); - } - - if( ( scrollOrientation & ScrollOrientation.Vertical ) == ScrollOrientation.Vertical ) - { - this.ScrollToVerticalOffset( m_mainScrollViewer.VerticalOffset ); - } - } - } - } - - #endregion - - #region ScrollOrientation property - - public static readonly DependencyProperty ScrollOrientationProperty = DependencyProperty.Register( - "ScrollOrientation", - typeof( ScrollOrientation ), - typeof( SynchronizedScrollViewer ), - new PropertyMetadata( ScrollOrientation.Horizontal ) ); - - public ScrollOrientation ScrollOrientation - { - get - { - return ( ScrollOrientation )this.GetValue( SynchronizedScrollViewer.ScrollOrientationProperty ); - } - - set - { - this.SetValue( SynchronizedScrollViewer.ScrollOrientationProperty, value ); - } - } - - #endregion - - #region LimitScrolling Internal Property - - internal static readonly DependencyProperty LimitScrollingProperty = DependencyProperty.Register( - "LimitScrolling", - typeof( bool ), - typeof( SynchronizedScrollViewer ), - new UIPropertyMetadata( true ) ); - - internal bool LimitScrolling - { - get - { - return ( bool )this.GetValue( SynchronizedScrollViewer.LimitScrollingProperty ); - } - set - { - this.SetValue( SynchronizedScrollViewer.LimitScrollingProperty, value ); - } - } - - #endregion - - public override void OnApplyTemplate() - { - base.OnApplyTemplate(); - - if( this.TemplatedParent != m_mainScrollViewer ) - { - if( m_mainScrollViewer != null ) - { - m_mainScrollViewer.ScrollChanged -= new ScrollChangedEventHandler( this.OnMainScrollViewer_ScrollChanged ); - } - - m_mainScrollViewer = this.TemplatedParent as ScrollViewer; - - if( m_mainScrollViewer != null ) - { - m_mainScrollViewer.ScrollChanged += new ScrollChangedEventHandler( this.OnMainScrollViewer_ScrollChanged ); - } - } - } - - protected override void OnScrollChanged( ScrollChangedEventArgs e ) - { - e.Handled = true; - - base.OnScrollChanged( e ); - - // m_mainScrollViewer will remain null in design mode and if it's null, nothing to update - if( m_mainScrollViewer == null ) - return; - - // Sometimes, a row in the SynchronizedScrollViewer will scroll by itself, - // not triggered by the main ScrollViewer scrolling. In that case, we want - // to update the main ScrollViewer. A typical example is when a Row's cell is - // brought into view by, let's say, activating the cell editor. - var invalidateMainScrollViewerMeasure = false; - - // If the Extent is 0, there is no reason to update the main ScrollViewer offset since this means there are no children. - if( this.CanScrollHorizontally() ) - { - invalidateMainScrollViewerMeasure = invalidateMainScrollViewerMeasure || !DoubleUtil.AreClose( 0, e.ExtentWidthChange ); - - this.BeginUpdateMainScrollViewer( e ); - } - - // If the Extent is 0, there is no reason to update the main ScrollViewer offset since this means there are no children. - if( this.CanScrollVertically() ) - { - invalidateMainScrollViewerMeasure = invalidateMainScrollViewerMeasure || !DoubleUtil.AreClose( 0, e.ExtentHeightChange ); - - this.BeginUpdateMainScrollViewer( e ); - } - - // In some situations, the Extent*Change event is received AFTER the - // layout pass of the mainScrollViewer is done. Since the measure of the - // mainScrollViewer uses the SynchronizedScrollViewer Extent size, we must - // call InvalidateMeasure on the mainScrollViewer to ensure it is correctly - // layouted - if( invalidateMainScrollViewerMeasure ) - { - m_mainScrollViewer.InvalidateMeasure(); - } - } - - protected override void OnPreviewKeyDown( KeyEventArgs e ) - { - if( e.Handled ) - return; - - switch( e.Key ) - { - // Handle the System key definition (basically with ALT key pressed) - case Key.System: - this.HandlePreviewSystemKey( e ); - break; - - case Key.Tab: - this.HandlePreviewTabKey( e ); - break; - - case Key.PageUp: - this.HandlePreviewPageUpKey( e ); - break; - - case Key.PageDown: - this.HandlePreviewPageDownKey( e ); - break; - - case Key.Home: - this.HandlePreviewHomeKey( e ); - break; - - case Key.End: - this.HandlePreviewEndKey( e ); - break; - - case Key.Up: - this.HandlePreviewUpKey( e ); - break; - - case Key.Down: - this.HandlePreviewDownKey( e ); - break; - - case Key.Left: - this.HandlePreviewLeftKey( e ); - break; - - case Key.Right: - this.HandlePreviewRightKey( e ); - break; - - default: - base.OnPreviewKeyDown( e ); - break; - } - } - - protected virtual void HandlePreviewSystemKey( KeyEventArgs e ) - { - } - - protected virtual void HandlePreviewTabKey( KeyEventArgs e ) - { - } - - protected virtual void HandlePreviewLeftKey( KeyEventArgs e ) - { - DataGridItemsHost.BringIntoViewKeyboardFocusedElement(); - this.UpdateLayout(); - } - - protected virtual void HandlePreviewRightKey( KeyEventArgs e ) - { - DataGridItemsHost.BringIntoViewKeyboardFocusedElement(); - this.UpdateLayout(); - } - - protected virtual void HandlePreviewUpKey( KeyEventArgs e ) - { - DataGridItemsHost.BringIntoViewKeyboardFocusedElement(); - this.UpdateLayout(); - } - - protected virtual void HandlePreviewDownKey( KeyEventArgs e ) - { - DataGridItemsHost.BringIntoViewKeyboardFocusedElement(); - this.UpdateLayout(); - } - - protected virtual void HandlePreviewPageUpKey( KeyEventArgs e ) - { - } - - protected virtual void HandlePreviewPageDownKey( KeyEventArgs e ) - { - } - - protected virtual void HandlePreviewHomeKey( KeyEventArgs e ) - { - } - - protected virtual void HandlePreviewEndKey( KeyEventArgs e ) - { - } - - protected override void OnKeyDown( KeyEventArgs e ) - { - if( e.Handled ) - return; - - switch( e.Key ) - { - // Handle the System key definition (basically with ALT key pressed) - case Key.System: - this.HandleSystemKey( e ); - break; - - case Key.Tab: - this.HandleTabKey( e ); - break; - - case Key.PageUp: - this.HandlePageUpKey( e ); - break; - - case Key.PageDown: - this.HandlePageDownKey( e ); - break; - - case Key.Home: - this.HandleHomeKey( e ); - break; - - case Key.End: - this.HandleEndKey( e ); - break; - - case Key.Up: - this.HandleUpKey( e ); - break; - - case Key.Down: - this.HandleDownKey( e ); - break; - - case Key.Left: - this.HandleLeftKey( e ); - break; - - case Key.Right: - this.HandleRightKey( e ); - break; - - default: - base.OnKeyDown( e ); - break; - } - } - - protected virtual void HandleSystemKey( KeyEventArgs e ) - { - } - - protected virtual void HandleTabKey( KeyEventArgs e ) - { - } - - protected virtual void HandlePageUpKey( KeyEventArgs e ) - { - // Ensure to at least process the PageUp as Key.Up - // to avoid the TableViewScrollViewer to process the key - // directly without moving the focus. - e.Handled = DataGridItemsHost.ProcessMoveFocus( Key.Up ); - - // We were not able to move focus out of the - // SynchronizedScrollViewer but the focus is still inside. - // Mark the key as handled to avoid the DataGridScrollViewer - // to process the PageUp. - if( !e.Handled && this.IsKeyboardFocusWithin ) - { - e.Handled = true; - } - } - - protected virtual void HandlePageDownKey( KeyEventArgs e ) - { - // Ensure to at least process the PageDown as Key.Down - // to avoid the TableViewScrollViewer to process the key - // directly without moving the focus. - e.Handled = DataGridItemsHost.ProcessMoveFocus( Key.Down ); - - // We were not able to move focus out of the - // SynchronizedScrollViewer but the focus is still inside. - // Mark the key as handled to avoid the DataGridScrollViewer - // to process the PageDown. - if( !e.Handled && this.IsKeyboardFocusWithin ) - { - e.Handled = true; - } - } - - protected virtual void HandleHomeKey( KeyEventArgs e ) - { - } - - protected virtual void HandleEndKey( KeyEventArgs e ) - { - } - - protected virtual void HandleUpKey( KeyEventArgs e ) - { - e.Handled = DataGridItemsHost.ProcessMoveFocus( e.Key ); - } - - protected virtual void HandleDownKey( KeyEventArgs e ) - { - e.Handled = DataGridItemsHost.ProcessMoveFocus( e.Key ); - } - - protected virtual void HandleLeftKey( KeyEventArgs e ) - { - e.Handled = DataGridItemsHost.ProcessMoveFocus( e.Key ); - } - - protected virtual void HandleRightKey( KeyEventArgs e ) - { - e.Handled = DataGridItemsHost.ProcessMoveFocus( e.Key ); - } - - private bool CanScrollHorizontally() - { - return ( ( this.ScrollOrientation & ScrollOrientation.Horizontal ) == ScrollOrientation.Horizontal ) - && ( this.ExtentWidth > 0d ); - } - - private bool CanScrollVertically() - { - return ( ( this.ScrollOrientation & ScrollOrientation.Vertical ) == ScrollOrientation.Vertical ) - && ( this.ExtentHeight > 0d ); - } - - private void BeginUpdateMainScrollViewer( ScrollChangedEventArgs e ) - { - if( m_scrollChangedEventArgs == null ) - { - m_scrollChangedEventArgs = e; - } - - if( m_updateMainScrollViewer == null ) - { - m_updateMainScrollViewer = this.Dispatcher.BeginInvoke( new Action( this.UpdateMainScrollViewer ), DispatcherPriority.Send ); - } - } - - private void UpdateMainScrollViewer() - { - var e = m_scrollChangedEventArgs; - - m_updateMainScrollViewer = null; - m_scrollChangedEventArgs = null; - - if( ( m_mainScrollViewer == null ) || ( e == null ) ) - return; - - if( this.CanScrollHorizontally() && ( e.HorizontalOffset != m_mainScrollViewer.HorizontalOffset ) ) - { - m_mainScrollViewer.ScrollToHorizontalOffset( e.HorizontalOffset ); - } - - if( this.CanScrollVertically() && ( e.VerticalOffset != m_mainScrollViewer.VerticalOffset ) ) - { - m_mainScrollViewer.ScrollToVerticalOffset( e.VerticalOffset ); - } - } - - private void OnMainScrollViewer_ScrollChanged( object sender, ScrollChangedEventArgs e ) - { - if( ( e.OriginalSource != m_mainScrollViewer ) || m_deferScrollChange ) - return; - - var orientation = this.ScrollOrientation; - var limitScrolling = this.LimitScrolling; - - // If the Extent is 0, there is no reason to update the main ScrollViewer offset since this means there are no children. - if( this.CanScrollHorizontally() ) - { - var offset = ( limitScrolling ) ? Math.Min( e.HorizontalOffset, this.ExtentWidth - this.ViewportWidth ) : e.HorizontalOffset; - - if( offset != this.HorizontalOffset ) - { - // We keep the original ScrollChangedEventArgs because when we'll update - // our offset, it might be less than what was asked in the first place. Even - // if this doesn't make sense to us, it might be ok for the m_mainScrollViewer - // to scroll to that value. Since changing our offset will trigger the OnScrollChanged - // that will update the m_mainScrollViewer, we want to changer it's offset to - // the right value. - m_scrollChangedEventArgs = e; - this.ScrollToHorizontalOffset( offset ); - } - } - - // If the Extent is 0, there is no reason to update the main ScrollViewer offset since this means there are no children. - if( this.CanScrollVertically() ) - { - var offset = ( limitScrolling ) ? Math.Min( e.VerticalOffset, this.ExtentHeight - this.ViewportHeight ) : e.VerticalOffset; - - if( offset != this.VerticalOffset ) - { - // We keep the original ScrollChangedEventArgs because when we'll update - // our offset, it might be less than what was asked in the first place. Even - // if this doesn't make sense to us, it might be ok for the m_mainScrollViewer - // to scroll to that value. Since changing our offset will trigger the OnScrollChanged - // that will update the m_mainScrollViewer, we want to changer it's offset to - // the right value. - m_scrollChangedEventArgs = e; - this.ScrollToVerticalOffset( offset ); - } - } - } - - #region Private Fields - - private ScrollViewer m_mainScrollViewer; //null - private bool m_deferScrollChange; //false - private ScrollChangedEventArgs m_scrollChangedEventArgs; //null - private DispatcherOperation m_updateMainScrollViewer; //null - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TableView.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TableView.cs deleted file mode 100644 index 0b564811..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TableView.cs +++ /dev/null @@ -1,949 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; -using System.Diagnostics; -using System.IO; -using System.Security; -using System.Windows; -using System.Windows.Input; -using System.Windows.Media; - -namespace Xceed.Wpf.DataGrid.Views -{ - public class TableView : UIViewBase - { - // We must add a setter since this value is used as default value of a DependencyObject which will be instanciated before the static constructor is called - internal static Cursor DefaultFixedColumnSplitterCursor - { - get - { - if( TableView.DefaultFixedColumnSplitterCursorCache == null ) - { - try - { - var uri = new Uri( _XceedVersionInfo.CurrentAssemblyPackUri + ";component/FixedColumnSplitter.cur" ); - var info = Application.GetResourceStream( uri ); - - if( info != null ) - { - TableView.DefaultFixedColumnSplitterCursorCache = new Cursor( info.Stream ); - } - } - catch( SecurityException ) - { - } - catch( UriFormatException ) - { - } - catch( IOException ) - { - } - finally - { - if( TableView.DefaultFixedColumnSplitterCursorCache == null ) - { - TableView.DefaultFixedColumnSplitterCursorCache = Cursors.SizeWE; - } - } - } - - return TableView.DefaultFixedColumnSplitterCursorCache; - } - } - - private static Cursor DefaultFixedColumnSplitterCursorCache; - - internal static Cursor DefaultRowSelectorResizeNorthSouthCursor = Cursors.SizeNS; - internal static Cursor DefaultRowSelectorResizeWestEastCursor = Cursors.SizeWE; - - static TableView() - { - FrameworkContentElement.DefaultStyleKeyProperty.OverrideMetadata( typeof( TableView ), new FrameworkPropertyMetadata( TableView.GetDefaultStyleKey( typeof( TableView ), null ) ) ); - - TableView.CompensationOffsetProperty = TableView.CompensationOffsetPropertyKey.DependencyProperty; - - TableView.DefaultColumnManagerRowTemplate = new DataTemplate(); - TableView.DefaultColumnManagerRowTemplate.VisualTree = new FrameworkElementFactory( typeof( ColumnManagerRow ) ); - TableView.DefaultColumnManagerRowTemplate.Seal(); - - TableView.DefaultGroupByControlTemplate = new DataTemplate(); - FrameworkElementFactory groupByControl = new FrameworkElementFactory( typeof( HierarchicalGroupByControl ) ); - groupByControl.SetValue( TableView.CanScrollHorizontallyProperty, false ); - TableView.DefaultGroupByControlTemplate.VisualTree = groupByControl; - TableView.DefaultGroupByControlTemplate.Seal(); - } - - public TableView() - { - } - - #region AutoFillLastPage Property - - [EditorBrowsable( EditorBrowsableState.Never )] - [ViewProperty( ViewPropertyMode.ViewOnly )] - public static readonly DependencyProperty AutoFillLastPageProperty = DependencyProperty.RegisterAttached( - "AutoFillLastPage", - typeof( bool ), - typeof( TableView ), - new PropertyMetadata( true ) ); - - [EditorBrowsable( EditorBrowsableState.Never )] - public bool AutoFillLastPage - { - get - { - return ( bool )this.GetValue( TableView.AutoFillLastPageProperty ); - } - set - { - this.SetValue( TableView.AutoFillLastPageProperty, value ); - } - } - - [EditorBrowsable( EditorBrowsableState.Never )] - public static bool GetAutoFillLastPage( DependencyObject obj ) - { - return ( bool )obj.GetValue( TableView.AutoFillLastPageProperty ); - } - - [EditorBrowsable( EditorBrowsableState.Never )] - public static void SetAutoFillLastPage( DependencyObject obj, bool value ) - { - obj.SetValue( TableView.AutoFillLastPageProperty, value ); - } - - #endregion - - #region CanScrollHorizontally Attached Property - - public static readonly DependencyProperty CanScrollHorizontallyProperty = DependencyProperty.RegisterAttached( - "CanScrollHorizontally", - typeof( bool ), - typeof( TableView ), - new UIPropertyMetadata( true, new PropertyChangedCallback( TableView.OnCanScrollHorizontallyChanged ) ) ); - - public static bool GetCanScrollHorizontally( DependencyObject obj ) - { - return ( bool )obj.GetValue( TableView.CanScrollHorizontallyProperty ); - } - - public static void SetCanScrollHorizontally( DependencyObject obj, bool value ) - { - obj.SetValue( TableView.CanScrollHorizontallyProperty, value ); - } - - private static void OnCanScrollHorizontallyChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - // This property makes sense (only works) for potentially visible element; UIElement. - var element = sender as FrameworkElement; - if( element == null ) - return; - - TableViewScrollViewer.SetFixedTranslateTransform( element, ( bool )e.NewValue ); - } - - #endregion - - #region CompensationOffset Attached Property - - internal static readonly DependencyPropertyKey CompensationOffsetPropertyKey = DependencyProperty.RegisterAttachedReadOnly( - "CompensationOffset", - typeof( double ), - typeof( TableView ), - new FrameworkPropertyMetadata( 0d, FrameworkPropertyMetadataOptions.Inherits ) ); - - internal static readonly DependencyProperty CompensationOffsetProperty; - - internal static double GetCompensationOffset( DependencyObject obj ) - { - return ( double )obj.GetValue( TableView.CompensationOffsetProperty ); - } - - internal static void SetCompensationOffset( DependencyObject obj, double value ) - { - obj.SetValue( TableView.CompensationOffsetPropertyKey, value ); - } - - #endregion - - // View properties - - #region ColumnStretchMinWidth Property - - [ViewProperty( ViewPropertyMode.Routed )] - public static readonly DependencyProperty ColumnStretchMinWidthProperty = DependencyProperty.RegisterAttached( - "ColumnStretchMinWidth", - typeof( double ), - typeof( TableView ), - new UIPropertyMetadata( 50d ), - new ValidateValueCallback( TableView.ValidateColumnStretchMinWidthCallback ) ); - - public double ColumnStretchMinWidth - { - get - { - return ( double )this.GetValue( TableView.ColumnStretchMinWidthProperty ); - } - set - { - this.SetValue( TableView.ColumnStretchMinWidthProperty, value ); - } - } - - public static double GetColumnStretchMinWidth( DependencyObject obj ) - { - return ( double )obj.GetValue( TableView.ColumnStretchMinWidthProperty ); - } - - public static void SetColumnStretchMinWidth( DependencyObject obj, double value ) - { - obj.SetValue( TableView.ColumnStretchMinWidthProperty, value ); - } - - internal static bool ValidateColumnStretchMinWidthCallback( object value ) - { - double doubleValue = ( double )value; - - if( doubleValue < 0d ) - return false; - - if( double.IsInfinity( doubleValue ) ) - return false; - - if( double.IsNaN( doubleValue ) ) - return false; - - return true; - } - - #endregion - - #region ColumnStretchMode Property - - [ViewProperty( ViewPropertyMode.Routed )] - public static readonly DependencyProperty ColumnStretchModeProperty = DependencyProperty.RegisterAttached( - "ColumnStretchMode", - typeof( ColumnStretchMode ), - typeof( TableView ), - new UIPropertyMetadata( ColumnStretchMode.None, new PropertyChangedCallback( TableView.ColumnStretchModeChanged ) ) ); - - public ColumnStretchMode ColumnStretchMode - { - get - { - return ( ColumnStretchMode )this.GetValue( TableView.ColumnStretchModeProperty ); - } - set - { - this.SetValue( TableView.ColumnStretchModeProperty, value ); - } - } - - public static ColumnStretchMode GetColumnStretchMode( DependencyObject obj ) - { - return ( ColumnStretchMode )obj.GetValue( TableView.ColumnStretchModeProperty ); - } - - public static void SetColumnStretchMode( DependencyObject obj, ColumnStretchMode value ) - { - obj.SetValue( TableView.ColumnStretchModeProperty, value ); - } - - private static void ColumnStretchModeChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - DataGridContext dataGridContext = sender as DataGridContext; - - System.Diagnostics.Debug.Assert( ( dataGridContext != null ) || ( sender is TableView ) || ( sender is DetailConfiguration ), "ColumnStretchMode is currently only handled on TableView, DetailConfiguration and DataGridContext." ); - - if( ( dataGridContext != null ) && ( dataGridContext.VisibleColumns.Count > 0 ) ) - { - // When ColumnStretchMode changes, the DesiredWidth columns will not be the - // same. Reset all DesiredWidth. - foreach( ColumnBase column in dataGridContext.VisibleColumns ) - { - column.ClearValue( Column.DesiredWidthProperty ); - } - - // The previous ClearValues don't necessary have an effect. For instance, if a - // MaxWidth was in effect for the previous stretch mode or if there are no * in - // "None" stretch mode. Force a refresh by assigning a dummy value to the - // DesiredWidth of the new stretch mode related Column that will be ultimately - // modified by VirtualizingStackPanel.MeasureOverride. - switch( ( ColumnStretchMode )e.NewValue ) - { - case ColumnStretchMode.First: - TableView.TouchColumnWidth( dataGridContext.VisibleColumns[ 0 ] ); - break; - - case ColumnStretchMode.Last: - TableView.TouchColumnWidth( dataGridContext.VisibleColumns[ dataGridContext.VisibleColumns.Count - 1 ] ); - break; - - case ColumnStretchMode.All: - { - foreach( ColumnBase column in dataGridContext.VisibleColumns ) - { - // One column.ActualWidth modification is enough to trigger a new - // Measure pass. Stop at the first effective "touch". - if( TableView.TouchColumnWidth( column ) ) - break; - } - } - break; - - case ColumnStretchMode.None: - { - foreach( ColumnBase column in dataGridContext.VisibleColumns ) - { - if( column.Width.UnitType == ColumnWidthUnitType.Star ) - { - // One column.ActualWidth modification is enough to trigger a new - // Measure pass. Stop at the first effective "touch". - if( TableView.TouchColumnWidth( column ) ) - break; - } - } - } - break; - } - } - } - - private static bool TouchColumnWidth( ColumnBase column ) - { - bool modified = false; - - if( column != null ) - { - double oldActualWidth = column.ActualWidth; - - // Assign a temporary value to DesiredWidth (different from ActualWidth) - // to force a new Measure pass. - if( column.ActualWidth > column.MinWidth ) - { - column.DesiredWidth = column.MinWidth; - } - else - { - column.DesiredWidth = column.ActualWidth + 1d; - } - - modified = !Xceed.Utils.Math.DoubleUtil.AreClose( oldActualWidth, column.ActualWidth ); - } - - return modified; - } - - #endregion - - #region RemoveColumnStretchingOnResize Property - - [ViewProperty( ViewPropertyMode.Routed )] - public static readonly DependencyProperty RemoveColumnStretchingOnResizeProperty = DependencyProperty.RegisterAttached( - "RemoveColumnStretchingOnResize", - typeof( bool ), - typeof( TableView ), - new UIPropertyMetadata( false ) ); - - public bool RemoveColumnStretchingOnResize - { - get - { - return ( bool )this.GetValue( TableView.RemoveColumnStretchingOnResizeProperty ); - } - set - { - this.SetValue( TableView.RemoveColumnStretchingOnResizeProperty, value ); - } - } - - public static bool GetRemoveColumnStretchingOnResize( DependencyObject obj ) - { - return ( bool )obj.GetValue( TableView.RemoveColumnStretchingOnResizeProperty ); - } - - public static void SetRemoveColumnStretchingOnResize( DependencyObject obj, bool value ) - { - obj.SetValue( TableView.RemoveColumnStretchingOnResizeProperty, value ); - } - - #endregion - - #region FixedColumnCount Property - - [ViewProperty( ViewPropertyMode.RoutedNoFallback, FlattenDetailBindingMode.MasterOneWay )] - public static readonly DependencyProperty FixedColumnCountProperty = DependencyProperty.RegisterAttached( - "FixedColumnCount", - typeof( int ), - typeof( TableView ), - new UIPropertyMetadata( 0 ), - new ValidateValueCallback( TableView.ValidateFixedColumnCountCallback ) ); - - public int FixedColumnCount - { - get - { - return ( int )this.GetValue( TableView.FixedColumnCountProperty ); - } - set - { - this.SetValue( TableView.FixedColumnCountProperty, value ); - } - } - - private static bool ValidateFixedColumnCountCallback( object value ) - { - return ( ( int )value >= 0 ); - } - - public static int GetFixedColumnCount( DependencyObject obj ) - { - return ( int )obj.GetValue( TableView.FixedColumnCountProperty ); - } - - public static void SetFixedColumnCount( DependencyObject obj, int value ) - { - obj.SetValue( TableView.FixedColumnCountProperty, value ); - } - - #endregion - - #region FixedColumnDropMarkPen Property - - [ViewProperty( ViewPropertyMode.Routed )] - public static readonly DependencyProperty FixedColumnDropMarkPenProperty = DependencyProperty.RegisterAttached( - "FixedColumnDropMarkPen", - typeof( Pen ), - typeof( TableView ) ); - - public Pen FixedColumnDropMarkPen - { - get - { - return ( Pen )this.GetValue( TableView.FixedColumnDropMarkPenProperty ); - } - set - { - this.SetValue( TableView.FixedColumnDropMarkPenProperty, value ); - } - } - - public static Pen GetFixedColumnDropMarkPen( DependencyObject obj ) - { - return ( Pen )obj.GetValue( TableView.FixedColumnDropMarkPenProperty ); - } - - public static void SetFixedColumnDropMarkPen( DependencyObject obj, Pen value ) - { - obj.SetValue( TableView.FixedColumnDropMarkPenProperty, value ); - } - - #endregion - - #region HorizontalGridLineBrush Property - - [ViewProperty( ViewPropertyMode.Routed )] - public static readonly DependencyProperty HorizontalGridLineBrushProperty = DependencyProperty.RegisterAttached( - "HorizontalGridLineBrush", - typeof( Brush ), - typeof( TableView ), - new PropertyMetadata( null ) ); - - public Brush HorizontalGridLineBrush - { - get - { - return ( Brush )this.GetValue( TableView.HorizontalGridLineBrushProperty ); - } - set - { - this.SetValue( TableView.HorizontalGridLineBrushProperty, value ); - } - } - - public static Brush GetHorizontalGridLineBrush( DependencyObject obj ) - { - return ( Brush )obj.GetValue( TableView.HorizontalGridLineBrushProperty ); - } - - public static void SetHorizontalGridLineBrush( DependencyObject obj, Brush value ) - { - obj.SetValue( TableView.HorizontalGridLineBrushProperty, value ); - } - - #endregion - - #region HorizontalGridLineThickness Property - - [ViewProperty( ViewPropertyMode.Routed )] - public static readonly DependencyProperty HorizontalGridLineThicknessProperty = DependencyProperty.RegisterAttached( - "HorizontalGridLineThickness", - typeof( double ), - typeof( TableView ), - new PropertyMetadata() ); - - public double HorizontalGridLineThickness - { - get - { - return ( double )this.GetValue( TableView.HorizontalGridLineThicknessProperty ); - } - set - { - this.SetValue( TableView.HorizontalGridLineThicknessProperty, value ); - } - } - - public static double GetHorizontalGridLineThickness( DependencyObject obj ) - { - return ( double )obj.GetValue( TableView.HorizontalGridLineThicknessProperty ); - } - - public static void SetHorizontalGridLineThickness( DependencyObject obj, double value ) - { - obj.SetValue( TableView.HorizontalGridLineThicknessProperty, value ); - } - - #endregion - - #region VerticalGridLineBrush Property - - [ViewProperty( ViewPropertyMode.Routed )] - public static readonly DependencyProperty VerticalGridLineBrushProperty = DependencyProperty.RegisterAttached( - "VerticalGridLineBrush", - typeof( Brush ), - typeof( TableView ), - new PropertyMetadata( null ) ); - - public Brush VerticalGridLineBrush - { - get - { - return ( Brush )this.GetValue( TableView.VerticalGridLineBrushProperty ); - } - set - { - this.SetValue( TableView.VerticalGridLineBrushProperty, value ); - } - } - - public static Brush GetVerticalGridLineBrush( DependencyObject obj ) - { - return ( Brush )obj.GetValue( TableView.VerticalGridLineBrushProperty ); - } - - public static void SetVerticalGridLineBrush( DependencyObject obj, Brush value ) - { - obj.SetValue( TableView.VerticalGridLineBrushProperty, value ); - } - - #endregion - - #region VerticalGridLineThickness Property - - [ViewProperty( ViewPropertyMode.Routed )] - public static readonly DependencyProperty VerticalGridLineThicknessProperty = DependencyProperty.RegisterAttached( - "VerticalGridLineThickness", - typeof( double ), - typeof( TableView ), - new PropertyMetadata() ); - - public double VerticalGridLineThickness - { - get - { - return ( double )this.GetValue( TableView.VerticalGridLineThicknessProperty ); - } - set - { - this.SetValue( TableView.VerticalGridLineThicknessProperty, value ); - } - } - - public static double GetVerticalGridLineThickness( DependencyObject obj ) - { - return ( double )obj.GetValue( TableView.VerticalGridLineThicknessProperty ); - } - - public static void SetVerticalGridLineThickness( DependencyObject obj, double value ) - { - obj.SetValue( TableView.VerticalGridLineThicknessProperty, value ); - } - - #endregion - - #region AllowRowResize Property - - //Note: This property is exceptional, effectivelly, while this is a property that configures the View, it is not an attached property - // This has the result that it is not settable on any other thing than a TableView (cannot be configured differently for details). - // The property keeps on working as intended since it is a DP and we rely on the "Attached" property mechanism only so that the - // property can be set on DetailConfigurations. - - [ViewProperty( ViewPropertyMode.ViewOnly )] - public static readonly DependencyProperty AllowRowResizeProperty = DependencyProperty.Register( - "AllowRowResize", - typeof( bool ), - typeof( TableView ), - new FrameworkPropertyMetadata( true ) ); - - public bool AllowRowResize - { - get - { - return ( bool )this.GetValue( TableView.AllowRowResizeProperty ); - } - set - { - this.SetValue( TableView.AllowRowResizeProperty, value ); - } - } - - #endregion - - #region RowSelectorPaneWidth Property - - //Note: This property is exceptional, effectivelly, while this is a property that configures the View, it is not an attached property - // This has the result that it is not settable on any other thing than a TableView (cannot be configured differently for details). - // The property keeps on working as intended since it is a DP and we rely on the "Attached" property mechanism only so that the - // property can be set on DetailConfigurations. - - [ViewProperty( ViewPropertyMode.ViewOnly )] - public static readonly DependencyProperty RowSelectorPaneWidthProperty = TableViewScrollViewer.RowSelectorPaneWidthProperty.AddOwner( typeof( TableView ) ); - - public double RowSelectorPaneWidth - { - get - { - return ( double )this.GetValue( TableView.RowSelectorPaneWidthProperty ); - } - set - { - this.SetValue( TableView.RowSelectorPaneWidthProperty, value ); - } - } - - #endregion - - #region ShowRowSelectorPane Property - - //Note: This property is exceptional, effectivelly, while this is a property that configures the View, it is not an attached property - // This has the result that it is not settable on any other thing than a TableView (cannot be configured differently for details). - // The property keeps on working as intended since it is a DP and we rely on the "Attached" property mechanism only so that the - // property can be set on DetailConfigurations. - - [ViewProperty( ViewPropertyMode.ViewOnly )] - public static readonly DependencyProperty ShowRowSelectorPaneProperty = DependencyProperty.Register( - "ShowRowSelectorPane", - typeof( bool ), - typeof( TableView ), - new PropertyMetadata( true ) ); - - public bool ShowRowSelectorPane - { - get - { - return ( bool )this.GetValue( TableView.ShowRowSelectorPaneProperty ); - } - set - { - this.SetValue( TableView.ShowRowSelectorPaneProperty, value ); - } - } - - #endregion - - #region GroupLevelIndicatorWidth Property - - [ViewProperty( ViewPropertyMode.Routed )] - public static readonly DependencyProperty GroupLevelIndicatorWidthProperty = DependencyProperty.RegisterAttached( - "GroupLevelIndicatorWidth", - typeof( double ), - typeof( TableView ), - new UIPropertyMetadata() ); - - public double GroupLevelIndicatorWidth - { - get - { - return ( double )this.GetValue( TableView.GroupLevelIndicatorWidthProperty ); - } - set - { - this.SetValue( TableView.GroupLevelIndicatorWidthProperty, value ); - } - } - - public static double GetGroupLevelIndicatorWidth( DependencyObject obj ) - { - return ( double )obj.GetValue( TableView.GroupLevelIndicatorWidthProperty ); - } - - public static void SetGroupLevelIndicatorWidth( DependencyObject obj, double value ) - { - obj.SetValue( TableView.GroupLevelIndicatorWidthProperty, value ); - } - - #endregion - - #region DetailIndicatorWidth Property - - [ViewProperty( ViewPropertyMode.Routed )] - public static readonly DependencyProperty DetailIndicatorWidthProperty = DependencyProperty.RegisterAttached( - "DetailIndicatorWidth", - typeof( double ), - typeof( TableView ), - new UIPropertyMetadata() ); - - public double DetailIndicatorWidth - { - get - { - return ( double )this.GetValue( TableView.DetailIndicatorWidthProperty ); - } - set - { - this.SetValue( TableView.DetailIndicatorWidthProperty, value ); - } - } - - public static double GetDetailIndicatorWidth( DependencyObject obj ) - { - return ( double )obj.GetValue( TableView.DetailIndicatorWidthProperty ); - } - - public static void SetDetailIndicatorWidth( DependencyObject obj, double value ) - { - obj.SetValue( TableView.DetailIndicatorWidthProperty, value ); - } - - #endregion - - #region IsColumnVirtualizationEnabled Property - - [Obsolete( "The IsColumnVirtualizationEnabled property is obsolete and has been replaced by the ColumnVirtualizationMode property.", false )] - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - [ViewProperty( ViewPropertyMode.ViewOnly )] - public static readonly DependencyProperty IsColumnVirtualizationEnabledProperty = DependencyProperty.RegisterAttached( - "IsColumnVirtualizationEnabled", - typeof( bool ), - typeof( TableView ), - new UIPropertyMetadata( true ) ); - - [Obsolete( "The IsColumnVirtualizationEnabled property is obsolete and has been replaced by the ColumnVirtualizationMode property.", false )] - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - public bool IsColumnVirtualizationEnabled - { - get - { - return ( bool )this.GetValue( TableView.IsColumnVirtualizationEnabledProperty ); - } - set - { - this.SetValue( TableView.IsColumnVirtualizationEnabledProperty, value ); - } - } - - public static bool GetIsColumnVirtualizationEnabled( DependencyObject obj ) - { -#pragma warning disable 618 - return ( bool )obj.GetValue( TableView.IsColumnVirtualizationEnabledProperty ); -#pragma warning restore 618 - } - - public static void SetIsColumnVirtualizationEnabled( DependencyObject obj, bool value ) - { -#pragma warning disable 618 - obj.SetValue( TableView.IsColumnVirtualizationEnabledProperty, value ); -#pragma warning restore 618 - } - - #endregion - - #region ColumnVirtualizationMode Property - - [ViewProperty( ViewPropertyMode.ViewOnly )] - public static readonly DependencyProperty ColumnVirtualizationModeProperty = DependencyProperty.RegisterAttached( - "ColumnVirtualizationMode", - typeof( ColumnVirtualizationMode ), - typeof( TableView ), - new FrameworkPropertyMetadata( ColumnVirtualizationMode.Recycling ) ); - - public ColumnVirtualizationMode ColumnVirtualizationMode - { - get - { - return ( ColumnVirtualizationMode )this.GetValue( TableView.ColumnVirtualizationModeProperty ); - } - set - { - this.SetValue( TableView.ColumnVirtualizationModeProperty, value ); - } - } - - public static ColumnVirtualizationMode GetColumnVirtualizationMode( DependencyObject obj ) - { - return ( ColumnVirtualizationMode )obj.GetValue( TableView.ColumnVirtualizationModeProperty ); - } - - public static void SetColumnVirtualizationMode( DependencyObject obj, ColumnVirtualizationMode value ) - { - obj.SetValue( TableView.ColumnVirtualizationModeProperty, value ); - } - - #endregion - - #region IsAlternatingRowStyleEnabled Property - - [ViewProperty( ViewPropertyMode.Routed, FlattenDetailBindingMode.MasterOneWay )] - public static readonly DependencyProperty IsAlternatingRowStyleEnabledProperty = DependencyProperty.RegisterAttached( - "IsAlternatingRowStyleEnabled", - typeof( bool ), - typeof( TableView ), - new UIPropertyMetadata( false ) ); - - public bool IsAlternatingRowStyleEnabled - { - get - { - return TableView.GetIsAlternatingRowStyleEnabled( this ); - } - set - { - TableView.SetIsAlternatingRowStyleEnabled( this, value ); - } - } - - public static bool GetIsAlternatingRowStyleEnabled( DependencyObject obj ) - { - return ( bool )obj.GetValue( TableView.IsAlternatingRowStyleEnabledProperty ); - } - - public static void SetIsAlternatingRowStyleEnabled( DependencyObject obj, bool value ) - { - obj.SetValue( TableView.IsAlternatingRowStyleEnabledProperty, value ); - } - - #endregion - - #region AutoScrollInterval Attached Property - - [ViewProperty( ViewPropertyMode.ViewOnly )] - public static readonly DependencyProperty AutoScrollIntervalProperty = DependencyProperty.RegisterAttached( - "AutoScrollInterval", - typeof( int ), - typeof( TableView ), - new FrameworkPropertyMetadata( 100 ) ); - - public static int GetAutoScrollInterval( DependencyObject obj ) - { - return ( int )obj.GetValue( TableView.AutoScrollIntervalProperty ); - } - - public static void SetAutoScrollInterval( DependencyObject obj, int value ) - { - obj.SetValue( TableView.AutoScrollIntervalProperty, value ); - } - - #endregion - - #region AutoScrollThreshold Attached Property - - [ViewProperty( ViewPropertyMode.ViewOnly )] - internal static readonly DependencyProperty AutoScrollThresholdProperty = DependencyProperty.RegisterAttached( - "AutoScrollThreshold", - typeof( int ), - typeof( TableView ), - new FrameworkPropertyMetadata( 5 ) ); - - internal static int GetAutoScrollThreshold( DependencyObject obj ) - { - return ( int )obj.GetValue( TableView.AutoScrollThresholdProperty ); - } - - internal static void SetAutoScrollThreshold( DependencyObject obj, int value ) - { - obj.SetValue( TableView.AutoScrollThresholdProperty, value ); - } - - #endregion - - #region RowSelectorResizeNorthSouthCursor Property - - [ViewProperty( ViewPropertyMode.Routed )] - public static readonly DependencyProperty RowSelectorResizeNorthSouthCursorProperty = DependencyProperty.Register( - "RowSelectorResizeNorthSouthCursor", - typeof( Cursor ), - typeof( TableView ), - new FrameworkPropertyMetadata( TableView.DefaultRowSelectorResizeNorthSouthCursor ) ); - - public Cursor RowSelectorResizeNorthSouthCursor - { - get - { - return ( Cursor )this.GetValue( TableView.RowSelectorResizeNorthSouthCursorProperty ); - } - set - { - this.SetValue( TableView.RowSelectorResizeNorthSouthCursorProperty, value ); - } - } - - #endregion - - #region RowSelectorResizeWestEastCursor Property - - [ViewProperty( ViewPropertyMode.Routed )] - public static readonly DependencyProperty RowSelectorResizeWestEastCursorProperty = DependencyProperty.Register( - "RowSelectorResizeWestEastCursor", - typeof( Cursor ), - typeof( TableView ), - new FrameworkPropertyMetadata( TableView.DefaultRowSelectorResizeWestEastCursor ) ); - - public Cursor RowSelectorResizeWestEastCursor - { - get - { - return ( Cursor )this.GetValue( TableView.RowSelectorResizeWestEastCursorProperty ); - } - set - { - this.SetValue( TableView.RowSelectorResizeWestEastCursorProperty, value ); - } - } - - #endregion - - protected override void AddDefaultHeadersFooters() - { - this.FixedHeaders.Insert( 0, TableView.DefaultColumnManagerRowTemplate ); - this.FixedHeaders.Insert( 0, TableView.DefaultGroupByControlTemplate ); - } - - internal override ColumnVirtualizationManager CreateColumnVirtualizationManager( DataGridContext dataGridContext ) - { - Debug.Assert( dataGridContext != null ); - - return new TableViewColumnVirtualizationManager( dataGridContext ); - } - - private static readonly DataTemplate DefaultColumnManagerRowTemplate; - private static readonly DataTemplate DefaultGroupByControlTemplate; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TableViewEndPageInfo.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TableViewEndPageInfo.cs deleted file mode 100644 index 5fea2421..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TableViewEndPageInfo.cs +++ /dev/null @@ -1,89 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal sealed class TableViewEndPageInfo : TableViewPartialPageInfo - { - #region Constructor - - internal TableViewEndPageInfo( int value ) - { - if( value < 0 ) - throw new ArgumentException( "value must be greater than or equal to zero.", "value" ); - - m_value = value; - } - - #endregion - - #region Start Property - - public override int Start - { - get - { - throw new NotSupportedException(); - } - } - - #endregion - - #region End Property - - public override int End - { - get - { - return m_value; - } - } - - private readonly int m_value; - - #endregion - - protected override int GetHashCodeImpl() - { - return m_value; - } - - protected override bool EqualsImpl( TableViewPageInfo obj ) - { - var page = obj as TableViewEndPageInfo; - if( object.ReferenceEquals( page, null ) ) - return false; - - return ( page.m_value == m_value ); - } - - public override bool TryGetStart( out int value ) - { - value = 0; - - return false; - } - - public override bool TryGetEnd( out int value ) - { - value = m_value; - - return true; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TableViewFullPageInfo.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TableViewFullPageInfo.cs deleted file mode 100644 index 5a673fdc..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TableViewFullPageInfo.cs +++ /dev/null @@ -1,130 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal sealed class TableViewFullPageInfo : TableViewPageInfo - { - #region Constructor - - internal TableViewFullPageInfo( int start, int end, double size ) - { - if( start < 0 ) - throw new ArgumentException( "start must be greater than or equal to zero.", "start" ); - - if( end < 0 ) - throw new ArgumentException( "end must be greater than or equal to zero.", "end" ); - - if( end < start ) - throw new ArgumentException( "end must be greater than or equal to start.", "end" ); - - if( size < 0 ) - throw new ArgumentException( "size must be greater than or equal to zero.", "size" ); - - m_start = start; - m_end = end; - m_size = size; - } - - #endregion - - #region Start Property - - public override int Start - { - get - { - return m_start; - } - } - - private readonly int m_start; - - #endregion - - #region End Property - - public override int End - { - get - { - return m_end; - } - } - - private readonly int m_end; - - #endregion - - #region Length Property - - public override int Length - { - get - { - return m_end - m_start + 1; - } - } - - #endregion - - #region Size Property - - public override double Size - { - get - { - return m_size; - } - } - - private readonly double m_size; - - #endregion - - public override bool TryGetStart( out int value ) - { - value = m_start; - - return true; - } - - public override bool TryGetEnd( out int value ) - { - value = m_end; - - return true; - } - - protected override int GetHashCodeImpl() - { - return ( m_start ^ m_end ); - } - - protected override bool EqualsImpl( TableViewPageInfo obj ) - { - var page = obj as TableViewFullPageInfo; - if( object.ReferenceEquals( page, null ) ) - return false; - - return ( page.m_start == m_start ) - && ( page.m_end == m_end ) - && ( page.m_size == m_size ); - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TableViewHeaderFooterPanel.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TableViewHeaderFooterPanel.cs deleted file mode 100644 index 25506c84..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TableViewHeaderFooterPanel.cs +++ /dev/null @@ -1,414 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Diagnostics; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Input; -using System.Windows.Media; -using Xceed.Utils.Wpf; - -namespace Xceed.Wpf.DataGrid.Views -{ - public class TableViewHeaderFooterPanel : StackPanel - { - #region Constructor - - public TableViewHeaderFooterPanel() - { - this.AddHandler( FrameworkElement.RequestBringIntoViewEvent, new RequestBringIntoViewEventHandler( this.OnRequestBringIntoView ) ); - } - - #endregion - - #region ParentDataGridControl Private Property - - private DataGridControl ParentDataGridControl - { - get - { - var dataGridContext = DataGridControl.GetDataGridContext( this ); - if( dataGridContext == null ) - return null; - - return dataGridContext.DataGridControl; - } - } - - #endregion - - #region PreviewKeyDown and KeyDown handling overrides - - protected override void OnPreviewKeyDown( KeyEventArgs e ) - { - if( e.Handled ) - return; - - switch( e.Key ) - { - case Key.Tab: - this.HandlePreviewTabKey( e ); - break; - - case Key.Home: - this.HandlePreviewHomeKey( e ); - break; - - case Key.End: - this.HandlePreviewEndKey( e ); - break; - - case Key.Left: - this.HandlePreviewLeftKey( e ); - break; - - case Key.Right: - this.HandlePreviewRightKey( e ); - break; - - default: - base.OnPreviewKeyDown( e ); - break; - } - } - - protected virtual void HandlePreviewTabKey( KeyEventArgs e ) - { - if( e.Handled ) - return; - - var dataGridControl = this.ParentDataGridControl; - if( dataGridControl == null ) - return; - - var dataGridContext = dataGridControl.CurrentContext; - if( dataGridContext == null ) - return; - - var container = dataGridContext.GetContainerFromItem( dataGridContext.InternalCurrentItem ); - if( container == null ) - return; - - var tabbingMode = KeyboardNavigation.GetTabNavigation( container ); - if( tabbingMode == KeyboardNavigationMode.None ) - return; - - if( ( Keyboard.Modifiers == ModifierKeys.None ) || ( Keyboard.Modifiers == ModifierKeys.Shift ) ) - { - DataGridItemsHost.BringIntoViewKeyboardFocusedElement(); - - //Force the "inline" relayout of the panel - //This has no effect if the panel do not have to be updated. - this.UpdateLayout(); - } - } - - protected virtual void HandlePreviewLeftKey( KeyEventArgs e ) - { - DataGridItemsHost.BringIntoViewKeyboardFocusedElement(); - this.UpdateLayout(); - } - - protected virtual void HandlePreviewRightKey( KeyEventArgs e ) - { - DataGridItemsHost.BringIntoViewKeyboardFocusedElement(); - this.UpdateLayout(); - } - - protected virtual void HandlePreviewHomeKey( KeyEventArgs e ) - { - } - - protected virtual void HandlePreviewEndKey( KeyEventArgs e ) - { - } - - protected override void OnKeyDown( KeyEventArgs e ) - { - if( e.Handled ) - return; - - switch( e.Key ) - { - case Key.Tab: - this.HandleTabKey( e ); - break; - - case Key.Home: - this.HandleHomeKey( e ); - break; - - case Key.End: - this.HandleEndKey( e ); - break; - - case Key.Left: - this.HandleLeftKey( e ); - break; - - case Key.Right: - this.HandleRightKey( e ); - break; - - default: - base.OnKeyDown( e ); - break; - } - } - - protected virtual void HandleTabKey( KeyEventArgs e ) - { - if( e.Handled ) - return; - - var dataGridControl = this.ParentDataGridControl; - if( dataGridControl == null ) - return; - - var dataGridContext = dataGridControl.CurrentContext; - if( dataGridContext == null ) - return; - - e.Handled = NavigationHelper.HandleTabKey( dataGridControl, dataGridContext, e.OriginalSource as FrameworkElement, e.KeyboardDevice ); - } - - protected virtual void HandleHomeKey( KeyEventArgs e ) - { - if( e.Handled ) - return; - - bool ctrlPressed = ( ( e.KeyboardDevice.Modifiers & ModifierKeys.Control ) == ModifierKeys.Control ); - if( !ctrlPressed ) - return; - - var dataGridControl = this.ParentDataGridControl; - if( ( dataGridControl == null ) || ( dataGridControl.NavigationBehavior != NavigationBehavior.CellOnly ) ) - return; - - NavigationHelper.MoveFocusToFirstVisibleColumn( dataGridControl.CurrentContext ); - - e.Handled = true; - } - - protected virtual void HandleEndKey( KeyEventArgs e ) - { - if( e.Handled ) - return; - - bool ctrlPressed = ( ( e.KeyboardDevice.Modifiers & ModifierKeys.Control ) == ModifierKeys.Control ); - if( !ctrlPressed ) - return; - - var dataGridControl = this.ParentDataGridControl; - if( ( dataGridControl == null ) || ( dataGridControl.NavigationBehavior != NavigationBehavior.CellOnly ) ) - return; - - NavigationHelper.MoveFocusToLastVisibleColumn( dataGridControl.CurrentContext ); - - e.Handled = true; - } - - protected virtual void HandleLeftKey( KeyEventArgs e ) - { - if( e.Handled ) - return; - - var dataGridControl = this.ParentDataGridControl; - if( dataGridControl == null ) - return; - - e.Handled = NavigationHelper.MoveFocusLeft( dataGridControl.CurrentContext ); - } - - protected virtual void HandleRightKey( KeyEventArgs e ) - { - if( e.Handled ) - return; - - var dataGridControl = this.ParentDataGridControl; - if( dataGridControl == null ) - return; - - e.Handled = NavigationHelper.MoveFocusRight( dataGridControl.CurrentContext ); - } - - #endregion - - #region BringIntoView Methods - - private void OnRequestBringIntoView( object sender, RequestBringIntoViewEventArgs e ) - { - if( e.Handled ) - return; - - Debug.Assert( this == sender ); - - var dataGridControl = this.ParentDataGridControl; - if( dataGridControl == null ) - return; - - // Prevent a BringIntoView to be requested twice when setting the focus on a cell. - if( dataGridControl.SettingFocusOnCell ) - { - e.Handled = true; - return; - } - - // Let the ScrollViewer handle this if the grid isn't virtualized. - var scrollViewer = TreeHelper.FindParent( this ); - if( ( scrollViewer == null ) || !scrollViewer.CanContentScroll ) - return; - - var targetVisual = e.TargetObject as Visual; - if( targetVisual == null ) - return; - - // Let the ScrollViewer handle this if the target is the container (i.e. HeaderFooterItem). - var container = this.GetContainerFromElement( targetVisual ); - if( ( container == null ) || ( container == targetVisual ) ) - return; - - Debug.Assert( this.Children.Contains( container ) ); - - e.Handled = true; - - var targetRect = e.TargetRect; - if( targetRect.IsEmpty ) - { - var uiElement = TreeHelper.FindParent( targetVisual, true ); - - // If we have a container, we surely have a UIElement. - Debug.Assert( uiElement != null ); - - targetVisual = uiElement; - targetRect = new Rect( 0d, 0d, Math.Min( uiElement.RenderSize.Width, scrollViewer.ViewportWidth ), 0d ); - } - - var area = targetVisual.TransformToAncestor( container ).TransformBounds( targetRect ); - - if( area.Left < scrollViewer.HorizontalOffset ) - { - scrollViewer.ScrollToHorizontalOffset( area.Left ); - } - else if( area.Right > scrollViewer.HorizontalOffset + scrollViewer.ViewportWidth ) - { - scrollViewer.ScrollToHorizontalOffset( Math.Min( area.Left, ( area.Right - scrollViewer.ViewportWidth ) ) ); - } - } - - #endregion - - protected override Size ArrangeOverride( Size arrangeSize ) - { - Size finalSize = base.ArrangeOverride( arrangeSize ); - - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - DataGridControl dataGridControl = ( dataGridContext != null ) - ? dataGridContext.DataGridControl - : null; - - RowSelectorPane rowSelectorPane = null; - - // dataGridControl can be null in design-time - if( dataGridControl != null ) - { - TableViewScrollViewer scrollViewer = dataGridControl.ScrollViewer as TableViewScrollViewer; - rowSelectorPane = ( scrollViewer != null ) ? scrollViewer.RowSelectorPane : null; - } - - if( rowSelectorPane == null ) - return finalSize; - - Visibility rowSelectorPaneVisibility = ( Visibility )rowSelectorPane.GetValue( RowSelectorPane.VisibilityProperty ); - - if( rowSelectorPaneVisibility != Visibility.Visible ) - return finalSize; - - foreach( UIElement child in this.InternalChildren ) - { - Vector offset = VisualTreeHelper.GetOffset( child ); - Size desiredSize = child.DesiredSize; - - rowSelectorPane.SetRowSelectorPosition( child, new Rect( offset.X, offset.Y, desiredSize.Width, desiredSize.Height ), this ); - } - - return finalSize; - } - - protected override Size MeasureOverride( Size availableSize ) - { - Size restrictedMeasureSize; - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - if( this.Orientation == Orientation.Vertical ) - { - restrictedMeasureSize = new Size( availableSize.Width, double.PositiveInfinity ); - - if( availableSize.Width != Double.PositiveInfinity ) - dataGridContext.FixedHeaderFooterViewPortSize = restrictedMeasureSize; - } - else - { - restrictedMeasureSize = new Size( double.PositiveInfinity, availableSize.Height ); - - if( availableSize.Height != Double.PositiveInfinity ) - dataGridContext.FixedHeaderFooterViewPortSize = restrictedMeasureSize; - } - - foreach( UIElement child in this.Children ) - { - if( ( child is HeaderFooterItem ) && ( typeof( Row ).IsAssignableFrom( ( ( HeaderFooterItem )child ).VisualRootElementType ) ) ) - { - dataGridContext.ColumnStretchingManager.ColumnStretchingCalculated = false; - - // Calling Measure with the Viewport's width will have the effect of - // distributing the extra space (see FixedCellPanel's MeasureOverride). - // Eventually, the FixedCellPanel will receive an adjusted viewport - // width (where GroupLevelIndicator's width et al will be substracted). - child.Measure( restrictedMeasureSize ); - - if( dataGridContext.ColumnStretchingManager.ColumnStretchingCalculated ) - break; - } - } - - return base.MeasureOverride( availableSize ); - } - - private UIElement GetContainerFromElement( DependencyObject element ) - { - if( element == null ) - return null; - - var uiElement = TreeHelper.FindParent( element, true ); - if( uiElement == null ) - return null; - - if( this.Children.Contains( uiElement ) ) - return uiElement; - - foreach( UIElement container in this.Children ) - { - if( container.IsAncestorOf( uiElement ) ) - return container; - } - - return null; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TableViewItemsHost.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TableViewItemsHost.cs deleted file mode 100644 index 6b70fb7b..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TableViewItemsHost.cs +++ /dev/null @@ -1,3005 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Threading; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Controls.Primitives; -using System.Windows.Input; -using System.Windows.Media; -using Xceed.Utils.Collections; -using Xceed.Utils.Wpf; - -namespace Xceed.Wpf.DataGrid.Views -{ - public class TableViewItemsHost : DataGridItemsHost, IScrollInfo, IDeferableScrollInfoRefresh - { - static TableViewItemsHost() - { - KeyboardNavigation.DirectionalNavigationProperty.OverrideMetadata( - typeof( TableViewItemsHost ), - new FrameworkPropertyMetadata( KeyboardNavigationMode.Local ) ); - - CommandManager.RegisterClassCommandBinding( typeof( TableViewItemsHost ), - new CommandBinding( ComponentCommands.MoveFocusForward, - TableViewItemsHost.MoveFocusForwardExecuted, TableViewItemsHost.MoveFocusForwardCanExecute ) ); - - CommandManager.RegisterClassCommandBinding( typeof( TableViewItemsHost ), - new CommandBinding( ComponentCommands.MoveFocusBack, - TableViewItemsHost.MoveFocusBackExecuted, TableViewItemsHost.MoveFocusBackCanExecute ) ); - - CommandManager.RegisterClassCommandBinding( typeof( TableViewItemsHost ), - new CommandBinding( ComponentCommands.MoveFocusUp, - TableViewItemsHost.MoveFocusUpExecuted, TableViewItemsHost.MoveFocusUpCanExecute ) ); - - CommandManager.RegisterClassCommandBinding( typeof( TableViewItemsHost ), - new CommandBinding( ComponentCommands.MoveFocusDown, - TableViewItemsHost.MoveFocusDownExecuted, TableViewItemsHost.MoveFocusDownCanExecute ) ); - } - - public TableViewItemsHost() - { - this.AddHandler( FrameworkElement.RequestBringIntoViewEvent, new RequestBringIntoViewEventHandler( this.OnRequestBringIntoView ) ); - } - - #region Orientation Property - - [Obsolete( "The Orientation property is obsolete. Only a vertical orientation is supported.", false )] - public static readonly DependencyProperty OrientationProperty = - DependencyProperty.Register( "Orientation", typeof( Orientation ), typeof( TableViewItemsHost ), new UIPropertyMetadata( Orientation.Vertical ) ); - - [Obsolete( "The Orientation property is obsolete. Only a vertical orientation is supported.", false )] - public Orientation Orientation - { - get - { -#pragma warning disable 618 - return ( Orientation )this.GetValue( TableViewItemsHost.OrientationProperty ); -#pragma warning restore 618 - } - set - { -#pragma warning disable 618 - this.SetValue( TableViewItemsHost.OrientationProperty, value ); -#pragma warning restore 618 - } - } - - #endregion - - #region StableScrollingEnabled Property - - [Obsolete( "The StableScrollingEnabled property is obsolete.", false )] - public static readonly DependencyProperty StableScrollingEnabledProperty = - DependencyProperty.Register( "StableScrollingEnabled", typeof( bool ), typeof( TableViewItemsHost ), new UIPropertyMetadata( true ) ); - - [Obsolete( "The StableScrollingEnabled property is obsolete.", false )] - public bool StableScrollingEnabled - { - get - { -#pragma warning disable 618 - return ( bool )this.GetValue( TableViewItemsHost.StableScrollingEnabledProperty ); -#pragma warning restore 618 - } - set - { -#pragma warning disable 618 - this.SetValue( TableViewItemsHost.StableScrollingEnabledProperty, value ); -#pragma warning restore 618 - } - } - - #endregion - - #region StableScrollingProportion Property - - [Obsolete( "The StableScrollingProportion property is obsolete.", false )] - public static readonly DependencyProperty StableScrollingProportionProperty = - DependencyProperty.Register( "StableScrollingProportion", typeof( double ), typeof( TableViewItemsHost ), new UIPropertyMetadata( 0.5d ) ); - - [Obsolete( "The StableScrollingProportion property is obsolete.", false )] - public double StableScrollingProportion - { - get - { -#pragma warning disable 618 - return ( double )this.GetValue( TableViewItemsHost.StableScrollingProportionProperty ); -#pragma warning restore 618 - } - set - { -#pragma warning disable 618 - this.SetValue( TableViewItemsHost.StableScrollingProportionProperty, value ); -#pragma warning restore 618 - } - } - - #endregion - - #region ScrollInfo Property - - internal IScrollInfo ScrollInfo - { - get - { - return ( IScrollInfo )this; - } - } - - #endregion - - #region PreviousTabNavigationMode ( private attached property ) - - private static readonly DependencyProperty PreviousTabNavigationModeProperty = DependencyProperty.RegisterAttached( - "PreviousTabNavigationMode", - typeof( KeyboardNavigationMode ), - typeof( TableViewItemsHost ), - new FrameworkPropertyMetadata( ( KeyboardNavigationMode )KeyboardNavigationMode.None ) ); - - private static KeyboardNavigationMode GetPreviousTabNavigationMode( DependencyObject d ) - { - return ( KeyboardNavigationMode )d.GetValue( TableViewItemsHost.PreviousTabNavigationModeProperty ); - } - - private static void SetPreviousTabNavigationMode( DependencyObject d, KeyboardNavigationMode value ) - { - d.SetValue( TableViewItemsHost.PreviousTabNavigationModeProperty, value ); - } - - #endregion - - #region PreviousDirectionalNavigationMode ( private attached property ) - - private static readonly DependencyProperty PreviousDirectionalNavigationModeProperty = DependencyProperty.RegisterAttached( - "PreviousDirectionalNavigationMode", - typeof( KeyboardNavigationMode ), - typeof( TableViewItemsHost ), - new FrameworkPropertyMetadata( ( KeyboardNavigationMode )KeyboardNavigationMode.None ) ); - - private static KeyboardNavigationMode GetPreviousDirectionalNavigationMode( DependencyObject d ) - { - return ( KeyboardNavigationMode )d.GetValue( TableViewItemsHost.PreviousDirectionalNavigationModeProperty ); - } - - private static void SetPreviousDirectionalNavigationMode( DependencyObject d, KeyboardNavigationMode value ) - { - d.SetValue( TableViewItemsHost.PreviousDirectionalNavigationModeProperty, value ); - } - - #endregion - - #region RowSelectorPane Property - - private RowSelectorPane RowSelectorPane - { - get - { - var scrollViewer = this.ScrollInfo.ScrollOwner as TableViewScrollViewer; - if( scrollViewer == null ) - return null; - - return scrollViewer.RowSelectorPane; - } - } - - private bool IsRowSelectorPaneVisible() - { - var rowSelectorPane = this.RowSelectorPane; - - return ( rowSelectorPane != null ) - && ( rowSelectorPane.Visibility == Visibility.Visible ); - } - - #endregion - - #region Measure/Arrange Methods - - protected override Size MeasureOverride( Size availableSize ) - { - m_cachedContainerDesiredWidth.Clear(); - m_cachedContainerRealDesiredWidth.Clear(); - m_autoWidthCalculatedDataGridContextList.Clear(); - m_lastMeasureAvailableSize = availableSize; - - var generatedPage = this.GeneratePageAndUpdateIScrollInfoValues( availableSize, true ); - - return this.GetNewDesiredSize( generatedPage ); - } - - private void MeasureContainer( UIElement container ) - { - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( container ); - - string dataGridContextName = this.GetDataGridContextName( container, dataGridContext ); - bool containerIsRow = this.ContainerIsRow( container ); - - if( ( !m_autoWidthCalculatedDataGridContextList.Contains( dataGridContextName ) ) - && ( containerIsRow ) ) - { - dataGridContext.ColumnStretchingManager.ColumnStretchingCalculated = false; - - // Calling Measure with the Viewport's width will have the effect of - // distributing the extra space (see FixedCellPanel's MeasureOverride). - // Eventually, the FixedCellPanel will receive an adjusted viewport - // width (where GroupLevelIndicator's width et al will be substracted). - container.Measure( new Size( m_lastMeasureAvailableSize.Width, double.PositiveInfinity ) ); - - if( dataGridContext.ColumnStretchingManager.ColumnStretchingCalculated ) - { - // We only calculate once per detail. - m_autoWidthCalculatedDataGridContextList.Add( dataGridContextName ); - } - } - else - { - // We invalidate the CellsHostPanel of the row and all is parent to ensure the - // size is correctly evaluated when we have some auto stretching column. - container.InvalidateMeasure(); - - var row = Row.FromContainer( container ); - if( row != null ) - { - UIElement itemToInvalidate = row.CellsHostPanel; - - while( ( itemToInvalidate != null ) && ( itemToInvalidate != container ) ) - { - itemToInvalidate.InvalidateMeasure(); - itemToInvalidate = VisualTreeHelper.GetParent( itemToInvalidate ) as UIElement; - } - } - } - - // We always measure the container with infinity so that we'll arrange each container, - // for a DataGridContext, with the maximum needed for that context. - container.Measure( new Size( double.PositiveInfinity, double.PositiveInfinity ) ); - - double desiredSize = container.DesiredSize.Width; - double cachedSize; - - if( m_cachedContainerDesiredWidth.TryGetValue( dataGridContextName, out cachedSize ) ) - { - // Keep the largest size! - if( cachedSize < desiredSize ) - { - m_cachedContainerDesiredWidth[ dataGridContextName ] = desiredSize; - } - } - else - { - // Cache the size for the context. - m_cachedContainerDesiredWidth.Add( dataGridContextName, desiredSize ); - } - - PassiveLayoutDecorator decorator = this.GetPassiveLayoutDecorator( container as HeaderFooterItem ); - if( decorator != null ) - { - desiredSize = decorator.RealDesiredSize.Width; - - if( m_cachedContainerRealDesiredWidth.TryGetValue( dataGridContextName, out cachedSize ) ) - { - // Keep the largest size! - if( cachedSize < desiredSize ) - { - m_cachedContainerRealDesiredWidth[ dataGridContextName ] = desiredSize; - } - } - else - { - // Cache the size for the context. - m_cachedContainerRealDesiredWidth.Add( dataGridContextName, desiredSize ); - } - } - } - - protected override Size ArrangeOverride( Size finalSize ) - { - HashSet layoutedContainers = new HashSet(); - - if( m_lastGeneratedPage != TableViewPage.Empty ) - { - var showRowSelector = this.IsRowSelectorPaneVisible(); - var innerPage = m_lastGeneratedPage.InnerPage; - var startIndex = innerPage.Start; - var endIndex = innerPage.End; - var verticalOffset = 0d; - - foreach( var container in ( from ci in m_layoutedContainers - let realizedIndex = ci.RealizedIndex - where ( realizedIndex >= startIndex ) - && ( realizedIndex <= endIndex ) - select ci.Container ) ) - { - layoutedContainers.Add( container ); - - this.ArrangeContainer( container, -m_horizontalOffset, verticalOffset, showRowSelector ); - - verticalOffset += container.RenderSize.Height; - } - } - - // Hide the containers that are not visible in the viewport. - foreach( var container in this.Children ) - { - if( layoutedContainers.Contains( container ) ) - continue; - - this.ArrangeContainerOutOfView( container ); - } - - CommandManager.InvalidateRequerySuggested(); - - // The call to Mouse.Synchronize must not start dragging rows. - // Update the mouse status to make sure no container has invalid mouse over status. - // Only do this when the mouse is over the panel, to prevent unescessary update when scrolling with thumb. - if( this.IsMouseOver ) - { - var dataGridControl = this.ParentDataGridControl; - if( dataGridControl != null ) - { - using( dataGridControl.InhibitDrag() ) - { - Mouse.Synchronize(); - } - } - } - - m_lastLayoutedPage = m_lastGeneratedPage; - m_indexToBringIntoView = TableViewItemsHost.NullIndex; - - return finalSize; - } - - private void ArrangeContainer( UIElement container, double horizontalOffset, double verticalOffset, bool showRowSelector ) - { - var origin = new Point( horizontalOffset, verticalOffset ); - var dataGridContext = DataGridControl.GetDataGridContext( container ); - var dataGridContextName = this.GetDataGridContextName( container, dataGridContext ); - var containerSize = new Size( this.GetContainerWidth( dataGridContextName ), container.DesiredSize.Height ); - - container.Arrange( new Rect( origin, containerSize ) ); - - this.SetCompensationOffset( dataGridContext, container, containerSize.Width ); - - if( showRowSelector ) - { - this.SetRowSelector( container, origin, containerSize ); - } - } - - private void ArrangeContainerOutOfView( UIElement container ) - { - container.Arrange( TableViewItemsHost.OutOfViewRect ); - - this.FreeRowSelector( container ); - } - - private PassiveLayoutDecorator GetPassiveLayoutDecorator( HeaderFooterItem item ) - { - if( ( item == null ) || ( VisualTreeHelper.GetChildrenCount( item ) == 0 ) ) - return null; - - var child = VisualTreeHelper.GetChild( item, 0 ); - if( child == null ) - return null; - - var decorator = child as PassiveLayoutDecorator; - if( ( decorator == null ) && ( VisualTreeHelper.GetChildrenCount( child ) > 0 ) ) - { - decorator = VisualTreeHelper.GetChild( child, 0 ) as PassiveLayoutDecorator; - } - - return decorator; - } - - private double GetContainerWidth( string dataGridContextName ) - { - double synchronizedWidth = this.GetSynchronizedExtentWidth(); - double desiredWidth = 0; - - bool sizeCached = m_cachedContainerDesiredWidth.TryGetValue( dataGridContextName, out desiredWidth ); - if( !sizeCached ) - { - desiredWidth = synchronizedWidth; - } - - if( string.IsNullOrEmpty( dataGridContextName ) ) // master level - { - //for the master level, I want to consider the Synchronized Extent size as well. - desiredWidth = Math.Max( synchronizedWidth, desiredWidth ); - } - - if( desiredWidth == 0 ) - { - m_cachedContainerRealDesiredWidth.TryGetValue( dataGridContextName, out desiredWidth ); - } - - return desiredWidth; - } - - private double GetSynchronizedExtentWidth() - { - var scrollViewer = this.ScrollInfo.ScrollOwner as DataGridScrollViewer; - if( scrollViewer == null ) - return 0d; - - return scrollViewer.SynchronizedScrollViewersWidth; - } - - private void SetCompensationOffset( DataGridContext dataGridContext, UIElement container, double desiredWidth ) - { - double compensationOffset = Math.Max( - 0, - ( ( m_horizontalOffset + Math.Min( m_viewportWidth, desiredWidth ) ) - desiredWidth ) ); - - TableView.SetCompensationOffset( container, compensationOffset ); - - // Affect the CompensationOffset on the DataGridContext for the TableViewColumnVirtualizationManager - // to bind to this value - TableView.SetCompensationOffset( dataGridContext, compensationOffset ); - } - - private void SetRowSelector( UIElement container, Point translationPoint, Size size ) - { - var rowSelectorPane = this.RowSelectorPane; - if( rowSelectorPane == null ) - return; - - rowSelectorPane.SetRowSelectorPosition( container, new Rect( translationPoint, size ), this ); - } - - private void FreeRowSelector( UIElement container ) - { - var rowSelectorPane = this.RowSelectorPane; - if( rowSelectorPane == null ) - return; - - rowSelectorPane.FreeRowSelector( container ); - } - - private double GetMaxDesiredWidth() - { - double maxDesiredWidth = 0d; - - foreach( var item in m_cachedContainerDesiredWidth ) - { - var desiredWidth = item.Value; - if( desiredWidth == 0 ) - { - m_cachedContainerRealDesiredWidth.TryGetValue( item.Key, out desiredWidth ); - } - - if( desiredWidth > maxDesiredWidth ) - { - maxDesiredWidth = desiredWidth; - } - } - - return maxDesiredWidth; - } - - private Size GetNewDesiredSize( TableViewPage pageInfo ) - { - double desiredHeight; - double availableHeight = m_lastMeasureAvailableSize.Height; - - if( pageInfo == TableViewPage.Empty ) - { - desiredHeight = 0d; - } - // The current generated page displays only a subset of the data source. - else if( pageInfo.InnerPage.Length < this.ScrollInfo.ExtentHeight ) - { - if( double.IsPositiveInfinity( availableHeight ) ) - { - desiredHeight = pageInfo.InnerPage.Size; - } - else - { - desiredHeight = availableHeight; - } - } - // The current generated page displays all containers. - else - { - var pageHeight = pageInfo.OuterPage.Size; - - if( double.IsPositiveInfinity( availableHeight ) ) - { - desiredHeight = pageHeight; - } - else - { - desiredHeight = Math.Min( availableHeight, pageHeight ); - } - } - - return new Size( m_viewportWidth, desiredHeight ); - } - - #endregion - - #region Containers Methods - - private bool ContainerIsRow( UIElement container ) - { - if( container is Row ) - return true; - - var headerFooterItem = container as HeaderFooterItem; - if( headerFooterItem != null ) - return typeof( Row ).IsAssignableFrom( headerFooterItem.VisualRootElementType ); - - return false; - } - - private string GetDataGridContextName( UIElement container, DataGridContext dataGridContext ) - { - return ( dataGridContext.SourceDetailConfiguration != null ) - ? dataGridContext.SourceDetailConfiguration.RelationName - : string.Empty; - } - - private TableViewPage GeneratePage( TableViewStartPageInfo pageInfo, double availableHeight, bool forceMeasure ) - { - // The generator can be null if we're in design mode. - var generator = this.CustomItemContainerGenerator; - if( generator == null ) - return m_lastGeneratedPage; - - var generatePage = ( forceMeasure ) - || ( m_lastGeneratedPage == TableViewPage.Empty ) - || ( m_lastGeneratedPage.InnerPage.Start != pageInfo.Start ) - || ( Math.Abs( m_lastGeneratedPage.ViewportHeight - availableHeight ) < 1d ); - - if( !generatePage ) - return m_lastGeneratedPage; - - var pageGenerator = new TopBottomPageGenerator( this, pageInfo.Start, availableHeight, forceMeasure ); - - return this.GeneratePage( pageGenerator ); - } - - private TableViewPage GeneratePage( TableViewEndPageInfo pageInfo, double availableHeight, bool forceMeasure ) - { - // The generator can be null if we're in design mode. - var generator = this.CustomItemContainerGenerator; - if( generator == null ) - return m_lastGeneratedPage; - - var pageGenerator = new BottomTopPageGenerator( this, pageInfo.End, availableHeight, forceMeasure ); - - return this.GeneratePage( pageGenerator ); - } - - private TableViewPage GeneratePage( PageGenerator pageGenerator ) - { - var pageResult = pageGenerator.Generate( m_layoutedContainers, m_lastGeneratedPage ); - - // Replace the layouted containers. - m_layoutedContainers.Clear(); - m_layoutedContainers.AddRange( pageResult.LayoutedContainers ); - m_layoutedContainers.Sort(); - - m_lastGeneratedPage = pageResult.PageInfo; - - return m_lastGeneratedPage; - } - - private void RecycleContainer( ICustomItemContainerGenerator generator, UIElement element, int realizedIndex, bool clearContainer = true ) - { - if( !clearContainer ) - { - var container = element as IDataGridItemContainer; - if( container != null ) - { - container.IsRecyclingCandidate = true; - } - } - else - { - this.ClearContainer( element ); - } - - if( ( generator != null ) && ( realizedIndex >= 0 ) ) - { - try - { - var position = generator.GeneratorPositionFromIndex( realizedIndex ); - generator.Remove( position, 1 ); - } - catch - { - Debug.Fail( "Unable to remove container for realized index " + realizedIndex ); - } - } - } - - private void CleanRecyclingCandidates() - { - var generator = this.CustomItemContainerGenerator as CustomItemContainerGenerator; - generator.CleanRecyclingCandidates(); - } - - private UIElement GenerateContainer( ICustomItemContainerGenerator generator, int index, bool forceMeasure ) - { - bool isNewlyRealized; - var container = ( UIElement )generator.GenerateNext( out isNewlyRealized ); - if( container == null ) - return null; - - if( isNewlyRealized ) - { - var collection = this.Children; - if( !collection.Contains( container ) ) - { - collection.Add( container ); - } - - this.EnableElementNavigation( container ); - KeyboardNavigation.SetTabIndex( container, index ); - this.PrepareContainer( container ); - this.MeasureContainer( container ); - } - else if( forceMeasure ) - { - this.MeasureContainer( container ); - } - - return container; - } - - private void DisableElementNavigation( UIElement child ) - { - //get previous values and store them on the container (attached) - TableViewItemsHost.SetPreviousDirectionalNavigationMode( child, KeyboardNavigation.GetDirectionalNavigation( child ) ); - TableViewItemsHost.SetPreviousTabNavigationMode( child, KeyboardNavigation.GetTabNavigation( child ) ); - - KeyboardNavigation.SetDirectionalNavigation( child, KeyboardNavigationMode.None ); - KeyboardNavigation.SetTabNavigation( child, KeyboardNavigationMode.None ); - } - - private void EnableElementNavigation( UIElement child ) - { - //checking only one of the 2 properties... This is because they are set together. - if( child.ReadLocalValue( TableViewItemsHost.PreviousDirectionalNavigationModeProperty ) != DependencyProperty.UnsetValue ) - { - KeyboardNavigation.SetDirectionalNavigation( child, TableViewItemsHost.GetPreviousDirectionalNavigationMode( child ) ); - KeyboardNavigation.SetTabNavigation( child, TableViewItemsHost.GetPreviousTabNavigationMode( child ) ); - } - //If unset, then nothing to do in this method! - } - - private void PrepareContainer( UIElement container ) - { - container.ClearValue( UIElement.VisibilityProperty ); - - var dataItemStore = Xceed.Wpf.DataGrid.CustomItemContainerGenerator.GetDataItemProperty( container ); - if( ( dataItemStore == null ) || dataItemStore.IsEmpty ) - return; - - var dataItem = dataItemStore.Data; - if( dataItem == null ) - return; - - // Prepare the container. - this.ParentDataGridControl.PrepareItemContainer( container, dataItem ); - } - - private void ClearContainer( UIElement container ) - { - this.DisableElementNavigation( container ); - this.FreeRowSelector( container ); - - container.Visibility = Visibility.Collapsed; - - // The call to DataGridControl.ClearItemContainer will be done by the CustomItemContainerGenerator. - } - - #endregion - - #region Scrolling Management - - internal void InvalidateScrollInfo() - { - var scrollOwner = this.ScrollInfo.ScrollOwner; - if( scrollOwner == null ) - return; - - scrollOwner.InvalidateScrollInfo(); - } - - private void GeneratePageAndUpdateIScrollInfoValues() - { - if( this.CachedRootDataGridContext != null ) - { - var generatedPage = this.GeneratePageAndUpdateIScrollInfoValues( m_lastMeasureAvailableSize, false ); - var newDesiredSize = this.GetNewDesiredSize( generatedPage ); - - if( newDesiredSize != this.DesiredSize ) - { - this.InvalidateMeasure(); - } - else - { - this.InvalidateArrange(); - } - } - } - - private TableViewPage GeneratePageAndUpdateIScrollInfoValues( Size availableSize, bool forceMeasure ) - { - // We must ensure the VerticalOffset is valid according - // to the actual viewport height in case the VerticalOffset - // is greater than the new viewportHeight. - var scrollInfo = this.ScrollInfo; - - double maxOffset = Math.Max( 0d, scrollInfo.ExtentHeight - 1 ); - double offset = Math.Max( Math.Min( m_verticalOffset, maxOffset ), 0d ); - - if( offset != m_verticalOffset ) - { - this.SetVerticalOffsetCore( offset ); - } - - int verticalOffset = ( int )m_verticalOffset; - TableViewPage generatedPage; - - if( m_indexToBringIntoView >= 0 ) - { - int intOffset = Math.Min( m_indexToBringIntoView, ( int )maxOffset ); - - if( ( m_lastLayoutedPage == TableViewPage.Empty ) || ( intOffset < m_lastLayoutedPage.InnerPage.Start ) ) - { - generatedPage = this.GeneratePage( new TableViewStartPageInfo( intOffset ), availableSize.Height, forceMeasure ); - } - else - { - generatedPage = this.GeneratePage( new TableViewEndPageInfo( intOffset ), availableSize.Height, forceMeasure ); - } - } - else - { - generatedPage = this.GeneratePage( new TableViewStartPageInfo( verticalOffset ), availableSize.Height, forceMeasure ); - } - - // CALCULATE THE EXTENT WIDTH - m_extentWidth = Math.Max( this.GetMaxDesiredWidth(), this.GetSynchronizedExtentWidth() ); - - // CALCULATE THE VIEWPORT WIDTH - m_viewportWidth = Double.IsInfinity( availableSize.Width ) ? m_extentWidth : Math.Min( m_extentWidth, availableSize.Width ); - - if( generatedPage != TableViewPage.Empty ) - { - this.SetVerticalOffsetCore( generatedPage.InnerPage.Start ); - } - - this.InvalidateScrollInfo(); - - return generatedPage; - } - - private void ScrollByHorizontalOffset( double offset ) - { - this.ScrollToHorizontalOffset( this.ScrollInfo.HorizontalOffset + offset ); - } - - private void ScrollToHorizontalOffset( double offset ) - { - IScrollInfo scrollInfo = this.ScrollInfo; - - double maxOffset = Math.Max( scrollInfo.ExtentWidth - scrollInfo.ViewportWidth, 0 ); - offset = Math.Max( offset, 0 ); - offset = Math.Min( offset, maxOffset ); - - if( scrollInfo.HorizontalOffset == offset ) - return; - - m_horizontalOffset = offset; - this.InvalidateArrange(); - this.InvalidateScrollInfo(); - } - - private void ScrollByVerticalOffset( double offset ) - { - this.ScrollToVerticalOffset( this.ScrollInfo.VerticalOffset + offset ); - } - - private void ScrollToVerticalOffset( double offset ) - { - IScrollInfo scrollInfo = this.ScrollInfo; - double maxOffset = Math.Max( scrollInfo.ExtentHeight - 1, 0 ); - offset = Math.Max( offset, 0 ); - offset = Math.Min( offset, maxOffset ); - - if( scrollInfo.VerticalOffset == offset ) - return; - - this.SetVerticalOffsetCore( offset ); - this.InvalidateLayoutFromScrollingHelper(); - } - - private void SetVerticalOffsetCore( double offset ) - { - m_verticalOffset = offset; - } - - private bool SetCurrent( int index, bool changeColumn ) - { - bool isDataRow; - return this.SetCurrent( index, changeColumn, out isDataRow ); - } - - private bool SetCurrent( int index, bool changeColumn, out bool isDataRow ) - { - var generator = this.CustomItemContainerGenerator; - var position = generator.GeneratorPositionFromIndex( index ); - var container = default( UIElement ); - - using( generator.StartAt( position, GeneratorDirection.Forward, true ) ) - { - container = this.GenerateContainer( generator, index, false ); - } - - isDataRow = false; - - if( container != null ) - { - isDataRow = ( container is DataRow ); - - if( m_layoutedContainers.IndexOfContainer( container ) < 0 ) - { - m_layoutedContainers.Add( new LayoutedContainerInfo( index, container ) ); - } - - var dataGridContext = DataGridControl.GetDataGridContext( container ); - var currentContext = dataGridContext.DataGridControl.CurrentContext; - var column = default( ColumnBase ); - - if( changeColumn ) - { - column = dataGridContext.CurrentColumn; - - if( isDataRow ) - { - if( ( currentContext != dataGridContext ) && dataGridContext.AreDetailsFlatten ) - { - column = dataGridContext.GetMatchingColumn( currentContext, currentContext.CurrentColumn ) ?? column; - } - - if( ( column == null ) || ( !column.CanBeCurrentWhenReadOnly && column.ReadOnly ) ) - { - var focusableIndex = NavigationHelper.GetFirstVisibleFocusableColumnIndex( dataGridContext ); - if( focusableIndex >= 0 ) - { - column = dataGridContext.VisibleColumns[ focusableIndex ]; - } - } - } - } - - try - { - if( currentContext != null ) - { - currentContext.EndEdit(); - } - } - catch( DataGridException ) - { - return false; - } - - var containerIndex = generator.GetRealizedIndexForContainer( container ); - if( containerIndex >= 0 ) - { - if( dataGridContext.DataGridControl.SetFocusHelper( container, column, true, true ) ) - { - generator.SetCurrentIndex( containerIndex ); - return true; - } - } - } - - return false; - } - - #endregion - - #region BringIntoView Methods - - private void OnRequestBringIntoView( object sender, RequestBringIntoViewEventArgs e ) - { - TableViewItemsHost.ProcessRequestBringIntoView( this, - Orientation.Vertical, - 0.5, // Default StableScrollingProportion - e ); - } - - private bool FocusContainerOrPreviousFocusable( UIElement focusedContainer, bool changeColumn ) - { - int firstIndex = 0; - int focusedIndex = this.CustomItemContainerGenerator.GetRealizedIndexForContainer( focusedContainer ); - int desiredIndex = focusedIndex - 1; - - System.Diagnostics.Debug.Assert( focusedIndex > -1, "How come the realized index is -1?!?" ); - - bool currentChanged = false; - - if( desiredIndex != focusedIndex ) - { - DataGridControl dataGridControl = this.ParentDataGridControl; - int cannotFocusCount = 0; - - // We want to find the first element that can receive focus upward. - while( ( desiredIndex >= 0 ) && ( !currentChanged ) ) - { - bool isDataRow; - currentChanged = this.SetCurrent( desiredIndex, changeColumn, out isDataRow ); - - if( !currentChanged ) - { - if( dataGridControl.HasValidationError ) - return false; - - if( isDataRow ) - { - cannotFocusCount++; - - if( cannotFocusCount > TableViewItemsHost.MaxDataRowFailFocusCount ) - return false; - } - } - - // We succeded in changing the current. - if( currentChanged ) - break; - - // We already are at the first index and still not focused on a new container. - if( desiredIndex == firstIndex ) - { - //Let's keep the focus on the last focused container. - currentChanged = this.SetCurrent( focusedIndex, changeColumn, out isDataRow ); - break; - } - - desiredIndex--; - } - - if( m_lastGeneratedPage != TableViewPage.Empty ) - { - // We will use MoveFocus if the focused index is currently in view. - if( ( !currentChanged ) && ( focusedIndex >= m_lastGeneratedPage.InnerPage.Start ) && ( focusedIndex <= m_lastGeneratedPage.InnerPage.End ) ) - { - currentChanged = this.MoveFocus( new TraversalRequest( FocusNavigationDirection.Up ) ); - } - } - } - - return currentChanged; - } - - private bool FocusIndexOrPreviousFocusable( int desiredIndex, int minimumIndex, bool changeColumn ) - { - bool currentChanged = false; - DataGridControl dataGridControl = this.ParentDataGridControl; - int cannotFocusCount = 0; - - // We want to find the first element that can receive focus upward. - while( ( desiredIndex >= 0 ) && ( !currentChanged ) ) - { - bool isDataRow; - currentChanged = this.SetCurrent( desiredIndex, changeColumn, out isDataRow ); - - if( !currentChanged ) - { - if( dataGridControl.HasValidationError ) - return false; - - if( isDataRow ) - { - cannotFocusCount++; - - if( cannotFocusCount > TableViewItemsHost.MaxDataRowFailFocusCount ) - return false; - } - } - - // We succeded in changing the current or we're already at the first index? Then nothing we can do. - if( ( currentChanged ) || ( desiredIndex == minimumIndex ) ) - break; - - desiredIndex--; - } - - return currentChanged; - } - - private bool FocusContainerOrNextFocusable( UIElement focusedContainer, bool changeColumn ) - { - int lastIndex = this.CustomItemContainerGenerator.ItemCount - 1; - int focusedIndex = this.CustomItemContainerGenerator.GetRealizedIndexForContainer( focusedContainer ); - int desiredIndex = focusedIndex + 1; - - System.Diagnostics.Debug.Assert( focusedIndex > -1, "How come the realized index is -1?!?" ); - - bool currentChanged = false; - - if( desiredIndex != focusedIndex ) - { - DataGridControl dataGridControl = this.ParentDataGridControl; - int cannotFocusCount = 0; - - // We want to find the first element that can receive focus downward. - while( ( desiredIndex <= lastIndex ) && ( !currentChanged ) ) - { - bool isDataRow; - currentChanged = this.SetCurrent( desiredIndex, changeColumn, out isDataRow ); - - if( !currentChanged ) - { - if( dataGridControl.HasValidationError ) - return false; - - if( isDataRow ) - { - cannotFocusCount++; - - if( cannotFocusCount > TableViewItemsHost.MaxDataRowFailFocusCount ) - return false; - } - } - - // We succeded in changing the current. - if( currentChanged ) - break; - - // We already are at the last index and still not focused on a new container. - if( desiredIndex == lastIndex ) - { - //Let's keep the focus on the last focused container. - currentChanged = this.SetCurrent( focusedIndex, changeColumn, out isDataRow ); - } - - desiredIndex++; - } - - if( m_lastGeneratedPage != TableViewPage.Empty ) - { - // We will use MoveFocus if the focused index is currently in view. - if( ( !currentChanged ) && ( focusedIndex >= m_lastGeneratedPage.InnerPage.Start ) && ( focusedIndex <= m_lastGeneratedPage.InnerPage.End ) ) - { - currentChanged = this.MoveFocus( new TraversalRequest( FocusNavigationDirection.Down ) ); - } - } - } - - return currentChanged; - } - - private bool FocusIndexOrNextFocusable( int desiredIndex, int maximumIndex, bool changeColumn ) - { - bool currentChanged = false; - DataGridControl dataGridControl = this.ParentDataGridControl; - int cannotFocusCount = 0; - - // We want to find the first element that can receive focus downward. - while( ( desiredIndex <= maximumIndex ) && ( !currentChanged ) ) - { - bool isDataRow; - currentChanged = this.SetCurrent( desiredIndex, changeColumn, out isDataRow ); - - if( !currentChanged ) - { - if( dataGridControl.HasValidationError ) - return false; - - if( isDataRow ) - { - cannotFocusCount++; - - if( cannotFocusCount > TableViewItemsHost.MaxDataRowFailFocusCount ) - return false; - } - } - - // We succeded in changing the current or we're already at the first index? Then nothing we can do. - if( ( currentChanged ) || ( desiredIndex == maximumIndex ) ) - break; - - desiredIndex++; - } - - return currentChanged; - } - - #endregion - - #region DataGridItemsHost Overrides - - protected override void OnItemsAdded() - { - // We are calling InvalidateMeasure to regenerate the current - // page and forcing the recycling of out-of-view containers. - this.InvalidateMeasure(); - } - - protected override void OnItemsRemoved( IList containers ) - { - // We are calling InvalidateMeasure to regenerate the current - // page and forcing the recycling of out-of-view containers. - this.InvalidateMeasure(); - } - - protected override void OnItemsReset() - { - // We are calling InvalidateMeasure to regenerate the current - // page and forcing the recycling of out-of-view containers. - this.InvalidateMeasure(); - } - - protected override void OnContainersRemoved( IList removedContainers ) - { - foreach( UIElement container in removedContainers ) - { - this.ClearContainer( container ); - - // Avoid checking if Children already contains the element. No exception will be thrown if the item is not found. - // This ensures to parse all children only one time. - this.Children.Remove( container ); - - int index = m_layoutedContainers.IndexOfContainer( container ); - if( index > -1 ) - { - m_layoutedContainers.RemoveAt( index ); - } - } - } - - protected override void OnRecyclingCandidatesCleaned( IList recyclingCandidates ) - { - foreach( UIElement candidate in recyclingCandidates ) - { - this.ClearContainer( candidate ); - } - } - - #endregion - - #region PreviewKeyDown and KeyDown Handling - - protected override void HandleTabKey( KeyEventArgs e ) - { - if( e.Handled ) - return; - - var dataGridControl = this.ParentDataGridControl; - if( dataGridControl == null ) - return; - - var dataGridContext = dataGridControl.CurrentContext; - if( dataGridContext == null ) - return; - - e.Handled = NavigationHelper.HandleTabKey( dataGridControl, dataGridContext, e.OriginalSource as FrameworkElement, e.KeyboardDevice ); - } - - protected override void HandleLeftKey( KeyEventArgs e ) - { - if( e.Handled ) - return; - - var dataGridControl = this.ParentDataGridControl; - if( dataGridControl == null ) - return; - - e.Handled = NavigationHelper.MoveFocusLeft( dataGridControl.CurrentContext ); - } - - protected override void HandleRightKey( KeyEventArgs e ) - { - if( e.Handled ) - return; - - var dataGridControl = this.ParentDataGridControl; - if( dataGridControl == null ) - return; - - e.Handled = NavigationHelper.MoveFocusRight( dataGridControl.CurrentContext ); - } - - protected override void HandleUpKey( KeyEventArgs e ) - { - if( e.Handled ) - return; - - e.Handled = this.MoveFocusUp(); - } - - protected override void HandleDownKey( KeyEventArgs e ) - { - if( e.Handled ) - return; - - e.Handled = this.MoveFocusDown(); - } - - protected override void HandlePageUpKey( KeyEventArgs e ) - { - if( e.Handled ) - return; - - e.Handled = true; - - DataGridControl dataGridControl = this.ParentDataGridControl; - NavigationBehavior navigationBehavior = dataGridControl.NavigationBehavior; - bool changeCurrentColumn = ( navigationBehavior == NavigationBehavior.CellOnly ); - - if( ( e.KeyboardDevice.Modifiers & ModifierKeys.Control ) == ModifierKeys.Control ) - { - this.MoveToFirstOverallUIElement( changeCurrentColumn ); - return; - } - - UIElement focusedContainer = DataGridItemsHost.GetItemsHostContainerFromElement( this, Keyboard.FocusedElement as DependencyObject ); - - if( ( focusedContainer == null ) || ( navigationBehavior == NavigationBehavior.None ) ) - { - // We just need to scroll one page up. - this.ScrollInfo.ScrollOwner.PageUp(); - return; - } - - int focusedContainerRealizedIndex = this.CustomItemContainerGenerator.GetRealizedIndexForContainer( focusedContainer ); - - if( focusedContainerRealizedIndex == 0 ) - { - this.MoveFocus( new TraversalRequest( FocusNavigationDirection.Up ) ); - } - else - { - this.InvalidateMeasure(); - - var generatedPage = this.GeneratePage( new TableViewEndPageInfo( focusedContainerRealizedIndex ), this.RenderSize.Height, false ); - - if( generatedPage != TableViewPage.Empty ) - { - int initialDesiredIndex = generatedPage.InnerPage.Start; - this.SetVerticalOffsetCore( initialDesiredIndex ); - - if( focusedContainerRealizedIndex != initialDesiredIndex ) - { - int desiredPageUpIndex = initialDesiredIndex; - bool isDataRow = false; - - // SetCurrent on the desired index or down until BEFORE the focused container. - while( ( !dataGridControl.HasValidationError ) && ( !isDataRow ) && ( desiredPageUpIndex < focusedContainerRealizedIndex ) ) - { - if( this.SetCurrent( desiredPageUpIndex, changeCurrentColumn, out isDataRow ) ) - return; - - desiredPageUpIndex++; - } - - if( ( dataGridControl.HasValidationError ) || ( isDataRow ) ) - return; - - // No container were focused while processing indexes from focused to initialDesiredIndex, try SetCurrent on indexes samller than the initial up to 0 - desiredPageUpIndex = initialDesiredIndex - 1; - isDataRow = false; - - while( ( !dataGridControl.HasValidationError ) && ( !isDataRow ) && ( desiredPageUpIndex > 0 ) ) - { - if( this.SetCurrent( desiredPageUpIndex, changeCurrentColumn, out isDataRow ) ) - return; - - desiredPageUpIndex--; - } - - // If not container was successfuly focused, set focus back to the current UIElement. - this.SetCurrent( focusedContainerRealizedIndex, changeCurrentColumn, out isDataRow ); - } - } - } - } - - protected override void HandlePageDownKey( KeyEventArgs e ) - { - if( e.Handled ) - return; - - e.Handled = true; - - DataGridControl dataGridControl = this.ParentDataGridControl; - NavigationBehavior navigationBehavior = dataGridControl.NavigationBehavior; - bool changeCurrentColumn = ( navigationBehavior == NavigationBehavior.CellOnly ); - - if( ( e.KeyboardDevice.Modifiers & ModifierKeys.Control ) == ModifierKeys.Control ) - { - this.MoveToLastOverallUIElement( changeCurrentColumn ); - return; - } - - UIElement focusedContainer = DataGridItemsHost.GetItemsHostContainerFromElement( this, Keyboard.FocusedElement as DependencyObject ); - - // No focused container or no navigation allowed - if( ( focusedContainer == null ) || ( navigationBehavior == NavigationBehavior.None ) ) - { - // We just need to scroll one page down. - this.ScrollInfo.ScrollOwner.PageDown(); - return; - } - - int focusedContainerRealizedIndex = this.CustomItemContainerGenerator.GetRealizedIndexForContainer( focusedContainer ); - int maxIndex = this.CustomItemContainerGenerator.ItemCount - 1; - - if( focusedContainerRealizedIndex == maxIndex ) - { - this.MoveFocus( new TraversalRequest( FocusNavigationDirection.Down ) ); - } - else - { - this.InvalidateMeasure(); - - var generatedPage = this.GeneratePage( new TableViewStartPageInfo( focusedContainerRealizedIndex ), this.RenderSize.Height, false ); - - if( generatedPage != TableViewPage.Empty ) - { - this.SetVerticalOffsetCore( generatedPage.InnerPage.Start ); - int initialDesiredIndex; - - // Last row not totally visible, take the one before the last - if( ( generatedPage.InnerPage.Size > this.RenderSize.Height ) && ( generatedPage.InnerPage.Length > 1 ) ) - { - initialDesiredIndex = generatedPage.InnerPage.End - 1; - } - else - { - initialDesiredIndex = generatedPage.InnerPage.End; - } - - if( focusedContainerRealizedIndex != initialDesiredIndex ) - { - int desiredPageDownIndex = initialDesiredIndex; - bool isDataRow = false; - - // SetCurrent on the desired index or up until BEFORE the focused container. - while( ( !dataGridControl.HasValidationError ) && ( !isDataRow ) && ( desiredPageDownIndex > focusedContainerRealizedIndex ) ) - { - if( this.SetCurrent( desiredPageDownIndex, changeCurrentColumn, out isDataRow ) ) - return; - - desiredPageDownIndex--; - } - - if( ( dataGridControl.HasValidationError ) || ( isDataRow ) ) - return; - - desiredPageDownIndex = initialDesiredIndex + 1; - isDataRow = false; - - // No container were focused while processing indexes from focused to initialDesiredIndex, try SetCurrent on indexes higher than the initial down to maxIndex - while( ( !dataGridControl.HasValidationError ) && ( !isDataRow ) && ( desiredPageDownIndex <= maxIndex ) ) - { - if( this.SetCurrent( desiredPageDownIndex, changeCurrentColumn, out isDataRow ) ) - return; - - desiredPageDownIndex++; - } - - // If not container was successfuly focused, set focus back to the current UIElement. - this.SetCurrent( focusedContainerRealizedIndex, changeCurrentColumn, out isDataRow ); - } - } - } - } - - protected override void HandleHomeKey( KeyEventArgs e ) - { - if( e.Handled ) - return; - - if( ( e.KeyboardDevice.Modifiers & ModifierKeys.Control ) == ModifierKeys.Control ) - { - DataGridControl dataGridControl = this.ParentDataGridControl; - IScrollInfo scrollInfo = this.ScrollInfo; - NavigationBehavior navigationBehavior = dataGridControl.NavigationBehavior; - bool changeCurrentColumn = ( navigationBehavior == NavigationBehavior.CellOnly ); - - if( navigationBehavior != NavigationBehavior.None ) - { - this.MoveToFirstOverallUIElement( changeCurrentColumn ); - - if( navigationBehavior == NavigationBehavior.CellOnly ) - { - this.MoveToFirstVisibleColumn(); - } - } - else - { - scrollInfo.ScrollOwner.ScrollToTop(); - } - - // In all cases, we must scroll to the left end of the panel. - scrollInfo.ScrollOwner.ScrollToLeftEnd(); - } - else - { - // This should be handled by a parent. - return; - } - - e.Handled = true; - } - - protected override void HandleEndKey( KeyEventArgs e ) - { - if( e.Handled ) - return; - - if( ( e.KeyboardDevice.Modifiers & ModifierKeys.Control ) == ModifierKeys.Control ) - { - DataGridControl dataGridControl = this.ParentDataGridControl; - IScrollInfo scrollInfo = this.ScrollInfo; - NavigationBehavior navigationBehavior = dataGridControl.NavigationBehavior; - bool changeCurrentColumn = ( navigationBehavior == NavigationBehavior.CellOnly ); - - if( navigationBehavior != NavigationBehavior.None ) - { - this.MoveToLastOverallUIElement( changeCurrentColumn ); - - if( navigationBehavior == NavigationBehavior.CellOnly ) - { - this.MoveToLastVisibleColumn(); - } - } - else - { - scrollInfo.ScrollOwner.ScrollToBottom(); - } - - // In all cases, we must scroll to the right end of the panel. - scrollInfo.ScrollOwner.ScrollToRightEnd(); - } - else - { - // This should be handled by a parent. - return; - } - - e.Handled = true; - } - - private void MoveToFirstOverallUIElement( bool changeCurrentColumn ) - { - // Simply scroll to top. - this.ScrollInfo.ScrollOwner.ScrollToTop(); - - //Try to focus on first UIElement. - if( !this.SetCurrent( 0, changeCurrentColumn ) ) - { - //If not focusable, find the next one downward. - CustomItemContainerGenerator generator = this.CustomItemContainerGenerator as CustomItemContainerGenerator; - this.FocusIndexOrNextFocusable( 1, generator.RealizedContainers.Count - 1, changeCurrentColumn ); - } - } - - private void MoveToLastOverallUIElement( bool changeCurrentColumn ) - { - // Simply scroll to end - this.ScrollInfo.ScrollOwner.ScrollToBottom(); - - CustomItemContainerGenerator generator = this.CustomItemContainerGenerator as CustomItemContainerGenerator; - int lastItemIndex = generator.ItemCount - 1; - - //Try to focus on last UIElement. - if( !this.SetCurrent( lastItemIndex, changeCurrentColumn ) ) - { - //If not focusable, find the next one upward. - int minimumIndex = lastItemIndex - generator.RealizedContainers.Count; - this.FocusIndexOrPreviousFocusable( lastItemIndex, minimumIndex, changeCurrentColumn ); - } - } - - private void MoveToFirstVisibleColumn() - { - DataGridControl dataGridControl = this.ParentDataGridControl; - - if( dataGridControl == null ) - return; - - DataGridContext currentDataGridContext = dataGridControl.CurrentContext; - ReadOnlyColumnCollection visibleColumnsCollection = ( ReadOnlyColumnCollection )currentDataGridContext.VisibleColumns; - - int visibleColumnsCollectionCount = visibleColumnsCollection.Count; - - // The previous SetCurrent will only select the first row. The CurrentColumn - // is left unchanged. We must set the current column to the first one. - - if( ( currentDataGridContext != null ) && ( visibleColumnsCollectionCount > 0 ) ) - { - int firstVisibleFocusableColumnIndex; - bool focusableColumnFound = false; - - Row currentRow = currentDataGridContext.CurrentRow; - - if( currentRow != null ) - { - for( firstVisibleFocusableColumnIndex = 0; firstVisibleFocusableColumnIndex < visibleColumnsCollectionCount; firstVisibleFocusableColumnIndex++ ) - { - if( currentRow.Cells[ visibleColumnsCollection[ firstVisibleFocusableColumnIndex ] ].GetCalculatedCanBeCurrent() ) - { - focusableColumnFound = true; - break; - } - } - - if( focusableColumnFound ) - { - try - { - currentDataGridContext.SetCurrentColumnAndChangeSelection( - currentDataGridContext.VisibleColumns[ firstVisibleFocusableColumnIndex ] ); - } - catch( DataGridException ) - { - // We swallow the exception if it occurs because of a validation error or Cell was read-only or - // any other GridException. - } - } - } - } - } - - private void MoveToLastVisibleColumn() - { - DataGridControl dataGridControl = this.ParentDataGridControl; - - if( dataGridControl == null ) - return; - - DataGridContext currentDataGridContext = dataGridControl.CurrentContext; - ReadOnlyColumnCollection visibleColumnsCollection = ( ReadOnlyColumnCollection )currentDataGridContext.VisibleColumns; - - int visibleColumnsCollectionCount = visibleColumnsCollection.Count; - - // The previous SetCurrent will only select the first row. The CurrentColumn - // is left unchanged. We must set the current column to the last one. - - if( ( visibleColumnsCollection != null ) && ( visibleColumnsCollectionCount > 0 ) ) - { - bool focusableColumnFound = false; - int lastVisibleFocusableColumnIndex; - - Row currentRow = currentDataGridContext.CurrentRow; - - if( currentRow != null ) - { - for( lastVisibleFocusableColumnIndex = visibleColumnsCollectionCount - 1; lastVisibleFocusableColumnIndex >= 0; lastVisibleFocusableColumnIndex-- ) - { - if( currentRow.Cells[ visibleColumnsCollection[ lastVisibleFocusableColumnIndex ] ].GetCalculatedCanBeCurrent() ) - { - focusableColumnFound = true; - break; - } - } - - if( focusableColumnFound ) - { - try - { - currentDataGridContext.SetCurrentColumnAndChangeSelection( - currentDataGridContext.VisibleColumns[ lastVisibleFocusableColumnIndex ] ); - } - catch( DataGridException ) - { - // We swallow the exception if it occurs because of a validation error or Cell was read-only or - // any other GridException. - } - } - } - } - } - - #endregion - - #region ICustomVirtualizingPanel Members - - protected override void BringIntoViewCore( int index ) - { - if( !this.DelayBringIntoView ) - { - if( m_lastGeneratedPage == TableViewPage.Empty ) - return; - - var pageInfo = m_lastGeneratedPage.InnerPage; - if( ( index >= pageInfo.Start ) && ( index < pageInfo.End ) ) - return; - } - - this.InvalidateMeasure(); - - m_indexToBringIntoView = index; - } - - #endregion - - #region IScrollInfo Members - - bool IScrollInfo.CanHorizontallyScroll - { - get; - set; - } - - bool IScrollInfo.CanVerticallyScroll - { - get; - set; - } - - double IScrollInfo.ExtentHeight - { - get - { - return ( this.CachedRootDataGridContext != null ) ? this.CustomItemContainerGenerator.ItemCount : 0; - } - } - - private double m_extentWidth; - double IScrollInfo.ExtentWidth - { - get - { - return m_extentWidth; - } - } - - private double m_horizontalOffset; - double IScrollInfo.HorizontalOffset - { - get - { - return m_horizontalOffset; - } - } - - void IScrollInfo.SetHorizontalOffset( double offset ) - { - if( offset == m_horizontalOffset ) - return; - - this.ScrollToHorizontalOffset( offset ); - } - - private ScrollViewer m_scrollOwner; - ScrollViewer IScrollInfo.ScrollOwner - { - get - { - return m_scrollOwner; - } - set - { - m_scrollOwner = value; - } - } - - private double m_verticalOffset; - double IScrollInfo.VerticalOffset - { - get - { - return m_verticalOffset; - } - } - - void IScrollInfo.SetVerticalOffset( double offset ) - { - if( offset == m_verticalOffset ) - return; - - this.ScrollToVerticalOffset( offset ); - } - - double IScrollInfo.ViewportHeight - { - get - { - if( m_lastGeneratedPage == TableViewPage.Empty ) - return 0d; - - var pageInfo = m_lastGeneratedPage.InnerPage; - var viewportHeight = m_lastGeneratedPage.ViewportHeight; - - if( pageInfo.Size > viewportHeight ) - return Math.Max( 1, pageInfo.Length - 1 ); - - return Math.Max( 1, pageInfo.Length ); - } - } - - private double m_viewportWidth; - double IScrollInfo.ViewportWidth - { - get - { - return m_viewportWidth; - } - } - - void IScrollInfo.LineDown() - { - this.ScrollByVerticalOffset( 1 ); - } - - void IScrollInfo.LineLeft() - { - this.ScrollByHorizontalOffset( ScrollViewerHelper.PixelScrollingCount * -1 ); - } - - void IScrollInfo.LineRight() - { - this.ScrollByHorizontalOffset( ScrollViewerHelper.PixelScrollingCount ); - } - - void IScrollInfo.LineUp() - { - this.ScrollByVerticalOffset( -1 ); - } - - void IScrollInfo.MouseWheelDown() - { - this.ScrollByVerticalOffset( SystemParameters.WheelScrollLines ); - } - - void IScrollInfo.MouseWheelLeft() - { - this.ScrollByHorizontalOffset( SystemParameters.WheelScrollLines * ScrollViewerHelper.PixelScrollingCount * -1 ); - } - - void IScrollInfo.MouseWheelRight() - { - this.ScrollByHorizontalOffset( SystemParameters.WheelScrollLines * ScrollViewerHelper.PixelScrollingCount ); - } - - void IScrollInfo.MouseWheelUp() - { - this.ScrollByVerticalOffset( SystemParameters.WheelScrollLines * -1 ); - } - - void IScrollInfo.PageDown() - { - if( m_lastGeneratedPage == TableViewPage.Empty ) - return; - - var pageInfo = m_lastGeneratedPage.InnerPage; - var viewportHeight = m_lastGeneratedPage.ViewportHeight; - var newOffset = pageInfo.End; - - // We only have one row and it is bigger than the view port. - if( ( pageInfo.Length == 1 ) && ( pageInfo.Size > viewportHeight ) ) - { - int itemCount = ( int )( ( IScrollInfo )this ).ExtentHeight; - - if( newOffset + 1 < itemCount ) - { - newOffset++; - } - } - - this.SetVerticalOffsetCore( newOffset ); - this.GeneratePageAndUpdateIScrollInfoValues(); - } - - void IScrollInfo.PageLeft() - { - this.ScrollByHorizontalOffset( this.ScrollInfo.ViewportWidth * -1 ); - } - - void IScrollInfo.PageRight() - { - this.ScrollByHorizontalOffset( this.ScrollInfo.ViewportWidth ); - } - - void IScrollInfo.PageUp() - { - if( m_lastGeneratedPage == TableViewPage.Empty ) - return; - - var pageInfo = m_lastGeneratedPage.InnerPage; - var viewportHeight = m_lastGeneratedPage.ViewportHeight; - - m_indexToBringIntoView = pageInfo.Start; - - // We only have one row and it is bigger than the view port. - if( ( pageInfo.Length == 1 ) && ( pageInfo.Size > viewportHeight ) ) - { - if( m_indexToBringIntoView > 0 ) - { - m_indexToBringIntoView--; - } - } - - this.GeneratePageAndUpdateIScrollInfoValues(); - } - - Rect IScrollInfo.MakeVisible( Visual visual, Rect rectangle ) - { - UIElement container = DataGridItemsHost.GetItemsHostContainerFromElement( this, visual ); - - if( container != null ) - { - Rect rectangleInItemsHost = visual.TransformToAncestor( this ).TransformBounds( rectangle ); - rectangle = visual.TransformToAncestor( container ).TransformBounds( rectangle ); - - if( ( rectangleInItemsHost.Bottom > this.RenderSize.Height ) || ( rectangleInItemsHost.Top < 0 ) ) - { - // Make sure that the item is vertically visible. - ICustomItemContainerGenerator generator = this.CustomItemContainerGenerator; - - if( generator != null ) - { - int itemIndex = generator.GetRealizedIndexForContainer( container ); - - if( itemIndex != -1 ) - { - // This will make sure to scroll to the right offsets. - ICustomVirtualizingPanel virtualizingPanel = ( ICustomVirtualizingPanel )this; - virtualizingPanel.BringIntoView( itemIndex ); - } - } - } - } - - // Make sure that the item is horizontally visible. - IScrollInfo scrollInfo = this.ScrollInfo; - - if( rectangle.Left < scrollInfo.HorizontalOffset ) - { - this.ScrollToHorizontalOffset( rectangle.Left ); - } - else if( rectangle.Right > scrollInfo.HorizontalOffset + scrollInfo.ViewportWidth ) - { - this.ScrollToHorizontalOffset( - Math.Min( rectangle.Left, ( rectangle.Right - scrollInfo.ViewportWidth ) ) ); - } - - return rectangle; - } - - #endregion - - #region IDeferableScrollInfoRefresh Members - - IDisposable IDeferableScrollInfoRefresh.DeferScrollInfoRefresh( Orientation orientation ) - { - if( orientation == Orientation.Vertical ) - return new LayoutSuspendedHelper( this ); - - return null; - } - - #endregion - - internal static bool ComputedCanScrollHorizontally( FrameworkElement target, DataGridItemsHost itemsHost ) - { - Debug.Assert( target != null ); - - bool retval = true; - - DependencyObject visual = target; - - do - { - retval = TableView.GetCanScrollHorizontally( visual ); - - if( retval ) - { - visual = TreeHelper.GetParent( visual ); - } - } - while( ( visual != null ) && ( visual != itemsHost ) && ( retval ) ); - - return retval; - } - - internal static double GetVisibleDimensionForRequestBringIntoViewTarget( double targetDimension, double targetToItemsHostOffset, double viewportDimension ) - { - // The items left upper corner is in the Viewport - if( targetToItemsHostOffset >= 0 ) - { - // The item is totally visible since its actual dimension is less than the viewport - if( ( targetToItemsHostOffset + targetDimension ) <= viewportDimension ) - { - // This will force the function to "cancel" the BringIntoView - // because the width to BringIntoView will be the viewport - return viewportDimension; - } - else - { - // Item is not totally visible, calculate how much place it occupies in the viewport. - return viewportDimension - targetToItemsHostOffset; - } - } - else - { - // This items left upper corner is at the left side of the viewPort - double itemActualVisibleValue = targetDimension - targetToItemsHostOffset; - - if( itemActualVisibleValue > viewportDimension ) - { - // Limit the value of itemActualVisibleValue to the viewport size (to prevent eventual bugs [even if nothing is visible on the horizon for this]) - itemActualVisibleValue = viewportDimension; - } - - return itemActualVisibleValue; - } - } - - internal static double CorrectBringIntoViewRectFromVisibleDimensionAndAcceptableThreshold( - double actualVisibleDimension, - double acceptableDimensionThreshold, - double targetToItemsHostPosition, - double targetToTemplatedParentDimension, - double itemsHostOffset ) - { - // The visible dimension is greater or equal than the acceptable threshold - if( actualVisibleDimension >= acceptableDimensionThreshold ) - { - return itemsHostOffset - targetToTemplatedParentDimension; - } - else - { - // Calculate the starting point of the rectangle to view. - return Math.Max( 0, targetToItemsHostPosition * -1 ); - } - } - - internal static bool TargetRequiresBringIntoView( double targetToItemsHostPosition, double targetDesiredSizeDimension, double itemsHostRenderSizeDimension ) - { - //If the Offset is negative, then it's sure its not totally visible - if( targetToItemsHostPosition < 0 ) - { - return true; - } - else if( ( targetDesiredSizeDimension < itemsHostRenderSizeDimension ) - && ( ( targetToItemsHostPosition + targetDesiredSizeDimension ) > itemsHostRenderSizeDimension ) ) - { - return true; - } - - return false; - } - - internal static void ProcessRequestBringIntoView( - DataGridItemsHost itemsHost, - Orientation orientation, - double stableScrollingProportion, - RequestBringIntoViewEventArgs e ) - { - IScrollInfo scrollInfo = itemsHost as IScrollInfo; - - if( scrollInfo == null ) - return; - - // Only perform this if we are virtualizing. - // If not, the ScrollViewer will take care of bringing the item into view. - if( ( scrollInfo.ScrollOwner == null ) || ( !scrollInfo.ScrollOwner.CanContentScroll ) ) - return; - - // If we are explicitly setting the focus on a cell, we don't want to bring it into view. - // A bringIntoView would cause the HorizontalOffset to change is not a wanted behavior. - // Therefore, flag the Request as handled and do nothing. - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( itemsHost ); - - DataGridControl dataGridControl = ( dataGridContext != null ) - ? dataGridContext.DataGridControl - : null; - - if( ( dataGridControl != null ) && ( dataGridControl.SettingFocusOnCell ) ) - { - e.Handled = true; - return; - } - - // Only perform this if the object is NOT a Cell and was not passed a specific rectangle. - if( ( e.TargetObject is Cell ) || ( e.TargetRect != Rect.Empty ) ) - return; - - // Before performing calculations, ensure that the element is a FrameworkElement. - FrameworkElement target = e.TargetObject as FrameworkElement; - - if( ( target == null ) || ( !target.IsDescendantOf( itemsHost ) ) ) - return; - - // Mark the routed event as handled, since under even the worst circumstances, - // a new event will be raised. - e.Handled = true; - - // Ensure to get the offset of the target visual element - // according to its Container when it is not directly - // a Container. This is to avoid horizontal scrolling when - // the NavigationBehavior is None and that the CellsHost - // request the focus when there are HierarchicalGroupLevelIndicators - // and/or GroupLevelIndicators present in the Container. - // This extra space must be taken into consideration, not - // only the offset between the target and the ItemsHost. - Point targetToParentContainer = TableViewItemsHost.OriginPoint; - FrameworkElement targetParentContainer = DataGridItemsHost.GetItemsHostContainerFromElement( itemsHost, target ) as FrameworkElement; - - if( ( targetParentContainer != null ) && ( target != targetParentContainer ) ) - { - targetToParentContainer = target.TranslatePoint( TableViewItemsHost.OriginPoint, - targetParentContainer ); - } - - Point targetToItemsHostPosition = target.TranslatePoint( TableViewItemsHost.OriginPoint, itemsHost ); - double acceptableThreshold; - double actualVisibleValue; - - //Calculate the VisibleWidth/Height of the object within the Viewport. - if( orientation == Orientation.Vertical ) - { - acceptableThreshold = scrollInfo.ViewportWidth * stableScrollingProportion; - - actualVisibleValue = TableViewItemsHost.GetVisibleDimensionForRequestBringIntoViewTarget( - target.ActualWidth, - targetToItemsHostPosition.X, - scrollInfo.ViewportWidth ); - } - else - { - acceptableThreshold = scrollInfo.ViewportHeight * stableScrollingProportion; - - actualVisibleValue = TableViewItemsHost.GetVisibleDimensionForRequestBringIntoViewTarget( - target.ActualHeight, - targetToItemsHostPosition.Y, - scrollInfo.ViewportHeight ); - } - - Rect newRect = newRect = new Rect( 0, 0, target.ActualWidth, target.ActualHeight ); - - // After the visible proportion of the object is calculated, compare it with threshold - if( actualVisibleValue < acceptableThreshold ) - { - // The required threshold is not visible, modify the bounds of the rectangle - // to bring the desired threshold. - if( orientation == Orientation.Vertical ) - { - if( targetToItemsHostPosition.X >= 0 ) - { - newRect.Width = Math.Min( acceptableThreshold, target.ActualWidth ); - } - else - { - newRect.X = Math.Max( 0, target.ActualWidth - acceptableThreshold ); - } - } - else - { - if( targetToItemsHostPosition.Y >= 0 ) - { - newRect.Height = Math.Min( acceptableThreshold, target.ActualHeight ); - } - else - { - newRect.Y = Math.Max( 0, target.ActualHeight - acceptableThreshold ); - } - } - - target.BringIntoView( newRect ); - - return; - } - - bool needBringIntoView = false; - - // Determine if the item is totally or partially visible on the main scrolling axis. - if( orientation == Orientation.Vertical ) - { - needBringIntoView = TableViewItemsHost.TargetRequiresBringIntoView( - targetToItemsHostPosition.Y, - target.DesiredSize.Height, - itemsHost.RenderSize.Height ); - } - else - { - needBringIntoView = TableViewItemsHost.TargetRequiresBringIntoView( - targetToItemsHostPosition.X, - target.DesiredSize.Width, - itemsHost.RenderSize.Width ); - } - - // Extra properties that must be verified to conclude - // the container must be put into view or not - if( itemsHost is TableflowViewItemsHost ) - { - // TableflowViewItemsHost must take Clip into consideration - // since this means the container is not fully visible - // and maybe under a Sticky container - needBringIntoView |= ( target.GetValue( UIElement.ClipProperty ) != null ); - - if( !needBringIntoView ) - { - // If the container is sticky, we must ensure all subsequent containers - // wil be correctly layouted and visible. e.g.: the GroupHeaderControl - // hides the 1st group value and the 2nd one is partially visible. - // If the container to bring into view is the sticky GroupHeaderControl, - // the 1st and 2nd group values must be completely visible - needBringIntoView |= TableflowViewItemsHost.GetIsSticky( target ); - } - } - - if( !needBringIntoView ) - return; - - // The goal is to preserve the actual opposed axis scrolling - if( orientation == Orientation.Vertical ) - { - //if the item to be brough into view is part of the elements in a TableView that do no scroll - if( ( dataGridControl != null ) - && ( dataGridControl.GetView() is TableView ) - && ( !TableViewItemsHost.ComputedCanScrollHorizontally( target, itemsHost ) ) ) - { - // Nothing to do since the item can't scroll horizontally, use 0 as newRect.X - // and ensure to use the container as BringIntoView target since it can't - // scroll horizontally - if( targetToParentContainer != null ) - { - target = targetParentContainer; - - // Ensure that the offset to bring into view - // is the HorizontalOffset since it does not - // scroll Horizontally. - newRect.X = scrollInfo.HorizontalOffset; - } - } - else - { - newRect.X = TableViewItemsHost.CorrectBringIntoViewRectFromVisibleDimensionAndAcceptableThreshold( - actualVisibleValue, - acceptableThreshold, - targetToItemsHostPosition.X, - targetToParentContainer.X, - scrollInfo.HorizontalOffset ); - } - - // If the rectangle of the object goes beyond the Viewport - if( newRect.Right > scrollInfo.ViewportWidth ) - { - // Subtract what goes beyond! - newRect.Width = newRect.Width - - ( newRect.Width - scrollInfo.ViewportWidth ) - - Math.Max( targetToItemsHostPosition.X, 0 ); - } - } - else - { - newRect.Y = TableViewItemsHost.CorrectBringIntoViewRectFromVisibleDimensionAndAcceptableThreshold( - actualVisibleValue, - acceptableThreshold, - targetToItemsHostPosition.Y, - targetToParentContainer.Y, - scrollInfo.VerticalOffset ); - - // If the rectangle of the object goes beyond the Viewport - if( newRect.Bottom > scrollInfo.ViewportHeight ) - { - // Subtract what goes beyond! - newRect.Height = newRect.Height - - ( newRect.Height - scrollInfo.ViewportHeight ) - - Math.Max( targetToItemsHostPosition.Y, 0 ); - } - } - - target.BringIntoView( newRect ); - } - - private static double MakeRectVisible( - double rectMinimum, - double rectMaximum, - double rectDimension, - double itemsHostViewport, - double itemsHostOffset, - out bool scrollRequired ) - { - scrollRequired = true; - - // Check if the beginning of the rectangle is before the "offset" - if( rectMinimum < itemsHostOffset ) - { - // Then make the origin of the rectangle visible (independent of dimension) - return rectMinimum; - } - //if the bottom of the rectangle is not visible - else if( rectMaximum > ( itemsHostOffset + itemsHostViewport ) ) - { - // And the rectangle is greater than viewport - if( rectDimension > itemsHostViewport ) - { - // Make the origin of the rectangle visible - return rectMinimum; - } - else - { - //align the bottom of the rectangle at the bottom edge of the viewport. - return rectMaximum - itemsHostViewport; - } - } - - scrollRequired = false; - return 0; - } - - private static void MoveFocusForwardExecuted( object sender, ExecutedRoutedEventArgs e ) - { - var itemsHost = ( TableViewItemsHost )sender; - var dataGridControl = itemsHost.ParentDataGridControl; - if( dataGridControl == null ) - return; - - e.Handled = NavigationHelper.MoveFocusRight( dataGridControl.CurrentContext ); - } - - private static void MoveFocusForwardCanExecute( object sender, CanExecuteRoutedEventArgs e ) - { - e.CanExecute = true; - e.Handled = true; - } - - private static void MoveFocusBackExecuted( object sender, ExecutedRoutedEventArgs e ) - { - var itemsHost = ( TableViewItemsHost )sender; - var dataGridControl = itemsHost.ParentDataGridControl; - if( dataGridControl == null ) - return; - - e.Handled = NavigationHelper.MoveFocusLeft( dataGridControl.CurrentContext ); - } - - private static void MoveFocusBackCanExecute( object sender, CanExecuteRoutedEventArgs e ) - { - e.CanExecute = true; - e.Handled = true; - } - - private static void MoveFocusUpExecuted( object sender, ExecutedRoutedEventArgs e ) - { - e.Handled = ( ( TableViewItemsHost )sender ).MoveFocusUp(); - } - - private static void MoveFocusUpCanExecute( object sender, CanExecuteRoutedEventArgs e ) - { - e.CanExecute = true; - e.Handled = true; - } - - private static void MoveFocusDownExecuted( object sender, ExecutedRoutedEventArgs e ) - { - e.Handled = ( ( TableViewItemsHost )sender ).MoveFocusDown(); - } - - private static void MoveFocusDownCanExecute( object sender, CanExecuteRoutedEventArgs e ) - { - e.CanExecute = true; - e.Handled = true; - } - - private bool MoveFocusUp() - { - DataGridControl dataGridControl = this.ParentDataGridControl; - UIElement focusedContainer = DataGridItemsHost.GetItemsHostContainerFromElement( this, Keyboard.FocusedElement as DependencyObject ); - - NavigationBehavior navigationBehavior = dataGridControl.NavigationBehavior; - bool changeCurrentColumn = ( navigationBehavior == NavigationBehavior.CellOnly ); - - if( ( focusedContainer == null ) || - ( navigationBehavior == NavigationBehavior.None ) ) - { - // We just need to scroll one line up. - this.ScrollInfo.ScrollOwner.LineUp(); - } - else - { - this.FocusContainerOrPreviousFocusable( focusedContainer, changeCurrentColumn ); - } - - return true; - } - - private bool MoveFocusDown() - { - DataGridControl dataGridControl = this.ParentDataGridControl; - UIElement focusedContainer = DataGridItemsHost.GetItemsHostContainerFromElement( this, Keyboard.FocusedElement as DependencyObject ); - - NavigationBehavior navigationBehavior = dataGridControl.NavigationBehavior; - bool changeCurrentColumn = ( navigationBehavior == NavigationBehavior.CellOnly ); - - if( ( focusedContainer == null ) || - ( navigationBehavior == NavigationBehavior.None ) ) - { - // We just need to scroll one line down. - this.ScrollInfo.ScrollOwner.LineDown(); - } - else - { - this.FocusContainerOrNextFocusable( focusedContainer, changeCurrentColumn ); - } - - return true; - } - - private void InvalidateLayoutFromScrollingHelper() - { - if( m_layoutSuspended.IsSet ) - { - m_layoutInvalidatedDuringSuspend = true; - return; - } - - this.GeneratePageAndUpdateIScrollInfoValues(); - } - - private const int MaxDataRowFailFocusCount = 50; - private const int NullIndex = int.MinValue; - - private static readonly Point OriginPoint = new Point( 0d, 0d ); - private static readonly Size EmptySize = new Size( 0d, 0d ); - private static readonly Rect OutOfViewRect = new Rect( new Point( -999999d, -999999d ), TableViewItemsHost.EmptySize ); - - private readonly LayoutedContainerInfoList m_layoutedContainers = new LayoutedContainerInfoList(); - - private TableViewPage m_lastGeneratedPage = TableViewPage.Empty; - private TableViewPage m_lastLayoutedPage = TableViewPage.Empty; - - private readonly Dictionary m_cachedContainerDesiredWidth = new Dictionary(); - private readonly Dictionary m_cachedContainerRealDesiredWidth = new Dictionary(); - - private readonly HashSet m_autoWidthCalculatedDataGridContextList = new HashSet(); - - private Size m_lastMeasureAvailableSize = TableViewItemsHost.EmptySize; - private int m_indexToBringIntoView = TableViewItemsHost.NullIndex; - - private AutoResetFlag m_layoutSuspended = AutoResetFlagFactory.Create( false ); - private bool m_layoutInvalidatedDuringSuspend; - - #region LayoutSuspendedHelper Private Class - - private sealed class LayoutSuspendedHelper : IDisposable - { - public LayoutSuspendedHelper( TableViewItemsHost owner ) - { - if( owner == null ) - throw new ArgumentNullException( "owner" ); - - m_owner = owner; - m_disposable = owner.m_layoutSuspended.Set(); - } - - void IDisposable.Dispose() - { - this.Dispose( true ); - GC.SuppressFinalize( this ); - } - - private void Dispose( bool disposing ) - { - var owner = Interlocked.Exchange( ref m_owner, null ); - if( owner == null ) - return; - - if( m_disposable != null ) - { - m_disposable.Dispose(); - m_disposable = null; - } - - if( !owner.m_layoutSuspended.IsSet && owner.m_layoutInvalidatedDuringSuspend ) - { - owner.InvalidateMeasure(); - } - } - - ~LayoutSuspendedHelper() - { - this.Dispose( false ); - } - - private TableViewItemsHost m_owner; - private IDisposable m_disposable; - } - - #endregion - - #region TableViewPageResult Private Class - - private sealed class TableViewPageResult - { - internal TableViewPageResult( TableViewPage pageInfo, IEnumerable layoutedContainers ) - { - if( pageInfo == null ) - throw new ArgumentNullException( "pageInfo" ); - - if( layoutedContainers == null ) - throw new ArgumentNullException( "layoutedContainers" ); - - m_pageInfo = pageInfo; - m_layoutedContainers = layoutedContainers; - } - - internal TableViewPage PageInfo - { - get - { - return m_pageInfo; - } - } - - internal IEnumerable LayoutedContainers - { - get - { - return m_layoutedContainers; - } - } - - private readonly TableViewPage m_pageInfo; - private readonly IEnumerable m_layoutedContainers; - } - - #endregion - - #region Range Private Struct - - private struct Range - { - internal static readonly Range Empty = new Range( true ); - - private Range( bool isEmpty ) - { - m_start = -1; - m_end = -1; - } - - internal Range( int start, int end ) - { - if( start < 0 ) - throw new ArgumentException( "The value must be greater than or equal to zero.", "start" ); - - if( end < 0 ) - throw new ArgumentException( "The value must be greater than or equal to zero.", "end" ); - - if( start > end ) - throw new ArgumentException( "The start value must be lesser than or equal to the end value.", "start" ); - - m_start = start; - m_end = end; - } - - public int Start - { - get - { - if( m_start < 0 ) - return 0; - - return m_start; - } - } - - public int End - { - get - { - if( m_end < 0 ) - return 0; - - return m_end; - } - } - - public bool IsEmpty - { - get - { - return ( m_start < 0 ); - } - } - - public int Length - { - get - { - if( this.IsEmpty ) - return 0; - - return ( m_end - m_start + 1 ); - } - } - - public static bool operator ==( Range x, Range y ) - { - return object.Equals( x, y ); - } - - public static bool operator !=( Range x, Range y ) - { - return !( x == y ); - } - - public override int GetHashCode() - { - return this.Start ^ this.End; - } - - public override bool Equals( object obj ) - { - if( !( obj is Range ) ) - return false; - - var range = ( Range )obj; - - if( this.IsEmpty ) - return range.IsEmpty; - - return ( !range.IsEmpty ) - && ( range.m_start == m_start ) - && ( range.m_end == m_end ); - } - - internal Range SetStart( int value ) - { - if( this.IsEmpty ) - throw new InvalidOperationException(); - - if( value > m_end ) - return Range.Empty; - - return new Range( value, m_end ); - } - - internal Range SetEnd( int value ) - { - if( this.IsEmpty ) - throw new InvalidOperationException(); - - if( value < m_start ) - return Range.Empty; - - return new Range( m_start, value ); - } - - private readonly int m_start; - private readonly int m_end; - } - - #endregion - - #region PageGenerator Private Class - - private abstract class PageGenerator - { - protected PageGenerator( TableViewItemsHost itemsHost, int startIndex, double availableHeight, bool forceMeasure ) - { - if( itemsHost == null ) - throw new ArgumentNullException( "itemsHost" ); - - m_itemsHost = itemsHost; - m_startIndex = startIndex; - m_availableHeight = availableHeight; - m_forceMeasure = forceMeasure; - } - - protected abstract TableViewPage GenerateContainers( int startIndex, int itemCount, double availableHeight, double extendedHeight, bool fillLastPage ); - - protected LayoutedContainerInfo CreateContainer( int realizedIndex ) - { - if( ( realizedIndex < 0 ) || ( realizedIndex >= m_itemCount ) ) - return null; - - this.RecycleCandidates( realizedIndex ); - - var position = m_generator.GeneratorPositionFromIndex( realizedIndex ); - using( m_generator.StartAt( position, GeneratorDirection.Forward, true ) ) - { - var container = m_itemsHost.GenerateContainer( m_generator, realizedIndex, m_forceMeasure ); - if( container == null ) - return null; - - m_remainingViewportHeight -= container.DesiredSize.Height; - m_nonRecyclableContainers.Remove( container ); - m_oldLayoutedContainers.Remove( container ); - - var containerInfo = new LayoutedContainerInfo( realizedIndex, container ); - m_newLayoutedContainers.Add( containerInfo ); - - return containerInfo; - } - } - - internal TableViewPageResult Generate( IEnumerable layoutedContainers, TableViewPage lastGeneratedPage ) - { - m_generator = m_itemsHost.CustomItemContainerGenerator; - Debug.Assert( m_generator != null ); - - m_generator.IsRecyclingEnabled = true; - - // We call ItemCount before any other call to make sure the internal state of the generator is up-to-date. - m_itemCount = m_generator.ItemCount; - - var lastGeneratedPageSize = lastGeneratedPage.OuterPage.Length; - m_nonRecyclableContainers = new HashSet(); - m_oldLayoutedContainers = new Dictionary( lastGeneratedPageSize ); - m_newLayoutedContainers = null; - - // Figure out the realized index of all currently layouted containers. - foreach( var container in layoutedContainers.Select( item => item.Container ) ) - { - var newRealizedIndex = m_generator.GetRealizedIndexForContainer( container ); - - if( !m_itemsHost.CanRecycleContainer( container ) ) - { - m_nonRecyclableContainers.Add( container ); - m_oldLayoutedContainers.Add( container, newRealizedIndex ); - } - else if( newRealizedIndex >= 0 ) - { - m_oldLayoutedContainers.Add( container, newRealizedIndex ); - } - // The container is lost, recycle it. - else - { - m_itemsHost.RecycleContainer( m_generator, container, newRealizedIndex ); - } - } - - TableViewPageResult result; - - if( m_itemCount > 0 ) - { - m_newLayoutedContainers = new List( lastGeneratedPageSize ); - - var extendedHeight = Math.Max( m_availableHeight, lastGeneratedPage.ViewportHeight ); - - this.PrepareRecycleCandidates( extendedHeight ); - - var dataGridContext = DataGridControl.GetDataGridContext( m_itemsHost ); - var fillLastPage = ( dataGridContext != null ) && TableView.GetAutoFillLastPage( dataGridContext ); - var pageInfo = this.GenerateContainers( m_startIndex, m_itemCount, m_availableHeight, extendedHeight, fillLastPage ); - - // Keep active the containers that cannot be recycled by putting them in the layouted containers collection. - foreach( var entry in m_nonRecyclableContainers ) - { - int realizedIndex; - if( !m_oldLayoutedContainers.TryGetValue( entry, out realizedIndex ) ) - continue; - - m_oldLayoutedContainers.Remove( entry ); - m_newLayoutedContainers.Add( new LayoutedContainerInfo( realizedIndex, entry ) ); - } - - result = new TableViewPageResult( pageInfo, m_newLayoutedContainers ); - } - else - { - result = new TableViewPageResult( TableViewPage.Empty, Enumerable.Empty() ); - } - - // Recycle the containers that have not been reused. - foreach( var entry in m_oldLayoutedContainers ) - { - m_itemsHost.RecycleContainer( m_generator, entry.Key, entry.Value ); - } - - m_itemsHost.CleanRecyclingCandidates(); - - return result; - } - - private void PrepareRecycleCandidates( double extendedHeight ) - { - m_recycleCandidates = ( from entry in m_oldLayoutedContainers - orderby entry.Value - select entry.Key ).ToArray(); - - var count = m_recycleCandidates.Length; - - m_recycleCandidatesRealizedIndex = new int[ count ]; - m_recycleCandidatesHeight = new DoubleFenwickTree( count ); - - for( int i = 0; i < count; i++ ) - { - var container = m_recycleCandidates[ i ]; - - m_recycleCandidatesRealizedIndex[ i ] = m_oldLayoutedContainers[ container ]; - m_recycleCandidatesHeight[ i ] = container.DesiredSize.Height; - } - - if( count > 0 ) - { - m_lowerRecycleCandidatesRange = new Range( 0, count - 1 ); - m_upperRecycleCandidatesRange = new Range( 0, count - 1 ); - } - else - { - m_lowerRecycleCandidatesRange = Range.Empty; - m_upperRecycleCandidatesRange = Range.Empty; - } - - m_remainingViewportHeight = extendedHeight; - } - - private void RecycleCandidates( int realizedIndex ) - { - if( m_lowerRecycleCandidatesRange.IsEmpty && m_upperRecycleCandidatesRange.IsEmpty ) - return; - - var pivot = Array.BinarySearch( m_recycleCandidatesRealizedIndex, realizedIndex ); - if( pivot < 0 ) - { - pivot = ~pivot; - - if( !m_upperRecycleCandidatesRange.IsEmpty && ( m_upperRecycleCandidatesRange.Start < pivot ) ) - { - m_upperRecycleCandidatesRange = m_upperRecycleCandidatesRange.SetStart( pivot ); - } - } - else - { - if( !m_upperRecycleCandidatesRange.IsEmpty && ( m_upperRecycleCandidatesRange.Start <= pivot ) ) - { - m_upperRecycleCandidatesRange = m_upperRecycleCandidatesRange.SetStart( pivot + 1 ); - } - } - - if( !m_lowerRecycleCandidatesRange.IsEmpty && ( m_lowerRecycleCandidatesRange.End >= pivot ) ) - { - m_lowerRecycleCandidatesRange = m_lowerRecycleCandidatesRange.SetEnd( pivot - 1 ); - } - - while( !m_lowerRecycleCandidatesRange.IsEmpty ) - { - var index = m_lowerRecycleCandidatesRange.Start; - var container = m_recycleCandidates[ index ]; - - // The container may no longer be a candidate if it has been reused already. - if( m_oldLayoutedContainers.ContainsKey( container ) ) - { - var distance = ( m_lowerRecycleCandidatesRange.Length > 1 ) - ? m_recycleCandidatesHeight.GetRunningSum( index + 1, m_lowerRecycleCandidatesRange.End ) - : 0d; - - if( distance < m_remainingViewportHeight ) - break; - - this.RecycleCandidate( container ); - } - - m_lowerRecycleCandidatesRange = m_lowerRecycleCandidatesRange.SetStart( index + 1 ); - } - - while( !m_upperRecycleCandidatesRange.IsEmpty ) - { - var index = m_upperRecycleCandidatesRange.End; - var container = m_recycleCandidates[ index ]; - - // The container may no longer be a candidate if it has been reused already. - if( m_oldLayoutedContainers.ContainsKey( container ) ) - { - var distance = ( m_upperRecycleCandidatesRange.Length > 1 ) - ? m_recycleCandidatesHeight.GetRunningSum( m_upperRecycleCandidatesRange.Start, index - 1 ) - : 0d; - - if( distance < m_remainingViewportHeight ) - break; - - this.RecycleCandidate( container ); - } - - m_upperRecycleCandidatesRange = m_upperRecycleCandidatesRange.SetEnd( index - 1 ); - } - } - - private void RecycleCandidate( UIElement container ) - { - //Do not recycle the focused container - if( m_nonRecyclableContainers.Contains( container ) ) - return; - - int realizedIndex; - if( !m_oldLayoutedContainers.TryGetValue( container, out realizedIndex ) ) - return; - - m_oldLayoutedContainers.Remove( container ); - m_itemsHost.RecycleContainer( m_generator, container, realizedIndex, false ); - } - - private readonly TableViewItemsHost m_itemsHost; - private readonly int m_startIndex; - private readonly double m_availableHeight; - private readonly bool m_forceMeasure; - - private ICustomItemContainerGenerator m_generator; - private int m_itemCount; - private HashSet m_nonRecyclableContainers; - private Dictionary m_oldLayoutedContainers; - private List m_newLayoutedContainers; - - private UIElement[] m_recycleCandidates; - private int[] m_recycleCandidatesRealizedIndex; - private DoubleFenwickTree m_recycleCandidatesHeight; - private Range m_lowerRecycleCandidatesRange; - private Range m_upperRecycleCandidatesRange; - private double m_remainingViewportHeight; - } - - #endregion - - #region TopBottomPageGenerator Private Class - - private sealed class TopBottomPageGenerator : PageGenerator - { - internal TopBottomPageGenerator( TableViewItemsHost itemsHost, int startIndex, double availableHeight, bool forceMeasure ) - : base( itemsHost, startIndex, availableHeight, forceMeasure ) - { - } - - protected override TableViewPage GenerateContainers( int startIndex, int itemCount, double availableHeight, double extendedHeight, bool fillLastPage ) - { - var innerStartIndex = startIndex; - var innerEndIndex = startIndex; - var innerContainersHeight = 0d; - var outerStartIndex = startIndex; - var outerEndIndex = startIndex; - var outerContainersHeight = 0d; - var remainingInnerContainersHeight = availableHeight; - var remainingOuterContainersHeight = extendedHeight; - - Debug.Assert( remainingInnerContainersHeight <= remainingOuterContainersHeight ); - - for( int i = innerStartIndex; ( remainingOuterContainersHeight > 0d ) && ( i < itemCount ); i++ ) - { - var containerInfo = this.CreateContainer( i ); - if( containerInfo == null ) - break; - - var containerHeight = containerInfo.Container.DesiredSize.Height; - - if( remainingInnerContainersHeight > 0d ) - { - innerEndIndex = i; - innerContainersHeight += containerHeight; - remainingInnerContainersHeight -= containerHeight; - } - - outerEndIndex = i; - outerContainersHeight += containerHeight; - remainingOuterContainersHeight -= containerHeight; - } - - if( fillLastPage ) - { - for( int i = innerStartIndex - 1; ( remainingOuterContainersHeight > 0d ) && ( i >= 0 ); i-- ) - { - var containerInfo = this.CreateContainer( i ); - if( containerInfo == null ) - break; - - var containerHeight = containerInfo.Container.DesiredSize.Height; - - if( containerHeight <= remainingInnerContainersHeight ) - { - innerStartIndex = i; - innerContainersHeight += containerHeight; - remainingInnerContainersHeight -= containerHeight; - } - - outerStartIndex = i; - outerContainersHeight += containerHeight; - remainingOuterContainersHeight -= containerHeight; - } - } - - return new TableViewPage( - new TableViewFullPageInfo( innerStartIndex, innerEndIndex, innerContainersHeight ), - new TableViewFullPageInfo( outerStartIndex, outerEndIndex, outerContainersHeight ), - availableHeight ); - } - } - - #endregion - - #region BottomTopPageGenerator Private Class - - private sealed class BottomTopPageGenerator : PageGenerator - { - internal BottomTopPageGenerator( TableViewItemsHost itemsHost, int startIndex, double availableHeight, bool forceMeasure ) - : base( itemsHost, startIndex, availableHeight, forceMeasure ) - { - } - - protected override TableViewPage GenerateContainers( int startIndex, int itemCount, double availableHeight, double extendedHeight, bool fillLastPage ) - { - var innerStartIndex = startIndex; - var innerEndIndex = startIndex; - var innerContainersHeight = 0d; - var outerStartIndex = startIndex; - var outerEndIndex = startIndex; - var outerContainersHeight = 0d; - var remainingInnerContainersHeight = availableHeight; - var remainingOuterContainersHeight = extendedHeight; - - Debug.Assert( remainingInnerContainersHeight <= remainingOuterContainersHeight ); - - for( int i = innerEndIndex; ( remainingOuterContainersHeight > 0d ) && ( i >= 0 ); i-- ) - { - var containerInfo = this.CreateContainer( i ); - if( containerInfo == null ) - break; - - var containerHeight = containerInfo.Container.DesiredSize.Height; - - outerStartIndex = i; - outerContainersHeight += containerHeight; - - if( containerHeight > remainingInnerContainersHeight ) - { - // The inner page must at least contain one container before we consider layouting in the other direction. - if( innerContainersHeight != 0d ) - break; - } - - innerStartIndex = i; - innerContainersHeight += containerHeight; - remainingInnerContainersHeight -= containerHeight; - remainingOuterContainersHeight -= containerHeight; - } - - for( int i = innerEndIndex + 1; ( remainingOuterContainersHeight > 0d ) && ( i < itemCount ); i++ ) - { - var containerInfo = this.CreateContainer( i ); - if( containerInfo == null ) - break; - - var containerHeight = containerInfo.Container.DesiredSize.Height; - - if( remainingInnerContainersHeight > 0d ) - { - innerEndIndex = i; - innerContainersHeight += containerHeight; - remainingInnerContainersHeight -= containerHeight; - } - - outerEndIndex = i; - outerContainersHeight += containerHeight; - remainingOuterContainersHeight -= containerHeight; - } - - return new TableViewPage( - new TableViewFullPageInfo( innerStartIndex, innerEndIndex, innerContainersHeight ), - new TableViewFullPageInfo( outerStartIndex, outerEndIndex, outerContainersHeight ), - availableHeight ); - } - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TableViewPage.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TableViewPage.cs deleted file mode 100644 index c8602144..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TableViewPage.cs +++ /dev/null @@ -1,103 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal sealed class TableViewPage - { - #region Static Fields - - internal static readonly TableViewPage Empty = new TableViewPage(); - - #endregion - - #region Constructors - - internal TableViewPage( TableViewFullPageInfo innerPage, TableViewFullPageInfo outerPage, double viewportHeight ) - { - if( innerPage == null ) - throw new ArgumentNullException( "innerPage" ); - - if( outerPage == null ) - throw new ArgumentNullException( "outerPage" ); - - if( innerPage.Start < outerPage.Start ) - throw new ArgumentException("The inner page must be a subset of the outer page.", "innerPage"); - - if( innerPage.End > outerPage.End ) - throw new ArgumentException( "The inner page must be a subset of the outer page.", "innerPage" ); - - if( viewportHeight < 0d ) - throw new ArgumentException( "viewportHeight must be greater than to equal to zero.", "viewportHeight" ); - - m_innerPage = innerPage; - m_outerPage = outerPage; - m_viewportHeight = viewportHeight; - } - - private TableViewPage() - { - m_innerPage = TableViewPageInfo.Empty; - m_outerPage = TableViewPageInfo.Empty; - } - - #endregion - - #region InnerPage Property - - public TableViewPageInfo InnerPage - { - get - { - return m_innerPage; - } - } - - private readonly TableViewPageInfo m_innerPage; - - #endregion - - #region OuterPage Property - - public TableViewPageInfo OuterPage - { - get - { - return m_outerPage; - } - } - - private readonly TableViewPageInfo m_outerPage; - - #endregion - - #region ViewportHeight Property - - public double ViewportHeight - { - get - { - return m_viewportHeight; - } - } - - private readonly double m_viewportHeight; //0d - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TableViewPageInfo.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TableViewPageInfo.cs deleted file mode 100644 index 729a0b03..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TableViewPageInfo.cs +++ /dev/null @@ -1,179 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal abstract class TableViewPageInfo : IEquatable - { - #region Static Fields - - internal static readonly TableViewPageInfo Empty = new EmptyPageInfo(); - - #endregion - - #region Constructor - - protected TableViewPageInfo() - { - } - - #endregion - - #region Start Property - - public abstract int Start - { - get; - } - - #endregion - - #region End Property - - public abstract int End - { - get; - } - - #endregion - - #region Length Property - - public abstract int Length - { - get; - } - - #endregion - - #region Size Property - - public abstract double Size - { - get; - } - - #endregion - - public static bool operator ==( TableViewPageInfo objA, TableViewPageInfo objB ) - { - if( object.ReferenceEquals( objA, null ) ) - return object.ReferenceEquals( objB, null ); - - return objA.Equals( objB ); - } - - public static bool operator !=( TableViewPageInfo objA, TableViewPageInfo objB ) - { - return !( objA == objB ); - } - - public sealed override int GetHashCode() - { - return this.GetHashCodeImpl(); - } - - public sealed override bool Equals( object obj ) - { - return this.Equals( obj as TableViewPageInfo ); - } - - public bool Equals( TableViewPageInfo obj ) - { - if( object.ReferenceEquals( obj, null ) ) - return false; - - if( object.ReferenceEquals( obj, this ) ) - return true; - - if( obj.GetHashCode() != this.GetHashCode() ) - return false; - - return this.EqualsImpl( obj ); - } - - public abstract bool TryGetStart( out int value ); - public abstract bool TryGetEnd( out int value ); - - protected abstract int GetHashCodeImpl(); - protected abstract bool EqualsImpl( TableViewPageInfo obj ); - - #region EmptyPageInfo Private Class - - private sealed class EmptyPageInfo : TableViewPageInfo - { - public override int Start - { - get - { - throw new NotSupportedException(); - } - } - - public override int End - { - get - { - throw new NotSupportedException(); - } - } - - public override int Length - { - get - { - return 0; - } - } - - public override double Size - { - get - { - return 0d; - } - } - - protected override int GetHashCodeImpl() - { - return 0; - } - - protected override bool EqualsImpl( TableViewPageInfo obj ) - { - return object.ReferenceEquals( obj, this ); - } - - public override bool TryGetStart( out int value ) - { - value = 0; - - return false; - } - - public override bool TryGetEnd( out int value ) - { - value = 0; - - return false; - } - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TableViewPartialPageInfo.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TableViewPartialPageInfo.cs deleted file mode 100644 index 8bcd9e34..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TableViewPartialPageInfo.cs +++ /dev/null @@ -1,47 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal abstract class TableViewPartialPageInfo : TableViewPageInfo - { - #region Length Property - - public sealed override int Length - { - get - { - throw new NotSupportedException(); - } - } - - #endregion - - #region Size Property - - public sealed override double Size - { - get - { - throw new NotSupportedException(); - } - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TableViewScrollViewer.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TableViewScrollViewer.cs deleted file mode 100644 index 4343ed28..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TableViewScrollViewer.cs +++ /dev/null @@ -1,378 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; -using System.Diagnostics; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Controls.Primitives; -using System.Windows.Data; -using System.Windows.Input; -using System.Windows.Media; -using Xceed.Utils.Wpf; - -namespace Xceed.Wpf.DataGrid.Views -{ - [TemplatePart( Name = "PART_RowSelectorPane", Type = typeof( RowSelectorPane ) )] - public class TableViewScrollViewer : DataGridScrollViewer - { - static TableViewScrollViewer() - { - DefaultStyleKeyProperty.OverrideMetadata( typeof( TableViewScrollViewer ), new FrameworkPropertyMetadata( typeof( TableViewScrollViewer ) ) ); - - TableViewScrollViewer.HorizontalScrollBarVisibilityHintProperty = TableViewScrollViewer.HorizontalScrollBarVisibilityHintPropertyKey.DependencyProperty; - TableViewScrollViewer.StoredFixedTransformProperty = TableViewScrollViewer.StoredFixedTransformPropertyKey.DependencyProperty; - } - - public TableViewScrollViewer() - { - ExecutedRoutedEventHandler executedRoutedEventHandler = new ExecutedRoutedEventHandler( this.OnScrollCommand ); - CanExecuteRoutedEventHandler canExecuteRoutedEventHandler = new CanExecuteRoutedEventHandler( this.OnQueryScrollCommand ); - - this.CommandBindings.Add( - new CommandBinding( ScrollBar.PageLeftCommand, - executedRoutedEventHandler, - canExecuteRoutedEventHandler ) ); - - this.CommandBindings.Add( - new CommandBinding( ScrollBar.PageRightCommand, - executedRoutedEventHandler, - canExecuteRoutedEventHandler ) ); - } - - #region RowSelectorPaneWidth Property - - public static readonly DependencyProperty RowSelectorPaneWidthProperty = DependencyProperty.Register( - "RowSelectorPaneWidth", - typeof( double ), - typeof( TableViewScrollViewer ), - new FrameworkPropertyMetadata( 20d ) ); - - public double RowSelectorPaneWidth - { - get - { - return ( double )this.GetValue( TableViewScrollViewer.RowSelectorPaneWidthProperty ); - } - set - { - this.SetValue( TableViewScrollViewer.RowSelectorPaneWidthProperty, value ); - } - } - - #endregion RowSelectorPaneWidth Property - - #region ShowRowSelectorPane Property - - public static readonly DependencyProperty ShowRowSelectorPaneProperty = DependencyProperty.Register( - "ShowRowSelectorPane", - typeof( bool ), - typeof( TableViewScrollViewer ), - new FrameworkPropertyMetadata( true ) ); - - public bool ShowRowSelectorPane - { - get - { - return ( bool )this.GetValue( TableViewScrollViewer.ShowRowSelectorPaneProperty ); - } - set - { - this.SetValue( TableViewScrollViewer.ShowRowSelectorPaneProperty, value ); - } - } - - #endregion ShowRowSelectorPane Property - - #region HorizontalScrollBarVisibilityHint Property - - private static readonly DependencyPropertyKey HorizontalScrollBarVisibilityHintPropertyKey = DependencyProperty.RegisterReadOnly( - "HorizontalScrollBarVisibilityHint", - typeof( ScrollBarVisibility ), - typeof( TableViewScrollViewer ), - new FrameworkPropertyMetadata( ScrollBarVisibility.Auto ) ); - - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - public static readonly DependencyProperty HorizontalScrollBarVisibilityHintProperty; - - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - public ScrollBarVisibility HorizontalScrollBarVisibilityHint - { - get - { - return ( ScrollBarVisibility )this.GetValue( TableViewScrollViewer.HorizontalScrollBarVisibilityHintProperty ); - } - } - - private void SetHorizontalScrollBarVisibilityHint( ScrollBarVisibility value ) - { - this.SetValue( TableViewScrollViewer.HorizontalScrollBarVisibilityHintPropertyKey, value ); - } - - private void ResetHorizontalScrollBarVisibilityHint() - { - this.ClearValue( TableViewScrollViewer.HorizontalScrollBarVisibilityHintPropertyKey ); - } - - #endregion HorizontalScrollBarVisibilityHint Property - - #region StoredFixedTransform Attached Property - - internal static readonly DependencyPropertyKey StoredFixedTransformPropertyKey = DependencyProperty.RegisterAttachedReadOnly( "StoredFixedTransform", - typeof( Transform ), - typeof( TableViewScrollViewer ), - new UIPropertyMetadata( null ) ); - - internal static readonly DependencyProperty StoredFixedTransformProperty; - - internal static Transform GetStoredFixedTransform( ScrollViewer obj ) - { - Transform actualValue = ( Transform )obj.GetValue( TableViewScrollViewer.StoredFixedTransformProperty ); - - if( actualValue == null ) - { - actualValue = TableViewScrollViewer.CreateFixedPanelTransform( obj ); - TableViewScrollViewer.SetStoredFixedTransform( obj, actualValue ); - } - - return actualValue; - } - - internal static void SetStoredFixedTransform( ScrollViewer obj, Transform value ) - { - obj.SetValue( TableViewScrollViewer.StoredFixedTransformPropertyKey, value ); - } - - #endregion StoredFixedTransform Attached Property - - #region RowSelectorPane Property - - internal RowSelectorPane RowSelectorPane - { - get - { - return m_rowSelectorPane; - } - } - - private RowSelectorPane m_rowSelectorPane; - - #endregion - - public override void OnApplyTemplate() - { - base.OnApplyTemplate(); - - m_rowSelectorPane = this.Template.FindName( "PART_RowSelectorPane", this ) as RowSelectorPane; - } - - protected override Size MeasureOverride( Size constraint ) - { - this.UpdateHorizontalScrollBarVisibilityHint( constraint ); - - return base.MeasureOverride( constraint ); - } - - internal static void SetFixedTranslateTransform( FrameworkElement element, bool canScrollHorizontally ) - { - if( element == null ) - throw new ArgumentNullException( "element" ); - - if( !TableViewScrollViewer.SetFixedTranslateTransformCore( element, canScrollHorizontally ) ) - { - if( !element.IsLoaded ) - { - // The method failed to apply the translate transform because it could not find a ScrollViewer - // among its ancestors. Try again when the element will be loaded in case it wasn't in the - // VisualTree. - element.Loaded += new RoutedEventHandler( TableViewScrollViewer.OnFixedElementLoaded ); - } - } - } - - internal static ScrollViewer GetParentScrollViewer( DependencyObject obj ) - { - DependencyObject parent = TreeHelper.GetParent( obj ); - ScrollViewer parentScrollViewer = parent as ScrollViewer; - - while( ( parent != null ) && ( parentScrollViewer == null ) ) - { - parent = TreeHelper.GetParent( parent ); - parentScrollViewer = parent as ScrollViewer; - } - - return parentScrollViewer; - } - - internal static TableViewScrollViewer GetParentTableViewScrollViewer( DependencyObject obj ) - { - DependencyObject parent = TreeHelper.GetParent( obj ); - TableViewScrollViewer parentScrollViewer = parent as TableViewScrollViewer; - - while( ( parent != null ) && ( parentScrollViewer == null ) ) - { - parent = TreeHelper.GetParent( parent ); - parentScrollViewer = parent as TableViewScrollViewer; - } - - return parentScrollViewer; - } - - internal static Transform CreateFixedPanelTransform( ScrollViewer parentScrollViewer ) - { - TranslateTransform newTransform = new TranslateTransform(); - - Binding horizontalOffsetBinding = new Binding(); - horizontalOffsetBinding.Source = parentScrollViewer; - horizontalOffsetBinding.Path = new PropertyPath( ScrollViewer.HorizontalOffsetProperty ); - - BindingOperations.SetBinding( newTransform, TranslateTransform.XProperty, horizontalOffsetBinding ); - - return newTransform; - } - - private static bool SetFixedTranslateTransformCore( FrameworkElement element, bool canScrollHorizontally ) - { - Debug.Assert( element != null ); - - var parentScrollViewer = TableViewScrollViewer.GetParentScrollViewer( element ) as ScrollViewer; - if( parentScrollViewer == null ) - return false; - - var fixedTransform = TableViewScrollViewer.GetStoredFixedTransform( parentScrollViewer ); - Debug.Assert( fixedTransform != null ); - - if( canScrollHorizontally ) - { - if( element.RenderTransform == fixedTransform ) - { - element.ClearValue( UIElement.RenderTransformProperty ); - } - } - else - { - element.RenderTransform = fixedTransform; - } - - return true; - } - - private static void OnFixedElementLoaded( object sender, RoutedEventArgs e ) - { - var element = sender as FrameworkElement; - if( element == null ) - return; - - element.Loaded -= new RoutedEventHandler( TableViewScrollViewer.OnFixedElementLoaded ); - - TableViewScrollViewer.SetFixedTranslateTransformCore( element, TableView.GetCanScrollHorizontally( element ) ); - } - - private void OnQueryScrollCommand( object sender, CanExecuteRoutedEventArgs e ) - { - e.CanExecute = true; - } - - private void OnScrollCommand( object sender, ExecutedRoutedEventArgs e ) - { - double scrollingViewport = this.ViewportWidth; - FixedCellPanel cellPanel = this.LocateFixedCellPanel( this ); - - if( cellPanel != null ) - { - scrollingViewport -= cellPanel.GetFixedWidth(); - } - - if( e.Command == ScrollBar.PageLeftCommand ) - { - double newOffset = Math.Max( this.HorizontalOffset - scrollingViewport, 0d ); - this.ScrollToHorizontalOffset( newOffset ); - e.Handled = true; - } - else if( e.Command == ScrollBar.PageRightCommand ) - { - double newOffset = Math.Min( this.HorizontalOffset + scrollingViewport, this.ScrollableWidth ); - this.ScrollToHorizontalOffset( newOffset ); - e.Handled = true; - } - else - { - System.Diagnostics.Debug.Assert( false ); - } - } - - private FixedCellPanel LocateFixedCellPanel( DependencyObject obj ) - { - if( obj == null ) - return null; - - for( int i = VisualTreeHelper.GetChildrenCount( obj ) - 1; i >= 0; i-- ) - { - var child = VisualTreeHelper.GetChild( obj, i ); - var foundPanel = child as FixedCellPanel; - - if( foundPanel != null ) - return foundPanel; - - foundPanel = this.LocateFixedCellPanel( child ); - - if( foundPanel != null ) - { - // The FixedCellPanel found can be one of the recycled container in the visual tree - var dataGridContext = DataGridControl.GetDataGridContext( foundPanel ); - if( dataGridContext != null ) - { - if( dataGridContext.GetItemFromContainer( foundPanel ) != null ) - return foundPanel; - } - } - } - - return null; - } - - private void UpdateHorizontalScrollBarVisibilityHint( Size viewport ) - { - bool isContentLargerThanViewport = false; - - var viewportWidth = viewport.Width; - if( !double.IsInfinity( viewportWidth ) ) - { - var dataGridContext = DataGridControl.GetDataGridContext( this ); - if( dataGridContext != null ) - { - var columnVirtualizationManager = dataGridContext.GetColumnVirtualizationManagerOrNull() as TableViewColumnVirtualizationManagerBase; - if( columnVirtualizationManager != null ) - { - isContentLargerThanViewport = ( columnVirtualizationManager.VisibleColumnsWidth > viewportWidth ); - } - } - } - - if( isContentLargerThanViewport ) - { - this.SetHorizontalScrollBarVisibilityHint( ScrollBarVisibility.Visible ); - } - else - { - this.ResetHorizontalScrollBarVisibilityHint(); - } - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TableViewStartPageInfo.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TableViewStartPageInfo.cs deleted file mode 100644 index 14b2d4bd..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TableViewStartPageInfo.cs +++ /dev/null @@ -1,89 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid.Views -{ - internal sealed class TableViewStartPageInfo : TableViewPartialPageInfo - { - #region Constructor - - internal TableViewStartPageInfo( int value ) - { - if( value < 0 ) - throw new ArgumentException( "value must be greater than or equal to zero.", "value" ); - - m_value = value; - } - - #endregion - - #region Start Property - - public override int Start - { - get - { - return m_value; - } - } - - private readonly int m_value; - - #endregion - - #region End Property - - public override int End - { - get - { - throw new NotSupportedException(); - } - } - - #endregion - - protected override int GetHashCodeImpl() - { - return m_value; - } - - protected override bool EqualsImpl( TableViewPageInfo obj ) - { - var page = obj as TableViewStartPageInfo; - if( object.ReferenceEquals( page, null ) ) - return false; - - return ( page.m_value == m_value ); - } - - public override bool TryGetStart( out int value ) - { - value = m_value; - - return true; - } - - public override bool TryGetEnd( out int value ) - { - value = 0; - - return false; - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TargetViewAttribute.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TargetViewAttribute.cs deleted file mode 100644 index 7ee79e4d..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/TargetViewAttribute.cs +++ /dev/null @@ -1,44 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Xceed.Wpf.DataGrid.Views -{ - [AttributeUsage( AttributeTargets.Class, Inherited = true, AllowMultiple = true )] - public sealed class TargetViewAttribute : Attribute - { - public TargetViewAttribute( Type viewType ) - { - if( !typeof( ViewBase ).IsAssignableFrom( viewType ) ) - throw new ArgumentException( "The specified view type must be derived from ViewBase.", "viewType" ); - - m_viewType = viewType; - } - - public Type ViewType - { - get - { - return m_viewType; - } - } - - private Type m_viewType; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/Theme.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/Theme.cs deleted file mode 100644 index 8a83b171..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/Theme.cs +++ /dev/null @@ -1,109 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; -using System.Windows; -using Xceed.Wpf.DataGrid.Markup; - -namespace Xceed.Wpf.DataGrid.Views -{ - [TypeConverter( typeof( ThemeConverter ) )] - public abstract class Theme : DependencyObject - { - public bool IsViewSupported( Type viewType ) - { - return Theme.IsViewSupported( viewType, this.GetType() ); - } - - public static bool IsViewSupported( Type viewType, Type themeType ) - { - object[] attributes = themeType.GetCustomAttributes( typeof( TargetViewAttribute ), true ); - - foreach( TargetViewAttribute attribute in attributes ) - { - if( attribute.ViewType == viewType ) - return true; - } - - return false; - } - - protected virtual ThemeKey CreateDefaultStyleKey( Type viewType, Type elementType ) - { - return new ThemeKey( viewType, this.GetType(), elementType ); - } - - internal ThemeKey GetDefaultStyleKey( Type viewType, Type elementType ) - { - return this.CreateDefaultStyleKey( viewType, elementType ); - } - } - - [TargetView( typeof( TableflowView ) )] - [TargetView( typeof( TableView ) )] - public class ClassicSystemColorTheme : Theme - { - } - - [TargetView( typeof( TableflowView ) )] - [TargetView( typeof( TableView ) )] - public class LunaNormalColorTheme : Theme - { - } - - [TargetView( typeof( TableflowView ) )] - [TargetView( typeof( TableView ) )] - public class LunaHomesteadTheme : Theme - { - } - - [TargetView( typeof( TableflowView ) )] - [TargetView( typeof( TableView ) )] - public class LunaMetallicTheme : Theme - { - } - - [TargetView( typeof( TableflowView ) )] - [TargetView( typeof( TableView ) )] - public class AeroNormalColorTheme : Theme - { - } - - [TargetView( typeof( TableflowView ) )] - [TargetView( typeof( TableView ) )] - public class RoyaleNormalColorTheme : Theme - { - } - - [TargetView( typeof( TableflowView ) )] - [TargetView( typeof( TableView ) )] - public class ZuneNormalColorTheme : Theme - { - } - - [TargetView( typeof( TableflowView ) )] - [TargetView( typeof( TableView ) )] - public class Windows7Theme : Theme - { - } - - [TargetView( typeof( TableflowView ) )] - [TargetView( typeof( TableView ) )] - public class Windows8Theme : Theme - { - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/UICellCollection.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/UICellCollection.cs deleted file mode 100644 index 53d3abe7..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/UICellCollection.cs +++ /dev/null @@ -1,525 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; -using System.Windows; -using System.Windows.Controls; - -namespace Xceed.Wpf.DataGrid.Views -{ - // This class manages the various panel of a FixedCellPanel and the Logical/Visual - // Parent of the elements added to it. More precisely : - // - The logical parent of all the elements added to this collection will be the - // FixedCellPanel. - // - An element added or inserted will be either added to the "fixed" sub panel or the - // "scrolling" sub panel, according to its index. Thus, the element's Visual Parent - // will either be the fixed or the scrolling sub panel. - // - When removing or inserting elements, some other elements may see their parent - // change. From the fixed sub panel to the scrolling sub panel or vice versa. - // - As long as the elements are added to FixedCellSubPanel objects (like our - // m_fixedPanel and m_scrollingPanel), this Visual vs Logical parent management will - // work. - // - The collapsed elements are not considered when counting the number of fixed - // elements, even 'though they can be found in the m_fixedPanel. This also means that - // for a FixedCellCount of 0, there can still be some (collapsed) element in m_fixedPanel. - internal class UICellCollection : UIElementCollection - { - // The visualParent is passed to the base constructor because it is mandatory, but - // the element's visual parent will always be either the fixed or the scrolling sub - // panel. This is one of the reason why we don't use the base implementation of this - // class functions. - public UICellCollection( Panel fixedPanel, Panel scrollingPanel, FixedCellPanel parentFixedCellPanel ) - : base( parentFixedCellPanel, parentFixedCellPanel ) - { - if( fixedPanel == null ) - throw new ArgumentNullException( "fixedPanel" ); - if( scrollingPanel == null ) - throw new ArgumentNullException( "scrollingPanel" ); - if( parentFixedCellPanel == null ) - throw new ArgumentNullException( "logicalParent" ); - - m_fixedPanel = fixedPanel; - m_scrollingPanel = scrollingPanel; - m_parentFixedCellPanel = parentFixedCellPanel; - } - - public override int Add( UIElement element ) - { - int itemsCount = this.Count; - - if( this.GetFixedVisibleChildrenCount() < m_parentFixedCellPanel.FixedCellCount ) - { - m_fixedPanel.Children.Add( element ); - } - else - { - m_scrollingPanel.Children.Add( element ); - } - - this.SetLogicalParent( element ); - this.IncrementVersion(); - - return itemsCount; // The old items count is necessarily the new element's index. - } - - public override int Capacity - { - get - { - Debug.Fail( "Check to see if the caller does something meaningful with this. We don't want to implement this property." ); - return 0; - } - set - { - Debug.Fail( "Check to see if the caller does something meaningful with this. We don't want to implement this property." ); - } - } - - public override void Clear() - { - int itemsCount = this.Count; - - if( itemsCount > 0 ) - { - UIElement[] elementArray = new UIElement[ itemsCount ]; - this.CopyTo( elementArray, 0 ); - m_fixedPanel.Children.Clear(); - m_scrollingPanel.Children.Clear(); - - // Only clear the logical parent once the elements are no longer attached. - UIElement element = null; - for( int i = 0; i < itemsCount; i++ ) - { - element = elementArray[ i ]; - - if( element != null ) - this.ClearLogicalParent( element ); - } - - this.IncrementVersion(); - } - } - - public override bool Contains( UIElement element ) - { - return ( ( m_scrollingPanel.Children.Contains( element ) ) || - ( m_fixedPanel.Children.Contains( element ) ) ); - } - - public override void CopyTo( Array array, int index ) - { - int fixedItemsCount = m_fixedPanel.Children.Count; - int scrollingItemsCount = m_scrollingPanel.Children.Count; - - if( array == null ) - throw new ArgumentNullException( "array" ); - - if( array.Rank != 1 ) - throw new ArgumentException( "The destination array must be one-dimensional (Rank == 1)." ); - - if( ( index < 0 ) || ( array.Length - index < fixedItemsCount + scrollingItemsCount ) ) - throw new ArgumentException( "The array size, given the provided index, cannot accommodate this collection element count." ); - - for( int i = 0; i < fixedItemsCount; i++ ) - { - array.SetValue( m_fixedPanel.Children[ i ], i + index ); - } - - for( int i = 0; i < scrollingItemsCount; i++ ) - { - array.SetValue( m_scrollingPanel.Children[ i ], fixedItemsCount + i + index ); - } - } - - public override void CopyTo( UIElement[] array, int index ) - { - this.CopyTo( ( Array )array, index ); - } - - public override int Count - { - get - { - return m_fixedPanel.Children.Count + m_scrollingPanel.Children.Count; - } - } - - public override IEnumerator GetEnumerator() - { - return new CellEnumerator( this ); - } - - public override int IndexOf( UIElement element ) - { - int index = m_scrollingPanel.Children.IndexOf( element ); - - if( index >= 0 ) - { - index += m_fixedPanel.Children.Count; - } - else - { - index = m_fixedPanel.Children.IndexOf( element ); - } - - return index; - } - - public override void Insert( int index, UIElement element ) - { - int itemsCount = this.Count; - - if( index > itemsCount ) - index = itemsCount; - - if( ( index < m_fixedPanel.Children.Count ) || ( itemsCount == m_fixedPanel.Children.Count ) ) - { - m_fixedPanel.Children.Insert( index, element ); - } - else - { - m_scrollingPanel.Children.Insert( index - m_fixedPanel.Children.Count, element ); - } - - if( element.Visibility != Visibility.Collapsed ) - { - int fixedPanelLastChildIndex = m_fixedPanel.Children.Count - 1; - int fixedCellCount = m_parentFixedCellPanel.FixedCellCount; - - // If necessary, move some elements (one visible and possibly some collapsed) - // from the fixed panel to the scrolling panel. - while( this.GetFixedVisibleChildrenCount() > fixedCellCount ) - { - UIElement bumpedElement = m_fixedPanel.Children[ fixedPanelLastChildIndex ]; - - m_fixedPanel.Children.RemoveAt( fixedPanelLastChildIndex ); - m_scrollingPanel.Children.Insert( 0, bumpedElement ); - // The logical parent has not changed. We don't have to call SetLogicalParent. - fixedPanelLastChildIndex--; - } - } - - this.SetLogicalParent( element ); - this.IncrementVersion(); - } - - public override bool IsSynchronized - { - get - { - return m_scrollingPanel.Children.IsSynchronized; - } - } - - public override object SyncRoot - { - get - { - return m_scrollingPanel.Children.SyncRoot; - } - } - - public override void Remove( UIElement element ) - { - int indexOfElement = m_scrollingPanel.Children.IndexOf( element ); - - if( indexOfElement >= 0 ) - { - m_scrollingPanel.Children.RemoveAt( indexOfElement ); - } - else - { - indexOfElement = m_fixedPanel.Children.IndexOf( element ); - - if( indexOfElement >= 0 ) - { - m_fixedPanel.Children.RemoveAt( indexOfElement ); - - int scrollingPanelChildrenCount = m_scrollingPanel.Children.Count; - - // If necessary, move some elements (one visible and possibly some collapsed) - // from the scrolling panel to the fixed panel. - if( scrollingPanelChildrenCount > 0 ) - { - int fixedCellCount = m_parentFixedCellPanel.FixedCellCount; - - while( ( this.GetFixedVisibleChildrenCount() < fixedCellCount ) && ( scrollingPanelChildrenCount > 0 ) ) - { - UIElement bumpedElement = m_scrollingPanel.Children[ 0 ]; - - m_scrollingPanel.Children.RemoveAt( 0 ); - m_fixedPanel.Children.Add( bumpedElement ); - // The logical parent has not changed. We don't have to call SetLogicalParent. - scrollingPanelChildrenCount--; - } - } - } - else - { - Debug.Assert( false, "Tried to remove an element that is not a child of the FixedCellPanel" ); - } - } - - this.ClearLogicalParent( element ); - this.IncrementVersion(); - } - - public override void RemoveAt( int index ) - { - if( ( index >= this.Count ) || ( index < 0 ) ) - throw new ArgumentOutOfRangeException( "index", index, "index must be less than count and greater than zero." ); - - int fixedPanelChildrenCount = m_fixedPanel.Children.Count; - - if( index < fixedPanelChildrenCount ) - { - this.Remove( m_fixedPanel.Children[ index ] ); - } - else - { - this.Remove( m_scrollingPanel.Children[ index - fixedPanelChildrenCount ] ); - } - } - - public override void RemoveRange( int index, int count ) - { - Debug.Fail( "This method has not been optimized because it should never be called." ); - - if( index < 0 ) - throw new ArgumentOutOfRangeException( "index", index, "index must be greater than or equal to zero." ); - - if( count < 0 ) - throw new ArgumentOutOfRangeException( "count", count, "count must be greater than or equal to zero." ); - - if( this.Count - index < count ) - throw new ArgumentException( "The specified index and count are greater than the size of this collection." ); - - for( int i = 0; i < count; i++ ) - { - this.RemoveAt( index ); - } - } - - public override UIElement this[ int index ] - { - get - { - if( index < 0 ) - throw new ArgumentOutOfRangeException( "index", index, "index must be greater than or equal to zero." ); - - if( index >= this.Count ) - throw new ArgumentOutOfRangeException( "index", index, "index must be less than the count of elements in this collection." ); - - int fixedPanelChildrenCount = m_fixedPanel.Children.Count; - - if( index < fixedPanelChildrenCount ) - { - return m_fixedPanel.Children[ index ]; - } - else - { - return m_scrollingPanel.Children[ index - fixedPanelChildrenCount ]; - } - } - - set - { - if( value == null ) - throw new ArgumentNullException( "value" ); - - if( index < 0 ) - throw new ArgumentOutOfRangeException( "index", index, "index must be greater than or equal to zero." ); - - if( index >= this.Count ) - throw new ArgumentOutOfRangeException( "index", index, "index must be less than the count of elements in this collection." ); - - int fixedPanelChildrenCount = m_fixedPanel.Children.Count; - - UIElement oldElement = null; - - if( index < fixedPanelChildrenCount ) - { - oldElement = m_fixedPanel.Children[ index ]; - m_fixedPanel.Children[ index ] = value; - } - else - { - oldElement = m_scrollingPanel.Children[ index - fixedPanelChildrenCount ]; - m_scrollingPanel.Children[ index - fixedPanelChildrenCount ] = value; - } - - this.SetLogicalParent( value ); - this.IncrementVersion(); - - if( oldElement != null ) - this.ClearLogicalParent( oldElement ); - } - } - - // Update the content of the two panels (fixed and scrolling) when the - // FixedColumnCount has changed. - public void UpdatePanels() - { - int fixedVisibleChildrenCount = this.GetFixedVisibleChildrenCount(); - int fixedCellCount = m_parentFixedCellPanel.FixedCellCount; - - if( fixedVisibleChildrenCount > fixedCellCount ) - { - UIElement element; - - while( fixedVisibleChildrenCount > fixedCellCount ) - { - element = m_fixedPanel.Children[ m_fixedPanel.Children.Count - 1 ]; - m_fixedPanel.Children.RemoveAt( m_fixedPanel.Children.Count - 1 ); - m_scrollingPanel.Children.Insert( 0, element ); - // The logical parent has not changed. We don't have to call SetLogicalParent. - if( element.Visibility != Visibility.Collapsed ) - fixedVisibleChildrenCount--; - } - - this.IncrementVersion(); - } - else if( ( fixedVisibleChildrenCount < fixedCellCount ) && ( m_scrollingPanel.Children.Count > 0 ) ) - { - UIElement element; - - while( ( fixedVisibleChildrenCount < fixedCellCount ) && ( m_scrollingPanel.Children.Count > 0 ) ) - { - element = m_scrollingPanel.Children[ 0 ]; - m_scrollingPanel.Children.RemoveAt( 0 ); - m_fixedPanel.Children.Add( element ); - // The logical parent has not changed. We don't have to call SetLogicalParent. - if( element.Visibility != Visibility.Collapsed ) - fixedVisibleChildrenCount++; - } - - this.IncrementVersion(); - } - } - - private int GetFixedVisibleChildrenCount() - { - int fixedVisibleChildrenCount = 0; - - foreach( UIElement child in m_fixedPanel.Children ) - { - if( child.Visibility != Visibility.Collapsed ) - fixedVisibleChildrenCount++; - } - - return fixedVisibleChildrenCount; - } - - private void IncrementVersion() - { - unchecked - { - m_version++; - } - } - - #region Private Class CellEnumerator - - // A IEnumerator class optimized to work with the UICellCollection. - private class CellEnumerator : IEnumerator - { - public CellEnumerator( UICellCollection cellCollection ) - { - if( cellCollection == null ) - throw new ArgumentNullException( "cellCollection" ); - - m_cellCollection = cellCollection; - m_version = cellCollection.m_version; - m_itemsCount = cellCollection.Count; - m_fixedCellCount = cellCollection.m_fixedPanel.Children.Count; - this.Reset(); - } - - public object Current - { - get - { - if( m_index < 0 ) - throw new InvalidOperationException( "The enumerator has not been started." ); - - if( m_index >= m_itemsCount ) - throw new InvalidOperationException( "The enumerator has reached the end." ); - - return m_current; - } - } - - public bool MoveNext() - { - if( m_version != m_cellCollection.m_version ) - throw new InvalidOperationException( "The collection has changed." ); - - bool result = false; - - if( m_index < m_itemsCount ) - { - m_index++; - - if( m_index < m_itemsCount ) - { - if( m_index < m_fixedCellCount ) - { - m_current = m_cellCollection.m_fixedPanel.Children[ m_index ]; - } - else - { - m_current = m_cellCollection.m_scrollingPanel.Children[ m_index - m_fixedCellCount ]; - } - - result = true; - } - else - { - m_current = null; - } - } - - return result; - } - - public void Reset() - { - if( m_version != m_cellCollection.m_version ) - throw new InvalidOperationException( "The collection has changed." ); - - m_index = -1; - m_current = null; - } - - private UICellCollection m_cellCollection; - private int m_index; - private UIElement m_current; - private int m_version; - private int m_itemsCount; - private int m_fixedCellCount; - } - - #endregion Private Class CellEnumerator - - private Panel m_fixedPanel; - private Panel m_scrollingPanel; - private FixedCellPanel m_parentFixedCellPanel; - private int m_version; - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/UIViewBase.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/UIViewBase.cs deleted file mode 100644 index 6b98ad30..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/UIViewBase.cs +++ /dev/null @@ -1,483 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.IO; -using System.Security; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Input; -using System.Windows.Media; - -namespace Xceed.Wpf.DataGrid.Views -{ - public abstract class UIViewBase : ViewBase - { - #region Static Fields - - // We must add a setter since this value is used as default - // value of a DependencyObject which will be instanciated - // before the static constructor is called - internal static Cursor DefaultGroupDraggedOutsideCursor - { - get - { - if( UIViewBase.DefaultGroupDraggedOutsiedCursorCache == null ) - { - try - { - var uri = new Uri( _XceedVersionInfo.CurrentAssemblyPackUri + ";component/NoDrop.cur" ); - var info = Application.GetResourceStream( uri ); - - if( info != null ) - { - UIViewBase.DefaultGroupDraggedOutsiedCursorCache = new Cursor( info.Stream ); - } - } - catch( SecurityException ) - { - } - catch( UriFormatException ) - { - } - catch( IOException ) - { - } - finally - { - if( UIViewBase.DefaultGroupDraggedOutsiedCursorCache == null ) - { - UIViewBase.DefaultGroupDraggedOutsiedCursorCache = Cursors.No; - } - } - } - - return UIViewBase.DefaultGroupDraggedOutsiedCursorCache; - } - } - - private static Cursor DefaultGroupDraggedOutsiedCursorCache; // = null; - - internal static Cursor DefaultColumnResizeWestEastCursor = Cursors.SizeWE; - internal static Cursor DefaultCannotDropDraggedElementCursor = Cursors.No; - - #endregion - - #region DropMarkPen Attached Property - - public static readonly DependencyProperty DropMarkPenProperty = DependencyProperty.RegisterAttached( - "DropMarkPen", - typeof( Pen ), - typeof( UIViewBase ), - new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.Inherits ) ); - - public static Pen GetDropMarkPen( DependencyObject obj ) - { - return ( Pen )obj.GetValue( UIViewBase.DropMarkPenProperty ); - } - - public static void SetDropMarkPen( DependencyObject obj, Pen value ) - { - obj.SetValue( UIViewBase.DropMarkPenProperty, value ); - } - - #endregion - - #region DropMarkOrientation Attached Property - - public static readonly DependencyProperty DropMarkOrientationProperty = DependencyProperty.RegisterAttached( - "DropMarkOrientation", - typeof( DropMarkOrientation ), - typeof( UIViewBase ), - new FrameworkPropertyMetadata( DropMarkOrientation.Default, FrameworkPropertyMetadataOptions.Inherits ) ); - - public static DropMarkOrientation GetDropMarkOrientation( DependencyObject obj ) - { - return ( DropMarkOrientation )obj.GetValue( UIViewBase.DropMarkOrientationProperty ); - } - - public static void SetDropMarkOrientation( DependencyObject obj, DropMarkOrientation value ) - { - obj.SetValue( UIViewBase.DropMarkOrientationProperty, value ); - } - - #endregion - - #region ShowScrollTip Property - - public static readonly DependencyProperty ShowScrollTipProperty = DependencyProperty.Register( - "ShowScrollTip", - typeof( bool ), - typeof( UIViewBase ) ); - - public bool ShowScrollTip - { - get - { - return ( bool )this.GetValue( UIViewBase.ShowScrollTipProperty ); - } - set - { - this.SetValue( UIViewBase.ShowScrollTipProperty, value ); - } - } - - #endregion - - #region DefaultDropMarkPen Property - - [ViewProperty( ViewPropertyMode.ViewOnly )] - public static readonly DependencyProperty DefaultDropMarkPenProperty = DependencyProperty.Register( - "DefaultDropMarkPen", - typeof( Pen ), - typeof( UIViewBase ), - new UIPropertyMetadata( null ) ); - - public Pen DefaultDropMarkPen - { - get - { - return ( Pen )this.GetValue( UIViewBase.DefaultDropMarkPenProperty ); - } - set - { - this.SetValue( UIViewBase.DefaultDropMarkPenProperty, value ); - } - } - - #endregion - - #region DefaultDropMarkOrientation Property - - [ViewProperty( ViewPropertyMode.ViewOnly )] - public static readonly DependencyProperty DefaultDropMarkOrientationProperty = DependencyProperty.Register( - "DefaultDropMarkOrientation", - typeof( DropMarkOrientation ), - typeof( UIViewBase ), - new UIPropertyMetadata( DropMarkOrientation.Vertical ) ); - - public DropMarkOrientation DefaultDropMarkOrientation - { - get - { - return ( DropMarkOrientation )this.GetValue( UIViewBase.DefaultDropMarkOrientationProperty ); - } - set - { - this.SetValue( UIViewBase.DefaultDropMarkOrientationProperty, value ); - } - } - - #endregion - - #region CurrentItemGlyph Property - - [ViewProperty( ViewPropertyMode.ViewOnly )] - public static readonly DependencyProperty CurrentItemGlyphProperty = DependencyProperty.Register( - "CurrentItemGlyph", - typeof( DataTemplate ), - typeof( UIViewBase ), - new FrameworkPropertyMetadata( null ) ); - - public DataTemplate CurrentItemGlyph - { - get - { - return ( DataTemplate )this.GetValue( UIViewBase.CurrentItemGlyphProperty ); - } - set - { - this.SetValue( UIViewBase.CurrentItemGlyphProperty, value ); - } - } - - #endregion - - #region EditingRowGlyph Property - - [ViewProperty( ViewPropertyMode.ViewOnly )] - public static readonly DependencyProperty EditingRowGlyphProperty = DependencyProperty.Register( - "EditingRowGlyph", - typeof( DataTemplate ), - typeof( UIViewBase ), - new FrameworkPropertyMetadata( null ) ); - - public DataTemplate EditingRowGlyph - { - get - { - return ( DataTemplate )this.GetValue( UIViewBase.EditingRowGlyphProperty ); - } - set - { - this.SetValue( UIViewBase.EditingRowGlyphProperty, value ); - } - } - - #endregion - - #region ValidationErrorGlyph Property - - [ViewProperty( ViewPropertyMode.ViewOnly )] - public static readonly DependencyProperty ValidationErrorGlyphProperty = DependencyProperty.Register( - "ValidationErrorGlyph", - typeof( DataTemplate ), - typeof( UIViewBase ), - new FrameworkPropertyMetadata( null ) ); - - public DataTemplate ValidationErrorGlyph - { - get - { - return ( DataTemplate )this.GetValue( UIViewBase.ValidationErrorGlyphProperty ); - } - set - { - this.SetValue( UIViewBase.ValidationErrorGlyphProperty, value ); - } - } - - #endregion - - #region ScrollTipContentTemplate Property - - [ViewProperty( ViewPropertyMode.ViewOnly )] - public static readonly DependencyProperty ScrollTipContentTemplateProperty = DependencyProperty.Register( - "ScrollTipContentTemplate", - typeof( DataTemplate ), - typeof( UIViewBase ) ); - - public DataTemplate ScrollTipContentTemplate - { - get - { - return ( DataTemplate )this.GetValue( UIViewBase.ScrollTipContentTemplateProperty ); - } - set - { - this.SetValue( UIViewBase.ScrollTipContentTemplateProperty, value ); - } - } - - #endregion - - #region ScrollTipContentTemplateSelector Property - - [ViewProperty( ViewPropertyMode.ViewOnly )] - public static readonly DependencyProperty ScrollTipContentTemplateSelectorProperty = DependencyProperty.Register( - "ScrollTipContentTemplateSelector", - typeof( DataTemplateSelector ), - typeof( UIViewBase ) ); - - public DataTemplateSelector ScrollTipContentTemplateSelector - { - get - { - return ( DataTemplateSelector )this.GetValue( UIViewBase.ScrollTipContentTemplateSelectorProperty ); - } - set - { - this.SetValue( UIViewBase.ScrollTipContentTemplateSelectorProperty, value ); - } - } - - #endregion - - #region IsConnectionStateGlyphEnabled Property - - [ViewProperty( ViewPropertyMode.ViewOnly )] - public static readonly DependencyProperty IsConnectionStateGlyphEnabledProperty = DependencyProperty.Register( - "IsConnectionStateGlyphEnabled", - typeof( bool ), - typeof( UIViewBase ), - new PropertyMetadata( true ) ); - - public bool IsConnectionStateGlyphEnabled - { - get - { - return ( bool )this.GetValue( UIViewBase.IsConnectionStateGlyphEnabledProperty ); - } - set - { - this.SetValue( UIViewBase.IsConnectionStateGlyphEnabledProperty, value ); - } - } - - #endregion - - #region ConnectionStateLoadingGlyph Property - - [ViewProperty( ViewPropertyMode.ViewOnly )] - public static readonly DependencyProperty ConnectionStateLoadingGlyphProperty = DependencyProperty.Register( - "ConnectionStateLoadingGlyph", - typeof( DataTemplate ), - typeof( UIViewBase ), - new FrameworkPropertyMetadata( null ) ); - - public DataTemplate ConnectionStateLoadingGlyph - { - get - { - return ( DataTemplate )this.GetValue( UIViewBase.ConnectionStateLoadingGlyphProperty ); - } - set - { - this.SetValue( UIViewBase.ConnectionStateLoadingGlyphProperty, value ); - } - } - - #endregion - - #region ConnectionStateCommittingGlyph Property - - [ViewProperty( ViewPropertyMode.ViewOnly )] - public static readonly DependencyProperty ConnectionStateCommittingGlyphProperty = DependencyProperty.Register( - "ConnectionStateCommittingGlyph", - typeof( DataTemplate ), - typeof( UIViewBase ), - new FrameworkPropertyMetadata( null ) ); - - public DataTemplate ConnectionStateCommittingGlyph - { - get - { - return ( DataTemplate )this.GetValue( UIViewBase.ConnectionStateCommittingGlyphProperty ); - } - set - { - this.SetValue( UIViewBase.ConnectionStateCommittingGlyphProperty, value ); - } - } - - #endregion - - #region ConnectionStateErrorGlyph Property - - [ViewProperty( ViewPropertyMode.ViewOnly )] - public static readonly DependencyProperty ConnectionStateErrorGlyphProperty = DependencyProperty.Register( - "ConnectionStateErrorGlyph", - typeof( DataTemplate ), - typeof( UIViewBase ), - new FrameworkPropertyMetadata( null ) ); - - public DataTemplate ConnectionStateErrorGlyph - { - get - { - return ( DataTemplate )this.GetValue( UIViewBase.ConnectionStateErrorGlyphProperty ); - } - set - { - this.SetValue( UIViewBase.ConnectionStateErrorGlyphProperty, value ); - } - } - - #endregion - - #region BusyCursor Property - - [ViewProperty( ViewPropertyMode.ViewOnly )] - public static readonly DependencyProperty BusyCursorProperty = DependencyProperty.Register( - "BusyCursor", - typeof( Cursor ), - typeof( UIViewBase ), - new FrameworkPropertyMetadata( Cursors.Wait ) ); - - public Cursor BusyCursor - { - get - { - return ( Cursor )this.GetValue( UIViewBase.BusyCursorProperty ); - } - set - { - this.SetValue( UIViewBase.BusyCursorProperty, value ); - } - } - - #endregion - - #region CannotDropDraggedElementCursor Property - - [ViewProperty( ViewPropertyMode.ViewOnly )] - public static readonly DependencyProperty CannotDropDraggedElementCursorProperty = DependencyProperty.Register( - "CannotDropDraggedElementCursor", - typeof( Cursor ), - typeof( UIViewBase ), - new FrameworkPropertyMetadata( Cursors.No ) ); - - public Cursor CannotDropDraggedElementCursor - { - get - { - return ( Cursor )this.GetValue( UIViewBase.CannotDropDraggedElementCursorProperty ); - } - set - { - this.SetValue( UIViewBase.CannotDropDraggedElementCursorProperty, value ); - } - } - - #endregion - - #region ColumnResizeWestEastCursor Property - - [ViewProperty( ViewPropertyMode.ViewOnly )] - public static readonly DependencyProperty ColumnResizeWestEastCursorProperty = DependencyProperty.Register( - "ColumnResizeWestEastCursor", - typeof( Cursor ), - typeof( UIViewBase ), - new FrameworkPropertyMetadata( UIViewBase.DefaultColumnResizeWestEastCursor ) ); - - public Cursor ColumnResizeWestEastCursor - { - get - { - return ( Cursor )this.GetValue( UIViewBase.ColumnResizeWestEastCursorProperty ); - } - set - { - this.SetValue( UIViewBase.ColumnResizeWestEastCursorProperty, value ); - } - } - - #endregion - - #region RemovingGroupCursor Property - - [ViewProperty( ViewPropertyMode.ViewOnly )] - public static readonly DependencyProperty RemovingGroupCursorProperty = DependencyProperty.Register( - "RemovingGroupCursor", - typeof( Cursor ), - typeof( UIViewBase ), - new FrameworkPropertyMetadata( UIViewBase.DefaultGroupDraggedOutsideCursor ) ); - - public Cursor RemovingGroupCursor - { - get - { - return ( Cursor )this.GetValue( UIViewBase.RemovingGroupCursorProperty ); - } - set - { - this.SetValue( UIViewBase.RemovingGroupCursorProperty, value ); - } - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/ViewBase.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/ViewBase.cs deleted file mode 100644 index c5b7df74..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/ViewBase.cs +++ /dev/null @@ -1,554 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.Diagnostics; -using System.Linq; -using System.Reflection; -using System.Windows; -using Xceed.Wpf.DataGrid.Markup; - -namespace Xceed.Wpf.DataGrid.Views -{ - public abstract class ViewBase : FrameworkContentElement - { - #region Static Members - - internal static object GetDefaultStyleKey( Type viewType, Type elementType ) - { - return new ThemeKey( viewType, null, elementType ); - } - - private static object GetDefaultStyleKey( Type viewType, Theme theme, Type elementType ) - { - if( theme == null ) - return ViewBase.GetDefaultStyleKey( viewType, elementType ); - - return theme.GetDefaultStyleKey( viewType, elementType ); - } - - #endregion Static Members - - static ViewBase() - { - ViewBase.FixedHeadersProperty = ViewBase.FixedHeadersPropertyKey.DependencyProperty; - ViewBase.HeadersProperty = ViewBase.HeadersPropertyKey.DependencyProperty; - ViewBase.FootersProperty = ViewBase.FootersPropertyKey.DependencyProperty; - ViewBase.FixedFootersProperty = ViewBase.FixedFootersPropertyKey.DependencyProperty; - } - - protected ViewBase() - { - this.SetValue( ViewBase.HeadersPropertyKey, new ObservableCollection() ); - this.SetValue( ViewBase.FootersPropertyKey, new ObservableCollection() ); - this.SetValue( ViewBase.FixedHeadersPropertyKey, new ObservableCollection() ); - this.SetValue( ViewBase.FixedFootersPropertyKey, new ObservableCollection() ); - - object newDefaultStyleKey = this.GetDefaultStyleKey( null ); - if( !object.Equals( newDefaultStyleKey, this.DefaultStyleKey ) ) - { - this.DefaultStyleKey = newDefaultStyleKey; - } - } - - #region Theme Property - - public static readonly DependencyProperty ThemeProperty = - DependencyProperty.Register( - "Theme", - typeof( Theme ), - typeof( ViewBase ), - new PropertyMetadata( null, - new PropertyChangedCallback( ViewBase.ThemeChangedCallback ), - new CoerceValueCallback( ViewBase.ThemeCoerceValueCallback ) ) ); - - public Theme Theme - { - get - { - // We don't use the GetStyledValue because this property will never support styling. - return ( Theme )this.GetValue( ViewBase.ThemeProperty ); - } - set - { - this.SetValue( ViewBase.ThemeProperty, value ); - } - } - - internal event DependencyPropertyChangedEventHandler ThemeChanged; - - private void OnThemeChanged( DependencyPropertyChangedEventArgs e ) - { - var handler = this.ThemeChanged; - if( handler == null ) - return; - - handler.Invoke( this, e ); - } - - private static void ThemeChangedCallback( DependencyObject sender, DependencyPropertyChangedEventArgs e ) - { - ViewBase view = ( ViewBase )sender; - - object newDefaultStyleKey = view.GetDefaultStyleKey( null ); - - if( !object.Equals( newDefaultStyleKey, view.DefaultStyleKey ) ) - { - view.ClearValue( FrameworkContentElement.DefaultStyleKeyProperty ); - - if( !object.Equals( newDefaultStyleKey, view.DefaultStyleKey ) ) - { - view.DefaultStyleKey = newDefaultStyleKey; - } - } - - view.OnThemeChanged( e ); - } - - private static object ThemeCoerceValueCallback( DependencyObject sender, object newValue ) - { - Theme newTheme = ( Theme )newValue; - - if( newTheme != null ) - { - if( !newTheme.IsViewSupported( sender.GetType() ) ) - throw new ArgumentException( "This view is not supported by the specified theme (" + sender.GetType().Name + ")." ); - } - - return newValue; - } - - #endregion Theme Property - - #region Headers Property - - private static readonly DependencyPropertyKey HeadersPropertyKey = - DependencyProperty.RegisterReadOnly( "Headers", typeof( ObservableCollection ), typeof( ViewBase ), new UIPropertyMetadata( null ) ); - - public static readonly DependencyProperty HeadersProperty; - - public ObservableCollection Headers - { - get - { - return ( ObservableCollection )this.GetValue( ViewBase.HeadersProperty ); - } - } - - #endregion Headers Property - - #region Footers Property - - private static readonly DependencyPropertyKey FootersPropertyKey = - DependencyProperty.RegisterReadOnly( "Footers", typeof( ObservableCollection ), typeof( ViewBase ), new UIPropertyMetadata( null ) ); - - public static readonly DependencyProperty FootersProperty; - - public ObservableCollection Footers - { - get - { - return ( ObservableCollection )this.GetValue( ViewBase.FootersProperty ); - } - } - - #endregion Footers Property - - #region FixedHeaders Property - - private static readonly DependencyPropertyKey FixedHeadersPropertyKey = - DependencyProperty.RegisterReadOnly( "FixedHeaders", typeof( ObservableCollection ), typeof( ViewBase ), new UIPropertyMetadata( null ) ); - - public static readonly DependencyProperty FixedHeadersProperty; - - public ObservableCollection FixedHeaders - { - get - { - return ( ObservableCollection )this.GetValue( ViewBase.FixedHeadersProperty ); - } - } - - #endregion FixedHeaders Property - - #region FixedFooters Property - - private static readonly DependencyPropertyKey FixedFootersPropertyKey = - DependencyProperty.RegisterReadOnly( "FixedFooters", typeof( ObservableCollection ), typeof( ViewBase ), new UIPropertyMetadata( null ) ); - - public static readonly DependencyProperty FixedFootersProperty; - - public ObservableCollection FixedFooters - { - get - { - return ( ObservableCollection )this.GetValue( ViewBase.FixedFootersProperty ); - } - } - - #endregion FixedFooters Property - - #region GroupLevelConfigurations Read-Only Property - - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - [Obsolete( "The GroupLevelConfiguration property is obsolete and has been replaced by the DataGridControl.GroupConfigurationSelector and DefaultGroupConfiguration properties. ", true )] - public static readonly DependencyProperty GroupLevelConfigurationsProperty; - - [Browsable( false )] - [EditorBrowsable( EditorBrowsableState.Never )] - [Obsolete( "The GroupLevelConfiguration property is obsolete and has been replaced by the DataGridControl.GroupConfigurationSelector and DefaultGroupConfiguration properties. ", true )] - public GroupLevelConfigurationCollection GroupLevelConfigurations - { - get - { - return null; - } - } - - #endregion GroupLevelConfigurations Read-Only Property - - #region AscendingSortGlyph Property - - [ViewProperty( ViewPropertyMode.ViewOnly )] - public static readonly DependencyProperty AscendingSortGlyphProperty = - DependencyProperty.Register( "AscendingSortGlyph", - typeof( DataTemplate ), - typeof( ViewBase ), - new FrameworkPropertyMetadata( null ) ); - - public DataTemplate AscendingSortGlyph - { - get - { - return ( DataTemplate )this.GetValue( ViewBase.AscendingSortGlyphProperty ); - } - set - { - this.SetValue( ViewBase.AscendingSortGlyphProperty, value ); - } - } - - #endregion AscendingSortGlyph Property - - #region DescendingSortGlyph Property - - [ViewProperty( ViewPropertyMode.ViewOnly )] - public static readonly DependencyProperty DescendingSortGlyphProperty = - DependencyProperty.Register( "DescendingSortGlyph", - typeof( DataTemplate ), - typeof( ViewBase ), - new FrameworkPropertyMetadata( null ) ); - - public DataTemplate DescendingSortGlyph - { - get - { - return ( DataTemplate )this.GetValue( ViewBase.DescendingSortGlyphProperty ); - } - set - { - this.SetValue( ViewBase.DescendingSortGlyphProperty, value ); - } - } - - #endregion SortOrderGlyph Property - - #region ExpandGroupGlyph Property - - [ViewProperty( ViewPropertyMode.ViewOnly )] - public static readonly DependencyProperty ExpandGroupGlyphProperty = - DependencyProperty.Register( "ExpandGroupGlyph", - typeof( DataTemplate ), - typeof( ViewBase ), - new FrameworkPropertyMetadata( null ) ); - - public DataTemplate ExpandGroupGlyph - { - get - { - return ( DataTemplate )this.GetValue( ViewBase.ExpandGroupGlyphProperty ); - } - set - { - this.SetValue( ViewBase.ExpandGroupGlyphProperty, value ); - } - } - - #endregion ExpandGroupGlyph Property - - #region CollapseGroupGlyph Property - - [ViewProperty( ViewPropertyMode.ViewOnly )] - public static readonly DependencyProperty CollapseGroupGlyphProperty = - DependencyProperty.Register( "CollapseGroupGlyph", - typeof( DataTemplate ), - typeof( ViewBase ), - new FrameworkPropertyMetadata( null ) ); - - public DataTemplate CollapseGroupGlyph - { - get - { - return ( DataTemplate )this.GetValue( ViewBase.CollapseGroupGlyphProperty ); - } - set - { - this.SetValue( ViewBase.CollapseGroupGlyphProperty, value ); - } - } - - #endregion CollapseGroupGlyph Property - - #region UseDefaultHeadersFooters Property - - // This property cannot be configured differently for details and won't be used with - // ViewBinding: don't assign a ViewProperty attribute. - public static readonly DependencyProperty UseDefaultHeadersFootersProperty = - DependencyProperty.Register( "UseDefaultHeadersFooters", typeof( bool ), typeof( ViewBase ), new PropertyMetadata( true ) ); - - public bool UseDefaultHeadersFooters - { - get - { - return ( bool )this.GetValue( TableView.UseDefaultHeadersFootersProperty ); - } - set - { - this.SetValue( TableView.UseDefaultHeadersFootersProperty, value ); - } - } - - #endregion UseDefaultHeadersFooters Property - - #region IsLastItem Attached Property - - public static readonly DependencyProperty IsLastItemProperty = DependencyProperty.RegisterAttached( - "IsLastItem", typeof( bool ), typeof( ViewBase ), - new FrameworkPropertyMetadata( false, FrameworkPropertyMetadataOptions.Inherits ) ); - - public static bool GetIsLastItem( DependencyObject obj ) - { - return ( bool )obj.GetValue( ViewBase.IsLastItemProperty ); - } - - public static void SetIsLastItem( DependencyObject obj, bool value ) - { - obj.SetValue( ViewBase.IsLastItemProperty, value ); - } - - #endregion IsLastItem Attached Property - - #region PreserveContainerSize Property - - internal static readonly DependencyProperty PreserveContainerSizeProperty = DependencyProperty.Register( - "PreserveContainerSize", - typeof( bool ), - typeof( ViewBase ), - new FrameworkPropertyMetadata( true ) ); - - internal bool PreserveContainerSize - { - get - { - return ( bool )this.GetValue( ViewBase.PreserveContainerSizeProperty ); - } - set - { - this.SetValue( ViewBase.PreserveContainerSizeProperty, value ); - } - } - - #endregion - - #region ViewTypeForThemeKey Property - - protected virtual Type ViewTypeForThemeKey - { - get - { - return this.GetType(); - } - } - - #endregion - - #region Protected Methods - - protected virtual void AddDefaultHeadersFooters() - { - } - - #endregion - - #region Internal Methods - - internal virtual ColumnVirtualizationManager CreateColumnVirtualizationManager( DataGridContext dataGridContext ) - { - Debug.Assert( dataGridContext != null ); - - return new ColumnVirtualizationManager( dataGridContext ); - } - - internal void InvokeAddDefaultHeadersFooters() - { - if( !m_defaultHeadersFootersAdded ) - { - m_defaultHeadersFootersAdded = true; - this.AddDefaultHeadersFooters(); - } - } - - internal object GetDefaultStyleKey( Type elementType ) - { - return ViewBase.GetDefaultStyleKey( this.ViewTypeForThemeKey, this.Theme, elementType ); - } - - internal IEnumerable GetViewProperties() - { - //This will ensure that the GetViewPropertiesCore will be called only once by instance of view (optimization to avoir re-doing it all the time ). - if( m_viewProperties == null ) - { - m_viewProperties = this.GetViewPropertiesCore( ViewPropertyMode.ViewOnly ).ToArray(); - } - - return m_viewProperties; - } - - internal IEnumerable GetSharedProperties() - { - //This will ensure that the GetViewPropertiesCore will be called only once by instance of view (optimization to avoir re-doing it all the time ). - if( m_sharedProperties == null ) - { - m_sharedProperties = this.GetViewPropertiesCore( ViewPropertyMode.Routed ).ToArray(); - } - - return m_sharedProperties; - } - - internal IEnumerable GetSharedNoFallbackProperties() - { - //This will ensure that the GetViewPropertiesCore will be called only once by instance of view (optimization to avoir re-doing it all the time ). - if( m_sharedNoFallbackProperties == null ) - { - m_sharedNoFallbackProperties = this.GetViewPropertiesCore( ViewPropertyMode.RoutedNoFallback ).ToArray(); - } - - return m_sharedNoFallbackProperties; - } - - #endregion - - #region Private Methods - - private static ViewPropertyAttribute GetViewPropertyAttribute( MemberInfo memberInfo ) - { - if( memberInfo == null ) - return null; - - var attributes = memberInfo.GetCustomAttributes( typeof( ViewPropertyAttribute ), true ); - if( ( attributes == null ) || ( attributes.GetLength( 0 ) != 1 ) ) - return null; - - return ( ViewPropertyAttribute )attributes[ 0 ]; - } - - private IEnumerable GetViewPropertiesCore( ViewPropertyMode viewPropertyMode ) - { - var fields = this.GetType().GetFields( BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy ); - foreach( FieldInfo field in fields ) - { - //Filter out any public static field that is not a DependencyProperty ( no examples ) - if( field.FieldType != typeof( DependencyProperty ) ) - continue; - - //Filter out all DependencyProperty that doesn't match the ViewPropertyMode. - var attribute = ViewBase.GetViewPropertyAttribute( field ); - if( ( attribute == null ) || ( attribute.ViewPropertyMode != viewPropertyMode ) ) - continue; - - var dependencyProperty = ( DependencyProperty )field.GetValue( null ); // parameter is ignored for static fields. - Debug.Assert( dependencyProperty != null ); - - if( dependencyProperty.ReadOnly ) - throw new InvalidOperationException( "An attempt was made to return a read-only property. Dependency properties returned by ViewBase.GetViewPropertiesCore() cannot be read-only." ); - - yield return new ViewPropertyStruct( dependencyProperty, attribute.ViewPropertyMode, attribute.FlattenDetailBindingMode ); - } - } - - #endregion - - #region Private Fields - - private IEnumerable m_viewProperties; // = null - private IEnumerable m_sharedProperties; // = null - private IEnumerable m_sharedNoFallbackProperties; // = null - private bool m_defaultHeadersFootersAdded; // = false - - #endregion - - #region ViewPropertyStruct Nested Type - - internal struct ViewPropertyStruct - { - internal ViewPropertyStruct( DependencyProperty dependencyProperty ) - { - if( dependencyProperty == null ) - throw new ArgumentNullException( "dependencyProperty" ); - - this.DependencyProperty = dependencyProperty; - this.ViewPropertyMode = ViewPropertyMode.None; - this.FlattenDetailBindingMode = FlattenDetailBindingMode.Default; - } - - internal ViewPropertyStruct( - DependencyProperty dependencyProperty, - ViewPropertyMode viewPropertyMode, - FlattenDetailBindingMode flattenDetailBindingMode ) - { - if( dependencyProperty == null ) - throw new ArgumentNullException( "dependencyProperty" ); - - this.DependencyProperty = dependencyProperty; - this.ViewPropertyMode = viewPropertyMode; - this.FlattenDetailBindingMode = flattenDetailBindingMode; - } - - internal readonly DependencyProperty DependencyProperty; - internal readonly ViewPropertyMode ViewPropertyMode; - internal readonly FlattenDetailBindingMode FlattenDetailBindingMode; - - public override bool Equals( object obj ) - { - if( !( obj is ViewPropertyStruct ) ) - return false; - - return ( this.DependencyProperty == ( ( ViewPropertyStruct )obj ).DependencyProperty ); - } - - public override int GetHashCode() - { - return this.DependencyProperty.GetHashCode(); - } - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/ViewPropertyAttribute.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/ViewPropertyAttribute.cs deleted file mode 100644 index 5e316b80..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Views/ViewPropertyAttribute.cs +++ /dev/null @@ -1,67 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; - -namespace Xceed.Wpf.DataGrid.Views -{ - [AttributeUsage( AttributeTargets.Field, AllowMultiple = false )] // Applies only to the fields that store the DependencyProperties - public sealed class ViewPropertyAttribute : Attribute - { - #region Constructors - - public ViewPropertyAttribute( ViewPropertyMode viewPropertyMode ) - : this( viewPropertyMode, FlattenDetailBindingMode.Default ) - { - } - - internal ViewPropertyAttribute( ViewPropertyMode viewPropertyMode, FlattenDetailBindingMode flattenDetailBindingMode ) - { - m_viewPropertyMode = viewPropertyMode; - m_flattenDetailBindingMode = flattenDetailBindingMode; - } - - #endregion - - #region ViewPropertyMode Property - - public ViewPropertyMode ViewPropertyMode - { - get - { - return m_viewPropertyMode; - } - } - - private readonly ViewPropertyMode m_viewPropertyMode = ViewPropertyMode.None; - - #endregion - - #region FlattenDetailBindingMode Internal Property - - internal FlattenDetailBindingMode FlattenDetailBindingMode - { - get - { - return m_flattenDetailBindingMode; - } - } - - private readonly FlattenDetailBindingMode m_flattenDetailBindingMode = FlattenDetailBindingMode.Default; - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/VirtualizingCellCollection.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/VirtualizingCellCollection.cs deleted file mode 100644 index 22e0b236..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/VirtualizingCellCollection.cs +++ /dev/null @@ -1,1415 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; -using System.Windows; -using Xceed.Wpf.DataGrid.Views; - -namespace Xceed.Wpf.DataGrid -{ - internal class VirtualizingCellCollection : CellCollection - { - internal VirtualizingCellCollection( Row parentRow ) - : base( new VirtualizingItemsList() ) - { - if( parentRow == null ) - throw new ArgumentNullException( "parentRow" ); - - m_parentRow = parentRow; - m_cells = new CellSet( parentRow ); - m_readOnlyCellsCollection = new ReadOnlyCollection( m_cells ); - - // We must assign the VirtualizingCellCollection of the VirtualizingItemsList manually - ( ( VirtualizingItemsList )this.Items ).SetParent( this ); - } - - #region Cells Property - - internal ICollection Cells - { - get - { - return m_readOnlyCellsCollection; - } - } - - private readonly ICollection m_readOnlyCellsCollection; - - #endregion - - #region BindedCells Property - - internal ICollection BindedCells - { - get - { - return m_bindedCells.Values; - } - } - - #endregion - - #region VirtualizedCells Property - - internal ICollection VirtualizedCells - { - get - { - return m_unbindedCells.Values; - } - } - - #endregion - - #region DataGridContext Private Property - - private DataGridContext DataGridContext - { - get - { - return DataGridControl.GetDataGridContext( m_parentRow ); - } - } - - #endregion - - #region Columns Private Property - - private ColumnCollection Columns - { - get - { - if( this.DataGridContext == null ) - return null; - - return this.DataGridContext.Columns; - } - } - - #endregion - - #region IsUpdating Property - - internal bool IsUpdating - { - get - { - return m_isUpdating.IsSet; - } - } - - internal IDisposable SetIsUpdating() - { - return m_isUpdating.Set(); - } - - private readonly AutoResetFlag m_isUpdating = AutoResetFlagFactory.Create(); - - #endregion - - #region VirtualizationMode property - - internal ColumnVirtualizationMode VirtualizationMode - { - get; - set; - } - - #endregion - - #region CollectionChanged Event - - internal event EventHandler CollectionChanged; - - private void NotifyCollectionChanged() - { - var handler = this.CollectionChanged; - if( handler == null ) - return; - - handler.Invoke( this, EventArgs.Empty ); - } - - #endregion - - public override Cell this[ ColumnBase column ] - { - get - { - if( column == null ) - return null; - - var columns = this.Columns; - if( columns == null ) - return null; - - var match = columns[ column.FieldName ]; - if( match == null ) - return null; - - Debug.Assert( match == column ); - - return this.GetCell( column, true ); - } - } - - public override Cell this[ string fieldName ] - { - get - { - return this.GetCell( this.GetColumn( fieldName ), true ); - } - } - - protected override void InsertItem( int index, Cell item ) - { - this.InternalInsert( index, item ); - } - - protected override void RemoveItem( int index ) - { - this.InternalRemoveAt( index ); - } - - protected override void SetItem( int index, Cell item ) - { - throw new NotSupportedException(); - } - - protected override void ClearItems() - { - this.InternalClear(); - } - - internal override void InternalAdd( Cell cell ) - { - this.InternalAddCore( cell ); - } - - internal override void InternalClear() - { - //Try to be GC friendly - if( m_recyclingBins != null ) - { - foreach( var recycleBin in m_recyclingBins.Values ) - { - recycleBin.Clear(); - } - m_recyclingBins.Clear(); - } - m_recyclingBins = null; - - if( m_freeCells != null ) - { - m_freeCells.Clear(); - m_freeCells.TrimExcess(); - } - m_freeCells = null; - - m_bindedCells.Clear(); - m_unbindedCells.Clear(); - m_unprocessedCells.Clear(); - m_cells.Clear(); - } - - internal override void InternalInsert( int index, Cell cell ) - { - this.InternalAddCore( cell ); - } - - internal override void InternalRemove( Cell cell ) - { - this.InternalRemoveCore( cell, true ); - } - - internal override void InternalRemoveAt( int index ) - { - ColumnBase column = this.Columns[ index ]; - if( column == null ) - return; - - Cell cell; - if( !m_bindedCells.TryGetValue( column.FieldName, out cell ) ) - return; - - this.InternalRemoveCore( cell, true ); - } - - internal override void InternalSetCell( int index, Cell cell ) - { - throw new NotSupportedException(); - } - - internal void Release( Cell cell ) - { - if( cell == null ) - return; - - // Remove the target cell from the binded cells. - this.ReleaseCore( cell ); - - cell.Visibility = Visibility.Collapsed; - } - - internal Cell GetCell( string fieldName, bool prepareCell ) - { - if( string.IsNullOrEmpty( fieldName ) ) - return null; - - Cell cell; - if( this.TryGetBindedCell( fieldName, prepareCell, out cell ) ) - return cell; - - return this.CreateOrRecoverCell( fieldName ); - } - - internal Cell GetCell( ColumnBase column, bool prepareCell ) - { - if( column == null ) - return null; - - Cell cell; - if( this.TryGetBindedCell( column, prepareCell, out cell ) ) - return cell; - - return this.CreateOrRecoverCell( column, this.DataGridContext ); - } - - internal bool TryGetBindedCell( string fieldName, out Cell cell ) - { - return this.TryGetBindedCell( fieldName, true, out cell ); - } - - internal bool TryGetBindedCell( ColumnBase column, out Cell cell ) - { - return this.TryGetBindedCell( column, true, out cell ); - } - - internal bool TryGetBindedCell( string fieldName, bool prepareCell, out Cell cell ) - { - return this.TryGetBindedCell( this.GetColumn( fieldName ), prepareCell, out cell ); - } - - internal bool TryGetBindedCell( ColumnBase column, bool prepareCell, out Cell cell ) - { - cell = null; - if( column == null ) - return false; - - if( !m_bindedCells.TryGetValue( column.FieldName, out cell ) ) - return false; - - if( prepareCell ) - { - this.PrepareCell( cell, column, this.DataGridContext ); - } - - return true; - } - - internal bool TryGetCreatedCell( string fieldName, out Cell cell ) - { - if( m_bindedCells.TryGetValue( fieldName, out cell ) ) - return true; - - //The required cell may have been added in xaml, but may still not be added to the binded cells. If this is the case, add it now. - if( m_unprocessedCells.TryGetValue( fieldName, out cell ) ) - { - m_unprocessedCells.Remove( fieldName ); - cell = m_parentRow.PrepareUnbindedCell( this.GetColumn( fieldName ), cell ); - - m_bindedCells.Add( fieldName, cell ); - - return true; - } - - return false; - } - - internal void MergeFreeCells() - { - if( m_freeCells == null ) - return; - - var dataGridContext = this.DataGridContext; - var columns = this.Columns; - - foreach( Cell cell in m_freeCells ) - { - this.MergeFreeCell( cell, dataGridContext, columns ); - } - - //Try to be GC friendly - m_freeCells.Clear(); - m_freeCells.TrimExcess(); - m_freeCells = null; - - m_freeCellsHaveBeenMerged = true; - } - - internal bool HasVirtualizedCell( string fieldName ) - { - if( string.IsNullOrWhiteSpace( fieldName ) ) - return false; - - if( m_bindedCells.ContainsKey( fieldName ) ) - return true; - - if( m_unbindedCells.ContainsKey( fieldName ) ) - return true; - - return false; - } - - internal Cell AddVirtualizedCell( ColumnBase column ) - { - var fieldName = column.FieldName; - Cell cell; - var addToCells = true; - - if( m_unprocessedCells.TryGetValue( fieldName, out cell ) ) - { - //A cell was provided in xaml - m_unprocessedCells.Remove( fieldName ); - addToCells = false; - } - - //If no cell was provided, this will generate one. - cell = m_parentRow.PrepareUnbindedCell( column, cell ); - - m_unbindedCells.Add( fieldName, cell ); - - //A new generated cell must be added to the CellSet. If it was provided through xaml, it is already added. - if( addToCells ) - { - m_cells.Add( cell ); - } - - return cell; - } - - internal void RemoveVirtualizedCell( ColumnBase column ) - { - Cell cell; - var binded = true; - - if( !this.TryGetBindedCell( column, false, out cell ) ) - { - binded = false; - this.TryRecoverCell( column, out cell, false ); - } - - if( cell != null ) - { - //Only remove cells that can be generated without any unique configuration (e.g. no custom template, no ResultPropertyName, etc..) - if( this.CanBeRemoved( cell ) ) - { - this.InternalRemoveCore( cell, binded ); - } - else - { - if( binded ) - { - m_bindedCells.Remove( cell.FieldName ); - cell.Visibility = Visibility.Collapsed; - cell.RemoveContentBinding(); - } - m_unprocessedCells.Add( cell.FieldName, cell ); - } - } - } - - internal void BindRecycledCells( ColumnCollection columns ) - { - if( m_recyclingBins == null ) - return; - - Cell cell; - - if( columns != null ) - { - foreach( ColumnBase column in columns ) - { - if( m_bindedCells.ContainsKey( column.FieldName ) ) - continue; - - if( this.TryGetRecycledCell( column, out cell ) ) - { - cell.ClearValue( Cell.VisibilityProperty ); - m_bindedCells.Add( cell.FieldName, cell ); - } - } - } - - this.ClearRecycleBins(); - } - - internal void BindVirtualizedCells() - { - foreach( KeyValuePair item in m_unbindedCells ) - { - var cell = item.Value; - cell.ClearValue( Cell.VisibilityProperty ); - m_bindedCells.Add( item.Key, cell ); - } - m_unbindedCells.Clear(); - - foreach( KeyValuePair item in m_unprocessedCells ) - { - var cell = m_parentRow.PrepareUnbindedCell( this.GetColumn( item.Key ), item.Value ); - cell.ClearValue( Cell.VisibilityProperty ); - m_bindedCells.Add( item.Key, cell ); - } - m_unprocessedCells.Clear(); - } - - internal void ClearOutOfViewBindedCells( List cells ) - { - foreach( Cell cell in cells ) - { - if( this.CanBeRemoved( cell ) ) - { - this.InternalRemoveCore( cell, true ); - continue; - } - - //No need to add the cell's fieldName to the FixedCellPanel.PermanentScrollingFieldNames, - //for FixedCellPanel.UpdateChildren() will take care of it in the next layout pass. - cell.RemoveContentBinding(); - } - } - - internal void ClearVirtualizedCells() - { - foreach( Cell cell in m_unbindedCells.Values ) - { - if( this.CanBeRemoved( cell ) ) - { - this.InternalRemoveCore( cell ); - continue; - } - - //No need to add the cell's fieldName to the FixedCellPanel.PermanentScrollingFieldNames, - //for FixedCellPanel.UpdateChildren() will take care of it in the next layout pass. - cell.RemoveContentBinding(); - cell.Arrange( new Rect( 0, 0, 0, 0 ) ); - cell.ClearValue( Cell.VisibilityProperty ); - m_bindedCells.Add( cell.FieldName, cell ); - } - - m_unbindedCells.Clear(); - - foreach( Cell cell in m_unprocessedCells.Values ) - { - if( this.CanBeRemoved( cell ) ) - { - this.InternalRemoveCore( cell ); - continue; - } - - var fieldName = cell.FieldName; - m_parentRow.PrepareUnbindedCell( this.GetColumn( fieldName ), cell ); - cell.Arrange( new Rect( 0, 0, 0, 0 ) ); - cell.ClearValue( Cell.VisibilityProperty ); - m_bindedCells.Add( fieldName, cell ); - } - - m_unprocessedCells.Clear(); - } - - internal void VirtualizeRecycledCells() - { - if( m_recyclingBins == null ) - return; - - foreach( LinkedList recycleBin in m_recyclingBins.Values ) - { - foreach( Cell cell in recycleBin ) - { - if( !m_unbindedCells.ContainsKey( cell.FieldName ) ) - { - m_unbindedCells.Add( cell.FieldName, cell ); - continue; - } - - Debug.Fail( "Why is there a cell with the same fieldname already present in the unbindedCells?" ); - this.InternalRemoveCore( cell ); - } - recycleBin.Clear(); - } - - m_recyclingBins.Clear(); - m_recyclingBins = null; - } - - internal void SynchronizeRecyclingBinsWithRecyclingGroups( IEnumerable visibleColumns ) - { - if( m_recyclingBins == null ) - return; - - //Get the recycling groups of visible columns only - var recyclingGroups = new List(); - foreach( ColumnBase column in visibleColumns ) - { - var recyclingGroup = this.GetRecyclingGroup( column ); - if( !recyclingGroups.Contains( recyclingGroup ) ) - { - recyclingGroups.Add( recyclingGroup ); - } - } - - //Clear cells and remove recycleBins not linked to a currently used recyclingGroup. - var unusedRecyclingGroups = new List(); - foreach( KeyValuePair> item in m_recyclingBins ) - { - var recyclingGroup = item.Key; - if( recyclingGroups.Contains( recyclingGroup ) ) - continue; - - unusedRecyclingGroups.Add( recyclingGroup ); - var recycleBin = item.Value; - foreach( Cell cell in recycleBin ) - { - this.InternalRemoveCore( cell ); - } - recycleBin.Clear(); - } - - foreach( object recyclingGroup in unusedRecyclingGroups ) - { - m_recyclingBins.Remove( recyclingGroup ); - } - } - - private bool CanBeRemoved( Cell cell ) - { - // Calling this method assumes it is for cells that are handled by the FixedCellPanel, which does not handle template cells, - // thus no need to check if it is one through Row.GetIsTemplateCell( cell ). - return ( cell.CanBeRecycled ) && ( cell.CanBeCollapsed ); - } - - private void ReleaseCore( Cell cell ) - { - Debug.Assert( !VirtualizingCellCollection.IsFreeCell( cell ), "Should always have a field name" ); - - m_bindedCells.Remove( cell.FieldName ); - - switch( this.VirtualizationMode ) - { - case ColumnVirtualizationMode.None: - { - //Not virtualizing - this.InternalRemoveCore( cell ); - break; - } - - case ColumnVirtualizationMode.Recycling: - { - // If recycling, put the cell into the appropriate recycle bin. - var recyclingGroup = this.GetRecyclingGroup( this.GetColumn( cell ) ); - var recycleBin = this.GetRecycleBinOrNew( recyclingGroup ); - - // A released cell shouldn't be in the recycle bin already. - Debug.Assert( !recycleBin.Contains( cell ) ); - recycleBin.Add( cell ); - break; - } - - case ColumnVirtualizationMode.Virtualizing: - { - //Virtualizing with no recycling - m_unbindedCells.Add( cell.FieldName, cell ); - break; - } - } - } - - private void InternalAddCore( Cell cell ) - { - //This method should be invoked only to add cells provided by the user through Row.Cells, in xaml for instance. - //For template cells, an other mechanism is used (See Row.OnApplyTemplate()). - Debug.Assert( cell != null ); - - //If a cell is provided in code behind, the user must provide a fieldname, and therefore it can be merged right away. - if( m_freeCellsHaveBeenMerged ) - { - this.MergeFreeCell( cell, this.DataGridContext, this.Columns ); - return; - } - - if( m_freeCells == null ) - { - m_freeCells = new List( 1 ); - } - - m_freeCells.Add( cell ); - m_cells.Add( cell ); - } - - private void InternalRemoveCore( Cell cell, bool unbind = false ) - { - Debug.Assert( !VirtualizingCellCollection.IsFreeCell( cell ), "Should always have a field name" ); - - if( unbind ) - { - m_bindedCells.Remove( cell.FieldName ); - } - - m_cells.Remove( cell ); - m_parentRow.RemoveFromVisualTree( cell ); - - //This must absolutely be done once every collection has removed the cell, for the ParentColumn will be set to null, thus the FieldName will be lost. - cell.CleanUpOnRemove(); - } - - private Cell CreateOrRecoverCell( string fieldName ) - { - return this.CreateOrRecoverCell( this.GetColumn( fieldName ), this.DataGridContext ); - } - - private Cell CreateOrRecoverCell( ColumnBase column, DataGridContext dataGridContext ) - { - Cell cell; - if( !this.TryRecoverCell( column, out cell, true ) ) - { - // Create a new cell if a suitable cell was not found. - cell = m_parentRow.ProvideCell( column ); - Debug.Assert( cell != null ); - - //Add the new cell to the CellSet - m_cells.Add( cell ); - } - else - { - //The current local value must be cleared instead of setting a new local value to give a chance for a style to set a value. - cell.ClearValue( Cell.VisibilityProperty ); - } - - // Make sure the cell is initialized and prepared to be used. - this.PrepareCell( cell, column, dataGridContext ); - - //Once the fieldname is updated, add it to the dictionary - m_bindedCells.Add( cell.FieldName, cell ); - - //Need to notify only when cells are not already binded, since the binded cells will get properly measured and arranged by the Virtualizing/FixedCellSubPanel(s). - if( !this.IsUpdating ) - { - this.NotifyCollectionChanged(); - } - - return cell; - } - - private void PrepareCell( Cell cell, ColumnBase column, DataGridContext dataGridContext ) - { - //context can be null when the DataGridCollectionView directly has a list of Xceed.Wpf.DataGrid.DataRow - if( ( cell == null ) || ( dataGridContext == null ) ) - return; - - // Initialize the cell in case it hasn't been initialized or in case of a column change. - cell.Initialize( dataGridContext, m_parentRow, column ); - - // Certain non recycling cells like StatCell must not be (re)prepared if their binding is not set, for performance reasons. - if( cell.HasAliveContentBinding ) - { - // Make sure the cell is prepared before leaving this method. - cell.PrepareContainer( dataGridContext, m_parentRow.DataContext ); - } - } - - private bool TryRecoverCell( ColumnBase column, out Cell cell, bool includeUnprocessedCells ) - { - cell = null; - - if( column == null ) - return false; - - switch( this.VirtualizationMode ) - { - case ColumnVirtualizationMode.Recycling: - { - return this.TryGetRecycledCell( column, out cell ); - } - - case ColumnVirtualizationMode.Virtualizing: - { - //When not recycling, get the cell already created for the required column. - if( ( m_unbindedCells.Count > 0 ) && ( m_unbindedCells.TryGetValue( column.FieldName, out cell ) ) ) - { - m_unbindedCells.Remove( column.FieldName ); - return true; - } - - //It may still be unprocessed (provided in xaml), so process it now. - if( ( m_unprocessedCells.Count > 0 ) && ( includeUnprocessedCells ) && ( m_unprocessedCells.TryGetValue( column.FieldName, out cell ) ) ) - { - m_unprocessedCells.Remove( column.FieldName ); - cell = m_parentRow.PrepareUnbindedCell( column, cell ); - return true; - } - - return false; - } - - default: - { - //Not virtualizing - return false; - } - } - } - - private bool TryGetRecycledCell( ColumnBase column, out Cell cell ) - { - cell = null; - - if( m_recyclingBins == null ) - return false; - - // Make sure the cell recycling group is up-to-date. - var dataGridContext = this.DataGridContext; - if( dataGridContext != null ) - { - var propertyDescription = ItemsSourceHelper.CreateOrGetPropertyDescriptionFromColumn( dataGridContext, column, null ); - ItemsSourceHelper.UpdateColumnFromPropertyDescription( column, dataGridContext.DataGridControl.DefaultCellEditors, dataGridContext.AutoCreateForeignKeyConfigurations, propertyDescription ); - } - - var recyclingGroup = this.GetRecyclingGroup( column ); - var recycleBin = default( LinkedList ); - - if( m_recyclingBins.TryGetValue( recyclingGroup, out recycleBin ) ) - { - // Try to recycle a cell that has already the appropriate column in order to minimize the cell's initialization time. - var targetNode = default( LinkedListNode ); - - for( var node = recycleBin.Last; node != null; node = node.Previous ) - { - targetNode = node; - - if( targetNode.Value.ParentColumn == column ) - break; - } - - // From here, the target node is either: - // 1. The cell with minimal initialization time. - // 2. The oldest cell. - // 3. null in case of an empty bin. - if( targetNode != null ) - { - cell = targetNode.Value; - recycleBin.Remove( targetNode ); - } - } - - return ( cell != null ); - } - - private void MergeFreeCell( Cell cell, DataGridContext dataGridContext, ColumnCollection columns ) - { - var fieldName = cell.FieldName; - - // Make sure the field name is valid and there is no other cell using it. - this.CheckCellFieldName( fieldName ); - this.CheckCellAlreadyExists( fieldName ); - - // Cells added in xaml (e.g a StatCell) must be added to the visual tree right away, even if they are not visible for the moment, - // to make sure any binding defined on a property works correctly. - m_parentRow.AddToVisualTree( cell ); - - //These cell will need further processing when not recycling before they can be used as BindedCells. - if( this.VirtualizationMode == ColumnVirtualizationMode.Virtualizing ) - { - m_unprocessedCells.Add( fieldName, cell ); - return; - } - - //This following calls will be done for unprocessedCells when actually using them. - cell.PrepareDefaultStyleKey( dataGridContext.DataGridControl.GetView() ); - - //It is possible a cell provided through Row.Cells does not correspond to any actual column in the grid, so do not prepare it. - var parentColumn = columns[ cell.FieldName ]; - if( parentColumn != null ) - { - cell.Initialize( dataGridContext, m_parentRow, parentColumn ); - cell.PrepareContainer( dataGridContext, m_parentRow.DataContext ); - } - - m_bindedCells.Add( fieldName, cell ); - } - - private ColumnBase GetColumn( Cell cell ) - { - if( cell == null ) - return null; - - var column = cell.ParentColumn; - if( column == null ) - { - column = this.GetColumn( cell.FieldName ); - } - - return column; - } - - private ColumnBase GetColumn( string fieldName ) - { - if( ( this.Columns == null ) || ( string.IsNullOrEmpty( fieldName ) ) ) - return null; - - return this.Columns[ fieldName ]; - } - - private object GetRecyclingGroup( ColumnBase column ) - { - return column.GetCellRecyclingGroupOrDefault(); - } - - private ICollection GetRecycleBinOrNew( object recyclingGroup ) - { - if( m_recyclingBins == null ) - { - m_recyclingBins = new Dictionary>(); - } - - LinkedList recycleBin; - - if( !m_recyclingBins.TryGetValue( recyclingGroup, out recycleBin ) ) - { - recycleBin = new LinkedList(); - m_recyclingBins.Add( recyclingGroup, recycleBin ); - } - - return recycleBin; - } - - private void ClearRecycleBins() - { - foreach( LinkedList recycleBin in m_recyclingBins.Values ) - { - foreach( Cell cell in recycleBin ) - { - this.InternalRemoveCore( cell ); - } - recycleBin.Clear(); - } - - m_recyclingBins.Clear(); - m_recyclingBins = null; - } - - private void CheckFieldName( string fieldName ) - { - if( string.IsNullOrEmpty( fieldName ) ) - throw new DataGridInternalException( "A field name is required.", this.DataGridContext.DataGridControl ); - } - - private void CheckCellFieldName( string fieldName ) - { - if( string.IsNullOrEmpty( fieldName ) ) - throw new DataGridInternalException( "A Cell should always have a FieldName.", this.DataGridContext.DataGridControl ); - } - - private void CheckCellAlreadyExists( string fieldName ) - { - var alreadyExists = false; - - if( this.VirtualizationMode == ColumnVirtualizationMode.Virtualizing ) - { - alreadyExists = m_unprocessedCells.ContainsKey( fieldName ); - - if( !alreadyExists ) - { - alreadyExists = m_unbindedCells.ContainsKey( fieldName ); - } - } - - if( !alreadyExists ) - { - alreadyExists = m_bindedCells.ContainsKey( fieldName ); - } - - if( alreadyExists ) - { - this.ThrowCellAlreadyExists( fieldName ); - } - } - - private void ThrowCellAlreadyExists( string fieldName ) - { - throw new DataGridInternalException( string.Format( "A cell with FieldName {0} already exists.", fieldName ), this.DataGridContext.DataGridControl ); - } - - private static bool IsFreeCell( Cell cell ) - { - Debug.Assert( cell != null ); - - return string.IsNullOrEmpty( cell.FieldName ); - } - - private readonly Row m_parentRow; - private readonly ICollection m_cells; - - // This Dictionary is used as a caching system to optimize lookup when virtualizing instead of parsing every columns looking for the fieldname, - // e.g.: looking for the last one when 1000 cells in the parent row. When virtualizing, only the cell visible in the viewport will be contained - // within this collection speeding the lookup. - private readonly Dictionary m_bindedCells = new Dictionary(); - - //This Dictionary is used in combinations with m_bindedCells when virtualizing without recycling. It contains cells assigned to a column, but not currently in view. - private readonly Dictionary m_unbindedCells = new Dictionary(); - - //This Dictionary is used to temporarily store FreeCells until they are correctly prepared and added to the designated dictionnary (binded or unbinded cells) - private readonly Dictionary m_unprocessedCells = new Dictionary(); - - // This Dictionary contains the recycling queues for the cells ready to be recycled. - private Dictionary> m_recyclingBins; //null - - // This collection is used to store cells that are added to the Collection before the FieldName and/or ParentColumn being set. - // This occurs when defining a Row with Cell in XAML during a BeginInit / EndInit. - private List m_freeCells; //null - private bool m_freeCellsHaveBeenMerged = false; - - #region VirtualizingCellCollectionEnumerator Nested Type - - private class VirtualizingCellCollectionEnumerator : IEnumerator, IEnumerator - { - internal VirtualizingCellCollectionEnumerator( VirtualizingCellCollection collection ) - { - if( collection == null ) - throw new ArgumentNullException( "collection" ); - - m_collection = collection; - - this.Reset(); - } - - public Cell Current - { - get - { - return m_current; - } - } - - object IEnumerator.Current - { - get - { - return this.Current; - } - } - - public bool MoveNext() - { - if( m_collection == null ) - throw new ObjectDisposedException( string.Empty ); - - var count = m_collection.Count; - m_index = Math.Min( m_index + 1, count ); - - if( m_index < count ) - { - m_current = m_collection[ m_index ]; - } - else - { - m_current = null; - } - - return ( m_current != null ); - } - - public void Reset() - { - m_index = -1; - m_current = null; - } - - void IDisposable.Dispose() - { - m_collection = null; - m_current = null; - } - - private VirtualizingCellCollection m_collection; - private int m_index; - private Cell m_current; // = null; - } - - #endregion - - #region VirtualizingItemsList Nested Type - - // This class is used to force the Collection.Items.Count to return the total number of columns. Every other method except this[index] are not supported - private class VirtualizingItemsList : IList - { - internal VirtualizingItemsList() - { - } - - internal void SetParent( VirtualizingCellCollection collection ) - { - if( collection == null ) - throw new ArgumentNullException( "collection" ); - - if( m_collection != null ) - throw new InvalidOperationException(); - - m_collection = collection; - } - - int ICollection.Count - { - get - { - ColumnCollection columns = this.Columns; - if( columns != null ) - return columns.Count; - - return 0; - } - } - - bool ICollection.IsReadOnly - { - get - { - return false; - } - } - - Cell IList.this[ int index ] - { - get - { - var cell = default( Cell ); - var columns = this.Columns; - - if( columns != null ) - { - var column = columns[ index ]; - - if( column != null ) - { - cell = m_collection[ column ]; - } - } - else - { - Debug.Fail( "An unprepared Row was asked for Cell" ); - } - - return cell; - } - set - { - throw new NotSupportedException(); - } - } - - private ColumnCollection Columns - { - get - { - if( m_collection == null ) - return null; - - return m_collection.Columns; - } - } - - int IList.IndexOf( Cell item ) - { - if( item == null ) - return -1; - - var columns = this.Columns; - - if( columns == null ) - return -1; - - string fieldName = item.FieldName; - var column = columns[ fieldName ]; - - if( column == null ) - return -1; - - return columns.IndexOf( column ); - } - - void IList.Insert( int index, Cell item ) - { - throw new NotSupportedException(); - } - - void IList.RemoveAt( int index ) - { - throw new NotSupportedException(); - } - - void ICollection.Add( Cell item ) - { - throw new NotSupportedException(); - } - - void ICollection.Clear() - { - throw new NotSupportedException(); - } - - bool ICollection.Contains( Cell item ) - { - if( item == null ) - return false; - - string fieldName = item.FieldName; - var columns = this.Columns; - - if( columns != null ) - return ( columns[ fieldName ] != null ); - - Debug.Fail( "An unprepared Row was asked for Cell" ); - - return false; - } - - void ICollection.CopyTo( Cell[] array, int arrayIndex ) - { - throw new NotSupportedException(); - } - - bool ICollection.Remove( Cell item ) - { - throw new NotSupportedException(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return new VirtualizingCellCollectionEnumerator( m_collection ); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return new VirtualizingCellCollectionEnumerator( m_collection ); - } - - private VirtualizingCellCollection m_collection; - } - - #endregion - - #region ReadOnlyCollection Nested Type - - private sealed class ReadOnlyCollection : ICollection - { - internal ReadOnlyCollection( ICollection collection ) - { - if( collection == null ) - throw new ArgumentNullException( "collection" ); - - m_collection = collection; - } - - int ICollection.Count - { - get - { - return m_collection.Count; - } - } - - bool ICollection.IsReadOnly - { - get - { - return true; - } - } - - void ICollection.Add( T item ) - { - throw new NotSupportedException(); - } - - void ICollection.Clear() - { - throw new NotSupportedException(); - } - - bool ICollection.Contains( T item ) - { - return m_collection.Contains( item ); - } - - void ICollection.CopyTo( T[] array, int arrayIndex ) - { - m_collection.CopyTo( array, arrayIndex ); - } - - bool ICollection.Remove( T item ) - { - throw new NotSupportedException(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return m_collection.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return m_collection.GetEnumerator(); - } - - private readonly ICollection m_collection; - } - - #endregion - - #region CellSet Nested Type - - private sealed class CellSet : ICollection, IWeakEventListener - { - internal CellSet( Row parentRow ) - { - Debug.Assert( parentRow != null ); - - m_parentRow = parentRow; - } - - public int Count - { - get - { - return m_collection.Count; - } - } - - bool ICollection.IsReadOnly - { - get - { - return false; - } - } - - public bool Contains( Cell item ) - { - return m_collection.Contains( item ); - } - - public void Add( Cell item ) - { - Debug.Assert( item != null ); - - m_collection.Add( item ); - - this.RegisterBringIntoView( item ); - } - - public bool Remove( Cell item ) - { - Debug.Assert( item != null ); - - if( !m_collection.Remove( item ) ) - return false; - - this.UnregisterBringIntoView( item ); - - return true; - } - - public void Clear() - { - foreach( var item in m_collection ) - { - this.UnregisterBringIntoView( item ); - } - - m_collection.Clear(); - m_collection.TrimExcess(); - } - - private void RegisterBringIntoView( Cell item ) - { - RequestBringIntoViewWeakEventManager.AddListener( item, this ); - } - - private void UnregisterBringIntoView( Cell item ) - { - RequestBringIntoViewWeakEventManager.RemoveListener( item, this ); - } - - private void OnRequestBringIntoView( object sender, RequestBringIntoViewEventArgs e ) - { - if( e.Handled ) - return; - - var targetCell = ( Cell )sender; - Debug.Assert( targetCell != null ); - Debug.Assert( m_collection.Contains( targetCell ) ); - - if( ( targetCell != e.TargetObject ) && !targetCell.IsAncestorOf( e.TargetObject ) ) - return; - - // Do not process the bring into view for a templated cell. - if( Row.GetIsTemplateCell( targetCell ) ) - return; - - var targetRow = targetCell.ParentRow; - Debug.Assert( ( targetRow == null ) || ( targetRow == m_parentRow ) ); - - var targetHost = ( targetRow != null ) ? targetRow.CellsHostPanel as IVirtualizingCellsHost : null; - - e.Handled = ( targetHost != null ) - && ( targetHost.BringIntoView( targetCell, e ) ); - } - - void ICollection.CopyTo( Cell[] array, int arrayIndex ) - { - m_collection.CopyTo( array, arrayIndex ); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return m_collection.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return m_collection.GetEnumerator(); - } - - bool IWeakEventListener.ReceiveWeakEvent( Type managerType, object sender, EventArgs e ) - { - if( managerType == typeof( RequestBringIntoViewWeakEventManager ) ) - { - this.OnRequestBringIntoView( sender, ( RequestBringIntoViewEventArgs )e ); - return true; - } - - return false; - } - - private readonly HashSet m_collection = new HashSet(); - private readonly Row m_parentRow; - } - - #endregion - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/VirtualizingStackPanel.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/VirtualizingStackPanel.cs deleted file mode 100644 index 406cff4a..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/VirtualizingStackPanel.cs +++ /dev/null @@ -1,2103 +0,0 @@ -/************************************************************************************* - - Extended WPF Toolkit - - Copyright (C) 2007-2013 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 - - For more features, controls, and fast professional support, - pick up the Plus Edition at http://xceed.com/wpf_toolkit - - Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids - - ***********************************************************************************/ - -using System; -using System.ComponentModel; -using System.Diagnostics; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Controls.Primitives; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Threading; -using Xceed.Wpf.DataGrid.Views; -using Xceed.Utils.Wpf; -using System.Collections.Generic; - -namespace Xceed.Wpf.DataGrid -{ - [Obsolete( "The VirtualizingStackPanel class is obsolete and has been replaced by the TableViewItemsHost class.", false )] - public sealed class VirtualizingStackPanel : DataGridVirtualizingPanel, ICustomVirtualizingPanel, IScrollInfo, IDeferableScrollInfoRefresh - { - private const int CleanupThreshold = 100; //100 ms max cleanup time. - - public VirtualizingStackPanel() - { - this.AddHandler( FrameworkElement.RequestBringIntoViewEvent, new RequestBringIntoViewEventHandler( OnRequestBringIntoView ) ); - } - - #region Orientation Property - - public static readonly DependencyProperty OrientationProperty = - DependencyProperty.Register( "Orientation", typeof( Orientation ), typeof( VirtualizingStackPanel ), new UIPropertyMetadata( Orientation.Vertical ) ); - - public Orientation Orientation - { - get - { - return ( Orientation )this.GetValue( VirtualizingStackPanel.OrientationProperty ); - } - set - { - this.SetValue( VirtualizingStackPanel.OrientationProperty, value ); - } - } - - #endregion Orientation Property - - #region StableScrollingEnabled Property - - public static readonly DependencyProperty StableScrollingEnabledProperty = - DependencyProperty.Register( "StableScrollingEnabled", typeof( bool ), typeof( VirtualizingStackPanel ), new UIPropertyMetadata( true ) ); - - public bool StableScrollingEnabled - { - get - { - return ( bool )this.GetValue( VirtualizingStackPanel.StableScrollingEnabledProperty ); - } - set - { - this.SetValue( VirtualizingStackPanel.StableScrollingEnabledProperty, value ); - } - } - - #endregion StableScrollingEnabled Property - - #region StableScrollingProportion Property - - public static readonly DependencyProperty StableScrollingProportionProperty = - DependencyProperty.Register( "StableScrollingProportion", typeof( double ), typeof( VirtualizingStackPanel ), new UIPropertyMetadata( 0.5d ) ); - - public double StableScrollingProportion - { - get - { - return ( double )this.GetValue( VirtualizingStackPanel.StableScrollingProportionProperty ); - } - set - { - this.SetValue( VirtualizingStackPanel.StableScrollingProportionProperty, value ); - } - } - - #endregion StableScrollingProportion Property - - #region UsedSurface Property - - private static readonly DependencyProperty UsedSurfaceProperty = - DependencyProperty.Register( "UsedSurface", typeof( Rect ), typeof( VirtualizingStackPanel ), new FrameworkPropertyMetadata( Rect.Empty, FrameworkPropertyMetadataOptions.AffectsRender ) ); - - private Rect UsedSurface - { - get - { - return ( Rect )this.GetValue( VirtualizingStackPanel.UsedSurfaceProperty ); - } - set - { - this.SetValue( VirtualizingStackPanel.UsedSurfaceProperty, value ); - } - } - - #endregion UsedSurface Property - - #region ContentBorderBrush Property - - public static readonly DependencyProperty ContentBorderBrushProperty = - DependencyProperty.Register( "ContentBorderBrush", typeof( Brush ), typeof( VirtualizingStackPanel ), new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.AffectsRender ) ); - - public Brush ContentBorderBrush - { - get - { - return ( Brush )this.GetValue( VirtualizingStackPanel.ContentBorderBrushProperty ); - } - set - { - this.SetValue( VirtualizingStackPanel.ContentBorderBrushProperty, value ); - } - } - - #endregion ContentBorderBrush Property - - #region ContentBorderThickness Property - - public static readonly DependencyProperty ContentBorderThicknessProperty = - DependencyProperty.Register( "ContentBorderThickness", typeof( Thickness ), typeof( VirtualizingStackPanel ), new FrameworkPropertyMetadata( DefaultThickness, FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsArrange ) ); - - public Thickness ContentBorderThickness - { - get - { - return ( Thickness )this.GetValue( VirtualizingStackPanel.ContentBorderThicknessProperty ); - } - set - { - this.SetValue( VirtualizingStackPanel.ContentBorderThicknessProperty, value ); - } - } - - #endregion ContentBorderThickness Property - - protected override Size ArrangeOverride( Size finalSize ) - { - UIElementCollection children = this.Children; - IItemContainerGenerator generator = this.CustomItemContainerGenerator; - Orientation orientation = this.Orientation; - GeneratorPosition firstItemGenPos; - - if( generator == null ) - { - // In design mode, there won't be any CustomItemContainerGenerator to work with - // when editing the style of VirtualizingStackPanel but, strangely, - // GetIsInDesignMode can return false. - Debug.WriteLineIf( !DesignerProperties.GetIsInDesignMode( this ), "Missing generator in VirtualizingStackPanel.ArrangeOverride()" ); - firstItemGenPos = new GeneratorPosition( 0, 0 ); - } - else - { - //retrieve the Generator position for the first visible item - firstItemGenPos = generator.GeneratorPositionFromIndex( ( int )( ( orientation == Orientation.Vertical ) ? this.VerticalOffset : this.HorizontalOffset ) ); - } - - //from that generator position, the Index is the child index in the children collection. - - Point offset = new Point(); - Rect itemRect = new Rect(); - - Point bottomRight = new Point(); - Point topLeft = new Point(); - - double compensationOffset; - double compensationSize; - double compensationItemSize; - - //place the "opposed" direction's offset to the initial offset. - if( orientation == Orientation.Vertical ) - { - // **************************************** - // The Starting offset is set to 0.05 so that layout is not "perfectly" aligned with start of panel. - // This is because a perfect layout sometimes cause glitches in the keyboard navigation for items of a different layout. - //**************************************** - if( this.VerticalOffset != 0 ) - { - offset.Y = 0.05; - } - else - { - offset.Y = this.ContentBorderThickness.Top; - } - - if( this.HorizontalOffset != 0 ) - { - offset.X = -this.HorizontalOffset; - } - else - { - offset.X = this.ContentBorderThickness.Left; - } - - //set the "starting" endpoint for the ContentBorder to the extent coordinates. - //for this case, I cannot rely on the ExtentHeight for the bottomRight.Y - bottomRight.X = this.ExtentWidth; - - compensationOffset = this.HorizontalOffset; - } - else - { - //**************************************** - // The Starting offset is set to 0.05 so that layout is not "perfectly" aligned with start of panel. - // This is because a perfect layout sometimes cause glitches in the keyboard navigation for items of a different layout. - //**************************************** - if( this.HorizontalOffset != 0 ) - { - offset.X = 0.05; - } - else - { - offset.X = this.ContentBorderThickness.Left; - } - - if( this.VerticalOffset != 0 ) - { - offset.Y = -this.VerticalOffset; - } - else - { - offset.Y = this.ContentBorderThickness.Top; - } - - //set the "starting" endpoint for the ContentBorder to the extent coordinates. - //for this case, I cannot rely on the ExtentHeight for the bottomRight.X - bottomRight.Y = this.ExtentHeight; - - compensationOffset = this.VerticalOffset; - } - - bool limitInSize = false; - - - //cycle through all the children, starting from that one - for( int i = firstItemGenPos.Index; i < children.Count; i++ ) - { - if( i >= 0 ) - { - UIElement item = children[ i ]; - DataGridContext itemContext = DataGridControl.GetDataGridContext( item ); - string itemContextName = ( itemContext.SourceDetailConfiguration == null ) ? "" : itemContext.SourceDetailConfiguration.RelationName; - - itemRect.X = offset.X; - itemRect.Y = offset.Y; - - if( orientation == Orientation.Vertical ) - { - compensationItemSize = this.GetCorrectedItemWidth( itemContextName, finalSize ); - - itemRect.Width = compensationItemSize; - compensationSize = Math.Min( this.ViewportWidth, compensationItemSize ); - - itemRect.Height = item.DesiredSize.Height; - - offset.Y += itemRect.Height; - - //Update the SurfaceRect with the coordinates of item just placed. - bottomRight.Y = itemRect.Bottom; - if( itemRect.Right > bottomRight.X ) - { - bottomRight.X = itemRect.Right; - } - } - else - { - itemRect.Width = item.DesiredSize.Width; - - compensationItemSize = this.GetCorrectedItemHeight( itemContextName, finalSize ); - - itemRect.Height = compensationItemSize; - compensationSize = Math.Min( this.ViewportHeight, compensationItemSize ); - - itemRect.Height = Math.Max( m_extent.Height, item.DesiredSize.Height ); - - offset.X += itemRect.Width; - - //Update the SurfaceRect with the coordinates of item just placed. - bottomRight.X = itemRect.Right; - if( itemRect.Bottom > bottomRight.Y ) - { - bottomRight.Y = itemRect.Bottom; - } - } - - TableView.SetCompensationOffset( item, Math.Max( 0, ( ( compensationOffset + compensationSize ) - compensationItemSize ) ) ); - item.Arrange( itemRect ); - } - } - - //reset the "opposed" direction's offset to the initial offset. - if( orientation == Orientation.Vertical ) - { - //**************************************** - // The Starting offset is set to 0.05 so that layout is not "perfectly" aligned with start of panel. - // This is because a perfect layout sometimes cause glitches in the keyboard navigation for items of a different layout. - //**************************************** - if( this.VerticalOffset != 0 ) - { - offset.Y = 0.05; - } - else - { - offset.Y = this.ContentBorderThickness.Top; - } - - if( this.HorizontalOffset != 0 ) - { - offset.X = -this.HorizontalOffset; - } - else - { - offset.X = this.ContentBorderThickness.Left; - } - - topLeft.X = offset.X; - } - else - { - //**************************************** - // The Starting offset is set to 0.05 so that layout is not "perfectly" aligned with start of panel. - // This is because a perfect layout sometimes cause glitches in the keyboard navigation for items of a different layout. - //**************************************** - if( this.HorizontalOffset != 0 ) - { - offset.X = 0.05; - } - else - { - offset.X = this.ContentBorderThickness.Left; - } - - if( this.VerticalOffset != 0 ) - { - offset.Y = -this.VerticalOffset; - } - else - { - offset.Y = this.ContentBorderThickness.Top; - } - - topLeft.Y = offset.Y; - } - - //cycle through all the items "prior" the first visible and place them before the first one - for( int i = firstItemGenPos.Index - 1; i >= 0; i-- ) - { - UIElement item = children[ i ]; - DataGridContext itemContext = DataGridControl.GetDataGridContext( item ); - string itemContextName = ( itemContext.SourceDetailConfiguration == null ) ? "" : itemContext.SourceDetailConfiguration.RelationName; - - limitInSize = ( itemContext.ParentDataGridContext != null ); - - if( orientation == Orientation.Vertical ) - { - compensationItemSize = this.GetCorrectedItemWidth( itemContextName, finalSize ); - - itemRect.Width = compensationItemSize; - compensationSize = Math.Min( this.ViewportWidth, compensationItemSize ); - - itemRect.Height = item.DesiredSize.Height; - - offset.Y -= itemRect.Height; - - //Update the SurfaceRect with the coordinates of item just placed. - topLeft.Y = offset.Y; - } - else - { - itemRect.Width = item.DesiredSize.Width; - - compensationItemSize = this.GetCorrectedItemHeight( itemContextName, finalSize ); - - itemRect.Height = compensationItemSize; - compensationSize = Math.Min( this.ViewportHeight, compensationItemSize ); - - offset.X -= itemRect.Width; - - //Update the SurfaceRect with the coordinates of item just placed. - topLeft.X = itemRect.X; - } - - itemRect.X = offset.X; - itemRect.Y = offset.Y; - - TableView.SetCompensationOffset( item, Math.Max( 0, ( ( compensationOffset + compensationSize ) - compensationItemSize ) ) ); - item.Arrange( itemRect ); - - } - - Rect surfaceRect = new Rect( topLeft, bottomRight ); - if( this.UsedSurface != surfaceRect ) - { - this.UsedSurface = surfaceRect; - } - - return finalSize; - - } - - private double GetSynchronizedExtentWidth() - { - DataGridScrollViewer dgScrollViewer = m_owner as DataGridScrollViewer; - if( dgScrollViewer != null ) - { - return dgScrollViewer.SynchronizedScrollViewersWidth; - } - return m_extent.Width; - } - - private double GetCorrectedItemWidth( string itemContextName, Size arrangeSize ) - { - double retval; - - double synchronizedWidth = this.GetSynchronizedExtentWidth(); - double extentWidth = Math.Max( synchronizedWidth, m_extent.Width ); - - bool foundContextName = m_desiredSizeDictionary.TryGetValue( itemContextName, out retval ); - - //if the itemContextName is not present in the desiredSizeDictionary - // OR - //if the desiredSize is real close to 0 - if( ( foundContextName == false ) || ( Xceed.Utils.Math.DoubleUtil.AreClose( retval, 0d ) == true ) ) - { - //I take a look at the previous sizes dictionary. - if( m_previousSizeDictionary.TryGetValue( itemContextName, out retval ) == false ) - { - //If the entry is not found in the previous sizes dictionary, then take the largest between the extentWidth or the arrangeSize. - retval = Math.Max( extentWidth, arrangeSize.Width ); - } - } - else - { - //Now, if the itemContextName was found in the desiredSize dictionary AND it was larger than 0 - //Store the value in the previousSizes dictionary - m_previousSizeDictionary[ itemContextName ] = retval; - } - - if( string.IsNullOrEmpty( itemContextName ) == true ) // master level - { - //for the master level, I want to consider the Synchronized Extent size as well. - retval = Math.Max( synchronizedWidth, retval ); - } - - return retval; - } - - private double GetSynchronizedExtentHeight() - { - DataGridScrollViewer dgScrollViewer = m_owner as DataGridScrollViewer; - if( dgScrollViewer != null ) - { - return dgScrollViewer.SynchronizedScrollViewersHeight; - } - return m_extent.Height; - } - - private double GetCorrectedItemHeight( string itemContextName, Size arrangeSize ) - { - double retval; - - double synchronizedHeight = this.GetSynchronizedExtentHeight(); - double extentHeight = Math.Max( synchronizedHeight, m_extent.Height ); - - bool foundContextName = m_desiredSizeDictionary.TryGetValue( itemContextName, out retval ); - - //if the itemContextName is not present in the desiredSizeDictionary - // OR - //if the desiredSize is real close to 0 - if( ( foundContextName == false ) || ( Xceed.Utils.Math.DoubleUtil.AreClose( retval, 0d ) == true ) ) - { - //I take a look at the previous sizes dictionary. - if( m_previousSizeDictionary.TryGetValue( itemContextName, out retval ) == false ) - { - //If the entry is not found in the previous sizes dictionary, then take the largest between the extentWidth or the arrangeSize. - retval = Math.Max( extentHeight, arrangeSize.Height ); - } - } - else - { - //Now, if the itemContextName was found in the desiredSize dictionary AND it was larger than 0 - //Store the value in the previousSizes dictionary - m_previousSizeDictionary[ itemContextName ] = retval; - } - - if( string.IsNullOrEmpty( itemContextName ) == true ) // master level - { - //for the master level, I want to consider the Synchronized Extent size as well. - retval = Math.Max( synchronizedHeight, retval ); - } - - return retval; - } - - protected override Size MeasureOverride( Size availableSize ) - { - UIElementCollection children = this.Children; - IItemContainerGenerator generator = this.CustomItemContainerGenerator; - List calculatedAutoWidthContextLevels = new List(); - - if( generator == null ) - { - // In design mode, there won't be any CustomItemContainerGenerator to work with - // when editing the style of VirtualizingStackPanel but, strangely, - // GetIsInDesignMode can return false. - Debug.WriteLineIf( !DesignerProperties.GetIsInDesignMode( this ), "Missing generator in VirtualizingStackPanel.MeasureOverride()" ); - return new Size( 20, 20 ); - } - - //clear the dictionary that holds the "maximum desired size" for the different DataGridContexts. - m_desiredSizeDictionary.Clear(); - - bool invalidateScrollInfo = false; - - Orientation orientation = this.Orientation; - - int numberItems = this.ItemCount; - - //retrieve the index of the first item to layout - int firstVisibleIndex = ( int )( ( orientation == Orientation.Vertical ) ? this.VerticalOffset : this.HorizontalOffset ); - - // If the item offset is past the last item in the items list, then use the last item... (move the offset) - if( firstVisibleIndex >= numberItems ) - { - firstVisibleIndex = Math.Max( 0, numberItems - 1 ); - - if( orientation == Orientation.Vertical ) - { - m_offset.Y = firstVisibleIndex; - } - else - { - m_offset.X = firstVisibleIndex; - } - } - - bool newlyRealized = false; - double actualSize = 0.0d; - Size desiredSize = new Size( 0, 0 ); - Size restrictedMeasureSize; - - // We need to set the viewPort width while calling MeasureOverride - // to be able to virtualize Columns - if( orientation == Orientation.Vertical ) - { - restrictedMeasureSize = new Size( availableSize.Width, double.PositiveInfinity ); - m_viewport.Width = availableSize.Width; - } - else - { - restrictedMeasureSize = new Size( double.PositiveInfinity, availableSize.Height ); - m_viewport.Height = availableSize.Height; - } - - //get the generator position for the first visible index - GeneratorPosition firstItemGeneratorPosition = generator.GeneratorPositionFromIndex( firstVisibleIndex ); - - // Get index where we would insert the child for this position. If the item is realized - // (position.Offset == 0), it's just position.Index, otherwise we have to add one to - // insert after the corresponding child - int childIndex = ( firstItemGeneratorPosition.Offset == 0 ) ? firstItemGeneratorPosition.Index : firstItemGeneratorPosition.Index + 1; - int itemsCount = 0; - - //if the items collection for the ItemsControl is not empty!. - if( numberItems > 0 ) - { - //this flag indicates if one item was placed but was only partially visible (or not at all) - bool busted = false; - - using( generator.StartAt( firstItemGeneratorPosition, GeneratorDirection.Forward, true ) ) - { - bool quitLoop = false; - DataGridContext dataGridContext; - // The rowDesiredSizeCalculated flag is necessary for ColumnStretchMode because - // the first row measurement will calculate and modify the columns ActualWidth. - // Consequently, this row will have the correct DesiredSize (using the correct - // ActualWidths). However, another Row in the same "measure pass" may not - // consider the new ActualWidths immediately (due to UIElement.Measure - // optimisation). With this flag, the first Row will be taking into account - // when determining the largest opposed size, but the following realized Rows - // will be ignored. This will always work because all the rows have the same - // opposed size (the same width when the orientation is vertical). - bool rowDesiredSizeCalculated = false; - - do - { - //If we reached the end of the possible items - if( ( firstVisibleIndex + itemsCount ) >= numberItems ) - { - //exit loop - quitLoop = true; - } - else - { - UIElement item = ( UIElement )generator.GenerateNext( out newlyRealized ); - - if( item == null ) - { - quitLoop = true; - } - else - { - - //if the items was just realized - if( newlyRealized == true ) - { - // Figure out if we need to insert the child at the end or somewhere in the middle - if( childIndex >= children.Count ) - { - base.AddInternalChild( item ); - } - else - { - base.InsertInternalChild( childIndex, item ); - } - - //prepare the new item container - generator.PrepareItemContainer( item ); - } - - itemsCount++; - childIndex++; - dataGridContext = DataGridControl.GetDataGridContext( item ); - - if( !calculatedAutoWidthContextLevels.Contains( dataGridContext.DetailLevel ) ) - { - bool isRow = item is Row; - - if( ( !isRow ) && ( item is HeaderFooterItem ) ) - isRow = typeof( Row ).IsAssignableFrom( ( ( HeaderFooterItem )item ).VisualRootElementType ); - - if( isRow ) - { - dataGridContext.ColumnStretchingManager.ColumnStretchingCalculated = false; - // Calling Measure with the Viewport's width will have the effect of - // distributing the extra space (see FixedCellPanel's MeasureOverride). - // Eventually, the FixedCellPanel will receive an adjusted viewport - // width (where GroupLevelIndicator's width et al will be substracted). - item.Measure( restrictedMeasureSize ); - - if( dataGridContext.ColumnStretchingManager.ColumnStretchingCalculated ) - calculatedAutoWidthContextLevels.Add( dataGridContext.DetailLevel ); - - // We still need to measure using infinity in case that the row is alone - // in its panel. - } - } - - item.Measure( VirtualizingStackPanel.InfiniteSize ); - - string dataGridContextName = ( dataGridContext.SourceDetailConfiguration != null ) ? dataGridContext.SourceDetailConfiguration.RelationName : string.Empty; - - if( m_desiredSizeDictionary.ContainsKey( dataGridContextName ) == false ) - { - m_desiredSizeDictionary.Add( dataGridContextName, 0d ); - } - - //if the orientation is "Vertical" - if( orientation == Orientation.Vertical ) - { - //and the width of the item is the largest found yet - if( item.DesiredSize.Width > m_desiredSizeDictionary[ dataGridContextName ] ) - { - //remember the width as the largest found! - if( ( !rowDesiredSizeCalculated ) || !( item is Row ) ) - m_desiredSizeDictionary[ dataGridContextName ] = item.DesiredSize.Width; - } - - //offset the coordinate by the height of the item. - actualSize += item.DesiredSize.Height; - - if( ( actualSize > availableSize.Height ) && ( itemsCount != 1 ) ) //the second condition is there to prevent a size 0 viewport (and to make sure at least 1 post item is generated) - { - //partially visible rows are not part of the viewport. - quitLoop = true; - busted = true; - } - } - else - { - //and the Height of the item is the largest found yet - if( item.DesiredSize.Height > m_desiredSizeDictionary[ dataGridContextName ] ) - { - //remember the Height as the largest found! - if( ( !rowDesiredSizeCalculated ) || !( item is Row ) ) - m_desiredSizeDictionary[ dataGridContextName ] = item.DesiredSize.Height; - } - - //offset the coordinate by the Width of the item. - actualSize += item.DesiredSize.Width; - - if( ( actualSize > availableSize.Width ) && ( itemsCount != 1 ) ) //the second condition is there to prevent a size 0 viewport (and to make sure at least 1 post item is generated) - { - //partially visible rows are not part of the viewport. - quitLoop = true; - busted = true; - } - } - - if( ( !rowDesiredSizeCalculated ) && ( item is Row ) ) - rowDesiredSizeCalculated = true; - } - } - - } - while( quitLoop == false ); - } //end using! - - //from this point, it is possible to calculate the Viewport and the extent sizes - double maxOpposedSize = this.ComputeMaxOpposedSize(); - - if( orientation == Orientation.Vertical ) - { - double synchronizedExtentWidth = 0; - DataGridScrollViewer dgsv = this.ScrollOwner as DataGridScrollViewer; - if( dgsv != null ) - { - synchronizedExtentWidth = dgsv.SynchronizedScrollViewersWidth; - } - - //if the calculated width of the viewport is larger than available size, - //use the available size as the viewport... otherwise, take the calculated size - // If the availableSize is Infinity, use the greater of the calculated sizes - // (either the grid body or headers/footers, aka SynchronizedScrollViewers). - double tmpWidth = ( Double.IsInfinity( availableSize.Width ) == false ) ? availableSize.Width : Math.Max( maxOpposedSize, synchronizedExtentWidth ); - if( m_viewport.Width != tmpWidth ) - { - m_viewport.Width = tmpWidth; - invalidateScrollInfo = true; - } - - int tmpHeight = ( busted == false ) ? itemsCount : itemsCount - 1; //-1 since I generate 1 more than required - if( m_viewport.Height != tmpHeight ) - { - m_viewport.Height = tmpHeight; - invalidateScrollInfo = true; - } - - // Determine this Panel's extent - maxOpposedSize = Math.Max( maxOpposedSize, synchronizedExtentWidth ); - - if( m_extent.Width != maxOpposedSize ) - { - m_extent.Width = maxOpposedSize; - invalidateScrollInfo = true; - } - - if( m_extent.Height != numberItems ) - { - m_extent.Height = numberItems; - invalidateScrollInfo = true; - } - - if( ( this.HorizontalOffset + this.ViewportWidth ) > this.ExtentWidth ) - { - m_offset.X = Math.Max( 0.0d, ( this.ExtentWidth - this.ViewportWidth ) ); - invalidateScrollInfo = true; - } - - //this sets the desiredSize of the Panel according to the values gathered during the Measure of all elements. - desiredSize.Height = Math.Min( availableSize.Height, actualSize ); - desiredSize.Width = Math.Min( availableSize.Width, maxOpposedSize ); - } - else - { - double synchronizedExtentHeight = 0; - DataGridScrollViewer dgsv = this.ScrollOwner as DataGridScrollViewer; - if( dgsv != null ) - { - synchronizedExtentHeight = dgsv.SynchronizedScrollViewersHeight; - } - - //if the calculated Height of the viewport is larger than available size, - //use the available size as the viewport... otherwise, take the calculated size - // If the availableSize is Infinity, use the greater of the calculated sizes - // (either the grid body or headers/footers, aka SynchronizedScrollViewers). - double tmpHeight = ( Double.IsInfinity( availableSize.Height ) == false ) ? availableSize.Height : Math.Max( maxOpposedSize, synchronizedExtentHeight ); - if( m_viewport.Height != tmpHeight ) - { - m_viewport.Height = tmpHeight; - invalidateScrollInfo = true; - } - - int tmpWidth = ( busted == false ) ? itemsCount : itemsCount - 1; //-1 since I generated 1 more than required - if( m_viewport.Width != tmpWidth ) - { - m_viewport.Width = tmpWidth; - invalidateScrollInfo = true; - } - - // Determine this Panel's extent - maxOpposedSize = Math.Max( maxOpposedSize, synchronizedExtentHeight ); - - if( m_extent.Height != maxOpposedSize ) - { - m_extent.Height = maxOpposedSize; - invalidateScrollInfo = true; - } - - if( m_extent.Width != numberItems ) - { - m_extent.Width = numberItems; - invalidateScrollInfo = true; - } - - if( ( this.VerticalOffset + this.ViewportHeight ) > this.ExtentHeight ) - { - m_offset.Y = Math.Max( 0.0d, ( this.ExtentHeight - this.ViewportHeight ) ); - invalidateScrollInfo = true; - } - - //this sets the desiredSize of the Panel according to the values gathered during the Measure of all elements. - desiredSize.Width = Math.Min( availableSize.Width, actualSize ); - desiredSize.Height = Math.Min( availableSize.Height, maxOpposedSize ); - } - - //finally, generate the pre-item! - if( firstVisibleIndex > 0 ) - { - GeneratorPosition preItemGeneratorPos = generator.GeneratorPositionFromIndex( firstVisibleIndex - 1 ); - int preChildIndex = ( preItemGeneratorPos.Offset == 0 ) ? preItemGeneratorPos.Index : preItemGeneratorPos.Index + 1; - - using( generator.StartAt( preItemGeneratorPos, GeneratorDirection.Backward, true ) ) - { - UIElement item = ( UIElement )generator.GenerateNext( out newlyRealized ); - - //if the items was just realized - if( newlyRealized == true ) - { - // Figure out if we need to insert the child at the end or somewhere in the middle - if( preChildIndex >= children.Count ) - { - base.AddInternalChild( item ); - } - else - { - base.InsertInternalChild( preChildIndex, item ); - } - - //prepare the new item container - generator.PrepareItemContainer( item ); - } - - //measure with the available size... - item.Measure( VirtualizingStackPanel.InfiniteSize ); - } //end using - }//end if firstVisibleIndex > 0 - - //set the members that will indicate to the cleaning function what items are truly used. - m_actualFirstItem = ( firstVisibleIndex > 0 ) ? firstVisibleIndex - 1 : 0; - m_actualLastItem = firstVisibleIndex + itemsCount - 1; - - } //end if numberItems > 0 - else - { - if( orientation == Orientation.Vertical ) - { - double synchronizedWidth = 0; - DataGridScrollViewer dgsv = this.ScrollOwner as DataGridScrollViewer; - if( dgsv != null ) - { - synchronizedWidth = dgsv.SynchronizedScrollViewersWidth; - } - - m_extent.Width = synchronizedWidth; - m_viewport.Width = availableSize.Width; - m_extent.Height = 0; - } - else - { - double synchronizedHeight = 0; - DataGridScrollViewer dgsv = this.ScrollOwner as DataGridScrollViewer; - if( dgsv != null ) - { - synchronizedHeight = dgsv.SynchronizedScrollViewersHeight; - } - - m_extent.Height = synchronizedHeight; - m_viewport.Height = availableSize.Height; - m_extent.Width = 0; - } - - invalidateScrollInfo = true; - - //indicate to the cleaning function that everything need to be cleaned! - m_actualFirstItem = -1; - m_actualLastItem = -1; - } - - //if one of the parameters of the IScrollInfo interface was changed, then Invalidate the ScrollInfo owner! - if( ( invalidateScrollInfo == true ) && ( m_owner != null ) ) - { - m_owner.InvalidateScrollInfo(); - } - - //call this so that the Cleanup is triggered with the latest parameters - this.SetupCleaning(); - - return desiredSize; - } - - private double ComputeMaxOpposedSize() - { - double actualMax = 0d; - foreach( double value in m_desiredSizeDictionary.Values ) - { - if( value > actualMax ) - actualMax = value; - } - - return actualMax; - } - - protected override void OnRender( DrawingContext drawingContext ) - { - base.OnRender( drawingContext ); - - Brush contentBrush = this.ContentBorderBrush; - Thickness contentThickness = this.ContentBorderThickness; - Rect usedSurface = this.UsedSurface; - - if( ( contentBrush != null ) && ( usedSurface != Rect.Empty ) ) - { - Pen myPen = new Pen( contentBrush, contentThickness.Left ); - - GuidelineSet gls = new GuidelineSet(); - gls.GuidelinesX.Add( 0 ); - gls.GuidelinesX.Add( usedSurface.Right ); - gls.GuidelinesY.Add( 0 ); - gls.GuidelinesY.Add( usedSurface.Bottom ); - - drawingContext.PushGuidelineSet( gls ); - - if( contentThickness.Left > 0 ) - { - drawingContext.DrawLine( myPen, new Point( 0 + ( contentThickness.Left / 2 ), 0 ), new Point( 0 + ( contentThickness.Left / 2 ), usedSurface.Bottom + contentThickness.Top ) ); - } - - if( contentThickness.Top > 0 ) - { - if( myPen.Thickness != contentThickness.Top ) - { - myPen = new Pen( contentBrush, contentThickness.Top ); - } - - drawingContext.DrawLine( myPen, new Point( 0, 0 + ( contentThickness.Top / 2 ) ), new Point( usedSurface.Right + contentThickness.Left, 0 + ( contentThickness.Top / 2 ) ) ); - } - - if( contentThickness.Right > 0 ) - { - if( myPen.Thickness != contentThickness.Right ) - { - myPen = new Pen( contentBrush, contentThickness.Right ); - } - - drawingContext.DrawLine( myPen, new Point( usedSurface.Right + ( contentThickness.Right / 2 ), 0 ), new Point( usedSurface.Right + ( contentThickness.Right / 2 ), usedSurface.Bottom + contentThickness.Top ) ); - } - - if( contentThickness.Bottom > 0 ) - { - if( myPen.Thickness != contentThickness.Bottom ) - { - myPen = new Pen( contentBrush, contentThickness.Bottom ); - } - - drawingContext.DrawLine( myPen, new Point( 0, usedSurface.Bottom + ( contentThickness.Bottom / 2 ) ), new Point( usedSurface.Right + contentThickness.Left, usedSurface.Bottom + ( contentThickness.Bottom / 2 ) ) ); - } - - drawingContext.Pop(); - } - } - - protected override void BringIndexIntoView( int index ) - { - ( ( ICustomVirtualizingPanel )this ).BringIntoView( index ); - } - - protected override void OnClearChildren() - { - base.OnClearChildren(); - } - - private void SetupCleaning() - { - //this function is used to setup the cleaninp of the old containers in the least possible - //intrusive way so that measure can return without processing the cleanup inline. - - //making the Cleanup asynchronous will somehow delay a little bit the Virtualization of cells, - //but, were trying to reach the best compromise between recycling and generation of items. - m_currentCleanupIndex = this.Children.Count - 1; - - if( m_cleanupOperation == null ) - { - m_cleanupOperation = this.Dispatcher.BeginInvoke( ( ( DispatcherPriority )m_initialCleanupPriority ), new CleanupHandler( DoCleanup ) ); - } - else - { - m_cleanupPriorityModifier = this.CalculateCleanupPriorityModifier(); - - if( m_cleanupPriorityModifier > 0 ) - { - m_cleanupOperation.Abort(); - m_cleanupOperation = this.Dispatcher.BeginInvoke( ( ( DispatcherPriority )m_initialCleanupPriority + m_cleanupPriorityModifier ), new CleanupHandler( DoCleanup ) ); - } - } - - } - - private void DoCleanup() - { - bool finished = this.CleanupWorker(); - if( finished == false ) - { - m_cleanupPriorityModifier = this.CalculateCleanupPriorityModifier(); - m_cleanupOperation = this.Dispatcher.BeginInvoke( ( ( DispatcherPriority )m_initialCleanupPriority + m_cleanupPriorityModifier ), new CleanupHandler( DoCleanup ) ); - } - else - { - m_cleanupOperation = null; - } - } - - private bool CleanupWorker() - { - bool retval = true; - - UIElementCollection children = this.InternalChildren; - IItemContainerGenerator generator = this.CustomItemContainerGenerator; - - if( generator != null ) - { - int viewportSize = this.GetViewportSize(); - - if( ( m_actualFirstItem == m_actualLastItem ) && ( m_actualFirstItem == -1 ) ) - { - this.RemoveInternalChildRange( 0, children.Count ); - generator.RemoveAll(); - } - else - { - int startTick = Environment.TickCount; - - while( m_currentCleanupIndex >= 0 ) - { - GeneratorPosition childGeneratorPos = new GeneratorPosition( m_currentCleanupIndex, 0 ); - int itemIndex = generator.IndexFromGeneratorPosition( childGeneratorPos ); - - if( ( itemIndex < ( m_actualFirstItem - viewportSize ) || itemIndex > ( m_actualLastItem + viewportSize ) ) && itemIndex != -1 ) - { - DependencyObject focusScope = FocusManager.GetFocusScope( children[ m_currentCleanupIndex ] ); - DependencyObject focusedElement = FocusManager.GetFocusedElement( focusScope ) as DependencyObject; - - if( ( focusedElement == null ) || ( !TreeHelper.IsDescendantOf( focusedElement, children[ m_currentCleanupIndex ] ) ) ) - { - RemoveInternalChildRange( m_currentCleanupIndex, 1 ); - generator.Remove( childGeneratorPos, 1 ); - } - } - - m_currentCleanupIndex--; - - if( Environment.TickCount - startTick > CleanupThreshold ) - { - retval = false; - break; - } - } - } - } - - return retval; - } - - private int CalculateCleanupPriorityModifier() - { - int viewportSize = this.GetViewportSize(); - - //Notes on the Algo: ViewportSize * 3 is because we want to keep 1 page before and after the actual viewport. - //Notes on the Algo: 10 - m_initialCleanupPriority is because we do not want the modifier to go beyond the scope of the enum... - return ( int )Math.Min( Math.Floor( this.InternalChildren.Count / ( viewportSize * 3d ) ) - 1, ( 10 - m_initialCleanupPriority ) ); - } - - private int GetViewportSize() - { - return ( int )( ( this.Orientation == Orientation.Vertical ) ? this.ViewportHeight : this.ViewportWidth ); - } - - private Rect MakeVisible( int childIndex, int index, Rect rectangle ) - { - this.BringIndexIntoViewHelper( childIndex, index ); - - if( this.Orientation == Orientation.Vertical ) - { - //check if the beginning of the rectangle is before the "offset" - if( rectangle.Left < this.HorizontalOffset ) - { - //then make the origin of the rectangle visible (independent of width) - this.SetHorizontalOffset( rectangle.Left ); - } - //if the right side of the rectangle is not visible - else if( rectangle.Right > ( this.HorizontalOffset + this.ViewportWidth ) ) - { - //and the rectangle is larger than viewport - if( rectangle.Width > this.ViewportWidth ) - { - //make the origin of the rectangle visible - this.SetHorizontalOffset( rectangle.Left ); - } - //and rectangle is not larger than viewport - else - { - //align the right side of the rectangle at the rightmost edge of the viewport. - this.SetHorizontalOffset( rectangle.Right - this.ViewportWidth ); - } - } - - } - else - { - //check if the beginning of the rectangle is before the "offset" - if( rectangle.Top < this.VerticalOffset ) - { - //then make the origin of the rectangle visible (independent of height) - this.SetVerticalOffset( rectangle.Top ); - } - //if the bottom of the rectangle is not visible - else if( rectangle.Bottom > ( this.VerticalOffset + this.ViewportHeight ) ) - { - //and the rectangle is higher than viewport - if( rectangle.Height > this.ViewportHeight ) - { - //make the origin of the rectangle visible - this.SetVerticalOffset( rectangle.Top ); - } - //and rectangle is not higher than viewport - else - { - //align the bottom of the rectangle at the bottom edge of the viewport. - this.SetVerticalOffset( rectangle.Bottom - this.ViewportHeight ); - } - } - } - - return rectangle; - } - - private void BringIndexIntoViewHelper( int childIndex, int itemIndex ) - { - IItemContainerGenerator generator = this.CustomItemContainerGenerator; - - if( this.Orientation == Orientation.Vertical ) - { - //Only do stuff if the item is out of the viewport. - if( itemIndex < this.VerticalOffset ) - { - //this is easy, just set the item as the first one. - this.SetVerticalOffset( itemIndex ); - } - else if( itemIndex >= this.VerticalOffset + this.ViewportHeight ) - { - //this is a little trickier... I need to determine the best possible offset to display the item passed. - int desiredChildIndex = childIndex; - int desiredOffset = itemIndex; - double cachedActualHeight = this.ActualHeight; - double totalHeight = 0; - bool passedOnce = false; - - do - { - //add the height of the current element to the total calculated height - totalHeight += this.Children[ desiredChildIndex ].RenderSize.Height; - - //if the calculated height is still lower that the size of the viewport (render size) - if( totalHeight < cachedActualHeight ) - { - int currentIndex = generator.IndexFromGeneratorPosition( new GeneratorPosition( desiredChildIndex, 0 ) ); - //if the container is not for the "next" item in line... - if( currentIndex != desiredOffset ) - { - desiredOffset++; - break; - } - else - { - desiredChildIndex--; - desiredOffset--; - passedOnce = true; - } - } - else if( passedOnce == true ) - { - //since we exceeded the constraint, go back one step - desiredOffset++; - } - - if( desiredOffset < 0 ) - { - desiredOffset = 0; - break; - } - - if( desiredChildIndex < 0 ) - { - break; - } - - - } - while( totalHeight < cachedActualHeight ); - - this.SetVerticalOffset( ( double )desiredOffset ); - } - } - else - { - //Only do stuff if the item is out of the viewport. - if( itemIndex < this.HorizontalOffset ) - { - //this is easy, just set the item as the first one. - this.SetHorizontalOffset( itemIndex ); - } - else if( itemIndex > this.HorizontalOffset + this.ViewportWidth ) - { - //this is a little trickier... I need to determine the best possible offset to display the item passed. - int desiredChildIndex = childIndex; - int desiredOffset = itemIndex; - double cachedActualWidth = this.ActualWidth; - double totalWidth = 0; - bool passedOnce = false; - - do - { - //add the height of the current element to the total calculated height - totalWidth += this.Children[ desiredChildIndex ].RenderSize.Width; - - //if the calculated height is still lower that the size of the viewport (render size) - if( totalWidth < cachedActualWidth ) - { - int currentIndex = generator.IndexFromGeneratorPosition( new GeneratorPosition( desiredChildIndex, 0 ) ); - //if the container is not for the "next" item in line... - if( currentIndex != desiredOffset ) - { - desiredOffset++; - break; - } - else - { - desiredChildIndex--; - desiredOffset--; - passedOnce = true; - } - } - else if( passedOnce == true ) - { - //since we exceeded the constraint, go back one step - desiredOffset++; - } - - if( desiredOffset < 0 ) - { - desiredOffset = 0; - break; - } - - if( desiredChildIndex < 0 ) - { - break; - } - - } - while( totalWidth < cachedActualWidth ); - - this.SetHorizontalOffset( ( double )desiredOffset ); - } - } - } - - private void OnRequestBringIntoView( object sender, RequestBringIntoViewEventArgs e ) - { - // Only perform this if we are virtualizing. - // If not, the ScrollViewer will take care of bringing the item into view. - if( ( this.ScrollOwner == null ) || ( !this.ScrollOwner.CanContentScroll ) ) - return; - - // Only perform this if the StableScrolling feature is enabled. - if( !this.StableScrollingEnabled ) - return; - - // If we are explicitly setting the focus on a cell, we don't want to bring it into view. - // A bringIntoView would cause the HorizontalOffset to change is not a wanted behavior. - // Therefore, flag the Request as handled and do nothing. - DataGridContext dataGridContext = DataGridControl.GetDataGridContext( this ); - - DataGridControl dataGridControl = ( dataGridContext != null ) - ? dataGridContext.DataGridControl - : null; - - if( ( dataGridControl != null ) && ( dataGridControl.SettingFocusOnCell ) ) - { - e.Handled = true; - return; - } - - // Only perform this if the object is NOT a Cell and was not passed a specific rectangle. - if( ( e.TargetObject is Cell ) || ( e.TargetRect != Rect.Empty ) ) - return; - - // Before performing calculations, ensure that the element is a UIElement. - FrameworkElement target = e.TargetObject as FrameworkElement; - - if( ( target == null ) || ( target.IsDescendantOf( this ) == false ) ) - return; - - Orientation orientation = this.Orientation; - - //mark the routed event as handled, since under even the worst circumstances, a new event will be raised. - e.Handled = true; - - double acceptableThreshold; - double actualVisibleValue; - - GeneralTransform itemToPanel = target.TransformToAncestor( this ); - Point itemOrigin = itemToPanel.Transform( new Point( 0, 0 ) ); - - //Calculate the VisibleWidth/Height of the object within the Viewport. - if( orientation == Orientation.Vertical ) - { - acceptableThreshold = this.ViewportWidth * this.StableScrollingProportion; - - //item offset is positive in the viewport. - if( itemOrigin.X >= 0 ) - { - //if the item is totally visible - if( target.ActualWidth + itemOrigin.X <= this.ViewportWidth ) - { - //this will force the function to "cancel" the BringIntoView - actualVisibleValue = this.ViewportWidth; - } - else - { - //item is not totally visible, calculate how much place it occupies in the viewport. - actualVisibleValue = this.ViewportWidth - itemOrigin.X; - } - } - //item offset is negative - else - { - actualVisibleValue = target.ActualWidth - itemOrigin.X; - if( actualVisibleValue > this.ViewportWidth ) - { - //limit the value of actualVisibleValue to the Viewport size (to prevent eventual bugs [even if nothing is visible on the horizon for this]) - actualVisibleValue = this.ViewportWidth; - } - } - } - else - { - acceptableThreshold = this.ViewportHeight * this.StableScrollingProportion; - - //item offset is positive in the viewport. - if( itemOrigin.Y >= 0 ) - { - //if the item is totally visible - if( target.ActualHeight + itemOrigin.Y <= this.ViewportHeight ) - { - //this will force the function to "cancel" the BringIntoView - actualVisibleValue = this.ViewportHeight; - } - else - { - //item is not totally visible, calculate how much place it occupies in the viewport. - actualVisibleValue = this.ViewportHeight - itemOrigin.Y; - } - } - //item offset is negative - else - { - actualVisibleValue = target.ActualHeight - itemOrigin.Y; - if( actualVisibleValue > this.ViewportHeight ) - { - //limit the value of actualVisibleValue to the Viewport size (to prevent eventual bugs [even if nothing is visible on the horizon for this]) - actualVisibleValue = this.ViewportHeight; - } - } - } - - bool needBringIntoView = false; - Rect newRect = new Rect( 0, 0, target.ActualWidth, target.ActualHeight ); - - //After the proportion visible from the object is calculated, compare with threshold - if( actualVisibleValue < acceptableThreshold ) - { - needBringIntoView = true; - //the required threshold is not visible, modify the bounds of the rectangle - //to bring at Max, the desired threshold. - if( orientation == Orientation.Vertical ) - { - if( itemOrigin.X >= 0 ) - { - newRect.Width = Math.Min( acceptableThreshold, target.ActualWidth ); - } - else - { - newRect.X = target.ActualWidth - acceptableThreshold; - if( newRect.X < 0 ) - { - newRect.X = 0; - } - } - } - else - { - if( itemOrigin.Y >= 0 ) - { - newRect.Height = Math.Min( acceptableThreshold, target.ActualHeight ); - } - else - { - newRect.Y = target.ActualHeight - acceptableThreshold; - if( newRect.Y < 0 ) - { - newRect.Y = 0; - } - } - }//end else orientation is Horizontal - } // end if actuallyVisible < acceptable threshold - else - { - //Determine if the item is totally or partially visible on the main scrolling axis. - if( orientation == Orientation.Vertical ) - { - //If the Offset is negative, then it's sure its not totally visible - if( itemOrigin.Y < 0 ) - { - needBringIntoView = true; - } - else if( ( ( itemOrigin.Y + target.DesiredSize.Height ) > this.RenderSize.Height ) && ( target.DesiredSize.Height < this.RenderSize.Height ) ) - { - needBringIntoView = true; - } - } - else - { - //If the Offset is negative, then it's sure its not totally visible - if( itemOrigin.X < 0 ) - { - needBringIntoView = true; - } - else if( ( ( itemOrigin.X + target.DesiredSize.Width ) > this.RenderSize.Width ) && ( target.DesiredSize.Width < this.RenderSize.Width ) ) - { - needBringIntoView = true; - } - } - - //if the item need to be scrolled in view - if( needBringIntoView == true ) - { - //the goal is to preserve the actual opposed axis scrolling - if( orientation == Orientation.Vertical ) - { - //calculate the starting point of the rectangle to view. - newRect.X = itemOrigin.X * -1; - if( newRect.X < 0 ) - { - newRect.X = 0; - } - - //if the item to be brough into view is part of the elements in a TableView that do no scroll - if( ( dataGridControl != null ) - && ( dataGridControl.GetView() is TableView ) - && ( this.ComputedCanScrollHorizontally( target ) == false ) ) - { - //then do not change the HorizontalOffset... set the same on the object as previously availlable. - newRect.X = this.HorizontalOffset; - } - - - //if the rectangle of the object goes beyond the Viewport - if( newRect.Right > this.ViewportWidth ) - { - //subtract what goes beyond! - newRect.Width = newRect.Width - ( newRect.Width - this.ViewportWidth ) - Math.Max( itemOrigin.X, 0 ); - } - } - else - { - //calculate the staring point if the rectangle to view. - newRect.Y = itemOrigin.Y * -1; - if( newRect.Y < 0 ) - { - newRect.Y = 0; - } - - //if the rectangle of the object goes beyond the Viewport - if( newRect.Bottom > this.ViewportHeight ) - { - //subtract what goes beyond! - newRect.Height = newRect.Height - ( newRect.Height - this.ViewportHeight ) - Math.Max( itemOrigin.Y, 0 ); - } - } - } // end if needBringIntoView == true - } // end else - - - //Call a new BringIntoView on the target element - if( needBringIntoView == true ) - target.BringIntoView( newRect ); - } - - private bool ComputedCanScrollHorizontally( FrameworkElement target ) - { - Debug.Assert( target != null ); - - bool retval = true; - - DependencyObject visual = target; - - do - { - retval = TableView.GetCanScrollHorizontally( visual ); - - if( retval == true ) - { - visual = TreeHelper.GetParent( visual ); - } - } - while( ( visual != null ) && ( visual != this ) && ( retval == true ) ); - - return retval; - } - - private void InvalidateMeasureHelper( Orientation orientation ) - { - if( ( m_layoutSuspended == true ) && ( m_layoutSuspendedOrientation == orientation ) ) - { - m_layoutInvalidated = true; - } - else - { - this.InvalidateMeasure(); - - m_layoutInvalidated = false; - } - - } - - #region ICustomVirtualizingPanel Members - - void ICustomVirtualizingPanel.BringIntoView( int index ) - { - if( this.Orientation == Orientation.Vertical ) - { - //if the item is the first item out of the viewport (partially visible) - if( index == ( this.VerticalOffset + this.ViewportHeight ) ) - { - //shift the Viewport 1 item up - this.SetVerticalOffset( this.VerticalOffset + 1 ); - } - else - { - //otherwise, if the item is below or above viewport, then bring it as the first item in the viewport - if( ( index < this.VerticalOffset ) || ( index > this.VerticalOffset + this.ViewportHeight ) ) - { - this.SetVerticalOffset( index ); - } - } - } - else - { - //if the item is the first item out of the viewport (partially visible) - if( index == ( this.HorizontalOffset + this.ViewportWidth ) ) - { - //shift the Viewport 1 item up - this.SetHorizontalOffset( this.HorizontalOffset + 1 ); - } - else - { - //otherwise, if the item is below or above viewport, then bring it as the first item in the viewport - if( ( index < this.HorizontalOffset ) || ( index > this.HorizontalOffset + this.ViewportWidth ) ) - { - this.SetHorizontalOffset( index ); - } - } - } - } - - #endregion - - #region IScrollInfo Members - - public bool CanHorizontallyScroll - { - get - { - return m_canHScroll; - } - set - { - m_canHScroll = value; - } - } - - public bool CanVerticallyScroll - { - get - { - return m_canVScroll; - } - set - { - m_canVScroll = value; - } - } - - public double ExtentHeight - { - get - { - return m_extent.Height; - } - } - - public double ExtentWidth - { - get - { - return m_extent.Width; - } - } - - public double HorizontalOffset - { - get - { - return m_offset.X; - } - } - - public void LineDown() - { - double verticalOffset = this.VerticalOffset; - - // Prevent scrolling if we are already showing the last item. - if( this.ExtentHeight <= ( verticalOffset + this.ViewportHeight ) ) - return; - - if( this.Orientation == Orientation.Vertical ) - { - this.SetVerticalOffset( verticalOffset + 1 ); - } - else - { - this.SetVerticalOffset( verticalOffset + ScrollViewerHelper.PixelScrollingCount ); - } - } - - public void LineLeft() - { - if( this.Orientation == Orientation.Horizontal ) - { - this.SetHorizontalOffset( this.HorizontalOffset - 1 ); - } - else - { - this.SetHorizontalOffset( this.HorizontalOffset - ScrollViewerHelper.PixelScrollingCount ); - } - } - - public void LineRight() - { - double horizontalOffset = this.HorizontalOffset; - - // Prevent scrolling if we are already showing the last item. - if( this.ExtentWidth <= ( horizontalOffset + this.ViewportWidth ) ) - return; - - if( this.Orientation == Orientation.Horizontal ) - { - this.SetHorizontalOffset( horizontalOffset + 1 ); - } - else - { - this.SetHorizontalOffset( horizontalOffset + ScrollViewerHelper.PixelScrollingCount ); - } - } - - public void LineUp() - { - if( this.Orientation == Orientation.Vertical ) - { - this.SetVerticalOffset( this.VerticalOffset - 1 ); - } - else - { - this.SetVerticalOffset( this.VerticalOffset - ScrollViewerHelper.PixelScrollingCount ); - } - } - - public Rect MakeVisible( Visual visual, Rect rectangle ) - { - UIElementCollection children = this.InternalChildren; - IItemContainerGenerator generator = this.CustomItemContainerGenerator; - - Rect actualRect = rectangle; - - //determine the index of the internal child for this visual - int internalChildIndex = children.IndexOf( ( UIElement )visual ); - - //if the visual is not a direct child of the panel - if( internalChildIndex == -1 ) - { - bool foundAncestor = false; - //cycle through all the visual children of the panel - foreach( UIElement element in children ) - { - //if the visual child of the panel is the ancestor of the given visual - if( element.IsAncestorOf( visual ) == true ) - { - //store the visual child index - internalChildIndex = children.IndexOf( element ); - - //transform the given rectangle into the actual child coordinate system - actualRect = visual.TransformToAncestor( element ).TransformBounds( rectangle ); - - foundAncestor = true; - break; - } - } - - Debug.Assert( foundAncestor == true, "Cannot find the actual child for the given Visual" ); - } - - int itemIndex = generator.IndexFromGeneratorPosition( new GeneratorPosition( internalChildIndex, 0 ) ); - - if( itemIndex != -1 ) - { - return MakeVisible( internalChildIndex, itemIndex, actualRect ); - } - else - { - return actualRect; - } - } - - public void MouseWheelDown() - { - double verticalOffset = this.VerticalOffset; - - // Prevent scrolling if we are already showing the last item. - if( this.ExtentHeight <= ( verticalOffset + this.ViewportHeight ) ) - return; - - if( this.Orientation == Orientation.Vertical ) - { - this.SetVerticalOffset( verticalOffset + SystemParameters.WheelScrollLines ); - } - else - { - this.SetVerticalOffset( verticalOffset - + ( SystemParameters.WheelScrollLines * ScrollViewerHelper.PixelScrollingCount ) ); - } - } - - public void MouseWheelLeft() - { - if( this.Orientation == Orientation.Horizontal ) - { - this.SetHorizontalOffset( this.HorizontalOffset - SystemParameters.WheelScrollLines ); - } - else - { - this.SetHorizontalOffset( this.HorizontalOffset - - ( SystemParameters.WheelScrollLines * ScrollViewerHelper.PixelScrollingCount ) ); - } - } - - public void MouseWheelRight() - { - double horizontalOffset = this.HorizontalOffset; - - // Prevent scrolling if we are already showing the last item. - if( this.ExtentWidth <= ( horizontalOffset + this.ViewportWidth ) ) - return; - - if( this.Orientation == Orientation.Horizontal ) - { - this.SetHorizontalOffset( horizontalOffset + SystemParameters.WheelScrollLines ); - } - else - { - this.SetHorizontalOffset( horizontalOffset - + ( SystemParameters.WheelScrollLines * ScrollViewerHelper.PixelScrollingCount ) ); - } - } - - public void MouseWheelUp() - { - if( this.Orientation == Orientation.Vertical ) - { - this.SetVerticalOffset( this.VerticalOffset - SystemParameters.WheelScrollLines ); - } - else - { - this.SetVerticalOffset( this.VerticalOffset - - ( SystemParameters.WheelScrollLines * ScrollViewerHelper.PixelScrollingCount ) ); - } - } - - public void PageDown() - { - double scrollOffset = ( this.ViewportHeight + this.VerticalOffset ); - - // Prevent scrolling if we are already showing the last item. - if( this.ExtentHeight <= scrollOffset ) - return; - - this.SetVerticalOffset( scrollOffset ); - } - - public void PageLeft() - { - this.SetHorizontalOffset( this.HorizontalOffset - this.ViewportWidth ); - } - - public void PageRight() - { - double scrollOffset = ( this.HorizontalOffset + this.ViewportWidth ); - - // Prevent scrolling if we are already showing the last item. - if( this.ExtentWidth <= scrollOffset ) - return; - - this.SetHorizontalOffset( scrollOffset ); - } - - public void PageUp() - { - this.SetVerticalOffset( this.VerticalOffset - this.ViewportHeight ); - } - - public ScrollViewer ScrollOwner - { - get - { - return m_owner; - } - set - { - m_owner = value; - } - } - - public void SetHorizontalOffset( double offset ) - { - bool invalidate = false; - - Orientation orientation = this.Orientation; - - if( Double.IsInfinity( offset ) == true ) - { - if( offset == Double.PositiveInfinity ) - { - if( orientation == Orientation.Horizontal ) - { - offset = this.ExtentWidth - 1; - } - else - { - offset = this.ExtentWidth - this.ViewportWidth; - } - } - else //negative infinity - { - offset = 0; - } - } - else - { - double width = ( orientation == Orientation.Vertical ) ? this.ExtentWidth : this.ItemCount; - - if( offset < 0 || m_viewport.Width >= width ) - { - offset = 0; - } - else - { - if( orientation == Orientation.Horizontal ) - { - if( offset >= width ) - { - offset = width - 1; - } - } - else - { - if( offset > ( width - m_viewport.Width ) ) - { - offset = width - m_viewport.Width; - } - } - } - } - - if( m_offset.X != offset ) - { - m_offset.X = offset; - invalidate = true; - } - - if( invalidate == true ) - { - if( m_owner != null ) - m_owner.InvalidateScrollInfo(); - - this.InvalidateMeasureHelper( Orientation.Horizontal ); - } - } - - public void SetVerticalOffset( double offset ) - { - bool invalidate = false; - - Orientation orientation = this.Orientation; - - if( Double.IsInfinity( offset ) == true ) - { - if( offset == Double.PositiveInfinity ) - { - if( orientation == Orientation.Vertical ) - { - offset = this.ExtentHeight - 1; - } - else - { - offset = this.ExtentHeight - this.ViewportHeight; - } - } - else //negative infinity - { - offset = 0; - } - } - else - { - double height = ( orientation == Orientation.Horizontal ) ? this.ExtentHeight : this.ItemCount; - - if( offset < 0 || m_viewport.Height >= height ) - { - offset = 0; - } - else - { - if( orientation == Orientation.Vertical ) - { - if( offset >= height ) - { - offset = height - 1; - } - } - else - { - if( offset > ( height - m_viewport.Height ) ) - { - offset = height - m_viewport.Height; - } - } - } - } - - if( m_offset.Y != offset ) - { - m_offset.Y = offset; - invalidate = true; - } - - if( invalidate == true ) - { - if( m_owner != null ) - m_owner.InvalidateScrollInfo(); - - this.InvalidateMeasureHelper( Orientation.Vertical ); - } - } - - public double VerticalOffset - { - get - { - return m_offset.Y; - } - } - - public double ViewportHeight - { - get - { - return m_viewport.Height; - } - } - - public double ViewportWidth - { - get - { - return m_viewport.Width; - } - } - - #endregion - - #region IDeferableScrollInfoRefresh Members - - IDisposable IDeferableScrollInfoRefresh.DeferScrollInfoRefresh( Orientation orientation ) - { - if( this.Orientation == orientation ) - { - return new LayoutSuspendedHelper( this, orientation ); - } - - return null; - } - - #endregion - - private bool m_canHScroll = false; - private bool m_canVScroll = false; - private ScrollViewer m_owner = null; - private Size m_extent = new Size( 0, 0 ); - private Size m_viewport = new Size( 0, 0 ); - private Point m_offset = new Point( 0, 0 ); - - private int m_actualFirstItem = -1; - private int m_actualLastItem = -1; - - //Those 3 members are used in conjunction with the IDeferableScrollInfoRefresh interface - private bool m_layoutSuspended; // = false - private Orientation m_layoutSuspendedOrientation; - private bool m_layoutInvalidated; // = false - - private DispatcherOperation m_cleanupOperation = null; - private int m_currentCleanupIndex = -1; - - private int m_initialCleanupPriority = ( ( int )DispatcherPriority.Background ); - private int m_cleanupPriorityModifier = 0; - - private Dictionary m_desiredSizeDictionary = new Dictionary(); - private Dictionary m_previousSizeDictionary = new Dictionary(); - - private delegate void CleanupHandler(); - - private static readonly Thickness DefaultThickness = new Thickness(); - private static readonly Size InfiniteSize = new Size( Double.PositiveInfinity, Double.PositiveInfinity ); - - private sealed class LayoutSuspendedHelper : IDisposable - { - public LayoutSuspendedHelper( VirtualizingStackPanel panel, Orientation orientation ) - { - if( panel == null ) - throw new ArgumentNullException( "panel" ); - - m_panel = panel; - - m_panel.m_layoutSuspendedOrientation = orientation; - m_panel.m_layoutSuspended = true; - } - - #region IDisposable Members - - public void Dispose() - { - m_panel.m_layoutSuspended = false; - - if( m_panel.m_layoutInvalidated == true ) - { - m_panel.InvalidateMeasureHelper( m_panel.m_layoutSuspendedOrientation ); - } - } - - #endregion - - private VirtualizingStackPanel m_panel; // = null - } - } -} diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Xceed.Wpf.DataGrid.csproj b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Xceed.Wpf.DataGrid.csproj deleted file mode 100644 index 74743f09..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/Xceed.Wpf.DataGrid.csproj +++ /dev/null @@ -1,1071 +0,0 @@ - - - - Debug - AnyCPU - {63648392-6CE9-4A60-96D4-F9FD718D29B0} - {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - Xceed.Wpf.DataGrid - Xceed.Wpf.DataGrid - 4 - library - - v4.0 - - - 3.5 - - - false - Client - false - - - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - true - - - true - full - false - .\bin\Debug\ - TRACE;DEBUG;XBAP_FRIENDLY - - - 1699 - 125829120 - AllRules.ruleset - prompt - - - true - true - .\bin\Release\ - TRACE;CODE_ANALYSIS;XBAP_FRIENDLY - - - 1699 - false - - - 125829120 - AllRules.ruleset - prompt - pdbonly - - - - - - - - - 3.5 - - - - 3.5 - - - - - - - 3.0 - - - 3.0 - - - 3.0 - - - 3.0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CustomItemContainerGenerator.cs - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - DataGridControlBackgroundBrushesResources.xaml - - - - - - - - - - - - - - - - - - - - Code - - - Code - - - - - Code - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Code - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Code - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - Designer - MSBuild:Compile - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - Designer - MSBuild:Compile - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - Designer - MSBuild:Compile - MSBuild:Compile - Designer - - - Designer - MSBuild:Compile - MSBuild:Compile - Designer - - - Designer - MSBuild:Compile - MSBuild:Compile - Designer - - - Designer - MSBuild:Compile - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - Designer - MSBuild:Compile - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile - Designer - - - Designer - MSBuild:Compile - MSBuild:Compile - Designer - - - - - - - - - - - False - Microsoft .NET Framework 4 %28x86 and x64%29 - true - - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 3.5 SP1 - false - - - False - Microsoft Visual Basic PowerPacks 10.0 - true - - - False - Windows Installer 3.1 - true - - - - - {72e591d6-8f83-4d8c-8f67-9c325e623234} - Xceed.Wpf.Toolkit - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/sn.snk b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/sn.snk deleted file mode 100644 index 1bdc9120..00000000 Binary files a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/sn.snk and /dev/null differ diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Aero/Resources/Aero.Resources.xaml b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Aero/Resources/Aero.Resources.xaml deleted file mode 100644 index ae69bff0..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Aero/Resources/Aero.Resources.xaml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Aero/Resources/Aero.normalcolor.Resources.xaml b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Aero/Resources/Aero.normalcolor.Resources.xaml deleted file mode 100644 index ccc95ca7..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Aero/Resources/Aero.normalcolor.Resources.xaml +++ /dev/null @@ -1,520 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Aero/Resources/TableView.Aero.Graphics.xaml b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Aero/Resources/TableView.Aero.Graphics.xaml deleted file mode 100644 index c345fcf3..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Aero/Resources/TableView.Aero.Graphics.xaml +++ /dev/null @@ -1,242 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Aero/TableView.Aero.normalcolor.xaml b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Aero/TableView.Aero.normalcolor.xaml deleted file mode 100644 index 780cd1cd..00000000 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.DataGrid/themes/Aero/TableView.Aero.normalcolor.xaml +++ /dev/null @@ -1,2789 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -