Compare commits
2 Commits
b893e8d8e4
...
9c0fdac9ba
| Author | SHA1 | Date | |
|---|---|---|---|
| 9c0fdac9ba | |||
| 1bbe9c9a4c |
@@ -1059,6 +1059,28 @@ namespace Lskj.Business.Impl
|
|||||||
table.Columns["tagid"].ColumnName = "nullable";
|
table.Columns["tagid"].ColumnName = "nullable";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!table.Columns.Contains("resultfields") && HasExistsColumn("p_systemwordbooktab", "resultfields"))
|
||||||
|
{
|
||||||
|
table.Columns.Add("resultfields", typeof(string));
|
||||||
|
DataTable resultFieldsTable = SqlHelper.ExecuteDataTable(
|
||||||
|
"select id,isnull(resultfields,'') resultfields from p_systemwordbooktab where tab=@modid",
|
||||||
|
new SqlParameter[] { new SqlParameter("@modid", menuCode) });
|
||||||
|
|
||||||
|
Dictionary<string, string> resultFieldsById = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
foreach (DataRow row in resultFieldsTable.Rows)
|
||||||
|
{
|
||||||
|
resultFieldsById[row["id"] + ""] = row["resultfields"] + "";
|
||||||
|
}
|
||||||
|
foreach (DataRow row in table.Rows)
|
||||||
|
{
|
||||||
|
string resultFields;
|
||||||
|
if (table.Columns.Contains("id") && resultFieldsById.TryGetValue(row["id"] + "", out resultFields))
|
||||||
|
{
|
||||||
|
row["resultfields"] = resultFields;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -1272,7 +1294,73 @@ namespace Lskj.Business.Impl
|
|||||||
p[1].Value = menuCode;
|
p[1].Value = menuCode;
|
||||||
p[2].Value = ERPInfo.Instance.UserName;
|
p[2].Value = ERPInfo.Instance.UserName;
|
||||||
|
|
||||||
return SqlHelper.ExecuteDataSet(CommandType.StoredProcedure, "p_getControlLocation", "temp", p).Tables[0];
|
DataTable table = SqlHelper.ExecuteDataSet(
|
||||||
|
CommandType.StoredProcedure,
|
||||||
|
"p_getControlLocation",
|
||||||
|
"temp",
|
||||||
|
p).Tables[0];
|
||||||
|
AppendExtendedReturnResultFields(table, menuCode);
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// p_getControlLocation 的旧版本不返回 resultfields。
|
||||||
|
/// 仅当窗体包含 180/181 扩展返回控件时按模块补取,普通窗体不增加查询。
|
||||||
|
/// </summary>
|
||||||
|
private static void AppendExtendedReturnResultFields(DataTable table, string menuCode)
|
||||||
|
{
|
||||||
|
if (table == null || table.Rows.Count == 0 ||
|
||||||
|
!table.Columns.Contains("id") || !table.Columns.Contains("fieldTypeId"))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<DataRow> extendedRows = new List<DataRow>();
|
||||||
|
bool allConfigured = table.Columns.Contains("resultfields");
|
||||||
|
foreach (DataRow row in table.Rows)
|
||||||
|
{
|
||||||
|
int fieldType;
|
||||||
|
if (!int.TryParse(row["fieldTypeId"] + "", out fieldType) ||
|
||||||
|
(fieldType != 180 && fieldType != 181))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
extendedRows.Add(row);
|
||||||
|
if (!table.Columns.Contains("resultfields") ||
|
||||||
|
string.IsNullOrWhiteSpace(row["resultfields"] + ""))
|
||||||
|
{
|
||||||
|
allConfigured = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extendedRows.Count == 0 || allConfigured) return;
|
||||||
|
if (!HasExistsColumn("p_systemwordbooktab", "resultfields")) return;
|
||||||
|
|
||||||
|
if (!table.Columns.Contains("resultfields"))
|
||||||
|
{
|
||||||
|
table.Columns.Add("resultfields", typeof(string));
|
||||||
|
}
|
||||||
|
|
||||||
|
DataTable resultFieldsTable = SqlHelper.ExecuteDataTable(
|
||||||
|
"select id,isnull(resultfields,'') resultfields " +
|
||||||
|
"from p_systemwordbooktab where tab=@modid",
|
||||||
|
new SqlParameter[] { new SqlParameter("@modid", menuCode) });
|
||||||
|
Dictionary<string, string> resultFieldsById =
|
||||||
|
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
foreach (DataRow row in resultFieldsTable.Rows)
|
||||||
|
{
|
||||||
|
resultFieldsById[row["id"] + ""] = row["resultfields"] + "";
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (DataRow row in extendedRows)
|
||||||
|
{
|
||||||
|
string resultFields;
|
||||||
|
if (resultFieldsById.TryGetValue(row["id"] + "", out resultFields))
|
||||||
|
{
|
||||||
|
row["resultfields"] = resultFields;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <para>说明:获取添加界面多标签</para>
|
/// <para>说明:获取添加界面多标签</para>
|
||||||
@@ -1436,4 +1524,4 @@ namespace Lskj.Business.Impl
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -461,6 +461,8 @@ namespace Lskj.Business.Impl
|
|||||||
sumCond += ",a.ColumnAnnotation ";
|
sumCond += ",a.ColumnAnnotation ";
|
||||||
if (dataTable.Columns.Contains("TitleColor"))
|
if (dataTable.Columns.Contains("TitleColor"))
|
||||||
sumCond += ",a.TitleColor ";
|
sumCond += ",a.TitleColor ";
|
||||||
|
if (dataTable.Columns.Contains("resultfields"))
|
||||||
|
sumCond += ",a.resultfields ";
|
||||||
|
|
||||||
string columsSql = string.Format(@"SELECT DISTINCT
|
string columsSql = string.Format(@"SELECT DISTINCT
|
||||||
isnull(CASE WHEN ISNULL(b.userList,'')='' AND ISNULL(a.PrivilegeView,'')<>'' OR isnull(isVisible,0)=1 THEN 0 ELSE width END,0) width,
|
isnull(CASE WHEN ISNULL(b.userList,'')='' AND ISNULL(a.PrivilegeView,'')<>'' OR isnull(isVisible,0)=1 THEN 0 ELSE width END,0) width,
|
||||||
@@ -559,6 +561,8 @@ namespace Lskj.Business.Impl
|
|||||||
sumCond += ",a.ColumnAnnotation ";
|
sumCond += ",a.ColumnAnnotation ";
|
||||||
if (dataTable.Columns.Contains("TitleColor"))
|
if (dataTable.Columns.Contains("TitleColor"))
|
||||||
sumCond += ",a.TitleColor ";
|
sumCond += ",a.TitleColor ";
|
||||||
|
if (dataTable.Columns.Contains("resultfields"))
|
||||||
|
sumCond += ",a.resultfields ";
|
||||||
|
|
||||||
string columsSql = string.Format(@"SELECT DISTINCT
|
string columsSql = string.Format(@"SELECT DISTINCT
|
||||||
isnull(CASE WHEN ISNULL(b.userList,'')='' AND ISNULL(a.PrivilegeView,'')<>'' OR isnull(isVisible,0)=1 THEN 0 ELSE width END,0) width,
|
isnull(CASE WHEN ISNULL(b.userList,'')='' AND ISNULL(a.PrivilegeView,'')<>'' OR isnull(isVisible,0)=1 THEN 0 ELSE width END,0) width,
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
using Lskj.Control.MultiModelLookUp;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Lskj.Control
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 按模块编号延迟读取模块数据源 SQL。只缓存 SQL 文本,不加载业务数据。
|
||||||
|
/// </summary>
|
||||||
|
internal sealed class ExtendedReturnModuleSourceResolver
|
||||||
|
{
|
||||||
|
private readonly object syncRoot = new object();
|
||||||
|
private readonly Dictionary<string, string> sourceSqlByModule =
|
||||||
|
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
public string Resolve(string moduleCode)
|
||||||
|
{
|
||||||
|
moduleCode = (moduleCode ?? string.Empty).Trim();
|
||||||
|
if (moduleCode.Length == 0)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("扩展模块搜索的模块编号不能为空。");
|
||||||
|
}
|
||||||
|
|
||||||
|
lock (syncRoot)
|
||||||
|
{
|
||||||
|
string cachedSql;
|
||||||
|
if (sourceSqlByModule.TryGetValue(moduleCode, out cachedSql))
|
||||||
|
{
|
||||||
|
return cachedSql;
|
||||||
|
}
|
||||||
|
|
||||||
|
using (FrmModelLookUp lookup = new FrmModelLookUp(moduleCode, true))
|
||||||
|
{
|
||||||
|
string sourceSql = lookup.SysModel == null
|
||||||
|
? string.Empty
|
||||||
|
: lookup.SysModel.MenuSql;
|
||||||
|
if (string.IsNullOrWhiteSpace(sourceSql))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(
|
||||||
|
string.Format("模块“{0}”未配置数据源 SQL。", moduleCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceSqlByModule.Add(moduleCode, sourceSql);
|
||||||
|
return sourceSql;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,233 @@
|
|||||||
|
using DevExpress.XtraEditors;
|
||||||
|
using DevExpress.XtraGrid;
|
||||||
|
using DevExpress.XtraGrid.Views.Grid;
|
||||||
|
using DevExpress.XtraGrid.Views.Grid.ViewInfo;
|
||||||
|
using DevExpress.Utils;
|
||||||
|
using System;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace Lskj.Control
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 181 扩展搜索专用弹窗。查询文本只存在于本控件中,不参与业务列绑定。
|
||||||
|
/// </summary>
|
||||||
|
internal sealed class ExtendedReturnSearchPopup : UserControl
|
||||||
|
{
|
||||||
|
private readonly TableLayoutPanel searchPanel;
|
||||||
|
private readonly TextEdit searchEdit;
|
||||||
|
private readonly SimpleButton queryButton;
|
||||||
|
private readonly SimpleButton clearButton;
|
||||||
|
private readonly GridControl resultGrid;
|
||||||
|
private readonly GridView resultView;
|
||||||
|
|
||||||
|
public event EventHandler SearchRequested;
|
||||||
|
public event EventHandler ClearRequested;
|
||||||
|
public event EventHandler ResultSelected;
|
||||||
|
|
||||||
|
public ExtendedReturnSearchPopup()
|
||||||
|
{
|
||||||
|
searchPanel = new TableLayoutPanel();
|
||||||
|
searchEdit = new TextEdit();
|
||||||
|
queryButton = new SimpleButton();
|
||||||
|
clearButton = new SimpleButton();
|
||||||
|
resultGrid = new GridControl();
|
||||||
|
resultView = new GridView(resultGrid);
|
||||||
|
|
||||||
|
SuspendLayout();
|
||||||
|
searchPanel.SuspendLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(searchEdit.Properties)).BeginInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(resultGrid)).BeginInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(resultView)).BeginInit();
|
||||||
|
|
||||||
|
searchPanel.Dock = DockStyle.Top;
|
||||||
|
searchPanel.Height = 36;
|
||||||
|
searchPanel.Padding = new Padding(4);
|
||||||
|
searchPanel.ColumnCount = 3;
|
||||||
|
searchPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
|
||||||
|
searchPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 72F));
|
||||||
|
searchPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 72F));
|
||||||
|
searchPanel.RowCount = 1;
|
||||||
|
searchPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
|
||||||
|
searchPanel.GrowStyle = TableLayoutPanelGrowStyle.FixedSize;
|
||||||
|
|
||||||
|
queryButton.Dock = DockStyle.Fill;
|
||||||
|
queryButton.Margin = new Padding(4, 0, 0, 0);
|
||||||
|
queryButton.Text = "查询";
|
||||||
|
queryButton.TabIndex = 1;
|
||||||
|
queryButton.Click += QueryButton_Click;
|
||||||
|
|
||||||
|
clearButton.Dock = DockStyle.Fill;
|
||||||
|
clearButton.Margin = new Padding(4, 0, 0, 0);
|
||||||
|
clearButton.Text = "清空";
|
||||||
|
clearButton.TabIndex = 2;
|
||||||
|
clearButton.Click += ClearButton_Click;
|
||||||
|
|
||||||
|
searchEdit.Dock = DockStyle.Fill;
|
||||||
|
searchEdit.Margin = new Padding(0);
|
||||||
|
searchEdit.TabIndex = 0;
|
||||||
|
searchEdit.Properties.AutoHeight = false;
|
||||||
|
searchEdit.Properties.NullValuePrompt = "输入查询内容后按回车";
|
||||||
|
searchEdit.Properties.NullValuePromptShowForEmptyValue = true;
|
||||||
|
searchEdit.KeyDown += SearchEdit_KeyDown;
|
||||||
|
|
||||||
|
searchPanel.Controls.Add(searchEdit, 0, 0);
|
||||||
|
searchPanel.Controls.Add(queryButton, 1, 0);
|
||||||
|
searchPanel.Controls.Add(clearButton, 2, 0);
|
||||||
|
|
||||||
|
resultGrid.Dock = DockStyle.Fill;
|
||||||
|
resultGrid.MainView = resultView;
|
||||||
|
resultGrid.ViewCollection.AddRange(new DevExpress.XtraGrid.Views.Base.BaseView[] { resultView });
|
||||||
|
|
||||||
|
resultView.GridControl = resultGrid;
|
||||||
|
resultView.OptionsBehavior.Editable = false;
|
||||||
|
resultView.OptionsSelection.EnableAppearanceFocusedCell = false;
|
||||||
|
resultView.OptionsView.ShowGroupPanel = false;
|
||||||
|
resultView.OptionsView.ShowIndicator = true;
|
||||||
|
resultView.OptionsView.ColumnAutoWidth = false;
|
||||||
|
resultView.IndicatorWidth = 40;
|
||||||
|
resultView.CustomDrawRowIndicator += ResultView_CustomDrawRowIndicator;
|
||||||
|
resultView.MouseDown += ResultView_MouseDown;
|
||||||
|
resultView.KeyDown += ResultView_KeyDown;
|
||||||
|
|
||||||
|
Controls.Add(resultGrid);
|
||||||
|
Controls.Add(searchPanel);
|
||||||
|
Name = "ExtendedReturnSearchPopup";
|
||||||
|
Size = new System.Drawing.Size(420, 240);
|
||||||
|
|
||||||
|
((System.ComponentModel.ISupportInitialize)(resultView)).EndInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(resultGrid)).EndInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(searchEdit.Properties)).EndInit();
|
||||||
|
searchPanel.ResumeLayout(false);
|
||||||
|
ResumeLayout(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GridControl ResultGrid
|
||||||
|
{
|
||||||
|
get { return resultGrid; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public GridView ResultView
|
||||||
|
{
|
||||||
|
get { return resultView; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string SearchText
|
||||||
|
{
|
||||||
|
get { return (searchEdit.Text ?? string.Empty).Trim(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PrepareForOpen()
|
||||||
|
{
|
||||||
|
searchEdit.Text = string.Empty;
|
||||||
|
resultGrid.DataSource = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void FocusSearchEditor()
|
||||||
|
{
|
||||||
|
if (!searchEdit.CanFocus) return;
|
||||||
|
|
||||||
|
searchEdit.Focus();
|
||||||
|
searchEdit.SelectionStart = searchEdit.Text.Length;
|
||||||
|
searchEdit.SelectionLength = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SearchEdit_KeyDown(object sender, KeyEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.KeyCode == Keys.Down)
|
||||||
|
{
|
||||||
|
e.Handled = true;
|
||||||
|
e.SuppressKeyPress = true;
|
||||||
|
FocusResultRow(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (e.KeyCode == Keys.Up)
|
||||||
|
{
|
||||||
|
e.Handled = true;
|
||||||
|
e.SuppressKeyPress = true;
|
||||||
|
FocusResultRow(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (e.KeyCode != Keys.Enter) return;
|
||||||
|
|
||||||
|
e.Handled = true;
|
||||||
|
e.SuppressKeyPress = true;
|
||||||
|
RaiseSearchRequested();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FocusResultRow(bool focusLastRow)
|
||||||
|
{
|
||||||
|
if (resultView.DataRowCount <= 0) return;
|
||||||
|
|
||||||
|
int visibleIndex = focusLastRow ? resultView.DataRowCount - 1 : 0;
|
||||||
|
int rowHandle = resultView.GetVisibleRowHandle(visibleIndex);
|
||||||
|
if (rowHandle < 0) return;
|
||||||
|
|
||||||
|
resultGrid.Focus();
|
||||||
|
resultView.FocusedRowHandle = rowHandle;
|
||||||
|
resultView.SelectRow(rowHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void QueryButton_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
RaiseSearchRequested();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RaiseSearchRequested()
|
||||||
|
{
|
||||||
|
if (SearchRequested != null)
|
||||||
|
{
|
||||||
|
SearchRequested(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ClearButton_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (ClearRequested != null)
|
||||||
|
{
|
||||||
|
ClearRequested(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ResultView_CustomDrawRowIndicator(object sender, RowIndicatorCustomDrawEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.Info == null || !e.Info.IsRowIndicator || e.RowHandle < 0) return;
|
||||||
|
|
||||||
|
e.Appearance.TextOptions.HAlignment = HorzAlignment.Center;
|
||||||
|
e.Info.DisplayText = (e.RowHandle + 1).ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ResultView_MouseDown(object sender, MouseEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.Button != MouseButtons.Left) return;
|
||||||
|
|
||||||
|
GridHitInfo hitInfo = resultView.CalcHitInfo(e.Location);
|
||||||
|
if (!hitInfo.InRow && !hitInfo.InRowCell) return;
|
||||||
|
|
||||||
|
resultView.FocusedRowHandle = hitInfo.RowHandle;
|
||||||
|
if (ResultSelected != null)
|
||||||
|
{
|
||||||
|
ResultSelected(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ResultView_KeyDown(object sender, KeyEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.KeyCode == Keys.Up &&
|
||||||
|
resultView.FocusedRowHandle == resultView.GetVisibleRowHandle(0))
|
||||||
|
{
|
||||||
|
e.Handled = true;
|
||||||
|
e.SuppressKeyPress = true;
|
||||||
|
FocusSearchEditor();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (e.KeyCode != Keys.Enter) return;
|
||||||
|
|
||||||
|
e.Handled = true;
|
||||||
|
e.SuppressKeyPress = true;
|
||||||
|
if (ResultSelected != null)
|
||||||
|
{
|
||||||
|
ResultSelected(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,844 @@
|
|||||||
|
using DevExpress.Utils;
|
||||||
|
using DevExpress.XtraEditors;
|
||||||
|
using DevExpress.XtraEditors.Controls;
|
||||||
|
using DevExpress.XtraGrid.Columns;
|
||||||
|
using Lskj.Business.Impl;
|
||||||
|
using Lskj.Control.Model;
|
||||||
|
using Lskj.Core;
|
||||||
|
using Lskj.Util;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
|
using System.Data.Common;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace Lskj.Control
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// MyControl 中的 173/174 扩展搜索控件。业务实际值与界面显示文本相互独立,
|
||||||
|
/// 数据源仅在弹出框打开或用户执行查询时按需访问。
|
||||||
|
/// </summary>
|
||||||
|
public sealed class LabelExtendedReturnSearchEdit : BaseUserControl
|
||||||
|
{
|
||||||
|
private const int MaxRows = 100;
|
||||||
|
private const int DefaultPopupWidth = 520;
|
||||||
|
private const int DefaultPopupHeight = 300;
|
||||||
|
private const int MinimumPopupWidth = 360;
|
||||||
|
|
||||||
|
private readonly Panel labelPanel;
|
||||||
|
private readonly Label titleLabel;
|
||||||
|
private readonly Panel editorPanel;
|
||||||
|
private readonly PopupContainerEdit popupEdit;
|
||||||
|
private readonly PopupContainerControl popupControl;
|
||||||
|
private readonly ExtendedReturnSearchPopup popup;
|
||||||
|
private readonly object schemaSyncRoot = new object();
|
||||||
|
private readonly object querySyncRoot = new object();
|
||||||
|
|
||||||
|
private string actualValue = string.Empty;
|
||||||
|
private string schemaSql = string.Empty;
|
||||||
|
private DataTable schema;
|
||||||
|
private SearchRequest pendingSearch;
|
||||||
|
private bool queryWorkerRunning;
|
||||||
|
private int queryVersion;
|
||||||
|
private bool disposed;
|
||||||
|
|
||||||
|
private sealed class SearchRequest
|
||||||
|
{
|
||||||
|
public int Version;
|
||||||
|
public string SourceSql;
|
||||||
|
public string Keyword;
|
||||||
|
public string ConnectionString;
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class QueryResult
|
||||||
|
{
|
||||||
|
public DataTable Table;
|
||||||
|
public Exception Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LabelExtendedReturnSearchEdit()
|
||||||
|
{
|
||||||
|
labelPanel = new Panel();
|
||||||
|
titleLabel = new Label();
|
||||||
|
editorPanel = new Panel();
|
||||||
|
popupEdit = new PopupContainerEdit();
|
||||||
|
popupControl = new PopupContainerControl();
|
||||||
|
popup = new ExtendedReturnSearchPopup();
|
||||||
|
|
||||||
|
// MyControl 的坐标和尺寸均来自配置值,保持与现有 LabelTextEdit 一致,
|
||||||
|
// 禁止 UserControl 在高 DPI/大字体环境下再次缩放配置宽度。
|
||||||
|
AutoScaleMode = AutoScaleMode.None;
|
||||||
|
|
||||||
|
SuspendLayout();
|
||||||
|
labelPanel.SuspendLayout();
|
||||||
|
editorPanel.SuspendLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(popupEdit.Properties)).BeginInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(popupControl)).BeginInit();
|
||||||
|
popupControl.SuspendLayout();
|
||||||
|
|
||||||
|
labelPanel.BackColor = Color.Transparent;
|
||||||
|
labelPanel.Dock = DockStyle.Left;
|
||||||
|
labelPanel.Width = 40;
|
||||||
|
labelPanel.Controls.Add(titleLabel);
|
||||||
|
|
||||||
|
titleLabel.AutoSize = true;
|
||||||
|
titleLabel.BackColor = Color.Transparent;
|
||||||
|
titleLabel.Location = new Point(5, 4);
|
||||||
|
titleLabel.Text = "名称";
|
||||||
|
|
||||||
|
editorPanel.BackColor = Color.Transparent;
|
||||||
|
editorPanel.Dock = DockStyle.Fill;
|
||||||
|
editorPanel.Controls.Add(popupEdit);
|
||||||
|
|
||||||
|
popupEdit.Dock = DockStyle.Fill;
|
||||||
|
popupEdit.Properties.AutoHeight = false;
|
||||||
|
popupEdit.Properties.AllowNullInput = DefaultBoolean.True;
|
||||||
|
popupEdit.Properties.NullText = string.Empty;
|
||||||
|
popupEdit.Properties.TextEditStyle = TextEditStyles.DisableTextEditor;
|
||||||
|
popupEdit.Properties.PopupSizeable = false;
|
||||||
|
popupEdit.Properties.PopupResizeMode = ResizeMode.Default;
|
||||||
|
popupEdit.Properties.PopupBorderStyle = PopupBorderStyles.Flat;
|
||||||
|
popupEdit.Properties.ShowPopupShadow = true;
|
||||||
|
popupEdit.Properties.PopupControl = popupControl;
|
||||||
|
popupEdit.Properties.Buttons.Clear();
|
||||||
|
popupEdit.Properties.Buttons.Add(new EditorButton(ButtonPredefines.Combo));
|
||||||
|
popupEdit.QueryPopUp += PopupEdit_QueryPopUp;
|
||||||
|
popupEdit.Popup += PopupEdit_Popup;
|
||||||
|
popupEdit.Closed += PopupEdit_Closed;
|
||||||
|
|
||||||
|
popup.Dock = DockStyle.Fill;
|
||||||
|
popupControl.Controls.Add(popup);
|
||||||
|
popup.SearchRequested += Popup_SearchRequested;
|
||||||
|
popup.ClearRequested += Popup_ClearRequested;
|
||||||
|
popup.ResultSelected += Popup_ResultSelected;
|
||||||
|
|
||||||
|
Controls.Add(editorPanel);
|
||||||
|
Controls.Add(labelPanel);
|
||||||
|
Name = "LabelExtendedReturnSearchEdit";
|
||||||
|
Size = new Size(249, 21);
|
||||||
|
Disposed += LabelExtendedReturnSearchEdit_Disposed;
|
||||||
|
|
||||||
|
popupControl.ResumeLayout(false);
|
||||||
|
((System.ComponentModel.ISupportInitialize)(popupControl)).EndInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(popupEdit.Properties)).EndInit();
|
||||||
|
editorPanel.ResumeLayout(false);
|
||||||
|
labelPanel.ResumeLayout(false);
|
||||||
|
labelPanel.PerformLayout();
|
||||||
|
ResumeLayout(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Model.MyControl ControlObj { get; set; }
|
||||||
|
|
||||||
|
public PopupContainerEdit TextEdit
|
||||||
|
{
|
||||||
|
get { return popupEdit; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 保存到当前业务字段的实际 ID。
|
||||||
|
/// </summary>
|
||||||
|
public string EditValue
|
||||||
|
{
|
||||||
|
get { return actualValue ?? string.Empty; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
actualValue = value ?? string.Empty;
|
||||||
|
RefreshDisplayText();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// BaseUserControl 的 EditText 仍用于常规赋值入口;读取时返回界面显示文本,
|
||||||
|
/// MyControl.GetControlValue 对 173/174 会显式读取 EditValue。
|
||||||
|
/// </summary>
|
||||||
|
public override string EditText
|
||||||
|
{
|
||||||
|
get { return popupEdit.Text ?? string.Empty; }
|
||||||
|
set { EditValue = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string LabelText
|
||||||
|
{
|
||||||
|
get { return titleLabel.Text; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
titleLabel.Text = value ?? string.Empty;
|
||||||
|
if (FontSize > 0)
|
||||||
|
{
|
||||||
|
labelPanel.AutoSize = false;
|
||||||
|
titleLabel.AutoSize = false;
|
||||||
|
titleLabel.Dock = DockStyle.Fill;
|
||||||
|
titleLabel.TextAlign = ContentAlignment.MiddleLeft;
|
||||||
|
labelPanel.Width = Math.Max(0, (value ?? string.Empty).Length * GetCharWidth());
|
||||||
|
GetCharWidthMultilingual(titleLabel, titleLabel.Text, labelPanel);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
labelPanel.Width = titleLabel.Width + PaddingLeft;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override float FontSize
|
||||||
|
{
|
||||||
|
get { return base.FontSize; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
base.FontSize = value;
|
||||||
|
if (value <= 0) return;
|
||||||
|
|
||||||
|
titleLabel.Font = new Font(titleLabel.Font.FontFamily, value);
|
||||||
|
popupEdit.Font = new Font(popupEdit.Font.FontFamily, value);
|
||||||
|
popup.ResultView.Appearance.Row.Font = new Font("微软雅黑", value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string NullText
|
||||||
|
{
|
||||||
|
get { return popupEdit.Properties.NullValuePrompt; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
popupEdit.Properties.NullValuePromptShowForEmptyValue = !string.IsNullOrEmpty(value);
|
||||||
|
popupEdit.Properties.NullValuePrompt = value ?? string.Empty;
|
||||||
|
base.NullText = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool ReadOnly
|
||||||
|
{
|
||||||
|
get { return base.ReadOnly; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
base.ReadOnly = value;
|
||||||
|
popupEdit.Properties.ReadOnly = value;
|
||||||
|
titleLabel.ForeColor = value
|
||||||
|
? ReadOnlyLabelForceColor
|
||||||
|
: Required ? RequiredLabelForceColor : DefaultLabelForceColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Required
|
||||||
|
{
|
||||||
|
get { return base.Required; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
base.Required = value;
|
||||||
|
if (value) titleLabel.ForeColor = RequiredLabelForceColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Color BackgroundColor
|
||||||
|
{
|
||||||
|
get { return popupEdit.Properties.Appearance.BackColor; }
|
||||||
|
set { popupEdit.Properties.Appearance.BackColor = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Color ForeColor
|
||||||
|
{
|
||||||
|
get { return popupEdit.Properties.Appearance.ForeColor; }
|
||||||
|
set { popupEdit.Properties.Appearance.ForeColor = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool ContentBold
|
||||||
|
{
|
||||||
|
get { return popupEdit.Properties.Appearance.Font.Bold; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Font oldFont = popupEdit.Properties.Appearance.Font;
|
||||||
|
popupEdit.Properties.Appearance.Font = new Font(
|
||||||
|
oldFont.FontFamily,
|
||||||
|
oldFont.Size,
|
||||||
|
value ? FontStyle.Bold : FontStyle.Regular);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool IsEmpty()
|
||||||
|
{
|
||||||
|
return Model != null && Model.IsEmpty && string.IsNullOrWhiteSpace(EditValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool IsUpdate()
|
||||||
|
{
|
||||||
|
return Model == null || Model.Text == null ||
|
||||||
|
!Model.Text.Equals(EditValue, StringComparison.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 从 ResultFields 中 TextMember 对应的业务控件读取预存显示文本。
|
||||||
|
/// </summary>
|
||||||
|
public void RefreshDisplayText()
|
||||||
|
{
|
||||||
|
string displayText = string.Empty;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string displayField = GetDisplayTargetField();
|
||||||
|
if (ControlObj != null && !string.IsNullOrWhiteSpace(displayField))
|
||||||
|
{
|
||||||
|
BaseUserControl displayControl = ControlObj.FindControl(displayField);
|
||||||
|
if (displayControl != null && !object.ReferenceEquals(displayControl, this))
|
||||||
|
{
|
||||||
|
displayText = displayControl.EditText ?? string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// 初始化配置尚未完整时保持为空,弹出时再给出明确配置错误。
|
||||||
|
}
|
||||||
|
popupEdit.EditValue = displayText;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PopupEdit_QueryPopUp(object sender, System.ComponentModel.CancelEventArgs e)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ValidateBusinessConfiguration();
|
||||||
|
Size popupSize = GetPopupSize();
|
||||||
|
popup.Size = popupSize;
|
||||||
|
popupControl.Size = popupSize;
|
||||||
|
popupEdit.Properties.PopupFormSize = popupSize;
|
||||||
|
popupEdit.Properties.PopupFormMinSize = popupSize;
|
||||||
|
popup.PrepareForOpen();
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(EditValue))
|
||||||
|
{
|
||||||
|
StartSearch(EditValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CancelSearch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
e.Cancel = true;
|
||||||
|
MessageUtil.Show("扩展搜索配置错误:" + ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PopupEdit_Popup(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
popup.BeginInvoke(new MethodInvoker(popup.FocusSearchEditor));
|
||||||
|
}
|
||||||
|
catch (ObjectDisposedException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
catch (InvalidOperationException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PopupEdit_Closed(object sender, ClosedEventArgs e)
|
||||||
|
{
|
||||||
|
CancelSearch();
|
||||||
|
popup.ResultGrid.DataSource = null;
|
||||||
|
RefreshDisplayText();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Popup_SearchRequested(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ValidateBusinessConfiguration();
|
||||||
|
string keyword = popup.SearchText;
|
||||||
|
if (string.IsNullOrWhiteSpace(keyword))
|
||||||
|
{
|
||||||
|
CancelSearch();
|
||||||
|
popup.ResultGrid.DataSource = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
StartSearch(keyword);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageUtil.Show("扩展搜索配置错误:" + ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Popup_ClearRequested(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IList<ExtendedReturnFieldMapping> mappings = ValidateClearConfiguration();
|
||||||
|
List<KeyValuePair<string, object>> values =
|
||||||
|
new List<KeyValuePair<string, object>>();
|
||||||
|
HashSet<string> targetFields =
|
||||||
|
new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
values.Add(new KeyValuePair<string, object>(Model.FieldName, string.Empty));
|
||||||
|
targetFields.Add(Model.FieldName);
|
||||||
|
foreach (ExtendedReturnFieldMapping mapping in mappings)
|
||||||
|
{
|
||||||
|
if (targetFields.Add(mapping.TargetField))
|
||||||
|
{
|
||||||
|
values.Add(new KeyValuePair<string, object>(
|
||||||
|
mapping.TargetField,
|
||||||
|
string.Empty));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ControlObj.ApplyExtendedReturnValues(values);
|
||||||
|
popupEdit.ClosePopup();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageUtil.Show("扩展搜索清空失败:" + ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Popup_ResultSelected(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
DataRow selectedRow = popup.ResultView.GetFocusedDataRow();
|
||||||
|
if (selectedRow == null) return;
|
||||||
|
|
||||||
|
IList<ExtendedReturnFieldMapping> mappings = ValidateBusinessConfiguration();
|
||||||
|
ValidateSourceColumns(selectedRow.Table.Columns, mappings);
|
||||||
|
|
||||||
|
List<KeyValuePair<string, object>> values = new List<KeyValuePair<string, object>>();
|
||||||
|
foreach (ExtendedReturnFieldMapping mapping in mappings)
|
||||||
|
{
|
||||||
|
KeyValuePair<string, object> mappedValue = new KeyValuePair<string, object>(
|
||||||
|
mapping.TargetField,
|
||||||
|
selectedRow[mapping.SourceField]);
|
||||||
|
if (string.Equals(mapping.TargetField, Model.FieldName, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
values.Insert(0, mappedValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
values.Add(mappedValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool containsActualField = mappings.Any(item =>
|
||||||
|
string.Equals(item.TargetField, Model.FieldName, StringComparison.OrdinalIgnoreCase));
|
||||||
|
if (!containsActualField)
|
||||||
|
{
|
||||||
|
values.Insert(0, new KeyValuePair<string, object>(
|
||||||
|
Model.FieldName,
|
||||||
|
selectedRow[Model.ValueMember]));
|
||||||
|
}
|
||||||
|
|
||||||
|
ApplyValues(values);
|
||||||
|
RefreshDisplayText();
|
||||||
|
popupEdit.ClosePopup();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageUtil.Show("扩展搜索返回值失败:" + ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyValues(IList<KeyValuePair<string, object>> values)
|
||||||
|
{
|
||||||
|
ControlObj.ApplyExtendedReturnValues(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IList<ExtendedReturnFieldMapping> ValidateClearConfiguration()
|
||||||
|
{
|
||||||
|
if (Model == null) throw new InvalidOperationException("扩展返回控件配置不存在。");
|
||||||
|
if (ControlObj == null) throw new InvalidOperationException("扩展返回控件未关联 MyControl。");
|
||||||
|
|
||||||
|
IList<ExtendedReturnFieldMapping> mappings =
|
||||||
|
ExtendedReturnSupport.ParseResultFields(Model.ResultFields);
|
||||||
|
if (mappings.Count == 0)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("resultfields 不能为空。");
|
||||||
|
}
|
||||||
|
if (ControlObj.FindControl(Model.FieldName) == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(
|
||||||
|
string.Format("MyControl 中不存在业务控件“{0}”。", Model.FieldName));
|
||||||
|
}
|
||||||
|
foreach (ExtendedReturnFieldMapping mapping in mappings)
|
||||||
|
{
|
||||||
|
if (ControlObj.FindControl(mapping.TargetField) == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(
|
||||||
|
string.Format("MyControl 中不存在业务控件“{0}”。", mapping.TargetField));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mappings;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IList<ExtendedReturnFieldMapping> ValidateBusinessConfiguration()
|
||||||
|
{
|
||||||
|
if (Model == null) throw new InvalidOperationException("扩展返回控件配置不存在。");
|
||||||
|
if (ControlObj == null) throw new InvalidOperationException("扩展返回控件未关联 MyControl。");
|
||||||
|
if (Model.FieldType == ControlType.LabModuleSelectReturnIdExtended)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(Model.AddModuleId))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("扩展模块搜索的模块编号不能为空。");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (string.IsNullOrWhiteSpace(Model.SourceSql))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("搜索数据源 SQL 不能为空。");
|
||||||
|
}
|
||||||
|
if (string.IsNullOrWhiteSpace(Model.ValueMember))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("fieldsqlid 不能为空。");
|
||||||
|
}
|
||||||
|
if (string.IsNullOrWhiteSpace(Model.TextMember))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("fieldsqlname 不能为空。");
|
||||||
|
}
|
||||||
|
if (string.Equals(Model.ValueMember, Model.TextMember, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("fieldsqlid 与 fieldsqlname 必须配置为不同的返回列。");
|
||||||
|
}
|
||||||
|
|
||||||
|
IList<ExtendedReturnFieldMapping> mappings = ExtendedReturnSupport.ParseResultFields(Model.ResultFields);
|
||||||
|
if (mappings.Count == 0)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("resultfields 不能为空。");
|
||||||
|
}
|
||||||
|
|
||||||
|
int displayMappingCount = mappings.Count(item =>
|
||||||
|
string.Equals(item.SourceField, Model.TextMember, StringComparison.OrdinalIgnoreCase));
|
||||||
|
if (displayMappingCount == 0)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(
|
||||||
|
string.Format("resultfields 未配置显示字段“{0}”的业务控件映射。", Model.TextMember));
|
||||||
|
}
|
||||||
|
if (displayMappingCount > 1)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(
|
||||||
|
string.Format("resultfields 中显示字段“{0}”只能映射到一个业务控件。", Model.TextMember));
|
||||||
|
}
|
||||||
|
|
||||||
|
ExtendedReturnFieldMapping actualMapping = mappings.FirstOrDefault(item =>
|
||||||
|
string.Equals(item.TargetField, Model.FieldName, StringComparison.OrdinalIgnoreCase));
|
||||||
|
if (actualMapping != null &&
|
||||||
|
!string.Equals(actualMapping.SourceField, Model.ValueMember, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(
|
||||||
|
string.Format("实际值控件“{0}”必须映射到 fieldsqlid 指定的返回列“{1}”。",
|
||||||
|
Model.FieldName,
|
||||||
|
Model.ValueMember));
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (ExtendedReturnFieldMapping mapping in mappings)
|
||||||
|
{
|
||||||
|
if (ControlObj.FindControl(mapping.TargetField) == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(
|
||||||
|
string.Format("MyControl 中不存在业务控件“{0}”。", mapping.TargetField));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mappings;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ValidateSourceColumns(
|
||||||
|
DataColumnCollection columns,
|
||||||
|
IEnumerable<ExtendedReturnFieldMapping> mappings)
|
||||||
|
{
|
||||||
|
if (columns == null || columns.Count == 0)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("扩展搜索数据源没有返回任何列。");
|
||||||
|
}
|
||||||
|
if (!columns.Contains(Model.ValueMember))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(
|
||||||
|
string.Format("返回数据不存在值字段“{0}”。", Model.ValueMember));
|
||||||
|
}
|
||||||
|
if (!columns.Contains(Model.TextMember))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(
|
||||||
|
string.Format("返回数据不存在显示字段“{0}”。", Model.TextMember));
|
||||||
|
}
|
||||||
|
foreach (ExtendedReturnFieldMapping mapping in mappings)
|
||||||
|
{
|
||||||
|
if (!columns.Contains(mapping.SourceField))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(
|
||||||
|
string.Format("返回数据不存在映射源字段“{0}”。", mapping.SourceField));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetDisplayTargetField()
|
||||||
|
{
|
||||||
|
if (Model == null) return string.Empty;
|
||||||
|
IList<ExtendedReturnFieldMapping> mappings = ExtendedReturnSupport.ParseResultFields(Model.ResultFields);
|
||||||
|
return ExtendedReturnSupport.FindTargetField(mappings, Model.TextMember);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Size GetPopupSize()
|
||||||
|
{
|
||||||
|
int width = Model != null && Model.LookUpWidth > 0
|
||||||
|
? Model.LookUpWidth
|
||||||
|
: DefaultPopupWidth;
|
||||||
|
width = Math.Max(width, MinimumPopupWidth);
|
||||||
|
return new Size(width, DefaultPopupHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string BuildSourceSql()
|
||||||
|
{
|
||||||
|
string sourceSql = GetBaseSourceSql();
|
||||||
|
if (ControlObj != null)
|
||||||
|
{
|
||||||
|
sourceSql = ControlObj.ReplaceControlValue(sourceSql);
|
||||||
|
}
|
||||||
|
sourceSql = BaseImpl.GetDefaultValue(sourceSql);
|
||||||
|
return ReplaceHelper.ReplaceParam(sourceSql);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetBaseSourceSql()
|
||||||
|
{
|
||||||
|
if (Model == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("扩展返回控件配置不存在。");
|
||||||
|
}
|
||||||
|
if (Model.FieldType == ControlType.LabModuleSelectReturnIdExtended)
|
||||||
|
{
|
||||||
|
if (ControlObj == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("扩展返回控件未关联 MyControl。");
|
||||||
|
}
|
||||||
|
return ControlObj.ResolveExtendedReturnModuleSourceSql(Model.AddModuleId);
|
||||||
|
}
|
||||||
|
if (string.IsNullOrWhiteSpace(Model.SourceSql))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("搜索数据源 SQL 不能为空。");
|
||||||
|
}
|
||||||
|
return Model.SourceSql;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StartSearch(string keyword)
|
||||||
|
{
|
||||||
|
SearchRequest request = new SearchRequest();
|
||||||
|
request.Version = Interlocked.Increment(ref queryVersion);
|
||||||
|
request.SourceSql = BuildSourceSql();
|
||||||
|
request.Keyword = keyword;
|
||||||
|
request.ConnectionString = SqlHelper._connection.ConnectionString;
|
||||||
|
|
||||||
|
bool startWorker = false;
|
||||||
|
lock (querySyncRoot)
|
||||||
|
{
|
||||||
|
pendingSearch = request;
|
||||||
|
if (!queryWorkerRunning)
|
||||||
|
{
|
||||||
|
queryWorkerRunning = true;
|
||||||
|
startWorker = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (startWorker)
|
||||||
|
{
|
||||||
|
ThreadPool.QueueUserWorkItem(ProcessSearchQueue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ProcessSearchQueue(object state)
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
SearchRequest request;
|
||||||
|
lock (querySyncRoot)
|
||||||
|
{
|
||||||
|
request = pendingSearch;
|
||||||
|
pendingSearch = null;
|
||||||
|
if (request == null)
|
||||||
|
{
|
||||||
|
queryWorkerRunning = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryResult result = Query(
|
||||||
|
request.SourceSql,
|
||||||
|
request.Keyword,
|
||||||
|
request.ConnectionString);
|
||||||
|
DeliverResult(request.Version, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private QueryResult Query(string sourceSql, string keyword, string connectionString)
|
||||||
|
{
|
||||||
|
QueryResult result = new QueryResult();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
DataTable sourceSchema = GetSchema(sourceSql, connectionString);
|
||||||
|
IList<ExtendedReturnFieldMapping> mappings = ExtendedReturnSupport.ParseResultFields(Model.ResultFields);
|
||||||
|
ValidateSourceColumns(sourceSchema.Columns, mappings);
|
||||||
|
string searchSql = ExtendedReturnSupport.BuildSearchSql(sourceSql, sourceSchema.Columns, MaxRows);
|
||||||
|
result.Table = ExecuteQuery(
|
||||||
|
searchSql,
|
||||||
|
ExtendedReturnSupport.BuildLikeParameterValue(keyword),
|
||||||
|
connectionString);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
result.Error = ex;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private DataTable GetSchema(string sourceSql, string connectionString)
|
||||||
|
{
|
||||||
|
lock (schemaSyncRoot)
|
||||||
|
{
|
||||||
|
if (schema != null && string.Equals(schemaSql, sourceSql, StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
return schema;
|
||||||
|
}
|
||||||
|
|
||||||
|
schema = ExecuteQuery(ExtendedReturnSupport.BuildStructureSql(sourceSql), null, connectionString);
|
||||||
|
schemaSql = sourceSql;
|
||||||
|
return schema;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static DataTable ExecuteQuery(
|
||||||
|
string commandText,
|
||||||
|
string keywordParameterValue,
|
||||||
|
string connectionString)
|
||||||
|
{
|
||||||
|
DataTable table = new DataTable();
|
||||||
|
using (DbConnection connection = SqlHelper.dbFactory.CreateConnection())
|
||||||
|
using (DbCommand command = SqlHelper.dbFactory.CreateCommand())
|
||||||
|
using (DbDataAdapter adapter = SqlHelper.dbFactory.CreateDataAdapter())
|
||||||
|
{
|
||||||
|
connection.ConnectionString = connectionString;
|
||||||
|
command.Connection = connection;
|
||||||
|
command.CommandText = commandText;
|
||||||
|
command.CommandType = CommandType.Text;
|
||||||
|
command.CommandTimeout = SqlHelper.CommandTimeout;
|
||||||
|
|
||||||
|
if (keywordParameterValue != null)
|
||||||
|
{
|
||||||
|
DbParameter parameter = SqlHelper.dbFactory.CreateParameter();
|
||||||
|
parameter.ParameterName = ExtendedReturnSupport.SearchParameterName;
|
||||||
|
parameter.DbType = DbType.String;
|
||||||
|
parameter.Size = 4000;
|
||||||
|
parameter.Value = keywordParameterValue;
|
||||||
|
command.Parameters.Add(parameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
adapter.SelectCommand = command;
|
||||||
|
connection.Open();
|
||||||
|
adapter.Fill(table);
|
||||||
|
}
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DeliverResult(int version, QueryResult result)
|
||||||
|
{
|
||||||
|
if (disposed || !IsHandleCreated) return;
|
||||||
|
|
||||||
|
MethodInvoker deliver = new MethodInvoker(delegate
|
||||||
|
{
|
||||||
|
if (disposed || IsDisposed || version != queryVersion || !popupEdit.IsPopupOpen) return;
|
||||||
|
if (result.Error != null)
|
||||||
|
{
|
||||||
|
MessageUtil.Show("扩展搜索查询失败:" + result.Error.Message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
popup.ResultGrid.DataSource = result.Table;
|
||||||
|
ConfigureResultColumns(result.Table);
|
||||||
|
});
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
BeginInvoke(deliver);
|
||||||
|
}
|
||||||
|
catch (ObjectDisposedException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
catch (InvalidOperationException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ConfigureResultColumns(DataTable table)
|
||||||
|
{
|
||||||
|
if (table == null) return;
|
||||||
|
|
||||||
|
IList<ExtendedReturnFieldMapping> mappings = ExtendedReturnSupport.ParseResultFields(Model.ResultFields);
|
||||||
|
popup.ResultView.Columns.Clear();
|
||||||
|
foreach (DataColumn dataColumn in table.Columns)
|
||||||
|
{
|
||||||
|
GridColumn column = new GridColumn();
|
||||||
|
column.Name = column.FieldName = dataColumn.ColumnName;
|
||||||
|
column.Caption = GetColumnCaption(dataColumn.ColumnName, mappings);
|
||||||
|
column.Visible = !dataColumn.ColumnName.StartsWith("_", StringComparison.Ordinal);
|
||||||
|
popup.ResultView.Columns.Add(column);
|
||||||
|
}
|
||||||
|
|
||||||
|
string[] configuredWidths = string.IsNullOrWhiteSpace(Model.LookUpFieldsWidth)
|
||||||
|
? null
|
||||||
|
: Model.LookUpFieldsWidth.Trim().TrimEnd(',').Split(',');
|
||||||
|
int visibleIndex = 0;
|
||||||
|
foreach (GridColumn column in popup.ResultView.Columns)
|
||||||
|
{
|
||||||
|
if (!column.Visible) continue;
|
||||||
|
|
||||||
|
int width;
|
||||||
|
if (configuredWidths != null && visibleIndex < configuredWidths.Length &&
|
||||||
|
int.TryParse(configuredWidths[visibleIndex], out width))
|
||||||
|
{
|
||||||
|
column.Width = width;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int captionWidth = GraphicsText.GetTextWidth(column.Caption);
|
||||||
|
int valueWidth = CalcMaxColumnWidth(table, column.FieldName);
|
||||||
|
column.Width = Math.Max(captionWidth, valueWidth);
|
||||||
|
}
|
||||||
|
visibleIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetColumnCaption(
|
||||||
|
string sourceField,
|
||||||
|
IEnumerable<ExtendedReturnFieldMapping> mappings)
|
||||||
|
{
|
||||||
|
string targetField = ExtendedReturnSupport.FindTargetField(mappings, sourceField);
|
||||||
|
if (string.IsNullOrWhiteSpace(targetField)) return sourceField;
|
||||||
|
|
||||||
|
BaseUserControl targetControl = ControlObj.FindControl(targetField);
|
||||||
|
if (targetControl != null && !string.IsNullOrWhiteSpace(targetControl.LabelText))
|
||||||
|
{
|
||||||
|
return targetControl.LabelText;
|
||||||
|
}
|
||||||
|
return targetField;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int CalcMaxColumnWidth(DataTable table, string fieldName)
|
||||||
|
{
|
||||||
|
int maxWidth = 0;
|
||||||
|
foreach (DataRow row in table.Rows)
|
||||||
|
{
|
||||||
|
object value = row[fieldName];
|
||||||
|
int width = GraphicsText.GetTextWidth(
|
||||||
|
value == null || value == DBNull.Value ? string.Empty : value + string.Empty);
|
||||||
|
if (width > maxWidth) maxWidth = width;
|
||||||
|
}
|
||||||
|
return maxWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CancelSearch()
|
||||||
|
{
|
||||||
|
Interlocked.Increment(ref queryVersion);
|
||||||
|
lock (querySyncRoot)
|
||||||
|
{
|
||||||
|
pendingSearch = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LabelExtendedReturnSearchEdit_Disposed(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
disposed = true;
|
||||||
|
CancelSearch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -192,30 +192,6 @@ namespace Lskj.Control
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public Dictionary<GridColumnModel, Task<DataTable>> mControlSourceDic = new Dictionary<GridColumnModel, Task<DataTable>>();
|
public Dictionary<GridColumnModel, Task<DataTable>> mControlSourceDic = new Dictionary<GridColumnModel, Task<DataTable>>();
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 字典搜索框数据源缓存,只用于弹出下拉框时临时绑定,避免表格滚动时控件持有大数据源。
|
|
||||||
/// </summary>
|
|
||||||
private Dictionary<string, DataTable> mSpecialReturnSourceDic = new Dictionary<string, DataTable>();
|
|
||||||
/// <summary>
|
|
||||||
/// 字典搜索框后台加载任务缓存。
|
|
||||||
/// </summary>
|
|
||||||
private Dictionary<string, Task<DataTable>> mSpecialReturnSourceTaskDic = new Dictionary<string, Task<DataTable>>();
|
|
||||||
/// <summary>
|
|
||||||
/// 字典搜索框显示文本缓存,表格显示时按单元格值快速转换为显示文本。
|
|
||||||
/// </summary>
|
|
||||||
private Dictionary<string, Dictionary<string, string>> mSpecialReturnDisplayDic = new Dictionary<string, Dictionary<string, string>>();
|
|
||||||
/// <summary>
|
|
||||||
/// 字典搜索框编辑器缓存,进入编辑状态时再替换为搜索框控件。
|
|
||||||
/// </summary>
|
|
||||||
private Dictionary<string, RepositoryItemGridLookUpEdit> mSpecialReturnEditDic = new Dictionary<string, RepositoryItemGridLookUpEdit>();
|
|
||||||
/// <summary>
|
|
||||||
/// 字典搜索框显示文本事件是否已绑定。
|
|
||||||
/// </summary>
|
|
||||||
private bool mSpecialReturnDisplayEventAttached = false;
|
|
||||||
/// <summary>
|
|
||||||
/// 字典搜索框编辑器替换事件是否已绑定。
|
|
||||||
/// </summary>
|
|
||||||
private bool mSpecialReturnEditEventAttached = false;
|
|
||||||
/// <summary>
|
|
||||||
/// 计算值
|
/// 计算值
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public decimal customSum;
|
public decimal customSum;
|
||||||
@@ -1019,7 +995,7 @@ namespace Lskj.Control
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(model.SqlSource) && !ControlType.IsNotLoadData(model.FieldType) && !IsSpecialReturnBox(model.FieldType))
|
if (!string.IsNullOrEmpty(model.SqlSource) && !ControlType.IsNotLoadData(model.FieldType))
|
||||||
{
|
{
|
||||||
Task<DataTable> sourceTask = new Task<DataTable>(() =>
|
Task<DataTable> sourceTask = new Task<DataTable>(() =>
|
||||||
{
|
{
|
||||||
@@ -1215,11 +1191,9 @@ namespace Lskj.Control
|
|||||||
case ControlType.LabModuleAddRowsText:
|
case ControlType.LabModuleAddRowsText:
|
||||||
InitModuleReturnLine(column, model);
|
InitModuleReturnLine(column, model);
|
||||||
break;
|
break;
|
||||||
case ControlType.DictionarySearchBoxToId:
|
case ControlType.LabModuleSelectReturnIdExtended:
|
||||||
case ControlType.DictionarySearchBoxToText:
|
case ControlType.LabSearchReturnIdExtended:
|
||||||
case ControlType.DictionarySearchBoxToIdParam:
|
InitExtendedReturn(column, model);
|
||||||
case ControlType.DictionarySearchBoxToTextParam:
|
|
||||||
InitSpecialReturn(column, model);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -1231,569 +1205,6 @@ namespace Lskj.Control
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 初始化字典搜索框。表格显示阶段使用文本编辑器,进入编辑状态时再切换为搜索框。
|
|
||||||
/// </summary>
|
|
||||||
private void InitSpecialReturn(GridColumn column, GridColumnModel model)
|
|
||||||
{
|
|
||||||
RepositoryItemGridLookUpEdit searchEdit = CreateSpecialReturnSearchEdit(model);
|
|
||||||
RepositoryItemTextEdit textEdit = new RepositoryItemTextEdit();
|
|
||||||
|
|
||||||
gridControl.RepositoryItems.Add(textEdit);
|
|
||||||
gridControl.RepositoryItems.Add(searchEdit);
|
|
||||||
column.ColumnEdit = textEdit;
|
|
||||||
|
|
||||||
mSpecialReturnEditDic[model.FieldName] = searchEdit;
|
|
||||||
this.mControlList.Add(model);
|
|
||||||
StartSpecialReturnSourceTask(model);
|
|
||||||
|
|
||||||
if (!mSpecialReturnDisplayEventAttached)
|
|
||||||
{
|
|
||||||
this.gridView.CustomColumnDisplayText += GridView_CustomColumnDisplayText_SpecialReturn;
|
|
||||||
mSpecialReturnDisplayEventAttached = true;
|
|
||||||
}
|
|
||||||
if (!mSpecialReturnEditEventAttached)
|
|
||||||
{
|
|
||||||
this.gridView.CustomRowCellEditForEditing += GridView_CustomRowCellEditForEditing_SpecialReturn;
|
|
||||||
mSpecialReturnEditEventAttached = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 判断是否为字典搜索框类型。
|
|
||||||
/// </summary>
|
|
||||||
private static bool IsSpecialReturnBox(int fieldType)
|
|
||||||
{
|
|
||||||
return fieldType == ControlType.DictionarySearchBoxToId
|
|
||||||
|| fieldType == ControlType.DictionarySearchBoxToText
|
|
||||||
|| fieldType == ControlType.DictionarySearchBoxToIdParam
|
|
||||||
|| fieldType == ControlType.DictionarySearchBoxToTextParam;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 判断字典搜索框是否保存显示文本。
|
|
||||||
/// </summary>
|
|
||||||
private static bool IsSpecialReturnTextBox(int fieldType)
|
|
||||||
{
|
|
||||||
return fieldType == ControlType.DictionarySearchBoxToText
|
|
||||||
|| fieldType == ControlType.DictionarySearchBoxToTextParam;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 判断字典搜索框是否为带参数类型。
|
|
||||||
/// </summary>
|
|
||||||
private static bool IsSpecialReturnParamBox(int fieldType)
|
|
||||||
{
|
|
||||||
return fieldType == ControlType.DictionarySearchBoxToIdParam
|
|
||||||
|| fieldType == ControlType.DictionarySearchBoxToTextParam;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建字典搜索框编辑器。
|
|
||||||
/// </summary>
|
|
||||||
private RepositoryItemGridLookUpEdit CreateSpecialReturnSearchEdit(GridColumnModel model)
|
|
||||||
{
|
|
||||||
RepositoryItemGridLookUpEdit searchEdit = new RepositoryItemGridLookUpEdit();
|
|
||||||
if (model.FontSize > 0) searchEdit.View.Appearance.Row.Font = new Font("微软雅黑", model.FontSize);
|
|
||||||
searchEdit.View.OptionsView.ShowIndicator = false;
|
|
||||||
searchEdit.View.OptionsView.ColumnAutoWidth = false;
|
|
||||||
searchEdit.PopupSizeable = true;
|
|
||||||
searchEdit.PopupResizeMode = ResizeMode.Default;
|
|
||||||
searchEdit.AllowFocused = true;
|
|
||||||
searchEdit.ImmediatePopup = true;
|
|
||||||
searchEdit.ShowFooter = false;
|
|
||||||
searchEdit.NullText = "";
|
|
||||||
searchEdit.TextEditStyle = TextEditStyles.Standard;
|
|
||||||
searchEdit.PopupBorderStyle = PopupBorderStyles.Flat;
|
|
||||||
searchEdit.AllowNullInput = DefaultBoolean.False;
|
|
||||||
searchEdit.ShowPopupShadow = true;
|
|
||||||
searchEdit.DisplayMember = model.TextMember;
|
|
||||||
searchEdit.ValueMember = IsSpecialReturnTextBox(model.FieldType) ? model.TextMember : model.ValueMember;
|
|
||||||
searchEdit.Tag = model;
|
|
||||||
searchEdit.View.Tag = searchEdit;
|
|
||||||
searchEdit.View.Appearance.HeaderPanel.TextOptions.HAlignment = HorzAlignment.Center;
|
|
||||||
searchEdit.View.PopupMenuShowing += new PopupMenuShowingEventHandler(OnAutoSearchEditPopupMenuShowing);
|
|
||||||
searchEdit.KeyDown += OnsearchEditKeyDown;
|
|
||||||
searchEdit.QueryPopUp += SpecialReturnEdit_QueryPopUp;
|
|
||||||
searchEdit.CloseUp += SpecialReturnEdit_CloseUp;
|
|
||||||
searchEdit.Closed += SpecialReturnEdit_Closed;
|
|
||||||
searchEdit.CustomDisplayText += SpecialReturnEdit_CustomDisplayText;
|
|
||||||
searchEdit.EditValueChanging += gridLookUpEdit1_EditValueChanging;
|
|
||||||
searchEdit.View.CustomDrawFilterPanel += OnCustomDrawFilterPanel;
|
|
||||||
|
|
||||||
GridColumn valueColumn = new GridColumn();
|
|
||||||
valueColumn.Name = valueColumn.FieldName = model.ValueMember;
|
|
||||||
valueColumn.Caption = "编码";
|
|
||||||
valueColumn.Visible = model.ValueMember.Substring(0, 1) != "_";
|
|
||||||
|
|
||||||
GridColumn textColumn = new GridColumn();
|
|
||||||
textColumn.Name = textColumn.FieldName = model.TextMember;
|
|
||||||
textColumn.Caption = "名称";
|
|
||||||
textColumn.Visible = model.TextMember.Substring(0, 1) != "_";
|
|
||||||
|
|
||||||
searchEdit.View.Columns.AddRange(new GridColumn[] { valueColumn, textColumn });
|
|
||||||
return searchEdit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 字典搜索框显示文本事件,表格滚动显示时只查字典,不绑定下拉框大数据源。
|
|
||||||
/// </summary>
|
|
||||||
private void GridView_CustomColumnDisplayText_SpecialReturn(object sender, CustomColumnDisplayTextEventArgs e)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
GridColumnModel model = e.Column.Tag as GridColumnModel;
|
|
||||||
if (model == null || !IsSpecialReturnBox(model.FieldType)) return;
|
|
||||||
|
|
||||||
string value = e.Value + "";
|
|
||||||
if (string.IsNullOrWhiteSpace(value)) return;
|
|
||||||
|
|
||||||
string displayText = string.Empty;
|
|
||||||
bool sourceReady = EnsureSpecialReturnSourceReady(model);
|
|
||||||
if (TryGetSpecialReturnDisplayText(model, value, out displayText))
|
|
||||||
{
|
|
||||||
e.DisplayText = displayText;
|
|
||||||
}
|
|
||||||
else if (sourceReady)
|
|
||||||
{
|
|
||||||
e.DisplayText = string.Empty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 字典搜索框编辑器替换事件,只有进入编辑状态时才使用搜索框控件。
|
|
||||||
/// </summary>
|
|
||||||
private void GridView_CustomRowCellEditForEditing_SpecialReturn(object sender, CustomRowCellEditEventArgs e)
|
|
||||||
{
|
|
||||||
GridColumnModel model = e.Column.Tag as GridColumnModel;
|
|
||||||
if (model == null || !IsSpecialReturnBox(model.FieldType)) return;
|
|
||||||
if (mSpecialReturnEditDic.ContainsKey(model.FieldName))
|
|
||||||
{
|
|
||||||
RepositoryItemGridLookUpEdit searchEdit = mSpecialReturnEditDic[model.FieldName];
|
|
||||||
BindSpecialReturnCurrentValue(searchEdit, model, this.gridView.GetRowCellValue(e.RowHandle, e.Column));
|
|
||||||
e.RepositoryItem = searchEdit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 字典搜索框编辑态显示文本事件,避免编辑器未绑定数据源时当前值显示为空。
|
|
||||||
/// </summary>
|
|
||||||
private void SpecialReturnEdit_CustomDisplayText(object sender, CustomDisplayTextEventArgs e)
|
|
||||||
{
|
|
||||||
RepositoryItemGridLookUpEdit edit = sender as RepositoryItemGridLookUpEdit;
|
|
||||||
if (edit == null || e.Value == null) return;
|
|
||||||
|
|
||||||
GridColumnModel model = edit.Tag as GridColumnModel;
|
|
||||||
if (model == null || !IsSpecialReturnBox(model.FieldType)) return;
|
|
||||||
|
|
||||||
string value = e.Value + "";
|
|
||||||
if (string.IsNullOrWhiteSpace(value)) return;
|
|
||||||
|
|
||||||
string displayText = string.Empty;
|
|
||||||
bool sourceReady = EnsureSpecialReturnSourceReady(model);
|
|
||||||
if (TryGetSpecialReturnDisplayText(model, value, out displayText))
|
|
||||||
{
|
|
||||||
e.DisplayText = displayText;
|
|
||||||
}
|
|
||||||
else if (sourceReady)
|
|
||||||
{
|
|
||||||
e.DisplayText = string.Empty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 字典搜索框弹出事件。普通类型使用缓存数据源,带参数类型按当前行条件重新查询。
|
|
||||||
/// </summary>
|
|
||||||
private void SpecialReturnEdit_QueryPopUp(object sender, CancelEventArgs e)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
GridLookUpEdit edit = sender as GridLookUpEdit;
|
|
||||||
if (edit == null) return;
|
|
||||||
GridColumnModel model = edit.Properties.Tag as GridColumnModel;
|
|
||||||
if (model == null) return;
|
|
||||||
|
|
||||||
CurrentOperColumnKey = Model.ModuleCode + "_" + model.FieldName;
|
|
||||||
CurrentOperModel = model;
|
|
||||||
|
|
||||||
DataTable table = IsSpecialReturnParamBox(model.FieldType) ? GetSpecialReturnParamSourceTable(model) : GetSpecialReturnSourceTable(model);
|
|
||||||
if (IsSpecialReturnParamBox(model.FieldType))
|
|
||||||
{
|
|
||||||
AddSpecialReturnManualData(model, table);
|
|
||||||
}
|
|
||||||
edit.Properties.DataSource = table;
|
|
||||||
AddSpecialReturnViewColumns(edit.Properties, table, model);
|
|
||||||
SetSpecialReturnPopupWidth(edit.Properties, table, model);
|
|
||||||
CacheSpecialReturnDisplayValues(model, table);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
string Message = ErrorMessage.PromptErrorMessage(ex, Model.ModuleCode);
|
|
||||||
MessageUtil.Show(Message, ex.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 字典搜索框关闭选择事件,把本次选择结果补入显示字典。
|
|
||||||
/// </summary>
|
|
||||||
private void SpecialReturnEdit_CloseUp(object sender, CloseUpEventArgs e)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
GridLookUpEdit edit = sender as GridLookUpEdit;
|
|
||||||
if (edit == null) return;
|
|
||||||
GridColumnModel model = edit.Properties.Tag as GridColumnModel;
|
|
||||||
if (model == null || e.Value == null) return;
|
|
||||||
|
|
||||||
DataTable table = edit.Properties.DataSource as DataTable;
|
|
||||||
if (table == null) return;
|
|
||||||
|
|
||||||
string value = e.Value + "";
|
|
||||||
string valueMember = IsSpecialReturnTextBox(model.FieldType) ? model.TextMember : model.ValueMember;
|
|
||||||
if (!table.Columns.Contains(valueMember) || !table.Columns.Contains(model.TextMember)) return;
|
|
||||||
|
|
||||||
DataRow row = table.Rows.Cast<DataRow>().FirstOrDefault(item => (item[valueMember] + "").Equals(value));
|
|
||||||
if (row != null)
|
|
||||||
{
|
|
||||||
GetSpecialReturnDisplayDic(model)[value] = row[model.TextMember] + "";
|
|
||||||
}
|
|
||||||
|
|
||||||
edit.EditValue = e.Value;
|
|
||||||
GridColumn column = this.gridView.Columns[model.FieldName];
|
|
||||||
if (column != null)
|
|
||||||
{
|
|
||||||
this.gridView.SetFocusedRowCellValue(column, e.Value);
|
|
||||||
}
|
|
||||||
this.gridView.PostEditor();
|
|
||||||
this.gridView.UpdateCurrentRow();
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 字典搜索框关闭后清空临时数据源,避免编辑器长期持有大量数据。
|
|
||||||
/// </summary>
|
|
||||||
private void SpecialReturnEdit_Closed(object sender, ClosedEventArgs e)
|
|
||||||
{
|
|
||||||
GridLookUpEdit edit = sender as GridLookUpEdit;
|
|
||||||
if (edit != null)
|
|
||||||
{
|
|
||||||
edit.Properties.DataSource = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取字典搜索框初始化数据源,用于普通弹出和显示字典缓存。
|
|
||||||
/// </summary>
|
|
||||||
private DataTable GetSpecialReturnSourceTable(GridColumnModel model)
|
|
||||||
{
|
|
||||||
string key = model.FieldName;
|
|
||||||
if (mSpecialReturnSourceDic.ContainsKey(key))
|
|
||||||
{
|
|
||||||
return mSpecialReturnSourceDic[key];
|
|
||||||
}
|
|
||||||
if (mSpecialReturnSourceTaskDic.ContainsKey(key))
|
|
||||||
{
|
|
||||||
DataTable taskTable = mSpecialReturnSourceTaskDic[key].Result;
|
|
||||||
mSpecialReturnSourceDic[key] = taskTable;
|
|
||||||
CacheSpecialReturnDisplayValues(model, taskTable);
|
|
||||||
return taskTable;
|
|
||||||
}
|
|
||||||
|
|
||||||
DataTable table = BaseImpl.GetDataTableResult(model.SqlSource);
|
|
||||||
mSpecialReturnSourceDic[key] = table;
|
|
||||||
CacheSpecialReturnDisplayValues(model, table);
|
|
||||||
return table;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取带参数字典搜索框弹出数据源,逻辑与原带参数搜索框弹出查询保持一致。
|
|
||||||
/// </summary>
|
|
||||||
private DataTable GetSpecialReturnParamSourceTable(GridColumnModel model)
|
|
||||||
{
|
|
||||||
DataRow[] dataRows = this.GetViewFocusedDataRows();
|
|
||||||
DataRow rowItem = dataRows.Count() > 0 ? dataRows[0] : this.gridView.GetFocusedDataRow();
|
|
||||||
if (rowItem == null && this.ParentControl == null)
|
|
||||||
{
|
|
||||||
return GetSpecialReturnSourceTable(model);
|
|
||||||
}
|
|
||||||
|
|
||||||
string sqlValue = model.SqlSource;
|
|
||||||
if (this.ParentControl != null)
|
|
||||||
sqlValue = this.ParentControl.ReplaceParentControlValue(sqlValue);
|
|
||||||
|
|
||||||
sqlValue = sqlValue.Replace("#", "");
|
|
||||||
|
|
||||||
if (rowItem != null)
|
|
||||||
{
|
|
||||||
sqlValue = ReplaceHelper.ReplaceRowParam(rowItem, sqlValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
return MainImpl.GetDataTableResult(sqlValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 带参数字典搜索框保存文本时,把手动新增的数据追加到本次弹出数据源。
|
|
||||||
/// </summary>
|
|
||||||
private void AddSpecialReturnManualData(GridColumnModel model, DataTable table)
|
|
||||||
{
|
|
||||||
if (model == null || table == null || !model.SearchBoxAddition || !IsSpecialReturnTextBox(model.FieldType)) return;
|
|
||||||
if (!this.ManuallyAddData.ContainsKey(model.FieldName)) return;
|
|
||||||
|
|
||||||
List<DataRow> dataRows = this.ManuallyAddData[model.FieldName];
|
|
||||||
foreach (DataRow row in dataRows)
|
|
||||||
{
|
|
||||||
DataRow newrow = table.NewRow();
|
|
||||||
newrow.ItemArray = row.ItemArray;
|
|
||||||
table.Rows.Add(newrow);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 后台加载字典搜索框数据源并建立显示字典。
|
|
||||||
/// </summary>
|
|
||||||
private void StartSpecialReturnSourceTask(GridColumnModel model)
|
|
||||||
{
|
|
||||||
if (model == null || string.IsNullOrWhiteSpace(model.SqlSource) || mSpecialReturnSourceTaskDic.ContainsKey(model.FieldName)) return;
|
|
||||||
|
|
||||||
Task<DataTable> sourceTask = new Task<DataTable>(() =>
|
|
||||||
{
|
|
||||||
return BaseImpl.GetDataTableResult(model.SqlSource);
|
|
||||||
});
|
|
||||||
sourceTask.ContinueWith(task =>
|
|
||||||
{
|
|
||||||
if (task.Status != TaskStatus.RanToCompletion || task.Result == null) return;
|
|
||||||
if (this.IsDisposed || !this.IsHandleCreated) return;
|
|
||||||
this.BeginInvoke(new MethodInvoker(delegate ()
|
|
||||||
{
|
|
||||||
if (this.IsDisposed) return;
|
|
||||||
mSpecialReturnSourceDic[model.FieldName] = task.Result;
|
|
||||||
CacheSpecialReturnDisplayValues(model, task.Result);
|
|
||||||
gridView.Invalidate();
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
mSpecialReturnSourceTaskDic.Add(model.FieldName, sourceTask);
|
|
||||||
sourceTask.Start(DataTableExtend.SchedulerUtil);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取字段对应的显示文本字典。
|
|
||||||
/// </summary>
|
|
||||||
private Dictionary<string, string> GetSpecialReturnDisplayDic(GridColumnModel model)
|
|
||||||
{
|
|
||||||
if (!mSpecialReturnDisplayDic.ContainsKey(model.FieldName))
|
|
||||||
{
|
|
||||||
mSpecialReturnDisplayDic[model.FieldName] = new Dictionary<string, string>();
|
|
||||||
}
|
|
||||||
return mSpecialReturnDisplayDic[model.FieldName];
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 确认字典搜索框数据源是否已加载;后台任务已完成但回调未执行时,在这里补建显示字典。
|
|
||||||
/// </summary>
|
|
||||||
private bool EnsureSpecialReturnSourceReady(GridColumnModel model)
|
|
||||||
{
|
|
||||||
if (model == null) return false;
|
|
||||||
if (mSpecialReturnSourceDic.ContainsKey(model.FieldName)) return true;
|
|
||||||
|
|
||||||
Task<DataTable> sourceTask = null;
|
|
||||||
if (!mSpecialReturnSourceTaskDic.TryGetValue(model.FieldName, out sourceTask)) return false;
|
|
||||||
if (!sourceTask.IsCompleted) return false;
|
|
||||||
|
|
||||||
if (sourceTask.Status == TaskStatus.RanToCompletion && sourceTask.Result != null)
|
|
||||||
{
|
|
||||||
mSpecialReturnSourceDic[model.FieldName] = sourceTask.Result;
|
|
||||||
CacheSpecialReturnDisplayValues(model, sourceTask.Result);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 把数据源中的值和显示文本缓存到字典中。
|
|
||||||
/// </summary>
|
|
||||||
private void CacheSpecialReturnDisplayValues(GridColumnModel model, DataTable table)
|
|
||||||
{
|
|
||||||
if (table == null || !table.Columns.Contains(model.ValueMember) || !table.Columns.Contains(model.TextMember)) return;
|
|
||||||
|
|
||||||
Dictionary<string, string> displayDic = GetSpecialReturnDisplayDic(model);
|
|
||||||
foreach (DataRow row in table.Rows)
|
|
||||||
{
|
|
||||||
string value = IsSpecialReturnTextBox(model.FieldType) ? row[model.TextMember] + "" : row[model.ValueMember] + "";
|
|
||||||
if (!string.IsNullOrWhiteSpace(value) && !displayDic.ContainsKey(value))
|
|
||||||
{
|
|
||||||
displayDic.Add(value, row[model.TextMember] + "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 根据单元格保存值获取显示文本。
|
|
||||||
/// </summary>
|
|
||||||
private string GetSpecialReturnDisplayText(GridColumnModel model, string value)
|
|
||||||
{
|
|
||||||
Dictionary<string, string> displayDic = GetSpecialReturnDisplayDic(model);
|
|
||||||
string[] values = value.Trim(',').Split(',');
|
|
||||||
StringBuilder result = new StringBuilder();
|
|
||||||
foreach (string item in values)
|
|
||||||
{
|
|
||||||
string key = (item + "").Trim();
|
|
||||||
if (string.IsNullOrWhiteSpace(key)) continue;
|
|
||||||
|
|
||||||
string displayText = string.Empty;
|
|
||||||
result.Append(displayDic.TryGetValue(key, out displayText) ? displayText : key);
|
|
||||||
result.Append(",");
|
|
||||||
}
|
|
||||||
return result.ToString().TrimEnd(',');
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 严格按字典获取显示文本,字典中不存在时返回false。
|
|
||||||
/// </summary>
|
|
||||||
private bool TryGetSpecialReturnDisplayText(GridColumnModel model, string value, out string displayText)
|
|
||||||
{
|
|
||||||
displayText = string.Empty;
|
|
||||||
Dictionary<string, string> displayDic = GetSpecialReturnDisplayDic(model);
|
|
||||||
string[] values = value.Trim(',').Split(',');
|
|
||||||
StringBuilder result = new StringBuilder();
|
|
||||||
foreach (string item in values)
|
|
||||||
{
|
|
||||||
string key = (item + "").Trim();
|
|
||||||
if (string.IsNullOrWhiteSpace(key)) continue;
|
|
||||||
|
|
||||||
string itemText = string.Empty;
|
|
||||||
if (!displayDic.TryGetValue(key, out itemText)) return false;
|
|
||||||
|
|
||||||
result.Append(itemText);
|
|
||||||
result.Append(",");
|
|
||||||
}
|
|
||||||
|
|
||||||
displayText = result.ToString().TrimEnd(',');
|
|
||||||
return !string.IsNullOrWhiteSpace(displayText);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 进入编辑态时只给当前有效值绑定一行临时数据,避免未弹出下拉框时显示为空。
|
|
||||||
/// </summary>
|
|
||||||
private void BindSpecialReturnCurrentValue(RepositoryItemGridLookUpEdit searchEdit, GridColumnModel model, object cellValue)
|
|
||||||
{
|
|
||||||
if (searchEdit == null || model == null || cellValue == null) return;
|
|
||||||
|
|
||||||
string value = cellValue + "";
|
|
||||||
if (string.IsNullOrWhiteSpace(value)) return;
|
|
||||||
|
|
||||||
string displayText = string.Empty;
|
|
||||||
bool sourceReady = EnsureSpecialReturnSourceReady(model);
|
|
||||||
if (!TryGetSpecialReturnDisplayText(model, value, out displayText))
|
|
||||||
{
|
|
||||||
if (sourceReady)
|
|
||||||
{
|
|
||||||
searchEdit.DataSource = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
displayText = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
DataTable table = new DataTable();
|
|
||||||
if (!table.Columns.Contains(model.ValueMember)) table.Columns.Add(model.ValueMember);
|
|
||||||
if (!table.Columns.Contains(model.TextMember)) table.Columns.Add(model.TextMember);
|
|
||||||
|
|
||||||
DataRow row = table.NewRow();
|
|
||||||
row[model.ValueMember] = IsSpecialReturnTextBox(model.FieldType) ? displayText : value;
|
|
||||||
row[model.TextMember] = displayText;
|
|
||||||
table.Rows.Add(row);
|
|
||||||
|
|
||||||
searchEdit.DataSource = table;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 根据弹出数据源补充搜索框显示列。
|
|
||||||
/// </summary>
|
|
||||||
private void AddSpecialReturnViewColumns(RepositoryItemGridLookUpEdit searchEdit, DataTable table, GridColumnModel model)
|
|
||||||
{
|
|
||||||
if (searchEdit == null || table == null) return;
|
|
||||||
|
|
||||||
foreach (DataColumn dcol in table.Columns)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(dcol.ColumnName) || dcol.ColumnName.Substring(0, 1) == "_") continue;
|
|
||||||
if (searchEdit.View.Columns.FirstOrDefault(item => item.FieldName == dcol.ColumnName) != null) continue;
|
|
||||||
|
|
||||||
GridColumn otherColumn = new GridColumn();
|
|
||||||
otherColumn.Name = otherColumn.FieldName = otherColumn.Caption = dcol.ColumnName;
|
|
||||||
otherColumn.Visible = true;
|
|
||||||
searchEdit.View.Columns.Add(otherColumn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 设置字典搜索框弹出宽度,规则与普通自动搜索框保持一致。
|
|
||||||
/// </summary>
|
|
||||||
private void SetSpecialReturnPopupWidth(RepositoryItemGridLookUpEdit searchEdit, DataTable table, GridColumnModel model)
|
|
||||||
{
|
|
||||||
if (searchEdit == null || table == null || model == null) return;
|
|
||||||
|
|
||||||
int popWidth = 0;
|
|
||||||
string[] columnsWidth = !string.IsNullOrWhiteSpace(model.LookUpFieldsWidth) ? model.LookUpFieldsWidth.Trim().TrimEnd(',').Split(',') : null;
|
|
||||||
if (columnsWidth != null && columnsWidth.Length > 0)
|
|
||||||
{
|
|
||||||
int columnWidthIndex = 0;
|
|
||||||
foreach (DataColumn dcol in table.Columns)
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(dcol.ColumnName) && dcol.ColumnName.Substring(0, 1) != "_")
|
|
||||||
{
|
|
||||||
GridColumn gCol = searchEdit.View.Columns.FirstOrDefault(x => x.FieldName == dcol.ColumnName);
|
|
||||||
if (gCol != null)
|
|
||||||
{
|
|
||||||
int width = 0;
|
|
||||||
if (columnWidthIndex < columnsWidth.Length)
|
|
||||||
{
|
|
||||||
string widthStr = columnsWidth[columnWidthIndex];
|
|
||||||
width = int.TryParse(widthStr, out width) ? width : GraphicsText.GetTextWidth(gCol.Caption);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
width = GraphicsText.GetTextWidth(gCol.Caption);
|
|
||||||
int maxWidth = CalcMaxColumnWidth(table, gCol.Name);
|
|
||||||
width = width > maxWidth ? width : maxWidth;
|
|
||||||
}
|
|
||||||
gCol.Width = width;
|
|
||||||
popWidth += gCol.Width;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
columnWidthIndex++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach (DataColumn dcol in table.Columns)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(dcol.ColumnName) || dcol.ColumnName.Substring(0, 1) == "_") continue;
|
|
||||||
GridColumn gCol = searchEdit.View.Columns.FirstOrDefault(x => x.FieldName == dcol.ColumnName);
|
|
||||||
if (gCol != null)
|
|
||||||
{
|
|
||||||
int columnWidth = GraphicsText.GetTextWidth(gCol.Caption);
|
|
||||||
gCol.Width = CalcMaxColumnWidth(table, gCol.Name);
|
|
||||||
gCol.Width = columnWidth > gCol.Width ? columnWidth : gCol.Width;
|
|
||||||
popWidth += gCol.Width;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (model.LookUpWidth > 0)
|
|
||||||
{
|
|
||||||
popWidth = model.LookUpWidth + 5;
|
|
||||||
}
|
|
||||||
searchEdit.PopupFormSize = new Size(popWidth, searchEdit.PopupFormSize.Height);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <para>说明:设置列格式化</para>
|
/// <para>说明:设置列格式化</para>
|
||||||
/// <para>创建人:龚宇超</para>
|
/// <para>创建人:龚宇超</para>
|
||||||
@@ -2113,7 +1524,6 @@ namespace Lskj.Control
|
|||||||
{
|
{
|
||||||
if (this.DisableFieldSources && item.isVislble) continue;
|
if (this.DisableFieldSources && item.isVislble) continue;
|
||||||
if (ControlType.IsNotLoadData(item.FieldType)) continue;
|
if (ControlType.IsNotLoadData(item.FieldType)) continue;
|
||||||
if (IsSpecialReturnBox(item.FieldType)) continue;
|
|
||||||
if (UpdateColumnRefresh && !string.IsNullOrWhiteSpace(UpdateColumns) && !UpdateColumns.Split(',').Contains(item.FieldName)) continue;
|
if (UpdateColumnRefresh && !string.IsNullOrWhiteSpace(UpdateColumns) && !UpdateColumns.Split(',').Contains(item.FieldName)) continue;
|
||||||
if (!string.IsNullOrWhiteSpace(item.SqlSource))
|
if (!string.IsNullOrWhiteSpace(item.SqlSource))
|
||||||
{
|
{
|
||||||
@@ -5230,11 +4640,6 @@ namespace Lskj.Control
|
|||||||
if (SystemInfo.Instance.DisableCellAutoFiltering && edit.Properties != null) edit.Properties.AutoComplete = false;//设置是否启用自动完成功能
|
if (SystemInfo.Instance.DisableCellAutoFiltering && edit.Properties != null) edit.Properties.AutoComplete = false;//设置是否启用自动完成功能
|
||||||
RepositoryItemGridLookUpEdit searchEdit = edit.Properties;
|
RepositoryItemGridLookUpEdit searchEdit = edit.Properties;
|
||||||
DataTable dt = (searchEdit.DataSource as DataTable);
|
DataTable dt = (searchEdit.DataSource as DataTable);
|
||||||
GridColumnModel model = searchEdit.Tag as GridColumnModel;
|
|
||||||
if (dt == null && model != null && IsSpecialReturnBox(model.FieldType))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
BeginInvoke(new MethodInvoker(delegate ()
|
BeginInvoke(new MethodInvoker(delegate ()
|
||||||
{
|
{
|
||||||
FilterLookup(sender, e.NewValue + "");
|
FilterLookup(sender, e.NewValue + "");
|
||||||
@@ -9933,16 +9338,7 @@ namespace Lskj.Control
|
|||||||
{
|
{
|
||||||
this.mLoading = false;
|
this.mLoading = false;
|
||||||
mControlSourceDic.Clear();
|
mControlSourceDic.Clear();
|
||||||
mSpecialReturnSourceDic.Clear();
|
ResetExtendedReturnState();
|
||||||
mSpecialReturnSourceTaskDic.Clear();
|
|
||||||
mSpecialReturnDisplayDic.Clear();
|
|
||||||
foreach (GridColumnModel model in mControlList)
|
|
||||||
{
|
|
||||||
if (IsSpecialReturnBox(model.FieldType))
|
|
||||||
{
|
|
||||||
StartSpecialReturnSourceTask(model);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SetColumnsSource(UpdateColumnRefresh);
|
SetColumnsSource(UpdateColumnRefresh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -708,6 +708,13 @@
|
|||||||
<Compile Include="AutoGridLookUp\AutoGridPopup.cs">
|
<Compile Include="AutoGridLookUp\AutoGridPopup.cs">
|
||||||
<SubType>UserControl</SubType>
|
<SubType>UserControl</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="AutoGridLookUp\ExtendedReturnSearchPopup.cs">
|
||||||
|
<SubType>UserControl</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="AutoGridLookUp\ExtendedReturnModuleSourceResolver.cs" />
|
||||||
|
<Compile Include="AutoGridLookUp\LabelExtendedReturnSearchEdit.cs">
|
||||||
|
<SubType>UserControl</SubType>
|
||||||
|
</Compile>
|
||||||
<Compile Include="AutoGridLookUp\AutoGridPopup.Designer.cs">
|
<Compile Include="AutoGridLookUp\AutoGridPopup.Designer.cs">
|
||||||
<DependentUpon>AutoGridPopup.cs</DependentUpon>
|
<DependentUpon>AutoGridPopup.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
@@ -1161,6 +1168,10 @@
|
|||||||
<Compile Include="GridControlEx.cs">
|
<Compile Include="GridControlEx.cs">
|
||||||
<SubType>UserControl</SubType>
|
<SubType>UserControl</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="GridControlEx.ExtendedReturn.cs">
|
||||||
|
<DependentUpon>GridControlEx.cs</DependentUpon>
|
||||||
|
<SubType>UserControl</SubType>
|
||||||
|
</Compile>
|
||||||
<Compile Include="GridControlEx.Designer.cs">
|
<Compile Include="GridControlEx.Designer.cs">
|
||||||
<DependentUpon>GridControlEx.cs</DependentUpon>
|
<DependentUpon>GridControlEx.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
@@ -1263,6 +1274,7 @@
|
|||||||
<Compile Include="Model\ControlModel.cs" />
|
<Compile Include="Model\ControlModel.cs" />
|
||||||
<Compile Include="Model\ControlType.cs" />
|
<Compile Include="Model\ControlType.cs" />
|
||||||
<Compile Include="Model\DateFormat.cs" />
|
<Compile Include="Model\DateFormat.cs" />
|
||||||
|
<Compile Include="Model\ExtendedReturnSupport.cs" />
|
||||||
<Compile Include="Model\GridColumnModel.cs" />
|
<Compile Include="Model\GridColumnModel.cs" />
|
||||||
<Compile Include="Model\GridRowColorModel.cs" />
|
<Compile Include="Model\GridRowColorModel.cs" />
|
||||||
<Compile Include="Model\MessageUtil.cs" />
|
<Compile Include="Model\MessageUtil.cs" />
|
||||||
@@ -1880,4 +1892,4 @@
|
|||||||
<Target Name="AfterBuild">
|
<Target Name="AfterBuild">
|
||||||
</Target>
|
</Target>
|
||||||
-->
|
-->
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -139,6 +139,10 @@ namespace Lskj.Control.Model
|
|||||||
/// <value>The text member.</value>
|
/// <value>The text member.</value>
|
||||||
public string TextMember { get; set; }
|
public string TextMember { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// 扩展返回字段映射,格式为“业务控件字段=返回数据字段”。
|
||||||
|
/// </summary>
|
||||||
|
public string ResultFields { get; set; }
|
||||||
|
/// <summary>
|
||||||
/// Gets or sets the source SQL.
|
/// Gets or sets the source SQL.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The source SQL.</value>
|
/// <value>The source SQL.</value>
|
||||||
|
|||||||
@@ -493,21 +493,13 @@ namespace Lskj.Control.Model
|
|||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 快速搜索框返回id(字典模式)
|
/// 模块选择返回ID-扩展
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const int DictionarySearchBoxToId = 181;
|
public const int LabModuleSelectReturnIdExtended = 173;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 快速搜索框返回text(字典模式)
|
/// 搜索返回ID-扩展
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const int DictionarySearchBoxToText = 182;
|
public const int LabSearchReturnIdExtended = 174;
|
||||||
/// <summary>
|
|
||||||
/// 快速搜索框返回id 带参数(字典模式)
|
|
||||||
/// </summary>
|
|
||||||
public const int DictionarySearchBoxToIdParam = 183;
|
|
||||||
/// <summary>
|
|
||||||
/// 快速搜索框返回text 带参数(字典模式)
|
|
||||||
/// </summary>
|
|
||||||
public const int DictionarySearchBoxToTextParam = 184;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <para>说明:是否为Value类型</para>
|
/// <para>说明:是否为Value类型</para>
|
||||||
@@ -628,6 +620,8 @@ namespace Lskj.Control.Model
|
|||||||
fieldType == LabPhone ||
|
fieldType == LabPhone ||
|
||||||
fieldType == LabSelectReturnIdNew ||
|
fieldType == LabSelectReturnIdNew ||
|
||||||
fieldType == LabSelectReturnTextNew ||
|
fieldType == LabSelectReturnTextNew ||
|
||||||
|
fieldType == LabModuleSelectReturnIdExtended ||
|
||||||
|
fieldType == LabSearchReturnIdExtended ||
|
||||||
fieldType == LabApiBtuton||
|
fieldType == LabApiBtuton||
|
||||||
fieldType == LabModuleAddRowsID ||
|
fieldType == LabModuleAddRowsID ||
|
||||||
fieldType == LabModuleAddRowsText;
|
fieldType == LabModuleAddRowsText;
|
||||||
|
|||||||
@@ -0,0 +1,151 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace Lskj.Control.Model
|
||||||
|
{
|
||||||
|
internal sealed class ExtendedReturnFieldMapping
|
||||||
|
{
|
||||||
|
public ExtendedReturnFieldMapping(string targetField, string sourceField)
|
||||||
|
{
|
||||||
|
TargetField = targetField;
|
||||||
|
SourceField = sourceField;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string TargetField { get; private set; }
|
||||||
|
|
||||||
|
public string SourceField { get; private set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class ExtendedReturnSupport
|
||||||
|
{
|
||||||
|
internal const string SearchAlias = "LS_ExtendedLookup";
|
||||||
|
internal const string SearchParameterName = "@lookupKeyword";
|
||||||
|
|
||||||
|
public static IList<ExtendedReturnFieldMapping> ParseResultFields(string resultFields)
|
||||||
|
{
|
||||||
|
List<ExtendedReturnFieldMapping> mappings = new List<ExtendedReturnFieldMapping>();
|
||||||
|
if (string.IsNullOrWhiteSpace(resultFields)) return mappings;
|
||||||
|
|
||||||
|
HashSet<string> targetFields = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
string[] items = resultFields.Split(new char[] { ';', ';' });
|
||||||
|
foreach (string rawItem in items)
|
||||||
|
{
|
||||||
|
string item = (rawItem ?? string.Empty).Trim();
|
||||||
|
if (item.Length == 0) continue;
|
||||||
|
|
||||||
|
int separatorIndex = item.IndexOf('=');
|
||||||
|
if (separatorIndex <= 0 || separatorIndex == item.Length - 1 || item.IndexOf('=', separatorIndex + 1) >= 0)
|
||||||
|
{
|
||||||
|
throw new FormatException(string.Format("返回字段配置“{0}”格式错误,应为“业务表字段=返回数据字段”。", item));
|
||||||
|
}
|
||||||
|
|
||||||
|
string targetField = item.Substring(0, separatorIndex).Trim();
|
||||||
|
string sourceField = item.Substring(separatorIndex + 1).Trim();
|
||||||
|
if (targetField.Length == 0 || sourceField.Length == 0)
|
||||||
|
{
|
||||||
|
throw new FormatException(string.Format("返回字段配置“{0}”存在空字段名。", item));
|
||||||
|
}
|
||||||
|
if (!targetFields.Add(targetField))
|
||||||
|
{
|
||||||
|
throw new FormatException(string.Format("返回字段配置中的业务表字段“{0}”重复。", targetField));
|
||||||
|
}
|
||||||
|
|
||||||
|
mappings.Add(new ExtendedReturnFieldMapping(targetField, sourceField));
|
||||||
|
}
|
||||||
|
return mappings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string FindTargetField(IEnumerable<ExtendedReturnFieldMapping> mappings, string sourceField)
|
||||||
|
{
|
||||||
|
if (mappings == null || string.IsNullOrWhiteSpace(sourceField)) return string.Empty;
|
||||||
|
|
||||||
|
foreach (ExtendedReturnFieldMapping mapping in mappings)
|
||||||
|
{
|
||||||
|
if (string.Equals(mapping.SourceField, sourceField, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return mapping.TargetField;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string BuildStructureSql(string sourceSql)
|
||||||
|
{
|
||||||
|
return string.Format("select top 0 * from ({0}) as [{1}]", NormalizeSourceSql(sourceSql), SearchAlias);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string BuildSearchSql(string sourceSql, DataColumnCollection columns, int maxRows)
|
||||||
|
{
|
||||||
|
if (columns == null || columns.Count == 0)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("搜索 SQL 没有返回任何可查询列。");
|
||||||
|
}
|
||||||
|
if (maxRows <= 0)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException("maxRows", "最大返回行数必须大于零。");
|
||||||
|
}
|
||||||
|
|
||||||
|
string alias = QuoteIdentifier(SearchAlias);
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.AppendFormat("select top ({0}) * from ({1}) as {2} where ", maxRows, NormalizeSourceSql(sourceSql), alias);
|
||||||
|
|
||||||
|
for (int i = 0; i < columns.Count; i++)
|
||||||
|
{
|
||||||
|
if (i > 0) builder.Append(" or ");
|
||||||
|
builder.Append("convert(nvarchar(4000), ");
|
||||||
|
builder.Append(alias);
|
||||||
|
builder.Append('.');
|
||||||
|
builder.Append(QuoteIdentifier(columns[i].ColumnName));
|
||||||
|
builder.Append(") like ");
|
||||||
|
builder.Append(SearchParameterName);
|
||||||
|
builder.Append(" escape N'\\'");
|
||||||
|
}
|
||||||
|
return builder.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string BuildLikeParameterValue(string keyword)
|
||||||
|
{
|
||||||
|
string value = keyword ?? string.Empty;
|
||||||
|
value = value.Replace("\\", "\\\\");
|
||||||
|
value = value.Replace("%", "\\%");
|
||||||
|
value = value.Replace("_", "\\_");
|
||||||
|
value = value.Replace("[", "\\[");
|
||||||
|
return "%" + value + "%";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string NormalizeSourceSql(string sourceSql)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(sourceSql))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("搜索数据源 SQL 不能为空。");
|
||||||
|
}
|
||||||
|
|
||||||
|
string normalized = sourceSql.Trim();
|
||||||
|
if (normalized.EndsWith(";", StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
normalized = normalized.Substring(0, normalized.Length - 1).TrimEnd();
|
||||||
|
}
|
||||||
|
if (normalized.IndexOf(';') >= 0)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("扩展搜索只支持一条可组合的 SELECT 语句。");
|
||||||
|
}
|
||||||
|
if (!Regex.IsMatch(normalized, @"^select\b", RegexOptions.IgnoreCase))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("扩展搜索数据源必须是可作为派生表使用的 SELECT 语句。");
|
||||||
|
}
|
||||||
|
return normalized;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string QuoteIdentifier(string identifier)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(identifier))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("搜索 SQL 返回了空列名。");
|
||||||
|
}
|
||||||
|
return "[" + identifier.Replace("]", "]]") + "]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -57,6 +57,7 @@ namespace Lskj.Control.Model
|
|||||||
private bool _frozenFlag;
|
private bool _frozenFlag;
|
||||||
private int _lookUpWidth;
|
private int _lookUpWidth;
|
||||||
private string _lookUpFieldsWidth;
|
private string _lookUpFieldsWidth;
|
||||||
|
private string _resultFields;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -326,6 +327,10 @@ namespace Lskj.Control.Model
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string LookUpFieldsWidth { get { return this._lookUpFieldsWidth; } }
|
public string LookUpFieldsWidth { get { return this._lookUpFieldsWidth; } }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// 扩展选择结果映射,格式:业务表字段=返回数据字段;业务表字段1=返回数据字段1。
|
||||||
|
/// </summary>
|
||||||
|
public string ResultFields { get { return this._resultFields; } }
|
||||||
|
/// <summary>
|
||||||
/// 动态列
|
/// 动态列
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool isDynamic;
|
public bool isDynamic;
|
||||||
@@ -459,6 +464,7 @@ namespace Lskj.Control.Model
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.addModuleResult = item.Table.Columns.Contains("addModuleResult") ? item["addModuleResult"] + "" : string.Empty;
|
this.addModuleResult = item.Table.Columns.Contains("addModuleResult") ? item["addModuleResult"] + "" : string.Empty;
|
||||||
|
this._resultFields = item.Table.Columns.Contains("resultfields") ? item["resultfields"] + "" : string.Empty;
|
||||||
this.addModuleld = item.Table.Columns.Contains("addModuleId") ? item["addModuleId"] + "" : string.Empty;
|
this.addModuleld = item.Table.Columns.Contains("addModuleId") ? item["addModuleId"] + "" : string.Empty;
|
||||||
this.unionCompare = item.Table.Columns.Contains("UnionCompare") ? item["UnionCompare"] + "" : string.Empty;
|
this.unionCompare = item.Table.Columns.Contains("UnionCompare") ? item["UnionCompare"] + "" : string.Empty;
|
||||||
this.isExportColumns = item.Table.Columns.Contains("isExportColumns") && !string.IsNullOrWhiteSpace(item["isExportColumns"] + "") ? "1".Equals(item["isExportColumns"] + "") : false;
|
this.isExportColumns = item.Table.Columns.Contains("isExportColumns") && !string.IsNullOrWhiteSpace(item["isExportColumns"] + "") ? "1".Equals(item["isExportColumns"] + "") : false;
|
||||||
|
|||||||
@@ -136,6 +136,13 @@ namespace Lskj.Control.Model
|
|||||||
/// 下拉框、搜索框控件对象
|
/// 下拉框、搜索框控件对象
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<ControlModel> mControlList = new List<ControlModel>();
|
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 readonly ExtendedReturnModuleSourceResolver mExtendedReturnModuleSourceResolver =
|
||||||
|
new ExtendedReturnModuleSourceResolver();
|
||||||
|
private int mExtendedReturnBatchDepth;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 数据源任务对象
|
/// 数据源任务对象
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -2253,6 +2260,11 @@ namespace Lskj.Control.Model
|
|||||||
LabelMultiAutoTextEdit4 moduleReturnsIdNew = ctr as LabelMultiAutoTextEdit4;
|
LabelMultiAutoTextEdit4 moduleReturnsIdNew = ctr as LabelMultiAutoTextEdit4;
|
||||||
value = ControlType.LabSelectReturnIdNew == model.FieldType ? moduleReturnsIdNew.EditValue : moduleReturnsIdNew.EditText;
|
value = ControlType.LabSelectReturnIdNew == model.FieldType ? moduleReturnsIdNew.EditValue : moduleReturnsIdNew.EditText;
|
||||||
break;
|
break;
|
||||||
|
case ControlType.LabModuleSelectReturnIdExtended:
|
||||||
|
case ControlType.LabSearchReturnIdExtended:
|
||||||
|
LabelExtendedReturnSearchEdit extendedReturnSearch = ctr as LabelExtendedReturnSearchEdit;
|
||||||
|
value = extendedReturnSearch == null ? string.Empty : extendedReturnSearch.EditValue;
|
||||||
|
break;
|
||||||
case ControlType.DynamicallyGeneratedSql:
|
case ControlType.DynamicallyGeneratedSql:
|
||||||
LabelMultiAutoTextEdit3 moduleSqlGenerated = ctr as LabelMultiAutoTextEdit3;
|
LabelMultiAutoTextEdit3 moduleSqlGenerated = ctr as LabelMultiAutoTextEdit3;
|
||||||
value = moduleSqlGenerated.EditText;
|
value = moduleSqlGenerated.EditText;
|
||||||
@@ -2679,6 +2691,7 @@ namespace Lskj.Control.Model
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
RefreshExtendedReturnDisplayControls();
|
||||||
foreach (ControlModel model in this.ControlModels)
|
foreach (ControlModel model in this.ControlModels)
|
||||||
{
|
{
|
||||||
BaseUserControl control = FindControl(model);
|
BaseUserControl control = FindControl(model);
|
||||||
@@ -3710,6 +3723,14 @@ namespace Lskj.Control.Model
|
|||||||
}
|
}
|
||||||
pictureEdit.TextEdit.Image = image;
|
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))
|
else if (baseControl.Model.FieldType == 7 && !"****".Equals(controlValue))
|
||||||
{
|
{
|
||||||
string dfmt = baseControl.Model.DataFormat;
|
string dfmt = baseControl.Model.DataFormat;
|
||||||
@@ -3750,6 +3771,118 @@ namespace Lskj.Control.Model
|
|||||||
//baseControl.Parent.Focus();
|
//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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ResolveExtendedReturnModuleSourceSql(string moduleCode)
|
||||||
|
{
|
||||||
|
return mExtendedReturnModuleSourceResolver.Resolve(moduleCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -4152,6 +4285,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.Sign = item.Table.Columns.Contains("TM_tagID") && !string.IsNullOrEmpty(item["TM_tagID"] + "") ? Convert.ToInt32(item["TM_tagID"] + "") : 0;
|
||||||
model.TextMember = item["lookupResult"] + "";
|
model.TextMember = item["lookupResult"] + "";
|
||||||
model.ValueMember = item["lookupKeyField"] + "";
|
model.ValueMember = item["lookupKeyField"] + "";
|
||||||
|
model.ResultFields = item.Table.Columns.Contains("resultfields") ? item["resultfields"] + "" : string.Empty;
|
||||||
|
|
||||||
if (!dataCaches.GetValue(item, "LookupSql", out string lookupSql))
|
if (!dataCaches.GetValue(item, "LookupSql", out string lookupSql))
|
||||||
{
|
{
|
||||||
@@ -4239,28 +4373,6 @@ namespace Lskj.Control.Model
|
|||||||
model.FieldType = 161;
|
model.FieldType = 161;
|
||||||
model.IsRadio = true;
|
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;
|
return model;
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -4830,6 +4942,19 @@ namespace Lskj.Control.Model
|
|||||||
if (!isLoadBorder) moduleReturnsIdNew.TextEdit.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
|
if (!isLoadBorder) moduleReturnsIdNew.TextEdit.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
|
||||||
baseControl = moduleReturnsIdNew;
|
baseControl = moduleReturnsIdNew;
|
||||||
break;
|
break;
|
||||||
|
case ControlType.LabModuleSelectReturnIdExtended:
|
||||||
|
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:
|
case ControlType.DynamicallyGeneratedSql:
|
||||||
LabelMultiAutoTextEdit3 moduleSqlGenerated = new LabelMultiAutoTextEdit3();
|
LabelMultiAutoTextEdit3 moduleSqlGenerated = new LabelMultiAutoTextEdit3();
|
||||||
// moduleSqlGenerated.SetDataSource();
|
// moduleSqlGenerated.SetDataSource();
|
||||||
@@ -5884,6 +6009,49 @@ namespace Lskj.Control.Model
|
|||||||
/// <param name="sender">The source of the event.</param>
|
/// <param name="sender">The source of the event.</param>
|
||||||
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
|
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
|
||||||
protected void OnTextEditTextChanged(object sender, EventArgs e)
|
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();
|
BaseUserControl baseControl = (sender as System.Windows.Forms.Control).ToBaseUserControl();
|
||||||
this.SetUnionAncCalcControl(baseControl);
|
this.SetUnionAncCalcControl(baseControl);
|
||||||
|
|||||||
@@ -156,6 +156,14 @@ namespace Lskj.Control.MultiModelLookUp
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public Dictionary<string, string> ModuleResultDic = new Dictionary<string, string>();
|
public Dictionary<string, string> ModuleResultDic = new Dictionary<string, string>();
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// 单选模式最后选中的原始数据行,供需要按动态列名返回多字段的调用方使用。
|
||||||
|
/// </summary>
|
||||||
|
public DataRow SelectedResultRow { get; private set; }
|
||||||
|
public DataRow GetSelectedResultRow()
|
||||||
|
{
|
||||||
|
return SelectedResultRow ?? this.gcMain.GridView.GetFocusedDataRow();
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
/// 返回多行的集合(模块返回添加行 167 168)
|
/// 返回多行的集合(模块返回添加行 167 168)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<string> EditValueList = new List<string>();
|
public List<string> EditValueList = new List<string>();
|
||||||
@@ -855,10 +863,12 @@ namespace Lskj.Control.MultiModelLookUp
|
|||||||
{
|
{
|
||||||
EditValue = string.Empty;
|
EditValue = string.Empty;
|
||||||
EditText = string.Empty;
|
EditText = string.Empty;
|
||||||
|
SelectedResultRow = null;
|
||||||
ModuleResultDic.Clear();
|
ModuleResultDic.Clear();
|
||||||
DataRow dr = this.gcMain.GridView.GetFocusedDataRow();
|
DataRow dr = this.gcMain.GridView.GetFocusedDataRow();
|
||||||
if (dr != null)
|
if (dr != null)
|
||||||
{
|
{
|
||||||
|
SelectedResultRow = dr;
|
||||||
this.EditValue = dr[ValueMember] + "";
|
this.EditValue = dr[ValueMember] + "";
|
||||||
this.EditText = dr[TextField] + "";
|
this.EditText = dr[TextField] + "";
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user