using System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using AIStudio.Wpf.DiagramDesigner; using AIStudio.Wpf.DiagramDesigner.Geometrys; using AIStudio.Wpf.Flowchart.Models; namespace AIStudio.Wpf.Flowchart.Controls { /// /// FlowchartEditor.xaml 的交互逻辑 /// [TemplatePart(Name = PART_DiagramControl, Type = typeof(DiagramControl))] public partial class FlowchartEditor : UserControl { public const string PART_DiagramControl = "PART_DiagramControl"; private DiagramControl _diagramControl; private IDiagramViewModel _diagramViewModel; static FlowchartEditor() { DefaultStyleKeyProperty.OverrideMetadata(typeof(FlowchartEditor), new FrameworkPropertyMetadata(typeof(FlowchartEditor))); } public FlowchartEditor() { _diagramViewModel = new DiagramViewModel(); _diagramViewModel.SetScreenScale(); _diagramViewModel.ShowGrid = true; _diagramViewModel.GridCellSize = new SizeBase(125 / _diagramViewModel.ScreenScale, 125 / _diagramViewModel.ScreenScale); _diagramViewModel.GridMarginSize = new Size(0, 0); _diagramViewModel.CellHorizontalAlignment = CellHorizontalAlignment.Center; _diagramViewModel.CellVerticalAlignment = CellVerticalAlignment.Center; _diagramViewModel.PageSizeType = PageSizeType.Custom; _diagramViewModel.PageSize = new SizeBase(double.NaN, double.NaN); _diagramViewModel.ColorViewModel = new ColorViewModel() { LineWidth = 2 }; //_diagramViewModel.DrawModeViewModel = new DrawModeViewModel() { LineDrawMode = DrawMode.BoundaryConnectingLine }; _diagramViewModel.PropertyChanged += DiagramViewModel_PropertyChanged; } public override void OnApplyTemplate() { base.OnApplyTemplate(); _diagramControl = GetTemplateChild(PART_DiagramControl) as DiagramControl; _diagramControl.HorizontalAlignment = HorizontalAlignment.Stretch; _diagramControl.VerticalAlignment = VerticalAlignment.Stretch; _diagramControl.DataContext = _diagramViewModel; GetDataFunc = GetData; } private void DiagramViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == "IsSelected") { SelectedObject = _diagramViewModel.SelectedItems?.FirstOrDefault(); } } //一点要绑定不为空的FlowchartModel才能用,即便为空的也要new一个再来绑定 public static readonly DependencyProperty DataProperty = DependencyProperty.Register(nameof(Data), typeof(string), typeof(FlowchartEditor), new FrameworkPropertyMetadata(null, OnDataChanged)); public string Data { get { return (string)GetValue(DataProperty); } set { SetValue(DataProperty, value); } } private static void OnDataChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var view = d as FlowchartEditor; var json = e.NewValue as string; if (json != null) { view.CreateFlowchartModel(json); } } private void CreateFlowchartModel(string json) { _diagramViewModel.IsLoading = true; _diagramViewModel.Items.Clear(); _diagramViewModel.ToObject(json); _diagramViewModel.IsLoading = false; } public static readonly DependencyProperty GetDataFuncProperty = DependencyProperty.Register(nameof(GetDataFunc), typeof(Func), typeof(FlowchartEditor), new FrameworkPropertyMetadata(null)); public Func GetDataFunc { get { return (Func)this.GetValue(GetDataFuncProperty); } set { this.SetValue(GetDataFuncProperty, value); } } public Func GetData { get { return new Func(() => _diagramViewModel.ToJson()); } } public static readonly DependencyProperty ModeProperty = DependencyProperty.Register(nameof(Mode), typeof(string), typeof(FlowchartEditor), new FrameworkPropertyMetadata("Edit", OnModeChanged)); public string Mode { get { return (string)GetValue(ModeProperty); } set { SetValue(ModeProperty, value); } } private static void OnModeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var view = d as FlowchartEditor; var mode = e.NewValue as string; if (mode != "Edit") { view._diagramViewModel.IsReadOnly = true; } else { view._diagramViewModel.IsReadOnly = false; } } #region ToolBox /// /// 附加组件模板 /// public static readonly DependencyProperty ToolBoxProperty = DependencyProperty.Register( nameof(ToolBox), typeof(ControlTemplate), typeof(FlowchartEditor), new FrameworkPropertyMetadata(default(ControlTemplate))); public ControlTemplate ToolBox { get { return (ControlTemplate)GetValue(ToolBoxProperty); } set { SetValue(ToolBoxProperty, value); } } #endregion #region PropertiesBox /// /// 附加组件模板 /// public static readonly DependencyProperty PropertiesBoxProperty = DependencyProperty.Register( nameof(PropertiesBox), typeof(ControlTemplate), typeof(FlowchartEditor), new FrameworkPropertyMetadata(default(ControlTemplate))); public ControlTemplate PropertiesBox { get { return (ControlTemplate)GetValue(PropertiesBoxProperty); } set { SetValue(PropertiesBoxProperty, value); } } #endregion #region SelectedObject public static readonly DependencyProperty SelectedObjectProperty = DependencyProperty.Register(nameof(SelectedObject), typeof(object), typeof(FlowchartEditor), new UIPropertyMetadata(default(object))); public object SelectedObject { get { return (object)GetValue(SelectedObjectProperty); } set { SetValue(SelectedObjectProperty, value); } } #endregion #region Users public static readonly DependencyProperty UsersProperty = DependencyProperty.Register(nameof(Users), typeof(List), typeof(FlowchartEditor), new UIPropertyMetadata(default(List))); public List Users { get { return (List)GetValue(UsersProperty); } set { SetValue(UsersProperty, value); } } #endregion #region Roles public static readonly DependencyProperty RolesProperty = DependencyProperty.Register(nameof(Roles), typeof(List), typeof(FlowchartEditor), new UIPropertyMetadata(default(List))); public List Roles { get { return (List)GetValue(RolesProperty); } set { SetValue(RolesProperty, value); } } #endregion protected override void OnPreviewKeyDown(KeyEventArgs e) { base.OnPreviewKeyDown(e); bool executed = true; var para = e.KeyboardDevice.Modifiers == ModifierKeys.None ? e.Key.ToString() : e.KeyboardDevice.Modifiers.ToString() + "+" + e.Key.ToString(); switch (para) { case "Control+A": _diagramViewModel.SelectAllCommand.Execute(null); break; case "Control+C": _diagramViewModel.CopyCommand.Execute(null); break; case "Control+V": _diagramViewModel.PasteCommand.Execute(null); break; case "Control+X": _diagramViewModel.CutCommand.Execute(null); break; case "Control+Z": _diagramViewModel.UndoCommand.Execute(null); break; case "Control+Y": _diagramViewModel.RedoCommand.Execute(null); break; case "Delete": _diagramViewModel.DeleteCommand.Execute(null); break; case "Left": _diagramViewModel.LeftMoveCommand.Execute(null); break; case "Right": _diagramViewModel.RightMoveCommand.Execute(null); break; case "Up": _diagramViewModel.UpMoveCommand.Execute(null); break; case "Down": _diagramViewModel.DownMoveCommand.Execute(null); break; default: executed = false; break; } e.Handled = executed; } } }