C#教程

关注公众号 jb51net

关闭
首页 > 软件编程 > C#教程 > C# WPF审批流程图

C#结合WPF实现审批流程图绘制及后台逻辑的示例详解

作者:code_shenbing

本文将通过完整示例演示如何利用WPF的图形渲染能力与MVVM模式,构建一个可交互的审批流程图系统,并实现审批状态跟踪与业务逻辑处理,需要的朋友可以参考下

一、架构设计:MVVM模式下的审批系统

二、核心实现:流程图绘制引擎

1. 审批节点控件 (XAML)

<!-- ApprovalNodeControl.xaml -->
<ControlTemplate x:Key="NodeTemplate" TargetType="ContentControl">
    <Grid>
        <!-- 节点基础图形 -->
        <Path Data="M 0,0 L 60,0 L 60,40 L 0,40 Z" 
              Fill="{Binding Status, Converter={StaticResource StatusToColorConverter}}"
              Stroke="DarkGray">
            <!-- 状态指示灯 -->
            <Path.Effect>
                <DropShadowEffect Opacity="0.7" BlurRadius="8" 
                                  Color="{Binding Status, Converter={StaticResource StatusToShadowColor}}"/>
            </Path.Effect>
        </Path>
        
        <!-- 节点内容 -->
        <StackPanel VerticalAlignment="Center" Margin="10">
            <TextBlock Text="{Binding NodeName}" FontWeight="Bold" HorizontalAlignment="Center"/>
            <TextBlock Text="{Binding Approvers}" 
                       TextTrimming="CharacterEllipsis" MaxWidth="50"/>
        </StackPanel>
        
        <!-- 连接锚点 -->
        <Ellipse Width="10" Height="10" Fill="Blue" 
                 Canvas.Left="55" Canvas.Top="17"
                 Visibility="{Binding ShowAnchor, Converter={StaticResource BoolToVisibility}}"/>
    </Grid>
</ControlTemplate>

2. 动态画布管理器

public class FlowCanvasManager
{
    private Canvas _canvas;
    private List<ApprovalNodeControl> _nodes = new List<ApprovalNodeControl>();
 
    // 添加新节点
    public void AddNode(ApprovalNodeModel nodeModel)
    {
        var nodeControl = new ApprovalNodeControl(nodeModel);
        Canvas.SetLeft(nodeControl, nodeModel.Position.X);
        Canvas.SetTop(nodeControl, nodeModel.Position.Y);
        
        // 实现拖拽
        nodeControl.MouseMove += (s, e) => {
            if (e.LeftButton == MouseButtonState.Pressed) 
            {
                DragDrop.DoDragDrop(nodeControl, nodeModel, DragDropEffects.Move);
            }
        };
 
        _canvas.Children.Add(nodeControl);
        _nodes.Add(nodeControl);
    }
 
    // 连接节点
    public void ConnectNodes(ApprovalNodeModel from, ApprovalNodeModel to)
    {
        var connector = new Polyline {
            Stroke = Brushes.Gray,
            StrokeThickness = 2,
            Points = CalculateConnectionPoints(from, to)
        };
        _canvas.Children.Add(connector);
    }
 
    private PointCollection CalculateConnectionPoints(ApprovalNodeModel from, ApprovalNodeModel to)
    {
        return new PointCollection {
            new Point(from.Position.X + 55, from.Position.Y + 20),
            new Point(to.Position.X + 5, to.Position.Y + 20)
        };
    }
}

三、审批状态机实现

1. 审批状态与命令管理

public enum ApprovalStatus { Pending, Approved, Rejected, Completed }
 
public class ApprovalStateMachine
{
    private readonly ApprovalFlowModel _flow;
 
    public void ProcessNode(Guid nodeId, bool isApproved)
    {
        var node = _flow.Nodes.First(n => n.Id == nodeId);
        
        // 状态更新逻辑
        node.Status = isApproved ? ApprovalStatus.Approved : ApprovalStatus.Rejected;
        
        // 自动推进逻辑
        if (isApproved && node.Type == NodeType.Final) 
        {
            _flow.Status = ApprovalStatus.Completed;
            ApprovalCompleted?.Invoke(this, EventArgs.Empty);
        }
        else if (!isApproved)
        {
            RollbackToPreviousNode(nodeId);
        }
    }
 
    private void RollbackToPreviousNode(Guid currentNodeId)
    {
        // 回溯算法示例
        var currentIndex = _flow.Nodes.IndexOf(
            _flow.Nodes.First(n => n.Id == currentNodeId));
        
        for (int i = currentIndex - 1; i >= 0; i--)
        {
            if (_flow.Nodes[i].Status == ApprovalStatus.Approved)
            {
                _flow.Nodes[i].Status = ApprovalStatus.Pending;
                RollbackOccurred?.Invoke(this, i);
                break;
            }
        }
    }
    
    // 状态变更事件
    public event EventHandler<int> RollbackOccurred;
    public event EventHandler ApprovalCompleted;
}

2. 基于命令模式的审批操作

public class ProcessApprovalCommand : ICommand
{
    private readonly ApprovalStateMachine _stateMachine;
    
    public ProcessApprovalCommand(ApprovalStateMachine stateMachine) => 
        _stateMachine = stateMachine;
 
    public bool CanExecute(object parameter) => 
        (parameter as ApprovalNodeModel)?.Status == ApprovalStatus.Pending;
 
    public void Execute(object parameter)
    {
        if (parameter is ApprovalNodeModel node)
        {
            var dialog = new ApprovalDialog("审批操作");
            if (dialog.ShowDialog() == true)
            {
                _stateMachine.ProcessNode(node.Id, dialog.IsApproved);
            }
        }
    }
 
    public event EventHandler CanExecuteChanged;
}

四、UI与后台 完整交互示例

1. 审批流程图定义数据

// 审批流程定义
{
  "FlowName": "员工报销流程",
  "Nodes": [
    {
      "Id": "node1",
      "NodeName": "提交报销",
      "Type": "Start",
      "Approvers": ["申请人"],
      "Position": { "X": 50, "Y": 100 }
    },
    {
      "Id": "node2",
      "NodeName": "部门审批",
      "Type": "Approval",
      "Approvers": ["部门主管"],
      "Position": { "X": 250, "Y": 100 }
    }
  ],
  "Connections": [
    {"From": "node1", "To": "node2"}
  ]
}

2. 主窗口MVVM绑定

<Window>
    <!-- 流程图画布区域 -->
    <ScrollViewer>
        <Canvas x:Name="MainCanvas" Width="800" Height="600" 
                Background="#FFF5F5F5">
            <!-- 通过ItemsControl动态绑定节点 -->
            <ItemsControl ItemsSource="{Binding Flow.Nodes}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <Canvas />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <local:ApprovalNodeControl />
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </Canvas>
    </ScrollViewer>
    
    <!-- 审批操作面板 -->
    <StackPanel Grid.Column="1">
        <Button Content="同意" 
                Command="{Binding ApproveCommand}" 
                CommandParameter="{Binding SelectedNode}"/>
                
        <Button Content="驳回" 
                Command="{Binding RejectCommand}"
                CommandParameter="{Binding SelectedNode}"/>
                
        <TextBlock Text="{Binding SelectedNode.Status}" />
    </StackPanel>
</Window>

五、高级功能实现技巧

1. 可视化状态跟踪

// 状态变更通知
public class ApprovalNodeModel : INotifyPropertyChanged
{
    private ApprovalStatus _status;
    public ApprovalStatus Status
    {
        get => _status;
        set
        {
            _status = value;
            OnPropertyChanged();
            
            // 状态变更自动记录审计日志
            AuditService.Log($"{NodeName}状态变更为{value}");
        }
    }
}

2. 审批规则引擎扩展

// 条件审批示例
public void ApplyApprovalRules()
{
    var expenseAmount = GetCurrentExpenseAmount();
    
    if (expenseAmount > 5000)
    {
        // 自动添加财务总监节点
        AddApprovalNode("财务总监审批", NodeType.Approval); 
    }
    else if(expenseAmount > 10000)
    {
        // 发起加签流程
        RequestAdditionalApproval(); 
    }
}

3. 流程图序列化保存

public void SaveFlowDiagram()
{
    // 生成流程图结构数据
    var flowData = new FlowSchema {
        Nodes = _nodes.Select(n => n.Model).ToList(),
        Connections = FindAllConnections()
    };
    
    // 序列化为XML
    var serializer = new XmlSerializer(typeof(FlowSchema));
    using (var writer = new StreamWriter("flow.xml"))
    {
        serializer.Serialize(writer, flowData);
    }
}

六、性能优化建议

​图形渲染优化​​:

// 启用GPU加速
RenderOptions.SetBitmapScalingMode(canvas, BitmapScalingMode.HighQuality);
RenderOptions.SetEdgeMode(canvas, EdgeMode.Aliased);

​大数据量处理​​:

// 虚拟化容器
<ItemsControl VirtualizingStackPanel.IsVirtualizing="True"
              VirtualizingStackPanel.VirtualizationMode="Recycling">

​增量刷新策略​​:

// 仅刷新变更节点
foreach (var changedNode in _stateMachine.GetChangedNodes())
{
    UpdateNodeVisual(changedNode);
}

WPF实现审批系统的优势

  1. ​声明式UI开发​​:XAML数据绑定显著提升UI开发效率
  2. ​强大的图形能力​​:支持复杂流程图、动画效果、可视化状态反馈
  3. ​完善的MVVM支持​​:业务逻辑与UI解耦,提升可测试性
  4. ​企业级集成能力​​:轻松对接WCF/Web API等后端服务
  5. ​桌面端性能优势​​:相比Web技术有更流畅的用户体验

通过本示例可以看到,结合WPF与C#可构建专业级的审批工作流系统。核心在于灵活运用:

实际项目中可扩展会签/或签、委托审批、电子签名等企业级功能,打造完整的BPM解决方案。

  • 流程设计器(拖拽创建节点)
  • 审批规则配置界面
  • 流程图导出为PNG/PDF
  • 审批历史跟踪时间线
  • 多语言本地化支持

以上就是C#结合WPF实现审批流程图绘制及后台逻辑的示例详解的详细内容,更多关于C# WPF审批流程图的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文