mirror of
https://gitee.com/akwkevin/aistudio.-wpf.-diagram
synced 2026-03-03 00:00:57 +08:00
348 lines
12 KiB
C#
348 lines
12 KiB
C#
using System;
|
|
using System.Linq;
|
|
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Input;
|
|
using System.Windows.Media;
|
|
using System.Windows.Shapes;
|
|
|
|
namespace AIStudio.Wpf.DiagramHelper.Controls
|
|
{
|
|
public class RectangleGridEventArgs
|
|
{
|
|
public int Row { get; set; }
|
|
public int Column { get; set; }
|
|
public RectangleGridEventArgs(int row, int column)
|
|
{
|
|
Row = row;
|
|
Column = column;
|
|
}
|
|
}
|
|
|
|
public class RectangleGrid : Grid
|
|
{
|
|
public static readonly DependencyProperty RowNumProperty = DependencyProperty.Register("RowNum", typeof(int),
|
|
typeof(RectangleGrid),
|
|
new FrameworkPropertyMetadata(4));
|
|
public int RowNum
|
|
{
|
|
get
|
|
{
|
|
return (int)GetValue(RowNumProperty);
|
|
}
|
|
set
|
|
{
|
|
SetValue(RowNumProperty, value);
|
|
}
|
|
}
|
|
|
|
public static readonly DependencyProperty ColumnNumProperty = DependencyProperty.Register("ColumnNum", typeof(int),
|
|
typeof(RectangleGrid),
|
|
new FrameworkPropertyMetadata(4));
|
|
public int ColumnNum
|
|
{
|
|
get
|
|
{
|
|
return (int)GetValue(ColumnNumProperty);
|
|
}
|
|
set
|
|
{
|
|
SetValue(ColumnNumProperty, value);
|
|
}
|
|
}
|
|
|
|
public static readonly DependencyProperty SelectRowProperty = DependencyProperty.Register("SelectRow", typeof(int),
|
|
typeof(RectangleGrid),
|
|
new FrameworkPropertyMetadata(0));
|
|
|
|
public int SelectRow
|
|
{
|
|
get
|
|
{
|
|
return (int)GetValue(SelectRowProperty);
|
|
}
|
|
set
|
|
{
|
|
SetValue(SelectRowProperty, value);
|
|
}
|
|
}
|
|
|
|
public static readonly DependencyProperty SelectColumnProperty = DependencyProperty.Register("SelectColumn", typeof(int),
|
|
typeof(RectangleGrid),
|
|
new FrameworkPropertyMetadata(0));
|
|
public int SelectColumn
|
|
{
|
|
get
|
|
{
|
|
return (int)GetValue(SelectColumnProperty);
|
|
}
|
|
set
|
|
{
|
|
SetValue(SelectColumnProperty, value);
|
|
}
|
|
}
|
|
|
|
public static readonly DependencyProperty SelectProperty = DependencyProperty.Register("Select", typeof(RectangleGridEventArgs),
|
|
typeof(RectangleGrid),
|
|
new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnSelectChanged)));
|
|
public RectangleGridEventArgs Select
|
|
{
|
|
get
|
|
{
|
|
return (RectangleGridEventArgs)GetValue(SelectProperty);
|
|
}
|
|
set
|
|
{
|
|
SetValue(SelectProperty, value);
|
|
}
|
|
}
|
|
|
|
#region MouseOverBrush 标题栏背景色
|
|
|
|
public static readonly DependencyProperty MouseOverBrushProperty = DependencyProperty.Register(
|
|
"MouseOverBrush", typeof(Brush), typeof(RectangleGrid), new PropertyMetadata(null));
|
|
|
|
public Brush MouseOverBrush
|
|
{
|
|
get { return (Brush)GetValue(MouseOverBrushProperty); }
|
|
set { SetValue(MouseOverBrushProperty, value); }
|
|
}
|
|
|
|
#endregion
|
|
|
|
private Rectangle[,] rectangles;
|
|
public RectangleGrid()
|
|
{
|
|
this.Loaded += RectangleGrid_Loaded;
|
|
}
|
|
|
|
void RectangleGrid_Loaded(object sender, RoutedEventArgs e)
|
|
{
|
|
this.Loaded -= RectangleGrid_Loaded;
|
|
for (int i = 0; i < RowNum; i++)
|
|
{
|
|
RowDefinition row = new RowDefinition() { Height = new GridLength(2, GridUnitType.Auto) };
|
|
this.RowDefinitions.Add(row);
|
|
}
|
|
for (int j = 0; j < ColumnNum; j++)
|
|
{
|
|
ColumnDefinition col = new ColumnDefinition() { Width = new GridLength(2, GridUnitType.Auto) };
|
|
this.ColumnDefinitions.Add(col);
|
|
}
|
|
|
|
rectangles = new Rectangle[RowNum, ColumnNum];
|
|
for (int i = 0; i < rectangles.GetLength(0); i++)
|
|
{
|
|
for (int j = 0; j < rectangles.GetLength(1); j++)
|
|
{
|
|
Rectangle rectangle = new Rectangle();
|
|
rectangle.IsHitTestVisible = true;
|
|
rectangle.SnapsToDevicePixels = true;
|
|
rectangle.Stroke = new SolidColorBrush(Colors.Black);
|
|
rectangle.Width = 24;
|
|
rectangle.Height = 24;
|
|
rectangle.Margin = new Thickness(2);
|
|
rectangle.MouseEnter += rectangle_MouseEnter;
|
|
rectangle.MouseLeave += rectangle_MouseLeave;
|
|
rectangle.MouseLeftButtonDown += rectangle_MouseLeftButtonDown;
|
|
rectangle.Fill = new SolidColorBrush(Color.FromArgb(0xff, 0xff, 0xff, 0xff));
|
|
Grid.SetRow(rectangle, i);
|
|
Grid.SetColumn(rectangle, j);
|
|
this.Children.Add(rectangle);
|
|
|
|
rectangles[i, j] = rectangle;
|
|
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
void rectangle_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
|
|
{
|
|
Brush myBrush = new SolidColorBrush(System.Windows.Media.Color.FromArgb(0xff, 0x30, 0x50, 0x68));
|
|
Brush myBrush2 = new SolidColorBrush(System.Windows.Media.Color.FromArgb(0xff, 0xff, 0xff, 0xff));
|
|
|
|
if (MouseOverBrush != null)
|
|
{
|
|
myBrush = MouseOverBrush;
|
|
}
|
|
|
|
#region
|
|
Rectangle rect = sender as Rectangle;
|
|
var rects = rectangles.Cast<Rectangle>().ToArray();
|
|
int index = Array.IndexOf(rects, rect);
|
|
|
|
int x = index / rectangles.GetLength(1);
|
|
int y = index % rectangles.GetLength(1);
|
|
FillRectangle(x, y);
|
|
#endregion
|
|
}
|
|
|
|
private void FillRectangle(int row, int column)
|
|
{
|
|
Brush myBrush = new SolidColorBrush(Color.FromArgb(0xff, 0x30, 0x50, 0x68));
|
|
Brush myBrush2 = new SolidColorBrush(Color.FromArgb(0xff, 0xff, 0xff, 0xff));
|
|
|
|
if (MouseOverBrush != null)
|
|
{
|
|
myBrush = MouseOverBrush;
|
|
}
|
|
|
|
for (int i = 0; i < rectangles.GetLength(0); i++)
|
|
{
|
|
for (int j = 0; j < rectangles.GetLength(1); j++)
|
|
{
|
|
if (i <= row && j <= column)
|
|
{
|
|
rectangles[i, j].Fill = myBrush;
|
|
}
|
|
else
|
|
{
|
|
rectangles[i, j].Fill = myBrush2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void rectangle_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
|
|
{
|
|
|
|
}
|
|
|
|
void rectangle_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
|
|
{
|
|
Rectangle rect = sender as Rectangle;
|
|
var rects = rectangles.Cast<Rectangle>().ToArray();
|
|
int index = Array.IndexOf(rects, rect);
|
|
|
|
int x = index / rectangles.GetLength(1);
|
|
int y = index % rectangles.GetLength(1);
|
|
|
|
this.SelectRow = x + 1;
|
|
this.SelectColumn = y + 1;
|
|
this.Select = new RectangleGridEventArgs(this.SelectRow, this.SelectColumn);
|
|
}
|
|
|
|
private static void OnSelectRowChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
|
|
{
|
|
RectangleGrid grid = (RectangleGrid)sender;
|
|
|
|
int oldRow = (int)e.OldValue;
|
|
int newRow = (int)e.NewValue;
|
|
if (oldRow == 0 || newRow == 0)
|
|
{
|
|
grid.FillRectangle((int)e.NewValue, grid.SelectColumn);
|
|
}
|
|
|
|
//避免两次触发
|
|
var oldArgs = new RectangleGridEventArgs(oldRow, grid.SelectColumn);
|
|
var newArgs = new RectangleGridEventArgs(newRow, grid.SelectColumn);
|
|
grid.OnSelectColumnChanged(oldArgs, newArgs);
|
|
}
|
|
|
|
private static void OnSelectColumnChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
|
|
{
|
|
RectangleGrid grid = (RectangleGrid)sender;
|
|
|
|
int oldColumn = (int)e.OldValue;
|
|
int newColumn = (int)e.NewValue;
|
|
|
|
grid.FillRectangle(grid.SelectRow, (int)e.NewValue);
|
|
|
|
var oldArgs = new RectangleGridEventArgs(grid.SelectRow, oldColumn);
|
|
var newArgs = new RectangleGridEventArgs(grid.SelectRow, newColumn);
|
|
grid.OnSelectColumnChanged(oldArgs, newArgs);
|
|
}
|
|
|
|
private static void OnSelectChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
|
|
{
|
|
RectangleGrid grid = (RectangleGrid)sender;
|
|
|
|
RectangleGridEventArgs oldArgs = e.OldValue as RectangleGridEventArgs;
|
|
RectangleGridEventArgs newArgs = e.NewValue as RectangleGridEventArgs;
|
|
|
|
//grid.FillRectangle(newArgs.Row, newArgs.Column);
|
|
|
|
grid.OnSelectColumnChanged(oldArgs, newArgs);
|
|
}
|
|
|
|
public static readonly RoutedEvent SelectRowColumnChangedEvent =
|
|
EventManager.RegisterRoutedEvent("SelectRowColumnChanged", RoutingStrategy.Bubble,
|
|
typeof(RoutedPropertyChangedEventHandler<RectangleGridEventArgs>), typeof(RectangleGrid));
|
|
|
|
public event RoutedPropertyChangedEventHandler<RectangleGridEventArgs> SelectRowColumnChanged
|
|
{
|
|
add { AddHandler(SelectRowColumnChangedEvent, value); }
|
|
remove { RemoveHandler(SelectRowColumnChangedEvent, value); }
|
|
}
|
|
|
|
private void OnSelectColumnChanged(RectangleGridEventArgs oldargs, RectangleGridEventArgs newargs)
|
|
{
|
|
RoutedPropertyChangedEventArgs<RectangleGridEventArgs> args = new RoutedPropertyChangedEventArgs<RectangleGridEventArgs>(oldargs, newargs);
|
|
args.RoutedEvent = RectangleGrid.SelectRowColumnChangedEvent;
|
|
RaiseEvent(args);
|
|
|
|
switch (Command)
|
|
{
|
|
case null:
|
|
return;
|
|
case RoutedCommand command:
|
|
command.Execute(CommandParameter, CommandTarget);
|
|
break;
|
|
default:
|
|
Command.Execute(CommandParameter);
|
|
break;
|
|
}
|
|
}
|
|
|
|
public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(
|
|
"Command", typeof(ICommand), typeof(RectangleGrid), new PropertyMetadata(default(ICommand), OnCommandChanged));
|
|
|
|
private static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
{
|
|
var ctl = (RectangleGrid)d;
|
|
if (e.OldValue is ICommand oldCommand)
|
|
{
|
|
oldCommand.CanExecuteChanged -= ctl.CanExecuteChanged;
|
|
}
|
|
if (e.NewValue is ICommand newCommand)
|
|
{
|
|
newCommand.CanExecuteChanged += ctl.CanExecuteChanged;
|
|
}
|
|
}
|
|
|
|
public ICommand Command
|
|
{
|
|
get => (ICommand)GetValue(CommandProperty);
|
|
set => SetValue(CommandProperty, value);
|
|
}
|
|
|
|
public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register(
|
|
"CommandParameter", typeof(object), typeof(RectangleGrid), new PropertyMetadata(default(object)));
|
|
|
|
public object CommandParameter
|
|
{
|
|
get => GetValue(CommandParameterProperty);
|
|
set => SetValue(CommandParameterProperty, value);
|
|
}
|
|
|
|
public static readonly DependencyProperty CommandTargetProperty = DependencyProperty.Register(
|
|
"CommandTarget", typeof(IInputElement), typeof(RectangleGrid), new PropertyMetadata(default(IInputElement)));
|
|
|
|
public IInputElement CommandTarget
|
|
{
|
|
get => (IInputElement)GetValue(CommandTargetProperty);
|
|
set => SetValue(CommandTargetProperty, value);
|
|
}
|
|
|
|
private void CanExecuteChanged(object sender, EventArgs e)
|
|
{
|
|
if (Command == null) return;
|
|
|
|
IsEnabled = Command is RoutedCommand command
|
|
? command.CanExecute(CommandParameter, CommandTarget)
|
|
: Command.CanExecute(CommandParameter);
|
|
}
|
|
}
|
|
}
|