删除原有的上 下,删 按钮方式的操作逻辑,改用拖动,和左键激活

This commit is contained in:
zhengxuan.zhang
2026-04-23 16:24:49 +08:00
parent 3f3820073f
commit 9bdd67ffb7
2 changed files with 57 additions and 107 deletions
@@ -68,32 +68,30 @@
Background="#F5F5F5" Background="#F5F5F5"
BorderBrush="{StaticResource PanelBorder}" BorderBrush="{StaticResource PanelBorder}"
BorderThickness="0,1,0,1"> BorderThickness="0,1,0,1">
<Grid> <StackPanel HorizontalAlignment="Left" Orientation="Horizontal">
<StackPanel HorizontalAlignment="Left" Orientation="Horizontal"> <Button
<Button Command="{Binding NewPipelineCommand}"
Command="{Binding NewPipelineCommand}" Content="新建"
Content="新建" Style="{StaticResource ToolbarBtn}"
Style="{StaticResource ToolbarBtn}" ToolTip="新建流水线" />
ToolTip="新建流水线" /> <Button
<Button Command="{Binding SavePipelineCommand}"
Command="{Binding SavePipelineCommand}" Content="保存"
Content="保存" Style="{StaticResource ToolbarBtn}"
Style="{StaticResource ToolbarBtn}" ToolTip="保存当前流水线" />
ToolTip="保存当前流水线" /> <Button
<Button Width="60"
Width="60" Command="{Binding SaveAsPipelineCommand}"
Command="{Binding SaveAsPipelineCommand}" Content="另存为"
Content="另存为" Style="{StaticResource ToolbarBtn}"
Style="{StaticResource ToolbarBtn}" ToolTip="另存当前流水线" />
ToolTip="另存当前流水线" /> <Button
<Button Width="52"
Width="52" Command="{Binding LoadPipelineCommand}"
Command="{Binding LoadPipelineCommand}" Content="加载"
Content="加载" Style="{StaticResource ToolbarBtn}"
Style="{StaticResource ToolbarBtn}" ToolTip="加载流水线" />
ToolTip="加载流水线" /> </StackPanel>
</StackPanel>
</Grid>
</Border> </Border>
<ListBox <ListBox
@@ -120,7 +118,6 @@
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="44" /> <ColumnDefinition Width="44" />
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Line <Line
@@ -176,54 +173,6 @@
Foreground="#6E6E6E" Foreground="#6E6E6E"
Text="已启用" /> Text="已启用" />
</StackPanel> </StackPanel>
<StackPanel
x:Name="NodeActions"
Grid.Column="2"
Margin="0,0,4,0"
VerticalAlignment="Center"
Orientation="Horizontal"
Visibility="Collapsed">
<Button
Width="22"
Height="22"
Margin="1,0"
Background="Transparent"
BorderBrush="#CDCBCB"
BorderThickness="1"
Command="{Binding DataContext.MoveNodeUpCommand, RelativeSource={RelativeSource AncestorType=ListBox}}"
CommandParameter="{Binding}"
Content="上"
Cursor="Hand"
FontSize="10"
ToolTip="上移" />
<Button
Width="22"
Height="22"
Margin="1,0"
Background="Transparent"
BorderBrush="#CDCBCB"
BorderThickness="1"
Command="{Binding DataContext.MoveNodeDownCommand, RelativeSource={RelativeSource AncestorType=ListBox}}"
CommandParameter="{Binding}"
Content="下"
Cursor="Hand"
FontSize="10"
ToolTip="下移" />
<Button
Width="22"
Height="22"
Margin="1,0"
Background="Transparent"
BorderBrush="#E05050"
BorderThickness="1"
Command="{Binding DataContext.RemoveOperatorCommand, RelativeSource={RelativeSource AncestorType=ListBox}}"
CommandParameter="{Binding}"
Content="删"
Cursor="Hand"
FontSize="10"
ToolTip="删除" />
</StackPanel>
</Grid> </Grid>
</Border> </Border>
<DataTemplate.Triggers> <DataTemplate.Triggers>
@@ -254,9 +203,6 @@
<Setter TargetName="NodeContainer" Property="BorderBrush" Value="#7E9AB6" /> <Setter TargetName="NodeContainer" Property="BorderBrush" Value="#7E9AB6" />
<Setter TargetName="NodeContainer" Property="Opacity" Value="1" /> <Setter TargetName="NodeContainer" Property="Opacity" Value="1" />
</MultiDataTrigger> </MultiDataTrigger>
<Trigger SourceName="NodeRoot" Property="IsMouseOver" Value="True">
<Setter TargetName="NodeActions" Property="Visibility" Value="Visible" />
</Trigger>
</DataTemplate.Triggers> </DataTemplate.Triggers>
</DataTemplate> </DataTemplate>
</ListBox.ItemTemplate> </ListBox.ItemTemplate>
@@ -5,6 +5,7 @@ using System.Windows.Controls;
using System.Windows.Controls.Primitives; using System.Windows.Controls.Primitives;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Threading;
using XP.Common.Logging.Interfaces; using XP.Common.Logging.Interfaces;
using XplorePlane.Models; using XplorePlane.Models;
using XplorePlane.ViewModels; using XplorePlane.ViewModels;
@@ -90,9 +91,14 @@ namespace XplorePlane.Views
} }
_isInternalDragging = true; _isInternalDragging = true;
_suppressClickToggle = true;
var data = new DataObject(PipelineNodeDragFormat, _draggedNode); var data = new DataObject(PipelineNodeDragFormat, _draggedNode);
DragDrop.DoDragDrop(PipelineListBox, data, DragDropEffects.Move); DragDrop.DoDragDrop(PipelineListBox, data, DragDropEffects.Move);
_suppressClickToggle = true; Dispatcher.BeginInvoke(new Action(() =>
{
_suppressClickToggle = false;
ResetDragState();
}), DispatcherPriority.Background);
} }
private void OnPreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e) private void OnPreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
@@ -195,29 +201,11 @@ namespace XplorePlane.Views
} }
var oldIndex = vm.PipelineNodes.IndexOf(draggedNode); var oldIndex = vm.PipelineNodes.IndexOf(draggedNode);
var targetIndex = GetDropTargetIndex(e.GetPosition(PipelineListBox)); var insertionIndex = GetDropInsertionIndex(e.GetPosition(PipelineListBox), vm.PipelineNodes.Count);
if (targetIndex < 0) var newIndex = insertionIndex > oldIndex ? insertionIndex - 1 : insertionIndex;
{ newIndex = Math.Max(0, Math.Min(newIndex, vm.PipelineNodes.Count - 1));
targetIndex = vm.PipelineNodes.Count - 1;
}
if (targetIndex >= oldIndex && targetIndex < vm.PipelineNodes.Count - 1) if (oldIndex == newIndex)
{
var targetItem = GetItemAtPosition(e.GetPosition(PipelineListBox));
if (targetItem != null)
{
var itemBounds = VisualTreeHelper.GetDescendantBounds(targetItem);
var itemTopLeft = targetItem.TranslatePoint(new Point(0, 0), PipelineListBox);
var itemMidY = itemTopLeft.Y + (itemBounds.Height / 2);
if (e.GetPosition(PipelineListBox).Y > itemMidY)
{
targetIndex = Math.Min(targetIndex + 1, vm.PipelineNodes.Count - 1);
}
}
}
targetIndex = Math.Max(0, Math.Min(targetIndex, vm.PipelineNodes.Count - 1));
if (oldIndex == targetIndex)
{ {
return; return;
} }
@@ -225,16 +213,27 @@ namespace XplorePlane.Views
vm.ReorderOperatorCommand.Execute(new PipelineReorderArgs vm.ReorderOperatorCommand.Execute(new PipelineReorderArgs
{ {
OldIndex = oldIndex, OldIndex = oldIndex,
NewIndex = targetIndex NewIndex = newIndex
}); });
} }
private int GetDropTargetIndex(Point position) private int GetDropInsertionIndex(Point position, int itemCount)
{ {
var item = GetItemAtPosition(position); var item = GetItemAtPosition(position);
return item == null if (item == null)
? -1 {
: PipelineListBox.ItemContainerGenerator.IndexFromContainer(item); return itemCount;
}
var targetIndex = PipelineListBox.ItemContainerGenerator.IndexFromContainer(item);
if (targetIndex < 0)
{
return itemCount;
}
var itemTop = item.TranslatePoint(new Point(0, 0), PipelineListBox).Y;
var itemMid = itemTop + (item.ActualHeight / 2);
return position.Y > itemMid ? targetIndex + 1 : targetIndex;
} }
private ListBoxItem GetItemAtPosition(Point position) private ListBoxItem GetItemAtPosition(Point position)
@@ -274,7 +273,12 @@ namespace XplorePlane.Views
var current = originalSource as DependencyObject; var current = originalSource as DependencyObject;
while (current != null) while (current != null)
{ {
if (current is ButtonBase || current is TextBoxBase || current is Selector || current is ScrollBar) if (current is ListBoxItem)
{
return false;
}
if (current is ButtonBase || current is TextBoxBase || current is ScrollBar)
{ {
return true; return true;
} }