From 9d1660270272180cd71147d6ddd53d1382643d2e Mon Sep 17 00:00:00 2001
From: wenxiangchao <wenxiangchao@ihengxin.com.cn>
Date: 星期一, 02 十一月 2026 18:00:14 +0800
Subject: [PATCH] merge: 并入远程 Initial commit 作为历史根节点
---
HMI.UI/MDI/Workspace.xaml.cs | 366 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 366 insertions(+), 0 deletions(-)
diff --git a/HMI.UI/MDI/Workspace.xaml.cs b/HMI.UI/MDI/Workspace.xaml.cs
new file mode 100644
index 0000000..01ae0a9
--- /dev/null
+++ b/HMI.UI/MDI/Workspace.xaml.cs
@@ -0,0 +1,366 @@
+锘縰sing HMI.Core.Util;
+using HMI.UI.Converter;
+using HMI.UI.DpUtil;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+
+namespace HMI.UI.MDI
+{
+ public class WorkspaceSetting
+ {
+ public bool IsLocked { get; set; }
+ public List<Position> positions { get; set; } = new List<Position>();
+ }
+ public class Position
+ {
+ public string Key { get; set; }
+ public double Left { get; set; }
+ public double Top { get; set; }
+ public double Width { get; set; }
+ public double Height { get; set; }
+ }
+ /// <summary>
+ /// Workspace.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class Workspace : UserControl
+ {
+
+ public Workspace()
+ {
+ InitializeComponent();
+ }
+
+ private WorkspaceSetting setting;
+
+ private Dictionary<string, InnerWindow> nameMap
+ = new Dictionary<string, InnerWindow>();
+
+ private Dictionary<string, Position> positionMap
+ = new Dictionary<string, Position>();
+
+ public static readonly DependencyProperty SettingPathProperty = DependencyProperty.Register(
+ "SettingPath",
+ typeof(string),
+ typeof(Workspace),
+ new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnSettingChanged)));
+
+ private static void OnSettingChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e)
+ {
+ if (dp is Workspace ws && e.Property == SettingPathProperty)
+ {
+ try
+ {
+ if (!File.Exists(e.NewValue.ToString()))
+ {
+ throw new Exception("Empty Workspace Setting.");
+ }
+ ws.setting = XmlHelper.DeserializeFromXml<WorkspaceSetting>(e.NewValue.ToString());
+ if (ws?.setting != null)
+ {
+ ws.IsLocked = ws.setting.IsLocked;
+ ws.positionMap = ws.setting.positions.ToDictionary(p => p.Key, p => p);
+ }
+ else
+ {
+ ws.positionMap.Clear();
+ }
+ }
+ catch
+ {
+ ws.setting = new WorkspaceSetting();
+ ws.positionMap.Clear();
+ }
+ }
+ }
+
+ private CanvasPosition GetPositionByIndex(int index)
+ {
+ double step = 15;
+ return new CanvasPosition
+ {
+ Left = (index + 1) * step,
+ Top = (index + 1) * step,
+ Width = 0.75 * ActualWidth,
+ Height = 0.75 * ActualHeight
+ };
+ }
+
+ public string SettingPath
+ {
+ get => (string)GetValue(SettingPathProperty);
+ set => SetValue(SettingPathProperty, value);
+ }
+
+ private int InnerWindowCount = 0;
+
+ public void AddInnerWindow(InnerWindow innerWindow)
+ {
+ AddInnerWindow(innerWindow, GetPositionByIndex(WorkArea.Children.Count));
+ }
+
+ public void AddInnerWindow(InnerWindow innerWindow, CanvasPosition canvasPosition)
+ {
+ HandleInnerWindow(innerWindow);
+ UpdatePosition(innerWindow, canvasPosition);
+ }
+
+ public void AddInnerWindow(string key, InnerWindow innerWindow)
+ {
+ if (nameMap.ContainsKey(key))
+ {
+ throw new Exception("Key Exists");
+ }
+ if (positionMap.ContainsKey(key))
+ {
+ var position = positionMap[key];
+ AddInnerWindow(innerWindow, new CanvasPosition
+ {
+ Left = position.Left * WorkArea.ActualWidth,
+ Top = position.Top * WorkArea.ActualHeight,
+ Width = position.Width * WorkArea.ActualWidth,
+ Height = position.Height * WorkArea.ActualHeight
+ });
+ }
+ else
+ {
+ AddInnerWindow(innerWindow);
+ }
+ nameMap.Add(key, innerWindow);
+ }
+
+ public void UpdatePosition(InnerWindow inner, CanvasPosition position)
+ {
+ inner.canvasPosition = position;
+ inner.Width = position.Width;
+ inner.Height = position.Height;
+ Canvas.SetLeft(inner, position.Left);
+ Canvas.SetTop(inner, position.Top);
+ }
+
+ /// <summary>
+ /// 璁剧疆InnerWindow
+ /// </summary>
+ /// <param name="inner"></param>
+ private void HandleInnerWindow(InnerWindow inner)
+ {
+ inner.MinEvent += InnerWindowMin;
+ inner.MaxEvent += InnerWindowMax;
+ inner.LockEvent += Inner_LockEvent;
+ inner.ZIndexEvent += Inner_ZIndexEvent;
+ inner.GotFocus += Inner_GotFocus;
+ inner.AttachToCanvas(WorkArea);
+ inner.CanResize = !IsLoaded;
+ Binding binding = new Binding("IsLocked")
+ {
+ Source = this,
+ Mode = BindingMode.OneWay,
+ Converter = new ReverseBoolConverter(),
+ UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
+ };
+ inner.SetBinding(InnerWindow.CanResizeProperty, binding);
+ inner.Zindex = InnerWindowCount++;
+ }
+
+ private void Inner_LockEvent(object sender, EventArgs e)
+ {
+ var inner = sender as InnerWindow;
+ var left = Canvas.GetLeft(inner) / WorkArea.ActualWidth;
+ var top = Canvas.GetTop(inner) / WorkArea.ActualHeight;
+ var width = inner.ActualWidth / WorkArea.ActualWidth;
+ var height = inner.ActualHeight / WorkArea.ActualHeight;
+
+ positionMap[inner.Title] = new Position
+ {
+ Left = left,
+ Top = top,
+ Width = width,
+ Height = height
+ };
+
+ List<Position> ps = new List<Position>();
+ foreach (var key in positionMap.Keys)
+ {
+ positionMap[key].Key = key;
+ ps.Add(positionMap[key]);
+ }
+
+ XmlHelper.SerializeToXml(SettingPath, ps);
+ }
+
+ /// <summary>
+ /// 搴曢儴MinInnerWindow澶勭悊
+ /// </summary>
+ /// <param name="inner"></param>
+ private void HandleMinInnerWindow(InnerWindow inner)
+ {
+ MinInnerWindow min = new MinInnerWindow(inner);
+ min.MaxEvent += MinInnerWindowMax;
+ min.CloseEvent += MinInnerWindowClose;
+ BottomBar.AddMinWindow(min);
+ }
+
+ /// <summary>
+ /// InnerWindow鐒︾偣浜嬩欢
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ private void Inner_GotFocus(object sender, RoutedEventArgs e)
+ {
+ CanvasHelper.SetTopZIndex(sender as InnerWindow, WorkArea, typeof(InnerWindow));
+ }
+
+ /// <summary>
+ /// InnerWindow ZIndex鍒囨崲浜嬩欢
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ private void Inner_ZIndexEvent(object sender, EventArgs e)
+ {
+ CanvasHelper.SetTopZIndex(sender as InnerWindow, WorkArea, typeof(InnerWindow));
+ }
+
+ /// <summary>
+ /// InnerWindow鏈�灏忓寲浜嬩欢
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ private void InnerWindowMin(object sender, System.EventArgs e)
+ {
+ InnerWindow inner = sender as InnerWindow;
+ inner.Visibility = Visibility.Collapsed;
+ HandleMinInnerWindow(inner);
+ }
+
+ /// <summary>
+ /// InnerWindow鏈�澶у寲浜嬩欢
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ private void InnerWindowMax(object sender, System.EventArgs e)
+ {
+ InnerWindow inner = sender as InnerWindow;
+ if (inner.WindowState == WindowState.Maximized)
+ {
+ Canvas.SetLeft(inner, inner.canvasPosition.Left);
+ Canvas.SetTop(inner, inner.canvasPosition.Top);
+
+ inner.Width = inner.canvasPosition.Width;
+ inner.Height = inner.canvasPosition.Height;
+ inner.WindowState = WindowState.Normal;
+ }
+ else
+ {
+ inner.canvasPosition.Left = Canvas.GetLeft(inner);
+ inner.canvasPosition.Top = Canvas.GetTop(inner);
+ inner.canvasPosition.Width = inner.ActualWidth;
+ inner.canvasPosition.Height = inner.ActualHeight;
+ Canvas.SetLeft(inner, 0);
+ Canvas.SetTop(inner, 0);
+ inner.Width = WorkArea.ActualWidth;
+ inner.Height = WorkArea.ActualHeight;
+ inner.WindowState = WindowState.Maximized;
+ }
+ }
+
+ /// <summary>
+ /// 搴曢儴MinInnerWindow灞曞紑
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ private void MinInnerWindowMax(object sender, System.EventArgs e)
+ {
+ MinInnerWindow min = sender as MinInnerWindow;
+ min.Inner.Visibility = Visibility.Visible;
+ CanvasHelper.SetTopZIndex(min.Inner, WorkArea, typeof(InnerWindow));
+ BottomBar.RemoveMinWindow(min);
+ }
+
+ /// <summary>
+ /// 搴曢儴MinInnerWin鍏抽棴
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ private void MinInnerWindowClose(object sender, System.EventArgs e)
+ {
+ MinInnerWindow min = sender as MinInnerWindow;
+ BottomBar.RemoveMinWindow(min);
+ }
+
+ private void MenuItem_Click(object sender, RoutedEventArgs e)
+ {
+ foreach (var inner in nameMap.Values)
+ {
+ var left = Canvas.GetLeft(inner) / WorkArea.ActualWidth;
+ var top = Canvas.GetTop(inner) / WorkArea.ActualHeight;
+ var width = inner.ActualWidth / WorkArea.ActualWidth;
+ var height = inner.ActualHeight / WorkArea.ActualHeight;
+ positionMap[inner.Title] = new Position
+ {
+ Left = left,
+ Top = top,
+ Width = width,
+ Height = height
+ };
+ }
+ List<Position> ps = new List<Position>();
+ foreach (var key in positionMap.Keys)
+ {
+ positionMap[key].Key = key;
+ ps.Add(positionMap[key]);
+ }
+ setting.positions = ps;
+ XmlHelper.SerializeToXml(SettingPath, setting);
+ }
+
+ public static readonly DependencyProperty IsLockedProperty = DependencyProperty.Register(
+ "IsLocked",
+ typeof(bool),
+ typeof(Workspace),
+ new FrameworkPropertyMetadata(false));
+
+ public bool IsLocked
+ {
+ get => (bool)GetValue(IsLockedProperty);
+ private set
+ {
+ if (setting != null)
+ {
+ setting.IsLocked = value;
+ }
+ SetValue(IsLockedProperty, value);
+ }
+ }
+
+ private void MenuItem_Checked(object sender, RoutedEventArgs e)
+ {
+ IsLocked = !IsLocked;
+ foreach (var inner in nameMap.Values)
+ {
+ var left = Canvas.GetLeft(inner) / WorkArea.ActualWidth;
+ var top = Canvas.GetTop(inner) / WorkArea.ActualHeight;
+ var width = inner.ActualWidth / WorkArea.ActualWidth;
+ var height = inner.ActualHeight / WorkArea.ActualHeight;
+ positionMap[inner.Title] = new Position
+ {
+ Left = left,
+ Top = top,
+ Width = width,
+ Height = height
+ };
+ }
+ List<Position> ps = new List<Position>();
+ foreach (var key in positionMap.Keys)
+ {
+ positionMap[key].Key = key;
+ ps.Add(positionMap[key]);
+ }
+ setting.positions = ps;
+ XmlHelper.SerializeToXml(SettingPath, setting);
+ }
+ }
+}
--
Gitblit v1.9.1