FlowchartEditor完成

This commit is contained in:
艾竹
2022-12-02 23:06:31 +08:00
parent 1abeefcc66
commit dc42f75610
23 changed files with 1336 additions and 65 deletions

View File

@@ -12,4 +12,11 @@
<ProjectReference Include="..\AIStudio.Wpf.DiagramHelper\AIStudio.Wpf.DiagramHelper.csproj" />
</ItemGroup>
<ItemGroup>
<Page Update="Controls\ToolBoxControl.xaml">
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
<SubType>Designer</SubType>
</Page>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,98 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:AIStudio.Wpf.Flowchart.Controls"
xmlns:dd="https://gitee.com/akwkevin/aistudio.-wpf.-diagram">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.Flowchart;component/Themes/FlowNode.xaml"/>
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.DiagramHelper;component/Controls/ComboBox.xaml" />
</ResourceDictionary.MergedDictionaries>
<Style x:Key="AIStudio.Styles.FlowchartEditor" TargetType="{x:Type controls:FlowchartEditor}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type controls:FlowchartEditor}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<!-- ToolBox Control -->
<ContentControl Template="{Binding ToolBox,RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"/>
<!-- Diagram Control -->
<dd:DiagramControl Grid.Column="1" x:Name="PART_DiagramControl" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<ContentControl Grid.Column="2" x:Name="properity" Template="{Binding PropertiesBox,RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="AIStudio.Styles.FlowchartEditor.Default" TargetType="{x:Type controls:FlowchartEditor}" BasedOn="{StaticResource AIStudio.Styles.FlowchartEditor}">
<Setter Property="ToolBox">
<Setter.Value>
<ControlTemplate TargetType="Control">
<controls:ToolBoxControl />
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="PropertiesBox">
<Setter.Value>
<ControlTemplate TargetType="Control">
<dd:PropertiesView CustomSetting="True"
SelectedObject="{Binding Path=SelectedObject,RelativeSource={RelativeSource AncestorType={x:Type controls:FlowchartEditor}}}"
Width="200">
<dd:PropertiesView.Resources>
<Style x:Key="ActTypeStyle" TargetType="{x:Type ContentControl}">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Grid DataContext="{Binding Path=DataContext,RelativeSource={RelativeSource AncestorType={x:Type ContentControl}}}">
<ComboBox BorderThickness="0" Text="{Binding ActType}" Style="{StaticResource ComboBoxStyle}">
<ComboBoxItem Content="or"/>
<ComboBoxItem Content="and"/>
</ComboBox>
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="UserIdsStyle" TargetType="{x:Type ContentControl}">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Grid DataContext="{Binding Path=DataContext,RelativeSource={RelativeSource AncestorType={x:Type ContentControl}}}">
<dd:MultiSelectComboBox BorderThickness="0" DisplayMemberPath="text" SelectedValuePath="value"
SelectedValues="{Binding UserIds}"
ItemsSource="{Binding Path=Users,RelativeSource={RelativeSource AncestorType={x:Type controls:FlowchartEditor}}}" ></dd:MultiSelectComboBox>
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="RoleIdsStyle" TargetType="{x:Type ContentControl}">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Grid DataContext="{Binding Path=DataContext,RelativeSource={RelativeSource AncestorType={x:Type ContentControl}}}">
<dd:MultiSelectComboBox BorderThickness="0" DisplayMemberPath="text" SelectedValuePath="value"
SelectedValues="{Binding RoleIds}"
ItemsSource="{Binding Path=Roles,RelativeSource={RelativeSource AncestorType={x:Type controls:FlowchartEditor}}}"></dd:MultiSelectComboBox>
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</dd:PropertiesView.Resources>
</dd:PropertiesView>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type controls:FlowchartEditor}" BasedOn="{StaticResource AIStudio.Styles.FlowchartEditor.Default}" />
</ResourceDictionary>

View File

@@ -0,0 +1,211 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using AIStudio.Wpf.DiagramDesigner;
using AIStudio.Wpf.Flowchart.Models;
using AIStudio.Wpf.Flowchart.ViewModels;
namespace AIStudio.Wpf.Flowchart.Controls
{
/// <summary>
/// FlowchartEditor.xaml 的交互逻辑
/// </summary>
[TemplatePart(Name = PART_DiagramControl, Type = typeof(DiagramControl))]
public partial class FlowchartEditor : UserControl
{
public const string PART_DiagramControl = "PART_DiagramControl";
private DiagramControl _diagramControl;
private IDiagramServiceProvider _service
{
get
{
return DiagramServicesProvider.Instance.Provider;
}
}
private DiagramViewModel _diagramViewModel = new DiagramViewModel()
{
ShowGrid = true,
GridCellSize = new Size(100, 60),
GridMargin = 0d,
CellHorizontalAlignment = CellHorizontalAlignment.Center,
CellVerticalAlignment = CellVerticalAlignment.Center,
PageSizeType = PageSizeType.Custom,
PageSize = new Size(double.NaN, double.NaN),
};
static FlowchartEditor()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(FlowchartEditor), new FrameworkPropertyMetadata(typeof(FlowchartEditor)));
}
public FlowchartEditor()
{
_diagramViewModel.PropertyChanged += DiagramViewModel_PropertyChanged;
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
_diagramControl = GetTemplateChild(PART_DiagramControl) as DiagramControl;
_diagramControl.HorizontalAlignment = HorizontalAlignment.Stretch;
_diagramControl.VerticalAlignment = VerticalAlignment.Stretch;
_diagramControl.DataContext = _diagramViewModel;
}
private void DiagramViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "IsSelected")
{
SelectedObject = _diagramViewModel.SelectedItems?.FirstOrDefault();
}
}
//一点要绑定不为空的FlowchartModel才能用即便为空的也要new一个再来绑定
public static readonly DependencyProperty FlowchartModelProperty =
DependencyProperty.Register(nameof(FlowchartModel),
typeof(FlowchartModel),
typeof(FlowchartEditor),
new FrameworkPropertyMetadata(null, OnFlowchartModelChanged));
public FlowchartModel FlowchartModel
{
get
{
return (FlowchartModel)GetValue(FlowchartModelProperty);
}
set
{
SetValue(FlowchartModelProperty, value);
}
}
private static void OnFlowchartModelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var view = d as FlowchartEditor;
var model = e.NewValue as FlowchartModel;
if (model != null)
{
view.CreateFlowchartModel(model);
}
}
private void CreateFlowchartModel(FlowchartModel model)
{
_service.DrawModeViewModel.VectorLineDrawMode = DrawMode.BoundaryConnectingLine;
_diagramViewModel.Items.Clear();
if (model != null)
{
foreach (var node in model.Nodes)
{
_diagramViewModel.DirectAddItemCommand.Execute(node);
}
foreach (var link in model.Links)
{
_diagramViewModel.DirectAddItemCommand.Execute(link);
}
}
}
#region ToolBox
/// <summary>
/// 附加组件模板
/// </summary>
public static readonly DependencyProperty ToolBoxProperty = DependencyProperty.Register(
nameof(ToolBox), typeof(ControlTemplate), typeof(FlowchartEditor), new FrameworkPropertyMetadata(default(ControlTemplate)));
public ControlTemplate ToolBox
{
get
{
return (ControlTemplate)GetValue(ToolBoxProperty);
}
set
{
SetValue(ToolBoxProperty, value);
}
}
#endregion
#region ToolBox
/// <summary>
/// 附加组件模板
/// </summary>
public static readonly DependencyProperty PropertiesBoxProperty = DependencyProperty.Register(
nameof(PropertiesBox), typeof(ControlTemplate), typeof(FlowchartEditor), new FrameworkPropertyMetadata(default(ControlTemplate)));
public ControlTemplate PropertiesBox
{
get
{
return (ControlTemplate)GetValue(PropertiesBoxProperty);
}
set
{
SetValue(PropertiesBoxProperty, value);
}
}
#endregion
#region SelectedObject
public static readonly DependencyProperty SelectedObjectProperty = DependencyProperty.Register(nameof(SelectedObject), typeof(object), typeof(FlowchartEditor), new UIPropertyMetadata(default(object)));
public object SelectedObject
{
get
{
return (object)GetValue(SelectedObjectProperty);
}
set
{
SetValue(SelectedObjectProperty, value);
}
}
#endregion
#region Users
public static readonly DependencyProperty UsersProperty
= DependencyProperty.Register(nameof(Users), typeof(List<SelectOption>), typeof(FlowchartEditor), new UIPropertyMetadata(default(List<SelectOption>)));
public List<SelectOption> Users
{
get
{
return (List<SelectOption>)GetValue(UsersProperty);
}
set
{
SetValue(UsersProperty, value);
}
}
#endregion
#region Roles
public static readonly DependencyProperty RolesProperty
= DependencyProperty.Register(nameof(Roles), typeof(List<SelectOption>), typeof(FlowchartEditor), new UIPropertyMetadata(default(List<SelectOption>)));
public List<SelectOption> Roles
{
get
{
return (List<SelectOption>)GetValue(RolesProperty);
}
set
{
SetValue(RolesProperty, value);
}
}
#endregion
}
}

View File

@@ -0,0 +1,72 @@
<UserControl x:Class="AIStudio.Wpf.Flowchart.Controls.ToolBoxControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dd="https://gitee.com/akwkevin/aistudio.-wpf.-diagram"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.Flowchart;component/Themes/FlowNode.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Border BorderBrush="LightGray" BorderThickness="1">
<ItemsControl ItemsSource="{Binding ToolBoxItems}">
<ItemsControl.Template>
<ControlTemplate TargetType="{x:Type ItemsControl}">
<Border BorderThickness="{TemplateBinding Border.BorderThickness}"
Padding="{TemplateBinding Control.Padding}"
BorderBrush="{TemplateBinding Border.BorderBrush}"
Background="{TemplateBinding Panel.Background}"
SnapsToDevicePixels="True">
<ScrollViewer VerticalScrollBarVisibility="Auto">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="{x:Type ContentPresenter}">
<Setter Property="Control.Padding"
Value="10" />
<Setter Property="ContentControl.HorizontalContentAlignment"
Value="Stretch" />
<Setter Property="ContentControl.VerticalContentAlignment"
Value="Stretch" />
<Setter Property="ToolTip"
Value="{Binding ToolTip}" />
<Setter Property="dd:DragAndDropProps.EnabledForDrag"
Value="True" />
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="5" Width="{Binding Width}" Height="{Binding Height}">
<Rectangle Name="Border"
StrokeThickness="1"
StrokeDashArray="2"
Fill="Transparent"
SnapsToDevicePixels="true"/>
<Grid IsHitTestVisible="False">
<ContentControl Style="{StaticResource CustomFlowNodeStyle}" Margin="2"/>
<TextBlock Text="{Binding Text}" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="{Binding ColorViewModel.LineColor,Converter={StaticResource ColorBrushConverter}}" />
</Grid>
</Grid>
<DataTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="Border" Property="Stroke" Value="Gray"/>
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Border>
</UserControl>

View File

@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using AIStudio.Wpf.Flowchart.ViewModels;
namespace AIStudio.Wpf.Flowchart.Controls
{
/// <summary>
/// Interaction logic for ToolBoxControl.xaml
/// </summary>
public partial class ToolBoxControl : UserControl
{
public ToolBoxControl()
{
InitializeComponent();
this.DataContext = new ToolBoxViewModel();
}
}
}

View File

@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Text;
using AIStudio.Wpf.DiagramDesigner;
using AIStudio.Wpf.Flowchart.ViewModels;
namespace AIStudio.Wpf.Flowchart.Models
{
public class FlowchartModel
{
private List<FlowNode> _nodes = new List<FlowNode>();
public List<FlowNode> Nodes
{
get
{
return _nodes;
}
}
private List<ConnectorViewModel> _links = new List<ConnectorViewModel>();
public List<ConnectorViewModel> Links
{
get
{
return _links;
}
}
}
}

View File

@@ -0,0 +1,17 @@
using System.Windows;
using System.Windows.Markup;
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
[assembly: XmlnsDefinition("https://gitee.com/akwkevin/aistudio.-wpf.-diagram", "AIStudio.Wpf.Flowchart")]
[assembly: XmlnsDefinition("https://gitee.com/akwkevin/aistudio.-wpf.-diagram", "AIStudio.Wpf.Flowchart.Controls")]
[assembly: XmlnsDefinition("https://gitee.com/akwkevin/aistudio.-wpf.-diagram", "AIStudio.Wpf.Flowchart.Controls")]
[assembly: XmlnsPrefix("https://gitee.com/akwkevin/aistudio.-wpf.-diagram", "dd")]

View File

@@ -0,0 +1,8 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.Flowchart;component/Controls/FlowchartEditor.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

View File

@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Media;
using AIStudio.Wpf.DiagramDesigner.Helpers;
using AIStudio.Wpf.Flowchart;
using AIStudio.Wpf.Flowchart.Models;
using AIStudio.Wpf.Flowchart.ViewModels;
namespace AIStudio.Wpf.Flowchart.ViewModels
{
public class ToolBoxViewModel
{
private List<ToolBoxData> toolBoxItems = new List<ToolBoxData>();
public ToolBoxViewModel()
{
toolBoxItems.Add(new FlowchartToolBoxData(NodeKinds.Start, typeof(StartFlowNode), 80, 48));
toolBoxItems.Add(new FlowchartToolBoxData(NodeKinds.End, typeof(EndFlowNode), 80, 48));
toolBoxItems.Add(new FlowchartToolBoxData(NodeKinds.Middle, typeof(MiddleFlowNode), 80, 48));
toolBoxItems.Add(new FlowchartToolBoxData(NodeKinds.Decide, typeof(DecideFlowNode), 80, 48));
toolBoxItems.Add(new FlowchartToolBoxData(NodeKinds.COBegin, typeof(COBeginFlowNode), 80, 48));
toolBoxItems.Add(new FlowchartToolBoxData(NodeKinds.COEnd, typeof(COEndFlowNode), 80, 48));
}
public List<ToolBoxData> ToolBoxItems
{
get
{
return toolBoxItems;
}
}
}
}