using 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);
|
}
|
}
|
}
|