C#結(jié)合WPF實現(xiàn)審批流程圖繪制及后臺邏輯的示例詳解
更新時間:2025年07月31日 08:44:30 作者:code_shenbing
本文將通過完整示例演示如何利用WPF的圖形渲染能力與MVVM模式,構(gòu)建一個可交互的審批流程圖系統(tǒng),并實現(xiàn)審批狀態(tài)跟蹤與業(yè)務(wù)邏輯處理,需要的朋友可以參考下
一、架構(gòu)設(shè)計:MVVM模式下的審批系統(tǒng)

二、核心實現(xiàn):流程圖繪制引擎
1. 審批節(jié)點控件 (XAML)
<!-- ApprovalNodeControl.xaml -->
<ControlTemplate x:Key="NodeTemplate" TargetType="ContentControl">
<Grid>
<!-- 節(jié)點基礎(chǔ)圖形 -->
<Path Data="M 0,0 L 60,0 L 60,40 L 0,40 Z"
Fill="{Binding Status, Converter={StaticResource StatusToColorConverter}}"
Stroke="DarkGray">
<!-- 狀態(tài)指示燈 -->
<Path.Effect>
<DropShadowEffect Opacity="0.7" BlurRadius="8"
Color="{Binding Status, Converter={StaticResource StatusToShadowColor}}"/>
</Path.Effect>
</Path>
<!-- 節(jié)點內(nèi)容 -->
<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. 動態(tài)畫布管理器
public class FlowCanvasManager
{
private Canvas _canvas;
private List<ApprovalNodeControl> _nodes = new List<ApprovalNodeControl>();
// 添加新節(jié)點
public void AddNode(ApprovalNodeModel nodeModel)
{
var nodeControl = new ApprovalNodeControl(nodeModel);
Canvas.SetLeft(nodeControl, nodeModel.Position.X);
Canvas.SetTop(nodeControl, nodeModel.Position.Y);
// 實現(xiàn)拖拽
nodeControl.MouseMove += (s, e) => {
if (e.LeftButton == MouseButtonState.Pressed)
{
DragDrop.DoDragDrop(nodeControl, nodeModel, DragDropEffects.Move);
}
};
_canvas.Children.Add(nodeControl);
_nodes.Add(nodeControl);
}
// 連接節(jié)點
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)
};
}
}三、審批狀態(tài)機實現(xiàn)
1. 審批狀態(tài)與命令管理
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);
// 狀態(tài)更新邏輯
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;
}
}
}
// 狀態(tài)變更事件
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. 審批流程圖定義數(shù)據(jù)
// 審批流程定義
{
"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>
<!-- 流程圖畫布區(qū)域 -->
<ScrollViewer>
<Canvas x:Name="MainCanvas" Width="800" Height="600"
Background="#FFF5F5F5">
<!-- 通過ItemsControl動態(tài)綁定節(jié)點 -->
<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>五、高級功能實現(xiàn)技巧
1. 可視化狀態(tài)跟蹤
// 狀態(tài)變更通知
public class ApprovalNodeModel : INotifyPropertyChanged
{
private ApprovalStatus _status;
public ApprovalStatus Status
{
get => _status;
set
{
_status = value;
OnPropertyChanged();
// 狀態(tài)變更自動記錄審計日志
AuditService.Log($"{NodeName}狀態(tài)變更為{value}");
}
}
}2. 審批規(guī)則引擎擴展
// 條件審批示例
public void ApplyApprovalRules()
{
var expenseAmount = GetCurrentExpenseAmount();
if (expenseAmount > 5000)
{
// 自動添加財務(wù)總監(jiān)節(jié)點
AddApprovalNode("財務(wù)總監(jiān)審批", NodeType.Approval);
}
else if(expenseAmount > 10000)
{
// 發(fā)起加簽流程
RequestAdditionalApproval();
}
}3. 流程圖序列化保存
public void SaveFlowDiagram()
{
// 生成流程圖結(jié)構(gòu)數(shù)據(jù)
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);
}
}六、性能優(yōu)化建議
??圖形渲染優(yōu)化??:
// 啟用GPU加速 RenderOptions.SetBitmapScalingMode(canvas, BitmapScalingMode.HighQuality); RenderOptions.SetEdgeMode(canvas, EdgeMode.Aliased);
??大數(shù)據(jù)量處理??:
// 虛擬化容器
<ItemsControl VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Recycling">??增量刷新策略??:
// 僅刷新變更節(jié)點
foreach (var changedNode in _stateMachine.GetChangedNodes())
{
UpdateNodeVisual(changedNode);
}WPF實現(xiàn)審批系統(tǒng)的優(yōu)勢
- ??聲明式UI開發(fā)??:XAML數(shù)據(jù)綁定顯著提升UI開發(fā)效率
- ??強大的圖形能力??:支持復(fù)雜流程圖、動畫效果、可視化狀態(tài)反饋
- ??完善的MVVM支持??:業(yè)務(wù)邏輯與UI解耦,提升可測試性
- ??企業(yè)級集成能力??:輕松對接WCF/Web API等后端服務(wù)
- ??桌面端性能優(yōu)勢??:相比Web技術(shù)有更流暢的用戶體驗
通過本示例可以看到,結(jié)合WPF與C#可構(gòu)建專業(yè)級的審批工作流系統(tǒng)。核心在于靈活運用:
- 自定義控件實現(xiàn)可視化元素
- 狀態(tài)機管理審批流程
- MVVM模式保持架構(gòu)清晰
- 命令模式處理用戶交互
實際項目中可擴展會簽/或簽、委托審批、電子簽名等企業(yè)級功能,打造完整的BPM解決方案。
- 流程設(shè)計器(拖拽創(chuàng)建節(jié)點)
- 審批規(guī)則配置界面
- 流程圖導(dǎo)出為PNG/PDF
- 審批歷史跟蹤時間線
- 多語言本地化支持
以上就是C#結(jié)合WPF實現(xiàn)審批流程圖繪制及后臺邏輯的示例詳解的詳細(xì)內(nèi)容,更多關(guān)于C# WPF審批流程圖的資料請關(guān)注腳本之家其它相關(guān)文章!
C#實現(xiàn)讀取USB轉(zhuǎn)串口參數(shù)并顯示在ComboBox
在很多應(yīng)用程序中,尤其是那些需要與外部硬件通信的程序中,自動檢測和讀取串口參數(shù)是一個非常有用的功能,下面我們就來看看如何在C#中實現(xiàn)這一功能吧
2024-01-01
C#基于正則表達(dá)式刪除字符串中數(shù)字或非數(shù)字的方法
這篇文章主要介紹了C#基于正則表達(dá)式刪除字符串中數(shù)字或非數(shù)字的方法,涉及C#針對數(shù)字的簡單正則匹配相關(guān)操作技巧,需要的朋友可以參考下
2017-06-06 
