mirror of
https://gitee.com/akwkevin/aistudio.-wpf.-diagram
synced 2026-05-02 14:01:29 +08:00
Merge branch 'master' of https://gitee.com/akwkevin/aistudio.-wpf.-diagram
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -26,11 +26,16 @@ namespace AIStudio.Wpf.DiagramApp.ViewModels
|
|||||||
}
|
}
|
||||||
public MindViewModel(string filename, DiagramDocument diagramDocument) : base(filename, diagramDocument)
|
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)
|
foreach (var vm in DiagramViewModels)
|
||||||
{
|
{
|
||||||
vm.Init(false);
|
vm.Init(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MindDiagramViewModel != null)
|
if (MindDiagramViewModel != null)
|
||||||
{
|
{
|
||||||
SubType = MindDiagramViewModel.MindType.ToString();
|
SubType = MindDiagramViewModel.MindType.ToString();
|
||||||
@@ -72,7 +77,7 @@ namespace AIStudio.Wpf.DiagramApp.ViewModels
|
|||||||
|
|
||||||
public MindTheme MindTheme
|
public MindTheme MindTheme
|
||||||
{
|
{
|
||||||
get;
|
get;set;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Init(bool initNew)
|
protected override void Init(bool initNew)
|
||||||
|
|||||||
@@ -391,39 +391,14 @@ namespace AIStudio.Wpf.DiagramApp.ViewModels
|
|||||||
List<DiagramViewModel> viewModels = new List<DiagramViewModel>();
|
List<DiagramViewModel> viewModels = new List<DiagramViewModel>();
|
||||||
foreach (var diagramItem in diagramDocument.DiagramItems)
|
foreach (var diagramItem in diagramDocument.DiagramItems)
|
||||||
{
|
{
|
||||||
var viewModel = GetDiagramViewModel(diagramItem.Name, diagramItem.DiagramType, false);
|
var viewModel = GetDiagramViewModel(diagramItem, ext);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
viewModels.Add(viewModel);
|
viewModels.Add(viewModel);
|
||||||
}
|
}
|
||||||
DiagramViewModels = new ObservableCollection<IDiagramViewModel>(viewModels);
|
DiagramViewModels = new ObservableCollection<IDiagramViewModel>(viewModels);
|
||||||
|
foreach (var vm in DiagramViewModels)
|
||||||
|
{
|
||||||
|
vm.Init(false);
|
||||||
|
}
|
||||||
DiagramViewModel = DiagramViewModels.FirstOrDefault();
|
DiagramViewModel = DiagramViewModels.FirstOrDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -456,14 +431,6 @@ namespace AIStudio.Wpf.DiagramApp.ViewModels
|
|||||||
foreach (var viewModel in DiagramViewModels)
|
foreach (var viewModel in DiagramViewModels)
|
||||||
{
|
{
|
||||||
DiagramItem diagramItem = new DiagramItem(viewModel);
|
DiagramItem diagramItem = new DiagramItem(viewModel);
|
||||||
|
|
||||||
var selectedDesignerItems = viewModel.Items.OfType<DesignerItemViewModelBase>();
|
|
||||||
var selectedConnections = viewModel.Items.OfType<ConnectionViewModel>();
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
|
|
||||||
diagramDocument.DiagramItems.Add(diagramItem);
|
diagramDocument.DiagramItems.Add(diagramItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -498,6 +465,11 @@ namespace AIStudio.Wpf.DiagramApp.ViewModels
|
|||||||
InitDiagramViewModel();
|
InitDiagramViewModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual DiagramViewModel GetDiagramViewModel(DiagramItem diagramItem, string ext)
|
||||||
|
{
|
||||||
|
return new BlockDiagramViewModel(diagramItem, ext);
|
||||||
|
}
|
||||||
|
|
||||||
protected virtual DiagramViewModel GetDiagramViewModel(string name, DiagramType diagramType, bool initNew)
|
protected virtual DiagramViewModel GetDiagramViewModel(string name, DiagramType diagramType, bool initNew)
|
||||||
{
|
{
|
||||||
return new BlockDiagramViewModel() { Name = name ?? NewNameHelper.GetNewName(DiagramViewModels.Select(p => p.Name), "页-"), DiagramType = diagramType };
|
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;
|
var viewModel = DiagramViewModel;
|
||||||
DiagramItem diagramItem = new DiagramItem(viewModel);
|
DiagramItem diagramItem = new DiagramItem(viewModel);
|
||||||
|
diagramItem.Name = NewNameHelper.GetNewName(DiagramViewModels.Select(p => p.Name), "页-");
|
||||||
|
|
||||||
var selectedDesignerItems = viewModel.Items.OfType<DesignerItemViewModelBase>();
|
viewModel = GetDiagramViewModel(diagramItem, ".json");
|
||||||
var selectedConnections = viewModel.Items.OfType<ConnectionViewModel>();
|
|
||||||
|
|
||||||
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<ConnectionItem>(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);
|
|
||||||
}
|
|
||||||
|
|
||||||
DiagramViewModels.Add(viewModel);
|
DiagramViewModels.Add(viewModel);
|
||||||
DiagramViewModel = viewModel;
|
DiagramViewModel = viewModel;
|
||||||
|
|||||||
@@ -2660,14 +2660,14 @@
|
|||||||
<i:CallMethodAction MethodName="View_Loaded" TargetObject="{Binding}" />
|
<i:CallMethodAction MethodName="View_Loaded" TargetObject="{Binding}" />
|
||||||
</i:EventTrigger>
|
</i:EventTrigger>
|
||||||
</i:Interaction.Triggers>
|
</i:Interaction.Triggers>
|
||||||
<dd:DiagramTabControl ItemsSource="{Binding DiagramViewModels}" SelectedItem="{Binding DiagramViewModel}" Style="{StaticResource AIStudio.DiagramApp.Styles.TabControl}"
|
<TabControl ItemsSource="{Binding DiagramViewModels}" SelectedItem="{Binding DiagramViewModel}" Style="{StaticResource AIStudio.DiagramApp.Styles.TabControl}" dd:DiagramTabControl.IsCached="True"
|
||||||
BorderThickness="0" Margin="0" Padding="0">
|
BorderThickness="0" Margin="0" Padding="0">
|
||||||
<TabControl.ItemContainerStyle>
|
<TabControl.ItemContainerStyle>
|
||||||
<Style>
|
<Style>
|
||||||
<Setter Property="TabItem.Visibility" Value="Collapsed"/>
|
<Setter Property="TabItem.Visibility" Value="Collapsed"/>
|
||||||
</Style>
|
</Style>
|
||||||
</TabControl.ItemContainerStyle>
|
</TabControl.ItemContainerStyle>
|
||||||
<TabControl.ContentTemplate>
|
<dd:DiagramTabControl.Template>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<Grid>
|
<Grid>
|
||||||
<ScrollViewer x:Name="designerScrollViewer"
|
<ScrollViewer x:Name="designerScrollViewer"
|
||||||
@@ -2736,8 +2736,8 @@
|
|||||||
Margin="20,0,0,20" />
|
Margin="20,0,0,20" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</TabControl.ContentTemplate>
|
</dd:DiagramTabControl.Template>
|
||||||
</dd:DiagramTabControl>
|
</TabControl>
|
||||||
</Grid>
|
</Grid>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</dragablz:TabablzControl.ContentTemplate>
|
</dragablz:TabablzControl.ContentTemplate>
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.31" />
|
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.31" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||||
<PackageReference Include="SvgPathProperties" Version="1.1.2" />
|
<PackageReference Include="SvgPathProperties" Version="1.1.2" />
|
||||||
|
<PackageReference Include="System.Drawing.Common" Version="6.0.0" />
|
||||||
<PackageReference Include="System.Management" Version="7.0.0" />
|
<PackageReference Include="System.Management" Version="7.0.0" />
|
||||||
<PackageReference Include="System.Reactive" Version="5.0.0" />
|
<PackageReference Include="System.Reactive" Version="5.0.0" />
|
||||||
<PackageReference Include="WpfAnimatedGif" Version="2.0.0" />
|
<PackageReference Include="WpfAnimatedGif" Version="2.0.0" />
|
||||||
|
|||||||
@@ -86,11 +86,11 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
dataObject.Icon = toolBoxData.Icon;
|
dataObject.Icon = toolBoxData.Icon;
|
||||||
dataObject.Text = toolBoxData.Text;
|
dataObject.Text = toolBoxData.Text;
|
||||||
dataObject.ColorViewModel = toolBoxData.ColorViewModel;
|
dataObject.ColorViewModel = toolBoxData.ColorViewModel;
|
||||||
//if (toolBoxData.Addition is DesignerItemViewModelBase designerItemViewModelBase)
|
if (toolBoxData.Addition is DesignerItemViewModelBase designerItemViewModelBase)
|
||||||
//{
|
{
|
||||||
// dataObject.DesignerItem = designerItemViewModelBase.ToSerializableItem();
|
dataObject.DesignerItem = designerItemViewModelBase.ToSerializableItem();
|
||||||
//}
|
}
|
||||||
//else
|
else
|
||||||
{
|
{
|
||||||
dataObject.DesignerItem = toolBoxData.Addition;
|
dataObject.DesignerItem = toolBoxData.Addition;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using System.Windows.Documents;
|
|||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Windows.Resources;
|
using System.Windows.Resources;
|
||||||
|
using AIStudio.Wpf.DiagramDesigner.Helpers;
|
||||||
using AIStudio.Wpf.DiagramDesigner.Models;
|
using AIStudio.Wpf.DiagramDesigner.Models;
|
||||||
using AIStudio.Wpf.DiagramDesigner.ViewModels;
|
using AIStudio.Wpf.DiagramDesigner.ViewModels;
|
||||||
using AIStudio.Wpf.DiagramDesigner.ViewModels.BaseViewModel;
|
using AIStudio.Wpf.DiagramDesigner.ViewModels.BaseViewModel;
|
||||||
@@ -714,6 +715,29 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
}
|
}
|
||||||
_viewModel.AddCommand.Execute(designerItems);
|
_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<BlockDesignerItemViewModel> { block });
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DesignerItemViewModelBase itemBase = null;
|
DesignerItemViewModelBase itemBase = null;
|
||||||
|
|||||||
318
AIStudio.Wpf.DiagramDesigner/Controls/DiagramTabControl.cs
Normal file
318
AIStudio.Wpf.DiagramDesigner/Controls/DiagramTabControl.cs
Normal file
@@ -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;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attached properties for persistent tab control
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>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.
|
||||||
|
/// </remarks>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Controls whether tab content is cached or not
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>When DiagramTabControl.IsCached is true, visual state of each tab is preserved (cached), even when the tab is hidden</remarks>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used instead of TabControl.ContentTemplate for cached tabs
|
||||||
|
/// </summary>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used instead of TabControl.ContentTemplateSelector for cached tabs
|
||||||
|
/// </summary>
|
||||||
|
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 =
|
||||||
|
"<DataTemplate><Border b:DiagramTabControl.InternalTabControl=\"{Binding RelativeSource={RelativeSource AncestorType=TabControl}}\" /></DataTemplate>";
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -213,7 +213,7 @@ namespace AIStudio.Wpf.DiagramDesigner.Controls
|
|||||||
|
|
||||||
protected override void OnPreviewMouseLeftButtonUp(MouseButtonEventArgs e)
|
protected override void OnPreviewMouseLeftButtonUp(MouseButtonEventArgs e)
|
||||||
{
|
{
|
||||||
base.OnPreviewMouseLeftButtonDown(e);
|
base.OnPreviewMouseLeftButtonUp(e);
|
||||||
|
|
||||||
if (EditClickCount == 1)
|
if (EditClickCount == 1)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Imaging;
|
using System.Drawing.Imaging;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.IO.Pipes;
|
||||||
using System.Runtime.InteropServices.ComTypes;
|
using System.Runtime.InteropServices.ComTypes;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Media.Imaging;
|
using System.Windows.Media.Imaging;
|
||||||
@@ -29,11 +31,6 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
rtb.Render(element);
|
rtb.Render(element);
|
||||||
var bit = BitmapSourceToBitmap(rtb);
|
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;
|
return bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,11 +48,6 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
|
|
||||||
var bit = BitmapSourceToBitmap(rtb);
|
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;
|
return bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,6 +117,106 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
return bitmapImage;
|
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)
|
public static string ToBase64String(this System.Windows.Media.Brush brush)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -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))
|
if (string.IsNullOrEmpty(base64String))
|
||||||
return null;
|
return null;
|
||||||
@@ -174,17 +296,10 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var byteArray = Convert.FromBase64String(base64String);
|
var byteArray = Convert.FromBase64String(base64String);
|
||||||
BitmapImage bitmapImage = null;
|
var stream = new MemoryStream(byteArray);
|
||||||
bitmapImage = new BitmapImage();
|
stream.Seek(0, SeekOrigin.Begin);
|
||||||
bitmapImage.BeginInit();
|
|
||||||
bitmapImage.CreateOptions = BitmapCreateOptions.IgnoreColorProfile;
|
|
||||||
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
|
|
||||||
bitmapImage.DecodePixelWidth = width;//需要缩略图的解码宽度
|
|
||||||
bitmapImage.DecodePixelHeight = height;//缩略图的解码高度
|
|
||||||
bitmapImage.StreamSource = new MemoryStream(byteArray);
|
|
||||||
bitmapImage.EndInit();
|
|
||||||
|
|
||||||
return new System.Windows.Media.ImageBrush(bitmapImage) { Stretch = System.Windows.Media.Stretch.Uniform };
|
return stream;
|
||||||
}
|
}
|
||||||
catch
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
this.ChildFlag = viewmodel.ChildFlag;
|
this.ChildFlag = viewmodel.ChildFlag;
|
||||||
this.PhysicalItemWidth = viewmodel.PhysicalItemWidth;
|
this.PhysicalItemWidth = viewmodel.PhysicalItemWidth;
|
||||||
this.PhysicalItemHeight = viewmodel.PhysicalItemHeight;
|
this.PhysicalItemHeight = viewmodel.PhysicalItemHeight;
|
||||||
|
this.Parameter = new ConstParameterItem(viewmodel.Parameter);
|
||||||
|
|
||||||
Children = new List<BlockDesignerItem>(viewmodel.Children.Select(p => new BlockDesignerItem(p)));
|
Children = new List<BlockDesignerItem>(viewmodel.Children.Select(p => new BlockDesignerItem(p)));
|
||||||
}
|
}
|
||||||
@@ -52,6 +53,12 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
get; set;
|
get; set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[XmlElement]
|
||||||
|
public ConstParameterItem Parameter
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
[XmlArray]
|
[XmlArray]
|
||||||
public List<BlockDesignerItem> Children
|
public List<BlockDesignerItem> Children
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Xml;
|
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;
|
Name = diagramView.Name;
|
||||||
DiagramType = diagramView.DiagramType;
|
DiagramType = diagramView.DiagramType;
|
||||||
@@ -30,9 +31,16 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
PageSizeType = diagramView.DiagramOption.LayoutOption.PageSizeType;
|
PageSizeType = diagramView.DiagramOption.LayoutOption.PageSizeType;
|
||||||
PhysicalGridMarginSize = diagramView.DiagramOption.LayoutOption.PhysicalGridMarginSize;
|
PhysicalGridMarginSize = diagramView.DiagramOption.LayoutOption.PhysicalGridMarginSize;
|
||||||
GridColor = diagramView.DiagramOption.LayoutOption.GridColor;
|
GridColor = diagramView.DiagramOption.LayoutOption.GridColor;
|
||||||
|
PageBackground = diagramView.DiagramOption.LayoutOption.PageBackground;
|
||||||
AllowDrop = diagramView.DiagramOption.LayoutOption.AllowDrop;
|
AllowDrop = diagramView.DiagramOption.LayoutOption.AllowDrop;
|
||||||
|
|
||||||
Thumbnail = diagramView.Thumbnail.ToBase64String();
|
Thumbnail = diagramView.Thumbnail.ToBase64String();
|
||||||
|
|
||||||
|
var selectedDesignerItems = diagramView.Items.OfType<DesignerItemViewModelBase>();
|
||||||
|
var selectedConnections = diagramView.Items.OfType<ConnectionViewModel>();
|
||||||
|
|
||||||
|
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]
|
[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]
|
[XmlAttribute]
|
||||||
public bool AllowDrop
|
public bool AllowDrop
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ using System.Text;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using System.Xml.Serialization;
|
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]));
|
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)
|
public static string SerializeObject(object obj, string serializableType = null)
|
||||||
{
|
{
|
||||||
if (serializableType?.ToLower() == ".xml")
|
if (serializableType?.ToLower() == ".xml")
|
||||||
|
|||||||
@@ -4,7 +4,15 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
{
|
{
|
||||||
public class ConstParameter : BindableBase, IParameter
|
public class ConstParameter : BindableBase, IParameter
|
||||||
{
|
{
|
||||||
|
public ConstParameter()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConstParameter(ConstParameterItem item)
|
||||||
|
{
|
||||||
|
Text = item.Text;
|
||||||
|
Value = item.Value?.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
private string _text;
|
private string _text;
|
||||||
|
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
private static PointBase[] GetRouteWithMiddlePoints(IDiagramViewModel _, ConnectionViewModel link, PointBase[] route)
|
private static PointBase[] GetRouteWithMiddlePoints(IDiagramViewModel _, ConnectionViewModel link, PointBase[] route)
|
||||||
{
|
{
|
||||||
var middle = GetMiddlePoints(
|
var middle = GetMiddlePoints(
|
||||||
link.SourceConnectorInfoFully.MiddlePosition,
|
link.SourceConnectorInfo.MiddlePosition,
|
||||||
link.SourceConnectorInfoFully.Orientation,
|
link.SourceConnectorInfo.Orientation,
|
||||||
link.SinkConnectorInfo.MiddlePosition,
|
link.SinkConnectorInfo.MiddlePosition,
|
||||||
link.IsFullConnection ? link.SinkConnectorInfoFully.Orientation : (link.SinkConnectorInfo.MiddlePosition.Y >= link.SourceConnectorInfo.MiddlePosition.Y ? ConnectorOrientation.Top : ConnectorOrientation.Bottom),
|
link.IsFullConnection ? link.SinkConnectorInfoFully.Orientation : (link.SinkConnectorInfo.MiddlePosition.Y >= link.SourceConnectorInfo.MiddlePosition.Y ? ConnectorOrientation.Top : ConnectorOrientation.Bottom),
|
||||||
_.DiagramOption.LayoutOption.GridCellSize,
|
_.DiagramOption.LayoutOption.GridCellSize,
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace AIStudio.Wpf.DiagramDesigner.Services
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dataContextForPopup">Object state to associate with the dialog</param>
|
/// <param name="dataContextForPopup">Object state to associate with the dialog</param>
|
||||||
/// <returns>True/False if UI is displayed.</returns>
|
/// <returns>True/False if UI is displayed.</returns>
|
||||||
bool? ShowDialog(object dataContextForPopup);
|
bool? ShowDialog(object dataContextForPopup, bool buttonVisable = true);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This method displays a modal dialog associated with the given key.
|
/// This method displays a modal dialog associated with the given key.
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ namespace AIStudio.Wpf.DiagramDesigner.Services
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dataContextForPopup">Object state to associate with the dialog</param>
|
/// <param name="dataContextForPopup">Object state to associate with the dialog</param>
|
||||||
/// <returns>True/False if UI is displayed.</returns>
|
/// <returns>True/False if UI is displayed.</returns>
|
||||||
public bool? ShowDialog(object dataContextForPopup)
|
public bool? ShowDialog(object dataContextForPopup, bool buttonVisable = true)
|
||||||
{
|
{
|
||||||
Window win = new PopupWindow();
|
Window win = new PopupWindow();
|
||||||
win.DataContext = dataContextForPopup;
|
win.DataContext = dataContextForPopup;
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
this.ChildFlag = designer.ChildFlag;
|
this.ChildFlag = designer.ChildFlag;
|
||||||
this.PhysicalItemWidth = designer.PhysicalItemWidth;
|
this.PhysicalItemWidth = designer.PhysicalItemWidth;
|
||||||
this.PhysicalItemHeight = designer.PhysicalItemHeight;
|
this.PhysicalItemHeight = designer.PhysicalItemHeight;
|
||||||
|
this.Parameter = new ConstParameter(designer.Parameter);
|
||||||
if (designer.Children != null)
|
if (designer.Children != null)
|
||||||
{
|
{
|
||||||
foreach (var child in designer.Children)
|
foreach (var child in designer.Children)
|
||||||
@@ -178,8 +179,8 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private IParameter _parameter;
|
private ConstParameter _parameter;
|
||||||
public IParameter Parameter
|
public ConstParameter Parameter
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@@ -350,5 +351,15 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
base.Dispose();
|
||||||
|
|
||||||
|
foreach (var child in Children)
|
||||||
|
{
|
||||||
|
child.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -814,7 +814,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
BuildMenuOptions();
|
BuildMenuOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
public DiagramViewModel(DiagramItem diagramItem, string ext) : this()
|
public DiagramViewModel(DiagramItem diagramItem, string ext =".json") : this()
|
||||||
{
|
{
|
||||||
Init(diagramItem);
|
Init(diagramItem);
|
||||||
|
|
||||||
@@ -849,6 +849,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
public void Init(DiagramItem diagramItem)
|
public void Init(DiagramItem diagramItem)
|
||||||
{
|
{
|
||||||
DiagramType = diagramItem.DiagramType;
|
DiagramType = diagramItem.DiagramType;
|
||||||
|
Name = diagramItem.Name;
|
||||||
DiagramOption.LayoutOption.ShowGrid = diagramItem.ShowGrid;
|
DiagramOption.LayoutOption.ShowGrid = diagramItem.ShowGrid;
|
||||||
DiagramOption.LayoutOption.PhysicalGridCellSize = diagramItem.PhysicalGridCellSize;
|
DiagramOption.LayoutOption.PhysicalGridCellSize = diagramItem.PhysicalGridCellSize;
|
||||||
DiagramOption.LayoutOption.CellHorizontalAlignment = diagramItem.CellHorizontalAlignment;
|
DiagramOption.LayoutOption.CellHorizontalAlignment = diagramItem.CellHorizontalAlignment;
|
||||||
@@ -858,6 +859,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
DiagramOption.LayoutOption.PageSizeType = diagramItem.PageSizeType;
|
DiagramOption.LayoutOption.PageSizeType = diagramItem.PageSizeType;
|
||||||
DiagramOption.LayoutOption.PhysicalGridMarginSize = diagramItem.PhysicalGridMarginSize;
|
DiagramOption.LayoutOption.PhysicalGridMarginSize = diagramItem.PhysicalGridMarginSize;
|
||||||
DiagramOption.LayoutOption.GridColor = diagramItem.GridColor;
|
DiagramOption.LayoutOption.GridColor = diagramItem.GridColor;
|
||||||
|
DiagramOption.LayoutOption.PageBackground = diagramItem.PageBackground;
|
||||||
DiagramOption.LayoutOption.AllowDrop = diagramItem.AllowDrop;
|
DiagramOption.LayoutOption.AllowDrop = diagramItem.AllowDrop;
|
||||||
|
|
||||||
Thumbnail = diagramItem.Thumbnail.ToBrush((int)DiagramOption.LayoutOption.PageSize.Width / 4, (int)DiagramOption.LayoutOption.PageSize.Height / 4);
|
Thumbnail = diagramItem.Thumbnail.ToBrush((int)DiagramOption.LayoutOption.PageSize.Width / 4, (int)DiagramOption.LayoutOption.PageSize.Height / 4);
|
||||||
|
|||||||
@@ -530,6 +530,19 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
base.Dispose();
|
||||||
|
|
||||||
|
if (ParentContainer == null)
|
||||||
|
{
|
||||||
|
foreach (var container in Containers)
|
||||||
|
{
|
||||||
|
container.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#region 扩展
|
#region 扩展
|
||||||
|
|||||||
@@ -14,6 +14,11 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BlockDiagramViewModel(DiagramItem diagramItem, string ext) : base(diagramItem, ext)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#region
|
#region
|
||||||
private ICommand _addNextCommand;
|
private ICommand _addNextCommand;
|
||||||
public ICommand AddNextCommand
|
public ICommand AddNextCommand
|
||||||
|
|||||||
@@ -18,13 +18,13 @@
|
|||||||
<ColumnDefinition Width="Auto"/>
|
<ColumnDefinition Width="Auto"/>
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<!-- ToolBox Control -->
|
<!-- ToolBox Control -->
|
||||||
<ContentControl Template="{Binding ToolBox,RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"/>
|
<ContentControl Template="{Binding ToolBox,RelativeSource={RelativeSource AncestorType={x:Type Control}}}"/>
|
||||||
|
|
||||||
<ScrollViewer Grid.Column="1">
|
<ScrollViewer Grid.Column="1">
|
||||||
<!-- Diagram Control -->
|
<!-- Diagram Control -->
|
||||||
<dd:DiagramControl x:Name="PART_DiagramControl" MinWidth="1000" MinHeight="1000" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
|
<dd:DiagramControl x:Name="PART_DiagramControl" MinWidth="1000" MinHeight="1000" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
<ContentControl Grid.Column="2" x:Name="properity" Template="{Binding PropertiesBox,RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"/>
|
<ContentControl Grid.Column="2" x:Name="properity" Template="{Binding PropertiesBox,RelativeSource={RelativeSource AncestorType={x:Type Control}}}"/>
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</ControlTemplate>
|
</ControlTemplate>
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace AIStudio.Wpf.Flowchart.Controls
|
|||||||
/// FlowchartEditor.xaml 的交互逻辑
|
/// FlowchartEditor.xaml 的交互逻辑
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[TemplatePart(Name = PART_DiagramControl, Type = typeof(DiagramControl))]
|
[TemplatePart(Name = PART_DiagramControl, Type = typeof(DiagramControl))]
|
||||||
public partial class FlowchartEditor : UserControl
|
public partial class FlowchartEditor : Control
|
||||||
{
|
{
|
||||||
public const string PART_DiagramControl = "PART_DiagramControl";
|
public const string PART_DiagramControl = "PART_DiagramControl";
|
||||||
private DiagramControl _diagramControl;
|
private DiagramControl _diagramControl;
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<RowDefinition/>
|
<RowDefinition/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<!-- ToolBox Control -->
|
<!-- ToolBox Control -->
|
||||||
<ContentControl x:Name="PART_ContentControl" Template="{Binding ToolBox,RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"/>
|
<ContentControl x:Name="PART_ContentControl" Template="{Binding ToolBox,RelativeSource={RelativeSource AncestorType={x:Type Control}}}"/>
|
||||||
|
|
||||||
<!-- Diagram Control -->
|
<!-- Diagram Control -->
|
||||||
<dd:DiagramControl Grid.Row="1" x:Name="PART_DiagramControl" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
|
<dd:DiagramControl Grid.Row="1" x:Name="PART_DiagramControl" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ namespace AIStudio.Wpf.Mind.Controls
|
|||||||
[TemplatePart(Name = PART_DiagramControl, Type = typeof(DiagramControl))]
|
[TemplatePart(Name = PART_DiagramControl, Type = typeof(DiagramControl))]
|
||||||
[TemplatePart(Name = PART_ContentControl, Type = typeof(ContentControl))]
|
[TemplatePart(Name = PART_ContentControl, Type = typeof(ContentControl))]
|
||||||
[TemplatePart(Name = PART_SearchControl, Type = typeof(Border))]
|
[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_DiagramControl = "PART_DiagramControl";
|
||||||
public const string PART_ContentControl = "PART_ContentControl";
|
public const string PART_ContentControl = "PART_ContentControl";
|
||||||
|
|||||||
BIN
Images/微信图片_20230825164357.png
Normal file
BIN
Images/微信图片_20230825164357.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.7 KiB |
@@ -746,6 +746,10 @@ nuget地址:
|
|||||||
|
|
||||||
<img src="Images/da3cc91baa07eb81acebf9fc1246a01.jpg" width=30%>
|
<img src="Images/da3cc91baa07eb81acebf9fc1246a01.jpg" width=30%>
|
||||||
|
|
||||||
|
## 捐赠列表:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
相关链接地址:
|
相关链接地址:
|
||||||
|
|
||||||
Fluent.Ribbon: https://github.com/fluentribbon/Fluent.Ribbon
|
Fluent.Ribbon: https://github.com/fluentribbon/Fluent.Ribbon
|
||||||
|
|||||||
Reference in New Issue
Block a user