窗体显示和 WinForms 对齐:文本框、下拉框、列表框、日期选择默认白底黑字,不沿用父控件的颜色(项目 8 白字分组框里的文本框填了字看不见);下拉框的背景色能显示、展开的列表跟着下拉框的颜色和字体;分组框、面板禁用时里面的控件也禁用(变灰、不响应操作,Enabled 读出 false 并触发 EnabledChanged);禁用的控件设了颜色也画灰字;窗体、文本框等设透明背景色和 WinForms 一样报错,设计器里也不提供"透明";多行文本框按 ScrollBars 显示滚动条;标签的边框和 TextAlign、窗体的 ControlBox、复选框的不确定状态能显示;设计器里 Enabled = false 的控件和 VS 一样照常显示
CI/CD / test (push) Canceled after 0s
CI/CD / deploy (push) Canceled after 0s

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
xuyueandClaude Opus 5.5 committed 2026-10-27 16:41:46 +08:00
1 parent a2f03ee57f
commit 50946467f6
15 files changed
+247 -26

No files matched your search

+32 -7
View File
@@ -11,7 +11,7 @@ namespace System.Windows.Forms;
/// <summary>
/// 仿真控件的基类。属性保存在本进程里;控件所在窗体显示后,属性变化以 patch 消息发给浏览器渲染。
/// Font、BackColor、ForeColor 是"环境属性":没有显式设置时沿用父控件的值,只把显式设置的值发给浏览器。
/// Font、BackColor、ForeColor 是"环境属性":没有显式设置时沿用父控件的值(文本框等的颜色除外,见 OwnBackColor),只把显式设置的值发给浏览器。
/// </summary>
public class Control : Component, IWin32Window
{
@@ -178,24 +178,42 @@ public class Control : Component, IWin32Window
}
}
/// <summary>和 WinForms 一样:父控件(分组框、面板)禁用时子控件也是禁用的,读出 false、不响应操作;浏览器按同样的规则画成灰色</summary>
public bool Enabled
{
get => _enabled;
get => _enabled && (_parent?.Enabled ?? true);
set
{
if (SetProp(ref _enabled, value, nameof(Enabled))) OnEnabledChanged(EventArgs.Empty);
var old = Enabled;
SetProp(ref _enabled, value, nameof(Enabled));
if (Enabled != old) OnEnabledChanged(EventArgs.Empty);
}
}
/// <summary>
/// 没有显式设置时控件自己的颜色;null 表示沿用父控件。文本框、列表框、下拉框、日期选择是白底黑字(SystemColors.Window / WindowText),
/// 不沿用父控件:分组框设成白字时,里面的文本框还是黑字。
/// </summary>
private protected virtual Color? OwnBackColor => null;
private protected virtual Color? OwnForeColor => null;
/// <summary>能不能把 BackColor 设成透明(含半透明):窗体、文本框、列表框、下拉框、日期选择、数据表格不行,和 WinForms 一样报错</summary>
private protected virtual bool SupportsTransparentBackColor => true;
public virtual Color BackColor
{
get => !_backColor.IsEmpty ? _backColor : _parent?.BackColor ?? DefaultBackColor;
set => SetProp(ref _backColor, value, nameof(BackColor));
get => !_backColor.IsEmpty ? _backColor : OwnBackColor ?? _parent?.BackColor ?? DefaultBackColor;
set
{
if (!value.IsEmpty && value.A < 255 && !SupportsTransparentBackColor) throw new ArgumentException("控件不支持透明的背景色。");
SetProp(ref _backColor, value, nameof(BackColor));
}
}
public virtual Color ForeColor
{
get => !_foreColor.IsEmpty ? _foreColor : _parent?.ForeColor ?? DefaultForeColor;
get => !_foreColor.IsEmpty ? _foreColor : OwnForeColor ?? _parent?.ForeColor ?? DefaultForeColor;
set => SetProp(ref _foreColor, value, nameof(ForeColor));
}
@@ -302,7 +320,14 @@ public class Control : Component, IWin32Window
protected virtual void OnMouseLeave(EventArgs e) => MouseLeave?.Invoke(this, e);
protected virtual void OnTextChanged(EventArgs e) => TextChanged?.Invoke(this, e);
protected virtual void OnVisibleChanged(EventArgs e) => VisibleChanged?.Invoke(this, e);
protected virtual void OnEnabledChanged(EventArgs e) => EnabledChanged?.Invoke(this, e);
protected virtual void OnEnabledChanged(EventArgs e)
{
EnabledChanged?.Invoke(this, e);
// 自己没被禁用的子控件实际状态也跟着变,同样触发 EnabledChanged(WinForms 的 OnParentEnabledChanged)
for (var i = 0; i < Controls.Count; i++)
if (Controls[i]._enabled) Controls[i].OnEnabledChanged(e);
}
protected virtual void OnGotFocus(EventArgs e) => GotFocus?.Invoke(this, e);
protected virtual void OnLostFocus(EventArgs e) => LostFocus?.Invoke(this, e);
protected virtual void OnPaint(PaintEventArgs e) => Paint?.Invoke(this, e);
@@ -468,6 +468,8 @@ public class DataGridView : Control, ISupportInitialize
private bool _initializing;
private bool _rowsDirty;
private protected override bool SupportsTransparentBackColor => false;
public DataGridView()
{
Columns = new DataGridViewColumnCollection(this);
@@ -22,6 +22,10 @@ public class DateTimePicker : Control
protected override Size DefaultSize => new(200, 21);
private protected override Color? OwnBackColor => SystemColors.Window;
private protected override Color? OwnForeColor => SystemColors.WindowText;
private protected override bool SupportsTransparentBackColor => false;
public DateTime Value
{
get => _value;
+2
View File
@@ -23,6 +23,8 @@ public class Form : ContainerControl
private bool _modal;
private DialogResult _dialogResult;
private protected override bool SupportsTransparentBackColor => false;
public Form()
{
base.Visible = false;
@@ -1,5 +1,6 @@
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
namespace System.Windows.Forms;
@@ -10,6 +11,10 @@ public abstract class ListControl : Control
/// <summary>选中项的序号。列表项增删时直接调整(和 WinForms 一样不触发 SelectedIndexChanged)</summary>
private protected int SelectedIndexValue = -1;
private protected override Color? OwnBackColor => SystemColors.Window;
private protected override Color? OwnForeColor => SystemColors.WindowText;
private protected override bool SupportsTransparentBackColor => false;
public abstract int SelectedIndex { get; set; }
public string DisplayMember { get; set; } = "";
+4
View File
@@ -10,6 +10,10 @@ public abstract class TextBoxBase : Control
private bool _readOnly;
private BorderStyle _borderStyle = BorderStyle.Fixed3D;
private protected override Color? OwnBackColor => _readOnly ? SystemColors.Control : SystemColors.Window;
private protected override Color? OwnForeColor => SystemColors.WindowText;
private protected override bool SupportsTransparentBackColor => false;
public bool Multiline
{
get => _multiline;