feat(control): add extended return search for tables and forms

This commit is contained in:
2026-07-29 15:57:29 +08:00
parent b893e8d8e4
commit 1bbe9c9a4c
13 changed files with 2818 additions and 645 deletions
+181 -22
View File
@@ -136,6 +136,11 @@ namespace Lskj.Control.Model
/// 下拉框、搜索框控件对象
/// </summary>
public List<ControlModel> mControlList = new List<ControlModel>();
private readonly List<LabelExtendedReturnSearchEdit> mExtendedReturnSearchControls =
new List<LabelExtendedReturnSearchEdit>();
private readonly List<KeyValuePair<object, EventArgs>> mExtendedReturnPendingChanges =
new List<KeyValuePair<object, EventArgs>>();
private int mExtendedReturnBatchDepth;
/// <summary>
/// 数据源任务对象
/// </summary>
@@ -2253,6 +2258,10 @@ namespace Lskj.Control.Model
LabelMultiAutoTextEdit4 moduleReturnsIdNew = ctr as LabelMultiAutoTextEdit4;
value = ControlType.LabSelectReturnIdNew == model.FieldType ? moduleReturnsIdNew.EditValue : moduleReturnsIdNew.EditText;
break;
case ControlType.LabSearchReturnIdExtended:
LabelExtendedReturnSearchEdit extendedReturnSearch = ctr as LabelExtendedReturnSearchEdit;
value = extendedReturnSearch == null ? string.Empty : extendedReturnSearch.EditValue;
break;
case ControlType.DynamicallyGeneratedSql:
LabelMultiAutoTextEdit3 moduleSqlGenerated = ctr as LabelMultiAutoTextEdit3;
value = moduleSqlGenerated.EditText;
@@ -2679,6 +2688,7 @@ namespace Lskj.Control.Model
}
}
RefreshExtendedReturnDisplayControls();
foreach (ControlModel model in this.ControlModels)
{
BaseUserControl control = FindControl(model);
@@ -3710,6 +3720,14 @@ namespace Lskj.Control.Model
}
pictureEdit.TextEdit.Image = image;
}
else if (baseControl is LabelExtendedReturnSearchEdit)
{
LabelExtendedReturnSearchEdit extendedReturnSearch = baseControl as LabelExtendedReturnSearchEdit;
extendedReturnSearch.EditValue = controlValue == null || controlValue == DBNull.Value
? string.Empty
: controlValue + "";
baseControl.Model.Text = extendedReturnSearch.EditValue;
}
else if (baseControl.Model.FieldType == 7 && !"****".Equals(controlValue))
{
string dfmt = baseControl.Model.DataFormat;
@@ -3750,6 +3768,113 @@ namespace Lskj.Control.Model
//baseControl.Parent.Focus();
}
}
RefreshExtendedReturnDisplayControls();
}
/// <summary>
/// 用户从扩展搜索弹窗选择或清空时,批量写入所有映射字段。
/// 中间值改变事件会延迟到全部字段提交成功后执行,且不改变原始值基线。
/// </summary>
public void ApplyExtendedReturnValues(IList<KeyValuePair<string, object>> values)
{
if (values == null || values.Count == 0) return;
if (mExtendedReturnBatchDepth > 0)
{
throw new InvalidOperationException("扩展返回字段正在批量赋值,不能重复执行。");
}
List<KeyValuePair<string, object>> normalizedValues =
new List<KeyValuePair<string, object>>();
Dictionary<string, string> originalValues =
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
Dictionary<BaseUserControl, string> originalModelTexts =
new Dictionary<BaseUserControl, string>();
HashSet<string> targetFields = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
foreach (KeyValuePair<string, object> value in values)
{
string targetField = (value.Key ?? string.Empty).Trim();
if (targetField.Length == 0)
{
throw new InvalidOperationException("扩展返回字段名称不能为空。");
}
if (!targetFields.Add(targetField))
{
throw new InvalidOperationException(
string.Format("扩展返回字段“{0}”重复。", targetField));
}
BaseUserControl targetControl = FindControl(targetField);
if (targetControl == null)
{
throw new InvalidOperationException(
string.Format("MyControl 中不存在业务控件“{0}”。", targetField));
}
object normalizedValue = value.Value == null || value.Value == DBNull.Value
? string.Empty
: value.Value;
normalizedValues.Add(new KeyValuePair<string, object>(targetField, normalizedValue));
originalValues[targetField] = GetControlValue(targetField);
originalModelTexts[targetControl] = targetControl.Model == null
? null
: targetControl.Model.Text;
}
bool success = false;
mExtendedReturnPendingChanges.Clear();
mExtendedReturnBatchDepth++;
try
{
foreach (KeyValuePair<string, object> value in normalizedValues)
{
SetControlValue(value.Key, value.Value);
}
RestoreExtendedReturnModelTexts(originalModelTexts);
RefreshExtendedReturnDisplayControls(true);
success = true;
}
catch
{
foreach (KeyValuePair<string, string> originalValue in originalValues)
{
SetControlValue(originalValue.Key, originalValue.Value);
}
RestoreExtendedReturnModelTexts(originalModelTexts);
RefreshExtendedReturnDisplayControls(true);
throw;
}
finally
{
mExtendedReturnBatchDepth--;
if (!success) mExtendedReturnPendingChanges.Clear();
}
FlushExtendedReturnPendingChanges();
}
private static void RestoreExtendedReturnModelTexts(
IDictionary<BaseUserControl, string> originalModelTexts)
{
foreach (KeyValuePair<BaseUserControl, string> item in originalModelTexts)
{
if (item.Key != null && item.Key.Model != null)
{
item.Key.Model.Text = item.Value;
}
}
}
private void RefreshExtendedReturnDisplayControls(bool force = false)
{
if (mExtendedReturnBatchDepth > 0 && !force) return;
foreach (LabelExtendedReturnSearchEdit control in mExtendedReturnSearchControls)
{
if (control != null && !control.IsDisposed && control.Model != null)
{
control.RefreshDisplayText();
}
}
}
/// <summary>
@@ -4152,6 +4277,7 @@ namespace Lskj.Control.Model
model.Sign = item.Table.Columns.Contains("TM_tagID") && !string.IsNullOrEmpty(item["TM_tagID"] + "") ? Convert.ToInt32(item["TM_tagID"] + "") : 0;
model.TextMember = item["lookupResult"] + "";
model.ValueMember = item["lookupKeyField"] + "";
model.ResultFields = item.Table.Columns.Contains("resultfields") ? item["resultfields"] + "" : string.Empty;
if (!dataCaches.GetValue(item, "LookupSql", out string lookupSql))
{
@@ -4239,28 +4365,6 @@ namespace Lskj.Control.Model
model.FieldType = 161;
model.IsRadio = true;
}
//快速搜索框在控件中转成普通搜索框
if (model.FieldType == 181 || model.FieldType == 182 || model.FieldType == 183 || model.FieldType == 184)
{
switch (model.FieldType)
{
case ControlType.DictionarySearchBoxToId:
model.FieldType = 5;
break;
case ControlType.DictionarySearchBoxToText:
model.FieldType = 6;
break;
case ControlType.DictionarySearchBoxToIdParam:
model.FieldType = 15;
break;
case ControlType.DictionarySearchBoxToTextParam:
model.FieldType = 16;
break;
}
}
return model;
}
/// <summary>
@@ -4830,6 +4934,18 @@ namespace Lskj.Control.Model
if (!isLoadBorder) moduleReturnsIdNew.TextEdit.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
baseControl = moduleReturnsIdNew;
break;
case ControlType.LabSearchReturnIdExtended:
LabelExtendedReturnSearchEdit extendedReturnSearch = new LabelExtendedReturnSearchEdit();
extendedReturnSearch.ControlObj = this;
mExtendedReturnSearchControls.Add(extendedReturnSearch);
extendedReturnSearch.TextEdit.KeyDown += new KeyEventHandler(OnTextEditKeyDown);
extendedReturnSearch.TextEdit.TextChanged += new EventHandler(OnTextEditTextChanged);
if (!isLoadBorder)
{
extendedReturnSearch.TextEdit.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
}
baseControl = extendedReturnSearch;
break;
case ControlType.DynamicallyGeneratedSql:
LabelMultiAutoTextEdit3 moduleSqlGenerated = new LabelMultiAutoTextEdit3();
// moduleSqlGenerated.SetDataSource();
@@ -5884,6 +6000,49 @@ namespace Lskj.Control.Model
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
protected void OnTextEditTextChanged(object sender, EventArgs e)
{
if (mExtendedReturnBatchDepth > 0)
{
QueueExtendedReturnPendingChange(sender, e);
return;
}
ProcessTextEditTextChanged(sender, e);
}
private void QueueExtendedReturnPendingChange(object sender, EventArgs e)
{
System.Windows.Forms.Control changedControl = sender as System.Windows.Forms.Control;
BaseUserControl baseControl = changedControl == null
? null
: changedControl.ToBaseUserControl();
foreach (KeyValuePair<object, EventArgs> pendingChange in mExtendedReturnPendingChanges)
{
System.Windows.Forms.Control pendingControl =
pendingChange.Key as System.Windows.Forms.Control;
BaseUserControl pendingBaseControl = pendingControl == null
? null
: pendingControl.ToBaseUserControl();
if (baseControl != null && object.ReferenceEquals(baseControl, pendingBaseControl))
{
return;
}
}
mExtendedReturnPendingChanges.Add(
new KeyValuePair<object, EventArgs>(sender, e ?? EventArgs.Empty));
}
private void FlushExtendedReturnPendingChanges()
{
KeyValuePair<object, EventArgs>[] pendingChanges =
mExtendedReturnPendingChanges.ToArray();
mExtendedReturnPendingChanges.Clear();
foreach (KeyValuePair<object, EventArgs> pendingChange in pendingChanges)
{
ProcessTextEditTextChanged(pendingChange.Key, pendingChange.Value);
}
}
private void ProcessTextEditTextChanged(object sender, EventArgs e)
{
BaseUserControl baseControl = (sender as System.Windows.Forms.Control).ToBaseUserControl();
this.SetUnionAncCalcControl(baseControl);