基线:全量源码首提(D1 版本控制落地,含第一轮优化 B1-B4/A1/A4/缩放修复)
This commit is contained in:
@@ -0,0 +1,392 @@
|
||||
# Designer.cs 代码生成规则(SharpDevelop CodeDom 序列化风格)
|
||||
|
||||
对应实现:SharpDevelop NRefactoryDesignerLoader 序列化 + `Commands/GenerateDockWindows.cs` 生成器。缩进用 **Tab**,语句带 `this.`,非 System 类型用全名。
|
||||
|
||||
## 0. 目标窗体约定(用户强制)
|
||||
|
||||
- 生成/手写 Designer.cs 的目标永远是解决方案**自带主窗口 MainForm**(MainForm.Designer.cs),事件运行时代码放 MainForm.cs;**绝不新建第二个窗体承载 UI**(TestForm/Form2 之类只在该项目本身就是测试工具时才允许)。
|
||||
- **写 Designer.cs 前先补引用,否则设计器死锁**(jk55 案例):设计器加载第一步是类型解析,项目没引用增强控件程序集就直接一片 CS0246;而"切设计标签自动补引用"的代码跑在设计器加载流程**内部**,类型解析不过它永远不执行——引用缺失→加载失败→自动补不触发→引用仍缺失。**AI 生成 Designer.cs 的同一次改动必须先写 §0.1 的 9 个引用。** 工具箱拖放场景不受影响(那时设计器本来就能加载)。
|
||||
|
||||
### 0.1 增强控件引用九件套(写 Designer.cs 时同步写进 csproj)
|
||||
|
||||
HintPath **默认指向 SharpDevelop 安装目录** `C:\Program Files (x86)\SharpDevelop\5.2\bin`:装完即存在、机器间一致(工具箱自动补引用与引用解析兜底用的同一规范位置)。三条变通:
|
||||
|
||||
- **装在非默认位置**:先用下面的命令找到真实安装 bin,把 9 个 HintPath 整体替换成实际路径(注册表卸载键 InstallLocation 为空,别用它):
|
||||
```powershell
|
||||
# ① IDE 在跑:进程路径(exe 所在目录即 bin)
|
||||
Get-Process SharpDevelop -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Path
|
||||
# ② 开始菜单快捷方式(已实测)
|
||||
$s = New-Object -ComObject WScript.Shell
|
||||
Get-ChildItem "$env:ProgramData\Microsoft\Windows\Start Menu\Programs","$env:AppData\Microsoft\Windows\Start Menu\Programs" -Recurse -Filter '*SharpDevelop*.lnk' -ErrorAction SilentlyContinue | ForEach-Object { $s.CreateShortcut($_.FullName).TargetPath }
|
||||
# ③ 已有项目 HintPath
|
||||
Get-ChildItem "$env:USERPROFILE\Documents\SharpDevelop Projects" -Recurse -Filter *.csproj -ErrorAction SilentlyContinue | Select-String 'Smart\.CustomComponents\.dll.*HintPath'
|
||||
```
|
||||
都找不到就问用户,不要瞎猜路径。完整说明见 SKILL.md 第一章"定位实际安装目录"。
|
||||
- **开发机临时追新**:仓库 bin `F:\Visual Studio\1\33\SharpDevelop-master\bin` 有最新控件时可把 HintPath 临时换成它,但该路径仅本机存在,**交付/给用户机的模板一律用安装目录**。
|
||||
- **前提:安装目录必须是最新构建**。jk55 案例发现 08-27 旧安装包缺 RibbonStrip/Logger(13 控件只认 11)——先重打 MSI 重装,或把仓库 bin 最新 DLL 覆盖到安装目录。
|
||||
|
||||
```xml
|
||||
<ItemGroup>
|
||||
<Reference Include="Smart.CustomComponents, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ba044a4aa43e0dc4">
|
||||
<HintPath>C:\Program Files (x86)\SharpDevelop\5.2\bin\Smart.CustomComponents.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="WeifenLuo.WinFormsUI.Docking">
|
||||
<HintPath>C:\Program Files (x86)\SharpDevelop\5.2\bin\WeifenLuo.WinFormsUI.Docking.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="WeifenLuo.WinFormsUI.Docking.ThemeVS2015">
|
||||
<HintPath>C:\Program Files (x86)\SharpDevelop\5.2\bin\WeifenLuo.WinFormsUI.Docking.ThemeVS2015.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Data.SQLite">
|
||||
<HintPath>C:\Program Files (x86)\SharpDevelop\5.2\bin\System.Data.SQLite.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="log4net">
|
||||
<HintPath>C:\Program Files (x86)\SharpDevelop\5.2\bin\log4net.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Resources.Extensions">
|
||||
<HintPath>C:\Program Files (x86)\SharpDevelop\5.2\bin\System.Resources.Extensions.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Memory">
|
||||
<HintPath>C:\Program Files (x86)\SharpDevelop\5.2\bin\System.Memory.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.CompilerServices.Unsafe">
|
||||
<HintPath>C:\Program Files (x86)\SharpDevelop\5.2\bin\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Numerics.Vectors">
|
||||
<HintPath>C:\Program Files (x86)\SharpDevelop\5.2\bin\System.Numerics.Vectors.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
```
|
||||
|
||||
`<Private>True</Private>` 会在编译时把 DLL 复制进项目 `bin\Debug`,之后项目运行/分发不再依赖 HintPath 原位置(换机器、重装 SharpDevelop 都不受影响)。
|
||||
|
||||
## 1. 标准骨架(单控件)
|
||||
|
||||
```csharp
|
||||
namespace DemoApp
|
||||
{
|
||||
partial class MainForm
|
||||
{
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
private Smart.CustomComponents.RoundedButton roundedButton1;
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null)) components.Dispose();
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.roundedButton1 = new Smart.CustomComponents.RoundedButton();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// roundedButton1
|
||||
//
|
||||
this.roundedButton1.Location = new System.Drawing.Point(40, 60);
|
||||
this.roundedButton1.Name = "roundedButton1";
|
||||
this.roundedButton1.Radius = 20;
|
||||
this.roundedButton1.Size = new System.Drawing.Size(140, 44);
|
||||
this.roundedButton1.Style = Smart.CustomComponents.RoundedButtonStyle.Success;
|
||||
this.roundedButton1.TabIndex = 0;
|
||||
this.roundedButton1.Text = "保存";
|
||||
this.roundedButton1.Click += new System.EventHandler(this.roundedButton1_Click);
|
||||
//
|
||||
// MainForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(784, 561);
|
||||
this.Controls.Add(this.roundedButton1);
|
||||
this.Name = "MainForm";
|
||||
this.Text = "DemoApp";
|
||||
this.ResumeLayout(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
规则:每个控件一段注释头;Location/Name/Size/TabIndex 总是写;其余属性只写**非默认值**(对照 components.md 表);事件在属性后、Controls.Add 前;容器结尾 `ResumeLayout(false)`,有子布局的控件加 `PerformLayout()` 对。
|
||||
|
||||
## 2. Content 集合生成
|
||||
|
||||
### 2.1 字符串项集合(MultiSelectComboBox.Items / ResizableComboBox.Items)
|
||||
|
||||
```csharp
|
||||
this.multiSelectComboBox1.Items.Add("选项A");
|
||||
this.multiSelectComboBox1.Items.Add("选项B");
|
||||
```
|
||||
|
||||
### 2.2 递归对象集合(SideMenuPanel.MenuItems,条目有 Children)
|
||||
|
||||
```csharp
|
||||
Smart.CustomComponents.SideMenuItem sideMenuItem1 = new Smart.CustomComponents.SideMenuItem();
|
||||
sideMenuItem1.Text = "首页";
|
||||
Smart.CustomComponents.SideMenuItem sideMenuItem2 = new Smart.CustomComponents.SideMenuItem();
|
||||
sideMenuItem2.Text = "数据管理";
|
||||
Smart.CustomComponents.SideMenuItem sideMenuItem3 = new Smart.CustomComponents.SideMenuItem();
|
||||
sideMenuItem3.Text = "导出记录";
|
||||
sideMenuItem2.Children.Add(sideMenuItem3);
|
||||
this.sideMenuPanel1.MenuItems.Add(sideMenuItem1);
|
||||
this.sideMenuPanel1.MenuItems.Add(sideMenuItem2);
|
||||
```
|
||||
|
||||
### 2.3 页面集合(SideMenuPanel.Pages)
|
||||
|
||||
页面是 Panel 派生 → 走**字段**路径(设计器把页面注册进 IDesignerHost.Container,命名为 sideMenuPageN):
|
||||
|
||||
```csharp
|
||||
private Smart.CustomComponents.SideMenuPage sideMenuPage1;
|
||||
|
||||
this.sideMenuPage1 = new Smart.CustomComponents.SideMenuPage();
|
||||
this.sideMenuPage1.BackColor = System.Drawing.Color.White;
|
||||
this.sideMenuPage1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.sideMenuPage1.Location = ...;
|
||||
this.sideMenuPage1.MenuKey = "首页";
|
||||
this.sideMenuPage1.Name = "sidePage_首页"; // 用户可改
|
||||
this.sideMenuPanel1.Pages.Add(this.sideMenuPage1);
|
||||
```
|
||||
|
||||
注意:页面一般由菜单自动同步生成(MenuKey=菜单文字);手写时 MenuKey 必须与某菜单项 Text 匹配才会被点击切换。**页面内子控件用 EnableDesignMode 暴露,不要生成 `父.页面` 形式的点号字段名**(历史崩溃点:`sideMenuPanel1.Page_0_首页` 是非法 C# 字段名)。
|
||||
|
||||
### 2.4 停靠窗口集合(DockSurface.DockWindows,DockWindowItem 条目)
|
||||
|
||||
```csharp
|
||||
Smart.CustomComponents.DockWindows.DockWindowItem dockWindowItem1 = new Smart.CustomComponents.DockWindows.DockWindowItem();
|
||||
dockWindowItem1.ClassName = "ToolWindow";
|
||||
dockWindowItem1.Title = "工具箱";
|
||||
dockWindowItem1.DockState = WeifenLuo.WinFormsUI.Docking.DockState.DockLeft;
|
||||
dockWindowItem1.DefaultWidth = 240;
|
||||
dockWindowItem1.ShowCloseButton = false;
|
||||
this.dockSurface1.DockWindows.Add(dockWindowItem1);
|
||||
```
|
||||
|
||||
只写非默认属性(DefaultHeight=180、FixedPosition=false、ShowCloseButton=true 是默认,省略)。
|
||||
|
||||
### 2.5 功能区三层集合(RibbonStrip.Tabs → RibbonTab.Groups → RibbonGroup.Buttons → RibbonButton)
|
||||
|
||||
```csharp
|
||||
Smart.CustomComponents.RibbonTab ribbonTab1 = new Smart.CustomComponents.RibbonTab();
|
||||
ribbonTab1.Text = "开始";
|
||||
Smart.CustomComponents.RibbonGroup ribbonGroup1 = new Smart.CustomComponents.RibbonGroup();
|
||||
ribbonGroup1.Text = "文件";
|
||||
Smart.CustomComponents.RibbonButton ribbonButton1 = new Smart.CustomComponents.RibbonButton();
|
||||
ribbonButton1.Text = "打开";
|
||||
ribbonButton1.Image = Smart.CustomComponents.RibbonButton.FromFile("C:\\icons\\open.png"); // 有图标时
|
||||
ribbonButton1.Enabled = false; // 非默认才写
|
||||
ribbonGroup1.Buttons.Add(ribbonButton1);
|
||||
ribbonTab1.Groups.Add(ribbonGroup1);
|
||||
this.ribbonStrip1.Tabs.Add(ribbonTab1);
|
||||
```
|
||||
|
||||
规则:
|
||||
- 逐层 `new` → 赋非默认属性 → `Add` 进上一级集合;只写非默认(Text 无默认标记通常总写,SizeStyle=Small、Enabled=true 是默认省略)。
|
||||
- **图标**:`按钮.Image = RibbonButton.FromFile("路径")`(RibbonImageConverter 序列化形态;ImageFile 本身隐藏不写)。无图标则不写 Image 行。
|
||||
- 事件统一走一个 `this.ribbonStrip1.ButtonClick += new System.EventHandler<Smart.CustomComponents.RibbonButtonEventArgs>(this.ribbonStrip1_ButtonClick);`,处理器里按 `e.Button.Text` 分发(参数带 e.Tab/e.Group/e.Button)。
|
||||
- `this.ribbonStrip1.ActiveTabIndex = 0;` 是默认,省略。
|
||||
|
||||
## 3. 停靠窗口三文件生成(等价"生成停靠窗口代码"命令)
|
||||
|
||||
集合配置好后生成 3 类文件(幂等:窗口类已存在不覆盖,仅同步 Designer.cs 的 this.Text 行;partial 与构造函数接线按当前配置刷新):
|
||||
|
||||
### 3.1 窗口类 `DockWindows\<类名>\<类名>.cs`
|
||||
|
||||
```csharp
|
||||
using System;
|
||||
using WeifenLuo.WinFormsUI.Docking;
|
||||
|
||||
namespace DemoApp
|
||||
{
|
||||
/// <summary>停靠窗口:工具箱。内容在本类的设计器视图中编辑。</summary>
|
||||
public partial class ToolWindow : DockContent
|
||||
{
|
||||
public ToolWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
Text = "工具箱";
|
||||
TabText = "工具箱";
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2 窗口类设计器骨架 `DockWindows\<类名>\<类名>.Designer.cs`
|
||||
|
||||
```csharp
|
||||
namespace DemoApp
|
||||
{
|
||||
partial class ToolWindow
|
||||
{
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null)) components.Dispose();
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Designer generated code
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.SuspendLayout();
|
||||
this.Name = "ToolWindow";
|
||||
this.Text = "工具箱";
|
||||
this.ResumeLayout(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
(双击 .cs 可继续用 SharpDevelop 设计器往里拖控件,序列化规则同第 1、2 节。)
|
||||
|
||||
### 3.3 创建/停靠 partial `DockWindows\<Form>.<surface>.DockWindows.cs`
|
||||
|
||||
```csharp
|
||||
// 本文件由『生成停靠窗口代码』自动生成,集合变更后会自动刷新,请勿手工编辑。
|
||||
using System;
|
||||
using WeifenLuo.WinFormsUI.Docking;
|
||||
|
||||
namespace DemoApp
|
||||
{
|
||||
public partial class MainForm
|
||||
{
|
||||
void CreateDockWindows_dockSurface1()
|
||||
{
|
||||
var dockSurface1 = this.dockSurface1 as Smart.CustomComponents.DockSurface;
|
||||
if (dockSurface1 == null) return;
|
||||
dockSurface1.EnsureDefaultTheme(); // 必须:Show 前保证有效主题
|
||||
var w1 = new ToolWindow();
|
||||
w1.CloseButtonVisible = false; // 仅 ShowCloseButton=false 时生成
|
||||
w1.DockAreas = WeifenLuo.WinFormsUI.Docking.DockAreas.DockLeft; // 仅 FixedPosition=true 时
|
||||
w1.TabText = "工具箱"; // Title 非空时生成
|
||||
w1.Text = "工具箱";
|
||||
w1.Show(dockSurface1, DockState.DockLeft);
|
||||
var w2 = new FloatWindow2();
|
||||
w2.Size = new System.Drawing.Size(320, 240); // 仅 DockState.Float 时
|
||||
w2.Show(dockSurface1, DockState.Float);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
属性设置**必须在 Show 之前**。FixedPosition 的 DockAreas 映射:
|
||||
|
||||
| DockState | DockAreas |
|
||||
|---|---|
|
||||
| DockLeft / DockLeftAutoHide | DockLeft |
|
||||
| DockRight / DockRightAutoHide | DockRight |
|
||||
| DockTop / DockTopAutoHide | DockTop |
|
||||
| DockBottom / DockBottomAutoHide | DockBottom |
|
||||
| Document | Document |
|
||||
| Float | Float |
|
||||
| Hidden / Unknown | 不锁定(不生成 DockAreas 行) |
|
||||
|
||||
### 3.4 构造函数接线(MainForm.cs)
|
||||
|
||||
`InitializeComponent();` 之后插入(已存在则跳过):
|
||||
|
||||
```csharp
|
||||
InitializeComponent();
|
||||
CreateDockWindows_dockSurface1();
|
||||
```
|
||||
|
||||
自动触发链:集合编辑器"确定" → IComponentChangeService.OnComponentChanged → 400ms 防抖静默生成。多面板时每个 DockSurface 各一个 `CreateDockWindows_<面板名>` 方法。
|
||||
|
||||
## 4. 特殊控件生成注意
|
||||
|
||||
- **属性白名单铁律(s23 案例 2026-09-01)**:Designer.cs 里写的每个属性必须能在 components.md 该控件条目下查到(自有属性表或继承属性行)。**跨控件抄属性是头号翻车点**——写一个该控件没有的属性,CodeDom 反序列化直接抛 `CodeDomSerializerException`("XX 没有名为 YY 的属性"),**整个设计器加载中止**、窗体全黑。已知最易抄错的两对:
|
||||
- `VariableEditTextBox` **没有 PlaceholderText**(那是 ResizableTextBox 的;它继承 TextBox,自有属性只有 BindVariable/Value,要占位提示就用 ResizableTextBox);
|
||||
- `VariableDisplayLabel` **没有 BorderStyle**(它继承 Control 不是 Label,自有属性只有 BindVariable/DisplayValue/TextAlign)。
|
||||
- **ImageButton**:属性名/枚举是中文标识符,直接写:`this.imageButton1.图文布局 = Smart.CustomComponents.图文布局枚举.图左文右;`
|
||||
- **OKNGStatusControl**:不写 Text(自绘 OK/NG);IsOK=true 默认省略。
|
||||
- **EnhancedDataGridView**:列与普通 DataGridView 相同(`this.enhancedDataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {...})` + 每列独立字段段);Sqlite 三属性按字符串直写。
|
||||
- **事件处理器签名**:`private void roundedButton1_Click(object sender, EventArgs e)`,写在主 .cs 文件(不放 Designer.cs)。
|
||||
- **图片属性**(SideMenuItem.Icon、Image 类型):走 .resx 资源(`System.ComponentModel.ComponentResourceManager resources = new ...typeof(MainForm));` + `resources.GetObject("$this.sideMenuItem1.Icon")`),SharpDevelop 风格同 WinForms。
|
||||
|
||||
## 5. 生成的运行时诊断(生成器自带,勿删)
|
||||
|
||||
partial 里附带了写 `bin\Debug\DockWindows.Log.txt` 的日志:主题类型/页签条/补丁重载数 + 每窗口 Show 前后的 CloseButtonVisible/DockAreas/DockState/TabText。排错时**先读这个文件**(用户要求:日志优先,截图最后)。
|
||||
|
||||
## 6. 非可视组件模板
|
||||
|
||||
属性表见 `winforms-components.md`。要点:无 Location/Size/TabIndex;构造带 IContainer 的(Timer/ImageList/ErrorProvider/ToolTip/BindingSource/NotifyIcon/HelpProvider/BackgroundWorker/SerialPort)写 `new ...(this.components)` 且不再 Add;不带的(PrintDocument/Process/EventLog/FileSystemWatcher/PerformanceCounter)用 `this.components.Add(this.xxx);`;DataSet/BindingSource 用 ISupportInitialize 的 BeginInit/EndInit 包裹。扩展提供器(ToolTip/ErrorProvider/HelpProvider)对其他控件逐行 `SetXxx(目标控件, 值)`。
|
||||
|
||||
## 7. 菜单/工具栏嵌套模板(每个菜单项/工具栏项都是字段)
|
||||
|
||||
```csharp
|
||||
private System.Windows.Forms.MenuStrip menuStrip1;
|
||||
private System.Windows.Forms.ToolStripMenuItem 文件ToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem 退出ToolStripMenuItem;
|
||||
|
||||
this.menuStrip1 = new System.Windows.Forms.MenuStrip();
|
||||
this.文件ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.退出ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
//
|
||||
// 退出ToolStripMenuItem
|
||||
//
|
||||
this.退出ToolStripMenuItem.Name = "退出ToolStripMenuItem";
|
||||
this.退出ToolStripMenuItem.Size = new System.Drawing.Size(180, 22); // 布局值,设计器会写
|
||||
this.退出ToolStripMenuItem.Text = "退出";
|
||||
this.退出ToolStripMenuItem.Click += new System.EventHandler(this.退出ToolStripMenuItem_Click);
|
||||
//
|
||||
// 文件ToolStripMenuItem
|
||||
//
|
||||
this.文件ToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.退出ToolStripMenuItem});
|
||||
this.文件ToolStripMenuItem.Text = "文件";
|
||||
//
|
||||
// menuStrip1
|
||||
//
|
||||
this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.文件ToolStripMenuItem});
|
||||
this.menuStrip1.Location = new System.Drawing.Point(0, 0);
|
||||
this.menuStrip1.Name = "menuStrip1";
|
||||
this.menuStrip1.Size = ...; this.menuStrip1.TabIndex = ...;
|
||||
this.menuStrip1.Text = "menuStrip1";
|
||||
// 窗体段:
|
||||
this.MainMenuStrip = this.menuStrip1;
|
||||
this.Controls.Add(this.menuStrip1);
|
||||
```
|
||||
|
||||
ContextMenuStrip 同构(无 Dock、无 MainMenuStrip 行);StatusStrip 用 ToolStripStatusLabel(Spring=true 占满 + BorderSide 等);ToolStrip 混用 ToolStripButton/ToolStripSeparator/ToolStripTextBox…,均独立字段。MenuStrip/ToolStrip 的 Items 段**不写每项 Name 之外的 Text 之外的默认值**;`DropDownItems.AddRange` 表示层级。
|
||||
|
||||
## 8. ListView / TreeView 集合模板
|
||||
|
||||
```csharp
|
||||
// ListView:列为字段,行可 ctor 一行带上
|
||||
this.columnHeader1 = new System.Windows.Forms.ColumnHeader();
|
||||
this.columnHeader1.Text = "姓名"; this.columnHeader1.Width = 120;
|
||||
this.columnHeader2 = new System.Windows.Forms.ColumnHeader();
|
||||
this.columnHeader2.Text = "分数";
|
||||
this.listView1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
|
||||
this.columnHeader1, this.columnHeader2});
|
||||
this.listView1.FullRowSelect = true; // View=Details 时常用组合
|
||||
this.listView1.View = System.Windows.Forms.View.Details;
|
||||
this.listView1.Items.AddRange(new System.Windows.Forms.ListViewItem[] {
|
||||
new System.Windows.Forms.ListViewItem(new string[] {"张三", "95"}),
|
||||
new System.Windows.Forms.ListViewItem(new string[] {"李四", "88"})});
|
||||
// 分组(可选)
|
||||
this.listViewGroup1 = new System.Windows.Forms.ListViewGroup("一组");
|
||||
this.listView1.Groups.AddRange(new System.Windows.Forms.ListViewGroup[] {this.listViewGroup1});
|
||||
|
||||
// TreeView:节点递归,ctor 带文本
|
||||
System.Windows.Forms.TreeNode treeNode1 = new System.Windows.Forms.TreeNode("根节点");
|
||||
System.Windows.Forms.TreeNode treeNode2 = new System.Windows.Forms.TreeNode("子节点1");
|
||||
System.Windows.Forms.TreeNode treeNode3 = new System.Windows.Forms.TreeNode(new string[] {
|
||||
"子节点1", "子节点2"}); // 兄弟数组写法(Name1,Name2 平铺)
|
||||
treeNode1.Nodes.AddRange(new System.Windows.Forms.TreeNode[] {treeNode3});
|
||||
this.treeView1.Nodes.AddRange(new System.Windows.Forms.TreeNode[] {treeNode1});
|
||||
```
|
||||
|
||||
TreeView 的 designer 实际写法是临时变量 treeNodeN 逐级挂 Nodes.AddRange;ImageKey/SelectedImageKey 在绑定 ImageList 后写。
|
||||
Reference in New Issue
Block a user