mirror of
https://gitee.com/akwkevin/aistudio.-wpf.-diagram
synced 2026-04-05 16:56:34 +08:00
Mind Editoe
This commit is contained in:
@@ -32,27 +32,18 @@ namespace AIStudio.Wpf.Flowchart
|
||||
|
||||
DiagramViewModel.GridCellSize = new Size(100, 100);
|
||||
DiagramViewModel.ShowGrid= false;
|
||||
_service.DrawModeViewModel.LineDrawMode = DrawMode.ConnectingLineSmooth;
|
||||
DiagramViewModel.AllowDrop = false;
|
||||
}
|
||||
|
||||
|
||||
private MindType _mindType = Mind.MindType.FishBone;
|
||||
public MindType MindType
|
||||
{
|
||||
get
|
||||
{
|
||||
return _mindType;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetProperty(ref _mindType, value);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Init()
|
||||
{
|
||||
base.Init();
|
||||
DiagramViewModels = new ObservableCollection<IDiagramViewModel>()
|
||||
{
|
||||
new MindDiagramViewModel(){Name= "页-1", DiagramType = DiagramType},
|
||||
};
|
||||
DiagramViewModel = DiagramViewModels.FirstOrDefault();
|
||||
|
||||
InitDiagramViewModel();
|
||||
|
||||
MindNode level1node = new MindNode(DiagramViewModel, Mind.NodeLevel.Level1, MindType) { Text = "思维导图" };
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(level1node);
|
||||
@@ -76,12 +67,28 @@ namespace AIStudio.Wpf.Flowchart
|
||||
MindNode level2node1_3 = new MindNode(DiagramViewModel, Mind.NodeLevel.Level2, MindType) { Text = "分支主题3" };
|
||||
level1node.AddChild(level2node1_3);
|
||||
|
||||
DiagramViewModel.ClearSelectedItemsCommand.Execute(null);
|
||||
DiagramViewModel.ClearSelectedItemsCommand.Execute(null);
|
||||
level1node.LayoutUpdated();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private MindType _mindType = Mind.MindType.Organizational;
|
||||
public MindType MindType
|
||||
{
|
||||
get
|
||||
{
|
||||
return _mindType;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _mindType, value))
|
||||
{
|
||||
//DiagramViewModel as MindDiagramViewModel
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
base.Dispose();
|
||||
|
||||
@@ -31,12 +31,6 @@ namespace AIStudio.Wpf.DiagramApp.ViewModels
|
||||
Status = status;
|
||||
DiagramType = diagramType;
|
||||
|
||||
DiagramViewModels = new ObservableCollection<IDiagramViewModel>()
|
||||
{
|
||||
new DiagramViewModel(){Name= "页-1", DiagramType = diagramType},
|
||||
};
|
||||
DiagramViewModel = DiagramViewModels.FirstOrDefault();
|
||||
|
||||
Init();
|
||||
}
|
||||
public PageViewModel(string filename)
|
||||
@@ -61,6 +55,12 @@ namespace AIStudio.Wpf.DiagramApp.ViewModels
|
||||
|
||||
protected virtual void Init()
|
||||
{
|
||||
DiagramViewModels = new ObservableCollection<IDiagramViewModel>()
|
||||
{
|
||||
new DiagramViewModel(){Name= "页-1", DiagramType = DiagramType},
|
||||
};
|
||||
DiagramViewModel = DiagramViewModels.FirstOrDefault();
|
||||
|
||||
InitDiagramViewModel();
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
Icon="A.ico"
|
||||
Identifier="RootWindow"
|
||||
Style="{StaticResource AIStudio.Styles.WindowBase}"
|
||||
Height="450" Width="800">
|
||||
Height="600" Width="850">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" MinWidth="100" />
|
||||
|
||||
@@ -16,10 +16,17 @@
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid>
|
||||
|
||||
<dd:FlowchartEditor Data="{Binding Data}"
|
||||
GetDataFunc="{Binding GetDataFunc,Mode=OneWayToSource}"
|
||||
Users="{Binding Users}"
|
||||
Roles="{Binding Roles}">
|
||||
</dd:FlowchartEditor>
|
||||
|
||||
<Grid Grid.Row="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
@@ -40,11 +47,6 @@
|
||||
Height="50"/>
|
||||
|
||||
</Grid>
|
||||
<dd:FlowchartEditor Grid.Row="1" Data="{Binding Data}"
|
||||
GetDataFunc="{Binding GetDataFunc,Mode=OneWayToSource}"
|
||||
Users="{Binding Users}"
|
||||
Roles="{Binding Roles}">
|
||||
</dd:FlowchartEditor>
|
||||
|
||||
<controls:TitleControl Grid.RowSpan="2"/>
|
||||
</Grid>
|
||||
|
||||
@@ -16,10 +16,14 @@
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid>
|
||||
|
||||
<dd:MindEditor Data="{Binding Data}"
|
||||
GetDataFunc="{Binding GetDataFunc,Mode=OneWayToSource}">
|
||||
</dd:MindEditor>
|
||||
<Grid Grid.Row="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
@@ -40,10 +44,6 @@
|
||||
Height="50"/>
|
||||
|
||||
</Grid>
|
||||
<dd:MindEditor Grid.Row="1" Data="{Binding Data}"
|
||||
GetDataFunc="{Binding GetDataFunc,Mode=OneWayToSource}">
|
||||
</dd:MindEditor>
|
||||
|
||||
<controls:TitleControl Grid.RowSpan="2"/>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
@@ -6,7 +6,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace AIStudio.Wpf.DiagramDesigner
|
||||
{
|
||||
class DoCommandManager
|
||||
public class DoCommandManager
|
||||
{
|
||||
#region Command定义
|
||||
public class Command
|
||||
@@ -24,9 +24,18 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
this.clearAction = clearAction;
|
||||
}
|
||||
|
||||
internal void Do() { action(); }
|
||||
internal void UnDo() { unDoAction(); }
|
||||
internal void Clear() { if (clearAction != null) clearAction(); }
|
||||
internal void Do()
|
||||
{
|
||||
action();
|
||||
}
|
||||
internal void UnDo()
|
||||
{
|
||||
unDoAction();
|
||||
}
|
||||
internal void Clear()
|
||||
{
|
||||
if (clearAction != null) clearAction();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
@@ -35,35 +44,57 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
}
|
||||
#endregion
|
||||
|
||||
public Stack<Command> ReDoActionStack { get; private set; }
|
||||
public Stack<Command> UnDoActionStack { get; private set; }
|
||||
public Stack<Command> ReDoActionStack
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
public Stack<Command> UnDoActionStack
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public int Capacity { get; set; } = 10;
|
||||
|
||||
public DoCommandManager()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
ReDoActionStack = new Stack<Command>();
|
||||
UnDoActionStack = new Stack<Command>();
|
||||
}
|
||||
|
||||
private bool _undoing;
|
||||
public void DoNewCommand(string name, Action action, Action unDoAction, Action clearAction = null, bool doit = true)
|
||||
{
|
||||
if (UnDoActionStack.Count >= Capacity)
|
||||
{
|
||||
//清理
|
||||
var clear = UnDoActionStack.LastOrDefault();
|
||||
clear.Clear();
|
||||
|
||||
UnDoActionStack = new Stack<Command>(UnDoActionStack.Take(Capacity - 1).Reverse());
|
||||
}
|
||||
|
||||
var cmd = new Command(name, action, unDoAction, clearAction);
|
||||
UnDoActionStack.Push(cmd);
|
||||
|
||||
ReDoActionStack.Clear();
|
||||
if (doit)
|
||||
if (_undoing == true) return;
|
||||
try
|
||||
{
|
||||
cmd.Do();
|
||||
_undoing = true;
|
||||
|
||||
if (UnDoActionStack.Count >= Capacity)
|
||||
{
|
||||
//清理
|
||||
var clear = UnDoActionStack.LastOrDefault();
|
||||
clear.Clear();
|
||||
|
||||
UnDoActionStack = new Stack<Command>(UnDoActionStack.Take(Capacity - 1).Reverse());
|
||||
}
|
||||
|
||||
var cmd = new Command(name, action, unDoAction, clearAction);
|
||||
UnDoActionStack.Push(cmd);
|
||||
|
||||
ReDoActionStack.Clear();
|
||||
if (doit)
|
||||
{
|
||||
cmd.Do();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_undoing = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,9 +103,19 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
if (!CanUnDo)
|
||||
return;
|
||||
|
||||
var cmd = UnDoActionStack.Pop();
|
||||
ReDoActionStack.Push(cmd);
|
||||
cmd.UnDo();
|
||||
if (_undoing == true) return;
|
||||
try
|
||||
{
|
||||
_undoing = true;
|
||||
|
||||
var cmd = UnDoActionStack.Pop();
|
||||
ReDoActionStack.Push(cmd);
|
||||
cmd.UnDo();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_undoing = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void ReDo()
|
||||
@@ -82,13 +123,34 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
if (!CanReDo)
|
||||
return;
|
||||
|
||||
var cmd = ReDoActionStack.Pop();
|
||||
UnDoActionStack.Push(cmd);
|
||||
cmd.Do();
|
||||
if (_undoing == true) return;
|
||||
try
|
||||
{
|
||||
_undoing = true;
|
||||
var cmd = ReDoActionStack.Pop();
|
||||
UnDoActionStack.Push(cmd);
|
||||
cmd.Do();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_undoing = false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanUnDo { get { return UnDoActionStack.Count != 0; } }
|
||||
public bool CanReDo { get { return ReDoActionStack.Count != 0; } }
|
||||
public bool CanUnDo
|
||||
{
|
||||
get
|
||||
{
|
||||
return UnDoActionStack.Count != 0;
|
||||
}
|
||||
}
|
||||
public bool CanReDo
|
||||
{
|
||||
get
|
||||
{
|
||||
return ReDoActionStack.Count != 0;
|
||||
}
|
||||
}
|
||||
//public IEnumerable<Command> Actions { get { return ReDoActionStack.Reverse().Concat(UnDoActionStack); } }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AIStudio.Wpf.DiagramDesigner.Helpers
|
||||
{
|
||||
public static class IEnumerableExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Invokes a transform function on each element of a sequence and returns the minimum Double value
|
||||
/// if the sequence is not empty; otherwise returns the specified default value.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSource"> The type of the elements of source. </typeparam>
|
||||
/// <param name="source"> A sequence of values to determine the minimum value of. </param>
|
||||
/// <param name="selector"> A transform function to apply to each element. </param>
|
||||
/// <param name="defaultValue"> The default value. </param>
|
||||
/// <returns> The minimum value in the sequence or default value if sequence is empty. </returns>
|
||||
public static double MinOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, double> selector, double defaultValue=default(double))
|
||||
{
|
||||
if (source.Any<TSource>())
|
||||
return source.Min<TSource>(selector);
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes a transform function on each element of a sequence and returns the maximum Double value
|
||||
/// if the sequence is not empty; otherwise returns the specified default value.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSource"> The type of the elements of source. </typeparam>
|
||||
/// <param name="source"> A sequence of values to determine the maximum value of. </param>
|
||||
/// <param name="selector"> A transform function to apply to each element. </param>
|
||||
/// <param name="defaultValue"> The default value. </param>
|
||||
/// <returns> The maximum value in the sequence or default value if sequence is empty. </returns>
|
||||
public static double MaxOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, double> selector, double defaultValue=default(double))
|
||||
{
|
||||
if (source.Any<TSource>())
|
||||
return source.Max<TSource>(selector);
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
|
||||
public static TResult MinOrDefault<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector, TResult defaultValue)
|
||||
{
|
||||
if (source.Any())
|
||||
{
|
||||
return source.Min(selector);
|
||||
}
|
||||
return defaultValue;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static TResult MaxOrDefault<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector, TResult defaultValue)
|
||||
{
|
||||
if (source.Any())
|
||||
{
|
||||
return source.Max(selector);
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes a transform function on each element of a sequence and returns the minimum Double value
|
||||
/// if the sequence is not empty; otherwise returns the specified default value.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSource"> The type of the elements of source. </typeparam>
|
||||
/// <param name="source"> A sequence of values to determine the minimum value of. </param>
|
||||
/// <param name="selector"> A transform function to apply to each element. </param>
|
||||
/// <param name="defaultValue"> The default value. </param>
|
||||
/// <returns> The minimum value in the sequence or default value if sequence is empty. </returns>
|
||||
public static double SumOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, double> selector, double defaultValue=default(double))
|
||||
{
|
||||
if (source.Any<TSource>())
|
||||
return source.Sum<TSource>(selector);
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -540,9 +540,10 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
var nodeB = Get(b);
|
||||
|
||||
if (nodeA == null || nodeB == null)
|
||||
return;
|
||||
return;
|
||||
|
||||
nodeA.AdjacentNodes.Add(nodeB, a.DistanceTo(b));
|
||||
if (!nodeA.AdjacentNodes.ContainsKey(nodeB))
|
||||
nodeA.AdjacentNodes.Add(nodeB, a.DistanceTo(b));
|
||||
}
|
||||
|
||||
public bool Has(PointBase p)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:s="clr-namespace:AIStudio.Wpf.DiagramDesigner">
|
||||
xmlns:dd="clr-namespace:AIStudio.Wpf.DiagramDesigner">
|
||||
<!--TextBox水印样式-->
|
||||
<Style TargetType="{x:Type TextBox}" x:Key="WaterTextBox">
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
@@ -29,7 +29,7 @@
|
||||
</ScrollViewer>
|
||||
<!--水印-->
|
||||
<TextBlock x:Name="Message" Padding="{TemplateBinding Padding}" Visibility="Collapsed"
|
||||
Text="{TemplateBinding s:ControlAttachProperty.Watermark}" Grid.Column="1"
|
||||
Text="{TemplateBinding dd:ControlAttachProperty.Watermark}" Grid.Column="1"
|
||||
Foreground="{TemplateBinding Foreground}" IsHitTestVisible="False" Opacity="0.5"
|
||||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="5,2,5,2" />
|
||||
@@ -78,7 +78,7 @@
|
||||
</ScrollViewer>
|
||||
<!--水印-->
|
||||
<TextBlock x:Name="Message" Padding="{TemplateBinding Padding}" Visibility="Collapsed"
|
||||
Text="{TemplateBinding s:ControlAttachProperty.Watermark}" Grid.Column="1"
|
||||
Text="{TemplateBinding dd:ControlAttachProperty.Watermark}" Grid.Column="1"
|
||||
Foreground="{TemplateBinding Foreground}" IsHitTestVisible="False" Opacity="0.5"
|
||||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="5,2,5,2" />
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:s="clr-namespace:AIStudio.Wpf.DiagramDesigner">
|
||||
xmlns:dd="clr-namespace:AIStudio.Wpf.DiagramDesigner">
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="Shared.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
<Style TargetType="{x:Type s:ZoomBox}">
|
||||
<Style TargetType="{x:Type dd:ZoomBox}">
|
||||
|
||||
<Style.Resources>
|
||||
|
||||
@@ -165,7 +165,7 @@
|
||||
Value="true" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type s:ZoomBox}">
|
||||
<ControlTemplate TargetType="{x:Type dd:ZoomBox}">
|
||||
<Border CornerRadius="1"
|
||||
BorderThickness="1"
|
||||
Background="#EEE"
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:s="clr-namespace:AIStudio.Wpf.DiagramDesigner"
|
||||
xmlns:dd="clr-namespace:AIStudio.Wpf.DiagramDesigner"
|
||||
xmlns:c="clr-namespace:AIStudio.Wpf.DiagramDesigner.Controls">
|
||||
<s:ColorBrushConverter x:Key="ColorBrushConverter" />
|
||||
<s:ConectorOrientationConverter x:Key="ConectorOrientationConverter" />
|
||||
<s:ConectorValueConverter x:Key="ConectorValueConverter"/>
|
||||
<dd:ColorBrushConverter x:Key="ColorBrushConverter" />
|
||||
<dd:ConectorOrientationConverter x:Key="ConectorOrientationConverter" />
|
||||
<dd:ConectorValueConverter x:Key="ConectorValueConverter"/>
|
||||
|
||||
<DataTemplate DataType="{x:Type s:FullyCreatedConnectorInfo}">
|
||||
<DataTemplate DataType="{x:Type dd:FullyCreatedConnectorInfo}">
|
||||
<Grid Width="{Binding ConnectorWidth}" Height="{Binding ConnectorHeight}">
|
||||
<Grid.ContextMenu>
|
||||
<ContextMenu ItemsSource="{Binding MenuOptions}" >
|
||||
@@ -29,7 +29,7 @@
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate DataType="{x:Type s:LogicalConnectorInfo}">
|
||||
<DataTemplate DataType="{x:Type dd:LogicalConnectorInfo}">
|
||||
<Grid>
|
||||
<Grid Width="{Binding ConnectorWidth}" Height="{Binding ConnectorHeight}" HorizontalAlignment="Left" VerticalAlignment="Top">
|
||||
<Grid.ContextMenu>
|
||||
|
||||
@@ -1,36 +1,36 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:s="clr-namespace:AIStudio.Wpf.DiagramDesigner"
|
||||
xmlns:dd="clr-namespace:AIStudio.Wpf.DiagramDesigner"
|
||||
xmlns:c="clr-namespace:AIStudio.Wpf.DiagramDesigner.Controls"
|
||||
xmlns:sys="clr-namespace:System;assembly=mscorlib"
|
||||
xmlns:gif="http://wpfanimatedgif.codeplex.com" >
|
||||
|
||||
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
|
||||
<s:ColorBrushConverter x:Key="ColorBrushConverter" />
|
||||
<s:ConectorOrientationConverter x:Key="ConectorOrientationConverter" />
|
||||
<s:ConectorValueConverter x:Key="ConectorValueConverter"/>
|
||||
<s:ArrowPathConverter x:Key="ArrowPathConverter"/>
|
||||
<s:ArrowSizeConverter x:Key="ArrowSizeConverter"/>
|
||||
<s:LineDashConverter x:Key="LineDashConverter"/>
|
||||
<s:ClipConverter x:Key="ClipConverter"/>
|
||||
<dd:ColorBrushConverter x:Key="ColorBrushConverter" />
|
||||
<dd:ConectorOrientationConverter x:Key="ConectorOrientationConverter" />
|
||||
<dd:ConectorValueConverter x:Key="ConectorValueConverter"/>
|
||||
<dd:ArrowPathConverter x:Key="ArrowPathConverter"/>
|
||||
<dd:ArrowSizeConverter x:Key="ArrowSizeConverter"/>
|
||||
<dd:LineDashConverter x:Key="LineDashConverter"/>
|
||||
<dd:ClipConverter x:Key="ClipConverter"/>
|
||||
|
||||
<DataTemplate DataType="{x:Type s:DefaultDesignerItemViewModel}">
|
||||
<DataTemplate DataType="{x:Type dd:DefaultDesignerItemViewModel}">
|
||||
<Grid IsHitTestVisible="False">
|
||||
<Rectangle StrokeThickness="1" Fill="{Binding ColorViewModel.FillColor,Converter={StaticResource ColorBrushConverter}}" Stroke="{Binding ColorViewModel.LineColor,Converter={StaticResource ColorBrushConverter}}" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate DataType="{x:Type s:TextDesignerItemViewModel}">
|
||||
<DataTemplate DataType="{x:Type dd:TextDesignerItemViewModel}">
|
||||
<Grid >
|
||||
<Border Background="{Binding ColorViewModel.FillColor,Converter={StaticResource ColorBrushConverter}}" IsHitTestVisible="False"/>
|
||||
<Grid Margin="5">
|
||||
<s:TextControl s:ControlAttachProperty.Watermark="{Binding Watermark}" />
|
||||
<dd:TextControl dd:ControlAttachProperty.Watermark="{Binding Watermark}" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate DataType="{x:Type s:ShapeDesignerItemViewModel}">
|
||||
<DataTemplate DataType="{x:Type dd:ShapeDesignerItemViewModel}">
|
||||
<Grid IsHitTestVisible="False" Background="White">
|
||||
<Grid.ContextMenu>
|
||||
<ContextMenu>
|
||||
@@ -84,7 +84,7 @@
|
||||
<Setter.Value>
|
||||
<ControlTemplate>
|
||||
<Polyline
|
||||
Points="{Binding ConnectionPoints, Converter={x:Static s:ConnectionPointConverter.Instance}}"
|
||||
Points="{Binding ConnectionPoints, Converter={x:Static dd:ConnectionPointConverter.Instance}}"
|
||||
Stroke="{Binding ColorViewModel.LineColor,Converter={StaticResource ColorBrushConverter}}"
|
||||
StrokeThickness="{Binding ColorViewModel.LineWidth}"
|
||||
Fill="{Binding ColorViewModel.FillColor,Converter={StaticResource ColorBrushConverter}}"
|
||||
@@ -99,7 +99,7 @@
|
||||
<Setter.Value>
|
||||
<ControlTemplate>
|
||||
<Polygon
|
||||
Points="{Binding ConnectionPoints, Converter={x:Static s:ConnectionPointConverter.Instance}}"
|
||||
Points="{Binding ConnectionPoints, Converter={x:Static dd:ConnectionPointConverter.Instance}}"
|
||||
Stroke="{Binding ColorViewModel.LineColor,Converter={StaticResource ColorBrushConverter}}"
|
||||
StrokeThickness="{Binding ColorViewModel.LineWidth}"
|
||||
Fill="{Binding ColorViewModel.FillColor,Converter={StaticResource ColorBrushConverter}}"
|
||||
@@ -114,7 +114,7 @@
|
||||
<Setter.Value>
|
||||
<ControlTemplate>
|
||||
<Polyline
|
||||
Points="{Binding ConnectionPoints, Converter={x:Static s:ConnectionPointConverter.Instance}}"
|
||||
Points="{Binding ConnectionPoints, Converter={x:Static dd:ConnectionPointConverter.Instance}}"
|
||||
Stroke="{Binding ColorViewModel.LineColor,Converter={StaticResource ColorBrushConverter}}"
|
||||
StrokeThickness="{Binding ColorViewModel.LineWidth}"
|
||||
Fill="{Binding ColorViewModel.FillColor,Converter={StaticResource ColorBrushConverter}}"
|
||||
@@ -129,13 +129,13 @@
|
||||
</DataTemplate.Triggers>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate DataType="{x:Type s:GroupDesignerItemViewModel}">
|
||||
<DataTemplate DataType="{x:Type dd:GroupDesignerItemViewModel}">
|
||||
<Grid IsHitTestVisible="False">
|
||||
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate DataType="{x:Type s:GifImageItemViewModel}">
|
||||
<DataTemplate DataType="{x:Type dd:GifImageItemViewModel}">
|
||||
<Grid IsHitTestVisible="False">
|
||||
<Image Name="PART_Image_run" gif:ImageBehavior.AnimatedSource="{Binding Icon}" gif:ImageBehavior.AutoStart="True" VerticalAlignment="Center" HorizontalAlignment="Center" Visibility="Visible"/>
|
||||
<Control x:Name="control" />
|
||||
@@ -147,13 +147,13 @@
|
||||
</DataTemplate.Triggers>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate DataType="{x:Type s:VideoItemViewModel}">
|
||||
<DataTemplate DataType="{x:Type dd:VideoItemViewModel}">
|
||||
<Grid IsHitTestVisible="False">
|
||||
<MediaElement x:Name="MediaPlayer" LoadedBehavior="Play" Source="{Binding Icon}" VerticalAlignment="Center" HorizontalAlignment="Center" Visibility="Visible"/>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate DataType="{x:Type s:ImageItemViewModel}">
|
||||
<DataTemplate DataType="{x:Type dd:ImageItemViewModel}">
|
||||
<Grid ToolTip="{Binding Icon}">
|
||||
<Grid IsHitTestVisible="False" ClipToBounds="True">
|
||||
<Image x:Name="image" Source="{Binding Icon}" Stretch="Fill"
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:s="clr-namespace:AIStudio.Wpf.DiagramDesigner"
|
||||
xmlns:c="clr-namespace:AIStudio.Wpf.DiagramDesigner.Controls"
|
||||
xmlns:sys="clr-namespace:System;assembly=mscorlib"
|
||||
xmlns:gif="http://wpfanimatedgif.codeplex.com" >
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="/AIStudio.Wpf.DiagramDesigner;component/Themes/DesignerItem.xaml" />
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.DiagramDesigner;component/Styles/Button.xaml" />
|
||||
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.DiagramDesigner;component/Styles/ScrollBar.xaml" />
|
||||
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.DiagramDesigner;component/Styles/Expander.xaml" />
|
||||
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.DiagramDesigner;component/Styles/GroupBox.xaml" />
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:s="clr-namespace:AIStudio.Wpf.DiagramDesigner"
|
||||
xmlns:dd="clr-namespace:AIStudio.Wpf.DiagramDesigner"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="300" d:DesignWidth="300">
|
||||
<ItemsControl.ItemsPanel>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:s="clr-namespace:AIStudio.Wpf.DiagramDesigner"
|
||||
xmlns:dd="clr-namespace:AIStudio.Wpf.DiagramDesigner"
|
||||
xmlns:c="clr-namespace:AIStudio.Wpf.DiagramDesigner.Controls"
|
||||
xmlns:sys="clr-namespace:System;assembly=mscorlib"
|
||||
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||
@@ -15,16 +15,16 @@
|
||||
<ResourceDictionary Source="/AIStudio.Wpf.DiagramDesigner;component/Themes/Generic.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
|
||||
<s:ColorBrushConverter x:Key="ColorBrushConverter" />
|
||||
<s:ConectorOrientationConverter x:Key="ConectorOrientationConverter" />
|
||||
<s:ConectorValueConverter x:Key="ConectorValueConverter"/>
|
||||
<s:ArrowPathConverter x:Key="ArrowPathConverter"/>
|
||||
<s:ArrowSizeConverter x:Key="ArrowSizeConverter"/>
|
||||
<s:LineDashConverter x:Key="LineDashConverter"/>
|
||||
<s:ClipConverter x:Key="ClipConverter"/>
|
||||
<s:InvertBoolConverter x:Key="InvertBoolConverter"/>
|
||||
<s:ConectorStyleConverter x:Key="ConectorStyleConverter"/>
|
||||
<s:NotNullOrEmptyToBoolConverter x:Key="NotNullOrEmptyToBoolConverter"/>
|
||||
<dd:ColorBrushConverter x:Key="ColorBrushConverter" />
|
||||
<dd:ConectorOrientationConverter x:Key="ConectorOrientationConverter" />
|
||||
<dd:ConectorValueConverter x:Key="ConectorValueConverter"/>
|
||||
<dd:ArrowPathConverter x:Key="ArrowPathConverter"/>
|
||||
<dd:ArrowSizeConverter x:Key="ArrowSizeConverter"/>
|
||||
<dd:LineDashConverter x:Key="LineDashConverter"/>
|
||||
<dd:ClipConverter x:Key="ClipConverter"/>
|
||||
<dd:InvertBoolConverter x:Key="InvertBoolConverter"/>
|
||||
<dd:ConectorStyleConverter x:Key="ConectorStyleConverter"/>
|
||||
<dd:NotNullOrEmptyToBoolConverter x:Key="NotNullOrEmptyToBoolConverter"/>
|
||||
|
||||
<!-- ResizeDecorator Default Template -->
|
||||
<!--
|
||||
@@ -145,7 +145,7 @@
|
||||
|
||||
<ObjectDataProvider x:Key="ConnectorOrientationMenu" MethodName="GetValues" ObjectType="{x:Type sys:Enum}">
|
||||
<ObjectDataProvider.MethodParameters>
|
||||
<x:Type TypeName="s:ConnectorOrientation" />
|
||||
<x:Type TypeName="dd:ConnectorOrientation" />
|
||||
</ObjectDataProvider.MethodParameters>
|
||||
</ObjectDataProvider>
|
||||
|
||||
@@ -157,11 +157,11 @@
|
||||
</Style>
|
||||
|
||||
<!-- Connector Style -->
|
||||
<Style x:Key="PointConnectorStyle" TargetType="{x:Type s:PointConnector}">
|
||||
<Style x:Key="PointConnectorStyle" TargetType="{x:Type dd:PointConnector}">
|
||||
<Setter Property="SnapsToDevicePixels" Value="true" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type s:PointConnector}">
|
||||
<ControlTemplate TargetType="{x:Type dd:PointConnector}">
|
||||
<Grid Width="{Binding ConnectorWidth}" Height="{Binding ConnectorHeight}">
|
||||
<!-- transparent extra space makes connector easier to hit -->
|
||||
<Ellipse Fill="Transparent" Margin="-2" />
|
||||
@@ -172,7 +172,7 @@
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="GifImageConnectorContainer" TargetType="{x:Type s:ConnectorContainer}">
|
||||
<Style x:Key="GifImageConnectorContainer" TargetType="{x:Type dd:ConnectorContainer}">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type ItemsControl}">
|
||||
@@ -182,7 +182,7 @@
|
||||
</Border>
|
||||
<Rectangle Fill="#7F243859" Opacity="0.5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Visibility="{Binding ShouldInsertAnchor, Converter={StaticResource BooleanToVisibilityConverter}}">
|
||||
<i:Interaction.Behaviors>
|
||||
<s:ControlMouseLeftButtonDownCommandBehavior Command="{Binding AddItemCommand}" />
|
||||
<dd:ControlMouseLeftButtonDownCommandBehavior Command="{Binding AddItemCommand}" />
|
||||
</i:Interaction.Behaviors>
|
||||
</Rectangle>
|
||||
</Grid>
|
||||
@@ -208,87 +208,87 @@
|
||||
<ControlTemplate x:Key="ConnectorDecoratorTemplate"
|
||||
TargetType="{x:Type Control}">
|
||||
<Grid Margin="-5">
|
||||
<s:Connector
|
||||
<dd:Connector
|
||||
Content="{Binding LeftConnector}"
|
||||
Cursor="Cross"
|
||||
SnapsToDevicePixels="True"
|
||||
Orientation="Left"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Left"
|
||||
Visibility="{Binding Path=ShowConnectors, Converter={x:Static s:BoolToVisibilityConverter.Instance}}" />
|
||||
<s:Connector
|
||||
Visibility="{Binding Path=ShowConnectors, Converter={x:Static dd:BoolToVisibilityConverter.Instance}}" />
|
||||
<dd:Connector
|
||||
Content="{Binding TopLeftConnector}"
|
||||
Cursor="Cross"
|
||||
SnapsToDevicePixels="True"
|
||||
Orientation="TopLeft"
|
||||
VerticalAlignment="Top"
|
||||
HorizontalAlignment="Left"
|
||||
Visibility="{Binding Path=ShowConnectors, Converter={x:Static s:BoolToVisibilityConverter.Instance}}" />
|
||||
<s:Connector
|
||||
Visibility="{Binding Path=ShowConnectors, Converter={x:Static dd:BoolToVisibilityConverter.Instance}}" />
|
||||
<dd:Connector
|
||||
Content="{Binding TopConnector}"
|
||||
Cursor="Cross"
|
||||
SnapsToDevicePixels="True"
|
||||
Orientation="Top"
|
||||
VerticalAlignment="Top"
|
||||
HorizontalAlignment="Center"
|
||||
Visibility="{Binding Path=ShowConnectors, Converter={x:Static s:BoolToVisibilityConverter.Instance}}" />
|
||||
<s:Connector
|
||||
Visibility="{Binding Path=ShowConnectors, Converter={x:Static dd:BoolToVisibilityConverter.Instance}}" />
|
||||
<dd:Connector
|
||||
Content="{Binding TopRightConnector}"
|
||||
Cursor="Cross"
|
||||
SnapsToDevicePixels="True"
|
||||
Orientation="TopRight"
|
||||
VerticalAlignment="Top"
|
||||
HorizontalAlignment="Right"
|
||||
Visibility="{Binding Path=ShowConnectors, Converter={x:Static s:BoolToVisibilityConverter.Instance}}" />
|
||||
<s:Connector
|
||||
Visibility="{Binding Path=ShowConnectors, Converter={x:Static dd:BoolToVisibilityConverter.Instance}}" />
|
||||
<dd:Connector
|
||||
Content="{Binding RightConnector}"
|
||||
Cursor="Cross"
|
||||
SnapsToDevicePixels="True"
|
||||
Orientation="Right"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Right"
|
||||
Visibility="{Binding Path=ShowConnectors, Converter={x:Static s:BoolToVisibilityConverter.Instance}}" />
|
||||
<s:Connector
|
||||
Visibility="{Binding Path=ShowConnectors, Converter={x:Static dd:BoolToVisibilityConverter.Instance}}" />
|
||||
<dd:Connector
|
||||
Content="{Binding BottomRightConnector}"
|
||||
Cursor="Cross"
|
||||
SnapsToDevicePixels="True"
|
||||
Orientation="BottomRight"
|
||||
VerticalAlignment="Bottom"
|
||||
HorizontalAlignment="Right"
|
||||
Visibility="{Binding Path=ShowConnectors, Converter={x:Static s:BoolToVisibilityConverter.Instance}}" />
|
||||
<s:Connector
|
||||
Visibility="{Binding Path=ShowConnectors, Converter={x:Static dd:BoolToVisibilityConverter.Instance}}" />
|
||||
<dd:Connector
|
||||
Content="{Binding BottomConnector}"
|
||||
Cursor="Cross"
|
||||
SnapsToDevicePixels="True"
|
||||
Orientation="Bottom"
|
||||
VerticalAlignment="Bottom"
|
||||
HorizontalAlignment="Center"
|
||||
Visibility="{Binding Path=ShowConnectors, Converter={x:Static s:BoolToVisibilityConverter.Instance}}" />
|
||||
<s:Connector
|
||||
Visibility="{Binding Path=ShowConnectors, Converter={x:Static dd:BoolToVisibilityConverter.Instance}}" />
|
||||
<dd:Connector
|
||||
Content="{Binding BottomLeftConnector}"
|
||||
Cursor="Cross"
|
||||
SnapsToDevicePixels="True"
|
||||
Orientation="BottomLeft"
|
||||
VerticalAlignment="Bottom"
|
||||
HorizontalAlignment="Left"
|
||||
Visibility="{Binding Path=ShowConnectors, Converter={x:Static s:BoolToVisibilityConverter.Instance}}" />
|
||||
Visibility="{Binding Path=ShowConnectors, Converter={x:Static dd:BoolToVisibilityConverter.Instance}}" />
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
|
||||
<ControlTemplate x:Key="InnerConnectorDecoratorTemplate"
|
||||
TargetType="{x:Type Control}">
|
||||
<s:ConnectorContainer x:Name="PART_ConnectorContainer" Style="{StaticResource ItemsControlStyle}" ItemsSource="{Binding Connectors}" Visibility="{Binding Path=ShowConnectors, Converter={x:Static s:BoolToVisibilityConverter.Instance}}">
|
||||
<s:ConnectorContainer.ItemTemplate>
|
||||
<dd:ConnectorContainer x:Name="PART_ConnectorContainer" Style="{StaticResource ItemsControlStyle}" ItemsSource="{Binding Connectors}" Visibility="{Binding Path=ShowConnectors, Converter={x:Static dd:BoolToVisibilityConverter.Instance}}">
|
||||
<dd:ConnectorContainer.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Grid>
|
||||
<s:Connector
|
||||
<dd:Connector
|
||||
Content="{Binding .}"
|
||||
Cursor="Cross"
|
||||
SnapsToDevicePixels="True"/>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</s:ConnectorContainer.ItemTemplate>
|
||||
</s:ConnectorContainer>
|
||||
</dd:ConnectorContainer.ItemTemplate>
|
||||
</dd:ConnectorContainer>
|
||||
</ControlTemplate>
|
||||
|
||||
<!--基础类型-->
|
||||
@@ -300,9 +300,9 @@
|
||||
Value="{Binding Top}" />
|
||||
<Setter Property="Canvas.ZIndex"
|
||||
Value="{Binding ZIndex}" />
|
||||
<Setter Property="s:SelectionProps.EnabledForSelection"
|
||||
<Setter Property="dd:SelectionProps.EnabledForSelection"
|
||||
Value="{Binding EnabledForSelection}" />
|
||||
<Setter Property="s:ItemConnectProps.EnabledForConnection"
|
||||
<Setter Property="dd:ItemConnectProps.EnabledForConnection"
|
||||
Value="{Binding EnabledForConnection}" />
|
||||
<Setter Property="Visibility"
|
||||
Value="{Binding Visible,Converter={StaticResource BooleanToVisibilityConverter}}"/>
|
||||
@@ -368,7 +368,7 @@
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate>
|
||||
<s:TextControl x:Name="PART_Text" />
|
||||
<dd:TextControl x:Name="PART_Text" />
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
@@ -377,7 +377,7 @@
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate>
|
||||
<s:TextControl x:Name="PART_Text" />
|
||||
<dd:TextControl x:Name="PART_Text" />
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
@@ -459,7 +459,7 @@
|
||||
Value="{Binding Area.Left}" />
|
||||
<Setter Property="Canvas.ZIndex"
|
||||
Value="{Binding ZIndex}" />
|
||||
<Setter Property="s:SelectionProps.EnabledForSelection"
|
||||
<Setter Property="dd:SelectionProps.EnabledForSelection"
|
||||
Value="{Binding EnabledForSelection}" />
|
||||
<Setter Property="Visibility"
|
||||
Value="{Binding Visible,Converter={StaticResource BooleanToVisibilityConverter}}"/>
|
||||
@@ -475,11 +475,11 @@
|
||||
<ContextMenu>
|
||||
<MenuItem Header="删除" Command="{Binding DeleteConnectionCommand}" CommandParameter="{Binding}"/>
|
||||
<MenuItem Header="添加文本" Command="{Binding AddLabelCommand}" CommandParameter="{Binding}"/>
|
||||
<MenuItem Header="插入点(按住ctrl可一直插入)" IsCheckable="True" IsChecked="{Binding ShouldInsertAnchor}" IsEnabled="{Binding IsReadOnly,Converter={s:InvertBoolConverter}}" />
|
||||
<MenuItem Header="插入点(按住ctrl可一直插入)" IsCheckable="True" IsChecked="{Binding ShouldInsertAnchor}" IsEnabled="{Binding IsReadOnly,Converter={dd:InvertBoolConverter}}" />
|
||||
</ContextMenu>
|
||||
</Grid.ContextMenu>
|
||||
|
||||
<s:LineControl x:Name="line"/>
|
||||
<dd:LineControl x:Name="line"/>
|
||||
|
||||
<!-- PART_DragThumb -->
|
||||
<c:DragThumb x:Name="PART_DragThumb" Margin="8"
|
||||
@@ -489,8 +489,8 @@
|
||||
</c:DragThumb.InputBindings>
|
||||
</c:DragThumb>
|
||||
|
||||
<s:PointContainer x:Name="PART_VerticesContainer" Style="{StaticResource ItemsControlStyle}" ItemsSource="{Binding Vertices}" Visibility="Collapsed">
|
||||
<s:PointContainer.ItemTemplate>
|
||||
<dd:PointContainer x:Name="PART_VerticesContainer" Style="{StaticResource ItemsControlStyle}" ItemsSource="{Binding Vertices}" Visibility="Collapsed">
|
||||
<dd:PointContainer.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Grid>
|
||||
<Grid.ContextMenu>
|
||||
@@ -498,23 +498,23 @@
|
||||
<MenuItem Header="删除" Command="{Binding DeleteVertexCommand}" CommandParameter="{Binding}"/>
|
||||
</ContextMenu>
|
||||
</Grid.ContextMenu>
|
||||
<s:PointConnector Style="{StaticResource PointConnectorStyle}"/>
|
||||
<dd:PointConnector Style="{StaticResource PointConnectorStyle}"/>
|
||||
<c:PointDragThumb Cursor="SizeAll" Opacity="0"/>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</s:PointContainer.ItemTemplate>
|
||||
<s:PointContainer.Resources>
|
||||
</dd:PointContainer.ItemTemplate>
|
||||
<dd:PointContainer.Resources>
|
||||
<Style TargetType="{x:Type ContentPresenter}">
|
||||
<Setter Property="Canvas.Left" Value="{Binding Left}" />
|
||||
<Setter Property="Canvas.Top" Value="{Binding Top}" />
|
||||
</Style>
|
||||
</s:PointContainer.Resources>
|
||||
</s:PointContainer>
|
||||
</dd:PointContainer.Resources>
|
||||
</dd:PointContainer>
|
||||
|
||||
<s:PointContainer x:Name="PART_LabelsContainer" Style="{StaticResource ItemsControlStyle}" ItemsSource="{Binding Labels}" >
|
||||
<s:PointContainer.ItemTemplate>
|
||||
<dd:PointContainer x:Name="PART_LabelsContainer" Style="{StaticResource ItemsControlStyle}" ItemsSource="{Binding Labels}" >
|
||||
<dd:PointContainer.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Grid s:SelectionProps.EnabledForSelection="True" Background="{Binding ColorViewModel.FillColor,Converter={StaticResource ColorBrushConverter}}">
|
||||
<Grid dd:SelectionProps.EnabledForSelection="True" Background="{Binding ColorViewModel.FillColor,Converter={StaticResource ColorBrushConverter}}">
|
||||
<Grid.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem Header="删除" Command="{Binding DeleteLabelCommand}" CommandParameter="{Binding}"/>
|
||||
@@ -525,21 +525,21 @@
|
||||
<MouseBinding MouseAction="LeftDoubleClick" Command="{Binding EditCommand}" CommandParameter="{Binding }" />
|
||||
</c:PointDragThumb.InputBindings>
|
||||
</c:PointDragThumb>
|
||||
<s:TextControl Margin="5" />
|
||||
<dd:TextControl Margin="5" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</s:PointContainer.ItemTemplate>
|
||||
<s:PointContainer.Resources>
|
||||
</dd:PointContainer.ItemTemplate>
|
||||
<dd:PointContainer.Resources>
|
||||
<Style TargetType="{x:Type ContentPresenter}">
|
||||
<Setter Property="Canvas.Left" Value="{Binding Left}" />
|
||||
<Setter Property="Canvas.Top" Value="{Binding Top}" />
|
||||
</Style>
|
||||
</s:PointContainer.Resources>
|
||||
</s:PointContainer>
|
||||
</dd:PointContainer.Resources>
|
||||
</dd:PointContainer>
|
||||
|
||||
<Rectangle Fill="#7F243859" Opacity="0.5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Visibility="{Binding ShouldInsertAnchor, Converter={StaticResource BooleanToVisibilityConverter}}">
|
||||
<i:Interaction.Behaviors>
|
||||
<s:ControlMouseLeftButtonDownCommandBehavior Command="{Binding AddVertexCommand}" />
|
||||
<dd:ControlMouseLeftButtonDownCommandBehavior Command="{Binding AddVertexCommand}" />
|
||||
</i:Interaction.Behaviors>
|
||||
</Rectangle>
|
||||
</Grid>
|
||||
@@ -572,9 +572,9 @@
|
||||
Value="{Binding Left}" />
|
||||
<Setter Property="Canvas.ZIndex"
|
||||
Value="{Binding ZIndex}" />
|
||||
<Setter Property="s:SelectionProps.EnabledForSelection"
|
||||
<Setter Property="dd:SelectionProps.EnabledForSelection"
|
||||
Value="{Binding EnabledForSelection}" />
|
||||
<Setter Property="s:ItemConnectProps.EnabledForConnection"
|
||||
<Setter Property="dd:ItemConnectProps.EnabledForConnection"
|
||||
Value="{Binding EnabledForConnection}" />
|
||||
<Setter Property="Visibility"
|
||||
Value="{Binding Visible,Converter={StaticResource BooleanToVisibilityConverter}}"/>
|
||||
@@ -608,13 +608,13 @@
|
||||
VerticalAlignment="Stretch"
|
||||
Content="{TemplateBinding Content}" />
|
||||
<!-- PART_ConnectorDecorator -->
|
||||
<s:ConnectorContainer x:Name="PART_ConnectorContainer" Visibility="Hidden" Style="{StaticResource GifImageConnectorContainer}" ItemsSource="{Binding Connectors}">
|
||||
<s:ConnectorContainer.ItemTemplate>
|
||||
<dd:ConnectorContainer x:Name="PART_ConnectorContainer" Visibility="Hidden" Style="{StaticResource GifImageConnectorContainer}" ItemsSource="{Binding Connectors}">
|
||||
<dd:ConnectorContainer.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<s:Connector Content="{Binding .}" Cursor="Cross" SnapsToDevicePixels="True"/>
|
||||
<dd:Connector Content="{Binding .}" Cursor="Cross" SnapsToDevicePixels="True"/>
|
||||
</DataTemplate>
|
||||
</s:ConnectorContainer.ItemTemplate>
|
||||
</s:ConnectorContainer>
|
||||
</dd:ConnectorContainer.ItemTemplate>
|
||||
</dd:ConnectorContainer>
|
||||
<Grid.RenderTransform>
|
||||
<TransformGroup>
|
||||
<RotateTransform Angle="{Binding Angle}" />
|
||||
@@ -652,9 +652,9 @@
|
||||
Value="{Binding Left}" />
|
||||
<Setter Property="Canvas.ZIndex"
|
||||
Value="{Binding ZIndex}" />
|
||||
<Setter Property="s:SelectionProps.EnabledForSelection"
|
||||
<Setter Property="dd:SelectionProps.EnabledForSelection"
|
||||
Value="{Binding EnabledForSelection}" />
|
||||
<Setter Property="s:ItemConnectProps.EnabledForConnection"
|
||||
<Setter Property="dd:ItemConnectProps.EnabledForConnection"
|
||||
Value="{Binding EnabledForConnection}" />
|
||||
<Setter Property="Visibility"
|
||||
Value="{Binding Visible,Converter={StaticResource BooleanToVisibilityConverter}}"/>
|
||||
@@ -685,15 +685,15 @@
|
||||
</Grid.ContextMenu>
|
||||
|
||||
<!--PART_ConnectorDecorator-->
|
||||
<s:ConnectorContainer x:Name="PART_ConnectorContainer" Style="{StaticResource ItemsControlStyle}" ItemsSource="{Binding Connectors}" Margin="0,0,0,0">
|
||||
<s:ConnectorContainer.ItemTemplate>
|
||||
<dd:ConnectorContainer x:Name="PART_ConnectorContainer" Style="{StaticResource ItemsControlStyle}" ItemsSource="{Binding Connectors}" Margin="0,0,0,0">
|
||||
<dd:ConnectorContainer.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Grid>
|
||||
<s:Connector Content="{Binding .}" Cursor="Cross" SnapsToDevicePixels="True"/>
|
||||
<dd:Connector Content="{Binding .}" Cursor="Cross" SnapsToDevicePixels="True"/>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</s:ConnectorContainer.ItemTemplate>
|
||||
</s:ConnectorContainer>
|
||||
</dd:ConnectorContainer.ItemTemplate>
|
||||
</dd:ConnectorContainer>
|
||||
<!-- PART_DragThumb -->
|
||||
<c:DragThumb x:Name="PART_DragThumb"
|
||||
Cursor="SizeAll" >
|
||||
@@ -733,7 +733,7 @@
|
||||
Value="{Binding Left}" />
|
||||
<Setter Property="Canvas.ZIndex"
|
||||
Value="{Binding ZIndex}" />
|
||||
<Setter Property="s:SelectionProps.EnabledForSelection"
|
||||
<Setter Property="dd:SelectionProps.EnabledForSelection"
|
||||
Value="{Binding EnabledForSelection}" />
|
||||
<Setter Property="Visibility"
|
||||
Value="{Binding Visible,Converter={StaticResource BooleanToVisibilityConverter}}"/>
|
||||
@@ -746,11 +746,11 @@
|
||||
<Setter Property="ContentTemplate">
|
||||
<Setter.Value>
|
||||
<DataTemplate>
|
||||
<Grid x:Name="selectedGrid" Visibility="{Binding Path=ShowConnectors, Converter={x:Static s:BoolToVisibilityConverter.Instance}}">
|
||||
<Grid x:Name="selectedGrid" Visibility="{Binding Path=ShowConnectors, Converter={x:Static dd:BoolToVisibilityConverter.Instance}}">
|
||||
<!-- PART_ConnectorDecorator -->
|
||||
<Grid Margin="-5"
|
||||
x:Name="PART_ConnectorDecorator">
|
||||
<s:PointConnector DataContext="{Binding TopConnector}" Style="{StaticResource PointConnectorStyle}"/>
|
||||
<dd:PointConnector DataContext="{Binding TopConnector}" Style="{StaticResource PointConnectorStyle}"/>
|
||||
</Grid>
|
||||
<!-- PART_DragThumb -->
|
||||
<c:DragThumb x:Name="PART_DragThumb"
|
||||
@@ -779,9 +779,9 @@
|
||||
Value="{Binding Left}" />
|
||||
<Setter Property="Canvas.ZIndex"
|
||||
Value="{Binding ZIndex}" />
|
||||
<Setter Property="s:SelectionProps.EnabledForSelection"
|
||||
<Setter Property="dd:SelectionProps.EnabledForSelection"
|
||||
Value="{Binding EnabledForSelection}" />
|
||||
<Setter Property="s:ItemConnectProps.EnabledForConnection"
|
||||
<Setter Property="dd:ItemConnectProps.EnabledForConnection"
|
||||
Value="{Binding EnabledForConnection}" />
|
||||
<Setter Property="Visibility"
|
||||
Value="{Binding Visible,Converter={StaticResource BooleanToVisibilityConverter}}"/>
|
||||
@@ -799,12 +799,12 @@
|
||||
<!-- PART_ConnectorDecorator -->
|
||||
<Grid Margin="-5"
|
||||
x:Name="PART_ConnectorDecorator">
|
||||
<s:Connector Content="{Binding Connectors[0]}"
|
||||
<dd:Connector Content="{Binding Connectors[0]}"
|
||||
Cursor="Cross"
|
||||
SnapsToDevicePixels="True"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center"
|
||||
Visibility="{Binding Path=ShowConnectors, Converter={x:Static s:BoolToVisibilityConverter.Instance}}" />
|
||||
Visibility="{Binding Path=ShowConnectors, Converter={x:Static dd:BoolToVisibilityConverter.Instance}}" />
|
||||
</Grid>
|
||||
<!-- PART_DragThumb -->
|
||||
<c:DragThumb x:Name="PART_DragThumb"
|
||||
@@ -835,10 +835,10 @@
|
||||
<ControlTemplate>
|
||||
<Grid>
|
||||
<ItemsControl ItemsSource="{Binding Items}"
|
||||
ItemContainerStyleSelector="{x:Static s:DesignerItemsControlItemStyleSelector.Instance}">
|
||||
ItemContainerStyleSelector="{x:Static dd:DesignerItemsControlItemStyleSelector.Instance}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<s:DesignerCanvas
|
||||
<dd:DesignerCanvas
|
||||
Height="{Binding PageSize.Height}"
|
||||
Width="{Binding PageSize.Width}"
|
||||
ShowGrid="{Binding ShowGrid}"
|
||||
@@ -847,10 +847,10 @@
|
||||
GridColor="{Binding GridColor}"
|
||||
Background="{Binding PageBackground,Converter={StaticResource ColorBrushConverter}}"
|
||||
AllowDrop="{Binding AllowDrop}">
|
||||
<s:DesignerCanvas.LayoutTransform>
|
||||
<dd:DesignerCanvas.LayoutTransform>
|
||||
<ScaleTransform ScaleX="{Binding ZoomValue}" ScaleY="{Binding ZoomValue}" />
|
||||
</s:DesignerCanvas.LayoutTransform>
|
||||
</s:DesignerCanvas>
|
||||
</dd:DesignerCanvas.LayoutTransform>
|
||||
</dd:DesignerCanvas>
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
|
||||
@@ -870,10 +870,10 @@
|
||||
HorizontalScrollBarVisibility="Auto"
|
||||
VerticalScrollBarVisibility="Auto">
|
||||
<ItemsControl x:Name="diagram" ItemsSource="{Binding Items}"
|
||||
ItemContainerStyleSelector="{x:Static s:DesignerItemsControlItemStyleSelector.Instance}">
|
||||
ItemContainerStyleSelector="{x:Static dd:DesignerItemsControlItemStyleSelector.Instance}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<s:DesignerCanvas
|
||||
<dd:DesignerCanvas
|
||||
Height="{Binding PageSize.Height}"
|
||||
Width="{Binding PageSize.Width}"
|
||||
ShowGrid="{Binding ShowGrid}"
|
||||
@@ -882,16 +882,16 @@
|
||||
GridColor="{Binding GridColor}"
|
||||
Background="{Binding PageBackground,Converter={StaticResource ColorBrushConverter}}"
|
||||
AllowDrop="{Binding AllowDrop}">
|
||||
<s:DesignerCanvas.LayoutTransform>
|
||||
<dd:DesignerCanvas.LayoutTransform>
|
||||
<ScaleTransform ScaleX="{Binding ZoomValue}" ScaleY="{Binding ZoomValue}" />
|
||||
</s:DesignerCanvas.LayoutTransform>
|
||||
</s:DesignerCanvas>
|
||||
</dd:DesignerCanvas.LayoutTransform>
|
||||
</dd:DesignerCanvas>
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
|
||||
</ItemsControl>
|
||||
</ScrollViewer>
|
||||
<s:ZoomBox x:Name="zoomBox"
|
||||
<dd:ZoomBox x:Name="zoomBox"
|
||||
Width="180"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Bottom"
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:s="clr-namespace:AIStudio.Wpf.DiagramDesigner"
|
||||
xmlns:dd="clr-namespace:AIStudio.Wpf.DiagramDesigner"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<UserControl.Resources>
|
||||
<s:ColorBrushConverter x:Key="ColorBrushConverter" />
|
||||
<s:LineDashConverter x:Key="LineDashConverter"/>
|
||||
<s:ArrowPathConverter x:Key="ArrowPathConverter"/>
|
||||
<s:ArrowSizeConverter x:Key="ArrowSizeConverter"/>
|
||||
<s:MathConverter x:Key="MathAddConverter" Operation="Add" />
|
||||
<dd:ColorBrushConverter x:Key="ColorBrushConverter" />
|
||||
<dd:LineDashConverter x:Key="LineDashConverter"/>
|
||||
<dd:ArrowPathConverter x:Key="ArrowPathConverter"/>
|
||||
<dd:ArrowSizeConverter x:Key="ArrowSizeConverter"/>
|
||||
<dd:MathConverter x:Key="MathAddConverter" Operation="Add" />
|
||||
<Style x:Key="LineStyle" TargetType="Path">
|
||||
<Setter Property="Stroke" Value="{Binding ColorViewModel.LineColor,Converter={StaticResource ColorBrushConverter}}"/>
|
||||
<Style.Triggers>
|
||||
@@ -40,7 +40,7 @@
|
||||
StrokeStartLineCap="Round"
|
||||
StrokeEndLineCap="Round">
|
||||
<Path.Data>
|
||||
<MultiBinding Converter="{x:Static s:ConnectionPathConverter.Instance}">
|
||||
<MultiBinding Converter="{x:Static dd:ConnectionPathConverter.Instance}">
|
||||
<Binding Path="PathGeneratorResult"/>
|
||||
</MultiBinding>
|
||||
</Path.Data>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:s="clr-namespace:AIStudio.Wpf.DiagramDesigner"
|
||||
xmlns:dd="clr-namespace:AIStudio.Wpf.DiagramDesigner"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<UserControl.Resources>
|
||||
@@ -11,8 +11,8 @@
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="/AIStudio.Wpf.DiagramDesigner;component/Styles/TextBox.xaml" />
|
||||
<ResourceDictionary>
|
||||
<s:ColorBrushConverter x:Key="ColorBrushConverter" />
|
||||
<s:TrueToFalseConverter x:Key="TrueToFalseConverter"/>
|
||||
<dd:ColorBrushConverter x:Key="ColorBrushConverter" />
|
||||
<dd:TrueToFalseConverter x:Key="TrueToFalseConverter"/>
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
@@ -32,7 +32,7 @@
|
||||
TextBlock.LineHeight="{Binding FontViewModel.LineHeight}"
|
||||
AcceptsReturn="True"
|
||||
IsHitTestVisible="False"
|
||||
s:ControlAttachProperty.Watermark="{Binding Path=(s:ControlAttachProperty.Watermark),RelativeSource={RelativeSource AncestorType={x:Type s:TextControl}}}"
|
||||
dd:ControlAttachProperty.Watermark="{Binding Path=(dd:ControlAttachProperty.Watermark),RelativeSource={RelativeSource AncestorType={x:Type dd:TextControl}}}"
|
||||
Style="{StaticResource WaterTextBoxWithEffect}" IsReadOnly="True">
|
||||
|
||||
</TextBox>
|
||||
@@ -50,7 +50,7 @@
|
||||
VerticalContentAlignment="{Binding FontViewModel.VerticalAlignment}"
|
||||
TextBlock.LineHeight="{Binding FontViewModel.LineHeight}"
|
||||
AcceptsReturn="True"
|
||||
s:ControlAttachProperty.Watermark="{Binding Path=(s:ControlAttachProperty.Watermark),RelativeSource={RelativeSource AncestorType={x:Type s:TextControl}}}"
|
||||
dd:ControlAttachProperty.Watermark="{Binding Path=(dd:ControlAttachProperty.Watermark),RelativeSource={RelativeSource AncestorType={x:Type dd:TextControl}}}"
|
||||
Style="{StaticResource WaterTextBoxWithEffect}" Visibility="Collapsed">
|
||||
</TextBox>
|
||||
|
||||
|
||||
@@ -40,13 +40,14 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
{
|
||||
this.Loaded -= TextControl_Loaded;
|
||||
|
||||
PART_ShowText.Visibility = Visibility.Visible;
|
||||
PART_TextBlock.Visibility = Visibility.Collapsed;
|
||||
PART_ShowText.Focus();
|
||||
if (!string.IsNullOrEmpty(PART_ShowText.Text))
|
||||
{
|
||||
PART_ShowText.SelectionStart = PART_ShowText.Text.Length;
|
||||
}
|
||||
//新建后处于编辑状态,暂时关闭
|
||||
//PART_ShowText.Visibility = Visibility.Visible;
|
||||
//PART_TextBlock.Visibility = Visibility.Collapsed;
|
||||
//PART_ShowText.Focus();
|
||||
//if (!string.IsNullOrEmpty(PART_ShowText.Text))
|
||||
//{
|
||||
// PART_ShowText.SelectionStart = PART_ShowText.Text.Length;
|
||||
//}
|
||||
|
||||
if (this.DataContext is ISelectable selectable)
|
||||
{
|
||||
@@ -74,6 +75,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
{
|
||||
PART_ShowText.Visibility = Visibility.Collapsed;
|
||||
PART_TextBlock.Visibility = Visibility.Visible;
|
||||
selectable.IsEditing = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -448,14 +448,20 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
}
|
||||
break;
|
||||
case nameof(SourceConnectorInfo):
|
||||
SourceA = PointHelper.GetPointForConnector(SourceConnectorInfo);
|
||||
SourceConnectorInfo.DataItem.PropertyChanged += new WeakINPCEventHandler(ConnectorViewModel_PropertyChanged).Handler;
|
||||
if (SourceConnectorInfo != null)
|
||||
{
|
||||
SourceA = PointHelper.GetPointForConnector(SourceConnectorInfo);
|
||||
SourceConnectorInfo.DataItem.PropertyChanged += new WeakINPCEventHandler(ConnectorViewModel_PropertyChanged).Handler;
|
||||
}
|
||||
break;
|
||||
case nameof(SinkConnectorInfo):
|
||||
SourceB = SinkConnectorInfo.Position;
|
||||
if (SinkConnectorInfo is FullyCreatedConnectorInfo)
|
||||
if (SinkConnectorInfo != null)
|
||||
{
|
||||
SinkConnectorInfoFully.DataItem.PropertyChanged += new WeakINPCEventHandler(ConnectorViewModel_PropertyChanged).Handler;
|
||||
SourceB = SinkConnectorInfo.Position;
|
||||
if (IsFullConnection)
|
||||
{
|
||||
SinkConnectorInfoFully.DataItem.PropertyChanged += new WeakINPCEventHandler(ConnectorViewModel_PropertyChanged).Handler;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case nameof(IsSelected):
|
||||
|
||||
@@ -26,6 +26,14 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
}
|
||||
}
|
||||
|
||||
public SelectableDesignerItemViewModelBase SelectedItem
|
||||
{
|
||||
get
|
||||
{
|
||||
return SelectedItems.FirstOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
private SelectionService selectionService;
|
||||
public SelectionService SelectionService
|
||||
{
|
||||
@@ -646,6 +654,11 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public SimpleCommand SelectItemCommand
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public SimpleCommand CopyCommand
|
||||
{
|
||||
get; private set;
|
||||
@@ -723,6 +736,11 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public SimpleCommand EditCommand
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
private SimpleCommand _undoCommand;
|
||||
public SimpleCommand UndoCommand
|
||||
{
|
||||
@@ -742,7 +760,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
}
|
||||
#endregion
|
||||
|
||||
private DoCommandManager DoCommandManager = new DoCommandManager();
|
||||
public DoCommandManager DoCommandManager = new DoCommandManager();
|
||||
|
||||
public event DiagramEventHandler Event;
|
||||
|
||||
@@ -770,6 +788,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
DistributeHorizontalCommand = new SimpleCommand(ExecuteEnable, ExecuteDistributeHorizontalCommand);
|
||||
DistributeVerticalCommand = new SimpleCommand(ExecuteEnable, ExecuteDistributeVerticalCommand);
|
||||
SelectAllCommand = new SimpleCommand(ExecuteEnable, ExecuteSelectAllCommand);
|
||||
SelectItemCommand = new SimpleCommand(ExecuteEnable, ExecuteSelectItemCommand);
|
||||
CopyCommand = new SimpleCommand(ExecuteEnable, ExecuteCopyCommand);
|
||||
PasteCommand = new SimpleCommand(ExecuteEnable, ExecutePasteCommand);
|
||||
CutCommand = new SimpleCommand(ExecuteEnable, ExecuteCutCommand);
|
||||
@@ -787,6 +806,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
UngroupCommand = new SimpleCommand(ExecuteEnable, ExecuteUngroupCommand);
|
||||
LockCommand = new SimpleCommand(ExecuteEnable, ExecuteLockCommand);
|
||||
UnlockCommand = new SimpleCommand(ExecuteEnable, ExecuteUnlockCommand);
|
||||
EditCommand = new SimpleCommand(ExecuteEnable, ExecuteEditCommand);
|
||||
Mediator.Instance.Register(this);
|
||||
|
||||
Items.CollectionChanged += Items_CollectionChanged;
|
||||
@@ -815,7 +835,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
AllowDrop = diagramItem.AllowDrop;
|
||||
}
|
||||
|
||||
public bool ExecuteEnable(object para)
|
||||
public virtual bool ExecuteEnable(object para)
|
||||
{
|
||||
return IsReadOnly == false;
|
||||
}
|
||||
@@ -832,7 +852,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
sender.SetPropertyValue(propertyName, oldvalue);
|
||||
}
|
||||
|
||||
private bool _undoing;
|
||||
|
||||
private void UndoExecuted(object para)
|
||||
{
|
||||
Undo(para);
|
||||
@@ -845,11 +865,9 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_undoing = true;
|
||||
|
||||
DoCommandManager.UnDo();
|
||||
_undoing = false;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -865,10 +883,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_undoing = true;
|
||||
DoCommandManager.ReDo();
|
||||
_undoing = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -909,8 +924,6 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
{
|
||||
RaisePropertyChanged(sender, e.PropertyName);
|
||||
|
||||
if (_undoing == true) return;
|
||||
|
||||
//连续改变,需要特殊处理,不单独触发属性改变ReDo
|
||||
if (sender is DesignerItemViewModelBase designer)
|
||||
{
|
||||
@@ -1121,6 +1134,14 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
item.IsSelected = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void ExecuteSelectItemCommand(object parameter)
|
||||
{
|
||||
if (parameter is ISelectable selectable)
|
||||
{
|
||||
selectable.IsSelected = true;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 布局
|
||||
@@ -2259,5 +2280,19 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected virtual void ExecuteEditCommand(object parameter)
|
||||
{
|
||||
if (parameter is SelectableDesignerItemViewModelBase designerItem)
|
||||
{
|
||||
designerItem.ShowText = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SelectedItem != null)
|
||||
SelectedItem.ShowText = true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,10 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
{
|
||||
get;
|
||||
}
|
||||
SelectableDesignerItemViewModelBase SelectedItem
|
||||
{
|
||||
get;
|
||||
}
|
||||
ObservableCollection<SelectableDesignerItemViewModelBase> Items
|
||||
{
|
||||
get;
|
||||
@@ -104,6 +108,10 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
{
|
||||
get;
|
||||
}
|
||||
SimpleCommand SelectItemCommand
|
||||
{
|
||||
get;
|
||||
}
|
||||
SimpleCommand CopyCommand
|
||||
{
|
||||
get;
|
||||
|
||||
@@ -119,71 +119,7 @@ namespace AIStudio.Wpf.DiagramModels
|
||||
|
||||
private static DiagramItemViewModel ToNodelModel(this DiagramNode diagramNode, IDiagramViewModel diagram)
|
||||
{
|
||||
DiagramItemViewModel nodeModel = diagramNode.ToNodel();
|
||||
//if (diagramNode is FlowchartNode flowchartNode)
|
||||
//{
|
||||
// FlowNode flowNode = null;
|
||||
// switch (flowchartNode.Kind)
|
||||
// {
|
||||
// case NodeKinds.Start:
|
||||
// {
|
||||
// var flowchartNodelModel = new StartFlowNode();
|
||||
// flowNode = flowchartNodelModel;
|
||||
// break;
|
||||
// }
|
||||
|
||||
// case NodeKinds.End:
|
||||
// {
|
||||
// var flowchartNodelModel = new EndFlowNode();
|
||||
// flowNode = flowchartNodelModel;
|
||||
// break;
|
||||
// }
|
||||
// case NodeKinds.Decide:
|
||||
// {
|
||||
// var flowchartNodelModel = new DecideFlowNode();
|
||||
// flowNode = flowchartNodelModel;
|
||||
// break;
|
||||
// }
|
||||
// case NodeKinds.COBegin:
|
||||
// {
|
||||
// var flowchartNodelModel = new COBeginFlowNode();
|
||||
// flowNode = flowchartNodelModel;
|
||||
// break;
|
||||
// }
|
||||
// case NodeKinds.COEnd:
|
||||
// {
|
||||
// var flowchartNodelModel = new COEndFlowNode();
|
||||
// flowNode = flowchartNodelModel;
|
||||
// break;
|
||||
// }
|
||||
// case NodeKinds.Middle:
|
||||
// {
|
||||
// var flowchartNodelModel = new MiddleFlowNode();
|
||||
// flowNode = flowchartNodelModel;
|
||||
// flowchartNodelModel.UserIds = flowchartNode.UserIds?.ToList();
|
||||
// flowchartNodelModel.RoleIds = flowchartNode.RoleIds?.ToList();
|
||||
// flowchartNodelModel.ActType = flowchartNode.ActType;
|
||||
// break;
|
||||
// }
|
||||
// default:
|
||||
// {
|
||||
// var flowNodelModel = new FlowNode(NodeKinds.Normal);
|
||||
// flowNode = flowNodelModel;
|
||||
// break;
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
// nodeModel = flowNode;
|
||||
// flowNode.Name = flowchartNode.Name;
|
||||
// flowNode.Color = flowchartNode.Color;
|
||||
// flowNode.Kind = flowchartNode.Kind;
|
||||
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// nodeModel = new TextDesignerItemViewModel();
|
||||
//}
|
||||
DiagramItemViewModel nodeModel = diagramNode.ToNodel();
|
||||
|
||||
nodeModel.Id = new Guid(diagramNode.Id);
|
||||
if (!string.IsNullOrEmpty(diagramNode.ParentId))
|
||||
|
||||
171
AIStudio.Wpf.Mind/Controls/DropDownButton.xaml
Normal file
171
AIStudio.Wpf.Mind/Controls/DropDownButton.xaml
Normal file
@@ -0,0 +1,171 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="clr-namespace:AIStudio.Wpf.Mind.Controls">
|
||||
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.Mind;component/Styles/Button.xaml" />
|
||||
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.Mind;component/Styles/ContextMenu.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<Style x:Key="AIStudio.Styles.DropDownButton" TargetType="{x:Type controls:DropDownButton}">
|
||||
<Setter Property="ArrowBrush" Value="Black" />
|
||||
<Setter Property="ArrowMouseOverBrush"
|
||||
Value="{Binding Foreground, RelativeSource={RelativeSource Mode=Self},
|
||||
Converter={StaticResource BrushOpacityConverter}, ConverterParameter=0.16}" />
|
||||
<Setter Property="ArrowPressedBrush" Value="Black" />
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="BorderBrush" Value="Transparent" />
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="ButtonStyle" Value="{StaticResource FlatButtonStyle}" />
|
||||
<Setter Property="Focusable" Value="False" />
|
||||
<Setter Property="Foreground" Value="Black" />
|
||||
<Setter Property="HorizontalContentAlignment" Value="Center" />
|
||||
<Setter Property="MenuStyle" Value="{StaticResource ContextMenuStyle}" />
|
||||
<Setter Property="MinHeight" Value="26" />
|
||||
<Setter Property="Padding" Value="3" />
|
||||
<Setter Property="SnapsToDevicePixels" Value="True" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type controls:DropDownButton}">
|
||||
<Grid>
|
||||
<Border x:Name="PART_Border"
|
||||
Background="Transparent"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="3"
|
||||
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
|
||||
UseLayoutRounding="True">
|
||||
<Button x:Name="PART_Button"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
VerticalContentAlignment="Stretch"
|
||||
Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
FocusVisualStyle="{TemplateBinding FocusVisualStyle}"
|
||||
Foreground="{TemplateBinding Foreground}"
|
||||
RenderOptions.ClearTypeHint="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(RenderOptions.ClearTypeHint), Mode=OneWay}"
|
||||
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
|
||||
Style="{TemplateBinding ButtonStyle}">
|
||||
<DockPanel x:Name="PART_Content"
|
||||
Focusable="False"
|
||||
LastChildFill="True">
|
||||
<!-- Material - ChevronDown -->
|
||||
<Path x:Name="PART_Arrow"
|
||||
Width="9"
|
||||
Height="6"
|
||||
Margin="0 0 3 0"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Data="M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z"
|
||||
DockPanel.Dock="Right"
|
||||
Stretch="Fill"
|
||||
Fill="{TemplateBinding ArrowBrush}"
|
||||
Visibility="{TemplateBinding ArrowVisibility}" />
|
||||
<StackPanel x:Name="PART_ContentOrientation"
|
||||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
Focusable="False"
|
||||
Orientation="Horizontal">
|
||||
<ContentPresenter HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Content="{TemplateBinding Icon}"
|
||||
ContentTemplate="{TemplateBinding IconTemplate}"
|
||||
Focusable="False"
|
||||
RecognizesAccessKey="True"
|
||||
UseLayoutRounding="False" />
|
||||
<ContentControl x:Name="PART_ButtonContent"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
Content="{Binding Content, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
|
||||
ContentStringFormat="{TemplateBinding ContentStringFormat}"
|
||||
ContentTemplate="{TemplateBinding ContentTemplate}"
|
||||
ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"
|
||||
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
|
||||
UseLayoutRounding="False" />
|
||||
</StackPanel>
|
||||
</DockPanel>
|
||||
<Button.ContextMenu>
|
||||
<ContextMenu x:Name="PART_Menu"
|
||||
MinWidth="{TemplateBinding ActualWidth}"
|
||||
DisplayMemberPath="{TemplateBinding DisplayMemberPath}"
|
||||
GroupStyleSelector="{TemplateBinding GroupStyleSelector}"
|
||||
IsOpen="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
|
||||
ItemContainerStyle="{TemplateBinding ItemContainerStyle}"
|
||||
ItemContainerStyleSelector="{TemplateBinding ItemContainerStyleSelector}"
|
||||
ItemStringFormat="{TemplateBinding ItemStringFormat}"
|
||||
ItemTemplate="{TemplateBinding ItemTemplate}"
|
||||
ItemTemplateSelector="{TemplateBinding ItemTemplateSelector}"
|
||||
ItemsPanel="{TemplateBinding ItemsPanel}"
|
||||
ItemsSource="{TemplateBinding ItemsSource}"
|
||||
Placement="Bottom"
|
||||
StaysOpen="False"
|
||||
Style="{TemplateBinding MenuStyle}"
|
||||
UseLayoutRounding="False" />
|
||||
</Button.ContextMenu>
|
||||
</Button>
|
||||
|
||||
</Border>
|
||||
<!--<Popup x:Name="PART_Popup"
|
||||
Placement="Bottom"
|
||||
IsOpen="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
|
||||
AllowsTransparency="True"
|
||||
Margin="0,0,-4,0">
|
||||
<Border>
|
||||
<ScrollViewer x:Name="PART_ScrollViewer"
|
||||
IsTabStop="False"
|
||||
Margin="1"
|
||||
SnapsToDevicePixels="True"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
HorizontalScrollBarVisibility="Hidden">
|
||||
<ItemsPresenter KeyboardNavigation.DirectionalNavigation="Local" />
|
||||
</ScrollViewer>
|
||||
</Border>
|
||||
</Popup>-->
|
||||
</Grid>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="Content" Value="{x:Null}">
|
||||
<Setter TargetName="PART_ButtonContent" Property="Margin" Value="0" />
|
||||
</Trigger>
|
||||
<Trigger Property="Orientation" Value="Vertical">
|
||||
<Setter TargetName="PART_Arrow" Property="DockPanel.Dock" Value="Bottom" />
|
||||
<Setter TargetName="PART_Arrow" Property="Margin" Value="0 0 0 3" />
|
||||
<Setter TargetName="PART_ContentOrientation" Property="Orientation" Value="Vertical" />
|
||||
</Trigger>
|
||||
<MultiTrigger>
|
||||
<MultiTrigger.Conditions>
|
||||
<Condition Property="IsMouseOver" Value="True" />
|
||||
<Condition SourceName="PART_Button" Property="IsEnabled" Value="True" />
|
||||
</MultiTrigger.Conditions>
|
||||
<Setter TargetName="PART_Arrow" Property="Fill" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ArrowMouseOverBrush, Mode=OneWay}" />
|
||||
</MultiTrigger>
|
||||
<Trigger SourceName="PART_Button" Property="IsPressed" Value="True">
|
||||
<Setter TargetName="PART_Arrow" Property="Fill" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ArrowPressedBrush, Mode=OneWay}" />
|
||||
</Trigger>
|
||||
<Trigger SourceName="PART_Button" Property="IsEnabled" Value="False">
|
||||
<Setter Property="Opacity" Value=".55" />
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Setter Property="VerticalContentAlignment" Value="Center" />
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsFocused" Value="True">
|
||||
<Setter Property="BorderBrush" Value="LightGray" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsKeyboardFocusWithin" Value="True">
|
||||
<Setter Property="BorderBrush" Value="LightGray" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsEnabled" Value="False">
|
||||
<Setter Property="Opacity" Value=".55" />
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="{x:Type controls:DropDownButton}" BasedOn="{StaticResource AIStudio.Styles.DropDownButton}" />
|
||||
|
||||
</ResourceDictionary>
|
||||
685
AIStudio.Wpf.Mind/Controls/DropDownButton.xaml.cs
Normal file
685
AIStudio.Wpf.Mind/Controls/DropDownButton.xaml.cs
Normal file
@@ -0,0 +1,685 @@
|
||||
using System;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Security;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace AIStudio.Wpf.Mind.Controls
|
||||
{
|
||||
[ContentProperty(nameof(ItemsSource))]
|
||||
[TemplatePart(Name = "PART_Button", Type = typeof(Button))]
|
||||
[TemplatePart(Name = "PART_ButtonContent", Type = typeof(ContentControl))]
|
||||
[TemplatePart(Name = "PART_Menu", Type = typeof(ContextMenu))]
|
||||
[StyleTypedProperty(Property = nameof(ButtonStyle), StyleTargetType = typeof(Button))]
|
||||
[StyleTypedProperty(Property = nameof(MenuStyle), StyleTargetType = typeof(ContextMenu))]
|
||||
public class DropDownButton : ItemsControl, ICommandSource
|
||||
{
|
||||
public static readonly RoutedEvent ClickEvent
|
||||
= EventManager.RegisterRoutedEvent(nameof(Click),
|
||||
RoutingStrategy.Bubble,
|
||||
typeof(RoutedEventHandler),
|
||||
typeof(DropDownButton));
|
||||
|
||||
public event RoutedEventHandler Click
|
||||
{
|
||||
add => this.AddHandler(ClickEvent, value);
|
||||
remove => this.RemoveHandler(ClickEvent, value);
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="IsExpanded"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty IsExpandedProperty
|
||||
= DependencyProperty.Register(nameof(IsExpanded),
|
||||
typeof(bool),
|
||||
typeof(DropDownButton),
|
||||
new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnIsExpandedPropertyChangedCallback));
|
||||
|
||||
private static void OnIsExpandedPropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
|
||||
{
|
||||
if (dependencyObject is DropDownButton dropDownButton
|
||||
&& !(dropDownButton.contextMenu == null))
|
||||
{
|
||||
dropDownButton.SetContextMenuPlacementTarget(dropDownButton.contextMenu);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void SetContextMenuPlacementTarget(ContextMenu contextMenu)
|
||||
{
|
||||
if (this.button != null)
|
||||
{
|
||||
contextMenu.PlacementTarget = this.button;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not the "popup" menu for this control is currently open
|
||||
/// </summary>
|
||||
public bool IsExpanded
|
||||
{
|
||||
get => (bool)this.GetValue(IsExpandedProperty);
|
||||
set => this.SetValue(IsExpandedProperty, (bool)value);
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="ExtraTag"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty ExtraTagProperty
|
||||
= DependencyProperty.Register(nameof(ExtraTag),
|
||||
typeof(object),
|
||||
typeof(DropDownButton));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an extra tag.
|
||||
/// </summary>
|
||||
public object ExtraTag
|
||||
{
|
||||
get => this.GetValue(ExtraTagProperty);
|
||||
set => this.SetValue(ExtraTagProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="Orientation"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty OrientationProperty
|
||||
= DependencyProperty.Register(nameof(Orientation),
|
||||
typeof(Orientation),
|
||||
typeof(DropDownButton),
|
||||
new FrameworkPropertyMetadata(Orientation.Horizontal, FrameworkPropertyMetadataOptions.AffectsMeasure));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the orientation of children stacking.
|
||||
/// </summary>
|
||||
public Orientation Orientation
|
||||
{
|
||||
get => (Orientation)this.GetValue(OrientationProperty);
|
||||
set => this.SetValue(OrientationProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="Icon"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty IconProperty
|
||||
= DependencyProperty.Register(nameof(Icon),
|
||||
typeof(object),
|
||||
typeof(DropDownButton));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the content for the icon part.
|
||||
/// </summary>
|
||||
[Bindable(true)]
|
||||
public object Icon
|
||||
{
|
||||
get => this.GetValue(IconProperty);
|
||||
set => this.SetValue(IconProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="IconTemplate"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty IconTemplateProperty
|
||||
= DependencyProperty.Register(nameof(IconTemplate),
|
||||
typeof(DataTemplate),
|
||||
typeof(DropDownButton));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the DataTemplate for the icon part.
|
||||
/// </summary>
|
||||
[Bindable(true)]
|
||||
public DataTemplate IconTemplate
|
||||
{
|
||||
get => (DataTemplate)this.GetValue(IconTemplateProperty);
|
||||
set => this.SetValue(IconTemplateProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="Command"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty CommandProperty
|
||||
= DependencyProperty.Register(nameof(Command),
|
||||
typeof(ICommand),
|
||||
typeof(DropDownButton),
|
||||
new PropertyMetadata(null, OnCommandPropertyChangedCallback));
|
||||
|
||||
private static void OnCommandPropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
(dependencyObject as DropDownButton).OnCommandChanged((ICommand)e.OldValue, (ICommand)e.NewValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the command to invoke when the content button is pressed.
|
||||
/// </summary>
|
||||
public ICommand Command
|
||||
{
|
||||
get => (ICommand)this.GetValue(CommandProperty);
|
||||
set => this.SetValue(CommandProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="CommandTarget"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty CommandTargetProperty
|
||||
= DependencyProperty.Register(nameof(CommandTarget),
|
||||
typeof(IInputElement),
|
||||
typeof(DropDownButton),
|
||||
new PropertyMetadata(null));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the element on which to raise the specified command.
|
||||
/// </summary>
|
||||
public IInputElement CommandTarget
|
||||
{
|
||||
get => (IInputElement)this.GetValue(CommandTargetProperty);
|
||||
set => this.SetValue(CommandTargetProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="CommandParameter"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty CommandParameterProperty
|
||||
= DependencyProperty.Register(nameof(CommandParameter),
|
||||
typeof(object),
|
||||
typeof(DropDownButton),
|
||||
new PropertyMetadata(null));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the parameter to pass to the command property.
|
||||
/// </summary>
|
||||
public object CommandParameter
|
||||
{
|
||||
get => (object)this.GetValue(CommandParameterProperty);
|
||||
set => this.SetValue(CommandParameterProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="Content"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty ContentProperty
|
||||
= DependencyProperty.Register(nameof(Content),
|
||||
typeof(object),
|
||||
typeof(DropDownButton));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the content of this control.
|
||||
/// </summary>
|
||||
public object Content
|
||||
{
|
||||
get => (object)this.GetValue(ContentProperty);
|
||||
set => this.SetValue(ContentProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="ContentTemplate"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty ContentTemplateProperty
|
||||
= DependencyProperty.Register(nameof(ContentTemplate),
|
||||
typeof(DataTemplate),
|
||||
typeof(DropDownButton),
|
||||
new FrameworkPropertyMetadata(null));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the data template used to display the content of the DropDownButton.
|
||||
/// </summary>
|
||||
[Bindable(true)]
|
||||
public DataTemplate ContentTemplate
|
||||
{
|
||||
get => (DataTemplate)this.GetValue(ContentTemplateProperty);
|
||||
set => this.SetValue(ContentTemplateProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="ContentTemplateSelector"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty ContentTemplateSelectorProperty
|
||||
= DependencyProperty.Register(nameof(ContentTemplateSelector),
|
||||
typeof(DataTemplateSelector),
|
||||
typeof(DropDownButton),
|
||||
new FrameworkPropertyMetadata(null));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a template selector that enables an application writer to provide custom template-selection logic.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This property is ignored if <seealso cref="ContentTemplate"/> is set.
|
||||
/// </remarks>
|
||||
[Bindable(true)]
|
||||
public DataTemplateSelector ContentTemplateSelector
|
||||
{
|
||||
get => (DataTemplateSelector)this.GetValue(ContentTemplateSelectorProperty);
|
||||
set => this.SetValue(ContentTemplateSelectorProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="ContentStringFormat"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty ContentStringFormatProperty
|
||||
= DependencyProperty.Register(nameof(ContentStringFormat),
|
||||
typeof(string),
|
||||
typeof(DropDownButton),
|
||||
new FrameworkPropertyMetadata(null));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a composite string that specifies how to format the content property if it is displayed as a string.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This property is ignored if <seealso cref="ContentTemplate"/> is set.
|
||||
/// </remarks>
|
||||
[Bindable(true)]
|
||||
public string ContentStringFormat
|
||||
{
|
||||
get => (string)this.GetValue(ContentStringFormatProperty);
|
||||
set => this.SetValue(ContentStringFormatProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="ButtonStyle"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty ButtonStyleProperty
|
||||
= DependencyProperty.Register(nameof(ButtonStyle),
|
||||
typeof(Style),
|
||||
typeof(DropDownButton),
|
||||
new FrameworkPropertyMetadata(default(Style), FrameworkPropertyMetadataOptions.Inherits | FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the button content style.
|
||||
/// </summary>
|
||||
public Style ButtonStyle
|
||||
{
|
||||
get => (Style)this.GetValue(ButtonStyleProperty);
|
||||
set => this.SetValue(ButtonStyleProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="MenuStyle"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty MenuStyleProperty
|
||||
= DependencyProperty.Register(nameof(MenuStyle),
|
||||
typeof(Style),
|
||||
typeof(DropDownButton),
|
||||
new FrameworkPropertyMetadata(default(Style), FrameworkPropertyMetadataOptions.Inherits | FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the "popup" menu style.
|
||||
/// </summary>
|
||||
public Style MenuStyle
|
||||
{
|
||||
get => (Style)this.GetValue(MenuStyleProperty);
|
||||
set => this.SetValue(MenuStyleProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="ArrowBrush"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty ArrowBrushProperty
|
||||
= DependencyProperty.Register(nameof(ArrowBrush),
|
||||
typeof(Brush),
|
||||
typeof(DropDownButton),
|
||||
new FrameworkPropertyMetadata(default(Brush), FrameworkPropertyMetadataOptions.AffectsRender));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the foreground brush for the button arrow icon.
|
||||
/// </summary>
|
||||
public Brush ArrowBrush
|
||||
{
|
||||
get => (Brush)this.GetValue(ArrowBrushProperty);
|
||||
set => this.SetValue(ArrowBrushProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="ArrowMouseOverBrush"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty ArrowMouseOverBrushProperty
|
||||
= DependencyProperty.Register(nameof(ArrowMouseOverBrush),
|
||||
typeof(Brush),
|
||||
typeof(DropDownButton),
|
||||
new FrameworkPropertyMetadata(default(Brush), FrameworkPropertyMetadataOptions.AffectsRender));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the foreground brush of the button arrow icon if the mouse is over the drop down button.
|
||||
/// </summary>
|
||||
public Brush ArrowMouseOverBrush
|
||||
{
|
||||
get => (Brush)this.GetValue(ArrowMouseOverBrushProperty);
|
||||
set => this.SetValue(ArrowMouseOverBrushProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="ArrowPressedBrush"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty ArrowPressedBrushProperty
|
||||
= DependencyProperty.Register(nameof(ArrowPressedBrush),
|
||||
typeof(Brush),
|
||||
typeof(DropDownButton),
|
||||
new FrameworkPropertyMetadata(default(Brush), FrameworkPropertyMetadataOptions.AffectsRender));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the foreground brush of the button arrow icon if the arrow button is pressed.
|
||||
/// </summary>
|
||||
public Brush ArrowPressedBrush
|
||||
{
|
||||
get => (Brush)this.GetValue(ArrowPressedBrushProperty);
|
||||
set => this.SetValue(ArrowPressedBrushProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="ArrowVisibility"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty ArrowVisibilityProperty
|
||||
= DependencyProperty.Register(nameof(ArrowVisibility),
|
||||
typeof(Visibility),
|
||||
typeof(DropDownButton),
|
||||
new FrameworkPropertyMetadata(Visibility.Visible, FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the visibility of the button arrow icon.
|
||||
/// </summary>
|
||||
public Visibility ArrowVisibility
|
||||
{
|
||||
get => (Visibility)this.GetValue(ArrowVisibilityProperty);
|
||||
set => this.SetValue(ArrowVisibilityProperty, value);
|
||||
}
|
||||
|
||||
static DropDownButton()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(DropDownButton), new FrameworkPropertyMetadata(typeof(DropDownButton)));
|
||||
}
|
||||
|
||||
private void OnCommandChanged(ICommand oldCommand, ICommand newCommand)
|
||||
{
|
||||
if (oldCommand != null)
|
||||
{
|
||||
this.UnhookCommand(oldCommand);
|
||||
}
|
||||
|
||||
if (newCommand != null)
|
||||
{
|
||||
this.HookCommand(newCommand);
|
||||
}
|
||||
}
|
||||
|
||||
private void UnhookCommand(ICommand command)
|
||||
{
|
||||
CanExecuteChangedEventManager.RemoveHandler(command, this.OnCanExecuteChanged);
|
||||
this.UpdateCanExecute();
|
||||
}
|
||||
|
||||
private void HookCommand(ICommand command)
|
||||
{
|
||||
CanExecuteChangedEventManager.AddHandler(command, this.OnCanExecuteChanged);
|
||||
this.UpdateCanExecute();
|
||||
}
|
||||
|
||||
private void OnCanExecuteChanged(object sender, EventArgs e)
|
||||
{
|
||||
this.UpdateCanExecute();
|
||||
}
|
||||
|
||||
private void UpdateCanExecute()
|
||||
{
|
||||
this.CanExecute = this.Command == null || CommandHelpers.CanExecuteCommandSource(this);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override bool IsEnabledCore => base.IsEnabledCore && this.CanExecute;
|
||||
|
||||
private bool canExecute = true;
|
||||
|
||||
private bool CanExecute
|
||||
{
|
||||
get => this.canExecute;
|
||||
set
|
||||
{
|
||||
if (value == this.canExecute)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.canExecute = value;
|
||||
this.CoerceValue(IsEnabledProperty);
|
||||
}
|
||||
}
|
||||
|
||||
private void ButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
CommandHelpers.ExecuteCommandSource(this);
|
||||
|
||||
if (this.contextMenu?.HasItems == true)
|
||||
{
|
||||
this.SetCurrentValue(IsExpandedProperty, true);
|
||||
}
|
||||
|
||||
e.RoutedEvent = ClickEvent;
|
||||
this.RaiseEvent(e);
|
||||
}
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
|
||||
if (this.button != null)
|
||||
{
|
||||
this.button.Click -= this.ButtonClick;
|
||||
}
|
||||
|
||||
this.button = this.GetTemplateChild("PART_Button") as Button;
|
||||
if (this.button != null)
|
||||
{
|
||||
this.button.Click += this.ButtonClick;
|
||||
}
|
||||
|
||||
this.GroupStyle.CollectionChanged -= this.OnGroupStyleCollectionChanged;
|
||||
|
||||
this.contextMenu = this.GetTemplateChild("PART_Menu") as ContextMenu;
|
||||
if (this.contextMenu != null)
|
||||
{
|
||||
foreach (var groupStyle in this.GroupStyle)
|
||||
{
|
||||
this.contextMenu.GroupStyle.Add(groupStyle);
|
||||
}
|
||||
|
||||
this.GroupStyle.CollectionChanged += this.OnGroupStyleCollectionChanged;
|
||||
|
||||
if (this.Items != null && this.ItemsSource == null)
|
||||
{
|
||||
foreach (var newItem in this.Items)
|
||||
{
|
||||
this.TryRemoveVisualFromOldTree(newItem);
|
||||
this.contextMenu.Items.Add(newItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if NET5_0_OR_GREATER
|
||||
private void OnGroupStyleCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
#else
|
||||
private void OnGroupStyleCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
#endif
|
||||
{
|
||||
if (e.OldItems != null)
|
||||
{
|
||||
foreach (var groupStyle in e.OldItems.OfType<GroupStyle>())
|
||||
{
|
||||
this.contextMenu?.GroupStyle.Remove(groupStyle);
|
||||
}
|
||||
}
|
||||
|
||||
if (e.NewItems != null)
|
||||
{
|
||||
foreach (var groupStyle in e.NewItems.OfType<GroupStyle>())
|
||||
{
|
||||
this.contextMenu?.GroupStyle.Add(groupStyle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnMouseRightButtonUp(MouseButtonEventArgs e)
|
||||
{
|
||||
base.OnMouseRightButtonUp(e);
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void TryRemoveVisualFromOldTree(object item)
|
||||
{
|
||||
if (item is Visual visual)
|
||||
{
|
||||
var parent = LogicalTreeHelper.GetParent(visual) as FrameworkElement ?? VisualTreeHelper.GetParent(visual) as FrameworkElement;
|
||||
if (Equals(this, parent))
|
||||
{
|
||||
this.RemoveLogicalChild(visual);
|
||||
this.RemoveVisualChild(visual);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Invoked when the <see cref="P:System.Windows.Controls.ItemsControl.Items" /> property changes.</summary>
|
||||
/// <param name="e">Information about the change.</param>
|
||||
protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
base.OnItemsChanged(e);
|
||||
if (this.contextMenu == null || this.ItemsSource != null || this.contextMenu.ItemsSource != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (e.Action)
|
||||
{
|
||||
case NotifyCollectionChangedAction.Add:
|
||||
if (e.NewItems != null)
|
||||
{
|
||||
foreach (var newItem in e.NewItems)
|
||||
{
|
||||
this.TryRemoveVisualFromOldTree(newItem);
|
||||
this.contextMenu.Items.Add(newItem);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Remove:
|
||||
if (e.OldItems != null)
|
||||
{
|
||||
foreach (var oldItem in e.OldItems)
|
||||
{
|
||||
this.contextMenu.Items.Remove(oldItem);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Move:
|
||||
case NotifyCollectionChangedAction.Replace:
|
||||
if (e.OldItems != null)
|
||||
{
|
||||
foreach (var oldItem in e.OldItems)
|
||||
{
|
||||
this.contextMenu.Items.Remove(oldItem);
|
||||
}
|
||||
}
|
||||
|
||||
if (e.NewItems != null)
|
||||
{
|
||||
foreach (var newItem in e.NewItems)
|
||||
{
|
||||
this.TryRemoveVisualFromOldTree(newItem);
|
||||
this.contextMenu.Items.Add(newItem);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Reset:
|
||||
if (this.Items != null)
|
||||
{
|
||||
this.contextMenu.Items.Clear();
|
||||
foreach (var newItem in this.Items)
|
||||
{
|
||||
this.TryRemoveVisualFromOldTree(newItem);
|
||||
this.contextMenu.Items.Add(newItem);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
private Button button;
|
||||
private ContextMenu contextMenu;
|
||||
}
|
||||
|
||||
internal static class CommandHelpers
|
||||
{
|
||||
internal static bool CanExecuteCommandSource(ICommandSource commandSource)
|
||||
{
|
||||
var command = commandSource.Command;
|
||||
if (command == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var commandParameter = commandSource.CommandParameter ?? commandSource;
|
||||
if (command is RoutedCommand routedCommand)
|
||||
{
|
||||
var target = commandSource.CommandTarget ?? commandSource as IInputElement;
|
||||
return routedCommand.CanExecute(commandParameter, target);
|
||||
}
|
||||
|
||||
return command.CanExecute(commandParameter);
|
||||
}
|
||||
|
||||
[SecurityCritical]
|
||||
[SecuritySafeCritical]
|
||||
internal static void ExecuteCommandSource(ICommandSource commandSource)
|
||||
{
|
||||
CriticalExecuteCommandSource(commandSource);
|
||||
}
|
||||
|
||||
[SecurityCritical]
|
||||
internal static void CriticalExecuteCommandSource(ICommandSource commandSource)
|
||||
{
|
||||
var command = commandSource.Command;
|
||||
if (command == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var commandParameter = commandSource.CommandParameter ?? commandSource;
|
||||
if (command is RoutedCommand routedCommand)
|
||||
{
|
||||
var target = commandSource.CommandTarget ?? commandSource as IInputElement;
|
||||
if (routedCommand.CanExecute(commandParameter, target))
|
||||
{
|
||||
routedCommand.Execute(commandParameter, target);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (command.CanExecute(commandParameter))
|
||||
{
|
||||
command.Execute(commandParameter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static bool CanExecuteCommandSource(ICommandSource commandSource, ICommand theCommand)
|
||||
{
|
||||
var command = theCommand;
|
||||
if (command == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var commandParameter = commandSource.CommandParameter ?? commandSource;
|
||||
if (command is RoutedCommand routedCommand)
|
||||
{
|
||||
var target = commandSource.CommandTarget ?? commandSource as IInputElement;
|
||||
return routedCommand.CanExecute(commandParameter, target);
|
||||
}
|
||||
|
||||
return command.CanExecute(commandParameter);
|
||||
}
|
||||
|
||||
[SecurityCritical]
|
||||
[SecuritySafeCritical]
|
||||
internal static void ExecuteCommandSource(ICommandSource commandSource, ICommand theCommand)
|
||||
{
|
||||
CriticalExecuteCommandSource(commandSource, theCommand);
|
||||
}
|
||||
|
||||
[SecurityCritical]
|
||||
internal static void CriticalExecuteCommandSource(ICommandSource commandSource, ICommand theCommand)
|
||||
{
|
||||
var command = theCommand;
|
||||
if (command == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var commandParameter = commandSource.CommandParameter ?? commandSource;
|
||||
if (command is RoutedCommand routedCommand)
|
||||
{
|
||||
var target = commandSource.CommandTarget ?? commandSource as IInputElement;
|
||||
if (routedCommand.CanExecute(commandParameter, target))
|
||||
{
|
||||
routedCommand.Execute(commandParameter, target);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (command.CanExecute(commandParameter))
|
||||
{
|
||||
command.Execute(commandParameter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@
|
||||
<!-- ToolBox Control -->
|
||||
<ContentControl Template="{Binding ToolBox,RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"/>
|
||||
|
||||
<ScrollViewer Grid.Column="1">
|
||||
<ScrollViewer Grid.Row="1">
|
||||
<!-- Diagram Control -->
|
||||
<dd:DiagramControl x:Name="PART_DiagramControl" MinWidth="1000" MinHeight="1000" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
|
||||
</ScrollViewer>
|
||||
|
||||
@@ -10,6 +10,7 @@ using System.Windows;
|
||||
using System.Xml.Linq;
|
||||
using AIStudio.Wpf.DiagramDesigner;
|
||||
using AIStudio.Wpf.DiagramDesigner.Geometrys;
|
||||
using AIStudio.Wpf.Mind.ViewModels;
|
||||
|
||||
namespace AIStudio.Wpf.Mind.Controls
|
||||
{
|
||||
@@ -22,7 +23,7 @@ namespace AIStudio.Wpf.Mind.Controls
|
||||
public const string PART_DiagramControl = "PART_DiagramControl";
|
||||
private DiagramControl _diagramControl;
|
||||
|
||||
private IDiagramViewModel _diagramViewModel;
|
||||
private MindDiagramViewModel _diagramViewModel;
|
||||
|
||||
static MindEditor()
|
||||
{
|
||||
@@ -31,16 +32,10 @@ namespace AIStudio.Wpf.Mind.Controls
|
||||
|
||||
public MindEditor()
|
||||
{
|
||||
_diagramViewModel = new DiagramViewModel();
|
||||
_diagramViewModel.ShowGrid = true;
|
||||
_diagramViewModel.GridCellSize = new SizeBase(125 / ScreenHelper.ScreenScale, 125 / ScreenHelper.ScreenScale);
|
||||
_diagramViewModel = new MindDiagramViewModel();
|
||||
_diagramViewModel.GridMarginSize = new Size(0, 0);
|
||||
_diagramViewModel.CellHorizontalAlignment = CellHorizontalAlignment.Center;
|
||||
_diagramViewModel.CellVerticalAlignment = CellVerticalAlignment.Center;
|
||||
_diagramViewModel.PageSizeType = PageSizeType.Custom;
|
||||
_diagramViewModel.PageSize = new SizeBase(double.NaN, double.NaN);
|
||||
_diagramViewModel.ColorViewModel = new ColorViewModel() { LineWidth = 2 };
|
||||
_diagramViewModel.DrawModeViewModel = new DrawModeViewModel() { LineDrawMode = DrawMode.ConnectingLineSmooth };
|
||||
|
||||
_diagramViewModel.PropertyChanged += DiagramViewModel_PropertyChanged;
|
||||
}
|
||||
@@ -52,7 +47,7 @@ namespace AIStudio.Wpf.Mind.Controls
|
||||
_diagramControl = GetTemplateChild(PART_DiagramControl) as DiagramControl;
|
||||
_diagramControl.HorizontalAlignment = HorizontalAlignment.Stretch;
|
||||
_diagramControl.VerticalAlignment = VerticalAlignment.Stretch;
|
||||
_diagramControl.DataContext = _diagramViewModel;
|
||||
this.DataContext = _diagramViewModel;
|
||||
|
||||
GetDataFunc = GetData;
|
||||
}
|
||||
@@ -97,7 +92,11 @@ namespace AIStudio.Wpf.Mind.Controls
|
||||
{
|
||||
_diagramViewModel.IsLoading = true;
|
||||
_diagramViewModel.Items.Clear();
|
||||
//_diagramViewModel.ToObject(json);
|
||||
MindNode level1node = new MindNode(_diagramViewModel, Mind.NodeLevel.Level1, _diagramViewModel.MindType) { Text = "思维导图" };
|
||||
_diagramViewModel.DirectAddItemCommand.Execute(level1node);
|
||||
level1node.Left = 200;
|
||||
level1node.Top = 200;
|
||||
_diagramViewModel.DoCommandManager.Init();
|
||||
_diagramViewModel.IsLoading = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,10 +3,18 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:AIStudio.Wpf.Mind.Controls"
|
||||
xmlns:dd="https://gitee.com/akwkevin/aistudio.-wpf.-diagram"
|
||||
xmlns:controls="clr-namespace:AIStudio.Wpf.Mind.Controls"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800" >
|
||||
<Grid Height="60">
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.Mind;component/Styles/Button.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
<Grid Height="70">
|
||||
<TabControl>
|
||||
<TabItem Header="思路">
|
||||
<Grid>
|
||||
@@ -14,6 +22,112 @@
|
||||
<RowDefinition/>
|
||||
<RowDefinition/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Button Style="{StaticResource FlatButtonStyle}" Grid.Row="0" Grid.Column="0" Command="{Binding UndoCommand}">
|
||||
<Path Width="12" Height="12" Stretch="Uniform" Fill="Black" Data="M255.545 8c-66.269.119-126.438 26.233-170.86 68.685L48.971 40.971C33.851 25.851 8 36.559 8 57.941V192c0 13.255 10.745 24 24 24h134.059c21.382 0 32.09-25.851 16.971-40.971l-41.75-41.75c30.864-28.899 70.801-44.907 113.23-45.273 92.398-.798 170.283 73.977 169.484 169.442C423.236 348.009 349.816 424 256 424c-41.127 0-79.997-14.678-110.63-41.556-4.743-4.161-11.906-3.908-16.368.553L89.34 422.659c-4.872 4.872-4.631 12.815.482 17.433C133.798 479.813 192.074 504 256 504c136.966 0 247.999-111.033 248-247.998C504.001 119.193 392.354 7.755 255.545 8z"></Path>
|
||||
</Button>
|
||||
<Button Style="{StaticResource FlatButtonStyle}" Grid.Row="1" Grid.Column="0" Command="{Binding RedoCommand}">
|
||||
<Path Width="12" Height="12" Stretch="Uniform" Fill="Black" Data="M256.455 8c66.269.119 126.437 26.233 170.859 68.685l35.715-35.715C478.149 25.851 504 36.559 504 57.941V192c0 13.255-10.745 24-24 24H345.941c-21.382 0-32.09-25.851-16.971-40.971l41.75-41.75c-30.864-28.899-70.801-44.907-113.23-45.273-92.398-.798-170.283 73.977-169.484 169.442C88.764 348.009 162.184 424 256 424c41.127 0 79.997-14.678 110.629-41.556 4.743-4.161 11.906-3.908 16.368.553l39.662 39.662c4.872 4.872 4.631 12.815-.482 17.433C378.202 479.813 319.926 504 256 504 119.034 504 8.001 392.967 8 256.002 7.999 119.193 119.646 7.755 256.455 8z"></Path>
|
||||
</Button>
|
||||
|
||||
<Button Style="{StaticResource FlatButtonStyle}" Grid.Row="0" Grid.Column="1" Command="{Binding AddChildCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Path Width="12" Height="12" Stretch="Uniform" Fill="Black" Data="M992.9 500.1H355c-19.3 0-35 15.7-35 35V660H182V340.8h427.8c32 0 58-26 58-58V58c0-32-25.9-58-58-58H58C26 0 0 26 0 58v224.8c0 32 26 58 58 58h54V689c0 13.3 7.4 24.8 18.2 30.7 6.3 6.3 15.1 10.3 24.8 10.3h165v145.9c0 19.3 15.7 35 35 35h226c19.3 0 35-15.7 35-35s-15.7-35-35-35H390V570.1h567.9V611c0 19.3 15.7 35 35 35s35-15.7 35-35v-75.9c0-19.3-15.7-35-35-35zM70 70h527.8v200.8H70V70zM989 830h-89v-89c0-19.3-15.7-35-35-35s-35 15.7-35 35v89h-89c-19.3 0-35 15.7-35 35s15.7 35 35 35h89v89c0 19.3 15.7 35 35 35s35-15.7 35-35v-89h89c19.3 0 35-15.7 35-35s-15.7-35-35-35z"></Path>
|
||||
<TextBlock>插入下级主题</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Style="{StaticResource FlatButtonStyle}" Grid.Row="1" Grid.Column="1" Command="{Binding AddPeerCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Path Width="12" Height="12" Stretch="Uniform" Fill="Black" Data="M651.8 775.5h-20.3v-527h178V305c0 19.3 15.7 35 35 35s35-15.7 35-35v-91.5c0-19.3-15.7-35-35-35h-248c-19.3 0-35 15.7-35 35V477H340.8V236.1c0-32-26-58-58-58H58c-32 0-58 26-58 58v551.8c0 32 26 58 58 58h224.8c32 0 58-26 58-58V547h220.7v263.5c0 19.3 15.7 35 35 35h55.3c19.3 0 35-15.7 35-35s-15.7-35-35-35z m-381 0.4H70V248.1h200.8v527.8zM990 651.5h-89v-89c0-19.3-15.7-35-35-35s-35 15.7-35 35v89h-89c-19.3 0-35 15.7-35 35s15.7 35 35 35h89v89c0 19.3 15.7 35 35 35s35-15.7 35-35v-89h89c19.3 0 35-15.7 35-35s-15.7-35-35-35z"></Path>
|
||||
<TextBlock>插入同级主题</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Style="{StaticResource FlatButtonStyle}" Grid.Row="0" Grid.Column="2" Command="{Binding AddParentCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Path Width="12" Height="12" Stretch="Uniform" Fill="Black" RenderTransformOrigin="0.5,0.5" Data="M992.9 500.1H355c-19.3 0-35 15.7-35 35V660H182V340.8h427.8c32 0 58-26 58-58V58c0-32-25.9-58-58-58H58C26 0 0 26 0 58v224.8c0 32 26 58 58 58h54V689c0 13.3 7.4 24.8 18.2 30.7 6.3 6.3 15.1 10.3 24.8 10.3h165v145.9c0 19.3 15.7 35 35 35h226c19.3 0 35-15.7 35-35s-15.7-35-35-35H390V570.1h567.9V611c0 19.3 15.7 35 35 35s35-15.7 35-35v-75.9c0-19.3-15.7-35-35-35zM70 70h527.8v200.8H70V70zM989 830h-89v-89c0-19.3-15.7-35-35-35s-35 15.7-35 35v89h-89c-19.3 0-35 15.7-35 35s15.7 35 35 35h89v89c0 19.3 15.7 35 35 35s35-15.7 35-35v-89h89c19.3 0 35-15.7 35-35s-15.7-35-35-35z">
|
||||
<Path.RenderTransform>
|
||||
<ScaleTransform ScaleX="-1" ScaleY="-1"/>
|
||||
</Path.RenderTransform>
|
||||
</Path>
|
||||
<TextBlock>插入上级主题</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
|
||||
<Button Style="{StaticResource FlatButtonStyle}" Grid.Row="0" Grid.Column="3" Command="{Binding MoveForwardCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Path Width="12" Height="12" Stretch="Uniform" Fill="Black" Data="M62.5 500L312.5 500L312.5 937.5L687.5 937.5L687.5 500L937.5 500L500 62.5Z"></Path>
|
||||
<TextBlock>上移</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Style="{StaticResource FlatButtonStyle}" Grid.Row="1" Grid.Column="3" Command="{Binding MoveBackCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Path Width="12" Height="12" Stretch="Uniform" Fill="Black" Data="M687.5 62.5L312.5 62.5L312.5 500L62.5 500L500 937.5L937.4 500L687.5 500Z"></Path>
|
||||
<TextBlock>下移</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Style="{StaticResource FlatButtonStyle}" Grid.Row="0" Grid.Column="4" Command="{Binding EditCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Path Width="12" Height="12" Stretch="Uniform" Fill="Black" Data="M8,12H16V14H8V12M10,20H6V4H13V9H18V12.1L20,10.1V8L14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H10V20M8,18H12.1L13,17.1V16H8V18M20.2,13C20.3,13 20.5,13.1 20.6,13.2L21.9,14.5C22.1,14.7 22.1,15.1 21.9,15.3L20.9,16.3L18.8,14.2L19.8,13.2C19.9,13.1 20,13 20.2,13M20.2,16.9L14.1,23H12V20.9L18.1,14.8L20.2,16.9Z"></Path>
|
||||
<TextBlock>编辑</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Style="{StaticResource FlatButtonStyle}" Grid.Column="4" Command="{Binding DeleteSelfCommand}" Height="22" Grid.RowSpan="2" VerticalAlignment="Bottom">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Path Width="12" Height="12" Stretch="Uniform" Fill="Black" Data="M 25.3333,23.75L 50.6667,23.75C 51.5411,23.75 51.8541,27.3125 51.8541,27.3125L 24.1458,27.3125C 24.1458,27.3125 24.4589,23.75 25.3333,23.75 Z M 35.625,19.7917L 40.375,19.7917C 40.8122,19.7917 41.9583,20.9378 41.9583,21.375C 41.9583,21.8122 40.8122,22.9584 40.375,22.9584L 35.625,22.9584C 35.1878,22.9584 34.0416,21.8122 34.0416,21.375C 34.0416,20.9378 35.1878,19.7917 35.625,19.7917 Z M 27.7083,28.5L 48.2916,28.5C 49.1661,28.5 49.875,29.2089 49.875,30.0834L 48.2916,53.8334C 48.2916,54.7078 47.5828,55.4167 46.7083,55.4167L 29.2917,55.4167C 28.4172,55.4167 27.7083,54.7078 27.7083,53.8334L 26.125,30.0834C 26.125,29.2089 26.8339,28.5 27.7083,28.5 Z M 30.0833,31.6667L 30.4792,52.25L 33.25,52.25L 32.8542,31.6667L 30.0833,31.6667 Z M 36.4167,31.6667L 36.4167,52.25L 39.5833,52.25L 39.5833,31.6667L 36.4167,31.6667 Z M 43.1458,31.6667L 42.75,52.25L 45.5208,52.25L 45.9167,31.6667L 43.1458,31.6667 Z "></Path>
|
||||
<TextBlock>删除</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
|
||||
<controls:DropDownButton Grid.RowSpan="2" Grid.Column="5" >
|
||||
<controls:DropDownButton.Content>
|
||||
<StackPanel>
|
||||
<Path Width="18" Height="18" Stretch="Uniform" Fill="Black" Data="M 23.4963,46.1288L 25.0796,48.8712L 29.4053,50.0303L 33.519,47.6553L 34.8902,46.8636L 37.6326,45.2803L 38.4242,46.6515L 37.2652,50.9772L 30.4091,54.9356L 21.7577,52.6174L 18.591,47.1326L 20.9091,38.4811L 27.7652,34.5227L 32.0909,35.6818L 32.8826,37.053L 30.1402,38.6364L 28.769,39.428L 24.6553,41.803L 23.4963,46.1288 Z M 38.7348,28.1895L 45.5908,24.2311L 54.2423,26.5493L 57.409,32.0341L 55.0908,40.6856L 48.2348,44.6439L 43.9091,43.4848L 43.1174,42.1136L 45.8598,40.5303L 47.231,39.7386L 51.3446,37.3636L 52.5037,33.0379L 50.9204,30.2955L 46.5946,29.1364L 42.481,31.5114L 41.1098,32.3031L 38.3674,33.8864L 37.5757,32.5152L 38.7348,28.1895 Z M 33.9006,45.1496L 31.7377,44.5701L 30.5502,42.5133L 31.1298,40.3504L 42.0994,34.0171L 44.2623,34.5966L 45.4498,36.6534L 44.8702,38.8163L 33.9006,45.1496 Z "></Path>
|
||||
<TextBlock>链接</TextBlock>
|
||||
</StackPanel>
|
||||
</controls:DropDownButton.Content>
|
||||
<controls:DropDownButton.Items>
|
||||
<MenuItem Header="插入链接"></MenuItem>
|
||||
<MenuItem Header="移除已有链接"></MenuItem>
|
||||
</controls:DropDownButton.Items>
|
||||
</controls:DropDownButton>
|
||||
<controls:DropDownButton Grid.RowSpan="2" Grid.Column="6" >
|
||||
<controls:DropDownButton.Content>
|
||||
<StackPanel>
|
||||
<Path Width="18" Height="18" Stretch="Uniform" Fill="Black" Data="M250 645L350 745L625 470L800 645L950 495V950H250V645zM250 503.55V250H405L554.3000000000001 399.25L350 603.55L250 503.55zM546.45 250H950V353.5500000000001L800 503.5500000000001L546.45 250zM200 1050H1000A50 50 0 0 0 1050 1000V200A50 50 0 0 0 1000 150H200A50 50 0 0 0 150 200V1000A50 50 0 0 0 200 1050zM775 700A75 75 0 1 0 775 850A75 75 0 0 0 775 700z"></Path>
|
||||
<TextBlock>图片</TextBlock>
|
||||
</StackPanel>
|
||||
</controls:DropDownButton.Content>
|
||||
<controls:DropDownButton.Items>
|
||||
<MenuItem Header="插入图片"></MenuItem>
|
||||
<MenuItem Header="移除已有图片"></MenuItem>
|
||||
</controls:DropDownButton.Items>
|
||||
</controls:DropDownButton>
|
||||
<controls:DropDownButton Grid.RowSpan="2" Grid.Column="7" >
|
||||
<controls:DropDownButton.Content>
|
||||
<StackPanel>
|
||||
<Path Width="18" Height="18" Stretch="Uniform" Fill="Black" Data="M5,3C3.89,3 3,3.89 3,5V19C3,20.11 3.89,21 5,21H19C20.11,21 21,20.11 21,19V5C21,3.89 20.11,3 19,3H5M5,5H19V19H5V5M7,7V9H17V7H7M7,11V13H17V11H7M7,15V17H14V15H7Z"></Path>
|
||||
<TextBlock>备注</TextBlock>
|
||||
</StackPanel>
|
||||
</controls:DropDownButton.Content>
|
||||
<controls:DropDownButton.Items>
|
||||
<MenuItem Header="插入备注"></MenuItem>
|
||||
<MenuItem Header="移除已有备注"></MenuItem>
|
||||
</controls:DropDownButton.Items>
|
||||
</controls:DropDownButton>
|
||||
</Grid>
|
||||
</TabItem>
|
||||
<TabItem Header="外观">
|
||||
@@ -22,6 +136,36 @@
|
||||
<RowDefinition/>
|
||||
<RowDefinition/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<controls:DropDownButton Grid.RowSpan="2" Grid.Column="7">
|
||||
<controls:DropDownButton.Content>
|
||||
<StackPanel>
|
||||
<Path Width="18" Height="18" Stretch="Uniform" Fill="Black" Data="M5,3C3.89,3 3,3.89 3,5V19C3,20.11 3.89,21 5,21H19C20.11,21 21,20.11 21,19V5C21,3.89 20.11,3 19,3H5M5,5H19V19H5V5M7,7V9H17V7H7M7,11V13H17V11H7M7,15V17H14V15H7Z"></Path>
|
||||
<TextBlock>类型</TextBlock>
|
||||
</StackPanel>
|
||||
</controls:DropDownButton.Content>
|
||||
<controls:DropDownButton.Items>
|
||||
<MenuItem Header="思维导图" IsCheckable="True" IsChecked="{Binding MindType,Converter={dd:ConverterValueMapToBool Parameter='Mind'}, ConverterParameter='Mind'}" />
|
||||
<MenuItem Header="目录组织图" IsCheckable="True" IsChecked="{Binding MindType,Converter={dd:ConverterValueMapToBool Parameter='Directory'}, ConverterParameter='Directory'}" />
|
||||
<MenuItem Header="鱼骨头图" IsCheckable="True" IsChecked="{Binding MindType,Converter={dd:ConverterValueMapToBool Parameter='FishBone'}, ConverterParameter='FishBone'}" />
|
||||
<MenuItem Header="逻辑结构图" IsCheckable="True" IsChecked="{Binding MindType,Converter={dd:ConverterValueMapToBool Parameter='Logical'}, ConverterParameter='Logical'}" />
|
||||
<MenuItem Header="组织结构图" IsCheckable="True" IsChecked="{Binding MindType,Converter={dd:ConverterValueMapToBool Parameter='Organizational'}, ConverterParameter='Organizational'}" />
|
||||
<MenuItem Header="天盘图" IsCheckable="True" IsChecked="{Binding MindType,Converter={dd:ConverterValueMapToBool Parameter='Celestial'}, ConverterParameter='Celestial'}" />
|
||||
</controls:DropDownButton.Items>
|
||||
</controls:DropDownButton>
|
||||
</Grid>
|
||||
</TabItem>
|
||||
<TabItem Header="视图">
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Windows.Media;
|
||||
using AIStudio.Wpf.DiagramDesigner;
|
||||
using AIStudio.Wpf.DiagramDesigner.Algorithms;
|
||||
using AIStudio.Wpf.DiagramDesigner.Geometrys;
|
||||
using AIStudio.Wpf.DiagramDesigner.Helpers;
|
||||
using AIStudio.Wpf.Mind.ViewModels;
|
||||
|
||||
namespace AIStudio.Wpf.Mind.Helpers
|
||||
@@ -34,6 +35,7 @@ namespace AIStudio.Wpf.Mind.Helpers
|
||||
mindNode.ShapeViewModel.SinkMarker.PathStyle = ArrowPathStyle.None;
|
||||
mindNode.ShapeViewModel.SinkMarker.SizeStyle = ArrowSizeStyle.VerySmall;
|
||||
|
||||
mindNode.ConnectorOrientation = ConnectorOrientation.None;
|
||||
break;
|
||||
}
|
||||
case NodeLevel.Level2:
|
||||
@@ -109,12 +111,12 @@ namespace AIStudio.Wpf.Mind.Helpers
|
||||
if (mindNode.NodeLevel == NodeLevel.Level1)
|
||||
{
|
||||
var childrensizes = mindNode.Children.Select(p => MeasureOverride(p, mindNode.IsExpanded && isExpanded)).ToArray();
|
||||
sizewithSpacing = new SizeBase(Math.Max(sizewithSpacing.Width, childrensizes.Sum(p => p.Width)), sizewithSpacing.Height + childrensizes.Max(p => p.Height));
|
||||
sizewithSpacing = new SizeBase(Math.Max(sizewithSpacing.Width, childrensizes.SumOrDefault(p => p.Width)), sizewithSpacing.Height + childrensizes.MaxOrDefault(p => p.Height));
|
||||
}
|
||||
else
|
||||
{
|
||||
var childrensizes = mindNode.Children.Select(p => MeasureOverride(p, mindNode.IsExpanded && isExpanded)).ToArray();
|
||||
sizewithSpacing = new SizeBase(Math.Max(sizewithSpacing.Width, sizewithSpacing.Width * 0.5 + childrensizes.Max(p => p.Width)), sizewithSpacing.Height + childrensizes.Sum(p => p.Height));
|
||||
sizewithSpacing = new SizeBase(Math.Max(sizewithSpacing.Width, sizewithSpacing.Width * 0.5 + childrensizes.MaxOrDefault(p => p.Width)), sizewithSpacing.Height + childrensizes.SumOrDefault(p => p.Height));
|
||||
}
|
||||
}
|
||||
mindNode.DesiredSize = isExpanded ? sizewithSpacing : new SizeBase(0, 0);
|
||||
@@ -127,7 +129,7 @@ namespace AIStudio.Wpf.Mind.Helpers
|
||||
{
|
||||
if (mindNode.NodeLevel == NodeLevel.Level1)
|
||||
{
|
||||
double left = mindNode.MiddlePosition.X - Math.Max(mindNode.DesiredSize.Width, mindNode.Children.Sum(p => p.DesiredSize.Width)) / 2;
|
||||
double left = mindNode.MiddlePosition.X - Math.Max(mindNode.DesiredSize.Width, mindNode.Children.SumOrDefault(p => p.DesiredSize.Width)) / 2;
|
||||
double top = mindNode.MiddlePosition.Y + mindNode.ItemHeight / 2 + mindNode.Spacing.Height;
|
||||
if (mindNode.Children?.Count > 0)
|
||||
{
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Windows.Media;
|
||||
using AIStudio.Wpf.DiagramDesigner;
|
||||
using AIStudio.Wpf.DiagramDesigner.Algorithms;
|
||||
using AIStudio.Wpf.DiagramDesigner.Geometrys;
|
||||
using AIStudio.Wpf.DiagramDesigner.Helpers;
|
||||
using AIStudio.Wpf.Mind.ViewModels;
|
||||
|
||||
namespace AIStudio.Wpf.Mind.Helpers
|
||||
@@ -39,6 +40,7 @@ namespace AIStudio.Wpf.Mind.Helpers
|
||||
mindNode.ShapeViewModel.SinkMarker.PathStyle = ArrowPathStyle.None;
|
||||
mindNode.ShapeViewModel.SinkMarker.SizeStyle = ArrowSizeStyle.VerySmall;
|
||||
|
||||
mindNode.ConnectorOrientation = ConnectorOrientation.None;
|
||||
break;
|
||||
}
|
||||
case NodeLevel.Level2:
|
||||
@@ -144,18 +146,18 @@ namespace AIStudio.Wpf.Mind.Helpers
|
||||
var bottoms = mindNode.Children.Where((p, index) => index % 2 == 1).ToList();
|
||||
bottoms.ForEach(p => p.ConnectorOrientation = ConnectorOrientation.TopLeft);
|
||||
var bottomsizes = bottoms.Select(p => MeasureOverride(p, mindNode.IsExpanded && isExpanded)).ToArray();
|
||||
sizewithSpacing = new SizeBase(sizewithSpacing.Width + bottomoffset + Math.Max(topsizes.Sum(p => p.Width), bottomsizes.Sum(p => p.Width)), sizewithSpacing.Height + topsizes.Max(p => p.Height) + bottomsizes.Max(p => p.Height));
|
||||
sizewithSpacing = new SizeBase(sizewithSpacing.Width + bottomoffset + Math.Max(topsizes.SumOrDefault(p => p.Width), bottomsizes.SumOrDefault(p => p.Width)), sizewithSpacing.Height + topsizes.MaxOrDefault(p => p.Height) + bottomsizes.MaxOrDefault(p => p.Height));
|
||||
}
|
||||
else if (mindNode.NodeLevel == NodeLevel.Level2)
|
||||
{
|
||||
var childrensizes = mindNode.Children.Select(p => MeasureOverride(p, mindNode.IsExpanded && isExpanded)).ToArray();
|
||||
var lastchildsize = childrensizes.LastOrDefault();
|
||||
sizewithSpacing = new SizeBase(Math.Max(sizewithSpacing.Width, sizewithSpacing.Height + childrensizes.Sum(p => p.Height) - lastchildsize.Height / 2 + lastchildsize.Width), sizewithSpacing.Height + childrensizes.Sum(p => p.Height));
|
||||
sizewithSpacing = new SizeBase(Math.Max(sizewithSpacing.Width, sizewithSpacing.Height + childrensizes.SumOrDefault(p => p.Height) - lastchildsize.Height / 2 + lastchildsize.Width), sizewithSpacing.Height + childrensizes.SumOrDefault(p => p.Height));
|
||||
}
|
||||
else if (mindNode.NodeLevel == NodeLevel.Level3)
|
||||
{
|
||||
var childrensizes = mindNode.Children.Select(p => MeasureOverride(p, mindNode.IsExpanded && isExpanded)).ToArray();
|
||||
sizewithSpacing = new SizeBase(Math.Max(sizewithSpacing.Width, sizewithSpacing.Width * 0.5 + childrensizes.Max(p => p.Width)), sizewithSpacing.Height + childrensizes.Sum(p => p.Height));
|
||||
sizewithSpacing = new SizeBase(Math.Max(sizewithSpacing.Width, sizewithSpacing.Width * 0.5 + childrensizes.MaxOrDefault(p => p.Width)), sizewithSpacing.Height + childrensizes.SumOrDefault(p => p.Height));
|
||||
}
|
||||
}
|
||||
mindNode.DesiredSize = isExpanded ? sizewithSpacing : new SizeBase(0, 0);
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Windows.Media;
|
||||
using AIStudio.Wpf.DiagramDesigner;
|
||||
using AIStudio.Wpf.DiagramDesigner.Algorithms;
|
||||
using AIStudio.Wpf.DiagramDesigner.Geometrys;
|
||||
using AIStudio.Wpf.DiagramDesigner.Helpers;
|
||||
using AIStudio.Wpf.Mind.ViewModels;
|
||||
|
||||
namespace AIStudio.Wpf.Mind.Helpers
|
||||
@@ -35,6 +36,7 @@ namespace AIStudio.Wpf.Mind.Helpers
|
||||
mindNode.ShapeViewModel.SinkMarker.PathStyle = ArrowPathStyle.Circle;
|
||||
mindNode.ShapeViewModel.SinkMarker.SizeStyle = ArrowSizeStyle.VerySmall;
|
||||
|
||||
mindNode.ConnectorOrientation = ConnectorOrientation.None;
|
||||
break;
|
||||
}
|
||||
case NodeLevel.Level2:
|
||||
@@ -106,7 +108,7 @@ namespace AIStudio.Wpf.Mind.Helpers
|
||||
if (mindNode.Children?.Count > 0)
|
||||
{
|
||||
var childrensizes = mindNode.Children.Select(p => MeasureOverride(p, mindNode.IsExpanded && isExpanded)).ToArray();
|
||||
sizewithSpacing = new SizeBase(sizewithSpacing.Width + childrensizes.Max(p => p.Width), Math.Max(sizewithSpacing.Height, childrensizes.Sum(p => p.Height)));
|
||||
sizewithSpacing = new SizeBase(sizewithSpacing.Width + childrensizes.MaxOrDefault(p => p.Width), Math.Max(sizewithSpacing.Height, childrensizes.SumOrDefault(p => p.Height)));
|
||||
}
|
||||
mindNode.DesiredSize = isExpanded ? sizewithSpacing : new SizeBase(0, 0);
|
||||
mindNode.Visible = isExpanded;
|
||||
@@ -117,7 +119,7 @@ namespace AIStudio.Wpf.Mind.Helpers
|
||||
public void ArrangeOverride(MindNode mindNode)
|
||||
{
|
||||
double left = mindNode.MiddlePosition.X + mindNode.ItemWidth / 2 + mindNode.Spacing.Width;
|
||||
double top = mindNode.MiddlePosition.Y - Math.Min(mindNode.DesiredSize.Height, mindNode.Children.Sum(p => p.DesiredSize.Height)) / 2;
|
||||
double top = mindNode.MiddlePosition.Y - Math.Min(mindNode.DesiredSize.Height, mindNode.Children.SumOrDefault(p => p.DesiredSize.Height)) / 2;
|
||||
if (mindNode.Children?.Count > 0)
|
||||
{
|
||||
foreach (var child in mindNode.Children)
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Windows.Media;
|
||||
using AIStudio.Wpf.DiagramDesigner;
|
||||
using AIStudio.Wpf.DiagramDesigner.Algorithms;
|
||||
using AIStudio.Wpf.DiagramDesigner.Geometrys;
|
||||
using AIStudio.Wpf.DiagramDesigner.Helpers;
|
||||
using AIStudio.Wpf.Mind.ViewModels;
|
||||
|
||||
namespace AIStudio.Wpf.Mind.Helpers
|
||||
@@ -35,6 +36,7 @@ namespace AIStudio.Wpf.Mind.Helpers
|
||||
mindNode.ShapeViewModel.SinkMarker.PathStyle = ArrowPathStyle.Circle;
|
||||
mindNode.ShapeViewModel.SinkMarker.SizeStyle = ArrowSizeStyle.VerySmall;
|
||||
|
||||
mindNode.ConnectorOrientation = ConnectorOrientation.None;
|
||||
break;
|
||||
}
|
||||
case NodeLevel.Level2:
|
||||
@@ -114,12 +116,12 @@ namespace AIStudio.Wpf.Mind.Helpers
|
||||
var lefts = mindNode.Children.Where((p, index) => index % 2 == 1).ToList();
|
||||
lefts.ForEach(p => p.ConnectorOrientation = ConnectorOrientation.Right);
|
||||
var leftsizes = lefts.Select(p => MeasureOverride(p, mindNode.IsExpanded && isExpanded)).ToArray();
|
||||
sizewithSpacing = new SizeBase(sizewithSpacing.Width + rightsizes.Max(p => p.Width) + +leftsizes.Max(p => p.Width), Math.Max(sizewithSpacing.Height, Math.Max(rightsizes.Sum(p => p.Height), leftsizes.Sum(p => p.Height))));
|
||||
sizewithSpacing = new SizeBase(sizewithSpacing.Width + rightsizes.MaxOrDefault(p => p.Width) + +leftsizes.MaxOrDefault(p => p.Width), Math.Max(sizewithSpacing.Height, Math.Max(rightsizes.SumOrDefault(p => p.Height), leftsizes.SumOrDefault(p => p.Height))));
|
||||
}
|
||||
else
|
||||
{
|
||||
var childrensizes = mindNode.Children.Select(p => MeasureOverride(p, mindNode.IsExpanded && isExpanded)).ToArray();
|
||||
sizewithSpacing = new SizeBase(sizewithSpacing.Width + childrensizes.Max(p => p.Width), Math.Max(sizewithSpacing.Height, childrensizes.Sum(p => p.Height)));
|
||||
sizewithSpacing = new SizeBase(sizewithSpacing.Width + childrensizes.MaxOrDefault(p => p.Width), Math.Max(sizewithSpacing.Height, childrensizes.SumOrDefault(p => p.Height)));
|
||||
}
|
||||
}
|
||||
mindNode.DesiredSize = isExpanded ? sizewithSpacing : new SizeBase(0, 0);
|
||||
@@ -136,7 +138,7 @@ namespace AIStudio.Wpf.Mind.Helpers
|
||||
{
|
||||
var rights = mindNode.Children.Where(p => p.ConnectorOrientation == ConnectorOrientation.Left).ToList();
|
||||
double left = mindNode.MiddlePosition.X + mindNode.ItemWidth / 2 + mindNode.Spacing.Width;
|
||||
double lefttop = mindNode.MiddlePosition.Y - Math.Min(mindNode.DesiredSize.Height, rights.Sum(p => p.DesiredSize.Height)) / 2;
|
||||
double lefttop = mindNode.MiddlePosition.Y - Math.Min(mindNode.DesiredSize.Height, rights.SumOrDefault(p => p.DesiredSize.Height)) / 2;
|
||||
foreach (var child in rights)
|
||||
{
|
||||
child.Left = left + child.Spacing.Width + child.Offset.X;
|
||||
@@ -154,7 +156,7 @@ namespace AIStudio.Wpf.Mind.Helpers
|
||||
|
||||
var lefts = mindNode.Children.Where(p => p.ConnectorOrientation == ConnectorOrientation.Right).ToList();
|
||||
double right = mindNode.MiddlePosition.X - mindNode.ItemWidth / 2 - mindNode.Spacing.Width;
|
||||
double righttop = mindNode.MiddlePosition.Y - Math.Min(mindNode.DesiredSize.Height, lefts.Sum(p => p.DesiredSize.Height)) / 2;
|
||||
double righttop = mindNode.MiddlePosition.Y - Math.Min(mindNode.DesiredSize.Height, lefts.SumOrDefault(p => p.DesiredSize.Height)) / 2;
|
||||
foreach (var child in lefts)
|
||||
{
|
||||
child.Left = right - child.Spacing.Width - child.ItemWidth + child.Offset.X;
|
||||
@@ -176,7 +178,7 @@ namespace AIStudio.Wpf.Mind.Helpers
|
||||
if (mindNode.GetLevel2Node().ConnectorOrientation == ConnectorOrientation.Left)
|
||||
{
|
||||
double left = mindNode.MiddlePosition.X + mindNode.ItemWidth / 2 + mindNode.Spacing.Width;
|
||||
double top = mindNode.MiddlePosition.Y - Math.Min(mindNode.DesiredSize.Height, mindNode.Children.Sum(p => p.DesiredSize.Height)) / 2;
|
||||
double top = mindNode.MiddlePosition.Y - Math.Min(mindNode.DesiredSize.Height, mindNode.Children.SumOrDefault(p => p.DesiredSize.Height)) / 2;
|
||||
if (mindNode.Children?.Count > 0)
|
||||
{
|
||||
foreach (var child in mindNode.Children)
|
||||
@@ -198,7 +200,7 @@ namespace AIStudio.Wpf.Mind.Helpers
|
||||
else
|
||||
{
|
||||
double right = mindNode.MiddlePosition.X - mindNode.ItemWidth / 2 - mindNode.Spacing.Width;
|
||||
double top = mindNode.MiddlePosition.Y - Math.Min(mindNode.DesiredSize.Height, mindNode.Children.Sum(p => p.DesiredSize.Height)) / 2;
|
||||
double top = mindNode.MiddlePosition.Y - Math.Min(mindNode.DesiredSize.Height, mindNode.Children.SumOrDefault(p => p.DesiredSize.Height)) / 2;
|
||||
if (mindNode.Children?.Count > 0)
|
||||
{
|
||||
foreach (var child in mindNode.Children)
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Windows.Media;
|
||||
using AIStudio.Wpf.DiagramDesigner;
|
||||
using AIStudio.Wpf.DiagramDesigner.Algorithms;
|
||||
using AIStudio.Wpf.DiagramDesigner.Geometrys;
|
||||
using AIStudio.Wpf.DiagramDesigner.Helpers;
|
||||
using AIStudio.Wpf.Mind.ViewModels;
|
||||
|
||||
namespace AIStudio.Wpf.Mind.Helpers
|
||||
@@ -33,6 +34,8 @@ namespace AIStudio.Wpf.Mind.Helpers
|
||||
mindNode.FontViewModel.FontSize = 15;
|
||||
mindNode.ShapeViewModel.SinkMarker.PathStyle = ArrowPathStyle.None;
|
||||
mindNode.ShapeViewModel.SinkMarker.SizeStyle = ArrowSizeStyle.VerySmall;
|
||||
|
||||
mindNode.ConnectorOrientation = ConnectorOrientation.None;
|
||||
break;
|
||||
}
|
||||
case NodeLevel.Level2:
|
||||
@@ -107,7 +110,7 @@ namespace AIStudio.Wpf.Mind.Helpers
|
||||
if (mindNode.Children?.Count > 0)
|
||||
{
|
||||
var childrensizes = mindNode.Children.Select(p => MeasureOverride(p, mindNode.IsExpanded && isExpanded)).ToArray();
|
||||
sizewithSpacing = new SizeBase(Math.Max(sizewithSpacing.Width, childrensizes.Sum(p => p.Width)), sizewithSpacing.Height + childrensizes.Max(p => p.Height));
|
||||
sizewithSpacing = new SizeBase(Math.Max(sizewithSpacing.Width, childrensizes.SumOrDefault(p => p.Width)), sizewithSpacing.Height + childrensizes.MaxOrDefault(p => p.Height));
|
||||
}
|
||||
mindNode.DesiredSize = isExpanded ? sizewithSpacing : new SizeBase(0, 0);
|
||||
mindNode.Visible = isExpanded;
|
||||
@@ -117,7 +120,7 @@ namespace AIStudio.Wpf.Mind.Helpers
|
||||
|
||||
public void ArrangeOverride(MindNode mindNode)
|
||||
{
|
||||
double left = mindNode.MiddlePosition.X - Math.Max(mindNode.DesiredSize.Width, mindNode.Children.Sum(p => p.DesiredSize.Width)) / 2;
|
||||
double left = mindNode.MiddlePosition.X - Math.Max(mindNode.DesiredSize.Width, mindNode.Children.SumOrDefault(p => p.DesiredSize.Width)) / 2;
|
||||
double top = mindNode.MiddlePosition.Y + mindNode.ItemHeight / 2 + mindNode.Spacing.Height;
|
||||
if (mindNode.Children?.Count > 0)
|
||||
{
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:s="clr-namespace:AIStudio.Wpf.DiagramDesigner">
|
||||
xmlns:dd="https://gitee.com/akwkevin/aistudio.-wpf.-diagram">
|
||||
|
||||
<s:BrushOpacityConverter x:Key="BrushOpacityConverter"/>
|
||||
|
||||
<Style x:Key="AIStudio.Styles.Button.Flat" TargetType="{x:Type ButtonBase}">
|
||||
<dd:BrushOpacityConverter x:Key="BrushOpacityConverter"/>
|
||||
|
||||
<Style x:Key="FlatButtonStyle" TargetType="{x:Type ButtonBase}">
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="Foreground" Value="Black" />
|
||||
<Setter Property="BorderBrush" Value="Transparent"/>
|
||||
61
AIStudio.Wpf.Mind/Styles/ContextMenu.xaml
Normal file
61
AIStudio.Wpf.Mind/Styles/ContextMenu.xaml
Normal file
@@ -0,0 +1,61 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:options="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options">
|
||||
|
||||
<DropShadowEffect x:Key="DropShadowEffectStyle"
|
||||
x:Shared="False"
|
||||
BlurRadius="4"
|
||||
Direction="315"
|
||||
Opacity="0.3"
|
||||
ShadowDepth="2"
|
||||
Color="Black"
|
||||
options:Freeze="True" />
|
||||
|
||||
<Style x:Key="ContextMenuStyle" TargetType="{x:Type ContextMenu}">
|
||||
<Setter Property="Background" Value="White" />
|
||||
<Setter Property="Block.TextAlignment" Value="Left" />
|
||||
<Setter Property="BorderBrush" Value="LightGray" />
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="Foreground" Value="Black" />
|
||||
<Setter Property="Grid.IsSharedSizeScope" Value="True" />
|
||||
<Setter Property="HasDropShadow" Value="True" />
|
||||
<Setter Property="HorizontalContentAlignment" Value="Left" />
|
||||
<Setter Property="OverridesDefaultStyle" Value="True" />
|
||||
<Setter Property="RenderOptions.ClearTypeHint" Value="Enabled" />
|
||||
<Setter Property="SnapsToDevicePixels" Value="True" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type ContextMenu}">
|
||||
<Border x:Name="Border"
|
||||
Width="{TemplateBinding Width}"
|
||||
Height="{TemplateBinding Height}"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="3"
|
||||
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
|
||||
|
||||
<ScrollViewer x:Name="SubMenuScrollViewer"
|
||||
CanContentScroll="True">
|
||||
<ItemsPresenter x:Name="ItemsPresenter"
|
||||
Margin="0"
|
||||
Grid.IsSharedSizeScope="True"
|
||||
KeyboardNavigation.DirectionalNavigation="Cycle"
|
||||
KeyboardNavigation.TabNavigation="Cycle"
|
||||
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
|
||||
</ScrollViewer>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="HasDropShadow" Value="True">
|
||||
<Setter TargetName="Border" Property="Effect" Value="{StaticResource DropShadowEffectStyle}" />
|
||||
<Setter TargetName="Border" Property="Margin" Value="0 0 6 6" />
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Setter Property="TextOptions.TextFormattingMode" Value="Ideal" />
|
||||
<Setter Property="VerticalContentAlignment" Value="Center" />
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
@@ -2,6 +2,7 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.Mind;component/Controls/DropDownButton.xaml"/>
|
||||
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.Mind;component/Controls/MindEditor.xaml"/>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
|
||||
@@ -37,6 +37,48 @@
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<ControlTemplate x:Key="MindNodeLevelStyle" TargetType="{x:Type ContentControl}">
|
||||
<Grid>
|
||||
<Grid.ContextMenu>
|
||||
<ContextMenu ItemsSource="{Binding MenuOptions}">
|
||||
<ContextMenu.ItemContainerStyle>
|
||||
<Style TargetType="MenuItem">
|
||||
<Setter Property="MenuItem.Header" Value="{Binding Text}" />
|
||||
<Setter Property="MenuItem.ItemsSource" Value="{Binding Children}" />
|
||||
<Setter Property="MenuItem.Command" Value="{Binding Command}" />
|
||||
<Setter Property="MenuItem.Icon" Value="{Binding Icon}" />
|
||||
<Setter Property="CommandParameter" Value="{Binding CommandParameter}" />
|
||||
<Setter Property="MenuItem.IsCheckable" Value="{Binding IsCheckable}" />
|
||||
<Setter Property="MenuItem.IsChecked" Value="{Binding IsChecked}" />
|
||||
</Style>
|
||||
</ContextMenu.ItemContainerStyle>
|
||||
</ContextMenu>
|
||||
</Grid.ContextMenu>
|
||||
<Grid IsHitTestVisible="False">
|
||||
<Border BorderThickness="{Binding BorderThickness}"
|
||||
BorderBrush="{Binding ColorViewModel.LineColor,Converter={StaticResource ColorBrushConverter}}"
|
||||
Background="{Binding ColorViewModel.FillColor,Converter={StaticResource ColorBrushConverter}}"
|
||||
CornerRadius="{Binding CornerRadius}">
|
||||
</Border>
|
||||
</Grid>
|
||||
<ToggleButton x:Name="toggle" IsChecked="{Binding IsExpanded}" Style="{StaticResource ExpandCollapseToggleStyle}" HorizontalAlignment="Left" Margin="-15,0,0,0" Visibility="{Binding Children.Count,Converter={StaticResource IntToVisibilityConverter}}"/>
|
||||
</Grid>
|
||||
<ControlTemplate.Triggers>
|
||||
<DataTrigger Binding="{Binding ConnectorOrientation}" Value="None">
|
||||
<Setter TargetName="toggle" Property="Visibility" Value="Collapsed"/>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding ConnectorOrientation}" Value="Right">
|
||||
<Setter TargetName="toggle" Property="HorizontalAlignment" Value="Right"/>
|
||||
<Setter TargetName="toggle" Property="Margin" Value="0,0,-15,0"/>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding ConnectorOrientation}" Value="Top">
|
||||
<Setter TargetName="toggle" Property="HorizontalAlignment" Value="Center"/>
|
||||
<Setter TargetName="toggle" Property="VerticalAlignment" Value="Top"/>
|
||||
<Setter TargetName="toggle" Property="Margin" Value="0,-15,0,0"/>
|
||||
</DataTrigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
|
||||
<ControlTemplate x:Key="MindLevel1NodeStyle" TargetType="{x:Type ContentControl}">
|
||||
<Grid >
|
||||
<Grid.ContextMenu>
|
||||
@@ -143,8 +185,8 @@
|
||||
</ControlTemplate>
|
||||
|
||||
<Style x:Key="MindNodeStyle" TargetType="{x:Type ContentControl}">
|
||||
<Setter Property="Template" Value="{StaticResource MindLevel1NodeStyle}" />
|
||||
<Style.Triggers>
|
||||
<Setter Property="Template" Value="{StaticResource MindNodeLevelStyle}" />
|
||||
<!--<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding NodeLevel}" Value="Level1">
|
||||
<Setter Property="Template" Value="{StaticResource MindLevel1NodeStyle}" />
|
||||
</DataTrigger>
|
||||
@@ -154,7 +196,7 @@
|
||||
<DataTrigger Binding="{Binding NodeLevel}" Value="Level3">
|
||||
<Setter Property="Template" Value="{StaticResource MindLevel3NodeStyle}" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style.Triggers>-->
|
||||
</Style>
|
||||
|
||||
<DataTemplate DataType="{x:Type viewmodel:MindNode}">
|
||||
|
||||
57
AIStudio.Wpf.Mind/ViewModels/IMindDiagramViewModel.cs
Normal file
57
AIStudio.Wpf.Mind/ViewModels/IMindDiagramViewModel.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using AIStudio.Wpf.DiagramDesigner;
|
||||
|
||||
namespace AIStudio.Wpf.Mind.ViewModels
|
||||
{
|
||||
public interface IMindDiagramViewModel : IDiagramViewModel
|
||||
{
|
||||
MindType MindType
|
||||
{
|
||||
get;set;
|
||||
}
|
||||
|
||||
SimpleCommand AddParentCommand
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
SimpleCommand AddChildCommand
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
SimpleCommand AddPeerCommand
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
SimpleCommand DeleteSelfCommand
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
SimpleCommand MoveForwardCommand
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
SimpleCommand MoveBackCommand
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
SimpleCommand ChangeMindTypeCommand
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
SimpleCommand ChangeMindThemeCommand
|
||||
{
|
||||
get;
|
||||
}
|
||||
}
|
||||
}
|
||||
382
AIStudio.Wpf.Mind/ViewModels/MindDiagramViewModel.cs
Normal file
382
AIStudio.Wpf.Mind/ViewModels/MindDiagramViewModel.cs
Normal file
@@ -0,0 +1,382 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using AIStudio.Wpf.DiagramDesigner;
|
||||
|
||||
namespace AIStudio.Wpf.Mind.ViewModels
|
||||
{
|
||||
public class MindDiagramViewModel : DiagramViewModel, IMindDiagramViewModel
|
||||
{
|
||||
#region
|
||||
private MindType _mindType = Mind.MindType.Mind;
|
||||
public MindType MindType
|
||||
{
|
||||
get
|
||||
{
|
||||
return _mindType;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _mindType, value))
|
||||
{
|
||||
ExecutedChangeMindTypeCommand(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 命令
|
||||
|
||||
public SimpleCommand AddParentCommand
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public SimpleCommand AddChildCommand
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public SimpleCommand AddPeerCommand
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public SimpleCommand DeleteSelfCommand
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public SimpleCommand MoveForwardCommand
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public SimpleCommand MoveBackCommand
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
private SimpleCommand _changeMindTypeCommand;
|
||||
public SimpleCommand ChangeMindTypeCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return this._changeMindTypeCommand ?? (this._changeMindTypeCommand = new SimpleCommand(MindExecuteEnable, this.ExecutedChangeMindTypeCommand));
|
||||
}
|
||||
}
|
||||
|
||||
public SimpleCommand ChangeMindThemeCommand
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public SimpleCommand ResetLayout
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public SimpleCommand Expand2Level1
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public SimpleCommand Expand2Level2
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public SimpleCommand Expand2Level3
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public SimpleCommand Expand2Level4
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public SimpleCommand Expand2Level5
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public SimpleCommand Expand2Level6
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
#endregion
|
||||
|
||||
public MindDiagramViewModel()
|
||||
{
|
||||
AddChildCommand = new SimpleCommand(MindExecuteEnable, ExecuteAddChildCommand);
|
||||
AddParentCommand = new SimpleCommand(MindLevelEnable, ExecuteAddParentCommand);
|
||||
AddPeerCommand = new SimpleCommand(MindLevelEnable, ExecuteAddPeerCommand);
|
||||
DeleteSelfCommand = new SimpleCommand(MindLevelEnable, ExecuteDeleteSelfCommand);
|
||||
MoveForwardCommand = new SimpleCommand(MindExecuteEnable, ExecuteMoveForwardCommand);
|
||||
MoveBackCommand = new SimpleCommand(MindExecuteEnable, ExecuteMoveBackCommand);
|
||||
}
|
||||
|
||||
public bool MindExecuteEnable(object para)
|
||||
{
|
||||
if (ExecuteEnable(para) == false) return false;
|
||||
|
||||
if (SelectedItem is MindNode) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool MindLevelEnable(object obj)
|
||||
{
|
||||
if (MindExecuteEnable(obj) == false) return false;
|
||||
|
||||
return (SelectedItem as MindNode).NodeLevel != NodeLevel.Level1;
|
||||
}
|
||||
|
||||
#region 操作
|
||||
private void ExecutedChangeMindTypeCommand(object obj)
|
||||
{
|
||||
if (obj is MindType mindType)
|
||||
{
|
||||
Items.OfType<MindNode>().ToList().ForEach(item => { item.MindType = mindType; });
|
||||
|
||||
Items.OfType<MindNode>().FirstOrDefault()?.LayoutUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
public void ExecuteAddChildCommand(object parameter)
|
||||
{
|
||||
List<MindNode> items = new List<MindNode>();
|
||||
if (parameter is MindNode parent)
|
||||
{
|
||||
|
||||
}
|
||||
else if (parameter is IEnumerable<MindNode> para)
|
||||
{
|
||||
parent = para.FirstOrDefault();//第一个固定为父节点
|
||||
items = para.Skip(1).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
parent = SelectedItem as MindNode;
|
||||
}
|
||||
|
||||
if (items?.Count == 0)
|
||||
{
|
||||
var node = new MindNode(this, (NodeLevel)Math.Min((int)parent.NodeLevel + 1, (int)NodeLevel.Level3), this.MindType) { Text = "分支主题" };
|
||||
items.Add(node);
|
||||
}
|
||||
|
||||
DoCommandManager.DoNewCommand(this.ToString(),
|
||||
() => {
|
||||
foreach (var item in items)
|
||||
{
|
||||
parent.AddChild(item);
|
||||
}
|
||||
parent.LayoutUpdated();
|
||||
},
|
||||
() => {
|
||||
foreach (var item in items)
|
||||
{
|
||||
parent.RemoveChild(item);
|
||||
}
|
||||
parent.LayoutUpdated();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public void ExecuteAddParentCommand(object parameter)
|
||||
{
|
||||
List<MindNode> items = new List<MindNode>();
|
||||
if (parameter is MindNode node)
|
||||
{
|
||||
|
||||
}
|
||||
else if (parameter is IEnumerable<MindNode> para)
|
||||
{
|
||||
node = para.FirstOrDefault();//第一个固定为父节点
|
||||
items = para.Skip(1).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
node = SelectedItem as MindNode;
|
||||
}
|
||||
if (items?.Count == 0)
|
||||
{
|
||||
items.Add(new MindNode(this, node.NodeLevel, this.MindType) { Text = "分支主题" });
|
||||
}
|
||||
|
||||
if (node.Parent is MindNode parent)
|
||||
{
|
||||
DoCommandManager.DoNewCommand(this.ToString(),
|
||||
() => {
|
||||
int index = parent.Children.IndexOf(node);
|
||||
|
||||
parent.AddChild(items[0], index + 1);
|
||||
parent.RemoveChild(node);
|
||||
items[0].AddChild(node);
|
||||
|
||||
parent.LayoutUpdated();
|
||||
},
|
||||
() => {
|
||||
int index = parent.Children.IndexOf(items[0]);
|
||||
items[0].RemoveChild(node);
|
||||
parent.AddChild(node, index + 1);
|
||||
|
||||
parent.LayoutUpdated();
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void ExecuteAddPeerCommand(object parameter)
|
||||
{
|
||||
List<MindNode> items = new List<MindNode>();
|
||||
if (parameter is MindNode pear)
|
||||
{
|
||||
|
||||
}
|
||||
else if (parameter is IEnumerable<MindNode> para)
|
||||
{
|
||||
pear = para.FirstOrDefault();//第一个固定为同级节点
|
||||
items = para.Skip(1).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
pear = SelectedItem as MindNode;
|
||||
}
|
||||
|
||||
if (items?.Count == 0)
|
||||
{
|
||||
var node = new MindNode(this, pear.NodeLevel, this.MindType) { Text = "分支主题" };
|
||||
items.Add(node);
|
||||
}
|
||||
|
||||
|
||||
if (pear.Parent is MindNode parent)
|
||||
{
|
||||
DoCommandManager.DoNewCommand(this.ToString(),
|
||||
() => {
|
||||
int index = parent.Children.IndexOf(pear);
|
||||
for (int i = 0; i < items.Count; i++)
|
||||
{
|
||||
parent.AddChild(items[i], index + i + 1);
|
||||
}
|
||||
|
||||
parent.LayoutUpdated();
|
||||
},
|
||||
() => {
|
||||
for (int i = 0; i < items.Count; i++)
|
||||
{
|
||||
parent.RemoveChild(items[i]);
|
||||
}
|
||||
parent.LayoutUpdated();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void ExecuteMoveBackCommand(object parameter)
|
||||
{
|
||||
if (parameter is MindNode node)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
node = SelectedItem as MindNode;
|
||||
}
|
||||
|
||||
if (node.Parent is MindNode parent)
|
||||
{
|
||||
DoCommandManager.DoNewCommand(this.ToString(),
|
||||
() => {
|
||||
int index = parent.Children.IndexOf(node);
|
||||
if (index < parent.Children.Count - 1)
|
||||
{
|
||||
parent.RemoveChild(node);
|
||||
parent.AddChild(node, index + 1);
|
||||
parent.LayoutUpdated();
|
||||
}
|
||||
},
|
||||
() => {
|
||||
int index = parent.Children.IndexOf(node);
|
||||
if (index > 0)
|
||||
{
|
||||
parent.RemoveChild(node);
|
||||
parent.AddChild(node, index - 1);
|
||||
parent.LayoutUpdated();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void ExecuteMoveForwardCommand(object parameter)
|
||||
{
|
||||
if (parameter is MindNode node)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
node = SelectedItem as MindNode;
|
||||
}
|
||||
|
||||
if (node.Parent is MindNode parent)
|
||||
{
|
||||
DoCommandManager.DoNewCommand(this.ToString(),
|
||||
() => {
|
||||
int index = parent.Children.IndexOf(node);
|
||||
if (index > 0)
|
||||
{
|
||||
parent.RemoveChild(node);
|
||||
parent.AddChild(node, index - 1);
|
||||
parent.LayoutUpdated();
|
||||
}
|
||||
},
|
||||
() => {
|
||||
int index = parent.Children.IndexOf(node);
|
||||
if (index < parent.Children.Count - 1)
|
||||
{
|
||||
parent.RemoveChild(node);
|
||||
parent.AddChild(node, index + 1);
|
||||
parent.LayoutUpdated();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void ExecuteDeleteSelfCommand(object parameter)
|
||||
{
|
||||
if (parameter is MindNode node)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
node = SelectedItem as MindNode;
|
||||
}
|
||||
|
||||
if (node.Parent is MindNode parent)
|
||||
{
|
||||
int index = parent.Children.IndexOf(node);
|
||||
DoCommandManager.DoNewCommand(this.ToString(),
|
||||
() => {
|
||||
parent.RemoveChild(node, true);
|
||||
parent.LayoutUpdated();
|
||||
},
|
||||
() => {
|
||||
parent.AddChild(node, index);
|
||||
parent.LayoutUpdated();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ using AIStudio.Wpf.Flowchart.Models;
|
||||
using AIStudio.Wpf.Mind.Helpers;
|
||||
using AIStudio.Wpf.Mind.Models;
|
||||
|
||||
|
||||
namespace AIStudio.Wpf.Mind.ViewModels
|
||||
{
|
||||
public class MindNode : DiagramItemViewModel
|
||||
@@ -31,20 +32,19 @@ namespace AIStudio.Wpf.Mind.ViewModels
|
||||
public MindNode(IDiagramViewModel root, NodeLevel nodeLevel, MindType mindType = MindType.Mind) : base(root)
|
||||
{
|
||||
NodeLevel = nodeLevel;
|
||||
MindType = mindType;
|
||||
MindType = mindType;
|
||||
|
||||
InitLayout();
|
||||
MindLayout.Appearance(this);
|
||||
InitLayout(true);
|
||||
}
|
||||
|
||||
public MindNode(IDiagramViewModel root, SelectableItemBase designer) : base(root, designer)
|
||||
{
|
||||
InitLayout();
|
||||
InitLayout(false);
|
||||
}
|
||||
|
||||
public MindNode(IDiagramViewModel root, SerializableItem serializableItem, string serializableType) : base(root, serializableItem, serializableType)
|
||||
{
|
||||
InitLayout();
|
||||
InitLayout(false);
|
||||
}
|
||||
|
||||
public override SelectableItemBase GetSerializableObject()
|
||||
@@ -58,21 +58,25 @@ namespace AIStudio.Wpf.Mind.ViewModels
|
||||
|
||||
EnabledForConnection = false;
|
||||
|
||||
AddChildCommand = new SimpleCommand(Command_Enable, ExecuteAddChildCommand);
|
||||
AddParentCommand = new SimpleCommand(Level_Enable, ExecuteAddParentCommand);
|
||||
AddPeerCommand = new SimpleCommand(Level_Enable, ExecuteAddPeerCommand);
|
||||
DeleteCommand = new SimpleCommand(Level_Enable, ExecuteDeleteCommand);
|
||||
MoveForwardCommand = new SimpleCommand(Command_Enable, ExecuteMoveForwardCommand);
|
||||
MoveBackCommand = new SimpleCommand(Command_Enable, ExecuteMoveBackCommand);
|
||||
AddChildCommand = (Root as IMindDiagramViewModel)?.AddChildCommand;
|
||||
AddParentCommand = (Root as IMindDiagramViewModel)?.AddParentCommand;
|
||||
AddPeerCommand = (Root as IMindDiagramViewModel)?.AddPeerCommand;
|
||||
DeleteSelfCommand = (Root as IMindDiagramViewModel)?.DeleteSelfCommand;
|
||||
MoveForwardCommand = (Root as IMindDiagramViewModel)?.MoveForwardCommand;
|
||||
MoveBackCommand = (Root as IMindDiagramViewModel)?.MoveBackCommand;
|
||||
BuildMenuOptions();
|
||||
|
||||
this.PropertyChanged += this.Item_PropertyChanged;
|
||||
}
|
||||
|
||||
protected void InitLayout()
|
||||
protected void InitLayout(bool initAppearance)
|
||||
{
|
||||
var layout = GlobalType.AllTypes.Where(p => typeof(IMindLayout).IsAssignableFrom(p)).FirstOrDefault(p => p.Name == MindType.ToString() + "Layout");
|
||||
MindLayout = layout != null ? (System.Activator.CreateInstance(layout) as IMindLayout) : new MindLayout();
|
||||
|
||||
if (initAppearance)
|
||||
{
|
||||
MindLayout.Appearance(this);
|
||||
}
|
||||
this.PropertyChanged += this.Item_PropertyChanged;
|
||||
}
|
||||
|
||||
protected override void LoadDesignerItemViewModel(SelectableItemBase designerbase)
|
||||
@@ -103,8 +107,6 @@ namespace AIStudio.Wpf.Mind.ViewModels
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private bool Level_Enable(object obj)
|
||||
{
|
||||
if (Command_Enable(obj) == false) return false;
|
||||
@@ -115,7 +117,7 @@ namespace AIStudio.Wpf.Mind.ViewModels
|
||||
#region 属性
|
||||
public IMindLayout MindLayout
|
||||
{
|
||||
get;set;
|
||||
get; set;
|
||||
}
|
||||
[Browsable(false)]
|
||||
private NodeLevel _nodeLevel;
|
||||
@@ -130,6 +132,29 @@ namespace AIStudio.Wpf.Mind.ViewModels
|
||||
SetProperty(ref _nodeLevel, value);
|
||||
}
|
||||
}
|
||||
//public MindNode ParentNode
|
||||
//{
|
||||
// get
|
||||
// {
|
||||
// return Parent as MindNode;
|
||||
// }
|
||||
|
||||
//}
|
||||
|
||||
//public int NodeLevel
|
||||
//{
|
||||
// get
|
||||
// {
|
||||
// if (ParentNode == null)
|
||||
// {
|
||||
// return 0;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return ParentNode.NodeLevel + 1;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
private MindType _mindType;
|
||||
public MindType MindType
|
||||
@@ -142,7 +167,7 @@ namespace AIStudio.Wpf.Mind.ViewModels
|
||||
{
|
||||
SetProperty(ref _mindType, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool _isExpanded = true;
|
||||
public bool IsExpanded
|
||||
@@ -214,7 +239,7 @@ namespace AIStudio.Wpf.Mind.ViewModels
|
||||
|
||||
public bool LayoutUpdating
|
||||
{
|
||||
get;set;
|
||||
get; set;
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -314,7 +339,7 @@ namespace AIStudio.Wpf.Mind.ViewModels
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public SimpleCommand DeleteCommand
|
||||
public SimpleCommand DeleteSelfCommand
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
@@ -337,136 +362,37 @@ namespace AIStudio.Wpf.Mind.ViewModels
|
||||
CinchMenuItem menuItem = new CinchMenuItem();
|
||||
menuItem.Text = "下级";
|
||||
menuItem.Command = AddChildCommand;
|
||||
menuItem.CommandParameter = this;
|
||||
menuOptions.Add(menuItem);
|
||||
menuItem = new CinchMenuItem();
|
||||
menuItem.Text = "同级";
|
||||
menuItem.Command = AddPeerCommand;
|
||||
menuItem.CommandParameter = this;
|
||||
menuOptions.Add(menuItem);
|
||||
menuItem = new CinchMenuItem();
|
||||
menuItem.Text = "上级";
|
||||
menuItem.Command = AddParentCommand;
|
||||
menuItem.CommandParameter = this;
|
||||
menuOptions.Add(menuItem);
|
||||
menuItem = new CinchMenuItem();
|
||||
menuItem.Text = "前移";
|
||||
menuItem.Command = MoveForwardCommand;
|
||||
menuItem.CommandParameter = this;
|
||||
menuOptions.Add(menuItem);
|
||||
menuItem = new CinchMenuItem();
|
||||
menuItem.Text = "后移";
|
||||
menuItem.Command = MoveBackCommand;
|
||||
menuItem.CommandParameter = this;
|
||||
menuOptions.Add(menuItem);
|
||||
menuItem = new CinchMenuItem();
|
||||
menuItem.Text = "删除";
|
||||
menuItem.Command = DeleteCommand;
|
||||
menuItem.Command = DeleteSelfCommand;
|
||||
menuItem.CommandParameter = this;
|
||||
menuOptions.Add(menuItem);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 操作
|
||||
public void ExecuteAddChildCommand(object obj)
|
||||
{
|
||||
if (obj is MindNode node)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
node = new MindNode(Root, (NodeLevel)Math.Min((int)NodeLevel + 1, (int)NodeLevel.Level3), this.MindType) { Text = "分支主题" };
|
||||
}
|
||||
AddChild(node);
|
||||
|
||||
LayoutUpdated();
|
||||
}
|
||||
|
||||
public void ExecuteAddParentCommand(object obj)
|
||||
{
|
||||
if (Parent is MindNode parent)
|
||||
{
|
||||
if (obj is MindNode node)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NodeLevel == NodeLevel.Level1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (NodeLevel == NodeLevel.Level2)
|
||||
node = new MindNode(Root, NodeLevel.Level2, this.MindType) { Text = "分支主题" };
|
||||
else
|
||||
node = new MindNode(Root, NodeLevel.Level3, this.MindType) { Text = "分支主题" };
|
||||
}
|
||||
|
||||
parent.RemoveChild(this);
|
||||
int index = parent.Children.IndexOf(this);
|
||||
parent.AddChild(node, index + 1);
|
||||
|
||||
node.AddChild(this);
|
||||
|
||||
LayoutUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
public void ExecuteAddPeerCommand(object obj)
|
||||
{
|
||||
if (Parent is MindNode parent)
|
||||
{
|
||||
if (obj is MindNode node)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NodeLevel == NodeLevel.Level1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (NodeLevel == NodeLevel.Level2)
|
||||
node = new MindNode(Root, NodeLevel.Level2, this.MindType) { Text = "分支主题" };
|
||||
else
|
||||
node = new MindNode(Root, NodeLevel.Level3, this.MindType) { Text = "分支主题" };
|
||||
}
|
||||
int index = parent.Children.IndexOf(this);
|
||||
parent.AddChild(node, index + 1);
|
||||
|
||||
LayoutUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
private void ExecuteMoveBackCommand(object obj)
|
||||
{
|
||||
if (Parent is MindNode parent)
|
||||
{
|
||||
int index = parent.Children.IndexOf(this);
|
||||
if (index < parent.Children.Count - 1)
|
||||
{
|
||||
parent.RemoveChild(this);
|
||||
parent.AddChild(this, index + 1);
|
||||
LayoutUpdated();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ExecuteMoveForwardCommand(object obj)
|
||||
{
|
||||
if (Parent is MindNode parent)
|
||||
{
|
||||
int index = parent.Children.IndexOf(this);
|
||||
if (index > 0)
|
||||
{
|
||||
parent.RemoveChild(this);
|
||||
parent.AddChild(this, index - 1);
|
||||
LayoutUpdated();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ExecuteDeleteCommand(object obj)
|
||||
{
|
||||
if (Parent is MindNode parent)
|
||||
{
|
||||
parent.RemoveChild(this, true);
|
||||
LayoutUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
#region 操作
|
||||
public void AddChild(MindNode item, int index = -1)
|
||||
{
|
||||
if (this.NodeLevel == NodeLevel.Level1)
|
||||
@@ -486,13 +412,10 @@ namespace AIStudio.Wpf.Mind.ViewModels
|
||||
this.Children.Add(item);
|
||||
}
|
||||
item.Parent = this;
|
||||
Root?.DirectAddItemCommand.Execute(item);
|
||||
|
||||
ConnectionViewModel connector = MindLayout?.GetConnectionViewModel(this, item);
|
||||
Root?.DirectAddItemCommand.Execute(connector);
|
||||
Root?.ClearSelectedItemsCommand.Execute(new SelectableDesignerItemViewModelBase[] { connector });
|
||||
|
||||
Root?.BringForwardCommand.Execute(new DesignerItemViewModelBase[] { item });
|
||||
Root?.DirectAddItemCommand.Execute(new SelectableDesignerItemViewModelBase[] { item, connector });
|
||||
connector.ZIndex = -1;
|
||||
this.IsSelected = true;
|
||||
}
|
||||
|
||||
public void RemoveChild(MindNode item, bool removeall = false)
|
||||
@@ -535,17 +458,9 @@ namespace AIStudio.Wpf.Mind.ViewModels
|
||||
case nameof(NodeLevel):
|
||||
MindLayout?.Appearance(this);
|
||||
break;
|
||||
//case nameof(MindType):
|
||||
// if (NodeLevel == NodeLevel.Level1)
|
||||
// {
|
||||
// MindLayout?.Appearance(this);
|
||||
// LayoutUpdated();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// GetLevel1Node().MindType = MindType;
|
||||
// }
|
||||
// break;
|
||||
case nameof(MindType):
|
||||
InitLayout(true);
|
||||
break;
|
||||
case nameof(Left):
|
||||
{
|
||||
if (e is ValuePropertyChangedEventArgs valuePropertyChangedEventArgs)
|
||||
@@ -625,7 +540,7 @@ namespace AIStudio.Wpf.Mind.ViewModels
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
public class LinkInfo : BindableBase
|
||||
{
|
||||
private string _url;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project>
|
||||
<!-- Project properties -->
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netcoreapp3.1;net5.0-windows</TargetFrameworks>
|
||||
<TargetFrameworks>net461;netcoreapp3.1;net5.0-windows</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
|
||||
Reference in New Issue
Block a user