From 9852cbb9d01e38805cd2c5e1a209718b9a153698 Mon Sep 17 00:00:00 2001 From: punker76 Date: Mon, 20 Sep 2021 22:45:03 +0200 Subject: [PATCH 01/29] Fix Costura.Fody usage, set v3.0.0 - set min target to v4.5.2 - add v4.8 target - remove .NET Core v3.0 target --- GitVersion.yml | 2 +- src/global.json => global.json | 0 src/Directory.build.props | 15 +++++++++--- src/Showcase/App.net45.config | 6 ----- src/Showcase/App.net46.config | 6 ----- src/Showcase/App.net462.config | 6 ----- src/Showcase/App.net47.config | 6 ----- src/Showcase/FodyWeavers.xsd | 30 +++++++++++++++++++++++ src/Showcase/Showcase.WPF.DragDrop.csproj | 8 ++---- 9 files changed, 44 insertions(+), 35 deletions(-) rename src/global.json => global.json (100%) delete mode 100644 src/Showcase/App.net45.config delete mode 100644 src/Showcase/App.net46.config delete mode 100644 src/Showcase/App.net462.config delete mode 100644 src/Showcase/App.net47.config diff --git a/GitVersion.yml b/GitVersion.yml index bdda27f5..a2441740 100644 --- a/GitVersion.yml +++ b/GitVersion.yml @@ -1,6 +1,6 @@ assembly-versioning-scheme: Major assembly-file-versioning-scheme: MajorMinorPatchTag -next-version: 2.4.0 +next-version: 3.0.0 mode: ContinuousDeployment branches: master: diff --git a/src/global.json b/global.json similarity index 100% rename from src/global.json rename to global.json diff --git a/src/Directory.build.props b/src/Directory.build.props index 56866552..da1609a4 100644 --- a/src/Directory.build.props +++ b/src/Directory.build.props @@ -6,13 +6,14 @@ - net45;net46;net462;net47;netcoreapp3.0;netcoreapp3.1;net5-windows + net452;net46;net462;net47;net48;netcoreapp3.1;net5-windows true false true + + latest latest - true - full + $(NoWarn);CS1591 $(NoError);CS1591 true @@ -26,15 +27,21 @@ true - + false true + embedded + true $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb + + + + diff --git a/src/Showcase/App.net45.config b/src/Showcase/App.net45.config deleted file mode 100644 index 38d47cd8..00000000 --- a/src/Showcase/App.net45.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/Showcase/App.net46.config b/src/Showcase/App.net46.config deleted file mode 100644 index 69f72246..00000000 --- a/src/Showcase/App.net46.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/Showcase/App.net462.config b/src/Showcase/App.net462.config deleted file mode 100644 index 3470d2d7..00000000 --- a/src/Showcase/App.net462.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/Showcase/App.net47.config b/src/Showcase/App.net47.config deleted file mode 100644 index 174c45ab..00000000 --- a/src/Showcase/App.net47.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/Showcase/FodyWeavers.xsd b/src/Showcase/FodyWeavers.xsd index 44a53744..05e92c11 100644 --- a/src/Showcase/FodyWeavers.xsd +++ b/src/Showcase/FodyWeavers.xsd @@ -17,6 +17,16 @@ A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks. + + + A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks + + + + + A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks. + + A list of unmanaged 32 bit assembly names to include, delimited with line breaks. @@ -43,6 +53,16 @@ Controls if .pdbs for reference assemblies are also embedded. + + + Controls if runtime assemblies are also embedded. + + + + + Controls whether the runtime assemblies are embedded with their full path or only with their assembly name. + + Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option. @@ -73,6 +93,16 @@ A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |. + + + A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with | + + + + + A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with |. + + A list of unmanaged 32 bit assembly names to include, delimited with |. diff --git a/src/Showcase/Showcase.WPF.DragDrop.csproj b/src/Showcase/Showcase.WPF.DragDrop.csproj index 88158bc0..f71ca229 100644 --- a/src/Showcase/Showcase.WPF.DragDrop.csproj +++ b/src/Showcase/Showcase.WPF.DragDrop.csproj @@ -28,19 +28,15 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + - - - $(AssemblyName).exe.config - From 7e6c4d2a7328d14495b6feb4380f04e1c9213caa Mon Sep 17 00:00:00 2001 From: punker76 Date: Mon, 20 Sep 2021 23:07:12 +0200 Subject: [PATCH 02/29] Add .NET 6 target --- README.md | 2 +- appveyor.yml | 4 ++-- global.json | 2 +- src/Directory.build.props | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 25e75408..02a0caa4 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ An easy to use drag'n'drop framework for WPF.

- Supporting .NET Framework 4.5+, .NET Core 3 (3.0 and 3.1), and .NET 5 (on Windows) + Supporting .NET Framework 4.5.2+, .NET Core 3.1, .NET 5 and .NET 6 (on Windows)

diff --git a/appveyor.yml b/appveyor.yml index 77f00ced..26433da2 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -17,12 +17,12 @@ environment: secure: BSPdW2TgnQtoQXXbeDECug== skip_tags: true -image: Visual Studio 2019 +image: Visual Studio 2019 Preview test: off install: - ps: Invoke-WebRequest 'https://dot.net/v1/dotnet-install.ps1' -OutFile 'dotnet-install.ps1' - - ps: ./dotnet-install.ps1 -Version 5.0.301 -InstallDir "C:\Program Files\dotnet" + - ps: ./dotnet-install.ps1 -Version 6.0.100 -InstallDir "C:\Program Files\dotnet" pull_requests: do_not_increment_build_number: false diff --git a/global.json b/global.json index 3b0cbe3b..0671e9a9 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "5.0.301", + "version": "6.0.*", "rollForward": "latestFeature" } } \ No newline at end of file diff --git a/src/Directory.build.props b/src/Directory.build.props index da1609a4..64434105 100644 --- a/src/Directory.build.props +++ b/src/Directory.build.props @@ -6,7 +6,7 @@ - net452;net46;net462;net47;net48;netcoreapp3.1;net5-windows + net452;net46;net462;net47;net48;netcoreapp3.1;net5.0-windows;net6.0-windows true false true From d5deb8e5c3be00d105785a9b7bf32a2ae278847b Mon Sep 17 00:00:00 2001 From: punker76 Date: Tue, 21 Sep 2021 08:44:20 +0200 Subject: [PATCH 03/29] DebugType = full --- src/Directory.build.props | 19 ----------- src/Directory.build.targets | 8 ++--- .../Directory.Build.props | 32 +++++++++++++++++++ .../GongSolutions.WPF.DragDrop.csproj | 7 ---- 4 files changed, 36 insertions(+), 30 deletions(-) create mode 100644 src/GongSolutions.WPF.DragDrop/Directory.Build.props diff --git a/src/Directory.build.props b/src/Directory.build.props index 64434105..70a8fcb3 100644 --- a/src/Directory.build.props +++ b/src/Directory.build.props @@ -23,25 +23,6 @@ $(DefineConstants);NET5_0_OR_GREATER - - - - true - false - - true - embedded - true - - $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb - - - - - - - - diff --git a/src/Directory.build.targets b/src/Directory.build.targets index d3f09c42..1c58d300 100644 --- a/src/Directory.build.targets +++ b/src/Directory.build.targets @@ -8,10 +8,10 @@ An easy to use drag'n'drop framework for WPF applications. true - 2.0.0.0 - 2.0.0.0 - 2.0.0.0 - 2.0.0.0 + 3.0.0.0 + 3.0.0.0 + 3.0.0.0 + 3.0.0.0
diff --git a/src/GongSolutions.WPF.DragDrop/Directory.Build.props b/src/GongSolutions.WPF.DragDrop/Directory.Build.props new file mode 100644 index 00000000..a4fe0d44 --- /dev/null +++ b/src/GongSolutions.WPF.DragDrop/Directory.Build.props @@ -0,0 +1,32 @@ + + + + + + true + false + + true + + full + true + + $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers + + + + + \ No newline at end of file diff --git a/src/GongSolutions.WPF.DragDrop/GongSolutions.WPF.DragDrop.csproj b/src/GongSolutions.WPF.DragDrop/GongSolutions.WPF.DragDrop.csproj index f11d732d..c3e8ed60 100644 --- a/src/GongSolutions.WPF.DragDrop/GongSolutions.WPF.DragDrop.csproj +++ b/src/GongSolutions.WPF.DragDrop/GongSolutions.WPF.DragDrop.csproj @@ -7,11 +7,4 @@ GongSolutions.Wpf.DragDrop true - - - - all - runtime; build; native; contentfiles; analyzers - - \ No newline at end of file From cf903dfc37eadd92a04f07c6981cd3969f2098f2 Mon Sep 17 00:00:00 2001 From: "daniel.banda" Date: Thu, 30 Sep 2021 12:54:16 -0700 Subject: [PATCH 04/29] Enable support for 3rd party controls. IDragInfoBuilder enables the specification of a DragInfo factory method to handle unsupported 3rd controls. --- .../DragDrop.Properties.cs | 24 ++++++++++++ src/GongSolutions.WPF.DragDrop/DragDrop.cs | 16 +++++++- src/GongSolutions.WPF.DragDrop/DragInfo.cs | 26 ++++++------- .../GongSolutions.WPF.DragDrop.csproj | 1 + .../IDragInfoBuilder.cs | 37 +++++++++++++++++++ 5 files changed, 89 insertions(+), 15 deletions(-) create mode 100644 src/GongSolutions.WPF.DragDrop/IDragInfoBuilder.cs diff --git a/src/GongSolutions.WPF.DragDrop/DragDrop.Properties.cs b/src/GongSolutions.WPF.DragDrop/DragDrop.Properties.cs index 9e604428..88fe0e87 100644 --- a/src/GongSolutions.WPF.DragDrop/DragDrop.Properties.cs +++ b/src/GongSolutions.WPF.DragDrop/DragDrop.Properties.cs @@ -401,6 +401,30 @@ public static void SetDropHandler(UIElement target, IDropTarget value) target.SetValue(DropHandlerProperty, value); } + /// + /// Gets or sets the drag info builder for the drag operation. + /// + public static readonly DependencyProperty DragInfoBuilderProperty + = DependencyProperty.RegisterAttached("DragInfoBuilder", + typeof(IDragInfoBuilder), + typeof(DragDrop)); + + /// + /// Gets the drag info builder for the drag operation. + /// + public static IDragInfoBuilder GetDragInfoBuilder(DependencyObject element) + { + return (IDragInfoBuilder)element.GetValue(DragInfoBuilderProperty); + } + + /// + /// Sets the drag info builder for the drag operation. + /// + public static void SetDragInfoBuilder(DependencyObject element, IDragInfoBuilder value) + { + element.SetValue(DragInfoBuilderProperty, value); + } + /// /// Gets or sets the ScrollingMode for the drop operation. /// diff --git a/src/GongSolutions.WPF.DragDrop/DragDrop.cs b/src/GongSolutions.WPF.DragDrop/DragDrop.cs index abe1413b..3be2a37d 100644 --- a/src/GongSolutions.WPF.DragDrop/DragDrop.cs +++ b/src/GongSolutions.WPF.DragDrop/DragDrop.cs @@ -274,6 +274,16 @@ private static IDropTarget TryGetDropHandler(DropInfo dropInfo, UIElement sender return dropHandler ?? DefaultDropHandler; } + /// + /// Gets the drag info builder from the sender. + /// + /// the sender from an event, e.g. drag over + /// + private static IDragInfoBuilder TryGetDragInfoBuilder(DependencyObject sender) + { + return GetDragInfoBuilder(sender); + } + /// /// Gets the RootElementFinder from the sender or uses the default implementation, if it's null. /// @@ -344,7 +354,8 @@ private static void DragSourceOnTouchDown(object sender, TouchEventArgs e) return; } - var dragInfo = new DragInfo(sender, e); + var infoBuilder = TryGetDragInfoBuilder(sender as DependencyObject); + var dragInfo = infoBuilder?.CreateDragInfo(sender, e) ?? new DragInfo(sender, e); DragSourceDown(sender, dragInfo, e); } @@ -365,7 +376,8 @@ private static void DoMouseButtonDown(object sender, MouseButtonEventArgs e) return; } - var dragInfo = new DragInfo(sender, e); + var infoBuilder = TryGetDragInfoBuilder(sender as DependencyObject); + var dragInfo = infoBuilder?.CreateDragInfo(sender, e) ?? new DragInfo(sender, e); DragSourceDown(sender, dragInfo, e); } diff --git a/src/GongSolutions.WPF.DragDrop/DragInfo.cs b/src/GongSolutions.WPF.DragDrop/DragInfo.cs index 09f2d53f..59506ff8 100644 --- a/src/GongSolutions.WPF.DragDrop/DragInfo.cs +++ b/src/GongSolutions.WPF.DragDrop/DragInfo.cs @@ -81,40 +81,40 @@ internal void RefreshSelectedItems(object sender) public object Data { get; set; } /// - public Point DragStartPosition { get; private set; } + public Point DragStartPosition { get; protected set; } /// - public Point PositionInDraggedItem { get; private set; } + public Point PositionInDraggedItem { get; protected set; } /// public DragDropEffects Effects { get; set; } /// - public MouseButton MouseButton { get; private set; } + public MouseButton MouseButton { get; protected set; } /// - public IEnumerable SourceCollection { get; private set; } + public IEnumerable SourceCollection { get; protected set; } /// - public int SourceIndex { get; private set; } + public int SourceIndex { get; protected set; } /// - public object SourceItem { get; private set; } + public object SourceItem { get; protected set; } /// - public IEnumerable SourceItems { get; private set; } + public IEnumerable SourceItems { get; protected set; } /// - public CollectionViewGroup SourceGroup { get; private set; } + public CollectionViewGroup SourceGroup { get; protected set; } /// - public UIElement VisualSource { get; private set; } + public UIElement VisualSource { get; protected set; } /// - public UIElement VisualSourceItem { get; private set; } + public UIElement VisualSourceItem { get; protected set; } /// - public FlowDirection VisualSourceFlowDirection { get; private set; } + public FlowDirection VisualSourceFlowDirection { get; protected set; } /// public object DataObject { get; set; } @@ -123,9 +123,9 @@ internal void RefreshSelectedItems(object sender) public Func DragDropHandler { get; set; } = System.Windows.DragDrop.DoDragDrop; /// - public DragDropKeyStates DragDropCopyKeyState { get; private set; } + public DragDropKeyStates DragDropCopyKeyState { get; protected set; } - private void InitializeDragInfo(object sender, object originalSource, Func getPosition) + protected virtual void InitializeDragInfo(object sender, object originalSource, Func getPosition) { this.Effects = DragDropEffects.None; this.VisualSource = sender as UIElement; diff --git a/src/GongSolutions.WPF.DragDrop/GongSolutions.WPF.DragDrop.csproj b/src/GongSolutions.WPF.DragDrop/GongSolutions.WPF.DragDrop.csproj index c3e8ed60..1a3896f7 100644 --- a/src/GongSolutions.WPF.DragDrop/GongSolutions.WPF.DragDrop.csproj +++ b/src/GongSolutions.WPF.DragDrop/GongSolutions.WPF.DragDrop.csproj @@ -2,6 +2,7 @@ + net5.0-windows GongSolutions.WPF.DragDrop gong-wpf-dragdrop GongSolutions.Wpf.DragDrop diff --git a/src/GongSolutions.WPF.DragDrop/IDragInfoBuilder.cs b/src/GongSolutions.WPF.DragDrop/IDragInfoBuilder.cs new file mode 100644 index 00000000..bffce41d --- /dev/null +++ b/src/GongSolutions.WPF.DragDrop/IDragInfoBuilder.cs @@ -0,0 +1,37 @@ +using System.Windows.Input; + +namespace GongSolutions.Wpf.DragDrop +{ + /// + /// Interface implemented by Drag Info Builders. + /// It enables custom construction of DragInfo objects from 3rd party controls like DevExpress, Telerik, etc. + /// + public interface IDragInfoBuilder + { + /// + /// Creates a drag info object from . + /// + /// + /// + /// The sender of the mouse event that initiated the drag. + /// + /// + /// + /// The mouse event that initiated the drag. + /// + DragInfo CreateDragInfo(object sender, MouseButtonEventArgs e); + + /// + /// Creates a drag info object from . + /// + /// + /// + /// The sender of the touch event that initiated the drag. + /// + /// + /// + /// The touch event that initiated the drag. + /// + DragInfo CreateDragInfo(object sender, TouchEventArgs e); + } +} \ No newline at end of file From 8b7e2d31c1d0b80dc80cca140b9a6fb98cd60de9 Mon Sep 17 00:00:00 2001 From: "daniel.banda" Date: Thu, 30 Sep 2021 12:57:59 -0700 Subject: [PATCH 05/29] Update IDragInfoBuilder.cs Improved comments. --- src/GongSolutions.WPF.DragDrop/IDragInfoBuilder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GongSolutions.WPF.DragDrop/IDragInfoBuilder.cs b/src/GongSolutions.WPF.DragDrop/IDragInfoBuilder.cs index bffce41d..7511b590 100644 --- a/src/GongSolutions.WPF.DragDrop/IDragInfoBuilder.cs +++ b/src/GongSolutions.WPF.DragDrop/IDragInfoBuilder.cs @@ -4,7 +4,7 @@ namespace GongSolutions.Wpf.DragDrop { /// /// Interface implemented by Drag Info Builders. - /// It enables custom construction of DragInfo objects from 3rd party controls like DevExpress, Telerik, etc. + /// It enables custom construction of DragInfo objects to support 3rd party controls like DevExpress, Telerik, etc. /// public interface IDragInfoBuilder { From 527d59ebb879a7b6651872b051150fb153cb00f2 Mon Sep 17 00:00:00 2001 From: "daniel.banda" Date: Thu, 30 Sep 2021 13:23:57 -0700 Subject: [PATCH 06/29] Reverting accidental commit Reverting unintended change. --- src/GongSolutions.WPF.DragDrop/GongSolutions.WPF.DragDrop.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/src/GongSolutions.WPF.DragDrop/GongSolutions.WPF.DragDrop.csproj b/src/GongSolutions.WPF.DragDrop/GongSolutions.WPF.DragDrop.csproj index 1a3896f7..c3e8ed60 100644 --- a/src/GongSolutions.WPF.DragDrop/GongSolutions.WPF.DragDrop.csproj +++ b/src/GongSolutions.WPF.DragDrop/GongSolutions.WPF.DragDrop.csproj @@ -2,7 +2,6 @@ - net5.0-windows GongSolutions.WPF.DragDrop gong-wpf-dragdrop GongSolutions.Wpf.DragDrop From 9a494f7117131b3b16c866b80d9e70adc9577f75 Mon Sep 17 00:00:00 2001 From: "Jan Ivar Z. Carlsen" Date: Fri, 8 Oct 2021 11:44:09 +0200 Subject: [PATCH 07/29] Fixed list box multi selection issue and reduced amount of SelectionChanged events --- .../Utilities/ItemsControlExtensions.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/GongSolutions.WPF.DragDrop/Utilities/ItemsControlExtensions.cs b/src/GongSolutions.WPF.DragDrop/Utilities/ItemsControlExtensions.cs index d31253b2..bce7e498 100644 --- a/src/GongSolutions.WPF.DragDrop/Utilities/ItemsControlExtensions.cs +++ b/src/GongSolutions.WPF.DragDrop/Utilities/ItemsControlExtensions.cs @@ -340,12 +340,7 @@ public static void SetSelectedItem(this ItemsControl itemsControl, object item2S if (selectionMode != SelectionMode.Single) { - var itemsToDeselect = listBox.SelectedItems.Cast().Where(si => si != item2Select).ToArray(); - - foreach (var item in itemsToDeselect) - { - listBox.SelectedItems.Remove(item); - } + listBox.UnselectAll(); } try From 1c18225d58602c6c8218772fd09ba6fcd9ee0005 Mon Sep 17 00:00:00 2001 From: punker76 Date: Fri, 8 Oct 2021 18:29:18 +0200 Subject: [PATCH 08/29] (#404) Fix issue with problem when arabic or hebrew language is selected. It's necessary to detect FlowDirection of the ItemsControl. Horizontal dragging works differently in languages with LeftToRight and in languages with RightToLeft flow. --- src/GongSolutions.WPF.DragDrop/DropInfo.cs | 48 ++++++++++++++++++---- 1 file changed, 39 insertions(+), 9 deletions(-) diff --git a/src/GongSolutions.WPF.DragDrop/DropInfo.cs b/src/GongSolutions.WPF.DragDrop/DropInfo.cs index 7df8c95a..5c1a130c 100644 --- a/src/GongSolutions.WPF.DragDrop/DropInfo.cs +++ b/src/GongSolutions.WPF.DragDrop/DropInfo.cs @@ -188,27 +188,57 @@ public DropInfo(object sender, DragEventArgs e, [CanBeNull] DragInfo dragInfo, E if (this.VisualTargetFlowDirection == FlowDirection.RightToLeft) { - if (currentXPos > targetWidth / 2) + if (itemsControl.FlowDirection == FlowDirection.LeftToRight) { - this.InsertPosition = RelativeInsertPosition.BeforeTargetItem; + if (currentXPos > targetWidth / 2) + { + this.InsertPosition = RelativeInsertPosition.BeforeTargetItem; + } + else + { + this.InsertIndex++; + this.InsertPosition = RelativeInsertPosition.AfterTargetItem; + } } else { - this.InsertIndex++; - this.InsertPosition = RelativeInsertPosition.AfterTargetItem; + if (currentXPos < targetWidth / 2) + { + this.InsertPosition = RelativeInsertPosition.BeforeTargetItem; + } + else + { + this.InsertIndex++; + this.InsertPosition = RelativeInsertPosition.AfterTargetItem; + } } } else if (this.VisualTargetFlowDirection == FlowDirection.LeftToRight) { - if (currentXPos > targetWidth / 2) + if (itemsControl.FlowDirection == FlowDirection.LeftToRight) { - this.InsertIndex++; - this.InsertPosition = RelativeInsertPosition.AfterTargetItem; + if (currentXPos > targetWidth / 2) + { + this.InsertIndex++; + this.InsertPosition = RelativeInsertPosition.AfterTargetItem; + } + else + { + this.InsertPosition = RelativeInsertPosition.BeforeTargetItem; + } } else { - this.InsertPosition = RelativeInsertPosition.BeforeTargetItem; - } + if (currentXPos < targetWidth / 2) + { + this.InsertIndex++; + this.InsertPosition = RelativeInsertPosition.AfterTargetItem; + } + else + { + this.InsertPosition = RelativeInsertPosition.BeforeTargetItem; + } + } } if (currentXPos > targetWidth * 0.25 && currentXPos < targetWidth * 0.75) From 9a10b3202cca4a903dca57eefee0ae646437a1a7 Mon Sep 17 00:00:00 2001 From: punker76 Date: Fri, 8 Oct 2021 18:31:18 +0200 Subject: [PATCH 09/29] (#404) Add sample --- src/Showcase/Views/ListBoxSamples.xaml | 27 +++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/Showcase/Views/ListBoxSamples.xaml b/src/Showcase/Views/ListBoxSamples.xaml index 620ddd1f..530b9a42 100644 --- a/src/Showcase/Views/ListBoxSamples.xaml +++ b/src/Showcase/Views/ListBoxSamples.xaml @@ -123,11 +123,36 @@ - + + + + + + ListBoxItem1 + ListBoxItem2 + ListBoxItem3 + ListBoxItem4 + ListBoxItem5 + + + From d36c6c6ee62f150dc05ebdac36fc0dfe6532361c Mon Sep 17 00:00:00 2001 From: punker76 Date: Fri, 8 Oct 2021 18:32:07 +0200 Subject: [PATCH 10/29] (#404) Fix calculation for InsertPosition and InsertIndex --- src/GongSolutions.WPF.DragDrop/DropInfo.cs | 54 ++++++---------------- 1 file changed, 13 insertions(+), 41 deletions(-) diff --git a/src/GongSolutions.WPF.DragDrop/DropInfo.cs b/src/GongSolutions.WPF.DragDrop/DropInfo.cs index 5c1a130c..881ab56d 100644 --- a/src/GongSolutions.WPF.DragDrop/DropInfo.cs +++ b/src/GongSolutions.WPF.DragDrop/DropInfo.cs @@ -179,7 +179,8 @@ public DropInfo(object sender, DragEventArgs e, [CanBeNull] DragInfo dragInfo, E this.InsertPosition |= RelativeInsertPosition.TargetItemCenter; } - //System.Diagnostics.Debug.WriteLine("==> DropInfo: pos={0}, idx={1}, Y={2}, Item={3}", this.InsertPosition, this.InsertIndex, currentYPos, item); + + // System.Diagnostics.Debug.WriteLine($"==> DropInfo: pos={this.InsertPosition}, index={this.InsertIndex}, currentXPos={currentXPos}, Item={this.item}"); } else { @@ -188,57 +189,27 @@ public DropInfo(object sender, DragEventArgs e, [CanBeNull] DragInfo dragInfo, E if (this.VisualTargetFlowDirection == FlowDirection.RightToLeft) { - if (itemsControl.FlowDirection == FlowDirection.LeftToRight) + if (currentXPos < targetWidth / 2) { - if (currentXPos > targetWidth / 2) - { - this.InsertPosition = RelativeInsertPosition.BeforeTargetItem; - } - else - { - this.InsertIndex++; - this.InsertPosition = RelativeInsertPosition.AfterTargetItem; - } + this.InsertPosition = RelativeInsertPosition.BeforeTargetItem; } else { - if (currentXPos < targetWidth / 2) - { - this.InsertPosition = RelativeInsertPosition.BeforeTargetItem; - } - else - { - this.InsertIndex++; - this.InsertPosition = RelativeInsertPosition.AfterTargetItem; - } + this.InsertIndex++; + this.InsertPosition = RelativeInsertPosition.AfterTargetItem; } } else if (this.VisualTargetFlowDirection == FlowDirection.LeftToRight) { - if (itemsControl.FlowDirection == FlowDirection.LeftToRight) + if (currentXPos > targetWidth / 2) { - if (currentXPos > targetWidth / 2) - { - this.InsertIndex++; - this.InsertPosition = RelativeInsertPosition.AfterTargetItem; - } - else - { - this.InsertPosition = RelativeInsertPosition.BeforeTargetItem; - } + this.InsertIndex++; + this.InsertPosition = RelativeInsertPosition.AfterTargetItem; } else { - if (currentXPos < targetWidth / 2) - { - this.InsertIndex++; - this.InsertPosition = RelativeInsertPosition.AfterTargetItem; - } - else - { - this.InsertPosition = RelativeInsertPosition.BeforeTargetItem; - } - } + this.InsertPosition = RelativeInsertPosition.BeforeTargetItem; + } } if (currentXPos > targetWidth * 0.25 && currentXPos < targetWidth * 0.75) @@ -251,7 +222,8 @@ public DropInfo(object sender, DragEventArgs e, [CanBeNull] DragInfo dragInfo, E this.InsertPosition |= RelativeInsertPosition.TargetItemCenter; } - //System.Diagnostics.Debug.WriteLine("==> DropInfo: pos={0}, idx={1}, X={2}, Item={3}", this.InsertPosition, this.InsertIndex, currentXPos, item); + + // System.Diagnostics.Debug.WriteLine($"==> DropInfo: pos={this.InsertPosition}, index={this.InsertIndex}, currentXPos={currentXPos}, Item={this.item}"); } } else From 93754f45e6aa0be542af240d1448b7307e04530b Mon Sep 17 00:00:00 2001 From: punker76 Date: Fri, 8 Oct 2021 18:32:53 +0200 Subject: [PATCH 11/29] (#404) Fix also the default target insertion adorner --- .../DropTargetInsertionAdorner.cs | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/GongSolutions.WPF.DragDrop/DropTargetInsertionAdorner.cs b/src/GongSolutions.WPF.DragDrop/DropTargetInsertionAdorner.cs index 5f3c6964..7778f7fd 100644 --- a/src/GongSolutions.WPF.DragDrop/DropTargetInsertionAdorner.cs +++ b/src/GongSolutions.WPF.DragDrop/DropTargetInsertionAdorner.cs @@ -133,18 +133,7 @@ protected override void OnRender(DrawingContext drawingContext) } else { - if (dropInfo.VisualTargetFlowDirection == FlowDirection.LeftToRight && dropInfo.InsertIndex == itemsCount) - { - if (itemsCount > 0) - { - itemRect.X += itemContainer.RenderSize.Width; - } - else - { - itemRect.X += this.Pen.Thickness; - } - } - else if (dropInfo.VisualTargetFlowDirection == FlowDirection.RightToLeft && dropInfo.InsertIndex != itemsCount) + if (dropInfo.InsertIndex == itemsCount) { if (itemsCount > 0) { From a7f507fd041ec06c41b26f10a1eeba8532cb947f Mon Sep 17 00:00:00 2001 From: punker76 Date: Fri, 8 Oct 2021 18:33:36 +0200 Subject: [PATCH 12/29] (#404) Fix default captured screen for RTL --- src/GongSolutions.WPF.DragDrop/Utilities/DragDropExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GongSolutions.WPF.DragDrop/Utilities/DragDropExtensions.cs b/src/GongSolutions.WPF.DragDrop/Utilities/DragDropExtensions.cs index 4aacbcef..e1b181c6 100644 --- a/src/GongSolutions.WPF.DragDrop/Utilities/DragDropExtensions.cs +++ b/src/GongSolutions.WPF.DragDrop/Utilities/DragDropExtensions.cs @@ -127,7 +127,7 @@ private static BitmapSource CaptureScreen(Visual target, FlowDirection flowDirec { var transformGroup = new TransformGroup(); transformGroup.Children.Add(new ScaleTransform(-1, 1)); - transformGroup.Children.Add(new TranslateTransform(bounds.Size.Width - 1, 0)); + transformGroup.Children.Add(new TranslateTransform(bounds.Size.Width, 0)); ctx.PushTransform(transformGroup); } From 6f85e4a39d6ec0fad5cdbf78cdb70490e542fc3a Mon Sep 17 00:00:00 2001 From: "daniel.banda" Date: Wed, 20 Oct 2021 14:00:36 -0700 Subject: [PATCH 13/29] Enable DropInfo creation for 3rd party controls IDropInfoBuilder enables the specification of a IDropInfo factory method to handle unsupported 3rd controls. --- .../DragDrop.Properties.cs | 24 ++++++++++++++ src/GongSolutions.WPF.DragDrop/DragDrop.cs | 29 +++++++++++----- .../DropTargetAdorner.cs | 4 +-- src/GongSolutions.WPF.DragDrop/IDropInfo.cs | 10 ++++++ .../IDropInfoBuilder.cs | 33 +++++++++++++++++++ 5 files changed, 90 insertions(+), 10 deletions(-) create mode 100644 src/GongSolutions.WPF.DragDrop/IDropInfoBuilder.cs diff --git a/src/GongSolutions.WPF.DragDrop/DragDrop.Properties.cs b/src/GongSolutions.WPF.DragDrop/DragDrop.Properties.cs index 88fe0e87..223cbc63 100644 --- a/src/GongSolutions.WPF.DragDrop/DragDrop.Properties.cs +++ b/src/GongSolutions.WPF.DragDrop/DragDrop.Properties.cs @@ -425,6 +425,30 @@ public static void SetDragInfoBuilder(DependencyObject element, IDragInfoBuilder element.SetValue(DragInfoBuilderProperty, value); } + /// + /// Gets or sets the drop info builder for the drop operation. + /// + public static readonly DependencyProperty DropInfoBuilderProperty + = DependencyProperty.RegisterAttached("DropInfoBuilder", + typeof(IDropInfoBuilder), + typeof(DragDrop)); + + /// + /// Gets the drop info builder for the drop operation. + /// + public static void SetDropInfoBuilder(DependencyObject element, IDropInfoBuilder value) + { + element.SetValue(DropInfoBuilderProperty, value); + } + + /// + /// Sets the drop info builder for the drop operation. + /// + public static IDropInfoBuilder GetDropInfoBuilder(DependencyObject element) + { + return (IDropInfoBuilder)element.GetValue(DropInfoBuilderProperty); + } + /// /// Gets or sets the ScrollingMode for the drop operation. /// diff --git a/src/GongSolutions.WPF.DragDrop/DragDrop.cs b/src/GongSolutions.WPF.DragDrop/DragDrop.cs index 3be2a37d..2948d9a3 100644 --- a/src/GongSolutions.WPF.DragDrop/DragDrop.cs +++ b/src/GongSolutions.WPF.DragDrop/DragDrop.cs @@ -82,7 +82,7 @@ private static DragDropPreview GetDragDropPreview(IDragInfo dragInfo, UIElement return null; } - private static DragDropEffectPreview GetDragDropEffectPreview(DropInfo dropInfo, UIElement sender) + private static DragDropEffectPreview GetDragDropEffectPreview(IDropInfo dropInfo, UIElement sender) { var dragInfo = dropInfo.DragInfo; var template = GetDragDropEffectTemplate(dragInfo.VisualSource, dropInfo); @@ -104,7 +104,7 @@ private static DragDropEffectPreview GetDragDropEffectPreview(DropInfo dropInfo, return null; } - private static DataTemplate GetDragDropEffectTemplate(UIElement target, DropInfo dropInfo) + private static DataTemplate GetDragDropEffectTemplate(UIElement target, IDropInfo dropInfo) { if (target is null) { @@ -202,7 +202,7 @@ private static DataTemplate CreateDefaultEffectDataTemplate(UIElement target, Bi return new DataTemplate { VisualTree = borderFactory }; } - private static void Scroll(DropInfo dropInfo, DragEventArgs e) + private static void Scroll(IDropInfo dropInfo, DragEventArgs e) { if (dropInfo?.TargetScrollViewer is null) { @@ -263,7 +263,7 @@ private static IDragSource TryGetDragHandler(IDragInfo dragInfo, UIElement sende /// the drop info object /// the sender from an event, e.g. drag over /// - private static IDropTarget TryGetDropHandler(DropInfo dropInfo, UIElement sender) + private static IDropTarget TryGetDropHandler(IDropInfo dropInfo, UIElement sender) { var dropHandler = dropInfo?.VisualTarget != null ? GetDropHandler(dropInfo.VisualTarget) : null; if (dropHandler is null && sender != null) @@ -284,6 +284,17 @@ private static IDragInfoBuilder TryGetDragInfoBuilder(DependencyObject sender) return GetDragInfoBuilder(sender); } + + /// + /// Gets the drop info builder from the sender. + /// + /// the sender from an event, e.g. drag over + /// + private static IDropInfoBuilder TryGetDropInfoBuilder(DependencyObject sender) + { + return GetDropInfoBuilder(sender); + } + /// /// Gets the RootElementFinder from the sender or uses the default implementation, if it's null. /// @@ -655,7 +666,8 @@ private static void DropTargetOnDragOver(object sender, DragEventArgs e, EventTy var elementPosition = e.GetPosition((IInputElement)sender); var dragInfo = _dragInfo; - var dropInfo = new DropInfo(sender, e, dragInfo, eventType); + var dropInfoBuilder = TryGetDropInfoBuilder(sender as DependencyObject); + var dropInfo = dropInfoBuilder?.CreateDropInfo(sender, e, dragInfo, eventType) ?? new DropInfo(sender, e, dragInfo, eventType); var dropHandler = TryGetDropHandler(dropInfo, sender as UIElement); var itemsControl = dropInfo.VisualTarget; @@ -777,7 +789,8 @@ private static void DropTargetOnPreviewDrop(object sender, DragEventArgs e) private static void DropTargetOnDrop(object sender, DragEventArgs e, EventType eventType) { var dragInfo = _dragInfo; - var dropInfo = new DropInfo(sender, e, dragInfo, eventType); + var dropInfoBuilder = TryGetDropInfoBuilder(sender as DependencyObject); + var dropInfo = dropInfoBuilder?.CreateDropInfo(sender, e, dragInfo, eventType) ?? new DropInfo(sender, e, dragInfo, eventType); var dropHandler = TryGetDropHandler(dropInfo, sender as UIElement); var dragHandler = TryGetDragHandler(dragInfo, sender as UIElement); var itemsSorter = TryGetDropTargetItemsSorter(dropInfo, sender as UIElement); @@ -787,9 +800,9 @@ private static void DropTargetOnDrop(object sender, DragEventArgs e, EventType e DropTargetAdorner = null; dropHandler.DragOver(dropInfo); - if (itemsSorter != null && dropInfo.Data is IEnumerable enumerable && !(enumerable is string)) + if (itemsSorter != null && dropInfo.Data is IEnumerable enumerable && !(enumerable is string) && dropInfo is DropInfo info) { - dropInfo.Data = itemsSorter.SortDropTargetItems(enumerable); + info.Data = itemsSorter.SortDropTargetItems(enumerable); } dropHandler.Drop(dropInfo); diff --git a/src/GongSolutions.WPF.DragDrop/DropTargetAdorner.cs b/src/GongSolutions.WPF.DragDrop/DropTargetAdorner.cs index 319333b0..5b9aa963 100644 --- a/src/GongSolutions.WPF.DragDrop/DropTargetAdorner.cs +++ b/src/GongSolutions.WPF.DragDrop/DropTargetAdorner.cs @@ -7,7 +7,7 @@ namespace GongSolutions.Wpf.DragDrop { public abstract class DropTargetAdorner : Adorner { - public DropTargetAdorner(UIElement adornedElement, DropInfo dropInfo) + public DropTargetAdorner(UIElement adornedElement, IDropInfo dropInfo) : base(adornedElement) { this.DropInfo = dropInfo; @@ -18,7 +18,7 @@ public DropTargetAdorner(UIElement adornedElement, DropInfo dropInfo) this.m_AdornerLayer.Add(this); } - public DropInfo DropInfo { get; set; } + public IDropInfo DropInfo { get; set; } /// /// Gets or Sets the pen which can be used for the render process. diff --git a/src/GongSolutions.WPF.DragDrop/IDropInfo.cs b/src/GongSolutions.WPF.DragDrop/IDropInfo.cs index 497d2a59..dd656078 100644 --- a/src/GongSolutions.WPF.DragDrop/IDropInfo.cs +++ b/src/GongSolutions.WPF.DragDrop/IDropInfo.cs @@ -87,6 +87,16 @@ public interface IDropInfo /// CollectionViewGroup TargetGroup { get; } + /// + /// Gets the ScrollViewer control for the visual target. + /// + ScrollViewer TargetScrollViewer { get; } + + /// + /// Gets or Sets the ScrollingMode for the drop action. + /// + ScrollingMode TargetScrollingMode { get; } + /// /// Gets the control that is the current drop target. /// diff --git a/src/GongSolutions.WPF.DragDrop/IDropInfoBuilder.cs b/src/GongSolutions.WPF.DragDrop/IDropInfoBuilder.cs new file mode 100644 index 00000000..f3c26606 --- /dev/null +++ b/src/GongSolutions.WPF.DragDrop/IDropInfoBuilder.cs @@ -0,0 +1,33 @@ +using System.Windows; +using JetBrains.Annotations; + +namespace GongSolutions.Wpf.DragDrop +{ + /// + /// Interface implemented by Drop Info Builders. + /// It enables custom construction of IDropInfo objects to support 3rd party controls like DevExpress, Telerik, etc. + /// + public interface IDropInfoBuilder + { + /// + /// Creates a drop info object from and . + /// + /// + /// + /// The sender of the mouse event that initiated the drag. + /// + /// + /// + /// The drag event args that initiated the drag. + /// + /// + /// + /// Object which contains the drag information. + /// + /// + /// + /// The mode of the underlying routed event. + /// + [CanBeNull] IDropInfo CreateDropInfo(object sender, [CanBeNull] DragEventArgs e, DragInfo dragInfo, EventType eventType); + } +} \ No newline at end of file From c2b48d46a025ee4d5e5a7679b6c86aeca236b38a Mon Sep 17 00:00:00 2001 From: punker76 Date: Thu, 28 Oct 2021 14:39:13 +0200 Subject: [PATCH 14/29] Make setter of Data for IDropInfo public --- src/GongSolutions.WPF.DragDrop/DragDrop.cs | 196 +++++++++--------- src/GongSolutions.WPF.DragDrop/DropInfo.cs | 2 +- src/GongSolutions.WPF.DragDrop/IDropInfo.cs | 2 +- .../IDropInfoBuilder.cs | 3 +- 4 files changed, 98 insertions(+), 105 deletions(-) diff --git a/src/GongSolutions.WPF.DragDrop/DragDrop.cs b/src/GongSolutions.WPF.DragDrop/DragDrop.cs index 2948d9a3..32bf7c80 100644 --- a/src/GongSolutions.WPF.DragDrop/DragDrop.cs +++ b/src/GongSolutions.WPF.DragDrop/DragDrop.cs @@ -14,6 +14,64 @@ namespace GongSolutions.Wpf.DragDrop { public static partial class DragDrop { + /// + /// Gets the drag handler from the drag info or from the sender, if the drag info is null + /// + /// the drag info object + /// the sender from an event, e.g. mouse down, mouse move + /// + private static IDragSource TryGetDragHandler(IDragInfo dragInfo, UIElement sender) + { + var dragHandler = (dragInfo?.VisualSource != null ? GetDragHandler(dragInfo.VisualSource) : null) ?? (sender != null ? GetDragHandler(sender) : null); + + return dragHandler ?? DefaultDragHandler; + } + + /// + /// Gets the drop handler from the drop info or from the sender, if the drop info is null + /// + /// the drop info object + /// the sender from an event, e.g. drag over + /// + private static IDropTarget TryGetDropHandler(IDropInfo dropInfo, UIElement sender) + { + var dropHandler = (dropInfo?.VisualTarget != null ? GetDropHandler(dropInfo.VisualTarget) : null) ?? (sender != null ? GetDropHandler(sender) : null); + + return dropHandler ?? DefaultDropHandler; + } + + /// + /// Gets the drag info builder from the sender. + /// + /// the sender from an event, e.g. drag over + /// + private static IDragInfoBuilder TryGetDragInfoBuilder(DependencyObject sender) + { + return sender != null ? GetDragInfoBuilder(sender) : null; + } + + /// + /// Gets the drop info builder from the sender. + /// + /// the sender from an event, e.g. drag over + /// + private static IDropInfoBuilder TryGetDropInfoBuilder(DependencyObject sender) + { + return sender != null ? GetDropInfoBuilder(sender) : null; + } + + /// + /// Gets the RootElementFinder from the sender or uses the default implementation, if it's null. + /// + /// the sender from an event, e.g. drag over + /// + private static IRootElementFinder TryGetRootElementFinder(UIElement sender) + { + var rootElementFinder = sender != null ? GetRootElementFinder(sender) : null; + + return rootElementFinder ?? DefaultRootElementFinder; + } + internal static DataTemplate TryGetDragAdornerTemplate(UIElement source, UIElement sender) { var template = source is not null ? GetDragAdornerTemplate(source) : null; @@ -58,6 +116,39 @@ internal static DataTemplateSelector TryGetDropAdornerTemplateSelector(UIElement return templateSelector; } + internal static int TryGetDragPreviewMaxItemsCount(IDragInfo dragInfo, UIElement sender) + { + var itemsCount = dragInfo?.VisualSource != null ? GetDragPreviewMaxItemsCount(dragInfo.VisualSource) : -1; + if (itemsCount < 0 && sender != null) + { + itemsCount = GetDragPreviewMaxItemsCount(sender); + } + + return itemsCount < 0 || itemsCount >= int.MaxValue ? 10 : itemsCount; + } + + internal static IDragPreviewItemsSorter TryGetDragPreviewItemsSorter(IDragInfo dragInfo, UIElement sender) + { + var itemsSorter = dragInfo?.VisualSource != null ? GetDragPreviewItemsSorter(dragInfo.VisualSource) : null; + if (itemsSorter is null && sender != null) + { + itemsSorter = GetDragPreviewItemsSorter(sender); + } + + return itemsSorter; + } + + private static IDropTargetItemsSorter TryGetDropTargetItemsSorter(IDropInfo dropInfo, UIElement sender) + { + var itemsSorter = dropInfo?.VisualTarget != null ? GetDropTargetItemsSorter(dropInfo.VisualTarget) : null; + if (itemsSorter is null && sender != null) + { + itemsSorter = GetDropTargetItemsSorter(sender); + } + + return itemsSorter; + } + private static DragDropPreview GetDragDropPreview(IDragInfo dragInfo, UIElement visualTarget, UIElement sender) { var visualSource = dragInfo?.VisualSource; @@ -240,106 +331,6 @@ private static void Scroll(IDropInfo dropInfo, DragEventArgs e) } } - /// - /// Gets the drag handler from the drag info or from the sender, if the drag info is null - /// - /// the drag info object - /// the sender from an event, e.g. mouse down, mouse move - /// - private static IDragSource TryGetDragHandler(IDragInfo dragInfo, UIElement sender) - { - var dragHandler = dragInfo?.VisualSource != null ? GetDragHandler(dragInfo.VisualSource) : null; - if (dragHandler is null && sender != null) - { - dragHandler = GetDragHandler(sender); - } - - return dragHandler ?? DefaultDragHandler; - } - - /// - /// Gets the drop handler from the drop info or from the sender, if the drop info is null - /// - /// the drop info object - /// the sender from an event, e.g. drag over - /// - private static IDropTarget TryGetDropHandler(IDropInfo dropInfo, UIElement sender) - { - var dropHandler = dropInfo?.VisualTarget != null ? GetDropHandler(dropInfo.VisualTarget) : null; - if (dropHandler is null && sender != null) - { - dropHandler = GetDropHandler(sender); - } - - return dropHandler ?? DefaultDropHandler; - } - - /// - /// Gets the drag info builder from the sender. - /// - /// the sender from an event, e.g. drag over - /// - private static IDragInfoBuilder TryGetDragInfoBuilder(DependencyObject sender) - { - return GetDragInfoBuilder(sender); - } - - - /// - /// Gets the drop info builder from the sender. - /// - /// the sender from an event, e.g. drag over - /// - private static IDropInfoBuilder TryGetDropInfoBuilder(DependencyObject sender) - { - return GetDropInfoBuilder(sender); - } - - /// - /// Gets the RootElementFinder from the sender or uses the default implementation, if it's null. - /// - /// the sender from an event, e.g. drag over - /// - private static IRootElementFinder TryGetRootElementFinder(UIElement sender) - { - var rootElementFinder = sender != null ? GetRootElementFinder(sender) : null; - - return rootElementFinder ?? DefaultRootElementFinder; - } - - internal static int TryGetDragPreviewMaxItemsCount(IDragInfo dragInfo, UIElement sender) - { - var itemsCount = dragInfo?.VisualSource != null ? GetDragPreviewMaxItemsCount(dragInfo.VisualSource) : -1; - if (itemsCount < 0 && sender != null) - { - itemsCount = GetDragPreviewMaxItemsCount(sender); - } - - return itemsCount < 0 || itemsCount >= int.MaxValue ? 10 : itemsCount; - } - - internal static IDragPreviewItemsSorter TryGetDragPreviewItemsSorter(IDragInfo dragInfo, UIElement sender) - { - var itemsSorter = dragInfo?.VisualSource != null ? GetDragPreviewItemsSorter(dragInfo.VisualSource) : null; - if (itemsSorter is null && sender != null) - { - itemsSorter = GetDragPreviewItemsSorter(sender); - } - - return itemsSorter; - } - - private static IDropTargetItemsSorter TryGetDropTargetItemsSorter(IDropInfo dropInfo, UIElement sender) - { - var itemsSorter = dropInfo?.VisualTarget != null ? GetDropTargetItemsSorter(dropInfo.VisualTarget) : null; - if (itemsSorter is null && sender != null) - { - itemsSorter = GetDropTargetItemsSorter(sender); - } - - return itemsSorter; - } - private static void DragSourceOnMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { DoMouseButtonDown(sender, e); @@ -800,9 +791,10 @@ private static void DropTargetOnDrop(object sender, DragEventArgs e, EventType e DropTargetAdorner = null; dropHandler.DragOver(dropInfo); - if (itemsSorter != null && dropInfo.Data is IEnumerable enumerable && !(enumerable is string) && dropInfo is DropInfo info) + + if (itemsSorter != null && dropInfo.Data is IEnumerable enumerable && !(enumerable is string)) { - info.Data = itemsSorter.SortDropTargetItems(enumerable); + dropInfo.Data = itemsSorter.SortDropTargetItems(enumerable); } dropHandler.Drop(dropInfo); diff --git a/src/GongSolutions.WPF.DragDrop/DropInfo.cs b/src/GongSolutions.WPF.DragDrop/DropInfo.cs index 881ab56d..c0d665a1 100644 --- a/src/GongSolutions.WPF.DragDrop/DropInfo.cs +++ b/src/GongSolutions.WPF.DragDrop/DropInfo.cs @@ -240,7 +240,7 @@ public DropInfo(object sender, DragEventArgs e, [CanBeNull] DragInfo dragInfo, E } /// - public object Data { get; internal set; } + public object Data { get; set; } /// public IDragInfo DragInfo { get; private set; } diff --git a/src/GongSolutions.WPF.DragDrop/IDropInfo.cs b/src/GongSolutions.WPF.DragDrop/IDropInfo.cs index dd656078..37d5b66b 100644 --- a/src/GongSolutions.WPF.DragDrop/IDropInfo.cs +++ b/src/GongSolutions.WPF.DragDrop/IDropInfo.cs @@ -17,7 +17,7 @@ public interface IDropInfo /// - The dragged data if a single item was dragged. /// - A typed IEnumerable if multiple items were dragged. /// - object Data { get; } + object Data { get; set; } /// /// Gets a object holding information about the source of the drag, diff --git a/src/GongSolutions.WPF.DragDrop/IDropInfoBuilder.cs b/src/GongSolutions.WPF.DragDrop/IDropInfoBuilder.cs index f3c26606..f2617f7f 100644 --- a/src/GongSolutions.WPF.DragDrop/IDropInfoBuilder.cs +++ b/src/GongSolutions.WPF.DragDrop/IDropInfoBuilder.cs @@ -28,6 +28,7 @@ public interface IDropInfoBuilder /// /// The mode of the underlying routed event. /// - [CanBeNull] IDropInfo CreateDropInfo(object sender, [CanBeNull] DragEventArgs e, DragInfo dragInfo, EventType eventType); + [CanBeNull] + IDropInfo CreateDropInfo(object sender, [CanBeNull] DragEventArgs e, DragInfo dragInfo, EventType eventType); } } \ No newline at end of file From 2995bd305ade860aa911748d65d95d32f5543cb4 Mon Sep 17 00:00:00 2001 From: punker76 Date: Sat, 30 Oct 2021 12:49:37 +0200 Subject: [PATCH 15/29] Simplify IDragInfoBuilder creation --- src/GongSolutions.WPF.DragDrop/DragDrop.cs | 6 +- src/GongSolutions.WPF.DragDrop/DragInfo.cs | 89 +++++++------------ .../IDragInfoBuilder.cs | 35 +++----- 3 files changed, 48 insertions(+), 82 deletions(-) diff --git a/src/GongSolutions.WPF.DragDrop/DragDrop.cs b/src/GongSolutions.WPF.DragDrop/DragDrop.cs index 32bf7c80..3f4ef043 100644 --- a/src/GongSolutions.WPF.DragDrop/DragDrop.cs +++ b/src/GongSolutions.WPF.DragDrop/DragDrop.cs @@ -357,7 +357,8 @@ private static void DragSourceOnTouchDown(object sender, TouchEventArgs e) } var infoBuilder = TryGetDragInfoBuilder(sender as DependencyObject); - var dragInfo = infoBuilder?.CreateDragInfo(sender, e) ?? new DragInfo(sender, e); + var dragInfo = infoBuilder?.CreateDragInfo(sender, e.OriginalSource, MouseButton.Left, item => e.GetTouchPoint(item).Position) + ?? new DragInfo(sender, e.OriginalSource, MouseButton.Left, item => e.GetTouchPoint(item).Position); DragSourceDown(sender, dragInfo, e); } @@ -379,7 +380,8 @@ private static void DoMouseButtonDown(object sender, MouseButtonEventArgs e) } var infoBuilder = TryGetDragInfoBuilder(sender as DependencyObject); - var dragInfo = infoBuilder?.CreateDragInfo(sender, e) ?? new DragInfo(sender, e); + var dragInfo = infoBuilder?.CreateDragInfo(sender, e.OriginalSource, e.ChangedButton, item => e.GetPosition(item)) + ?? new DragInfo(sender, e.OriginalSource, e.ChangedButton, item => e.GetPosition(item)); DragSourceDown(sender, dragInfo, e); } diff --git a/src/GongSolutions.WPF.DragDrop/DragInfo.cs b/src/GongSolutions.WPF.DragDrop/DragInfo.cs index 59506ff8..48fe6994 100644 --- a/src/GongSolutions.WPF.DragDrop/DragInfo.cs +++ b/src/GongSolutions.WPF.DragDrop/DragInfo.cs @@ -20,60 +20,6 @@ namespace GongSolutions.Wpf.DragDrop /// public class DragInfo : IDragInfo { - /// - /// Initializes a new instance of the DragInfo class. - /// - /// - /// - /// The sender of the mouse event that initiated the drag. - /// - /// - /// - /// The mouse event that initiated the drag. - /// - public DragInfo(object sender, MouseButtonEventArgs e) - { - this.InitializeDragInfo(sender, e.OriginalSource, item => e.GetPosition(item)); - this.MouseButton = e.ChangedButton; - } - - /// - /// Initializes a new instance of the DragInfo class. - /// - /// - /// - /// The sender of the mouse event that initiated the drag. - /// - /// - /// - /// The touch event that initiated the drag. - /// - public DragInfo(object sender, TouchEventArgs e) - { - this.InitializeDragInfo(sender, e.OriginalSource, item => e.GetTouchPoint(item).Position); - } - - internal void RefreshSelectedItems(object sender) - { - if (sender is ItemsControl) - { - var itemsControl = (ItemsControl)sender; - - var selectedItems = itemsControl.GetSelectedItems().OfType().Where(i => i != CollectionView.NewItemPlaceholder).ToList(); - this.SourceItems = selectedItems; - - // Some controls (I'm looking at you TreeView!) haven't updated their - // SelectedItem by this point. Check to see if there 1 or less item in - // the SourceItems collection, and if so, override the control's SelectedItems with the clicked item. - // - // The control has still the old selected items at the mouse down event, so we should check this and give only the real selected item to the user. - if (selectedItems.Count <= 1 || this.SourceItem != null && !selectedItems.Contains(this.SourceItem)) - { - this.SourceItems = Enumerable.Repeat(this.SourceItem, 1); - } - } - } - /// public DataFormat DataFormat { get; set; } = DragDrop.DataFormat; @@ -125,8 +71,16 @@ internal void RefreshSelectedItems(object sender) /// public DragDropKeyStates DragDropCopyKeyState { get; protected set; } - protected virtual void InitializeDragInfo(object sender, object originalSource, Func getPosition) + /// + /// Initializes a new instance of the DragInfo class. + /// + /// The sender of the input event that initiated the drag operation. + /// The original source of the input event. + /// The mouse button which was used for the drag operation. + /// A function of the input event which is used to get drag position points. + public DragInfo(object sender, object originalSource, MouseButton mouseButton, Func getPosition) { + this.MouseButton = mouseButton; this.Effects = DragDropEffects.None; this.VisualSource = sender as UIElement; this.DragStartPosition = getPosition(this.VisualSource); @@ -158,7 +112,7 @@ protected virtual void InitializeDragInfo(object sender, object originalSource, if (item == null) { - var itemPosition = getPosition(itemsControl); + var itemPosition = this.DragStartPosition; if (DragDrop.GetDragDirectlySelectedOnly(this.VisualSource)) { @@ -201,6 +155,7 @@ protected virtual void InitializeDragInfo(object sender, object originalSource, return; } } + this.SourceIndex = itemParent.ItemContainerGenerator.IndexFromContainer(item); this.SourceItem = itemParent.ItemContainerGenerator.ItemFromContainer(item); } @@ -236,6 +191,7 @@ protected virtual void InitializeDragInfo(object sender, object originalSource, { this.SourceItems = Enumerable.Repeat(this.SourceItem, 1); } + this.VisualSourceItem = sourceElement; this.PositionInDraggedItem = sourceElement != null ? getPosition(sourceElement) : this.DragStartPosition; } @@ -245,5 +201,26 @@ protected virtual void InitializeDragInfo(object sender, object originalSource, this.SourceItems = Enumerable.Empty(); } } + + internal void RefreshSelectedItems(object sender) + { + if (sender is ItemsControl) + { + var itemsControl = (ItemsControl)sender; + + var selectedItems = itemsControl.GetSelectedItems().OfType().Where(i => i != CollectionView.NewItemPlaceholder).ToList(); + this.SourceItems = selectedItems; + + // Some controls (I'm looking at you TreeView!) haven't updated their + // SelectedItem by this point. Check to see if there 1 or less item in + // the SourceItems collection, and if so, override the control's SelectedItems with the clicked item. + // + // The control has still the old selected items at the mouse down event, so we should check this and give only the real selected item to the user. + if (selectedItems.Count <= 1 || this.SourceItem != null && !selectedItems.Contains(this.SourceItem)) + { + this.SourceItems = Enumerable.Repeat(this.SourceItem, 1); + } + } + } } } \ No newline at end of file diff --git a/src/GongSolutions.WPF.DragDrop/IDragInfoBuilder.cs b/src/GongSolutions.WPF.DragDrop/IDragInfoBuilder.cs index 7511b590..05d3c897 100644 --- a/src/GongSolutions.WPF.DragDrop/IDragInfoBuilder.cs +++ b/src/GongSolutions.WPF.DragDrop/IDragInfoBuilder.cs @@ -1,4 +1,7 @@ -using System.Windows.Input; +using System; +using System.Windows; +using System.Windows.Input; +using JetBrains.Annotations; namespace GongSolutions.Wpf.DragDrop { @@ -9,29 +12,13 @@ namespace GongSolutions.Wpf.DragDrop public interface IDragInfoBuilder { /// - /// Creates a drag info object from . + /// Initializes a new instance of the DragInfo class. /// - /// - /// - /// The sender of the mouse event that initiated the drag. - /// - /// - /// - /// The mouse event that initiated the drag. - /// - DragInfo CreateDragInfo(object sender, MouseButtonEventArgs e); - - /// - /// Creates a drag info object from . - /// - /// - /// - /// The sender of the touch event that initiated the drag. - /// - /// - /// - /// The touch event that initiated the drag. - /// - DragInfo CreateDragInfo(object sender, TouchEventArgs e); + /// The sender of the input event that initiated the drag operation. + /// The original source of the input event. + /// The mouse button which was used for the drag operation. + /// A function of the input event which is used to get drag position points. + [CanBeNull] + DragInfo CreateDragInfo(object sender, object originalSource, MouseButton mouseButton, Func getPosition); } } \ No newline at end of file From a0dd11acaf8fec4909b8464c589fa5d465975c3d Mon Sep 17 00:00:00 2001 From: punker76 Date: Sat, 30 Oct 2021 12:50:14 +0200 Subject: [PATCH 16/29] Update documentation of IDropInfoBuilder --- src/GongSolutions.WPF.DragDrop/DropInfo.cs | 276 +++++++++--------- .../IDropInfoBuilder.cs | 24 +- 2 files changed, 138 insertions(+), 162 deletions(-) diff --git a/src/GongSolutions.WPF.DragDrop/DropInfo.cs b/src/GongSolutions.WPF.DragDrop/DropInfo.cs index c0d665a1..bbfb6139 100644 --- a/src/GongSolutions.WPF.DragDrop/DropInfo.cs +++ b/src/GongSolutions.WPF.DragDrop/DropInfo.cs @@ -24,26 +24,141 @@ public class DropInfo : IDropInfo private ItemsControl itemParent = null; private UIElement item = null; + /// + public object Data { get; set; } + + /// + public IDragInfo DragInfo { get; private set; } + + /// + public Point DropPosition { get; private set; } + + /// + public Type DropTargetAdorner { get; set; } + + /// + public DragDropEffects Effects { get; set; } + + /// + public int InsertIndex { get; private set; } + + /// + public int UnfilteredInsertIndex + { + get + { + var insertIndex = this.InsertIndex; + if (itemParent != null) + { + var itemSourceAsList = itemParent.ItemsSource.TryGetList(); + if (itemSourceAsList != null && itemParent.Items != null && itemParent.Items.Count != itemSourceAsList.Count) + { + if (insertIndex >= 0 && insertIndex < itemParent.Items.Count) + { + var indexOf = itemSourceAsList.IndexOf(itemParent.Items[insertIndex]); + if (indexOf >= 0) + { + return indexOf; + } + } + else if (itemParent.Items.Count > 0 && insertIndex == itemParent.Items.Count) + { + var indexOf = itemSourceAsList.IndexOf(itemParent.Items[insertIndex - 1]); + if (indexOf >= 0) + { + return indexOf + 1; + } + } + } + } + + return insertIndex; + } + } + + /// + public IEnumerable TargetCollection { get; private set; } + + /// + public object TargetItem { get; private set; } + + /// + public CollectionViewGroup TargetGroup { get; private set; } + + /// + /// Gets the ScrollViewer control for the visual target. + /// + public ScrollViewer TargetScrollViewer { get; private set; } + + /// + /// Gets or Sets the ScrollingMode for the drop action. + /// + public ScrollingMode TargetScrollingMode { get; set; } + + /// + public UIElement VisualTarget { get; private set; } + + /// + public UIElement VisualTargetItem { get; private set; } + + /// + public Orientation VisualTargetOrientation { get; private set; } + + /// + public FlowDirection VisualTargetFlowDirection { get; private set; } + + /// + public string DestinationText { get; set; } + + /// + public string EffectText { get; set; } + + /// + public RelativeInsertPosition InsertPosition { get; private set; } + + /// + public DragDropKeyStates KeyStates { get; private set; } + + /// + public bool NotHandled { get; set; } + + /// + public bool IsSameDragDropContextAsSource + { + get + { + // Check if DragInfo stuff exists + if (this.DragInfo?.VisualSource is null) + { + return true; + } + + // A target should be exists + if (this.VisualTarget is null) + { + return true; + } + + // Source element has a drag context constraint, we need to check the target property matches. + var sourceContext = DragDrop.GetDragDropContext(this.DragInfo.VisualSource); + var targetContext = DragDrop.GetDragDropContext(this.VisualTarget); + + return string.Equals(sourceContext, targetContext) + || string.IsNullOrEmpty(targetContext); + } + } + + /// + public EventType EventType { get; } + /// /// Initializes a new instance of the DropInfo class. /// - /// - /// - /// The sender of the drag event. - /// - /// - /// - /// The drag event. - /// - /// - /// - /// Information about the source of the drag, if the drag came from within the framework. - /// - /// - /// - /// The type of the underlying event (tunneled or bubbled). - /// - public DropInfo(object sender, DragEventArgs e, [CanBeNull] DragInfo dragInfo, EventType eventType) + /// The sender of the drop event. + /// The drag event arguments. + /// Information about the drag source, if the drag came from within the framework. + /// The type of the underlying event (tunneled or bubbled). + public DropInfo(object sender, DragEventArgs e, [CanBeNull] IDragInfo dragInfo, EventType eventType) { this.DragInfo = dragInfo; this.KeyStates = e.KeyStates; @@ -238,133 +353,6 @@ public DropInfo(object sender, DragEventArgs e, [CanBeNull] DragInfo dragInfo, E this.VisualTargetItem = this.VisualTarget; } } - - /// - public object Data { get; set; } - - /// - public IDragInfo DragInfo { get; private set; } - - /// - public Point DropPosition { get; private set; } - - /// - public Type DropTargetAdorner { get; set; } - - /// - public DragDropEffects Effects { get; set; } - - /// - public int InsertIndex { get; private set; } - - /// - public int UnfilteredInsertIndex - { - get - { - var insertIndex = this.InsertIndex; - if (itemParent != null) - { - var itemSourceAsList = itemParent.ItemsSource.TryGetList(); - if (itemSourceAsList != null && itemParent.Items != null && itemParent.Items.Count != itemSourceAsList.Count) - { - if (insertIndex >= 0 && insertIndex < itemParent.Items.Count) - { - var indexOf = itemSourceAsList.IndexOf(itemParent.Items[insertIndex]); - if (indexOf >= 0) - { - return indexOf; - } - } - else if (itemParent.Items.Count > 0 && insertIndex == itemParent.Items.Count) - { - var indexOf = itemSourceAsList.IndexOf(itemParent.Items[insertIndex - 1]); - if (indexOf >= 0) - { - return indexOf + 1; - } - } - } - } - - return insertIndex; - } - } - - /// - public IEnumerable TargetCollection { get; private set; } - - /// - public object TargetItem { get; private set; } - - /// - public CollectionViewGroup TargetGroup { get; private set; } - - /// - /// Gets the ScrollViewer control for the visual target. - /// - public ScrollViewer TargetScrollViewer { get; private set; } - - /// - /// Gets or Sets the ScrollingMode for the drop action. - /// - public ScrollingMode TargetScrollingMode { get; set; } - - /// - public UIElement VisualTarget { get; private set; } - - /// - public UIElement VisualTargetItem { get; private set; } - - /// - public Orientation VisualTargetOrientation { get; private set; } - - /// - public FlowDirection VisualTargetFlowDirection { get; private set; } - - /// - public string DestinationText { get; set; } - - /// - public string EffectText { get; set; } - - /// - public RelativeInsertPosition InsertPosition { get; private set; } - - /// - public DragDropKeyStates KeyStates { get; private set; } - - /// - public bool NotHandled { get; set; } - - /// - public bool IsSameDragDropContextAsSource - { - get - { - // Check if DragInfo stuff exists - if (this.DragInfo?.VisualSource is null) - { - return true; - } - - // A target should be exists - if (this.VisualTarget is null) - { - return true; - } - - // Source element has a drag context constraint, we need to check the target property matches. - var sourceContext = DragDrop.GetDragDropContext(this.DragInfo.VisualSource); - var targetContext = DragDrop.GetDragDropContext(this.VisualTarget); - - return string.Equals(sourceContext, targetContext) - || string.IsNullOrEmpty(targetContext); - } - } - - /// - public EventType EventType { get; } } [Flags] diff --git a/src/GongSolutions.WPF.DragDrop/IDropInfoBuilder.cs b/src/GongSolutions.WPF.DragDrop/IDropInfoBuilder.cs index f2617f7f..aba25dda 100644 --- a/src/GongSolutions.WPF.DragDrop/IDropInfoBuilder.cs +++ b/src/GongSolutions.WPF.DragDrop/IDropInfoBuilder.cs @@ -10,25 +10,13 @@ namespace GongSolutions.Wpf.DragDrop public interface IDropInfoBuilder { /// - /// Creates a drop info object from and . + /// Initializes a new instance of the DropInfo class. /// - /// - /// - /// The sender of the mouse event that initiated the drag. - /// - /// - /// - /// The drag event args that initiated the drag. - /// - /// - /// - /// Object which contains the drag information. - /// - /// - /// - /// The mode of the underlying routed event. - /// + /// The sender of the drop event. + /// The drag event arguments. + /// Information about the drag source, if the drag came from within the framework. + /// The type of the underlying event (tunneled or bubbled). [CanBeNull] - IDropInfo CreateDropInfo(object sender, [CanBeNull] DragEventArgs e, DragInfo dragInfo, EventType eventType); + IDropInfo CreateDropInfo(object sender, DragEventArgs e, [CanBeNull] DragInfo dragInfo, EventType eventType); } } \ No newline at end of file From 29266ce8ea85cb0e8c09c3f048ad0f822f2a6c74 Mon Sep 17 00:00:00 2001 From: punker76 Date: Sun, 31 Oct 2021 11:19:17 +0100 Subject: [PATCH 17/29] (#402) Add DragLeave method to IDropTarget --- .../DefaultDropHandler.cs | 154 +++++++++--------- src/GongSolutions.WPF.DragDrop/DragDrop.cs | 16 +- src/GongSolutions.WPF.DragDrop/IDropTarget.cs | 15 +- src/Showcase/Models/GroupedDropHandler.cs | 8 + src/Showcase/Models/NestedDropHandler.cs | 8 + .../Models/SerializableDropHandler.cs | 9 + .../Models/TextBoxCustomDropHandler.cs | 8 + 7 files changed, 143 insertions(+), 75 deletions(-) diff --git a/src/GongSolutions.WPF.DragDrop/DefaultDropHandler.cs b/src/GongSolutions.WPF.DragDrop/DefaultDropHandler.cs index 17eb8932..8c0bbee0 100644 --- a/src/GongSolutions.WPF.DragDrop/DefaultDropHandler.cs +++ b/src/GongSolutions.WPF.DragDrop/DefaultDropHandler.cs @@ -144,6 +144,79 @@ public static bool ShouldCopyData(IDropInfo dropInfo) return copyData; } + protected static int GetInsertIndex(IDropInfo dropInfo) + { + var insertIndex = dropInfo.UnfilteredInsertIndex; + + if (dropInfo.VisualTarget is ItemsControl itemsControl) + { + if (itemsControl.Items is IEditableCollectionView editableItems) + { + var newItemPlaceholderPosition = editableItems.NewItemPlaceholderPosition; + if (newItemPlaceholderPosition == NewItemPlaceholderPosition.AtBeginning && insertIndex == 0) + { + ++insertIndex; + } + else if (newItemPlaceholderPosition == NewItemPlaceholderPosition.AtEnd && insertIndex == itemsControl.Items.Count) + { + --insertIndex; + } + } + } + + return insertIndex; + } + + protected static void Move(IList list, int sourceIndex, int destinationIndex) + { + if (!list.IsObservableCollection()) + { + throw new ArgumentException("ObservableCollection was expected", nameof(list)); + } + + if (sourceIndex != destinationIndex) + { + var method = list.GetType().GetMethod("Move", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public); + _ = method?.Invoke(list, new object[] { sourceIndex, destinationIndex }); + } + } + + protected static bool IsChildOf(UIElement targetItem, UIElement sourceItem) + { + var parent = ItemsControl.ItemsControlFromItemContainer(targetItem); + + while (parent != null) + { + if (parent == sourceItem) + { + return true; + } + + parent = ItemsControl.ItemsControlFromItemContainer(parent); + } + + return false; + } + + protected static bool TestCompatibleTypes(IEnumerable target, object data) + { + bool InterfaceFilter(Type t, object o) => (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IEnumerable<>)); + + var enumerableInterfaces = target.GetType().FindInterfaces(InterfaceFilter, null); + var enumerableTypes = from i in enumerableInterfaces + select i.GetGenericArguments().Single(); + + if (enumerableTypes.Any()) + { + var dataType = TypeUtilities.GetCommonBaseClass(ExtractData(data)); + return enumerableTypes.Any(t => t.IsAssignableFrom(dataType)); + } + else + { + return target is IList || target is ICollectionView; + } + } + /// public virtual void DragOver(IDropInfo dropInfo) { @@ -156,6 +229,14 @@ public virtual void DragOver(IDropInfo dropInfo) } } +#if !NETCOREAPP3_1_OR_GREATER + /// + public void DragLeave(IDropInfo dropInfo) + { + // nothing here + } +#endif + /// public virtual void Drop(IDropInfo dropInfo) { @@ -238,78 +319,5 @@ public virtual void Drop(IDropInfo dropInfo) SelectDroppedItems(dropInfo, objects2Insert); } } - - protected static int GetInsertIndex(IDropInfo dropInfo) - { - var insertIndex = dropInfo.UnfilteredInsertIndex; - - if (dropInfo.VisualTarget is ItemsControl itemsControl) - { - if (itemsControl.Items is IEditableCollectionView editableItems) - { - var newItemPlaceholderPosition = editableItems.NewItemPlaceholderPosition; - if (newItemPlaceholderPosition == NewItemPlaceholderPosition.AtBeginning && insertIndex == 0) - { - ++insertIndex; - } - else if (newItemPlaceholderPosition == NewItemPlaceholderPosition.AtEnd && insertIndex == itemsControl.Items.Count) - { - --insertIndex; - } - } - } - - return insertIndex; - } - - protected static void Move(IList list, int sourceIndex, int destinationIndex) - { - if (!list.IsObservableCollection()) - { - throw new ArgumentException("ObservableCollection was expected", nameof(list)); - } - - if (sourceIndex != destinationIndex) - { - var method = list.GetType().GetMethod("Move", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public); - _ = method?.Invoke(list, new object[] { sourceIndex, destinationIndex }); - } - } - - protected static bool IsChildOf(UIElement targetItem, UIElement sourceItem) - { - var parent = ItemsControl.ItemsControlFromItemContainer(targetItem); - - while (parent != null) - { - if (parent == sourceItem) - { - return true; - } - - parent = ItemsControl.ItemsControlFromItemContainer(parent); - } - - return false; - } - - protected static bool TestCompatibleTypes(IEnumerable target, object data) - { - bool InterfaceFilter(Type t, object o) => (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IEnumerable<>)); - - var enumerableInterfaces = target.GetType().FindInterfaces(InterfaceFilter, null); - var enumerableTypes = from i in enumerableInterfaces - select i.GetGenericArguments().Single(); - - if (enumerableTypes.Any()) - { - var dataType = TypeUtilities.GetCommonBaseClass(ExtractData(data)); - return enumerableTypes.Any(t => t.IsAssignableFrom(dataType)); - } - else - { - return target is IList || target is ICollectionView; - } - } } } \ No newline at end of file diff --git a/src/GongSolutions.WPF.DragDrop/DragDrop.cs b/src/GongSolutions.WPF.DragDrop/DragDrop.cs index 3f4ef043..d6ac4210 100644 --- a/src/GongSolutions.WPF.DragDrop/DragDrop.cs +++ b/src/GongSolutions.WPF.DragDrop/DragDrop.cs @@ -636,8 +636,22 @@ private static void DropTargetOnDragLeave(object sender, DragEventArgs e) })); } - private static void OnRealTargetDragLeave(object sender, DragEventArgs dragEventArgs) + private static void OnRealTargetDragLeave(object sender, DragEventArgs e) { + var eventType = e.RoutedEvent?.RoutingStrategy switch + { + RoutingStrategy.Tunnel => EventType.Tunneled, + RoutingStrategy.Bubble => EventType.Bubbled, + _ => EventType.Auto + }; + + var dragInfo = _dragInfo; + var dropInfoBuilder = TryGetDropInfoBuilder(sender as DependencyObject); + var dropInfo = dropInfoBuilder?.CreateDropInfo(sender, e, dragInfo, eventType) ?? new DropInfo(sender, e, dragInfo, eventType); + var dropHandler = TryGetDropHandler(dropInfo, sender as UIElement); + + dropHandler?.DragLeave(dropInfo); + DragDropEffectPreview = null; DropTargetAdorner = null; } diff --git a/src/GongSolutions.WPF.DragDrop/IDropTarget.cs b/src/GongSolutions.WPF.DragDrop/IDropTarget.cs index 89e4206a..a6d2cc3f 100644 --- a/src/GongSolutions.WPF.DragDrop/IDropTarget.cs +++ b/src/GongSolutions.WPF.DragDrop/IDropTarget.cs @@ -19,7 +19,20 @@ public interface IDropTarget void DragOver(IDropInfo dropInfo); /// - /// Performs a drop. + /// Notifies the drop handler when dragging operation leaves a potential drop target. + /// + /// Object which contains several drop information. +#if NETCOREAPP3_1_OR_GREATER + void DragLeave(IDropInfo dropInfo) + { + // nothing here + } +#else + void DragLeave(IDropInfo dropInfo); +#endif + + /// + /// Performs a drop on the target. /// /// Object which contains several drop information. void Drop(IDropInfo dropInfo); diff --git a/src/Showcase/Models/GroupedDropHandler.cs b/src/Showcase/Models/GroupedDropHandler.cs index 217877d2..0899ac53 100644 --- a/src/Showcase/Models/GroupedDropHandler.cs +++ b/src/Showcase/Models/GroupedDropHandler.cs @@ -20,6 +20,14 @@ public void DragOver(IDropInfo dropInfo) } } +#if !NETCOREAPP3_1_OR_GREATER + /// + public void DragLeave(IDropInfo dropInfo) + { + // nothing here + } +#endif + /// public void Drop(IDropInfo dropInfo) { diff --git a/src/Showcase/Models/NestedDropHandler.cs b/src/Showcase/Models/NestedDropHandler.cs index 1cc0b835..eaca7a7f 100644 --- a/src/Showcase/Models/NestedDropHandler.cs +++ b/src/Showcase/Models/NestedDropHandler.cs @@ -16,6 +16,14 @@ public void DragOver(IDropInfo dropInfo) } } +#if !NETCOREAPP3_1_OR_GREATER + /// + public void DragLeave(IDropInfo dropInfo) + { + // nothing here + } +#endif + /// public void Drop(IDropInfo dropInfo) { diff --git a/src/Showcase/Models/SerializableDropHandler.cs b/src/Showcase/Models/SerializableDropHandler.cs index d50385a7..dadc412c 100644 --- a/src/Showcase/Models/SerializableDropHandler.cs +++ b/src/Showcase/Models/SerializableDropHandler.cs @@ -18,6 +18,14 @@ public void DragOver(IDropInfo dropInfo) } } +#if !NETCOREAPP3_1_OR_GREATER + /// + public void DragLeave(IDropInfo dropInfo) + { + // nothing here + } +#endif + /// public void Drop(IDropInfo dropInfo) { @@ -95,6 +103,7 @@ private static bool ShouldCopyData(IDropInfo dropInfo, DragDropKeyStates dragDro { return false; } + var copyData = ((dragDropCopyKeyState != default(DragDropKeyStates)) && dropInfo.KeyStates.HasFlag(dragDropCopyKeyState)) || dragDropCopyKeyState.HasFlag(DragDropKeyStates.LeftMouseButton); return copyData; diff --git a/src/Showcase/Models/TextBoxCustomDropHandler.cs b/src/Showcase/Models/TextBoxCustomDropHandler.cs index 7c080f6e..737902a0 100644 --- a/src/Showcase/Models/TextBoxCustomDropHandler.cs +++ b/src/Showcase/Models/TextBoxCustomDropHandler.cs @@ -15,6 +15,14 @@ public void DragOver(IDropInfo dropInfo) dropInfo.Effects = DragDropEffects.Move; } +#if !NETCOREAPP3_1_OR_GREATER + /// + public void DragLeave(IDropInfo dropInfo) + { + // nothing here + } +#endif + /// public void Drop(IDropInfo dropInfo) { From aae66dcd79d0be94378a326a901a9401ca65bd4f Mon Sep 17 00:00:00 2001 From: punker76 Date: Sun, 31 Oct 2021 18:08:11 +0100 Subject: [PATCH 18/29] (#402) Add DragEnter method to IDropTarget --- .../DefaultDropHandler.cs | 8 ++ src/GongSolutions.WPF.DragDrop/DragDrop.cs | 74 ++++++++++++++----- src/GongSolutions.WPF.DragDrop/IDropTarget.cs | 13 ++++ src/Showcase/Models/GroupedDropHandler.cs | 8 ++ src/Showcase/Models/NestedDropHandler.cs | 8 ++ .../Models/SerializableDropHandler.cs | 8 ++ .../Models/TextBoxCustomDropHandler.cs | 8 ++ 7 files changed, 110 insertions(+), 17 deletions(-) diff --git a/src/GongSolutions.WPF.DragDrop/DefaultDropHandler.cs b/src/GongSolutions.WPF.DragDrop/DefaultDropHandler.cs index 8c0bbee0..d789c90f 100644 --- a/src/GongSolutions.WPF.DragDrop/DefaultDropHandler.cs +++ b/src/GongSolutions.WPF.DragDrop/DefaultDropHandler.cs @@ -217,6 +217,14 @@ protected static bool TestCompatibleTypes(IEnumerable target, object data) } } +#if !NETCOREAPP3_1_OR_GREATER + /// + public void DragEnter(IDropInfo dropInfo) + { + // nothing here + } +#endif + /// public virtual void DragOver(IDropInfo dropInfo) { diff --git a/src/GongSolutions.WPF.DragDrop/DragDrop.cs b/src/GongSolutions.WPF.DragDrop/DragDrop.cs index d6ac4210..1504263b 100644 --- a/src/GongSolutions.WPF.DragDrop/DragDrop.cs +++ b/src/GongSolutions.WPF.DragDrop/DragDrop.cs @@ -612,24 +612,14 @@ private static void DragSourceOnQueryContinueDrag(object sender, QueryContinueDr } } - private static void DropTargetOnDragEnter(object sender, DragEventArgs e) - { - DropTargetOnDragOver(sender, e, EventType.Bubbled); - } - - private static void DropTargetOnPreviewDragEnter(object sender, DragEventArgs e) - { - DropTargetOnDragOver(sender, e, EventType.Tunneled); - } - private static void DropTargetOnDragLeave(object sender, DragEventArgs e) { - _isDragOver = false; + SetIsDragOver(sender as DependencyObject, false); DropTargetAdorner = null; (sender as UIElement)?.Dispatcher.BeginInvoke(new Action(() => { - if (_isDragOver == false) + if (GetIsDragOver(sender as DependencyObject) == false && GetIsDragLeaved(sender as DependencyObject) == false) { OnRealTargetDragLeave(sender, e); } @@ -638,6 +628,8 @@ private static void DropTargetOnDragLeave(object sender, DragEventArgs e) private static void OnRealTargetDragLeave(object sender, DragEventArgs e) { + SetIsDragLeaved(sender as DependencyObject, true); + var eventType = e.RoutedEvent?.RoutingStrategy switch { RoutingStrategy.Tunnel => EventType.Tunneled, @@ -656,19 +648,30 @@ private static void OnRealTargetDragLeave(object sender, DragEventArgs e) DropTargetAdorner = null; } + private static void DropTargetOnDragEnter(object sender, DragEventArgs e) + { + DropTargetOnDragOver(sender, e, EventType.Bubbled, GetIsDragLeaved(sender as DependencyObject)); + } + + private static void DropTargetOnPreviewDragEnter(object sender, DragEventArgs e) + { + DropTargetOnDragOver(sender, e, EventType.Tunneled, GetIsDragLeaved(sender as DependencyObject)); + } + private static void DropTargetOnDragOver(object sender, DragEventArgs e) { - DropTargetOnDragOver(sender, e, EventType.Bubbled); + DropTargetOnDragOver(sender, e, EventType.Bubbled, false); } private static void DropTargetOnPreviewDragOver(object sender, DragEventArgs e) { - DropTargetOnDragOver(sender, e, EventType.Tunneled); + DropTargetOnDragOver(sender, e, EventType.Tunneled, false); } - private static void DropTargetOnDragOver(object sender, DragEventArgs e, EventType eventType) + private static void DropTargetOnDragOver(object sender, DragEventArgs e, EventType eventType, bool isDragEnter) { - _isDragOver = true; + SetIsDragOver(sender as DependencyObject, true); + SetIsDragLeaved(sender as DependencyObject, false); var elementPosition = e.GetPosition((IInputElement)sender); @@ -678,6 +681,11 @@ private static void DropTargetOnDragOver(object sender, DragEventArgs e, EventTy var dropHandler = TryGetDropHandler(dropInfo, sender as UIElement); var itemsControl = dropInfo.VisualTarget; + if (isDragEnter) + { + dropHandler.DragEnter(dropInfo); + } + dropHandler.DragOver(dropInfo); if (dragInfo is not null) @@ -820,6 +828,7 @@ private static void DropTargetOnDrop(object sender, DragEventArgs e, EventType e e.Handled = !dropInfo.NotHandled; Mouse.OverrideCursor = null; + SetIsDragLeaved(sender as DependencyObject, true); } private static void DragSourceOnGiveFeedback(object sender, GiveFeedbackEventArgs e) @@ -920,9 +929,40 @@ private static DropTargetAdorner DropTargetAdorner } } - private static bool _isDragOver; private static DragInfo _dragInfo; private static bool _dragInProgress; private static object _clickSupressItem; + + private static readonly DependencyProperty IsDragOverProperty + = DependencyProperty.RegisterAttached("IsDragOver", + typeof(bool), + typeof(DragDrop), + new PropertyMetadata(default(bool))); + + private static void SetIsDragOver(DependencyObject element, bool value) + { + element.SetValue(IsDragOverProperty, value); + } + + private static bool GetIsDragOver(DependencyObject element) + { + return (bool)element.GetValue(IsDragOverProperty); + } + + private static readonly DependencyProperty IsDragLeavedProperty + = DependencyProperty.RegisterAttached("IsDragLeaved", + typeof(bool), + typeof(DragDrop), + new PropertyMetadata(true)); + + private static void SetIsDragLeaved(DependencyObject element, bool value) + { + element.SetValue(IsDragLeavedProperty, value); + } + + private static bool GetIsDragLeaved(DependencyObject element) + { + return (bool)element.GetValue(IsDragLeavedProperty); + } } } \ No newline at end of file diff --git a/src/GongSolutions.WPF.DragDrop/IDropTarget.cs b/src/GongSolutions.WPF.DragDrop/IDropTarget.cs index a6d2cc3f..1a6970d5 100644 --- a/src/GongSolutions.WPF.DragDrop/IDropTarget.cs +++ b/src/GongSolutions.WPF.DragDrop/IDropTarget.cs @@ -7,6 +7,19 @@ namespace GongSolutions.Wpf.DragDrop /// public interface IDropTarget { + /// + /// Notifies the drop handler when dragging operation enters a potential drop target. + /// + /// Object which contains several drop information. +#if NETCOREAPP3_1_OR_GREATER + void DragEnter(IDropInfo dropInfo) + { + // nothing here + } +#else + void DragEnter(IDropInfo dropInfo); +#endif + /// /// Notifies the drop handler about the current drag operation state. /// diff --git a/src/Showcase/Models/GroupedDropHandler.cs b/src/Showcase/Models/GroupedDropHandler.cs index 0899ac53..4402a8df 100644 --- a/src/Showcase/Models/GroupedDropHandler.cs +++ b/src/Showcase/Models/GroupedDropHandler.cs @@ -9,6 +9,14 @@ namespace Showcase.WPF.DragDrop.Models /// public class GroupedDropHandler : IDropTarget { +#if !NETCOREAPP3_1_OR_GREATER + /// + public void DragEnter(IDropInfo dropInfo) + { + // nothing here + } +#endif + /// public void DragOver(IDropInfo dropInfo) { diff --git a/src/Showcase/Models/NestedDropHandler.cs b/src/Showcase/Models/NestedDropHandler.cs index eaca7a7f..437b453d 100644 --- a/src/Showcase/Models/NestedDropHandler.cs +++ b/src/Showcase/Models/NestedDropHandler.cs @@ -6,6 +6,14 @@ namespace Showcase.WPF.DragDrop.Models { public class NestedDropHandler : IDropTarget { +#if !NETCOREAPP3_1_OR_GREATER + /// + public void DragEnter(IDropInfo dropInfo) + { + // nothing here + } +#endif + /// public void DragOver(IDropInfo dropInfo) { diff --git a/src/Showcase/Models/SerializableDropHandler.cs b/src/Showcase/Models/SerializableDropHandler.cs index dadc412c..e34d49e3 100644 --- a/src/Showcase/Models/SerializableDropHandler.cs +++ b/src/Showcase/Models/SerializableDropHandler.cs @@ -7,6 +7,14 @@ namespace Showcase.WPF.DragDrop.Models { public class SerializableDropHandler : IDropTarget { +#if !NETCOREAPP3_1_OR_GREATER + /// + public void DragEnter(IDropInfo dropInfo) + { + // nothing here + } +#endif + /// public void DragOver(IDropInfo dropInfo) { diff --git a/src/Showcase/Models/TextBoxCustomDropHandler.cs b/src/Showcase/Models/TextBoxCustomDropHandler.cs index 737902a0..76f29970 100644 --- a/src/Showcase/Models/TextBoxCustomDropHandler.cs +++ b/src/Showcase/Models/TextBoxCustomDropHandler.cs @@ -8,6 +8,14 @@ namespace Showcase.WPF.DragDrop.Models { public class TextBoxCustomDropHandler : IDropTarget { +#if !NETCOREAPP3_1_OR_GREATER + /// + public void DragEnter(IDropInfo dropInfo) + { + // nothing here + } +#endif + /// public void DragOver(IDropInfo dropInfo) { From 1f4c6f00d90c7da870fcddc1da99017bda01527e Mon Sep 17 00:00:00 2001 From: punker76 Date: Mon, 1 Nov 2021 13:36:52 +0100 Subject: [PATCH 19/29] Update/Improve TextBox sample --- .../Models/TextBoxCustomDropHandler.cs | 25 ++++++++++++++++--- src/Showcase/Views/Issues.xaml | 18 ++++++++----- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/src/Showcase/Models/TextBoxCustomDropHandler.cs b/src/Showcase/Models/TextBoxCustomDropHandler.cs index 76f29970..30fb557e 100644 --- a/src/Showcase/Models/TextBoxCustomDropHandler.cs +++ b/src/Showcase/Models/TextBoxCustomDropHandler.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System; +using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Media; @@ -34,8 +35,26 @@ public void DragLeave(IDropInfo dropInfo) /// public void Drop(IDropInfo dropInfo) { - var dataAsList = DefaultDropHandler.ExtractData(dropInfo.Data); - ((TextBox)dropInfo.VisualTarget).Text = string.Join(", ", dataAsList.OfType().ToArray()); + var textBox = (TextBox)dropInfo.VisualTarget; + + if (dropInfo.Data is IDataObject dataObject) + { + if (dataObject.GetDataPresent(DataFormats.Text)) + { + textBox.Text = dataObject.GetData(DataFormats.Text) as string ?? string.Empty; + } + else if (dataObject.GetDataPresent(DataFormats.FileDrop)) + { + // Note that you can have more than one file. + string[] files = (string[])dataObject.GetData(DataFormats.FileDrop); + textBox.Text = string.Join(Environment.NewLine, files); + } + } + else + { + var realData = DefaultDropHandler.ExtractData(dropInfo.Data); + textBox.Text = string.Join(", ", realData.OfType().ToArray()); + } } } diff --git a/src/Showcase/Views/Issues.xaml b/src/Showcase/Views/Issues.xaml index f421f3b3..1281fdac 100644 --- a/src/Showcase/Views/Issues.xaml +++ b/src/Showcase/Views/Issues.xaml @@ -531,12 +531,18 @@ dd:DragDrop.IsDropTarget="True" ItemsSource="{Binding Data.Collection1}" /> - + + + + From c1c69cd7740ae9f6277e9512a1ed11dbf8435e79 Mon Sep 17 00:00:00 2001 From: punker76 Date: Tue, 2 Nov 2021 12:45:01 +0100 Subject: [PATCH 20/29] (Housekeeping) warnings and suggestions --- .../DefaultDragHandler.cs | 13 +- .../DefaultDropHandler.cs | 10 +- .../DragDrop.Properties.cs | 40 ++++--- src/GongSolutions.WPF.DragDrop/DragDrop.cs | 38 +++--- .../DragDropPreview.cs | 5 +- src/GongSolutions.WPF.DragDrop/DragInfo.cs | 34 +++--- src/GongSolutions.WPF.DragDrop/DropInfo.cs | 91 +++++++------- .../Utilities/HitTestUtilities.cs | 111 +++++++++--------- .../Models/SerializableDropHandler.cs | 94 +++++++++++---- 9 files changed, 235 insertions(+), 201 deletions(-) diff --git a/src/GongSolutions.WPF.DragDrop/DefaultDragHandler.cs b/src/GongSolutions.WPF.DragDrop/DefaultDragHandler.cs index 61d109cc..ec0e5e9e 100644 --- a/src/GongSolutions.WPF.DragDrop/DefaultDragHandler.cs +++ b/src/GongSolutions.WPF.DragDrop/DefaultDragHandler.cs @@ -11,8 +11,8 @@ namespace GongSolutions.Wpf.DragDrop /// public class DefaultDragHandler : IDragSource { - /// - public virtual void StartDrag(IDragInfo dragInfo) + /// + public virtual void StartDrag(IDragInfo dragInfo) { var items = TypeUtilities.CreateDynamicallyTypedList(dragInfo.SourceItems).Cast().ToList(); if (items.Count > 1) @@ -23,14 +23,7 @@ public virtual void StartDrag(IDragInfo dragInfo) { // special case: if the single item is an enumerable then we can not drop it as single item var singleItem = items.FirstOrDefault(); - if (singleItem is IEnumerable && !(singleItem is string)) - { - dragInfo.Data = items; - } - else - { - dragInfo.Data = singleItem; - } + dragInfo.Data = singleItem is IEnumerable and not string ? items : singleItem; } dragInfo.Effects = dragInfo.Data != null ? DragDropEffects.Copy | DragDropEffects.Move : DragDropEffects.None; diff --git a/src/GongSolutions.WPF.DragDrop/DefaultDropHandler.cs b/src/GongSolutions.WPF.DragDrop/DefaultDropHandler.cs index d789c90f..c26bdd8b 100644 --- a/src/GongSolutions.WPF.DragDrop/DefaultDropHandler.cs +++ b/src/GongSolutions.WPF.DragDrop/DefaultDropHandler.cs @@ -61,7 +61,7 @@ public static bool CanAcceptData(IDropInfo dropInfo) public static IEnumerable ExtractData(object data) { - if (data is IEnumerable enumerable && !(enumerable is string)) + if (data is IEnumerable enumerable and not string) { return enumerable; } @@ -138,9 +138,9 @@ public static bool ShouldCopyData(IDropInfo dropInfo) var copyData = ((dropInfo.DragInfo.DragDropCopyKeyState != default) && dropInfo.KeyStates.HasFlag(dropInfo.DragInfo.DragDropCopyKeyState)) || dropInfo.DragInfo.DragDropCopyKeyState.HasFlag(DragDropKeyStates.LeftMouseButton); copyData = copyData - && !(dropInfo.DragInfo.SourceItem is HeaderedContentControl) - && !(dropInfo.DragInfo.SourceItem is HeaderedItemsControl) - && !(dropInfo.DragInfo.SourceItem is ListBoxItem); + && dropInfo.DragInfo.SourceItem is not HeaderedContentControl + && dropInfo.DragInfo.SourceItem is not HeaderedItemsControl + && dropInfo.DragInfo.SourceItem is not ListBoxItem; return copyData; } @@ -213,7 +213,7 @@ protected static bool TestCompatibleTypes(IEnumerable target, object data) } else { - return target is IList || target is ICollectionView; + return target is IList or ICollectionView; } } diff --git a/src/GongSolutions.WPF.DragDrop/DragDrop.Properties.cs b/src/GongSolutions.WPF.DragDrop/DragDrop.Properties.cs index 223cbc63..d0a94cdf 100644 --- a/src/GongSolutions.WPF.DragDrop/DragDrop.Properties.cs +++ b/src/GongSolutions.WPF.DragDrop/DragDrop.Properties.cs @@ -17,6 +17,7 @@ public static partial class DragDrop /// /// Gets or sets the data format which will be used for the drag and drop operations. /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("WpfAnalyzers.Correctness", "WPF0150:Use nameof() instead of literal.", Justification = "")] public static readonly DependencyProperty DataFormatProperty = DependencyProperty.RegisterAttached("DataFormat", typeof(DataFormat), @@ -46,7 +47,7 @@ public static readonly DependencyProperty IsDragSourceProperty = DependencyProperty.RegisterAttached("IsDragSource", typeof(bool), typeof(DragDrop), - new UIPropertyMetadata(false, IsDragSourceChanged)); + new UIPropertyMetadata(false, OnIsDragSourceChanged)); /// /// Gets whether the control can be used as drag source. @@ -64,7 +65,7 @@ public static void SetIsDragSource(UIElement target, bool value) target.SetValue(IsDragSourceProperty, value); } - private static void IsDragSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + private static void OnIsDragSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var uiElement = (UIElement)d; @@ -103,7 +104,7 @@ public static readonly DependencyProperty IsDropTargetProperty = DependencyProperty.RegisterAttached("IsDropTarget", typeof(bool), typeof(DragDrop), - new UIPropertyMetadata(false, IsDropTargetChanged)); + new UIPropertyMetadata(false, OnIsDropTargetChanged)); /// /// Gets whether the control can be used as drop target. @@ -121,7 +122,7 @@ public static void SetIsDropTarget(UIElement target, bool value) target.SetValue(IsDropTargetProperty, value); } - private static void IsDropTargetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + private static void OnIsDropTargetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var uiElement = (UIElement)d; @@ -164,14 +165,16 @@ public static readonly DependencyProperty DropEventTypeProperty = DependencyProperty.RegisterAttached("DropEventType", typeof(EventType), typeof(DragDrop), - new PropertyMetadata(EventType.Auto, DropEventTypeChanged)); + new PropertyMetadata(EventType.Auto, OnDropEventTypeChanged)); - private static void DropEventTypeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + private static void OnDropEventTypeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var uiElement = (UIElement)d; if (!GetIsDropTarget(uiElement)) + { return; + } UnregisterDragDropEvents(uiElement, (EventType)e.OldValue); RegisterDragDropEvents(uiElement, (EventType)e.NewValue); @@ -304,7 +307,7 @@ public static readonly DependencyProperty CanDragWithMouseRightButtonProperty = DependencyProperty.RegisterAttached("CanDragWithMouseRightButton", typeof(bool), typeof(DragDrop), - new UIPropertyMetadata(false, CanDragWithMouseRightButtonChanged)); + new UIPropertyMetadata(false, OnCanDragWithMouseRightButtonChanged)); /// /// Gets whether the control can be used as drag source together with the right mouse. @@ -322,19 +325,18 @@ public static void SetCanDragWithMouseRightButton(UIElement target, bool value) target.SetValue(CanDragWithMouseRightButtonProperty, value); } - private static void CanDragWithMouseRightButtonChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + private static void OnCanDragWithMouseRightButtonChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { - var uiElement = (UIElement)d; - - if ((bool)e.NewValue) - { - uiElement.PreviewMouseRightButtonDown += DragSourceOnMouseRightButtonDown; - uiElement.PreviewMouseRightButtonUp += DragSourceOnMouseRightButtonUp; - } - else + if (d is UIElement uiElement) { uiElement.PreviewMouseRightButtonDown -= DragSourceOnMouseRightButtonDown; uiElement.PreviewMouseRightButtonUp -= DragSourceOnMouseRightButtonUp; + + if ((bool)e.NewValue) + { + uiElement.PreviewMouseRightButtonDown += DragSourceOnMouseRightButtonDown; + uiElement.PreviewMouseRightButtonUp += DragSourceOnMouseRightButtonUp; + } } } @@ -585,7 +587,7 @@ public static readonly DependencyProperty DragDirectlySelectedOnlyProperty new PropertyMetadata(false)); /// - /// Gets wheter the drag action should be started only directly on a selected item. + /// Gets whether the drag action should be started only directly on a selected item. /// public static bool GetDragDirectlySelectedOnly(DependencyObject obj) { @@ -593,7 +595,7 @@ public static bool GetDragDirectlySelectedOnly(DependencyObject obj) } /// - /// Sets wheter the drag action should be started only directly on a selected item. + /// Sets whether the drag action should be started only directly on a selected item. /// public static void SetDragDirectlySelectedOnly(DependencyObject obj, bool value) { @@ -1216,7 +1218,7 @@ public static readonly DependencyProperty DragPreviewMaxItemsCountProperty = DependencyProperty.RegisterAttached("DragPreviewMaxItemsCount", typeof(int), typeof(DragDrop), - new PropertyMetadata(10, null, (d, baseValue) => + new PropertyMetadata(10, null, (_, baseValue) => { var itemsCount = (int)baseValue; // Checking for MaxValue is maybe not necessary diff --git a/src/GongSolutions.WPF.DragDrop/DragDrop.cs b/src/GongSolutions.WPF.DragDrop/DragDrop.cs index 1504263b..f7c442d2 100644 --- a/src/GongSolutions.WPF.DragDrop/DragDrop.cs +++ b/src/GongSolutions.WPF.DragDrop/DragDrop.cs @@ -407,8 +407,11 @@ private static void DragSourceDown(object sender, DragInfo dragInfo, InputEventA // If the sender is a list box that allows multiple selections, ensure that clicking on an // already selected item does not change the selection, otherwise dragging multiple items // is made impossible. - var itemsControl = sender as ItemsControl; - if ((Keyboard.Modifiers & ModifierKeys.Shift) == 0 && (Keyboard.Modifiers & ModifierKeys.Control) == 0 && dragInfo.VisualSourceItem != null && itemsControl != null && itemsControl.CanSelectMultipleItems()) + if ((Keyboard.Modifiers & ModifierKeys.Shift) == 0 + && (Keyboard.Modifiers & ModifierKeys.Control) == 0 + && dragInfo.VisualSourceItem != null + && sender is ItemsControl itemsControl + && itemsControl.CanSelectMultipleItems()) { var selectedItems = itemsControl.GetSelectedItems().OfType().ToList(); if (selectedItems.Count > 1 && selectedItems.Contains(dragInfo.SourceItem)) @@ -423,25 +426,20 @@ private static void DragSourceDown(object sender, DragInfo dragInfo, InputEventA private static void DragSourceOnMouseLeftButtonUp(object sender, MouseButtonEventArgs e) { - DoMouseButtonUp(sender, e); + DragSourceUp(sender); } private static void DragSourceOnMouseRightButtonUp(object sender, MouseButtonEventArgs e) { - DoMouseButtonUp(sender, e); + DragSourceUp(sender); } private static void DragSourceOnTouchUp(object sender, TouchEventArgs e) { - DragSourceUp(sender, e.GetTouchPoint((IInputElement)sender).Position); + DragSourceUp(sender); } - private static void DoMouseButtonUp(object sender, MouseButtonEventArgs e) - { - DragSourceUp(sender, e.GetPosition((IInputElement)sender)); - } - - private static void DragSourceUp(object sender, Point elementPosition) + private static void DragSourceUp(object sender) { var dragInfo = _dragInfo; @@ -716,7 +714,7 @@ private static void DropTargetOnDragOver(object sender, DragEventArgs e, EventTy // Display the adorner in the control's ItemsPresenter. If there is no // ItemsPresenter provided by the style, try getting hold of a // ScrollContentPresenter and using that. - UIElement adornedElement = null; + UIElement adornedElement; if (itemsControl is TabControl) { adornedElement = itemsControl.GetVisualDescendent(); @@ -747,7 +745,7 @@ private static void DropTargetOnDragOver(object sender, DragEventArgs e, EventTy var adornerBrush = GetDropTargetAdornerBrush(dropInfo.VisualTarget); if (adornerBrush != null) { - adorner.Pen.Brush = adornerBrush; + adorner.Pen.SetCurrentValue(Pen.BrushProperty, adornerBrush); } adorner.DropInfo = dropInfo; @@ -816,7 +814,7 @@ private static void DropTargetOnDrop(object sender, DragEventArgs e, EventType e dropHandler.DragOver(dropInfo); - if (itemsSorter != null && dropInfo.Data is IEnumerable enumerable && !(enumerable is string)) + if (itemsSorter != null && dropInfo.Data is IEnumerable enumerable and not string) { dropInfo.Data = itemsSorter.SortDropTargetItems(enumerable); } @@ -933,34 +931,34 @@ private static DropTargetAdorner DropTargetAdorner private static bool _dragInProgress; private static object _clickSupressItem; - private static readonly DependencyProperty IsDragOverProperty + internal static readonly DependencyProperty IsDragOverProperty = DependencyProperty.RegisterAttached("IsDragOver", typeof(bool), typeof(DragDrop), new PropertyMetadata(default(bool))); - private static void SetIsDragOver(DependencyObject element, bool value) + internal static void SetIsDragOver(DependencyObject element, bool value) { element.SetValue(IsDragOverProperty, value); } - private static bool GetIsDragOver(DependencyObject element) + internal static bool GetIsDragOver(DependencyObject element) { return (bool)element.GetValue(IsDragOverProperty); } - private static readonly DependencyProperty IsDragLeavedProperty + internal static readonly DependencyProperty IsDragLeavedProperty = DependencyProperty.RegisterAttached("IsDragLeaved", typeof(bool), typeof(DragDrop), new PropertyMetadata(true)); - private static void SetIsDragLeaved(DependencyObject element, bool value) + internal static void SetIsDragLeaved(DependencyObject element, bool value) { element.SetValue(IsDragLeavedProperty, value); } - private static bool GetIsDragLeaved(DependencyObject element) + internal static bool GetIsDragLeaved(DependencyObject element) { return (bool)element.GetValue(IsDragLeavedProperty); } diff --git a/src/GongSolutions.WPF.DragDrop/DragDropPreview.cs b/src/GongSolutions.WPF.DragDrop/DragDropPreview.cs index fa8dfa9f..4385e9e7 100644 --- a/src/GongSolutions.WPF.DragDrop/DragDropPreview.cs +++ b/src/GongSolutions.WPF.DragDrop/DragDropPreview.cs @@ -231,9 +231,10 @@ public UIElement CreatePreviewPresenter(IDragInfo dragInfo, UIElement visualTarg if (this.ItemTemplate != null || this.ItemTemplateSelector != null) { - if (dragInfo.Data is IEnumerable items && !(items is string)) + if (dragInfo.Data is IEnumerable enumerable and not string) { - var itemsCount = items.Cast().Count(); + var items = enumerable.Cast().ToList(); + var itemsCount = items.Count; var maxItemsCount = DragDrop.TryGetDragPreviewMaxItemsCount(dragInfo, sender); if (!this.UseDefaultDragAdorner && itemsCount <= maxItemsCount) { diff --git a/src/GongSolutions.WPF.DragDrop/DragInfo.cs b/src/GongSolutions.WPF.DragDrop/DragInfo.cs index 48fe6994..15c1cba1 100644 --- a/src/GongSolutions.WPF.DragDrop/DragInfo.cs +++ b/src/GongSolutions.WPF.DragDrop/DragInfo.cs @@ -141,8 +141,7 @@ public DragInfo(object sender, object originalSource, MouseButton mouseButton, F this.SourceCollection = itemParent.ItemsSource ?? itemParent.Items; if (itemParent != itemsControl) { - var tvItem = item as TreeViewItem; - if (tvItem != null) + if (item is TreeViewItem tvItem) { var tv = tvItem.GetVisualAncestor(); if (tv != null && tv != itemsControl && !tv.IsDragSource()) @@ -196,30 +195,27 @@ public DragInfo(object sender, object originalSource, MouseButton mouseButton, F this.PositionInDraggedItem = sourceElement != null ? getPosition(sourceElement) : this.DragStartPosition; } - if (this.SourceItems == null) - { - this.SourceItems = Enumerable.Empty(); - } + this.SourceItems ??= Enumerable.Empty(); } internal void RefreshSelectedItems(object sender) { - if (sender is ItemsControl) + if (sender is not ItemsControl itemsControl) { - var itemsControl = (ItemsControl)sender; + return; + } - var selectedItems = itemsControl.GetSelectedItems().OfType().Where(i => i != CollectionView.NewItemPlaceholder).ToList(); - this.SourceItems = selectedItems; + var selectedItems = itemsControl.GetSelectedItems().OfType().Where(i => i != CollectionView.NewItemPlaceholder).ToList(); + this.SourceItems = selectedItems; - // Some controls (I'm looking at you TreeView!) haven't updated their - // SelectedItem by this point. Check to see if there 1 or less item in - // the SourceItems collection, and if so, override the control's SelectedItems with the clicked item. - // - // The control has still the old selected items at the mouse down event, so we should check this and give only the real selected item to the user. - if (selectedItems.Count <= 1 || this.SourceItem != null && !selectedItems.Contains(this.SourceItem)) - { - this.SourceItems = Enumerable.Repeat(this.SourceItem, 1); - } + // Some controls (I'm looking at you TreeView!) haven't updated their + // SelectedItem by this point. Check to see if there 1 or less item in + // the SourceItems collection, and if so, override the control's SelectedItems with the clicked item. + // + // The control has still the old selected items at the mouse down event, so we should check this and give only the real selected item to the user. + if (selectedItems.Count <= 1 || this.SourceItem != null && !selectedItems.Contains(this.SourceItem)) + { + this.SourceItems = Enumerable.Repeat(this.SourceItem, 1); } } } diff --git a/src/GongSolutions.WPF.DragDrop/DropInfo.cs b/src/GongSolutions.WPF.DragDrop/DropInfo.cs index bbfb6139..740afed0 100644 --- a/src/GongSolutions.WPF.DragDrop/DropInfo.cs +++ b/src/GongSolutions.WPF.DragDrop/DropInfo.cs @@ -21,17 +21,16 @@ namespace GongSolutions.Wpf.DragDrop /// public class DropInfo : IDropInfo { - private ItemsControl itemParent = null; - private UIElement item = null; + private readonly ItemsControl itemParent; /// public object Data { get; set; } /// - public IDragInfo DragInfo { get; private set; } + public IDragInfo DragInfo { get; protected set; } /// - public Point DropPosition { get; private set; } + public Point DropPosition { get; protected set; } /// public Type DropTargetAdorner { get; set; } @@ -40,7 +39,7 @@ public class DropInfo : IDropInfo public DragDropEffects Effects { get; set; } /// - public int InsertIndex { get; private set; } + public int InsertIndex { get; protected set; } /// public int UnfilteredInsertIndex @@ -48,26 +47,28 @@ public int UnfilteredInsertIndex get { var insertIndex = this.InsertIndex; - if (itemParent != null) + if (this.itemParent is null) { - var itemSourceAsList = itemParent.ItemsSource.TryGetList(); - if (itemSourceAsList != null && itemParent.Items != null && itemParent.Items.Count != itemSourceAsList.Count) + return insertIndex; + } + + var itemSourceAsList = this.itemParent.ItemsSource.TryGetList(); + if (itemSourceAsList != null && this.itemParent.Items != null && this.itemParent.Items.Count != itemSourceAsList.Count) + { + if (insertIndex >= 0 && insertIndex < this.itemParent.Items.Count) { - if (insertIndex >= 0 && insertIndex < itemParent.Items.Count) + var indexOf = itemSourceAsList.IndexOf(this.itemParent.Items[insertIndex]); + if (indexOf >= 0) { - var indexOf = itemSourceAsList.IndexOf(itemParent.Items[insertIndex]); - if (indexOf >= 0) - { - return indexOf; - } + return indexOf; } - else if (itemParent.Items.Count > 0 && insertIndex == itemParent.Items.Count) + } + else if (this.itemParent.Items.Count > 0 && insertIndex == this.itemParent.Items.Count) + { + var indexOf = itemSourceAsList.IndexOf(this.itemParent.Items[insertIndex - 1]); + if (indexOf >= 0) { - var indexOf = itemSourceAsList.IndexOf(itemParent.Items[insertIndex - 1]); - if (indexOf >= 0) - { - return indexOf + 1; - } + return indexOf + 1; } } } @@ -77,18 +78,18 @@ public int UnfilteredInsertIndex } /// - public IEnumerable TargetCollection { get; private set; } + public IEnumerable TargetCollection { get; protected set; } /// - public object TargetItem { get; private set; } + public object TargetItem { get; protected set; } /// - public CollectionViewGroup TargetGroup { get; private set; } + public CollectionViewGroup TargetGroup { get; protected set; } /// /// Gets the ScrollViewer control for the visual target. /// - public ScrollViewer TargetScrollViewer { get; private set; } + public ScrollViewer TargetScrollViewer { get; protected set; } /// /// Gets or Sets the ScrollingMode for the drop action. @@ -96,16 +97,16 @@ public int UnfilteredInsertIndex public ScrollingMode TargetScrollingMode { get; set; } /// - public UIElement VisualTarget { get; private set; } + public UIElement VisualTarget { get; protected set; } /// - public UIElement VisualTargetItem { get; private set; } + public UIElement VisualTargetItem { get; protected set; } /// - public Orientation VisualTargetOrientation { get; private set; } + public Orientation VisualTargetOrientation { get; protected set; } /// - public FlowDirection VisualTargetFlowDirection { get; private set; } + public FlowDirection VisualTargetFlowDirection { get; protected set; } /// public string DestinationText { get; set; } @@ -114,10 +115,10 @@ public int UnfilteredInsertIndex public string EffectText { get; set; } /// - public RelativeInsertPosition InsertPosition { get; private set; } + public RelativeInsertPosition InsertPosition { get; protected set; } /// - public DragDropKeyStates KeyStates { get; private set; } + public DragDropKeyStates KeyStates { get; protected set; } /// public bool NotHandled { get; set; } @@ -207,12 +208,12 @@ public DropInfo(object sender, DragEventArgs e, [CanBeNull] IDragInfo dragInfo, } } - if (this.VisualTarget is ItemsControl) + if (this.VisualTarget is ItemsControl itemsControl) { - var itemsControl = (ItemsControl)this.VisualTarget; //System.Diagnostics.Debug.WriteLine(">>> Name = {0}", itemsControl.Name); + // get item under the mouse - item = itemsControl.GetItemContainerAt(this.DropPosition); + var item = itemsControl.GetItemContainerAt(this.DropPosition); var directlyOverItem = item != null; this.TargetGroup = itemsControl.FindGroup(this.DropPosition); @@ -223,38 +224,38 @@ public DropInfo(object sender, DragEventArgs e, [CanBeNull] IDragInfo dragInfo, { // ok, no item found, so maybe we can found an item at top, left, right or bottom item = itemsControl.GetItemContainerAt(this.DropPosition, this.VisualTargetOrientation); - directlyOverItem = DropPosition.DirectlyOverElement(this.item, itemsControl); + directlyOverItem = this.DropPosition.DirectlyOverElement(item, itemsControl); } - if (item == null && this.TargetGroup != null && this.TargetGroup.IsBottomLevel) + if (item == null && this.TargetGroup is { IsBottomLevel: true }) { var itemData = this.TargetGroup.Items.FirstOrDefault(); if (itemData != null) { item = itemsControl.ItemContainerGenerator.ContainerFromItem(itemData) as UIElement; - directlyOverItem = DropPosition.DirectlyOverElement(this.item, itemsControl); + directlyOverItem = this.DropPosition.DirectlyOverElement(item, itemsControl); } } if (item != null) { - itemParent = ItemsControl.ItemsControlFromItemContainer(item); - this.VisualTargetOrientation = itemParent.GetItemsPanelOrientation(); - this.VisualTargetFlowDirection = itemParent.GetItemsPanelFlowDirection(); + this.itemParent = ItemsControl.ItemsControlFromItemContainer(item); + this.VisualTargetOrientation = this.itemParent.GetItemsPanelOrientation(); + this.VisualTargetFlowDirection = this.itemParent.GetItemsPanelFlowDirection(); - this.InsertIndex = itemParent.ItemContainerGenerator.IndexFromContainer(item); - this.TargetCollection = itemParent.ItemsSource ?? itemParent.Items; + this.InsertIndex = this.itemParent.ItemContainerGenerator.IndexFromContainer(item); + this.TargetCollection = this.itemParent.ItemsSource ?? this.itemParent.Items; var tvItem = item as TreeViewItem; if (directlyOverItem || tvItem != null) { this.VisualTargetItem = item; - this.TargetItem = itemParent.ItemContainerGenerator.ItemFromContainer(item); + this.TargetItem = this.itemParent.ItemContainerGenerator.ItemFromContainer(item); } - var expandedTVItem = tvItem != null && tvItem.HasHeader && tvItem.HasItems && tvItem.IsExpanded; - var itemRenderSize = expandedTVItem ? tvItem.GetHeaderSize() : item.RenderSize; + var tvItemIsExpanded = tvItem is { HasHeader: true, HasItems: true, IsExpanded: true }; + var itemRenderSize = tvItemIsExpanded ? tvItem.GetHeaderSize() : item.RenderSize; if (this.VisualTargetOrientation == Orientation.Vertical) { @@ -265,7 +266,7 @@ public DropInfo(object sender, DragEventArgs e, [CanBeNull] IDragInfo dragInfo, var bottomGap = targetHeight * 0.75; if (currentYPos > targetHeight / 2) { - if (expandedTVItem && (currentYPos < topGap || currentYPos > bottomGap)) + if (tvItemIsExpanded && (currentYPos < topGap || currentYPos > bottomGap)) { this.VisualTargetItem = tvItem.ItemContainerGenerator.ContainerFromIndex(0) as UIElement; this.TargetItem = this.VisualTargetItem != null ? tvItem.ItemContainerGenerator.ItemFromContainer(this.VisualTargetItem) : null; diff --git a/src/GongSolutions.WPF.DragDrop/Utilities/HitTestUtilities.cs b/src/GongSolutions.WPF.DragDrop/Utilities/HitTestUtilities.cs index dee2a7a7..7cd49e8f 100644 --- a/src/GongSolutions.WPF.DragDrop/Utilities/HitTestUtilities.cs +++ b/src/GongSolutions.WPF.DragDrop/Utilities/HitTestUtilities.cs @@ -1,4 +1,4 @@ -using System.Windows; +using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Input; @@ -13,24 +13,20 @@ public static bool HitTest4Type(object sender, Point elementPosition) where T : UIElement { var uiElement = GetHitTestElement4Type(sender, elementPosition); - return uiElement != null && uiElement.Visibility == Visibility.Visible; + return uiElement is { Visibility: Visibility.Visible }; } private static T GetHitTestElement4Type(object sender, Point elementPosition) where T : UIElement { - var visual = sender as Visual; - if (visual == null) + if (sender is not Visual visual) { return null; } + var hit = VisualTreeHelper.HitTest(visual, elementPosition); - if (hit == null) - { - return null; - } - var uiElement = hit.VisualHit.GetVisualAncestor(); - return uiElement; + + return hit?.VisualHit.GetVisualAncestor(); } public static bool HitTest4GridViewColumnHeader(object sender, Point elementPosition) @@ -44,48 +40,55 @@ public static bool HitTest4GridViewColumnHeader(object sender, Point elementPosi return true; } } + return false; } public static bool HitTest4DataGridTypes(object sender, Point elementPosition) { - if (sender is DataGrid) + if (sender is not DataGrid) { - // no drag&drop for column header - var columnHeader = GetHitTestElement4Type(sender, elementPosition); - if (columnHeader != null && columnHeader.Visibility == Visibility.Visible) + return false; + } + + // no drag&drop for column header + var columnHeader = GetHitTestElement4Type(sender, elementPosition); + if (columnHeader is { Visibility: Visibility.Visible }) + { + return true; + } + + // no drag&drop for row header + var rowHeader = GetHitTestElement4Type(sender, elementPosition); + if (rowHeader is { Visibility: Visibility.Visible }) + { + // no drag&drop for row header gripper + var thumb = GetHitTestElement4Type(sender, elementPosition); + if (thumb != null) { return true; } - // no drag&drop for row header - var rowHeader = GetHitTestElement4Type(sender, elementPosition); - if (rowHeader != null && rowHeader.Visibility == Visibility.Visible) - { - // no drag&drop for row header gripper - var thumb = GetHitTestElement4Type(sender, elementPosition); - if (thumb != null) - { - return true; - } - } - // drag&drop only for data grid row - var dataRow = GetHitTestElement4Type(sender, elementPosition); - return dataRow == null || Equals(dataRow.DataContext, CollectionView.NewItemPlaceholder); } - return false; + + // drag&drop only for data grid row + var dataRow = GetHitTestElement4Type(sender, elementPosition); + return dataRow == null || Equals(dataRow.DataContext, CollectionView.NewItemPlaceholder); } public static bool HitTest4DataGridTypesOnDragOver(object sender, Point elementPosition) { - if (sender is DataGrid) + if (sender is not DataGrid) { - // no drag&drop on column header - var columnHeader = GetHitTestElement4Type(sender, elementPosition); - if (columnHeader != null && columnHeader.Visibility == Visibility.Visible) - { - return true; - } + return false; + } + + // no drag&drop on column header + var columnHeader = GetHitTestElement4Type(sender, elementPosition); + if (columnHeader is { Visibility: Visibility.Visible }) + { + return true; } + return false; } @@ -108,39 +111,31 @@ public static bool IsNotPartOfSender(object sender, TouchEventArgs e) private static bool IsNotPartOfSender(object sender, object originalSource, Point position) { - var visual = originalSource as Visual; - - if (visual == null) + if (originalSource is not Visual visual) { return false; } - var hit = VisualTreeHelper.HitTest(visual, position); - if (hit == null) + var hit = VisualTreeHelper.HitTest(visual, position); + if (hit is null) { return false; } - else + + if (visual == sender) { - var depObj = originalSource as DependencyObject; - if (depObj == null) - { - return false; - } - if (depObj == sender) - { - return false; - } + return false; + } - var item = VisualTreeHelper.GetParent(depObj.FindVisualTreeRoot()); - //var item = VisualTreeHelper.GetParent(e.OriginalSource as DependencyObject); + var parent = VisualTreeHelper.GetParent(visual.FindVisualTreeRoot()); + //var item = VisualTreeHelper.GetParent(e.OriginalSource as DependencyObject); - while (item != null && item != sender) - { - item = VisualTreeHelper.GetParent(item); - } - return item != sender; + while (parent != null && parent != sender) + { + parent = VisualTreeHelper.GetParent(parent); } + + return parent != sender; } } } \ No newline at end of file diff --git a/src/Showcase/Models/SerializableDropHandler.cs b/src/Showcase/Models/SerializableDropHandler.cs index e34d49e3..49605163 100644 --- a/src/Showcase/Models/SerializableDropHandler.cs +++ b/src/Showcase/Models/SerializableDropHandler.cs @@ -5,6 +5,10 @@ namespace Showcase.WPF.DragDrop.Models { + using System.Collections; + using System.Collections.Generic; + using System.Linq; + public class SerializableDropHandler : IDropTarget { #if !NETCOREAPP3_1_OR_GREATER @@ -38,24 +42,34 @@ public void DragLeave(IDropInfo dropInfo) public void Drop(IDropInfo dropInfo) { var wrapper = GetSerializableWrapper(dropInfo); - if (wrapper != null && dropInfo.TargetCollection != null) + if (wrapper == null || dropInfo.TargetCollection == null) { - // at this point the drag info can be null, cause the other app doesn't know it - var insertIndex = dropInfo.InsertIndex != dropInfo.UnfilteredInsertIndex ? dropInfo.UnfilteredInsertIndex : dropInfo.InsertIndex; - var destinationList = dropInfo.TargetCollection.TryGetList(); - var copyData = ShouldCopyData(dropInfo, wrapper.DragDropCopyKeyState); + return; + } + + // at this point the drag info can be null, cause the other app doesn't know it - if (!copyData) + var insertIndex = dropInfo.UnfilteredInsertIndex; + var destinationList = dropInfo.TargetCollection.TryGetList(); + var data = wrapper.Items.ToList(); + bool isSameCollection = false; + + var copyData = ShouldCopyData(dropInfo, wrapper.DragDropCopyKeyState); + if (!copyData) + { + var sourceList = dropInfo.DragInfo?.SourceCollection?.TryGetList(); + if (sourceList != null) { - var sourceList = dropInfo.DragInfo?.SourceCollection?.TryGetList(); - if (sourceList != null) + isSameCollection = sourceList.IsSameObservableCollection(destinationList); + if (!isSameCollection) { - foreach (var o in wrapper.Items) + foreach (var o in data) { var index = sourceList.IndexOf(o); if (index != -1) { sourceList.RemoveAt(index); + // so, is the source list the destination list too ? if (destinationList != null && Equals(sourceList, destinationList) && index < insertIndex) { @@ -65,27 +79,62 @@ public void Drop(IDropInfo dropInfo) } } } + } - if (destinationList != null) + if (destinationList != null) + { + var objects2Insert = new List(); + + // check for cloning + var cloneData = dropInfo.Effects.HasFlag(DragDropEffects.Copy) || dropInfo.Effects.HasFlag(DragDropEffects.Link); + + foreach (var o in data) { - // check for cloning - var cloneData = dropInfo.Effects.HasFlag(DragDropEffects.Copy) - || dropInfo.Effects.HasFlag(DragDropEffects.Link); - foreach (var o in wrapper.Items) + var obj2Insert = o; + if (cloneData) + { + if (o is ICloneable cloneable) + { + obj2Insert = cloneable.Clone(); + } + } + + objects2Insert.Add(obj2Insert); + + if (!cloneData && isSameCollection) { - var obj2Insert = o; - if (cloneData) + var index = destinationList.IndexOf(o); + if (index != -1) { - var cloneable = o as ICloneable; - if (cloneable != null) + if (insertIndex > index) { - obj2Insert = cloneable.Clone(); + insertIndex--; } - } + Move(destinationList, index, insertIndex++); + } + } + else + { destinationList.Insert(insertIndex++, obj2Insert); } } + + DefaultDropHandler.SelectDroppedItems(dropInfo, objects2Insert); + } + } + + private static void Move(IList list, int sourceIndex, int destinationIndex) + { + if (!list.IsObservableCollection()) + { + throw new ArgumentException("ObservableCollection was expected", nameof(list)); + } + + if (sourceIndex != destinationIndex) + { + var method = list.GetType().GetMethod("Move", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public); + _ = method?.Invoke(list, new object[] { sourceIndex, destinationIndex }); } } @@ -93,8 +142,7 @@ private static SerializableWrapper GetSerializableWrapper(IDropInfo dropInfo) { var data = dropInfo.Data; - var dataObject = data as DataObject; - if (dataObject != null) + if (data is DataObject dataObject) { var dataFormat = DataFormats.GetDataFormat(DataFormats.Serializable); data = dataObject.GetDataPresent(dataFormat.Name) ? dataObject.GetData(dataFormat.Name) : data; @@ -112,7 +160,7 @@ private static bool ShouldCopyData(IDropInfo dropInfo, DragDropKeyStates dragDro return false; } - var copyData = ((dragDropCopyKeyState != default(DragDropKeyStates)) && dropInfo.KeyStates.HasFlag(dragDropCopyKeyState)) + var copyData = ((dragDropCopyKeyState != default) && dropInfo.KeyStates.HasFlag(dragDropCopyKeyState)) || dragDropCopyKeyState.HasFlag(DragDropKeyStates.LeftMouseButton); return copyData; } From 723f145a57b621a8694c24260504a423ef120530 Mon Sep 17 00:00:00 2001 From: punker76 Date: Tue, 2 Nov 2021 17:56:36 +0100 Subject: [PATCH 21/29] (Housekeeping) update documentation --- .../DragDrop.Properties.cs | 1109 ++++++++++------- src/GongSolutions.WPF.DragDrop/DragDrop.cs | 16 + .../DragDropPreview.cs | 2 + 3 files changed, 657 insertions(+), 470 deletions(-) diff --git a/src/GongSolutions.WPF.DragDrop/DragDrop.Properties.cs b/src/GongSolutions.WPF.DragDrop/DragDrop.Properties.cs index d0a94cdf..c368a7cb 100644 --- a/src/GongSolutions.WPF.DragDrop/DragDrop.Properties.cs +++ b/src/GongSolutions.WPF.DragDrop/DragDrop.Properties.cs @@ -14,6 +14,21 @@ public static partial class DragDrop /// public static DataFormat DataFormat { get; } = DataFormats.GetDataFormat("GongSolutions.Wpf.DragDrop"); + /// + /// Gets the default DragHandler. + /// + public static IDragSource DefaultDragHandler { get; } = new DefaultDragHandler(); + + /// + /// Gets the default DropHandler. + /// + public static IDropTarget DefaultDropHandler { get; } = new DefaultDropHandler(); + + /// + /// Gets the default RootElementFinder. + /// + public static IRootElementFinder DefaultRootElementFinder { get; } = new RootElementFinder(); + /// /// Gets or sets the data format which will be used for the drag and drop operations. /// @@ -24,20 +39,24 @@ public static readonly DependencyProperty DataFormatProperty typeof(DragDrop), new PropertyMetadata(DragDrop.DataFormat)); - /// - /// Gets the data format which will be used for the drag and drop operations. - /// - public static DataFormat GetDataFormat(UIElement source) + /// Helper for getting from . + /// to read from. + /// Gets the data format which will be used for the drag and drop operations. + /// DataFormat property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static DataFormat GetDataFormat(DependencyObject element) { - return (DataFormat)source.GetValue(DataFormatProperty); + return (DataFormat)element.GetValue(DataFormatProperty); } - /// - /// Sets the data format which will be used for the drag and drop operations. - /// - public static void SetDataFormat(UIElement source, DataFormat value) + /// Helper for setting on . + /// to set on. + /// DataFormat property value. + /// Sets the data format which will be used for the drag and drop operations. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetDataFormat(DependencyObject element, DataFormat value) { - source.SetValue(DataFormatProperty, value); + element.SetValue(DataFormatProperty, value); } /// @@ -47,42 +66,31 @@ public static readonly DependencyProperty IsDragSourceProperty = DependencyProperty.RegisterAttached("IsDragSource", typeof(bool), typeof(DragDrop), - new UIPropertyMetadata(false, OnIsDragSourceChanged)); + new PropertyMetadata(false, OnIsDragSourceChanged)); - /// - /// Gets whether the control can be used as drag source. - /// - public static bool GetIsDragSource(UIElement target) + /// Helper for getting from . + /// to read from. + /// Gets whether the control can be used as drag source. + /// IsDragSource property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static bool GetIsDragSource(DependencyObject element) { - return (bool)target.GetValue(IsDragSourceProperty); + return (bool)element.GetValue(IsDragSourceProperty); } - /// - /// Sets whether the control can be used as drag source. - /// - public static void SetIsDragSource(UIElement target, bool value) + /// Helper for setting on . + /// to set on. + /// IsDragSource property value. + /// Sets whether the control can be used as drag source. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetIsDragSource(DependencyObject element, bool value) { - target.SetValue(IsDragSourceProperty, value); + element.SetValue(IsDragSourceProperty, value); } private static void OnIsDragSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { - var uiElement = (UIElement)d; - - if ((bool)e.NewValue) - { - uiElement.PreviewMouseLeftButtonDown += DragSourceOnMouseLeftButtonDown; - uiElement.PreviewMouseLeftButtonUp += DragSourceOnMouseLeftButtonUp; - uiElement.PreviewMouseMove += DragSourceOnMouseMove; - - uiElement.PreviewTouchDown += DragSourceOnTouchDown; - uiElement.PreviewTouchUp += DragSourceOnTouchUp; - uiElement.PreviewTouchMove += DragSourceOnTouchMove; - - uiElement.QueryContinueDrag += DragSourceOnQueryContinueDrag; - uiElement.GiveFeedback += DragSourceOnGiveFeedback; - } - else + if (e.OldValue != e.NewValue && d is UIElement uiElement) { uiElement.PreviewMouseLeftButtonDown -= DragSourceOnMouseLeftButtonDown; uiElement.PreviewMouseLeftButtonUp -= DragSourceOnMouseLeftButtonUp; @@ -94,6 +102,20 @@ private static void OnIsDragSourceChanged(DependencyObject d, DependencyProperty uiElement.QueryContinueDrag -= DragSourceOnQueryContinueDrag; uiElement.GiveFeedback -= DragSourceOnGiveFeedback; + + if ((bool)e.NewValue) + { + uiElement.PreviewMouseLeftButtonDown += DragSourceOnMouseLeftButtonDown; + uiElement.PreviewMouseLeftButtonUp += DragSourceOnMouseLeftButtonUp; + uiElement.PreviewMouseMove += DragSourceOnMouseMove; + + uiElement.PreviewTouchDown += DragSourceOnTouchDown; + uiElement.PreviewTouchUp += DragSourceOnTouchUp; + uiElement.PreviewTouchMove += DragSourceOnTouchMove; + + uiElement.QueryContinueDrag += DragSourceOnQueryContinueDrag; + uiElement.GiveFeedback += DragSourceOnGiveFeedback; + } } } @@ -104,60 +126,43 @@ public static readonly DependencyProperty IsDropTargetProperty = DependencyProperty.RegisterAttached("IsDropTarget", typeof(bool), typeof(DragDrop), - new UIPropertyMetadata(false, OnIsDropTargetChanged)); + new PropertyMetadata(false, OnIsDropTargetChanged)); - /// - /// Gets whether the control can be used as drop target. - /// - public static bool GetIsDropTarget(UIElement target) + /// Helper for getting from . + /// to read from. + /// Gets whether the control can be used as drop target. + /// IsDropTarget property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static bool GetIsDropTarget(DependencyObject element) { - return (bool)target.GetValue(IsDropTargetProperty); + return (bool)element.GetValue(IsDropTargetProperty); } - /// - /// Sets whether the control can be used as drop target. - /// - public static void SetIsDropTarget(UIElement target, bool value) + /// Helper for setting on . + /// to set on. + /// IsDropTarget property value. + /// Sets whether the control can be used as drop target. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetIsDropTarget(DependencyObject element, bool value) { - target.SetValue(IsDropTargetProperty, value); + element.SetValue(IsDropTargetProperty, value); } private static void OnIsDropTargetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { - var uiElement = (UIElement)d; - - if ((bool)e.NewValue) + if (e.OldValue != e.NewValue && d is UIElement uiElement) { - uiElement.AllowDrop = true; - - RegisterDragDropEvents(uiElement, GetDropEventType(d)); - } - else - { - uiElement.AllowDrop = false; + uiElement.AllowDrop = (bool)e.NewValue; UnregisterDragDropEvents(uiElement, GetDropEventType(d)); - Mouse.OverrideCursor = null; + if ((bool)e.NewValue) + { + RegisterDragDropEvents(uiElement, GetDropEventType(d)); + } } } - /// - /// Gets which type of events are subscribed for the drag and drop events. - /// - public static EventType GetDropEventType(DependencyObject obj) - { - return (EventType)obj.GetValue(DropEventTypeProperty); - } - - /// - /// Sets which type of events are subscribed for the drag and drop events. - /// - public static void SetDropEventType(DependencyObject obj, EventType value) - { - obj.SetValue(DropEventTypeProperty, value); - } - /// /// Gets or sets the events which are subscribed for the drag and drop events. /// @@ -167,17 +172,38 @@ public static readonly DependencyProperty DropEventTypeProperty typeof(DragDrop), new PropertyMetadata(EventType.Auto, OnDropEventTypeChanged)); - private static void OnDropEventTypeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + /// Helper for getting from . + /// to read from. + /// Gets which type of events are subscribed for the drag and drop events. + /// DropEventType property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static EventType GetDropEventType(DependencyObject element) + { + return (EventType)element.GetValue(DropEventTypeProperty); + } + + /// Helper for setting on . + /// to set on. + /// DropEventType property value. + /// Sets which type of events are subscribed for the drag and drop events. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetDropEventType(DependencyObject element, EventType value) { - var uiElement = (UIElement)d; + element.SetValue(DropEventTypeProperty, value); + } - if (!GetIsDropTarget(uiElement)) + private static void OnDropEventTypeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (e.OldValue != e.NewValue && d is UIElement uiElement) { - return; - } + if (!GetIsDropTarget(uiElement)) + { + return; + } - UnregisterDragDropEvents(uiElement, (EventType)e.OldValue); - RegisterDragDropEvents(uiElement, (EventType)e.NewValue); + UnregisterDragDropEvents(uiElement, (EventType)e.OldValue); + RegisterDragDropEvents(uiElement, (EventType)e.NewValue); + } } private static void RegisterDragDropEvents(UIElement uiElement, EventType eventType) @@ -298,6 +324,8 @@ private static void UnregisterDragDropEvents(UIElement uiElement, EventType even default: throw new ArgumentException("Unknown value for eventType: " + eventType.ToString(), nameof(eventType)); } + + Mouse.OverrideCursor = null; } /// @@ -307,27 +335,31 @@ public static readonly DependencyProperty CanDragWithMouseRightButtonProperty = DependencyProperty.RegisterAttached("CanDragWithMouseRightButton", typeof(bool), typeof(DragDrop), - new UIPropertyMetadata(false, OnCanDragWithMouseRightButtonChanged)); + new PropertyMetadata(false, OnCanDragWithMouseRightButtonChanged)); - /// - /// Gets whether the control can be used as drag source together with the right mouse. - /// - public static bool GetCanDragWithMouseRightButton(UIElement target) + /// Helper for getting from . + /// to read from. + /// Gets whether the control can be used as drag source together with the right mouse. + /// CanDragWithMouseRightButton property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static bool GetCanDragWithMouseRightButton(DependencyObject element) { - return (bool)target.GetValue(CanDragWithMouseRightButtonProperty); + return (bool)element.GetValue(CanDragWithMouseRightButtonProperty); } - /// - /// Sets whether the control can be used as drag source together with the right mouse. - /// - public static void SetCanDragWithMouseRightButton(UIElement target, bool value) + /// Helper for setting on . + /// to set on. + /// CanDragWithMouseRightButton property value. + /// Sets whether the control can be used as drag source together with the right mouse. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetCanDragWithMouseRightButton(DependencyObject element, bool value) { - target.SetValue(CanDragWithMouseRightButtonProperty, value); + element.SetValue(CanDragWithMouseRightButtonProperty, value); } private static void OnCanDragWithMouseRightButtonChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { - if (d is UIElement uiElement) + if (e.OldValue != e.NewValue && d is UIElement uiElement) { uiElement.PreviewMouseRightButtonDown -= DragSourceOnMouseRightButtonDown; uiElement.PreviewMouseRightButtonUp -= DragSourceOnMouseRightButtonUp; @@ -340,21 +372,6 @@ private static void OnCanDragWithMouseRightButtonChanged(DependencyObject d, Dep } } - /// - /// Gets the default DragHandler. - /// - public static IDragSource DefaultDragHandler { get; } = new DefaultDragHandler(); - - /// - /// Gets the default DropHandler. - /// - public static IDropTarget DefaultDropHandler { get; } = new DefaultDropHandler(); - - /// - /// Gets the default RootElementFinder. - /// - public static IRootElementFinder DefaultRootElementFinder { get; } = new RootElementFinder(); - /// /// Gets or sets the handler for the drag operation. /// @@ -363,20 +380,24 @@ public static readonly DependencyProperty DragHandlerProperty typeof(IDragSource), typeof(DragDrop)); - /// - /// Gets the handler for the drag operation. - /// - public static IDragSource GetDragHandler(UIElement target) + /// Helper for getting from . + /// to read from. + /// Gets the handler for the drag operation. + /// DragHandler property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static IDragSource GetDragHandler(DependencyObject element) { - return (IDragSource)target.GetValue(DragHandlerProperty); + return (IDragSource)element.GetValue(DragHandlerProperty); } - /// - /// Sets the handler for the drag operation. - /// - public static void SetDragHandler(UIElement target, IDragSource value) + /// Helper for setting on . + /// to set on. + /// DragHandler property value. + /// Sets the handler for the drag operation. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetDragHandler(DependencyObject element, IDragSource value) { - target.SetValue(DragHandlerProperty, value); + element.SetValue(DragHandlerProperty, value); } /// @@ -387,20 +408,24 @@ public static readonly DependencyProperty DropHandlerProperty typeof(IDropTarget), typeof(DragDrop)); - /// - /// Gets the handler for the drop operation. - /// - public static IDropTarget GetDropHandler(UIElement target) + /// Helper for getting from . + /// to read from. + /// Gets the handler for the drop operation. + /// DropHandler property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static IDropTarget GetDropHandler(DependencyObject element) { - return (IDropTarget)target.GetValue(DropHandlerProperty); + return (IDropTarget)element.GetValue(DropHandlerProperty); } - /// - /// Sets the handler for the drop operation. - /// - public static void SetDropHandler(UIElement target, IDropTarget value) + /// Helper for setting on . + /// to set on. + /// DropHandler property value. + /// Sets the handler for the drop operation. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetDropHandler(DependencyObject element, IDropTarget value) { - target.SetValue(DropHandlerProperty, value); + element.SetValue(DropHandlerProperty, value); } /// @@ -411,17 +436,21 @@ public static readonly DependencyProperty DragInfoBuilderProperty typeof(IDragInfoBuilder), typeof(DragDrop)); - /// - /// Gets the drag info builder for the drag operation. - /// + /// Helper for getting from . + /// to read from. + /// Gets the drag info builder for the drag operation. + /// DragInfoBuilder property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] public static IDragInfoBuilder GetDragInfoBuilder(DependencyObject element) { return (IDragInfoBuilder)element.GetValue(DragInfoBuilderProperty); } - /// - /// Sets the drag info builder for the drag operation. - /// + /// Helper for setting on . + /// to set on. + /// DragInfoBuilder property value. + /// Sets the drag info builder for the drag operation. + [AttachedPropertyBrowsableForType(typeof(UIElement))] public static void SetDragInfoBuilder(DependencyObject element, IDragInfoBuilder value) { element.SetValue(DragInfoBuilderProperty, value); @@ -435,20 +464,24 @@ public static readonly DependencyProperty DropInfoBuilderProperty typeof(IDropInfoBuilder), typeof(DragDrop)); - /// - /// Gets the drop info builder for the drop operation. - /// - public static void SetDropInfoBuilder(DependencyObject element, IDropInfoBuilder value) + /// Helper for getting from . + /// to read from. + /// Gets the drop info builder for the drop operation. + /// DropInfoBuilder property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static IDropInfoBuilder GetDropInfoBuilder(DependencyObject element) { - element.SetValue(DropInfoBuilderProperty, value); + return (IDropInfoBuilder)element.GetValue(DropInfoBuilderProperty); } - /// - /// Sets the drop info builder for the drop operation. - /// - public static IDropInfoBuilder GetDropInfoBuilder(DependencyObject element) + /// Helper for setting on . + /// to set on. + /// DropInfoBuilder property value. + /// Sets the drop info builder for the drop operation. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetDropInfoBuilder(DependencyObject element, IDropInfoBuilder value) { - return (IDropInfoBuilder)element.GetValue(DropInfoBuilderProperty); + element.SetValue(DropInfoBuilderProperty, value); } /// @@ -460,20 +493,24 @@ public static readonly DependencyProperty DropScrollingModeProperty typeof(DragDrop), new PropertyMetadata(ScrollingMode.Both)); - /// - /// Gets the ScrollingMode for the drop operation. - /// - public static ScrollingMode GetDropScrollingMode(UIElement target) + /// Helper for getting from . + /// to read from. + /// Gets the ScrollingMode for the drop operation. + /// DropScrollingMode property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static ScrollingMode GetDropScrollingMode(DependencyObject element) { - return (ScrollingMode)target.GetValue(DropScrollingModeProperty); + return (ScrollingMode)element.GetValue(DropScrollingModeProperty); } - /// - /// Sets the ScrollingMode for the drop operation. - /// - public static void SetDropScrollingMode(UIElement target, ScrollingMode value) + /// Helper for setting on . + /// to set on. + /// DropScrollingMode property value. + /// Sets the ScrollingMode for the drop operation. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetDropScrollingMode(DependencyObject element, ScrollingMode value) { - target.SetValue(DropScrollingModeProperty, value); + element.SetValue(DropScrollingModeProperty, value); } /// @@ -485,20 +522,24 @@ public static readonly DependencyProperty ShowAlwaysDropTargetAdornerProperty typeof(DragDrop), new PropertyMetadata(false)); - /// - /// Gets whether to show the DropTargetAdorner (DropTargetInsertionAdorner) on an empty target too. - /// - public static bool GetShowAlwaysDropTargetAdorner(UIElement target) + /// Helper for getting from . + /// to read from. + /// Gets whether to show the DropTargetAdorner (DropTargetInsertionAdorner) on an empty target too. + /// ShowAlwaysDropTargetAdorner property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static bool GetShowAlwaysDropTargetAdorner(DependencyObject element) { - return (bool)target.GetValue(ShowAlwaysDropTargetAdornerProperty); + return (bool)element.GetValue(ShowAlwaysDropTargetAdornerProperty); } - /// - /// Sets whether to show the DropTargetAdorner (DropTargetInsertionAdorner) on an empty target too. - /// - public static void SetShowAlwaysDropTargetAdorner(UIElement target, bool value) + /// Helper for setting on . + /// to set on. + /// ShowAlwaysDropTargetAdorner property value. + /// Sets whether to show the DropTargetAdorner (DropTargetInsertionAdorner) on an empty target too. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetShowAlwaysDropTargetAdorner(DependencyObject element, bool value) { - target.SetValue(ShowAlwaysDropTargetAdornerProperty, value); + element.SetValue(ShowAlwaysDropTargetAdornerProperty, value); } /// @@ -510,20 +551,24 @@ public static readonly DependencyProperty DropTargetAdornerBrushProperty typeof(DragDrop), new PropertyMetadata((Brush)null)); - /// - /// Gets the brush for the DropTargetAdorner. - /// - public static Brush GetDropTargetAdornerBrush(UIElement target) + /// Helper for getting from . + /// to read from. + /// Gets the brush for the DropTargetAdorner. + /// DropTargetAdornerBrush property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static Brush GetDropTargetAdornerBrush(DependencyObject element) { - return (Brush)target.GetValue(DropTargetAdornerBrushProperty); + return (Brush)element.GetValue(DropTargetAdornerBrushProperty); } - /// - /// Sets the brush for the DropTargetAdorner. - /// - public static void SetDropTargetAdornerBrush(UIElement target, Brush value) + /// Helper for setting on . + /// to set on. + /// DropTargetAdornerBrush property value. + /// Sets the brush for the DropTargetAdorner. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetDropTargetAdornerBrush(DependencyObject element, Brush value) { - target.SetValue(DropTargetAdornerBrushProperty, value); + element.SetValue(DropTargetAdornerBrushProperty, value); } /// @@ -533,22 +578,26 @@ public static readonly DependencyProperty DragDropContextProperty = DependencyProperty.RegisterAttached("DragDropContext", typeof(string), typeof(DragDrop), - new UIPropertyMetadata(string.Empty)); + new PropertyMetadata(string.Empty)); - /// - /// Gets a context for a control. Only controls with the same context are allowed for drag or drop actions. - /// - public static string GetDragDropContext(UIElement target) + /// Helper for getting from . + /// to read from. + /// Gets a context for a control. Only controls with the same context are allowed for drag or drop actions. + /// DragDropContext property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static string GetDragDropContext(DependencyObject element) { - return (string)target.GetValue(DragDropContextProperty); + return (string)element.GetValue(DragDropContextProperty); } - /// - /// Sets a context for a control. Only controls with the same context are allowed for drag or drop actions. - /// - public static void SetDragDropContext(UIElement target, string value) + /// Helper for setting on . + /// to set on. + /// DragDropContext property value. + /// Sets a context for a control. Only controls with the same context are allowed for drag or drop actions. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetDragDropContext(DependencyObject element, string value) { - target.SetValue(DragDropContextProperty, value); + element.SetValue(DragDropContextProperty, value); } /// @@ -560,20 +609,24 @@ public static readonly DependencyProperty DragSourceIgnoreProperty typeof(DragDrop), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.Inherits)); - /// - /// Gets whether an element under the mouse should be ignored for the drag operation. - /// - public static bool GetDragSourceIgnore(UIElement source) + /// Helper for getting from . + /// to read from. + /// Gets whether an element under the mouse should be ignored for the drag operation. + /// DragSourceIgnore property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static bool GetDragSourceIgnore(DependencyObject element) { - return (bool)source.GetValue(DragSourceIgnoreProperty); + return (bool)element.GetValue(DragSourceIgnoreProperty); } - /// - /// Sets whether an element under the mouse should be ignored for the drag operation. - /// - public static void SetDragSourceIgnore(UIElement source, bool value) + /// Helper for setting on . + /// to set on. + /// DragSourceIgnore property value. + /// Sets whether an element under the mouse should be ignored for the drag operation. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetDragSourceIgnore(DependencyObject element, bool value) { - source.SetValue(DragSourceIgnoreProperty, value); + element.SetValue(DragSourceIgnoreProperty, value); } /// @@ -586,20 +639,24 @@ public static readonly DependencyProperty DragDirectlySelectedOnlyProperty typeof(DragDrop), new PropertyMetadata(false)); - /// - /// Gets whether the drag action should be started only directly on a selected item. - /// - public static bool GetDragDirectlySelectedOnly(DependencyObject obj) + /// Helper for getting from . + /// to read from. + /// Gets whether the drag action should be started only directly on a selected item. + /// DragDirectlySelectedOnly property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static bool GetDragDirectlySelectedOnly(DependencyObject element) { - return (bool)obj.GetValue(DragDirectlySelectedOnlyProperty); + return (bool)element.GetValue(DragDirectlySelectedOnlyProperty); } - /// - /// Sets whether the drag action should be started only directly on a selected item. - /// - public static void SetDragDirectlySelectedOnly(DependencyObject obj, bool value) + /// Helper for setting on . + /// to set on. + /// DragDirectlySelectedOnly property value. + /// Sets whether the drag action should be started only directly on a selected item. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetDragDirectlySelectedOnly(DependencyObject element, bool value) { - obj.SetValue(DragDirectlySelectedOnlyProperty, value); + element.SetValue(DragDirectlySelectedOnlyProperty, value); } /// @@ -614,20 +671,24 @@ public static readonly DependencyProperty DragDropCopyKeyStateProperty typeof(DragDrop), new PropertyMetadata(default(DragDropKeyStates))); - /// - /// Gets the copy key state which indicates the effect of the drag drop operation. - /// - public static DragDropKeyStates GetDragDropCopyKeyState(UIElement target) + /// Helper for getting from . + /// to read from. + /// Gets the copy key state which indicates the effect of the drag drop operation. + /// DragDropCopyKeyState property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static DragDropKeyStates GetDragDropCopyKeyState(DependencyObject element) { - return (DragDropKeyStates)target.GetValue(DragDropCopyKeyStateProperty); + return (DragDropKeyStates)element.GetValue(DragDropCopyKeyStateProperty); } - /// - /// Sets the copy key state which indicates the effect of the drag drop operation. - /// - public static void SetDragDropCopyKeyState(UIElement target, DragDropKeyStates value) + /// Helper for setting on . + /// to set on. + /// DragDropCopyKeyState property value. + /// Sets the copy key state which indicates the effect of the drag drop operation. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetDragDropCopyKeyState(DependencyObject element, DragDropKeyStates value) { - target.SetValue(DragDropCopyKeyStateProperty, value); + element.SetValue(DragDropCopyKeyStateProperty, value); } /// @@ -639,20 +700,24 @@ public static readonly DependencyProperty UseDefaultDragAdornerProperty typeof(DragDrop), new PropertyMetadata(false)); - /// - /// Gets whether if the default DragAdorner is used. - /// - public static bool GetUseDefaultDragAdorner(UIElement target) + /// Helper for getting from . + /// to read from. + /// Gets whether if the default DragAdorner is used. + /// UseDefaultDragAdorner property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static bool GetUseDefaultDragAdorner(DependencyObject element) { - return (bool)target.GetValue(UseDefaultDragAdornerProperty); + return (bool)element.GetValue(UseDefaultDragAdornerProperty); } - /// - /// Sets whether if the default DragAdorner should be use. - /// - public static void SetUseDefaultDragAdorner(UIElement target, bool value) + /// Helper for setting on . + /// to set on. + /// UseDefaultDragAdorner property value. + /// Sets whether if the default DragAdorner should be use. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetUseDefaultDragAdorner(DependencyObject element, bool value) { - target.SetValue(UseDefaultDragAdornerProperty, value); + element.SetValue(UseDefaultDragAdornerProperty, value); } /// @@ -664,20 +729,24 @@ public static readonly DependencyProperty DefaultDragAdornerOpacityProperty typeof(DragDrop), new PropertyMetadata(0.8)); - /// - /// Gets the opacity of the default DragAdorner. - /// - public static double GetDefaultDragAdornerOpacity(UIElement target) + /// Helper for getting from . + /// to read from. + /// Gets the opacity of the default DragAdorner. + /// DefaultDragAdornerOpacity property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static double GetDefaultDragAdornerOpacity(DependencyObject element) { - return (double)target.GetValue(DefaultDragAdornerOpacityProperty); + return (double)element.GetValue(DefaultDragAdornerOpacityProperty); } - /// - /// Sets the opacity of the default DragAdorner. - /// - public static void SetDefaultDragAdornerOpacity(UIElement target, double value) + /// Helper for setting on . + /// to set on. + /// DefaultDragAdornerOpacity property value. + /// Sets the opacity of the default DragAdorner. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetDefaultDragAdornerOpacity(DependencyObject element, double value) { - target.SetValue(DefaultDragAdornerOpacityProperty, value); + element.SetValue(DefaultDragAdornerOpacityProperty, value); } /// @@ -689,20 +758,24 @@ public static readonly DependencyProperty DragMouseAnchorPointProperty typeof(DragDrop), new PropertyMetadata(new Point(0, 1))); - /// - /// Gets the horizontal and vertical proportion at which the pointer will anchor on the DragAdorner. - /// - public static Point GetDragMouseAnchorPoint(UIElement target) + /// Helper for getting from . + /// to read from. + /// Gets the horizontal and vertical proportion at which the pointer will anchor on the DragAdorner. + /// DragMouseAnchorPoint property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static Point GetDragMouseAnchorPoint(DependencyObject element) { - return (Point)target.GetValue(DragMouseAnchorPointProperty); + return (Point)element.GetValue(DragMouseAnchorPointProperty); } - /// - /// Sets the horizontal and vertical proportion at which the pointer will anchor on the DragAdorner. - /// - public static void SetDragMouseAnchorPoint(UIElement target, Point value) + /// Helper for setting on . + /// to set on. + /// DragMouseAnchorPoint property value. + /// Sets the horizontal and vertical proportion at which the pointer will anchor on the DragAdorner. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetDragMouseAnchorPoint(DependencyObject element, Point value) { - target.SetValue(DragMouseAnchorPointProperty, value); + element.SetValue(DragMouseAnchorPointProperty, value); } /// @@ -714,18 +787,22 @@ public static readonly DependencyProperty DragAdornerTranslationProperty typeof(DragDrop), new PropertyMetadata(new Point(-4, -4))); - /// - /// Gets the translation transform which will be used for the DragAdorner. - /// - public static Point GetDragAdornerTranslation(UIElement element) + /// Helper for getting from . + /// to read from. + /// Gets the translation transform which will be used for the DragAdorner. + /// DragAdornerTranslation property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static Point GetDragAdornerTranslation(DependencyObject element) { return (Point)element.GetValue(DragAdornerTranslationProperty); } - /// - /// Sets the translation transform which will be used for the DragAdorner. - /// - public static void SetDragAdornerTranslation(UIElement element, Point value) + /// Helper for setting on . + /// to set on. + /// DragAdornerTranslation property value. + /// Sets the translation transform which will be used for the DragAdorner. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetDragAdornerTranslation(DependencyObject element, Point value) { element.SetValue(DragAdornerTranslationProperty, value); } @@ -739,18 +816,22 @@ public static readonly DependencyProperty EffectAdornerTranslationProperty typeof(DragDrop), new PropertyMetadata(new Point(16, 16))); - /// - /// Gets the translation transform which will be used for the EffectAdorner. - /// - public static Point GetEffectAdornerTranslation(UIElement element) + /// Helper for getting from . + /// to read from. + /// Gets the translation transform which will be used for the EffectAdorner. + /// EffectAdornerTranslation property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static Point GetEffectAdornerTranslation(DependencyObject element) { return (Point)element.GetValue(EffectAdornerTranslationProperty); } - /// - /// Sets the translation transform which will be used for the EffectAdorner. - /// - public static void SetEffectAdornerTranslation(UIElement element, Point value) + /// Helper for setting on . + /// to set on. + /// EffectAdornerTranslation property value. + /// Sets the translation transform which will be used for the EffectAdorner. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetEffectAdornerTranslation(DependencyObject element, Point value) { element.SetValue(EffectAdornerTranslationProperty, value); } @@ -763,20 +844,24 @@ public static readonly DependencyProperty DragAdornerTemplateProperty typeof(DataTemplate), typeof(DragDrop)); - /// - /// Gets the DataTemplate for the DragAdorner. - /// - public static DataTemplate GetDragAdornerTemplate(UIElement target) + /// Helper for getting from . + /// to read from. + /// Gets the DataTemplate for the DragAdorner. + /// DragAdornerTemplate property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static DataTemplate GetDragAdornerTemplate(DependencyObject element) { - return (DataTemplate)target.GetValue(DragAdornerTemplateProperty); + return (DataTemplate)element.GetValue(DragAdornerTemplateProperty); } - /// - /// Sets the DataTemplate for the DragAdorner. - /// - public static void SetDragAdornerTemplate(UIElement target, DataTemplate value) + /// Helper for setting on . + /// to set on. + /// DragAdornerTemplate property value. + /// Sets the DataTemplate for the DragAdorner. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetDragAdornerTemplate(DependencyObject element, DataTemplate value) { - target.SetValue(DragAdornerTemplateProperty, value); + element.SetValue(DragAdornerTemplateProperty, value); } /// @@ -787,20 +872,24 @@ public static readonly DependencyProperty DropAdornerTemplateProperty typeof(DataTemplate), typeof(DragDrop)); - /// - /// Gets the DataTemplate for the DragAdorner based on the DropTarget. - /// - public static DataTemplate GetDropAdornerTemplate(UIElement target) + /// Helper for getting from . + /// to read from. + /// Gets the DataTemplate for the DragAdorner based on the DropTarget. + /// DropAdornerTemplate property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static DataTemplate GetDropAdornerTemplate(DependencyObject element) { - return (DataTemplate)target.GetValue(DropAdornerTemplateProperty); + return (DataTemplate)element.GetValue(DropAdornerTemplateProperty); } - /// - /// Sets the DataTemplate for the DragAdorner based on the DropTarget. - /// - public static void SetDropAdornerTemplate(UIElement target, DataTemplate value) + /// Helper for setting on . + /// to set on. + /// DropAdornerTemplate property value. + /// Sets the DataTemplate for the DragAdorner based on the DropTarget. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetDropAdornerTemplate(DependencyObject element, DataTemplate value) { - target.SetValue(DropAdornerTemplateProperty, value); + element.SetValue(DropAdornerTemplateProperty, value); } /// @@ -812,20 +901,24 @@ public static readonly DependencyProperty DragAdornerTemplateSelectorProperty typeof(DragDrop), new PropertyMetadata(default(DataTemplateSelector))); - /// - /// Gets the DataTemplateSelector for the DragAdorner. - /// - public static void SetDragAdornerTemplateSelector(DependencyObject element, DataTemplateSelector value) + /// Helper for getting from . + /// to read from. + /// Gets the DataTemplateSelector for the DragAdorner. + /// DragAdornerTemplateSelector property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static DataTemplateSelector GetDragAdornerTemplateSelector(DependencyObject element) { - element.SetValue(DragAdornerTemplateSelectorProperty, value); + return (DataTemplateSelector)element.GetValue(DragAdornerTemplateSelectorProperty); } - /// - /// Gets the DataTemplateSelector for the DragAdorner. - /// - public static DataTemplateSelector GetDragAdornerTemplateSelector(DependencyObject element) + /// Helper for setting on . + /// to set on. + /// DragAdornerTemplateSelector property value. + /// Sets the DataTemplateSelector for the DragAdorner. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetDragAdornerTemplateSelector(DependencyObject element, DataTemplateSelector value) { - return (DataTemplateSelector)element.GetValue(DragAdornerTemplateSelectorProperty); + element.SetValue(DragAdornerTemplateSelectorProperty, value); } /// @@ -837,20 +930,24 @@ public static readonly DependencyProperty DropAdornerTemplateSelectorProperty typeof(DragDrop), new PropertyMetadata(default(DataTemplateSelector))); - /// - /// Gets the DataTemplateSelector for the DragAdorner based on the DropTarget. - /// - public static void SetDropAdornerTemplateSelector(DependencyObject element, DataTemplateSelector value) + /// Helper for getting from . + /// to read from. + /// Gets the DataTemplateSelector for the DragAdorner based on the DropTarget. + /// DropAdornerTemplateSelector property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static DataTemplateSelector GetDropAdornerTemplateSelector(DependencyObject element) { - element.SetValue(DropAdornerTemplateSelectorProperty, value); + return (DataTemplateSelector)element.GetValue(DropAdornerTemplateSelectorProperty); } - /// - /// Gets the DataTemplateSelector for the DragAdorner based on the DropTarget. - /// - public static DataTemplateSelector GetDropAdornerTemplateSelector(DependencyObject element) + /// Helper for setting on . + /// to set on. + /// DropAdornerTemplateSelector property value. + /// Sets the DataTemplateSelector for the DragAdorner based on the DropTarget. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetDropAdornerTemplateSelector(DependencyObject element, DataTemplateSelector value) { - return (DataTemplateSelector)element.GetValue(DropAdornerTemplateSelectorProperty); + element.SetValue(DropAdornerTemplateSelectorProperty, value); } /// @@ -862,20 +959,24 @@ public static readonly DependencyProperty UseVisualSourceItemSizeForDragAdornerP typeof(DragDrop), new PropertyMetadata(false)); - /// - /// Get the flag which indicates if the DragAdorner use the descendant bounds of the VisualSourceItem as MinWidth. - /// - public static bool GetUseVisualSourceItemSizeForDragAdorner(UIElement target) + /// Helper for getting from . + /// to read from. + /// Gets the flag which indicates if the DragAdorner use the descendant bounds of the VisualSourceItem as MinWidth. + /// UseVisualSourceItemSizeForDragAdorner property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static bool GetUseVisualSourceItemSizeForDragAdorner(DependencyObject element) { - return (bool)target.GetValue(UseVisualSourceItemSizeForDragAdornerProperty); + return (bool)element.GetValue(UseVisualSourceItemSizeForDragAdornerProperty); } - /// - /// Set the flag which indicates if the DragAdorner use the descendant bounds of the VisualSourceItem as MinWidth. - /// - public static void SetUseVisualSourceItemSizeForDragAdorner(UIElement target, bool value) + /// Helper for setting on . + /// to set on. + /// UseVisualSourceItemSizeForDragAdorner property value. + /// Sets the flag which indicates if the DragAdorner use the descendant bounds of the VisualSourceItem as MinWidth. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetUseVisualSourceItemSizeForDragAdorner(DependencyObject element, bool value) { - target.SetValue(UseVisualSourceItemSizeForDragAdornerProperty, value); + element.SetValue(UseVisualSourceItemSizeForDragAdornerProperty, value); } /// @@ -887,20 +988,24 @@ public static readonly DependencyProperty UseDefaultEffectDataTemplateProperty typeof(DragDrop), new PropertyMetadata(false)); - /// - /// Gets whether if the default DataTemplate for the effects should be use. - /// - public static bool GetUseDefaultEffectDataTemplate(UIElement target) + /// Helper for getting from . + /// to read from. + /// Gets whether if the default DataTemplate for the effects should be use. + /// UseDefaultEffectDataTemplate property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static bool GetUseDefaultEffectDataTemplate(DependencyObject element) { - return (bool)target.GetValue(UseDefaultEffectDataTemplateProperty); + return (bool)element.GetValue(UseDefaultEffectDataTemplateProperty); } - /// - /// Sets whether if the default DataTemplate for the effects should be use. - /// - public static void SetUseDefaultEffectDataTemplate(UIElement target, bool value) + /// Helper for setting on . + /// to set on. + /// UseDefaultEffectDataTemplate property value. + /// Sets whether if the default DataTemplate for the effects should be use. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetUseDefaultEffectDataTemplate(DependencyObject element, bool value) { - target.SetValue(UseDefaultEffectDataTemplateProperty, value); + element.SetValue(UseDefaultEffectDataTemplateProperty, value); } /// @@ -912,20 +1017,24 @@ public static readonly DependencyProperty EffectNoneAdornerTemplateProperty typeof(DragDrop), new PropertyMetadata((DataTemplate)null)); - /// - /// Gets a EffectAdorner DataTemplate for effect type None. - /// - public static DataTemplate GetEffectNoneAdornerTemplate(UIElement target) + /// Helper for getting from . + /// to read from. + /// Gets a EffectAdorner DataTemplate for effect type None. + /// EffectNoneAdornerTemplate property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static DataTemplate GetEffectNoneAdornerTemplate(DependencyObject element) { - return (DataTemplate)target.GetValue(EffectNoneAdornerTemplateProperty); + return (DataTemplate)element.GetValue(EffectNoneAdornerTemplateProperty); } - /// - /// Sets a EffectAdorner DataTemplate for effect type None. - /// - public static void SetEffectNoneAdornerTemplate(UIElement target, DataTemplate value) + /// Helper for setting on . + /// to set on. + /// EffectNoneAdornerTemplate property value. + /// Sets a EffectAdorner DataTemplate for effect type None. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetEffectNoneAdornerTemplate(DependencyObject element, DataTemplate value) { - target.SetValue(EffectNoneAdornerTemplateProperty, value); + element.SetValue(EffectNoneAdornerTemplateProperty, value); } /// @@ -937,20 +1046,24 @@ public static readonly DependencyProperty EffectCopyAdornerTemplateProperty typeof(DragDrop), new PropertyMetadata((DataTemplate)null)); - /// - /// Gets a EffectAdorner DataTemplate for effect type Copy. - /// - public static DataTemplate GetEffectCopyAdornerTemplate(UIElement target) + /// Helper for getting from . + /// to read from. + /// Gets a EffectAdorner DataTemplate for effect type Copy. + /// EffectCopyAdornerTemplate property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static DataTemplate GetEffectCopyAdornerTemplate(DependencyObject element) { - return (DataTemplate)target.GetValue(EffectCopyAdornerTemplateProperty); + return (DataTemplate)element.GetValue(EffectCopyAdornerTemplateProperty); } - /// - /// Sets a EffectAdorner DataTemplate for effect type Copy. - /// - public static void SetEffectCopyAdornerTemplate(UIElement target, DataTemplate value) + /// Helper for setting on . + /// to set on. + /// EffectCopyAdornerTemplate property value. + /// Sets a EffectAdorner DataTemplate for effect type Copy. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetEffectCopyAdornerTemplate(DependencyObject element, DataTemplate value) { - target.SetValue(EffectCopyAdornerTemplateProperty, value); + element.SetValue(EffectCopyAdornerTemplateProperty, value); } /// @@ -962,20 +1075,24 @@ public static readonly DependencyProperty EffectMoveAdornerTemplateProperty typeof(DragDrop), new PropertyMetadata((DataTemplate)null)); - /// - /// Gets a EffectAdorner DataTemplate for effect type Move. - /// - public static DataTemplate GetEffectMoveAdornerTemplate(UIElement target) + /// Helper for getting from . + /// to read from. + /// Gets a EffectAdorner DataTemplate for effect type Move. + /// EffectMoveAdornerTemplate property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static DataTemplate GetEffectMoveAdornerTemplate(DependencyObject element) { - return (DataTemplate)target.GetValue(EffectMoveAdornerTemplateProperty); + return (DataTemplate)element.GetValue(EffectMoveAdornerTemplateProperty); } - /// - /// Sets a EffectAdorner DataTemplate for effect type Move. - /// - public static void SetEffectMoveAdornerTemplate(UIElement target, DataTemplate value) + /// Helper for setting on . + /// to set on. + /// EffectMoveAdornerTemplate property value. + /// Sets a EffectAdorner DataTemplate for effect type Move. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetEffectMoveAdornerTemplate(DependencyObject element, DataTemplate value) { - target.SetValue(EffectMoveAdornerTemplateProperty, value); + element.SetValue(EffectMoveAdornerTemplateProperty, value); } /// @@ -987,20 +1104,24 @@ public static readonly DependencyProperty EffectLinkAdornerTemplateProperty typeof(DragDrop), new PropertyMetadata((DataTemplate)null)); - /// - /// Gets a EffectAdorner DataTemplate for effect type Link. - /// - public static DataTemplate GetEffectLinkAdornerTemplate(UIElement target) + /// Helper for getting from . + /// to read from. + /// Gets a EffectAdorner DataTemplate for effect type Link. + /// EffectLinkAdornerTemplate property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static DataTemplate GetEffectLinkAdornerTemplate(DependencyObject element) { - return (DataTemplate)target.GetValue(EffectLinkAdornerTemplateProperty); + return (DataTemplate)element.GetValue(EffectLinkAdornerTemplateProperty); } - /// - /// Sets a EffectAdorner DataTemplate for effect type Link. - /// - public static void SetEffectLinkAdornerTemplate(UIElement target, DataTemplate value) + /// Helper for setting on . + /// to set on. + /// EffectLinkAdornerTemplate property value. + /// Sets a EffectAdorner DataTemplate for effect type Link. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetEffectLinkAdornerTemplate(DependencyObject element, DataTemplate value) { - target.SetValue(EffectLinkAdornerTemplateProperty, value); + element.SetValue(EffectLinkAdornerTemplateProperty, value); } /// @@ -1012,20 +1133,24 @@ public static readonly DependencyProperty EffectAllAdornerTemplateProperty typeof(DragDrop), new PropertyMetadata((DataTemplate)null)); - /// - /// Gets a EffectAdorner DataTemplate for effect type All. - /// - public static DataTemplate GetEffectAllAdornerTemplate(UIElement target) + /// Helper for getting from . + /// to read from. + /// Gets a EffectAdorner DataTemplate for effect type All. + /// EffectAllAdornerTemplate property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static DataTemplate GetEffectAllAdornerTemplate(DependencyObject element) { - return (DataTemplate)target.GetValue(EffectAllAdornerTemplateProperty); + return (DataTemplate)element.GetValue(EffectAllAdornerTemplateProperty); } - /// - /// Sets a EffectAdorner DataTemplate for effect type All. - /// - public static void SetEffectAllAdornerTemplate(UIElement target, DataTemplate value) + /// Helper for setting on . + /// to set on. + /// EffectAllAdornerTemplate property value. + /// Sets a EffectAdorner DataTemplate for effect type All. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetEffectAllAdornerTemplate(DependencyObject element, DataTemplate value) { - target.SetValue(EffectAllAdornerTemplateProperty, value); + element.SetValue(EffectAllAdornerTemplateProperty, value); } /// @@ -1037,20 +1162,24 @@ public static readonly DependencyProperty EffectScrollAdornerTemplateProperty typeof(DragDrop), new PropertyMetadata((DataTemplate)null)); - /// - /// Gets a EffectAdorner DataTemplate for effect type Scroll. - /// - public static DataTemplate GetEffectScrollAdornerTemplate(UIElement target) + /// Helper for getting from . + /// to read from. + /// Gets a EffectAdorner DataTemplate for effect type Scroll. + /// EffectScrollAdornerTemplate property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static DataTemplate GetEffectScrollAdornerTemplate(DependencyObject element) { - return (DataTemplate)target.GetValue(EffectScrollAdornerTemplateProperty); + return (DataTemplate)element.GetValue(EffectScrollAdornerTemplateProperty); } - /// - /// Sets a EffectAdorner DataTemplate for effect type Scroll. - /// - public static void SetEffectScrollAdornerTemplate(UIElement target, DataTemplate value) + /// Helper for setting on . + /// to set on. + /// EffectScrollAdornerTemplate property value. + /// Sets a EffectAdorner DataTemplate for effect type Scroll. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetEffectScrollAdornerTemplate(DependencyObject element, DataTemplate value) { - target.SetValue(EffectScrollAdornerTemplateProperty, value); + element.SetValue(EffectScrollAdornerTemplateProperty, value); } /// @@ -1064,24 +1193,32 @@ public static readonly DependencyProperty ItemsPanelOrientationProperty typeof(DragDrop), new PropertyMetadata(null)); - /// + /// Helper for getting from . + /// to read from. + /// /// Gets the Orientation which should be used for the drag drop action (default null). /// Normally it will be look up to find the correct orientation of the inner ItemsPanel, /// but sometimes it's necessary to force the orientation, if the look up is wrong. - /// - public static Orientation? GetItemsPanelOrientation(UIElement source) + /// + /// ItemsPanelOrientation property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static Orientation? GetItemsPanelOrientation(DependencyObject element) { - return (Orientation?)source.GetValue(ItemsPanelOrientationProperty); + return (Orientation?)element.GetValue(ItemsPanelOrientationProperty); } - /// + /// Helper for setting on . + /// to set on. + /// ItemsPanelOrientation property value. + /// /// Sets the Orientation which should be used for the drag drop action (default null). /// Normally it will be look up to find the correct orientation of the inner ItemsPanel, /// but sometimes it's necessary to force the orientation, if the look up is wrong. - /// - public static void SetItemsPanelOrientation(UIElement source, Orientation? value) + /// + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetItemsPanelOrientation(DependencyObject element, Orientation? value) { - source.SetValue(ItemsPanelOrientationProperty, value); + element.SetValue(ItemsPanelOrientationProperty, value); } /// @@ -1094,20 +1231,24 @@ public static readonly DependencyProperty MinimumHorizontalDragDistanceProperty typeof(DragDrop), new PropertyMetadata(SystemParameters.MinimumHorizontalDragDistance)); - /// - /// Sets the minimum horizontal drag distance. - /// - public static double GetMinimumHorizontalDragDistance(UIElement source) + /// Helper for getting from . + /// to read from. + /// Gets the minimum horizontal drag distance. + /// MinimumHorizontalDragDistance property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static double GetMinimumHorizontalDragDistance(DependencyObject element) { - return (double)source.GetValue(MinimumHorizontalDragDistanceProperty); + return (double)element.GetValue(MinimumHorizontalDragDistanceProperty); } - /// - /// Sets the minimum horizontal drag distance. - /// - public static void SetMinimumHorizontalDragDistance(UIElement source, double value) + /// Helper for setting on . + /// to set on. + /// MinimumHorizontalDragDistance property value. + /// Sets the minimum horizontal drag distance. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetMinimumHorizontalDragDistance(DependencyObject element, double value) { - source.SetValue(MinimumHorizontalDragDistanceProperty, value); + element.SetValue(MinimumHorizontalDragDistanceProperty, value); } /// @@ -1120,20 +1261,24 @@ public static readonly DependencyProperty MinimumVerticalDragDistanceProperty typeof(DragDrop), new PropertyMetadata(SystemParameters.MinimumVerticalDragDistance)); - /// - /// Gets the minimum vertical drag distance. - /// - public static double GetMinimumVerticalDragDistance(UIElement source) + /// Helper for getting from . + /// to read from. + /// Gets the minimum vertical drag distance. + /// MinimumVerticalDragDistance property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static double GetMinimumVerticalDragDistance(DependencyObject element) { - return (double)source.GetValue(MinimumVerticalDragDistanceProperty); + return (double)element.GetValue(MinimumVerticalDragDistanceProperty); } - /// - /// Sets the minimum vertical drag distance. - /// - public static void SetMinimumVerticalDragDistance(UIElement source, double value) + /// Helper for setting on . + /// to set on. + /// MinimumVerticalDragDistance property value. + /// Sets the minimum vertical drag distance. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetMinimumVerticalDragDistance(DependencyObject element, double value) { - source.SetValue(MinimumVerticalDragDistanceProperty, value); + element.SetValue(MinimumVerticalDragDistanceProperty, value); } /// @@ -1146,20 +1291,24 @@ public static readonly DependencyProperty SelectDroppedItemsProperty typeof(DragDrop), new PropertyMetadata(false)); - /// - /// Gets whether if the dropped items should be select again (should keep the selection). - /// - public static bool GetSelectDroppedItems(UIElement target) + /// Helper for getting from . + /// to read from. + /// Gets whether if the dropped items should be select again (should keep the selection). + /// SelectDroppedItems property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static bool GetSelectDroppedItems(DependencyObject element) { - return (bool)target.GetValue(SelectDroppedItemsProperty); + return (bool)element.GetValue(SelectDroppedItemsProperty); } - /// - /// Sets whether if the dropped items should be select again (should keep the selection). - /// - public static void SetSelectDroppedItems(UIElement target, bool value) + /// Helper for setting on . + /// to set on. + /// SelectDroppedItems property value. + /// Sets whether if the dropped items should be select again (should keep the selection). + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetSelectDroppedItems(DependencyObject element, bool value) { - target.SetValue(SelectDroppedItemsProperty, value); + element.SetValue(SelectDroppedItemsProperty, value); } /// @@ -1171,20 +1320,24 @@ public static readonly DependencyProperty DropTargetScrollViewerProperty typeof(DragDrop), new PropertyMetadata((ScrollViewer)null)); - /// - /// Sets the that will be used as . - /// - public static void SetDropTargetScrollViewer(DependencyObject element, ScrollViewer value) + /// Helper for getting from . + /// to read from. + /// Gets the that will be used as . + /// DropTargetScrollViewer property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static ScrollViewer GetDropTargetScrollViewer(DependencyObject element) { - element.SetValue(DropTargetScrollViewerProperty, value); + return (ScrollViewer)element?.GetValue(DropTargetScrollViewerProperty); } - /// - /// Gets the that will be used as . - /// - public static ScrollViewer GetDropTargetScrollViewer(DependencyObject element) + /// Helper for setting on . + /// to set on. + /// DropTargetScrollViewer property value. + /// Sets the that will be used as . + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetDropTargetScrollViewer(DependencyObject element, ScrollViewer value) { - return (ScrollViewer)element?.GetValue(DropTargetScrollViewerProperty); + element.SetValue(DropTargetScrollViewerProperty, value); } /// @@ -1195,20 +1348,24 @@ public static readonly DependencyProperty RootElementFinderProperty typeof(IRootElementFinder), typeof(DragDrop)); - /// - /// Gets the root element finder. - /// - public static IRootElementFinder GetRootElementFinder(UIElement target) + /// Helper for getting from . + /// to read from. + /// Gets the root element finder. + /// RootElementFinder property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static IRootElementFinder GetRootElementFinder(DependencyObject element) { - return (IRootElementFinder)target.GetValue(RootElementFinderProperty); + return (IRootElementFinder)element.GetValue(RootElementFinderProperty); } - /// - /// Sets the root element finder. - /// - public static void SetRootElementFinder(UIElement target, IRootElementFinder value) + /// Helper for setting on . + /// to set on. + /// RootElementFinder property value. + /// Sets the root element finder. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetRootElementFinder(DependencyObject element, IRootElementFinder value) { - target.SetValue(RootElementFinderProperty, value); + element.SetValue(RootElementFinderProperty, value); } /// @@ -1225,20 +1382,24 @@ public static readonly DependencyProperty DragPreviewMaxItemsCountProperty return itemsCount < 0 ? 0 : itemsCount >= int.MaxValue ? int.MaxValue : itemsCount; })); - /// - /// Gets the maximum items count which will be used for the dragged preview. - /// - public static int GetDragPreviewMaxItemsCount(UIElement target) + /// Helper for getting from . + /// to read from. + /// Gets the maximum items count which will be used for the dragged preview. + /// DragPreviewMaxItemsCount property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static int GetDragPreviewMaxItemsCount(DependencyObject element) { - return (int)target.GetValue(DragPreviewMaxItemsCountProperty); + return (int)element.GetValue(DragPreviewMaxItemsCountProperty); } - /// - /// Sets the maximum items count which will be used for the dragged preview. - /// - public static void SetDragPreviewMaxItemsCount(UIElement target, int value) + /// Helper for setting on . + /// to set on. + /// DragPreviewMaxItemsCount property value. + /// Sets the maximum items count which will be used for the dragged preview. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetDragPreviewMaxItemsCount(DependencyObject element, int value) { - target.SetValue(DragPreviewMaxItemsCountProperty, value); + element.SetValue(DragPreviewMaxItemsCountProperty, value); } /// @@ -1250,20 +1411,24 @@ public static readonly DependencyProperty DragPreviewItemsSorterProperty typeof(DragDrop), new PropertyMetadata(null)); - /// - /// Get the drag preview items sorter handler - /// - public static IDragPreviewItemsSorter GetDragPreviewItemsSorter(UIElement target) + /// Helper for getting from . + /// to read from. + /// Gets the drag preview items sorter handler + /// DragPreviewItemsSorter property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static IDragPreviewItemsSorter GetDragPreviewItemsSorter(DependencyObject element) { - return (IDragPreviewItemsSorter)target.GetValue(DragPreviewItemsSorterProperty); + return (IDragPreviewItemsSorter)element.GetValue(DragPreviewItemsSorterProperty); } - /// - /// Sets the handler for the drag preview items sorter - /// - public static void SetDragPreviewItemsSorter(UIElement target, IDragPreviewItemsSorter value) + /// Helper for setting on . + /// to set on. + /// DragPreviewItemsSorter property value. + /// Sets the handler for the drag preview items sorter + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetDragPreviewItemsSorter(DependencyObject element, IDragPreviewItemsSorter value) { - target.SetValue(DragPreviewItemsSorterProperty, value); + element.SetValue(DragPreviewItemsSorterProperty, value); } /// @@ -1275,20 +1440,24 @@ public static readonly DependencyProperty DropTargetItemsSorterProperty typeof(DragDrop), new PropertyMetadata(null)); - /// - /// Get the drop target items sorter handler - /// - public static IDropTargetItemsSorter GetDropTargetItemsSorter(UIElement target) + /// Helper for getting from . + /// to read from. + /// Gets the drop target items sorter handler + /// DropTargetItemsSorter property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static IDropTargetItemsSorter GetDropTargetItemsSorter(DependencyObject element) { - return (IDropTargetItemsSorter)target.GetValue(DropTargetItemsSorterProperty); + return (IDropTargetItemsSorter)element.GetValue(DropTargetItemsSorterProperty); } - /// - /// Sets the handler for the drop target items sorter - /// - public static void SetDropTargetItemsSorter(UIElement target, IDropTargetItemsSorter value) + /// Helper for setting on . + /// to set on. + /// DropTargetItemsSorter property value. + /// Sets the handler for the drop target items sorter + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetDropTargetItemsSorter(DependencyObject element, IDropTargetItemsSorter value) { - target.SetValue(DropTargetItemsSorterProperty, value); + element.SetValue(DropTargetItemsSorterProperty, value); } } } \ No newline at end of file diff --git a/src/GongSolutions.WPF.DragDrop/DragDrop.cs b/src/GongSolutions.WPF.DragDrop/DragDrop.cs index f7c442d2..945dc5e2 100644 --- a/src/GongSolutions.WPF.DragDrop/DragDrop.cs +++ b/src/GongSolutions.WPF.DragDrop/DragDrop.cs @@ -937,11 +937,19 @@ internal static readonly DependencyProperty IsDragOverProperty typeof(DragDrop), new PropertyMetadata(default(bool))); + /// Helper for setting on . + /// to set on. + /// IsDragOver property value. + [AttachedPropertyBrowsableForType(typeof(DependencyObject))] internal static void SetIsDragOver(DependencyObject element, bool value) { element.SetValue(IsDragOverProperty, value); } + /// Helper for getting from . + /// to read from. + /// IsDragOver property value. + [AttachedPropertyBrowsableForType(typeof(DependencyObject))] internal static bool GetIsDragOver(DependencyObject element) { return (bool)element.GetValue(IsDragOverProperty); @@ -953,11 +961,19 @@ internal static readonly DependencyProperty IsDragLeavedProperty typeof(DragDrop), new PropertyMetadata(true)); + /// Helper for setting on . + /// to set on. + /// IsDragLeaved property value. + [AttachedPropertyBrowsableForType(typeof(DependencyObject))] internal static void SetIsDragLeaved(DependencyObject element, bool value) { element.SetValue(IsDragLeavedProperty, value); } + /// Helper for getting from . + /// to read from. + /// IsDragLeaved property value. + [AttachedPropertyBrowsableForType(typeof(DependencyObject))] internal static bool GetIsDragLeaved(DependencyObject element) { return (bool)element.GetValue(IsDragLeavedProperty); diff --git a/src/GongSolutions.WPF.DragDrop/DragDropPreview.cs b/src/GongSolutions.WPF.DragDrop/DragDropPreview.cs index 4385e9e7..af426d8e 100644 --- a/src/GongSolutions.WPF.DragDrop/DragDropPreview.cs +++ b/src/GongSolutions.WPF.DragDrop/DragDropPreview.cs @@ -62,6 +62,7 @@ public DragDropPreview(UIElement rootElement, IDragInfo dragInfo, UIElement visu public bool UseDefaultDragAdorner { get; private set; } + /// Identifies the dependency property. public static readonly DependencyProperty ItemTemplateProperty = DependencyProperty.Register(nameof(ItemTemplate), typeof(DataTemplate), @@ -74,6 +75,7 @@ public DataTemplate ItemTemplate set => this.SetValue(ItemTemplateProperty, value); } + /// Identifies the dependency property. public static readonly DependencyProperty ItemTemplateSelectorProperty = DependencyProperty.Register(nameof(ItemTemplateSelector), typeof(DataTemplateSelector), From cce7d84dfc7b67cfe6998930938a2a291889b41d Mon Sep 17 00:00:00 2001 From: punker76 Date: Sat, 13 Nov 2021 15:28:26 +0100 Subject: [PATCH 22/29] Update build config and use cake v1.3.0 --- .config/dotnet-tools.json | 12 ++ .gitignore | 1 - appveyor.yml | 8 +- build.cake | 237 +++++++++++++++++++++-------------- build.ps1 | 253 ++------------------------------------ global.json | 2 +- tools/packages.config | 4 - 7 files changed, 170 insertions(+), 347 deletions(-) create mode 100644 .config/dotnet-tools.json delete mode 100644 tools/packages.config diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json new file mode 100644 index 00000000..4903ba5f --- /dev/null +++ b/.config/dotnet-tools.json @@ -0,0 +1,12 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "cake.tool": { + "version": "1.3.0", + "commands": [ + "dotnet-cake" + ] + } + } +} \ No newline at end of file diff --git a/.gitignore b/.gitignore index a6990ce1..2e5f8c7f 100644 --- a/.gitignore +++ b/.gitignore @@ -258,7 +258,6 @@ paket-files/ # cake [tT]ools/ -![tT]ools/packages.config # XamlStyler !XamlStyler/ diff --git a/appveyor.yml b/appveyor.yml index 26433da2..47115ee4 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -11,13 +11,15 @@ environment: secure: 1mKS/HfCVq+iYNRVSrrN8NEowOkKt3knrpMzw+SOy3g= azure-key-vault-client-id: secure: JfSqzmsJdXB6uIxttCRoQw1NygwxqXHDj9uIqQnWOb9VCnQYlRPlAnxgW0yTSX4b + azure-key-vault-tenant-id: + secure: FxjkcqtpulfpDpfSAu4onaLVP/H1S1ORRCQCqsZkDC6YhCSmFoMxYNsWv5uGe3ah azure-key-vault-client-secret: secure: CUpRJxMLeUZwNPMcqI0wECaWfy5AMnWn1UZhBd9WnQ3Z16lJP1Vzrkf24mccbhUD azure-key-vault-certificate: secure: BSPdW2TgnQtoQXXbeDECug== skip_tags: true -image: Visual Studio 2019 Preview +image: Visual Studio 2019 test: off install: @@ -29,7 +31,7 @@ pull_requests: build_script: - ps: dotnet --list-sdks - - ps: .\build.ps1 -target appveyor + - ps: .\build.ps1 --target=ci artifacts: - path: \Publish\*.* @@ -39,4 +41,4 @@ nuget: skip_commits: files: - - '**/*.md' \ No newline at end of file + - '**/*.md' diff --git a/build.cake b/build.cake index f93c15d2..ca6cd65e 100644 --- a/build.cake +++ b/build.cake @@ -2,65 +2,72 @@ // TOOLS / ADDINS /////////////////////////////////////////////////////////////////////////////// -#module nuget:?package=Cake.DotNetTool.Module&version=0.5.0 #tool dotnet:?package=NuGetKeyVaultSignTool&version=1.2.28 -#tool dotnet:?package=AzureSignTool&version=2.0.17 -#tool dotnet:?package=GitReleaseManager.Tool&version=0.12.0 -#tool dotnet:?package=GitVersion.Tool&version=5.6.6 +#tool dotnet:?package=AzureSignTool&version=3.0.0 +#tool dotnet:?package=GitReleaseManager.Tool&version=0.12.1 +#tool dotnet:?package=GitVersion.Tool&version=5.6.3 #tool vswhere&version=2.8.4 -#addin nuget:?package=Cake.Figlet&version=1.4.0 +#addin nuget:?package=Cake.Figlet&version=2.0.1 /////////////////////////////////////////////////////////////////////////////// // ARGUMENTS /////////////////////////////////////////////////////////////////////////////// var target = Argument("target", "Default"); -var configuration = Argument("configuration", "Release"); -var verbosity = Argument("verbosity", Verbosity.Minimal); -var dotnetcoreverbosity = Argument("dotnetcoreverbosity", DotNetCoreVerbosity.Minimal); /////////////////////////////////////////////////////////////////////////////// // PREPARATION /////////////////////////////////////////////////////////////////////////////// var repoName = "gong-wpf-dragdrop"; -var isLocal = BuildSystem.IsLocalBuild; +var baseDir = MakeAbsolute(Directory(".")).ToString(); +var srcDir = baseDir + "/src"; +var solution = srcDir + "/GongSolutions.WPF.DragDrop.sln"; +var publishDir = baseDir + "/Publish"; -// Set build version -if (isLocal == false || verbosity == Verbosity.Verbose) +public class BuildData { - GitVersion(new GitVersionSettings { OutputType = GitVersionOutput.BuildServer }); -} -GitVersion gitVersion = GitVersion(new GitVersionSettings { OutputType = GitVersionOutput.Json }); - -var isPullRequest = AppVeyor.Environment.PullRequest.IsPullRequest; -var branchName = gitVersion.BranchName; -var isDevelopBranch = StringComparer.OrdinalIgnoreCase.Equals("develop", branchName); -var isReleaseBranch = StringComparer.OrdinalIgnoreCase.Equals("main", branchName); -var isTagged = AppVeyor.Environment.Repository.Tag.IsTag; + public string Configuration { get; } + public Verbosity Verbosity { get; } + public DotNetCoreVerbosity DotNetCoreVerbosity { get; } + public bool IsLocalBuild { get; set; } + public bool IsPullRequest { get; set; } + public bool IsDevelopBranch { get; set; } + public bool IsReleaseBranch { get; set; } + public GitVersion GitVersion { get; set; } + public DirectoryPath MSBuildPath { get; } + public FilePath MSBuildExe { get; } + + public BuildData( + string configuration, + Verbosity verbosity, + DotNetCoreVerbosity dotNetCoreVerbosity, + DirectoryPath latestMSBuildInstallationPath + ) + { + Configuration = configuration; + Verbosity = verbosity; + DotNetCoreVerbosity = dotNetCoreVerbosity; -var latestInstallationPath = VSWhereLatest(new VSWhereLatestSettings { IncludePrerelease = true }); -var msBuildPath = latestInstallationPath.Combine("./MSBuild/Current/Bin"); -var msBuildPathExe = msBuildPath.CombineWithFilePath("./MSBuild.exe"); + MSBuildPath = latestMSBuildInstallationPath.Combine("./MSBuild/Current/Bin"); + MSBuildExe = MSBuildPath.CombineWithFilePath("./MSBuild.exe"); + } -if (FileExists(msBuildPathExe) == false) -{ - throw new NotImplementedException("You need at least Visual Studio 2019 to build this project."); + public void SetGitVersion(GitVersion gitVersion) + { + GitVersion = gitVersion; + + IsDevelopBranch = StringComparer.OrdinalIgnoreCase.Equals("develop", GitVersion.BranchName); + IsReleaseBranch = StringComparer.OrdinalIgnoreCase.Equals("main", GitVersion.BranchName); + } } -// Directories and Paths -var solution = "./src/GongSolutions.WPF.DragDrop.sln"; -var publishDir = "./Publish"; - -// Define global marcos. -Action Abort = () => { throw new Exception("a non-recoverable fatal error occurred."); }; - /////////////////////////////////////////////////////////////////////////////// // SETUP / TEARDOWN /////////////////////////////////////////////////////////////////////////////// -Setup(ctx => +Setup(ctx => { if (!IsRunningOnWindows()) { @@ -69,15 +76,46 @@ Setup(ctx => Information(Figlet(repoName)); - Information("Informational Version: {0}", gitVersion.InformationalVersion); - Information("SemVer Version: {0}", gitVersion.SemVer); - Information("AssemblySemVer Version: {0}", gitVersion.AssemblySemVer); - Information("MajorMinorPatch Version: {0}", gitVersion.MajorMinorPatch); - Information("NuGet Version: {0}", gitVersion.NuGetVersion); - Information("IsLocalBuild : {0}", isLocal); - Information("Branch : {0}", branchName); - Information("Configuration : {0}", configuration); - Information("MSBuildPath : {0}", msBuildPath); + var gitVersionPath = Context.Tools.Resolve("dotnet-gitversion.exe"); + + Information("GitVersion : {0}", gitVersionPath); + + var buildData = new BuildData( + configuration: Argument("configuration", "Release"), + verbosity: Argument("verbosity", Verbosity.Minimal), + dotNetCoreVerbosity: Argument("dotnetnetcoreverbosity", DotNetCoreVerbosity.Minimal), + latestMSBuildInstallationPath: VSWhereLatest(new VSWhereLatestSettings { IncludePrerelease = true }) + ) + { + IsLocalBuild = BuildSystem.IsLocalBuild, + IsPullRequest = + (BuildSystem.GitHubActions.IsRunningOnGitHubActions && BuildSystem.GitHubActions.Environment.PullRequest.IsPullRequest) + || (BuildSystem.AppVeyor.IsRunningOnAppVeyor && BuildSystem.AppVeyor.Environment.PullRequest.IsPullRequest) + }; + + // Set build version for CI + if (buildData.IsLocalBuild == false || buildData.Verbosity == Verbosity.Verbose) + { + GitVersion(new GitVersionSettings { ToolPath = gitVersionPath, OutputType = GitVersionOutput.BuildServer }); + } + buildData.SetGitVersion(GitVersion(new GitVersionSettings { ToolPath = gitVersionPath, OutputType = GitVersionOutput.Json })); + + Information("MSBuild : {0}", buildData.MSBuildExe); + Information("Branch : {0}", buildData.GitVersion.BranchName); + Information("Configuration : {0}", buildData.Configuration); + Information("IsLocalBuild : {0}", buildData.IsLocalBuild); + Information("Informational Version: {0}", buildData.GitVersion.InformationalVersion); + Information("SemVer Version: {0}", buildData.GitVersion.SemVer); + Information("AssemblySemVer Version: {0}", buildData.GitVersion.AssemblySemVer); + Information("MajorMinorPatch Version: {0}", buildData.GitVersion.MajorMinorPatch); + Information("NuGet Version: {0}", buildData.GitVersion.NuGetVersion); + + if (FileExists(buildData.MSBuildExe) == false) + { + throw new NotImplementedException("You need at least Visual Studio 2019 to build this project."); + } + + return buildData; }); Teardown(ctx => @@ -99,82 +137,80 @@ Task("Clean") }); Task("Restore") - .Does(() => + .Does(data => { - NuGetRestore(solution, new NuGetRestoreSettings { MSBuildPath = msBuildPath.ToString() }); + NuGetRestore(solution, new NuGetRestoreSettings { MSBuildPath = data.MSBuildPath.ToString() }); }); Task("Build") - .Does(() => + .Does(data => { var msBuildSettings = new MSBuildSettings { - Verbosity = verbosity - , ToolPath = msBuildPathExe - , Configuration = configuration + Verbosity = data.Verbosity + , ToolPath = data.MSBuildExe + , Configuration = data.Configuration , ArgumentCustomization = args => args.Append("/m").Append("/nr:false") // The /nr switch tells msbuild to quite once it�s done - , BinaryLogger = new MSBuildBinaryLogSettings() { Enabled = isLocal } + , BinaryLogger = new MSBuildBinaryLogSettings() { Enabled = data.IsLocalBuild } }; MSBuild(solution, msBuildSettings .SetMaxCpuCount(0) - .WithProperty("Version", isReleaseBranch ? gitVersion.MajorMinorPatch : gitVersion.NuGetVersion) - .WithProperty("AssemblyVersion", gitVersion.AssemblySemVer) - .WithProperty("FileVersion", gitVersion.AssemblySemFileVer) - .WithProperty("InformationalVersion", gitVersion.InformationalVersion) - .WithProperty("ContinuousIntegrationBuild", "true") + .WithProperty("Version", data.IsReleaseBranch ? data.GitVersion.MajorMinorPatch : data.GitVersion.NuGetVersion) + .WithProperty("AssemblyVersion", data.GitVersion.AssemblySemVer) + .WithProperty("FileVersion", data.GitVersion.AssemblySemFileVer) + .WithProperty("InformationalVersion", data.GitVersion.InformationalVersion) + .WithProperty("ContinuousIntegrationBuild", data.IsReleaseBranch ? "true" : "false") ); }); Task("dotnetBuild") - .Does(() => + .Does(data => { var buildSettings = new DotNetCoreBuildSettings { - Verbosity = dotnetcoreverbosity, - Configuration = configuration, - ArgumentCustomization = args => args.Append("/m").Append("/nr:false"), // The /nr switch tells msbuild to quite once it�s done - MSBuildSettings = new DotNetCoreMSBuildSettings() + Verbosity = data.DotNetCoreVerbosity + , Configuration = data.Configuration + , ArgumentCustomization = args => args.Append("/m").Append("/nr:false") // The /nr switch tells msbuild to quite once it�s done + , MSBuildSettings = new DotNetCoreMSBuildSettings() .SetMaxCpuCount(0) - .SetConfiguration(configuration) - .WithProperty("Version", isReleaseBranch ? gitVersion.MajorMinorPatch : gitVersion.NuGetVersion) - .WithProperty("AssemblyVersion", gitVersion.AssemblySemVer) - .WithProperty("FileVersion", gitVersion.AssemblySemFileVer) - .WithProperty("InformationalVersion", gitVersion.InformationalVersion) - .WithProperty("ContinuousIntegrationBuild", "true") + .SetConfiguration(data.Configuration) + .WithProperty("Version", data.IsReleaseBranch ? data.GitVersion.MajorMinorPatch : data.GitVersion.NuGetVersion) + .WithProperty("AssemblyVersion", data.GitVersion.AssemblySemVer) + .WithProperty("FileVersion", data.GitVersion.AssemblySemFileVer) + .WithProperty("InformationalVersion", data.GitVersion.InformationalVersion) + .WithProperty("ContinuousIntegrationBuild", data.IsReleaseBranch ? "true" : "false") }; DotNetCoreBuild(solution, buildSettings); }); Task("Pack") - .WithCriteria(() => !isPullRequest) - .Does(() => + .ContinueOnError() + .Does(data => { EnsureDirectoryExists(Directory(publishDir)); var buildSettings = new DotNetCorePackSettings { - Verbosity = dotnetcoreverbosity, - Configuration = configuration, - NoRestore = true, - MSBuildSettings = new DotNetCoreMSBuildSettings() + Verbosity = data.DotNetCoreVerbosity + , Configuration = data.Configuration + , NoRestore = true + , MSBuildSettings = new DotNetCoreMSBuildSettings() .SetMaxCpuCount(0) - .SetConfiguration(configuration) + .SetConfiguration(data.Configuration) .WithProperty("NoBuild", "true") .WithProperty("IncludeBuildOutput", "true") .WithProperty("PackageOutputPath", MakeAbsolute(Directory(publishDir)).FullPath) - .WithProperty("RepositoryBranch", branchName) - .WithProperty("RepositoryCommit", gitVersion.Sha) - .WithProperty("Version", isReleaseBranch ? gitVersion.MajorMinorPatch : gitVersion.NuGetVersion) - .WithProperty("AssemblyVersion", gitVersion.AssemblySemVer) - .WithProperty("FileVersion", gitVersion.AssemblySemFileVer) - .WithProperty("InformationalVersion", gitVersion.InformationalVersion) + .WithProperty("RepositoryBranch", data.GitVersion.BranchName) + .WithProperty("RepositoryCommit", data.GitVersion.Sha) + .WithProperty("Version", data.IsReleaseBranch ? data.GitVersion.MajorMinorPatch : data.GitVersion.NuGetVersion) + .WithProperty("AssemblyVersion", data.GitVersion.AssemblySemVer) + .WithProperty("FileVersion", data.GitVersion.AssemblySemFileVer) + .WithProperty("InformationalVersion", data.GitVersion.InformationalVersion) }; var projects = GetFiles("./src/GongSolutions.WPF.DragDrop/*.csproj"); foreach(var project in projects) { Information("Packing {0}", project); - DeleteFiles(GetFiles("./src/**/*.nuspec")); - DotNetCorePack(project.ToString(), buildSettings); } }); @@ -193,6 +229,12 @@ void SignFiles(IEnumerable files, string description) return; } + var vctid = EnvironmentVariable("azure-key-vault-tenant-id"); + if(string.IsNullOrWhiteSpace(vctid)) { + Error("Could not resolve signing client tenant id."); + return; + } + var vcs = EnvironmentVariable("azure-key-vault-client-secret"); if(string.IsNullOrWhiteSpace(vcs)) { Error("Could not resolve signing client secret."); @@ -222,6 +264,7 @@ void SignFiles(IEnumerable files, string description) .AppendSwitchQuoted("--timestamp-digest", "sha256") .AppendSwitchQuoted("--azure-key-vault-url", vurl) .AppendSwitchQuotedSecret("--azure-key-vault-client-id", vcid) + .AppendSwitchQuotedSecret("--azure-key-vault-tenant-id", vctid) .AppendSwitchQuotedSecret("--azure-key-vault-client-secret", vcs) .AppendSwitchQuotedSecret("--azure-key-vault-certificate", vc) }; @@ -247,7 +290,7 @@ void SignFiles(IEnumerable files, string description) } Task("Sign") - .WithCriteria(() => !isPullRequest) + .WithCriteria((context, data) => !data.IsPullRequest) .ContinueOnError() .Does(() => { @@ -259,7 +302,7 @@ Task("Sign") }); Task("SignNuGet") - .WithCriteria(() => !isPullRequest) + .WithCriteria((context, data) => !data.IsPullRequest) .ContinueOnError() .Does(() => { @@ -280,6 +323,12 @@ Task("SignNuGet") return; } + var vctid = EnvironmentVariable("azure-key-vault-tenant-id"); + if(string.IsNullOrWhiteSpace(vctid)) { + Error("Could not resolve signing client tenant id."); + return; + } + var vcs = EnvironmentVariable("azure-key-vault-client-secret"); if(string.IsNullOrWhiteSpace(vcs)) { Error("Could not resolve signing client secret."); @@ -308,6 +357,7 @@ Task("SignNuGet") .AppendSwitchQuoted("--timestamp-digest", "sha256") .AppendSwitchQuoted("--azure-key-vault-url", vurl) .AppendSwitchQuotedSecret("--azure-key-vault-client-id", vcid) + .AppendSwitchQuotedSecret("--azure-key-vault-tenant-id", vctid) .AppendSwitchQuotedSecret("--azure-key-vault-client-secret", vcs) .AppendSwitchQuotedSecret("--azure-key-vault-certificate", vc) }; @@ -333,16 +383,15 @@ Task("SignNuGet") }); Task("Zip") - .Does(() => + .Does(data => { EnsureDirectoryExists(Directory(publishDir)); - Zip($"./src/Showcase/bin/{configuration}", $"{publishDir}/Showcase.DragDrop.{configuration}-v" + gitVersion.NuGetVersion + ".zip"); + Zip($"./src/Showcase/bin/{data.Configuration}", $"{publishDir}/Showcase.DragDrop.{data.Configuration}-v" + data.GitVersion.NuGetVersion + ".zip"); }); Task("CreateRelease") - .WithCriteria(() => !isTagged) - .WithCriteria(() => !isPullRequest) - .Does(() => + .WithCriteria((context, data) => !data.IsPullRequest) + .Does(data => { var token = EnvironmentVariable("GITHUB_TOKEN"); if (string.IsNullOrEmpty(token)) @@ -351,10 +400,10 @@ Task("CreateRelease") } GitReleaseManagerCreate(token, "punker76", repoName, new GitReleaseManagerCreateSettings { - Milestone = gitVersion.MajorMinorPatch, - Name = gitVersion.AssemblySemFileVer, - Prerelease = isDevelopBranch, - TargetCommitish = branchName, + Milestone = data.GitVersion.MajorMinorPatch, + Name = data.GitVersion.AssemblySemFileVer, + Prerelease = data.IsDevelopBranch, + TargetCommitish = data.GitVersion.BranchName, WorkingDirectory = "." }); }); @@ -370,7 +419,7 @@ Task("Default") .IsDependentOn("dotnetBuild") // doesn't work with Fody ; -Task("appveyor") +Task("ci") .IsDependentOn("Default") .IsDependentOn("Sign") .IsDependentOn("Pack") @@ -382,4 +431,4 @@ Task("appveyor") // EXECUTION /////////////////////////////////////////////////////////////////////////////// -RunTarget(target); \ No newline at end of file +RunTarget(target); diff --git a/build.ps1 b/build.ps1 index ffbd272d..21821d29 100644 --- a/build.ps1 +++ b/build.ps1 @@ -1,248 +1,13 @@ -########################################################################## -# This is the Cake bootstrapper script for PowerShell. -# This file was downloaded from https://github.com/cake-build/resources -# Feel free to change this file to fit your needs. -########################################################################## +$ErrorActionPreference = 'Stop' -<# +Set-Location -LiteralPath $PSScriptRoot -.SYNOPSIS -This is a Powershell script to bootstrap a Cake build. +$env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE = '1' +$env:DOTNET_CLI_TELEMETRY_OPTOUT = '1' +$env:DOTNET_NOLOGO = '1' -.DESCRIPTION -This Powershell script will download NuGet if missing, restore NuGet tools (including Cake) -and execute your Cake build script with the parameters you provide. +dotnet tool restore +if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } -.PARAMETER Script -The build script to execute. -.PARAMETER Target -The build script target to run. -.PARAMETER Configuration -The build configuration to use. -.PARAMETER Verbosity -Specifies the amount of information to be displayed. -.PARAMETER ShowDescription -Shows description about tasks. -.PARAMETER DryRun -Performs a dry run. -.PARAMETER SkipToolPackageRestore -Skips restoring of packages. -.PARAMETER ScriptArgs -Remaining arguments are added here. - -.LINK -https://cakebuild.net - -#> - -[CmdletBinding()] -Param( - [string]$Script = "build.cake", - [string]$Target, - [string]$Configuration, - [ValidateSet("Quiet", "Minimal", "Normal", "Verbose", "Diagnostic")] - [string]$Verbosity, - [switch]$ShowDescription, - [Alias("WhatIf", "Noop")] - [switch]$DryRun, - [switch]$SkipToolPackageRestore, - [Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)] - [string[]]$ScriptArgs -) - -# Attempt to set highest encryption available for SecurityProtocol. -# PowerShell will not set this by default (until maybe .NET 4.6.x). This -# will typically produce a message for PowerShell v2 (just an info -# message though) -try { - # Set TLS 1.2 (3072), then TLS 1.1 (768), then TLS 1.0 (192), finally SSL 3.0 (48) - # Use integers because the enumeration values for TLS 1.2 and TLS 1.1 won't - # exist in .NET 4.0, even though they are addressable if .NET 4.5+ is - # installed (.NET 4.5 is an in-place upgrade). - [System.Net.ServicePointManager]::SecurityProtocol = 3072 -bor 768 -bor 192 -bor 48 - } catch { - Write-Output 'Unable to set PowerShell to use TLS 1.2 and TLS 1.1 due to old .NET Framework installed. If you see underlying connection closed or trust errors, you may need to upgrade to .NET Framework 4.5+ and PowerShell v3' - } - -[Reflection.Assembly]::LoadWithPartialName("System.Security") | Out-Null -function MD5HashFile([string] $filePath) -{ - if ([string]::IsNullOrEmpty($filePath) -or !(Test-Path $filePath -PathType Leaf)) - { - return $null - } - - [System.IO.Stream] $file = $null; - [System.Security.Cryptography.MD5] $md5 = $null; - try - { - $md5 = [System.Security.Cryptography.MD5]::Create() - $file = [System.IO.File]::OpenRead($filePath) - return [System.BitConverter]::ToString($md5.ComputeHash($file)) - } - finally - { - if ($file -ne $null) - { - $file.Dispose() - } - } -} - -function GetProxyEnabledWebClient -{ - $wc = New-Object System.Net.WebClient - $proxy = [System.Net.WebRequest]::GetSystemWebProxy() - $proxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials - $wc.Proxy = $proxy - return $wc -} - -Write-Host "Preparing to run build script..." - -if(!$PSScriptRoot){ - $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent -} - -$TOOLS_DIR = Join-Path $PSScriptRoot "tools" -$ADDINS_DIR = Join-Path $TOOLS_DIR "Addins" -$MODULES_DIR = Join-Path $TOOLS_DIR "Modules" -$NUGET_EXE = Join-Path $TOOLS_DIR "nuget.exe" -$CAKE_EXE = Join-Path $TOOLS_DIR "Cake/Cake.exe" -$NUGET_URL = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" -$PACKAGES_CONFIG = Join-Path $TOOLS_DIR "packages.config" -$PACKAGES_CONFIG_MD5 = Join-Path $TOOLS_DIR "packages.config.md5sum" -$ADDINS_PACKAGES_CONFIG = Join-Path $ADDINS_DIR "packages.config" -$MODULES_PACKAGES_CONFIG = Join-Path $MODULES_DIR "packages.config" - -# Make sure tools folder exists -if ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) { - Write-Verbose -Message "Creating tools directory..." - New-Item -Path $TOOLS_DIR -Type directory | out-null -} - -# Make sure that packages.config exist. -if (!(Test-Path $PACKAGES_CONFIG)) { - Write-Verbose -Message "Downloading packages.config..." - try { - $wc = GetProxyEnabledWebClient - $wc.DownloadFile("https://cakebuild.net/download/bootstrapper/packages", $PACKAGES_CONFIG) - } catch { - Throw "Could not download packages.config." - } -} - -# Try find NuGet.exe in path if not exists -if (!(Test-Path $NUGET_EXE)) { - Write-Verbose -Message "Trying to find nuget.exe in PATH..." - $existingPaths = $Env:Path -Split ';' | Where-Object { (![string]::IsNullOrEmpty($_)) -and (Test-Path $_ -PathType Container) } - $NUGET_EXE_IN_PATH = Get-ChildItem -Path $existingPaths -Filter "nuget.exe" | Select -First 1 - if ($NUGET_EXE_IN_PATH -ne $null -and (Test-Path $NUGET_EXE_IN_PATH.FullName)) { - Write-Verbose -Message "Found in PATH at $($NUGET_EXE_IN_PATH.FullName)." - $NUGET_EXE = $NUGET_EXE_IN_PATH.FullName - } -} - -# Try download NuGet.exe if not exists -if (!(Test-Path $NUGET_EXE)) { - Write-Verbose -Message "Downloading NuGet.exe..." - try { - $wc = GetProxyEnabledWebClient - $wc.DownloadFile($NUGET_URL, $NUGET_EXE) - } catch { - Throw "Could not download NuGet.exe." - } -} - -# Save nuget.exe path to environment to be available to child processed -$ENV:NUGET_EXE = $NUGET_EXE - -# Restore tools from NuGet? -if(-Not $SkipToolPackageRestore.IsPresent) { - Push-Location - Set-Location $TOOLS_DIR - - # Check for changes in packages.config and remove installed tools if true. - [string] $md5Hash = MD5HashFile($PACKAGES_CONFIG) - if((!(Test-Path $PACKAGES_CONFIG_MD5)) -Or - ($md5Hash -ne (Get-Content $PACKAGES_CONFIG_MD5 ))) { - Write-Verbose -Message "Missing or changed package.config hash..." - Get-ChildItem -Exclude packages.config,nuget.exe,Cake.Bakery | - Remove-Item -Recurse - } - - Write-Verbose -Message "Restoring tools from NuGet..." - $NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$TOOLS_DIR`"" - - if ($LASTEXITCODE -ne 0) { - Throw "An error occurred while restoring NuGet tools." - } - else - { - $md5Hash | Out-File $PACKAGES_CONFIG_MD5 -Encoding "ASCII" - } - Write-Verbose -Message ($NuGetOutput | out-string) - - Pop-Location -} - -# Restore addins from NuGet -if (Test-Path $ADDINS_PACKAGES_CONFIG) { - Push-Location - Set-Location $ADDINS_DIR - - Write-Verbose -Message "Restoring addins from NuGet..." - $NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$ADDINS_DIR`"" - - if ($LASTEXITCODE -ne 0) { - Throw "An error occurred while restoring NuGet addins." - } - - Write-Verbose -Message ($NuGetOutput | out-string) - - Pop-Location -} - -# Restore modules from NuGet -if (Test-Path $MODULES_PACKAGES_CONFIG) { - Push-Location - Set-Location $MODULES_DIR - - Write-Verbose -Message "Restoring modules from NuGet..." - $NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$MODULES_DIR`"" - - if ($LASTEXITCODE -ne 0) { - Throw "An error occurred while restoring NuGet modules." - } - - Write-Verbose -Message ($NuGetOutput | out-string) - - Pop-Location -} - -# Make sure that Cake has been installed. -if (!(Test-Path $CAKE_EXE)) { - Throw "Could not find Cake.exe at $CAKE_EXE" -} - - - -# Build Cake arguments -$cakeArguments = @("$Script"); -if ($Target) { $cakeArguments += "-target=$Target" } -if ($Configuration) { $cakeArguments += "-configuration=$Configuration" } -if ($Verbosity) { $cakeArguments += "-verbosity=$Verbosity" } -if ($ShowDescription) { $cakeArguments += "-showdescription" } -if ($DryRun) { $cakeArguments += "-dryrun" } -$cakeArguments += $ScriptArgs - -# Start Cake -Write-Host "Running build script..." - -& "$CAKE_EXE" ./build.cake --bootstrap -if ($LASTEXITCODE -eq 0) -{ - & "$CAKE_EXE" $cakeArguments -} - -exit $LASTEXITCODE \ No newline at end of file +dotnet cake @args +if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } diff --git a/global.json b/global.json index 0671e9a9..d6c2c37f 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "6.0.*", + "version": "6.0.100", "rollForward": "latestFeature" } } \ No newline at end of file diff --git a/tools/packages.config b/tools/packages.config deleted file mode 100644 index 007f90a2..00000000 --- a/tools/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - From 916f840051ab5c551b4c809f39c0189bd47276ee Mon Sep 17 00:00:00 2001 From: punker76 Date: Sat, 13 Nov 2021 15:56:55 +0100 Subject: [PATCH 23/29] NuGet sign doesn't need tenant id --- build.cake | 7 ------- 1 file changed, 7 deletions(-) diff --git a/build.cake b/build.cake index ca6cd65e..ba45a28b 100644 --- a/build.cake +++ b/build.cake @@ -323,12 +323,6 @@ Task("SignNuGet") return; } - var vctid = EnvironmentVariable("azure-key-vault-tenant-id"); - if(string.IsNullOrWhiteSpace(vctid)) { - Error("Could not resolve signing client tenant id."); - return; - } - var vcs = EnvironmentVariable("azure-key-vault-client-secret"); if(string.IsNullOrWhiteSpace(vcs)) { Error("Could not resolve signing client secret."); @@ -357,7 +351,6 @@ Task("SignNuGet") .AppendSwitchQuoted("--timestamp-digest", "sha256") .AppendSwitchQuoted("--azure-key-vault-url", vurl) .AppendSwitchQuotedSecret("--azure-key-vault-client-id", vcid) - .AppendSwitchQuotedSecret("--azure-key-vault-tenant-id", vctid) .AppendSwitchQuotedSecret("--azure-key-vault-client-secret", vcs) .AppendSwitchQuotedSecret("--azure-key-vault-certificate", vc) }; From 5a1b3e72a0419e3115fd037cb310b9c801e217de Mon Sep 17 00:00:00 2001 From: punker76 Date: Sun, 14 Nov 2021 13:19:50 +0100 Subject: [PATCH 24/29] Warnings and suggestions --- .../DragDropPreview.cs | 10 +- src/GongSolutions.WPF.DragDrop/IDragInfo.cs | 2 + .../Properties/AssemblyInfo.cs | 7 +- .../Utilities/DpiHelper.cs | 13 ++- .../Utilities/DragDropExtensions.cs | 6 +- .../Utilities/WindowStyleHelper.cs | 3 - src/Showcase/MainWindow.xaml.cs | 6 +- src/Showcase/Models/DataGridRowModel.cs | 4 +- .../Models/DragAdornerTemplateSelector.cs | 2 +- src/Showcase/Models/GroupedItem.cs | 19 ++-- src/Showcase/Models/ItemModel.cs | 54 +++++------ .../Models/SerializableDragHandler.cs | 9 +- .../Models/TextBoxCustomDropHandler.cs | 8 +- src/Showcase/Models/TreeNode.cs | 34 +++---- src/Showcase/ViewModels/MainViewModel.cs | 94 +++++++++---------- src/Showcase/ViewModels/SimpleCommand.cs | 4 +- src/Showcase/ViewModels/ViewModelBase.cs | 2 +- src/Showcase/Views/DataGridSamples.xaml.cs | 2 +- src/Showcase/Views/Issues.xaml.cs | 2 +- src/Showcase/Views/ListBoxSamples.xaml.cs | 2 +- src/Showcase/Views/ListViewSamples.xaml.cs | 2 +- src/Showcase/Views/MixedSamples.xaml.cs | 6 +- src/Showcase/Views/TabControlSamples.xaml.cs | 2 +- src/Showcase/Views/TreeViewSamples.xaml.cs | 2 +- 24 files changed, 150 insertions(+), 145 deletions(-) diff --git a/src/GongSolutions.WPF.DragDrop/DragDropPreview.cs b/src/GongSolutions.WPF.DragDrop/DragDropPreview.cs index af426d8e..fb253c00 100644 --- a/src/GongSolutions.WPF.DragDrop/DragDropPreview.cs +++ b/src/GongSolutions.WPF.DragDrop/DragDropPreview.cs @@ -13,7 +13,7 @@ namespace GongSolutions.Wpf.DragDrop { internal class DragDropPreview : Popup { - public DragDropPreview(UIElement rootElement, UIElement previewElement, Point translation, Point anchorPoint) + protected DragDropPreview(UIElement rootElement, UIElement previewElement, Point translation, Point anchorPoint) { this.PlacementTarget = rootElement; this.Placement = PlacementMode.Relative; @@ -130,12 +130,12 @@ protected override void OnOpened(EventArgs e) if (PresentationSource.FromVisual(this.Child) is HwndSource hwndSource) { var windowHandle = hwndSource.Handle; - var wsex = WindowStyleHelper.GetWindowStyleEx(windowHandle); + var wsEx = WindowStyleHelper.GetWindowStyleEx(windowHandle); - wsex |= WindowStyleHelper.WS_EX.NOACTIVATE; // We don't want our this window to be activated - wsex |= WindowStyleHelper.WS_EX.TRANSPARENT; + wsEx |= WindowStyleHelper.WS_EX.NOACTIVATE; // We don't want our this window to be activated + wsEx |= WindowStyleHelper.WS_EX.TRANSPARENT; - WindowStyleHelper.SetWindowStyleEx(windowHandle, wsex); + WindowStyleHelper.SetWindowStyleEx(windowHandle, wsEx); } } diff --git a/src/GongSolutions.WPF.DragDrop/IDragInfo.cs b/src/GongSolutions.WPF.DragDrop/IDragInfo.cs index 4139f139..bbd78542 100644 --- a/src/GongSolutions.WPF.DragDrop/IDragInfo.cs +++ b/src/GongSolutions.WPF.DragDrop/IDragInfo.cs @@ -106,11 +106,13 @@ public interface IDragInfo /// object DataObject { get; set; } +#pragma warning disable 1572 /// Initiates a drag-and-drop operation. /// A reference to the dependency object that is the source of the data being dragged. /// A data object that contains the data being dragged. /// One of the values that specifies permitted effects of the drag-and-drop operation. /// One of the values that specifies the final effect that was performed during the drag-and-drop operation. +#pragma warning restore 1572 Func DragDropHandler { get; set; } /// diff --git a/src/GongSolutions.WPF.DragDrop/Properties/AssemblyInfo.cs b/src/GongSolutions.WPF.DragDrop/Properties/AssemblyInfo.cs index 4a3a50db..99b475dd 100644 --- a/src/GongSolutions.WPF.DragDrop/Properties/AssemblyInfo.cs +++ b/src/GongSolutions.WPF.DragDrop/Properties/AssemblyInfo.cs @@ -1,6 +1,9 @@ -using System.Runtime.InteropServices; +using System; +using System.Runtime.InteropServices; using System.Windows.Markup; +[assembly: CLSCompliant(true)] + [assembly: XmlnsPrefix("urn:gong-wpf-dragdrop", "dd")] [assembly: XmlnsDefinition("urn:gong-wpf-dragdrop", "GongSolutions.Wpf.DragDrop")] [assembly: XmlnsDefinition("urn:gong-wpf-dragdrop", "GongSolutions.Wpf.DragDrop.Utilities")] @@ -9,4 +12,4 @@ // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("940084f7-d48e-41b3-9e0d-cf574d587643")] +[assembly: Guid("940084f7-d48e-41b3-9e0d-cf574d587643")] \ No newline at end of file diff --git a/src/GongSolutions.WPF.DragDrop/Utilities/DpiHelper.cs b/src/GongSolutions.WPF.DragDrop/Utilities/DpiHelper.cs index ad548e21..3e96dd5f 100644 --- a/src/GongSolutions.WPF.DragDrop/Utilities/DpiHelper.cs +++ b/src/GongSolutions.WPF.DragDrop/Utilities/DpiHelper.cs @@ -1,14 +1,13 @@ using System; using System.Diagnostics.CodeAnalysis; +#if !NET462_OR_GREATER && !NETCOREAPP + using System.Reflection; +#endif using System.Windows; using System.Windows.Media; namespace GongSolutions.Wpf.DragDrop.Utilities { -#if NET461 || NET46 || NET452 || NET451 || NET45 - using System.Reflection; -#endif - /// /// A helper class for Dpi logicm cause Microsoft hides this with the internal flag. /// @@ -23,6 +22,8 @@ public static class DpiHelper /// Convert a point in device independent pixels (1/96") to a point in the system coordinates. /// /// A point in the logical coordinate system. + /// The scale factor in the x dimension + /// The scale factor in the y dimension /// Returns the parameter converted to the system's coordinates. public static Point LogicalPixelsToDevice(Point logicalPoint, double dpiScaleX, double dpiScaleY) { @@ -35,6 +36,8 @@ public static Point LogicalPixelsToDevice(Point logicalPoint, double dpiScaleX, /// Convert a point in system coordinates to a point in device independent pixels (1/96"). /// /// A point in the physical coordinate system. + /// The scale factor in the x dimension + /// The scale factor in the y dimension /// Returns the parameter converted to the device independent coordinate system. public static Point DevicePixelsToLogical(Point devicePoint, double dpiScaleX, double dpiScaleY) { @@ -83,7 +86,7 @@ public static Thickness LogicalThicknessToDevice(Thickness logicalThickness, dou return new Thickness(topLeft.X, topLeft.Y, bottomRight.X, bottomRight.Y); } -#if NET461 || NET46 || NET452 || NET451 || NET45 +#if !NET462_OR_GREATER && !NETCOREAPP public static double DpiX = 0d; public static double DpiY = 0d; diff --git a/src/GongSolutions.WPF.DragDrop/Utilities/DragDropExtensions.cs b/src/GongSolutions.WPF.DragDrop/Utilities/DragDropExtensions.cs index e1b181c6..f15fb17e 100644 --- a/src/GongSolutions.WPF.DragDrop/Utilities/DragDropExtensions.cs +++ b/src/GongSolutions.WPF.DragDrop/Utilities/DragDropExtensions.cs @@ -9,7 +9,7 @@ namespace GongSolutions.Wpf.DragDrop.Utilities public static class DragDropExtensions { /// - /// Determines whether the given element is ignored on drag start (). + /// Determines whether the given element is ignored on drag start (). /// /// The given element. /// Element is ignored or not. @@ -19,7 +19,7 @@ public static bool IsDragSourceIgnored(this UIElement element) } /// - /// Determines whether the given element is ignored on drop action (). + /// Determines whether the given element is ignored on drop action (). /// /// The given element. /// Element is ignored or not. @@ -29,7 +29,7 @@ public static bool IsDragSource(this UIElement element) } /// - /// Determines whether the given element is ignored on drop action (). + /// Determines whether the given element is ignored on drop action (). /// /// The given element. /// Element is ignored or not. diff --git a/src/GongSolutions.WPF.DragDrop/Utilities/WindowStyleHelper.cs b/src/GongSolutions.WPF.DragDrop/Utilities/WindowStyleHelper.cs index 685e62c1..4d8a8422 100644 --- a/src/GongSolutions.WPF.DragDrop/Utilities/WindowStyleHelper.cs +++ b/src/GongSolutions.WPF.DragDrop/Utilities/WindowStyleHelper.cs @@ -8,13 +8,11 @@ namespace GongSolutions.Wpf.DragDrop.Utilities { internal static class WindowStyleHelper { - [CLSCompliant(false)] internal static WS_EX GetWindowStyleEx(IntPtr hWnd) { return (WS_EX)GetWindowLongPtr(hWnd, GWL.EXSTYLE); } - [CLSCompliant(false)] internal static WS_EX SetWindowStyleEx(IntPtr hWnd, WS_EX dwNewLong) { return (WS_EX)SetWindowLongPtr(hWnd, GWL.EXSTYLE, (IntPtr)(int)dwNewLong); @@ -88,7 +86,6 @@ internal enum GWL /// Window style extended values, WS_EX_* /// [Flags] - [CLSCompliant(false)] internal enum WS_EX : uint { None = 0, diff --git a/src/Showcase/MainWindow.xaml.cs b/src/Showcase/MainWindow.xaml.cs index 46af96df..010088da 100644 --- a/src/Showcase/MainWindow.xaml.cs +++ b/src/Showcase/MainWindow.xaml.cs @@ -13,9 +13,9 @@ public partial class MainWindow : Window { public MainWindow() { - InitializeComponent(); + this.InitializeComponent(); this.DataContext = new MainViewModel(); - this.Loaded += MainWindowLoaded; + this.Loaded += this.MainWindowLoaded; } private void MainWindowLoaded(object sender, RoutedEventArgs e) @@ -23,7 +23,7 @@ private void MainWindowLoaded(object sender, RoutedEventArgs e) var appArgs = Environment.GetCommandLineArgs(); if (appArgs.Length > 1 && appArgs[1] == "anotherOne") { - this.MainTabControl.SelectedItem = MainTabControl.Items.OfType().FirstOrDefault(t => (string)t.Header == "Mixed"); + this.MainTabControl.SelectedItem = this.MainTabControl.Items.OfType().FirstOrDefault(t => (string)t.Header == "Mixed"); } } } diff --git a/src/Showcase/Models/DataGridRowModel.cs b/src/Showcase/Models/DataGridRowModel.cs index e8fc585c..96056880 100644 --- a/src/Showcase/Models/DataGridRowModel.cs +++ b/src/Showcase/Models/DataGridRowModel.cs @@ -6,8 +6,8 @@ public class DataGridRowModel { public string Name { get; set; } = Faker.Name.FullName(NameFormats.Standard); - public string StreetName { get; set; } = Faker.Address.StreetName(); + public string StreetName { get; set; } = Address.StreetName(); - public string City { get; set; } = Faker.Address.City(); + public string City { get; set; } = Address.City(); } } \ No newline at end of file diff --git a/src/Showcase/Models/DragAdornerTemplateSelector.cs b/src/Showcase/Models/DragAdornerTemplateSelector.cs index 06da48f8..c9aa415e 100644 --- a/src/Showcase/Models/DragAdornerTemplateSelector.cs +++ b/src/Showcase/Models/DragAdornerTemplateSelector.cs @@ -12,7 +12,7 @@ public class DragAdornerTemplateSelector : DataTemplateSelector public override DataTemplate SelectTemplate(object item, DependencyObject container) { var itemModel = item as ItemModel; - return itemModel != null && (itemModel.Index & 0x01) == 0 ? TemplateEven : TemplateOdd; + return itemModel != null && (itemModel.Index & 0x01) == 0 ? this.TemplateEven : this.TemplateOdd; } } } \ No newline at end of file diff --git a/src/Showcase/Models/GroupedItem.cs b/src/Showcase/Models/GroupedItem.cs index b61e4066..f0f7d1e5 100644 --- a/src/Showcase/Models/GroupedItem.cs +++ b/src/Showcase/Models/GroupedItem.cs @@ -17,27 +17,28 @@ public GroupedItem(int group, int item) public string Caption { - get { return _caption; } + get => this._caption; set { - if (value == _caption) return; - _caption = value; - OnPropertyChanged(); + if (value == this._caption) return; + this._caption = value; + this.OnPropertyChanged(); } } public string Group { - get { return _group; } + get => this._group; set { - if (value == _group) + if (value == this._group) { return; } - _group = value; - OnPropertyChanged(); + + this._group = value; + this.OnPropertyChanged(); } } @@ -46,7 +47,7 @@ public string Group [NotifyPropertyChangedInvocator] protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } } \ No newline at end of file diff --git a/src/Showcase/Models/ItemModel.cs b/src/Showcase/Models/ItemModel.cs index 5b6fb621..c1ab5f20 100644 --- a/src/Showcase/Models/ItemModel.cs +++ b/src/Showcase/Models/ItemModel.cs @@ -19,7 +19,7 @@ public ItemModel() this.BindableDoubleValue = Faker.RandomNumber.Next(0, 100); for (int i = 0; i < Faker.RandomNumber.Next(2, 20); i++) { - SubItemCollection.Add(new SubItemModel($"Sub item {i}")); + this.SubItemCollection.Add(new SubItemModel($"Sub item {i}")); } } @@ -38,34 +38,34 @@ public ItemModel(int itemIndex) public string SelectedSubItem { - get { return _selectedSubItem; } + get => this._selectedSubItem; set { - if (value == _selectedSubItem) return; - _selectedSubItem = value; - OnPropertyChanged(); + if (value == this._selectedSubItem) return; + this._selectedSubItem = value; + this.OnPropertyChanged(); } } public bool IsChecked { - get { return _isChecked; } + get => this._isChecked; set { - if (value == _isChecked) return; - _isChecked = value; - OnPropertyChanged(); + if (value == this._isChecked) return; + this._isChecked = value; + this.OnPropertyChanged(); } } public double BindableDoubleValue { - get { return _bindableDoubleValue; } + get => this._bindableDoubleValue; set { - if (value.Equals(_bindableDoubleValue)) return; - _bindableDoubleValue = value; - OnPropertyChanged(); + if (value.Equals(this._bindableDoubleValue)) return; + this._bindableDoubleValue = value; + this.OnPropertyChanged(); } } @@ -79,7 +79,7 @@ public override string ToString() [NotifyPropertyChangedInvocator] protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } @@ -101,34 +101,34 @@ public SubItemModel(string caption) public string BindableValue { - get { return _bindableValue; } + get => this._bindableValue; set { - if (value == _bindableValue) return; - _bindableValue = value; - OnPropertyChanged(); + if (value == this._bindableValue) return; + this._bindableValue = value; + this.OnPropertyChanged(); } } public bool BindableOptionA { - get { return _bindableOptionA; } + get => this._bindableOptionA; set { - if (value == _bindableOptionA) return; - _bindableOptionA = value; - OnPropertyChanged(); + if (value == this._bindableOptionA) return; + this._bindableOptionA = value; + this.OnPropertyChanged(); } } public bool BindableOptionB { - get { return _bindableOptionB; } + get => this._bindableOptionB; set { - if (value == _bindableOptionB) return; - _bindableOptionB = value; - OnPropertyChanged(); + if (value == this._bindableOptionB) return; + this._bindableOptionB = value; + this.OnPropertyChanged(); } } @@ -142,7 +142,7 @@ public override string ToString() [NotifyPropertyChangedInvocator] protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } diff --git a/src/Showcase/Models/SerializableDragHandler.cs b/src/Showcase/Models/SerializableDragHandler.cs index 10e0d0a0..40267cb2 100644 --- a/src/Showcase/Models/SerializableDragHandler.cs +++ b/src/Showcase/Models/SerializableDragHandler.cs @@ -22,7 +22,7 @@ public class SerializableDragHandler : IDragSource /// public void StartDrag(IDragInfo dragInfo) { - alreadyDropped = false; + this.alreadyDropped = false; var items = dragInfo.SourceItems.OfType().ToList(); var wrapper = new SerializableWrapper() { @@ -43,13 +43,13 @@ public bool CanStartDrag(IDragInfo dragInfo) /// public void Dropped(IDropInfo dropInfo) { - alreadyDropped = true; + this.alreadyDropped = true; } /// public void DragDropOperationFinished(DragDropEffects operationResult, IDragInfo dragInfo) { - if (alreadyDropped || dragInfo == null) + if (this.alreadyDropped || dragInfo == null) { return; } @@ -68,7 +68,8 @@ public void DragDropOperationFinished(DragDropEffects operationResult, IDragInfo sourceList.Remove(o); } } - alreadyDropped = true; + + this.alreadyDropped = true; } } } diff --git a/src/Showcase/Models/TextBoxCustomDropHandler.cs b/src/Showcase/Models/TextBoxCustomDropHandler.cs index 30fb557e..b4fff1ea 100644 --- a/src/Showcase/Models/TextBoxCustomDropHandler.cs +++ b/src/Showcase/Models/TextBoxCustomDropHandler.cs @@ -66,9 +66,9 @@ public class DropTargetHighlightAdorner : DropTargetAdorner public DropTargetHighlightAdorner(UIElement adornedElement, DropInfo dropInfo) : base(adornedElement, dropInfo) { - _pen = new Pen(Brushes.Tomato, 2); - _pen.Freeze(); - _brush = new SolidColorBrush(Colors.Coral) { Opacity = 0.2 }; + this._pen = new Pen(Brushes.Tomato, 2); + this._pen.Freeze(); + this._brush = new SolidColorBrush(Colors.Coral) { Opacity = 0.2 }; this._brush.Freeze(); this.SetValue(SnapsToDevicePixelsProperty, true); @@ -83,7 +83,7 @@ protected override void OnRender(DrawingContext drawingContext) translatePoint.Offset(1, 1); var bounds = new Rect(translatePoint, new Size(visualTarget.RenderSize.Width - 2, visualTarget.RenderSize.Height - 2)); - drawingContext.DrawRectangle(_brush, _pen, bounds); + drawingContext.DrawRectangle(this._brush, this._pen, bounds); } } } diff --git a/src/Showcase/Models/TreeNode.cs b/src/Showcase/Models/TreeNode.cs index 7d530a46..ceaa7210 100644 --- a/src/Showcase/Models/TreeNode.cs +++ b/src/Showcase/Models/TreeNode.cs @@ -21,45 +21,45 @@ public TreeNode(string caption) public string Caption { - get { return _caption; } + get => this._caption; set { - if (value == _caption) return; - _caption = value; - OnPropertyChanged(); + if (value == this._caption) return; + this._caption = value; + this.OnPropertyChanged(); } } public ObservableCollection Children { - get { return _children; } + get => this._children; set { - if (Equals(value, _children)) return; - _children = value; - OnPropertyChanged(); + if (Equals(value, this._children)) return; + this._children = value; + this.OnPropertyChanged(); } } public bool IsCloned { - get { return _isCloned; } + get => this._isCloned; set { - if (value == _isCloned) return; - _isCloned = value; - OnPropertyChanged(); + if (value == this._isCloned) return; + this._isCloned = value; + this.OnPropertyChanged(); } } public bool IsExpanded { - get { return _isExpanded; } + get => this._isExpanded; set { - if (value == _isExpanded) return; - _isExpanded = value; - OnPropertyChanged(); + if (value == this._isExpanded) return; + this._isExpanded = value; + this.OnPropertyChanged(); } } @@ -83,7 +83,7 @@ public object Clone() [NotifyPropertyChangedInvocator] protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } } \ No newline at end of file diff --git a/src/Showcase/ViewModels/MainViewModel.cs b/src/Showcase/ViewModels/MainViewModel.cs index e85facdc..57654cfa 100644 --- a/src/Showcase/ViewModels/MainViewModel.cs +++ b/src/Showcase/ViewModels/MainViewModel.cs @@ -1,16 +1,15 @@ -using System.Diagnostics; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Diagnostics; +using System.Linq; using System.Windows.Data; using System.Windows.Input; +using GongSolutions.Wpf.DragDrop; using Showcase.WPF.DragDrop.Models; namespace Showcase.WPF.DragDrop.ViewModels { - using GongSolutions.Wpf.DragDrop; - using System.Collections; - using System.Collections.Generic; - using System.Collections.ObjectModel; - using System.Linq; - public class ListMember : List { public string Name { get; set; } @@ -23,11 +22,11 @@ public class SubMember public class MainViewModel : ViewModelBase, IDragPreviewItemsSorter, IDropTargetItemsSorter { - private SampleData _data; - private ICommand _openIssueCommand; - private ICommand _openPullRequestCommand; - private ICommand _openLinkCommand; - private ICommand _filterCollectionCommand; + private SampleData data; + private ICommand openIssueCommand; + private ICommand openPullRequestCommand; + private ICommand openLinkCommand; + private ICommand filterCollectionCommand; public ObservableCollection Members { get; set; } = new ObservableCollection(); @@ -46,26 +45,23 @@ public MainViewModel() ////} var listMember = new ListMember() { Name = "Item 1" }; - Members.Add(listMember); + this.Members.Add(listMember); listMember = new ListMember() { Name = "Item 2 with SubItems" }; listMember.Add(new SubMember() { Name = "SubItem 1" }); listMember.Add(new SubMember() { Name = "SubItem 2" }); - Members.Add(listMember); + this.Members.Add(listMember); listMember = new ListMember() { Name = "Item 3" }; - Members.Add(listMember); + this.Members.Add(listMember); this.Data = new SampleData(); - this.OpenIssueCommand = new SimpleCommand(issue => - { - OpenUrlLink($"https://github.com/punker76/gong-wpf-dragdrop/issues/{issue}"); - }); + this.OpenIssueCommand = new SimpleCommand(issue => { OpenUrlLink($"https://github.com/punker76/gong-wpf-dragdrop/issues/{issue}"); }); this.OpenPullRequestCommand = new SimpleCommand(pr => { OpenUrlLink($"https://github.com/punker76/gong-wpf-dragdrop/pull/{pr}"); }); this.OpenLinkCommand = new SimpleCommand(link => { OpenUrlLink(link.ToString()); }); this.FilterCollectionCommand = new SimpleCommand(isChecked => { - var coll = Data.FilterCollection1; + var coll = this.Data.FilterCollection1; var collView = CollectionViewSource.GetDefaultView(coll); collView.Filter += o => { @@ -73,6 +69,7 @@ public MainViewModel() { return true; } + var itemModel = (ItemModel)o; var number = itemModel.Index; return (number & 0x01) == 0; @@ -80,72 +77,72 @@ public MainViewModel() }); static void OpenUrlLink(string link) => Process.Start(new ProcessStartInfo - { - FileName = link ?? throw new System.ArgumentNullException(nameof(link)), - // UseShellExecute is default to false on .NET Core while true on .NET Framework. - // Only this value is set to true, the url link can be opened. - UseShellExecute = true, - }); + { + FileName = link ?? throw new System.ArgumentNullException(nameof(link)), + // UseShellExecute is default to false on .NET Core while true on .NET Framework. + // Only this value is set to true, the url link can be opened. + UseShellExecute = true, + }); } public SampleData Data { - get { return _data; } + get => this.data; set { - if (Equals(value, _data)) return; - _data = value; - OnPropertyChanged(); + if (Equals(value, this.data)) return; + this.data = value; + this.OnPropertyChanged(); } } public ICommand OpenIssueCommand { - get { return _openIssueCommand; } + get => this.openIssueCommand; set { - if (Equals(value, _openIssueCommand)) return; - _openIssueCommand = value; - OnPropertyChanged(); + if (Equals(value, this.openIssueCommand)) return; + this.openIssueCommand = value; + this.OnPropertyChanged(); } } public ICommand OpenPullRequestCommand { - get { return _openPullRequestCommand; } + get => this.openPullRequestCommand; set { - if (Equals(value, _openPullRequestCommand)) return; - _openPullRequestCommand = value; - OnPropertyChanged(); + if (Equals(value, this.openPullRequestCommand)) return; + this.openPullRequestCommand = value; + this.OnPropertyChanged(); } } public ICommand OpenLinkCommand { - get { return _openLinkCommand; } + get => this.openLinkCommand; set { - if (Equals(value, _openLinkCommand)) return; - _openLinkCommand = value; - OnPropertyChanged(); + if (Equals(value, this.openLinkCommand)) return; + this.openLinkCommand = value; + this.OnPropertyChanged(); } } public ICommand FilterCollectionCommand { - get { return _filterCollectionCommand; } + get => this.filterCollectionCommand; set { - if (Equals(value, _filterCollectionCommand)) return; - _filterCollectionCommand = value; - OnPropertyChanged(); + if (Equals(value, this.filterCollectionCommand)) return; + this.filterCollectionCommand = value; + this.OnPropertyChanged(); } } public IEnumerable SortDropTargetItems(IEnumerable items) { - return SortDragPreviewItems(items); + return this.SortDragPreviewItems(items); } public IEnumerable SortDragPreviewItems(IEnumerable items) @@ -158,7 +155,8 @@ public IEnumerable SortDragPreviewItems(IEnumerable items) return allItems.OrderBy(x => ((ItemModel)x).Index); } } - return items; + + return allItems; } } } \ No newline at end of file diff --git a/src/Showcase/ViewModels/SimpleCommand.cs b/src/Showcase/ViewModels/SimpleCommand.cs index ad2e25a7..ff5f5d53 100644 --- a/src/Showcase/ViewModels/SimpleCommand.cs +++ b/src/Showcase/ViewModels/SimpleCommand.cs @@ -23,8 +23,8 @@ public bool CanExecute(object parameter) public event EventHandler CanExecuteChanged { - add { CommandManager.RequerySuggested += value; } - remove { CommandManager.RequerySuggested -= value; } + add => CommandManager.RequerySuggested += value; + remove => CommandManager.RequerySuggested -= value; } public void Execute(object parameter) diff --git a/src/Showcase/ViewModels/ViewModelBase.cs b/src/Showcase/ViewModels/ViewModelBase.cs index b179f337..34c0de35 100644 --- a/src/Showcase/ViewModels/ViewModelBase.cs +++ b/src/Showcase/ViewModels/ViewModelBase.cs @@ -11,7 +11,7 @@ public class ViewModelBase : INotifyPropertyChanged [NotifyPropertyChangedInvocator] protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } } \ No newline at end of file diff --git a/src/Showcase/Views/DataGridSamples.xaml.cs b/src/Showcase/Views/DataGridSamples.xaml.cs index 88a4e276..959dfdd8 100644 --- a/src/Showcase/Views/DataGridSamples.xaml.cs +++ b/src/Showcase/Views/DataGridSamples.xaml.cs @@ -9,7 +9,7 @@ public partial class DataGridSamples : UserControl { public DataGridSamples() { - InitializeComponent(); + this.InitializeComponent(); } } } \ No newline at end of file diff --git a/src/Showcase/Views/Issues.xaml.cs b/src/Showcase/Views/Issues.xaml.cs index e87a91fc..6199409a 100644 --- a/src/Showcase/Views/Issues.xaml.cs +++ b/src/Showcase/Views/Issues.xaml.cs @@ -9,7 +9,7 @@ public partial class Issues : UserControl { public Issues() { - InitializeComponent(); + this.InitializeComponent(); } } } \ No newline at end of file diff --git a/src/Showcase/Views/ListBoxSamples.xaml.cs b/src/Showcase/Views/ListBoxSamples.xaml.cs index 27b72d7c..a77725ff 100644 --- a/src/Showcase/Views/ListBoxSamples.xaml.cs +++ b/src/Showcase/Views/ListBoxSamples.xaml.cs @@ -9,7 +9,7 @@ public partial class ListBoxSamples : UserControl { public ListBoxSamples() { - InitializeComponent(); + this.InitializeComponent(); } } } \ No newline at end of file diff --git a/src/Showcase/Views/ListViewSamples.xaml.cs b/src/Showcase/Views/ListViewSamples.xaml.cs index 803fbacb..c5e45f39 100644 --- a/src/Showcase/Views/ListViewSamples.xaml.cs +++ b/src/Showcase/Views/ListViewSamples.xaml.cs @@ -9,7 +9,7 @@ public partial class ListViewSamples : UserControl { public ListViewSamples() { - InitializeComponent(); + this.InitializeComponent(); } } } \ No newline at end of file diff --git a/src/Showcase/Views/MixedSamples.xaml.cs b/src/Showcase/Views/MixedSamples.xaml.cs index e6e4e900..33013a39 100644 --- a/src/Showcase/Views/MixedSamples.xaml.cs +++ b/src/Showcase/Views/MixedSamples.xaml.cs @@ -14,8 +14,8 @@ public partial class MixedSamples : UserControl { public MixedSamples() { - InitializeComponent(); - this.Loaded += MainWindowLoaded; + this.InitializeComponent(); + this.Loaded += this.MainWindowLoaded; } private void MainWindowLoaded(object sender, RoutedEventArgs e) @@ -23,7 +23,7 @@ private void MainWindowLoaded(object sender, RoutedEventArgs e) var appArgs = Environment.GetCommandLineArgs(); if (appArgs.Length > 1 && appArgs[1] == "anotherOne") { - MixedTabControl.SelectedItem = MixedTabControl.Items.OfType().FirstOrDefault(t => (string)t.Header == "Outside"); + this.MixedTabControl.SelectedItem = this.MixedTabControl.Items.OfType().FirstOrDefault(t => (string)t.Header == "Outside"); } } diff --git a/src/Showcase/Views/TabControlSamples.xaml.cs b/src/Showcase/Views/TabControlSamples.xaml.cs index 40d376ff..94e9222c 100644 --- a/src/Showcase/Views/TabControlSamples.xaml.cs +++ b/src/Showcase/Views/TabControlSamples.xaml.cs @@ -9,7 +9,7 @@ public partial class TabControlSamples : UserControl { public TabControlSamples() { - InitializeComponent(); + this.InitializeComponent(); } } } \ No newline at end of file diff --git a/src/Showcase/Views/TreeViewSamples.xaml.cs b/src/Showcase/Views/TreeViewSamples.xaml.cs index 92d2c80c..e029a99d 100644 --- a/src/Showcase/Views/TreeViewSamples.xaml.cs +++ b/src/Showcase/Views/TreeViewSamples.xaml.cs @@ -10,7 +10,7 @@ public partial class TreeViewSamples : UserControl { public TreeViewSamples() { - InitializeComponent(); + this.InitializeComponent(); } private void LeftBoundTreeView_RequestBringIntoView(object sender, System.Windows.RequestBringIntoViewEventArgs e) From 2bc99b2ff4badd7f7da87f1800e13218b857ba54 Mon Sep 17 00:00:00 2001 From: punker76 Date: Sun, 14 Nov 2021 14:44:14 +0100 Subject: [PATCH 25/29] (#414) Allow set the ItemsPanel for DragAdorner or DropAdorner preview --- .../DragDrop.Properties.cs | 58 +++++++++++++++++++ src/GongSolutions.WPF.DragDrop/DragDrop.cs | 22 +++++++ .../DragDropPreview.cs | 17 ++++++ 3 files changed, 97 insertions(+) diff --git a/src/GongSolutions.WPF.DragDrop/DragDrop.Properties.cs b/src/GongSolutions.WPF.DragDrop/DragDrop.Properties.cs index c368a7cb..fab54ef5 100644 --- a/src/GongSolutions.WPF.DragDrop/DragDrop.Properties.cs +++ b/src/GongSolutions.WPF.DragDrop/DragDrop.Properties.cs @@ -921,6 +921,35 @@ public static void SetDragAdornerTemplateSelector(DependencyObject element, Data element.SetValue(DragAdornerTemplateSelectorProperty, value); } + /// + /// Gets or sets a ItemsPanel for the DragAdorner. + /// + public static readonly DependencyProperty DragAdornerItemsPanelProperty + = DependencyProperty.RegisterAttached("DragAdornerItemsPanel", + typeof(ItemsPanelTemplate), + typeof(DragDrop), + new PropertyMetadata(ItemsControl.ItemsPanelProperty.DefaultMetadata.DefaultValue)); + + /// Helper for getting from . + /// to read from. + /// Gets the ItemsPanel for the DragAdorner. + /// DragAdornerItemsPanel property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static ItemsPanelTemplate GetDragAdornerItemsPanel(DependencyObject element) + { + return (ItemsPanelTemplate)element.GetValue(DragAdornerItemsPanelProperty); + } + + /// Helper for setting on . + /// to set on. + /// DragAdornerItemsPanel property value. + /// Sets the ItemsPanel for the DragAdorner. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetDragAdornerItemsPanel(DependencyObject element, ItemsPanelTemplate value) + { + element.SetValue(DragAdornerItemsPanelProperty, value); + } + /// /// Gets or sets a DataTemplateSelector for the DragAdorner based on the DropTarget. /// @@ -950,6 +979,35 @@ public static void SetDropAdornerTemplateSelector(DependencyObject element, Data element.SetValue(DropAdornerTemplateSelectorProperty, value); } + /// + /// Gets or sets a ItemsPanel for the DragAdorner based on the DropTarget. + /// + public static readonly DependencyProperty DropAdornerItemsPanelProperty + = DependencyProperty.RegisterAttached("DropAdornerItemsPanel", + typeof(ItemsPanelTemplate), + typeof(DragDrop), + new PropertyMetadata(ItemsControl.ItemsPanelProperty.DefaultMetadata.DefaultValue)); + + /// Helper for getting from . + /// to read from. + /// Gets the ItemsPanel for the DragAdorner based on the DropTarget. + /// DropAdornerItemsPanel property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static ItemsPanelTemplate GetDropAdornerItemsPanel(DependencyObject element) + { + return (ItemsPanelTemplate)element.GetValue(DropAdornerItemsPanelProperty); + } + + /// Helper for setting on . + /// to set on. + /// DropAdornerItemsPanel property value. + /// Sets the ItemsPanel for the DragAdorner based on the DropTarget. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetDropAdornerItemsPanel(DependencyObject element, ItemsPanelTemplate value) + { + element.SetValue(DropAdornerItemsPanelProperty, value); + } + /// /// Use descendant bounds of the VisualSourceItem as MinWidth for the DragAdorner. /// diff --git a/src/GongSolutions.WPF.DragDrop/DragDrop.cs b/src/GongSolutions.WPF.DragDrop/DragDrop.cs index 945dc5e2..5374e303 100644 --- a/src/GongSolutions.WPF.DragDrop/DragDrop.cs +++ b/src/GongSolutions.WPF.DragDrop/DragDrop.cs @@ -94,6 +94,17 @@ internal static DataTemplateSelector TryGetDragAdornerTemplateSelector(UIElement return templateSelector; } + internal static ItemsPanelTemplate TryGetDragAdornerItemsPanel(UIElement source, UIElement sender) + { + var itemsPanel = source is not null ? GetDragAdornerItemsPanel(source) : null; + if (itemsPanel is null && sender is not null) + { + itemsPanel = GetDragAdornerItemsPanel(sender); + } + + return itemsPanel; + } + internal static DataTemplate TryGetDropAdornerTemplate(UIElement source, UIElement sender) { var template = source is not null ? GetDropAdornerTemplate(source) : null; @@ -116,6 +127,17 @@ internal static DataTemplateSelector TryGetDropAdornerTemplateSelector(UIElement return templateSelector; } + internal static ItemsPanelTemplate TryGetDropAdornerItemsPanel(UIElement source, UIElement sender) + { + var itemsPanel = source is not null ? GetDropAdornerItemsPanel(source) : null; + if (itemsPanel is null && sender is not null) + { + itemsPanel = GetDropAdornerItemsPanel(sender); + } + + return itemsPanel; + } + internal static int TryGetDragPreviewMaxItemsCount(IDragInfo dragInfo, UIElement sender) { var itemsCount = dragInfo?.VisualSource != null ? GetDragPreviewMaxItemsCount(dragInfo.VisualSource) : -1; diff --git a/src/GongSolutions.WPF.DragDrop/DragDropPreview.cs b/src/GongSolutions.WPF.DragDrop/DragDropPreview.cs index fb253c00..27f5d4cd 100644 --- a/src/GongSolutions.WPF.DragDrop/DragDropPreview.cs +++ b/src/GongSolutions.WPF.DragDrop/DragDropPreview.cs @@ -88,6 +88,19 @@ public DataTemplateSelector ItemTemplateSelector set => this.SetValue(ItemTemplateSelectorProperty, value); } + /// Identifies the dependency property. + public static readonly DependencyProperty ItemsPanelProperty + = DependencyProperty.Register(nameof(ItemsPanel), + typeof(ItemsPanelTemplate), + typeof(DragDropPreview), + new PropertyMetadata(default(ItemsPanelTemplate))); + + public ItemsPanelTemplate ItemsPanel + { + get => (ItemsPanelTemplate)this.GetValue(ItemsPanelProperty); + set => this.SetValue(ItemsPanelProperty, value); + } + public void Move(Point point) { var translation = this.Translation; @@ -188,6 +201,7 @@ public void UpdatePreviewPresenter(IDragInfo dragInfo, UIElement visualTarget, U // Get target template or template selector DataTemplate template = DragDrop.TryGetDropAdornerTemplate(visualTarget, sender); DataTemplateSelector templateSelector = DragDrop.TryGetDropAdornerTemplateSelector(visualTarget, sender); + ItemsPanelTemplate itemsPanel = DragDrop.TryGetDropAdornerItemsPanel(visualTarget, sender); if (template is not null) { @@ -199,6 +213,7 @@ public void UpdatePreviewPresenter(IDragInfo dragInfo, UIElement visualTarget, U { template = DragDrop.TryGetDragAdornerTemplate(visualSource, sender); templateSelector = DragDrop.TryGetDragAdornerTemplateSelector(visualSource, sender); + itemsPanel = DragDrop.TryGetDragAdornerItemsPanel(visualTarget, sender); this.UseDefaultDragAdorner = template is null && templateSelector is null && DragDrop.GetUseDefaultDragAdorner(visualSource); if (this.UseDefaultDragAdorner) @@ -215,6 +230,7 @@ public void UpdatePreviewPresenter(IDragInfo dragInfo, UIElement visualTarget, U this.SetCurrentValue(ItemTemplateSelectorProperty, templateSelector); this.SetCurrentValue(ItemTemplateProperty, template); + this.SetCurrentValue(ItemsPanelProperty, itemsPanel); } public UIElement CreatePreviewPresenter(IDragInfo dragInfo, UIElement visualTarget, UIElement sender) @@ -251,6 +267,7 @@ public UIElement CreatePreviewPresenter(IDragInfo dragInfo, UIElement visualTarg itemsControl.SetBinding(ItemsControl.ItemTemplateProperty, new Binding(nameof(this.ItemTemplate)) { Source = this }); itemsControl.SetBinding(ItemsControl.ItemTemplateSelectorProperty, new Binding(nameof(this.ItemTemplateSelector)) { Source = this }); + itemsControl.SetBinding(ItemsControl.ItemsPanelProperty, new Binding(nameof(this.ItemsPanel)) { Source = this }); if (useVisualSourceItemSizeForDragAdorner) { From fa2b2599c57c865200a71040abd469ff2ff6c4ac Mon Sep 17 00:00:00 2001 From: punker76 Date: Sun, 21 Nov 2021 18:49:45 +0100 Subject: [PATCH 26/29] (#228) DragAdorner and DropAdorner DataTemplate/Selector for multiple item selection --- .../DragDrop.Properties.cs | 170 +++++++++++++++--- src/GongSolutions.WPF.DragDrop/DragDrop.cs | 44 +++++ .../DragDropPreview.cs | 43 ++++- 3 files changed, 220 insertions(+), 37 deletions(-) diff --git a/src/GongSolutions.WPF.DragDrop/DragDrop.Properties.cs b/src/GongSolutions.WPF.DragDrop/DragDrop.Properties.cs index fab54ef5..29e23065 100644 --- a/src/GongSolutions.WPF.DragDrop/DragDrop.Properties.cs +++ b/src/GongSolutions.WPF.DragDrop/DragDrop.Properties.cs @@ -864,34 +864,6 @@ public static void SetDragAdornerTemplate(DependencyObject element, DataTemplate element.SetValue(DragAdornerTemplateProperty, value); } - /// - /// Gets or sets a DataTemplate for the DragAdorner based on the DropTarget. - /// - public static readonly DependencyProperty DropAdornerTemplateProperty - = DependencyProperty.RegisterAttached("DropAdornerTemplate", - typeof(DataTemplate), - typeof(DragDrop)); - - /// Helper for getting from . - /// to read from. - /// Gets the DataTemplate for the DragAdorner based on the DropTarget. - /// DropAdornerTemplate property value. - [AttachedPropertyBrowsableForType(typeof(UIElement))] - public static DataTemplate GetDropAdornerTemplate(DependencyObject element) - { - return (DataTemplate)element.GetValue(DropAdornerTemplateProperty); - } - - /// Helper for setting on . - /// to set on. - /// DropAdornerTemplate property value. - /// Sets the DataTemplate for the DragAdorner based on the DropTarget. - [AttachedPropertyBrowsableForType(typeof(UIElement))] - public static void SetDropAdornerTemplate(DependencyObject element, DataTemplate value) - { - element.SetValue(DropAdornerTemplateProperty, value); - } - /// /// Gets or sets a DataTemplateSelector for the DragAdorner. /// @@ -921,6 +893,63 @@ public static void SetDragAdornerTemplateSelector(DependencyObject element, Data element.SetValue(DragAdornerTemplateSelectorProperty, value); } + /// + /// Gets or sets a DragAdorner DataTemplate for multiple item selection. + /// + public static readonly DependencyProperty DragAdornerMultiItemTemplateProperty + = DependencyProperty.RegisterAttached("DragAdornerMultiItemTemplate", + typeof(DataTemplate), + typeof(DragDrop)); + + /// Helper for getting from . + /// to read from. + /// Gets the DragAdorner DataTemplate for multiple item selection. + /// DragAdornerMultiItemTemplate property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static DataTemplate GetDragAdornerMultiItemTemplate(DependencyObject element) + { + return (DataTemplate)element.GetValue(DragAdornerMultiItemTemplateProperty); + } + + /// Helper for setting on . + /// to set on. + /// DragAdornerMultiItemTemplate property value. + /// Sets the DragAdorner DataTemplate for multiple item selection. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetDragAdornerMultiItemTemplate(DependencyObject element, DataTemplate value) + { + element.SetValue(DragAdornerMultiItemTemplateProperty, value); + } + + /// + /// Gets or sets a DragAdorner DataTemplateSelector for multiple item selection. + /// + public static readonly DependencyProperty DragAdornerMultiItemTemplateSelectorProperty + = DependencyProperty.RegisterAttached("DragAdornerMultiItemTemplateSelector", + typeof(DataTemplateSelector), + typeof(DragDrop), + new PropertyMetadata(default(DataTemplateSelector))); + + /// Helper for getting from . + /// to read from. + /// Gets the DragAdorner DataTemplateSelector for multiple item selection. + /// DragAdornerMultiItemTemplateSelector property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static DataTemplateSelector GetDragAdornerMultiItemTemplateSelector(DependencyObject element) + { + return (DataTemplateSelector)element.GetValue(DragAdornerMultiItemTemplateSelectorProperty); + } + + /// Helper for setting on . + /// to set on. + /// DragAdornerMultiItemTemplateSelector property value. + /// Sets the DragAdorner DataTemplateSelector for multiple item selection. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetDragAdornerMultiItemTemplateSelector(DependencyObject element, DataTemplateSelector value) + { + element.SetValue(DragAdornerMultiItemTemplateSelectorProperty, value); + } + /// /// Gets or sets a ItemsPanel for the DragAdorner. /// @@ -950,6 +979,34 @@ public static void SetDragAdornerItemsPanel(DependencyObject element, ItemsPanel element.SetValue(DragAdornerItemsPanelProperty, value); } + /// + /// Gets or sets a DataTemplate for the DragAdorner based on the DropTarget. + /// + public static readonly DependencyProperty DropAdornerTemplateProperty + = DependencyProperty.RegisterAttached("DropAdornerTemplate", + typeof(DataTemplate), + typeof(DragDrop)); + + /// Helper for getting from . + /// to read from. + /// Gets the DataTemplate for the DragAdorner based on the DropTarget. + /// DropAdornerTemplate property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static DataTemplate GetDropAdornerTemplate(DependencyObject element) + { + return (DataTemplate)element.GetValue(DropAdornerTemplateProperty); + } + + /// Helper for setting on . + /// to set on. + /// DropAdornerTemplate property value. + /// Sets the DataTemplate for the DragAdorner based on the DropTarget. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetDropAdornerTemplate(DependencyObject element, DataTemplate value) + { + element.SetValue(DropAdornerTemplateProperty, value); + } + /// /// Gets or sets a DataTemplateSelector for the DragAdorner based on the DropTarget. /// @@ -979,6 +1036,63 @@ public static void SetDropAdornerTemplateSelector(DependencyObject element, Data element.SetValue(DropAdornerTemplateSelectorProperty, value); } + /// + /// Gets or sets a DropAdorner DataTemplate for multiple item selection. + /// + public static readonly DependencyProperty DropAdornerMultiItemTemplateProperty + = DependencyProperty.RegisterAttached("DropAdornerMultiItemTemplate", + typeof(DataTemplate), + typeof(DragDrop)); + + /// Helper for getting from . + /// to read from. + /// Gets the DropAdorner DataTemplate for multiple item selection. + /// DropAdornerMultiItemTemplate property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static DataTemplate GetDropAdornerMultiItemTemplate(DependencyObject element) + { + return (DataTemplate)element.GetValue(DropAdornerMultiItemTemplateProperty); + } + + /// Helper for setting on . + /// to set on. + /// DropAdornerMultiItemTemplate property value. + /// Sets the DropAdorner DataTemplate for multiple item selection. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetDropAdornerMultiItemTemplate(DependencyObject element, DataTemplate value) + { + element.SetValue(DropAdornerMultiItemTemplateProperty, value); + } + + /// + /// Gets or sets a DropAdorner DataTemplateSelector for multiple item selection. + /// + public static readonly DependencyProperty DropAdornerMultiItemTemplateSelectorProperty + = DependencyProperty.RegisterAttached("DropAdornerMultiItemTemplateSelector", + typeof(DataTemplateSelector), + typeof(DragDrop), + new PropertyMetadata(default(DataTemplateSelector))); + + /// Helper for getting from . + /// to read from. + /// Gets the DropAdorner DataTemplateSelector for multiple item selection. + /// DropAdornerMultiItemTemplateSelector property value. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static DataTemplateSelector GetDropAdornerMultiItemTemplateSelector(DependencyObject element) + { + return (DataTemplateSelector)element.GetValue(DropAdornerMultiItemTemplateSelectorProperty); + } + + /// Helper for setting on . + /// to set on. + /// DropAdornerMultiItemTemplateSelector property value. + /// Sets the DropAdorner DataTemplateSelector for multiple item selection. + [AttachedPropertyBrowsableForType(typeof(UIElement))] + public static void SetDropAdornerMultiItemTemplateSelector(DependencyObject element, DataTemplateSelector value) + { + element.SetValue(DropAdornerMultiItemTemplateSelectorProperty, value); + } + /// /// Gets or sets a ItemsPanel for the DragAdorner based on the DropTarget. /// diff --git a/src/GongSolutions.WPF.DragDrop/DragDrop.cs b/src/GongSolutions.WPF.DragDrop/DragDrop.cs index 5374e303..a1bd0d25 100644 --- a/src/GongSolutions.WPF.DragDrop/DragDrop.cs +++ b/src/GongSolutions.WPF.DragDrop/DragDrop.cs @@ -94,6 +94,28 @@ internal static DataTemplateSelector TryGetDragAdornerTemplateSelector(UIElement return templateSelector; } + internal static DataTemplate TryGetDragAdornerMultiItemTemplate(UIElement source, UIElement sender) + { + var template = source is not null ? GetDragAdornerMultiItemTemplate(source) : null; + if (template is null && sender is not null) + { + template = GetDragAdornerMultiItemTemplate(sender); + } + + return template; + } + + internal static DataTemplateSelector TryGetDragAdornerMultiItemTemplateSelector(UIElement source, UIElement sender) + { + var templateSelector = source is not null ? GetDragAdornerMultiItemTemplateSelector(source) : null; + if (templateSelector is null && sender is not null) + { + templateSelector = GetDragAdornerMultiItemTemplateSelector(sender); + } + + return templateSelector; + } + internal static ItemsPanelTemplate TryGetDragAdornerItemsPanel(UIElement source, UIElement sender) { var itemsPanel = source is not null ? GetDragAdornerItemsPanel(source) : null; @@ -127,6 +149,28 @@ internal static DataTemplateSelector TryGetDropAdornerTemplateSelector(UIElement return templateSelector; } + internal static DataTemplate TryGetDropAdornerMultiItemTemplate(UIElement source, UIElement sender) + { + var template = source is not null ? GetDropAdornerMultiItemTemplate(source) : null; + if (template is null && sender is not null) + { + template = GetDropAdornerMultiItemTemplate(sender); + } + + return template; + } + + internal static DataTemplateSelector TryGetDropAdornerMultiItemTemplateSelector(UIElement source, UIElement sender) + { + var templateSelector = source is not null ? GetDropAdornerMultiItemTemplateSelector(source) : null; + if (templateSelector is null && sender is not null) + { + templateSelector = GetDropAdornerMultiItemTemplateSelector(sender); + } + + return templateSelector; + } + internal static ItemsPanelTemplate TryGetDropAdornerItemsPanel(UIElement source, UIElement sender) { var itemsPanel = source is not null ? GetDropAdornerItemsPanel(source) : null; diff --git a/src/GongSolutions.WPF.DragDrop/DragDropPreview.cs b/src/GongSolutions.WPF.DragDrop/DragDropPreview.cs index 27f5d4cd..5190a83a 100644 --- a/src/GongSolutions.WPF.DragDrop/DragDropPreview.cs +++ b/src/GongSolutions.WPF.DragDrop/DragDropPreview.cs @@ -152,6 +152,11 @@ protected override void OnOpened(EventArgs e) } } + private static bool IsMultiSelection(IDragInfo dragInfo) + { + return dragInfo?.Data is IEnumerable and not string; + } + public static bool HasDragDropPreview(IDragInfo dragInfo, UIElement visualTarget, UIElement sender) { var visualSource = dragInfo?.VisualSource; @@ -160,9 +165,15 @@ public static bool HasDragDropPreview(IDragInfo dragInfo, UIElement visualTarget return false; } + var isMultiSelection = IsMultiSelection(dragInfo); + // Check for target template or template selector - DataTemplate template = DragDrop.TryGetDropAdornerTemplate(visualTarget, sender); - DataTemplateSelector templateSelector = DragDrop.TryGetDropAdornerTemplateSelector(visualTarget, sender); + DataTemplate template = isMultiSelection + ? DragDrop.TryGetDropAdornerMultiItemTemplate(visualTarget, sender) ?? DragDrop.TryGetDropAdornerTemplate(visualTarget, sender) + : DragDrop.TryGetDropAdornerTemplate(visualTarget, sender); + DataTemplateSelector templateSelector = isMultiSelection + ? DragDrop.TryGetDropAdornerMultiItemTemplateSelector(visualTarget, sender) ?? DragDrop.TryGetDropAdornerTemplateSelector(visualTarget, sender) + : DragDrop.TryGetDropAdornerTemplateSelector(visualTarget, sender); if (template is not null) { @@ -172,8 +183,12 @@ public static bool HasDragDropPreview(IDragInfo dragInfo, UIElement visualTarget // Check for source template or template selector if there is no target one if (template is null && templateSelector is null) { - template = DragDrop.TryGetDragAdornerTemplate(visualSource, sender); - templateSelector = DragDrop.TryGetDragAdornerTemplateSelector(visualSource, sender); + template = isMultiSelection + ? DragDrop.TryGetDragAdornerMultiItemTemplate(visualSource, sender) ?? DragDrop.TryGetDragAdornerTemplate(visualSource, sender) + : DragDrop.TryGetDragAdornerTemplate(visualSource, sender); + templateSelector = isMultiSelection + ? DragDrop.TryGetDragAdornerMultiItemTemplateSelector(visualSource, sender) ?? DragDrop.TryGetDragAdornerTemplateSelector(visualSource, sender) + : DragDrop.TryGetDragAdornerTemplateSelector(visualSource, sender); var useDefaultDragAdorner = template is null && templateSelector is null && DragDrop.GetUseDefaultDragAdorner(visualSource); if (useDefaultDragAdorner) @@ -198,9 +213,15 @@ public void UpdatePreviewPresenter(IDragInfo dragInfo, UIElement visualTarget, U return; } + var isMultiSelection = IsMultiSelection(dragInfo); + // Get target template or template selector - DataTemplate template = DragDrop.TryGetDropAdornerTemplate(visualTarget, sender); - DataTemplateSelector templateSelector = DragDrop.TryGetDropAdornerTemplateSelector(visualTarget, sender); + DataTemplate template = isMultiSelection + ? DragDrop.TryGetDropAdornerMultiItemTemplate(visualTarget, sender) ?? DragDrop.TryGetDropAdornerTemplate(visualTarget, sender) + : DragDrop.TryGetDropAdornerTemplate(visualTarget, sender); + DataTemplateSelector templateSelector = isMultiSelection + ? DragDrop.TryGetDropAdornerMultiItemTemplateSelector(visualTarget, sender) ?? DragDrop.TryGetDropAdornerTemplateSelector(visualTarget, sender) + : DragDrop.TryGetDropAdornerTemplateSelector(visualTarget, sender); ItemsPanelTemplate itemsPanel = DragDrop.TryGetDropAdornerItemsPanel(visualTarget, sender); if (template is not null) @@ -211,8 +232,12 @@ public void UpdatePreviewPresenter(IDragInfo dragInfo, UIElement visualTarget, U // Get source template or template selector if there is no target one if (template is null && templateSelector is null) { - template = DragDrop.TryGetDragAdornerTemplate(visualSource, sender); - templateSelector = DragDrop.TryGetDragAdornerTemplateSelector(visualSource, sender); + template = isMultiSelection + ? DragDrop.TryGetDragAdornerMultiItemTemplate(visualSource, sender) ?? DragDrop.TryGetDragAdornerTemplate(visualSource, sender) + : DragDrop.TryGetDragAdornerTemplate(visualSource, sender); + templateSelector = isMultiSelection + ? DragDrop.TryGetDragAdornerMultiItemTemplateSelector(visualSource, sender) ?? DragDrop.TryGetDragAdornerTemplateSelector(visualSource, sender) + : DragDrop.TryGetDragAdornerTemplateSelector(visualSource, sender); itemsPanel = DragDrop.TryGetDragAdornerItemsPanel(visualTarget, sender); this.UseDefaultDragAdorner = template is null && templateSelector is null && DragDrop.GetUseDefaultDragAdorner(visualSource); @@ -233,7 +258,7 @@ public void UpdatePreviewPresenter(IDragInfo dragInfo, UIElement visualTarget, U this.SetCurrentValue(ItemsPanelProperty, itemsPanel); } - public UIElement CreatePreviewPresenter(IDragInfo dragInfo, UIElement visualTarget, UIElement sender) + private UIElement CreatePreviewPresenter(IDragInfo dragInfo, UIElement visualTarget, UIElement sender) { var visualSource = dragInfo?.VisualSource; if (visualSource is null) From 5b4cfe6149773aa0f8a4f4b2138f2ee05d5ed19e Mon Sep 17 00:00:00 2001 From: punker76 Date: Sun, 5 Dec 2021 00:11:14 +0100 Subject: [PATCH 27/29] refactor(demo): #420 change sample from #342 --- src/Showcase/Models/ItemModel.cs | 12 ++++++++++++ src/Showcase/Views/Issues.xaml | 22 ++++++++++++---------- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/Showcase/Models/ItemModel.cs b/src/Showcase/Models/ItemModel.cs index c1ab5f20..d8450701 100644 --- a/src/Showcase/Models/ItemModel.cs +++ b/src/Showcase/Models/ItemModel.cs @@ -13,6 +13,7 @@ public class ItemModel : INotifyPropertyChanged private double _bindableDoubleValue; private string _selectedSubItem; private bool _isChecked; + private bool _isExpanded; public ItemModel() { @@ -58,6 +59,17 @@ public bool IsChecked } } + public bool IsExpanded + { + get => this._isExpanded; + set + { + if (value == this._isExpanded) return; + this._isExpanded = value; + this.OnPropertyChanged(); + } + } + public double BindableDoubleValue { get => this._bindableDoubleValue; diff --git a/src/Showcase/Views/Issues.xaml b/src/Showcase/Views/Issues.xaml index 1281fdac..ae1ca691 100644 --- a/src/Showcase/Views/Issues.xaml +++ b/src/Showcase/Views/Issues.xaml @@ -937,16 +937,18 @@ SelectionMode="Extended"> - - - - - - - - - - + + + + + + + + + + + + From f9b5fcd4df5ce78ce312d0a5bd140619fb2ea607 Mon Sep 17 00:00:00 2001 From: punker76 Date: Sun, 5 Dec 2021 00:16:13 +0100 Subject: [PATCH 28/29] fix: #420 enable dragging ToggleButton controls With changes for #342 the dragging of ToggleButton controls was gone. To re-enable this it's necessary to remove the test in GetHitTestResult and don't handle the mouse inputs for it (down and up). So after that it's possible to toggle the state or drag the control. --- src/GongSolutions.WPF.DragDrop/DragDrop.cs | 27 ++++++++++++++-------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/GongSolutions.WPF.DragDrop/DragDrop.cs b/src/GongSolutions.WPF.DragDrop/DragDrop.cs index a1bd0d25..4da63068 100644 --- a/src/GongSolutions.WPF.DragDrop/DragDrop.cs +++ b/src/GongSolutions.WPF.DragDrop/DragDrop.cs @@ -426,7 +426,7 @@ private static void DragSourceOnTouchDown(object sender, TouchEventArgs e) var dragInfo = infoBuilder?.CreateDragInfo(sender, e.OriginalSource, MouseButton.Left, item => e.GetTouchPoint(item).Position) ?? new DragInfo(sender, e.OriginalSource, MouseButton.Left, item => e.GetTouchPoint(item).Position); - DragSourceDown(sender, dragInfo, e); + DragSourceDown(sender, dragInfo, e, elementPosition); } private static void DoMouseButtonDown(object sender, MouseButtonEventArgs e) @@ -449,10 +449,10 @@ private static void DoMouseButtonDown(object sender, MouseButtonEventArgs e) var dragInfo = infoBuilder?.CreateDragInfo(sender, e.OriginalSource, e.ChangedButton, item => e.GetPosition(item)) ?? new DragInfo(sender, e.OriginalSource, e.ChangedButton, item => e.GetPosition(item)); - DragSourceDown(sender, dragInfo, e); + DragSourceDown(sender, dragInfo, e, elementPosition); } - private static void DragSourceDown(object sender, DragInfo dragInfo, InputEventArgs e) + private static void DragSourceDown(object sender, DragInfo dragInfo, InputEventArgs e, Point elementPosition) { if (dragInfo.VisualSource is ItemsControl control && control.CanSelectMultipleItems()) { @@ -482,8 +482,11 @@ private static void DragSourceDown(object sender, DragInfo dragInfo, InputEventA var selectedItems = itemsControl.GetSelectedItems().OfType().ToList(); if (selectedItems.Count > 1 && selectedItems.Contains(dragInfo.SourceItem)) { - _clickSupressItem = dragInfo.SourceItem; - e.Handled = true; + if (!HitTestUtilities.HitTest4Type(sender, elementPosition)) + { + _clickSupressItem = dragInfo.SourceItem; + e.Handled = true; + } } } @@ -492,21 +495,26 @@ private static void DragSourceDown(object sender, DragInfo dragInfo, InputEventA private static void DragSourceOnMouseLeftButtonUp(object sender, MouseButtonEventArgs e) { - DragSourceUp(sender); + DragSourceUp(sender, e.GetPosition((IInputElement)sender)); } private static void DragSourceOnMouseRightButtonUp(object sender, MouseButtonEventArgs e) { - DragSourceUp(sender); + DragSourceUp(sender, e.GetPosition((IInputElement)sender)); } private static void DragSourceOnTouchUp(object sender, TouchEventArgs e) { - DragSourceUp(sender); + DragSourceUp(sender, e.GetTouchPoint((IInputElement)sender).Position); } - private static void DragSourceUp(object sender) + private static void DragSourceUp(object sender, Point elementPosition) { + if (HitTestUtilities.HitTest4Type(sender, elementPosition)) + { + return; + } + var dragInfo = _dragInfo; // If we prevented the control's default selection handling in DragSource_PreviewMouseLeftButtonDown @@ -946,7 +954,6 @@ private static bool GetHitTestResult(object sender, Point elementPosition) || HitTestUtilities.HitTest4Type(sender, elementPosition) || HitTestUtilities.HitTest4Type(sender, elementPosition) || HitTestUtilities.HitTest4Type(sender, elementPosition) - || HitTestUtilities.HitTest4Type(sender, elementPosition) || HitTestUtilities.HitTest4Type(sender, elementPosition) || HitTestUtilities.HitTest4GridViewColumnHeader(sender, elementPosition) || HitTestUtilities.HitTest4DataGridTypes(sender, elementPosition); From 67e73aa6f2b8d5c9aa5bfbde8737d1de098a3261 Mon Sep 17 00:00:00 2001 From: punker76 Date: Sun, 5 Dec 2021 19:41:29 +0100 Subject: [PATCH 29/29] refactor(targetframeworks): #419 drop .Net 4.5.2 and 4.6 target --- appveyor.yml | 10 +- build.cake | 91 +++++++------------ src/Directory.build.props | 8 +- .../Directory.Build.props | 32 ------- .../GongSolutions.WPF.DragDrop.csproj | 25 +++++ .../Utilities/DpiHelper.cs | 80 ---------------- .../Utilities/DragDropExtensions.cs | 8 -- 7 files changed, 67 insertions(+), 187 deletions(-) delete mode 100644 src/GongSolutions.WPF.DragDrop/Directory.Build.props diff --git a/appveyor.yml b/appveyor.yml index 47115ee4..d68534f6 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -4,7 +4,6 @@ branches: only: - develop - main - - /\d*\.\d*\.\d*/ environment: azure-key-vault-url: @@ -19,18 +18,19 @@ environment: secure: BSPdW2TgnQtoQXXbeDECug== skip_tags: true -image: Visual Studio 2019 +image: Visual Studio 2022 test: off -install: - - ps: Invoke-WebRequest 'https://dot.net/v1/dotnet-install.ps1' -OutFile 'dotnet-install.ps1' - - ps: ./dotnet-install.ps1 -Version 6.0.100 -InstallDir "C:\Program Files\dotnet" +# install: + # - ps: Invoke-WebRequest 'https://dot.net/v1/dotnet-install.ps1' -OutFile 'dotnet-install.ps1' + # - ps: ./dotnet-install.ps1 -Version 6.0.100 -InstallDir "C:\Program Files\dotnet" pull_requests: do_not_increment_build_number: false build_script: - ps: dotnet --list-sdks + - ps: gitversion /version - ps: .\build.ps1 --target=ci artifacts: diff --git a/build.cake b/build.cake index ba45a28b..abf671b8 100644 --- a/build.cake +++ b/build.cake @@ -139,31 +139,11 @@ Task("Clean") Task("Restore") .Does(data => { - NuGetRestore(solution, new NuGetRestoreSettings { MSBuildPath = data.MSBuildPath.ToString() }); + DotNetCoreRestore(solution); }); Task("Build") .Does(data => -{ - var msBuildSettings = new MSBuildSettings { - Verbosity = data.Verbosity - , ToolPath = data.MSBuildExe - , Configuration = data.Configuration - , ArgumentCustomization = args => args.Append("/m").Append("/nr:false") // The /nr switch tells msbuild to quite once it�s done - , BinaryLogger = new MSBuildBinaryLogSettings() { Enabled = data.IsLocalBuild } - }; - MSBuild(solution, msBuildSettings - .SetMaxCpuCount(0) - .WithProperty("Version", data.IsReleaseBranch ? data.GitVersion.MajorMinorPatch : data.GitVersion.NuGetVersion) - .WithProperty("AssemblyVersion", data.GitVersion.AssemblySemVer) - .WithProperty("FileVersion", data.GitVersion.AssemblySemFileVer) - .WithProperty("InformationalVersion", data.GitVersion.InformationalVersion) - .WithProperty("ContinuousIntegrationBuild", data.IsReleaseBranch ? "true" : "false") - ); -}); - -Task("dotnetBuild") - .Does(data => { var buildSettings = new DotNetCoreBuildSettings { Verbosity = data.DotNetCoreVerbosity @@ -247,45 +227,43 @@ void SignFiles(IEnumerable files, string description) return; } - foreach(var file in files) + var filesToSign = string.Join(" ", files.Select(f => MakeAbsolute(f).FullPath)); + + var processSettings = new ProcessSettings { + RedirectStandardOutput = true, + RedirectStandardError = true, + Arguments = new ProcessArgumentBuilder() + .Append("sign") + .Append(filesToSign) + .AppendSwitchQuoted("--file-digest", "sha256") + .AppendSwitchQuoted("--description", description) + .AppendSwitchQuoted("--description-url", "https://github.com/punker76/gong-wpf-dragdrop") + .Append("--no-page-hashing") + .AppendSwitchQuoted("--timestamp-rfc3161", "http://timestamp.digicert.com") + .AppendSwitchQuoted("--timestamp-digest", "sha256") + .AppendSwitchQuoted("--azure-key-vault-url", vurl) + .AppendSwitchQuotedSecret("--azure-key-vault-client-id", vcid) + .AppendSwitchQuotedSecret("--azure-key-vault-tenant-id", vctid) + .AppendSwitchQuotedSecret("--azure-key-vault-client-secret", vcs) + .AppendSwitchQuotedSecret("--azure-key-vault-certificate", vc) + }; + + using(var process = StartAndReturnProcess("tools/AzureSignTool", processSettings)) { - Information($"Sign file: {file}"); - var processSettings = new ProcessSettings { - RedirectStandardOutput = true, - RedirectStandardError = true, - Arguments = new ProcessArgumentBuilder() - .Append("sign") - .Append(MakeAbsolute(file).FullPath) - .AppendSwitchQuoted("--file-digest", "sha256") - .AppendSwitchQuoted("--description", description) - .AppendSwitchQuoted("--description-url", "https://github.com/punker76/gong-wpf-dragdrop") - .Append("--no-page-hashing") - .AppendSwitchQuoted("--timestamp-rfc3161", "http://timestamp.digicert.com") - .AppendSwitchQuoted("--timestamp-digest", "sha256") - .AppendSwitchQuoted("--azure-key-vault-url", vurl) - .AppendSwitchQuotedSecret("--azure-key-vault-client-id", vcid) - .AppendSwitchQuotedSecret("--azure-key-vault-tenant-id", vctid) - .AppendSwitchQuotedSecret("--azure-key-vault-client-secret", vcs) - .AppendSwitchQuotedSecret("--azure-key-vault-certificate", vc) - }; + process.WaitForExit(); - using(var process = StartAndReturnProcess("tools/AzureSignTool", processSettings)) + if (process.GetStandardOutput().Any()) { - process.WaitForExit(); - - if (process.GetStandardOutput().Any()) - { - Information($"Output:{Environment.NewLine}{string.Join(Environment.NewLine, process.GetStandardOutput())}"); - } - - if (process.GetStandardError().Any()) - { - Information($"Errors occurred:{Environment.NewLine}{string.Join(Environment.NewLine, process.GetStandardError())}"); - } + Information($"Output:{Environment.NewLine}{string.Join(Environment.NewLine, process.GetStandardOutput())}"); + } - // This should output 0 as valid arguments supplied - Information("Exit code: {0}", process.GetExitCode()); + if (process.GetStandardError().Any()) + { + Information($"Errors occurred:{Environment.NewLine}{string.Join(Environment.NewLine, process.GetStandardError())}"); } + + // This should output 0 as valid arguments supplied + Information("Exit code: {0}", process.GetExitCode()); } } @@ -408,8 +386,7 @@ Task("CreateRelease") Task("Default") .IsDependentOn("Clean") .IsDependentOn("Restore") - //.IsDependentOn("Build") - .IsDependentOn("dotnetBuild") // doesn't work with Fody + .IsDependentOn("Build") ; Task("ci") diff --git a/src/Directory.build.props b/src/Directory.build.props index 70a8fcb3..e474fe97 100644 --- a/src/Directory.build.props +++ b/src/Directory.build.props @@ -6,7 +6,7 @@ - net452;net46;net462;net47;net48;netcoreapp3.1;net5.0-windows;net6.0-windows + net462;net47;net48;netcoreapp3.1;net5.0-windows;net6.0-windows true false true @@ -14,15 +14,13 @@ latest latest + true + full $(NoWarn);CS1591 $(NoError);CS1591 true - - $(DefineConstants);NET5_0_OR_GREATER - - diff --git a/src/GongSolutions.WPF.DragDrop/Directory.Build.props b/src/GongSolutions.WPF.DragDrop/Directory.Build.props deleted file mode 100644 index a4fe0d44..00000000 --- a/src/GongSolutions.WPF.DragDrop/Directory.Build.props +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - true - false - - true - - full - true - - $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb - - - - - - - - - - - - all - runtime; build; native; contentfiles; analyzers - - - - - \ No newline at end of file diff --git a/src/GongSolutions.WPF.DragDrop/GongSolutions.WPF.DragDrop.csproj b/src/GongSolutions.WPF.DragDrop/GongSolutions.WPF.DragDrop.csproj index c3e8ed60..f6dca3b3 100644 --- a/src/GongSolutions.WPF.DragDrop/GongSolutions.WPF.DragDrop.csproj +++ b/src/GongSolutions.WPF.DragDrop/GongSolutions.WPF.DragDrop.csproj @@ -7,4 +7,29 @@ GongSolutions.Wpf.DragDrop true + + + + + true + + + true + + + true + snupkg + + + + + + all + runtime; build; native; contentfiles; analyzers + + + + + + \ No newline at end of file diff --git a/src/GongSolutions.WPF.DragDrop/Utilities/DpiHelper.cs b/src/GongSolutions.WPF.DragDrop/Utilities/DpiHelper.cs index 3e96dd5f..b62068a5 100644 --- a/src/GongSolutions.WPF.DragDrop/Utilities/DpiHelper.cs +++ b/src/GongSolutions.WPF.DragDrop/Utilities/DpiHelper.cs @@ -1,8 +1,5 @@ using System; using System.Diagnostics.CodeAnalysis; -#if !NET462_OR_GREATER && !NETCOREAPP - using System.Reflection; -#endif using System.Windows; using System.Windows.Media; @@ -85,82 +82,5 @@ public static Thickness LogicalThicknessToDevice(Thickness logicalThickness, dou return new Thickness(topLeft.X, topLeft.Y, bottomRight.X, bottomRight.Y); } - -#if !NET462_OR_GREATER && !NETCOREAPP - public static double DpiX = 0d; - public static double DpiY = 0d; - - [SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline")] - static DpiHelper() - { - var dpiXProperty = typeof(SystemParameters).GetProperty("DpiX", BindingFlags.NonPublic | BindingFlags.Static); - var dpiYProperty = typeof(SystemParameters).GetProperty("Dpi", BindingFlags.NonPublic | BindingFlags.Static); - - var pixelsPerInchX = (int)dpiXProperty.GetValue(null, null); - DpiX = (double)pixelsPerInchX; - var pixelsPerInchY = (int)dpiYProperty.GetValue(null, null); - DpiY = (double)pixelsPerInchY; - } - - /// - /// Convert a point in device independent pixels (1/96") to a point in the system coordinates. - /// - /// A point in the logical coordinate system. - /// Returns the point converted to the system's coordinates. - public static Point LogicalPixelsToDevice(Point logicalPoint) - { - return LogicalPixelsToDevice(logicalPoint, DpiX / 96d, DpiY / 96d); - } - - /// - /// Convert a point in system coordinates to a point in device independent pixels (1/96"). - /// - /// A point in the physical coordinate system. - /// Returns the point converted to the device independent coordinate system. - public static Point DevicePixelsToLogical(Point devicePoint) - { - return DevicePixelsToLogical(devicePoint, 96d / DpiX, 96d / DpiY); - } - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static Rect LogicalRectToDevice(Rect logicalRectangle) - { - Point topLeft = LogicalPixelsToDevice(new Point(logicalRectangle.Left, logicalRectangle.Top)); - Point bottomRight = LogicalPixelsToDevice(new Point(logicalRectangle.Right, logicalRectangle.Bottom)); - - return new Rect(topLeft, bottomRight); - } - - public static Rect DeviceRectToLogical(Rect deviceRectangle) - { - Point topLeft = DevicePixelsToLogical(new Point(deviceRectangle.Left, deviceRectangle.Top)); - Point bottomRight = DevicePixelsToLogical(new Point(deviceRectangle.Right, deviceRectangle.Bottom)); - - return new Rect(topLeft, bottomRight); - } - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public static Size LogicalSizeToDevice(Size logicalSize) - { - Point pt = LogicalPixelsToDevice(new Point(logicalSize.Width, logicalSize.Height)); - - return new Size { Width = pt.X, Height = pt.Y }; - } - - public static Size DeviceSizeToLogical(Size deviceSize) - { - Point pt = DevicePixelsToLogical(new Point(deviceSize.Width, deviceSize.Height)); - - return new Size(pt.X, pt.Y); - } - - public static Thickness LogicalThicknessToDevice(Thickness logicalThickness) - { - Point topLeft = LogicalPixelsToDevice(new Point(logicalThickness.Left, logicalThickness.Top)); - Point bottomRight = LogicalPixelsToDevice(new Point(logicalThickness.Right, logicalThickness.Bottom)); - - return new Thickness(topLeft.X, topLeft.Y, bottomRight.X, bottomRight.Y); - } -#endif } } \ No newline at end of file diff --git a/src/GongSolutions.WPF.DragDrop/Utilities/DragDropExtensions.cs b/src/GongSolutions.WPF.DragDrop/Utilities/DragDropExtensions.cs index f15fb17e..1369598f 100644 --- a/src/GongSolutions.WPF.DragDrop/Utilities/DragDropExtensions.cs +++ b/src/GongSolutions.WPF.DragDrop/Utilities/DragDropExtensions.cs @@ -93,18 +93,10 @@ private static BitmapSource CaptureScreen(Visual target, FlowDirection flowDirec var bounds = VisualTreeHelper.GetDescendantBounds(target); var cropBounds = VisualTreeExtensions.GetVisibleDescendantBounds(target); -#if NET461 || NET46 || NET452 || NET451 || NET45 - var dpiX = DpiHelper.DpiX; - var dpiY = DpiHelper.DpiY; - - var dpiBounds = DpiHelper.LogicalRectToDevice(cropBounds); -#else var dpiScale = VisualTreeHelper.GetDpi(target); var dpiX = dpiScale.PixelsPerInchX; var dpiY = dpiScale.PixelsPerInchY; - var dpiBounds = DpiHelper.LogicalRectToDevice(cropBounds, dpiScale.DpiScaleX, dpiScale.DpiScaleY); -#endif var pixelWidth = (int)Math.Ceiling(dpiBounds.Width); var pixelHeight = (int)Math.Ceiling(dpiBounds.Height);