窗体设计器:工具箱、拖放、属性与事件窗口,读写 VS 格式的 Designer.cs
- Designer.cs 在浏览器端解析为语句列表,未改动的语句保留原文: 教材 25 个参考窗体和全部示例读入再写出逐字节不变 - 编辑操作:添加 / 删除 / 移动 / 改名控件、属性、事件、列表项; 布局语句增删规则与 VS 一致(对全部现有文件执行无变化) - 双击控件或事件:绑定事件并在窗体代码末尾插入处理方法,跳到代码 - 预览复用运行时的 ControlView,设计时与运行时外观一致 - 修正:窗体属性 this.ClientSize = new Size(...) 被误认成创建控件; 示例 Designer.cs 的块头注释改为 VS 的 "// " 格式 - 测试:73 个(读写往返、布局规则、编辑操作、插入事件处理方法) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
03e80ce2e2
commit
ea5a25af06
20 files changed
+2767
-132
No files matched your search
@@ -0,0 +1,41 @@
|
||||
/// <reference types="bun" />
|
||||
import { describe, expect, test } from 'bun:test'
|
||||
import { existsSync } from 'node:fs'
|
||||
import { resolve } from 'node:path'
|
||||
import { generateDesigner, parseDesigner } from './document'
|
||||
|
||||
const ROOT = resolve(import.meta.dir, '../../..')
|
||||
// 教材配套的参考工程不在仓库里(版权),本机有时才测
|
||||
const REFERENCE_DIR = resolve(ROOT, 'docs/物联网编程与应用配套/物联网编程与应用')
|
||||
|
||||
async function designerFiles(dir: string) {
|
||||
const files: string[] = []
|
||||
for await (const path of new Bun.Glob('**/*.Designer.cs').scan({ cwd: dir })) {
|
||||
if (path.includes('/obj/') || path.includes('/Properties/')) continue
|
||||
files.push(resolve(dir, path))
|
||||
}
|
||||
return files.sort()
|
||||
}
|
||||
|
||||
describe('读入 Designer.cs 再原样写出,内容逐字节不变', async () => {
|
||||
const files = [
|
||||
...(await designerFiles(resolve(ROOT, 'samples'))),
|
||||
...(existsSync(REFERENCE_DIR) ? await designerFiles(REFERENCE_DIR) : []),
|
||||
]
|
||||
for (const file of files) {
|
||||
test(file.replace(`${ROOT}/`, ''), async () => {
|
||||
const text = await Bun.file(file).text()
|
||||
expect(generateDesigner(parseDesigner(text))).toBe(text)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
test('窗体属性 this.ClientSize = new Size(...) 不会被当成创建控件', async () => {
|
||||
const text = await Bun.file(resolve(ROOT, 'samples/p2-t2-模拟量采集/frm_analog.Designer.cs')).text()
|
||||
const doc = parseDesigner(text)
|
||||
const creates = doc.prologue.filter((s) => s.kind === 'create').map((s) => (s.kind === 'create' ? s.name : ''))
|
||||
expect(creates).not.toContain('ClientSize')
|
||||
expect(creates).not.toContain('AutoScaleDimensions')
|
||||
const formProps = doc.blocks.at(-1)!.stmts.flatMap((s) => (s.kind === 'prop' ? [s.path] : []))
|
||||
expect(formProps).toContain('ClientSize')
|
||||
})
|
||||
Reference in new issue
Block a user