using Microsoft.Win32; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.ComponentModel; using System.IO; 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 WPFDemo { /// /// SiloPanel.xaml 的交互逻辑 /// public partial class SiloPanel : UserControl, INotifyPropertyChanged { //料仓模块左键按下标识 bool siloIsMouseDown = false; //画线标识 bool lineIsDraw = false; //当前线条 private Line currentLine; //线条集合 private List lines = new List(); //料仓集合 private List silos = new List(); //用于序列化 private Segment segment = new Segment(); //提示 private string tips = "常规模式"; /// /// 提示 /// public string Tips { get { return tips; } set { tips = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Tips")); } } /// /// 当前选中的料仓 /// public Silo CurrentSilo { get; private set; } /// /// 画布宽度 /// public double PanelWidth { get { return (double)GetValue(PanelWidthProperty); } set { SetValue(PanelWidthProperty, value); } } // Using a DependencyProperty as the backing store for PanelWidth. This enables animation, styling, binding, etc... public static readonly DependencyProperty PanelWidthProperty = DependencyProperty.Register("PanelWidth", typeof(double), typeof(SiloPanel), new PropertyMetadata(1920d)); /// /// 画布高度 /// public double PanelHeight { get { return (double)GetValue(PanelHeightProperty); } set { SetValue(PanelHeightProperty, value); } } // Using a DependencyProperty as the backing store for PanelHeight. This enables animation, styling, binding, etc... public static readonly DependencyProperty PanelHeightProperty = DependencyProperty.Register("PanelHeight", typeof(double), typeof(SiloPanel), new PropertyMetadata(1080d)); public event PropertyChangedEventHandler? PropertyChanged; public SiloPanel() { InitializeComponent(); cvMain.PreviewMouseLeftButtonDown += CvMain_PreviewMouseLeftButtonDown; cvMain.PreviewMouseMove += CvMain_PreviewMouseMove; cvMain.PreviewMouseLeftButtonUp += CvMain_PreviewMouseLeftButtonUp; } /// /// 开始画线 /// public void AddLine() { lineIsDraw = true; Tips = "线条绘制"; } /// /// 添加料仓模块 /// public void AddSilo() { if (lineIsDraw) lineIsDraw = false; newSilo(String.Empty, String.Empty); } /// /// 保存文件 /// public void Save() { segment.Silos.Clear(); segment.Lines.Clear(); lines.ForEach(line => { segment.Lines.Add(new Segment.SimpleLine() { X1 = line.X1, X2 = line.X2, Y1 = line.Y1, Y2 = line.Y2 }); }); silos.ForEach(silo => { segment.Silos.Add(new Segment.SimpleSilo() { Left = (double)silo.GetValue(Canvas.LeftProperty), Top = (double)silo.GetValue(Canvas.TopProperty), Caption = silo.Caption, Index = silo.Index }); }); string ResultJson = JsonConvert.SerializeObject(segment); SaveFileDialog dialog = new SaveFileDialog(); dialog.Filter = "配置文件|*.json"; if (dialog.ShowDialog() == true) { File.WriteAllText(dialog.FileName, ResultJson); } } /// /// 加载文件 /// public void Load() { OpenFileDialog dialog = new OpenFileDialog(); dialog.Filter = "配置文件|*.json"; if (dialog.ShowDialog() == true) { string content = File.ReadAllText(dialog.FileName); try { segment = JsonConvert.DeserializeObject(content); lines.Clear(); silos.Clear(); cvMain.Children.Clear(); foreach (var line in segment.Lines) { newLine(line.X1, line.Y1, line.X2, line.Y2); } foreach (var temp in segment.Silos) { newSilo(temp.Caption, temp.Index,temp.Left,temp.Top); } } catch (Exception ex) { MessageBox.Show(ex.Message); } } } /// /// 清空画布 /// public void Clear() { lines.Clear(); silos.Clear(); cvMain.Children.Clear(); } private void newSilo(string caption, string index, double left = -1, double top = -1) { Silo silo = new Silo() { Caption = caption, Index = index }; if (left == -1) silo.SetValue(Canvas.LeftProperty, cvMain.ActualWidth / 2 - silo.Width / 2); else silo.SetValue(Canvas.LeftProperty, left); if (top == -1) silo.SetValue(Canvas.TopProperty, cvMain.ActualHeight / 2 - silo.Height / 2); else silo.SetValue(Canvas.TopProperty, top); silo.AllowDrop = true; cvMain.Children.Add(silo); silos.Add(silo); silo.PreviewMouseLeftButtonDown += Silo_PreviewMouseLeftButtonDown; silo.PreviewMouseMove += Silo_PreviewMouseMove; silo.PreviewMouseLeftButtonUp += Silo_PreviewMouseLeftButtonUp; CurrentSilo = silo; } private void newLine(double x1, double y1, double x2, double y2) { var temp = new Line(); temp.Stroke = Brushes.Green; temp.StrokeThickness = 1; temp.X1 = x1; temp.Y1 = y1; temp.X2 = x2; temp.Y2 = y2; cvMain.Children.Add(temp); lines.Add(temp); currentLine = temp; } private void CvMain_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e) { lineIsDraw = false; Tips = "常规模式"; } private void CvMain_PreviewMouseMove(object sender, MouseEventArgs e) { if (e.LeftButton == MouseButtonState.Pressed && lineIsDraw) { Point point = e.GetPosition(cvMain); currentLine.X2 = point.X; currentLine.Y2 = point.Y; } } private void CvMain_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { if (!lineIsDraw) return; var point = e.GetPosition(cvMain); newLine(point.X, point.Y, point.X, point.Y); } private void Silo_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e) { var c = sender as UIElement; siloIsMouseDown = false; c.ReleaseMouseCapture(); CurrentSilo = sender as Silo; } private void Silo_PreviewMouseMove(object sender, MouseEventArgs e) { if (siloIsMouseDown) { var c = sender as UIElement; var pos = e.GetPosition(this); c.SetValue(Canvas.LeftProperty, pos.X); c.SetValue(Canvas.TopProperty, pos.Y); } } private void Silo_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { var c = sender as UIElement; siloIsMouseDown = true; var transform = c.RenderTransform as TranslateTransform; if (transform == null) { transform = new TranslateTransform(); c.RenderTransform = transform; } c.CaptureMouse(); } } }