using DevExpress.Data;
using DevExpress.Utils;
using DevExpress.XtraBars;
using DevExpress.XtraEditors;
using DevExpress.XtraGrid.Columns;
using DevExpress.XtraGrid.Views.Base;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraTab;
using DevExpress.XtraTreeList.Columns;
using DevExpress.XtraTreeList.Nodes;
using Lskj.Business;
using Lskj.Business.Impl;
using Lskj.Control;
using Lskj.Control.BrowserSetting;
using Lskj.Control.Model;
using Lskj.Core;
using Lskj.Data;
using Lskj.Model;
using Lskj.PubBill.Model;
using Lskj.Util;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Lskj.PubBill
{
public partial class BillModule : UserControl
{
///
/// 是否为初始化创建
///
private bool _isInitFinish;
///
/// 是否加载右侧控件数据
///
private bool _isLoadRightControlValue = true;
///
/// 是否手动选择了模版
///
private bool _isSelectedTemplete;
///
/// 是否直接打印
///
private bool _isExcPrint;
///
/// 是否选择关联下发
///
private bool _isCheck;
///
/// 主打印Sql
///
private string _mainPrintSql;
private string guidField = "xxxxx_guid";
///
/// 主键字段
///
private string mRecordPrimaryField;
///
/// 单据水印
///
private WaterMark _waterMark;
///
/// 导入单据明细数据、导入单据明细并更新
///
private BarButtonItem _itemImport, _itemImportUpdate;
///
/// 打印主sql中关联打印次数返回条件
///
private string _printModeCond;
///
/// 打印完成后添加数据用到的参数: 表名,列前缀,主键字段,主键值,模块编号,主打印Sql
///
private List _printSaveParams;
///
/// 单据明细列
///
private DataTable _detailColumns;
private bool IsCopying = false;
private bool _moduleResourcesReleased;
private int _preferredSourcePanelWidth;
private bool _sourcePanelWidthRestorePending;
private bool _restoringSourcePanelWidth;
protected DataRow BillRowItem;
///
/// 主表控件
///
public MyControl ControlObj;
///
/// 入口参数
///
protected DynamicBillModel SysModel;
///
/// 是否为Brp模版
///
/// true if this instance is BRP templete; otherwise, false.
protected bool IsBrpTemplete { get { return SysModel is DynamicBillBrpModel; } }
///
///
///
public BillModel BillModel;
///
/// 快速扫码控件
///
/// The main bottom input object.
public PanelControl MainBottomInputObj { get { return this.pl_input; } }
///
/// Brp模版控件
///
/// The main bottom templete object.
public PanelControl MainBottomTempleteObj { get { return this.pl_templete; } }
///
/// 明细表格数据
///
/// The main bottom templete object.
public GridControlEx gcMainDetilObj { get { return this.gcMain; } }
///
/// Brp模版控件
///
/// 扫码框
public TextEdit txtinputobj { get { return this.txt_input; } }
///
/// 数量名称
///
public string NumberMc;
///
/// 红字单据的分配管理模块
///
public string rdRedUnionCode;
///
/// 蓝字单据的分配管理模块
///
public string rdBlueUnionCode;
///
/// 蓝字单据的分配管理模块
///
Dictionary pageNumKey = new Dictionary();
///
/// 是否拖拽换行展示
///
public bool isDragWrap = true;
///
/// 触发主表改变刷新来源限制
///
private bool IsBillMaster = true;
///
/// 是否执行了加载储存过程
///
//public bool ProcessExists = false;
///
/// 保存或修改时报错信息
///
public string SaveErrorMessage = string.Empty;
///
/// 单据明细删除的行
///
// private Dictionary ToWithdrawRows = new Dictionary();
private List> ToWithdrawRows = new List>();
///
///改变颜色行
///
private List ChangeColorRow = new List();
///
///
///
public string AssociatedField = string.Empty;
///
/// 注册设置公共事件私有类
///
private static PubEvenImpl _eventHandler;
///
/// 注册设置公共事件类
///
private static PubEvenImpl eventHandler;
///
/// 当前人员是否有导出权限
///
public bool ExportPermission;
///
/// 是否显示单据管理条数
///
public bool IsBillShowCount = false;
///
/// 来源明细的页面名字后缀(设置成全局变量,更好的处理语言翻译的情况)
///
public string DetailedSuffix = Business.Impl.LanguageTranslation.Translatable ? "-" + Business.Impl.LanguageTranslation.GetTranslatedText("明细") : "-明细";
///
/// 数量后缀
///
public string QuantitySuffix = Business.Impl.LanguageTranslation.Translatable ? Business.Impl.LanguageTranslation.GetTranslatedText("条") + ")" : "条)";
///
/// 新增
///
public string addText = Business.Impl.LanguageTranslation.Translatable ? "(" + Business.Impl.LanguageTranslation.GetTranslatedText("新增") + ")" : "(新增)";
///
/// 修改
///
public string updateText = Business.Impl.LanguageTranslation.Translatable ? "(" + Business.Impl.LanguageTranslation.GetTranslatedText("修改") + ")" : "(修改)";
///
/// 单据来源控件集合
///
public Dictionary BillModuleModelDic = new Dictionary();
///
/// 当前单据在 UI 线程创建的来源明细页。部分非首来源页不会立即加入
/// TabControl,模块永久关闭时需要按所属范围释放这些脱离父级的页面。
///
private readonly HashSet _ownedSourceDetailPages =
new HashSet();
///
/// 主表动态生成的日期列
///
public List DateColumnList = new List();
///
/// 主表动态生成的合计列
///
public GridColumn SumGridColumn = new GridColumn();
///
/// 附加右键菜单集合
///
public List itemCommonList = new List();
///
/// 是否已经添加了多行汇总
///
public bool MultiLineSummary;
///
/// 扫码框
///
public TextEdit ScanCodeTextEdit = null;
///
/// 初始化时选中的页签
///
public XtraTabPage InitialSelectionTab = null;
///
/// 当前操作的ImageEdit
///
private LabelImageEdit _imageEdit;
///
/// 当前来源明细中变色行
///
private HashSet ColorHandles = new HashSet();
///
/// 保存验证条件表
///
public DataTable SaveCondTab = new DataTable();
///
/// 明细对应字段(参数9中的明细sql对应的主表明细字段) Dictionary
///
public Dictionary DetailMappingField = new Dictionary();
public BillModule()
{
InitializeComponent();
this.ssc_main_top.SizeChanged += OnTopSplitterSizeChanged;
}
///
/// Releases runtime objects created by the bill module. Cleanup is
/// idempotent and best-effort so it cannot change the close result.
///
public void ReleaseModuleResources()
{
if (_moduleResourcesReleased)
return;
_moduleResourcesReleased = true;
TryRelease(() => PrintUtil.OnAfterPrint -= new EventHandler(OnReportPrintAfter), "打印回调");
TryRelease(ReleaseModuleEvents, "模块事件");
TryRelease(ReleaseModuleDataSources, "模块数据源");
TryRelease(DisposeDetachedOwnedSourceControls, "已脱离父容器的来源控件");
TryRelease(ReleaseRuntimeCollections, "运行时集合");
BillRowItem = null;
ControlObj = null;
BillModel = null;
SysModel = null;
SumGridColumn = null;
ScanCodeTextEdit = null;
InitialSelectionTab = null;
_imageEdit = null;
_waterMark = null;
_itemImport = null;
_itemImportUpdate = null;
}
private void ReleaseModuleEvents()
{
// BillModule 会给来源、明细以及明细的明细动态创建的 GridView 注册
// 实例方法。DevExpress 的事件委托保存在 View 的 EventHandlerList 中,
// 即使 View 已经脱离 GridControl,也会继续强引用 BillModule。关闭时
// 只解除本模块注册的处理器,不 Dispose 共享的 GridControl/GridView。
List moduleControls = new List();
try
{
moduleControls.AddRange(EnumerateChildControls(this).ToList());
}
catch (Exception exception)
{
Debug.WriteLine("收集单据模块控件失败:" + exception);
}
// Form.Close/Dispose 期间某些页签可能已经从 Controls 移除,
// BillModuleModelDic 和页签 Tag 仍然保留这些动态控件的引用,
// 因此一并加入快照,确保解绑覆盖所有来源表格。
try
{
foreach (BillModuleModel moduleModel in BillModuleModelDic.Values.ToList())
{
AddModuleControlSnapshot(moduleControls, moduleModel == null ? null : moduleModel.SourceControl as System.Windows.Forms.Control);
AddModuleControlSnapshot(moduleControls, moduleModel == null ? null : moduleModel.SourceDetailControl as System.Windows.Forms.Control);
AddModuleControlSnapshot(moduleControls, moduleModel == null ? null : moduleModel.SourceDetailDetailControl as System.Windows.Forms.Control);
}
}
catch (Exception exception)
{
Debug.WriteLine("收集单据来源控件失败:" + exception);
}
foreach (System.Windows.Forms.Control control in moduleControls.ToList())
{
try
{
GridControlEx grid = control as GridControlEx;
if (grid != null)
ReleaseBillModuleGridEvents(grid);
TreeViewEx treeView = control as TreeViewEx;
if (treeView != null)
treeView.TreeNodeSelectAfter -= OnTreeNodeSelectAfter;
SplitContainerControl splitContainer = control as SplitContainerControl;
if (splitContainer != null)
{
splitContainer.SplitterMoved -= OnTopSplitterMoved;
splitContainer.SplitterMoved -= OnMainSplitterMoved;
splitContainer.SplitterMoved -= OnDetailsSplitterMoved;
splitContainer.SplitterMoved -= OnSpecialMainSplitterMoved;
splitContainer.SplitterMoved -= OnSpecialLeftSplitterMoved;
splitContainer.SizeChanged -= OnTopSplitterSizeChanged;
}
SimpleButton commonButton = control as SimpleButton;
if (commonButton != null)
commonButton.Click -= itemCommon_Click;
LabelImageEdit imageEdit = control as LabelImageEdit;
if (imageEdit != null)
{
imageEdit.UploadEvent -= OnImageUploadEvent;
imageEdit.DeleteEvent -= OnImageDeleteEvent;
}
}
catch (Exception exception)
{
Debug.WriteLine("解除单据模块控件事件失败:" + exception);
}
}
ReleaseBillModuleSearchEvents(moduleControls);
ReleaseBillModuleBarEvents();
if (_imageEdit != null)
{
_imageEdit.UploadEvent -= OnImageUploadEvent;
_imageEdit.DeleteEvent -= OnImageDeleteEvent;
}
if (ScanCodeTextEdit != null)
ScanCodeTextEdit.KeyDown -= Text_KeyDown;
if (gcMain != null)
{
gcMain.OnAfterLinkCilk -= OnAfterLinkCilkCall;
gcMain.OnAllAfterParseCallBack -= OnAllAfterParseCallBack;
}
if (tb_buttom != null)
{
tb_buttom.OnDetailSaveGridCallBack -= Tab_OnDetailSaveGridCallBack;
tb_buttom.BillDetailRightGridCallBack -= Tab_OnDetailSaveGridCallBack;
tb_buttom.OnRightCallback -= OnButtomRightCallBack;
if (tb_buttom.TabControlObj != null)
tb_buttom.TabControlObj.SelectedPageChanged -= TabControlObj_SelectedPageChanged;
}
}
private void DisposeDetachedOwnedSourceControls()
{
// 非首个来源明细页由当前 BillModule 创建,但不会立即加入底部页签。
// 只释放本模块明确登记且仍未挂到任何父容器的页面;已挂载页面继续
// 交给其所在窗体的正常 Dispose 链,避免影响其他未关闭模块。
foreach (XtraTabPage detailPage in _ownedSourceDetailPages.ToList())
{
if (detailPage == null || detailPage.IsDisposed ||
!IsDetachedOwnedSourceDetailPage(detailPage))
{
continue;
}
try
{
detailPage.Dispose();
}
catch (Exception exception)
{
Debug.WriteLine("释放单据来源明细页失败:" + exception);
}
}
// 来源页签切换会通过 Controls.Clear 临时摘下非当前页的控件。
// 模块永久关闭时只处理当前 BillModuleModelDic 明确登记的三个
// 顶层来源控件,不扫描其他窗体或全局控件树。释放父控件可让
// ModuleGridEx 等控件按自身 Dispose 逻辑释放其专属 Grid/BarManager。
var ownedSourceControls =
new HashSet();
foreach (BillModuleModel moduleModel in BillModuleModelDic.Values.ToList())
{
if (moduleModel == null)
continue;
AddOwnedSourceControl(ownedSourceControls, moduleModel.SourceControl);
AddOwnedSourceControl(ownedSourceControls, moduleModel.SourceDetailControl);
AddOwnedSourceControl(ownedSourceControls, moduleModel.SourceDetailDetailControl);
}
foreach (System.Windows.Forms.Control sourceControl in ownedSourceControls)
{
if (sourceControl == null || sourceControl.IsDisposed ||
!IsDetachedFromModuleDisposeChain(sourceControl))
{
continue;
}
try
{
// 仅释放当前单据持有且已脱离窗体 Dispose 链的实例;
// 不会触碰仍挂在其他 BillModule/Form 下的控件。
sourceControl.Dispose();
}
catch (Exception exception)
{
Debug.WriteLine("释放单据来源控件失败:" + exception);
}
}
}
private bool IsDetachedOwnedSourceDetailPage(XtraTabPage detailPage)
{
if (detailPage == null)
return false;
try
{
if (tb_buttom != null && tb_buttom.TabControlObj != null &&
tb_buttom.TabControlObj.TabPages.Contains(detailPage))
{
return false;
}
// 明确存在父级表示页面已经挂入某个活动控件树,不由当前模块
// 的“孤立页面”清理路径处理。
return detailPage.Parent == null;
}
catch (ObjectDisposedException)
{
return true;
}
}
private static void AddOwnedSourceControl(
HashSet target,
object sourceControl)
{
System.Windows.Forms.Control control =
sourceControl as System.Windows.Forms.Control;
if (target != null && control != null)
target.Add(control);
}
private static void AttachCachedTask(
Dictionary