Sic.Framework-Nanjing-Baishi/MECF.Framework.UI.Client/RecipeEditorLib/DGExtension/DataGridRecipe.xaml.cs

302 lines
9.9 KiB
C#

using System;
using MECF.Framework.UI.Client.RecipeEditorLib.RecipeModel.Params;
using MECF.Framework.UI.Client.RecipeEditorLib.RecipeModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using DataGridRowEventArgs = ExtendedGrid.Microsoft.Windows.Controls.DataGridRowEventArgs;
using ExDataGridRow = ExtendedGrid.Microsoft.Windows.Controls.DataGridRow;
using MECF.Framework.UI.Client.RecipeEditorLib.DGExtension.CustomColumn;
using System.Diagnostics;
using DataGridCellEditEndingEventArgs = ExtendedGrid.Microsoft.Windows.Controls.DataGridCellEditEndingEventArgs;
using MECF.Framework.UI.Client.ClientBase;
using OpenSEMI.ClientBase;
using DataGridBeginningEditEventArgs = ExtendedGrid.Microsoft.Windows.Controls.DataGridBeginningEditEventArgs;
namespace MECF.Framework.UI.Client.RecipeEditorLib.DGExtension
{
/// <summary>
/// Interaction logic for DataGridRecipe.xaml
/// </summary>
public partial class DataGridRecipe : UserControl
{
#region Constructors
public DataGridRecipe()
{
InitializeComponent();
}
#endregion
#region Properties
#endregion
#region Dependency Properties
#region RecipeData
public static readonly DependencyProperty RecipeProperty = DependencyProperty.Register(
nameof(Recipe), typeof(RecipeData), typeof(DataGridRecipe), new PropertyMetadata(default(RecipeData), RecipePropertyChangedCallback));
private static void RecipePropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is DataGridRecipe dg)
{
if (e.NewValue is RecipeData recipe)
{
dg.dgCustom.ItemsSource = recipe.Steps;
recipe.PropertyChanged += (sender, e) =>
{
// 同步白名单编辑模式
if (e.PropertyName == nameof(RecipeData.IsAccessibleWhitelistEditMode))
{
dg.dgCustom.IsAccessibleWhitelistEditMode = recipe.IsAccessibleWhitelistEditMode;
}
};
// 创建DataGrid列
dg.ClearColumns();
foreach (var col in recipe.Columns)
dg.AddColumn(col);
}
else
dg.dgCustom.ItemsSource = null;
}
}
/// <summary>
/// 设置或返回编辑器正在编辑的Recipe。
/// </summary>
public RecipeData Recipe
{
get => (RecipeData)GetValue(RecipeProperty);
set => SetValue(RecipeProperty, value);
}
#endregion
#region FrozenColumnCount
public static readonly DependencyProperty FrozenColumnCountProperty = DependencyProperty.Register(
nameof(FrozenColumnCount), typeof(int), typeof(DataGridRecipe), new PropertyMetadata(default(int), FrozenColumnCountPropertyChangedCallback));
private static void FrozenColumnCountPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is DataGridRecipe dg)
{
if (e.NewValue is int count)
dg.dgCustom.FrozenColumnCount = count;
else
dg.dgCustom.FrozenColumnCount = 0;
}
}
/// <summary>
/// 设置或返回编辑器冻结的列数。
/// </summary>
public int FrozenColumnCount
{
get => (int)GetValue(FrozenColumnCountProperty);
set => SetValue(FrozenColumnCountProperty, value);
}
#endregion
#endregion
#region Methods
private void RowOnSelected(object sender, RoutedEventArgs e)
{
if (!(e.Source is ExDataGridRow dgr))
return;
if (!(dgr.DataContext is RecipeStep recipeStep))
return;
var param = recipeStep.FindParamByControlName(RecipeControlNames.STEP_NO);
if (param is StepParam sp)
{
sp.IsChecked = true;
}
}
private void RowOnUnselected(object sender, RoutedEventArgs e)
{
if (!(e.Source is ExDataGridRow dgr))
return;
if (!(dgr.DataContext is RecipeStep recipeStep))
return;
var param = recipeStep.FindParamByControlName(RecipeControlNames.STEP_NO);
if (param is StepParam sp)
{
sp.IsChecked = false;
}
}
private void ClearColumns()
{
dgCustom.Columns.Clear();
}
/// <summary>
/// 生成编辑器的列。
/// </summary>
private void AddColumn(EditorDataGridTemplateColumnBase col)
{
// 设置ColumnHeaderTemplate和DataGridCellTemplate
if (string.IsNullOrEmpty(col.StringCellTemplate) == false)
col.CellTemplate = (DataTemplate)FindResource(col.StringCellTemplate);
if (string.IsNullOrEmpty(col.StringCellEditingTemplate) == false)
col.CellEditingTemplate = (DataTemplate)FindResource(col.StringCellEditingTemplate);
if (string.IsNullOrEmpty(col.StringHeaderTemplate) == false)
col.HeaderTemplate = (DataTemplate)FindResource(col.StringHeaderTemplate);
// 通过Columns重建XDataGrid列
dgCustom.Columns.Add(col);
}
/// <summary>
/// 滚动到并高亮指定的参数单元格。
/// </summary>
/// <param name="param"></param>
public void FocusToParam(IParam param)
{
if (param == null)
return;
Recipe.Steps.ResetHighlight();
var row = param.RowOwner;
var col = param.ColumnOwner;
if (row != null && col != null)
{
dgCustom.ScrollIntoView(param.Parent, col);
param.Highlight();
}
}
#endregion
#region Events
private void DgCustom_OnBeginningEdit(object sender, DataGridBeginningEditEventArgs e)
{
Debug.Assert(e.Row.Item is RecipeStep, "The content of row is not RecipeStep.");
if (e.Row.Item is RecipeStep step)
{
var param = step[e.Column.DisplayIndex];
if (param is IValueParam && param.Permission != MenuPermissionEnum.MP_READ_WRITE)
{
e.Cancel = true;
// 如果单元格为只读权限,则提示不能编辑
var reason = "";
if (param.ColumnPermission != MenuPermissionEnum.MP_READ_WRITE)
reason = "Recipe Row Access Denied!\r\n\r\nPlease check the RecipeRow Access Permission.";
else if (param.StepPermission != MenuPermissionEnum.MP_READ_WRITE)
reason = "Recipe Step Access Denied!\r\n\r\nPlease check the RecipeCol Access Permission.";
else
reason = "Cell Access Denied!\r\n\r\nPlease check the RecipeRow/RecipeCol Access Permission.";
DialogBox.ShowError(reason);
}
}
else
e.Cancel = true;
}
private void DataGridCell_OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
// 仅在编辑AccessPermissionWhitelist编辑模式下有效。
if (!Recipe.IsAccessibleWhitelistEditMode)
return;
if (sender is Border bdr && bdr.DataContext is Param param)
{
if (param.IsHighlighted)
param.ResetHighlight();
else
param.Highlight();
}
}
private void DgCustom_OnLoadingRow(object sender, DataGridRowEventArgs e)
{
e.Row.Selected += RowOnSelected;
e.Row.Unselected += RowOnUnselected;
if (sender is XDataGrid dg && e.Row.DataContext is RecipeStep step)
{
for (var i = 0; i < step.Count; i++)
{
step[i].RowOwner = e.Row;
step[i].ColumnOwner = dg.Columns[i];
}
}
}
private void DgCustom_OnUnloadingRow(object sender, DataGridRowEventArgs e)
{
e.Row.Selected -= RowOnSelected;
e.Row.Unselected -= RowOnUnselected;
}
private void DgCustom_OnCellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
if (e.Row.Item is RecipeStep step)
{
step.CalculateGasFlow();
step.Parent.Validate();
}
}
private void Expander_OnExpanded(object sender, RoutedEventArgs e)
{
if (sender is Expander expander && expander.DataContext is ExpanderColumn col)
{
foreach (var subCol in col.ChildColumns)
{
subCol.UpdateVisibility();
}
}
}
private void Expander_OnCollapsed(object sender, RoutedEventArgs e)
{
if (sender is Expander expander && expander.DataContext is ExpanderColumn col)
{
foreach (var subCol in col.ChildColumns)
{
subCol.Visibility = Visibility.Collapsed;
}
}
}
/// <summary>
/// 滚动DataGrid视图到指定的配方步骤。
/// </summary>
/// <param name="step"></param>
public void ScrollToRecipeStep(RecipeStep step)
{
dgCustom.ScrollIntoView(step);
}
#endregion
}
}