#0025 新增加载按钮;修复线居中

This commit is contained in:
zhengxuan.zhang
2026-03-15 10:46:13 +08:00
parent 1cc4b5e4d0
commit 880cdfc937
4 changed files with 111 additions and 37 deletions
@@ -55,6 +55,7 @@ namespace XplorePlane.ViewModels
SavePipelineCommand = new DelegateCommand(async () => await SavePipelineAsync()); SavePipelineCommand = new DelegateCommand(async () => await SavePipelineAsync());
SaveAsPipelineCommand = new DelegateCommand(async () => await SaveAsPipelineAsync()); SaveAsPipelineCommand = new DelegateCommand(async () => await SaveAsPipelineAsync());
DeletePipelineCommand = new DelegateCommand(async () => await DeletePipelineAsync()); DeletePipelineCommand = new DelegateCommand(async () => await DeletePipelineAsync());
LoadPipelineCommand = new DelegateCommand(async () => await LoadPipelineAsync());
} }
// ── State Properties ────────────────────────────────────────── // ── State Properties ──────────────────────────────────────────
@@ -133,6 +134,7 @@ namespace XplorePlane.ViewModels
public DelegateCommand SavePipelineCommand { get; } public DelegateCommand SavePipelineCommand { get; }
public DelegateCommand SaveAsPipelineCommand { get; } public DelegateCommand SaveAsPipelineCommand { get; }
public DelegateCommand DeletePipelineCommand { get; } public DelegateCommand DeletePipelineCommand { get; }
public DelegateCommand LoadPipelineCommand { get; }
// ── Command Implementations ─────────────────────────────────── // ── Command Implementations ───────────────────────────────────
@@ -383,6 +385,58 @@ namespace XplorePlane.ViewModels
await Task.CompletedTask; await Task.CompletedTask;
} }
private async Task LoadPipelineAsync()
{
var dialog = new OpenFileDialog
{
Filter = "流水线文件 (*.pipeline.json)|*.pipeline.json",
InitialDirectory = GetPipelineDirectory()
};
if (dialog.ShowDialog() != true) return;
try
{
var model = await _persistenceService.LoadAsync(dialog.FileName);
PipelineNodes.Clear();
SelectedNode = null;
PipelineName = model.Name;
SelectedDevice = model.DeviceId;
_currentFilePath = dialog.FileName;
foreach (var nodeModel in model.Nodes)
{
var displayName = _imageProcessingService.GetProcessorDisplayName(nodeModel.OperatorKey)
?? nodeModel.OperatorKey;
var node = new PipelineNodeViewModel(nodeModel.OperatorKey, displayName)
{
Order = nodeModel.Order,
IsEnabled = nodeModel.IsEnabled
};
LoadNodeParameters(node);
// 恢复已保存的参数值
foreach (var param in node.Parameters)
{
if (nodeModel.Parameters.TryGetValue(param.Name, out var savedValue))
param.Value = savedValue;
}
PipelineNodes.Add(node);
}
Serilog.Log.Information("流水线已加载:{Name},节点数={Count}", model.Name, PipelineNodes.Count);
StatusMessage = $"已加载流水线:{model.Name}{PipelineNodes.Count} 个节点)";
}
catch (Exception ex)
{
Serilog.Log.Warning("加载流水线失败:{Error}", ex.Message);
StatusMessage = $"加载失败:{ex.Message}";
}
}
private PipelineModel BuildPipelineModel() private PipelineModel BuildPipelineModel()
{ {
return new PipelineModel return new PipelineModel
@@ -18,10 +18,13 @@ namespace XplorePlane.Views
private void OnLoaded(object sender, RoutedEventArgs e) private void OnLoaded(object sender, RoutedEventArgs e)
{ {
if (DataContext == null) var container = ContainerLocator.Current;
DataContext = ContainerLocator.Container.Resolve<ImageProcessingViewModel>(); if (container == null) return;
_imageProcessingService = ContainerLocator.Container.Resolve<IImageProcessingService>(); if (DataContext == null)
DataContext = container.Resolve<ImageProcessingViewModel>();
_imageProcessingService = container.Resolve<IImageProcessingService>();
} }
private void OnProcessorComboChanged(object sender, SelectionChangedEventArgs e) private void OnProcessorComboChanged(object sender, SelectionChangedEventArgs e)
@@ -1,11 +1,14 @@
<Window x:Class="XplorePlane.Views.ImageProcessingWindow" <Window
x:Class="XplorePlane.Views.ImageProcessingWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:views="clr-namespace:XplorePlane.Views" xmlns:views="clr-namespace:XplorePlane.Views"
Title="图像处理" Title="图像处理"
Width="1200" Height="750" Width="1200"
MinWidth="900" MinHeight="550" Height="750"
WindowStartupLocation="CenterOwner" MinWidth="900"
ShowInTaskbar="False"> MinHeight="550"
ShowInTaskbar="False"
WindowStartupLocation="CenterOwner">
<views:ImageProcessingPanelView /> <views:ImageProcessingPanelView />
</Window> </Window>
@@ -123,6 +123,11 @@
Content="另存为" Content="另存为"
Style="{StaticResource ToolbarBtn}" Style="{StaticResource ToolbarBtn}"
ToolTip="另存为" Width="43" /> ToolTip="另存为" Width="43" />
<Button
Command="{Binding LoadPipelineCommand}"
Content="加载"
Style="{StaticResource ToolbarBtn}"
ToolTip="加载流水线" Width="43" />
<Button <Button
Command="{Binding ExecutePipelineCommand}" Command="{Binding ExecutePipelineCommand}"
Content="▶" Content="▶"
@@ -156,38 +161,47 @@
ScrollViewer.HorizontalScrollBarVisibility="Disabled"> ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemTemplate> <ListBox.ItemTemplate>
<DataTemplate> <DataTemplate>
<Grid MinHeight="44"> <Grid MinHeight="48">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="28" /> <ColumnDefinition Width="44" />
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<!-- 竖线连接 + 节点方块 --> <!-- 连接线列:上半段 + 下半段 -->
<Grid Grid.Column="0"> <Line x:Name="TopLine"
Stroke="#5B9BD5" StrokeThickness="2"
X1="0" X2="0" Y1="0" Y2="10"
VerticalAlignment="Top"
HorizontalAlignment="Center" />
<Line Stroke="#5B9BD5" StrokeThickness="2" <Line Stroke="#5B9BD5" StrokeThickness="2"
X1="14" X2="14" Y1="0" Y2="44" X1="0" X2="0" Y1="0" Y2="14"
HorizontalAlignment="Left" /> VerticalAlignment="Bottom"
<Border Width="16" Height="16" HorizontalAlignment="Center" />
Background="White"
BorderBrush="#5B9BD5" BorderThickness="1.5"
CornerRadius="2"
VerticalAlignment="Center" HorizontalAlignment="Center" />
</Grid>
<!-- 节点行 --> <!-- 算子图标 -->
<Border Grid.Column="1" Padding="6,8"> <Border Grid.Column="0"
<StackPanel Orientation="Horizontal"> Width="28" Height="28"
<Border Width="28" Height="28" Margin="0,0,8,0" Background="#E8F0FE"
Background="#E8F0FE" CornerRadius="3"> BorderBrush="#5B9BD5" BorderThickness="1.5"
CornerRadius="4"
VerticalAlignment="Center"
HorizontalAlignment="Center">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center"
FontSize="13" Text="⚙" /> FontSize="13" Text="⚙" />
</Border> </Border>
<TextBlock VerticalAlignment="Center"
<!-- 算子名称 -->
<TextBlock Grid.Column="1"
VerticalAlignment="Center"
Margin="6,0,0,0"
FontFamily="Microsoft YaHei UI" FontSize="12" FontFamily="Microsoft YaHei UI" FontSize="12"
Text="{Binding DisplayName}" /> Text="{Binding DisplayName}" />
</StackPanel>
</Border>
</Grid> </Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Order}" Value="0">
<Setter TargetName="TopLine" Property="Visibility" Value="Collapsed" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate> </DataTemplate>
</ListBox.ItemTemplate> </ListBox.ItemTemplate>
</ListBox> </ListBox>