Flowchart

This commit is contained in:
艾竹
2022-12-04 23:07:20 +08:00
parent dc42f75610
commit 0487857d7b
30 changed files with 1621 additions and 383 deletions

View File

@@ -9,9 +9,9 @@
<ResourceDictionary Source="pack://application:,,,/Fluent;component/Themes/Generic.xaml" />
<ResourceDictionary Source="pack://application:,,,/Dragablz;component/Themes/Generic.xaml" />
<ResourceDictionary Source="/AIStudio.Wpf.DiagramApp;component/Themes/Generic.xaml" />
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.Flowchart;component/ViewModels/FlowNode.xaml"/>
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.Logical;component/ViewModels/LogicalGateItemViewModel.xaml"/>
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.SFC;component/ViewModels/SFCNode.xaml"/>
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.Flowchart;component/Themes/FlowNode.xaml"/>
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.Logical;component/Themes/LogicalGateItemViewModel.xaml"/>
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.SFC;component/Themes/SFCNode.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>

View File

@@ -43,31 +43,31 @@ namespace AIStudio.Wpf.Flowchart
{
base.Init();
DesignerItemViewModelBase start = new StartFlowNode() { Left = 100, Top = 0, Color = Colors.Yellow.ToString() };
DesignerItemViewModelBase start = new StartFlowNode() { Left = 100, Top = 0, ItemWidth = 80, ItemHeight = 40, Color = Colors.Yellow.ToString() };
DiagramViewModel.DirectAddItemCommand.Execute(start);
DesignerItemViewModelBase middle1 = new MiddleFlowNode() { Left = 100, Top = 100, Color = Colors.Yellow.ToString(), Text = "主管审批", UserIds= new List<string> { "操作员1", "操作员2" }, ActType = "or" };
DesignerItemViewModelBase middle1 = new MiddleFlowNode() { Left = 100, Top = 100, ItemWidth = 80, ItemHeight = 40, Color = Colors.Yellow.ToString(), Text = "主管审批", UserIds= new List<string> { "操作员1", "操作员2" }, ActType = "or" };
DiagramViewModel.DirectAddItemCommand.Execute(middle1);
DesignerItemViewModelBase decide = new DecideFlowNode() { Left = 100, Top = 200, Color = Colors.Yellow.ToString(), Text = "5" };
DesignerItemViewModelBase decide = new DecideFlowNode() { Left = 100, Top = 200, ItemWidth = 80, ItemHeight = 40, Color = Colors.Yellow.ToString(), Text = "5" };
DiagramViewModel.DirectAddItemCommand.Execute(decide);
DesignerItemViewModelBase middle2 = new MiddleFlowNode() { Left = 200, Top = 300, Color = Colors.Yellow.ToString(), Text = "分管领导", UserIds = new List<string> { "操作员1", "操作员2" }, ActType = "and" };
DesignerItemViewModelBase middle2 = new MiddleFlowNode() { Left = 200, Top = 300, ItemWidth = 80, ItemHeight = 40, Color = Colors.Yellow.ToString(), Text = "分管领导", UserIds = new List<string> { "操作员1", "操作员2" }, ActType = "and" };
DiagramViewModel.DirectAddItemCommand.Execute(middle2);
DesignerItemViewModelBase cobegin = new COBeginFlowNode() { Left = 100, Top = 400, Color = Colors.Yellow.ToString() };
DesignerItemViewModelBase cobegin = new COBeginFlowNode() { Left = 100, Top = 400, ItemWidth = 80, ItemHeight = 40, Color = Colors.Yellow.ToString() };
DiagramViewModel.DirectAddItemCommand.Execute(cobegin);
DesignerItemViewModelBase middle3 = new MiddleFlowNode() { Left = 100, Top = 500, Color = Colors.Yellow.ToString(), Text = "财务审批", UserIds = new List<string> { "Admin" }, ActType = "or" };
DesignerItemViewModelBase middle3 = new MiddleFlowNode() { Left = 100, Top = 500, ItemWidth = 80, ItemHeight = 40, Color = Colors.Yellow.ToString(), Text = "财务审批", UserIds = new List<string> { "Admin" }, ActType = "or" };
DiagramViewModel.DirectAddItemCommand.Execute(middle3);
DesignerItemViewModelBase middle4 = new MiddleFlowNode() { Left = 200, Top = 500, Color = Colors.Yellow.ToString(), Text = "人力审批", RoleIds = new List<string> { "操作员", "管理员" }, ActType = "or" };
DesignerItemViewModelBase middle4 = new MiddleFlowNode() { Left = 200, Top = 500, ItemWidth = 80, ItemHeight = 40, Color = Colors.Yellow.ToString(), Text = "人力审批", RoleIds = new List<string> { "操作员", "管理员" }, ActType = "or" };
DiagramViewModel.DirectAddItemCommand.Execute(middle4);
DesignerItemViewModelBase coend = new COEndFlowNode() { Left = 100, Top = 600, Color = Colors.Yellow.ToString() };
DesignerItemViewModelBase coend = new COEndFlowNode() { Left = 100, Top = 600, ItemWidth = 80, ItemHeight = 40, Color = Colors.Yellow.ToString() };
DiagramViewModel.DirectAddItemCommand.Execute(coend);
DesignerItemViewModelBase end = new EndFlowNode() { Left = 100, Top = 700, Color = Colors.Yellow.ToString() };
DesignerItemViewModelBase end = new EndFlowNode() { Left = 100, Top = 700, ItemWidth = 80, ItemHeight = 40, Color = Colors.Yellow.ToString() };
DiagramViewModel.DirectAddItemCommand.Execute(end);
ConnectorViewModel connector1 = new ConnectorViewModel(start.BottomConnector, middle1.TopConnector, _service.DrawModeViewModel.VectorLineDrawMode);

View File

@@ -18,6 +18,7 @@ using AIStudio.Wpf.SFC.ViewModels;
using System.Windows.Media;
using AIStudio.Wpf.Flowchart.Models;
using AIStudio.Wpf.SFC.Models;
using System.Windows;
namespace AIStudio.Wpf.DiagramApp.ViewModels
{
@@ -168,12 +169,12 @@ namespace AIStudio.Wpf.DiagramApp.ViewModels
ToolBoxCategory.Add(new ToolBoxCategory() { Header = "逻辑图", ToolBoxItems = new ObservableCollection<ToolBoxData>(logicalChartToolBoxItems) });
List<ToolBoxData> flowchartToolBoxItems = new List<ToolBoxData>();
flowchartToolBoxItems.Add(new FlowchartToolBoxData(NodeKinds.Start, typeof(StartFlowNode)));
flowchartToolBoxItems.Add(new FlowchartToolBoxData(NodeKinds.End, typeof(EndFlowNode)));
flowchartToolBoxItems.Add(new FlowchartToolBoxData(NodeKinds.Middle, typeof(MiddleFlowNode)));
flowchartToolBoxItems.Add(new FlowchartToolBoxData(NodeKinds.Decide, typeof(DecideFlowNode)));
flowchartToolBoxItems.Add(new FlowchartToolBoxData(NodeKinds.COBegin, typeof(COBeginFlowNode)));
flowchartToolBoxItems.Add(new FlowchartToolBoxData(NodeKinds.COEnd, typeof(COEndFlowNode)));
flowchartToolBoxItems.Add(new FlowchartToolBoxData(NodeKinds.Start, typeof(StartFlowNode), 32, 32, new Size(80, 40)));
flowchartToolBoxItems.Add(new FlowchartToolBoxData(NodeKinds.End, typeof(EndFlowNode), 32, 32, new Size(80, 40)));
flowchartToolBoxItems.Add(new FlowchartToolBoxData(NodeKinds.Middle, typeof(MiddleFlowNode), 32, 32, new Size(80, 40)));
flowchartToolBoxItems.Add(new FlowchartToolBoxData(NodeKinds.Decide, typeof(DecideFlowNode), 32, 32, new Size(80, 40)));
flowchartToolBoxItems.Add(new FlowchartToolBoxData(NodeKinds.COBegin, typeof(COBeginFlowNode), 32, 32, new Size(80, 40))); ;
flowchartToolBoxItems.Add(new FlowchartToolBoxData(NodeKinds.COEnd, typeof(COEndFlowNode), 32, 32, new Size(80, 40)));
ToolBoxCategory.Add(new ToolBoxCategory() { Header = "流程图", ToolBoxItems = new ObservableCollection<ToolBoxData>(flowchartToolBoxItems) });
List<ToolBoxData> mediaToolBoxItems = new List<ToolBoxData>();

View File

@@ -69,7 +69,7 @@
</ResourceDictionary>
</Window.Resources>
<TabControl>
<TabItem Header="Custom">
<TabItem Header="Custom" >
<Grid x:Name="grid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
@@ -86,9 +86,9 @@
Width="3" />
<!-- Diagram Control -->
<dd:DiagramControl Grid.Column="1" x:Name="diagram" DataContext="{Binding DiagramViewModel}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<dd:DiagramControl Grid.Column="1" x:Name="diagram" DataContext="{Binding TabItem1ViewModel.DiagramViewModel}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<dd:PropertiesView Grid.Column="2" CustomSetting="True" SelectedObject="{Binding SelectedItem}" Width="200">
<dd:PropertiesView Grid.Column="2" CustomSetting="True" SelectedObject="{Binding TabItem1ViewModel.SelectedItem}" Width="200">
<dd:PropertiesView.Resources>
<Style x:Key="ActTypeStyle" TargetType="{x:Type ContentControl}">
@@ -112,7 +112,7 @@
<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=DataContext.Users,RelativeSource={RelativeSource AncestorType={x:Type Window}}}" ></dd:MultiSelectComboBox>
ItemsSource="{Binding Path=DataContext.TabItem1ViewModel.Users,RelativeSource={RelativeSource AncestorType={x:Type Window}}}" ></dd:MultiSelectComboBox>
</Grid>
</DataTemplate>
</Setter.Value>
@@ -125,7 +125,7 @@
<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=DataContext.Roles,RelativeSource={RelativeSource AncestorType={x:Type Window}}}"></dd:MultiSelectComboBox>
ItemsSource="{Binding Path=DataContext.TabItem1ViewModel.Roles,RelativeSource={RelativeSource AncestorType={x:Type Window}}}"></dd:MultiSelectComboBox>
</Grid>
</DataTemplate>
</Setter.Value>
@@ -136,9 +136,40 @@
</Grid>
</TabItem>
<TabItem Header="Flowchart">
<dd:FlowchartEditor Users="{Binding Users}" Roles="{Binding Roles}">
</dd:FlowchartEditor>
<TabItem Header="Flowchart" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBox Text="{Binding TabItem2ViewModel.InputData}"
TextWrapping="Wrap"
AcceptsReturn="True"
VerticalScrollBarVisibility="Auto"
Height="50"/>
<Button Grid.Column="1" Content="加载数据" Command="{Binding TabItem2ViewModel.SetDataCommand}"/>
<Button Grid.Column="2" Content="获取数据" Command="{Binding TabItem2ViewModel.GetDataCommand}"/>
<TextBox Grid.Column="3" Text="{Binding TabItem2ViewModel.OutputData}"
TextWrapping="Wrap"
AcceptsReturn="True"
VerticalScrollBarVisibility="Auto"
Height="50"/>
</Grid>
<dd:FlowchartEditor Grid.Row="1" Data="{Binding TabItem2ViewModel.Data}"
GetDataFunc="{Binding TabItem2ViewModel.GetDataFunc,Mode=OneWayToSource}"
Users="{Binding TabItem2ViewModel.Users}"
Roles="{Binding TabItem2ViewModel.Roles}">
</dd:FlowchartEditor>
</Grid>
</TabItem>
</TabControl>
</Window>

View File

@@ -10,90 +10,16 @@ namespace AIStudio.Wpf.DiagramDesigner.Test.ViewModels
{
class MainWindowViewModel : BindableBase
{
public ToolBoxViewModel ToolBoxViewModel
public TabItem1ViewModel TabItem1ViewModel
{
get; private set;
}
get; set;
} = new TabItem1ViewModel();
public DiagramViewModel DiagramViewModel
public TabItem2ViewModel TabItem2ViewModel
{
get; private set;
}
protected IDiagramServiceProvider _service
{
get
{
return DiagramServicesProvider.Instance.Provider;
}
}
public SelectableDesignerItemViewModelBase SelectedItem
{
get
{
return DiagramViewModel.SelectedItems?.FirstOrDefault();
}
}
private List<SelectOption> _users = new List<SelectOption>()
{
new SelectOption(){ value = "操作员1",text = "操作员1" },
new SelectOption(){ value = "操作员2",text = "操作员2" },
new SelectOption(){ value = "Admin",text = "Admin" },
};
public List<SelectOption> Users
{
get
{
return _users;
}
set
{
_users = value;
}
}
private List<SelectOption> _roles = new List<SelectOption>()
{
new SelectOption(){ value = "操作员",text = "操作员" },
new SelectOption(){ value = "管理员",text = "管理员" },
};
public List<SelectOption> Roles
{
get
{
return _roles;
}
set
{
_roles = value;
}
}
public MainWindowViewModel()
{
ToolBoxViewModel = new ToolBoxViewModel();
DiagramViewModel = new DiagramViewModel();
DiagramViewModel.ShowGrid = true;
DiagramViewModel.GridCellSize = new Size(100, 60);
DiagramViewModel.GridMargin = 0d;
DiagramViewModel.CellHorizontalAlignment = CellHorizontalAlignment.Center;
DiagramViewModel.CellVerticalAlignment = CellVerticalAlignment.Center;
DiagramViewModel.PageSizeType = PageSizeType.Custom;
DiagramViewModel.PageSize = new Size(double.NaN, double.NaN);
_service.DrawModeViewModel.VectorLineDrawMode = DrawMode.BoundaryConnectingLine;
DiagramViewModel.PropertyChanged += DiagramViewModel_PropertyChanged;
}
private void DiagramViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == "IsSelected")
{
RaisePropertyChanged(nameof(SelectedItem));
}
}
get; set;
} = new TabItem2ViewModel();
}
}

View File

@@ -0,0 +1,91 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using AIStudio.Wpf.Flowchart;
using AIStudio.Wpf.Flowchart.ViewModels;
namespace AIStudio.Wpf.DiagramDesigner.Test.ViewModels
{
public class TabItem1ViewModel: BindableBase
{
public ToolBoxViewModel ToolBoxViewModel
{
get; private set;
}
public DiagramViewModel DiagramViewModel
{
get; private set;
}
public SelectableDesignerItemViewModelBase SelectedItem
{
get
{
return DiagramViewModel.SelectedItems?.FirstOrDefault();
}
}
private List<SelectOption> _users = new List<SelectOption>()
{
new SelectOption(){ value = "操作员1",text = "操作员1" },
new SelectOption(){ value = "操作员2",text = "操作员2" },
new SelectOption(){ value = "Admin",text = "Admin" },
};
public List<SelectOption> Users
{
get
{
return _users;
}
set
{
_users = value;
}
}
private List<SelectOption> _roles = new List<SelectOption>()
{
new SelectOption(){ value = "操作员",text = "操作员" },
new SelectOption(){ value = "管理员",text = "管理员" },
};
public List<SelectOption> Roles
{
get
{
return _roles;
}
set
{
_roles = value;
}
}
public TabItem1ViewModel()
{
ToolBoxViewModel = new ToolBoxViewModel();
DiagramViewModel = new DiagramViewModel();
DiagramViewModel.ShowGrid = true;
DiagramViewModel.GridCellSize = new Size(100, 60);
DiagramViewModel.GridMargin = 0d;
DiagramViewModel.CellHorizontalAlignment = CellHorizontalAlignment.Center;
DiagramViewModel.CellVerticalAlignment = CellVerticalAlignment.Center;
DiagramViewModel.PageSizeType = PageSizeType.Custom;
DiagramViewModel.PageSize = new Size(double.NaN, double.NaN);
DiagramViewModel.VectorLineDrawMode = DrawMode.BoundaryConnectingLine;
DiagramViewModel.PropertyChanged += DiagramViewModel_PropertyChanged;
}
private void DiagramViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == "IsSelected")
{
RaisePropertyChanged(nameof(SelectedItem));
}
}
}
}

View File

@@ -0,0 +1,128 @@
using System;
using System.Collections.Generic;
using System.Text;
using AIStudio.Wpf.Flowchart;
namespace AIStudio.Wpf.DiagramDesigner.Test.ViewModels
{
public class TabItem2ViewModel : BindableBase
{
private List<SelectOption> _users = new List<SelectOption>()
{
new SelectOption(){ value = "操作员1",text = "操作员1" },
new SelectOption(){ value = "操作员2",text = "操作员2" },
new SelectOption(){ value = "Admin",text = "Admin" },
new SelectOption(){ value = "Bob",text = "Bob" },
new SelectOption(){ value = "Alice",text = "Alice" },
};
public List<SelectOption> Users
{
get
{
return _users;
}
set
{
_users = value;
}
}
private List<SelectOption> _roles = new List<SelectOption>()
{
new SelectOption(){ value = "操作员",text = "操作员" },
new SelectOption(){ value = "管理员",text = "管理员" },
new SelectOption(){ value = "Admin",text = "Admin" },
};
public List<SelectOption> Roles
{
get
{
return _roles;
}
set
{
_roles = value;
}
}
private Func<string> _getDataFunc;
public Func<string> GetDataFunc
{
get
{
return _getDataFunc;
}
set
{
SetProperty(ref _getDataFunc, value);
}
}
private string _inputData;
public string InputData
{
get
{
return _inputData;
}
set
{
SetProperty(ref _inputData, value);
}
}
private string _outputData;
public string OutputData
{
get
{
return _outputData;
}
set
{
SetProperty(ref _outputData, value);
}
}
private string _data = "{}";
public string Data
{
get
{
return _data;
}
set
{
SetProperty(ref _data, value);
}
}
public SimpleCommand GetDataCommand
{
get; private set;
}
public SimpleCommand SetDataCommand
{
get; private set;
}
public TabItem2ViewModel()
{
GetDataCommand = new SimpleCommand(GetDataExcute);
SetDataCommand = new SimpleCommand(SetDataExcute);
}
private void GetDataExcute(object obj)
{
OutputData = GetDataFunc();
}
private void SetDataExcute(object obj)
{
Data = "{}";
Data = InputData;
}
}
}

View File

@@ -72,14 +72,14 @@ namespace AIStudio.Wpf.DiagramDesigner
if (e.LeftButton != MouseButtonState.Pressed)
dragStartPoint = null;
if (dragStartPoint.HasValue)
if (dragStartPoint.HasValue && ((FrameworkElement)sender).DataContext is ToolBoxData toolBoxData)
{
DragObject dataObject = new DragObject();
dataObject.ContentType = (((FrameworkElement)sender).DataContext as ToolBoxData).Type;
dataObject.DesiredSize = new Size(65, 65);
dataObject.Icon = (((FrameworkElement)sender).DataContext as ToolBoxData).Icon;
dataObject.ColorViewModel = (((FrameworkElement)sender).DataContext as ToolBoxData).ColorViewModel;
dataObject.DesignerItem = (((FrameworkElement)sender).DataContext as ToolBoxData).Addition as DesignerItemBase;
dataObject.ContentType = toolBoxData.Type;
dataObject.DesiredSize = toolBoxData.DesiredSize;
dataObject.Icon = toolBoxData.Icon;
dataObject.ColorViewModel = toolBoxData.ColorViewModel;
dataObject.DesignerItem = toolBoxData.Addition as DesignerItemBase;
DragDrop.DoDragDrop((DependencyObject)sender, dataObject, DragDropEffects.Copy);
e.Handled = true;

View File

@@ -25,6 +25,21 @@ namespace AIStudio.Wpf.DiagramDesigner
private Point? rubberbandSelectionStartPoint = null;
private DrawMode VectorLineDrawMode
{
get
{
if (_viewModel.VectorLineDrawMode != null)
{
return _viewModel.VectorLineDrawMode.Value;
}
else
{
return _service.DrawModeViewModel.VectorLineDrawMode;
}
}
}
#region GridCellSize
public static readonly DependencyProperty GridCellSizeProperty =
@@ -188,7 +203,7 @@ namespace AIStudio.Wpf.DiagramDesigner
Rect rectangleBounds = sourceConnector.TransformToVisual(this).TransformBounds(new Rect(sourceConnector.RenderSize));
Point point = new Point(rectangleBounds.Left + (rectangleBounds.Width / 2),
rectangleBounds.Bottom + (rectangleBounds.Height / 2));
partialConnection = new ConnectorViewModel(sourceDataItem, new PartCreatedConnectionInfo(point), _service.DrawModeViewModel.VectorLineDrawMode);
partialConnection = new ConnectorViewModel(sourceDataItem, new PartCreatedConnectionInfo(point), VectorLineDrawMode);
_viewModel.DirectAddItemCommand.Execute(partialConnection);
}
}
@@ -209,7 +224,7 @@ namespace AIStudio.Wpf.DiagramDesigner
Rect rectangleBounds = new Rect(sourceConnectorInfo.DataItem.Left, sourceConnectorInfo.DataItem.Top, 3, 3);
Point point = new Point(rectangleBounds.Left + (rectangleBounds.Width / 2),
rectangleBounds.Bottom + (rectangleBounds.Height / 2));
partialConnection = new ConnectorViewModel(sourceConnectorInfo, new PartCreatedConnectionInfo(point), _service.DrawModeViewModel.VectorLineDrawMode);
partialConnection = new ConnectorViewModel(sourceConnectorInfo, new PartCreatedConnectionInfo(point), VectorLineDrawMode);
_viewModel.DirectAddItemCommand.Execute(partialConnection);
}
}
@@ -218,6 +233,7 @@ namespace AIStudio.Wpf.DiagramDesigner
protected override void OnMouseDown(MouseButtonEventArgs e)
{
base.OnMouseDown(e);
if (_viewModel.IsReadOnly) return;
if (_service.DrawModeViewModel.CursorMode == CursorMode.Format)
{
@@ -271,6 +287,8 @@ namespace AIStudio.Wpf.DiagramDesigner
{
base.OnMouseMove(e);
if (_viewModel.IsReadOnly) return;
Point currentPoint = e.GetPosition(this);
_viewModel.CurrentPoint = currentPoint;
var point = CursorPointManager.GetCursorPosition();
@@ -323,6 +341,8 @@ namespace AIStudio.Wpf.DiagramDesigner
{
base.OnMouseUp(e);
if (_viewModel.IsReadOnly) return;
if (_service.DrawModeViewModel.GetDrawMode() == DrawMode.DirectLine)
{
return;
@@ -341,7 +361,7 @@ namespace AIStudio.Wpf.DiagramDesigner
int indexOfLastTempConnection = sinkDataItem.DataItem.Parent.Items.Count - 1;
sinkDataItem.DataItem.Parent.DirectRemoveItemCommand.Execute(
sinkDataItem.DataItem.Parent.Items[indexOfLastTempConnection]);
sinkDataItem.DataItem.Parent.AddItemCommand.Execute(new ConnectorViewModel(sourceDataItem, sinkDataItem, _service.DrawModeViewModel.VectorLineDrawMode));
sinkDataItem.DataItem.Parent.AddItemCommand.Execute(new ConnectorViewModel(sourceDataItem, sinkDataItem, VectorLineDrawMode));
}
else if (_service.DrawModeViewModel.GetDrawMode() == DrawMode.ConnectingLine && connectorsHit.Count() == 1)
{
@@ -352,7 +372,7 @@ namespace AIStudio.Wpf.DiagramDesigner
_viewModel.DirectRemoveItemCommand.Execute(_viewModel.Items[indexOfLastTempConnection]);
_viewModel.DirectAddItemCommand.Execute(pointItemView);
var connector = new ConnectorViewModel(sourceDataItem, sinkDataItem, _service.DrawModeViewModel.VectorLineDrawMode);
var connector = new ConnectorViewModel(sourceDataItem, sinkDataItem, VectorLineDrawMode);
_viewModel.AddItemCommand.Execute(connector);
sourceDataItem.DataItem.ZIndex++;
@@ -380,6 +400,8 @@ namespace AIStudio.Wpf.DiagramDesigner
{
base.OnPreviewKeyDown(e);
if (_viewModel.IsReadOnly) return;
if (e.Key == Key.Left)
{
if (_viewModel.SelectedItems != null)
@@ -472,6 +494,9 @@ namespace AIStudio.Wpf.DiagramDesigner
protected override void OnDrop(DragEventArgs e)
{
base.OnDrop(e);
if (_viewModel.IsReadOnly) return;
DragObject dragObject = e.Data.GetData(typeof(DragObject)) as DragObject;
if (dragObject != null)
{
@@ -480,17 +505,22 @@ namespace AIStudio.Wpf.DiagramDesigner
DesignerItemViewModelBase itemBase = null;
if (dragObject.DesignerItem != null)
{
itemBase = (DesignerItemViewModelBase)Activator.CreateInstance(dragObject.ContentType, null, dragObject.DesignerItem);
itemBase = (DesignerItemViewModelBase)Activator.CreateInstance(dragObject.ContentType, _viewModel, dragObject.DesignerItem);
}
else
{
itemBase = (DesignerItemViewModelBase)Activator.CreateInstance(dragObject.ContentType);
itemBase.Icon = dragObject.Icon;
itemBase.ColorViewModel = CopyHelper.Mapper(dragObject.ColorViewModel);
if (dragObject.DesiredSize != null)
{
itemBase.ItemWidth = dragObject.DesiredSize.Value.Width;
itemBase.ItemHeight = dragObject.DesiredSize.Value.Height;
}
}
itemBase.Left = Math.Max(0, position.X - itemBase.ItemWidth / 2);
itemBase.Top = Math.Max(0, position.Y - itemBase.ItemHeight / 2);
(DataContext as IDiagramViewModel).AddItemCommand.Execute(itemBase);
_viewModel.AddItemCommand.Execute(itemBase);
}
var dragFile = e.Data.GetData(DataFormats.FileDrop);
if (dragFile != null && dragFile is string[] files)

View File

@@ -31,8 +31,10 @@ namespace AIStudio.Wpf.DiagramDesigner.Controls
if (designerItem is ConnectorViewModel connector)
{
designerItems.Add(connector.SourceConnectorInfo.DataItem);
designerItems.Add((connector.SinkConnectorInfo as FullyCreatedConnectorInfo).DataItem);
if (connector.SinkConnectorInfo is FullyCreatedConnectorInfo)
{
designerItems.Add((connector.SinkConnectorInfo as FullyCreatedConnectorInfo).DataItem);
}
if (designerItem.OutTextItem != null)
{
designerItems.Remove(designerItem.OutTextItem);//这个自动计算位置

View File

@@ -6,6 +6,17 @@ namespace AIStudio.Wpf.DiagramDesigner
{
public static class EnumExtension
{
/// <summary>
/// Converts to enum.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="str">The string.</param>
/// <returns></returns>
public static T ToEnum<T>(this string str)
{
return (T)Enum.Parse(typeof(T), str);
}
public static string GetDescription(this Enum value)
{
FieldInfo field = value.GetType().GetField(value.ToString());

View File

@@ -0,0 +1,48 @@
using System;
using System.Drawing;
using System.Runtime.InteropServices;
namespace AIStudio.Wpf.DiagramDesigner
{
public static class ScreenHelper
{
[DllImport("user32.dll", EntryPoint = "ReleaseDC")]
public static extern IntPtr ReleaseDC(
IntPtr hWnd,
IntPtr hDc
);
[DllImport("gdi32.dll")]
public static extern int GetDeviceCaps(
IntPtr hdc, // handle to DC
int nIndex // index of capability
);
public static System.Drawing.Size GetPhysicalDisplaySize()
{
Graphics g = Graphics.FromHwnd(IntPtr.Zero);
IntPtr desktop = g.GetHdc();
int physicalScreenHeight = GetDeviceCaps(desktop, (int)DeviceCap.Desktopvertres);
int physicalScreenWidth = GetDeviceCaps(desktop, (int)DeviceCap.Desktophorzres);
ReleaseDC(IntPtr.Zero, desktop);
g.Dispose();
return new System.Drawing.Size(physicalScreenWidth, physicalScreenHeight);
}
public enum DeviceCap
{
Desktopvertres = 117,
Desktophorzres = 118
}
public static double ResetScreenScale()
{
using (var g = Graphics.FromHwnd(IntPtr.Zero))
{
IntPtr desktop = g.GetHdc();
int physicalScreenWidth = GetDeviceCaps(desktop, (int)DeviceCap.Desktophorzres);
return physicalScreenWidth * 1.0000 / System.Windows.SystemParameters.PrimaryScreenWidth;
}
}
}
}

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
namespace AIStudio.Wpf.DiagramDesigner.Helpers
{
@@ -13,16 +14,18 @@ namespace AIStudio.Wpf.DiagramDesigner.Helpers
public IColorViewModel ColorViewModel { get; set; }
public double Width { get; set; }
public double Height { get; set; }
public Size? DesiredSize{ get; set; }
public object Addition { get; set; }
public ToolBoxData(string text, string icon, Type type, double width, double height)
public ToolBoxData(string text, string icon, Type type, double width, double height, Size? desiredSize = null)
{
this.Text = text;
this.Icon = icon;
this.Type = type;
this.Width = width;
this.Height = height;
this.Height = height;
this.DesiredSize = desiredSize;
this.ColorViewModel = new ColorViewModel();
}
}

View File

@@ -46,32 +46,56 @@ namespace AIStudio.Wpf.DiagramDesigner
}
[XmlAttribute]
public Guid Id { get; set; }
public Guid Id
{
get; set;
}
[XmlAttribute]
public int ZIndex { get; set; }
public int ZIndex
{
get; set;
}
[XmlAttribute]
public bool IsGroup { get; set; }
public bool IsGroup
{
get; set;
}
[XmlAttribute]
public Guid ParentId { get; set; }
public Guid ParentId
{
get; set;
}
[XmlAttribute]
public string Text { get; set; }
public string Text
{
get; set;
}
[XmlElement]
public ColorItem ColorItem { get; set; }
public ColorItem ColorItem
{
get; set;
}
[XmlElement]
public FontItem FontItem { get; set; }
public FontItem FontItem
{
get; set;
}
}
public class ColorItem : IColorViewModel
{
{
[XmlIgnore]
public IColorObject LineColor { get; set; }
public IColorObject LineColor
{
get; set;
}
[JsonIgnore]
[XmlElement("LineColor")]
@@ -88,7 +112,10 @@ namespace AIStudio.Wpf.DiagramDesigner
}
[XmlIgnore]
public IColorObject FillColor { get; set; }
public IColorObject FillColor
{
get; set;
}
[JsonIgnore]
[XmlElement("FillColor")]
@@ -106,7 +133,10 @@ namespace AIStudio.Wpf.DiagramDesigner
[XmlIgnore]
public Color ShadowColor { get; set; }
public Color ShadowColor
{
get; set;
}
[JsonIgnore]
[XmlElement("ShadowColor")]
@@ -123,19 +153,34 @@ namespace AIStudio.Wpf.DiagramDesigner
}
[XmlAttribute]
public double LineWidth { get; set; }
public double LineWidth
{
get; set;
}
[XmlAttribute]
public ArrowPathStyle LeftArrowPathStyle { get; set; }
public ArrowPathStyle LeftArrowPathStyle
{
get; set;
}
[XmlAttribute]
public ArrowPathStyle RightArrowPathStyle { get; set; }
public ArrowPathStyle RightArrowPathStyle
{
get; set;
}
[XmlAttribute]
public ArrowSizeStyle LeftArrowSizeStyle { get; set; }
public ArrowSizeStyle LeftArrowSizeStyle
{
get; set;
}
[XmlAttribute]
public ArrowSizeStyle RightArrowSizeStyle { get; set; }
public ArrowSizeStyle RightArrowSizeStyle
{
get; set;
}
public event PropertyChangedEventHandler PropertyChanged;
}
@@ -144,20 +189,41 @@ namespace AIStudio.Wpf.DiagramDesigner
public class FontItem : IFontViewModel
{
[XmlIgnore]
public FontWeight FontWeight { get; set; }
public FontWeight FontWeight
{
get; set;
}
[XmlIgnore]
public FontStyle FontStyle { get; set; }
public FontStyle FontStyle
{
get; set;
}
[XmlIgnore]
public FontStretch FontStretch { get; set; }
public FontStretch FontStretch
{
get; set;
}
[XmlAttribute]
public bool Underline { get; set; }
public bool Underline
{
get; set;
}
[XmlAttribute]
public bool Strikethrough { get; set; }
public bool Strikethrough
{
get; set;
}
[XmlAttribute]
public bool OverLine { get; set; }
public bool OverLine
{
get; set;
}
[XmlIgnore]
public Color FontColor { get; set; }
public Color FontColor
{
get; set;
}
[JsonIgnore]
[XmlElement("FontColor")]
@@ -174,10 +240,16 @@ namespace AIStudio.Wpf.DiagramDesigner
}
[XmlIgnore]
public string FontFamily { get; set; }
public string FontFamily
{
get; set;
}
[XmlIgnore]
public double FontSize { get; set; }
public double FontSize
{
get; set;
}
[XmlIgnore]
@@ -237,7 +309,10 @@ namespace AIStudio.Wpf.DiagramDesigner
}
[XmlIgnore]
public Color TextEffectColor { get; set; }
public Color TextEffectColor
{
get; set;
}
[JsonIgnore]
[XmlElement("TextEffectColor")]
@@ -254,7 +329,10 @@ namespace AIStudio.Wpf.DiagramDesigner
}
[XmlIgnore]
public Color HighlightColor { get; set; }
public Color HighlightColor
{
get; set;
}
[JsonIgnore]
[XmlElement("HighlightColor")]
@@ -271,13 +349,25 @@ namespace AIStudio.Wpf.DiagramDesigner
}
[XmlAttribute]
public FontCase FontCase { get; set; }
public FontCase FontCase
{
get; set;
}
[XmlAttribute]
public HorizontalAlignment HorizontalAlignment { get; set; }
public HorizontalAlignment HorizontalAlignment
{
get; set;
}
[XmlAttribute]
public VerticalAlignment VerticalAlignment { get; set; }
public VerticalAlignment VerticalAlignment
{
get; set;
}
[XmlAttribute]
public double LineHeight { get; set; }
public double LineHeight
{
get; set;
}
public event PropertyChangedEventHandler PropertyChanged;
}
@@ -286,18 +376,38 @@ namespace AIStudio.Wpf.DiagramDesigner
{
public static string SerializeColor(Color color)
{
return string.Format("{0}:{1}:{2}:{3}", color.A, color.R, color.G, color.B);
return string.Format("#{0:X2}{1:X2}{2:X2}{3:X2}", color.A, color.R, color.G, color.B);
}
public static Color DeserializeColor(string color)
{
{
byte a, r, g, b;
string[] pieces = color.Split(new char[] { ':' });
a = byte.Parse(pieces[0]);
r = byte.Parse(pieces[1]);
g = byte.Parse(pieces[2]);
b = byte.Parse(pieces[3]);
return Color.FromArgb(a, r, g, b);
try
{
if (color?.Length == 9)
{
a = Convert.ToByte(color.Substring(1, 2), 16);
r = Convert.ToByte(color.Substring(3, 2), 16);
g = Convert.ToByte(color.Substring(5, 2), 16);
b = Convert.ToByte(color.Substring(7, 2), 16);
return Color.FromArgb(a, r, g, b);
}
else if (color?.Length == 7)
{
r = Convert.ToByte(color.Substring(1, 2), 16);
g = Convert.ToByte(color.Substring(3, 2), 16);
b = Convert.ToByte(color.Substring(5, 2), 16);
return Color.FromRgb(r, g, b);
}
else
{
return Colors.Black;
}
}
catch
{
return Colors.Black;
}
}
public static GradientStop DeserializeGradientStop(string str)
@@ -308,7 +418,7 @@ namespace AIStudio.Wpf.DiagramDesigner
public static string SerializeColorList(IEnumerable<Color> colors)
{
return string.Join("-", colors.Select(color => string.Format("{0}:{1}:{2}:{3}", color.A, color.R, color.G, color.B)));
return string.Join("-", colors.Select(color => string.Format("#{0:X2}{1:X2}{2:X2}{3:X2}", color.A, color.R, color.G, color.B)));
}
public static List<Color> DeserializeColorList(string colorstring)
@@ -317,13 +427,7 @@ namespace AIStudio.Wpf.DiagramDesigner
var colors = colorstring.Split('-');
foreach (var color in colors)
{
byte a, r, g, b;
string[] pieces = color.Split(new char[] { ':' });
a = byte.Parse(pieces[0]);
r = byte.Parse(pieces[1]);
g = byte.Parse(pieces[2]);
b = byte.Parse(pieces[3]);
colorlist.Add(Color.FromArgb(a, r, g, b));
colorlist.Add(DeserializeColor(color));
}
return colorlist;
}
@@ -388,10 +492,16 @@ namespace AIStudio.Wpf.DiagramDesigner
{
[XmlAttribute]
public BrushType BrushType { get; set; }
public BrushType BrushType
{
get; set;
}
[XmlIgnore]
public Color Color { get; set; }
public Color Color
{
get; set;
}
[JsonIgnore]
[XmlElement("FillColor")]
@@ -408,7 +518,10 @@ namespace AIStudio.Wpf.DiagramDesigner
}
[XmlIgnore]
public ObservableCollection<GradientStop> GradientStop { get; set; }
public ObservableCollection<GradientStop> GradientStop
{
get; set;
}
[JsonIgnore]
[XmlArray("GradientStop")]
@@ -427,7 +540,10 @@ namespace AIStudio.Wpf.DiagramDesigner
[XmlIgnore]
public IEnumerable<double> Offset { get; set; }
public IEnumerable<double> Offset
{
get; set;
}
[JsonIgnore]
[XmlArray("Offset")]
@@ -444,13 +560,22 @@ namespace AIStudio.Wpf.DiagramDesigner
}
[XmlAttribute]
public string Image { get; set; }
public string Image
{
get; set;
}
[XmlAttribute]
public int SubType { get; set; }
public int SubType
{
get; set;
}
[XmlIgnore]
public Point StartPoint { get; set; }
public Point StartPoint
{
get; set;
}
[JsonIgnore]
[XmlAttribute("StartPoint")]
@@ -467,7 +592,10 @@ namespace AIStudio.Wpf.DiagramDesigner
}
[XmlIgnore]
public Point EndPoint { get; set; }
public Point EndPoint
{
get; set;
}
[JsonIgnore]
[XmlAttribute("EndPoint")]
@@ -484,13 +612,25 @@ namespace AIStudio.Wpf.DiagramDesigner
}
[XmlAttribute]
public double Opacity { get; set; }
public double Opacity
{
get; set;
}
[XmlAttribute]
public LinearOrientation LinearOrientation { get; set; }
public LinearOrientation LinearOrientation
{
get; set;
}
[XmlAttribute]
public RadialOrientation RadialOrientation { get; set; }
public RadialOrientation RadialOrientation
{
get; set;
}
[XmlAttribute]
public int Angle { get; set; }
public int Angle
{
get; set;
}
}
}

View File

@@ -144,7 +144,11 @@ namespace AIStudio.Wpf.DiagramDesigner
{
get
{
if (LockObjectViewModel != null && LockObjectViewModel.LockObject.FirstOrDefault(p => p.LockFlag == LockFlag.All).IsChecked == true)
if (Parent?.IsReadOnly == true)
{
return true;
}
if (LockObjectViewModel?.LockObject.FirstOrDefault(p => p.LockFlag == LockFlag.All)?.IsChecked == true)
{
return true;
}

View File

@@ -14,6 +14,24 @@ namespace AIStudio.Wpf.DiagramDesigner
public class DiagramViewModel : BindableBase, IDiagramViewModel
{
#region
private bool _isReadOnly;
public bool IsReadOnly
{
get
{
return _isReadOnly;
}
set
{
SetProperty(ref _isReadOnly, value);
}
}
public DrawMode? VectorLineDrawMode
{
get; set;
}
private PageSizeType _pageSizeType = PageSizeType.A4;
public PageSizeType PageSizeType
{
@@ -320,6 +338,11 @@ namespace AIStudio.Wpf.DiagramDesigner
SetProperty(ref _currentColor, value);
}
}
/// <summary>
/// 用于wpf大小与物理像素之间转换
/// </summary>
public double ScreenScale { get; set; } = 1;
#endregion
private DoCommandManager DoCommandManager = new DoCommandManager();
@@ -439,26 +462,83 @@ namespace AIStudio.Wpf.DiagramDesigner
}
}
public SimpleCommand CreateNewDiagramCommand { get; private set; }
public SimpleCommand DirectAddItemCommand { get; private set; }
public SimpleCommand AddItemCommand { get; private set; }
public SimpleCommand DirectRemoveItemCommand { get; private set; }
public SimpleCommand RemoveItemCommand { get; private set; }
public SimpleCommand ClearSelectedItemsCommand { get; private set; }
public SimpleCommand AlignTopCommand { get; private set; }
public SimpleCommand AlignVerticalCentersCommand { get; private set; }
public SimpleCommand AlignBottomCommand { get; private set; }
public SimpleCommand AlignLeftCommand { get; private set; }
public SimpleCommand AlignHorizontalCentersCommand { get; private set; }
public SimpleCommand AlignRightCommand { get; private set; }
public SimpleCommand BringForwardCommand { get; private set; }
public SimpleCommand BringToFrontCommand { get; private set; }
public SimpleCommand SendBackwardCommand { get; private set; }
public SimpleCommand SendToBackCommand { get; private set; }
public SimpleCommand CreateNewDiagramCommand
{
get; private set;
}
public SimpleCommand DirectAddItemCommand
{
get; private set;
}
public SimpleCommand AddItemCommand
{
get; private set;
}
public SimpleCommand DirectRemoveItemCommand
{
get; private set;
}
public SimpleCommand RemoveItemCommand
{
get; private set;
}
public SimpleCommand ClearSelectedItemsCommand
{
get; private set;
}
public SimpleCommand AlignTopCommand
{
get; private set;
}
public SimpleCommand AlignVerticalCentersCommand
{
get; private set;
}
public SimpleCommand AlignBottomCommand
{
get; private set;
}
public SimpleCommand AlignLeftCommand
{
get; private set;
}
public SimpleCommand AlignHorizontalCentersCommand
{
get; private set;
}
public SimpleCommand AlignRightCommand
{
get; private set;
}
public SimpleCommand BringForwardCommand
{
get; private set;
}
public SimpleCommand BringToFrontCommand
{
get; private set;
}
public SimpleCommand SendBackwardCommand
{
get; private set;
}
public SimpleCommand SendToBackCommand
{
get; private set;
}
public SimpleCommand DistributeHorizontalCommand { get; private set; }
public SimpleCommand DistributeVerticalCommand { get; private set; }
public SimpleCommand SelectAllCommand { get; private set; }
public SimpleCommand DistributeHorizontalCommand
{
get; private set;
}
public SimpleCommand DistributeVerticalCommand
{
get; private set;
}
public SimpleCommand SelectAllCommand
{
get; private set;
}
private SimpleCommand _undoCommand;
public SimpleCommand UndoCommand
@@ -483,7 +563,10 @@ namespace AIStudio.Wpf.DiagramDesigner
public List<SelectableDesignerItemViewModelBase> SelectedItems
{
get { return Items.Where(x => x.IsSelected).ToList(); }
get
{
return Items.Where(x => x.IsSelected).ToList();
}
}
@@ -499,7 +582,10 @@ namespace AIStudio.Wpf.DiagramDesigner
}
}
public Func<SelectableDesignerItemViewModelBase, bool> OutAddVerify { get; set; }
public Func<SelectableDesignerItemViewModelBase, bool> OutAddVerify
{
get; set;
}
public bool AddVerify(SelectableDesignerItemViewModelBase item)
{
@@ -567,13 +653,11 @@ namespace AIStudio.Wpf.DiagramDesigner
if (AddVerify(ite) != true) return;
DoCommandManager.DoNewCommand(this.ToString(),
() =>
{
() => {
ClearSelectedItems();
Add(ite);
},
() =>
{
() => {
Items.Remove(ite);
});
}
@@ -582,16 +666,14 @@ namespace AIStudio.Wpf.DiagramDesigner
if (items.Select(p => AddVerify(p)).Any() != true) return;
DoCommandManager.DoNewCommand(this.ToString(),
() =>
{
() => {
ClearSelectedItems();
foreach (var item in items)
{
Add(item);
}
},
() =>
{
() => {
items.ForEach(item => Items.Remove(item));
});
}
@@ -626,8 +708,7 @@ namespace AIStudio.Wpf.DiagramDesigner
if (parameter is SelectableDesignerItemViewModelBase ite)
{
DoCommandManager.DoNewCommand(this.ToString(),
() =>
{
() => {
ite.IsSelected = false;
Items.Remove(ite);
if (ite.OutTextItem != null)
@@ -636,16 +717,14 @@ namespace AIStudio.Wpf.DiagramDesigner
}
},
() =>
{
() => {
Items.Add(ite);
});
}
else if (parameter is List<SelectableDesignerItemViewModelBase> items)
{
DoCommandManager.DoNewCommand(this.ToString(),
() =>
{
() => {
foreach (var item in items)
{
item.IsSelected = false;
@@ -657,8 +736,7 @@ namespace AIStudio.Wpf.DiagramDesigner
}
},
() =>
{
() => {
foreach (var item in items)
{
Items.Add(item);
@@ -693,8 +771,7 @@ namespace AIStudio.Wpf.DiagramDesigner
if (selectedItems.Count() > 1)
{
DoCommandManager.DoNewCommand(this.ToString(),
() =>
{
() => {
double top = selectedItems.OrderBy(p => p.Top).Select(p => p.Top).FirstOrDefault();
foreach (DesignerItemViewModelBase item in selectedItems)
@@ -703,15 +780,13 @@ namespace AIStudio.Wpf.DiagramDesigner
item.Top = top;
}
},
() =>
{
() => {
foreach (DesignerItemViewModelBase item in selectedItems)
{
item.Top = item.GetOldValue<double>(nameof(item.Top), guid.ToString());
}
},
() =>
{
() => {
foreach (DesignerItemViewModelBase item in selectedItems)
{
item.ClearOldValue<double>(nameof(item.Top), guid.ToString());
@@ -728,8 +803,7 @@ namespace AIStudio.Wpf.DiagramDesigner
if (selectedItems.Count() > 1)
{
DoCommandManager.DoNewCommand(this.ToString(),
() =>
{
() => {
double mid = selectedItems.Select(p => p.Top + p.ItemHeight / 2).Average();
foreach (DesignerItemViewModelBase item in selectedItems)
@@ -738,15 +812,13 @@ namespace AIStudio.Wpf.DiagramDesigner
item.Top = mid - item.ItemHeight / 2;
}
},
() =>
{
() => {
foreach (DesignerItemViewModelBase item in selectedItems)
{
item.Top = item.GetOldValue<double>(nameof(item.Top), guid.ToString());
}
},
() =>
{
() => {
foreach (DesignerItemViewModelBase item in selectedItems)
{
item.ClearOldValue<double>(nameof(item.Top), guid.ToString());
@@ -763,8 +835,7 @@ namespace AIStudio.Wpf.DiagramDesigner
if (selectedItems.Count() > 1)
{
DoCommandManager.DoNewCommand(this.ToString(),
() =>
{
() => {
double top = selectedItems.OrderBy(p => p.Top + p.ItemHeight).Select(p => p.Top + p.ItemHeight).LastOrDefault();
foreach (DesignerItemViewModelBase item in selectedItems)
@@ -773,15 +844,13 @@ namespace AIStudio.Wpf.DiagramDesigner
item.Top = top - item.ItemHeight;
}
},
() =>
{
() => {
foreach (DesignerItemViewModelBase item in selectedItems)
{
item.Top = item.GetOldValue<double>(nameof(item.Top), guid.ToString());
}
},
() =>
{
() => {
foreach (DesignerItemViewModelBase item in selectedItems)
{
item.ClearOldValue<double>(nameof(item.Top), guid.ToString());
@@ -798,8 +867,7 @@ namespace AIStudio.Wpf.DiagramDesigner
if (selectedItems.Count() > 1)
{
DoCommandManager.DoNewCommand(this.ToString(),
() =>
{
() => {
double left = selectedItems.OrderBy(p => p.Left).Select(p => p.Left).FirstOrDefault();
foreach (DesignerItemViewModelBase item in selectedItems)
@@ -808,15 +876,13 @@ namespace AIStudio.Wpf.DiagramDesigner
item.Left = left;
}
},
() =>
{
() => {
foreach (DesignerItemViewModelBase item in selectedItems)
{
item.Left = item.GetOldValue<double>(nameof(item.Left), guid.ToString());
}
},
() =>
{
() => {
foreach (DesignerItemViewModelBase item in selectedItems)
{
item.ClearOldValue<double>(nameof(item.Left), guid.ToString());
@@ -833,8 +899,7 @@ namespace AIStudio.Wpf.DiagramDesigner
if (selectedItems.Count() > 1)
{
DoCommandManager.DoNewCommand(this.ToString(),
() =>
{
() => {
double mid = selectedItems.Select(p => p.Left + p.ItemWidth / 2).Average();
foreach (DesignerItemViewModelBase item in selectedItems)
@@ -843,15 +908,13 @@ namespace AIStudio.Wpf.DiagramDesigner
item.Left = mid - item.ItemWidth / 2;
}
},
() =>
{
() => {
foreach (DesignerItemViewModelBase item in selectedItems)
{
item.Left = item.GetOldValue<double>(nameof(item.Left), guid.ToString());
}
},
() =>
{
() => {
foreach (DesignerItemViewModelBase item in selectedItems)
{
item.ClearOldValue<double>(nameof(item.Left), guid.ToString());
@@ -868,8 +931,7 @@ namespace AIStudio.Wpf.DiagramDesigner
if (selectedItems.Count() > 1)
{
DoCommandManager.DoNewCommand(this.ToString(),
() =>
{
() => {
double right = selectedItems.OrderBy(p => p.Left + p.ItemWidth).Select(p => p.Left + p.ItemWidth).LastOrDefault();
foreach (DesignerItemViewModelBase item in selectedItems)
@@ -878,15 +940,13 @@ namespace AIStudio.Wpf.DiagramDesigner
item.Left = right - item.ItemWidth;
}
},
() =>
{
() => {
foreach (DesignerItemViewModelBase item in selectedItems)
{
item.Left = item.GetOldValue<double>(nameof(item.Left), guid.ToString());
}
},
() =>
{
() => {
foreach (DesignerItemViewModelBase item in selectedItems)
{
item.ClearOldValue<double>(nameof(item.Left), guid.ToString());
@@ -904,8 +964,7 @@ namespace AIStudio.Wpf.DiagramDesigner
var guid = Guid.NewGuid();
DoCommandManager.DoNewCommand(this.ToString(),
() =>
{
() => {
int count = this.Items.Count;
for (int i = 0; i < ordered.Count; i++)
{
@@ -933,15 +992,13 @@ namespace AIStudio.Wpf.DiagramDesigner
}
}
},
() =>
{
() => {
foreach (var item in changeditems)
{
item.ZIndex = item.GetOldValue<int>(nameof(item.ZIndex), guid.ToString());
}
},
() =>
{
() => {
foreach (var item in changeditems)
{
item.ClearOldValue<double>(nameof(item.ZIndex), guid.ToString());
@@ -957,8 +1014,7 @@ namespace AIStudio.Wpf.DiagramDesigner
var guid = Guid.NewGuid();
DoCommandManager.DoNewCommand(this.ToString(),
() =>
{
() => {
int i = childrenSorted.Count - 1;
int j = childrenSorted.Count - selectionSorted.Count - 1;
@@ -976,15 +1032,13 @@ namespace AIStudio.Wpf.DiagramDesigner
changeditems.Add(item);
}
},
() =>
{
() => {
foreach (var item in changeditems)
{
item.ZIndex = item.GetOldValue<int>(nameof(item.ZIndex), guid.ToString());
}
},
() =>
{
() => {
foreach (var item in changeditems)
{
item.ClearOldValue<double>(nameof(item.ZIndex), guid.ToString());
@@ -1000,8 +1054,7 @@ namespace AIStudio.Wpf.DiagramDesigner
var guid = Guid.NewGuid();
DoCommandManager.DoNewCommand(this.ToString(),
() =>
{
() => {
for (int i = 0; i < ordered.Count; i++)
{
var item = ordered[i];
@@ -1028,15 +1081,13 @@ namespace AIStudio.Wpf.DiagramDesigner
}
}
},
() =>
{
() => {
foreach (var item in changeditems)
{
item.ZIndex = item.GetOldValue<int>(nameof(item.ZIndex), guid.ToString());
}
},
() =>
{
() => {
foreach (var item in changeditems)
{
item.ClearOldValue<double>(nameof(item.ZIndex), guid.ToString());
@@ -1052,8 +1103,7 @@ namespace AIStudio.Wpf.DiagramDesigner
var guid = Guid.NewGuid();
DoCommandManager.DoNewCommand(this.ToString(),
() =>
{
() => {
int i = childrenSorted.Count - 1;
int j = selectionSorted.Count - 1;
@@ -1071,15 +1121,13 @@ namespace AIStudio.Wpf.DiagramDesigner
changeditems.Add(item);
}
},
() =>
{
() => {
foreach (var item in changeditems)
{
item.ZIndex = item.GetOldValue<int>(nameof(item.ZIndex), guid.ToString());
}
},
() =>
{
() => {
foreach (var item in changeditems)
{
item.ClearOldValue<double>(nameof(item.ZIndex), guid.ToString());
@@ -1097,8 +1145,7 @@ namespace AIStudio.Wpf.DiagramDesigner
if (selectedItems.Count() > 1)
{
DoCommandManager.DoNewCommand(this.ToString(),
() =>
{
() => {
double left = Double.MaxValue;
double right = Double.MinValue;
double sumWidth = 0;
@@ -1124,8 +1171,7 @@ namespace AIStudio.Wpf.DiagramDesigner
}
},
() =>
{
() => {
foreach (DesignerItemViewModelBase item in selectedItems)
{
foreach (DesignerItemViewModelBase di in SelectionService.GetGroupMembers(item))
@@ -1134,8 +1180,7 @@ namespace AIStudio.Wpf.DiagramDesigner
}
}
},
() =>
{
() => {
foreach (DesignerItemViewModelBase item in selectedItems)
{
foreach (DesignerItemViewModelBase di in SelectionService.GetGroupMembers(item))
@@ -1158,8 +1203,7 @@ namespace AIStudio.Wpf.DiagramDesigner
if (selectedItems.Count() > 1)
{
DoCommandManager.DoNewCommand(this.ToString(),
() =>
{
() => {
double top = Double.MaxValue;
double bottom = Double.MinValue;
double sumHeight = 0;
@@ -1184,8 +1228,7 @@ namespace AIStudio.Wpf.DiagramDesigner
offset = offset + item.ItemHeight + distance;
}
},
() =>
{
() => {
foreach (DesignerItemViewModelBase item in selectedItems)
{
foreach (DesignerItemViewModelBase di in SelectionService.GetGroupMembers(item))
@@ -1194,8 +1237,7 @@ namespace AIStudio.Wpf.DiagramDesigner
}
}
},
() =>
{
() => {
foreach (DesignerItemViewModelBase item in selectedItems)
{
foreach (DesignerItemViewModelBase di in SelectionService.GetGroupMembers(item))
@@ -1253,7 +1295,12 @@ namespace AIStudio.Wpf.DiagramDesigner
return new Rect(new Point(x1, y1), new Point(x2, y2));
}
#region wpf大小与物理像素之间转换
public void SetScreenScale()
{
ScreenScale = ScreenHelper.ResetScreenScale();
}
#endregion
}

View File

@@ -45,6 +45,7 @@ namespace AIStudio.Wpf.DiagramDesigner
Rect GetBoundingRectangle(IEnumerable<DesignerItemViewModelBase> items);
void UpdateZIndex();
bool IsReadOnly{ get; set; }
Size PageSize { get; set; }
PageSizeType PageSizeType { get; set; }
bool ShowGrid { get; set; }
@@ -58,6 +59,12 @@ namespace AIStudio.Wpf.DiagramDesigner
Point CurrentPoint { get; set; }
Color CurrentColor { get; set; }
//如果这个赋值了,优先用这个的
DrawMode? VectorLineDrawMode { get; set; }
//用于wpf大小与物理像素之间转换
double ScreenScale { get; set; }
void SetScreenScale();
event PropertyChangedEventHandler PropertyChanged;

View File

@@ -176,7 +176,7 @@ namespace AIStudio.Wpf.DiagramHelper.Controls
{
foreach (var item in SelectedValues)
{
Node node = _nodeList.FirstOrDefault(i => i.Object != null && i.Object.ToString() != "All" && i.Object.GetPropertyValue(SelectedValuePath) == item);
Node node = _nodeList.FirstOrDefault(i => i.Object != null && i.Object.ToString() != "All" && i.Object.GetPropertyValue(SelectedValuePath)?.ToString() == item?.ToString());
if (node != null)
node.IsSelected = true;
}

View File

@@ -42,7 +42,7 @@
<Setter Property="PropertiesBox">
<Setter.Value>
<ControlTemplate TargetType="Control">
<dd:PropertiesView CustomSetting="True"
<dd:PropertiesView
SelectedObject="{Binding Path=SelectedObject,RelativeSource={RelativeSource AncestorType={x:Type controls:FlowchartEditor}}}"
Width="200">
<dd:PropertiesView.Resources>

View File

@@ -1,20 +1,12 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
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
{
@@ -26,24 +18,8 @@ namespace AIStudio.Wpf.Flowchart.Controls
{
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),
};
private IDiagramViewModel _diagramViewModel;
static FlowchartEditor()
{
@@ -51,7 +27,18 @@ namespace AIStudio.Wpf.Flowchart.Controls
}
public FlowchartEditor()
{
{
_diagramViewModel = new DiagramViewModel();
_diagramViewModel.SetScreenScale();
_diagramViewModel.ShowGrid = true;
_diagramViewModel.GridCellSize = new Size(125 / _diagramViewModel.ScreenScale, 125 / _diagramViewModel.ScreenScale);
_diagramViewModel.GridMargin = 0d;
_diagramViewModel.CellHorizontalAlignment = CellHorizontalAlignment.Center;
_diagramViewModel.CellVerticalAlignment = CellVerticalAlignment.Center;
_diagramViewModel.PageSizeType = PageSizeType.Custom;
_diagramViewModel.PageSize = new Size(double.NaN, double.NaN);
_diagramViewModel.VectorLineDrawMode = DrawMode.BoundaryConnectingLine;
_diagramViewModel.PropertyChanged += DiagramViewModel_PropertyChanged;
}
@@ -63,6 +50,8 @@ namespace AIStudio.Wpf.Flowchart.Controls
_diagramControl.HorizontalAlignment = HorizontalAlignment.Stretch;
_diagramControl.VerticalAlignment = VerticalAlignment.Stretch;
_diagramControl.DataContext = _diagramViewModel;
GetDataFunc = GetData;
}
private void DiagramViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
@@ -74,47 +63,95 @@ namespace AIStudio.Wpf.Flowchart.Controls
}
//一点要绑定不为空的FlowchartModel才能用即便为空的也要new一个再来绑定
public static readonly DependencyProperty FlowchartModelProperty =
DependencyProperty.Register(nameof(FlowchartModel),
typeof(FlowchartModel),
public static readonly DependencyProperty DataProperty =
DependencyProperty.Register(nameof(Data),
typeof(string),
typeof(FlowchartEditor),
new FrameworkPropertyMetadata(null, OnFlowchartModelChanged));
new FrameworkPropertyMetadata(null, OnDataChanged));
public FlowchartModel FlowchartModel
public string Data
{
get
{
return (FlowchartModel)GetValue(FlowchartModelProperty);
return (string)GetValue(DataProperty);
}
set
{
SetValue(FlowchartModelProperty, value);
SetValue(DataProperty, value);
}
}
private static void OnFlowchartModelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
private static void OnDataChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var view = d as FlowchartEditor;
var model = e.NewValue as FlowchartModel;
if (model != null)
var json = e.NewValue as string;
if (json != null)
{
view.CreateFlowchartModel(model);
view.CreateFlowchartModel(json);
}
}
private void CreateFlowchartModel(FlowchartModel model)
private void CreateFlowchartModel(string json)
{
_service.DrawModeViewModel.VectorLineDrawMode = DrawMode.BoundaryConnectingLine;
_diagramViewModel.Items.Clear();
if (model != null)
_diagramViewModel.ToObject(json);
}
public static readonly DependencyProperty GetDataFuncProperty =
DependencyProperty.Register(nameof(GetDataFunc),
typeof(Func<string>),
typeof(FlowchartEditor),
new FrameworkPropertyMetadata(null));
public Func<string> GetDataFunc
{
get
{
foreach (var node in model.Nodes)
{
_diagramViewModel.DirectAddItemCommand.Execute(node);
}
foreach (var link in model.Links)
{
_diagramViewModel.DirectAddItemCommand.Execute(link);
}
return (Func<string>)this.GetValue(GetDataFuncProperty);
}
set
{
this.SetValue(GetDataFuncProperty, value);
}
}
public Func<string> GetData
{
get
{
return new Func<string>(() => _diagramViewModel.ToJson());
}
}
public static readonly DependencyProperty ModeProperty =
DependencyProperty.Register(nameof(Mode),
typeof(string),
typeof(FlowchartEditor),
new FrameworkPropertyMetadata("Edit", OnModeChanged));
public string Mode
{
get
{
return (string)GetValue(ModeProperty);
}
set
{
SetValue(ModeProperty, value);
}
}
private static void OnModeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var view = d as FlowchartEditor;
var mode = e.NewValue as string;
if (mode != "Edit")
{
view._diagramViewModel.IsReadOnly = true;
}
else
{
view._diagramViewModel.IsReadOnly = false;
}
}

View File

@@ -0,0 +1,408 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace AIStudio.Wpf.Flowchart.Models
{
/// <summary>
///
/// </summary>
public class DiagramData
{
/// <summary>
/// Gets or sets the nodes.
/// </summary>
/// <value>
/// The nodes.
/// </value>
public DiagramNode[] Nodes
{
get; set;
}
/// <summary>
/// Gets or sets the links.
/// </summary>
/// <value>
/// The links.
/// </value>
public DiagramLink[] Links
{
get; set;
}
/// <summary>
/// Gets or sets the groups.
/// </summary>
/// <value>
/// The groups.
/// </value>
public DiagramGroup[] Groups
{
get; set;
}
/// <summary>
/// Initializes a new instance of the <see cref="DiagramData"/> class.
/// </summary>
public DiagramData()
{
Nodes = new DiagramNode[0];
Links = new DiagramLink[0];
Groups = new DiagramGroup[0];
}
}
/// <summary>
/// DiagramNode
/// </summary>
public class DiagramNode
{
/// <summary>
/// Gets or sets the identifier.
/// </summary>
/// <value>
/// The identifier.
/// </value>
public string Id
{
get; set;
}
/// <summary>
/// Gets or sets the name.
/// </summary>
/// <value>
/// The name.
/// </value>
public string Name
{
get; set;
}
/// <summary>
/// Gets or sets the color.
/// </summary>
/// <value>
/// The color.
/// </value>
public string Color
{
get; set;
}
/// <summary>
/// Gets or sets the label.
/// </summary>
/// <value>
/// The label.
/// </value>
public string Label
{
get; set;
}
/// <summary>
/// Gets or sets the width.
/// </summary>
/// <value>
/// The width.
/// </value>
public double Width
{
get; set;
}
/// <summary>
/// Gets or sets the height.
/// </summary>
/// <value>
/// The height.
/// </value>
public double Height
{
get; set;
}
/// <summary>
/// Gets or sets the x.
/// </summary>
/// <value>
/// The x.
/// </value>
public double X
{
get; set;
}
/// <summary>
/// Gets or sets the y.
/// </summary>
/// <value>
/// The y.
/// </value>
public double Y
{
get; set;
}
/// <summary>
/// Gets or sets the type.
/// </summary>
/// <value>
/// The type.
/// </value>
public string Type
{
get; set;
}
/// <summary>
/// Gets or sets the index of the z.
/// </summary>
/// <value>
/// The index of the z.
/// </value>
public int ZIndex
{
get; set;
}
/// <summary>
/// Gets or sets the port alignment list.
/// </summary>
/// <value>
/// The port alignment list.
/// </value>
public List<string> PortAlignmentList
{
get; set;
}
}
/// <summary>
///
/// </summary>
public class DiagramLink
{
/// <summary>
/// Gets or sets the identifier.
/// </summary>
/// <value>
/// The identifier.
/// </value>
public string Id
{
get; set;
}
/// <summary>
/// Gets or sets the color.
/// </summary>
/// <value>
/// The color.
/// </value>
public string Color
{
get; set;
}
/// <summary>
/// Gets or sets the color of the selected.
/// </summary>
/// <value>
/// The color of the selected.
/// </value>
public string SelectedColor
{
get; set;
}
/// <summary>
/// Gets or sets the width.
/// </summary>
/// <value>
/// The width.
/// </value>
public double Width
{
get; set;
}
/// <summary>
/// Gets or sets the label.
/// </summary>
/// <value>
/// The label.
/// </value>
public string Label
{
get; set;
}//TODO
/// <summary>
/// Gets or sets the source identifier.
/// </summary>
/// <value>
/// The source identifier.
/// </value>
public string SourceId
{
get; set;
}
/// <summary>
/// Gets or sets the target identifier.
/// </summary>
/// <value>
/// The target identifier.
/// </value>
public string TargetId
{
get; set;
}
/// <summary>
/// Gets or sets the source port alignment.
/// </summary>
/// <value>
/// The source port alignment.
/// </value>
public string SourcePortAlignment
{
get; set;
}
/// <summary>
/// Gets or sets the target port alignment.
/// </summary>
/// <value>
/// The target port alignment.
/// </value>
public string TargetPortAlignment
{
get; set;
}
/// <summary>
/// Gets or sets the type.
/// </summary>
/// <value>
/// The type.
/// </value>
public string Type
{
get; set;
}
/// <summary>
/// Gets or sets the router.
/// </summary>
/// <value>
/// The router.
/// </value>
public string Router
{
get; set;
}
/// <summary>
/// Gets or sets the path generator.
/// </summary>
/// <value>
/// The path generator.
/// </value>
public string PathGenerator
{
get; set;
}
/// <summary>
/// Gets or sets the source marker path.
/// </summary>
/// <value>
/// The source marker path.
/// </value>
public string SourceMarkerPath
{
get; set;
}
/// <summary>
/// Gets or sets the width of the source marker.
/// </summary>
/// <value>
/// The width of the source marker.
/// </value>
public double? SourceMarkerWidth
{
get; set;
}
/// <summary>
/// Gets or sets the target marker path.
/// </summary>
/// <value>
/// The target marker path.
/// </value>
public string TargetMarkerPath
{
get; set;
}
/// <summary>
/// Gets or sets the width of the target marker.
/// </summary>
/// <value>
/// The width of the target marker.
/// </value>
public double? TargetMarkerWidth
{
get; set;
}
}
/// <summary>
///
/// </summary>
/// <seealso cref="AIStudio.Util.DiagramEntity.DiagramNode" />
public class FlowchartNode : DiagramNode
{
/// <summary>
/// Gets or sets the kind.
/// </summary>
/// <value>
/// The kind.
/// </value>
public NodeKinds Kind
{
get; set;
}
/// <summary>
/// Gets or sets the user ids.
/// </summary>
/// <value>
/// The user ids.
/// </value>
public IEnumerable<string> UserIds
{
get; set;
}
/// <summary>
/// Gets or sets the role ids.
/// </summary>
/// <value>
/// The role ids.
/// </value>
public IEnumerable<string> RoleIds
{
get; set;
}
/// <summary>
/// Gets or sets the type of the act.
/// </summary>
/// <value>
/// The type of the act.
/// </value>
public string ActType
{
get; set;
}
}
/// <summary>
///
/// </summary>
public class DiagramGroup
{
/// <summary>
/// Gets or sets the flow node ids.
/// </summary>
/// <value>
/// The flow node ids.
/// </value>
public List<string> FlowNodeIds { get; set; } = new List<string>();
}
}

View File

@@ -0,0 +1,103 @@
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace AIStudio.Wpf.Flowchart.Models
{
public class DiagramNodeConverter : DATACreationConverter<DiagramNode>
{
protected override DiagramNode Create(Type objectType, JObject jObject)
{
//第一种方法:判断属性值来确认是哪个派生类
if (FieldExists("Type", jObject, out string type))
{
if (type == "FlowchartNode")
{
return new FlowchartNode();
}
else
{
return new DiagramNode();
}
}
else
{
return new DiagramNode();
}
//第二种方法:判断字段是否存在来确认是哪个派生类
}
private bool FieldExists(string fieldName, JObject jObject, out string entityName)
{
entityName = jObject[fieldName] == null ? "" : jObject[fieldName].ToString();
return jObject[fieldName] != null;
}
}
public class DiagramLinkConverter : DATACreationConverter<DiagramLink>
{
protected override DiagramLink Create(Type objectType, JObject jObject)
{
//第一种方法:判断属性值来确认是哪个派生类
if (FieldExists("Type", jObject, out string type))
{
return new DiagramLink();
}
else
{
return new DiagramLink();
}
//第二种方法:判断字段是否存在来确认是哪个派生类
}
private bool FieldExists(string fieldName, JObject jObject, out string entityName)
{
entityName = jObject[fieldName] == null ? "" : jObject[fieldName].ToString();
return jObject[fieldName] != null;
}
}
public abstract class DATACreationConverter<T> : JsonConverter
{
/// <summary>
/// Create an instance of objectType, based properties in the JSON object
/// </summary>
/// <param name="objectType">type of object expected</param>
/// <param name="jObject">
/// contents of JSON object that will be deserialized
/// </param>
/// <returns></returns>
protected abstract T Create(Type objectType, JObject jObject);
public override bool CanConvert(Type objectType)
{
return typeof(T).IsAssignableFrom(objectType);
}
public override object ReadJson(JsonReader reader,
Type objectType,
object existingValue,
JsonSerializer serializer)
{
// Load JObject from stream
JObject jObject = JObject.Load(reader);
// Create target object based on JObject
T target = Create(objectType, jObject);
// Populate the object properties
serializer.Populate(jObject.CreateReader(), target);
return target;
}
public override void WriteJson(JsonWriter writer,
object value,
JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,244 @@
using System;
using System.Collections.Generic;
using System.Text;
using AIStudio.Wpf.DiagramDesigner;
using Newtonsoft.Json;
using System.Linq;
using System.Windows.Media;
using AIStudio.Wpf.Flowchart.ViewModels;
namespace AIStudio.Wpf.Flowchart.Models
{
public static class DiagramDataExtention
{
#region ToJson
public static string ToJson(this IDiagramViewModel diagram)
{
var json = JsonConvert.SerializeObject(new {
Nodes = diagram.Items.OfType<DesignerItemViewModelBase>().Select(p => p.ToDiagramNode()),
Links = diagram.Items.OfType<ConnectorViewModel>().Select(p => p.ToDiagramLink())
}, new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
});
return json;
}
public static DiagramNode ToDiagramNode(this DesignerItemViewModelBase nodeModel)
{
DiagramNode diagramNode;
if (nodeModel is FlowNode flowNode)
{
var flowchartNode = new FlowchartNode();
diagramNode = flowchartNode;
diagramNode.Name = flowNode.Name;
flowchartNode.Color = flowNode.Color;
flowchartNode.Kind = flowNode.Kind;
if (nodeModel is MiddleFlowNode middleflowNode)
{
flowchartNode.UserIds = middleflowNode.UserIds;
flowchartNode.RoleIds = middleflowNode.RoleIds;
flowchartNode.ActType = middleflowNode.ActType;
}
}
else
{
diagramNode = new DiagramNode();
}
diagramNode.Id = nodeModel.Id.ToString();
diagramNode.Label = nodeModel.Text;
diagramNode.Width = nodeModel.ItemWidth * nodeModel.Parent.ScreenScale;
diagramNode.Height = nodeModel.ItemHeight * nodeModel.Parent.ScreenScale;
diagramNode.X = nodeModel.Left * nodeModel.Parent.ScreenScale;
diagramNode.Y = nodeModel.Top * nodeModel.Parent.ScreenScale;
diagramNode.ZIndex = nodeModel.ZIndex;
diagramNode.Type = diagramNode.GetType().Name;
diagramNode.PortAlignmentList = nodeModel.Connectors.Select(p => p.Orientation.ToString()).ToList();
return diagramNode;
}
public static DiagramLink ToDiagramLink(this ConnectorViewModel linkModel)
{
DiagramLink diagramLink = new DiagramLink();
diagramLink.Id = linkModel.Id.ToString();
diagramLink.Color = SerializeHelper.SerializeColor(linkModel.ColorViewModel.LineColor.Color);
diagramLink.SelectedColor = SerializeHelper.SerializeColor(Colors.Black);
diagramLink.Width = linkModel.ColorViewModel.LineWidth;
if (linkModel.SinkConnectorInfo is FullyCreatedConnectorInfo sinkConnector)
{
diagramLink.SourceId = linkModel.SourceConnectorInfo.DataItem.Id.ToString();
diagramLink.TargetId = sinkConnector.DataItem.Id.ToString();
//线条形状与箭头待处理
//diagramLink.Router = baseLinkModel.Router?.Method.Name;
//diagramLink.PathGenerator = baseLinkModel.PathGenerator?.Method.Name;
//diagramLink.SourceMarkerPath = baseLinkModel.SourceMarker?.Path;
//diagramLink.SourceMarkerWidth = baseLinkModel.SourceMarker?.Width;
//diagramLink.TargetMarkerPath = baseLinkModel.TargetMarker?.Path;
//diagramLink.TargetMarkerWidth = baseLinkModel.TargetMarker?.Width;
diagramLink.Type = diagramLink.GetType().Name;
diagramLink.SourcePortAlignment = linkModel.SourceConnectorInfo.Orientation.ToString();
diagramLink.TargetPortAlignment = sinkConnector.Orientation.ToString();
}
return diagramLink;
}
#endregion
#region ToObject
public static void ToObject(this IDiagramViewModel diagram, string json)
{
var data = JsonConvert.DeserializeObject<DiagramData>(json, new JsonConverter[] { new DiagramNodeConverter(), new DiagramLinkConverter() });
if (data != null)
{
ToObject(diagram, data);
}
}
public static void ToObject(this IDiagramViewModel diagram, DiagramData data)
{
diagram.Items.Clear();
List<DesignerItemViewModelBase> nodes = new List<DesignerItemViewModelBase>();
if (data.Nodes != null)
{
foreach (var node in data.Nodes)
{
var nodemodel = node.ToNodelModel(diagram);
nodes.Add(nodemodel);
diagram.Items.Add(nodemodel);
}
}
if (data.Links != null)
{
foreach (var link in data.Links)
{
var source = nodes.FirstOrDefault(p => p.Id == new Guid(link.SourceId));
var target = nodes.FirstOrDefault(p => p.Id == new Guid(link.TargetId));
var linkmodel = link.ToLinkModel(diagram, source, target);
diagram.Items.Add(linkmodel);
}
}
}
private static DesignerItemViewModelBase ToNodelModel(this DiagramNode diagramNode, IDiagramViewModel diagram)
{
DesignerItemViewModelBase nodeModel;
if (diagramNode is FlowchartNode flowchartNode)
{
FlowNode flowNode = null;
switch (flowchartNode.Kind)
{
case NodeKinds.Start:
{
var flowchartNodelModel = new StartFlowNode();
flowNode = flowchartNodelModel;
break;
}
case NodeKinds.End:
{
var flowchartNodelModel = new EndFlowNode();
flowNode = flowchartNodelModel;
break;
}
case NodeKinds.Decide:
{
var flowchartNodelModel = new DecideFlowNode();
flowNode = flowchartNodelModel;
break;
}
case NodeKinds.COBegin:
{
var flowchartNodelModel = new COBeginFlowNode();
flowNode = flowchartNodelModel;
break;
}
case NodeKinds.COEnd:
{
var flowchartNodelModel = new COEndFlowNode();
flowNode = flowchartNodelModel;
break;
}
case NodeKinds.Middle:
{
var flowchartNodelModel = new MiddleFlowNode();
flowNode = flowchartNodelModel;
flowchartNodelModel.UserIds = flowchartNode.UserIds?.ToList();
flowchartNodelModel.RoleIds = flowchartNode.RoleIds?.ToList();
flowchartNodelModel.ActType = flowchartNode.ActType;
break;
}
default:
{
var flowNodelModel = new FlowNode(NodeKinds.Normal);
flowNode = flowNodelModel;
break;
}
}
nodeModel = flowNode;
flowNode.Name = flowchartNode.Name;
flowNode.Color = flowchartNode.Color;
flowNode.Kind = flowchartNode.Kind;
}
else
{
nodeModel = new TextDesignerItemViewModel();
}
nodeModel.Id = new Guid(diagramNode.Id);
nodeModel.Parent = diagram;
nodeModel.Text = diagramNode.Label;
nodeModel.ItemWidth = diagramNode.Width / diagram.ScreenScale;
nodeModel.ItemHeight = diagramNode.Height / diagram.ScreenScale;
nodeModel.Left = diagramNode.X / diagram.ScreenScale;
nodeModel.Top = diagramNode.Y / diagram.ScreenScale;
nodeModel.ZIndex = diagramNode.ZIndex;
diagramNode.PortAlignmentList?.ForEach(p => nodeModel.AddConnector(new FullyCreatedConnectorInfo(nodeModel, p.ToEnum<ConnectorOrientation>())));
return nodeModel;
}
public static ConnectorViewModel ToLinkModel(this DiagramLink diagramLink, IDiagramViewModel diagram, DesignerItemViewModelBase sourceNode, DesignerItemViewModelBase targetNode)
{
FullyCreatedConnectorInfo sourceConnectorInfo = sourceNode.Connectors.FirstOrDefault(p => p.Orientation.ToString() == diagramLink.SourcePortAlignment);
FullyCreatedConnectorInfo sinkConnectorInfo = targetNode.Connectors.FirstOrDefault(p => p.Orientation.ToString() == diagramLink.TargetPortAlignment);
ConnectorViewModel linkModel = new ConnectorViewModel(sourceConnectorInfo, sinkConnectorInfo, diagram.VectorLineDrawMode ?? DrawMode.BoundaryConnectingLine);
linkModel.ColorViewModel.LineColor.Color = SerializeHelper.DeserializeColor(diagramLink.Color);
linkModel.ColorViewModel.LineWidth = diagramLink.Width;
//线条形状与箭头待处理
//switch (diagramLink.Router)
//{
// case "Normal": linkModel.Router = Routers.Normal; break;
// case "Orthogonal": linkModel.Router = Routers.Orthogonal; break;
//}
//switch (diagramLink.PathGenerator)
//{
// case "Smooth": linkModel.PathGenerator = PathGenerators.Smooth; break;
// case "Straight": linkModel.PathGenerator = PathGenerators.Straight; break;
//}
//if (!string.IsNullOrEmpty(diagramLink.SourceMarkerPath))
//{
// linkModel.SourceMarker = new LinkMarker(diagramLink.SourceMarkerPath, diagramLink.SourceMarkerWidth ?? 10.0);
//}
//if (!string.IsNullOrEmpty(diagramLink.TargetMarkerPath))
//{
// linkModel.TargetMarker = new LinkMarker(diagramLink.TargetMarkerPath, diagramLink.TargetMarkerWidth ?? 10.0);
//}
return linkModel;
}
#endregion
}
}

View File

@@ -1,29 +0,0 @@
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

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Media;
using AIStudio.Wpf.DiagramDesigner;
using AIStudio.Wpf.DiagramDesigner.Helpers;
@@ -14,7 +15,7 @@ namespace AIStudio.Wpf.Flowchart.Models
get; set;
}
public FlowchartToolBoxData(NodeKinds kind, Type type, double width = 32, double height = 32) : base(kind.GetDescription(), null, type, width, height)
public FlowchartToolBoxData(NodeKinds kind, Type type, double width, double height, Size? desiredSize) : base(kind.GetDescription(), null, type, width, height, desiredSize)
{
Kind = kind;
ColorViewModel.LineColor.Color = Colors.Black;

View File

@@ -15,9 +15,6 @@ namespace AIStudio.Wpf.Flowchart.ViewModels
{
Kind = kind;
Text = Kind.GetDescription();
ItemWidth = 80;
ItemHeight = 40;
}
public FlowNode(IDiagramViewModel parent, DesignerItemBase designer) : base(parent, designer)
@@ -70,6 +67,9 @@ namespace AIStudio.Wpf.Flowchart.ViewModels
[Browsable(false)]
public string StateImage { get; set; }
[Browsable(true)]
public string Name{ get; set; }
#region 使,
private int _status;
@@ -102,7 +102,8 @@ namespace AIStudio.Wpf.Flowchart.ViewModels
get
{
return new Dictionary<string, string>()
{
{
{ "Name","名称" },
{ "Text","文本" },
};
}

View File

@@ -87,6 +87,7 @@ namespace AIStudio.Wpf.Flowchart.ViewModels
{
return new Dictionary<string, string>()
{
{ "Name","名称" },
{ "Text","文本" },
{"UserIds", "用户" },
{"RoleIds", "角色" },

View File

@@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Media;
using AIStudio.Wpf.DiagramDesigner;
using AIStudio.Wpf.DiagramDesigner.Helpers;
using AIStudio.Wpf.Flowchart;
using AIStudio.Wpf.Flowchart.Models;
@@ -15,12 +17,13 @@ namespace AIStudio.Wpf.Flowchart.ViewModels
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));
var screenScale = ScreenHelper.ResetScreenScale();
toolBoxItems.Add(new FlowchartToolBoxData(NodeKinds.Start, typeof(StartFlowNode), 80, 60, new Size(100 / screenScale, 80/ screenScale)));
toolBoxItems.Add(new FlowchartToolBoxData(NodeKinds.End, typeof(EndFlowNode), 80, 60, new Size(100 / screenScale, 80 / screenScale)));
toolBoxItems.Add(new FlowchartToolBoxData(NodeKinds.Middle, typeof(MiddleFlowNode), 80, 60, new Size(100 / screenScale, 80 / screenScale)));
toolBoxItems.Add(new FlowchartToolBoxData(NodeKinds.Decide, typeof(DecideFlowNode), 80, 60, new Size(100 / screenScale, 80 / screenScale)));
toolBoxItems.Add(new FlowchartToolBoxData(NodeKinds.COBegin, typeof(COBeginFlowNode), 80, 60, new Size(100 / screenScale, 80 / screenScale)));
toolBoxItems.Add(new FlowchartToolBoxData(NodeKinds.COEnd, typeof(COEndFlowNode), 80, 60, new Size(100 / screenScale, 80 / screenScale)));
}
public List<ToolBoxData> ToolBoxItems