mirror of
https://gitee.com/akwkevin/aistudio.-wpf.-diagram
synced 2026-05-01 21:41:28 +08:00
添加项目文件。
This commit is contained in:
256
Util.DiagramDesigner/Adorners/RubberbandAdorner.cs
Normal file
256
Util.DiagramDesigner/Adorners/RubberbandAdorner.cs
Normal file
@@ -0,0 +1,256 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public class RubberbandAdorner : Adorner
|
||||
{
|
||||
private Point? startPoint;
|
||||
private Point? endPoint;
|
||||
private List<Point> pointList = new List<Point>();
|
||||
private List<PointDesignerItemViewModel> pointDesignerItemViewModelList = new List<PointDesignerItemViewModel>();
|
||||
private Pen rubberbandPen;
|
||||
|
||||
private DesignerCanvas _designerCanvas;
|
||||
|
||||
private IDiagramViewModel _viewModel { get { return _designerCanvas.DataContext as IDiagramViewModel; } }
|
||||
private IDiagramServiceProvider _service { get { return DiagramServicesProvider.Instance.Provider; } }
|
||||
|
||||
public RubberbandAdorner(DesignerCanvas designerCanvas, Point? dragStartPoint)
|
||||
: base(designerCanvas)
|
||||
{
|
||||
this._designerCanvas = designerCanvas;
|
||||
this.startPoint = dragStartPoint;
|
||||
rubberbandPen = new Pen(Brushes.LightSlateGray, 1);
|
||||
rubberbandPen.DashStyle = new DashStyle(new double[] { 2 }, 1);
|
||||
}
|
||||
|
||||
protected override void OnMouseMove(System.Windows.Input.MouseEventArgs e)
|
||||
{
|
||||
if (e.LeftButton == MouseButtonState.Pressed)
|
||||
{
|
||||
if (!this.IsMouseCaptured)
|
||||
this.CaptureMouse();
|
||||
|
||||
endPoint = e.GetPosition(this);
|
||||
if (this._service.DrawModeViewModel.GetDrawMode() == DrawMode.Polyline)
|
||||
{
|
||||
if (pointList.Count == 0 && this.startPoint.HasValue)
|
||||
{
|
||||
pointList.Add(this.startPoint.Value);
|
||||
}
|
||||
pointList.Add(endPoint.Value);
|
||||
}
|
||||
|
||||
UpdateSelection();
|
||||
this.InvalidateVisual();
|
||||
}
|
||||
else if (this._service.DrawModeViewModel.GetDrawMode() == DrawMode.DirectLine)
|
||||
{
|
||||
if (pointList.Count == 0 && this.startPoint.HasValue)
|
||||
{
|
||||
pointList.Add(this.startPoint.Value);
|
||||
var item = new PointDesignerItemViewModel(startPoint.Value);
|
||||
item.ShowConnectors = true;
|
||||
_viewModel.DirectAddItemCommand.Execute(item);
|
||||
pointDesignerItemViewModelList.Add(item);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this.IsMouseCaptured) this.ReleaseMouseCapture();
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
protected override void OnMouseUp(System.Windows.Input.MouseButtonEventArgs e)
|
||||
{
|
||||
if (this._service.DrawModeViewModel.GetDrawMode() == DrawMode.DirectLine && e.ChangedButton == MouseButton.Left )
|
||||
{
|
||||
endPoint = e.GetPosition(this);
|
||||
|
||||
bool isend = false;
|
||||
var connector = ControlExtession.TryFindFromPoint<PointConnector>(this._designerCanvas, endPoint.Value);
|
||||
if (connector != null)
|
||||
{
|
||||
if (object.Equals(connector.DataContext, pointDesignerItemViewModelList[0].TopConnector))
|
||||
{
|
||||
isend = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (isend == false)
|
||||
{
|
||||
pointList.Add(endPoint.Value);
|
||||
var item = new PointDesignerItemViewModel(endPoint.Value);
|
||||
item.ShowConnectors = true;
|
||||
_viewModel.DirectAddItemCommand.Execute(item);
|
||||
pointDesignerItemViewModelList.Add(item);
|
||||
|
||||
UpdateSelection();
|
||||
this.InvalidateVisual();
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
this._service.DrawModeViewModel.SetDrawMode(DrawMode.Polygon);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// release mouse capture
|
||||
if (this.IsMouseCaptured) this.ReleaseMouseCapture();
|
||||
|
||||
// remove this adorner from adorner layer
|
||||
AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this._designerCanvas);
|
||||
if (adornerLayer != null)
|
||||
adornerLayer.Remove(this);
|
||||
|
||||
if (this._service.DrawModeViewModel.GetDrawMode() == DrawMode.Line ||
|
||||
this._service.DrawModeViewModel.GetDrawMode() == DrawMode.Rectangle ||
|
||||
this._service.DrawModeViewModel.GetDrawMode() == DrawMode.Ellipse ||
|
||||
this._service.DrawModeViewModel.GetDrawMode() == DrawMode.Polyline ||
|
||||
this._service.DrawModeViewModel.GetDrawMode() == DrawMode.Polygon ||
|
||||
this._service.DrawModeViewModel.GetDrawMode() == DrawMode.DirectLine ||
|
||||
this._service.DrawModeViewModel.GetDrawMode() == DrawMode.Text)
|
||||
{
|
||||
if (this.startPoint.HasValue && this.endPoint.HasValue)
|
||||
{
|
||||
if (this._service.DrawModeViewModel.GetDrawMode() == DrawMode.Polyline
|
||||
|| this._service.DrawModeViewModel.GetDrawMode() == DrawMode.Polygon
|
||||
|| this._service.DrawModeViewModel.GetDrawMode() == DrawMode.DirectLine)
|
||||
{
|
||||
ShapeDesignerItemViewModel itemBase = new ShapeDesignerItemViewModel(this._service.DrawModeViewModel.GetDrawMode(), pointList);
|
||||
_viewModel.AddItemCommand.Execute(itemBase);
|
||||
itemBase.PointDesignerItemViewModels.ForEach(p =>
|
||||
{
|
||||
p.ParentId = itemBase.Id;
|
||||
_viewModel.DirectAddItemCommand.Execute(p);
|
||||
});
|
||||
}
|
||||
else if (this._service.DrawModeViewModel.GetDrawMode() == DrawMode.Text)
|
||||
{
|
||||
TextDesignerItemViewModel itemBase = new TextDesignerItemViewModel();
|
||||
Point position = e.GetPosition(this);
|
||||
itemBase.Left = Math.Min(this.startPoint.Value.X, this.endPoint.Value.X);
|
||||
itemBase.Top = Math.Min(this.startPoint.Value.Y, this.endPoint.Value.Y);
|
||||
itemBase.ItemWidth = Math.Abs(this.endPoint.Value.X - this.startPoint.Value.X);
|
||||
itemBase.ItemHeight = Math.Abs(this.endPoint.Value.Y - this.startPoint.Value.Y);
|
||||
|
||||
_viewModel.AddItemCommand.Execute(itemBase);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShapeDesignerItemViewModel itemBase = new ShapeDesignerItemViewModel(this._service.DrawModeViewModel.GetDrawMode(), new List<Point> { this.startPoint.Value, this.endPoint.Value });
|
||||
_viewModel.AddItemCommand.Execute(itemBase);
|
||||
itemBase.PointDesignerItemViewModels.ForEach(p =>
|
||||
{
|
||||
p.ParentId = itemBase.Id;
|
||||
_viewModel.DirectAddItemCommand.Execute(p);
|
||||
});
|
||||
}
|
||||
}
|
||||
this._service.DrawModeViewModel.ResetDrawMode();
|
||||
}
|
||||
|
||||
pointDesignerItemViewModelList.ForEach(p => _viewModel.DirectRemoveItemCommand.Execute(p));
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
protected override void OnRender(DrawingContext dc)
|
||||
{
|
||||
base.OnRender(dc);
|
||||
|
||||
// without a background the OnMouseMove event would not be fired !
|
||||
// Alternative: implement a Canvas as a child of this adorner, like
|
||||
// the ConnectionAdorner does.
|
||||
dc.DrawRectangle(Brushes.Transparent, null, new Rect(RenderSize));
|
||||
|
||||
if (this.startPoint.HasValue && this.endPoint.HasValue)
|
||||
{
|
||||
if (this._service.DrawModeViewModel.GetDrawMode() == DrawMode.Line)
|
||||
{
|
||||
dc.DrawLine(rubberbandPen, this.startPoint.Value, this.endPoint.Value);
|
||||
}
|
||||
else if (this._service.DrawModeViewModel.GetDrawMode() == DrawMode.Ellipse)
|
||||
{
|
||||
var centerPoint = new Point((this.startPoint.Value.X + this.endPoint.Value.X) / 2, (this.startPoint.Value.Y + this.endPoint.Value.Y) / 2);
|
||||
dc.DrawEllipse(Brushes.Transparent, rubberbandPen, centerPoint, Math.Abs(this.startPoint.Value.X - this.endPoint.Value.X) / 2, Math.Abs(this.startPoint.Value.Y - this.endPoint.Value.Y) / 2);
|
||||
}
|
||||
else if (_service.DrawModeViewModel.GetDrawMode() == DrawMode.Polyline)
|
||||
{
|
||||
var disList = pointList.ToList();
|
||||
for (int i = 1; i < pointList.Count; i++)
|
||||
{
|
||||
dc.DrawLine(rubberbandPen, disList[i - 1], disList[i]);
|
||||
}
|
||||
}
|
||||
else if (_service.DrawModeViewModel.GetDrawMode() == DrawMode.DirectLine)
|
||||
{
|
||||
var disList = pointList.ToList();
|
||||
for (int i = 1; i < pointList.Count; i++)
|
||||
{
|
||||
dc.DrawLine(rubberbandPen, disList[i - 1], disList[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dc.DrawRectangle(Brushes.Transparent, rubberbandPen, new Rect(this.startPoint.Value, this.endPoint.Value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private T GetParent<T>(Type parentType, DependencyObject dependencyObject) where T : DependencyObject
|
||||
{
|
||||
DependencyObject parent = VisualTreeHelper.GetParent(dependencyObject);
|
||||
if (parent.GetType() == parentType)
|
||||
return (T)parent;
|
||||
|
||||
return GetParent<T>(parentType, parent);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void UpdateSelection()
|
||||
{
|
||||
IDiagramViewModel vm = (_designerCanvas.DataContext as IDiagramViewModel);
|
||||
Rect rubberBand = new Rect(startPoint.Value, endPoint.Value);
|
||||
ItemsControl itemsControl = GetParent<ItemsControl>(typeof(ItemsControl), _designerCanvas);
|
||||
|
||||
foreach (SelectableDesignerItemViewModelBase item in vm.Items)
|
||||
{
|
||||
if (item is SelectableDesignerItemViewModelBase)
|
||||
{
|
||||
DependencyObject container = itemsControl.ItemContainerGenerator.ContainerFromItem(item);
|
||||
|
||||
Rect itemRect = VisualTreeHelper.GetDescendantBounds((Visual)container);
|
||||
Rect itemBounds = ((Visual)container).TransformToAncestor(_designerCanvas).TransformBounds(itemRect);
|
||||
|
||||
if (rubberBand.Contains(itemBounds))
|
||||
{
|
||||
//item.IsSelected = true;
|
||||
vm.SelectionService.AddToSelection(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)))
|
||||
{
|
||||
//item.IsSelected = false;
|
||||
vm.SelectionService.RemoveFromSelection(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
94
Util.DiagramDesigner/AttachedProperties/DragAndDropProps.cs
Normal file
94
Util.DiagramDesigner/AttachedProperties/DragAndDropProps.cs
Normal file
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Input;
|
||||
using Util.DiagramDesigner.Helpers;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public static class DragAndDropProps
|
||||
{
|
||||
#region EnabledForDrag
|
||||
|
||||
public static readonly DependencyProperty EnabledForDragProperty =
|
||||
DependencyProperty.RegisterAttached("EnabledForDrag", typeof(bool), typeof(DragAndDropProps),
|
||||
new FrameworkPropertyMetadata((bool)false,
|
||||
new PropertyChangedCallback(OnEnabledForDragChanged)));
|
||||
|
||||
public static bool GetEnabledForDrag(DependencyObject d)
|
||||
{
|
||||
return (bool)d.GetValue(EnabledForDragProperty);
|
||||
}
|
||||
|
||||
public static void SetEnabledForDrag(DependencyObject d, bool value)
|
||||
{
|
||||
d.SetValue(EnabledForDragProperty, value);
|
||||
}
|
||||
|
||||
private static void OnEnabledForDragChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
FrameworkElement fe = (FrameworkElement) d;
|
||||
|
||||
|
||||
if((bool)e.NewValue)
|
||||
{
|
||||
fe.PreviewMouseDown += Fe_PreviewMouseDown;
|
||||
fe.MouseMove += Fe_MouseMove;
|
||||
}
|
||||
else
|
||||
{
|
||||
fe.PreviewMouseDown -= Fe_PreviewMouseDown;
|
||||
fe.MouseMove -= Fe_MouseMove;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region DragStartPoint
|
||||
|
||||
public static readonly DependencyProperty DragStartPointProperty =
|
||||
DependencyProperty.RegisterAttached("DragStartPoint", typeof(Point?), typeof(DragAndDropProps));
|
||||
|
||||
public static Point? GetDragStartPoint(DependencyObject d)
|
||||
{
|
||||
return (Point?)d.GetValue(DragStartPointProperty);
|
||||
}
|
||||
|
||||
|
||||
public static void SetDragStartPoint(DependencyObject d, Point? value)
|
||||
{
|
||||
d.SetValue(DragStartPointProperty, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
static void Fe_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
|
||||
{
|
||||
Point? dragStartPoint = GetDragStartPoint((DependencyObject)sender);
|
||||
|
||||
if (e.LeftButton != MouseButtonState.Pressed)
|
||||
dragStartPoint = null;
|
||||
|
||||
if (dragStartPoint.HasValue)
|
||||
{
|
||||
DragObject dataObject = new DragObject();
|
||||
dataObject.ContentType = (((FrameworkElement)sender).DataContext as ToolBoxData).Type;
|
||||
dataObject.DesiredSize = new Size(65, 65);
|
||||
dataObject.Icon = (((FrameworkElement)sender).DataContext as ToolBoxData).Icon;
|
||||
dataObject.ColorViewModel = (((FrameworkElement)sender).DataContext as ToolBoxData).ColorViewModel;
|
||||
dataObject.DesignerItem = (((FrameworkElement)sender).DataContext as ToolBoxData).Addition as DesignerItemBase;
|
||||
|
||||
DragDrop.DoDragDrop((DependencyObject)sender, dataObject, DragDropEffects.Copy);
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void Fe_PreviewMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
|
||||
{
|
||||
SetDragStartPoint((DependencyObject)sender, e.GetPosition((IInputElement)sender));
|
||||
}
|
||||
}
|
||||
}
|
||||
60
Util.DiagramDesigner/AttachedProperties/ItemConnectProps.cs
Normal file
60
Util.DiagramDesigner/AttachedProperties/ItemConnectProps.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public static class ItemConnectProps
|
||||
{
|
||||
#region EnabledForConnection
|
||||
|
||||
public static readonly DependencyProperty EnabledForConnectionProperty =
|
||||
DependencyProperty.RegisterAttached("EnabledForConnection", typeof(bool), typeof(ItemConnectProps),
|
||||
new FrameworkPropertyMetadata((bool)false,
|
||||
new PropertyChangedCallback(OnEnabledForConnectionChanged)));
|
||||
|
||||
public static bool GetEnabledForConnection(DependencyObject d)
|
||||
{
|
||||
return (bool)d.GetValue(EnabledForConnectionProperty);
|
||||
}
|
||||
|
||||
public static void SetEnabledForConnection(DependencyObject d, bool value)
|
||||
{
|
||||
d.SetValue(EnabledForConnectionProperty, value);
|
||||
}
|
||||
|
||||
private static void OnEnabledForConnectionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
FrameworkElement fe = (FrameworkElement)d;
|
||||
|
||||
|
||||
if ((bool)e.NewValue)
|
||||
{
|
||||
fe.MouseEnter += Fe_MouseEnter;
|
||||
}
|
||||
else
|
||||
{
|
||||
fe.MouseEnter -= Fe_MouseEnter;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
static void Fe_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (((FrameworkElement)sender).DataContext is DesignerItemViewModelBase)
|
||||
{
|
||||
DesignerItemViewModelBase designerItem = (DesignerItemViewModelBase)((FrameworkElement)sender).DataContext;
|
||||
designerItem.ShowConnectors = true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
75
Util.DiagramDesigner/AttachedProperties/SelectionProps.cs
Normal file
75
Util.DiagramDesigner/AttachedProperties/SelectionProps.cs
Normal file
@@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public static class SelectionProps
|
||||
{
|
||||
#region EnabledForSelection
|
||||
|
||||
public static readonly DependencyProperty EnabledForSelectionProperty =
|
||||
DependencyProperty.RegisterAttached("EnabledForSelection", typeof(bool), typeof(SelectionProps),
|
||||
new FrameworkPropertyMetadata((bool)false,
|
||||
new PropertyChangedCallback(OnEnabledForSelectionChanged)));
|
||||
|
||||
public static bool GetEnabledForSelection(DependencyObject d)
|
||||
{
|
||||
return (bool)d.GetValue(EnabledForSelectionProperty);
|
||||
}
|
||||
|
||||
public static void SetEnabledForSelection(DependencyObject d, bool value)
|
||||
{
|
||||
d.SetValue(EnabledForSelectionProperty, value);
|
||||
}
|
||||
|
||||
private static void OnEnabledForSelectionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
FrameworkElement fe = (FrameworkElement)d;
|
||||
if ((bool)e.NewValue)
|
||||
{
|
||||
fe.PreviewMouseDown += Fe_PreviewMouseDown;
|
||||
}
|
||||
else
|
||||
{
|
||||
fe.PreviewMouseDown -= Fe_PreviewMouseDown;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
static void Fe_PreviewMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
|
||||
{
|
||||
SelectableDesignerItemViewModelBase selectableDesignerItemViewModelBase =
|
||||
(SelectableDesignerItemViewModelBase)((FrameworkElement)sender).DataContext;
|
||||
|
||||
if(selectableDesignerItemViewModelBase != null && selectableDesignerItemViewModelBase.IsHitTestVisible)
|
||||
{
|
||||
if ((Keyboard.Modifiers & (ModifierKeys.Shift | ModifierKeys.Control)) != ModifierKeys.None)
|
||||
{
|
||||
if ((Keyboard.Modifiers & (ModifierKeys.Shift)) != ModifierKeys.None)
|
||||
{
|
||||
selectableDesignerItemViewModelBase.IsSelected = !selectableDesignerItemViewModelBase.IsSelected;
|
||||
}
|
||||
|
||||
if ((Keyboard.Modifiers & (ModifierKeys.Control)) != ModifierKeys.None)
|
||||
{
|
||||
selectableDesignerItemViewModelBase.IsSelected = !selectableDesignerItemViewModelBase.IsSelected;
|
||||
}
|
||||
}
|
||||
else if (!selectableDesignerItemViewModelBase.IsSelected)
|
||||
{
|
||||
foreach (SelectableDesignerItemViewModelBase item in selectableDesignerItemViewModelBase.Parent.SelectedItems)
|
||||
item.IsSelected = false;
|
||||
|
||||
selectableDesignerItemViewModelBase.Parent.SelectedItems.Clear();
|
||||
//selectableDesignerItemViewModelBase.IsSelected = true;
|
||||
selectableDesignerItemViewModelBase.Parent.SelectionService.AddToSelection(selectableDesignerItemViewModelBase);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Util.DiagramDesigner/Attributes/CanDoAttribute.cs
Normal file
11
Util.DiagramDesigner/Attributes/CanDoAttribute.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class CanDoAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
||||
152
Util.DiagramDesigner/Controls/BorderResizeThumb.cs
Normal file
152
Util.DiagramDesigner/Controls/BorderResizeThumb.cs
Normal file
@@ -0,0 +1,152 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Util.DiagramDesigner.Controls
|
||||
{
|
||||
public class BorderResizeThumb : Thumb
|
||||
{
|
||||
#region ResizeMode
|
||||
|
||||
/// <summary>
|
||||
/// BindingWidthAndHeight Dependency Property
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty ResizeModeProperty =
|
||||
DependencyProperty.Register("ResizeMode", typeof(ResizeMode), typeof(BorderResizeThumb),
|
||||
new FrameworkPropertyMetadata(ResizeMode.Size));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the BindingWidthAndHeight property. This dependency property
|
||||
/// indicates if the ResizableItemsControl is in Composing mode.
|
||||
/// </summary>
|
||||
public ResizeMode ResizeMode
|
||||
{
|
||||
get { return (ResizeMode)GetValue(ResizeModeProperty); }
|
||||
set { SetValue(ResizeModeProperty, value); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ResizeElement
|
||||
|
||||
/// <summary>
|
||||
/// BindingWidthAndHeight Dependency Property
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty ResizeElementProperty =
|
||||
DependencyProperty.Register("ResizeElement", typeof(FrameworkElement), typeof(BorderResizeThumb),
|
||||
new FrameworkPropertyMetadata(null));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the BindingWidthAndHeight property. This dependency property
|
||||
/// indicates if the ResizableItemsControl is in Composing mode.
|
||||
/// </summary>
|
||||
public FrameworkElement ResizeElement
|
||||
{
|
||||
get { return (FrameworkElement)GetValue(ResizeElementProperty); }
|
||||
set { SetValue(ResizeElementProperty, value); }
|
||||
}
|
||||
#endregion
|
||||
|
||||
public BorderResizeThumb()
|
||||
{
|
||||
base.DragDelta += new DragDeltaEventHandler(ResizeThumb_DragDelta);
|
||||
}
|
||||
|
||||
void ResizeThumb_DragDelta(object sender, DragDeltaEventArgs e)
|
||||
{
|
||||
if (ResizeElement == null) return;
|
||||
|
||||
if (ResizeMode == ResizeMode.Size)
|
||||
{
|
||||
switch (base.VerticalAlignment)
|
||||
{
|
||||
case VerticalAlignment.Top:
|
||||
if (ResizeElement.Height - e.VerticalChange > ResizeElement.MinHeight && ResizeElement.Height - e.VerticalChange < ResizeElement.MaxHeight)
|
||||
{
|
||||
ResizeElement.Height -= e.VerticalChange;
|
||||
}
|
||||
break;
|
||||
case VerticalAlignment.Bottom:
|
||||
if (ResizeElement.Height + e.VerticalChange > ResizeElement.MinHeight && ResizeElement.Height + e.VerticalChange < ResizeElement.MaxHeight)
|
||||
{
|
||||
ResizeElement.Height += e.VerticalChange;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (base.HorizontalAlignment)
|
||||
{
|
||||
case HorizontalAlignment.Left:
|
||||
if (ResizeElement.Width - e.HorizontalChange > ResizeElement.MinWidth && ResizeElement.Width - e.HorizontalChange < ResizeElement.MaxWidth)
|
||||
{
|
||||
ResizeElement.Width -= e.HorizontalChange;
|
||||
}
|
||||
break;
|
||||
case HorizontalAlignment.Right:
|
||||
if (ResizeElement.Width + e.HorizontalChange > ResizeElement.MinWidth && ResizeElement.Width + e.HorizontalChange < ResizeElement.MaxWidth)
|
||||
{
|
||||
ResizeElement.Width += e.HorizontalChange;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (ResizeMode == ResizeMode.Margin)
|
||||
{
|
||||
switch (base.VerticalAlignment)
|
||||
{
|
||||
case VerticalAlignment.Top:
|
||||
if (ResizeElement.Margin.Top + e.VerticalChange > 0)
|
||||
{
|
||||
ResizeElement.Margin = new Thickness(ResizeElement.Margin.Left, ResizeElement.Margin.Top + e.VerticalChange, ResizeElement.Margin.Right, ResizeElement.Margin.Bottom);
|
||||
}
|
||||
break;
|
||||
case VerticalAlignment.Bottom:
|
||||
if (ResizeElement.Margin.Bottom - e.VerticalChange > 0)
|
||||
{
|
||||
ResizeElement.Margin = new Thickness(ResizeElement.Margin.Left, ResizeElement.Margin.Top, ResizeElement.Margin.Right, ResizeElement.Margin.Bottom - e.VerticalChange);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (base.HorizontalAlignment)
|
||||
{
|
||||
case HorizontalAlignment.Left:
|
||||
if (ResizeElement.Margin.Left + e.HorizontalChange > 0)
|
||||
{
|
||||
ResizeElement.Margin = new Thickness(ResizeElement.Margin.Left + e.HorizontalChange, ResizeElement.Margin.Top, ResizeElement.Margin.Right, ResizeElement.Margin.Bottom);
|
||||
}
|
||||
break;
|
||||
case HorizontalAlignment.Right:
|
||||
if (ResizeElement.Margin.Right - e.HorizontalChange > 0)
|
||||
{
|
||||
ResizeElement.Margin = new Thickness(ResizeElement.Margin.Left, ResizeElement.Margin.Top, ResizeElement.Margin.Right - e.HorizontalChange, ResizeElement.Margin.Bottom);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (ResizeMode == ResizeMode.DragMargin)
|
||||
{
|
||||
ResizeElement.Margin = new Thickness(ResizeElement.Margin.Left + e.HorizontalChange, ResizeElement.Margin.Top + e.VerticalChange, ResizeElement.Margin.Right - e.HorizontalChange, ResizeElement.Margin.Bottom - e.VerticalChange);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum ResizeMode
|
||||
{
|
||||
Size,
|
||||
Margin,
|
||||
DragMargin,
|
||||
}
|
||||
}
|
||||
84
Util.DiagramDesigner/Controls/CinchMenuItem.cs
Normal file
84
Util.DiagramDesigner/Controls/CinchMenuItem.cs
Normal file
@@ -0,0 +1,84 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a mechanism for constructing MenuItems
|
||||
/// within a ViewModel
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <![CDATA[
|
||||
///
|
||||
/// AND IN VIEWMODEL C# DO THIS TO CREATE MENUS
|
||||
/// private List<CinchMenuItem> CreateMenus()
|
||||
/// {
|
||||
/// var menu = new List<CinchMenuItem>();
|
||||
/// //create the File Menu
|
||||
/// var miFile = new CinchMenuItem("File");
|
||||
/// var miExit = new CinchMenuItem("Exit");
|
||||
/// miExit.Command = ExitApplicationCommand;
|
||||
/// miFile.Children.Add(miExit);
|
||||
/// menu.Add(miFile);
|
||||
/// //create the Actions Menu
|
||||
/// menu.Add(new CinchMenuItem("Actions"));
|
||||
/// return menu;
|
||||
/// }
|
||||
///
|
||||
///
|
||||
/// public List<CinchMenuItem> MenuOptions
|
||||
/// {
|
||||
/// get
|
||||
/// {
|
||||
/// return CreateMenus();
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// AND IN XAML DO THE FOLLOWING FOR THE STYLE
|
||||
/// <Style x:Key="ContextMenuItemStyle">
|
||||
/// <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}" />
|
||||
/// </Style>
|
||||
///
|
||||
/// AND YOU CAN CREATE A MENU LIKE THIS
|
||||
/// <StackPanel Orientation="Horizontal">
|
||||
/// <Image Source="{Binding Image}" Width="16" Height="16" />
|
||||
/// <TextBlock Margin="5" HorizontalAlignment="Left" VerticalAlignment="Center"
|
||||
/// Text="{Binding Header}" />
|
||||
/// <StackPanel.ContextMenu>
|
||||
/// <ContextMenu ItemContainerStyle="{StaticResource ContextMenuItemStyle}"
|
||||
/// ItemsSource="{Binding MenuOptions}" />
|
||||
/// </StackPanel.ContextMenu>
|
||||
/// </StackPanel>
|
||||
/// ]]>
|
||||
/// </example>
|
||||
public class CinchMenuItem
|
||||
{
|
||||
#region Public Properties
|
||||
public String Text { get; set; }
|
||||
public String IconUrl { get; set; }
|
||||
public bool IsChecked { get; set; }
|
||||
public bool IsCheckable { get; set; }
|
||||
public List<CinchMenuItem> Children { get; private set; }
|
||||
public Object CommandParameter { get; set; }
|
||||
public SimpleCommand Command { get; set; }
|
||||
#endregion
|
||||
|
||||
#region Ctor
|
||||
public CinchMenuItem()
|
||||
{
|
||||
Children = new List<CinchMenuItem>();
|
||||
}
|
||||
|
||||
public CinchMenuItem(string item)
|
||||
{
|
||||
Text = item;
|
||||
Children = new List<CinchMenuItem>();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
40
Util.DiagramDesigner/Controls/Connector.cs
Normal file
40
Util.DiagramDesigner/Controls/Connector.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public class Connector : Control
|
||||
{
|
||||
|
||||
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
|
||||
{
|
||||
base.OnMouseLeftButtonDown(e);
|
||||
DesignerCanvas canvas = GetDesignerCanvas(this);
|
||||
if (canvas != null)
|
||||
{
|
||||
canvas.SourceConnector = this;
|
||||
}
|
||||
}
|
||||
|
||||
public ConnectorOrientation Orientation { get; set; }
|
||||
|
||||
// iterate through visual tree to get parent DesignerCanvas
|
||||
private DesignerCanvas GetDesignerCanvas(DependencyObject element)
|
||||
{
|
||||
while (element != null && !(element is DesignerCanvas))
|
||||
element = VisualTreeHelper.GetParent(element);
|
||||
|
||||
return element as DesignerCanvas;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
470
Util.DiagramDesigner/Controls/DesignerCanvas.cs
Normal file
470
Util.DiagramDesigner/Controls/DesignerCanvas.cs
Normal file
@@ -0,0 +1,470 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Media;
|
||||
using System.Xml;
|
||||
using System.Linq;
|
||||
using System.Windows.Shapes;
|
||||
using System.Windows.Resources;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public class DesignerCanvas : Canvas
|
||||
{
|
||||
private IDiagramViewModel _viewModel { get { return DataContext as IDiagramViewModel; } }
|
||||
private IDiagramServiceProvider _service { get { return DiagramServicesProvider.Instance.Provider; } }
|
||||
|
||||
private ConnectorViewModel partialConnection;
|
||||
private List<Connector> connectorsHit = new List<Connector>();
|
||||
|
||||
private Point? rubberbandSelectionStartPoint = null;
|
||||
|
||||
#region GridCellSize
|
||||
|
||||
public static readonly DependencyProperty GridCellSizeProperty =
|
||||
DependencyProperty.Register("GridCellSize",
|
||||
typeof(Size),
|
||||
typeof(DesignerCanvas),
|
||||
new FrameworkPropertyMetadata(new Size(50, 50), FrameworkPropertyMetadataOptions.AffectsRender));
|
||||
|
||||
public Size GridCellSize
|
||||
{
|
||||
get { return (Size)GetValue(GridCellSizeProperty); }
|
||||
set { SetValue(GridCellSizeProperty, value); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ShowGrid
|
||||
|
||||
public static readonly DependencyProperty ShowGridProperty =
|
||||
DependencyProperty.Register("ShowGrid",
|
||||
typeof(bool),
|
||||
typeof(DesignerCanvas),
|
||||
new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender));
|
||||
|
||||
public bool ShowGrid
|
||||
{
|
||||
get { return (bool)GetValue(ShowGridProperty); }
|
||||
set { SetValue(ShowGridProperty, value); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region GridColor
|
||||
|
||||
public static readonly DependencyProperty GridColorProperty =
|
||||
DependencyProperty.Register("GridColor",
|
||||
typeof(Color),
|
||||
typeof(DesignerCanvas),
|
||||
new FrameworkPropertyMetadata(Colors.LightGray, FrameworkPropertyMetadataOptions.AffectsRender));
|
||||
|
||||
public Color GridColor
|
||||
{
|
||||
get { return (Color)GetValue(GridColorProperty); }
|
||||
set { SetValue(GridColorProperty, value); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region GridMargin 单位mm
|
||||
|
||||
public static readonly DependencyProperty GridMarginProperty =
|
||||
DependencyProperty.Register("GridMargin",
|
||||
typeof(double),
|
||||
typeof(DesignerCanvas),
|
||||
new FrameworkPropertyMetadata(28d, FrameworkPropertyMetadataOptions.AffectsRender));
|
||||
|
||||
public double GridMargin
|
||||
{
|
||||
get { return (double)GetValue(GridMarginProperty); }
|
||||
set { SetValue(GridMarginProperty, value); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public DesignerCanvas()
|
||||
{
|
||||
this.AllowDrop = true;
|
||||
Mediator.Instance.Register(this);
|
||||
|
||||
_service.PropertyChanged += _service_PropertyChanged;
|
||||
}
|
||||
|
||||
protected override void OnRender(DrawingContext dc)
|
||||
{
|
||||
var rect = new Rect(0, 0, RenderSize.Width, RenderSize.Height);
|
||||
dc.DrawRectangle(Background, null, rect);
|
||||
if (ShowGrid && GridCellSize.Width > 0 && GridCellSize.Height > 0)
|
||||
DrawGrid(dc, rect);
|
||||
}
|
||||
|
||||
protected virtual void DrawGrid(DrawingContext dc, Rect rect)
|
||||
{
|
||||
//using .5 forces wpf to draw a single pixel line
|
||||
for (var i = GridMargin + 0.5; i < rect.Height - GridMargin; i += GridCellSize.Height)
|
||||
dc.DrawLine(new Pen(new SolidColorBrush(GridColor), 1), new Point(GridMargin, i), new Point(rect.Width - GridMargin, i));
|
||||
dc.DrawLine(new Pen(new SolidColorBrush(GridColor), 1), new Point(GridMargin, rect.Height - GridMargin), new Point(rect.Width - GridMargin, rect.Height - GridMargin));
|
||||
|
||||
for (var i = GridMargin + 0.5; i < rect.Width - GridMargin; i += GridCellSize.Width)
|
||||
dc.DrawLine(new Pen(new SolidColorBrush(GridColor), 1), new Point(i, GridMargin), new Point(i, rect.Height - GridMargin));
|
||||
dc.DrawLine(new Pen(new SolidColorBrush(GridColor), 1), new Point(rect.Width - GridMargin, GridMargin), new Point(rect.Width - GridMargin, rect.Height - GridMargin));
|
||||
}
|
||||
|
||||
private void _service_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
{
|
||||
if (sender is IDrawModeViewModel)
|
||||
{
|
||||
if (e.PropertyName == nameof(CursorMode))
|
||||
{
|
||||
if (_service.DrawModeViewModel.CursorMode == CursorMode.Format)
|
||||
{
|
||||
EnterFormat();
|
||||
}
|
||||
else if (_service.DrawModeViewModel.CursorMode == CursorMode.Move)
|
||||
{
|
||||
EnterMove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Format/Move
|
||||
private void EnterFormat()
|
||||
{
|
||||
StreamResourceInfo sri = Application.GetResourceStream(new Uri("pack://application:,,,/Util.DiagramDesigner;component/Images/FormatPainter.cur", UriKind.RelativeOrAbsolute));
|
||||
this.Cursor = new Cursor(sri.Stream);
|
||||
foreach (SelectableDesignerItemViewModelBase item in _viewModel.Items)
|
||||
{
|
||||
item.IsHitTestVisible = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void EnterMove()
|
||||
{
|
||||
this.Cursor = Cursors.SizeAll;
|
||||
foreach (SelectableDesignerItemViewModelBase item in _viewModel.Items)
|
||||
{
|
||||
item.IsHitTestVisible = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void ExitCursor()
|
||||
{
|
||||
this.Cursor = Cursors.Arrow;
|
||||
foreach (SelectableDesignerItemViewModelBase item in _viewModel.Items)
|
||||
{
|
||||
item.IsHitTestVisible = true;
|
||||
}
|
||||
_service.DrawModeViewModel.CursorMode = CursorMode.Normal;
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void Format(SelectableDesignerItemViewModelBase source, SelectableDesignerItemViewModelBase target)
|
||||
{
|
||||
CopyHelper.CopyPropertyValue(source.ColorViewModel, target.ColorViewModel);
|
||||
CopyHelper.CopyPropertyValue(source.FontViewModel, target.FontViewModel);
|
||||
}
|
||||
|
||||
private Connector sourceConnector;
|
||||
public Connector SourceConnector
|
||||
{
|
||||
get { return sourceConnector; }
|
||||
set
|
||||
{
|
||||
if (sourceConnector != value)
|
||||
{
|
||||
sourceConnector = value;
|
||||
connectorsHit.Add(sourceConnector);
|
||||
FullyCreatedConnectorInfo sourceDataItem = sourceConnector.DataContext as FullyCreatedConnectorInfo;
|
||||
|
||||
|
||||
Rect rectangleBounds = sourceConnector.TransformToVisual(this).TransformBounds(new Rect(sourceConnector.RenderSize));
|
||||
Point point = new Point(rectangleBounds.Left + (rectangleBounds.Width / 2),
|
||||
rectangleBounds.Bottom + (rectangleBounds.Height / 2));
|
||||
partialConnection = new ConnectorViewModel(sourceDataItem, new PartCreatedConnectionInfo(point));
|
||||
_viewModel.DirectAddItemCommand.Execute(partialConnection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private FullyCreatedConnectorInfo sourceConnectorInfo;
|
||||
public FullyCreatedConnectorInfo SourceConnectorInfo
|
||||
{
|
||||
get { return sourceConnectorInfo; }
|
||||
set
|
||||
{
|
||||
if (sourceConnectorInfo != value)
|
||||
{
|
||||
sourceConnectorInfo = value;
|
||||
sourceConnector = new Connector() { Name = "占位" };//占位使用
|
||||
connectorsHit.Add(sourceConnector);
|
||||
|
||||
Rect rectangleBounds = new Rect(sourceConnectorInfo.DataItem.Left, sourceConnectorInfo.DataItem.Top, 3, 3);
|
||||
Point point = new Point(rectangleBounds.Left + (rectangleBounds.Width / 2),
|
||||
rectangleBounds.Bottom + (rectangleBounds.Height / 2));
|
||||
partialConnection = new ConnectorViewModel(sourceConnectorInfo, new PartCreatedConnectionInfo(point));
|
||||
_viewModel.DirectAddItemCommand.Execute(partialConnection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnMouseDown(MouseButtonEventArgs e)
|
||||
{
|
||||
base.OnMouseDown(e);
|
||||
|
||||
if (_service.DrawModeViewModel.CursorMode == CursorMode.Format)
|
||||
{
|
||||
var element = (e.OriginalSource as FrameworkElement);
|
||||
if (element.DataContext is SelectableDesignerItemViewModelBase target)
|
||||
{
|
||||
Format(_viewModel.SelectedItems.FirstOrDefault(), target);
|
||||
return;
|
||||
}
|
||||
|
||||
ExitCursor();
|
||||
}
|
||||
else if (_service.DrawModeViewModel.CursorMode == CursorMode.Move)
|
||||
{
|
||||
ExitCursor();
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.LeftButton == MouseButtonState.Pressed)
|
||||
{
|
||||
//if we are source of event, we are rubberband selecting
|
||||
if (e.Source == this)
|
||||
{
|
||||
// in case that this click is the start for a
|
||||
// drag operation we cache the start point
|
||||
rubberbandSelectionStartPoint = e.GetPosition(this);
|
||||
|
||||
IDiagramViewModel vm = (this.DataContext as IDiagramViewModel);
|
||||
if (!(Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)))
|
||||
{
|
||||
vm.ClearSelectedItemsCommand.Execute(null);
|
||||
|
||||
}
|
||||
e.Handled = true;
|
||||
|
||||
if (_service.DrawModeViewModel.GetDrawMode() == DrawMode.ConnectingLine)
|
||||
{
|
||||
if (connectorsHit.Count == 0)
|
||||
{
|
||||
LinkPointDesignerItemViewModel pointItemView = new LinkPointDesignerItemViewModel(rubberbandSelectionStartPoint.Value);
|
||||
_viewModel.DirectAddItemCommand.Execute(pointItemView);
|
||||
SourceConnectorInfo = pointItemView.TopConnector;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected override void OnMouseMove(MouseEventArgs e)
|
||||
{
|
||||
base.OnMouseMove(e);
|
||||
|
||||
Point currentPoint = e.GetPosition(this);
|
||||
_viewModel.CurrentPoint = currentPoint;
|
||||
var point = CursorPointManager.GetCursorPosition();
|
||||
_viewModel.CurrentColor = ColorPickerManager.GetColor(point.X, point.Y);
|
||||
|
||||
if (_service.DrawModeViewModel.CursorMode == CursorMode.Move)
|
||||
{
|
||||
_viewModel.SelectedItems.OfType<DesignerItemViewModelBase>().ToList().ForEach(p =>
|
||||
{
|
||||
p.Left = currentPoint.X;
|
||||
p.Top = currentPoint.Y;
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (SourceConnector != null)
|
||||
{
|
||||
if (e.LeftButton == MouseButtonState.Pressed)
|
||||
{
|
||||
partialConnection.SinkConnectorInfo = new PartCreatedConnectionInfo(currentPoint);
|
||||
HitTesting(currentPoint);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// if mouse button is not pressed we have no drag operation, ...
|
||||
if (e.LeftButton != MouseButtonState.Pressed && _service.DrawModeViewModel.GetDrawMode() != DrawMode.DirectLine)
|
||||
rubberbandSelectionStartPoint = null;
|
||||
|
||||
// ... but if mouse button is pressed and start
|
||||
// point value is set we do have one
|
||||
if (this.rubberbandSelectionStartPoint.HasValue)
|
||||
{
|
||||
// create rubberband adorner
|
||||
AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this);
|
||||
if (adornerLayer != null)
|
||||
{
|
||||
RubberbandAdorner adorner = new RubberbandAdorner(this, rubberbandSelectionStartPoint);
|
||||
if (adorner != null)
|
||||
{
|
||||
adornerLayer.Add(adorner);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
protected override void OnMouseUp(MouseButtonEventArgs e)
|
||||
{
|
||||
base.OnMouseUp(e);
|
||||
|
||||
if (_service.DrawModeViewModel.GetDrawMode() == DrawMode.DirectLine)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Mediator.Instance.NotifyColleagues<bool>("DoneDrawingMessage", true);
|
||||
|
||||
if (sourceConnector != null)
|
||||
{
|
||||
FullyCreatedConnectorInfo sourceDataItem = sourceConnectorInfo ?? (sourceConnector.DataContext as FullyCreatedConnectorInfo);
|
||||
if (connectorsHit.Count() == 2)
|
||||
{
|
||||
Connector sinkConnector = connectorsHit.Last();
|
||||
FullyCreatedConnectorInfo sinkDataItem = sinkConnector.DataContext as FullyCreatedConnectorInfo;
|
||||
|
||||
int indexOfLastTempConnection = sinkDataItem.DataItem.Parent.Items.Count - 1;
|
||||
sinkDataItem.DataItem.Parent.DirectRemoveItemCommand.Execute(
|
||||
sinkDataItem.DataItem.Parent.Items[indexOfLastTempConnection]);
|
||||
sinkDataItem.DataItem.Parent.AddItemCommand.Execute(new ConnectorViewModel(sourceDataItem, sinkDataItem));
|
||||
}
|
||||
else if (_service.DrawModeViewModel.GetDrawMode() == DrawMode.ConnectingLine && connectorsHit.Count() == 1)
|
||||
{
|
||||
LinkPointDesignerItemViewModel pointItemView = new LinkPointDesignerItemViewModel(e.GetPosition(this));
|
||||
FullyCreatedConnectorInfo sinkDataItem = pointItemView.TopConnector;
|
||||
|
||||
int indexOfLastTempConnection = _viewModel.Items.Count - 1;
|
||||
_viewModel.DirectRemoveItemCommand.Execute(_viewModel.Items[indexOfLastTempConnection]);
|
||||
_viewModel.DirectAddItemCommand.Execute(pointItemView);
|
||||
|
||||
var connector = new ConnectorViewModel(sourceDataItem, sinkDataItem);
|
||||
_viewModel.AddItemCommand.Execute(connector);
|
||||
|
||||
sourceDataItem.DataItem.ZIndex++;
|
||||
connector.ZIndex--;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Need to remove last item as we did not finish drawing the path
|
||||
int indexOfLastTempConnection = sourceDataItem.DataItem.Parent.Items.Count - 1;
|
||||
sourceDataItem.DataItem.Parent.DirectRemoveItemCommand.Execute(
|
||||
sourceDataItem.DataItem.Parent.Items[indexOfLastTempConnection]);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
connectorsHit = new List<Connector>();
|
||||
sourceConnector = null;
|
||||
sourceConnectorInfo = null;
|
||||
|
||||
_service.DrawModeViewModel.ResetDrawMode();
|
||||
}
|
||||
|
||||
protected override Size MeasureOverride(Size constraint)
|
||||
{
|
||||
Size size = new Size();
|
||||
foreach (UIElement element in this.InternalChildren)
|
||||
{
|
||||
double left = Canvas.GetLeft(element);
|
||||
double top = Canvas.GetTop(element);
|
||||
left = double.IsNaN(left) ? 0 : left;
|
||||
top = double.IsNaN(top) ? 0 : top;
|
||||
|
||||
//measure desired size for each child
|
||||
element.Measure(constraint);
|
||||
|
||||
Size desiredSize = element.DesiredSize;
|
||||
if (!double.IsNaN(desiredSize.Width) && !double.IsNaN(desiredSize.Height))
|
||||
{
|
||||
size.Width = Math.Max(size.Width, left + desiredSize.Width);
|
||||
size.Height = Math.Max(size.Height, top + desiredSize.Height);
|
||||
}
|
||||
}
|
||||
// add margin
|
||||
size.Width += 10;
|
||||
size.Height += 10;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
private void HitTesting(Point hitPoint)
|
||||
{
|
||||
DependencyObject hitObject = this.InputHitTest(hitPoint) as DependencyObject;
|
||||
while (hitObject != null &&
|
||||
hitObject.GetType() != typeof(DesignerCanvas))
|
||||
{
|
||||
if (hitObject is Connector)
|
||||
{
|
||||
if (connectorsHit.Any(p => p.Name == "占位"))
|
||||
{
|
||||
connectorsHit.Remove(connectorsHit.FirstOrDefault(p => p.Name == "占位"));
|
||||
}
|
||||
if (!connectorsHit.Contains(hitObject as Connector))
|
||||
connectorsHit.Add(hitObject as Connector);
|
||||
}
|
||||
hitObject = VisualTreeHelper.GetParent(hitObject);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected override void OnDrop(DragEventArgs e)
|
||||
{
|
||||
base.OnDrop(e);
|
||||
DragObject dragObject = e.Data.GetData(typeof(DragObject)) as DragObject;
|
||||
if (dragObject != null)
|
||||
{
|
||||
(DataContext as IDiagramViewModel).ClearSelectedItemsCommand.Execute(null);
|
||||
Point position = e.GetPosition(this);
|
||||
DesignerItemViewModelBase itemBase = null;
|
||||
if (dragObject.DesignerItem != null)
|
||||
{
|
||||
itemBase = (DesignerItemViewModelBase)Activator.CreateInstance(dragObject.ContentType, null, dragObject.DesignerItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
itemBase = (DesignerItemViewModelBase)Activator.CreateInstance(dragObject.ContentType);
|
||||
itemBase.Icon = dragObject.Icon;
|
||||
itemBase.ColorViewModel = CopyHelper.Mapper(dragObject.ColorViewModel);
|
||||
}
|
||||
itemBase.Left = Math.Max(0, position.X - itemBase.ItemWidth / 2);
|
||||
itemBase.Top = Math.Max(0, position.Y - itemBase.ItemHeight / 2);
|
||||
(DataContext as IDiagramViewModel).AddItemCommand.Execute(itemBase);
|
||||
}
|
||||
var dragFile = e.Data.GetData(DataFormats.FileDrop);
|
||||
if (dragFile != null && dragFile is string[] files)
|
||||
{
|
||||
foreach (var file in files)
|
||||
{
|
||||
(DataContext as IDiagramViewModel).ClearSelectedItemsCommand.Execute(null);
|
||||
Point position = e.GetPosition(this);
|
||||
ImageItemViewModel itemBase = new ImageItemViewModel();
|
||||
itemBase.Icon = file;
|
||||
itemBase.Suffix = System.IO.Path.GetExtension(itemBase.Icon).ToLower();
|
||||
itemBase.InitWidthAndHeight();
|
||||
itemBase.AutoSize();
|
||||
|
||||
itemBase.Left = Math.Max(0, position.X - itemBase.ItemWidth / 2);
|
||||
itemBase.Top = Math.Max(0, position.Y - itemBase.ItemHeight / 2);
|
||||
(DataContext as IDiagramViewModel).AddItemCommand.Execute(itemBase);
|
||||
}
|
||||
}
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
111
Util.DiagramDesigner/Controls/DragThumb.cs
Normal file
111
Util.DiagramDesigner/Controls/DragThumb.cs
Normal file
@@ -0,0 +1,111 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Util.DiagramDesigner.Controls
|
||||
{
|
||||
public class DragThumb : Thumb
|
||||
{
|
||||
public DragThumb()
|
||||
{
|
||||
base.DragDelta += new DragDeltaEventHandler(DragThumb_DragDelta);
|
||||
base.DragStarted += DragThumb_DragStarted;
|
||||
base.DragCompleted += DragThumb_DragCompleted;
|
||||
}
|
||||
|
||||
private List<SelectableDesignerItemViewModelBase> designerItems;
|
||||
|
||||
private void DragThumb_DragStarted(object sender, DragStartedEventArgs e)
|
||||
{
|
||||
SelectableDesignerItemViewModelBase designerItem = this.DataContext as SelectableDesignerItemViewModelBase;
|
||||
|
||||
if (designerItem != null && designerItem.IsSelected)
|
||||
{
|
||||
// we only move DesignerItems
|
||||
designerItems = designerItem.SelectedItems.ToList();
|
||||
if (designerItem is ConnectorViewModel connector)
|
||||
{
|
||||
designerItems.Add(connector.SourceConnectorInfo.DataItem);
|
||||
designerItems.Add((connector.SinkConnectorInfo as FullyCreatedConnectorInfo).DataItem);
|
||||
|
||||
if (designerItem.OutTextItem != null)
|
||||
{
|
||||
designerItems.Remove(designerItem.OutTextItem);//这个自动计算位置
|
||||
}
|
||||
}
|
||||
|
||||
if (designerItem is PointDesignerItemViewModel)
|
||||
{
|
||||
designerItems = new List<SelectableDesignerItemViewModelBase> { designerItem };
|
||||
}
|
||||
|
||||
foreach (DesignerItemViewModelBase item in designerItems.OfType<DesignerItemViewModelBase>())
|
||||
{
|
||||
item.BeginDo = true;
|
||||
item.SetOldValue(item.Left, nameof(item.Left));
|
||||
item.SetOldValue(item.Top, nameof(item.Top));
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
designerItems = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void DragThumb_DragCompleted(object sender, DragCompletedEventArgs e)
|
||||
{
|
||||
if (designerItems != null)
|
||||
{
|
||||
foreach (DesignerItemViewModelBase item in designerItems.OfType<DesignerItemViewModelBase>())
|
||||
{
|
||||
item.SetCellAlignment();
|
||||
item.BeginDo = false;
|
||||
item.RaiseTopLeft();
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
void DragThumb_DragDelta(object sender, DragDeltaEventArgs e)
|
||||
{
|
||||
if (designerItems != null)
|
||||
{
|
||||
double minLeft = double.MaxValue;
|
||||
double minTop = double.MaxValue;
|
||||
|
||||
foreach (DesignerItemViewModelBase item in designerItems.OfType<DesignerItemViewModelBase>())
|
||||
{
|
||||
double left = item.Left;
|
||||
double top = item.Top;
|
||||
minLeft = double.IsNaN(left) ? 0 : Math.Min(left, minLeft);
|
||||
minTop = double.IsNaN(top) ? 0 : Math.Min(top, minTop);
|
||||
|
||||
double deltaHorizontal = Math.Max(-minLeft, e.HorizontalChange);
|
||||
double deltaVertical = Math.Max(-minTop, e.VerticalChange);
|
||||
item.Left += deltaHorizontal;
|
||||
item.Top += deltaVertical;
|
||||
}
|
||||
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private DesignerCanvas GetDesignerCanvas(DependencyObject element)
|
||||
{
|
||||
while (element != null && !(element is DesignerCanvas))
|
||||
element = VisualTreeHelper.GetParent(element);
|
||||
|
||||
return element as DesignerCanvas;
|
||||
}
|
||||
}
|
||||
}
|
||||
20
Util.DiagramDesigner/Controls/PointConnector.cs
Normal file
20
Util.DiagramDesigner/Controls/PointConnector.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public class PointConnector : Control
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
85
Util.DiagramDesigner/Controls/RelativePositionPanel.cs
Normal file
85
Util.DiagramDesigner/Controls/RelativePositionPanel.cs
Normal file
@@ -0,0 +1,85 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public class RelativePositionPanel : Panel
|
||||
{
|
||||
public static readonly DependencyProperty RelativePositionProperty =
|
||||
DependencyProperty.RegisterAttached("RelativePosition", typeof(Point), typeof(RelativePositionPanel),
|
||||
new FrameworkPropertyMetadata(new Point(0, 0),
|
||||
new PropertyChangedCallback(RelativePositionPanel.OnRelativePositionChanged)));
|
||||
|
||||
public static Point GetRelativePosition(UIElement element)
|
||||
{
|
||||
if (element == null)
|
||||
{
|
||||
throw new ArgumentNullException("element");
|
||||
}
|
||||
return (Point)element.GetValue(RelativePositionProperty);
|
||||
}
|
||||
|
||||
public static void SetRelativePosition(UIElement element, Point value)
|
||||
{
|
||||
if (element == null)
|
||||
{
|
||||
throw new ArgumentNullException("element");
|
||||
}
|
||||
element.SetValue(RelativePositionProperty, value);
|
||||
}
|
||||
|
||||
private static void OnRelativePositionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
UIElement reference = d as UIElement;
|
||||
if (reference != null)
|
||||
{
|
||||
RelativePositionPanel parent = VisualTreeHelper.GetParent(reference) as RelativePositionPanel;
|
||||
if (parent != null)
|
||||
{
|
||||
parent.InvalidateArrange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override Size ArrangeOverride(Size arrangeSize)
|
||||
{
|
||||
foreach (UIElement element in base.InternalChildren)
|
||||
{
|
||||
if (element != null)
|
||||
{
|
||||
Point relPosition = GetRelativePosition(element);
|
||||
double x = (arrangeSize.Width - element.DesiredSize.Width) * relPosition.X;
|
||||
double y = (arrangeSize.Height - element.DesiredSize.Height) * relPosition.Y;
|
||||
|
||||
if (double.IsNaN(x)) x = 0;
|
||||
if (double.IsNaN(y)) y = 0;
|
||||
|
||||
element.Arrange(new Rect(new Point(x, y), element.DesiredSize));
|
||||
}
|
||||
}
|
||||
return arrangeSize;
|
||||
}
|
||||
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
Size size = new Size(double.PositiveInfinity, double.PositiveInfinity);
|
||||
|
||||
// SDK docu says about InternalChildren Property: 'Classes that are derived from Panel
|
||||
// should use this property, instead of the Children property, for internal overrides
|
||||
// such as MeasureCore and ArrangeCore.
|
||||
|
||||
foreach (UIElement element in this.InternalChildren)
|
||||
{
|
||||
if (element != null)
|
||||
element.Measure(size);
|
||||
}
|
||||
|
||||
return base.MeasureOverride(availableSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
196
Util.DiagramDesigner/Controls/ResizeThumb.cs
Normal file
196
Util.DiagramDesigner/Controls/ResizeThumb.cs
Normal file
@@ -0,0 +1,196 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Util.DiagramDesigner.Controls
|
||||
{
|
||||
public class ResizeThumb : Thumb
|
||||
{
|
||||
public ResizeThumb()
|
||||
{
|
||||
base.DragDelta += new DragDeltaEventHandler(ResizeThumb_DragDelta);
|
||||
base.DragStarted += ResizeThumb_DragStarted;
|
||||
base.DragCompleted += ResizeThumb_DragCompleted;
|
||||
}
|
||||
|
||||
private List<SelectableDesignerItemViewModelBase> designerItems;
|
||||
IDiagramViewModel diagarmViewModel;
|
||||
|
||||
private void ResizeThumb_DragStarted(object sender, DragStartedEventArgs e)
|
||||
{
|
||||
DesignerItemViewModelBase designerItem = this.DataContext as DesignerItemViewModelBase;
|
||||
diagarmViewModel = designerItem.Parent;
|
||||
if (designerItem != null && designerItem.IsSelected)
|
||||
{
|
||||
designerItems = designerItem.SelectedItems.ToList();
|
||||
foreach (DesignerItemViewModelBase item in designerItems.OfType<DesignerItemViewModelBase>())
|
||||
{
|
||||
item.BeginDo = true;
|
||||
item.SetOldValue(item.ItemWidth, nameof(item.ItemWidth));
|
||||
item.SetOldValue(item.ItemHeight, nameof(item.ItemHeight));
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
designerItems = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void ResizeThumb_DragCompleted(object sender, DragCompletedEventArgs e)
|
||||
{
|
||||
if (designerItems != null)
|
||||
{
|
||||
foreach (DesignerItemViewModelBase item in designerItems.OfType<DesignerItemViewModelBase>())
|
||||
{
|
||||
item.BeginDo = false;
|
||||
item.RaiseItemWidthHeight();
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ResizeThumb_DragDelta(object sender, DragDeltaEventArgs e)
|
||||
{
|
||||
if (designerItems != null)
|
||||
{
|
||||
double minLeft, minTop, minDeltaHorizontal, minDeltaVertical;
|
||||
double dragDeltaVertical, dragDeltaHorizontal, scale;
|
||||
|
||||
CalculateDragLimits(designerItems.OfType<DesignerItemViewModelBase>(), out minLeft, out minTop,
|
||||
out minDeltaHorizontal, out minDeltaVertical);
|
||||
|
||||
foreach (DesignerItemViewModelBase item in designerItems.OfType<DesignerItemViewModelBase>())
|
||||
{
|
||||
if (item != null && item.ParentId == Guid.Empty)
|
||||
{
|
||||
switch (base.VerticalAlignment)
|
||||
{
|
||||
case VerticalAlignment.Bottom:
|
||||
dragDeltaVertical = Math.Min(-e.VerticalChange, minDeltaVertical);
|
||||
scale = (item.ItemHeight - dragDeltaVertical) / item.ItemHeight;
|
||||
DragBottom(scale, item, diagarmViewModel.SelectionService);
|
||||
break;
|
||||
case VerticalAlignment.Top:
|
||||
double top = item.Top;
|
||||
dragDeltaVertical = Math.Min(Math.Max(-minTop, e.VerticalChange), minDeltaVertical);
|
||||
scale = (item.ItemHeight - dragDeltaVertical) / item.ItemHeight;
|
||||
DragTop(scale, item, diagarmViewModel.SelectionService);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (base.HorizontalAlignment)
|
||||
{
|
||||
case HorizontalAlignment.Left:
|
||||
double left = item.Left;
|
||||
dragDeltaHorizontal = Math.Min(Math.Max(-minLeft, e.HorizontalChange), minDeltaHorizontal);
|
||||
scale = (item.ItemWidth - dragDeltaHorizontal) / item.ItemWidth;
|
||||
DragLeft(scale, item, diagarmViewModel.SelectionService);
|
||||
break;
|
||||
case HorizontalAlignment.Right:
|
||||
dragDeltaHorizontal = Math.Min(-e.HorizontalChange, minDeltaHorizontal);
|
||||
scale = (item.ItemWidth - dragDeltaHorizontal) / item.ItemWidth;
|
||||
DragRight(scale, item, diagarmViewModel.SelectionService);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
#region Helper methods
|
||||
|
||||
private void DragLeft(double scale, DesignerItemViewModelBase item, SelectionService selectionService)
|
||||
{
|
||||
IEnumerable<DesignerItemViewModelBase> groupItems = selectionService.GetGroupMembers(item).Cast<DesignerItemViewModelBase>();
|
||||
|
||||
double groupLeft = item.Left + item.ItemWidth;
|
||||
foreach (DesignerItemViewModelBase groupItem in groupItems)
|
||||
{
|
||||
double groupItemLeft = groupItem.Left;
|
||||
double delta = (groupLeft - groupItemLeft) * (scale - 1);
|
||||
groupItem.Left = groupItemLeft - delta;
|
||||
groupItem.ItemWidth = groupItem.ItemWidth * scale;
|
||||
}
|
||||
}
|
||||
|
||||
private void DragTop(double scale, DesignerItemViewModelBase item, SelectionService selectionService)
|
||||
{
|
||||
IEnumerable<DesignerItemViewModelBase> groupItems = selectionService.GetGroupMembers(item).Cast<DesignerItemViewModelBase>();
|
||||
double groupBottom = item.Top + item.ItemHeight;
|
||||
foreach (DesignerItemViewModelBase groupItem in groupItems)
|
||||
{
|
||||
double groupItemTop = groupItem.Top;
|
||||
double delta = (groupBottom - groupItemTop) * (scale - 1);
|
||||
groupItem.Top = groupItemTop - delta;
|
||||
groupItem.ItemHeight = groupItem.ItemHeight * scale;
|
||||
}
|
||||
}
|
||||
|
||||
private void DragRight(double scale, DesignerItemViewModelBase item, SelectionService selectionService)
|
||||
{
|
||||
IEnumerable<DesignerItemViewModelBase> groupItems = selectionService.GetGroupMembers(item).Cast<DesignerItemViewModelBase>();
|
||||
|
||||
double groupLeft = item.Left;
|
||||
foreach (DesignerItemViewModelBase groupItem in groupItems)
|
||||
{
|
||||
double groupItemLeft = groupItem.Left;
|
||||
double delta = (groupItemLeft - groupLeft) * (scale - 1);
|
||||
|
||||
groupItem.Left = groupItemLeft + delta;
|
||||
groupItem.ItemWidth = groupItem.ItemWidth * scale;
|
||||
}
|
||||
}
|
||||
|
||||
private void DragBottom(double scale, DesignerItemViewModelBase item, SelectionService selectionService)
|
||||
{
|
||||
IEnumerable<DesignerItemViewModelBase> groupItems = selectionService.GetGroupMembers(item).Cast<DesignerItemViewModelBase>();
|
||||
double groupTop = item.Top;
|
||||
foreach (DesignerItemViewModelBase groupItem in groupItems)
|
||||
{
|
||||
double groupItemTop = groupItem.Top;
|
||||
double delta = (groupItemTop - groupTop) * (scale - 1);
|
||||
|
||||
groupItem.Top = groupItemTop + delta;
|
||||
groupItem.ItemHeight = groupItem.ItemHeight * scale;
|
||||
}
|
||||
}
|
||||
|
||||
private void CalculateDragLimits(IEnumerable<DesignerItemViewModelBase> selectedItems, out double minLeft, out double minTop, out double minDeltaHorizontal, out double minDeltaVertical)
|
||||
{
|
||||
minLeft = double.MaxValue;
|
||||
minTop = double.MaxValue;
|
||||
minDeltaHorizontal = double.MaxValue;
|
||||
minDeltaVertical = double.MaxValue;
|
||||
|
||||
// drag limits are set by these parameters: canvas top, canvas left, minHeight, minWidth
|
||||
// calculate min value for each parameter for each item
|
||||
foreach (DesignerItemViewModelBase item in selectedItems)
|
||||
{
|
||||
double left = item.Left;
|
||||
double top = item.Top;
|
||||
|
||||
minLeft = double.IsNaN(left) ? 0 : Math.Min(left, minLeft);
|
||||
minTop = double.IsNaN(top) ? 0 : Math.Min(top, minTop);
|
||||
|
||||
minDeltaVertical = Math.Min(minDeltaVertical, 10);
|
||||
minDeltaHorizontal = Math.Min(minDeltaHorizontal, 10);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
106
Util.DiagramDesigner/Controls/RotateThumb.cs
Normal file
106
Util.DiagramDesigner/Controls/RotateThumb.cs
Normal file
@@ -0,0 +1,106 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Util.DiagramDesigner.Controls
|
||||
{
|
||||
public class RotateThumb : Thumb
|
||||
{
|
||||
private Point centerPoint;
|
||||
private Vector startVector;
|
||||
private double initialAngle;
|
||||
private Canvas designerCanvas;
|
||||
private DesignerItemViewModelBase designerItem;
|
||||
private RotateTransform rotateTransform;
|
||||
|
||||
public RotateThumb()
|
||||
{
|
||||
DragDelta += RotateThumb_DragDelta;
|
||||
DragStarted += RotateThumb_DragStarted;
|
||||
DragCompleted += RotateThumb_DragCompleted;
|
||||
}
|
||||
|
||||
private List<SelectableDesignerItemViewModelBase> designerItems;
|
||||
|
||||
private void RotateThumb_DragStarted(object sender, DragStartedEventArgs e)
|
||||
{
|
||||
this.designerItem = this.DataContext as DesignerItemViewModelBase;
|
||||
|
||||
if (this.designerItem != null)
|
||||
{
|
||||
designerItems = designerItem.SelectedItems.ToList();
|
||||
|
||||
foreach (DesignerItemViewModelBase item in designerItems.OfType<DesignerItemViewModelBase>())
|
||||
{
|
||||
item.BeginDo = true;
|
||||
item.SetOldValue(this.designerItem.Angle, nameof(this.designerItem.Angle));
|
||||
}
|
||||
|
||||
this.designerCanvas = GetDesignerCanvas(this);
|
||||
if (this.designerCanvas != null)
|
||||
{
|
||||
this.centerPoint =
|
||||
new Point(this.designerItem.Left + this.designerItem.ItemWidth * 0.5,
|
||||
this.designerItem.Top + this.designerItem.ItemHeight * 0.5);
|
||||
|
||||
Point startPoint = Mouse.GetPosition(this.designerCanvas);
|
||||
this.startVector = Point.Subtract(startPoint, this.centerPoint);
|
||||
|
||||
|
||||
this.initialAngle = this.designerItem.Angle;
|
||||
}
|
||||
e.Handled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
designerItems = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void RotateThumb_DragCompleted(object sender, DragCompletedEventArgs e)
|
||||
{
|
||||
this.designerItem = this.DataContext as DesignerItemViewModelBase;
|
||||
|
||||
if (this.designerItems != null)
|
||||
{
|
||||
foreach (DesignerItemViewModelBase item in designerItems.OfType<DesignerItemViewModelBase>())
|
||||
{
|
||||
item.BeginDo = false;
|
||||
item.RaiseAngle();
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void RotateThumb_DragDelta(object sender, DragDeltaEventArgs e)
|
||||
{
|
||||
if (this.designerItems != null && this.designerCanvas != null)
|
||||
{
|
||||
Point currentPoint = Mouse.GetPosition(this.designerCanvas);
|
||||
Vector deltaVector = Point.Subtract(currentPoint, this.centerPoint);
|
||||
|
||||
double angle = Vector.AngleBetween(this.startVector, deltaVector);
|
||||
|
||||
foreach (DesignerItemViewModelBase item in designerItems.OfType<DesignerItemViewModelBase>())
|
||||
{
|
||||
item.Angle = this.initialAngle + Math.Round(angle, 0);
|
||||
}
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private DesignerCanvas GetDesignerCanvas(DependencyObject element)
|
||||
{
|
||||
while (element != null && !(element is DesignerCanvas))
|
||||
element = VisualTreeHelper.GetParent(element);
|
||||
|
||||
return element as DesignerCanvas;
|
||||
}
|
||||
}
|
||||
}
|
||||
162
Util.DiagramDesigner/Controls/ZoomBox.cs
Normal file
162
Util.DiagramDesigner/Controls/ZoomBox.cs
Normal file
@@ -0,0 +1,162 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public class ZoomBox : Control
|
||||
{
|
||||
private Thumb zoomThumb;
|
||||
private Canvas zoomCanvas;
|
||||
private Slider zoomSlider;
|
||||
private ScaleTransform scaleTransform;
|
||||
|
||||
#region DPs
|
||||
|
||||
#region ScrollViewer
|
||||
public ScrollViewer ScrollViewer
|
||||
{
|
||||
get { return (ScrollViewer)GetValue(ScrollViewerProperty); }
|
||||
set { SetValue(ScrollViewerProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty ScrollViewerProperty =
|
||||
DependencyProperty.Register("ScrollViewer", typeof(ScrollViewer), typeof(ZoomBox));
|
||||
#endregion
|
||||
|
||||
#region DesignerCanvas
|
||||
|
||||
|
||||
public static readonly DependencyProperty DesignerCanvasProperty =
|
||||
DependencyProperty.Register("DesignerCanvas", typeof(DesignerCanvas), typeof(ZoomBox),
|
||||
new FrameworkPropertyMetadata(null,
|
||||
new PropertyChangedCallback(OnDesignerCanvasChanged)));
|
||||
|
||||
|
||||
public DesignerCanvas DesignerCanvas
|
||||
{
|
||||
get { return (DesignerCanvas)GetValue(DesignerCanvasProperty); }
|
||||
set { SetValue(DesignerCanvasProperty, value); }
|
||||
}
|
||||
|
||||
|
||||
private static void OnDesignerCanvasChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
ZoomBox target = (ZoomBox)d;
|
||||
DesignerCanvas oldDesignerCanvas = (DesignerCanvas)e.OldValue;
|
||||
DesignerCanvas newDesignerCanvas = target.DesignerCanvas;
|
||||
target.OnDesignerCanvasChanged(oldDesignerCanvas, newDesignerCanvas);
|
||||
}
|
||||
|
||||
|
||||
protected virtual void OnDesignerCanvasChanged(DesignerCanvas oldDesignerCanvas, DesignerCanvas newDesignerCanvas)
|
||||
{
|
||||
if (oldDesignerCanvas != null)
|
||||
{
|
||||
newDesignerCanvas.LayoutUpdated -= new EventHandler(this.DesignerCanvas_LayoutUpdated);
|
||||
newDesignerCanvas.MouseWheel -= new MouseWheelEventHandler(this.DesignerCanvas_MouseWheel);
|
||||
}
|
||||
|
||||
if (newDesignerCanvas != null)
|
||||
{
|
||||
newDesignerCanvas.LayoutUpdated += new EventHandler(this.DesignerCanvas_LayoutUpdated);
|
||||
newDesignerCanvas.MouseWheel += new MouseWheelEventHandler(this.DesignerCanvas_MouseWheel);
|
||||
newDesignerCanvas.LayoutTransform = this.scaleTransform;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
|
||||
if (this.ScrollViewer == null)
|
||||
return;
|
||||
|
||||
this.zoomThumb = Template.FindName("PART_ZoomThumb", this) as Thumb;
|
||||
if (this.zoomThumb == null)
|
||||
throw new Exception("PART_ZoomThumb template is missing!");
|
||||
|
||||
this.zoomCanvas = Template.FindName("PART_ZoomCanvas", this) as Canvas;
|
||||
if (this.zoomCanvas == null)
|
||||
throw new Exception("PART_ZoomCanvas template is missing!");
|
||||
|
||||
this.zoomSlider = Template.FindName("PART_ZoomSlider", this) as Slider;
|
||||
if (this.zoomSlider == null)
|
||||
throw new Exception("PART_ZoomSlider template is missing!");
|
||||
|
||||
this.zoomThumb.DragDelta += new DragDeltaEventHandler(this.Thumb_DragDelta);
|
||||
this.zoomSlider.ValueChanged += new RoutedPropertyChangedEventHandler<double>(this.ZoomSlider_ValueChanged);
|
||||
this.scaleTransform = new ScaleTransform();
|
||||
}
|
||||
|
||||
private void ZoomSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
|
||||
{
|
||||
double scale = e.NewValue / e.OldValue;
|
||||
double halfViewportHeight = this.ScrollViewer.ViewportHeight / 2;
|
||||
double newVerticalOffset = ((this.ScrollViewer.VerticalOffset + halfViewportHeight) * scale - halfViewportHeight);
|
||||
double halfViewportWidth = this.ScrollViewer.ViewportWidth / 2;
|
||||
double newHorizontalOffset = ((this.ScrollViewer.HorizontalOffset + halfViewportWidth) * scale - halfViewportWidth);
|
||||
this.scaleTransform.ScaleX *= scale;
|
||||
this.scaleTransform.ScaleY *= scale;
|
||||
this.ScrollViewer.ScrollToHorizontalOffset(newHorizontalOffset);
|
||||
this.ScrollViewer.ScrollToVerticalOffset(newVerticalOffset);
|
||||
}
|
||||
|
||||
private void Thumb_DragDelta(object sender, DragDeltaEventArgs e)
|
||||
{
|
||||
double scale, xOffset, yOffset;
|
||||
this.InvalidateScale(out scale, out xOffset, out yOffset);
|
||||
this.ScrollViewer.ScrollToHorizontalOffset(this.ScrollViewer.HorizontalOffset + e.HorizontalChange / scale);
|
||||
this.ScrollViewer.ScrollToVerticalOffset(this.ScrollViewer.VerticalOffset + e.VerticalChange / scale);
|
||||
}
|
||||
|
||||
private void DesignerCanvas_LayoutUpdated(object sender, EventArgs e)
|
||||
{
|
||||
//htzk
|
||||
try
|
||||
{
|
||||
|
||||
double scale, xOffset, yOffset;
|
||||
this.InvalidateScale(out scale, out xOffset, out yOffset);
|
||||
this.zoomThumb.Width = this.ScrollViewer.ViewportWidth * scale;
|
||||
this.zoomThumb.Height = this.ScrollViewer.ViewportHeight * scale;
|
||||
Canvas.SetLeft(this.zoomThumb, xOffset + this.ScrollViewer.HorizontalOffset * scale);
|
||||
Canvas.SetTop(this.zoomThumb, yOffset + this.ScrollViewer.VerticalOffset * scale);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
private void DesignerCanvas_MouseWheel(object sender, EventArgs e)
|
||||
{
|
||||
MouseWheelEventArgs wheel = (MouseWheelEventArgs)e;
|
||||
|
||||
//divide the value by 10 so that it is more smooth
|
||||
double value = Math.Max(0, wheel.Delta / 10);
|
||||
value = Math.Min(wheel.Delta, 10);
|
||||
this.zoomSlider.Value += value;
|
||||
}
|
||||
|
||||
private void InvalidateScale(out double scale, out double xOffset, out double yOffset)
|
||||
{
|
||||
double w = DesignerCanvas.ActualWidth * this.scaleTransform.ScaleX;
|
||||
double h = DesignerCanvas.ActualHeight * this.scaleTransform.ScaleY;
|
||||
|
||||
// zoom canvas size
|
||||
double x = this.zoomCanvas.ActualWidth;
|
||||
double y = this.zoomCanvas.ActualHeight;
|
||||
double scaleX = x / w;
|
||||
double scaleY = y / h;
|
||||
scale = (scaleX < scaleY) ? scaleX : scaleY;
|
||||
xOffset = (x - scale * w) / 2;
|
||||
yOffset = (y - scale * h) / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
24
Util.DiagramDesigner/Converters/ArrowPathConverter.cs
Normal file
24
Util.DiagramDesigner/Converters/ArrowPathConverter.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
|
||||
public class ArrowPathConverter : IValueConverter
|
||||
{
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
if (value is ArrowPathStyle arrowStyle)
|
||||
{
|
||||
return ArrowPathData.Arrow[(int)arrowStyle];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
23
Util.DiagramDesigner/Converters/ArrowSizeConverter.cs
Normal file
23
Util.DiagramDesigner/Converters/ArrowSizeConverter.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public class ArrowSizeConverter : IValueConverter
|
||||
{
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
if (value is ArrowSizeStyle arrowStyle)
|
||||
{
|
||||
return (int)arrowStyle;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
42
Util.DiagramDesigner/Converters/BoolToVisibilityConverter.cs
Normal file
42
Util.DiagramDesigner/Converters/BoolToVisibilityConverter.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
[ValueConversion(typeof(bool), typeof(Visibility))]
|
||||
public class BoolToVisibilityConverter : IValueConverter
|
||||
{
|
||||
static BoolToVisibilityConverter()
|
||||
{
|
||||
Instance = new BoolToVisibilityConverter();
|
||||
}
|
||||
|
||||
public static BoolToVisibilityConverter Instance
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
return ((bool)value) ? Visibility.Visible : Visibility.Collapsed;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
78
Util.DiagramDesigner/Converters/ClipConverter.cs
Normal file
78
Util.DiagramDesigner/Converters/ClipConverter.cs
Normal file
@@ -0,0 +1,78 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public class ClipConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
string para = parameter?.ToString();
|
||||
try
|
||||
{
|
||||
if (value is ImageItemViewModel imageItemViewModel)
|
||||
{
|
||||
double xradio = imageItemViewModel.ItemWidth / imageItemViewModel.ImageWidth;
|
||||
double yradio = imageItemViewModel.ItemHeight / imageItemViewModel.ImageHeight;
|
||||
if (para == "Clip")
|
||||
{
|
||||
if (imageItemViewModel.ClipMode == ClipMode.RectangleGeometry)
|
||||
{
|
||||
RectangleGeometry rectangle = new RectangleGeometry();
|
||||
if (imageItemViewModel.ResizeMode == false)
|
||||
{
|
||||
rectangle.Rect = new System.Windows.Rect(imageItemViewModel.ResizeMargin.Left * xradio, imageItemViewModel.ResizeMargin.Top * yradio, imageItemViewModel.ItemWidth, imageItemViewModel.ItemHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
rectangle.Rect = new System.Windows.Rect(imageItemViewModel.ResizeMargin.Left, imageItemViewModel.ResizeMargin.Top , imageItemViewModel.ItemWidth - (imageItemViewModel.ResizeMargin.Left + imageItemViewModel.ResizeMargin.Right), imageItemViewModel.ItemHeight - (imageItemViewModel.ResizeMargin.Top + imageItemViewModel.ResizeMargin.Bottom));
|
||||
}
|
||||
return rectangle;
|
||||
}
|
||||
else if (imageItemViewModel.ClipMode == ClipMode.EllipseGeometry)
|
||||
{
|
||||
EllipseGeometry ellipse = new EllipseGeometry();
|
||||
if (imageItemViewModel.ResizeMode == false)
|
||||
{
|
||||
ellipse.Center = new Point(imageItemViewModel.ResizeMargin.Left * xradio + imageItemViewModel.ItemWidth / 2, imageItemViewModel.ResizeMargin.Top * yradio + imageItemViewModel.ItemHeight / 2);
|
||||
ellipse.RadiusX = imageItemViewModel.ItemWidth / 2;
|
||||
ellipse.RadiusY = imageItemViewModel.ItemHeight / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
ellipse.Center = new Point(imageItemViewModel.ResizeMargin.Left + (imageItemViewModel.ItemWidth - imageItemViewModel.ResizeMargin.Left - imageItemViewModel.ResizeMargin.Right) / 2, imageItemViewModel.ResizeMargin.Top + (imageItemViewModel.ItemHeight - imageItemViewModel.ResizeMargin.Top - imageItemViewModel.ResizeMargin.Bottom)/ 2);
|
||||
ellipse.RadiusX = (imageItemViewModel.ItemWidth - imageItemViewModel.ResizeMargin.Left - imageItemViewModel.ResizeMargin.Right) / 2;
|
||||
ellipse.RadiusY = (imageItemViewModel.ItemHeight - imageItemViewModel.ResizeMargin.Top - imageItemViewModel.ResizeMargin.Bottom) / 2;
|
||||
}
|
||||
return ellipse;
|
||||
}
|
||||
}
|
||||
else if (para == "Margin")
|
||||
{
|
||||
if (imageItemViewModel.ResizeMode == false)
|
||||
{
|
||||
return new Thickness(-imageItemViewModel.ResizeMargin.Left * xradio, -imageItemViewModel.ResizeMargin.Top * yradio, -imageItemViewModel.ResizeMargin.Right * xradio, -imageItemViewModel.ResizeMargin.Bottom * yradio);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new Thickness();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
218
Util.DiagramDesigner/Converters/ColorBrushConverter.cs
Normal file
218
Util.DiagramDesigner/Converters/ColorBrushConverter.cs
Normal file
@@ -0,0 +1,218 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public class ColorBrushConverter : IValueConverter
|
||||
{
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
Brush brush = null;
|
||||
if (value is Color)
|
||||
{
|
||||
brush = new SolidColorBrush((Color)value);
|
||||
}
|
||||
else if (value is ColorObject colorObject)
|
||||
{
|
||||
if (colorObject.BrushType == BrushType.None)
|
||||
brush = new SolidColorBrush(Colors.Transparent);
|
||||
else if (colorObject.BrushType == BrushType.SolidColorBrush)
|
||||
brush = new SolidColorBrush(colorObject.Color);
|
||||
else if (colorObject.BrushType == BrushType.LinearGradientBrush)
|
||||
{
|
||||
Point startPoint;
|
||||
Point endPoint;
|
||||
if (colorObject.LinearOrientation == LinearOrientation.LeftToRight)
|
||||
{
|
||||
startPoint = new Point(0, 0.5);
|
||||
endPoint = new Point(1, 0.5);
|
||||
}
|
||||
else if (colorObject.LinearOrientation == LinearOrientation.LeftTopToRightBottom)
|
||||
{
|
||||
startPoint = new Point(0, 0);
|
||||
endPoint = new Point(1, 1);
|
||||
}
|
||||
else if (colorObject.LinearOrientation == LinearOrientation.TopToBottom)
|
||||
{
|
||||
startPoint = new Point(0.5, 0);
|
||||
endPoint = new Point(0.5, 1);
|
||||
}
|
||||
else if (colorObject.LinearOrientation == LinearOrientation.RightTopToLeftBottom)
|
||||
{
|
||||
startPoint = new Point(1, 0);
|
||||
endPoint = new Point(0, 1);
|
||||
}
|
||||
else if (colorObject.LinearOrientation == LinearOrientation.RightToLeft)
|
||||
{
|
||||
startPoint = new Point(1, 0.5);
|
||||
endPoint = new Point(0, 0.5);
|
||||
}
|
||||
else if (colorObject.LinearOrientation == LinearOrientation.RightBottomToLeftTop)
|
||||
{
|
||||
startPoint = new Point(1, 1);
|
||||
endPoint = new Point(0, 0);
|
||||
}
|
||||
else if (colorObject.LinearOrientation == LinearOrientation.BottomToTop)
|
||||
{
|
||||
startPoint = new Point(0.5, 1);
|
||||
endPoint = new Point(0.5, 0);
|
||||
}
|
||||
else if (colorObject.LinearOrientation == LinearOrientation.LeftBottomToRightTop)
|
||||
{
|
||||
startPoint = new Point(0, 1);
|
||||
endPoint = new Point(1, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
startPoint = new Point(0, 0.5);
|
||||
endPoint = new Point(1, 0.5);
|
||||
}
|
||||
|
||||
LinearGradientBrush myBrush = new LinearGradientBrush();
|
||||
myBrush.StartPoint = startPoint;
|
||||
myBrush.EndPoint = endPoint;
|
||||
if (colorObject.GradientStop != null)
|
||||
{
|
||||
foreach (var stop in colorObject.GradientStop)
|
||||
{
|
||||
myBrush.GradientStops.Add(new System.Windows.Media.GradientStop(stop.Color, stop.Offset));
|
||||
}
|
||||
}
|
||||
brush = myBrush;
|
||||
|
||||
RotateTransform rotateTransform = new RotateTransform(colorObject.Angle, 0.5, 0.5);
|
||||
myBrush.RelativeTransform = rotateTransform;
|
||||
}
|
||||
else if (colorObject.BrushType == BrushType.RadialGradientBrush)
|
||||
{
|
||||
Point center;
|
||||
Point gradientOrigin;
|
||||
double radiusX;
|
||||
double radiusY;
|
||||
|
||||
if (colorObject.RadialOrientation == RadialOrientation.LeftTop)
|
||||
{
|
||||
center = new Point(0, 0);
|
||||
gradientOrigin = center;
|
||||
radiusX = 1;
|
||||
radiusY = 1;
|
||||
}
|
||||
else if (colorObject.RadialOrientation == RadialOrientation.RightTop)
|
||||
{
|
||||
center = new Point(1, 0);
|
||||
gradientOrigin = center;
|
||||
radiusX = 1;
|
||||
radiusY = 1;
|
||||
}
|
||||
else if (colorObject.RadialOrientation == RadialOrientation.RightBottom)
|
||||
{
|
||||
center = new Point(1, 1);
|
||||
gradientOrigin = center;
|
||||
radiusX = 1;
|
||||
radiusY = 1;
|
||||
}
|
||||
else if (colorObject.RadialOrientation == RadialOrientation.LeftBottom)
|
||||
{
|
||||
center = new Point(0, 1);
|
||||
gradientOrigin = center;
|
||||
radiusX = 1;
|
||||
radiusY = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
center = new Point(0.5, 0.5);
|
||||
gradientOrigin = center;
|
||||
radiusX = 0.5;
|
||||
radiusY = 0.5;
|
||||
}
|
||||
|
||||
RadialGradientBrush myBrush = new RadialGradientBrush();
|
||||
myBrush.Center = center;
|
||||
myBrush.GradientOrigin = gradientOrigin;
|
||||
myBrush.RadiusX = radiusX;
|
||||
myBrush.RadiusY = radiusY;
|
||||
if (colorObject.GradientStop != null)
|
||||
{
|
||||
foreach (var stop in colorObject.GradientStop)
|
||||
{
|
||||
myBrush.GradientStops.Add(new System.Windows.Media.GradientStop(stop.Color, stop.Offset));
|
||||
}
|
||||
}
|
||||
brush = myBrush;
|
||||
|
||||
RotateTransform rotateTransform = new RotateTransform(colorObject.Angle, 0.5, 0.5);
|
||||
myBrush.RelativeTransform = rotateTransform;
|
||||
}
|
||||
else if (colorObject.BrushType == BrushType.ImageBrush)
|
||||
{
|
||||
ImageBrush myBrush = new ImageBrush();
|
||||
myBrush.ImageSource = new BitmapImage(new Uri(colorObject.Image, UriKind.Absolute));
|
||||
brush = myBrush;
|
||||
}
|
||||
else if (colorObject.BrushType == BrushType.DrawingBrush)
|
||||
{
|
||||
DrawingBrush myBrush = new DrawingBrush();
|
||||
|
||||
GeometryDrawing backgroundSquare =
|
||||
new GeometryDrawing(
|
||||
Brushes.White,
|
||||
null,
|
||||
new RectangleGeometry(new Rect(0, 0, 100, 100)));
|
||||
|
||||
GeometryGroup aGeometryGroup = new GeometryGroup();
|
||||
aGeometryGroup.Children.Add(new RectangleGeometry(new Rect(0, 0, 50, 50)));
|
||||
aGeometryGroup.Children.Add(new RectangleGeometry(new Rect(50, 50, 50, 50)));
|
||||
|
||||
LinearGradientBrush checkerBrush = new LinearGradientBrush();
|
||||
checkerBrush.GradientStops.Add(new System.Windows.Media.GradientStop(Colors.Black, 0.0));
|
||||
checkerBrush.GradientStops.Add(new System.Windows.Media.GradientStop(Colors.Gray, 1.0));
|
||||
|
||||
GeometryDrawing checkers = new GeometryDrawing(checkerBrush, null, aGeometryGroup);
|
||||
|
||||
DrawingGroup checkersDrawingGroup = new DrawingGroup();
|
||||
checkersDrawingGroup.Children.Add(backgroundSquare);
|
||||
checkersDrawingGroup.Children.Add(checkers);
|
||||
|
||||
myBrush.Drawing = checkersDrawingGroup;
|
||||
myBrush.Viewport = new Rect(0, 0, 0.25, 0.25);
|
||||
myBrush.TileMode = TileMode.Tile;
|
||||
|
||||
brush = myBrush;
|
||||
}
|
||||
if (brush != null)
|
||||
{
|
||||
brush.Opacity = colorObject.Opacity;
|
||||
}
|
||||
}
|
||||
else if (value is ObservableCollection<GradientStop> gradientStop)
|
||||
{
|
||||
LinearGradientBrush myBrush = new LinearGradientBrush();
|
||||
myBrush.StartPoint = new Point(0, 0.5);
|
||||
myBrush.EndPoint = new Point(1, 0.5);
|
||||
if (gradientStop != null)
|
||||
{
|
||||
foreach (var stop in gradientStop)
|
||||
{
|
||||
myBrush.GradientStops.Add(new System.Windows.Media.GradientStop(stop.Color, stop.Offset));
|
||||
}
|
||||
}
|
||||
brush = myBrush;
|
||||
}
|
||||
|
||||
return brush;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using Util.DiagramDesigner;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public class ConectorOrientationConverter : IValueConverter
|
||||
{
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
if (value is string)
|
||||
{
|
||||
string str = value as string;
|
||||
|
||||
return -5 - (str.Length * 4);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
47
Util.DiagramDesigner/Converters/ConectorValueConverter.cs
Normal file
47
Util.DiagramDesigner/Converters/ConectorValueConverter.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using Util.DiagramDesigner;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public class ConectorValueConverter : IMultiValueConverter
|
||||
{
|
||||
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
if (values == null || values.Length < 1)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
if (values[0] is double && values[1] is ValueTypePoint)
|
||||
{
|
||||
double connectorValue = (double)values[0];
|
||||
ValueTypePoint valueTypePoint = (ValueTypePoint)values[1];
|
||||
|
||||
if (valueTypePoint == ValueTypePoint.Bool)
|
||||
{
|
||||
return (connectorValue == 0) ? "F" : "T";
|
||||
}
|
||||
else if (valueTypePoint == ValueTypePoint.Int)
|
||||
{
|
||||
return connectorValue.ToString("0");
|
||||
}
|
||||
else
|
||||
{
|
||||
return connectorValue.ToString("f3");
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
45
Util.DiagramDesigner/Converters/ConnectionPathConverter.cs
Normal file
45
Util.DiagramDesigner/Converters/ConnectionPathConverter.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
[ValueConversion(typeof(List<Point>), typeof(PathSegmentCollection))]
|
||||
public class ConnectionPathConverter : IValueConverter
|
||||
{
|
||||
static ConnectionPathConverter()
|
||||
{
|
||||
Instance = new ConnectionPathConverter();
|
||||
}
|
||||
|
||||
public static ConnectionPathConverter Instance
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
List<Point> points = (List<Point>)value;
|
||||
PointCollection pointCollection = new PointCollection();
|
||||
if (points != null)
|
||||
{
|
||||
foreach (Point point in points)
|
||||
{
|
||||
pointCollection.Add(point);
|
||||
}
|
||||
}
|
||||
return pointCollection;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
85
Util.DiagramDesigner/Converters/DoubleToThickness.cs
Normal file
85
Util.DiagramDesigner/Converters/DoubleToThickness.cs
Normal file
@@ -0,0 +1,85 @@
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public class DoubleToThickness : IValueConverter
|
||||
{
|
||||
public object Convert(object value, System.Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
if (parameter != null)
|
||||
{
|
||||
switch (parameter.ToString())
|
||||
{
|
||||
case "Left":
|
||||
return new Thickness(System.Convert.ToDouble(value), 0, 0, 0);
|
||||
|
||||
case "Top":
|
||||
return new Thickness(0, System.Convert.ToDouble(value), 0, 0);
|
||||
|
||||
case "Right":
|
||||
return new Thickness(0, 0, System.Convert.ToDouble(value), 0);
|
||||
|
||||
case "Buttom":
|
||||
return new Thickness(0, 0, 0, System.Convert.ToDouble(value));
|
||||
|
||||
case "LeftTop":
|
||||
return new Thickness(System.Convert.ToDouble(value), System.Convert.ToDouble(value), 0, 0);
|
||||
|
||||
case "LeftButtom":
|
||||
return new Thickness(System.Convert.ToDouble(value), 0, 0, System.Convert.ToDouble(value));
|
||||
|
||||
case "RightTop":
|
||||
return new Thickness(0, System.Convert.ToDouble(value), System.Convert.ToDouble(value), 0);
|
||||
|
||||
case "RigthButtom":
|
||||
return new Thickness(0, 0, System.Convert.ToDouble(value), System.Convert.ToDouble(value));
|
||||
|
||||
case "LeftRight":
|
||||
return new Thickness(System.Convert.ToDouble(value), 0, System.Convert.ToDouble(value), 0);
|
||||
|
||||
case "TopButtom":
|
||||
return new Thickness(0, System.Convert.ToDouble(value), 0, System.Convert.ToDouble(value));
|
||||
|
||||
default:
|
||||
return new Thickness(System.Convert.ToDouble(value));
|
||||
}
|
||||
}
|
||||
return new Thickness(System.Convert.ToDouble(value));
|
||||
}
|
||||
return new Thickness(0);
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, System.Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
if (parameter != null)
|
||||
{
|
||||
switch (parameter.ToString())
|
||||
{
|
||||
case "Left":
|
||||
return ((Thickness)value).Left;
|
||||
|
||||
case "Top":
|
||||
return ((Thickness)value).Top;
|
||||
|
||||
case "Right":
|
||||
return ((Thickness)value).Right;
|
||||
|
||||
case "Buttom":
|
||||
return ((Thickness)value).Bottom;
|
||||
|
||||
default:
|
||||
return ((Thickness)value).Left;
|
||||
}
|
||||
}
|
||||
return ((Thickness)value).Left;
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
51
Util.DiagramDesigner/Converters/EnumDescriptionConverter.cs
Normal file
51
Util.DiagramDesigner/Converters/EnumDescriptionConverter.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public class EnumDescriptionConverter : IValueConverter
|
||||
{
|
||||
#region constructor
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EnumDescriptionConverter"/> class.
|
||||
/// </summary>
|
||||
public EnumDescriptionConverter()
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IValueConverter
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
if (value is Enum)
|
||||
{
|
||||
return ((Enum)value).GetDescription();
|
||||
}
|
||||
else
|
||||
{
|
||||
return value.ToString();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
37
Util.DiagramDesigner/Converters/ImageUrlConverter.cs
Normal file
37
Util.DiagramDesigner/Converters/ImageUrlConverter.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
[ValueConversion(typeof(string), typeof(ImageSource))]
|
||||
public class ImageUrlConverter : IValueConverter
|
||||
{
|
||||
static ImageUrlConverter()
|
||||
{
|
||||
Instance = new ImageUrlConverter();
|
||||
}
|
||||
|
||||
public static ImageUrlConverter Instance
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
Uri imagePath = new Uri(value.ToString(), UriKind.RelativeOrAbsolute);
|
||||
ImageSource source = new BitmapImage(imagePath);
|
||||
return source;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
24
Util.DiagramDesigner/Converters/LineDashConverter.cs
Normal file
24
Util.DiagramDesigner/Converters/LineDashConverter.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
|
||||
public class LineDashConverter : IValueConverter
|
||||
{
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
if (value is LineDashStyle arrowStyle)
|
||||
{
|
||||
return StrokeDashArray.Dash[(int)arrowStyle];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
23
Util.DiagramDesigner/Converters/TrueToFalseConverter.cs
Normal file
23
Util.DiagramDesigner/Converters/TrueToFalseConverter.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
/// <summary>
|
||||
/// 这是一个颠倒黑白的世界
|
||||
/// </summary>
|
||||
public sealed class TrueToFalseConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
var v = (bool)value;
|
||||
return !v;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
22
Util.DiagramDesigner/Enums/ArrowPathStyle.cs
Normal file
22
Util.DiagramDesigner/Enums/ArrowPathStyle.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public enum ArrowPathStyle
|
||||
{
|
||||
None,
|
||||
Arrow1,
|
||||
Arrow2,
|
||||
Arrow3,
|
||||
Arrow4,
|
||||
Arrow5,
|
||||
Arrow6,
|
||||
Arrow7,
|
||||
Arrow8,
|
||||
Arrow9,
|
||||
Arrow10,
|
||||
Arrow11,
|
||||
}
|
||||
}
|
||||
24
Util.DiagramDesigner/Enums/ArrowSizeStyle.cs
Normal file
24
Util.DiagramDesigner/Enums/ArrowSizeStyle.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Text;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public enum ArrowSizeStyle
|
||||
{
|
||||
[Description("非常小")]
|
||||
VerySmall = 6,
|
||||
[Description("小")]
|
||||
Small = 8,
|
||||
[Description("中")]
|
||||
Middle = 10,
|
||||
[Description("大")]
|
||||
Large = 12,
|
||||
[Description("特别大")]
|
||||
ExtraLarge = 16,
|
||||
[Description("巨大")]
|
||||
Huge = 24,
|
||||
|
||||
}
|
||||
}
|
||||
18
Util.DiagramDesigner/Enums/BrushType.cs
Normal file
18
Util.DiagramDesigner/Enums/BrushType.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Text;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public enum BrushType
|
||||
{
|
||||
None,
|
||||
SolidColorBrush,
|
||||
LinearGradientBrush,
|
||||
RadialGradientBrush,
|
||||
ImageBrush,
|
||||
VisualBrush,
|
||||
DrawingBrush
|
||||
}
|
||||
}
|
||||
22
Util.DiagramDesigner/Enums/CellHorizontalAlignment.cs
Normal file
22
Util.DiagramDesigner/Enums/CellHorizontalAlignment.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public enum CellHorizontalAlignment
|
||||
{
|
||||
None,
|
||||
Left,
|
||||
Center,
|
||||
Right
|
||||
}
|
||||
|
||||
public enum CellVerticalAlignment
|
||||
{
|
||||
None,
|
||||
Top,
|
||||
Center,
|
||||
Bottom
|
||||
}
|
||||
}
|
||||
15
Util.DiagramDesigner/Enums/ConnectorOrientation.cs
Normal file
15
Util.DiagramDesigner/Enums/ConnectorOrientation.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public enum ConnectorOrientation
|
||||
{
|
||||
None = 0,
|
||||
Left = 1,
|
||||
Top = 2,
|
||||
Right = 3,
|
||||
Bottom = 4
|
||||
}
|
||||
}
|
||||
13
Util.DiagramDesigner/Enums/CursorMode.cs
Normal file
13
Util.DiagramDesigner/Enums/CursorMode.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public enum CursorMode
|
||||
{
|
||||
Normal = 0,
|
||||
Format = 1,
|
||||
Move = 2,
|
||||
}
|
||||
}
|
||||
13
Util.DiagramDesigner/Enums/DiagramType.cs
Normal file
13
Util.DiagramDesigner/Enums/DiagramType.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public enum DiagramType
|
||||
{
|
||||
Normal,
|
||||
FlowChart,
|
||||
Logical
|
||||
}
|
||||
}
|
||||
21
Util.DiagramDesigner/Enums/DrawMode.cs
Normal file
21
Util.DiagramDesigner/Enums/DrawMode.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public enum DrawMode
|
||||
{
|
||||
Normal = 0,
|
||||
Line = 1,
|
||||
Rectangle = 2,
|
||||
Ellipse = 3,
|
||||
Polyline = 4,
|
||||
Polygon = 5,
|
||||
DirectLine = 6,
|
||||
ConnectingLine = 10,
|
||||
CornerConnectingLine = 11,
|
||||
RadiusConnectingLine = 12,
|
||||
Text = 20,
|
||||
}
|
||||
}
|
||||
14
Util.DiagramDesigner/Enums/FontCase.cs
Normal file
14
Util.DiagramDesigner/Enums/FontCase.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
|
||||
public enum FontCase
|
||||
{
|
||||
None,
|
||||
Upper,
|
||||
Lower,
|
||||
}
|
||||
}
|
||||
22
Util.DiagramDesigner/Enums/HorizontalVerticalAlignment.cs
Normal file
22
Util.DiagramDesigner/Enums/HorizontalVerticalAlignment.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public enum HorizontalVerticalAlignment
|
||||
{
|
||||
TopAlignLeft,
|
||||
TopAlignCenter,
|
||||
TopAlignRight,
|
||||
TopAlignJustify,
|
||||
CenterAlignLeft,
|
||||
CenterAlignCenter,
|
||||
CenterAlignRight,
|
||||
CenterAlignJustify,
|
||||
BottomAlignLeft,
|
||||
BottomAlignCenter,
|
||||
BottomAlignRight,
|
||||
BottomAlignJustify,
|
||||
}
|
||||
}
|
||||
32
Util.DiagramDesigner/Enums/LineDashStyle.cs
Normal file
32
Util.DiagramDesigner/Enums/LineDashStyle.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public enum LineDashStyle
|
||||
{
|
||||
None,
|
||||
Dash1,
|
||||
Dash2,
|
||||
Dash3,
|
||||
Dash4,
|
||||
Dash5,
|
||||
Dash6,
|
||||
Dash7,
|
||||
Dash8,
|
||||
Dash9,
|
||||
Dash10,
|
||||
Dash11,
|
||||
Dash12,
|
||||
Dash13,
|
||||
Dash14,
|
||||
Dash15,
|
||||
Dash16,
|
||||
Dash17,
|
||||
Dash18,
|
||||
Dash19,
|
||||
Dash20,
|
||||
Dash21
|
||||
}
|
||||
}
|
||||
27
Util.DiagramDesigner/Enums/LinearOrientation.cs
Normal file
27
Util.DiagramDesigner/Enums/LinearOrientation.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Text;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public enum LinearOrientation
|
||||
{
|
||||
[Description("左到右")]
|
||||
LeftToRight,
|
||||
[Description("左上到右下")]
|
||||
LeftTopToRightBottom,
|
||||
[Description("上到下")]
|
||||
TopToBottom,
|
||||
[Description("右上到左下")]
|
||||
RightTopToLeftBottom,
|
||||
[Description("右到左")]
|
||||
RightToLeft,
|
||||
[Description("右下到左上")]
|
||||
RightBottomToLeftTop,
|
||||
[Description("下到上")]
|
||||
BottomToTop,
|
||||
[Description("左下到右上")]
|
||||
LeftBottomToRightTop
|
||||
}
|
||||
}
|
||||
45
Util.DiagramDesigner/Enums/LockFlag.cs
Normal file
45
Util.DiagramDesigner/Enums/LockFlag.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Text;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public enum LockFlag
|
||||
{
|
||||
[Description("无锁定")]
|
||||
None,
|
||||
[Description("锁定所有")]
|
||||
All,
|
||||
[Description("宽度(敬请期待)")]
|
||||
Width,
|
||||
[Description("高度(敬请期待)")]
|
||||
Height,
|
||||
[Description("纵横比(敬请期待)")]
|
||||
Ratio,
|
||||
[Description("水平位置(敬请期待)")]
|
||||
Horizontal,
|
||||
[Description("垂直位置(敬请期待)")]
|
||||
Vertical,
|
||||
[Description("旋转(敬请期待)")]
|
||||
Rotate,
|
||||
[Description("起点(敬请期待)")]
|
||||
Start,
|
||||
[Description("终点(敬请期待)")]
|
||||
End,
|
||||
[Description("取消组合(敬请期待)")]
|
||||
UnGroup,
|
||||
[Description("编辑文本(敬请期待)")]
|
||||
Text,
|
||||
[Description("保护选中(敬请期待)")]
|
||||
IsSelected,
|
||||
[Description("保护删除(敬请期待)")]
|
||||
Delete,
|
||||
[Description("阻止连接(敬请期待)")]
|
||||
Link,
|
||||
[Description("格式(敬请期待)")]
|
||||
Format,
|
||||
[Description("保护主题(敬请期待)")]
|
||||
Theme,
|
||||
}
|
||||
}
|
||||
56
Util.DiagramDesigner/Enums/LogicalType.cs
Normal file
56
Util.DiagramDesigner/Enums/LogicalType.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public enum LogicalType
|
||||
{
|
||||
Input = -4,
|
||||
Output = -3,
|
||||
Constant = -2,
|
||||
Time = -1,
|
||||
None = 0,
|
||||
ADD = 1,
|
||||
SUB = 2,
|
||||
MUL = 3,
|
||||
DIV = 4,
|
||||
AVE = 5,
|
||||
MOD = 6,
|
||||
AND = 7,
|
||||
OR = 8,
|
||||
XOR = 9,
|
||||
NOT = 10,
|
||||
SHL = 11,//左移
|
||||
SHR = 12,//又移
|
||||
ROL = 13,//循环左移
|
||||
ROR = 14,//循环右移
|
||||
SEL = 15,//选择
|
||||
MAX = 16,
|
||||
MIN = 17,
|
||||
LIMIT = 18,//限幅
|
||||
GT = 19,//大于
|
||||
LT = 20,//小于
|
||||
GE = 21,//大于等于
|
||||
LE = 22,//小于等于
|
||||
EQ = 23,//等于
|
||||
NE = 24,//不等于
|
||||
ABS = 25,
|
||||
SQRT = 26,
|
||||
LN = 27,
|
||||
LOG = 28,
|
||||
EXP = 29,
|
||||
SIN = 30,
|
||||
COS = 31,
|
||||
TAN = 32,
|
||||
ASIN = 33,
|
||||
ACOS = 34,
|
||||
ATAN = 35,
|
||||
EXPT = 36,//幂
|
||||
Bool2Double = 37,
|
||||
Double2Bool = 38,
|
||||
BoolsToDouble = 39,
|
||||
DoubleToBools = 40,
|
||||
|
||||
}
|
||||
}
|
||||
15
Util.DiagramDesigner/Enums/PageSizeOrientation.cs
Normal file
15
Util.DiagramDesigner/Enums/PageSizeOrientation.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Text;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public enum PageSizeOrientation
|
||||
{
|
||||
[Description("竖向")]
|
||||
Vertical,
|
||||
[Description("横向")]
|
||||
Horizontal,
|
||||
}
|
||||
}
|
||||
74
Util.DiagramDesigner/Enums/PageSizeType.cs
Normal file
74
Util.DiagramDesigner/Enums/PageSizeType.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Text;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public enum PageSizeType
|
||||
{
|
||||
|
||||
[Description("Letter,8.5英寸*11英寸")]//612*792
|
||||
Letter,
|
||||
[Description("Folio,8.5英寸*13英寸")]//612*936
|
||||
Folio,
|
||||
[Description("Folio,8.5英寸*14英寸")]//612*1008
|
||||
Legal,
|
||||
[Description("Folio,7.25英寸*10.5英寸")]//522*756
|
||||
Executive,
|
||||
[Description("Folio,5.5英寸*8.5英寸")]//396*612
|
||||
Statement,
|
||||
[Description("#10 Envelope,4.125英寸*9.5英寸")]//297*684
|
||||
Envelope,
|
||||
[Description("Monarch Envelope,3.875英寸*7.5英寸")]//279*540
|
||||
MonarchEnvelope,
|
||||
[Description("Tabloid,11英寸*17英寸")]//792*1224
|
||||
Tabloid,
|
||||
[Description("Letter Small,8 1/2英寸*11英寸")]//612*792
|
||||
LetterSmall,
|
||||
[Description("C Sheet,17英寸*22英寸")]//1224*1584
|
||||
CSheet,
|
||||
[Description("D Sheet,22英寸*34英寸")]//1584*2448
|
||||
DSheet,
|
||||
[Description("E Sheet,34英寸*44英寸")]//2448*3168
|
||||
ESheet,
|
||||
[Description("A3 sheet,297毫米*420毫米")]//842*1191
|
||||
A3,
|
||||
[Description("A4 sheet,210毫米*297毫米")]//595*842
|
||||
A4,
|
||||
[Description("A5 sheet,148毫米*210毫米")]//420*595
|
||||
A5,
|
||||
[Description("B4 sheet,250毫米*354毫米")]//709*1003
|
||||
B4,
|
||||
[Description("B5 sheet,182毫米*257毫米")]//516*729
|
||||
B5,
|
||||
[Description("DL Envelope,110毫米*220毫米")]//312*624
|
||||
DLEnvelope,
|
||||
[Description("C5 Envelope,162毫米*229毫米")]//459*649
|
||||
C5Envelope,
|
||||
[Description("Quarto,215毫米*275毫米")]//609*780
|
||||
Quarto,
|
||||
[Description("C6 Quarto,114毫米*162毫米")]//323*459
|
||||
C6Quarto,
|
||||
[Description("B5 Quarto,176毫米*250毫米")]//499*709
|
||||
B5Quarto,
|
||||
[Description("Italy Quarto,110毫米*230毫米")]//312*652
|
||||
ItalyQuarto,
|
||||
[Description("A4 small sheet,210毫米*297毫米")]//595*842
|
||||
A4small,
|
||||
[Description("German Std Fanfold,8.5英寸*12英寸")]//612*864
|
||||
GermanStdFanfold,
|
||||
[Description("German Lagal Fanfold,8英寸*13英寸")]//576*936
|
||||
GermanLegalFanfold,
|
||||
[Description("PRC 16K,146毫米*215毫米")]//414*609
|
||||
PRC16K,
|
||||
[Description("PRC 32K,97毫米*151毫米")]//275*428
|
||||
PRC32K,
|
||||
//[Description("Japanese Postcard")]//283*420
|
||||
//JapanesePostcard,
|
||||
//[Description("Double Japanese Postcard")]//420*566
|
||||
//DoubleJapanesePostcard,
|
||||
[Description("自定义")]
|
||||
Custom,
|
||||
}
|
||||
}
|
||||
39
Util.DiagramDesigner/Enums/PageUnit.cs
Normal file
39
Util.DiagramDesigner/Enums/PageUnit.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Text;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public enum PageUnit
|
||||
{
|
||||
[Description("毫米(暂未实现)")]
|
||||
mm,
|
||||
[Description("厘米")]
|
||||
cm,
|
||||
[Description("米(暂未实现)")]
|
||||
m,
|
||||
[Description("千米(暂未实现)")]
|
||||
km,
|
||||
[Description("英寸")]
|
||||
inch,
|
||||
[Description("英尺和英寸(暂未实现)")]
|
||||
ftin,
|
||||
[Description("英尺(暂未实现)")]
|
||||
foot,
|
||||
[Description("码(暂未实现)")]
|
||||
yard,
|
||||
[Description("英里(暂未实现)")]
|
||||
mile,
|
||||
[Description("点(暂未实现)")]
|
||||
tiny,
|
||||
[Description("皮卡(暂未实现)")]
|
||||
pickup,
|
||||
[Description("迪多(暂未实现)")]
|
||||
ditto,
|
||||
[Description("西塞罗(暂未实现)")]
|
||||
cicero,
|
||||
[Description("像素(暂未实现)")]
|
||||
pixel,
|
||||
}
|
||||
}
|
||||
21
Util.DiagramDesigner/Enums/RadialOrientation.cs
Normal file
21
Util.DiagramDesigner/Enums/RadialOrientation.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Text;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public enum RadialOrientation
|
||||
{
|
||||
[Description("中心")]
|
||||
Center,
|
||||
[Description("左上")]
|
||||
LeftTop,
|
||||
[Description("右上")]
|
||||
RightTop,
|
||||
[Description("右下")]
|
||||
RightBottom,
|
||||
[Description("左下")]
|
||||
LeftBottom,
|
||||
}
|
||||
}
|
||||
13
Util.DiagramDesigner/Enums/ValueTypePoint.cs
Normal file
13
Util.DiagramDesigner/Enums/ValueTypePoint.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public enum ValueTypePoint
|
||||
{
|
||||
Real = 0,
|
||||
Int = 1,
|
||||
Bool = 2,
|
||||
}
|
||||
}
|
||||
626
Util.DiagramDesigner/Helpers/ColorHelper.cs
Normal file
626
Util.DiagramDesigner/Helpers/ColorHelper.cs
Normal file
@@ -0,0 +1,626 @@
|
||||
using System;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
/// <summary>
|
||||
/// 类 名:ColorHelper
|
||||
/// 功 能:提供从RGB到HSV/HSL色彩空间的相互转换
|
||||
/// 日 期:2015-02-08
|
||||
/// 修 改:2015-03-20
|
||||
/// 作 者:ls9512
|
||||
/// </summary>
|
||||
public static class ColorHelper
|
||||
{
|
||||
public static Color AdjustBrightness(Color c1, double factor)
|
||||
{
|
||||
|
||||
double r = ((c1.R * factor) > 255) ? 255 : (c1.R * factor);
|
||||
double g = ((c1.G * factor) > 255) ? 255 : (c1.G * factor);
|
||||
double b = ((c1.B * factor) > 255) ? 255 : (c1.B * factor);
|
||||
|
||||
Color c = Color.FromArgb(c1.A, (byte)r, (byte)g, (byte)b);
|
||||
return c;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// RGB转换HSV
|
||||
/// </summary>
|
||||
/// <param name="rgb"></param>
|
||||
/// <returns></returns>
|
||||
public static ColorHSV RgbToHsv(ColorRGB rgb)
|
||||
{
|
||||
float min, max, tmp, H, S, V;
|
||||
float R = rgb.R * 1.0f / 255, G = rgb.G * 1.0f / 255, B = rgb.B * 1.0f / 255;
|
||||
tmp = Math.Min(R, G);
|
||||
min = Math.Min(tmp, B);
|
||||
tmp = Math.Max(R, G);
|
||||
max = Math.Max(tmp, B);
|
||||
// H
|
||||
H = 0;
|
||||
if (max == min)
|
||||
{
|
||||
H = 0;
|
||||
}
|
||||
else if (max == R && G > B)
|
||||
{
|
||||
H = 60 * (G - B) * 1.0f / (max - min) + 0;
|
||||
}
|
||||
else if (max == R && G < B)
|
||||
{
|
||||
H = 60 * (G - B) * 1.0f / (max - min) + 360;
|
||||
}
|
||||
else if (max == G)
|
||||
{
|
||||
H = H = 60 * (B - R) * 1.0f / (max - min) + 120;
|
||||
}
|
||||
else if (max == B)
|
||||
{
|
||||
H = H = 60 * (R - G) * 1.0f / (max - min) + 240;
|
||||
}
|
||||
// S
|
||||
if (max == 0)
|
||||
{
|
||||
S = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
S = (max - min) * 1.0f / max;
|
||||
}
|
||||
// V
|
||||
V = max;
|
||||
return new ColorHSV((int)H, (int)(S * 255), (int)(V * 255));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// HSV转换RGB
|
||||
/// </summary>
|
||||
/// <param name="hsv"></param>
|
||||
/// <returns></returns>
|
||||
public static ColorRGB HsvToRgb(ColorHSV hsv)
|
||||
{
|
||||
if (hsv.H == 360) hsv.H = 359; // 360为全黑,原因不明
|
||||
float R = 0f, G = 0f, B = 0f;
|
||||
if (hsv.S == 0)
|
||||
{
|
||||
return new ColorRGB(hsv.V, hsv.V, hsv.V);
|
||||
}
|
||||
float S = hsv.S * 1.0f / 255, V = hsv.V * 1.0f / 255;
|
||||
int H1 = (int)(hsv.H * 1.0f / 60), H = hsv.H;
|
||||
float F = H * 1.0f / 60 - H1;
|
||||
float P = V * (1.0f - S);
|
||||
float Q = V * (1.0f - F * S);
|
||||
float T = V * (1.0f - (1.0f - F) * S);
|
||||
switch (H1)
|
||||
{
|
||||
case 0: R = V; G = T; B = P; break;
|
||||
case 1: R = Q; G = V; B = P; break;
|
||||
case 2: R = P; G = V; B = T; break;
|
||||
case 3: R = P; G = Q; B = V; break;
|
||||
case 4: R = T; G = P; B = V; break;
|
||||
case 5: R = V; G = P; B = Q; break;
|
||||
}
|
||||
R = R * 255;
|
||||
G = G * 255;
|
||||
B = B * 255;
|
||||
while (R > 255) R -= 255;
|
||||
while (R < 0) R += 255;
|
||||
while (G > 255) G -= 255;
|
||||
while (G < 0) G += 255;
|
||||
while (B > 255) B -= 255;
|
||||
while (B < 0) B += 255;
|
||||
return new ColorRGB((int)R, (int)G, (int)B);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// RGB转换HSL
|
||||
/// </summary>
|
||||
/// <param name="rgb"></param>
|
||||
/// <returns></returns>
|
||||
public static ColorHSL RgbToHsl(ColorRGB rgb)
|
||||
{
|
||||
float min, max, tmp, H, S, L;
|
||||
float R = rgb.R * 1.0f / 255, G = rgb.G * 1.0f / 255, B = rgb.B * 1.0f / 255;
|
||||
tmp = Math.Min(R, G);
|
||||
min = Math.Min(tmp, B);
|
||||
tmp = Math.Max(R, G);
|
||||
max = Math.Max(tmp, B);
|
||||
// H
|
||||
H = 0;
|
||||
if (max == min)
|
||||
{
|
||||
H = 0; // 此时H应为未定义,通常写为0
|
||||
}
|
||||
else if (max == R && G > B)
|
||||
{
|
||||
H = 60 * (G - B) * 1.0f / (max - min) + 0;
|
||||
}
|
||||
else if (max == R && G < B)
|
||||
{
|
||||
H = 60 * (G - B) * 1.0f / (max - min) + 360;
|
||||
}
|
||||
else if (max == G)
|
||||
{
|
||||
H = H = 60 * (B - R) * 1.0f / (max - min) + 120;
|
||||
}
|
||||
else if (max == B)
|
||||
{
|
||||
H = H = 60 * (R - G) * 1.0f / (max - min) + 240;
|
||||
}
|
||||
// L
|
||||
L = 0.5f * (max + min);
|
||||
// S
|
||||
S = 0;
|
||||
if (L == 0 || max == min)
|
||||
{
|
||||
S = 0;
|
||||
}
|
||||
else if (0 < L && L < 0.5)
|
||||
{
|
||||
S = (max - min) / (L * 2);
|
||||
}
|
||||
else if (L > 0.5)
|
||||
{
|
||||
S = (max - min) / (2 - 2 * L);
|
||||
}
|
||||
return new ColorHSL((int)H, (int)(S * 255), (int)(L * 255));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// HSL转换RGB
|
||||
/// </summary>
|
||||
/// <param name="hsl"></param>
|
||||
/// <returns></returns>
|
||||
public static ColorRGB HslToRgb(ColorHSL hsl)
|
||||
{
|
||||
float R = 0f, G = 0f, B = 0f;
|
||||
float S = hsl.S * 1.0f / 255, L = hsl.L * 1.0f / 255;
|
||||
float temp1, temp2, temp3;
|
||||
if (S == 0f) // 灰色
|
||||
{
|
||||
R = L;
|
||||
G = L;
|
||||
B = L;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (L < 0.5f)
|
||||
{
|
||||
temp2 = L * (1.0f + S);
|
||||
}
|
||||
else
|
||||
{
|
||||
temp2 = L + S - L * S;
|
||||
}
|
||||
temp1 = 2.0f * L - temp2;
|
||||
float H = hsl.H * 1.0f / 360;
|
||||
// R
|
||||
temp3 = H + 1.0f / 3.0f;
|
||||
if (temp3 < 0) temp3 += 1.0f;
|
||||
if (temp3 > 1) temp3 -= 1.0f;
|
||||
R = temp3;
|
||||
// G
|
||||
temp3 = H;
|
||||
if (temp3 < 0) temp3 += 1.0f;
|
||||
if (temp3 > 1) temp3 -= 1.0f;
|
||||
G = temp3;
|
||||
// B
|
||||
temp3 = H - 1.0f / 3.0f;
|
||||
if (temp3 < 0) temp3 += 1.0f;
|
||||
if (temp3 > 1) temp3 -= 1.0f;
|
||||
B = temp3;
|
||||
}
|
||||
R = R * 255;
|
||||
G = G * 255;
|
||||
B = B * 255;
|
||||
return new ColorRGB((int)R, (int)G, (int)B);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// RGB转换HSV
|
||||
/// </summary>
|
||||
/// <param name="rgb"></param>
|
||||
/// <returns></returns>
|
||||
public static ColorHSV ColorToHsv(Color rgb)
|
||||
{
|
||||
float min, max, tmp, H, S, V;
|
||||
float R = rgb.R * 1.0f / 255, G = rgb.G * 1.0f / 255, B = rgb.B * 1.0f / 255;
|
||||
tmp = Math.Min(R, G);
|
||||
min = Math.Min(tmp, B);
|
||||
tmp = Math.Max(R, G);
|
||||
max = Math.Max(tmp, B);
|
||||
// H
|
||||
H = 0;
|
||||
if (max == min)
|
||||
{
|
||||
H = 0;
|
||||
}
|
||||
else if (max == R && G > B)
|
||||
{
|
||||
H = 60 * (G - B) * 1.0f / (max - min) + 0;
|
||||
}
|
||||
else if (max == R && G < B)
|
||||
{
|
||||
H = 60 * (G - B) * 1.0f / (max - min) + 360;
|
||||
}
|
||||
else if (max == G)
|
||||
{
|
||||
H = H = 60 * (B - R) * 1.0f / (max - min) + 120;
|
||||
}
|
||||
else if (max == B)
|
||||
{
|
||||
H = H = 60 * (R - G) * 1.0f / (max - min) + 240;
|
||||
}
|
||||
// S
|
||||
if (max == 0)
|
||||
{
|
||||
S = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
S = (max - min) * 1.0f / max;
|
||||
}
|
||||
// V
|
||||
V = max;
|
||||
return new ColorHSV((int)H, (int)(S * 255), (int)(V * 255));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// HSV转换RGB
|
||||
/// </summary>
|
||||
/// <param name="hsv"></param>
|
||||
/// <returns></returns>
|
||||
public static Color HsvToColor(ColorHSV hsv)
|
||||
{
|
||||
if (hsv.H == 360) hsv.H = 359; // 360为全黑,原因不明
|
||||
float R = 0f, G = 0f, B = 0f;
|
||||
if (hsv.S == 0)
|
||||
{
|
||||
return Color.FromArgb(0xff, (byte)hsv.V, (byte)hsv.V, (byte)hsv.V);
|
||||
}
|
||||
float S = hsv.S * 1.0f / 255, V = hsv.V * 1.0f / 255;
|
||||
int H1 = (int)(hsv.H * 1.0f / 60), H = hsv.H;
|
||||
float F = H * 1.0f / 60 - H1;
|
||||
float P = V * (1.0f - S);
|
||||
float Q = V * (1.0f - F * S);
|
||||
float T = V * (1.0f - (1.0f - F) * S);
|
||||
switch (H1)
|
||||
{
|
||||
case 0: R = V; G = T; B = P; break;
|
||||
case 1: R = Q; G = V; B = P; break;
|
||||
case 2: R = P; G = V; B = T; break;
|
||||
case 3: R = P; G = Q; B = V; break;
|
||||
case 4: R = T; G = P; B = V; break;
|
||||
case 5: R = V; G = P; B = Q; break;
|
||||
}
|
||||
R = R * 255;
|
||||
G = G * 255;
|
||||
B = B * 255;
|
||||
while (R > 255) R -= 255;
|
||||
while (R < 0) R += 255;
|
||||
while (G > 255) G -= 255;
|
||||
while (G < 0) G += 255;
|
||||
while (B > 255) B -= 255;
|
||||
while (B < 0) B += 255;
|
||||
return Color.FromArgb(0xff, (byte)R, (byte)G, (byte)B);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// RGB转换HSL
|
||||
/// </summary>
|
||||
/// <param name="rgb"></param>
|
||||
/// <returns></returns>
|
||||
public static ColorHSL ColorToHsl(Color rgb)
|
||||
{
|
||||
float min, max, tmp, H, S, L;
|
||||
float R = rgb.R * 1.0f / 255, G = rgb.G * 1.0f / 255, B = rgb.B * 1.0f / 255;
|
||||
tmp = Math.Min(R, G);
|
||||
min = Math.Min(tmp, B);
|
||||
tmp = Math.Max(R, G);
|
||||
max = Math.Max(tmp, B);
|
||||
// H
|
||||
H = 0;
|
||||
if (max == min)
|
||||
{
|
||||
H = 0; // 此时H应为未定义,通常写为0
|
||||
}
|
||||
else if (max == R && G > B)
|
||||
{
|
||||
H = 60 * (G - B) * 1.0f / (max - min) + 0;
|
||||
}
|
||||
else if (max == R && G < B)
|
||||
{
|
||||
H = 60 * (G - B) * 1.0f / (max - min) + 360;
|
||||
}
|
||||
else if (max == G)
|
||||
{
|
||||
H = H = 60 * (B - R) * 1.0f / (max - min) + 120;
|
||||
}
|
||||
else if (max == B)
|
||||
{
|
||||
H = H = 60 * (R - G) * 1.0f / (max - min) + 240;
|
||||
}
|
||||
// L
|
||||
L = 0.5f * (max + min);
|
||||
// S
|
||||
S = 0;
|
||||
if (L == 0 || max == min)
|
||||
{
|
||||
S = 0;
|
||||
}
|
||||
else if (0 < L && L < 0.5)
|
||||
{
|
||||
S = (max - min) / (L * 2);
|
||||
}
|
||||
else if (L > 0.5)
|
||||
{
|
||||
S = (max - min) / (2 - 2 * L);
|
||||
}
|
||||
return new ColorHSL((int)H, (int)(S * 255), (int)(L * 255));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// HSL转换RGB
|
||||
/// </summary>
|
||||
/// <param name="hsl"></param>
|
||||
/// <returns></returns>
|
||||
public static Color HslToColor(ColorHSL hsl)
|
||||
{
|
||||
float R = 0f, G = 0f, B = 0f;
|
||||
float S = hsl.S * 1.0f / 255, L = hsl.L * 1.0f / 255;
|
||||
float temp1, temp2, temp3;
|
||||
if (S == 0f) // 灰色
|
||||
{
|
||||
R = L;
|
||||
G = L;
|
||||
B = L;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (L < 0.5f)
|
||||
{
|
||||
temp2 = L * (1.0f + S);
|
||||
}
|
||||
else
|
||||
{
|
||||
temp2 = L + S - L * S;
|
||||
}
|
||||
temp1 = 2.0f * L - temp2;
|
||||
float H = hsl.H * 1.0f / 360;
|
||||
// R
|
||||
temp3 = H + 1.0f / 3.0f;
|
||||
if (temp3 < 0) temp3 += 1.0f;
|
||||
if (temp3 > 1) temp3 -= 1.0f;
|
||||
R = temp3;
|
||||
// G
|
||||
temp3 = H;
|
||||
if (temp3 < 0) temp3 += 1.0f;
|
||||
if (temp3 > 1) temp3 -= 1.0f;
|
||||
G = temp3;
|
||||
// B
|
||||
temp3 = H - 1.0f / 3.0f;
|
||||
if (temp3 < 0) temp3 += 1.0f;
|
||||
if (temp3 > 1) temp3 -= 1.0f;
|
||||
B = temp3;
|
||||
}
|
||||
R = R * 255;
|
||||
G = G * 255;
|
||||
B = B * 255;
|
||||
return Color.FromArgb(0xff, (byte)R, (byte)G, (byte)B);
|
||||
}
|
||||
}
|
||||
|
||||
#region RGB / HSV / HSL 颜色模型类
|
||||
/// <summary>
|
||||
/// 类 名:ColorHSL
|
||||
/// 功 能:H 色相 \ S 饱和度(纯度) \ L 亮度 颜色模型
|
||||
/// 日 期:2015-02-08
|
||||
/// 修 改:2015-03-20
|
||||
/// 作 者:ls9512
|
||||
/// </summary>
|
||||
public class ColorHSL
|
||||
{
|
||||
public ColorHSL(int h, int s, int l)
|
||||
{
|
||||
this._h = h;
|
||||
this._s = s;
|
||||
this._l = l;
|
||||
}
|
||||
|
||||
private int _h;
|
||||
private int _s;
|
||||
private int _l;
|
||||
|
||||
/// <summary>
|
||||
/// 色相
|
||||
/// </summary>
|
||||
public int H
|
||||
{
|
||||
get { return this._h; }
|
||||
set
|
||||
{
|
||||
this._h = value;
|
||||
this._h = this._h > 360 ? 360 : this._h;
|
||||
this._h = this._h < 0 ? 0 : this._h;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 饱和度(纯度)
|
||||
/// </summary>
|
||||
public int S
|
||||
{
|
||||
get { return this._s; }
|
||||
set
|
||||
{
|
||||
this._s = value;
|
||||
this._s = this._s > 255 ? 255 : this._s;
|
||||
this._s = this._s < 0 ? 0 : this._s;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 饱和度
|
||||
/// </summary>
|
||||
public int L
|
||||
{
|
||||
get { return this._l; }
|
||||
set
|
||||
{
|
||||
this._l = value;
|
||||
this._l = this._l > 255 ? 255 : this._l;
|
||||
this._l = this._l < 0 ? 0 : this._l;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 类 名:ColorHSV
|
||||
/// 功 能:H 色相 \ S 饱和度(纯度) \ V 明度 颜色模型
|
||||
/// 日 期:2015-01-22
|
||||
/// 修 改:2015-03-20
|
||||
/// 作 者:ls9512
|
||||
/// </summary>
|
||||
public class ColorHSV
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造方法
|
||||
/// </summary>
|
||||
/// <param name="h"></param>
|
||||
/// <param name="s"></param>
|
||||
/// <param name="v"></param>
|
||||
public ColorHSV(int h, int s, int v)
|
||||
{
|
||||
this._h = h;
|
||||
this._s = s;
|
||||
this._v = v;
|
||||
}
|
||||
|
||||
private int _h;
|
||||
private int _s;
|
||||
private int _v;
|
||||
|
||||
/// <summary>
|
||||
/// 色相
|
||||
/// </summary>
|
||||
public int H
|
||||
{
|
||||
get { return this._h; }
|
||||
set
|
||||
{
|
||||
this._h = value;
|
||||
this._h = this._h > 360 ? 360 : this._h;
|
||||
this._h = this._h < 0 ? 0 : this._h;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 饱和度(纯度)
|
||||
/// </summary>
|
||||
public int S
|
||||
{
|
||||
get { return this._s; }
|
||||
set
|
||||
{
|
||||
this._s = value;
|
||||
this._s = this._s > 255 ? 255 : this._s;
|
||||
this._s = this._s < 0 ? 0 : this._s;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 明度
|
||||
/// </summary>
|
||||
public int V
|
||||
{
|
||||
get { return this._v; }
|
||||
set
|
||||
{
|
||||
this._v = value;
|
||||
this._v = this._v > 255 ? 255 : this._v;
|
||||
this._v = this._v < 0 ? 0 : this._v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 类 名:ColorRGB
|
||||
/// 功 能:R 红色 \ G 绿色 \ B 蓝色 颜色模型
|
||||
/// 所有颜色模型的基类,RGB是用于输出到屏幕的颜色模式,所以所有模型都将转换成RGB输出
|
||||
/// 日 期:2015-01-22
|
||||
/// 修 改:2015-03-20
|
||||
/// 作 者:ls9512
|
||||
/// </summary>
|
||||
public class ColorRGB
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造方法
|
||||
/// </summary>
|
||||
/// <param name="r"></param>
|
||||
/// <param name="g"></param>
|
||||
/// <param name="b"></param>
|
||||
public ColorRGB(int r, int g, int b)
|
||||
{
|
||||
this._r = r;
|
||||
this._g = g;
|
||||
this._b = b;
|
||||
}
|
||||
|
||||
private int _r;
|
||||
private int _g;
|
||||
private int _b;
|
||||
|
||||
/// <summary>
|
||||
/// 红色
|
||||
/// </summary>
|
||||
public int R
|
||||
{
|
||||
get { return this._r; }
|
||||
set
|
||||
{
|
||||
this._r = value;
|
||||
this._r = this._r > 255 ? 255 : this._r;
|
||||
this._r = this._r < 0 ? 0 : this._r;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 绿色
|
||||
/// </summary>
|
||||
public int G
|
||||
{
|
||||
get { return this._g; }
|
||||
set
|
||||
{
|
||||
this._g = value;
|
||||
this._g = this._g > 255 ? 255 : this._g;
|
||||
this._g = this._g < 0 ? 0 : this._g;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 蓝色
|
||||
/// </summary>
|
||||
public int B
|
||||
{
|
||||
get { return this._b; }
|
||||
set
|
||||
{
|
||||
this._b = value;
|
||||
this._b = this._b > 255 ? 255 : this._b;
|
||||
this._b = this._b < 0 ? 0 : this._b;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取实际颜色
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Color GetColor()
|
||||
{
|
||||
return Color.FromArgb(0xff, (byte)this._r, (byte)this._g, (byte)this._b);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
93
Util.DiagramDesigner/Helpers/ColorPickerManager.cs
Normal file
93
Util.DiagramDesigner/Helpers/ColorPickerManager.cs
Normal file
@@ -0,0 +1,93 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取当前光标处颜色,win8下wpf测试成功
|
||||
/// </summary>
|
||||
public class ColorPickerManager
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="x">鼠标相对于显示器的坐标X</param>
|
||||
/// <param name="y">鼠标相对于显示器的坐标Y</param>
|
||||
/// <returns></returns>
|
||||
//public static System.Drawing.Color GetColor(int x, int y)
|
||||
//{
|
||||
// IntPtr hdc = GetDC(IntPtr.Zero);
|
||||
// uint pixel = GetPixel(hdc, x, y);
|
||||
// ReleaseDC(IntPtr.Zero, hdc);
|
||||
// System.Drawing.Color color = System.Drawing.Color.FromArgb((int)(pixel & 0x000000FF), (int)(pixel & 0x0000FF00) >> 8, (int)(pixel & 0x00FF0000) >> 16);
|
||||
|
||||
// return color;
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="x">鼠标相对于显示器的坐标X</param>
|
||||
/// <param name="y">鼠标相对于显示器的坐标Y</param>
|
||||
/// <returns></returns>
|
||||
public static System.Windows.Media.Color GetColor(int x, int y)
|
||||
{
|
||||
IntPtr hdc = GetDC(IntPtr.Zero);
|
||||
uint pixel = GetPixel(hdc, x, y);
|
||||
ReleaseDC(IntPtr.Zero, hdc);
|
||||
System.Windows.Media.Color color = System.Windows.Media.Color.FromRgb((byte)(pixel & 0x000000FF), (byte)((pixel & 0x0000FF00) >> 8), (byte)((pixel & 0x00FF0000) >> 16));
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
private static extern bool BitBlt(
|
||||
IntPtr hdcDest, // 目标设备的句柄
|
||||
int nXDest, // 目标对象的左上角的X坐标
|
||||
int nYDest, // 目标对象的左上角的X坐标
|
||||
int nWidth, // 目标对象的矩形的宽度
|
||||
int nHeight, // 目标对象的矩形的长度
|
||||
IntPtr hdcSrc, // 源设备的句柄
|
||||
int nXSrc, // 源对象的左上角的X坐标
|
||||
int nYSrc, // 源对象的左上角的X坐标
|
||||
int dwRop // 光栅的操作值
|
||||
);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
private static extern IntPtr CreateDC(
|
||||
string lpszDriver, // 驱动名称
|
||||
string lpszDevice, // 设备名称
|
||||
string lpszOutput, // 无用,可以设定位"NULL"
|
||||
IntPtr lpInitData // 任意的打印机数据
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定窗口的设备场景
|
||||
/// </summary>
|
||||
/// <param name="hwnd">将获取其设备场景的窗口的句柄。若为0,则要获取整个屏幕的DC</param>
|
||||
/// <returns>指定窗口的设备场景句柄,出错则为0</returns>
|
||||
[DllImport("user32.dll")]
|
||||
private static extern IntPtr GetDC(IntPtr hwnd);
|
||||
|
||||
/// <summary>
|
||||
/// 释放由调用GetDC函数获取的指定设备场景
|
||||
/// </summary>
|
||||
/// <param name="hwnd">要释放的设备场景相关的窗口句柄</param>
|
||||
/// <param name="hdc">要释放的设备场景句柄</param>
|
||||
/// <returns>执行成功为1,否则为0</returns>
|
||||
[DllImport("user32.dll")]
|
||||
private static extern Int32 ReleaseDC(IntPtr hwnd, IntPtr hdc);
|
||||
|
||||
/// <summary>
|
||||
/// 在指定的设备场景中取得一个像素的RGB值
|
||||
/// </summary>
|
||||
/// <param name="hdc">一个设备场景的句柄</param>
|
||||
/// <param name="nXPos">逻辑坐标中要检查的横坐标</param>
|
||||
/// <param name="nYPos">逻辑坐标中要检查的纵坐标</param>
|
||||
/// <returns>指定点的颜色</returns>
|
||||
[DllImport("gdi32.dll")]
|
||||
private static extern uint GetPixel(IntPtr hdc, int nXPos, int nYPos);
|
||||
}
|
||||
}
|
||||
17
Util.DiagramDesigner/Helpers/ConnectorInfo.cs
Normal file
17
Util.DiagramDesigner/Helpers/ConnectorInfo.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public struct ConnectorInfo
|
||||
{
|
||||
public double DesignerItemLeft { get; set; }
|
||||
public double DesignerItemTop { get; set; }
|
||||
public Size DesignerItemSize { get; set; }
|
||||
public Point Position { get; set; }
|
||||
public ConnectorOrientation Orientation { get; set; }
|
||||
}
|
||||
}
|
||||
406
Util.DiagramDesigner/Helpers/ControlExtession.cs
Normal file
406
Util.DiagramDesigner/Helpers/ControlExtession.cs
Normal file
@@ -0,0 +1,406 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public static class ControlExtession
|
||||
{
|
||||
#region TreeView操作扩展方法
|
||||
//code:http://www.codeproject.com/Articles/36193/WPF-TreeView-tools
|
||||
|
||||
/// <summary>
|
||||
/// Returns the TreeViewItem of a data bound object.
|
||||
/// </summary>
|
||||
/// <param name="treeView">TreeView</param>
|
||||
/// <param name="obj">Data bound object</param>
|
||||
/// <returns>The TreeViewItem of the data bound object or null.</returns>
|
||||
public static TreeViewItem GetItemFromObject(this TreeView treeView, object obj)
|
||||
{
|
||||
try
|
||||
{
|
||||
DependencyObject dObject = GetContainerFormObject(treeView, obj);
|
||||
TreeViewItem tvi = dObject as TreeViewItem;
|
||||
while (tvi == null)
|
||||
{
|
||||
dObject = VisualTreeHelper.GetParent(dObject);
|
||||
tvi = dObject as TreeViewItem;
|
||||
}
|
||||
return tvi;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static DependencyObject GetContainerFormObject(ItemsControl item, object obj)
|
||||
{
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
DependencyObject dObject = null;
|
||||
dObject = item.ItemContainerGenerator.ContainerFromItem(obj);
|
||||
|
||||
if (dObject != null)
|
||||
return dObject;
|
||||
|
||||
var query = from childItem in item.Items.Cast<object>()
|
||||
let childControl = item.ItemContainerGenerator.ContainerFromItem(childItem) as ItemsControl
|
||||
select GetContainerFormObject(childControl, obj);
|
||||
|
||||
return query.FirstOrDefault(i => i != null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Selects a data bound object of a TreeView.
|
||||
/// </summary>
|
||||
/// <param name="treeView">TreeView</param>
|
||||
/// <param name="obj">Data bound object</param>
|
||||
public static void SelectObject(this TreeView treeView, object obj)
|
||||
{
|
||||
treeView.SelectObject(obj, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Selects or deselects a data bound object of a TreeView.
|
||||
/// </summary>
|
||||
/// <param name="treeView">TreeView</param>
|
||||
/// <param name="obj">Data bound object</param>
|
||||
/// <param name="selected">select or deselect</param>
|
||||
public static void SelectObject(this TreeView treeView, object obj, bool selected)
|
||||
{
|
||||
var tvi = treeView.GetItemFromObject(obj);
|
||||
if (tvi != null)
|
||||
{
|
||||
tvi.IsSelected = selected;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns if a data bound object of a TreeView is selected.
|
||||
/// </summary>
|
||||
/// <param name="treeView">TreeView</param>
|
||||
/// <param name="obj">Data bound object</param>
|
||||
/// <returns>Returns true if the object is selected, and false if it is not selected or obj is not in the tree.</returns>
|
||||
public static bool IsObjectSelected(this TreeView treeView, object obj)
|
||||
{
|
||||
var tvi = treeView.GetItemFromObject(obj);
|
||||
if (tvi != null)
|
||||
{
|
||||
return tvi.IsSelected;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns if a data bound object of a TreeView is focused.
|
||||
/// </summary>
|
||||
/// <param name="treeView">TreeView</param>
|
||||
/// <param name="obj">Data bound object</param>
|
||||
/// <returns>Returns true if the object is focused, and false if it is not focused or obj is not in the tree.</returns>
|
||||
public static bool IsObjectFocused(this TreeView treeView, object obj)
|
||||
{
|
||||
var tvi = treeView.GetItemFromObject(obj);
|
||||
if (tvi != null)
|
||||
{
|
||||
return tvi.IsFocused;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Expands a data bound object of a TreeView.
|
||||
/// </summary>
|
||||
/// <param name="treeView">TreeView</param>
|
||||
/// <param name="obj">Data bound object</param>
|
||||
public static void ExpandObject(this TreeView treeView, object obj)
|
||||
{
|
||||
treeView.ExpandObject(obj, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Expands or collapses a data bound object of a TreeView.
|
||||
/// </summary>
|
||||
/// <param name="treeView">TreeView</param>
|
||||
/// <param name="obj">Data bound object</param>
|
||||
/// <param name="expanded">expand or collapse</param>
|
||||
public static void ExpandObject(this TreeView treeView, object obj, bool expanded)
|
||||
{
|
||||
var tvi = treeView.GetItemFromObject(obj);
|
||||
if (tvi != null)
|
||||
{
|
||||
tvi.IsExpanded = expanded;
|
||||
if (expanded)
|
||||
{
|
||||
// update layout, so that following calls to f.e. SelectObject on child nodes will
|
||||
// find theire TreeViewNodes
|
||||
treeView.UpdateLayout();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns if a douta bound object of a TreeView is expanded.
|
||||
/// </summary>
|
||||
/// <param name="treeView">TreeView</param>
|
||||
/// <param name="obj">Data bound object</param>
|
||||
/// <returns>Returns true if the object is expanded, and false if it is collapsed or obj is not in the tree.</returns>
|
||||
public static bool IsObjectExpanded(this TreeView treeView, object obj)
|
||||
{
|
||||
var tvi = treeView.GetItemFromObject(obj);
|
||||
if (tvi != null)
|
||||
{
|
||||
return tvi.IsExpanded;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retuns the parent TreeViewItem.
|
||||
/// </summary>
|
||||
/// <param name="item">TreeViewItem</param>
|
||||
/// <returns>Parent TreeViewItem</returns>
|
||||
public static TreeViewItem GetParentItem(this TreeViewItem item)
|
||||
{
|
||||
var dObject = VisualTreeHelper.GetParent(item);
|
||||
TreeViewItem tvi = dObject as TreeViewItem;
|
||||
while (tvi == null)
|
||||
{
|
||||
dObject = VisualTreeHelper.GetParent(dObject);
|
||||
tvi = dObject as TreeViewItem;
|
||||
}
|
||||
return tvi;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region FindParent/FindChildren
|
||||
/// <summary>
|
||||
/// Finds a parent of a given item on the visual tree.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the queried item.</typeparam>
|
||||
/// <param name="child">A direct or indirect child of the
|
||||
/// queried item.</param>
|
||||
/// <returns>The first parent item that matches the submitted
|
||||
/// type parameter. If not matching item can be found, a null
|
||||
/// reference is being returned.</returns>
|
||||
public static T TryFindParent<T>(this DependencyObject child)
|
||||
where T : DependencyObject
|
||||
{
|
||||
//get parent item
|
||||
DependencyObject parentObject = GetParentObject(child);
|
||||
|
||||
//we've reached the end of the tree
|
||||
if (parentObject == null) return null;
|
||||
|
||||
//check if the parent matches the type we're looking for
|
||||
T parent = parentObject as T;
|
||||
return parent ?? TryFindParent<T>(parentObject);
|
||||
}
|
||||
|
||||
//public static T FindParent<T>(DependencyObject child) where T : DependencyObject
|
||||
//{
|
||||
// //get parent item
|
||||
// var parentObject = VisualTreeHelper.GetParent(child);
|
||||
|
||||
// //we've reached the end of the tree
|
||||
// if (parentObject == null) return null;
|
||||
|
||||
// //check if the parent matches the type we're looking for
|
||||
// var parent = parentObject as T;
|
||||
// return parent ?? FindParent<T>(parentObject);
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// Finds a Child of a given item in the visual tree.
|
||||
/// </summary>
|
||||
/// <param name="parent">A direct parent of the queried item.</param>
|
||||
/// <typeparam name="T">The type of the queried item.</typeparam>
|
||||
/// <param name="childName">x:Name or Name of child. </param>
|
||||
/// <returns>The first parent item that matches the submitted type parameter.
|
||||
/// If not matching item can be found,
|
||||
/// a null parent is being returned.</returns>
|
||||
public static T FindChild<T>(this DependencyObject parent, string childName)
|
||||
where T : DependencyObject
|
||||
{
|
||||
// Confirm parent and childName are valid.
|
||||
if (parent == null) return null;
|
||||
|
||||
T foundChild = null;
|
||||
|
||||
int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
|
||||
for (int i = 0; i < childrenCount; i++)
|
||||
{
|
||||
var child = VisualTreeHelper.GetChild(parent, i);
|
||||
// If the child is not of the request child type child
|
||||
T childType = child as T;
|
||||
if (childType == null)
|
||||
{
|
||||
// recursively drill down the tree
|
||||
foundChild = FindChild<T>(child, childName);
|
||||
|
||||
// If the child is found, break so we do not overwrite the found child.
|
||||
if (foundChild != null) break;
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(childName))
|
||||
{
|
||||
var frameworkElement = child as FrameworkElement;
|
||||
// If the child's name is set for search
|
||||
if (frameworkElement != null && frameworkElement.Name == childName)
|
||||
{
|
||||
// if the child's name is of the request name
|
||||
foundChild = (T)child;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// child element found.
|
||||
foundChild = (T)child;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return foundChild;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method is an alternative to WPF's
|
||||
/// <see cref="VisualTreeHelper.GetParent"/> method, which also
|
||||
/// supports content elements. Keep in mind that for content element,
|
||||
/// this method falls back to the logical tree of the element!
|
||||
/// </summary>
|
||||
/// <param name="child">The item to be processed.</param>
|
||||
/// <returns>The submitted item's parent, if available. Otherwise
|
||||
/// null.</returns>
|
||||
public static DependencyObject GetParentObject(this DependencyObject child)
|
||||
{
|
||||
if (child == null) return null;
|
||||
|
||||
//handle content elements separately
|
||||
var contentElement = child as ContentElement;
|
||||
if (contentElement != null)
|
||||
{
|
||||
DependencyObject parent = ContentOperations.GetParent(contentElement);
|
||||
if (parent != null) return parent;
|
||||
|
||||
var fce = contentElement as FrameworkContentElement;
|
||||
return fce != null ? fce.Parent : null;
|
||||
}
|
||||
|
||||
//also try searching for parent in framework elements (such as DockPanel, etc)
|
||||
var frameworkElement = child as FrameworkElement;
|
||||
if (frameworkElement != null)
|
||||
{
|
||||
DependencyObject parent = frameworkElement.Parent;
|
||||
if (parent != null) return parent;
|
||||
}
|
||||
|
||||
//if it's not a ContentElement/FrameworkElement, rely on VisualTreeHelper
|
||||
return VisualTreeHelper.GetParent(child);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Analyzes both visual and logical tree in order to find all elements of a given
|
||||
/// type that are descendants of the <paramref name="source"/> item.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the queried items.</typeparam>
|
||||
/// <param name="source">The root element that marks the source of the search. If the
|
||||
/// source is already of the requested type, it will not be included in the result.</param>
|
||||
/// <param name="forceUsingTheVisualTreeHelper">Sometimes it's better to search in the VisualTree (e.g. in tests)</param>
|
||||
/// <returns>All descendants of <paramref name="source"/> that match the requested type.</returns>
|
||||
public static IEnumerable<T> FindChildren<T>(this DependencyObject source, bool forceUsingTheVisualTreeHelper = false) where T : DependencyObject
|
||||
{
|
||||
if (source != null)
|
||||
{
|
||||
var childs = GetChildObjects(source, forceUsingTheVisualTreeHelper);
|
||||
foreach (DependencyObject child in childs)
|
||||
{
|
||||
//analyze if children match the requested type
|
||||
if (child != null && child is T)
|
||||
{
|
||||
yield return (T)child;
|
||||
}
|
||||
|
||||
//recurse tree
|
||||
foreach (T descendant in FindChildren<T>(child))
|
||||
{
|
||||
yield return descendant;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method is an alternative to WPF's
|
||||
/// <see cref="VisualTreeHelper.GetChild"/> method, which also
|
||||
/// supports content elements. Keep in mind that for content elements,
|
||||
/// this method falls back to the logical tree of the element.
|
||||
/// </summary>
|
||||
/// <param name="parent">The item to be processed.</param>
|
||||
/// <param name="forceUsingTheVisualTreeHelper">Sometimes it's better to search in the VisualTree (e.g. in tests)</param>
|
||||
/// <returns>The submitted item's child elements, if available.</returns>
|
||||
public static IEnumerable<DependencyObject> GetChildObjects(this DependencyObject parent, bool forceUsingTheVisualTreeHelper = false)
|
||||
{
|
||||
if (parent == null) yield break;
|
||||
|
||||
if (!forceUsingTheVisualTreeHelper && (parent is ContentElement || parent is FrameworkElement))
|
||||
{
|
||||
//use the logical tree for content / framework elements
|
||||
foreach (object obj in LogicalTreeHelper.GetChildren(parent))
|
||||
{
|
||||
var depObj = obj as DependencyObject;
|
||||
if (depObj != null) yield return (DependencyObject)obj;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//use the visual tree per default
|
||||
int count = VisualTreeHelper.GetChildrenCount(parent);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
yield return VisualTreeHelper.GetChild(parent, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to locate a given item within the visual tree,
|
||||
/// starting with the dependency object at a given position.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the element to be found
|
||||
/// on the visual tree of the element at the given location.</typeparam>
|
||||
/// <param name="reference">The main element which is used to perform
|
||||
/// hit testing.</param>
|
||||
/// <param name="point">The position to be evaluated on the origin.</param>
|
||||
public static T TryFindFromPoint<T>(UIElement reference, Point point)
|
||||
where T : DependencyObject
|
||||
{
|
||||
var element = reference.InputHitTest(point) as DependencyObject;
|
||||
|
||||
if (element == null)
|
||||
return null;
|
||||
if (element is T)
|
||||
return (T)element;
|
||||
return TryFindParent<T>(element);
|
||||
|
||||
//DependencyObject hitObject = reference.InputHitTest(point) as DependencyObject;
|
||||
//while (hitObject != null &&
|
||||
// hitObject.GetType() != typeof(DesignerCanvas))
|
||||
//{
|
||||
// if (hitObject is T)
|
||||
// {
|
||||
// return (T)hitObject;
|
||||
// }
|
||||
// hitObject = VisualTreeHelper.GetParent(hitObject);
|
||||
//}
|
||||
|
||||
//return null;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
using Microsoft.Xaml.Behaviors;
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public class ControlMouseDoubleClickCommandBehavior : Behavior<FrameworkElement>
|
||||
{
|
||||
#region Overrides
|
||||
protected override void OnAttached()
|
||||
{
|
||||
|
||||
base.OnAttached();
|
||||
AssociatedObject.MouseLeftButtonDown += AssociatedObject_MouseLeftButtonDown;
|
||||
EnableDisableElement();
|
||||
}
|
||||
|
||||
protected override void OnDetaching()
|
||||
{
|
||||
AssociatedObject.MouseLeftButtonDown -= AssociatedObject_MouseLeftButtonDown;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
private void AssociatedObject_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
//Get the ItemsControl and then get the item, and check there
|
||||
//is an actual item, as if we are using a ListView we may have clicked the
|
||||
//headers which are not items
|
||||
//ItemsControl listView = sender as ItemsControl;
|
||||
//DependencyObject originalSender = e.OriginalSource as DependencyObject;
|
||||
//if (listView == null || originalSender == null) return;
|
||||
|
||||
//DependencyObject container =
|
||||
// ItemsControl.ContainerFromElement
|
||||
// (sender as ItemsControl, e.OriginalSource as DependencyObject);
|
||||
|
||||
//if (container == null ||
|
||||
// container == DependencyProperty.UnsetValue) return;
|
||||
|
||||
//// found a container, now find the item.
|
||||
//object activatedItem =
|
||||
// listView.ItemContainerGenerator.ItemFromContainer(container);
|
||||
|
||||
//if (activatedItem != null)
|
||||
//{
|
||||
// Invoke(activatedItem, e);
|
||||
//}
|
||||
|
||||
FrameworkElement control = sender as FrameworkElement;
|
||||
DependencyObject originalSender = e.OriginalSource as DependencyObject;
|
||||
if (control == null || originalSender == null) return;
|
||||
|
||||
if (e.ClickCount >= 2)
|
||||
{
|
||||
Invoke(control, e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnCommandChanged(ControlMouseDoubleClickCommandBehavior thisBehaviour,
|
||||
DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (thisBehaviour == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.OldValue != null)
|
||||
{
|
||||
((ICommand)e.OldValue).CanExecuteChanged -= thisBehaviour.OnCommandCanExecuteChanged;
|
||||
}
|
||||
|
||||
ICommand command = (ICommand)e.NewValue;
|
||||
|
||||
if (command != null)
|
||||
{
|
||||
command.CanExecuteChanged += thisBehaviour.OnCommandCanExecuteChanged;
|
||||
}
|
||||
|
||||
thisBehaviour.EnableDisableElement();
|
||||
}
|
||||
|
||||
private bool IsAssociatedElementDisabled()
|
||||
{
|
||||
return AssociatedObject != null && !AssociatedObject.IsEnabled;
|
||||
}
|
||||
|
||||
private void EnableDisableElement()
|
||||
{
|
||||
if (AssociatedObject == null || Command == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AssociatedObject.IsEnabled = Command.CanExecute(this.CommandParameter);
|
||||
}
|
||||
|
||||
private void OnCommandCanExecuteChanged(object sender, EventArgs e)
|
||||
{
|
||||
EnableDisableElement();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Protected Methods
|
||||
/// <param name="parameter">The EventArgs of the fired event.</param>
|
||||
protected void Invoke(object clickedItem, MouseButtonEventArgs parameter)
|
||||
{
|
||||
if (IsAssociatedElementDisabled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ICommand command = Command;
|
||||
if (command != null && command.CanExecute(CommandParameter))
|
||||
{
|
||||
command.Execute(new EventToCommandArgs(clickedItem, command,
|
||||
CommandParameter, (EventArgs)parameter));
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region DPs
|
||||
|
||||
#region CommandParameter
|
||||
/// <summary>
|
||||
/// Identifies the <see cref="CommandParameter" /> dependency property
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register(
|
||||
"CommandParameter", typeof(object), typeof(ControlMouseDoubleClickCommandBehavior),
|
||||
new PropertyMetadata(null,
|
||||
(s, e) =>
|
||||
{
|
||||
ControlMouseDoubleClickCommandBehavior sender = s as ControlMouseDoubleClickCommandBehavior;
|
||||
if (sender == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (sender.AssociatedObject == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sender.EnableDisableElement();
|
||||
}));
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an object that will be passed to the <see cref="Command" />
|
||||
/// attached to this trigger. This is a DependencyProperty.
|
||||
/// </summary>
|
||||
public object CommandParameter
|
||||
{
|
||||
get { return (Object)GetValue(CommandParameterProperty); }
|
||||
set { SetValue(CommandParameterProperty, value); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Command
|
||||
/// <summary
|
||||
/// >
|
||||
/// Identifies the <see cref="Command" /> dependency property
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(
|
||||
"Command", typeof(ICommand), typeof(ControlMouseDoubleClickCommandBehavior),
|
||||
new PropertyMetadata(null,
|
||||
(s, e) => OnCommandChanged(s as ControlMouseDoubleClickCommandBehavior, e)));
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the ICommand that this trigger is bound to. This
|
||||
/// is a DependencyProperty.
|
||||
/// </summary>
|
||||
public ICommand Command
|
||||
{
|
||||
get { return (ICommand)GetValue(CommandProperty); }
|
||||
set { SetValue(CommandProperty, value); }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
using Microsoft.Xaml.Behaviors;
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public class ControlMouseLeftButtonDownCommandBehavior : Behavior<FrameworkElement>
|
||||
{
|
||||
#region Overrides
|
||||
protected override void OnAttached()
|
||||
{
|
||||
|
||||
base.OnAttached();
|
||||
AssociatedObject.PreviewMouseLeftButtonDown += AssociatedObject_PreviewMouseLeftButtonDown;
|
||||
EnableDisableElement();
|
||||
}
|
||||
|
||||
protected override void OnDetaching()
|
||||
{
|
||||
AssociatedObject.PreviewMouseLeftButtonDown -= AssociatedObject_PreviewMouseLeftButtonDown;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
private void AssociatedObject_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
//Get the ItemsControl and then get the item, and check there
|
||||
//is an actual item, as if we are using a ListView we may have clicked the
|
||||
//headers which are not items
|
||||
//ItemsControl listView = sender as ItemsControl;
|
||||
//DependencyObject originalSender = e.OriginalSource as DependencyObject;
|
||||
//if (listView == null || originalSender == null) return;
|
||||
|
||||
//DependencyObject container =
|
||||
// ItemsControl.ContainerFromElement
|
||||
// (sender as ItemsControl, e.OriginalSource as DependencyObject);
|
||||
|
||||
//if (container == null ||
|
||||
// container == DependencyProperty.UnsetValue) return;
|
||||
|
||||
//// found a container, now find the item.
|
||||
//object activatedItem =
|
||||
// listView.ItemContainerGenerator.ItemFromContainer(container);
|
||||
|
||||
//if (activatedItem != null)
|
||||
//{
|
||||
// Invoke(activatedItem, e);
|
||||
//}
|
||||
|
||||
FrameworkElement control = sender as FrameworkElement;
|
||||
DependencyObject originalSender = e.OriginalSource as DependencyObject;
|
||||
if (control == null || originalSender == null) return;
|
||||
|
||||
Invoke(control, e);
|
||||
}
|
||||
|
||||
private static void OnCommandChanged(ControlMouseLeftButtonDownCommandBehavior thisBehaviour,
|
||||
DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (thisBehaviour == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.OldValue != null)
|
||||
{
|
||||
((ICommand)e.OldValue).CanExecuteChanged -= thisBehaviour.OnCommandCanExecuteChanged;
|
||||
}
|
||||
|
||||
ICommand command = (ICommand)e.NewValue;
|
||||
|
||||
if (command != null)
|
||||
{
|
||||
command.CanExecuteChanged += thisBehaviour.OnCommandCanExecuteChanged;
|
||||
}
|
||||
|
||||
thisBehaviour.EnableDisableElement();
|
||||
}
|
||||
|
||||
private bool IsAssociatedElementDisabled()
|
||||
{
|
||||
return AssociatedObject != null && !AssociatedObject.IsEnabled;
|
||||
}
|
||||
|
||||
private void EnableDisableElement()
|
||||
{
|
||||
if (AssociatedObject == null || Command == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AssociatedObject.IsEnabled = Command.CanExecute(this.CommandParameter);
|
||||
}
|
||||
|
||||
private void OnCommandCanExecuteChanged(object sender, EventArgs e)
|
||||
{
|
||||
EnableDisableElement();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Protected Methods
|
||||
/// <param name="parameter">The EventArgs of the fired event.</param>
|
||||
protected void Invoke(object clickedItem, MouseButtonEventArgs parameter)
|
||||
{
|
||||
if (IsAssociatedElementDisabled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ICommand command = Command;
|
||||
if (command != null && command.CanExecute(CommandParameter))
|
||||
{
|
||||
command.Execute(new EventToCommandArgs(clickedItem, command,
|
||||
CommandParameter, (EventArgs)parameter));
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region DPs
|
||||
|
||||
#region CommandParameter
|
||||
/// <summary>
|
||||
/// Identifies the <see cref="CommandParameter" /> dependency property
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register(
|
||||
"CommandParameter", typeof(object), typeof(ControlMouseLeftButtonDownCommandBehavior),
|
||||
new PropertyMetadata(null,
|
||||
(s, e) =>
|
||||
{
|
||||
ControlMouseLeftButtonDownCommandBehavior sender = s as ControlMouseLeftButtonDownCommandBehavior;
|
||||
if (sender == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (sender.AssociatedObject == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sender.EnableDisableElement();
|
||||
}));
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an object that will be passed to the <see cref="Command" />
|
||||
/// attached to this trigger. This is a DependencyProperty.
|
||||
/// </summary>
|
||||
public object CommandParameter
|
||||
{
|
||||
get { return (Object)GetValue(CommandParameterProperty); }
|
||||
set { SetValue(CommandParameterProperty, value); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Command
|
||||
/// <summary
|
||||
/// >
|
||||
/// Identifies the <see cref="Command" /> dependency property
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(
|
||||
"Command", typeof(ICommand), typeof(ControlMouseLeftButtonDownCommandBehavior),
|
||||
new PropertyMetadata(null,
|
||||
(s, e) => OnCommandChanged(s as ControlMouseLeftButtonDownCommandBehavior, e)));
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the ICommand that this trigger is bound to. This
|
||||
/// is a DependencyProperty.
|
||||
/// </summary>
|
||||
public ICommand Command
|
||||
{
|
||||
get { return (ICommand)GetValue(CommandProperty); }
|
||||
set { SetValue(CommandProperty, value); }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
177
Util.DiagramDesigner/Helpers/CopyHelper.cs
Normal file
177
Util.DiagramDesigner/Helpers/CopyHelper.cs
Normal file
@@ -0,0 +1,177 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
using System.Text;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public class CopyHelper
|
||||
{
|
||||
public static T DeepCopyByReflect<T>(T obj)
|
||||
{
|
||||
//如果是字符串或值类型则直接返回
|
||||
if (obj == null || obj is string || obj.GetType().IsValueType) return obj;
|
||||
object retval = Activator.CreateInstance(obj.GetType());
|
||||
FieldInfo[] fields = obj.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
|
||||
foreach (FieldInfo field in fields)
|
||||
{
|
||||
try { field.SetValue(retval, DeepCopyByReflect(field.GetValue(obj))); }
|
||||
catch { }
|
||||
}
|
||||
return (T)retval;
|
||||
}
|
||||
|
||||
public static TChild AutoCopy<TParent, TChild>(TParent parent) where TChild : TParent, new()
|
||||
{
|
||||
TChild child = new TChild();
|
||||
var ParentType = typeof(TParent);
|
||||
var Properties = ParentType.GetProperties();
|
||||
foreach (var Propertie in Properties)
|
||||
{
|
||||
//循环遍历属性
|
||||
if (Propertie.CanRead && Propertie.CanWrite)
|
||||
{
|
||||
//进行属性拷贝
|
||||
Propertie.SetValue(child, Propertie.GetValue(parent, null), null);
|
||||
}
|
||||
}
|
||||
return child;
|
||||
}
|
||||
|
||||
public static T AutoCopy<T>(T source) where T : new()
|
||||
{
|
||||
T target = new T();
|
||||
var Properties = typeof(T).GetProperties();
|
||||
foreach (var Propertie in Properties)
|
||||
{
|
||||
//循环遍历属性
|
||||
if (Propertie.CanRead && Propertie.CanWrite)
|
||||
{
|
||||
//进行属性拷贝
|
||||
Propertie.SetValue(target, Propertie.GetValue(source, null), null);
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
public static T DeepCopy<T>(T obj)
|
||||
{
|
||||
if (obj == null) return obj;
|
||||
|
||||
object retval;
|
||||
using (MemoryStream ms = new MemoryStream())
|
||||
{
|
||||
XmlSerializer xml = new XmlSerializer(typeof(T));
|
||||
xml.Serialize(ms, obj);
|
||||
ms.Seek(0, SeekOrigin.Begin);
|
||||
retval = xml.Deserialize(ms);
|
||||
ms.Close();
|
||||
}
|
||||
return (T)retval;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 反射实现两个类的对象之间相同属性的值的复制
|
||||
/// 适用于初始化新实体
|
||||
/// </summary>
|
||||
/// <typeparam name="D">返回的实体</typeparam>
|
||||
/// <typeparam name="S">数据源实体</typeparam>
|
||||
/// <param name="s">数据源实体</param>
|
||||
/// <returns>返回的新实体</returns>
|
||||
public static D Mapper<D, S>(S s)
|
||||
{
|
||||
D d = Activator.CreateInstance<D>(); //构造新实例
|
||||
try
|
||||
{
|
||||
var Types = s.GetType();//获得类型
|
||||
var Typed = typeof(D);
|
||||
foreach (PropertyInfo sp in Types.GetProperties().Where(p => p.CanRead))//获得类型的属性字段
|
||||
{
|
||||
foreach (PropertyInfo dp in Typed.GetProperties().Where(p => p.CanWrite))
|
||||
{
|
||||
if (dp.Name == sp.Name && dp.PropertyType == sp.PropertyType)//判断属性名是否相同
|
||||
{
|
||||
dp.SetValue(d, sp.GetValue(s, null), null);//获得s对象属性的值复制给d对象的属性
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
public static void CopyPropertyValue(object s, object d, string propertyName = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var Types = s.GetType();//获得类型
|
||||
var Typed = d.GetType();
|
||||
var sps = Types.GetProperties().Where(p => p.CanRead && (string.IsNullOrEmpty(propertyName) || p.Name == propertyName));//获得类型的属性字段
|
||||
var dps = Typed.GetProperties().Where(p => p.CanWrite && (string.IsNullOrEmpty(propertyName) || p.Name == propertyName));
|
||||
|
||||
foreach (PropertyInfo sp in sps)//获得类型的属性字段
|
||||
{
|
||||
foreach (PropertyInfo dp in dps)
|
||||
{
|
||||
if (dp.Name == sp.Name && dp.PropertyType == sp.PropertyType)//判断属性名是否相同
|
||||
{
|
||||
dp.SetValue(d, sp.GetValue(s, null), null);//获得s对象属性的值复制给d对象的属性
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
public static ColorViewModel Mapper(IColorViewModel s)
|
||||
{
|
||||
var d = CopyHelper.Mapper<ColorViewModel, IColorViewModel>(s);
|
||||
d.LineColor = CopyHelper.Mapper<ColorObject, IColorObject>(s.LineColor);
|
||||
d.FillColor = CopyHelper.Mapper<ColorObject, IColorObject>(s.FillColor);
|
||||
d.LineColor.GradientStop = CopyHelper.DeepCopy<ObservableCollection<GradientStop>>(s.LineColor.GradientStop);
|
||||
d.FillColor.GradientStop = CopyHelper.DeepCopy<ObservableCollection<GradientStop>>(s.FillColor.GradientStop);
|
||||
return d;
|
||||
}
|
||||
|
||||
public static T Mapper<T>(IColorViewModel s) where T: IColorViewModel
|
||||
{
|
||||
var d = CopyHelper.Mapper<T, IColorViewModel>(s);
|
||||
d.LineColor = CopyHelper.Mapper<ColorObjectItem, IColorObject>(s.LineColor);
|
||||
d.FillColor = CopyHelper.Mapper<ColorObjectItem, IColorObject>(s.FillColor);
|
||||
d.LineColor.GradientStop = CopyHelper.DeepCopy<ObservableCollection<GradientStop>>(s.LineColor.GradientStop);
|
||||
d.FillColor.GradientStop = CopyHelper.DeepCopy<ObservableCollection<GradientStop>>(s.FillColor.GradientStop);
|
||||
return d;
|
||||
}
|
||||
|
||||
public static void CopyPropertyValue(IColorViewModel s, IColorViewModel d, string propertyName = null)
|
||||
{
|
||||
if (propertyName == "LineColor")
|
||||
{
|
||||
CopyPropertyValue(s.LineColor, d.LineColor);
|
||||
d.LineColor.GradientStop = CopyHelper.DeepCopy<ObservableCollection<GradientStop>>(s.LineColor.GradientStop);
|
||||
}
|
||||
else if (propertyName == "FillColor")
|
||||
{
|
||||
CopyPropertyValue(s.FillColor, d.FillColor);
|
||||
d.FillColor.GradientStop = CopyHelper.DeepCopy<ObservableCollection<GradientStop>>(s.FillColor.GradientStop);
|
||||
}
|
||||
else
|
||||
{
|
||||
CopyPropertyValue((object)s, (object)d, propertyName);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
29
Util.DiagramDesigner/Helpers/CursorPointManager.cs
Normal file
29
Util.DiagramDesigner/Helpers/CursorPointManager.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
/// <summary>
|
||||
/// win8下wpf程序测试成功
|
||||
/// </summary>
|
||||
public class CursorPointManager
|
||||
{
|
||||
#region 得到光标在屏幕上的位置
|
||||
[DllImport("user32")]
|
||||
private static extern bool GetCursorPos(out Point lpPoint);
|
||||
|
||||
/// <summary>
|
||||
/// 获取光标相对于显示器的位置
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static Point GetCursorPosition()
|
||||
{
|
||||
Point showPoint = new Point();
|
||||
GetCursorPos(out showPoint);
|
||||
return showPoint;
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
94
Util.DiagramDesigner/Helpers/DoCommandManager.cs
Normal file
94
Util.DiagramDesigner/Helpers/DoCommandManager.cs
Normal file
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
class DoCommandManager
|
||||
{
|
||||
#region Command定义
|
||||
public class Command
|
||||
{
|
||||
string name;
|
||||
Action action;
|
||||
Action unDoAction;
|
||||
Action clearAction;
|
||||
|
||||
internal Command(string name, Action action, Action unDoAction, Action clearAction)
|
||||
{
|
||||
this.name = name;
|
||||
this.action = action;
|
||||
this.unDoAction = unDoAction;
|
||||
this.clearAction = clearAction;
|
||||
}
|
||||
|
||||
internal void Do() { action(); }
|
||||
internal void UnDo() { unDoAction(); }
|
||||
internal void Clear() { if (clearAction != null) clearAction(); }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return name.ToString();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
public Stack<Command> ReDoActionStack { get; private set; }
|
||||
public Stack<Command> UnDoActionStack { get; private set; }
|
||||
|
||||
public int Capacity { get; set; } = 10;
|
||||
|
||||
public DoCommandManager()
|
||||
{
|
||||
ReDoActionStack = new Stack<Command>();
|
||||
UnDoActionStack = new Stack<Command>();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
cmd.Do();
|
||||
}
|
||||
}
|
||||
|
||||
public void UnDo()
|
||||
{
|
||||
if (!CanUnDo)
|
||||
return;
|
||||
|
||||
var cmd = UnDoActionStack.Pop();
|
||||
ReDoActionStack.Push(cmd);
|
||||
cmd.UnDo();
|
||||
}
|
||||
|
||||
public void ReDo()
|
||||
{
|
||||
if (!CanReDo)
|
||||
return;
|
||||
|
||||
var cmd = ReDoActionStack.Pop();
|
||||
UnDoActionStack.Push(cmd);
|
||||
cmd.Do();
|
||||
}
|
||||
|
||||
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); } }
|
||||
}
|
||||
}
|
||||
18
Util.DiagramDesigner/Helpers/DragObject.cs
Normal file
18
Util.DiagramDesigner/Helpers/DragObject.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
// Wraps info of the dragged object into a class
|
||||
public class DragObject
|
||||
{
|
||||
public Size? DesiredSize { get; set; }
|
||||
public Type ContentType { get; set; }
|
||||
public string Icon { get; set; }
|
||||
public IColorViewModel ColorViewModel { get; set; }
|
||||
public DesignerItemBase DesignerItem { get; set; }
|
||||
}
|
||||
}
|
||||
18
Util.DiagramDesigner/Helpers/EnumExtension.cs
Normal file
18
Util.DiagramDesigner/Helpers/EnumExtension.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public static class EnumExtension
|
||||
{
|
||||
public static string GetDescription(this Enum value)
|
||||
{
|
||||
FieldInfo field = value.GetType().GetField(value.ToString());
|
||||
DescriptionAttribute attribute = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) as DescriptionAttribute;
|
||||
|
||||
return attribute == null ? value.ToString() : attribute.Description;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
25
Util.DiagramDesigner/Helpers/EventToCommandArgs.cs
Normal file
25
Util.DiagramDesigner/Helpers/EventToCommandArgs.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public class EventToCommandArgs
|
||||
{
|
||||
public Object Sender { get; private set; }
|
||||
public ICommand CommandRan { get; private set; }
|
||||
public Object CommandParameter { get; private set; }
|
||||
public EventArgs EventArgs { get; private set; }
|
||||
|
||||
public EventToCommandArgs(Object sender, ICommand commandRan, Object commandParameter, EventArgs eventArgs)
|
||||
{
|
||||
this.Sender = sender;
|
||||
this.CommandRan = commandRan;
|
||||
this.CommandParameter = commandParameter;
|
||||
this.EventArgs = eventArgs;
|
||||
}
|
||||
}
|
||||
}
|
||||
264
Util.DiagramDesigner/Helpers/Extention.Object.cs
Normal file
264
Util.DiagramDesigner/Helpers/Extention.Object.cs
Normal file
@@ -0,0 +1,264 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public static partial class Extention
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
static Extention()
|
||||
{
|
||||
JsonSerializerSettings setting = new JsonSerializerSettings();
|
||||
JsonConvert.DefaultSettings = new Func<JsonSerializerSettings>(() =>
|
||||
{
|
||||
//日期类型默认格式化处理
|
||||
setting.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat;
|
||||
setting.DateFormatString = "yyyy-MM-dd HH:mm:ss";
|
||||
setting.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
|
||||
return setting;
|
||||
});
|
||||
}
|
||||
|
||||
private static BindingFlags _bindingFlags { get; }
|
||||
= BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static;
|
||||
|
||||
/// <summary>
|
||||
/// 将一个object对象序列化,返回一个byte[]
|
||||
/// </summary>
|
||||
/// <param name="obj">能序列化的对象</param>
|
||||
/// <returns></returns>
|
||||
public static byte[] ToBytes(this object obj)
|
||||
{
|
||||
using (MemoryStream ms = new MemoryStream())
|
||||
{
|
||||
IFormatter formatter = new BinaryFormatter();
|
||||
formatter.Serialize(ms, obj);
|
||||
return ms.GetBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断是否为Null或者空
|
||||
/// </summary>
|
||||
/// <param name="obj">对象</param>
|
||||
/// <returns></returns>
|
||||
public static bool IsNullOrEmpty(this object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
return true;
|
||||
else
|
||||
{
|
||||
string objStr = obj.ToString();
|
||||
return string.IsNullOrEmpty(objStr);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将对象序列化成Json字符串
|
||||
/// </summary>
|
||||
/// <param name="obj">需要序列化的对象</param>
|
||||
/// <returns></returns>
|
||||
public static string ToJson(this object obj)
|
||||
{
|
||||
return JsonConvert.SerializeObject(obj);
|
||||
}
|
||||
|
||||
public static JsonSerializerSettings Settings { get; set; } = new JsonSerializerSettings
|
||||
{
|
||||
DateFormatString = "yyyy-MM-dd HH:mm:ss.fff",
|
||||
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
|
||||
NullValueHandling = NullValueHandling.Ignore,
|
||||
};
|
||||
|
||||
public static string ToStandardTimeFormatJson(this object obj)
|
||||
{
|
||||
return JsonConvert.SerializeObject(obj, Settings);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 实体类转json数据,速度快
|
||||
/// </summary>
|
||||
/// <param name="t">实体类</param>
|
||||
/// <returns></returns>
|
||||
public static string EntityToJson(this object t)
|
||||
{
|
||||
if (t == null)
|
||||
return null;
|
||||
string jsonStr = "";
|
||||
jsonStr += "{";
|
||||
PropertyInfo[] infos = t.GetType().GetProperties();
|
||||
for (int i = 0; i < infos.Length; i++)
|
||||
{
|
||||
jsonStr = jsonStr + "\"" + infos[i].Name + "\":\"" + infos[i].GetValue(t).ToString() + "\"";
|
||||
if (i != infos.Length - 1)
|
||||
jsonStr += ",";
|
||||
}
|
||||
jsonStr += "}";
|
||||
return jsonStr;
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
///// 深复制
|
||||
///// </summary>
|
||||
///// <typeparam name="T">类型</typeparam>
|
||||
///// <param name="obj">对象</param>
|
||||
///// <returns></returns>
|
||||
//public static T DeepClone<T>(this T obj) where T : class
|
||||
//{
|
||||
// if (obj == null)
|
||||
// return null;
|
||||
|
||||
// return obj.ToJson().ToObject<T>();
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// 将对象序列化为XML字符串
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型</typeparam>
|
||||
/// <param name="obj">对象</param>
|
||||
/// <returns></returns>
|
||||
public static string ToXmlStr<T>(this T obj)
|
||||
{
|
||||
var jsonStr = obj.ToJson();
|
||||
var xmlDoc = JsonConvert.DeserializeXmlNode(jsonStr);
|
||||
string xmlDocStr = xmlDoc.InnerXml;
|
||||
|
||||
return xmlDocStr;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将对象序列化为XML字符串
|
||||
/// </summary>
|
||||
/// <typeparam name="T">对象类型</typeparam>
|
||||
/// <param name="obj">对象</param>
|
||||
/// <param name="rootNodeName">根节点名(建议设为xml)</param>
|
||||
/// <returns></returns>
|
||||
public static string ToXmlStr<T>(this T obj, string rootNodeName)
|
||||
{
|
||||
var jsonStr = obj.ToJson();
|
||||
var xmlDoc = JsonConvert.DeserializeXmlNode(jsonStr, rootNodeName);
|
||||
string xmlDocStr = xmlDoc.InnerXml;
|
||||
|
||||
return xmlDocStr;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否拥有某属性
|
||||
/// </summary>
|
||||
/// <param name="obj">对象</param>
|
||||
/// <param name="propertyName">属性名</param>
|
||||
/// <returns></returns>
|
||||
public static bool ContainsProperty(this object obj, string propertyName)
|
||||
{
|
||||
return obj.GetType().GetProperty(propertyName, _bindingFlags) != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取某属性值
|
||||
/// </summary>
|
||||
/// <param name="obj">对象</param>
|
||||
/// <param name="propertyName">属性名</param>
|
||||
/// <returns></returns>
|
||||
public static object GetPropertyValue(this object obj, string propertyName)
|
||||
{
|
||||
return obj.GetType().GetProperty(propertyName, _bindingFlags).GetValue(obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置某属性值
|
||||
/// </summary>
|
||||
/// <param name="obj">对象</param>
|
||||
/// <param name="propertyName">属性名</param>
|
||||
/// <param name="value">值</param>
|
||||
/// <returns></returns>
|
||||
public static void SetPropertyValue(this object obj, string propertyName, object value)
|
||||
{
|
||||
obj.GetType().GetProperty(propertyName, _bindingFlags).SetValue(obj, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否拥有某字段
|
||||
/// </summary>
|
||||
/// <param name="obj">对象</param>
|
||||
/// <param name="fieldName">字段名</param>
|
||||
/// <returns></returns>
|
||||
public static bool ContainsField(this object obj, string fieldName)
|
||||
{
|
||||
return obj.GetType().GetField(fieldName, _bindingFlags) != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取某字段值
|
||||
/// </summary>
|
||||
/// <param name="obj">对象</param>
|
||||
/// <param name="fieldName">字段名</param>
|
||||
/// <returns></returns>
|
||||
public static object GetGetFieldValue(this object obj, string fieldName)
|
||||
{
|
||||
return obj.GetType().GetField(fieldName, _bindingFlags).GetValue(obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置某字段值
|
||||
/// </summary>
|
||||
/// <param name="obj">对象</param>
|
||||
/// <param name="fieldName">字段名</param>
|
||||
/// <param name="value">值</param>
|
||||
/// <returns></returns>
|
||||
public static void SetFieldValue(this object obj, string fieldName, object value)
|
||||
{
|
||||
obj.GetType().GetField(fieldName, _bindingFlags).SetValue(obj, value);
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
///// 改变实体类型
|
||||
///// </summary>
|
||||
///// <param name="obj">对象</param>
|
||||
///// <param name="targetType">目标类型</param>
|
||||
///// <returns></returns>
|
||||
//public static object ChangeType(this object obj, Type targetType)
|
||||
//{
|
||||
// return obj.ToJson().ToObject(targetType);
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
///// 改变实体类型
|
||||
///// </summary>
|
||||
///// <typeparam name="T">目标泛型</typeparam>
|
||||
///// <param name="obj">对象</param>
|
||||
///// <returns></returns>
|
||||
//public static T ChangeType<T>(this object obj)
|
||||
//{
|
||||
// return obj.ToJson().ToObject<T>();
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// 改变类型
|
||||
/// </summary>
|
||||
/// <param name="obj">原对象</param>
|
||||
/// <param name="targetType">目标类型</param>
|
||||
/// <returns></returns>
|
||||
public static object ChangeType_ByConvert(this object obj, Type targetType)
|
||||
{
|
||||
object resObj;
|
||||
if (targetType.IsGenericType && targetType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
|
||||
{
|
||||
NullableConverter newNullableConverter = new NullableConverter(targetType);
|
||||
resObj = newNullableConverter.ConvertFrom(obj);
|
||||
}
|
||||
else
|
||||
{
|
||||
resObj = Convert.ChangeType(obj, targetType);
|
||||
}
|
||||
|
||||
return resObj;
|
||||
}
|
||||
}
|
||||
}
|
||||
14
Util.DiagramDesigner/Helpers/IPathFinder.cs
Normal file
14
Util.DiagramDesigner/Helpers/IPathFinder.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public interface IPathFinder
|
||||
{
|
||||
List<Point> GetConnectionLine(ConnectorInfo source, ConnectorInfo sink, bool showLastLine, bool sourceInnerPoint = false);
|
||||
List<Point> GetConnectionLine(ConnectorInfo source, Point sinkPoint, ConnectorOrientation preferredOrientation, bool isInnerPoint = false);
|
||||
}
|
||||
}
|
||||
693
Util.DiagramDesigner/Helpers/OrthogonalPathFinder.cs
Normal file
693
Util.DiagramDesigner/Helpers/OrthogonalPathFinder.cs
Normal file
@@ -0,0 +1,693 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
// Note: I couldn't find a useful open source library that does
|
||||
// orthogonal routing so started to write something on my own.
|
||||
// Categorize this as a quick and dirty short term solution.
|
||||
// I will keep on searching.
|
||||
|
||||
// Helper class to provide an orthogonal connection path
|
||||
public class OrthogonalPathFinder : IPathFinder
|
||||
{
|
||||
private const int const_margin = 20;
|
||||
|
||||
public List<Point> GetConnectionLine(ConnectorInfo source, ConnectorInfo sink, bool showLastLine, bool sourceInnerPoint = false)
|
||||
{
|
||||
List<Point> linePoints = new List<Point>();
|
||||
int margin1 = sourceInnerPoint ? 0 : const_margin;
|
||||
int margin2 = const_margin;
|
||||
|
||||
Rect rectSource = GetRectWithMargin(source, margin1);
|
||||
Rect rectSink = GetRectWithMargin(sink, margin2);
|
||||
|
||||
Point startPoint = GetOffsetPoint(source, rectSource, sourceInnerPoint);
|
||||
Point endPoint = GetOffsetPoint(sink, rectSink);
|
||||
|
||||
linePoints.Add(startPoint);
|
||||
Point currentPoint = startPoint;
|
||||
|
||||
if (!rectSink.Contains(currentPoint) && !rectSource.Contains(endPoint))
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
#region source node
|
||||
|
||||
if (IsPointVisible(currentPoint, endPoint, new Rect[] { rectSource, rectSink }))
|
||||
{
|
||||
linePoints.Add(endPoint);
|
||||
currentPoint = endPoint;
|
||||
break;
|
||||
}
|
||||
|
||||
Point neighbour = GetNearestVisibleNeighborSink(currentPoint, endPoint, sink, rectSource, rectSink);
|
||||
if (!double.IsNaN(neighbour.X))
|
||||
{
|
||||
linePoints.Add(neighbour);
|
||||
linePoints.Add(endPoint);
|
||||
currentPoint = endPoint;
|
||||
break;
|
||||
}
|
||||
|
||||
if (currentPoint == startPoint)
|
||||
{
|
||||
bool flag;
|
||||
Point n = GetNearestNeighborSource(source, endPoint, rectSource, rectSink, out flag, sourceInnerPoint);
|
||||
linePoints.Add(n);
|
||||
currentPoint = n;
|
||||
|
||||
if (!IsRectVisible(currentPoint, rectSink, new Rect[] { rectSource }))
|
||||
{
|
||||
Point n1, n2;
|
||||
GetOppositeCorners(source.Orientation, rectSource, out n1, out n2, sourceInnerPoint);
|
||||
if (flag)
|
||||
{
|
||||
linePoints.Add(n1);
|
||||
currentPoint = n1;
|
||||
}
|
||||
else
|
||||
{
|
||||
linePoints.Add(n2);
|
||||
currentPoint = n2;
|
||||
}
|
||||
if (!IsRectVisible(currentPoint, rectSink, new Rect[] { rectSource }))
|
||||
{
|
||||
if (flag)
|
||||
{
|
||||
linePoints.Add(n2);
|
||||
currentPoint = n2;
|
||||
}
|
||||
else
|
||||
{
|
||||
linePoints.Add(n1);
|
||||
currentPoint = n1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region sink node
|
||||
|
||||
else // from here on we jump to the sink node
|
||||
{
|
||||
Point n1, n2; // neighbour corner
|
||||
Point s1, s2; // opposite corner
|
||||
GetNeighborCorners(sink.Orientation, rectSink, out s1, out s2);
|
||||
GetOppositeCorners(sink.Orientation, rectSink, out n1, out n2);
|
||||
|
||||
bool n1Visible = IsPointVisible(currentPoint, n1, new Rect[] { rectSource, rectSink });
|
||||
bool n2Visible = IsPointVisible(currentPoint, n2, new Rect[] { rectSource, rectSink });
|
||||
|
||||
if (n1Visible && n2Visible)
|
||||
{
|
||||
if (rectSource.Contains(n1))
|
||||
{
|
||||
linePoints.Add(n2);
|
||||
if (rectSource.Contains(s2))
|
||||
{
|
||||
linePoints.Add(n1);
|
||||
linePoints.Add(s1);
|
||||
}
|
||||
else
|
||||
linePoints.Add(s2);
|
||||
|
||||
linePoints.Add(endPoint);
|
||||
currentPoint = endPoint;
|
||||
break;
|
||||
}
|
||||
|
||||
if (rectSource.Contains(n2))
|
||||
{
|
||||
linePoints.Add(n1);
|
||||
if (rectSource.Contains(s1))
|
||||
{
|
||||
linePoints.Add(n2);
|
||||
linePoints.Add(s2);
|
||||
}
|
||||
else
|
||||
linePoints.Add(s1);
|
||||
|
||||
linePoints.Add(endPoint);
|
||||
currentPoint = endPoint;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((Distance(n1, endPoint) <= Distance(n2, endPoint)))
|
||||
{
|
||||
linePoints.Add(n1);
|
||||
if (rectSource.Contains(s1))
|
||||
{
|
||||
linePoints.Add(n2);
|
||||
linePoints.Add(s2);
|
||||
}
|
||||
else
|
||||
linePoints.Add(s1);
|
||||
linePoints.Add(endPoint);
|
||||
currentPoint = endPoint;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
linePoints.Add(n2);
|
||||
if (rectSource.Contains(s2))
|
||||
{
|
||||
linePoints.Add(n1);
|
||||
linePoints.Add(s1);
|
||||
}
|
||||
else
|
||||
linePoints.Add(s2);
|
||||
linePoints.Add(endPoint);
|
||||
currentPoint = endPoint;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (n1Visible)
|
||||
{
|
||||
linePoints.Add(n1);
|
||||
if (rectSource.Contains(s1))
|
||||
{
|
||||
linePoints.Add(n2);
|
||||
linePoints.Add(s2);
|
||||
}
|
||||
else
|
||||
linePoints.Add(s1);
|
||||
linePoints.Add(endPoint);
|
||||
currentPoint = endPoint;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
linePoints.Add(n2);
|
||||
if (rectSource.Contains(s2))
|
||||
{
|
||||
linePoints.Add(n1);
|
||||
linePoints.Add(s1);
|
||||
}
|
||||
else
|
||||
linePoints.Add(s2);
|
||||
linePoints.Add(endPoint);
|
||||
currentPoint = endPoint;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
linePoints.Add(endPoint);
|
||||
}
|
||||
|
||||
linePoints = OptimizeLinePoints(linePoints, new Rect[] { rectSource, rectSink }, source.Orientation, sink.Orientation);
|
||||
|
||||
CheckPathEnd(source, sink, showLastLine, linePoints, sourceInnerPoint);
|
||||
|
||||
return linePoints;
|
||||
}
|
||||
|
||||
public List<Point> GetConnectionLine(ConnectorInfo source, Point sinkPoint, ConnectorOrientation preferredOrientation, bool isInnerPoint = false)
|
||||
{
|
||||
List<Point> linePoints = new List<Point>();
|
||||
int margin = isInnerPoint ? 0 : const_margin;
|
||||
|
||||
Rect rectSource = GetRectWithMargin(source, margin);
|
||||
Point startPoint = GetOffsetPoint(source, rectSource, isInnerPoint);
|
||||
Point endPoint = sinkPoint;
|
||||
|
||||
linePoints.Add(startPoint);
|
||||
Point currentPoint = startPoint;
|
||||
|
||||
if (!rectSource.Contains(endPoint))
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (IsPointVisible(currentPoint, endPoint, new Rect[] { rectSource }))
|
||||
{
|
||||
linePoints.Add(endPoint);
|
||||
break;
|
||||
}
|
||||
|
||||
bool sideFlag;
|
||||
Point n = GetNearestNeighborSource(source, endPoint, rectSource, out sideFlag, isInnerPoint);
|
||||
linePoints.Add(n);
|
||||
currentPoint = n;
|
||||
|
||||
if (IsPointVisible(currentPoint, endPoint, new Rect[] { rectSource }))
|
||||
{
|
||||
linePoints.Add(endPoint);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
Point n1, n2;
|
||||
GetOppositeCorners(source.Orientation, rectSource, out n1, out n2, isInnerPoint);
|
||||
if (sideFlag)
|
||||
linePoints.Add(n1);
|
||||
else
|
||||
linePoints.Add(n2);
|
||||
|
||||
linePoints.Add(endPoint);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
linePoints.Add(endPoint);
|
||||
}
|
||||
|
||||
if (preferredOrientation != ConnectorOrientation.None)
|
||||
linePoints = OptimizeLinePoints(linePoints, new Rect[] { rectSource }, source.Orientation, preferredOrientation);
|
||||
else
|
||||
linePoints = OptimizeLinePoints(linePoints, new Rect[] { rectSource }, source.Orientation, GetOpositeOrientation(source.Orientation));
|
||||
|
||||
if (!isInnerPoint)
|
||||
{
|
||||
linePoints.Insert(0, source.Position);
|
||||
}
|
||||
|
||||
return linePoints;
|
||||
}
|
||||
|
||||
private static List<Point> OptimizeLinePoints(List<Point> linePoints, Rect[] rectangles, ConnectorOrientation sourceOrientation, ConnectorOrientation sinkOrientation)
|
||||
{
|
||||
List<Point> points = new List<Point>();
|
||||
int cut = 0;
|
||||
|
||||
for (int i = 0; i < linePoints.Count; i++)
|
||||
{
|
||||
if (i >= cut)
|
||||
{
|
||||
for (int k = linePoints.Count - 1; k > i; k--)
|
||||
{
|
||||
if (IsPointVisible(linePoints[i], linePoints[k], rectangles))
|
||||
{
|
||||
cut = k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
points.Add(linePoints[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#region Line
|
||||
for (int j = 0; j < points.Count - 1; j++)
|
||||
{
|
||||
if (points[j].X != points[j + 1].X && points[j].Y != points[j + 1].Y)
|
||||
{
|
||||
ConnectorOrientation orientationFrom;
|
||||
ConnectorOrientation orientationTo;
|
||||
|
||||
// orientation from point
|
||||
if (j == 0)
|
||||
orientationFrom = sourceOrientation;
|
||||
else
|
||||
orientationFrom = GetOrientation(points[j], points[j - 1]);
|
||||
|
||||
// orientation to pint
|
||||
if (j == points.Count - 2)
|
||||
orientationTo = sinkOrientation;
|
||||
else
|
||||
orientationTo = GetOrientation(points[j + 1], points[j + 2]);
|
||||
|
||||
|
||||
if ((orientationFrom == ConnectorOrientation.Left || orientationFrom == ConnectorOrientation.Right) &&
|
||||
(orientationTo == ConnectorOrientation.Left || orientationTo == ConnectorOrientation.Right))
|
||||
{
|
||||
double centerX = Math.Min(points[j].X, points[j + 1].X) + Math.Abs(points[j].X - points[j + 1].X) / 2;
|
||||
points.Insert(j + 1, new Point(centerX, points[j].Y));
|
||||
points.Insert(j + 2, new Point(centerX, points[j + 2].Y));
|
||||
if (points.Count - 1 > j + 3)
|
||||
points.RemoveAt(j + 3);
|
||||
return points;
|
||||
}
|
||||
|
||||
if ((orientationFrom == ConnectorOrientation.Top || orientationFrom == ConnectorOrientation.Bottom) &&
|
||||
(orientationTo == ConnectorOrientation.Top || orientationTo == ConnectorOrientation.Bottom))
|
||||
{
|
||||
double centerY = Math.Min(points[j].Y, points[j + 1].Y) + Math.Abs(points[j].Y - points[j + 1].Y) / 2;
|
||||
points.Insert(j + 1, new Point(points[j].X, centerY));
|
||||
points.Insert(j + 2, new Point(points[j + 2].X, centerY));
|
||||
if (points.Count - 1 > j + 3)
|
||||
points.RemoveAt(j + 3);
|
||||
return points;
|
||||
}
|
||||
|
||||
if ((orientationFrom == ConnectorOrientation.Left || orientationFrom == ConnectorOrientation.Right) &&
|
||||
(orientationTo == ConnectorOrientation.Top || orientationTo == ConnectorOrientation.Bottom))
|
||||
{
|
||||
points.Insert(j + 1, new Point(points[j + 1].X, points[j].Y));
|
||||
return points;
|
||||
}
|
||||
|
||||
if ((orientationFrom == ConnectorOrientation.Top || orientationFrom == ConnectorOrientation.Bottom) &&
|
||||
(orientationTo == ConnectorOrientation.Left || orientationTo == ConnectorOrientation.Right))
|
||||
{
|
||||
points.Insert(j + 1, new Point(points[j].X, points[j + 1].Y));
|
||||
return points;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
return points;
|
||||
}
|
||||
|
||||
private static ConnectorOrientation GetOrientation(Point p1, Point p2)
|
||||
{
|
||||
if (p1.X == p2.X)
|
||||
{
|
||||
if (p1.Y >= p2.Y)
|
||||
return ConnectorOrientation.Bottom;
|
||||
else
|
||||
return ConnectorOrientation.Top;
|
||||
}
|
||||
else if (p1.Y == p2.Y)
|
||||
{
|
||||
if (p1.X >= p2.X)
|
||||
return ConnectorOrientation.Right;
|
||||
else
|
||||
return ConnectorOrientation.Left;
|
||||
}
|
||||
throw new Exception("Failed to retrieve orientation");
|
||||
}
|
||||
|
||||
private static Orientation GetOrientation(ConnectorOrientation sourceOrientation, bool isInnerPoint)
|
||||
{
|
||||
if (isInnerPoint)
|
||||
{
|
||||
return Orientation.Vertical;
|
||||
}
|
||||
switch (sourceOrientation)
|
||||
{
|
||||
case ConnectorOrientation.Left:
|
||||
return Orientation.Horizontal;
|
||||
case ConnectorOrientation.Top:
|
||||
return Orientation.Vertical;
|
||||
case ConnectorOrientation.Right:
|
||||
return Orientation.Horizontal;
|
||||
case ConnectorOrientation.Bottom:
|
||||
return Orientation.Vertical;
|
||||
default:
|
||||
throw new Exception("Unknown ConnectorOrientation");
|
||||
}
|
||||
}
|
||||
|
||||
private static Point GetNearestNeighborSource(ConnectorInfo source, Point endPoint, Rect rectSource, Rect rectSink, out bool flag, bool isInnerPoint)
|
||||
{
|
||||
Point n1, n2; // neighbors
|
||||
GetNeighborCorners(source.Orientation, rectSource, out n1, out n2, isInnerPoint);
|
||||
|
||||
if (rectSink.Contains(n1))
|
||||
{
|
||||
flag = false;
|
||||
return n2;
|
||||
}
|
||||
|
||||
if (rectSink.Contains(n2))
|
||||
{
|
||||
flag = true;
|
||||
return n1;
|
||||
}
|
||||
|
||||
if ((Distance(n1, endPoint) <= Distance(n2, endPoint)))
|
||||
{
|
||||
flag = true;
|
||||
return n1;
|
||||
}
|
||||
else
|
||||
{
|
||||
flag = false;
|
||||
return n2;
|
||||
}
|
||||
}
|
||||
|
||||
private static Point GetNearestNeighborSource(ConnectorInfo source, Point endPoint, Rect rectSource, out bool flag, bool isInnerPoint)
|
||||
{
|
||||
Point n1, n2; // neighbors
|
||||
GetNeighborCorners(source.Orientation, rectSource, out n1, out n2, isInnerPoint);
|
||||
|
||||
if ((Distance(n1, endPoint) <= Distance(n2, endPoint)))
|
||||
{
|
||||
flag = true;
|
||||
return n1;
|
||||
}
|
||||
else
|
||||
{
|
||||
flag = false;
|
||||
return n2;
|
||||
}
|
||||
}
|
||||
|
||||
private static Point GetNearestVisibleNeighborSink(Point currentPoint, Point endPoint, ConnectorInfo sink, Rect rectSource, Rect rectSink)
|
||||
{
|
||||
Point s1, s2; // neighbors on sink side
|
||||
GetNeighborCorners(sink.Orientation, rectSink, out s1, out s2);
|
||||
|
||||
bool flag1 = IsPointVisible(currentPoint, s1, new Rect[] { rectSource, rectSink });
|
||||
bool flag2 = IsPointVisible(currentPoint, s2, new Rect[] { rectSource, rectSink });
|
||||
|
||||
if (flag1) // s1 visible
|
||||
{
|
||||
if (flag2) // s1 and s2 visible
|
||||
{
|
||||
if (rectSink.Contains(s1))
|
||||
return s2;
|
||||
|
||||
if (rectSink.Contains(s2))
|
||||
return s1;
|
||||
|
||||
if ((Distance(s1, endPoint) <= Distance(s2, endPoint)))
|
||||
return s1;
|
||||
else
|
||||
return s2;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return s1;
|
||||
}
|
||||
}
|
||||
else // s1 not visible
|
||||
{
|
||||
if (flag2) // only s2 visible
|
||||
{
|
||||
return s2;
|
||||
}
|
||||
else // s1 and s2 not visible
|
||||
{
|
||||
return new Point(double.NaN, double.NaN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsPointVisible(Point fromPoint, Point targetPoint, Rect[] rectangles)
|
||||
{
|
||||
foreach (Rect rect in rectangles)
|
||||
{
|
||||
if (RectangleIntersectsLine(rect, fromPoint, targetPoint))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool IsRectVisible(Point fromPoint, Rect targetRect, Rect[] rectangles)
|
||||
{
|
||||
if (IsPointVisible(fromPoint, targetRect.TopLeft, rectangles))
|
||||
return true;
|
||||
|
||||
if (IsPointVisible(fromPoint, targetRect.TopRight, rectangles))
|
||||
return true;
|
||||
|
||||
if (IsPointVisible(fromPoint, targetRect.BottomLeft, rectangles))
|
||||
return true;
|
||||
|
||||
if (IsPointVisible(fromPoint, targetRect.BottomRight, rectangles))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool RectangleIntersectsLine(Rect rect, Point startPoint, Point endPoint)
|
||||
{
|
||||
rect.Inflate(-1, -1);
|
||||
return rect.IntersectsWith(new Rect(startPoint, endPoint));
|
||||
}
|
||||
|
||||
private static void GetOppositeCorners(ConnectorOrientation orientation, Rect rect, out Point n1, out Point n2, bool isInnerPoint = false)
|
||||
{
|
||||
if (isInnerPoint)
|
||||
{
|
||||
n1 = rect.Location; n2 = rect.Location;
|
||||
return;
|
||||
}
|
||||
switch (orientation)
|
||||
{
|
||||
case ConnectorOrientation.Left:
|
||||
n1 = rect.TopRight; n2 = rect.BottomRight;
|
||||
break;
|
||||
case ConnectorOrientation.Top:
|
||||
n1 = rect.BottomLeft; n2 = rect.BottomRight;
|
||||
break;
|
||||
case ConnectorOrientation.Right:
|
||||
n1 = rect.TopLeft; n2 = rect.BottomLeft;
|
||||
break;
|
||||
case ConnectorOrientation.Bottom:
|
||||
n1 = rect.TopLeft; n2 = rect.TopRight;
|
||||
break;
|
||||
default:
|
||||
throw new Exception("No opposite corners found!");
|
||||
}
|
||||
}
|
||||
|
||||
private static void GetNeighborCorners(ConnectorOrientation orientation, Rect rect, out Point n1, out Point n2, bool isInnerPoint = false)
|
||||
{
|
||||
if (isInnerPoint)
|
||||
{
|
||||
n1 = rect.Location; n2 = rect.Location;
|
||||
return;
|
||||
}
|
||||
switch (orientation)
|
||||
{
|
||||
case ConnectorOrientation.Left:
|
||||
n1 = rect.TopLeft; n2 = rect.BottomLeft;
|
||||
break;
|
||||
case ConnectorOrientation.Top:
|
||||
n1 = rect.TopLeft; n2 = rect.TopRight;
|
||||
break;
|
||||
case ConnectorOrientation.Right:
|
||||
n1 = rect.TopRight; n2 = rect.BottomRight;
|
||||
break;
|
||||
case ConnectorOrientation.Bottom:
|
||||
n1 = rect.BottomLeft; n2 = rect.BottomRight;
|
||||
break;
|
||||
default:
|
||||
throw new Exception("No neighour corners found!");
|
||||
}
|
||||
}
|
||||
|
||||
private static double Distance(Point p1, Point p2)
|
||||
{
|
||||
return Point.Subtract(p1, p2).Length;
|
||||
}
|
||||
|
||||
private static Rect GetRectWithMargin(ConnectorInfo connectorThumb, double margin)
|
||||
{
|
||||
Rect rect = new Rect(connectorThumb.DesignerItemLeft,
|
||||
connectorThumb.DesignerItemTop,
|
||||
0,
|
||||
0);
|
||||
|
||||
rect.Inflate(margin, margin);
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
private static Point GetOffsetPoint(ConnectorInfo connector, Rect rect, bool isInnerPoint = false)
|
||||
{
|
||||
Point offsetPoint = new Point();
|
||||
if (isInnerPoint)
|
||||
{
|
||||
offsetPoint = new Point(connector.Position.X, connector.Position.Y);
|
||||
return offsetPoint;
|
||||
}
|
||||
|
||||
switch (connector.Orientation)
|
||||
{
|
||||
case ConnectorOrientation.Left:
|
||||
offsetPoint = new Point(rect.Left, connector.Position.Y);
|
||||
break;
|
||||
case ConnectorOrientation.Top:
|
||||
offsetPoint = new Point(connector.Position.X, rect.Top);
|
||||
break;
|
||||
case ConnectorOrientation.Right:
|
||||
offsetPoint = new Point(rect.Right, connector.Position.Y);
|
||||
break;
|
||||
case ConnectorOrientation.Bottom:
|
||||
offsetPoint = new Point(connector.Position.X, rect.Bottom);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return offsetPoint;
|
||||
}
|
||||
|
||||
private static void CheckPathEnd(ConnectorInfo source, ConnectorInfo sink, bool showLastLine, List<Point> linePoints, bool sourceInnerPoint)
|
||||
{
|
||||
if (showLastLine)
|
||||
{
|
||||
Point startPoint = new Point(0, 0);
|
||||
Point endPoint = new Point(0, 0);
|
||||
double marginPath = 15;
|
||||
switch (source.Orientation)
|
||||
{
|
||||
case ConnectorOrientation.Left:
|
||||
startPoint = new Point(source.Position.X - marginPath, source.Position.Y);
|
||||
break;
|
||||
case ConnectorOrientation.Top:
|
||||
startPoint = new Point(source.Position.X, source.Position.Y - marginPath);
|
||||
break;
|
||||
case ConnectorOrientation.Right:
|
||||
startPoint = new Point(source.Position.X + marginPath, source.Position.Y);
|
||||
break;
|
||||
case ConnectorOrientation.Bottom:
|
||||
startPoint = new Point(source.Position.X, source.Position.Y + marginPath);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (sourceInnerPoint)
|
||||
{
|
||||
startPoint = new Point(source.Position.X, source.Position.Y);
|
||||
}
|
||||
|
||||
switch (sink.Orientation)
|
||||
{
|
||||
case ConnectorOrientation.Left:
|
||||
endPoint = new Point(sink.Position.X - marginPath, sink.Position.Y);
|
||||
break;
|
||||
case ConnectorOrientation.Top:
|
||||
endPoint = new Point(sink.Position.X, sink.Position.Y - marginPath);
|
||||
break;
|
||||
case ConnectorOrientation.Right:
|
||||
endPoint = new Point(sink.Position.X + marginPath, sink.Position.Y);
|
||||
break;
|
||||
case ConnectorOrientation.Bottom:
|
||||
endPoint = new Point(sink.Position.X, sink.Position.Y + marginPath);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
linePoints.Insert(0, startPoint);
|
||||
linePoints.Add(endPoint);
|
||||
}
|
||||
else
|
||||
{
|
||||
linePoints.Insert(0, source.Position);
|
||||
linePoints.Add(sink.Position);
|
||||
}
|
||||
}
|
||||
|
||||
private static ConnectorOrientation GetOpositeOrientation(ConnectorOrientation connectorOrientation)
|
||||
{
|
||||
switch (connectorOrientation)
|
||||
{
|
||||
case ConnectorOrientation.Left:
|
||||
return ConnectorOrientation.Right;
|
||||
case ConnectorOrientation.Top:
|
||||
return ConnectorOrientation.Bottom;
|
||||
case ConnectorOrientation.Right:
|
||||
return ConnectorOrientation.Left;
|
||||
case ConnectorOrientation.Bottom:
|
||||
return ConnectorOrientation.Top;
|
||||
default:
|
||||
return ConnectorOrientation.Top;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
69
Util.DiagramDesigner/Helpers/PointHelper.cs
Normal file
69
Util.DiagramDesigner/Helpers/PointHelper.cs
Normal file
@@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public class PointHelper
|
||||
{
|
||||
public static Point GetPointForConnector(FullyCreatedConnectorInfo connector)
|
||||
{
|
||||
Point point = new Point();
|
||||
if (connector.IsInnerPoint)
|
||||
{
|
||||
switch (connector.Orientation)
|
||||
{
|
||||
case ConnectorOrientation.Top:
|
||||
point = new Point(connector.DataItem.Left + connector.DataItem.ItemWidth * connector.XRatio + connector.ConnectorWidth / 2,
|
||||
connector.DataItem.Top + connector.DataItem.ItemHeight * connector.YRatio);
|
||||
break;
|
||||
case ConnectorOrientation.Bottom:
|
||||
point = new Point(connector.DataItem.Left + connector.DataItem.ItemWidth * connector.XRatio + connector.ConnectorWidth / 2,
|
||||
connector.DataItem.Top + connector.DataItem.ItemHeight * connector.YRatio + connector.ConnectorHeight / 2); ;
|
||||
break;
|
||||
case ConnectorOrientation.Right:
|
||||
point = new Point(connector.DataItem.Left + connector.DataItem.ItemWidth * connector.XRatio,
|
||||
connector.DataItem.Top + connector.DataItem.ItemHeight * connector.YRatio + connector.ConnectorHeight / 2);
|
||||
break;
|
||||
case ConnectorOrientation.Left:
|
||||
point = new Point(connector.DataItem.Left + connector.DataItem.ItemWidth * connector.XRatio,
|
||||
connector.DataItem.Top + connector.DataItem.ItemHeight * connector.YRatio + connector.ConnectorHeight / 2);
|
||||
break;
|
||||
default:
|
||||
point = new Point(connector.DataItem.Left + connector.DataItem.ItemWidth * connector.XRatio + connector.ConnectorWidth / 2,
|
||||
connector.DataItem.Top + connector.DataItem.ItemHeight * connector.YRatio + connector.ConnectorHeight / 2);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
switch (connector.Orientation)
|
||||
{
|
||||
case ConnectorOrientation.Top:
|
||||
point = new Point(connector.DataItem.Left + (connector.DataItem.ItemWidth / 2), connector.DataItem.Top);
|
||||
break;
|
||||
case ConnectorOrientation.Bottom:
|
||||
point = new Point(connector.DataItem.Left + (connector.DataItem.ItemWidth / 2), (connector.DataItem.Top + connector.DataItem.ItemHeight));
|
||||
break;
|
||||
case ConnectorOrientation.Right:
|
||||
point = new Point(connector.DataItem.Left + connector.DataItem.ItemWidth, connector.DataItem.Top + (connector.DataItem.ItemHeight / 2));
|
||||
break;
|
||||
case ConnectorOrientation.Left:
|
||||
point = new Point(connector.DataItem.Left, connector.DataItem.Top + (connector.DataItem.ItemHeight / 2));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return point;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
29
Util.DiagramDesigner/Helpers/ToolBoxData.cs
Normal file
29
Util.DiagramDesigner/Helpers/ToolBoxData.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Util.DiagramDesigner.Helpers
|
||||
{
|
||||
public class ToolBoxData
|
||||
{
|
||||
public string Text { get; protected set; }
|
||||
public string Icon { get; protected set; }
|
||||
public Type Type { get; protected set; }
|
||||
public IColorViewModel ColorViewModel { get; set; }
|
||||
public double Width { get; set; }
|
||||
public double Height { get; set; }
|
||||
|
||||
public object Addition { get; set; }
|
||||
|
||||
public ToolBoxData(string text, string icon, Type type, double width, double height)
|
||||
{
|
||||
this.Text = text;
|
||||
this.Icon = icon;
|
||||
this.Type = type;
|
||||
this.Width = width;
|
||||
this.Height = height;
|
||||
this.ColorViewModel = new ColorViewModel();
|
||||
}
|
||||
}
|
||||
}
|
||||
37
Util.DiagramDesigner/Helpers/WeakINPCEventHandler.cs
Normal file
37
Util.DiagramDesigner/Helpers/WeakINPCEventHandler.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
namespace Util.DiagramDesigner.Helpers
|
||||
{
|
||||
//[DebuggerNonUserCode]
|
||||
public sealed class WeakINPCEventHandler
|
||||
{
|
||||
private readonly WeakReference _targetReference;
|
||||
private readonly MethodInfo _method;
|
||||
|
||||
public WeakINPCEventHandler(PropertyChangedEventHandler callback)
|
||||
{
|
||||
_method = callback.Method;
|
||||
_targetReference = new WeakReference(callback.Target, true);
|
||||
}
|
||||
|
||||
//[DebuggerNonUserCode]
|
||||
public void Handler(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
var target = _targetReference.Target;
|
||||
if (target != null)
|
||||
{
|
||||
var callback = (Action<object, PropertyChangedEventArgs>)Delegate.CreateDelegate(typeof(Action<object, PropertyChangedEventArgs>), target, _method, true);
|
||||
if (callback != null)
|
||||
{
|
||||
callback(sender, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
Util.DiagramDesigner/Images/FormatPainter.cur
Normal file
BIN
Util.DiagramDesigner/Images/FormatPainter.cur
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Util.DiagramDesigner/Images/Gifs/car_chase.gif
Normal file
BIN
Util.DiagramDesigner/Images/Gifs/car_chase.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.5 MiB |
BIN
Util.DiagramDesigner/Images/file.png
Normal file
BIN
Util.DiagramDesigner/Images/file.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.2 KiB |
369
Util.DiagramDesigner/Messenger/Mediator.cs
Normal file
369
Util.DiagramDesigner/Messenger/Mediator.cs
Normal file
@@ -0,0 +1,369 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
#region WeakAction Inner Class
|
||||
/// <summary>
|
||||
/// This class creates a weak delegate of form Action(Of Object)
|
||||
/// </summary>
|
||||
public class WeakAction
|
||||
{
|
||||
#region Data
|
||||
private readonly WeakReference _target;
|
||||
private readonly Type _ownerType;
|
||||
private readonly Type _actionType;
|
||||
private readonly string _methodName;
|
||||
#endregion
|
||||
|
||||
#region Public Properties/Methods
|
||||
public WeakAction(object target, Type actionType, MethodBase mi)
|
||||
{
|
||||
if (target == null)
|
||||
{
|
||||
Debug.Assert(mi.IsStatic);
|
||||
_ownerType = mi.DeclaringType;
|
||||
}
|
||||
else
|
||||
_target = new WeakReference(target);
|
||||
_methodName = mi.Name;
|
||||
_actionType = actionType;
|
||||
}
|
||||
|
||||
public Type ActionType
|
||||
{
|
||||
get { return _actionType; }
|
||||
}
|
||||
|
||||
public bool HasBeenCollected
|
||||
{
|
||||
get
|
||||
{
|
||||
return (_ownerType == null && (_target == null || !_target.IsAlive));
|
||||
}
|
||||
}
|
||||
|
||||
public Delegate GetMethod()
|
||||
{
|
||||
if (_ownerType != null)
|
||||
{
|
||||
return Delegate.CreateDelegate(_actionType, _ownerType, _methodName);
|
||||
}
|
||||
|
||||
if (_target != null && _target.IsAlive)
|
||||
{
|
||||
object target = _target.Target;
|
||||
if (target != null)
|
||||
return Delegate.CreateDelegate(_actionType, target, _methodName);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// This class creates a simple Mediator which loosely connects different objects together.
|
||||
/// The message handlers are organized using string-based message keys and are held in a WeakReference
|
||||
/// collection.
|
||||
/// </summary>
|
||||
public class Mediator
|
||||
{
|
||||
|
||||
|
||||
#region Data
|
||||
static readonly Mediator instance = new Mediator();
|
||||
static readonly object syncLock = new object();
|
||||
private readonly Dictionary<object, List<WeakAction>> _registeredHandlers =
|
||||
new Dictionary<object, List<WeakAction>>();
|
||||
#endregion
|
||||
|
||||
#region Ctor
|
||||
static Mediator()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private Mediator()
|
||||
{
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
/// <summary>
|
||||
/// Performs the actual registration of a target
|
||||
/// </summary>
|
||||
/// <param name="key">Key to store in dictionary</param>
|
||||
/// <param name="actionType">Delegate type</param>
|
||||
/// <param name="handler">Method</param>
|
||||
private void RegisterHandler(object key, Type actionType, Delegate handler)
|
||||
{
|
||||
var action = new WeakAction(handler.Target, actionType, handler.Method);
|
||||
|
||||
lock (_registeredHandlers)
|
||||
{
|
||||
List<WeakAction> wr;
|
||||
if (_registeredHandlers.TryGetValue(key, out wr))
|
||||
{
|
||||
if (wr.Count > 0)
|
||||
{
|
||||
WeakAction wa = wr[0];
|
||||
if (wa.ActionType != actionType &&
|
||||
!wa.ActionType.IsAssignableFrom(actionType))
|
||||
throw new ArgumentException("Invalid key passed to RegisterHandler - existing handler has incompatible parameter type");
|
||||
}
|
||||
|
||||
wr.Add(action);
|
||||
}
|
||||
else
|
||||
{
|
||||
wr = new List<WeakAction> { action };
|
||||
_registeredHandlers.Add(key, wr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs the unregistration from a target
|
||||
/// </summary>
|
||||
/// <param name="key">Key to store in dictionary</param>
|
||||
/// <param name="actionType">Delegate type</param>
|
||||
/// <param name="handler">Method</param>
|
||||
private void UnregisterHandler(object key, Type actionType, Delegate handler)
|
||||
{
|
||||
lock (_registeredHandlers)
|
||||
{
|
||||
List<WeakAction> wr;
|
||||
if (_registeredHandlers.TryGetValue(key, out wr))
|
||||
{
|
||||
wr.RemoveAll(wa => handler == wa.GetMethod() && actionType == wa.ActionType);
|
||||
|
||||
if (wr.Count == 0)
|
||||
_registeredHandlers.Remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method broadcasts a message to all message targets for a given
|
||||
/// message key and passes a parameter.
|
||||
/// </summary>
|
||||
/// <param name="key">Message key</param>
|
||||
/// <param name="message">Message parameter</param>
|
||||
/// <returns>True/False if any handlers were invoked.</returns>
|
||||
private bool NotifyColleagues(object key, object message)
|
||||
{
|
||||
List<WeakAction> wr;
|
||||
List<WeakAction> wrCopy = new List<WeakAction>();
|
||||
lock (_registeredHandlers)
|
||||
{
|
||||
if (!_registeredHandlers.TryGetValue(key, out wr))
|
||||
return false;
|
||||
else
|
||||
{
|
||||
foreach (var weakRe in wr)
|
||||
{
|
||||
wrCopy.Add(weakRe);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
foreach (var cb in wrCopy)
|
||||
{
|
||||
Delegate action = cb.GetMethod();
|
||||
|
||||
if (action != null)
|
||||
action.DynamicInvoke(message);
|
||||
}
|
||||
|
||||
lock (_registeredHandlers)
|
||||
{
|
||||
wr.RemoveAll(wa => wa.HasBeenCollected);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public Properties/Methods
|
||||
|
||||
/// <summary>
|
||||
/// Singleton Instance
|
||||
/// </summary>
|
||||
public static Mediator Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This registers a Type with the mediator. Any methods decorated with <seealso cref="MediatorMessageSinkAttribute"/> will be
|
||||
/// registered as target method handlers for the given message key.
|
||||
/// </summary>
|
||||
/// <param name="view">Object to register</param>
|
||||
public void Register(object view)
|
||||
{
|
||||
// Look at all instance/static methods on this object type.
|
||||
foreach (var mi in view.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public))
|
||||
{
|
||||
// See if we have a target attribute - if so, register the method as a handler.
|
||||
foreach (var att in mi.GetCustomAttributes(typeof(MediatorMessageSinkAttribute), true))
|
||||
{
|
||||
var mha = (MediatorMessageSinkAttribute)att;
|
||||
var pi = mi.GetParameters();
|
||||
if (pi.Length != 1)
|
||||
throw new InvalidCastException("Cannot cast " + mi.Name + " to Action<T> delegate type.");
|
||||
|
||||
Type actionType = typeof(Action<>).MakeGenericType(pi[0].ParameterType);
|
||||
object key = (mha.MessageKey) ?? actionType;
|
||||
|
||||
if (mi.IsStatic)
|
||||
RegisterHandler(key, actionType, Delegate.CreateDelegate(actionType, mi));
|
||||
else
|
||||
RegisterHandler(key, actionType, Delegate.CreateDelegate(actionType, view, mi.Name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method unregisters a type from the message mediator.
|
||||
/// </summary>
|
||||
/// <param name="view">Object to unregister</param>
|
||||
public void Unregister(object view)
|
||||
{
|
||||
foreach (var mi in view.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public))
|
||||
{
|
||||
foreach (var att in mi.GetCustomAttributes(typeof(MediatorMessageSinkAttribute), true))
|
||||
{
|
||||
var mha = (MediatorMessageSinkAttribute)att;
|
||||
var pi = mi.GetParameters();
|
||||
if (pi.Length != 1)
|
||||
throw new InvalidCastException("Cannot cast " + mi.Name + " to Action<T> delegate type.");
|
||||
|
||||
Type actionType = typeof(Action<>).MakeGenericType(pi[0].ParameterType);
|
||||
object key = (mha.MessageKey) ?? actionType;
|
||||
|
||||
if (mi.IsStatic)
|
||||
UnregisterHandler(key, actionType, Delegate.CreateDelegate(actionType, mi));
|
||||
else
|
||||
UnregisterHandler(key, actionType, Delegate.CreateDelegate(actionType, view, mi.Name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This registers a specific method as a message handler for a specific type.
|
||||
/// </summary>
|
||||
/// <param name="key">Message key</param>
|
||||
/// <param name="handler">Handler method</param>
|
||||
public void RegisterHandler<T>(string key, Action<T> handler)
|
||||
{
|
||||
RegisterHandler(key, handler.GetType(), handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This registers a specific method as a message handler for a specific type.
|
||||
/// </summary>
|
||||
/// <param name="handler">Handler method</param>
|
||||
public void RegisterHandler<T>(Action<T> handler)
|
||||
{
|
||||
RegisterHandler(typeof(Action<T>), handler.GetType(), handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This unregisters a method as a handler.
|
||||
/// </summary>
|
||||
/// <param name="key">Message key</param>
|
||||
/// <param name="handler">Handler</param>
|
||||
public void UnregisterHandler<T>(string key, Action<T> handler)
|
||||
{
|
||||
UnregisterHandler(key, handler.GetType(), handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This unregisters a method as a handler for a specific type
|
||||
/// </summary>
|
||||
/// <param name="handler">Handler</param>
|
||||
public void UnregisterHandler<T>(Action<T> handler)
|
||||
{
|
||||
UnregisterHandler(typeof(Action<T>), handler.GetType(), handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method broadcasts a message to all message targets for a given
|
||||
/// message key and passes a parameter.
|
||||
/// </summary>
|
||||
/// <param name="key">Message key</param>
|
||||
/// <param name="message">Message parameter</param>
|
||||
/// <returns>True/False if any handlers were invoked.</returns>
|
||||
public bool NotifyColleagues<T>(string key, T message)
|
||||
{
|
||||
return NotifyColleagues((object)key, message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method broadcasts a message to all message targets for a given parameter type.
|
||||
/// If a derived type is passed, any handlers for interfaces or base types will also be
|
||||
/// invoked.
|
||||
/// </summary>
|
||||
/// <param name="message">Message parameter</param>
|
||||
/// <returns>True/False if any handlers were invoked.</returns>
|
||||
public bool NotifyColleagues<T>(T message)
|
||||
{
|
||||
Type actionType = typeof(Action<>).MakeGenericType(typeof(T));
|
||||
var keyList = from key in _registeredHandlers.Keys
|
||||
where key is Type && ((Type)key).IsAssignableFrom(actionType)
|
||||
select key;
|
||||
bool rc = false;
|
||||
foreach (var key in keyList)
|
||||
rc |= NotifyColleagues(key, message);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method broadcasts a message to all message targets for a given
|
||||
/// message key and passes a parameter. The message targets are all called
|
||||
/// asynchronously and any resulting exceptions are ignored.
|
||||
/// </summary>
|
||||
/// <param name="key">Message key</param>
|
||||
/// <param name="message">Message parameter</param>
|
||||
public void NotifyColleaguesAsync<T>(string key, T message)
|
||||
{
|
||||
Func<string, T, bool> smaFunc = NotifyColleagues;
|
||||
smaFunc.BeginInvoke(key, message, ia =>
|
||||
{
|
||||
try { smaFunc.EndInvoke(ia); }
|
||||
catch { }
|
||||
}, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method broadcasts a message to all message targets for a given parameter type.
|
||||
/// If a derived type is passed, any handlers for interfaces or base types will also be
|
||||
/// invoked. The message targets are all called asynchronously and any resulting exceptions
|
||||
/// are ignored.
|
||||
/// </summary>
|
||||
/// <param name="message">Message parameter</param>
|
||||
public void NotifyColleaguesAsync<T>(T message)
|
||||
{
|
||||
Func<T, bool> smaFunc = NotifyColleagues;
|
||||
smaFunc.BeginInvoke(message, ia =>
|
||||
{
|
||||
try { smaFunc.EndInvoke(ia); }
|
||||
catch { }
|
||||
}, null);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
/// <summary>
|
||||
/// This attribute allows a method to be targeted as a recipient for a message.
|
||||
/// It requires that the Type is registered with the MessageMediator through the
|
||||
/// <seealso cref="MessageMediator.Register"/> method
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public sealed class MediatorMessageSinkAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Message key
|
||||
/// </summary>
|
||||
public object MessageKey { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor
|
||||
/// </summary>
|
||||
public MediatorMessageSinkAttribute()
|
||||
{
|
||||
MessageKey = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor that takes a message key
|
||||
/// </summary>
|
||||
/// <param name="messageKey">Message Key</param>
|
||||
public MediatorMessageSinkAttribute(string messageKey)
|
||||
{
|
||||
MessageKey = messageKey;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
103
Util.DiagramDesigner/Models/ConnectionItem.cs
Normal file
103
Util.DiagramDesigner/Models/ConnectionItem.cs
Normal file
@@ -0,0 +1,103 @@
|
||||
using Util.DiagramDesigner;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Media;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
[Serializable]
|
||||
[XmlInclude(typeof(ConnectionItem))]
|
||||
public class ConnectionItem : SelectableDesignerItemBase
|
||||
{
|
||||
public ConnectionItem()
|
||||
{
|
||||
|
||||
}
|
||||
public ConnectionItem(Guid id, Guid sourceId, ConnectorOrientation sourceOrientation, Type sourceType, double sourceXRatio, double sourceYRatio, bool sourceInnerPoint,
|
||||
Guid sinkId, ConnectorOrientation sinkOrientation, Type sinkType, double sinkXRatio, double sinkYRatio, bool sinkInnerPoint,
|
||||
int zIndex, bool isGroup, Guid parentId, ColorViewModel colorViewModel, FontViewModel fontViewModel) : base(id, zIndex, isGroup, parentId, colorViewModel, fontViewModel)
|
||||
{
|
||||
this.SourceId = sourceId;
|
||||
this.SourceOrientation = sourceOrientation;
|
||||
this.SourceType = sourceType;
|
||||
this.SourceTypeName = sourceType.FullName;
|
||||
this.SourceXRatio = sourceXRatio;
|
||||
this.SourceYRatio = sourceYRatio;
|
||||
this.SourceInnerPoint = sourceInnerPoint;
|
||||
|
||||
this.SinkId = sinkId;
|
||||
this.SinkOrientation = sinkOrientation;
|
||||
this.SinkType = sinkType;
|
||||
this.SinkTypeName = sinkType.FullName;
|
||||
this.SinkXRatio = sinkXRatio;
|
||||
this.SinkYRatio = sinkYRatio;
|
||||
this.SinkInnerPoint = sinkInnerPoint;
|
||||
}
|
||||
|
||||
public ConnectionItem(Guid sourceId, ConnectorOrientation sourceOrientation, Type sourceType, double sourceXRatio, double sourceYRatio, bool sourceInnerPoint,
|
||||
Guid sinkId, ConnectorOrientation sinkOrientation, Type sinkType, double sinkXRatio, double sinkYRatio, bool sinkInnerPoint, ConnectorViewModel viewmodel) : base(viewmodel)
|
||||
{
|
||||
this.SourceId = sourceId;
|
||||
this.SourceOrientation = sourceOrientation;
|
||||
this.SourceType = sourceType;
|
||||
this.SourceTypeName = sourceType.FullName;
|
||||
this.SourceXRatio = sourceXRatio;
|
||||
this.SourceYRatio = sourceYRatio;
|
||||
this.SourceInnerPoint = sourceInnerPoint;
|
||||
|
||||
this.SinkId = sinkId;
|
||||
this.SinkOrientation = sinkOrientation;
|
||||
this.SinkType = sinkType;
|
||||
this.SinkTypeName = sinkType.FullName;
|
||||
this.SinkXRatio = sinkXRatio;
|
||||
this.SinkYRatio = sinkYRatio;
|
||||
this.SinkInnerPoint = sinkInnerPoint;
|
||||
}
|
||||
|
||||
[XmlAttribute]
|
||||
public Guid SourceId { get; set; }
|
||||
|
||||
[XmlAttribute]
|
||||
public ConnectorOrientation SourceOrientation { get; set; }
|
||||
|
||||
[XmlIgnore]
|
||||
public Type SourceType { get; set; }
|
||||
|
||||
[XmlAttribute]
|
||||
public string SourceTypeName { get; set; }
|
||||
|
||||
[XmlAttribute]
|
||||
public double SourceXRatio { get; set; }
|
||||
|
||||
[XmlAttribute]
|
||||
public double SourceYRatio { get; set; }
|
||||
|
||||
[XmlAttribute]
|
||||
public bool SourceInnerPoint { get; set; }
|
||||
|
||||
[XmlAttribute]
|
||||
public Guid SinkId { get; set; }
|
||||
|
||||
[XmlAttribute]
|
||||
public ConnectorOrientation SinkOrientation { get; set; }
|
||||
|
||||
[XmlIgnore]
|
||||
public Type SinkType { get; set; }
|
||||
|
||||
[XmlAttribute]
|
||||
public string SinkTypeName { get; set; }
|
||||
|
||||
[XmlAttribute]
|
||||
public double SinkXRatio { get; set; }
|
||||
|
||||
[XmlAttribute]
|
||||
public double SinkYRatio { get; set; }
|
||||
|
||||
[XmlAttribute]
|
||||
public bool SinkInnerPoint { get; set; }
|
||||
}
|
||||
}
|
||||
23
Util.DiagramDesigner/Models/ConnectorItem.cs
Normal file
23
Util.DiagramDesigner/Models/ConnectorItem.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using Util.DiagramDesigner;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public class ConnectorItem
|
||||
{
|
||||
public Guid ParentId { get; set; }
|
||||
public Guid Id { get; set; }
|
||||
public double XRatio { get; set; }
|
||||
public double YRatio { get; set; }
|
||||
public double ConnectorWidth { get; set; }
|
||||
public double ConnectorHeight { get; set; }
|
||||
public ConnectorOrientation Orientation { get; set; }
|
||||
public bool IsInnerPoint { get; set; }
|
||||
public ValueTypePoint ValueTypePoint { get; set; }
|
||||
public double ConnectorValue { get; set; }
|
||||
}
|
||||
}
|
||||
72
Util.DiagramDesigner/Models/DesignerItemBase.cs
Normal file
72
Util.DiagramDesigner/Models/DesignerItemBase.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
using Util.DiagramDesigner;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Media;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
[Serializable]
|
||||
[XmlInclude(typeof(DesignerItemBase))]
|
||||
public class DesignerItemBase : SelectableDesignerItemBase
|
||||
{
|
||||
public DesignerItemBase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public DesignerItemBase(DesignerItemViewModelBase viewmodel, string reserve = null) : base(viewmodel)
|
||||
{
|
||||
this.Left = viewmodel.Left;
|
||||
this.Top = viewmodel.Top;
|
||||
this.Angle = viewmodel.Angle;
|
||||
this.ScaleX = viewmodel.ScaleX;
|
||||
this.ScaleY = viewmodel.ScaleY;
|
||||
this.ItemWidth = viewmodel.ItemWidth;
|
||||
this.ItemHeight = viewmodel.ItemHeight;
|
||||
this.Icon = viewmodel.Icon;
|
||||
this.ItemTypeName = viewmodel.GetType().FullName;
|
||||
this.Margin = viewmodel.Margin;
|
||||
this.Reserve = reserve;
|
||||
}
|
||||
|
||||
[XmlAttribute]
|
||||
public double Left { get; set; }
|
||||
|
||||
[XmlAttribute]
|
||||
public double Top { get; set; }
|
||||
|
||||
[XmlAttribute]
|
||||
public double Angle { get; set; }
|
||||
|
||||
[XmlAttribute]
|
||||
public double ScaleX { get; set; }
|
||||
|
||||
[XmlAttribute]
|
||||
public double ScaleY { get; set; }
|
||||
|
||||
[XmlAttribute]
|
||||
public double Margin { get; set; }
|
||||
|
||||
[XmlAttribute]
|
||||
public double ItemWidth { get; set; }
|
||||
|
||||
[XmlAttribute]
|
||||
public double ItemHeight { get; set; }
|
||||
|
||||
[XmlAttribute]
|
||||
public string Icon { get; set; }
|
||||
|
||||
[XmlAttribute]
|
||||
public string Reserve { get; set; }
|
||||
|
||||
[XmlAttribute]
|
||||
public string ItemTypeName { get; set; }
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
34
Util.DiagramDesigner/Models/ImageDesignerItem.cs
Normal file
34
Util.DiagramDesigner/Models/ImageDesignerItem.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public class ImageDesignerItem : DesignerItemBase
|
||||
{
|
||||
public ImageDesignerItem()
|
||||
{
|
||||
|
||||
}
|
||||
public ImageDesignerItem(ImageItemViewModel item) : base(item)
|
||||
{
|
||||
Icon = item.Icon;
|
||||
Connectors = new List<ConnectorItem>();
|
||||
foreach (var fullyCreatedConnectorInfo in item.Connectors)
|
||||
{
|
||||
ConnectorItem connector = new ConnectorItem()
|
||||
{
|
||||
XRatio = fullyCreatedConnectorInfo.XRatio,
|
||||
YRatio = fullyCreatedConnectorInfo.YRatio,
|
||||
ConnectorWidth = fullyCreatedConnectorInfo.ConnectorWidth,
|
||||
ConnectorHeight = fullyCreatedConnectorInfo.ConnectorHeight,
|
||||
Orientation = fullyCreatedConnectorInfo.Orientation
|
||||
};
|
||||
Connectors.Add(connector);
|
||||
}
|
||||
}
|
||||
|
||||
[XmlArray]
|
||||
public List<ConnectorItem> Connectors { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
56
Util.DiagramDesigner/Models/LogicalGateDesignerItemBase.cs
Normal file
56
Util.DiagramDesigner/Models/LogicalGateDesignerItemBase.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public class LogicalGateDesignerItemBase : DesignerItemBase
|
||||
{
|
||||
public LogicalGateDesignerItemBase()
|
||||
{
|
||||
|
||||
}
|
||||
public LogicalGateDesignerItemBase(LogicalGateItemViewModelBase item) : base(item)
|
||||
{
|
||||
this.Connectors = new List<ConnectorItem>();
|
||||
foreach (var fullyCreatedConnectorInfo in item.Connectors)
|
||||
{
|
||||
ConnectorItem connector = new ConnectorItem()
|
||||
{
|
||||
XRatio = fullyCreatedConnectorInfo.XRatio,
|
||||
YRatio = fullyCreatedConnectorInfo.YRatio,
|
||||
ConnectorWidth = fullyCreatedConnectorInfo.ConnectorWidth,
|
||||
ConnectorHeight = fullyCreatedConnectorInfo.ConnectorHeight,
|
||||
Orientation = fullyCreatedConnectorInfo.Orientation,
|
||||
IsInnerPoint = fullyCreatedConnectorInfo.IsInnerPoint,
|
||||
ValueTypePoint = fullyCreatedConnectorInfo.ValueTypePoint,
|
||||
ConnectorValue = fullyCreatedConnectorInfo.ConnectorValue
|
||||
};
|
||||
this.Connectors.Add(connector);
|
||||
}
|
||||
this.OrderNumber = item.OrderNumber;
|
||||
this.LogicalType = item.LogicalType;
|
||||
this.Value = item.Value;
|
||||
this.IsEnabled = item.IsEnabled;
|
||||
}
|
||||
|
||||
[XmlArray]
|
||||
public List<ConnectorItem> Connectors { get; set; }
|
||||
|
||||
[XmlAttribute]
|
||||
public int OrderNumber { get; set; }
|
||||
|
||||
[XmlAttribute]
|
||||
public double Value { get; set; }
|
||||
|
||||
[XmlAttribute]
|
||||
public LogicalType LogicalType { get; set; }
|
||||
|
||||
[XmlAttribute]
|
||||
public bool IsEnabled { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
51
Util.DiagramDesigner/Models/MediaDesignerItem.cs
Normal file
51
Util.DiagramDesigner/Models/MediaDesignerItem.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public class MediaDesignerItem : DesignerItemBase
|
||||
{
|
||||
public MediaDesignerItem()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public MediaDesignerItem(GifImageItemViewModel item) : base(item)
|
||||
{
|
||||
Connectors = new List<ConnectorItem>();
|
||||
foreach (var fullyCreatedConnectorInfo in item.Connectors)
|
||||
{
|
||||
ConnectorItem connector = new ConnectorItem()
|
||||
{
|
||||
XRatio = fullyCreatedConnectorInfo.XRatio,
|
||||
YRatio = fullyCreatedConnectorInfo.YRatio,
|
||||
ConnectorWidth = fullyCreatedConnectorInfo.ConnectorWidth,
|
||||
ConnectorHeight = fullyCreatedConnectorInfo.ConnectorHeight,
|
||||
Orientation = fullyCreatedConnectorInfo.Orientation
|
||||
};
|
||||
Connectors.Add(connector);
|
||||
}
|
||||
}
|
||||
|
||||
public MediaDesignerItem(MediaItemViewModel item) : base(item)
|
||||
{
|
||||
Connectors = new List<ConnectorItem>();
|
||||
foreach (var fullyCreatedConnectorInfo in item.Connectors)
|
||||
{
|
||||
ConnectorItem connector = new ConnectorItem()
|
||||
{
|
||||
XRatio = fullyCreatedConnectorInfo.XRatio,
|
||||
YRatio = fullyCreatedConnectorInfo.YRatio,
|
||||
ConnectorWidth = fullyCreatedConnectorInfo.ConnectorWidth,
|
||||
ConnectorHeight = fullyCreatedConnectorInfo.ConnectorHeight,
|
||||
Orientation = fullyCreatedConnectorInfo.Orientation
|
||||
};
|
||||
Connectors.Add(connector);
|
||||
}
|
||||
}
|
||||
|
||||
[XmlArray]
|
||||
public List<ConnectorItem> Connectors { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
485
Util.DiagramDesigner/Models/SelectableDesignerItemBase.cs
Normal file
485
Util.DiagramDesigner/Models/SelectableDesignerItemBase.cs
Normal file
@@ -0,0 +1,485 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
|
||||
public abstract class SelectableDesignerItemBase
|
||||
{
|
||||
public SelectableDesignerItemBase()
|
||||
{
|
||||
ColorItem = new ColorItem() { LineColor = new ColorObjectItem(), FillColor = new ColorObjectItem() };
|
||||
FontItem = new FontItem();
|
||||
}
|
||||
|
||||
public SelectableDesignerItemBase(Guid id, int zIndex, bool isGroup, Guid parentId, IColorViewModel colorViewModel, IFontViewModel fontViewModel)
|
||||
{
|
||||
this.Id = id;
|
||||
this.ZIndex = zIndex;
|
||||
this.IsGroup = isGroup;
|
||||
this.ParentId = parentId;
|
||||
|
||||
|
||||
ColorItem = CopyHelper.Mapper<ColorItem>(colorViewModel);
|
||||
FontItem = CopyHelper.Mapper<FontItem, IFontViewModel>(fontViewModel);
|
||||
}
|
||||
|
||||
public SelectableDesignerItemBase(SelectableDesignerItemViewModelBase viewmodel)
|
||||
{
|
||||
this.Id = viewmodel.Id;
|
||||
this.ZIndex = viewmodel.ZIndex;
|
||||
this.IsGroup = viewmodel.IsGroup;
|
||||
this.ParentId = viewmodel.ParentId;
|
||||
this.Text = viewmodel.Text;
|
||||
|
||||
ColorItem = CopyHelper.Mapper<ColorItem>(viewmodel.ColorViewModel);
|
||||
FontItem = CopyHelper.Mapper<FontItem, IFontViewModel>(viewmodel.FontViewModel);
|
||||
}
|
||||
|
||||
[XmlAttribute]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
[XmlAttribute]
|
||||
public int ZIndex { get; set; }
|
||||
|
||||
[XmlAttribute]
|
||||
public bool IsGroup { get; set; }
|
||||
|
||||
[XmlAttribute]
|
||||
public Guid ParentId { get; set; }
|
||||
|
||||
[XmlAttribute]
|
||||
public string Text { get; set; }
|
||||
|
||||
[XmlElement]
|
||||
public ColorItem ColorItem { get; set; }
|
||||
|
||||
[XmlElement]
|
||||
public FontItem FontItem { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class ColorItem : IColorViewModel
|
||||
{
|
||||
[XmlIgnore]
|
||||
public IColorObject LineColor { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
[XmlElement("LineColor")]
|
||||
public ColorObjectItem XmlLineColor
|
||||
{
|
||||
get
|
||||
{
|
||||
return LineColor as ColorObjectItem;
|
||||
}
|
||||
set
|
||||
{
|
||||
LineColor = value;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlIgnore]
|
||||
public IColorObject FillColor { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
[XmlElement("FillColor")]
|
||||
public ColorObjectItem XmlFillColor
|
||||
{
|
||||
get
|
||||
{
|
||||
return FillColor as ColorObjectItem;
|
||||
}
|
||||
set
|
||||
{
|
||||
FillColor = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[XmlIgnore]
|
||||
public Color ShadowColor { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
[XmlElement("ShadowColor")]
|
||||
public string XmlShadowColor
|
||||
{
|
||||
get
|
||||
{
|
||||
return SerializeHelper.SerializeColor(ShadowColor);
|
||||
}
|
||||
set
|
||||
{
|
||||
ShadowColor = SerializeHelper.DeserializeColor(value);
|
||||
}
|
||||
}
|
||||
|
||||
[XmlAttribute]
|
||||
public double LineWidth { get; set; }
|
||||
|
||||
[XmlAttribute]
|
||||
public ArrowPathStyle LeftArrowPathStyle { get; set; }
|
||||
|
||||
[XmlAttribute]
|
||||
public ArrowPathStyle RightArrowPathStyle { get; set; }
|
||||
|
||||
[XmlAttribute]
|
||||
public ArrowSizeStyle LeftArrowSizeStyle { get; set; }
|
||||
|
||||
[XmlAttribute]
|
||||
public ArrowSizeStyle RightArrowSizeStyle { get; set; }
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
}
|
||||
|
||||
[XmlInclude(typeof(FontItem))]
|
||||
public class FontItem : IFontViewModel
|
||||
{
|
||||
[XmlIgnore]
|
||||
public FontWeight FontWeight { get; set; }
|
||||
[XmlIgnore]
|
||||
public FontStyle FontStyle { get; set; }
|
||||
[XmlIgnore]
|
||||
public FontStretch FontStretch { get; set; }
|
||||
[XmlAttribute]
|
||||
public bool Underline { get; set; }
|
||||
[XmlAttribute]
|
||||
public bool Strikethrough { get; set; }
|
||||
[XmlAttribute]
|
||||
public bool OverLine { get; set; }
|
||||
|
||||
[XmlIgnore]
|
||||
public Color FontColor { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
[XmlElement("FontColor")]
|
||||
public string XmlFontColor
|
||||
{
|
||||
get
|
||||
{
|
||||
return SerializeHelper.SerializeColor(FontColor);
|
||||
}
|
||||
set
|
||||
{
|
||||
FontColor = SerializeHelper.DeserializeColor(value);
|
||||
}
|
||||
}
|
||||
|
||||
[XmlIgnore]
|
||||
public string FontFamily { get; set; }
|
||||
|
||||
[XmlIgnore]
|
||||
public double FontSize { get; set; }
|
||||
|
||||
|
||||
[XmlIgnore]
|
||||
public System.Drawing.Font FontObject
|
||||
{
|
||||
get
|
||||
{
|
||||
var xmlFontStyle = System.Drawing.FontStyle.Regular;
|
||||
if (FontStyle == FontStyles.Italic)
|
||||
{
|
||||
xmlFontStyle |= System.Drawing.FontStyle.Italic;
|
||||
}
|
||||
if (FontWeight == FontWeights.Bold)
|
||||
{
|
||||
xmlFontStyle |= System.Drawing.FontStyle.Bold;
|
||||
}
|
||||
return new System.Drawing.Font(FontFamily, (float)FontSize, xmlFontStyle);
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
FontFamily = value.FontFamily.Name;
|
||||
FontSize = value.Size;
|
||||
var xmlFontStyle = value.Style;
|
||||
if ((xmlFontStyle & System.Drawing.FontStyle.Italic) == System.Drawing.FontStyle.Italic)
|
||||
{
|
||||
FontStyle = FontStyles.Italic;
|
||||
}
|
||||
else
|
||||
{
|
||||
FontStyle = FontStyles.Normal;
|
||||
}
|
||||
if ((xmlFontStyle & System.Drawing.FontStyle.Bold) == System.Drawing.FontStyle.Bold)
|
||||
{
|
||||
FontWeight = FontWeights.Bold;
|
||||
}
|
||||
else
|
||||
{
|
||||
FontWeight = FontWeights.Regular;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
[XmlElement("FontObject")]
|
||||
public XmlFont XmlFontObject
|
||||
{
|
||||
get
|
||||
{
|
||||
return SerializeHelper.SerializeFont(FontObject);
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
FontObject = SerializeHelper.DeserializeFont(value);
|
||||
}
|
||||
}
|
||||
|
||||
[XmlIgnore]
|
||||
public Color TextEffectColor { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
[XmlElement("TextEffectColor")]
|
||||
public string XmlTextEffectColor
|
||||
{
|
||||
get
|
||||
{
|
||||
return SerializeHelper.SerializeColor(TextEffectColor);
|
||||
}
|
||||
set
|
||||
{
|
||||
TextEffectColor = SerializeHelper.DeserializeColor(value);
|
||||
}
|
||||
}
|
||||
|
||||
[XmlIgnore]
|
||||
public Color HighlightColor { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
[XmlElement("HighlightColor")]
|
||||
public string XmlHighlightColor
|
||||
{
|
||||
get
|
||||
{
|
||||
return SerializeHelper.SerializeColor(HighlightColor);
|
||||
}
|
||||
set
|
||||
{
|
||||
HighlightColor = SerializeHelper.DeserializeColor(value);
|
||||
}
|
||||
}
|
||||
|
||||
[XmlAttribute]
|
||||
public FontCase FontCase { get; set; }
|
||||
[XmlAttribute]
|
||||
public HorizontalAlignment HorizontalAlignment { get; set; }
|
||||
[XmlAttribute]
|
||||
public VerticalAlignment VerticalAlignment { get; set; }
|
||||
[XmlAttribute]
|
||||
public double LineHeight { get; set; }
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
}
|
||||
|
||||
public class SerializeHelper
|
||||
{
|
||||
public static string SerializeColor(Color color)
|
||||
{
|
||||
return string.Format("{0}:{1}:{2}:{3}", color.A, color.R, color.G, color.B);
|
||||
}
|
||||
|
||||
public static Color DeserializeColor(string color)
|
||||
{
|
||||
byte a, r, g, b;
|
||||
string[] pieces = color.Split(new char[] { ':' });
|
||||
a = byte.Parse(pieces[0]);
|
||||
r = byte.Parse(pieces[1]);
|
||||
g = byte.Parse(pieces[2]);
|
||||
b = byte.Parse(pieces[3]);
|
||||
return Color.FromArgb(a, r, g, b);
|
||||
}
|
||||
|
||||
public static GradientStop DeserializeGradientStop(string str)
|
||||
{
|
||||
var strList = str.Split('-');
|
||||
return new GradientStop(DeserializeColor(strList[0]), double.Parse(strList[1]));
|
||||
}
|
||||
|
||||
public static string SerializeColorList(IEnumerable<Color> colors)
|
||||
{
|
||||
return string.Join("-", colors.Select(color => string.Format("{0}:{1}:{2}:{3}", color.A, color.R, color.G, color.B)));
|
||||
}
|
||||
|
||||
public static List<Color> DeserializeColorList(string colorstring)
|
||||
{
|
||||
List<Color> colorlist = new List<Color>();
|
||||
var colors = colorstring.Split('-');
|
||||
foreach (var color in colors)
|
||||
{
|
||||
byte a, r, g, b;
|
||||
string[] pieces = color.Split(new char[] { ':' });
|
||||
a = byte.Parse(pieces[0]);
|
||||
r = byte.Parse(pieces[1]);
|
||||
g = byte.Parse(pieces[2]);
|
||||
b = byte.Parse(pieces[3]);
|
||||
colorlist.Add(Color.FromArgb(a, r, g, b));
|
||||
}
|
||||
return colorlist;
|
||||
}
|
||||
|
||||
public static XmlFont SerializeFont(System.Drawing.Font font)
|
||||
{
|
||||
return new XmlFont(font);
|
||||
}
|
||||
|
||||
public static System.Drawing.Font DeserializeFont(XmlFont font)
|
||||
{
|
||||
return font.ToFont();
|
||||
}
|
||||
|
||||
public static string SerializePoint(Point point)
|
||||
{
|
||||
return string.Format("{0},{1}", point.X, point.Y);
|
||||
}
|
||||
|
||||
public static Point DeserializePoint(string point)
|
||||
{
|
||||
string[] pieces = point.Split(new char[] { ',' });
|
||||
return new Point(double.Parse(pieces[0]), double.Parse(pieces[1]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public struct XmlFont
|
||||
{
|
||||
public string FontFamily;
|
||||
public System.Drawing.GraphicsUnit GraphicsUnit;
|
||||
public float Size;
|
||||
public System.Drawing.FontStyle Style;
|
||||
|
||||
public XmlFont(System.Drawing.Font f)
|
||||
{
|
||||
FontFamily = f.FontFamily.Name;
|
||||
GraphicsUnit = f.Unit;
|
||||
Size = f.Size;
|
||||
Style = f.Style;
|
||||
}
|
||||
|
||||
public System.Drawing.Font ToFont()
|
||||
{
|
||||
return new System.Drawing.Font(FontFamily, Size, Style, GraphicsUnit);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class ColorObjectItem : IColorObject
|
||||
{
|
||||
|
||||
[XmlAttribute]
|
||||
public BrushType BrushType { get; set; }
|
||||
|
||||
[XmlIgnore]
|
||||
public Color Color { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
[XmlElement("FillColor")]
|
||||
public string XmlFillColor
|
||||
{
|
||||
get
|
||||
{
|
||||
return SerializeHelper.SerializeColor(Color);
|
||||
}
|
||||
set
|
||||
{
|
||||
Color = SerializeHelper.DeserializeColor(value);
|
||||
}
|
||||
}
|
||||
|
||||
[XmlIgnore]
|
||||
public ObservableCollection<GradientStop> GradientStop { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
[XmlArray("GradientStop")]
|
||||
public List<string> XmlGradientStop
|
||||
{
|
||||
get
|
||||
{
|
||||
return GradientStop?.Select(p => SerializeHelper.SerializeColor(p.Color) + "-" + p.Offset).ToList();
|
||||
}
|
||||
set
|
||||
{
|
||||
GradientStop = new ObservableCollection<GradientStop>(value?.Select(p => SerializeHelper.DeserializeGradientStop(p)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
[XmlIgnore]
|
||||
public IEnumerable<double> Offset { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
[XmlArray("Offset")]
|
||||
public List<double> XmlOffset
|
||||
{
|
||||
get
|
||||
{
|
||||
return Offset?.ToList();
|
||||
}
|
||||
set
|
||||
{
|
||||
Offset = value;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlAttribute]
|
||||
public string Image { get; set; }
|
||||
|
||||
[XmlAttribute]
|
||||
public int SubType { get; set; }
|
||||
|
||||
[XmlIgnore]
|
||||
public Point StartPoint { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
[XmlAttribute("StartPoint")]
|
||||
public string XmlStartPoint
|
||||
{
|
||||
get
|
||||
{
|
||||
return SerializeHelper.SerializePoint(StartPoint);
|
||||
}
|
||||
set
|
||||
{
|
||||
StartPoint = SerializeHelper.DeserializePoint(value);
|
||||
}
|
||||
}
|
||||
|
||||
[XmlIgnore]
|
||||
public Point EndPoint { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
[XmlAttribute("EndPoint")]
|
||||
public string XmlEndPoint
|
||||
{
|
||||
get
|
||||
{
|
||||
return SerializeHelper.SerializePoint(EndPoint);
|
||||
}
|
||||
set
|
||||
{
|
||||
EndPoint = SerializeHelper.DeserializePoint(value);
|
||||
}
|
||||
}
|
||||
|
||||
[XmlAttribute]
|
||||
public double Opacity { get; set; }
|
||||
[XmlAttribute]
|
||||
public LinearOrientation LinearOrientation { get; set; }
|
||||
[XmlAttribute]
|
||||
public RadialOrientation RadialOrientation { get; set; }
|
||||
[XmlAttribute]
|
||||
public int Angle { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
23
Util.DiagramDesigner/Models/TextDesignerItem.cs
Normal file
23
Util.DiagramDesigner/Models/TextDesignerItem.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using Util.DiagramDesigner;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public class TextDesignerItem : DesignerItemBase
|
||||
{
|
||||
public TextDesignerItem()
|
||||
{
|
||||
|
||||
}
|
||||
public TextDesignerItem(TextDesignerItemViewModel item) : base(item)
|
||||
{
|
||||
this.Text = item.Text;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
25
Util.DiagramDesigner/Paths/ArrowPathData.cs
Normal file
25
Util.DiagramDesigner/Paths/ArrowPathData.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public class ArrowPathData
|
||||
{
|
||||
public static readonly List<string> Arrow = new List<string>()
|
||||
{
|
||||
"",
|
||||
"M0,10 L5,0 10,10 z",
|
||||
"M832 664c0 10.752-3.968 20.096-11.904 28.096C812.096 700.096 802.752 704 792 704l-560 0c-10.816 0-20.16-3.904-28.096-11.904C195.904 684.096 192 674.752 192 664s3.904-20.096 11.904-28.096l280-280C491.84 348.032 501.184 344 512 344c10.752 0 20.096 3.968 28.096 11.904l280 280C828.032 643.904 832 653.248 832 664z",
|
||||
"M691.626667 682.666667H332.373333a75.093333 75.093333 0 0 1-67.84-42.666667 89.6 89.6 0 0 1 11.093334-94.293333l179.626666-217.6a75.093333 75.093333 0 0 1 113.493334 0l179.626666 217.6A89.6 89.6 0 0 1 759.466667 640a75.093333 75.093333 0 0 1-67.84 42.666667z",
|
||||
"M171.64288 701.41952a47.18592 47.18592 0 0 1 4.11648-57.344l276.70528-310.12864a79.60576 79.60576 0 0 1 119.05024 0l276.72576 310.10816a47.18592 47.18592 0 0 1 3.072 58.83904c-11.30496 15.29856-32.768 18.45248-47.9232 7.04512l-255.488-192.14336a59.65824 59.65824 0 0 0-71.80288 0l-255.488 192.14336a34.05824 34.05824 0 0 1-48.9472-8.54016z",
|
||||
"M119.466667 827.733333L512 435.2l392.533333 392.533333 119.466667-119.466666-512-512-512 512z",
|
||||
"M957.44 772.813L509.952 391.066 66.97 772.608 0 694.886 509.542 256 1024 694.784z",
|
||||
"M828.47744 660.7872a81.7152 81.7152 0 0 1-62.48448 28.89728 81.73568 81.73568 0 0 1-52.98176-19.47648l-172.46208-146.45248-172.4416 146.45248a81.94048 81.94048 0 0 1-106.06592-124.86656l225.4848-191.50848a81.89952 81.89952 0 0 1 106.06592 0l225.4848 191.50848a81.85856 81.85856 0 0 1 9.40032 115.44576z",
|
||||
"M256.917333 780.288c-40.725333 40.405333-106.645333 40.512-147.264 0.192l-36.373333-36.096a103.36 103.36 0 0 1 0.085333-146.944l350.421334-347.754667a125.290667 125.290667 0 0 1 176.490666 0l350.4 347.754667a103.466667 103.466667 0 0 1 0.085334 146.944l-36.352 36.096c-40.682667 40.362667-106.56 40.192-147.264-0.192L512.021333 527.104 256.917333 780.288z m225.066667-343.594667a42.666667 42.666667 0 0 1 60.096 0l285.184 283.029334a19.328 19.328 0 0 0 27.029333 0.192l36.352-36.096a18.154667 18.154667 0 0 0-0.064-25.813334L540.16 310.250667a39.957333 39.957333 0 0 0-56.256 0L133.482667 658.005333a18.026667 18.026667 0 0 0-0.085334 25.813334l36.373334 36.096a19.349333 19.349333 0 0 0 27.029333-0.192L481.962667 436.693333z",
|
||||
"M67.969 562.046c0 23.955 19.441 43.396 43.396 43.396 10.773 0 20.33-4.346 27.937-10.86l0.425 0.425 2.235-2.235c0.044-0.044 0.067-0.063 0.112-0.106l358.336-358.338c6.256-6.239 16.377-6.239 22.61 0l360.685 360.679 0.658-0.659c7.647 6.685 17.356 11.093 28.3 11.093 23.935 0 43.374-19.441 43.374-43.396 0-15.289-8.389-28.084-20.355-35.812-0.724-1.344-0.576-2.983-1.705-4.112l-410.958-410.948c-6.234-6.244-16.354-6.244-22.61 0l-410.95 410.949c-1.279 1.279-1.172 3.108-1.916 4.641-11.522 7.794-19.571 20.336-19.571 35.283zM67.969 874.116c0 23.955 19.441 43.394 43.396 43.394 10.773 0 20.33-4.342 27.937-10.855l0.425 0.425 2.235-2.235c0.044-0.045 0.067-0.065 0.112-0.109l358.336-358.339c6.256-6.239 16.377-6.239 22.61 0l360.685 360.684 0.658-0.66c7.647 6.685 17.356 11.091 28.3 11.091 23.935 0 43.374-19.439 43.374-43.394 0-15.289-8.389-28.087-20.355-35.815-0.724-1.341-0.576-2.98-1.705-4.109l-410.958-410.951c-6.234-6.239-16.354-6.239-22.61 0l-410.95 410.953c-1.279 1.277-1.172 3.107-1.916 4.641-11.522 7.794-19.571 20.334-19.571 35.282z",
|
||||
"M548.010667 233.088c-15.658667-24.576-56.32-24.576-72.021334 0l-298.666666 469.333333a42.794667 42.794667 0 0 0-1.408 43.477334c7.509333 13.610667 21.845333 22.101333 37.418666 22.101333h597.333334a42.709333 42.709333 0 0 0 36.010666-65.621333l-298.666666-469.290667zM291.029333 682.666667L512 335.488 732.970667 682.666667H291.029333z",
|
||||
"M512.1 511.2m-447.3 0a447.3 447.3 0 1 0 894.6 0 447.3 447.3 0 1 0-894.6 0Z",
|
||||
};
|
||||
}
|
||||
}
|
||||
36
Util.DiagramDesigner/Paths/StrokeDashArray.cs
Normal file
36
Util.DiagramDesigner/Paths/StrokeDashArray.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public class StrokeDashArray
|
||||
{
|
||||
public static readonly List<DoubleCollection> Dash = new List<DoubleCollection>
|
||||
{
|
||||
new DoubleCollection() { 1, 0 },
|
||||
new DoubleCollection() { 8, 4 },
|
||||
new DoubleCollection() { 1, 4 },
|
||||
new DoubleCollection() { 8, 4, 2, 4 },
|
||||
new DoubleCollection() { 8, 4, 2, 4, 2, 4 },
|
||||
new DoubleCollection() { 8, 4, 8, 4, 2, 4 },
|
||||
new DoubleCollection() { 18, 4, 4, 4 },
|
||||
new DoubleCollection() { 18, 4, 4, 4, 4, 4 },
|
||||
new DoubleCollection() { 4, 4 },
|
||||
new DoubleCollection() { 2, 2 },
|
||||
new DoubleCollection() { 5, 2, 2, 2 },
|
||||
new DoubleCollection() { 5, 2, 2, 2, 2, 2 },
|
||||
new DoubleCollection() { 10, 4, 4, 4 },
|
||||
new DoubleCollection() { 10, 4, 4, 4, 4, 4 },
|
||||
new DoubleCollection() { 16, 8 },
|
||||
new DoubleCollection() { 2, 8 },
|
||||
new DoubleCollection() { 16, 8, 2, 8 },
|
||||
new DoubleCollection() { 16, 8, 2, 8, 2, 8 },
|
||||
new DoubleCollection() { 16, 8, 16, 8, 2, 8 },
|
||||
new DoubleCollection() { 40, 8, 8, 8 },
|
||||
new DoubleCollection() { 40, 8, 8, 8, 8, 8 },
|
||||
new DoubleCollection() { 4, 2 },
|
||||
};
|
||||
}
|
||||
}
|
||||
16
Util.DiagramDesigner/Properties/AssemblyInfo.cs
Normal file
16
Util.DiagramDesigner/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Markup;
|
||||
|
||||
[assembly: ThemeInfo(
|
||||
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
|
||||
//(used if a resource is not found in the page,
|
||||
// or application resource dictionaries)
|
||||
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
|
||||
//(used if a resource is not found in the page,
|
||||
// app, or any theme specific resource dictionaries)
|
||||
)]
|
||||
|
||||
[assembly: XmlnsDefinition("https://astudio.github.io/diagram", "Util.DiagramDesigner")]
|
||||
[assembly: XmlnsDefinition("https://astudio.github.io/diagram", "Util.DiagramDesigner.Controls")]
|
||||
|
||||
[assembly: XmlnsPrefix("https://astudio.github.io/diagram", "dd")]
|
||||
69
Util.DiagramDesigner/Resources/Styles/DesignerItems.xaml
Normal file
69
Util.DiagramDesigner/Resources/Styles/DesignerItems.xaml
Normal file
@@ -0,0 +1,69 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:s="clr-namespace:Util.DiagramDesigner"
|
||||
xmlns:c="clr-namespace:Util.DiagramDesigner.Controls">
|
||||
|
||||
|
||||
<!-- Connector Style -->
|
||||
<Style TargetType="{x:Type s:Connector}">
|
||||
<Setter Property="Width"
|
||||
Value="8" />
|
||||
<Setter Property="Height"
|
||||
Value="8" />
|
||||
<Setter Property="Cursor"
|
||||
Value="Cross" />
|
||||
<Setter Property="SnapsToDevicePixels"
|
||||
Value="true" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type s:Connector}">
|
||||
<Grid>
|
||||
<!-- transparent extra space makes connector easier to hit -->
|
||||
<Rectangle Fill="Transparent"
|
||||
Margin="-2" />
|
||||
<Rectangle Fill="Lavender"
|
||||
StrokeThickness="1"
|
||||
Stroke="#AA000080" />
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- ConnectorDecoratorTemplate Default Template -->
|
||||
<ControlTemplate x:Key="ConnectorDecoratorTemplate"
|
||||
TargetType="{x:Type Control}">
|
||||
<Grid Margin="-5">
|
||||
<s:Connector x:Name="Left"
|
||||
Orientation="Left"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Left" />
|
||||
<s:Connector x:Name="Top"
|
||||
Orientation="Top"
|
||||
VerticalAlignment="Top"
|
||||
HorizontalAlignment="Center" />
|
||||
<s:Connector x:Name="Right"
|
||||
Orientation="Right"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Right" />
|
||||
<s:Connector x:Name="Bottom"
|
||||
Orientation="Bottom"
|
||||
VerticalAlignment="Bottom"
|
||||
HorizontalAlignment="Center" />
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
|
||||
|
||||
<!-- DragThumb Default Template -->
|
||||
<Style TargetType="{x:Type c:DragThumb}">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type c:DragThumb}">
|
||||
<Rectangle Fill="Transparent" />
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
|
||||
</ResourceDictionary>
|
||||
117
Util.DiagramDesigner/Resources/Styles/Expander.xaml
Normal file
117
Util.DiagramDesigner/Resources/Styles/Expander.xaml
Normal file
@@ -0,0 +1,117 @@
|
||||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
|
||||
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="Shared.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<!-- SimpleStyles: Expander -->
|
||||
|
||||
<ControlTemplate x:Key="ExpanderToggleButton" TargetType="ToggleButton">
|
||||
<Border
|
||||
Name="Border"
|
||||
CornerRadius="2,0,0,0"
|
||||
Background="Transparent"
|
||||
BorderBrush="{StaticResource NormalBorderBrush}"
|
||||
BorderThickness="0,0,0,0">
|
||||
<Path
|
||||
Name="Arrow"
|
||||
Fill="{StaticResource GlyphBrush}"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Data="M 0 0 L 4 4 L 8 0 Z"/>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="ToggleButton.IsMouseOver" Value="true">
|
||||
<Setter TargetName="Border" Property="Background"
|
||||
Value="{StaticResource DarkBrush}" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsPressed" Value="true">
|
||||
<Setter TargetName="Border" Property="Background"
|
||||
Value="{StaticResource PressedBrush}" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsChecked" Value="true">
|
||||
<Setter TargetName="Arrow" Property="Data"
|
||||
Value="M 0 4 L 4 0 L 8 4 Z" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsEnabled" Value="False">
|
||||
<Setter TargetName="Border" Property="Background"
|
||||
Value="{StaticResource DisabledBackgroundBrush}" />
|
||||
<Setter TargetName="Border" Property="BorderBrush"
|
||||
Value="{StaticResource DisabledBorderBrush}" />
|
||||
<Setter Property="Foreground"
|
||||
Value="{StaticResource DisabledForegroundBrush}"/>
|
||||
<Setter TargetName="Arrow" Property="Fill"
|
||||
Value="{StaticResource DisabledForegroundBrush}" />
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
|
||||
<Style TargetType="Expander">
|
||||
<Setter Property="FontFamily" Value="SegoeUI"/>
|
||||
<Setter Property="FontSize" Value="12"/>
|
||||
<Setter Property="Foreground" Value="#4C4C4C"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Expander">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Name="ContentRow" Height="0"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Border
|
||||
Name="Border"
|
||||
Grid.Row="0"
|
||||
Background="{StaticResource LightBrush}"
|
||||
BorderBrush="{StaticResource NormalBorderBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="2,2,0,0" >
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="20" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ToggleButton
|
||||
IsChecked="{Binding Path=IsExpanded,Mode=TwoWay,
|
||||
RelativeSource={RelativeSource TemplatedParent}}"
|
||||
OverridesDefaultStyle="True"
|
||||
Template="{StaticResource ExpanderToggleButton}"
|
||||
Background="{StaticResource NormalBrush}" />
|
||||
<ContentPresenter
|
||||
Grid.Column="1"
|
||||
Margin="4"
|
||||
ContentSource="Header"
|
||||
RecognizesAccessKey="True" />
|
||||
</Grid>
|
||||
</Border>
|
||||
<Border
|
||||
Name="Content"
|
||||
Grid.Row="1"
|
||||
Background="{StaticResource WindowBackgroundBrush}"
|
||||
BorderBrush="{StaticResource SolidBorderBrush}"
|
||||
BorderThickness="1,0,1,1"
|
||||
CornerRadius="0,0,2,2" >
|
||||
<ContentPresenter Margin="4" />
|
||||
</Border>
|
||||
</Grid>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsExpanded" Value="True">
|
||||
<Setter TargetName="ContentRow" Property="Height"
|
||||
Value="{Binding ElementName=Content,Path=DesiredHeight}" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsEnabled" Value="False">
|
||||
<Setter TargetName="Border" Property="Background"
|
||||
Value="{StaticResource DisabledBackgroundBrush}" />
|
||||
<Setter TargetName="Border" Property="BorderBrush"
|
||||
Value="{StaticResource DisabledBorderBrush}" />
|
||||
<Setter Property="Foreground"
|
||||
Value="{StaticResource DisabledForegroundBrush}"/>
|
||||
</Trigger>
|
||||
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
47
Util.DiagramDesigner/Resources/Styles/GroupBox.xaml
Normal file
47
Util.DiagramDesigner/Resources/Styles/GroupBox.xaml
Normal file
@@ -0,0 +1,47 @@
|
||||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
|
||||
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="Shared.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<!-- SimpleStyles: GroupBox -->
|
||||
<Style TargetType="GroupBox">
|
||||
<Setter Property="FontFamily" Value="SegoeUI"/>
|
||||
<Setter Property="FontSize" Value="12"/>
|
||||
<Setter Property="Foreground" Value="#4C4C4C"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="GroupBox">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Border
|
||||
Grid.Row="0"
|
||||
Background="{StaticResource LightBrush}"
|
||||
BorderBrush="{StaticResource NormalBorderBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="2,2,0,0" >
|
||||
<ContentPresenter
|
||||
Margin="4"
|
||||
ContentSource="Header"
|
||||
RecognizesAccessKey="True" />
|
||||
</Border>
|
||||
<Border
|
||||
Grid.Row="1"
|
||||
Background="{TemplateBinding Background}"
|
||||
BorderBrush="{StaticResource SolidBorderBrush}"
|
||||
BorderThickness="1,0,1,1"
|
||||
CornerRadius="0,0,2,2" >
|
||||
<ContentPresenter
|
||||
Margin="4" />
|
||||
</Border>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
186
Util.DiagramDesigner/Resources/Styles/ScrollBar.xaml
Normal file
186
Util.DiagramDesigner/Resources/Styles/ScrollBar.xaml
Normal file
@@ -0,0 +1,186 @@
|
||||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
|
||||
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="Shared.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<Style x:Key="ScrollBarLineButton" TargetType="{x:Type RepeatButton}">
|
||||
<Setter Property="SnapsToDevicePixels" Value="True"/>
|
||||
<Setter Property="OverridesDefaultStyle" Value="true"/>
|
||||
<Setter Property="Focusable" Value="false"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type RepeatButton}">
|
||||
<Border
|
||||
Name="Border"
|
||||
Margin="1"
|
||||
CornerRadius="2"
|
||||
Background="{StaticResource NormalBrush}"
|
||||
BorderBrush="{StaticResource NormalBorderBrush}"
|
||||
BorderThickness="1">
|
||||
<Path
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Fill="{StaticResource GlyphBrush}"
|
||||
Data="{Binding Path=Content,RelativeSource={RelativeSource TemplatedParent}}" />
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsPressed" Value="true">
|
||||
<Setter TargetName="Border" Property="Background" Value="{StaticResource PressedBrush}" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsEnabled" Value="false">
|
||||
<Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ScrollBarPageButton" TargetType="{x:Type RepeatButton}">
|
||||
<Setter Property="SnapsToDevicePixels" Value="True"/>
|
||||
<Setter Property="OverridesDefaultStyle" Value="true"/>
|
||||
<Setter Property="IsTabStop" Value="false"/>
|
||||
<Setter Property="Focusable" Value="false"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type RepeatButton}">
|
||||
<Border Background="Transparent" />
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ScrollBarThumb" TargetType="{x:Type Thumb}">
|
||||
<Setter Property="SnapsToDevicePixels" Value="True"/>
|
||||
<Setter Property="OverridesDefaultStyle" Value="true"/>
|
||||
<Setter Property="IsTabStop" Value="false"/>
|
||||
<Setter Property="Focusable" Value="false"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type Thumb}">
|
||||
<Border
|
||||
CornerRadius="2"
|
||||
Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="1" />
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<ControlTemplate x:Key="VerticalScrollBar" TargetType="{x:Type ScrollBar}">
|
||||
<Grid >
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition MaxHeight="18"/>
|
||||
<RowDefinition Height="0.00001*"/>
|
||||
<RowDefinition MaxHeight="18"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Border
|
||||
Grid.RowSpan="3"
|
||||
CornerRadius="2"
|
||||
Background="#F0F0F0" />
|
||||
<RepeatButton
|
||||
Grid.Row="0"
|
||||
Style="{StaticResource ScrollBarLineButton}"
|
||||
Height="18"
|
||||
Command="ScrollBar.LineUpCommand"
|
||||
Content="M 0 4 L 8 4 L 4 0 Z" />
|
||||
<Track
|
||||
Name="PART_Track"
|
||||
Grid.Row="1"
|
||||
IsDirectionReversed="true">
|
||||
<Track.DecreaseRepeatButton>
|
||||
<RepeatButton
|
||||
Style="{StaticResource ScrollBarPageButton}"
|
||||
Command="ScrollBar.PageUpCommand" />
|
||||
</Track.DecreaseRepeatButton>
|
||||
<Track.Thumb>
|
||||
<Thumb
|
||||
Style="{StaticResource ScrollBarThumb}"
|
||||
Margin="1,0,1,0"
|
||||
Background="{StaticResource HorizontalNormalBrush}"
|
||||
BorderBrush="{StaticResource HorizontalNormalBorderBrush}" />
|
||||
</Track.Thumb>
|
||||
<Track.IncreaseRepeatButton>
|
||||
<RepeatButton
|
||||
Style="{StaticResource ScrollBarPageButton}"
|
||||
Command="ScrollBar.PageDownCommand" />
|
||||
</Track.IncreaseRepeatButton>
|
||||
</Track>
|
||||
<RepeatButton
|
||||
Grid.Row="3"
|
||||
Style="{StaticResource ScrollBarLineButton}"
|
||||
Height="18"
|
||||
Command="ScrollBar.LineDownCommand"
|
||||
Content="M 0 0 L 4 4 L 8 0 Z"/>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
|
||||
<ControlTemplate x:Key="HorizontalScrollBar" TargetType="{x:Type ScrollBar}">
|
||||
<Grid >
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition MaxWidth="18"/>
|
||||
<ColumnDefinition Width="0.00001*"/>
|
||||
<ColumnDefinition MaxWidth="18"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border
|
||||
Grid.ColumnSpan="3"
|
||||
CornerRadius="2"
|
||||
Background="#F0F0F0" />
|
||||
<RepeatButton
|
||||
Grid.Column="0"
|
||||
Style="{StaticResource ScrollBarLineButton}"
|
||||
Width="18"
|
||||
Command="ScrollBar.LineLeftCommand"
|
||||
Content="M 4 0 L 4 8 L 0 4 Z" />
|
||||
<Track
|
||||
Name="PART_Track"
|
||||
Grid.Column="1"
|
||||
IsDirectionReversed="False">
|
||||
<Track.DecreaseRepeatButton>
|
||||
<RepeatButton
|
||||
Style="{StaticResource ScrollBarPageButton}"
|
||||
Command="ScrollBar.PageLeftCommand" />
|
||||
</Track.DecreaseRepeatButton>
|
||||
<Track.Thumb>
|
||||
<Thumb
|
||||
Style="{StaticResource ScrollBarThumb}"
|
||||
Margin="0,1,0,1"
|
||||
Background="{StaticResource NormalBrush}"
|
||||
BorderBrush="{StaticResource NormalBorderBrush}" />
|
||||
</Track.Thumb>
|
||||
<Track.IncreaseRepeatButton>
|
||||
<RepeatButton
|
||||
Style="{StaticResource ScrollBarPageButton}"
|
||||
Command="ScrollBar.PageRightCommand" />
|
||||
</Track.IncreaseRepeatButton>
|
||||
</Track>
|
||||
<RepeatButton
|
||||
Grid.Column="3"
|
||||
Style="{StaticResource ScrollBarLineButton}"
|
||||
Width="18"
|
||||
Command="ScrollBar.LineRightCommand"
|
||||
Content="M 0 0 L 4 4 L 0 8 Z"/>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
|
||||
<Style x:Key="{x:Type ScrollBar}" TargetType="{x:Type ScrollBar}">
|
||||
<Setter Property="SnapsToDevicePixels" Value="True"/>
|
||||
<Setter Property="OverridesDefaultStyle" Value="true"/>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="Orientation" Value="Horizontal">
|
||||
<Setter Property="Width" Value="Auto"/>
|
||||
<Setter Property="Height" Value="18" />
|
||||
<Setter Property="Template" Value="{StaticResource HorizontalScrollBar}" />
|
||||
</Trigger>
|
||||
<Trigger Property="Orientation" Value="Vertical">
|
||||
<Setter Property="Width" Value="18"/>
|
||||
<Setter Property="Height" Value="Auto" />
|
||||
<Setter Property="Template" Value="{StaticResource VerticalScrollBar}" />
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
43
Util.DiagramDesigner/Resources/Styles/ScrollViewer.xaml
Normal file
43
Util.DiagramDesigner/Resources/Styles/ScrollViewer.xaml
Normal file
@@ -0,0 +1,43 @@
|
||||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
|
||||
|
||||
<!-- SimpleStyles: ScrollViewer -->
|
||||
|
||||
<Style x:Key="LeftScrollViewer" TargetType="{x:Type ScrollViewer}">
|
||||
<Setter Property="OverridesDefaultStyle" Value="True"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type ScrollViewer}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<ScrollContentPresenter Grid.Column="1"/>
|
||||
|
||||
<ScrollBar Name="PART_VerticalScrollBar"
|
||||
Value="{TemplateBinding VerticalOffset}"
|
||||
Maximum="{TemplateBinding ScrollableHeight}"
|
||||
ViewportSize="{TemplateBinding ViewportHeight}"
|
||||
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"/>
|
||||
<ScrollBar Name="PART_HorizontalScrollBar"
|
||||
Orientation="Horizontal"
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Value="{TemplateBinding HorizontalOffset}"
|
||||
Maximum="{TemplateBinding ScrollableWidth}"
|
||||
ViewportSize="{TemplateBinding ViewportWidth}"
|
||||
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"/>
|
||||
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
118
Util.DiagramDesigner/Resources/Styles/Shared.xaml
Normal file
118
Util.DiagramDesigner/Resources/Styles/Shared.xaml
Normal file
@@ -0,0 +1,118 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
|
||||
<!-- Fill Brushes -->
|
||||
|
||||
<LinearGradientBrush x:Key="NormalBrush" StartPoint="0,0" EndPoint="0,1">
|
||||
<GradientBrush.GradientStops>
|
||||
<GradientStopCollection>
|
||||
<GradientStop Color="#FFF" Offset="0.0"/>
|
||||
<GradientStop Color="#CCC" Offset="1.0"/>
|
||||
</GradientStopCollection>
|
||||
</GradientBrush.GradientStops>
|
||||
</LinearGradientBrush>
|
||||
|
||||
<LinearGradientBrush x:Key="HorizontalNormalBrush" StartPoint="0,0" EndPoint="1,0">
|
||||
<GradientBrush.GradientStops>
|
||||
<GradientStopCollection>
|
||||
<GradientStop Color="#FFF" Offset="0.0"/>
|
||||
<GradientStop Color="#CCC" Offset="1.0"/>
|
||||
</GradientStopCollection>
|
||||
</GradientBrush.GradientStops>
|
||||
</LinearGradientBrush>
|
||||
|
||||
<LinearGradientBrush x:Key="LightBrush" StartPoint="0,0" EndPoint="0,1">
|
||||
<GradientBrush.GradientStops>
|
||||
<GradientStopCollection>
|
||||
<GradientStop Color="#FFF" Offset="0.0"/>
|
||||
<GradientStop Color="#EEE" Offset="1.0"/>
|
||||
</GradientStopCollection>
|
||||
</GradientBrush.GradientStops>
|
||||
</LinearGradientBrush>
|
||||
|
||||
<LinearGradientBrush x:Key="HorizontalLightBrush" StartPoint="0,0" EndPoint="1,0">
|
||||
<GradientBrush.GradientStops>
|
||||
<GradientStopCollection>
|
||||
<GradientStop Color="#FFF" Offset="0.0"/>
|
||||
<GradientStop Color="#EEE" Offset="1.0"/>
|
||||
</GradientStopCollection>
|
||||
</GradientBrush.GradientStops>
|
||||
</LinearGradientBrush>
|
||||
|
||||
<LinearGradientBrush x:Key="DarkBrush" StartPoint="0,0" EndPoint="0,1">
|
||||
<GradientBrush.GradientStops>
|
||||
<GradientStopCollection>
|
||||
<GradientStop Color="#FFF" Offset="0.0"/>
|
||||
<GradientStop Color="#AAA" Offset="1.0"/>
|
||||
</GradientStopCollection>
|
||||
</GradientBrush.GradientStops>
|
||||
</LinearGradientBrush>
|
||||
|
||||
<LinearGradientBrush x:Key="PressedBrush" StartPoint="0,0" EndPoint="0,1">
|
||||
<GradientBrush.GradientStops>
|
||||
<GradientStopCollection>
|
||||
<GradientStop Color="#BBB" Offset="0.0"/>
|
||||
<GradientStop Color="#EEE" Offset="0.1"/>
|
||||
<GradientStop Color="#EEE" Offset="0.9"/>
|
||||
<GradientStop Color="#FFF" Offset="1.0"/>
|
||||
</GradientStopCollection>
|
||||
</GradientBrush.GradientStops>
|
||||
</LinearGradientBrush>
|
||||
|
||||
<SolidColorBrush x:Key="DisabledForegroundBrush" Color="#888" />
|
||||
|
||||
<SolidColorBrush x:Key="DisabledBackgroundBrush" Color="#EEE" />
|
||||
|
||||
<SolidColorBrush x:Key="WindowBackgroundBrush" Color="#FFF" />
|
||||
|
||||
<SolidColorBrush x:Key="SelectedBackgroundBrush" Color="#DDD" />
|
||||
|
||||
<!-- Border Brushes -->
|
||||
|
||||
<LinearGradientBrush x:Key="NormalBorderBrush" StartPoint="0,0" EndPoint="0,1">
|
||||
<GradientBrush.GradientStops>
|
||||
<GradientStopCollection>
|
||||
<GradientStop Color="#CCC" Offset="0.0"/>
|
||||
<GradientStop Color="#444" Offset="1.0"/>
|
||||
</GradientStopCollection>
|
||||
</GradientBrush.GradientStops>
|
||||
</LinearGradientBrush>
|
||||
|
||||
<LinearGradientBrush x:Key="HorizontalNormalBorderBrush" StartPoint="0,0" EndPoint="1,0">
|
||||
<GradientBrush.GradientStops>
|
||||
<GradientStopCollection>
|
||||
<GradientStop Color="#CCC" Offset="0.0"/>
|
||||
<GradientStop Color="#444" Offset="1.0"/>
|
||||
</GradientStopCollection>
|
||||
</GradientBrush.GradientStops>
|
||||
</LinearGradientBrush>
|
||||
|
||||
<LinearGradientBrush x:Key="DefaultedBorderBrush" StartPoint="0,0" EndPoint="0,1">
|
||||
<GradientBrush.GradientStops>
|
||||
<GradientStopCollection>
|
||||
<GradientStop Color="#777" Offset="0.0"/>
|
||||
<GradientStop Color="#000" Offset="1.0"/>
|
||||
</GradientStopCollection>
|
||||
</GradientBrush.GradientStops>
|
||||
</LinearGradientBrush>
|
||||
|
||||
<LinearGradientBrush x:Key="PressedBorderBrush" StartPoint="0,0" EndPoint="0,1">
|
||||
<GradientBrush.GradientStops>
|
||||
<GradientStopCollection>
|
||||
<GradientStop Color="#444" Offset="0.0"/>
|
||||
<GradientStop Color="#888" Offset="1.0"/>
|
||||
</GradientStopCollection>
|
||||
</GradientBrush.GradientStops>
|
||||
</LinearGradientBrush>
|
||||
|
||||
<SolidColorBrush x:Key="DisabledBorderBrush" Color="#AAA" />
|
||||
|
||||
<SolidColorBrush x:Key="SolidBorderBrush" Color="#888" />
|
||||
|
||||
<SolidColorBrush x:Key="LightBorderBrush" Color="#AAA" />
|
||||
|
||||
<SolidColorBrush x:Key="GlyphBrush" Color="#444" />
|
||||
|
||||
<SolidColorBrush x:Key="LightColorBrush" Color="#DDD" />
|
||||
|
||||
</ResourceDictionary>
|
||||
38
Util.DiagramDesigner/Resources/Styles/ToolTip.xaml
Normal file
38
Util.DiagramDesigner/Resources/Styles/ToolTip.xaml
Normal file
@@ -0,0 +1,38 @@
|
||||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
|
||||
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="Shared.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<!-- SimpleStyles: ToolTip -->
|
||||
<Style x:Key="{x:Type ToolTip}" TargetType="ToolTip">
|
||||
<Setter Property="OverridesDefaultStyle" Value="true"/>
|
||||
<Setter Property="HasDropShadow" Value="True"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="ToolTip">
|
||||
<Border Name="Border"
|
||||
Background="{StaticResource LightBrush}"
|
||||
BorderBrush="{StaticResource SolidBorderBrush}"
|
||||
BorderThickness="1"
|
||||
Width="{TemplateBinding Width}"
|
||||
Height="{TemplateBinding Height}">
|
||||
<ContentPresenter
|
||||
Margin="4"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top" />
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="HasDropShadow" Value="true">
|
||||
<Setter TargetName="Border" Property="CornerRadius" Value="4"/>
|
||||
<Setter TargetName="Border" Property="SnapsToDevicePixels" Value="true"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
</ResourceDictionary>
|
||||
245
Util.DiagramDesigner/Resources/Styles/ZoomBox.xaml
Normal file
245
Util.DiagramDesigner/Resources/Styles/ZoomBox.xaml
Normal file
@@ -0,0 +1,245 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:s="clr-namespace:Util.DiagramDesigner">
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="Shared.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
<Style TargetType="{x:Type s:ZoomBox}">
|
||||
|
||||
<Style.Resources>
|
||||
|
||||
<VisualBrush x:Key="AlphaBrush"
|
||||
Stretch="None"
|
||||
TileMode="Tile"
|
||||
ViewportUnits="Absolute"
|
||||
Viewport="0,0,8,8">
|
||||
<VisualBrush.Visual>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="4" />
|
||||
<ColumnDefinition Width="4" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="4" />
|
||||
<RowDefinition Height="4" />
|
||||
</Grid.RowDefinitions>
|
||||
<Rectangle Fill="#EEE"
|
||||
Grid.Row="0"
|
||||
Grid.Column="0" />
|
||||
<Rectangle Fill="#AAA"
|
||||
Grid.Row="0"
|
||||
Grid.Column="1" />
|
||||
<Rectangle Fill="#AAA"
|
||||
Grid.Row="1"
|
||||
Grid.Column="0" />
|
||||
<Rectangle Fill="#EEE"
|
||||
Grid.Row="1"
|
||||
Grid.Column="1" />
|
||||
</Grid>
|
||||
</VisualBrush.Visual>
|
||||
</VisualBrush>
|
||||
|
||||
<Style x:Key="ToggleButtonStyle"
|
||||
TargetType="ToggleButton">
|
||||
<Setter Property="SnapsToDevicePixels"
|
||||
Value="true" />
|
||||
<Setter Property="OverridesDefaultStyle"
|
||||
Value="true" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="ToggleButton">
|
||||
<Border x:Name="Border"
|
||||
Background="{StaticResource NormalBrush}">
|
||||
<ContentPresenter />
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver"
|
||||
Value="true">
|
||||
<Setter TargetName="Border"
|
||||
Property="Background"
|
||||
Value="{StaticResource DarkBrush}" />
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Expander">
|
||||
<Setter Property="SnapsToDevicePixels"
|
||||
Value="true" />
|
||||
<Setter Property="OverridesDefaultStyle"
|
||||
Value="true" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Expander">
|
||||
<DockPanel>
|
||||
<ToggleButton Style="{StaticResource ToggleButtonStyle}"
|
||||
DockPanel.Dock="Top"
|
||||
IsChecked="{Binding Path=IsExpanded,Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
|
||||
HorizontalContentAlignment="Left"
|
||||
VerticalContentAlignment="Center">
|
||||
<ToggleButton.Content>
|
||||
<Grid Margin="4">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="20" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Path Grid.Column="0"
|
||||
SnapsToDevicePixels="True"
|
||||
Name="Arrow"
|
||||
Fill="{TemplateBinding Foreground}"
|
||||
Stroke="{TemplateBinding Foreground}"
|
||||
StrokeThickness="0.5"
|
||||
RenderTransformOrigin="0.5,0.5"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Data="M 0 0 L 0 8 L 5 4 Z">
|
||||
<Path.RenderTransform>
|
||||
<RotateTransform Angle="0" />
|
||||
</Path.RenderTransform>
|
||||
</Path>
|
||||
<ContentPresenter Grid.Column="1"
|
||||
Name="HeaderContent"
|
||||
ContentSource="Header" />
|
||||
</Grid>
|
||||
</ToggleButton.Content>
|
||||
</ToggleButton>
|
||||
<Border Name="Content">
|
||||
<Border.LayoutTransform>
|
||||
<ScaleTransform ScaleY="0" />
|
||||
</Border.LayoutTransform>
|
||||
<ContentPresenter Content="{TemplateBinding Content}" />
|
||||
</Border>
|
||||
</DockPanel>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="Expander.IsExpanded"
|
||||
Value="True">
|
||||
<Trigger.EnterActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetName="Content"
|
||||
Storyboard.TargetProperty="LayoutTransform.ScaleY"
|
||||
To="1"
|
||||
Duration="0:0:0.3" />
|
||||
<DoubleAnimation Storyboard.TargetName="Content"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
To="1"
|
||||
Duration="0:0:0.3" />
|
||||
<DoubleAnimation Storyboard.TargetName="Arrow"
|
||||
Storyboard.TargetProperty="(FrameworkElement.RenderTransform).(RotateTransform.Angle)"
|
||||
Duration="0:0:0.2"
|
||||
To="90"
|
||||
DecelerationRatio="1" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</Trigger.EnterActions>
|
||||
<Trigger.ExitActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetName="Content"
|
||||
Storyboard.TargetProperty="LayoutTransform.ScaleY"
|
||||
To="0"
|
||||
Duration="0:0:0.3" />
|
||||
<DoubleAnimation Storyboard.TargetName="Content"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
To="0"
|
||||
Duration="0:0:0.3" />
|
||||
<DoubleAnimation Storyboard.TargetName="Arrow"
|
||||
Storyboard.TargetProperty="(FrameworkElement.RenderTransform).(RotateTransform.Angle)"
|
||||
Duration="0:0:0.2"
|
||||
AccelerationRatio="1" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</Trigger.ExitActions>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
</Style.Resources>
|
||||
|
||||
<Setter Property="SnapsToDevicePixels"
|
||||
Value="true" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type s:ZoomBox}">
|
||||
<Border CornerRadius="1"
|
||||
BorderThickness="1"
|
||||
Background="#EEE"
|
||||
BorderBrush="DimGray">
|
||||
<Expander IsExpanded="True"
|
||||
Background="Transparent">
|
||||
<Border BorderBrush="DimGray"
|
||||
BorderThickness="0,1,0,0"
|
||||
Padding="0"
|
||||
Height="180">
|
||||
<Grid>
|
||||
<Canvas Margin="5"
|
||||
Name="PART_ZoomCanvas">
|
||||
<Canvas.Background>
|
||||
<VisualBrush Stretch="Uniform"
|
||||
Visual="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ScrollViewer.Content}" />
|
||||
</Canvas.Background>
|
||||
<Thumb Name="PART_ZoomThumb"
|
||||
Cursor="SizeAll">
|
||||
<Thumb.Style>
|
||||
<Style TargetType="Thumb">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Thumb">
|
||||
<Rectangle StrokeThickness="1"
|
||||
Stroke="Black"
|
||||
Fill="Transparent" />
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</Thumb.Style>
|
||||
</Thumb>
|
||||
</Canvas>
|
||||
</Grid>
|
||||
</Border>
|
||||
<Expander.Header>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Slider Name="PART_ZoomSlider"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center"
|
||||
Margin="0"
|
||||
Ticks="25,50,75,100,125,150,200,300,400,500"
|
||||
Minimum="25"
|
||||
Maximum="500"
|
||||
SmallChange="25"
|
||||
LargeChange="25"
|
||||
Value="100"
|
||||
MinWidth="104"
|
||||
MinHeight="21"
|
||||
IsSnapToTickEnabled="True"
|
||||
IsMoveToPointEnabled="False" />
|
||||
|
||||
<TextBlock Text="{Binding ElementName=PART_ZoomSlider, Path=Value}"
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Right"
|
||||
Margin="0,0,14,0" />
|
||||
<TextBlock Text="%"
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Right"
|
||||
Margin="1,0,2,0" />
|
||||
</Grid>
|
||||
</Expander.Header>
|
||||
</Expander>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
</ResourceDictionary>
|
||||
@@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
public class DesignerItemsControlItemStyleSelector : StyleSelector
|
||||
{
|
||||
static DesignerItemsControlItemStyleSelector()
|
||||
{
|
||||
Instance = new DesignerItemsControlItemStyleSelector();
|
||||
}
|
||||
|
||||
public static DesignerItemsControlItemStyleSelector Instance
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
|
||||
public override Style SelectStyle(object item, DependencyObject container)
|
||||
{
|
||||
ItemsControl itemsControl = ItemsControl.ItemsControlFromItemContainer(container);
|
||||
if (itemsControl == null)
|
||||
throw new InvalidOperationException("DesignerItemsControlItemStyleSelector : Could not find ItemsControl");
|
||||
|
||||
if (item is GifImageItemViewModel)
|
||||
{
|
||||
return (Style)itemsControl.FindResource("gifimageItemStyle");
|
||||
}
|
||||
|
||||
if (item is LinkPointDesignerItemViewModel)
|
||||
{
|
||||
return (Style)itemsControl.FindResource("linkpointItemStyle");
|
||||
}
|
||||
|
||||
if (item is PointDesignerItemViewModel)
|
||||
{
|
||||
return (Style)itemsControl.FindResource("pointItemStyle");
|
||||
}
|
||||
|
||||
if (item is LogicalGateItemViewModelBase)
|
||||
{
|
||||
return (Style)itemsControl.FindResource("logicalItemStyle");
|
||||
}
|
||||
|
||||
if (item is DesignerItemViewModelBase)
|
||||
{
|
||||
|
||||
return (Style)itemsControl.FindResource("designerItemStyle");
|
||||
}
|
||||
|
||||
if (item is ConnectorViewModel)
|
||||
{
|
||||
return (Style)itemsControl.FindResource("connectorItemStyle");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
204
Util.DiagramDesigner/Themes/Generic.xaml
Normal file
204
Util.DiagramDesigner/Themes/Generic.xaml
Normal file
@@ -0,0 +1,204 @@
|
||||
<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:Util.DiagramDesigner"
|
||||
xmlns:c="clr-namespace:Util.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"/>
|
||||
|
||||
<DataTemplate DataType="{x:Type s:TextDesignerItemViewModel}">
|
||||
<Grid >
|
||||
<Border Background="{Binding ColorViewModel.FillColor,Converter={StaticResource ColorBrushConverter}}" IsHitTestVisible="False"/>
|
||||
<Grid Margin="5">
|
||||
<s:TextControl s:ControlAttachProperty.Watermark="{Binding Watermark}" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate DataType="{x:Type s:ShapeDesignerItemViewModel}">
|
||||
<Grid IsHitTestVisible="False" Background="White">
|
||||
<Grid.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem Header="显示点" IsCheckable="True" IsChecked="{Binding ShowConnectors}" />
|
||||
</ContextMenu>
|
||||
</Grid.ContextMenu>
|
||||
<Control x:Name="control" />
|
||||
</Grid>
|
||||
<DataTemplate.Triggers>
|
||||
<DataTrigger Binding="{Binding DrawMode}" Value="Line">
|
||||
<Setter TargetName="control" Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate>
|
||||
<Line X1="{Binding ConnectionPoints[0].X}" Y1="{Binding ConnectionPoints[0].Y}"
|
||||
X2="{Binding ConnectionPoints[1].X}" Y2="{Binding ConnectionPoints[1].Y}"
|
||||
Stroke="{Binding ColorViewModel.LineColor,Converter={StaticResource ColorBrushConverter}}"
|
||||
StrokeThickness="{Binding ColorViewModel.LineWidth}"
|
||||
Stretch="Fill"></Line>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding DrawMode}" Value="Rectangle">
|
||||
<Setter TargetName="control" Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate>
|
||||
<Rectangle
|
||||
Stroke="{Binding ColorViewModel.LineColor,Converter={StaticResource ColorBrushConverter}}"
|
||||
StrokeThickness="{Binding ColorViewModel.LineWidth}"
|
||||
Fill="{Binding ColorViewModel.FillColor,Converter={StaticResource ColorBrushConverter}}"
|
||||
Stretch="Fill"></Rectangle>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding DrawMode}" Value="Ellipse">
|
||||
<Setter TargetName="control" Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate>
|
||||
<Ellipse
|
||||
Stroke="{Binding ColorViewModel.LineColor,Converter={StaticResource ColorBrushConverter}}"
|
||||
StrokeThickness="{Binding ColorViewModel.LineWidth}"
|
||||
Fill="{Binding ColorViewModel.FillColor,Converter={StaticResource ColorBrushConverter}}"
|
||||
Stretch="Fill"></Ellipse>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding DrawMode}" Value="Polyline">
|
||||
<Setter TargetName="control" Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate>
|
||||
<Polyline
|
||||
Points="{Binding ConnectionPoints, Converter={x:Static s:ConnectionPathConverter.Instance}}"
|
||||
Stroke="{Binding ColorViewModel.LineColor,Converter={StaticResource ColorBrushConverter}}"
|
||||
StrokeThickness="{Binding ColorViewModel.LineWidth}"
|
||||
Fill="{Binding ColorViewModel.FillColor,Converter={StaticResource ColorBrushConverter}}"
|
||||
FillRule="Nonzero"
|
||||
Stretch="Fill"></Polyline>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding DrawMode}" Value="Polygon">
|
||||
<Setter TargetName="control" Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate>
|
||||
<Polygon
|
||||
Points="{Binding ConnectionPoints, Converter={x:Static s:ConnectionPathConverter.Instance}}"
|
||||
Stroke="{Binding ColorViewModel.LineColor,Converter={StaticResource ColorBrushConverter}}"
|
||||
StrokeThickness="{Binding ColorViewModel.LineWidth}"
|
||||
Fill="{Binding ColorViewModel.FillColor,Converter={StaticResource ColorBrushConverter}}"
|
||||
FillRule="Nonzero"
|
||||
Stretch="Fill"></Polygon>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding DrawMode}" Value="DirectLine">
|
||||
<Setter TargetName="control" Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate>
|
||||
<Polyline
|
||||
Points="{Binding ConnectionPoints, Converter={x:Static s:ConnectionPathConverter.Instance}}"
|
||||
Stroke="{Binding ColorViewModel.LineColor,Converter={StaticResource ColorBrushConverter}}"
|
||||
StrokeThickness="{Binding ColorViewModel.LineWidth}"
|
||||
Fill="{Binding ColorViewModel.FillColor,Converter={StaticResource ColorBrushConverter}}"
|
||||
FillRule="Nonzero"
|
||||
Stretch="Fill"></Polyline>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</DataTrigger>
|
||||
|
||||
|
||||
</DataTemplate.Triggers>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate DataType="{x:Type s:GroupDesignerItemViewModel}">
|
||||
<Grid IsHitTestVisible="{Binding IsHitTestVisible}">
|
||||
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate DataType="{x:Type s: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" />
|
||||
</Grid>
|
||||
<DataTemplate.Triggers>
|
||||
<DataTrigger Binding="{Binding IsRunning}" Value="false">
|
||||
<Setter TargetName="PART_Image_run" Property="gif:ImageBehavior.AutoStart" Value="False" />
|
||||
</DataTrigger>
|
||||
</DataTemplate.Triggers>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate DataType="{x:Type s: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}">
|
||||
<Grid ToolTip="{Binding Icon}">
|
||||
<Grid IsHitTestVisible="False" ClipToBounds="True">
|
||||
<Image x:Name="image" Source="{Binding Icon}" Stretch="Fill"
|
||||
Margin="{Binding Object,Converter={StaticResource ClipConverter},ConverterParameter='Margin'}"
|
||||
Clip="{Binding Object,Converter={StaticResource ClipConverter},ConverterParameter='Clip'}">
|
||||
</Image>
|
||||
<Image x:Name="gif" gif:ImageBehavior.AnimatedSource="{Binding Icon}" gif:ImageBehavior.AutoStart="True" Visibility="Collapsed" Stretch="Fill"/>
|
||||
</Grid>
|
||||
<!-- PART_ResizeDecorator -->
|
||||
<Border x:Name="PART_ResizeDecorator" SnapsToDevicePixels="true" Margin="{Binding ResizeMargin,Mode=TwoWay}" Visibility="Collapsed">
|
||||
<Grid x:Name="Grid" Margin="-2">
|
||||
<c:BorderResizeThumb Height="5" Cursor="SizeAll" Margin="-3" ResizeMode="DragMargin" BorderBrush="Blue" BorderThickness="5" ResizeElement="{Binding ElementName=PART_ResizeDecorator}"
|
||||
VerticalAlignment="Top" HorizontalAlignment="Stretch"/>
|
||||
<c:BorderResizeThumb Width="5" Cursor="SizeAll" Margin="-3" ResizeMode="DragMargin" BorderBrush="Blue" BorderThickness="5" ResizeElement="{Binding ElementName=PART_ResizeDecorator}"
|
||||
VerticalAlignment="Stretch" HorizontalAlignment="Left"/>
|
||||
<c:BorderResizeThumb Width="5" Cursor="SizeAll" Margin="-3" ResizeMode="DragMargin" BorderBrush="Blue" BorderThickness="5" ResizeElement="{Binding ElementName=PART_ResizeDecorator}"
|
||||
VerticalAlignment="Stretch" HorizontalAlignment="Right"/>
|
||||
<c:BorderResizeThumb Height="5" Cursor="SizeAll" Margin="-3" ResizeMode="DragMargin" BorderBrush="Blue" BorderThickness="5" ResizeElement="{Binding ElementName=PART_ResizeDecorator}"
|
||||
VerticalAlignment="Bottom" HorizontalAlignment="Stretch"/>
|
||||
<c:BorderResizeThumb Width="5" Height="5" Cursor="SizeNS" ResizeMode="Margin" Margin="-3" ResizeElement="{Binding ElementName=PART_ResizeDecorator}"
|
||||
VerticalAlignment="Top" HorizontalAlignment="Center"/>
|
||||
<c:BorderResizeThumb Width="5" Height="5" Cursor="SizeWE" ResizeMode="Margin" Margin="-3" ResizeElement="{Binding ElementName=PART_ResizeDecorator}"
|
||||
VerticalAlignment="Center" HorizontalAlignment="Left"/>
|
||||
<c:BorderResizeThumb Width="5" Height="5" Cursor="SizeWE" ResizeMode="Margin" Margin="-3" ResizeElement="{Binding ElementName=PART_ResizeDecorator}"
|
||||
VerticalAlignment="Center" HorizontalAlignment="Right"/>
|
||||
<c:BorderResizeThumb Width="5" Height="5" Cursor="SizeNS" ResizeMode="Margin" Margin="-3" ResizeElement="{Binding ElementName=PART_ResizeDecorator}"
|
||||
VerticalAlignment="Bottom" HorizontalAlignment="Center"/>
|
||||
<c:BorderResizeThumb Width="5" Height="5" Cursor="SizeNWSE" ResizeMode="Margin" Margin="-3" ResizeElement="{Binding ElementName=PART_ResizeDecorator}"
|
||||
VerticalAlignment="Top" HorizontalAlignment="Left"/>
|
||||
<c:BorderResizeThumb Width="5" Height="5" Cursor="SizeNESW" ResizeMode="Margin" Margin="-3" ResizeElement="{Binding ElementName=PART_ResizeDecorator}"
|
||||
VerticalAlignment="Top" HorizontalAlignment="Right"/>
|
||||
<c:BorderResizeThumb Width="5" Height="5" Cursor="SizeNESW" ResizeMode="Margin" Margin="-3" ResizeElement="{Binding ElementName=PART_ResizeDecorator}"
|
||||
VerticalAlignment="Bottom" HorizontalAlignment="Left"/>
|
||||
<c:BorderResizeThumb Width="5" Height="5" Cursor="SizeNWSE" ResizeMode="Margin" Margin="-3" ResizeElement="{Binding ElementName=PART_ResizeDecorator}"
|
||||
VerticalAlignment="Bottom" HorizontalAlignment="Right"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
<DataTemplate.Triggers>
|
||||
<DataTrigger Binding="{Binding Suffix}" Value=".gif">
|
||||
<Setter TargetName="gif" Property="Visibility" Value="Visible"/>
|
||||
<Setter TargetName="image" Property="Visibility" Value="Collapsed"/>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding ResizeMode}" Value="True">
|
||||
<Setter TargetName="PART_ResizeDecorator" Property="Visibility" Value="Visible"/>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding Suffix}" Value=".txt">
|
||||
<Setter TargetName="image" Property="Source" Value="pack://application:,,,/Util.DiagramDesigner;component/Images/file.png"/>
|
||||
<Setter TargetName="image" Property="Margin" Value="0"/>
|
||||
<Setter TargetName="image" Property="Clip" Value="{x:Null}"/>
|
||||
</DataTrigger>
|
||||
</DataTemplate.Triggers>
|
||||
</DataTemplate>
|
||||
</ResourceDictionary>
|
||||
14
Util.DiagramDesigner/UserControls/ConnectorContainer.xaml
Normal file
14
Util.DiagramDesigner/UserControls/ConnectorContainer.xaml
Normal file
@@ -0,0 +1,14 @@
|
||||
<ItemsControl x:Class="Util.DiagramDesigner.ConnectorContainer"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
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:Util.DiagramDesigner"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="300" d:DesignWidth="300">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<Canvas x:Name="rootCanvas" Loaded="rootCanvas_Loaded"/>
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
</ItemsControl>
|
||||
72
Util.DiagramDesigner/UserControls/ConnectorContainer.xaml.cs
Normal file
72
Util.DiagramDesigner/UserControls/ConnectorContainer.xaml.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for ConnectorContainer.xaml
|
||||
/// </summary>
|
||||
public partial class ConnectorContainer : ItemsControl
|
||||
{
|
||||
private Canvas rootCanvas;
|
||||
public ConnectorContainer()
|
||||
{
|
||||
InitializeComponent();
|
||||
((INotifyCollectionChanged)Items).CollectionChanged += ConnectorContainer_CollectionChanged;
|
||||
}
|
||||
|
||||
void ConnectorContainer_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
if (e.Action == NotifyCollectionChangedAction.Add)
|
||||
{
|
||||
foreach(var item in e.NewItems)
|
||||
{
|
||||
FullyCreatedConnectorInfo vm = item as FullyCreatedConnectorInfo;
|
||||
var connector = ItemContainerGenerator.ContainerFromItem(item) as ContentPresenter;
|
||||
|
||||
Canvas.SetLeft(connector, vm.DataItem.ItemWidth * vm.XRatio);
|
||||
Canvas.SetTop(connector, vm.DataItem.ItemHeight * vm.YRatio);
|
||||
}
|
||||
SetConnectorLocation();
|
||||
}
|
||||
}
|
||||
|
||||
void ConnectorContainer_SizeChanged(object sender, SizeChangedEventArgs e)
|
||||
{
|
||||
SetConnectorLocation();
|
||||
}
|
||||
|
||||
private void rootCanvas_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
rootCanvas = sender as Canvas;
|
||||
SetConnectorLocation();
|
||||
SizeChanged += ConnectorContainer_SizeChanged;
|
||||
}
|
||||
|
||||
private void SetConnectorLocation()
|
||||
{
|
||||
foreach (var connector in rootCanvas.Children.OfType<ContentPresenter>())
|
||||
{
|
||||
var vm = connector.DataContext as FullyCreatedConnectorInfo;
|
||||
if (vm != null)
|
||||
{
|
||||
Canvas.SetLeft(connector, vm.DataItem.ItemWidth * vm.XRatio);
|
||||
Canvas.SetTop(connector, vm.DataItem.ItemHeight * vm.YRatio);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
978
Util.DiagramDesigner/UserControls/DiagramControl.xaml
Normal file
978
Util.DiagramDesigner/UserControls/DiagramControl.xaml
Normal file
@@ -0,0 +1,978 @@
|
||||
<UserControl x:Class="Util.DiagramDesigner.DiagramControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
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:Util.DiagramDesigner"
|
||||
xmlns:c="clr-namespace:Util.DiagramDesigner.Controls"
|
||||
xmlns:sys="clr-namespace:System;assembly=mscorlib"
|
||||
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||
mc:Ignorable="d" HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
d:DesignHeight="300" d:DesignWidth="300">
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="/Util.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"/>
|
||||
|
||||
<!-- ResizeDecorator Default Template -->
|
||||
<!--
|
||||
<ControlTemplate x:Key="ResizeDecoratorTemplate" TargetType="{x:Type Control}">
|
||||
<Grid SnapsToDevicePixels="true">
|
||||
<c:ResizeThumb Height="1" Cursor="SizeNS" Margin="0 0 0 0"
|
||||
VerticalAlignment="Top" HorizontalAlignment="Stretch"/>
|
||||
<c:ResizeThumb Width="1" Cursor="SizeWE" Margin="0 0 0 0"
|
||||
VerticalAlignment="Stretch" HorizontalAlignment="Left"/>
|
||||
<c:ResizeThumb Width="1" Cursor="SizeWE" Margin="0 0 0 0"
|
||||
VerticalAlignment="Stretch" HorizontalAlignment="Right"/>
|
||||
<c:ResizeThumb Height="1" Cursor="SizeNS" Margin="0 0 0 0"
|
||||
VerticalAlignment="Bottom" HorizontalAlignment="Stretch"/>
|
||||
<c:ResizeThumb Width="7" Height="7" Cursor="SizeNWSE" Margin="-3 -3 0 0"
|
||||
VerticalAlignment="Top" HorizontalAlignment="Left"/>
|
||||
<c:ResizeThumb Width="7" Height="7" Cursor="SizeNESW" Margin="0 -3 -3 0"
|
||||
VerticalAlignment="Top" HorizontalAlignment="Right"/>
|
||||
<c:ResizeThumb Width="7" Height="7" Cursor="SizeNESW" Margin="-3 0 0 -3"
|
||||
VerticalAlignment="Bottom" HorizontalAlignment="Left"/>
|
||||
<c:ResizeThumb Width="7" Height="7" Cursor="SizeNWSE" Margin="0 0 -3 -3"
|
||||
VerticalAlignment="Bottom" HorizontalAlignment="Right"/>
|
||||
</Grid>
|
||||
</ControlTemplate>-->
|
||||
|
||||
<Style TargetType="{x:Type Shape}" x:Key="ThumbCorner">
|
||||
<Setter Property="SnapsToDevicePixels" Value="true" />
|
||||
<Setter Property="Stroke" Value="#FFC8C8C8" />
|
||||
<Setter Property="StrokeThickness" Value=".5" />
|
||||
<Setter Property="Width" Value="7" />
|
||||
<Setter Property="Height" Value="7" />
|
||||
<Setter Property="Margin" Value="-2" />
|
||||
<Setter Property="Fill">
|
||||
<Setter.Value>
|
||||
<RadialGradientBrush Center="0.2, 0.2" GradientOrigin="0.2, 0.2" RadiusX="0.8" RadiusY="0.8">
|
||||
<GradientStop Color="White" Offset="0.0" />
|
||||
<GradientStop Color="Gray" Offset="0.8" />
|
||||
</RadialGradientBrush>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!--ResizeDecorator Default Template-->
|
||||
<ControlTemplate x:Key="ResizeDecoratorTemplate" TargetType="{x:Type Control}">
|
||||
<Grid>
|
||||
<Grid Opacity="0" Margin="-3">
|
||||
<c:RotateThumb x:Name="rotate" Width="7"
|
||||
Height="7"
|
||||
Margin="0,-20,0,0"
|
||||
Cursor="Hand"
|
||||
VerticalAlignment="Top"
|
||||
HorizontalAlignment="Center"/>
|
||||
<c:ResizeThumb Height="3"
|
||||
Cursor="SizeNS"
|
||||
VerticalAlignment="Top"
|
||||
HorizontalAlignment="Stretch"/>
|
||||
<c:ResizeThumb Width="3"
|
||||
Cursor="SizeWE"
|
||||
VerticalAlignment="Stretch"
|
||||
HorizontalAlignment="Left"/>
|
||||
<c:ResizeThumb Width="3"
|
||||
Cursor="SizeWE"
|
||||
VerticalAlignment="Stretch"
|
||||
HorizontalAlignment="Right"/>
|
||||
<c:ResizeThumb Height="3"
|
||||
Cursor="SizeNS"
|
||||
VerticalAlignment="Bottom"
|
||||
HorizontalAlignment="Stretch"/>
|
||||
<c:ResizeThumb Width="7"
|
||||
Height="7"
|
||||
Margin="-2"
|
||||
Cursor="SizeNWSE"
|
||||
VerticalAlignment="Top"
|
||||
HorizontalAlignment="Left"/>
|
||||
<c:ResizeThumb Width="7"
|
||||
Height="7"
|
||||
Margin="-2"
|
||||
Cursor="SizeNESW"
|
||||
VerticalAlignment="Top"
|
||||
HorizontalAlignment="Right"/>
|
||||
<c:ResizeThumb Width="7"
|
||||
Height="7"
|
||||
Margin="-2"
|
||||
Cursor="SizeNESW"
|
||||
VerticalAlignment="Bottom"
|
||||
HorizontalAlignment="Left"/>
|
||||
<c:ResizeThumb Width="7"
|
||||
Height="7"
|
||||
Margin="-2"
|
||||
Cursor="SizeNWSE"
|
||||
VerticalAlignment="Bottom"
|
||||
HorizontalAlignment="Right"/>
|
||||
</Grid>
|
||||
<Grid IsHitTestVisible="False" Opacity="1" Margin="-3">
|
||||
<Rectangle SnapsToDevicePixels="True"
|
||||
StrokeThickness="1"
|
||||
Margin="1"
|
||||
Stroke="Gray"/>
|
||||
<Line x:Name="line" StrokeThickness="1" X1="0" Y1="0" X2="0" Y2="20"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Top"
|
||||
Margin="0,-19,0,0"
|
||||
Stroke="Gray"/>
|
||||
<Ellipse x:Name="top" Style="{StaticResource ThumbCorner}" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="-1,-20,0,0"/>
|
||||
<Ellipse Style="{StaticResource ThumbCorner}" HorizontalAlignment="Left" VerticalAlignment="Top"/>
|
||||
<Ellipse Style="{StaticResource ThumbCorner}" HorizontalAlignment="Right" VerticalAlignment="Top"/>
|
||||
<Ellipse Style="{StaticResource ThumbCorner}" HorizontalAlignment="Left" VerticalAlignment="Bottom"/>
|
||||
<Ellipse Style="{StaticResource ThumbCorner}" HorizontalAlignment="Right" VerticalAlignment="Bottom"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<ControlTemplate.Triggers>
|
||||
<DataTrigger Binding="{Binding ShowRotate}" Value="false">
|
||||
<Setter TargetName="rotate" Property="Visibility" Value="Collapsed"/>
|
||||
<Setter TargetName="line" Property="Visibility" Value="Collapsed"/>
|
||||
<Setter TargetName="top" Property="Visibility" Value="Collapsed"/>
|
||||
</DataTrigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
|
||||
<ObjectDataProvider x:Key="ConnectorOrientationMenu" MethodName="GetValues" ObjectType="{x:Type sys:Enum}">
|
||||
<ObjectDataProvider.MethodParameters>
|
||||
<x:Type TypeName="s:ConnectorOrientation" />
|
||||
</ObjectDataProvider.MethodParameters>
|
||||
</ObjectDataProvider>
|
||||
|
||||
<Style x:Key="CinchMenuItemStyle" TargetType="{x:Type MenuItem}" >
|
||||
<Setter Property="Header" Value="{Binding Text}" />
|
||||
<Setter Property="ItemsSource" Value="{Binding Children}" />
|
||||
<Setter Property="Command" Value="{Binding Command}" />
|
||||
<Setter Property="CommandParameter" Value="{Binding CommandParameter}" />
|
||||
</Style>
|
||||
|
||||
<!-- Connector Style -->
|
||||
<Style x:Key="normalConnector" TargetType="{x:Type s:Connector}">
|
||||
<Setter Property="Cursor" Value="Cross" />
|
||||
<Setter Property="SnapsToDevicePixels" Value="true" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type s:Connector}">
|
||||
<Grid Width="{Binding ConnectorWidth}" Height="{Binding ConnectorHeight}">
|
||||
<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>
|
||||
<!-- transparent extra space makes connector easier to hit -->
|
||||
<Rectangle Fill="Transparent" Margin="-2" />
|
||||
<Rectangle Fill="{Binding ColorViewModel.FillColor,Converter={StaticResource ColorBrushConverter}}" StrokeThickness="1" Stroke="{Binding ColorViewModel.LineColor,Converter={StaticResource ColorBrushConverter}}" />
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- Connector Style -->
|
||||
<Style x:Key="logicalConnector" TargetType="{x:Type s:Connector}">
|
||||
<Setter Property="Cursor" Value="Cross" />
|
||||
<Setter Property="SnapsToDevicePixels" Value="true" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type s:Connector}">
|
||||
<Grid>
|
||||
<Grid Width="{Binding ConnectorWidth}" Height="{Binding ConnectorHeight}" HorizontalAlignment="Left" VerticalAlignment="Top">
|
||||
<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>
|
||||
<!-- transparent extra space makes connector easier to hit -->
|
||||
<Rectangle Fill="Transparent" Margin="-2" />
|
||||
<Rectangle Fill="{Binding ColorViewModel.FillColor,Converter={StaticResource ColorBrushConverter}}" StrokeThickness="1" Stroke="{Binding ColorViewModel.LineColor,Converter={StaticResource ColorBrushConverter}}" />
|
||||
</Grid>
|
||||
<TextBlock x:Name="txtleft" FontSize="10" RenderTransformOrigin="0.5,0.5">
|
||||
<TextBlock.Text>
|
||||
<MultiBinding Converter="{StaticResource ConectorValueConverter}">
|
||||
<Binding Path="ConnectorValue" />
|
||||
<Binding Path="ValueTypePoint"/>
|
||||
</MultiBinding>
|
||||
</TextBlock.Text>
|
||||
<TextBlock.RenderTransform>
|
||||
<TransformGroup>
|
||||
<ScaleTransform/>
|
||||
<SkewTransform/>
|
||||
<RotateTransform/>
|
||||
<TranslateTransform Y="10" X="{Binding ElementName=txtleft,Path=Text,Converter={StaticResource ConectorOrientationConverter}}"/>
|
||||
</TransformGroup>
|
||||
</TextBlock.RenderTransform>
|
||||
</TextBlock>
|
||||
<TextBlock x:Name="txtRight" FontSize="10" RenderTransformOrigin="0.5,0.5" Visibility="Collapsed">
|
||||
<TextBlock.Text>
|
||||
<MultiBinding Converter="{StaticResource ConectorValueConverter}">
|
||||
<Binding Path="ConnectorValue" />
|
||||
<Binding Path="ValueTypePoint"/>
|
||||
</MultiBinding>
|
||||
</TextBlock.Text>
|
||||
<TextBlock.RenderTransform>
|
||||
<TransformGroup>
|
||||
<ScaleTransform/>
|
||||
<SkewTransform/>
|
||||
<RotateTransform/>
|
||||
<TranslateTransform Y="10" X="5"/>
|
||||
</TransformGroup>
|
||||
</TextBlock.RenderTransform>
|
||||
</TextBlock>
|
||||
</Grid>
|
||||
<ControlTemplate.Triggers>
|
||||
<DataTrigger Value="Right" Binding="{Binding Orientation}">
|
||||
<Setter TargetName="txtleft" Property="Visibility" Value="Collapsed" />
|
||||
<Setter TargetName="txtRight" Property="Visibility" Value="Visible" />
|
||||
</DataTrigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- Connector Style -->
|
||||
<Style x:Key="pointConnector" TargetType="{x:Type s:PointConnector}">
|
||||
<Setter Property="SnapsToDevicePixels" Value="true" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type s:PointConnector}">
|
||||
<Grid Width="{Binding ConnectorWidth}" Height="{Binding ConnectorHeight}">
|
||||
<!-- transparent extra space makes connector easier to hit -->
|
||||
<Ellipse Fill="Transparent" Margin="-2" />
|
||||
<Ellipse Fill="{Binding ColorViewModel.FillColor,Converter={StaticResource ColorBrushConverter}}" StrokeThickness="1" Stroke="{Binding ColorViewModel.LineColor,Converter={StaticResource ColorBrushConverter}}" />
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="normalConnectorContainer" TargetType="{x:Type s:ConnectorContainer}">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type ItemsControl}">
|
||||
<Grid>
|
||||
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
|
||||
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
|
||||
</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}" />
|
||||
</i:Interaction.Behaviors>
|
||||
</Rectangle>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="logicConnectorContainer" TargetType="{x:Type s:ConnectorContainer}">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type ItemsControl}">
|
||||
<Grid>
|
||||
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
|
||||
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
|
||||
</Border>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
<UserControl.LayoutTransform>
|
||||
<ScaleTransform x:Name="scale" ScaleX="{Binding ZoomValue}" ScaleY="{Binding ZoomValue}" Changed="ScaleTransform_Changed" />
|
||||
</UserControl.LayoutTransform>
|
||||
<Border BorderBrush="LightGray"
|
||||
BorderThickness="0">
|
||||
<Grid>
|
||||
<ItemsControl ItemsSource="{Binding Items}"
|
||||
ItemContainerStyleSelector="{x:Static s:DesignerItemsControlItemStyleSelector.Instance}">
|
||||
<ItemsControl.Resources>
|
||||
<Style x:Key="designerItemStyle"
|
||||
TargetType="{x:Type ContentPresenter}">
|
||||
<Setter Property="Canvas.Top"
|
||||
Value="{Binding Top}" />
|
||||
<Setter Property="Canvas.Left"
|
||||
Value="{Binding Left}" />
|
||||
<Setter Property="Canvas.ZIndex"
|
||||
Value="{Binding ZIndex}" />
|
||||
<Setter Property="s:SelectionProps.EnabledForSelection"
|
||||
Value="True" />
|
||||
<Setter Property="s:ItemConnectProps.EnabledForConnection"
|
||||
Value="True" />
|
||||
<Setter Property="Width"
|
||||
Value="{Binding ItemWidth}" />
|
||||
<Setter Property="Height"
|
||||
Value="{Binding ItemHeight}" />
|
||||
<Setter Property="SnapsToDevicePixels"
|
||||
Value="True" />
|
||||
<Setter Property="ContentTemplate">
|
||||
<Setter.Value>
|
||||
<DataTemplate>
|
||||
<Grid x:Name="selectedGrid" IsHitTestVisible="{Binding IsHitTestVisible}" >
|
||||
<Grid.ContextMenu>
|
||||
<ContextMenu ItemsSource="{Binding MenuOptions}" Visibility="{Binding ShowMenuOptions,Converter={StaticResource BooleanToVisibilityConverter}}">
|
||||
<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>
|
||||
|
||||
<!-- PART_DragThumb -->
|
||||
<c:DragThumb x:Name="PART_DragThumb"
|
||||
Cursor="SizeAll" >
|
||||
<c:DragThumb.InputBindings>
|
||||
<MouseBinding MouseAction="LeftDoubleClick" Command="{Binding EditCommand}" CommandParameter="{Binding }" />
|
||||
</c:DragThumb.InputBindings>
|
||||
</c:DragThumb>
|
||||
|
||||
<Grid RenderTransformOrigin="0.5,0.5">
|
||||
<!-- PART_ResizeDecorator -->
|
||||
<Control x:Name="PART_ResizeDecorator"
|
||||
Visibility="Collapsed"
|
||||
Template="{StaticResource ResizeDecoratorTemplate}"/>
|
||||
|
||||
|
||||
<!-- PART_ContentPresenter -->
|
||||
<ContentPresenter x:Name="PART_ContentPresenter"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
Content="{TemplateBinding Content}" />
|
||||
|
||||
<Control x:Name="PART_Text" Margin="5">
|
||||
<Control.Style>
|
||||
<Style TargetType="Control">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate>
|
||||
<Grid/>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding ShowText}" Value="True">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate>
|
||||
<s:TextControl x:Name="PART_Text" />
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</DataTrigger>
|
||||
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Control.Style>
|
||||
</Control>
|
||||
|
||||
<!-- PART_ConnectorDecorator -->
|
||||
<Grid Margin="-5"
|
||||
x:Name="PART_ConnectorDecorator">
|
||||
<s:Connector DataContext="{Binding LeftConnector}" Style="{StaticResource normalConnector}"
|
||||
Orientation="Left"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Left"
|
||||
Visibility="{Binding Path=ShowConnectors, Converter={x:Static s:BoolToVisibilityConverter.Instance}}" />
|
||||
<s:Connector DataContext="{Binding TopConnector}" Style="{StaticResource normalConnector}"
|
||||
Orientation="Top"
|
||||
VerticalAlignment="Top"
|
||||
HorizontalAlignment="Center"
|
||||
Visibility="{Binding Path=ShowConnectors, Converter={x:Static s:BoolToVisibilityConverter.Instance}}" />
|
||||
<s:Connector DataContext="{Binding RightConnector}" Style="{StaticResource normalConnector}"
|
||||
Orientation="Right"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Right"
|
||||
Visibility="{Binding Path=ShowConnectors, Converter={x:Static s:BoolToVisibilityConverter.Instance}}" />
|
||||
<s:Connector DataContext="{Binding BottomConnector}" Style="{StaticResource normalConnector}"
|
||||
Orientation="Bottom"
|
||||
VerticalAlignment="Bottom"
|
||||
HorizontalAlignment="Center"
|
||||
Visibility="{Binding Path=ShowConnectors, Converter={x:Static s:BoolToVisibilityConverter.Instance}}" />
|
||||
</Grid>
|
||||
|
||||
<Grid.RenderTransform>
|
||||
<TransformGroup>
|
||||
<RotateTransform Angle="{Binding Angle}" />
|
||||
<ScaleTransform x:Name="scale" ScaleX="{Binding ScaleX}" ScaleY="{Binding ScaleY}"></ScaleTransform>
|
||||
</TransformGroup>
|
||||
</Grid.RenderTransform>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<DataTemplate.Triggers>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Value="True" Binding="{Binding IsSelected}"/>
|
||||
<Condition Value="{x:Static sys:Guid.Empty}" Binding="{Binding ParentId}"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter TargetName="PART_ResizeDecorator" Property="Visibility" Value="Visible"/>
|
||||
</MultiDataTrigger>
|
||||
<Trigger Property="IsMouseOver"
|
||||
Value="true">
|
||||
<Setter TargetName="PART_ConnectorDecorator" Property="Visibility" Value="Visible"/>
|
||||
</Trigger>
|
||||
<DataTrigger Value="True"
|
||||
Binding="{Binding RelativeSource={RelativeSource Self},Path=IsDragConnectionOver}">
|
||||
<Setter TargetName="PART_ConnectorDecorator" Property="Visibility" Value="Visible" />
|
||||
</DataTrigger>
|
||||
<DataTrigger Value="0"
|
||||
Binding="{Binding Connectors.Count}">
|
||||
<Setter TargetName="PART_ConnectorDecorator" Property="Visibility" Value="Collapsed" />
|
||||
</DataTrigger>
|
||||
</DataTemplate.Triggers>
|
||||
</DataTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Setter Property="Effect">
|
||||
<Setter.Value>
|
||||
<DropShadowEffect BlurRadius="10" Color="{Binding ColorViewModel.ShadowColor}"/>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding ColorViewModel.ShadowColor}" Value="Transparent">
|
||||
<Setter Property="Effect" Value="{x:Null}"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="connectorItemStyle"
|
||||
TargetType="{x:Type ContentPresenter}">
|
||||
<Setter Property="Width"
|
||||
Value="{Binding Area.Width}" />
|
||||
<Setter Property="Height"
|
||||
Value="{Binding Area.Height}" />
|
||||
<Setter Property="Canvas.Top"
|
||||
Value="{Binding Area.Top}" />
|
||||
<Setter Property="Canvas.Left"
|
||||
Value="{Binding Area.Left}" />
|
||||
<Setter Property="Canvas.ZIndex"
|
||||
Value="{Binding ZIndex}" />
|
||||
<Setter Property="s:SelectionProps.EnabledForSelection"
|
||||
Value="True" />
|
||||
<Setter Property="ContentTemplate">
|
||||
<Setter.Value>
|
||||
<DataTemplate>
|
||||
<Grid>
|
||||
<Grid.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem Header="删除" Command="{Binding DeleteConnectionCommand}" CommandParameter="{Binding}"/>
|
||||
</ContextMenu>
|
||||
</Grid.ContextMenu>
|
||||
|
||||
<Canvas Margin="0"
|
||||
x:Name="selectedGrid"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch">
|
||||
<Canvas.InputBindings>
|
||||
<MouseBinding MouseAction="LeftDoubleClick" Command="{Binding EditCommand}" CommandParameter="{Binding }" />
|
||||
</Canvas.InputBindings>
|
||||
<Polyline x:Name="poly"
|
||||
Points="{Binding Path=ConnectionPoints, Converter={x:Static s:ConnectionPathConverter.Instance}}"
|
||||
Stroke="{Binding ColorViewModel.LineColor,Converter={StaticResource ColorBrushConverter}}"
|
||||
StrokeThickness="{Binding ColorViewModel.LineWidth}"
|
||||
StrokeDashArray="{Binding ColorViewModel.LineDashStyle,Converter={StaticResource LineDashConverter}}" />
|
||||
|
||||
<Path x:Name="rightarrow"
|
||||
Data="{Binding ColorViewModel.RightArrowPathStyle,Converter={StaticResource ArrowPathConverter}}"
|
||||
Visibility="{Binding Path=IsFullConnection, Converter={x:Static s:BoolToVisibilityConverter.Instance}}"
|
||||
Fill="{Binding ColorViewModel.LineColor,Converter={StaticResource ColorBrushConverter}}"
|
||||
HorizontalAlignment="Left"
|
||||
Height="{Binding ColorViewModel.RightArrowSizeStyle, Converter={StaticResource ArrowSizeConverter}}"
|
||||
Width="{Binding ColorViewModel.RightArrowSizeStyle, Converter={StaticResource ArrowSizeConverter}}"
|
||||
Canvas.Left="{Binding EndPoint.X}"
|
||||
Canvas.Top="{Binding EndPoint.Y}"
|
||||
Stretch="Fill"
|
||||
Stroke="{Binding ColorViewModel.LineColor,Converter={StaticResource ColorBrushConverter}}"
|
||||
VerticalAlignment="Top"
|
||||
RenderTransformOrigin="0.5,0.5">
|
||||
<Path.RenderTransform>
|
||||
<RotateTransform x:Name="rightrot" />
|
||||
</Path.RenderTransform>
|
||||
</Path>
|
||||
|
||||
<Path x:Name="leftarrow"
|
||||
Data="{Binding ColorViewModel.LeftArrowPathStyle,Converter={StaticResource ArrowPathConverter}}"
|
||||
Visibility="{Binding Path=IsFullConnection, Converter={x:Static s:BoolToVisibilityConverter.Instance}}"
|
||||
Fill="{Binding ColorViewModel.LineColor,Converter={StaticResource ColorBrushConverter}}"
|
||||
HorizontalAlignment="Left"
|
||||
Height="{Binding ColorViewModel.LeftArrowSizeStyle, Converter={StaticResource ArrowSizeConverter}}"
|
||||
Width="{Binding ColorViewModel.LeftArrowSizeStyle, Converter={StaticResource ArrowSizeConverter}}"
|
||||
Canvas.Left="{Binding StartPoint.X}"
|
||||
Canvas.Top="{Binding StartPoint.Y}"
|
||||
Stretch="Fill"
|
||||
Stroke="{Binding ColorViewModel.LineColor,Converter={StaticResource ColorBrushConverter}}"
|
||||
VerticalAlignment="Top"
|
||||
RenderTransformOrigin="0.5,0.5">
|
||||
<Path.RenderTransform>
|
||||
<RotateTransform x:Name="leftrot" />
|
||||
</Path.RenderTransform>
|
||||
</Path>
|
||||
</Canvas>
|
||||
|
||||
<!-- PART_DragThumb -->
|
||||
<c:DragThumb x:Name="PART_DragThumb"
|
||||
Cursor="SizeAll" >
|
||||
<c:DragThumb.InputBindings>
|
||||
<MouseBinding MouseAction="LeftDoubleClick" Command="{Binding EditCommand}" CommandParameter="{Binding }" />
|
||||
</c:DragThumb.InputBindings>
|
||||
</c:DragThumb>
|
||||
</Grid>
|
||||
<DataTemplate.Triggers>
|
||||
<DataTrigger Value="True"
|
||||
Binding="{Binding IsSelected}">
|
||||
<Setter TargetName="poly"
|
||||
Property="Stroke"
|
||||
Value="Black" />
|
||||
<Setter TargetName="rightarrow"
|
||||
Property="Stroke"
|
||||
Value="Black" />
|
||||
<Setter TargetName="rightarrow"
|
||||
Property="Fill"
|
||||
Value="Black" />
|
||||
</DataTrigger>
|
||||
|
||||
<!--右箭头-->
|
||||
<DataTrigger Binding="{Binding Path=SinkConnectorInfo.Orientation}"
|
||||
Value="Left">
|
||||
<Setter TargetName="rightarrow"
|
||||
Property="Margin"
|
||||
Value="-10,-5,0,0" />
|
||||
<Setter TargetName="rightarrow"
|
||||
Property="RenderTransform">
|
||||
<Setter.Value>
|
||||
<RotateTransform Angle="90" />
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding Path=SinkConnectorInfo.Orientation}"
|
||||
Value="Top">
|
||||
<Setter TargetName="rightarrow"
|
||||
Property="Margin"
|
||||
Value="-5,-10,0,0" />
|
||||
<Setter TargetName="rightarrow"
|
||||
Property="RenderTransform">
|
||||
<Setter.Value>
|
||||
<RotateTransform Angle="180" />
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding Path=SinkConnectorInfo.Orientation}"
|
||||
Value="Right">
|
||||
<Setter TargetName="rightarrow"
|
||||
Property="Margin"
|
||||
Value="0,-5,0,0" />
|
||||
<Setter TargetName="rightarrow"
|
||||
Property="RenderTransform">
|
||||
<Setter.Value>
|
||||
<RotateTransform Angle="-90" />
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding Path=SinkConnectorInfo.Orientation}"
|
||||
Value="Bottom">
|
||||
<Setter TargetName="rightarrow"
|
||||
Property="Margin"
|
||||
Value="-5,0,0,0" />
|
||||
<Setter TargetName="rightarrow"
|
||||
Property="RenderTransform">
|
||||
<Setter.Value>
|
||||
<RotateTransform Angle="0" />
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</DataTrigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Value="True" Binding="{Binding SinkConnectorInfo.IsInnerPoint}"/>
|
||||
<Condition Value="0" Binding="{Binding SinkConnectorInfo.XRatio}"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter TargetName="rightarrow" Property="Visibility" Value="Hidden"/>
|
||||
</MultiDataTrigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Value="True" Binding="{Binding SinkConnectorInfo.IsInnerPoint}"/>
|
||||
<Condition Value="1" Binding="{Binding SinkConnectorInfo.XRatio}"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter TargetName="rightarrow" Property="Visibility" Value="Hidden"/>
|
||||
</MultiDataTrigger>
|
||||
<DataTrigger Binding="{Binding Path=ColorViewModel.RightArrowStyle}" Value="None">
|
||||
<Setter TargetName="rightarrow" Property="Visibility" Value="Hidden"/>
|
||||
</DataTrigger>
|
||||
|
||||
<!--左箭头-->
|
||||
<DataTrigger Binding="{Binding Path=SourceConnectorInfo.Orientation}"
|
||||
Value="Left">
|
||||
<Setter TargetName="leftarrow"
|
||||
Property="Margin"
|
||||
Value="-10,-5,0,0" />
|
||||
<Setter TargetName="leftarrow"
|
||||
Property="RenderTransform">
|
||||
<Setter.Value>
|
||||
<RotateTransform Angle="90" />
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding Path=SourceConnectorInfo.Orientation}"
|
||||
Value="Top">
|
||||
<Setter TargetName="leftarrow"
|
||||
Property="Margin"
|
||||
Value="-5,-10,0,0" />
|
||||
<Setter TargetName="leftarrow"
|
||||
Property="RenderTransform">
|
||||
<Setter.Value>
|
||||
<RotateTransform Angle="180" />
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding Path=SourceConnectorInfo.Orientation}"
|
||||
Value="Right">
|
||||
<Setter TargetName="leftarrow"
|
||||
Property="Margin"
|
||||
Value="0,-5,0,0" />
|
||||
<Setter TargetName="leftarrow"
|
||||
Property="RenderTransform">
|
||||
<Setter.Value>
|
||||
<RotateTransform Angle="-90" />
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding Path=SourceConnectorInfo.Orientation}"
|
||||
Value="Bottom">
|
||||
<Setter TargetName="leftarrow"
|
||||
Property="Margin"
|
||||
Value="-5,0,0,0" />
|
||||
<Setter TargetName="leftarrow"
|
||||
Property="RenderTransform">
|
||||
<Setter.Value>
|
||||
<RotateTransform Angle="0" />
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</DataTrigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Value="True" Binding="{Binding SourceConnectorInfo.IsInnerPoint}"/>
|
||||
<Condition Value="0" Binding="{Binding SourceConnectorInfo.XRatio}"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter TargetName="leftarrow" Property="Visibility" Value="Hidden"/>
|
||||
</MultiDataTrigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Value="True" Binding="{Binding SourceConnectorInfo.IsInnerPoint}"/>
|
||||
<Condition Value="1" Binding="{Binding SourceConnectorInfo.XRatio}"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter TargetName="leftarrow" Property="Visibility" Value="Hidden"/>
|
||||
</MultiDataTrigger>
|
||||
<DataTrigger Binding="{Binding Path=ColorViewModel.LeftArrowStyle}" Value="None">
|
||||
<Setter TargetName="leftarrow" Property="Visibility" Value="Hidden"/>
|
||||
</DataTrigger>
|
||||
</DataTemplate.Triggers>
|
||||
</DataTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="gifimageItemStyle"
|
||||
TargetType="{x:Type ContentPresenter}">
|
||||
<Setter Property="Canvas.Top"
|
||||
Value="{Binding Top}" />
|
||||
<Setter Property="Canvas.Left"
|
||||
Value="{Binding Left}" />
|
||||
<Setter Property="Canvas.ZIndex"
|
||||
Value="{Binding ZIndex}" />
|
||||
<Setter Property="s:SelectionProps.EnabledForSelection"
|
||||
Value="True" />
|
||||
<Setter Property="s:ItemConnectProps.EnabledForConnection"
|
||||
Value="True" />
|
||||
<Setter Property="Width"
|
||||
Value="{Binding ItemWidth}" />
|
||||
<Setter Property="Height"
|
||||
Value="{Binding ItemHeight}" />
|
||||
<Setter Property="SnapsToDevicePixels"
|
||||
Value="True" />
|
||||
<Setter Property="ContentTemplate">
|
||||
<Setter.Value>
|
||||
<DataTemplate>
|
||||
<Grid x:Name="selectedGrid" IsHitTestVisible="{Binding IsHitTestVisible}">
|
||||
<Grid.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem Header="插入点" IsCheckable="True" IsChecked="{Binding ShouldInsertAnchor}" />
|
||||
<MenuItem Header="选择" ItemsSource="{Binding MenuOptions}" ItemContainerStyle="{StaticResource CinchMenuItemStyle}"/>
|
||||
</ContextMenu>
|
||||
</Grid.ContextMenu>
|
||||
<!-- PART_DragThumb -->
|
||||
<c:DragThumb x:Name="PART_DragThumb"
|
||||
Cursor="SizeAll" />
|
||||
<Grid RenderTransformOrigin="0.5,0.5">
|
||||
<!-- PART_ResizeDecorator -->
|
||||
<Control x:Name="PART_ResizeDecorator"
|
||||
Visibility="Collapsed"
|
||||
Template="{StaticResource ResizeDecoratorTemplate}"/>
|
||||
<!-- PART_ContentPresenter -->
|
||||
<ContentPresenter x:Name="PART_ContentPresenter"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
Content="{TemplateBinding Content}" />
|
||||
<!-- PART_ConnectorDecorator -->
|
||||
<s:ConnectorContainer x:Name="PART_ConnectorContainer" Visibility="Hidden" Style="{StaticResource normalConnectorContainer}" ItemsSource="{Binding Connectors}">
|
||||
<s:ConnectorContainer.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<s:Connector Style="{StaticResource normalConnector}"/>
|
||||
</DataTemplate>
|
||||
</s:ConnectorContainer.ItemTemplate>
|
||||
</s:ConnectorContainer>
|
||||
<Grid.RenderTransform>
|
||||
<TransformGroup>
|
||||
<RotateTransform Angle="{Binding Angle}" />
|
||||
<ScaleTransform x:Name="scale" ScaleX="{Binding ScaleX}" ScaleY="{Binding ScaleY}"></ScaleTransform>
|
||||
</TransformGroup>
|
||||
</Grid.RenderTransform>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<DataTemplate.Triggers>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Value="True" Binding="{Binding IsSelected}"/>
|
||||
<Condition Value="{x:Static sys:Guid.Empty}" Binding="{Binding ParentId}"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter TargetName="PART_ResizeDecorator" Property="Visibility" Value="Visible"/>
|
||||
</MultiDataTrigger>
|
||||
<Trigger Property="IsMouseOver" Value="true">
|
||||
<Setter TargetName="PART_ConnectorContainer" Property="Visibility" Value="Visible" />
|
||||
</Trigger>
|
||||
<DataTrigger Value="True" Binding="{Binding IsDragConnectionOver}">
|
||||
<Setter TargetName="PART_ConnectorContainer" Property="Visibility" Value="Visible" />
|
||||
</DataTrigger>
|
||||
</DataTemplate.Triggers>
|
||||
</DataTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="logicalItemStyle"
|
||||
TargetType="{x:Type ContentPresenter}">
|
||||
<Setter Property="Canvas.Top"
|
||||
Value="{Binding Top}" />
|
||||
<Setter Property="Canvas.Left"
|
||||
Value="{Binding Left}" />
|
||||
<Setter Property="Canvas.ZIndex"
|
||||
Value="{Binding ZIndex}" />
|
||||
<Setter Property="s:SelectionProps.EnabledForSelection"
|
||||
Value="True" />
|
||||
<Setter Property="s:ItemConnectProps.EnabledForConnection"
|
||||
Value="True" />
|
||||
<Setter Property="Width"
|
||||
Value="{Binding ItemWidth}" />
|
||||
<Setter Property="Height"
|
||||
Value="{Binding ItemHeight}" />
|
||||
<Setter Property="SnapsToDevicePixels"
|
||||
Value="True" />
|
||||
<Setter Property="ContentTemplate">
|
||||
<Setter.Value>
|
||||
<DataTemplate>
|
||||
<Grid x:Name="selectedGrid">
|
||||
<Grid.ContextMenu>
|
||||
<ContextMenu ItemsSource="{Binding MenuOptions}" Visibility="{Binding ShowMenuOptions,Converter={StaticResource BooleanToVisibilityConverter}}">
|
||||
<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>
|
||||
|
||||
<!--PART_ConnectorDecorator-->
|
||||
<s:ConnectorContainer x:Name="PART_ConnectorContainer" Style="{StaticResource logicConnectorContainer}" ItemsSource="{Binding Connectors}" Margin="-4,0,0,0">
|
||||
<s:ConnectorContainer.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Grid>
|
||||
<s:Connector Style="{StaticResource logicalConnector}"/>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</s:ConnectorContainer.ItemTemplate>
|
||||
</s:ConnectorContainer>
|
||||
<!-- PART_DragThumb -->
|
||||
<c:DragThumb x:Name="PART_DragThumb"
|
||||
Cursor="SizeAll" >
|
||||
<c:DragThumb.InputBindings>
|
||||
<MouseBinding MouseAction="LeftDoubleClick" Command="{Binding EditCommand}" CommandParameter="{Binding }" />
|
||||
</c:DragThumb.InputBindings>
|
||||
</c:DragThumb>
|
||||
<!-- PART_ResizeDecorator -->
|
||||
<Control x:Name="PART_ResizeDecorator"
|
||||
Visibility="Collapsed"
|
||||
Template="{StaticResource ResizeDecoratorTemplate}"/>
|
||||
<!-- PART_ContentPresenter -->
|
||||
<ContentPresenter x:Name="PART_ContentPresenter"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
Content="{TemplateBinding Content}" />
|
||||
</Grid>
|
||||
<DataTemplate.Triggers>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Value="True" Binding="{Binding IsSelected}"/>
|
||||
<Condition Value="{x:Static sys:Guid.Empty}" Binding="{Binding ParentId}"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter TargetName="PART_ResizeDecorator" Property="Visibility" Value="Visible"/>
|
||||
</MultiDataTrigger>
|
||||
</DataTemplate.Triggers>
|
||||
</DataTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="pointItemStyle"
|
||||
TargetType="{x:Type ContentPresenter}">
|
||||
<Setter Property="Canvas.Top"
|
||||
Value="{Binding Top}" />
|
||||
<Setter Property="Canvas.Left"
|
||||
Value="{Binding Left}" />
|
||||
<Setter Property="Canvas.ZIndex"
|
||||
Value="{Binding ZIndex}" />
|
||||
<Setter Property="s:SelectionProps.EnabledForSelection"
|
||||
Value="True" />
|
||||
<Setter Property="Width"
|
||||
Value="{Binding ItemWidth}" />
|
||||
<Setter Property="Height"
|
||||
Value="{Binding ItemHeight}" />
|
||||
<Setter Property="SnapsToDevicePixels"
|
||||
Value="True" />
|
||||
<Setter Property="ContentTemplate">
|
||||
<Setter.Value>
|
||||
<DataTemplate>
|
||||
<Grid x:Name="selectedGrid" Visibility="{Binding Path=ShowConnectors, Converter={x:Static s:BoolToVisibilityConverter.Instance}}">
|
||||
<!-- PART_ConnectorDecorator -->
|
||||
<Grid Margin="-5"
|
||||
x:Name="PART_ConnectorDecorator">
|
||||
<s:PointConnector DataContext="{Binding TopConnector}" Style="{StaticResource pointConnector}"/>
|
||||
</Grid>
|
||||
<!-- PART_DragThumb -->
|
||||
<c:DragThumb x:Name="PART_DragThumb"
|
||||
Cursor="SizeAll" />
|
||||
</Grid>
|
||||
<DataTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver"
|
||||
Value="true">
|
||||
<Setter TargetName="PART_ConnectorDecorator" Property="Visibility" Value="Visible"/>
|
||||
</Trigger>
|
||||
<DataTrigger Value="True" Binding="{Binding RelativeSource={RelativeSource Self},Path=IsDragConnectionOver}">
|
||||
<Setter TargetName="PART_ConnectorDecorator" Property="Visibility" Value="Visible" />
|
||||
</DataTrigger>
|
||||
|
||||
</DataTemplate.Triggers>
|
||||
</DataTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="linkpointItemStyle"
|
||||
TargetType="{x:Type ContentPresenter}">
|
||||
<Setter Property="Canvas.Top"
|
||||
Value="{Binding Top}" />
|
||||
<Setter Property="Canvas.Left"
|
||||
Value="{Binding Left}" />
|
||||
<Setter Property="Canvas.ZIndex"
|
||||
Value="{Binding ZIndex}" />
|
||||
<Setter Property="s:SelectionProps.EnabledForSelection"
|
||||
Value="True" />
|
||||
<Setter Property="s:ItemConnectProps.EnabledForConnection"
|
||||
Value="True" />
|
||||
<Setter Property="Width"
|
||||
Value="{Binding ItemWidth}" />
|
||||
<Setter Property="Height"
|
||||
Value="{Binding ItemHeight}" />
|
||||
<Setter Property="SnapsToDevicePixels"
|
||||
Value="True" />
|
||||
<Setter Property="ContentTemplate">
|
||||
<Setter.Value>
|
||||
<DataTemplate>
|
||||
<Grid x:Name="selectedGrid">
|
||||
|
||||
<!-- PART_ConnectorDecorator -->
|
||||
<Grid Margin="-5"
|
||||
x:Name="PART_ConnectorDecorator">
|
||||
<s:Connector DataContext="{Binding TopConnector}" Style="{StaticResource normalConnector}"
|
||||
Orientation="Right"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center"
|
||||
Visibility="{Binding Path=ShowConnectors, Converter={x:Static s:BoolToVisibilityConverter.Instance}}" />
|
||||
</Grid>
|
||||
<!-- PART_DragThumb -->
|
||||
<c:DragThumb x:Name="PART_DragThumb"
|
||||
Cursor="SizeAll" />
|
||||
</Grid>
|
||||
<DataTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver"
|
||||
Value="true">
|
||||
<Setter TargetName="PART_ConnectorDecorator" Property="Visibility" Value="Visible"/>
|
||||
</Trigger>
|
||||
<DataTrigger Value="True" Binding="{Binding RelativeSource={RelativeSource Self},Path=IsDragConnectionOver}">
|
||||
<Setter TargetName="PART_ConnectorDecorator" Property="Visibility" Value="Visible" />
|
||||
</DataTrigger>
|
||||
</DataTemplate.Triggers>
|
||||
</DataTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</ItemsControl.Resources>
|
||||
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<s:DesignerCanvas Loaded="DesignerCanvas_Loaded"
|
||||
Height="{Binding PageSize.Height}"
|
||||
Width="{Binding PageSize.Width}"
|
||||
ShowGrid="{Binding ShowGrid}"
|
||||
GridCellSize="{Binding GridCellSize}"
|
||||
GridMargin="{Binding GridMargin}"
|
||||
GridColor="{Binding GridColor}"
|
||||
Background="{Binding PageBackground,Converter={StaticResource ColorBrushConverter}}"
|
||||
AllowDrop="True">
|
||||
</s:DesignerCanvas>
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
|
||||
</ItemsControl>
|
||||
</Grid>
|
||||
</Border>
|
||||
</UserControl>
|
||||
52
Util.DiagramDesigner/UserControls/DiagramControl.xaml.cs
Normal file
52
Util.DiagramDesigner/UserControls/DiagramControl.xaml.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for DiagramControl.xaml
|
||||
/// </summary>
|
||||
public partial class DiagramControl : UserControl
|
||||
{
|
||||
public DiagramControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty ZoomValueProperty = DependencyProperty.Register("ZoomValue", typeof(double), typeof(DiagramControl), new UIPropertyMetadata(1d));
|
||||
public double ZoomValue
|
||||
{
|
||||
get
|
||||
{
|
||||
return (double)GetValue(ZoomValueProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(ZoomValueProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void DesignerCanvas_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private async void ScaleTransform_Changed(object sender, EventArgs e)
|
||||
{
|
||||
await System.Threading.Tasks.Task.Delay(100);
|
||||
ZoomValue = scale.ScaleX;
|
||||
}
|
||||
}
|
||||
}
|
||||
101
Util.DiagramDesigner/UserControls/TextControl.xaml
Normal file
101
Util.DiagramDesigner/UserControls/TextControl.xaml
Normal file
@@ -0,0 +1,101 @@
|
||||
<UserControl x:Class="Util.DiagramDesigner.TextControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
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:Util.DiagramDesigner"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<UserControl.Resources>
|
||||
<s:ColorBrushConverter x:Key="ColorBrushConverter" />
|
||||
<s:TrueToFalseConverter x:Key="TrueToFalseConverter"/>
|
||||
<!--TextBox默认样式-->
|
||||
<Style TargetType="{x:Type TextBox}" x:Key="WaterTextBox">
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Setter Property="TextWrapping" Value="Wrap"/>
|
||||
<Setter Property="Width" Value="Auto"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
||||
<Setter Property="VerticalAlignment" Value="Stretch"/>
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type TextBox}">
|
||||
<Grid x:Name="PART_Root">
|
||||
<Border x:Name="Bg" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
Background="{TemplateBinding Background}" />
|
||||
<Grid x:Name="PART_InnerGrid">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!--内容区域-->
|
||||
<ScrollViewer x:Name="PART_ContentHost" BorderThickness="0" Grid.Column="1" IsTabStop="False" Margin="2"
|
||||
VerticalAlignment="Stretch" Background="{x:Null}" >
|
||||
<ScrollViewer.Effect>
|
||||
<DropShadowEffect x:Name="effect" Color="{Binding FontViewModel.TextEffectColor}" ></DropShadowEffect>
|
||||
</ScrollViewer.Effect>
|
||||
</ScrollViewer>
|
||||
<!--水印-->
|
||||
<TextBlock x:Name="Message" Padding="{TemplateBinding Padding}" Visibility="Collapsed"
|
||||
Text="{TemplateBinding s:ControlAttachProperty.Watermark}" Grid.Column="1"
|
||||
Foreground="{TemplateBinding Foreground}" IsHitTestVisible="False" Opacity="0.5"
|
||||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="5,2,5,2" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
<ControlTemplate.Triggers>
|
||||
<!--显示水印-->
|
||||
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Text}" Value="">
|
||||
<Setter TargetName="Message" Property="Visibility" Value="Visible" />
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding FontViewModel.TextEffectColor}" Value="Transparent">
|
||||
<Setter TargetName="PART_ContentHost" Property="Effect" Value="{x:Null}"/>
|
||||
</DataTrigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
<Grid IsHitTestVisible="{Binding IsHitTestVisible}">
|
||||
<TextBox x:Name="PART_TextBlock"
|
||||
Text="{Binding Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
Foreground="{Binding FontViewModel.FontColor,Converter={StaticResource ColorBrushConverter}}"
|
||||
FontSize="{Binding FontViewModel.FontSize}"
|
||||
FontFamily="{Binding FontViewModel.FontFamily}"
|
||||
FontWeight="{Binding FontViewModel.FontWeight}"
|
||||
FontStyle="{Binding FontViewModel.FontStyle}"
|
||||
FontStretch="{Binding FontViewModel.FontStretch}"
|
||||
TextDecorations="{Binding FontViewModel.TextDecorations}"
|
||||
HorizontalContentAlignment="{Binding FontViewModel.HorizontalAlignment}"
|
||||
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}}}"
|
||||
Style="{StaticResource WaterTextBox}" IsReadOnly="True">
|
||||
|
||||
</TextBox>
|
||||
<TextBox x:Name="PART_ShowText"
|
||||
Text="{Binding Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
Foreground="{Binding FontViewModel.FontColor,Converter={StaticResource ColorBrushConverter}}"
|
||||
IsReadOnly="{Binding IsReadOnly}"
|
||||
FontSize="{Binding FontViewModel.FontSize}"
|
||||
FontFamily="{Binding FontViewModel.FontFamily}"
|
||||
FontWeight="{Binding FontViewModel.FontWeight}"
|
||||
FontStyle="{Binding FontViewModel.FontStyle}"
|
||||
FontStretch="{Binding FontViewModel.FontStretch}"
|
||||
TextDecorations="{Binding FontViewModel.TextDecorations}"
|
||||
HorizontalContentAlignment="{Binding FontViewModel.HorizontalAlignment}"
|
||||
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}}}"
|
||||
Style="{StaticResource WaterTextBox}" Visibility="Collapsed">
|
||||
</TextBox>
|
||||
|
||||
</Grid>
|
||||
</UserControl>
|
||||
123
Util.DiagramDesigner/UserControls/TextControl.xaml.cs
Normal file
123
Util.DiagramDesigner/UserControls/TextControl.xaml.cs
Normal file
@@ -0,0 +1,123 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace Util.DiagramDesigner
|
||||
{
|
||||
/// <summary>
|
||||
/// TextControl.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class TextControl : UserControl
|
||||
{
|
||||
public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
|
||||
"DoubleEdit", typeof(bool), typeof(TextControl), new FrameworkPropertyMetadata(
|
||||
true));
|
||||
|
||||
public bool DoubleEdit
|
||||
{
|
||||
get => (bool)GetValue(TextProperty);
|
||||
set => SetValue(TextProperty, value);
|
||||
}
|
||||
|
||||
public TextControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.Loaded += TextControl_Loaded;
|
||||
}
|
||||
|
||||
|
||||
private void TextControl_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
(this.DataContext as SelectableDesignerItemViewModelBase).PropertyChanged += TextControl_PropertyChanged;
|
||||
TextControl_PropertyChanged(this.DataContext, new System.ComponentModel.PropertyChangedEventArgs("IsSelected"));
|
||||
}
|
||||
|
||||
private void TextControl_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == "IsSelected")
|
||||
{
|
||||
if (sender is SelectableDesignerItemViewModelBase itemViewModelBase)
|
||||
{
|
||||
if (itemViewModelBase.IsSelected == false)
|
||||
{
|
||||
PART_ShowText.Visibility = Visibility.Collapsed;
|
||||
PART_TextBlock.Visibility = Visibility.Visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnPreviewMouseDown(MouseButtonEventArgs e)
|
||||
{
|
||||
base.OnPreviewMouseDown(e);
|
||||
|
||||
if (DoubleEdit == false)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnPreviewMouseDoubleClick(MouseButtonEventArgs e)
|
||||
{
|
||||
base.OnPreviewMouseDoubleClick(e);
|
||||
|
||||
if (DoubleEdit == true)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ControlAttachProperty
|
||||
{
|
||||
#region WatermarkProperty 水印
|
||||
/// <summary>
|
||||
/// 水印
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty WatermarkProperty = DependencyProperty.RegisterAttached(
|
||||
"Watermark", typeof(string), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(""));
|
||||
|
||||
public static string GetWatermark(DependencyObject d)
|
||||
{
|
||||
return (string)d.GetValue(WatermarkProperty);
|
||||
}
|
||||
|
||||
public static void SetWatermark(DependencyObject obj, string value)
|
||||
{
|
||||
obj.SetValue(WatermarkProperty, value);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
38
Util.DiagramDesigner/Util.DiagramDesigner.csproj
Normal file
38
Util.DiagramDesigner/Util.DiagramDesigner.csproj
Normal file
@@ -0,0 +1,38 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netcoreapp3.1;net462;net472</TargetFrameworks>
|
||||
<UseWPF>true</UseWPF>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="Images\file.png" />
|
||||
<None Remove="Images\FormatPainter.cur" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.31" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="System.Reactive" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\WpfAnimatedGif\WpfAnimatedGif.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="$(DefineConstants.Contains(NETCOREAPP)) == true">
|
||||
<PackageReference Include="System.Drawing.Common" Version="5.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Resource Include="Images\file.png" />
|
||||
<Resource Include="Images\FormatPainter.cur" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="Images\Gifs\car_chase.gif">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
114
Util.DiagramDesigner/Util.DiagramDesigner_kn2lil5m_wpftmp.csproj
Normal file
114
Util.DiagramDesigner/Util.DiagramDesigner_kn2lil5m_wpftmp.csproj
Normal file
@@ -0,0 +1,114 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netcoreapp3.1;net462;net472</TargetFrameworks>
|
||||
<UseWPF>true</UseWPF>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Remove="Images\file.png" />
|
||||
<None Remove="Images\FormatPainter.cur" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.31" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="System.Reactive" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\WpfAnimatedGif\WpfAnimatedGif.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="$(DefineConstants.Contains(NETCOREAPP)) == true">
|
||||
<PackageReference Include="System.Drawing.Common" Version="5.0.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Update="Images\Gifs\Null.gif">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Images\Gifs\刮板.gif">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Images\Gifs\压缩机.gif">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Images\Gifs\双馈风机.gif">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Images\Gifs\圆锥破碎机.gif">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Images\Gifs\振动筛.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Images\Gifs\水泵.gif">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Images\Gifs\泥浆泵侧面.gif">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Images\Gifs\泥浆泵前端.gif">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Images\Gifs\泵.gif">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Images\Gifs\皮带.gif">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Images\Gifs\破碎机.PNG">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Images\Gifs\离心机.gif">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Images\Gifs\设备#1.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Images\Gifs\转子实验台.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Images\Gifs\风力发电机.gif">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Images\Gifs\风机.jpg">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Images\Gifs\风机轴.jpg">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ReferencePath Include="C:\Users\Administrator\.nuget\packages\microsoft.xaml.behaviors.wpf\1.1.31\lib\net45\Microsoft.Xaml.Behaviors.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\mscorlib.dll" />
|
||||
<ReferencePath Include="C:\Users\Administrator\.nuget\packages\newtonsoft.json\13.0.1\lib\net45\Newtonsoft.Json.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\PresentationCore.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\PresentationFramework.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\System.Core.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\System.Data.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\System.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\System.Drawing.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\System.IO.Compression.FileSystem.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\System.Numerics.dll" />
|
||||
<ReferencePath Include="C:\Users\Administrator\.nuget\packages\system.reactive\5.0.0\lib\net472\System.Reactive.dll" />
|
||||
<ReferencePath Include="C:\Users\Administrator\.nuget\packages\system.runtime.compilerservices.unsafe\4.5.3\ref\net461\System.Runtime.CompilerServices.Unsafe.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\System.Runtime.Serialization.dll" />
|
||||
<ReferencePath Include="C:\Users\Administrator\.nuget\packages\system.threading.tasks.extensions\4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\System.Windows.Controls.Ribbon.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\System.Windows.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\System.Windows.Forms.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\System.Xaml.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\System.Xml.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\System.Xml.Linq.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\UIAutomationClient.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\UIAutomationClientsideProviders.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\UIAutomationProvider.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\UIAutomationTypes.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\WindowsBase.dll" />
|
||||
<ReferencePath Include="F:\AIStudio.Wpf.Diagram\WpfAnimatedGif\bin\Debug\net4\WpfAnimatedGif.dll" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="F:\AIStudio.Wpf.Diagram\Util.DiagramDesigner\obj\Debug\net472\UserControls\ConnectorContainer.g.cs" />
|
||||
<Compile Include="F:\AIStudio.Wpf.Diagram\Util.DiagramDesigner\obj\Debug\net472\UserControls\DiagramControl.g.cs" />
|
||||
<Compile Include="F:\AIStudio.Wpf.Diagram\Util.DiagramDesigner\obj\Debug\net472\UserControls\TextControl.g.cs" />
|
||||
<Compile Include="F:\AIStudio.Wpf.Diagram\Util.DiagramDesigner\obj\Debug\net472\GeneratedInternalTypeHelper.g.cs" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
168
Util.DiagramDesigner/Util.DiagramDesigner_q2uer1wu_wpftmp.csproj
Normal file
168
Util.DiagramDesigner/Util.DiagramDesigner_q2uer1wu_wpftmp.csproj
Normal file
@@ -0,0 +1,168 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netcoreapp3.1;net462;net472</TargetFrameworks>
|
||||
<UseWPF>true</UseWPF>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Remove="Images\file.png" />
|
||||
<None Remove="Images\FormatPainter.cur" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.31" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="System.Reactive" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\WpfAnimatedGif\WpfAnimatedGif.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="$(DefineConstants.Contains(NETCOREAPP)) == true">
|
||||
<PackageReference Include="System.Drawing.Common" Version="5.0.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Update="Images\Gifs\car_chase.gif">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\Microsoft.Win32.Primitives.dll" />
|
||||
<ReferencePath Include="C:\Users\Administrator\.nuget\packages\microsoft.xaml.behaviors.wpf\1.1.31\lib\net45\Microsoft.Xaml.Behaviors.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\mscorlib.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\netfx.force.conflicts.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\netstandard.dll" />
|
||||
<ReferencePath Include="C:\Users\Administrator\.nuget\packages\newtonsoft.json\13.0.1\lib\net45\Newtonsoft.Json.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\PresentationCore.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\PresentationFramework.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.AppContext.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Collections.Concurrent.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Collections.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Collections.NonGeneric.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Collections.Specialized.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.ComponentModel.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.ComponentModel.EventBasedAsync.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.ComponentModel.Primitives.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.ComponentModel.TypeConverter.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Console.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\System.Core.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Data.Common.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\System.Data.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Diagnostics.Contracts.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Diagnostics.Debug.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Diagnostics.FileVersionInfo.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Diagnostics.Process.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Diagnostics.StackTrace.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Diagnostics.TextWriterTraceListener.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Diagnostics.Tools.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Diagnostics.TraceSource.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Diagnostics.Tracing.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\System.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\System.Drawing.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Drawing.Primitives.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Dynamic.Runtime.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Globalization.Calendars.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Globalization.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Globalization.Extensions.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.IO.Compression.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\System.IO.Compression.FileSystem.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.IO.Compression.ZipFile.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.IO.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.IO.FileSystem.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.IO.FileSystem.DriveInfo.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.IO.FileSystem.Primitives.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.IO.FileSystem.Watcher.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.IO.IsolatedStorage.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.IO.MemoryMappedFiles.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.IO.Pipes.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.IO.UnmanagedMemoryStream.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Linq.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Linq.Expressions.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Linq.Parallel.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Linq.Queryable.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Net.Http.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Net.NameResolution.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Net.NetworkInformation.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Net.Ping.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Net.Primitives.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Net.Requests.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Net.Security.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Net.Sockets.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Net.WebHeaderCollection.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Net.WebSockets.Client.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Net.WebSockets.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\System.Numerics.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.ObjectModel.dll" />
|
||||
<ReferencePath Include="C:\Users\Administrator\.nuget\packages\system.reactive\5.0.0\lib\netstandard2.0\System.Reactive.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Reflection.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Reflection.Extensions.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Reflection.Primitives.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Resources.Reader.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Resources.ResourceManager.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Resources.Writer.dll" />
|
||||
<ReferencePath Include="C:\Users\Administrator\.nuget\packages\system.runtime.compilerservices.unsafe\4.5.3\ref\net461\System.Runtime.CompilerServices.Unsafe.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Runtime.CompilerServices.VisualC.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Runtime.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Runtime.Extensions.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Runtime.Handles.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Runtime.InteropServices.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net462\lib\System.Runtime.InteropServices.RuntimeInformation.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Runtime.Numerics.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\System.Runtime.Serialization.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Runtime.Serialization.Formatters.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Runtime.Serialization.Json.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Runtime.Serialization.Primitives.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Runtime.Serialization.Xml.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Security.Claims.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Security.Cryptography.Algorithms.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Security.Cryptography.Csp.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Security.Cryptography.Encoding.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Security.Cryptography.Primitives.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Security.Cryptography.X509Certificates.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Security.Principal.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Security.SecureString.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Text.Encoding.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Text.Encoding.Extensions.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Text.RegularExpressions.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Threading.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Threading.Overlapped.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Threading.Tasks.dll" />
|
||||
<ReferencePath Include="C:\Users\Administrator\.nuget\packages\system.threading.tasks.extensions\4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Threading.Tasks.Parallel.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Threading.Thread.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Threading.ThreadPool.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Threading.Timer.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.ValueTuple.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\System.Windows.Controls.Ribbon.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\System.Xaml.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\System.Xml.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\System.Xml.Linq.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Xml.ReaderWriter.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Xml.XDocument.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Xml.XmlDocument.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Xml.XmlSerializer.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Xml.XPath.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Xml.XPath.XDocument.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\UIAutomationClient.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\UIAutomationClientsideProviders.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\UIAutomationProvider.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\UIAutomationTypes.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\WindowsBase.dll" />
|
||||
<ReferencePath Include="F:\AIStudio.Wpf.Diagram\WpfAnimatedGif\bin\Debug\net4\WpfAnimatedGif.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\Facades\System.ComponentModel.Annotations.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\Facades\System.Reflection.Emit.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\Facades\System.Reflection.Emit.ILGeneration.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\Facades\System.Reflection.Emit.Lightweight.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\Facades\System.Runtime.InteropServices.WindowsRuntime.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\Facades\System.ServiceModel.Duplex.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\Facades\System.ServiceModel.Http.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\Facades\System.ServiceModel.NetTcp.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\Facades\System.ServiceModel.Primitives.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\Facades\System.ServiceModel.Security.dll" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="F:\AIStudio.Wpf.Diagram\Util.DiagramDesigner\obj\Debug\net462\UserControls\ConnectorContainer.g.cs" />
|
||||
<Compile Include="F:\AIStudio.Wpf.Diagram\Util.DiagramDesigner\obj\Debug\net462\UserControls\DiagramControl.g.cs" />
|
||||
<Compile Include="F:\AIStudio.Wpf.Diagram\Util.DiagramDesigner\obj\Debug\net462\UserControls\TextControl.g.cs" />
|
||||
<Compile Include="F:\AIStudio.Wpf.Diagram\Util.DiagramDesigner\obj\Debug\net462\GeneratedInternalTypeHelper.g.cs" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user