diff --git a/AIStudio.Wpf.DiagramDesigner.Additionals/Extensions/ViewModels/BarcodeDesignerItemViewModel.cs b/AIStudio.Wpf.DiagramDesigner.Additionals/Extensions/ViewModels/BarcodeDesignerItemViewModel.cs index b76a5e2..b06cfd6 100644 --- a/AIStudio.Wpf.DiagramDesigner.Additionals/Extensions/ViewModels/BarcodeDesignerItemViewModel.cs +++ b/AIStudio.Wpf.DiagramDesigner.Additionals/Extensions/ViewModels/BarcodeDesignerItemViewModel.cs @@ -37,8 +37,10 @@ namespace AIStudio.Wpf.DiagramDesigner.Additionals.Extensions.ViewModels protected override void Init(IDiagramViewModel root) { base.Init(root); - visualiserService = ApplicationServicesProvider.Instance.Provider.VisualizerService; + CustomText = true; + + visualiserService = ApplicationServicesProvider.Instance.Provider.VisualizerService; } protected override void LoadDesignerItemViewModel(SelectableItemBase designerbase) @@ -71,19 +73,6 @@ namespace AIStudio.Wpf.DiagramDesigner.Additionals.Extensions.ViewModels public BarcodeFormat Format { get; set; } = BarcodeFormat.QR_CODE; - private bool _showText; - public override bool ShowText - { - get - { - return false; - } - set - { - SetProperty(ref _showText, value); - } - } - public override bool EditData() { if (IsReadOnly == true) return false; diff --git a/AIStudio.Wpf.DiagramDesigner.Demo/MainWindow.xaml.cs b/AIStudio.Wpf.DiagramDesigner.Demo/MainWindow.xaml.cs index e983a4e..82f14aa 100644 --- a/AIStudio.Wpf.DiagramDesigner.Demo/MainWindow.xaml.cs +++ b/AIStudio.Wpf.DiagramDesigner.Demo/MainWindow.xaml.cs @@ -70,6 +70,12 @@ namespace AIStudio.Wpf.DiagramDesigner.Demo new MenuItemViewModel(){Title = "Routers"}, new MenuItemViewModel(){Title = "PathGenerators"}, } + }, + new MenuItemViewModel(){Title = "Ports", + Children=new List + { + new MenuItemViewModel(){Title = "ColoredPort"}, + } }, new MenuItemViewModel(){Title = "Groups", Children=new List diff --git a/AIStudio.Wpf.DiagramDesigner.Demo/ViewModels/Ports/ColoredPortViewModel.cs b/AIStudio.Wpf.DiagramDesigner.Demo/ViewModels/Ports/ColoredPortViewModel.cs new file mode 100644 index 0000000..a27acb6 --- /dev/null +++ b/AIStudio.Wpf.DiagramDesigner.Demo/ViewModels/Ports/ColoredPortViewModel.cs @@ -0,0 +1,85 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows; +using System.Windows.Media; +using AIStudio.Wpf.DiagramDesigner.Models; + +namespace AIStudio.Wpf.DiagramDesigner.Demo.ViewModels +{ + class ColoredPortViewModel : BaseViewModel + { + public ColoredPortViewModel() + { + Title = "Custom port"; + Info = "Creating your own custom ports is very easy!" + + "In this example, you can only attach links from/to ports with the same color."; + + DiagramViewModel = new DiagramViewModel(); + DiagramViewModel.PageSizeType = PageSizeType.Custom; + DiagramViewModel.PageSize = new Size(double.NaN, double.NaN); + DiagramViewModel.ColorViewModel = new ColorViewModel(); + DiagramViewModel.ColorViewModel.FillColor.Color = System.Windows.Media.Colors.Orange; + + DefaultDesignerItemViewModel node1 = new DefaultDesignerItemViewModel(DiagramViewModel) { Left = 50, Top = 50, Text = "1" }; + node1.ClearConnectors(); + node1.AddConnector(new ColoredPortConnectorInfo(DiagramViewModel, node1, ConnectorOrientation.Top, Colors.Red)); + node1.AddConnector(new ColoredPortConnectorInfo(DiagramViewModel, node1, ConnectorOrientation.Bottom, Colors.Red)); + node1.AddConnector(new ColoredPortConnectorInfo(DiagramViewModel, node1, ConnectorOrientation.Left, Colors.Green)); + node1.AddConnector(new ColoredPortConnectorInfo(DiagramViewModel, node1, ConnectorOrientation.Right, Colors.Green)); + DiagramViewModel.DirectAddItemCommand.Execute(node1); + + DefaultDesignerItemViewModel node2 = new DefaultDesignerItemViewModel(DiagramViewModel) { Left = 300, Top = 300, Text = "2" }; + node2.ClearConnectors(); + node2.AddConnector(new ColoredPortConnectorInfo(DiagramViewModel, node2, ConnectorOrientation.Top, Colors.Red)); + node2.AddConnector(new ColoredPortConnectorInfo(DiagramViewModel, node2, ConnectorOrientation.Bottom, Colors.Red)); + node2.AddConnector(new ColoredPortConnectorInfo(DiagramViewModel, node2, ConnectorOrientation.Left, Colors.Green)); + node2.AddConnector(new ColoredPortConnectorInfo(DiagramViewModel, node2, ConnectorOrientation.Right, Colors.Green)); + DiagramViewModel.DirectAddItemCommand.Execute(node2); + + DefaultDesignerItemViewModel node3 = new DefaultDesignerItemViewModel(DiagramViewModel) { Left = 300, Top = 50, Text = "3" }; + node3.ClearConnectors(); + node3.AddConnector(new ColoredPortConnectorInfo(DiagramViewModel, node3, ConnectorOrientation.Top, Colors.Red)); + node3.AddConnector(new ColoredPortConnectorInfo(DiagramViewModel, node3, ConnectorOrientation.Bottom, Colors.Red)); + node3.AddConnector(new ColoredPortConnectorInfo(DiagramViewModel, node3, ConnectorOrientation.Left, Colors.Green)); + node3.AddConnector(new ColoredPortConnectorInfo(DiagramViewModel, node3, ConnectorOrientation.Right, Colors.Green)); DiagramViewModel.DirectAddItemCommand.Execute(node3); + + DiagramViewModel.ClearSelectedItemsCommand.Execute(null); + } + } + + public class ColoredPortConnectorInfo : FullyCreatedConnectorInfo + { + public ColoredPortConnectorInfo(DesignerItemViewModelBase dataItem, ConnectorOrientation orientation, Color color, bool isInnerPoint = false, bool isPortless = false) : base(dataItem, orientation, isInnerPoint, isPortless) + { + ColorViewModel.FillColor.Color = color; + } + + public ColoredPortConnectorInfo(IDiagramViewModel root, DesignerItemViewModelBase dataItem, ConnectorOrientation orientation, Color color, bool isInnerPoint = false, bool isPortless = false) : base(root, dataItem, orientation, isInnerPoint, isPortless) + { + ColorViewModel.FillColor.Color = color; + } + + public ColoredPortConnectorInfo(IDiagramViewModel root, DesignerItemViewModelBase dataItem, SelectableItemBase designer) : base(root, dataItem, designer) + { + } + + public ColoredPortConnectorInfo(IDiagramViewModel root, DesignerItemViewModelBase dataItem, SerializableItem serializableItem, string serializableType) : base(root, dataItem, serializableItem, serializableType) + { + } + + public override bool CanAttachTo(FullyCreatedConnectorInfo port) + { + // Checks for same-node/port attachements + if (!base.CanAttachTo(port)) + return false; + + // Only able to attach to the same port type + if (!(port is ColoredPortConnectorInfo cp)) + return false; + + return ColorViewModel.FillColor.Color == cp.ColorViewModel.FillColor.Color;// 颜色一样才能连接 + } + + } +} diff --git a/AIStudio.Wpf.DiagramDesigner.Demo/Views/Ports/ColoredPortView.xaml b/AIStudio.Wpf.DiagramDesigner.Demo/Views/Ports/ColoredPortView.xaml new file mode 100644 index 0000000..d31facf --- /dev/null +++ b/AIStudio.Wpf.DiagramDesigner.Demo/Views/Ports/ColoredPortView.xaml @@ -0,0 +1,16 @@ + + + + + + + + diff --git a/AIStudio.Wpf.DiagramDesigner.Demo/Views/Ports/ColoredPortView.xaml.cs b/AIStudio.Wpf.DiagramDesigner.Demo/Views/Ports/ColoredPortView.xaml.cs new file mode 100644 index 0000000..3503e7b --- /dev/null +++ b/AIStudio.Wpf.DiagramDesigner.Demo/Views/Ports/ColoredPortView.xaml.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +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; + +namespace AIStudio.Wpf.DiagramDesigner.Demo.Views +{ + /// + /// ColoredPort.xaml 的交互逻辑 + /// + public partial class ColoredPortView : UserControl + { + public ColoredPortView() + { + InitializeComponent(); + } + } +} diff --git a/AIStudio.Wpf.DiagramDesigner/AIStudio.Wpf.DiagramDesigner_5labitf3_wpftmp.csproj b/AIStudio.Wpf.DiagramDesigner/AIStudio.Wpf.DiagramDesigner_5labitf3_wpftmp.csproj new file mode 100644 index 0000000..67a15f9 --- /dev/null +++ b/AIStudio.Wpf.DiagramDesigner/AIStudio.Wpf.DiagramDesigner_5labitf3_wpftmp.csproj @@ -0,0 +1,267 @@ + + + AIStudio.Wpf.DiagramDesigner + obj\Debug\ + obj\ + F:\aistudio.-wpf.-diagram\AIStudio.Wpf.DiagramDesigner\obj\ + <_TargetAssemblyProjectName>AIStudio.Wpf.DiagramDesigner + + + + true + AIStudio.Wpf.Controls + akwkevin + https://gitee.com/akwkevin + A.png + + + 1.0.4 + 一个Wpf的Diagram控件基础库 + + + + + + True + + + + + + + + + + + + + + + + + + + PreserveNewest + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/AIStudio.Wpf.DiagramDesigner/Controls/DesignerCanvas.cs b/AIStudio.Wpf.DiagramDesigner/Controls/DesignerCanvas.cs index 37cf4ed..5b8ce9c 100644 --- a/AIStudio.Wpf.DiagramDesigner/Controls/DesignerCanvas.cs +++ b/AIStudio.Wpf.DiagramDesigner/Controls/DesignerCanvas.cs @@ -539,14 +539,17 @@ namespace AIStudio.Wpf.DiagramDesigner while (hitObject != null && hitObject.GetType() != typeof(DesignerCanvas)) { - if (hitObject is Connector) + if (hitObject is Connector connector && connector.Info != null) { - if (connectorsHit.Any(p => p.Name == "占位")) + if (SourceConnector == null || connector.Info.CanAttachTo(SourceConnector.Info)) { - connectorsHit.Remove(connectorsHit.FirstOrDefault(p => p.Name == "占位")); + if (connectorsHit.Any(p => p.Name == "占位")) + { + connectorsHit.Remove(connectorsHit.FirstOrDefault(p => p.Name == "占位")); + } + if (!connectorsHit.Contains(hitObject as Connector)) + connectorsHit.Add(hitObject as Connector); } - if (!connectorsHit.Contains(hitObject as Connector)) - connectorsHit.Add(hitObject as Connector); } hitObject = VisualTreeHelper.GetParent(hitObject); } diff --git a/AIStudio.Wpf.DiagramDesigner/UserControls/DiagramControl.xaml b/AIStudio.Wpf.DiagramDesigner/UserControls/DiagramControl.xaml index 683fcd3..b2e3ca1 100644 --- a/AIStudio.Wpf.DiagramDesigner/UserControls/DiagramControl.xaml +++ b/AIStudio.Wpf.DiagramDesigner/UserControls/DiagramControl.xaml @@ -392,6 +392,15 @@ + + + + + + + + + diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/Connector/ConnectorLabelModel.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/Connector/ConnectorLabelModel.cs index 1dd224c..8552004 100644 --- a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/Connector/ConnectorLabelModel.cs +++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/Connector/ConnectorLabelModel.cs @@ -82,27 +82,6 @@ namespace AIStudio.Wpf.DiagramDesigner get; set; } - private bool _isSelected; - public override bool IsSelected - { - get - { - return _isSelected; - } - set - { - if (SetProperty(ref _isSelected, value)) - { - //如果没有文字,失去焦点自动清除 - if (_isSelected == false && string.IsNullOrEmpty(Text)) - { - Connector.Labels.Remove(this); - } - } - - } - } - public SimpleCommand DeleteLabelCommand { get; set; @@ -196,6 +175,11 @@ namespace AIStudio.Wpf.DiagramDesigner } } + protected override void ClearText() + { + Connector.Labels.Remove(this); + } + private void DeleteLabel(object parameter) { if (parameter is ConnectorLabelModel label) diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/Connector/FullyCreatedConnectorInfo.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/Connector/FullyCreatedConnectorInfo.cs index 89c289c..1c41c82 100644 --- a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/Connector/FullyCreatedConnectorInfo.cs +++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/Connector/FullyCreatedConnectorInfo.cs @@ -10,12 +10,12 @@ namespace AIStudio.Wpf.DiagramDesigner { public class FullyCreatedConnectorInfo : ConnectorInfoBase { - public FullyCreatedConnectorInfo(DesignerItemViewModelBase dataItem, ConnectorOrientation orientation, bool isInnerPoint = false, bool isPortless = false, ValueTypePoint valueTypePoint = 0) - : this(null, dataItem, orientation, isInnerPoint, isPortless, valueTypePoint) + public FullyCreatedConnectorInfo(DesignerItemViewModelBase dataItem, ConnectorOrientation orientation, bool isInnerPoint = false, bool isPortless = false) + : this(null, dataItem, orientation, isInnerPoint, isPortless) { } - public FullyCreatedConnectorInfo(IDiagramViewModel root, DesignerItemViewModelBase dataItem, ConnectorOrientation orientation, bool isInnerPoint = false, bool isPortless = false, ValueTypePoint valueTypePoint = 0) + public FullyCreatedConnectorInfo(IDiagramViewModel root, DesignerItemViewModelBase dataItem, ConnectorOrientation orientation, bool isInnerPoint = false, bool isPortless = false) : base(root, orientation) { this.Parent = dataItem; diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/Connector/LogicalConnectorInfo.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/Connector/LogicalConnectorInfo.cs index f23363f..9faacdc 100644 --- a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/Connector/LogicalConnectorInfo.cs +++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/Connector/LogicalConnectorInfo.cs @@ -7,11 +7,12 @@ namespace AIStudio.Wpf.DiagramDesigner { public class LogicalConnectorInfo : FullyCreatedConnectorInfo { - public LogicalConnectorInfo(DesignerItemViewModelBase dataItem, ConnectorOrientation orientation, bool isInnerPoint = false, bool isPortless = false, ValueTypePoint valueTypePoint = ValueTypePoint.Real) : base(dataItem, orientation, isInnerPoint, isPortless, valueTypePoint) + public LogicalConnectorInfo(DesignerItemViewModelBase dataItem, ConnectorOrientation orientation, bool isInnerPoint = false, bool isPortless = false, ValueTypePoint valueTypePoint = ValueTypePoint.Real) : base(dataItem, orientation, isInnerPoint, isPortless) { + this.ValueTypePoint = valueTypePoint; } - public LogicalConnectorInfo(IDiagramViewModel root, DesignerItemViewModelBase dataItem, ConnectorOrientation orientation, bool isInnerPoint = false, bool isPortless = false, ValueTypePoint valueTypePoint = ValueTypePoint.Real) : base(root, dataItem, orientation, isInnerPoint, isPortless, valueTypePoint) + public LogicalConnectorInfo(IDiagramViewModel root, DesignerItemViewModelBase dataItem, ConnectorOrientation orientation, bool isInnerPoint = false, bool isPortless = false, ValueTypePoint valueTypePoint = ValueTypePoint.Real) : base(root, dataItem, orientation, isInnerPoint, isPortless) { this.ValueTypePoint = valueTypePoint; } diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/SelectableDesignerItemViewModelBase.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/SelectableDesignerItemViewModelBase.cs index b135a17..f5ce8c3 100644 --- a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/SelectableDesignerItemViewModelBase.cs +++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/SelectableDesignerItemViewModelBase.cs @@ -73,55 +73,6 @@ namespace AIStudio.Wpf.DiagramDesigner get; private set; } - private bool _isSelected; - [Browsable(false)] - public override bool IsSelected - { - get - { - return _isSelected; - } - set - { - if (SetProperty(ref _isSelected, value)) - { - //如果没有文字,失去焦点自动清除 - if (_isSelected == false && string.IsNullOrEmpty(Text)) - { - ShowText = false; - } - } - - } - } - - private string _text; - [Browsable(true)] - [CanDo] - public override string Text - { - get - { - var text = _text; - if (FontViewModel.FontCase == FontCase.Upper) - { - return text?.ToUpper(); - } - else if (FontViewModel.FontCase == FontCase.Lower) - { - return text?.ToLower(); - } - else - { - return text; - } - } - set - { - SetProperty(ref _text, value); - } - } - private bool _isReadOnlyText = false; public bool IsReadOnlyText { @@ -137,8 +88,22 @@ namespace AIStudio.Wpf.DiagramDesigner } } + //自己定义文本显示,文本框不显示 + private bool _customText = false; + public bool CustomText + { + get + { + return _customText; + } + set + { + SetProperty(ref _customText, value); + } + } + private bool _showText; - public virtual bool ShowText + public bool ShowText { get { @@ -153,6 +118,11 @@ namespace AIStudio.Wpf.DiagramDesigner } } + protected override void ClearText() + { + ShowText = false; + } + private void ExecuteSelectItemCommand(object param) { SelectItem((bool)param, !IsSelected); @@ -164,7 +134,7 @@ namespace AIStudio.Wpf.DiagramDesigner { foreach (var designerItemViewModelBase in Root.SelectedItems.ToList()) { - designerItemViewModelBase._isSelected = false; + designerItemViewModelBase.ClearSelected(); } } diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/SelectableViewModelBase.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/SelectableViewModelBase.cs index f84703a..6a7580d 100644 --- a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/SelectableViewModelBase.cs +++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/SelectableViewModelBase.cs @@ -146,7 +146,7 @@ namespace AIStudio.Wpf.DiagramDesigner private bool _isSelected; [Browsable(false)] - public virtual bool IsSelected + public bool IsSelected { get { @@ -154,7 +154,14 @@ namespace AIStudio.Wpf.DiagramDesigner } set { - SetProperty(ref _isSelected, value); + if (SetProperty(ref _isSelected, value)) + { + //如果没有文字,失去焦点自动清除 + if (_isSelected == false && string.IsNullOrEmpty(Text)) + { + ClearText(); + } + } } } @@ -298,6 +305,16 @@ namespace AIStudio.Wpf.DiagramDesigner } + protected virtual void ClearText() + { + + } + + public virtual void ClearSelected() + { + _isSelected = false; + } + public virtual void AddToSelection(bool selected) { diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/SimpleViewModel/TextDesignerItemViewModel.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/SimpleViewModel/TextDesignerItemViewModel.cs index ad3fb84..bd1bc40 100644 --- a/AIStudio.Wpf.DiagramDesigner/ViewModels/SimpleViewModel/TextDesignerItemViewModel.cs +++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/SimpleViewModel/TextDesignerItemViewModel.cs @@ -36,6 +36,8 @@ namespace AIStudio.Wpf.DiagramDesigner { base.Init(root); + CustomText = true; + this.ItemWidth = 150; this.ClearConnectors(); } @@ -57,19 +59,5 @@ namespace AIStudio.Wpf.DiagramDesigner SetProperty(ref _watermark, value); } } - - //固定在DataTemplate中处理 - private bool _showText; - public override bool ShowText - { - get - { - return false; - } - set - { - SetProperty(ref _showText, value); - } - } } } diff --git a/AIStudio.Wpf.SFC/ViewModels/SFCConditionNode.cs b/AIStudio.Wpf.SFC/ViewModels/SFCConditionNode.cs index 4860eda..63f1d45 100644 --- a/AIStudio.Wpf.SFC/ViewModels/SFCConditionNode.cs +++ b/AIStudio.Wpf.SFC/ViewModels/SFCConditionNode.cs @@ -38,19 +38,7 @@ namespace AIStudio.Wpf.SFC.ViewModels protected override void Init(IDiagramViewModel root) { base.Init(root); - } - - private bool _showText; - public override bool ShowText - { - get - { - return false; - } - set - { - SetProperty(ref _showText, value); - } + CustomText = true; } private ObservableCollection _linkPoint = new ObservableCollection(); diff --git a/AIStudio.Wpf.SFC/ViewModels/Simulate_SolenoidViewModel.cs b/AIStudio.Wpf.SFC/ViewModels/Simulate_SolenoidViewModel.cs index 7bc530c..f3df464 100644 --- a/AIStudio.Wpf.SFC/ViewModels/Simulate_SolenoidViewModel.cs +++ b/AIStudio.Wpf.SFC/ViewModels/Simulate_SolenoidViewModel.cs @@ -37,6 +37,8 @@ namespace AIStudio.Wpf.SFC.ViewModels protected override void Init(IDiagramViewModel root) { base.Init(root); + CustomText = true; + if (diChangedSubscription != null) { diChangedSubscription.Dispose(); @@ -45,19 +47,6 @@ namespace AIStudio.Wpf.SFC.ViewModels diChangedSubscription = WhenPropertyChanged.Where(o => o.ToString() == "Value").Throttle(TimeSpan.FromSeconds(random.Next(1,10))).Subscribe(OnValueChanged);//Sample } - private bool _showText; - public override bool ShowText - { - get - { - return false; - } - set - { - SetProperty(ref _showText, value); - } - } - /// /// 输入 ///