Inverting ifs, using switchcases etc. The things the IDE likes more.

This commit is contained in:
Matěj Kubíček
2026-03-28 21:22:31 +01:00
parent 9e88ce1cee
commit e46f38d153
4 changed files with 243 additions and 227 deletions
+1 -3
View File
@@ -1,6 +1,4 @@
using System.Configuration; using System.Windows;
using System.Data;
using System.Windows;
namespace NetworkDiagram; namespace NetworkDiagram;
+3 -5
View File
@@ -1,13 +1,11 @@
using System;
using System.Linq;
using System.Windows; using System.Windows;
using NetworkDiagram.Models; using NetworkDiagram.Models;
namespace NetworkDiagram namespace NetworkDiagram
{ {
public partial class EditDeviceWindow : Window public partial class EditDeviceWindow
{ {
private PlacedDevice _device; private readonly PlacedDevice _device;
public EditDeviceWindow(PlacedDevice device) public EditDeviceWindow(PlacedDevice device)
{ {
@@ -20,7 +18,7 @@ namespace NetworkDiagram
private void Save_Click(object sender, RoutedEventArgs e) private void Save_Click(object sender, RoutedEventArgs e)
{ {
_device.Name = NameBox.Text; _device.Name = NameBox.Text;
_device.IpAddresses = IpBox.Text.Split(new[] { Environment.NewLine, "\n", "\r" }, StringSplitOptions.RemoveEmptyEntries).ToList(); _device.IpAddresses = IpBox.Text.Split([Environment.NewLine, "\n", "\r"], StringSplitOptions.RemoveEmptyEntries).ToList();
DialogResult = true; DialogResult = true;
Close(); Close();
} }
+198 -184
View File
@@ -1,9 +1,5 @@
using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Text.Json; using System.Text.Json;
using System.Text.Json.Serialization;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Input; using System.Windows.Input;
@@ -16,13 +12,13 @@ using Path = System.IO.Path;
namespace NetworkDiagram namespace NetworkDiagram
{ {
public partial class MainWindow : Window public partial class MainWindow
{ {
private List<DeviceTemplate> _deviceTemplates = new List<DeviceTemplate>(); private List<DeviceTemplate> _deviceTemplates = [];
private Diagram _currentDiagram = new Diagram(); private Diagram _currentDiagram = new();
// Selection & Dragging // Selection & Dragging
private HashSet<FrameworkElement> _selectedElements = new HashSet<FrameworkElement>(); private readonly HashSet<FrameworkElement> _selectedElements = [];
private Point _dragStartPoint; private Point _dragStartPoint;
private bool _isDraggingDevices; private bool _isDraggingDevices;
private bool _isSelectingArea; private bool _isSelectingArea;
@@ -31,8 +27,8 @@ namespace NetworkDiagram
private ConnectionType? _activeTool; private ConnectionType? _activeTool;
private PlacedDevice? _firstDeviceForConnection; private PlacedDevice? _firstDeviceForConnection;
private Dictionary<Connection, Line> _connectionLines = new Dictionary<Connection, Line>(); private readonly Dictionary<Connection, Line> _connectionLines = new();
private Dictionary<PlacedDevice, FrameworkElement> _deviceElements = new Dictionary<PlacedDevice, FrameworkElement>(); private readonly Dictionary<PlacedDevice, FrameworkElement> _deviceElements = new();
public MainWindow() public MainWindow()
{ {
@@ -44,40 +40,42 @@ namespace NetworkDiagram
{ {
try try
{ {
if (File.Exists("devices.json")) if (!File.Exists("devices.json")) return;
var json = File.ReadAllText("devices.json");
_deviceTemplates = JsonSerializer.Deserialize<List<DeviceTemplate>>(json) ?? [];
foreach (var t in _deviceTemplates.Where(t => !string.IsNullOrEmpty(t.IconPath)))
{ {
string json = File.ReadAllText("devices.json"); t.IconPath = Path.GetFullPath(t.IconPath);
_deviceTemplates = JsonSerializer.Deserialize<List<DeviceTemplate>>(json) ?? new List<DeviceTemplate>();
foreach(var t in _deviceTemplates)
{
if (!string.IsNullOrEmpty(t.IconPath)) t.IconPath = Path.GetFullPath(t.IconPath);
}
ToolboxList.ItemsSource = _deviceTemplates;
} }
ToolboxList.ItemsSource = _deviceTemplates;
} }
catch (Exception ex) { MessageBox.Show($"Error loading templates: {ex.Message}"); } catch (Exception ex) { MessageBox.Show($"Error loading templates: {ex.Message}"); }
} }
private string GetLocalizedString(string key) => Application.Current.Resources[key] as string ?? key; private static string GetLocalizedString(string key) => Application.Current.Resources[key] as string ?? key;
private void LangCombo_SelectionChanged(object sender, SelectionChangedEventArgs e) private void LangCombo_SelectionChanged(object sender, SelectionChangedEventArgs e)
{ {
if (LangCombo.SelectedItem is ComboBoxItem item && item.Tag is string lang) if (LangCombo.SelectedItem is not ComboBoxItem { Tag: string lang }) return;
var dict = new ResourceDictionary
{ {
var dict = new ResourceDictionary(); Source = new Uri($"Localization/Strings.{lang}.xaml", UriKind.Relative)
dict.Source = new Uri($"Localization/Strings.{lang}.xaml", UriKind.Relative); };
// Replace the existing localization dictionary // Replace the existing localization dictionary
var oldDict = Application.Current.Resources.MergedDictionaries.FirstOrDefault(d => d.Source != null && d.Source.OriginalString.Contains("Localization/Strings.")); var oldDict = Application.Current.Resources.MergedDictionaries.FirstOrDefault(d => d.Source != null && d.Source.OriginalString.Contains("Localization/Strings."));
if (oldDict != null) Application.Current.Resources.MergedDictionaries.Remove(oldDict); if (oldDict != null) Application.Current.Resources.MergedDictionaries.Remove(oldDict);
Application.Current.Resources.MergedDictionaries.Add(dict); Application.Current.Resources.MergedDictionaries.Add(dict);
}
} }
#region Drag and Drop (Toolbox to Canvas) #region Drag and Drop (Toolbox to Canvas)
private void Toolbox_PreviewMouseDown(object sender, MouseButtonEventArgs e) private void Toolbox_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{ {
if (sender is ListBox listBox && listBox.SelectedItem is DeviceTemplate template) if (sender is ListBox { SelectedItem: DeviceTemplate template } listBox)
DragDrop.DoDragDrop(listBox, template, DragDropEffects.Copy); DragDrop.DoDragDrop(listBox, template, DragDropEffects.Copy);
} }
@@ -89,12 +87,11 @@ namespace NetworkDiagram
private void DiagramCanvas_Drop(object sender, DragEventArgs e) private void DiagramCanvas_Drop(object sender, DragEventArgs e)
{ {
if (e.Data.GetDataPresent(typeof(DeviceTemplate))) if (!e.Data.GetDataPresent(typeof(DeviceTemplate))) return;
{
var template = (DeviceTemplate)e.Data.GetData(typeof(DeviceTemplate)); var template = (DeviceTemplate)e.Data.GetData(typeof(DeviceTemplate));
Point dropPoint = e.GetPosition(DiagramCanvas); var dropPoint = e.GetPosition(DiagramCanvas);
AddDeviceToCanvas(template, dropPoint.X, dropPoint.Y); AddDeviceToCanvas(template, dropPoint.X, dropPoint.Y);
}
} }
#endregion #endregion
@@ -118,18 +115,26 @@ namespace NetworkDiagram
Canvas.SetLeft(container, device.X); Canvas.SetLeft(container, device.X);
Canvas.SetTop(container, device.Y); Canvas.SetTop(container, device.Y);
device.PropertyChanged += (s, e) => { device.PropertyChanged += (s, e) =>
if (e.PropertyName == nameof(PlacedDevice.X)) Canvas.SetLeft(container, device.X); {
if (e.PropertyName == nameof(PlacedDevice.Y)) Canvas.SetTop(container, device.Y); switch (e.PropertyName)
{
case nameof(PlacedDevice.X):
Canvas.SetLeft(container, device.X);
break;
case nameof(PlacedDevice.Y):
Canvas.SetTop(container, device.Y);
break;
}
}; };
container.MouseDown += Device_MouseDown; container.MouseDown += Device_MouseDown;
container.MouseLeftButtonDown += (s, e) => { container.MouseLeftButtonDown += (s, e) =>
if (e.ClickCount == 2) { {
StopDragging(); if (e.ClickCount != 2) return;
EditDevice(device); StopDragging();
e.Handled = true; EditDevice(device);
} e.Handled = true;
}; };
_deviceElements[device] = container; _deviceElements[device] = container;
@@ -146,36 +151,35 @@ namespace NetworkDiagram
private void Device_MouseDown(object sender, MouseButtonEventArgs e) private void Device_MouseDown(object sender, MouseButtonEventArgs e)
{ {
if (sender is FrameworkElement element && element.Tag is PlacedDevice device) if (sender is not FrameworkElement { Tag: PlacedDevice device } element) return;
if (_activeTool != null)
{ {
if (_activeTool != null) HandleConnectionTool(device, element);
{
HandleConnectionTool(device, element);
e.Handled = true;
return;
}
// Handle Selection
if (!Keyboard.IsKeyDown(Key.LeftCtrl) && !Keyboard.IsKeyDown(Key.RightCtrl))
{
if (!_selectedElements.Contains(element))
{
ClearSelection();
SelectElement(element);
}
}
else
{
if (_selectedElements.Contains(element)) DeselectElement(element);
else SelectElement(element);
}
// Start Dragging
_isDraggingDevices = true;
_dragStartPoint = e.GetPosition(DiagramCanvas);
DiagramCanvas.CaptureMouse();
e.Handled = true; e.Handled = true;
return;
} }
// Handle Selection
if (!Keyboard.IsKeyDown(Key.LeftCtrl) && !Keyboard.IsKeyDown(Key.RightCtrl))
{
if (!_selectedElements.Contains(element))
{
ClearSelection();
SelectElement(element);
}
}
else
{
if (_selectedElements.Contains(element)) DeselectElement(element);
else SelectElement(element);
}
// Start Dragging
_isDraggingDevices = true;
_dragStartPoint = e.GetPosition(DiagramCanvas);
DiagramCanvas.CaptureMouse();
e.Handled = true;
} }
private void SelectElement(FrameworkElement element) private void SelectElement(FrameworkElement element)
@@ -196,15 +200,16 @@ namespace NetworkDiagram
private void DeselectElement(FrameworkElement element) private void DeselectElement(FrameworkElement element)
{ {
_selectedElements.Remove(element); _selectedElements.Remove(element);
if (element is Border b) switch (element)
{ {
b.BorderBrush = Brushes.Transparent; case Border b:
b.Background = Brushes.Transparent; b.BorderBrush = Brushes.Transparent;
} b.Background = Brushes.Transparent;
else if (element is Line l) break;
{ case Line l:
l.StrokeThickness = 3; l.StrokeThickness = 3;
l.Opacity = 1.0; l.Opacity = 1.0;
break;
} }
} }
@@ -233,14 +238,14 @@ namespace NetworkDiagram
private void DiagramCanvas_MouseMove(object sender, MouseEventArgs e) private void DiagramCanvas_MouseMove(object sender, MouseEventArgs e)
{ {
Point currentPoint = e.GetPosition(DiagramCanvas); var currentPoint = e.GetPosition(DiagramCanvas);
if (_isSelectingArea) if (_isSelectingArea)
{ {
double x = Math.Min(_selectionStartPoint.X, currentPoint.X); var x = Math.Min(_selectionStartPoint.X, currentPoint.X);
double y = Math.Min(_selectionStartPoint.Y, currentPoint.Y); var y = Math.Min(_selectionStartPoint.Y, currentPoint.Y);
double w = Math.Abs(_selectionStartPoint.X - currentPoint.X); var w = Math.Abs(_selectionStartPoint.X - currentPoint.X);
double h = Math.Abs(_selectionStartPoint.Y - currentPoint.Y); var h = Math.Abs(_selectionStartPoint.Y - currentPoint.Y);
Canvas.SetLeft(SelectionRect, x); Canvas.SetLeft(SelectionRect, x);
Canvas.SetTop(SelectionRect, y); Canvas.SetTop(SelectionRect, y);
@@ -248,10 +253,10 @@ namespace NetworkDiagram
SelectionRect.Height = h; SelectionRect.Height = h;
// Real-time selection preview // Real-time selection preview
Rect selectionBounds = new Rect(x, y, w, h); var selectionBounds = new Rect(x, y, w, h);
foreach (var border in _deviceElements.Values) foreach (var border in _deviceElements.Values)
{ {
Rect elementBounds = new Rect(Canvas.GetLeft(border), Canvas.GetTop(border), border.ActualWidth, border.ActualHeight); var elementBounds = new Rect(Canvas.GetLeft(border), Canvas.GetTop(border), border.ActualWidth, border.ActualHeight);
if (selectionBounds.IntersectsWith(elementBounds)) if (selectionBounds.IntersectsWith(elementBounds))
{ {
if (!_selectedElements.Contains(border)) SelectElement(border); if (!_selectedElements.Contains(border)) SelectElement(border);
@@ -266,7 +271,7 @@ namespace NetworkDiagram
// Also preview for lines // Also preview for lines
foreach (var line in _connectionLines.Values) foreach (var line in _connectionLines.Values)
{ {
Rect lineBounds = new Rect( var lineBounds = new Rect(
Math.Min(line.X1, line.X2), Math.Min(line.X1, line.X2),
Math.Min(line.Y1, line.Y2), Math.Min(line.Y1, line.Y2),
Math.Abs(line.X1 - line.X2), Math.Abs(line.X1 - line.X2),
@@ -284,8 +289,8 @@ namespace NetworkDiagram
} }
else if (_isDraggingDevices && e.LeftButton == MouseButtonState.Pressed) else if (_isDraggingDevices && e.LeftButton == MouseButtonState.Pressed)
{ {
double deltaX = currentPoint.X - _dragStartPoint.X; var deltaX = currentPoint.X - _dragStartPoint.X;
double deltaY = currentPoint.Y - _dragStartPoint.Y; var deltaY = currentPoint.Y - _dragStartPoint.Y;
foreach (var element in _selectedElements) foreach (var element in _selectedElements)
{ {
@@ -303,7 +308,7 @@ namespace NetworkDiagram
{ {
if (_isSelectingArea) if (_isSelectingArea)
{ {
Rect selectionBounds = new Rect( var selectionBounds = new Rect(
Canvas.GetLeft(SelectionRect), Canvas.GetLeft(SelectionRect),
Canvas.GetTop(SelectionRect), Canvas.GetTop(SelectionRect),
SelectionRect.Width, SelectionRect.Width,
@@ -311,7 +316,7 @@ namespace NetworkDiagram
foreach (var border in _deviceElements.Values) foreach (var border in _deviceElements.Values)
{ {
Rect elementBounds = new Rect(Canvas.GetLeft(border), Canvas.GetTop(border), border.ActualWidth, border.ActualHeight); var elementBounds = new Rect(Canvas.GetLeft(border), Canvas.GetTop(border), border.ActualWidth, border.ActualHeight);
if (selectionBounds.IntersectsWith(elementBounds)) SelectElement(border); if (selectionBounds.IntersectsWith(elementBounds)) SelectElement(border);
} }
} }
@@ -353,7 +358,7 @@ namespace NetworkDiagram
StrokeThickness = 3, StrokeThickness = 3,
Tag = conn Tag = conn
}; };
if (conn.Type == ConnectionType.Wifi) line.StrokeDashArray = new DoubleCollection { 2, 2 }; if (conn.Type == ConnectionType.Wifi) line.StrokeDashArray = [2, 2];
UpdateLinePosition(conn, line); UpdateLinePosition(conn, line);
@@ -372,60 +377,68 @@ namespace NetworkDiagram
private void UpdateLinePosition(Connection conn, Line line) private void UpdateLinePosition(Connection conn, Line line)
{ {
if (_deviceElements.TryGetValue(conn.StartDevice, out var startElem) && if (!_deviceElements.TryGetValue(conn.StartDevice, out var startElem) ||
_deviceElements.TryGetValue(conn.EndDevice, out var endElem)) !_deviceElements.TryGetValue(conn.EndDevice, out var endElem)) return;
{
if (startElem.ActualWidth == 0) startElem.UpdateLayout(); if (startElem.ActualWidth == 0) startElem.UpdateLayout();
if (endElem.ActualWidth == 0) endElem.UpdateLayout(); if (endElem.ActualWidth == 0) endElem.UpdateLayout();
line.X1 = conn.StartDevice.X + (startElem.ActualWidth / 2); line.X1 = conn.StartDevice.X + (startElem.ActualWidth / 2);
line.Y1 = conn.StartDevice.Y + 24; line.Y1 = conn.StartDevice.Y + 24;
line.X2 = conn.EndDevice.X + (endElem.ActualWidth / 2); line.X2 = conn.EndDevice.X + (endElem.ActualWidth / 2);
line.Y2 = conn.EndDevice.Y + 24; line.Y2 = conn.EndDevice.Y + 24;
}
} }
private void Window_KeyDown(object sender, KeyEventArgs e) private void Window_KeyDown(object sender, KeyEventArgs e)
{ {
if (e.Key == Key.Delete && _selectedElements.Count > 0) switch (e.Key)
{ {
foreach (var el in _selectedElements.ToList()) case Key.Delete when _selectedElements.Count > 0:
{ {
if (el is Line line && el.Tag is Connection conn) foreach (var el in _selectedElements.ToList())
{ {
_currentDiagram.Connections.Remove(conn); switch (el)
_connectionLines.Remove(conn);
DiagramCanvas.Children.Remove(line);
}
else if (el is Border border && border.Tag is PlacedDevice device)
{
_currentDiagram.Devices.Remove(device);
_deviceElements.Remove(device);
var toRemove = _currentDiagram.Connections.Where(c => c.StartDevice == device || c.EndDevice == device).ToList();
foreach (var c in toRemove)
{ {
if (_connectionLines.TryGetValue(c, out var l)) DiagramCanvas.Children.Remove(l); case Line line when el.Tag is Connection conn:
_currentDiagram.Connections.Remove(c); _currentDiagram.Connections.Remove(conn);
_connectionLines.Remove(c); _connectionLines.Remove(conn);
DiagramCanvas.Children.Remove(line);
break;
case Border { Tag: PlacedDevice device } border:
{
_currentDiagram.Devices.Remove(device);
_deviceElements.Remove(device);
var toRemove = _currentDiagram.Connections.Where(c => c.StartDevice == device || c.EndDevice == device).ToList();
foreach (var c in toRemove)
{
if (_connectionLines.TryGetValue(c, out var l)) DiagramCanvas.Children.Remove(l);
_currentDiagram.Connections.Remove(c);
_connectionLines.Remove(c);
}
DiagramCanvas.Children.Remove(border);
break;
}
} }
DiagramCanvas.Children.Remove(border);
} }
_selectedElements.Clear();
break;
} }
_selectedElements.Clear(); case Key.Escape:
ResetConnectionTool(); StopDragging(); ClearSelection();
break;
} }
else if (e.Key == Key.Escape) { ResetConnectionTool(); StopDragging(); ClearSelection(); }
} }
private void EditDevice(PlacedDevice device) private void EditDevice(PlacedDevice device)
{ {
var dialog = new EditDeviceWindow(device); var dialog = new EditDeviceWindow(device);
dialog.ShowDialog(); dialog.ShowDialog();
if (_deviceElements.TryGetValue(device, out var elem))
{ if (!_deviceElements.TryGetValue(device, out var elem)) return;
elem.UpdateLayout();
var attached = _currentDiagram.Connections.Where(c => c.StartDevice == device || c.EndDevice == device).ToList(); elem.UpdateLayout();
foreach(var c in attached) if (_connectionLines.TryGetValue(c, out var l)) UpdateLinePosition(c, l); var attached = _currentDiagram.Connections.Where(c => c.StartDevice == device || c.EndDevice == device).ToList();
} foreach(var c in attached) if (_connectionLines.TryGetValue(c, out var l)) UpdateLinePosition(c, l);
} }
#region Toolbar Events #region Toolbar Events
@@ -441,48 +454,46 @@ namespace NetworkDiagram
private void SaveDiagram_Click(object sender, RoutedEventArgs e) private void SaveDiagram_Click(object sender, RoutedEventArgs e)
{ {
var sfd = new SaveFileDialog { Filter = "Network Diagram (*.ndjson)|*.ndjson" }; var sfd = new SaveFileDialog { Filter = "Network Diagram (*.ndjson)|*.ndjson" };
if (sfd.ShowDialog() == true) if (sfd.ShowDialog() != true) return;
{
var model = new DiagramSaveModel { var model = new DiagramSaveModel {
Devices = _currentDiagram.Devices, Devices = _currentDiagram.Devices,
Connections = _currentDiagram.Connections.Select(c => new ConnectionSaveModel { Connections = _currentDiagram.Connections.Select(c => new ConnectionSaveModel {
StartIndex = _currentDiagram.Devices.IndexOf(c.StartDevice), StartIndex = _currentDiagram.Devices.IndexOf(c.StartDevice),
EndIndex = _currentDiagram.Devices.IndexOf(c.EndDevice), EndIndex = _currentDiagram.Devices.IndexOf(c.EndDevice),
Type = c.Type Type = c.Type
}).ToList() }).ToList()
}; };
string json = JsonSerializer.Serialize(model, new JsonSerializerOptions { WriteIndented = true });
File.WriteAllText(sfd.FileName, json); var json = JsonSerializer.Serialize(model, new JsonSerializerOptions { WriteIndented = true });
} File.WriteAllText(sfd.FileName, json);
} }
private void LoadDiagram_Click(object sender, RoutedEventArgs e) private void LoadDiagram_Click(object sender, RoutedEventArgs e)
{ {
var ofd = new OpenFileDialog { Filter = "Network Diagram (*.ndjson)|*.ndjson" }; var ofd = new OpenFileDialog { Filter = "Network Diagram (*.ndjson)|*.ndjson" };
if (ofd.ShowDialog() == true) if (ofd.ShowDialog() != true) return;
var json = File.ReadAllText(ofd.FileName);
var model = JsonSerializer.Deserialize<DiagramSaveModel>(json);
if (model == null) return;
_currentDiagram = new Diagram { Devices = model.Devices };
foreach (var device in _currentDiagram.Devices)
{ {
string json = File.ReadAllText(ofd.FileName); var template = _deviceTemplates.FirstOrDefault(t => t.Name == device.TemplateName);
var model = JsonSerializer.Deserialize<DiagramSaveModel>(json); if (template != null) device.IconPath = template.IconPath;
if (model == null) return; }
_currentDiagram = new Diagram { Devices = model.Devices };
foreach (var device in _currentDiagram.Devices) DiagramCanvas.Children.Clear();
{ _connectionLines.Clear();
var template = _deviceTemplates.FirstOrDefault(t => t.Name == device.TemplateName); _deviceElements.Clear();
if (template != null) device.IconPath = template.IconPath; ClearSelection();
} foreach (var device in _currentDiagram.Devices) RenderDevice(device);
foreach (var conn in model.Connections.Select(cModel => new Connection { StartDevice = _currentDiagram.Devices[cModel.StartIndex], EndDevice = _currentDiagram.Devices[cModel.EndIndex], Type = cModel.Type }))
DiagramCanvas.Children.Clear(); {
_connectionLines.Clear(); _currentDiagram.Connections.Add(conn);
_deviceElements.Clear(); RenderConnection(conn);
ClearSelection();
foreach (var device in _currentDiagram.Devices) RenderDevice(device);
foreach (var cModel in model.Connections)
{
var conn = new Connection { StartDevice = _currentDiagram.Devices[cModel.StartIndex], EndDevice = _currentDiagram.Devices[cModel.EndIndex], Type = cModel.Type };
_currentDiagram.Connections.Add(conn);
RenderConnection(conn);
}
} }
} }
@@ -504,14 +515,14 @@ namespace NetworkDiagram
var result = MessageBox.Show(GetLocalizedString("ExportWhiteBgMsg"), GetLocalizedString("ExportOptionsTitle"), MessageBoxButton.YesNoCancel); var result = MessageBox.Show(GetLocalizedString("ExportWhiteBgMsg"), GetLocalizedString("ExportOptionsTitle"), MessageBoxButton.YesNoCancel);
if (result == MessageBoxResult.Cancel) return; if (result == MessageBoxResult.Cancel) return;
bool whiteBg = result == MessageBoxResult.Yes; var whiteBg = result == MessageBoxResult.Yes;
// 1. Find content bounds // 1. Find content bounds
double minX = double.MaxValue, minY = double.MaxValue, maxX = double.MinValue, maxY = double.MinValue; double minX = double.MaxValue, minY = double.MaxValue, maxX = double.MinValue, maxY = double.MinValue;
foreach (var border in _deviceElements.Values) foreach (var border in _deviceElements.Values)
{ {
double x = Canvas.GetLeft(border); var x = Canvas.GetLeft(border);
double y = Canvas.GetTop(border); var y = Canvas.GetTop(border);
minX = Math.Min(minX, x); minX = Math.Min(minX, x);
minY = Math.Min(minY, y); minY = Math.Min(minY, y);
maxX = Math.Max(maxX, x + border.ActualWidth); maxX = Math.Max(maxX, x + border.ActualWidth);
@@ -525,16 +536,16 @@ namespace NetworkDiagram
maxY = Math.Max(maxY, Math.Max(line.Y1, line.Y2)); maxY = Math.Max(maxY, Math.Max(line.Y1, line.Y2));
} }
double margin = 20; const double margin = 20;
minX -= margin; minY -= margin; maxX += margin; maxY += margin; minX -= margin; minY -= margin; maxX += margin; maxY += margin;
double width = Math.Max(1, maxX - minX); var width = Math.Max(1, maxX - minX);
double height = Math.Max(1, maxY - minY); var height = Math.Max(1, maxY - minY);
try try
{ {
RenderTargetBitmap rtb = new RenderTargetBitmap((int)width, (int)height, 96, 96, PixelFormats.Pbgra32); var rtb = new RenderTargetBitmap((int)width, (int)height, 96, 96, PixelFormats.Pbgra32);
DrawingVisual dv = new DrawingVisual(); var dv = new DrawingVisual();
using (DrawingContext dc = dv.RenderOpen()) using (var dc = dv.RenderOpen())
{ {
if (whiteBg) dc.DrawRectangle(Brushes.White, null, new Rect(0, 0, width, height)); if (whiteBg) dc.DrawRectangle(Brushes.White, null, new Rect(0, 0, width, height));
dc.PushTransform(new TranslateTransform(-minX, -minY)); dc.PushTransform(new TranslateTransform(-minX, -minY));
@@ -543,23 +554,26 @@ namespace NetworkDiagram
{ {
if (child == SelectionRect || !(child is Visual v) || ((UIElement)child).Visibility != Visibility.Visible) continue; if (child == SelectionRect || !(child is Visual v) || ((UIElement)child).Visibility != Visibility.Visible) continue;
double left = Canvas.GetLeft((UIElement)child); var left = Canvas.GetLeft((UIElement)child);
double top = Canvas.GetTop((UIElement)child); var top = Canvas.GetTop((UIElement)child);
if (child is Line line) switch (child)
{ {
dc.DrawLine(new Pen(line.Stroke, line.StrokeThickness) { DashStyle = new DashStyle(line.StrokeDashArray, 0) }, case Line line:
new Point(line.X1, line.Y1), new Point(line.X2, line.Y2)); dc.DrawLine(new Pen(line.Stroke, line.StrokeThickness) { DashStyle = new DashStyle(line.StrokeDashArray, 0) },
} new Point(line.X1, line.Y1), new Point(line.X2, line.Y2));
else if (child is FrameworkElement fe) break;
{ case FrameworkElement fe:
VisualBrush vb = new VisualBrush(fe) { Stretch = Stretch.None }; {
dc.DrawRectangle(vb, null, new Rect(left, top, fe.ActualWidth, fe.ActualHeight)); var vb = new VisualBrush(fe) { Stretch = Stretch.None };
dc.DrawRectangle(vb, null, new Rect(left, top, fe.ActualWidth, fe.ActualHeight));
break;
}
} }
} }
} }
rtb.Render(dv); rtb.Render(dv);
PngBitmapEncoder encoder = new PngBitmapEncoder(); var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(rtb)); encoder.Frames.Add(BitmapFrame.Create(rtb));
using (var stream = File.Create(sfd.FileName)) encoder.Save(stream); using (var stream = File.Create(sfd.FileName)) encoder.Save(stream);
MessageBox.Show(GetLocalizedString("ExportSuccess")); MessageBox.Show(GetLocalizedString("ExportSuccess"));
@@ -570,11 +584,11 @@ namespace NetworkDiagram
} }
public class DiagramSaveModel { public class DiagramSaveModel {
public List<PlacedDevice> Devices { get; set; } = new(); public List<PlacedDevice> Devices { get; set; } = [];
public List<ConnectionSaveModel> Connections { get; set; } = new(); public List<ConnectionSaveModel> Connections { get; set; } = [];
} }
public class ConnectionSaveModel { public class ConnectionSaveModel {
public int StartIndex { get; set; } public int StartIndex { get; init; }
public int EndIndex { get; set; } public int EndIndex { get; set; }
public ConnectionType Type { get; set; } public ConnectionType Type { get; set; }
} }
+41 -35
View File
@@ -1,4 +1,3 @@
using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
@@ -13,58 +12,65 @@ namespace NetworkDiagram.Models
public class DeviceTemplate public class DeviceTemplate
{ {
public string Name { get; set; } = string.Empty; public string Name { get; init; } = string.Empty;
public string IconPath { get; set; } = string.Empty; public string IconPath { get; set; } = string.Empty;
} }
public class PlacedDevice : INotifyPropertyChanged public class PlacedDevice : INotifyPropertyChanged
{ {
private string _name = string.Empty; public string Name
private List<string> _ipAddresses = new List<string>(); {
private string _annotation = string.Empty; get;
private double _x; set
private double _y; {
field = value;
public string Name OnPropertyChanged();
{ }
get => _name; } = string.Empty;
set { _name = value; OnPropertyChanged(); }
}
public string TemplateName { get; set; } = string.Empty; public string TemplateName { get; set; } = string.Empty;
[JsonIgnore] [JsonIgnore]
public string IconPath { get; set; } = string.Empty; public string IconPath { get; set; } = string.Empty;
public double X public double X
{ {
get => _x; get;
set { _x = value; OnPropertyChanged(); OnPropertyChanged(nameof(CenterX)); } set
{
field = value;
OnPropertyChanged();
OnPropertyChanged(nameof(CenterX));
}
} }
public double Y public double Y
{ {
get => _y; get;
set { _y = value; OnPropertyChanged(); OnPropertyChanged(nameof(CenterY)); } set
{
field = value;
OnPropertyChanged();
OnPropertyChanged(nameof(CenterY));
}
} }
public List<string> IpAddresses public List<string> IpAddresses
{ {
get => _ipAddresses; get;
set { _ipAddresses = value; OnPropertyChanged(); } set
} {
field = value;
OnPropertyChanged();
}
} = [];
public string Annotation
{
get => _annotation;
set { _annotation = value; OnPropertyChanged(); }
}
public double CenterX => X + 50; public double CenterX => X + 50;
public double CenterY => Y + 40; public double CenterY => Y + 40;
public event PropertyChangedEventHandler? PropertyChanged; public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string? name = null)
private void OnPropertyChanged([CallerMemberName] string? name = null)
{ {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
} }
@@ -79,7 +85,7 @@ namespace NetworkDiagram.Models
public class Diagram public class Diagram
{ {
public List<PlacedDevice> Devices { get; set; } = new List<PlacedDevice>(); public List<PlacedDevice> Devices { get; set; } = [];
public List<Connection> Connections { get; set; } = new List<Connection>(); public List<Connection> Connections { get; set; } = [];
} }
} }