diff --git a/AIStudio.Wpf.DiagramApp/AIStudio.Wpf.DiagramApp_bypphsza_wpftmp.csproj b/AIStudio.Wpf.DiagramApp/AIStudio.Wpf.DiagramApp_bypphsza_wpftmp.csproj new file mode 100644 index 0000000..7163875 --- /dev/null +++ b/AIStudio.Wpf.DiagramApp/AIStudio.Wpf.DiagramApp_bypphsza_wpftmp.csproj @@ -0,0 +1,1040 @@ + + + AIStudio.Wpf.DiagramApp + obj\Debug\ + obj\ + F:\aistudio.-wpf.-diagram\AIStudio.Wpf.DiagramApp\obj\ + <_TargetAssemblyProjectName>AIStudio.Wpf.DiagramApp + + + + WinExe + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + 8.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/AIStudio.Wpf.DiagramApp/ViewModels/MindViewModel.cs b/AIStudio.Wpf.DiagramApp/ViewModels/MindViewModel.cs index 8cb473d..4695b61 100644 --- a/AIStudio.Wpf.DiagramApp/ViewModels/MindViewModel.cs +++ b/AIStudio.Wpf.DiagramApp/ViewModels/MindViewModel.cs @@ -22,15 +22,20 @@ namespace AIStudio.Wpf.DiagramApp.ViewModels { public MindViewModel(string title, string status, DiagramType diagramType, MindType mindType) : base(title, status, diagramType, mindType.ToString()) { - + } public MindViewModel(string filename, DiagramDocument diagramDocument) : base(filename, diagramDocument) { + + } + + protected override void OpenFile(DiagramDocument diagramDocument, string ext) + { + base.OpenFile(diagramDocument, ext); foreach (var vm in DiagramViewModels) { vm.Init(false); } - if (MindDiagramViewModel != null) { SubType = MindDiagramViewModel.MindType.ToString(); @@ -72,11 +77,11 @@ namespace AIStudio.Wpf.DiagramApp.ViewModels public MindTheme MindTheme { - get; + get;set; } protected override void Init(bool initNew) - { + { DiagramViewModels = new ObservableCollection() { GetDiagramViewModel("页-1", DiagramType, initNew), diff --git a/AIStudio.Wpf.DiagramApp/ViewModels/PageViewModel.cs b/AIStudio.Wpf.DiagramApp/ViewModels/PageViewModel.cs index e8ca2dc..c26fab7 100644 --- a/AIStudio.Wpf.DiagramApp/ViewModels/PageViewModel.cs +++ b/AIStudio.Wpf.DiagramApp/ViewModels/PageViewModel.cs @@ -391,39 +391,14 @@ namespace AIStudio.Wpf.DiagramApp.ViewModels List viewModels = new List(); foreach (var diagramItem in diagramDocument.DiagramItems) { - var viewModel = GetDiagramViewModel(diagramItem.Name, diagramItem.DiagramType, false); - viewModel.Init(diagramItem); - - foreach (var diagramItemData in diagramItem.DesignerItems) - { - Type type = TypeHelper.GetType(diagramItemData.ModelTypeName); - DesignerItemViewModelBase itemBase = Activator.CreateInstance(type, viewModel, diagramItemData, ext) as DesignerItemViewModelBase; - viewModel.Items.Add(itemBase); - } - - foreach (var connection in diagramItem.Connections) - { - Type type = TypeHelper.GetType(connection.SerializableTypeName); - var connectionItem = SerializeHelper.DeserializeObject(type, connection.SerializableString, ext) as ConnectionItem; - - connectionItem.SourceType = System.Type.GetType(connectionItem.SourceTypeName); - connectionItem.SinkType = System.Type.GetType(connectionItem.SinkTypeName); - DesignerItemViewModelBase sourceItem = DiagramViewModelHelper.GetConnectorDataItem(viewModel.Items, connectionItem.SourceId, connectionItem.SourceType); - ConnectorOrientation sourceConnectorOrientation = connectionItem.SourceOrientation; - FullyCreatedConnectorInfo sourceConnectorInfo = sourceItem.GetFullConnectorInfo(connectionItem.Id, sourceConnectorOrientation, connectionItem.SourceXRatio, connectionItem.SourceYRatio, connectionItem.SourceInnerPoint, connectionItem.SourceInnerPoint); - - DesignerItemViewModelBase sinkItem = DiagramViewModelHelper.GetConnectorDataItem(viewModel.Items, connectionItem.SinkId, connectionItem.SinkType); - ConnectorOrientation sinkConnectorOrientation = connectionItem.SinkOrientation; - FullyCreatedConnectorInfo sinkConnectorInfo = sinkItem.GetFullConnectorInfo(connectionItem.Id, sinkConnectorOrientation, connectionItem.SinkXRatio, connectionItem.SinkYRatio, connectionItem.SinkInnerPoint, connectionItem.SinkInnerPoint); - - ConnectionViewModel connectionVM = new ConnectionViewModel(viewModel, sourceConnectorInfo, sinkConnectorInfo, connectionItem); - connectionVM.Id = Guid.NewGuid(); - viewModel.Items.Add(connectionVM); - } - + var viewModel = GetDiagramViewModel(diagramItem, ext); viewModels.Add(viewModel); } DiagramViewModels = new ObservableCollection(viewModels); + foreach (var vm in DiagramViewModels) + { + vm.Init(false); + } DiagramViewModel = DiagramViewModels.FirstOrDefault(); } @@ -455,15 +430,7 @@ namespace AIStudio.Wpf.DiagramApp.ViewModels foreach (var viewModel in DiagramViewModels) { - DiagramItem diagramItem = new DiagramItem(viewModel); - - var selectedDesignerItems = viewModel.Items.OfType(); - var selectedConnections = viewModel.Items.OfType(); - - diagramItem.DesignerItems = selectedDesignerItems.Select(p => p.ToSerializableItem(ext)).Where(p => p != null).ToList(); - diagramItem.Connections = selectedConnections.Select(p => p.ToSerializableItem(ext)).Where(p => p != null).ToList(); - - + DiagramItem diagramItem = new DiagramItem(viewModel); diagramDocument.DiagramItems.Add(diagramItem); } @@ -498,6 +465,11 @@ namespace AIStudio.Wpf.DiagramApp.ViewModels InitDiagramViewModel(); } + protected virtual DiagramViewModel GetDiagramViewModel(DiagramItem diagramItem, string ext) + { + return new BlockDiagramViewModel(diagramItem, ext); + } + protected virtual DiagramViewModel GetDiagramViewModel(string name, DiagramType diagramType, bool initNew) { return new BlockDiagramViewModel() { Name = name ?? NewNameHelper.GetNewName(DiagramViewModels.Select(p => p.Name), "页-"), DiagramType = diagramType }; @@ -509,41 +481,9 @@ namespace AIStudio.Wpf.DiagramApp.ViewModels { var viewModel = DiagramViewModel; DiagramItem diagramItem = new DiagramItem(viewModel); + diagramItem.Name = NewNameHelper.GetNewName(DiagramViewModels.Select(p => p.Name), "页-"); - var selectedDesignerItems = viewModel.Items.OfType(); - var selectedConnections = viewModel.Items.OfType(); - - diagramItem.DesignerItems = selectedDesignerItems.Select(p => p.ToSerializableItem("json")).Where(p => p != null).ToList(); - diagramItem.Connections = selectedConnections.Select(p => p.ToSerializableItem("json")).Where(p => p != null).ToList(); - - viewModel = GetDiagramViewModel(NewNameHelper.GetNewName(DiagramViewModels.Select(p => p.Name), "页-"), diagramItem.DiagramType, false); - viewModel.Init(diagramItem); - - foreach (var diagramItemData in diagramItem.DesignerItems) - { - Type type = TypeHelper.GetType(diagramItemData.ModelTypeName); - DesignerItemViewModelBase itemBase = Activator.CreateInstance(type, viewModel, diagramItemData, "json") as DesignerItemViewModelBase; - viewModel.Items.Add(itemBase); - } - - foreach (var connection in diagramItem.Connections) - { - var connectionItem = JsonConvert.DeserializeObject(connection.SerializableString); - - connectionItem.SourceType = System.Type.GetType(connectionItem.SourceTypeName); - connectionItem.SinkType = System.Type.GetType(connectionItem.SinkTypeName); - DesignerItemViewModelBase sourceItem = DiagramViewModelHelper.GetConnectorDataItem(viewModel.Items, connectionItem.SourceId, connectionItem.SourceType); - ConnectorOrientation sourceConnectorOrientation = connectionItem.SourceOrientation; - FullyCreatedConnectorInfo sourceConnectorInfo = sourceItem.GetFullConnectorInfo(connectionItem.Id, sourceConnectorOrientation, connectionItem.SourceXRatio, connectionItem.SourceYRatio, connectionItem.SourceInnerPoint, connectionItem.SourceIsPortless); - - DesignerItemViewModelBase sinkItem = DiagramViewModelHelper.GetConnectorDataItem(viewModel.Items, connectionItem.SinkId, connectionItem.SinkType); - ConnectorOrientation sinkConnectorOrientation = connectionItem.SinkOrientation; - FullyCreatedConnectorInfo sinkConnectorInfo = sinkItem.GetFullConnectorInfo(connectionItem.Id, sinkConnectorOrientation, connectionItem.SinkXRatio, connectionItem.SinkYRatio, connectionItem.SinkInnerPoint, connectionItem.SinkIsPortless); - - ConnectionViewModel connectionVM = new ConnectionViewModel(viewModel, sourceConnectorInfo, sinkConnectorInfo, connectionItem); - connectionVM.Id = Guid.NewGuid(); - viewModel.Items.Add(connectionVM); - } + viewModel = GetDiagramViewModel(diagramItem, ".json"); DiagramViewModels.Add(viewModel); DiagramViewModel = viewModel; diff --git a/AIStudio.Wpf.DiagramApp/Views/MainWindow.xaml b/AIStudio.Wpf.DiagramApp/Views/MainWindow.xaml index 19936cc..ed9f781 100644 --- a/AIStudio.Wpf.DiagramApp/Views/MainWindow.xaml +++ b/AIStudio.Wpf.DiagramApp/Views/MainWindow.xaml @@ -2660,14 +2660,14 @@ - - + - - + + diff --git a/AIStudio.Wpf.DiagramDesigner/AIStudio.Wpf.DiagramDesigner.csproj b/AIStudio.Wpf.DiagramDesigner/AIStudio.Wpf.DiagramDesigner.csproj index 5c56737..83c64dd 100644 --- a/AIStudio.Wpf.DiagramDesigner/AIStudio.Wpf.DiagramDesigner.csproj +++ b/AIStudio.Wpf.DiagramDesigner/AIStudio.Wpf.DiagramDesigner.csproj @@ -31,6 +31,7 @@ + diff --git a/AIStudio.Wpf.DiagramDesigner/AttachedProperties/DragAndDropProps.cs b/AIStudio.Wpf.DiagramDesigner/AttachedProperties/DragAndDropProps.cs index 526f05d..8c59fdf 100644 --- a/AIStudio.Wpf.DiagramDesigner/AttachedProperties/DragAndDropProps.cs +++ b/AIStudio.Wpf.DiagramDesigner/AttachedProperties/DragAndDropProps.cs @@ -86,11 +86,11 @@ namespace AIStudio.Wpf.DiagramDesigner dataObject.Icon = toolBoxData.Icon; dataObject.Text = toolBoxData.Text; dataObject.ColorViewModel = toolBoxData.ColorViewModel; - //if (toolBoxData.Addition is DesignerItemViewModelBase designerItemViewModelBase) - //{ - // dataObject.DesignerItem = designerItemViewModelBase.ToSerializableItem(); - //} - //else + if (toolBoxData.Addition is DesignerItemViewModelBase designerItemViewModelBase) + { + dataObject.DesignerItem = designerItemViewModelBase.ToSerializableItem(); + } + else { dataObject.DesignerItem = toolBoxData.Addition; } diff --git a/AIStudio.Wpf.DiagramDesigner/Controls/DesignerCanvas.cs b/AIStudio.Wpf.DiagramDesigner/Controls/DesignerCanvas.cs index eaf0582..715a65a 100644 --- a/AIStudio.Wpf.DiagramDesigner/Controls/DesignerCanvas.cs +++ b/AIStudio.Wpf.DiagramDesigner/Controls/DesignerCanvas.cs @@ -6,6 +6,7 @@ using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Resources; +using AIStudio.Wpf.DiagramDesigner.Helpers; using AIStudio.Wpf.DiagramDesigner.Models; using AIStudio.Wpf.DiagramDesigner.ViewModels; using AIStudio.Wpf.DiagramDesigner.ViewModels.BaseViewModel; @@ -714,6 +715,29 @@ namespace AIStudio.Wpf.DiagramDesigner } _viewModel.AddCommand.Execute(designerItems); } + else if (dragObject.DesignerItem is SerializableItem serializableItem) + { + Type type = TypeHelper.GetType(serializableItem.ModelTypeName); + DesignerItemViewModelBase itemBase = Activator.CreateInstance(type, _viewModel, serializableItem, ".json") as DesignerItemViewModelBase; + itemBase.Left = Math.Max(0, position.X - itemBase.GetItemWidth() / 2); + itemBase.Top = Math.Max(0, position.Y - itemBase.GetItemHeight() / 2); + if (dragObject.DesiredSize != null) + { + itemBase.ItemWidth = dragObject.DesiredSize.Value.Width; + itemBase.ItemHeight = dragObject.DesiredSize.Value.Height; + } + if (dragObject.DesiredMinSize != null) + { + itemBase.MinItemWidth = dragObject.DesiredMinSize.Value.Width; + itemBase.MinItemHeight = dragObject.DesiredMinSize.Value.Height; + } + _viewModel.AddCommand.Execute(itemBase); + + if (itemBase is BlockDesignerItemViewModel block) + { + (_viewModel as IBlockDiagramViewModel).FinishNearBlock(new System.Collections.Generic.List { block }); + } + } else { DesignerItemViewModelBase itemBase = null; diff --git a/AIStudio.Wpf.DiagramDesigner/Controls/DiagramTabControl.cs b/AIStudio.Wpf.DiagramDesigner/Controls/DiagramTabControl.cs new file mode 100644 index 0000000..ecf9af3 --- /dev/null +++ b/AIStudio.Wpf.DiagramDesigner/Controls/DiagramTabControl.cs @@ -0,0 +1,318 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Markup; + +namespace AIStudio.Wpf.DiagramDesigner.Controls +{ + //public class DiagramTabControl : TabControl + //{ + // public DiagramTabControl() + // { + // // Attach event handler to TabControl.SelectionChanged event + // this.SelectionChanged += DiagramTabControl_SelectionChanged; + // this.IsVisibleChanged += DiagramTabControl_IsVisibleChanged; + // } + + // private void DiagramTabControl_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) + // { + // foreach (var item in this.Items) + // { + // if (item is DiagramViewModel viewModel) + // { + // viewModel.ShowSearch = false; + // } + // } + // } + + // private void DiagramTabControl_SelectionChanged(object sender, SelectionChangedEventArgs e) + // { + // // Iterate through all TabItems and manually set the Visibility property + // foreach (var item in this.Items) + // { + // if (item is DiagramViewModel viewModel) + // { + // if (item != this.SelectedItem) + // { + // viewModel.ShowSearch = false; + // } + // } + // } + // } + //} + + /// + /// Attached properties for persistent tab control + /// + /// By default WPF TabControl bound to an ItemsSource destroys visual state of invisible tabs. + /// Set ikriv:DiagramTabControl.IsCached="True" to preserve visual state of each tab. + /// + public static class DiagramTabControl + { + public static bool GetIsCached(DependencyObject obj) + { + return (bool)obj.GetValue(IsCachedProperty); + } + + public static void SetIsCached(DependencyObject obj, bool value) + { + obj.SetValue(IsCachedProperty, value); + } + + /// + /// Controls whether tab content is cached or not + /// + /// When DiagramTabControl.IsCached is true, visual state of each tab is preserved (cached), even when the tab is hidden + public static readonly DependencyProperty IsCachedProperty = + DependencyProperty.RegisterAttached("IsCached", typeof(bool), typeof(DiagramTabControl), new UIPropertyMetadata(false, OnIsCachedChanged)); + + + public static DataTemplate GetTemplate(DependencyObject obj) + { + return (DataTemplate)obj.GetValue(TemplateProperty); + } + + public static void SetTemplate(DependencyObject obj, DataTemplate value) + { + obj.SetValue(TemplateProperty, value); + } + + /// + /// Used instead of TabControl.ContentTemplate for cached tabs + /// + public static readonly DependencyProperty TemplateProperty = + DependencyProperty.RegisterAttached("Template", typeof(DataTemplate), typeof(DiagramTabControl), new UIPropertyMetadata(null)); + + + public static DataTemplateSelector GetTemplateSelector(DependencyObject obj) + { + return (DataTemplateSelector)obj.GetValue(TemplateSelectorProperty); + } + + public static void SetTemplateSelector(DependencyObject obj, DataTemplateSelector value) + { + obj.SetValue(TemplateSelectorProperty, value); + } + + /// + /// Used instead of TabControl.ContentTemplateSelector for cached tabs + /// + public static readonly DependencyProperty TemplateSelectorProperty = + DependencyProperty.RegisterAttached("TemplateSelector", typeof(DataTemplateSelector), typeof(DiagramTabControl), new UIPropertyMetadata(null)); + + [EditorBrowsable(EditorBrowsableState.Never)] + public static TabControl GetInternalTabControl(DependencyObject obj) + { + return (TabControl)obj.GetValue(InternalTabControlProperty); + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public static void SetInternalTabControl(DependencyObject obj, TabControl value) + { + obj.SetValue(InternalTabControlProperty, value); + } + + // Using a DependencyProperty as the backing store for InternalTabControl. This enables animation, styling, binding, etc... + [EditorBrowsable(EditorBrowsableState.Never)] + public static readonly DependencyProperty InternalTabControlProperty = + DependencyProperty.RegisterAttached("InternalTabControl", typeof(TabControl), typeof(DiagramTabControl), new UIPropertyMetadata(null, OnInternalTabControlChanged)); + + + [EditorBrowsable(EditorBrowsableState.Never)] + public static ContentControl GetInternalCachedContent(DependencyObject obj) + { + return (ContentControl)obj.GetValue(InternalCachedContentProperty); + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public static void SetInternalCachedContent(DependencyObject obj, ContentControl value) + { + obj.SetValue(InternalCachedContentProperty, value); + } + + // Using a DependencyProperty as the backing store for InternalCachedContent. This enables animation, styling, binding, etc... + [EditorBrowsable(EditorBrowsableState.Never)] + public static readonly DependencyProperty InternalCachedContentProperty = + DependencyProperty.RegisterAttached("InternalCachedContent", typeof(ContentControl), typeof(DiagramTabControl), new UIPropertyMetadata(null)); + + [EditorBrowsable(EditorBrowsableState.Never)] + public static object GetInternalContentManager(DependencyObject obj) + { + return (object)obj.GetValue(InternalContentManagerProperty); + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public static void SetInternalContentManager(DependencyObject obj, object value) + { + obj.SetValue(InternalContentManagerProperty, value); + } + + // Using a DependencyProperty as the backing store for InternalContentManager. This enables animation, styling, binding, etc... + public static readonly DependencyProperty InternalContentManagerProperty = + DependencyProperty.RegisterAttached("InternalContentManager", typeof(object), typeof(DiagramTabControl), new UIPropertyMetadata(null)); + + private static void OnIsCachedChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) + { + if (obj == null) return; + + var tabControl = obj as TabControl; + if (tabControl == null) + { + throw new InvalidOperationException("Cannot set DiagramTabControl.IsCached on object of type " + args.NewValue.GetType().Name + + ". Only objects of type TabControl can have DiagramTabControl.IsCached property."); + } + + bool newValue = (bool)args.NewValue; + + if (!newValue) + { + if (args.OldValue != null && ((bool)args.OldValue)) + { + throw new NotImplementedException("Cannot change DiagramTabControl.IsCached from True to False. Turning tab caching off is not implemented"); + } + + return; + } + + EnsureContentTemplateIsNull(tabControl); + tabControl.ContentTemplate = CreateContentTemplate(); + EnsureContentTemplateIsNotModified(tabControl); + } + + private static DataTemplate CreateContentTemplate() + { + const string xaml = + ""; + + var context = new ParserContext(); + + context.XamlTypeMapper = new XamlTypeMapper(new string[0]); + context.XamlTypeMapper.AddMappingProcessingInstruction("b", typeof(DiagramTabControl).Namespace, typeof(DiagramTabControl).Assembly.FullName); + + context.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation"); + context.XmlnsDictionary.Add("b", "b"); + + var template = (DataTemplate)XamlReader.Parse(xaml, context); + return template; + } + + private static void OnInternalTabControlChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) + { + if (obj == null) return; + var container = obj as Decorator; + + if (container == null) + { + var message = "Cannot set DiagramTabControl.InternalTabControl on object of type " + obj.GetType().Name + + ". Only controls that derive from Decorator, such as Border can have a DiagramTabControl.InternalTabControl."; + throw new InvalidOperationException(message); + } + + if (args.NewValue == null) return; + if (!(args.NewValue is TabControl)) + { + throw new InvalidOperationException("Value of DiagramTabControl.InternalTabControl cannot be of type " + args.NewValue.GetType().Name + ", it must be of type TabControl"); + } + + var tabControl = (TabControl)args.NewValue; + var contentManager = GetContentManager(tabControl, container); + contentManager.UpdateSelectedTab(); + } + + private static ContentManager GetContentManager(TabControl tabControl, Decorator container) + { + var contentManager = (ContentManager)GetInternalContentManager(tabControl); + if (contentManager != null) + { + /* + * Content manager already exists for the tab control. This means that tab content template is applied + * again, and new instance of the Border control (container) has been created. The old container + * referenced by the content manager is no longer visible and needs to be replaced + */ + contentManager.ReplaceContainer(container); + } + else + { + // create content manager for the first time + contentManager = new ContentManager(tabControl, container); + SetInternalContentManager(tabControl, contentManager); + } + + return contentManager; + } + + private static void EnsureContentTemplateIsNull(TabControl tabControl) + { + if (tabControl.ContentTemplate != null) + { + throw new InvalidOperationException("TabControl.ContentTemplate value is not null. If DiagramTabControl.IsCached is True, use DiagramTabControl.Template instead of ContentTemplate"); + } + } + + private static void EnsureContentTemplateIsNotModified(TabControl tabControl) + { + var descriptor = DependencyPropertyDescriptor.FromProperty(TabControl.ContentTemplateProperty, typeof(TabControl)); + descriptor.AddValueChanged(tabControl, (sender, args) => + { + throw new InvalidOperationException("Cannot assign to TabControl.ContentTemplate when DiagramTabControl.IsCached is True. Use DiagramTabControl.Template instead"); + }); + } + + public class ContentManager + { + TabControl _tabControl; + Decorator _border; + + public ContentManager(TabControl tabControl, Decorator border) + { + _tabControl = tabControl; + _border = border; + _tabControl.SelectionChanged += (sender, args) => { UpdateSelectedTab(); }; + } + + public void ReplaceContainer(Decorator newBorder) + { + if (Object.ReferenceEquals(_border, newBorder)) return; + + _border.Child = null; // detach any tab content that old border may hold + _border = newBorder; + } + + public void UpdateSelectedTab() + { + _border.Child = GetCurrentContent(); + } + + private ContentControl GetCurrentContent() + { + var item = _tabControl.SelectedItem; + if (item == null) return null; + + var tabItem = _tabControl.ItemContainerGenerator.ContainerFromItem(item); + if (tabItem == null) return null; + + var cachedContent = DiagramTabControl.GetInternalCachedContent(tabItem); + if (cachedContent == null) + { + cachedContent = new ContentControl + { + DataContext = item, + ContentTemplate = DiagramTabControl.GetTemplate(_tabControl), + ContentTemplateSelector = DiagramTabControl.GetTemplateSelector(_tabControl) + }; + + cachedContent.SetBinding(ContentControl.ContentProperty, new Binding()); + DiagramTabControl.SetInternalCachedContent(tabItem, cachedContent); + } + + return cachedContent; + } + } + } +} \ No newline at end of file diff --git a/AIStudio.Wpf.DiagramDesigner/Controls/DragThumb.cs b/AIStudio.Wpf.DiagramDesigner/Controls/DragThumb.cs index f9b11ee..e543d0d 100644 --- a/AIStudio.Wpf.DiagramDesigner/Controls/DragThumb.cs +++ b/AIStudio.Wpf.DiagramDesigner/Controls/DragThumb.cs @@ -213,7 +213,7 @@ namespace AIStudio.Wpf.DiagramDesigner.Controls protected override void OnPreviewMouseLeftButtonUp(MouseButtonEventArgs e) { - base.OnPreviewMouseLeftButtonDown(e); + base.OnPreviewMouseLeftButtonUp(e); if (EditClickCount == 1) { diff --git a/AIStudio.Wpf.DiagramDesigner/Controls/MyTabControl.cs b/AIStudio.Wpf.DiagramDesigner/Controls/MyTabControl.cs deleted file mode 100644 index e50a061..0000000 --- a/AIStudio.Wpf.DiagramDesigner/Controls/MyTabControl.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls; - -namespace AIStudio.Wpf.DiagramDesigner.Controls -{ - public class DiagramTabControl : TabControl - { - public DiagramTabControl() - { - // Attach event handler to TabControl.SelectionChanged event - this.SelectionChanged += DiagramTabControl_SelectionChanged; - this.IsVisibleChanged += DiagramTabControl_IsVisibleChanged; - } - - private void DiagramTabControl_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) - { - foreach (var item in this.Items) - { - if (item is DiagramViewModel viewModel) - { - viewModel.ShowSearch = false; - } - } - } - - private void DiagramTabControl_SelectionChanged(object sender, SelectionChangedEventArgs e) - { - // Iterate through all TabItems and manually set the Visibility property - foreach (var item in this.Items) - { - if (item is DiagramViewModel viewModel) - { - if (item != this.SelectedItem) - { - viewModel.ShowSearch = false; - } - } - } - } - } -} \ No newline at end of file diff --git a/AIStudio.Wpf.DiagramDesigner/Helpers/BitmapHelper.cs b/AIStudio.Wpf.DiagramDesigner/Helpers/BitmapHelper.cs index 5ab7b2b..c137ff7 100644 --- a/AIStudio.Wpf.DiagramDesigner/Helpers/BitmapHelper.cs +++ b/AIStudio.Wpf.DiagramDesigner/Helpers/BitmapHelper.cs @@ -1,7 +1,9 @@ using System; +using System.Collections; using System.Drawing; using System.Drawing.Imaging; using System.IO; +using System.IO.Pipes; using System.Runtime.InteropServices.ComTypes; using System.Windows; using System.Windows.Media.Imaging; @@ -29,11 +31,6 @@ namespace AIStudio.Wpf.DiagramDesigner rtb.Render(element); var bit = BitmapSourceToBitmap(rtb); - ////测试代码 - //DirectoryInfo d = new DirectoryInfo(System.IO.Path.Combine(Directory.GetCurrentDirectory(), "Cache")); - //if (!d.Exists) d.Create(); - //bit.Save(System.IO.Path.Combine(d.FullName, "控件截图.png")); - return bit; } @@ -51,11 +48,6 @@ namespace AIStudio.Wpf.DiagramDesigner var bit = BitmapSourceToBitmap(rtb); - ////测试代码 - //DirectoryInfo d = new DirectoryInfo(System.IO.Path.Combine(Directory.GetCurrentDirectory(), "Cache")); - //if (!d.Exists) d.Create(); - //bit.Save(System.IO.Path.Combine(d.FullName, "控件截图.png")); - return bit; } @@ -123,6 +115,106 @@ namespace AIStudio.Wpf.DiagramDesigner bitmapImage.StreamSource = stream; bitmapImage.EndInit(); return bitmapImage; + } + + public static System.Windows.Media.Brush ToBrush(this string base64String, int width, int height) + { + if (string.IsNullOrEmpty(base64String)) + return null; + + try + { + var bitmapImage = base64String.ToBitmapImage(width, height); + + return new System.Windows.Media.ImageBrush(bitmapImage) { Stretch = System.Windows.Media.Stretch.Uniform }; + } + catch + { + return null; + } + } + + public static BitmapImage ToBitmapImage(this string base64String, int width = 0, int height = 0) + { + if (string.IsNullOrEmpty(base64String)) + return null; + + try + { + var byteArray = Convert.FromBase64String(base64String); + BitmapImage bitmapImage = null; + bitmapImage = new BitmapImage(); + bitmapImage.BeginInit(); + bitmapImage.CreateOptions = BitmapCreateOptions.IgnoreColorProfile; + bitmapImage.CacheOption = BitmapCacheOption.OnLoad; + bitmapImage.DecodePixelWidth = width;//需要缩略图的解码宽度 + bitmapImage.DecodePixelHeight = height;//缩略图的解码高度 + bitmapImage.StreamSource = new MemoryStream(byteArray); + bitmapImage.EndInit(); + + return bitmapImage; + } + catch + { + return null; + } + } + + public static BitmapImage ToBitmapImage(this System.Drawing.Bitmap ImageOriginal, int width = 0, int height = 0) + { + System.Drawing.Bitmap ImageOriginalBase = new System.Drawing.Bitmap(ImageOriginal); + BitmapImage bitmapImage = new BitmapImage() { DecodePixelWidth = width, DecodePixelHeight = height }; + System.IO.MemoryStream ms = new System.IO.MemoryStream(); + ImageOriginalBase.Save(ms, System.Drawing.Imaging.ImageFormat.Png); + bitmapImage.BeginInit(); + bitmapImage.StreamSource = ms; + bitmapImage.CacheOption = BitmapCacheOption.OnLoad; + bitmapImage.EndInit(); + bitmapImage.Freeze(); + + return bitmapImage; + } + + public static BitmapImage ToBitmapImage(this byte[] byteArray, int width = 0, int height = 0) + { + BitmapImage bitmapImage = new BitmapImage() { DecodePixelWidth = width, DecodePixelHeight = height }; + System.IO.MemoryStream ms = new System.IO.MemoryStream(byteArray); + bitmapImage.BeginInit(); + bitmapImage.StreamSource = ms; + bitmapImage.CacheOption = BitmapCacheOption.OnLoad; + bitmapImage.EndInit(); + bitmapImage.Freeze(); + + return bitmapImage; + + } + + public static Bitmap ToBitmap(this string base64String, int width = 0, int height = 0) + { + if (string.IsNullOrEmpty(base64String)) + return null; + + try + { + var byteArray = Convert.FromBase64String(base64String); + + return byteArray.ToBitmap(); + } + catch + { + return null; + } + } + + public static Bitmap ToBitmap(this byte[] byteArray) + { + //var stream = new MemoryStream(byteArray); + //return new Bitmap(stream); + MemoryStream ms = new MemoryStream(byteArray); + Bitmap bitmap = (Bitmap)Image.FromStream(ms); + ms.Close(); + + return bitmap; } public static string ToBase64String(this System.Windows.Media.Brush brush) @@ -143,7 +235,7 @@ namespace AIStudio.Wpf.DiagramDesigner { var bitmap = (imageBrush.ImageSource as BitmapImage); byte[] bytearray = null; - Stream smarket = bitmap.StreamSource; + Stream smarket = bitmap.StreamSource; if (smarket != null && smarket.Length > 0) { //设置当前位置 @@ -166,7 +258,37 @@ namespace AIStudio.Wpf.DiagramDesigner } } - public static System.Windows.Media.Brush ToBrush(this string base64String, int width, int height) + public static string ToBase64String(this BitmapImage bitmap) + { + Stream stream = bitmap.StreamSource; + byte[] bytearray = new byte[stream.Length]; + stream.Seek(0, SeekOrigin.Begin); + stream.Read(bytearray, 0, bytearray.Length); + + return Convert.ToBase64String(bytearray); + } + + public static string ToBase64String(this Bitmap bitmap) + { + var ms = new MemoryStream(); + bitmap.Save(ms, bitmap.RawFormat); + byte[] bytearray = new byte[ms.Length]; + bytearray = ms.ToArray(); + + return Convert.ToBase64String(bytearray); + } + + + public static string ToBase64String(this Stream stream) + { + byte[] bytearray = new byte[stream.Length]; + stream.Seek(0, SeekOrigin.Begin); + stream.Read(bytearray, 0, bytearray.Length); + + return Convert.ToBase64String(bytearray); + } + + public static MemoryStream ToMemoryStream(this string base64String, int width = 0, int height = 0) { if (string.IsNullOrEmpty(base64String)) return null; @@ -174,17 +296,10 @@ namespace AIStudio.Wpf.DiagramDesigner try { var byteArray = Convert.FromBase64String(base64String); - BitmapImage bitmapImage = null; - bitmapImage = new BitmapImage(); - bitmapImage.BeginInit(); - bitmapImage.CreateOptions = BitmapCreateOptions.IgnoreColorProfile; - bitmapImage.CacheOption = BitmapCacheOption.OnLoad; - bitmapImage.DecodePixelWidth = width;//需要缩略图的解码宽度 - bitmapImage.DecodePixelHeight = height;//缩略图的解码高度 - bitmapImage.StreamSource = new MemoryStream(byteArray); - bitmapImage.EndInit(); + var stream = new MemoryStream(byteArray); + stream.Seek(0, SeekOrigin.Begin); - return new System.Windows.Media.ImageBrush(bitmapImage) { Stretch = System.Windows.Media.Stretch.Uniform }; + return stream; } catch { @@ -192,5 +307,33 @@ namespace AIStudio.Wpf.DiagramDesigner } } + public static FileStream ToFileStream(this string base64String, string filename, int width = 0, int height = 0) + { + if (string.IsNullOrEmpty(base64String)) + return null; + + try + { + var byteArray = Convert.FromBase64String(base64String); + FileStream fs = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.ReadWrite); + fs.Write(byteArray, 0, byteArray.Length); + fs.Seek(0, SeekOrigin.Begin); + return fs; + } + catch + { + return null; + } + } + + public static Stream CopyStream(this Stream stream) + { + byte[] bytearray = new byte[stream.Length]; + stream.Seek(0, SeekOrigin.Begin); + stream.Read(bytearray, 0, bytearray.Length); + + var destination = new MemoryStream(bytearray); + return destination; + } } } diff --git a/AIStudio.Wpf.DiagramDesigner/Models/Serializables/Container/BlockItemsContainerInfoItem.cs b/AIStudio.Wpf.DiagramDesigner/Models/Serializables/Container/BlockItemsContainerInfoItem.cs index 1e624a7..2798633 100644 --- a/AIStudio.Wpf.DiagramDesigner/Models/Serializables/Container/BlockItemsContainerInfoItem.cs +++ b/AIStudio.Wpf.DiagramDesigner/Models/Serializables/Container/BlockItemsContainerInfoItem.cs @@ -23,6 +23,7 @@ namespace AIStudio.Wpf.DiagramDesigner this.ChildFlag = viewmodel.ChildFlag; this.PhysicalItemWidth = viewmodel.PhysicalItemWidth; this.PhysicalItemHeight = viewmodel.PhysicalItemHeight; + this.Parameter = new ConstParameterItem(viewmodel.Parameter); Children = new List(viewmodel.Children.Select(p => new BlockDesignerItem(p))); } @@ -52,10 +53,16 @@ namespace AIStudio.Wpf.DiagramDesigner get; set; } + [XmlElement] + public ConstParameterItem Parameter + { + get; set; + } + [XmlArray] public List Children { get; set; - } + } } } diff --git a/AIStudio.Wpf.DiagramDesigner/Models/Serializables/Container/ConstParameterItem.cs b/AIStudio.Wpf.DiagramDesigner/Models/Serializables/Container/ConstParameterItem.cs new file mode 100644 index 0000000..ab2f3c7 --- /dev/null +++ b/AIStudio.Wpf.DiagramDesigner/Models/Serializables/Container/ConstParameterItem.cs @@ -0,0 +1,31 @@ +using AIStudio.Wpf.DiagramDesigner; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Serialization; + +namespace AIStudio.Wpf.DiagramDesigner +{ + [XmlInclude(typeof(ConstParameterItem))] + public class ConstParameterItem + { + [XmlAttribute] + public string Text { get; set; } + + [XmlAttribute] + public virtual string Value { get; set; } + + public ConstParameterItem() + { + + } + + public ConstParameterItem(ConstParameter viewmodel) + { + Text = viewmodel?.Text; + Value = viewmodel?.Value?.ToString(); + } + } +} diff --git a/AIStudio.Wpf.DiagramDesigner/Models/Serializables/DiagramItem.cs b/AIStudio.Wpf.DiagramDesigner/Models/Serializables/DiagramItem.cs index 74105a5..09b0b02 100644 --- a/AIStudio.Wpf.DiagramDesigner/Models/Serializables/DiagramItem.cs +++ b/AIStudio.Wpf.DiagramDesigner/Models/Serializables/DiagramItem.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Windows; using System.Windows.Media; using System.Xml; @@ -17,7 +18,7 @@ namespace AIStudio.Wpf.DiagramDesigner } - public DiagramItem(IDiagramViewModel diagramView) + public DiagramItem(IDiagramViewModel diagramView, string ext = ".json") { Name = diagramView.Name; DiagramType = diagramView.DiagramType; @@ -30,9 +31,16 @@ namespace AIStudio.Wpf.DiagramDesigner PageSizeType = diagramView.DiagramOption.LayoutOption.PageSizeType; PhysicalGridMarginSize = diagramView.DiagramOption.LayoutOption.PhysicalGridMarginSize; GridColor = diagramView.DiagramOption.LayoutOption.GridColor; + PageBackground = diagramView.DiagramOption.LayoutOption.PageBackground; AllowDrop = diagramView.DiagramOption.LayoutOption.AllowDrop; Thumbnail = diagramView.Thumbnail.ToBase64String(); + + var selectedDesignerItems = diagramView.Items.OfType(); + var selectedConnections = diagramView.Items.OfType(); + + DesignerItems = selectedDesignerItems.Select(p => p.ToSerializableItem(ext)).Where(p => p != null).ToList(); + Connections = selectedConnections.Select(p => p.ToSerializableItem(ext)).Where(p => p != null).ToList(); } [XmlAttribute] @@ -157,6 +165,26 @@ namespace AIStudio.Wpf.DiagramDesigner } } + [XmlIgnore] + public Color PageBackground + { + get; set; + } + + [JsonIgnore] + [XmlAttribute("PageBackground")] + public string XmlPageBackground + { + get + { + return SerializeHelper.SerializeColor(PageBackground); + } + set + { + PageBackground = SerializeHelper.DeserializeColor(value); + } + } + [XmlAttribute] public bool AllowDrop { diff --git a/AIStudio.Wpf.DiagramDesigner/Models/Serializables/SelectableItemBase.cs b/AIStudio.Wpf.DiagramDesigner/Models/Serializables/SelectableItemBase.cs index ce71f1c..6278390 100644 --- a/AIStudio.Wpf.DiagramDesigner/Models/Serializables/SelectableItemBase.cs +++ b/AIStudio.Wpf.DiagramDesigner/Models/Serializables/SelectableItemBase.cs @@ -12,6 +12,7 @@ using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Media; +using System.Windows.Media.Imaging; using System.Xml; using System.Xml.Serialization; @@ -646,6 +647,23 @@ namespace AIStudio.Wpf.DiagramDesigner return new Matrix(double.Parse(pieces[0]), double.Parse(pieces[1]), double.Parse(pieces[2]), double.Parse(pieces[3]), double.Parse(pieces[4]), double.Parse(pieces[5])); } + public static string SerializeBitmapImage(BitmapImage bitmapImage) + { + return bitmapImage.ToBase64String(); + } + + public static BitmapImage DeserializeBitmapImage(string bitmapImagestring) + { + try + { + return bitmapImagestring.ToBitmapImage(); + } + catch + { + return null; + } + } + public static string SerializeObject(object obj, string serializableType = null) { if (serializableType?.ToLower() == ".xml") diff --git a/AIStudio.Wpf.DiagramDesigner/Models/Values/ConstParameter.cs b/AIStudio.Wpf.DiagramDesigner/Models/Values/ConstParameter.cs index 4f375b8..5602648 100644 --- a/AIStudio.Wpf.DiagramDesigner/Models/Values/ConstParameter.cs +++ b/AIStudio.Wpf.DiagramDesigner/Models/Values/ConstParameter.cs @@ -4,7 +4,15 @@ namespace AIStudio.Wpf.DiagramDesigner { public class ConstParameter : BindableBase, IParameter { + public ConstParameter() + { + } + public ConstParameter(ConstParameterItem item) + { + Text = item.Text; + Value = item.Value?.ToString(); + } private string _text; diff --git a/AIStudio.Wpf.DiagramDesigner/PathGenerators/PathGenerators.Boundary.cs b/AIStudio.Wpf.DiagramDesigner/PathGenerators/PathGenerators.Boundary.cs index b81fb9e..58ac7fc 100644 --- a/AIStudio.Wpf.DiagramDesigner/PathGenerators/PathGenerators.Boundary.cs +++ b/AIStudio.Wpf.DiagramDesigner/PathGenerators/PathGenerators.Boundary.cs @@ -33,8 +33,8 @@ namespace AIStudio.Wpf.DiagramDesigner private static PointBase[] GetRouteWithMiddlePoints(IDiagramViewModel _, ConnectionViewModel link, PointBase[] route) { var middle = GetMiddlePoints( - link.SourceConnectorInfoFully.MiddlePosition, - link.SourceConnectorInfoFully.Orientation, + link.SourceConnectorInfo.MiddlePosition, + link.SourceConnectorInfo.Orientation, link.SinkConnectorInfo.MiddlePosition, link.IsFullConnection ? link.SinkConnectorInfoFully.Orientation : (link.SinkConnectorInfo.MiddlePosition.Y >= link.SourceConnectorInfo.MiddlePosition.Y ? ConnectorOrientation.Top : ConnectorOrientation.Bottom), _.DiagramOption.LayoutOption.GridCellSize, diff --git a/AIStudio.Wpf.DiagramDesigner/Services/IUIVisualizerService.cs b/AIStudio.Wpf.DiagramDesigner/Services/IUIVisualizerService.cs index 375dc04..5025f5f 100644 --- a/AIStudio.Wpf.DiagramDesigner/Services/IUIVisualizerService.cs +++ b/AIStudio.Wpf.DiagramDesigner/Services/IUIVisualizerService.cs @@ -17,7 +17,7 @@ namespace AIStudio.Wpf.DiagramDesigner.Services /// /// Object state to associate with the dialog /// True/False if UI is displayed. - bool? ShowDialog(object dataContextForPopup); + bool? ShowDialog(object dataContextForPopup, bool buttonVisable = true); /// /// This method displays a modal dialog associated with the given key. diff --git a/AIStudio.Wpf.DiagramDesigner/Services/WPFUIVisualizerService.cs b/AIStudio.Wpf.DiagramDesigner/Services/WPFUIVisualizerService.cs index b5c9058..5f209e0 100644 --- a/AIStudio.Wpf.DiagramDesigner/Services/WPFUIVisualizerService.cs +++ b/AIStudio.Wpf.DiagramDesigner/Services/WPFUIVisualizerService.cs @@ -12,7 +12,7 @@ namespace AIStudio.Wpf.DiagramDesigner.Services /// /// Object state to associate with the dialog /// True/False if UI is displayed. - public bool? ShowDialog(object dataContextForPopup) + public bool? ShowDialog(object dataContextForPopup, bool buttonVisable = true) { Window win = new PopupWindow(); win.DataContext = dataContextForPopup; diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/Container/BlockItemsContainerInfo.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/Container/BlockItemsContainerInfo.cs index a704de7..b0d4df7 100644 --- a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/Container/BlockItemsContainerInfo.cs +++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/Container/BlockItemsContainerInfo.cs @@ -65,6 +65,7 @@ namespace AIStudio.Wpf.DiagramDesigner this.ChildFlag = designer.ChildFlag; this.PhysicalItemWidth = designer.PhysicalItemWidth; this.PhysicalItemHeight = designer.PhysicalItemHeight; + this.Parameter = new ConstParameter(designer.Parameter); if (designer.Children != null) { foreach (var child in designer.Children) @@ -178,8 +179,8 @@ namespace AIStudio.Wpf.DiagramDesigner } } - private IParameter _parameter; - public IParameter Parameter + private ConstParameter _parameter; + public ConstParameter Parameter { get { @@ -350,5 +351,15 @@ namespace AIStudio.Wpf.DiagramDesigner return null; } } + + public override void Dispose() + { + base.Dispose(); + + foreach (var child in Children) + { + child.Dispose(); + } + } } } diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DiagramViewModel.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DiagramViewModel.cs index e8bc873..de24da7 100644 --- a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DiagramViewModel.cs +++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DiagramViewModel.cs @@ -814,7 +814,7 @@ namespace AIStudio.Wpf.DiagramDesigner BuildMenuOptions(); } - public DiagramViewModel(DiagramItem diagramItem, string ext) : this() + public DiagramViewModel(DiagramItem diagramItem, string ext =".json") : this() { Init(diagramItem); @@ -849,6 +849,7 @@ namespace AIStudio.Wpf.DiagramDesigner public void Init(DiagramItem diagramItem) { DiagramType = diagramItem.DiagramType; + Name = diagramItem.Name; DiagramOption.LayoutOption.ShowGrid = diagramItem.ShowGrid; DiagramOption.LayoutOption.PhysicalGridCellSize = diagramItem.PhysicalGridCellSize; DiagramOption.LayoutOption.CellHorizontalAlignment = diagramItem.CellHorizontalAlignment; @@ -858,7 +859,8 @@ namespace AIStudio.Wpf.DiagramDesigner DiagramOption.LayoutOption.PageSizeType = diagramItem.PageSizeType; DiagramOption.LayoutOption.PhysicalGridMarginSize = diagramItem.PhysicalGridMarginSize; DiagramOption.LayoutOption.GridColor = diagramItem.GridColor; - DiagramOption.LayoutOption.AllowDrop = diagramItem.AllowDrop; + DiagramOption.LayoutOption.PageBackground = diagramItem.PageBackground; + DiagramOption.LayoutOption.AllowDrop = diagramItem.AllowDrop; Thumbnail = diagramItem.Thumbnail.ToBrush((int)DiagramOption.LayoutOption.PageSize.Width / 4, (int)DiagramOption.LayoutOption.PageSize.Height / 4); Init(true); diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/BlockViewModel/BlockDesignerItemViewModel.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/BlockViewModel/BlockDesignerItemViewModel.cs index efb7a0a..5b2f417 100644 --- a/AIStudio.Wpf.DiagramDesigner/ViewModels/BlockViewModel/BlockDesignerItemViewModel.cs +++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/BlockViewModel/BlockDesignerItemViewModel.cs @@ -530,6 +530,19 @@ namespace AIStudio.Wpf.DiagramDesigner return null; } #endregion + + public override void Dispose() + { + base.Dispose(); + + if (ParentContainer == null) + { + foreach (var container in Containers) + { + container.Dispose(); + } + } + } } #region 扩展 diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/BlockViewModel/BlockDiagramViewModel.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/BlockViewModel/BlockDiagramViewModel.cs index e963fb7..ecab8d6 100644 --- a/AIStudio.Wpf.DiagramDesigner/ViewModels/BlockViewModel/BlockDiagramViewModel.cs +++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/BlockViewModel/BlockDiagramViewModel.cs @@ -14,6 +14,11 @@ namespace AIStudio.Wpf.DiagramDesigner { } + public BlockDiagramViewModel(DiagramItem diagramItem, string ext) : base(diagramItem, ext) + { + + } + #region private ICommand _addNextCommand; public ICommand AddNextCommand diff --git a/Extensions/AIStudio.Wpf.Flowchart/Controls/FlowchartEditor.xaml b/Extensions/AIStudio.Wpf.Flowchart/Controls/FlowchartEditor.xaml index fb4852f..e6f4b68 100644 --- a/Extensions/AIStudio.Wpf.Flowchart/Controls/FlowchartEditor.xaml +++ b/Extensions/AIStudio.Wpf.Flowchart/Controls/FlowchartEditor.xaml @@ -18,13 +18,13 @@ - + - + diff --git a/Extensions/AIStudio.Wpf.Flowchart/Controls/FlowchartEditor.xaml.cs b/Extensions/AIStudio.Wpf.Flowchart/Controls/FlowchartEditor.xaml.cs index 832daeb..8c81be6 100644 --- a/Extensions/AIStudio.Wpf.Flowchart/Controls/FlowchartEditor.xaml.cs +++ b/Extensions/AIStudio.Wpf.Flowchart/Controls/FlowchartEditor.xaml.cs @@ -18,7 +18,7 @@ namespace AIStudio.Wpf.Flowchart.Controls /// FlowchartEditor.xaml 的交互逻辑 /// [TemplatePart(Name = PART_DiagramControl, Type = typeof(DiagramControl))] - public partial class FlowchartEditor : UserControl + public partial class FlowchartEditor : Control { public const string PART_DiagramControl = "PART_DiagramControl"; private DiagramControl _diagramControl; diff --git a/Extensions/AIStudio.Wpf.Mind/Controls/MindEditor.xaml b/Extensions/AIStudio.Wpf.Mind/Controls/MindEditor.xaml index 04556a1..567570e 100644 --- a/Extensions/AIStudio.Wpf.Mind/Controls/MindEditor.xaml +++ b/Extensions/AIStudio.Wpf.Mind/Controls/MindEditor.xaml @@ -21,7 +21,7 @@ - + diff --git a/Extensions/AIStudio.Wpf.Mind/Controls/MindEditor.xaml.cs b/Extensions/AIStudio.Wpf.Mind/Controls/MindEditor.xaml.cs index 39c7f63..dec24f0 100644 --- a/Extensions/AIStudio.Wpf.Mind/Controls/MindEditor.xaml.cs +++ b/Extensions/AIStudio.Wpf.Mind/Controls/MindEditor.xaml.cs @@ -21,7 +21,7 @@ namespace AIStudio.Wpf.Mind.Controls [TemplatePart(Name = PART_DiagramControl, Type = typeof(DiagramControl))] [TemplatePart(Name = PART_ContentControl, Type = typeof(ContentControl))] [TemplatePart(Name = PART_SearchControl, Type = typeof(Border))] - public partial class MindEditor : UserControl + public partial class MindEditor : Control { public const string PART_DiagramControl = "PART_DiagramControl"; public const string PART_ContentControl = "PART_ContentControl"; diff --git a/Images/微信图片_20230825164357.png b/Images/微信图片_20230825164357.png new file mode 100644 index 0000000..7db792e Binary files /dev/null and b/Images/微信图片_20230825164357.png differ diff --git a/README.md b/README.md index cd80f21..0af4e80 100644 --- a/README.md +++ b/README.md @@ -746,6 +746,10 @@ nuget地址:![输入图片说明](Images/nuget.png) +## 捐赠列表: + +![输入图片说明](Images/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20230825164357.png) + 相关链接地址: Fluent.Ribbon: https://github.com/fluentribbon/Fluent.Ribbon @@ -756,6 +760,6 @@ nuget地址:![输入图片说明](Images/nuget.png) QQ技术交流群:51286643(如果您还喜欢,帮忙点个星,谢谢) - 特别感谢:https://dotnet9.com/ 的站长:dotnet9。 + 特别感谢:https://dotnet9.com/ 的站长:dotnet9。 有想加入开发的朋友可以联系我。 \ No newline at end of file diff --git a/thank.png b/thank.png new file mode 100644 index 0000000..d92841a Binary files /dev/null and b/thank.png differ