From 8d344c1b64a4b88fa78a46c0825f5d71c557a815 Mon Sep 17 00:00:00 2001
From: chr <chrry550@163.com>
Date: 星期五, 01 三月 2024 15:31:14 +0800
Subject: [PATCH] 优化DataGridUI;完善拖拽;

---
 UI/Test/ProgramList.xaml        |   72 ++--
 UI/Test/SequnceList.xaml        |  314 +++++++++++++++-----
 Models/FuncModel.cs             |   24 +
 UI/Test/FunctionSetting.xaml    |   38 +-
 UI/Test/ProgramList.xaml.cs     |    5 
 packages.config                 |   29 +
 Style/Colors.xaml               |    1 
 WPFProject.csproj               |    6 
 UI/Test/FunctionSetting.xaml.cs |   55 +++
 Utils/DdDropHandler.cs          |   94 ++++++
 Utils/DdDragHandler.cs          |   20 +
 Controls/InnerWindow.xaml       |    1 
 Style/CommonTree.xaml           |   18 
 UI/Test/SequnceList.xaml.cs     |  174 ++++++-----
 14 files changed, 605 insertions(+), 246 deletions(-)

diff --git a/Controls/InnerWindow.xaml b/Controls/InnerWindow.xaml
index 3e4e262..5d57033 100644
--- a/Controls/InnerWindow.xaml
+++ b/Controls/InnerWindow.xaml
@@ -4,6 +4,7 @@
              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
              xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
              xmlns:local="clr-namespace:WPFProject.Controls"
+             
              mc:Ignorable="d" 
              HorizontalAlignment="Stretch"
              HorizontalContentAlignment="Stretch"
diff --git a/Models/FuncModel.cs b/Models/FuncModel.cs
new file mode 100644
index 0000000..cec83ef
--- /dev/null
+++ b/Models/FuncModel.cs
@@ -0,0 +1,24 @@
+锘縰sing System.Collections.ObjectModel;
+
+namespace WPFProject.Models
+{
+    public class FuncModel : NotifyBase 
+    {
+		private string _Name;
+
+		public string Name
+		{
+			get { return _Name; }
+			set => RaiseAndSetIfChanged(ref _Name, value);
+		}
+
+		private ObservableCollection<FuncModel> _Children;
+
+		public ObservableCollection<FuncModel> Children
+		{
+			get { return _Children; }
+			set => RaiseAndSetIfChanged(ref _Children, value);
+		}
+
+	}
+}
diff --git a/Style/Colors.xaml b/Style/Colors.xaml
index 553baf9..845ba16 100644
--- a/Style/Colors.xaml
+++ b/Style/Colors.xaml
@@ -7,6 +7,7 @@
 
     <Brush x:Key="SecondaryImportant">Orange</Brush>
     <Brush x:Key="Important">#e17933</Brush>
+    <Brush x:Key="ImportantFont">#FFF</Brush>
 
 
     <Brush x:Key="ButtonColor">#103156</Brush>
diff --git a/Style/CommonTree.xaml b/Style/CommonTree.xaml
index f442292..b85aa19 100644
--- a/Style/CommonTree.xaml
+++ b/Style/CommonTree.xaml
@@ -1,13 +1,13 @@
-锘�<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
-                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+锘�<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                     
-             xmlns:hc="https://handyorg.github.io/handycontrol"
-                    >
+             xmlns:hc="https://handyorg.github.io/handycontrol"
+                    >
     <ResourceDictionary.MergedDictionaries>
-        <ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Theme.xaml"/>
-        <ResourceDictionary Source="/WPFProject;component/Style/colors.xaml"/>
-    </ResourceDictionary.MergedDictionaries>
-
+        <ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Theme.xaml"/>
+        <ResourceDictionary Source="/WPFProject;component/Style/colors.xaml"/>
+    </ResourceDictionary.MergedDictionaries>
+
     <Style TargetType="TreeViewItem" BasedOn="{StaticResource TreeViewItemBaseStyle}">
         <Setter Property="Template">
             <Setter.Value>
@@ -47,5 +47,5 @@
                 </ControlTemplate>
             </Setter.Value>
         </Setter>
-    </Style>
+    </Style>
 </ResourceDictionary>
\ No newline at end of file
diff --git a/UI/Test/FunctionSetting.xaml b/UI/Test/FunctionSetting.xaml
index 7cd077c..6347066 100644
--- a/UI/Test/FunctionSetting.xaml
+++ b/UI/Test/FunctionSetting.xaml
@@ -4,6 +4,10 @@
              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
              xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
              xmlns:local="clr-namespace:WPFProject.UI.Test"
+             xmlns:dd="urn:gong-wpf-dragdrop"
+             
+             xmlns:m="clr-namespace:WPFProject.Models"
+             xmlns:util="clr-namespace:WPFProject.Utils"
              xmlns:hc="https://handyorg.github.io/handycontrol"
              mc:Ignorable="d" 
              d:DesignHeight="450" d:DesignWidth="800">
@@ -19,41 +23,29 @@
             <Style TargetType="Label"/>
 
             <Style TargetType="TabControl"/>
-
-
-            
-
             <Style TargetType="TreeView">
-
-
-
             </Style>
         </ResourceDictionary>
     </UserControl.Resources>
 
     <Grid>
         <TabControl Style="{StaticResource ControlStyle}">
-
             <TabItem Header="鍑芥暟鍒楄〃">
                 <StackPanel>
                     <hc:SearchBar hc:InfoElement.Placeholder="杈撳叆鏂囨湰鏌ヨ"  Style="{StaticResource SearchBarPlus}" Margin="10,5,10,5"/>
-                    <TreeView BorderThickness="0" >
-
-                        <TreeViewItem Header="111">
-                            <TreeViewItem Header="111">
-                                <TreeViewItem Header="999"/>
-                            </TreeViewItem>
-                            <TreeViewItem Header="222"/>
-                            <TreeViewItem Header="333"/>
-                        </TreeViewItem>
-                        <TreeViewItem Header="222">
-                            <TreeViewItem Header="111"/>
-                            <TreeViewItem Header="222"/>
-                            <TreeViewItem Header="333"/>
-                        </TreeViewItem>
+                    <TreeView BorderThickness="0" ItemsSource="{Binding FuncModels}"
+                              dd:DragDrop.IsDragSource="True"
+                                dd:DragDrop.ShowAlwaysDropTargetAdorner="True"
+                                dd:DragDrop.UseDefaultDragAdorner="True"
+                                dd:DragDrop.DragHandler="{Binding dragHandler}"
+                              >
+                        <TreeView.ItemTemplate>
+                            <HierarchicalDataTemplate DataType="{x:Type m:FuncModel}" ItemsSource="{Binding Path=Children}">
+                                <ContentControl Content="{Binding Name}"/>
+                            </HierarchicalDataTemplate>
+                        </TreeView.ItemTemplate>
                     </TreeView>
                 </StackPanel>
-
             </TabItem>
             <TabItem Header="鍙橀噺鍒楄〃">
             </TabItem>
diff --git a/UI/Test/FunctionSetting.xaml.cs b/UI/Test/FunctionSetting.xaml.cs
index 3049928..637c21d 100644
--- a/UI/Test/FunctionSetting.xaml.cs
+++ b/UI/Test/FunctionSetting.xaml.cs
@@ -1,6 +1,9 @@
 锘縰sing System;
 using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
 using System.Linq;
+using System.Runtime.CompilerServices;
 using System.Text;
 using System.Threading.Tasks;
 using System.Windows;
@@ -12,17 +15,65 @@
 using System.Windows.Media.Imaging;
 using System.Windows.Navigation;
 using System.Windows.Shapes;
+using WPFProject.Models;
+using WPFProject.Utils;
 
 namespace WPFProject.UI.Test
 {
     /// <summary>
     /// FunctionSetting.xaml 鐨勪氦浜掗�昏緫
     /// </summary>
-    public partial class FunctionSetting : UserControl
-    {
+    public partial class FunctionSetting : UserControl, INotifyPropertyChanged
+    {
+        public virtual event PropertyChangedEventHandler PropertyChanged;
+
+        protected virtual void RaisePropertyChanged(string name)
+        {
+            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
+        }
+
+        protected void RaiseAndSetIfChanged<T>(ref T old, T @new, [CallerMemberName] string propertyName = null)
+        {
+            old = @new;
+            if (propertyName != null)
+            {
+                RaisePropertyChanged(propertyName);
+            }
+        }
+
         public FunctionSetting()
         {
+            DataContext = this;
             InitializeComponent();
+           
         }
+
+        public DdDragHandler dragHandler { get; set; } = new DdDragHandler();
+
+        private ObservableCollection<FuncModel> _FuncModels = new ObservableCollection<FuncModel>() { 
+        
+            new FuncModel(){ 
+                Name = "111",
+                Children = new ObservableCollection<FuncModel>(){ 
+                    new FuncModel(){ Name = "1123"},
+                    new FuncModel(){ Name = "1223"},
+                }
+            },
+            new FuncModel()
+            {
+                Name = "222",
+                Children = new ObservableCollection<FuncModel>(){
+                    new FuncModel(){ Name = "2123"},
+                    new FuncModel(){ Name = "2223"},
+                }
+            }
+        };
+
+        public ObservableCollection<FuncModel> FuncModels
+        {
+            get { return _FuncModels; }
+            set => RaiseAndSetIfChanged(ref _FuncModels, value);
+        }
+
     }
 }
diff --git a/UI/Test/ProgramList.xaml b/UI/Test/ProgramList.xaml
index c6bae47..56d6444 100644
--- a/UI/Test/ProgramList.xaml
+++ b/UI/Test/ProgramList.xaml
@@ -1,33 +1,39 @@
-锘�<UserControl x:Class="WPFProject.UI.Test.ProgramList"
-             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
-             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
-             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
-             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
-             xmlns:local="clr-namespace:WPFProject.UI.Test"
-             xmlns:vm="clr-namespace:WPFProject.ViewModels"
-             mc:Ignorable="d" 
-             HorizontalAlignment="Stretch"
-             HorizontalContentAlignment="Stretch"
-             Background="#FFF" >
-    <UserControl.Resources>
-        <ResourceDictionary>
-            <ResourceDictionary.MergedDictionaries>
-                <ResourceDictionary Source="/WPFProject;component/Style/ListViewStyle.xaml"/>
-            </ResourceDictionary.MergedDictionaries>
-
-            <Style TargetType="Label"></Style>
-        </ResourceDictionary>
-    </UserControl.Resources>
-    
-    <Grid>
-        <ListView ItemsSource="{Binding Programs}" ItemContainerStyle="{StaticResource a}" 
-                  VerticalContentAlignment="Center"
-                  SelectionChanged="ListView_SelectionChanged">
-            <ListView.ItemTemplate>
-                <DataTemplate>
-                    <ContentControl Content="{Binding Name}"/>
-                </DataTemplate>
-            </ListView.ItemTemplate>
-        </ListView>
-    </Grid>
-</UserControl>
+锘�<UserControl x:Class="WPFProject.UI.Test.ProgramList"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
+             xmlns:local="clr-namespace:WPFProject.UI.Test"
+             xmlns:vm="clr-namespace:WPFProject.ViewModels"
+             xmlns:dd="urn:gong-wpf-dragdrop"
+             
+             mc:Ignorable="d" 
+             HorizontalAlignment="Stretch"
+             HorizontalContentAlignment="Stretch"
+             Background="#FFF" >
+    <UserControl.Resources>
+        <ResourceDictionary>
+            <ResourceDictionary.MergedDictionaries>
+                <ResourceDictionary Source="/WPFProject;component/Style/ListViewStyle.xaml"/>
+            </ResourceDictionary.MergedDictionaries>
+
+            <Style TargetType="Label"></Style>
+        </ResourceDictionary>
+    </UserControl.Resources>
+    
+    <Grid>
+        <ListView ItemsSource="{Binding Programs}" ItemContainerStyle="{StaticResource a}" 
+                  VerticalContentAlignment="Center"
+                  dd:DragDrop.IsDragSource="True"
+                  dd:DragDrop.IsDropTarget="True"
+                  dd:DragDrop.ShowAlwaysDropTargetAdorner="True"
+                  dd:DragDrop.UseDefaultDragAdorner="True"
+                  SelectionChanged="ListView_SelectionChanged">
+            <ListView.ItemTemplate>
+                <DataTemplate>
+                    <ContentControl Content="{Binding Name}"/>
+                </DataTemplate>
+            </ListView.ItemTemplate>
+        </ListView>
+    </Grid>
+</UserControl>
diff --git a/UI/Test/ProgramList.xaml.cs b/UI/Test/ProgramList.xaml.cs
index f7eccb0..e2516e9 100644
--- a/UI/Test/ProgramList.xaml.cs
+++ b/UI/Test/ProgramList.xaml.cs
@@ -73,7 +73,10 @@
 
         private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
         {
-            ProgramChanged?.Invoke(this, e.AddedItems[0] as Program);
+            if (e.AddedItems.Count > 0)
+            {
+                ProgramChanged?.Invoke(this, e.AddedItems[0] as Program);
+            }
         }
     }
 }
diff --git a/UI/Test/SequnceList.xaml b/UI/Test/SequnceList.xaml
index 54a58d6..38396cb 100644
--- a/UI/Test/SequnceList.xaml
+++ b/UI/Test/SequnceList.xaml
@@ -1,87 +1,227 @@
-锘�<UserControl x:Class="WPFProject.UI.Test.SequnceList"
-             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
-             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
-             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
-             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
-             xmlns:local="clr-namespace:WPFProject.UI.Test"
-             
-             mc:Ignorable="d" 
-             Background="#FFF"
-             d:DesignHeight="450" d:DesignWidth="800">
-    <UserControl.Resources>
-        <ResourceDictionary>
-            <ResourceDictionary.MergedDictionaries>
-                <ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/SkinDefault.xaml"/>
-                <ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Theme.xaml"/>
-                <ResourceDictionary Source="/WPFProject;component/Style/colors.xaml"/>
-                <ResourceDictionary Source="/WPFProject;component/Style/WindowResources.xaml"/>
-                <ResourceDictionary Source="/WPFProject;component/Style/ListViewStyle.xaml"/>
-            </ResourceDictionary.MergedDictionaries>
-
-            <Style TargetType="Label"></Style>
-            <Style TargetType="ListView"></Style>
-            <Color x:Key="DarkPrimaryColor">#e17933</Color>
-            <Color x:Key="PrimaryColor">#e17933</Color>
-
-        </ResourceDictionary>
-    </UserControl.Resources>
-    
-    <Grid>
-        <Grid.ColumnDefinitions>
-            <ColumnDefinition Width="3*"/>
-            <ColumnDefinition Width="2"/>
-            <ColumnDefinition Width="7*"/>
-        </Grid.ColumnDefinitions>
-        <ListView ItemContainerStyle="{StaticResource a}" ItemsSource="{Binding Sequences}" BorderThickness="0">
-
-            <ListView.ItemTemplate>
-                <DataTemplate>
-                    <ContentControl Content="{Binding Name}"/>
-                </DataTemplate>
-            </ListView.ItemTemplate>
-        </ListView>
-
-        <GridSplitter Grid.Column="1" Background="LightGray" HorizontalAlignment="Center" Width="2" ResizeDirection="Columns"/>
-
-        <Grid Grid.Column="2">
-            <Grid.RowDefinitions>
-                <RowDefinition Height="30"/>
-                <RowDefinition/>
-            </Grid.RowDefinitions>
-            <Label Content="娴嬭瘯娴佺▼" VerticalContentAlignment="Center"/>
-
-            <DataGrid x:Name="dataGrid" AutoGenerateColumns="False" FrozenColumnCount="1" Background="#FFF" Grid.Row="1" 
-                      BorderThickness="0"
-                      ItemsSource="{Binding Steps}">
-                <DataGrid.Columns>
-                    <DataGridTextColumn IsReadOnly="True" Width="80" CanUserResize="False" Binding="{Binding Index}" Header="搴忓彿"/>
-
-                    <DataGridTextColumn Header="鏍囬1" Binding="{Binding Name}"></DataGridTextColumn>
-                    <DataGridTextColumn Header="鏍囬2" Binding="{Binding Name}"></DataGridTextColumn>
-                    <DataGridTextColumn Header="鏍囬3" Binding="{Binding Name}"></DataGridTextColumn>
-                    <DataGridTextColumn Header="鏍囬4" Binding="{Binding Name}"></DataGridTextColumn>
-
-                    <DataGridTemplateColumn x:Name="opt" Width="120" CanUserResize="False" Header="鎿嶄綔">
-                        <DataGridTemplateColumn.CellTemplate>
-                            <DataTemplate>
-                                <StackPanel Orientation="Horizontal">
-                                    <Button Style="{StaticResource LinkButton}" Margin="0,0,20,0">123</Button>
-                                    <Button Style="{StaticResource LinkButton}">鍒犻櫎</Button>
-                                </StackPanel>
-                            </DataTemplate>
-                        </DataGridTemplateColumn.CellTemplate>
-                    </DataGridTemplateColumn>
-                </DataGrid.Columns>
-            </DataGrid>
-
-            <!--<ListView >
-                <ListView.View>
-                    <GridView>
-                        
-                    </GridView>
-                </ListView.View>
-            </ListView>-->
-        </Grid>
-
-    </Grid>
-</UserControl>
+锘�<UserControl x:Class="WPFProject.UI.Test.SequnceList"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
+             xmlns:local="clr-namespace:WPFProject.UI.Test"
+             xmlns:hc="https://handyorg.github.io/handycontrol"
+             xmlns:dd="urn:gong-wpf-dragdrop"
+             
+             mc:Ignorable="d" 
+             Background="#FFF"
+             d:DesignHeight="450" d:DesignWidth="800">
+    <UserControl.Resources>
+        <ResourceDictionary>
+            <ResourceDictionary.MergedDictionaries>
+                <ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/SkinDefault.xaml"/>
+                <ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Theme.xaml"/>
+                <ResourceDictionary Source="/WPFProject;component/Style/colors.xaml"/>
+                <ResourceDictionary Source="/WPFProject;component/Style/WindowResources.xaml"/>
+                <ResourceDictionary Source="/WPFProject;component/Style/ListViewStyle.xaml"/>
+            </ResourceDictionary.MergedDictionaries>
+
+            <Style TargetType="Label"></Style>
+            <Style TargetType="ListView"></Style>
+
+            <Style TargetType="DataGridRow" x:Key="CommonRow" BasedOn="{StaticResource DataGridRowStyle}">
+                <Setter Property="Margin" Value="0"/>
+                <Setter Property="Template">
+                    <Setter.Value>
+                        <ControlTemplate TargetType="DataGridRow">
+                            <SelectiveScrollingGrid>
+                                <SelectiveScrollingGrid.ColumnDefinitions>
+                                    <ColumnDefinition Width="Auto"/>
+                                    <ColumnDefinition Width="*"/>
+                                </SelectiveScrollingGrid.ColumnDefinitions>
+                                <SelectiveScrollingGrid.RowDefinitions>
+                                    <RowDefinition Height="*"/>
+                                    <RowDefinition Height="Auto"/>
+                                </SelectiveScrollingGrid.RowDefinitions>
+                                <Border Grid.ColumnSpan="2" x:Name="DGR_Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True"/>
+                                <DataGridCellsPresenter MinHeight="{TemplateBinding MinHeight}" VerticalContentAlignment="Center" Grid.Row="0" Grid.Column="1" ItemsPanel="{TemplateBinding ItemsPanel}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
+                                <DataGridDetailsPresenter Grid.Column="1" Grid.Row="1" SelectiveScrollingGrid.SelectiveScrollingOrientation="{Binding AreRowDetailsFrozen, ConverterParameter={x:Static SelectiveScrollingOrientation.Vertical}, Converter={x:Static DataGrid.RowDetailsScrollingConverter}, RelativeSource={RelativeSource AncestorType=DataGrid}}" Visibility="{TemplateBinding DetailsVisibility}"/>
+                                <DataGridRowHeader Grid.Row="0" Grid.Column="0" SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical" Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.Row}, Converter={x:Static DataGrid.HeadersVisibilityConverter}, RelativeSource={RelativeSource AncestorType=DataGrid}}"/>
+                            </SelectiveScrollingGrid>
+                        </ControlTemplate>
+                    </Setter.Value>
+                </Setter>
+                <Style.Triggers>
+                    <Trigger Property="IsMouseOver" Value="true">
+                        <Setter Property="Background" Value="{StaticResource SecondaryImportant}"/>
+                    </Trigger>
+                    <Trigger Property="IsSelected" Value="True">
+                        <Setter Property="Background" Value="{StaticResource Important}"/>
+                        <Setter Property="TextElement.Foreground" Value="#FFF"/>
+                    </Trigger>
+                    <!--<MultiTrigger>
+                        <MultiTrigger.Conditions>
+                            <Condition Property="IsSelected" Value="true"/>
+                            <Condition Property="Selector.IsSelectionActive" Value="false"/>
+                        </MultiTrigger.Conditions>
+                        <Setter Property="Background" Value="{DynamicResource DarkDefaultBrush}"/>
+                        <Setter Property="Foreground" Value="{DynamicResource PrimaryTextBrush}"/>
+                    </MultiTrigger>-->
+                </Style.Triggers>
+
+            </Style>
+
+            <Style TargetType="DataGridColumnHeader" x:Key="CommonColumnHeader">
+                <Setter Property="BorderBrush" Value="{Binding Path=HorizontalGridLinesBrush,RelativeSource={RelativeSource FindAncestor,AncestorType=DataGrid}}"/>
+                <Setter Property="BorderThickness" Value="0,1,1,1"/>
+
+                <Style.Triggers>
+                    <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Column.DisplayIndex}" Value="0">
+                        <Setter Property="BorderThickness" Value="1,1,1,1"/>
+                    </DataTrigger>
+                </Style.Triggers>
+            </Style>
+
+            <Style TargetType="DataGridCell" x:Key="CommonCell" BasedOn="{StaticResource DataGridCellStyle}">
+                <Setter Property="BorderBrush" Value="{Binding Path=HorizontalGridLinesBrush,RelativeSource={RelativeSource FindAncestor,AncestorType=DataGrid}}"/>
+                <Setter Property="BorderThickness" Value="0,0,1,1"/>
+                <Setter Property="Padding" Value="0"/>
+                <Setter Property="Template">
+                    <Setter.Value>
+                        <ControlTemplate TargetType="DataGridCell">
+                            <Border Padding="{TemplateBinding Padding}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
+                                <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
+                            </Border>
+                        </ControlTemplate>
+                    </Setter.Value>
+                </Setter>
+                <Style.Triggers>
+                    <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Column.DisplayIndex}" Value="0">
+                        <Setter Property="BorderThickness" Value="1,0,1,1"/>
+                    </DataTrigger>
+                    <MultiDataTrigger>
+                        <MultiDataTrigger.Conditions>
+                            <Condition Binding="{Binding IsSelected,RelativeSource={RelativeSource Self}}" Value="true"/>
+                            <Condition Binding="{Binding SelectionUnit,RelativeSource={RelativeSource FindAncestor,AncestorType=DataGrid}}" Value="Cell"/>
+                        </MultiDataTrigger.Conditions>
+                        <Setter Property="Foreground" Value="{StaticResource ImportantFont}"/>
+                        <Setter Property="Background" Value="{StaticResource Important}"/>
+                    </MultiDataTrigger>
+                    <MultiDataTrigger>
+                        <MultiDataTrigger.Conditions>
+                            <Condition Binding="{Binding IsSelected,RelativeSource={RelativeSource Self}}" Value="true"/>
+                            <Condition Binding="{Binding IsSelected,RelativeSource={RelativeSource AncestorType=DataGridRow}}" Value="False"/>
+                            <Condition Binding="{Binding SelectionUnit,RelativeSource={RelativeSource FindAncestor,AncestorType=DataGrid}}" Value="CellOrRowHeader"/>
+                        </MultiDataTrigger.Conditions>
+                        <Setter Property="Foreground" Value="{StaticResource ImportantFont}"/>
+                        <Setter Property="Background" Value="{StaticResource Important}"/>
+                    </MultiDataTrigger>
+                    <MultiDataTrigger>
+                        <MultiDataTrigger.Conditions>
+                            <Condition Binding="{Binding IsSelected,RelativeSource={RelativeSource Self}}" Value="true"/>
+                            <Condition Binding="{Binding IsSelected,RelativeSource={RelativeSource AncestorType=DataGridRow}}" Value="True"/>
+                            <Condition Binding="{Binding SelectionUnit,RelativeSource={RelativeSource FindAncestor,AncestorType=DataGrid}}" Value="CellOrRowHeader"/>
+                        </MultiDataTrigger.Conditions>
+                        <Setter Property="Foreground" Value="{StaticResource ImportantFont}"/>
+                    </MultiDataTrigger>
+                    <MultiDataTrigger>
+                        <MultiDataTrigger.Conditions>
+                            <Condition Binding="{Binding IsSelected,RelativeSource={RelativeSource Self}}" Value="true"/>
+                            <Condition Binding="{Binding SelectionUnit,RelativeSource={RelativeSource FindAncestor,AncestorType=DataGrid}}" Value="FullRow"/>
+                        </MultiDataTrigger.Conditions>
+                        <Setter Property="Foreground" Value="{StaticResource ImportantFont}"/>
+                    </MultiDataTrigger>
+                    <MultiTrigger>
+                        <MultiTrigger.Conditions>
+                            <Condition Property="IsSelected" Value="true"/>
+                            <Condition Property="Selector.IsSelectionActive" Value="false"/>
+                        </MultiTrigger.Conditions>
+                        <Setter Property="Foreground" Value="{StaticResource ImportantFont}"/>
+                        <Setter Property="Background" Value="{StaticResource Important}"/>
+                    </MultiTrigger>
+                </Style.Triggers>
+            </Style>
+
+            <Style TargetType="DataGrid" BasedOn="{StaticResource DataGridBaseStyle}">
+                <Setter Property="GridLinesVisibility" Value="None"/>
+                <Setter Property="HorizontalGridLinesBrush" Value="Gray"/>
+                <Setter Property="RowStyle" Value="{StaticResource CommonRow}"/>
+                <Setter Property="CellStyle" Value="{StaticResource CommonCell}"/>
+                <Setter Property="ColumnHeaderStyle" Value="{StaticResource CommonColumnHeader}"/>
+                <Setter Property="hc:BorderElement.CornerRadius" Value="0" />
+                <Setter Property="RowHeight" Value="30"/>
+            </Style>
+
+        </ResourceDictionary>
+    </UserControl.Resources>
+    
+    <Grid>
+        <Grid.ColumnDefinitions>
+            <ColumnDefinition Width="3*"/>
+            <ColumnDefinition Width="2"/>
+            <ColumnDefinition Width="7*"/>
+        </Grid.ColumnDefinitions>
+        <ListView ItemContainerStyle="{StaticResource a}" ItemsSource="{Binding Sequences}" BorderThickness="0"
+                  dd:DragDrop.IsDragSource="True"
+                    dd:DragDrop.IsDropTarget="True"
+                    dd:DragDrop.ShowAlwaysDropTargetAdorner="True"
+                    dd:DragDrop.UseDefaultDragAdorner="True"
+                  SelectionChanged="ListView_SelectionChanged">
+
+            <ListView.ItemTemplate>
+                <DataTemplate>
+                    <ContentControl Content="{Binding Name}"/>
+                </DataTemplate>
+            </ListView.ItemTemplate>
+        </ListView>
+
+        <GridSplitter Grid.Column="1" Background="LightGray" HorizontalAlignment="Center" Width="2" ResizeDirection="Columns"/>
+
+        <Grid Grid.Column="2">
+            <Grid.RowDefinitions>
+                <RowDefinition Height="30"/>
+                <RowDefinition/>
+            </Grid.RowDefinitions>
+            <Label Content="娴嬭瘯娴佺▼" VerticalContentAlignment="Center"/>
+
+            <DataGrid x:Name="dataGrid" AutoGenerateColumns="False" 
+                       
+                      CanUserAddRows="False"
+                      CanUserSortColumns="False"
+                      FrozenColumnCount="1" Background="#FFF" Grid.Row="1" 
+                      BorderThickness="0"
+                      dd:DragDrop.IsDragSource="True"
+                      dd:DragDrop.IsDropTarget="True"
+                      dd:DragDrop.ShowAlwaysDropTargetAdorner="True"
+                      dd:DragDrop.UseDefaultDragAdorner="True"
+                    
+                      dd:DragDrop.SelectDroppedItems="True"
+                      dd:DragDrop.DropHandler="{Binding dropHandler}"
+                      
+                      ItemsSource="{Binding Steps}">
+                <DataGrid.Columns>
+                    <DataGridTextColumn IsReadOnly="True" Binding="{Binding Index}" Header="搴忓彿"/>
+
+                    <DataGridTextColumn Header="鏍囬1" Binding="{Binding Name}"></DataGridTextColumn>
+                    <DataGridTextColumn Header="鏍囬2" Binding="{Binding Name}"></DataGridTextColumn>
+                    <DataGridTextColumn Header="鏍囬3" Binding="{Binding Name}"></DataGridTextColumn>
+                    <DataGridTextColumn Header="鏍囬4" Binding="{Binding Name}"></DataGridTextColumn>
+
+                    <DataGridTemplateColumn x:Name="opt" Width="*" Header="鎿嶄綔">
+                        <DataGridTemplateColumn.CellTemplate>
+                            <DataTemplate>
+                                <StackPanel Orientation="Horizontal">
+                                    <Button Style="{StaticResource LinkButton}" Margin="0,0,20,0">123</Button>
+                                    <Button Style="{StaticResource LinkButton}">鍒犻櫎</Button>
+                                </StackPanel>
+                            </DataTemplate>
+                        </DataGridTemplateColumn.CellTemplate>
+                    </DataGridTemplateColumn>
+                </DataGrid.Columns>
+            </DataGrid>
+
+            <!--<ListView >
+                <ListView.View>
+                    <GridView>
+                        
+                    </GridView>
+                </ListView.View>
+            </ListView>-->
+        </Grid>
+
+    </Grid>
+</UserControl>
diff --git a/UI/Test/SequnceList.xaml.cs b/UI/Test/SequnceList.xaml.cs
index 03bed2e..7baf5b2 100644
--- a/UI/Test/SequnceList.xaml.cs
+++ b/UI/Test/SequnceList.xaml.cs
@@ -1,77 +1,97 @@
-锘縰sing AIStudio.Wpf.Controls;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
-using System.Runtime.CompilerServices;
-using System.Windows.Controls;
-using WPFProject.Models;
-
-namespace WPFProject.UI.Test
-{
-
-
-    /// <summary>
-    /// SequnceList.xaml 鐨勪氦浜掗�昏緫
-    /// </summary>
-    public partial class SequnceList : UserControl, INotifyPropertyChanged
-    {
-        public virtual event PropertyChangedEventHandler PropertyChanged;
-
-        protected virtual void RaisePropertyChanged(string name)
-        {
-            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
-        }
-
-        protected void RaiseAndSetIfChanged<T>(ref T old, T @new, [CallerMemberName] string propertyName = null)
-        {
-            old = @new;
-            if (propertyName != null)
-            {
-                RaisePropertyChanged(propertyName);
-            }
-        }
-        public SequnceList()
-        {
-            DataContext = this;
-
-            Sequences = new ObservableCollection<Sequence>
-            {
-                new Sequence{ Name="SSSSS"},
-                new Sequence{ Name="SSSSS2"},
-            };
-
-            Steps = Sequences[0].Steps;
-
-            InitializeComponent();
-        }
-        private ObservableCollection<Sequence> _Sequences;
-        public ObservableCollection<Sequence> Sequences
-        {
-            get => _Sequences;
-            set
-            {
-                if (value != null && value.Count > 0)
-                {
-                    Steps = value[0].Steps;
-                }
-                else {
-                    Steps = null;
-                }
-                RaiseAndSetIfChanged(ref _Sequences, value);
-            }
-        }
-
-        private ObservableCollection<Step> _Steps;
-        public ObservableCollection<Step> Steps
-        {
-            get => _Steps;
-            set => RaiseAndSetIfChanged(ref _Steps, value);
-        }
-
-
-        public void Selected_Program_Changed(object sender, Program program)
-        {
-            this.Sequences = program.Sequences;
-        }
-
-    }
-}
+锘縰sing AIStudio.Wpf.Controls;
+using GongSolutions.Wpf.DragDrop;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+using System.Windows.Controls;
+using WPFProject.Models;
+using WPFProject.Utils;
+
+namespace WPFProject.UI.Test
+{
+
+
+    /// <summary>
+    /// SequnceList.xaml 鐨勪氦浜掗�昏緫
+    /// </summary>
+    public partial class SequnceList : UserControl, INotifyPropertyChanged
+    {
+        public virtual event PropertyChangedEventHandler PropertyChanged;
+
+        protected virtual void RaisePropertyChanged(string name)
+        {
+            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
+        }
+
+        protected void RaiseAndSetIfChanged<T>(ref T old, T @new, [CallerMemberName] string propertyName = null)
+        {
+            old = @new;
+            if (propertyName != null)
+            {
+                RaisePropertyChanged(propertyName);
+            }
+        }
+        public SequnceList()
+        {
+            DataContext = this;
+
+            Sequences = new ObservableCollection<Sequence>
+            {
+                new Sequence{ Name="SSSSS"},
+                new Sequence{ Name="SSSSS2"},
+            };
+
+            Steps = Sequences[0].Steps;
+
+            InitializeComponent();
+        }
+        private ObservableCollection<Program> _ps = new ObservableCollection<Program>();
+        public ObservableCollection<Program> Ps
+        {
+            get => _ps;
+            set => RaiseAndSetIfChanged(ref _ps, value);
+        }
+
+
+        private ObservableCollection<Sequence> _Sequences;
+        public ObservableCollection<Sequence> Sequences
+        {
+            get => _Sequences;
+            set
+            {
+                if (value != null && value.Count > 0)
+                {
+                    Steps = value[0].Steps;
+                }
+                else {
+                    Steps = null;
+                }
+                RaiseAndSetIfChanged(ref _Sequences, value);
+            }
+        }
+
+        private ObservableCollection<Step> _Steps;
+        public ObservableCollection<Step> Steps
+        {
+            get => _Steps;
+            set => RaiseAndSetIfChanged(ref _Steps, value);
+        }
+
+
+        public void Selected_Program_Changed(object sender, Program program)
+        {
+            this.Sequences = program.Sequences;
+        }
+
+        private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
+        {
+            if (e.AddedItems.Count > 0)
+            {
+                Steps = (e.AddedItems[0] as Sequence).Steps;
+            }
+        }
+
+        public IDropTarget dropHandler { get; set; } = new DdDropHandler();
+
+    }
+}
diff --git a/Utils/DdDragHandler.cs b/Utils/DdDragHandler.cs
new file mode 100644
index 0000000..009f608
--- /dev/null
+++ b/Utils/DdDragHandler.cs
@@ -0,0 +1,20 @@
+锘縰sing GongSolutions.Wpf.DragDrop;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using WPFProject.Models;
+
+namespace WPFProject.Utils
+{
+    public class DdDragHandler : DefaultDragHandler
+    {
+        public override bool CanStartDrag(IDragInfo dragInfo)
+        {
+            FuncModel model = dragInfo.SourceItem as FuncModel;
+            return model.Children ==null || model.Children.Count == 0;
+        }
+    }
+}
diff --git a/Utils/DdDropHandler.cs b/Utils/DdDropHandler.cs
new file mode 100644
index 0000000..6722c5c
--- /dev/null
+++ b/Utils/DdDropHandler.cs
@@ -0,0 +1,94 @@
+锘縰sing GongSolutions.Wpf.DragDrop;
+using GongSolutions.Wpf.DragDrop.Utilities;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Markup;
+using System.Linq;
+using System.Collections;
+using WPFProject.Models;
+
+namespace WPFProject.Utils
+{
+    public class DdDropHandler : DefaultDropHandler
+    {
+        public bool CanConvert(IDropInfo dropInfo)
+        {
+            bool InterfaceFilter(Type t, object o) => (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IEnumerable<>));
+            Type[] enumerableInterfaces = dropInfo.TargetCollection.GetType().FindInterfaces(InterfaceFilter, null);
+            var enumerableTypes = from i in enumerableInterfaces
+                                  select i.GetGenericArguments().Single();
+
+            if (enumerableTypes.Any())
+            {
+                Type dataType = TypeUtilities.GetCommonBaseClass(ExtractData(dropInfo.Data));
+                return dataType == typeof(FuncModel) && enumerableTypes.Any(t => t==typeof(Step));
+            }
+
+            return false;
+        }
+
+        public Step ConvertFunc2Step(FuncModel func) {
+            return new Step
+            {
+                Name = func.Name
+            };
+        }
+
+
+
+        public override void DragOver(IDropInfo dropInfo)
+        {
+            if (CanAcceptData(dropInfo))
+            {
+                base.DragOver(dropInfo);
+            }
+            else if (CanConvert(dropInfo))
+            {
+                // 鍥哄畾Copy
+                dropInfo.Effects = DragDropEffects.Copy;
+                var isTreeViewItem = dropInfo.InsertPosition.HasFlag(RelativeInsertPosition.TargetItemCenter) && dropInfo.VisualTargetItem is TreeViewItem;
+                dropInfo.DropTargetAdorner = isTreeViewItem ? DropTargetAdorners.Highlight : DropTargetAdorners.Insert;
+            }
+        }
+
+        public override void Drop(IDropInfo dropInfo)
+        {
+            if (CanAcceptData(dropInfo))
+            {
+                base.Drop(dropInfo);
+            }
+            else if (CanConvert(dropInfo))
+            {
+                int insertIndex = GetInsertIndex(dropInfo);
+                var destinationList = dropInfo.TargetCollection.TryGetList();
+                var data = ExtractData(dropInfo.Data).OfType<object>().ToList();
+
+                if (destinationList != null)
+                {
+                    var objects2Insert = new List<object>();
+
+                    foreach (var o in data)
+                    {
+                        var obj2Insert = ConvertFunc2Step(o as FuncModel);
+
+                        objects2Insert.Add(obj2Insert);
+
+                        destinationList.Insert(insertIndex++, obj2Insert);
+                        // 涓嬫柟瀵硅薄濡傛灉瀹炵幇浜� IDragItemSource 鎺ュ彛锛屼細鍦ㄨ繖閲岃皟鐢� ItemDropped 鏂规硶锛岀畻鏄悗缃鐞�
+                        if (obj2Insert is IDragItemSource dragItemSource)
+                        {
+                            dragItemSource.ItemDropped(dropInfo);
+                        }
+                    }
+
+                    SelectDroppedItems(dropInfo, objects2Insert);
+                }
+            }
+            
+        }
+
+    }
+}
diff --git a/WPFProject.csproj b/WPFProject.csproj
index a395084..3510247 100644
--- a/WPFProject.csproj
+++ b/WPFProject.csproj
@@ -39,6 +39,9 @@
     <Reference Include="AIStudio.Wpf.Controls, Version=1.2.2.0, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>packages\AIStudio.Wpf.Controls.1.2.2\lib\net461\AIStudio.Wpf.Controls.dll</HintPath>
     </Reference>
+    <Reference Include="GongSolutions.WPF.DragDrop, Version=3.0.0.0, Culture=neutral, PublicKeyToken=91f1945125b7a587, processorArchitecture=MSIL">
+      <HintPath>packages\gong-wpf-dragdrop.3.2.1\lib\net47\GongSolutions.WPF.DragDrop.dll</HintPath>
+    </Reference>
     <Reference Include="HandyControl, Version=3.4.0.0, Culture=neutral, PublicKeyToken=45be8712787a1e5b, processorArchitecture=MSIL">
       <HintPath>packages\HandyControl.3.4.0\lib\net472\HandyControl.dll</HintPath>
     </Reference>
@@ -129,6 +132,7 @@
       <DependentUpon>Form1.cs</DependentUpon>
     </Compile>
     <Compile Include="Models\CanvasPosition.cs" />
+    <Compile Include="Models\FuncModel.cs" />
     <Compile Include="Models\NotifyBase.cs" />
     <Compile Include="Models\Program.cs" />
     <Compile Include="Models\Sequence.cs" />
@@ -158,6 +162,8 @@
       <DependentUpon>WorkWindow.xaml</DependentUpon>
     </Compile>
     <Compile Include="Utils\CanvasHelper.cs" />
+    <Compile Include="Utils\DdDragHandler.cs" />
+    <Compile Include="Utils\DdDropHandler.cs" />
     <Compile Include="Utils\IPlugin.cs" />
     <Compile Include="Utils\Resize.cs" />
     <Compile Include="Utils\Win32Helper.cs" />
diff --git a/packages.config b/packages.config
index 1edd804..925ee0e 100644
--- a/packages.config
+++ b/packages.config
@@ -1,15 +1,16 @@
-锘�<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="AIStudio.Wpf.Controls" version="1.2.2" targetFramework="net472" />
-  <package id="HandyControl" version="3.4.0" targetFramework="net472" />
-  <package id="Microsoft.Xaml.Behaviors.Wpf" version="1.1.39" targetFramework="net472" />
-  <package id="Newtonsoft.Json" version="13.0.1" targetFramework="net472" />
-  <package id="System.IO" version="4.3.0" targetFramework="net472" />
-  <package id="System.Net.Http" version="4.3.4" targetFramework="net472" />
-  <package id="System.Runtime" version="4.3.0" targetFramework="net472" />
-  <package id="System.Security.Cryptography.Algorithms" version="4.3.0" targetFramework="net472" />
-  <package id="System.Security.Cryptography.Encoding" version="4.3.0" targetFramework="net472" />
-  <package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="net472" />
-  <package id="System.Security.Cryptography.X509Certificates" version="4.3.0" targetFramework="net472" />
-  <package id="WPF.MDI" version="1.1.4" targetFramework="net472" />
+锘�<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="AIStudio.Wpf.Controls" version="1.2.2" targetFramework="net472" />
+  <package id="gong-wpf-dragdrop" version="3.2.1" targetFramework="net472" />
+  <package id="HandyControl" version="3.4.0" targetFramework="net472" />
+  <package id="Microsoft.Xaml.Behaviors.Wpf" version="1.1.39" targetFramework="net472" />
+  <package id="Newtonsoft.Json" version="13.0.1" targetFramework="net472" />
+  <package id="System.IO" version="4.3.0" targetFramework="net472" />
+  <package id="System.Net.Http" version="4.3.4" targetFramework="net472" />
+  <package id="System.Runtime" version="4.3.0" targetFramework="net472" />
+  <package id="System.Security.Cryptography.Algorithms" version="4.3.0" targetFramework="net472" />
+  <package id="System.Security.Cryptography.Encoding" version="4.3.0" targetFramework="net472" />
+  <package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="net472" />
+  <package id="System.Security.Cryptography.X509Certificates" version="4.3.0" targetFramework="net472" />
+  <package id="WPF.MDI" version="1.1.4" targetFramework="net472" />
 </packages>
\ No newline at end of file

--
Gitblit v1.9.1