Compare commits
55 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d3587a16f1 | |||
| 6b78bbbf04 | |||
| 57dedb5e9d | |||
| a65dfab897 | |||
| d098dde830 | |||
| ef13d46fa2 | |||
| fc5faab65d | |||
| b091eca540 | |||
| 7d8ad77f5c | |||
| f72b153eb6 | |||
| c49015d390 | |||
| f665688d0b | |||
| 222ae3c08a | |||
| a803070819 | |||
| a9c986f9d5 | |||
| f1ce6ff658 | |||
| f92fd2f1cc | |||
| 000a69ce15 | |||
| c07220bbf0 | |||
| 219caba818 | |||
| 031fc34f12 | |||
| 66cab000ea | |||
| 4fe8844e86 | |||
| d71657bcb2 | |||
| a644184078 | |||
| 250f65b3d0 | |||
| 004778f2a8 | |||
| e06a67f002 | |||
| 2acae8551f | |||
| 7e819b44b7 | |||
| c5b6466fab | |||
| 5c4682bbbd | |||
| cc9bd1f0d1 | |||
| 5e6449cf1f | |||
| 11e395aa0f | |||
| 79399b0ef4 | |||
| 517d001eb8 | |||
| b9a3dd3b86 | |||
| 4fbe8324fc | |||
| dd1e354e2f | |||
| b651ea915b | |||
| bccccff428 | |||
| a82bc39edf | |||
| e50a29c37a | |||
| e86fb0a5db | |||
| 113433f656 | |||
| 94af6e7faa | |||
| b843ee30b1 | |||
| 9c0fdac9ba | |||
| 1bbe9c9a4c | |||
| b893e8d8e4 | |||
| e4b40a32d7 | |||
| a11ef73f1c | |||
| 0a1d027407 | |||
| bcf9f1b58c |
@@ -32,6 +32,7 @@
|
||||
*.zip
|
||||
*.rar
|
||||
*.7z
|
||||
*.r[0-9]*
|
||||
|
||||
# Confirmed unnecessary large files.
|
||||
/其他程序/工作部署记录/Smart X1 SDK V1.0.zip
|
||||
|
||||
@@ -0,0 +1,478 @@
|
||||
# 浏览器 JSON 复杂字段兼容 Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** 让旧 WinForms 浏览器桥接能够把任意对象或数组字段保留为紧凑 JSON 字符串,并继续安全转换为 `DataTable`。
|
||||
|
||||
**Architecture:** 在 `Lskj.Util.JsonUtil` 增加一个只供明确调用方选用的转换入口:先扫描整批 JSON 行,确定复杂列,再把这些列统一字符串化,最后复用 Newtonsoft.Json 原有 `DataTableConverter`。`Lskj.Control` 只在网页右键和返回行两个边界调用新入口,其他 JSON 转换和 WPF 宿主保持不变。
|
||||
|
||||
**Tech Stack:** .NET Framework 4.0、C# 7.3、Newtonsoft.Json 13.0.1、`System.Data.DataTable`、MSBuild、无第三方测试框架的控制台回归测试程序。
|
||||
|
||||
## Global Constraints
|
||||
|
||||
- 保留对象和数组字段,不删除 `$styles` 或其他未来字段。
|
||||
- 复杂值必须转换成无缩进的紧凑 JSON 字符串。
|
||||
- 从未出现对象或数组的标量列继续使用现有 Newtonsoft.Json 类型推断。
|
||||
- 不修改现有 `JsonUtil.ToDataTable` 和 `JsonUtil.ToDataRow` 的语义。
|
||||
- 不修改全局 Newtonsoft.Json 设置,不替换项目中的其他 `DeserializeObject<DataTable>` 调用。
|
||||
- 不修改 WPF、数据库、菜单查找、参数替换或 DLL 加载逻辑。
|
||||
- 只接入 `BsOpenModuleHandler.OpenRightModule` 和 `BsOpenModuleHandler.AddReturnRow`。
|
||||
- 现有两个目标源码文件只有 CRLF/LF 换行差异;执行前必须确认没有语义差异,再机械归一化,避免产生整文件噪声提交。
|
||||
|
||||
---
|
||||
|
||||
### Task 1: 建立回归测试并实现公共转换器
|
||||
|
||||
**Files:**
|
||||
- Create: `插件库/Lskj.Util.Tests/Lskj.Util.Tests.csproj`
|
||||
- Create: `插件库/Lskj.Util.Tests/Program.cs`
|
||||
- Modify: `插件库/Lskj.Util/JsonUtil.cs:1-190`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: Newtonsoft.Json `JToken`、`JArray`、`JObject` 和现有 `DataTableConverter`。
|
||||
- Produces: `public static DataTable JsonUtil.ToDataTablePreservingComplexValues(string json)`;接受顶层对象或对象数组,返回保留所有字段的 `DataTable`。
|
||||
|
||||
- [ ] **Step 1: 确认目标源码没有未提交的语义改动**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
git diff --ignore-space-at-eol --exit-code -- \
|
||||
'插件库/Lskj.Util/JsonUtil.cs' \
|
||||
'插件库/Lskj.Control/BrowserSetting/BsOpenModuleHandler.cs'
|
||||
```
|
||||
|
||||
Expected: exit code `0`,无输出。当前普通 `git diff --numstat` 显示的是 CRLF/LF 差异,不代表业务代码变化。
|
||||
|
||||
- [ ] **Step 2: 机械归一化两个目标源码的换行符**
|
||||
|
||||
只有 Step 1 成功后执行:
|
||||
|
||||
```bash
|
||||
perl -pi -e 's/\r$//' \
|
||||
'插件库/Lskj.Util/JsonUtil.cs' \
|
||||
'插件库/Lskj.Control/BrowserSetting/BsOpenModuleHandler.cs'
|
||||
git diff --check -- \
|
||||
'插件库/Lskj.Util/JsonUtil.cs' \
|
||||
'插件库/Lskj.Control/BrowserSetting/BsOpenModuleHandler.cs'
|
||||
```
|
||||
|
||||
Expected: `git diff --check` 无输出;此时两个文件不再显示整文件换行差异。
|
||||
|
||||
- [ ] **Step 3: 创建不依赖测试框架的回归测试项目**
|
||||
|
||||
Create `插件库/Lskj.Util.Tests/Lskj.Util.Tests.csproj`:
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{8E501869-816F-4E3E-81EE-A3BF9C223D61}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>Lskj.Util.Tests</RootNamespace>
|
||||
<AssemblyName>Lskj.Util.Tests</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="Newtonsoft.Json, Version=13.0.1.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\引用DLL\Newtonsoft.Json.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Program.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Lskj.Util\Lskj.Util.csproj">
|
||||
<Project>{A51BF642-6543-4DE3-8948-83F558B72BD4}</Project>
|
||||
<Name>Lskj.Util</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
```
|
||||
|
||||
Create `插件库/Lskj.Util.Tests/Program.cs`:
|
||||
|
||||
```csharp
|
||||
using Lskj.Util;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Data;
|
||||
|
||||
namespace Lskj.Util.Tests
|
||||
{
|
||||
internal static class Program
|
||||
{
|
||||
private static int Main()
|
||||
{
|
||||
try
|
||||
{
|
||||
PreservesStylesObjectAsCompactJson();
|
||||
PreservesArrayAsCompactJson();
|
||||
NormalizesEveryValueInAMixedComplexColumn();
|
||||
LeavesScalarColumnsEquivalentToExistingConverter();
|
||||
AcceptsSingleObject();
|
||||
RejectsInvalidTopLevelValues();
|
||||
Console.WriteLine("PASS: JsonUtil complex-value conversion tests");
|
||||
return 0;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.Error.WriteLine(ex);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
private static void PreservesStylesObjectAsCompactJson()
|
||||
{
|
||||
const string json = "[{\"id\":1,\"$styles\":{\"rowstyle\":\"{color:'#FFFF00','background-color':'#FF0000'}\"}}]";
|
||||
DataTable table = JsonUtil.ToDataTablePreservingComplexValues(json);
|
||||
AssertEqual(1, table.Rows.Count, "styles row count");
|
||||
AssertEqual("{\"rowstyle\":\"{color:'#FFFF00','background-color':'#FF0000'}\"}",
|
||||
table.Rows[0]["$styles"].ToString(), "styles JSON");
|
||||
}
|
||||
|
||||
private static void PreservesArrayAsCompactJson()
|
||||
{
|
||||
const string json = "[{\"id\":1,\"items\":[{\"code\":\"A\"},{\"code\":\"B\"}]}]";
|
||||
DataTable table = JsonUtil.ToDataTablePreservingComplexValues(json);
|
||||
AssertEqual("[{\"code\":\"A\"},{\"code\":\"B\"}]",
|
||||
table.Rows[0]["items"].ToString(), "array JSON");
|
||||
}
|
||||
|
||||
private static void NormalizesEveryValueInAMixedComplexColumn()
|
||||
{
|
||||
const string json = "["
|
||||
+ "{\"id\":1,\"payload\":5},"
|
||||
+ "{\"id\":2,\"payload\":{\"code\":\"A\"}},"
|
||||
+ "{\"id\":3,\"payload\":[1,2]},"
|
||||
+ "{\"id\":4,\"payload\":null},"
|
||||
+ "{\"id\":5,\"payload\":\"ready\"}]";
|
||||
DataTable table = JsonUtil.ToDataTablePreservingComplexValues(json);
|
||||
AssertEqual(typeof(string), table.Columns["payload"].DataType, "mixed column type");
|
||||
AssertEqual("5", table.Rows[0]["payload"].ToString(), "numeric scalar text");
|
||||
AssertEqual("{\"code\":\"A\"}", table.Rows[1]["payload"].ToString(), "object text");
|
||||
AssertEqual("[1,2]", table.Rows[2]["payload"].ToString(), "array text");
|
||||
AssertTrue(table.Rows[3].IsNull("payload"), "null remains null");
|
||||
AssertEqual("ready", table.Rows[4]["payload"].ToString(), "string remains string");
|
||||
}
|
||||
|
||||
private static void LeavesScalarColumnsEquivalentToExistingConverter()
|
||||
{
|
||||
const string json = "[{\"id\":1,\"title\":\"A\",\"active\":true},{\"id\":2,\"title\":\"B\",\"active\":false}]";
|
||||
DataTable expected = JsonConvert.DeserializeObject<DataTable>(json);
|
||||
DataTable actual = JsonUtil.ToDataTablePreservingComplexValues(json);
|
||||
AssertEqual(expected.Columns.Count, actual.Columns.Count, "scalar column count");
|
||||
AssertEqual(expected.Rows.Count, actual.Rows.Count, "scalar row count");
|
||||
foreach (DataColumn column in expected.Columns)
|
||||
{
|
||||
AssertEqual(column.DataType, actual.Columns[column.ColumnName].DataType,
|
||||
"scalar column type " + column.ColumnName);
|
||||
for (int rowIndex = 0; rowIndex < expected.Rows.Count; rowIndex++)
|
||||
{
|
||||
AssertEqual(expected.Rows[rowIndex][column.ColumnName],
|
||||
actual.Rows[rowIndex][column.ColumnName],
|
||||
"scalar value " + column.ColumnName + " row " + rowIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void AcceptsSingleObject()
|
||||
{
|
||||
const string json = "{\"ProductId\":\"P001\",\"meta\":{\"source\":\"web\"}}";
|
||||
DataTable table = JsonUtil.ToDataTablePreservingComplexValues(json);
|
||||
AssertEqual(1, table.Rows.Count, "single object row count");
|
||||
AssertEqual("P001", table.Rows[0]["ProductId"].ToString(), "single object scalar");
|
||||
AssertEqual("{\"source\":\"web\"}", table.Rows[0]["meta"].ToString(), "single object nested JSON");
|
||||
}
|
||||
|
||||
private static void RejectsInvalidTopLevelValues()
|
||||
{
|
||||
AssertThrows<ArgumentException>(delegate { JsonUtil.ToDataTablePreservingComplexValues(" "); }, "empty input");
|
||||
AssertThrows<JsonReaderException>(delegate { JsonUtil.ToDataTablePreservingComplexValues("{"); }, "invalid JSON");
|
||||
AssertThrows<JsonSerializationException>(delegate { JsonUtil.ToDataTablePreservingComplexValues("[1]"); }, "non-object row");
|
||||
}
|
||||
|
||||
private static void AssertThrows<TException>(Action action, string name) where TException : Exception
|
||||
{
|
||||
try { action(); }
|
||||
catch (TException) { return; }
|
||||
throw new InvalidOperationException("Expected " + typeof(TException).Name + ": " + name);
|
||||
}
|
||||
|
||||
private static void AssertTrue(bool value, string name)
|
||||
{
|
||||
if (!value) throw new InvalidOperationException("Assertion failed: " + name);
|
||||
}
|
||||
|
||||
private static void AssertEqual<T>(T expected, T actual, string name)
|
||||
{
|
||||
if (!object.Equals(expected, actual))
|
||||
{
|
||||
throw new InvalidOperationException(name + ": expected <" + expected + ">, actual <" + actual + ">");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 4: 构建测试项目并确认它先失败**
|
||||
|
||||
Run in Windows PowerShell from `E:\lserp_project\lserp_cs_6.0`:
|
||||
|
||||
```powershell
|
||||
$msbuild = Get-ChildItem "${env:ProgramFiles(x86)}\Microsoft Visual Studio\2022\*\MSBuild\Current\Bin\MSBuild.exe" |
|
||||
Select-Object -First 1 -ExpandProperty FullName
|
||||
if (-not $msbuild) { $msbuild = "$env:WINDIR\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe" }
|
||||
& $msbuild "插件库\Lskj.Util.Tests\Lskj.Util.Tests.csproj" /t:Rebuild /p:Configuration=Debug /p:Platform=AnyCPU
|
||||
```
|
||||
|
||||
Expected: build fails with `CS0117` because `JsonUtil.ToDataTablePreservingComplexValues` does not exist yet. Dependency or SDK errors do not satisfy this step。
|
||||
|
||||
- [ ] **Step 5: 实现复杂字段归一化方法**
|
||||
|
||||
Add `using System.Globalization;` to `插件库/Lskj.Util/JsonUtil.cs`, then add this method to `JsonUtil` without changing existing methods:
|
||||
|
||||
```csharp
|
||||
public static DataTable ToDataTablePreservingComplexValues(string json)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(json))
|
||||
{
|
||||
throw new ArgumentException("网页行 JSON 不能为空。", "json");
|
||||
}
|
||||
|
||||
JToken root = JToken.Parse(json);
|
||||
JArray rows;
|
||||
if (root.Type == JTokenType.Array)
|
||||
{
|
||||
rows = (JArray)root;
|
||||
}
|
||||
else if (root.Type == JTokenType.Object)
|
||||
{
|
||||
rows = new JArray(root);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new JsonSerializationException("网页行 JSON 的顶层必须是对象或对象数组。");
|
||||
}
|
||||
|
||||
HashSet<string> complexColumns = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
foreach (JToken rowToken in rows)
|
||||
{
|
||||
if (rowToken.Type != JTokenType.Object)
|
||||
{
|
||||
throw new JsonSerializationException("网页行 JSON 数组中的每一项都必须是对象。");
|
||||
}
|
||||
|
||||
foreach (JProperty property in ((JObject)rowToken).Properties())
|
||||
{
|
||||
if (property.Value.Type == JTokenType.Object || property.Value.Type == JTokenType.Array)
|
||||
{
|
||||
complexColumns.Add(property.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (JObject row in rows.Children<JObject>())
|
||||
{
|
||||
foreach (JProperty property in row.Properties().ToList())
|
||||
{
|
||||
if (!complexColumns.Contains(property.Name)
|
||||
|| property.Value.Type == JTokenType.Null
|
||||
|| property.Value.Type == JTokenType.Undefined)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string text;
|
||||
if (property.Value.Type == JTokenType.Object || property.Value.Type == JTokenType.Array)
|
||||
{
|
||||
text = property.Value.ToString(Formatting.None);
|
||||
}
|
||||
else if (property.Value.Type == JTokenType.String)
|
||||
{
|
||||
text = property.Value.Value<string>();
|
||||
}
|
||||
else
|
||||
{
|
||||
JValue scalar = property.Value as JValue;
|
||||
text = scalar == null || scalar.Value == null
|
||||
? null
|
||||
: Convert.ToString(scalar.Value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
property.Value = text == null ? JValue.CreateNull() : new JValue(text);
|
||||
}
|
||||
}
|
||||
|
||||
return JsonConvert.DeserializeObject<DataTable>(rows.ToString(Formatting.None));
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 6: 构建并运行转换级回归测试**
|
||||
|
||||
```powershell
|
||||
& $msbuild "插件库\Lskj.Util.Tests\Lskj.Util.Tests.csproj" /t:Rebuild /p:Configuration=Debug /p:Platform=AnyCPU
|
||||
if ($LASTEXITCODE -ne 0) { throw "Lskj.Util.Tests build failed" }
|
||||
& "插件库\Lskj.Util.Tests\bin\Debug\Lskj.Util.Tests.exe"
|
||||
if ($LASTEXITCODE -ne 0) { throw "Lskj.Util.Tests failed" }
|
||||
```
|
||||
|
||||
Expected: build succeeds and executable prints `PASS: JsonUtil complex-value conversion tests`.
|
||||
|
||||
- [ ] **Step 7: 提交公共转换器和回归测试**
|
||||
|
||||
```bash
|
||||
git add \
|
||||
'插件库/Lskj.Util/JsonUtil.cs' \
|
||||
'插件库/Lskj.Util.Tests/Lskj.Util.Tests.csproj' \
|
||||
'插件库/Lskj.Util.Tests/Program.cs'
|
||||
git diff --cached --check
|
||||
git commit -m 'fix(util): preserve complex JSON values in data tables'
|
||||
```
|
||||
|
||||
Expected: commit only contains the new test project and the focused `JsonUtil` method.
|
||||
|
||||
---
|
||||
|
||||
### Task 2: 在旧浏览器桥接的两个入口接入转换器
|
||||
|
||||
**Files:**
|
||||
- Modify: `插件库/Lskj.Control/BrowserSetting/BsOpenModuleHandler.cs:101-116`
|
||||
- Modify: `插件库/Lskj.Control/BrowserSetting/BsOpenModuleHandler.cs:322-334`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: `JsonUtil.ToDataTablePreservingComplexValues(string json)` from Task 1。
|
||||
- Produces: `OpenRightModule` 和 `AddReturnRow` 对任意对象/数组字段的兼容行为;其他菜单及模块调用接口不变。
|
||||
|
||||
- [ ] **Step 1: 将右键入口切换到公共转换器**
|
||||
|
||||
Replace:
|
||||
|
||||
```csharp
|
||||
DataTable dataTable = JsonConvert.DeserializeObject<DataTable>(arrayItem);
|
||||
```
|
||||
|
||||
with:
|
||||
|
||||
```csharp
|
||||
DataTable dataTable = JsonUtil.ToDataTablePreservingComplexValues(arrayItem);
|
||||
```
|
||||
|
||||
Do not change the `BaseImpl.GetDataRowResult` query, `GridRightMenuModel`, `DynamicModel` or `menu.ExecRightMenu` calls.
|
||||
|
||||
- [ ] **Step 2: 将网页返回行入口切换到公共转换器并删除冗余包装**
|
||||
|
||||
Replace:
|
||||
|
||||
```csharp
|
||||
JObject rowObject = JsonConvert.DeserializeObject<JObject>(rowdata);
|
||||
JArray jArray = new JArray();
|
||||
jArray.Add(rowObject);
|
||||
DataTable dataTable = JsonConvert.DeserializeObject<DataTable>(JsonConvert.SerializeObject(jArray));
|
||||
```
|
||||
|
||||
with:
|
||||
|
||||
```csharp
|
||||
DataTable dataTable = JsonUtil.ToDataTablePreservingComplexValues(rowdata);
|
||||
```
|
||||
|
||||
Remove the now-unused `using Newtonsoft.Json;` and `using Newtonsoft.Json.Linq;`. Keep product-prefix renaming and `StaticControl.ReturnRowLisy.Add` unchanged.
|
||||
|
||||
- [ ] **Step 3: 静态检查浏览器桥接范围**
|
||||
|
||||
```bash
|
||||
rg -n 'DeserializeObject\s*<\s*DataTable\s*>|ToDataTablePreservingComplexValues' \
|
||||
'插件库/Lskj.Control/BrowserSetting/BsOpenModuleHandler.cs'
|
||||
git diff --check -- '插件库/Lskj.Control/BrowserSetting/BsOpenModuleHandler.cs'
|
||||
```
|
||||
|
||||
Expected: only two `ToDataTablePreservingComplexValues` calls remain in this file;没有直接的 `DeserializeObject<DataTable>`,且 `git diff --check` 无输出。
|
||||
|
||||
- [ ] **Step 4: 重跑转换级测试并构建 Lskj.Control**
|
||||
|
||||
```powershell
|
||||
& "插件库\Lskj.Util.Tests\bin\Debug\Lskj.Util.Tests.exe"
|
||||
if ($LASTEXITCODE -ne 0) { throw "Lskj.Util.Tests failed" }
|
||||
& $msbuild "插件库\Lskj.Control\Lskj.Control.csproj" /t:Rebuild /p:Configuration=Debug /p:Platform=AnyCPU
|
||||
if ($LASTEXITCODE -ne 0) { throw "Lskj.Control build failed" }
|
||||
```
|
||||
|
||||
Expected: tests print `PASS`;`Lskj.Control` build succeeds without new warnings or errors and refreshes `Debug\Lskj.Control.dll` plus referenced `Lskj.Util.dll`.
|
||||
|
||||
- [ ] **Step 5: 提交浏览器桥接改动**
|
||||
|
||||
```bash
|
||||
git add '插件库/Lskj.Control/BrowserSetting/BsOpenModuleHandler.cs'
|
||||
git diff --cached --check
|
||||
git commit -m 'fix(browser): accept nested values in row callbacks'
|
||||
```
|
||||
|
||||
Expected: commit only changes the two intended browser callback conversions and removes the two unused Newtonsoft `using` directives.
|
||||
|
||||
---
|
||||
|
||||
### Task 3: 最终构建与业务验收交接
|
||||
|
||||
**Files:**
|
||||
- Verify: `Debug/Lskj.Util.dll`
|
||||
- Verify: `Debug/Lskj.Control.dll`
|
||||
- Verify: `Debug/Ls_NERP.exe`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: Task 1 的转换器和 Task 2 的浏览器接入。
|
||||
- Produces: 可由用户分别从旧 WinForms 和 WPF 宿主进行验收的 Debug 运行目录。
|
||||
|
||||
- [ ] **Step 1: 执行最终自动验证**
|
||||
|
||||
```powershell
|
||||
& $msbuild "插件库\Lskj.Util.Tests\Lskj.Util.Tests.csproj" /t:Rebuild /p:Configuration=Debug /p:Platform=AnyCPU
|
||||
if ($LASTEXITCODE -ne 0) { throw "Lskj.Util.Tests build failed" }
|
||||
& "插件库\Lskj.Util.Tests\bin\Debug\Lskj.Util.Tests.exe"
|
||||
if ($LASTEXITCODE -ne 0) { throw "Lskj.Util.Tests failed" }
|
||||
& $msbuild "插件库\Lskj.Control\Lskj.Control.csproj" /t:Rebuild /p:Configuration=Debug /p:Platform=AnyCPU
|
||||
if ($LASTEXITCODE -ne 0) { throw "Lskj.Control build failed" }
|
||||
Get-Item "Debug\Lskj.Util.dll", "Debug\Lskj.Control.dll" |
|
||||
Select-Object FullName, Length, LastWriteTime
|
||||
```
|
||||
|
||||
Expected: both builds succeed, test executable prints `PASS`, and both runtime DLL timestamps reflect the current build.
|
||||
|
||||
- [ ] **Step 2: 核对最终差异和提交历史**
|
||||
|
||||
```bash
|
||||
git diff --check
|
||||
git status --short
|
||||
git log -4 --oneline --decorate
|
||||
```
|
||||
|
||||
Expected: no uncommitted implementation changes;历史包含设计提交、公共转换器提交和浏览器桥接提交。构建输出和原有忽略文件不应进入 Git。
|
||||
|
||||
- [ ] **Step 3: 交给用户执行业务验收**
|
||||
|
||||
Provide this exact checklist:
|
||||
|
||||
```text
|
||||
1. 从 WPF 宿主启动,进入同一待办任务页面并点击“待办任务”。
|
||||
2. 确认不再出现 Path '[0].$styles' / StartObject 的 DataTable 反序列化错误。
|
||||
3. 确认右键配置继续解析到 PUR_4004,并正常进入原有客户端模块加载流程。
|
||||
4. 使用一个不包含对象/数组字段的旧网页右键功能,确认行为未变化。
|
||||
5. 如可用,再从旧 WinForms 入口重复步骤 1-4,确认两个宿主行为一致。
|
||||
6. 验证网页返回行功能,确认 ProductId 前缀和原有回填逻辑未变化。
|
||||
```
|
||||
|
||||
No additional source commit is required for this manual acceptance step.
|
||||
@@ -0,0 +1,96 @@
|
||||
# 173/174 Popup Contains Filtering Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** Make the DevExpress auto-filter row in 173/174 extended-return result popups use contains matching instead of starts-with matching.
|
||||
|
||||
**Architecture:** Keep the shared popup and query flow unchanged. Set `GridColumn.OptionsFilter.AutoFilterCondition` when each host dynamically creates result columns, following the existing `AutoFilterCondition.Contains` pattern already used elsewhere in Lskj.Control.
|
||||
|
||||
**Tech Stack:** C# on .NET Framework 4.0, WinForms, DevExpress GridControl/GridView.
|
||||
|
||||
## Global Constraints
|
||||
|
||||
- Work in `E:\lserp_project\lserp_cs_6.0` on `main` and preserve unrelated work.
|
||||
- Do not change database search SQL, search-column selection, ResultFields mapping, clear, selection, or display translation behavior.
|
||||
- Apply the behavior to both MyControl and GridControlEx 173/174 popup result columns.
|
||||
- Do not add dependencies or require a framework newer than .NET Framework 4.0.
|
||||
- Do not push unless the user explicitly requests it.
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Set dynamic popup result columns to contains filtering
|
||||
|
||||
**Files:**
|
||||
- Modify: `插件库/Lskj.Control/AutoGridLookUp/LabelExtendedReturnSearchEdit.cs`
|
||||
- Modify: `插件库/Lskj.Control/GridControlEx.ExtendedReturn.cs`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: DevExpress `GridColumn.OptionsFilter.AutoFilterCondition` and `DevExpress.XtraGrid.Columns.AutoFilterCondition.Contains`.
|
||||
- Produces: Contains-based local auto-filter behavior for every visible and hidden dynamic result column in both popup hosts.
|
||||
|
||||
- [ ] **Step 1: Run the failing structural contract**
|
||||
|
||||
Run from the repository root:
|
||||
|
||||
```powershell
|
||||
$formPath = '插件库\Lskj.Control\AutoGridLookUp\LabelExtendedReturnSearchEdit.cs'
|
||||
$gridPath = '插件库\Lskj.Control\GridControlEx.ExtendedReturn.cs'
|
||||
$form = Get-Content -LiteralPath $formPath -Raw
|
||||
$grid = Get-Content -LiteralPath $gridPath -Raw
|
||||
$setting = 'column.OptionsFilter.AutoFilterCondition = AutoFilterCondition.Contains;'
|
||||
if (-not $form.Contains($setting)) { throw 'MyControl result columns do not use contains filtering.' }
|
||||
if (-not $grid.Contains($setting)) { throw 'GridControlEx result columns do not use contains filtering.' }
|
||||
```
|
||||
|
||||
Expected: fail on the MyControl assertion because neither dynamic result-column loop currently sets the condition.
|
||||
|
||||
- [ ] **Step 2: Implement the minimal per-column setting**
|
||||
|
||||
In `LabelExtendedReturnSearchEdit.ConfigureResultColumns`, immediately after assigning `column.Visible`, add:
|
||||
|
||||
```csharp
|
||||
column.OptionsFilter.AutoFilterCondition = AutoFilterCondition.Contains;
|
||||
```
|
||||
|
||||
In `GridControlEx.ConfigureExtendedReturnViewColumns`, immediately after assigning `column.Visible`, add the identical line:
|
||||
|
||||
```csharp
|
||||
column.OptionsFilter.AutoFilterCondition = AutoFilterCondition.Contains;
|
||||
```
|
||||
|
||||
Both files already import `DevExpress.XtraGrid.Columns`, so no new using directive is needed.
|
||||
|
||||
- [ ] **Step 3: Re-run the structural contract**
|
||||
|
||||
Run the exact PowerShell contract from Step 1.
|
||||
|
||||
Expected: exit code `0` with no exception.
|
||||
|
||||
- [ ] **Step 4: Compile the dependency chain in isolation**
|
||||
|
||||
Upload `/Users/langsukeji/Documents/MyApps/lserp_project/codex_compile_project.ps1` to `E:\lserp_project\codex_compile_project.ps1`. Create `E:\lserp_project\lserp_cs_6.0\DebugCodexFilterContains`, copy `Debug\*.dll` into it, then invoke the helper for these projects in order, using the temporary directory as both `DebugDirectory` and the output DLL directory:
|
||||
|
||||
1. `插件库\Lskj.Model\Lskj.Model.csproj`
|
||||
2. `插件库\Lskj.Util\Lskj.Util.csproj`
|
||||
3. `插件库\Lskj.Business\Lskj.Business.csproj`
|
||||
4. `插件库\Lskj.Control\Lskj.Control.csproj`
|
||||
|
||||
Expected: all compiler exits are `0`; the existing `CS2023 /noconfig` warning is acceptable.
|
||||
|
||||
Delete the uploaded helper and `DebugCodexFilterContains` after compilation.
|
||||
|
||||
- [ ] **Step 5: Inspect and commit only the two source files**
|
||||
|
||||
```bat
|
||||
git diff --check
|
||||
git add -- "插件库/Lskj.Control/AutoGridLookUp/LabelExtendedReturnSearchEdit.cs" "插件库/Lskj.Control/GridControlEx.ExtendedReturn.cs"
|
||||
git diff --cached --check
|
||||
git commit -m "fix(control): use contains filtering in extended lookup"
|
||||
git status --short
|
||||
```
|
||||
|
||||
Expected: commit succeeds and the working tree is clean.
|
||||
|
||||
- [ ] **Step 6: Hand off runtime verification**
|
||||
|
||||
Ask the user to verify both MyControl and GridControlEx 173/174 popups by entering a middle substring such as `板` into the auto-filter row for a value such as `钢板/Q235B`. Do not push automatically.
|
||||
@@ -0,0 +1,652 @@
|
||||
# 173/174 Extended Return Search Column and Local Filter Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** Add a persistent search-column selector and DevExpress in-memory auto-filter row to the shared 173/174 popup without changing existing value display, ResultFields mapping, clearing, or selection behavior.
|
||||
|
||||
**Architecture:** Extend the shared SQL builder to distinguish visible searchable columns from hidden technical columns, then extend the shared popup to own column selection and local filtering state. The MyControl and grid hosts continue to own caption translation and asynchronous schema/query lifecycles; each request snapshots the selected real field name so background execution is deterministic.
|
||||
|
||||
**Tech Stack:** C# on .NET Framework 4.0, WinForms, DevExpress `PopupContainerEdit`/`ComboBoxEdit`/`GridControl`/`GridView`, ADO.NET provider factory, SQL Server-compatible derived-table SQL.
|
||||
|
||||
## Global Constraints
|
||||
|
||||
- Work in `E:\lserp_project\lserp_cs_6.0` on the current `main` branch and preserve unrelated work.
|
||||
- Do not add NuGet dependencies or require a framework newer than .NET Framework 4.0.
|
||||
- Keep 173 module SQL resolution and 174 configured SourceSql resolution unchanged.
|
||||
- Keep ResultFields, ValueMember, TextMember, display-value translation, clear, mouse selection, arrow navigation, and Enter selection unchanged.
|
||||
- Do not load complete lookup data during parent control initialization.
|
||||
- Opening the popup may asynchronously execute only the existing `top 0` structure query.
|
||||
- The selector displays translated result-grid captions but stores real source field names.
|
||||
- Columns whose real names start with `_` are hidden from the selector and excluded from “所有列” database predicates.
|
||||
- A new database search clears old DevExpress local filters and old results.
|
||||
- DevExpress auto-filtering operates only on the returned result table and must not issue a database request.
|
||||
- Preserve the last valid selector choice per popup instance; fall back to “所有列” only after a loaded schema proves that field no longer exists.
|
||||
- The automatic popup-open lookup for an existing business value always searches all visible columns; it must not consume or reset the user's preserved selector choice.
|
||||
- Keep the database result limit at 100 rows and continue using `@lookupKeyword` with existing LIKE escaping.
|
||||
|
||||
---
|
||||
|
||||
## File Map
|
||||
|
||||
- Modify `插件库/Lskj.Control/Model/ExtendedReturnSupport.cs`: central hidden-column rule and selected-column SQL generation.
|
||||
- Modify `插件库/Lskj.Control/AutoGridLookUp/ExtendedReturnSearchPopup.cs`: selector UI, selection persistence, result/filter reset, and auto-filter row.
|
||||
- Modify `插件库/Lskj.Control/AutoGridLookUp/LabelExtendedReturnSearchEdit.cs`: MyControl schema-only requests, translated selector options, and selected-field request snapshots.
|
||||
- Modify `插件库/Lskj.Control/GridControlEx.ExtendedReturn.cs`: grid schema-only requests, source-aware schema cache, translated selector options, and selected-field request snapshots.
|
||||
- Do not add production source files or change `Lskj.Control.csproj`.
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Make selected-column SQL generation a tested shared contract
|
||||
|
||||
**Files:**
|
||||
- Modify: `插件库/Lskj.Control/Model/ExtendedReturnSupport.cs:22-149`
|
||||
- Test temporarily: `E:\lserp_project\codex_extended_return_support_tests.cs`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: `string sourceSql`, `DataColumnCollection columns`, `int maxRows`, and optional real `string searchField`.
|
||||
- Produces: `IsSearchableColumn(string columnName)` and the overload `BuildSearchSql(string sourceSql, DataColumnCollection columns, int maxRows, string searchField)` while preserving the existing three-argument overload.
|
||||
|
||||
- [ ] **Step 1: Write the failing SQL contract harness**
|
||||
|
||||
Create the temporary test source with this exact behavior:
|
||||
|
||||
```csharp
|
||||
using System;
|
||||
using System.Data;
|
||||
using Lskj.Control.Model;
|
||||
|
||||
internal static class ExtendedReturnSupportContractTests
|
||||
{
|
||||
private static void Require(bool value, string message)
|
||||
{
|
||||
if (!value) throw new InvalidOperationException(message);
|
||||
}
|
||||
|
||||
private static void RequireThrows(Action action, string message)
|
||||
{
|
||||
try
|
||||
{
|
||||
action();
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
return;
|
||||
}
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
DataTable schema = new DataTable();
|
||||
schema.Columns.Add("productid");
|
||||
schema.Columns.Add("appellation");
|
||||
schema.Columns.Add("_rowid");
|
||||
|
||||
string allSql = ExtendedReturnSupport.BuildSearchSql(
|
||||
"select productid, appellation, _rowid from p_ProductTab",
|
||||
schema.Columns,
|
||||
100,
|
||||
string.Empty);
|
||||
Require(allSql.Contains("[productid]"), "all columns omitted productid");
|
||||
Require(allSql.Contains("[appellation]"), "all columns omitted appellation");
|
||||
Require(!allSql.Contains("[_rowid]"), "all columns included hidden field");
|
||||
|
||||
string oneSql = ExtendedReturnSupport.BuildSearchSql(
|
||||
"select productid, appellation, _rowid from p_ProductTab",
|
||||
schema.Columns,
|
||||
100,
|
||||
"appellation");
|
||||
Require(oneSql.Contains("[appellation]"), "selected column omitted appellation");
|
||||
Require(!oneSql.Contains("[productid]"), "selected column included productid");
|
||||
Require(!oneSql.Contains("[_rowid]"), "selected column included hidden field");
|
||||
|
||||
Require(!ExtendedReturnSupport.IsSearchableColumn("_rowid"), "hidden field is searchable");
|
||||
Require(ExtendedReturnSupport.IsSearchableColumn("productid"), "business field is not searchable");
|
||||
RequireThrows(delegate
|
||||
{
|
||||
ExtendedReturnSupport.BuildSearchSql("select 1", schema.Columns, 100, "_rowid");
|
||||
}, "hidden selected field did not fail");
|
||||
RequireThrows(delegate
|
||||
{
|
||||
ExtendedReturnSupport.BuildSearchSql("select 1", schema.Columns, 100, "missing");
|
||||
}, "missing selected field did not fail");
|
||||
|
||||
Console.WriteLine("ExtendedReturnSupport contract tests passed.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Compile the harness to prove it fails before implementation**
|
||||
|
||||
Run the production support file and harness through the installed Roslyn compiler with .NET Framework 4.0 references:
|
||||
|
||||
```bat
|
||||
dotnet "C:\Program Files\dotnet\sdk\10.0.201\Roslyn\bincore\csc.dll" /nologo /target:exe /out:"E:\lserp_project\codex_extended_return_support_tests.exe" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\mscorlib.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Data.dll" "插件库\Lskj.Control\Model\ExtendedReturnSupport.cs" "E:\lserp_project\codex_extended_return_support_tests.cs"
|
||||
```
|
||||
|
||||
Expected: compilation fails because the four-argument overload and `IsSearchableColumn` do not exist.
|
||||
|
||||
- [ ] **Step 3: Implement the visible-column rule and overload**
|
||||
|
||||
Keep the old overload as a compatibility wrapper and select columns using case-insensitive real field names:
|
||||
|
||||
```csharp
|
||||
public static bool IsSearchableColumn(string columnName)
|
||||
{
|
||||
return !string.IsNullOrWhiteSpace(columnName) &&
|
||||
!columnName.StartsWith("_", StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
public static string BuildSearchSql(
|
||||
string sourceSql,
|
||||
DataColumnCollection columns,
|
||||
int maxRows)
|
||||
{
|
||||
return BuildSearchSql(sourceSql, columns, maxRows, string.Empty);
|
||||
}
|
||||
|
||||
public static string BuildSearchSql(
|
||||
string sourceSql,
|
||||
DataColumnCollection columns,
|
||||
int maxRows,
|
||||
string searchField)
|
||||
{
|
||||
if (columns == null || columns.Count == 0)
|
||||
throw new InvalidOperationException("搜索 SQL 没有返回任何可查询列。");
|
||||
if (maxRows <= 0)
|
||||
throw new ArgumentOutOfRangeException("maxRows", "最大返回行数必须大于零。");
|
||||
|
||||
List<DataColumn> selectedColumns = new List<DataColumn>();
|
||||
foreach (DataColumn column in columns)
|
||||
{
|
||||
if (!IsSearchableColumn(column.ColumnName)) continue;
|
||||
if (string.IsNullOrWhiteSpace(searchField) ||
|
||||
string.Equals(column.ColumnName, searchField, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
selectedColumns.Add(column);
|
||||
}
|
||||
}
|
||||
if (selectedColumns.Count == 0)
|
||||
{
|
||||
throw new InvalidOperationException(string.IsNullOrWhiteSpace(searchField)
|
||||
? "搜索 SQL 没有返回可见业务列。"
|
||||
: string.Format("搜索字段“{0}”不存在或属于隐藏技术列。", searchField));
|
||||
}
|
||||
|
||||
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 < selectedColumns.Count; i++)
|
||||
{
|
||||
if (i > 0) builder.Append(" or ");
|
||||
builder.Append("convert(nvarchar(4000), ");
|
||||
builder.Append(alias);
|
||||
builder.Append('.');
|
||||
builder.Append(QuoteIdentifier(selectedColumns[i].ColumnName));
|
||||
builder.Append(") like ");
|
||||
builder.Append(SearchParameterName);
|
||||
builder.Append(" escape N'\\'");
|
||||
}
|
||||
return builder.ToString();
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Compile and run the contract harness**
|
||||
|
||||
Run the same compiler command, then:
|
||||
|
||||
```bat
|
||||
E:\lserp_project\codex_extended_return_support_tests.exe
|
||||
```
|
||||
|
||||
Expected: exit code `0` and `ExtendedReturnSupport contract tests passed.`
|
||||
|
||||
- [ ] **Step 5: Remove temporary harness artifacts and commit Task 1**
|
||||
|
||||
```bat
|
||||
del "E:\lserp_project\codex_extended_return_support_tests.cs"
|
||||
del "E:\lserp_project\codex_extended_return_support_tests.exe"
|
||||
git add -- "插件库/Lskj.Control/Model/ExtendedReturnSupport.cs"
|
||||
git diff --cached --check
|
||||
git commit -m "feat(control): support selected extended search columns"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 2: Add selector persistence and local filter UI to the shared popup
|
||||
|
||||
**Files:**
|
||||
- Modify: `插件库/Lskj.Control/AutoGridLookUp/ExtendedReturnSearchPopup.cs:14-232`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: translated column options as `IEnumerable<KeyValuePair<string, string>>`, where key is the real field and value is the displayed caption.
|
||||
- Produces: `SelectedSearchField`, `SetSearchColumns(...)`, and `ClearResultAndFilter()` for both hosts.
|
||||
|
||||
- [ ] **Step 1: Record failing structural assertions**
|
||||
|
||||
Run this PowerShell check before editing:
|
||||
|
||||
```powershell
|
||||
$path = '插件库\Lskj.Control\AutoGridLookUp\ExtendedReturnSearchPopup.cs'
|
||||
$text = Get-Content -LiteralPath $path -Raw
|
||||
$required = @(
|
||||
'ComboBoxEdit searchFieldEdit',
|
||||
'searchPanel.ColumnCount = 4',
|
||||
'ShowAutoFilterRow = true',
|
||||
'SelectedSearchField',
|
||||
'SetSearchColumns',
|
||||
'ClearResultAndFilter'
|
||||
)
|
||||
foreach ($item in $required) {
|
||||
if (-not $text.Contains($item)) { throw "Missing popup contract: $item" }
|
||||
}
|
||||
```
|
||||
|
||||
Expected: failure on the first missing popup contract.
|
||||
|
||||
- [ ] **Step 2: Add the selector option model and public popup contract**
|
||||
|
||||
Add `using Lskj.Control.Model;` and `using System.Collections.Generic;`. Inside `ExtendedReturnSearchPopup`, add a private option object and the host-facing API:
|
||||
|
||||
```csharp
|
||||
private sealed class SearchColumnOption
|
||||
{
|
||||
public SearchColumnOption(string fieldName, string caption)
|
||||
{
|
||||
FieldName = fieldName ?? string.Empty;
|
||||
Caption = caption ?? string.Empty;
|
||||
}
|
||||
|
||||
public string FieldName { get; private set; }
|
||||
public string Caption { get; private set; }
|
||||
public override string ToString() { return Caption; }
|
||||
}
|
||||
|
||||
public string SelectedSearchField
|
||||
{
|
||||
get
|
||||
{
|
||||
SearchColumnOption option = searchFieldEdit.SelectedItem as SearchColumnOption;
|
||||
return option == null ? string.Empty : option.FieldName;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetSearchColumns(IEnumerable<KeyValuePair<string, string>> columns)
|
||||
{
|
||||
string preferredField = selectedSearchField;
|
||||
searchFieldEdit.Properties.BeginUpdate();
|
||||
try
|
||||
{
|
||||
searchFieldEdit.Properties.Items.Clear();
|
||||
SearchColumnOption all = new SearchColumnOption(string.Empty, "所有列");
|
||||
searchFieldEdit.Properties.Items.Add(all);
|
||||
SearchColumnOption selected = null;
|
||||
if (columns != null)
|
||||
{
|
||||
foreach (KeyValuePair<string, string> column in columns)
|
||||
{
|
||||
if (!ExtendedReturnSupport.IsSearchableColumn(column.Key)) continue;
|
||||
SearchColumnOption option = new SearchColumnOption(column.Key, column.Value);
|
||||
searchFieldEdit.Properties.Items.Add(option);
|
||||
if (string.Equals(option.FieldName, preferredField, StringComparison.OrdinalIgnoreCase))
|
||||
selected = option;
|
||||
}
|
||||
}
|
||||
searchFieldEdit.SelectedItem = selected ?? all;
|
||||
selectedSearchField = selected == null ? string.Empty : selected.FieldName;
|
||||
}
|
||||
finally
|
||||
{
|
||||
searchFieldEdit.Properties.EndUpdate();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Add `selectedSearchField` and update it from `SelectedIndexChanged`; `PrepareForOpen()` must not reset it.
|
||||
|
||||
- [ ] **Step 3: Change the top layout and keep input focus behavior**
|
||||
|
||||
Instantiate a `ComboBoxEdit`, set `TextEditStyle = TextEditStyles.DisableTextEditor`, and change the layout to four columns:
|
||||
|
||||
```csharp
|
||||
searchPanel.ColumnCount = 4;
|
||||
searchPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 120F));
|
||||
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.Controls.Add(searchFieldEdit, 0, 0);
|
||||
searchPanel.Controls.Add(searchEdit, 1, 0);
|
||||
searchPanel.Controls.Add(queryButton, 2, 0);
|
||||
searchPanel.Controls.Add(clearButton, 3, 0);
|
||||
```
|
||||
|
||||
Set selector/input/query/clear tab indices to `0/1/2/3`. Keep `FocusSearchEditor()` focused on `searchEdit` so opening the popup still allows immediate typing.
|
||||
|
||||
- [ ] **Step 4: Enable and reset DevExpress local filtering**
|
||||
|
||||
Enable the built-in filter row and centralize clearing:
|
||||
|
||||
```csharp
|
||||
resultView.OptionsView.ShowAutoFilterRow = true;
|
||||
|
||||
public void ClearResultAndFilter()
|
||||
{
|
||||
resultView.ClearColumnsFilter();
|
||||
resultGrid.DataSource = null;
|
||||
}
|
||||
|
||||
public void PrepareForOpen()
|
||||
{
|
||||
searchEdit.Text = string.Empty;
|
||||
ClearResultAndFilter();
|
||||
}
|
||||
```
|
||||
|
||||
Do not attach the selector or auto-filter row to `SearchRequested`; only Enter in `searchEdit` and the query button raise database search events.
|
||||
|
||||
- [ ] **Step 5: Run structural assertions and compile `Lskj.Control`**
|
||||
|
||||
Run the Step 1 PowerShell check and the repository’s isolated C# compile helper. Expected: structural check exit `0` and `Lskj.Control` compile exit `0`.
|
||||
|
||||
- [ ] **Step 6: Commit Task 2**
|
||||
|
||||
```bat
|
||||
git add -- "插件库/Lskj.Control/AutoGridLookUp/ExtendedReturnSearchPopup.cs"
|
||||
git diff --cached --check
|
||||
git commit -m "feat(control): add extended lookup filter UI"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 3: Integrate schema-only loading and selected fields in MyControl
|
||||
|
||||
**Files:**
|
||||
- Modify: `插件库/Lskj.Control/AutoGridLookUp/LabelExtendedReturnSearchEdit.cs:37-60,294-360,616-760`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: `popup.SelectedSearchField`, `popup.SetSearchColumns(...)`, the existing `GetSchema(...)`, and the four-argument SQL builder.
|
||||
- Produces: schema-only asynchronous requests and result delivery that configures selector options before optionally binding rows.
|
||||
|
||||
- [ ] **Step 1: Record failing MyControl integration assertions**
|
||||
|
||||
```powershell
|
||||
$path = '插件库\Lskj.Control\AutoGridLookUp\LabelExtendedReturnSearchEdit.cs'
|
||||
$text = Get-Content -LiteralPath $path -Raw
|
||||
$required = @(
|
||||
'public string SearchField;',
|
||||
'public bool SchemaOnly;',
|
||||
'public DataTable Schema;',
|
||||
'popup.SelectedSearchField',
|
||||
'popup.SetSearchColumns',
|
||||
'MaxRows, request.SearchField'
|
||||
)
|
||||
foreach ($item in $required) {
|
||||
if (-not $text.Contains($item)) { throw "Missing MyControl integration: $item" }
|
||||
}
|
||||
```
|
||||
|
||||
Expected: failure before implementation.
|
||||
|
||||
- [ ] **Step 2: Extend request/result snapshots**
|
||||
|
||||
Add exact state to the existing nested classes:
|
||||
|
||||
```csharp
|
||||
private sealed class SearchRequest
|
||||
{
|
||||
public int Version;
|
||||
public string SourceSql;
|
||||
public string Keyword;
|
||||
public string SearchField;
|
||||
public string ConnectionString;
|
||||
public bool SchemaOnly;
|
||||
}
|
||||
|
||||
private sealed class QueryResult
|
||||
{
|
||||
public DataTable Schema;
|
||||
public DataTable Table;
|
||||
public Exception Error;
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Queue schema-only work on popup open**
|
||||
|
||||
Resolve `sourceSql` once in `PopupEdit_QueryPopUp`. After `PrepareForOpen()`:
|
||||
|
||||
```csharp
|
||||
DataTable cachedSchema = TryGetSchema(sourceSql);
|
||||
if (cachedSchema != null) ConfigureSearchColumns(cachedSchema);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(EditValue))
|
||||
QueueSearch(sourceSql, EditValue, string.Empty, false);
|
||||
else if (cachedSchema == null)
|
||||
QueueSearch(sourceSql, string.Empty, string.Empty, true);
|
||||
else
|
||||
CancelSearch();
|
||||
```
|
||||
|
||||
`TryGetSchema` must take `schemaSyncRoot` and return the cached table only when `schemaSql` equals the resolved SQL. `QueueSearch` replaces the old `StartSearch` request construction and snapshots `SearchField` and `SchemaOnly`. The popup-open lookup deliberately uses an empty search field so an existing actual ID is found independently of the preserved selector; only explicit Enter/query actions use `popup.SelectedSearchField`.
|
||||
|
||||
- [ ] **Step 4: Build translated options from schema**
|
||||
|
||||
Use existing caption translation and shared visibility rules:
|
||||
|
||||
```csharp
|
||||
private void ConfigureSearchColumns(DataTable sourceSchema)
|
||||
{
|
||||
List<KeyValuePair<string, string>> options = new List<KeyValuePair<string, string>>();
|
||||
IList<ExtendedReturnFieldMapping> mappings =
|
||||
ExtendedReturnSupport.ParseResultFields(Model.ResultFields);
|
||||
foreach (DataColumn column in sourceSchema.Columns)
|
||||
{
|
||||
if (!ExtendedReturnSupport.IsSearchableColumn(column.ColumnName)) continue;
|
||||
options.Add(new KeyValuePair<string, string>(
|
||||
column.ColumnName,
|
||||
GetColumnCaption(column.ColumnName, mappings)));
|
||||
}
|
||||
popup.SetSearchColumns(options);
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 5: Make query and delivery schema-aware**
|
||||
|
||||
`Query(SearchRequest request)` must always load and validate schema, set `result.Schema`, and execute row SQL only when `!request.SchemaOnly`:
|
||||
|
||||
```csharp
|
||||
DataTable sourceSchema = GetSchema(request.SourceSql, request.ConnectionString);
|
||||
result.Schema = sourceSchema;
|
||||
IList<ExtendedReturnFieldMapping> mappings =
|
||||
ExtendedReturnSupport.ParseResultFields(Model.ResultFields);
|
||||
ValidateSourceColumns(sourceSchema.Columns, mappings);
|
||||
if (!request.SchemaOnly)
|
||||
{
|
||||
string searchSql = ExtendedReturnSupport.BuildSearchSql(
|
||||
request.SourceSql, sourceSchema.Columns, MaxRows, request.SearchField);
|
||||
result.Table = ExecuteQuery(
|
||||
searchSql,
|
||||
ExtendedReturnSupport.BuildLikeParameterValue(request.Keyword),
|
||||
request.ConnectionString);
|
||||
}
|
||||
```
|
||||
|
||||
Change delivery to receive the request, reject stale versions, call `ConfigureSearchColumns(result.Schema)`, and bind/configure result rows only when `result.Table != null`.
|
||||
|
||||
- [ ] **Step 6: Clear local filters on explicit database search**
|
||||
|
||||
In `Popup_SearchRequested`, call `popup.ClearResultAndFilter()` before queuing any non-empty keyword. Capture `popup.SelectedSearchField` in that same UI event. Empty keywords cancel work and leave a cleared result.
|
||||
|
||||
- [ ] **Step 7: Run assertions and compile through `Lskj.Control`**
|
||||
|
||||
Run the Step 1 check. Compile `Lskj.Model`, `Lskj.Util`, `Lskj.Business`, then `Lskj.Control` into an isolated dependency directory. Expected: all exits `0`.
|
||||
|
||||
- [ ] **Step 8: Commit Task 3**
|
||||
|
||||
```bat
|
||||
git add -- "插件库/Lskj.Control/AutoGridLookUp/LabelExtendedReturnSearchEdit.cs"
|
||||
git diff --cached --check
|
||||
git commit -m "feat(control): add form extended lookup column search"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 4: Integrate schema-only loading and selected fields in GridControlEx
|
||||
|
||||
**Files:**
|
||||
- Modify: `插件库/Lskj.Control/GridControlEx.ExtendedReturn.cs:32-85,323-449,621-905,1189-1220`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: the shared popup contract and selected-column SQL builder from Tasks 1-2.
|
||||
- Produces: per-grid-column source-aware schema caching, schema-only requests, and selected-field request snapshots within the existing serialized request state machine.
|
||||
|
||||
- [ ] **Step 1: Record failing grid integration assertions**
|
||||
|
||||
```powershell
|
||||
$path = '插件库\Lskj.Control\GridControlEx.ExtendedReturn.cs'
|
||||
$text = Get-Content -LiteralPath $path -Raw
|
||||
$required = @(
|
||||
'mExtendedReturnSchemaSqls',
|
||||
'public string SearchField;',
|
||||
'public bool SchemaOnly;',
|
||||
'public DataTable Schema;',
|
||||
'popup.SelectedSearchField',
|
||||
'popup.SetSearchColumns',
|
||||
'request.SearchField'
|
||||
)
|
||||
foreach ($item in $required) {
|
||||
if (-not $text.Contains($item)) { throw "Missing grid integration: $item" }
|
||||
}
|
||||
```
|
||||
|
||||
Expected: failure before implementation.
|
||||
|
||||
- [ ] **Step 2: Make cached schemas source-aware**
|
||||
|
||||
Add:
|
||||
|
||||
```csharp
|
||||
private readonly Dictionary<string, string> mExtendedReturnSchemaSqls =
|
||||
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
```
|
||||
|
||||
`GetExtendedReturnSchema` and a new `TryGetExtendedReturnSchema` must return a cached table only when both field name and resolved `sourceSql` match. Store the SQL beside each cached table and clear both dictionaries in `ResetExtendedReturnState()`.
|
||||
|
||||
- [ ] **Step 3: Extend grid request/result snapshots**
|
||||
|
||||
Add `SearchField` and `SchemaOnly` to `ExtendedLookupRequest`, plus `Schema` to `ExtendedLookupQueryResult`. Preserve the existing version, pending-request, and single-worker-per-field rules.
|
||||
|
||||
- [ ] **Step 4: Configure or asynchronously load schema on popup open**
|
||||
|
||||
In `ExtendedReturnSearch_QueryPopUp`, resolve source SQL after the business row is known. Configure selector options immediately from a matching cache. If the actual business value is empty and no schema is cached, enqueue a schema-only request; if it is non-empty, enqueue the normal initial search with an empty search field so it searches all visible columns without changing the preserved selector.
|
||||
|
||||
Use the existing caption method when building options:
|
||||
|
||||
```csharp
|
||||
private void ConfigureExtendedReturnSearchColumns(
|
||||
ExtendedReturnPopupContext context,
|
||||
DataTable sourceSchema)
|
||||
{
|
||||
List<KeyValuePair<string, string>> options = new List<KeyValuePair<string, string>>();
|
||||
IList<ExtendedReturnFieldMapping> mappings =
|
||||
ExtendedReturnSupport.ParseResultFields(context.Model.ResultFields);
|
||||
foreach (DataColumn column in sourceSchema.Columns)
|
||||
{
|
||||
if (!ExtendedReturnSupport.IsSearchableColumn(column.ColumnName)) continue;
|
||||
options.Add(new KeyValuePair<string, string>(
|
||||
column.ColumnName,
|
||||
GetExtendedReturnColumnCaption(column.ColumnName, mappings)));
|
||||
}
|
||||
context.Popup.SetSearchColumns(options);
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 5: Snapshot selector state for explicit searches**
|
||||
|
||||
`ExtendedReturnSearch_SearchRequested` must pass `popup.SelectedSearchField`. `StartExtendedReturnSearch` must clear the popup’s filters/results, reject an empty keyword, validate business configuration, resolve SQL, and enqueue a non-schema-only request containing the selected field.
|
||||
|
||||
- [ ] **Step 6: Make the worker result schema-aware without weakening stale-result guards**
|
||||
|
||||
`QueryExtendedReturn` must always populate `result.Schema`; it calls the four-argument SQL builder only for non-schema-only requests. In `BeginInvokeExtendedReturnResult`:
|
||||
|
||||
1. Keep every existing editor, focused column, business row, and request-version guard.
|
||||
2. Configure selector options from `result.Schema`.
|
||||
3. For schema-only requests, stop without setting `DeliveredVersion` or binding a result table.
|
||||
4. For row requests, set `DeliveredVersion`, bind the result table, configure result columns, and retain existing popup visibility behavior.
|
||||
|
||||
- [ ] **Step 7: Run assertions and compile through `Lskj.Control`**
|
||||
|
||||
Run the Step 1 check and the isolated four-project compile chain. Expected: all exits `0`.
|
||||
|
||||
- [ ] **Step 8: Commit Task 4**
|
||||
|
||||
```bat
|
||||
git add -- "插件库/Lskj.Control/GridControlEx.ExtendedReturn.cs"
|
||||
git diff --cached --check
|
||||
git commit -m "feat(control): add grid extended lookup column search"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 5: Final compatibility verification and delivery
|
||||
|
||||
**Files:**
|
||||
- Verify: `插件库/Lskj.Control/Model/ExtendedReturnSupport.cs`
|
||||
- Verify: `插件库/Lskj.Control/AutoGridLookUp/ExtendedReturnSearchPopup.cs`
|
||||
- Verify: `插件库/Lskj.Control/AutoGridLookUp/LabelExtendedReturnSearchEdit.cs`
|
||||
- Verify: `插件库/Lskj.Control/GridControlEx.ExtendedReturn.cs`
|
||||
- Verify: `docs/superpowers/specs/2026-07-31-extended-return-search-column-filter-design.md`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: all contracts created in Tasks 1-4.
|
||||
- Produces: a clean, compiled local `main` ready for user runtime verification and later push authorization.
|
||||
|
||||
- [ ] **Step 1: Re-run the SQL contract harness from a clean temporary file**
|
||||
|
||||
Recreate the exact Task 1 harness, compile it with the final support source, run it, and confirm exit `0`. Delete the temporary `.cs` and `.exe` afterward.
|
||||
|
||||
- [ ] **Step 2: Run final structural behavior checks**
|
||||
|
||||
Assert all of the following exact invariants with PowerShell `Get-Content -Raw` checks:
|
||||
|
||||
- Popup layout has four columns and `ShowAutoFilterRow = true`.
|
||||
- `PrepareForOpen()` does not reset `selectedSearchField`.
|
||||
- Both explicit search handlers read `SelectedSearchField` and call `ClearResultAndFilter()`.
|
||||
- Both query paths call the four-argument SQL builder.
|
||||
- Both schema delivery paths call `SetSearchColumns`.
|
||||
- Grid reset clears both schema dictionaries.
|
||||
- Existing `ClearRequested`, `ResultSelected`, row indicator, arrow-key, and Enter-key event hookups remain present.
|
||||
|
||||
- [ ] **Step 3: Compile the final dependency chain in isolation**
|
||||
|
||||
Use `E:\lserp_project\codex_compile_project.ps1` with a fresh `DebugCodexExtendedFilter` directory. Compile in this exact order:
|
||||
|
||||
1. `插件库\Lskj.Model\Lskj.Model.csproj`
|
||||
2. `插件库\Lskj.Util\Lskj.Util.csproj`
|
||||
3. `插件库\Lskj.Business\Lskj.Business.csproj`
|
||||
4. `插件库\Lskj.Control\Lskj.Control.csproj`
|
||||
|
||||
Expected: each compiler exit is `0`; the known `CS2023 /noconfig` warning is acceptable.
|
||||
|
||||
- [ ] **Step 4: Inspect repository scope**
|
||||
|
||||
```bat
|
||||
git diff --check origin/main...main
|
||||
git status --short
|
||||
git log --oneline --decorate -8
|
||||
```
|
||||
|
||||
Expected: no whitespace errors, no temporary artifacts, and only the approved design/plan documents plus four production source files differ from the pre-feature base.
|
||||
|
||||
- [ ] **Step 5: Hand off runtime verification scenarios**
|
||||
|
||||
Report the ten scenarios in the design spec, emphasizing:
|
||||
|
||||
- selector captions and hidden-column exclusion;
|
||||
- all-column versus single-column database behavior;
|
||||
- selector persistence and fallback;
|
||||
- auto-filter row local-only behavior and reset on new search;
|
||||
- mouse/keyboard selection, clear, display translation, and ResultFields mapping for MyControl/grid with both 173 and 174.
|
||||
|
||||
Do not push until the user explicitly requests it.
|
||||
@@ -0,0 +1,124 @@
|
||||
# 浏览器 JSON 复杂字段兼容设计
|
||||
|
||||
## 背景
|
||||
|
||||
网页通过 `OpenOnRightClick` 将选中行 JSON 传入旧 WinForms 客户端。当前代码直接使用 Newtonsoft.Json 将 JSON 数组反序列化为 `DataTable`。当行数据包含对象或数组字段时,例如:
|
||||
|
||||
```json
|
||||
{
|
||||
"$styles": {
|
||||
"rowstyle": "{color:'#FFFF00','background-color':'#FF0000'}"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`DataTableConverter` 无法把 `StartObject` 或 `StartArray` 直接写入普通 `DataColumn`,因此抛出 `Unexpected JSON token when reading DataTable`。字段名 `$styles` 本身合法,真正的问题是字段值为嵌套对象。
|
||||
|
||||
## 目标
|
||||
|
||||
- 保留对象和数组字段,不删除 `$styles` 或其他未来字段。
|
||||
- 将复杂值转换成紧凑 JSON 字符串后再生成 `DataTable`。
|
||||
- 保持纯标量字段现有的列名、值和类型推断行为。
|
||||
- 只影响网页与旧客户端交互的数据边界,不改变全局 Newtonsoft.Json 行为。
|
||||
- 同时兼容右键调用和网页返回行两个浏览器入口。
|
||||
|
||||
## 非目标
|
||||
|
||||
- 不修改 WPF 启动、窗口或宿主逻辑。
|
||||
- 不修改数据库中的 JSON。
|
||||
- 不扁平化嵌套对象,不删除未知字段。
|
||||
- 不替换项目中所有 `DeserializeObject<DataTable>` 调用。
|
||||
- 不改变旧模块的菜单查找、参数替换和 DLL 加载流程。
|
||||
|
||||
## 方案比较
|
||||
|
||||
### 方案一:在浏览器边界归一化复杂列(采用)
|
||||
|
||||
解析网页 JSON,扫描整批记录,找出任一行中出现对象或数组值的列。将这些列的所有非空值统一转换为字符串,其中对象和数组使用紧凑 JSON;其他纯标量列保持不变。归一化后继续使用现有 Newtonsoft.Json `DataTable` 转换。
|
||||
|
||||
优点:影响范围小;保留现有标量类型;能处理未来任意字段名;可复用在两个浏览器入口。
|
||||
|
||||
### 方案二:手工构造全部为 `object` 的 DataTable
|
||||
|
||||
可以容纳复杂值,但会改变所有列的类型,可能影响比较、筛选、参数替换和旧模块中的类型判断,兼容风险较大。
|
||||
|
||||
### 方案三:注册全局 Newtonsoft.Json 转换器
|
||||
|
||||
可以统一处理,但会影响整个旧系统中大量 JSON 反序列化入口,难以证明不会改变其他模块行为,范围过宽。
|
||||
|
||||
## 详细设计
|
||||
|
||||
### 公共转换入口
|
||||
|
||||
在 `Lskj.Util.JsonUtil` 中增加一个含义明确的新方法,专门把可能包含复杂字段的网页行 JSON 转为 `DataTable`。不修改现有 `ToDataTable` 和 `ToDataRow` 的语义,避免影响未知调用方。
|
||||
|
||||
该方法接受:
|
||||
|
||||
- 顶层 JSON 数组,用于网页右键选中行。
|
||||
- 顶层单个 JSON 对象,用于网页返回一行数据;内部统一包装成数组处理。
|
||||
|
||||
空输入、非对象行或其他不符合约定的顶层结构视为无效输入,抛出可诊断异常,继续交给当前宿主的既有异常保护策略处理。
|
||||
|
||||
### 复杂列识别
|
||||
|
||||
必须先扫描全部记录,再执行转换。只要某列在任意一行中的值为 `JObject` 或 `JArray`,该列就被标记为复杂列。
|
||||
|
||||
不能只转换当前遇到的复杂值。例如第一行是数字、第二行是对象时,如果第一行已让 `DataTable` 将列推断为数值类型,第二行即使变成字符串仍会发生类型冲突。
|
||||
|
||||
### 值归一化规则
|
||||
|
||||
对于复杂列:
|
||||
|
||||
- `JObject` 转换为不带缩进和额外空白的 JSON 字符串。
|
||||
- `JArray` 转换为不带缩进和额外空白的 JSON 字符串。
|
||||
- 同列中的字符串保持原字符串内容。
|
||||
- 同列中的数字、布尔值等标量转换为稳定的字符串表示,确保整列类型一致。
|
||||
- `null` 保留为空值,不转换为空字符串。
|
||||
|
||||
对于从未出现对象或数组的列,不进行任何预处理,由现有 `DataTableConverter` 继续推断原有类型。
|
||||
|
||||
### 调用点
|
||||
|
||||
仅替换以下两个浏览器桥接入口的直接反序列化:
|
||||
|
||||
1. `Lskj.Control.BrowserSetting.BsOpenModuleHandler.OpenRightModule`
|
||||
2. `Lskj.Control.BrowserSetting.BsOpenModuleHandler.AddReturnRow`
|
||||
|
||||
`OpenRightModule` 后续仍把原有 `DataRow[]` 交给 `BaseRightMenu.ExecRightMenu`。菜单 ID 查询、占位符替换、`PUR_4004` 模块解析和 DLL 加载逻辑不变。
|
||||
|
||||
`AddReturnRow` 后续仍执行现有产品前缀处理并加入 `StaticControl.ReturnRowLisy`。
|
||||
|
||||
### 下游兼容性
|
||||
|
||||
经过归一化的 `DataRow` 再序列化传给动态模块时,复杂字段已经是普通字符串。下游 `DynamicModuleModel`、`DynamicModuleDetailModel` 等现有 `DataTable` 反序列化可继续工作,无需全局改造。
|
||||
|
||||
## 异常处理
|
||||
|
||||
- 合法对象/数组字段不再产生 `StartObject` 或 `StartArray` 异常。
|
||||
- 语法错误的 JSON、非对象行等仍作为真实错误报告,不静默删除数据。
|
||||
- 转换方法不吞异常;沿用当前宿主已经建立的异常保护策略,避免用空表或残缺数据掩盖真实输入错误。
|
||||
- 错误信息应保留原始异常,便于定位具体字段和输入。
|
||||
|
||||
## 验证方案
|
||||
|
||||
### 转换级测试
|
||||
|
||||
1. 当前实际 `$styles` 对象:成功生成一行,`$styles` 为紧凑 JSON 字符串。
|
||||
2. 任意名称的嵌套对象字段:成功并保留字段名和内容。
|
||||
3. 数组字段:成功并保留为紧凑 JSON 字符串。
|
||||
4. 同一复杂列在不同行中分别为对象、字符串、数字和 `null`:整列稳定转换,不发生类型冲突。
|
||||
5. 只有标量的原有 JSON:列和值与修改前一致。
|
||||
6. 单对象输入:用于 `AddReturnRow` 时成功生成一行。
|
||||
7. 无效 JSON 和非对象数组元素:明确失败,不产生不完整数据。
|
||||
|
||||
### 集成验证
|
||||
|
||||
1. 使用当前待办任务 JSON 点击网页“待办任务”,不再出现 `$styles` 的 `DataTable` 反序列化错误。
|
||||
2. 右键配置 ID 能继续解析,模块编号 `PUR_4004` 正常传入原 DLL 加载流程。
|
||||
3. 不含复杂字段的网页右键功能行为不变。
|
||||
4. 网页返回行功能仍可回填,包含复杂字段时不崩溃。
|
||||
5. 分别通过旧 WinForms 启动和 WPF 宿主启动验证相同行为。
|
||||
|
||||
## 构建与交付
|
||||
|
||||
改动位于旧代码项目。完成后重新编译并更新运行目录使用的 `Lskj.Util.dll` 与 `Lskj.Control.dll`;WPF 项目无需为本修复修改代码。
|
||||
@@ -0,0 +1,32 @@
|
||||
# 173/174 弹窗本地筛选改为包含匹配
|
||||
|
||||
## 目标
|
||||
|
||||
将 173/174 扩展返回弹窗中 DevExpress 自动筛选行的文本匹配方式,从默认的“开头匹配”改为“包含匹配”。例如在“物料名称”筛选框输入“板”,应匹配“钢板/Q235B”。
|
||||
|
||||
## 根因
|
||||
|
||||
共享弹窗已经启用 `ShowAutoFilterRow`,但 MyControl 与 GridControlEx 在查询完成后动态创建结果列时,没有设置 `GridColumn.OptionsFilter.AutoFilterCondition`,因此沿用了 DevExpress 默认的开头匹配。
|
||||
|
||||
项目内其他表格列已普遍使用 `AutoFilterCondition.Contains`,可直接沿用这一兼容写法。
|
||||
|
||||
## 设计
|
||||
|
||||
仅修改两处动态结果列创建逻辑:
|
||||
|
||||
- `LabelExtendedReturnSearchEdit.ConfigureResultColumns`
|
||||
- `GridControlEx.ConfigureExtendedReturnViewColumns`
|
||||
|
||||
每个结果列创建后设置:
|
||||
|
||||
```csharp
|
||||
column.OptionsFilter.AutoFilterCondition = AutoFilterCondition.Contains;
|
||||
```
|
||||
|
||||
不修改共享弹窗事件,不增加自定义筛选处理,不改变数据库查询 SQL、搜索列下拉框、ResultFields 映射、清空、选择和显示翻译逻辑。
|
||||
|
||||
## 验证
|
||||
|
||||
- 结构检查确认两处动态列均设置 `Contains`。
|
||||
- 编译 `Lskj.Model`、`Lskj.Util`、`Lskj.Business`、`Lskj.Control`。
|
||||
- 运行时由用户确认:自动筛选行输入位于文本中间的内容时仍能命中结果。
|
||||
@@ -0,0 +1,130 @@
|
||||
# 173/174 扩展返回搜索列与本地筛选设计
|
||||
|
||||
## 背景
|
||||
|
||||
173“模块选择返回 Id-扩展”和 174“搜索返回 Id-扩展”目前共用 `ExtendedReturnSearchPopup`。弹窗只提供一个搜索输入框,数据库查询会对数据源返回的全部列拼接 `OR LIKE`。结果表格已使用 DevExpress `GridView`,但没有显示自动筛选行。
|
||||
|
||||
本次改动在不改变现有数据源解析、ResultFields 回填、显示值翻译和键盘选择行为的前提下,增加数据库搜索列选择及结果集本地二次筛选。
|
||||
|
||||
## 目标
|
||||
|
||||
- 弹窗顶部增加搜索列下拉框。
|
||||
- 支持“所有列”数据库搜索和指定单列数据库搜索。
|
||||
- 下拉项显示与结果表头一致的中文标题,内部使用真实数据源字段名。
|
||||
- `_` 开头的隐藏技术列不进入下拉,也不参与“所有列”搜索。
|
||||
- 下方 DevExpress 表格显示自动筛选行,对数据库已返回的数据进行本地二次筛选。
|
||||
- 173、174 在表格控件和 MyControl 中保持一致行为。
|
||||
- 保留原有清空、选择、回填、显示和键盘操作。
|
||||
|
||||
## 非目标
|
||||
|
||||
- 不修改 173 的模块数据源解析规则。
|
||||
- 不修改 174 的 SourceSql 配置规则。
|
||||
- 不修改 ResultFields、ValueMember、TextMember 的含义或校验。
|
||||
- 不把 DevExpress 自动筛选条件发送到数据库。
|
||||
- 不在控件初始化阶段加载完整业务数据。
|
||||
- 不跨应用重启持久化搜索列选择。
|
||||
|
||||
## 交互设计
|
||||
|
||||
弹窗顶部从左到右排列:
|
||||
|
||||
1. 搜索列下拉框。
|
||||
2. 搜索文本输入框。
|
||||
3. “查询”按钮。
|
||||
4. “清空”按钮。
|
||||
|
||||
下拉框规则:
|
||||
|
||||
- 第一项固定为“所有列”。
|
||||
- 后续项来自实际数据源结构,只包含名称不以 `_` 开头的列。
|
||||
- 显示文本复用结果表格现有列标题翻译逻辑;选项内部保存真实字段名。
|
||||
- 每个 173/174 控件实例在内存中保留最后一次选择,关闭并重新打开弹窗时不重置。
|
||||
- 数据源结构变化且原选择字段已不存在时,自动回退到“所有列”。
|
||||
|
||||
输入框仍按现有方式仅在回车或点击“查询”时访问数据库。上下键进入结果表、结果表回车选择、鼠标点击选择和“清空”按钮行为保持不变。
|
||||
|
||||
## 数据结构加载
|
||||
|
||||
弹窗打开时只异步执行现有 `top 0` 结构查询,用于取得列名,不加载完整业务数据。
|
||||
|
||||
- 已有缓存结构时立即构建下拉项,不重复访问数据库。
|
||||
- 首次打开且尚无缓存时,下拉先保留“所有列”,结构查询完成后补充列项。
|
||||
- 如果当前业务值非空,现有首次搜索请求同时取得并缓存结构,无需额外加载完整数据。
|
||||
- 弹窗关闭、控件销毁或请求版本已过期时丢弃后台返回结果,不更新已经失效的界面。
|
||||
|
||||
## 数据库搜索
|
||||
|
||||
`ExtendedReturnSupport.BuildSearchSql` 增加可选搜索字段参数:
|
||||
|
||||
- “所有列”:只对所有可见业务列生成 `OR LIKE` 条件。
|
||||
- 指定列:校验字段存在且不是隐藏列,只为该列生成 `LIKE` 条件。
|
||||
- 返回结果仍保留数据源的全部列,包括隐藏技术列,以免破坏 ResultFields 回填。
|
||||
- 继续使用现有 `@lookupKeyword` 参数、LIKE 转义和字段名引用,不把输入文本或下拉显示标题直接拼入 SQL。
|
||||
- 最大返回行数继续保持 100。
|
||||
|
||||
搜索请求必须在提交时同时快照关键字和真实字段名,避免后台查询期间用户切换下拉导致请求含义变化。
|
||||
|
||||
## 本地二次筛选
|
||||
|
||||
共享结果 `GridView` 启用 DevExpress `OptionsView.ShowAutoFilterRow`。
|
||||
|
||||
- 自动筛选只作用于当前绑定的最多 100 行结果,不触发数据库查询。
|
||||
- 每次按回车或点击“查询”发起新的数据库搜索前,清除全部本地筛选条件和旧结果。
|
||||
- 关闭并重新打开弹窗时不保留上一次的本地筛选条件。
|
||||
- 自动筛选后的焦点行仍可通过回车或鼠标点击执行原有 ResultFields 回填。
|
||||
|
||||
## 代码边界
|
||||
|
||||
### `ExtendedReturnSearchPopup`
|
||||
|
||||
- 负责下拉框、输入框、按钮和结果表的布局。
|
||||
- 暴露当前真实搜索字段,不包含 SQL 或业务映射逻辑。
|
||||
- 接收调用方生成的“真实字段名 + 中文标题”选项。
|
||||
- 负责保留有效选择、无效选择回退、清空本地筛选及启用自动筛选行。
|
||||
|
||||
### `ExtendedReturnSupport`
|
||||
|
||||
- 统一生成“所有可见列”或“指定可见列”的参数化搜索 SQL。
|
||||
- 统一判定 `_` 开头的隐藏技术列,避免表格和 MyControl 产生不同规则。
|
||||
- 对不存在、隐藏或空白的指定字段给出明确配置错误。
|
||||
|
||||
### `LabelExtendedReturnSearchEdit`
|
||||
|
||||
- 为 MyControl 173/174 异步加载和缓存数据源结构。
|
||||
- 使用现有业务控件标签生成中文列标题。
|
||||
- 把下拉选择快照带入后台搜索请求。
|
||||
|
||||
### `GridControlEx.ExtendedReturn`
|
||||
|
||||
- 为表格 173/174 异步加载和缓存每个字段的数据源结构。
|
||||
- 使用现有表格列标题翻译逻辑生成中文列标题。
|
||||
- 把下拉选择快照带入现有每列串行查询状态机。
|
||||
|
||||
## 兼容性与错误处理
|
||||
|
||||
- 默认选择“所有列”时,用户操作方式与现有版本一致,但隐藏技术列不再参与模糊搜索。
|
||||
- 173 继续通过模块编号解析 SQL,174 继续直接使用配置 SQL。
|
||||
- 结构查询或业务查询失败时沿用现有提示机制,不能覆盖当前业务值或 ResultFields 字段。
|
||||
- 后台返回旧版本结果时继续丢弃,不覆盖更新的搜索结果。
|
||||
- 清空按钮仍清空当前业务行全部 ResultFields 映射字段并关闭弹窗。
|
||||
- 原业务列仍为只读弹出编辑器,弹窗搜索文本不参与业务字段显示或保存。
|
||||
|
||||
## 验收场景
|
||||
|
||||
1. 首次打开空值控件,只执行结构查询,下拉最终显示“所有列”和所有可见中文列名。
|
||||
2. 选择“所有列”搜索时,SQL 条件只包含非 `_` 开头的列。
|
||||
3. 选择单列搜索时,SQL 条件只包含该真实字段。
|
||||
4. 关闭后重开同一控件,保留上次有效搜索列;数据源缺少该列时回退到“所有列”。
|
||||
5. 新数据库搜索会清除旧自动筛选条件。
|
||||
6. 自动筛选行改变可见结果但不产生数据库请求。
|
||||
7. 筛选后鼠标点击、上下键和回车仍能选择正确 DataRow 并完成 ResultFields 回填。
|
||||
8. `_` 开头的列不显示、不进入下拉、不参与“所有列”搜索,但仍可作为 ResultFields 映射来源。
|
||||
9. 表格和 MyControl 的 173、174 四种组合行为一致。
|
||||
10. 原有清空、显示值翻译、实际值保存和模块数据源加载保持正常。
|
||||
|
||||
## 验证范围
|
||||
|
||||
- 对 SQL 构建规则、隐藏列排除、指定列校验和选择回退进行结构化检查。
|
||||
- 编译 `Lskj.Model`、`Lskj.Util`、`Lskj.Business`、`Lskj.Control`。
|
||||
- 运行时验收由实际 ERP 界面对上述十个场景进行人工验证。
|
||||
@@ -71,24 +71,24 @@ namespace NewMyFormDesigner
|
||||
}
|
||||
|
||||
|
||||
//DialogResult dr = MessageBox.Show("是否为达梦数据库?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
||||
//if (dr == System.Windows.Forms.DialogResult.Yes)
|
||||
//{
|
||||
// if (!string.IsNullOrWhiteSpace(ServerName) && !string.IsNullOrWhiteSpace(DatabaseName) && !string.IsNullOrWhiteSpace(AccountNumber))
|
||||
// {
|
||||
// string connect = "Nzg5REZBQ0IzMjYzQkQzRTZFRTExNjY5MThCNjUwQTVFRUQyMDMxQzI5REIwODY5REIwMkVCQzQ4MTMzRDhDNEU1N0JFREI0MDM3MTQ1MDZGQzdGOEQxQTE4MkQ2QzgyNEE4RkMzRDQzQUM4MzgyOEQ2REZERTIzQzBDMjJGQUE=";
|
||||
// string hostname = Environment.MachineName;
|
||||
// if (!string.IsNullOrWhiteSpace(Password))
|
||||
// {
|
||||
// LinkString = string.Format("Server={0}; schema={1}; UserId={2}; PWD={3};host={4}", ServerName, DatabaseName, AccountNumber, Password, hostname);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// LinkString = string.Format(Lskj.Util.AESUtil.Decrypt(connect), ServerName, DatabaseName, AccountNumber, hostname);
|
||||
// }
|
||||
// connectionType = ConnectionType.DmServer;
|
||||
// }
|
||||
//}
|
||||
DialogResult dr = MessageBox.Show("是否为达梦数据库?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
||||
if (dr == System.Windows.Forms.DialogResult.Yes)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(ServerName) && !string.IsNullOrWhiteSpace(DatabaseName) && !string.IsNullOrWhiteSpace(AccountNumber))
|
||||
{
|
||||
string connect = "Nzg5REZBQ0IzMjYzQkQzRTZFRTExNjY5MThCNjUwQTVFRUQyMDMxQzI5REIwODY5REIwMkVCQzQ4MTMzRDhDNEU1N0JFREI0MDM3MTQ1MDZGQzdGOEQxQTE4MkQ2QzgyNEE4RkMzRDQzQUM4MzgyOEQ2REZERTIzQzBDMjJGQUE=";
|
||||
string hostname = Environment.MachineName;
|
||||
if (!string.IsNullOrWhiteSpace(Password))
|
||||
{
|
||||
LinkString = string.Format("Server={0}; schema={1}; UserId={2}; PWD={3};host={4}", ServerName, DatabaseName, AccountNumber, Password, hostname);
|
||||
}
|
||||
else
|
||||
{
|
||||
LinkString = string.Format(Lskj.Util.AESUtil.Decrypt(connect), ServerName, DatabaseName, AccountNumber, hostname);
|
||||
}
|
||||
connectionType = ConnectionType.DmServer;
|
||||
}
|
||||
}
|
||||
//MessageBox.Show(LinkString);
|
||||
|
||||
|
||||
|
||||
@@ -21,21 +21,21 @@ namespace NewMyFormDesigner
|
||||
{
|
||||
MyFormDesigner myFormDesigner = new MyFormDesigner();
|
||||
|
||||
//myFormDesigner.FrmKey = "{83184D92-F406-487E-9110-2CB991BFA817}";//B32C9D6E-EB85-4CE1-9B81-2B22EDF2D125 56F43621-6C15-4BDD-8870-98D235ECAB91
|
||||
//myFormDesigner.FrmKey = "{D50D2D31-2120-4AE5-9F27-6F363AB6E76C}";//B32C9D6E-EB85-4CE1-9B81-2B22EDF2D125 56F43621-6C15-4BDD-8870-98D235ECAB91
|
||||
|
||||
//myFormDesigner.SelectSQL = @"select b.orderid,b.id as fieldid,fieldname,username1 as username,
|
||||
// fieldsqltag as fieldtypeid,defaultdate as defaultValue
|
||||
// from p_systemDlltab a
|
||||
// left join p_systemwordbooktab b on a.DllCoid=b.tab where a.formkey='{83184D92-F406-487E-9110-2CB991BFA817}' and fieldsqltag<>3 and username1 is not null and isnull(addVisible,0)=0";
|
||||
// left join p_systemwordbooktab b on a.DllCoid=b.tab where a.formkey='{D50D2D31-2120-4AE5-9F27-6F363AB6E76C}' and fieldsqltag<>3 and username1 is not null and isnull(addVisible,0)=0";
|
||||
|
||||
//myFormDesigner.updateSQL = @"update p_systemwordbooktab set controlleft=b.controlleft ,controlTop=b.controlTop, controlHeight=b.controlHeight,controlWidth=b.controlWidth, tabOrder=b.tabOrder from p_systemControlLocation b where p_systemwordbooktab.formKey=b.formKey and p_systemwordbooktab.id=b.fieldId and b.formkey='{83184D92-F406-487E-9110-2CB991BFA817}'";
|
||||
//myFormDesigner.updateSQL = @"update p_systemwordbooktab set controlleft=b.controlleft ,controlTop=b.controlTop, controlHeight=b.controlHeight,controlWidth=b.controlWidth, tabOrder=b.tabOrder from p_systemControlLocation b where p_systemwordbooktab.formKey=b.formKey and p_systemwordbooktab.id=b.fieldId and b.formkey='{D50D2D31-2120-4AE5-9F27-6F363AB6E76C}'";
|
||||
|
||||
|
||||
|
||||
//myFormDesigner.ServerName = "110.185.161.104:5236";
|
||||
//myFormDesigner.ServerName = "222.211.229.79:5238";
|
||||
//myFormDesigner.DatabaseName = "LSERP_JTCS";
|
||||
//myFormDesigner.AccountNumber = "lserpAdmin";
|
||||
//myFormDesigner.Password = "DWlserp1101";//XDerp20210411%
|
||||
//myFormDesigner.Password = "Lserp110";//XDerp20210411%
|
||||
|
||||
//MessageBox.Show(args.Length + "");
|
||||
//MessageBox.Show("1:"+args[0]);
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -162,18 +162,27 @@ namespace Lskj.AutoWordFile
|
||||
}
|
||||
private DataSet Worddata(string modid, int tagid, int mid)
|
||||
{
|
||||
SqlParameter[] param =
|
||||
try
|
||||
{
|
||||
SqlParameter[] param =
|
||||
{
|
||||
new SqlParameter("@modid",SqlDbType.VarChar,15),
|
||||
new SqlParameter("@tagid",SqlDbType.Int),
|
||||
new SqlParameter("@Mid",SqlDbType.Int)
|
||||
|
||||
};
|
||||
param[0].Value = modid;
|
||||
param[1].Value = tagid;
|
||||
param[2].Value = mid;
|
||||
DataSet ds = SqlHelper.ExecuteDataSet(CommandType.StoredProcedure, "pr_system_File01", "#ba_firstpage", param);
|
||||
return ds;
|
||||
param[0].Value = modid;
|
||||
param[1].Value = tagid;
|
||||
param[2].Value = mid;
|
||||
DataSet ds = SqlHelper.ExecuteDataSet(CommandType.StoredProcedure, "pr_system_File01", "#ba_firstpage", param);
|
||||
return ds;
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
}
|
||||
public void Mulu()
|
||||
{
|
||||
|
||||
+10
-6
@@ -13,9 +13,13 @@
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
if (disposing)
|
||||
{
|
||||
components.Dispose();
|
||||
ReleaseResourcesForDispose();
|
||||
if (components != null)
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
@@ -103,7 +107,7 @@
|
||||
this.btnCancel.Name = "btnCancel";
|
||||
this.btnCancel.Size = new System.Drawing.Size(80, 28);
|
||||
this.btnCancel.TabIndex = 4;
|
||||
this.btnCancel.Text = "退出(&C)";
|
||||
this.btnCancel.Text = "退出(C)";
|
||||
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
|
||||
//
|
||||
// btnFileManger
|
||||
@@ -171,7 +175,7 @@
|
||||
this.btnSave.Name = "btnSave";
|
||||
this.btnSave.Size = new System.Drawing.Size(80, 28);
|
||||
this.btnSave.TabIndex = 11;
|
||||
this.btnSave.Text = "保存(&S)";
|
||||
this.btnSave.Text = "保存(S)";
|
||||
this.btnSave.Click += new System.EventHandler(this.btnSave_Click);
|
||||
//
|
||||
// dpb_Tools
|
||||
@@ -454,7 +458,7 @@
|
||||
this.btnClose.Name = "btnClose";
|
||||
this.btnClose.Size = new System.Drawing.Size(58, 23);
|
||||
this.btnClose.TabIndex = 12;
|
||||
this.btnClose.Text = "关闭(&Q)";
|
||||
this.btnClose.Text = "关闭(Q)";
|
||||
this.btnClose.Click += new System.EventHandler(this.btnClose_Click);
|
||||
//
|
||||
// labeltxt_managerAudit
|
||||
@@ -666,4 +670,4 @@
|
||||
private Control.TabControlEx tab_basicInfo;
|
||||
private DevExpress.XtraEditors.DropDownButton btnPrint;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,9 @@ namespace Lskj.BaseAccraditation
|
||||
{
|
||||
public partial class FrmBaseAccraditation : BaseForm
|
||||
{
|
||||
private readonly AltButtonShortcutManager mAltButtonShortcuts =
|
||||
new AltButtonShortcutManager();
|
||||
|
||||
#region 公用变量
|
||||
/// <summary>
|
||||
/// 审批模型
|
||||
@@ -64,6 +67,7 @@ namespace Lskj.BaseAccraditation
|
||||
/// 主表控件
|
||||
/// </summary>
|
||||
public MyControl ControlObj;
|
||||
private bool mResourcesReleased;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -189,6 +193,59 @@ namespace Lskj.BaseAccraditation
|
||||
public FrmBaseAccraditation()
|
||||
{
|
||||
InitializeComponent();
|
||||
InitializeAltButtonShortcuts();
|
||||
}
|
||||
|
||||
private void InitializeAltButtonShortcuts()
|
||||
{
|
||||
mAltButtonShortcuts.Register(btnCancel, Keys.C);
|
||||
mAltButtonShortcuts.Register(btnSave, Keys.S);
|
||||
mAltButtonShortcuts.Register(btnAudit, Keys.Y);
|
||||
mAltButtonShortcuts.Register(btnClose, Keys.Q);
|
||||
mAltButtonShortcuts.Register(btnReturnd, Keys.N);
|
||||
}
|
||||
|
||||
protected override bool ProcessCmdKey(
|
||||
ref System.Windows.Forms.Message msg, Keys keyData)
|
||||
{
|
||||
return mAltButtonShortcuts.ProcessKey(keyData) ||
|
||||
base.ProcessCmdKey(ref msg, keyData);
|
||||
}
|
||||
|
||||
private void ReleaseResourcesForDispose()
|
||||
{
|
||||
if (mResourcesReleased)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mResourcesReleased = true;
|
||||
PrintUtil.OnAfterPrint -= OnReportPrintAfter;
|
||||
|
||||
MyControl control = ControlObj;
|
||||
ControlObj = null;
|
||||
if (control != null)
|
||||
{
|
||||
control.OnDataSourceBindCallBack -=
|
||||
OnControlObjOnDataSourceBindCallBack;
|
||||
control.Dispose();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (tab_basicInfo != null)
|
||||
{
|
||||
tab_basicInfo.ParentControlEx = null;
|
||||
}
|
||||
if (SysModel != null && SysModel.DataCaches != null)
|
||||
{
|
||||
SysModel.DataCaches.RemoveCache(this);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// A partially disposed child must not stop form cleanup.
|
||||
}
|
||||
}
|
||||
|
||||
public override void SetFormSize()
|
||||
@@ -615,7 +672,7 @@ namespace Lskj.BaseAccraditation
|
||||
{
|
||||
this._flowRowData = BaseAuditImpl.GetCurrentFlowRowData(this.ModuleModelObj.MenuTable, this.ModuleModelObj.ParmaryKey, this.SysModel.PrimaryValue);
|
||||
}
|
||||
|
||||
this.UpdateCirculationData();
|
||||
string billType = this._flowRowData != null ? _flowRowData[this.ModuleModelObj.BillType] + "" : "";
|
||||
if (string.IsNullOrEmpty(billType) || billType == "0")
|
||||
{
|
||||
@@ -1443,7 +1500,7 @@ namespace Lskj.BaseAccraditation
|
||||
{
|
||||
this.btnAudit.Enabled = true;
|
||||
this.btnClose.Visible = this.btnRemindAccradit.Visible = this.btnRemindBack.Visible = this.btnSave.Visible = this.btnReturnd.Visible = false;
|
||||
this.btnAudit.Text = "确认(&Y)";
|
||||
this.btnAudit.Text = "确认(Y)";
|
||||
this.label_auditPerson.Text = "确认意见";
|
||||
this.labeltxt_managerAudit.Text = "会签人";
|
||||
this.txt_remark.Text = "确认";
|
||||
@@ -1733,6 +1790,7 @@ namespace Lskj.BaseAccraditation
|
||||
{
|
||||
string printFile = e.Item.Tag + "";
|
||||
this._flowRowData = BaseAuditImpl.GetCurrentFlowRowData(this.ModuleModelObj.MenuTable, this.ModuleModelObj.ParmaryKey, this.SysModel.PrimaryValue);
|
||||
this.UpdateCirculationData();
|
||||
string printPath = PubUtil.PrintFileAbsolutelyPath;
|
||||
if (!File.Exists(printPath))
|
||||
{
|
||||
@@ -1911,6 +1969,7 @@ namespace Lskj.BaseAccraditation
|
||||
if (this.ModuleModelObj.SaveSuccessfullyRefresh && !isSuccess) return;//保存成功才刷新
|
||||
// 刷新主表
|
||||
this._flowRowData = BaseAuditImpl.GetCurrentFlowRowData(this.ModuleModelObj.MenuTable, this.ModuleModelObj.ParmaryKey, this.SysModel.PrimaryValue);
|
||||
this.UpdateCirculationData();
|
||||
this._baseRowData = BaseAuditImpl.GetCurrentControlData(ReplaceHelper.ReplaceWhereCond(ReplaceHelper.ReplaceUserInfo(this.ModuleModelObj.MenuSql)), this.ModuleModelObj.ParmaryKey, this.SysModel.PrimaryValue);
|
||||
if (this._baseRowData == null) this._baseRowData = this._flowRowData;
|
||||
this.ControlObj.CanExecControl = false;
|
||||
@@ -2915,5 +2974,25 @@ namespace Lskj.BaseAccraditation
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新当前流转数据
|
||||
/// </summary>
|
||||
public void UpdateCirculationData()
|
||||
{
|
||||
if (SystemInfo.Instance.IsSpecialAuditSave)
|
||||
{
|
||||
DataTable snapshotTable = this._flowRowData.Table.Clone();
|
||||
DataRow snapshotRow = snapshotTable.NewRow();
|
||||
snapshotRow.ItemArray = (object[])this._flowRowData.ItemArray.Clone();
|
||||
snapshotTable.Rows.Add(snapshotRow);
|
||||
snapshotTable.AcceptChanges();
|
||||
this.ControlObj.beforeData = snapshotRow;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -290,15 +290,16 @@ namespace Lskj.Business.Impl
|
||||
return 1;
|
||||
}
|
||||
|
||||
//2026-08-08 pz说不要判断,工具统一处理
|
||||
//P_MessageToolLinkDllTab表中cardId=-99为通用模块(右侧快捷通道通用模块),默认有权限 2023-12-4 徐成说的cardId=-99的配置
|
||||
string sql = string.Format("select a.*,b.PurviewId,b.MouseOutImg,b.MouseOverImg1 from("
|
||||
+ " select * from P_MessageToolLinkDllTab where cardId=-99 and ( grouptagid=2 or grouptagid=1) "
|
||||
+ ")a join p_formmenuconfigtab b on a.LMenuId=b.MenuId where LinkModeTag=1 and LMenuid='{1}' order by grouptagid,ItemTagId", ERPInfo.Instance.UserId, menuId);
|
||||
DataTable table = SqlHelper.ExecuteDataTable(sql);
|
||||
if (table.Rows.Count > 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
//string sql = string.Format("select a.*,b.PurviewId,b.MouseOutImg,b.MouseOverImg1 from("
|
||||
// + " select * from P_MessageToolLinkDllTab where cardId=-99 and ( grouptagid=2 or grouptagid=1) "
|
||||
// + ")a join p_formmenuconfigtab b on a.LMenuId=b.MenuId where LinkModeTag=1 and LMenuid='{1}' order by grouptagid,ItemTagId", ERPInfo.Instance.UserId, menuId);
|
||||
//DataTable table = SqlHelper.ExecuteDataTable(sql);
|
||||
//if (table.Rows.Count > 0)
|
||||
//{
|
||||
// return 1;
|
||||
//}
|
||||
|
||||
if (ERPInfo.Instance.UserName == ERPInfo.Instance.UserManager)
|
||||
return 1;
|
||||
@@ -1234,7 +1235,7 @@ namespace Lskj.Business.Impl
|
||||
public static bool GetOpenRestrictions(string MenuId)
|
||||
{
|
||||
|
||||
if (BaseImpl.HasExistsColumn("p_formmenuconfigtab", "SingleOpenMode"))
|
||||
if (ERPInfo.Instance.SingleOpenMode)
|
||||
{
|
||||
string sqlValue = string.Format("SELECT SingleOpenMode from p_formmenuconfigtab where MenuId='{0}'", MenuId);
|
||||
DataTable dtTable = SqlHelper.ExecuteDataTable(sqlValue);
|
||||
|
||||
@@ -926,7 +926,15 @@ namespace Lskj.Business.Impl
|
||||
{
|
||||
string field = string.Empty;
|
||||
|
||||
DataTable dataTable = GetTableColumns("p_systembillsourcecond");
|
||||
DataTable dataTable;
|
||||
try
|
||||
{
|
||||
dataTable = InitialParamCache.GetTableColumns("p_systembillsourcecond", delegate { return GetTableColumns("p_systembillsourcecond"); });
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
dataTable = GetTableColumns("p_systembillsourcecond");
|
||||
}
|
||||
|
||||
if (dataTable.Columns.Contains("FontSize"))
|
||||
{
|
||||
@@ -1015,6 +1023,7 @@ namespace Lskj.Business.Impl
|
||||
/// <exception cref="System.NotImplementedException"></exception>
|
||||
public static DataTable GetSchemesList(int moduleId)
|
||||
{
|
||||
if (moduleId <= 0) return new DataTable();
|
||||
try
|
||||
{
|
||||
string sqlValue = "select * from P_SystemReportProjectTab where ProjectMode=1 and operatorId=@userid and ModuleId=@moduleId";
|
||||
@@ -1059,6 +1068,28 @@ namespace Lskj.Business.Impl
|
||||
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;
|
||||
}
|
||||
/// <summary>
|
||||
@@ -1119,7 +1150,16 @@ namespace Lskj.Business.Impl
|
||||
switch (type)
|
||||
{
|
||||
case ModuleType.MrpClickBtn:
|
||||
if (BaseImpl.HasExistsColumn("P_systempopupmenu", "isMrpClickBtn", "int"))
|
||||
bool isMrpClickBtnExists;
|
||||
try
|
||||
{
|
||||
isMrpClickBtnExists = InitialParamCache.GetColumnExists("P_systempopupmenu", "isMrpClickBtn", "int", delegate { return BaseImpl.HasExistsColumn("P_systempopupmenu", "isMrpClickBtn", "int"); });
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
isMrpClickBtnExists = BaseImpl.HasExistsColumn("P_systempopupmenu", "isMrpClickBtn", "int");
|
||||
}
|
||||
if (isMrpClickBtnExists)
|
||||
{
|
||||
where = " and isnull(isMrpClickBtn,0)=1 and visible1=0 ";
|
||||
}
|
||||
@@ -1146,26 +1186,86 @@ namespace Lskj.Business.Impl
|
||||
where = " and isnull(menutype,0)=0";
|
||||
break;
|
||||
}
|
||||
string sqlTemplate = @"WITH UserRoles AS (
|
||||
SELECT r.roleName
|
||||
FROM p_systemRoleOperSetTab AS ro
|
||||
JOIN p_systemRoleSetTab AS r ON r.id = ro.roleId
|
||||
WHERE ro.operatorname = '{0}'
|
||||
)
|
||||
SELECT pm.*
|
||||
FROM P_systempopupmenu AS pm WITH (NOLOCK)
|
||||
WHERE ISNULL(pm.visible, 0) = 0
|
||||
AND pm.tab = '{1}'
|
||||
AND (
|
||||
ISNULL(pm.privilegeOper, '') = ''
|
||||
OR CHARINDEX(',' + '{0}' + ',', ',' + pm.privilegeOper + ',') > 0
|
||||
OR EXISTS (
|
||||
SELECT 1
|
||||
FROM UserRoles AS ur
|
||||
WHERE CHARINDEX('{{&' + ur.roleName + '&}}', pm.privilegeOper) > 0)
|
||||
) {2} ORDER BY pm.orderid;";
|
||||
string sqlValue = string.Format(sqlTemplate, ERPInfo.Instance.UserName, key, where);
|
||||
return SqlHelper.ExecuteDataTable(sqlValue);
|
||||
string sqlValue = string.Format(@"SELECT pm.*
|
||||
FROM P_systempopupmenu AS pm WITH (NOLOCK)
|
||||
WHERE ISNULL(pm.visible, 0) = 0
|
||||
AND pm.tab = @tab {0}
|
||||
ORDER BY pm.orderid;", where);
|
||||
DataTable rightMenuTable = SqlHelper.ExecuteDataTable(sqlValue,
|
||||
new SqlParameter[] { new SqlParameter("@tab", key) });
|
||||
|
||||
return FilterRowsByOperatorPrivilege(rightMenuTable, "privilegeOper");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据人员或角色权限过滤配置数据,只有存在角色配置时才读取角色表。
|
||||
/// </summary>
|
||||
internal static DataTable FilterRowsByOperatorPrivilege(DataTable sourceTable, string privilegeField)
|
||||
{
|
||||
if (sourceTable == null || !sourceTable.Columns.Contains(privilegeField))
|
||||
{
|
||||
return sourceTable;
|
||||
}
|
||||
|
||||
string operatorName = ERPInfo.Instance.UserName;
|
||||
string operatorToken = "," + operatorName + ",";
|
||||
List<DataRow> rolePermissionRows = new List<DataRow>();
|
||||
HashSet<DataRow> allowedRows = new HashSet<DataRow>();
|
||||
foreach (DataRow row in sourceTable.Rows)
|
||||
{
|
||||
string privilegeOper = row[privilegeField] + "";
|
||||
if (string.IsNullOrWhiteSpace(privilegeOper) ||
|
||||
("," + privilegeOper + ",").IndexOf(operatorToken, StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
{
|
||||
allowedRows.Add(row);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 只配置人员且当前人员不匹配时,无需读取角色表。
|
||||
if (privilegeOper.IndexOf("{&", StringComparison.Ordinal) >= 0 &&
|
||||
privilegeOper.IndexOf("&}", StringComparison.Ordinal) >= 0)
|
||||
{
|
||||
rolePermissionRows.Add(row);
|
||||
}
|
||||
}
|
||||
|
||||
if (rolePermissionRows.Count == 0)
|
||||
{
|
||||
DataTable resultTable = sourceTable.Clone();
|
||||
foreach (DataRow row in sourceTable.Rows)
|
||||
{
|
||||
if (allowedRows.Contains(row)) resultTable.ImportRow(row);
|
||||
}
|
||||
return resultTable;
|
||||
}
|
||||
|
||||
string roleSql = @"SELECT r.roleName
|
||||
FROM p_systemRoleOperSetTab AS ro
|
||||
JOIN p_systemRoleSetTab AS r ON r.id = ro.roleId
|
||||
WHERE ro.operatorname = @operatorname";
|
||||
DataTable roleTable = SqlHelper.ExecuteDataTable(roleSql,
|
||||
new SqlParameter[] { new SqlParameter("@operatorname", operatorName) });
|
||||
string[] roleTokens = roleTable.Rows.Cast<DataRow>()
|
||||
.Select(row => row["roleName"] + "")
|
||||
.Where(roleName => !string.IsNullOrWhiteSpace(roleName))
|
||||
.Select(roleName => "{&" + roleName + "&}")
|
||||
.ToArray();
|
||||
|
||||
foreach (DataRow row in rolePermissionRows)
|
||||
{
|
||||
string privilegeOper = row[privilegeField] + "";
|
||||
if (roleTokens.Any(token => privilegeOper.IndexOf(token, StringComparison.OrdinalIgnoreCase) >= 0))
|
||||
{
|
||||
allowedRows.Add(row);
|
||||
}
|
||||
}
|
||||
|
||||
DataTable resultTableWithRoles = sourceTable.Clone();
|
||||
foreach (DataRow row in sourceTable.Rows)
|
||||
{
|
||||
if (allowedRows.Contains(row)) resultTableWithRoles.ImportRow(row);
|
||||
}
|
||||
return resultTableWithRoles;
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取单个右键菜单
|
||||
@@ -1272,7 +1372,73 @@ namespace Lskj.Business.Impl
|
||||
p[1].Value = menuCode;
|
||||
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。
|
||||
/// 仅当窗体包含 173/174 扩展返回控件时按模块补取,普通窗体不增加查询。
|
||||
/// </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 != 173 && fieldType != 174))
|
||||
{
|
||||
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>
|
||||
/// <para>说明:获取添加界面多标签</para>
|
||||
@@ -1313,26 +1479,14 @@ namespace Lskj.Business.Impl
|
||||
{
|
||||
try
|
||||
{
|
||||
string sqlTemplate = @"WITH UserRoles AS (
|
||||
SELECT r.roleName
|
||||
FROM p_systemRoleOperSetTab AS ro
|
||||
JOIN p_systemRoleSetTab AS r ON r.id = ro.roleId
|
||||
WHERE ro.operatorname = '{0}'
|
||||
)
|
||||
SELECT pm.*
|
||||
FROM p_systemDlltabDetail AS pm WITH (NOLOCK)
|
||||
WHERE ISNULL(pm.isvisible, 0) = 0
|
||||
AND pm.tab = '{1}'
|
||||
AND (
|
||||
ISNULL(pm.privilegeOper, '') = ''
|
||||
OR CHARINDEX(',' + '{0}' + ',', ',' + pm.privilegeOper + ',') > 0
|
||||
OR EXISTS (
|
||||
SELECT 1
|
||||
FROM UserRoles AS ur
|
||||
WHERE CHARINDEX('{{&' + ur.roleName + '&}}', pm.privilegeOper) > 0)
|
||||
) ORDER BY pm.orderid;";
|
||||
string sqlValue = string.Format(sqlTemplate, ERPInfo.Instance.UserName, menuCode);
|
||||
return SqlHelper.ExecuteDataTable(sqlValue);
|
||||
string sqlValue = @"SELECT pm.*
|
||||
FROM p_systemDlltabDetail AS pm WITH (NOLOCK)
|
||||
WHERE ISNULL(pm.isvisible, 0) = 0
|
||||
AND pm.tab = @tab
|
||||
ORDER BY pm.orderid;";
|
||||
DataTable detailPageTable = SqlHelper.ExecuteDataTable(sqlValue,
|
||||
new SqlParameter[] { new SqlParameter("@tab", menuCode) });
|
||||
return FilterRowsByOperatorPrivilege(detailPageTable, "privilegeOper");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
@@ -1427,7 +1581,19 @@ namespace Lskj.Business.Impl
|
||||
//保存条件表
|
||||
public static DataTable GetClientCond(string MenuCode)
|
||||
{
|
||||
if (BaseImpl.HasExistsTable("P_SystemClientCondTab"))
|
||||
const string tableName = "P_SystemClientCondTab";
|
||||
bool tableExists;
|
||||
try
|
||||
{
|
||||
tableExists = InitialParamCache.GetTableExists(tableName, delegate { return BaseImpl.HasExistsTable(tableName); });
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// 缓存未能正常读取或记录时,重新查询,避免影响原有功能。
|
||||
tableExists = BaseImpl.HasExistsTable(tableName);
|
||||
}
|
||||
|
||||
if (tableExists)
|
||||
{
|
||||
string sqlValue = string.Format(@"select * from P_SystemClientCondTab where tab='{0}' and disableflag=0 order by orderid ", MenuCode);
|
||||
return GetDataTableResult(sqlValue);
|
||||
@@ -1436,4 +1602,4 @@ namespace Lskj.Business.Impl
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -461,6 +461,8 @@ namespace Lskj.Business.Impl
|
||||
sumCond += ",a.ColumnAnnotation ";
|
||||
if (dataTable.Columns.Contains("TitleColor"))
|
||||
sumCond += ",a.TitleColor ";
|
||||
if (dataTable.Columns.Contains("resultfields"))
|
||||
sumCond += ",a.resultfields ";
|
||||
|
||||
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,
|
||||
@@ -559,6 +561,8 @@ namespace Lskj.Business.Impl
|
||||
sumCond += ",a.ColumnAnnotation ";
|
||||
if (dataTable.Columns.Contains("TitleColor"))
|
||||
sumCond += ",a.TitleColor ";
|
||||
if (dataTable.Columns.Contains("resultfields"))
|
||||
sumCond += ",a.resultfields ";
|
||||
|
||||
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,
|
||||
@@ -673,33 +677,37 @@ namespace Lskj.Business.Impl
|
||||
conditions = "and isnull(mxflag,0)=0";
|
||||
}
|
||||
string cond = !string.IsNullOrEmpty(sourceCond) ? string.Format(" and id in ({0})", sourceCond.Trim(',')) : string.Empty;
|
||||
string sqlValue = string.Format(@"WITH UserRoles AS (
|
||||
SELECT r.roleName
|
||||
FROM p_systemRoleOperSetTab AS ro
|
||||
JOIN p_systemRoleSetTab AS r ON r.id = ro.roleId
|
||||
WHERE ro.operatorname = '{0}'
|
||||
)
|
||||
select * from p_systembillsource where typeCode=@typeCode" + cond +
|
||||
@" and isnull(isVisible,0)=0 and (isnull(viewOper,'')='' or CHARINDEX(',' + '{0}' + ',', ',' + viewOper + ',')>0 OR EXISTS (
|
||||
SELECT 1 FROM UserRoles AS ur WHERE CHARINDEX('{{&' + ur.roleName + '&}}', viewOper) > 0)) order by orderid", ERPInfo.Instance.UserName);
|
||||
string sqlDetail = string.Format(@"WITH UserRoles AS (
|
||||
SELECT r.roleName
|
||||
FROM p_systemRoleOperSetTab AS ro
|
||||
JOIN p_systemRoleSetTab AS r ON r.id = ro.roleId
|
||||
WHERE ro.operatorname = '{1}'
|
||||
)
|
||||
SELECT id,sourceId,fieldName,sysName,userName,orderid,isVisible,sourceKey,privilegeView,DataFormat,isSum,ifmerge,{2}
|
||||
string sqlValue = @"select * from p_systembillsource
|
||||
where typeCode=@typeCode" + cond + @"
|
||||
and isnull(isVisible,0)=0
|
||||
order by orderid";
|
||||
DataTable sourceTable = SqlHelper.ExecuteDataTable(sqlValue,
|
||||
new SqlParameter[] { new SqlParameter("@typeCode", menuCode) });
|
||||
sourceTable = BaseModuleImpl.FilterRowsByOperatorPrivilege(sourceTable, "viewOper");
|
||||
htTable["master"] = sourceTable;
|
||||
|
||||
string sqlDetail = string.Format(@"SELECT id,sourceId,fieldName,sysName,userName,orderid,isVisible,sourceKey,privilegeView,DataFormat,isSum,ifmerge,{2}
|
||||
isnull(CASE WHEN isVisible=1 OR (ISNULL(b.userList,'')='' AND ISNULL(a.PrivilegeView,'')<>'') THEN 0 ELSE width END,0) width
|
||||
FROM p_systembillsourcedetail a
|
||||
LEFT JOIN (
|
||||
SELECT userList,privTypeId from p_systemPrivilege b where modId = '{0}'
|
||||
AND CHARINDEX(',' + '{1}' + ',', ',' + userList + ',') > 0
|
||||
) b on CHARINDEX(',' + CAST(b.privTypeId AS VARCHAR(5)) + ',',',' + PrivilegeView + ',') > 0
|
||||
where sourceId in (select id from p_systembillsource where typeCode=@typeCode" + cond + @" and isnull(isVisible,0)=0 and (isnull(viewOper,'')='' or CHARINDEX(',' + '{1}' + ',', ',' + viewOper + ',')>0) OR EXISTS (
|
||||
SELECT 1 FROM UserRoles AS ur WHERE CHARINDEX('{{&' + ur.roleName + '&}}', viewOper) > 0)) {3} ", menuCode, ERPInfo.Instance.UserName, otherfield, conditions);
|
||||
htTable["master"] = SqlHelper.ExecuteDataTable(sqlValue, new SqlParameter[] { new SqlParameter("@typeCode", menuCode) });
|
||||
where sourceId in (select id from p_systembillsource where typeCode=@typeCode" + cond + @" and isnull(isVisible,0)=0) {3} ", menuCode, ERPInfo.Instance.UserName, otherfield, conditions);
|
||||
|
||||
DataTable detailTable= SqlHelper.ExecuteDataTable(sqlDetail, new SqlParameter[] { new SqlParameter("@typeCode", menuCode) });
|
||||
HashSet<string> sourceIds = new HashSet<string>(
|
||||
sourceTable.Rows.Cast<DataRow>().Select(row => row["id"] + ""));
|
||||
if (detailTable != null && detailTable.Rows.Count > 0)
|
||||
{
|
||||
DataTable allowedDetailTable = detailTable.Clone();
|
||||
foreach (DataRow row in detailTable.Rows)
|
||||
{
|
||||
if (sourceIds.Contains(row["sourceId"] + "")) allowedDetailTable.ImportRow(row);
|
||||
}
|
||||
detailTable = allowedDetailTable;
|
||||
}
|
||||
|
||||
// order by sourceId,orderid 数据库不排序,在表格中排序(解决慢查询)
|
||||
if (detailTable != null && detailTable.Rows.Count > 0)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
|
||||
namespace Lskj.Business.Impl
|
||||
{
|
||||
/// <summary>
|
||||
/// 单次模块初始化期间复用的参数缓存。
|
||||
/// </summary>
|
||||
public static class InitialParamCache
|
||||
{
|
||||
private static readonly object SyncRoot = new object();
|
||||
private static readonly Dictionary<string, bool> TableExistsCache =
|
||||
new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
|
||||
private static readonly Dictionary<string, bool> ColumnExistsCache =
|
||||
new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
|
||||
private static readonly Dictionary<string, DataTable> TableColumnsCache =
|
||||
new Dictionary<string, DataTable>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
/// <summary>
|
||||
/// 获取表是否存在。没有缓存时执行查询,并记录查询结果。
|
||||
/// </summary>
|
||||
public static bool GetTableExists(string tableName, Func<bool> query)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(tableName))
|
||||
{
|
||||
throw new ArgumentException("表名不能为空。", "tableName");
|
||||
}
|
||||
if (query == null)
|
||||
{
|
||||
throw new ArgumentNullException("query");
|
||||
}
|
||||
|
||||
lock (SyncRoot)
|
||||
{
|
||||
bool tableExists;
|
||||
if (TableExistsCache.TryGetValue(tableName, out tableExists))
|
||||
{
|
||||
return tableExists;
|
||||
}
|
||||
|
||||
tableExists = query();
|
||||
TableExistsCache[tableName] = tableExists;
|
||||
return tableExists;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取字段是否存在。没有缓存时执行查询,并记录查询结果。
|
||||
/// </summary>
|
||||
public static bool GetColumnExists(string tableName, string columnName, string columnType, Func<bool> query)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(tableName))
|
||||
{
|
||||
throw new ArgumentException("表名不能为空。", "tableName");
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(columnName))
|
||||
{
|
||||
throw new ArgumentException("字段名不能为空。", "columnName");
|
||||
}
|
||||
if (query == null)
|
||||
{
|
||||
throw new ArgumentNullException("query");
|
||||
}
|
||||
|
||||
string cacheKey = tableName + "|" + columnName + "|" + (columnType ?? string.Empty);
|
||||
lock (SyncRoot)
|
||||
{
|
||||
bool columnExists;
|
||||
if (ColumnExistsCache.TryGetValue(cacheKey, out columnExists))
|
||||
{
|
||||
return columnExists;
|
||||
}
|
||||
|
||||
columnExists = query();
|
||||
ColumnExistsCache[cacheKey] = columnExists;
|
||||
return columnExists;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取表结构。没有缓存时执行查询,并缓存不包含数据的结构模板。
|
||||
/// </summary>
|
||||
public static DataTable GetTableColumns(string tableName, Func<DataTable> query)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(tableName))
|
||||
{
|
||||
throw new ArgumentException("表名不能为空。", "tableName");
|
||||
}
|
||||
if (query == null)
|
||||
{
|
||||
throw new ArgumentNullException("query");
|
||||
}
|
||||
|
||||
lock (SyncRoot)
|
||||
{
|
||||
DataTable tableColumns;
|
||||
if (!TableColumnsCache.TryGetValue(tableName, out tableColumns))
|
||||
{
|
||||
DataTable queryResult = query();
|
||||
if (queryResult == null)
|
||||
{
|
||||
throw new InvalidOperationException("获取表结构失败。" + tableName);
|
||||
}
|
||||
|
||||
tableColumns = queryResult.Clone();
|
||||
TableColumnsCache[tableName] = tableColumns;
|
||||
}
|
||||
|
||||
return tableColumns.Clone();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清空上一次模块初始化记录的参数。
|
||||
/// </summary>
|
||||
public static void Clear()
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
TableExistsCache.Clear();
|
||||
ColumnExistsCache.Clear();
|
||||
TableColumnsCache.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -42,18 +42,18 @@ namespace Lskj.Business
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!BaseImpl.HasExistsColumn("P_LogTab", "IPAddress"))
|
||||
{
|
||||
SqlHelper.ExecuteNonQuery("alter table P_LogTab add IPAddress varchar(500)");
|
||||
}
|
||||
if (!BaseImpl.HasExistsColumn("P_LogTab", "MacAddress"))
|
||||
{
|
||||
SqlHelper.ExecuteNonQuery("alter table P_LogTab add MacAddress varchar(500)");
|
||||
}
|
||||
if (!BaseImpl.HasExistsColumn("P_LogTab", "ModuleId"))
|
||||
{
|
||||
SqlHelper.ExecuteNonQuery("alter table P_LogTab add ModuleId varchar(500)");
|
||||
}
|
||||
//if (!BaseImpl.HasExistsColumn("P_LogTab", "IPAddress"))
|
||||
//{
|
||||
// SqlHelper.ExecuteNonQuery("alter table P_LogTab add IPAddress varchar(500)");
|
||||
//}
|
||||
//if (!BaseImpl.HasExistsColumn("P_LogTab", "MacAddress"))
|
||||
//{
|
||||
// SqlHelper.ExecuteNonQuery("alter table P_LogTab add MacAddress varchar(500)");
|
||||
//}
|
||||
//if (!BaseImpl.HasExistsColumn("P_LogTab", "ModuleId"))
|
||||
//{
|
||||
// SqlHelper.ExecuteNonQuery("alter table P_LogTab add ModuleId varchar(500)");
|
||||
//}
|
||||
|
||||
//string ModuleCode = string.Empty;
|
||||
//string ModuleId = string.Empty;
|
||||
@@ -108,14 +108,14 @@ namespace Lskj.Business
|
||||
string exmessage = Regex.Replace(ex.Message, "'", "''");
|
||||
|
||||
|
||||
if (!BaseImpl.HasExistsColumn("p_errlogtab", "IPAddress"))
|
||||
{
|
||||
SqlHelper.ExecuteNonQuery("alter table p_errlogtab add IPAddress varchar(500)");
|
||||
}
|
||||
if (!BaseImpl.HasExistsColumn("p_errlogtab", "MacAddress"))
|
||||
{
|
||||
SqlHelper.ExecuteNonQuery("alter table p_errlogtab add MacAddress varchar(500)");
|
||||
}
|
||||
//if (!BaseImpl.HasExistsColumn("p_errlogtab", "IPAddress"))
|
||||
//{
|
||||
// SqlHelper.ExecuteNonQuery("alter table p_errlogtab add IPAddress varchar(500)");
|
||||
//}
|
||||
//if (!BaseImpl.HasExistsColumn("p_errlogtab", "MacAddress"))
|
||||
//{
|
||||
// SqlHelper.ExecuteNonQuery("alter table p_errlogtab add MacAddress varchar(500)");
|
||||
//}
|
||||
|
||||
string sqlValue = string.Format("insert into p_errlogtab(Operatedate,Operator,Content,ErrMsg,Ws,IPAddress,MacAddress) values(getdate(),'{0}','{1}','{2}','{3}','{4}','{5}')",
|
||||
ERPInfo.Instance.UserName, content, exmessage + "\r\n" + ex.StackTrace, ERPInfo.Instance.WindowName, ERPInfo.Instance.LoginIPV4, ERPInfo.Instance.MacAddress);
|
||||
|
||||
@@ -293,6 +293,27 @@ namespace Lskj.Business.Impl
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录修改后的密码
|
||||
/// </summary>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="afterPass"></param>
|
||||
/// <returns></returns>
|
||||
public static bool RecordPassword(string afterPass,string text)
|
||||
{
|
||||
try
|
||||
{
|
||||
//加密密码
|
||||
afterPass = AESUtil.Encrypt(afterPass);
|
||||
LogUtil.WriteDebug("", text, afterPass, "");
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -642,6 +663,37 @@ namespace Lskj.Business.Impl
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取菜单是否使用 BS 网页方式打开。
|
||||
/// </summary>
|
||||
/// <param name="menuId">菜单 ID。</param>
|
||||
/// <returns>1 表示使用 BS 网页方式打开;其他值按原 CS 方式打开。</returns>
|
||||
public static int GetBsOpenMode(string menuId)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(menuId) || !HasExistsColumn("P_FormMenuConfigTab", "BsOpenMode"))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
const string sqlValue = @"select ISNULL(BsOpenMode,0) as BsOpenMode
|
||||
from P_FormMenuConfigTab
|
||||
where MenuId=@MenuId";
|
||||
DataTable dataTable = SqlHelper.ExecuteDataTable(
|
||||
sqlValue,
|
||||
new SqlParameter("@MenuId", menuId));
|
||||
int bsOpenMode;
|
||||
return dataTable.Rows.Count > 0 &&
|
||||
int.TryParse(dataTable.Rows[0]["BsOpenMode"] + "", out bsOpenMode)
|
||||
? bsOpenMode
|
||||
: 0;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// <para>说明:根据配置MenuType加载菜单</para>
|
||||
/// <para>创建人:龚宇超</para>
|
||||
/// <para>创建日期:2017-08-16 </para>
|
||||
@@ -1337,4 +1389,4 @@ namespace Lskj.Business.Impl
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Text;
|
||||
using System.Data.SqlClient;
|
||||
using Lskj.Util;
|
||||
using Lskj.Model;
|
||||
using Lskj.Core;
|
||||
|
||||
namespace Lskj.Business.Impl
|
||||
{
|
||||
@@ -202,6 +203,26 @@ namespace Lskj.Business.Impl
|
||||
public static bool SaveRoleOperDate(string OperId, string OperName, string departemnt, string readdate, string editdate)
|
||||
{
|
||||
string sqlValue = string.Format(" if exists (select * from p_systemRoleOperSetTab s where s.operatorid='{0}' and roleId='0' ) update p_systemRoleOperSetTab set ReadPurview='{4}',EditPurview='{5}' where operatorid = '{0}' and roleId='0' ELSE insert into p_systemRoleOperSetTab (roleId,roleOperatorId,operatorid,operatorname,operatedate,department,ReadPurview,EditPurview) values ('0','{0}','{0}','{1}','{2}','{3}','{4}','{5}')", OperId, OperName, DateTime.Now, departemnt, readdate, editdate);
|
||||
|
||||
if (SqlHelper.ConnectionType == ConnectionType.DmServer)
|
||||
{
|
||||
string dmOperId = (OperId ?? string.Empty).Replace("'", "''");
|
||||
string dmOperName = (OperName ?? string.Empty).Replace("'", "''");
|
||||
string dmDepartment = (departemnt ?? string.Empty).Replace("'", "''");
|
||||
string dmReadDate = (readdate ?? string.Empty).Replace("'", "''");
|
||||
string dmEditDate = (editdate ?? string.Empty).Replace("'", "''");
|
||||
|
||||
sqlValue = string.Format(@"
|
||||
MERGE INTO p_systemRoleOperSetTab t
|
||||
USING (SELECT '{0}' operatorid, '0' roleId FROM DUAL) s
|
||||
ON (t.operatorid = s.operatorid AND t.roleId = s.roleId)
|
||||
WHEN MATCHED THEN
|
||||
UPDATE SET ReadPurview = '{3}', EditPurview = '{4}'
|
||||
WHEN NOT MATCHED THEN
|
||||
INSERT (roleId, roleOperatorId, operatorid, operatorname, operatedate, department, ReadPurview, EditPurview)
|
||||
VALUES ('0', '{0}', '{0}', '{1}', SYSDATE, '{2}', '{3}', '{4}')",
|
||||
dmOperId, dmOperName, dmDepartment, dmReadDate, dmEditDate);
|
||||
}
|
||||
return ExecSqlValue(sqlValue) > 0;
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ using System.Xml;
|
||||
using Lskj.Business.Impl;
|
||||
using Lskj.Core;
|
||||
using Lskj.Model;
|
||||
using Lskj.Data;
|
||||
|
||||
namespace Lskj.Business
|
||||
{
|
||||
@@ -65,6 +66,9 @@ namespace Lskj.Business
|
||||
|
||||
if (item.Table.Columns.Contains("UpdateAddressXp") && ERPInfo.Instance.SystemVersion.Contains("Windows XP"))
|
||||
Instance.UpdateAddress = !string.IsNullOrEmpty(item["UpdateAddressXp"] + "") ? item["UpdateAddressXp"] + "" : "";
|
||||
//内网对应的升级地址
|
||||
Instance.UpdateAddress = DBConfig.Instance.IsInternalNetwork && item.Table.Columns.Contains("InternalUpdateAddress") && !string.IsNullOrEmpty(item["InternalUpdateAddress"] + "") ? item["InternalUpdateAddress"] + "" : Instance.UpdateAddress;
|
||||
|
||||
|
||||
|
||||
Instance.OAUrl = DBConfig.Instance.Internet && item.Table.Columns.Contains("localOAUrl") && !string.IsNullOrEmpty(item["localOAUrl"] + "") ? item["localOAUrl"] + "" : item["OAUrl"] + "";
|
||||
@@ -330,6 +334,14 @@ namespace Lskj.Business
|
||||
Instance.LoginUsername = item.Table.Columns.Contains("LoginUsername") && !string.IsNullOrEmpty(item["LoginUsername"] + "") ? item["LoginUsername"] + "" : "";
|
||||
Instance.MainLeftShowMode = item.Table.Columns.Contains("MainLeftShowMode") && !string.IsNullOrEmpty(item["MainLeftShowMode"] + "") ? item["MainLeftShowMode"] + "" : "";
|
||||
Instance.DeadlockPrompt = item.Table.Columns.Contains("DeadlockPrompt") && !string.IsNullOrEmpty(item["DeadlockPrompt"] + "") ? item["DeadlockPrompt"] + "" : "";
|
||||
Instance.SpecialAttachmentBrowser = item.Table.Columns.Contains("SpecialAttachmentBrowser") && !string.IsNullOrEmpty(item["SpecialAttachmentBrowser"] + "") ? "1".Equals(item["SpecialAttachmentBrowser"] + "") : false;
|
||||
if (Instance.SpecialAttachmentBrowser)
|
||||
{
|
||||
ResourceDynamic.PubBrower = System.Environment.OSVersion.Version.Major == 5 && (System.Environment.OSVersion.Version.Minor == 1 || System.Environment.OSVersion.Version.Minor == 2) ? "Lskj.PubBrowerXp.dll" : "Lskj.PubBrower2.dll";
|
||||
}
|
||||
Instance.IsSpecialAuditSave = item.Table.Columns.Contains("IsSpecialAuditSave") && !string.IsNullOrEmpty(item["IsSpecialAuditSave"] + "") ? "1".Equals(item["IsSpecialAuditSave"] + "") : false;
|
||||
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 高拍仪AccessKey
|
||||
@@ -1154,6 +1166,18 @@ namespace Lskj.Business
|
||||
/// 死锁提示
|
||||
/// </summary>
|
||||
public string DeadlockPrompt;
|
||||
|
||||
/// <summary>
|
||||
/// 附件按钮打开Lskj.PubBrower2.dll
|
||||
/// </summary>
|
||||
public bool SpecialAttachmentBrowser;
|
||||
/// <summary>
|
||||
/// 特殊审核保存模式(修改语句只拼接修改后的控件)
|
||||
/// </summary>
|
||||
public bool IsSpecialAuditSave;
|
||||
/// <summary>
|
||||
/// 默认权限模块
|
||||
/// P_MessageToolLinkDllTab表中cardId=-99为通用模块(右侧快捷通道通用模块) 2023-12-4 徐成说的cardId=-99的配置
|
||||
/// </summary>
|
||||
//public DataTable DefaultPermissionTable;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,6 +87,7 @@
|
||||
<Compile Include="Impl\BillImpl.cs" />
|
||||
<Compile Include="Impl\ConditionalCaching.cs" />
|
||||
<Compile Include="Impl\ErrorMessage.cs" />
|
||||
<Compile Include="Impl\InitialParamCache.cs" />
|
||||
<Compile Include="Impl\LanguageTranslation.cs" />
|
||||
<Compile Include="Impl\MainImpl.cs" />
|
||||
<Compile Include="Impl\BillAuditImpl.cs" />
|
||||
|
||||
Generated
+15
-10
@@ -13,9 +13,14 @@
|
||||
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
if (disposing)
|
||||
{
|
||||
components.Dispose();
|
||||
Lskj.Control.Model.PrintUtil.OnAfterPrint -=
|
||||
new System.EventHandler(OnReportPrintAfter);
|
||||
if (components != null)
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
@@ -170,7 +175,7 @@
|
||||
this.btnClose.Name = "btnClose";
|
||||
this.btnClose.Size = new System.Drawing.Size(75, 26);
|
||||
this.btnClose.TabIndex = 22;
|
||||
this.btnClose.Text = "关闭(&Q)";
|
||||
this.btnClose.Text = "关闭(Q)";
|
||||
//
|
||||
// btnBack
|
||||
//
|
||||
@@ -182,7 +187,7 @@
|
||||
this.btnBack.Name = "btnBack";
|
||||
this.btnBack.Size = new System.Drawing.Size(75, 26);
|
||||
this.btnBack.TabIndex = 21;
|
||||
this.btnBack.Text = "返退(&N)";
|
||||
this.btnBack.Text = "返退(N)";
|
||||
this.btnBack.Click += new System.EventHandler(this.btnReturn_Click);
|
||||
//
|
||||
// btnSave
|
||||
@@ -195,7 +200,7 @@
|
||||
this.btnSave.Name = "btnSave";
|
||||
this.btnSave.Size = new System.Drawing.Size(75, 26);
|
||||
this.btnSave.TabIndex = 25;
|
||||
this.btnSave.Text = "保存(&S)";
|
||||
this.btnSave.Text = "保存(S)";
|
||||
this.btnSave.Click += new System.EventHandler(this.btnSave_Click);
|
||||
//
|
||||
// btnAccradit
|
||||
@@ -208,7 +213,7 @@
|
||||
this.btnAccradit.Name = "btnAccradit";
|
||||
this.btnAccradit.Size = new System.Drawing.Size(75, 26);
|
||||
this.btnAccradit.TabIndex = 20;
|
||||
this.btnAccradit.Text = "审核(&Y)";
|
||||
this.btnAccradit.Text = "审核(Y)";
|
||||
this.btnAccradit.Click += new System.EventHandler(this.btnAccradit_Click);
|
||||
//
|
||||
// btnPrint
|
||||
@@ -251,7 +256,7 @@
|
||||
this.btnSpare.Name = "btnSpare";
|
||||
this.btnSpare.Size = new System.Drawing.Size(75, 26);
|
||||
this.btnSpare.TabIndex = 27;
|
||||
this.btnSpare.Text = "分单(&P)";
|
||||
this.btnSpare.Text = "分单(P)";
|
||||
this.btnSpare.Click += new System.EventHandler(this.btnSpare_Click);
|
||||
//
|
||||
// pcTool
|
||||
@@ -376,7 +381,7 @@
|
||||
this.btnReflash.Name = "btnReflash";
|
||||
this.btnReflash.Size = new System.Drawing.Size(75, 26);
|
||||
this.btnReflash.TabIndex = 27;
|
||||
this.btnReflash.Text = "刷新(&R)";
|
||||
this.btnReflash.Text = "刷新(R)";
|
||||
this.btnReflash.Click += new System.EventHandler(this.btnReflash_Click);
|
||||
//
|
||||
// panelControl1
|
||||
@@ -518,7 +523,7 @@
|
||||
this.btnSearch.Name = "btnSearch";
|
||||
this.btnSearch.Size = new System.Drawing.Size(72, 26);
|
||||
this.btnSearch.TabIndex = 6;
|
||||
this.btnSearch.Text = "搜索(&Q)";
|
||||
this.btnSearch.Text = "搜索(Q)";
|
||||
this.btnSearch.Click += new System.EventHandler(this.btnSearch_Click);
|
||||
//
|
||||
// labeldate_end
|
||||
@@ -566,7 +571,7 @@
|
||||
this.btnBackTop.Name = "btnBackTop";
|
||||
this.btnBackTop.Size = new System.Drawing.Size(72, 26);
|
||||
this.btnBackTop.TabIndex = 8;
|
||||
this.btnBackTop.Text = "返审(&W)";
|
||||
this.btnBackTop.Text = "返审(W)";
|
||||
this.btnBackTop.Click += new System.EventHandler(this.btnBack_Click);
|
||||
//
|
||||
// pcBillDetail
|
||||
|
||||
@@ -29,11 +29,35 @@ namespace Lskj.Control
|
||||
{
|
||||
public partial class AuditPanel2 : UserControl
|
||||
{
|
||||
private readonly AltButtonShortcutManager mAltButtonShortcuts =
|
||||
new AltButtonShortcutManager();
|
||||
|
||||
public AuditPanel2()
|
||||
{
|
||||
InitializeComponent();
|
||||
InitializeAltButtonShortcuts();
|
||||
SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.Selectable | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.SupportsTransparentBackColor, true);
|
||||
}
|
||||
|
||||
private void InitializeAltButtonShortcuts()
|
||||
{
|
||||
mAltButtonShortcuts.Register(btnClose, Keys.Q);
|
||||
mAltButtonShortcuts.Register(btnBack, Keys.N);
|
||||
mAltButtonShortcuts.Register(btnSave, Keys.S);
|
||||
mAltButtonShortcuts.Register(btnAccradit, Keys.Y);
|
||||
mAltButtonShortcuts.Register(btnSpare, Keys.P);
|
||||
mAltButtonShortcuts.Register(btnReflash, Keys.R);
|
||||
mAltButtonShortcuts.Register(btnSearch, Keys.Q);
|
||||
mAltButtonShortcuts.Register(btnBackTop, Keys.W);
|
||||
}
|
||||
|
||||
protected override bool ProcessCmdKey(
|
||||
ref System.Windows.Forms.Message msg, Keys keyData)
|
||||
{
|
||||
return mAltButtonShortcuts.ProcessKey(keyData) ||
|
||||
base.ProcessCmdKey(ref msg, keyData);
|
||||
}
|
||||
|
||||
#region 公有变量
|
||||
public string modelkeyName = "";
|
||||
/// <summary>
|
||||
@@ -1601,7 +1625,7 @@ namespace Lskj.Control
|
||||
this.btnClose.Enabled = this.btnSave.Enabled = this.btnAccradit.Enabled = this.btnBack.Enabled = this.btnSpare.Enabled = false;
|
||||
|
||||
this.btnSave.Visible = this.btnClose.Visible = this.btnBack.Visible = this.pcTool.Visible = true;
|
||||
this.btnAccradit.Text = "确认(&Y)";
|
||||
this.btnAccradit.Text = "确认(Y)";
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2016,7 +2040,7 @@ namespace Lskj.Control
|
||||
}
|
||||
|
||||
//选中上一次选中行行号
|
||||
if (SelectGridControlEx != null && oldRowHandle > 0)
|
||||
if (SelectGridControlEx != null && oldRowHandle >= 0)
|
||||
{
|
||||
SelectGridControlEx.GridView.SelectRowHandler(oldRowHandle);
|
||||
OnPcgridRowCellClick(SelectGridControlEx.GridView, null);
|
||||
@@ -2057,10 +2081,25 @@ namespace Lskj.Control
|
||||
string fieldValue = this.ControlObj.GetControlValue(model);
|
||||
if (fieldValue == "****") continue;
|
||||
|
||||
if (SystemInfo.Instance.IsSpecialAuditSave &&
|
||||
this._drBillInfoMsg != null &&
|
||||
this._drBillInfoMsg.Table != null &&
|
||||
this._drBillInfoMsg.Table.Columns.Contains(model.FieldName) &&
|
||||
AuditChangeLog.IsSameValue(this._drBillInfoMsg[model.FieldName] + "", fieldValue))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
//updateBuilder.AppendFormat("{0}='{1}',", model.FieldName, fieldValue);
|
||||
updateBuilder.Append(string.IsNullOrEmpty(fieldValue) ? string.Format("{0}={1}", model.FieldName, this.ControlObj.GetNullValue(model)) : string.Format("{0}=N'{1}',", model.FieldName, fieldValue.Contains("'") ? fieldValue.Replace("'", "''") : fieldValue));
|
||||
}
|
||||
}
|
||||
string updateFields = updateBuilder.ToString().TrimEnd(',');
|
||||
if (string.IsNullOrEmpty(updateFields))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
return string.Format("update {0} set {1} where {2}='{3}'", this.BillModelObj.MasterTable, updateBuilder.ToString().TrimEnd(','), BillModelObj.PrimaryKey, this.SysModel.BillDocumentId);
|
||||
}
|
||||
#endregion
|
||||
@@ -3609,4 +3648,4 @@ namespace Lskj.Control
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+273
-259
@@ -13,9 +13,13 @@
|
||||
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
if (disposing)
|
||||
{
|
||||
components.Dispose();
|
||||
ReleaseResourcesForDispose();
|
||||
if (components != null)
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
@@ -28,8 +32,21 @@
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this.tabMain = new DevExpress.XtraTab.XtraTabControl();
|
||||
this.label_tips = new DevExpress.XtraEditors.LabelControl();
|
||||
this.label_date = new DevExpress.XtraEditors.LabelControl();
|
||||
this.pl_bottom = new DevExpress.XtraEditors.PanelControl();
|
||||
this.btnReverseSelection = new DevExpress.XtraEditors.SimpleButton();
|
||||
this.btnSelectAll = new DevExpress.XtraEditors.SimpleButton();
|
||||
this.dpb_Tools = new DevExpress.XtraEditors.DropDownButton();
|
||||
this.p_menu = new DevExpress.XtraBars.PopupMenu();
|
||||
this.barManager1 = new DevExpress.XtraBars.BarManager();
|
||||
this.barDockControlTop = new DevExpress.XtraBars.BarDockControl();
|
||||
this.barDockControlBottom = new DevExpress.XtraBars.BarDockControl();
|
||||
this.barDockControlLeft = new DevExpress.XtraBars.BarDockControl();
|
||||
this.barDockControlRight = new DevExpress.XtraBars.BarDockControl();
|
||||
this.btnOkAudit = new DevExpress.XtraEditors.SimpleButton();
|
||||
this.btnBackAudit = new DevExpress.XtraEditors.SimpleButton();
|
||||
this.btnRefresh = new DevExpress.XtraEditors.SimpleButton();
|
||||
this.tabpage_finish = new DevExpress.XtraTab.XtraTabPage();
|
||||
this.gridFinish = new Lskj.Control.GridControlEx();
|
||||
this.splitBelow = new DevExpress.XtraEditors.SplitContainerControl();
|
||||
@@ -45,23 +62,11 @@
|
||||
this.pl_top_right = new DevExpress.XtraEditors.PanelControl();
|
||||
this.simpleButton1 = new DevExpress.XtraEditors.SimpleButton();
|
||||
this.btnBack = new DevExpress.XtraEditors.SimpleButton();
|
||||
this.label_tips = new DevExpress.XtraEditors.LabelControl();
|
||||
this.label_date = new DevExpress.XtraEditors.LabelControl();
|
||||
this.pl_bottom = new DevExpress.XtraEditors.PanelControl();
|
||||
this.btnReverseSelection = new DevExpress.XtraEditors.SimpleButton();
|
||||
this.btnSelectAll = new DevExpress.XtraEditors.SimpleButton();
|
||||
this.dpb_Tools = new DevExpress.XtraEditors.DropDownButton();
|
||||
this.p_menu = new DevExpress.XtraBars.PopupMenu(this.components);
|
||||
this.barManager1 = new DevExpress.XtraBars.BarManager(this.components);
|
||||
this.barDockControlTop = new DevExpress.XtraBars.BarDockControl();
|
||||
this.barDockControlBottom = new DevExpress.XtraBars.BarDockControl();
|
||||
this.barDockControlLeft = new DevExpress.XtraBars.BarDockControl();
|
||||
this.barDockControlRight = new DevExpress.XtraBars.BarDockControl();
|
||||
this.btnOkAudit = new DevExpress.XtraEditors.SimpleButton();
|
||||
this.btnBackAudit = new DevExpress.XtraEditors.SimpleButton();
|
||||
this.btnRefresh = new DevExpress.XtraEditors.SimpleButton();
|
||||
((System.ComponentModel.ISupportInitialize)(this.tabMain)).BeginInit();
|
||||
this.tabMain.SuspendLayout();
|
||||
this.tabMain = new DevExpress.XtraTab.XtraTabControl();
|
||||
((System.ComponentModel.ISupportInitialize)(this.pl_bottom)).BeginInit();
|
||||
this.pl_bottom.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.p_menu)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.barManager1)).BeginInit();
|
||||
this.tabpage_finish.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.splitBelow)).BeginInit();
|
||||
this.splitBelow.SuspendLayout();
|
||||
@@ -71,216 +76,10 @@
|
||||
this.pl_top_searchCond.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.pl_top_right)).BeginInit();
|
||||
this.pl_top_right.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.pl_bottom)).BeginInit();
|
||||
this.pl_bottom.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.p_menu)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.barManager1)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.tabMain)).BeginInit();
|
||||
this.tabMain.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// tabMain
|
||||
//
|
||||
this.tabMain.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
|
||||
this.tabMain.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tabMain.HeaderLocation = DevExpress.XtraTab.TabHeaderLocation.Bottom;
|
||||
this.tabMain.Location = new System.Drawing.Point(0, 0);
|
||||
this.tabMain.Name = "tabMain";
|
||||
this.tabMain.SelectedTabPage = this.tabpage_finish;
|
||||
this.tabMain.Size = new System.Drawing.Size(1051, 683);
|
||||
this.tabMain.TabIndex = 20;
|
||||
this.tabMain.TabPages.AddRange(new DevExpress.XtraTab.XtraTabPage[] {
|
||||
this.tabpage_finish});
|
||||
//
|
||||
// tabpage_finish
|
||||
//
|
||||
this.tabpage_finish.Controls.Add(this.gridFinish);
|
||||
this.tabpage_finish.Controls.Add(this.splitBelow);
|
||||
this.tabpage_finish.Controls.Add(this.pl_top);
|
||||
this.tabpage_finish.Name = "tabpage_finish";
|
||||
this.tabpage_finish.Size = new System.Drawing.Size(1045, 654);
|
||||
this.tabpage_finish.Text = "已完成单据";
|
||||
//
|
||||
// gridFinish
|
||||
//
|
||||
this.gridFinish.AdapterObj = null;
|
||||
this.gridFinish.AutoSize = true;
|
||||
this.gridFinish.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.gridFinish.Location = new System.Drawing.Point(0, 39);
|
||||
this.gridFinish.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.gridFinish.Name = "gridFinish";
|
||||
this.gridFinish.SiftEnumObj = Lskj.Control.GridControlEx.HeaderSiftEnum.Sum;
|
||||
this.gridFinish.Size = new System.Drawing.Size(1045, 322);
|
||||
this.gridFinish.TabIndex = 29;
|
||||
//
|
||||
// splitBelow
|
||||
//
|
||||
this.splitBelow.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||
this.splitBelow.Location = new System.Drawing.Point(0, 361);
|
||||
this.splitBelow.Name = "splitBelow";
|
||||
this.splitBelow.Panel1.Controls.Add(this.gridFlow);
|
||||
this.splitBelow.Panel1.Text = "Panel1";
|
||||
this.splitBelow.Panel2.Controls.Add(this.gridDetail);
|
||||
this.splitBelow.Panel2.Text = "Panel2";
|
||||
this.splitBelow.Size = new System.Drawing.Size(1045, 293);
|
||||
this.splitBelow.SplitterPosition = 453;
|
||||
this.splitBelow.TabIndex = 28;
|
||||
this.splitBelow.Text = "splitContainerControl1";
|
||||
//
|
||||
// gridFlow
|
||||
//
|
||||
this.gridFlow.AdapterObj = null;
|
||||
this.gridFlow.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.gridFlow.Location = new System.Drawing.Point(0, 0);
|
||||
this.gridFlow.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.gridFlow.Name = "gridFlow";
|
||||
this.gridFlow.SiftEnumObj = Lskj.Control.GridControlEx.HeaderSiftEnum.Sum;
|
||||
this.gridFlow.Size = new System.Drawing.Size(453, 293);
|
||||
this.gridFlow.TabIndex = 19;
|
||||
//
|
||||
// gridDetail
|
||||
//
|
||||
this.gridDetail.AdapterObj = null;
|
||||
this.gridDetail.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.gridDetail.Location = new System.Drawing.Point(0, 0);
|
||||
this.gridDetail.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.gridDetail.Name = "gridDetail";
|
||||
this.gridDetail.SiftEnumObj = Lskj.Control.GridControlEx.HeaderSiftEnum.Sum;
|
||||
this.gridDetail.Size = new System.Drawing.Size(587, 293);
|
||||
this.gridDetail.TabIndex = 20;
|
||||
//
|
||||
// pl_top
|
||||
//
|
||||
this.pl_top.Controls.Add(this.pl_top_searchCond);
|
||||
this.pl_top.Controls.Add(this.pl_top_right);
|
||||
this.pl_top.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
this.pl_top.Location = new System.Drawing.Point(0, 0);
|
||||
this.pl_top.Name = "pl_top";
|
||||
this.pl_top.Size = new System.Drawing.Size(1045, 39);
|
||||
this.pl_top.TabIndex = 25;
|
||||
//
|
||||
// pl_top_searchCond
|
||||
//
|
||||
this.pl_top_searchCond.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
|
||||
this.pl_top_searchCond.Controls.Add(this.labeldate_start);
|
||||
this.pl_top_searchCond.Controls.Add(this.labelcheck_finalAuditor);
|
||||
this.pl_top_searchCond.Controls.Add(this.labeltxt_dataFlag);
|
||||
this.pl_top_searchCond.Controls.Add(this.btnSearch);
|
||||
this.pl_top_searchCond.Controls.Add(this.labeldate_end);
|
||||
this.pl_top_searchCond.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.pl_top_searchCond.Location = new System.Drawing.Point(2, 2);
|
||||
this.pl_top_searchCond.Name = "pl_top_searchCond";
|
||||
this.pl_top_searchCond.Size = new System.Drawing.Size(778, 35);
|
||||
this.pl_top_searchCond.TabIndex = 23;
|
||||
//
|
||||
// labeldate_start
|
||||
//
|
||||
this.labeldate_start.BackColor = System.Drawing.Color.Transparent;
|
||||
this.labeldate_start.EditText = null;
|
||||
this.labeldate_start.FontSize = 0F;
|
||||
this.labeldate_start.LabelText = "终审时间起";
|
||||
this.labeldate_start.Location = new System.Drawing.Point(10, 8);
|
||||
this.labeldate_start.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.labeldate_start.Model = null;
|
||||
this.labeldate_start.Name = "labeldate_start";
|
||||
this.labeldate_start.NullText = null;
|
||||
this.labeldate_start.ReadOnly = false;
|
||||
this.labeldate_start.Required = false;
|
||||
this.labeldate_start.Size = new System.Drawing.Size(196, 21);
|
||||
this.labeldate_start.TabIndex = 11;
|
||||
//
|
||||
// labelcheck_finalAuditor
|
||||
//
|
||||
this.labelcheck_finalAuditor.BackColor = System.Drawing.Color.Transparent;
|
||||
this.labelcheck_finalAuditor.EditText = null;
|
||||
this.labelcheck_finalAuditor.FontSize = 0F;
|
||||
this.labelcheck_finalAuditor.LabelText = "终审人";
|
||||
this.labelcheck_finalAuditor.Location = new System.Drawing.Point(419, 8);
|
||||
this.labelcheck_finalAuditor.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.labelcheck_finalAuditor.Model = null;
|
||||
this.labelcheck_finalAuditor.Name = "labelcheck_finalAuditor";
|
||||
this.labelcheck_finalAuditor.NullText = null;
|
||||
this.labelcheck_finalAuditor.ReadOnly = false;
|
||||
this.labelcheck_finalAuditor.Required = false;
|
||||
this.labelcheck_finalAuditor.Size = new System.Drawing.Size(180, 21);
|
||||
this.labelcheck_finalAuditor.TabIndex = 13;
|
||||
//
|
||||
// labeltxt_dataFlag
|
||||
//
|
||||
this.labeltxt_dataFlag.BackColor = System.Drawing.Color.Transparent;
|
||||
this.labeltxt_dataFlag.EditText = "";
|
||||
this.labeltxt_dataFlag.FontSize = 0F;
|
||||
this.labeltxt_dataFlag.LabelText = "数据标识号";
|
||||
this.labeltxt_dataFlag.Location = new System.Drawing.Point(605, 8);
|
||||
this.labeltxt_dataFlag.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.labeltxt_dataFlag.Model = null;
|
||||
this.labeltxt_dataFlag.Name = "labeltxt_dataFlag";
|
||||
this.labeltxt_dataFlag.NullText = "";
|
||||
this.labeltxt_dataFlag.ReadOnly = false;
|
||||
this.labeltxt_dataFlag.Required = false;
|
||||
this.labeltxt_dataFlag.Size = new System.Drawing.Size(164, 21);
|
||||
this.labeltxt_dataFlag.TabIndex = 10;
|
||||
//
|
||||
// btnSearch
|
||||
//
|
||||
this.btnSearch.Appearance.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.btnSearch.Appearance.Options.UseFont = true;
|
||||
this.btnSearch.Location = new System.Drawing.Point(774, 5);
|
||||
this.btnSearch.Name = "btnSearch";
|
||||
this.btnSearch.Size = new System.Drawing.Size(72, 26);
|
||||
this.btnSearch.TabIndex = 6;
|
||||
this.btnSearch.Text = "搜索(&Q)";
|
||||
this.btnSearch.Click += new System.EventHandler(this.btnSearch_Click);
|
||||
//
|
||||
// labeldate_end
|
||||
//
|
||||
this.labeldate_end.BackColor = System.Drawing.Color.Transparent;
|
||||
this.labeldate_end.EditText = null;
|
||||
this.labeldate_end.FontSize = 0F;
|
||||
this.labeldate_end.LabelText = "终审时间止";
|
||||
this.labeldate_end.Location = new System.Drawing.Point(216, 8);
|
||||
this.labeldate_end.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.labeldate_end.Model = null;
|
||||
this.labeldate_end.Name = "labeldate_end";
|
||||
this.labeldate_end.NullText = null;
|
||||
this.labeldate_end.ReadOnly = false;
|
||||
this.labeldate_end.Required = false;
|
||||
this.labeldate_end.Size = new System.Drawing.Size(196, 21);
|
||||
this.labeldate_end.TabIndex = 12;
|
||||
//
|
||||
// pl_top_right
|
||||
//
|
||||
this.pl_top_right.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
|
||||
this.pl_top_right.Controls.Add(this.simpleButton1);
|
||||
this.pl_top_right.Controls.Add(this.btnBack);
|
||||
this.pl_top_right.Dock = System.Windows.Forms.DockStyle.Right;
|
||||
this.pl_top_right.Location = new System.Drawing.Point(780, 2);
|
||||
this.pl_top_right.Name = "pl_top_right";
|
||||
this.pl_top_right.Size = new System.Drawing.Size(263, 35);
|
||||
this.pl_top_right.TabIndex = 24;
|
||||
//
|
||||
// simpleButton1
|
||||
//
|
||||
this.simpleButton1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.simpleButton1.Appearance.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.simpleButton1.Appearance.Options.UseFont = true;
|
||||
this.simpleButton1.Location = new System.Drawing.Point(188, 5);
|
||||
this.simpleButton1.Name = "simpleButton1";
|
||||
this.simpleButton1.Size = new System.Drawing.Size(72, 26);
|
||||
this.simpleButton1.TabIndex = 9;
|
||||
this.simpleButton1.Text = "帮助文档";
|
||||
this.simpleButton1.Click += new System.EventHandler(this.simpleButton1_Click);
|
||||
//
|
||||
// btnBack
|
||||
//
|
||||
this.btnBack.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnBack.Appearance.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.btnBack.Appearance.Options.UseFont = true;
|
||||
this.btnBack.Location = new System.Drawing.Point(100, 5);
|
||||
this.btnBack.Name = "btnBack";
|
||||
this.btnBack.Size = new System.Drawing.Size(82, 26);
|
||||
this.btnBack.TabIndex = 8;
|
||||
this.btnBack.Text = "返审(&W)";
|
||||
this.btnBack.Click += new System.EventHandler(this.btnBack_Click);
|
||||
//
|
||||
// label_tips
|
||||
//
|
||||
this.label_tips.Appearance.Font = new System.Drawing.Font("宋体", 9F);
|
||||
@@ -313,9 +112,9 @@
|
||||
this.pl_bottom.Controls.Add(this.label_tips);
|
||||
this.pl_bottom.Controls.Add(this.label_date);
|
||||
this.pl_bottom.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||
this.pl_bottom.Location = new System.Drawing.Point(0, 683);
|
||||
this.pl_bottom.Location = new System.Drawing.Point(0, 1036);
|
||||
this.pl_bottom.Name = "pl_bottom";
|
||||
this.pl_bottom.Size = new System.Drawing.Size(1051, 32);
|
||||
this.pl_bottom.Size = new System.Drawing.Size(1576, 36);
|
||||
this.pl_bottom.TabIndex = 21;
|
||||
//
|
||||
// btnReverseSelection
|
||||
@@ -323,7 +122,7 @@
|
||||
this.btnReverseSelection.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnReverseSelection.Appearance.Font = new System.Drawing.Font("宋体", 9F);
|
||||
this.btnReverseSelection.Appearance.Options.UseFont = true;
|
||||
this.btnReverseSelection.Location = new System.Drawing.Point(586, 3);
|
||||
this.btnReverseSelection.Location = new System.Drawing.Point(1111, 7);
|
||||
this.btnReverseSelection.Name = "btnReverseSelection";
|
||||
this.btnReverseSelection.Size = new System.Drawing.Size(55, 26);
|
||||
this.btnReverseSelection.TabIndex = 13;
|
||||
@@ -336,7 +135,7 @@
|
||||
this.btnSelectAll.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnSelectAll.Appearance.Font = new System.Drawing.Font("宋体", 9F);
|
||||
this.btnSelectAll.Appearance.Options.UseFont = true;
|
||||
this.btnSelectAll.Location = new System.Drawing.Point(647, 3);
|
||||
this.btnSelectAll.Location = new System.Drawing.Point(1172, 7);
|
||||
this.btnSelectAll.Name = "btnSelectAll";
|
||||
this.btnSelectAll.Size = new System.Drawing.Size(55, 26);
|
||||
this.btnSelectAll.TabIndex = 12;
|
||||
@@ -351,7 +150,7 @@
|
||||
this.dpb_Tools.Appearance.Options.UseFont = true;
|
||||
this.dpb_Tools.DropDownArrowStyle = DevExpress.XtraEditors.DropDownArrowStyle.Show;
|
||||
this.dpb_Tools.DropDownControl = this.p_menu;
|
||||
this.dpb_Tools.Location = new System.Drawing.Point(888, 3);
|
||||
this.dpb_Tools.Location = new System.Drawing.Point(1413, 7);
|
||||
this.dpb_Tools.Name = "dpb_Tools";
|
||||
this.dpb_Tools.Size = new System.Drawing.Size(80, 26);
|
||||
this.dpb_Tools.TabIndex = 11;
|
||||
@@ -377,39 +176,39 @@
|
||||
this.barDockControlTop.CausesValidation = false;
|
||||
this.barDockControlTop.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
this.barDockControlTop.Location = new System.Drawing.Point(0, 0);
|
||||
this.barDockControlTop.Size = new System.Drawing.Size(1051, 0);
|
||||
this.barDockControlTop.Size = new System.Drawing.Size(1576, 0);
|
||||
//
|
||||
// barDockControlBottom
|
||||
//
|
||||
this.barDockControlBottom.CausesValidation = false;
|
||||
this.barDockControlBottom.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||
this.barDockControlBottom.Location = new System.Drawing.Point(0, 715);
|
||||
this.barDockControlBottom.Size = new System.Drawing.Size(1051, 0);
|
||||
this.barDockControlBottom.Location = new System.Drawing.Point(0, 1072);
|
||||
this.barDockControlBottom.Size = new System.Drawing.Size(1576, 0);
|
||||
//
|
||||
// barDockControlLeft
|
||||
//
|
||||
this.barDockControlLeft.CausesValidation = false;
|
||||
this.barDockControlLeft.Dock = System.Windows.Forms.DockStyle.Left;
|
||||
this.barDockControlLeft.Location = new System.Drawing.Point(0, 0);
|
||||
this.barDockControlLeft.Size = new System.Drawing.Size(0, 715);
|
||||
this.barDockControlLeft.Size = new System.Drawing.Size(0, 1072);
|
||||
//
|
||||
// barDockControlRight
|
||||
//
|
||||
this.barDockControlRight.CausesValidation = false;
|
||||
this.barDockControlRight.Dock = System.Windows.Forms.DockStyle.Right;
|
||||
this.barDockControlRight.Location = new System.Drawing.Point(1051, 0);
|
||||
this.barDockControlRight.Size = new System.Drawing.Size(0, 715);
|
||||
this.barDockControlRight.Location = new System.Drawing.Point(1576, 0);
|
||||
this.barDockControlRight.Size = new System.Drawing.Size(0, 1072);
|
||||
//
|
||||
// btnOkAudit
|
||||
//
|
||||
this.btnOkAudit.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnOkAudit.Appearance.Font = new System.Drawing.Font("宋体", 9F);
|
||||
this.btnOkAudit.Appearance.Options.UseFont = true;
|
||||
this.btnOkAudit.Location = new System.Drawing.Point(708, 3);
|
||||
this.btnOkAudit.Location = new System.Drawing.Point(1233, 7);
|
||||
this.btnOkAudit.Name = "btnOkAudit";
|
||||
this.btnOkAudit.Size = new System.Drawing.Size(82, 26);
|
||||
this.btnOkAudit.TabIndex = 7;
|
||||
this.btnOkAudit.Text = "批量审核(&Y)";
|
||||
this.btnOkAudit.Text = "批量审核(Y)";
|
||||
this.btnOkAudit.Visible = false;
|
||||
this.btnOkAudit.Click += new System.EventHandler(this.OnBtnOkAuditClick);
|
||||
//
|
||||
@@ -418,11 +217,11 @@
|
||||
this.btnBackAudit.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnBackAudit.Appearance.Font = new System.Drawing.Font("宋体", 9F);
|
||||
this.btnBackAudit.Appearance.Options.UseFont = true;
|
||||
this.btnBackAudit.Location = new System.Drawing.Point(796, 3);
|
||||
this.btnBackAudit.Location = new System.Drawing.Point(1321, 7);
|
||||
this.btnBackAudit.Name = "btnBackAudit";
|
||||
this.btnBackAudit.Size = new System.Drawing.Size(86, 26);
|
||||
this.btnBackAudit.TabIndex = 6;
|
||||
this.btnBackAudit.Text = "批量返审(&B)";
|
||||
this.btnBackAudit.Text = "批量返审(B)";
|
||||
this.btnBackAudit.Visible = false;
|
||||
this.btnBackAudit.Click += new System.EventHandler(this.OnBtnBackAuditClick);
|
||||
//
|
||||
@@ -431,13 +230,228 @@
|
||||
this.btnRefresh.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnRefresh.Appearance.Font = new System.Drawing.Font("宋体", 9F);
|
||||
this.btnRefresh.Appearance.Options.UseFont = true;
|
||||
this.btnRefresh.Location = new System.Drawing.Point(974, 3);
|
||||
this.btnRefresh.Location = new System.Drawing.Point(1499, 7);
|
||||
this.btnRefresh.Name = "btnRefresh";
|
||||
this.btnRefresh.Size = new System.Drawing.Size(72, 26);
|
||||
this.btnRefresh.TabIndex = 5;
|
||||
this.btnRefresh.Text = "刷新(&R)";
|
||||
this.btnRefresh.Text = "刷新(R)";
|
||||
this.btnRefresh.Click += new System.EventHandler(this.BtnReflash_Click);
|
||||
//
|
||||
// tabpage_finish
|
||||
//
|
||||
this.tabpage_finish.Controls.Add(this.gridFinish);
|
||||
this.tabpage_finish.Controls.Add(this.splitBelow);
|
||||
this.tabpage_finish.Controls.Add(this.pl_top);
|
||||
this.tabpage_finish.Name = "tabpage_finish";
|
||||
this.tabpage_finish.Size = new System.Drawing.Size(1570, 1007);
|
||||
this.tabpage_finish.Text = "已完成单据";
|
||||
//
|
||||
// gridFinish
|
||||
//
|
||||
this.gridFinish.AdapterObj = null;
|
||||
this.gridFinish.AutoSize = true;
|
||||
this.gridFinish.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.gridFinish.Location = new System.Drawing.Point(0, 39);
|
||||
this.gridFinish.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.gridFinish.Name = "gridFinish";
|
||||
this.gridFinish.SiftEnumObj = Lskj.Control.GridControlEx.HeaderSiftEnum.Sum;
|
||||
this.gridFinish.Size = new System.Drawing.Size(1570, 675);
|
||||
this.gridFinish.SysModel = null;
|
||||
this.gridFinish.TabIndex = 29;
|
||||
//
|
||||
// splitBelow
|
||||
//
|
||||
this.splitBelow.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||
this.splitBelow.Location = new System.Drawing.Point(0, 714);
|
||||
this.splitBelow.Name = "splitBelow";
|
||||
this.splitBelow.Panel1.Controls.Add(this.gridFlow);
|
||||
this.splitBelow.Panel1.Text = "Panel1";
|
||||
this.splitBelow.Panel2.Controls.Add(this.gridDetail);
|
||||
this.splitBelow.Panel2.Text = "Panel2";
|
||||
this.splitBelow.Size = new System.Drawing.Size(1570, 293);
|
||||
this.splitBelow.SplitterPosition = 453;
|
||||
this.splitBelow.TabIndex = 28;
|
||||
this.splitBelow.Text = "splitContainerControl1";
|
||||
//
|
||||
// gridFlow
|
||||
//
|
||||
this.gridFlow.AdapterObj = null;
|
||||
this.gridFlow.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.gridFlow.Location = new System.Drawing.Point(0, 0);
|
||||
this.gridFlow.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.gridFlow.Name = "gridFlow";
|
||||
this.gridFlow.SiftEnumObj = Lskj.Control.GridControlEx.HeaderSiftEnum.Sum;
|
||||
this.gridFlow.Size = new System.Drawing.Size(453, 293);
|
||||
this.gridFlow.SysModel = null;
|
||||
this.gridFlow.TabIndex = 19;
|
||||
//
|
||||
// gridDetail
|
||||
//
|
||||
this.gridDetail.AdapterObj = null;
|
||||
this.gridDetail.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.gridDetail.Location = new System.Drawing.Point(0, 0);
|
||||
this.gridDetail.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.gridDetail.Name = "gridDetail";
|
||||
this.gridDetail.SiftEnumObj = Lskj.Control.GridControlEx.HeaderSiftEnum.Sum;
|
||||
this.gridDetail.Size = new System.Drawing.Size(1112, 293);
|
||||
this.gridDetail.SysModel = null;
|
||||
this.gridDetail.TabIndex = 20;
|
||||
//
|
||||
// pl_top
|
||||
//
|
||||
this.pl_top.Controls.Add(this.pl_top_searchCond);
|
||||
this.pl_top.Controls.Add(this.pl_top_right);
|
||||
this.pl_top.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
this.pl_top.Location = new System.Drawing.Point(0, 0);
|
||||
this.pl_top.Name = "pl_top";
|
||||
this.pl_top.Size = new System.Drawing.Size(1570, 39);
|
||||
this.pl_top.TabIndex = 25;
|
||||
//
|
||||
// pl_top_searchCond
|
||||
//
|
||||
this.pl_top_searchCond.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
|
||||
this.pl_top_searchCond.Controls.Add(this.labeldate_start);
|
||||
this.pl_top_searchCond.Controls.Add(this.labelcheck_finalAuditor);
|
||||
this.pl_top_searchCond.Controls.Add(this.labeltxt_dataFlag);
|
||||
this.pl_top_searchCond.Controls.Add(this.btnSearch);
|
||||
this.pl_top_searchCond.Controls.Add(this.labeldate_end);
|
||||
this.pl_top_searchCond.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.pl_top_searchCond.Location = new System.Drawing.Point(2, 2);
|
||||
this.pl_top_searchCond.Name = "pl_top_searchCond";
|
||||
this.pl_top_searchCond.Size = new System.Drawing.Size(1303, 35);
|
||||
this.pl_top_searchCond.TabIndex = 23;
|
||||
//
|
||||
// labeldate_start
|
||||
//
|
||||
this.labeldate_start.BackColor = System.Drawing.Color.Transparent;
|
||||
this.labeldate_start.BackgroundColor = System.Drawing.Color.Empty;
|
||||
this.labeldate_start.ContentBold = false;
|
||||
this.labeldate_start.EditText = null;
|
||||
this.labeldate_start.FontSize = 0F;
|
||||
this.labeldate_start.LabelText = "终审时间起";
|
||||
this.labeldate_start.Location = new System.Drawing.Point(10, 8);
|
||||
this.labeldate_start.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.labeldate_start.Model = null;
|
||||
this.labeldate_start.Name = "labeldate_start";
|
||||
this.labeldate_start.NullText = null;
|
||||
this.labeldate_start.ReadOnly = false;
|
||||
this.labeldate_start.Required = false;
|
||||
this.labeldate_start.Size = new System.Drawing.Size(196, 21);
|
||||
this.labeldate_start.TabIndex = 11;
|
||||
//
|
||||
// labelcheck_finalAuditor
|
||||
//
|
||||
this.labelcheck_finalAuditor.BackColor = System.Drawing.Color.Transparent;
|
||||
this.labelcheck_finalAuditor.BackgroundColor = System.Drawing.Color.Empty;
|
||||
this.labelcheck_finalAuditor.ContentBold = false;
|
||||
this.labelcheck_finalAuditor.EditText = null;
|
||||
this.labelcheck_finalAuditor.FontSize = 0F;
|
||||
this.labelcheck_finalAuditor.LabelText = "终审人";
|
||||
this.labelcheck_finalAuditor.Location = new System.Drawing.Point(419, 8);
|
||||
this.labelcheck_finalAuditor.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.labelcheck_finalAuditor.Model = null;
|
||||
this.labelcheck_finalAuditor.Name = "labelcheck_finalAuditor";
|
||||
this.labelcheck_finalAuditor.NullText = null;
|
||||
this.labelcheck_finalAuditor.ReadOnly = false;
|
||||
this.labelcheck_finalAuditor.Required = false;
|
||||
this.labelcheck_finalAuditor.Size = new System.Drawing.Size(180, 21);
|
||||
this.labelcheck_finalAuditor.TabIndex = 13;
|
||||
//
|
||||
// labeltxt_dataFlag
|
||||
//
|
||||
this.labeltxt_dataFlag.BackColor = System.Drawing.Color.Transparent;
|
||||
this.labeltxt_dataFlag.BackgroundColor = System.Drawing.Color.Empty;
|
||||
this.labeltxt_dataFlag.ContentBold = false;
|
||||
this.labeltxt_dataFlag.EditText = "";
|
||||
this.labeltxt_dataFlag.FontSize = 0F;
|
||||
this.labeltxt_dataFlag.LabelText = "数据标识号";
|
||||
this.labeltxt_dataFlag.Location = new System.Drawing.Point(605, 8);
|
||||
this.labeltxt_dataFlag.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.labeltxt_dataFlag.Model = null;
|
||||
this.labeltxt_dataFlag.Name = "labeltxt_dataFlag";
|
||||
this.labeltxt_dataFlag.NullText = "";
|
||||
this.labeltxt_dataFlag.ReadOnly = false;
|
||||
this.labeltxt_dataFlag.Required = false;
|
||||
this.labeltxt_dataFlag.Size = new System.Drawing.Size(164, 21);
|
||||
this.labeltxt_dataFlag.TabIndex = 10;
|
||||
//
|
||||
// btnSearch
|
||||
//
|
||||
this.btnSearch.Appearance.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.btnSearch.Appearance.Options.UseFont = true;
|
||||
this.btnSearch.Location = new System.Drawing.Point(774, 5);
|
||||
this.btnSearch.Name = "btnSearch";
|
||||
this.btnSearch.Size = new System.Drawing.Size(72, 26);
|
||||
this.btnSearch.TabIndex = 6;
|
||||
this.btnSearch.Text = "搜索(Q)";
|
||||
this.btnSearch.Click += new System.EventHandler(this.btnSearch_Click);
|
||||
//
|
||||
// labeldate_end
|
||||
//
|
||||
this.labeldate_end.BackColor = System.Drawing.Color.Transparent;
|
||||
this.labeldate_end.BackgroundColor = System.Drawing.Color.Empty;
|
||||
this.labeldate_end.ContentBold = false;
|
||||
this.labeldate_end.EditText = null;
|
||||
this.labeldate_end.FontSize = 0F;
|
||||
this.labeldate_end.LabelText = "终审时间止";
|
||||
this.labeldate_end.Location = new System.Drawing.Point(216, 8);
|
||||
this.labeldate_end.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.labeldate_end.Model = null;
|
||||
this.labeldate_end.Name = "labeldate_end";
|
||||
this.labeldate_end.NullText = null;
|
||||
this.labeldate_end.ReadOnly = false;
|
||||
this.labeldate_end.Required = false;
|
||||
this.labeldate_end.Size = new System.Drawing.Size(196, 21);
|
||||
this.labeldate_end.TabIndex = 12;
|
||||
//
|
||||
// pl_top_right
|
||||
//
|
||||
this.pl_top_right.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
|
||||
this.pl_top_right.Controls.Add(this.simpleButton1);
|
||||
this.pl_top_right.Controls.Add(this.btnBack);
|
||||
this.pl_top_right.Dock = System.Windows.Forms.DockStyle.Right;
|
||||
this.pl_top_right.Location = new System.Drawing.Point(1305, 2);
|
||||
this.pl_top_right.Name = "pl_top_right";
|
||||
this.pl_top_right.Size = new System.Drawing.Size(263, 35);
|
||||
this.pl_top_right.TabIndex = 24;
|
||||
//
|
||||
// simpleButton1
|
||||
//
|
||||
this.simpleButton1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.simpleButton1.Appearance.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.simpleButton1.Appearance.Options.UseFont = true;
|
||||
this.simpleButton1.Location = new System.Drawing.Point(188, 5);
|
||||
this.simpleButton1.Name = "simpleButton1";
|
||||
this.simpleButton1.Size = new System.Drawing.Size(72, 26);
|
||||
this.simpleButton1.TabIndex = 9;
|
||||
this.simpleButton1.Text = "帮助文档";
|
||||
this.simpleButton1.Click += new System.EventHandler(this.simpleButton1_Click);
|
||||
//
|
||||
// btnBack
|
||||
//
|
||||
this.btnBack.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnBack.Appearance.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.btnBack.Appearance.Options.UseFont = true;
|
||||
this.btnBack.Location = new System.Drawing.Point(100, 5);
|
||||
this.btnBack.Name = "btnBack";
|
||||
this.btnBack.Size = new System.Drawing.Size(82, 26);
|
||||
this.btnBack.TabIndex = 8;
|
||||
this.btnBack.Text = "返审(W)";
|
||||
this.btnBack.Click += new System.EventHandler(this.btnBack_Click);
|
||||
//
|
||||
// tabMain
|
||||
//
|
||||
this.tabMain.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
|
||||
this.tabMain.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tabMain.HeaderLocation = DevExpress.XtraTab.TabHeaderLocation.Bottom;
|
||||
this.tabMain.Location = new System.Drawing.Point(0, 0);
|
||||
this.tabMain.Name = "tabMain";
|
||||
this.tabMain.SelectedTabPage = this.tabpage_finish;
|
||||
this.tabMain.Size = new System.Drawing.Size(1576, 1036);
|
||||
this.tabMain.TabIndex = 20;
|
||||
this.tabMain.TabPages.AddRange(new DevExpress.XtraTab.XtraTabPage[] {
|
||||
this.tabpage_finish});
|
||||
//
|
||||
// AuditPanelEx
|
||||
//
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
|
||||
@@ -448,9 +462,12 @@
|
||||
this.Controls.Add(this.barDockControlBottom);
|
||||
this.Controls.Add(this.barDockControlTop);
|
||||
this.Name = "AuditPanelEx";
|
||||
this.Size = new System.Drawing.Size(1051, 715);
|
||||
((System.ComponentModel.ISupportInitialize)(this.tabMain)).EndInit();
|
||||
this.tabMain.ResumeLayout(false);
|
||||
this.Size = new System.Drawing.Size(1576, 1072);
|
||||
((System.ComponentModel.ISupportInitialize)(this.pl_bottom)).EndInit();
|
||||
this.pl_bottom.ResumeLayout(false);
|
||||
this.pl_bottom.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.p_menu)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.barManager1)).EndInit();
|
||||
this.tabpage_finish.ResumeLayout(false);
|
||||
this.tabpage_finish.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.splitBelow)).EndInit();
|
||||
@@ -461,18 +478,14 @@
|
||||
this.pl_top_searchCond.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this.pl_top_right)).EndInit();
|
||||
this.pl_top_right.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this.pl_bottom)).EndInit();
|
||||
this.pl_bottom.ResumeLayout(false);
|
||||
this.pl_bottom.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.p_menu)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.barManager1)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.tabMain)).EndInit();
|
||||
this.tabMain.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
private DevExpress.XtraTab.XtraTabControl tabMain;
|
||||
private DevExpress.XtraEditors.LabelControl label_date;
|
||||
private DevExpress.XtraEditors.LabelControl label_tips;
|
||||
private DevExpress.XtraEditors.PanelControl pl_bottom;
|
||||
@@ -488,7 +501,12 @@
|
||||
private DevExpress.XtraBars.BarDockControl barDockControlRight;
|
||||
private DevExpress.XtraEditors.SimpleButton btnSelectAll;
|
||||
private DevExpress.XtraEditors.SimpleButton btnReverseSelection;
|
||||
private DevExpress.XtraTab.XtraTabControl tabMain;
|
||||
private DevExpress.XtraTab.XtraTabPage tabpage_finish;
|
||||
private GridControlEx gridFinish;
|
||||
private DevExpress.XtraEditors.SplitContainerControl splitBelow;
|
||||
private GridControlEx gridFlow;
|
||||
private GridControlEx gridDetail;
|
||||
private DevExpress.XtraEditors.PanelControl pl_top;
|
||||
private DevExpress.XtraEditors.PanelControl pl_top_searchCond;
|
||||
private LabelCheckDateEdit labeldate_start;
|
||||
@@ -499,9 +517,5 @@
|
||||
private DevExpress.XtraEditors.PanelControl pl_top_right;
|
||||
private DevExpress.XtraEditors.SimpleButton simpleButton1;
|
||||
private DevExpress.XtraEditors.SimpleButton btnBack;
|
||||
private DevExpress.XtraEditors.SplitContainerControl splitBelow;
|
||||
private GridControlEx gridFlow;
|
||||
private GridControlEx gridFinish;
|
||||
private GridControlEx gridDetail;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,9 +41,96 @@ namespace Lskj.Control
|
||||
{
|
||||
public partial class AuditPanelEx : UserControl
|
||||
{
|
||||
private bool mResourcesReleased;
|
||||
private readonly AltButtonShortcutManager mAltButtonShortcuts =
|
||||
new AltButtonShortcutManager();
|
||||
|
||||
public AuditPanelEx()
|
||||
{
|
||||
InitializeComponent();
|
||||
InitializeAltButtonShortcuts();
|
||||
}
|
||||
|
||||
private void InitializeAltButtonShortcuts()
|
||||
{
|
||||
mAltButtonShortcuts.Register(btnOkAudit, Keys.Y);
|
||||
mAltButtonShortcuts.Register(btnBackAudit, Keys.B);
|
||||
mAltButtonShortcuts.Register(btnRefresh, Keys.R);
|
||||
mAltButtonShortcuts.Register(btnBack, Keys.W);
|
||||
mAltButtonShortcuts.Register(btnSearch, Keys.Q);
|
||||
}
|
||||
|
||||
protected override bool ProcessCmdKey(
|
||||
ref System.Windows.Forms.Message msg, Keys keyData)
|
||||
{
|
||||
return mAltButtonShortcuts.ProcessKey(keyData) ||
|
||||
base.ProcessCmdKey(ref msg, keyData);
|
||||
}
|
||||
|
||||
internal void ReleaseResourcesForDispose()
|
||||
{
|
||||
if (mResourcesReleased)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mResourcesReleased = true;
|
||||
MyControl searchControl = _searchContrl;
|
||||
_searchContrl = null;
|
||||
if (searchControl != null)
|
||||
{
|
||||
searchControl.Dispose();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (gridFinish != null && gridFinish.GridView != null)
|
||||
{
|
||||
gridFinish.GridView.SelectionChanged -= GvFinish_SelectionChangedClick;
|
||||
gridFinish.GridView.DoubleClick -= GvFinish_DoubleClick;
|
||||
}
|
||||
foreach (TabPageObj tabPage in _tabPageObjs)
|
||||
{
|
||||
foreach (TabPageItemObj item in tabPage.TabPageItemObjs)
|
||||
{
|
||||
if (item.GridControlObj != null &&
|
||||
item.GridControlObj.GridView != null)
|
||||
{
|
||||
item.GridControlObj.GridView.DoubleClick -=
|
||||
OnGridViewDoubleClick;
|
||||
item.GridControlObj.Model = null;
|
||||
}
|
||||
}
|
||||
tabPage.TabPageItemObjs.Clear();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// A partially disposed DevExpress view must not stop cleanup.
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (SysModel != null && SysModel.DataCaches != null)
|
||||
{
|
||||
SysModel.DataCaches.RemoveCache(this);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Cache cleanup must not interrupt control disposal.
|
||||
}
|
||||
|
||||
_tabPageObjs.Clear();
|
||||
_tabPageCount.Clear();
|
||||
OnGridViewDoubleCallBack = null;
|
||||
OnGridFinshViewDoubleCallBack = null;
|
||||
OnBtnSearchCallBack = null;
|
||||
SectionAccradit = null;
|
||||
AuditComModelObj = null;
|
||||
BaseAccraditModelObj = null;
|
||||
PubSysModel = null;
|
||||
SysModel = null;
|
||||
}
|
||||
|
||||
#region 公有变量
|
||||
@@ -299,17 +386,12 @@ namespace Lskj.Control
|
||||
{
|
||||
return new AccraditationModel(dataRow);
|
||||
}));
|
||||
Task<GridControlEx> gridControlExTask = cachesDic.AddTask(dataRow, "GridControlEx", new Task<GridControlEx>(() =>
|
||||
{
|
||||
return new GridControlEx();
|
||||
}));
|
||||
GridControlEx gridControlEx = gridControlExTask.Result;
|
||||
string key = "FLOWSTEP_" + dynamicModel.ModuleCode + "_" + flowTypeStepModelTask.Result.StepCode + "_" + accraditationModelTask.Result.Id + "";
|
||||
Task<DataTable> baseGridRowColorsTask = cachesDic.AddTask(gridControlEx, "BaseGridRowColors", new Task<DataTable>(() =>
|
||||
Task<DataTable> baseGridRowColorsTask = cachesDic.AddTask(dataRow, "BaseGridRowColors", new Task<DataTable>(() =>
|
||||
{
|
||||
return BaseModuleImpl.GetBaseGridRowColors(key);
|
||||
}));
|
||||
Task<DataTable> flowstepGridRightMenusTask = cachesDic.AddTask(gridControlEx, "FlowstepGridRightMenus", new Task<DataTable>(() =>
|
||||
Task<DataTable> flowstepGridRightMenusTask = cachesDic.AddTask(dataRow, "FlowstepGridRightMenus", new Task<DataTable>(() =>
|
||||
{
|
||||
return BaseModuleImpl.GetBaseGridRightMenus($"FLOWSTEP_{accraditationModelTask.Result.Formkey}");
|
||||
}));
|
||||
@@ -317,10 +399,6 @@ namespace Lskj.Control
|
||||
//{
|
||||
// return BaseImpl.GetDataTableResult(accraditationModelTask.Result.StepSql);
|
||||
//}));
|
||||
string modelkeyName = isBill ? GridCustomColumnStruct.AuditMainGridView : GridCustomColumnStruct.BaseAuditMainGridView;
|
||||
string customColumKey = modelkeyName + key;
|
||||
cachesDic.AddTask(gridControlEx, "DynamicModel", dynamicModelTask);
|
||||
gridControlEx.GetDataCaches(cachesDic, customColumKey);
|
||||
}
|
||||
return flowList;
|
||||
}));
|
||||
@@ -613,18 +691,19 @@ namespace Lskj.Control
|
||||
gridPanel.Padding = new System.Windows.Forms.Padding(2);
|
||||
gridPanel.Dock = DockStyle.Right;
|
||||
gridPanel.BorderStyle = BorderStyles.NoBorder;
|
||||
if (!dataCaches.GetValue(dataRow, "GridControlEx", out GridControlEx grid))
|
||||
GridControlEx grid = new GridControlEx();
|
||||
if (dataCaches != null)
|
||||
{
|
||||
grid = new GridControlEx();
|
||||
grid.GetDataCaches(dataCaches, modelkeyName + key);
|
||||
}
|
||||
grid.Parent = gridPanel;
|
||||
grid.Dock = DockStyle.Fill;
|
||||
grid.BorderStyle = BorderStyle.None;
|
||||
if (!dataCaches.GetValue(grid, "BaseGridRowColors", out DataTable dtGridRowColors))
|
||||
if (!dataCaches.GetValue(dataRow, "BaseGridRowColors", out DataTable dtGridRowColors))
|
||||
{
|
||||
dtGridRowColors = BaseModuleImpl.GetBaseGridRowColors(key);
|
||||
}
|
||||
if (!dataCaches.GetValue(grid, "FlowstepGridRightMenus", out DataTable dtGridRightMenus))
|
||||
if (!dataCaches.GetValue(dataRow, "FlowstepGridRightMenus", out DataTable dtGridRightMenus))
|
||||
{
|
||||
dtGridRightMenus = BaseModuleImpl.GetBaseGridRightMenus($"FLOWSTEP_{accrModel.Formkey}");
|
||||
}
|
||||
@@ -1906,4 +1985,4 @@ namespace Lskj.Control
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,13 @@ namespace Lskj.Control
|
||||
/// </summary>
|
||||
private bool _working = false;
|
||||
private List<string> _queryQueue = new List<string>();
|
||||
private LatestValueWorker<PopupQueryRequest> _queryWorker;
|
||||
|
||||
private sealed class PopupQueryRequest
|
||||
{
|
||||
public string SqlValue;
|
||||
public bool IsNewPopup;
|
||||
}
|
||||
/// <summary>
|
||||
/// The _popup
|
||||
/// </summary>
|
||||
@@ -246,9 +253,7 @@ namespace Lskj.Control
|
||||
public void OnAutoPopupShow()
|
||||
{
|
||||
this.CalcPopupLocation();
|
||||
Thread queryThread = new Thread(CalcPopupSize);
|
||||
queryThread.IsBackground = true;
|
||||
queryThread.Start(Popup);
|
||||
ThreadPool.QueueUserWorkItem(CalcPopupSize, Popup);
|
||||
|
||||
//// 在主线程中显示等待对话框,并在后台线程中执行查询和数据绑定
|
||||
//Task.Run(() =>
|
||||
@@ -339,6 +344,7 @@ namespace Lskj.Control
|
||||
public AutoGridLookUp()
|
||||
{
|
||||
InitializePopup();
|
||||
_queryWorker = new LatestValueWorker<PopupQueryRequest>(ExecuteLatestPopupQuery);
|
||||
InitializeEvent();
|
||||
this.Disposed += OnDisposed;
|
||||
}
|
||||
@@ -390,9 +396,7 @@ namespace Lskj.Control
|
||||
this.ShowPopup();
|
||||
}
|
||||
|
||||
Thread queryThread = new Thread(CalcPopupSize);
|
||||
queryThread.IsBackground = true;
|
||||
queryThread.Start(Popup);
|
||||
ThreadPool.QueueUserWorkItem(CalcPopupSize, Popup);
|
||||
}
|
||||
/// <summary>
|
||||
/// <para>说明:计算弹出控件位置</para>
|
||||
@@ -600,16 +604,7 @@ namespace Lskj.Control
|
||||
sqlValue = ControlObj.ReplaceControlValue(sourceSql);
|
||||
}
|
||||
|
||||
if (!this._working)
|
||||
{
|
||||
Thread thread = new Thread(new ParameterizedThreadStart(RefreshPopupDataSource));
|
||||
thread.IsBackground = true;
|
||||
thread.Start(sqlValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
this._queryQueue.Add(sqlValue);
|
||||
}
|
||||
QueuePopupQuery(sqlValue, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -709,9 +704,9 @@ namespace Lskj.Control
|
||||
string sql = MainImpl.GetDefaultValue(this._queryQueue.Last());
|
||||
sql = ReplaceHelper.ReplaceParam(sql);
|
||||
// 在检索过程中还存在输入数据,则拿最后一次数据在进行匹配一次
|
||||
Thread thread = new Thread(new ParameterizedThreadStart(RefreshPopupDataSource));
|
||||
thread.IsBackground = true;
|
||||
thread.Start(sql);
|
||||
ThreadPool.QueueUserWorkItem(
|
||||
RefreshPopupDataSource,
|
||||
sql);
|
||||
|
||||
this._queryQueue.Clear();
|
||||
}
|
||||
@@ -1601,17 +1596,74 @@ namespace Lskj.Control
|
||||
}
|
||||
sqlValue = ControlObj.ReplaceControlValue(sourceSql.Replace("#", ""));
|
||||
}
|
||||
if (!this._working)
|
||||
QueuePopupQuery(sqlValue, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void QueuePopupQuery(string sqlValue, bool isNewPopup)
|
||||
{
|
||||
if (_queryWorker == null || IsDisposed || Disposing)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_working = true;
|
||||
if (Popup != null)
|
||||
{
|
||||
Popup.LabelObj.Text = "正在筛选数据,请稍后...";
|
||||
Popup.BottomPanelObj.Visible = true;
|
||||
}
|
||||
|
||||
_queryWorker.Queue(new PopupQueryRequest
|
||||
{
|
||||
SqlValue = sqlValue,
|
||||
IsNewPopup = isNewPopup
|
||||
});
|
||||
}
|
||||
|
||||
private void ExecuteLatestPopupQuery(PopupQueryRequest request, int version)
|
||||
{
|
||||
DateTime beginTime = DateTime.Now;
|
||||
DataTable table = new DataTable();
|
||||
|
||||
if (request != null && !string.IsNullOrWhiteSpace(request.SqlValue))
|
||||
{
|
||||
try
|
||||
{
|
||||
Thread thread = new Thread(new ParameterizedThreadStart(RefreshPopupDataSourceNew));
|
||||
thread.IsBackground = true;
|
||||
thread.Start(sqlValue);
|
||||
table = SqlHelper.ExecuteDataTable(request.SqlValue);
|
||||
}
|
||||
else
|
||||
catch
|
||||
{
|
||||
this._queryQueue.Add(sqlValue);
|
||||
table = new DataTable();
|
||||
}
|
||||
}
|
||||
|
||||
DateTime endTime = DateTime.Now;
|
||||
if (_queryWorker == null || !_queryWorker.IsCurrent(version) || IsDisposed || Disposing || !IsHandleCreated)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
BeginInvoke(new MethodInvoker(delegate
|
||||
{
|
||||
if (_queryWorker == null || !_queryWorker.IsCurrent(version) || IsDisposed || Disposing || Popup == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int second = Convert.ToInt32((endTime - beginTime).TotalSeconds);
|
||||
string tipMsg = "数据筛选完成.";
|
||||
Popup.LabelObj.Text = second > 0 ? string.Format(tipMsg + "(耗时{0}秒)", second) : tipMsg;
|
||||
Popup.GridControlObj.DataSource = table;
|
||||
_working = false;
|
||||
CalcFormAndGrid(request != null && request.IsNewPopup);
|
||||
}));
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshPopupDataSourceNew(object sqlValue)
|
||||
@@ -1646,9 +1698,9 @@ namespace Lskj.Control
|
||||
if (this._queryQueue.Count > 0)
|
||||
{
|
||||
// 在检索过程中还存在输入数据,则拿最后一次数据在进行匹配一次
|
||||
Thread thread = new Thread(new ParameterizedThreadStart(RefreshPopupDataSourceNew));
|
||||
thread.IsBackground = true;
|
||||
thread.Start(this._queryQueue.Last());
|
||||
ThreadPool.QueueUserWorkItem(
|
||||
RefreshPopupDataSourceNew,
|
||||
this._queryQueue.Last());
|
||||
this._queryQueue.Clear();
|
||||
}
|
||||
else
|
||||
@@ -1681,8 +1733,15 @@ namespace Lskj.Control
|
||||
/// <param name="e"></param>
|
||||
private void OnDisposed(object sender, EventArgs e)
|
||||
{
|
||||
if (_queryWorker != null)
|
||||
{
|
||||
_queryWorker.Dispose();
|
||||
_queryWorker = null;
|
||||
}
|
||||
_working = false;
|
||||
_queryQueue.Clear();
|
||||
this._popup?.Dispose();
|
||||
this._popup = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,13 @@ namespace Lskj.Control
|
||||
/// </summary>
|
||||
private bool _working = false;
|
||||
private List<string> _queryQueue = new List<string>();
|
||||
private LatestValueWorker<PopupQueryRequest> _queryWorker;
|
||||
|
||||
private sealed class PopupQueryRequest
|
||||
{
|
||||
public string SqlValue;
|
||||
public bool IsNewPopup;
|
||||
}
|
||||
/// <summary>
|
||||
/// The _popup
|
||||
/// </summary>
|
||||
@@ -318,6 +325,7 @@ namespace Lskj.Control
|
||||
public AutoGridRevLookUp()
|
||||
{
|
||||
InitializePopup();
|
||||
_queryWorker = new LatestValueWorker<PopupQueryRequest>(ExecuteLatestPopupQuery);
|
||||
InitializeEvent();
|
||||
this.Disposed += OnDisposed;
|
||||
}
|
||||
@@ -360,9 +368,7 @@ namespace Lskj.Control
|
||||
}
|
||||
private void CalcFormAndGrid()
|
||||
{
|
||||
Thread queryThread = new Thread(CalcPopupSize);
|
||||
queryThread.IsBackground = true;
|
||||
queryThread.Start(Popup);
|
||||
ThreadPool.QueueUserWorkItem(CalcPopupSize, Popup);
|
||||
}
|
||||
/// <summary>
|
||||
/// <para>说明:计算弹出控件位置</para>
|
||||
@@ -527,16 +533,7 @@ namespace Lskj.Control
|
||||
}
|
||||
sqlValue = ControlObj.ReplaceControlValue(sourceSql.Replace("#", ""));
|
||||
}
|
||||
if (!this._working)
|
||||
{
|
||||
Thread thread = new Thread(new ParameterizedThreadStart(RefreshPopupDataSource));
|
||||
thread.IsBackground = true;
|
||||
thread.Start(sqlValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
this._queryQueue.Add(sqlValue);
|
||||
}
|
||||
QueuePopupQuery(sqlValue, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -627,9 +624,9 @@ namespace Lskj.Control
|
||||
string sql = MainImpl.GetDefaultValue(this._queryQueue.Last());
|
||||
sql = ReplaceHelper.ReplaceParam(sql);
|
||||
// 在检索过程中还存在输入数据,则拿最后一次数据在进行匹配一次
|
||||
Thread thread = new Thread(new ParameterizedThreadStart(RefreshPopupDataSource));
|
||||
thread.IsBackground = true;
|
||||
thread.Start(sql);
|
||||
ThreadPool.QueueUserWorkItem(
|
||||
RefreshPopupDataSource,
|
||||
sql);
|
||||
this._queryQueue.Clear();
|
||||
}
|
||||
else
|
||||
@@ -1022,15 +1019,23 @@ namespace Lskj.Control
|
||||
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
|
||||
protected void OnAutoGridLookUpGotFocus(object sender, EventArgs e)
|
||||
{
|
||||
System.Threading.Thread thread = new Thread(() =>
|
||||
ThreadPool.QueueUserWorkItem(delegate
|
||||
{
|
||||
while (!this.IsSetDataSource)
|
||||
{
|
||||
if (IsDisposed || Disposing)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Thread.Sleep(10);
|
||||
}
|
||||
if (IsDisposed || Disposing)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.HandPopupSqlValue(this.Text);
|
||||
ShowPopup();
|
||||
});
|
||||
thread.Start();
|
||||
}
|
||||
/// <summary>
|
||||
/// 鼠标单击控件时
|
||||
@@ -1041,15 +1046,23 @@ namespace Lskj.Control
|
||||
{
|
||||
if (this._popup.Visible == false)
|
||||
{
|
||||
System.Threading.Thread thread = new Thread(() =>
|
||||
ThreadPool.QueueUserWorkItem(delegate
|
||||
{
|
||||
while (!this.IsSetDataSource)
|
||||
{
|
||||
if (IsDisposed || Disposing)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Thread.Sleep(10);
|
||||
}
|
||||
if (IsDisposed || Disposing)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.HandPopupSqlValue(this.Text);
|
||||
ShowPopup();
|
||||
});
|
||||
thread.Start();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
@@ -1327,17 +1340,78 @@ namespace Lskj.Control
|
||||
}
|
||||
sqlValue = ControlObj.ReplaceControlValue(sourceSql.Replace("#", ""));
|
||||
}
|
||||
if (!this._working)
|
||||
QueuePopupQuery(sqlValue, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void QueuePopupQuery(string sqlValue, bool isNewPopup)
|
||||
{
|
||||
if (_queryWorker == null || IsDisposed || Disposing)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_working = true;
|
||||
if (Popup != null)
|
||||
{
|
||||
Popup.LabelObj.Text = "正在筛选数据,请稍后...";
|
||||
Popup.BottomPanelObj.Visible = true;
|
||||
Popup.GridControlObj.DataSourceTable().Clear();
|
||||
}
|
||||
|
||||
_queryWorker.Queue(new PopupQueryRequest
|
||||
{
|
||||
SqlValue = sqlValue,
|
||||
IsNewPopup = isNewPopup
|
||||
});
|
||||
}
|
||||
|
||||
private void ExecuteLatestPopupQuery(PopupQueryRequest request, int version)
|
||||
{
|
||||
DateTime beginTime = DateTime.Now;
|
||||
DataTable table = new DataTable();
|
||||
|
||||
if (request != null && !string.IsNullOrWhiteSpace(request.SqlValue))
|
||||
{
|
||||
try
|
||||
{
|
||||
Thread thread = new Thread(new ParameterizedThreadStart(RefreshPopupDataSourceNew));
|
||||
thread.IsBackground = true;
|
||||
thread.Start(sqlValue);
|
||||
table = SqlHelper.ExecuteDataTable(request.SqlValue);
|
||||
}
|
||||
else
|
||||
catch
|
||||
{
|
||||
this._queryQueue.Add(sqlValue);
|
||||
table = new DataTable();
|
||||
}
|
||||
}
|
||||
|
||||
DateTime endTime = DateTime.Now;
|
||||
if (_queryWorker == null || !_queryWorker.IsCurrent(version) || IsDisposed || Disposing || !IsHandleCreated)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
BeginInvoke(new MethodInvoker(delegate
|
||||
{
|
||||
if (_queryWorker == null || !_queryWorker.IsCurrent(version) || IsDisposed || Disposing || Popup == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int second = Convert.ToInt32((endTime - beginTime).TotalSeconds);
|
||||
string tipMsg = "数据筛选完成.";
|
||||
Popup.LabelObj.Text = second > 0 ? string.Format(tipMsg + "(耗时{0}秒)", second) : tipMsg;
|
||||
Popup.GridControlObj.DataSource = table;
|
||||
_working = false;
|
||||
if (request != null && !request.IsNewPopup)
|
||||
{
|
||||
CalcFormAndGrid();
|
||||
}
|
||||
}));
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
}
|
||||
}
|
||||
private void RefreshPopupDataSourceNew(object sqlValue)
|
||||
{
|
||||
@@ -1372,9 +1446,9 @@ namespace Lskj.Control
|
||||
if (this._queryQueue.Count > 0)
|
||||
{
|
||||
// 在检索过程中还存在输入数据,则拿最后一次数据在进行匹配一次
|
||||
Thread thread = new Thread(new ParameterizedThreadStart(RefreshPopupDataSourceNew));
|
||||
thread.IsBackground = true;
|
||||
thread.Start(this._queryQueue.Last());
|
||||
ThreadPool.QueueUserWorkItem(
|
||||
RefreshPopupDataSourceNew,
|
||||
this._queryQueue.Last());
|
||||
|
||||
this._queryQueue.Clear();
|
||||
}
|
||||
@@ -1419,8 +1493,15 @@ namespace Lskj.Control
|
||||
/// <param name="e"></param>
|
||||
private void OnDisposed(object sender, EventArgs e)
|
||||
{
|
||||
if (_queryWorker != null)
|
||||
{
|
||||
_queryWorker.Dispose();
|
||||
_queryWorker = null;
|
||||
}
|
||||
_working = false;
|
||||
_queryQueue.Clear();
|
||||
this._popup?.Dispose();
|
||||
this._popup = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,331 @@
|
||||
using DevExpress.XtraEditors;
|
||||
using DevExpress.XtraGrid;
|
||||
using DevExpress.XtraGrid.Views.Grid;
|
||||
using DevExpress.XtraGrid.Views.Grid.ViewInfo;
|
||||
using DevExpress.Utils;
|
||||
using Lskj.Control.Model;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Lskj.Control
|
||||
{
|
||||
/// <summary>
|
||||
/// 173/174 扩展搜索专用弹窗。查询文本只存在于本控件中,不参与业务列绑定。
|
||||
/// </summary>
|
||||
internal sealed class ExtendedReturnSearchPopup : UserControl
|
||||
{
|
||||
private sealed class SearchColumnOption
|
||||
{
|
||||
public SearchColumnOption(string fieldName, string caption)
|
||||
{
|
||||
FieldName = fieldName ?? string.Empty;
|
||||
Caption = caption ?? string.Empty;
|
||||
}
|
||||
|
||||
public string FieldName { get; private set; }
|
||||
|
||||
public string Caption { get; private set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Caption;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly TableLayoutPanel searchPanel;
|
||||
private readonly ComboBoxEdit searchFieldEdit;
|
||||
private readonly TextEdit searchEdit;
|
||||
private readonly SimpleButton queryButton;
|
||||
private readonly SimpleButton clearButton;
|
||||
private readonly GridControl resultGrid;
|
||||
private readonly GridView resultView;
|
||||
private string selectedSearchField = string.Empty;
|
||||
|
||||
public event EventHandler SearchRequested;
|
||||
public event EventHandler ClearRequested;
|
||||
public event EventHandler ResultSelected;
|
||||
|
||||
public ExtendedReturnSearchPopup()
|
||||
{
|
||||
searchPanel = new TableLayoutPanel();
|
||||
searchFieldEdit = new ComboBoxEdit();
|
||||
searchEdit = new TextEdit();
|
||||
queryButton = new SimpleButton();
|
||||
clearButton = new SimpleButton();
|
||||
resultGrid = new GridControl();
|
||||
resultView = new GridView(resultGrid);
|
||||
|
||||
SuspendLayout();
|
||||
searchPanel.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(searchFieldEdit.Properties)).BeginInit();
|
||||
((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 = 4;
|
||||
searchPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 120F));
|
||||
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 = 2;
|
||||
queryButton.Click += QueryButton_Click;
|
||||
|
||||
clearButton.Dock = DockStyle.Fill;
|
||||
clearButton.Margin = new Padding(4, 0, 0, 0);
|
||||
clearButton.Text = "清空";
|
||||
clearButton.TabIndex = 3;
|
||||
clearButton.Click += ClearButton_Click;
|
||||
|
||||
searchFieldEdit.Dock = DockStyle.Fill;
|
||||
searchFieldEdit.Margin = new Padding(0, 0, 4, 0);
|
||||
searchFieldEdit.TabIndex = 0;
|
||||
searchFieldEdit.Properties.AutoHeight = false;
|
||||
searchFieldEdit.Properties.TextEditStyle = DevExpress.XtraEditors.Controls.TextEditStyles.DisableTextEditor;
|
||||
searchFieldEdit.SelectedIndexChanged += SearchFieldEdit_SelectedIndexChanged;
|
||||
|
||||
searchEdit.Dock = DockStyle.Fill;
|
||||
searchEdit.Margin = new Padding(0);
|
||||
searchEdit.TabIndex = 1;
|
||||
searchEdit.Properties.AutoHeight = false;
|
||||
searchEdit.Properties.NullValuePrompt = "输入查询内容后按回车";
|
||||
searchEdit.Properties.NullValuePromptShowForEmptyValue = true;
|
||||
searchEdit.KeyDown += SearchEdit_KeyDown;
|
||||
|
||||
searchPanel.Controls.Add(searchFieldEdit, 0, 0);
|
||||
searchPanel.Controls.Add(searchEdit, 1, 0);
|
||||
searchPanel.Controls.Add(queryButton, 2, 0);
|
||||
searchPanel.Controls.Add(clearButton, 3, 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.ShowAutoFilterRow = 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();
|
||||
((System.ComponentModel.ISupportInitialize)(searchFieldEdit.Properties)).EndInit();
|
||||
searchPanel.ResumeLayout(false);
|
||||
ResumeLayout(false);
|
||||
|
||||
SetSearchColumns(null);
|
||||
}
|
||||
|
||||
public GridControl ResultGrid
|
||||
{
|
||||
get { return resultGrid; }
|
||||
}
|
||||
|
||||
public GridView ResultView
|
||||
{
|
||||
get { return resultView; }
|
||||
}
|
||||
|
||||
public string SearchText
|
||||
{
|
||||
get { return (searchEdit.Text ?? string.Empty).Trim(); }
|
||||
}
|
||||
|
||||
public string SelectedSearchField
|
||||
{
|
||||
get
|
||||
{
|
||||
SearchColumnOption option = searchFieldEdit.SelectedItem as SearchColumnOption;
|
||||
return option == null ? string.Empty : option.FieldName;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetSearchColumns(IEnumerable<KeyValuePair<string, string>> columns)
|
||||
{
|
||||
string preferredField = selectedSearchField;
|
||||
SearchColumnOption all = new SearchColumnOption(string.Empty, "所有列");
|
||||
SearchColumnOption selected = null;
|
||||
HashSet<string> fields = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
searchFieldEdit.Properties.BeginUpdate();
|
||||
try
|
||||
{
|
||||
searchFieldEdit.Properties.Items.Clear();
|
||||
searchFieldEdit.Properties.Items.Add(all);
|
||||
if (columns != null)
|
||||
{
|
||||
foreach (KeyValuePair<string, string> column in columns)
|
||||
{
|
||||
if (!ExtendedReturnSupport.IsSearchableColumn(column.Key) || !fields.Add(column.Key))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string caption = string.IsNullOrWhiteSpace(column.Value) ? column.Key : column.Value;
|
||||
SearchColumnOption option = new SearchColumnOption(column.Key, caption);
|
||||
searchFieldEdit.Properties.Items.Add(option);
|
||||
if (string.Equals(option.FieldName, preferredField, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
selected = option;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
searchFieldEdit.SelectedItem = selected ?? all;
|
||||
selectedSearchField = selected == null ? string.Empty : selected.FieldName;
|
||||
}
|
||||
finally
|
||||
{
|
||||
searchFieldEdit.Properties.EndUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
public void PrepareForOpen()
|
||||
{
|
||||
searchEdit.Text = string.Empty;
|
||||
ClearResultAndFilter();
|
||||
}
|
||||
|
||||
public void ClearResultAndFilter()
|
||||
{
|
||||
resultView.ClearColumnsFilter();
|
||||
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 SearchFieldEdit_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
SearchColumnOption option = searchFieldEdit.SelectedItem as SearchColumnOption;
|
||||
selectedSearchField = option == null ? string.Empty : option.FieldName;
|
||||
}
|
||||
|
||||
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,897 @@
|
||||
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 SearchField;
|
||||
public string ConnectionString;
|
||||
public bool SchemaOnly;
|
||||
}
|
||||
|
||||
private sealed class QueryResult
|
||||
{
|
||||
public DataTable Schema;
|
||||
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();
|
||||
string sourceSql = BuildSourceSql();
|
||||
DataTable cachedSchema = TryGetSchema(sourceSql);
|
||||
if (cachedSchema != null)
|
||||
{
|
||||
ConfigureSearchColumns(cachedSchema);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(EditValue))
|
||||
{
|
||||
QueueSearch(sourceSql, EditValue, string.Empty, false);
|
||||
}
|
||||
else if (cachedSchema == null)
|
||||
{
|
||||
QueueSearch(sourceSql, string.Empty, string.Empty, true);
|
||||
}
|
||||
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.ClearResultAndFilter();
|
||||
RefreshDisplayText();
|
||||
}
|
||||
|
||||
private void Popup_SearchRequested(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
ValidateBusinessConfiguration();
|
||||
string keyword = popup.SearchText;
|
||||
string searchField = popup.SelectedSearchField;
|
||||
popup.ClearResultAndFilter();
|
||||
if (string.IsNullOrWhiteSpace(keyword))
|
||||
{
|
||||
CancelSearch();
|
||||
return;
|
||||
}
|
||||
QueueSearch(BuildSourceSql(), keyword, searchField, false);
|
||||
}
|
||||
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 QueueSearch(string sourceSql, string keyword, string searchField, bool schemaOnly)
|
||||
{
|
||||
SearchRequest request = new SearchRequest();
|
||||
request.Version = Interlocked.Increment(ref queryVersion);
|
||||
request.SourceSql = sourceSql;
|
||||
request.Keyword = keyword;
|
||||
request.SearchField = searchField;
|
||||
request.ConnectionString = SqlHelper._connection.ConnectionString;
|
||||
request.SchemaOnly = schemaOnly;
|
||||
|
||||
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);
|
||||
DeliverResult(request, result);
|
||||
}
|
||||
}
|
||||
|
||||
private QueryResult Query(SearchRequest request)
|
||||
{
|
||||
QueryResult result = new QueryResult();
|
||||
try
|
||||
{
|
||||
DataTable sourceSchema = GetSchema(request.SourceSql, request.ConnectionString);
|
||||
result.Schema = sourceSchema;
|
||||
IList<ExtendedReturnFieldMapping> mappings = ExtendedReturnSupport.ParseResultFields(Model.ResultFields);
|
||||
ValidateSourceColumns(sourceSchema.Columns, mappings);
|
||||
if (!request.SchemaOnly)
|
||||
{
|
||||
string searchSql = ExtendedReturnSupport.BuildSearchSql(
|
||||
request.SourceSql, sourceSchema.Columns, MaxRows, request.SearchField);
|
||||
result.Table = ExecuteQuery(
|
||||
searchSql,
|
||||
ExtendedReturnSupport.BuildLikeParameterValue(request.Keyword),
|
||||
request.ConnectionString);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
result.Error = ex;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private DataTable TryGetSchema(string sourceSql)
|
||||
{
|
||||
lock (schemaSyncRoot)
|
||||
{
|
||||
if (schema != null && string.Equals(schemaSql, sourceSql, StringComparison.Ordinal))
|
||||
{
|
||||
return schema;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
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(SearchRequest request, QueryResult result)
|
||||
{
|
||||
if (disposed || !IsHandleCreated) return;
|
||||
|
||||
MethodInvoker deliver = new MethodInvoker(delegate
|
||||
{
|
||||
if (disposed || IsDisposed || request.Version != queryVersion || !popupEdit.IsPopupOpen) return;
|
||||
ConfigureSearchColumns(result.Schema);
|
||||
if (result.Error != null)
|
||||
{
|
||||
MessageUtil.Show("扩展搜索查询失败:" + result.Error.Message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.Table != null)
|
||||
{
|
||||
popup.ResultGrid.DataSource = result.Table;
|
||||
ConfigureResultColumns(result.Table);
|
||||
}
|
||||
});
|
||||
|
||||
try
|
||||
{
|
||||
BeginInvoke(deliver);
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private void ConfigureSearchColumns(DataTable sourceSchema)
|
||||
{
|
||||
if (sourceSchema == null) return;
|
||||
|
||||
List<KeyValuePair<string, string>> options = new List<KeyValuePair<string, string>>();
|
||||
IList<ExtendedReturnFieldMapping> mappings =
|
||||
ExtendedReturnSupport.ParseResultFields(Model.ResultFields);
|
||||
foreach (DataColumn column in sourceSchema.Columns)
|
||||
{
|
||||
if (!ExtendedReturnSupport.IsSearchableColumn(column.ColumnName)) continue;
|
||||
|
||||
options.Add(new KeyValuePair<string, string>(
|
||||
column.ColumnName,
|
||||
GetColumnCaption(column.ColumnName, mappings)));
|
||||
}
|
||||
popup.SetSearchColumns(options);
|
||||
}
|
||||
|
||||
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);
|
||||
column.OptionsFilter.AutoFilterCondition = AutoFilterCondition.Contains;
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,6 +46,13 @@ namespace Lskj.Control
|
||||
/// </summary>
|
||||
private bool _working = false;
|
||||
private List<string> _queryQueue = new List<string>();
|
||||
private LatestValueWorker<PopupQueryRequest> _queryWorker;
|
||||
|
||||
private sealed class PopupQueryRequest
|
||||
{
|
||||
public string SqlValue;
|
||||
public bool IsNewPopup;
|
||||
}
|
||||
/// <summary>
|
||||
/// The _popup
|
||||
/// </summary>
|
||||
@@ -307,7 +314,9 @@ namespace Lskj.Control
|
||||
{
|
||||
InitializeComponent();
|
||||
InitializePopup();
|
||||
_queryWorker = new LatestValueWorker<PopupQueryRequest>(ExecuteLatestPopupQuery);
|
||||
InitializeEvent();
|
||||
this.Disposed += OnDisposed;
|
||||
//this.Properties.Buttons[0].Kind = DevExpress.XtraEditors.Controls.ButtonPredefines.Down;
|
||||
}
|
||||
|
||||
@@ -361,9 +370,7 @@ namespace Lskj.Control
|
||||
this.ShowPopup();
|
||||
}
|
||||
|
||||
Thread queryThread = new Thread(CalcPopupSize);
|
||||
queryThread.IsBackground = true;
|
||||
queryThread.Start(Popup);
|
||||
ThreadPool.QueueUserWorkItem(CalcPopupSize, Popup);
|
||||
}
|
||||
/// <summary>
|
||||
/// <para>说明:计算弹出控件位置</para>
|
||||
@@ -551,16 +558,7 @@ namespace Lskj.Control
|
||||
sqlValue = ControlObj.ReplaceControlValue(sourceSql);
|
||||
}
|
||||
|
||||
if (!this._working)
|
||||
{
|
||||
Thread thread = new Thread(new ParameterizedThreadStart(RefreshPopupDataSource));
|
||||
thread.IsBackground = true;
|
||||
thread.Start(sqlValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
this._queryQueue.Add(sqlValue);
|
||||
}
|
||||
QueuePopupQuery(sqlValue, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -656,9 +654,9 @@ namespace Lskj.Control
|
||||
string sql = MainImpl.GetDefaultValue(this._queryQueue.Last());
|
||||
sql = ReplaceHelper.ReplaceParam(sql);
|
||||
// 在检索过程中还存在输入数据,则拿最后一次数据在进行匹配一次
|
||||
Thread thread = new Thread(new ParameterizedThreadStart(RefreshPopupDataSource));
|
||||
thread.IsBackground = true;
|
||||
thread.Start(sql);
|
||||
ThreadPool.QueueUserWorkItem(
|
||||
RefreshPopupDataSource,
|
||||
sql);
|
||||
|
||||
this._queryQueue.Clear();
|
||||
}
|
||||
@@ -1403,17 +1401,78 @@ namespace Lskj.Control
|
||||
sqlValue = ControlObj.ReplaceControlValue(sourceSql.Replace("#", ""));
|
||||
}
|
||||
|
||||
if (!this._working)
|
||||
QueuePopupQuery(sqlValue, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void QueuePopupQuery(string sqlValue, bool isNewPopup)
|
||||
{
|
||||
if (_queryWorker == null || IsDisposed || Disposing)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_working = true;
|
||||
if (Popup != null)
|
||||
{
|
||||
Popup.LabelObj.Text = "正在筛选数据,请稍后...";
|
||||
Popup.BottomPanelObj.Visible = true;
|
||||
Popup.GridControlObj.DataSourceTable().Clear();
|
||||
}
|
||||
|
||||
_queryWorker.Queue(new PopupQueryRequest
|
||||
{
|
||||
SqlValue = sqlValue,
|
||||
IsNewPopup = isNewPopup
|
||||
});
|
||||
}
|
||||
|
||||
private void ExecuteLatestPopupQuery(PopupQueryRequest request, int version)
|
||||
{
|
||||
DateTime beginTime = DateTime.Now;
|
||||
DataTable table = new DataTable();
|
||||
|
||||
if (request != null && !string.IsNullOrWhiteSpace(request.SqlValue))
|
||||
{
|
||||
try
|
||||
{
|
||||
Thread thread = new Thread(new ParameterizedThreadStart(RefreshPopupDataSourceNew));
|
||||
thread.IsBackground = true;
|
||||
thread.Start(sqlValue);
|
||||
table = SqlHelper.ExecuteDataTable(request.SqlValue);
|
||||
}
|
||||
else
|
||||
catch
|
||||
{
|
||||
this._queryQueue.Add(sqlValue);
|
||||
table = new DataTable();
|
||||
}
|
||||
}
|
||||
|
||||
DateTime endTime = DateTime.Now;
|
||||
if (_queryWorker == null || !_queryWorker.IsCurrent(version) || IsDisposed || Disposing || !IsHandleCreated)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
BeginInvoke(new MethodInvoker(delegate
|
||||
{
|
||||
if (_queryWorker == null || !_queryWorker.IsCurrent(version) || IsDisposed || Disposing || Popup == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int second = Convert.ToInt32((endTime - beginTime).TotalSeconds);
|
||||
string tipMsg = "数据筛选完成.";
|
||||
Popup.LabelObj.Text = second > 0 ? string.Format(tipMsg + "(耗时{0}秒)", second) : tipMsg;
|
||||
Popup.GridControlObj.DataSource = table;
|
||||
_working = false;
|
||||
if (request != null && !request.IsNewPopup)
|
||||
{
|
||||
CalcFormAndGrid();
|
||||
}
|
||||
}));
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshPopupDataSourceNew(object sqlValue)
|
||||
@@ -1449,9 +1508,9 @@ namespace Lskj.Control
|
||||
if (this._queryQueue.Count > 0)
|
||||
{
|
||||
// 在检索过程中还存在输入数据,则拿最后一次数据在进行匹配一次
|
||||
Thread thread = new Thread(new ParameterizedThreadStart(RefreshPopupDataSourceNew));
|
||||
thread.IsBackground = true;
|
||||
thread.Start(this._queryQueue.Last());
|
||||
ThreadPool.QueueUserWorkItem(
|
||||
RefreshPopupDataSourceNew,
|
||||
this._queryQueue.Last());
|
||||
|
||||
this._queryQueue.Clear();
|
||||
}
|
||||
@@ -1478,5 +1537,21 @@ namespace Lskj.Control
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisposed(object sender, EventArgs e)
|
||||
{
|
||||
if (_queryWorker != null)
|
||||
{
|
||||
_queryWorker.Dispose();
|
||||
_queryWorker = null;
|
||||
}
|
||||
_working = false;
|
||||
_queryQueue.Clear();
|
||||
if (_popup != null)
|
||||
{
|
||||
_popup.Dispose();
|
||||
_popup = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,7 +258,8 @@ namespace Lskj.Control
|
||||
DataRow gridRow = this.GridView.GetDataRow(e.RowHandle);
|
||||
foreach (DataRow item in this.GridRowColorsTable.Rows)
|
||||
{
|
||||
string cond = ReplaceHelper.ReplaceRowParam(gridRow, item["condition"] + "");
|
||||
//string cond = ReplaceHelper.ReplaceRowParam(gridRow, item["condition"] + "");
|
||||
string cond = ReplaceHelper.ReplaceRowParamEmptyWrapQuote(gridRow, item["condition"] + "");
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(cond) && ReplaceHelper.EvalCond(cond))
|
||||
@@ -360,7 +361,8 @@ namespace Lskj.Control
|
||||
continue;
|
||||
}
|
||||
}
|
||||
cond = ReplaceHelper.ReplaceRowParam(gridRow, item["condition"] + "").ReplaceColumnParam(e.Column.Name, e.Column.Caption, e.CellValue + "");
|
||||
//cond = ReplaceHelper.ReplaceRowParam(gridRow, item["condition"] + "").ReplaceColumnParam(e.Column.Name, e.Column.Caption, e.CellValue + "");
|
||||
cond = ReplaceHelper.ReplaceRowParamEmptyWrapQuote(gridRow, item["condition"] + "").ReplaceColumnParam(e.Column.Name, e.Column.Caption, e.CellValue + "");
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(cond) && ReplaceHelper.EvalCond(cond) && (!string.IsNullOrEmpty(e.CellValue + "") || isLaterDatePresent|| SystemInfo.Instance.isBlankCellColor))
|
||||
|
||||
@@ -75,12 +75,14 @@ namespace Lskj.Control
|
||||
case ControlType.LabDate:
|
||||
case ControlType.LabDateTime:
|
||||
case ControlType.LabDateTimeShort:
|
||||
case ControlType.LabTime:
|
||||
case ControlType.LabShortTime:
|
||||
// 日期控件
|
||||
LabelDateEdit dateEdit = this as LabelDateEdit;
|
||||
UpdContrast = dateEdit.TextEdit.EditValue == null ? dateEdit.EditText : dateEdit.TextEdit.EditValue.ToString();
|
||||
break;
|
||||
case ControlType.LabTime:
|
||||
case ControlType.LabShortTime:
|
||||
LabelTimeEdit timeEdit = this as LabelTimeEdit;
|
||||
return timeEdit != null && !timeEdit.IsSameTime(this.Model.Text);
|
||||
}
|
||||
return this.Model == null || this.Model.Text == null || !this.Model.Text.Equals(UpdContrast, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Lskj.Business;
|
||||
using Lskj.Model;
|
||||
using Lskj.Util;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -56,6 +57,19 @@ namespace Lskj.Control.BrowserSetting
|
||||
return contextMenuHandler;
|
||||
}
|
||||
protected override bool OnProcessMessageReceived(CefBrowser browser, CefFrame frame, CefProcessId sourceProcess, CefProcessMessage message)
|
||||
{
|
||||
try
|
||||
{
|
||||
return OnProcessMessageReceivedCore(browser, frame, sourceProcess, message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
ReportProcessMessageFailure(exception);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private bool OnProcessMessageReceivedCore(CefBrowser browser, CefFrame frame, CefProcessId sourceProcess, CefProcessMessage message)
|
||||
{
|
||||
if (message.Name.Equals("OpenModule"))
|
||||
{
|
||||
@@ -150,6 +164,46 @@ namespace Lskj.Control.BrowserSetting
|
||||
|
||||
return base.OnProcessMessageReceived(browser, frame, sourceProcess, message);
|
||||
}
|
||||
|
||||
private static void ReportProcessMessageFailure(Exception exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
LogHelper.Instance.WriteError(exception);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Logging must never rethrow across the native CEF callback.
|
||||
}
|
||||
|
||||
Action showError = () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
MessageUtil.Show(exception);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Error reporting must never terminate the browser callback.
|
||||
}
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
System.Windows.Forms.Control mainControl = ERPInfo.Instance.MainControl;
|
||||
if (mainControl == null || mainControl.IsDisposed || !mainControl.IsHandleCreated)
|
||||
return;
|
||||
|
||||
if (mainControl.InvokeRequired)
|
||||
mainControl.BeginInvoke(showError);
|
||||
else
|
||||
showError();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// The main window may close while the CEF callback is reporting.
|
||||
}
|
||||
}
|
||||
public void Created(CefBrowser cefBrowser)
|
||||
{
|
||||
if (OnCreated != null)
|
||||
|
||||
@@ -7,8 +7,6 @@ using Lskj.Control.Model;
|
||||
using Lskj.Data;
|
||||
using Lskj.Model;
|
||||
using Lskj.Util;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
@@ -108,7 +106,7 @@ namespace Lskj.Control.BrowserSetting
|
||||
menu.Model = new DynamicModel(new string[] { MenuName, ERPInfo.Instance.UserId, ERPInfo.Instance.UserName, "1", mMenuCode });
|
||||
//DataRow[] dataRows = JsonHandler.ParseJsonArrayToDataRows(arrayItem);
|
||||
//JArray jArray = (JArray)JsonConvert.DeserializeObject(arrayItem);
|
||||
DataTable dataTable = JsonConvert.DeserializeObject<DataTable>(arrayItem);
|
||||
DataTable dataTable = JsonUtil.ToDataTablePreservingComplexValues(arrayItem);
|
||||
if (dataTable != null && dataTable.Rows.Count > 0)
|
||||
{
|
||||
menu.ExecRightMenu(menuModel, dataTable.Select());
|
||||
@@ -323,10 +321,7 @@ namespace Lskj.Control.BrowserSetting
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(rowdata) && StaticControl.RightMenuGridView != null)
|
||||
{
|
||||
JObject rowObject = JsonConvert.DeserializeObject<JObject>(rowdata);
|
||||
JArray jArray = new JArray();
|
||||
jArray.Add(rowObject);
|
||||
DataTable dataTable = JsonConvert.DeserializeObject<DataTable>(JsonConvert.SerializeObject(jArray));
|
||||
DataTable dataTable = JsonUtil.ToDataTablePreservingComplexValues(rowdata);
|
||||
|
||||
|
||||
DataTable gridTable = (StaticControl.RightMenuGridView.GridControl.DataSource as DataTable).TrimDeleteRows();
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+3
-1
@@ -28,6 +28,7 @@
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this.pl_buttom = new DevExpress.XtraEditors.PanelControl();
|
||||
this.panelControl1 = new DevExpress.XtraEditors.PanelControl();
|
||||
this.btnAdd = new DevExpress.XtraEditors.SimpleButton();
|
||||
@@ -35,7 +36,7 @@
|
||||
this.btnDel = new DevExpress.XtraEditors.SimpleButton();
|
||||
this.btnSave = new DevExpress.XtraEditors.SimpleButton();
|
||||
this.spreadsheetControl1 = new DevExpress.XtraSpreadsheet.SpreadsheetControl();
|
||||
this.barManager1 = new DevExpress.XtraBars.BarManager();
|
||||
this.barManager1 = new DevExpress.XtraBars.BarManager(this.components);
|
||||
this.commonBar1 = new DevExpress.XtraSpreadsheet.UI.CommonBar();
|
||||
this.spreadsheetCommandBarButtonItem1 = new DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem();
|
||||
this.spreadsheetCommandBarButtonItem2 = new DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem();
|
||||
@@ -51,6 +52,7 @@
|
||||
this.barDockControlLeft = new DevExpress.XtraBars.BarDockControl();
|
||||
this.barDockControlRight = new DevExpress.XtraBars.BarDockControl();
|
||||
this.spreadsheetBarController1 = new DevExpress.XtraSpreadsheet.UI.SpreadsheetBarController();
|
||||
this.components.Add(this.spreadsheetBarController1);
|
||||
((System.ComponentModel.ISupportInitialize)(this.pl_buttom)).BeginInit();
|
||||
this.pl_buttom.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.panelControl1)).BeginInit();
|
||||
|
||||
@@ -654,13 +654,14 @@ namespace Lskj.Control
|
||||
if (parametersArray.Length > i)
|
||||
{
|
||||
string commandParameter = parametersArray[i];
|
||||
//string field = commandParameter.Replace("@", "").Replace("{", "").Replace("}", "");
|
||||
string field = commandParameter.Replace("@", "").Replace("{", "").Replace("}", "");
|
||||
//string value = focusedRow.Table.Columns.Contains(field) ? focusedRow[field] + "" : commandParameter.Replace("@", "");
|
||||
//value = SearchObj.ReplaceControlValue(value);
|
||||
//value = TopControlObj.ReplaceControlValue(value);
|
||||
//value = ReplaceControlValue(value, MainControlPanel);
|
||||
//value = value.Replace("@", "").Replace("{", "").Replace("}", "");
|
||||
//sqlParameter.Value = value;
|
||||
sqlParameter.Value = field;
|
||||
}
|
||||
}
|
||||
SqlParameter returnValue = new SqlParameter("@return", SqlDbType.Int, 4);
|
||||
@@ -670,16 +671,19 @@ namespace Lskj.Control
|
||||
if (!(returnValue.Value + "").Equals("1"))
|
||||
{
|
||||
SqlParameter outSqlParameter = sqlParameters.Cast<SqlParameter>().Where(n => n.Direction == ParameterDirection.Output).FirstOrDefault();
|
||||
string msg = "导入后执行sql失败";
|
||||
if (outSqlParameter != null)
|
||||
{
|
||||
string outMessage = outSqlParameter.Value + "";
|
||||
if (!string.IsNullOrEmpty(outMessage))
|
||||
{
|
||||
MessageUtil.Show("导入后执行sql失败:" + outSqlParameter.Value + "");
|
||||
msg="导入后执行sql失败:" + outSqlParameter.Value + "";
|
||||
}
|
||||
}
|
||||
MessageUtil.Show(msg);
|
||||
string deleteSql = string.Format("delete from {0} where {1}='1'", this._tableName, this._importFlag);
|
||||
SqlHelper.ExecuteNonQuery(deleteSql);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -25,6 +25,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
@@ -36,6 +37,11 @@ namespace Lskj.Control
|
||||
/// </summary>
|
||||
public partial class FrmExport : Form
|
||||
{
|
||||
/// <summary>
|
||||
/// 临时导出表无法执行原表的自定义汇总逻辑,保存原表已经计算完成的总计值。
|
||||
/// </summary>
|
||||
private readonly Dictionary<string, object> _exportCustomSummaryValues = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
public FrmExport()
|
||||
{
|
||||
InitializeComponent();
|
||||
@@ -45,8 +51,57 @@ namespace Lskj.Control
|
||||
gridView1.Appearance.Row.Font = new Font("宋体", 9);
|
||||
gridView1.OptionsView.RowAutoHeight = true;
|
||||
gridView1.RowCellStyle += new RowCellStyleEventHandler(OnGridViewRowCellStyle);
|
||||
gridView1.CustomSummaryCalculate += OnExportCustomSummaryCalculate;
|
||||
Lskj.Control.Model.AutoSizeChange.ControllInitializeSize(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将原表已经计算完成的自定义总计回填到临时导出表。
|
||||
/// </summary>
|
||||
private void OnExportCustomSummaryCalculate(object sender, DevExpress.Data.CustomSummaryEventArgs e)
|
||||
{
|
||||
if (!e.IsTotalSummary || e.SummaryProcess != DevExpress.Data.CustomSummaryProcess.Finalize)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GridSummaryItem summaryItem = e.Item as GridSummaryItem;
|
||||
object summaryValue;
|
||||
if (summaryItem != null && !string.IsNullOrEmpty(summaryItem.FieldName) &&
|
||||
_exportCustomSummaryValues.TryGetValue(summaryItem.FieldName, out summaryValue))
|
||||
{
|
||||
e.TotalValue = summaryValue;
|
||||
e.TotalValueReady = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 百分率自定义汇总在原表中可能已经格式化为字符串,导出前还原为数值。
|
||||
/// </summary>
|
||||
private static object GetExportSummaryValue(GridColumn column, GridSummaryItem summaryItem)
|
||||
{
|
||||
object summaryValue = summaryItem.SummaryValue;
|
||||
string valueText = summaryValue as string;
|
||||
string summaryFormat = summaryItem.DisplayFormat ?? string.Empty;
|
||||
string columnFormat = column == null ? string.Empty : column.DisplayFormat.FormatString;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(valueText) ||
|
||||
(!summaryFormat.Contains("%") && !columnFormat.Contains("%")))
|
||||
{
|
||||
return summaryValue;
|
||||
}
|
||||
|
||||
string percentSymbol = CultureInfo.CurrentCulture.NumberFormat.PercentSymbol;
|
||||
string numericText = valueText.Replace(percentSymbol, string.Empty).Replace("%", string.Empty).Trim();
|
||||
decimal percentageValue;
|
||||
if (decimal.TryParse(numericText, NumberStyles.Any, CultureInfo.CurrentCulture, out percentageValue) ||
|
||||
decimal.TryParse(numericText, NumberStyles.Any, CultureInfo.InvariantCulture, out percentageValue))
|
||||
{
|
||||
return percentageValue / 100m;
|
||||
}
|
||||
|
||||
return summaryValue;
|
||||
}
|
||||
/// <summary>
|
||||
/// DataTable转换成Excel文档流(导出数据量超出65535条,分sheet)
|
||||
/// </summary>
|
||||
@@ -105,10 +160,12 @@ namespace Lskj.Control
|
||||
/// <returns>GridControl.</returns>
|
||||
public BandedGridControlEx ReplaceBitColumn(BandedGridControlEx bandGridControlEx, bool IsCustomColumn = false)
|
||||
{
|
||||
_exportCustomSummaryValues.Clear();
|
||||
bool hasBoolean = false;
|
||||
BandedGridView gridView = bandGridControlEx.GridView as BandedGridView;
|
||||
BandedGridControlEx NewBandedGridControlEx = new BandedGridControlEx();
|
||||
BandedGridView gridView2 = NewBandedGridControlEx.GridView as BandedGridView;
|
||||
gridView2.CustomSummaryCalculate += OnExportCustomSummaryCalculate;
|
||||
gridView2.Columns.Clear();//默认有2个列
|
||||
List<string> boolList = new List<string>();
|
||||
List<string> datetimeList = new List<string>();
|
||||
@@ -164,6 +221,8 @@ namespace Lskj.Control
|
||||
newCol.Width = col.Width;
|
||||
newCol.OptionsColumn.AllowEdit = col.OptionsColumn.AllowEdit;
|
||||
newCol.ColumnEdit = boolList.Contains(col.FieldName) || datetimeList.Contains(col.FieldName) ? null : col.ColumnEdit;
|
||||
newCol.DisplayFormat.FormatType = col.DisplayFormat.FormatType;
|
||||
newCol.DisplayFormat.FormatString = col.DisplayFormat.FormatString;
|
||||
|
||||
//多表头默认都有1级标题(默认有空白表头)
|
||||
if (col.OwnerBand != null)
|
||||
@@ -377,6 +436,7 @@ namespace Lskj.Control
|
||||
//底部汇总是否导出
|
||||
if (SystemInfo.Instance.ExportSummary)
|
||||
{
|
||||
gridView.UpdateTotalSummary();
|
||||
for (int i = 1; i < gridView2.Columns.Count; i++)
|
||||
{
|
||||
string columnName = gridView2.Columns[i].FieldName;
|
||||
@@ -384,6 +444,11 @@ namespace Lskj.Control
|
||||
GridSummaryItem gsi = gridView.Columns[columnName].SummaryItem;
|
||||
if (gsi.SummaryType != DevExpress.Data.SummaryItemType.None) //gsi.SummaryValue!=null&& !string.IsNullOrEmpty(gsi.SummaryValue.ToString())
|
||||
{
|
||||
if (gsi.SummaryType == DevExpress.Data.SummaryItemType.Custom)
|
||||
{
|
||||
_exportCustomSummaryValues[columnName] = GetExportSummaryValue(gridView.Columns[columnName], gsi);
|
||||
}
|
||||
|
||||
gridView2.Columns[i].Summary.AddRange(new DevExpress.XtraGrid.GridSummaryItem[] { new DevExpress.XtraGrid.GridColumnSummaryItem(gsi.SummaryType, gridView2.Columns[i].FieldName.ToString(), gsi.DisplayFormat) });
|
||||
|
||||
if (SystemInfo.Instance.GroupSpecialMode)
|
||||
@@ -422,6 +487,7 @@ namespace Lskj.Control
|
||||
public GridControl ReplaceBitColumn(GridControl control, bool IsCustomColumn = false)
|
||||
{
|
||||
GridView gridView = control.FocusedView as GridView;
|
||||
_exportCustomSummaryValues.Clear();
|
||||
bool hasBoolean = false;
|
||||
List<string> boolList = new List<string>();
|
||||
List<string> datetimeList = new List<string>();
|
||||
@@ -481,6 +547,8 @@ namespace Lskj.Control
|
||||
newCol.Width = 100;
|
||||
newCol.OptionsColumn.AllowEdit = col.OptionsColumn.AllowEdit;
|
||||
newCol.ColumnEdit = boolList.Contains(col.FieldName) || datetimeList.Contains(col.FieldName) ? null : col.ColumnEdit;
|
||||
newCol.DisplayFormat.FormatType = col.DisplayFormat.FormatType;
|
||||
newCol.DisplayFormat.FormatString = col.DisplayFormat.FormatString;
|
||||
this.gridView1.Columns.Add(newCol);
|
||||
visibleList.Add(col.FieldName);
|
||||
if (gridModel != null && !dictionary.ContainsKey(col.FieldName))
|
||||
@@ -733,7 +801,9 @@ namespace Lskj.Control
|
||||
if (firstColumn != null)
|
||||
{
|
||||
this.gridView1.OptionsView.ShowFooter = true;
|
||||
firstColumn.Summary.AddRange(new DevExpress.XtraGrid.GridSummaryItem[] { new DevExpress.XtraGrid.GridColumnSummaryItem(DevExpress.Data.SummaryItemType.Count, firstColumn.FieldName.ToString(), "合计: {0:#,###}行") });
|
||||
string firstFieldName = firstColumn.FieldName.ToString();
|
||||
_exportCustomSummaryValues[firstFieldName] = string.Format("合计: {0}行", dtTable.Rows.Count);
|
||||
firstColumn.Summary.AddRange(new DevExpress.XtraGrid.GridSummaryItem[] { new DevExpress.XtraGrid.GridColumnSummaryItem(DevExpress.Data.SummaryItemType.Custom, firstFieldName, "{0}") });
|
||||
|
||||
if (SystemInfo.Instance.GroupSpecialMode)
|
||||
{
|
||||
@@ -748,6 +818,7 @@ namespace Lskj.Control
|
||||
//底部汇总是否导出
|
||||
if (SystemInfo.Instance.ExportSummary)
|
||||
{
|
||||
gridView.UpdateTotalSummary();
|
||||
for (int i = 1; i < this.gridView1.Columns.Count; i++)
|
||||
{
|
||||
string columnName = this.gridView1.Columns[i].FieldName;
|
||||
@@ -755,6 +826,11 @@ namespace Lskj.Control
|
||||
|
||||
if (gsi.SummaryType != DevExpress.Data.SummaryItemType.None) //gsi.SummaryValue!=null&& !string.IsNullOrEmpty(gsi.SummaryValue.ToString())
|
||||
{
|
||||
if (gsi.SummaryType == DevExpress.Data.SummaryItemType.Custom)
|
||||
{
|
||||
_exportCustomSummaryValues[columnName] = GetExportSummaryValue(gridView.Columns[columnName], gsi);
|
||||
}
|
||||
|
||||
string originalFormat = gsi.DisplayFormat;
|
||||
// 匹配 {0:#.##}、{0:0.##} 等格式 避免出现没有小数但是还有小数点的情况,如 0.
|
||||
try
|
||||
@@ -763,7 +839,7 @@ namespace Lskj.Control
|
||||
if (match.Success)
|
||||
{
|
||||
string innerFormat = match.Groups[1].Value;
|
||||
if (innerFormat.Contains("."))
|
||||
if (innerFormat.Contains(".") && innerFormat.Split(';').Length == 1)
|
||||
{
|
||||
// 生成条件格式:正数;负数;零(整数无小数点)
|
||||
string newInnerFormat = $"{innerFormat};{innerFormat};{innerFormat.Split('.')[0]}";
|
||||
|
||||
@@ -1157,7 +1157,10 @@ namespace Lskj.Control
|
||||
if (groupDataTable.Columns.Count > 0)
|
||||
{
|
||||
DataTable orderTable = groupDataTable.Clone();
|
||||
groupDataTable.Select().OrderBy(n => n[groupDataTable.Columns[0]]).CopyToDataTable(orderTable, LoadOption.PreserveChanges);
|
||||
// DataTable中的数据库空值是DBNull,不能直接和String等实际类型比较。
|
||||
// 仅将DBNull作为null参与排序,非空数据仍按字段原始类型排序。
|
||||
DataColumn orderColumn = groupDataTable.Columns[0];
|
||||
groupDataTable.Select().OrderBy(n => n.IsNull(orderColumn) ? null : n[orderColumn]).CopyToDataTable(orderTable, LoadOption.PreserveChanges);
|
||||
InitShowDataGridColumns(orderTable);
|
||||
try
|
||||
{
|
||||
@@ -1331,15 +1334,17 @@ namespace Lskj.Control
|
||||
/// <returns></returns>
|
||||
static int CalcIndicatorBestWidth(DevExpress.XtraGrid.Views.Grid.GridView view)
|
||||
{
|
||||
Graphics graphics = new System.Windows.Forms.Control().CreateGraphics();
|
||||
SizeF sizeF = new SizeF();
|
||||
int count = view.TopRowIndex + ((DevExpress.XtraGrid.Views.Grid.ViewInfo.GridViewInfo)view.GetViewInfo()).RowsInfo.Count;
|
||||
if (count == 0)
|
||||
{
|
||||
count = 30;
|
||||
}
|
||||
sizeF = graphics.MeasureString(count.ToString(), view.Appearance.Row.Font);
|
||||
return Convert.ToInt32(sizeF.Width) + 20;
|
||||
int textWidth = TextRenderer.MeasureText(
|
||||
count.ToString(),
|
||||
view.Appearance.Row.Font,
|
||||
Size.Empty,
|
||||
TextFormatFlags.NoPadding | TextFormatFlags.SingleLine).Width;
|
||||
return textWidth + 20;
|
||||
}
|
||||
/// <summary>
|
||||
/// 计算默认的宽度
|
||||
@@ -1349,16 +1354,18 @@ namespace Lskj.Control
|
||||
static int CalcIndicatorDefaultWidth(DevExpress.XtraGrid.Views.Grid.GridView view)
|
||||
{
|
||||
var grid = view.GridControl;
|
||||
Graphics graphics = new System.Windows.Forms.Control().CreateGraphics();
|
||||
SizeF sizeF = new SizeF();
|
||||
int rowHeight = 22;//22是Row的估计高度
|
||||
if (view.RowHeight > 0)
|
||||
{
|
||||
rowHeight = view.RowHeight;
|
||||
}
|
||||
int count = grid != null ? grid.Height / rowHeight : 30;
|
||||
sizeF = graphics.MeasureString(count.ToString(), view.Appearance.Row.Font);
|
||||
return Convert.ToInt32(sizeF.Width) + 20;
|
||||
int textWidth = TextRenderer.MeasureText(
|
||||
count.ToString(),
|
||||
view.Appearance.Row.Font,
|
||||
Size.Empty,
|
||||
TextFormatFlags.NoPadding | TextFormatFlags.SingleLine).Width;
|
||||
return textWidth + 20;
|
||||
}
|
||||
#endregion
|
||||
#region 选中行颜色改变
|
||||
@@ -2156,4 +2163,4 @@ namespace Lskj.Control
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,6 +94,11 @@ namespace Lskj.Control
|
||||
/// 父容器表格
|
||||
/// </summary>
|
||||
public GridControlEx ParentGridEx;
|
||||
/// <summary>
|
||||
/// 父容器表格条件
|
||||
/// </summary>
|
||||
public MyControl SearchObj;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 源表格
|
||||
@@ -391,6 +396,7 @@ namespace Lskj.Control
|
||||
//提交到数据库
|
||||
try
|
||||
{
|
||||
WaitForm.ShowForm();
|
||||
string sql = "select * from " + _tableName + " where 1<>1";
|
||||
//SqlDataAdapter dat = BaseImpl.GetAdapterResult(sql);
|
||||
//SqlCommandBuilder scb = new SqlCommandBuilder(dat);
|
||||
@@ -678,6 +684,10 @@ namespace Lskj.Control
|
||||
string errorMsg = string.Format("{0}\r\n第{1}行,第{2}列\r\n列名:{3}", mesage, rowNum, colNum, colName);
|
||||
XtraMessageBox.Show("数据提交错误:\n" + errorMsg + "\r\n", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
finally
|
||||
{
|
||||
WaitForm.HideForm();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 数字转换时间格式
|
||||
@@ -954,7 +964,12 @@ namespace Lskj.Control
|
||||
DataRow SelectTheLine = this.ParentGridEx.GetViewFocusedDataRow();
|
||||
fieldValue = ReplaceHelper.ReplaceRowParam(SelectTheLine, fieldValue);
|
||||
}
|
||||
fieldValue= BaseImpl.GetDefaultValue(fieldValue);
|
||||
if (this.SearchObj != null)
|
||||
{
|
||||
fieldValue = this.SearchObj.ReplaceParentControlValue(fieldValue);
|
||||
}
|
||||
|
||||
fieldValue = BaseImpl.GetDefaultValue(fieldValue);
|
||||
if (!string.IsNullOrEmpty(fieldValue))
|
||||
{
|
||||
rowItem[col.FieldName] = fieldValue;
|
||||
|
||||
+3
-4
@@ -31,11 +31,10 @@ namespace Lskj.Control
|
||||
{
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// FrmWebBrowser
|
||||
// FrmWebBrowser2
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Name = "FrmWebBrowser";
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
|
||||
this.Name = "FrmWebBrowser2";
|
||||
this.Size = new System.Drawing.Size(800, 450);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
|
||||
@@ -64,24 +64,35 @@ namespace Lskj.Control
|
||||
private void bsClient_OnCreated(object sender, EventArgs e)
|
||||
{
|
||||
cefBrowserSettings = (CefBrowser)sender;
|
||||
var handle = cefBrowserSettings.GetHost().GetWindowHandle();
|
||||
ResizeWindow(handle, this.Width, this.Height);
|
||||
SyncBrowserBounds();
|
||||
}
|
||||
protected override void OnResize(EventArgs e)
|
||||
{
|
||||
base.OnResize(e);
|
||||
if (cefBrowserSettings != null)
|
||||
SyncBrowserBounds();
|
||||
}
|
||||
/// <summary>
|
||||
/// 将CEF原生子窗口同步到当前控件的客户区,修正高DPI或父容器布局变化造成的位置偏移。
|
||||
/// </summary>
|
||||
public void SyncBrowserBounds()
|
||||
{
|
||||
if (cefBrowserSettings == null || IsDisposed || Disposing ||
|
||||
ClientSize.Width <= 0 || ClientSize.Height <= 0)
|
||||
{
|
||||
ResizeWindow(cefBrowserSettings.GetHost().GetWindowHandle(), Width, Height);
|
||||
return;
|
||||
}
|
||||
|
||||
ResizeWindow(cefBrowserSettings.GetHost().GetWindowHandle(), ClientSize.Width, ClientSize.Height);
|
||||
}
|
||||
public void ResizeWindow(IntPtr handle, int width, int height)
|
||||
{
|
||||
if (handle != IntPtr.Zero)
|
||||
{
|
||||
const uint SWP_NOZORDER = 0x0004;
|
||||
const uint SWP_NOACTIVATE = 0x0010;
|
||||
NativeMethod.SetWindowPos(handle, IntPtr.Zero,
|
||||
0, 0, width, height,
|
||||
0x0002 | 0x0004
|
||||
SWP_NOZORDER | SWP_NOACTIVATE
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+6
-2
@@ -13,9 +13,13 @@
|
||||
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
if (disposing)
|
||||
{
|
||||
components.Dispose();
|
||||
DisposeGridResources();
|
||||
if (components != null)
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+698
-730
File diff suppressed because it is too large
Load Diff
@@ -12,10 +12,15 @@ using DevExpress.XtraGrid.Views.Grid;
|
||||
using DevExpress.XtraGrid.Views.Grid.ViewInfo;
|
||||
|
||||
// Token: 0x02000003 RID: 3
|
||||
public class AmountCellRender
|
||||
public class AmountCellRender : IDisposable
|
||||
{
|
||||
public AmountCellRender(GridView gridView_0)
|
||||
{
|
||||
if (gridView_0 == null)
|
||||
{
|
||||
throw new ArgumentNullException("gridView_0");
|
||||
}
|
||||
|
||||
Class5.gBkiB4AzUqwkh();
|
||||
this.colorGray = Color.FromArgb(189, 185, 185);
|
||||
this.colorGreen = Color.Green;
|
||||
@@ -25,23 +30,58 @@ public class AmountCellRender
|
||||
this.dictionary_0 = new Dictionary<string, Class2>();
|
||||
this.list_0 = new List<GridColumn>();
|
||||
this.object_0 = gridView_0;
|
||||
this.gridControl_0 = this.object_0.GridControl;
|
||||
this.object_0.CustomDrawCell += this.object_0_CustomDrawCell;
|
||||
this.object_0.CustomDrawColumnHeader += this.object_0_CustomDrawColumnHeader;
|
||||
this.object_0.CustomDrawFooterCell += this.object_0_CustomDrawFooterCell;
|
||||
this.object_0.GridControl.Paint += this.method_0;
|
||||
if (this.gridControl_0 != null)
|
||||
{
|
||||
this.gridControl_0.Paint += this.method_0;
|
||||
}
|
||||
}
|
||||
|
||||
private void method_0(object sender, PaintEventArgs e)
|
||||
{
|
||||
BaseViewInfo viewInfo = ((sender as GridControl).FocusedView as GridView).GetViewInfo();
|
||||
if (this.disposed || this.list_0.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GridControl gridControl = sender as GridControl;
|
||||
if (gridControl == null || gridControl.IsDisposed || gridControl.Disposing)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GridView gridView = gridControl.FocusedView as GridView;
|
||||
if (gridView == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GridViewInfo gridViewInfo = gridView.GetViewInfo() as GridViewInfo;
|
||||
if (gridViewInfo == null || gridViewInfo.ColumnsInfo == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (GridColumn gridColumn in this.list_0)
|
||||
{
|
||||
Class2 @class = this.dictionary_0[gridColumn.Name];
|
||||
Class2 @class;
|
||||
if (gridColumn == null ||
|
||||
!this.dictionary_0.TryGetValue(gridColumn.Name, out @class) ||
|
||||
@class == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (@class.IsCountinuousCell())
|
||||
{
|
||||
GridViewInfo gridViewInfo = viewInfo as GridViewInfo;
|
||||
GridColumnInfoArgs gridColumnInfoArgs = gridViewInfo.ColumnsInfo[gridColumn];
|
||||
if (gridColumnInfoArgs == null) return;
|
||||
if (gridColumnInfoArgs == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
int num = 0;
|
||||
int int_;
|
||||
if (@class.method_4())
|
||||
@@ -82,10 +122,16 @@ public class AmountCellRender
|
||||
|
||||
private void object_0_CustomDrawCell(object sender, RowCellCustomDrawEventArgs e)
|
||||
{
|
||||
if (this.dictionary_0.ContainsKey(e.Column.Name))
|
||||
if (this.disposed || e.Column == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Class2 @class;
|
||||
if (this.dictionary_0.TryGetValue(e.Column.Name, out @class) &&
|
||||
@class != null)
|
||||
{
|
||||
e.DisplayText = "";
|
||||
Class2 @class = this.dictionary_0[e.Column.Name];
|
||||
Rectangle bounds = e.Bounds;
|
||||
Rectangle rectangle_ = bounds;
|
||||
Graphics graphics = e.Graphics;
|
||||
@@ -98,14 +144,20 @@ public class AmountCellRender
|
||||
|
||||
private void object_0_CustomDrawFooterCell(object sender, FooterCellCustomDrawEventArgs e)
|
||||
{
|
||||
if (this.dictionary_0.ContainsKey(e.Column.Name))
|
||||
if (this.disposed || e.Column == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Class2 @class;
|
||||
if (this.dictionary_0.TryGetValue(e.Column.Name, out @class) &&
|
||||
@class != null)
|
||||
{
|
||||
Class2 @class = this.dictionary_0[e.Column.Name];
|
||||
if (@class.method_8())
|
||||
{
|
||||
e.Info.DisplayText = "";
|
||||
Rectangle bounds = e.Bounds;
|
||||
@class.method_17(bounds, e.Graphics, e.Appearance.Font, e.Info.Value.ToString());
|
||||
@class.method_17(bounds, e.Graphics, e.Appearance.Font, Convert.ToString(e.Info.Value));
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
@@ -113,13 +165,15 @@ public class AmountCellRender
|
||||
|
||||
private void object_0_CustomDrawColumnHeader(object sender, ColumnHeaderCustomDrawEventArgs e)
|
||||
{
|
||||
if (e.Column == null)
|
||||
if (this.disposed || e.Column == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (this.dictionary_0.ContainsKey(e.Column.Name))
|
||||
|
||||
Class2 @class;
|
||||
if (this.dictionary_0.TryGetValue(e.Column.Name, out @class) &&
|
||||
@class != null)
|
||||
{
|
||||
Class2 @class = this.dictionary_0[e.Column.Name];
|
||||
if (@class.method_6())
|
||||
{
|
||||
e.Column.Caption = "";
|
||||
@@ -204,14 +258,44 @@ public class AmountCellRender
|
||||
|
||||
public void RemoveAmountColumn(GridColumn gridColumn_0)
|
||||
{
|
||||
if (this.dictionary_0.ContainsKey(gridColumn_0.Name))
|
||||
if (gridColumn_0 != null && this.dictionary_0.ContainsKey(gridColumn_0.Name))
|
||||
{
|
||||
this.dictionary_0.Remove(gridColumn_0.Name);
|
||||
this.list_0.Remove(gridColumn_0);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (this.disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.disposed = true;
|
||||
GridView gridView = this.object_0;
|
||||
GridControl gridControl = this.gridControl_0;
|
||||
this.object_0 = null;
|
||||
this.gridControl_0 = null;
|
||||
|
||||
if (gridView != null)
|
||||
{
|
||||
gridView.CustomDrawCell -= this.object_0_CustomDrawCell;
|
||||
gridView.CustomDrawColumnHeader -= this.object_0_CustomDrawColumnHeader;
|
||||
gridView.CustomDrawFooterCell -= this.object_0_CustomDrawFooterCell;
|
||||
}
|
||||
if (gridControl != null)
|
||||
{
|
||||
gridControl.Paint -= this.method_0;
|
||||
}
|
||||
|
||||
this.dictionary_0.Clear();
|
||||
this.list_0.Clear();
|
||||
}
|
||||
|
||||
private GridView object_0;
|
||||
private GridControl gridControl_0;
|
||||
private bool disposed;
|
||||
|
||||
private Color colorGray;
|
||||
private Color colorGreen;
|
||||
|
||||
@@ -255,7 +255,10 @@ public class Class2
|
||||
if (color != Color.Empty)
|
||||
{
|
||||
Rectangle rect = new Rectangle(rectangle_0.Left + i - 2, int_2, int_1, int_3);
|
||||
graphics_0.FillRectangle(new SolidBrush(color), rect);
|
||||
using (SolidBrush solidBrush = new SolidBrush(color))
|
||||
{
|
||||
graphics_0.FillRectangle(solidBrush, rect);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -265,9 +268,12 @@ public class Class2
|
||||
num++;
|
||||
}
|
||||
Rectangle rect2 = new Rectangle(rectangle_0.Left - 1, int_2, int_1 + 1, int_3);
|
||||
graphics_0.FillRectangle(new SolidBrush(Color.FromArgb(161, 157, 157)), rect2);
|
||||
Rectangle rect3 = new Rectangle(rectangle_0.Left + rectangle_0.Width - 1, int_2, int_1 + 1, int_3);
|
||||
graphics_0.FillRectangle(new SolidBrush(Color.FromArgb(161, 157, 157)), rect3);
|
||||
using (SolidBrush solidBrush = new SolidBrush(Color.FromArgb(161, 157, 157)))
|
||||
{
|
||||
graphics_0.FillRectangle(solidBrush, rect2);
|
||||
graphics_0.FillRectangle(solidBrush, rect3);
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x06000028 RID: 40 RVA: 0x00002CC8 File Offset: 0x00000EC8
|
||||
|
||||
@@ -75,6 +75,11 @@ namespace Lskj.Control
|
||||
/// 初始赋值
|
||||
/// </summary>
|
||||
public string ControlValue = string.Empty;
|
||||
/// <summary>
|
||||
/// 保存表格属性用到的key
|
||||
/// </summary>
|
||||
public string CurrentOperColumnKey = string.Empty;
|
||||
|
||||
|
||||
|
||||
public LabelMultiAutoTextEdit()
|
||||
@@ -380,6 +385,7 @@ namespace Lskj.Control
|
||||
_lookUpForm.TextField = TextField;
|
||||
_lookUpForm.SourceSQL = SourceSQL;
|
||||
_lookUpForm.DataSource = dataSource;
|
||||
_lookUpForm.CurrentOperColumnKey = CurrentOperColumnKey;
|
||||
}
|
||||
/// <summary>
|
||||
/// <para>说明:清空选中的值</para>
|
||||
@@ -419,6 +425,7 @@ namespace Lskj.Control
|
||||
_lookUpForm.EditValue = this.EditValue;
|
||||
_lookUpForm.IsType = Model.FieldType;
|
||||
_lookUpForm.EditText = this.TextEdit.Text;
|
||||
_lookUpForm.CurrentOperColumnKey = CurrentOperColumnKey;
|
||||
string sqlValue = string.Empty;
|
||||
if (this.ControlObj != null)
|
||||
{
|
||||
|
||||
@@ -160,9 +160,11 @@ namespace Lskj.Control
|
||||
}
|
||||
else
|
||||
{
|
||||
Graphics g = this.lblText.CreateGraphics();
|
||||
SizeF sizeF = g.MeasureString(value, this.lblText.Font);
|
||||
this.plLeft.Width = (int)sizeF.Width + PaddingLeft;
|
||||
this.plLeft.Width = TextRenderer.MeasureText(
|
||||
value,
|
||||
this.lblText.Font,
|
||||
Size.Empty,
|
||||
TextFormatFlags.NoPadding | TextFormatFlags.SingleLine).Width + PaddingLeft;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,252 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using DevExpress.XtraEditors;
|
||||
|
||||
namespace Lskj.Control
|
||||
{
|
||||
/// <summary>
|
||||
/// 带标题的时间输入控件,使用上下按钮调整时间。
|
||||
/// </summary>
|
||||
public class LabelTimeEdit : BaseUserControl
|
||||
{
|
||||
private readonly Panel plLeft;
|
||||
private readonly Panel plRight;
|
||||
private readonly Label lblText;
|
||||
private readonly TimeEdit txtEdit;
|
||||
private string formatString = "HH:mm:ss";
|
||||
|
||||
public LabelTimeEdit()
|
||||
{
|
||||
plLeft = new Panel();
|
||||
plRight = new Panel();
|
||||
lblText = new Label();
|
||||
txtEdit = new TimeEdit();
|
||||
|
||||
SuspendLayout();
|
||||
plLeft.SuspendLayout();
|
||||
plRight.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)txtEdit.Properties).BeginInit();
|
||||
|
||||
plLeft.BackColor = Color.Transparent;
|
||||
plLeft.Controls.Add(lblText);
|
||||
plLeft.Dock = DockStyle.Left;
|
||||
plLeft.Size = new Size(40, 21);
|
||||
|
||||
lblText.AutoSize = true;
|
||||
lblText.Location = new Point(5, 4);
|
||||
lblText.Text = "名称";
|
||||
|
||||
plRight.Controls.Add(txtEdit);
|
||||
plRight.Dock = DockStyle.Fill;
|
||||
plRight.Location = new Point(40, 0);
|
||||
|
||||
txtEdit.Dock = DockStyle.Fill;
|
||||
txtEdit.EditValue = null;
|
||||
txtEdit.Properties.Buttons.Clear();
|
||||
txtEdit.Properties.Buttons.Add(new DevExpress.XtraEditors.Controls.EditorButton(
|
||||
DevExpress.XtraEditors.Controls.ButtonPredefines.Combo));
|
||||
txtEdit.Properties.TimeEditStyle = DevExpress.XtraEditors.Repository.TimeEditStyle.SpinButtons;
|
||||
|
||||
AutoScaleMode = AutoScaleMode.None;
|
||||
BackColor = Color.Transparent;
|
||||
Controls.Add(plRight);
|
||||
Controls.Add(plLeft);
|
||||
Size = new Size(162, 21);
|
||||
|
||||
((System.ComponentModel.ISupportInitialize)txtEdit.Properties).EndInit();
|
||||
plRight.ResumeLayout(false);
|
||||
plLeft.ResumeLayout(false);
|
||||
plLeft.PerformLayout();
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 时间编辑器。
|
||||
/// </summary>
|
||||
public TimeEdit TextEdit
|
||||
{
|
||||
get { return txtEdit; }
|
||||
}
|
||||
|
||||
public override string LabelText
|
||||
{
|
||||
get { return lblText.Text; }
|
||||
set
|
||||
{
|
||||
lblText.Text = value;
|
||||
if (FontSize > 0)
|
||||
{
|
||||
plLeft.AutoSize = false;
|
||||
lblText.AutoSize = false;
|
||||
lblText.Dock = DockStyle.Fill;
|
||||
lblText.Location = new Point(0, 0);
|
||||
lblText.TextAlign = ContentAlignment.MiddleLeft;
|
||||
txtEdit.Properties.AutoHeight = false;
|
||||
plLeft.Width = value.Length * GetCharWidth();
|
||||
GetCharWidthMultilingual(lblText, lblText.Text, plLeft);
|
||||
}
|
||||
else
|
||||
{
|
||||
plLeft.Width = lblText.Width + PaddingLeft;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override float FontSize
|
||||
{
|
||||
get { return base.FontSize; }
|
||||
set
|
||||
{
|
||||
base.FontSize = value;
|
||||
if (value > 0)
|
||||
{
|
||||
lblText.Font = new Font(lblText.Font.FontFamily, value);
|
||||
txtEdit.Font = new Font(txtEdit.Font.FontFamily, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override string EditText
|
||||
{
|
||||
get { return txtEdit.EditValue == null ? string.Empty : txtEdit.Text; }
|
||||
set
|
||||
{
|
||||
TimeSpan timeValue;
|
||||
txtEdit.EditValue = TryGetTime(value, out timeValue)
|
||||
? (object)DateTime.Today.Add(timeValue)
|
||||
: null;
|
||||
}
|
||||
}
|
||||
|
||||
public override string NullText
|
||||
{
|
||||
get { return txtEdit.Properties.NullValuePrompt; }
|
||||
set
|
||||
{
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
{
|
||||
txtEdit.Properties.NullValuePromptShowForEmptyValue = true;
|
||||
txtEdit.Properties.NullValuePrompt = value;
|
||||
}
|
||||
base.NullText = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool ReadOnly
|
||||
{
|
||||
get { return base.ReadOnly; }
|
||||
set
|
||||
{
|
||||
base.ReadOnly = value;
|
||||
txtEdit.Properties.ReadOnly = value;
|
||||
txtEdit.Enabled = !value;
|
||||
lblText.ForeColor = value ? ReadOnlyLabelForceColor : Required ? RequiredLabelForceColor : DefaultLabelForceColor;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Required
|
||||
{
|
||||
get { return base.Required; }
|
||||
set
|
||||
{
|
||||
base.Required = value;
|
||||
if (value)
|
||||
{
|
||||
lblText.ForeColor = RequiredLabelForceColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override Color BackgroundColor
|
||||
{
|
||||
get { return txtEdit.Properties.Appearance.BackColor; }
|
||||
set { txtEdit.Properties.Appearance.BackColor = value; }
|
||||
}
|
||||
|
||||
public override Color ForeColor
|
||||
{
|
||||
get { return txtEdit.Properties.Appearance.ForeColor; }
|
||||
set { txtEdit.Properties.Appearance.ForeColor = value; }
|
||||
}
|
||||
|
||||
public override bool ContentBold
|
||||
{
|
||||
get { return txtEdit.Properties.Appearance.Font.Bold; }
|
||||
set
|
||||
{
|
||||
Font oldFont = txtEdit.Properties.Appearance.Font;
|
||||
txtEdit.Properties.Appearance.Font = new Font(oldFont.FontFamily, oldFont.Size, value ? FontStyle.Bold : FontStyle.Regular);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置时间的显示和输入格式。
|
||||
/// </summary>
|
||||
public void TimeFormat(string value)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
formatString = value;
|
||||
txtEdit.Properties.DisplayFormat.FormatString = value;
|
||||
txtEdit.Properties.EditFormat.FormatString = value;
|
||||
txtEdit.Properties.DisplayFormat.FormatType = DevExpress.Utils.FormatType.Custom;
|
||||
txtEdit.Properties.EditFormat.FormatType = DevExpress.Utils.FormatType.Custom;
|
||||
txtEdit.Properties.Mask.EditMask = value;
|
||||
txtEdit.Properties.Mask.UseMaskAsDisplayFormat = true;
|
||||
txtEdit.Properties.TimeFormat = value.IndexOf("ss", StringComparison.OrdinalIgnoreCase) >= 0
|
||||
? DevExpress.XtraEditors.Controls.TimeFormat.HourMinSec
|
||||
: DevExpress.XtraEditors.Controls.TimeFormat.HourMin;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 按控件显示精度比较当前值和原值,避免 DateTime/TimeSpan 字符串格式差异造成误判。
|
||||
/// </summary>
|
||||
public bool IsSameTime(string value)
|
||||
{
|
||||
TimeSpan oldTime;
|
||||
TimeSpan currentTime;
|
||||
bool hasOldTime = TryGetTime(value, out oldTime);
|
||||
bool hasCurrentTime = TryGetTime(EditText, out currentTime);
|
||||
if (!hasOldTime || !hasCurrentTime)
|
||||
{
|
||||
return !hasOldTime && !hasCurrentTime;
|
||||
}
|
||||
|
||||
if (formatString.IndexOf("ss", StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
{
|
||||
return oldTime.Hours == currentTime.Hours &&
|
||||
oldTime.Minutes == currentTime.Minutes &&
|
||||
oldTime.Seconds == currentTime.Seconds;
|
||||
}
|
||||
|
||||
return oldTime.Hours == currentTime.Hours && oldTime.Minutes == currentTime.Minutes;
|
||||
}
|
||||
|
||||
private static bool TryGetTime(string value, out TimeSpan timeValue)
|
||||
{
|
||||
timeValue = TimeSpan.Zero;
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (TimeSpan.TryParse(value, out timeValue))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
DateTime dateValue;
|
||||
if (DateTime.TryParse(value, out dateValue))
|
||||
{
|
||||
timeValue = dateValue.TimeOfDay;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace Lskj.Control
|
||||
{
|
||||
/// <summary>
|
||||
/// 串行处理请求,并在繁忙时只保留最后一次请求。
|
||||
/// 用于输入联想控件,避免每次 TextChanged 都创建独立线程。
|
||||
/// </summary>
|
||||
internal sealed class LatestValueWorker<T> : IDisposable
|
||||
{
|
||||
private readonly object _syncRoot = new object();
|
||||
private readonly Action<T, int> _work;
|
||||
private T _pendingValue;
|
||||
private bool _hasPendingValue;
|
||||
private bool _workerRunning;
|
||||
private bool _disposed;
|
||||
private int _version;
|
||||
|
||||
public LatestValueWorker(Action<T, int> work)
|
||||
{
|
||||
if (work == null)
|
||||
{
|
||||
throw new ArgumentNullException("work");
|
||||
}
|
||||
|
||||
_work = work;
|
||||
}
|
||||
|
||||
public int Queue(T value)
|
||||
{
|
||||
bool startWorker = false;
|
||||
int version;
|
||||
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
version = ++_version;
|
||||
_pendingValue = value;
|
||||
_hasPendingValue = true;
|
||||
|
||||
if (!_workerRunning)
|
||||
{
|
||||
_workerRunning = true;
|
||||
startWorker = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (startWorker && !ThreadPool.QueueUserWorkItem(Run))
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
_workerRunning = false;
|
||||
}
|
||||
|
||||
throw new InvalidOperationException("无法启动输入联想查询任务。");
|
||||
}
|
||||
|
||||
return version;
|
||||
}
|
||||
|
||||
public bool IsCurrent(int version)
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
return !_disposed && version == _version;
|
||||
}
|
||||
}
|
||||
|
||||
private void Run(object state)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
T value;
|
||||
int version;
|
||||
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (_disposed || !_hasPendingValue)
|
||||
{
|
||||
_workerRunning = false;
|
||||
return;
|
||||
}
|
||||
|
||||
value = _pendingValue;
|
||||
version = _version;
|
||||
_pendingValue = default(T);
|
||||
_hasPendingValue = false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_work(value, version);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 查询异常由控件自身转换为空结果;这里确保工作循环能够继续或退出。
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
_disposed = true;
|
||||
_hasPendingValue = false;
|
||||
_pendingValue = default(T);
|
||||
_version++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -456,6 +456,7 @@
|
||||
<Compile Include="BlinkBrowser.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="CefBrowserLifetimeCoordinator.cs" />
|
||||
<Compile Include="BrowserSetting2\BsClient.cs" />
|
||||
<Compile Include="BrowserSetting2\BsContextMenuHandler.cs" />
|
||||
<Compile Include="BrowserSetting2\BsDownloadHandler.cs" />
|
||||
@@ -708,6 +709,14 @@
|
||||
<Compile Include="AutoGridLookUp\AutoGridPopup.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="AutoGridLookUp\ExtendedReturnSearchPopup.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="AutoGridLookUp\ExtendedReturnModuleSourceResolver.cs" />
|
||||
<Compile Include="LatestValueWorker.cs" />
|
||||
<Compile Include="AutoGridLookUp\LabelExtendedReturnSearchEdit.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="AutoGridLookUp\AutoGridPopup.Designer.cs">
|
||||
<DependentUpon>AutoGridPopup.cs</DependentUpon>
|
||||
</Compile>
|
||||
@@ -919,6 +928,7 @@
|
||||
<DependentUpon>LabelWeigh.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Model\AttachHelper.cs" />
|
||||
<Compile Include="Model\AltButtonShortcutManager.cs" />
|
||||
<Compile Include="AuditPanelEx.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
@@ -1161,6 +1171,10 @@
|
||||
<Compile Include="GridControlEx.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="GridControlEx.ExtendedReturn.cs">
|
||||
<DependentUpon>GridControlEx.cs</DependentUpon>
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="GridControlEx.Designer.cs">
|
||||
<DependentUpon>GridControlEx.cs</DependentUpon>
|
||||
</Compile>
|
||||
@@ -1206,6 +1220,9 @@
|
||||
<Compile Include="LabelDateEdit.Designer.cs">
|
||||
<DependentUpon>LabelDateEdit.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="LabelTimeEdit.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="LabelImageEdit.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
@@ -1263,6 +1280,7 @@
|
||||
<Compile Include="Model\ControlModel.cs" />
|
||||
<Compile Include="Model\ControlType.cs" />
|
||||
<Compile Include="Model\DateFormat.cs" />
|
||||
<Compile Include="Model\ExtendedReturnSupport.cs" />
|
||||
<Compile Include="Model\GridColumnModel.cs" />
|
||||
<Compile Include="Model\GridRowColorModel.cs" />
|
||||
<Compile Include="Model\MessageUtil.cs" />
|
||||
@@ -1880,4 +1898,4 @@
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows.Forms;
|
||||
using DevExpress.XtraEditors;
|
||||
|
||||
namespace Lskj.Control.Model
|
||||
{
|
||||
/// <summary>
|
||||
/// 将按钮原有的 & 助记键改为必须按 Alt 才能触发的快捷键。
|
||||
/// </summary>
|
||||
public sealed class AltButtonShortcutManager
|
||||
{
|
||||
private sealed class ShortcutItem
|
||||
{
|
||||
public SimpleButton Button;
|
||||
public Keys Key;
|
||||
}
|
||||
|
||||
private readonly List<ShortcutItem> mShortcutItems =
|
||||
new List<ShortcutItem>();
|
||||
private bool mUpdatingText;
|
||||
|
||||
/// <summary>
|
||||
/// 注册按钮快捷键,并移除标题中的 &,保持界面显示为“按钮名(X)”。
|
||||
/// </summary>
|
||||
public void Register(SimpleButton button, Keys defaultKey)
|
||||
{
|
||||
if (button == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ShortcutItem item = mShortcutItems.Find(
|
||||
shortcut => ReferenceEquals(shortcut.Button, button));
|
||||
if (item == null)
|
||||
{
|
||||
item = new ShortcutItem { Button = button, Key = defaultKey };
|
||||
mShortcutItems.Add(item);
|
||||
button.TextChanged += OnButtonTextChanged;
|
||||
}
|
||||
|
||||
UpdateShortcut(item, defaultKey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 只响应 Alt+原助记键;未按 Alt、同时按下其他修饰键时均不处理。
|
||||
/// </summary>
|
||||
public bool ProcessKey(Keys keyData)
|
||||
{
|
||||
if ((keyData & Keys.Modifiers) != Keys.Alt)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Keys keyCode = keyData & Keys.KeyCode;
|
||||
foreach (ShortcutItem item in mShortcutItems)
|
||||
{
|
||||
SimpleButton button = item.Button;
|
||||
if (item.Key == keyCode && button != null &&
|
||||
!button.IsDisposed && button.Visible && button.Enabled)
|
||||
{
|
||||
button.PerformClick();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void OnButtonTextChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (mUpdatingText)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SimpleButton button = sender as SimpleButton;
|
||||
ShortcutItem item = mShortcutItems.Find(
|
||||
shortcut => ReferenceEquals(shortcut.Button, button));
|
||||
if (item != null)
|
||||
{
|
||||
UpdateShortcut(item, item.Key);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateShortcut(ShortcutItem item, Keys defaultKey)
|
||||
{
|
||||
string text = item.Button.Text ?? string.Empty;
|
||||
int mnemonicIndex = FindMnemonicIndex(text);
|
||||
if (mnemonicIndex >= 0)
|
||||
{
|
||||
item.Key = (Keys)char.ToUpperInvariant(text[mnemonicIndex + 1]);
|
||||
mUpdatingText = true;
|
||||
try
|
||||
{
|
||||
item.Button.Text = text.Remove(mnemonicIndex, 1);
|
||||
}
|
||||
finally
|
||||
{
|
||||
mUpdatingText = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
item.Key = defaultKey;
|
||||
}
|
||||
}
|
||||
|
||||
private static int FindMnemonicIndex(string text)
|
||||
{
|
||||
for (int index = 0; index < text.Length - 1; index++)
|
||||
{
|
||||
if (text[index] == '&' && char.IsLetterOrDigit(text[index + 1]))
|
||||
{
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -182,7 +182,10 @@ namespace Lskj.Control.Model
|
||||
/// 判断两个值是否相同。
|
||||
/// 优先按日期、数字进行值比较,最后再按普通字符串比较。
|
||||
/// </summary>
|
||||
private static bool IsSameValue(string oldValue, string newValue)
|
||||
/// <param name="oldValue">原始值</param>
|
||||
/// <param name="newValue">当前值</param>
|
||||
/// <returns>两个值在统一格式后是否相同</returns>
|
||||
public static bool IsSameValue(string oldValue, string newValue)
|
||||
{
|
||||
oldValue = NormalizeValue(oldValue);
|
||||
newValue = NormalizeValue(newValue);
|
||||
|
||||
@@ -26,8 +26,68 @@ namespace Lskj.Control.Model
|
||||
/// <summary>
|
||||
/// 表格拖拽到表格
|
||||
/// </summary>
|
||||
public class BandedGridDragGrid
|
||||
public class BandedGridDragGrid : IDisposable
|
||||
{
|
||||
private bool _disposed;
|
||||
|
||||
internal static void DisposeRegistrations(
|
||||
Dictionary<BandedGridView, List<BandedGridDragGrid>> sourceRegistrations,
|
||||
Dictionary<GridView, List<BandedGridDragGrid>> targetRegistrations,
|
||||
BandedGridView sourceGridView,
|
||||
GridView targetGridView)
|
||||
{
|
||||
DisposeSourceRegistrations(sourceRegistrations, sourceGridView);
|
||||
DisposeTargetRegistrations(targetRegistrations, targetGridView);
|
||||
}
|
||||
|
||||
private static void DisposeSourceRegistrations(
|
||||
Dictionary<BandedGridView, List<BandedGridDragGrid>> registrations,
|
||||
BandedGridView gridView)
|
||||
{
|
||||
foreach (KeyValuePair<BandedGridView, List<BandedGridDragGrid>> entry in registrations.ToList())
|
||||
{
|
||||
bool removeKey = ReferenceEquals(entry.Key, gridView);
|
||||
foreach (BandedGridDragGrid registration in entry.Value.ToList())
|
||||
{
|
||||
if (removeKey || registration == null || registration._disposed || registration.References(gridView))
|
||||
{
|
||||
if (registration != null)
|
||||
registration.Dispose();
|
||||
entry.Value.Remove(registration);
|
||||
}
|
||||
}
|
||||
if (removeKey || entry.Value.Count == 0)
|
||||
registrations.Remove(entry.Key);
|
||||
}
|
||||
}
|
||||
|
||||
private static void DisposeTargetRegistrations(
|
||||
Dictionary<GridView, List<BandedGridDragGrid>> registrations,
|
||||
GridView gridView)
|
||||
{
|
||||
foreach (KeyValuePair<GridView, List<BandedGridDragGrid>> entry in registrations.ToList())
|
||||
{
|
||||
bool removeKey = ReferenceEquals(entry.Key, gridView);
|
||||
foreach (BandedGridDragGrid registration in entry.Value.ToList())
|
||||
{
|
||||
if (removeKey || registration == null || registration._disposed || registration.References(gridView))
|
||||
{
|
||||
if (registration != null)
|
||||
registration.Dispose();
|
||||
entry.Value.Remove(registration);
|
||||
}
|
||||
}
|
||||
if (removeKey || entry.Value.Count == 0)
|
||||
registrations.Remove(entry.Key);
|
||||
}
|
||||
}
|
||||
|
||||
internal bool References(GridView gridView)
|
||||
{
|
||||
return gridView != null &&
|
||||
(ReferenceEquals(_sourceGridView, gridView) ||
|
||||
ReferenceEquals(_targetGridView, gridView));
|
||||
}
|
||||
/// <summary>
|
||||
/// 是否正在拖拽
|
||||
/// </summary>
|
||||
@@ -106,6 +166,99 @@ namespace Lskj.Control.Model
|
||||
this._targetGridView.GridControl.DragEnter += new System.Windows.Forms.DragEventHandler(gridControl_DragEnter);
|
||||
this._targetGridView.GridControl.DragDrop += new System.Windows.Forms.DragEventHandler(gridControl_DragDrop);
|
||||
this._targetGridView.GridControl.DragLeave += new EventHandler(gridControl_DragLeave);
|
||||
this._sourceGridView.Disposed += OnGridViewDisposed;
|
||||
if (!ReferenceEquals(this._sourceGridView, this._targetGridView))
|
||||
{
|
||||
this._targetGridView.Disposed += OnGridViewDisposed;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnGridViewDisposed(object sender, EventArgs e)
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_disposed = true;
|
||||
BandedGridView sourceGridView = _sourceGridView;
|
||||
GridView targetGridView = _targetGridView;
|
||||
|
||||
if (sourceGridView != null)
|
||||
{
|
||||
sourceGridView.MouseDown -= sourceGridView_MouseDown;
|
||||
sourceGridView.MouseMove -= sourceGridView_MouseMove;
|
||||
sourceGridView.MouseUp -= sourceGridView_MouseUp;
|
||||
sourceGridView.RowClick -= OnRowClick;
|
||||
sourceGridView.Disposed -= OnGridViewDisposed;
|
||||
}
|
||||
|
||||
if (targetGridView != null)
|
||||
{
|
||||
if (targetGridView.GridControl != null)
|
||||
{
|
||||
targetGridView.GridControl.DragOver -= gridControl_DragOver;
|
||||
targetGridView.GridControl.DragEnter -= gridControl_DragEnter;
|
||||
targetGridView.GridControl.DragDrop -= gridControl_DragDrop;
|
||||
targetGridView.GridControl.DragLeave -= gridControl_DragLeave;
|
||||
}
|
||||
|
||||
if (!ReferenceEquals(sourceGridView, targetGridView))
|
||||
{
|
||||
targetGridView.Disposed -= OnGridViewDisposed;
|
||||
}
|
||||
}
|
||||
|
||||
RemoveRegistration(
|
||||
StaticBandedControl.BandedGridViewDragGridDic,
|
||||
sourceGridView,
|
||||
this);
|
||||
RemoveRegistration(
|
||||
StaticBandedControl.BandedTargetViewDragGridDic,
|
||||
targetGridView,
|
||||
this);
|
||||
|
||||
if (ReferenceEquals(
|
||||
StaticBandedControl.SourceDragBandedGridView,
|
||||
sourceGridView))
|
||||
{
|
||||
StaticBandedControl.SourceDragBandedGridView = null;
|
||||
}
|
||||
|
||||
OnDragComplete = null;
|
||||
DragHander.Clear();
|
||||
_hitInfo = null;
|
||||
_sourceGridView = null;
|
||||
_targetGridView = null;
|
||||
}
|
||||
|
||||
private static void RemoveRegistration<TKey>(
|
||||
Dictionary<TKey, List<BandedGridDragGrid>> registrations,
|
||||
TKey key,
|
||||
BandedGridDragGrid registration)
|
||||
where TKey : class
|
||||
{
|
||||
if (key == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<BandedGridDragGrid> registrationsForView;
|
||||
if (!registrations.TryGetValue(key, out registrationsForView))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
registrationsForView.Remove(registration);
|
||||
if (registrationsForView.Count == 0)
|
||||
{
|
||||
registrations.Remove(key);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 点击时候判断位置
|
||||
|
||||
@@ -22,6 +22,7 @@ using System.IO;
|
||||
using System.Data.SqlClient;
|
||||
using Lskj.Business;
|
||||
using DevExpress.XtraGrid.Views.Grid;
|
||||
using Lskj.Core;
|
||||
|
||||
namespace Lskj.Control.Model
|
||||
{
|
||||
@@ -38,6 +39,12 @@ namespace Lskj.Control.Model
|
||||
/// </summary>
|
||||
private MyControl _controlObj;
|
||||
public bool issuccess = true;
|
||||
|
||||
/// <summary>
|
||||
/// 最初账套版本
|
||||
/// </summary>
|
||||
public DataRow AccountItem;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [apply before].
|
||||
/// </summary>
|
||||
@@ -73,13 +80,12 @@ namespace Lskj.Control.Model
|
||||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
|
||||
public bool Apply(DataRow rowItem)
|
||||
{
|
||||
bool resultValue = false;
|
||||
if (rowItem == null || this._controlObj == null) return resultValue;
|
||||
GridRightMenuModel model = new GridRightMenuModel(rowItem);
|
||||
|
||||
try
|
||||
{
|
||||
bool resultValue = false;
|
||||
if (rowItem == null || this._controlObj == null) return resultValue;
|
||||
|
||||
GridRightMenuModel model = new GridRightMenuModel(rowItem);
|
||||
|
||||
//if (!string.IsNullOrWhiteSpace(model.MenuCond))
|
||||
//{
|
||||
// try
|
||||
@@ -103,6 +109,18 @@ namespace Lskj.Control.Model
|
||||
// }
|
||||
//}
|
||||
|
||||
if (!string.IsNullOrEmpty(model.UnionZTid))
|
||||
{
|
||||
string UnionZTid = ReplaceHelper.ReplaceRowParam(BaseGridView.GetFocusedDataRow(), model.UnionZTid);
|
||||
string condition = string.Format("where ShowName ='{0}'", ERPInfo.Instance.AccountBook);
|
||||
DataTable dt = MainImpl.GetLedgerList(condition);
|
||||
DataRow RT = BaseImpl.GetDataRowResult($"select * from p_sydbGroupTab where ID={UnionZTid}");
|
||||
|
||||
AccountItem = dt.Rows[0];
|
||||
AccountItem["IP"] = DBConfig.Instance.ServerName;
|
||||
ToDBatching(RT, AccountItem);
|
||||
}
|
||||
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(model.BeforeMsg))
|
||||
{
|
||||
@@ -186,6 +204,10 @@ namespace Lskj.Control.Model
|
||||
string Message = ErrorMessage.PromptErrorMessage(ex);
|
||||
MessageUtil.Show(Message, ex.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!string.IsNullOrEmpty(model.UnionZTid)) ToDBatching(AccountItem, AccountItem);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/// <summary>
|
||||
@@ -507,5 +529,29 @@ namespace Lskj.Control.Model
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 启动账套数据源刷新
|
||||
/// </summary>
|
||||
protected void ToDBatching(DataRow RT, DataRow firstrow)
|
||||
{
|
||||
string serverIP = RT["IP"] + "";
|
||||
string dbName = RT["DBName"] + "";
|
||||
string dataBook = RT["ShowName"] + "";
|
||||
bool isInternal = RT.Table.Columns.Contains("IsInternalNetwork") && !string.IsNullOrEmpty(RT["IsInternalNetwork"] + "") ? "1".Equals(RT["IsInternalNetwork"] + "") : false;
|
||||
DBConfig.Instance.DataBook = dataBook;
|
||||
DBConfig.Instance.ServerName = serverIP;
|
||||
DBConfig.Instance.DataBase = dbName;
|
||||
DBConfig.Instance.IsInternalNetwork = isInternal;
|
||||
if (!DBConfig.Instance.CreateConnection())
|
||||
{
|
||||
ToDBatching(firstrow, firstrow);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,6 +139,10 @@ namespace Lskj.Control.Model
|
||||
/// <value>The text member.</value>
|
||||
public string TextMember { get; set; }
|
||||
/// <summary>
|
||||
/// 扩展返回字段映射,格式为“业务控件字段=返回数据字段”。
|
||||
/// </summary>
|
||||
public string ResultFields { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the source SQL.
|
||||
/// </summary>
|
||||
/// <value>The source SQL.</value>
|
||||
@@ -204,7 +208,7 @@ namespace Lskj.Control.Model
|
||||
/// <value>The enable cond.</value>
|
||||
public string RequiredCond { get; set; }
|
||||
/// <summary>
|
||||
/// 可以方式
|
||||
/// 禁用方式(默认禁编,设置为1就禁显)
|
||||
/// </summary>
|
||||
/// <value>The type of the enable.</value>
|
||||
public string DisableType { get; set; }
|
||||
@@ -366,7 +370,10 @@ namespace Lskj.Control.Model
|
||||
///记住上一次的值(关闭时记住上一次的条件值,下一次打开时输入上去。关闭程序后清空)
|
||||
/// </summary>
|
||||
public bool RememberValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 明细合计
|
||||
/// </summary>
|
||||
public string SumlistField { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,7 +161,7 @@ namespace Lskj.Control.Model
|
||||
/// </summary>
|
||||
public const int LabComboxCheckListText = 19;
|
||||
/// <summary>
|
||||
/// Memo控件
|
||||
/// Memo控件 (备注框A)
|
||||
/// </summary>
|
||||
public const int LabMemoEdit = 20;
|
||||
/// <summary>
|
||||
@@ -493,21 +493,30 @@ namespace Lskj.Control.Model
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 快速搜索框返回id(字典模式)
|
||||
/// 模块选择返回ID-扩展
|
||||
/// </summary>
|
||||
public const int DictionarySearchBoxToId = 181;
|
||||
public const int LabModuleSelectReturnIdExtended = 173;
|
||||
/// <summary>
|
||||
/// 快速搜索框返回text(字典模式)
|
||||
/// 搜索返回ID-扩展
|
||||
/// </summary>
|
||||
public const int DictionarySearchBoxToText = 182;
|
||||
/// <summary>
|
||||
/// 快速搜索框返回id 带参数(字典模式)
|
||||
/// </summary>
|
||||
public const int DictionarySearchBoxToIdParam = 183;
|
||||
/// <summary>
|
||||
/// 快速搜索框返回text 带参数(字典模式)
|
||||
/// </summary>
|
||||
public const int DictionarySearchBoxToTextParam = 184;
|
||||
public const int LabSearchReturnIdExtended = 174;
|
||||
|
||||
///// <summary>
|
||||
///// 快速搜索框返回id(字典模式)
|
||||
///// </summary>
|
||||
//public const int DictionarySearchBoxToId = 181;
|
||||
///// <summary>
|
||||
///// 快速搜索框返回text(字典模式)
|
||||
///// </summary>
|
||||
//public const int DictionarySearchBoxToText = 182;
|
||||
///// <summary>
|
||||
///// 快速搜索框返回id 带参数(字典模式)
|
||||
///// </summary>
|
||||
//public const int DictionarySearchBoxToIdParam = 183;
|
||||
///// <summary>
|
||||
///// 快速搜索框返回text 带参数(字典模式)
|
||||
///// </summary>
|
||||
//public const int DictionarySearchBoxToTextParam = 184;
|
||||
|
||||
/// <summary>
|
||||
/// <para>说明:是否为Value类型</para>
|
||||
@@ -628,6 +637,8 @@ namespace Lskj.Control.Model
|
||||
fieldType == LabPhone ||
|
||||
fieldType == LabSelectReturnIdNew ||
|
||||
fieldType == LabSelectReturnTextNew ||
|
||||
fieldType == LabModuleSelectReturnIdExtended ||
|
||||
fieldType == LabSearchReturnIdExtended ||
|
||||
fieldType == LabApiBtuton||
|
||||
fieldType == LabModuleAddRowsID ||
|
||||
fieldType == LabModuleAddRowsText;
|
||||
|
||||
@@ -0,0 +1,195 @@
|
||||
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)
|
||||
{
|
||||
return BuildSearchSql(sourceSql, columns, maxRows, string.Empty);
|
||||
}
|
||||
|
||||
public static string BuildSearchSql(string sourceSql, DataColumnCollection columns, int maxRows, string searchField)
|
||||
{
|
||||
if (columns == null || columns.Count == 0)
|
||||
{
|
||||
throw new InvalidOperationException("搜索 SQL 没有返回任何可查询列。");
|
||||
}
|
||||
if (maxRows <= 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("maxRows", "最大返回行数必须大于零。");
|
||||
}
|
||||
|
||||
List<DataColumn> searchColumns = new List<DataColumn>();
|
||||
string selectedField = (searchField ?? string.Empty).Trim();
|
||||
if (selectedField.Length == 0)
|
||||
{
|
||||
foreach (DataColumn column in columns)
|
||||
{
|
||||
if (IsSearchableColumn(column.ColumnName))
|
||||
{
|
||||
searchColumns.Add(column);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (DataColumn column in columns)
|
||||
{
|
||||
if (string.Equals(column.ColumnName, selectedField, StringComparison.OrdinalIgnoreCase) &&
|
||||
IsSearchableColumn(column.ColumnName))
|
||||
{
|
||||
searchColumns.Add(column);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (searchColumns.Count == 0)
|
||||
{
|
||||
if (selectedField.Length > 0)
|
||||
{
|
||||
throw new InvalidOperationException(string.Format("搜索字段“{0}”不存在或不允许查询。", selectedField));
|
||||
}
|
||||
throw new InvalidOperationException("搜索 SQL 没有返回任何可查询列。");
|
||||
}
|
||||
|
||||
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 < searchColumns.Count; i++)
|
||||
{
|
||||
if (i > 0) builder.Append(" or ");
|
||||
builder.Append("convert(nvarchar(4000), ");
|
||||
builder.Append(alias);
|
||||
builder.Append('.');
|
||||
builder.Append(QuoteIdentifier(searchColumns[i].ColumnName));
|
||||
builder.Append(") like ");
|
||||
builder.Append(SearchParameterName);
|
||||
builder.Append(" escape N'\\'");
|
||||
}
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
public static bool IsSearchableColumn(string columnName)
|
||||
{
|
||||
return !string.IsNullOrWhiteSpace(columnName) &&
|
||||
!columnName.StartsWith("_", StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
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 int _lookUpWidth;
|
||||
private string _lookUpFieldsWidth;
|
||||
private string _resultFields;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -326,6 +327,10 @@ namespace Lskj.Control.Model
|
||||
/// </summary>
|
||||
public string LookUpFieldsWidth { get { return this._lookUpFieldsWidth; } }
|
||||
/// <summary>
|
||||
/// 扩展选择结果映射,格式:业务表字段=返回数据字段;业务表字段1=返回数据字段1。
|
||||
/// </summary>
|
||||
public string ResultFields { get { return this._resultFields; } }
|
||||
/// <summary>
|
||||
/// 动态列
|
||||
/// </summary>
|
||||
public bool isDynamic;
|
||||
@@ -459,6 +464,7 @@ namespace Lskj.Control.Model
|
||||
}
|
||||
|
||||
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.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;
|
||||
|
||||
@@ -307,6 +307,11 @@ namespace Lskj.Control.Model
|
||||
/// </summary>
|
||||
public bool AddHideBottomPanel;
|
||||
|
||||
/// <summary>
|
||||
/// 禁用条件
|
||||
/// </summary>
|
||||
public string VisibleCond;
|
||||
|
||||
/// <summary>
|
||||
/// 主模块编号
|
||||
/// </summary>
|
||||
@@ -379,6 +384,7 @@ namespace Lskj.Control.Model
|
||||
this.IgnoreAssociatedFields = item.Table.Columns.Contains("IgnoreAssociatedFields") ? "1".Equals(item["IgnoreAssociatedFields"] + "") : false;
|
||||
this.Library = item.Table.Columns.Contains("Library") ? item["Library"] + "" : "";
|
||||
this.AddHideBottomPanel = item.Table.Columns.Contains("AddHideBottomPanel") ? "1".Equals(item["AddHideBottomPanel"] + "") : false;
|
||||
this.VisibleCond = item.Table.Columns.Contains("VisibleCond") ? item["VisibleCond"] + "" : "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,8 +29,46 @@ namespace Lskj.Control.Model
|
||||
/// <summary>
|
||||
/// 表格拖拽到表格
|
||||
/// </summary>
|
||||
public class GridDragGrid
|
||||
public class GridDragGrid : IDisposable
|
||||
{
|
||||
private bool _disposed;
|
||||
|
||||
internal static void DisposeRegistrations(
|
||||
Dictionary<GridView, List<GridDragGrid>> sourceRegistrations,
|
||||
Dictionary<GridView, List<GridDragGrid>> targetRegistrations,
|
||||
GridView gridView)
|
||||
{
|
||||
DisposeRegistrations(sourceRegistrations, gridView);
|
||||
DisposeRegistrations(targetRegistrations, gridView);
|
||||
}
|
||||
|
||||
private static void DisposeRegistrations(
|
||||
Dictionary<GridView, List<GridDragGrid>> registrations,
|
||||
GridView gridView)
|
||||
{
|
||||
foreach (KeyValuePair<GridView, List<GridDragGrid>> entry in registrations.ToList())
|
||||
{
|
||||
bool removeKey = ReferenceEquals(entry.Key, gridView);
|
||||
foreach (GridDragGrid registration in entry.Value.ToList())
|
||||
{
|
||||
if (removeKey || registration == null || registration._disposed || registration.References(gridView))
|
||||
{
|
||||
if (registration != null)
|
||||
registration.Dispose();
|
||||
entry.Value.Remove(registration);
|
||||
}
|
||||
}
|
||||
if (removeKey || entry.Value.Count == 0)
|
||||
registrations.Remove(entry.Key);
|
||||
}
|
||||
}
|
||||
|
||||
internal bool References(GridView gridView)
|
||||
{
|
||||
return gridView != null &&
|
||||
(ReferenceEquals(_sourceGridView, gridView) ||
|
||||
ReferenceEquals(_targetGridView, gridView));
|
||||
}
|
||||
/// <summary>
|
||||
/// 是否正在拖拽
|
||||
/// </summary>
|
||||
@@ -119,6 +157,97 @@ namespace Lskj.Control.Model
|
||||
this._targetGridView.GridControl.DragEnter += new System.Windows.Forms.DragEventHandler(gridControl_DragEnter);
|
||||
this._targetGridView.GridControl.DragDrop += new System.Windows.Forms.DragEventHandler(gridControl_DragDrop);
|
||||
this._targetGridView.GridControl.DragLeave += new EventHandler(gridControl_DragLeave);
|
||||
this._sourceGridView.Disposed += OnGridViewDisposed;
|
||||
if (!ReferenceEquals(this._sourceGridView, this._targetGridView))
|
||||
{
|
||||
this._targetGridView.Disposed += OnGridViewDisposed;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnGridViewDisposed(object sender, EventArgs e)
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_disposed = true;
|
||||
GridView sourceGridView = _sourceGridView;
|
||||
GridView targetGridView = _targetGridView;
|
||||
|
||||
if (sourceGridView != null)
|
||||
{
|
||||
sourceGridView.MouseDown -= sourceGridView_MouseDown;
|
||||
sourceGridView.MouseMove -= sourceGridView_MouseMove;
|
||||
sourceGridView.MouseUp -= sourceGridView_MouseUp;
|
||||
sourceGridView.RowClick -= OnRowClick;
|
||||
sourceGridView.Disposed -= OnGridViewDisposed;
|
||||
}
|
||||
|
||||
if (targetGridView != null)
|
||||
{
|
||||
if (targetGridView.GridControl != null)
|
||||
{
|
||||
targetGridView.GridControl.DragOver -= gridControl_DragOver;
|
||||
targetGridView.GridControl.DragEnter -= gridControl_DragEnter;
|
||||
targetGridView.GridControl.DragDrop -= gridControl_DragDrop;
|
||||
targetGridView.GridControl.DragLeave -= gridControl_DragLeave;
|
||||
}
|
||||
|
||||
if (!ReferenceEquals(sourceGridView, targetGridView))
|
||||
{
|
||||
targetGridView.Disposed -= OnGridViewDisposed;
|
||||
}
|
||||
}
|
||||
|
||||
RemoveRegistration(
|
||||
StaticControl.GridViewDragGridDic,
|
||||
sourceGridView,
|
||||
this);
|
||||
RemoveRegistration(
|
||||
StaticControl.TargetViewDragGridDic,
|
||||
targetGridView,
|
||||
this);
|
||||
|
||||
if (ReferenceEquals(StaticControl.SourceDragGridView, sourceGridView))
|
||||
{
|
||||
StaticControl.SourceDragGridView = null;
|
||||
}
|
||||
|
||||
OnDragComplete = null;
|
||||
DragHander.Clear();
|
||||
_hitInfo = null;
|
||||
_sourceGridView = null;
|
||||
_targetGridView = null;
|
||||
}
|
||||
|
||||
private static void RemoveRegistration<TKey>(
|
||||
Dictionary<TKey, List<GridDragGrid>> registrations,
|
||||
TKey key,
|
||||
GridDragGrid registration)
|
||||
where TKey : class
|
||||
{
|
||||
if (key == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<GridDragGrid> registrationsForView;
|
||||
if (!registrations.TryGetValue(key, out registrationsForView))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
registrationsForView.Remove(registration);
|
||||
if (registrationsForView.Count == 0)
|
||||
{
|
||||
registrations.Remove(key);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 点击时候判断位置
|
||||
|
||||
@@ -24,8 +24,9 @@ namespace Lskj.Control.Model
|
||||
/// <summary>
|
||||
/// 表格拖拽到树结构
|
||||
/// </summary>
|
||||
public class GridDragTree
|
||||
public class GridDragTree : IDisposable
|
||||
{
|
||||
private bool _disposed;
|
||||
/// <summary>
|
||||
/// 拖动位置
|
||||
/// </summary>
|
||||
@@ -59,8 +60,47 @@ namespace Lskj.Control.Model
|
||||
this._treeView.AllowDrop = true;
|
||||
this._treeView.DragOver += new DragEventHandler(treeView_DragOver);
|
||||
this._treeView.DragDrop += new DragEventHandler(treeView_DragDrop);
|
||||
if (this._gridView.GridControl != null)
|
||||
{
|
||||
this._gridView.GridControl.Disposed += OnOwnerDisposed;
|
||||
}
|
||||
this._treeView.Disposed += OnOwnerDisposed;
|
||||
}
|
||||
|
||||
private void OnOwnerDisposed(object sender, EventArgs e)
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 模块关闭时解除源表格和目标树的拖拽事件。
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
if (_disposed) return;
|
||||
_disposed = true;
|
||||
|
||||
if (_gridView != null)
|
||||
{
|
||||
_gridView.MouseDown -= gridView_MouseDown;
|
||||
_gridView.MouseMove -= gridView_MouseMove;
|
||||
if (_gridView.GridControl != null)
|
||||
{
|
||||
_gridView.GridControl.Disposed -= OnOwnerDisposed;
|
||||
}
|
||||
}
|
||||
if (_treeView != null)
|
||||
{
|
||||
_treeView.DragOver -= treeView_DragOver;
|
||||
_treeView.DragDrop -= treeView_DragDrop;
|
||||
_treeView.Disposed -= OnOwnerDisposed;
|
||||
}
|
||||
|
||||
OnDragComplete = null;
|
||||
_hitInfo = null;
|
||||
_gridView = null;
|
||||
_treeView = null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// <para>说明:获取表格选中行数据</para>
|
||||
|
||||
@@ -913,6 +913,14 @@ namespace Lskj.Control.Model
|
||||
/// <param name="key">The key.</param>
|
||||
/// <returns>DataTable.</returns>
|
||||
public static DataTable GetCustomColumnByDatabase(this GridView gridView, string key)
|
||||
{
|
||||
return GetCustomColumnByDatabase(key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取个性配置列数据,不依赖任何界面控件。
|
||||
/// </summary>
|
||||
public static DataTable GetCustomColumnByDatabase(string key)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -950,22 +958,11 @@ namespace Lskj.Control.Model
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!BaseImpl.HasExistsColumn(ResourceKeys.SettingTableName, ""))
|
||||
if (!BaseImpl.HasExistsColumn(ResourceKeys.SettingTableName, "IfFixColumn"))
|
||||
{
|
||||
BaseImpl.ExecSqlValue("alter table " + ResourceKeys.SettingTableName + " add IfFixColumn bit");
|
||||
}
|
||||
// 读取普通用户读取个人配置,没有则读取管理员配置,管理未配置则读取系统默认.逐级上报读取方式.
|
||||
string sqlValue = string.Format("select * from {0} where formKey='{1}' and operatorid='{2}' order by orderid ", ResourceKeys.SettingTableName, key, ERPInfo.Instance.UserId);
|
||||
|
||||
DataTable table = BaseImpl.GetDataTableResult(sqlValue);
|
||||
|
||||
//if (table == null || table.Rows.Count == 0)
|
||||
//{
|
||||
// sqlValue = string.Format("select * from {0} where formKey='{1}' and operatorid='{2}'", ResourceKeys.SettingTableName, key, ERPInfo.Instance.UserManager);
|
||||
// table = BaseImpl.GetDataTableResult(sqlValue);
|
||||
//}
|
||||
|
||||
return table;
|
||||
return GetCustomColumnByDatabase(key);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
@@ -1110,6 +1107,7 @@ namespace Lskj.Control.Model
|
||||
gridControl.gridViewRightMenu = rightMenu;
|
||||
rightMenu.InitRightMenus(gridControl, table, model, control, menu);
|
||||
rightMenu.SetRightCallback(handler);
|
||||
gridControl.SetRightMenuButtonTable(table);
|
||||
}
|
||||
/// <summary>
|
||||
/// <para>说明:设置表格右键菜单</para>
|
||||
@@ -2801,7 +2799,9 @@ namespace Lskj.Control.Model
|
||||
GridColumnModel model = col.Tag as GridColumnModel;
|
||||
if (cell != null)
|
||||
{
|
||||
if (cell.CellType == CellType.Blank)
|
||||
// DevExpress导出的xlsx空值可能是内容为空的String单元格,也应按空单元格处理。
|
||||
if (cell.CellType == CellType.Blank ||
|
||||
(cell.CellType == CellType.String && string.IsNullOrEmpty(cell.StringCellValue)))
|
||||
{
|
||||
//isImportRows = false;
|
||||
continue;
|
||||
@@ -3564,7 +3564,8 @@ namespace Lskj.Control.Model
|
||||
{
|
||||
string field = fields[i];
|
||||
string value = rowResult.Table.Columns.Contains(field) ? rowResult[field] + "" : null;
|
||||
rowItem[field] = value;
|
||||
|
||||
if(rowItem.Table.Columns.Contains(field)) rowItem[field] = value;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -3573,7 +3574,7 @@ namespace Lskj.Control.Model
|
||||
for (int i = 0; i < fields.Length; i++)
|
||||
{
|
||||
string field = fields[i];
|
||||
rowItem[field] = DBNull.Value;
|
||||
if (rowItem.Table.Columns.Contains(field)) rowItem[field] = DBNull.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,54 +36,62 @@ namespace Lskj.Control.Model.MenuStrip
|
||||
}
|
||||
protected override void MenuStripOpening(object sender, System.ComponentModel.CancelEventArgs e)
|
||||
{
|
||||
int[] mSelectRows = this._gridView.GetSelectedRows();
|
||||
if (mSelectRows == null || mSelectRows.Length == 0) return;
|
||||
int[] mSelectRows = this._gridView.GetSelectedRows() ?? new int[0];
|
||||
|
||||
DataRow mSelectRow = this._gridView.GetDataRow(mSelectRows[0]);
|
||||
DataRow[] dataRows = new DataRow[mSelectRows.Length];
|
||||
for (int i = 0; i < mSelectRows.Length; i++)
|
||||
{
|
||||
dataRows[i] = this._gridView.GetDataRow(mSelectRows[i]);
|
||||
}
|
||||
|
||||
ContextMenuStrip cmsMenu = (ContextMenuStrip)sender;
|
||||
cmsMenu.Items.Clear();
|
||||
cmsMenu.Items.AddRange(this.RightMenuItems.ToArray());
|
||||
|
||||
// 创建QQ、浏览器右键菜单
|
||||
List<ToolStripMenuItem> mQQArray = new List<ToolStripMenuItem>();
|
||||
List<ToolStripMenuItem> mBrowerArray = new List<ToolStripMenuItem>();
|
||||
|
||||
foreach (GridColumn column in this._gridView.Columns)
|
||||
if (mSelectRows.Length > 0)
|
||||
{
|
||||
if (!mSelectRow.Table.Columns.Contains(column.Name))
|
||||
continue;
|
||||
string rowValue = mSelectRow[column.Name] + "";
|
||||
if (!string.IsNullOrWhiteSpace(rowValue))
|
||||
DataRow mSelectRow = this._gridView.GetDataRow(mSelectRows[0]);
|
||||
|
||||
// 创建QQ、浏览器右键菜单
|
||||
List<ToolStripMenuItem> mQQArray = new List<ToolStripMenuItem>();
|
||||
List<ToolStripMenuItem> mBrowerArray = new List<ToolStripMenuItem>();
|
||||
|
||||
foreach (GridColumn column in this._gridView.Columns)
|
||||
{
|
||||
GridColumnModel model = column.Tag as GridColumnModel;
|
||||
if (model == null) continue;
|
||||
|
||||
if (model.FieldType == ControlType.LabQQ)
|
||||
if (!mSelectRow.Table.Columns.Contains(column.Name))
|
||||
continue;
|
||||
string rowValue = mSelectRow[column.Name] + "";
|
||||
if (!string.IsNullOrWhiteSpace(rowValue))
|
||||
{
|
||||
ToolStripMenuItem item = new ToolStripMenuItem("(" + column.Caption + ")" + rowValue, Resources.qq);
|
||||
item.Tag = mSelectRow[column.Name] + "";
|
||||
item.Click += new EventHandler(QQItemClick);
|
||||
mQQArray.Add(item);
|
||||
}
|
||||
GridColumnModel model = column.Tag as GridColumnModel;
|
||||
if (model == null) continue;
|
||||
|
||||
if (model.FieldType == ControlType.LabWWW ||
|
||||
rowValue.StartsWith("www.") ||
|
||||
rowValue.StartsWith("http://") ||
|
||||
rowValue.StartsWith("https://") ||
|
||||
rowValue.StartsWith("ftp://") ||
|
||||
rowValue.StartsWith("file://"))
|
||||
{
|
||||
ToolStripMenuItem item = new ToolStripMenuItem("(" + column.Caption + ")" + rowValue, Resources.qq);
|
||||
item.Tag = mSelectRow[column.Name] + "";
|
||||
item.Click += new EventHandler(BrowerItemClick);
|
||||
mBrowerArray.Add(item);
|
||||
if (model.FieldType == ControlType.LabQQ)
|
||||
{
|
||||
ToolStripMenuItem item = new ToolStripMenuItem("(" + column.Caption + ")" + rowValue, Resources.qq);
|
||||
item.Tag = mSelectRow[column.Name] + "";
|
||||
item.Click += new EventHandler(QQItemClick);
|
||||
mQQArray.Add(item);
|
||||
}
|
||||
|
||||
if (model.FieldType == ControlType.LabWWW ||
|
||||
rowValue.StartsWith("www.") ||
|
||||
rowValue.StartsWith("http://") ||
|
||||
rowValue.StartsWith("https://") ||
|
||||
rowValue.StartsWith("ftp://") ||
|
||||
rowValue.StartsWith("file://"))
|
||||
{
|
||||
ToolStripMenuItem item = new ToolStripMenuItem("(" + column.Caption + ")" + rowValue, Resources.qq);
|
||||
item.Tag = mSelectRow[column.Name] + "";
|
||||
item.Click += new EventHandler(BrowerItemClick);
|
||||
mBrowerArray.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cmsMenu.Items.AddRange(mQQArray.ToArray());
|
||||
cmsMenu.Items.AddRange(mBrowerArray.ToArray());
|
||||
cmsMenu.Items.AddRange(mQQArray.ToArray());
|
||||
cmsMenu.Items.AddRange(mBrowerArray.ToArray());
|
||||
}
|
||||
|
||||
// 判断右键菜单是否可用
|
||||
foreach (ToolStripItem cms in cmsMenu.Items)
|
||||
@@ -95,34 +103,84 @@ namespace Lskj.Control.Model.MenuStrip
|
||||
{
|
||||
try
|
||||
{
|
||||
string cond = string.Empty;
|
||||
if (this._control != null)
|
||||
cond = _control.ReplaceParentControlValue(model.MenuCond);
|
||||
cond = ReplaceHelper.ReplaceRowParam(mSelectRow, model.MenuCond);
|
||||
if (this._gridView != null)
|
||||
bool condResult = false;
|
||||
StringBuilder condBuilder = new StringBuilder();
|
||||
StringBuilder sqlCondBuilder = new StringBuilder();
|
||||
GridCell[] cells = this._gridView.GetSelectedCells();
|
||||
DataRow focusedRow = this.BaseGridView.GetFocusedDataRow();
|
||||
|
||||
DataRow[] conditionRows = dataRows;
|
||||
if (model.AllowNullExec && conditionRows.Length == 0)
|
||||
{
|
||||
GridCell[] cells = this._gridView.GetSelectedCells();
|
||||
if (cells != null && cells.Length > 0 && cond.Contains("{COLUMN_"))
|
||||
conditionRows = new DataRow[] { new DataTable().NewRow() };
|
||||
}
|
||||
if (conditionRows.Length == 0) continue;
|
||||
|
||||
foreach (DataRow selectRow in conditionRows)
|
||||
{
|
||||
string cond = ReplaceHelper.ReplaceUserInfo(model.MenuCond);
|
||||
cond = RaiseBeforeHandleParamsCallback(model.ParamList, conditionRows, model.MenuCond, selectRow, cond);
|
||||
if (this._control != null)
|
||||
{
|
||||
GridCell cell = cells[0];
|
||||
DataRow focusedRow = this.BaseGridView.GetFocusedDataRow();
|
||||
string colValue = focusedRow == null || !focusedRow.Table.Columns.Contains(cell.Column.Name) ? "" : focusedRow[cell.Column.Name] + "";
|
||||
cond = cond.ReplaceColumnParam(cell.Column.Name, cell.Column.Caption, colValue);
|
||||
cond = _control.ReplaceParentControlValue(cond);
|
||||
}
|
||||
//cond = ReplaceHelper.ReplaceRowParam(selectRow, cond);
|
||||
cond = ReplaceHelper.ReplaceRowParamEmptyWrapQuote(selectRow, cond);
|
||||
if (model.Mergeexec && cond.StartsWith("@"))
|
||||
{
|
||||
//替换[],替换的是多选行中的数据
|
||||
cond = ReplaceHelper.ReplaceRowParam(conditionRows, cond.Replace("[", "{").Replace("]", "}"), "", "");
|
||||
}
|
||||
|
||||
if (this._gridView != null)
|
||||
{
|
||||
if (cells != null && cells.Length > 0 && cond.Contains("{COLUMN_"))
|
||||
{
|
||||
GridCell cell = cells[0];
|
||||
string colValue = focusedRow == null || !focusedRow.Table.Columns.Contains(cell.Column.Name) ? "" : focusedRow[cell.Column.Name] + "";
|
||||
cond = cond.ReplaceColumnParam(cell.Column.Name, cell.Column.Caption, colValue);
|
||||
}
|
||||
}
|
||||
|
||||
if (ControlObj != null)
|
||||
{
|
||||
cond = ControlObj.ReplaceParentControlValue(cond);
|
||||
}
|
||||
if (cond.StartsWith("@"))
|
||||
{
|
||||
sqlCondBuilder.Append($"({cond.TrimStart('@')}) = '1' and ");
|
||||
}
|
||||
else
|
||||
{
|
||||
condBuilder.Append($"({cond}) and ");
|
||||
}
|
||||
}
|
||||
if (ControlObj != null)
|
||||
cond = ControlObj.ReplaceParentControlValue(cond);
|
||||
string condStr = model.MenuCond;
|
||||
if (!string.IsNullOrWhiteSpace(sqlCondBuilder.ToString()) || !string.IsNullOrWhiteSpace(condBuilder.ToString()))
|
||||
{
|
||||
if (model.MenuCond.StartsWith("@"))
|
||||
{
|
||||
condStr = $"@if({sqlCondBuilder.ToString().TrimEnd().TrimEnd('d', 'n', 'a')}) begin select '1' end else begin select '0' end";
|
||||
}
|
||||
else
|
||||
{
|
||||
condStr = condBuilder.ToString().TrimEnd().TrimEnd('d', 'n', 'a');
|
||||
}
|
||||
}
|
||||
|
||||
condResult = ValidateCond(condStr, null);
|
||||
//cms.Enabled = ReplaceHelper.EvalCond(cond);
|
||||
if (model.ForbiddenDisplay)
|
||||
{
|
||||
cms.Visible = ValidateCond(cond, null); ;
|
||||
cms.Visible = condResult;
|
||||
}
|
||||
cms.Enabled = ValidateCond(cond, null); ;
|
||||
cms.Enabled = condResult;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
string Message = ErrorMessage.PromptErrorMessage(ex);
|
||||
MessageUtil.Show(ResourceKeys.SetRightMenuCondFault + "\r\n" + Message);
|
||||
e.Cancel = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ namespace Lskj.Control.Model
|
||||
/// 最初账套版本
|
||||
/// </summary>
|
||||
public DataRow AccountItem;
|
||||
|
||||
public DataTable MenuTable;
|
||||
public DynamicModel Model;
|
||||
public MyControl ControlObj;
|
||||
@@ -71,6 +72,23 @@ namespace Lskj.Control.Model
|
||||
/// 替换参数前执行
|
||||
/// </summary>
|
||||
public event BeforeHandleParamsEventHandler OnBeforeHandleParamsCallback;
|
||||
|
||||
/// <summary>
|
||||
/// 触发替换参数前事件,并返回事件处理后的参数值。
|
||||
/// </summary>
|
||||
protected string RaiseBeforeHandleParamsCallback(List<string> paramList, DataRow[] rowDatas, string paramItem, DataRow rowData, string fieldValue)
|
||||
{
|
||||
BeforeHandleParamsEventHandler handler = OnBeforeHandleParamsCallback;
|
||||
if (handler == null)
|
||||
return fieldValue;
|
||||
|
||||
HandleParamsArgs handleParamsArgs = new HandleParamsArgs(paramList, rowDatas, paramItem, rowData)
|
||||
{
|
||||
FieldValue = fieldValue
|
||||
};
|
||||
handler(this, handleParamsArgs);
|
||||
return handleParamsArgs.FieldValue;
|
||||
}
|
||||
/// <summary>
|
||||
/// 缓存右键菜单
|
||||
/// </summary>
|
||||
@@ -156,6 +174,11 @@ namespace Lskj.Control.Model
|
||||
cmsMenu.Items.Add(menuItem);
|
||||
RightMenuItems.Add(menuItem);
|
||||
}
|
||||
if (menuModel.FontSize != 0)
|
||||
{
|
||||
menuItem.Font = new Font(menuItem.Font.FontFamily, menuModel.FontSize);
|
||||
}
|
||||
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(menuModel.ExecuteFirstCode))
|
||||
{
|
||||
@@ -245,7 +268,7 @@ namespace Lskj.Control.Model
|
||||
public bool ValidateCond(string cond, DataRow dataRow)
|
||||
{
|
||||
bool result = false;
|
||||
cond = ReplaceHelper.ReplaceRowParam(dataRow, cond);
|
||||
cond = ReplaceHelper.ReplaceRowParamEmptyWrapQuote(dataRow, cond);
|
||||
if (cond.StartsWith("@") || cond.StartsWith("!"))
|
||||
{
|
||||
result = "1".Equals(BaseImpl.GetDefaultValue(cond));
|
||||
@@ -287,7 +310,7 @@ namespace Lskj.Control.Model
|
||||
return;
|
||||
}
|
||||
|
||||
if (model.VerifyUpdate && BaseGridView!=null)
|
||||
if (model.VerifyUpdate && BaseGridView != null)
|
||||
{
|
||||
for (int i = 0; i < BaseGridView.DataRowCount; i++)
|
||||
{
|
||||
@@ -485,7 +508,7 @@ namespace Lskj.Control.Model
|
||||
{
|
||||
tipOnlyOne = false;
|
||||
string prompt = ReplaceHelper.ReplaceRowParam(rowData, model.BeforeMsg);
|
||||
if (model.Mergeexec)
|
||||
if (model.Mergeexec)
|
||||
{
|
||||
//替换[],替换的是多选行中的数据
|
||||
prompt = ReplaceHelper.ReplaceRowParam(rows, prompt.Replace("[", "{").Replace("]", "}"), "", "");
|
||||
@@ -960,7 +983,7 @@ namespace Lskj.Control.Model
|
||||
case -1:
|
||||
if (rValue == -1)
|
||||
{
|
||||
if (SqlHelper.ConnectionType == ConnectionType.SqlServer)
|
||||
if (SqlHelper.ConnectionType == ConnectionType.SqlServer)
|
||||
{
|
||||
SqlStoredProcedurepPrompt.GenerateProcedureExecutionScript(procName, paramList, isFirstFlag, comfirmFlag);
|
||||
}
|
||||
@@ -1794,7 +1817,7 @@ namespace Lskj.Control.Model
|
||||
paramList[2] = ReplaceHelper.ReplaceRowParam(rows, url) + "";
|
||||
}
|
||||
}
|
||||
if (model.DllName.ToLower().Contains("p_PubPrint.lsp".ToLower())&& !model.CancelDefaultReplace)
|
||||
if (model.DllName.ToLower().Contains("p_PubPrint.lsp".ToLower()) && !model.CancelDefaultReplace)
|
||||
{
|
||||
string paramsql1 = paramList[2];
|
||||
paramList[2] = ReplaceHelper.ReplaceRowParam(rows, paramsql1, "'", "'");
|
||||
@@ -1899,15 +1922,7 @@ namespace Lskj.Control.Model
|
||||
if (!string.IsNullOrWhiteSpace(item))
|
||||
{
|
||||
string fieldValue = ReplaceHelper.ReplaceUserInfo(item);
|
||||
if (OnBeforeHandleParamsCallback != null)
|
||||
{
|
||||
HandleParamsArgs handleParamsArgs = new HandleParamsArgs(paramList, rowDatas, item, rowData)
|
||||
{
|
||||
FieldValue = fieldValue
|
||||
};
|
||||
OnBeforeHandleParamsCallback(this, handleParamsArgs);
|
||||
fieldValue = handleParamsArgs.FieldValue;
|
||||
}
|
||||
fieldValue = RaiseBeforeHandleParamsCallback(paramList, rowDatas, item, rowData, fieldValue);
|
||||
if (!string.IsNullOrWhiteSpace(fieldValue) && fieldValue.TrimStart().StartsWith("MergeExec_", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
fieldValue = ReplaceHelper.ReplaceRowParam(rowDatas, fieldValue.Replace("MergeExec_", "", true));
|
||||
@@ -2086,4 +2101,4 @@ namespace Lskj.Control.Model
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,8 +40,7 @@ namespace Lskj.Control.Model
|
||||
|
||||
protected override void MenuStripOpening(object sender, System.ComponentModel.CancelEventArgs e)
|
||||
{
|
||||
int[] mSelectRows = this._gridView.GetSelectedRows();
|
||||
if (mSelectRows == null || mSelectRows.Length == 0) return;
|
||||
int[] mSelectRows = this._gridView.GetSelectedRows() ?? new int[0];
|
||||
|
||||
DataRow[] dataRows = new DataRow[mSelectRows.Length];
|
||||
for (int i = 0; i < mSelectRows.Length; i++)
|
||||
@@ -49,49 +48,53 @@ namespace Lskj.Control.Model
|
||||
dataRows[i] = this._gridView.GetDataRow(mSelectRows[i]);
|
||||
}
|
||||
|
||||
|
||||
DataRow mSelectRow = this._gridView.GetDataRow(mSelectRows[0]);
|
||||
this._gridView.UpdateCurrentRow();
|
||||
this._gridView.ShowEditor();
|
||||
|
||||
ContextMenuStrip cmsMenu = (ContextMenuStrip)sender;
|
||||
cmsMenu.Items.Clear();
|
||||
cmsMenu.Items.AddRange(this.RightMenuItems.ToArray());
|
||||
|
||||
// 创建QQ、浏览器右键菜单
|
||||
List<ToolStripMenuItem> mQQArray = new List<ToolStripMenuItem>();
|
||||
List<ToolStripMenuItem> mBrowerArray = new List<ToolStripMenuItem>();
|
||||
|
||||
foreach (GridColumn column in this._gridView.Columns)
|
||||
if (mSelectRows.Length > 0)
|
||||
{
|
||||
if (!mSelectRow.Table.Columns.Contains(column.Name))
|
||||
continue;
|
||||
string rowValue = mSelectRow[column.Name] + "";
|
||||
if (!string.IsNullOrWhiteSpace(rowValue))
|
||||
DataRow mSelectRow = this._gridView.GetDataRow(mSelectRows[0]);
|
||||
this._gridView.UpdateCurrentRow();
|
||||
this._gridView.ShowEditor();
|
||||
|
||||
// 创建QQ、浏览器右键菜单
|
||||
List<ToolStripMenuItem> mQQArray = new List<ToolStripMenuItem>();
|
||||
List<ToolStripMenuItem> mBrowerArray = new List<ToolStripMenuItem>();
|
||||
|
||||
foreach (GridColumn column in this._gridView.Columns)
|
||||
{
|
||||
GridColumnModel model = column.Tag as GridColumnModel;
|
||||
if (model == null) continue;
|
||||
|
||||
if (model.FieldType == ControlType.LabQQ)
|
||||
if (!mSelectRow.Table.Columns.Contains(column.Name))
|
||||
continue;
|
||||
string rowValue = mSelectRow[column.Name] + "";
|
||||
if (!string.IsNullOrWhiteSpace(rowValue))
|
||||
{
|
||||
ToolStripMenuItem item = new ToolStripMenuItem("(" + column.Caption + ")" + rowValue, Resources.qq);
|
||||
item.Tag = mSelectRow[column.Name] + "";
|
||||
item.Click += new EventHandler(QQItemClick);
|
||||
mQQArray.Add(item);
|
||||
}
|
||||
GridColumnModel model = column.Tag as GridColumnModel;
|
||||
if (model == null) continue;
|
||||
|
||||
if (model.FieldType == ControlType.LabWWW && !string.IsNullOrWhiteSpace(rowValue))
|
||||
{
|
||||
ToolStripMenuItem item = new ToolStripMenuItem("(" + column.Caption + ")" + rowValue, Resources.www);
|
||||
item.Tag = mSelectRow[column.Name] + "";
|
||||
item.Click += new EventHandler(BrowerItemClick);
|
||||
mBrowerArray.Add(item);
|
||||
if (model.FieldType == ControlType.LabQQ)
|
||||
{
|
||||
ToolStripMenuItem item = new ToolStripMenuItem("(" + column.Caption + ")" + rowValue, Resources.qq);
|
||||
item.Tag = mSelectRow[column.Name] + "";
|
||||
item.Click += new EventHandler(QQItemClick);
|
||||
mQQArray.Add(item);
|
||||
}
|
||||
|
||||
if (model.FieldType == ControlType.LabWWW && !string.IsNullOrWhiteSpace(rowValue))
|
||||
{
|
||||
ToolStripMenuItem item = new ToolStripMenuItem("(" + column.Caption + ")" + rowValue, Resources.www);
|
||||
item.Tag = mSelectRow[column.Name] + "";
|
||||
item.Click += new EventHandler(BrowerItemClick);
|
||||
mBrowerArray.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cmsMenu.Items.AddRange(mQQArray.ToArray());
|
||||
cmsMenu.Items.AddRange(mBrowerArray.ToArray());
|
||||
}
|
||||
|
||||
cmsMenu.Items.AddRange(mQQArray.ToArray());
|
||||
cmsMenu.Items.AddRange(mBrowerArray.ToArray());
|
||||
|
||||
Dictionary<ToolStripItem, GridRightMenuModel> cmsModelDic = new Dictionary<ToolStripItem, GridRightMenuModel>();
|
||||
List<string> roleNamesList = new List<string>();
|
||||
@@ -103,6 +106,8 @@ namespace Lskj.Control.Model
|
||||
roleNamesList.Add(model.PrivilegeOper);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 判断右键菜单是否可用
|
||||
foreach (ToolStripItem cms in cmsMenu.Items)
|
||||
{
|
||||
@@ -126,20 +131,29 @@ namespace Lskj.Control.Model
|
||||
StringBuilder sqlCondBuilder = new StringBuilder();
|
||||
GridCell[] cells = this._gridView.GetSelectedCells();
|
||||
DataRow focusedRow = this.BaseGridView.GetFocusedDataRow();
|
||||
foreach (int itemIndex in mSelectRows)
|
||||
|
||||
DataRow[] conditionRows = dataRows;
|
||||
if (model.AllowNullExec && conditionRows.Length == 0)
|
||||
{
|
||||
DataRow selectRow = this._gridView.GetDataRow(itemIndex);
|
||||
string cond = string.Empty;
|
||||
conditionRows = new DataRow[] { new DataTable().NewRow() };
|
||||
}
|
||||
if (conditionRows.Length == 0) continue;
|
||||
|
||||
foreach (DataRow selectRow in conditionRows)
|
||||
{
|
||||
//DataRow selectRow = this._gridView.GetDataRow(itemIndex);
|
||||
string cond = ReplaceHelper.ReplaceUserInfo(model.MenuCond);
|
||||
cond = RaiseBeforeHandleParamsCallback(model.ParamList, conditionRows, model.MenuCond, selectRow, cond);
|
||||
if (this._control != null)
|
||||
{
|
||||
cond = _control.ReplaceParentControlValue(model.MenuCond);
|
||||
cond = _control.ReplaceParentControlValue(cond);
|
||||
}
|
||||
cond = ReplaceHelper.ReplaceRowParam(selectRow, model.MenuCond);
|
||||
|
||||
//cond = ReplaceHelper.ReplaceRowParam(selectRow, cond);
|
||||
cond = ReplaceHelper.ReplaceRowParamEmptyWrapQuote(selectRow, cond);
|
||||
if (model.Mergeexec&& cond.StartsWith("@"))
|
||||
{
|
||||
//替换[],替换的是多选行中的数据
|
||||
cond = ReplaceHelper.ReplaceRowParam(dataRows, cond.Replace("[", "{").Replace("]", "}"), "", "");
|
||||
cond = ReplaceHelper.ReplaceRowParam(conditionRows, cond.Replace("[", "{").Replace("]", "}"), "", "");
|
||||
}
|
||||
|
||||
if (this._gridView != null)
|
||||
@@ -151,6 +165,7 @@ namespace Lskj.Control.Model
|
||||
cond = cond.ReplaceColumnParam(cell.Column.Name, cell.Column.Caption, colValue);
|
||||
}
|
||||
}
|
||||
|
||||
if (ControlObj != null)
|
||||
{
|
||||
cond = ControlObj.ReplaceParentControlValue(cond);
|
||||
@@ -164,15 +179,19 @@ namespace Lskj.Control.Model
|
||||
condBuilder.Append($"({cond}) and ");
|
||||
}
|
||||
}
|
||||
string condStr = "";
|
||||
if (model.MenuCond.StartsWith("@"))
|
||||
string condStr = model.MenuCond;
|
||||
if (!string.IsNullOrWhiteSpace(sqlCondBuilder.ToString()) || !string.IsNullOrWhiteSpace(condBuilder.ToString()))
|
||||
{
|
||||
condStr = $"@if({sqlCondBuilder.ToString().TrimEnd().TrimEnd('d', 'n', 'a')}) begin select '1' end else begin select '0' end";
|
||||
}
|
||||
else
|
||||
{
|
||||
condStr = condBuilder.ToString().TrimEnd().TrimEnd('d', 'n', 'a');
|
||||
if (model.MenuCond.StartsWith("@"))
|
||||
{
|
||||
condStr = $"@if({sqlCondBuilder.ToString().TrimEnd().TrimEnd('d', 'n', 'a')}) begin select '1' end else begin select '0' end";
|
||||
}
|
||||
else
|
||||
{
|
||||
condStr = condBuilder.ToString().TrimEnd().TrimEnd('d', 'n', 'a');
|
||||
}
|
||||
}
|
||||
|
||||
condResult = ValidateCond(condStr, null);
|
||||
//if (!condResult) break;
|
||||
//cms.Enabled = ReplaceHelper.EvalCond(cond);
|
||||
|
||||
@@ -346,6 +346,10 @@ namespace Lskj.Control.Model
|
||||
/// 右键多选合并不走默认替换(p_PubPrint.lsp)
|
||||
/// </summary>
|
||||
public bool CancelDefaultReplace;
|
||||
/// <summary>
|
||||
/// 右键字体大小
|
||||
/// </summary>
|
||||
public int FontSize;
|
||||
|
||||
|
||||
/// <summary>
|
||||
@@ -485,6 +489,8 @@ namespace Lskj.Control.Model
|
||||
this.VerifyUpdate = string.IsNullOrWhiteSpace(item["VerifyUpdate"] + "") ? false : "1".Equals(item["VerifyUpdate"] + "");
|
||||
if (item.Table.Columns.Contains("CancelDefaultReplace"))
|
||||
this.CancelDefaultReplace = string.IsNullOrWhiteSpace(item["CancelDefaultReplace"] + "") ? false : "1".Equals(item["CancelDefaultReplace"] + "");
|
||||
|
||||
this.FontSize = item.Table.Columns.Contains("FontSize") && !string.IsNullOrEmpty(item["FontSize"] + "") ? Convert.ToInt32(item["FontSize"] + "") : 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -73,56 +73,58 @@ namespace Lskj.Control.Model.MenuStrip
|
||||
}
|
||||
protected override void MenuStripOpening(object sender, System.ComponentModel.CancelEventArgs e)
|
||||
{
|
||||
DataRow[] mSelectRows = this.TreeGridControlObj.GetViewFocusedDataRows();
|
||||
if (mSelectRows == null || mSelectRows.Length == 0) return;
|
||||
|
||||
DataRow mSelectRow = mSelectRows[0];
|
||||
this._treeView.EndCurrentEdit();
|
||||
this._treeView.ShowEditor();
|
||||
DataRow[] mSelectRows = this.TreeGridControlObj.GetViewFocusedDataRows() ?? new DataRow[0];
|
||||
|
||||
ContextMenuStrip cmsMenu = (ContextMenuStrip)sender;
|
||||
cmsMenu.Items.Clear();
|
||||
cmsMenu.Items.AddRange(this.RightMenuItems.ToArray());
|
||||
|
||||
// 创建QQ、浏览器右键菜单
|
||||
List<ToolStripMenuItem> mQQArray = new List<ToolStripMenuItem>();
|
||||
List<ToolStripMenuItem> mBrowerArray = new List<ToolStripMenuItem>();
|
||||
|
||||
foreach (TreeListColumn column in this._treeView.Columns)
|
||||
if (mSelectRows.Length > 0)
|
||||
{
|
||||
if (!mSelectRow.Table.Columns.Contains(column.Name))
|
||||
continue;
|
||||
string rowValue = mSelectRow[column.Name] + "";
|
||||
if (!string.IsNullOrWhiteSpace(rowValue))
|
||||
DataRow mSelectRow = mSelectRows[0];
|
||||
this._treeView.EndCurrentEdit();
|
||||
this._treeView.ShowEditor();
|
||||
|
||||
// 创建QQ、浏览器右键菜单
|
||||
List<ToolStripMenuItem> mQQArray = new List<ToolStripMenuItem>();
|
||||
List<ToolStripMenuItem> mBrowerArray = new List<ToolStripMenuItem>();
|
||||
|
||||
foreach (TreeListColumn column in this._treeView.Columns)
|
||||
{
|
||||
GridColumnModel model = column.Tag as GridColumnModel;
|
||||
if (model == null) continue;
|
||||
|
||||
if (model.FieldType == ControlType.LabQQ)
|
||||
if (!mSelectRow.Table.Columns.Contains(column.Name))
|
||||
continue;
|
||||
string rowValue = mSelectRow[column.Name] + "";
|
||||
if (!string.IsNullOrWhiteSpace(rowValue))
|
||||
{
|
||||
ToolStripMenuItem item = new ToolStripMenuItem("(" + column.Caption + ")" + rowValue, Resources.qq);
|
||||
item.Tag = mSelectRow[column.Name] + "";
|
||||
item.Click += new EventHandler(QQItemClick);
|
||||
mQQArray.Add(item);
|
||||
}
|
||||
GridColumnModel model = column.Tag as GridColumnModel;
|
||||
if (model == null) continue;
|
||||
|
||||
if (model.FieldType == ControlType.LabWWW &&
|
||||
(rowValue.StartsWith("www.") ||
|
||||
rowValue.StartsWith("http://") ||
|
||||
rowValue.StartsWith("https://") ||
|
||||
rowValue.StartsWith("ftp://") ||
|
||||
rowValue.StartsWith("file://")))
|
||||
{
|
||||
ToolStripMenuItem item = new ToolStripMenuItem("(" + column.Caption + ")" + rowValue, Resources.qq);
|
||||
item.Tag = mSelectRow[column.Name] + "";
|
||||
item.Click += new EventHandler(BrowerItemClick);
|
||||
mBrowerArray.Add(item);
|
||||
if (model.FieldType == ControlType.LabQQ)
|
||||
{
|
||||
ToolStripMenuItem item = new ToolStripMenuItem("(" + column.Caption + ")" + rowValue, Resources.qq);
|
||||
item.Tag = mSelectRow[column.Name] + "";
|
||||
item.Click += new EventHandler(QQItemClick);
|
||||
mQQArray.Add(item);
|
||||
}
|
||||
|
||||
if (model.FieldType == ControlType.LabWWW &&
|
||||
(rowValue.StartsWith("www.") ||
|
||||
rowValue.StartsWith("http://") ||
|
||||
rowValue.StartsWith("https://") ||
|
||||
rowValue.StartsWith("ftp://") ||
|
||||
rowValue.StartsWith("file://")))
|
||||
{
|
||||
ToolStripMenuItem item = new ToolStripMenuItem("(" + column.Caption + ")" + rowValue, Resources.qq);
|
||||
item.Tag = mSelectRow[column.Name] + "";
|
||||
item.Click += new EventHandler(BrowerItemClick);
|
||||
mBrowerArray.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cmsMenu.Items.AddRange(mQQArray.ToArray());
|
||||
cmsMenu.Items.AddRange(mBrowerArray.ToArray());
|
||||
cmsMenu.Items.AddRange(mQQArray.ToArray());
|
||||
cmsMenu.Items.AddRange(mBrowerArray.ToArray());
|
||||
}
|
||||
|
||||
// 判断右键菜单是否可用
|
||||
foreach (ToolStripItem cms in cmsMenu.Items)
|
||||
@@ -139,19 +141,28 @@ namespace Lskj.Control.Model.MenuStrip
|
||||
StringBuilder sqlCondBuilder = new StringBuilder();
|
||||
List<TreeListCell> cells = this._treeView != null ? this._treeView.GetSelectedCells() : null;
|
||||
DataRow focusedRow = this.TreeGridControlObj.GetViewFocusedDataRow();
|
||||
foreach (DataRow selectRow in mSelectRows)
|
||||
|
||||
DataRow[] conditionRows = mSelectRows;
|
||||
if (model.AllowNullExec && conditionRows.Length == 0)
|
||||
{
|
||||
conditionRows = new DataRow[] { new DataTable().NewRow() };
|
||||
}
|
||||
if (conditionRows.Length == 0) continue;
|
||||
|
||||
foreach (DataRow selectRow in conditionRows)
|
||||
{
|
||||
if (selectRow == null) continue;
|
||||
|
||||
string cond = string.Empty;
|
||||
string cond = ReplaceHelper.ReplaceUserInfo(model.MenuCond);
|
||||
cond = RaiseBeforeHandleParamsCallback(model.ParamList, conditionRows, model.MenuCond, selectRow, cond);
|
||||
if (this._control != null)
|
||||
cond = _control.ReplaceParentControlValue(model.MenuCond);
|
||||
cond = ReplaceHelper.ReplaceRowParam(selectRow, model.MenuCond);
|
||||
|
||||
cond = _control.ReplaceParentControlValue(cond);
|
||||
//cond = ReplaceHelper.ReplaceRowParam(selectRow, cond);
|
||||
cond = ReplaceHelper.ReplaceRowParamEmptyWrapQuote(selectRow, cond);
|
||||
if (model.Mergeexec && cond.StartsWith("@"))
|
||||
{
|
||||
//替换[],替换的是多选行中的数据
|
||||
cond = ReplaceHelper.ReplaceRowParam(mSelectRows, cond.Replace("[", "{").Replace("]", "}"), "", "");
|
||||
cond = ReplaceHelper.ReplaceRowParam(conditionRows, cond.Replace("[", "{").Replace("]", "}"), "", "");
|
||||
}
|
||||
|
||||
if (cells != null && cells.Count > 0 && cond.Contains("{COLUMN_"))
|
||||
@@ -173,14 +184,17 @@ namespace Lskj.Control.Model.MenuStrip
|
||||
condBuilder.Append($"({cond}) and ");
|
||||
}
|
||||
}
|
||||
string condStr = "";
|
||||
if (model.MenuCond.StartsWith("@"))
|
||||
string condStr = model.MenuCond;
|
||||
if (!string.IsNullOrWhiteSpace(sqlCondBuilder.ToString()) || !string.IsNullOrWhiteSpace(condBuilder.ToString()))
|
||||
{
|
||||
condStr = $"@if({sqlCondBuilder.ToString().TrimEnd().TrimEnd('d', 'n', 'a')}) begin select '1' end else begin select '0' end";
|
||||
}
|
||||
else
|
||||
{
|
||||
condStr = condBuilder.ToString().TrimEnd().TrimEnd('d', 'n', 'a');
|
||||
if (model.MenuCond.StartsWith("@"))
|
||||
{
|
||||
condStr = $"@if({sqlCondBuilder.ToString().TrimEnd().TrimEnd('d', 'n', 'a')}) begin select '1' end else begin select '0' end";
|
||||
}
|
||||
else
|
||||
{
|
||||
condStr = condBuilder.ToString().TrimEnd().TrimEnd('d', 'n', 'a');
|
||||
}
|
||||
}
|
||||
condResult = ValidateCond(condStr, null);
|
||||
//cms.Enabled = ReplaceHelper.EvalCond(cond);
|
||||
|
||||
@@ -27,7 +27,43 @@ namespace Lskj.Control
|
||||
public sealed class MessageUtil
|
||||
{
|
||||
|
||||
public static string Prompt = string.IsNullOrWhiteSpace(SystemInfo.Instance.DeadlockPrompt) ? "网络连接超时,请稍候再试!" : SystemInfo.Instance.DeadlockPrompt;
|
||||
public static string Prompt = "网络连接超时,请稍候再试!";
|
||||
|
||||
/// <summary>
|
||||
/// 系统配置尚未初始化时不主动访问数据库,读取失败则使用默认死锁提示。
|
||||
/// </summary>
|
||||
private static bool TryGetDeadlockPrompt(string message, out string deadlockPrompt)
|
||||
{
|
||||
deadlockPrompt = message;
|
||||
if (string.IsNullOrEmpty(message) || !message.Contains("与另一个进程被死锁在"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool promptDeadlock = false;
|
||||
string configuredPrompt = string.Empty;
|
||||
try
|
||||
{
|
||||
SystemInfo systemInfo = SystemInfo.Instance;
|
||||
if (systemInfo != null)
|
||||
{
|
||||
promptDeadlock = systemInfo.PromptDeadlock;
|
||||
configuredPrompt = systemInfo.DeadlockPrompt;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 数据库连接失败或系统参数尚未初始化时,提示框仍使用安全默认值。
|
||||
}
|
||||
|
||||
if (promptDeadlock)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
deadlockPrompt = string.IsNullOrWhiteSpace(configuredPrompt) ? Prompt : configuredPrompt;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
@@ -54,8 +90,9 @@ namespace Lskj.Control
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(msg) && msg.Contains("与另一个进程被死锁在")&& !SystemInfo.Instance.PromptDeadlock)
|
||||
msg = Prompt;
|
||||
string deadlockPrompt;
|
||||
if (TryGetDeadlockPrompt(msg, out deadlockPrompt))
|
||||
msg = deadlockPrompt;
|
||||
if (Business.Impl.LanguageTranslation.Translatable)
|
||||
{
|
||||
msg = Business.Impl.LanguageTranslation.GetTranslatedText(msg);
|
||||
@@ -89,9 +126,10 @@ namespace Lskj.Control
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(errorMessage) && errorMessage.Contains("与另一个进程被死锁在") && !SystemInfo.Instance.PromptDeadlock)
|
||||
string deadlockPrompt;
|
||||
if (TryGetDeadlockPrompt(errorMessage, out deadlockPrompt))
|
||||
{
|
||||
errorMessage = Prompt;
|
||||
errorMessage = deadlockPrompt;
|
||||
if (Business.Impl.LanguageTranslation.Translatable)
|
||||
{
|
||||
errorMessage = Business.Impl.LanguageTranslation.GetTranslatedText(errorMessage);
|
||||
@@ -165,8 +203,9 @@ namespace Lskj.Control
|
||||
if (Debugger.IsAttached)
|
||||
{
|
||||
string msg = ex == null ? ResourceKeys.UnKownErrorTip : ex.StackTrace;
|
||||
if (!string.IsNullOrEmpty(msg) && msg.Contains("与另一个进程被死锁在") && !SystemInfo.Instance.PromptDeadlock)
|
||||
msg = Prompt;
|
||||
string deadlockPrompt;
|
||||
if (TryGetDeadlockPrompt(msg, out deadlockPrompt))
|
||||
msg = deadlockPrompt;
|
||||
if (Business.Impl.LanguageTranslation.Translatable)
|
||||
{
|
||||
msg = Business.Impl.LanguageTranslation.GetTranslatedText(msg);
|
||||
@@ -176,8 +215,9 @@ namespace Lskj.Control
|
||||
else
|
||||
{
|
||||
string msg = ex == null ? ResourceKeys.UnKownErrorTip : ex.Message; //ResourceKeys.SystemErrorTip + "\r\n" + ex.Message + "\r\n" + ex.StackTrace;
|
||||
if (!string.IsNullOrEmpty(msg) && msg.Contains("与另一个进程被死锁在") && !SystemInfo.Instance.PromptDeadlock)
|
||||
msg = Prompt;
|
||||
string deadlockPrompt;
|
||||
if (TryGetDeadlockPrompt(msg, out deadlockPrompt))
|
||||
msg = deadlockPrompt;
|
||||
if (Business.Impl.LanguageTranslation.Translatable)
|
||||
{
|
||||
msg = Business.Impl.LanguageTranslation.GetTranslatedText(msg);
|
||||
|
||||
@@ -32,8 +32,10 @@ namespace Lskj.Control.Model
|
||||
/// <summary>
|
||||
/// 查询控件、添加修改界面控件管理类
|
||||
/// </summary>
|
||||
public class MyControl
|
||||
public class MyControl : IDisposable
|
||||
{
|
||||
private const long UserSearchCooldownTicks =
|
||||
TimeSpan.TicksPerMillisecond * 350;
|
||||
private string _searchSql;
|
||||
private DataTable _controls;
|
||||
private DataTable _schemes;
|
||||
@@ -46,8 +48,12 @@ namespace Lskj.Control.Model
|
||||
private GridControlEx _gridLeft;
|
||||
private TreeViewEx _tvLeft;
|
||||
private MyControl _leftSearch;
|
||||
private DropDownButton _dropDown = new DropDownButton();
|
||||
private PopupMenu _popupMenu = new PopupMenu();
|
||||
private DropDownButton _dropDown;
|
||||
private PopupMenu _popupMenu;
|
||||
private bool mDisposed;
|
||||
private bool mUserSearchInProgress;
|
||||
private long mLastUserSearchCompletedTicks;
|
||||
private int mAcceptedUserSearchCount;
|
||||
/// <summary>
|
||||
/// 计算字段
|
||||
/// </summary>
|
||||
@@ -112,6 +118,10 @@ namespace Lskj.Control.Model
|
||||
/// </summary>
|
||||
/// <value>The button object.</value>
|
||||
public SimpleButton ButtonObj { get { return _button; } }
|
||||
public int AcceptedUserSearchCount
|
||||
{
|
||||
get { return mAcceptedUserSearchCount; }
|
||||
}
|
||||
/// <summary>
|
||||
/// 条件数据源刷新按钮
|
||||
/// </summary>
|
||||
@@ -133,9 +143,20 @@ namespace Lskj.Control.Model
|
||||
public DataRow CurrentData;
|
||||
public ModuleModel SystemModel;
|
||||
/// <summary>
|
||||
/// 外部已查询的MRP操作按钮数据;为空时保持原查询逻辑。
|
||||
/// </summary>
|
||||
public DataTable MrpClickMenus;
|
||||
/// <summary>
|
||||
/// 下拉框、搜索框控件对象
|
||||
/// </summary>
|
||||
public List<ControlModel> mControlList = new List<ControlModel>();
|
||||
private readonly List<LabelExtendedReturnSearchEdit> mExtendedReturnSearchControls =
|
||||
new List<LabelExtendedReturnSearchEdit>();
|
||||
private readonly List<KeyValuePair<object, EventArgs>> mExtendedReturnPendingChanges =
|
||||
new List<KeyValuePair<object, EventArgs>>();
|
||||
private readonly ExtendedReturnModuleSourceResolver mExtendedReturnModuleSourceResolver =
|
||||
new ExtendedReturnModuleSourceResolver();
|
||||
private int mExtendedReturnBatchDepth;
|
||||
/// <summary>
|
||||
/// 数据源任务对象
|
||||
/// </summary>
|
||||
@@ -258,6 +279,12 @@ namespace Lskj.Control.Model
|
||||
///特殊左侧表
|
||||
/// </summary>
|
||||
public GridControlEx SpecialLeftTable;
|
||||
/// <summary>
|
||||
///修改前的数据源
|
||||
/// </summary>
|
||||
public DataRow beforeData;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 控件Panel对象
|
||||
/// </summary>
|
||||
@@ -886,10 +913,13 @@ namespace Lskj.Control.Model
|
||||
return controlModel;
|
||||
}));
|
||||
}
|
||||
Task<DataTable> rightDtGridRightMenusTask = cachesDic.AddTask(this, "RightDtGridRightMenus", new Task<DataTable>(() =>
|
||||
if (MrpClickMenus == null)
|
||||
{
|
||||
return BaseModuleImpl.GetBaseGridRightMenus(dynamicModel.ModuleCode, ModuleType.MrpClickBtn);
|
||||
}));
|
||||
Task<DataTable> rightDtGridRightMenusTask = cachesDic.AddTask(this, "RightDtGridRightMenus", new Task<DataTable>(() =>
|
||||
{
|
||||
return BaseModuleImpl.GetBaseGridRightMenus(dynamicModel.ModuleCode, ModuleType.MrpClickBtn);
|
||||
}));
|
||||
}
|
||||
return true;
|
||||
}));
|
||||
}
|
||||
@@ -1011,6 +1041,10 @@ namespace Lskj.Control.Model
|
||||
// 创建模版搜索
|
||||
if (_schemes != null && ModuleId > 0 && _schemes.Rows.Count > 0)
|
||||
{
|
||||
if (_popupMenu == null)
|
||||
{
|
||||
_popupMenu = new PopupMenu();
|
||||
}
|
||||
_dropDown = new DropDownButton();
|
||||
_dropDown.DropDownArrowStyle = DropDownArrowStyle.Show;
|
||||
_dropDown.DropDownControl = this._popupMenu;
|
||||
@@ -1029,7 +1063,17 @@ namespace Lskj.Control.Model
|
||||
}
|
||||
if (dynamicModel != null && !string.IsNullOrEmpty(dynamicModel.ModuleCode))
|
||||
{
|
||||
if (!dataCaches.GetValue(parent, "SysModel", out ModuleModel moduleModel))
|
||||
ModuleModel moduleModel = null;
|
||||
if (SystemModel != null && string.Equals(SystemModel.ModeCode, dynamicModel.ModuleCode, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
moduleModel = SystemModel;
|
||||
}
|
||||
if (moduleModel == null && dataCaches.GetValue(parent, "SysModel", out ModuleModel cacheModuleModel) &&
|
||||
cacheModuleModel != null && string.Equals(cacheModuleModel.ModeCode, dynamicModel.ModuleCode, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
moduleModel = cacheModuleModel;
|
||||
}
|
||||
if (moduleModel == null)
|
||||
{
|
||||
moduleModel = new ModuleModel(MainImpl.GetSystemdllTab(dynamicModel.ModuleCode));
|
||||
}
|
||||
@@ -1047,13 +1091,14 @@ namespace Lskj.Control.Model
|
||||
btnCondSearch.Click += new EventHandler(OnBtnCondSearchClick);
|
||||
}
|
||||
}
|
||||
DataTable rightDt = null;
|
||||
if (dynamicModel != null)
|
||||
DataTable rightDt = MrpClickMenus;
|
||||
if (rightDt == null && dynamicModel != null)
|
||||
{
|
||||
if (!dataCaches.GetValue(parent, "RightDtGridRightMenus", out rightDt))
|
||||
if (!dataCaches.GetValue(this, "RightDtGridRightMenus", out rightDt))
|
||||
{
|
||||
rightDt = BaseModuleImpl.GetBaseGridRightMenus(dynamicModel.ModuleCode, ModuleType.MrpClickBtn);
|
||||
}
|
||||
MrpClickMenus = rightDt;
|
||||
}
|
||||
if (rightDt != null && rightDt.Rows.Count > 0)
|
||||
{
|
||||
@@ -1191,6 +1236,10 @@ namespace Lskj.Control.Model
|
||||
// 创建模版搜索
|
||||
if (_schemes != null && ModuleId > 0 && _schemes.Rows.Count > 0)
|
||||
{
|
||||
if (_popupMenu == null)
|
||||
{
|
||||
_popupMenu = new PopupMenu();
|
||||
}
|
||||
_dropDown = new DropDownButton();
|
||||
_dropDown.DropDownArrowStyle = DropDownArrowStyle.Show;
|
||||
_dropDown.DropDownControl = this._popupMenu;
|
||||
@@ -1207,13 +1256,14 @@ namespace Lskj.Control.Model
|
||||
_popupMenu.Name = "pm_search";
|
||||
CreateSearchScheme();
|
||||
}
|
||||
DataTable rightDt = null;
|
||||
if (dynamicModel != null)
|
||||
DataTable rightDt = MrpClickMenus;
|
||||
if (rightDt == null && dynamicModel != null)
|
||||
{
|
||||
if (!dynamicModel.DataCaches.GetValue(parent, "RightDtGridRightMenus", out rightDt))
|
||||
if (!dynamicModel.DataCaches.GetValue(this, "RightDtGridRightMenus", out rightDt))
|
||||
{
|
||||
rightDt = BaseModuleImpl.GetBaseGridRightMenus(dynamicModel.ModuleCode, ModuleType.MrpClickBtn);
|
||||
}
|
||||
MrpClickMenus = rightDt;
|
||||
}
|
||||
if (rightDt != null && rightDt.Rows.Count > 0)
|
||||
{
|
||||
@@ -1282,10 +1332,13 @@ namespace Lskj.Control.Model
|
||||
return controlModel;
|
||||
}));
|
||||
}
|
||||
Task<DataTable> rightDtGridRightMenusTask = cachesDic.AddTask(this, "RightDtGridRightMenus", new Task<DataTable>(() =>
|
||||
if (MrpClickMenus == null)
|
||||
{
|
||||
return BaseModuleImpl.GetBaseGridRightMenus(dynamicModel.ModuleCode, ModuleType.MrpClickBtn);
|
||||
}));
|
||||
Task<DataTable> rightDtGridRightMenusTask = cachesDic.AddTask(this, "RightDtGridRightMenus", new Task<DataTable>(() =>
|
||||
{
|
||||
return BaseModuleImpl.GetBaseGridRightMenus(dynamicModel.ModuleCode, ModuleType.MrpClickBtn);
|
||||
}));
|
||||
}
|
||||
return true;
|
||||
}));
|
||||
}
|
||||
@@ -1723,8 +1776,14 @@ namespace Lskj.Control.Model
|
||||
WaitForm.HideForm();
|
||||
mControlSourceDic.Clear();
|
||||
if (this.OnDataSourceBindCallBack != null) this.OnDataSourceBindCallBack(this, null);
|
||||
this.mTimer.Stop();
|
||||
this.mTimer.Dispose();
|
||||
Timer timer = this.mTimer;
|
||||
this.mTimer = null;
|
||||
if (timer != null)
|
||||
{
|
||||
timer.Tick -= mTimerTick;
|
||||
timer.Stop();
|
||||
timer.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2036,8 +2095,6 @@ namespace Lskj.Control.Model
|
||||
case ControlType.LabDate:
|
||||
case ControlType.LabDateTime:
|
||||
case ControlType.LabDateTimeShort:
|
||||
case ControlType.LabTime:
|
||||
case ControlType.LabShortTime:
|
||||
// 日期控件
|
||||
LabelDateEdit dateEdit = ctr as LabelDateEdit;
|
||||
if (string.IsNullOrWhiteSpace(dateEdit.FormatType))
|
||||
@@ -2050,6 +2107,12 @@ namespace Lskj.Control.Model
|
||||
}
|
||||
//value = dateEdit.TextEdit.EditValue == null ? dateEdit.EditText : dateEdit.TextEdit.EditValue.ToString();
|
||||
break;
|
||||
case ControlType.LabTime:
|
||||
case ControlType.LabShortTime:
|
||||
// 时间控件只返回时分秒部分,不附带日期。
|
||||
LabelTimeEdit timeEdit = ctr as LabelTimeEdit;
|
||||
value = timeEdit == null ? string.Empty : timeEdit.EditText;
|
||||
break;
|
||||
case ControlType.LabDateHalfDay:
|
||||
// 日期半天控件
|
||||
LabelDateHalfDayEdit dateHalfDayEdit = ctr as LabelDateHalfDayEdit;
|
||||
@@ -2253,6 +2316,11 @@ namespace Lskj.Control.Model
|
||||
LabelMultiAutoTextEdit4 moduleReturnsIdNew = ctr as LabelMultiAutoTextEdit4;
|
||||
value = ControlType.LabSelectReturnIdNew == model.FieldType ? moduleReturnsIdNew.EditValue : moduleReturnsIdNew.EditText;
|
||||
break;
|
||||
case ControlType.LabModuleSelectReturnIdExtended:
|
||||
case ControlType.LabSearchReturnIdExtended:
|
||||
LabelExtendedReturnSearchEdit extendedReturnSearch = ctr as LabelExtendedReturnSearchEdit;
|
||||
value = extendedReturnSearch == null ? string.Empty : extendedReturnSearch.EditValue;
|
||||
break;
|
||||
case ControlType.DynamicallyGeneratedSql:
|
||||
LabelMultiAutoTextEdit3 moduleSqlGenerated = ctr as LabelMultiAutoTextEdit3;
|
||||
value = moduleSqlGenerated.EditText;
|
||||
@@ -2679,6 +2747,7 @@ namespace Lskj.Control.Model
|
||||
|
||||
}
|
||||
}
|
||||
RefreshExtendedReturnDisplayControls();
|
||||
foreach (ControlModel model in this.ControlModels)
|
||||
{
|
||||
BaseUserControl control = FindControl(model);
|
||||
@@ -3035,6 +3104,8 @@ namespace Lskj.Control.Model
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
// 修改记录
|
||||
foreach (ControlModel model in this.ControlModels)
|
||||
{
|
||||
@@ -3051,6 +3122,16 @@ namespace Lskj.Control.Model
|
||||
if (userControl != null)
|
||||
{
|
||||
string fieldValue = this.GetControlValue(model);
|
||||
|
||||
if (beforeData != null &&
|
||||
beforeData.Table != null &&
|
||||
beforeData.Table.Columns.Contains(model.FieldName) &&
|
||||
AuditChangeLog.IsSameValue(beforeData[model.FieldName] + "", fieldValue))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (fieldValue == "****") continue;
|
||||
if (model.FieldType == 7)
|
||||
{
|
||||
@@ -3710,6 +3791,14 @@ namespace Lskj.Control.Model
|
||||
}
|
||||
pictureEdit.TextEdit.Image = image;
|
||||
}
|
||||
else if (baseControl is LabelExtendedReturnSearchEdit)
|
||||
{
|
||||
LabelExtendedReturnSearchEdit extendedReturnSearch = baseControl as LabelExtendedReturnSearchEdit;
|
||||
extendedReturnSearch.EditValue = controlValue == null || controlValue == DBNull.Value
|
||||
? string.Empty
|
||||
: controlValue + "";
|
||||
baseControl.Model.Text = extendedReturnSearch.EditValue;
|
||||
}
|
||||
else if (baseControl.Model.FieldType == 7 && !"****".Equals(controlValue))
|
||||
{
|
||||
string dfmt = baseControl.Model.DataFormat;
|
||||
@@ -3750,6 +3839,118 @@ namespace Lskj.Control.Model
|
||||
//baseControl.Parent.Focus();
|
||||
}
|
||||
}
|
||||
RefreshExtendedReturnDisplayControls();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 用户从扩展搜索弹窗选择或清空时,批量写入所有映射字段。
|
||||
/// 中间值改变事件会延迟到全部字段提交成功后执行,且不改变原始值基线。
|
||||
/// </summary>
|
||||
public void ApplyExtendedReturnValues(IList<KeyValuePair<string, object>> values)
|
||||
{
|
||||
if (values == null || values.Count == 0) return;
|
||||
if (mExtendedReturnBatchDepth > 0)
|
||||
{
|
||||
throw new InvalidOperationException("扩展返回字段正在批量赋值,不能重复执行。");
|
||||
}
|
||||
|
||||
List<KeyValuePair<string, object>> normalizedValues =
|
||||
new List<KeyValuePair<string, object>>();
|
||||
Dictionary<string, string> originalValues =
|
||||
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
Dictionary<BaseUserControl, string> originalModelTexts =
|
||||
new Dictionary<BaseUserControl, string>();
|
||||
HashSet<string> targetFields = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
foreach (KeyValuePair<string, object> value in values)
|
||||
{
|
||||
string targetField = (value.Key ?? string.Empty).Trim();
|
||||
if (targetField.Length == 0)
|
||||
{
|
||||
throw new InvalidOperationException("扩展返回字段名称不能为空。");
|
||||
}
|
||||
if (!targetFields.Add(targetField))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
string.Format("扩展返回字段“{0}”重复。", targetField));
|
||||
}
|
||||
|
||||
BaseUserControl targetControl = FindControl(targetField);
|
||||
if (targetControl == null)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
string.Format("MyControl 中不存在业务控件“{0}”。", targetField));
|
||||
}
|
||||
|
||||
object normalizedValue = value.Value == null || value.Value == DBNull.Value
|
||||
? string.Empty
|
||||
: value.Value;
|
||||
normalizedValues.Add(new KeyValuePair<string, object>(targetField, normalizedValue));
|
||||
originalValues[targetField] = GetControlValue(targetField);
|
||||
originalModelTexts[targetControl] = targetControl.Model == null
|
||||
? null
|
||||
: targetControl.Model.Text;
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
mExtendedReturnPendingChanges.Clear();
|
||||
mExtendedReturnBatchDepth++;
|
||||
try
|
||||
{
|
||||
foreach (KeyValuePair<string, object> value in normalizedValues)
|
||||
{
|
||||
SetControlValue(value.Key, value.Value);
|
||||
}
|
||||
RestoreExtendedReturnModelTexts(originalModelTexts);
|
||||
RefreshExtendedReturnDisplayControls(true);
|
||||
success = true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
foreach (KeyValuePair<string, string> originalValue in originalValues)
|
||||
{
|
||||
SetControlValue(originalValue.Key, originalValue.Value);
|
||||
}
|
||||
RestoreExtendedReturnModelTexts(originalModelTexts);
|
||||
RefreshExtendedReturnDisplayControls(true);
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
mExtendedReturnBatchDepth--;
|
||||
if (!success) mExtendedReturnPendingChanges.Clear();
|
||||
}
|
||||
|
||||
FlushExtendedReturnPendingChanges();
|
||||
}
|
||||
|
||||
private static void RestoreExtendedReturnModelTexts(
|
||||
IDictionary<BaseUserControl, string> originalModelTexts)
|
||||
{
|
||||
foreach (KeyValuePair<BaseUserControl, string> item in originalModelTexts)
|
||||
{
|
||||
if (item.Key != null && item.Key.Model != null)
|
||||
{
|
||||
item.Key.Model.Text = item.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshExtendedReturnDisplayControls(bool force = false)
|
||||
{
|
||||
if (mExtendedReturnBatchDepth > 0 && !force) return;
|
||||
foreach (LabelExtendedReturnSearchEdit control in mExtendedReturnSearchControls)
|
||||
{
|
||||
if (control != null && !control.IsDisposed && control.Model != null)
|
||||
{
|
||||
control.RefreshDisplayText();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string ResolveExtendedReturnModuleSourceSql(string moduleCode)
|
||||
{
|
||||
return mExtendedReturnModuleSourceResolver.Resolve(moduleCode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -4152,6 +4353,7 @@ namespace Lskj.Control.Model
|
||||
model.Sign = item.Table.Columns.Contains("TM_tagID") && !string.IsNullOrEmpty(item["TM_tagID"] + "") ? Convert.ToInt32(item["TM_tagID"] + "") : 0;
|
||||
model.TextMember = item["lookupResult"] + "";
|
||||
model.ValueMember = item["lookupKeyField"] + "";
|
||||
model.ResultFields = item.Table.Columns.Contains("resultfields") ? item["resultfields"] + "" : string.Empty;
|
||||
|
||||
if (!dataCaches.GetValue(item, "LookupSql", out string lookupSql))
|
||||
{
|
||||
@@ -4212,7 +4414,7 @@ namespace Lskj.Control.Model
|
||||
model.ModuleFrameDisplayText = item.Table.Columns.Contains("ModuleFrameDisplayText") ? "1".Equals(item["ModuleFrameDisplayText"] + "") : false;
|
||||
model.InputBoxFontSize = item.Table.Columns.Contains("InputBoxFontSize") && !string.IsNullOrEmpty(item["InputBoxFontSize"] + "") ? Convert.ToInt32(item["InputBoxFontSize"] + "") : 0;
|
||||
model.RememberValue = item.Table.Columns.Contains("RememberValue") ? "1".Equals(item["RememberValue"] + "") : false;
|
||||
|
||||
model.SumlistField = item.Table.Columns.Contains("SumlistField") ? item["SumlistField"] + "" : "";
|
||||
|
||||
//为了和工具里和bs里统一
|
||||
if (model.FieldType == 42)
|
||||
@@ -4239,27 +4441,7 @@ namespace Lskj.Control.Model
|
||||
model.FieldType = 161;
|
||||
model.IsRadio = true;
|
||||
}
|
||||
//快速搜索框在控件中转成普通搜索框
|
||||
if (model.FieldType == 181 || model.FieldType == 182 || model.FieldType == 183 || model.FieldType == 184)
|
||||
{
|
||||
switch (model.FieldType)
|
||||
{
|
||||
case ControlType.DictionarySearchBoxToId:
|
||||
model.FieldType = 5;
|
||||
break;
|
||||
case ControlType.DictionarySearchBoxToText:
|
||||
model.FieldType = 6;
|
||||
break;
|
||||
case ControlType.DictionarySearchBoxToIdParam:
|
||||
model.FieldType = 15;
|
||||
break;
|
||||
case ControlType.DictionarySearchBoxToTextParam:
|
||||
model.FieldType = 16;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
return model;
|
||||
}
|
||||
@@ -4341,11 +4523,20 @@ namespace Lskj.Control.Model
|
||||
Font mRowFont = new Font("Microsoft YaHei UI", 12);
|
||||
switch (model.FieldType)
|
||||
{
|
||||
case ControlType.LabTime:
|
||||
case ControlType.LabShortTime:
|
||||
// 时间控件使用 TimeEdit,避免 DateEdit 显示日期日历。
|
||||
LabelTimeEdit timeEdit = new LabelTimeEdit();
|
||||
timeEdit.TextEdit.KeyDown += new KeyEventHandler(OnTextEditKeyDown);
|
||||
timeEdit.TextEdit.TextChanged += new EventHandler(OnTextEditTextChanged);
|
||||
// 时间类型固定使用时分或时分秒,避免旧的日期格式配置覆盖为年月日。
|
||||
timeEdit.TimeFormat(DateFormat.Format(model.FieldType));
|
||||
if (!isLoadBorder) timeEdit.TextEdit.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
|
||||
baseControl = timeEdit;
|
||||
break;
|
||||
case ControlType.LabDate:
|
||||
case ControlType.LabDateTime:
|
||||
case ControlType.LabDateTimeShort:
|
||||
case ControlType.LabTime:
|
||||
case ControlType.LabShortTime:
|
||||
case ControlType.LabShortDate:
|
||||
// 日期控件
|
||||
LabelDateEdit dateEdit = new LabelDateEdit();
|
||||
@@ -4615,6 +4806,11 @@ namespace Lskj.Control.Model
|
||||
multiAutoEdit.ValueField = model.ValueMember;
|
||||
multiAutoEdit.TextField = model.TextMember;
|
||||
multiAutoEdit.ControlObj = this;
|
||||
if (Model != null)
|
||||
{
|
||||
multiAutoEdit.CurrentOperColumnKey = Model.ModuleCode + "_" + model.FieldName;
|
||||
}
|
||||
|
||||
//multiAutoEdit.SetDataSource(dataSource);
|
||||
multiAutoEdit.TextBoxProhibition = model.TextBoxProhibition;
|
||||
multiAutoEdit.TextEdit.KeyDown += new KeyEventHandler(OnTextEditKeyDown);
|
||||
@@ -4829,6 +5025,19 @@ namespace Lskj.Control.Model
|
||||
if (!isLoadBorder) moduleReturnsIdNew.TextEdit.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
|
||||
baseControl = moduleReturnsIdNew;
|
||||
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:
|
||||
LabelMultiAutoTextEdit3 moduleSqlGenerated = new LabelMultiAutoTextEdit3();
|
||||
// moduleSqlGenerated.SetDataSource();
|
||||
@@ -5883,6 +6092,49 @@ namespace Lskj.Control.Model
|
||||
/// <param name="sender">The source of the event.</param>
|
||||
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
|
||||
protected void OnTextEditTextChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (mExtendedReturnBatchDepth > 0)
|
||||
{
|
||||
QueueExtendedReturnPendingChange(sender, e);
|
||||
return;
|
||||
}
|
||||
ProcessTextEditTextChanged(sender, e);
|
||||
}
|
||||
|
||||
private void QueueExtendedReturnPendingChange(object sender, EventArgs e)
|
||||
{
|
||||
System.Windows.Forms.Control changedControl = sender as System.Windows.Forms.Control;
|
||||
BaseUserControl baseControl = changedControl == null
|
||||
? null
|
||||
: changedControl.ToBaseUserControl();
|
||||
foreach (KeyValuePair<object, EventArgs> pendingChange in mExtendedReturnPendingChanges)
|
||||
{
|
||||
System.Windows.Forms.Control pendingControl =
|
||||
pendingChange.Key as System.Windows.Forms.Control;
|
||||
BaseUserControl pendingBaseControl = pendingControl == null
|
||||
? null
|
||||
: pendingControl.ToBaseUserControl();
|
||||
if (baseControl != null && object.ReferenceEquals(baseControl, pendingBaseControl))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
mExtendedReturnPendingChanges.Add(
|
||||
new KeyValuePair<object, EventArgs>(sender, e ?? EventArgs.Empty));
|
||||
}
|
||||
|
||||
private void FlushExtendedReturnPendingChanges()
|
||||
{
|
||||
KeyValuePair<object, EventArgs>[] pendingChanges =
|
||||
mExtendedReturnPendingChanges.ToArray();
|
||||
mExtendedReturnPendingChanges.Clear();
|
||||
foreach (KeyValuePair<object, EventArgs> pendingChange in pendingChanges)
|
||||
{
|
||||
ProcessTextEditTextChanged(pendingChange.Key, pendingChange.Value);
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessTextEditTextChanged(object sender, EventArgs e)
|
||||
{
|
||||
BaseUserControl baseControl = (sender as System.Windows.Forms.Control).ToBaseUserControl();
|
||||
this.SetUnionAncCalcControl(baseControl);
|
||||
@@ -5898,6 +6150,61 @@ namespace Lskj.Control.Model
|
||||
}
|
||||
}
|
||||
|
||||
private bool TryBeginUserSearch()
|
||||
{
|
||||
if (mDisposed || mUserSearchInProgress)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
long now = DateTime.UtcNow.Ticks;
|
||||
if (mLastUserSearchCompletedTicks > 0 &&
|
||||
now - mLastUserSearchCompletedTicks < UserSearchCooldownTicks)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
mUserSearchInProgress = true;
|
||||
mAcceptedUserSearchCount++;
|
||||
return true;
|
||||
}
|
||||
|
||||
private void EndUserSearch()
|
||||
{
|
||||
mUserSearchInProgress = false;
|
||||
mLastUserSearchCompletedTicks = DateTime.UtcNow.Ticks;
|
||||
}
|
||||
|
||||
private bool ExecuteUserSearch(object sender, EventArgs e)
|
||||
{
|
||||
if (!TryBeginUserSearch())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
SearchArgs args = new SearchArgs();
|
||||
if (OnSearchBeforeCallBack != null)
|
||||
{
|
||||
OnSearchBeforeCallBack(sender, args);
|
||||
}
|
||||
if (args.Continue)
|
||||
{
|
||||
this.SearchGrid(false);
|
||||
}
|
||||
if (OnSearchAfterCallBack != null)
|
||||
{
|
||||
OnSearchAfterCallBack(sender, e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
EndUserSearch();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>说明:</para>
|
||||
/// <para>创建人:龚宇超</para>
|
||||
@@ -5922,18 +6229,8 @@ namespace Lskj.Control.Model
|
||||
{
|
||||
if (baseControl.Model.IsSearchControl)
|
||||
{
|
||||
// 搜索控件回车直接搜索
|
||||
SearchArgs args = new SearchArgs();
|
||||
// 查询之前
|
||||
if (OnSearchBeforeCallBack != null)
|
||||
OnSearchBeforeCallBack(sender, args);
|
||||
|
||||
if (args.Continue) this.SearchGrid(false);
|
||||
|
||||
// 查询之后
|
||||
if (OnSearchAfterCallBack != null) OnSearchAfterCallBack(sender, e);
|
||||
|
||||
if (baseControl.Model.ScanAfterEmpty)
|
||||
if (ExecuteUserSearch(sender, e) &&
|
||||
baseControl.Model.ScanAfterEmpty)
|
||||
{
|
||||
baseControl.EditText = string.Empty;
|
||||
}
|
||||
@@ -6032,14 +6329,7 @@ namespace Lskj.Control.Model
|
||||
{
|
||||
if (baseControl.Model.IsSearchControl)
|
||||
{
|
||||
// 搜索控件回车直接搜索
|
||||
SearchArgs args = new SearchArgs();
|
||||
// 查询之前
|
||||
if (OnSearchBeforeCallBack != null)
|
||||
OnSearchBeforeCallBack(sender, args);
|
||||
if (args.Continue) this.SearchGrid(false);
|
||||
// 查询之后
|
||||
if (OnSearchAfterCallBack != null) OnSearchAfterCallBack(sender, e);
|
||||
ExecuteUserSearch(sender, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6056,45 +6346,57 @@ namespace Lskj.Control.Model
|
||||
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
|
||||
protected void OnSimpleButtonClick(object sender, EventArgs e)
|
||||
{
|
||||
if (!TryBeginUserSearch())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (Model != null)
|
||||
try
|
||||
{
|
||||
bool allowBefore = ApiHelper.IsExecEventApi(Interface.Api.OperateEvent.BeforeSearchBtnClick, Model.ModuleCode, 0);
|
||||
//查询前调用Api接口
|
||||
if (allowBefore)
|
||||
if (Model != null)
|
||||
{
|
||||
DataRow dataRow = this.GetAllControlValueRow();
|
||||
ApiHelper apiHelper = new ApiHelper(Model.ModuleCode, 0, dataRow);
|
||||
apiHelper.OnEvent(Interface.Api.OperateEvent.BeforeSearchBtnClick, Interface.Api.ActionType.None);
|
||||
if (apiHelper.apiHandlerModels.Count > 0)
|
||||
bool allowBefore = ApiHelper.IsExecEventApi(Interface.Api.OperateEvent.BeforeSearchBtnClick, Model.ModuleCode, 0);
|
||||
//查询前调用Api接口
|
||||
if (allowBefore)
|
||||
{
|
||||
Hashtable hashtable = apiHelper.apiHandlerModels[apiHelper.apiHandlerModels.Count - 1].resultPmsHashtables[0];
|
||||
if (hashtable.ContainsKey("result"))
|
||||
DataRow dataRow = this.GetAllControlValueRow();
|
||||
ApiHelper apiHelper = new ApiHelper(Model.ModuleCode, 0, dataRow);
|
||||
apiHelper.OnEvent(Interface.Api.OperateEvent.BeforeSearchBtnClick, Interface.Api.ActionType.None);
|
||||
if (apiHelper.apiHandlerModels.Count > 0)
|
||||
{
|
||||
string jsonResult = hashtable["result"] + "";
|
||||
DataTable dataTable = JsonConvert.DeserializeObject<DataTable>(jsonResult);
|
||||
this._mainGridEx.SetGridViewDataSource(dataTable);
|
||||
return;
|
||||
Hashtable hashtable = apiHelper.apiHandlerModels[apiHelper.apiHandlerModels.Count - 1].resultPmsHashtables[0];
|
||||
if (hashtable.ContainsKey("result"))
|
||||
{
|
||||
string jsonResult = hashtable["result"] + "";
|
||||
DataTable dataTable = JsonConvert.DeserializeObject<DataTable>(jsonResult);
|
||||
this._mainGridEx.SetGridViewDataSource(dataTable);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageUtil.Show(ex.Message);
|
||||
}
|
||||
SearchArgs args = new SearchArgs();
|
||||
// 查询之前
|
||||
if (OnSearchBeforeCallBack != null)
|
||||
OnSearchBeforeCallBack(sender, args);
|
||||
|
||||
if (args.Continue) this.SearchGrid(false);
|
||||
|
||||
// 查询之后
|
||||
if (OnSearchAfterCallBack != null) OnSearchAfterCallBack(sender, e);
|
||||
}
|
||||
catch (Exception ex)
|
||||
finally
|
||||
{
|
||||
MessageUtil.Show(ex.Message);
|
||||
EndUserSearch();
|
||||
}
|
||||
SearchArgs args = new SearchArgs();
|
||||
// 查询之前
|
||||
if (OnSearchBeforeCallBack != null)
|
||||
OnSearchBeforeCallBack(sender, args);
|
||||
|
||||
if (args.Continue) this.SearchGrid(false);
|
||||
|
||||
// 查询之后
|
||||
if (OnSearchAfterCallBack != null) OnSearchAfterCallBack(sender, e);
|
||||
}
|
||||
|
||||
|
||||
@@ -6129,15 +6431,7 @@ namespace Lskj.Control.Model
|
||||
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
|
||||
protected void OnFixButtonClick(object sender, EventArgs e)
|
||||
{
|
||||
SearchArgs args = new SearchArgs();
|
||||
// 查询之前
|
||||
if (OnSearchBeforeCallBack != null)
|
||||
OnSearchBeforeCallBack(sender, args);
|
||||
|
||||
if (args.Continue) this.SearchGrid(false);
|
||||
|
||||
// 查询之后
|
||||
if (OnSearchAfterCallBack != null) OnSearchAfterCallBack(sender, e);
|
||||
ExecuteUserSearch(sender, e);
|
||||
}
|
||||
/// <summary>
|
||||
/// <para>说明:高级搜索按钮鼠标离开时</para>
|
||||
@@ -6418,6 +6712,10 @@ namespace Lskj.Control.Model
|
||||
LabelDateEdit dateEdit = controlObj as LabelDateEdit;
|
||||
value = dateEdit.TextEdit.EditValue == null ? dateEdit.EditText : dateEdit.TextEdit.DateTime.ToString("yyyy-MM-dd");
|
||||
}
|
||||
else if (controlObj is LabelTimeEdit)
|
||||
{
|
||||
value = ((LabelTimeEdit)controlObj).EditText;
|
||||
}
|
||||
else if (controlObj is LabelCheckEdit)
|
||||
{
|
||||
LabelCheckEdit checkEdit = controlObj as LabelCheckEdit;
|
||||
@@ -6523,6 +6821,154 @@ namespace Lskj.Control.Model
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!disposing || mDisposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mDisposed = true;
|
||||
mUserSearchInProgress = false;
|
||||
|
||||
Timer timer = mTimer;
|
||||
mTimer = null;
|
||||
if (timer != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
timer.Tick -= mTimerTick;
|
||||
timer.Stop();
|
||||
timer.Dispose();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// A completed delayed-load timer may already be disposed.
|
||||
}
|
||||
}
|
||||
|
||||
if (_button != null)
|
||||
{
|
||||
_button.Click -= OnSimpleButtonClick;
|
||||
_button.Tag = null;
|
||||
}
|
||||
if (_fixButton != null)
|
||||
{
|
||||
_fixButton.Click -= OnFixButtonClick;
|
||||
}
|
||||
if (_refreshButton != null)
|
||||
{
|
||||
_refreshButton.Click -= OnRefreshButtonClick;
|
||||
_refreshButton.Tag = null;
|
||||
}
|
||||
if (btnCondSearch != null)
|
||||
{
|
||||
btnCondSearch.Click -= OnBtnCondSearchClick;
|
||||
btnCondSearch.Tag = null;
|
||||
}
|
||||
if (_dropDown != null)
|
||||
{
|
||||
_dropDown.Leave -= OnDropDownLeave;
|
||||
_dropDown.DropDownControl = null;
|
||||
}
|
||||
foreach (SimpleButton button in mrpBtnDic.Values.Distinct())
|
||||
{
|
||||
if (button != null)
|
||||
{
|
||||
button.Click -= OnModuleClick;
|
||||
button.Tag = null;
|
||||
}
|
||||
}
|
||||
|
||||
BarManager searchSchemeManager =
|
||||
_popupMenu == null ? null : _popupMenu.Manager;
|
||||
if (_popupMenu != null)
|
||||
{
|
||||
_popupMenu.Manager = null;
|
||||
_popupMenu.ItemLinks.Clear();
|
||||
_popupMenu.Dispose();
|
||||
}
|
||||
if (searchSchemeManager != null)
|
||||
{
|
||||
searchSchemeManager.Dispose();
|
||||
}
|
||||
|
||||
if (_mainGridEx != null &&
|
||||
ReferenceEquals(_mainGridEx.ParentControl, this))
|
||||
{
|
||||
_mainGridEx.ParentControl = null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (Model != null && Model.DataCaches != null)
|
||||
{
|
||||
Model.DataCaches.RemoveCache(this);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Cache cleanup must not interrupt module disposal.
|
||||
}
|
||||
|
||||
preSearchVerification = null;
|
||||
OnSearchBeforeCallBack = null;
|
||||
OnSearchAfterCallBack = null;
|
||||
OnAddCallBack = null;
|
||||
ClearDetails = null;
|
||||
OnLastQueryTriggered = null;
|
||||
OnSourceRefrshCallBack = null;
|
||||
OnDataSourceBindCallBack = null;
|
||||
OnDataFileRefrshCallBack = null;
|
||||
OpenDocumentSource = null;
|
||||
|
||||
_calcControls.Clear();
|
||||
_models.Clear();
|
||||
mControlList.Clear();
|
||||
mExtendedReturnSearchControls.Clear();
|
||||
mExtendedReturnPendingChanges.Clear();
|
||||
mControlSourceDic.Clear();
|
||||
mCacheDictionary.Clear();
|
||||
DetailSelection.Clear();
|
||||
changeLabelAutoGridLooks.Clear();
|
||||
mrpBtnDic.Clear();
|
||||
ModuleResultDic.Clear();
|
||||
ParaContrlsDic.Clear();
|
||||
|
||||
_controls = null;
|
||||
_schemes = null;
|
||||
_fixField = null;
|
||||
_fixKey = null;
|
||||
_button = null;
|
||||
_fixButton = null;
|
||||
_refreshButton = null;
|
||||
_dropDown = null;
|
||||
_popupMenu = null;
|
||||
btnCondSearch = null;
|
||||
_gridControl = null;
|
||||
_mainGridEx = null;
|
||||
_gridLeft = null;
|
||||
_tvLeft = null;
|
||||
_leftSearch = null;
|
||||
_parentPanel = null;
|
||||
CurrentData = null;
|
||||
SystemModel = null;
|
||||
SaveCondTab = null;
|
||||
mrpDyncModel = null;
|
||||
Model = null;
|
||||
popUpDyncModel = null;
|
||||
rightItemLinks = null;
|
||||
SpecialLeftTable = null;
|
||||
beforeData = null;
|
||||
OtherParams = null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,11 +7,94 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using WinFormsControl = System.Windows.Forms.Control;
|
||||
|
||||
namespace Lskj.Control.Model
|
||||
{
|
||||
public static class StaticBandedControl
|
||||
{
|
||||
public static void ReleaseModuleReferences(WinFormsControl moduleRoot, XtraTabPage modulePage, string moduleCode)
|
||||
{
|
||||
try
|
||||
{
|
||||
List<BandedGridView> bandedViews = CollectBandedGridViews(moduleRoot);
|
||||
List<GridView> targetViews = CollectTargetGridViews(moduleRoot);
|
||||
foreach (BandedGridView view in bandedViews)
|
||||
BandedGridDragGrid.DisposeRegistrations(
|
||||
BandedGridViewDragGridDic,
|
||||
BandedTargetViewDragGridDic,
|
||||
view,
|
||||
null);
|
||||
foreach (GridView view in targetViews)
|
||||
BandedGridDragGrid.DisposeRegistrations(
|
||||
BandedGridViewDragGridDic,
|
||||
BandedTargetViewDragGridDic,
|
||||
null,
|
||||
view);
|
||||
if (SourceDragBandedGridView != null &&
|
||||
(bandedViews.Contains(SourceDragBandedGridView) ||
|
||||
(SourceDragBandedGridView.GridControl != null && SourceDragBandedGridView.GridControl.IsDisposed)))
|
||||
SourceDragBandedGridView = null;
|
||||
RemoveConditionPanels(moduleCode);
|
||||
while (modulePage != null && DogVerifyModuleForms.Remove(modulePage))
|
||||
{
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine("释放旧 Banded 模块引用失败:" + exception);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<BandedGridView> CollectBandedGridViews(WinFormsControl root)
|
||||
{
|
||||
List<BandedGridView> result = new List<BandedGridView>();
|
||||
if (root == null)
|
||||
return result;
|
||||
foreach (WinFormsControl control in EnumerateControls(root))
|
||||
{
|
||||
DevExpress.XtraGrid.GridControl grid = control as DevExpress.XtraGrid.GridControl;
|
||||
BandedGridView view = grid == null ? null : grid.MainView as BandedGridView;
|
||||
if (view != null && !result.Contains(view))
|
||||
result.Add(view);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static List<GridView> CollectTargetGridViews(WinFormsControl root)
|
||||
{
|
||||
List<GridView> result = new List<GridView>();
|
||||
if (root == null)
|
||||
return result;
|
||||
foreach (WinFormsControl control in EnumerateControls(root))
|
||||
{
|
||||
DevExpress.XtraGrid.GridControl grid = control as DevExpress.XtraGrid.GridControl;
|
||||
GridView view = grid == null ? null : grid.MainView as GridView;
|
||||
if (view != null && !result.Contains(view))
|
||||
result.Add(view);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static IEnumerable<WinFormsControl> EnumerateControls(WinFormsControl root)
|
||||
{
|
||||
yield return root;
|
||||
foreach (WinFormsControl child in root.Controls)
|
||||
foreach (WinFormsControl nested in EnumerateControls(child))
|
||||
yield return nested;
|
||||
}
|
||||
|
||||
private static void RemoveConditionPanels(string moduleCode)
|
||||
{
|
||||
foreach (string key in ConditionsPanelDic.Keys.ToList())
|
||||
{
|
||||
ModuleConditionsPanelEx panel;
|
||||
if (string.Equals(key, moduleCode, StringComparison.OrdinalIgnoreCase) ||
|
||||
!ConditionsPanelDic.TryGetValue(key, out panel) || panel == null || panel.IsDisposed)
|
||||
ConditionsPanelDic.Remove(key);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 记录当前U盾权限窗口
|
||||
/// </summary>
|
||||
@@ -44,4 +127,4 @@ namespace Lskj.Control.Model
|
||||
/// </summary>
|
||||
public static FrmProgressBar frmProgressBar;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,17 +3,215 @@ using DevExpress.XtraTab;
|
||||
using Lskj.Control.ZKFinger;
|
||||
using Lskj.Util;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using Lskj.Model;
|
||||
using System.Reflection;
|
||||
using WinFormsControl = System.Windows.Forms.Control;
|
||||
|
||||
namespace Lskj.Control.Model
|
||||
{
|
||||
public static class StaticControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Releases static references owned by a closed legacy module. Cleanup is
|
||||
/// best-effort so it cannot change the module close result.
|
||||
/// </summary>
|
||||
public static void ReleaseModuleReferences(WinFormsControl moduleRoot, XtraTabPage modulePage, string moduleCode)
|
||||
{
|
||||
List<GridView> gridViews = new List<GridView>();
|
||||
try
|
||||
{
|
||||
gridViews = CollectGridViews(moduleRoot);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
TraceCleanupFailure("收集表格引用", exception);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
foreach (GridView gridView in gridViews)
|
||||
{
|
||||
try
|
||||
{
|
||||
RemoveGridReferences(gridView);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
TraceCleanupFailure("释放表格拖拽引用", exception);
|
||||
}
|
||||
}
|
||||
|
||||
TryCleanup(() => RemoveConditionPanels(moduleCode), "释放条件面板引用");
|
||||
TryCleanup(() => RemoveProtectedReferences(moduleRoot, modulePage), "释放权限保护引用");
|
||||
TryCleanup(() => ClearRightMenuReferences(moduleRoot, gridViews), "释放右键菜单引用");
|
||||
TryCleanup(
|
||||
() => StaticBandedControl.ReleaseModuleReferences(moduleRoot, modulePage, moduleCode),
|
||||
"释放带状表格引用");
|
||||
}
|
||||
finally
|
||||
{
|
||||
// DynamicModel caches retain completed tasks, result tables and
|
||||
// their closures. Always release them after other references.
|
||||
TryCleanup(() => ClearDataCaches(moduleRoot), "释放动态数据缓存");
|
||||
}
|
||||
}
|
||||
|
||||
private static void TryCleanup(Action cleanup, string operation)
|
||||
{
|
||||
try
|
||||
{
|
||||
cleanup();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
TraceCleanupFailure(operation, exception);
|
||||
}
|
||||
}
|
||||
|
||||
private static void TraceCleanupFailure(string operation, Exception exception)
|
||||
{
|
||||
Debug.WriteLine("释放旧模块引用失败[" + operation + "]:" + exception);
|
||||
}
|
||||
|
||||
private static List<GridView> CollectGridViews(WinFormsControl root)
|
||||
{
|
||||
List<GridView> result = new List<GridView>();
|
||||
if (root == null)
|
||||
return result;
|
||||
foreach (WinFormsControl control in EnumerateControls(root))
|
||||
{
|
||||
DevExpress.XtraGrid.GridControl grid = control as DevExpress.XtraGrid.GridControl;
|
||||
GridView view = grid == null ? null : grid.MainView as GridView;
|
||||
if (view != null && !result.Contains(view))
|
||||
result.Add(view);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static IEnumerable<WinFormsControl> EnumerateControls(WinFormsControl root)
|
||||
{
|
||||
yield return root;
|
||||
foreach (WinFormsControl child in root.Controls)
|
||||
foreach (WinFormsControl nested in EnumerateControls(child))
|
||||
yield return nested;
|
||||
}
|
||||
|
||||
private static void RemoveGridReferences(GridView gridView)
|
||||
{
|
||||
GridDragGrid.DisposeRegistrations(GridViewDragGridDic, TargetViewDragGridDic, gridView);
|
||||
if (ReferenceEquals(SourceDragGridView, gridView) ||
|
||||
(SourceDragGridView != null && SourceDragGridView.GridControl != null && SourceDragGridView.GridControl.IsDisposed))
|
||||
SourceDragGridView = null;
|
||||
}
|
||||
|
||||
private static void RemoveConditionPanels(string moduleCode)
|
||||
{
|
||||
foreach (string key in ConditionsPanelDic.Keys.ToList())
|
||||
{
|
||||
ModuleConditionsPanelEx panel;
|
||||
if (string.Equals(key, moduleCode, StringComparison.OrdinalIgnoreCase) ||
|
||||
!ConditionsPanelDic.TryGetValue(key, out panel) || panel == null || panel.IsDisposed)
|
||||
ConditionsPanelDic.Remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
private static void RemoveProtectedReferences(WinFormsControl root, XtraTabPage page)
|
||||
{
|
||||
while (page != null && DogVerifyModuleForms.Remove(page))
|
||||
{
|
||||
}
|
||||
foreach (XtraTabPage item in DogVerifyModuleForms.ToList())
|
||||
if (item == null || item.IsDisposed || IsContained(root, item))
|
||||
DogVerifyModuleForms.Remove(item);
|
||||
foreach (IForm item in DogVerifyNoPageForms.ToList())
|
||||
if (item == null || item.SubForm == null || item.SubForm.IsDisposed || IsContained(root, item.SubForm))
|
||||
DogVerifyNoPageForms.Remove(item);
|
||||
}
|
||||
|
||||
private static bool IsContained(WinFormsControl root, WinFormsControl value)
|
||||
{
|
||||
if (root == null || value == null)
|
||||
return false;
|
||||
if (ReferenceEquals(root, value))
|
||||
return true;
|
||||
foreach (WinFormsControl child in root.Controls)
|
||||
if (IsContained(child, value))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void ClearRightMenuReferences(WinFormsControl root, List<GridView> gridViews)
|
||||
{
|
||||
if (_RightMenuGridView != null && (gridViews.Contains(_RightMenuGridView) ||
|
||||
(_RightMenuGridView.GridControl != null && _RightMenuGridView.GridControl.IsDisposed)))
|
||||
RightMenuGridView = null;
|
||||
if (RightMenuMyControl != null && RightMenuMyControl.MainGridEx != null &&
|
||||
(RightMenuMyControl.MainGridEx.IsDisposed || IsContained(root, RightMenuMyControl.MainGridEx)))
|
||||
RightMenuMyControl = null;
|
||||
if (BomUnionPage != null && (BomUnionPage.IsDisposed || IsContained(root, BomUnionPage)))
|
||||
BomUnionPage = null;
|
||||
if (AddParentGrid.Value != null && (AddParentGrid.Value.IsDisposed || IsContained(root, AddParentGrid.Value)))
|
||||
AddParentGrid = new KeyValuePair<string, GridControlEx>();
|
||||
}
|
||||
|
||||
private static void ClearDataCaches(WinFormsControl root)
|
||||
{
|
||||
if (root == null)
|
||||
return;
|
||||
|
||||
// Clear the root first because child enumeration can fail while a
|
||||
// DevExpress control is disposing its child collection.
|
||||
ClearDynamicModels(root);
|
||||
try
|
||||
{
|
||||
foreach (WinFormsControl control in EnumerateControls(root).Skip(1).ToList())
|
||||
ClearDynamicModels(control);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
TraceCleanupFailure("遍历动态数据缓存", exception);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ClearDynamicModels(object instance)
|
||||
{
|
||||
if (instance == null)
|
||||
return;
|
||||
BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
|
||||
for (Type type = instance.GetType(); type != null; type = type.BaseType)
|
||||
foreach (FieldInfo field in type.GetFields(flags | BindingFlags.DeclaredOnly))
|
||||
try
|
||||
{
|
||||
ClearDynamicModel(field.GetValue(instance));
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Debug.WriteLine("清理动态缓存字段失败:" + exception);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ClearDynamicModel(object value)
|
||||
{
|
||||
DynamicModel model = value as DynamicModel;
|
||||
if (model == null || model.DataCaches == null)
|
||||
return;
|
||||
Dictionary<object, Hashtable> caches = model.DataCaches;
|
||||
foreach (Hashtable cache in caches.Values.OfType<Hashtable>().ToList())
|
||||
{
|
||||
foreach (IDisposable item in cache.Values.OfType<IDisposable>().ToList())
|
||||
try { item.Dispose(); } catch { }
|
||||
cache.Clear();
|
||||
}
|
||||
caches.Clear();
|
||||
model.DataCaches = null;
|
||||
}
|
||||
/// <summary>
|
||||
/// 记录当前U盾权限窗口
|
||||
/// </summary>
|
||||
@@ -84,4 +282,4 @@ namespace Lskj.Control.Model
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,10 +73,23 @@ namespace Lskj.Control.Model
|
||||
/// </summary>
|
||||
public static void HideForm()
|
||||
{
|
||||
bool isSplashFormVisible = LoadForm.IsSplashFormVisible;
|
||||
if (isSplashFormVisible)
|
||||
SplashScreenManager manager = _loadForm;
|
||||
if (manager == null)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
_loadForm.CloseWaitForm();
|
||||
if (manager.IsSplashFormVisible)
|
||||
{
|
||||
manager.CloseWaitForm();
|
||||
manager.WaitForSplashFormClose();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
manager.Dispose();
|
||||
if (ReferenceEquals(_loadForm, manager))
|
||||
_loadForm = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+7
-191
@@ -13,9 +13,13 @@
|
||||
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
if (disposing)
|
||||
{
|
||||
components.Dispose();
|
||||
ReleaseResourcesForDispose();
|
||||
if (components != null)
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
@@ -28,6 +32,7 @@
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this.scc_container = new DevExpress.XtraEditors.SplitContainerControl();
|
||||
this.pl_left = new DevExpress.XtraEditors.PanelControl();
|
||||
this.pl_left_main = new System.Windows.Forms.Panel();
|
||||
@@ -38,25 +43,8 @@
|
||||
this.pl_left_top = new DevExpress.XtraEditors.PanelControl();
|
||||
this.pl_right = new DevExpress.XtraEditors.PanelControl();
|
||||
this.moduleGridDetailEx1 = new Lskj.Control.ModuleGridDetailEx();
|
||||
this.excelControlEx1 = new Lskj.Control.ExcelControlEx();
|
||||
this.repModelDetailEx = new Lskj.Control.ReplacementDetailEx();
|
||||
this.MainBodyTab = new DevExpress.XtraTab.XtraTabControl();
|
||||
this.barManager1 = new DevExpress.XtraBars.BarManager();
|
||||
this.barDockControlTop = new DevExpress.XtraBars.BarDockControl();
|
||||
this.barDockControlBottom = new DevExpress.XtraBars.BarDockControl();
|
||||
this.barDockControlLeft = new DevExpress.XtraBars.BarDockControl();
|
||||
this.barDockControlRight = new DevExpress.XtraBars.BarDockControl();
|
||||
this.commonBar1 = new DevExpress.XtraSpreadsheet.UI.CommonBar();
|
||||
this.spreadsheetCommandBarButtonItem1 = new DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem();
|
||||
this.spreadsheetCommandBarButtonItem2 = new DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem();
|
||||
this.spreadsheetCommandBarButtonItem3 = new DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem();
|
||||
this.spreadsheetCommandBarButtonItem4 = new DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem();
|
||||
this.spreadsheetCommandBarButtonItem5 = new DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem();
|
||||
this.spreadsheetCommandBarButtonItem6 = new DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem();
|
||||
this.spreadsheetCommandBarButtonItem7 = new DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem();
|
||||
this.spreadsheetCommandBarButtonItem8 = new DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem();
|
||||
this.spreadsheetCommandBarButtonItem9 = new DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem();
|
||||
this.spreadsheetBarController1 = new DevExpress.XtraSpreadsheet.UI.SpreadsheetBarController();
|
||||
((System.ComponentModel.ISupportInitialize)(this.scc_container)).BeginInit();
|
||||
this.scc_container.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.pl_left)).BeginInit();
|
||||
@@ -68,8 +56,6 @@
|
||||
((System.ComponentModel.ISupportInitialize)(this.pl_right)).BeginInit();
|
||||
this.pl_right.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.MainBodyTab)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.barManager1)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.spreadsheetBarController1)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// scc_container
|
||||
@@ -172,7 +158,6 @@
|
||||
//
|
||||
this.pl_right.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
|
||||
this.pl_right.Controls.Add(this.moduleGridDetailEx1);
|
||||
this.pl_right.Controls.Add(this.excelControlEx1);
|
||||
this.pl_right.Controls.Add(this.repModelDetailEx);
|
||||
this.pl_right.Controls.Add(this.MainBodyTab);
|
||||
this.pl_right.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
@@ -190,20 +175,6 @@
|
||||
this.moduleGridDetailEx1.TabIndex = 0;
|
||||
this.moduleGridDetailEx1.VisibleDetailPanel = true;
|
||||
//
|
||||
// excelControlEx1
|
||||
//
|
||||
this.excelControlEx1.AddEnabled = true;
|
||||
this.excelControlEx1.DeleteEnabled = true;
|
||||
this.excelControlEx1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.excelControlEx1.Location = new System.Drawing.Point(0, 0);
|
||||
this.excelControlEx1.Margin = new System.Windows.Forms.Padding(6);
|
||||
this.excelControlEx1.Name = "excelControlEx1";
|
||||
this.excelControlEx1.PrintEnabled = true;
|
||||
this.excelControlEx1.SaveEnabled = true;
|
||||
this.excelControlEx1.Size = new System.Drawing.Size(712, 610);
|
||||
this.excelControlEx1.TabIndex = 1;
|
||||
this.excelControlEx1.Visible = false;
|
||||
//
|
||||
// repModelDetailEx
|
||||
//
|
||||
this.repModelDetailEx.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
@@ -224,147 +195,11 @@
|
||||
this.MainBodyTab.TabIndex = 6;
|
||||
this.MainBodyTab.Visible = false;
|
||||
//
|
||||
// barManager1
|
||||
//
|
||||
this.barManager1.DockControls.Add(this.barDockControlTop);
|
||||
this.barManager1.DockControls.Add(this.barDockControlBottom);
|
||||
this.barManager1.DockControls.Add(this.barDockControlLeft);
|
||||
this.barManager1.DockControls.Add(this.barDockControlRight);
|
||||
this.barManager1.Form = this;
|
||||
this.barManager1.MaxItemId = 9;
|
||||
//
|
||||
// barDockControlTop
|
||||
//
|
||||
this.barDockControlTop.CausesValidation = false;
|
||||
this.barDockControlTop.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
this.barDockControlTop.Location = new System.Drawing.Point(0, 0);
|
||||
this.barDockControlTop.Size = new System.Drawing.Size(915, 0);
|
||||
//
|
||||
// barDockControlBottom
|
||||
//
|
||||
this.barDockControlBottom.CausesValidation = false;
|
||||
this.barDockControlBottom.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||
this.barDockControlBottom.Location = new System.Drawing.Point(0, 610);
|
||||
this.barDockControlBottom.Size = new System.Drawing.Size(915, 0);
|
||||
//
|
||||
// barDockControlLeft
|
||||
//
|
||||
this.barDockControlLeft.CausesValidation = false;
|
||||
this.barDockControlLeft.Dock = System.Windows.Forms.DockStyle.Left;
|
||||
this.barDockControlLeft.Location = new System.Drawing.Point(0, 0);
|
||||
this.barDockControlLeft.Size = new System.Drawing.Size(0, 610);
|
||||
//
|
||||
// barDockControlRight
|
||||
//
|
||||
this.barDockControlRight.CausesValidation = false;
|
||||
this.barDockControlRight.Dock = System.Windows.Forms.DockStyle.Right;
|
||||
this.barDockControlRight.Location = new System.Drawing.Point(915, 0);
|
||||
this.barDockControlRight.Size = new System.Drawing.Size(0, 610);
|
||||
//
|
||||
// commonBar1
|
||||
//
|
||||
this.commonBar1.BarName = "";
|
||||
this.commonBar1.Control = null;
|
||||
this.commonBar1.DockCol = 0;
|
||||
this.commonBar1.DockRow = 0;
|
||||
this.commonBar1.FloatLocation = new System.Drawing.Point(339, 195);
|
||||
this.commonBar1.FloatSize = new System.Drawing.Size(244, 31);
|
||||
this.commonBar1.Offset = 44;
|
||||
this.commonBar1.Text = "";
|
||||
//
|
||||
// spreadsheetCommandBarButtonItem1
|
||||
//
|
||||
this.spreadsheetCommandBarButtonItem1.Caption = "New";
|
||||
this.spreadsheetCommandBarButtonItem1.CommandName = "FileNew";
|
||||
this.spreadsheetCommandBarButtonItem1.Enabled = false;
|
||||
this.spreadsheetCommandBarButtonItem1.Id = 8;
|
||||
this.spreadsheetCommandBarButtonItem1.Name = "spreadsheetCommandBarButtonItem1";
|
||||
//
|
||||
// spreadsheetCommandBarButtonItem2
|
||||
//
|
||||
this.spreadsheetCommandBarButtonItem2.Caption = "Open";
|
||||
this.spreadsheetCommandBarButtonItem2.CommandName = "FileOpen";
|
||||
this.spreadsheetCommandBarButtonItem2.Enabled = false;
|
||||
this.spreadsheetCommandBarButtonItem2.Id = 7;
|
||||
this.spreadsheetCommandBarButtonItem2.Name = "spreadsheetCommandBarButtonItem2";
|
||||
//
|
||||
// spreadsheetCommandBarButtonItem3
|
||||
//
|
||||
this.spreadsheetCommandBarButtonItem3.Caption = "Save";
|
||||
this.spreadsheetCommandBarButtonItem3.CommandName = "FileSave";
|
||||
this.spreadsheetCommandBarButtonItem3.Enabled = false;
|
||||
this.spreadsheetCommandBarButtonItem3.Id = 6;
|
||||
this.spreadsheetCommandBarButtonItem3.Name = "spreadsheetCommandBarButtonItem3";
|
||||
//
|
||||
// spreadsheetCommandBarButtonItem4
|
||||
//
|
||||
this.spreadsheetCommandBarButtonItem4.Caption = "Save As";
|
||||
this.spreadsheetCommandBarButtonItem4.CommandName = "FileSaveAs";
|
||||
this.spreadsheetCommandBarButtonItem4.Enabled = false;
|
||||
this.spreadsheetCommandBarButtonItem4.Id = 5;
|
||||
this.spreadsheetCommandBarButtonItem4.Name = "spreadsheetCommandBarButtonItem4";
|
||||
//
|
||||
// spreadsheetCommandBarButtonItem5
|
||||
//
|
||||
this.spreadsheetCommandBarButtonItem5.Caption = "&Quick Print";
|
||||
this.spreadsheetCommandBarButtonItem5.CommandName = "FileQuickPrint";
|
||||
this.spreadsheetCommandBarButtonItem5.Enabled = false;
|
||||
this.spreadsheetCommandBarButtonItem5.Id = 4;
|
||||
this.spreadsheetCommandBarButtonItem5.Name = "spreadsheetCommandBarButtonItem5";
|
||||
//
|
||||
// spreadsheetCommandBarButtonItem6
|
||||
//
|
||||
this.spreadsheetCommandBarButtonItem6.Caption = "&Print";
|
||||
this.spreadsheetCommandBarButtonItem6.CommandName = "FilePrint";
|
||||
this.spreadsheetCommandBarButtonItem6.Enabled = false;
|
||||
this.spreadsheetCommandBarButtonItem6.Id = 3;
|
||||
this.spreadsheetCommandBarButtonItem6.Name = "spreadsheetCommandBarButtonItem6";
|
||||
//
|
||||
// spreadsheetCommandBarButtonItem7
|
||||
//
|
||||
this.spreadsheetCommandBarButtonItem7.Caption = "Print Pre&view";
|
||||
this.spreadsheetCommandBarButtonItem7.CommandName = "FilePrintPreview";
|
||||
this.spreadsheetCommandBarButtonItem7.Enabled = false;
|
||||
this.spreadsheetCommandBarButtonItem7.Id = 2;
|
||||
this.spreadsheetCommandBarButtonItem7.Name = "spreadsheetCommandBarButtonItem7";
|
||||
//
|
||||
// spreadsheetCommandBarButtonItem8
|
||||
//
|
||||
this.spreadsheetCommandBarButtonItem8.Caption = "Undo";
|
||||
this.spreadsheetCommandBarButtonItem8.CommandName = "FileUndo";
|
||||
this.spreadsheetCommandBarButtonItem8.Enabled = false;
|
||||
this.spreadsheetCommandBarButtonItem8.Id = 1;
|
||||
this.spreadsheetCommandBarButtonItem8.Name = "spreadsheetCommandBarButtonItem8";
|
||||
//
|
||||
// spreadsheetCommandBarButtonItem9
|
||||
//
|
||||
this.spreadsheetCommandBarButtonItem9.Caption = "Redo";
|
||||
this.spreadsheetCommandBarButtonItem9.CommandName = "FileRedo";
|
||||
this.spreadsheetCommandBarButtonItem9.Enabled = false;
|
||||
this.spreadsheetCommandBarButtonItem9.Id = 0;
|
||||
this.spreadsheetCommandBarButtonItem9.Name = "spreadsheetCommandBarButtonItem9";
|
||||
//
|
||||
// spreadsheetBarController1
|
||||
//
|
||||
this.spreadsheetBarController1.BarItems.Add(this.spreadsheetCommandBarButtonItem1);
|
||||
this.spreadsheetBarController1.BarItems.Add(this.spreadsheetCommandBarButtonItem2);
|
||||
this.spreadsheetBarController1.BarItems.Add(this.spreadsheetCommandBarButtonItem3);
|
||||
this.spreadsheetBarController1.BarItems.Add(this.spreadsheetCommandBarButtonItem4);
|
||||
this.spreadsheetBarController1.BarItems.Add(this.spreadsheetCommandBarButtonItem5);
|
||||
this.spreadsheetBarController1.BarItems.Add(this.spreadsheetCommandBarButtonItem6);
|
||||
this.spreadsheetBarController1.BarItems.Add(this.spreadsheetCommandBarButtonItem7);
|
||||
this.spreadsheetBarController1.BarItems.Add(this.spreadsheetCommandBarButtonItem8);
|
||||
this.spreadsheetBarController1.BarItems.Add(this.spreadsheetCommandBarButtonItem9);
|
||||
//
|
||||
// ModuleEx
|
||||
//
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
|
||||
this.BackColor = System.Drawing.SystemColors.Control;
|
||||
this.Controls.Add(this.scc_container);
|
||||
this.Controls.Add(this.barDockControlLeft);
|
||||
this.Controls.Add(this.barDockControlRight);
|
||||
this.Controls.Add(this.barDockControlBottom);
|
||||
this.Controls.Add(this.barDockControlTop);
|
||||
this.Name = "ModuleEx";
|
||||
this.Size = new System.Drawing.Size(915, 610);
|
||||
((System.ComponentModel.ISupportInitialize)(this.scc_container)).EndInit();
|
||||
@@ -378,10 +213,7 @@
|
||||
((System.ComponentModel.ISupportInitialize)(this.pl_right)).EndInit();
|
||||
this.pl_right.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this.MainBodyTab)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.barManager1)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.spreadsheetBarController1)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
@@ -389,22 +221,6 @@
|
||||
|
||||
private DevExpress.XtraEditors.SplitContainerControl scc_container;
|
||||
private DevExpress.XtraEditors.PanelControl pl_right;
|
||||
private DevExpress.XtraBars.BarManager barManager1;
|
||||
private DevExpress.XtraBars.BarDockControl barDockControlTop;
|
||||
private DevExpress.XtraBars.BarDockControl barDockControlBottom;
|
||||
private DevExpress.XtraBars.BarDockControl barDockControlLeft;
|
||||
private DevExpress.XtraBars.BarDockControl barDockControlRight;
|
||||
private DevExpress.XtraSpreadsheet.UI.CommonBar commonBar1;
|
||||
private DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem spreadsheetCommandBarButtonItem1;
|
||||
private DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem spreadsheetCommandBarButtonItem2;
|
||||
private DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem spreadsheetCommandBarButtonItem3;
|
||||
private DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem spreadsheetCommandBarButtonItem4;
|
||||
private DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem spreadsheetCommandBarButtonItem5;
|
||||
private DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem spreadsheetCommandBarButtonItem6;
|
||||
private DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem spreadsheetCommandBarButtonItem7;
|
||||
private DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem spreadsheetCommandBarButtonItem8;
|
||||
private DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem spreadsheetCommandBarButtonItem9;
|
||||
private DevExpress.XtraSpreadsheet.UI.SpreadsheetBarController spreadsheetBarController1;
|
||||
private DevExpress.XtraEditors.PanelControl pl_left;
|
||||
private System.Windows.Forms.Panel pl_left_main;
|
||||
private DevExpress.XtraEditors.PanelControl pl_gridandtree_container;
|
||||
|
||||
+319
-38
@@ -31,7 +31,6 @@ using FastReport;
|
||||
using DevExpress.XtraGrid.Views.BandedGrid;
|
||||
using System.Diagnostics;
|
||||
using Lskj.Core;
|
||||
using System.Text.RegularExpressions;
|
||||
using Lskj.Business;
|
||||
using DevExpress.XtraTreeList.Nodes;
|
||||
using DevExpress.XtraTreeList;
|
||||
@@ -63,6 +62,10 @@ namespace Lskj.Control
|
||||
/// 左侧表格查询条件
|
||||
/// </summary>
|
||||
private MyControl _leftGridSearchObj;
|
||||
private GridDragTree _gridDragTree;
|
||||
private bool mModuleResourcesReleased;
|
||||
private GridDragGrid _gridDragGrid;
|
||||
private BandedGridDragGrid _bandedGridDragGrid;
|
||||
|
||||
public bool IsExcel { get { return Model is DynamicExcelModel; } }
|
||||
/// <summary>
|
||||
@@ -151,6 +154,179 @@ namespace Lskj.Control
|
||||
public ModuleEx()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.Disposed += OnModuleExDisposed;
|
||||
}
|
||||
|
||||
public void ReleaseResourcesForDispose()
|
||||
{
|
||||
if (mModuleResourcesReleased)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mModuleResourcesReleased = true;
|
||||
HashSet<ModuleGridDetailEx> details =
|
||||
new HashSet<ModuleGridDetailEx>();
|
||||
HashSet<ModuleGridEx> grids = new HashSet<ModuleGridEx>();
|
||||
foreach (System.Windows.Forms.Control control in
|
||||
EnumerateModuleControls(this))
|
||||
{
|
||||
ModuleGridDetailEx detail = control as ModuleGridDetailEx;
|
||||
if (detail != null)
|
||||
{
|
||||
details.Add(detail);
|
||||
}
|
||||
ModuleGridEx grid = control as ModuleGridEx;
|
||||
if (grid != null)
|
||||
{
|
||||
grids.Add(grid);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (ModuleGridDetailEx detail in details)
|
||||
{
|
||||
detail.ReleaseResourcesForDispose();
|
||||
}
|
||||
foreach (ModuleGridEx grid in grids)
|
||||
{
|
||||
grid.SaveEvent -= SetDetailGridView;
|
||||
grid.OnExportCallBack -= SetExportGridView;
|
||||
grid.ReleaseResourcesForDispose();
|
||||
}
|
||||
|
||||
MyControl leftSearch = _leftGridSearchObj;
|
||||
_leftGridSearchObj = null;
|
||||
if (leftSearch != null)
|
||||
{
|
||||
leftSearch.OnDataSourceBindCallBack -= OnLeftControlObjDataSourceBindCallBack;
|
||||
leftSearch.Dispose();
|
||||
}
|
||||
|
||||
GridDragTree dragTree = _gridDragTree;
|
||||
_gridDragTree = null;
|
||||
if (dragTree != null)
|
||||
{
|
||||
dragTree.OnDragComplete -= OnDragTreeCompleted;
|
||||
dragTree.Dispose();
|
||||
}
|
||||
|
||||
GridDragGrid dragGrid = _gridDragGrid;
|
||||
_gridDragGrid = null;
|
||||
if (dragGrid != null)
|
||||
{
|
||||
dragGrid.OnDragComplete -= OnDragGridCompleted;
|
||||
dragGrid.Dispose();
|
||||
}
|
||||
|
||||
BandedGridDragGrid bandedDragGrid = _bandedGridDragGrid;
|
||||
_bandedGridDragGrid = null;
|
||||
if (bandedDragGrid != null)
|
||||
{
|
||||
bandedDragGrid.OnDragComplete -= OnDragBandedGridCompleted;
|
||||
bandedDragGrid.Dispose();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (treeLeft != null)
|
||||
{
|
||||
treeLeft.TreeNodeSelectAfter -= OnTreeLeftTreeNodeSelected;
|
||||
treeLeft.OnTreeNodeMouseDoubleClick -= TreeLeft_OnTreeNodeMouseDoubleClick;
|
||||
}
|
||||
if (gridLeft != null && gridLeft.GridView != null)
|
||||
{
|
||||
gridLeft.GridView.RowClick -= OnGridViewRowClick;
|
||||
}
|
||||
if (treeGridLeft != null && treeGridLeft.TreeListObj != null)
|
||||
{
|
||||
treeGridLeft.TreeListObj.Click -= TreeListObj_Click;
|
||||
treeGridLeft.TreeListObj.BeforeExpand -= TreeListObj_BeforeExpand;
|
||||
treeGridLeft.TreeListObj.BeforeCollapse -= TreeListObj_BeforeCollapse;
|
||||
}
|
||||
if (MainBodyTab != null)
|
||||
{
|
||||
MainBodyTab.SelectedPageChanged -= MainBodyTab_SelectedPageChanged;
|
||||
}
|
||||
if (excelControlEx1 != null)
|
||||
{
|
||||
excelControlEx1.SaveCallBack -= OnExcelSaveClick;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// A partially disposed child control must not stop cleanup.
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (Model != null && Model.DataCaches != null)
|
||||
{
|
||||
Model.DataCaches.RemoveCache(this);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Cache cleanup must not interrupt module disposal.
|
||||
}
|
||||
|
||||
OnLeftGridViewRowClickCallBack = null;
|
||||
OnLeftTreeViewRowClickCallBack = null;
|
||||
if (Details != null)
|
||||
{
|
||||
Details.Clear();
|
||||
}
|
||||
LeftRowObj = null;
|
||||
ColumnNameTable = null;
|
||||
_currentRow = null;
|
||||
ExcelControlObj = null;
|
||||
Model = null;
|
||||
SysModel = null;
|
||||
}
|
||||
|
||||
private static IEnumerable<System.Windows.Forms.Control>
|
||||
EnumerateModuleControls(System.Windows.Forms.Control parent)
|
||||
{
|
||||
if (parent == null)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
foreach (System.Windows.Forms.Control child in parent.Controls)
|
||||
{
|
||||
yield return child;
|
||||
foreach (System.Windows.Forms.Control nested in
|
||||
EnumerateModuleControls(child))
|
||||
{
|
||||
yield return nested;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Excel 控件包含 SpreadsheetControl、BarManager 和命令注册项,
|
||||
/// 普通表格模块不应在设计器初始化阶段创建这些重型资源。
|
||||
/// </summary>
|
||||
private ExcelControlEx EnsureExcelControl()
|
||||
{
|
||||
if (this.excelControlEx1 != null && !this.excelControlEx1.IsDisposed)
|
||||
{
|
||||
return this.excelControlEx1;
|
||||
}
|
||||
|
||||
this.excelControlEx1 = new ExcelControlEx
|
||||
{
|
||||
AddEnabled = true,
|
||||
DeleteEnabled = true,
|
||||
Dock = DockStyle.Fill,
|
||||
Margin = new Padding(6),
|
||||
Name = "excelControlEx1",
|
||||
PrintEnabled = true,
|
||||
SaveEnabled = true,
|
||||
TabIndex = 1,
|
||||
Visible = false
|
||||
};
|
||||
this.pl_right.Controls.Add(this.excelControlEx1);
|
||||
this.ExcelControlObj = this.excelControlEx1;
|
||||
return this.excelControlEx1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -222,9 +398,14 @@ namespace Lskj.Control
|
||||
if (Model.HasOperPrivilege() && model.IsBaseModule)
|
||||
{
|
||||
// 有权限则允许拖拽
|
||||
GridDragTree dragTree = new GridDragTree(this.ModuleGridObj.GridControlObj.GridView, this.treeLeft.TreeView);
|
||||
dragTree.CanDragParentNode = true;
|
||||
dragTree.OnDragComplete += new GridDragTreeCompleteEventHandler(OnDragTreeCompleted);
|
||||
if (_gridDragTree != null)
|
||||
{
|
||||
_gridDragTree.OnDragComplete -= OnDragTreeCompleted;
|
||||
_gridDragTree.Dispose();
|
||||
}
|
||||
_gridDragTree = new GridDragTree(this.ModuleGridObj.GridControlObj.GridView, this.treeLeft.TreeView);
|
||||
_gridDragTree.CanDragParentNode = true;
|
||||
_gridDragTree.OnDragComplete += new GridDragTreeCompleteEventHandler(OnDragTreeCompleted);
|
||||
}
|
||||
if (this.SysModel.TreeDoubleClick)
|
||||
{
|
||||
@@ -271,10 +452,11 @@ namespace Lskj.Control
|
||||
if (Model.HasOperPrivilege() && model.IsBaseModule && !this.SysModel.IsTreeTable)
|
||||
{
|
||||
// 有权限则允许拖拽
|
||||
GridDragGrid dragGrid = new GridDragGrid(this.ModuleGridObj.GridControlObj.GridView, this.gridLeft.GridView);
|
||||
dragGrid.OnDragComplete += new GridFragGridCompleteEventHandler(OnDragGridCompleted);
|
||||
_gridDragGrid?.Dispose();
|
||||
_gridDragGrid = new GridDragGrid(this.ModuleGridObj.GridControlObj.GridView, this.gridLeft.GridView);
|
||||
_gridDragGrid.OnDragComplete += new GridFragGridCompleteEventHandler(OnDragGridCompleted);
|
||||
//配置了拖拽条件后,在点击时判断条件
|
||||
dragGrid.DragConditions = this.SysModel.DragConditions;
|
||||
_gridDragGrid.DragConditions = this.SysModel.DragConditions;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -285,20 +467,22 @@ namespace Lskj.Control
|
||||
}
|
||||
if (this.IsExcel)
|
||||
{
|
||||
//由于创建对象时候要注册,所以动态构造这控件不在设计器进行否则表格模式也会弹出注册
|
||||
// 只有 Excel 模式才创建 Spreadsheet/Bar 相关资源。
|
||||
ExcelControlEx excelControl = EnsureExcelControl();
|
||||
this.ModuleGridDetailObj.Visible = false;
|
||||
this.repModelDetailEx.Visible = false;
|
||||
this.excelControlEx1.Visible = true;
|
||||
excelControl.Visible = true;
|
||||
excelControl.BringToFront();
|
||||
if (!Model.DataCaches.GetValue(this, "BasePrimaryKey", out SysModel.ParmaryKey))
|
||||
{
|
||||
SysModel.ParmaryKey = BaseImpl.GetBasePrimaryKey(this.Model.ModuleCode);
|
||||
}
|
||||
this.excelControlEx1.AddEnabled = this.SysModel.AddEnable;
|
||||
this.excelControlEx1.DeleteEnabled = this.SysModel.DeleteEnable;
|
||||
this.excelControlEx1.PrintEnabled = !string.IsNullOrWhiteSpace(this.SysModel.PrintFile);
|
||||
this.excelControlEx1.SaveEnabled = this.SysModel.ModifyEnable;
|
||||
this.excelControlEx1.CreateFile();
|
||||
this.excelControlEx1.SaveCallBack += new EventHandler(OnExcelSaveClick);
|
||||
excelControl.AddEnabled = this.SysModel.AddEnable;
|
||||
excelControl.DeleteEnabled = this.SysModel.DeleteEnable;
|
||||
excelControl.PrintEnabled = !string.IsNullOrWhiteSpace(this.SysModel.PrintFile);
|
||||
excelControl.SaveEnabled = this.SysModel.ModifyEnable;
|
||||
excelControl.CreateFile();
|
||||
excelControl.SaveCallBack += new EventHandler(OnExcelSaveClick);
|
||||
if (!Model.DataCaches.GetValue(this, "BaseGridColumns", out DataTable dtGridColumns))
|
||||
{
|
||||
dtGridColumns = BaseModuleImpl.GetBaseGridColumns(this.Model.ModuleCode);
|
||||
@@ -315,8 +499,10 @@ namespace Lskj.Control
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
this.excelControlEx1.Visible = false;
|
||||
if (this.excelControlEx1 != null)
|
||||
{
|
||||
this.excelControlEx1.Visible = false;
|
||||
}
|
||||
if (SysModel.isReplacMainDetail == "1")
|
||||
{
|
||||
this.ModuleGridDetailObj.Visible = false;
|
||||
@@ -343,8 +529,9 @@ namespace Lskj.Control
|
||||
if (Model.HasOperPrivilege() && model.IsBaseModule && !this.SysModel.IsTreeTable && this.ModuleGridObj.GridControlObj.GridView is BandedGridView&&(this.SysModel.MenuType==2 || this.SysModel.MenuType==5))
|
||||
{
|
||||
// 有权限则允许拖拽
|
||||
BandedGridDragGrid BandedDragGrid = new BandedGridDragGrid(this.ModuleGridObj.GridControlObj.GridView as BandedGridView, this.gridLeft.GridView);
|
||||
BandedDragGrid.OnDragComplete += new BandedGridFragGridCompleteEventHandler(OnDragBandedGridCompleted);
|
||||
_bandedGridDragGrid?.Dispose();
|
||||
_bandedGridDragGrid = new BandedGridDragGrid(this.ModuleGridObj.GridControlObj.GridView as BandedGridView, this.gridLeft.GridView);
|
||||
_bandedGridDragGrid.OnDragComplete += new BandedGridFragGridCompleteEventHandler(OnDragBandedGridCompleted);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -446,7 +633,6 @@ namespace Lskj.Control
|
||||
{
|
||||
case 1:
|
||||
case 4://左侧为树节点
|
||||
this.ModuleGridObj.LeftTreeViewEx = this.treeLeft;
|
||||
Task<DataRow> baseLeftTreeFieldTask = cachesDic.AddTask(this, "BaseLeftTreeField", new Task<DataRow>(() =>
|
||||
{
|
||||
return BaseModuleImpl.GetBaseLeftTreeField(dynamicModel.ModuleCode);//获取表格左侧树字段
|
||||
@@ -500,12 +686,7 @@ namespace Lskj.Control
|
||||
DataTable customQueryFieldsTab = customQueryFieldsTask.Result;
|
||||
if (customQueryFieldsTab != null && customQueryFieldsTab.Rows.Count > 0)
|
||||
{
|
||||
Task<MyControl> leftGridSearchObjTask = cachesDic.AddTask(this, "LeftGridSearchObj", new Task<MyControl>(() =>
|
||||
{
|
||||
string searchSql = baseLeftTreeFieldTask.Result["fieldsql"] + "";
|
||||
return new MyControl(searchSql, sysModel.IsTreeTable ? this.treeGridLeft as GridControlEx : this.gridLeft);
|
||||
}));
|
||||
ModuleGridDetailObj._leftGridSearchObj = leftGridSearchObjTask.Result;
|
||||
// MyControl 必须由后续 UI 初始化阶段创建。
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -527,7 +708,7 @@ namespace Lskj.Control
|
||||
Task<DataTable> customColumnByDatabaseTask = cachesDic.AddTask(gridLeft, "CustomColumnByDatabase", new Task<DataTable>(() =>
|
||||
{
|
||||
string customColumKey = GridCustomColumnStruct.BaseLeftGridView + dynamicModel.ModuleCode;
|
||||
return gridLeft.GridView.GetCustomColumnByDatabase(customColumKey);
|
||||
return GridExtend.GetCustomColumnByDatabase(customColumKey);
|
||||
}));
|
||||
}
|
||||
else
|
||||
@@ -535,12 +716,11 @@ namespace Lskj.Control
|
||||
Task<DataTable> customColumnByDatabaseTask = cachesDic.AddTask(treeGridLeft, "CustomColumnByDatabase", new Task<DataTable>(() =>
|
||||
{
|
||||
string customColumKey = GridCustomColumnStruct.BaseLeftGridView + dynamicModel.ModuleCode;
|
||||
return treeGridLeft.GridView.GetCustomColumnByDatabase(customColumKey);
|
||||
return GridExtend.GetCustomColumnByDatabase(customColumKey);
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
ModuleGridObj.LeftGridEx = sysModel.IsTreeTable ? this.treeGridLeft : this.gridLeft;
|
||||
break;
|
||||
}
|
||||
if (dynamicModel is DynamicExcelModel)//isExcel
|
||||
@@ -680,8 +860,35 @@ namespace Lskj.Control
|
||||
// this.ModuleGridObj.InitlizeSpiltLocation();
|
||||
//}
|
||||
this.ModuleGridObj.SearchObj.SearchGrid(sqlValue);
|
||||
if (!this.IsDragDetail)
|
||||
this.ModuleGridDetailObj.SetDetailGridDataSource();
|
||||
if (!this.IsDragDetail)
|
||||
{
|
||||
bool enter = false;
|
||||
|
||||
try
|
||||
{
|
||||
if (this.ModuleGridObj != null)
|
||||
{
|
||||
DataRow rowItem = this.ModuleGridObj.GridControlObj.GetViewFocusedDataRow();
|
||||
if (this.ModuleGridObj.GridControlObj.CustomGroupSelectedRow != null)
|
||||
{
|
||||
rowItem = this.ModuleGridObj.GridControlObj.CustomGroupSelectedRow;
|
||||
}
|
||||
if (rowItem != null&& !this.SysModel.DoubleClickDetail) enter = true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
}
|
||||
//enter判断 2026-7-24 添加 因为主表有行改版后事件,主表赋值后会刷新一次,这里是重复刷新(方法里有判断,主表有值执行的逻辑是相同的)
|
||||
//如果是主表有数据,并且绑定了行改变事件,就执行了(重复执行)
|
||||
//如果主表没有数据,就执行(清空明细) 或者绑定的是双击加载明细事件也执行(节点改变后刷新主表,顺便刷新明细)
|
||||
if (!enter)
|
||||
{
|
||||
this.ModuleGridDetailObj.SetDetailGridDataSource();
|
||||
}
|
||||
}
|
||||
|
||||
if (this.treeGridLeft.Visible && ModuleGridDetailObj.GridDetailList != null && ModuleGridDetailObj.GridDetailList.Count > 0)
|
||||
{
|
||||
this.ModuleGridDetailObj.scc_container.PanelVisibility = this.ModuleGridObj.GridControlObj.DataRowCount() == 0 ? SplitPanelVisibility.Panel1 : SplitPanelVisibility.Both;
|
||||
@@ -1851,16 +2058,81 @@ namespace Lskj.Control
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断是否是selete开头(可以处理sql前方有注释和空格的情况)
|
||||
/// 判断有效SQL是否以select开头(忽略前方空格、BOM和注释)
|
||||
/// </summary>
|
||||
/// <param name="sqlText"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsSelectAtStart(string sqlText)
|
||||
{
|
||||
// Remove comments and whitespace at the start of the text
|
||||
string cleanedText = Regex.Replace(sqlText, @"^(\s*--.*?(\r\n|\n)|\s*)*", "");
|
||||
// Check if the remaining text starts with 'select'
|
||||
return cleanedText.StartsWith("select", StringComparison.OrdinalIgnoreCase);
|
||||
if (string.IsNullOrEmpty(sqlText))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
while (index < sqlText.Length)
|
||||
{
|
||||
while (index < sqlText.Length &&
|
||||
(char.IsWhiteSpace(sqlText[index]) || sqlText[index] == '\uFEFF'))
|
||||
{
|
||||
index++;
|
||||
}
|
||||
|
||||
// 跳过SQL开头连续出现的单行注释。
|
||||
if (index + 1 < sqlText.Length && sqlText[index] == '-' && sqlText[index + 1] == '-')
|
||||
{
|
||||
index += 2;
|
||||
while (index < sqlText.Length && sqlText[index] != '\r' && sqlText[index] != '\n')
|
||||
{
|
||||
index++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// 跳过块注释,同时兼容SQL Server支持的嵌套块注释。
|
||||
if (index + 1 < sqlText.Length && sqlText[index] == '/' && sqlText[index + 1] == '*')
|
||||
{
|
||||
index += 2;
|
||||
int commentDepth = 1;
|
||||
while (index < sqlText.Length && commentDepth > 0)
|
||||
{
|
||||
if (index + 1 < sqlText.Length && sqlText[index] == '/' && sqlText[index + 1] == '*')
|
||||
{
|
||||
commentDepth++;
|
||||
index += 2;
|
||||
}
|
||||
else if (index + 1 < sqlText.Length && sqlText[index] == '*' && sqlText[index + 1] == '/')
|
||||
{
|
||||
commentDepth--;
|
||||
index += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
if (commentDepth > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
const string selectKeyword = "select";
|
||||
if (index + selectKeyword.Length > sqlText.Length ||
|
||||
string.Compare(sqlText, index, selectKeyword, 0, selectKeyword.Length,
|
||||
StringComparison.OrdinalIgnoreCase) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int nextIndex = index + selectKeyword.Length;
|
||||
return nextIndex == sqlText.Length ||
|
||||
(!char.IsLetterOrDigit(sqlText[nextIndex]) && sqlText[nextIndex] != '_');
|
||||
}
|
||||
|
||||
|
||||
@@ -1876,6 +2148,15 @@ namespace Lskj.Control
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 控件销毁后释放拖拽辅助对象;关闭被取消时不会触发,不影响模块继续使用。
|
||||
/// </summary>
|
||||
private void OnModuleExDisposed(object sender, EventArgs e)
|
||||
{
|
||||
this.Disposed -= OnModuleExDisposed;
|
||||
ReleaseResourcesForDispose();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 初始化页签
|
||||
@@ -1990,7 +2271,7 @@ namespace Lskj.Control
|
||||
{
|
||||
if (this.gridLeft.Visible) this.OnGridViewRowClick(null, null);
|
||||
if (this.treeGridLeft.Visible) this.TreeListObj_Click(null, null);
|
||||
if (this.treeLeft.Visible)
|
||||
if (this.treeLeft.Visible&& this.treeLeft.TreeView.SelectedNode!=null)
|
||||
{
|
||||
TreeViewEventArgs treeViewEventArgs = new TreeViewEventArgs(this.treeLeft.TreeView.SelectedNode);
|
||||
this.OnTreeLeftTreeNodeSelected(null, treeViewEventArgs);
|
||||
@@ -2000,4 +2281,4 @@ namespace Lskj.Control
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-2
@@ -13,9 +13,13 @@
|
||||
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
if (disposing)
|
||||
{
|
||||
components.Dispose();
|
||||
ReleaseResourcesForDispose();
|
||||
if (components != null)
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@ namespace Lskj.Control
|
||||
/// </summary>
|
||||
public partial class ModuleGridDetailEx : UserControl
|
||||
{
|
||||
private bool mModuleResourcesReleased;
|
||||
private bool mDetailPageCachesPrepared;
|
||||
|
||||
/// <summary>
|
||||
/// 系统模块实体对象
|
||||
@@ -147,6 +149,68 @@ namespace Lskj.Control
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
internal void ReleaseResourcesForDispose()
|
||||
{
|
||||
if (mModuleResourcesReleased)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mModuleResourcesReleased = true;
|
||||
MyControl searchObj = SearchObj;
|
||||
if (searchObj != null)
|
||||
{
|
||||
searchObj.OnSearchAfterCallBack -= SearchObj_ClearDetails_DoubleMode;
|
||||
searchObj.OnLastQueryTriggered -= SearchObj_ClearDetails_DoubleMode;
|
||||
searchObj.OnSearchAfterCallBack -= SearchObj_ClearDetails;
|
||||
searchObj.OnLastQueryTriggered -= SearchObj_ClearDetails;
|
||||
}
|
||||
|
||||
if (ModuleGridObj != null)
|
||||
{
|
||||
ModuleGridObj.AfterRefreshingCallBack -= ModuleGridObj_AfterRefreshingCallBack;
|
||||
try
|
||||
{
|
||||
GridControlEx grid = ModuleGridObj.GridControlObj;
|
||||
if (grid != null && grid.GridView != null)
|
||||
{
|
||||
grid.GridView.DoubleClick -= GridView_DoubleClick;
|
||||
grid.GridView.DoubleClick -= OnGridViewDoubleClick;
|
||||
grid.GridView.Click -= OnGridViewDoubleClick;
|
||||
grid.GridView.MouseDown -= GridView_MouseDown;
|
||||
grid.GridView.FocusedRowObjectChanged -= OnGridViewFocusedRowObjectChanged;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// A partially disposed DevExpress view must not stop cleanup.
|
||||
}
|
||||
ModuleGridObj.ReleaseResourcesForDispose();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (Model != null && Model.DataCaches != null)
|
||||
{
|
||||
Model.DataCaches.RemoveCache(this);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Cache cleanup must not interrupt control disposal.
|
||||
}
|
||||
|
||||
OnGridViewRowClickCallBack = null;
|
||||
if (GridDetailList != null)
|
||||
{
|
||||
GridDetailList.Clear();
|
||||
}
|
||||
datamodel.Clear();
|
||||
_leftGridSearchObj = null;
|
||||
Model = null;
|
||||
SysModel = null;
|
||||
}
|
||||
/// <summary>
|
||||
/// <para>说明:初始化控件</para>
|
||||
/// <para>创建人:龚宇超</para>
|
||||
@@ -189,6 +253,7 @@ namespace Lskj.Control
|
||||
}
|
||||
else
|
||||
{
|
||||
PrepareDetailPageCaches(dataCaches);
|
||||
// 初始化底部多标签
|
||||
this.InitializePages();
|
||||
}
|
||||
@@ -220,7 +285,6 @@ namespace Lskj.Control
|
||||
//获取通用数据
|
||||
Task<ModuleModel> sysModelTask = cachesDic.GetTask<ModuleModel>(this, "SysModel");
|
||||
Task<DynamicModel> dynamicModelTask = cachesDic.GetTask<DynamicModel>(this, "DynamicModel");
|
||||
Task<List<GridDetailModel>> detailsTask = cachesDic.GetTask<List<GridDetailModel>>(this, "Details");
|
||||
ModuleGridObj._leftGridSearchObj = _leftGridSearchObj;
|
||||
Task<bool> getDataCachesTask = cachesDic.AddTask(this, "DataCaches", new Task<bool>(() =>
|
||||
{
|
||||
@@ -231,23 +295,42 @@ namespace Lskj.Control
|
||||
cachesDic.AddTask(ModuleGridObj, "DynamicModel", dynamicModelTask);
|
||||
cachesDic.AddTask(ModuleGridObj, "SysModel", sysModelTask);
|
||||
this.ModuleGridObj.GetDataCaches(cachesDic);
|
||||
if (!string.IsNullOrEmpty(sysModel.MainModuleCodeField) && this.ModuleGridObj.GridControlObj.GridView.Columns.ColumnByFieldName(sysModel.MainModuleCodeField) != null)
|
||||
// 下方模块都使用当前主表的主键,共享主表已经创建的查询任务,避免每个明细重复查询。
|
||||
Task<string> parentPrimaryKeyTask = cachesDic.GetTask<string>(ModuleGridObj, "BasePrimaryKey");
|
||||
if (parentPrimaryKeyTask != null)
|
||||
{
|
||||
//InitializeDynamicPages();
|
||||
}
|
||||
else
|
||||
{
|
||||
//添加数据到mControl
|
||||
cachesDic.AddTask(tcButtom, "DynamicModel", dynamicModelTask);
|
||||
cachesDic.AddTask(tcButtom, "Details", detailsTask);
|
||||
// 初始化底部多标签
|
||||
this.tcButtom.GetDataCaches(cachesDic);
|
||||
cachesDic.AddTask(tcButtom, "ParentPrimaryKey", parentPrimaryKeyTask);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}));
|
||||
}
|
||||
|
||||
private void PrepareDetailPageCaches(
|
||||
Dictionary<object, Hashtable> cachesDic)
|
||||
{
|
||||
if (mDetailPageCachesPrepared || cachesDic == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Task<DynamicModel> dynamicModelTask =
|
||||
cachesDic.GetTask<DynamicModel>(this, "DynamicModel");
|
||||
Task<List<GridDetailModel>> detailsTask =
|
||||
cachesDic.GetTask<List<GridDetailModel>>(this, "Details");
|
||||
|
||||
// 未启用预加载缓存时,InitializePages 会按原有同步方式创建明细页签。
|
||||
if (dynamicModelTask == null || detailsTask == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mDetailPageCachesPrepared = true;
|
||||
cachesDic.AddTask(tcButtom, "DynamicModel", dynamicModelTask);
|
||||
cachesDic.AddTask(tcButtom, "Details", detailsTask);
|
||||
this.tcButtom.GetDataCaches(cachesDic);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// <para>说明:初始化底部多标签数据</para>
|
||||
@@ -707,6 +790,13 @@ namespace Lskj.Control
|
||||
}
|
||||
}
|
||||
|
||||
if (model!=null&& !string.IsNullOrWhiteSpace(model.VisibleCond))
|
||||
{
|
||||
tabPage.PageVisible = !ValidateCond(model.VisibleCond, rowItem);
|
||||
if (!tabPage.PageVisible) return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (IsDynamicDetailType)
|
||||
{
|
||||
@@ -1464,9 +1554,48 @@ namespace Lskj.Control
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// <para>说明:检查可用条件</para>
|
||||
/// <para>创建人:龚宇超</para>
|
||||
/// <para>创建日期:2017-11-09 </para>
|
||||
/// <para>修改人:</para>
|
||||
/// <para>修改日期:</para>
|
||||
/// <para>修改备注:</para>
|
||||
/// <para>版本:1.0</para>
|
||||
/// </summary>
|
||||
/// <param name="cond">The cond.</param>
|
||||
/// <param name="dataRow">The data row.</param>
|
||||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
|
||||
private bool ValidateCond(string cond, DataRow dataRow)
|
||||
{
|
||||
bool result = false;
|
||||
string condition = cond;
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(cond)) return true;//如果值是空格或者空行,默认正确
|
||||
cond = ReplaceHelper.ReplaceRowParamEmptyWrapQuote(dataRow, cond);
|
||||
if (cond.StartsWith("@") || cond.StartsWith("!"))
|
||||
{
|
||||
result = "1".Equals(BaseImpl.GetDefaultValue(cond));
|
||||
}
|
||||
else if (dataRow == null)
|
||||
{
|
||||
result = ReplaceHelper.EvalCond(cond);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = ReplaceHelper.ReplaceRowParamCond(dataRow, cond);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+16
-10
@@ -13,9 +13,15 @@
|
||||
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
if (disposing)
|
||||
{
|
||||
components.Dispose();
|
||||
ReleaseResourcesForDispose();
|
||||
Lskj.Control.Model.PrintUtil.OnAfterPrint -=
|
||||
new System.EventHandler(OnReportPrintAfter);
|
||||
if (components != null)
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
@@ -337,7 +343,7 @@
|
||||
this.btnFixSearch.Name = "btnFixSearch";
|
||||
this.btnFixSearch.Size = new System.Drawing.Size(63, 24);
|
||||
this.btnFixSearch.TabIndex = 33;
|
||||
this.btnFixSearch.Text = "查询(&Q)";
|
||||
this.btnFixSearch.Text = "查询(Q)";
|
||||
//
|
||||
// txtFixKey
|
||||
//
|
||||
@@ -433,7 +439,7 @@
|
||||
this.btnSave.Name = "btnSave";
|
||||
this.btnSave.Size = new System.Drawing.Size(72, 26);
|
||||
this.btnSave.TabIndex = 37;
|
||||
this.btnSave.Text = "保存(&S)";
|
||||
this.btnSave.Text = "保存(S)";
|
||||
this.btnSave.Click += new System.EventHandler(this.OnSaveClick);
|
||||
//
|
||||
// btnUpdate
|
||||
@@ -445,7 +451,7 @@
|
||||
this.btnUpdate.Name = "btnUpdate";
|
||||
this.btnUpdate.Size = new System.Drawing.Size(72, 26);
|
||||
this.btnUpdate.TabIndex = 38;
|
||||
this.btnUpdate.Text = "修改(&U)";
|
||||
this.btnUpdate.Text = "修改(U)";
|
||||
this.btnUpdate.Visible = false;
|
||||
this.btnUpdate.Click += new System.EventHandler(this.OnUpdateClick);
|
||||
//
|
||||
@@ -458,7 +464,7 @@
|
||||
this.btnPrint.Name = "btnPrint";
|
||||
this.btnPrint.Size = new System.Drawing.Size(72, 26);
|
||||
this.btnPrint.TabIndex = 37;
|
||||
this.btnPrint.Text = "打印(&P)";
|
||||
this.btnPrint.Text = "打印(P)";
|
||||
this.btnPrint.Visible = false;
|
||||
this.btnPrint.Click += new System.EventHandler(this.OnPrintClick);
|
||||
//
|
||||
@@ -471,7 +477,7 @@
|
||||
this.btnExport.Name = "btnExport";
|
||||
this.btnExport.Size = new System.Drawing.Size(72, 26);
|
||||
this.btnExport.TabIndex = 37;
|
||||
this.btnExport.Text = "导出(&E)";
|
||||
this.btnExport.Text = "导出(E)";
|
||||
this.btnExport.Visible = false;
|
||||
this.btnExport.Click += new System.EventHandler(this.OnExportClick);
|
||||
//
|
||||
@@ -484,7 +490,7 @@
|
||||
this.btnImport.Name = "btnImport";
|
||||
this.btnImport.Size = new System.Drawing.Size(72, 26);
|
||||
this.btnImport.TabIndex = 37;
|
||||
this.btnImport.Text = "导入(&I)";
|
||||
this.btnImport.Text = "导入(I)";
|
||||
this.btnImport.Visible = false;
|
||||
this.btnImport.Click += new System.EventHandler(this.OnImportClick);
|
||||
//
|
||||
@@ -497,7 +503,7 @@
|
||||
this.btnDel.Name = "btnDel";
|
||||
this.btnDel.Size = new System.Drawing.Size(72, 26);
|
||||
this.btnDel.TabIndex = 36;
|
||||
this.btnDel.Text = "删除(&D)";
|
||||
this.btnDel.Text = "删除(D)";
|
||||
this.btnDel.Click += new System.EventHandler(this.OnDelClick);
|
||||
//
|
||||
// btnAdd
|
||||
@@ -509,7 +515,7 @@
|
||||
this.btnAdd.Name = "btnAdd";
|
||||
this.btnAdd.Size = new System.Drawing.Size(72, 26);
|
||||
this.btnAdd.TabIndex = 35;
|
||||
this.btnAdd.Text = "增加(&A)";
|
||||
this.btnAdd.Text = "增加(A)";
|
||||
this.btnAdd.Click += new System.EventHandler(this.OnAddClick);
|
||||
//
|
||||
// ModuleGridEx
|
||||
|
||||
@@ -53,6 +53,9 @@ namespace Lskj.Control
|
||||
/// </summary>
|
||||
public partial class ModuleGridEx : UserControl
|
||||
{
|
||||
private readonly AltButtonShortcutManager mAltButtonShortcuts =
|
||||
new AltButtonShortcutManager();
|
||||
|
||||
#region private property
|
||||
|
||||
/// <summary>
|
||||
@@ -77,6 +80,10 @@ namespace Lskj.Control
|
||||
/// </summary>
|
||||
private bool _visibleMrpSearchPanel;
|
||||
/// <summary>
|
||||
/// 外部已查询的MRP操作按钮数据,供搜索区域复用。
|
||||
/// </summary>
|
||||
public DataTable MrpClickMenus;
|
||||
/// <summary>
|
||||
/// 底部操作按钮是否显示简短模式,默认为简短模式
|
||||
/// </summary>
|
||||
private bool _operShortMode = true;
|
||||
@@ -424,6 +431,7 @@ namespace Lskj.Control
|
||||
/// 自定义查询条件
|
||||
/// </summary>
|
||||
public MyControl SearchObj { get; private set; }
|
||||
private bool mModuleResourcesReleased;
|
||||
/// <summary>
|
||||
/// 左查询条件
|
||||
/// </summary>
|
||||
@@ -516,8 +524,29 @@ namespace Lskj.Control
|
||||
searchObj = new MyControl(ReplaceBmpField(this.SysModel.MenuSql), gcMain, LeftTreeViewEx, LeftGridEx, _leftGridSearchObj);//替换sql语句中的bmp字段
|
||||
searchObj.SpecialLeftTable = this.SpecialLeftTable;
|
||||
searchObj.Model = Model;
|
||||
if (!fixedQuery && Model.DataCaches != null)
|
||||
{
|
||||
searchObj.OtherParams = Model.OtherParams();
|
||||
DynamicModel searchModel = Model;
|
||||
DataTable searchControls = _queryTable;
|
||||
Model.DataCaches.AddTask(searchObj, "DynamicModel",
|
||||
new Task<DynamicModel>(() => searchModel));
|
||||
Model.DataCaches.AddTask(searchObj, "ControlsTable",
|
||||
new Task<DataTable>(() => searchControls));
|
||||
searchObj.GetSearchDataCaches(Model.DataCaches);
|
||||
}
|
||||
}
|
||||
if (this.MrpClickMenus == null && Model.DataCaches != null)
|
||||
{
|
||||
Model.DataCaches.GetValue(
|
||||
this,
|
||||
"UnionBaseGridRightMenus",
|
||||
out this.MrpClickMenus);
|
||||
}
|
||||
this.SearchObj = searchObj;
|
||||
// 搜索区域复用当前模块配置,MyControl 内部会校验模块号,不一致时仍按原逻辑查询。
|
||||
this.SearchObj.SystemModel = this.SysModel;
|
||||
this.SearchObj.MrpClickMenus = this.MrpClickMenus;
|
||||
|
||||
if (this._leftGridField != null)
|
||||
{
|
||||
@@ -538,6 +567,7 @@ namespace Lskj.Control
|
||||
|
||||
if (fixedQuery)
|
||||
{
|
||||
|
||||
this.pl_top_fix_search.Visible = true;
|
||||
|
||||
// 加载固定查询条件
|
||||
@@ -550,7 +580,12 @@ namespace Lskj.Control
|
||||
{
|
||||
table = Business.Impl.LanguageTranslation.TranslationTableColumn(table, "fieldText");
|
||||
}
|
||||
|
||||
//固定条件不显示,隐藏上方。(只显示表格)
|
||||
if (SystemInfo.Instance.HideFixedConditions)
|
||||
{
|
||||
this.pl_top.Visible = false;
|
||||
table = new DataTable();
|
||||
}
|
||||
|
||||
// DataTable
|
||||
this.cbField.DisplayMember = "fieldText";
|
||||
@@ -560,11 +595,7 @@ namespace Lskj.Control
|
||||
this.SearchObj.InitDefaultSearchControl(table, this.pl_top_fix_search, false);
|
||||
else
|
||||
this.SearchObj.InitDefaultSearchControl(table, this.pl_top_fix_search);
|
||||
//固定条件不显示,隐藏上方。(只显示表格)
|
||||
if (SystemInfo.Instance.HideFixedConditions)
|
||||
{
|
||||
this.pl_top.Visible = false;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1603,6 +1634,8 @@ namespace Lskj.Control
|
||||
this.bbi_export.Enabled = this.SysModel.ExportEnable;
|
||||
this.pl_top_fix_search.Enabled = this.pl_top_search.Enabled = this.SysModel.SearchEnable;
|
||||
this.pl_buttom.Visible = this.VisibleOperPanel && (this.SysModel.AddEnable || this.SysModel.DeleteEnable || (this.SysModel.ModifyEnable && this.SysModel.CanEdit));
|
||||
|
||||
this.btnUpdate.Enabled = this.SysModel.ModifyEnable && this.SysModel.CanEdit;
|
||||
|
||||
this.gcMain.GridView.FocusedRowObjectChanged += new DevExpress.XtraGrid.Views.Base.FocusedRowObjectChangedEventHandler(OnGridViewFocusedRowObjectChanged);
|
||||
if (this.LeftGridEx != null) this.LeftGridEx.GridView.FocusedRowObjectChanged += new DevExpress.XtraGrid.Views.Base.FocusedRowObjectChangedEventHandler(OnGridViewFocusedRowObjectChanged);
|
||||
@@ -1611,7 +1644,7 @@ namespace Lskj.Control
|
||||
}
|
||||
else
|
||||
{
|
||||
this.btnAdd.Enabled = this.btnDel.Enabled = this.btnSave.Enabled = this.bbi_import.Enabled = false;
|
||||
this.btnUpdate.Enabled=this.btnAdd.Enabled = this.btnDel.Enabled = this.btnSave.Enabled = this.bbi_import.Enabled = false;
|
||||
this.gcMain.GridView.OptionsBehavior.Editable = false;
|
||||
this.pl_buttom.Visible = false;
|
||||
}
|
||||
@@ -1678,7 +1711,8 @@ namespace Lskj.Control
|
||||
}
|
||||
else
|
||||
{
|
||||
cond = ReplaceHelper.ReplaceRowParam(dataRow, cond);
|
||||
//cond = ReplaceHelper.ReplaceRowParam(dataRow, cond);
|
||||
cond = ReplaceHelper.ReplaceRowParamEmptyWrapQuote(dataRow, cond);
|
||||
if (cond.StartsWith("@") || cond.StartsWith("!"))
|
||||
{
|
||||
result = "1".Equals(BaseImpl.GetDefaultValue(cond));
|
||||
@@ -2452,8 +2486,6 @@ namespace Lskj.Control
|
||||
|
||||
form.SubForm.Dispose();
|
||||
form = null;
|
||||
GC.Collect();
|
||||
GC.WaitForPendingFinalizers();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -3463,6 +3495,12 @@ namespace Lskj.Control
|
||||
// 刷新数据
|
||||
if (ImportResults)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(this.SysModel.afterimportSql))
|
||||
{
|
||||
string sql = this.SearchObj.ReplaceControlValue(this.SysModel.afterimportSql);
|
||||
string newResult = SqlHelper.ExecuteScalar(sql) + "";
|
||||
}
|
||||
|
||||
if (ImportReturnName.Count > 0)
|
||||
{
|
||||
this.SearchObj.SearchGrid();
|
||||
@@ -3471,11 +3509,7 @@ namespace Lskj.Control
|
||||
{
|
||||
this.SearchObj.SearchLastGrid();
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(this.SysModel.afterimportSql))
|
||||
{
|
||||
string sql = this.SearchObj.ReplaceControlValue(this.SysModel.afterimportSql);
|
||||
string newResult = SqlHelper.ExecuteScalar(sql) + "";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//GridColumnCollection gridColumns = this.gcMain.GridView.Columns;
|
||||
@@ -3510,11 +3544,20 @@ namespace Lskj.Control
|
||||
|
||||
FrmImport import = new FrmImport(this.SysModel.MenuTable, this.Model.ModuleCode, _parmaryKey, this.gcMain, this.SysModel.PrefixKey, leftField, leftValue, this.Model.FormText, this.SysModel.ConcatenatedPrefix);
|
||||
import.ParentGridEx = this.ParentGridEx;
|
||||
import.SearchObj = this.SearchObj;
|
||||
import.ImportReturnName = ImportReturnName;
|
||||
import.ImportReturnValue = ImportReturnValue;
|
||||
DialogResult result = import.ShowDialog();
|
||||
if (result == DialogResult.OK)
|
||||
{
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(this.SysModel.afterimportSql))
|
||||
{
|
||||
string sql = this.SearchObj.ReplaceControlValue(this.SysModel.afterimportSql);
|
||||
string newResult = SqlHelper.ExecuteScalar(sql) + "";
|
||||
//if (!string.IsNullOrEmpty(newResult)) MessageUtil.Show(newResult);
|
||||
}
|
||||
|
||||
// 刷新数据
|
||||
if (ImportReturnName.Count > 0)
|
||||
{
|
||||
@@ -3525,14 +3568,6 @@ namespace Lskj.Control
|
||||
this.SearchObj.SearchLastGrid();
|
||||
}
|
||||
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(this.SysModel.afterimportSql))
|
||||
{
|
||||
string sql = this.SearchObj.ReplaceControlValue(this.SysModel.afterimportSql);
|
||||
string newResult = SqlHelper.ExecuteScalar(sql) + "";
|
||||
//if (!string.IsNullOrEmpty(newResult)) MessageUtil.Show(newResult);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3670,7 +3705,141 @@ namespace Lskj.Control
|
||||
public ModuleGridEx()
|
||||
{
|
||||
InitializeComponent();
|
||||
InitializeAltButtonShortcuts();
|
||||
this.OperShortMode = true;
|
||||
this.Disposed += OnModuleGridExDisposed;
|
||||
}
|
||||
|
||||
private void InitializeAltButtonShortcuts()
|
||||
{
|
||||
mAltButtonShortcuts.Register(btnFixSearch, Keys.Q);
|
||||
mAltButtonShortcuts.Register(btnSave, Keys.S);
|
||||
mAltButtonShortcuts.Register(btnUpdate, Keys.U);
|
||||
mAltButtonShortcuts.Register(btnPrint, Keys.P);
|
||||
mAltButtonShortcuts.Register(btnExport, Keys.E);
|
||||
mAltButtonShortcuts.Register(btnImport, Keys.I);
|
||||
mAltButtonShortcuts.Register(btnDel, Keys.D);
|
||||
mAltButtonShortcuts.Register(btnAdd, Keys.A);
|
||||
}
|
||||
|
||||
protected override bool ProcessCmdKey(
|
||||
ref System.Windows.Forms.Message msg, Keys keyData)
|
||||
{
|
||||
return mAltButtonShortcuts.ProcessKey(keyData) ||
|
||||
base.ProcessCmdKey(ref msg, keyData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理公共事件和全局右键引用,避免模块关闭后仍保留当前表格。
|
||||
/// </summary>
|
||||
private void OnModuleGridExDisposed(object sender, EventArgs e)
|
||||
{
|
||||
this.Disposed -= OnModuleGridExDisposed;
|
||||
ReleaseResourcesForDispose();
|
||||
}
|
||||
|
||||
internal void ReleaseResourcesForDispose()
|
||||
{
|
||||
if (mModuleResourcesReleased)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mModuleResourcesReleased = true;
|
||||
PrintUtil.OnAfterPrint -= OnReportPrintAfter;
|
||||
|
||||
MyControl searchObj = SearchObj;
|
||||
SearchObj = null;
|
||||
if (searchObj != null)
|
||||
{
|
||||
searchObj.OnSearchBeforeCallBack -= OnSearchBeforeCallBack;
|
||||
searchObj.OnSearchAfterCallBack -= OnSearchAfterCallBack;
|
||||
searchObj.OnDataSourceBindCallBack -= OnMainSearchDataSourceBindCallBack;
|
||||
if (ReferenceEquals(StaticControl.RightMenuMyControl, searchObj))
|
||||
{
|
||||
StaticControl.RightMenuMyControl = null;
|
||||
}
|
||||
searchObj.Dispose();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (gcMain != null)
|
||||
{
|
||||
if (ReferenceEquals(StaticControl.RightMenuGridView, gcMain.GridView))
|
||||
{
|
||||
StaticControl.RightMenuGridView = null;
|
||||
}
|
||||
if (gcMain.GridView != null)
|
||||
{
|
||||
gcMain.GridView.FocusedRowObjectChanged -= OnGridViewFocusedRowObjectChanged;
|
||||
gcMain.GridView.ShowingEditor -= OnGridViewShowingEditor;
|
||||
gcMain.GridView.DoubleClick -= OnGridViewDoubleClick;
|
||||
gcMain.GridView.MouseDown -= OnGridViewMouseDown;
|
||||
gcMain.GridView.MouseDown -= OnGridMouseDown;
|
||||
gcMain.GridView.MouseMove -= OnGridMouseMove;
|
||||
gcMain.GridView.MouseUp -= OnGridMouseUp;
|
||||
}
|
||||
if (gcMain.CustomGroupBandEx != null)
|
||||
{
|
||||
gcMain.CustomGroupBandEx.GridView.FocusedRowObjectChanged -= OnGridViewFocusedRowObjectChanged;
|
||||
gcMain.CustomGroupBandEx.GridView.ShowingEditor -= OnGridViewShowingEditor;
|
||||
}
|
||||
if (gcMain.ParentControl != null &&
|
||||
ReferenceEquals(gcMain.ParentControl, searchObj))
|
||||
{
|
||||
gcMain.ParentControl = null;
|
||||
}
|
||||
gcMain.Model = null;
|
||||
gcMain.SysModel = null;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// A partially disposed DevExpress view must not stop module cleanup.
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (Model != null && Model.DataCaches != null)
|
||||
{
|
||||
Model.DataCaches.RemoveCache(this);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Cache cleanup must not interrupt control disposal.
|
||||
}
|
||||
|
||||
OnSaveGridCallBack = null;
|
||||
AfterDeleteGridCallBack = null;
|
||||
RightGridCallBack = null;
|
||||
DetailRightGridCallBack = null;
|
||||
OnCloseCallback = null;
|
||||
AfterRefreshingCallBack = null;
|
||||
SaveEvent = null;
|
||||
OnExportCallBack = null;
|
||||
verifyDetailsTab = null;
|
||||
|
||||
if (m_dragRowShadow != null)
|
||||
{
|
||||
m_dragRowShadow.Dispose();
|
||||
m_dragRowShadow = null;
|
||||
}
|
||||
ButtonModeRightMenus.Clear();
|
||||
RightButtons.Clear();
|
||||
itemCommonList.Clear();
|
||||
LineStatus.Clear();
|
||||
_leftGridSearchObj = null;
|
||||
LeftTreeViewEx = null;
|
||||
LeftGridEx = null;
|
||||
SpecialLeftTable = null;
|
||||
ParentGridEx = null;
|
||||
ParentControlEx = null;
|
||||
ParentControlObj = null;
|
||||
TabObj = null;
|
||||
Model = null;
|
||||
SysModel = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -3782,13 +3951,10 @@ namespace Lskj.Control
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (this.SearchObj != null)
|
||||
{
|
||||
this.SearchObj.SystemModel = sysModel;
|
||||
}
|
||||
|
||||
//if (this.SearchObj != null)
|
||||
//{
|
||||
// this.SearchObj.SystemModel = sysModel;
|
||||
//}
|
||||
|
||||
//禁用条件
|
||||
if (this.SysModel.ForbiddenCondition)
|
||||
@@ -3955,33 +4121,12 @@ namespace Lskj.Control
|
||||
{
|
||||
return BaseModuleImpl.GetSchemesList(dynamicModel.ModuleId);//获取高级查询条件模版
|
||||
}));
|
||||
//InitializeQueryCondition
|
||||
Task<MyControl> searchObjTask = cachesDic.AddTask(this, "SearchObj", new Task<MyControl>(() =>
|
||||
{
|
||||
DataTable queryTable = customQueryFieldsTask.Result;
|
||||
bool fixedQuery = queryTable == null || queryTable.Rows.Count == 0;
|
||||
MyControl myControl = new MyControl(sysModel.MenuSql, gcMain, LeftTreeViewEx, LeftGridEx, _leftGridSearchObj)
|
||||
{
|
||||
SpecialLeftTable = this.SpecialLeftTable,
|
||||
Model = dynamicModel
|
||||
};
|
||||
if (!fixedQuery)
|
||||
{
|
||||
myControl.OtherParams = dynamicModel.OtherParams();
|
||||
cachesDic.AddTask(myControl, "DynamicModel", dynamicModelTask);
|
||||
cachesDic.AddTask(myControl, "ControlsTable", customQueryFieldsTask);
|
||||
myControl.GetSearchDataCaches(cachesDic);
|
||||
}
|
||||
return myControl;
|
||||
}));
|
||||
Task<ModuleModel> searchSysModelTask = cachesDic.AddTask(pl_top_search, "SysModel", new Task<ModuleModel>(() =>
|
||||
{
|
||||
return new ModuleModel(MainImpl.GetSystemdllTab(dynamicModel.ModuleCode));
|
||||
}));
|
||||
Task<DataTable> searchBaseGridRightMenusTask = cachesDic.AddTask(pl_top_search, "BaseGridRightMenus", new Task<DataTable>(() =>
|
||||
{
|
||||
return BaseModuleImpl.GetBaseGridRightMenus(dynamicModel.ModuleCode, ModuleType.MrpClickBtn);
|
||||
}));
|
||||
// 搜索区域与当前模块共享同一个模块配置任务,避免再次查询模块信息。
|
||||
cachesDic.AddTask(pl_top_search, "SysModel", sysModelTask);
|
||||
//Task<DataTable> searchBaseGridRightMenusTask = cachesDic.AddTask(pl_top_search, "BaseGridRightMenus", new Task<DataTable>(() =>
|
||||
//{
|
||||
// return BaseModuleImpl.GetBaseGridRightMenus(dynamicModel.ModuleCode, ModuleType.MrpClickBtn);
|
||||
//}));
|
||||
Task<DataTable> fixedQueryFieldsTask = cachesDic.AddTask(this, "FixedQueryFields", new Task<DataTable>(() =>
|
||||
{
|
||||
return BaseModuleImpl.GetFixedQueryFields(dynamicModel.ModuleCode);//加载固定查询条件
|
||||
@@ -5169,28 +5314,6 @@ namespace Lskj.Control
|
||||
if (!gridView.FocusedColumn.FieldName.Equals("RightMenuBtnEdit"))//操作列可点击
|
||||
{
|
||||
e.Cancel = !btnSave.Enabled;
|
||||
//如果是备注框,显示编辑框,但不能修改(编辑框弹出和取消编辑冲突,只能改变只读状态后,开始编辑)
|
||||
if (gridColumnModel != null && gridColumnModel.FieldType == ControlType.LabMemoEdit)
|
||||
{
|
||||
RepositoryItemMemoExEdit memoEdit = gridColumn.ColumnEdit as RepositoryItemMemoExEdit;
|
||||
if (e.Cancel)
|
||||
{
|
||||
//设置只读
|
||||
memoEdit.ReadOnly = true;
|
||||
//只读状态允许下拉列表
|
||||
memoEdit.AllowDropDownWhenReadOnly = DevExpress.Utils.DefaultBoolean.True;
|
||||
//允许编辑(编辑框弹出)
|
||||
e.Cancel = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gridColumn.OptionsColumn.AllowEdit && memoEdit.ReadOnly)
|
||||
{
|
||||
memoEdit.ReadOnly = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (!string.IsNullOrEmpty(this.SysModel.RowAllowEditCond) && focusedRow != null)
|
||||
{
|
||||
@@ -5202,6 +5325,22 @@ namespace Lskj.Control
|
||||
//e.Cancel = !ReplaceHelper.EvalCond(ReplaceHelper.ReplaceRowParam(focusedRow, gridColumnModel.DisableCond));
|
||||
e.Cancel = !ValidateCond(gridColumnModel.DisableCond, focusedRow);
|
||||
}
|
||||
|
||||
// 备注框在禁编状态下仍允许打开弹窗查看内容,但不能修改。
|
||||
if (gridColumnModel != null && gridColumnModel.FieldType == ControlType.LabMemoEdit)
|
||||
{
|
||||
RepositoryItemMemoExEdit memoEdit = gridColumn.ColumnEdit as RepositoryItemMemoExEdit;
|
||||
if (memoEdit != null)
|
||||
{
|
||||
bool readOnly = !btnSave.Enabled || e.Cancel || gridColumn.OptionsColumn.ReadOnly;
|
||||
memoEdit.ReadOnly = readOnly;
|
||||
if (readOnly)
|
||||
{
|
||||
memoEdit.AllowDropDownWhenReadOnly = DevExpress.Utils.DefaultBoolean.True;
|
||||
e.Cancel = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
+12
-7
@@ -14,9 +14,14 @@ namespace Lskj.Control
|
||||
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
if (disposing)
|
||||
{
|
||||
components.Dispose();
|
||||
Lskj.Control.Model.PrintUtil.OnAfterPrint -=
|
||||
new EventHandler(OnReportPrintAfter);
|
||||
if (components != null)
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
@@ -305,7 +310,7 @@ namespace Lskj.Control
|
||||
this.btnAttach.Size = new System.Drawing.Size(80, 28);
|
||||
this.btnAttach.TabIndex = 6;
|
||||
this.btnAttach.TabStop = false;
|
||||
this.btnAttach.Text = "附件管理(&F)";
|
||||
this.btnAttach.Text = "附件管理(F)";
|
||||
//
|
||||
// btnUpdate
|
||||
//
|
||||
@@ -316,7 +321,7 @@ namespace Lskj.Control
|
||||
this.btnUpdate.Size = new System.Drawing.Size(80, 28);
|
||||
this.btnUpdate.TabIndex = 4;
|
||||
this.btnUpdate.TabStop = false;
|
||||
this.btnUpdate.Text = "修改保存(&E)";
|
||||
this.btnUpdate.Text = "修改保存(E)";
|
||||
//
|
||||
// ddb_common
|
||||
//
|
||||
@@ -337,7 +342,7 @@ namespace Lskj.Control
|
||||
this.btnApply.Name = "btnApply";
|
||||
this.btnApply.Size = new System.Drawing.Size(80, 28);
|
||||
this.btnApply.TabIndex = 5;
|
||||
this.btnApply.Text = "提交审核(&R)";
|
||||
this.btnApply.Text = "提交审核(R)";
|
||||
//
|
||||
// btnAdd
|
||||
//
|
||||
@@ -348,7 +353,7 @@ namespace Lskj.Control
|
||||
this.btnAdd.Size = new System.Drawing.Size(80, 28);
|
||||
this.btnAdd.TabIndex = 3;
|
||||
this.btnAdd.TabStop = false;
|
||||
this.btnAdd.Text = "添加保存(&A)";
|
||||
this.btnAdd.Text = "添加保存(A)";
|
||||
//
|
||||
// btnClose
|
||||
//
|
||||
@@ -359,7 +364,7 @@ namespace Lskj.Control
|
||||
this.btnClose.Size = new System.Drawing.Size(80, 28);
|
||||
this.btnClose.TabIndex = 10;
|
||||
this.btnClose.TabStop = false;
|
||||
this.btnClose.Text = "退出(&C)";
|
||||
this.btnClose.Text = "退出(C)";
|
||||
//
|
||||
// simpleButton1
|
||||
//
|
||||
|
||||
@@ -47,6 +47,9 @@ namespace Lskj.Control
|
||||
/// </summary>
|
||||
public partial class ModulePanelEx : UserControl
|
||||
{
|
||||
private readonly AltButtonShortcutManager mAltButtonShortcuts =
|
||||
new AltButtonShortcutManager();
|
||||
|
||||
public LabelTextEdit ScanEdit { get { return this._scanEdit; } }
|
||||
#region private property
|
||||
|
||||
@@ -228,6 +231,7 @@ namespace Lskj.Control
|
||||
{
|
||||
SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.Selectable | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.SupportsTransparentBackColor, true);
|
||||
InitializeComponent();
|
||||
InitializeAltButtonShortcuts();
|
||||
this.scc_container.PanelVisibility = SplitPanelVisibility.Panel1;
|
||||
this.simpleButton1.Click += simpleButton1_Click;
|
||||
this.btnClear.Click += OnBtnClearClick;
|
||||
@@ -241,6 +245,22 @@ namespace Lskj.Control
|
||||
this.BtnMesClose.Click += OnBtnMesCloseClick;
|
||||
}
|
||||
|
||||
private void InitializeAltButtonShortcuts()
|
||||
{
|
||||
mAltButtonShortcuts.Register(btnAttach, Keys.F);
|
||||
mAltButtonShortcuts.Register(btnUpdate, Keys.E);
|
||||
mAltButtonShortcuts.Register(btnApply, Keys.R);
|
||||
mAltButtonShortcuts.Register(btnAdd, Keys.A);
|
||||
mAltButtonShortcuts.Register(btnClose, Keys.C);
|
||||
}
|
||||
|
||||
protected override bool ProcessCmdKey(
|
||||
ref System.Windows.Forms.Message msg, Keys keyData)
|
||||
{
|
||||
return mAltButtonShortcuts.ProcessKey(keyData) ||
|
||||
base.ProcessCmdKey(ref msg, keyData);
|
||||
}
|
||||
|
||||
#region private method
|
||||
/// <summary>
|
||||
/// <para>说明:控制滚动条是否存在横向的</para>
|
||||
@@ -360,9 +380,9 @@ namespace Lskj.Control
|
||||
this.btnUpdate.Location = this.btnApply.Location;
|
||||
}
|
||||
// 设置文本
|
||||
btnAdd.Text = !string.IsNullOrWhiteSpace(this.SysModel.AddCaption) ? this.SysModel.AddCaption : "添加保存(&A)";
|
||||
btnUpdate.Text = !string.IsNullOrWhiteSpace(this.SysModel.ModifyCaption) ? this.SysModel.ModifyCaption : "修改保存(&E)";
|
||||
btnApply.Text = !string.IsNullOrWhiteSpace(this.SysModel.ApplyCaption) ? this.SysModel.ApplyCaption : "提交审核(&R)";
|
||||
btnAdd.Text = !string.IsNullOrWhiteSpace(this.SysModel.AddCaption) ? this.SysModel.AddCaption : "添加保存(A)";
|
||||
btnUpdate.Text = !string.IsNullOrWhiteSpace(this.SysModel.ModifyCaption) ? this.SysModel.ModifyCaption : "修改保存(E)";
|
||||
btnApply.Text = !string.IsNullOrWhiteSpace(this.SysModel.ApplyCaption) ? this.SysModel.ApplyCaption : "提交审核(R)";
|
||||
|
||||
//隐藏帮助文档按钮
|
||||
if (SystemInfo.Instance.HideHelpDocument) this.simpleButton1.Visible = false;
|
||||
@@ -1814,7 +1834,11 @@ namespace Lskj.Control
|
||||
{
|
||||
// 提交数据
|
||||
this.PrimaryValue = this.SysModel.NewVer == 0 ? this.ControlObj.GetControlValue(this.PrimaryKey) : this.PrimaryValue;
|
||||
if (string.IsNullOrEmpty(PrimaryValue) || SavaState) this.AddControlRecord(true, false);
|
||||
if (string.IsNullOrEmpty(PrimaryValue) || SavaState)
|
||||
{
|
||||
isApply=this.AddControlRecord(true, false);
|
||||
if (!isApply) return;//保存失败不执行提交
|
||||
}
|
||||
DialogResult result = MessageUtil.Show(ResourceKeys.BillApply, MessageBoxButtons.YesNo);
|
||||
if (result == DialogResult.Yes)
|
||||
{
|
||||
@@ -2739,7 +2763,7 @@ namespace Lskj.Control
|
||||
BaseUserControl baseControl = this.ControlObj.FindControl(PrimaryKey);
|
||||
if (baseControl != null)
|
||||
{
|
||||
this.ControlObj.CopyControlValue();
|
||||
this.ControlObj.CopyControlValue(this.SysModel.CancelCopyAssociation);
|
||||
baseControl.EditText = BaseImpl.GetDefaultValue(baseControl.Model.Default, ParentKey);
|
||||
|
||||
lteSpeciesNo.TextEdit.EditValue = this.ParentKey;
|
||||
|
||||
@@ -186,6 +186,8 @@ namespace Lskj.Control.MultiGridLookUp
|
||||
this.Location = new Point((SystemInformation.PrimaryMonitorSize.Width - this.Width) / 2,
|
||||
(SystemInformation.PrimaryMonitorSize.Height - this.Height) / 2);
|
||||
}
|
||||
// 自动列宽和弹窗尺寸计算完成后,最后应用个性化列配置,避免配置被覆盖。
|
||||
this.SetCustomColumns();
|
||||
}
|
||||
/// <summary>
|
||||
/// <para>说明:计算控件Size,只计算一次</para>
|
||||
@@ -374,7 +376,6 @@ namespace Lskj.Control.MultiGridLookUp
|
||||
}
|
||||
}
|
||||
}
|
||||
SetCustomColumns();
|
||||
this.gcDetail.GridControl.DataSource = this.gridControl1.DataSourceTable().Clone();
|
||||
this.gcMain.BestFitColumns();
|
||||
//this.gcDetail.SelectAll();
|
||||
@@ -397,28 +398,53 @@ namespace Lskj.Control.MultiGridLookUp
|
||||
DataTable customTable = this.gcMain.GetCustomColumnByDatabase(this.CurrentOperColumnKey);
|
||||
if (customTable != null && customTable.Rows.Count > 0)
|
||||
{
|
||||
foreach (DataRow rowItem in customTable.Rows)
|
||||
this.gcMain.BeginUpdate();
|
||||
this.gcDetail.BeginUpdate();
|
||||
try
|
||||
{
|
||||
string fieldName = rowItem["fieldName"] + "";
|
||||
int fieldWidth = Convert.ToInt32(rowItem["fieldWidth"]);
|
||||
int index = Convert.ToInt32(rowItem["orderid"]);
|
||||
bool visible = "1".Equals(rowItem["isVisible"] + "") && fieldWidth > 0;
|
||||
bool isFix = "True".Equals(rowItem["IfFixColumn"] + "", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
GridColumn gridColumn = this.gcMain.Columns.ColumnByName(fieldName);
|
||||
if (gridColumn != null && gridColumn.Visible && gridColumn.Width > 0)
|
||||
foreach (DataRow rowItem in customTable.Rows)
|
||||
{
|
||||
GridColumn colObj = this.gcMain.Columns[fieldName];
|
||||
colObj.VisibleIndex = index;
|
||||
colObj.Width = fieldWidth;
|
||||
colObj.Visible = visible;
|
||||
colObj.Fixed = isFix ? FixedStyle.Left : FixedStyle.None;
|
||||
colObj.OptionsFilter.FilterPopupMode = FilterPopupMode.CheckedList;
|
||||
string fieldName = rowItem["fieldName"] + "";
|
||||
int fieldWidth = Convert.ToInt32(rowItem["fieldWidth"]);
|
||||
int index = Convert.ToInt32(rowItem["orderid"]);
|
||||
bool visible = "1".Equals(rowItem["isVisible"] + "") && fieldWidth > 0;
|
||||
bool isFix = "True".Equals(rowItem["IfFixColumn"] + "", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
SetCustomColumn(this.gcMain.Columns.ColumnByName(fieldName), fieldWidth, index, visible, isFix);
|
||||
SetCustomColumn(this.gcDetail.Columns.ColumnByName(fieldName), fieldWidth, index, visible, isFix);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
this.gcDetail.EndUpdate();
|
||||
this.gcMain.EndUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 应用单列的个性化布局。
|
||||
/// </summary>
|
||||
private static void SetCustomColumn(GridColumn column, int width, int visibleIndex, bool visible, bool isFix)
|
||||
{
|
||||
if (column == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
column.Visible = visible;
|
||||
if (visible)
|
||||
{
|
||||
column.VisibleIndex = visibleIndex;
|
||||
}
|
||||
if (width > 0)
|
||||
{
|
||||
column.Width = width;
|
||||
}
|
||||
column.Fixed = isFix ? FixedStyle.Left : FixedStyle.None;
|
||||
column.OptionsFilter.FilterPopupMode = FilterPopupMode.CheckedList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>说明:设置默认选中</para>
|
||||
/// <para>创建人:龚宇超</para>
|
||||
|
||||
@@ -247,11 +247,10 @@ namespace Lskj.Control.MultiModelLookUp
|
||||
{
|
||||
try
|
||||
{
|
||||
string width = IniHelper.Read(string.Format("base_width_{0}", this.UnionModuleCodel));//通过Key获取Value值
|
||||
string width = IniHelper.Read(string.Format("FrmModelLookUp_width_{0}", this.UnionModuleCodel));//通过Key获取Value值
|
||||
if (!string.IsNullOrEmpty(width))
|
||||
{
|
||||
this.splitMain.SplitterPosition = Convert.ToInt32(width);
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -777,6 +776,7 @@ namespace Lskj.Control.MultiModelLookUp
|
||||
private void PositionChange(object sender, EventArgs e)
|
||||
{
|
||||
PositionSplitter = this.splitMain_Right.SplitterPosition;
|
||||
IniHelper.Write(string.Format("FrmModelLookUp_height_{0}", this.UnionModuleCodel), PositionSplitter + "");
|
||||
}
|
||||
#endregion
|
||||
#region 窗口大小改变
|
||||
@@ -1028,6 +1028,21 @@ namespace Lskj.Control.MultiModelLookUp
|
||||
this.SysModel = new ModuleModel(modelRow);// 系统模块实体对象
|
||||
if (this.SysModel != null)
|
||||
{
|
||||
if (this.SysModel.ModuleFrameHeight > 0 && this.SysModel.ModuleFrameWidth > 0)
|
||||
{
|
||||
this.Height = this.SysModel.ModuleFrameHeight;
|
||||
this.Width = this.SysModel.ModuleFrameWidth;
|
||||
}
|
||||
|
||||
string height = IniHelper.Read(string.Format("FrmModelLookUp_height_{0}", this.UnionModuleCodel));//通过Key获取Value值
|
||||
if (!string.IsNullOrEmpty(height))
|
||||
{
|
||||
this.splitMain_Right.SplitterPosition = Convert.ToInt32(height);
|
||||
}
|
||||
else if (this.SysModel.BottomHeight > 0)
|
||||
{
|
||||
this.splitMain_Right.SplitterPosition = Convert.ToInt32(this.splitMain_Right.Height - this.SysModel.BottomHeight);
|
||||
}
|
||||
|
||||
|
||||
switch (this.SysModel.MenuType)
|
||||
@@ -1053,7 +1068,7 @@ namespace Lskj.Control.MultiModelLookUp
|
||||
this.splitMain.PanelVisibility = SplitPanelVisibility.Panel2;
|
||||
break;
|
||||
}
|
||||
|
||||
this.splitMain.SplitterPositionChanged += SplitMain_SplitterPositionChanged;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1063,6 +1078,12 @@ namespace Lskj.Control.MultiModelLookUp
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private void SplitMain_SplitterPositionChanged(object sender, EventArgs e)
|
||||
{
|
||||
IniHelper.Write(string.Format("FrmModelLookUp_width_{0}", this.UnionModuleCodel), this.splitMain.SplitterPosition + "");
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
+13
-14
@@ -28,11 +28,11 @@
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this.splitMain = new DevExpress.XtraEditors.SplitContainerControl();
|
||||
this.pl_left = new DevExpress.XtraEditors.PanelControl();
|
||||
this.pl_left_main = new System.Windows.Forms.Panel();
|
||||
this.pl_gridandtree_container = new DevExpress.XtraEditors.PanelControl();
|
||||
this.treeLeft = new Lskj.Control.TreeViewEx();
|
||||
this.gridLeft = new Lskj.Control.GridControlEx();
|
||||
this.pl_left_top = new DevExpress.XtraEditors.PanelControl();
|
||||
this.splitMain_Right = new DevExpress.XtraEditors.SplitContainerControl();
|
||||
@@ -44,12 +44,11 @@
|
||||
this.btn_selectAll = new DevExpress.XtraEditors.SimpleButton();
|
||||
this.btn_cancelAll = new DevExpress.XtraEditors.SimpleButton();
|
||||
this.btnOk = new DevExpress.XtraEditors.SimpleButton();
|
||||
this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||
this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip();
|
||||
this.tsmi_all = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.tsmi_reserve = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.tsmi_cancel = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.treeLeft = new Lskj.Control.TreeViewEx();
|
||||
((System.ComponentModel.ISupportInitialize)(this.splitMain)).BeginInit();
|
||||
this.splitMain.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.pl_left)).BeginInit();
|
||||
@@ -118,6 +117,16 @@
|
||||
this.pl_gridandtree_container.Size = new System.Drawing.Size(260, 454);
|
||||
this.pl_gridandtree_container.TabIndex = 9;
|
||||
//
|
||||
// treeLeft
|
||||
//
|
||||
this.treeLeft.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.treeLeft.Location = new System.Drawing.Point(0, 0);
|
||||
this.treeLeft.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.treeLeft.Name = "treeLeft";
|
||||
this.treeLeft.Size = new System.Drawing.Size(260, 454);
|
||||
this.treeLeft.TabIndex = 7;
|
||||
this.treeLeft.Visible = false;
|
||||
//
|
||||
// gridLeft
|
||||
//
|
||||
this.gridLeft.AdapterObj = null;
|
||||
@@ -218,7 +227,7 @@
|
||||
this.btnCancel.Location = new System.Drawing.Point(772, 5);
|
||||
this.btnCancel.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.btnCancel.Name = "btnCancel";
|
||||
this.btnCancel.Size = new System.Drawing.Size(79, 35);
|
||||
this.btnCancel.Size = new System.Drawing.Size(76, 35);
|
||||
this.btnCancel.TabIndex = 24;
|
||||
this.btnCancel.Text = "取消(&C)";
|
||||
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
|
||||
@@ -297,16 +306,6 @@
|
||||
this.tsmi_cancel.Size = new System.Drawing.Size(100, 22);
|
||||
this.tsmi_cancel.Text = "取消";
|
||||
//
|
||||
// treeLeft
|
||||
//
|
||||
this.treeLeft.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.treeLeft.Location = new System.Drawing.Point(0, 0);
|
||||
this.treeLeft.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.treeLeft.Name = "treeLeft";
|
||||
this.treeLeft.Size = new System.Drawing.Size(260, 454);
|
||||
this.treeLeft.TabIndex = 7;
|
||||
this.treeLeft.Visible = false;
|
||||
//
|
||||
// FrmModelLookUp2
|
||||
//
|
||||
this.Appearance.BackColor = System.Drawing.SystemColors.Control;
|
||||
|
||||
@@ -156,6 +156,14 @@ namespace Lskj.Control.MultiModelLookUp
|
||||
/// </summary>
|
||||
public Dictionary<string, string> ModuleResultDic = new Dictionary<string, string>();
|
||||
/// <summary>
|
||||
/// 单选模式最后选中的原始数据行,供需要按动态列名返回多字段的调用方使用。
|
||||
/// </summary>
|
||||
public DataRow SelectedResultRow { get; private set; }
|
||||
public DataRow GetSelectedResultRow()
|
||||
{
|
||||
return SelectedResultRow ?? this.gcMain.GridView.GetFocusedDataRow();
|
||||
}
|
||||
/// <summary>
|
||||
/// 返回多行的集合(模块返回添加行 167 168)
|
||||
/// </summary>
|
||||
public List<string> EditValueList = new List<string>();
|
||||
@@ -258,12 +266,12 @@ namespace Lskj.Control.MultiModelLookUp
|
||||
{
|
||||
try
|
||||
{
|
||||
string width = IniHelper.Read(string.Format("base_width_{0}", this.UnionModuleCodel));//通过Key获取Value值
|
||||
string width = IniHelper.Read(string.Format("FrmModelLookUp2_width_{0}", this.UnionModuleCodel));//通过Key获取Value值
|
||||
if (!string.IsNullOrEmpty(width))
|
||||
{
|
||||
this.splitMain.SplitterPosition = Convert.ToInt32(width);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -458,7 +466,8 @@ namespace Lskj.Control.MultiModelLookUp
|
||||
}
|
||||
}
|
||||
}
|
||||
SetCustomColumns();
|
||||
|
||||
//SetCustomColumns();
|
||||
}
|
||||
#endregion
|
||||
#region 加载自定义列
|
||||
@@ -473,7 +482,7 @@ namespace Lskj.Control.MultiModelLookUp
|
||||
/// </summary>
|
||||
private void SetCustomColumns()
|
||||
{
|
||||
if (string.IsNullOrEmpty(this.CurrentOperColumnKey) || !BaseImpl.HasExistsTable(ResourceKeys.SettingTableName)) return;
|
||||
if (string.IsNullOrEmpty(this.CurrentOperColumnKey)) return;
|
||||
|
||||
DataTable customTable = this.gcMain.GridView.GetCustomColumnByDatabase(this.CurrentOperColumnKey);
|
||||
if (customTable != null && customTable.Rows.Count > 0)
|
||||
@@ -797,6 +806,7 @@ namespace Lskj.Control.MultiModelLookUp
|
||||
private void PositionChange(object sender, EventArgs e)
|
||||
{
|
||||
PositionSplitter = this.splitMain_Right.SplitterPosition;
|
||||
IniHelper.Write(string.Format("FrmModelLookUp2_height_{0}", this.UnionModuleCodel), PositionSplitter + "");
|
||||
}
|
||||
#endregion
|
||||
#region 窗口大小改变
|
||||
@@ -855,10 +865,12 @@ namespace Lskj.Control.MultiModelLookUp
|
||||
{
|
||||
EditValue = string.Empty;
|
||||
EditText = string.Empty;
|
||||
SelectedResultRow = null;
|
||||
ModuleResultDic.Clear();
|
||||
DataRow dr = this.gcMain.GridView.GetFocusedDataRow();
|
||||
if (dr != null)
|
||||
{
|
||||
SelectedResultRow = dr;
|
||||
this.EditValue = dr[ValueMember] + "";
|
||||
this.EditText = dr[TextField] + "";
|
||||
|
||||
@@ -1121,7 +1133,21 @@ namespace Lskj.Control.MultiModelLookUp
|
||||
this.SysModel = new ModuleModel(modelRow);// 系统模块实体对象
|
||||
if (this.SysModel != null)
|
||||
{
|
||||
if (this.SysModel.ModuleFrameHeight > 0 && this.SysModel.ModuleFrameWidth > 0)
|
||||
{
|
||||
this.Height = this.SysModel.ModuleFrameHeight;
|
||||
this.Width = this.SysModel.ModuleFrameWidth;
|
||||
}
|
||||
|
||||
string height = IniHelper.Read(string.Format("FrmModelLookUp2_height_{0}", this.UnionModuleCodel));//通过Key获取Value值
|
||||
if (!string.IsNullOrEmpty(height))
|
||||
{
|
||||
this.splitMain_Right.SplitterPosition = Convert.ToInt32(height);
|
||||
}
|
||||
else if (this.SysModel.BottomHeight > 0)
|
||||
{
|
||||
this.splitMain_Right.SplitterPosition = Convert.ToInt32(this.splitMain_Right.Height - this.SysModel.BottomHeight);
|
||||
}
|
||||
|
||||
switch (this.SysModel.MenuType)
|
||||
{
|
||||
@@ -1146,7 +1172,7 @@ namespace Lskj.Control.MultiModelLookUp
|
||||
this.splitMain.PanelVisibility = SplitPanelVisibility.Panel2;
|
||||
break;
|
||||
}
|
||||
|
||||
this.splitMain.SplitterPositionChanged += SplitMain_SplitterPositionChanged;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1156,6 +1182,11 @@ namespace Lskj.Control.MultiModelLookUp
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void SplitMain_SplitterPositionChanged(object sender, EventArgs e)
|
||||
{
|
||||
IniHelper.Write(string.Format("FrmModelLookUp2_width_{0}", this.UnionModuleCodel), this.splitMain.SplitterPosition + "");
|
||||
}
|
||||
#endregion
|
||||
|
||||
//设置选中框的值
|
||||
|
||||
+6
-2
@@ -13,9 +13,13 @@
|
||||
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
if (disposing)
|
||||
{
|
||||
components.Dispose();
|
||||
ReleaseResourcesForDispose();
|
||||
if (components != null)
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
@@ -37,6 +37,8 @@ namespace Lskj.Control
|
||||
/// </summary>
|
||||
public partial class ReplacementDetailEx : UserControl
|
||||
{
|
||||
private bool mResourcesReleased;
|
||||
private bool mDetailPageCachesPrepared;
|
||||
/// <summary>
|
||||
/// 系统模块实体对象
|
||||
/// </summary>
|
||||
@@ -102,6 +104,39 @@ namespace Lskj.Control
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
internal void ReleaseResourcesForDispose()
|
||||
{
|
||||
if (mResourcesReleased)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mResourcesReleased = true;
|
||||
if (ModuleGridObj != null)
|
||||
{
|
||||
ModuleGridObj.ReleaseResourcesForDispose();
|
||||
}
|
||||
try
|
||||
{
|
||||
if (Model != null && Model.DataCaches != null)
|
||||
{
|
||||
Model.DataCaches.RemoveCache(this);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Cache cleanup must not interrupt control disposal.
|
||||
}
|
||||
|
||||
if (GridDetailList != null)
|
||||
{
|
||||
GridDetailList.Clear();
|
||||
}
|
||||
_leftGridSearchObj = null;
|
||||
Model = null;
|
||||
SysModel = null;
|
||||
}
|
||||
/// <summary>
|
||||
/// <para>说明:初始化控件</para>
|
||||
/// <para>创建人:龚宇超</para>
|
||||
@@ -128,6 +163,7 @@ namespace Lskj.Control
|
||||
this.ModuleGridObj.InitializeControl(sysModel, dyncModel);
|
||||
RefreshDetail = this.SysModel.RefreshDetail == "0";
|
||||
Console.WriteLine(DateTime.Now);
|
||||
PrepareDetailPageCaches(dyncModel.DataCaches);
|
||||
// 初始化底部多标签
|
||||
this.InitializePages();
|
||||
Console.WriteLine(DateTime.Now);
|
||||
@@ -162,15 +198,27 @@ namespace Lskj.Control
|
||||
//获取通用数据
|
||||
Task<ModuleModel> sysModelTask = cachesDic.GetTask<ModuleModel>(this, "SysModel");
|
||||
Task<DynamicModel> dynamicModelTask = cachesDic.GetTask<DynamicModel>(this, "DynamicModel");
|
||||
Task<List<GridDetailModel>> detailsTask = cachesDic.GetTask<List<GridDetailModel>>(this, "Details");
|
||||
cachesDic.AddTask(ModuleGridObj, "DynamicModel", dynamicModelTask);
|
||||
cachesDic.AddTask(ModuleGridObj, "SysModel", sysModelTask);
|
||||
cachesDic.AddTask(ModuleGridObj, "Details", detailsTask);
|
||||
cachesDic.AddTask(tcButtom, "DynamicModel", dynamicModelTask);
|
||||
cachesDic.AddTask(tcButtom, "Details", detailsTask);
|
||||
//初始化顶部表格
|
||||
ModuleGridObj.GetDataCaches(cachesDic);
|
||||
// 初始化底部多标签
|
||||
}
|
||||
|
||||
private void PrepareDetailPageCaches(
|
||||
Dictionary<object, Hashtable> cachesDic)
|
||||
{
|
||||
if (mDetailPageCachesPrepared || cachesDic == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mDetailPageCachesPrepared = true;
|
||||
Task<DynamicModel> dynamicModelTask =
|
||||
cachesDic.GetTask<DynamicModel>(this, "DynamicModel");
|
||||
Task<List<GridDetailModel>> detailsTask =
|
||||
cachesDic.GetTask<List<GridDetailModel>>(this, "Details");
|
||||
cachesDic.AddTask(tcButtom, "DynamicModel", dynamicModelTask);
|
||||
cachesDic.AddTask(tcButtom, "Details", detailsTask);
|
||||
tcButtom.GetDataCaches(cachesDic);
|
||||
}
|
||||
|
||||
@@ -650,4 +698,4 @@ namespace Lskj.Control
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,15 +111,17 @@ namespace Lskj.Control.SiftColControl
|
||||
/// <returns></returns>
|
||||
static int CalcIndicatorBestWidth(DevExpress.XtraGrid.Views.Grid.GridView view)
|
||||
{
|
||||
Graphics graphics = new System.Windows.Forms.Control().CreateGraphics();
|
||||
SizeF sizeF = new SizeF();
|
||||
int count = view.TopRowIndex + ((DevExpress.XtraGrid.Views.Grid.ViewInfo.GridViewInfo)view.GetViewInfo()).RowsInfo.Count;
|
||||
if (count == 0)
|
||||
{
|
||||
count = 30;
|
||||
}
|
||||
sizeF = graphics.MeasureString(count.ToString(), view.Appearance.Row.Font);
|
||||
return Convert.ToInt32(sizeF.Width) + 20;
|
||||
int textWidth = TextRenderer.MeasureText(
|
||||
count.ToString(),
|
||||
view.Appearance.Row.Font,
|
||||
Size.Empty,
|
||||
TextFormatFlags.NoPadding | TextFormatFlags.SingleLine).Width;
|
||||
return textWidth + 20;
|
||||
}
|
||||
/// <summary>
|
||||
/// 计算默认的宽度
|
||||
@@ -129,16 +131,18 @@ namespace Lskj.Control.SiftColControl
|
||||
static int CalcIndicatorDefaultWidth(DevExpress.XtraGrid.Views.Grid.GridView view)
|
||||
{
|
||||
var grid = view.GridControl;
|
||||
Graphics graphics = new System.Windows.Forms.Control().CreateGraphics();
|
||||
SizeF sizeF = new SizeF();
|
||||
int rowHeight = 22;//22是Row的估计高度
|
||||
if (view.RowHeight > 0)
|
||||
{
|
||||
rowHeight = view.RowHeight;
|
||||
}
|
||||
int count = grid != null ? grid.Height / rowHeight : 30;
|
||||
sizeF = graphics.MeasureString(count.ToString(), view.Appearance.Row.Font);
|
||||
return Convert.ToInt32(sizeF.Width) + 20;
|
||||
int textWidth = TextRenderer.MeasureText(
|
||||
count.ToString(),
|
||||
view.Appearance.Row.Font,
|
||||
Size.Empty,
|
||||
TextFormatFlags.NoPadding | TextFormatFlags.SingleLine).Width;
|
||||
return textWidth + 20;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -211,7 +211,10 @@ namespace Lskj.Control
|
||||
private void btnClear_Click(object sender, EventArgs e)
|
||||
{
|
||||
try {
|
||||
pictureEdit1.CreateGraphics().Clear(Color.White);
|
||||
using (Graphics graphics = pictureEdit1.CreateGraphics())
|
||||
{
|
||||
graphics.Clear(Color.White);
|
||||
}
|
||||
_mousePath.Reset();
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -211,17 +211,17 @@ namespace Lskj.Control
|
||||
g.SetGridViewDataSource(table);
|
||||
break;
|
||||
|
||||
/* ③ Tag 是面板/其它容器,递归找内部网格 ------------------------ */
|
||||
/* ③ 图表控件:需先于通用容器判断,避免绑定到图表内部隐藏网格 -- */
|
||||
case ChartControlEx chartEx:
|
||||
chartEx.CreateChart(table);
|
||||
break;
|
||||
|
||||
/* ④ Tag 是面板/其它容器,递归找内部网格 ------------------------ */
|
||||
case System.Windows.Forms.Control container when FindGridControlEx(container) is GridControlEx g2:
|
||||
g2.LastSearchSql = lastSql ?? g2.LastSearchSql;
|
||||
g2.SetGridViewDataSource(table);
|
||||
break;
|
||||
|
||||
/* ④ 图表控件 ---------------------------------------------------- */
|
||||
case ChartControlEx chartEx:
|
||||
chartEx.CreateChart(table);
|
||||
break;
|
||||
|
||||
/* ⑤ 其它控件无需绑定 ------------------------------------------- */
|
||||
default:
|
||||
break;
|
||||
@@ -501,6 +501,14 @@ namespace Lskj.Control
|
||||
|
||||
Dictionary<object, Hashtable> dataCaches = Model?.DataCaches;
|
||||
|
||||
// 普通 ModuleGridEx 明细使用同一个父模块主键,避免同步加载时每个明细重复查询。
|
||||
bool hasModuleGridDetail = Model != null && gridDetail.Any(model => IsModuleGridDetail(model, gridDetail, isGridmerge));
|
||||
string parentPrimaryKey = null;
|
||||
if (hasModuleGridDetail && !dataCaches.GetValue(this, "ParentPrimaryKey", out parentPrimaryKey))
|
||||
{
|
||||
parentPrimaryKey = BaseImpl.GetBasePrimaryKey(Model.ModuleCode);
|
||||
}
|
||||
|
||||
this.DetaiName = string.Empty;
|
||||
|
||||
foreach (GridDetailModel model in gridDetail)
|
||||
@@ -520,7 +528,7 @@ namespace Lskj.Control
|
||||
page.SizeChanged += OnPageSizeChanged;
|
||||
|
||||
// 2️⃣ 先生成“左侧”父明细控件
|
||||
System.Windows.Forms.Control leftCtrl = CreateDetailControl(page, model, dataCaches);
|
||||
System.Windows.Forms.Control leftCtrl = CreateDetailControl(page, model, dataCaches, true, null, hasModuleGridDetail, parentPrimaryKey);
|
||||
int position = int.TryParse(IniHelper.Read($"base_TabPageMain_{model.Id}"), out int value) ? value : 0; // 0 是转换失败时的默认值
|
||||
if (hasRight && isGridmerge)
|
||||
{
|
||||
@@ -559,7 +567,7 @@ namespace Lskj.Control
|
||||
foreach (var child in rightChildren.OrderBy(c => c.Orderid))
|
||||
{
|
||||
XtraTabPage childPage = new XtraTabPage { Text = child.DetailName };
|
||||
System.Windows.Forms.Control childCtrl = CreateDetailControl(childPage, child, dataCaches, true, leftControl);
|
||||
System.Windows.Forms.Control childCtrl = CreateDetailControl(childPage, child, dataCaches, true, leftControl, hasModuleGridDetail, parentPrimaryKey);
|
||||
childPage.Controls.Add(childCtrl);
|
||||
rightTab.TabPages.Add(childPage);
|
||||
_rightSideTabPages.Add(childPage);
|
||||
@@ -605,6 +613,21 @@ namespace Lskj.Control
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断明细配置是否会创建普通 ModuleGridEx 控件。
|
||||
/// </summary>
|
||||
private static bool IsModuleGridDetail(GridDetailModel model, List<GridDetailModel> gridDetail, bool isGridmerge)
|
||||
{
|
||||
if (model == null || model.IsChart || model.IsExcel || model.IsWebView || model.IsWebView2 || model.IsWebView3 ||
|
||||
model.IsSched || (model.IsAddPanel && isGridmerge) || model.IsDetailView)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int sameDetailCount = gridDetail.Count(item => item.DetailName.Equals(model.DetailName));
|
||||
return !(model.IsReadOnly && sameDetailCount == 1) && !(sameDetailCount > 1 && isGridmerge);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -989,6 +1012,7 @@ namespace Lskj.Control
|
||||
this.isMrpDetail = true;
|
||||
gridEx.VisibleMrpSearchPanel = true;
|
||||
}
|
||||
gridEx.MrpClickMenus = rightDt;
|
||||
gridEx.VisibleOperPanel = !model.IsReadOnly;
|
||||
gridEx.InitializeControl(model.SystemModel, dyncModel);
|
||||
gridEx.GridControlObj.Tag = model;
|
||||
@@ -1106,7 +1130,7 @@ namespace Lskj.Control
|
||||
/// <param name="dataCaches"></param>
|
||||
/// <param name="isGridmerge"></param>
|
||||
/// <returns></returns>
|
||||
private System.Windows.Forms.Control CreateDetailControl(System.Windows.Forms.Control parentControl, GridDetailModel model, Dictionary<object, Hashtable> dataCaches, bool isGridmerge = true, GridControlEx leftGridControlEx =null)
|
||||
private System.Windows.Forms.Control CreateDetailControl(System.Windows.Forms.Control parentControl, GridDetailModel model, Dictionary<object, Hashtable> dataCaches, bool isGridmerge = true, GridControlEx leftGridControlEx = null, bool hasParentPrimaryKey = false, string parentPrimaryKey = null)
|
||||
{
|
||||
|
||||
GridDetailModel[] isMeage = _gridDetail.Cast<GridDetailModel>().Where(x => x.DetailName.Equals(model.DetailName)).ToArray();
|
||||
@@ -1441,8 +1465,11 @@ namespace Lskj.Control
|
||||
|
||||
if (Model != null)
|
||||
{
|
||||
if (!dataCaches.GetValue(gridEx, "ParentPrimaryKey", out string primaryKey))
|
||||
string primaryKey = parentPrimaryKey;
|
||||
if (!hasParentPrimaryKey && !dataCaches.GetValue(gridEx, "ParentPrimaryKey", out primaryKey))
|
||||
{
|
||||
primaryKey = BaseImpl.GetBasePrimaryKey(Model.ModuleCode);
|
||||
}
|
||||
model.SystemModel.ParmaryKey = primaryKey;
|
||||
}
|
||||
|
||||
@@ -1465,6 +1492,7 @@ namespace Lskj.Control
|
||||
isMrpDetail = true;
|
||||
gridEx.VisibleMrpSearchPanel = true;
|
||||
}
|
||||
gridEx.MrpClickMenus = rightDt;
|
||||
|
||||
gridEx.VisibleOperPanel = !model.IsReadOnly;
|
||||
if (model.HideBottomPanel|| model.Library.Equals("Lskj.Report.dll", StringComparison.OrdinalIgnoreCase))
|
||||
@@ -1600,6 +1628,15 @@ namespace Lskj.Control
|
||||
Task<List<GridDetailModel>> detailsTask = cachesDic.GetTask<List<GridDetailModel>>(this, "Details");
|
||||
DynamicModel dynamicModel = dynamicModelTask.Result;
|
||||
List<GridDetailModel> details = detailsTask.Result;
|
||||
// 所有子模块使用同一个父模块主键。优先复用外部主表的查询任务,其他入口只补查一次。
|
||||
Task<string> parentPrimaryKeyTask = cachesDic.GetTask<string>(this, "ParentPrimaryKey");
|
||||
if (parentPrimaryKeyTask == null)
|
||||
{
|
||||
parentPrimaryKeyTask = cachesDic.AddTask(this, "ParentPrimaryKey", new Task<string>(() =>
|
||||
{
|
||||
return BaseImpl.GetBasePrimaryKey(dynamicModel.ModuleCode);
|
||||
}));
|
||||
}
|
||||
string DetaiName = string.Empty;
|
||||
PageControlsDic.Clear();
|
||||
foreach (GridDetailModel model in details)
|
||||
@@ -1778,11 +1815,7 @@ namespace Lskj.Control
|
||||
}));
|
||||
if (dynamicModel != null)
|
||||
{
|
||||
Task<string> basePrimaryKeyTask = cachesDic.AddTask(gridEx, "ParentPrimaryKey", new Task<string>(() =>
|
||||
{
|
||||
string basePrimaryKey = BaseImpl.GetBasePrimaryKey(dynamicModel.ModuleCode);
|
||||
return basePrimaryKey;
|
||||
}));
|
||||
cachesDic.AddTask(gridEx, "ParentPrimaryKey", parentPrimaryKeyTask);
|
||||
}
|
||||
Task<DataTable> baseGridRightMenusTask = cachesDic.AddTask(gridEx, "UnionBaseGridRightMenus", new Task<DataTable>(() =>
|
||||
{
|
||||
|
||||
@@ -2112,6 +2112,7 @@ namespace Lskj.Control
|
||||
public override int SetGridViewDataSource(DbDataAdapter adapter, bool selectRowHandler = true)
|
||||
{
|
||||
if (adapter == null) return 0;
|
||||
DbDataAdapter previousAdapter = this.AdapterObj;
|
||||
if (this.ColumnList == null || this.ColumnList.Count == 0)
|
||||
{
|
||||
this.gcMain.Bands.Clear();
|
||||
@@ -2122,53 +2123,74 @@ namespace Lskj.Control
|
||||
lastNodeIndex = 0;
|
||||
if (selectRowHandler) lastNodeIndex = this.TreeListObj.GetVisibleIndexByNode(this.TreeListObj.FocusedNode);
|
||||
|
||||
this.AdapterObj = adapter;
|
||||
DataSet dataSet = new DataSet();
|
||||
//adapter.Fill(dataSet, "SetGridViewDataSource");
|
||||
// 重连配置
|
||||
int maxRetryCount = 2; // 次数
|
||||
int retryDelay = 1000; // 等待时间
|
||||
for (int i = 0; i < maxRetryCount; i++)
|
||||
try
|
||||
{
|
||||
try
|
||||
for (int i = 0; i < maxRetryCount; i++)
|
||||
{
|
||||
adapter.Fill(dataSet, "SetGridViewDataSource");
|
||||
break;//连接成功
|
||||
}
|
||||
catch (SqlException ex)
|
||||
{
|
||||
// 判断是否是连接相关错误
|
||||
if (IsConnectionError(ex.Number) ||
|
||||
ex.Message.Contains("物理连接不可用") ||
|
||||
ex.Message.Contains("传输级错误"))
|
||||
try
|
||||
{
|
||||
if (i < maxRetryCount - 1)
|
||||
adapter.Fill(dataSet, "SetGridViewDataSource");
|
||||
break;//连接成功
|
||||
}
|
||||
catch (SqlException ex)
|
||||
{
|
||||
// 判断是否是连接相关错误
|
||||
if (IsConnectionError(ex.Number) ||
|
||||
ex.Message.Contains("物理连接不可用") ||
|
||||
ex.Message.Contains("传输级错误"))
|
||||
{
|
||||
SqlConnection.ClearAllPools();
|
||||
System.Threading.Thread.Sleep(retryDelay);
|
||||
continue; // 重试
|
||||
if (i < maxRetryCount - 1)
|
||||
{
|
||||
SqlConnection.ClearAllPools();
|
||||
System.Threading.Thread.Sleep(retryDelay);
|
||||
continue; // 重试
|
||||
}
|
||||
else
|
||||
{
|
||||
// 最后一次重试失败,抛出错误
|
||||
throw new Exception($"经过 {maxRetryCount} 次重试后仍无法连接到数据库: {ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 最后一次重试失败,抛出错误
|
||||
throw new Exception($"经过 {maxRetryCount} 次重试后仍无法连接到数据库: {ex.Message}", ex);
|
||||
// 其他SQL错误直接抛出
|
||||
throw;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 其他SQL错误直接抛出
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
dataSet.Dispose();
|
||||
DisposeDataAdapter(adapter);
|
||||
throw;
|
||||
}
|
||||
|
||||
DataTable resultTable = dataSet.Tables.Count > 0 ? dataSet.Tables[0] : null;
|
||||
int rowCount = resultTable == null ? 0 : resultTable.Rows.Count;
|
||||
if (resultTable != null)
|
||||
{
|
||||
dataSet.Tables.Remove(resultTable);
|
||||
}
|
||||
dataSet.Dispose();
|
||||
|
||||
DbCommandBuilder cb = SqlHelper.dbFactory.CreateCommandBuilder();
|
||||
cb.DataAdapter = this.AdapterObj;
|
||||
DisposeAdapterCommandBuilder();
|
||||
if (previousAdapter != null && !ReferenceEquals(previousAdapter, adapter))
|
||||
{
|
||||
DisposeDataAdapter(previousAdapter);
|
||||
}
|
||||
this.AdapterObj = adapter;
|
||||
|
||||
SetAdapterCommandBuilder(this.AdapterObj);
|
||||
//SqlCommandBuilder cb = new SqlCommandBuilder(this.AdapterObj);
|
||||
|
||||
GetTreeExpanded();
|
||||
this.gcMain.DataSource = dataSet.Tables[0];
|
||||
this.gcMain.DataSource = resultTable;
|
||||
this.SetAutoColumns();
|
||||
//根据记录展开对应节点
|
||||
foreach (TreeListNode treeListNode in treeListNodes)
|
||||
@@ -2193,7 +2215,7 @@ namespace Lskj.Control
|
||||
{
|
||||
this.TreeListObj.FocusedNode = lastNode;
|
||||
}
|
||||
return dataSet.Tables[0] != null ? dataSet.Tables[0].Rows.Count : 0;
|
||||
return rowCount;
|
||||
}
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Lskj.Core
|
||||
{
|
||||
@@ -148,15 +148,18 @@ namespace Lskj.Core
|
||||
apiHandlerModels = new List<ApiHandlerModel>();
|
||||
apiHandler._dataImpl = new Data.Api.DataImpl();
|
||||
|
||||
apiHandler._dataImpl.dbOperator = new Lskj.Data.ADO.Template.DbTemplate(SqlHelper._connection.ConnectionString, "system.data.sqlclient");
|
||||
apiHandler._dataImpl = new Lskj.Data.Api.DataImpl()//新建数据库连接
|
||||
{
|
||||
dbOperator = new Lskj.Data.ADO.Template.DbTemplate(SqlHelper._connection.ConnectionString, "system.data.sqlclient")
|
||||
};
|
||||
if (isSend)//是否发送数据
|
||||
{
|
||||
apiHandler.GetEventApiSendData(mep, apiHandlerModels);
|
||||
apiHandler.SendEventApiData(apiHandlerModels);
|
||||
apiHandler.GetEventApiSendData(mep, apiHandlerModels, apiHandler._dataImpl);
|
||||
apiHandler.SendEventApiData(apiHandlerModels, apiHandler._dataImpl);
|
||||
}
|
||||
else
|
||||
{
|
||||
apiHandler.GetEventApiSendData(mep, apiHandlerModels);
|
||||
apiHandler.GetEventApiSendData(mep, apiHandlerModels, apiHandler._dataImpl);
|
||||
}
|
||||
this.apiResutMsg = apiHandler.GetApiReturnMsg(apiHandlerModels);
|
||||
}
|
||||
|
||||
@@ -381,6 +381,15 @@ namespace Lskj.Core
|
||||
{
|
||||
return Internet ? AESUtil.Decrypt(Connection3) : AESUtil.Decrypt(Connection4);
|
||||
}
|
||||
|
||||
private static string EnableSqlServerIdleConnectionResilience(string connectionString)
|
||||
{
|
||||
SqlConnectionStringBuilder builder =
|
||||
new SqlConnectionStringBuilder(connectionString);
|
||||
builder["ConnectRetryCount"] = 1;
|
||||
return builder.ConnectionString;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>说明:创建数据库连接</para>
|
||||
/// <para>创建人:龚宇超</para>
|
||||
@@ -420,6 +429,10 @@ namespace Lskj.Core
|
||||
providerName = "Dm";
|
||||
SqlHelper.ConnectionType = ConnectionType.DmServer;
|
||||
}
|
||||
if (connectionType == ConnectionType.SqlServer)
|
||||
{
|
||||
connStr = EnableSqlServerIdleConnectionResilience(connStr);
|
||||
}
|
||||
SqlHelper.dbFactory = DbProviderFactories.GetFactory(providerName);
|
||||
if (SqlHelper._connection != null)
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user