B站朝夕教育 【.NET9.0+WPF实战三类流程化业务逻辑控制】学习记录 【八】
播放地址:20241120-.NET9.0+WPF实战三类流程化业务逻辑控制-10_哔哩哔哩_bilibili
第20-23节 对两个控件中间增加连线,并且移动控件可以让线跟着移动
主要思路是对拖动的控件增加状态判断,nodetype=1为线,nodetype=0为元素在MainView.xaml文件中判断展示
nodemodel中增加连入线和连出线的记录
当右键点击一个元素时设置记录这个元素作为线的进线控件
当在另一个元素上放开右键时,判断是否有进线控件,有的话创建线控件并添加到ProcessList里
并调整Node_MouseMove方法增加判断
详见代码
1 using System.Collections.ObjectModel; 2 using System.Windows.Controls; 3 using System.Windows.Input; 4 using System.Windows; 5 using CommunityToolkit.Mvvm.Input; 6 using System.Reflection; 7 8 namespace WpfApp2 9 { 10 public partial class MainViewModel 11 { 12 public ObservableCollection<NodeModel> ProcessList { get; set; } = new ObservableCollection<NodeModel>(); 13 14 public void ListViewItem_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 15 { 16 DragDrop.DoDragDrop((DependencyObject)sender, (sender as ListViewItem).Tag, DragDropEffects.Copy); 17 } 18 19 public void ListBox_Drop(object sender, DragEventArgs e) 20 { 21 string tag = e.Data.GetData(typeof(string)).ToString(); 22 var point = e.GetPosition((IInputElement)sender); 23 //反射 24 //根据字符串获取类型 25 Type type = Assembly.GetEntryAssembly().GetType("WpfApp2." + tag); 26 //根据类型创建实例 27 NodeModel instance = (NodeModel)Activator.CreateInstance(type); 28 instance.X=point.X-60; 29 instance.Y=point.Y-15; 30 ProcessList.Add(instance); 31 } 32 bool is_moving = false; 33 Point old_point = new Point(); 34 public void Node_MouseLeftButtonDown(object obj, MouseButtonEventArgs e) 35 { 36 is_moving = true; 37 old_point = e.GetPosition((IInputElement)obj); 38 Mouse.Capture((IInputElement)obj); 39 } 40 public void Node_MouseLeftButtonUp(object obj, MouseButtonEventArgs e) 41 { 42 is_moving = false; 43 Mouse.Capture(null); 44 } 45 public void Node_MouseMove(object sender, MouseEventArgs e) 46 { 47 if (is_moving) 48 { 49 var new_point = e.GetPosition((IInputElement)sender); 50 var node_model=(sender as FrameworkElement).DataContext as NodeModel; 51 node_model.X += new_point.X- old_point.X; 52 node_model.Y+= new_point.Y - old_point.Y; 53 if (node_model.OutputLine != null) 54 { 55 node_model.OutputLine.X1 = node_model.X+60; 56 if (node_model.Y > node_model.OutputLine.Y2) 57 { 58 node_model.OutputLine.Y1 = node_model.Y; 59 } 60 else 61 { 62 node_model.OutputLine.Y1 = node_model.Y + 30; 63 } 64 } 65 if (node_model.InputLine != null) 66 { 67 node_model.InputLine.X2 = node_model.X+60; 68 69 if (node_model.Y > node_model.InputLine.Y2) 70 { 71 node_model.InputLine.Y2 = node_model.Y; 72 } 73 else 74 { 75 node_model.InputLine.Y2 = node_model.Y+30; 76 } 77 } 78 } 79 } 80 81 NodeModel nm = null; 82 public void Node_MouseRightButtonDown(object obj, MouseButtonEventArgs e) 83 { 84 nm = (obj as FrameworkElement).DataContext as NodeModel; 85 } 86 public void Node_MouseRightButtonUp(object obj, MouseButtonEventArgs e) 87 { 88 //var point = e.GetPosition((IInputElement)obj); 89 var nowmodel = (obj as FrameworkElement).DataContext as NodeModel; 90 if (nm != null) 91 { 92 LineModel lm = null; 93 if (nm.Y > nowmodel.Y) 94 { 95 lm = new LineModel() { NodeType = 1, X1 = nm.X + 60, Y1 = nm.Y, X2 = nowmodel.X + 60, Y2 = nowmodel.Y + 30 }; 96 } 97 else 98 { 99 lm = new LineModel() { NodeType = 1, X1 = nm.X + 60, Y1 = nm.Y + 30, X2 = nowmodel.X + 60, Y2 = nowmodel.Y }; 100 } 101 102 ProcessList.Add(lm); 103 nowmodel.InputLine = lm; 104 nm.OutputLine = lm; 105 nm = null; 106 } 107 } 108 109 [RelayCommand] 110 private void Execute() 111 { 112 foreach (var item in ProcessList) 113 { 114 item.Execute(); 115 } 116 } 117 } 118 }
1 <Window x:Class="WpfApp2.MainView" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 xmlns:local="clr-namespace:WpfApp2" xmlns:i="http://schemas.microsoft.com/xaml/behaviors" 7 mc:Ignorable="d" 8 WindowStartupLocation="CenterScreen" 9 Background="White" 10 Title="MainView" Height="650" Width="1300"> 11 <Grid> 12 <Grid.RowDefinitions> 13 <RowDefinition Height="Auto" /> 14 <RowDefinition /> 15 </Grid.RowDefinitions> 16 <Grid.ColumnDefinitions> 17 <ColumnDefinition Width="200" /> 18 <ColumnDefinition Width="300" /> 19 <ColumnDefinition /> 20 </Grid.ColumnDefinitions> 21 <Button Content="执行" HorizontalAlignment="Stretch" Margin="3" Command="{Binding ExecuteCommand}" /> 22 <TextBlock Text="循序流程" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock> 23 <TextBlock Text="流程图控制" Grid.Column="2" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock> 24 <ListView Grid.Row="1" Grid.Column="0"> 25 <ListViewItem Content="AAA" Tag="ProcessA"> 26 <i:Interaction.Triggers> 27 <i:EventTrigger EventName="PreviewMouseLeftButtonDown"> 28 <i:CallMethodAction MethodName="ListViewItem_MouseLeftButtonDown" TargetObject="{Binding}" /> 29 </i:EventTrigger> 30 </i:Interaction.Triggers> 31 </ListViewItem> 32 <ListViewItem Content="BBB" Tag="ProcessB"> 33 <i:Interaction.Triggers> 34 <i:EventTrigger EventName="PreviewMouseLeftButtonDown"> 35 <i:CallMethodAction MethodName="ListViewItem_MouseLeftButtonDown" TargetObject="{Binding}" /> 36 </i:EventTrigger> 37 </i:Interaction.Triggers></ListViewItem> 38 <ListViewItem Content="CCC" Tag="ProcessC"> 39 <i:Interaction.Triggers> 40 <i:EventTrigger EventName="PreviewMouseLeftButtonDown"> 41 <i:CallMethodAction MethodName="ListViewItem_MouseLeftButtonDown" TargetObject="{Binding}" /> 42 </i:EventTrigger> 43 </i:Interaction.Triggers></ListViewItem> 44 <ListViewItem Content="DDD" Tag="ProcessD"> 45 <i:Interaction.Triggers> 46 <i:EventTrigger EventName="PreviewMouseLeftButtonDown"> 47 <i:CallMethodAction MethodName="ListViewItem_MouseLeftButtonDown" TargetObject="{Binding}" /> 48 </i:EventTrigger> 49 </i:Interaction.Triggers></ListViewItem> 50 </ListView> 51 <ListBox Grid.Row="1" Grid.Column="1" AllowDrop="True" ItemsSource="{Binding ProcessList}"> 52 <i:Interaction.Triggers> 53 <i:EventTrigger EventName="Drop"> 54 <i:CallMethodAction MethodName="ListBox_Drop" TargetObject="{Binding}" /> 55 </i:EventTrigger> 56 </i:Interaction.Triggers> 57 <ListBox.ItemTemplate> 58 <DataTemplate> 59 <TextBlock Text="{Binding Name}"> 60 </TextBlock> 61 </DataTemplate> 62 </ListBox.ItemTemplate> 63 </ListBox> 64 <ItemsControl Grid.Row="1" Grid.Column="2" Background="Transparent" AllowDrop="true" ItemsSource="{Binding ProcessList}"> 65 <i:Interaction.Triggers> 66 <i:EventTrigger EventName="Drop"> 67 <i:CallMethodAction MethodName="ListBox_Drop" TargetObject="{Binding}" /> 68 </i:EventTrigger> 69 </i:Interaction.Triggers> 70 <ItemsControl.ItemsPanel> 71 <ItemsPanelTemplate> 72 <Canvas Background="AliceBlue" /> 73 </ItemsPanelTemplate> 74 </ItemsControl.ItemsPanel> 75 <ItemsControl.ItemContainerStyle> 76 <Style TargetType="ContentPresenter"> 77 <Setter Property="Canvas.Left" Value="{Binding X}"/> 78 <Setter Property="Canvas.Top" Value="{Binding Y}"/> 79 </Style> 80 </ItemsControl.ItemContainerStyle> 81 82 <ItemsControl.ItemTemplate> 83 <DataTemplate> 84 <Grid> 85 <Border Width="120" Height="30" Background="White" CornerRadius="5" Name="border"> 86 <Border.Effect> 87 <DropShadowEffect Color="Gray" ShadowDepth="0" BlurRadius="5" Opacity="0.2" /> 88 </Border.Effect> 89 <i:Interaction.Triggers> 90 <i:EventTrigger EventName="MouseLeftButtonDown"> 91 <i:CallMethodAction MethodName="Node_MouseLeftButtonDown" TargetObject="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=DataContext}" /> 92 </i:EventTrigger> 93 <i:EventTrigger EventName="MouseLeftButtonUp"> 94 <i:CallMethodAction MethodName="Node_MouseLeftButtonUp" TargetObject="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=DataContext}" /> 95 </i:EventTrigger> 96 <i:EventTrigger EventName="MouseMove"> 97 <i:CallMethodAction MethodName="Node_MouseMove" TargetObject="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=DataContext}" /> 98 </i:EventTrigger> 99 <i:EventTrigger EventName="MouseRightButtonDown"> 100 <i:CallMethodAction MethodName="Node_MouseRightButtonDown" TargetObject="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=DataContext}" /> 101 </i:EventTrigger> 102 <i:EventTrigger EventName="MouseRightButtonUp"> 103 <i:CallMethodAction MethodName="Node_MouseRightButtonUp" TargetObject="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=DataContext}" /> 104 </i:EventTrigger> 105 </i:Interaction.Triggers> 106 <TextBlock Text="{Binding Name}" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock> 107 </Border> 108 <Line X1="{Binding X1}" Y1="{Binding Y1}" X2="{Binding X2}" Y2="{Binding Y2}" Stroke="Green" StrokeThickness="2" Name="line" Visibility="Collapsed" /> 109 </Grid> 110 <DataTemplate.Triggers> 111 <DataTrigger Binding="{Binding NodeType}" Value="1" > 112 <Setter TargetName="border" Property="Visibility" Value="Collapsed" /> 113 <Setter TargetName="line" Property="Visibility" Value="Visible" /> 114 </DataTrigger> 115 </DataTemplate.Triggers> 116 </DataTemplate> 117 </ItemsControl.ItemTemplate> 118 </ItemsControl> 119 </Grid> 120 </Window>
LineModel 代码
1 public class LineModel : NodeModel 2 { 3 public override string Name { get; set; } 4 private double x1; 5 public double X1 { get { return x1; } set => SetProperty(ref x1, value); } 6 private double y1; 7 public double Y1 { get { return y1; } set => SetProperty(ref y1, value); } 8 private double x2; 9 public double X2 { get { return x2; } set => SetProperty(ref x2, value); } 10 private double y2; 11 public double Y2 { get { return y2; } set => SetProperty(ref y2, value); } 12 public override void Execute(){ 13 } 14 }

浙公网安备 33010602011771号